[
  {
    "path": ".gitignore",
    "content": ".*\n\n#\n# git files that we don't want to ignore even it they are dot-files\n#\n!.gitignore\n!.mailmap\n.github*\npatches-*\nbuild/\noutgoing/\nMakefile\n\n# documentation artifacts\n_build/\n_doxygen/\n_images/\n_static/\n_templates/\n_toc.yml\ndoxygen\n\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n\ncmake_minimum_required(VERSION 3.7)\n\n# Set the project name\nproject(\"rocr\")\n\nset(CMAKE_VERBOSE_MAKEFILE ON)\n## Expose static library option\nif ( NOT DEFINED BUILD_SHARED_LIBS )\n  set ( BUILD_SHARED_LIBS ON )\nendif()\nset ( BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS} CACHE BOOL \"Build shared library (.so) or not.\")\n\nif (NOT DEFINED BUILD_ROCR)\n  set(BUILD_ROCR ON)\nendif()\n\nfunction(add_rocm_subdir subdir subdir_assigns)\n    message(\"add_rocm_subdir() -- \" ${subdir})\n    # message(\"  subdir_assigns before:\" ${subdir_assigns} \"EOM\")\n    string(STRIP \"${subdir_assigns}\" subdir_assigns)\n    message(\"  subdir_assigns:\" ${subdir_assigns} \"EOM\")\n\n    # if the subdir_assigns is defined and  non-empty, then..\n\n    if(NOT \"${subdir_assigns}\" STREQUAL \"\")\n        foreach(assignment IN LISTS subdir_assigns)\n            # The format of each var should be VARNAME=VALUE\n            message(\"assignment: \" ${assignment})\n            string(REPLACE \"=\" \";\" pair ${assignment})\n            list(GET pair 0 var_name)\n            list(GET pair 1 var_value)\n\n            # Set variable locally for this function and for the subdirectory\n            set(${var_name} \"${var_value}\")\n            message(\"The value of ${var_name} is: ${${var_name}}\")\n        endforeach()\n    endif()\n    add_subdirectory(${subdir})\nendfunction()\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules\")\ninclude(utils)\n\n\n## Get version strings\nget_version(\"1.18.0\")\nif (${ROCM_PATCH_VERSION})\n  set(VERSION_PATCH ${ROCM_PATCH_VERSION})\nendif()\nset(SO_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}\")\nset(PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_COMMIT_COUNT}\")\n\nif (NOT DEFINED BUILD_SHARED_LIBS)\n\tset(BUILD_SHARED_LIBS ON)\nendif()\n\n# Set hsa pkg dependency with rocprofiler-register package\n# for Shared Library Only.\nif (BUILD_SHARED_LIBS)\n  set(HSA_DEP_ROCPROFILER_REGISTER ON CACHE INTERNAL \"\")\nendif()\n\nif (HSA_DEP_ROCPROFILER_REGISTER)\n  string(APPEND CPACK_DEBIAN_BINARY_PACKAGE_DEPENDS \", rocprofiler-register\")\n  string(APPEND CPACK_RPM_BINARY_PACKAGE_REQUIRES \" rocprofiler-register\")\nendif()\n\nif (NOT DEFINED BUILD_THUNK_VIRTIO)\n  set(BUILD_THUNK_VIRTIO OFF)\nendif()\n\nadd_rocm_subdir(libhsakmt \"${THUNK_DEFINITIONS}\")\nset_target_properties(hsakmt PROPERTIES\n                                ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/libhsakmt/archive\"\n                                LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/libhsakmt/lib\"\n                                RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/libhsakmt/runtime\")\n\nif (BUILD_THUNK_VIRTIO)\n  add_rocm_subdir(libhsakmt/src/virtio \"${THUNK_VIRTIO_DEFINITIONS}\")\nendif()\n\nif (BUILD_ROCR)\n  add_rocm_subdir(runtime/hsa-runtime \"${ROCR_DEFINITIONS}\")\n  set_target_properties(hsa-runtime64 PROPERTIES\n                               ARCHIVE_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/rocr/archive\"\n                               LIBRARY_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/rocr/lib\"\n                               RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/rocr/runtime\")\n\n  if (BUILD_SHARED_LIBS)\n    add_dependencies(hsa-runtime64 hsakmt)\n    if (BUILD_THUNK_VIRTIO)\n      add_dependencies(hsa-runtime64 hsakmt_virtio)\n    endif()\n  else()\n    add_dependencies(hsa-runtime64 hsakmt-staticdrm)\n  endif()\nendif()\n\n# Optionally record the package's find module in the user's package cache.\nif ( NOT DEFINED EXPORT_TO_USER_PACKAGE_REGISTRY )\n  set ( EXPORT_TO_USER_PACKAGE_REGISTRY \"off\")\nendif()\nset ( EXPORT_TO_USER_PACKAGE_REGISTRY ${EXPORT_TO_USER_PACKAGE_REGISTRY} CACHE BOOL \"Add cmake package config location to the user's cmake package registry.\")\nif(${EXPORT_TO_USER_PACKAGE_REGISTRY})\n  # Enable writing to the registry\n  set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)\n  # Generate a target file for the build\n  export(TARGETS ${CORE_RUNTIME_NAME} NAMESPACE ${CORE_RUNTIME_NAME}:: FILE ${CORE_RUNTIME_NAME}Targets.cmake)\n  # Record the package in the user's cache.\n  export(PACKAGE ${CORE_RUNTIME_NAME})\nendif()\n\n## Packaging directives\nset(CPACK_VERBOSE 1)\nset(CPACK_GENERATOR \"DEB;RPM\" CACHE STRING \"Package types to build\")\nset(ENABLE_LDCONFIG ON CACHE BOOL \"Set library links and caches using ldconfig.\")\n\n# From libhsakmt:\nset(CPACK_PACKAGING_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"  CACHE STRING \"Default packaging prefix.\")\n\nif(DEFINED CPACK_PACKAGING_INSTALL_PREFIX)\n  set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION \"${CPACK_PACKAGING_INSTALL_PREFIX} ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}\")\nendif()\n\n# ASAN Package will have libraries and license file\nif (ENABLE_ASAN_PACKAGING)\n  # ASAN Package requires only asan component with libraries and license file\n  set(CPACK_COMPONENTS_ALL asan)\nelse()\n  set(CPACK_COMPONENTS_ALL binary dev)\nendif()\nset(CPACK_DEB_COMPONENT_INSTALL ON)\nset(CPACK_RPM_COMPONENT_INSTALL ON)\nset(CPACK_PACKAGE_VENDOR \"Advanced Micro Devices, Inc.\")\nset(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION_STRING})\nset(CPACK_PACKAGE_CONTACT \"AMD HSA Support <dl.HSA-Runtime-Support@amd.com>\")\nset(CPACK_COMPONENT_DESCRIPTION \"AMD Heterogeneous System Architecture HSA - Linux HSA Runtime for Boltzmann (ROCm) platforms\\nIncludes HSAKMT, the user-mode API interfaces used to interact with the ROCk driver.\\n Contains the headers, pkgonfig and\\n cmake files for ROCT.\")\nset(CPACK_COMPONENT_BINARY_DESCRIPTION \"AMD Heterogeneous System Architecture HSA - Linux HSA Runtime for Boltzmann (ROCm) platforms\")\nset(CPACK_COMPONENT_DEV_DESCRIPTION \"AMD Heterogeneous System Architecture HSA development package.\\n This package contains the headers and cmake files for the rocr-runtime package.\")\nset(CPACK_COMPONENT_ASAN_DESCRIPTION \"AMD Heterogeneous System Architecture HSA - Linux HSA instrumented libraries for Boltzmann (ROCm) platforms\")\n\nif (DEFINED ENV{ROCM_LIBPATCH_VERSION})\n  set(CPACK_PACKAGE_VERSION \"${CPACK_PACKAGE_VERSION}.$ENV{ROCM_LIBPATCH_VERSION}\")\n  message(\"Using CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}\")\nendif()\n\n# Debian package specific variables\nset(CPACK_DEBIAN_BINARY_PACKAGE_NAME \"hsa-rocr\")\nset(CPACK_DEBIAN_DEV_PACKAGE_NAME \"hsa-rocr-dev\")\nset(CPACK_DEBIAN_ASAN_PACKAGE_NAME \"hsa-rocr-asan\")\nif (DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE})\n  set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE})\nelse()\n  set(CPACK_DEBIAN_PACKAGE_RELEASE \"local\")\nendif()\nmessage(\"Using CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_DEBIAN_PACKAGE_RELEASE}\")\nset(CPACK_DEBIAN_FILE_NAME \"DEB-DEFAULT\")\nset(CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/RadeonOpenCompute/ROCR-Runtime\")\n\n## Process the Debian install/remove scripts to update the CPACK variables\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/DEBIAN/Binary/postinst.in DEBIAN/Binary/postinst @ONLY)\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/DEBIAN/Binary/prerm.in DEBIAN/Binary/prerm @ONLY)\nfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/DEBIAN/preinst DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/DEBIAN)\nset (CPACK_DEBIAN_BINARY_PACKAGE_CONTROL_EXTRA \"DEBIAN/preinst;DEBIAN/Binary/postinst;DEBIAN/Binary/prerm\")\n# Needed since some packages still say they need hsakmt-roct\nset(CPACK_DEBIAN_DEV_PACKAGE_REPLACES \"hsakmt-roct,hsakmt-roct-dev,hsa-ext-rocr-dev\")\nset(CPACK_DEBIAN_DEV_PACKAGE_PROVIDES \"hsakmt-roct,hsakmt-roct-dev,hsa-ext-rocr-dev\")\n#TODO: hsa-ext-rocr-dev can be added to conflicts list and remove CPACK_DEBIAN_DEV_PACKAGE_BREAKS\nset(CPACK_DEBIAN_DEV_PACKAGE_CONFLICTS \"hsakmt-roct,hsakmt-roct-dev\")\n# package dependencies\nset(CPACK_DEBIAN_PACKAGE_DEPENDS \"libdrm-amdgpu-dev | libdrm-dev, rocm-core\")\nset(CPACK_DEBIAN_PACKAGE_RECOMMENDS \"libdrm-amdgpu-dev\")\n# Setting devel package dependendent version\nset(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS \"libdrm-amdgpu-dev | libdrm-dev, rocm-core, hsa-rocr\")\n\nset(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS \"libdrm-amdgpu-dev\")\n\nset(CPACK_DEBIAN_BINARY_PACKAGE_DEPENDS \"libdrm-amdgpu-amdgpu1 | libdrm-amdgpu1, libnuma1, libelf1\")\nset(CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS \"libdrm-amdgpu-dev | libdrm-dev, rocm-core-asan, libdrm-amdgpu-amdgpu1 | libdrm-amdgpu1, libnuma1, libelf1\")\nset(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS \"libdrm-amdgpu-dev\")\n\nset(CPACK_DEBIAN_BINARY_PACKAGE_RECOMMENDS \"libdrm-amdgpu-amdgpu1\")\nif (ROCM_DEP_ROCMCORE)\n  string(APPEND CPACK_DEBIAN_BINARY_PACKAGE_DEPENDS \", rocm-core\")\n  string(APPEND CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS \", rocm-core-asan\")\nendif()\nif (HSA_DEP_ROCPROFILER_REGISTER)\n  string(APPEND CPACK_DEBIAN_BINARY_PACKAGE_DEPENDS \", rocprofiler-register\")\nendif()\n# Declare package relationships (hsa-ext-rocr-dev is a legacy package that we subsume)\nset(CPACK_DEBIAN_DEV_PACKAGE_BREAKS \"hsa-ext-rocr-dev\")\n\n# RPM package specific variables\nset(EL7_DISTRO \"FALSE\")\nChecksetel7(EL7_DISTRO)\nset(CPACK_RPM_BINARY_PACKAGE_NAME \"hsa-rocr\")\n# Since we changed the package name to match RPM specs, take care of older builds that had -dev installed\n# Also cover the fact that this now replaces the old binary package hsakmt-roct\nset(CPACK_RPM_DEV_PACKAGE_PROVIDES \"hsakmt-roct,hsakmt-roct-devel,hsakmt-roct-dev,hsa-ext-rocr-dev\")\nset(CPACK_RPM_DEV_PACKAGE_OBSOLETES \"hsakmt-roct,hsakmt-roct-devel,hsakmt-roct-dev,hsa-ext-rocr-dev\")\n\nset(CPACK_RPM_DEV_PACKAGE_NAME \"hsa-rocr-devel\")\nset(CPACK_RPM_ASAN_PACKAGE_NAME \"hsa-rocr-asan\")\nif (DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE})\n  set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE})\nelse()\n  set(CPACK_RPM_PACKAGE_RELEASE \"local\")\nendif()\n\nstring(APPEND CPACK_RPM_PACKAGE_RELEASE \"%{?dist}\")\nset(CPACK_RPM_FILE_NAME \"RPM-DEFAULT\")\nmessage(\"CPACK_RPM_PACKAGE_RELEASE: ${CPACK_RPM_PACKAGE_RELEASE}\")\nset(CPACK_RPM_PACKAGE_LICENSE \"NCSA\")\n\n## Process the Rpm install/remove scripts to update the CPACK variables\nconfigure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/RPM/Binary/post.in\" RPM/Binary/post @ONLY)\nconfigure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/RPM/Binary/postun.in\" RPM/Binary/postun @ONLY)\nfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/RPM/preinst DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/RPM)\nset (CPACK_RPM_PRE_INSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_BINARY_DIR}/RPM/preinst\")\n\nset(CPACK_RPM_BINARY_POST_INSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_BINARY_DIR}/RPM/Binary/post\")\nset(CPACK_RPM_BINARY_POST_UNINSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_BINARY_DIR}/RPM/Binary/postun\")\n\n# package dependencies\nset(CPACK_RPM_DEV_PACKAGE_REQUIRES \"rocm-core , hsa-rocr\")\n\n#\nif (${EL7_DISTRO} STREQUAL \"TRUE\")\n  set(CPACK_RPM_BINARY_PACKAGE_REQUIRES \"libdrm-amdgpu, numactl-libs\")\n  set(CPACK_RPM_ASAN_PACKAGE_REQUIRES \"libdrm-amdgpu, numactl-libs, libdrm-amdgpu-devel\")\n  set(CPACK_RPM_PACKAGE_REQUIRES \"libdrm-amdgpu-devel\")\n  string(APPEND CPACK_RPM_DEV_PACKAGE_REQUIRES \", libdrm-amdgpu-devel\")\nelse()\n  set(CPACK_RPM_BINARY_PACKAGE_REQUIRES \"(libdrm-amdgpu or libdrm or libdrm_amdgpu1), (libnuma1 or numactl-libs)\")\n  set(CPACK_RPM_ASAN_PACKAGE_REQUIRES \"(libdrm-amdgpu or libdrm or libdrm_amdgpu1), (libnuma1 or numactl-libs), (libdrm-amdgpu-devel or libdrm-devel)\")\n  set(CPACK_RPM_USER_BINARY_SPECFILE \"${CMAKE_CURRENT_SOURCE_DIR}/RPM/hsa-rocr.spec.in\")\n  set(CPACK_RPM_PACKAGE_RECOMMENDS \"libdrm-amdgpu, libdrm-amdgpu-devel\")\n\n  set(CPACK_RPM_PACKAGE_REQUIRES \"(libdrm-amdgpu-devel or libdrm-devel)\")\n  string(APPEND CPACK_RPM_DEV_PACKAGE_REQUIRES \", (libdrm-amdgpu-devel or libdrm-devel)\")\n  set(CPACK_RPM_DEV_PACKAGE_RECOMMENDS \"libdrm-amdgpu-devel\")\n  set(CPACK_RPM_ASAN_PACKAGE_RECOMMENDS \"libdrm-amdgpu-devel\")\n\nendif()\n\nif (ROCM_DEP_ROCMCORE)\n  string(APPEND CPACK_RPM_BINARY_PACKAGE_REQUIRES \" rocm-core\")\n  string(APPEND CPACK_RPM_ASAN_PACKAGE_REQUIRES \" rocm-core-asan\")\nelse()\n  string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_RPM_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})\n  string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_DEBIAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})\n  string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_DEV_PACKAGE_REQUIRES})\n  string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ${CPACK_DEBIAN_DEV_PACKAGE_DEPENDS})\n  string(REGEX REPLACE \",? ?rocm-core-asan\" \"\" CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_ASAN_PACKAGE_REQUIRES})\n  string(REGEX REPLACE \",? ?rocm-core-asan\" \"\" CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS})\nendif()\nif (HSA_DEP_ROCPROFILER_REGISTER)\n  string(APPEND CPACK_RPM_BINARY_PACKAGE_REQUIRES \" rocprofiler-register\")\nendif()\n\nif(NOT BUILD_SHARED_LIBS)\n  # Suffix package name with static\n  set(CPACK_RPM_STATIC_PACKAGE_NAME \"hsa-rocr-static-devel\")\n  set(CPACK_DEBIAN_STATIC_PACKAGE_NAME \"hsa-rocr-static-dev\")\n  set(CPACK_COMPONENT_STATIC_DESCRIPTION \"HSA (Heterogenous System Architecture) core runtime - Linux static libraries\")\n  set(CPACK_RPM_STATIC_PACKAGE_REQUIRES \"${CPACK_RPM_BINARY_PACKAGE_REQUIRES}\")\n  set(CPACK_DEBIAN_STATIC_PACKAGE_DEPENDS \"${CPACK_DEBIAN_BINARY_PACKAGE_DEPENDS}\")\nendif()\n\n## Include packaging\ninclude(CPack)\n\n# static package generation\n# Group binary and dev component to single package\nif(NOT BUILD_SHARED_LIBS)\n    cpack_add_component_group(\"static\")\n    cpack_add_component(binary  GROUP static)\n    cpack_add_component(dev GROUP static)\nendif()\n\ncpack_add_component(asan\n  DISPLAY_NAME \"ASAN\"\n  DESCRIPTION \"ASAN libraries for rocr-runtime\")\n"
  },
  {
    "path": "DEBIAN/Binary/postinst.in",
    "content": "#!/bin/bash\n\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2020-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nset -e\n\n# left-hand term originates from @ENABLE_LDCONFIG@ = ON/OFF at package build\ndo_ldconfig() {\n  if [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /etc/ld.so.conf.d/rocr-runtime.conf\n    ldconfig\n  fi\n}\n\ncase \"$1\" in\n   ( configure )\n       do_ldconfig\n   ;;\n  ( abort-upgrade | abort-remove | abort-deconfigure )\n    echo \"$1\"\n  ;;\n   ( * )\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "DEBIAN/Binary/prerm.in",
    "content": "#!/bin/bash\n\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2020-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nset -e\n\n# left-hand term originates from @ENABLE_LDCONFIG@ = ON/OFF at package build\nrm_ldconfig() {\n  if [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    rm -f /etc/ld.so.conf.d/rocr-runtime.conf\n    ldconfig\n  fi\n}\n\ncase \"$1\" in\n   ( remove | upgrade)\n       rm_ldconfig\n   ;;\n  ( purge )\n  ;;\n   ( * )\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "DEBIAN/Dev/postinst.in",
    "content": "#!/bin/bash\n\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2020-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nset -e\n\ncase \"$1\" in\n   ( configure )\n       # Workaround for CPACK directory symlink handling error.\n       mkdir -p @CPACK_PACKAGING_INSTALL_PREFIX@/hsa/include\n       ln -sf ../../@CMAKE_INSTALL_INCLUDEDIR@/hsa @CPACK_PACKAGING_INSTALL_PREFIX@/hsa/include/hsa\n   ;;\n   ( * )\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "DEBIAN/Dev/prerm.in",
    "content": "#!/bin/bash\n\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2020-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nset -e\n\ncase \"$1\" in\n   ( remove | upgrade )\n       # Workaround for CPACK directory symlink handling error.\n       # Needed for remove and upgrade scenarios since\n       # upgrade installs to new folder and old folders need to be cleaned\n       rm -rf @CPACK_PACKAGING_INSTALL_PREFIX@/hsa\n   ;;\n   ( * )\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "DEBIAN/preinst",
    "content": "#!/bin/bash\n\necho \"Pre-install check for ROCr.\"\n\n# Check for old installations...\nif ls /usr/lib/libhsa-runtime* 1> /dev/null 2>&1; then\n  echo \"An old version of libhsa-runtime was found in /usr/lib.\"\n  echo \"This must be uninstalled before proceeding with the installation\"\n  echo \"to avoid potential incompatibilities.\"\n\n  read -r -p \"Do you want to uninstall the old version? [y/N] \" response\n  if [ \"$response\" = \"y\" ]; then\n    if ! rm -rf /usr/lib/libhsa-runtime*; then\n      echo \"Failed to remove /usr/lib/libhsa-runtime* files.\"\n      echo \"Try to uninstall these files manually.\"\n      exit 1\n    fi\n    echo \"Old version uninstalled.\"\n  else\n    echo \"The old and new versions of ROCm are incompatible. Installation aborted.\"\n    exit 1\n  fi\nfi\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "The University of Illinois/NCSA\nOpen Source License (NCSA)\n\nCopyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n\nDeveloped by:\n\n                AMD Research and AMD HSA Software Development\n\n                Advanced Micro Devices, Inc.\n\n                www.amd.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal with the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\n - Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimers.\n - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimers in\n   the documentation and/or other materials provided with the distribution.\n - Neither the names of Advanced Micro Devices, Inc,\n   nor the names of its contributors may be used to endorse or promote\n   products derived from this Software without specific prior written\n   permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS WITH THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# ROCR Runtime\n\n> [!CAUTION]\n> The ROCR-Runtime repository is retired, please use the [ROCm/rocm-systems](https://github.com/ROCm/rocm-systems/tree/develop/projects/rocr-runtime) repository\n\nThis ROCm Runtime (ROCr) repo combines 2 previously separate repos into a single repo:\n- The HSA Runtime (`hsa-runtime`) for AMD GPU application development and\n- The ROCt Thunk Library (`libhsakmt`), a \"thunk\" interface to the ROCm kernel driver (ROCk), used by the runtime.\n"
  },
  {
    "path": "RPM/Binary/post.in",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2016-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n# left-hand term originates from @ENABLE_LDCONFIG@ = ON/OFF at package build\nif [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n  echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /etc/ld.so.conf.d/hsa-rocr.conf\n  ldconfig\nfi\n"
  },
  {
    "path": "RPM/Binary/postun.in",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2016-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n# left-hand term originates from @ENABLE_LDCONFIG@ = ON/OFF at package build\nif [ $1 -le 1 ] && [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    # perform the below actions for rpm remove($1=0) or upgrade($1=1) operations\n    rm -f /etc/ld.so.conf.d/hsa-rocr.conf\n    ldconfig\nfi\n"
  },
  {
    "path": "RPM/Dev/post.in",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2016-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n# Workaround for CPACK directory symlink handling error.\nmkdir -p @CPACK_PACKAGING_INSTALL_PREFIX@/hsa/include\nln -sf ../../@CMAKE_INSTALL_INCLUDEDIR@/hsa @CPACK_PACKAGING_INSTALL_PREFIX@/hsa/include/hsa\n"
  },
  {
    "path": "RPM/Dev/postun.in",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2016-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nif [ $1 -le 1 ]; then\n  # Workaround for CPACK directory symlink handling error.\n  # Needed for uninstall and upgrade scenarios since\n  # upgrade install to new folder and old folders need to be cleaned\n  rm -rf @CPACK_PACKAGING_INSTALL_PREFIX@/hsa\nfi\n"
  },
  {
    "path": "RPM/hsa-rocr.spec.in",
    "content": "# Restore old style debuginfo creation for rpm >= 4.14.\n%undefine _debugsource_packages\n%undefine _debuginfo_subpackages\n\n# -*- rpm-spec -*-\nBuildRoot:      %_topdir/@CPACK_PACKAGE_FILE_NAME@@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH@\nSummary:        @CPACK_RPM_PACKAGE_SUMMARY@\nName:           @CPACK_RPM_PACKAGE_NAME@\nVersion:        @CPACK_RPM_PACKAGE_VERSION@\nRelease:        @CPACK_RPM_PACKAGE_RELEASE@\nLicense:        @CPACK_RPM_PACKAGE_LICENSE@\nGroup:          @CPACK_RPM_PACKAGE_GROUP@\nVendor:         @CPACK_RPM_PACKAGE_VENDOR@\n\n# Modifications to allow recommends to be used (not implemented in cpack):\n%if \"@CPACK_RPM_PACKAGE_RECOMMENDS@\" != \"\"\nRecommends: @CPACK_RPM_PACKAGE_RECOMMENDS@\n%endif\n# End of modifications\n\n@TMP_RPM_URL@\n@TMP_RPM_REQUIRES@\n@TMP_RPM_REQUIRES_PRE@\n@TMP_RPM_REQUIRES_POST@\n@TMP_RPM_REQUIRES_PREUN@\n@TMP_RPM_REQUIRES_POSTUN@\n@TMP_RPM_PROVIDES@\n@TMP_RPM_OBSOLETES@\n@TMP_RPM_CONFLICTS@\n@TMP_RPM_SUGGESTS@\n@TMP_RPM_AUTOPROV@\n@TMP_RPM_AUTOREQ@\n@TMP_RPM_AUTOREQPROV@\n@TMP_RPM_BUILDARCH@\n@TMP_RPM_PREFIXES@\n@TMP_RPM_EPOCH@\n\n@TMP_RPM_DEBUGINFO@\n\n%define _rpmdir %_topdir/RPMS\n%define _srcrpmdir %_topdir/SRPMS\n@FILE_NAME_DEFINE@\n%define _unpackaged_files_terminate_build 0\n@TMP_RPM_SPEC_INSTALL_POST@\n@CPACK_RPM_SPEC_MORE_DEFINE@\n@CPACK_RPM_COMPRESSION_TYPE_TMP@\n\n%description\n@CPACK_RPM_PACKAGE_DESCRIPTION@\n\n# This is a shortcutted spec file generated by CMake RPM generator\n# we skip _install step because CPack does that for us.\n# We do only save CPack installed tree in _prepr\n# and then restore it in build.\n%prep\nmv $RPM_BUILD_ROOT %_topdir/tmpBBroot\n\n%install\nif [ -e $RPM_BUILD_ROOT ];\nthen\n  rm -rf $RPM_BUILD_ROOT\nfi\nmv %_topdir/tmpBBroot $RPM_BUILD_ROOT\n\n@TMP_RPM_DEBUGINFO_INSTALL@\n\n%clean\n\n%post\n@RPM_SYMLINK_POSTINSTALL@\n@CPACK_RPM_SPEC_POSTINSTALL@\n\n%posttrans\n@CPACK_RPM_SPEC_POSTTRANS@\n\n%postun\n@CPACK_RPM_SPEC_POSTUNINSTALL@\n\n%pre\n@CPACK_RPM_SPEC_PREINSTALL@\n\n%pretrans\n@CPACK_RPM_SPEC_PRETRANS@\n\n%preun\n@CPACK_RPM_SPEC_PREUNINSTALL@\n\n%files\n%defattr(@TMP_DEFAULT_FILE_PERMISSIONS@,@TMP_DEFAULT_USER@,@TMP_DEFAULT_GROUP@,@TMP_DEFAULT_DIR_PERMISSIONS@)\n@CPACK_RPM_INSTALL_FILES@\n@CPACK_RPM_ABSOLUTE_INSTALL_FILES@\n@CPACK_RPM_USER_INSTALL_FILES@\n\n%changelog\n@CPACK_RPM_SPEC_CHANGELOG@\n\n@TMP_OTHER_COMPONENTS@\n"
  },
  {
    "path": "RPM/preinst",
    "content": "#!/bin/bash\n\necho \"Pre-install check for ROCr.\"\n\n# Check for old installations...\nif ls /usr/lib/libhsa-runtime* 1> /dev/null 2>&1; then\n  echo \"An old version of libhsa-runtime was found in /usr/lib.\"\n  echo \"This must be uninstalled before proceeding with the installation\"\n  echo \"to avoid potential incompatibilities.\"\n\n  read -r -p \"Do you want to uninstall the old version? [y/N] \" response\n  if [ \"$response\" = \"y\" ]; then\n    if ! rm -rf /usr/lib/libhsa-runtime*; then\n      echo \"Failed to remove /usr/lib/libhsa-runtime* files.\"\n      echo \"Try to uninstall these files manually.\"\n      exit 1\n    fi\n    echo \"Old version uninstalled.\"\n  else\n    echo \"The old and new versions of ROCm are incompatible. Installation aborted.\"\n    exit 1\n  fi\nfi\n"
  },
  {
    "path": "_clang-format",
    "content": "---\nLanguage:        Cpp\n# BasedOnStyle:  Google\nAccessModifierOffset: -1\nConstructorInitializerIndentWidth: 4\nAlignEscapedNewlinesLeft: false\nAlignTrailingComments: true\nAlignConsecutiveAssignments: false\nAlignOperands: false\nAllowAllParametersOfDeclarationOnNextLine: true\nAllowShortBlocksOnASingleLine: false\nAllowShortIfStatementsOnASingleLine: true\nAllowShortLoopsOnASingleLine: true\nAllowShortFunctionsOnASingleLine: All\nAlwaysBreakAfterDefinitionReturnType: false\nAlwaysBreakTemplateDeclarations: false\nAlwaysBreakBeforeMultilineStrings: true\nBreakBeforeBinaryOperators: false\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializersBeforeComma: false\nBinPackParameters: true\nColumnLimit:     100\nConstructorInitializerAllOnOneLineOrOnePerLine: true\nExperimentalAutoDetectBinPacking: false\nIndentCaseLabels: true\nIndentWrappedFunctionNames: false\nIndentFunctionDeclarationAfterType: false\nMaxEmptyLinesToKeep: 2\nKeepEmptyLinesAtTheStartOfBlocks: false\nNamespaceIndentation: None\nObjCSpaceAfterProperty: false\nObjCSpaceBeforeProtocolList: false\nPenaltyBreakBeforeFirstCallParameter: 1\nPenaltyBreakComment: 300\nPenaltyBreakString: 1000\nPenaltyBreakFirstLessLess: 120\nPenaltyExcessCharacter: 1000000\nPenaltyReturnTypeOnItsOwnLine: 200\nDerivePointerAlignment: false\nPointerAlignment: Left\nSpacesBeforeTrailingComments: 2\nCpp11BracedListStyle: true\nStandard:        Auto\nIndentWidth:     2\nTabWidth:        8\nUseTab:          Never\nBreakBeforeBraces: Attach\nSpacesInParentheses: false\nSpacesInAngles:  false\nSpaceInEmptyParentheses: false\nSpacesInCStyleCastParentheses: false\nSpacesInContainerLiterals: true\nSpaceBeforeAssignmentOperators: true\nContinuationIndentWidth: 4\nCommentPragmas:  '^ IWYU pragma:'\nForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]\nSpaceBeforeParens: ControlStatements\nDisableFormat: false\nSortIncludes: false\n...\n"
  },
  {
    "path": "clang-format-diff.py",
    "content": "#!/usr/bin/env python3\n#\n#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#\n#\n# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.\n# See https://llvm.org/LICENSE.txt for license information.\n# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n#\n#===------------------------------------------------------------------------===#\n\n\"\"\"\nThis script reads input from a unified diff and reformats all the changed\nlines. This is useful to reformat all the lines touched by a specific patch.\nExample usage for git/svn users:\n\n  git diff -U0 --no-color --relative HEAD^ | clang-format-diff.py -p1 -i\n  svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i\n\nIt should be noted that the filename contained in the diff is used unmodified\nto determine the source file to update. Users calling this script directly\nshould be careful to ensure that the path in the diff is correct relative to the\ncurrent working directory.\n\"\"\"\nfrom __future__ import absolute_import, division, print_function\n\nimport argparse\nimport difflib\nimport re\nimport subprocess\nimport sys\n\nif sys.version_info.major >= 3:\n    from io import StringIO\nelse:\n    from io import BytesIO as StringIO\n\n\ndef main():\n  parser = argparse.ArgumentParser(description=__doc__,\n                                   formatter_class=\n                                           argparse.RawDescriptionHelpFormatter)\n  parser.add_argument('-i', action='store_true', default=False,\n                      help='apply edits to files instead of displaying a diff')\n  parser.add_argument('-p', metavar='NUM', default=0,\n                      help='strip the smallest prefix containing P slashes')\n  parser.add_argument('-regex', metavar='PATTERN', default=None,\n                      help='custom pattern selecting file paths to reformat '\n                      '(case sensitive, overrides -iregex)')\n  parser.add_argument('-iregex', metavar='PATTERN', default=\n                      r'.*\\.(cpp|cc|c\\+\\+|cxx|c|cl|h|hh|hpp|hxx|m|mm|inc|js|ts'\n                      r'|proto|protodevel|java|cs)',\n                      help='custom pattern selecting file paths to reformat '\n                      '(case insensitive, overridden by -regex)')\n  parser.add_argument('-sort-includes', action='store_true', default=False,\n                      help='let clang-format sort include blocks')\n  parser.add_argument('-v', '--verbose', action='store_true',\n                      help='be more verbose, ineffective without -i')\n  parser.add_argument('-style',\n                      help='formatting style to apply (LLVM, GNU, Google, Chromium, '\n                      'Microsoft, Mozilla, WebKit)')\n  parser.add_argument('-binary', default='clang-format',\n                      help='location of binary to use for clang-format')\n  args = parser.parse_args()\n\n  # Extract changed lines for each file.\n  filename = None\n  lines_by_file = {}\n  for line in sys.stdin:\n    match = re.search(r'^\\+\\+\\+\\ (.*?/){%s}(\\S*)' % args.p, line)\n    if match:\n      filename = match.group(2)\n    if filename is None:\n      continue\n\n    if args.regex is not None:\n      if not re.match('^%s$' % args.regex, filename):\n        continue\n    else:\n      if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):\n        continue\n\n    match = re.search(r'^@@.*\\+(\\d+)(,(\\d+))?', line)\n    if match:\n      start_line = int(match.group(1))\n      line_count = 1\n      if match.group(3):\n        line_count = int(match.group(3))\n      if line_count == 0:\n        continue\n      end_line = start_line + line_count - 1\n      lines_by_file.setdefault(filename, []).extend(\n          ['-lines', str(start_line) + ':' + str(end_line)])\n\n  # Reformat files containing changes in place.\n  for filename, lines in lines_by_file.items():\n    if args.i and args.verbose:\n      print('Formatting {}'.format(filename))\n    command = [args.binary, filename]\n    if args.i:\n      command.append('-i')\n    if args.sort_includes:\n      command.append('-sort-includes')\n    command.extend(lines)\n    if args.style:\n      command.extend(['-style', args.style])\n\n    try:\n      p = subprocess.Popen(command,\n                           stdout=subprocess.PIPE,\n                           stderr=None,\n                           stdin=subprocess.PIPE,\n                           universal_newlines=True)\n    except OSError as e:\n      # Give the user more context when clang-format isn't\n      # found/isn't executable, etc.\n      raise RuntimeError(\n        'Failed to run \"%s\" - %s\"' % (\" \".join(command), e.strerror))\n\n    stdout, stderr = p.communicate()\n    if p.returncode != 0:\n      sys.exit(p.returncode)\n\n    if not args.i:\n      with open(filename) as f:\n        code = f.readlines()\n      formatted_code = StringIO(stdout).readlines()\n      diff = difflib.unified_diff(code, formatted_code,\n                                  filename, filename,\n                                  '(before formatting)', '(after formatting)')\n      diff_string = ''.join(diff)\n      if len(diff_string) > 0:\n        sys.stdout.write(diff_string)\n\nif __name__ == '__main__':\n  main()\n"
  },
  {
    "path": "cmake_modules/utils.cmake",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and#or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and#or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nfunction( get_path LIB CACHED_PATH HELP )\n\n    set( options \"\")\n    set( oneValueArgs RESULT )\n    set( multiValueArgs HINTS NAMES )\n    cmake_parse_arguments(ARGS \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN} )\n\n    # Search for canary file.\n    if( ${LIB} )\n        find_library( FULLPATH NAMES ${ARGS_NAMES} HINTS ${${CACHED_PATH}} ${ARGS_HINTS} )\n    else()\n        find_file( FULLPATH NAMES ${ARGS_NAMES} HINTS ${${CACHED_PATH}} ${ARGS_HINTS} )\n    endif()\n    set( RESULT (NOT ${FULLPATH} MATCHES NOTFOUND) )\n    \n    # Extract path\n    get_filename_component ( DIRPATH ${FULLPATH} DIRECTORY )\n    \n    # Check path against cache\n    if( NOT \"${${CACHED_PATH}}\" STREQUAL \"\" )\n        if ( NOT \"${${CACHED_PATH}}\" STREQUAL \"${DIRPATH}\" )\n            message(WARNING \"${CACHED_PATH} may be incorrect.\" )\n            set( DIRPATH ${${CACHED_PATH}} )\n        endif()\n    elseif(NOT ${RESULT})\n        message(WARNING \"${CACHED_PATH} not located during path search.\")\n    endif()\n\n    # Set cache variable and help text\n    set( ${CACHED_PATH} ${DIRPATH} CACHE PATH ${HELP} FORCE )\n    unset( FULLPATH CACHE )\n\n    # Return success flag\n    if( NOT ${ARGS_RESULT} STREQUAL \"\" )\n        set( ${ARGS_RESULT} ${RESULT} PARENT_SCOPE)\n    endif()\n\nendfunction()\n\n## Searches for a file using include paths and stores the path to that file in the cache\n## using the cached value if set.  Search paths are optional.  Returns success in RESULT.\n## get_include_path(<VAR> NAMES name1 [name2...] [HINTS path1 [path2 ... ENV var]] [RESULT <var>]\nmacro( get_include_path CACHED_PATH HELP )\n    get_path( 0 ${ARGV} )\nendmacro()\n\n## Searches for a file using library paths and stores the path to that file in the cache\n## using the cached value if set.  Search paths are optional.  Returns success in RESULT.\n## get_library_path(<VAR> NAMES name1 [name2...] [HINTS path1 [path2 ... ENV var]] [RESULT <var>]\nmacro( get_library_path CACHED_PATH HELP )\n    get_path( 1 ${ARGV} )\nendmacro()\n\n## Parses the VERSION_STRING variable and places\n## the first, second and third number values in\n## the major, minor and patch variables.\nfunction( parse_version VERSION_STRING )\n\n    string ( FIND ${VERSION_STRING} \"-\" STRING_INDEX )\n\n    if ( ${STRING_INDEX} GREATER -1 )\n        math ( EXPR STRING_INDEX \"${STRING_INDEX} + 1\" )\n        string ( SUBSTRING ${VERSION_STRING} ${STRING_INDEX} -1 VERSION_BUILD )\n    endif ()\n\n    string ( REGEX MATCHALL \"[0123456789]+\" VERSIONS ${VERSION_STRING} )\n    list ( LENGTH VERSIONS VERSION_COUNT )\n\n    if ( ${VERSION_COUNT} GREATER 0)\n        list ( GET VERSIONS 0 MAJOR )\n        set ( VERSION_MAJOR ${MAJOR} PARENT_SCOPE )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 1 )\n        list ( GET VERSIONS 1 MINOR )\n        set ( VERSION_MINOR ${MINOR} PARENT_SCOPE )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 2 )\n        list ( GET VERSIONS 2 PATCH )\n        set ( VERSION_PATCH ${PATCH} PARENT_SCOPE )\n    endif ()\n\nendfunction ()\n\n## Gets the current version of the repository\n## using versioning tags and git describe.\n## Passes back a packaging version string\n## and a library version string.\nfunction ( get_version DEFAULT_VERSION_STRING )\n\n    set( VERSION_JOB \"local-build\" )\n    set( VERSION_COMMIT_COUNT 0 )\n    set( VERSION_HASH \"unknown\" )\n\n    find_program( GIT NAMES git )\n\n    if( GIT )\n\n        #execute_process ( COMMAND git describe --tags --dirty --long\n        #                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n        #                  OUTPUT_VARIABLE GIT_TAG_STRING\n        #                  OUTPUT_STRIP_TRAILING_WHITESPACE\n        #                  RESULT_VARIABLE RESULT )\n\n        # Get branch commit (common ancestor) of current branch and master branch.\n        execute_process(COMMAND git merge-base HEAD origin/HEAD\n                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                        OUTPUT_VARIABLE GIT_MERGE_BASE\n                        OUTPUT_STRIP_TRAILING_WHITESPACE\n                        RESULT_VARIABLE RESULT )\n\n        if( ${RESULT} EQUAL 0 )\n            # Count commits from branch point.\n            execute_process(COMMAND git rev-list --count ${GIT_MERGE_BASE}..HEAD\n                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                            OUTPUT_VARIABLE VERSION_COMMIT_COUNT\n                            OUTPUT_STRIP_TRAILING_WHITESPACE\n                            RESULT_VARIABLE RESULT )\n            if(NOT ${RESULT} EQUAL 0 )\n                set( VERSION_COMMIT_COUNT 0 )\n            endif()\n        endif()\n\n        # Get current short hash.\n        execute_process(COMMAND git rev-parse --short HEAD\n                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                        OUTPUT_VARIABLE VERSION_HASH\n                        OUTPUT_STRIP_TRAILING_WHITESPACE\n                        RESULT_VARIABLE RESULT )\n        if( ${RESULT} EQUAL 0 )\n            # Check for dirty workspace.\n            execute_process(COMMAND git diff --quiet\n                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                            RESULT_VARIABLE RESULT )\n            if(${RESULT} EQUAL 1)\n                set(VERSION_HASH \"${VERSION_HASH}-dirty\")\n            endif()\n        else()\n            set( VERSION_HASH \"unknown\" )\n        endif()\n    endif()\n\n    # Build automation IDs\n    if(DEFINED ENV{ROCM_BUILD_ID})\n        set( VERSION_JOB $ENV{ROCM_BUILD_ID} )\n    endif()\n\n    parse_version(${DEFAULT_VERSION_STRING})\n\n    set( VERSION_MAJOR  \"${VERSION_MAJOR}\" PARENT_SCOPE )\n    set( VERSION_MINOR  \"${VERSION_MINOR}\" PARENT_SCOPE )\n    set( VERSION_PATCH  \"${VERSION_PATCH}\" PARENT_SCOPE )\n    set( VERSION_COMMIT_COUNT \"${VERSION_COMMIT_COUNT}\" PARENT_SCOPE )\n    set( VERSION_HASH \"${VERSION_HASH}\" PARENT_SCOPE )\n    set( VERSION_JOB \"${VERSION_JOB}\" PARENT_SCOPE )\n\n    #message(\"${VERSION_MAJOR}\" )\n    #message(\"${VERSION_MINOR}\" )\n    #message(\"${VERSION_PATCH}\" )\n    #message(\"${VERSION_COMMIT_COUNT}\")\n    #message(\"${VERSION_HASH}\")\n    #message(\"${VERSION_JOB}\")\n\nendfunction()\n\n## Collects subdirectory names and returns them in a list\nfunction ( listsubdirs DIRPATH SUBDIRECTORIES )\n    file( GLOB CONTENTS RELATIVE ${DIRPATH} \"${DIRPATH}/*\" )\n    set ( FOLDERS, \"\" )\n    foreach( ITEM IN LISTS CONTENTS)\n        if( IS_DIRECTORY \"${DIRPATH}/${ITEM}\" )\n            list( APPEND FOLDERS ${ITEM} )\n        endif()\n    endforeach()\n    set (${SUBDIRECTORIES} ${FOLDERS} PARENT_SCOPE)\nendfunction()\n\n## Sets el7 flag to be true\nfunction (Checksetel7 EL7_DISTRO)\nexecute_process(COMMAND rpm --eval %{?dist}\n                 RESULT_VARIABLE PROC_RESULT\n                 OUTPUT_VARIABLE EVAL_RESULT\n                 OUTPUT_STRIP_TRAILING_WHITESPACE)\nmessage(\"RESULT_VARIABLE ${PROC_RESULT} OUTPUT_VARIABLE: ${EVAL_RESULT}\")\nif (PROC_RESULT EQUAL \"0\" AND NOT EVAL_RESULT STREQUAL \"\")\n  if (\"${EVAL_RESULT}\" STREQUAL \".el7\")\n     set (${EL7_DISTRO} TRUE PARENT_SCOPE)\n  endif()\nendif()\nendfunction()\n"
  },
  {
    "path": "format",
    "content": "#!/bin/bash\nroot=`git rev-parse --show-toplevel`\npushd . > /dev/null\ncd $root\ngit diff -U0 HEAD^ | ./clang-format-diff.py -p1 -i -style=file\npopd > /dev/null\n"
  },
  {
    "path": "libhsakmt/CMakeLists.txt",
    "content": "################################################################################\n##\n## Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.\n##\n## MIT LICENSE:\n## Permission is hereby granted, free of charge, to any person obtaining a copy of\n## this software and associated documentation files (the \"Software\"), to deal in\n## the Software without restriction, including without limitation the rights to\n## use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n## of the Software, and to permit persons to whom the Software is furnished to do\n## so, subject to the following conditions:\n##\n## The above copyright notice and this permission notice shall be included in all\n## copies or substantial portions of the Software.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n## SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.6.3 )\n\nset(CMAKE_VERBOSE_MAKEFILE ON)\n\nset ( HSAKMT \"hsakmt\" )\nset ( HSAKMT_PACKAGE \"hsakmt-roct\" )\nset ( HSAKMT_COMPONENT \"lib${HSAKMT}\" )\nset ( HSAKMT_TARGET \"${HSAKMT}\" )\nset(HSAKMT_STATIC_DRM_TARGET \"${HSAKMT_TARGET}-staticdrm\")\n\nproject ( ${HSAKMT_TARGET} VERSION 1.9.0)\n\n# Optionally, build HSAKMT with ccache.\nset(ROCM_CCACHE_BUILD OFF CACHE BOOL \"Set to ON for a ccache enabled build\")\nif (ROCM_CCACHE_BUILD)\n  find_program(CCACHE_PROGRAM ccache)\n  if (CCACHE_PROGRAM)\n    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})\n  else()\n    message(WARNING \"Unable to find ccache. Falling back to real compiler\")\n  endif() # if (CCACHE_PROGRAM)\nendif() # if (ROCM_CCACHE_BUILD)\n\nlist( PREPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules\" )\n\n## Include common cmake modules\ninclude ( utils )\ninclude ( GNUInstallDirs )\n\n## Setup the package version.\nget_version ( \"1.0.0\" )\n\nset ( BUILD_VERSION_MAJOR ${VERSION_MAJOR} )\nset ( BUILD_VERSION_MINOR ${VERSION_MINOR} )\nset ( BUILD_VERSION_PATCH ${VERSION_PATCH} )\n\nset ( LIB_VERSION_MAJOR 1)\nset ( LIB_VERSION_MINOR 0)\nif (${ROCM_PATCH_VERSION})\n    set ( LIB_VERSION_PATCH ${ROCM_PATCH_VERSION} )\nelse ()\n    set ( LIB_VERSION_PATCH 6)\nendif ()\nset ( LIB_VERSION_STRING \"${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}\" )\n\nif ( DEFINED VERSION_BUILD AND NOT ${VERSION_BUILD} STREQUAL \"\" )\n    message ( \"VERSION BUILD DEFINED ${VERSION_BUILD}\" )\n    set ( BUILD_VERSION_PATCH \"${BUILD_VERSION_PATCH}-${VERSION_BUILD}\" )\nendif ()\nset ( BUILD_VERSION_STRING \"${BUILD_VERSION_MAJOR}.${BUILD_VERSION_MINOR}.${BUILD_VERSION_PATCH}\" )\n\n## Compiler flags\nset (HSAKMT_C_FLAGS -fPIC -W -Wall -Wextra -Wno-unused-parameter -Wformat-security -Wswitch-default -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wunreachable-code -std=gnu99 -fvisibility=hidden)\nif ( CMAKE_COMPILER_IS_GNUCC )\n    set ( HSAKMT_C_FLAGS \"${HSAKMT_C_FLAGS}\" -Wlogical-op)\nendif ()\nif ( ${HSAKMT_WERROR} )\n    set ( HSAKMT_C_FLAGS \"${HSAKMT_C_FLAGS}\" -Werror )\nendif ()\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    set ( HSAKMT_C_FLAGS \"${HSAKMT_C_FLAGS}\" -O2 )\nelse ()\n    set ( HSAKMT_C_FLAGS \"${HSAKMT_C_FLAGS}\" -g )\nendif ()\n\nset ( HSAKMT_LINKER_SCRIPT \"${CMAKE_CURRENT_SOURCE_DIR}/src/libhsakmt.ver\" )\n\n## Linker Flags\n## Add --enable-new-dtags to generate DT_RUNPATH\nset (HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -Wl,--enable-new-dtags -Wl,--version-script=${HSAKMT_LINKER_SCRIPT} -Wl,-soname=${HSAKMT_COMPONENT}.so.${LIB_VERSION_MAJOR} -Wl,-z,nodelete\")\n\n## Address Sanitize Flag\nif ( ${ADDRESS_SANITIZER} )\n    set ( HSAKMT_C_FLAGS \"${HSAKMT_C_FLAGS}\" -fsanitize=address )\n    set ( HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -fsanitize=address\" )\n    if ( BUILD_SHARED_LIBS )\n        set ( HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -shared-libsan\" )\n    else ()\n        set ( HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -static-libsan\" )\n    endif ()\nelse ()\n    if ( CMAKE_COMPILER_IS_GNUCC )\n        set ( HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -Wl,-no-undefined\" )\n    else ()\n        set ( HSAKMT_LINK_FLAGS \"${HSAKMT_LINK_FLAGS} -Wl,-undefined,error\" )\n    endif ()\nendif ()\n\n## Source files\nset ( HSAKMT_SRC \"src/debug.c\"\n                 \"src/events.c\"\n                 \"src/fmm.c\"\n                 \"src/globals.c\"\n                 \"src/hsakmtmodel.c\"\n                 \"src/libhsakmt.c\"\n                 \"src/memory.c\"\n                 \"src/openclose.c\"\n                 \"src/perfctr.c\"\n                 \"src/pmc_table.c\"\n                 \"src/queues.c\"\n                 \"src/time.c\"\n                 \"src/topology.c\"\n                 \"src/rbtree.c\"\n                 \"src/spm.c\"\n                 \"src/version.c\"\n                 \"src/svm.c\"\n                 \"src/pc_sampling.c\")\n\n## Declare the library target name\nadd_library (${HSAKMT_TARGET} STATIC \"\")\n\n## Add sources\ntarget_sources ( ${HSAKMT_TARGET} PRIVATE ${HSAKMT_SRC} )\n\n## Add headers.  The public headers need to point at their location in both build and install\n## directory layouts.  This declaration allows publishing library use data to downstream clients.\ntarget_include_directories( ${HSAKMT_TARGET}\n  PUBLIC\n  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\n  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n  PRIVATE\n  ${CMAKE_CURRENT_SOURCE_DIR}/src )\n\nset_property(TARGET ${HSAKMT_TARGET} PROPERTY LINK_FLAGS ${HSAKMT_LINK_FLAGS})\n\n## Set the VERSION and SOVERSION values\nset_property ( TARGET ${HSAKMT_TARGET} PROPERTY VERSION \"${LIB_VERSION_STRING}\" )\nset_property ( TARGET ${HSAKMT_TARGET} PROPERTY SOVERSION \"${LIB_VERSION_MAJOR}\" )\n\nfind_package(PkgConfig)\n# get OS-info for OS-specific build dependencies\nget_os_info()\n\nfind_package(PkgConfig)\n# Check for libraries required for building\nfind_library(LIBC NAMES c REQUIRED)\nfind_package(NUMA)\nif(NUMA_FOUND)\n  set(NUMA \"${NUMA_LIBRARIES}\")\nelse()\n  find_library(NUMA NAMES numa REQUIRED)\nendif()\nmessage(STATUS \"LIBC: \" ${LIBC})\nmessage(STATUS \"NUMA: \" ${NUMA})\n\n## If environment variable DRM_DIR is set, the script\n## will pick up the corresponding libraries from that path.\nif(DRM_DIR)\n  list (PREPEND CMAKE_PREFIX_PATH \"${DRM_DIR}\")\nendif()\n\n# The module name passed to pkg_check_modules() is determined by the\n# name of file *.pc\npkg_check_modules(DRM REQUIRED IMPORTED_TARGET libdrm)\npkg_check_modules(DRM_AMDGPU REQUIRED IMPORTED_TARGET libdrm_amdgpu)\ninclude_directories(${DRM_AMDGPU_INCLUDE_DIRS})\ninclude_directories(${DRM_INCLUDE_DIRS})\n\ntarget_link_libraries ( ${HSAKMT_TARGET}\n  PRIVATE ${DRM_LDFLAGS} ${DRM_AMDGPU_LDFLAGS} pthread rt ${LIBC} ${NUMA} ${CMAKE_DL_LIBS}\n)\n\ntarget_compile_options(${HSAKMT_TARGET} PRIVATE ${DRM_CFLAGS} ${HSAKMT_C_FLAGS})\n\ninclude(CheckFunctionExists)\nset(CMAKE_REQUIRED_DEFINITIONS -D__USE_GNU=1)\nset(CMAKE_REQUIRED_INCLUDES sys/mman.h)\ncheck_function_exists(memfd_create HAVE_MEMFD_CREATE)\nif(HAVE_MEMFD_CREATE)\n  target_compile_definitions(${HSAKMT_TARGET} PRIVATE -DHAVE_MEMFD_CREATE=1)\nendif()\n\n## Define default paths and packages.\nif( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT )\n  set ( CMAKE_INSTALL_PREFIX \"/opt/rocm\" )\nendif()\nset ( CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE STRING \"Default installation directory.\" FORCE )\n\n# Installs binaries and exports the library usage data to ${HSAKMT_TARGET}Targets\ninstall ( TARGETS ${HSAKMT_TARGET} EXPORT ${HSAKMT_TARGET}Targets\n    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT asan\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT asan )\ninstall ( TARGETS ${HSAKMT_TARGET}\n    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary )\n\n# Install public headers\ninstall ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/${HSAKMT_TARGET} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}\n  COMPONENT dev PATTERN \"linux\" EXCLUDE PATTERN \"*virtio*\" EXCLUDE)\n\n# Record our usage data for clients find_package calls.\ninstall ( EXPORT ${HSAKMT_TARGET}Targets\n  FILE ${HSAKMT_TARGET}Targets.cmake\n  NAMESPACE ${HSAKMT_TARGET}::\n  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${HSAKMT_TARGET}\n  COMPONENT dev)\n\n# Adds the target alias hsakmt::hsakmt to the local cmake cache.\n# This isn't necessary today.  It's harmless preparation for some\n# hypothetical future in which the we might be included by add_subdirectory()\n# in some other project's cmake file.  It allows uniform use of find_package\n# and target_link_library() without regard to whether a target is external or\n# a subdirectory of the current build.\nadd_library( ${HSAKMT_TARGET}::${HSAKMT_TARGET} ALIAS ${HSAKMT_TARGET} )\n\n# Create cmake configuration files\ninclude(CMakePackageConfigHelpers)\n\nconfigure_package_config_file(${HSAKMT_TARGET}-config.cmake.in\n                            ${HSAKMT_TARGET}-config.cmake\n                            INSTALL_DESTINATION\n                            ${CMAKE_INSTALL_LIBDIR}/cmake/${HSAKMT_TARGET} )\n\nwrite_basic_package_version_file(${HSAKMT_TARGET}-config-version.cmake\n                 VERSION ${BUILD_VERSION_STRING}\n                 COMPATIBILITY\n                 AnyNewerVersion)\n\ninstall(FILES\n        ${CMAKE_CURRENT_BINARY_DIR}/${HSAKMT_TARGET}-config.cmake\n        ${CMAKE_CURRENT_BINARY_DIR}/${HSAKMT_TARGET}-config-version.cmake\n        DESTINATION\n        ${CMAKE_INSTALL_LIBDIR}/cmake/${HSAKMT_TARGET}\n        COMPONENT dev)\n\n# Optionally record the package's find module in the user's package cache.\nif ( NOT DEFINED EXPORT_TO_USER_PACKAGE_REGISTRY )\n  set ( EXPORT_TO_USER_PACKAGE_REGISTRY \"off\" )\nendif()\nset ( EXPORT_TO_USER_PACKAGE_REGISTRY ${EXPORT_TO_USER_PACKAGE_REGISTRY}\n             CACHE BOOL \"Add cmake package config location to the user's cmake package registry.\")\nif(${EXPORT_TO_USER_PACKAGE_REGISTRY})\n  # Enable writing to the registry\n  set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)\n  # Generate a target file for the build\n  export(TARGETS ${HSAKMT_TARGET} NAMESPACE ${HSAKMT_TARGET}:: FILE ${HSAKMT_TARGET}Targets.cmake)\n  # Record the package in the user's cache.\n  export(PACKAGE ${HSAKMT_TARGET})\nendif()\n\n# CPACK_PACKAGING_INSTALL_PREFIX is needed in libhsakmt.pc.in\n# TODO: Add support for relocatable packages.\nconfigure_file ( libhsakmt.pc.in libhsakmt.pc @ONLY )\n\ninstall ( FILES ${CMAKE_CURRENT_BINARY_DIR}/libhsakmt.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT dev)\n\nif ( NOT BUILD_SHARED_LIBS)\n  ## Create separate target file for static builds\n  ## In static builds, libdrm and libdrm_amdgpu need to be linked statically\n  add_library (${HSAKMT_STATIC_DRM_TARGET}  STATIC \"\")\n  target_sources (${HSAKMT_STATIC_DRM_TARGET} PRIVATE ${HSAKMT_SRC})\n\n  target_include_directories( ${HSAKMT_STATIC_DRM_TARGET}\n    PUBLIC\n    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\n    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n    PRIVATE\n    ${CMAKE_CURRENT_SOURCE_DIR}/src )\n\n  ## Set the VERSION and SOVERSION values\n  set_property(TARGET ${HSAKMT_STATIC_DRM_TARGET} PROPERTY LINK_FLAGS ${HSAKMT_LINK_FLAGS}\n              PROPERTY VERSION \"${LIB_VERSION_STRING}\"\n              PROPERTY SOVERSION \"${LIB_VERSION_MAJOR}\" )\n\n  #Additional search path for static libraries\n  if(${DISTRO_ID} MATCHES \"ubuntu\")\n      set(AMDGPU_STATIC_LIB_PATHS \"-L/opt/amdgpu/lib/x86_64-linux-gnu\")\n  else()\n      set(AMDGPU_STATIC_LIB_PATHS \"-L/opt/amdgpu/lib64\" \"-L/opt/amdgpu/lib\")\n  endif()\n  # Link drm_amdgpu and drm library statically\n  target_link_libraries ( ${HSAKMT_STATIC_DRM_TARGET}\n    PRIVATE pthread rt c numa ${CMAKE_DL_LIBS}\n    INTERFACE -Wl,-Bstatic ${AMDGPU_STATIC_LIB_PATHS} ${DRM_AMDGPU_LDFLAGS} ${DRM_LDFLAGS} -Wl,-Bdynamic\n  )\n  target_compile_options(${HSAKMT_STATIC_DRM_TARGET} PRIVATE ${DRM_CFLAGS} ${HSAKMT_C_FLAGS})\n\n  install ( TARGETS ${HSAKMT_STATIC_DRM_TARGET} EXPORT ${HSAKMT_STATIC_DRM_TARGET}Targets\n            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary\n            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary)\n  install ( EXPORT ${HSAKMT_STATIC_DRM_TARGET}Targets\n    FILE ${HSAKMT_STATIC_DRM_TARGET}Targets.cmake\n    NAMESPACE ${HSAKMT_STATIC_DRM_TARGET}::\n    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${HSAKMT_TARGET}\n    COMPONENT dev)\n\n  add_library( ${HSAKMT_STATIC_DRM_TARGET}::${HSAKMT_STATIC_DRM_TARGET} ALIAS ${HSAKMT_STATIC_DRM_TARGET} )\nendif()\n\n###########################\n# Packaging directives\n###########################\n# Use component packaging\nset ( ENABLE_LDCONFIG ON CACHE BOOL \"Set library links and caches using ldconfig.\")\n"
  },
  {
    "path": "libhsakmt/DEBIAN/postinst.in",
    "content": "#!/bin/bash\n\nset -e\n\n# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build\ndo_ldconfig() {\n  if [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/x86_64-libhsakmt.conf\n    ldconfig\n  fi\n}\n\ncase \"$1\" in\n  ( configure )\n    do_ldconfig\n  ;;\n  ( abort-upgrade | abort-remove | abort-deconfigure )\n    echo \"$1\"\n  ;;\n  ( * )\n    exit 0\n  ;;\nesac\n"
  },
  {
    "path": "libhsakmt/DEBIAN/prerm.in",
    "content": "#!/bin/bash\n\nset -e\n\n# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build\nrm_ldconfig() {\n  if [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    rm -f /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/x86_64-libhsakmt.conf && ldconfig\n  fi\n}\n\ncase \"$1\" in\n  ( remove | upgrade )\n    rm_ldconfig\n  ;;\n  ( purge )\n  ;;\n  ( * )\n    exit 0\n  ;;\nesac\n"
  },
  {
    "path": "libhsakmt/LICENSE.md",
    "content": "ROCT-Thunk Interface LICENSE\n\nCopyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.\n\nMIT LICENSE:\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nThis product contains software provided by Nginx, Inc. and its contributors.\n\nCopyright (C) 2002-2018 Igor Sysoev\nCopyright (C) 2011-2018 Nginx, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n1. Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\nOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGE.\n"
  },
  {
    "path": "libhsakmt/README.md",
    "content": "# ROCt Library\n\nThis repository includes the user-mode API interfaces used to interact with the ROCk driver.\n\nStarting at 1.7 release, ROCt uses drm render device. This requires the user to belong to video group. Add the user account to video group with \"sudo usermod -a -G video _username_\" command if the user if not part of video group yet.\nNOTE: Users of Ubuntu 20.04 will need to add the user to the new \"render\" group, as Ubuntu has changed the owner:group of /dev/kfd to render:render as of that release\n\n## ROCk Driver\n\nThe ROCt library is not a standalone product and requires that you have the correct ROCk driver installed, or are using a compatible upstream kernel.\nPlease refer to <https://rocm.docs.amd.com> under \"Getting Started Guide\" for a list of supported Operating Systems and kernel versions, as well as supported hardware.\n\n## Building the Thunk\n\nA simple cmake-based system is available for building thunk. To build the thunk from the the ROCT-Thunk-Interface directory, execute:\n\n```bash\n    mkdir -p build\n    cd build\n    cmake ..\n    make\n```\n\nIf the hsakmt-roct and hsakmt-roct-dev packages are desired:\n\n```bash\n    mkdir -p build\n    cd build\n    cmake ..\n    make package\n```\n\nIf you choose not to build and install packages, manual installation of the binaries and header files can be done via:\n\n```bash\n    make install\n```\n\nNOTE: For older versions of the thunk where hsakmt-dev.txt is present, \"make package-dev\" and \"make install-dev\" are required to generate/install the developer packages. Currently, these are created via the \"make package\" and \"make install\" commands\n\n## Disclaimer\n\nThe information contained herein is for informational purposes only, and is subject to change without notice. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein. No license, including implied or arising by estoppel, to any intellectual property rights is granted by this document. Terms and limitations applicable to the purchase or use of AMD's products are as set forth in a signed agreement between the parties or in AMD's Standard Terms and Conditions of Sale.\n\nAMD, the AMD Arrow logo, and combinations thereof are trademarks of Advanced Micro Devices, Inc. Other product names used in this publication are for identification purposes only and may be trademarks of their respective companies.\n\nCopyright (c) 2014-2023 Advanced Micro Devices, Inc. All rights reserved.\n"
  },
  {
    "path": "libhsakmt/RPM/hsakmt-roct-devel.spec.in",
    "content": "# Restore old style debuginfo creation for rpm >= 4.14.\n%undefine _debugsource_packages\n%undefine _debuginfo_subpackages\n\n# -*- rpm-spec -*-\nBuildRoot:      %_topdir/@CPACK_PACKAGE_FILE_NAME@@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH@\nSummary:        @CPACK_RPM_PACKAGE_SUMMARY@\nName:           @CPACK_RPM_PACKAGE_NAME@\nVersion:        @CPACK_RPM_PACKAGE_VERSION@\nRelease:        @CPACK_RPM_PACKAGE_RELEASE@\nLicense:        @CPACK_RPM_PACKAGE_LICENSE@\nGroup:          @CPACK_RPM_PACKAGE_GROUP@\nVendor:         @CPACK_RPM_PACKAGE_VENDOR@\n\n@TMP_RPM_URL@\n@TMP_RPM_REQUIRES@\n@TMP_RPM_REQUIRES_PRE@\n@TMP_RPM_REQUIRES_POST@\n@TMP_RPM_REQUIRES_PREUN@\n@TMP_RPM_REQUIRES_POSTUN@\n@TMP_RPM_PROVIDES@\n@TMP_RPM_OBSOLETES@\n@TMP_RPM_CONFLICTS@\n@TMP_RPM_SUGGESTS@\n@TMP_RPM_AUTOPROV@\n@TMP_RPM_AUTOREQ@\n@TMP_RPM_AUTOREQPROV@\n@TMP_RPM_BUILDARCH@\n@TMP_RPM_PREFIXES@\n@TMP_RPM_EPOCH@\n\n# Modifications to allow recommends to be used (not implemented in cpack):\n%if \"@CPACK_RPM_PACKAGE_RECOMMENDS@\" != \"\"\nRecommends: @CPACK_RPM_PACKAGE_RECOMMENDS@\n%endif\n# End of modifications\n\n@TMP_RPM_DEBUGINFO@\n\n%define _rpmdir %_topdir/RPMS\n%define _srcrpmdir %_topdir/SRPMS\n@FILE_NAME_DEFINE@\n%define _unpackaged_files_terminate_build 0\n@TMP_RPM_SPEC_INSTALL_POST@\n@CPACK_RPM_SPEC_MORE_DEFINE@\n@CPACK_RPM_COMPRESSION_TYPE_TMP@\n\n%description\n@CPACK_RPM_PACKAGE_DESCRIPTION@\n\n# This is a shortcutted spec file generated by CMake RPM generator\n# we skip _install step because CPack does that for us.\n# We do only save CPack installed tree in _prepr\n# and then restore it in build.\n%prep\nmv $RPM_BUILD_ROOT %_topdir/tmpBBroot\n\n%install\nif [ -e $RPM_BUILD_ROOT ];\nthen\n  rm -rf $RPM_BUILD_ROOT\nfi\nmv %_topdir/tmpBBroot $RPM_BUILD_ROOT\n\n@TMP_RPM_DEBUGINFO_INSTALL@\n\n%clean\n\n%post\n@RPM_SYMLINK_POSTINSTALL@\n@CPACK_RPM_SPEC_POSTINSTALL@\n\n%posttrans\n@CPACK_RPM_SPEC_POSTTRANS@\n\n%postun\n@CPACK_RPM_SPEC_POSTUNINSTALL@\n\n%pre\n@CPACK_RPM_SPEC_PREINSTALL@\n\n%pretrans\n@CPACK_RPM_SPEC_PRETRANS@\n\n%preun\n@CPACK_RPM_SPEC_PREUNINSTALL@\n\n%files\n%defattr(@TMP_DEFAULT_FILE_PERMISSIONS@,@TMP_DEFAULT_USER@,@TMP_DEFAULT_GROUP@,@TMP_DEFAULT_DIR_PERMISSIONS@)\n@CPACK_RPM_INSTALL_FILES@\n@CPACK_RPM_ABSOLUTE_INSTALL_FILES@\n@CPACK_RPM_USER_INSTALL_FILES@\n\n%changelog\n@CPACK_RPM_SPEC_CHANGELOG@\n\n@TMP_OTHER_COMPONENTS@\n"
  },
  {
    "path": "libhsakmt/RPM/libhsakmt.spec",
    "content": "%define name        hsakmt-rocm-dev\n%define version     %{getenv:PACKAGE_VER}\n%define packageroot %{getenv:PACKAGE_DIR}\n\nName:       %{name}\nVersion:    %{version}\nRelease:    1\nSummary:    Thunk libraries for AMD KFD\n\nGroup:      System Environment/Libraries\nLicense:    Advanced Micro Devices Inc.\n\n%if 0%{?centos} == 6\nRequires:   numactl\n%else\nRequires:   numactl-libs\n%endif\n\n\n%description\nThis package includes the libhsakmt (Thunk) libraries\nfor AMD KFD\n\n%prep\n%setup -T -D -c -n %{name}\n\n%install\ncp -R %packageroot $RPM_BUILD_ROOT\nfind $RPM_BUILD_ROOT \\! -type d | sed \"s|$RPM_BUILD_ROOT||\"> thunk.list\n\n%post\nldconfig\n\n%postun\nldconfig\n\n%clean\nrm -rf $RPM_BUILD_ROOT\n\n%files -f thunk.list\n\n%defattr(-,root,root,-)\n"
  },
  {
    "path": "libhsakmt/RPM/post.in",
    "content": "# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build\nif [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n  echo -e \"@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@\" > /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/x86_64-libhsakmt.conf\n  ldconfig\nfi\n"
  },
  {
    "path": "libhsakmt/RPM/postun.in",
    "content": "# second term originates from ENABLE_LDCONFIG = ON/OFF at package build\nif [ $1 -le 1 ] && [ \"@ENABLE_LDCONFIG@\" == \"ON\" ]; then\n    # perform the below actions for rpm remove($1=0) or upgrade($1=1) operations\n    rm -f /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/x86_64-libhsakmt.conf\n    ldconfig\nfi\n"
  },
  {
    "path": "libhsakmt/cmake_modules/utils.cmake",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and#or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and#or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n## Parses the VERSION_STRING variable and places\n## the first, second and third number values in\n## the major, minor and patch variables.\nfunction( parse_version VERSION_STRING )\n\n    string ( FIND ${VERSION_STRING} \"-\" STRING_INDEX )\n\n    if ( ${STRING_INDEX} GREATER -1 )\n        math ( EXPR STRING_INDEX \"${STRING_INDEX} + 1\" )\n        string ( SUBSTRING ${VERSION_STRING} ${STRING_INDEX} -1 VERSION_BUILD )\n    endif ()\n\n    string ( REGEX MATCHALL \"[0123456789]+\" VERSIONS ${VERSION_STRING} )\n    list ( LENGTH VERSIONS VERSION_COUNT )\n\n    if ( ${VERSION_COUNT} GREATER 0)\n        list ( GET VERSIONS 0 MAJOR )\n        set ( VERSION_MAJOR ${MAJOR} PARENT_SCOPE )\n        set ( TEMP_VERSION_STRING \"${MAJOR}\" )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 1 )\n        list ( GET VERSIONS 1 MINOR )\n        set ( VERSION_MINOR ${MINOR} PARENT_SCOPE )\n        set ( TEMP_VERSION_STRING \"${TEMP_VERSION_STRING}.${MINOR}\" )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 2 )\n        list ( GET VERSIONS 2 PATCH )\n        set ( VERSION_PATCH ${PATCH} PARENT_SCOPE )\n        set ( TEMP_VERSION_STRING \"${TEMP_VERSION_STRING}.${PATCH}\" )\n    endif ()\n\n    if ( DEFINED VERSION_BUILD )\n        set ( VERSION_BUILD \"${VERSION_BUILD}\" PARENT_SCOPE )\n    endif ()\n\n    set ( VERSION_STRING \"${TEMP_VERSION_STRING}\" PARENT_SCOPE )\n\nendfunction ()\n\n## Gets the current version of the repository\n## using versioning tags and git describe.\n## Passes back a packaging version string\n## and a library version string.\nfunction ( get_version DEFAULT_VERSION_STRING )\n\n    parse_version ( ${DEFAULT_VERSION_STRING} )\n\n    find_program ( GIT NAMES git )\n\n    if ( GIT )\n\n        execute_process ( COMMAND git describe --tags --dirty --long\n                          WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                          OUTPUT_VARIABLE GIT_TAG_STRING\n                          OUTPUT_STRIP_TRAILING_WHITESPACE\n                          RESULT_VARIABLE RESULT )\n\n        if ( ${RESULT} EQUAL 0 )\n\n            parse_version ( ${GIT_TAG_STRING} )\n\n        endif ()\n\n    endif ()\n\n    set( VERSION_STRING \"${VERSION_STRING}\" PARENT_SCOPE )\n    set( VERSION_MAJOR  \"${VERSION_MAJOR}\" PARENT_SCOPE )\n    set( VERSION_MINOR  \"${VERSION_MINOR}\" PARENT_SCOPE )\n    set( VERSION_PATCH  \"${VERSION_PATCH}\" PARENT_SCOPE )\n    set( VERSION_BUILD  \"${VERSION_BUILD}\" PARENT_SCOPE )\n\nendfunction()\n\n#get the OS version\nfunction(get_os_info)\nif( EXISTS \"/etc/os-release\")\n    file(STRINGS \"/etc/os-release\" DISTRO_ID REGEX \"^ID=\")\n    file(STRINGS \"/etc/os-release\" DISTRO_RELEASE REGEX \"^VERSION_ID=\")\n    string(REPLACE \"ID=\" \"\" DISTRO_ID \"${DISTRO_ID}\")\n    string(REPLACE \"VERSION_ID=\" \"\" DISTRO_RELEASE \"${DISTRO_RELEASE}\")\n    message(STATUS \"Detected distribution: ${DISTRO_ID}:${DISTRO_RELEASE}\")\nelseif(EXISTS \"/etc/centos-release\" )\n    # Example: CentOS release 6.10 (Final)\n    file(STRINGS \"/etc/centos-release\" DISTRO_FULL_STR REGEX \"release\")\n    string(REGEX MATCH \"^[a-zA-Z]+\" DISTRO_ID \"${DISTRO_FULL_STR}\")\n    string(TOLOWER \"${DISTRO_ID}\" DISTRO_ID)\n    string(REGEX MATCH \"[0-9]+\" DISTRO_RELEASE \"${DISTRO_FULL_STR}\")\n    message(STATUS \"Detected distribution: ${DISTRO_ID}:${DISTRO_RELEASE}\")\nelse()\n     message(STATUS \"Not able to detect OS\")\nendif()\n    set(DISTRO_ID \"${DISTRO_ID}\" PARENT_SCOPE )\n    set(DISTRO_RELEASE \"${DISTRO_RELEASE}\" PARENT_SCOPE )\n\nendfunction()\n"
  },
  {
    "path": "libhsakmt/hsakmt-config.cmake.in",
    "content": "@PACKAGE_INIT@\n\ninclude( CMakeFindDependencyMacro )\n\n# Locate dependent packages here.  Finding them propagates usage requirements,\n# if any, to our clients and ensures that their target names are in scope for\n# the build.  hsakmt has no cmake project dependencies so there is nothing to\n# find.  If we switch to use find_package with external (to ROCm) library\n# dependencies (ie libnuma) then those packages should be located here using\n# find_dependencies as shown below.\n#find_dependency(Bar, 2.0)\n\n# If the option is ON link other dependent libraries dynamically\n# If the option is OFF, then link libdrm and libdrm_amdgpu statically\nif(@BUILD_SHARED_LIBS@)\n  include( \"${CMAKE_CURRENT_LIST_DIR}/@HSAKMT_TARGET@Targets.cmake\" )\nelse()\n  include( \"${CMAKE_CURRENT_LIST_DIR}/@HSAKMT_STATIC_DRM_TARGET@Targets.cmake\" )\nendif()\n"
  },
  {
    "path": "libhsakmt/include/hsakmt/hsakmt.h",
    "content": "/*\n * Copyright © 2024 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef _HSAKMT_H_\n#define _HSAKMT_H_\n\n#include \"hsakmttypes.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/**\n  \"Opens\" the HSA kernel driver for user-kernel mode communication.\n\n  On Windows, this function gets a handle to the KFD's AMDKFDIO device object that\n  is responsible for user-kernel communication, this handle is used internally by\n  the thunk library to send device I/O control to the HSA kernel driver.\n  No other thunk library function may be called unless the user-kernel communication\n  channel is opened first.\n\n  On Linux this call opens the \"/dev/kfd\" device file to establish a communication\n  path to the kernel.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtOpenKFD( void );\n\n/**\n  \"Closes\" the user-kernel communication path.\n\n  On Windows, the handle obtained by the hsaKmtOpenKFD() function is closed;\n  no other communication with the kernel driver is possible after the successful\n  execution of the saKmdCloseKFD() function. Depending on the failure reason,\n  the user-kernel communication path may or may not be still active.\n\n  On Linux the function closes the \"dev/kfd\" device file.\n  No further communication to the kernel driver is allowed until hsaKmtOpenKFD()\n  function is called again.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtCloseKFD( void );\n\n\n/**\n  Returns the user-kernel interface version supported by KFD.\n  Higher major numbers usually add new features to KFD and may break user-kernel\n  compatibility; higher minor numbers define additional functionality associated\n  within a major number.\n  The calling software should validate that it meets the minimum interface version\n  as described in the API specification.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetVersion(\n    HsaVersionInfo*  VersionInfo    //OUT\n    );\n\n/**\n  The function takes a \"snapshot\" of the topology information within the KFD\n  to avoid any changes during the enumeration process.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAcquireSystemProperties(\n    HsaSystemProperties*  SystemProperties    //OUT\n    );\n\n/**\n  Releases the topology \"snapshot\" taken by hsaKmtAcquireSystemProperties()\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtReleaseSystemProperties( void ) ;\n\n/**\n  Retrieves the discoverable sub-properties for a given HSA\n  node. The parameters returned allow the application or runtime to size the\n  management structures necessary to store the information.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetNodeProperties(\n    HSAuint32               NodeId,            //IN\n    HsaNodeProperties*      NodeProperties     //OUT\n    );\n\n/**\n  Retrieves the memory properties of a specific HSA node.\n  the memory pointer passed as MemoryProperties is sized as\n  NumBanks * sizeof(HsaMemoryProperties). NumBanks is retrieved with the\n  hsaKmtGetNodeProperties() call.\n\n  Some of the data returned is optional. Not all implementations may return all\n  parameters in the hsaMemoryProperties.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetNodeMemoryProperties(\n    HSAuint32             NodeId,             //IN\n    HSAuint32             NumBanks,           //IN\n    HsaMemoryProperties*  MemoryProperties    //OUT\n    );\n\n/**\n  Retrieves the cache properties of a specific HSA node and processor ID.\n  ProcessorID refers to either a CPU core or a SIMD unit as enumerated earlier\n  via the hsaKmtGetNodeProperties() call.\n  The memory pointer passed as CacheProperties is sized as\n  NumCaches * sizeof(HsaCacheProperties). NumCaches is retrieved with the\n  hsaKmtGetNodeProperties() call.\n\n  The data returned is optional. Not all implementations may return all\n  parameters in the CacheProperties.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetNodeCacheProperties(\n    HSAuint32           NodeId,         //IN\n    HSAuint32           ProcessorId,    //IN\n    HSAuint32           NumCaches,      //IN\n    HsaCacheProperties* CacheProperties //OUT\n    );\n\n/**\n  Retrieves the HSA IO affinity properties of a specific HSA node.\n  the memory pointer passed as Properties is sized as\n  NumIoLinks * sizeof(HsaIoLinkProperties). NumIoLinks is retrieved with the\n  hsaKmtGetNodeProperties() call.\n\n  The data returned is optional. Not all implementations may return all\n  parameters in the IoLinkProperties.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetNodeIoLinkProperties(\n    HSAuint32            NodeId,            //IN\n    HSAuint32            NumIoLinks,        //IN\n    HsaIoLinkProperties* IoLinkProperties  //OUT\n    );\n\n\n\n/**\n  Creates an operating system event associated with a HSA event ID\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtCreateEvent(\n    HsaEventDescriptor* EventDesc,              //IN\n    bool                ManualReset,            //IN\n    bool                IsSignaled,             //IN\n    HsaEvent**          Event                   //OUT\n    );\n\n/**\n  Destroys an operating system event associated with a HSA event ID\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDestroyEvent(\n    HsaEvent*   Event    //IN\n    );\n\n/**\n  Sets the specified event object to the signaled state\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSetEvent(\n    HsaEvent*  Event    //IN\n    );\n\n/**\n  Sets the specified event object to the non-signaled state\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtResetEvent(\n    HsaEvent*  Event    //IN\n    );\n\n/**\n  Queries the state of the specified event object\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtQueryEventState(\n    HsaEvent*  Event    //IN\n    );\n\n/**\n  Checks the current state of the event object. If the object's state is\n  nonsignaled, the calling thread enters the wait state.\n\n The function returns when one of the following occurs:\n- The specified event object is in the signaled state.\n- The time-out interval elapses.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtWaitOnEvent(\n    HsaEvent*   Event,          //IN\n    HSAuint32   Milliseconds    //IN\n    );\n\n/**\n  Checks the current state of the event object. If the object's state is\n  nonsignaled, the calling thread enters the wait state. event_age can\n  help avoiding race conditions.\n\n The function returns when one of the following occurs:\n- The specified event object is in the signaled state.\n- The time-out interval elapses.\n- Tracking event age\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtWaitOnEvent_Ext(\n    HsaEvent*   Event,          //IN\n    HSAuint32   Milliseconds,   //IN\n    uint64_t   *event_age       //IN/OUT\n    );\n\n/**\n  Checks the current state of multiple event objects.\n\n The function returns when one of the following occurs:\n- Either any one or all of the specified objects are in the signaled state\n  - if \"WaitOnAll\" is \"true\" the function returns when the state of all\n    objects in array is signaled\n  - if \"WaitOnAll\" is \"false\" the function returns when the state of any\n    one of the objects is set to signaled\n- The time-out interval elapses.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtWaitOnMultipleEvents(\n    HsaEvent*   Events[],       //IN\n    HSAuint32   NumEvents,      //IN\n    bool        WaitOnAll,      //IN\n    HSAuint32   Milliseconds    //IN\n    );\n\n/**\n  Checks the current state of multiple event objects.\n  event_age can help avoiding race conditions.\n\n The function returns when one of the following occurs:\n- Either any one or all of the specified objects are in the signaled state\n  - if \"WaitOnAll\" is \"true\" the function returns when the state of all\n    objects in array is signaled\n  - if \"WaitOnAll\" is \"false\" the function returns when the state of any\n    one of the objects is set to signaled\n- The time-out interval elapses.\n- Tracking event age\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtWaitOnMultipleEvents_Ext(\n    HsaEvent*   Events[],       //IN\n    HSAuint32   NumEvents,      //IN\n    bool        WaitOnAll,      //IN\n    HSAuint32   Milliseconds,   //IN\n    uint64_t   *event_age       //IN/OUT\n    );\n\n/**\n  new TEMPORARY function definition - to be used only on \"Triniti + Southern Islands\" platform\n  If used on other platforms the function will return HSAKMT_STATUS_ERROR\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtReportQueue(\n    HSA_QUEUEID     QueueId,        //IN\n    HsaQueueReport* QueueReport     //OUT\n    );\n\n/**\n  Creates a GPU queue with user-mode access rights\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtCreateQueue(\n    HSAuint32           NodeId,           //IN\n    HSA_QUEUE_TYPE      Type,             //IN\n    HSAuint32           QueuePercentage,  //IN\n    HSA_QUEUE_PRIORITY  Priority,         //IN\n    void*               QueueAddress,     //IN\n    HSAuint64           QueueSizeInBytes, //IN\n    HsaEvent*           Event,            //IN\n    HsaQueueResource*   QueueResource     //OUT\n    );\n\n/**\n  Creates a GPU queue with user-mode access rights\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtCreateQueueExt(\n    HSAuint32           NodeId,           //IN\n    HSA_QUEUE_TYPE      Type,             //IN\n    HSAuint32           QueuePercentage,  //IN\n    HSA_QUEUE_PRIORITY  Priority,         //IN\n    HSAuint32           SdmaEngineId,     //IN\n    void*               QueueAddress,     //IN\n    HSAuint64           QueueSizeInBytes, //IN\n    HsaEvent*           Event,            //IN\n    HsaQueueResource*   QueueResource     //OUT\n    );\n\n/**\n  Updates a queue\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtUpdateQueue(\n    HSA_QUEUEID         QueueId,        //IN\n    HSAuint32           QueuePercentage,//IN\n    HSA_QUEUE_PRIORITY  Priority,       //IN\n    void*               QueueAddress,   //IN\n    HSAuint64           QueueSize,      //IN\n    HsaEvent*           Event           //IN\n    );\n\n/**\n  Destroys a queue\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDestroyQueue(\n    HSA_QUEUEID         QueueId         //IN\n    );\n\n/**\n  Set cu mask for a queue\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSetQueueCUMask(\n    HSA_QUEUEID         QueueId,        //IN\n    HSAuint32           CUMaskCount,    //IN\n    HSAuint32*          QueueCUMask     //IN\n    );\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetQueueInfo(\n    HSA_QUEUEID QueueId,\t//IN\n    HsaQueueInfo *QueueInfo\t//IN\n);\n\n/**\n  Allows an HSA process to set/change the default and alternate memory coherency, before starting to dispatch. \n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSetMemoryPolicy(\n    HSAuint32       Node,                       //IN\n    HSAuint32       DefaultPolicy,     \t   \t    //IN  \n    HSAuint32       AlternatePolicy,       \t    //IN  \n    void*           MemoryAddressAlternate,     //IN (page-aligned)\n    HSAuint64       MemorySizeInBytes   \t    //IN (page-aligned)\n    );\n/**\n  Allocates a memory buffer that may be accessed by the GPU\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAllocMemory(\n    HSAuint32       PreferredNode,          //IN\n    HSAuint64       SizeInBytes,            //IN  (multiple of page size)\n    HsaMemFlags     MemFlags,               //IN\n    void**          MemoryAddress           //IN/OUT (page-aligned)\n    );\n\n/**\n  Allocates a memory buffer with specific alignment that may be accessed by the GPU\n  If Alignment is 0, the smallest possible alignment will be used\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAllocMemoryAlign(\n    HSAuint32       PreferredNode,          //IN\n    HSAuint64       SizeInBytes,            //IN  (multiple of page size)\n    HSAuint64       Alignment,              //IN  (power of 2 and >= page size)\n    HsaMemFlags     MemFlags,               //IN\n    void**          MemoryAddress           //IN/OUT (page-aligned)\n    );\n\n/**\n  Frees a memory buffer\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtFreeMemory(\n    void*       MemoryAddress,      //IN (page-aligned)\n    HSAuint64   SizeInBytes         //IN\n    );\n\n/**\n  Inquires memory available for allocation as a memory buffer\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAvailableMemory(\n    HSAuint32 Node,\n    HSAuint64 *AvailableBytes\n    );\n\n/**\n  Registers with KFD a memory buffer that may be accessed by the GPU\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterMemory(\n    void*       MemoryAddress,      //IN (cache-aligned)\n    HSAuint64   MemorySizeInBytes   //IN (cache-aligned)\n    );\n\n\n/**\n  Registers with KFD a memory buffer that may be accessed by specific GPUs\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterMemoryToNodes(\n    void        *MemoryAddress,     // IN (cache-aligned)\n    HSAuint64   MemorySizeInBytes,  // IN (cache-aligned)\n    HSAuint64   NumberOfNodes,      // IN\n    HSAuint32*  NodeArray           // IN\n    );\n\n\n/**\n  Registers with KFD a memory buffer with memory attributes\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterMemoryWithFlags(\n    void        *MemoryAddress,     // IN (cache-aligned)\n    HSAuint64   MemorySizeInBytes,  // IN (cache-aligned)\n    HsaMemFlags MemFlags            // IN\n    );\n\n/**\n  Registers with KFD a graphics buffer and returns graphics metadata\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterGraphicsHandleToNodes(\n    HSAuint64       GraphicsResourceHandle,        //IN\n    HsaGraphicsResourceInfo *GraphicsResourceInfo, //OUT\n    HSAuint64       NumberOfNodes,                 //IN\n    HSAuint32*      NodeArray                      //IN\n    );\n\n/**\n  Similar to hsaKmtRegisterGraphicsHandleToNodes but provides registration\n  options via RegisterFlags.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterGraphicsHandleToNodesExt(\n    HSAuint64       GraphicsResourceHandle,        //IN\n    HsaGraphicsResourceInfo *GraphicsResourceInfo, //OUT\n    HSAuint64       NumberOfNodes,                 //IN\n    HSAuint32*      NodeArray,                     //IN\n    HSA_REGISTER_MEM_FLAGS RegisterFlags           //IN\n    );\n\n/**\n * Export a dmabuf handle and offset for a given memory address\n *\n * Validates that @MemoryAddress belongs to a valid allocation and that the\n * @MemorySizeInBytes doesn't exceed the end of that allocation. Returns a\n * dmabuf fd of the allocation and the offset of MemoryAddress within that\n * allocation. The memory will remain allocated even after the allocation is\n * freed by hsaKmtFreeMemory for as long as a dmabuf fd remains open or any\n * importer of that fd maintains an active reference to the memory.\n */\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtExportDMABufHandle(\n    void *MemoryAddress,\t\t//IN\n    HSAuint64 MemorySizeInBytes,\t//IN\n    int *DMABufFd,\t\t\t//OUT\n    HSAuint64 *Offset\t\t\t//OUT\n    );\n\n/**\n Export a memory buffer for sharing with other processes\n\n NOTE: for the current revision of the thunk spec, SizeInBytes\n must match whole allocation.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtShareMemory(\n\tvoid                  *MemoryAddress,     // IN\n\tHSAuint64             SizeInBytes,        // IN\n\tHsaSharedMemoryHandle *SharedMemoryHandle // OUT\n);\n\n/**\n Register shared memory handle\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterSharedHandle(\n\tconst HsaSharedMemoryHandle *SharedMemoryHandle, // IN\n\tvoid                        **MemoryAddress,     // OUT\n\tHSAuint64                   *SizeInBytes         // OUT\n);\n\n/**\n Register shared memory handle to specific nodes only\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRegisterSharedHandleToNodes(\n\tconst HsaSharedMemoryHandle *SharedMemoryHandle, // IN\n\tvoid                        **MemoryAddress,     // OUT\n\tHSAuint64                   *SizeInBytes,        // OUT\n\tHSAuint64                   NumberOfNodes,       // OUT\n\tHSAuint32*                  NodeArray            // OUT\n);\n\n/**\n Copy data from the GPU address space of the process identified\n by Pid. Size Copied will return actual amount of data copied.\n If return is not SUCCESS, partial copies could have happened.\n */\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtProcessVMRead(\n\tHSAuint32                 Pid,                     // IN\n\tHsaMemoryRange            *LocalMemoryArray,       // IN\n\tHSAuint64                 LocalMemoryArrayCount,   // IN\n\tHsaMemoryRange            *RemoteMemoryArray,      // IN\n\tHSAuint64                 RemoteMemoryArrayCount,  // IN\n\tHSAuint64                 *SizeCopied              // OUT\n);\n\n/**\n Write data to the GPU address space of the process identified\n by Pid. See also hsaKmtProcessVMRead.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtProcessVMWrite(\n\tHSAuint32                 Pid,                     // IN\n\tHsaMemoryRange            *LocalMemoryArray,       // IN\n\tHSAuint64                 LocalMemoryArrayCount,   // IN\n\tHsaMemoryRange            *RemoteMemoryArray,      // IN\n\tHSAuint64                 RemoteMemoryArrayCount,  // IN\n\tHSAuint64                 *SizeCopied              // OUT\n);\n\n/**\n  Unregisters with KFD a memory buffer\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDeregisterMemory(\n    void*       MemoryAddress  //IN\n    );\n\n\n/**\n  Ensures that the memory is resident and can be accessed by GPU\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtMapMemoryToGPU(\n    void*           MemoryAddress,     //IN (page-aligned)\n    HSAuint64       MemorySizeInBytes, //IN (page-aligned)\n    HSAuint64*      AlternateVAGPU     //OUT (page-aligned)     \n    );\n\n/**\n  Ensures that the memory is resident and can be accessed by GPUs\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtMapMemoryToGPUNodes(\n    void*           MemoryAddress,         //IN (page-aligned)\n    HSAuint64       MemorySizeInBytes,     //IN (page-aligned)\n    HSAuint64*      AlternateVAGPU,        //OUT (page-aligned)\n    HsaMemMapFlags  MemMapFlags,           //IN\n    HSAuint64       NumberOfNodes,         //IN\n    HSAuint32*      NodeArray              //IN\n    );\n\n/**\n  Releases the residency of the memory\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtUnmapMemoryToGPU(\n    void*           MemoryAddress       //IN (page-aligned)\n    );\n\n\n/**\n  Notifies the kernel driver that a process wants to use GPU debugging facilities\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtMapGraphicHandle(\n                HSAuint32          NodeId,                              //IN\n                HSAuint64          GraphicDeviceHandle,                 //IN\n                HSAuint64          GraphicResourceHandle,               //IN\n                HSAuint64          GraphicResourceOffset,               //IN\n                HSAuint64          GraphicResourceSize,                 //IN\n                HSAuint64*         FlatMemoryAddress            //OUT\n                );\n\n\n/**\n  Stub for Unmap Graphic Handle\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtUnmapGraphicHandle(\n                HSAuint32          NodeId,                      //IN\n                HSAuint64          FlatMemoryAddress,           //IN\n                HSAuint64              SizeInBytes              //IN\n                );\n\n/**\n * Get an AMDGPU device handle for a GPU node\n */\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetAMDGPUDeviceHandle(\n                HSAuint32               NodeId,                    //IN\n                HsaAMDGPUDeviceHandle   *DeviceHandle              //OUT\n                );\n\n/**\n  Allocate GWS resource for a queue\n */\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAllocQueueGWS(\n                HSA_QUEUEID        QueueId,                     //IN\n                HSAuint32          nGWS,                        //IN\n                HSAuint32          *firstGWS                    //OUT\n                );\n\n/**\n  Notifies the kernel driver that a process wants to use GPU debugging facilities\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgRegister(\n    HSAuint32       NodeId      //IN\n    );\n\n/**\n  Detaches the debugger process from the HW debug established by hsaKmtDbgRegister() API\n*/\n\nHSAKMT_STATUS \nHSAKMTAPI \nhsaKmtDbgUnregister(\n    HSAuint32       NodeId      //IN\n    );\n\n/**\n  Controls a wavefront\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgWavefrontControl(\n    HSAuint32           NodeId,         //IN\n    HSA_DBG_WAVEOP      Operand,        //IN\n    HSA_DBG_WAVEMODE    Mode,           //IN\n    HSAuint32           TrapId,         //IN\n    HsaDbgWaveMessage*  DbgWaveMsgRing  //IN\n    );\n\n/**\n  Sets watch points on memory address ranges to generate exception events when the\n  watched addresses are  accessed\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgAddressWatch(\n    HSAuint32           NodeId,         //IN\n    HSAuint32           NumWatchPoints, //IN\n    HSA_DBG_WATCH_MODE  WatchMode[],    //IN\n    void*               WatchAddress[], //IN\n    HSAuint64           WatchMask[],    //IN, optional\n    HsaEvent*           WatchEvent[]    //IN, optional\n    );\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRuntimeEnable(\n    void*     rDebug,    // IN\n    bool      setupTtmp\n    );\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtRuntimeDisable(void);\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetRuntimeCapabilities(\n    HSAuint32\t*caps_mask // OUT\n    );\n\n/**\n  Enable debug trap.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgEnable(\n    void **runtime_info, //Out\n    HSAuint32 *data_size //Out\n    );\n\n/**\n  Disable debug trap.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgDisable(void);\n\n/**\n  Get device snapshot.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgGetDeviceData(\n    void **data, //Out\n    HSAuint32 *n_entries, //Out\n    HSAuint32 *entry_size //Out\n    );\n\n/**\n  Get queues snapshot.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtDbgGetQueueData(\n    void **data, //Out\n    HSAuint32 *n_entries, //Out\n    HSAuint32 *entry_size, //Out\n    bool suspend_queues //In\n    );\n\n/**   \n  Check whether gpu firmware and kernel support debugging\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtCheckRuntimeDebugSupport(\n    void\n    );\n\n/**\n  Debug ops call primarily used for KFD testing\n */\nHSAKMT_STATUS HSAKMTAPI hsaKmtDebugTrapIoctl(\n    struct kfd_ioctl_dbg_trap_args *arg,\n    HSA_QUEUEID *Queues,\n    HSAuint64 *DebugReturn\n    );\n\n/**\n  Gets GPU and CPU clock counters for particular Node\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetClockCounters(\n    HSAuint32         NodeId,  //IN\n    HsaClockCounters* Counters //OUT\n    );\n\n/**\n  Retrieves information on the available HSA counters\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcGetCounterProperties(\n    HSAuint32                   NodeId,             //IN\n    HsaCounterProperties**      CounterProperties   //OUT\n    );\n\n/**\n  Registers a set of (HW) counters to be used for tracing/profiling\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcRegisterTrace(\n    HSAuint32           NodeId,             //IN\n    HSAuint32           NumberOfCounters,   //IN\n    HsaCounter*         Counters,           //IN\n    HsaPmcTraceRoot*    TraceRoot           //OUT\n    );\n\n/**\n  Unregisters a set of (HW) counters used for tracing/profiling\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcUnregisterTrace(\n    HSAuint32   NodeId,     //IN\n    HSATraceId  TraceId     //IN\n    );\n\n/**\n  Allows a user mode process to get exclusive access to the defined set of (HW) counters\n  used for tracing/profiling\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcAcquireTraceAccess(\n    HSAuint32   NodeId,     //IN\n    HSATraceId  TraceId     //IN\n    );\n\n/**\n  Allows a user mode process to release exclusive access to the defined set of (HW) counters\n  used for tracing/profiling\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcReleaseTraceAccess(\n    HSAuint32   NodeId,     //IN\n    HSATraceId  TraceId     //IN\n    );\n\n/**\n  Starts tracing operation on a previously established set of performance counters\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcStartTrace(\n    HSATraceId  TraceId,                //IN\n    void*       TraceBuffer,            //IN (page aligned) \n    HSAuint64   TraceBufferSizeBytes    //IN (page aligned)\n    );\n\n/**\n   Forces an update of all the counters that a previously started trace operation has registered\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcQueryTrace(\n    HSATraceId    TraceId   //IN\n    );\n\n/**\n  Stops tracing operation on a previously established set of performance counters\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPmcStopTrace(\n    HSATraceId  TraceId     //IN\n    );\n\n/**\n  Sets trap handler and trap buffer to be used for all queues associated with the specified NodeId within this process context\n*/\n\nHSAKMT_STATUS \nHSAKMTAPI \nhsaKmtSetTrapHandler(\n    HSAuint32           NodeId,                   //IN\n    void*               TrapHandlerBaseAddress,   //IN\n    HSAuint64           TrapHandlerSizeInBytes,   //IN\n    void*               TrapBufferBaseAddress,    //IN\n    HSAuint64           TrapBufferSizeInBytes     //IN\n    );\n\n/**\n  Gets image tile configuration.\n */\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetTileConfig(\n    HSAuint32           NodeId,     // IN\n    HsaGpuTileConfig*   config      // IN & OUT\n    );\n\n/**\n  Returns information about pointers\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtQueryPointerInfo(\n    const void *        Pointer,        //IN\n    HsaPointerInfo *    PointerInfo     //OUT\n    );\n\n/**\n  Associates user data with a memory allocation\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSetMemoryUserData(\n    const void *    Pointer,    //IN\n    void *          UserData    //IN\n    );\n\n/**\n  Acquire request exclusive use of SPM\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSPMAcquire(\n    HSAuint32\tPreferredNode\t//IN\n    );\n\n\n/**\n  Release exclusive use of SPM\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSPMRelease(\n    HSAuint32\tPreferredNode\t//IN\n    );\n\n/**\n   Set up the destination user mode buffer for stream performance\n   counter data.\n*/\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSPMSetDestBuffer(\n\tHSAuint32   PreferredNode,\t\t//IN\n\tHSAuint32   SizeInBytes,\t\t//IN\n\tHSAuint32   * timeout,\t\t\t//IN/OUT\n\tHSAuint32   * SizeCopied,\t\t//OUT\n\tvoid        *DestMemoryAddress,\t\t//IN\n\tbool        *isSPMDataLoss\t\t//OUT\n    );\n\n/* Helper functions for calling KFD SVM ioctl */\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSVMSetAttr(\n    void *start_addr,   // IN: Start of the virtual address range (page-aligned)\n    HSAuint64 size,     // IN: size (page-aligned)\n    unsigned int nattr, // IN: number of attributes\n    HSA_SVM_ATTRIBUTE *attrs  // IN: array of attributes\n);\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSVMGetAttr(\n    void *start_addr,   // IN: Start of the virtual address range (page-aligned)\n    HSAuint64 size,     // IN: size (page aligned)\n    unsigned int nattr, // IN: number of attributes\n    HSA_SVM_ATTRIBUTE *attrs  // IN/OUT: array of attributes\n);\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtSetXNACKMode(\n    HSAint32 enable  // IN: enable/disable XNACK node.\n);\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetXNACKMode(\n    HSAint32 * enable  // OUT: returns XNACK value.\n);\n\n/**\n   Open anonymous file handle to enable events and read SMI events.\n\n   To enable events, write 64bit events mask to fd, event enums as bit index.\n   for example, event mask (HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_INDEX_MAX) - 1) to enable all events\n\n   Read event from fd is not blocking, use poll with timeout value to check if event is available.\n   Event is dropped if kernel event fifo is full.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtOpenSMI(\n    HSAuint32 NodeId,   // IN: GPU node_id to receive the SMI event from\n    int *fd             // OUT: anonymous file handle\n);\n\n/**\n   If this is GPU Mapped memory, remap the first page at this address to be normal system memory\n\n   This is used in ASAN mode to remap the first page of device memory to share host ASAN logic.\n   This function is only supported when libhsakmt is compiled in ASAN mode.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtReplaceAsanHeaderPage(\n    void *addr     // IN: Start of othe virtual address page\n);\n\n/**\n   If this is GPU Mapped memory, remap the first page back to the original GPU memory\n\n   This is used in ASAN mode to remap the first page back to its original mapping.\n   This function is only supported when libhsakmt is compiled in ASAN mode.\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtReturnAsanHeaderPage(\n    void *addr     // IN: Start of othe virtual address page\n);\n\n/**\n   Check whether kernel support pc sampling\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingSupport(\n    void\n);\n\n/**\n * Query device PC Sampling capabilities\n *\n *  Arguments:\n *   @NodeId        (IN) - GPU node_id\n *   @sample_info   (IN) - Pointer to array of HSAPcSamplingInfo\n *   @sample_info_sz(IN) - Size of sampling_info in units of HSAPcSamplingInfo\n *   @sz_needed     (OUT)- If sampling_info_sz is too small, sample_info_sz needed\n *\n *  Return:\n *   HSAKMT_STATUS_ERROR             - failed\n *   HSAKMT_STATUS_SUCCESS           - successfully complete\n *   HSAKMT_STATUS_INVALID_PARAMETER - invalid input\n *   HSAKMT_STATUS_BUFFER_TOO_SMALL  - sample buffer size is too small. Retry with sample_info_sz\n *                                     >= sz_needed\n *   HSAKMT_STATUS_NOT_SUPPORTED     - this asic doesn't support pc sampling\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingQueryCapabilities(\n    HSAuint32 NodeId,\n    void *sample_info,\n    HSAuint32 sample_info_sz,\n    HSAuint32 *sz_needed\n);\n\n/**\n * Create PC Sampling Session\n *\n *  Arguments:\n *   @NodeId     (IN)  - GPU node_id\n *   @sample_info(IN)  - PC Sampling configuration requested\n *   @traceId    (OUT) - Unique PC Sampling trace Id\n *\n *  Return:\n *   HSAKMT_STATUS_ERROR             - failed\n *   HSAKMT_STATUS_SUCCESS           - successfully complete\n *   HSAKMT_STATUS_INVALID_PARAMETER - invalid input\n *   HSAKMT_STATUS_NO_MEMORY         - not enough memory to create new pc sampling session\n *   HSAKMT_STATUS_UNAVAILABLE       - a different pc sampling session started on this node\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingCreate(\n  HSAuint32 node_id,\n  HsaPcSamplingInfo *sample_info,\n  HsaPcSamplingTraceId *traceId\n);\n\n/**\n * Destroy PC Sampling Session\n *\n *  Arguments:\n *   @NodeId (IN) - GPU node_id\n *   @traceId(IN) - PC Sampling trace Id\n *\n *  Return:\n *   HSAKMT_STATUS_ERROR             - failed\n *   HSAKMT_STATUS_SUCCESS           - successfully complete\n *   HSAKMT_STATUS_INVALID_PARAMETER - invalid input\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingDestroy(\n    HSAuint32 NodeId,\n    HsaPcSamplingTraceId traceId\n);\n\n/**\n * Start PC Sampling Session\n *\n *  Arguments:\n *   @NodeId (IN) - GPU node_id\n *   @traceId(IN) - PC Sampling trace Id\n *\n *  Return:\n *   HSAKMT_STATUS_ERROR             - failed\n *   HSAKMT_STATUS_SUCCESS           - successfully complete\n *   HSAKMT_STATUS_INVALID_PARAMETER - invalid input\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingStart(\n    HSAuint32 NodeId,\n    HsaPcSamplingTraceId traceId\n);\n\n/**\n * Stop PC Sampling Session\n *\n *  Arguments:\n *   @NodeId (IN) - GPU node_id\n *   @traceId(IN) - PC Sampling trace Id\n *\n *  Return:\n *   HSAKMT_STATUS_ERROR                 - failed\n *   HSAKMT_STATUS_SUCCESS               - successfully complete\n *   HSAKMT_STATUS_INVALID_PARAMETER     - invalid input\n *   HSAKMT_STATUS_KERNEL_ALREADY_OPENED - stop already\n*/\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtPcSamplingStop(\n    HSAuint32 NodeId,\n    HsaPcSamplingTraceId traceId\n);\n\n/**\n * Check if the HSA KMT Model is enabled\n * \n *  Arguments:\n *   @enable (OUT) - true if the HSA KMT Model is enabled, false otherwise\n * \n *  Return:\n *   HSAKMT_STATUS_ERROR             - failed\n *   HSAKMT_STATUS_SUCCESS           - successfully complete\n */\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtModelEnabled(\n    bool* enable // OUT\n);\n\n#ifdef __cplusplus\n}   //extern \"C\"\n#endif\n\n#endif //_HSAKMT_H_\n"
  },
  {
    "path": "libhsakmt/include/hsakmt/hsakmt_virtio.h",
    "content": "/*\n * Copyright © 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef HSAKMT_VIRTIO_H\n#define HSAKMT_VIRTIO_H\n\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"hsakmt/hsakmt.h\"\n#include <libdrm/amdgpu.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtOpenKFD(void);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCloseKFD(void);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAllocMemory(HSAuint32 PreferredNode, HSAuint64 SizeInBytes,\n                                           HsaMemFlags MemFlags, void** MemoryAddress);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtFreeMemory(void* MemoryAddress, HSAuint64 SizeInBytes);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtMapMemoryToGPUNodes(void* MemoryAddress, HSAuint64 MemorySizeInBytes,\n                                                   HSAuint64* AlternateVAGPU,\n                                                   HsaMemMapFlags MemMapFlags,\n                                                   HSAuint64 NumberOfNodes, HSAuint32* NodeArray);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtUnmapMemoryToGPU(void* MemoryAddress);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAvailableMemory(HSAuint32 Node, HSAuint64* AvailableBytes);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtMapMemoryToGPU(void* MemoryAddress, HSAuint64 MemorySizeInBytes,\n                                              HSAuint64* AlternateVAGPU);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRegisterMemoryWithFlags(void* MemoryAddress,\n                                                       HSAuint64 MemorySizeInBytes,\n                                                       HsaMemFlags MemFlags);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDeregisterMemory(void* MemoryAddress);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetVersion(HsaVersionInfo* v);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAcquireSystemProperties(HsaSystemProperties* SystemProperties);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtReleaseSystemProperties(void);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeProperties(HSAuint32 NodeId,\n                                                 HsaNodeProperties* NodeProperties);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetXNACKMode(HSAint32* enable);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRuntimeEnable(void* rDebug, bool setupTtmp);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRuntimeDisable(void);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeMemoryProperties(HSAuint32 NodeId, HSAuint32 NumBanks,\n                                                       HsaMemoryProperties* MemoryProperties);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeCacheProperties(HSAuint32 NodeId, HSAuint32 ProcessorId,\n                                                      HSAuint32 NumCaches,\n                                                      HsaCacheProperties* CacheProperties);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeIoLinkProperties(HSAuint32 NodeId, HSAuint32 NumIoLinks,\n                                                       HsaIoLinkProperties* IoLinkProperties);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetClockCounters(HSAuint32 NodeId, HsaClockCounters* Counters);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetAMDGPUDeviceHandle(HSAuint32 NodeId,\n                                                     HsaAMDGPUDeviceHandle* DeviceHandle);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtQueryPointerInfo(const void* Pointer, HsaPointerInfo* PointerInfo);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetTileConfig(HSAuint32 NodeId, HsaGpuTileConfig* config);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateEvent(HsaEventDescriptor* EventDesc, _Bool ManualReset,\n                                           _Bool IsSignaled, HsaEvent** Event);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDestroyEvent(HsaEvent* Event);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtSetEvent(HsaEvent* Event);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtResetEvent(HsaEvent* Event);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtQueryEventState(HsaEvent* Event);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnMultipleEvents(HsaEvent* Events[], HSAuint32 NumEvents,\n                                                    bool WaitOnAll, HSAuint32 Milliseconds);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnEvent(HsaEvent* Event, HSAuint32 Milliseconds);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnEvent_Ext(HsaEvent* Event, HSAuint32 Milliseconds,\n                                               uint64_t* event_age);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnMultipleEvents_Ext(HsaEvent* Events[], HSAuint32 NumEvents,\n                                                        bool WaitOnAll, HSAuint32 Milliseconds,\n                                                        uint64_t* event_age);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtSetTrapHandler(HSAuint32 NodeId, void* TrapHandlerBaseAddress,\n                                              HSAuint64 TrapHandlerSizeInBytes,\n                                              void* TrapBufferBaseAddress,\n                                              HSAuint64 TrapBufferSizeInBytes);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateQueueExt(HSAuint32 NodeId, HSA_QUEUE_TYPE Type,\n                                              HSAuint32 QueuePercentage,\n                                              HSA_QUEUE_PRIORITY Priority, HSAuint32 SdmaEngineId,\n                                              void* QueueAddress, HSAuint64 QueueSizeInBytes,\n                                              HsaEvent* Event, HsaQueueResource* QueueResource);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateQueue(HSAuint32 NodeId, HSA_QUEUE_TYPE Type,\n                                           HSAuint32 QueuePercentage, HSA_QUEUE_PRIORITY Priority,\n                                           void* QueueAddress, HSAuint64 QueueSizeInBytes,\n                                           HsaEvent* Event, HsaQueueResource* QueueResource);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDestroyQueue(HSA_QUEUEID QueueId);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRegisterGraphicsHandleToNodes(\n    HSAuint64 GraphicsResourceHandle, HsaGraphicsResourceInfo* GraphicsResourceInfo,\n    HSAuint64 NumberOfNodes, HSAuint32* NodeArray);\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetRuntimeCapabilities(HSAuint32* caps_mask);\n\nint vamdgpu_query_gpu_info(amdgpu_device_handle dev, void* out);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* HSAKMT_VIRTIO_H */\n"
  },
  {
    "path": "libhsakmt/include/hsakmt/hsakmtmodel.h",
    "content": "/*\n * Copyright © 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef _HSAKMTMODEL_H_\n#define _HSAKMTMODEL_H_\n#include <stdbool.h>\nextern bool hsakmt_use_model;\nextern char *hsakmt_model_topology;\nvoid model_init_env_vars(void);\nvoid model_init(void);\nvoid model_set_mmio_page(void *ptr);\nvoid model_set_event_page(void *ptr, unsigned event_limit);\nint model_kfd_ioctl(unsigned long request, void *arg);\n#endif /* _HSAKMTMODEL_H_ */"
  },
  {
    "path": "libhsakmt/include/hsakmt/hsakmtmodeliface.h",
    "content": "/*\n * Copyright © 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef _HSAKMTMODELIFACE_H_\n#define _HSAKMTMODELIFACE_H_\n\n#include <inttypes.h>\n\n// Changelog:\n//  0.2: Add set_set_event function to hsakmt_model_functions\n#define HSAKMT_MODEL_INTERFACE_VERSION_MAJOR 0\n#define HSAKMT_MODEL_INTERFACE_VERSION_MINOR 4\n\ntypedef struct hsakmt_model hsakmt_model_t;\ntypedef struct hsakmt_model_queue hsakmt_model_queue_t;\n\n// Description of a queue to be registered with the model.\n//\n// Addresses are relative to the global aperture.\nstruct hsakmt_model_queue_info {\n\tuint64_t ring_base_address;\n\tuint64_t write_pointer_address;\n\tuint64_t read_pointer_address;\n\n\tuint64_t *doorbell;\n\n\tuint32_t ring_size; // in bytes\n\tuint32_t queue_type;\n};\n\n// Pointer to a \"set event\" function.\n//\n// data is a user-provided opaque pointer.\n// event_id is the ID of the event to set (as in amd_signal_s::event_id).\ntypedef void (*hsakmt_model_set_event_fn)(void *data, unsigned event_id);\n\n// Interface provided by the software model implementation.\n//\n// Queried from a shared library by calling an export called\n// `get_hsakmt_model_functions`\n//\n// Interface versioning follows the semantic versioning model: clients that\n// know about interface version X.Y can use any implementation that provides\n// version X.Z with Z >= Y.\n//\n// The model is designed to support only one VMID space.\nstruct hsakmt_model_functions {\n\tuint32_t version_major; // HSAKMT_MODEL_INTERFACE_VERSION_MAJOR\n\tuint32_t version_minor; // HSAKMT_MODEL_INTERFACE_VERSION_MINOR\n\n\t// Create a GPU device model.\n\thsakmt_model_t *(*create)(void);\n\n\t// Destroy a GPU device model.\n\tvoid (*destroy)(hsakmt_model_t *model);\n\n\t// Set the global aperture. GPU virtual address 0 is at CPU address `base`.\n\tvoid (*set_global_aperture)(hsakmt_model_t *model, void *base, uint64_t size);\n\tvoid (*alloced_memory)(hsakmt_model_t *model, void *base, uint64_t size, uint32_t flags);\n\tvoid (*freed_memory)(hsakmt_model_t *model, void *base, uint64_t size);\n\t// Register a callback that the model should call when an event is signaled.\n\t// `data` is client data that is opaque to the model.\n\t//\n\t// TODO: Deprecated -- remove this!\n\tvoid (*set_notify_event)(hsakmt_model_t *model, void (*callback)(void *data), void *data);\n\n\t// Register a callback that the model should call in order to wait for an\n\t// event to be signaled.\n\t// `data` is client data that is opaque to the model.\n\tvoid (*set_wait_event)(hsakmt_model_t *model, void (*callback)(void *data, uint64_t address, uint64_t age), void *data);\n\n\t// Register a queue with the model. The model will immediately begin\n\t// asynchronous processing of the queue (but by default, the model need not\n\t// provide forward progress guarantees between multiple queues).\n\thsakmt_model_queue_t *(*register_queue)(hsakmt_model_t *model, struct hsakmt_model_queue_info *info);\n\n\t// Register a callback that allows the model to set an event.\n\tvoid (*set_set_event)(hsakmt_model_t *model, hsakmt_model_set_event_fn fn, void *data);\n\n\t// Destroy a queue that was returned by register_queue.\n\tvoid (*destroy_queue)(hsakmt_model_t *model, hsakmt_model_queue_t *queue);\n};\n\n// Type of a shared library export called `get_hsakmt_model_functions`.\ntypedef const struct hsakmt_model_functions *(*get_hsakmt_model_functions_t)(void);\n\n#endif // _HSAKMTMODELIFACE_H_"
  },
  {
    "path": "libhsakmt/include/hsakmt/hsakmttypes.h",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef _HSAKMTTYPES_H_\n#define _HSAKMTTYPES_H_\n\n//the definitions and THUNK API are version specific - define the version numbers here\n#define HSAKMT_VERSION_MAJOR    0\n#define HSAKMT_VERSION_MINOR    99\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(_WIN64) || defined(_WINDOWS) || defined(_WIN32)\n\n    #if defined(_WIN32)\n        #define HSAKMTAPI  __stdcall\n    #else\n        #define HSAKMTAPI\n    #endif\n\n    typedef unsigned char      HSAuint8;\n    typedef char               HSAint8;\n    typedef unsigned short     HSAuint16;\n    typedef signed short       HSAint16;\n    typedef unsigned __int32   HSAuint32;\n    typedef signed __int32     HSAint32;\n    typedef signed __int64     HSAint64;\n    typedef unsigned __int64   HSAuint64;\n\n#elif defined(__linux__)\n\n#include <stdbool.h>\n#include <stdint.h>\n\n    #define HSAKMTAPI\n\n    typedef uint8_t     HSAuint8;\n    typedef int8_t      HSAint8;\n    typedef uint16_t\tHSAuint16;\n    typedef int16_t\tHSAint16;\n    typedef uint32_t\tHSAuint32;\n    typedef int32_t \tHSAint32;\n    typedef int64_t\tHSAint64;\n    typedef uint64_t\tHSAuint64;\n\n#endif\n\ntypedef void*              HSA_HANDLE;\ntypedef HSAuint64          HSA_QUEUEID;\n// An HSA_QUEUEID that is never a valid queue ID.\n#define INVALID_QUEUEID 0xFFFFFFFFFFFFFFFFULL\n\n// A PID that is never a valid process ID.\n#define INVALID_PID 0xFFFFFFFF\n\n// // A HSA_NODEID that is never a valid node ID.\n#define INVALID_NODEID 0xFFFFFFFF\n\n// This is included in order to force the alignments to be 4 bytes so that\n// it avoids extra padding added by the compiler when a 64-bit binary is generated.\n#pragma pack(push, hsakmttypes_h, 4)\n\n//\n// HSA STATUS codes returned by the KFD Interfaces\n//\n\ntypedef enum _HSAKMT_STATUS\n{\n    HSAKMT_STATUS_SUCCESS                      = 0,  // Operation successful\n    HSAKMT_STATUS_ERROR                        = 1,  // General error return if not otherwise specified\n    HSAKMT_STATUS_DRIVER_MISMATCH              = 2,  // User mode component is not compatible with kernel HSA driver\n\n    HSAKMT_STATUS_INVALID_PARAMETER            = 3,  // KFD identifies input parameters invalid\n    HSAKMT_STATUS_INVALID_HANDLE               = 4,  // KFD identifies handle parameter invalid\n    HSAKMT_STATUS_INVALID_NODE_UNIT            = 5,  // KFD identifies node or unit parameter invalid\n\n    HSAKMT_STATUS_NO_MEMORY                    = 6,  // No memory available (when allocating queues or memory)\n    HSAKMT_STATUS_BUFFER_TOO_SMALL             = 7,  // A buffer needed to handle a request is too small\n\n    HSAKMT_STATUS_NOT_IMPLEMENTED              = 10, // KFD function is not implemented for this set of paramters\n    HSAKMT_STATUS_NOT_SUPPORTED                = 11, // KFD function is not supported on this node\n    HSAKMT_STATUS_UNAVAILABLE                  = 12, // KFD function is not available currently on this node (but\n                                                     // may be at a later time)\n    HSAKMT_STATUS_OUT_OF_RESOURCES             = 13, // KFD function request exceeds the resources currently available.\n\n    HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED = 20, // KFD driver path not opened\n    HSAKMT_STATUS_KERNEL_COMMUNICATION_ERROR   = 21, // user-kernel mode communication failure\n    HSAKMT_STATUS_KERNEL_ALREADY_OPENED        = 22, // KFD driver path already opened\n    HSAKMT_STATUS_HSAMMU_UNAVAILABLE           = 23, // ATS/PRI 1.1 (Address Translation Services) not available\n                                                     // (IOMMU driver not installed or not-available)\n\n    HSAKMT_STATUS_WAIT_FAILURE                 = 30, // The wait operation failed\n    HSAKMT_STATUS_WAIT_TIMEOUT                 = 31, // The wait operation timed out\n\n    HSAKMT_STATUS_MEMORY_ALREADY_REGISTERED    = 35, // Memory buffer already registered\n    HSAKMT_STATUS_MEMORY_NOT_REGISTERED        = 36, // Memory buffer not registered\n    HSAKMT_STATUS_MEMORY_ALIGNMENT             = 37, // Memory parameter not aligned\n\n} HSAKMT_STATUS;\n\n//\n// HSA KFD interface version information. Calling software has to validate that it meets\n// the minimum interface version as described in the API specification.\n// All future structures will be extended in a backward compatible fashion.\n//\n\ntypedef struct _HsaVersionInfo\n{\n    HSAuint32    KernelInterfaceMajorVersion;    // supported kernel interface major version\n    HSAuint32    KernelInterfaceMinorVersion;    // supported kernel interface minor version\n} HsaVersionInfo;\n\n//\n// HSA Topology Discovery Infrastructure structure definitions.\n// The infrastructure implementation is based on design specified in the Kernel HSA Driver ADD\n// The discoverable data is retrieved from ACPI structures in the platform infrastructure, as defined\n// in the \"Heterogeneous System Architecture Detail Topology\" specification.\n//\n// The following structure is returned on a call to hsaKmtAcquireSystemProperties() as output.\n// When the call is made within a process context, a \"snapshot\" of the topology information\n// is taken within the KFD to avoid any changes during the enumeration process.\n// The Snapshot is released when hsaKmtReleaseSystemProperties() is called\n// or when the process exits or is terminated.\n//\n\ntypedef struct _HsaSystemProperties\n{\n    HSAuint32    NumNodes;         // the number of \"H-NUMA\" memory nodes.\n                                   // each node represents a discoverable node of the system\n                                   // All other enumeration is done on a per-node basis\n\n    HSAuint32    PlatformOem;      // identifies HSA platform, reflects the OEMID in the CRAT\n    HSAuint32    PlatformId;       // HSA platform ID, reflects OEM TableID in the CRAT\n    HSAuint32    PlatformRev;      // HSA platform revision, reflects Platform Table Revision ID\n} HsaSystemProperties;\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int uCode    : 10;  // ucode packet processor version\n        unsigned int Major    :  6;  // GFXIP Major engine version\n        unsigned int Minor    :  8;  // GFXIP Minor engine version\n        unsigned int Stepping :  8;  // GFXIP Stepping info\n    }ui32;\n} HSA_ENGINE_ID;\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int uCodeSDMA: 10; // ucode version SDMA engine\n        unsigned int uCodeRes : 10; // ucode version (reserved)\n        unsigned int Reserved : 12; // Reserved, must be 0\n    };\n} HSA_ENGINE_VERSION;\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int HotPluggable        : 1;    // the node may be removed by some system action\n                                                 // (event will be sent)\n        unsigned int HSAMMUPresent       : 1;    // This node has an ATS/PRI 1.1 compatible\n                                                 // translation agent in the system (e.g. IOMMUv2)\n        unsigned int SharedWithGraphics  : 1;    // this HSA nodes' GPU function is also used for OS primary\n                                                 // graphics render (= UI)\n        unsigned int QueueSizePowerOfTwo : 1;    // This node GPU requires the queue size to be a power of 2 value\n        unsigned int QueueSize32bit      : 1;    // This node GPU requires the queue size to be less than 4GB\n        unsigned int QueueIdleEvent      : 1;    // This node GPU supports notification on Queue Idle\n        unsigned int VALimit             : 1;    // This node GPU has limited VA range for platform\n                                                 // (typical 40bit). Affects shared VM use for 64bit apps\n        unsigned int WatchPointsSupported: 1;\t // Indicates if Watchpoints are available on the node.\n        unsigned int WatchPointsTotalBits: 4;    // Watchpoints available. To determine the number use 2^value\n\n        unsigned int DoorbellType        : 2;    // 0: This node has pre-1.0 doorbell characteristic\n                                                 // 1: This node has 1.0 doorbell characteristic\n                                                 // 2,3: reserved for future use\n        unsigned int AQLQueueDoubleMap   : 1;\t // The unit needs a VA “double map”\n        unsigned int DebugTrapSupported  : 1;    // Indicates if Debug Trap is supported on the node.\n        unsigned int WaveLaunchTrapOverrideSupported: 1; // Indicates if Wave Launch Trap Override is supported on the node.\n        unsigned int WaveLaunchModeSupported: 1; // Indicates if Wave Launch Mode is supported on the node.\n        unsigned int PreciseMemoryOperationsSupported: 1; // Indicates if Precise Memory Operations are supported on the node.\n        unsigned int DEPRECATED_SRAM_EDCSupport: 1; // Old buggy user mode depends on this being 0\n        unsigned int Mem_EDCSupport: 1;          // Indicates if GFX internal DRAM/HBM EDC/ECC functionality is active\n        unsigned int RASEventNotify: 1;          // Indicates if GFX extended RASFeatures and RAS EventNotify status is available\n        unsigned int ASICRevision: 4;            // Indicates the ASIC revision of the chip on this node.\n        unsigned int SRAM_EDCSupport: 1;         // Indicates if GFX internal SRAM EDC/ECC functionality is active\n        unsigned int SVMAPISupported     : 1;    // Whether or not the SVM API is supported\n        unsigned int CoherentHostAccess: 1;      // Whether or not device memory can be coherently accessed by the host CPU\n        unsigned int DebugSupportedFirmware : 1; // Indicates if HWS firmware supports GPU debugging\n        unsigned int PreciseALUOperationsSupported : 1; //Indicates if precise ALU operations are supported for GPU debugging\n        unsigned int PerQueueResetSupported : 1; // Indicates per-queue reset supported\n    } ui32;\n} HSA_CAPABILITY;\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int PerSDMAQueueResetSupported : 1; // Indicates per-sdma queue reset supported\n        unsigned int Reserved : 31; // Reserved\n    } ui32;\n} HSA_CAPABILITY2;\n\n// Debug Properties and values\n// HSA runtime may expose a subset of the capabilities outlined to the applicati\ntypedef union\n{\n    HSAuint64 Value;\n    struct\n    {\n        HSAuint64 WatchAddrMaskLoBit: 4; // Only bits\n                                        // WatchAddrMaskLoBit..WatchAddrMaskHiBit\n                                        // of the\n        HSAuint64 WatchAddrMaskHiBit: 6; // watch address mask are used.\n                                         // 0 is the least significant bit.\n        HSAuint64 DispatchInfoAlwaysValid: 1; // 0 if control of TTMP setup is\n                                              // controlled on a per process\n                                              // basis and is not always enabled\n                                              // 1 if TTMP setup is always\n                                              // enabled\n        HSAuint64 AddressWatchpointShareKind: 1; // whether the address watchpoint\n                                                 //     is per process or shared with\n                                                 //     all proccesses\n                                                 // 0 if shared or unsuppoted\n                                                 //    (unsupported indicated by\n                                                 //    address_watchpoint_count == 0)\n                                                 //    All current devices have shared watchpoints\n                                                 // 1 if unshared\n        HSAuint64 Reserved: 52;              //\n    };\n} HSA_DEBUG_PROPERTIES;\n\n//\n// HSA node properties. This structure is an output parameter of hsaKmtGetNodeProperties()\n// The application or runtime can use the information herein to size the topology management structures\n// Unless there is some very weird setup, there is at most one \"GPU\" device (with a certain number\n// of throughput compute units (= SIMDs) associated with a H-NUMA node.\n//\n\n#define HSA_PUBLIC_NAME_SIZE        64   // Marketing name string size\n\ntypedef struct _HsaNodeProperties\n{\n    HSAuint32       NumCPUCores;       // # of latency (= CPU) cores present on this HSA node.\n                                       // This value is 0 for a HSA node with no such cores,\n                                       // e.g a \"discrete HSA GPU\"\n    HSAuint32       NumFComputeCores;  // # of HSA throughtput (= GPU) FCompute cores (\"SIMD\") present in a node.\n                                       // This value is 0 if no FCompute cores are present (e.g. pure \"CPU node\").\n    HSAuint32 NumNeuralCores;          // # of HSA neural processing units (= AIE) present in a\n                                       // node. This value is 0 if there are no NeuralCores.\n    HSAuint32       NumMemoryBanks;    // # of discoverable memory bank affinity properties on this \"H-NUMA\" node.\n    HSAuint32       NumCaches;         // # of discoverable cache affinity properties on this \"H-NUMA\"  node.\n\n    HSAuint32       NumIOLinks;        // # of discoverable IO link affinity properties of this node\n                                       // connecting to other nodes.\n\n    HSAuint32       CComputeIdLo;      // low value of the logical processor ID of the latency (= CPU)\n                                       // cores available on this node\n    HSAuint32       FComputeIdLo;      // low value of the logical processor ID of the throughput (= GPU)\n                                       // units available on this node\n\n    HSA_CAPABILITY  Capability;        // see above\n    HSA_CAPABILITY2  Capability2;      // see above\n\n    HSAuint32       MaxWavesPerSIMD;   // This identifies the max. number of launched waves per SIMD.\n                                       // If NumFComputeCores is 0, this value is ignored.\n    HSAuint32       LDSSizeInKB;       // Size of Local Data Store in Kilobytes per SIMD Wavefront\n    HSAuint32       GDSSizeInKB;       // Size of Global Data Store in Kilobytes shared across SIMD Wavefronts\n\n    HSAuint32       WaveFrontSize;     // Number of SIMD cores per wavefront executed, typically 64,\n                                       // may be 32 or a different value for some HSA based architectures\n\n    HSAuint32       NumShaderBanks;    // Number of Shader Banks or Shader Engines, typical values are 1 or 2\n\n\n    HSAuint32       NumArrays;         // Number of SIMD arrays per engine\n    HSAuint32       NumCUPerArray;     // Number of Compute Units (CU) per SIMD array\n    HSAuint32       NumSIMDPerCU;      // Number of SIMD representing a Compute Unit (CU)\n\n    HSAuint32       MaxSlotsScratchCU; // Number of temp. memory (\"scratch\") wave slots available to access,\n                                       // may be 0 if HW has no restrictions\n\n    HSA_ENGINE_ID   EngineId;          // Identifier (rev) of the GPU uEngine or Firmware, may be 0\n    HSA_ENGINE_ID   OverrideEngineId;  // Identifier (rev) of the Overrided GPU uEngine or Firmware, may be 0\n\n    HSAuint16       VendorId;          // GPU vendor id; 0 on latency (= CPU)-only nodes\n    HSAuint16       DeviceId;          // GPU device id; 0 on latency (= CPU)-only nodes\n\n    HSAuint32       LocationId;        // GPU BDF (Bus/Device/function number) - identifies the device\n                                       // location in the overall system\n    HSAuint64       LocalMemSize;       // Local memory size\n    HSAuint32       MaxEngineClockMhzFCompute;  // maximum engine clocks for CPU and\n    HSAuint32       MaxEngineClockMhzCCompute;  // GPU function, including any boost caopabilities,\n    HSAint32        DrmRenderMinor;             // DRM render device minor device number\n    HSAuint16       MarketingName[HSA_PUBLIC_NAME_SIZE];   // Public name of the \"device\" on the node (board or APU name).\n                                       // Unicode string\n    HSAuint8        AMDName[HSA_PUBLIC_NAME_SIZE];   //CAL Name of the \"device\", ASCII\n    HSA_ENGINE_VERSION uCodeEngineVersions;\n    HSA_DEBUG_PROPERTIES DebugProperties; // Debug properties of this node.\n    HSAuint64       HiveID;            // XGMI Hive the GPU node belongs to in the system. It is an opaque and static\n                                       // number hash created by the PSP\n    HSAuint32       NumSdmaEngines;    // number of PCIe optimized SDMA engines\n    HSAuint32       NumSdmaXgmiEngines;// number of XGMI optimized SDMA engines\n\n    HSAuint8        NumSdmaQueuesPerEngine;// number of SDMA queue per one engine\n    HSAuint8        NumCpQueues; // number of Compute queues\n    HSAuint8        NumGws;            // number of GWS barriers\n    HSAuint8        Integrated;        // 0 - discrete GPU, 1 - integrated GPU (including small APU and APP APU)\n\n    HSAuint32       Domain;            // PCI domain of the GPU\n    HSAuint64       UniqueID;          // Globally unique immutable id\n\n    HSAuint32       VGPRSizePerCU;     // VGPR size in bytes per CU\n    HSAuint32       SGPRSizePerCU;     // SGPR size in bytes per CU\n\n    HSAuint32       NumXcc;            // Number of XCC\n    HSAuint32       KFDGpuID;          // GPU Hash ID generated by KFD\n\n    HSAuint32       FamilyID;          // GPU family id\n} HsaNodeProperties;\n\n\ntypedef enum _HSA_HEAPTYPE\n{\n    HSA_HEAPTYPE_SYSTEM                = 0,\n    HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC   = 1, // CPU \"visible\" part of GPU device local memory (for discrete GPU)\n    HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE  = 2, // CPU \"invisible\" part of GPU device local memory (for discrete GPU)\n                                            // All HSA accessible memory is per definition \"CPU visible\"\n                                            // \"Private memory\" is relevant for graphics interop only.\n    HSA_HEAPTYPE_GPU_GDS               = 3, // GPU internal memory (GDS)\n    HSA_HEAPTYPE_GPU_LDS               = 4, // GPU internal memory (LDS)\n    HSA_HEAPTYPE_GPU_SCRATCH           = 5, // GPU special memory (scratch)\n    HSA_HEAPTYPE_DEVICE_SVM            = 6, // sys-memory mapped by device page tables\n    HSA_HEAPTYPE_MMIO_REMAP            = 7, // remapped mmio, such as hdp flush registers\n\n    HSA_HEAPTYPE_NUMHEAPTYPES,\n    HSA_HEAPTYPE_SIZE                  = 0xFFFFFFFF\n} HSA_HEAPTYPE;\n\ntypedef union\n{\n    HSAuint32 MemoryProperty;\n    struct\n    {\n        unsigned int HotPluggable      : 1; // the memory may be removed by some system action,\n                                            // memory should be used for temporary data\n        unsigned int NonVolatile       : 1; // memory content is preserved across a power-off cycle.\n        unsigned int Reserved          :30;\n    } ui32;\n} HSA_MEMORYPROPERTY;\n\n\n//\n// Discoverable HSA Memory properties.\n// The structure is the output parameter of the hsaKmtGetNodeMemoryProperties() function\n//\n\ntypedef struct _HsaMemoryProperties\n{\n    HSA_HEAPTYPE    HeapType;          // system or frame buffer,\n    union\n    {\n        HSAuint64   SizeInBytes;       // physical memory size of the memory range in bytes\n        struct\n        {\n            HSAuint32 SizeInBytesLow;  // physical memory size of the memory range in bytes (lower 32bit)\n            HSAuint32 SizeInBytesHigh; // physical memory size of the memory range in bytes (higher 32bit)\n        } ui32;\n    };\n    HSA_MEMORYPROPERTY  Flags;         // See definitions above\n\n    HSAuint32    Width;                // memory width - the number of parallel bits of the memory interface\n    HSAuint32    MemoryClockMax;       // memory clock for the memory, this allows computing the available bandwidth\n                                       // to the memory when needed\n    HSAuint64    VirtualBaseAddress;   // if set to value != 0, indicates the virtual base address of the memory\n                                       // in process virtual space\n} HsaMemoryProperties;\n\n//\n// Discoverable Cache Properties. (optional).\n// The structure is the output parameter of the hsaKmtGetNodeMemoryProperties() function\n// Any of the parameters may be 0 (= not defined)\n//\n\n#define HSA_CPU_SIBLINGS            256\n#define HSA_PROCESSORID_ALL         0xFFFFFFFF\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int Data           : 1;\n        unsigned int Instruction    : 1;\n        unsigned int CPU            : 1;\n        unsigned int HSACU          : 1;\n        unsigned int Reserved       :28;\n    } ui32;\n} HsaCacheType;\n\ntypedef struct _HaCacheProperties\n{\n    HSAuint32    ProcessorIdLow;   // Identifies the processor number\n\n    HSAuint32    CacheLevel;       // Integer representing level: 1, 2, 3, 4, etc\n    HSAuint32    CacheSize;        // Size of the cache\n    HSAuint32    CacheLineSize;    // Cache line size in bytes\n    HSAuint32    CacheLinesPerTag; // Cache lines per Cache Tag\n    HSAuint32    CacheAssociativity; // Cache Associativity\n    HSAuint32    CacheLatency;     // Cache latency in ns\n    HsaCacheType CacheType;\n    HSAuint32    SiblingMap[HSA_CPU_SIBLINGS];\n} HsaCacheProperties;\n\n\n//\n// Discoverable CPU Compute Properties. (optional).\n// The structure is the output parameter of the hsaKmtGetCComputeProperties() function\n// Any of the parameters may be 0 (= not defined)\n//\n\ntypedef struct _HsaCComputeProperties\n{\n    HSAuint32    SiblingMap[HSA_CPU_SIBLINGS];\n} HsaCComputeProperties;\n\n//\n// Discoverable IoLink Properties (optional).\n// The structure is the output parameter of the hsaKmtGetIoLinkProperties() function.\n// Any of the parameters may be 0 (= not defined)\n//\n\ntypedef enum _HSA_IOLINKTYPE {\n    HSA_IOLINKTYPE_UNDEFINED      = 0,\n    HSA_IOLINKTYPE_HYPERTRANSPORT = 1,\n    HSA_IOLINKTYPE_PCIEXPRESS     = 2,\n    HSA_IOLINKTYPE_AMBA           = 3,\n    HSA_IOLINKTYPE_MIPI           = 4,\n    HSA_IOLINK_TYPE_QPI_1_1       = 5,\n    HSA_IOLINK_TYPE_RESERVED1     = 6,\n    HSA_IOLINK_TYPE_RESERVED2     = 7,\n    HSA_IOLINK_TYPE_RAPID_IO      = 8,\n    HSA_IOLINK_TYPE_INFINIBAND    = 9,\n    HSA_IOLINK_TYPE_RESERVED3     = 10,\n    HSA_IOLINK_TYPE_XGMI          = 11,\n    HSA_IOLINK_TYPE_XGOP          = 12,\n    HSA_IOLINK_TYPE_GZ            = 13,\n    HSA_IOLINK_TYPE_ETHERNET_RDMA = 14,\n    HSA_IOLINK_TYPE_RDMA_OTHER    = 15,\n    HSA_IOLINK_TYPE_OTHER         = 16,\n    HSA_IOLINKTYPE_NUMIOLINKTYPES,\n    HSA_IOLINKTYPE_SIZE           = 0xFFFFFFFF\n} HSA_IOLINKTYPE;\n\ntypedef union\n{\n    HSAuint32 LinkProperty;\n    struct\n    {\n        unsigned int Override          : 1;  // bus link properties are determined by this structure\n                                             // not by the HSA_IOLINKTYPE. The other flags are valid\n                                             // only if this bit is set to one\n        unsigned int NonCoherent       : 1;  // The link doesn't support coherent transactions\n                                             // memory accesses across must not be set to \"host cacheable\"!\n        unsigned int NoAtomics32bit    : 1;  // The link doesn't support 32bit-wide atomic transactions\n        unsigned int NoAtomics64bit    : 1;  // The link doesn't support 64bit-wide atomic transactions\n        unsigned int NoPeerToPeerDMA   : 1;  // The link doesn't allow device P2P access\n        unsigned int Reserved          :27;\n    } ui32;\n} HSA_LINKPROPERTY;\n\n\ntypedef struct _HsaIoLinkProperties\n{\n    HSA_IOLINKTYPE  IoLinkType;      // see above\n    HSAuint32    VersionMajor;       // Bus interface version (optional)\n    HSAuint32    VersionMinor;       // Bus interface version (optional)\n\n    HSAuint32    NodeFrom;           //\n    HSAuint32    NodeTo;             //\n\n    HSAuint32    Weight;             // weight factor (derived from CDIT)\n\n    HSAuint32    MinimumLatency;     // minimum cost of time to transfer (rounded to ns)\n    HSAuint32    MaximumLatency;     // maximum cost of time to transfer (rounded to ns)\n    HSAuint32    MinimumBandwidth;   // minimum interface Bandwidth in MB/s\n    HSAuint32    MaximumBandwidth;   // maximum interface Bandwidth in MB/s\n    HSAuint32    RecTransferSize;    // recommended transfer size to reach maximum bandwidth in Bytes\n    HSAuint32    RecSdmaEngIdMask;   // recommended sdma engine IDs to reach maximum bandwidth\n    HSA_LINKPROPERTY Flags;          // override flags (may be active for specific platforms)\n} HsaIoLinkProperties;\n\n//\n// Memory allocation definitions for the KFD HSA interface\n//\n\ntypedef struct _HsaMemFlags\n{\n    union\n    {\n        struct\n        {\n            unsigned int NonPaged    : 1; // default = 0: pageable memory\n            unsigned int CachePolicy : 2; // see HSA_CACHING_TYPE\n            unsigned int ReadOnly    : 1; // default = 0: Read/Write memory\n            unsigned int PageSize    : 2; // see HSA_PAGE_SIZE\n            unsigned int HostAccess  : 1; // default = 0: GPU access only\n            unsigned int NoSubstitute: 1; // default = 0: if specific memory is not available on node (e.g. on\n                                          // discrete GPU local), allocation may fall back to system memory node 0\n                                          // memory (= always available). Otherwise no allocation is possible.\n            unsigned int GDSMemory   : 1; // default = 0: If set, the allocation will occur in GDS heap.\n                                          // HostAccess must be 0, all other flags (except NoSubstitute) should\n                                          // be 0 when setting this entry to 1. GDS allocation may fail due to\n                                          // limited resources. Application code is required to work without\n                                          // any allocated GDS memory using regular memory.\n                                          // Allocation fails on any node without GPU function.\n            unsigned int Scratch     : 1; // default = 0: If set, the allocation will occur in GPU \"scratch area\".\n                                          // HostAccess must be 0, all other flags (except NoSubstitute) should be 0\n                                          // when setting this entry to 1. Scratch allocation may fail due to limited\n                                          // resources. Application code is required to work without any allocation.\n                                          // Allocation fails on any node without GPU function.\n            unsigned int AtomicAccessFull: 1; // default = 0: If set, the memory will be allocated and mapped to allow \n                                              // atomic ops processing. On AMD APU, this will use the ATC path on system \n                                              // memory, irrespective of the NonPaged flag setting (= if NonPaged is set, \n                                              // the memory is pagelocked but mapped through IOMMUv2 instead of GPUVM). \n                                              // All atomic ops must be supported on this memory.\n            unsigned int AtomicAccessPartial: 1; // default = 0: See above for AtomicAccessFull description, however \n                                                 // focused on AMD discrete GPU that support PCIe atomics; the memory \n                                                 // allocation is mapped to allow for PCIe atomics to operate on system \n                                                 // memory, irrespective of NonPaged set or the presence of an ATC path \n                                                 // in the system. The atomic operations supported are limited to SWAP, \n                                                 // CompareAndSwap (CAS) and FetchAdd (this PCIe op allows both atomic \n                                                 // increment and decrement via 2-complement arithmetic), which are the \n                                                 // only atomic ops directly supported in PCI Express.\n                                                 // On AMD APU, setting this flag will allocate the same type of memory \n                                                 // as AtomicAccessFull, but it will be considered compatible with \n                                                 // discrete GPU atomic operations access.\n            unsigned int ExecuteAccess: 1; // default = 0: Identifies if memory is primarily used for data or accessed \n                                           // for executable code (e.g. queue memory) by the host CPU or the device. \n                                           // Influences the page attribute setting within the allocation\n            unsigned int CoarseGrain : 1;  // default = 0: The memory can be accessed assuming cache\n                                           // coherency maintained by link infrastructure and HSA agents.\n                                           // 1: memory consistency needs to be enforced at\n                                           // synchronization points at dispatch or other software\n                                           // enforced synchronization boundaries.\n            unsigned int AQLQueueMemory: 1; // default = 0; If 1: The caller indicates that the memory will be used as AQL queue memory.\n\t\t\t\t\t    // The KFD will ensure that the memory returned is allocated in the optimal memory location\n\t\t\t\t\t    // and optimal alignment requirements\n            unsigned int FixedAddress : 1; // Allocate memory at specified virtual address. Fail if address is not free.\n            unsigned int NoNUMABind:    1; // Don't bind system memory to a specific NUMA node\n            unsigned int Uncached:      1; // Caching flag for fine-grained memory on A+A HW platform\n            unsigned int NoAddress:     1; // only do vram allocation, return a handle, not allocate virtual address.\n            unsigned int OnlyAddress:   1; // only do virtal address allocation without vram allocation.\n            unsigned int ExtendedCoherent: 1;  // system-scope coherence on atomic instructions\n            unsigned int GTTAccess:     1;  // default = 0; If 1: The caller indicates this memory will be mapped to GART for MES\n\t\t\t\t\t    // KFD will allocate GTT memory with the Preferred_node set as gpu_id for GART mapping\n            unsigned int Contiguous:\t1; // Allocate contiguous VRAM\n            unsigned int ExecuteBlit:\t1; // default = 0; If 1: The caller indicates that the memory is for blit kernel object.\n            unsigned int Reserved:      8;\n\n        } ui32;\n        HSAuint32 Value;\n    };\n} HsaMemFlags;\n\ntypedef struct _HsaMemMapFlags\n{\n    union\n    {\n        struct\n        {\n            unsigned int Reserved1      :  1; //\n            unsigned int CachePolicy    :  2; // see HSA_CACHING_TYPE\n            unsigned int ReadOnly       :  1; // memory is not modified while mapped\n            \t    \t    \t    \t      // allows migration scale-out\n\t    unsigned int PageSize\t    :  2; // see HSA_PAGE_SIZE, hint to use\n\t\t\t\t\t  // this page size if possible and\n\t\t\t\t\t  // smaller than default\n\t    unsigned int HostAccess     :  1; // default = 0: GPU access only\n\t    unsigned int Migrate        :  1; // Hint: Allows migration to local mem\n\t\t\t\t\t\t  // of mapped GPU(s), instead of mapping\n\t\t\t\t\t\t  // physical location\n            unsigned int Probe          :  1;     // default = 0: Indicates that a range\n                                                  // will be mapped by the process soon,\n\t\t\t\t\t\t  // but does not initiate a map operation\n\t\t\t\t\t\t  // may trigger eviction of nonessential\n\t\t\t\t\t\t  // data from the memory, reduces latency\n\t\t\t\t\t\t  // “cleanup hint” only, may be ignored\n            unsigned int Reserved       : 23;\n        } ui32;\n        HSAuint32 Value;\n    };\n} HsaMemMapFlags;\n\ntypedef struct _HsaGraphicsResourceInfo {\n    void       *MemoryAddress;      // For use in hsaKmtMapMemoryToGPU(Nodes)\n    HSAuint64  SizeInBytes;         // Buffer size\n    const void *Metadata;           // Pointer to metadata owned by Thunk\n    HSAuint32  MetadataSizeInBytes; // Size of metadata\n    HSAuint32  NodeId;              // GPU exported the buffer\n} HsaGraphicsResourceInfo;\n\ntypedef enum _HSA_CACHING_TYPE\n{\n    HSA_CACHING_CACHED        = 0,\n    HSA_CACHING_NONCACHED     = 1,\n    HSA_CACHING_WRITECOMBINED = 2,\n    HSA_CACHING_RESERVED      = 3,\n    HSA_CACHING_NUM_CACHING,\n    HSA_CACHING_SIZE          = 0xFFFFFFFF\n} HSA_CACHING_TYPE;\n\ntypedef enum _HSA_PAGE_SIZE\n{\n    HSA_PAGE_SIZE_4KB         = 0,\n    HSA_PAGE_SIZE_64KB        = 1,  //64KB pages, not generally available in systems\n    HSA_PAGE_SIZE_2MB         = 2,\n    HSA_PAGE_SIZE_1GB         = 3,  //1GB pages, not generally available in systems\n} HSA_PAGE_SIZE;\n\n\ntypedef enum _HSA_DEVICE\n{\n    HSA_DEVICE_CPU  = 0,\n    HSA_DEVICE_GPU  = 1,\n    MAX_HSA_DEVICE  = 2\n} HSA_DEVICE;\n\n\ntypedef enum _HSA_QUEUE_PRIORITY\n{\n    HSA_QUEUE_PRIORITY_MINIMUM        = -3,\n    HSA_QUEUE_PRIORITY_LOW            = -2,\n    HSA_QUEUE_PRIORITY_BELOW_NORMAL   = -1,\n    HSA_QUEUE_PRIORITY_NORMAL         =  0,\n    HSA_QUEUE_PRIORITY_ABOVE_NORMAL   =  1,\n    HSA_QUEUE_PRIORITY_HIGH           =  2,\n    HSA_QUEUE_PRIORITY_MAXIMUM        =  3,\n    HSA_QUEUE_PRIORITY_NUM_PRIORITY,\n    HSA_QUEUE_PRIORITY_SIZE           = 0xFFFFFFFF\n} HSA_QUEUE_PRIORITY;\n\ntypedef enum _HSA_QUEUE_TYPE\n{\n    HSA_QUEUE_COMPUTE            = 1,  // AMD PM4 compatible Compute Queue\n    HSA_QUEUE_SDMA               = 2,  // PCIe optimized SDMA Queue, used for data transport and format conversion (e.g. (de-)tiling, etc).\n    HSA_QUEUE_MULTIMEDIA_DECODE  = 3,  // reserved, for HSA multimedia decode queue\n    HSA_QUEUE_MULTIMEDIA_ENCODE  = 4,  // reserved, for HSA multimedia encode queue\n    HSA_QUEUE_SDMA_XGMI          = 5,  // XGMI optimized SDMA Queue\n    HSA_QUEUE_SDMA_BY_ENG_ID     = 6,  // Queue with specified SDMA engine ID\n\n    // the following values indicate a queue type permitted to reference OS graphics\n    // resources through the interoperation API. See [5] \"HSA Graphics Interoperation\n    // specification\" for more details on use of such resources.\n\n    HSA_QUEUE_COMPUTE_OS           = 11, // AMD PM4 compatible Compute Queue\n    HSA_QUEUE_SDMA_OS              = 12, // SDMA Queue, used for data transport and format conversion (e.g. (de-)tiling, etc).\n    HSA_QUEUE_MULTIMEDIA_DECODE_OS = 13, // reserved, for HSA multimedia decode queue\n    HSA_QUEUE_MULTIMEDIA_ENCODE_OS = 14,  // reserved, for HSA multimedia encode queue\n\n    HSA_QUEUE_COMPUTE_AQL          = 21, // HSA AQL packet compatible Compute Queue\n    HSA_QUEUE_DMA_AQL              = 22, // HSA AQL packet compatible DMA Queue\n    HSA_QUEUE_DMA_AQL_XGMI         = 23, // HSA AQL packet compatible XGMI optimized DMA Queue\n\n    // more types in the future\n\n    HSA_QUEUE_TYPE_SIZE            = 0xFFFFFFFF     //aligns to 32bit enum\n} HSA_QUEUE_TYPE;\n\n/**\n  The user context save area is page aligned. The HsaUserContextSaveAreaHeader\n  header starts at offset 0. Space for a user space copy of the control stack\n  comes next and is immediately followed by the user space wave save state. The\n  start of the user space wave save state is page aligned. The debugger reserved\n  area comes next and is 64 byte aligned.\n\n  The user context save area is valid for the duration that the associated\n  queue exists. When a context save occurs, the HsaUserContextSaveAreaHeader\n  header will be updated with information about the context save. The context\n  save area is not modified by any other operation, including a context resume.\n */\n\ntypedef struct\n{\n    HSAuint32 ControlStackOffset;  // Byte offset from start of user context\n                                 // save area to the last saved top (lowest\n                                 // address) of control stack data. Must be\n                                 // 4 byte aligned.\n    HSAuint32 ControlStackSize;  // Byte size of the last saved control stack\n                                 // data. Must be 4 byte aligned.\n    HSAuint32 WaveStateOffset;   // Byte offset from start of user context save\n                                 // area to the last saved base (lowest address)\n                                 // of wave state data. Must be 4 byte aligned.\n    HSAuint32 WaveStateSize;     // Byte size of the last saved wave state data.\n                                 // Must be 4 byte aligned.\n    HSAuint32 DebugOffset;       // Byte offset from start of the user context\n                                 // save area to the memory reserved for the\n                                 // debugger. Must be 64 byte aligned.\n    HSAuint32 DebugSize;         // Byte size of the memory reserved for the\n                                 // debugger. Must be 64 byte aligned.\n    volatile HSAint64 *ErrorReason;      // Address of the HSA signal payload for\n                                         // reporting the error reason bitmask.\n                                         // Must be 4 byte aligned.\n    HSAuint32 ErrorEventId;      // Event ID used for exception signalling.\n                                 // Must be 4 byte aligned.\n    HSAuint32 Reserved1;\n} HsaUserContextSaveAreaHeader;\n\n\ntypedef struct\n{\n\tHSAuint32 QueueDetailError;\t// HW specific queue error state\n\tHSAuint32 QueueTypeExtended;\t// HW specific queue type info.\n\t\t\t\t\t// 0 = no information\n\tHSAuint32 NumCUAssigned;\t// size of *CUMaskInfo bit array, Multiple\n\t\t\t\t\t// of 32, 0 = no information\n\tHSAuint32* CUMaskInfo;\t\t// runtime/system CU assignment for realtime\n\t\t\t\t\t// queue & reserved CU priority. Ptr to\n\t\t\t\t\t// bit-array, each bit represents one CU.\n\t\t\t\t\t// NULL = no information\n\tHSAuint32* UserContextSaveArea;\t// reference to user space context save area\n\tHSAuint64 SaveAreaSizeInBytes;\t// Must be 4-Byte aligned\n\tHSAuint32* ControlStackTop;\t// ptr to the TOS\n\tHSAuint64 ControlStackUsedInBytes; // Must be 4-Byte aligned\n\tHsaUserContextSaveAreaHeader *SaveAreaHeader;\n\tHSAuint64 Reserved2;\t\t// runtime/system CU assignment\n} HsaQueueInfo;\n\ntypedef struct _HsaQueueResource\n{\n    HSA_QUEUEID     QueueId;    /** queue ID */\n    /** Doorbell address to notify HW of a new dispatch */\n    union\n    {\n        HSAuint32*  Queue_DoorBell;\n        HSAuint64*  Queue_DoorBell_aql;\n        HSAuint64   QueueDoorBell;\n    };\n\n    /** virtual address to notify HW of queue write ptr value */\n    union\n    {\n        HSAuint32*  Queue_write_ptr;\n        HSAuint64*  Queue_write_ptr_aql;\n        HSAuint64   QueueWptrValue;\n    };\n\n    /** virtual address updated by HW to indicate current read location */\n    union\n    {\n        HSAuint32*  Queue_read_ptr;\n        HSAuint64*  Queue_read_ptr_aql;\n        HSAuint64   QueueRptrValue;\n    };\n\n    volatile HSAint64* ErrorReason;  /** exception bits signal payload */\n} HsaQueueResource;\n\n\n//TEMPORARY structure definition - to be used only on \"Triniti + Southern Islands\" platform\ntypedef struct _HsaQueueReport\n{\n    HSAuint32     VMID;         //Required on SI to dispatch IB in primary ring\n    void*         QueueAddress; //virtual address of UM mapped compute ring\n    HSAuint64     QueueSize;    //size of the UM mapped compute ring\n} HsaQueueReport;\n\n\n\ntypedef enum _HSA_DBG_WAVEOP\n{\n    HSA_DBG_WAVEOP_HALT        = 1, //Halts a wavefront\n    HSA_DBG_WAVEOP_RESUME      = 2, //Resumes a wavefront\n    HSA_DBG_WAVEOP_KILL        = 3, //Kills a wavefront\n    HSA_DBG_WAVEOP_DEBUG       = 4, //Causes wavefront to enter debug mode\n    HSA_DBG_WAVEOP_TRAP        = 5, //Causes wavefront to take a trap\n    HSA_DBG_NUM_WAVEOP         = 5,\n    HSA_DBG_MAX_WAVEOP         = 0xFFFFFFFF\n} HSA_DBG_WAVEOP;\n\ntypedef enum _HSA_DBG_WAVEMODE\n{\n    HSA_DBG_WAVEMODE_SINGLE               = 0,  //send command to a single wave\n    //Broadcast to all wavefronts of all processes is not supported for HSA user mode\n    HSA_DBG_WAVEMODE_BROADCAST_PROCESS    = 2,  //send to waves within current process\n    HSA_DBG_WAVEMODE_BROADCAST_PROCESS_CU = 3,  //send to waves within current process on CU\n    HSA_DBG_NUM_WAVEMODE                  = 3,\n    HSA_DBG_MAX_WAVEMODE                  = 0xFFFFFFFF\n} HSA_DBG_WAVEMODE;\n\n\ntypedef enum _HSA_DBG_WAVEMSG_TYPE\n{\n    HSA_DBG_WAVEMSG_AUTO    = 0,\n    HSA_DBG_WAVEMSG_USER    = 1,\n    HSA_DBG_WAVEMSG_ERROR   = 2,\n    HSA_DBG_NUM_WAVEMSG,\n    HSA_DBG_MAX_WAVEMSG     = 0xFFFFFFFF\n} HSA_DBG_WAVEMSG_TYPE;\n\ntypedef enum _HSA_DBG_WATCH_MODE\n{\n    HSA_DBG_WATCH_READ        = 0, //Read operations only\n    HSA_DBG_WATCH_NONREAD     = 1, //Write or Atomic operations only\n    HSA_DBG_WATCH_ATOMIC      = 2, //Atomic Operations only\n    HSA_DBG_WATCH_ALL         = 3, //Read, Write or Atomic operations\n    HSA_DBG_WATCH_NUM\n} HSA_DBG_WATCH_MODE;\n\ntypedef enum _HSA_DBG_TRAP_OVERRIDE\n{\n  HSA_DBG_TRAP_OVERRIDE_OR      = 0, // Bitwise OR exception mask with HSA_DBG_TRAP_MASK\n  HSA_DBG_TRAP_OVERRIDE_REPLACE = 1, // Replace exception mask with HSA_DBG_TRAP_MASK\n  HSA_DBG_TRAP_OVERRIDE_NUM\n} HSA_DBG_TRAP_OVERRIDE;\n\ntypedef enum _HSA_DBG_TRAP_MASK\n{\n  HSA_DBG_TRAP_MASK_FP_INVALID           = 1,   // Floating point invalid operation\n  HSA_DBG_TRAP_MASK_FP_INPUT_DENOMAL     = 2,   // Floating point input denormal\n  HSA_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO    = 4,   // Floating point divide by zero\n  HSA_DBG_TRAP_MASK_FP_OVERFLOW          = 8,   // Floating point overflow\n  HSA_DBG_TRAP_MASK_FP_UNDERFLOW         = 16,  // Floating point underflow\n  HSA_DBG_TRAP_MASK_FP_INEXACT           = 32,  // Floating point inexact\n  HSA_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO   = 64,  // Integer divide by zero\n  HSA_DBG_TRAP_MASK_DBG_ADDRESS_WATCH    = 128, // Debug address watch\n  HSA_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION = 256  // Memory violation\n} HSA_DBG_TRAP_MASK;\n\ntypedef enum _HSA_DBG_TRAP_EXCEPTION_CODE {\n\tHSA_DBG_EC_NONE = 0,\n\t/* per queue */\n\tHSA_DBG_EC_QUEUE_WAVE_ABORT = 1,\n\tHSA_DBG_EC_QUEUE_WAVE_TRAP = 2,\n\tHSA_DBG_EC_QUEUE_WAVE_MATH_ERROR = 3,\n\tHSA_DBG_EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION = 4,\n\tHSA_DBG_EC_QUEUE_WAVE_MEMORY_VIOLATION = 5,\n\tHSA_DBG_EC_QUEUE_WAVE_APERTURE_VIOLATION = 6,\n\tHSA_DBG_EC_QUEUE_PACKET_DISPATCH_DIM_INVALID = 16,\n\tHSA_DBG_EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID = 17,\n\tHSA_DBG_EC_QUEUE_PACKET_DISPATCH_CODE_INVALID = 18,\n\tHSA_DBG_EC_QUEUE_PACKET_RESERVED = 19,\n\tHSA_DBG_EC_QUEUE_PACKET_UNSUPPORTED = 20,\n\tHSA_DBG_EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID = 21,\n\tHSA_DBG_EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID = 22,\n\tHSA_DBG_EC_QUEUE_PACKET_VENDOR_UNSUPPORTED = 23,\n\tHSA_DBG_EC_QUEUE_PREEMPTION_ERROR = 30,\n\tHSA_DBG_EC_QUEUE_NEW = 31,\n\t/* per device */\n\tHSA_DBG_EC_DEVICE_QUEUE_DELETE = 32,\n\tHSA_DBG_EC_DEVICE_MEMORY_VIOLATION = 33,\n\tHSA_DBG_EC_DEVICE_RAS_ERROR = 34,\n\tHSA_DBG_EC_DEVICE_FATAL_HALT = 35,\n\tHSA_DBG_EC_DEVICE_NEW = 36,\n\t/* per process */\n\tHSA_DBG_EC_PROCESS_RUNTIME = 48,\n\tHSA_DBG_EC_PROCESS_DEVICE_REMOVE = 49,\n\tHSA_DBG_EC_MAX\n} HSA_DBG_TRAP_EXCEPTION_CODE;\n\n/* Mask generated by ecode defined in enum above. */\n#define HSA_EC_MASK(ecode)\t(1ULL << (ecode - 1))\n\ntypedef enum _HSA_DBG_WAVE_LAUNCH_MODE\n{\n    HSA_DBG_WAVE_LAUNCH_MODE_NORMAL      = 0, // Wavefront launched normally.\n    HSA_DBG_WAVE_LAUNCH_MODE_HALT        = 1, // Wavefront launched in halted mode.\n    HSA_DBG_WAVE_LAUNCH_MODE_KILL        = 2, // Wavefront is launched but immediately\n                                              // terminated before executing any instructions.\n    HSA_DBG_WAVE_LAUNCH_MODE_SINGLE_STEP = 3, // Wavefront is launched in single step (debug)\n                                              // mode. If debug trap is enabled by\n                                              // hsaKmtDbgEnableDebugTrap() then causes a\n                                              // trap after executing each instruction,\n                                              // otherwise behaves the same as\n                                              // HSA_DBG_WAVE_LAUNCH_MODE_NORMAL.\n    HSA_DBG_WAVE_LAUNCH_MODE_DISABLE     = 4, // Disable launching any new waves.\n    HSA_DBG_WAVE_LAUNCH_MODE_NUM\n} HSA_DBG_WAVE_LAUNCH_MODE;\n\n/**\n *    There are no flags currently defined.\n */\ntypedef enum HSA_DBG_NODE_CONTROL {\n    HSA_DBG_NODE_CONTROL_FLAG_MAX = 0x01\n} HSA_DBG_NODE_CONTROL;\n\n#define HSA_RUNTIME_ENABLE_CAPS_SUPPORTS_CORE_DUMP_MASK 0x80000000\n\n//This structure is hardware specific and may change in the future\ntypedef struct _HsaDbgWaveMsgAMDGen2\n{\n    HSAuint32      Value;\n    HSAuint32      Reserved2;\n\n} HsaDbgWaveMsgAMDGen2;\n\ntypedef union _HsaDbgWaveMessageAMD\n{\n    HsaDbgWaveMsgAMDGen2    WaveMsgInfoGen2;\n    //for future HsaDbgWaveMsgAMDGen3;\n} HsaDbgWaveMessageAMD;\n\ntypedef struct _HsaDbgWaveMessage\n{\n    void*                   MemoryVA;         // ptr to associated host-accessible data\n    HsaDbgWaveMessageAMD    DbgWaveMsg;\n} HsaDbgWaveMessage;\n\n\n//\n// HSA sync primitive, Event and HW Exception notification API definitions\n// The API functions allow the runtime to define a so-called sync-primitive, a SW object\n// combining a user-mode provided \"syncvar\" and a scheduler event that can be signaled\n// through a defined GPU interrupt. A syncvar is a process virtual memory location of\n// a certain size that can be accessed by CPU and GPU shader code within the process to set\n// and query the content within that memory. The definition of the content is determined by\n// the HSA runtime and potentially GPU shader code interfacing with the HSA runtime.\n// The syncvar values may be commonly written through an PM4 WRITE_DATA packet in the\n// user mode instruction stream.\n// The OS scheduler event is typically associated and signaled by an interrupt issued by\n// the GPU, but other HSA system interrupt conditions from other HW (e.g. IOMMUv2) may be\n// surfaced by the KFD by this mechanism, too.\n//\n\n// these are the new definitions for events\ntypedef enum _HSA_EVENTTYPE\n{\n    HSA_EVENTTYPE_SIGNAL                     = 0, //user-mode generated GPU signal\n    HSA_EVENTTYPE_NODECHANGE                 = 1, //HSA node change (attach/detach)\n    HSA_EVENTTYPE_DEVICESTATECHANGE          = 2, //HSA device state change( start/stop )\n    HSA_EVENTTYPE_HW_EXCEPTION               = 3, //GPU shader exception event\n    HSA_EVENTTYPE_SYSTEM_EVENT               = 4, //GPU SYSCALL with parameter info\n    HSA_EVENTTYPE_DEBUG_EVENT                = 5, //GPU signal for debugging\n    HSA_EVENTTYPE_PROFILE_EVENT              = 6, //GPU signal for profiling\n    HSA_EVENTTYPE_QUEUE_EVENT                = 7, //GPU signal queue idle state (EOP pm4)\n    HSA_EVENTTYPE_MEMORY                     = 8, //GPU signal for signaling memory access faults and memory subsystem issues\n    //...\n    HSA_EVENTTYPE_MAXID,\n    HSA_EVENTTYPE_TYPE_SIZE                  = 0xFFFFFFFF\n} HSA_EVENTTYPE;\n\n\n//\n// Definitions for types of pending debug events\n//\ntypedef enum _HSA_DEBUG_EVENT_TYPE\n{\n\tHSA_DEBUG_EVENT_TYPE_NONE\t\t\t\t= 0,\n\tHSA_DEBUG_EVENT_TYPE_TRAP\t\t\t\t= 1,\n\tHSA_DEBUG_EVENT_TYPE_VMFAULT\t\t\t= 2,\n\tHSA_DEBUG_EVENT_TYPE_TRAP_VMFAULT\t\t= 3\n} HSA_DEBUG_EVENT_TYPE;\n\ntypedef HSAuint32  HSA_EVENTID;\n\n//\n// Subdefinitions for various event types: Syncvar\n//\n\ntypedef struct _HsaSyncVar\n{\n    union\n    {\n        void*       UserData;           //pointer to user mode data\n        HSAuint64   UserDataPtrValue;   //64bit compatibility of value\n    } SyncVar;\n    HSAuint64       SyncVarSize;\n} HsaSyncVar;\n\n//\n// Subdefinitions for various event types: NodeChange\n//\n\ntypedef enum _HSA_EVENTTYPE_NODECHANGE_FLAGS\n{\n    HSA_EVENTTYPE_NODECHANGE_ADD     = 0,\n    HSA_EVENTTYPE_NODECHANGE_REMOVE  = 1,\n    HSA_EVENTTYPE_NODECHANGE_SIZE    = 0xFFFFFFFF\n} HSA_EVENTTYPE_NODECHANGE_FLAGS;\n\ntypedef struct _HsaNodeChange\n{\n    HSA_EVENTTYPE_NODECHANGE_FLAGS Flags;   // HSA node added/removed on the platform\n} HsaNodeChange;\n\n//\n// Sub-definitions for various event types: DeviceStateChange\n//\n\ntypedef enum _HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS\n{\n    HSA_EVENTTYPE_DEVICESTATUSCHANGE_START     = 0, //device started (and available)\n    HSA_EVENTTYPE_DEVICESTATUSCHANGE_STOP      = 1, //device stopped (i.e. unavailable)\n    HSA_EVENTTYPE_DEVICESTATUSCHANGE_SIZE      = 0xFFFFFFFF\n} HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS;\n\ntypedef struct _HsaDeviceStateChange\n{\n    HSAuint32                           NodeId;     // F-NUMA node that contains the device\n    HSA_DEVICE                          Device;     // device type: GPU or CPU\n    HSA_EVENTTYPE_DEVICESTATECHANGE_FLAGS Flags;    // event flags\n} HsaDeviceStateChange;\n\n//\n// Sub-definitions for various event types: Memory exception\n//\n\ntypedef enum _HSA_EVENTID_MEMORYFLAGS\n{\n    HSA_EVENTID_MEMORY_RECOVERABLE           = 0, //access fault, recoverable after page adjustment\n    HSA_EVENTID_MEMORY_FATAL_PROCESS         = 1, //memory access requires process context destruction, unrecoverable\n    HSA_EVENTID_MEMORY_FATAL_VM              = 2, //memory access requires all GPU VA context destruction, unrecoverable\n} HSA_EVENTID_MEMORYFLAGS;\n\ntypedef struct _HsaAccessAttributeFailure\n{\n    unsigned int NotPresent  : 1;  // Page not present or supervisor privilege \n    unsigned int ReadOnly    : 1;  // Write access to a read-only page\n    unsigned int NoExecute   : 1;  // Execute access to a page marked NX\n    unsigned int GpuAccess   : 1;  // Host access only\n    unsigned int ECC         : 1;  // RAS ECC failure (notification of DRAM ECC - non-recoverable - error, if supported by HW)\n    unsigned int Imprecise   : 1;  // Can't determine the exact fault address\n    unsigned int ErrorType   : 3;  // Indicates RAS errors or other errors causing the access to GPU to fail\n                                      // 0 = no RAS error, 1 = ECC_SRAM, 2 = Link_SYNFLOOD (poison), 3 = GPU hang (not attributable to a specific cause), other values reserved\n    unsigned int Reserved    : 23; // must be 0\n} HsaAccessAttributeFailure;\n\n// data associated with HSA_EVENTID_MEMORY\ntypedef struct _HsaMemoryAccessFault\n{\n    HSAuint32                       NodeId;             // H-NUMA node that contains the device where the memory access occurred\n    HSAuint64                       VirtualAddress;     // virtual address this occurred on\n    HsaAccessAttributeFailure       Failure;            // failure attribute\n    HSA_EVENTID_MEMORYFLAGS         Flags;              // event flags\n} HsaMemoryAccessFault;\n\ntypedef enum _HSA_EVENTID_HW_EXCEPTION_CAUSE\n{\n    HSA_EVENTID_HW_EXCEPTION_GPU_HANG  = 0, // GPU Hang\n    HSA_EVENTID_HW_EXCEPTION_ECC       = 1, // SRAM ECC error\n} HSA_EVENTID_HW_EXCEPTION_CAUSE;\n\n// data associated with HSA_EVENTID_HW_EXCEPTION\ntypedef struct _HsaHwException\n{\n    HSAuint32                       NodeId;    // Node Id where the memory exception occured\n    HSAuint32                       ResetType;\n    HSAuint32                       MemoryLost;\n    HSA_EVENTID_HW_EXCEPTION_CAUSE  ResetCause;\n} HsaHwException;\n\ntypedef struct _HsaEventData\n{\n    HSA_EVENTTYPE   EventType;      //event type\n\n    union\n    {\n        // return data associated with HSA_EVENTTYPE_SIGNAL and other events\n        HsaSyncVar              SyncVar;\n\n        // data associated with HSA_EVENTTYPE_NODE_CHANGE\n        HsaNodeChange           NodeChangeState;\n\n        // data associated with HSA_EVENTTYPE_DEVICE_STATE_CHANGE\n        HsaDeviceStateChange    DeviceState;\n\n        // data associated with HSA_EVENTTYPE_MEMORY\n        HsaMemoryAccessFault    MemoryAccessFault;\n\n        // data associated with HSA_EVENTTYPE_HW_EXCEPTION\n        HsaHwException          HwException;\n    } EventData;\n\n    // the following data entries are internal to the KFD & thunk itself.\n\n    HSAuint64       HWData1;                    // internal thunk store for Event data  (OsEventHandle)\n    HSAuint64       HWData2;                    // internal thunk store for Event data  (HWAddress)\n    HSAuint32       HWData3;                    // internal thunk store for Event data  (HWData)\n} HsaEventData;\n\n\ntypedef struct _HsaEventDescriptor\n{\n    HSA_EVENTTYPE   EventType;                  // event type to allocate\n    HSAuint32       NodeId;                     // H-NUMA node containing GPU device that is event source\n    HsaSyncVar      SyncVar;                    // pointer to user mode syncvar data, syncvar->UserDataPtrValue may be NULL\n} HsaEventDescriptor;\n\n\ntypedef struct _HsaEvent\n{\n    HSA_EVENTID     EventId;\n    HsaEventData    EventData;\n} HsaEvent;\n\ntypedef enum _HsaEventTimeout\n{\n    HSA_EVENTTIMEOUT_IMMEDIATE  = 0,\n    HSA_EVENTTIMEOUT_INFINITE   = 0xFFFFFFFF\n} HsaEventTimeOut;\n\ntypedef struct _HsaClockCounters\n{\n    HSAuint64   GPUClockCounter;\n    HSAuint64   CPUClockCounter;\n    HSAuint64   SystemClockCounter;\n    HSAuint64   SystemClockFrequencyHz;\n} HsaClockCounters;\n\n#ifndef DEFINE_GUID\ntypedef struct _HSA_UUID\n{\n    HSAuint32   Data1;\n    HSAuint16   Data2;\n    HSAuint16   Data3;\n    HSAuint8    Data4[8];\n} HSA_UUID;\n\n#define HSA_DEFINE_UUID(name, dw, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \\\n    static const HSA_UUID name = {dw, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}\n#else\n#define HSA_UUID GUID\n#define HSA_DEFINE_UUID DEFINE_GUID\n#endif\n\n// HSA_UUID that identifies the GPU ColorBuffer (CB) block\n// {9ba429c6-af2d-4b38-b349-157271beac6a}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_CB,\n0x9ba429c6, 0xaf2d, 0x4b38, 0xb3, 0x49, 0x15, 0x72, 0x71, 0xbe, 0xac, 0x6a);\n\n// HSA_UUID that identifies the GPU (CPF) block\n// {2b0ad2b5-1c43-4f46-a7bc-e119411ea6c9}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_CPF,\n0x2b0ad2b5, 0x1c43, 0x4f46, 0xa7, 0xbc, 0xe1, 0x19, 0x41, 0x1e, 0xa6, 0xc9);\n\n// HSA_UUID that identifies the GPU (CPG) block\n// {590ec94d-20f0-448f-8dff-316c679de7ff\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_CPG,\n0x590ec94d, 0x20f0, 0x448f, 0x8d, 0xff, 0x31, 0x6c, 0x67, 0x9d, 0xe7, 0xff);\n\n// HSA_UUID that identifies the GPU (DB) block\n// {3d1a47fc-0013-4ed4-8306-822ca0b7a6c2\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_DB,\n0x3d1a47fc, 0x0013, 0x4ed4, 0x83, 0x06, 0x82, 0x2c, 0xa0, 0xb7, 0xa6, 0xc2);\n\n// HSA_UUID that identifies the GPU (GDS) block\n// {f59276ec-2526-4bf8-8ec0-118f77700dc9\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_GDS,\n0xf59276ec, 0x2526, 0x4bf8, 0x8e, 0xc0, 0x11, 0x8f, 0x77, 0x70, 0x0d, 0xc9);\n\n// HSA_UUID that identifies the GPU (GRBM) block\n// {8f00933c-c33d-4801-97b7-7007f78573ad\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_GRBM,\n0x8f00933c, 0xc33d, 0x4801, 0x97, 0xb7, 0x70, 0x07, 0xf7, 0x85, 0x73, 0xad);\n\n// HSA_UUID that identifies the GPU (GRBMSE) block\n// {34ebd8d7-7c8b-4d15-88fa-0e4e4af59ac1\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_GRBMSE,\n0x34ebd8d7, 0x7c8b, 0x4d15, 0x88, 0xfa, 0x0e, 0x4e, 0x4a, 0xf5, 0x9a, 0xc1);\n\n// HSA_UUID that identifies the GPU (IA) block\n// {34276944-4264-4fcd-9d6e-ae264582ec51\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_IA,\n0x34276944, 0x4264, 0x4fcd, 0x9d, 0x6e, 0xae, 0x26, 0x45, 0x82, 0xec, 0x51);\n\n// HSA_UUID that identifies the GPU Memory Controller (MC) block\n// {13900B57-4956-4D98-81D0-68521937F59C\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_MC,\n0x13900b57, 0x4956, 0x4d98, 0x81, 0xd0, 0x68, 0x52, 0x19, 0x37, 0xf5, 0x9c);\n\n// HSA_UUID that identifies the GPU (PASC) block\n// {b0e7fb5d-0efc-4744-b516-5d23dc1fd56c\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_PASC,\n0xb0e7fb5d, 0x0efc, 0x4744, 0xb5, 0x16, 0x5d, 0x23, 0xdc, 0x1f, 0xd5, 0x6c);\n\n// HSA_UUID that identifies the GPU (PASU) block\n// {9a152b6a-1fad-45f2-a5bf-f163826bd0cd\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_PASU,\n0x9a152b6a, 0x1fad, 0x45f2, 0xa5, 0xbf, 0xf1, 0x63, 0x82, 0x6b, 0xd0, 0xcd);\n\n// HSA_UUID that identifies the GPU (SPI) block\n// {eda81044-d62c-47eb-af89-4f6fbf3b38e0\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_SPI,\n0xeda81044, 0xd62c, 0x47eb, 0xaf, 0x89, 0x4f, 0x6f, 0xbf, 0x3b, 0x38, 0xe0);\n\n// HSA_UUID that identifies the GPU (SRBM) block\n// {9f8040e0-6830-4019-acc8-463c9e445b89\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_SRBM,\n0x9f8040e0, 0x6830, 0x4019, 0xac, 0xc8, 0x46, 0x3c, 0x9e, 0x44, 0x5b, 0x89);\n\n// GUID that identifies the GPU Shader Sequencer (SQ) block\n// {B5C396B6-D310-47E4-86FC-5CC3043AF508}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_SQ,\n0xb5c396b6, 0xd310, 0x47e4, 0x86, 0xfc, 0x5c, 0xc3, 0x4, 0x3a, 0xf5, 0x8);\n\n// HSA_UUID that identifies the GPU (SX) block\n// {bdb8d737-43cc-4162-be52-51cfb847beaf}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_SX,\n0xbdb8d737, 0x43cc, 0x4162, 0xbe, 0x52, 0x51, 0xcf, 0xb8, 0x47, 0xbe, 0xaf);\n\n// HSA_UUID that identifies the GPU (TA) block\n// {c01ee43d-ad92-44b1-8ab9-be5e696ceea7}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TA,\n0xc01ee43d, 0xad92, 0x44b1, 0x8a, 0xb9, 0xbe, 0x5e, 0x69, 0x6c, 0xee, 0xa7);\n\n// HSA_UUID that identifies the GPU TextureCache (TCA) block\n// {333e393f-e147-4f49-a6d1-60914c7086b0}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TCA,\n0x333e393f, 0xe147, 0x4f49, 0xa6, 0xd1,0x60, 0x91, 0x4c, 0x70, 0x86, 0xb0);\n\n// HSA_UUID that identifies the GPU TextureCache (TCC) block\n// {848ce855-d805-4566-a8ab-73e884cc6bff}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TCC,\n0x848ce855, 0xd805, 0x4566, 0xa8, 0xab, 0x73, 0xe8, 0x84, 0xcc, 0x6b, 0xff);\n\n// HSA_UUID that identifies the GPU (TCP) block\n// {e10a013b-17d4-4bf5-b089-429591059b60}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TCP,\n0xe10a013b, 0x17d4, 0x4bf5, 0xb0, 0x89, 0x42, 0x95, 0x91, 0x05, 0x9b, 0x60);\n\n// HSA_UUID that identifies the GPU (TCS) block\n// {4126245c-4d96-4d1a-8aed-a939d4cc8ec9}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TCS,\n0x4126245c, 0x4d96, 0x4d1a, 0x8a, 0xed, 0xa9, 0x39, 0xd4, 0xcc, 0x8e, 0xc9);\n\n// HSA_UUID that identifies the GPU (TD) block\n// {7d7c0fe4-fe41-4fea-92c9-4544d7706dc6}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_TD,\n0x7d7c0fe4, 0xfe41, 0x4fea, 0x92, 0xc9, 0x45, 0x44, 0xd7, 0x70, 0x6d, 0xc6);\n\n// HSA_UUID that identifies the GPU (VGT) block\n// {0b6a8cb7-7a01-409f-a22c-3014854f1359}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_VGT,\n0x0b6a8cb7, 0x7a01, 0x409f, 0xa2, 0x2c, 0x30, 0x14, 0x85, 0x4f, 0x13, 0x59);\n\n// HSA_UUID that identifies the GPU (WD) block\n// {0e176789-46ed-4b02-972a-916d2fac244a}\nHSA_DEFINE_UUID(HSA_PROFILEBLOCK_AMD_WD,\n0x0e176789, 0x46ed, 0x4b02, 0x97, 0x2a, 0x91, 0x6d, 0x2f, 0xac, 0x24, 0x4a);\n\ntypedef enum _HSA_PROFILE_TYPE\n{\n    HSA_PROFILE_TYPE_PRIVILEGED_IMMEDIATE = 0, //immediate access counter (KFD access only)\n    HSA_PROFILE_TYPE_PRIVILEGED_STREAMING = 1, //streaming counter, HW continuously\n                                               //writes to memory on updates (KFD access only)\n    HSA_PROFILE_TYPE_NONPRIV_IMMEDIATE    = 2, //user-queue accessible counter\n    HSA_PROFILE_TYPE_NONPRIV_STREAMING    = 3, //user-queue accessible counter\n    //...\n    HSA_PROFILE_TYPE_NUM,\n\n    HSA_PROFILE_TYPE_SIZE                 = 0xFFFFFFFF      // In order to align to 32-bit value\n} HSA_PROFILE_TYPE;\n\n\ntypedef struct _HsaCounterFlags\n{\n    union\n    {\n        struct\n        {\n            unsigned int  Global       : 1;  // counter is global\n                                             // (not tied to VMID/WAVE/CU, ...)\n            unsigned int  Resettable   : 1;  // counter can be reset by SW\n                                             // (always to 0?)\n            unsigned int  ReadOnly     : 1;  // counter is read-only\n                                             // (but may be reset, if indicated)\n            unsigned int  Stream       : 1;  // counter has streaming capability\n                                             // (after trigger, updates buffer)\n            unsigned int  Reserved     : 28;\n        } ui32;\n        HSAuint32      Value;\n    };\n} HsaCounterFlags;\n\n\ntypedef struct _HsaCounter\n{\n    HSA_PROFILE_TYPE Type;              // specifies the counter type\n    HSAuint64        CounterId;         // indicates counter register offset\n    HSAuint32        CounterSizeInBits; // indicates relevant counter bits\n    HSAuint64        CounterMask;       // bitmask for counter value (if applicable)\n    HsaCounterFlags  Flags;             // Property flags (see above)\n    HSAuint32        BlockIndex;        // identifies block the counter belongs to,\n                                        // value may be 0 to NumBlocks\n} HsaCounter;\n\n\ntypedef struct _HsaCounterBlockProperties\n{\n    HSA_UUID                    BlockId;        // specifies the block location\n    HSAuint32                   NumCounters;    // How many counters are available?\n                                                // (sizes Counters[] array below)\n    HSAuint32                   NumConcurrent;  // How many counter slots are available\n                                                // in block?\n    HsaCounter                  Counters[1];    // Start of counter array\n                                                // (NumCounters elements total)\n} HsaCounterBlockProperties;\n\n\ntypedef struct _HsaCounterProperties\n{\n    HSAuint32                   NumBlocks;      // How many profilable block are available?\n                                                // (sizes Blocks[] array below)\n    HSAuint32                   NumConcurrent;  // How many blocks slots can be queried\n                                                // concurrently by HW?\n    HsaCounterBlockProperties   Blocks[1];      // Start of block array\n                                                // (NumBlocks elements total)\n} HsaCounterProperties;\n\ntypedef HSAuint64   HSATraceId;\n\ntypedef struct _HsaPmcTraceRoot\n{\n    HSAuint64                   TraceBufferMinSizeBytes;// (page aligned)\n    HSAuint32                   NumberOfPasses;\n    HSATraceId                  TraceId;\n} HsaPmcTraceRoot;\n\ntypedef struct _HsaGpuTileConfig\n{\n    HSAuint32 *TileConfig;\n    HSAuint32 *MacroTileConfig;\n    HSAuint32 NumTileConfigs;\n    HSAuint32 NumMacroTileConfigs;\n\n    HSAuint32 GbAddrConfig;\n\n    HSAuint32 NumBanks;\n    HSAuint32 NumRanks;\n    /* 9 dwords on 64-bit system */\n    HSAuint32 Reserved[7]; /* Round up to 16 dwords for future extension */\n} HsaGpuTileConfig;\n\ntypedef enum _HSA_POINTER_TYPE {\n    HSA_POINTER_UNKNOWN = 0,\n    HSA_POINTER_ALLOCATED = 1,           // Allocated with hsaKmtAllocMemory (except scratch)\n    HSA_POINTER_REGISTERED_USER = 2,     // Registered user pointer\n    HSA_POINTER_REGISTERED_GRAPHICS = 3, // Registered graphics buffer\n    HSA_POINTER_REGISTERED_SHARED = 4,   // Registered shared buffer (IPC)\n                                         // (hsaKmtRegisterGraphicsToNodes)\n    HSA_POINTER_RESERVED_ADDR = 5        // address-only reservation VA\n} HSA_POINTER_TYPE;\n\ntypedef struct _HsaPointerInfo {\n    HSA_POINTER_TYPE   Type;             // Pointer type\n    HSAuint32          Node;             // Node where the memory is located\n    HsaMemFlags        MemFlags;         // HsaMemFlags used to alloc memory\n    void               *CPUAddress;      // Start address for CPU access\n    HSAuint64          GPUAddress;       // Start address for GPU access\n    HSAuint64          SizeInBytes;      // Size in bytes\n    HSAuint32          NRegisteredNodes; // Number of nodes the memory is registered to\n    HSAuint32          NMappedNodes;     // Number of nodes the memory is mapped to\n    const HSAuint32    *RegisteredNodes; // Array of registered nodes\n    const HSAuint32    *MappedNodes;     // Array of mapped nodes\n    void               *UserData;        // User data associated with the memory\n} HsaPointerInfo;\n\ntypedef HSAuint32 HsaSharedMemoryHandle[8];\n\ntypedef struct _HsaMemoryRange {\n\tvoid               *MemoryAddress;   // Pointer to GPU memory\n\tHSAuint64          SizeInBytes;      // Size of above memory\n} HsaMemoryRange;\n\ntypedef enum _HSA_SVM_FLAGS {\n\tHSA_SVM_FLAG_HOST_ACCESS = 0x00000001, // Guarantee host access to memory\n\tHSA_SVM_FLAG_COHERENT    = 0x00000002, // Fine grained coherency between all devices with access\n\tHSA_SVM_FLAG_HIVE_LOCAL  = 0x00000004, // Use any GPU in same hive as preferred device\n\tHSA_SVM_FLAG_GPU_RO      = 0x00000008, // GPUs only read, allows replication\n\tHSA_SVM_FLAG_GPU_EXEC    = 0x00000010, // Allow execution on GPU\n\tHSA_SVM_FLAG_GPU_READ_MOSTLY = 0x00000020, // GPUs mostly read, may allow similar optimizations as RO, but writes fault\n\tHSA_SVM_FLAG_GPU_ALWAYS_MAPPED = 0x00000040, // Keep GPU memory mapping always valid as if XNACK is disable\n\tHSA_SVM_FLAG_EXT_COHERENT = 0x00000080, //  Fine grained coherency between all devices using device-scope atomics\n} HSA_SVM_FLAGS;\n\ntypedef enum _HSA_SVM_ATTR_TYPE {\n\tHSA_SVM_ATTR_PREFERRED_LOC,  // gpuid of the preferred location, 0 for\n                                     // system memory, INVALID_NODEID for\n                                     // \"don't care\"\n\tHSA_SVM_ATTR_PREFETCH_LOC,   // gpuid of the prefetch location, 0 for\n                                     // system memory. Setting this triggers an\n                                     // immediate prefetch (migration)\n\tHSA_SVM_ATTR_ACCESS,\n\tHSA_SVM_ATTR_ACCESS_IN_PLACE,\n\tHSA_SVM_ATTR_NO_ACCESS,      // specify memory access for the gpuid given\n                                     // by the attribute value\n\tHSA_SVM_ATTR_SET_FLAGS,      // bitmask of flags to set (see HSA_SVM_FLAGS)\n\tHSA_SVM_ATTR_CLR_FLAGS,      // bitmask of flags to clear\n\tHSA_SVM_ATTR_GRANULARITY     // migration granularity (log2 num pages)\n} HSA_SVM_ATTR_TYPE;\n\ntypedef struct _HSA_SVM_ATTRIBUTE {\n\tHSAuint32 type;  // attribute type (see enum HSA_SVM_ATTR_TYPE)\n\tHSAuint32 value; // attribute value\n} HSA_SVM_ATTRIBUTE;\n\ntypedef enum _HSA_SMI_EVENT {\n\tHSA_SMI_EVENT_NONE = 0, /* not used */\n\tHSA_SMI_EVENT_VMFAULT = 1, /* event start counting at 1 */\n\tHSA_SMI_EVENT_THERMAL_THROTTLE = 2,\n\tHSA_SMI_EVENT_GPU_PRE_RESET = 3,\n\tHSA_SMI_EVENT_GPU_POST_RESET = 4,\n\tHSA_SMI_EVENT_MIGRATE_START = 5,\n\tHSA_SMI_EVENT_MIGRATE_END = 6,\n\tHSA_SMI_EVENT_PAGE_FAULT_START = 7,\n\tHSA_SMI_EVENT_PAGE_FAULT_END = 8,\n\tHSA_SMI_EVENT_QUEUE_EVICTION = 9,\n\tHSA_SMI_EVENT_QUEUE_RESTORE = 10,\n\tHSA_SMI_EVENT_UNMAP_FROM_GPU = 11,\n\tHSA_SMI_EVENT_INDEX_MAX = 12,\n\n\t/*\n\t * max event number, as a flag bit to get events from all processes,\n\t * this requires super user permission, otherwise will not be able to\n\t * receive event from any process. Without this flag to receive events\n\t * from same process.\n\t */\n\tHSA_SMI_EVENT_ALL_PROCESS = 64\n} HSA_EVENT_TYPE;\n\ntypedef enum _HSA_MIGRATE_TRIGGERS {\n\tHSA_MIGRATE_TRIGGER_PREFETCH,\n\tHSA_MIGRATE_TRIGGER_PAGEFAULT_GPU,\n\tHSA_MIGRATE_TRIGGER_PAGEFAULT_CPU,\n\tHSA_MIGRATE_TRIGGER_TTM_EVICTION\n} HSA_MIGRATE_TRIGGERS;\n\ntypedef enum _HSA_QUEUE_EVICTION_TRIGGERS {\n\tHSA_QUEUE_EVICTION_TRIGGER_SVM,\n\tHSA_QUEUE_EVICTION_TRIGGER_USERPTR,\n\tHSA_QUEUE_EVICTION_TRIGGER_TTM,\n\tHSA_QUEUE_EVICTION_TRIGGER_SUSPEND,\n\tHSA_QUEUE_EVICTION_CRIU_CHECKPOINT,\n\tHSA_QUEUE_EVICTION_CRIU_RESTORE\n} HSA_QUEUE_EVICTION_TRIGGERS;\n\ntypedef enum _HSA_SVM_UNMAP_TRIGGERS {\n\tHSA_SVM_UNMAP_TRIGGER_MMU_NOTIFY,\n\tHSA_SVM_UNMAP_TRIGGER_MMU_NOTIFY_MIGRATE,\n\tHSA_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU\n} HSA_SVM_UNMAP_TRIGGERS;\n\n#define HSA_SMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1))\n#define HSA_SMI_EVENT_MSG_SIZE\t96\n\ntypedef void *HsaAMDGPUDeviceHandle;\n\ntypedef HSAuint32 HsaPcSamplingTraceId;\n\ntypedef enum _HSA_PC_SAMPLING_METHOD_KIND\n{\n    HSA_PC_SAMPLING_METHOD_KIND_HOSTTRAP_V1 = 1,\n    HSA_PC_SAMPLING_METHOD_KIND_STOCHASTIC_V1,\n} HSA_PC_SAMPLING_METHOD_KIND;\n\ntypedef enum _HSA_PC_SAMPLING_UNITS\n{\n    HSA_PC_SAMPLING_UNIT_INTERVAL_MICROSECONDS,\n    HSA_PC_SAMPLING_UNIT_INTERVAL_CYCLES,\n    HSA_PC_SAMPLING_UNIT_INTERVAL_INSTRUCTIONS,\n} HSA_PC_SAMPLING_UNIT_INTERVAL;\n\ntypedef struct _HsaPcSamplingInfo\n{\n    HSAuint64 value;\n    HSAuint64 value_min;\n    HSAuint64 value_max;\n    HSAuint64 flags;\n    HSA_PC_SAMPLING_METHOD_KIND method;\n    HSA_PC_SAMPLING_UNIT_INTERVAL units;\n}\nHsaPcSamplingInfo;\n\ntypedef union\n{\n    HSAuint32 Value;\n    struct\n    {\n        unsigned int requiresVAddr : 1;  // Requires virtual address\n    } ui32;\n} HSA_REGISTER_MEM_FLAGS;\n\n#pragma pack(pop, hsakmttypes_h)\n\n\n#ifdef __cplusplus\n}   //extern \"C\"\n#endif\n\n#endif //_HSAKMTTYPES_H_\n"
  },
  {
    "path": "libhsakmt/include/hsakmt/linux/kfd_ioctl.h",
    "content": "/*\n * Copyright 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef KFD_IOCTL_H_INCLUDED\n#define KFD_IOCTL_H_INCLUDED\n\n#include <libdrm/drm.h>\n#include <linux/ioctl.h>\n\n/*\n * - 1.1 - initial version\n * - 1.3 - Add SMI events support\n * - 1.4 - Indicate new SRAM EDC bit in device properties\n * - 1.5 - Add SVM API\n * - 1.6 - Query clear flags in SVM get_attr API\n * - 1.7 - Checkpoint Restore (CRIU) API\n * - 1.8 - CRIU - Support for SDMA transfers with GTT BOs\n * - 1.9 - Add available_memory ioctl\n * - 1.10 - Add SMI profiler event log\n * - 1.11 - Add unified memory for ctx save/restore area\n * - 1.12 - Add DMA buf export ioctl\n * - 1.13 - Add debugger API\n * - 1.14 - Update kfd_event_data\n * - 1.15 - Enable managing mappings in compute VMs with GEM_VA ioctl\n * - 1.16 - Add contiguous VRAM allocation flag\n * - 1.17 - Add SDMA queue creation with target SDMA engine ID\n */\n#define KFD_IOCTL_MAJOR_VERSION 1\n#define KFD_IOCTL_MINOR_VERSION 17\n\nstruct kfd_ioctl_get_version_args {\n\t__u32 major_version;\t/* from KFD */\n\t__u32 minor_version;\t/* from KFD */\n};\n\n/* For kfd_ioctl_create_queue_args.queue_type. */\n#define KFD_IOC_QUEUE_TYPE_COMPUTE\t\t0x0\n#define KFD_IOC_QUEUE_TYPE_SDMA\t\t\t0x1\n#define KFD_IOC_QUEUE_TYPE_COMPUTE_AQL\t\t0x2\n#define KFD_IOC_QUEUE_TYPE_SDMA_XGMI\t\t0x3\n#define KFD_IOC_QUEUE_TYPE_SDMA_BY_ENG_ID\t0x4\n\n#define KFD_MAX_QUEUE_PERCENTAGE\t100\n#define KFD_MAX_QUEUE_PRIORITY\t\t15\n\nstruct kfd_ioctl_create_queue_args {\n\t__u64 ring_base_address;\t/* to KFD */\n\t__u64 write_pointer_address;\t/* from KFD */\n\t__u64 read_pointer_address;\t/* from KFD */\n\t__u64 doorbell_offset;\t/* from KFD */\n\n\t__u32 ring_size;\t\t/* to KFD */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 queue_type;\t\t/* to KFD */\n\t__u32 queue_percentage;\t/* to KFD */\n\t__u32 queue_priority;\t/* to KFD */\n\t__u32 queue_id;\t\t/* from KFD */\n\n\t__u64 eop_buffer_address;\t/* to KFD */\n\t__u64 eop_buffer_size;\t/* to KFD */\n\t__u64 ctx_save_restore_address; /* to KFD */\n\t__u32 ctx_save_restore_size;\t/* to KFD */\n\t__u32 ctl_stack_size;\t\t/* to KFD */\n\t__u32 sdma_engine_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_destroy_queue_args {\n\t__u32 queue_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_update_queue_args {\n\t__u64 ring_base_address;\t/* to KFD */\n\n\t__u32 queue_id;\t\t/* to KFD */\n\t__u32 ring_size;\t\t/* to KFD */\n\t__u32 queue_percentage;\t/* to KFD */\n\t__u32 queue_priority;\t/* to KFD */\n};\n\nstruct kfd_ioctl_set_cu_mask_args {\n\t__u32 queue_id;\t\t/* to KFD */\n\t__u32 num_cu_mask;\t\t/* to KFD */\n\t__u64 cu_mask_ptr;\t\t/* to KFD */\n};\n\nstruct kfd_ioctl_get_queue_wave_state_args {\n\t__u64 ctl_stack_address;\t/* to KFD */\n\t__u32 ctl_stack_used_size;\t/* from KFD */\n\t__u32 save_area_used_size;\t/* from KFD */\n\t__u32 queue_id;\t\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_queue_snapshot_entry {\n\t__u64 exception_status;\n\t__u64 ring_base_address;\n\t__u64 write_pointer_address;\n\t__u64 read_pointer_address;\n\t__u64 ctx_save_restore_address;\n\t__u32 queue_id;\n\t__u32 gpu_id;\n\t__u32 ring_size;\n\t__u32 queue_type;\n\t__u32 ctx_save_restore_area_size;\n\t__u32 reserved;\n};\n\nstruct kfd_dbg_device_info_entry {\n\t__u64 exception_status;\n\t__u64 lds_base;\n\t__u64 lds_limit;\n\t__u64 scratch_base;\n\t__u64 scratch_limit;\n\t__u64 gpuvm_base;\n\t__u64 gpuvm_limit;\n\t__u32 gpu_id;\n\t__u32 location_id;\n\t__u32 vendor_id;\n\t__u32 device_id;\n\t__u32 revision_id;\n\t__u32 subsystem_vendor_id;\n\t__u32 subsystem_device_id;\n\t__u32 fw_version;\n\t__u32 gfx_target_version;\n\t__u32 simd_count;\n\t__u32 max_waves_per_simd;\n\t__u32 array_count;\n\t__u32 simd_arrays_per_engine;\n\t__u32 num_xcc;\n\t__u32 capability;\n\t__u32 debug_prop;\n};\n\n/* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */\n#define KFD_IOC_CACHE_POLICY_COHERENT 0\n#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1\n\nstruct kfd_ioctl_set_memory_policy_args {\n\t__u64 alternate_aperture_base;\t/* to KFD */\n\t__u64 alternate_aperture_size;\t/* to KFD */\n\n\t__u32 gpu_id;\t\t\t/* to KFD */\n\t__u32 default_policy;\t\t/* to KFD */\n\t__u32 alternate_policy;\t\t/* to KFD */\n\t__u32 misc_process_flag;        /* to KFD */\n};\n\n/*\n * All counters are monotonic. They are used for profiling of compute jobs.\n * The profiling is done by userspace.\n *\n * In case of GPU reset, the counter should not be affected.\n */\n\nstruct kfd_ioctl_get_clock_counters_args {\n\t__u64 gpu_clock_counter;\t/* from KFD */\n\t__u64 cpu_clock_counter;\t/* from KFD */\n\t__u64 system_clock_counter;\t/* from KFD */\n\t__u64 system_clock_freq;\t/* from KFD */\n\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_process_device_apertures {\n\t__u64 lds_base;\t\t/* from KFD */\n\t__u64 lds_limit;\t\t/* from KFD */\n\t__u64 scratch_base;\t\t/* from KFD */\n\t__u64 scratch_limit;\t\t/* from KFD */\n\t__u64 gpuvm_base;\t\t/* from KFD */\n\t__u64 gpuvm_limit;\t\t/* from KFD */\n\t__u32 gpu_id;\t\t/* from KFD */\n\t__u32 pad;\n};\n\n/*\n * AMDKFD_IOC_GET_PROCESS_APERTURES is deprecated. Use\n * AMDKFD_IOC_GET_PROCESS_APERTURES_NEW instead, which supports an\n * unlimited number of GPUs.\n */\n#define NUM_OF_SUPPORTED_GPUS 7\nstruct kfd_ioctl_get_process_apertures_args {\n\tstruct kfd_process_device_apertures\n\t\t\tprocess_apertures[NUM_OF_SUPPORTED_GPUS];/* from KFD */\n\n\t/* from KFD, should be in the range [1 - NUM_OF_SUPPORTED_GPUS] */\n\t__u32 num_of_nodes;\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_get_process_apertures_new_args {\n\t/* User allocated. Pointer to struct kfd_process_device_apertures\n\t * filled in by Kernel\n\t */\n\t__u64 kfd_process_device_apertures_ptr;\n\t/* to KFD - indicates amount of memory present in\n\t *  kfd_process_device_apertures_ptr\n\t * from KFD - Number of entries filled by KFD.\n\t */\n\t__u32 num_of_nodes;\n\t__u32 pad;\n};\n\n#define MAX_ALLOWED_NUM_POINTS    100\n#define MAX_ALLOWED_AW_BUFF_SIZE 4096\n#define MAX_ALLOWED_WAC_BUFF_SIZE  128\n\nstruct kfd_ioctl_dbg_register_args {\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_dbg_unregister_args {\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_dbg_address_watch_args {\n\t__u64 content_ptr;\t\t/* a pointer to the actual content */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 buf_size_in_bytes;\t/*including gpu_id and buf_size */\n};\n\nstruct kfd_ioctl_dbg_wave_control_args {\n\t__u64 content_ptr;\t\t/* a pointer to the actual content */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 buf_size_in_bytes;\t/*including gpu_id and buf_size */\n};\n#define\tKFD_DBG_EV_FLAG_CLEAR_STATUS\t1\n\n/* queue states for suspend/resume */\n#define KFD_DBG_QUEUE_ERROR_BIT\t\t30\n#define KFD_DBG_QUEUE_INVALID_BIT\t31\n#define KFD_DBG_QUEUE_ERROR_MASK\t(1 << KFD_DBG_QUEUE_ERROR_BIT)\n#define KFD_DBG_QUEUE_INVALID_MASK\t(1 << KFD_DBG_QUEUE_INVALID_BIT)\n\n#define KFD_INVALID_GPUID\t0xffffffff\n#define KFD_INVALID_QUEUEID\t0xffffffff\n#define KFD_INVALID_FD\t\t0xffffffff\n\nenum kfd_dbg_trap_override_mode {\n\tKFD_DBG_TRAP_OVERRIDE_OR = 0,\n\tKFD_DBG_TRAP_OVERRIDE_REPLACE = 1\n};\nenum kfd_dbg_trap_mask {\n\tKFD_DBG_TRAP_MASK_FP_INVALID = 1,\n\tKFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL = 2,\n\tKFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO = 4,\n\tKFD_DBG_TRAP_MASK_FP_OVERFLOW = 8,\n\tKFD_DBG_TRAP_MASK_FP_UNDERFLOW = 16,\n\tKFD_DBG_TRAP_MASK_FP_INEXACT = 32,\n\tKFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO = 64,\n\tKFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH = 128,\n\tKFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION = 256,\n\tKFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START = (1 << 30),\n\tKFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END = (1 << 31)\n};\n\n/* Wave launch modes */\nenum kfd_dbg_trap_wave_launch_mode {\n\tKFD_DBG_TRAP_WAVE_LAUNCH_MODE_NORMAL = 0,\n\tKFD_DBG_TRAP_WAVE_LAUNCH_MODE_HALT = 1,\n\tKFD_DBG_TRAP_WAVE_LAUNCH_MODE_DEBUG = 3\n};\n\n/* Address watch modes */\nenum kfd_dbg_trap_address_watch_mode {\n\tKFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ = 0,\n\tKFD_DBG_TRAP_ADDRESS_WATCH_MODE_NONREAD = 1,\n\tKFD_DBG_TRAP_ADDRESS_WATCH_MODE_ATOMIC = 2,\n\tKFD_DBG_TRAP_ADDRESS_WATCH_MODE_ALL = 3\n};\n\n/* Additional wave settings */\nenum kfd_dbg_trap_flags {\n\tKFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1,\n};\n\nenum kfd_dbg_trap_exception_code {\n\tEC_NONE = 0,\n\t/* per queue */\n\tEC_QUEUE_WAVE_ABORT = 1,\n\tEC_QUEUE_WAVE_TRAP = 2,\n\tEC_QUEUE_WAVE_MATH_ERROR = 3,\n\tEC_QUEUE_WAVE_ILLEGAL_INSTRUCTION = 4,\n\tEC_QUEUE_WAVE_MEMORY_VIOLATION = 5,\n\tEC_QUEUE_WAVE_APERTURE_VIOLATION = 6,\n\tEC_QUEUE_PACKET_DISPATCH_DIM_INVALID = 16,\n\tEC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID = 17,\n\tEC_QUEUE_PACKET_DISPATCH_CODE_INVALID = 18,\n\tEC_QUEUE_PACKET_RESERVED = 19,\n\tEC_QUEUE_PACKET_UNSUPPORTED = 20,\n\tEC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID = 21,\n\tEC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID = 22,\n\tEC_QUEUE_PACKET_VENDOR_UNSUPPORTED = 23,\n\tEC_QUEUE_PREEMPTION_ERROR = 30,\n\tEC_QUEUE_NEW = 31,\n\t/* per device */\n\tEC_DEVICE_QUEUE_DELETE = 32,\n\tEC_DEVICE_MEMORY_VIOLATION = 33,\n\tEC_DEVICE_RAS_ERROR = 34,\n\tEC_DEVICE_FATAL_HALT = 35,\n\tEC_DEVICE_NEW = 36,\n\t/* per process */\n\tEC_PROCESS_RUNTIME = 48,\n\tEC_PROCESS_DEVICE_REMOVE = 49,\n\tEC_MAX\n};\n\n/* Mask generated by ecode defined in enum above. */\n#define KFD_EC_MASK(ecode)\t(1ULL << (ecode - 1))\n\n/* Masks for exception code type checks below. */\n#define KFD_EC_MASK_QUEUE\t(KFD_EC_MASK(EC_QUEUE_WAVE_ABORT) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_WAVE_MATH_ERROR) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_WAVE_MEMORY_VIOLATION) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_WAVE_APERTURE_VIOLATION) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED)\t|\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_PREEMPTION_ERROR)\t|\t\\\n\t\t\t\t KFD_EC_MASK(EC_QUEUE_NEW))\n#define KFD_EC_MASK_DEVICE\t(KFD_EC_MASK(EC_DEVICE_QUEUE_DELETE) |\t\t\\\n\t\t\t\t KFD_EC_MASK(EC_DEVICE_RAS_ERROR) |\t\t\\\n\t\t\t\t KFD_EC_MASK(EC_DEVICE_FATAL_HALT) |\t\t\\\n\t\t\t\t KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_DEVICE_NEW))\n#define KFD_EC_MASK_PROCESS\t(KFD_EC_MASK(EC_PROCESS_RUNTIME) |\t\\\n\t\t\t\t KFD_EC_MASK(EC_PROCESS_DEVICE_REMOVE))\n\n/* Checks for exception code types for KFD search. */\n#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode)\t\t\t\t\t\\\n\t\t\t(!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE))\n#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode)\t\t\t\t\\\n\t\t\t(!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE))\n#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode)\t\t\t\t\\\n\t\t\t(!!(KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS))\n\n/* Misc. per process flags */\n#define ENABLE_MFMA_HIGH_PRECISION              (1 << 0)\n\nenum kfd_dbg_runtime_state {\n\tDEBUG_RUNTIME_STATE_DISABLED = 0,\n\tDEBUG_RUNTIME_STATE_ENABLED = 1,\n\tDEBUG_RUNTIME_STATE_ENABLED_BUSY = 2,\n\tDEBUG_RUNTIME_STATE_ENABLED_ERROR = 3\n};\n\nstruct kfd_runtime_info {\n\t__u64 r_debug;\n\t__u32 runtime_state;\n\t__u32 ttmp_setup;\n};\n\n/* Enable modes for runtime enable */\n#define KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK\t1\n#define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK\t2\n#define KFD_RUNTIME_ENABLE_CAPS_SUPPORTS_CORE_DUMP_MASK 0x80000000\n\n/**\n * kfd_ioctl_runtime_enable_args - Arguments for runtime enable\n *\n * Coordinates debug exception signalling and debug device enablement with runtime.\n *\n * @r_debug - pointer to user struct for sharing information between ROCr and the debuggger\n * @mode_mask - mask to set mode\n *\tKFD_RUNTIME_ENABLE_MODE_ENABLE_MASK - enable runtime for debugging, otherwise disable\n *\tKFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK - enable trap temporary setup (ignore on disable)\n *\n * Return - 0 on SUCCESS.\n *\t  - EBUSY if runtime enable call already pending.\n *\t  - EEXIST if user queues already active prior to call.\n *\t    If process is debug enabled, runtime enable will enable debug devices and\n *\t    wait for debugger process to send runtime exception EC_PROCESS_RUNTIME\n *\t    to unblock - see kfd_ioctl_dbg_trap_args.\n *\n */\nstruct kfd_ioctl_runtime_enable_args {\n\t__u64 r_debug;\n\t__u32 mode_mask;\n\t__u32 capabilities_mask;\n};\n\n/* Context save area header information */\nstruct kfd_context_save_area_header {\n\tstruct {\n\t\t__u32 control_stack_offset;\n\t\t__u32 control_stack_size;\n\t\t__u32 wave_state_offset;\n\t\t__u32 wave_state_size;\n\t} wave_state;\n\t__u32 debug_offset;\n\t__u32 debug_size;\n\t__u64 err_payload_addr;\n\t__u32 err_event_id;\n\t__u32 reserved1;\n};\n\n/*\n * Debug operations\n *\n * For specifics on usage and return values, see documentation per operation\n * below.  Otherwise, generic error returns apply:\n *\t- ESRCH if the process to debug does not exist.\n *\n *\t- EINVAL (with KFD_IOC_DBG_TRAP_ENABLE exempt) if operation\n *\t\t KFD_IOC_DBG_TRAP_ENABLE has not succeeded prior.\n *\t\t Also returns this error if GPU hardware scheduling is not supported.\n *\n *\t- EPERM (with KFD_IOC_DBG_TRAP_DISABLE exempt) if target process is not\n *\t\t PTRACE_ATTACHED.  KFD_IOC_DBG_TRAP_DISABLE is exempt to allow\n *\t\t clean up of debug mode as long as process is debug enabled.\n *\n *\t- EACCES if any DBG_HW_OP (debug hardware operation) is requested when\n *\t\t AMDKFD_IOC_RUNTIME_ENABLE has not succeeded prior.\n *\n *\t- ENODEV if any GPU does not support debugging on a DBG_HW_OP call.\n *\n *\t- Other errors may be returned when a DBG_HW_OP occurs while the GPU\n *\t  is in a fatal state.\n *\n */\nenum kfd_dbg_trap_operations {\n\tKFD_IOC_DBG_TRAP_ENABLE = 0,\n\tKFD_IOC_DBG_TRAP_DISABLE = 1,\n\tKFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT = 2,\n\tKFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED = 3,\n\tKFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE = 4,  /* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE = 5,      /* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_SUSPEND_QUEUES = 6,\t\t/* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_RESUME_QUEUES = 7,\t\t/* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH = 8,\t/* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH = 9,\t/* DBG_HW_OP */\n\tKFD_IOC_DBG_TRAP_SET_FLAGS = 10,\n\tKFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT = 11,\n\tKFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO = 12,\n\tKFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT = 13,\n\tKFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT = 14\n};\n\n/**\n * kfd_ioctl_dbg_trap_enable_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_ENABLE.\n *\n *     Enables debug session for target process. Call @op KFD_IOC_DBG_TRAP_DISABLE in\n *     kfd_ioctl_dbg_trap_args to disable debug session.\n *\n *     @exception_mask (IN)\t- exceptions to raise to the debugger\n *     @rinfo_ptr      (IN)\t- pointer to runtime info buffer (see kfd_runtime_info)\n *     @rinfo_size     (IN/OUT)\t- size of runtime info buffer in bytes\n *     @dbg_fd\t       (IN)\t- fd the KFD will nofify the debugger with of raised\n *\t\t\t\t  exceptions set in exception_mask.\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t\tCopies KFD saved kfd_runtime_info to @rinfo_ptr on enable.\n *\t\tSize of kfd_runtime saved by the KFD returned to @rinfo_size.\n *            - EBADF if KFD cannot get a reference to dbg_fd.\n *            - EFAULT if KFD cannot copy runtime info to rinfo_ptr.\n *            - EINVAL if target process is already debug enabled.\n *\n */\nstruct kfd_ioctl_dbg_trap_enable_args {\n\t__u64 exception_mask;\n\t__u64 rinfo_ptr;\n\t__u32 rinfo_size;\n\t__u32 dbg_fd;\n};\n\n/**\n * kfd_ioctl_dbg_trap_send_runtime_event_args\n *\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT.\n *     Raises exceptions to runtime.\n *\n *     @exception_mask (IN) - exceptions to raise to runtime\n *     @gpu_id\t       (IN) - target device id\n *     @queue_id       (IN) - target queue id\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t      - ENODEV if gpu_id not found.\n *\t\tIf exception_mask contains EC_PROCESS_RUNTIME, unblocks pending\n *\t\tAMDKFD_IOC_RUNTIME_ENABLE call - see kfd_ioctl_runtime_enable_args.\n *\t\tAll other exceptions are raised to runtime through err_payload_addr.\n *\t\tSee kfd_context_save_area_header.\n */\nstruct kfd_ioctl_dbg_trap_send_runtime_event_args {\n\t__u64 exception_mask;\n\t__u32 gpu_id;\n\t__u32 queue_id;\n};\n\n/**\n * kfd_ioctl_dbg_trap_set_exceptions_enabled_args\n *\n *     Arguments for KFD_IOC_SET_EXCEPTIONS_ENABLED\n *     Set new exceptions to be raised to the debugger.\n *\n *     @exception_mask (IN) - new exceptions to raise the debugger\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n */\nstruct kfd_ioctl_dbg_trap_set_exceptions_enabled_args {\n\t__u64 exception_mask;\n};\n\n/**\n * kfd_ioctl_dbg_trap_set_wave_launch_override_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE\n *     Enable HW exceptions to raise trap.\n *\n *     @override_mode\t     (IN)     - see kfd_dbg_trap_override_mode\n *     @enable_mask\t     (IN/OUT) - reference kfd_dbg_trap_mask.\n *\t\t\t\t\tIN is the override modes requested to be enabled.\n *\t\t\t\t\tOUT is referenced in Return below.\n *     @support_request_mask (IN/OUT) - reference kfd_dbg_trap_mask.\n *\t\t\t\t\tIN is the override modes requested for support check.\n *\t\t\t\t\tOUT is referenced in Return below.\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t\tPrevious enablement is returned in @enable_mask.\n *\t\tActual override support is returned in @support_request_mask.\n *\t      - EINVAL if override mode is not supported.\n *\t      - EACCES if trap support requested is not actually supported.\n *\t\ti.e. enable_mask (IN) is not a subset of support_request_mask (OUT).\n *\t\tOtherwise it is considered a generic error (see kfd_dbg_trap_operations).\n */\nstruct kfd_ioctl_dbg_trap_set_wave_launch_override_args {\n\t__u32 override_mode;\n\t__u32 enable_mask;\n\t__u32 support_request_mask;\n\t__u32 pad;\n};\n\n/**\n * kfd_ioctl_dbg_trap_set_wave_launch_mode_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE\n *     Set wave launch mode.\n *\n *     @mode (IN) - see kfd_dbg_trap_wave_launch_mode\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n */\nstruct kfd_ioctl_dbg_trap_set_wave_launch_mode_args {\n\t__u32 launch_mode;\n\t__u32 pad;\n};\n\n/**\n * kfd_ioctl_dbg_trap_suspend_queues_ags\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SUSPEND_QUEUES\n *     Suspend queues.\n *\n *     @exception_mask\t(IN) - raised exceptions to clear\n *     @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id)\n *\t\t\t       to suspend\n *     @num_queues\t(IN) - number of queues to suspend in @queue_array_ptr\n *     @grace_period\t(IN) - wave time allowance before preemption\n *\t\t\t       per 1K GPU clock cycle unit\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Destruction of a suspended queue is blocked until the queue is\n *     resumed.  This allows the debugger to access queue information and\n *     the its context save area without running into a race condition on\n *     queue destruction.\n *     Automatically copies per queue context save area header information\n *     into the save area base\n *     (see kfd_queue_snapshot_entry and kfd_context_save_area_header).\n *\n *     Return - Number of queues suspended on SUCCESS.\n *\t.\tKFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK masked\n *\t\tfor each queue id in @queue_array_ptr array reports unsuccessful\n *\t\tsuspend reason.\n *\t\tKFD_DBG_QUEUE_ERROR_MASK = HW failure.\n *\t\tKFD_DBG_QUEUE_INVALID_MASK = queue does not exist, is new or\n *\t\tis being destroyed.\n */\nstruct kfd_ioctl_dbg_trap_suspend_queues_args {\n\t__u64 exception_mask;\n\t__u64 queue_array_ptr;\n\t__u32 num_queues;\n\t__u32 grace_period;\n};\n\n/**\n * kfd_ioctl_dbg_trap_resume_queues_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_RESUME_QUEUES\n *     Resume queues.\n *\n *     @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id)\n *\t\t\t       to resume\n *     @num_queues\t(IN) - number of queues to resume in @queue_array_ptr\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - Number of queues resumed on SUCCESS.\n *\t\tKFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK mask\n *\t\tfor each queue id in @queue_array_ptr array reports unsuccessful\n *\t\tresume reason.\n *\t\tKFD_DBG_QUEUE_ERROR_MASK = HW failure.\n *\t\tKFD_DBG_QUEUE_INVALID_MASK = queue does not exist.\n */\nstruct kfd_ioctl_dbg_trap_resume_queues_args {\n\t__u64 queue_array_ptr;\n\t__u32 num_queues;\n\t__u32 pad;\n};\n\n/**\n * kfd_ioctl_dbg_trap_set_node_address_watch_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH\n *     Sets address watch for device.\n *\n *     @address\t(IN)  - watch address to set\n *     @mode    (IN)  - see kfd_dbg_trap_address_watch_mode\n *     @mask    (IN)  - watch address mask\n *     @gpu_id  (IN)  - target gpu to set watch point\n *     @id      (OUT) - watch id allocated\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t\tAllocated watch ID returned to @id.\n *\t      - ENODEV if gpu_id not found.\n *\t      - ENOMEM if watch IDs can be allocated\n */\nstruct kfd_ioctl_dbg_trap_set_node_address_watch_args {\n\t__u64 address;\n\t__u32 mode;\n\t__u32 mask;\n\t__u32 gpu_id;\n\t__u32 id;\n};\n\n/**\n * kfd_ioctl_dbg_trap_clear_node_address_watch_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH\n *     Clear address watch for device.\n *\n *     @gpu_id  (IN)  - target device to clear watch point\n *     @id      (IN) - allocated watch id to clear\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t      - ENODEV if gpu_id not found.\n *\t      - EINVAL if watch ID has not been allocated.\n */\nstruct kfd_ioctl_dbg_trap_clear_node_address_watch_args {\n\t__u32 gpu_id;\n\t__u32 id;\n};\n\n/**\n * kfd_ioctl_dbg_trap_set_flags_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_SET_FLAGS\n *     Sets flags for wave behaviour.\n *\n *     @flags (IN/OUT) - IN = flags to enable, OUT = flags previously enabled\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *\t      - EACCESS if any debug device does not allow flag options.\n */\nstruct kfd_ioctl_dbg_trap_set_flags_args {\n\t__u32 flags;\n\t__u32 pad;\n};\n\n/**\n * kfd_ioctl_dbg_trap_query_debug_event_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT\n *\n *     Find one or more raised exceptions. This function can return multiple\n *     exceptions from a single queue or a single device with one call. To find\n *     all raised exceptions, this function must be called repeatedly until it\n *     returns -EAGAIN. Returned exceptions can optionally be cleared by\n *     setting the corresponding bit in the @exception_mask input parameter.\n *     However, clearing an exception prevents retrieving further information\n *     about it with KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO.\n *\n *     @exception_mask (IN/OUT) - exception to clear (IN) and raised (OUT)\n *     @gpu_id\t       (OUT)    - gpu id of exceptions raised\n *     @queue_id       (OUT)    - queue id of exceptions raised\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on raised exception found\n *              Raised exceptions found are returned in @exception mask\n *              with reported source id returned in @gpu_id or @queue_id.\n *            - EAGAIN if no raised exception has been found\n */\nstruct kfd_ioctl_dbg_trap_query_debug_event_args {\n\t__u64 exception_mask;\n\t__u32 gpu_id;\n\t__u32 queue_id;\n};\n\n/**\n * kfd_ioctl_dbg_trap_query_exception_info_args\n *\n *     Arguments KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO\n *     Get additional info on raised exception.\n *\n *     @info_ptr\t(IN)\t - pointer to exception info buffer to copy to\n *     @info_size\t(IN/OUT) - exception info buffer size (bytes)\n *     @source_id\t(IN)     - target gpu or queue id\n *     @exception_code\t(IN)     - target exception\n *     @clear_exception\t(IN)     - clear raised @exception_code exception\n *\t\t\t\t   (0 = false, 1 = true)\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *              If @exception_code is EC_DEVICE_MEMORY_VIOLATION, copy @info_size(OUT)\n *\t\tbytes of memory exception data to @info_ptr.\n *              If @exception_code is EC_PROCESS_RUNTIME, copy saved\n *              kfd_runtime_info to @info_ptr.\n *              Actual required @info_ptr size (bytes) is returned in @info_size.\n */\nstruct kfd_ioctl_dbg_trap_query_exception_info_args {\n\t__u64 info_ptr;\n\t__u32 info_size;\n\t__u32 source_id;\n\t__u32 exception_code;\n\t__u32 clear_exception;\n};\n\n/**\n * kfd_ioctl_dbg_trap_get_queue_snapshot_args\n *\n *     Arguments KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT\n *     Get queue information.\n *\n *     @exception_mask\t (IN)\t  - exceptions raised to clear\n *     @snapshot_buf_ptr (IN)\t  - queue snapshot entry buffer (see kfd_queue_snapshot_entry)\n *     @num_queues\t (IN/OUT) - number of queue snapshot entries\n *         The debugger specifies the size of the array allocated in @num_queues.\n *         KFD returns the number of queues that actually existed. If this is\n *         larger than the size specified by the debugger, KFD will not overflow\n *         the array allocated by the debugger.\n *\n *     @entry_size\t (IN/OUT) - size per entry in bytes\n *         The debugger specifies sizeof(struct kfd_queue_snapshot_entry) in\n *         @entry_size. KFD returns the number of bytes actually populated per\n *         entry. The debugger should use the KFD_IOCTL_MINOR_VERSION to determine,\n *         which fields in struct kfd_queue_snapshot_entry are valid. This allows\n *         growing the ABI in a backwards compatible manner.\n *         Note that entry_size(IN) should still be used to stride the snapshot buffer in the\n *         event that it's larger than actual kfd_queue_snapshot_entry.\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *              Copies @num_queues(IN) queue snapshot entries of size @entry_size(IN)\n *              into @snapshot_buf_ptr if @num_queues(IN) > 0.\n *              Otherwise return @num_queues(OUT) queue snapshot entries that exist.\n */\nstruct kfd_ioctl_dbg_trap_queue_snapshot_args {\n\t__u64 exception_mask;\n\t__u64 snapshot_buf_ptr;\n\t__u32 num_queues;\n\t__u32 entry_size;\n};\n\n/**\n * kfd_ioctl_dbg_trap_get_device_snapshot_args\n *\n *     Arguments for KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT\n *     Get device information.\n *\n *     @exception_mask\t (IN)\t  - exceptions raised to clear\n *     @snapshot_buf_ptr (IN)\t  - pointer to snapshot buffer (see kfd_dbg_device_info_entry)\n *     @num_devices\t (IN/OUT) - number of debug devices to snapshot\n *         The debugger specifies the size of the array allocated in @num_devices.\n *         KFD returns the number of devices that actually existed. If this is\n *         larger than the size specified by the debugger, KFD will not overflow\n *         the array allocated by the debugger.\n *\n *     @entry_size\t (IN/OUT) - size per entry in bytes\n *         The debugger specifies sizeof(struct kfd_dbg_device_info_entry) in\n *         @entry_size. KFD returns the number of bytes actually populated. The\n *         debugger should use KFD_IOCTL_MINOR_VERSION to determine, which fields\n *         in struct kfd_dbg_device_info_entry are valid. This allows growing the\n *         ABI in a backwards compatible manner.\n *         Note that entry_size(IN) should still be used to stride the snapshot buffer in the\n *         event that it's larger than actual kfd_dbg_device_info_entry.\n *\n *     Generic errors apply (see kfd_dbg_trap_operations).\n *     Return - 0 on SUCCESS.\n *              Copies @num_devices(IN) device snapshot entries of size @entry_size(IN)\n *              into @snapshot_buf_ptr if @num_devices(IN) > 0.\n *              Otherwise return @num_devices(OUT) queue snapshot entries that exist.\n */\nstruct kfd_ioctl_dbg_trap_device_snapshot_args {\n\t__u64 exception_mask;\n\t__u64 snapshot_buf_ptr;\n\t__u32 num_devices;\n\t__u32 entry_size;\n};\n\n/**\n * kfd_ioctl_dbg_trap_args\n *\n * Arguments to debug target process.\n *\n *     @pid - target process to debug\n *     @op  - debug operation (see kfd_dbg_trap_operations)\n *\n *     @op determines which union struct args to use.\n *     Refer to kern docs for each kfd_ioctl_dbg_trap_*_args struct.\n */\nstruct kfd_ioctl_dbg_trap_args {\n\t__u32 pid;\n\t__u32 op;\n\n\tunion {\n\t\tstruct kfd_ioctl_dbg_trap_enable_args enable;\n\t\tstruct kfd_ioctl_dbg_trap_send_runtime_event_args send_runtime_event;\n\t\tstruct kfd_ioctl_dbg_trap_set_exceptions_enabled_args set_exceptions_enabled;\n\t\tstruct kfd_ioctl_dbg_trap_set_wave_launch_override_args launch_override;\n\t\tstruct kfd_ioctl_dbg_trap_set_wave_launch_mode_args launch_mode;\n\t\tstruct kfd_ioctl_dbg_trap_suspend_queues_args suspend_queues;\n\t\tstruct kfd_ioctl_dbg_trap_resume_queues_args resume_queues;\n\t\tstruct kfd_ioctl_dbg_trap_set_node_address_watch_args set_node_address_watch;\n\t\tstruct kfd_ioctl_dbg_trap_clear_node_address_watch_args clear_node_address_watch;\n\t\tstruct kfd_ioctl_dbg_trap_set_flags_args set_flags;\n\t\tstruct kfd_ioctl_dbg_trap_query_debug_event_args query_debug_event;\n\t\tstruct kfd_ioctl_dbg_trap_query_exception_info_args query_exception_info;\n\t\tstruct kfd_ioctl_dbg_trap_queue_snapshot_args queue_snapshot;\n\t\tstruct kfd_ioctl_dbg_trap_device_snapshot_args device_snapshot;\n\t};\n};\n\n/* Matching HSA_EVENTTYPE */\n#define KFD_IOC_EVENT_SIGNAL\t\t\t0\n#define KFD_IOC_EVENT_NODECHANGE\t\t1\n#define KFD_IOC_EVENT_DEVICESTATECHANGE\t\t2\n#define KFD_IOC_EVENT_HW_EXCEPTION\t\t3\n#define KFD_IOC_EVENT_SYSTEM_EVENT\t\t4\n#define KFD_IOC_EVENT_DEBUG_EVENT\t\t5\n#define KFD_IOC_EVENT_PROFILE_EVENT\t\t6\n#define KFD_IOC_EVENT_QUEUE_EVENT\t\t7\n#define KFD_IOC_EVENT_MEMORY\t\t\t8\n\n#define KFD_IOC_WAIT_RESULT_COMPLETE\t\t0\n#define KFD_IOC_WAIT_RESULT_TIMEOUT\t\t1\n#define KFD_IOC_WAIT_RESULT_FAIL\t\t2\n\n#define KFD_SIGNAL_EVENT_LIMIT\t\t\t4096\n\n/* For kfd_event_data.hw_exception_data.reset_type. */\n#define KFD_HW_EXCEPTION_WHOLE_GPU_RESET\t0\n#define KFD_HW_EXCEPTION_PER_ENGINE_RESET\t1\n\n/* For kfd_event_data.hw_exception_data.reset_cause. */\n#define KFD_HW_EXCEPTION_GPU_HANG\t0\n#define KFD_HW_EXCEPTION_ECC\t\t1\n\n/* For kfd_hsa_memory_exception_data.ErrorType */\n#define KFD_MEM_ERR_NO_RAS\t\t0\n#define KFD_MEM_ERR_SRAM_ECC\t\t1\n#define KFD_MEM_ERR_POISON_CONSUMED\t2\n#define KFD_MEM_ERR_GPU_HANG\t\t3\n\nstruct kfd_ioctl_create_event_args {\n\t__u64 event_page_offset;\t/* from KFD */\n\t__u32 event_trigger_data;\t/* from KFD - signal events only */\n\t__u32 event_type;\t\t/* to KFD */\n\t__u32 auto_reset;\t\t/* to KFD */\n\t__u32 node_id;\t\t/* to KFD - only valid for certain\n\t\t\t\t\t\t\tevent types */\n\t__u32 event_id;\t\t/* from KFD */\n\t__u32 event_slot_index;\t/* from KFD */\n};\n\nstruct kfd_ioctl_destroy_event_args {\n\t__u32 event_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_set_event_args {\n\t__u32 event_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_reset_event_args {\n\t__u32 event_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_memory_exception_failure {\n\t__u32 NotPresent;\t/* Page not present or supervisor privilege */\n\t__u32 ReadOnly;\t/* Write access to a read-only page */\n\t__u32 NoExecute;\t/* Execute access to a page marked NX */\n\t__u32 imprecise;\t/* Can't determine the\texact fault address */\n};\n\n/* memory exception data */\nstruct kfd_hsa_memory_exception_data {\n\tstruct kfd_memory_exception_failure failure;\n\t__u64 va;\n\t__u32 gpu_id;\n\t__u32 ErrorType; /* 0 = no RAS error,\n\t\t\t  * 1 = ECC_SRAM,\n\t\t\t  * 2 = Link_SYNFLOOD (poison),\n\t\t\t  * 3 = GPU hang (not attributable to a specific cause),\n\t\t\t  * other values reserved\n\t\t\t  */\n};\n\n/* hw exception data */\nstruct kfd_hsa_hw_exception_data {\n\t__u32 reset_type;\n\t__u32 reset_cause;\n\t__u32 memory_lost;\n\t__u32 gpu_id;\n};\n\n/* hsa signal event data */\nstruct kfd_hsa_signal_event_data {\n\t__u64 last_event_age;\t/* to and from KFD */\n};\n\n/* Event data */\nstruct kfd_event_data {\n\tunion {\n\t\t/* From KFD */\n\t\tstruct kfd_hsa_memory_exception_data memory_exception_data;\n\t\tstruct kfd_hsa_hw_exception_data hw_exception_data;\n\t\t/* To and From KFD */\n\t\tstruct kfd_hsa_signal_event_data signal_event_data;\n\t};\n\t__u64 kfd_event_data_ext;\t/* pointer to an extension structure\n\t\t\t\t\t   for future exception types */\n\t__u32 event_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_wait_events_args {\n\t__u64 events_ptr;\t\t/* pointed to struct\n\t\t\t\t\t   kfd_event_data array, to KFD */\n\t__u32 num_events;\t\t/* to KFD */\n\t__u32 wait_for_all;\t\t/* to KFD */\n\t__u32 timeout;\t\t/* to KFD */\n\t__u32 wait_result;\t\t/* from KFD */\n};\n\nstruct kfd_ioctl_set_scratch_backing_va_args {\n\t__u64 va_addr;\t/* to KFD */\n\t__u32 gpu_id;\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_get_tile_config_args {\n\t/* to KFD: pointer to tile array */\n\t__u64 tile_config_ptr;\n\t/* to KFD: pointer to macro tile array */\n\t__u64 macro_tile_config_ptr;\n\t/* to KFD: array size allocated by user mode\n\t * from KFD: array size filled by kernel\n\t */\n\t__u32 num_tile_configs;\n\t/* to KFD: array size allocated by user mode\n\t * from KFD: array size filled by kernel\n\t */\n\t__u32 num_macro_tile_configs;\n\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 gb_addr_config;\t/* from KFD */\n\t__u32 num_banks;\t\t/* from KFD */\n\t__u32 num_ranks;\t\t/* from KFD */\n\t/* struct size can be extended later if needed\n\t * without breaking ABI compatibility\n\t */\n};\n\nstruct kfd_ioctl_set_trap_handler_args {\n\t__u64 tba_addr;\t\t/* to KFD */\n\t__u64 tma_addr;\t\t/* to KFD */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_acquire_vm_args {\n\t__u32 drm_fd;\t/* to KFD */\n\t__u32 gpu_id;\t/* to KFD */\n};\n\n/* Allocation flags: memory types */\n#define KFD_IOC_ALLOC_MEM_FLAGS_VRAM\t\t(1 << 0)\n#define KFD_IOC_ALLOC_MEM_FLAGS_GTT\t\t(1 << 1)\n#define KFD_IOC_ALLOC_MEM_FLAGS_USERPTR\t\t(1 << 2)\n#define KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL\t(1 << 3)\n#define KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP\t(1 << 4)\n/* Allocation flags: attributes/access options */\n#define KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE\t(1 << 31)\n#define KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE\t(1 << 30)\n#define KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC\t\t(1 << 29)\n#define KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE\t(1 << 28)\n#define KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM\t(1 << 27)\n#define KFD_IOC_ALLOC_MEM_FLAGS_COHERENT\t(1 << 26)\n#define KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED\t(1 << 25)\n#define KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT\t(1 << 24)\n#define KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS_BEST_EFFORT\t(1 << 23)\n\n/* Allocate memory for later SVM (shared virtual memory) mapping.\n *\n * @va_addr:     virtual address of the memory to be allocated\n *               all later mappings on all GPUs will use this address\n * @size:        size in bytes\n * @handle:      buffer handle returned to user mode, used to refer to\n *               this allocation for mapping, unmapping and freeing\n * @mmap_offset: for CPU-mapping the allocation by mmapping a render node\n *               for userptrs this is overloaded to specify the CPU address\n * @gpu_id:      device identifier\n * @flags:       memory type and attributes. See KFD_IOC_ALLOC_MEM_FLAGS above\n */\nstruct kfd_ioctl_alloc_memory_of_gpu_args {\n\t__u64 va_addr;\t\t/* to KFD */\n\t__u64 size;\t\t/* to KFD */\n\t__u64 handle;\t\t/* from KFD */\n\t__u64 mmap_offset;\t/* to KFD (userptr), from KFD (mmap offset) */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 flags;\n};\n\n/* Free memory allocated with kfd_ioctl_alloc_memory_of_gpu\n *\n * @handle: memory handle returned by alloc\n */\nstruct kfd_ioctl_free_memory_of_gpu_args {\n\t__u64 handle;\t\t/* to KFD */\n};\n\n/* Inquire available memory with kfd_ioctl_get_available_memory\n *\n * @available: memory available for alloc\n */\nstruct  kfd_ioctl_get_available_memory_args {\n\t__u64 available;\t/* from KFD */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 pad;\n};\n\n/* Map memory to one or more GPUs\n *\n * @handle:                memory handle returned by alloc\n * @device_ids_array_ptr:  array of gpu_ids (__u32 per device)\n * @n_devices:             number of devices in the array\n * @n_success:             number of devices mapped successfully\n *\n * @n_success returns information to the caller how many devices from\n * the start of the array have mapped the buffer successfully. It can\n * be passed into a subsequent retry call to skip those devices. For\n * the first call the caller should initialize it to 0.\n *\n * If the ioctl completes with return code 0 (success), n_success ==\n * n_devices.\n */\nstruct kfd_ioctl_map_memory_to_gpu_args {\n\t__u64 handle;\t\t\t/* to KFD */\n\t__u64 device_ids_array_ptr;\t/* to KFD */\n\t__u32 n_devices;\t\t/* to KFD */\n\t__u32 n_success;\t\t/* to/from KFD */\n};\n\n/* Unmap memory from one or more GPUs\n *\n * same arguments as for mapping\n */\nstruct kfd_ioctl_unmap_memory_from_gpu_args {\n\t__u64 handle;\t\t\t/* to KFD */\n\t__u64 device_ids_array_ptr;\t/* to KFD */\n\t__u32 n_devices;\t\t/* to KFD */\n\t__u32 n_success;\t\t/* to/from KFD */\n};\n\n/* Allocate GWS for specific queue\n *\n * @queue_id:    queue's id that GWS is allocated for\n * @num_gws:     how many GWS to allocate\n * @first_gws:   index of the first GWS allocated.\n *               only support contiguous GWS allocation\n */\nstruct kfd_ioctl_alloc_queue_gws_args {\n\t__u32 queue_id;\t\t/* to KFD */\n\t__u32 num_gws;\t\t/* to KFD */\n\t__u32 first_gws;\t/* from KFD */\n\t__u32 pad;\n};\n\nstruct kfd_ioctl_get_dmabuf_info_args {\n\t__u64 size;\t\t/* from KFD */\n\t__u64 metadata_ptr;\t/* to KFD */\n\t__u32 metadata_size;\t/* to KFD (space allocated by user)\n\t\t\t\t * from KFD (actual metadata size)\n\t\t\t\t */\n\t__u32 gpu_id;\t/* from KFD */\n\t__u32 flags;\t\t/* from KFD (KFD_IOC_ALLOC_MEM_FLAGS) */\n\t__u32 dmabuf_fd;\t/* to KFD */\n};\n\nstruct kfd_ioctl_import_dmabuf_args {\n\t__u64 va_addr;\t/* to KFD */\n\t__u64 handle;\t/* from KFD */\n\t__u32 gpu_id;\t/* to KFD */\n\t__u32 dmabuf_fd;\t/* to KFD */\n};\n\nstruct kfd_ioctl_export_dmabuf_args {\n\t__u64 handle;\t\t/* to KFD */\n\t__u32 flags;\t\t/* to KFD */\n\t__u32 dmabuf_fd;\t/* from KFD */\n};\n\n/*\n * KFD SMI(System Management Interface) events\n */\nenum kfd_smi_event {\n\tKFD_SMI_EVENT_NONE = 0, /* not used */\n\tKFD_SMI_EVENT_VMFAULT = 1, /* event start counting at 1 */\n\tKFD_SMI_EVENT_THERMAL_THROTTLE = 2,\n\tKFD_SMI_EVENT_GPU_PRE_RESET = 3,\n\tKFD_SMI_EVENT_GPU_POST_RESET = 4,\n};\n\n#define KFD_SMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1))\n#define KFD_SMI_EVENT_MSG_SIZE\t96\n\nstruct kfd_ioctl_smi_events_args {\n\t__u32 gpuid;\t/* to KFD */\n\t__u32 anon_fd;\t/* from KFD */\n};\n\n/**\n * kfd_ioctl_spm_op - SPM ioctl operations\n *\n * @KFD_IOCTL_SPM_OP_ACQUIRE: acquire exclusive access to SPM\n * @KFD_IOCTL_SPM_OP_RELEASE: release exclusive access to SPM\n * @KFD_IOCTL_SPM_OP_SET_DEST_BUF: set or unset destination buffer for SPM streaming\n */\nenum kfd_ioctl_spm_op {\n\tKFD_IOCTL_SPM_OP_ACQUIRE,\n\tKFD_IOCTL_SPM_OP_RELEASE,\n\tKFD_IOCTL_SPM_OP_SET_DEST_BUF\n};\n\n/**\n * kfd_ioctl_spm_args - Arguments for SPM ioctl\n *\n * @op[in]:            specifies the operation to perform\n * @gpu_id[in]:        GPU ID of the GPU to profile\n * @dst_buf[in]:       used for the address of the destination buffer\n *                      in @KFD_IOCTL_SPM_SET_DEST_BUFFER\n * @buf_size[in]:      size of the destination buffer\n * @timeout[in/out]:   [in]: timeout in milliseconds, [out]: amount of time left\n *                      `in the timeout window\n * @bytes_copied[out]: total amount of data that was copied to the previous dest_buf\n * @has_data_loss:     total count for sub-block which has data loss\n *\n * This ioctl performs different functions depending on the @op parameter.\n *\n * KFD_IOCTL_SPM_OP_ACQUIRE\n * ------------------------\n *\n * Acquires exclusive access of SPM on the specified @gpu_id for the calling process.\n * This must be called before using KFD_IOCTL_SPM_OP_SET_DEST_BUF.\n *\n * KFD_IOCTL_SPM_OP_RELEASE\n * ------------------------\n *\n * Releases exclusive access of SPM on the specified @gpu_id for the calling process,\n * which allows another process to acquire it in the future.\n *\n * KFD_IOCTL_SPM_OP_SET_DEST_BUF\n * -----------------------------\n *\n * If @dst_buf is NULL, the destination buffer address is unset and copying of counters\n * is stopped.\n *\n * If @dst_buf is not NULL, it specifies the pointer to a new destination buffer.\n * @buf_size specifies the size of the buffer.\n *\n * If @timeout is non-0, the call will wait for up to @timeout ms for the previous\n * buffer to be filled. If previous buffer to be filled before timeout, the @timeout\n * will be updated value with the time remaining. If the timeout is exceeded, the function\n * copies any partial data available into the previous user buffer and returns success.\n * The amount of valid data in the previous user buffer is indicated by @bytes_copied.\n *\n * If @timeout is 0, the function immediately replaces the previous destination buffer\n * without waiting for the previous buffer to be filled. That means the previous buffer\n * may only be partially filled, and @bytes_copied will indicate how much data has been\n * copied to it.\n *\n * If data was lost, e.g. due to a ring buffer overflow, @has_data_loss will be non-0.\n *\n * Returns negative error code on failure, 0 on success.\n */\nstruct kfd_ioctl_spm_args {\n\t__u64 dest_buf;\n\t__u32 buf_size;\n\t__u32 op;\n\t__u32 timeout;\n\t__u32 gpu_id;\n\t__u32 bytes_copied;\n\t__u32 has_data_loss;\n};\n\n/**\n * kfd_ioctl_spm_buffer_header - SPM Buffer header for kfd_ioctl_spm_args->dest_buf\n *\n * @version        [out]: spm versiom\n * @bytes_copied   [out]: amount of data for each sub-block\n * @has_data_loss: [out]: boolean indicating whether data was lost for each sub-block\n *                        (e.g. due to a ring-buffer overflow)\n */\nstruct kfd_ioctl_spm_buffer_header {\n\t__u32 version; /* 0-23: minor 24-31: major */\n\t__u32 bytes_copied;\n\t__u32 has_data_loss;\n\t__u32 reserved[5];\n};\n\n/**************************************************************************************************\n * CRIU IOCTLs (Checkpoint Restore In Userspace)\n *\n * When checkpointing a process, the userspace application will perform:\n * 1. PROCESS_INFO op to determine current process information. This pauses execution and evicts\n *    all the queues.\n * 2. CHECKPOINT op to checkpoint process contents (BOs, queues, events, svm-ranges)\n * 3. UNPAUSE op to un-evict all the queues\n *\n * When restoring a process, the CRIU userspace application will perform:\n *\n * 1. RESTORE op to restore process contents\n * 2. RESUME op to start the process\n *\n * Note: Queues are forced into an evicted state after a successful PROCESS_INFO. User\n * application needs to perform an UNPAUSE operation after calling PROCESS_INFO.\n */\n\nenum kfd_criu_op {\n\tKFD_CRIU_OP_PROCESS_INFO,\n\tKFD_CRIU_OP_CHECKPOINT,\n\tKFD_CRIU_OP_UNPAUSE,\n\tKFD_CRIU_OP_RESTORE,\n\tKFD_CRIU_OP_RESUME,\n};\n\n/**\n * kfd_ioctl_criu_args - Arguments perform CRIU operation\n * @devices:\t\t[in/out] User pointer to memory location for devices information.\n * \t\t\tThis is an array of type kfd_criu_device_bucket.\n * @bos:\t\t[in/out] User pointer to memory location for BOs information\n * \t\t\tThis is an array of type kfd_criu_bo_bucket.\n * @priv_data:\t\t[in/out] User pointer to memory location for private data\n * @priv_data_size:\t[in/out] Size of priv_data in bytes\n * @num_devices:\t[in/out] Number of GPUs used by process. Size of @devices array.\n * @num_bos\t\t[in/out] Number of BOs used by process. Size of @bos array.\n * @num_objects:\t[in/out] Number of objects used by process. Objects are opaque to\n *\t\t\t\t user application.\n * @pid:\t\t[in/out] PID of the process being checkpointed\n * @op\t\t\t[in] Type of operation (kfd_criu_op)\n *\n * Return: 0 on success, -errno on failure\n */\nstruct kfd_ioctl_criu_args {\n\t__u64 devices;\t\t/* Used during ops: CHECKPOINT, RESTORE */\n\t__u64 bos;\t\t/* Used during ops: CHECKPOINT, RESTORE */\n\t__u64 priv_data;\t/* Used during ops: CHECKPOINT, RESTORE */\n\t__u64 priv_data_size;\t/* Used during ops: PROCESS_INFO, RESTORE */\n\t__u32 num_devices;\t/* Used during ops: PROCESS_INFO, RESTORE */\n\t__u32 num_bos;\t\t/* Used during ops: PROCESS_INFO, RESTORE */\n\t__u32 num_objects;\t/* Used during ops: PROCESS_INFO, RESTORE */\n\t__u32 pid;\t\t/* Used during ops: PROCESS_INFO, RESUME */\n\t__u32 op;\n};\n\nstruct kfd_criu_device_bucket {\n\t__u32 user_gpu_id;\n\t__u32 actual_gpu_id;\n\t__u32 drm_fd;\n\t__u32 pad;\n};\n\nstruct kfd_criu_bo_bucket {\n\t__u64 addr;\n\t__u64 size;\n\t__u64 offset;\n\t__u64 restored_offset;    /* During restore, updated offset for BO */\n\t__u32 gpu_id;             /* This is the user_gpu_id */\n\t__u32 alloc_flags;\n\t__u32 dmabuf_fd;\n\t__u32 pad;\n};\n\n/* CRIU IOCTLs - END */\n/**************************************************************************************************/\n/* Register offset inside the remapped mmio page\n */\nenum kfd_mmio_remap {\n\tKFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL = 0,\n\tKFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL = 4,\n};\n\nstruct kfd_ioctl_ipc_export_handle_args {\n\t__u64 handle;\t\t/* to KFD */\n\t__u32 share_handle[4];\t/* from KFD */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 flags;\t\t/* to KFD */\n};\n\nstruct kfd_ioctl_ipc_import_handle_args {\n\t__u64 handle;\t\t/* from KFD */\n\t__u64 va_addr;\t\t/* to KFD */\n\t__u64 mmap_offset;\t/* from KFD */\n\t__u32 share_handle[4];\t/* to KFD */\n\t__u32 gpu_id;\t\t/* to KFD */\n\t__u32 flags;\t\t/* from KFD */\n};\n\nstruct kfd_memory_range {\n\t__u64 va_addr;\n\t__u64 size;\n};\n\n/* flags definitions\n * BIT0: 0: read operation, 1: write operation.\n * This also identifies if the src or dst array belongs to remote process\n */\n#define KFD_CROSS_MEMORY_RW_BIT (1 << 0)\n#define KFD_SET_CROSS_MEMORY_READ(flags) (flags &= ~KFD_CROSS_MEMORY_RW_BIT)\n#define KFD_SET_CROSS_MEMORY_WRITE(flags) (flags |= KFD_CROSS_MEMORY_RW_BIT)\n#define KFD_IS_CROSS_MEMORY_WRITE(flags) (flags & KFD_CROSS_MEMORY_RW_BIT)\n\nstruct kfd_ioctl_cross_memory_copy_args {\n\t/* to KFD: Process ID of the remote process */\n\t__u32 pid;\n\t/* to KFD: See above definition */\n\t__u32 flags;\n\t/* to KFD: Source GPU VM range */\n\t__u64 src_mem_range_array;\n\t/* to KFD: Size of above array */\n\t__u64 src_mem_array_size;\n\t/* to KFD: Destination GPU VM range */\n\t__u64 dst_mem_range_array;\n\t/* to KFD: Size of above array */\n\t__u64 dst_mem_array_size;\n\t/* from KFD: Total amount of bytes copied */\n\t__u64 bytes_copied;\n};\n\n/* Guarantee host access to memory */\n#define KFD_IOCTL_SVM_FLAG_HOST_ACCESS 0x00000001\n/* Fine grained coherency between all devices with access */\n#define KFD_IOCTL_SVM_FLAG_COHERENT    0x00000002\n/* Use any GPU in same hive as preferred device */\n#define KFD_IOCTL_SVM_FLAG_HIVE_LOCAL  0x00000004\n/* GPUs only read, allows replication */\n#define KFD_IOCTL_SVM_FLAG_GPU_RO      0x00000008\n/* Allow execution on GPU */\n#define KFD_IOCTL_SVM_FLAG_GPU_EXEC    0x00000010\n/* GPUs mostly read, may allow similar optimizations as RO, but writes fault */\n#define KFD_IOCTL_SVM_FLAG_GPU_READ_MOSTLY     0x00000020\n/* Keep GPU memory mapping always valid as if XNACK is disable */\n#define KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED   0x00000040\n/* Fine grained coherency between all devices using device-scope atomics */\n#define KFD_IOCTL_SVM_FLAG_EXT_COHERENT        0x00000080\n\n/**\n * kfd_ioctl_svm_op - SVM ioctl operations\n *\n * @KFD_IOCTL_SVM_OP_SET_ATTR: Modify one or more attributes\n * @KFD_IOCTL_SVM_OP_GET_ATTR: Query one or more attributes\n */\nenum kfd_ioctl_svm_op {\n\tKFD_IOCTL_SVM_OP_SET_ATTR,\n\tKFD_IOCTL_SVM_OP_GET_ATTR\n};\n\n/** kfd_ioctl_svm_location - Enum for preferred and prefetch locations\n *\n * GPU IDs are used to specify GPUs as preferred and prefetch locations.\n * Below definitions are used for system memory or for leaving the preferred\n * location unspecified.\n */\nenum kfd_ioctl_svm_location {\n\tKFD_IOCTL_SVM_LOCATION_SYSMEM = 0,\n\tKFD_IOCTL_SVM_LOCATION_UNDEFINED = 0xffffffff\n};\n\n/**\n * kfd_ioctl_svm_attr_type - SVM attribute types\n *\n * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: gpuid of the preferred location, 0 for\n *                                    system memory\n * @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC: gpuid of the prefetch location, 0 for\n *                                   system memory. Setting this triggers an\n *                                   immediate prefetch (migration).\n * @KFD_IOCTL_SVM_ATTR_ACCESS:\n * @KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:\n * @KFD_IOCTL_SVM_ATTR_NO_ACCESS: specify memory access for the gpuid given\n *                                by the attribute value\n * @KFD_IOCTL_SVM_ATTR_SET_FLAGS: bitmask of flags to set (see\n *                                KFD_IOCTL_SVM_FLAG_...)\n * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS: bitmask of flags to clear\n * @KFD_IOCTL_SVM_ATTR_GRANULARITY: migration granularity\n *                                  (log2 num pages)\n */\nenum kfd_ioctl_svm_attr_type {\n\tKFD_IOCTL_SVM_ATTR_PREFERRED_LOC,\n\tKFD_IOCTL_SVM_ATTR_PREFETCH_LOC,\n\tKFD_IOCTL_SVM_ATTR_ACCESS,\n\tKFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE,\n\tKFD_IOCTL_SVM_ATTR_NO_ACCESS,\n\tKFD_IOCTL_SVM_ATTR_SET_FLAGS,\n\tKFD_IOCTL_SVM_ATTR_CLR_FLAGS,\n\tKFD_IOCTL_SVM_ATTR_GRANULARITY\n};\n\n/**\n * kfd_ioctl_svm_attribute - Attributes as pairs of type and value\n *\n * The meaning of the @value depends on the attribute type.\n *\n * @type: attribute type (see enum @kfd_ioctl_svm_attr_type)\n * @value: attribute value\n */\nstruct kfd_ioctl_svm_attribute {\n\t__u32 type;\n\t__u32 value;\n};\n\n/**\n * kfd_ioctl_svm_args - Arguments for SVM ioctl\n *\n * @op specifies the operation to perform (see enum\n * @kfd_ioctl_svm_op).  @start_addr and @size are common for all\n * operations.\n *\n * A variable number of attributes can be given in @attrs.\n * @nattr specifies the number of attributes. New attributes can be\n * added in the future without breaking the ABI. If unknown attributes\n * are given, the function returns -EINVAL.\n *\n * @KFD_IOCTL_SVM_OP_SET_ATTR sets attributes for a virtual address\n * range. It may overlap existing virtual address ranges. If it does,\n * the existing ranges will be split such that the attribute changes\n * only apply to the specified address range.\n *\n * @KFD_IOCTL_SVM_OP_GET_ATTR returns the intersection of attributes\n * over all memory in the given range and returns the result as the\n * attribute value. If different pages have different preferred or\n * prefetch locations, 0xffffffff will be returned for\n * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC or\n * @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC resepctively. For\n * @KFD_IOCTL_SVM_ATTR_SET_FLAGS, flags of all pages will be\n * aggregated by bitwise AND. That means, a flag will be set in the\n * output, if that flag is set for all pages in the range. For\n * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS, flags of all pages will be\n * aggregated by bitwise NOR. That means, a flag will be set in the\n * output, if that flag is clear for all pages in the range.\n * The minimum migration granularity throughout the range will be\n * returned for @KFD_IOCTL_SVM_ATTR_GRANULARITY.\n *\n * Querying of accessibility attributes works by initializing the\n * attribute type to @KFD_IOCTL_SVM_ATTR_ACCESS and the value to the\n * GPUID being queried. Multiple attributes can be given to allow\n * querying multiple GPUIDs. The ioctl function overwrites the\n * attribute type to indicate the access for the specified GPU.\n */\nstruct kfd_ioctl_svm_args {\n\t__u64 start_addr;\n\t__u64 size;\n\t__u32 op;\n\t__u32 nattr;\n\t/* Variable length array of attributes */\n\tstruct kfd_ioctl_svm_attribute attrs[];\n};\n\n/**\n * kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode\n *\n * @xnack_enabled:       [in/out] Whether to enable XNACK mode for this process\n *\n * @xnack_enabled indicates whether recoverable page faults should be\n * enabled for the current process. 0 means disabled, positive means\n * enabled, negative means leave unchanged. If enabled, virtual address\n * translations on GFXv9 and later AMD GPUs can return XNACK and retry\n * the access until a valid PTE is available. This is used to implement\n * device page faults.\n *\n * On output, @xnack_enabled returns the (new) current mode (0 or\n * positive). Therefore, a negative input value can be used to query\n * the current mode without changing it.\n *\n * The XNACK mode fundamentally changes the way SVM managed memory works\n * in the driver, with subtle effects on application performance and\n * functionality.\n *\n * Enabling XNACK mode requires shader programs to be compiled\n * differently. Furthermore, not all GPUs support changing the mode\n * per-process. Therefore changing the mode is only allowed while no\n * user mode queues exist in the process. This ensure that no shader\n * code is running that may be compiled for the wrong mode. And GPUs\n * that cannot change to the requested mode will prevent the XNACK\n * mode from occurring. All GPUs used by the process must be in the\n * same XNACK mode.\n *\n * GFXv8 or older GPUs do not support 48 bit virtual addresses or SVM.\n * Therefore those GPUs are not considered for the XNACK mode switch.\n *\n * Return: 0 on success, -errno on failure\n */\nstruct kfd_ioctl_set_xnack_mode_args {\n\t__s32 xnack_enabled;\n};\n\n/**\n * kfd_ioctl_pc_sample_op - PC Sampling ioctl operations\n *\n * @KFD_IOCTL_PCS_OP_QUERY_CAPABILITIES: Query device PC Sampling capabilities\n * @KFD_IOCTL_PCS_OP_CREATE:             Register this process with a per-device PC sampler instance\n * @KFD_IOCTL_PCS_OP_DESTROY:            Unregister from a previously registered PC sampler instance\n * @KFD_IOCTL_PCS_OP_START:              Process begins taking samples from a previously registered PC sampler instance\n * @KFD_IOCTL_PCS_OP_STOP:               Process stops taking samples from a previously registered PC sampler instance\n */\nenum kfd_ioctl_pc_sample_op {\n\tKFD_IOCTL_PCS_OP_QUERY_CAPABILITIES,\n\tKFD_IOCTL_PCS_OP_CREATE,\n\tKFD_IOCTL_PCS_OP_DESTROY,\n\tKFD_IOCTL_PCS_OP_START,\n\tKFD_IOCTL_PCS_OP_STOP,\n};\n\n/* Values have to be a power of 2*/\n#define KFD_IOCTL_PCS_FLAG_POWER_OF_2 0x00000001\n\nenum kfd_ioctl_pc_sample_method {\n\tKFD_IOCTL_PCS_METHOD_HOSTTRAP = 1,\n\tKFD_IOCTL_PCS_METHOD_STOCHASTIC,\n};\n\nenum kfd_ioctl_pc_sample_type {\n\tKFD_IOCTL_PCS_TYPE_TIME_US,\n\tKFD_IOCTL_PCS_TYPE_CLOCK_CYCLES,\n\tKFD_IOCTL_PCS_TYPE_INSTRUCTIONS\n};\n\nstruct kfd_pc_sample_info {\n\t__u64 interval;      /* [IN] if PCS_TYPE_INTERVAL_US: sample interval in us\n\t                      * if PCS_TYPE_CLOCK_CYCLES: sample interval in graphics core clk cycles\n\t                      * if PCS_TYPE_INSTRUCTIONS: sample interval in instructions issued by\n\t                      * graphics compute units\n\t                      */\n\t__u64 interval_min;  /* [OUT] */\n\t__u64 interval_max;  /* [OUT] */\n\t__u64 flags;         /* [OUT] indicate potential restrictions e.g FLAG_POWER_OF_2 */\n\t__u32 method;        /* [IN/OUT] kfd_ioctl_pc_sample_method */\n\t__u32 type;          /* [IN/OUT] kfd_ioctl_pc_sample_type */\n};\n\n#define KFD_IOCTL_PCS_QUERY_TYPE_FULL (1 << 0) /* If not set, return current */\n\nstruct kfd_ioctl_pc_sample_args {\n\t__u64 sample_info_ptr;   /* array of kfd_pc_sample_info */\n\t__u32 num_sample_info;\n\t__u32 op;                /* kfd_ioctl_pc_sample_op */\n\t__u32 gpu_id;\n\t__u32 trace_id;\n\t__u32 flags;             /* kfd_ioctl_pcs_query flags */\n\t__u32 reserved;\n};\n\n#define AMDKFD_IOCTL_BASE 'K'\n#define AMDKFD_IO(nr)\t\t\t_IO(AMDKFD_IOCTL_BASE, nr)\n#define AMDKFD_IOR(nr, type)\t\t_IOR(AMDKFD_IOCTL_BASE, nr, type)\n#define AMDKFD_IOW(nr, type)\t\t_IOW(AMDKFD_IOCTL_BASE, nr, type)\n#define AMDKFD_IOWR(nr, type)\t\t_IOWR(AMDKFD_IOCTL_BASE, nr, type)\n\n#define AMDKFD_IOC_GET_VERSION\t\t\t\\\n\t\tAMDKFD_IOR(0x01, struct kfd_ioctl_get_version_args)\n\n#define AMDKFD_IOC_CREATE_QUEUE\t\t\t\\\n\t\tAMDKFD_IOWR(0x02, struct kfd_ioctl_create_queue_args)\n\n#define AMDKFD_IOC_DESTROY_QUEUE\t\t\\\n\t\tAMDKFD_IOWR(0x03, struct kfd_ioctl_destroy_queue_args)\n\n#define AMDKFD_IOC_SET_MEMORY_POLICY\t\t\\\n\t\tAMDKFD_IOW(0x04, struct kfd_ioctl_set_memory_policy_args)\n\n#define AMDKFD_IOC_GET_CLOCK_COUNTERS\t\t\\\n\t\tAMDKFD_IOWR(0x05, struct kfd_ioctl_get_clock_counters_args)\n\n#define AMDKFD_IOC_GET_PROCESS_APERTURES\t\\\n\t\tAMDKFD_IOR(0x06, struct kfd_ioctl_get_process_apertures_args)\n\n#define AMDKFD_IOC_UPDATE_QUEUE\t\t\t\\\n\t\tAMDKFD_IOW(0x07, struct kfd_ioctl_update_queue_args)\n\n#define AMDKFD_IOC_CREATE_EVENT\t\t\t\\\n\t\tAMDKFD_IOWR(0x08, struct kfd_ioctl_create_event_args)\n\n#define AMDKFD_IOC_DESTROY_EVENT\t\t\\\n\t\tAMDKFD_IOW(0x09, struct kfd_ioctl_destroy_event_args)\n\n#define AMDKFD_IOC_SET_EVENT\t\t\t\\\n\t\tAMDKFD_IOW(0x0A, struct kfd_ioctl_set_event_args)\n\n#define AMDKFD_IOC_RESET_EVENT\t\t\t\\\n\t\tAMDKFD_IOW(0x0B, struct kfd_ioctl_reset_event_args)\n\n#define AMDKFD_IOC_WAIT_EVENTS\t\t\t\\\n\t\tAMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args)\n\n#define AMDKFD_IOC_DBG_REGISTER_DEPRECATED\t\\\n\t\tAMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args)\n\n#define AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED\t\\\n\t\tAMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)\n\n#define AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED\t\\\n\t\tAMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)\n\n#define AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED\t\\\n\t\tAMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)\n\n#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA\t\\\n\t\tAMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args)\n\n#define AMDKFD_IOC_GET_TILE_CONFIG                                      \\\n\t\tAMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args)\n\n#define AMDKFD_IOC_SET_TRAP_HANDLER\t\t\\\n\t\tAMDKFD_IOW(0x13, struct kfd_ioctl_set_trap_handler_args)\n\n#define AMDKFD_IOC_GET_PROCESS_APERTURES_NEW\t\\\n\t\tAMDKFD_IOWR(0x14,\t\t\\\n\t\t\tstruct kfd_ioctl_get_process_apertures_new_args)\n\n#define AMDKFD_IOC_ACQUIRE_VM\t\t\t\\\n\t\tAMDKFD_IOW(0x15, struct kfd_ioctl_acquire_vm_args)\n\n#define AMDKFD_IOC_ALLOC_MEMORY_OF_GPU\t\t\\\n\t\tAMDKFD_IOWR(0x16, struct kfd_ioctl_alloc_memory_of_gpu_args)\n\n#define AMDKFD_IOC_FREE_MEMORY_OF_GPU\t\t\\\n\t\tAMDKFD_IOW(0x17, struct kfd_ioctl_free_memory_of_gpu_args)\n\n#define AMDKFD_IOC_MAP_MEMORY_TO_GPU\t\t\\\n\t\tAMDKFD_IOWR(0x18, struct kfd_ioctl_map_memory_to_gpu_args)\n\n#define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU\t\\\n\t\tAMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args)\n\n#define AMDKFD_IOC_SET_CU_MASK\t\t\\\n\t\tAMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args)\n\n#define AMDKFD_IOC_GET_QUEUE_WAVE_STATE\t\t\\\n\t\tAMDKFD_IOWR(0x1B, struct kfd_ioctl_get_queue_wave_state_args)\n\n#define AMDKFD_IOC_GET_DMABUF_INFO\t\t\\\n\t\tAMDKFD_IOWR(0x1C, struct kfd_ioctl_get_dmabuf_info_args)\n\n#define AMDKFD_IOC_IMPORT_DMABUF\t\t\\\n\t\tAMDKFD_IOWR(0x1D, struct kfd_ioctl_import_dmabuf_args)\n\n#define AMDKFD_IOC_ALLOC_QUEUE_GWS\t\t\\\n\t\tAMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args)\n\n#define AMDKFD_IOC_SMI_EVENTS\t\t\t\\\n\t\tAMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)\n\n#define AMDKFD_IOC_SVM\tAMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args)\n\n#define AMDKFD_IOC_SET_XNACK_MODE\t\t\\\n\t\tAMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args)\n\n#define AMDKFD_IOC_CRIU_OP\t\t\t\\\n\t\tAMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args)\n\n#define AMDKFD_IOC_AVAILABLE_MEMORY\t\t\\\n\t\tAMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)\n\n#define AMDKFD_IOC_EXPORT_DMABUF\t\t\\\n\t\tAMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args)\n\n#define AMDKFD_IOC_RUNTIME_ENABLE\t\t\\\n\t\tAMDKFD_IOWR(0x25, struct kfd_ioctl_runtime_enable_args)\n\n#define AMDKFD_IOC_DBG_TRAP\t\t\t\\\n\t\tAMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args)\n\n#define AMDKFD_COMMAND_START\t\t0x01\n#define AMDKFD_COMMAND_END\t\t0x27\n\n/* non-upstream ioctls */\n#define AMDKFD_IOC_IPC_IMPORT_HANDLE                                    \\\n\t\tAMDKFD_IOWR(0x80, struct kfd_ioctl_ipc_import_handle_args)\n\n#define AMDKFD_IOC_IPC_EXPORT_HANDLE\t\t\\\n\t\tAMDKFD_IOWR(0x81, struct kfd_ioctl_ipc_export_handle_args)\n\n#define AMDKFD_IOC_CROSS_MEMORY_COPY\t\t\\\n\t\tAMDKFD_IOWR(0x83, struct kfd_ioctl_cross_memory_copy_args)\n\n#define AMDKFD_IOC_RLC_SPM\t\t\\\n\t\tAMDKFD_IOWR(0x84, struct kfd_ioctl_spm_args)\n\n#define AMDKFD_IOC_PC_SAMPLE\t\t\\\n\t\tAMDKFD_IOWR(0x85, struct kfd_ioctl_pc_sample_args)\n\n#define AMDKFD_COMMAND_START_2\t\t0x80\n#define AMDKFD_COMMAND_END_2\t\t0x86\n\n#endif\n"
  },
  {
    "path": "libhsakmt/include/hsakmt/linux/udmabuf.h",
    "content": "/* GPL-2.0 WITH Linux-syscall-note */\n/*\n * This file was copied from inux-libc-dev package\n * This header provides interface to linux kernel udmabuf drver\n * Modifications may have been made.\n */\n#ifndef _THUNK_UDMABUF_H\n#define _THUNK_UDMABUF_H\n\n#include <linux/types.h>\n#include <linux/ioctl.h>\n\n#define UDMABUF_FLAGS_CLOEXEC   0x01\n\nstruct udmabuf_create {\n        __u32 memfd;\n        __u32 flags;\n        __u64 offset;\n        __u64 size;\n};\n\nstruct udmabuf_create_item {\n        __u32 memfd;\n        __u32 __pad;\n        __u64 offset;\n        __u64 size;\n};\n\nstruct udmabuf_create_list {\n        __u32 flags;\n        __u32 count;\n        struct udmabuf_create_item list[];\n};\n\n#define UDMABUF_CREATE       _IOW('u', 0x42, struct udmabuf_create)\n#define UDMABUF_CREATE_LIST  _IOW('u', 0x43, struct udmabuf_create_list)\n\n#endif /* _THUNK_UDMABUF_H */\n"
  },
  {
    "path": "libhsakmt/libhsakmt.pc.in",
    "content": "prefix=${pcfiledir}/../..\nexec_prefix=${prefix}\nlibdir=${prefix}/@CMAKE_INSTALL_LIBDIR@\nincludedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@\n\nName: libhsakmt\nDescription: HSA Kernel Mode Thunk library for AMD KFD support\nVersion: @LIB_VERSION_STRING@\n\nLibs: -L${libdir} -lhsakmt\nCflags: -I${includedir}\n"
  },
  {
    "path": "libhsakmt/src/debug.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <errno.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nstatic bool *is_device_debugged;\nstatic uint32_t runtime_capabilities_mask = 0;\n\nHSAKMT_STATUS hsakmt_init_device_debugging_memory(unsigned int NumNodes)\n{\n\tunsigned int i;\n\n\tis_device_debugged = malloc(NumNodes * sizeof(bool));\n\tif (!is_device_debugged)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tfor (i = 0; i < NumNodes; i++)\n\t\tis_device_debugged[i] = false;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nvoid hsakmt_destroy_device_debugging_memory(void)\n{\n\tif (is_device_debugged) {\n\t\tfree(is_device_debugged);\n\t\tis_device_debugged = NULL;\n\t}\n}\n\nbool hsakmt_debug_get_reg_status(uint32_t node_id)\n{\n\treturn is_device_debugged[node_id];\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgRegister(HSAuint32 NodeId)\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\n\tCHECK_KFD_OPEN();\n\n\tif (!is_device_debugged)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\tstruct kfd_ioctl_dbg_register_args args = {0};\n\n\targs.gpu_id = gpu_id;\n\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_REGISTER_DEPRECATED, &args);\n\n\tif (err == 0)\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\telse\n\t\tresult = HSAKMT_STATUS_ERROR;\n\n\treturn result;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgUnregister(HSAuint32 NodeId)\n{\n\tuint32_t gpu_id;\n\tHSAKMT_STATUS result;\n\n\tCHECK_KFD_OPEN();\n\n\tif (!is_device_debugged)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\tstruct kfd_ioctl_dbg_unregister_args args = {0};\n\n\targs.gpu_id = gpu_id;\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED, &args);\n\n\tif (err)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgWavefrontControl(HSAuint32 NodeId,\n\t\t\t\t\t\t  HSA_DBG_WAVEOP Operand,\n\t\t\t\t\t\t  HSA_DBG_WAVEMODE Mode,\n\t\t\t\t\t\t  HSAuint32 TrapId,\n\t\t\t\t\t\t  HsaDbgWaveMessage *DbgWaveMsgRing)\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\n\tstruct kfd_ioctl_dbg_wave_control_args *args;\n\n\tCHECK_KFD_OPEN();\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\n/* Determine Size of the ioctl buffer */\n\tuint32_t buff_size = sizeof(Operand) + sizeof(Mode) + sizeof(TrapId) +\n\t\t\t     sizeof(DbgWaveMsgRing->DbgWaveMsg) +\n\t\t\t     sizeof(DbgWaveMsgRing->MemoryVA) + sizeof(*args);\n\n\targs = (struct kfd_ioctl_dbg_wave_control_args *)malloc(buff_size);\n\tif (!args)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemset(args, 0, buff_size);\n\n\targs->gpu_id = gpu_id;\n\targs->buf_size_in_bytes = buff_size;\n\n\t/* increment pointer to the start of the non fixed part */\n\tunsigned char *run_ptr = (unsigned char *)args + sizeof(*args);\n\n\t/* save variable content pointer for kfd */\n\targs->content_ptr = (uint64_t)run_ptr;\n\n\t/* insert items, and increment pointer accordingly */\n\t*((HSA_DBG_WAVEOP *)run_ptr) = Operand;\n\trun_ptr += sizeof(Operand);\n\n\t*((HSA_DBG_WAVEMODE *)run_ptr) = Mode;\n\trun_ptr += sizeof(Mode);\n\n\t*((HSAuint32 *)run_ptr) = TrapId;\n\trun_ptr += sizeof(TrapId);\n\n\t*((HsaDbgWaveMessageAMD *)run_ptr) = DbgWaveMsgRing->DbgWaveMsg;\n\trun_ptr += sizeof(DbgWaveMsgRing->DbgWaveMsg);\n\n\t*((void **)run_ptr) = DbgWaveMsgRing->MemoryVA;\n\trun_ptr += sizeof(DbgWaveMsgRing->MemoryVA);\n\n\t/* send to kernel */\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED, args);\n\n\tfree(args);\n\n\tif (err)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgAddressWatch(HSAuint32 NodeId,\n\t\t\t\t\t      HSAuint32 NumWatchPoints,\n\t\t\t\t\t      HSA_DBG_WATCH_MODE WatchMode[],\n\t\t\t\t\t      void *WatchAddress[],\n\t\t\t\t\t      HSAuint64 WatchMask[],\n\t\t\t\t\t      HsaEvent *WatchEvent[])\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\n\t/* determine the size of the watch mask and event buffers\n\t * the value is NULL if and only if no vector data should be attached\n\t */\n\tuint32_t watch_mask_items = WatchMask[0] > 0 ? NumWatchPoints:1;\n\tuint32_t watch_event_items = WatchEvent != NULL ? NumWatchPoints:0;\n\n\tstruct kfd_ioctl_dbg_address_watch_args *args;\n\tHSAuint32\t\t i = 0;\n\n\tCHECK_KFD_OPEN();\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\tif (NumWatchPoints > MAX_ALLOWED_NUM_POINTS)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\t/* Size and structure of the ioctl buffer is dynamic in this case\n\t * Here we calculate the buff size.\n\t */\n\tuint32_t buff_size = sizeof(NumWatchPoints) +\n\t\t(sizeof(WatchMode[0]) + sizeof(WatchAddress[0])) *\n\t\t\tNumWatchPoints +\n\t\twatch_mask_items * sizeof(HSAuint64) +\n\t\twatch_event_items * sizeof(HsaEvent *) + sizeof(*args);\n\n\targs = (struct kfd_ioctl_dbg_address_watch_args *) malloc(buff_size);\n\tif (!args)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemset(args, 0, buff_size);\n\n\targs->gpu_id = gpu_id;\n\targs->buf_size_in_bytes = buff_size;\n\n\n\t/* increment pointer to the start of the non fixed part */\n\tunsigned char *run_ptr = (unsigned char *)args + sizeof(*args);\n\n\t/* save variable content pointer for kfd */\n\targs->content_ptr = (uint64_t)run_ptr;\n\t/* insert items, and increment pointer accordingly */\n\n\t*((HSAuint32 *)run_ptr) = NumWatchPoints;\n\trun_ptr += sizeof(NumWatchPoints);\n\n\tfor (i = 0; i < NumWatchPoints; i++) {\n\t\t*((HSA_DBG_WATCH_MODE *)run_ptr) = WatchMode[i];\n\t\trun_ptr += sizeof(WatchMode[i]);\n\t}\n\n\tfor (i = 0; i < NumWatchPoints; i++) {\n\t\t*((void **)run_ptr) = WatchAddress[i];\n\t\trun_ptr += sizeof(WatchAddress[i]);\n\t}\n\n\tfor (i = 0; i < watch_mask_items; i++) {\n\t\t*((HSAuint64 *)run_ptr) = WatchMask[i];\n\t\trun_ptr += sizeof(WatchMask[i]);\n\t}\n\n\tfor (i = 0; i < watch_event_items; i++)\t{\n\t\t*((HsaEvent **)run_ptr) = WatchEvent[i];\n\t\trun_ptr += sizeof(WatchEvent[i]);\n\t}\n\n\t/* send to kernel */\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED, args);\n\n\tfree(args);\n\n\tif (err)\n\t\treturn HSAKMT_STATUS_ERROR;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n#define HSA_RUNTIME_ENABLE_MAX_MAJOR   1\n#define HSA_RUNTIME_ENABLE_MIN_MINOR   13\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtCheckRuntimeDebugSupport(void) {\n\tHsaNodeProperties node = {0};\n\tHsaSystemProperties props = {0};\n\tHsaVersionInfo versionInfo = {0};\n\n\tmemset(&node, 0x00, sizeof(node));\n\tmemset(&props, 0x00, sizeof(props));\n\tif (hsaKmtAcquireSystemProperties(&props))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t//the firmware of gpu node doesn't support the debugger, disable it.\n\tfor (uint32_t i = 0; i < props.NumNodes; i++) {\n\t\tif (hsaKmtGetNodeProperties(i, &node))\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\n\t\t//ignore cpu node\n\t\tif (node.NumCPUCores && !node.NumFComputeCores)\n\t\t\tcontinue;\n\t\tif (!node.Capability.ui32.DebugSupportedFirmware)\n\t\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\t}\n\n\tif (hsaKmtGetVersion(&versionInfo))\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\tif (versionInfo.KernelInterfaceMajorVersion < HSA_RUNTIME_ENABLE_MAX_MAJOR ||\n\t\t(versionInfo.KernelInterfaceMajorVersion ==\n\t\t\tHSA_RUNTIME_ENABLE_MAX_MAJOR &&\n\t\t(int)versionInfo.KernelInterfaceMinorVersion < HSA_RUNTIME_ENABLE_MIN_MINOR))\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRuntimeEnable(void *rDebug,\n\t\t\t\t\t    bool setupTtmp)\n{\n\tstruct kfd_ioctl_runtime_enable_args args = {0};\n\tHSAKMT_STATUS result = hsaKmtCheckRuntimeDebugSupport();\n\n\tif (result)\n\t\treturn result;\n\n\tmemset(&args, 0x00, sizeof(args));\n\targs.mode_mask = KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK |\n\t\t((setupTtmp) ? KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK : 0);\n\targs.r_debug = (HSAuint64)rDebug;\n\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RUNTIME_ENABLE, &args);\n\n\tif (err) {\n\t\tif (errno == EBUSY)\n\t\t\treturn HSAKMT_STATUS_UNAVAILABLE;\n\t\telse\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\truntime_capabilities_mask= args.capabilities_mask;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRuntimeDisable(void)\n{\n\tstruct kfd_ioctl_runtime_enable_args args = {0};\n\tHSAKMT_STATUS result = hsaKmtCheckRuntimeDebugSupport();\n\n\tif (result)\n\t\treturn result;\n\n\tmemset(&args, 0x00, sizeof(args));\n\targs.mode_mask = 0; //Disable\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RUNTIME_ENABLE, &args))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetRuntimeCapabilities(HSAuint32 *caps_mask)\n{\n\t*caps_mask = runtime_capabilities_mask;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS dbg_trap_get_device_data(void *data,\n\t\t\t\t\t      uint32_t *n_entries,\n\t\t\t\t\t      uint32_t entry_size)\n{\n\tstruct kfd_ioctl_dbg_trap_args args = {0};\n\n\targs.device_snapshot.snapshot_buf_ptr = (uint64_t) data;\n\targs.device_snapshot.num_devices = *n_entries;\n\targs.device_snapshot.entry_size = entry_size;\n\targs.op = KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT;\n\targs.pid = getpid();\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, &args))\n\t\treturn HSAKMT_STATUS_ERROR;\n\t*n_entries = args.device_snapshot.num_devices;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS dbg_trap_get_queue_data(void *data,\n\t\t\t\t\t     uint32_t *n_entries,\n\t\t\t\t\t     uint32_t entry_size,\n\t\t\t\t\t     uint32_t *queue_ids)\n{\n\tstruct kfd_ioctl_dbg_trap_args args = {0};\n\n\targs.queue_snapshot.num_queues = *n_entries;\n\targs.queue_snapshot.entry_size = entry_size;\n\targs.queue_snapshot.exception_mask = KFD_EC_MASK(EC_QUEUE_NEW);\n\targs.op = KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT;\n\targs.queue_snapshot.snapshot_buf_ptr = (uint64_t) data;\n\targs.pid = getpid();\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, &args))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t*n_entries = args.queue_snapshot.num_queues;\n\tif (queue_ids && *n_entries) {\n\t\tstruct kfd_queue_snapshot_entry *queue_entry =\n\t\t    (struct kfd_queue_snapshot_entry *) data;\n\t\tfor (uint32_t i = 0; i < *n_entries; i++)\n\t\t\tqueue_ids[i] = queue_entry[i].queue_id;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS dbg_trap_suspend_queues(uint32_t *queue_ids,\n\t\t\t\t\t     uint32_t num_queues)\n{\n\tstruct kfd_ioctl_dbg_trap_args args = {0};\n\tint r;\n\n\targs.suspend_queues.queue_array_ptr = (uint64_t) queue_ids;\n\targs.suspend_queues.num_queues = num_queues;\n\targs.suspend_queues.exception_mask = KFD_EC_MASK(EC_QUEUE_NEW);\n\targs.op = KFD_IOC_DBG_TRAP_SUSPEND_QUEUES;\n\targs.pid = getpid();\n\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, &args);\n\tif (r < 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* Debugger support has been in KFD ABI 1.13.  */\n#define KFD_MINOR_MIN_DEBUG 13\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgEnable(void **runtime_info,\n\t\t\t\t\t     HSAuint32 *data_size)\n{\n\tstruct kfd_ioctl_dbg_trap_args args = {0};\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(KFD_MINOR_MIN_DEBUG);\n\t*data_size = sizeof(struct kfd_runtime_info);\n\targs.enable.rinfo_size = *data_size;\n\targs.enable.dbg_fd = hsakmt_kfd_fd;\n\t*runtime_info = malloc(args.enable.rinfo_size);\n\tif (!*runtime_info)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\targs.enable.rinfo_ptr = (uint64_t) *runtime_info;\n\targs.op = KFD_IOC_DBG_TRAP_ENABLE;\n\targs.pid = getpid();\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, &args)) {\n\t\tfree(*runtime_info);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgDisable(void)\n{\n\tstruct kfd_ioctl_dbg_trap_args args = {0};\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(KFD_MINOR_MIN_DEBUG);\n\targs.enable.dbg_fd = hsakmt_kfd_fd;\n\targs.op = KFD_IOC_DBG_TRAP_DISABLE;\n\targs.pid = getpid();\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, &args))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgGetDeviceData(void **data,\n\t\t\t\t\t\tHSAuint32 *n_entries,\n\t\t\t\t\t\tHSAuint32 *entry_size)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_NO_MEMORY;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(KFD_MINOR_MIN_DEBUG);\n\t*n_entries = UINT32_MAX;\n\t*entry_size = sizeof(struct kfd_dbg_device_info_entry);\n\t*data = malloc(*entry_size * *n_entries);\n\tif (!*data)\n\t\treturn ret;\n\tret = dbg_trap_get_device_data(*data, n_entries, *entry_size);\n\tif (ret)\n\t\tfree(*data);\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDbgGetQueueData(void **data,\n\t\t\t\t\t\tHSAuint32 *n_entries,\n\t\t\t\t\t\tHSAuint32 *entry_size,\n\t\t\t\t\t\tbool suspend_queues)\n{\n\tuint32_t *queue_ids = NULL;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(KFD_MINOR_MIN_DEBUG);\n\t*entry_size = sizeof(struct kfd_queue_snapshot_entry);\n\t*n_entries = 0;\n\tif (dbg_trap_get_queue_data(NULL, n_entries, *entry_size, NULL))\n\t\treturn HSAKMT_STATUS_ERROR;\n\t*data = malloc(*n_entries * *entry_size);\n\tif (!*data)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\tif (suspend_queues && *n_entries)\n\t\tqueue_ids = (uint32_t *)malloc(sizeof(uint32_t) * *n_entries);\n\tif (!queue_ids ||\n\t    dbg_trap_get_queue_data(*data, n_entries, *entry_size, queue_ids))\n\t\tgoto free_data;\n\tif (queue_ids) {\n\t\tif (dbg_trap_suspend_queues(queue_ids, *n_entries) ||\n\t\t    dbg_trap_get_queue_data(*data, n_entries, *entry_size, NULL))\n\t\t\tgoto free_data;\n\t\tfree(queue_ids);\n\t}\n\treturn HSAKMT_STATUS_SUCCESS;\nfree_data:\n\tfree(*data);\n\tif (queue_ids)\n\t\tfree(queue_ids);\n\n\treturn HSAKMT_STATUS_ERROR;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDebugTrapIoctl(struct kfd_ioctl_dbg_trap_args *args,\n\t\t\t\t\tHSA_QUEUEID *Queues,\n\t\t\t\t\tHSAuint64 *DebugReturn)\n{\n\tHSAKMT_STATUS result;\n\n\tCHECK_KFD_OPEN();\n\n\tif (Queues) {\n\t\tint num_queues = args->op == KFD_IOC_DBG_TRAP_SUSPEND_QUEUES ?\n\t\t\t\t\t\targs->suspend_queues.num_queues :\n\t\t\t\t\t\targs->resume_queues.num_queues;\n\t\tvoid *queue_ptr = args->op == KFD_IOC_DBG_TRAP_SUSPEND_QUEUES ?\n\t\t\t\t\t\t(void *)args->suspend_queues.queue_array_ptr :\n\t\t\t\t\t\t(void *)args->resume_queues.queue_array_ptr;\n\n\t\tuint32_t *queue_ids = hsakmt_convert_queue_ids(num_queues, Queues);\n\t\tif (!queue_ids) {\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\t}\n\t\tmemcpy(queue_ptr, queue_ids, num_queues * sizeof(uint32_t));\n\t\tfree(queue_ids);\n\t}\n\n\tlong err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DBG_TRAP, args);\n\tif (DebugReturn)\n\t\t*DebugReturn = err;\n\n\tif (args->op == KFD_IOC_DBG_TRAP_SUSPEND_QUEUES &&\n\t\t\t\terr >= 0 && err <= args->suspend_queues.num_queues)\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\telse if (args->op == KFD_IOC_DBG_TRAP_RESUME_QUEUES &&\n\t\t\t\terr >= 0 && err <= args->resume_queues.num_queues)\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\telse if (err == 0)\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\telse\n\t\tresult = HSAKMT_STATUS_ERROR;\n\n\treturn result;\n}\n"
  },
  {
    "path": "libhsakmt/src/events.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <unistd.h>\n#include <sys/mman.h>\n#include <stdio.h>\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"fmm.h\"\n#include \"hsakmt/hsakmtmodel.h\"\n\nstatic HSAuint64 *events_page = NULL;\n\nvoid hsakmt_clear_events_page(void)\n{\n\tevents_page = NULL;\n}\n\nstatic bool IsSystemEventType(HSA_EVENTTYPE type)\n{\n\t// Debug events behave as signal events.\n\treturn (type != HSA_EVENTTYPE_SIGNAL && type != HSA_EVENTTYPE_DEBUG_EVENT);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtCreateEvent(HsaEventDescriptor *EventDesc,\n\t\t\t\t\t  bool ManualReset, bool IsSignaled,\n\t\t\t\t\t  HsaEvent **Event)\n{\n\tunsigned int event_limit = KFD_SIGNAL_EVENT_LIMIT;\n\n\tCHECK_KFD_OPEN();\n\n\tif (EventDesc->EventType >= HSA_EVENTTYPE_MAXID)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tHsaEvent *e = malloc(sizeof(HsaEvent));\n\n\tif (!e)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemset(e, 0, sizeof(*e));\n\n\tstruct kfd_ioctl_create_event_args args = {0};\n\n\targs.event_type = EventDesc->EventType;\n\targs.node_id = EventDesc->NodeId;\n\targs.auto_reset = !ManualReset;\n\n\t/* dGPU code */\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\tif (hsakmt_is_dgpu && !events_page) {\n\t\tevents_page = hsakmt_allocate_exec_aligned_memory_gpu(\n\t\t\tKFD_SIGNAL_EVENT_LIMIT * 8, PAGE_SIZE, 0, 0, true, false, true);\n\t\tif (!events_page) {\n\t\t\tfree(e);\n\t\t\tpthread_mutex_unlock(&hsakmt_mutex);\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t\t}\n\t\tif (hsakmt_use_model)\n\t\t\tmodel_set_event_page(events_page, KFD_SIGNAL_EVENT_LIMIT);\n\t\telse\n\t\t\thsakmt_fmm_get_handle(events_page, (uint64_t *)&args.event_page_offset);\n\t}\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_CREATE_EVENT, &args) != 0) {\n\t\tfree(e);\n\t\t*Event = NULL;\n\t\tpthread_mutex_unlock(&hsakmt_mutex);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\te->EventId = args.event_id;\n\n\tif (!events_page && args.event_page_offset > 0) {\n\t\tevents_page = mmap(NULL, event_limit * 8, PROT_WRITE | PROT_READ,\n\t\t\t\tMAP_SHARED, hsakmt_kfd_fd, args.event_page_offset);\n\t\tif (events_page == MAP_FAILED) {\n\t\t\t/* old kernels only support 256 events */\n\t\t\tevent_limit = 256;\n\t\t\tevents_page = mmap(NULL, PAGE_SIZE, PROT_WRITE | PROT_READ,\n\t\t\t\t\t   MAP_SHARED, hsakmt_kfd_fd, args.event_page_offset);\n\t\t}\n\t\tif (events_page == MAP_FAILED) {\n\t\t\tevents_page = NULL;\n\t\t\tpthread_mutex_unlock(&hsakmt_mutex);\n\t\t\thsaKmtDestroyEvent(e);\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t\t}\n\t}\n\n\tif (args.event_page_offset > 0 && args.event_slot_index < event_limit)\n\t\te->EventData.HWData2 = (HSAuint64)&events_page[args.event_slot_index];\n\n        pthread_mutex_unlock(&hsakmt_mutex);\n\n        e->EventData.EventType = EventDesc->EventType;\n        e->EventData.HWData1 = args.event_id;\n\n\te->EventData.HWData3 = args.event_trigger_data;\n\te->EventData.EventData.SyncVar.SyncVar.UserData =\n\t\tEventDesc->SyncVar.SyncVar.UserData;\n\te->EventData.EventData.SyncVar.SyncVarSize =\n\t\tEventDesc->SyncVar.SyncVarSize;\n\n\tif (IsSignaled && !IsSystemEventType(e->EventData.EventType)) {\n\t\tstruct kfd_ioctl_set_event_args set_args = {0};\n\n\t\tset_args.event_id = args.event_id;\n\n                if (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_EVENT,\n                                 &set_args) != 0) {\n                  hsaKmtDestroyEvent(e);\n                  return HSAKMT_STATUS_ERROR;\n                }\n        }\n\n        *Event = e;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDestroyEvent(HsaEvent *Event)\n{\n\tCHECK_KFD_OPEN();\n\n\tif (!Event)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tstruct kfd_ioctl_destroy_event_args args = {0};\n\n\targs.event_id = Event->EventId;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DESTROY_EVENT, &args) != 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tfree(Event);\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSetEvent(HsaEvent *Event)\n{\n\tCHECK_KFD_OPEN();\n\n\tif (!Event)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\t/* Although the spec is doesn't say, don't allow system-defined events\n\t * to be signaled.\n\t */\n\tif (IsSystemEventType(Event->EventData.EventType))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tstruct kfd_ioctl_set_event_args args = {0};\n\n\targs.event_id = Event->EventId;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_EVENT, &args) == -1)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtResetEvent(HsaEvent *Event)\n{\n\tCHECK_KFD_OPEN();\n\n\tif (!Event)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\t/* Although the spec is doesn't say, don't allow system-defined events\n\t * to be signaled.\n\t */\n\tif (IsSystemEventType(Event->EventData.EventType))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tstruct kfd_ioctl_reset_event_args args = {0};\n\n\targs.event_id = Event->EventId;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RESET_EVENT, &args) == -1)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtQueryEventState(HsaEvent *Event)\n{\n\tCHECK_KFD_OPEN();\n\n\tif (!Event)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtWaitOnEvent(HsaEvent *Event,\n\t\tHSAuint32 Milliseconds)\n{\n\treturn hsaKmtWaitOnEvent_Ext(Event, Milliseconds, NULL);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtWaitOnEvent_Ext(HsaEvent *Event,\n\t\tHSAuint32 Milliseconds, uint64_t *event_age)\n{\n\tif (!Event)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\treturn hsaKmtWaitOnMultipleEvents_Ext(&Event, 1, true, Milliseconds, event_age);\n}\n\nstatic HSAKMT_STATUS get_mem_info_svm_api(uint64_t address, uint32_t gpu_id)\n{\n\tstruct kfd_ioctl_svm_args *args;\n        uint32_t node_id = 0;\n        HSAuint32 s_attr;\n        HSAuint32 i;\n\tHSA_SVM_ATTRIBUTE attrs[] = {\n\t\t\t\t\t{HSA_SVM_ATTR_PREFERRED_LOC, 0},\n\t\t\t\t\t{HSA_SVM_ATTR_PREFETCH_LOC, 0},\n\t\t\t\t\t{HSA_SVM_ATTR_ACCESS, gpu_id},\n\t\t\t\t\t{HSA_SVM_ATTR_SET_FLAGS, 0},\n\t\t\t\t    };\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(5);\n\n\ts_attr = sizeof(attrs);\n\targs = alloca(sizeof(*args) + s_attr);\n\targs->start_addr = address;\n\targs->size = PAGE_SIZE;\n\targs->op = KFD_IOCTL_SVM_OP_GET_ATTR;\n\targs->nattr = s_attr / sizeof(*attrs);\n\tmemcpy(args->attrs, attrs, s_attr);\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SVM + (s_attr << _IOC_SIZESHIFT), args)) {\n\t\tpr_debug(\"op get range attrs failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tpr_err(\"GPU address 0x%lx, is Unified memory\\n\", address);\n\tfor (i = 0; i < args->nattr; i++) {\n\t\tif (args->attrs[i].value == KFD_IOCTL_SVM_LOCATION_SYSMEM ||\n\t\t    args->attrs[i].value == KFD_IOCTL_SVM_LOCATION_UNDEFINED)\n\t\t\tnode_id = args->attrs[i].value;\n\t\telse\n\t\t\thsakmt_gpuid_to_nodeid(args->attrs[i].value, &node_id);\n\t\tswitch (args->attrs[i].type) {\n\t\tcase KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:\n\t\t\tpr_err(\"Preferred location for address 0x%lx is Node id %d\\n\",\n\t\t\t\taddress, node_id);\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:\n\t\t\tpr_err(\"Prefetch location for address 0x%lx is Node id %d\\n\",\n\t\t\t\taddress, node_id);\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_ATTR_ACCESS:\n\t\t\tpr_err(\"Node id %d has access to address 0x%lx\\n\",\n\t\t\t\tnode_id, address);\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:\n\t\t\tpr_err(\"Node id %d has access in place to address 0x%lx\\n\",\n\t\t\t\tnode_id, address);\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_ATTR_NO_ACCESS:\n\t\t\tpr_err(\"Node id %d has no access to address 0x%lx\\n\",\n\t\t\t\tnode_id, address);\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_ATTR_SET_FLAGS:\n\t\t\tif (args->attrs[i].value & KFD_IOCTL_SVM_FLAG_COHERENT)\n\t\t\t\tpr_err(\"Fine grained coherency between devices\\n\");\n\t\t\tif (args->attrs[i].value & KFD_IOCTL_SVM_FLAG_GPU_RO)\n\t\t\t\tpr_err(\"Read only\\n\");\n\t\t\tif (args->attrs[i].value & KFD_IOCTL_SVM_FLAG_GPU_EXEC)\n\t\t\t\tpr_err(\"GPU exec allowed\\n\");\n\t\t\tif (args->attrs[i].value & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED)\n\t\t\t\t pr_err(\"GPU always mapped\\n\");\n\t\t\tif (args->attrs[i].value & KFD_IOCTL_SVM_FLAG_EXT_COHERENT)\n\t\t\t\t pr_err(\"Extended-scope fine grained coherency between devices\\n\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpr_debug(\"get invalid attr type 0x%x\\n\", args->attrs[i].type);\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t\t}\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n//Analysis memory exception data, print debug messages\nstatic void analysis_memory_exception(struct kfd_hsa_memory_exception_data *\n\t\t\t\t\t\tmemory_exception_data)\n{\n\tHSAKMT_STATUS ret;\n\tHsaPointerInfo info;\n\tconst uint64_t addr = memory_exception_data->va;\n\tuint32_t node_id = 0;\n\tunsigned int i;\n\n\thsakmt_gpuid_to_nodeid(memory_exception_data->gpu_id, &node_id);\n\tpr_err(\"Memory exception on virtual address 0x%lx, \", addr);\n\tpr_err(\"node id %d : \", node_id);\n\tif (memory_exception_data->failure.NotPresent)\n\t\tpr_err(\"Page not present\\n\");\n\telse if (memory_exception_data->failure.ReadOnly)\n\t\tpr_err(\"Writing to readonly page\\n\");\n\telse if (memory_exception_data->failure.NoExecute)\n\t\tpr_err(\"Execute to none-executable page\\n\");\n\n\tret = hsakmt_fmm_get_mem_info((const void *)addr, &info);\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\tret = get_mem_info_svm_api(addr, memory_exception_data->gpu_id);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tpr_err(\"Address does not belong to a known buffer\\n\");\n\t\treturn;\n\t}\n\n\tpr_err(\"GPU address 0x%lx, node id %d, size in byte 0x%lx\\n\",\n\t\t\tinfo.GPUAddress, info.Node, info.SizeInBytes);\n\tswitch (info.Type) {\n\tcase HSA_POINTER_REGISTERED_SHARED:\n\t\tpr_err(\"Memory is registered shared buffer (IPC)\\n\");\n\t\tbreak;\n\tcase HSA_POINTER_REGISTERED_GRAPHICS:\n\t\tpr_err(\"Memory is registered graphics buffer\\n\");\n\t\tbreak;\n\tcase HSA_POINTER_REGISTERED_USER:\n\t\tpr_err(\"Memory is registered user pointer\\n\");\n\t\tpr_err(\"CPU address of the memory is %p\\n\", info.CPUAddress);\n\t\tbreak;\n\tcase HSA_POINTER_ALLOCATED:\n\t\tpr_err(\"Memory is allocated using hsaKmtAllocMemory\\n\");\n\t\tpr_err(\"CPU address of the memory is %p\\n\", info.CPUAddress);\n\t\tbreak;\n\tcase HSA_POINTER_RESERVED_ADDR:\n\t\tpr_err(\"Memory is allocated by OnlyAddress mode\\n\");\n\t\tbreak;\n\tdefault:\n\t\tpr_err(\"Invalid memory type %d\\n\", info.Type);\n\t\tbreak;\n\t}\n\n\tif (info.RegisteredNodes) {\n\t\tpr_err(\"Memory is registered to node id: \");\n\t\tfor (i = 0; i < info.NRegisteredNodes; i++)\n\t\t\tpr_err(\"%d \", info.RegisteredNodes[i]);\n\t\tpr_err(\"\\n\");\n\t}\n\tif (info.MappedNodes) {\n\t\tpr_err(\"Memory is mapped to node id: \");\n\t\tfor (i = 0; i < info.NMappedNodes; i++)\n\t\t\tpr_err(\"%d \", info.MappedNodes[i]);\n\t\tpr_err(\"\\n\");\n\t}\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtWaitOnMultipleEvents(HsaEvent *Events[],\n\t\t\t\t\t\t   HSAuint32 NumEvents,\n\t\t\t\t\t\t   bool WaitOnAll,\n\t\t\t\t\t\t   HSAuint32 Milliseconds)\n{\n\treturn hsaKmtWaitOnMultipleEvents_Ext(Events, NumEvents, WaitOnAll, Milliseconds, NULL);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtWaitOnMultipleEvents_Ext(HsaEvent *Events[],\n\t\t\t\t\t\t   HSAuint32 NumEvents,\n\t\t\t\t\t\t   bool WaitOnAll,\n\t\t\t\t\t\t   HSAuint32 Milliseconds,\n\t\t\t\t\t\t   uint64_t *event_age)\n{\n        HSAKMT_STATUS result;\n        CHECK_KFD_OPEN();\n\n        if (!Events)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n        struct kfd_event_data *event_data =\n        calloc(NumEvents, sizeof(struct kfd_event_data));\n        if (!event_data) {\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t}\n        for (HSAuint32 i = 0; i < NumEvents; i++) {\n\t\tevent_data[i].event_id = Events[i]->EventId;\n\t\tevent_data[i].kfd_event_data_ext = (uint64_t)(uintptr_t)NULL;\n\t\tif (event_age && Events[i]->EventData.EventType == HSA_EVENTTYPE_SIGNAL)\n\t\t\tevent_data[i].signal_event_data.last_event_age = event_age[i];\n\t}\n\n        struct kfd_ioctl_wait_events_args args = {0};\n\n\targs.wait_for_all = WaitOnAll;\n\targs.timeout = Milliseconds;\n\targs.num_events = NumEvents;\n\targs.events_ptr = (uint64_t)(uintptr_t)event_data;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_WAIT_EVENTS, &args) == -1)\n\t\tresult = HSAKMT_STATUS_ERROR;\n\telse if (args.wait_result == KFD_IOC_WAIT_RESULT_TIMEOUT)\n\t\tresult = HSAKMT_STATUS_WAIT_TIMEOUT;\n\telse {\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\t\tfor (HSAuint32 i = 0; i < NumEvents; i++) {\n\t\t\tif (Events[i]->EventData.EventType == HSA_EVENTTYPE_MEMORY &&\n\t\t\t    event_data[i].memory_exception_data.gpu_id) {\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.VirtualAddress = event_data[i].memory_exception_data.va;\n\t\t\t\tresult = hsakmt_gpuid_to_nodeid(event_data[i].memory_exception_data.gpu_id, &Events[i]->EventData.EventData.MemoryAccessFault.NodeId);\n\t\t\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t\t\t\tgoto out;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.NotPresent = event_data[i].memory_exception_data.failure.NotPresent;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.ReadOnly = event_data[i].memory_exception_data.failure.ReadOnly;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.NoExecute = event_data[i].memory_exception_data.failure.NoExecute;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.Imprecise = event_data[i].memory_exception_data.failure.imprecise;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.ErrorType = event_data[i].memory_exception_data.ErrorType;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Failure.ECC =\n\t\t\t\t\t\t((event_data[i].memory_exception_data.ErrorType == 1) || (event_data[i].memory_exception_data.ErrorType == 2)) ? 1 : 0;\n\t\t\t\tEvents[i]->EventData.EventData.MemoryAccessFault.Flags = HSA_EVENTID_MEMORY_FATAL_PROCESS;\n\t\t\t\tanalysis_memory_exception(&event_data[i].memory_exception_data);\n\t\t\t} else if (Events[i]->EventData.EventType == HSA_EVENTTYPE_HW_EXCEPTION &&\n\t\t\t\tevent_data[i].hw_exception_data.gpu_id) {\n\n\t\t\t\tresult = hsakmt_gpuid_to_nodeid(event_data[i].hw_exception_data.gpu_id, &Events[i]->EventData.EventData.HwException.NodeId);\n\t\t\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t\t\t\tgoto out;\n\n\t\t\t\tEvents[i]->EventData.EventData.HwException.ResetType = event_data[i].hw_exception_data.reset_type;\n\t\t\t\tEvents[i]->EventData.EventData.HwException.ResetCause = event_data[i].hw_exception_data.reset_cause;\n\t\t\t\tEvents[i]->EventData.EventData.HwException.MemoryLost = event_data[i].hw_exception_data.memory_lost;\n\t\t\t}\n\t\t}\n\t}\nout:\n\n\tfor (HSAuint32 i = 0; i < NumEvents; i++) {\n\t\tif (event_age && Events[i]->EventData.EventType == HSA_EVENTTYPE_SIGNAL)\n\t\t\tevent_age[i] = event_data[i].signal_event_data.last_event_age;\n\t}\n\n\tfree(event_data);\n\n\treturn result;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtOpenSMI(HSAuint32 NodeId, int *fd)\n{\n\tstruct kfd_ioctl_smi_events_args args;\n\tHSAKMT_STATUS result;\n\tuint32_t gpuid;\n\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] node %d\\n\", __func__, NodeId);\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpuid);\n\tif (result != HSAKMT_STATUS_SUCCESS) {\n\t\tpr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n\t\treturn result;\n\t}\n\n\targs.gpuid = gpuid;\n\tresult = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SMI_EVENTS, &args);\n\tif (result) {\n\t\tpr_debug(\"open SMI event fd failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\t*fd = args.anon_fd;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/src/fmm.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#define _GNU_SOURCE\n#include \"libhsakmt.h\"\n#include \"fmm.h\"\n#include \"hsakmt/hsakmtmodel.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <sys/mman.h>\n#include <sys/time.h>\n#include <errno.h>\n#include <assert.h>\n\n#include <numa.h>\n#include <numaif.h>\n#include \"rbtree.h\"\n#include <amdgpu.h>\n\n#include <fcntl.h>\n#include <sys/ioctl.h>\n#include <sys/stat.h>\n#include \"hsakmt/linux/udmabuf.h\"\n\n#ifndef MPOL_F_STATIC_NODES\n/* Bug in numaif.h, this should be defined in there. Definition copied\n * from linux/mempolicy.h.\n */\n#define MPOL_F_STATIC_NODES     (1 << 15)\n#endif\n\n#define NON_VALID_GPU_ID 0\n\n#define INIT_MANAGEABLE_APERTURE(base_value, limit_value) {\t\\\n\t.base = (void *) base_value,\t\t\t\t\\\n\t.limit = (void *) limit_value,\t\t\t\t\\\n\t.align = 0,\t\t\t\t\t\t\\\n\t.guard_pages = 1,\t\t\t\t\t\\\n\t.vm_ranges = NULL,\t\t\t\t\t\\\n\t.fmm_mutex = PTHREAD_MUTEX_INITIALIZER,\t\t\t\\\n\t.is_cpu_accessible = false,\t\t\t\t\\\n\t.ops = &reserved_aperture_ops\t\t\t\t\\\n\t}\n\n#define container_of(ptr, type, member) ({\t\t\t\\\n\t\tchar *__mptr = (void *)(ptr);\t\t\t\\\n\t\t((type *)(__mptr - offsetof(type, member))); })\n\n#define rb_entry(ptr, type, member)\t\t\t\t\\\n\t\tcontainer_of(ptr, type, member)\n\n#define vm_object_entry(n, is_userptr) ({\t\t\t\\\n\t\t(is_userptr) == 0 ?\t\t\t\t\\\n\t\trb_entry(n, vm_object_t, node) :\t\t\\\n\t\trb_entry(n, vm_object_t, user_node); })\n\n#define vm_object_tree(app, is_userptr)\t\t\t\t\\\n\t\t((is_userptr) ? &(app)->user_tree : &(app)->tree)\n\n#define START_NON_CANONICAL_ADDR (1ULL << 47)\n#define END_NON_CANONICAL_ADDR (~0UL - (1UL << 47))\n\nstruct vm_object {\n\tvoid *start;\n\tvoid *userptr;\n\tuint64_t userptr_size;\n\tuint64_t size; /* size allocated on GPU. When the user requests a random\n\t\t\t* size, Thunk aligns it to page size and allocates this\n\t\t\t* aligned size on GPU\n\t\t\t*/\n\tuint32_t node_id;\n\trbtree_node_t node;\n\trbtree_node_t user_node;\n\n\tHsaMemFlags mflags; /* memory allocation flags */\n\t/* Registered nodes to map on SVM mGPU */\n\tuint32_t *registered_device_id_array;\n\tuint32_t registered_device_id_array_size;\n\tuint32_t *registered_node_id_array;\n\tuint32_t registration_count; /* the same memory region can be registered multiple times */\n\t/* Nodes that mapped already */\n\tuint32_t *mapped_device_id_array;\n\tuint32_t mapped_device_id_array_size;\n\tuint32_t *mapped_node_id_array;\n\tuint32_t mapping_count;\n\t/* Metadata of imported graphics buffers */\n\tvoid *metadata;\n\t/* User data associated with the memory */\n\tvoid *user_data;\n\t/* Flag to indicate imported KFD buffer */\n\tbool is_imported_kfd_bo;\n#ifdef SANITIZER_AMDGPU\n\tint mmap_flags;\n\tint mmap_fd;\n\toff_t mmap_offset;\n#endif\n\tuint32_t handle_num; /* number of handles */\n\tuint64_t handles[]; /* kfd handles array */\n};\ntypedef struct vm_object vm_object_t;\n\nstruct vm_area {\n\tvoid *start;\n\tvoid *end;\n\tstruct vm_area *next;\n\tstruct vm_area *prev;\n};\ntypedef struct vm_area vm_area_t;\n\n/* Memory manager for an aperture */\ntypedef struct manageable_aperture manageable_aperture_t;\n\n/* Aperture management function pointers to allow different management\n * schemes.\n */\ntypedef struct {\n\tvoid *(*allocate_area_aligned)(manageable_aperture_t *aper, void *addr,\n\t\t\t\t       uint64_t size, uint64_t align);\n\tvoid (*release_area)(manageable_aperture_t *aper,\n\t\t\t     void *addr, uint64_t size);\n} manageable_aperture_ops_t;\n\n/* Reserved aperture type managed by its own address allocator */\nstatic void *reserved_aperture_allocate_aligned(manageable_aperture_t *aper,\n\t\t\t\t\t\tvoid *addr,\n\t\t\t\t\t\tuint64_t size, uint64_t align);\nstatic void reserved_aperture_release(manageable_aperture_t *aper,\n\t\t\t\t      void *addr, uint64_t size);\n\nstatic int bind_mem_to_numa(uint32_t node_id, void *mem,\n\t\t\t    uint64_t SizeInBytes, HsaMemFlags mflags);\n\nstatic const manageable_aperture_ops_t reserved_aperture_ops = {\n\treserved_aperture_allocate_aligned,\n\treserved_aperture_release\n};\n\n/* Unreserved aperture type using mmap to allocate virtual address space */\nstatic void *mmap_aperture_allocate_aligned(manageable_aperture_t *aper,\n\t\t\t\t\t    void *addr,\n\t\t\t\t\t    uint64_t size, uint64_t align);\nstatic void mmap_aperture_release(manageable_aperture_t *aper,\n\t\t\t\t  void *addr, uint64_t size);\nstatic const manageable_aperture_ops_t mmap_aperture_ops = {\n\tmmap_aperture_allocate_aligned,\n\tmmap_aperture_release\n};\n\nstruct manageable_aperture {\n\tvoid *base;\n\tvoid *limit;\n\tuint64_t align;\n\tuint32_t guard_pages;\n\tvm_area_t *vm_ranges;\n\trbtree_t tree;\n\trbtree_t user_tree;\n\tpthread_mutex_t fmm_mutex;\n\tbool is_cpu_accessible;\n\tconst manageable_aperture_ops_t *ops;\n};\n\ntypedef struct {\n\tvoid *base;\n\tvoid *limit;\n} aperture_t;\n\ntypedef struct {\n\tuint32_t gpu_id;\n\tuint32_t device_id;\n\tuint32_t node_id;\n\tuint64_t local_mem_size;\n\tHSA_ENGINE_ID EngineId;\n\taperture_t lds_aperture;\n\taperture_t scratch_aperture;\n\taperture_t mmio_aperture;\n\tmanageable_aperture_t scratch_physical; /* For dGPU, scratch physical is allocated from\n\t\t\t\t\t\t * dgpu_aperture. When requested by RT, each\n\t\t\t\t\t\t * GPU will get a differnt range\n\t\t\t\t\t\t */\n\tmanageable_aperture_t gpuvm_aperture;   /* used for GPUVM on APU, outsidethe canonical address range */\n\tint drm_render_fd;\n\tuint32_t usable_peer_id_num;\n\tuint32_t *usable_peer_id_array;\n\tint drm_render_minor;\n} gpu_mem_t;\n\nenum svm_aperture_type {\n\tSVM_DEFAULT = 0,\n\tSVM_COHERENT,\n\tSVM_APERTURE_NUM\n};\n\n/* The main structure for dGPU Shared Virtual Memory Management */\ntypedef struct {\n\t/* Two apertures can have different MTypes (for coherency) */\n\tmanageable_aperture_t apertures[SVM_APERTURE_NUM];\n\n\t/* Pointers to apertures, may point to the same aperture on\n\t * GFXv9 and later, where MType is not based on apertures\n\t */\n\tmanageable_aperture_t *dgpu_aperture;\n\tmanageable_aperture_t *dgpu_alt_aperture;\n\n\t/* whether to use userptr for paged memory */\n\tbool userptr_for_paged_mem;\n\n\t/* whether to check userptrs on registration */\n\tbool check_userptr;\n\n\t/* whether to check reserve svm on registration */\n\tbool reserve_svm;\n\n\t/* whether all memory is coherent (GPU cache disabled) */\n\tbool disable_cache;\n\n\t/* specifies the alignment size as PAGE_SIZE * 2^alignment_order */\n\tuint32_t alignment_order;\n} svm_t;\n\n/* The other apertures are specific to each GPU. gpu_mem_t manages GPU\n * specific memory apertures.\n */\nstatic gpu_mem_t *gpu_mem;\nstatic unsigned int gpu_mem_count;\nstatic gpu_mem_t *g_first_gpu_mem;\n\nstatic void *dgpu_shared_aperture_base;\nstatic void *dgpu_shared_aperture_limit;\n\nstatic svm_t svm = {\n\t.apertures = {INIT_MANAGEABLE_APERTURE(0, 0),\n\t\t      INIT_MANAGEABLE_APERTURE(0, 0)},\n\t.dgpu_aperture = NULL,\n\t.dgpu_alt_aperture = NULL,\n\t.userptr_for_paged_mem = false,\n\t.check_userptr = false,\n\t.disable_cache = false,\n};\n\n/* On APU, for memory allocated on the system memory that GPU doesn't access\n * via GPU driver, they are not managed by GPUVM. cpuvm_aperture keeps track\n * of this part of memory.\n */\nstatic manageable_aperture_t cpuvm_aperture = INIT_MANAGEABLE_APERTURE(0, 0);\n\n/* mem_handle_aperture is used to generate memory handles\n * for allocations that don't have a valid virtual address\n * its size is 47bits.\n*/\nstatic manageable_aperture_t mem_handle_aperture = INIT_MANAGEABLE_APERTURE(START_NON_CANONICAL_ADDR, (START_NON_CANONICAL_ADDR + (1ULL << 47)));\n\n/* GPU node array for default mappings */\nstatic uint32_t all_gpu_id_array_size;\nstatic uint32_t *all_gpu_id_array;\n\n/* IPC structures and helper functions */\ntypedef enum _HSA_APERTURE {\n\tHSA_APERTURE_UNSUPPORTED = 0,\n\tHSA_APERTURE_DGPU,\n\tHSA_APERTURE_DGPU_ALT,\n\tHSA_APERTURE_GPUVM,\n\tHSA_APERTURE_CPUVM,\n\tHSA_APERTURE_MEMHANDLE\n} HSA_APERTURE;\n\ntypedef struct _HsaApertureInfo {\n\tHSA_APERTURE\ttype;\t\t// Aperture type\n\tHSAuint32\tidx;\t\t// Aperture index\n} HsaApertureInfo;\n\ntypedef struct _HsaSharedMemoryStruct {\n\tHSAuint32\tShareHandle[4];\n\tHsaApertureInfo\tApeInfo;\n\tHSAuint32\tSizeInPages;\n\tHSAuint32\tExportGpuId;\n} HsaSharedMemoryStruct;\n\nstatic inline const HsaSharedMemoryStruct *to_const_hsa_shared_memory_struct(\n\t\t\tconst HsaSharedMemoryHandle *SharedMemoryHandle)\n{\n\treturn (const HsaSharedMemoryStruct *)SharedMemoryHandle;\n}\n\nstatic inline HsaSharedMemoryStruct *to_hsa_shared_memory_struct(\n\t\t\tHsaSharedMemoryHandle *SharedMemoryHandle)\n{\n\treturn (HsaSharedMemoryStruct *)SharedMemoryHandle;\n}\n\n__attribute__((unused))\nstatic inline HsaSharedMemoryHandle *to_hsa_shared_memory_handle(\n\t\t\tHsaSharedMemoryStruct *SharedMemoryStruct)\n{\n\treturn (HsaSharedMemoryHandle *)SharedMemoryStruct;\n}\n\nstatic int __fmm_release(vm_object_t *object, manageable_aperture_t *aperture);\nstatic int _fmm_unmap_from_gpu_scratch(uint32_t gpu_id,\n\t\t\t\t       manageable_aperture_t *aperture,\n\t\t\t\t       void *address);\nstatic void print_device_id_array(uint32_t *device_id_array, uint32_t device_id_array_size);\n\nstatic vm_area_t *vm_create_and_init_area(void *start, void *end)\n{\n\tvm_area_t *area = (vm_area_t *) malloc(sizeof(vm_area_t));\n\n\tif (area) {\n\t\tarea->start = start;\n\t\tarea->end = end;\n\t\tarea->next = area->prev = NULL;\n\t}\n\n\treturn area;\n}\n\n/* One huge page smaller than 512GB system buffer limit,\n * because 512GB allocation will cause TTM failure.\n */\n#define BIGGEST_SINGLE_BUF_SIZE ((1ULL << 39) - GPU_HUGE_PAGE_SIZE)\n\nstatic vm_object_t *vm_create_and_init_object(void *start, uint64_t size,\n\t\t\t\t\t      uint64_t handle, HsaMemFlags mflags)\n{\n\tvm_object_t *object;\n\tuint64_t handle_array_size = (size + BIGGEST_SINGLE_BUF_SIZE - 1) /\n\t\t\t\t     BIGGEST_SINGLE_BUF_SIZE;\n\n\tobject = (vm_object_t *) malloc(sizeof(vm_object_t) +\n\t\t handle_array_size * sizeof(uint64_t));\n\n\tif (object) {\n\t\tobject->start = start;\n\t\tobject->userptr = NULL;\n\t\tobject->userptr_size = 0;\n\t\tobject->size = size;\n\t\tobject->handles[0] = handle;\n\t\tobject->handle_num = 1;\n\t\tobject->registered_device_id_array_size = 0;\n\t\tobject->mapped_device_id_array_size = 0;\n\t\tobject->registered_device_id_array = NULL;\n\t\tobject->mapped_device_id_array = NULL;\n\t\tobject->registered_node_id_array = NULL;\n\t\tobject->mapped_node_id_array = NULL;\n\t\tobject->registration_count = 0;\n\t\tobject->mapping_count = 0;\n\t\tobject->mflags = mflags;\n\t\tobject->metadata = NULL;\n\t\tobject->user_data = NULL;\n\t\tobject->is_imported_kfd_bo = false;\n\t\tobject->node.key = rbtree_key((unsigned long)start, size);\n\t\tobject->user_node.key = rbtree_key(0, 0);\n#ifdef SANITIZER_AMDGPU\n\t\tobject->mmap_fd = 0;\n#endif\n\t}\n\n\treturn object;\n}\n\n\nstatic void vm_remove_area(manageable_aperture_t *app, vm_area_t *area)\n{\n\tvm_area_t *next;\n\tvm_area_t *prev;\n\n\tnext = area->next;\n\tprev = area->prev;\n\n\tif (!prev) /* The first element */\n\t\tapp->vm_ranges = next;\n\telse\n\t\tprev->next = next;\n\n\tif (next) /* If not the last element */\n\t\tnext->prev = prev;\n\n\tfree(area);\n}\n\nstatic void vm_remove_object(manageable_aperture_t *app, vm_object_t *object)\n{\n\t/* Free allocations inside the object */\n\tif (object->registered_device_id_array)\n\t\tfree(object->registered_device_id_array);\n\n\tif (object->mapped_device_id_array)\n\t\tfree(object->mapped_device_id_array);\n\n\tif (object->metadata)\n\t\tfree(object->metadata);\n\n\tif (object->registered_node_id_array)\n\t\tfree(object->registered_node_id_array);\n\tif (object->mapped_node_id_array)\n\t\tfree(object->mapped_node_id_array);\n\n\thsakmt_rbtree_delete(&app->tree, &object->node);\n\tif (object->userptr)\n\t\thsakmt_rbtree_delete(&app->user_tree, &object->user_node);\n\n\tfree(object);\n}\n\nstatic void vm_add_area_after(vm_area_t *after_this, vm_area_t *new_area)\n{\n\tvm_area_t *next = after_this->next;\n\n\tafter_this->next = new_area;\n\tnew_area->next = next;\n\n\tnew_area->prev = after_this;\n\tif (next)\n\t\tnext->prev = new_area;\n}\n\nstatic void vm_split_area(manageable_aperture_t *app, vm_area_t *area,\n\t\t\t\tvoid *address, uint64_t MemorySizeInBytes)\n{\n\t/*\n\t * The existing area is split to: [area->start, address - 1]\n\t * and [address + MemorySizeInBytes, area->end]\n\t */\n\tvm_area_t *new_area = vm_create_and_init_area(\n\t\t\t\tVOID_PTR_ADD(address, MemorySizeInBytes),\n\t\t\t\tarea->end);\n\n\tif (new_area == NULL) {\n\t\tpr_err(\"[%s] Failed to create new area during split.\", __func__);\n\t\treturn;\n\t}\n\t/* Shrink the existing area */\n\tarea->end = VOID_PTR_SUB(address, 1);\n\n\tvm_add_area_after(area, new_area);\n}\n\nstatic vm_object_t *vm_find_object_by_address_userptr(manageable_aperture_t *app,\n\t\t\t\t\tconst void *address, uint64_t size, int is_userptr)\n{\n\tvm_object_t *cur = NULL;\n\n\trbtree_t *tree = vm_object_tree(app, is_userptr);\n\trbtree_key_t key = rbtree_key((unsigned long)address, size);\n\tvoid *start;\n\tuint64_t s;\n\n\t/* rbtree_lookup_nearest(,,,RIGHT) will return a node with\n\t * its size >= key.size and its address >= key.address\n\t * if there are two nodes with format(address, size),\n\t * (0x100, 16) and (0x110, 8). the key is (0x100, 0),\n\t * then node (0x100, 16) will be returned.\n\t */\n\trbtree_node_t *n = rbtree_lookup_nearest(tree, &key, LKP_ALL, RIGHT);\n\n\tif (n) {\n\t\tcur = vm_object_entry(n, is_userptr);\n\t\tif (is_userptr == 0) {\n\t\t\tstart = cur->start;\n\t\t\ts = cur->size;\n\t\t} else {\n\t\t\tstart = cur->userptr;\n\t\t\ts = cur->userptr_size;\n\t\t}\n\n\t\tif (start != address)\n\t\t\treturn NULL;\n\n\t\tif (size)\n\t\t\treturn size == s ? cur : NULL;\n\n\t\t/* size is 0, make sure there is only one node whose address == key.address*/\n\t\tkey = rbtree_key((unsigned long)address, (unsigned long)-1);\n\t\trbtree_node_t *rn = rbtree_lookup_nearest(tree, &key, LKP_ALL, LEFT);\n\n\t\tif (rn != n)\n\t\t\treturn NULL;\n\t}\n\n\treturn cur; /* NULL if not found */\n}\n\n\nstatic vm_object_t *vm_find_object_by_address_userptr_range(manageable_aperture_t *app,\n\t\t\t\t\t\t    const void *address, int is_userptr)\n{\n\tvm_object_t *cur = NULL;\n\trbtree_t *tree = vm_object_tree(app, is_userptr);\n\trbtree_key_t key = rbtree_key((unsigned long)address, 0);\n\trbtree_node_t *rn = rbtree_lookup_nearest(tree, &key, LKP_ALL, RIGHT);\n\trbtree_node_t *ln;\n\tvoid *start;\n\tuint64_t size;\n\n\t/* all nodes might sit on left side of *address*, in this case rn is NULL.\n\t * So pick up the rightest one as rn.\n\t */\n\tif (!rn)\n\t\trn = rbtree_min_max(tree, RIGHT);\n\n\tif (is_userptr) {\n\t\t/* userptr might overlap. Need walk through the tree from right to left as only left nodes\n\t\t * can obtain the *address*\n\t\t */\n\t\tln = rbtree_min_max(tree, LEFT);\n\t} else {\n\t\t/* if key->size is -1, it match the node with start <= address.\n\t\t * if key->size is 0, it match the node with start < address.\n\t\t */\n\t\tkey = rbtree_key((unsigned long)address, -1);\n\t\tln = rbtree_lookup_nearest(tree, &key, LKP_ALL, LEFT);\n\t}\n\tif (!ln)\n\t\treturn NULL;\n\n\twhile (rn) {\n\t\tcur = vm_object_entry(rn, is_userptr);\n\t\tif (is_userptr == 0) {\n\t\t\tstart = cur->start;\n\t\t\tsize = cur->size;\n\t\t} else {\n\t\t\tstart = cur->userptr;\n\t\t\tsize = cur->userptr_size;\n\t\t}\n\n\t\tif (address >= start &&\n\t\t\t\t(uint64_t)address < ((uint64_t)start + size))\n\t\t\tbreak;\n\n\t\tcur = NULL;\n\n\t\tif (ln == rn)\n\t\t\tbreak;\n\n\t\trn = hsakmt_rbtree_prev(tree, rn);\n\t}\n\n\treturn cur; /* NULL if not found */\n}\n\nstatic vm_object_t *vm_find_object_by_address(manageable_aperture_t *app,\n\t\t\t\t\tconst void *address, uint64_t size)\n{\n\treturn vm_find_object_by_address_userptr(app, address, size, 0);\n}\n\nstatic vm_object_t *vm_find_object_by_address_range(manageable_aperture_t *app,\n\t\t\t\t\t\t    const void *address)\n{\n\treturn vm_find_object_by_address_userptr_range(app, address, 0);\n}\n\nstatic vm_object_t *vm_find_object_by_userptr(manageable_aperture_t *app,\n\t\t\t\t\tconst void *address, HSAuint64 size)\n{\n\treturn vm_find_object_by_address_userptr(app, address, size, 1);\n}\n\nstatic vm_object_t *vm_find_object_by_userptr_range(manageable_aperture_t *app,\n\t\t\t\t\t\tconst void *address)\n{\n\treturn vm_find_object_by_address_userptr_range(app, address, 1);\n}\n\nstatic vm_area_t *vm_find(manageable_aperture_t *app, void *address)\n{\n\tvm_area_t *cur = app->vm_ranges;\n\n\t/* Look up the appropriate address range containing the given address */\n\twhile (cur) {\n\t\tif (cur->start <= address && cur->end >= address)\n\t\t\tbreak;\n\t\tcur = cur->next;\n\t};\n\n\treturn cur; /* NULL if not found */\n}\n\nstatic bool aperture_is_valid(void *app_base, void *app_limit)\n{\n\tif (app_base && app_limit && app_base < app_limit)\n\t\treturn true;\n\treturn false;\n}\n\n/* Align size of a VM area\n *\n * Leave at least one guard page after every object to catch\n * out-of-bounds accesses with VM faults.\n */\nstatic uint64_t vm_align_area_size(manageable_aperture_t *app, uint64_t size)\n{\n\treturn size + (uint64_t)app->guard_pages * PAGE_SIZE;\n}\n\n/*\n * Assumes that fmm_mutex is locked on entry.\n */\nstatic void reserved_aperture_release(manageable_aperture_t *app,\n\t\t\t\t      void *address,\n\t\t\t\t      uint64_t MemorySizeInBytes)\n{\n\tvm_area_t *area;\n\tuint64_t SizeOfRegion;\n\n\tMemorySizeInBytes = vm_align_area_size(app, MemorySizeInBytes);\n\n\tarea = vm_find(app, address);\n\tif (!area)\n\t\treturn;\n\n\tSizeOfRegion = VOID_PTRS_SUB(area->end, area->start) + 1;\n\n\t/* check if block is whole region or part of it */\n\tif (SizeOfRegion == MemorySizeInBytes) {\n\t\tvm_remove_area(app, area);\n\t} else if (SizeOfRegion > MemorySizeInBytes) {\n\t\t/* shrink from the start */\n\t\tif (area->start == address)\n\t\t\tarea->start =\n\t\t\t\tVOID_PTR_ADD(area->start, MemorySizeInBytes);\n\t\t/* shrink from the end */\n\t\telse if (VOID_PTRS_SUB(area->end, address) + 1 ==\n\t\t\t\tMemorySizeInBytes)\n\t\t\tarea->end = VOID_PTR_SUB(area->end, MemorySizeInBytes);\n\t\t/* split the area */\n\t\telse\n\t\t\tvm_split_area(app, area, address, MemorySizeInBytes);\n\t}\n\n\tif (app->is_cpu_accessible) {\n\t\tvoid *mmap_ret;\n\n\t\t/* Reset NUMA policy */\n\t\tmbind(address, MemorySizeInBytes, MPOL_DEFAULT, NULL, 0, 0);\n\n\t\t/* Remove any CPU mapping, but keep the address range reserved */\n\t\tmmap_ret = mmap(address, MemorySizeInBytes, PROT_NONE,\n\t\t\tMAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_FIXED,\n\t\t\t-1, 0);\n\t\tif (mmap_ret == MAP_FAILED && errno == ENOMEM) {\n\t\t\t/* When mmap count reaches max_map_count, any mmap will\n\t\t\t * fail. Reduce the count with munmap then map it as\n\t\t\t * NORESERVE immediately.\n\t\t\t */\n\t\t\tif (munmap(address, MemorySizeInBytes) == 0) {\n\t\t\t\t/* After unmapping, try mmap again and handle failure\n\t\t\t\t * */\n\t\t\t\tmmap_ret = mmap(address, MemorySizeInBytes, PROT_NONE,\n\t\t\t\t\t\tMAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_FIXED,\n\t\t\t\t\t\t-1, 0);\n\t\t\t\tif (mmap_ret == MAP_FAILED) {\n\t\t\t\t\t/* Handle mmap failure gracefully, log if needed */\n\t\t\t\t\tpr_err(\"Failed to remap memory after unmap\\n\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Handle munmap failure if needed */\n\t\t\t\tpr_err(\"Failed to unmap memory\\n\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n * returns allocated address or NULL. Assumes, that fmm_mutex is locked\n * on entry.\n */\nstatic void *reserved_aperture_allocate_aligned(manageable_aperture_t *app,\n\t\t\t\t\t\tvoid *address,\n\t\t\t\t\t\tuint64_t MemorySizeInBytes,\n\t\t\t\t\t\tuint64_t align)\n{\n\tuint64_t offset = 0, orig_align = align;\n\tvm_area_t *cur, *next;\n\tvoid *start;\n\n\tif (align < app->align)\n\t\talign = app->align;\n\n\t/* Align big buffers to the next power-of-2 up to huge page\n\t * size for flexible fragment size TLB optimizations\n\t */\n\twhile (align < GPU_HUGE_PAGE_SIZE && MemorySizeInBytes >= (align << 1))\n\t\talign <<= 1;\n\n\t/* If no specific alignment was requested, align the end of\n\t * buffers instead of the start. For fragment optimizations,\n\t * aligning the start or the end achieves the same effective\n\t * optimization. End alignment to the TLB cache line size is\n\t * needed as a workaround for TLB issues on some older GPUs.\n\t */\n\tif (orig_align <= (uint64_t)PAGE_SIZE)\n\t\toffset = align - (MemorySizeInBytes & (align - 1));\n\n\tMemorySizeInBytes = vm_align_area_size(app, MemorySizeInBytes);\n\n\t/* Find a big enough \"hole\" in the address space */\n\tcur = NULL;\n\tnext = app->vm_ranges;\n\tstart = address ? address :\n\t\t(void *)(ALIGN_UP((uint64_t)app->base, align) + offset);\n\twhile (next) {\n\t\tif (next->start > start &&\n\t\t    VOID_PTRS_SUB(next->start, start) >= MemorySizeInBytes)\n\t\t\tbreak;\n\n\t\tcur = next;\n\t\tnext = next->next;\n\t\tif (!address)\n\t\t\tstart = (void *)(ALIGN_UP((uint64_t)cur->end + 1, align) + offset);\n\t}\n\tif (!next && VOID_PTRS_SUB(app->limit, start) + 1 < MemorySizeInBytes)\n\t\t/* No hole found and not enough space after the last area */\n\t\treturn NULL;\n\n\tif (cur && address && address < (void *)ALIGN_UP((uint64_t)cur->end + 1, align))\n\t\t/* Required address is not free or overlaps */\n\t\treturn NULL;\n\n\tif (cur && VOID_PTR_ADD(cur->end, 1) == start) {\n\t\t/* extend existing area */\n\t\tcur->end = VOID_PTR_ADD(start, MemorySizeInBytes-1);\n\t} else {\n\t\tvm_area_t *new_area;\n\t\t/* create a new area between cur and next */\n\t\tnew_area = vm_create_and_init_area(start,\n\t\t\t\tVOID_PTR_ADD(start, (MemorySizeInBytes - 1)));\n\t\tif (!new_area)\n\t\t\treturn NULL;\n\t\tnew_area->next = next;\n\t\tnew_area->prev = cur;\n\t\tif (cur)\n\t\t\tcur->next = new_area;\n\t\telse\n\t\t\tapp->vm_ranges = new_area;\n\t\tif (next)\n\t\t\tnext->prev = new_area;\n\t}\n\n\treturn start;\n}\n\nvoid *hsakmt_mmap_allocate_aligned(int prot, int flags, uint64_t size, uint64_t align,\n\t\t\t    uint64_t guard_size, void *aper_base, void *aper_limit, int fd)\n{\n\tvoid *addr, *aligned_addr, *aligned_end, *mapping_end;\n\tuint64_t aligned_padded_size;\n\n\taligned_padded_size = size + guard_size * 2 + (align - PAGE_SIZE);\n\n\t/* Map memory PROT_NONE to alloc address space only */\n\taddr = mmap(0, aligned_padded_size, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);\n\tif (addr == MAP_FAILED) {\n\t\tpr_err(\"mmap failed: %s\\n\", strerror(errno));\n\t\treturn NULL;\n\t}\n\n\t/* Adjust for alignment and guard pages */\n\taligned_addr = (void *)ALIGN_UP((uint64_t)addr + guard_size, align);\n\tif (aligned_addr < aper_base ||\n\t    VOID_PTR_ADD(aligned_addr, size - 1) > aper_limit) {\n\t\tpr_err(\"mmap returned %p, out of range %p-%p\\n\", aligned_addr,\n\t\t       aper_base, aper_limit);\n\t\tmunmap(addr, aligned_padded_size);\n\t\treturn NULL;\n\t}\n\n\t/* Unmap padding and guard pages */\n\tif (aligned_addr > addr)\n\t\tmunmap(addr, VOID_PTRS_SUB(aligned_addr, addr));\n\n\taligned_end = VOID_PTR_ADD(aligned_addr, size);\n\tmapping_end = VOID_PTR_ADD(addr, aligned_padded_size);\n\tif (mapping_end > aligned_end)\n\t\tmunmap(aligned_end, VOID_PTRS_SUB(mapping_end, aligned_end));\n\n\tif (prot == PROT_NONE)\n\t\treturn aligned_addr;\n\n\t/*  MAP_FIXED to the aligned address with required prot */\n\taddr = mmap(aligned_addr, size, prot, flags | MAP_FIXED, fd, 0);\n\tif (addr == MAP_FAILED) {\n\t\tpr_err(\"mmap failed: %s\\n\", strerror(errno));\n\t\treturn NULL;\n\t}\n\n\treturn addr;\n}\n\nstatic void *mmap_aperture_allocate_aligned(manageable_aperture_t *aper,\n\t\t\t\t\t    void *address,\n\t\t\t\t\t    uint64_t size, uint64_t align)\n{\n\tuint64_t alignment_size = PAGE_SIZE << svm.alignment_order;\n\tuint64_t guard_size;\n\n\tif (!aper->is_cpu_accessible) {\n\t\tpr_err(\"MMap Aperture must be CPU accessible\\n\");\n\t\treturn NULL;\n\t}\n\n\tif (address) {\n\t\tvoid *addr;\n\n#ifdef MAP_FIXED_NOREPLACE\n\t\taddr = mmap(address, size, PROT_NONE,\n\t\t\tMAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_FIXED_NOREPLACE,\n\t\t\t-1, 0);\n#else\n\t\taddr = mmap(address, size, PROT_NONE,\n\t\t\tMAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE,\n\t\t\t-1, 0);\n#endif\n\t\tif (addr == MAP_FAILED) {\n\t\t\tpr_err(\"mmap failed: %s\\n\", strerror(errno));\n\t\t\treturn NULL;\n\t\t}\n\n#ifndef MAP_FIXED_NOREPLACE\n\t\tif (address != addr) {\n\t\t\tpr_err(\"mmap failed to return addr asked\\n\");\n\t\t\tmunmap(addr, size);\n\t\t\treturn NULL;\n\t\t}\n#endif\n\t\treturn addr;\n\t}\n\n\t/* Align big buffers to the next power-of-2. By default, the max alignment\n\t * size is set to 2MB. This can be modified by the env variable\n\t * HSA_MAX_VA_ALIGN. This variable sets the order of the alignment size as\n\t * PAGE_SIZE * 2^HSA_MAX_VA_ALIGN. Setting HSA_MAX_VA_ALIGN = 18 (1GB),\n\t * improves the time for memory allocation and mapping. But it might lose\n\t * performance when GFX access it, specially for big allocations (>3GB).\n\t */\n\twhile (align < alignment_size && size >= (align << 1))\n\t\talign <<= 1;\n\n\t/* Add padding to guarantee proper alignment and leave guard\n\t * pages on both sides\n\t */\n\tguard_size = (uint64_t)aper->guard_pages * PAGE_SIZE;\n\n\treturn hsakmt_mmap_allocate_aligned(PROT_NONE, MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE,\n\t\t\t\t     size, align, guard_size, aper->base, aper->limit, -1);\n}\n\nstatic void mmap_aperture_release(manageable_aperture_t *aper,\n\t\t\t\t  void *addr, uint64_t size)\n{\n\tif (!aper->is_cpu_accessible) {\n\t\tpr_err(\"MMap Aperture must be CPU accessible\\n\");\n\t\treturn;\n\t}\n\n\t/* Reset NUMA policy */\n\tmbind(addr, size, MPOL_DEFAULT, NULL, 0, 0);\n\n\t/* Unmap memory */\n\tmunmap(addr, size);\n}\n\n/* Wrapper functions to call aperture-specific VA management functions */\nstatic void *aperture_allocate_area_aligned(manageable_aperture_t *app,\n\t\t\t\t\t    void *address,\n\t\t\t\t\t    uint64_t MemorySizeInBytes,\n\t\t\t\t\t    uint64_t align)\n{\n\treturn app->ops->allocate_area_aligned(app, address, MemorySizeInBytes, align ? align : app->align);\n}\nstatic void *aperture_allocate_area(manageable_aperture_t *app, void *address,\n\t\t\t\t    uint64_t MemorySizeInBytes)\n{\n\treturn app->ops->allocate_area_aligned(app, address, MemorySizeInBytes, app->align);\n}\nstatic void aperture_release_area(manageable_aperture_t *app, void *address,\n\t\t\t\t  uint64_t MemorySizeInBytes)\n{\n\tapp->ops->release_area(app, address, MemorySizeInBytes);\n}\n\n/* returns 0 on success. Assumes, that fmm_mutex is locked on entry */\nstatic vm_object_t *aperture_allocate_object(manageable_aperture_t *app,\n\t\t\t\t\t     void *new_address,\n\t\t\t\t\t     uint64_t handle,\n\t\t\t\t\t     uint64_t MemorySizeInBytes,\n\t\t\t\t\t     HsaMemFlags mflags)\n{\n\tvm_object_t *new_object;\n\n\t/* Allocate new object */\n\tnew_object = vm_create_and_init_object(new_address,\n\t\t\t\t\t       MemorySizeInBytes,\n\t\t\t\t\t       handle, mflags);\n\tif (!new_object)\n\t\treturn NULL;\n\n\thsakmt_rbtree_insert(&app->tree, &new_object->node);\n\n\treturn new_object;\n}\n\nstatic int32_t gpu_mem_find_by_gpu_id(uint32_t gpu_id)\n{\n\tuint32_t i;\n\n\tfor (i = 0 ; i < gpu_mem_count ; i++)\n\t\tif (gpu_mem[i].gpu_id == gpu_id)\n\t\t\treturn i;\n\n\treturn -1;\n}\n\nstatic int32_t gpu_mem_find_by_node_id(uint32_t node_id)\n{\n\tuint32_t i;\n\n\tfor (i = 0 ; i < gpu_mem_count ; i++)\n\t\tif (gpu_mem[i].node_id == node_id)\n\t\t\treturn i;\n\n\treturn -1;\n}\n\nstatic manageable_aperture_t *fmm_get_aperture(HsaApertureInfo info)\n{\n\tswitch (info.type) {\n\tcase HSA_APERTURE_DGPU:\n\t\treturn svm.dgpu_aperture;\n\tcase HSA_APERTURE_DGPU_ALT:\n\t\treturn svm.dgpu_alt_aperture;\n\tcase HSA_APERTURE_GPUVM:\n\t\treturn &gpu_mem[info.idx].gpuvm_aperture;\n\tcase HSA_APERTURE_CPUVM:\n\t\treturn &cpuvm_aperture;\n\tcase HSA_APERTURE_MEMHANDLE:\n\t\treturn &mem_handle_aperture;\n\tdefault:\n\t\treturn NULL;\n\t}\n}\n\nstatic gpu_mem_t *fmm_is_scratch_aperture(const void *address)\n{\n\tuint32_t i;\n\n\tfor (i = 0; i < gpu_mem_count; i++) {\n\t\tif (gpu_mem[i].gpu_id == NON_VALID_GPU_ID)\n\t\t\tcontinue;\n\n\t\tif ((address >= gpu_mem[i].scratch_physical.base) &&\n\t\t\t(address <= gpu_mem[i].scratch_physical.limit))\n\t\t\treturn &gpu_mem[i];\n\n\t}\n\treturn NULL;\n}\n\nstatic manageable_aperture_t *fmm_find_aperture(const void *address,\n\t\t\t\t\t\tHsaApertureInfo *info)\n{\n\tmanageable_aperture_t *aperture = NULL;\n\tuint32_t i;\n\tHsaApertureInfo _info = { .type = HSA_APERTURE_UNSUPPORTED, .idx = 0};\n\tgpu_mem_t *gpu_mem_ptr = NULL;\n\n\tif ((address >= mem_handle_aperture.base) &&\n\t\t(address <= mem_handle_aperture.limit)){\n\n\t\taperture = &mem_handle_aperture;\n\t\t_info.type = HSA_APERTURE_MEMHANDLE;\n\n\t} else if (hsakmt_is_dgpu) {\n\t\tif (address >= svm.dgpu_aperture->base &&\n\t\t\taddress <= svm.dgpu_aperture->limit) {\n\n\t\t\tgpu_mem_ptr = fmm_is_scratch_aperture(address);\n\t\t\tif (gpu_mem_ptr) {\n\t\t\t\taperture = &gpu_mem_ptr->scratch_physical;\n\t\t\t} else {\n\t\t\t\taperture = svm.dgpu_aperture;\n\t\t\t\t_info.type = HSA_APERTURE_DGPU;\n\t\t\t}\n\t\t} else if (address >= svm.dgpu_alt_aperture->base &&\n\t\t\taddress <= svm.dgpu_alt_aperture->limit) {\n\t\t\taperture = svm.dgpu_alt_aperture;\n\t\t\t_info.type = HSA_APERTURE_DGPU_ALT;\n\t\t} else {\n\t\t\t/* Not in SVM, it can be system memory registered by userptr */\n\t\t\taperture = svm.dgpu_aperture;\n\t\t\t_info.type = HSA_APERTURE_DGPU;\n\t\t}\n\t} else { /* APU */\n\t\tif (address >= svm.dgpu_aperture->base && address <= svm.dgpu_aperture->limit) {\n\t\t\taperture = svm.dgpu_aperture;\n\t\t\t_info.type = HSA_APERTURE_DGPU;\n\t\t} else {\n\t\t\t/* gpuvm_aperture */\n\t\t\tfor (i = 0; i < gpu_mem_count; i++) {\n\t\t\t\tif ((address >= gpu_mem[i].gpuvm_aperture.base) &&\n\t\t\t\t\t(address <= gpu_mem[i].gpuvm_aperture.limit)) {\n\t\t\t\t\taperture = &gpu_mem[i].gpuvm_aperture;\n\t\t\t\t\t_info.type = HSA_APERTURE_GPUVM;\n\t\t\t\t\t_info.idx = i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!aperture) {\n\t\t\t/* Not in GPUVM */\n\t\t\taperture = &cpuvm_aperture;\n\t\t\t_info.type = HSA_APERTURE_CPUVM;\n\t\t}\n\t}\n\n\tif (info)\n\t\t*info = _info;\n\n\treturn aperture;\n}\n\nstatic HsaMemFlags fmm_translate_ioc_to_hsa_flags(uint32_t ioc_flags)\n{\n\tHsaMemFlags mflags = {0};\n\n\tif (!(ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE))\n\t\tmflags.ui32.ReadOnly = 1;\n\tif (!(ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_COHERENT))\n\t\tmflags.ui32.CoarseGrain = 1;\n\tif (ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT)\n\t\tmflags.ui32.ExtendedCoherent = 1;\n\tif (ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC)\n\t\tmflags.ui32.HostAccess = 1;\n\treturn mflags;\n}\n\nstatic HSAKMT_STATUS fmm_register_mem_svm_api(void *address,\n\t\t\t\t\t      uint64_t size,\n\t\t\t\t\t      bool coarse_grain,\n\t\t\t\t\t      bool ext_coherent)\n{\n\tstruct kfd_ioctl_svm_args *args;\n\tsize_t s_attr;\n\tHSAuint32 page_offset = (HSAuint64)address & (PAGE_SIZE-1);\n\tHSAuint64 aligned_addr = (HSAuint64)address - page_offset;\n\tHSAuint64 aligned_size = PAGE_ALIGN_UP(page_offset + size);\n\n\tif (!g_first_gpu_mem)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\ts_attr = 2 * sizeof(struct kfd_ioctl_svm_attribute);\n\targs = alloca(sizeof(*args) + s_attr);\n\targs->start_addr = aligned_addr;\n\targs->size = aligned_size;\n\targs->op = KFD_IOCTL_SVM_OP_SET_ATTR;\n\targs->nattr = 2;\n\targs->attrs[0].type = coarse_grain ?\n\t\t\t      HSA_SVM_ATTR_CLR_FLAGS : HSA_SVM_ATTR_SET_FLAGS;\n\targs->attrs[0].value = HSA_SVM_FLAG_COHERENT;\n\targs->attrs[1].type = ext_coherent ? HSA_SVM_ATTR_SET_FLAGS : HSA_SVM_ATTR_CLR_FLAGS ;\n\targs->attrs[1].value = HSA_SVM_FLAG_EXT_COHERENT;\n\tpr_debug(\"Registering to SVM %p size: %ld\\n\", (void*)aligned_addr,\n\t\t aligned_size);\n\t/* Driver does one copy_from_user, with extra attrs size */\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SVM + (s_attr << _IOC_SIZESHIFT), args)) {\n\t\tpr_debug(\"op set range attrs failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS fmm_map_mem_svm_api(void *address,\n\t\t\t\t\t      uint64_t size,\n\t\t\t\t\t      uint32_t *nodes_to_map,\n\t\t\t\t\t      uint32_t nodes_array_size)\n{\n\tstruct kfd_ioctl_svm_args *args;\n\tsize_t s_attr;\n\tuint32_t i, nattr;\n\n\tif (!g_first_gpu_mem)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tnattr = nodes_array_size;\n\ts_attr = sizeof(struct kfd_ioctl_svm_attribute) * nattr;\n\targs = alloca(sizeof(*args) + s_attr);\n\n\targs->start_addr = (uint64_t)address;\n\targs->size = size;\n\targs->op = KFD_IOCTL_SVM_OP_SET_ATTR;\n\targs->nattr = nattr;\n\tfor (i = 0; i < nodes_array_size; i++) {\n\t\targs->attrs[i].type = HSA_SVM_ATTR_ACCESS_IN_PLACE;\n\t\targs->attrs[i].value = nodes_to_map[i];\n\t}\n\t/* Driver does one copy_from_user, with extra attrs size */\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SVM + (s_attr << _IOC_SIZESHIFT), args)) {\n\t\tpr_debug(\"op set range attrs failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* After allocating the memory, return the vm_object created for this memory.\n * Return NULL if any failure.\n */\nstatic vm_object_t *fmm_allocate_memory_object(uint32_t gpu_id, void *mem,\n\t\t\t\t\t\tuint64_t MemorySizeInBytes,\n\t\t\t\t\t\tmanageable_aperture_t *aperture,\n\t\t\t\t\t\tuint64_t *mmap_offset,\n\t\t\t\t\t\tuint32_t ioc_flags)\n{\n\tstruct kfd_ioctl_alloc_memory_of_gpu_args args = {0};\n\tstruct kfd_ioctl_free_memory_of_gpu_args free_args = {0};\n\tvm_object_t *vm_obj = NULL;\n\tHsaMemFlags mflags;\n\tuint64_t offset = 0, total_size, size;\n\n\tif (!mem)\n\t\treturn NULL;\n\n\t/* Allocate memory from amdkfd */\n\targs.gpu_id = gpu_id;\n\n\targs.flags = ioc_flags |\n\t\tKFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE;\n\targs.va_addr = (uint64_t)mem;\n\tif (!hsakmt_is_dgpu &&\n\t    (ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM))\n\t\targs.va_addr = VOID_PTRS_SUB(mem, aperture->base);\n\n\t/* if allocate vram-only, use an invalid VA */\n\tif (aperture == &mem_handle_aperture)\n\t\targs.va_addr = 0;\n\n\ttotal_size = 0;\n\t/* Split to multiple buffers, if size is too big */\n\tif (ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {\n\t\tsize = MemorySizeInBytes < BIGGEST_SINGLE_BUF_SIZE ?\n\t\t\tMemorySizeInBytes : BIGGEST_SINGLE_BUF_SIZE;\n\t\toffset = *mmap_offset;\n\t\targs.mmap_offset = *mmap_offset;\n\t} else {\n\t\tsize = MemorySizeInBytes;\n\t}\n\n\tmflags = fmm_translate_ioc_to_hsa_flags(ioc_flags);\n\n\tdo {\n\t\targs.size = size;\n\n\t\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_ALLOC_MEMORY_OF_GPU, &args))\n\t\t\tgoto err_hsakmt_ioctl_failed;\n\n\t\t/* Allocate object */\n\t\tif (!vm_obj) {\n\t\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\t\tvm_obj = aperture_allocate_object(aperture, mem, args.handle,\n\t\t\t\t\tMemorySizeInBytes, mflags);\n\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\tif (!vm_obj)\n\t\t\t\tgoto err_object_allocation_failed;\n\n\t\t\tif (mmap_offset)\n\t\t\t\t*mmap_offset = args.mmap_offset;\n\t\t} else {\n\t\t\tvm_obj->handles[vm_obj->handle_num++] = args.handle;\n\t\t}\n\n\t\targs.va_addr += size;\n\t\toffset += size;\n\n\t\tif (ioc_flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR)\n\t\t\targs.mmap_offset = offset;\n\n\t\ttotal_size += size;\n\t\tif (total_size + BIGGEST_SINGLE_BUF_SIZE > MemorySizeInBytes)\n\t\t\tsize = MemorySizeInBytes - total_size;\n\t\telse\n\t\t\tsize = BIGGEST_SINGLE_BUF_SIZE;\n\t} while (total_size < MemorySizeInBytes);\n\n\treturn vm_obj;\n\nerr_object_allocation_failed:\n\tfree_args.handle = args.handle;\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_FREE_MEMORY_OF_GPU, &free_args)) {\n\t\tpr_err(\"Failed to free GPU memory with handle: 0x%llx\\n\", free_args.handle);\n\t}\nerr_hsakmt_ioctl_failed:\n\tif (vm_obj) {\n\t\tdo {\n\t\t\tfree_args.handle = vm_obj->handles[--vm_obj->handle_num];\n\t\t\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_FREE_MEMORY_OF_GPU, &free_args))\n\t\t\t\tpr_err(\"Failed to free GPU memory with handle: 0x%llx\\n\", free_args.handle);\n\t\t} while (vm_obj->handle_num);\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\tvm_remove_object(aperture, vm_obj);\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t}\n\treturn NULL;\n}\n\n#ifdef DEBUG_PRINT_APERTURE\nstatic void aperture_print(aperture_t *app)\n{\n\tpr_info(\"\\t Base: %p\\n\", app->base);\n\tpr_info(\"\\t Limit: %p\\n\", app->limit);\n}\n\nstatic void manageable_aperture_print(manageable_aperture_t *app)\n{\n\tvm_area_t *cur = app->vm_ranges;\n\trbtree_node_t *n = rbtree_node_any(&app->tree, LEFT);\n\tvm_object_t *object;\n\n\tpr_info(\"\\t Base: %p\\n\", app->base);\n\tpr_info(\"\\t Limit: %p\\n\", app->limit);\n\tpr_info(\"\\t Ranges:\\n\");\n\twhile (cur) {\n\t\tpr_info(\"\\t\\t Range [%p - %p]\\n\", cur->start, cur->end);\n\t\tcur = cur->next;\n\t};\n\tpr_info(\"\\t Objects:\\n\");\n\twhile (n) {\n\t\tobject = vm_object_entry(n, 0);\n\t\tpr_info(\"\\t\\t Object [%p - %\" PRIu64 \"]\\n\",\n\t\t\t\tobject->start, object->size);\n\t\tn = hsakmt_rbtree_next(&app->tree, n);\n\t}\n}\n\nvoid hsakmt_fmm_print(uint32_t gpu_id)\n{\n\tint32_t gpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\n\tif (gpu_mem_id >= 0) { /* Found */\n\t\tpr_info(\"LDS aperture:\\n\");\n\t\taperture_print(&gpu_mem[gpu_mem_id].lds_aperture);\n\t\tpr_info(\"GPUVM aperture:\\n\");\n\t\tmanageable_aperture_print(&gpu_mem[gpu_mem_id].gpuvm_aperture);\n\t\tpr_info(\"Scratch aperture:\\n\");\n\t\taperture_print(&gpu_mem[gpu_mem_id].scratch_aperture);\n\t\tpr_info(\"Scratch backing memory:\\n\");\n\t\tmanageable_aperture_print(&gpu_mem[gpu_mem_id].scratch_physical);\n\t}\n\n\tpr_info(\"dGPU aperture:\\n\");\n\tmanageable_aperture_print(svm.dgpu_aperture);\n\tpr_info(\"dGPU alt aperture:\\n\");\n\tif (svm.dgpu_aperture == svm.dgpu_alt_aperture)\n\t\tpr_info(\"\\t Alias of dGPU aperture\\n\");\n\telse\n\t\tmanageable_aperture_print(svm.dgpu_alt_aperture);\n}\n#else\nvoid hsakmt_fmm_print(uint32_t gpu_id)\n{\n}\n#endif\n\n/* vm_find_object - Find a VM object in any aperture\n *\n * @addr: VM address of the object\n * @size: size of the object, 0 means \"don't care\",\n *        UINT64_MAX means addr can match any address within the object\n * @out_aper: Aperture where the object was found\n *\n * Returns a pointer to the object if found, NULL otherwise. If an\n * object is found, this function returns with the\n * (*out_aper)->fmm_mutex locked.\n */\nstatic vm_object_t *vm_find_object(const void *addr, uint64_t size,\n\t\t\t\t   manageable_aperture_t **out_aper)\n{\n\tmanageable_aperture_t *aper = NULL;\n\tbool range = (size == UINT64_MAX);\n\tbool userptr = false;\n\tvm_object_t *obj = NULL;\n\tuint32_t i;\n\n\tfor (i = 0; i < gpu_mem_count; i++)\n\t\tif (gpu_mem[i].gpu_id != NON_VALID_GPU_ID &&\n\t\t    addr >= gpu_mem[i].gpuvm_aperture.base &&\n\t\t    addr <= gpu_mem[i].gpuvm_aperture.limit) {\n\t\t\taper = &gpu_mem[i].gpuvm_aperture;\n\t\t\tbreak;\n\t\t}\n\n\tif (!aper) {\n\t\tif ((addr >= mem_handle_aperture.base) &&\n\t\t\t (addr <= mem_handle_aperture.limit)){\n\t\t\t aper = &mem_handle_aperture;\n\t\t}\n\t}\n\n\tif (!aper) {\n\t\tif (!svm.dgpu_aperture)\n\t\t\tgoto no_svm;\n\n\t\tif ((addr >= svm.dgpu_aperture->base) &&\n\t\t    (addr <= svm.dgpu_aperture->limit))\n\t\t\taper = svm.dgpu_aperture;\n\t\telse if ((addr >= svm.dgpu_alt_aperture->base) &&\n\t\t\t (addr <= svm.dgpu_alt_aperture->limit))\n\t\t\taper = svm.dgpu_alt_aperture;\n\t\telse {\n\t\t\taper = svm.dgpu_aperture;\n\t\t\tuserptr = true;\n\t\t}\n\t}\n\n\tpthread_mutex_lock(&aper->fmm_mutex);\n\tif (range) {\n\t\t/* mmap_apertures can have userptrs in them. Try to\n\t\t * look up addresses as userptrs first to sort out any\n\t\t * ambiguity of multiple overlapping mappings at\n\t\t * different GPU addresses.\n\t\t */\n\t\tif (userptr || aper->ops == &mmap_aperture_ops)\n\t\t\tobj = vm_find_object_by_userptr_range(aper, addr);\n\t\tif (!obj && !userptr)\n\t\t\tobj = vm_find_object_by_address_range(aper, addr);\n\t} else {\n\t\tif (userptr || aper->ops == &mmap_aperture_ops)\n\t\t\tobj = vm_find_object_by_userptr(aper, addr, size);\n\t\tif (!obj && !userptr) {\n\t\t\tlong page_offset = (long)addr & (PAGE_SIZE-1);\n\t\t\tconst void *page_addr = (const uint8_t *)addr - page_offset;\n\n\t\t\tobj = vm_find_object_by_address(aper, page_addr, 0);\n\t\t\t/* If we find a userptr here, it's a match on\n\t\t\t * the aligned GPU address. Make sure that the\n\t\t\t * page offset and size match too.\n\t\t\t */\n\t\t\tif (obj && obj->userptr &&\n\t\t\t    (((long)obj->userptr & (PAGE_SIZE - 1)) != page_offset ||\n\t\t\t     (size && size != obj->userptr_size)))\n\t\t\t\tobj = NULL;\n\t\t}\n\t}\n\nno_svm:\n\tif (!obj && !hsakmt_is_dgpu) {\n\t\t/* On APUs try finding it in the CPUVM aperture */\n\t\tif (aper)\n\t\t\tpthread_mutex_unlock(&aper->fmm_mutex);\n\n\t\taper = &cpuvm_aperture;\n\n\t\tpthread_mutex_lock(&aper->fmm_mutex);\n\t\tif (range)\n\t\t\tobj = vm_find_object_by_address_range(aper, addr);\n\t\telse\n\t\t\tobj = vm_find_object_by_address(aper, addr, 0);\n\t}\n\n\tif (obj) {\n\t\t*out_aper = aper;\n\t\treturn obj;\n\t}\n\n\tif (aper)\n\t\tpthread_mutex_unlock(&aper->fmm_mutex);\n\treturn NULL;\n}\n\nstatic HSAuint8 fmm_check_user_memory(const void *addr, HSAuint64 size)\n{\n\tvolatile const HSAuint8 *ptr = addr;\n\tvolatile const HSAuint8 *end = ptr + size;\n\tHSAuint8 sum = 0;\n\n\t/* Access every page in the buffer to make sure the mapping is\n\t * valid. If it's not, it will die with a segfault that's easy\n\t * to debug.\n\t */\n\tfor (; ptr < end; ptr = (void *)PAGE_ALIGN_UP(ptr + 1))\n\t\tsum += *ptr;\n\n\treturn sum;\n}\n\nstatic void fmm_release_scratch(uint32_t gpu_id)\n{\n\tint32_t gpu_mem_id;\n\tuint64_t size;\n\tvm_object_t *obj;\n\tmanageable_aperture_t *aperture;\n\trbtree_node_t *n;\n\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn;\n\n\taperture = &gpu_mem[gpu_mem_id].scratch_physical;\n\n\tsize = VOID_PTRS_SUB(aperture->limit, aperture->base) + 1;\n\n\tif (hsakmt_is_dgpu) {\n\t\t/* unmap and remove all remaining objects */\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\twhile ((n = rbtree_node_any(&aperture->tree, MID))) {\n\t\t\tobj = vm_object_entry(n, 0);\n\n\t\t\tvoid *obj_addr = obj->start;\n\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t\t\t_fmm_unmap_from_gpu_scratch(gpu_id, aperture, obj_addr);\n\n\t\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\t}\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t\t/* release address space */\n\t\tpthread_mutex_lock(&svm.dgpu_aperture->fmm_mutex);\n\t\taperture_release_area(svm.dgpu_aperture,\n\t\t\t\t      gpu_mem[gpu_mem_id].scratch_physical.base,\n\t\t\t\t      size);\n\t\tpthread_mutex_unlock(&svm.dgpu_aperture->fmm_mutex);\n\t} else\n\t\t/* release address space */\n\t\tmunmap(gpu_mem[gpu_mem_id].scratch_physical.base, size);\n\n\t/* invalidate scratch backing aperture */\n\tgpu_mem[gpu_mem_id].scratch_physical.base = NULL;\n\tgpu_mem[gpu_mem_id].scratch_physical.limit = NULL;\n}\n\nstatic uint32_t fmm_translate_hsa_to_ioc_flags(HsaMemFlags flags)\n{\n\tuint32_t ioc_flags = 0;\n\n\tif (flags.ui32.AQLQueueMemory)\n\t\tioc_flags |= (KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM |\n\t\t\t      KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED);\n\tif (!flags.ui32.ReadOnly)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE;\n\tif (flags.ui32.ExecuteAccess)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE;\n\treturn ioc_flags;\n}\n\n#define SCRATCH_ALIGN 0x10000\nvoid *hsakmt_fmm_allocate_scratch(uint32_t gpu_id, void *address, uint64_t MemorySizeInBytes)\n{\n\tmanageable_aperture_t *aperture_phy;\n\tstruct kfd_ioctl_set_scratch_backing_va_args args = {0};\n\tint32_t gpu_mem_id;\n\tvoid *mem = NULL;\n\tuint64_t aligned_size = ALIGN_UP(MemorySizeInBytes, SCRATCH_ALIGN);\n\n\t/* Retrieve gpu_mem id according to gpu_id */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn NULL;\n\n\taperture_phy = &gpu_mem[gpu_mem_id].scratch_physical;\n\tif (aperture_phy->base || aperture_phy->limit)\n\t\t/* Scratch was already allocated for this GPU */\n\t\treturn NULL;\n\n\t/* Allocate address space for scratch backing, 64KB aligned */\n\tif (hsakmt_is_dgpu) {\n\t\tpthread_mutex_lock(&svm.dgpu_aperture->fmm_mutex);\n\t\tmem = aperture_allocate_area_aligned(\n\t\t\tsvm.dgpu_aperture, address,\n\t\t\taligned_size, SCRATCH_ALIGN);\n\t\tpthread_mutex_unlock(&svm.dgpu_aperture->fmm_mutex);\n\t} else {\n\t\tif (address)\n\t\t\treturn NULL;\n\n\t\tmem = hsakmt_mmap_allocate_aligned(PROT_READ | PROT_WRITE,\n\t\t\t\t\t    MAP_PRIVATE | MAP_ANONYMOUS,\n\t\t\t\t\t    aligned_size, SCRATCH_ALIGN, 0,\n\t\t\t\t\t    0, (void *)LONG_MAX, -1);\n\t}\n\n\t/* Remember scratch backing aperture for later */\n\taperture_phy->base = mem;\n\taperture_phy->limit = VOID_PTR_ADD(mem, aligned_size-1);\n\taperture_phy->is_cpu_accessible = true;\n\n\t/* Program SH_HIDDEN_PRIVATE_BASE */\n\targs.gpu_id = gpu_id;\n\targs.va_addr = ((uint64_t)mem) >> 16;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_SCRATCH_BACKING_VA, &args)) {\n\t\tfmm_release_scratch(gpu_id);\n\t\treturn NULL;\n\t}\n\n\treturn mem;\n}\n\nstatic void *__fmm_allocate_device(uint32_t gpu_id, void *address, uint64_t MemorySizeInBytes,\n\t\tmanageable_aperture_t *aperture, uint64_t *mmap_offset,\n\t\tuint32_t ioc_flags, uint64_t alignment, vm_object_t **vm_obj)\n{\n\tvoid *mem = NULL;\n\tvm_object_t *obj;\n\n\t/* Check that aperture is properly initialized/supported */\n\tif (!aperture_is_valid(aperture->base, aperture->limit))\n\t\treturn NULL;\n\n\t/* Allocate address space */\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tmem = aperture_allocate_area_aligned(aperture, address, MemorySizeInBytes, alignment);\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\tif (!mem)\n\t\treturn NULL;\n\t/*\n\t * Now that we have the area reserved, allocate memory in the device\n\t * itself\n\t */\n\tobj = fmm_allocate_memory_object(gpu_id, mem,\n\t\t\tMemorySizeInBytes, aperture, mmap_offset, ioc_flags);\n\tif (!obj) {\n\t\t/*\n\t\t * allocation of memory in device failed.\n\t\t * Release region in aperture\n\t\t */\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\taperture_release_area(aperture, mem, MemorySizeInBytes);\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t\t/* Assign NULL to mem to indicate failure to calling function */\n\t\tmem = NULL;\n\t}\n\tif (vm_obj)\n\t\t*vm_obj = obj;\n\n\treturn mem;\n}\n\nstatic void *fmm_map_to_cpu(void *mem, uint64_t size, bool host_access,\n\t\t\t    int fd, uint64_t mmap_offset) {\n\tint flag = MAP_SHARED | MAP_FIXED;\n\tint prot = host_access ? PROT_READ | PROT_WRITE : PROT_NONE;\n\tvoid *ret = mmap(mem, size, prot, flag, fd, mmap_offset);\n\n\tif (ret != MAP_FAILED)\n\t\t/* This madvise() call is needed to avoid additional references\n\t\t * to mapped BOs in child processes that can prevent freeing\n\t\t * memory in the parent process and lead to out-of-memory\n\t\t * conditions.\n\t\t */\n\t\tmadvise(mem, size, MADV_DONTFORK);\n\n\treturn ret;\n}\n\nstatic void *fmm_allocate_va(uint32_t gpu_id, void *address, uint64_t size,\n\t\t\tmanageable_aperture_t *aperture, uint64_t alignment, HsaMemFlags mflags)\n{\n\tvoid *mem = NULL;\n\tvm_object_t *vm_obj = NULL;\n\n\t/* Check aperture is properly initialized/supported */\n\tif (!aperture_is_valid(aperture->base, aperture->limit))\n\t\treturn NULL;\n\n\t/* Allocate address space */\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tmem = aperture_allocate_area_aligned(aperture, address, size, alignment);\n\n\tif (mem) {\n\t\t/* Assign handle 0 to vm_obj since no memory allocated yet */\n\t\tvm_obj = aperture_allocate_object(aperture, mem, 0, size, mflags);\n\t\tif (!vm_obj) {\n\t\t\taperture_release_area(aperture, mem, size);\n\t\t\tmem = NULL;\n\t\t}\n\t\t/* Set node_id to 0 for OnlyAddress */\n\t\tvm_obj->node_id = 0;\n\t}\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\treturn mem;\n}\n\n/* use udmabuf driver to allocate buf */\nstatic void* udmabuf_allocation(uint32_t gpu_id, uint32_t node_id, uint64_t size,\n                               manageable_aperture_t *aperture, uint64_t alignment,\n                               HsaMemFlags mflags, vm_object_t** vm_obj)\n{\n\tstruct kfd_ioctl_import_dmabuf_args importArgs = {0};\n\tint memfd, dmabuf_fd;\n\tlong long node_size, free_size;\n\tstruct udmabuf_create create;\n\tuint64_t alignment_size;\n\tuint32_t numa_node_id;\n\tuint64_t guard_size;\n\tvoid *mem;\n\tint ret;\n\n\tdmabuf_fd = -1;\n\tmemfd = -1;\n\n\t*vm_obj = NULL;\n\n\tmemfd = memfd_create(\"thunk_memfd\", MFD_ALLOW_SEALING);\n\tif (memfd == -1) {\n\t\tpr_debug(\"running kernel does not support memfd\\n\");\n\t\treturn NULL;\n\t}\n\n\tif (ftruncate(memfd, size) == -1) {\n\t\tpr_debug(\"ftruncate fail\\n\");\n\t\tgoto error_release_memfd;\n\t}\n\tpr_debug(\"PID: %jd; fd: %d; /proc/%jd/fd/%d\\n\",\n               (intmax_t) getpid(), memfd, (intmax_t) getpid(), memfd);\n\n\tif (fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW) < 0) {\n\t\tpr_debug(\"fcntl fail %s\\n\", strerror(errno));\n\t\tgoto error_release_memfd;\n\t}\n\n\talignment_size = PAGE_SIZE << svm.alignment_order;\n\talignment = alignment ? alignment : aperture->align;\n\twhile (alignment < alignment_size && size >= (alignment << 1))\n\t\talignment <<= 1;\n\n\tguard_size = (uint64_t)aperture->guard_pages * PAGE_SIZE;\n\n\tmem = hsakmt_mmap_allocate_aligned(PROT_WRITE | PROT_READ, MAP_NORESERVE | MAP_SHARED,\n\t\t\t\t\t  size, alignment, guard_size, aperture->base, aperture->limit, memfd);\n\tif (!mem)\n\t\tgoto error_release_memfd;\n\n\t/* set madvise flags to HUGEPAGE if allocate more than 2MB */\n\tif (size >= (2 * 1024 * 1024))\n\t\tmadvise(mem, size, MADV_HUGEPAGE);\n\n\t/* always bind to numa node */\n\tmflags.ui32.NoSubstitute = 1;\n\t/* Bind to NUMA node */\n\t/* node_id is gpu id, get closed numa id */\n\tnuma_node_id = hsakmt_get_direct_link_cpu(node_id);\n\tif (bind_mem_to_numa(numa_node_id, mem, size, mflags))\n\t\tgoto error_release_aperture;\n\n\tnode_size = numa_node_size64(numa_node_id, &free_size);\n\tpr_debug(\"udmabuf_allocation: numa_node_id %d, node_size %lld, free_size %lld\\n\",\n\t\tnuma_node_id, node_size, free_size);\n\t/* compare free size at numa_node_id with size */\n\tif ((uint64_t)free_size < size) {\n\t\tpr_debug(\"udmabuf_allocation: has no enough ram on numa_node_id %d, node_size %lld, free_size %lld\\n\",\n\t\t\tnuma_node_id, node_size, free_size);\n\t\tgoto error_release_aperture;\n\t}\n\n\tcreate.memfd = memfd;\n\tcreate.flags = UDMABUF_FLAGS_CLOEXEC;\n\tcreate.offset = 0;\n\tcreate.size = size;\n\tdmabuf_fd = ioctl(hsakmt_udmabuf_dev_fd, UDMABUF_CREATE, &create);\n\n\tif (dmabuf_fd < 0) {\n\t\tpr_debug(\"ioctl UDMABUF_CREATE failed\\n\");\n\t\tgoto error_release_aperture;\n\t}\n\n\timportArgs.va_addr = (uint64_t)mem;\n\timportArgs.gpu_id = gpu_id;\n\timportArgs.dmabuf_fd = dmabuf_fd;\n\n\tret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_IMPORT_DMABUF, (void *)&importArgs);\n\tif (ret) {\n\t\tpr_debug(\"ioctl AMDKFD_IOC_IMPORT_DMABUF failed\\n, ret 0x%x\", ret);\n\t\tgoto error_release_dmabuf;\n\t}\n\n\t/* Allocate object */\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t*vm_obj = aperture_allocate_object(aperture, mem, importArgs.handle,\n                                          size, mflags);\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\tif (*vm_obj == NULL)\n\t\tgoto error_release_dmabuf;\n\n\t/* after import udmabuf into kfd driver close dmabuf_fd\n\t * as kfd driver holds the dmabuf\n\t */\n\tclose(dmabuf_fd);\n\tclose(memfd);\n\n\treturn mem;\n\nerror_release_dmabuf:\n\tclose(dmabuf_fd);\nerror_release_aperture:\n\taperture_release_area(aperture, mem, size);\nerror_release_memfd:\n\tclose(memfd);\n\n\treturn NULL;\n}\n\nvoid *hsakmt_fmm_allocate_device(uint32_t gpu_id, uint32_t node_id, void *address,\n\t\t\t  uint64_t MemorySizeInBytes, uint64_t alignment, HsaMemFlags mflags)\n{\n\tmanageable_aperture_t *aperture;\n\tint32_t gpu_mem_id;\n\tuint32_t ioc_flags = KFD_IOC_ALLOC_MEM_FLAGS_VRAM;\n\tuint64_t size, mmap_offset;\n\tvoid *mem;\n\tvm_object_t *vm_obj = NULL;\n\n\t/* Retrieve gpu_mem id according to gpu_id */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn NULL;\n\n\tsize = MemorySizeInBytes;\n\n\tif (mflags.ui32.HostAccess)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC;\n\n\tioc_flags |= fmm_translate_hsa_to_ioc_flags(mflags);\n\n\tif (hsakmt_topology_is_svm_needed(gpu_mem[gpu_mem_id].EngineId)) {\n\t\taperture = svm.dgpu_aperture;\n\t\tif (mflags.ui32.AQLQueueMemory)\n\t\t\tsize = MemorySizeInBytes * 2;\n\t} else {\n\t\taperture = &gpu_mem[gpu_mem_id].gpuvm_aperture;\n\t}\n\n\t/* special case for va allocation without vram alloc */\n\tif (mflags.ui32.OnlyAddress)\n\t\treturn fmm_allocate_va(gpu_id, address, size, aperture, alignment, mflags);\n\n\t/* special case for vram allocation without addr */\n\tif(mflags.ui32.NoAddress)\n\t\taperture = &mem_handle_aperture;\n\n\tif (!mflags.ui32.CoarseGrain || svm.disable_cache)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_COHERENT;\n\n\tif (mflags.ui32.Uncached || svm.disable_cache)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED;\n\n\tif (mflags.ui32.ExtendedCoherent)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT;\n\n\tif (mflags.ui32.Contiguous)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS_BEST_EFFORT;\n\n\tmem = NULL;\n\tif (hsakmt_udmabuf_dev_fd > 0 && aperture == svm.dgpu_aperture && !hsakmt_is_dgpu\n\t\t && aperture->ops == &mmap_aperture_ops) {\n\t\tmem  = udmabuf_allocation(gpu_id, node_id, size, aperture, alignment,\n                                        mflags, &vm_obj);\n\t\tpr_debug(\"udmabuf_allocation mem %p\\n\", mem);\n\t\tif (!mem)\n\t\t\tpr_debug(\"udmabuf_allocation allocation fail\\n\");\n\t}\n\n\t/* env HSA_USE_UDMABUF not set, or not apu, or cannot use udmabuf,\n\t * fall back to use device driver to allocate memory\n\t */\n\tif (!mem) {\n\t\tmem = __fmm_allocate_device(gpu_id, address, size, aperture, &mmap_offset,\n\t\t\t\t\t   ioc_flags, alignment, &vm_obj);\n\n\t\t/* if alloc vram-only not mmap to cpu vm since no va */\n\t\tif (mem && !mflags.ui32.NoAddress) {\n\t\t\tvoid *ret = fmm_map_to_cpu(mem, MemorySizeInBytes,\n\t\t\t\t\t   mflags.ui32.HostAccess,\n\t\t\t\t\t   gpu_mem[gpu_mem_id].drm_render_fd,\n\t\t\t\t\t   mmap_offset);\n\n\t\t\tif (ret == MAP_FAILED) {\n\t\t\t\t__fmm_release(vm_obj, aperture);\n\t\t\t\treturn NULL;\n\t\t\t}\n#ifdef SANITIZER_AMDGPU\n\t\t\tif (vm_obj) {\n\t\t\t\tvm_obj->mmap_flags = mflags.ui32.HostAccess ? PROT_READ | PROT_WRITE : PROT_NONE;\n\t\t\t\tvm_obj->mmap_fd = gpu_mem[gpu_mem_id].drm_render_fd;\n\t\t\t\tvm_obj->mmap_offset = mmap_offset;\n\t\t\t}\n#endif\n\t\t}\n\t}\n\n\tif (mem && vm_obj) {\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\t/* Store memory allocation flags, not ioc flags */\n\t\t vm_obj->mflags = mflags;\n\t\t hsakmt_gpuid_to_nodeid(gpu_id, &vm_obj->node_id);\n\t\t pthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t}\n\n\treturn mem;\n}\n\nvoid *hsakmt_fmm_allocate_doorbell(uint32_t gpu_id, uint64_t MemorySizeInBytes,\n\t\t\t    uint64_t doorbell_mmap_offset)\n{\n\tmanageable_aperture_t *aperture;\n\tint32_t gpu_mem_id;\n\tuint32_t ioc_flags;\n\tvoid *mem;\n\tvm_object_t *vm_obj = NULL;\n\n\t/* Retrieve gpu_mem id according to gpu_id */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn NULL;\n\n\t/* Use fine-grained aperture */\n\taperture = svm.dgpu_alt_aperture;\n\tioc_flags = KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |\n\t\t    KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE |\n\t\t    KFD_IOC_ALLOC_MEM_FLAGS_COHERENT;\n\n\tmem = __fmm_allocate_device(gpu_id, NULL, MemorySizeInBytes, aperture, NULL,\n\t\t\t\t    ioc_flags, 0, &vm_obj);\n\n\tif (mem && vm_obj) {\n\t\tHsaMemFlags mflags;\n\n\t\t/* Cook up some flags for storing in the VM object */\n\t\tmflags.Value = 0;\n\t\tmflags.ui32.NonPaged = 1;\n\t\tmflags.ui32.HostAccess = 1;\n\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\tvm_obj->mflags = mflags;\n\t\thsakmt_gpuid_to_nodeid(gpu_id, &vm_obj->node_id);\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t}\n\n\tif (mem) {\n\t\tvoid *ret = mmap(mem, MemorySizeInBytes,\n\t\t\t\t PROT_READ | PROT_WRITE,\n\t\t\t\t MAP_SHARED | MAP_FIXED, hsakmt_kfd_fd,\n\t\t\t\t doorbell_mmap_offset);\n\t\tif (ret == MAP_FAILED) {\n\t\t\t__fmm_release(vm_obj, aperture);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\treturn mem;\n}\n\nstatic void *fmm_allocate_host_cpu(void *address, uint64_t MemorySizeInBytes,\n\t\t\t\tHsaMemFlags mflags)\n{\n\tvoid *mem = NULL;\n\tvm_object_t *vm_obj;\n\tint mmap_prot = PROT_READ;\n\n\tif (address)\n\t\treturn NULL;\n\n\tif (mflags.ui32.ExecuteAccess)\n\t\tmmap_prot |= PROT_EXEC;\n\n\tif (!mflags.ui32.ReadOnly)\n\t\tmmap_prot |= PROT_WRITE;\n\n\t/* mmap will return a pointer with alignment equal to\n\t * sysconf(_SC_PAGESIZE).\n\t */\n\tmem = mmap(NULL, MemorySizeInBytes, mmap_prot,\n\t\t\tMAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n\n\tif (mem == MAP_FAILED)\n\t\treturn NULL;\n\n\tpthread_mutex_lock(&cpuvm_aperture.fmm_mutex);\n\tvm_obj = aperture_allocate_object(&cpuvm_aperture, mem, 0,\n\t\t\t\t      MemorySizeInBytes, mflags);\n\tif (vm_obj)\n\t\tvm_obj->node_id = 0; /* APU systems only have one CPU node */\n\tpthread_mutex_unlock(&cpuvm_aperture.fmm_mutex);\n\n\treturn mem;\n}\n\nstatic int bind_mem_to_numa(uint32_t numa_node_id, void *mem,\n\t\t\t    uint64_t SizeInBytes, HsaMemFlags mflags)\n{\n\tint mode = MPOL_F_STATIC_NODES;\n\tstruct bitmask *node_mask;\n\tint num_node;\n\tlong r;\n\n\tpr_debug(\"%s mem %p flags 0x%x size 0x%lx node_id %d\\n\", __func__,\n\t\tmem, mflags.Value, SizeInBytes, numa_node_id);\n\n\tif (mflags.ui32.NoNUMABind || numa_available() == -1) {\n\t\t/* but need bind to a numa node */\n\t\tif (mflags.ui32.NoSubstitute)\n\t\t\treturn -EFAULT;\n\t\telse\n\t\t\treturn 0;\n\t}\n\n\tnum_node = numa_max_node() + 1;\n\n\t/* Ignore binding requests to invalid nodes IDs */\n\tif (numa_node_id >= (unsigned)num_node || numa_node_id == INVALID_NODEID || num_node <= 1) {\n\t\tpr_warn(\"numa_node_id is out range: numa_node_id %d, num_node %d\\n\", numa_node_id, num_node);\n\t\tif (mflags.ui32.NoSubstitute)\n\t\t\treturn -EFAULT;\n\t\telse\n\t\t\treturn 0;\n\t}\n\n\tnode_mask = numa_bitmask_alloc(num_node);\n\tif (!node_mask)\n\t\treturn -ENOMEM;\n\n#ifdef __PPC64__\n\tnuma_bitmask_setbit(node_mask, numa_node_id * 8);\n#else\n\tnuma_bitmask_setbit(node_mask, numa_node_id);\n#endif\n\n\tmode |= mflags.ui32.NoSubstitute ? MPOL_BIND : MPOL_PREFERRED;\n\tr = mbind(mem, SizeInBytes, mode, node_mask->maskp, num_node + 1, 0);\n\tnuma_bitmask_free(node_mask);\n\n\tif (r) {\n\t\t/* If applcation is running inside docker, still return\n\t\t * ok because docker seccomp blocks mbind by default,\n\t\t * otherwise application cannot allocate system memory.\n\t\t */\n\t\tif (errno == EPERM) {\n\t\t\tpr_err_once(\"mbind is blocked by seccomp\\n\");\n\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* Ignore mbind failure if no memory available on node */\n\t\tif (!mflags.ui32.NoSubstitute)\n\t\t\treturn 0;\n\n\t\tpr_warn_once(\"Failed to set NUMA policy for %p: %s\\n\", mem,\n\t\t\t     strerror(errno));\n\n\t\treturn -EFAULT;\n\t}\n\n\treturn 0;\n}\n\nstatic void *fmm_allocate_host_gpu(uint32_t gpu_id, uint32_t node_id, void *address,\n\t\t\t\t   uint64_t MemorySizeInBytes, uint64_t alignment, HsaMemFlags mflags)\n{\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *vm_obj = NULL;\n\tint flags = MADV_DONTFORK;\n\tuint64_t mmap_offset;\n\tint32_t gpu_drm_fd;\n\tuint32_t ioc_flags;\n\tuint32_t preferred_gpu_id;\n\tint gpu_mem_id = 0; /* default to g_first_gpu_mem */\n\tuint64_t size;\n\tvoid *mem;\n\n\t/* set madvise flags to HUGEPAGE always for 2MB pages */\n\tif (MemorySizeInBytes >= (2 * 1024 * 1024))\n\t\tflags |= MADV_HUGEPAGE;\n\n\n\tif (!g_first_gpu_mem)\n\t\treturn NULL;\n\n\tif (gpu_id) {\n\t\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\t\tif (gpu_mem_id < 0)\n\t\t\treturn NULL;\n\t}\n\n\tpreferred_gpu_id = gpu_mem[gpu_mem_id].gpu_id;\n\tgpu_drm_fd = gpu_mem[gpu_mem_id].drm_render_fd;\n\n\tsize = MemorySizeInBytes;\n\tioc_flags = 0;\n\tif (mflags.ui32.CoarseGrain)\n\t\taperture = svm.dgpu_aperture;\n\telse\n\t\taperture = svm.dgpu_alt_aperture; /* always coherent */\n\n\tif (!mflags.ui32.CoarseGrain || svm.disable_cache)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_COHERENT;\n\n\tif (mflags.ui32.Uncached || svm.disable_cache)\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED;\n\n\tioc_flags |= fmm_translate_hsa_to_ioc_flags(mflags);\n\n\tif (mflags.ui32.AQLQueueMemory)\n\t\tsize = MemorySizeInBytes * 2;\n\n\t/* special case for va allocation without real memory alloc */\n\tif (mflags.ui32.OnlyAddress)\n\t\treturn fmm_allocate_va(gpu_id, address, size, aperture, alignment, mflags);\n\n\t/* Paged memory is allocated as a userptr mapping, non-paged\n\t * memory is allocated from KFD\n\t */\n\tif (!mflags.ui32.NonPaged && svm.userptr_for_paged_mem) {\n\t\t/* Allocate address space */\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\tmem = aperture_allocate_area_aligned(aperture, address, size, alignment);\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\tif (!mem)\n\t\t\treturn NULL;\n\n\t\t/* Map anonymous pages */\n\t\tif (mmap(mem, MemorySizeInBytes, PROT_READ | PROT_WRITE,\n\t\t\t MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)\n\t\t    == MAP_FAILED)\n\t\t\tgoto out_release_area;\n\n\t\t/* Bind to NUMA node */\n\t\tif (bind_mem_to_numa(node_id, mem, MemorySizeInBytes, mflags))\n\t\t\tgoto out_release_area;\n\n\t\t/* Mappings in the DGPU aperture don't need to be copied on\n\t\t * fork. This avoids MMU notifiers and evictions due to user\n\t\t * memory mappings on fork.\n\t\t */\n\t\tmadvise(mem, MemorySizeInBytes, flags);\n\n\t\t/* Create userptr BO */\n\t\tmmap_offset = (uint64_t)mem;\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_USERPTR;\n\t\tvm_obj = fmm_allocate_memory_object(preferred_gpu_id, mem, size,\n\t\t\t\t\t\t       aperture, &mmap_offset,\n\t\t\t\t\t\t       ioc_flags);\n\t\tif (!vm_obj)\n\t\t\tgoto out_release_area;\n\t} else {\n\t\tioc_flags |= KFD_IOC_ALLOC_MEM_FLAGS_GTT;\n\t\tmem =  __fmm_allocate_device(preferred_gpu_id, address, size, aperture,\n\t\t\t\t\t     &mmap_offset, ioc_flags, alignment, &vm_obj);\n\n\t\tif (mem && mflags.ui32.HostAccess) {\n\t\t\tvoid *ret = fmm_map_to_cpu(mem, MemorySizeInBytes,\n\t\t\t\t\t\t   mflags.ui32.HostAccess,\n\t\t\t\t\t\t   gpu_drm_fd, mmap_offset);\n\n\t\t\tif (ret == MAP_FAILED) {\n\t\t\t\t__fmm_release(vm_obj, aperture);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}\n    }\n\n#ifdef SANITIZER_AMDGPU\n\t\tif (mem && vm_obj) {\n\t\t\tvm_obj->mmap_flags = mflags.ui32.HostAccess ? PROT_READ | PROT_WRITE : PROT_NONE;\n\t\t\tvm_obj->mmap_fd = gpu_drm_fd;\n\t\t\tvm_obj->mmap_offset = mmap_offset;\n\t\t}\n#endif\n\n\tif (mem && vm_obj) {\n\t\t/* Store memory allocation flags, not ioc flags */\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\tvm_obj->mflags = mflags;\n\t\tvm_obj->node_id = node_id;\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t}\n\n\treturn mem;\n\nout_release_area:\n\t/* Release address space */\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tif (mem) {\n\t\taperture_release_area(aperture, mem, size);\n\t}\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\treturn NULL;\n}\n\nvoid *hsakmt_fmm_allocate_host(uint32_t gpu_id, uint32_t node_id, void *address,\n\t\t\tuint64_t MemorySizeInBytes, uint64_t alignment, HsaMemFlags mflags)\n{\n\tif (hsakmt_is_dgpu)\n\t\treturn fmm_allocate_host_gpu(gpu_id, node_id, address, MemorySizeInBytes, alignment, mflags);\n\n\tif (alignment) {//Alignment not supported on non-dgpu\n\t\tpr_err(\"Non-default alignment not supported on non-dgpu\\n\");\n\t\treturn NULL;\n\t}\n\n\treturn fmm_allocate_host_cpu(address, MemorySizeInBytes, mflags);\n}\n\nstatic int __fmm_release(vm_object_t *object, manageable_aperture_t *aperture)\n{\n\tstruct kfd_ioctl_free_memory_of_gpu_args args = {0};\n\tint ret = 0;\n\tuint32_t i;\n\n\tif (!object)\n\t\treturn -EINVAL;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\n\tif (object->userptr) {\n\t\tobject->registration_count--;\n\t\tif (object->registration_count > 0) {\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* If memory is user memory and it's still GPU mapped, munmap\n\t * would cause an eviction. If the restore happens quickly\n\t * enough, restore would also fail with an error message. So\n\t * free the BO before unmapping the pages.\n\t */\n\tfor (i = 0; i < object->handle_num; i++) {\n\t\targs.handle = object->handles[i];\n\t\tif (args.handle == 0)\n\t\t\tcontinue;\n\t\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_FREE_MEMORY_OF_GPU, &args))\n\t\t\tret = -errno;\n\t}\n\n\tif (ret)\n\t\tgoto err_free_mem_failed;\n\n\taperture_release_area(aperture, object->start, object->size);\n\tvm_remove_object(aperture, object);\n\nerr_free_mem_failed:\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nHSAKMT_STATUS hsakmt_fmm_release(void *address)\n{\n\tmanageable_aperture_t *aperture = NULL;\n\tvm_object_t *object = NULL;\n\tgpu_mem_t *gpu_mem_ptr = NULL;\n\n\t/* Special handling for scratch memory */\n\tgpu_mem_ptr = fmm_is_scratch_aperture(address);\n\tif (gpu_mem_ptr) {\n\t\tfmm_release_scratch(gpu_mem_ptr->gpu_id);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tobject = vm_find_object(address, 0, &aperture);\n\n\tif (!object)\n\t\treturn hsakmt_is_svm_api_supported ?\n\t\t\tHSAKMT_STATUS_SUCCESS :\n\t\t\tHSAKMT_STATUS_MEMORY_NOT_REGISTERED;\n\n\tif (aperture == &cpuvm_aperture) {\n\t\t/* APU system memory */\n\t\tuint64_t size = 0;\n\n\t\tsize = object->size;\n\t\tvm_remove_object(&cpuvm_aperture, object);\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\tmunmap(address, size);\n\t} else {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t\tif (__fmm_release(object, aperture))\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic int fmm_set_memory_policy(uint32_t gpu_id, int default_policy, int alt_policy,\n\t\t\t\t uintptr_t alt_base, uint64_t alt_size,\n\t\t\t\t uint32_t misc_process_flags)\n{\n\tstruct kfd_ioctl_set_memory_policy_args args = {0};\n\n\targs.gpu_id = gpu_id;\n\targs.default_policy = default_policy;\n\targs.alternate_policy = alt_policy;\n\targs.alternate_aperture_base = alt_base;\n\targs.alternate_aperture_size = alt_size;\n\targs.misc_process_flag = misc_process_flags;\n\n\treturn hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_MEMORY_POLICY, &args);\n}\n\nstatic uint32_t get_vm_alignment(uint32_t device_id)\n{\n\tint page_size = 0;\n\n\tif (device_id >= 0x6920 && device_id <= 0x6939) /* Tonga */\n\t\tpage_size = TONGA_PAGE_SIZE;\n\telse if (device_id >= 0x9870 && device_id <= 0x9877) /* Carrizo */\n\t\tpage_size = TONGA_PAGE_SIZE;\n\n\treturn MAX(PAGE_SIZE, page_size);\n}\n\nstatic HSAKMT_STATUS get_process_apertures(\n\tstruct kfd_process_device_apertures *process_apertures,\n\tuint32_t *num_of_nodes)\n{\n\tstruct kfd_ioctl_get_process_apertures_new_args args_new = {0};\n\tstruct kfd_ioctl_get_process_apertures_args args_old;\n\n\targs_new.kfd_process_device_apertures_ptr = (uintptr_t)process_apertures;\n\targs_new.num_of_nodes = *num_of_nodes;\n\tif (!hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_PROCESS_APERTURES_NEW,\n\t\t      (void *)&args_new)) {\n\t\t*num_of_nodes = args_new.num_of_nodes;\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\t/* New IOCTL failed, try the old one in case we're running on\n\t * a really old kernel */\n\tmemset(&args_old, 0, sizeof(args_old));\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_PROCESS_APERTURES,\n\t\t     (void *)&args_old))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tif (args_old.num_of_nodes < *num_of_nodes)\n\t\t*num_of_nodes = args_old.num_of_nodes;\n\n\tmemcpy(process_apertures, args_old.process_apertures,\n\t       sizeof(*process_apertures) * *num_of_nodes);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* The VMs from DRM render nodes are used by KFD for the lifetime of\n * the process. Therefore we have to keep using the same FDs for the\n * lifetime of the process, even when we close and reopen KFD. There\n * are up to 128 render nodes that we cache in this array.\n */\n#define DRM_FIRST_RENDER_NODE 128\n#define DRM_LAST_RENDER_NODE 255\nstatic int drm_render_fds[DRM_LAST_RENDER_NODE + 1 - DRM_FIRST_RENDER_NODE];\n\n/* amdgpu device handle for each gpu that libdrm uses */\nstatic struct amdgpu_device *amdgpu_handle[DRM_LAST_RENDER_NODE + 1 - DRM_FIRST_RENDER_NODE];\n\nint hsakmt_open_drm_render_device(int minor)\n{\n\tchar path[128];\n\tint index, fd;\n\tuint32_t major_drm, minor_drm;\n\tstruct amdgpu_device **device_handle;\n\n\t/* Bypass amdgpu if we're running a model. Return hsakmt_kfd_fd, which is the\n\t * backing for all our \"GPU\" memory. */\n\tif (hsakmt_use_model)\n\t\treturn hsakmt_kfd_fd;\n\n\tif (minor < DRM_FIRST_RENDER_NODE || minor > DRM_LAST_RENDER_NODE) {\n\t\tpr_err(\"DRM render minor %d out of range [%d, %d]\\n\", minor,\n\t\t       DRM_FIRST_RENDER_NODE, DRM_LAST_RENDER_NODE);\n\t\treturn -EINVAL;\n\t}\n\tindex = minor - DRM_FIRST_RENDER_NODE;\n\n\t/* If the render node was already opened, keep using the same FD */\n\tif (drm_render_fds[index])\n\t\treturn drm_render_fds[index];\n\n\tsprintf(path, \"/dev/dri/renderD%d\", minor);\n\tfd = open(path, O_RDWR | O_CLOEXEC);\n\tif (fd < 0) {\n\t\tif (errno != ENOENT && errno != EPERM) {\n\t\t\tpr_err(\"Failed to open %s: %s\\n\", path, strerror(errno));\n\t\t\tif (errno == EACCES)\n\t\t\t\tpr_info(\"Check user is in \\\"video\\\" group\\n\");\n\t\t}\n\t\treturn -errno;\n\t}\n\tdrm_render_fds[index] = fd;\n\n\tdevice_handle = &amdgpu_handle[index];\n\tif (!amdgpu_device_initialize(fd, &major_drm, &minor_drm, device_handle)) {\n\t\t/* if amdgpu_device_get_fd available query render fd that libdrm uses,\n\t\t * then close drm_render_fds above, replace it by fd libdrm uses.\n\t\t */\n\t\tif (hsakmt_fn_amdgpu_device_get_fd) {\n\t\t\tfd = hsakmt_fn_amdgpu_device_get_fd(*device_handle);\n\t\t\tif (fd > 0) {\n\t\t\t\tclose(drm_render_fds[index]);\n\t\t\t\tdrm_render_fds[index] = fd;\n\t\t\t} else {\n\t\t\t\tpr_err(\"amdgpu_device_get_fd failed: %d\\n\", fd);\n\t\t\t\tamdgpu_device_deinitialize(*device_handle);\n\t\t\t\t*device_handle = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fd;\n}\n\nstatic HSAKMT_STATUS acquire_vm(uint32_t gpu_id, int fd)\n{\n\tstruct kfd_ioctl_acquire_vm_args args;\n\n\targs.gpu_id = gpu_id;\n\targs.drm_fd = fd;\n\tpr_info(\"acquiring VM for %x using %d\\n\", gpu_id, fd);\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_ACQUIRE_VM, (void *)&args)) {\n\t\tpr_err(\"AMDKFD_IOC_ACQUIRE_VM failed\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS init_mmap_apertures(HSAuint64 base, HSAuint64 limit,\n\t\t\t\t\t HSAuint32 align, HSAuint32 guard_pages)\n{\n\tvoid *addr;\n\n\tif (align > (HSAuint32)PAGE_SIZE) {\n\t\t/* This should never happen. Alignment constraints\n\t\t * only apply to old GPUs that don't support 48-bit\n\t\t * virtual addresses.\n\t\t */\n\t\tpr_info(\"Falling back to reserved SVM apertures due to alignment constraints.\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\t/* Set up one SVM aperture */\n\tsvm.apertures[SVM_DEFAULT].base  = (void *)base;\n\tsvm.apertures[SVM_DEFAULT].limit = (void *)limit;\n\tsvm.apertures[SVM_DEFAULT].align = align;\n\tsvm.apertures[SVM_DEFAULT].guard_pages = guard_pages;\n\tsvm.apertures[SVM_DEFAULT].is_cpu_accessible = true;\n\tsvm.apertures[SVM_DEFAULT].ops = &mmap_aperture_ops;\n\n\tsvm.apertures[SVM_COHERENT].base = svm.apertures[SVM_COHERENT].limit =\n\t\tNULL;\n\n\t/* Try to allocate one page. If it fails, we'll fall back to\n\t * managing our own reserved address range.\n\t */\n\taddr = aperture_allocate_area(&svm.apertures[SVM_DEFAULT], NULL, PAGE_SIZE);\n\tif (addr) {\n\t\taperture_release_area(&svm.apertures[SVM_DEFAULT], addr,\n\t\t\t\t      PAGE_SIZE);\n\n\t\tsvm.dgpu_aperture = svm.dgpu_alt_aperture =\n\t\t\t&svm.apertures[SVM_DEFAULT];\n\t\tpr_info(\"Initialized unreserved SVM apertures: %p - %p\\n\",\n\t\t\tsvm.apertures[SVM_DEFAULT].base,\n\t\t\tsvm.apertures[SVM_DEFAULT].limit);\n\t} else {\n\t\tpr_info(\"Failed to allocate unreserved SVM address space.\\n\");\n\t\tpr_info(\"Falling back to reserved SVM apertures.\\n\");\n\t}\n\n\treturn addr ? HSAKMT_STATUS_SUCCESS : HSAKMT_STATUS_ERROR;\n}\n\nstatic void *reserve_address(void *addr, unsigned long long int len)\n{\n\tvoid *ret_addr;\n\n\tif (len <= 0)\n\t\treturn NULL;\n\n\tret_addr = mmap(addr, len, PROT_NONE,\n\t\t\t\t MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0);\n\tif (ret_addr == MAP_FAILED)\n\t\treturn NULL;\n\n\treturn ret_addr;\n}\n\n/* Managed SVM aperture limits: only reserve up to 40 bits (1TB, what\n * GFX8 supports). Need to find at least 4GB of usable address space.\n */\n#define SVM_RESERVATION_LIMIT ((1ULL << 40) - 1)\n#define SVM_MIN_VM_SIZE (4ULL << 30)\n#define IS_CANONICAL_ADDR(a) ((a) < (1ULL << 47))\n\nstatic HSAKMT_STATUS init_svm_apertures(HSAuint64 base, HSAuint64 limit,\n\t\t\t\t\tHSAuint32 align, HSAuint32 guard_pages)\n{\n\tconst HSAuint64 ADDR_INC = GPU_HUGE_PAGE_SIZE;\n\tHSAuint64 len, map_size, alt_base, alt_size;\n\tbool found = false;\n\tvoid *addr, *ret_addr = NULL;\n\n\t/* If we already have an SVM aperture initialized (from a\n\t * parent process), keep using it\n\t */\n\tif (dgpu_shared_aperture_limit)\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\n\t/* Align base and limit to huge page size */\n\tbase = ALIGN_UP(base, GPU_HUGE_PAGE_SIZE);\n\tlimit = ((limit + 1) & ~(HSAuint64)(GPU_HUGE_PAGE_SIZE - 1)) - 1;\n\n\t/* If the limit is greater or equal 47-bits of address space,\n\t * it means we have GFXv9 or later GPUs only. We don't need\n\t * apertures to determine the MTYPE and the virtual address\n\t * space of the GPUs covers the full CPU address range (on\n\t * x86_64) or at least mmap is unlikely to run out of\n\t * addresses the GPUs can handle.\n\t */\n\tif (limit >= (1ULL << 47) - 1 && !svm.reserve_svm) {\n\t\tHSAKMT_STATUS status = init_mmap_apertures(base, limit, align,\n\t\t\t\t\t\t\t   guard_pages);\n\n\t\tif (status == HSAKMT_STATUS_SUCCESS)\n\t\t\treturn status;\n\t\t/* fall through: fall back to reserved address space */\n\t}\n\n\tif (limit > SVM_RESERVATION_LIMIT)\n\t\tlimit = SVM_RESERVATION_LIMIT;\n\tif (base >= limit) {\n\t\tpr_err(\"No SVM range compatible with all GPU and software constraints\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\t/* Try to reserve address space for SVM.\n\t *\n\t * Inner loop: try start addresses in huge-page increments up\n\t * to half the VM size we're trying to reserve\n\t *\n\t * Outer loop: reduce size of the allocation by factor 2 at a\n\t * time and print a warning for every reduction\n\t */\n\tfor (len = limit - base + 1; !found && len >= SVM_MIN_VM_SIZE;\n\t     len = (len + 1) >> 1) {\n\t\tfor (addr = (void *)base; (HSAuint64)addr + ((len + 1) >> 1) - 1 <= limit;\n\t\t     addr = (void *)((HSAuint64)addr + ADDR_INC)) {\n\t\t\tHSAuint64 top = MIN((HSAuint64)addr + len, limit+1);\n\n\t\t\tmap_size = (top - (HSAuint64)addr) &\n\t\t\t\t~(HSAuint64)(PAGE_SIZE - 1);\n\t\t\tif (map_size < SVM_MIN_VM_SIZE)\n\t\t\t\tbreak;\n\n\t\t\tret_addr = reserve_address(addr, map_size);\n\t\t\tif (!ret_addr)\n\t\t\t\tbreak;\n\t\t\tif ((HSAuint64)ret_addr + ((len + 1) >> 1) - 1 <= limit)\n\t\t\t\t/* At least half the returned address\n\t\t\t\t * space is GPU addressable, we'll\n\t\t\t\t * take it\n\t\t\t\t */\n\t\t\t\tbreak;\n\t\t\tmunmap(ret_addr, map_size);\n\t\t\tret_addr = NULL;\n\t\t}\n\t\tif (!ret_addr) {\n\t\t\tpr_warn(\"Failed to reserve %uGB for SVM ...\\n\",\n\t\t\t\t(unsigned int)(len >> 30));\n\t\t\tcontinue;\n\t\t}\n\t\tif ((HSAuint64)ret_addr + SVM_MIN_VM_SIZE - 1 > limit) {\n\t\t\t/* addressable size is less than the minimum */\n\t\t\tpr_warn(\"Got %uGB for SVM at %p with only %dGB usable ...\\n\",\n\t\t\t\t(unsigned int)(map_size >> 30), ret_addr,\n\t\t\t\t(int)((limit - (HSAint64)ret_addr) >> 30));\n\t\t\tmunmap(ret_addr, map_size);\n\t\t\tret_addr = NULL;\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!found) {\n\t\tpr_err(\"Failed to reserve SVM address range. Giving up.\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tbase = (HSAuint64)ret_addr;\n\tif (base + map_size - 1 > limit)\n\t\t/* trim the tail that's not GPU-addressable */\n\t\tmunmap((void *)(limit + 1), base + map_size - 1 - limit);\n\telse\n\t\tlimit = base + map_size - 1;\n\n\t/* init two apertures for non-coherent and coherent memory */\n\tsvm.apertures[SVM_DEFAULT].base  = dgpu_shared_aperture_base  = ret_addr;\n\tsvm.apertures[SVM_DEFAULT].limit = dgpu_shared_aperture_limit = (void *)limit;\n\tsvm.apertures[SVM_DEFAULT].align = align;\n\tsvm.apertures[SVM_DEFAULT].guard_pages = guard_pages;\n\tsvm.apertures[SVM_DEFAULT].is_cpu_accessible = true;\n\tsvm.apertures[SVM_DEFAULT].ops = &reserved_aperture_ops;\n\n\t/* Use the first 1/4 of the dGPU aperture as\n\t * alternate aperture for coherent access.\n\t * Base and size must be 64KB aligned.\n\t */\n\talt_base = (HSAuint64)svm.apertures[SVM_DEFAULT].base;\n\talt_size = (VOID_PTRS_SUB(svm.apertures[SVM_DEFAULT].limit,\n\t\t\t\t  svm.apertures[SVM_DEFAULT].base) + 1) >> 2;\n\talt_base = (alt_base + 0xffff) & ~0xffffULL;\n\talt_size = (alt_size + 0xffff) & ~0xffffULL;\n\tsvm.apertures[SVM_COHERENT].base = (void *)alt_base;\n\tsvm.apertures[SVM_COHERENT].limit = (void *)(alt_base + alt_size - 1);\n\tsvm.apertures[SVM_COHERENT].align = align;\n\tsvm.apertures[SVM_COHERENT].guard_pages = guard_pages;\n\tsvm.apertures[SVM_COHERENT].is_cpu_accessible = true;\n\tsvm.apertures[SVM_COHERENT].ops = &reserved_aperture_ops;\n\n\tsvm.apertures[SVM_DEFAULT].base = VOID_PTR_ADD(svm.apertures[SVM_COHERENT].limit, 1);\n\n\tpr_info(\"SVM alt (coherent): %12p - %12p\\n\",\n\t\tsvm.apertures[SVM_COHERENT].base, svm.apertures[SVM_COHERENT].limit);\n\tpr_info(\"SVM (non-coherent): %12p - %12p\\n\",\n\t\tsvm.apertures[SVM_DEFAULT].base, svm.apertures[SVM_DEFAULT].limit);\n\n\tsvm.dgpu_aperture = &svm.apertures[SVM_DEFAULT];\n\tsvm.dgpu_alt_aperture = &svm.apertures[SVM_COHERENT];\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic void fmm_init_rbtree(void)\n{\n\tstatic int once;\n\tint i = gpu_mem_count;\n\n\tif (once++ == 0) {\n\t\trbtree_init(&svm.apertures[SVM_DEFAULT].tree);\n\t\trbtree_init(&svm.apertures[SVM_DEFAULT].user_tree);\n\t\trbtree_init(&svm.apertures[SVM_COHERENT].tree);\n\t\trbtree_init(&svm.apertures[SVM_COHERENT].user_tree);\n\t\trbtree_init(&cpuvm_aperture.tree);\n\t\trbtree_init(&cpuvm_aperture.user_tree);\n\t\trbtree_init(&mem_handle_aperture.tree);\n\t\trbtree_init(&mem_handle_aperture.user_tree);\n\t}\n\n\twhile (i--) {\n\t\trbtree_init(&gpu_mem[i].scratch_physical.tree);\n\t\trbtree_init(&gpu_mem[i].scratch_physical.user_tree);\n\t\trbtree_init(&gpu_mem[i].gpuvm_aperture.tree);\n\t\trbtree_init(&gpu_mem[i].gpuvm_aperture.user_tree);\n\t}\n}\n\nstatic void *map_mmio(uint32_t node_id, uint32_t gpu_id, int mmap_fd)\n{\n\tvoid *mem;\n\tmanageable_aperture_t *aperture = svm.dgpu_alt_aperture;\n\tuint32_t ioc_flags;\n\tvm_object_t *vm_obj = NULL;\n\tHsaMemFlags mflags;\n\tvoid *ret;\n\tuint64_t mmap_offset;\n\n\t/* Allocate physical memory and vm object*/\n\tioc_flags = KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP |\n\t\tKFD_IOC_ALLOC_MEM_FLAGS_WRITABLE |\n\t\tKFD_IOC_ALLOC_MEM_FLAGS_COHERENT;\n\tmem = __fmm_allocate_device(gpu_id, NULL, PAGE_SIZE, aperture,\n\t\t\t&mmap_offset, ioc_flags, 0, &vm_obj);\n\n\tif (!mem || !vm_obj)\n\t\treturn NULL;\n\n\tmflags.Value = 0;\n\tmflags.ui32.NonPaged = 1;\n\tmflags.ui32.HostAccess = 1;\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tvm_obj->mflags = mflags;\n\tvm_obj->node_id = node_id;\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\tif (hsakmt_use_model) {\n\t\tmodel_set_mmio_page(mem);\n\t\treturn mem;\n\t}\n\n\t/* Map for CPU access*/\n\tret = mmap(mem, PAGE_SIZE,\n\t\t\t PROT_READ | PROT_WRITE,\n\t\t\t MAP_SHARED | MAP_FIXED, mmap_fd,\n\t\t\t mmap_offset);\n\tif (ret == MAP_FAILED) {\n\t\t__fmm_release(vm_obj, aperture);\n\t\treturn NULL;\n\t}\n\n\t/* Map for GPU access*/\n\tif (hsakmt_fmm_map_to_gpu(mem, PAGE_SIZE, NULL)) {\n\t\t__fmm_release(vm_obj, aperture);\n\t\treturn NULL;\n\t}\n\n\treturn mem;\n}\n\nstatic void release_mmio(void)\n{\n\tuint32_t gpu_mem_id;\n\n\tfor (gpu_mem_id = 0; (uint32_t)gpu_mem_id < gpu_mem_count; gpu_mem_id++) {\n\t\tif (!gpu_mem[gpu_mem_id].mmio_aperture.base)\n\t\t\tcontinue;\n\t\thsakmt_fmm_unmap_from_gpu(gpu_mem[gpu_mem_id].mmio_aperture.base);\n\t\tmunmap(gpu_mem[gpu_mem_id].mmio_aperture.base, PAGE_SIZE);\n\t\thsakmt_fmm_release(gpu_mem[gpu_mem_id].mmio_aperture.base);\n\t}\n}\n\nHSAKMT_STATUS hsakmt_fmm_get_amdgpu_device_handle(uint32_t node_id,\n\t\t\t\t\t\tHsaAMDGPUDeviceHandle *DeviceHandle)\n{\n\tint32_t i = gpu_mem_find_by_node_id(node_id);\n\tint index;\n\n\tif (i < 0)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\tif (hsakmt_use_model) {\n\t\t*DeviceHandle = NULL;\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tindex = gpu_mem[i].drm_render_minor - DRM_FIRST_RENDER_NODE;\n\tif (!amdgpu_handle[index])\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\t*DeviceHandle = amdgpu_handle[index];\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic bool two_apertures_overlap(void *start_1, void *limit_1, void *start_2, void *limit_2)\n{\n    return (start_1 >= start_2 && start_1 <= limit_2) || (start_2 >= start_1 && start_2 <= limit_1);\n}\n\nstatic bool init_mem_handle_aperture(HSAuint32 align, HSAuint32 guard_pages)\n{\n\tbool found;\n\tuint32_t i;\n\n\t/* init mem_handle_aperture for buffer handler management */\n\tmem_handle_aperture.align = align;\n\tmem_handle_aperture.guard_pages = guard_pages;\n\tmem_handle_aperture.is_cpu_accessible = false;\n\tmem_handle_aperture.ops = &reserved_aperture_ops;\n\n\twhile (PORT_VPTR_TO_UINT64(mem_handle_aperture.base) < END_NON_CANONICAL_ADDR - 1) {\n\n\t\tfound = true;\n\t\tfor (i = 0; i < gpu_mem_count; i++) {\n\n\t\t\tif (gpu_mem[i].lds_aperture.base &&\n\t\t\t\ttwo_apertures_overlap(gpu_mem[i].lds_aperture.base, gpu_mem[i].lds_aperture.limit,\n\t\t\t\t\t\t\t\t\tmem_handle_aperture.base, mem_handle_aperture.limit)) {\n\t\t\t\t\tfound = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (gpu_mem[i].scratch_aperture.base &&\n\t\t\t\ttwo_apertures_overlap(gpu_mem[i].scratch_aperture.base, gpu_mem[i].scratch_aperture.limit,\n\t\t\t\t\t\t\t\t\tmem_handle_aperture.base, mem_handle_aperture.limit)){\n\t\t\t\t\tfound = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (gpu_mem[i].gpuvm_aperture.base &&\n\t\t\t   two_apertures_overlap(gpu_mem[i].gpuvm_aperture.base, gpu_mem[i].gpuvm_aperture.limit,\n\t\t\t\t\t\t\t\t\tmem_handle_aperture.base, mem_handle_aperture.limit)){\n\t\t\t\t\tfound = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (found) {\n\t\t\tpr_info(\"mem_handle_aperture start %p, mem_handle_aperture limit %p\\n\",\n\t\t\t\t\tmem_handle_aperture.base, mem_handle_aperture.limit);\n\t\t\treturn true;\n\t\t} else {\n\t\t\t/* increase base by 1UL<<47 to check next hole */\n\t\t\tmem_handle_aperture.base =  VOID_PTR_ADD(mem_handle_aperture.base, (1UL << 47));\n\t\t\tmem_handle_aperture.limit = VOID_PTR_ADD(mem_handle_aperture.base, (1ULL << 47));\n\t\t}\n\t}\n\n\t/* set invalid aperture if fail locating a hole for it */\n\tmem_handle_aperture.base =  0;\n\tmem_handle_aperture.limit = 0;\n\n\treturn false;\n}\n\nHSAKMT_STATUS hsakmt_fmm_init_process_apertures(unsigned int NumNodes)\n{\n\tuint32_t i;\n\tint32_t gpu_mem_id = 0;\n\tstruct kfd_process_device_apertures *process_apertures;\n\tuint32_t num_of_sysfs_nodes;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tchar *disableCache, *pagedUserptr, *checkUserptr, *guardPagesStr, *reserveSvm;\n\tchar *maxVaAlignStr, *mfmaHighPrecisionModeStr;\n\tunsigned int guardPages = 1;\n\tuint64_t svm_base = 0, svm_limit = 0;\n\tuint32_t svm_alignment = 0, mfma_high_precision_mode = 0;\n\n\t/* If HSA_DISABLE_CACHE is set to a non-0 value, disable caching */\n\tdisableCache = getenv(\"HSA_DISABLE_CACHE\");\n\tsvm.disable_cache = (disableCache && strcmp(disableCache, \"0\"));\n\n\t/* If HSA_USERPTR_FOR_PAGED_MEM is not set or set to a non-0\n\t * value, enable userptr for all paged memory allocations\n\t */\n\tpagedUserptr = getenv(\"HSA_USERPTR_FOR_PAGED_MEM\");\n\tsvm.userptr_for_paged_mem = (!pagedUserptr || strcmp(pagedUserptr, \"0\"));\n\n\tif (hsakmt_use_model)\n\t\tsvm.userptr_for_paged_mem = false;\n\t/* If HSA_CHECK_USERPTR is set to a non-0 value, check all userptrs\n\t * when they are registered\n\t */\n\tcheckUserptr = getenv(\"HSA_CHECK_USERPTR\");\n\tsvm.check_userptr = (checkUserptr && strcmp(checkUserptr, \"0\"));\n\n\t/* If HSA_RESERVE_SVM is set to a non-0 value,\n\t * enable packet capture and replay mode.\n\t */\n\treserveSvm = getenv(\"HSA_RESERVE_SVM\");\n\tsvm.reserve_svm = (reserveSvm && strcmp(reserveSvm, \"0\"));\n\n\t/* Specify number of guard pages for SVM apertures, default is 1 */\n\tguardPagesStr = getenv(\"HSA_SVM_GUARD_PAGES\");\n\tif (!guardPagesStr || sscanf(guardPagesStr, \"%u\", &guardPages) != 1)\n\t\tguardPages = 1;\n\n\tmfmaHighPrecisionModeStr = getenv(\"HSA_HIGH_PRECISION_MODE\");\n\tmfma_high_precision_mode = (mfmaHighPrecisionModeStr &&\n\t\t\t\t    strcmp(mfmaHighPrecisionModeStr, \"0\"));\n\t/* Sets the max VA alignment order size during mapping. By default the order\n\t * size is set to 18(1G) for GFX950 to reduce TLB hits. If any non-gfx950\n\t * ASIC is found in the system, set back to 9(2MB).\n\t */\n\tmaxVaAlignStr = getenv(\"HSA_MAX_VA_ALIGN\");\n\tif (!maxVaAlignStr || sscanf(maxVaAlignStr, \"%u\", &svm.alignment_order) != 1) {\n\t\tsvm.alignment_order = 18;\n\n\t\tfor (i = 0; i < NumNodes; i++) {\n\t\t\tif (hsakmt_get_gfxv_by_node_id(i) != GFX_VERSION_GFX950) {\n\t\t\t\tsvm.alignment_order = 9;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tpr_info(\"SVM alignment default order is %d.\", svm.alignment_order);\n\n\tgpu_mem_count = 0;\n\tg_first_gpu_mem = NULL;\n\n\t/* Trade off - NumNodes includes GPU nodes + CPU Node. So in\n\t * systems with CPU node, slightly more memory is allocated than\n\t * necessary\n\t */\n\tgpu_mem = (gpu_mem_t *)calloc(NumNodes, sizeof(gpu_mem_t));\n\tif (!gpu_mem)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\t/* Initialize gpu_mem[] from sysfs topology. Rest of the members are\n\t * set to 0 by calloc. This is necessary because this function\n\t * gets called before hsaKmtAcquireSystemProperties() is called.\n\t */\n\n\thsakmt_is_dgpu = false;\n\n\tfor (i = 0; i < NumNodes; i++) {\n\t\tHsaNodeProperties props;\n\n\t\tret = hsakmt_topology_get_node_props(i, &props);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto gpu_mem_init_failed;\n\n\t\thsakmt_topology_setup_is_dgpu_param(&props);\n\n\t\t/* Skip non-GPU nodes */\n\t\tif (props.KFDGpuID) {\n\t\t\tint fd = hsakmt_open_drm_render_device(props.DrmRenderMinor);\n\t\t\tif (fd <= 0) {\n\t\t\t\tret = HSAKMT_STATUS_ERROR;\n\t\t\t\tgoto gpu_mem_init_failed;\n\t\t\t}\n\n\t\t\tgpu_mem[gpu_mem_count].drm_render_minor = props.DrmRenderMinor;\n\t\t\tgpu_mem[gpu_mem_count].usable_peer_id_array =\n\t\t\t\tcalloc(NumNodes, sizeof(uint32_t));\n\t\t\tif (!gpu_mem[gpu_mem_count].usable_peer_id_array) {\n\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\tgoto gpu_mem_init_failed;\n\t\t\t}\n\t\t\tgpu_mem[gpu_mem_count].usable_peer_id_array[0] = props.KFDGpuID;\n\t\t\tgpu_mem[gpu_mem_count].usable_peer_id_num = 1;\n\n\t\t\tgpu_mem[gpu_mem_count].EngineId.ui32.Major = props.EngineId.ui32.Major;\n\t\t\tgpu_mem[gpu_mem_count].EngineId.ui32.Minor = props.EngineId.ui32.Minor;\n\t\t\tgpu_mem[gpu_mem_count].EngineId.ui32.Stepping = props.EngineId.ui32.Stepping;\n\n\t\t\tgpu_mem[gpu_mem_count].drm_render_fd = fd;\n\t\t\tgpu_mem[gpu_mem_count].gpu_id = props.KFDGpuID;\n\t\t\tgpu_mem[gpu_mem_count].local_mem_size = props.LocalMemSize;\n\t\t\tgpu_mem[gpu_mem_count].device_id = props.DeviceId;\n\t\t\tgpu_mem[gpu_mem_count].node_id = i;\n\t\t\thsakmt_is_svm_api_supported &= props.Capability.ui32.SVMAPISupported;\n\n\t\t\tgpu_mem[gpu_mem_count].scratch_physical.align = PAGE_SIZE;\n\t\t\tgpu_mem[gpu_mem_count].scratch_physical.ops = &reserved_aperture_ops;\n\t\t\tpthread_mutex_init(&gpu_mem[gpu_mem_count].scratch_physical.fmm_mutex, NULL);\n\n\t\t\tgpu_mem[gpu_mem_count].gpuvm_aperture.align =\n\t\t\t\tget_vm_alignment(props.DeviceId);\n\t\t\tgpu_mem[gpu_mem_count].gpuvm_aperture.guard_pages = guardPages;\n\t\t\tgpu_mem[gpu_mem_count].gpuvm_aperture.ops = &reserved_aperture_ops;\n\t\t\tpthread_mutex_init(&gpu_mem[gpu_mem_count].gpuvm_aperture.fmm_mutex, NULL);\n\n\t\t\tif (!g_first_gpu_mem)\n\t\t\t\tg_first_gpu_mem = &gpu_mem[gpu_mem_count];\n\n\t\t\tgpu_mem_count++;\n\t\t}\n\t}\n\n\t/* The ioctl will also return Number of Nodes if\n\t * args.kfd_process_device_apertures_ptr is set to NULL. This is not\n\t * required since Number of nodes is already known. Kernel will fill in\n\t * the apertures in kfd_process_device_apertures_ptr\n\t */\n\tnum_of_sysfs_nodes = hsakmt_get_num_sysfs_nodes();\n\tif (num_of_sysfs_nodes < gpu_mem_count) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto sysfs_parse_failed;\n\t}\n\n\tprocess_apertures = calloc(num_of_sysfs_nodes, sizeof(struct kfd_process_device_apertures));\n\tif (!process_apertures) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto sysfs_parse_failed;\n\t}\n\n\t/* GPU Resource management can disable some of the GPU nodes.\n\t * The Kernel driver could be not aware of this.\n\t * Get from Kernel driver information of all the nodes and then filter it.\n\t */\n\tret = get_process_apertures(process_apertures, &num_of_sysfs_nodes);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\tgoto get_aperture_ioctl_failed;\n\n\tall_gpu_id_array_size = 0;\n\tall_gpu_id_array = NULL;\n\tif (num_of_sysfs_nodes > 0) {\n\t\tall_gpu_id_array = malloc(sizeof(uint32_t) * gpu_mem_count);\n\t\tif (!all_gpu_id_array) {\n\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\tgoto get_aperture_ioctl_failed;\n\t\t}\n\t}\n\n\tfor (i = 0 ; i < num_of_sysfs_nodes ; i++) {\n\t\tHsaNodeProperties nodeProps;\n\t\tHsaIoLinkProperties linkProps[NumNodes];\n\t\tuint32_t nodeId;\n\t\tuint32_t j;\n\n\t\t/* Map Kernel process device data node i <--> gpu_mem_id which\n\t\t * indexes into gpu_mem[] based on gpu_id\n\t\t */\n\t\tgpu_mem_id = gpu_mem_find_by_gpu_id(process_apertures[i].gpu_id);\n\t\tif (gpu_mem_id < 0)\n\t\t\tcontinue;\n\n\t\tif (all_gpu_id_array_size == gpu_mem_count) {\n\t\t\tret = HSAKMT_STATUS_ERROR;\n\t\t\tgoto aperture_init_failed;\n\t\t}\n\t\tall_gpu_id_array[all_gpu_id_array_size++] = process_apertures[i].gpu_id;\n\n\t\t/* Add this GPU to the usable_peer_id_arrays of all GPUs that\n\t\t * this GPU has an IO link to. This GPU can map memory\n\t\t * allocated on those GPUs.\n\t\t */\n\t\tnodeId = gpu_mem[gpu_mem_id].node_id;\n\t\tret = hsakmt_topology_get_node_props(nodeId, &nodeProps);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto aperture_init_failed;\n\t\tassert(nodeProps.NumIOLinks <= NumNodes);\n\t\tret = hsakmt_topology_get_iolink_props(nodeId, nodeProps.NumIOLinks,\n\t\t\t\t\t\tlinkProps);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto aperture_init_failed;\n\t\tfor (j = 0; j < nodeProps.NumIOLinks; j++) {\n\t\t\tint32_t to_gpu_mem_id =\n\t\t\t\tgpu_mem_find_by_node_id(linkProps[j].NodeTo);\n\t\t\tuint32_t peer;\n\n\t\t\tif (to_gpu_mem_id < 0)\n\t\t\t\tcontinue;\n\n\t\t\tassert(gpu_mem[to_gpu_mem_id].usable_peer_id_num < NumNodes);\n\t\t\tpeer = gpu_mem[to_gpu_mem_id].usable_peer_id_num++;\n\t\t\tgpu_mem[to_gpu_mem_id].usable_peer_id_array[peer] =\n\t\t\t\tgpu_mem[gpu_mem_id].gpu_id;\n\t\t}\n\n\t\tgpu_mem[gpu_mem_id].lds_aperture.base =\n\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].lds_base);\n\t\tgpu_mem[gpu_mem_id].lds_aperture.limit =\n\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].lds_limit);\n\n\t\tgpu_mem[gpu_mem_id].scratch_aperture.base =\n\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].scratch_base);\n\t\tgpu_mem[gpu_mem_id].scratch_aperture.limit =\n\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].scratch_limit);\n\n\t\tif (IS_CANONICAL_ADDR(process_apertures[i].gpuvm_limit)) {\n\t\t\tuint64_t vm_alignment = get_vm_alignment(\n\t\t\t\tgpu_mem[gpu_mem_id].device_id);\n\n\t\t\t/* Set proper alignment for scratch backing aperture */\n\t\t\tgpu_mem[gpu_mem_id].scratch_physical.align = vm_alignment;\n\n\t\t\t/* Non-canonical per-ASIC GPUVM aperture does\n\t\t\t * not exist on dGPUs in GPUVM64 address mode\n\t\t\t */\n\t\t\tgpu_mem[gpu_mem_id].gpuvm_aperture.base = NULL;\n\t\t\tgpu_mem[gpu_mem_id].gpuvm_aperture.limit = NULL;\n\n\t\t\t/* Update SVM aperture limits and alignment */\n\t\t\tif (process_apertures[i].gpuvm_base > svm_base)\n\t\t\t\tsvm_base = process_apertures[i].gpuvm_base;\n\t\t\tif (process_apertures[i].gpuvm_limit < svm_limit ||\n\t\t\t    svm_limit == 0)\n\t\t\t\tsvm_limit = process_apertures[i].gpuvm_limit;\n\t\t\tif (vm_alignment > svm_alignment)\n\t\t\t\tsvm_alignment = vm_alignment;\n\t\t} else {\n\t\t\tgpu_mem[gpu_mem_id].gpuvm_aperture.base =\n\t\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].gpuvm_base);\n\t\t\tgpu_mem[gpu_mem_id].gpuvm_aperture.limit =\n\t\t\t\tPORT_UINT64_TO_VPTR(process_apertures[i].gpuvm_limit);\n\t\t\t/* Reserve space at the start of the\n\t\t\t * aperture. After subtracting the base, we\n\t\t\t * don't want valid pointers to become NULL.\n\t\t\t */\n\t\t\taperture_allocate_area(\n\t\t\t\t&gpu_mem[gpu_mem_id].gpuvm_aperture,\n\t\t\t\tNULL,\n\t\t\t\tgpu_mem[gpu_mem_id].gpuvm_aperture.align);\n\t\t}\n\n\t\t/* Acquire the VM from the DRM render node for KFD use */\n\t\tret = acquire_vm(gpu_mem[gpu_mem_id].gpu_id,\n\t\t\t\t gpu_mem[gpu_mem_id].drm_render_fd);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto aperture_init_failed;\n\t}\n\tall_gpu_id_array_size *= sizeof(uint32_t);\n\n\tif (svm_limit) {\n\t\t/* At least one GPU uses GPUVM in canonical address\n\t\t * space. Set up SVM apertures shared by all such GPUs\n\t\t */\n\t\tret = init_svm_apertures(svm_base, svm_limit, svm_alignment,\n\t\t\t\t\t guardPages);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto init_svm_failed;\n\n\t\tfor (i = 0 ; i < num_of_sysfs_nodes ; i++) {\n\t\t\tuintptr_t alt_base;\n\t\t\tuint64_t alt_size;\n\t\t\tint err;\n\n\t\t\tif (!IS_CANONICAL_ADDR(process_apertures[i].gpuvm_limit))\n\t\t\t\tcontinue;\n\n\t\t\t/* Set memory policy to match the SVM apertures */\n\t\t\talt_base = (uintptr_t)svm.dgpu_alt_aperture->base;\n\t\t\talt_size = VOID_PTRS_SUB(svm.dgpu_alt_aperture->limit,\n\t\t\t\tsvm.dgpu_alt_aperture->base) + 1;\n\t\t\terr = fmm_set_memory_policy(process_apertures[i].gpu_id,\n\t\t\t\t\t\t    svm.disable_cache ?\n\t\t\t\t\t\t    KFD_IOC_CACHE_POLICY_COHERENT :\n\t\t\t\t\t\t    KFD_IOC_CACHE_POLICY_NONCOHERENT,\n\t\t\t\t\t\t    KFD_IOC_CACHE_POLICY_COHERENT,\n\t\t\t\t\t\t    alt_base, alt_size,\n\t\t\t\t\t\t    hsakmt_get_gfxv_by_node_id(i) == GFX_VERSION_GFX950 ?\n\t\t\t\t\t\t    mfma_high_precision_mode : 0);\n\t\t\tif (err) {\n\t\t\t\tpr_err(\"Failed to set mem policy for GPU [0x%x]\\n\",\n\t\t\t\t       process_apertures[i].gpu_id);\n\t\t\t\tret = HSAKMT_STATUS_ERROR;\n\t\t\t\tgoto set_memory_policy_failed;\n\t\t\t}\n\t\t}\n\t}\n\n\tcpuvm_aperture.align = PAGE_SIZE;\n\tcpuvm_aperture.limit = (void *)0x7FFFFFFFFFFF; /* 2^47 - 1 */\n\n\tfmm_init_rbtree();\n\n\tif (!init_mem_handle_aperture(PAGE_SIZE, guardPages))\n\t\tpr_err(\"Failed to init mem_handle_aperture\\n\");\n\n\tfor (gpu_mem_id = 0; (uint32_t)gpu_mem_id < gpu_mem_count; gpu_mem_id++) {\n\t\tif (!hsakmt_topology_is_svm_needed(gpu_mem[gpu_mem_id].EngineId))\n\t\t\tcontinue;\n\t\tgpu_mem[gpu_mem_id].mmio_aperture.base = map_mmio(\n\t\t\t\tgpu_mem[gpu_mem_id].node_id,\n\t\t\t\tgpu_mem[gpu_mem_id].gpu_id,\n\t\t\t\thsakmt_kfd_fd);\n\t\tif (gpu_mem[gpu_mem_id].mmio_aperture.base)\n\t\t\tgpu_mem[gpu_mem_id].mmio_aperture.limit = (void *)\n\t\t\t((char *)gpu_mem[gpu_mem_id].mmio_aperture.base +\n\t\t\t PAGE_SIZE - 1);\n\t\telse\n\t\t\tpr_err(\"Failed to map remapped mmio page on gpu_mem %d\\n\",\n\t\t\t\t\tgpu_mem_id);\n\t}\n\n\tfree(process_apertures);\n\treturn ret;\n\naperture_init_failed:\ninit_svm_failed:\nset_memory_policy_failed:\n\tfree(all_gpu_id_array);\n\tall_gpu_id_array = NULL;\nget_aperture_ioctl_failed:\n\tfree(process_apertures);\nsysfs_parse_failed:\ngpu_mem_init_failed:\n\thsakmt_fmm_destroy_process_apertures();\n\treturn ret;\n}\n\nvoid hsakmt_fmm_destroy_process_apertures(void)\n{\n\trelease_mmio();\n\n\tif (all_gpu_id_array) {\n\t\tfree(all_gpu_id_array);\n\t\tall_gpu_id_array = NULL;\n\t}\n\tall_gpu_id_array_size = 0;\n\n\tif (gpu_mem) {\n\t\twhile (gpu_mem_count-- > 0)\n\t\t\tfree(gpu_mem[gpu_mem_count].usable_peer_id_array);\n\t\tfree(gpu_mem);\n\t\tgpu_mem = NULL;\n\t}\n\tgpu_mem_count = 0;\n}\n\nHSAKMT_STATUS hsakmt_fmm_get_aperture_base_and_limit(aperture_type_e aperture_type, HSAuint32 gpu_id,\n\t\t\tHSAuint64 *aperture_base, HSAuint64 *aperture_limit)\n{\n\tHSAKMT_STATUS err = HSAKMT_STATUS_ERROR;\n\tint32_t slot = gpu_mem_find_by_gpu_id(gpu_id);\n\n\tif (slot < 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tswitch (aperture_type) {\n\tcase FMM_GPUVM:\n\t\tif (aperture_is_valid(gpu_mem[slot].gpuvm_aperture.base,\n\t\t\tgpu_mem[slot].gpuvm_aperture.limit)) {\n\t\t\t*aperture_base = PORT_VPTR_TO_UINT64(gpu_mem[slot].gpuvm_aperture.base);\n\t\t\t*aperture_limit = PORT_VPTR_TO_UINT64(gpu_mem[slot].gpuvm_aperture.limit);\n\t\t\terr = HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tbreak;\n\n\tcase FMM_SCRATCH:\n\t\tif (aperture_is_valid(gpu_mem[slot].scratch_aperture.base,\n\t\t\tgpu_mem[slot].scratch_aperture.limit)) {\n\t\t\t*aperture_base = PORT_VPTR_TO_UINT64(gpu_mem[slot].scratch_aperture.base);\n\t\t\t*aperture_limit = PORT_VPTR_TO_UINT64(gpu_mem[slot].scratch_aperture.limit);\n\t\t\terr = HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tbreak;\n\n\tcase FMM_LDS:\n\t\tif (aperture_is_valid(gpu_mem[slot].lds_aperture.base,\n\t\t\tgpu_mem[slot].lds_aperture.limit)) {\n\t\t\t*aperture_base = PORT_VPTR_TO_UINT64(gpu_mem[slot].lds_aperture.base);\n\t\t\t*aperture_limit = PORT_VPTR_TO_UINT64(gpu_mem[slot].lds_aperture.limit);\n\t\t\terr = HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tbreak;\n\n\tcase FMM_SVM:\n\t\t/* Report single SVM aperture, starting at base of\n\t\t * fine-grained, ending at limit of coarse-grained\n\t\t */\n\t\tif (aperture_is_valid(svm.dgpu_alt_aperture->base,\n\t\t\t\t      svm.dgpu_aperture->limit)) {\n\t\t\t*aperture_base = PORT_VPTR_TO_UINT64(svm.dgpu_alt_aperture->base);\n\t\t\t*aperture_limit = PORT_VPTR_TO_UINT64(svm.dgpu_aperture->limit);\n\t\t\terr = HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tbreak;\n\n\tcase FMM_MMIO:\n\t\tif (aperture_is_valid(gpu_mem[slot].mmio_aperture.base,\n\t\t\tgpu_mem[slot].mmio_aperture.limit)) {\n\t\t\t*aperture_base = PORT_VPTR_TO_UINT64(gpu_mem[slot].mmio_aperture.base);\n\t\t\t*aperture_limit = PORT_VPTR_TO_UINT64(gpu_mem[slot].mmio_aperture.limit);\n\t\t\terr = HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn err;\n}\n\nstatic bool id_in_array(uint32_t id, uint32_t *ids_array,\n\t\tuint32_t ids_array_size)\n{\n\tuint32_t i;\n\n\tfor (i = 0; i < ids_array_size/sizeof(uint32_t); i++) {\n\t\tif (id == ids_array[i])\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\n/* Helper function to remove ids_array from\n * obj->mapped_device_id_array\n */\nstatic void remove_device_ids_from_mapped_array(vm_object_t *obj,\n\t\tuint32_t *ids_array, uint32_t ids_array_size)\n{\n\tuint32_t i = 0, j = 0;\n\n\tif (obj->mapped_device_id_array == ids_array)\n\t\tgoto set_size_and_free;\n\n\tfor (i = 0; i < obj->mapped_device_id_array_size/\n\t\t\tsizeof(uint32_t); i++) {\n\t\tif (!id_in_array(obj->mapped_device_id_array[i],\n\t\t\t\t\tids_array, ids_array_size))\n\t\t\tobj->mapped_device_id_array[j++] =\n\t\t\t\tobj->mapped_device_id_array[i];\n\t}\n\nset_size_and_free:\n\tobj->mapped_device_id_array_size = j*sizeof(uint32_t);\n\tif (!j) {\n\t\tif (obj->mapped_device_id_array)\n\t\t\tfree(obj->mapped_device_id_array);\n\n\t\tobj->mapped_device_id_array = NULL;\n\t}\n}\n\n/* Helper function to add ids_array to\n * obj->mapped_device_id_array\n */\nstatic void add_device_ids_to_mapped_array(vm_object_t *obj,\n\t\tuint32_t *ids_array, uint32_t ids_array_size)\n{\n\tuint32_t new_array_size;\n\n\t/* Remove any potential duplicated ids */\n\tremove_device_ids_from_mapped_array(obj, ids_array, ids_array_size);\n\tnew_array_size = obj->mapped_device_id_array_size\n\t\t+ ids_array_size;\n\n\tobj->mapped_device_id_array = (uint32_t *)realloc(\n\t\t\tobj->mapped_device_id_array, new_array_size);\n\tif (!obj->mapped_device_id_array) {\n\t\t pr_err(\"Failed to allocate memory for mapped device ID array.\\n\");\n\t\t return;\n\t}\n\n\tmemcpy(&obj->mapped_device_id_array\n\t\t\t[obj->mapped_device_id_array_size/sizeof(uint32_t)],\n\t\t\tids_array, ids_array_size);\n\n\tobj->mapped_device_id_array_size = new_array_size;\n}\n\n\n/* If nodes_to_map is not NULL, map the nodes specified; otherwise map all. */\nstatic HSAKMT_STATUS _fmm_map_to_gpu(manageable_aperture_t *aperture,\n\t\t\tvoid *address, uint64_t size, vm_object_t *obj,\n\t\t\tuint32_t *nodes_to_map, uint32_t nodes_array_size)\n{\n\tstruct kfd_ioctl_map_memory_to_gpu_args args = {0};\n\tvm_object_t *object;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tint ret_ioctl;\n\tuint32_t i;\n\n\tif (!obj)\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\n\tobject = obj;\n\tif (!object) {\n\t\t/* Find the object to retrieve the handle */\n\t\tobject = vm_find_object_by_address(aperture, address, 0);\n\t\tif (!object) {\n\t\t\tret = HSAKMT_STATUS_INVALID_HANDLE;\n\t\t\tgoto err_object_not_found;\n\t\t}\n\t}\n\n\t/* For a memory region that is registered by user pointer, changing\n\t * mapping nodes is not allowed, so we don't need to check the mapping\n\t * nodes or map if it's already mapped. Just increase the reference.\n\t */\n\tif (object->userptr && object->mapping_count) {\n\t\t++object->mapping_count;\n\t\tgoto exit_ok;\n\t}\n\n\tif (nodes_to_map) {\n\t/* If specified, map the requested */\n\t\targs.device_ids_array_ptr = (uint64_t)nodes_to_map;\n\t\targs.n_devices = nodes_array_size / sizeof(uint32_t);\n\t} else if (object->registered_device_id_array_size > 0) {\n\t/* otherwise map all registered */\n\t\targs.device_ids_array_ptr =\n\t\t\t(uint64_t)object->registered_device_id_array;\n\t\targs.n_devices = object->registered_device_id_array_size /\n\t\t\tsizeof(uint32_t);\n\t} else {\n\t/* not specified, not registered: map all GPUs */\n\t\tint32_t gpu_mem_id = gpu_mem_find_by_node_id(obj->node_id);\n\n\t\tif (!obj->userptr && hsakmt_get_device_id_by_node_id(obj->node_id) &&\n\t\t    gpu_mem_id >= 0) {\n\t\t\targs.device_ids_array_ptr = (uint64_t)\n\t\t\t\tgpu_mem[gpu_mem_id].usable_peer_id_array;\n\t\t\targs.n_devices =\n\t\t\t\tgpu_mem[gpu_mem_id].usable_peer_id_num;\n\t\t} else {\n\t\t\targs.device_ids_array_ptr = (uint64_t)all_gpu_id_array;\n\t\t\targs.n_devices = all_gpu_id_array_size / sizeof(uint32_t);\n\t\t}\n\t}\n\n\tfor (i = 0; i < object->handle_num; i++) {\n\t\targs.n_success = 0;\n\t\targs.handle = object->handles[i];\n\n\t\tret_ioctl = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_MAP_MEMORY_TO_GPU, &args);\n\t\tif (ret_ioctl) {\n\t\t\tpr_err(\"GPU mapping failed (%d) for obj at %p, userptr %p, size %lu\",\n\t\t\t\tret_ioctl, object->start, object->userptr, object->size);\n\t\t\tret = HSAKMT_STATUS_ERROR;\n\t\t\tgoto err_map_failed;\n\t\t}\n\t}\n\n\tadd_device_ids_to_mapped_array(object,\n\t\t\t\t(uint32_t *)args.device_ids_array_ptr,\n\t\t\t\targs.n_success * sizeof(uint32_t));\n\tprint_device_id_array((uint32_t *)object->mapped_device_id_array,\n\t\t\t      object->mapped_device_id_array_size);\n\n\tobject->mapping_count = 1;\n\t/* Mapping changed and lifecycle of object->mapped_node_id_array\n\t * terminates here. Free it and allocate on next query\n\t */\n\tif (object->mapped_node_id_array) {\n\t\tfree(object->mapped_node_id_array);\n\t\tobject->mapped_node_id_array = NULL;\n\t}\n\nerr_map_failed:\n\twhile (ret && i--) {\n\t\targs.handle = object->handles[i];\n\t\thsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU, &args);\n\t}\nexit_ok:\nerr_object_not_found:\n\tif (!obj)\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS _fmm_map_to_gpu_scratch(uint32_t gpu_id, manageable_aperture_t *aperture,\n\t\t\t\t   void *address, uint64_t size)\n{\n\tint32_t gpu_mem_id;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tbool is_debugger = 0;\n\tuint32_t flags;\n\tvoid *mmap_ret = NULL;\n\tuint64_t mmap_offset = 0;\n\tvm_object_t *obj;\n\n\t/* Retrieve gpu_mem id according to gpu_id */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (!hsakmt_is_dgpu)\n\t\treturn HSAKMT_STATUS_SUCCESS; /* Nothing to do on APU */\n\n\t/* sanity check the address */\n\tif (address < aperture->base ||\n\t    VOID_PTR_ADD(address, size - 1) > aperture->limit)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tis_debugger = hsakmt_debug_get_reg_status(gpu_mem[gpu_mem_id].node_id);\n\tflags = is_debugger ? KFD_IOC_ALLOC_MEM_FLAGS_GTT :\n\t\t\t      KFD_IOC_ALLOC_MEM_FLAGS_VRAM;\n\tflags |= KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE;\n\t/* allocate object within the scratch backing aperture */\n\tobj = fmm_allocate_memory_object(gpu_id, address, size,\n\t\t\t\t\t aperture, &mmap_offset, flags);\n\tif (!obj)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\t/* Create a CPU mapping for the debugger */\n\tmmap_ret = fmm_map_to_cpu(address, size, is_debugger,\n\t\t\t\t  gpu_mem[gpu_mem_id].drm_render_fd,\n\t\t\t\t  mmap_offset);\n\tif (mmap_ret == MAP_FAILED) {\n\t\t__fmm_release(obj, aperture);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\t/* map to GPU */\n\tret = _fmm_map_to_gpu(aperture, address, size, NULL, &gpu_id, sizeof(uint32_t));\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t__fmm_release(obj, aperture);\n\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS _fmm_map_to_gpu_userptr(void *addr, uint64_t size,\n\t\t\t\t\t     uint64_t *gpuvm_addr, vm_object_t *object,\n\t\t\t\t\t     uint32_t *nodes_to_map, uint32_t nodes_array_size)\n{\n\tmanageable_aperture_t *aperture;\n\tvoid *svm_addr;\n\tHSAuint32 page_offset = (HSAuint64)addr & (PAGE_SIZE-1);\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\taperture = svm.dgpu_aperture;\n\n\t/* Map and return the GPUVM address adjusted by the offset\n\t * from the start of the page\n\t */\n\tif (!object && hsakmt_is_svm_api_supported) {\n\t\tsvm_addr = (void*)((HSAuint64)addr - page_offset);\n\t\tif (!nodes_to_map) {\n\t\t\tnodes_to_map = all_gpu_id_array;\n\t\t\tnodes_array_size = all_gpu_id_array_size;\n\t\t}\n\t\tpr_debug(\"%s Mapping Address %p size aligned: %ld offset: %x\\n\",\n\t\t\t__func__, svm_addr, PAGE_ALIGN_UP(page_offset + size), page_offset);\n\t\tret = fmm_map_mem_svm_api(svm_addr,\n\t\t\t\t\t\t  PAGE_ALIGN_UP(page_offset + size),\n\t\t\t\t\t\t  nodes_to_map,\n\t\t\t\t\t\t  nodes_array_size / sizeof(uint32_t));\n\n\t} else if (object) {\n\t\tsvm_addr = object->start;\n\t\tret = _fmm_map_to_gpu(aperture, svm_addr, object->size, object, NULL, 0);\n\t} else {\n\t\tpr_err(\"Object is null and SVM API is not supported.\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\tif (ret == HSAKMT_STATUS_SUCCESS && gpuvm_addr)\n\t\t*gpuvm_addr = (uint64_t)svm_addr + page_offset;\n\n\treturn ret;\n}\n\nHSAKMT_STATUS hsakmt_fmm_map_to_gpu(void *address, uint64_t size, uint64_t *gpuvm_address)\n{\n\tmanageable_aperture_t *aperture = NULL;\n\tvm_object_t *object;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tgpu_mem_t *gpu_mem_ptr = NULL;\n\n\t/* Special handling for scratch memory */\n\tgpu_mem_ptr = fmm_is_scratch_aperture(address);\n\tif (gpu_mem_ptr) {\n\t\treturn _fmm_map_to_gpu_scratch(gpu_mem_ptr->gpu_id,\n\t\t\t\t\t\t\t&gpu_mem_ptr->scratch_physical,\n\t\t\t\t\t\t\taddress, size);\n\t}\n\n\tobject = vm_find_object(address, size, &aperture);\n\tif (!object && !hsakmt_is_svm_api_supported) {\n\t\tif (!hsakmt_is_dgpu) {\n\t\t\t/* Prefetch memory on APUs with dummy-reads */\n\t\t\tfmm_check_user_memory(address, size);\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t\tpr_err(\"Object not found at %p\\n\", address);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\t/* Successful vm_find_object returns with the aperture locked */\n\n\t/* allocate VA only */\n\tif (object && object->handles[0] == 0) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\t/* allocate buffer only, should be mapped by GEM API */\n        if (aperture && (aperture == &mem_handle_aperture)) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tif (aperture && (aperture == &cpuvm_aperture)) {\n\t\t/* Prefetch memory on APUs with dummy-reads */\n\t\tfmm_check_user_memory(address, size);\n\t\tret = HSAKMT_STATUS_SUCCESS;\n\t} else if ((hsakmt_is_svm_api_supported && !object) || (object && (object->userptr))) {\n\t\tret = _fmm_map_to_gpu_userptr(address, size, gpuvm_address, object, NULL, 0);\n\t} else if (aperture) {\n\t\tret = _fmm_map_to_gpu(aperture, address, size, object, NULL, 0);\n\t\t/* Update alternate GPUVM address only for\n\t\t * CPU-invisible apertures on old APUs\n\t\t */\n\t\tif (ret == HSAKMT_STATUS_SUCCESS && gpuvm_address && !aperture->is_cpu_accessible)\n\t\t\t*gpuvm_address = VOID_PTRS_SUB(object->start, aperture->base);\n\t}\n\n\tif (object)\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nstatic void print_device_id_array(uint32_t *device_id_array, uint32_t device_id_array_size)\n{\n#ifdef DEBUG_PRINT_APERTURE\n\tdevice_id_array_size /= sizeof(uint32_t);\n\n\tpr_info(\"device id array size %d\\n\", device_id_array_size);\n\n\tfor (uint32_t i = 0 ; i < device_id_array_size; i++)\n\t\tpr_info(\"%d . 0x%x\\n\", (i+1), device_id_array[i]);\n#endif\n}\n\nstatic int _fmm_unmap_from_gpu(manageable_aperture_t *aperture, void *address,\n\t\tuint32_t *device_ids_array, uint32_t device_ids_array_size,\n\t\tvm_object_t *obj)\n{\n\tvm_object_t *object;\n\tint ret = 0, tmp_ret;\n\tuint32_t i;\n\tstruct kfd_ioctl_unmap_memory_from_gpu_args args = {0};\n\tHSAuint32 page_offset = (HSAint64)address & (PAGE_SIZE - 1);\n\n\tif (!obj)\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\n\t/* Find the object to retrieve the handle */\n\tobject = obj;\n\tif (!object) {\n\t\tobject = vm_find_object_by_address(aperture,\n\t\t\t\t\tVOID_PTR_SUB(address, page_offset), 0);\n\t\tif (!object) {\n\t\t\tret = -1;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif (object->userptr && object->mapping_count > 1) {\n\t\t--object->mapping_count;\n\t\tgoto out;\n\t}\n\n\tif (device_ids_array && device_ids_array_size > 0) {\n\t\targs.device_ids_array_ptr = (uint64_t)device_ids_array;\n\t\targs.n_devices = device_ids_array_size / sizeof(uint32_t);\n\t} else if (object->mapped_device_id_array_size > 0) {\n\t\targs.device_ids_array_ptr = (uint64_t)object->mapped_device_id_array;\n\t\targs.n_devices = object->mapped_device_id_array_size /\n\t\t\tsizeof(uint32_t);\n\t} else {\n\t\t/*\n\t\t * When unmap exits here it should return failing error code as the user tried to\n\t\t * unmap already unmapped buffer. Currently we returns success as KFDTEST and RT\n\t\t * need to deploy the change on there side before thunk fails on this case.\n\t\t */\n\t\tret = 0;\n\t\tgoto out;\n\t}\n\n\tprint_device_id_array((void *)args.device_ids_array_ptr,\n\t\t\t      args.n_devices * sizeof(uint32_t));\n\n\tfor (i = 0; i < object->handle_num; i++) {\n\t\targs.handle = object->handles[i];\n\t\targs.n_success = 0;\n\n\t\ttmp_ret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU, &args);\n\t\tif (tmp_ret)\n\t\t\tret = tmp_ret;\n\t}\n\n\tif (!ret) {\n\t\tremove_device_ids_from_mapped_array(object,\n\t\t\t\t(uint32_t *)args.device_ids_array_ptr,\n\t\t\t\targs.n_success * sizeof(uint32_t));\n\n\t\tif (object->mapped_node_id_array)\n\t\t\tfree(object->mapped_node_id_array);\n\t\tobject->mapped_node_id_array = NULL;\n\t\tobject->mapping_count = 0;\n\t}\nout:\n\tif (!obj)\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nstatic int _fmm_unmap_from_gpu_scratch(uint32_t gpu_id,\n\t\t\t\t       manageable_aperture_t *aperture,\n\t\t\t\t       void *address)\n{\n\tint32_t gpu_mem_id;\n\tvm_object_t *object;\n\tstruct kfd_ioctl_unmap_memory_from_gpu_args args = {0};\n\tint ret;\n\n\t/* Retrieve gpu_mem id according to gpu_id */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(gpu_id);\n\tif (gpu_mem_id < 0)\n\t\treturn -1;\n\n\tif (!hsakmt_is_dgpu)\n\t\treturn 0; /* Nothing to do on APU */\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\n\t/* Find the object to retrieve the handle and size */\n\tobject = vm_find_object_by_address(aperture, address, 0);\n\tif (!object) {\n\t\tret = -EINVAL;\n\t\tgoto err;\n\t}\n\n\tif (!object->mapped_device_id_array ||\n\t\t\tobject->mapped_device_id_array_size == 0) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn 0;\n\t}\n\n\t/* unmap from GPU */\n\targs.handle = object->handles[0];\n\targs.device_ids_array_ptr = (uint64_t)object->mapped_device_id_array;\n\targs.n_devices = object->mapped_device_id_array_size / sizeof(uint32_t);\n\targs.n_success = 0;\n\tret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU, &args);\n\n\t/* unmap from CPU while keeping the address space reserved */\n\tmmap(address, object->size, PROT_NONE,\n\t     MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_FIXED,\n\t     -1, 0);\n\n\tremove_device_ids_from_mapped_array(object,\n\t\t\t(uint32_t *)args.device_ids_array_ptr,\n\t\t\targs.n_success * sizeof(uint32_t));\n\n\tif (object->mapped_node_id_array)\n\t\tfree(object->mapped_node_id_array);\n\tobject->mapped_node_id_array = NULL;\n\n\tif (ret)\n\t\tgoto err;\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t/* free object in scratch backing aperture */\n\treturn __fmm_release(object, aperture);\n\nerr:\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nint hsakmt_fmm_unmap_from_gpu(void *address)\n{\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *object;\n\tint ret;\n\tgpu_mem_t *gpu_mem_ptr = NULL;\n\n\t/* Special handling for scratch memory */\n\tgpu_mem_ptr = fmm_is_scratch_aperture(address);\n\tif (gpu_mem_ptr) {\n\t\treturn _fmm_unmap_from_gpu_scratch(gpu_mem_ptr->gpu_id,\n\t\t\t\t\t\t\t&gpu_mem_ptr->scratch_physical,\n\t\t\t\t\t\t\taddress);\n\t}\n\n\tobject = vm_find_object(address, 0, &aperture);\n\tif (!object)\n\t\t/* On APUs GPU unmapping of system memory is a no-op */\n\t\treturn (!hsakmt_is_dgpu || hsakmt_is_svm_api_supported) ? 0 : -EINVAL;\n\t/* Successful vm_find_object returns with the aperture locked */\n\n\tif (aperture == &cpuvm_aperture)\n\t\t/* On APUs GPU unmapping of system memory is a no-op */\n\t\tret = 0;\n\telse\n\t\tret = _fmm_unmap_from_gpu(aperture, address, NULL, 0, object);\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\treturn ret;\n}\n\nbool hsakmt_fmm_get_handle(void *address, uint64_t *handle)\n{\n\tuint32_t i;\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *object;\n\tbool found;\n\n\tfound = false;\n\taperture = NULL;\n\n\t/* Find the aperture the requested address belongs to */\n\tfor (i = 0; i < gpu_mem_count; i++) {\n\t\tif (gpu_mem[i].gpu_id == NON_VALID_GPU_ID)\n\t\t\tcontinue;\n\n\t\tif ((address >= gpu_mem[i].gpuvm_aperture.base) &&\n\t\t\t(address <= gpu_mem[i].gpuvm_aperture.limit)) {\n\t\t\taperture = &gpu_mem[i].gpuvm_aperture;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!aperture) {\n\t\tif ((address >= svm.dgpu_aperture->base) &&\n\t\t\t(address <= svm.dgpu_aperture->limit)) {\n\t\t\taperture = svm.dgpu_aperture;\n\t\t} else if ((address >= svm.dgpu_alt_aperture->base) &&\n\t\t\t(address <= svm.dgpu_alt_aperture->limit)) {\n\t\t\taperture = svm.dgpu_alt_aperture;\n\t\t}\n\t}\n\n\tif (!aperture)\n\t\treturn false;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t/* Find the object to retrieve the handle */\n\tobject = vm_find_object_by_address(aperture, address, 0);\n\tif (object && handle) {\n\t\t*handle = object->handles[0];\n\t\tfound = true;\n\t}\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\n\treturn found;\n}\n\nstatic HSAKMT_STATUS fmm_register_user_memory(void *addr,\n\t\t\t\t\t\tHSAuint64 size,\n\t\t\t\t\t\tvm_object_t **obj_ret,\n\t\t\t\t\t\tbool coarse_grain,\n\t\t\t\t\t\tbool ext_coherent)\n{\n\tmanageable_aperture_t *aperture = svm.dgpu_aperture;\n\tHSAuint32 page_offset = (HSAuint64)addr & (PAGE_SIZE-1);\n\tHSAuint64 aligned_addr = (HSAuint64)addr - page_offset;\n\tHSAuint64 aligned_size = PAGE_ALIGN_UP(page_offset + size);\n\tvoid *svm_addr;\n\tHSAuint32 gpu_id;\n\tvm_object_t *obj, *exist_obj;\n\n\t/* Find first GPU for creating the userptr BO */\n\tif (!g_first_gpu_mem)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tgpu_id = g_first_gpu_mem->gpu_id;\n\n\t/* Optionally check that the CPU mapping is valid */\n\tif (svm.check_userptr)\n\t\tfmm_check_user_memory(addr, size);\n\n\t/* Allocate BO, userptr address is passed in mmap_offset */\n\tsvm_addr = __fmm_allocate_device(gpu_id, NULL, aligned_size, aperture,\n\t\t\t &aligned_addr, KFD_IOC_ALLOC_MEM_FLAGS_USERPTR |\n\t\t\t KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE |\n\t\t\t KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE |\n\t\t\t (coarse_grain ? 0 : KFD_IOC_ALLOC_MEM_FLAGS_COHERENT) |\n\t\t\t (ext_coherent ? KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT : 0),\n\t\t\t 0,\n\t\t\t &obj);\n\tif (!svm_addr)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tif (!obj)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\n\t/* catch the race condition where some other thread added the userptr\n\t * object already after the vm_find_object.\n\t */\n\texist_obj = vm_find_object_by_userptr(aperture, addr, size);\n\tif (exist_obj) {\n\t\t++exist_obj->registration_count;\n\t} else {\n\t\tobj->userptr = addr;\n\t\thsakmt_gpuid_to_nodeid(gpu_id, &obj->node_id);\n\t\tobj->userptr_size = size;\n\t\tobj->registration_count = 1;\n\t\tobj->user_node.key = rbtree_key((unsigned long)addr, size);\n\t\thsakmt_rbtree_insert(&aperture->user_tree, &obj->user_node);\n\t}\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\tif (exist_obj)\n\t\t__fmm_release(obj, aperture);\n\n\tif (obj_ret)\n\t\t*obj_ret = exist_obj ? exist_obj : obj;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_fmm_register_memory(void *address, uint64_t size_in_bytes,\n\t\t\t\t  uint32_t *gpu_id_array,\n\t\t\t\t  uint32_t gpu_id_array_size,\n\t\t\t\t  bool coarse_grain,\n\t\t\t\t  bool ext_coherent)\n{\n\tmanageable_aperture_t *aperture = NULL;\n\tvm_object_t *object = NULL;\n\tHSAKMT_STATUS ret;\n\n\tif (gpu_id_array_size > 0 && !gpu_id_array)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (coarse_grain && ext_coherent)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tobject = vm_find_object(address, size_in_bytes, &aperture);\n\tif (!object) {\n\t\tif (!hsakmt_is_dgpu)\n\t\t\t/* System memory registration on APUs is a no-op */\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\n\t\t/* Register a new user ptr */\n\t\tif (hsakmt_is_svm_api_supported) {\n\t\t\tret = fmm_register_mem_svm_api(address,\n\t\t\t\t\t\t\tsize_in_bytes,\n\t\t\t\t\t\t\tcoarse_grain,\n\t\t\t\t\t\t\text_coherent);\n\t\t\tif (ret == HSAKMT_STATUS_SUCCESS)\n\t\t\t\treturn ret;\n\t\t\tpr_debug(\"SVM failed, falling back to old registration\\n\");\n\t\t}\n\t\tret = fmm_register_user_memory(address,\n\t\t\t\t\t       size_in_bytes,\n\t\t\t\t\t       &object,\n\t\t\t\t\t       coarse_grain,\n\t\t\t\t\t       ext_coherent);\n\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\treturn ret;\n\t\tif (gpu_id_array_size == 0)\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\taperture = svm.dgpu_aperture;\n\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\t/* fall through for registered device ID array setup */\n\t} else if (object->userptr) {\n\t\t/* Update an existing userptr */\n\t\t++object->registration_count;\n\t} else {\n\t\t/* Not a userptr when we are expecting one */\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\t}\n\t/* Successful vm_find_object returns with aperture locked */\n\n\tif (object->registered_device_id_array_size > 0) {\n\t\t/* Multiple registration is allowed, but not changing nodes */\n\t\tif ((gpu_id_array_size != object->registered_device_id_array_size)\n\t\t\t|| memcmp(object->registered_device_id_array,\n\t\t\t\t\tgpu_id_array, gpu_id_array_size)) {\n\t\t\tpr_err(\"Cannot change nodes in a registered addr.\\n\");\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn HSAKMT_STATUS_MEMORY_ALREADY_REGISTERED;\n\t\t} else {\n\t\t\t/* Delete the new array, keep the existing one. */\n\t\t\tif (gpu_id_array)\n\t\t\t\tfree(gpu_id_array);\n\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t}\n\n\tif (gpu_id_array_size > 0) {\n\t\tobject->registered_device_id_array = gpu_id_array;\n\t\tobject->registered_device_id_array_size = gpu_id_array_size;\n\t\t/* Registration of object changed. Lifecycle of object->\n\t\t * registered_node_id_array terminates here. Free old one\n\t\t * and re-allocate on next query\n\t\t */\n\t\tif (object->registered_node_id_array) {\n\t\t\tfree(object->registered_node_id_array);\n\t\t\tobject->registered_node_id_array = NULL;\n\t\t}\n\t}\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n#define GRAPHICS_METADATA_DEFAULT_SIZE 64\nHSAKMT_STATUS hsakmt_fmm_register_graphics_handle(HSAuint64 GraphicsResourceHandle,\n\t\t\t\t\t   HsaGraphicsResourceInfo *GraphicsResourceInfo,\n\t\t\t\t\t   uint32_t *gpu_id_array,\n\t\t\t\t\t   uint32_t gpu_id_array_size,\n\t\t\t\t\t   HSA_REGISTER_MEM_FLAGS RegisterFlags)\n{\n\tstruct kfd_ioctl_get_dmabuf_info_args infoArgs = {0};\n\tstruct kfd_ioctl_import_dmabuf_args importArgs = {0};\n\tstruct kfd_ioctl_free_memory_of_gpu_args freeArgs = {0};\n\tmanageable_aperture_t *aperture;\n\tHsaMemFlags mflags;\n\tvm_object_t *obj;\n\tvoid *metadata;\n\tvoid *mem = NULL, *aperture_base = NULL;\n\tint32_t gpu_mem_id;\n\tint r;\n\tHSAKMT_STATUS status = HSAKMT_STATUS_ERROR;\n\tstatic const uint64_t IMAGE_ALIGN = 256*1024;\n\n\tif (gpu_id_array_size > 0 && !gpu_id_array)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tinfoArgs.dmabuf_fd = GraphicsResourceHandle;\n\tinfoArgs.metadata_size = GRAPHICS_METADATA_DEFAULT_SIZE;\n\tmetadata = calloc(infoArgs.metadata_size, 1);\n\tif (!metadata)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\tinfoArgs.metadata_ptr = (uint64_t)metadata;\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_DMABUF_INFO, (void *)&infoArgs);\n\tif (r && infoArgs.metadata_size > GRAPHICS_METADATA_DEFAULT_SIZE) {\n\t\t/* Try again with bigger metadata */\n\t\tfree(metadata);\n\t\tmetadata = calloc(infoArgs.metadata_size, 1);\n\t\tif (!metadata)\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\tinfoArgs.metadata_ptr = (uint64_t)metadata;\n\t\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_DMABUF_INFO, (void *)&infoArgs);\n\t}\n\n\tif (r)\n\t\tgoto error_free_metadata;\n\n\t/* Choose aperture based on GPU and allocate virtual address */\n\tgpu_mem_id = gpu_mem_find_by_gpu_id(infoArgs.gpu_id);\n\tif (gpu_mem_id < 0)\n\t\tgoto error_free_metadata;\n\n\t/* import DMA buffer without VA assigned */\n\tif (!gpu_id_array && gpu_id_array_size == 0 && !RegisterFlags.ui32.requiresVAddr) {\n\t\taperture = &mem_handle_aperture;\n\t} else if (hsakmt_topology_is_svm_needed(gpu_mem[gpu_mem_id].EngineId)) {\n\t\taperture = svm.dgpu_aperture;\n\t} else {\n\t\taperture = &gpu_mem[gpu_mem_id].gpuvm_aperture;\n\t\taperture_base = aperture->base;\n\t}\n\tif (!aperture_is_valid(aperture->base, aperture->limit))\n\t\tgoto error_free_metadata;\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tmem = aperture_allocate_area_aligned(aperture, NULL, infoArgs.size,\n\t\t\t\t\t     IMAGE_ALIGN);\n\tif (!mem) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\tgoto error_free_metadata;\n\t}\n\n\t/* Import DMA buffer */\n\tif (aperture == &mem_handle_aperture)\n\t\timportArgs.va_addr = 0;\n\telse\n\t\timportArgs.va_addr = VOID_PTRS_SUB(mem, aperture_base);\n\n\timportArgs.gpu_id = infoArgs.gpu_id;\n\timportArgs.dmabuf_fd = GraphicsResourceHandle;\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_IMPORT_DMABUF, (void *)&importArgs);\n\tif (r) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\tgoto error_release_aperture;\n\t}\n\n\t/* Atomically update and register the object */\n\tmflags = fmm_translate_ioc_to_hsa_flags(infoArgs.flags);\n\tmflags.ui32.CoarseGrain = 1;\n\tobj = aperture_allocate_object(aperture, mem, importArgs.handle,\n\t\t\t\t       infoArgs.size, mflags);\n\tif (obj) {\n\t\tobj->metadata = metadata;\n\t\tobj->registered_device_id_array = gpu_id_array;\n\t\tobj->registered_device_id_array_size = gpu_id_array_size;\n\t\thsakmt_gpuid_to_nodeid(infoArgs.gpu_id, &obj->node_id);\n\t}\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\tif (!obj)\n\t\tgoto error_release_buffer;\n\n\tGraphicsResourceInfo->MemoryAddress = mem;\n\tGraphicsResourceInfo->SizeInBytes = infoArgs.size;\n\tGraphicsResourceInfo->Metadata = (void *)(unsigned long)infoArgs.metadata_ptr;\n\tGraphicsResourceInfo->MetadataSizeInBytes = infoArgs.metadata_size;\n\thsakmt_gpuid_to_nodeid(infoArgs.gpu_id, &GraphicsResourceInfo->NodeId);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n\nerror_release_buffer:\n\tfreeArgs.handle = importArgs.handle;\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_FREE_MEMORY_OF_GPU, &freeArgs) != 0) {\n\t\t/* Handle error if memory is not freed properly */\n\t\tpr_err(\"Failed to free GPU memory\\n\");\n\t}\nerror_release_aperture:\n\taperture_release_area(aperture, mem, infoArgs.size);\nerror_free_metadata:\n\tfree(metadata);\n\n\treturn status;\n}\n\nHSAKMT_STATUS hsakmt_fmm_export_dma_buf_fd(void *MemoryAddress,\n\t\t\t\t    HSAuint64 MemorySizeInBytes,\n\t\t\t\t    int *DMABufFd,\n\t\t\t\t    HSAuint64 *Offset)\n{\n\tstruct kfd_ioctl_export_dmabuf_args exportArgs = {0};\n\tmanageable_aperture_t *aperture;\n\tHsaApertureInfo ApeInfo;\n\tvm_object_t *obj;\n\tHSAuint64 offset;\n\tint r;\n\n\taperture = fmm_find_aperture(MemoryAddress, &ApeInfo);\n\tif (!aperture)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tobj = vm_find_object_by_address_range(aperture, MemoryAddress);\n\tif (obj) {\n\t\toffset = VOID_PTRS_SUB(MemoryAddress, obj->start);\n\t\tif (offset + MemorySizeInBytes <= obj->size) {\n\t\t\texportArgs.handle = obj->handles[0];\n\t\t\texportArgs.flags = O_CLOEXEC;\n\t\t\texportArgs.dmabuf_fd = 0;\n\t\t} else {\n\t\t\tobj = NULL;\n\t\t}\n\t}\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\tif (!obj)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_EXPORT_DMABUF, (void *)&exportArgs);\n\tif (r)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t*DMABufFd = exportArgs.dmabuf_fd;\n\t*Offset = offset;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_fmm_share_memory(void *MemoryAddress,\n\t\t\t\tHSAuint64 SizeInBytes,\n\t\t\t\tHsaSharedMemoryHandle *SharedMemoryHandle)\n{\n\tint r = 0;\n\tHSAuint32 gpu_id = 0;\n\tvm_object_t *obj = NULL;\n\tmanageable_aperture_t *aperture = NULL;\n\tstruct kfd_ioctl_ipc_export_handle_args exportArgs = {0};\n\tHsaApertureInfo ApeInfo;\n\tHsaSharedMemoryStruct *SharedMemoryStruct =\n\t\tto_hsa_shared_memory_struct(SharedMemoryHandle);\n\n\tif (SizeInBytes >= (1ULL << ((sizeof(HSAuint32) * 8) + PAGE_SHIFT)))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\taperture = fmm_find_aperture(MemoryAddress, &ApeInfo);\n\tif (!aperture)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\tobj = vm_find_object_by_address(aperture, MemoryAddress, 0);\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\tif (!obj)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tr = hsakmt_validate_nodeid(obj->node_id, &gpu_id);\n\tif (r != HSAKMT_STATUS_SUCCESS)\n\t\treturn r;\n\tif (!gpu_id && hsakmt_is_dgpu) {\n\t\t/* Sharing non paged system memory. Use first GPU which was\n\t\t * used during allocation. See fmm_allocate_host_gpu()\n\t\t */\n\t\tif (!g_first_gpu_mem)\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\n\t\tgpu_id = g_first_gpu_mem->gpu_id;\n\t}\n\texportArgs.handle = obj->handles[0];\n\texportArgs.gpu_id = gpu_id;\n\texportArgs.flags = obj->mflags.Value;\n\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_IPC_EXPORT_HANDLE, (void *)&exportArgs);\n\tif (r)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemcpy(SharedMemoryStruct->ShareHandle, exportArgs.share_handle,\n\t\t\tsizeof(SharedMemoryStruct->ShareHandle));\n\tSharedMemoryStruct->ApeInfo = ApeInfo;\n\tSharedMemoryStruct->SizeInPages = (HSAuint32) (SizeInBytes >> PAGE_SHIFT);\n\tSharedMemoryStruct->ExportGpuId = gpu_id;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_fmm_register_shared_memory(const HsaSharedMemoryHandle *SharedMemoryHandle,\n\t\t\t\t\t\tHSAuint64 *SizeInBytes,\n\t\t\t\t\t\tvoid **MemoryAddress,\n\t\t\t\t\t\tuint32_t *gpu_id_array,\n\t\t\t\t\t\tuint32_t gpu_id_array_size)\n{\n\tint r = 0;\n\tHSAKMT_STATUS err = HSAKMT_STATUS_ERROR;\n\tvm_object_t *obj = NULL;\n\tvoid *reservedMem = NULL;\n\tmanageable_aperture_t *aperture;\n\tstruct kfd_ioctl_ipc_import_handle_args importArgs = {0};\n\tstruct kfd_ioctl_free_memory_of_gpu_args freeArgs = {0};\n\tconst HsaSharedMemoryStruct *SharedMemoryStruct =\n\t\tto_const_hsa_shared_memory_struct(SharedMemoryHandle);\n\tHSAuint64 SizeInPages = SharedMemoryStruct->SizeInPages;\n\tHsaMemFlags mflags;\n\n\tif (gpu_id_array_size > 0 && !gpu_id_array)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tmemcpy(importArgs.share_handle, SharedMemoryStruct->ShareHandle,\n\t\t\tsizeof(importArgs.share_handle));\n\timportArgs.gpu_id = SharedMemoryStruct->ExportGpuId;\n\n\taperture = fmm_get_aperture(SharedMemoryStruct->ApeInfo);\n\tif (!aperture)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tpthread_mutex_lock(&aperture->fmm_mutex);\n\treservedMem = aperture_allocate_area(aperture, NULL,\n\t\t\t(SizeInPages << PAGE_SHIFT));\n\tif (!reservedMem) {\n\t\terr = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err_free_buffer;\n\t}\n\n\timportArgs.va_addr = (uint64_t)reservedMem;\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_IPC_IMPORT_HANDLE, (void *)&importArgs);\n\tif (r) {\n\t\terr = HSAKMT_STATUS_ERROR;\n\t\tgoto err_import;\n\t}\n\n\tmflags.Value = importArgs.flags;\n\tobj = aperture_allocate_object(aperture, reservedMem, importArgs.handle,\n\t\t\t(SizeInPages << PAGE_SHIFT), mflags);\n\tif (!obj) {\n\t\terr = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err_free_mem;\n\t}\n\n\tif (importArgs.mmap_offset) {\n\t\tint32_t gpu_mem_id = gpu_mem_find_by_gpu_id(importArgs.gpu_id);\n\t\tvoid *ret;\n\n\t\tif (gpu_mem_id < 0) {\n\t\t\tvm_remove_object(aperture, obj);\n\t\t\taperture_release_area(aperture, reservedMem,\n\t\t\t\t\t(SizeInPages << PAGE_SHIFT));\n\t\t\terr = HSAKMT_STATUS_ERROR;\n\t\t\tgoto err_free_mem;\n\t\t}\n\t\tobj->node_id = gpu_mem[gpu_mem_id].node_id;\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\t\tret = fmm_map_to_cpu(reservedMem, (SizeInPages << PAGE_SHIFT),\n\t\t\t\ttrue, gpu_mem[gpu_mem_id].drm_render_fd,\n\t\t\t\timportArgs.mmap_offset);\n\n\t\tif (ret == MAP_FAILED) {\n\t\t\tpthread_mutex_lock(&aperture->fmm_mutex);\n\t\t\tvm_remove_object(aperture, obj);\n\t\t\taperture_release_area(aperture, reservedMem,\n\t\t\t\t\t(SizeInPages << PAGE_SHIFT));\n\t\t\terr = HSAKMT_STATUS_ERROR;\n\t\t\tgoto err_free_mem_handle;\n\t\t}\n\t} else {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t}\n\n\t*MemoryAddress = reservedMem;\n\t*SizeInBytes = (SizeInPages << PAGE_SHIFT);\n\n\tif (gpu_id_array_size > 0) {\n\t\tobj->registered_device_id_array = gpu_id_array;\n\t\tobj->registered_device_id_array_size = gpu_id_array_size;\n\t}\n\tobj->is_imported_kfd_bo = true;\n\n\treturn HSAKMT_STATUS_SUCCESS;\nerr_free_mem_handle:\n\tfreeArgs.handle = importArgs.handle;\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_FREE_MEMORY_OF_GPU, &freeArgs) != 0) {\n\t\tpr_err(\"Failed to free GPU memory for handle %llu\\n\", freeArgs.handle);\n\t}\nerr_free_mem:\nerr_free_buffer:\nerr_import:\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn err;\n}\n\nHSAKMT_STATUS hsakmt_fmm_deregister_memory(void *address)\n{\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *object;\n\n\tobject = vm_find_object(address, 0, &aperture);\n\tif (!object)\n\t\t/* On APUs we assume it's a random system memory address\n\t\t * where registration and dergistration is a no-op\n\t\t */\n\t\treturn (!hsakmt_is_dgpu || hsakmt_is_svm_api_supported) ?\n\t\t\tHSAKMT_STATUS_SUCCESS :\n\t\t\tHSAKMT_STATUS_MEMORY_NOT_REGISTERED;\n\t/* Successful vm_find_object returns with aperture locked */\n\n\tif (aperture == &cpuvm_aperture) {\n\t\t/* API-allocated system memory on APUs, deregistration\n\t\t * is a no-op\n\t\t */\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tif (object->metadata || object->userptr || object->is_imported_kfd_bo) {\n\t\t/* An object with metadata is an imported graphics\n\t\t * buffer. Deregistering imported graphics buffers or\n\t\t * userptrs means releasing the BO.\n\t\t */\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t__fmm_release(object, aperture);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tif (!object->registered_device_id_array ||\n\t\tobject->registered_device_id_array_size <= 0) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_MEMORY_NOT_REGISTERED;\n\t}\n\n\tif (object->registered_device_id_array) {\n\t\tfree(object->registered_device_id_array);\n\t\tobject->registered_device_id_array = NULL;\n\t\tobject->registered_device_id_array_size = 0;\n\t}\n\tif (object->registered_node_id_array)\n\t\tfree(object->registered_node_id_array);\n\tobject->registered_node_id_array = NULL;\n\tobject->registration_count = 0;\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/*\n * This function unmaps all nodes on current mapped nodes list that are not included on nodes_to_map\n * and maps nodes_to_map\n */\n\nHSAKMT_STATUS hsakmt_fmm_map_to_gpu_nodes(void *address, uint64_t size,\n\t\tuint32_t *nodes_to_map, uint64_t num_of_nodes,\n\t\tuint64_t *gpuvm_address)\n{\n\tmanageable_aperture_t *aperture = NULL;\n\tvm_object_t *object;\n\tuint32_t i;\n\tuint32_t *registered_node_id_array, registered_node_id_array_size;\n\tHSAKMT_STATUS ret;\n\tint retcode = 0;\n\n\tif (!num_of_nodes || !nodes_to_map || !address)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tobject = vm_find_object(address, size, &aperture);\n\tif (!object && !hsakmt_is_svm_api_supported)\n\t\treturn HSAKMT_STATUS_ERROR;\n\t/* Successful vm_find_object returns with aperture locked */\n\n\t/* allocates VA only */\n\tif (object && object->handles[0] == 0) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\t/* allocates buffer only, should be mapped by GEM API */\n\tif (aperture == &mem_handle_aperture) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\t/* APU memory is not supported by this function */\n\tif (aperture &&\n\t   (aperture == &cpuvm_aperture || !aperture->is_cpu_accessible)) {\n\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tif ((hsakmt_is_svm_api_supported && !object) || object->userptr) {\n\t\tretcode = _fmm_map_to_gpu_userptr(address, size, gpuvm_address,\n\t\t\t\tobject, nodes_to_map, num_of_nodes * sizeof(uint32_t));\n\t\tif (object)\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\treturn retcode ? HSAKMT_STATUS_ERROR : HSAKMT_STATUS_SUCCESS;\n\t}\n\n\t/* Verify that all nodes to map are registered already */\n\tregistered_node_id_array = all_gpu_id_array;\n\tregistered_node_id_array_size = all_gpu_id_array_size;\n\tif (object->registered_device_id_array_size > 0 &&\n\t\t\tobject->registered_device_id_array) {\n\t\tregistered_node_id_array = object->registered_device_id_array;\n\t\tregistered_node_id_array_size = object->registered_device_id_array_size;\n\t}\n\tfor (i = 0 ; i < num_of_nodes; i++) {\n\t\tif (!id_in_array(nodes_to_map[i], registered_node_id_array,\n\t\t\t\t\tregistered_node_id_array_size)) {\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t\t}\n\t}\n\n\t/* Unmap buffer from all nodes that have this buffer mapped that are not included on nodes_to_map array */\n\tif (object->mapped_device_id_array_size > 0) {\n\t\tuint32_t temp_node_id_array[object->mapped_device_id_array_size];\n\t\tuint32_t temp_node_id_array_size = 0;\n\n\t\tfor (i = 0 ; i < object->mapped_device_id_array_size / sizeof(uint32_t); i++) {\n\t\t\tif (!id_in_array(object->mapped_device_id_array[i],\n\t\t\t\t\tnodes_to_map,\n\t\t\t\t\tnum_of_nodes*sizeof(uint32_t)))\n\t\t\t\ttemp_node_id_array[temp_node_id_array_size++] =\n\t\t\t\t\tobject->mapped_device_id_array[i];\n\t\t}\n\t\ttemp_node_id_array_size *= sizeof(uint32_t);\n\n\t\tif (temp_node_id_array_size) {\n\t\t\tret = _fmm_unmap_from_gpu(aperture, address,\n\t\t\t\t\ttemp_node_id_array,\n\t\t\t\t\ttemp_node_id_array_size,\n\t\t\t\t\tobject);\n\t\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Remove already mapped nodes from nodes_to_map\n\t * to generate the final map list\n\t */\n\tuint32_t map_node_id_array[num_of_nodes];\n\tuint32_t map_node_id_array_size = 0;\n\n\tfor (i = 0; i < num_of_nodes; i++) {\n\t\tif (!id_in_array(nodes_to_map[i],\n\t\t\t\tobject->mapped_device_id_array,\n\t\t\t\tobject->mapped_device_id_array_size))\n\t\t\tmap_node_id_array[map_node_id_array_size++] =\n\t\t\t\tnodes_to_map[i];\n\t}\n\n\tif (map_node_id_array_size)\n\t\tretcode = _fmm_map_to_gpu(aperture, address, size, object,\n\t\t\t\tmap_node_id_array,\n\t\t\t\tmap_node_id_array_size * sizeof(uint32_t));\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\n\tif (retcode != 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_fmm_get_mem_info(const void *address, HsaPointerInfo *info)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint32_t i;\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *vm_obj;\n\n\tmemset(info, 0, sizeof(HsaPointerInfo));\n\n\tvm_obj = vm_find_object(address, UINT64_MAX, &aperture);\n\tif (!vm_obj) {\n\t\tinfo->Type = HSA_POINTER_UNKNOWN;\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\t/* Successful vm_find_object returns with the aperture locked */\n\n\tif (vm_obj->is_imported_kfd_bo)\n\t\tinfo->Type = HSA_POINTER_REGISTERED_SHARED;\n\telse if (vm_obj->metadata)\n\t\tinfo->Type = HSA_POINTER_REGISTERED_GRAPHICS;\n\telse if (vm_obj->userptr)\n\t\tinfo->Type = HSA_POINTER_REGISTERED_USER;\n\telse if (vm_obj->handles[0] == 0)\n\t\tinfo->Type = HSA_POINTER_RESERVED_ADDR;\n\telse\n\t\tinfo->Type = HSA_POINTER_ALLOCATED;\n\n\tinfo->Node = vm_obj->node_id;\n\tinfo->GPUAddress = (HSAuint64)vm_obj->start;\n\tinfo->SizeInBytes = vm_obj->size;\n\t/* registered nodes */\n\tinfo->NRegisteredNodes =\n\t\tvm_obj->registered_device_id_array_size / sizeof(uint32_t);\n\tif (info->NRegisteredNodes && !vm_obj->registered_node_id_array) {\n\t\tvm_obj->registered_node_id_array = (uint32_t *)\n\t\t\t(uint32_t *)malloc(vm_obj->registered_device_id_array_size);\n\t\tif (!vm_obj->registered_node_id_array) {\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\t}\n\t\t/* vm_obj->registered_node_id_array allocated here will be\n\t\t * freed whenever the registration is changed (deregistration or\n\t\t * register to new nodes) or the memory being freed\n\t\t */\n\t\tfor (i = 0; i < info->NRegisteredNodes; i++)\n\t\t\thsakmt_gpuid_to_nodeid(vm_obj->registered_device_id_array[i],\n\t\t\t\t&vm_obj->registered_node_id_array[i]);\n\t}\n\tinfo->RegisteredNodes = vm_obj->registered_node_id_array;\n\t/* mapped nodes */\n\tinfo->NMappedNodes =\n\t\tvm_obj->mapped_device_id_array_size / sizeof(uint32_t);\n\tif (info->NMappedNodes && !vm_obj->mapped_node_id_array) {\n\t\tvm_obj->mapped_node_id_array =\n\t\t\t(uint32_t *)malloc(vm_obj->mapped_device_id_array_size);\n\t\tif (!vm_obj->mapped_node_id_array) {\n\t\t\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\t}\n\t\t/* vm_obj->mapped_node_id_array allocated here will be\n\t\t * freed whenever the mapping is changed (unmapped or map\n\t\t * to new nodes) or memory being freed\n\t\t */\n\t\tfor (i = 0; i < info->NMappedNodes; i++)\n\t\t\thsakmt_gpuid_to_nodeid(vm_obj->mapped_device_id_array[i],\n\t\t\t\t&vm_obj->mapped_node_id_array[i]);\n\t}\n\tinfo->MappedNodes = vm_obj->mapped_node_id_array;\n\tinfo->UserData = vm_obj->user_data;\n\n\tinfo->MemFlags = vm_obj->mflags;\n\n\tif (info->Type == HSA_POINTER_REGISTERED_USER) {\n\t\tinfo->CPUAddress = vm_obj->userptr;\n\t\tinfo->SizeInBytes = vm_obj->userptr_size;\n\t\tinfo->GPUAddress += ((HSAuint64)info->CPUAddress & (PAGE_SIZE - 1));\n\t} else if (info->Type == HSA_POINTER_ALLOCATED) {\n\t\tinfo->CPUAddress = vm_obj->start;\n\t}\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\n#ifdef SANITIZER_AMDGPU\nHSAKMT_STATUS hsakmt_fmm_replace_asan_header_page(void* address)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tmanageable_aperture_t* aperture;\n\tvm_object_t* vm_obj;\n\n\tvm_obj = vm_find_object(address, UINT64_MAX, &aperture);\n\tif (!vm_obj)\n\t\treturn HSAKMT_STATUS_ERROR;\n\t/* Successful vm_find_object returns with the aperture locked */\n\n\t/* If this is a GPU-mapped memory, remap the first page to be normal system memory*/\n\tif (vm_obj->mmap_fd) {\n\t\tvoid* p = mmap(address,\n\t\t\t\tPAGE_SIZE,\n\t\t\t\tPROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,\n\t\t\t\t-1,\n\t\t\t\t0);\n\n\t\tif (p == MAP_FAILED)\n\t\t\tret = HSAKMT_STATUS_ERROR;\n\t}\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n\nHSAKMT_STATUS hsakmt_fmm_return_asan_header_page(void* address)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tmanageable_aperture_t* aperture;\n\tvm_object_t* vm_obj;\n\n\tvm_obj = vm_find_object(address, UINT64_MAX, &aperture);\n\tif (!vm_obj)\n\t\treturn HSAKMT_STATUS_ERROR;\n\t/* Successful vm_find_object returns with the aperture locked */\n\n\t/* If this is a GPU-mapped memory, remap the first page back to the original GPU memory*/\n\tif (vm_obj->mmap_fd) {\n\t\toff_t mmap_offset = vm_obj->mmap_offset + ((char*)address - (char*)vm_obj->start);\n\t\tvoid* p = mmap(address,\n\t\t\t\tPAGE_SIZE,\n\t\t\t\tvm_obj->mmap_flags,\n\t\t\t\tMAP_SHARED | MAP_FIXED,\n\t\t\t\tvm_obj->mmap_fd,\n\t\t\t\tmmap_offset);\n\n\t\tif (p == MAP_FAILED)\n\t\t\tret = HSAKMT_STATUS_ERROR;\n\t}\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn ret;\n}\n#endif\n\nHSAKMT_STATUS hsakmt_fmm_set_mem_user_data(const void *mem, void *usr_data)\n{\n\tmanageable_aperture_t *aperture;\n\tvm_object_t *vm_obj;\n\n\tvm_obj = vm_find_object(mem, 0, &aperture);\n\tif (!vm_obj)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tvm_obj->user_data = usr_data;\n\n\tpthread_mutex_unlock(&aperture->fmm_mutex);\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic void fmm_clear_aperture(manageable_aperture_t *app)\n{\n\trbtree_node_t *n;\n\n\tpthread_mutex_init(&app->fmm_mutex, NULL);\n\n\twhile ((n = rbtree_node_any(&app->tree, MID)))\n\t\tvm_remove_object(app, vm_object_entry(n, 0));\n\n\twhile (app->vm_ranges) {\n\t\tvoid *next_range = app->vm_ranges->next;\n\t\tvm_remove_area(app, app->vm_ranges);\n\t\tapp->vm_ranges = next_range;\n\t}\n}\n\n/* This is a special funcion that should be called only from the child process\n * after a fork(). This will clear all vm_objects and mmaps duplicated from\n * the parent.\n */\nvoid hsakmt_fmm_clear_all_mem(void)\n{\n\tuint32_t i;\n\tvoid *map_addr;\n\n\t/* Close render node FDs. The child process needs to open new ones */\n\tfor (i = 0; i <= DRM_LAST_RENDER_NODE - DRM_FIRST_RENDER_NODE; i++) {\n\n\t\tif (amdgpu_handle[i]) {\n\t\t\tamdgpu_device_deinitialize(amdgpu_handle[i]);\n\t\t\tamdgpu_handle[i] = NULL;\n\t\t} else if (drm_render_fds[i]) {\n\t\t\tclose(drm_render_fds[i]);\n\t\t}\n\t\tdrm_render_fds[i] = 0;\n\t}\n\n\tfmm_clear_aperture(&mem_handle_aperture);\n\tfmm_clear_aperture(&cpuvm_aperture);\n\tfmm_clear_aperture(&svm.apertures[SVM_DEFAULT]);\n\tfmm_clear_aperture(&svm.apertures[SVM_COHERENT]);\n\n\tif (dgpu_shared_aperture_limit) {\n\t\t/* Use the same dgpu range as the parent. If failed, then set\n\t\t * hsakmt_is_dgpu_mem_init to false. Later on dgpu_mem_init will try\n\t\t * to get a new range\n\t\t */\n\t\tmap_addr = mmap(dgpu_shared_aperture_base, (HSAuint64)(dgpu_shared_aperture_limit)-\n\t\t\t(HSAuint64)(dgpu_shared_aperture_base) + 1, PROT_NONE,\n\t\t\tMAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE | MAP_FIXED, -1, 0);\n\n\t\tif (map_addr == MAP_FAILED) {\n\t\t\tmunmap(dgpu_shared_aperture_base,\n\t\t\t\t   (HSAuint64)(dgpu_shared_aperture_limit) -\n\t\t\t\t   (HSAuint64)(dgpu_shared_aperture_base) + 1);\n\n\t\t\tdgpu_shared_aperture_base = NULL;\n\t\t\tdgpu_shared_aperture_limit = NULL;\n\t\t}\n\t}\n\n\t/* Nothing is initialized. */\n\tif (!gpu_mem)\n\t\treturn;\n\n\tfor (i = 0; i < gpu_mem_count; i++) {\n\t\tfmm_clear_aperture(&gpu_mem[i].gpuvm_aperture);\n\t\tfmm_clear_aperture(&gpu_mem[i].scratch_physical);\n\t}\n\n\thsakmt_fmm_destroy_process_apertures();\n}\n"
  },
  {
    "path": "libhsakmt/src/fmm.h",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef FMM_H_\n#define FMM_H_\n\n#include \"hsakmt/hsakmttypes.h\"\n#include <stddef.h>\n\ntypedef enum {\n\tFMM_FIRST_APERTURE_TYPE = 0,\n\tFMM_GPUVM = FMM_FIRST_APERTURE_TYPE,\n\tFMM_LDS,\n\tFMM_SCRATCH,\n\tFMM_SVM,\n\tFMM_MMIO,\n\tFMM_LAST_APERTURE_TYPE\n} aperture_type_e;\n\ntypedef struct {\n\taperture_type_e app_type;\n\tuint64_t size;\n\tvoid *start_address;\n} aperture_properties_t;\n\nHSAKMT_STATUS hsakmt_fmm_get_amdgpu_device_handle(uint32_t node_id,  HsaAMDGPUDeviceHandle *DeviceHandle);\nHSAKMT_STATUS hsakmt_fmm_init_process_apertures(unsigned int NumNodes);\nvoid hsakmt_fmm_destroy_process_apertures(void);\n\n/* Memory interface */\nvoid *hsakmt_fmm_allocate_scratch(uint32_t gpu_id, void *address, uint64_t MemorySizeInBytes);\nvoid *hsakmt_fmm_allocate_device(uint32_t gpu_id, uint32_t node_id, void *address,\n\t\t\tuint64_t MemorySizeInBytes, uint64_t alignment, HsaMemFlags flags);\nvoid *hsakmt_fmm_allocate_doorbell(uint32_t gpu_id, uint64_t MemorySizeInBytes, uint64_t doorbell_offset);\nvoid *hsakmt_fmm_allocate_host(uint32_t gpu_id, uint32_t node_id, void *address, uint64_t MemorySizeInBytes,\n\t\t\tuint64_t alignment, HsaMemFlags flags);\nvoid hsakmt_fmm_print(uint32_t node);\nHSAKMT_STATUS hsakmt_fmm_release(void *address);\nHSAKMT_STATUS hsakmt_fmm_map_to_gpu(void *address, uint64_t size, uint64_t *gpuvm_address);\nint hsakmt_fmm_unmap_from_gpu(void *address);\nbool hsakmt_fmm_get_handle(void *address, uint64_t *handle);\nHSAKMT_STATUS hsakmt_fmm_get_mem_info(const void *address, HsaPointerInfo *info);\nHSAKMT_STATUS hsakmt_fmm_set_mem_user_data(const void *mem, void *usr_data);\n#ifdef SANITIZER_AMDGPU\nHSAKMT_STATUS hsakmt_fmm_replace_asan_header_page(void* address);\nHSAKMT_STATUS hsakmt_fmm_return_asan_header_page(void* address);\n#endif\n\n/* Topology interface*/\nHSAKMT_STATUS hsakmt_fmm_get_aperture_base_and_limit(aperture_type_e aperture_type, HSAuint32 gpu_id,\n\t\tHSAuint64 *aperture_base, HSAuint64 *aperture_limit);\n\nHSAKMT_STATUS hsakmt_fmm_register_memory(void *address, uint64_t size_in_bytes,\n\t\t\t\t\t\t\t\t  uint32_t *gpu_id_array,\n\t\t\t\t\t\t\t\t  uint32_t gpu_id_array_size,\n\t\t\t\t\t\t\t\t  bool coarse_grain,\n\t\t\t\t\t\t\t\t  bool ext_coherent);\nHSAKMT_STATUS hsakmt_fmm_register_graphics_handle(HSAuint64 GraphicsResourceHandle,\n\t\t\t\t\t   HsaGraphicsResourceInfo *GraphicsResourceInfo,\n\t\t\t\t\t   uint32_t *gpu_id_array,\n\t\t\t\t\t   uint32_t gpu_id_array_size,\n\t\t\t\t\t   HSA_REGISTER_MEM_FLAGS RegisterFlags);\nHSAKMT_STATUS hsakmt_fmm_deregister_memory(void *address);\nHSAKMT_STATUS hsakmt_fmm_export_dma_buf_fd(void *MemoryAddress,\n\t\t\t\t    HSAuint64 MemorySizeInBytes,\n\t\t\t\t    int *DMABufFd,\n\t\t\t\t    HSAuint64 *Offset);\nHSAKMT_STATUS hsakmt_fmm_share_memory(void *MemoryAddress,\n\t\t\t       HSAuint64 SizeInBytes,\n\t\t\t       HsaSharedMemoryHandle *SharedMemoryHandle);\nHSAKMT_STATUS hsakmt_fmm_register_shared_memory(const HsaSharedMemoryHandle *SharedMemoryHandle,\n\t\t\t\t\t HSAuint64 *SizeInBytes,\n\t\t\t\t\t void **MemoryAddress,\n\t\t\t\t\t uint32_t *gpu_id_array,\n\t\t\t\t\t uint32_t gpu_id_array_size);\nHSAKMT_STATUS hsakmt_fmm_map_to_gpu_nodes(void *address, uint64_t size,\n\t\tuint32_t *nodes_to_map, uint64_t num_of_nodes, uint64_t *gpuvm_address);\n\nint hsakmt_open_drm_render_device(int minor);\nvoid *hsakmt_mmap_allocate_aligned(int prot, int flags, uint64_t size, uint64_t align,\n\t\t\t    uint64_t guard_size, void *aper_base, void *aper_limit, int fd);\n\nextern int (*hsakmt_fn_amdgpu_device_get_fd)(HsaAMDGPUDeviceHandle device_handle);\n#endif /* FMM_H_ */\n"
  },
  {
    "path": "libhsakmt/src/globals.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n\n// HSAKMT global data\n\nint hsakmt_kfd_fd = -1;\nint hsakmt_udmabuf_dev_fd = -1;\nunsigned long hsakmt_kfd_open_count;\nunsigned long hsakmt_system_properties_count;\npthread_mutex_t hsakmt_mutex = PTHREAD_MUTEX_INITIALIZER;\nbool hsakmt_is_dgpu;\n\nint hsakmt_page_size;\nint hsakmt_page_shift;\n\n/* whether to check all dGPUs in the topology support SVM API */\nbool hsakmt_is_svm_api_supported;\n/* zfb is mainly used during emulation */\nint hsakmt_zfb_support;\n"
  },
  {
    "path": "libhsakmt/src/hsakmtmodel.c",
    "content": "/*\n * Copyright © 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmtmodel.h\"\n#include \"libhsakmt.h\"\n#include \"hsakmt/hsakmttypes.h\"\n#include \"hsakmt/hsakmtmodeliface.h\"\n#define _GNU_SOURCE\n#define __USE_GNU\n#include <assert.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <dlfcn.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n\nbool hsakmt_use_model;\nchar *hsakmt_model_topology;\n\nstruct model_node\n{\n\tbool is_gpu;\n\tvoid *aperture;\n\thsakmt_model_t *model;\n\tuint64_t doorbell_offset;\n\tuint64_t total_memory_size;\n\tuint64_t allocated_memory_size;\n};\n\nstruct model_event\n{\n\tuint32_t event_type;\n\tuint32_t auto_reset;\n\tuint64_t value;\n};\n\nstruct model_mem_data\n{\n\tuint64_t va_addr;\n\tuint64_t file_offset;\n\tuint64_t size;\n\tuint64_t mapped_nodes_bitmask;\n\tuint32_t flags;\n\tuint32_t node_id;\n};\n\nstruct model_queue\n{\n\thsakmt_model_queue_t *queue;\n\tuint32_t node_id;\n};\n\n#define MAX_MODEL_QUEUES 128\n// Use a 256GB aperture for the model.\n#define MODEL_APERTURE_SIZE (1llu << 38)\nstatic void *model_mmio_page;\nstatic pthread_mutex_t model_ioctl_mutex = PTHREAD_MUTEX_INITIALIZER;\nstatic unsigned model_event_limit;\nstatic uint64_t *model_event_bitmap;\nstatic struct model_event *model_events;\nstatic pthread_cond_t model_event_condvar;\nstatic void *model_library;\nstatic const struct hsakmt_model_functions *model_functions;\nstatic uint64_t model_memfd_size;\nstatic uint64_t model_num_nodes;\nstatic struct model_node *model_nodes;\nstatic struct model_queue model_queues[MAX_MODEL_QUEUES];\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtModelEnabled(bool* enable)\n{\n\t*enable = hsakmt_use_model;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nvoid model_init_env_vars(void)\n{\n\t/* Check whether to use a model instead of real hardware */\n\thsakmt_model_topology = getenv(\"HSA_MODEL_TOPOLOGY\");\n\tif (hsakmt_model_topology)\n\t\thsakmt_use_model = true;\n\tif (hsakmt_use_model)\n\t{\n\t\t/* Backing memory file is used to stand in for the kfd_fd,\n\t\t * which is needed early, so create it already.\n\t\t *\n\t\t * For old systems without memfd_create, or if the user prefers,\n\t\t * we create a regular backing file. Prefer to use memfd_create\n\t\t * by default where possible.\n\t\t */\n\t\tint fd = -1;\n\t\tconst char *fname = getenv(\"HSA_MODEL_MEMFILE\");\n\t\tif (fname)\n\t\t{\n\t\t\tfprintf(stderr, \"model: use memory backing file given in HSA_MODEL_MEMFILE: %s\\n\", fname);\n\n\t\t\tfd = open(fname, O_CREAT | O_EXCL | O_CLOEXEC | O_RDWR, S_IRUSR | S_IWUSR);\n\t\t\tif (fd < 0)\n\t\t\t{\n\t\t\t\tperror(\"model: failed to create backing file\");\n\t\t\t\tabort();\n\t\t\t}\n\n\t\t\tunlink(fname);\n\t\t}\n\n\t\tif (fd < 0)\n\t\t{\n#ifdef HAVE_MEMFD_CREATE\n\t\t\tfd = memfd_create(\"hsakmt_model\", MFD_CLOEXEC);\n\t\t\tif (fd < 0)\n\t\t\t{\n\t\t\t\tfprintf(stderr, \"model: Failed to create memfd\\n\");\n\t\t\t\tabort();\n\t\t\t}\n#else\n\t\t\tfprintf(stderr, \"model: built without memfd support\\n\"\n\t\t\t\t\t\t\t\"model: set HSA_MODEL_MEMFILE to path of a backing file\\n\");\n\t\t\tabort();\n#endif\n\t\t}\n\t\tassert(hsakmt_kfd_fd < 0);\n\t\thsakmt_kfd_fd = fd;\n\t\tpthread_condattr_t condattr;\n\t\tpthread_condattr_init(&condattr);\n\t\tpthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);\n\t\tpthread_cond_init(&model_event_condvar, &condattr);\n\t\tpthread_condattr_destroy(&condattr);\n\t\tconst char *libname = getenv(\"HSA_MODEL_LIB\");\n\t\tif (!libname)\n\t\t{\n\t\t\tfprintf(stderr, \"model: HSA_MODEL_LIB environment variable must be set to FFM .so\\n\");\n\t\t\tabort();\n\t\t}\n\t\t// model_library = dlmopen(LM_ID_NEWLM, libname, RTLD_NOW);\n\t\tmodel_library = dlopen(libname, RTLD_NOW | RTLD_LOCAL);\n\t\tif (!model_library)\n\t\t{\n\t\t\tfprintf(stderr, \"model: failed to load %s: %s\\n\", libname, dlerror());\n\t\t\tabort();\n\t\t}\n\t\tget_hsakmt_model_functions_t getter = dlsym(model_library, \"get_hsakmt_model_functions\");\n\t\tif (!getter)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Failed to get hsakmt_model_functions\\n\");\n\t\t\tabort();\n\t\t}\n\t\tmodel_functions = getter();\n\t\tif (model_functions->version_major != HSAKMT_MODEL_INTERFACE_VERSION_MAJOR ||\n\t\t\tmodel_functions->version_minor < HSAKMT_MODEL_INTERFACE_VERSION_MINOR)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Model has interface version %u.%u, need version %u.%u\\n\",\n\t\t\t\t\tmodel_functions->version_major, model_functions->version_minor,\n\t\t\t\t\tHSAKMT_MODEL_INTERFACE_VERSION_MAJOR, HSAKMT_MODEL_INTERFACE_VERSION_MINOR);\n\t\t\tabort();\n\t\t}\n\t}\n}\n\nstatic uint64_t allocate_from_memfd(uint64_t size, uint64_t align)\n{\n\tif (!align)\n\t\talign = 4096;\n\tassert(POWER_OF_2(align)); /* must be power of two */\n\tassert(align >= 4096);\n\tsize = (size + 4095) & ~4095;\n\tmodel_memfd_size = (model_memfd_size + align - 1) & ~(align - 1);\n\tuint64_t offset = model_memfd_size;\n\tmodel_memfd_size += size;\n\tint ret = ftruncate(hsakmt_kfd_fd, model_memfd_size);\n\tif (ret < 0)\n\t{\n\t\tfprintf(stderr, \"model: ftruncate on memfd failed\\n\");\n\t\tabort();\n\t}\n\treturn offset;\n}\nstatic uint64_t get_sysfs_mem_bank_size(unsigned node_id, unsigned mem_id)\n{\n\tchar prop_name[256];\n\tchar path[256];\n\tsnprintf(path, sizeof(path), \"%s/nodes/%u/mem_banks/%u/properties\",\n\t\t\t hsakmt_model_topology, node_id, mem_id);\n\tFILE *f = fopen(path, \"r\");\n\tif (!f)\n\t{\n\t\tfprintf(stderr, \"model: Failed to open %s\\n\", path);\n\t\tabort();\n\t}\n\tuint64_t prop_val;\n\twhile (fscanf(f, \"%s %\" PRIu64 \"\\n\", prop_name, &prop_val) == 2)\n\t{\n\t\tif (!strcmp(prop_name, \"size_in_bytes\"))\n\t\t{\n\t\t\tfclose(f);\n\t\t\treturn prop_val;\n\t\t}\n\t}\n\tfprintf(stderr, \"model: Missing size_in_bytes in %s\\n\", path);\n\tabort();\n}\n\nstatic void model_set_event(void *data, unsigned event_id)\n{\n\tif (!event_id)\n\t\treturn;\n\n\tif (event_id > model_event_limit)\n\t{\n\t\tfprintf(stderr, \"model_set_event: event_id = %u out of bounds\\n\",\n\t\t\t\tevent_id);\n\t\tabort();\n\t}\n\n\tunsigned slot = event_id - 1;\n\n\tif (!((model_event_bitmap[slot / 64] >> (slot % 64)) & 1))\n\t{\n\t\tfprintf(stderr, \"model_set_event: event_id = %u is not allocated\\n\",\n\t\t\t\tevent_id);\n\t\tabort();\n\t}\n\n\tstruct model_event *event = &model_events[slot];\n\tif (event->event_type == HSA_EVENTTYPE_SIGNAL)\n\t{\n\t\tassert(model_events[slot].value <= 1);\n\t\tmodel_events[slot].value = 1;\n\t}\n\telse\n\t{\n\t\tfprintf(stderr, \"model: Unimplemented event type\\n\");\n\t\tabort();\n\t}\n\n\tpthread_cond_broadcast(&model_event_condvar);\n}\n\nvoid model_init(void)\n{\n\tif (!hsakmt_use_model)\n\t\treturn;\n\tHSAKMT_STATUS result;\n\tHsaSystemProperties props;\n\t/* Read the topology to determine nodes. */\n\tresult = hsakmt_topology_sysfs_get_system_props(&props);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t{\n\t\tfprintf(stderr, \"model: Failed to parse topology\\n\");\n\t\tabort();\n\t}\n\tmodel_nodes = calloc(props.NumNodes, sizeof(*model_nodes));\n\tif (!model_nodes)\n\t\tabort();\n\tmodel_num_nodes = props.NumNodes;\n\tfor (unsigned node_id = 0; node_id < props.NumNodes; node_id++)\n\t{\n\t\tHsaNodeProperties node_props;\n\t\tresult = hsakmt_topology_get_node_props(node_id, &node_props);\n\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Failed to get node %u properties\\n\", node_id);\n\t\t\tabort();\n\t\t}\n\t\tif (node_props.KFDGpuID == 0)\n\t\t\tcontinue;\n\t\tif (node_props.KFDGpuID != node_id + 1)\n\t\t{\n\t\t\tfprintf(stderr,\n\t\t\t\t\t\"model: Node %u has KFD GPU ID %u, but should be %u.\"\n\t\t\t\t\t\" Please change the gpu_id file.\\n\",\n\t\t\t\t\tnode_id, node_props.KFDGpuID, node_id + 1);\n\t\t\tabort();\n\t\t}\n\t\tmodel_nodes[node_id].is_gpu = true;\n\t\t/* Reserve the VA space for the aperture, but don't fill it with pages. */\n\t\tmodel_nodes[node_id].aperture =\n\t\t\tmmap(NULL, MODEL_APERTURE_SIZE, PROT_NONE,\n\t\t\t\t MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, -1, 0);\n\t\tpr_debug(\"Modeling Creating Memory Aperture: %p\\n\", model_nodes[node_id].aperture);\n\t\tif (model_nodes[node_id].aperture == MAP_FAILED)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Failed to reserve aperture via mmap\\n\");\n\t\t\tabort();\n\t\t}\n\t\t/* Create the doorbell region */\n\t\tmodel_nodes[node_id].doorbell_offset = allocate_from_memfd(8192, 8192);\n\t\tfor (unsigned mem_id = 0; mem_id < node_props.NumMemoryBanks; ++mem_id)\n\t\t{\n\t\t\tmodel_nodes[node_id].total_memory_size += get_sysfs_mem_bank_size(node_id, mem_id);\n\t\t}\n\t\t/* Create the model */\n\t\t// TODO: Move this into a separate thread\n\t\tmodel_nodes[node_id].model = model_functions->create();\n\t\tif (!model_nodes[node_id].model)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Failed to create model\\n\");\n\t\t\tabort();\n\t\t}\n\t\tmodel_functions->set_global_aperture(model_nodes[node_id].model,\n\t\t\t\t\t\t\t\t\t\t\t model_nodes[node_id].aperture,\n\t\t\t\t\t\t\t\t\t\t\t MODEL_APERTURE_SIZE);\n\n\t\tmodel_functions->set_set_event(model_nodes[node_id].model, model_set_event, NULL);\n\t}\n}\nvoid model_set_mmio_page(void *ptr)\n{\n\tassert(!model_mmio_page);\n\tmodel_mmio_page = ptr;\n}\nvoid model_set_event_page(void *ptr, unsigned event_limit)\n{\n\t// TODO: Fully understand what's happening with this page and the event limit.\n\t//       ROCR-Runtime allocates a pool of 4096 events, but also a handful or so\n\t//       of additional events, which blows through the event_limit of 4096\n\t//       that is passed here. And it seems that not using the page at all\n\t//       is supported?\n\tassert(!model_event_limit);\n\tassert(event_limit % 64 == 0);\n\tevent_limit *= 2;\n\tmodel_event_limit = event_limit;\n\tmodel_event_bitmap = calloc(event_limit / 64, 8);\n\tmodel_events = calloc(event_limit, sizeof(*model_events));\n}\n/* Model implementation of KFD ioctl. */\n\nstatic int model_kfd_ioctl_locked(unsigned long request, void *arg)\n{\n\tassert(_IOC_TYPE(request) == AMDKFD_IOCTL_BASE);\n\tif (_IOC_NR(request) == 0x20)\n\t{\n\t\t// This is AMDKFD_IOC_SVM. It is defined / used in an unusual way.\n\t\tstruct kfd_ioctl_svm_args *args = arg;\n\t\tif (args->op == KFD_IOCTL_SVM_OP_SET_ATTR)\n\t\t{\n\t\t\t// todo?\n\t\t\treturn 0;\n\t\t}\n\t\tfprintf(stderr, \"model: Unimplemented SVM op\\n\");\n\t\tabort();\n\t}\n\tswitch (request)\n\t{\n\tcase AMDKFD_IOC_GET_VERSION:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_GET_VERSION\\n\");\n\t\tstruct kfd_ioctl_get_version_args *args = arg;\n\t\targs->major_version = 1;\n\t\targs->minor_version = 14;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_GET_PROCESS_APERTURES_NEW:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_GET_PROCESS_APERTURES_NEW\\n\");\n\t\tstruct kfd_ioctl_get_process_apertures_new_args *args = arg;\n\t\tstruct kfd_process_device_apertures *apertures =\n\t\t\t(void *)args->kfd_process_device_apertures_ptr;\n\t\tassert(args->num_of_nodes == model_num_nodes);\n\t\tfor (unsigned node_id = 0; node_id < args->num_of_nodes; ++node_id)\n\t\t{\n\t\t\tmemset(&apertures[node_id], 0, sizeof(apertures[node_id]));\n\t\t\tif (!model_nodes[node_id].is_gpu)\n\t\t\t\tcontinue;\n\t\t\tapertures[node_id].gpu_id = 1 + node_id;\n\t\t\tapertures[node_id].gpuvm_base = 0x4000llu;\n\t\t\tapertures[node_id].gpuvm_limit = MODEL_APERTURE_SIZE;\n\t\t\tapertures[node_id].lds_base = 0x4000000000000000llu; // 0x1000000000000?\n\t\t\tapertures[node_id].lds_limit = 0x40000000ffffffffllu;\n\t\t\tapertures[node_id].scratch_base = 0x5000000000000000llu; // 0x2000000000000?\n\t\t\tapertures[node_id].scratch_limit = 0x50000000ffffffffllu;\n\t\t}\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_SET_XNACK_MODE:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_SET_XNACK_MODE\\n\");\n\t\t// Don't support XNACK\n\t\tstruct kfd_ioctl_set_xnack_mode_args *args = arg;\n\t\tif (args->xnack_enabled < 0)\n\t\t{\n\t\t\targs->xnack_enabled = 0;\n\t\t\treturn 0;\n\t\t}\n\t\terrno = EPERM;\n\t\treturn -1;\n\t}\n\tcase AMDKFD_IOC_GET_CLOCK_COUNTERS:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_GET_CLOCK_COUNTERS\\n\");\n\t\tstruct kfd_ioctl_get_clock_counters_args *args = arg;\n\t\targs->gpu_clock_counter = 0; // TODO\n\t\targs->cpu_clock_counter = 0;\n\t\targs->system_clock_counter = 0;\n\t\targs->system_clock_freq = 0;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_ACQUIRE_VM:\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_ACQUIRE_VM\\n\");\n\t\treturn 0;\n\tcase AMDKFD_IOC_SET_MEMORY_POLICY:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_SET_MEMORY_POLICY\\n\");\n\t\t// todo?\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_AVAILABLE_MEMORY:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_AVAILABLE_MEMORY\\n\");\n\t\tstatic const uint64_t minimum_reported = 128 * 1024 * 1024;\n\t\tstruct kfd_ioctl_get_available_memory_args *args = arg;\n\t\tunsigned node_id = args->gpu_id - 1;\n\t\tstruct model_node *node = &model_nodes[node_id];\n\t\tassert(node_id < model_num_nodes);\n\t\tif (node->allocated_memory_size + minimum_reported >= node->total_memory_size)\n\t\t\targs->available = minimum_reported;\n\t\telse\n\t\t\targs->available = node->total_memory_size - node->allocated_memory_size;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_ALLOC_MEMORY_OF_GPU:\n\t{\n\t\t// Expect an SVM style allocation: The memory is allocated on the host\n\t\t// side e.g. via mmap(), and this IOCTL \"only\" registers the memory\n\t\t// with the GPU. This is a no-op for us because we aren't a GPU.\n\t\tstruct kfd_ioctl_alloc_memory_of_gpu_args *args = arg;\n\t\tunsigned node_id = args->gpu_id - 1;\n\t\tassert(node_id < model_num_nodes);\n\t\tassert(model_nodes[node_id].is_gpu);\n\t\tif (args->va_addr == 0)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Expect only SVM allocations?\\n\");\n\t\t\tabort();\n\t\t}\n\t\tif (args->size % PAGE_SIZE != 0)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Allocation size not a multiple of page size\\n\");\n\t\t\tabort();\n\t\t}\n\t\tif (args->flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR)\n\t\t{\n\t\t\tfprintf(stderr, \"model: userptr not supported\\n\");\n\t\t\tabort();\n\t\t}\n\t\tstruct model_mem_data *mem_data = calloc(1, sizeof(*mem_data));\n\t\tif (!mem_data)\n\t\t\tabort();\n\t\tmem_data->va_addr = args->va_addr;\n\t\tmem_data->size = args->size;\n\t\tmem_data->flags = args->flags;\n\t\tmem_data->node_id = node_id;\n\t\tif (args->flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL)\n\t\t{\n\t\t\tassert(args->size == 8192);\n\t\t\tmem_data->file_offset = model_nodes[node_id].doorbell_offset;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmem_data->file_offset = allocate_from_memfd(args->size, 0);\n\t\t}\n\t\targs->handle = (__u64)mem_data;\n\t\targs->mmap_offset = mem_data->file_offset;\n\t\tmodel_nodes[node_id].allocated_memory_size += args->size;\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_ALLOC_MEMORY_OF_GPU: VA: %lx : Size: %lu, Flags: %x\\n\", mem_data->va_addr, mem_data->size, mem_data->flags);\n\t\tmodel_functions->alloced_memory(model_nodes[node_id].model, (uint64_t *)mem_data->va_addr, mem_data->size, mem_data->flags);\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_FREE_MEMORY_OF_GPU:\n\t{\n\t\tstruct kfd_ioctl_free_memory_of_gpu_args *args = arg;\n\t\tstruct model_mem_data *mem_data = (void *)args->handle;\n\t\tassert(!mem_data->mapped_nodes_bitmask);\n\t\t// Free the memory by punching a hole into the underlying memfd.\n\t\t//\n\t\t// Ideally, we'd also remember holes in the file and re-use them for\n\t\t// allocations to avoid the file size from growing indefinitely. It's\n\t\t// unclear whether the current implementation causes kernel data\n\t\t// structures to grow. But in practice, it almost certainly never\n\t\t// matters.\n\t\tint ret = fallocate(hsakmt_kfd_fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,\n\t\t\t\t\t\t\tmem_data->file_offset, mem_data->size);\n\t\tif (ret != 0)\n\t\t{\n\t\t\tperror(\"model: failed to punch hole in memfd\");\n\t\t\tabort();\n\t\t}\n\t\tmodel_nodes[mem_data->node_id].allocated_memory_size -= mem_data->size;\n\t\tmodel_functions->freed_memory(model_nodes[mem_data->node_id].model, (uint64_t *)mem_data->va_addr, mem_data->size);\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_FREE_MEMORY_OF_GPU: VA: %lx : Size: %lu, Flags: %x\\n\", mem_data->va_addr, mem_data->size, mem_data->flags);\n\t\tfree(mem_data);\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_MAP_MEMORY_TO_GPU:\n\t{\n\t\tstruct kfd_ioctl_map_memory_to_gpu_args *args = arg;\n\t\tstruct model_mem_data *mem_data = (void *)args->handle;\n\t\twhile (args->n_success < args->n_devices)\n\t\t{\n\t\t\tuint32_t gpu_id = ((uint32_t *)args->device_ids_array_ptr)[args->n_success];\n\t\t\tuint32_t node_id = gpu_id - 1;\n\t\t\tassert(node_id < model_num_nodes);\n\t\t\tif (mem_data->mapped_nodes_bitmask & (1llu << node_id))\n\t\t\t{\n\t\t\t\tfprintf(stderr, \"model: Already mapped\\n\");\n\t\t\t\tabort();\n\t\t\t}\n\t\t\tassert(model_nodes[node_id].aperture);\n\t\t\tunsigned prot = PROT_READ;\n\t\t\tif (mem_data->flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE)\n\t\t\t\tprot |= PROT_WRITE;\n\t\t\t// TODO: Mark *shader*-executable memory?\n\n\t\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_MAP_MEMORY_TO_GPU: VA: %lx : Size: %lu, Flags: %x\\n\", mem_data->va_addr, mem_data->size, mem_data->flags);\n\t\t\tvoid *ret = mmap(VOID_PTR_ADD(model_nodes[node_id].aperture, mem_data->va_addr),\n\t\t\t\t\t\t\t mem_data->size, prot,\n\t\t\t\t\t\t\t MAP_SHARED | MAP_FIXED, hsakmt_kfd_fd, mem_data->file_offset);\n\t\t\tif (ret == MAP_FAILED)\n\t\t\t{\n\t\t\t\tfprintf(stderr, \"model: mmap failed\\n\");\n\t\t\t\tabort();\n\t\t\t}\n\t\t\tmem_data->mapped_nodes_bitmask |= (1llu << node_id);\n\t\t\targs->n_success++;\n\t\t}\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU\\n\");\n\t\tstruct kfd_ioctl_unmap_memory_from_gpu_args *args = arg;\n\t\tstruct model_mem_data *mem_data = (void *)args->handle;\n\t\twhile (args->n_success < args->n_devices)\n\t\t{\n\t\t\tuint32_t gpu_id = ((uint32_t *)args->device_ids_array_ptr)[args->n_success];\n\t\t\tuint32_t node_id = gpu_id - 1;\n\t\t\tassert(node_id < model_num_nodes);\n\t\t\tif (!(mem_data->mapped_nodes_bitmask & (1llu << node_id)))\n\t\t\t{\n\t\t\t\tfprintf(stderr, \"model: Not mapped\\n\");\n\t\t\t\tabort();\n\t\t\t}\n\t\t\tassert(model_nodes[node_id].aperture);\n\t\t\t/* Overwrite the mapping with an empty mapping to keep\n\t\t\t * it reserved. */\n\t\t\tvoid *ret = mmap(VOID_PTR_ADD(model_nodes[node_id].aperture, mem_data->va_addr),\n\t\t\t\t\t\t\t mem_data->size, PROT_NONE,\n\t\t\t\t\t\t\t MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_NORESERVE, -1, 0);\n\t\t\tif (ret == MAP_FAILED)\n\t\t\t{\n\t\t\t\tperror(\"model: unmap failed\");\n\t\t\t\tabort();\n\t\t\t}\n\t\t\tmem_data->mapped_nodes_bitmask &= ~(1llu << node_id);\n\t\t\targs->n_success++;\n\t\t}\n\t\targs->n_success = args->n_devices;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_CREATE_EVENT:\n\t{\n\t\tstruct kfd_ioctl_create_event_args *args = arg;\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_CREATE_EVENT: %u\\n\", args->event_type);\n\t\t// Find a free slot\n\t\tunsigned i;\n\t\tfor (i = 0; i < model_event_limit; i += 64)\n\t\t{\n\t\t\tuint64_t bitmap = model_event_bitmap[i / 64];\n\t\t\tif (bitmap == ~(uint64_t)0)\n\t\t\t\tcontinue;\n\t\t\ti += ffsll(~bitmap) - 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (i >= model_event_limit)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Ran out of event slots. Should be an application error.\\n\");\n\t\t\tabort();\n\t\t}\n\t\t// Allocate the signal\n\t\tmodel_event_bitmap[i / 64] |= (uint64_t)1 << (i % 64);\n\t\tmodel_events[i].event_type = args->event_type;\n\t\tmodel_events[i].auto_reset = args->auto_reset;\n\t\tmodel_events[i].value = 0;\n\t\targs->event_trigger_data = 0xbadf001; // ???\n\t\targs->event_id = 1 + i;\n\t\targs->event_slot_index = ~0;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_WAIT_EVENTS:\n\t{\n\t\tstruct kfd_ioctl_wait_events_args *args = arg;\n\t\tstruct kfd_event_data *events = (void *)args->events_ptr;\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_WAIT_EVENTS: %u\\n\", args->num_events);\n\t\tbool have_timeout = args->timeout != 0xffffffffu;\n\t\tbool hit_timeout = false;\n\t\tstruct timespec timeout;\n\t\tif (have_timeout)\n\t\t{\n\t\t\tclock_gettime(CLOCK_MONOTONIC, &timeout);\n\t\t\ttimeout.tv_sec += args->timeout / 1000;\n\t\t\ttimeout.tv_nsec += (args->timeout % 1000) * 1000000;\n\t\t\tif (timeout.tv_nsec > 1000000000)\n\t\t\t{\n\t\t\t\ttimeout.tv_nsec -= 1000000000;\n\t\t\t\ttimeout.tv_sec++;\n\t\t\t}\n\t\t}\n\t\tfor (;;)\n\t\t{\n\t\t\tbool final_ready = args->wait_for_all;\n\t\t\tfor (unsigned i = 0; i < args->num_events; ++i)\n\t\t\t{\n\t\t\t\tunsigned slot = events[i].event_id - 1;\n\t\t\t\tstruct model_event *event = &model_events[slot];\n\t\t\t\tbool this_ready = false;\n\t\t\t\tif (event->event_type == HSA_EVENTTYPE_SIGNAL)\n\t\t\t\t{\n\t\t\t\t\tuint64_t current_age = event->value;\n\t\t\t\t\tuint64_t target_age = events[i].signal_event_data.last_event_age;\n\t\t\t\t\tthis_ready = current_age >= target_age;\n\t\t\t\t}\n\t\t\t\telse if (event->event_type == HSA_EVENTTYPE_HW_EXCEPTION ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_NODECHANGE ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_DEVICESTATECHANGE ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_HW_EXCEPTION ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_DEBUG_EVENT ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_PROFILE_EVENT ||\n\t\t\t\t\t\t event->event_type == HSA_EVENTTYPE_MEMORY)\n\t\t\t\t{\n\t\t\t\t\t// These never happen in the model\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf(stderr, \"model: Unimplemented event type\\n\");\n\t\t\t\t\tabort();\n\t\t\t\t}\n\t\t\t\tif (final_ready != this_ready)\n\t\t\t\t{\n\t\t\t\t\tfinal_ready = this_ready;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (final_ready)\n\t\t\t\tbreak;\n\t\t\tif (have_timeout)\n\t\t\t{\n\t\t\t\tint ret = pthread_cond_timedwait(\n\t\t\t\t\t&model_event_condvar, &model_ioctl_mutex, &timeout);\n\t\t\t\tif (ret == ETIMEDOUT)\n\t\t\t\t{\n\t\t\t\t\thit_timeout = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpthread_cond_wait(&model_event_condvar, &model_ioctl_mutex);\n\t\t\t}\n\t\t}\n\t\t/* Record most recent event ages and perform auto reset. */\n\t\tfor (unsigned i = 0; i < args->num_events; ++i)\n\t\t{\n\t\t\tunsigned slot = events[i].event_id - 1;\n\t\t\tstruct model_event *event = &model_events[slot];\n\t\t\tif (event->event_type == HSA_EVENTTYPE_SIGNAL)\n\t\t\t{\n\t\t\t\tuint64_t last_age = event->value;\n\t\t\t\tif (event->auto_reset && last_age >= events[i].signal_event_data.last_event_age)\n\t\t\t\t\tevent->value = 0;\n\t\t\t\tevents[i].signal_event_data.last_event_age = last_age;\n\t\t\t}\n\t\t}\n\t\targs->wait_result = hit_timeout ? KFD_IOC_WAIT_RESULT_TIMEOUT\n\t\t\t\t\t\t\t\t\t\t: KFD_IOC_WAIT_RESULT_COMPLETE;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_SET_EVENT:\n\t{\n\t\tstruct kfd_ioctl_set_event_args *args = arg;\n\t\tmodel_set_event(NULL, args->event_id);\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_RESET_EVENT:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_RESET_EVENT\\n\");\n\t\tstruct kfd_ioctl_reset_event_args *args = arg;\n\t\tunsigned slot = args->event_id - 1;\n\t\tstruct model_event *event = &model_events[slot];\n\t\tif (event->event_type == HSA_EVENTTYPE_SIGNAL)\n\t\t{\n\t\t\tmodel_events[slot].value = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfprintf(stderr, \"model: Unimplemented event type\\n\");\n\t\t\tabort();\n\t\t}\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_DESTROY_EVENT:\n\t{\n\t\tstruct kfd_ioctl_destroy_event_args *args = arg;\n\t\tunsigned i = args->event_id - 1;\n\t\tif (i >= model_event_limit || !(model_event_bitmap[i / 64] & ((uint64_t)1 << (i % 64))))\n\t\t{\n\t\t\tfprintf(stderr, \"model: trying to destroy an event that doesn't exist.\\n\");\n\t\t\tabort();\n\t\t}\n\t\tmemset(&model_events[i], 0, sizeof(model_events[i]));\n\t\tmodel_event_bitmap[i / 64] &= ~((uint64_t)1 << (i % 64));\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_CREATE_QUEUE:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_CREATE_QUEUE\\n\");\n\t\tstruct kfd_ioctl_create_queue_args *args = arg;\n\t\tunsigned node_id = args->gpu_id - 1;\n\t\tassert(node_id < model_num_nodes);\n\t\tassert(model_nodes[node_id].model);\n\t\tconst bool supported_queue_type = args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL ||\n\t\t\t\t\t\t\t\t\t\t  args->queue_type == KFD_IOC_QUEUE_TYPE_SDMA;\n\t\tif (!supported_queue_type)\n\t\t{\n\t\t\tfprintf(stderr, \"model: Unsupported queue type\\n\");\n\t\t\tabort();\n\t\t}\n\t\tunsigned queue_id = 0;\n\t\twhile (queue_id < MAX_MODEL_QUEUES && model_queues[queue_id].queue)\n\t\t\tqueue_id++;\n\t\tif (queue_id >= MAX_MODEL_QUEUES)\n\t\t{\n\t\t\tfprintf(stderr, \"model: too many queues\\n\");\n\t\t\tabort();\n\t\t}\n\t\tstruct hsakmt_model_queue_info info = {0};\n\t\tinfo.ring_base_address = args->ring_base_address;\n\t\tinfo.ring_size = args->ring_size;\n\t\tinfo.write_pointer_address = args->write_pointer_address;\n\t\tinfo.read_pointer_address = args->read_pointer_address;\n\t\tinfo.queue_type = args->queue_type;\n\t\tmodel_queues[queue_id].queue =\n\t\t\tmodel_functions->register_queue(model_nodes[node_id].model, &info);\n\t\tmodel_queues[queue_id].node_id = node_id;\n\t\targs->queue_id = queue_id;\n\t\t// Note that strictly speaking, this is the offset into the hsakmt_kfd_fd\n\t\t// file, not the DRM fd (but they are the same in our case).\n\t\targs->doorbell_offset = model_nodes[node_id].doorbell_offset + 8 * queue_id;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_DESTROY_QUEUE:\n\t{\n\t\tstruct kfd_ioctl_destroy_queue_args *args = arg;\n\t\tif (args->queue_id >= MAX_MODEL_QUEUES || !model_queues[args->queue_id].queue)\n\t\t{\n\t\t\tfprintf(stderr, \"model: trying to destroy a queue that doesn't exist\\n\");\n\t\t\tabort();\n\t\t}\n\t\tstruct model_queue *queue = &model_queues[args->queue_id];\n\t\t// Older model versions simply leak the queue.\n\t\tif (model_functions->version_minor >= 3)\n\t\t\tmodel_functions->destroy_queue(model_nodes[queue->node_id].model, queue->queue);\n\t\tqueue->queue = NULL;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_GET_TILE_CONFIG:\n\t{\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_GET_TILE_CONFIG\\n\");\n\t\tstruct kfd_ioctl_get_tile_config_args *args = arg;\n\t\targs->gb_addr_config = 0x10000444;\n\t\treturn 0;\n\t}\n\tcase AMDKFD_IOC_SET_SCRATCH_BACKING_VA:\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_SET_SCRATCH_BACKING_VA\\n\");\n\t\t// no-op -- scratch allocations are communicated via amd_queue_s\n\t\treturn 0;\n\tcase AMDKFD_IOC_RUNTIME_ENABLE:\n\t\tpr_debug(\"MODEL IOCTL: AMDKFD_IOC_RUNTIME_ENABLE\\n\");\n\t\tfprintf(stderr, \"model: Debugger runtime not implemented\\n\");\n\t\tfprintf(stderr, \"Fix this by clearing bit 30 of the 'capability' field in $HSA_MODEL_TOPOLOGY/%%d/properties\\n\");\n\t\tabort();\n\tdefault:\n\t\tfprintf(stderr, \"model: Unimplemented KFD ioctl\\n\");\n\t\tabort();\n\t}\n}\nint model_kfd_ioctl(unsigned long request, void *arg)\n{\n\t/* Use a very simle locking strategy for correctness. IOCTLs should\n\t * be rare anyway and not contended considering the cost of running\n\t * the model itself.\n\t *\n\t * The bulk of model execution happens in a separate thread *without*\n\t * holding the IOCTL mutex. */\n\tpthread_mutex_lock(&model_ioctl_mutex);\n\tint ret = model_kfd_ioctl_locked(request, arg);\n\tpthread_mutex_unlock(&model_ioctl_mutex);\n\treturn ret;\n}"
  },
  {
    "path": "libhsakmt/src/libhsakmt.c",
    "content": "#include <stdio.h>\n#include <errno.h>\n#include <sys/ioctl.h>\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/hsakmtmodel.h\"\n\n/* Call ioctl, restarting if it is interrupted */\nint hsakmt_ioctl(int fd, unsigned long request, void *arg)\n{\n\tif (hsakmt_use_model)\n\t\treturn model_kfd_ioctl(request, arg);\n\n\tint ret;\n\n\tdo {\n\t\tret = ioctl(fd, request, arg);\n\t} while (ret == -1 && (errno == EINTR || errno == EAGAIN));\n\n\tif (ret == -1 && errno == EBADF) {\n\t\t/* In case pthread_atfork didn't catch it, this will\n\t\t * make any subsequent hsaKmt calls fail in CHECK_KFD_OPEN.\n\t\t */\n\t\tpr_err(\"KFD file descriptor not valid in this process\\n\");\n\t\thsakmt_is_forked_child();\n\t}\n\n\treturn ret;\n}\n"
  },
  {
    "path": "libhsakmt/src/libhsakmt.h",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef LIBHSAKMT_H_INCLUDED\n#define LIBHSAKMT_H_INCLUDED\n\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"hsakmt/hsakmt.h\"\n#include <pthread.h>\n#include <stdint.h>\n#include <limits.h>\n\nextern int hsakmt_kfd_fd;\nextern int hsakmt_udmabuf_dev_fd;\nextern unsigned long hsakmt_kfd_open_count;\nextern bool hsakmt_forked;\nextern pthread_mutex_t hsakmt_mutex;\nextern bool hsakmt_is_dgpu;\nextern bool hsakmt_is_svm_api_supported;\nextern int hsakmt_zfb_support;\n\nextern HsaVersionInfo hsakmt_kfd_version_info;\n\n#undef HSAKMTAPI\n#define HSAKMTAPI __attribute__((visibility (\"default\")))\n\n#if defined(__clang__)\n#if __has_feature(address_sanitizer)\n#define SANITIZER_AMDGPU 1\n#endif\n#endif\n\n/*Avoid pointer-to-int-cast warning*/\n#define PORT_VPTR_TO_UINT64(vptr) ((uint64_t)(unsigned long)(vptr))\n\n/*Avoid int-to-pointer-cast warning*/\n#define PORT_UINT64_TO_VPTR(v) ((void*)(unsigned long)(v))\n\n#define CHECK_KFD_OPEN() \\\n\tdo { if (hsakmt_kfd_open_count == 0 || hsakmt_forked) return HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED; } while (0)\n\n#define CHECK_KFD_MINOR_VERSION(minor)\t\t\t\t\t\\\n\tdo { if ((minor) > hsakmt_kfd_version_info.KernelInterfaceMinorVersion)\\\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED; } while (0)\n\nextern int hsakmt_page_size;\nextern int hsakmt_page_shift;\n\n/* Might be defined in limits.h on platforms where it is constant (used by musl) */\n/* See also: https://pubs.opengroup.org/onlinepubs/7908799/xsh/limits.h.html */\n#ifndef PAGE_SIZE\n#define PAGE_SIZE hsakmt_page_size\n#endif\n#ifndef PAGE_SHIFT\n#define PAGE_SHIFT hsakmt_page_shift\n#endif\n\n/* VI HW bug requires this virtual address alignment */\n#define TONGA_PAGE_SIZE 0x8000\n\n/* 64KB BigK fragment size for TLB efficiency */\n#define GPU_BIGK_PAGE_SIZE (1 << 16)\n\n/* 2MB huge page size for 4-level page tables on Vega10 and later GPUs */\n#define GPU_HUGE_PAGE_SIZE (2 << 20)\n\n#define CHECK_PAGE_MULTIPLE(x) \\\n\tdo { if ((uint64_t)PORT_VPTR_TO_UINT64(x) % PAGE_SIZE) return HSAKMT_STATUS_INVALID_PARAMETER; } while(0)\n\n#define ALIGN_UP(x,align) (((uint64_t)(x) + (align) - 1) & ~(uint64_t)((align)-1))\n#define ALIGN_UP_32(x,align) (((uint32_t)(x) + (align) - 1) & ~(uint32_t)((align)-1))\n#define PAGE_ALIGN_UP(x) ALIGN_UP(x,PAGE_SIZE)\n#define BITMASK(n) ((n) ? (UINT64_MAX >> (sizeof(UINT64_MAX) * CHAR_BIT - (n))) : 0)\n#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))\n\n/* HSA Thunk logging usage */\nextern int hsakmt_debug_level;\n#define hsakmt_print(level, fmt, ...) \\\n\tdo { if (level <= hsakmt_debug_level) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)\n#define HSAKMT_DEBUG_LEVEL_DEFAULT\t-1\n#define HSAKMT_DEBUG_LEVEL_ERR\t\t3\n#define HSAKMT_DEBUG_LEVEL_WARNING\t4\n#define HSAKMT_DEBUG_LEVEL_INFO\t\t6\n#define HSAKMT_DEBUG_LEVEL_DEBUG\t7\n#define pr_err(fmt, ...) \\\n\thsakmt_print(HSAKMT_DEBUG_LEVEL_ERR, fmt, ##__VA_ARGS__)\n#define pr_warn(fmt, ...) \\\n\thsakmt_print(HSAKMT_DEBUG_LEVEL_WARNING, fmt, ##__VA_ARGS__)\n#define pr_info(fmt, ...) \\\n\thsakmt_print(HSAKMT_DEBUG_LEVEL_INFO, fmt, ##__VA_ARGS__)\n#define pr_debug(fmt, ...) \\\n\thsakmt_print(HSAKMT_DEBUG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)\n#define pr_err_once(fmt, ...)                   \\\n({                                              \\\n        static bool __print_once;               \\\n        if (!__print_once) {                    \\\n                __print_once = true;            \\\n                pr_err(fmt, ##__VA_ARGS__);     \\\n        }                                       \\\n})\n#define pr_warn_once(fmt, ...)                  \\\n({                                              \\\n        static bool __print_once;               \\\n        if (!__print_once) {                    \\\n                __print_once = true;            \\\n                pr_warn(fmt, ##__VA_ARGS__);    \\\n        }                                       \\\n})\n\n/* Expects gfxv (full) in decimal */\n#define HSA_GET_GFX_VERSION_MAJOR(gfxv)   (((gfxv) / 10000) % 100)\n#define HSA_GET_GFX_VERSION_MINOR(gfxv)   (((gfxv) / 100) % 100)\n#define HSA_GET_GFX_VERSION_STEP(gfxv)    ((gfxv) % 100)\n\n/* Expects HSA_ENGINE_ID.ui32, returns gfxv (full) in hex */\n#define HSA_GET_GFX_VERSION_FULL(ui32) \\\n\t(((ui32.Major) << 16) | ((ui32.Minor) << 8) | (ui32.Stepping))\n\nenum full_gfx_versions {\n\tGFX_VERSION_KAVERI\t\t= 0x070000,\n\tGFX_VERSION_HAWAII\t\t= 0x070001,\n\tGFX_VERSION_CARRIZO\t\t= 0x080001,\n\tGFX_VERSION_TONGA\t\t= 0x080002,\n\tGFX_VERSION_FIJI\t\t= 0x080003,\n\tGFX_VERSION_POLARIS10\t\t= 0x080003,\n\tGFX_VERSION_POLARIS11\t\t= 0x080003,\n\tGFX_VERSION_POLARIS12\t\t= 0x080003,\n\tGFX_VERSION_VEGAM\t\t= 0x080003,\n\tGFX_VERSION_VEGA10\t\t= 0x090000,\n\tGFX_VERSION_RAVEN\t\t= 0x090002,\n\tGFX_VERSION_VEGA12\t\t= 0x090004,\n\tGFX_VERSION_VEGA20\t\t= 0x090006,\n\tGFX_VERSION_ARCTURUS\t\t= 0x090008,\n\tGFX_VERSION_ALDEBARAN\t\t= 0x09000A,\n\tGFX_VERSION_AQUA_VANJARAM\t= 0x090400,\n\tGFX_VERSION_GFX950\t\t= 0x090500,\n\tGFX_VERSION_RENOIR\t\t= 0x09000C,\n\tGFX_VERSION_NAVI10\t\t= 0x0A0100,\n\tGFX_VERSION_NAVI12\t\t= 0x0A0101,\n\tGFX_VERSION_NAVI14\t\t= 0x0A0102,\n\tGFX_VERSION_CYAN_SKILLFISH\t= 0x0A0103,\n\tGFX_VERSION_SIENNA_CICHLID\t= 0x0A0300,\n\tGFX_VERSION_NAVY_FLOUNDER\t= 0x0A0301,\n\tGFX_VERSION_DIMGREY_CAVEFISH\t= 0x0A0302,\n\tGFX_VERSION_VANGOGH\t \t= 0x0A0303,\n\tGFX_VERSION_BEIGE_GOBY\t \t= 0x0A0304,\n\tGFX_VERSION_YELLOW_CARP\t \t= 0x0A0305,\n\tGFX_VERSION_PLUM_BONITO\t\t= 0x0B0000,\n\tGFX_VERSION_WHEAT_NAS\t\t= 0x0B0001,\n\tGFX_VERSION_GFX1200\t\t= 0x0C0000,\n\tGFX_VERSION_GFX1201\t\t= 0x0C0001,\n};\n\nstruct hsa_gfxip_table {\n\tuint16_t device_id;\t\t// Device ID\n\tunsigned char major;\t\t// GFXIP Major engine version\n\tunsigned char minor;\t\t// GFXIP Minor engine version\n\tunsigned char stepping;\t\t// GFXIP Stepping info\n\tconst char *amd_name;\t\t// CALName of the device\n};\n\nHSAKMT_STATUS hsakmt_init_kfd_version(void);\n\n#define IS_SOC15(gfxv) ((gfxv) >= GFX_VERSION_VEGA10)\n\nHSAKMT_STATUS hsakmt_validate_nodeid(uint32_t nodeid, uint32_t *gpu_id);\nHSAKMT_STATUS hsakmt_gpuid_to_nodeid(uint32_t gpu_id, uint32_t* node_id);\nuint32_t hsakmt_get_gfxv_by_node_id(HSAuint32 node_id);\nbool hsakmt_prefer_ats(HSAuint32 node_id);\nuint16_t hsakmt_get_device_id_by_node_id(HSAuint32 node_id);\nuint16_t hsakmt_get_device_id_by_gpu_id(HSAuint32 gpu_id);\nuint32_t hsakmt_get_direct_link_cpu(uint32_t gpu_node);\nint get_drm_render_fd_by_gpu_id(HSAuint32 gpu_id);\nHSAKMT_STATUS hsakmt_validate_nodeid_array(uint32_t **gpu_id_array,\n\t\tuint32_t NumberOfNodes, uint32_t *NodeArray);\n\nHSAKMT_STATUS hsakmt_topology_sysfs_get_system_props(HsaSystemProperties *props);\nHSAKMT_STATUS hsakmt_topology_get_node_props(HSAuint32 NodeId,\n\t\t\t\t      HsaNodeProperties *NodeProperties);\nHSAKMT_STATUS hsakmt_topology_get_iolink_props(HSAuint32 NodeId,\n\t\t\t\t\tHSAuint32 NumIoLinks,\n\t\t\t\t\tHsaIoLinkProperties *IoLinkProperties);\nvoid hsakmt_topology_setup_is_dgpu_param(HsaNodeProperties *props);\nbool hsakmt_topology_is_svm_needed(HSA_ENGINE_ID EngineId);\n\nHSAuint32 hsakmt_PageSizeFromFlags(unsigned int pageSizeFlags);\n\nvoid* hsakmt_allocate_exec_aligned_memory_gpu(uint32_t size, uint32_t align,\n\t\t\t\t       uint32_t gpu_id,\n\t\t\t\t       uint32_t NodeId, bool NonPaged,\n\t\t\t\t       bool DeviceLocal, bool Uncached);\nvoid hsakmt_free_exec_aligned_memory_gpu(void *addr, uint32_t size, uint32_t align);\nHSAKMT_STATUS hsakmt_init_process_doorbells(unsigned int NumNodes);\nvoid hsakmt_destroy_process_doorbells(void);\nHSAKMT_STATUS hsakmt_init_device_debugging_memory(unsigned int NumNodes);\nvoid hsakmt_destroy_device_debugging_memory(void);\nbool hsakmt_debug_get_reg_status(uint32_t node_id);\nHSAKMT_STATUS hsakmt_init_counter_props(unsigned int NumNodes);\nvoid hsakmt_destroy_counter_props(void);\nuint32_t *hsakmt_convert_queue_ids(HSAuint32 NumQueues, HSA_QUEUEID *Queues);\n\nextern int hsakmt_ioctl(int fd, unsigned long request, void *arg);\n\n/* Void pointer arithmetic (or remove -Wpointer-arith to allow void pointers arithmetic) */\n#define VOID_PTR_ADD32(ptr,n) (void*)((uint32_t*)(ptr) + n)/*ptr + offset*/\n#define VOID_PTR_ADD(ptr,n) (void*)((uint8_t*)(ptr) + n)/*ptr + offset*/\n#define VOID_PTR_SUB(ptr,n) (void*)((uint8_t*)(ptr) - n)/*ptr - offset*/\n#define VOID_PTRS_SUB(ptr1,ptr2) (uint64_t)((uint8_t*)(ptr1) - (uint8_t*)(ptr2)) /*ptr1 - ptr2*/\n\n#define MIN(a, b) ({\t\t\t\t\\\n\ttypeof(a) tmp1 = (a), tmp2 = (b);\t\\\n\ttmp1 < tmp2 ? tmp1 : tmp2; })\n\n#define MAX(a, b) ({\t\t\t\t\\\n\ttypeof(a) tmp1 = (a), tmp2 = (b);\t\\\n\ttmp1 > tmp2 ? tmp1 : tmp2; })\n\n#define POWER_OF_2(x) ((x && (!(x & (x - 1)))) ? 1 : 0)\n\nvoid hsakmt_clear_events_page(void);\nvoid hsakmt_fmm_clear_all_mem(void);\nvoid hsakmt_clear_process_doorbells(void);\nuint32_t hsakmt_get_num_sysfs_nodes(void);\n\nbool hsakmt_is_forked_child(void);\n\n/* Calculate VGPR and SGPR register file size per CU */\nuint32_t hsakmt_get_vgpr_size_per_cu(uint32_t gfxv);\n#define SGPR_SIZE_PER_CU 0x4000\n#endif\n"
  },
  {
    "path": "libhsakmt/src/libhsakmt.ver",
    "content": "HSAKMT_1\n{\nglobal:\nhsaKmtOpenKFD;\nhsaKmtCloseKFD;\nhsaKmtGetVersion;\nhsaKmtAcquireSystemProperties;\nhsaKmtReleaseSystemProperties;\nhsaKmtGetNodeProperties;\nhsaKmtGetNodeMemoryProperties;\nhsaKmtGetNodeCacheProperties;\nhsaKmtGetNodeIoLinkProperties;\nhsaKmtCreateEvent;\nhsaKmtDestroyEvent;\nhsaKmtSetEvent;\nhsaKmtResetEvent;\nhsaKmtQueryEventState;\nhsaKmtWaitOnEvent;\nhsaKmtWaitOnMultipleEvents;\nhsaKmtCreateQueue;\nhsaKmtUpdateQueue;\nhsaKmtDestroyQueue;\nhsaKmtSetQueueCUMask;\nhsaKmtSetMemoryPolicy;\nhsaKmtAllocMemory;\nhsaKmtAllocMemoryAlign;\nhsaKmtFreeMemory;\nhsaKmtAvailableMemory;\nhsaKmtRegisterMemory;\nhsaKmtRegisterMemoryToNodes;\nhsaKmtRegisterMemoryWithFlags;\nhsaKmtRegisterGraphicsHandleToNodes;\nhsaKmtShareMemory;\nhsaKmtRegisterSharedHandle;\nhsaKmtRegisterSharedHandleToNodes;\nhsaKmtProcessVMRead;\nhsaKmtProcessVMWrite;\nhsaKmtDeregisterMemory;\nhsaKmtMapMemoryToGPU;\nhsaKmtMapMemoryToGPUNodes;\nhsaKmtUnmapMemoryToGPU;\nhsaKmtDbgRegister;\nhsaKmtDbgUnregister;\nhsaKmtDbgWavefrontControl;\nhsaKmtDbgAddressWatch;\nhsaKmtDbgEnable;\nhsaKmtDbgDisable;\nhsaKmtDbgGetDeviceData;\nhsaKmtDbgGetQueueData;\nhsaKmtGetClockCounters;\nhsaKmtPmcGetCounterProperties;\nhsaKmtPmcRegisterTrace;\nhsaKmtPmcUnregisterTrace;\nhsaKmtPmcAcquireTraceAccess;\nhsaKmtPmcReleaseTraceAccess;\nhsaKmtPmcStartTrace;\nhsaKmtPmcQueryTrace;\nhsaKmtPmcStopTrace;\nhsaKmtMapGraphicHandle;\nhsaKmtUnmapGraphicHandle;\nhsaKmtSetTrapHandler;\nhsaKmtGetTileConfig;\nhsaKmtQueryPointerInfo;\nhsaKmtSetMemoryUserData;\nhsaKmtGetQueueInfo;\nhsaKmtAllocQueueGWS;\nhsaKmtRuntimeEnable;\nhsaKmtRuntimeDisable;\nhsaKmtCheckRuntimeDebugSupport;\nhsaKmtGetRuntimeCapabilities;\nhsaKmtDebugTrapIoctl;\nhsaKmtSPMAcquire;\nhsaKmtSPMRelease;\nhsaKmtSPMSetDestBuffer;\nhsaKmtSVMSetAttr;\nhsaKmtSVMGetAttr;\nhsaKmtSetXNACKMode;\nhsaKmtGetXNACKMode;\nhsaKmtOpenSMI;\nhsaKmtExportDMABufHandle;\nhsaKmtWaitOnEvent_Ext;\nhsaKmtWaitOnMultipleEvents_Ext;\nhsaKmtReplaceAsanHeaderPage;\nhsaKmtReturnAsanHeaderPage;\nhsaKmtGetAMDGPUDeviceHandle;\nhsaKmtPcSamplingQueryCapabilities;\nhsaKmtPcSamplingCreate;\nhsaKmtPcSamplingDestroy;\nhsaKmtPcSamplingStart;\nhsaKmtPcSamplingStop;\nhsaKmtPcSamplingSupport;\nlocal: *;\n};\n\n"
  },
  {
    "path": "libhsakmt/src/memory.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n#include <sys/types.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n#include \"fmm.h\"\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSetMemoryPolicy(HSAuint32 Node,\n\t\t\t\t\t      HSAuint32 DefaultPolicy,\n\t\t\t\t\t      HSAuint32 AlternatePolicy,\n\t\t\t\t\t      void *MemoryAddressAlternate,\n\t\t\t\t\t      HSAuint64 MemorySizeInBytes)\n{\n\tstruct kfd_ioctl_set_memory_policy_args args = {0};\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] node %d; default %d; alternate %d\\n\",\n\t\t__func__, Node, DefaultPolicy, AlternatePolicy);\n\n\tresult = hsakmt_validate_nodeid(Node, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\tif (hsakmt_get_gfxv_by_node_id(Node) != GFX_VERSION_KAVERI)\n\t\t/* This is a legacy API useful on Kaveri only. On dGPU\n\t\t * the alternate aperture is setup and used\n\t\t * automatically for coherent allocations. Don't let\n\t\t * app override it.\n\t\t */\n\t\treturn HSAKMT_STATUS_NOT_IMPLEMENTED;\n\n\t/*\n\t * We accept any legal policy and alternate address location.\n\t * You get CC everywhere anyway.\n\t */\n\tif ((DefaultPolicy != HSA_CACHING_CACHED &&\n\t\tDefaultPolicy != HSA_CACHING_NONCACHED) ||\n\t\t\t(AlternatePolicy != HSA_CACHING_CACHED &&\n\t\t\tAlternatePolicy != HSA_CACHING_NONCACHED))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tCHECK_PAGE_MULTIPLE(MemoryAddressAlternate);\n\tCHECK_PAGE_MULTIPLE(MemorySizeInBytes);\n\n\targs.gpu_id = gpu_id;\n\targs.default_policy = (DefaultPolicy == HSA_CACHING_CACHED) ?\n\t\t\t\t\tKFD_IOC_CACHE_POLICY_COHERENT :\n\t\t\t\t\tKFD_IOC_CACHE_POLICY_NONCOHERENT;\n\n\targs.alternate_policy = (AlternatePolicy == HSA_CACHING_CACHED) ?\n\t\t\t\t\tKFD_IOC_CACHE_POLICY_COHERENT :\n\t\t\t\t\tKFD_IOC_CACHE_POLICY_NONCOHERENT;\n\n\targs.alternate_aperture_base = (uintptr_t) MemoryAddressAlternate;\n\targs.alternate_aperture_size = MemorySizeInBytes;\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_MEMORY_POLICY, &args);\n\n\treturn (err == -1) ? HSAKMT_STATUS_ERROR : HSAKMT_STATUS_SUCCESS;\n}\n\nHSAuint32 hsakmt_PageSizeFromFlags(unsigned int pageSizeFlags)\n{\n\tswitch (pageSizeFlags) {\n\tcase HSA_PAGE_SIZE_4KB: return 4*1024;\n\tcase HSA_PAGE_SIZE_64KB: return 64*1024;\n\tcase HSA_PAGE_SIZE_2MB: return 2*1024*1024;\n\tcase HSA_PAGE_SIZE_1GB: return 1024*1024*1024;\n\tdefault:\n\t\tassert(false);\n\t\treturn 4*1024;\n\t}\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtAllocMemory(HSAuint32 PreferredNode,\n\t\t\t\t\t  HSAuint64 SizeInBytes,\n\t\t\t\t\t  HsaMemFlags MemFlags,\n\t\t\t\t\t  void **MemoryAddress)\n{\n\treturn hsaKmtAllocMemoryAlign(PreferredNode, SizeInBytes, 0, MemFlags, MemoryAddress);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtAllocMemoryAlign(HSAuint32 PreferredNode,\n\t\t\t\t\t  HSAuint64 SizeInBytes,\n\t\t\t\t\t  HSAuint64 Alignment,\n\t\t\t\t\t  HsaMemFlags MemFlags,\n\t\t\t\t\t  void **MemoryAddress)\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\tHSAuint64 page_size;\n\n\tCHECK_KFD_OPEN();\n\n\tif (MemFlags.ui32.Contiguous)\n\t\tCHECK_KFD_MINOR_VERSION(16);\n\n\tpr_debug(\"[%s] node %d\\n\", __func__, PreferredNode);\n\n\tresult = hsakmt_validate_nodeid(PreferredNode, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS) {\n\t\tpr_err(\"[%s] invalid node ID: %d\\n\", __func__, PreferredNode);\n\t\treturn result;\n\t}\n\n\tpage_size = hsakmt_PageSizeFromFlags(MemFlags.ui32.PageSize);\n\n\tif (Alignment && (Alignment < page_size || !POWER_OF_2(Alignment)))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (!MemoryAddress || !SizeInBytes || (SizeInBytes & (page_size-1)))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (MemFlags.ui32.FixedAddress) {\n\t\tif (*MemoryAddress == NULL)\n\t\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t} else\n\t\t*MemoryAddress = NULL;\n\n\tif ((MemFlags.ui32.CoarseGrain && MemFlags.ui32.ExtendedCoherent) ||\n\t    (MemFlags.ui32.ExtendedCoherent && MemFlags.ui32.Uncached))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (MemFlags.ui32.Scratch) {\n\t\tif (Alignment) {\n\t\t\t// Scratch memory currently forced to SCRATCH_ALIGN\n\t\t\tpr_err(\"[%s] Alignment not supported for scratch memory: %d\\n\", __func__, PreferredNode);\n\t\t\treturn HSAKMT_STATUS_NOT_IMPLEMENTED;\n\t\t}\n\n\t\t*MemoryAddress = hsakmt_fmm_allocate_scratch(gpu_id, *MemoryAddress, SizeInBytes);\n\n\t\tif (!(*MemoryAddress)) {\n\t\t\tpr_err(\"[%s] failed to allocate %lu bytes from scratch\\n\",\n\t\t\t\t__func__, SizeInBytes);\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\t}\n\n\t\tpr_debug(\"[%s] node %d address %p size %lu from scratch\\n\", __func__, PreferredNode, *MemoryAddress, SizeInBytes);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\t/* GPU allocated system memory */\n\tif (!gpu_id || !MemFlags.ui32.NonPaged || hsakmt_zfb_support || MemFlags.ui32.GTTAccess\n\t\t|| MemFlags.ui32.OnlyAddress) {\n\t\t/* Backwards compatibility hack: Allocate system memory if app\n\t\t * asks for paged memory from a GPU node.\n\t\t */\n\n\t\t/* If allocate VRAM under ZFB mode */\n\t\tif (hsakmt_zfb_support && gpu_id && MemFlags.ui32.NonPaged == 1)\n\t\t\tMemFlags.ui32.CoarseGrain = 1;\n\n\t\t*MemoryAddress = hsakmt_fmm_allocate_host(gpu_id, MemFlags.ui32.GTTAccess ? 0 : PreferredNode,\n\t\t\t\t\t\t   *MemoryAddress, SizeInBytes, Alignment, MemFlags);\n\n\t\tif (!(*MemoryAddress)) {\n\t\t\tpr_err(\"[%s] failed to allocate %lu bytes from host\\n\",\n\t\t\t\t__func__, SizeInBytes);\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t\t}\n\n\t\tpr_debug(\"[%s] node %d address %p size %lu from host\\n\", __func__, PreferredNode, *MemoryAddress, SizeInBytes);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\t/* GPU allocated VRAM */\n\t/* sanity check cannot do OnlyAddress and NoAddress alloc at same time */\n\tif (MemFlags.ui32.OnlyAddress && MemFlags.ui32.NoAddress) {\n\t\tpr_err(\"[%s] allocate addr-only and memory-only at same time\\n\",\n\t\t\t__func__);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\t*MemoryAddress = hsakmt_fmm_allocate_device(gpu_id, PreferredNode, *MemoryAddress,\n\t\t\t\t\t     SizeInBytes, Alignment, MemFlags);\n\n\tif (!(*MemoryAddress)) {\n\t\tpr_err(\"[%s] failed to allocate %lu bytes from device\\n\",\n\t\t\t__func__, SizeInBytes);\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t}\n\n\tpr_debug(\"[%s] node %d address %p size %lu from device\\n\", __func__, PreferredNode, *MemoryAddress, SizeInBytes);\n\treturn HSAKMT_STATUS_SUCCESS;\n\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtFreeMemory(void *MemoryAddress,\n\t\t\t\t\t HSAuint64 SizeInBytes)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\tif (!MemoryAddress) {\n\t\tpr_err(\"FIXME: freeing NULL pointer\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn hsakmt_fmm_release(MemoryAddress);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtAvailableMemory(HSAuint32 Node,\n\t\t\t\t\t      HSAuint64 *AvailableBytes)\n{\n\tstruct kfd_ioctl_get_available_memory_args args = {};\n\tHSAKMT_STATUS result;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(9);\n\n\tpr_debug(\"[%s] node %d\\n\", __func__, Node);\n\n\tresult = hsakmt_validate_nodeid(Node, &args.gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS) {\n\t\tpr_err(\"[%s] invalid node ID: %d\\n\", __func__, Node);\n\t\treturn result;\n\t}\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_AVAILABLE_MEMORY, &args))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t*AvailableBytes = args.available;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterMemory(void *MemoryAddress,\n\t\t\t\t\t     HSAuint64 MemorySizeInBytes)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p size %lu\\n\", __func__, MemoryAddress, MemorySizeInBytes);\n\n\tif (!hsakmt_is_dgpu)\n\t\t/* TODO: support mixed APU and dGPU configurations */\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\n\treturn hsakmt_fmm_register_memory(MemoryAddress, MemorySizeInBytes,\n\t\t\t\t   NULL, 0, true, false);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterMemoryToNodes(void *MemoryAddress,\n\t\t\t\t\t\t    HSAuint64 MemorySizeInBytes,\n\t\t\t\t\t\t    HSAuint64 NumberOfNodes,\n\t\t\t\t\t\t    HSAuint32 *NodeArray)\n{\n\tCHECK_KFD_OPEN();\n\tuint32_t *gpu_id_array;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] address %p size %lu number of nodes %lu\\n\",\n\t\t__func__, MemoryAddress, MemorySizeInBytes, NumberOfNodes);\n\n\tif (!hsakmt_is_dgpu)\n\t\t/* TODO: support mixed APU and dGPU configurations */\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\tret = hsakmt_validate_nodeid_array(&gpu_id_array,\n\t\t\tNumberOfNodes, NodeArray);\n\n\tif (ret == HSAKMT_STATUS_SUCCESS) {\n\t\tret = hsakmt_fmm_register_memory(MemoryAddress, MemorySizeInBytes,\n\t\t\t\t\t  gpu_id_array,\n\t\t\t\t\t  NumberOfNodes*sizeof(uint32_t),\n\t\t\t\t\t  true, false);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tfree(gpu_id_array);\n\t}\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterMemoryWithFlags(void *MemoryAddress,\n\t\t\t\t\t\t    HSAuint64 MemorySizeInBytes,\n\t\t\t\t\t\t    HsaMemFlags MemFlags)\n{\n\tCHECK_KFD_OPEN();\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] address %p size %lu\\n\",\n\t\t__func__, MemoryAddress, MemorySizeInBytes);\n\n\tif (MemFlags.ui32.ExtendedCoherent && MemFlags.ui32.CoarseGrain)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\t// Registered memory should be ordinary paged host memory.\n\tif ((MemFlags.ui32.HostAccess != 1) || (MemFlags.ui32.NonPaged == 1))\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\tif (!hsakmt_is_dgpu)\n\t\t/* TODO: support mixed APU and dGPU configurations */\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\tret = hsakmt_fmm_register_memory(MemoryAddress, MemorySizeInBytes,\n\t\tNULL, 0, MemFlags.ui32.CoarseGrain, MemFlags.ui32.ExtendedCoherent);\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterGraphicsHandleToNodes(HSAuint64 GraphicsResourceHandle,\n\t\t\t\t\t\t\t    HsaGraphicsResourceInfo *GraphicsResourceInfo,\n\t\t\t\t\t\t\t    HSAuint64 NumberOfNodes,\n\t\t\t\t\t\t\t    HSAuint32 *NodeArray)\n{\n       HSA_REGISTER_MEM_FLAGS regFlags;\n       regFlags.Value = 0;\n        \n       return hsaKmtRegisterGraphicsHandleToNodesExt(GraphicsResourceHandle,\n\t\t\t\t\t\t     GraphicsResourceInfo,\n\t\t\t\t\t\t     NumberOfNodes,\n\t\t\t\t\t\t     NodeArray,\n\t\t\t\t\t\t     regFlags);\n\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterGraphicsHandleToNodesExt(HSAuint64 GraphicsResourceHandle,\n\t\t\t\t\t\t\t       HsaGraphicsResourceInfo *GraphicsResourceInfo,\n\t\t\t\t\t\t\t       HSAuint64 NumberOfNodes,\n\t\t\t\t\t\t\t       HSAuint32 *NodeArray,\n\t\t\t\t\t\t\t       HSA_REGISTER_MEM_FLAGS RegisterFlags)\n{\n\tCHECK_KFD_OPEN();\n\tuint32_t *gpu_id_array = NULL;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] number of nodes %lu\\n\", __func__, NumberOfNodes);\n\n\tif (NodeArray != NULL || NumberOfNodes != 0) {\n\t\tret = hsakmt_validate_nodeid_array(&gpu_id_array,\n\t\t\t\tNumberOfNodes, NodeArray);\n\t}\n\n\tif (ret == HSAKMT_STATUS_SUCCESS) {\n\t\tret = hsakmt_fmm_register_graphics_handle(\n\t\t\tGraphicsResourceHandle, GraphicsResourceInfo,\n\t\t\tgpu_id_array, NumberOfNodes * sizeof(uint32_t), RegisterFlags);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tfree(gpu_id_array);\n\t}\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtExportDMABufHandle(void *MemoryAddress,\n\t\t\t\t\t\t HSAuint64 MemorySizeInBytes,\n\t\t\t\t\t\t int *DMABufFd,\n\t\t\t\t\t\t HSAuint64 *Offset)\n{\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(12);\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\treturn hsakmt_fmm_export_dma_buf_fd(MemoryAddress, MemorySizeInBytes,\n\t\t\t\t     DMABufFd, Offset);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtShareMemory(void *MemoryAddress,\n\t\t\t\t\t  HSAuint64 SizeInBytes,\n\t\t\t\t\t  HsaSharedMemoryHandle *SharedMemoryHandle)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\tif (!SharedMemoryHandle)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\treturn hsakmt_fmm_share_memory(MemoryAddress, SizeInBytes, SharedMemoryHandle);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterSharedHandle(const HsaSharedMemoryHandle *SharedMemoryHandle,\n\t\t\t\t\t\t   void **MemoryAddress,\n\t\t\t\t\t\t   HSAuint64 *SizeInBytes)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] handle %p\\n\", __func__, SharedMemoryHandle);\n\n\treturn hsaKmtRegisterSharedHandleToNodes(SharedMemoryHandle,\n\t\t\t\t\t\t MemoryAddress,\n\t\t\t\t\t\t SizeInBytes,\n\t\t\t\t\t\t 0,\n\t\t\t\t\t\t NULL);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtRegisterSharedHandleToNodes(const HsaSharedMemoryHandle *SharedMemoryHandle,\n\t\t\t\t\t\t\t  void **MemoryAddress,\n\t\t\t\t\t\t\t  HSAuint64 *SizeInBytes,\n\t\t\t\t\t\t\t  HSAuint64 NumberOfNodes,\n\t\t\t\t\t\t\t  HSAuint32 *NodeArray)\n{\n\tCHECK_KFD_OPEN();\n\n\tuint32_t *gpu_id_array = NULL;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] handle %p number of nodes %lu\\n\",\n\t\t__func__, SharedMemoryHandle, NumberOfNodes);\n\n\tif (!SharedMemoryHandle)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (NodeArray) {\n\t\tret = hsakmt_validate_nodeid_array(&gpu_id_array, NumberOfNodes, NodeArray);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto error;\n\t}\n\n\tret = hsakmt_fmm_register_shared_memory(SharedMemoryHandle,\n\t\t\t\t\t SizeInBytes,\n\t\t\t\t\t MemoryAddress,\n\t\t\t\t\t gpu_id_array,\n\t\t\t\t\t NumberOfNodes*sizeof(uint32_t));\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\tgoto error;\n\n\treturn ret;\n\nerror:\n\tif (gpu_id_array)\n\t\tfree(gpu_id_array);\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtProcessVMRead(HSAuint32 Pid,\n\t\t\t\t\t    HsaMemoryRange *LocalMemoryArray,\n\t\t\t\t\t    HSAuint64 LocalMemoryArrayCount,\n\t\t\t\t\t    HsaMemoryRange *RemoteMemoryArray,\n\t\t\t\t\t    HSAuint64 RemoteMemoryArrayCount,\n\t\t\t\t\t    HSAuint64 *SizeCopied)\n{\n\tpr_err(\"[%s] Deprecated\\n\", __func__);\n\n\treturn HSAKMT_STATUS_NOT_IMPLEMENTED;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtProcessVMWrite(HSAuint32 Pid,\n\t\t\t\t\t     HsaMemoryRange *LocalMemoryArray,\n\t\t\t\t\t     HSAuint64 LocalMemoryArrayCount,\n\t\t\t\t\t     HsaMemoryRange *RemoteMemoryArray,\n\t\t\t\t\t     HSAuint64 RemoteMemoryArrayCount,\n\t\t\t\t\t     HSAuint64 *SizeCopied)\n{\n\tpr_err(\"[%s] Deprecated\\n\", __func__);\n\n\treturn HSAKMT_STATUS_NOT_IMPLEMENTED;\n}\n\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDeregisterMemory(void *MemoryAddress)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\treturn hsakmt_fmm_deregister_memory(MemoryAddress);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtMapMemoryToGPU(void *MemoryAddress,\n\t\t\t\t\t     HSAuint64 MemorySizeInBytes,\n\t\t\t\t\t     HSAuint64 *AlternateVAGPU)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\tif (!MemoryAddress) {\n\t\tpr_err(\"FIXME: mapping NULL pointer\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tif (AlternateVAGPU)\n\t\t*AlternateVAGPU = 0;\n\n\treturn hsakmt_fmm_map_to_gpu(MemoryAddress, MemorySizeInBytes, AlternateVAGPU);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtMapMemoryToGPUNodes(void *MemoryAddress,\n\t\t\t\t\t\t  HSAuint64 MemorySizeInBytes,\n\t\t\t\t\t\t  HSAuint64 *AlternateVAGPU,\n\t\t\t\t\t\t  HsaMemMapFlags MemMapFlags,\n\t\t\t\t\t\t  HSAuint64 NumberOfNodes,\n\t\t\t\t\t\t  HSAuint32 *NodeArray)\n{\n\tuint32_t *gpu_id_array;\n\tHSAKMT_STATUS ret;\n\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p number of nodes %lu\\n\",\n\t\t__func__, MemoryAddress, NumberOfNodes);\n\n\tif (!MemoryAddress) {\n\t\tpr_err(\"FIXME: mapping NULL pointer\\n\");\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tif (!hsakmt_is_dgpu && NumberOfNodes == 1)\n\t\treturn hsaKmtMapMemoryToGPU(MemoryAddress,\n\t\t\t\tMemorySizeInBytes,\n\t\t\t\tAlternateVAGPU);\n\n\tret = hsakmt_validate_nodeid_array(&gpu_id_array,\n\t\t\t\tNumberOfNodes, NodeArray);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tret = hsakmt_fmm_map_to_gpu_nodes(MemoryAddress, MemorySizeInBytes,\n\t\tgpu_id_array, NumberOfNodes, AlternateVAGPU);\n\n\tif (gpu_id_array)\n\t\tfree(gpu_id_array);\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtUnmapMemoryToGPU(void *MemoryAddress)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] address %p\\n\", __func__, MemoryAddress);\n\n\tif (!MemoryAddress) {\n\t\t/* Workaround for runtime bug */\n\t\tpr_err(\"FIXME: Unmapping NULL pointer\\n\");\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tif (!hsakmt_fmm_unmap_from_gpu(MemoryAddress))\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\telse\n\t\treturn HSAKMT_STATUS_ERROR;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtMapGraphicHandle(HSAuint32 NodeId,\n\t\t\t\t\t       HSAuint64 GraphicDeviceHandle,\n\t\t\t\t\t       HSAuint64 GraphicResourceHandle,\n\t\t\t\t\t       HSAuint64 GraphicResourceOffset,\n\t\t\t\t\t       HSAuint64 GraphicResourceSize,\n\t\t\t\t\t       HSAuint64 *FlatMemoryAddress)\n{\n\t/* This API was only ever implemented in KFD for Kaveri and\n\t * was never upstreamed. There are no open-source users of\n\t * this interface. It has been superseded by\n\t * RegisterGraphicsHandleToNodes.\n\t */\n\treturn HSAKMT_STATUS_NOT_IMPLEMENTED;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtUnmapGraphicHandle(HSAuint32 NodeId,\n\t\t\t\t\t\t HSAuint64 FlatMemoryAddress,\n\t\t\t\t\t\t HSAuint64 SizeInBytes)\n{\n\tCHECK_KFD_OPEN();\n\n\treturn hsaKmtUnmapMemoryToGPU(PORT_UINT64_TO_VPTR(FlatMemoryAddress));\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetTileConfig(HSAuint32 NodeId, HsaGpuTileConfig *config)\n{\n\tstruct kfd_ioctl_get_tile_config_args args = {0};\n\tuint32_t gpu_id;\n\tHSAKMT_STATUS result;\n\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] node %d\\n\", __func__, NodeId);\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\t/* Avoid Valgrind warnings about uninitialized data. Valgrind doesn't\n\t * know that KFD writes this.\n\t */\n\tmemset(config->TileConfig, 0, sizeof(*config->TileConfig) * config->NumTileConfigs);\n\tmemset(config->MacroTileConfig, 0, sizeof(*config->MacroTileConfig) * config->NumMacroTileConfigs);\n\n\targs.gpu_id = gpu_id;\n\targs.tile_config_ptr = (uint64_t)config->TileConfig;\n\targs.macro_tile_config_ptr = (uint64_t)config->MacroTileConfig;\n\targs.num_tile_configs = config->NumTileConfigs;\n\targs.num_macro_tile_configs = config->NumMacroTileConfigs;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_TILE_CONFIG, &args) != 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tconfig->NumTileConfigs = args.num_tile_configs;\n\tconfig->NumMacroTileConfigs = args.num_macro_tile_configs;\n\n\tconfig->GbAddrConfig = args.gb_addr_config;\n\n\tconfig->NumBanks = args.num_banks;\n\tconfig->NumRanks = args.num_ranks;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtQueryPointerInfo(const void *Pointer,\n\t\t\t\t\t       HsaPointerInfo *PointerInfo)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] pointer %p\\n\", __func__, Pointer);\n\n\tif (!PointerInfo)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\treturn hsakmt_fmm_get_mem_info(Pointer, PointerInfo);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSetMemoryUserData(const void *Pointer,\n\t\t\t\t\t\tvoid *UserData)\n{\n\tCHECK_KFD_OPEN();\n\n\tpr_debug(\"[%s] pointer %p\\n\", __func__, Pointer);\n\n\treturn hsakmt_fmm_set_mem_user_data(Pointer, UserData);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtReplaceAsanHeaderPage(void *addr)\n{\n#ifdef SANITIZER_AMDGPU\n\tpr_debug(\"[%s] address %p\\n\", __func__, addr);\n\tCHECK_KFD_OPEN();\n\n\treturn hsakmt_fmm_replace_asan_header_page(addr);\n#else\n\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n#endif\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtReturnAsanHeaderPage(void *addr)\n{\n#ifdef SANITIZER_AMDGPU\n\tpr_debug(\"[%s] address %p\\n\", __func__, addr);\n\tCHECK_KFD_OPEN();\n\n\treturn hsakmt_fmm_return_asan_header_page(addr);\n#else\n\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n#endif\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetAMDGPUDeviceHandle( HSAuint32 NodeId,\n\t\t\t\t\t\tHsaAMDGPUDeviceHandle   *DeviceHandle)\n{\n\tCHECK_KFD_OPEN();\n\n\treturn hsakmt_fmm_get_amdgpu_device_handle(NodeId, DeviceHandle);\n}\n"
  },
  {
    "path": "libhsakmt/src/openclose.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/* glibc macro that enables access some nonstandard GNU/Linux extensions\n * such as RTLD_DEFAULT used by dlsym\n */\n#define _GNU_SOURCE\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/hsakmtmodel.h\"\n\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <sys/ioctl.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <strings.h>\n#include \"fmm.h\"\n#include <dlfcn.h>\n#include <string.h>\n\nint (*hsakmt_fn_amdgpu_device_get_fd)(HsaAMDGPUDeviceHandle device_handle);\n\nstatic const char kfd_device_name[] = \"/dev/kfd\";\nstatic const char kfd_udmabuf_device_name[] = \"/dev/udmabuf\";\nstatic pid_t parent_pid = -1;\nint hsakmt_debug_level;\nbool hsakmt_forked;\n\n/* hsakmt_is_forked_child detects when the process has forked since the last\n * time this function was called. We cannot rely on pthread_atfork\n * because the process can fork without calling the fork function in\n * libc (using clone or calling the system call directly).\n */\nbool hsakmt_is_forked_child(void)\n{\n\tpid_t cur_pid;\n\n\tif (hsakmt_forked)\n\t\treturn true;\n\n\tcur_pid = getpid();\n\n\tif (parent_pid == -1) {\n\t\tparent_pid = cur_pid;\n\t\treturn false;\n\t}\n\n\tif (parent_pid != cur_pid) {\n\t\thsakmt_forked = true;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/* Callbacks from pthread_atfork */\nstatic void prepare_fork_handler(void)\n{\n\tpthread_mutex_lock(&hsakmt_mutex);\n}\nstatic void parent_fork_handler(void)\n{\n\tpthread_mutex_unlock(&hsakmt_mutex);\n}\nstatic void child_fork_handler(void)\n{\n\tpthread_mutex_init(&hsakmt_mutex, NULL);\n\thsakmt_forked = true;\n}\n\n/* Call this from the child process after fork. This will clear all\n * data that is duplicated from the parent process, that is not valid\n * in the child.\n * The topology information is duplicated from the parent is valid\n * in the child process so it is not cleared\n */\nstatic void clear_after_fork(void)\n{\n\thsakmt_clear_process_doorbells();\n\thsakmt_clear_events_page();\n\thsakmt_fmm_clear_all_mem();\n\thsakmt_destroy_device_debugging_memory();\n\tif (hsakmt_kfd_fd) {\n\t\tclose(hsakmt_kfd_fd);\n\t\thsakmt_kfd_fd = -1;\n\t}\n\tif (hsakmt_udmabuf_dev_fd > 0) {\n\t\tclose(hsakmt_udmabuf_dev_fd);\n\t\thsakmt_udmabuf_dev_fd = -1;\n\t}\n\thsakmt_kfd_open_count = 0;\n\tparent_pid = -1;\n\thsakmt_forked = false;\n}\n\nstatic inline void init_page_size(void)\n{\n\thsakmt_page_size = sysconf(_SC_PAGESIZE);\n\thsakmt_page_shift = ffs(hsakmt_page_size) - 1;\n}\n\nstatic HSAKMT_STATUS init_vars_from_env(void)\n{\n\tchar *envvar;\n\tint debug_level;\n\n\t/* Normally libraries don't print messages. For debugging purpose, we'll\n\t * print messages if an environment variable, HSAKMT_DEBUG_LEVEL, is set.\n\t */\n\thsakmt_debug_level = HSAKMT_DEBUG_LEVEL_DEFAULT;\n\n\tenvvar = getenv(\"HSAKMT_DEBUG_LEVEL\");\n\tif (envvar) {\n\t\tdebug_level = atoi(envvar);\n\t\tif (debug_level >= HSAKMT_DEBUG_LEVEL_ERR &&\n\t\t\t\tdebug_level <= HSAKMT_DEBUG_LEVEL_DEBUG)\n\t\t\thsakmt_debug_level = debug_level;\n\t}\n\n\t/* Check whether to support Zero frame buffer */\n\tenvvar = getenv(\"HSA_ZFB\");\n\tif (envvar)\n\t\thsakmt_zfb_support = atoi(envvar);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtOpenKFD(void)\n{\n\tHSAKMT_STATUS result;\n\tint fd = -1;\n\tHsaSystemProperties sys_props;\n\tchar *error;\n\tchar *useSvmStr;\n\tchar *useUdmaBuf;\n\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\t/* If the process has forked, the child process must re-initialize\n\t * it's connection to KFD. Any references tracked by hsakmt_kfd_open_count\n\t * belong to the parent\n\t */\n\tif (hsakmt_is_forked_child())\n\t\tclear_after_fork();\n\n\tif (hsakmt_kfd_open_count == 0) {\n\t\tstatic bool atfork_installed = false;\n\n\t\thsakmt_fn_amdgpu_device_get_fd = dlsym(RTLD_DEFAULT, \"amdgpu_device_get_fd\");\n\t\tif ((error = dlerror()) != NULL)\n\t\t\tpr_err(\"amdgpu_device_get_fd is not available: %s\\n\", error);\n\t\telse\n\t\t\tpr_info(\"amdgpu_device_get_fd is available %p\\n\", hsakmt_fn_amdgpu_device_get_fd);\n\n\t\tresult = init_vars_from_env();\n\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto open_failed;\n\n\t\t// Check if we are using the hsakmtmodel and setup initial state\n\t\tmodel_init_env_vars();\n\n\t\tif (hsakmt_kfd_fd < 0 && !hsakmt_use_model) {\n\t\t\tfd = open(kfd_device_name, O_RDWR | O_CLOEXEC);\n\n\t\t\tif (fd == -1) {\n\t\t\t\tresult = HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED;\n\t\t\t\tgoto open_failed;\n\t\t\t}\n\n\t\t\thsakmt_kfd_fd = fd;\n\t\t}\n\n\t\tinit_page_size();\n\n\t\tresult = hsakmt_init_kfd_version();\n\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto kfd_version_failed;\n\n\t\t/* check if udmabuf is enabled by env HSA_USE_UDMABUF */\n\t\tuseUdmaBuf = getenv(\"HSA_USE_UDMABUF\");\n\t\tif (useUdmaBuf && atoi(useUdmaBuf)) {\n\t\t\t/* open udmabuf device */\n\t\t\thsakmt_udmabuf_dev_fd = open(kfd_udmabuf_device_name, 0);\n\t\t\tif (hsakmt_udmabuf_dev_fd < 0)\n\t\t\t\tpr_debug(\"running kernel does not support udmabuf\\n\");\n\t\t\telse\n\t\t\t\tpr_debug(\"udmabuf is enabled\\n\");\n\t\t} else\n\t\t\tpr_debug(\"udmabuf is not enabled\\n\");\n\n\t\tuseSvmStr = getenv(\"HSA_USE_SVM\");\n\t\thsakmt_is_svm_api_supported = !(useSvmStr && !strcmp(useSvmStr, \"0\"));\n\t\tif(!hsakmt_use_model)\n\t\t\tresult = hsakmt_topology_sysfs_get_system_props(&sys_props);\n\t\t\n\t\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto topology_sysfs_failed;\n\n\t\thsakmt_kfd_open_count = 1;\n\n\t\tif (hsakmt_init_device_debugging_memory(sys_props.NumNodes) != HSAKMT_STATUS_SUCCESS)\n\t\t\tpr_warn(\"Insufficient Memory. Debugging unavailable\\n\");\n\n\t\thsakmt_init_counter_props(sys_props.NumNodes);\n\n\t\tif (!atfork_installed) {\n\t\t\t/* Atfork handlers cannot be uninstalled and\n\t\t\t * must be installed only once. Otherwise\n\t\t\t * prepare will deadlock when trying to take\n\t\t\t * the same lock multiple times.\n\t\t\t */\n\t\t\tpthread_atfork(prepare_fork_handler,\n\t\t\t\t       parent_fork_handler,\n\t\t\t\t       child_fork_handler);\n\t\t\tatfork_installed = true;\n\t\t}\n\t} else {\n\t\thsakmt_kfd_open_count++;\n\t\tresult = HSAKMT_STATUS_KERNEL_ALREADY_OPENED;\n\t}\n\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn result;\ntopology_sysfs_failed:\nkfd_version_failed:\n\tif (fd >= 0)\n\t\tclose(fd);\nopen_failed:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\n\treturn result;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtCloseKFD(void)\n{\n\tHSAKMT_STATUS result;\n\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\tif (hsakmt_kfd_open_count > 0)\t{\n\t\tif (--hsakmt_kfd_open_count == 0) {\n\t\t\thsakmt_destroy_counter_props();\n\t\t\thsakmt_destroy_device_debugging_memory();\n\t\t}\n\n\t\tresult = HSAKMT_STATUS_SUCCESS;\n\t} else\n\t\tresult = HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED;\n\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\n\treturn result;\n}\n"
  },
  {
    "path": "libhsakmt/src/pc_sampling.c",
    "content": "/*\n * Copyright © 2023 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <assert.h>\n#include <errno.h>\n\n#define INVALID_TRACE_ID 0x0\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingSupport(void)\n{\n    CHECK_KFD_OPEN();\n    CHECK_KFD_MINOR_VERSION(16);\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingQueryCapabilities(HSAuint32 NodeId, void *sample_info,\n                            HSAuint32 sample_info_sz, HSAuint32 *size)\n{\n    struct kfd_ioctl_pc_sample_args args = {0};\n    uint32_t gpu_id;\n\n    if (size == NULL)\n        return HSAKMT_STATUS_INVALID_PARAMETER;\n\n    CHECK_KFD_OPEN();\n    CHECK_KFD_MINOR_VERSION(16);\n\n    HSAKMT_STATUS ret = hsakmt_validate_nodeid(NodeId, &gpu_id);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        pr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n        return ret;\n    }\n    assert(sizeof(HsaPcSamplingInfo) == sizeof(struct kfd_pc_sample_info));\n\n    args.op = KFD_IOCTL_PCS_OP_QUERY_CAPABILITIES;\n    args.gpu_id = gpu_id;\n    args.sample_info_ptr = (uint64_t)sample_info;\n    args.num_sample_info = sample_info_sz;\n    args.flags = 0;\n\n    int err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_PC_SAMPLE, &args);\n\n    *size = args.num_sample_info;\n\n    if (err) {\n        switch (errno) {\n        case ENOSPC:\n                return HSAKMT_STATUS_BUFFER_TOO_SMALL;\n        case EINVAL:\n                return HSAKMT_STATUS_INVALID_PARAMETER;\n        case EOPNOTSUPP:\n                return HSAKMT_STATUS_NOT_SUPPORTED;\n        case EBUSY:\n                return HSAKMT_STATUS_UNAVAILABLE;\n        default:\n                return HSAKMT_STATUS_ERROR;\n        }\n    }\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingCreate(HSAuint32 NodeId, HsaPcSamplingInfo *sample_info,\n\t\t\t\t\t\tHsaPcSamplingTraceId *traceId)\n{\n    struct kfd_ioctl_pc_sample_args args = {0};\n    uint32_t gpu_id;\n\n    if (sample_info == NULL || traceId == NULL)\n        return HSAKMT_STATUS_INVALID_PARAMETER;\n\n    CHECK_KFD_OPEN();\n\n    *traceId = INVALID_TRACE_ID;\n    HSAKMT_STATUS ret = hsakmt_validate_nodeid(NodeId, &gpu_id);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        pr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n        return ret;\n    }\n\n    args.op = KFD_IOCTL_PCS_OP_CREATE;\n    args.gpu_id = gpu_id;\n    args.sample_info_ptr = (uint64_t)sample_info;\n    args.num_sample_info = 1;\n    args.trace_id = INVALID_TRACE_ID;\n\n    int err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_PC_SAMPLE, &args);\n    if (err) {\n        switch (errno) {\n        case EINVAL:\n            return HSAKMT_STATUS_INVALID_PARAMETER;\n        case ENOMEM:\n            return HSAKMT_STATUS_NO_MEMORY;\n        case EBUSY:\n            return HSAKMT_STATUS_UNAVAILABLE;\n        default:\n            return HSAKMT_STATUS_ERROR;\n        }\n    }\n\n    *traceId = args.trace_id;\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingDestroy(HSAuint32 NodeId, HsaPcSamplingTraceId traceId)\n{\n    struct kfd_ioctl_pc_sample_args args = {0};\n    uint32_t gpu_id;\n\n    if (traceId == INVALID_TRACE_ID)\n        return HSAKMT_STATUS_INVALID_HANDLE;\n\n    CHECK_KFD_OPEN();\n\n    HSAKMT_STATUS ret = hsakmt_validate_nodeid(NodeId, &gpu_id);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        pr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n        return ret;\n    }\n\n    hsaKmtPcSamplingStop(NodeId, traceId);\n\n    args.op = KFD_IOCTL_PCS_OP_DESTROY;\n    args.gpu_id = gpu_id;\n    args.trace_id = traceId;\n\n    int err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_PC_SAMPLE, &args);\n    if (err) {\n        if (errno == EINVAL)\n            return HSAKMT_STATUS_INVALID_PARAMETER;\n        return HSAKMT_STATUS_ERROR;\n    }\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingStart(HSAuint32 NodeId, HsaPcSamplingTraceId traceId)\n{\n    struct kfd_ioctl_pc_sample_args args = {0};\n    uint32_t gpu_id;\n\n    if (traceId == INVALID_TRACE_ID)\n        return HSAKMT_STATUS_INVALID_HANDLE;\n\n    CHECK_KFD_OPEN();\n\n    HSAKMT_STATUS ret = hsakmt_validate_nodeid(NodeId, &gpu_id);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        pr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n        return ret;\n    }\n\n    args.op = KFD_IOCTL_PCS_OP_START;\n    args.gpu_id = gpu_id;\n    args.trace_id = traceId;\n\n    int err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_PC_SAMPLE, &args);\n    if (err) {\n        switch (errno) {\n        case EINVAL:\n            return HSAKMT_STATUS_INVALID_PARAMETER;\n        case ENOMEM:\n            return HSAKMT_STATUS_OUT_OF_RESOURCES;\n        case EBUSY:\n            return HSAKMT_STATUS_UNAVAILABLE;\n        case EALREADY:\n            return HSAKMT_STATUS_KERNEL_ALREADY_OPENED;\n        default:\n            return HSAKMT_STATUS_ERROR;\n        }\n    }\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPcSamplingStop(HSAuint32 NodeId, HsaPcSamplingTraceId traceId)\n{\n    struct kfd_ioctl_pc_sample_args args = {0};\n    uint32_t gpu_id;\n\n    if (traceId == INVALID_TRACE_ID)\n        return HSAKMT_STATUS_INVALID_HANDLE;\n\n    CHECK_KFD_OPEN();\n\n    HSAKMT_STATUS ret = hsakmt_validate_nodeid(NodeId, &gpu_id);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        pr_err(\"[%s] invalid node ID: %d\\n\", __func__, NodeId);\n        return ret;\n    }\n\n    args.op = KFD_IOCTL_PCS_OP_STOP;\n    args.gpu_id = gpu_id;\n    args.trace_id = traceId;\n\n    int err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_PC_SAMPLE, &args);\n    if (err) {\n        switch (errno) {\n        case EINVAL:\n            return HSAKMT_STATUS_INVALID_PARAMETER;\n        case EALREADY:\n            return HSAKMT_STATUS_KERNEL_ALREADY_OPENED;\n        default:\n            return HSAKMT_STATUS_ERROR;\n        }\n    }\n    return HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/src/perfctr.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <linux/perf_event.h>\n#include <sys/syscall.h>\n#include \"libhsakmt.h\"\n#include \"pmc_table.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <unistd.h>\n#include <sys/ioctl.h>\n#include <errno.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n#include <semaphore.h>\n\n#define BITS_PER_BYTE\t\tCHAR_BIT\n\n#define HSA_PERF_MAGIC4CC\t0x54415348\n\nenum perf_trace_state {\n\tPERF_TRACE_STATE__STOPPED = 0,\n\tPERF_TRACE_STATE__STARTED\n};\n\nstruct perf_trace_block {\n\tenum perf_block_id block_id;\n\tuint32_t num_counters;\n\tuint64_t *counter_id;\n\tint *perf_event_fd;\n};\n\nstruct perf_trace {\n\tuint32_t magic4cc;\n\tuint32_t gpu_id;\n\tenum perf_trace_state state;\n\tuint32_t num_blocks;\n\tvoid *buf;\n\tuint64_t buf_size;\n\tstruct perf_trace_block blocks[0];\n};\n\nstruct perf_counts_values {\n\tunion {\n\t\tstruct {\n\t\t\tuint64_t val;\n\t\t\tuint64_t ena;\n\t\t\tuint64_t run;\n\t\t};\n\t\tuint64_t values[3];\n\t};\n};\n\nstatic HsaCounterProperties **counter_props;\nstatic unsigned int counter_props_count;\n\nstatic ssize_t readn(int fd, void *buf, size_t n)\n{\n\tsize_t left = n;\n\tssize_t bytes;\n\n\twhile (left) {\n\t\tbytes = read(fd, buf, left);\n\t\tif (!bytes) /* reach EOF */\n\t\t\treturn (n - left);\n\t\tif (bytes < 0) {\n\t\t\tif (errno == EINTR) /* read got interrupted */\n\t\t\t\tcontinue;\n\t\t\telse\n\t\t\t\treturn -errno;\n\t\t}\n\t\tleft -= bytes;\n\t\tbuf = VOID_PTR_ADD(buf, bytes);\n\t}\n\treturn n;\n}\n\nHSAKMT_STATUS hsakmt_init_counter_props(unsigned int NumNodes)\n{\n\tcounter_props = calloc(NumNodes, sizeof(struct HsaCounterProperties *));\n\tif (!counter_props) {\n\t\tpr_warn(\"Profiling is not available.\\n\");\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t}\n\n\tcounter_props_count = NumNodes;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nvoid hsakmt_destroy_counter_props(void)\n{\n\tunsigned int i;\n\n\tif (!counter_props)\n\t\treturn;\n\n\tfor (i = 0; i < counter_props_count; i++)\n\t\tif (counter_props[i]) {\n\t\t\tfree(counter_props[i]);\n\t\t\tcounter_props[i] = NULL;\n\t\t}\n\n\tfree(counter_props);\n}\n\nstatic int blockid2uuid(enum perf_block_id block_id, HSA_UUID *uuid)\n{\n\tint rc = 0;\n\n\tswitch (block_id) {\n\tcase PERFCOUNTER_BLOCKID__CB:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_CB;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__CPF:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_CPF;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__CPG:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_CPG;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__DB:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_DB;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__GDS:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_GDS;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__GRBM:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_GRBM;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__GRBMSE:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_GRBMSE;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__IA:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_IA;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__MC:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_MC;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__PASC:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_PASC;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__PASU:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_PASU;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__SPI:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_SPI;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__SRBM:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_SRBM;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__SQ:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_SQ;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__SX:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_SX;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TA:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TA;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TCA:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TCA;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TCC:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TCC;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TCP:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TCP;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TCS:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TCS;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__TD:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_TD;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__VGT:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_VGT;\n\t\tbreak;\n\tcase PERFCOUNTER_BLOCKID__WD:\n\t\t*uuid = HSA_PROFILEBLOCK_AMD_WD;\n\t\tbreak;\n\tdefault:\n\t\t/* If we reach this point, it's a bug */\n\t\trc = -1;\n\t\tbreak;\n\t}\n\n\treturn rc;\n}\n\nstatic HSAuint32 get_block_concurrent_limit(uint32_t node_id,\n\t\t\t\t\t\tHSAuint32 block_id)\n{\n\tuint32_t i;\n\tHsaCounterBlockProperties *block = &counter_props[node_id]->Blocks[0];\n\n\tfor (i = 0; i < PERFCOUNTER_BLOCKID__MAX; i++) {\n\t\tif (block->Counters[0].BlockIndex == block_id)\n\t\t\treturn block->NumConcurrent;\n\t\tblock = (HsaCounterBlockProperties *)&block->Counters[block->NumCounters];\n\t}\n\n\treturn 0;\n}\n\nstatic HSAKMT_STATUS perf_trace_ioctl(struct perf_trace_block *block,\n\t\t\t\t      uint32_t cmd)\n{\n\tuint32_t i;\n\n\tfor (i = 0; i < block->num_counters; i++) {\n\t\tif (block->perf_event_fd[i] < 0)\n\t\t\treturn HSAKMT_STATUS_UNAVAILABLE;\n\t\tif (ioctl(block->perf_event_fd[i], cmd, NULL))\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS query_trace(int fd, uint64_t *buf)\n{\n\tstruct perf_counts_values content;\n\n\tif (fd < 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tif (readn(fd, &content, sizeof(content)) != sizeof(content))\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t*buf = content.val;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcGetCounterProperties(HSAuint32 NodeId,\n\t\t\t\t\t\t      HsaCounterProperties **CounterProperties)\n{\n\tHSAKMT_STATUS rc = HSAKMT_STATUS_SUCCESS;\n\tuint32_t gpu_id, i, block_id;\n\tuint32_t counter_props_size = 0;\n\tuint32_t total_counters = 0;\n\tuint32_t total_concurrent = 0;\n\tstruct perf_counter_block block = {0};\n\tuint32_t total_blocks = 0;\n\tHsaCounterBlockProperties *block_prop;\n\n\tif (!counter_props)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tif (!CounterProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (hsakmt_validate_nodeid(NodeId, &gpu_id) != HSAKMT_STATUS_SUCCESS)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\tif (counter_props[NodeId]) {\n\t\t*CounterProperties = counter_props[NodeId];\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tfor (i = 0; i < PERFCOUNTER_BLOCKID__MAX; i++) {\n\t\trc = hsakmt_get_block_properties(NodeId, i, &block);\n\t\tif (rc != HSAKMT_STATUS_SUCCESS)\n\t\t\treturn rc;\n\t\ttotal_concurrent += block.num_of_slots;\n\t\ttotal_counters += block.num_of_counters;\n\t\t/* If num_of_slots=0, this block doesn't exist */\n\t\tif (block.num_of_slots)\n\t\t\ttotal_blocks++;\n\t}\n\n\tcounter_props_size = sizeof(HsaCounterProperties) +\n\t\t\tsizeof(HsaCounterBlockProperties) * (total_blocks - 1) +\n\t\t\tsizeof(HsaCounter) * (total_counters - total_blocks);\n\n\tcounter_props[NodeId] = malloc(counter_props_size);\n\tif (!counter_props[NodeId])\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tcounter_props[NodeId]->NumBlocks = total_blocks;\n\tcounter_props[NodeId]->NumConcurrent = total_concurrent;\n\n\tblock_prop = &counter_props[NodeId]->Blocks[0];\n\tfor (block_id = 0; block_id < PERFCOUNTER_BLOCKID__MAX; block_id++) {\n\t\trc = hsakmt_get_block_properties(NodeId, block_id, &block);\n\t\tif (rc != HSAKMT_STATUS_SUCCESS) {\n\t\t\tfree(counter_props[NodeId]);\n\t\t\tcounter_props[NodeId] = NULL;\n\t\t\treturn rc;\n\t\t}\n\n\t\tif (!block.num_of_slots) /* not a valid block */\n\t\t\tcontinue;\n\n\t\tblockid2uuid(block_id, &block_prop->BlockId);\n\t\tblock_prop->NumCounters = block.num_of_counters;\n\t\tblock_prop->NumConcurrent = block.num_of_slots;\n\t\tfor (i = 0; i < block.num_of_counters; i++) {\n\t\t\tblock_prop->Counters[i].BlockIndex = block_id;\n\t\t\tblock_prop->Counters[i].CounterId = block.counter_ids[i];\n\t\t\tblock_prop->Counters[i].CounterSizeInBits = block.counter_size_in_bits;\n\t\t\tblock_prop->Counters[i].CounterMask = block.counter_mask;\n\t\t\tblock_prop->Counters[i].Flags.ui32.Global = 1;\n\t\t\tblock_prop->Counters[i].Type = HSA_PROFILE_TYPE_NONPRIV_IMMEDIATE;\n\t\t}\n\n\t\tblock_prop = (HsaCounterBlockProperties *)&block_prop->Counters[block_prop->NumCounters];\n\t}\n\n\t*CounterProperties = counter_props[NodeId];\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* Registers a set of (HW) counters to be used for tracing/profiling */\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcRegisterTrace(HSAuint32 NodeId,\n\t\t\t\t\t       HSAuint32 NumberOfCounters,\n\t\t\t\t\t       HsaCounter *Counters,\n\t\t\t\t\t       HsaPmcTraceRoot *TraceRoot)\n{\n\tuint32_t gpu_id, i, j;\n\tuint64_t min_buf_size = 0;\n\tstruct perf_trace *trace = NULL;\n\tuint32_t concurrent_limit;\n\tconst uint32_t MAX_COUNTERS = 512;\n\n\t/* Declare performance counter ID 2D array as a contiguous block */\n\tuint64_t *counter_id = malloc(\n\t\t\tPERFCOUNTER_BLOCKID__MAX * MAX_COUNTERS * sizeof(uint64_t));\n\tuint32_t num_counters[PERFCOUNTER_BLOCKID__MAX] = {0};\n\tuint32_t block, num_blocks = 0, total_counters = 0;\n\tuint64_t *counter_id_ptr;\n\tint *fd_ptr;\n\n\tpr_debug(\"[%s] Number of counters %d\\n\", __func__, NumberOfCounters);\n\n\tif (counter_id == NULL) {\n\t\tpr_err(\"Failed to allocate memory for counter_id. Requested %zu bytes.\\n\",\n\t\t\t\tPERFCOUNTER_BLOCKID__MAX * MAX_COUNTERS * sizeof(uint64_t));\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t}\n\n\tif (!counter_props) {\n\t\tpr_err(\"Profiling is not available, counter_props is NULL.\\n\");\n\t\tgoto no_memory_exit;\n\t}\n\n\tif (!Counters || !TraceRoot || NumberOfCounters == 0)\n\t\tgoto invalid_parameter_exit;\n\n\tif (hsakmt_validate_nodeid(NodeId, &gpu_id) != HSAKMT_STATUS_SUCCESS) {\n\t\tfree(counter_id);\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t}\n\n\tif (NumberOfCounters > MAX_COUNTERS) {\n\t\tpr_err(\"MAX_COUNTERS is too small for %d.\\n\", NumberOfCounters);\n\t\tgoto no_memory_exit;\n\t}\n\n\t/* Calculating the minimum buffer size */\n\tfor (i = 0; i < NumberOfCounters; i++) {\n\t\tif (Counters[i].BlockIndex >= PERFCOUNTER_BLOCKID__MAX)\n\t\t\tgoto invalid_parameter_exit;\n\t\t/* Only privileged counters need to register */\n\t\tif (Counters[i].Type > HSA_PROFILE_TYPE_PRIVILEGED_STREAMING)\n\t\t\tcontinue;\n\t\tmin_buf_size += Counters[i].CounterSizeInBits/BITS_PER_BYTE;\n\t\t/* j: the first blank entry in the block to record counter_id */\n\t\tj = num_counters[Counters[i].BlockIndex];\n\t\t/* Make sure counter_id stays within bounds */\n\t\tif (j >= MAX_COUNTERS) {\n\t\t\tpr_err(\"Counter ID exceeded MAX_COUNTERS for block %d.\\n\",\n\t\t\t\t\tCounters[i].BlockIndex);\n\t\t\tgoto invalid_parameter_exit;\n\t\t}\n\t\t/* Initialize counter_id */\n\t\tcounter_id[Counters[i].BlockIndex * MAX_COUNTERS + j] = Counters[i].CounterId;\n\t\tnum_counters[Counters[i].BlockIndex]++;\n\t\ttotal_counters++;\n\t}\n\n\t/* Verify that the number of counters per block is not larger than the\n\t * number of slots.\n\t */\n\tfor (i = 0; i < PERFCOUNTER_BLOCKID__MAX; i++) {\n\t\tif (!num_counters[i])\n\t\t\tcontinue;\n\t\tconcurrent_limit = get_block_concurrent_limit(NodeId, i);\n\t\tif (!concurrent_limit) {\n\t\t\tpr_err(\"Invalid block ID: %d\\n\", i);\n\t\t\tgoto invalid_parameter_exit;\n\t\t}\n\t\tif (num_counters[i] > concurrent_limit) {\n\t\t\tpr_err(\"Counters exceed the limit.\\n\");\n\t\t\tgoto invalid_parameter_exit;\n\t\t}\n\t\tnum_blocks++;\n\t}\n\n\tif (!num_blocks)\n\t\tgoto invalid_parameter_exit;\n\n\t/* Now we have sorted blocks/counters information in\n\t * num_counters[block_id] and counter_id[block_id][]. Allocate trace\n\t * and record the information.\n\t */\n\ttrace = (struct perf_trace *)calloc(sizeof(struct perf_trace)\n\t\t\t+ sizeof(struct perf_trace_block) * num_blocks\n\t\t\t+ sizeof(uint64_t) * total_counters\n\t\t\t+ sizeof(int) * total_counters,\n\t\t\t1);\n\tif (!trace) {\n\t\tpr_err(\"Failed to allocate memory for trace. Requested %zu bytes.\\n\",\n\t\t\t\tsizeof(struct perf_trace)\n\t\t\t\t+ sizeof(struct perf_trace_block) * num_blocks\n\t\t\t\t+ sizeof(uint64_t) * total_counters\n\t\t\t\t+ sizeof(int) * total_counters);\n\t\tgoto no_memory_exit;\n\t}\n\n\t/* Allocated area is partitioned as:\n\t * +---------------------------------+ trace\n\t * |    perf_trace                   |\n\t * |---------------------------------| trace->blocks[0]\n\t * | perf_trace_block 0              |\n\t * | ....                            |\n\t * | perf_trace_block N-1            | trace->blocks[N-1]\n\t * |---------------------------------| <-- counter_id_ptr starts here\n\t * | block 0's counter IDs(uint64_t) |\n\t * | ......                          |\n\t * | block N-1's counter IDs         |\n\t * |---------------------------------| <-- perf_event_fd starts here\n\t * | block 0's perf_event_fds(int)   |\n\t * | ......                          |\n\t * | block N-1's perf_event_fds      |\n\t * +---------------------------------+\n\t */\n\tblock = 0;\n\tcounter_id_ptr = (uint64_t *)((char *)\n\t\t\ttrace + sizeof(struct perf_trace)\n\t\t\t+ sizeof(struct perf_trace_block) * num_blocks);\n\tfd_ptr = (int *)(counter_id_ptr + total_counters);\n\t/* Fill in each block's information to the TraceId */\n\tfor (i = 0; i < PERFCOUNTER_BLOCKID__MAX; i++) {\n\t\tif (!num_counters[i]) /* not a block to trace */\n\t\t\tcontinue;\n\t\t/* Following perf_trace + perf_trace_block x N are those\n\t\t * counter_id arrays. Assign the counter_id array belonging to\n\t\t * this block.\n\t\t */\n\t\ttrace->blocks[block].counter_id = counter_id_ptr;\n\t\t/* Fill in counter IDs to the counter_id array. */\n\t\tfor (j = 0; j < num_counters[i]; j++)\n\t\t\ttrace->blocks[block].counter_id[j] = counter_id[i * MAX_COUNTERS + j];\n\t\ttrace->blocks[block].perf_event_fd = fd_ptr;\n\t\t/* how many counters to trace */\n\t\ttrace->blocks[block].num_counters = num_counters[i];\n\t\t/* block index in \"enum perf_block_id\" */\n\t\ttrace->blocks[block].block_id = i;\n\t\tblock++; /* move to next */\n\t\tcounter_id_ptr += num_counters[i];\n\t\tfd_ptr += num_counters[i];\n\t}\n\n\ttrace->magic4cc = HSA_PERF_MAGIC4CC;\n\ttrace->gpu_id = gpu_id;\n\ttrace->state = PERF_TRACE_STATE__STOPPED;\n\ttrace->num_blocks = num_blocks;\n\n\tTraceRoot->NumberOfPasses = 1;\n\tTraceRoot->TraceBufferMinSizeBytes = PAGE_ALIGN_UP(min_buf_size);\n\tTraceRoot->TraceId = PORT_VPTR_TO_UINT64(trace);\n\n\tfree(trace);\n\tfree(counter_id);\n\treturn HSAKMT_STATUS_SUCCESS;\n\n\tno_memory_exit:\n\t\tfree(counter_id);\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tinvalid_parameter_exit:\n\t\tfree(counter_id);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n}\n\n/* Unregisters a set of (HW) counters used for tracing/profiling */\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcUnregisterTrace(HSAuint32 NodeId,\n\t\t\t\t\t\t HSATraceId TraceId)\n{\n\tuint32_t gpu_id;\n\tstruct perf_trace *trace;\n\n\tpr_debug(\"[%s] Trace ID 0x%lx\\n\", __func__, TraceId);\n\n\tif (TraceId == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (hsakmt_validate_nodeid(NodeId, &gpu_id) != HSAKMT_STATUS_SUCCESS)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\ttrace = (struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tif (trace->gpu_id != gpu_id)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\t/* If the trace is in the running state, stop it */\n\tif (trace->state == PERF_TRACE_STATE__STARTED) {\n\t\tHSAKMT_STATUS status = hsaKmtPmcStopTrace(TraceId);\n\n\t\tif (status != HSAKMT_STATUS_SUCCESS)\n\t\t\treturn status;\n\t}\n\n\tfree(trace);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcAcquireTraceAccess(HSAuint32 NodeId,\n\t\t\t\t\t\t    HSATraceId TraceId)\n{\n\tstruct perf_trace *trace;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint32_t gpu_id;\n\n\tpr_debug(\"[%s] Trace ID 0x%lx\\n\", __func__, TraceId);\n\n\tif (TraceId == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\ttrace = (struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tif (hsakmt_validate_nodeid(NodeId, &gpu_id) != HSAKMT_STATUS_SUCCESS)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcReleaseTraceAccess(HSAuint32 NodeId,\n\t\t\t\t\t\t    HSATraceId TraceId)\n{\n\tstruct perf_trace *trace;\n\n\tpr_debug(\"[%s] Trace ID 0x%lx\\n\", __func__, TraceId);\n\n\tif (TraceId == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\ttrace = (struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n\n/* Starts tracing operation on a previously established set of performance counters */\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcStartTrace(HSATraceId TraceId,\n\t\t\t\t\t    void *TraceBuffer,\n\t\t\t\t\t    HSAuint64 TraceBufferSizeBytes)\n{\n\tstruct perf_trace *trace =\n\t\t\t(struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\tuint32_t i;\n\tint32_t j;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] Trace ID 0x%lx\\n\", __func__, TraceId);\n\n\tif (TraceId == 0 || !TraceBuffer || TraceBufferSizeBytes == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tfor (i = 0; i < trace->num_blocks; i++) {\n\t\tret = perf_trace_ioctl(&trace->blocks[i],\n\t\t\t\t\tPERF_EVENT_IOC_ENABLE);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tbreak;\n\t}\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t/* Disable enabled blocks before returning the failure. */\n\t\tj = (int32_t)i;\n\t\twhile (--j >= 0)\n\t\t\tperf_trace_ioctl(&trace->blocks[j],\n\t\t\t\t\tPERF_EVENT_IOC_DISABLE);\n\t\treturn ret;\n\t}\n\n\ttrace->state = PERF_TRACE_STATE__STARTED;\n\ttrace->buf = TraceBuffer;\n\ttrace->buf_size = TraceBufferSizeBytes;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n\n/*Forces an update of all the counters that a previously started trace operation has registered */\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcQueryTrace(HSATraceId TraceId)\n{\n\tstruct perf_trace *trace =\n\t\t\t(struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\tuint32_t i, j;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint64_t *buf;\n\tuint64_t buf_filled = 0;\n\n\tif (TraceId == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tbuf = (uint64_t *)trace->buf;\n\tpr_debug(\"[%s] Trace buffer(%p): \", __func__, buf);\n\tfor (i = 0; i < trace->num_blocks; i++)\n\t\tfor (j = 0; j < trace->blocks[i].num_counters; j++) {\n\t\t\tbuf_filled += sizeof(uint64_t);\n\t\t\tif (buf_filled > trace->buf_size)\n\t\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t\t\tret = query_trace(trace->blocks[i].perf_event_fd[j],\n\t\t\t\t\tbuf);\n\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\treturn ret;\n\t\t\tpr_debug(\"%lu_\", *buf);\n\t\t\tbuf++;\n\t\t}\n\tpr_debug(\"\\n\");\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n\n/* Stops tracing operation on a previously established set of performance counters */\nHSAKMT_STATUS HSAKMTAPI hsaKmtPmcStopTrace(HSATraceId TraceId)\n{\n\tstruct perf_trace *trace =\n\t\t\t(struct perf_trace *)PORT_UINT64_TO_VPTR(TraceId);\n\tuint32_t i;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tpr_debug(\"[%s] Trace ID 0x%lx\\n\", __func__, TraceId);\n\n\tif (TraceId == 0)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (trace->magic4cc != HSA_PERF_MAGIC4CC)\n\t\treturn HSAKMT_STATUS_INVALID_HANDLE;\n\n\tfor (i = 0; i < trace->num_blocks; i++) {\n\t\tret = perf_trace_ioctl(&trace->blocks[i],\n\t\t\t\t\tPERF_EVENT_IOC_DISABLE);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\treturn ret;\n\t}\n\n\ttrace->state = PERF_TRACE_STATE__STOPPED;\n\n\treturn ret;\n}\n"
  },
  {
    "path": "libhsakmt/src/pmc_table.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include <sys/types.h>\n#include <dirent.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include \"libhsakmt.h\"\n#include \"pmc_table.h\"\n\n/****** CB ******/\nstatic uint32_t gfx7_cb_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225\n};\n\nstatic uint32_t gfx8_cb_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395\n};\n\nstatic uint32_t gfx9_cb_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,\n421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n437\n};\n\nstatic uint32_t gfx10_cb_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,\n421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452,\n453, 454, 455, 456, 457, 458, 459, 460\n};\n\n/****** CPF ******/\nstatic uint32_t gfx7_cpf_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16\n};\n\nstatic uint32_t gfx8_cpf_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19\n};\n\nstatic uint32_t gfx9_cpf_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n};\n\nstatic uint32_t gfx10_cpf_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39\n};\n\n/****** CPG ******/\nstatic uint32_t gfx7_cpg_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45\n};\n\nstatic uint32_t gfx8_cpg_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48\n};\n\nstatic uint32_t gfx9_cpg_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58\n};\n\nstatic uint32_t gfx10_cpg_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81\n};\n\n/****** DB ******/\nstatic uint32_t gfx7_db_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256\n};\n/* gfx8_db_counter_ids are the same as gfx7_db_counter_ids */\n\nstatic uint32_t gfx9_db_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327\n};\n\nstatic uint32_t gfx10_db_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369\n};\n\n/****** GDS ******/\nstatic uint32_t gfx7_gds_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120\n};\n/* gfx8_gds_counter_ids are the same as gfx7_gds_counter_ids */\n/* gfx9_gds_counter_ids are the same as gfx7_gds_counter_ids */\n\nstatic uint32_t gfx10_gds_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122\n};\n\n/****** GRBM ******/\nstatic uint32_t gfx7_grbm_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33\n};\n/* gfx8_grbm_counter_ids are the same as gfx7_grbm_counter_ids */\n\nstatic uint32_t gfx9_grbm_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37\n};\n\nstatic uint32_t gfx10_grbm_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46\n};\n\n/****** GRBMSE ******/\nstatic uint32_t gfx7_grbmse_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14\n};\n/* gfx8_grbmse_counter_ids are the same as gfx7_grbmse_counter_ids */\n\nstatic uint32_t gfx9_grbmse_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n};\n\nstatic uint32_t gfx10_grbmse_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n};\n\n/****** IA ******/\nstatic uint32_t gfx7_ia_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17\n};\n\nstatic uint32_t gfx8_ia_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23\n};\n\nstatic uint32_t gfx9_ia_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31\n};\n/* gfx10 doesn't have IA */\n\n/****** PASC ******/\nstatic uint32_t gfx7_pasc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394\n};\n\nstatic uint32_t gfx8_pasc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396\n};\n\nstatic uint32_t gfx9_pasc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,\n421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452,\n453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468,\n469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,\n485, 486, 487, 488, 489, 490\n};\n\nstatic uint32_t gfx10_pasc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,\n421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452,\n453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468,\n469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,\n485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500,\n501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516,\n517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,\n533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548,\n549, 550, 551\n};\n\n/****** PASU ******/\nstatic uint32_t gfx7_pasu_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152\n};\n/* gfx8_pasu_counter_ids are the same as gfx7_pasu_counter_ids */\n\nstatic uint32_t gfx9_pasu_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291\n};\n\nstatic uint32_t gfx10_pasu_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265\n};\n\n/****** SPI ******/\nstatic uint32_t gfx7_spi_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185\n};\n\nstatic uint32_t gfx8_spi_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196\n};\n\nstatic uint32_t gfx9_spi_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195\n};\n\nstatic uint32_t gfx10_spi_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328\n};\n\n/****** SQ ******/\n/* Unused counters - 163-167 */\nstatic uint32_t gfx7_sq_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 168, 169,\n170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185,\n186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201,\n202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,\n218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,\n234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,\n250\n};\n\n/* Unused counters - 166, 292 - 297 */\nstatic uint32_t gfx8_sq_counter_ids[] = {\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,\n43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\n63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,\n83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,\n102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,\n118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,\n134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\n150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,\n167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,\n183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,\n199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,\n215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230,\n231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,\n247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,\n263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278,\n279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 298\n};\n\n/* Polaris 10/11/12 have the same SQ cpunter IDs but different from other gfx8's. */\n/* Unused counters - 167 and 275 are *_DUMMY_LAST */\nstatic uint32_t gfx8_pl_sq_counter_ids[] = {\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\n60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,\n79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,\n98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,\n128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,\n143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,\n158, 159, 160, 161, 162, 163, 164, 165, 168, 169, 170, 171, 172, 173, 174,\n175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,\n190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,\n205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,\n220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,\n235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,\n250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264,\n265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 276, 277, 278, 279, 280,\n281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295\n};\n\nstatic uint32_t gfx9_sq_counter_ids[] = {\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\n60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,\n79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,\n98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,\n113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,\n128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,\n143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,\n158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,\n173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 255, 256, 257, 258,\n259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,\n274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,\n289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,\n304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318,\n319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333,\n334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348,\n349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363,\n364, 365, 366, 367, 368, 369, 370, 371, 372\n};\n\nstatic uint32_t gfx10_sq_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,\n229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,\n245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,\n261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,\n277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,\n293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,\n309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,\n325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,\n341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,\n357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,\n373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388,\n389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,\n405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,\n421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436,\n437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452,\n453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468,\n469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,\n485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500,\n501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511\n};\n\n/****** SRBM ******/\nstatic uint32_t gfx7_srbm_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n};\n\nstatic uint32_t gfx8_srbm_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27\n};\n/* gfx9 doesn't have SRBM */\n/* gfx10 doesn't have SRBM */\n\n/****** SX ******/\nstatic uint32_t gfx7_sx_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33\n};\n/* gfx8_sx_counter_ids are the same as gfx7_sx_counter_ids */\n\nstatic uint32_t gfx9_sx_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207\n};\n\nstatic uint32_t gfx10_sx_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224\n};\n\n/****** TA ******/\nstatic uint32_t gfx7_ta_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110\n};\n\nstatic uint32_t gfx8_ta_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118\n};\n/* gfx9_ta_counter_ids is same as gfx8_ta_counter_ids */\n\nstatic uint32_t gfx10_ta_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,\n197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,\n213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225\n};\n\n/****** TCA ******/\nstatic uint32_t gfx7_tca_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38\n};\n\nstatic uint32_t gfx8_tca_counter_ids[] = {\n1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34\n};\n/* gfx9_tca_counter_ids is same as gfx8_tca_counter_ids */\n/* gfx10 doesn't have TCA */\n\n/****** TCC ******/\nstatic uint32_t gfx7_tcc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 159\n};\n\nstatic uint32_t gfx8_tcc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 128, 129, 130, 131, 132, 133, 134, 135, 136,\n137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,\n153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,\n169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,\n185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,\n201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216,\n217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,\n233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,\n249, 250, 251, 252, 253, 254, 255\n};\n\nstatic uint32_t gfx8_cz_tcc_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 128, 129, 130, 131, 132, 133, 134, 135, 136,\n137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,\n153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,\n169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,\n185, 186, 187, 188, 189, 190, 191\n};\n/* gfx9_tcc_counter_ids is same as gfx8_tcc_counter_ids */\n/* gfx10 doesn't have TCC */\n\n/****** TCP ******/\nstatic uint32_t gfx7_tcp_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153\n};\n\nstatic uint32_t gfx8_tcp_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,\n149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,\n165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,\n181, 182\n};\n\nstatic uint32_t gfx9_tcp_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84\n};\n\nstatic uint32_t gfx10_tcp_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76\n};\n\n/****** TCS ******/\nstatic uint32_t gfx7_tcs_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 64,\n65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,\n85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,\n104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\n120, 121, 122, 123, 124, 125, 126, 127\n};\n/* gfx8 doesn't have TCS */\n/* gfx9 doesn't have TCS */\n/* gfx10 doesn't have TCS */\n\n/****** TD ******/\nstatic uint32_t gfx7_td_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54\n};\n/* gfx8_td_counter_ids are the same as gfx7_td_counter_ids */\n\nstatic uint32_t gfx9_td_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56\n};\n\nstatic uint32_t gfx10_td_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60\n};\n\n/****** VGT ******/\nstatic uint32_t gfx7_vgt_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139\n};\n\nstatic uint32_t gfx8_vgt_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145\n};\n\nstatic uint32_t gfx8_pl_vgt_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146\n};\n\nstatic uint32_t gfx9_vgt_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,\n82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,\n101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,\n117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132,\n133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147\n};\n/* gfx10 doesn't have VGT */\n\n/****** WD ******/\nstatic uint32_t gfx7_wd_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n};\n\nstatic uint32_t gfx8_wd_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36\n};\n\nstatic uint32_t gfx9_wd_counter_ids[] = {\n0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,\n22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,\n42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57\n};\n/* gfx10 doesn't have WD */\n\nstatic struct perf_counter_block kaveri_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 8,\n\t\t.num_of_counters = sizeof(gfx7_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sq_counter_ids),\n\t\t.counter_ids = gfx7_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block hawaii_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx7_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_cb_counter_ids),\n\t\t.counter_ids = gfx7_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx7_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_cpf_counter_ids),\n\t\t.counter_ids = gfx7_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx7_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_cpg_counter_ids),\n\t\t.counter_ids = gfx7_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx7_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_db_counter_ids),\n\t\t.counter_ids = gfx7_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_gds_counter_ids),\n\t\t.counter_ids = gfx7_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx7_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbm_counter_ids),\n\t\t.counter_ids = gfx7_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx7_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbmse_counter_ids),\n\t\t.counter_ids = gfx7_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__IA] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx7_ia_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_ia_counter_ids),\n\t\t.counter_ids = gfx7_ia_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx7_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_pasc_counter_ids),\n\t\t.counter_ids = gfx7_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_pasu_counter_ids),\n\t\t.counter_ids = gfx7_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_spi_counter_ids),\n\t\t.counter_ids = gfx7_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx7_srbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_srbm_counter_ids),\n\t\t.counter_ids = gfx7_srbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 8,\n\t\t.num_of_counters = sizeof(gfx7_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sq_counter_ids),\n\t\t.counter_ids = gfx7_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sx_counter_ids),\n\t\t.counter_ids = gfx7_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx7_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_ta_counter_ids),\n\t\t.counter_ids = gfx7_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCA] = {\n\t\t.num_of_slots = 10, /* same as CZ */\n\t\t.num_of_counters = sizeof(gfx7_tca_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_tca_counter_ids),\n\t\t.counter_ids = gfx7_tca_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCC] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_tcc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_tcc_counter_ids),\n\t\t.counter_ids = gfx7_tcc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_tcp_counter_ids),\n\t\t.counter_ids = gfx7_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCS] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx7_tcs_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_tcs_counter_ids),\n\t\t.counter_ids = gfx7_tcs_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx7_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_td_counter_ids),\n\t\t.counter_ids = gfx7_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__VGT] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_vgt_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_vgt_counter_ids),\n\t\t.counter_ids = gfx7_vgt_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__WD] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_wd_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_wd_counter_ids),\n\t\t.counter_ids = gfx7_wd_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block carrizo_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cb_counter_ids),\n\t\t.counter_ids = gfx8_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpf_counter_ids),\n\t\t.counter_ids = gfx8_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpg_counter_ids),\n\t\t.counter_ids = gfx8_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx7_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_db_counter_ids),\n\t\t.counter_ids = gfx7_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_gds_counter_ids),\n\t\t.counter_ids = gfx7_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx7_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbm_counter_ids),\n\t\t.counter_ids = gfx7_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx7_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbmse_counter_ids),\n\t\t.counter_ids = gfx7_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__IA] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_ia_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ia_counter_ids),\n\t\t.counter_ids = gfx8_ia_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx8_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_pasc_counter_ids),\n\t\t.counter_ids = gfx8_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_pasu_counter_ids),\n\t\t.counter_ids = gfx7_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_spi_counter_ids),\n\t\t.counter_ids = gfx8_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx8_srbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_srbm_counter_ids),\n\t\t.counter_ids = gfx8_srbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 8,\n\t\t.num_of_counters = sizeof(gfx8_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_sq_counter_ids),\n\t\t.counter_ids = gfx8_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sx_counter_ids),\n\t\t.counter_ids = gfx7_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx8_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ta_counter_ids),\n\t\t.counter_ids = gfx8_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCA] = {\n\t\t/* PMC0: PERF_SEL~PERF_SEL3, PMC1: PERF_SEL~PERF_SEL3,\n\t\t * PMC2: PERF_SEL, PMC3: PERF_SEL. So 10 PERF_SELs in total\n\t\t */\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tca_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tca_counter_ids),\n\t\t.counter_ids = gfx8_tca_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCC] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_cz_tcc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cz_tcc_counter_ids),\n\t\t.counter_ids = gfx8_cz_tcc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcp_counter_ids),\n\t\t.counter_ids = gfx8_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx7_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_td_counter_ids),\n\t\t.counter_ids = gfx7_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__VGT] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_vgt_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_vgt_counter_ids),\n\t\t.counter_ids = gfx8_vgt_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__WD] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_wd_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_wd_counter_ids),\n\t\t.counter_ids = gfx8_wd_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block fiji_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cb_counter_ids),\n\t\t.counter_ids = gfx8_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpf_counter_ids),\n\t\t.counter_ids = gfx8_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpg_counter_ids),\n\t\t.counter_ids = gfx8_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx7_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_db_counter_ids),\n\t\t.counter_ids = gfx7_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_gds_counter_ids),\n\t\t.counter_ids = gfx7_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx7_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbm_counter_ids),\n\t\t.counter_ids = gfx7_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx7_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbmse_counter_ids),\n\t\t.counter_ids = gfx7_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__IA] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_ia_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ia_counter_ids),\n\t\t.counter_ids = gfx8_ia_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx8_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_pasc_counter_ids),\n\t\t.counter_ids = gfx8_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_pasu_counter_ids),\n\t\t.counter_ids = gfx7_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_spi_counter_ids),\n\t\t.counter_ids = gfx8_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx8_srbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_srbm_counter_ids),\n\t\t.counter_ids = gfx8_srbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 8,\n\t\t.num_of_counters = sizeof(gfx8_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_sq_counter_ids),\n\t\t.counter_ids = gfx8_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sx_counter_ids),\n\t\t.counter_ids = gfx7_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx8_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ta_counter_ids),\n\t\t.counter_ids = gfx8_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCA] = {\n\t\t.num_of_slots = 10, /* same as CZ */\n\t\t.num_of_counters = sizeof(gfx8_tca_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tca_counter_ids),\n\t\t.counter_ids = gfx8_tca_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCC] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcc_counter_ids),\n\t\t.counter_ids = gfx8_tcc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcp_counter_ids),\n\t\t.counter_ids = gfx8_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx7_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_td_counter_ids),\n\t\t.counter_ids = gfx7_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__VGT] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_vgt_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_vgt_counter_ids),\n\t\t.counter_ids = gfx8_vgt_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__WD] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_wd_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_wd_counter_ids),\n\t\t.counter_ids = gfx8_wd_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block polaris_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cb_counter_ids),\n\t\t.counter_ids = gfx8_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpf_counter_ids),\n\t\t.counter_ids = gfx8_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx8_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_cpg_counter_ids),\n\t\t.counter_ids = gfx8_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx7_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_db_counter_ids),\n\t\t.counter_ids = gfx7_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_gds_counter_ids),\n\t\t.counter_ids = gfx7_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx7_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbm_counter_ids),\n\t\t.counter_ids = gfx7_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx7_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_grbmse_counter_ids),\n\t\t.counter_ids = gfx7_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__IA] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx8_ia_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ia_counter_ids),\n\t\t.counter_ids = gfx8_ia_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx8_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_pasc_counter_ids),\n\t\t.counter_ids = gfx8_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx7_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_pasu_counter_ids),\n\t\t.counter_ids = gfx7_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_spi_counter_ids),\n\t\t.counter_ids = gfx8_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 8,\n\t\t.num_of_counters = sizeof(gfx8_pl_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_pl_sq_counter_ids),\n\t\t.counter_ids = gfx8_pl_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx8_srbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_srbm_counter_ids),\n\t\t.counter_ids = gfx8_srbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_sx_counter_ids),\n\t\t.counter_ids = gfx7_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx8_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ta_counter_ids),\n\t\t.counter_ids = gfx8_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCA] = {\n\t\t.num_of_slots = 10, /* same as CZ */\n\t\t.num_of_counters = sizeof(gfx8_tca_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tca_counter_ids),\n\t\t.counter_ids = gfx8_tca_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCC] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcc_counter_ids),\n\t\t.counter_ids = gfx8_tcc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcp_counter_ids),\n\t\t.counter_ids = gfx8_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx7_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_td_counter_ids),\n\t\t.counter_ids = gfx7_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__VGT] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_pl_vgt_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_pl_vgt_counter_ids),\n\t\t.counter_ids = gfx8_pl_vgt_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__WD] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx8_wd_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_wd_counter_ids),\n\t\t.counter_ids = gfx8_wd_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block vega_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx9_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_cb_counter_ids),\n\t\t.counter_ids = gfx9_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx9_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_cpf_counter_ids),\n\t\t.counter_ids = gfx9_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx9_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_cpg_counter_ids),\n\t\t.counter_ids = gfx9_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx9_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_db_counter_ids),\n\t\t.counter_ids = gfx9_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx7_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx7_gds_counter_ids),\n\t\t.counter_ids = gfx7_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx9_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_grbm_counter_ids),\n\t\t.counter_ids = gfx9_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx9_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_grbmse_counter_ids),\n\t\t.counter_ids = gfx9_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__IA] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx9_ia_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_ia_counter_ids),\n\t\t.counter_ids = gfx9_ia_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx9_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_pasc_counter_ids),\n\t\t.counter_ids = gfx9_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx9_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_pasu_counter_ids),\n\t\t.counter_ids = gfx9_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 18,\n\t\t.num_of_counters = sizeof(gfx9_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_spi_counter_ids),\n\t\t.counter_ids = gfx9_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 16,\n\t\t.num_of_counters = sizeof(gfx9_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_sq_counter_ids),\n\t\t.counter_ids = gfx9_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx9_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_sx_counter_ids),\n\t\t.counter_ids = gfx9_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx8_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_ta_counter_ids),\n\t\t.counter_ids = gfx8_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCA] = {\n\t\t.num_of_slots = 10, /* same as Fiji */\n\t\t/* Greenland has the same TCA counter IDs with Fiji */\n\t\t.num_of_counters = sizeof(gfx8_tca_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tca_counter_ids),\n\t\t.counter_ids = gfx8_tca_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCC] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx8_tcc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx8_tcc_counter_ids),\n\t\t.counter_ids = gfx8_tcc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx9_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_tcp_counter_ids),\n\t\t.counter_ids = gfx9_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx9_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_td_counter_ids),\n\t\t.counter_ids = gfx9_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__VGT] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx9_vgt_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_vgt_counter_ids),\n\t\t.counter_ids = gfx9_vgt_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__WD] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx9_wd_counter_ids) /\n\t\t\t\t\tsizeof(*gfx9_wd_counter_ids),\n\t\t.counter_ids = gfx9_wd_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nstatic struct perf_counter_block navi_blocks[PERFCOUNTER_BLOCKID__MAX] = {\n\t[PERFCOUNTER_BLOCKID__CB] = {\n\t\t.num_of_slots = 7,\n\t\t.num_of_counters = sizeof(gfx10_cb_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_cb_counter_ids),\n\t\t.counter_ids = gfx10_cb_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPF] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx10_cpf_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_cpf_counter_ids),\n\t\t.counter_ids = gfx10_cpf_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__CPG] = {\n\t\t.num_of_slots = 6,\n\t\t.num_of_counters = sizeof(gfx10_cpg_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_cpg_counter_ids),\n\t\t.counter_ids = gfx10_cpg_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__DB] = {\n\t\t.num_of_slots = 12,\n\t\t.num_of_counters = sizeof(gfx10_db_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_db_counter_ids),\n\t\t.counter_ids = gfx10_db_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GDS] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx10_gds_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_gds_counter_ids),\n\t\t.counter_ids = gfx10_gds_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBM] = {\n\t\t.num_of_slots = 2,\n\t\t.num_of_counters = sizeof(gfx10_grbm_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_grbm_counter_ids),\n\t\t.counter_ids = gfx10_grbm_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__GRBMSE] = {\n\t\t.num_of_slots = 1,\n\t\t.num_of_counters = sizeof(gfx10_grbmse_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_grbmse_counter_ids),\n\t\t.counter_ids = gfx10_grbmse_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASC] = {\n\t\t.num_of_slots = 11,\n\t\t.num_of_counters = sizeof(gfx10_pasc_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_pasc_counter_ids),\n\t\t.counter_ids = gfx10_pasc_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__PASU] = {\n\t\t.num_of_slots = 16,\n\t\t.num_of_counters = sizeof(gfx10_pasu_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_pasu_counter_ids),\n\t\t.counter_ids = gfx10_pasu_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SPI] = {\n\t\t.num_of_slots = 18,\n\t\t.num_of_counters = sizeof(gfx10_spi_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_spi_counter_ids),\n\t\t.counter_ids = gfx10_spi_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SQ] = {\n\t\t.num_of_slots = 16,\n\t\t.num_of_counters = sizeof(gfx10_sq_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_sq_counter_ids),\n\t\t.counter_ids = gfx10_sq_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__SX] = {\n\t\t.num_of_slots = 4,\n\t\t.num_of_counters = sizeof(gfx10_sx_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_sx_counter_ids),\n\t\t.counter_ids = gfx10_sx_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TA] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx10_ta_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_ta_counter_ids),\n\t\t.counter_ids = gfx10_ta_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TCP] = {\n\t\t.num_of_slots = 10,\n\t\t.num_of_counters = sizeof(gfx10_tcp_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_tcp_counter_ids),\n\t\t.counter_ids = gfx10_tcp_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n\t[PERFCOUNTER_BLOCKID__TD] = {\n\t\t.num_of_slots = 5,\n\t\t.num_of_counters = sizeof(gfx10_td_counter_ids) /\n\t\t\t\t\tsizeof(*gfx10_td_counter_ids),\n\t\t.counter_ids = gfx10_td_counter_ids,\n\t\t.counter_size_in_bits = 64,\n\t\t.counter_mask = BITMASK(64)\n\t},\n};\n\nHSAKMT_STATUS hsakmt_get_block_properties(uint32_t node_id,\n\t\t\t\t   enum perf_block_id block_id,\n\t\t\t\t   struct perf_counter_block *block)\n{\n\tuint32_t gfxv = hsakmt_get_gfxv_by_node_id(node_id);\n\tuint16_t dev_id = hsakmt_get_device_id_by_node_id(node_id);\n\n\tif (block_id >= PERFCOUNTER_BLOCKID__MAX ||\n\t\t\tblock_id < PERFCOUNTER_BLOCKID__FIRST)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\t/* Major GFX Version */\n\tswitch (gfxv >> 16) {\n\tcase 7:\n\t\tif (gfxv == GFX_VERSION_KAVERI)\n\t\t\t*block = kaveri_blocks[block_id];\n\t\telse\n\t\t\t*block = hawaii_blocks[block_id];\n\t\tbreak;\n\tcase 8:\n\t\tif (gfxv == GFX_VERSION_TONGA)\n\t\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t\telse if (gfxv == GFX_VERSION_CARRIZO)\n\t\t\t*block = carrizo_blocks[block_id];\n\t\telse {\n\t\t\t/*\n\t\t\t * Fiji/Polaris/VegaM cards are of the same GFXIP Engine Version (8.0.3).\n\t\t\t * Only way to differentiate b/t Fiji and Polaris/VegaM is via DID.\n\t\t\t */\n\t\t\tif (dev_id == 0x7300 || dev_id == 0x730F)\n\t\t\t\t*block = fiji_blocks[block_id];\n\t\t\telse\n\t\t\t\t*block = polaris_blocks[block_id];\n\t\t}\n\t\tbreak;\n\tcase 9:\n\t\t*block = vega_blocks[block_id];\n\t\tbreak;\n\tcase 10:\n\t\t*block = navi_blocks[block_id];\n\t\tbreak;\n\tdefault:\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/src/pmc_table.h",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef PMC_TABLE_H\n#define PMC_TABLE_H\n\n#include \"libhsakmt.h\"\n\nenum perf_block_id {\n\tPERFCOUNTER_BLOCKID__FIRST = 0,\n\t/* non-privileged */\n\tPERFCOUNTER_BLOCKID__CB = PERFCOUNTER_BLOCKID__FIRST,\n\tPERFCOUNTER_BLOCKID__CPC,\n\tPERFCOUNTER_BLOCKID__CPF,\n\tPERFCOUNTER_BLOCKID__CPG,\n\tPERFCOUNTER_BLOCKID__DB,\n\tPERFCOUNTER_BLOCKID__GDS,\n\tPERFCOUNTER_BLOCKID__GRBM,\n\tPERFCOUNTER_BLOCKID__GRBMSE,\n\tPERFCOUNTER_BLOCKID__IA,\n\tPERFCOUNTER_BLOCKID__MC,\n\tPERFCOUNTER_BLOCKID__PASC,\n\tPERFCOUNTER_BLOCKID__PASU,\n\tPERFCOUNTER_BLOCKID__SPI,\n\tPERFCOUNTER_BLOCKID__SRBM,\n\tPERFCOUNTER_BLOCKID__SQ,\n\tPERFCOUNTER_BLOCKID__SX,\n\tPERFCOUNTER_BLOCKID__TA,\n\tPERFCOUNTER_BLOCKID__TCA,\n\tPERFCOUNTER_BLOCKID__TCC,\n\tPERFCOUNTER_BLOCKID__TCP,\n\tPERFCOUNTER_BLOCKID__TCS,\n\tPERFCOUNTER_BLOCKID__TD,\n\tPERFCOUNTER_BLOCKID__VGT,\n\tPERFCOUNTER_BLOCKID__WD,\n\t/* privileged */\n\tPERFCOUNTER_BLOCKID__MAX\n};\n\nstruct perf_counter_block {\n\tuint32_t    num_of_slots;\n\tuint32_t    num_of_counters;\n\tuint32_t    *counter_ids;\n\tuint32_t    counter_size_in_bits;\n\tuint64_t    counter_mask;\n};\n\nHSAKMT_STATUS hsakmt_get_block_properties(uint32_t node_id,\n\t\t\t\t   enum perf_block_id block_id,\n\t\t\t\t   struct perf_counter_block *block);\n\n#endif // PMC_TABLE_H\n"
  },
  {
    "path": "libhsakmt/src/queues.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"fmm.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <stdlib.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <math.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n#include <errno.h>\n\n/* 1024 doorbells, 4 or 8 bytes each doorbell depending on ASIC generation */\n#define DOORBELL_SIZE(gfxv)\t(((gfxv) >= 0x90000) ? 8 : 4)\n#define DOORBELLS_PAGE_SIZE(ds)\t(1024 * (ds))\n\n#define WG_CONTEXT_DATA_SIZE_PER_CU(gfxv, node) \t\t\\\n\t(hsakmt_get_vgpr_size_per_cu(gfxv) + SGPR_SIZE_PER_CU +\t\\\n\t (node.LDSSizeInKB << 10) + HWREG_SIZE_PER_CU)\n\n#define CNTL_STACK_BYTES_PER_WAVE(gfxv)\t\\\n\t((gfxv) >= GFX_VERSION_NAVI10 ? 12 : 8)\n\n#define HWREG_SIZE_PER_CU\t0x1000\n#define DEBUGGER_BYTES_ALIGN\t64\n#define DEBUGGER_BYTES_PER_WAVE\t32\n\nstruct queue {\n\tuint32_t queue_id;\n\tuint64_t wptr;\n\tuint64_t rptr;\n\tvoid *eop_buffer;\n\tvoid *ctx_save_restore;\n\tuint32_t ctx_save_restore_size;\n\tuint32_t ctl_stack_size;\n\tuint32_t debug_memory_size;\n\tuint32_t eop_buffer_size;\n\tuint32_t total_mem_alloc_size;\n\tuint32_t gfxv;\n\tbool use_ats;\n\tbool unified_ctx_save_restore;\n\t/* This queue structure is allocated from GPU with page aligned size\n\t * but only small bytes are used. We use the extra space in the end for\n\t * cu_mask bits array.\n\t */\n\tuint32_t cu_mask_count; /* in bits */\n\tuint32_t cu_mask[0];\n};\n\nstruct process_doorbells {\n\tbool use_gpuvm;\n\tuint32_t size;\n\tvoid *mapping;\n\tpthread_mutex_t mutex;\n};\n\nstatic unsigned int num_doorbells;\nstatic struct process_doorbells *doorbells;\n\nuint32_t hsakmt_get_vgpr_size_per_cu(uint32_t gfxv)\n{\n\tuint32_t vgpr_size = 0x40000;\n\n\tif (gfxv == GFX_VERSION_GFX950 ||\n\t\t(gfxv & ~(0xff)) == GFX_VERSION_AQUA_VANJARAM ||\n\t\t gfxv == GFX_VERSION_ALDEBARAN ||\n\t\t gfxv == GFX_VERSION_ARCTURUS)\n\t\tvgpr_size = 0x80000;\n\n\telse if (gfxv == GFX_VERSION_PLUM_BONITO ||\n\t\t gfxv == GFX_VERSION_WHEAT_NAS ||\n\t\t gfxv == GFX_VERSION_GFX1200 ||\n\t\t gfxv == GFX_VERSION_GFX1201)\n\t\tvgpr_size = 0x60000;\n\n\treturn vgpr_size;\n}\n\nHSAKMT_STATUS hsakmt_init_process_doorbells(unsigned int NumNodes)\n{\n\tunsigned int i;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\t/* doorbells[] is accessed using Topology NodeId. This means doorbells[0],\n\t * which corresponds to CPU only Node, might not be used\n\t */\n\tdoorbells = malloc(NumNodes * sizeof(struct process_doorbells));\n\tif (!doorbells)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tfor (i = 0; i < NumNodes; i++) {\n\t\tdoorbells[i].use_gpuvm = false;\n\t\tdoorbells[i].size = 0;\n\t\tdoorbells[i].mapping = NULL;\n\t\tpthread_mutex_init(&doorbells[i].mutex, NULL);\n\t}\n\n\tnum_doorbells = NumNodes;\n\n\treturn ret;\n}\n\nstatic void get_doorbell_map_info(uint32_t node_id,\n\t\t\t\t  struct process_doorbells *doorbell)\n{\n\t/*\n\t * GPUVM doorbell on Tonga requires a workaround for VM TLB ACTIVE bit\n\t * lookup bug. Remove ASIC check when this is implemented in amdgpu.\n\t */\n\tuint32_t gfxv = hsakmt_get_gfxv_by_node_id(node_id);\n\tdoorbell->use_gpuvm = (hsakmt_is_dgpu && gfxv != GFX_VERSION_TONGA);\n\tdoorbell->size = DOORBELLS_PAGE_SIZE(DOORBELL_SIZE(gfxv));\n\n\tif (doorbell->size < (uint32_t) PAGE_SIZE) {\n\t\tdoorbell->size = PAGE_SIZE;\n\t}\n\n\treturn;\n}\n\nvoid hsakmt_destroy_process_doorbells(void)\n{\n\tunsigned int i;\n\n\tif (!doorbells)\n\t\treturn;\n\n\tfor (i = 0; i < num_doorbells; i++) {\n\t\tif (!doorbells[i].size)\n\t\t\tcontinue;\n\n\t\tif (doorbells[i].use_gpuvm) {\n\t\t\thsakmt_fmm_unmap_from_gpu(doorbells[i].mapping);\n\t\t\thsakmt_fmm_release(doorbells[i].mapping);\n\t\t} else\n\t\t\tmunmap(doorbells[i].mapping, doorbells[i].size);\n\t}\n\n\tfree(doorbells);\n\tdoorbells = NULL;\n\tnum_doorbells = 0;\n}\n\n/* This is a special funcion that should be called only from the child process\n * after a fork(). This will clear doorbells duplicated from the parent.\n */\nvoid hsakmt_clear_process_doorbells(void)\n{\n\tunsigned int i;\n\n\tif (!doorbells)\n\t\treturn;\n\n\tfor (i = 0; i < num_doorbells; i++) {\n\t\tif (!doorbells[i].size)\n\t\t\tcontinue;\n\n\t\tif (!doorbells[i].use_gpuvm)\n\t\t\tmunmap(doorbells[i].mapping, doorbells[i].size);\n\t}\n\n\tfree(doorbells);\n\tdoorbells = NULL;\n\tnum_doorbells = 0;\n}\n\nstatic HSAKMT_STATUS map_doorbell_apu(HSAuint32 NodeId, HSAuint32 gpu_id,\n\t\t\t\t      HSAuint64 doorbell_mmap_offset)\n{\n\tvoid *ptr;\n\n\tptr = mmap(0, doorbells[NodeId].size, PROT_READ|PROT_WRITE,\n\t\t   MAP_SHARED, hsakmt_kfd_fd, doorbell_mmap_offset);\n\n\tif (ptr == MAP_FAILED)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tdoorbells[NodeId].mapping = ptr;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS map_doorbell_dgpu(HSAuint32 NodeId, HSAuint32 gpu_id,\n\t\t\t\t       HSAuint64 doorbell_mmap_offset)\n{\n\tvoid *ptr;\n\n\tptr = hsakmt_fmm_allocate_doorbell(gpu_id, doorbells[NodeId].size,\n\t\t\t\tdoorbell_mmap_offset);\n\n\tif (!ptr)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t/* map for GPU access */\n\tif (hsakmt_fmm_map_to_gpu(ptr, doorbells[NodeId].size, NULL)) {\n\t\thsakmt_fmm_release(ptr);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tdoorbells[NodeId].mapping = ptr;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS map_doorbell(HSAuint32 NodeId, HSAuint32 gpu_id,\n\t\t\t\t  HSAuint64 doorbell_mmap_offset)\n{\n\tHSAKMT_STATUS status = HSAKMT_STATUS_SUCCESS;\n\n\tpthread_mutex_lock(&doorbells[NodeId].mutex);\n\tif (doorbells[NodeId].size) {\n\t\tpthread_mutex_unlock(&doorbells[NodeId].mutex);\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tget_doorbell_map_info(NodeId, &doorbells[NodeId]);\n\n\tif (doorbells[NodeId].use_gpuvm) {\n\t\tstatus = map_doorbell_dgpu(NodeId, gpu_id, doorbell_mmap_offset);\n\t\tif (status != HSAKMT_STATUS_SUCCESS) {\n\t\t\t/* Fall back to the old method if KFD doesn't\n\t\t\t * support doorbells in GPUVM\n\t\t\t */\n\t\t\tdoorbells[NodeId].use_gpuvm = false;\n\t\t\tstatus = map_doorbell_apu(NodeId, gpu_id, doorbell_mmap_offset);\n\t\t}\n\t} else\n\t\tstatus = map_doorbell_apu(NodeId, gpu_id, doorbell_mmap_offset);\n\n\tif (status != HSAKMT_STATUS_SUCCESS)\n\t\tdoorbells[NodeId].size = 0;\n\n\tpthread_mutex_unlock(&doorbells[NodeId].mutex);\n\n\treturn status;\n}\n\nstatic void *allocate_exec_aligned_memory_cpu(uint32_t size)\n{\n\tvoid *ptr;\n\n\t/* mmap will return a pointer with alignment equal to\n\t * sysconf(_SC_PAGESIZE).\n\t *\n\t * MAP_ANONYMOUS initializes the memory to zero.\n\t */\n\tptr = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,\n\t\t\t\tMAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n\n\tif (ptr == MAP_FAILED)\n\t\treturn NULL;\n\treturn ptr;\n}\n\n/* The bool return indicate whether the queue needs a context-save-restore area*/\nstatic bool update_ctx_save_restore_size(uint32_t nodeid, struct queue *q)\n{\n\tHsaNodeProperties node;\n\n\tif (q->gfxv < GFX_VERSION_CARRIZO)\n\t\treturn false;\n\tif (hsaKmtGetNodeProperties(nodeid, &node))\n\t\treturn false;\n\tif (node.NumFComputeCores && node.NumSIMDPerCU) {\n\t\tuint32_t ctl_stack_size, wg_data_size;\n\t\tuint32_t cu_num = node.NumFComputeCores / node.NumSIMDPerCU / node.NumXcc;\n\t\tuint32_t wave_num = (q->gfxv < GFX_VERSION_NAVI10)\n\t\t\t? MIN(cu_num * 40, node.NumShaderBanks / node.NumArrays * 512)\n\t\t\t: cu_num * 32;\n\n\t\tctl_stack_size = wave_num * CNTL_STACK_BYTES_PER_WAVE(q->gfxv) + 8;\n\t\twg_data_size = cu_num * WG_CONTEXT_DATA_SIZE_PER_CU(q->gfxv, node);\n\t\tq->ctl_stack_size = PAGE_ALIGN_UP(sizeof(HsaUserContextSaveAreaHeader)\n\t\t\t\t\t+ ctl_stack_size);\n\t\tif ((q->gfxv & 0x3f0000) == 0xA0000) {\n\t\t\t/* HW design limits control stack size to 0x7000.\n\t\t\t * This is insufficient for theoretical PM4 cases\n\t\t\t * but sufficient for AQL, limited by SPI events.\n\t\t\t */\n\t\t\tq->ctl_stack_size = MIN(q->ctl_stack_size, 0x7000);\n\t\t}\n\n\t\tq->debug_memory_size =\n\t\t\tALIGN_UP(wave_num * DEBUGGER_BYTES_PER_WAVE, DEBUGGER_BYTES_ALIGN);\n\n\t\tq->ctx_save_restore_size = q->ctl_stack_size\n\t\t\t\t\t+ PAGE_ALIGN_UP(wg_data_size);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nvoid *hsakmt_allocate_exec_aligned_memory_gpu(uint32_t size, uint32_t align, uint32_t gpu_id,\n\t\t\t\t       uint32_t NodeId, bool nonPaged,\n\t\t\t\t       bool DeviceLocal,\n\t\t\t\t       bool Uncached)\n{\n\tvoid *mem = NULL;\n\tHSAuint64 gpu_va;\n\tHsaMemFlags flags;\n\tHSAuint32 cpu_id = 0;\n\n\tflags.Value = 0;\n\tflags.ui32.HostAccess = !DeviceLocal;\n\tflags.ui32.ExecuteAccess = 1;\n\tflags.ui32.NonPaged = nonPaged;\n\tflags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n\tflags.ui32.CoarseGrain = DeviceLocal;\n\tflags.ui32.Uncached = Uncached;\n\n\tsize = ALIGN_UP(size, align);\n\n\tif (DeviceLocal && !hsakmt_zfb_support)\n\t\tmem = hsakmt_fmm_allocate_device(gpu_id, NodeId, mem, size, 0, flags);\n\telse {\n\t\t/* VRAM under ZFB mode should be supported here without any\n\t\t * additional code\n\t\t */\n\t\t/* Get the closest cpu_id to GPU NodeId for system memory allocation\n\t\t * nonPaged=0 system memory allocation uses GTT path\n\t\t */\n\t\tif (!nonPaged) {\n\t\t\tcpu_id = hsakmt_get_direct_link_cpu(NodeId);\n\t\t\tif (cpu_id == INVALID_NODEID) {\n\t\t\t\tflags.ui32.NoNUMABind = 1;\n\t\t\t\tcpu_id = 0;\n\t\t\t}\n\t\t}\n\t\tmem = hsakmt_fmm_allocate_host(gpu_id, cpu_id, mem, size, 0, flags);\n\t}\n\n\tif (!mem) {\n\t\tpr_err(\"Alloc %s memory failed size %d\\n\",\n\t\t       DeviceLocal ? \"VRAM\" : \"GTT\", size);\n\t\treturn NULL;\n\t}\n\n\tif (NodeId != 0) {\n\t\tuint32_t nodes_array[1] = {NodeId};\n\t\tHsaMemMapFlags map_flags = {0};\n\t\tHSAKMT_STATUS result;\n\n\t\tresult = hsaKmtMapMemoryToGPUNodes(mem, size, &gpu_va, map_flags, 1, nodes_array);\n\t\tif (result != HSAKMT_STATUS_SUCCESS) {\n\t\t\thsaKmtFreeMemory(mem, size);\n\t\t\treturn NULL;\n\t\t}\n\n\t\treturn mem;\n\t}\n\n\tif (hsaKmtMapMemoryToGPU(mem, size, &gpu_va) != HSAKMT_STATUS_SUCCESS) {\n\t\thsaKmtFreeMemory(mem, size);\n\t\treturn NULL;\n\t}\n\n\treturn mem;\n}\n\nvoid hsakmt_free_exec_aligned_memory_gpu(void *addr, uint32_t size, uint32_t align)\n{\n\tsize = ALIGN_UP(size, align);\n\n\tif (hsaKmtUnmapMemoryToGPU(addr) == HSAKMT_STATUS_SUCCESS)\n\t\thsaKmtFreeMemory(addr, size);\n}\n\n/*\n * Allocates memory aligned to sysconf(_SC_PAGESIZE)\n */\nstatic void *allocate_exec_aligned_memory(uint32_t size,\n\t\t\t\t\t  bool use_ats,\n\t\t\t\t\t  uint32_t gpu_id,\n\t\t\t\t\t  uint32_t NodeId,\n\t\t\t\t\t  bool nonPaged,\n\t\t\t\t\t  bool DeviceLocal,\n\t\t\t\t\t  bool Uncached)\n{\n\tif (!use_ats)\n\t\treturn hsakmt_allocate_exec_aligned_memory_gpu(size, PAGE_SIZE, gpu_id, NodeId,\n\t\t\t\t\t\t\tnonPaged, DeviceLocal,\n\t\t\t\t\t\t\tUncached);\n\treturn allocate_exec_aligned_memory_cpu(size);\n}\n\nstatic void free_exec_aligned_memory(void *addr, uint32_t size, uint32_t align,\n\t\t\t\t     bool use_ats)\n{\n\tif (!use_ats)\n\t\thsakmt_free_exec_aligned_memory_gpu(addr, size, align);\n\telse\n\t\tmunmap(addr, size);\n}\n\nstatic HSAKMT_STATUS register_svm_range(void *mem, uint32_t size,\n\t\t\t\tuint32_t gpuNode, uint32_t prefetchNode,\n\t\t\t\tuint32_t preferredNode, bool alwaysMapped)\n{\n\tHSA_SVM_ATTRIBUTE *attrs;\n\tHSAuint64 s_attr;\n\tHSAuint32 nattr;\n\tHSAuint32 flags;\n\n\tflags = HSA_SVM_FLAG_HOST_ACCESS | HSA_SVM_FLAG_GPU_EXEC;\n\n\tif (alwaysMapped) {\n\t\tCHECK_KFD_MINOR_VERSION(11);\n\t\tflags |= HSA_SVM_FLAG_GPU_ALWAYS_MAPPED;\n\t}\n\n\tnattr = 6;\n\ts_attr = sizeof(*attrs) * nattr;\n\tattrs = (HSA_SVM_ATTRIBUTE *)alloca(s_attr);\n\n\tattrs[0].type = HSA_SVM_ATTR_PREFETCH_LOC;\n\tattrs[0].value = prefetchNode;\n\tattrs[1].type = HSA_SVM_ATTR_PREFERRED_LOC;\n\tattrs[1].value = preferredNode;\n\tattrs[2].type = HSA_SVM_ATTR_CLR_FLAGS;\n\tattrs[2].value = ~flags;\n\tattrs[3].type = HSA_SVM_ATTR_SET_FLAGS;\n\tattrs[3].value = flags;\n\tattrs[4].type = HSA_SVM_ATTR_ACCESS;\n\tattrs[4].value = gpuNode;\n\tattrs[5].type = HSA_SVM_ATTR_GRANULARITY;\n\tattrs[5].value = 0xFF;\n\n\treturn hsaKmtSVMSetAttr(mem, size, nattr, attrs);\n}\n\nstatic void free_queue(struct queue *q)\n{\n\tif (q->eop_buffer)\n\t\tfree_exec_aligned_memory(q->eop_buffer,\n\t\t\t\t\t q->eop_buffer_size,\n\t\t\t\t\t PAGE_SIZE, q->use_ats);\n\tif (q->unified_ctx_save_restore)\n\t\tmunmap(q->ctx_save_restore, q->total_mem_alloc_size);\n\telse if (q->ctx_save_restore)\n\t\tfree_exec_aligned_memory(q->ctx_save_restore,\n\t\t\t\t\t q->total_mem_alloc_size,\n\t\t\t\t\t PAGE_SIZE, q->use_ats);\n\n\tfree_exec_aligned_memory((void *)q, sizeof(*q), PAGE_SIZE, q->use_ats);\n}\n\nstatic inline void fill_cwsr_header(struct queue *q, void *addr,\n\t\tHsaEvent *Event, volatile HSAint64 *ErrPayload, HSAuint32 NumXcc)\n{\n\tuint32_t i;\n\tHsaUserContextSaveAreaHeader *header;\n\n\tfor (i = 0; i < NumXcc; i++) {\n\t\theader = (HsaUserContextSaveAreaHeader *)\n\t\t\t((uintptr_t)addr + (i * q->ctx_save_restore_size));\n\t\theader->ErrorEventId = 0;\n\t\tif (Event)\n\t\t\theader->ErrorEventId = Event->EventId;\n\t\theader->ErrorReason = ErrPayload;\n\t\theader->DebugOffset = (NumXcc - i) * q->ctx_save_restore_size;\n\t\theader->DebugSize = q->debug_memory_size * NumXcc;\n\t}\n}\n\nstatic int handle_concrete_asic(struct queue *q,\n\t\t\t\tstruct kfd_ioctl_create_queue_args *args,\n\t\t\t\tuint32_t gpu_id,\n\t\t\t\tuint32_t NodeId,\n\t\t\t\tHsaEvent *Event,\n\t\t\t\tvolatile HSAint64 *ErrPayload)\n{\n\tbool ret;\n\n\tif (args->queue_type == KFD_IOC_QUEUE_TYPE_SDMA ||\n\t    args->queue_type == KFD_IOC_QUEUE_TYPE_SDMA_XGMI)\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\n\tif (q->eop_buffer_size > 0) {\n\t\tpr_info(\"Allocating VRAM for EOP\\n\");\n\t\tq->eop_buffer = allocate_exec_aligned_memory(q->eop_buffer_size,\n\t\t\t\tq->use_ats, gpu_id,\n\t\t\t\tNodeId, true, true, /* Unused for VRAM */false);\n\t\tif (!q->eop_buffer)\n\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\t\targs->eop_buffer_address = (uintptr_t)q->eop_buffer;\n\t\targs->eop_buffer_size = q->eop_buffer_size;\n\t}\n\n\tret = update_ctx_save_restore_size(NodeId, q);\n\n\tif (ret) {\n\t\tHsaNodeProperties node;\n\n\t\tif (hsaKmtGetNodeProperties(NodeId, &node))\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\n\t\targs->ctx_save_restore_size = q->ctx_save_restore_size;\n\t\targs->ctl_stack_size = q->ctl_stack_size;\n\n\t\t/* Total memory to be allocated is =\n\t\t * (Control Stack size + WG size +\n\t\t *  Debug memory area size) * num_xcc\n\t\t */\n\t\tq->total_mem_alloc_size = (q->ctx_save_restore_size +\n\t\t\t\t\tq->debug_memory_size) * node.NumXcc;\n\n\t\t/* Allocate unified memory for context save restore\n\t\t * area on dGPU.\n\t\t */\n\t\tif (!q->use_ats && hsakmt_is_svm_api_supported) {\n\t\t\tuint32_t size = PAGE_ALIGN_UP(q->total_mem_alloc_size);\n\n\t\t\tpr_info(\"Allocating GTT for CWSR\\n\");\n\t\t\tvoid *addr = hsakmt_mmap_allocate_aligned(PROT_READ | PROT_WRITE,\n\t\t\t\t\t\t     MAP_ANONYMOUS | MAP_PRIVATE,\n\t\t\t\t\t\t     size, GPU_HUGE_PAGE_SIZE, 0,\n\t\t\t\t\t\t     0, (void *)LONG_MAX, -1);\n\t\t\tif (!addr) {\n\t\t\t\tpr_err(\"mmap failed to alloc ctx area size 0x%x: %s\\n\",\n\t\t\t\t\tsize, strerror(errno));\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * To avoid fork child process COW MMU notifier\n\t\t\t\t * callback evict parent process queues.\n\t\t\t\t */\n\t\t\t\tif (madvise(addr, size, MADV_DONTFORK))\n\t\t\t\t\tpr_err(\"madvise failed -%d\\n\", errno);\n\n\t\t\t\tfill_cwsr_header(q, addr, Event, ErrPayload, node.NumXcc);\n\n\t\t\t\tHSAKMT_STATUS r = register_svm_range(addr, size,\n\t\t\t\t\t\tNodeId, NodeId, 0, true);\n\n\t\t\t\tif (r == HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\tq->ctx_save_restore = addr;\n\t\t\t\t\tq->unified_ctx_save_restore = true;\n\t\t\t\t} else {\n\t\t\t\t\tmunmap(addr, size);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!q->unified_ctx_save_restore) {\n\t\t\tq->ctx_save_restore = allocate_exec_aligned_memory(\n\t\t\t\t\t\t\tq->total_mem_alloc_size,\n\t\t\t\t\t\t\tq->use_ats, gpu_id, NodeId,\n\t\t\t\t\t\t\tfalse, false, false);\n\n\t\t\tif (!q->ctx_save_restore)\n\t\t\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\t\t\tfill_cwsr_header(q, q->ctx_save_restore, Event, ErrPayload, node.NumXcc);\n\t\t}\n\n\t\targs->ctx_save_restore_address = (uintptr_t)q->ctx_save_restore;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* A map to translate thunk queue priority (-3 to +3)\n * to KFD queue priority (0 to 15)\n * Indexed by thunk_queue_priority+3\n */\nstatic uint32_t priority_map[] = {0, 3, 5, 7, 9, 11, 15};\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueue(HSAuint32 NodeId,\n\t\t\t\t\t  HSA_QUEUE_TYPE Type,\n\t\t\t\t\t  HSAuint32 QueuePercentage,\n\t\t\t\t\t  HSA_QUEUE_PRIORITY Priority,\n\t\t\t\t\t  void *QueueAddress,\n\t\t\t\t\t  HSAuint64 QueueSizeInBytes,\n\t\t\t\t\t  HsaEvent *Event,\n\t\t\t\t\t  HsaQueueResource *QueueResource)\n{\n\tif (Type == HSA_QUEUE_SDMA_BY_ENG_ID)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn hsaKmtCreateQueueExt(NodeId, Type, QueuePercentage, Priority, 0,\n\t\t\t\t    QueueAddress, QueueSizeInBytes, Event,\n\t\t\t\t    QueueResource);\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtCreateQueueExt(HSAuint32 NodeId,\n\t\t\t\t\t     HSA_QUEUE_TYPE Type,\n\t\t\t\t\t     HSAuint32 QueuePercentage,\n\t\t\t\t\t     HSA_QUEUE_PRIORITY Priority,\n\t\t\t\t\t     HSAuint32 SdmaEngineId,\n\t\t\t\t\t     void *QueueAddress,\n\t\t\t\t\t     HSAuint64 QueueSizeInBytes,\n\t\t\t\t\t     HsaEvent *Event,\n\t\t\t\t\t     HsaQueueResource *QueueResource)\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\tuint64_t doorbell_mmap_offset;\n\tunsigned int doorbell_offset;\n\tint err;\n\tHsaNodeProperties props;\n\tuint32_t cu_num, i;\n\n\tCHECK_KFD_OPEN();\n\n\tif (Priority < HSA_QUEUE_PRIORITY_MINIMUM ||\n\t\tPriority > HSA_QUEUE_PRIORITY_MAXIMUM)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\tstruct queue *q = allocate_exec_aligned_memory(sizeof(*q),\n\t\t\tfalse, gpu_id, NodeId, true, false, true);\n\tif (!q)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tmemset(q, 0, sizeof(*q));\n\n\tq->gfxv = hsakmt_get_gfxv_by_node_id(NodeId);\n\tq->use_ats = false;\n\n\tif (q->gfxv == GFX_VERSION_TONGA)\n\t\tq->eop_buffer_size = TONGA_PAGE_SIZE;\n\telse if ((q->gfxv & ~(0xff)) == GFX_VERSION_AQUA_VANJARAM)\n\t\tq->eop_buffer_size = ((Type == HSA_QUEUE_COMPUTE) ? 4096 : 0);\n\telse if (q->gfxv >= 0x80000)\n\t\tq->eop_buffer_size = 4096;\n\n\t/* By default, CUs are all turned on. Initialize cu_mask to '1\n\t * for all CU bits.\n\t */\n\tif (hsaKmtGetNodeProperties(NodeId, &props))\n\t\tq->cu_mask_count = 0;\n\telse {\n\t\tcu_num = props.NumFComputeCores / props.NumSIMDPerCU;\n\t\t/* cu_mask_count counts bits. It must be multiple of 32 */\n\t\tq->cu_mask_count = ALIGN_UP_32(cu_num, 32);\n\t\tfor (i = 0; i < cu_num; i++)\n\t\t\tq->cu_mask[i/32] |= (1 << (i % 32));\n\t}\n\n\tstruct kfd_ioctl_create_queue_args args = {0};\n\n\targs.gpu_id = gpu_id;\n\n\tswitch (Type) {\n\tcase HSA_QUEUE_COMPUTE:\n\t\targs.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE;\n\t\tbreak;\n\tcase HSA_QUEUE_SDMA:\n\t\targs.queue_type = KFD_IOC_QUEUE_TYPE_SDMA;\n\t\tbreak;\n\tcase HSA_QUEUE_SDMA_XGMI:\n\t\targs.queue_type = KFD_IOC_QUEUE_TYPE_SDMA_XGMI;\n\t\tbreak;\n\tcase HSA_QUEUE_SDMA_BY_ENG_ID:\n\t\targs.queue_type = KFD_IOC_QUEUE_TYPE_SDMA_BY_ENG_ID;\n\t\tbreak;\n\tcase HSA_QUEUE_COMPUTE_AQL:\n\t\targs.queue_type = KFD_IOC_QUEUE_TYPE_COMPUTE_AQL;\n\t\tbreak;\n\tdefault:\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tif (Type != HSA_QUEUE_COMPUTE_AQL) {\n\t\tQueueResource->QueueRptrValue = (uintptr_t)&q->rptr;\n\t\tQueueResource->QueueWptrValue = (uintptr_t)&q->wptr;\n\t}\n\n\terr = handle_concrete_asic(q, &args, gpu_id, NodeId, Event, QueueResource->ErrorReason);\n\tif (err != HSAKMT_STATUS_SUCCESS) {\n\t\tfree_queue(q);\n\t\treturn err;\n\t}\n\n\targs.read_pointer_address = QueueResource->QueueRptrValue;\n\targs.write_pointer_address = QueueResource->QueueWptrValue;\n\targs.ring_base_address = (uintptr_t)QueueAddress;\n\targs.ring_size = QueueSizeInBytes;\n\targs.queue_percentage = QueuePercentage;\n\targs.queue_priority = priority_map[Priority+3];\n\targs.sdma_engine_id = SdmaEngineId;\n\n\terr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_CREATE_QUEUE, &args);\n\n\tif (err == -1) {\n\t\tfree_queue(q);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tq->queue_id = args.queue_id;\n\n\tif (IS_SOC15(q->gfxv)) {\n\t\tHSAuint64 mask = DOORBELLS_PAGE_SIZE(DOORBELL_SIZE(q->gfxv)) - 1;\n\n\t\t/* On SOC15 chips, the doorbell offset within the\n\t\t * doorbell page is included in the doorbell offset\n\t\t * returned by KFD. This allows CP queue doorbells to be\n\t\t * allocated dynamically (while SDMA queue doorbells fixed)\n\t\t * rather than based on the its process queue ID.\n\t\t */\n\t\tdoorbell_mmap_offset = args.doorbell_offset & ~mask;\n\t\tdoorbell_offset = args.doorbell_offset & mask;\n\t} else {\n\t\t/* On older chips, the doorbell offset within the\n\t\t * doorbell page is based on the queue ID.\n\t\t */\n\t\tdoorbell_mmap_offset = args.doorbell_offset;\n\t\tdoorbell_offset = q->queue_id * DOORBELL_SIZE(q->gfxv);\n\t}\n\n\terr = map_doorbell(NodeId, gpu_id, doorbell_mmap_offset);\n\tif (err != HSAKMT_STATUS_SUCCESS) {\n\t\thsaKmtDestroyQueue(q->queue_id);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tQueueResource->QueueId = PORT_VPTR_TO_UINT64(q);\n\tQueueResource->Queue_DoorBell = VOID_PTR_ADD(doorbells[NodeId].mapping,\n\t\t\t\t\t\t     doorbell_offset);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtUpdateQueue(HSA_QUEUEID QueueId,\n\t\t\t\t\t  HSAuint32 QueuePercentage,\n\t\t\t\t\t  HSA_QUEUE_PRIORITY Priority,\n\t\t\t\t\t  void *QueueAddress,\n\t\t\t\t\t  HSAuint64 QueueSize,\n\t\t\t\t\t  HsaEvent *Event)\n{\n\tstruct kfd_ioctl_update_queue_args arg = {0};\n\tstruct queue *q = PORT_UINT64_TO_VPTR(QueueId);\n\n\tCHECK_KFD_OPEN();\n\n\tif (Priority < HSA_QUEUE_PRIORITY_MINIMUM ||\n\t\tPriority > HSA_QUEUE_PRIORITY_MAXIMUM)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (!q)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\targ.queue_id = (HSAuint32)q->queue_id;\n\targ.ring_base_address = (uintptr_t)QueueAddress;\n\targ.ring_size = QueueSize;\n\targ.queue_percentage = QueuePercentage;\n\targ.queue_priority = priority_map[Priority+3];\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_UPDATE_QUEUE, &arg);\n\n\tif (err == -1)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtDestroyQueue(HSA_QUEUEID QueueId)\n{\n\tCHECK_KFD_OPEN();\n\n\tstruct queue *q = PORT_UINT64_TO_VPTR(QueueId);\n\tstruct kfd_ioctl_destroy_queue_args args = {0};\n\n\tif (!q)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\targs.queue_id = q->queue_id;\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_DESTROY_QUEUE, &args);\n\n\tif (err == -1) {\n\t\tpr_err(\"Failed to destroy queue: %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tfree_queue(q);\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSetQueueCUMask(HSA_QUEUEID QueueId,\n\t\t\t\t\t     HSAuint32 CUMaskCount,\n\t\t\t\t\t     HSAuint32 *QueueCUMask)\n{\n\tstruct queue *q = PORT_UINT64_TO_VPTR(QueueId);\n\tstruct kfd_ioctl_set_cu_mask_args args = {0};\n\n\tCHECK_KFD_OPEN();\n\n\tif (CUMaskCount == 0 || !QueueCUMask || ((CUMaskCount % 32) != 0))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\targs.queue_id = q->queue_id;\n\targs.num_cu_mask = CUMaskCount;\n\targs.cu_mask_ptr = (uintptr_t)QueueCUMask;\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_CU_MASK, &args);\n\n\tif (err == -1)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemcpy(q->cu_mask, QueueCUMask, CUMaskCount / 8);\n\tq->cu_mask_count = CUMaskCount;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtGetQueueInfo(\n\tHSA_QUEUEID QueueId,\n\tHsaQueueInfo *QueueInfo\n)\n{\n\tstruct queue *q = PORT_UINT64_TO_VPTR(QueueId);\n\tstruct kfd_ioctl_get_queue_wave_state_args args = {0};\n\n\tCHECK_KFD_OPEN();\n\n\tif (QueueInfo == NULL || q == NULL)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (q->ctx_save_restore == NULL)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\targs.queue_id = q->queue_id;\n\targs.ctl_stack_address = (uintptr_t)q->ctx_save_restore;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_QUEUE_WAVE_STATE, &args) < 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tQueueInfo->ControlStackTop = (void *)(args.ctl_stack_address +\n\t\t\t\tq->ctl_stack_size - args.ctl_stack_used_size);\n\tQueueInfo->UserContextSaveArea = (void *)\n\t\t\t\t (args.ctl_stack_address + q->ctl_stack_size);\n\tQueueInfo->SaveAreaSizeInBytes = args.save_area_used_size;\n\tQueueInfo->ControlStackUsedInBytes = args.ctl_stack_used_size;\n\tQueueInfo->NumCUAssigned = q->cu_mask_count;\n\tQueueInfo->CUMaskInfo = q->cu_mask;\n\tQueueInfo->QueueDetailError = 0;\n\tQueueInfo->QueueTypeExtended = 0;\n\tQueueInfo->SaveAreaHeader = q->ctx_save_restore;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSetTrapHandler(HSAuint32 Node,\n\t\t\t\t\t     void *TrapHandlerBaseAddress,\n\t\t\t\t\t     HSAuint64 TrapHandlerSizeInBytes,\n\t\t\t\t\t     void *TrapBufferBaseAddress,\n\t\t\t\t\t     HSAuint64 TrapBufferSizeInBytes)\n{\n\tstruct kfd_ioctl_set_trap_handler_args args = {0};\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\n\tCHECK_KFD_OPEN();\n\n\tresult = hsakmt_validate_nodeid(Node, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\targs.gpu_id = gpu_id;\n\targs.tba_addr = (uintptr_t)TrapHandlerBaseAddress;\n\targs.tma_addr = (uintptr_t)TrapBufferBaseAddress;\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_TRAP_HANDLER, &args);\n\n\treturn (err == -1) ? HSAKMT_STATUS_ERROR : HSAKMT_STATUS_SUCCESS;\n}\n\nuint32_t *hsakmt_convert_queue_ids(HSAuint32 NumQueues, HSA_QUEUEID *Queues)\n{\n\tuint32_t *queue_ids_ptr;\n\tunsigned int i;\n\n\tif (NumQueues == 0 || Queues == NULL)\n\t\treturn NULL;\n\n\tqueue_ids_ptr = malloc(NumQueues * sizeof(uint32_t));\n\tif (!queue_ids_ptr)\n\t\treturn NULL;\n\n\tfor (i = 0; i < NumQueues; i++) {\n\t\tstruct queue *q = PORT_UINT64_TO_VPTR(Queues[i]);\n\n\t\tif (q == NULL) {\n\t\t\tfree(queue_ids_ptr);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tqueue_ids_ptr[i] = q->queue_id;\n\t}\n\treturn queue_ids_ptr;\n}\n\nHSAKMT_STATUS\nHSAKMTAPI\nhsaKmtAllocQueueGWS(\n                HSA_QUEUEID        QueueId,\n                HSAuint32          nGWS,\n                HSAuint32          *firstGWS)\n{\n\tstruct kfd_ioctl_alloc_queue_gws_args args = {0};\n\tstruct queue *q = PORT_UINT64_TO_VPTR(QueueId);\n\n\tCHECK_KFD_OPEN();\n\n\targs.queue_id = (HSAuint32)q->queue_id;\n\targs.num_gws = nGWS;\n\n\tint err = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_ALLOC_QUEUE_GWS, &args);\n\n\tif (!err && firstGWS)\n\t\t*firstGWS = args.first_gws;\n\n\tif (!err)\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\telse if (errno == EINVAL)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\telse if (errno == EBUSY)\n\t\treturn HSAKMT_STATUS_OUT_OF_RESOURCES;\n\telse if (errno == ENODEV)\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\telse\n\t\treturn HSAKMT_STATUS_ERROR;\n}\n"
  },
  {
    "path": "libhsakmt/src/rbtree.c",
    "content": "/*\n * Copyright (C) 2002-2018 Igor Sysoev\n * Copyright (C) 2011-2018 Nginx, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"rbtree.h\"\n\nstatic inline void rbtree_left_rotate(rbtree_node_t **root,\n\t\trbtree_node_t *sentinel, rbtree_node_t *node);\nstatic inline void rbtree_right_rotate(rbtree_node_t **root,\n\t\trbtree_node_t *sentinel, rbtree_node_t *node);\n\nstatic void\nhsakmt_rbtree_insert_value(rbtree_node_t *temp, rbtree_node_t *node,\n\t\trbtree_node_t *sentinel)\n{\n\trbtree_node_t  **p;\n\n\tfor ( ;; ) {\n\n\t\tp = rbtree_key_compare(LKP_ALL, &node->key, &temp->key) < 0 ?\n\t\t\t&temp->left : &temp->right;\n\n\t\tif (*p == sentinel) {\n\t\t\tbreak;\n\t\t}\n\n\t\ttemp = *p;\n\t}\n\n\t*p = node;\n\tnode->parent = temp;\n\tnode->left = sentinel;\n\tnode->right = sentinel;\n\trbt_red(node);\n}\n\n\nvoid\nhsakmt_rbtree_insert(rbtree_t *tree, rbtree_node_t *node)\n{\n\trbtree_node_t  **root, *temp, *sentinel;\n\n\t/* a binary tree insert */\n\n\troot = &tree->root;\n\tsentinel = &tree->sentinel;\n\n\tif (*root == sentinel) {\n\t\tnode->parent = NULL;\n\t\tnode->left = sentinel;\n\t\tnode->right = sentinel;\n\t\trbt_black(node);\n\t\t*root = node;\n\n\t\treturn;\n\t}\n\n\thsakmt_rbtree_insert_value(*root, node, sentinel);\n\n\t/* re-balance tree */\n\n\twhile (node != *root && rbt_is_red(node->parent)) {\n\n\t\tif (node->parent == node->parent->parent->left) {\n\t\t\ttemp = node->parent->parent->right;\n\n\t\t\tif (rbt_is_red(temp)) {\n\t\t\t\trbt_black(node->parent);\n\t\t\t\trbt_black(temp);\n\t\t\t\trbt_red(node->parent->parent);\n\t\t\t\tnode = node->parent->parent;\n\n\t\t\t} else {\n\t\t\t\tif (node == node->parent->right) {\n\t\t\t\t\tnode = node->parent;\n\t\t\t\t\trbtree_left_rotate(root, sentinel, node);\n\t\t\t\t}\n\n\t\t\t\trbt_black(node->parent);\n\t\t\t\trbt_red(node->parent->parent);\n\t\t\t\trbtree_right_rotate(root, sentinel, node->parent->parent);\n\t\t\t}\n\n\t\t} else {\n\t\t\ttemp = node->parent->parent->left;\n\n\t\t\tif (rbt_is_red(temp)) {\n\t\t\t\trbt_black(node->parent);\n\t\t\t\trbt_black(temp);\n\t\t\t\trbt_red(node->parent->parent);\n\t\t\t\tnode = node->parent->parent;\n\n\t\t\t} else {\n\t\t\t\tif (node == node->parent->left) {\n\t\t\t\t\tnode = node->parent;\n\t\t\t\t\trbtree_right_rotate(root, sentinel, node);\n\t\t\t\t}\n\n\t\t\t\trbt_black(node->parent);\n\t\t\t\trbt_red(node->parent->parent);\n\t\t\t\trbtree_left_rotate(root, sentinel, node->parent->parent);\n\t\t\t}\n\t\t}\n\t}\n\n\trbt_black(*root);\n}\n\n\nvoid\nhsakmt_rbtree_delete(rbtree_t *tree, rbtree_node_t *node)\n{\n\tunsigned int red;\n\trbtree_node_t  **root, *sentinel, *subst, *temp, *w;\n\n\t/* a binary tree delete */\n\n\troot = &tree->root;\n\tsentinel = &tree->sentinel;\n\n\tif (node->left == sentinel) {\n\t\ttemp = node->right;\n\t\tsubst = node;\n\n\t} else if (node->right == sentinel) {\n\t\ttemp = node->left;\n\t\tsubst = node;\n\n\t} else {\n\t\tsubst = rbtree_min(node->right, sentinel);\n\n\t\tif (subst->left != sentinel) {\n\t\t\ttemp = subst->left;\n\t\t} else {\n\t\t\ttemp = subst->right;\n\t\t}\n\t}\n\n\tif (subst == *root) {\n\t\t*root = temp;\n\t\trbt_black(temp);\n\n\t\treturn;\n\t}\n\n\tred = rbt_is_red(subst);\n\n\tif (subst == subst->parent->left) {\n\t\tsubst->parent->left = temp;\n\n\t} else {\n\t\tsubst->parent->right = temp;\n\t}\n\n\tif (subst == node) {\n\n\t\ttemp->parent = subst->parent;\n\n\t} else {\n\n\t\tif (subst->parent == node) {\n\t\t\ttemp->parent = subst;\n\n\t\t} else {\n\t\t\ttemp->parent = subst->parent;\n\t\t}\n\n\t\tsubst->left = node->left;\n\t\tsubst->right = node->right;\n\t\tsubst->parent = node->parent;\n\t\trbt_copy_color(subst, node);\n\n\t\tif (node == *root) {\n\t\t\t*root = subst;\n\n\t\t} else {\n\t\t\tif (node == node->parent->left) {\n\t\t\t\tnode->parent->left = subst;\n\t\t\t} else {\n\t\t\t\tnode->parent->right = subst;\n\t\t\t}\n\t\t}\n\n\t\tif (subst->left != sentinel) {\n\t\t\tsubst->left->parent = subst;\n\t\t}\n\n\t\tif (subst->right != sentinel) {\n\t\t\tsubst->right->parent = subst;\n\t\t}\n\t}\n\n\tif (red) {\n\t\treturn;\n\t}\n\n\t/* a delete fixup */\n\n\twhile (temp != *root && rbt_is_black(temp)) {\n\n\t\tif (temp == temp->parent->left) {\n\t\t\tw = temp->parent->right;\n\n\t\t\tif (rbt_is_red(w)) {\n\t\t\t\trbt_black(w);\n\t\t\t\trbt_red(temp->parent);\n\t\t\t\trbtree_left_rotate(root, sentinel, temp->parent);\n\t\t\t\tw = temp->parent->right;\n\t\t\t}\n\n\t\t\tif (rbt_is_black(w->left) && rbt_is_black(w->right)) {\n\t\t\t\trbt_red(w);\n\t\t\t\ttemp = temp->parent;\n\n\t\t\t} else {\n\t\t\t\tif (rbt_is_black(w->right)) {\n\t\t\t\t\trbt_black(w->left);\n\t\t\t\t\trbt_red(w);\n\t\t\t\t\trbtree_right_rotate(root, sentinel, w);\n\t\t\t\t\tw = temp->parent->right;\n\t\t\t\t}\n\n\t\t\t\trbt_copy_color(w, temp->parent);\n\t\t\t\trbt_black(temp->parent);\n\t\t\t\trbt_black(w->right);\n\t\t\t\trbtree_left_rotate(root, sentinel, temp->parent);\n\t\t\t\ttemp = *root;\n\t\t\t}\n\n\t\t} else {\n\t\t\tw = temp->parent->left;\n\n\t\t\tif (rbt_is_red(w)) {\n\t\t\t\trbt_black(w);\n\t\t\t\trbt_red(temp->parent);\n\t\t\t\trbtree_right_rotate(root, sentinel, temp->parent);\n\t\t\t\tw = temp->parent->left;\n\t\t\t}\n\n\t\t\tif (rbt_is_black(w->left) && rbt_is_black(w->right)) {\n\t\t\t\trbt_red(w);\n\t\t\t\ttemp = temp->parent;\n\n\t\t\t} else {\n\t\t\t\tif (rbt_is_black(w->left)) {\n\t\t\t\t\trbt_black(w->right);\n\t\t\t\t\trbt_red(w);\n\t\t\t\t\trbtree_left_rotate(root, sentinel, w);\n\t\t\t\t\tw = temp->parent->left;\n\t\t\t\t}\n\n\t\t\t\trbt_copy_color(w, temp->parent);\n\t\t\t\trbt_black(temp->parent);\n\t\t\t\trbt_black(w->left);\n\t\t\t\trbtree_right_rotate(root, sentinel, temp->parent);\n\t\t\t\ttemp = *root;\n\t\t\t}\n\t\t}\n\t}\n\n\trbt_black(temp);\n}\n\n\nstatic inline void\nrbtree_left_rotate(rbtree_node_t **root, rbtree_node_t *sentinel,\n\t\trbtree_node_t *node)\n{\n\trbtree_node_t  *temp;\n\n\ttemp = node->right;\n\tnode->right = temp->left;\n\n\tif (temp->left != sentinel) {\n\t\ttemp->left->parent = node;\n\t}\n\n\ttemp->parent = node->parent;\n\n\tif (node == *root) {\n\t\t*root = temp;\n\n\t} else if (node == node->parent->left) {\n\t\tnode->parent->left = temp;\n\n\t} else {\n\t\tnode->parent->right = temp;\n\t}\n\n\ttemp->left = node;\n\tnode->parent = temp;\n}\n\n\nstatic inline void\nrbtree_right_rotate(rbtree_node_t **root, rbtree_node_t *sentinel,\n\t\trbtree_node_t *node)\n{\n\trbtree_node_t  *temp;\n\n\ttemp = node->left;\n\tnode->left = temp->right;\n\n\tif (temp->right != sentinel) {\n\t\ttemp->right->parent = node;\n\t}\n\n\ttemp->parent = node->parent;\n\n\tif (node == *root) {\n\t\t*root = temp;\n\n\t} else if (node == node->parent->right) {\n\t\tnode->parent->right = temp;\n\n\t} else {\n\t\tnode->parent->left = temp;\n\t}\n\n\ttemp->right = node;\n\tnode->parent = temp;\n}\n\n\nrbtree_node_t *\nhsakmt_rbtree_next(rbtree_t *tree, rbtree_node_t *node)\n{\n\trbtree_node_t  *root, *sentinel, *parent;\n\n\tsentinel = &tree->sentinel;\n\n\tif (node->right != sentinel) {\n\t\treturn rbtree_min(node->right, sentinel);\n\t}\n\n\troot = tree->root;\n\n\tfor ( ;; ) {\n\t\tparent = node->parent;\n\n\t\tif (node == root) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tif (node == parent->left) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tnode = parent;\n\t}\n}\n\nrbtree_node_t *\nhsakmt_rbtree_prev(rbtree_t *tree, rbtree_node_t *node)\n{\n\trbtree_node_t  *root, *sentinel, *parent;\n\n\tsentinel = &tree->sentinel;\n\n\tif (node->left != sentinel) {\n\t\treturn rbtree_max(node->left, sentinel);\n\t}\n\n\troot = tree->root;\n\n\tfor ( ;; ) {\n\t\tparent = node->parent;\n\n\t\tif (node == root) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\tif (node == parent->right) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tnode = parent;\n\t}\n}\n"
  },
  {
    "path": "libhsakmt/src/rbtree.h",
    "content": "/*\n * Copyright (C) 2002-2018 Igor Sysoev\n * Copyright (C) 2011-2018 Nginx, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef _RBTREE_H_\n#define _RBTREE_H_\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <sys/mman.h>\n#include <sys/time.h>\n#include <errno.h>\n#include \"rbtree_amd.h\"\n\ntypedef struct rbtree_node_s rbtree_node_t;\n\nstruct rbtree_node_s {\n\trbtree_key_t    key;\n\trbtree_node_t   *left;\n\trbtree_node_t   *right;\n\trbtree_node_t   *parent;\n\tunsigned char   color;\n\tunsigned char   data;\n};\n\ntypedef struct rbtree_s rbtree_t;\n\nstruct rbtree_s {\n\trbtree_node_t   *root;\n\trbtree_node_t   sentinel;\n};\n\n#define rbtree_init(tree)\t\t\t\t\\\n\trbtree_sentinel_init(&(tree)->sentinel);\t\\\n\t(tree)->root = &(tree)->sentinel;\n\nvoid hsakmt_rbtree_insert(rbtree_t *tree, rbtree_node_t *node);\nvoid hsakmt_rbtree_delete(rbtree_t *tree, rbtree_node_t *node);\nrbtree_node_t *hsakmt_rbtree_prev(rbtree_t *tree,\n\t\trbtree_node_t *node);\nrbtree_node_t *hsakmt_rbtree_next(rbtree_t *tree,\n\t\trbtree_node_t *node);\n\n#define rbt_red(node)\t\t\t((node)->color = 1)\n#define rbt_black(node)\t\t\t((node)->color = 0)\n#define rbt_is_red(node)\t\t((node)->color)\n#define rbt_is_black(node)\t\t(!rbt_is_red(node))\n#define rbt_copy_color(n1, n2)\t\t(n1->color = n2->color)\n\n/* a sentinel must be black */\n\n#define rbtree_sentinel_init(node)\trbt_black(node)\n\nstatic inline rbtree_node_t *\nrbtree_min(rbtree_node_t *node, rbtree_node_t *sentinel)\n{\n\twhile (node->left != sentinel) {\n\t\tnode = node->left;\n\t}\n\n\treturn node;\n}\n\n#include \"rbtree_amd.h\"\n\n#endif\n"
  },
  {
    "path": "libhsakmt/src/rbtree_amd.h",
    "content": "/*\n * Copyright © 2018 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef _RBTREE_AMD_H_\n#define _RBTREE_AMD_H_\n\ntypedef struct rbtree_key_s rbtree_key_t;\nstruct rbtree_key_s {\n#define ADDR_BIT 0\n#define SIZE_BIT 1\n\tunsigned long addr;\n\tunsigned long size;\n};\n#define BIT(x) (1<<(x))\n#define LKP_ALL (BIT(ADDR_BIT) | BIT(SIZE_BIT))\n#define LKP_ADDR (BIT(ADDR_BIT))\n#define LKP_ADDR_SIZE (BIT(ADDR_BIT) | BIT(SIZE_BIT))\n\nstatic inline rbtree_key_t\nrbtree_key(unsigned long addr, unsigned long size)\n{\n\treturn (rbtree_key_t){addr, size};\n}\n\n/*\n * compare addr, size one by one\n */\nstatic inline int\nrbtree_key_compare(unsigned int type, rbtree_key_t *key1, rbtree_key_t *key2)\n{\n\tif ((type & 1 << ADDR_BIT) && (key1->addr != key2->addr))\n\t\treturn key1->addr > key2->addr ? 1 : -1;\n\n\tif ((type & 1 << SIZE_BIT) && (key1->size != key2->size))\n\t\treturn key1->size > key2->size ? 1 : -1;\n\n\treturn 0;\n}\n#endif /*_RBTREE_AMD_H_*/\n\n/*inlcude this file again with RBTREE_HELPER defined*/\n#ifndef RBTREE_HELPER\n#define RBTREE_HELPER\n#else\n#ifndef _RBTREE_AMD_H_HELPER_\n#define _RBTREE_AMD_H_HELPER_\nstatic inline rbtree_node_t *\nrbtree_max(rbtree_node_t *node, rbtree_node_t *sentinel)\n{\n\twhile (node->right != sentinel)\n\t\tnode = node->right;\n\n\treturn node;\n}\n\n#define LEFT 0\n#define RIGHT 1\n#define MID 2\nstatic inline rbtree_node_t *\nrbtree_min_max(rbtree_t *tree, int lr)\n{\n\trbtree_node_t *sentinel = &tree->sentinel;\n\trbtree_node_t *node = tree->root;\n\n\tif (node == sentinel)\n\t\treturn NULL;\n\n\tif (lr == LEFT)\n\t\tnode = rbtree_min(node, sentinel);\n\telse if (lr == RIGHT)\n\t\tnode = rbtree_max(node, sentinel);\n\n\treturn node;\n}\n\nstatic inline rbtree_node_t *\nrbtree_node_any(rbtree_t *tree, int lmr)\n{\n\trbtree_node_t *sentinel = &tree->sentinel;\n\trbtree_node_t *node = tree->root;\n\n\tif (node == sentinel)\n\t\treturn NULL;\n\n\tif (lmr == MID)\n\t\treturn node;\n\n\treturn rbtree_min_max(tree, lmr);\n}\n\nstatic inline rbtree_node_t *\nrbtree_lookup_nearest(rbtree_t *rbtree, rbtree_key_t *key,\n\t\tunsigned int type, int lr)\n{\n\tint rc;\n\trbtree_node_t *node, *sentinel, *n = NULL;\n\n\tnode = rbtree->root;\n\tsentinel = &rbtree->sentinel;\n\n\twhile (node != sentinel) {\n\t\trc = rbtree_key_compare(type, key, &node->key);\n\n\t\tif (rc < 0) {\n\t\t\tif (lr == RIGHT)\n\t\t\t\tn = node;\n\t\t\tnode = node->left;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (rc > 0) {\n\t\t\tif (lr == LEFT)\n\t\t\t\tn = node;\n\t\t\tnode = node->right;\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn node;\n\t}\n\n\treturn n;\n}\n\nstatic inline rbtree_node_t *\nrbtree_lookup(rbtree_t *rbtree, rbtree_key_t *key,\n\t\tunsigned int type)\n{\n\treturn rbtree_lookup_nearest(rbtree, key, type, -1);\n}\n#endif /*_RBTREE_AMD_H_HELPER_*/\n\n#endif /*RBTREE_HELPER*/\n\n"
  },
  {
    "path": "libhsakmt/src/spm.c",
    "content": "/*\n * Copyright © 2020 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include <stdlib.h>\n#include <stdio.h>\n\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSPMAcquire(HSAuint32 PreferredNode)\n{\n\tint ret;\n\tstruct kfd_ioctl_spm_args args = {0};\n\tuint32_t gpu_id;\n\n\tret = hsakmt_validate_nodeid(PreferredNode, &gpu_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\tpr_err(\"[%s] invalid node ID: %d\\n\", __func__, PreferredNode);\n\t\treturn ret;\n\t}\n\n\tret = HSAKMT_STATUS_SUCCESS;\n\targs.op = KFD_IOCTL_SPM_OP_ACQUIRE;\n\targs.gpu_id = gpu_id;\n\n\tret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RLC_SPM, &args);\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSPMSetDestBuffer(HSAuint32 PreferredNode,\n\t\t\t\t\t\tHSAuint32 SizeInBytes,\n\t\t\t\t\t\tHSAuint32 * timeout,\n\t\t\t\t\t\tHSAuint32 * SizeCopied,\n\t\t\t\t\t\tvoid *DestMemoryAddress,\n\t\t\t\t\t\tbool *isSPMDataLoss)\n{\n\tint ret;\n\tstruct kfd_ioctl_spm_args args = {0};\n\tuint32_t gpu_id = 0;\n\n\tret = hsakmt_validate_nodeid(PreferredNode, &gpu_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\treturn ret;\n\t}\n\n\targs.timeout    = *timeout;\n\targs.dest_buf    = (uint64_t)DestMemoryAddress;\n\targs.buf_size   = SizeInBytes;\n\targs.op         = KFD_IOCTL_SPM_OP_SET_DEST_BUF;\n\targs.gpu_id     = gpu_id;\n\n\tret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RLC_SPM, &args);\n\n\t*SizeCopied = args.bytes_copied;\n\t*isSPMDataLoss = args.has_data_loss;\n\t*timeout = args.timeout;\n\n\treturn ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtSPMRelease(HSAuint32 PreferredNode)\n{\n\tint ret = HSAKMT_STATUS_SUCCESS;\n\tstruct kfd_ioctl_spm_args args = {0};\n\tuint32_t gpu_id;\n\n\tret = hsakmt_validate_nodeid(PreferredNode, &gpu_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\tpr_err(\"[%s] invalid node ID: %d\\n\", __func__, PreferredNode);\n\t\treturn ret;\n\t}\n\n\targs.op = KFD_IOCTL_SPM_OP_RELEASE;\n\targs.gpu_id = gpu_id;\n\n\tret = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_RLC_SPM, &args);\n\n\treturn ret;\n}\n\n\n"
  },
  {
    "path": "libhsakmt/src/svm.c",
    "content": "/*\n * Copyright © 2020 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n#include \"libhsakmt.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <sys/mman.h>\n#include <sys/time.h>\n#include <errno.h>\n\n/* Helper functions for calling KFD SVM ioctl */\n\nHSAKMT_STATUS HSAKMTAPI\nhsaKmtSVMSetAttr(void *start_addr, HSAuint64 size, unsigned int nattr,\n\t\t HSA_SVM_ATTRIBUTE *attrs)\n{\n\tstruct kfd_ioctl_svm_args *args;\n\tHSAuint64 s_attr;\n\tHSAKMT_STATUS r;\n\tHSAuint32 i;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(5);\n\n\tpr_debug(\"%s: address 0x%p size 0x%lx\\n\", __func__, start_addr, size);\n\n\tif (!start_addr || !size)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\tif ((uint64_t)start_addr & (PAGE_SIZE - 1))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\tif (size & (PAGE_SIZE - 1))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\ts_attr = sizeof(*attrs) * nattr;\n\targs = alloca(sizeof(*args) + s_attr);\n\n\targs->start_addr = (uint64_t)start_addr;\n\targs->size = size;\n\targs->op = KFD_IOCTL_SVM_OP_SET_ATTR;\n\targs->nattr = nattr;\n\tmemcpy(args->attrs, attrs, s_attr);\n\n\tfor (i = 0; i < nattr; i++) {\n\t\tif (attrs[i].type != KFD_IOCTL_SVM_ATTR_PREFERRED_LOC &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_PREFETCH_LOC &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_NO_ACCESS)\n\t\t    continue;\n\n\t\tif (attrs[i].type == KFD_IOCTL_SVM_ATTR_PREFERRED_LOC &&\n\t\t    attrs[i].value == INVALID_NODEID) {\n\t\t\targs->attrs[i].value = KFD_IOCTL_SVM_LOCATION_UNDEFINED;\n\t\t\tcontinue;\n\t\t}\n\n\t\tr = hsakmt_validate_nodeid(attrs[i].value, &args->attrs[i].value);\n\t\tif (r != HSAKMT_STATUS_SUCCESS) {\n\t\t\tpr_debug(\"invalid node ID: %d\\n\", attrs[i].value);\n\t\t\treturn r;\n\t\t} else if (!args->attrs[i].value &&\n\t\t\t   (attrs[i].type == KFD_IOCTL_SVM_ATTR_ACCESS ||\n\t\t\t    attrs[i].type == KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE ||\n\t\t\t    attrs[i].type == KFD_IOCTL_SVM_ATTR_NO_ACCESS)) {\n\t\t\tpr_debug(\"CPU node invalid for access attribute\\n\");\n\t\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t\t}\n\t}\n\n\t/* Driver does one copy_from_user, with extra attrs size */\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SVM + (s_attr << _IOC_SIZESHIFT), args);\n\tif (r) {\n\t\tpr_debug(\"op set range attrs failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI\nhsaKmtSVMGetAttr(void *start_addr, HSAuint64 size, unsigned int nattr,\n\t\t HSA_SVM_ATTRIBUTE *attrs)\n{\n\tstruct kfd_ioctl_svm_args *args;\n\tHSAuint64 s_attr;\n\tHSAKMT_STATUS r;\n\tHSAuint32 i;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(5);\n\n\tpr_debug(\"%s: address 0x%p size 0x%lx\\n\", __func__, start_addr, size);\n\n\tif (!start_addr || !size)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\tif ((uint64_t)start_addr & (PAGE_SIZE - 1))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\tif (size & (PAGE_SIZE - 1))\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\ts_attr = sizeof(*attrs) * nattr;\n\targs = alloca(sizeof(*args) + s_attr);\n\n\targs->start_addr = (uint64_t)start_addr;\n\targs->size = size;\n\targs->op = KFD_IOCTL_SVM_OP_GET_ATTR;\n\targs->nattr = nattr;\n\tmemcpy(args->attrs, attrs, s_attr);\n\n\tfor (i = 0; i < nattr; i++) {\n\t\tif (attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_NO_ACCESS)\n\t\t    continue;\n\n\t\tr = hsakmt_validate_nodeid(attrs[i].value, &args->attrs[i].value);\n\t\tif (r != HSAKMT_STATUS_SUCCESS) {\n\t\t\tpr_debug(\"invalid node ID: %d\\n\", attrs[i].value);\n\t\t\treturn r;\n\t\t} else if (!args->attrs[i].value) {\n\t\t\tpr_debug(\"CPU node invalid for access attribute\\n\");\n\t\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t\t}\n\t}\n\n\t/* Driver does one copy_from_user, with extra attrs size */\n\tr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SVM + (s_attr << _IOC_SIZESHIFT), args);\n\tif (r) {\n\t\tpr_debug(\"op get range attrs failed %s\\n\", strerror(errno));\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tmemcpy(attrs, args->attrs, s_attr);\n\n\tfor (i = 0; i < nattr; i++) {\n\t\tif (attrs[i].type != KFD_IOCTL_SVM_ATTR_PREFERRED_LOC &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_PREFETCH_LOC &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE &&\n\t\t    attrs[i].type != KFD_IOCTL_SVM_ATTR_NO_ACCESS)\n\t\t\tcontinue;\n\n\t\tswitch (attrs[i].value) {\n\t\tcase KFD_IOCTL_SVM_LOCATION_SYSMEM:\n\t\t\tattrs[i].value = 0;\n\t\t\tbreak;\n\t\tcase KFD_IOCTL_SVM_LOCATION_UNDEFINED:\n\t\t\tattrs[i].value = INVALID_NODEID;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tr = hsakmt_gpuid_to_nodeid(attrs[i].value, &attrs[i].value);\n\t\t\tif (r != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\tpr_debug(\"invalid GPU ID: %d\\n\",\n\t\t\t\t\t attrs[i].value);\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS\nhsaKmtSetGetXNACKMode(HSAint32 * enable)\n{\n\tstruct kfd_ioctl_set_xnack_mode_args args;\n\n\tCHECK_KFD_OPEN();\n\tCHECK_KFD_MINOR_VERSION(5);\n\n\targs.xnack_enabled = *enable;\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_SET_XNACK_MODE, &args)) {\n\t\tif (errno == EPERM) {\n\t\t\tpr_debug(\"set mode not supported %s\\n\",\n\t\t\t\t strerror(errno));\n\t\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\t\t} else if (errno == EBUSY) {\n\t\t\tpr_debug(\"hsakmt_ioctl queues not empty %s\\n\",\n\t\t\t\t strerror(errno));\n\t\t}\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\t*enable = args.xnack_enabled;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI\nhsaKmtSetXNACKMode(HSAint32 enable)\n{\n\treturn hsaKmtSetGetXNACKMode(&enable);\n}\n\nHSAKMT_STATUS HSAKMTAPI\nhsaKmtGetXNACKMode(HSAint32 * enable)\n{\n\t*enable = -1;\n\treturn hsaKmtSetGetXNACKMode(enable);\n}\n"
  },
  {
    "path": "libhsakmt/src/time.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetClockCounters(HSAuint32 NodeId,\n\t\t\t\t\t       HsaClockCounters *Counters)\n{\n\tHSAKMT_STATUS result;\n\tuint32_t gpu_id;\n\tstruct kfd_ioctl_get_clock_counters_args args = {0};\n\tint err;\n\n\tCHECK_KFD_OPEN();\n\n\tresult = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (result != HSAKMT_STATUS_SUCCESS)\n\t\treturn result;\n\n\targs.gpu_id = gpu_id;\n\n\terr = hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_CLOCK_COUNTERS, &args);\n\tif (err < 0) {\n\t\tresult = HSAKMT_STATUS_ERROR;\n\t} else {\n\t\t/* At this point the result is already HSAKMT_STATUS_SUCCESS */\n\t\tCounters->GPUClockCounter = args.gpu_clock_counter;\n\t\tCounters->CPUClockCounter = args.cpu_clock_counter;\n\t\tCounters->SystemClockCounter = args.system_clock_counter;\n\t\tCounters->SystemClockFrequencyHz = args.system_clock_freq;\n\t}\n\n\treturn result;\n}\n"
  },
  {
    "path": "libhsakmt/src/topology.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n * Copyright 2016-2018 Raptor Engineering, LLC. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <dirent.h>\n#include <malloc.h>\n#include <string.h>\n#include <unistd.h>\n#include <ctype.h>\n#include <limits.h>\n\n#include <errno.h>\n#include <sys/sysinfo.h>\n#include <xf86drm.h>\n#include <amdgpu.h>\n#include <amdgpu_drm.h>\n\n#include \"libhsakmt.h\"\n#include \"hsakmt/hsakmtmodel.h\"\n#include \"fmm.h\"\n\n/* Number of memory banks added by thunk on top of topology\n * This only includes static heaps like LDS, scratch and SVM,\n * not for MMIO_REMAP heap. MMIO_REMAP memory bank is reported\n * dynamically based on whether mmio aperture was mapped\n * successfully on this node.\n */\n#define NUM_OF_IGPU_HEAPS 3\n#define NUM_OF_DGPU_HEAPS 3\n/* SYSFS related */\n#define KFD_SYSFS_PATH \"/sys/devices/virtual/kfd/kfd/topology\"\n#define KFD_SYSFS_PATH_GENERATION_ID \"%s/generation_id\"\n#define KFD_SYSFS_PATH_SYSTEM_PROPERTIES \"%s/system_properties\"\n#define KFD_SYSFS_PATH_NODES \"%s/nodes\"\n\nstatic const char *get_topology_dir(void)\n{\n\tif (hsakmt_use_model)\n\t\treturn hsakmt_model_topology;\n\treturn KFD_SYSFS_PATH;\n}\n\ntypedef struct {\n\tHsaNodeProperties node;\n\tHsaMemoryProperties *mem;     /* node->NumBanks elements */\n\tHsaCacheProperties *cache;\n\tHsaIoLinkProperties *link;\n} node_props_t;\n\nstatic HsaSystemProperties *g_system;\nstatic node_props_t *g_props;\n\n/* This array caches sysfs based node IDs of CPU nodes + all supported GPU nodes.\n * It will be used to map user-node IDs to sysfs-node IDs.\n */\nstatic uint32_t *map_user_to_sysfs_node_id;\nstatic uint32_t map_user_to_sysfs_node_id_size;\nstatic uint32_t num_sysfs_nodes;\n\nstatic int processor_vendor = -1;\n/* Supported System Vendors */\nenum SUPPORTED_PROCESSOR_VENDORS {\n\tGENUINE_INTEL = 0,\n\tAUTHENTIC_AMD,\n\tIBM_POWER\n};\n/* Adding newline to make the search easier */\nstatic const char *supported_processor_vendor_name[] = {\n\t\"GenuineIntel\\n\",\n\t\"AuthenticAMD\\n\",\n\t\"\\n\"\t\t\t// POWER requires a different search method\n};\n\nstatic HSAKMT_STATUS topology_take_snapshot(void);\nstatic void topology_drop_snapshot(void);\n\nstatic const struct hsa_gfxip_table gfxip_lookup_table[] = {\n\t/* Kaveri Family */\n\t{ 0x1304, 7, 0, 0, \"Spectre\" },\n\t{ 0x1305, 7, 0, 0, \"Spectre\" },\n\t{ 0x1306, 7, 0, 0, \"Spectre\" },\n\t{ 0x1307, 7, 0, 0, \"Spectre\" },\n\t{ 0x1309, 7, 0, 0, \"Spectre\" },\n\t{ 0x130A, 7, 0, 0, \"Spectre\" },\n\t{ 0x130B, 7, 0, 0, \"Spectre\" },\n\t{ 0x130C, 7, 0, 0, \"Spectre\" },\n\t{ 0x130D, 7, 0, 0, \"Spectre\" },\n\t{ 0x130E, 7, 0, 0, \"Spectre\" },\n\t{ 0x130F, 7, 0, 0, \"Spectre\" },\n\t{ 0x1310, 7, 0, 0, \"Spectre\" },\n\t{ 0x1311, 7, 0, 0, \"Spectre\" },\n\t{ 0x1312, 7, 0, 0, \"Spooky\" },\n\t{ 0x1313, 7, 0, 0, \"Spectre\" },\n\t{ 0x1315, 7, 0, 0, \"Spectre\" },\n\t{ 0x1316, 7, 0, 0, \"Spooky\" },\n\t{ 0x1317, 7, 0, 0, \"Spooky\" },\n\t{ 0x1318, 7, 0, 0, \"Spectre\" },\n\t{ 0x131B, 7, 0, 0, \"Spectre\" },\n\t{ 0x131C, 7, 0, 0, \"Spectre\" },\n\t{ 0x131D, 7, 0, 0, \"Spectre\" },\n\t/* Hawaii Family */\n\t{ 0x67A0, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67A1, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67A2, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67A8, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67A9, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67AA, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67B0, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67B1, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67B8, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67B9, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67BA, 7, 0, 1, \"Hawaii\" },\n\t{ 0x67BE, 7, 0, 1, \"Hawaii\" },\n\t/* Carrizo Family */\n\t{ 0x9870, 8, 0, 1, \"Carrizo\" },\n\t{ 0x9874, 8, 0, 1, \"Carrizo\" },\n\t{ 0x9875, 8, 0, 1, \"Carrizo\" },\n\t{ 0x9876, 8, 0, 1, \"Carrizo\" },\n\t{ 0x9877, 8, 0, 1, \"Carrizo\" },\n\t/* Tonga Family */\n\t{ 0x6920, 8, 0, 2, \"Tonga\" },\n\t{ 0x6921, 8, 0, 2, \"Tonga\" },\n\t{ 0x6928, 8, 0, 2, \"Tonga\" },\n\t{ 0x6929, 8, 0, 2, \"Tonga\" },\n\t{ 0x692B, 8, 0, 2, \"Tonga\" },\n\t{ 0x692F, 8, 0, 2, \"Tonga\" },\n\t{ 0x6930, 8, 0, 2, \"Tonga\" },\n\t{ 0x6938, 8, 0, 2, \"Tonga\" },\n\t{ 0x6939, 8, 0, 2, \"Tonga\" },\n\t/* Fiji */\n\t{ 0x7300, 8, 0, 3, \"Fiji\" },\n\t{ 0x730F, 8, 0, 3, \"Fiji\" },\n\t/* Polaris10 */\n\t{ 0x67C0, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C1, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C2, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C4, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C7, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C8, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67C9, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67CA, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67CC, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67CF, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67D0, 8, 0, 3, \"Polaris10\" },\n\t{ 0x67DF, 8, 0, 3, \"Polaris10\" },\n\t{ 0x6FDF, 8, 0, 3, \"Polaris10\" },\n\t/* Polaris11 */\n\t{ 0x67E0, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67E1, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67E3, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67E7, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67E8, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67E9, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67EB, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67EF, 8, 0, 3, \"Polaris11\" },\n\t{ 0x67FF, 8, 0, 3, \"Polaris11\" },\n\t/* Polaris12 */\n\t{ 0x6980, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6981, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6985, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6986, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6987, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6995, 8, 0, 3, \"Polaris12\" },\n\t{ 0x6997, 8, 0, 3, \"Polaris12\" },\n\t{ 0x699F, 8, 0, 3, \"Polaris12\" },\n\t/* VegaM */\n\t{ 0x694C, 8, 0, 3, \"VegaM\" },\n\t{ 0x694E, 8, 0, 3, \"VegaM\" },\n\t{ 0x694F, 8, 0, 3, \"VegaM\" },\n\t/* Vega10 */\n\t{ 0x6860, 9, 0, 0, \"Vega10\" },\n\t{ 0x6861, 9, 0, 0, \"Vega10\" },\n\t{ 0x6862, 9, 0, 0, \"Vega10\" },\n\t{ 0x6863, 9, 0, 0, \"Vega10\" },\n\t{ 0x6864, 9, 0, 0, \"Vega10\" },\n\t{ 0x6867, 9, 0, 0, \"Vega10\" },\n\t{ 0x6868, 9, 0, 0, \"Vega10\" },\n\t{ 0x6869, 9, 0, 0, \"Vega10\" },\n\t{ 0x686A, 9, 0, 0, \"Vega10\" },\n\t{ 0x686B, 9, 0, 0, \"Vega10\" },\n\t{ 0x686C, 9, 0, 0, \"Vega10\" },\n\t{ 0x686D, 9, 0, 0, \"Vega10\" },\n\t{ 0x686E, 9, 0, 0, \"Vega10\" },\n\t{ 0x687F, 9, 0, 0, \"Vega10\" },\n\t/* Vega12 */\n\t{ 0x69A0, 9, 0, 4, \"Vega12\" },\n\t{ 0x69A1, 9, 0, 4, \"Vega12\" },\n\t{ 0x69A2, 9, 0, 4, \"Vega12\" },\n\t{ 0x69A3, 9, 0, 4, \"Vega12\" },\n\t{ 0x69Af, 9, 0, 4, \"Vega12\" },\n\t/* Raven */\n\t{ 0x15DD, 9, 0, 2, \"Raven\" },\n\t{ 0x15D8, 9, 0, 2, \"Raven\" },\n\t/* Vega20 */\n\t{ 0x66A0, 9, 0, 6, \"Vega20\" },\n\t{ 0x66A1, 9, 0, 6, \"Vega20\" },\n\t{ 0x66A2, 9, 0, 6, \"Vega20\" },\n\t{ 0x66A3, 9, 0, 6, \"Vega20\" },\n\t{ 0x66A4, 9, 0, 6, \"Vega20\" },\n\t{ 0x66A7, 9, 0, 6, \"Vega20\" },\n\t{ 0x66AF, 9, 0, 6, \"Vega20\" },\n\t/* Arcturus */\n\t{ 0x7388, 9, 0, 8, \"Arcturus\" },\n\t{ 0x738C, 9, 0, 8, \"Arcturus\" },\n\t{ 0x738E, 9, 0, 8, \"Arcturus\" },\n\t{ 0x7390, 9, 0, 8, \"Arcturus\" },\n\t/* Aldebaran */\n\t{ 0x7408, 9, 0, 10, \"Aldebaran\" },\n\t{ 0x740C, 9, 0, 10, \"Aldebaran\" },\n\t{ 0x740F, 9, 0, 10, \"Aldebaran\" },\n\t{ 0x7410, 9, 0, 10, \"Aldebaran\" },\n\t/* Renoir */\n\t{ 0x15E7, 9, 0, 12, \"Renoir\" },\n\t{ 0x1636, 9, 0, 12, \"Renoir\" },\n\t{ 0x1638, 9, 0, 12, \"Renoir\" },\n\t{ 0x164C, 9, 0, 12, \"Renoir\" },\n\t/* Navi10 */\n\t{ 0x7310, 10, 1, 0, \"Navi10\" },\n\t{ 0x7312, 10, 1, 0, \"Navi10\" },\n\t{ 0x7318, 10, 1, 0, \"Navi10\" },\n\t{ 0x731A, 10, 1, 0, \"Navi10\" },\n\t{ 0x731E, 10, 1, 0, \"Navi10\" },\n\t{ 0x731F, 10, 1, 0, \"Navi10\" },\n\t/* cyan_skillfish */\n\t{ 0x13F9, 10, 1, 3, \"cyan_skillfish\" },\n\t{ 0x13FA, 10, 1, 3, \"cyan_skillfish\" },\n\t{ 0x13FB, 10, 1, 3, \"cyan_skillfish\" },\n\t{ 0x13FC, 10, 1, 3, \"cyan_skillfish\" },\n\t{ 0x13FE, 10, 1, 3, \"cyan_skillfish\" },\n\t{ 0x143F, 10, 1, 3, \"cyan_skillfish\" },\n\t/* Navi14 */\n\t{ 0x7340, 10, 1, 2, \"Navi14\" },\n\t{ 0x7341, 10, 1, 2, \"Navi14\" },\n\t{ 0x7347, 10, 1, 2, \"Navi14\" },\n\t/* Navi12 */\n\t{ 0x7360, 10, 1, 1, \"Navi12\" },\n\t{ 0x7362, 10, 1, 1, \"Navi12\" },\n\t/* SIENNA_CICHLID */\n\t{ 0x73A0, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A1, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A2, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A3, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A5, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A8, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73A9, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73AC, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73AD, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73AB, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73AE, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t{ 0x73BF, 10, 3, 0, \"SIENNA_CICHLID\" },\n\t/* NAVY_FLOUNDER */\n\t{ 0x73C0, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73C1, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73C3, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DA, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DB, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DC, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DD, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DE, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t{ 0x73DF, 10, 3, 1, \"NAVY_FLOUNDER\" },\n\t/* DIMGREY_CAVEFISH */\n\t{ 0x73E0, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73E1, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73E2, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73E8, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73E9, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73EA, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73EB, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73EC, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73ED, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73EF, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t{ 0x73FF, 10, 3, 2, \"DIMGREY_CAVEFISH\" },\n\t/* VanGogh */\n\t{ 0x163F, 10, 3, 3, \"VanGogh\" },\n\t/* BEIGE_GOBY */\n\t{ 0x7420, 10, 3, 4, \"BEIGE_GOBY\" },\n\t{ 0x7421, 10, 3, 4, \"BEIGE_GOBY\" },\n\t{ 0x7422, 10, 3, 4, \"BEIGE_GOBY\" },\n\t{ 0x7423, 10, 3, 4, \"BEIGE_GOBY\" },\n\t{ 0x743F, 10, 3, 4, \"BEIGE_GOBY\" },\n\t/* Yellow_Carp */\n\t{ 0x164D, 10, 3, 5, \"YELLOW_CARP\" },\n\t{ 0x1681, 10, 3, 5, \"YELLOW_CARP\" },\n};\n\n/* information from /proc/cpuinfo */\nstruct proc_cpuinfo {\n\tuint32_t proc_num; /* processor */\n\tuint32_t apicid; /* apicid */\n\tchar model_name[HSA_PUBLIC_NAME_SIZE]; /* model name */\n};\n\n/* CPU cache table for all CPUs on the system. Each entry has the relative CPU\n * info and caches connected to that CPU.\n */\ntypedef struct cpu_cacheinfo {\n\tuint32_t len; /* length of the table = number of online procs */\n\tint32_t proc_num; /* this cpu's processor number */\n\tuint32_t num_caches; /* number of caches reported by this cpu */\n\tHsaCacheProperties *cache_prop; /* a list of cache properties */\n} cpu_cacheinfo_t;\n\nstatic void free_properties(node_props_t *props, int size)\n{\n\tif (props) {\n\t\tint i;\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tfree(props[i].mem);\n\t\t\tfree(props[i].cache);\n\t\t\tfree(props[i].link);\n\t\t}\n\n\t\tfree(props);\n\t}\n}\n\n/* num_subdirs - find the number of sub-directories in the specified path\n *\t@dirpath - directory path to find sub-directories underneath\n *\t@prefix - only count sub-directory names starting with prefix.\n *\t\tUse blank string, \"\", to count all.\n *\tReturn - number of sub-directories\n */\nstatic int num_subdirs(char *dirpath, char *prefix)\n{\n\tint count = 0;\n\tDIR *dirp;\n\tstruct dirent *dir;\n\tint prefix_len = strlen(prefix);\n\n\tdirp = opendir(dirpath);\n\tif (dirp) {\n\t\twhile ((dir = readdir(dirp)) != 0) {\n\t\t\tif ((strcmp(dir->d_name, \".\") == 0) ||\n\t\t\t\t(strcmp(dir->d_name, \"..\") == 0))\n\t\t\t\tcontinue;\n\t\t\tif (prefix_len &&\n\t\t\t\tstrncmp(dir->d_name, prefix, prefix_len))\n\t\t\t\tcontinue;\n\t\t\tcount++;\n\t\t}\n\t\tclosedir(dirp);\n\t}\n\n\treturn count;\n}\n\n/* fscanf_dec - read a file whose content is a decimal number\n *      @file [IN ] file to read\n *      @num [OUT] number in the file\n */\nstatic HSAKMT_STATUS fscanf_dec(char *file, uint32_t *num)\n{\n\tFILE *fd;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tfd = fopen(file, \"r\");\n\tif (!fd) {\n\t\tpr_err(\"Failed to open %s\\n\", file);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\tif (fscanf(fd, \"%u\", num) != 1) {\n\t\tpr_err(\"Failed to parse %s as a decimal.\\n\", file);\n\t\tret = HSAKMT_STATUS_ERROR;\n\t}\n\n\tfclose(fd);\n\treturn ret;\n}\n\n/* fscanf_str - read a file whose content is a string\n *      @file [IN ] file to read\n *      @str [OUT] string in the file\n */\nstatic HSAKMT_STATUS fscanf_str(const char *file, char *str, size_t str_size)\n{\n\tFILE *fd;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tfd = fopen(file, \"r\");\n\tif (!fd) {\n\t\tpr_err(\"Failed to open %s\\n\", file);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tif (!fgets(str, (int)str_size, fd)) {\n\t\tpr_err(\"Failed to read from %s.\\n\", file);\n\t\tret = HSAKMT_STATUS_ERROR;\n\t} else {\n\t\t// Remove possible newline characters at the end, due to using fgets function\n\t\tstr[strcspn(str, \"\\r\\n\")] = '\\0';\n\t}\n\n\tfclose(fd);\n\treturn ret;\n}\n\n/* fscanf_size - read a file whose content represents size as a string\n *      @file [IN ] file to read\n *      @bytes [OUT] sizes in bytes\n */\nstatic HSAKMT_STATUS fscanf_size(char *file, uint32_t *bytes)\n{\n\tFILE *fd;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tchar unit;\n\tint n;\n\n\tfd = fopen(file, \"r\");\n\tif (!fd) {\n\t\tpr_err(\"Failed to open %s\\n\", file);\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tn = fscanf(fd, \"%u%c\", bytes, &unit);\n\tif (n < 1) {\n\t\tpr_err(\"Failed to parse %s\\n\", file);\n\t\tret = HSAKMT_STATUS_ERROR;\n\t}\n\n\tif (n == 2) {\n\t\tswitch (unit) {\n\t\tcase 'K':\n\t\t\t*bytes <<= 10; break;\n\t\tcase 'M':\n\t\t\t*bytes <<= 20; break;\n\t\tcase 'G':\n\t\t\t*bytes <<= 30; break;\n\t\tdefault:\n\t\t\tret = HSAKMT_STATUS_ERROR; break;\n\t\t}\n\t}\n\n\tfclose(fd);\n\treturn ret;\n}\n\n/* cpumap_to_cpu_ci - translate shared_cpu_map string + cpuinfo->apicid into\n *\t\t      SiblingMap in cache\n *\t@shared_cpu_map [IN ] shared_cpu_map string\n *\t@cpuinfo [IN ] cpuinfo to get apicid\n *\t@this_cache [OUT] CPU cache to fill in SiblingMap\n */\nstatic void cpumap_to_cpu_ci(char *shared_cpu_map,\n\t\t\t     struct proc_cpuinfo *cpuinfo,\n\t\t\t     HsaCacheProperties *this_cache)\n{\n\tint num_hexs, bit;\n\tuint32_t proc, apicid, mask;\n\tchar *ch_ptr;\n\n\t/* shared_cpu_map is shown as ...X3,X2,X1 Each X is a hex without 0x\n\t * and it's up to 8 characters(32 bits). For the first 32 CPUs(actually\n\t * procs), it's presented in X1. The next 32 is in X2, and so on.\n\t */\n\tnum_hexs = (strlen(shared_cpu_map) + 8) / 9; /* 8 characters + \",\" */\n\tch_ptr = strtok(shared_cpu_map, \",\");\n\twhile (num_hexs-- > 0) {\n\t\tmask = strtol(ch_ptr, NULL, 16); /* each X */\n\t\tfor (bit = 0; bit < 32; bit++) {\n\t\t\tif (!((1 << bit) & mask))\n\t\t\t\tcontinue;\n\t\t\tproc = num_hexs * 32 + bit;\n\t\t\tapicid = cpuinfo[proc].apicid;\n\t\t\tif (apicid >= HSA_CPU_SIBLINGS) {\n\t\t\t\tpr_warn(\"SiblingMap buffer %d is too small\\n\",\n\t\t\t\t\tHSA_CPU_SIBLINGS);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis_cache->SiblingMap[apicid] = 1;\n\t\t}\n\t\tch_ptr = strtok(NULL, \",\");\n\t}\n}\n\n/* get_cpu_cache_info - get specified CPU's cache information from sysfs\n *     @prefix [IN] sysfs path for target cpu cache,\n *                  /sys/devices/system/node/nodeX/cpuY/cache\n *     @cpuinfo [IN] /proc/cpuinfo data to get apicid\n *     @cpu_ci: CPU specified. This parameter is an input and also an output.\n *             [IN] cpu_ci->num_caches: number of index dirs\n *             [OUT] cpu_ci->cache_info: to store cache info collected\n *             [OUT] cpu_ci->num_caches: reduces when shared with other cpu(s)\n * Return: number of cache reported from this cpu\n */\nstatic int get_cpu_cache_info(const char *prefix, struct proc_cpuinfo *cpuinfo,\n\t\t\t      cpu_cacheinfo_t *cpu_ci)\n{\n\tint idx, num_idx, n;\n\tHsaCacheProperties *this_cache;\n\tchar path[256], str[256];\n\tbool is_power9 = false;\n\n\tif (processor_vendor == IBM_POWER) {\n\t\tif (strcmp(cpuinfo[0].model_name, \"POWER9\") == 0) {\n\t\t\tis_power9 = true;\n\t\t}\n\t}\n\n\tthis_cache = cpu_ci->cache_prop;\n\tnum_idx = cpu_ci->num_caches;\n\tfor (idx = 0; idx < num_idx; idx++) {\n\t\t/* If this cache is shared by multiple CPUs, we only need\n\t\t * to list it in the first CPU.\n\t\t */\n\t\tif (is_power9) {\n\t\t\t// POWER9 has SMT4\n\t\t\tif (cpu_ci->proc_num & 0x3) {\n\t\t\t\t/* proc is not 0,4,8,etc.  Skip and reduce the cache count. */\n\t\t\t\t--cpu_ci->num_caches;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n\t\t\tsnprintf(path, 256, \"%s/index%d/shared_cpu_list\", prefix, idx);\n\t\t\t/* shared_cpu_list is shown as n1,n2... or n1-n2,n3-n4...\n\t\t\t * For both cases, this cache is listed to proc n1 only.\n\t\t\t */\n\t\t\tfscanf_dec(path, (uint32_t *)&n);\n\t\t\tif (cpu_ci->proc_num != n) {\n\t\t\t\t/* proc is not n1. Skip and reduce the cache count. */\n\t\t\t\t--cpu_ci->num_caches;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis_cache->ProcessorIdLow = cpuinfo[cpu_ci->proc_num].apicid;\n\t\t}\n\n\t\t/* CacheLevel */\n\t\tsnprintf(path, 256, \"%s/index%d/level\", prefix, idx);\n\t\tfscanf_dec(path, &this_cache->CacheLevel);\n\t\t/* CacheType */\n\t\tsnprintf(path, 256, \"%s/index%d/type\", prefix, idx);\n\n\t\tmemset(str, 0, sizeof(str));\n\t\tfscanf_str(path, str, sizeof(str));\n\t\tif (!strcmp(str, \"Data\"))\n\t\t\tthis_cache->CacheType.ui32.Data = 1;\n\t\tif (!strcmp(str, \"Instruction\"))\n\t\t\tthis_cache->CacheType.ui32.Instruction = 1;\n\t\tif (!strcmp(str, \"Unified\")) {\n\t\t\tthis_cache->CacheType.ui32.Data = 1;\n\t\t\tthis_cache->CacheType.ui32.Instruction = 1;\n\t\t}\n\t\tthis_cache->CacheType.ui32.CPU = 1;\n\t\t/* CacheSize */\n\t\tsnprintf(path, 256, \"%s/index%d/size\", prefix, idx);\n\t\tfscanf_size(path, &this_cache->CacheSize);\n\t\t/* CacheLineSize */\n\t\tsnprintf(path, 256, \"%s/index%d/coherency_line_size\", prefix, idx);\n\t\tfscanf_dec(path, &this_cache->CacheLineSize);\n\t\t/* CacheAssociativity */\n\t\tsnprintf(path, 256, \"%s/index%d/ways_of_associativity\", prefix, idx);\n\t\tfscanf_dec(path, &this_cache->CacheAssociativity);\n\t\t/* CacheLinesPerTag */\n\t\tsnprintf(path, 256, \"%s/index%d/physical_line_partition\", prefix, idx);\n\t\tfscanf_dec(path, &this_cache->CacheLinesPerTag);\n\t\t/* CacheSiblings */\n\t\tsnprintf(path, 256, \"%s/index%d/shared_cpu_map\", prefix, idx);\n\t\tfscanf_str(path, str, sizeof(str));\n\t\tcpumap_to_cpu_ci(str, cpuinfo, this_cache);\n\n\t\t++this_cache;\n\t}\n\n\treturn cpu_ci->num_caches;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_get_generation(uint32_t *gen)\n{\n\tFILE *fd;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tchar path[256];\n\tsnprintf(path, sizeof(path), KFD_SYSFS_PATH_GENERATION_ID, get_topology_dir());\n\n\tassert(gen);\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tif (fscanf(fd, \"%ul\", gen) != 1) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err;\n\t}\n\nerr:\n\tfclose(fd);\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_map_node_id(uint32_t node_id, uint32_t *sys_node_id)\n{\n\tif ((!map_user_to_sysfs_node_id) || (node_id >= map_user_to_sysfs_node_id_size))\n\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\n\t*sys_node_id = map_user_to_sysfs_node_id[node_id];\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_get_gpu_id(uint32_t sysfs_node_id, uint32_t *gpu_id)\n{\n\tFILE *fd;\n\tchar path[256];\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tassert(gpu_id);\n\tsnprintf(path, sizeof(path), KFD_SYSFS_PATH_NODES \"/%d/gpu_id\", get_topology_dir(), sysfs_node_id);\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tif (fscanf(fd, \"%ul\", gpu_id) != 1)\n\t\tret = (errno == EPERM) ? HSAKMT_STATUS_NOT_SUPPORTED :\n\t\t\t\t\t HSAKMT_STATUS_ERROR;\n\tfclose(fd);\n\n\treturn ret;\n}\n\n/* Check if the @sysfs_node_id is supported. This function will be passed with sysfs node id.\n * This function can not use topology_* help functions, because those functions are\n * using user node id.\n * A sysfs node is not supported\n *\t- if corresponding drm render node is not available.\n *\t- if node information is not accessible (EPERM)\n */\nstatic HSAKMT_STATUS topology_sysfs_check_node_supported(uint32_t sysfs_node_id, bool *is_node_supported)\n{\n\tuint32_t gpu_id;\n\tFILE *fd;\n\tchar *read_buf, *p;\n\tint read_size;\n\tchar prop_name[256];\n\tchar path[256];\n\tunsigned long long prop_val;\n\tuint32_t prog;\n\tuint32_t drm_render_minor = 0;\n\tint ret_value;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\t*is_node_supported = false;\n\n\t/* Retrieve the GPU ID */\n\tret = topology_sysfs_get_gpu_id(sysfs_node_id, &gpu_id);\n\tif (ret == HSAKMT_STATUS_NOT_SUPPORTED)\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tif (gpu_id == 0) {\n\t\t*is_node_supported = true;\n\t\treturn HSAKMT_STATUS_SUCCESS;\n\t}\n\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\t/* Retrieve the node properties */\n\tsnprintf(path, 256, KFD_SYSFS_PATH_NODES \"/%d/properties\", get_topology_dir(), sysfs_node_id);\n\tfd = fopen(path, \"r\");\n\tif (!fd) {\n\t\tfree(read_buf);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\t/* Read the node properties */\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"drm_render_minor\") == 0) {\n\t\t\tdrm_render_minor = (int32_t)prop_val;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!drm_render_minor) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err;\n\t}\n\n\t/* Open DRM Render device */\n\tret_value = hsakmt_open_drm_render_device(drm_render_minor);\n\tif (ret_value > 0)\n\t\t*is_node_supported = true;\n\telse if (ret_value != -ENOENT && ret_value != -EPERM)\n\t\tret = HSAKMT_STATUS_ERROR;\n\nerr:\n\tfree(read_buf);\n\tfclose(fd);\n\treturn ret;\n}\n\nHSAKMT_STATUS hsakmt_topology_sysfs_get_system_props(HsaSystemProperties *props)\n{\n\tFILE *fd;\n\tchar *read_buf, *p;\n\tchar path[256];\n\tchar prop_name[256];\n\tunsigned long long prop_val;\n\tuint32_t prog;\n\tint read_size;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tbool is_node_supported = true;\n\tuint32_t num_supported_nodes = 0;\n\n\tassert(props);\n\tsnprintf(path, sizeof(path), KFD_SYSFS_PATH_SYSTEM_PROPERTIES, get_topology_dir());\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err1;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err2;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\t/* Read the system properties */\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"platform_oem\") == 0)\n\t\t\tprops->PlatformOem = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"platform_id\") == 0)\n\t\t\tprops->PlatformId = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"platform_rev\") == 0)\n\t\t\tprops->PlatformRev = (uint32_t)prop_val;\n\t}\n\n\t/*\n\t * Discover the number of sysfs nodes:\n\t * Assuming that inside nodes folder there are only folders\n\t * which represent the node numbers\n\t */\n\tsnprintf(path, sizeof(path), KFD_SYSFS_PATH_NODES, get_topology_dir());\n\tnum_sysfs_nodes = num_subdirs(path, \"\");\n\n\tif (map_user_to_sysfs_node_id == NULL) {\n\t\t/* Trade off - num_sysfs_nodes includes all CPU and GPU nodes.\n\t\t * Slightly more memory is allocated than necessary.\n\t\t */\n\t\tmap_user_to_sysfs_node_id = calloc(num_sysfs_nodes, sizeof(uint32_t));\n\t\tif (map_user_to_sysfs_node_id == NULL) {\n\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\tgoto err2;\n\t\t}\n\t\tmap_user_to_sysfs_node_id_size = num_sysfs_nodes;\n\t} else if (num_sysfs_nodes > map_user_to_sysfs_node_id_size) {\n\t\tfree(map_user_to_sysfs_node_id);\n\t\tmap_user_to_sysfs_node_id = calloc(num_sysfs_nodes, sizeof(uint32_t));\n\t\tif (map_user_to_sysfs_node_id == NULL) {\n\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\tgoto err2;\n\t\t}\n\t\tmap_user_to_sysfs_node_id_size = num_sysfs_nodes;\n\t}\n\n\tfor (uint32_t i = 0; i < num_sysfs_nodes; i++) {\n\t\tret = topology_sysfs_check_node_supported(i, &is_node_supported);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\tgoto sysfs_parse_failed;\n\t\tif (is_node_supported)\n\t\t\tmap_user_to_sysfs_node_id[num_supported_nodes++] = i;\n\t}\n\tprops->NumNodes = num_supported_nodes;\n\n\tfree(read_buf);\n\tfclose(fd);\n\treturn ret;\n\nsysfs_parse_failed:\n\tfree(map_user_to_sysfs_node_id);\n\tmap_user_to_sysfs_node_id = NULL;\nerr2:\n\tfree(read_buf);\nerr1:\n\tfclose(fd);\n\treturn ret;\n}\n\nstatic const struct hsa_gfxip_table *find_hsa_gfxip_device(uint16_t device_id, uint8_t gfxv_major)\n{\n\tif (gfxv_major > 10)\n\t\treturn NULL;\n\n\tuint32_t i, table_size;\n\n\ttable_size = sizeof(gfxip_lookup_table)/sizeof(struct hsa_gfxip_table);\n\tfor (i = 0; i < table_size; i++) {\n\t\tif (gfxip_lookup_table[i].device_id == device_id)\n\t\t\treturn &gfxip_lookup_table[i];\n\t}\n\treturn NULL;\n}\n\nvoid hsakmt_topology_setup_is_dgpu_param(HsaNodeProperties *props)\n{\n\t/* if we found a dGPU node, then treat the whole system as dGPU */\n\tif (!props->NumCPUCores && props->NumFComputeCores)\n\t\thsakmt_is_dgpu = true;\n}\n\nbool hsakmt_topology_is_svm_needed(HSA_ENGINE_ID EngineId)\n{\n\tif (hsakmt_is_dgpu)\n\t\treturn true;\n\n\tif (HSA_GET_GFX_VERSION_FULL(EngineId.ui32) >= GFX_VERSION_VEGA10)\n\t\treturn true;\n\n\treturn false;\n}\n\nstatic HSAKMT_STATUS topology_get_cpu_model_name(HsaNodeProperties *props,\n\t\t\t\tstruct proc_cpuinfo *cpuinfo, int num_procs)\n{\n\tint i, j;\n\n\tif (!props) {\n\t\tpr_err(\"Invalid props to get cpu model name\\n\");\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tfor (i = 0; i < num_procs; i++, cpuinfo++) {\n\t\tif (props->CComputeIdLo == cpuinfo->apicid) {\n\t\t\tif (!props->DeviceId) /* CPU-only node */\n\t\t\t\tstrncpy((char *)props->AMDName, cpuinfo->model_name, sizeof(props->AMDName));\n\t\t\t/* Convert from UTF8 to UTF16 */\n\t\t\tfor (j = 0; cpuinfo->model_name[j] != '\\0' && j < HSA_PUBLIC_NAME_SIZE - 1; j++)\n\t\t\t\tprops->MarketingName[j] = cpuinfo->model_name[j];\n\t\t\tprops->MarketingName[j] = '\\0';\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t}\n\n\treturn HSAKMT_STATUS_ERROR;\n}\n\nstatic int topology_search_processor_vendor(const char *processor_name)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < ARRAY_LEN(supported_processor_vendor_name); i++) {\n\t\tif (!strcmp(processor_name, supported_processor_vendor_name[i]))\n\t\t\treturn i;\n\t\tif (!strcmp(processor_name, \"POWER9, altivec supported\\n\"))\n\t\t\treturn IBM_POWER;\n\t}\n\treturn -1;\n}\n\n/* topology_parse_cpuinfo - Parse /proc/cpuinfo and fill up required\n *\t\t\ttopology information\n * cpuinfo [OUT]: output buffer to hold cpu information\n * num_procs: number of processors the output buffer can hold\n */\nstatic HSAKMT_STATUS topology_parse_cpuinfo(struct proc_cpuinfo *cpuinfo,\n\t\t\t\t\t    uint32_t num_procs)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tFILE *fd;\n\tchar read_buf[256];\n\tchar *p;\n\tuint32_t proc = 0;\n\tsize_t p_len;\n\tconst char *proc_cpuinfo_path = \"/proc/cpuinfo\";\n\n\tif (!cpuinfo) {\n\t\tpr_err(\"CPU information will be missing\\n\");\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\t}\n\n\tfd = fopen(proc_cpuinfo_path, \"r\");\n\tif (!fd) {\n\t\tpr_err(\"Failed to open [%s]. Unable to get CPU information\",\n\t\t\tproc_cpuinfo_path);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n#ifdef __PPC64__\n\tchar *p2;\n\n\t/* Each line in /proc/cpuinfo that read_buf is constructed, the format\n\t * is like this:\n\t * \"token       : value\\n\"\n\t * where token is our target like vendor_id, model name, apicid ...\n\t * and value is the answer\n\t */\n\twhile (fgets(read_buf, sizeof(read_buf), fd)) {\n\t\t/* processor number */\n\t\tif (!strncmp(\"processor\t\", read_buf, sizeof(\"processor\t\") - 1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tproc = atoi(p);\n\t\t\tif (proc >= num_procs) {\n\t\t\t\tpr_warn(\"cpuinfo contains processor %d larger than %u\\n\",\n\t\t\t\t\tproc, num_procs);\n\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\tgoto exit;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* vendor name / model name */\n\t\tif (!strncmp(\"cpu\t\", read_buf, sizeof(\"cpu\t\") - 1) &&\n\t\t\t(processor_vendor == -1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tprocessor_vendor = topology_search_processor_vendor(p);\n\n\t\t\tp2 = strchr(p, ',');\n\t\t\tif (p2 != NULL) {\n\t\t\t\tp2++;\n\t\t\t\t*p2 = 0;\n\t\t\t}\n\t\t\tif (strlen(p) < HSA_PUBLIC_NAME_SIZE) {\n\t\t\t\t/* -1 to remove \\n from p */\n\t\t\t\tstrncpy(cpuinfo[proc].model_name, p, strlen(p) - 1);\n\t\t\t\tcpuinfo[proc].model_name[strlen(p) - 1] = '\\0';\n\t\t\t} else\n\t\t\t\tstrncpy(cpuinfo[proc].model_name, p, HSA_PUBLIC_NAME_SIZE);\n\t\t\tcontinue;\n\t\t}\n\t}\n#else\n\t/* Each line in /proc/cpuinfo that read_buf is constructed, the format\n\t * is like this:\n\t * \"token       : value\\n\"\n\t * where token is our target like vendor_id, model name, apicid ...\n\t * and value is the answer\n\t */\n\twhile (fgets(read_buf, sizeof(read_buf), fd)) {\n\t\t/* processor number */\n\t\tif (!strncmp(\"processor\", read_buf, sizeof(\"processor\") - 1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tproc = atoi(p);\n\t\t\tif (proc >= num_procs) {\n\t\t\t\tpr_warn(\"cpuinfo contains processor %d larger than %u\\n\",\n\t\t\t\t\tproc, num_procs);\n\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\tgoto exit;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* vendor name */\n\t\tif (!strncmp(\"vendor_id\", read_buf, sizeof(\"vendor_id\") - 1) &&\n\t\t\t(processor_vendor == -1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tprocessor_vendor = topology_search_processor_vendor(p);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* model name */\n\t\tif (!strncmp(\"model name\", read_buf, sizeof(\"model name\") - 1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tp_len = strlen(p);\n\t\t\tif (p_len > HSA_PUBLIC_NAME_SIZE)\n\t\t\t\tp_len = HSA_PUBLIC_NAME_SIZE;\n\t\t\tmemcpy(cpuinfo[proc].model_name, p, p_len);\n\t\t\tcpuinfo[proc].model_name[p_len - 1] = '\\0';\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* apicid */\n\t\tif (!strncmp(\"apicid\", read_buf, sizeof(\"apicid\") - 1)) {\n\t\t\tp = strchr(read_buf, ':');\n\t\t\tp += 2; /* remove \": \" */\n\t\t\tcpuinfo[proc].apicid = atoi(p);\n\t\t}\n\t}\n#endif\n\n\tif (processor_vendor < 0) {\n\t\tpr_err(\"Failed to get Processor Vendor. Setting to %s\",\n\t\t\tsupported_processor_vendor_name[GENUINE_INTEL]);\n\t\tprocessor_vendor = GENUINE_INTEL;\n\t}\n\nexit:\n\tfclose(fd);\n\treturn ret;\n}\n\nstatic int topology_get_node_props_from_drm(HsaNodeProperties *props)\n{\n\tint drm_fd;\n\tuint32_t major_version;\n\tuint32_t minor_version;\n\tamdgpu_device_handle device_handle;\n\tstruct amdgpu_gpu_info gpu_info;\n\tconst char *name;\n\tint i, ret = 0;\n\n\tif (props == NULL)\n\t\treturn -1;\n\n\tdrm_fd = drmOpenRender(props->DrmRenderMinor);\n\tif (drm_fd < 0)\n\t\treturn -1;\n\n\tif (amdgpu_device_initialize(drm_fd,\n\t\t&major_version, &minor_version, &device_handle) < 0) {\n\t\tret = -1;\n\t\tgoto err_device_initialize;\n\t}\n\n\tname = amdgpu_get_marketing_name(device_handle);\n\tif (name != NULL) {\n\t\tfor (i = 0; name[i] != 0 && i < HSA_PUBLIC_NAME_SIZE - 1; i++)\n\t\t\tprops->MarketingName[i] = name[i];\n\t\tprops->MarketingName[i] = '\\0';\n\t}\n\n\tif (amdgpu_query_gpu_info(device_handle, &gpu_info)) {\n\t\tret = -1;\n\t\tgoto err_query_gpu_info;\n\t}\n\n\tprops->FamilyID = gpu_info.family_id;\n\tprops->Integrated = !!(gpu_info.ids_flags & AMDGPU_IDS_FLAGS_FUSION);\n\nerr_query_gpu_info:\n\tamdgpu_device_deinitialize(device_handle);\nerr_device_initialize:\n\tdrmClose(drm_fd);\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_get_node_props(uint32_t node_id,\n\t\t\t\t\t\t   HsaNodeProperties *props,\n\t\t\t\t\t\t   bool *p2p_links,\n\t\t\t\t\t\t   uint32_t *num_p2pLinks)\n{\n\tFILE *fd;\n\tchar *read_buf, *p, *envvar, dummy = '\\0';\n\tchar prop_name[256];\n\tchar path[256];\n\tchar per_node_override[32];\n\tunsigned long long prop_val = 0;\n\tuint32_t prog, major = 0, minor = 0, step = 0;\n\tint read_size;\n\tconst struct hsa_gfxip_table *hsa_gfxip;\n\tuint32_t sys_node_id;\n\tuint32_t gfxv = 0;\n\tuint8_t gfxv_major, gfxv_minor, gfxv_stepping;\n\tuint32_t simd_arrays_count = 0;\n\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n\tassert(props);\n\tret = topology_sysfs_map_node_id(node_id, &sys_node_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\t/* Retrieve the GPU ID */\n\tret = topology_sysfs_get_gpu_id(sys_node_id, &props->KFDGpuID);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\t/* Retrieve the node properties */\n\tsnprintf(path, 256, KFD_SYSFS_PATH_NODES \"/%d/properties\", get_topology_dir(), sys_node_id);\n\tfd = fopen(path, \"r\");\n\tif (!fd) {\n\t\tfree(read_buf);\n\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto out;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\t/* Read the node properties */\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"cpu_cores_count\") == 0)\n\t\t\tprops->NumCPUCores = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"simd_count\") == 0)\n\t\t\tprops->NumFComputeCores = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"mem_banks_count\") == 0)\n\t\t\tprops->NumMemoryBanks = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"caches_count\") == 0)\n\t\t\tprops->NumCaches = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"io_links_count\") == 0)\n\t\t\tprops->NumIOLinks = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"p2p_links_count\") == 0) {\n\t\t\tprops->NumIOLinks += (uint32_t)prop_val;\n\t\t\tif (num_p2pLinks)\n\t\t\t\t*num_p2pLinks = (uint32_t)prop_val;\n\t\t\tif (p2p_links)\n\t\t\t\t*p2p_links = true;\n\t\t} else if (strcmp(prop_name, \"cpu_core_id_base\") == 0)\n\t\t\tprops->CComputeIdLo = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"simd_id_base\") == 0)\n\t\t\tprops->FComputeIdLo = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"capability\") == 0)\n\t\t\tprops->Capability.Value = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"capability2\") == 0)\n\t\t\tprops->Capability2.Value = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"debug_prop\") == 0)\n\t\t\tprops->DebugProperties.Value = (uint64_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_waves_per_simd\") == 0)\n\t\t\tprops->MaxWavesPerSIMD = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"lds_size_in_kb\") == 0)\n\t\t\tprops->LDSSizeInKB = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"gds_size_in_kb\") == 0)\n\t\t\tprops->GDSSizeInKB = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"wave_front_size\") == 0)\n\t\t\tprops->WaveFrontSize = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"array_count\") == 0)\n\t\t\tsimd_arrays_count = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"simd_arrays_per_engine\") == 0)\n\t\t\tprops->NumArrays = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"cu_per_simd_array\") == 0)\n\t\t\tprops->NumCUPerArray = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"simd_per_cu\") == 0)\n\t\t\tprops->NumSIMDPerCU = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_slots_scratch_cu\") == 0)\n\t\t\tprops->MaxSlotsScratchCU = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"fw_version\") == 0)\n\t\t\tprops->EngineId.Value = (uint32_t)prop_val & 0x3ff;\n\t\telse if (strcmp(prop_name, \"vendor_id\") == 0)\n\t\t\tprops->VendorId = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"device_id\") == 0)\n\t\t\tprops->DeviceId = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"location_id\") == 0)\n\t\t\tprops->LocationId = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"domain\") == 0)\n\t\t\tprops->Domain = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_engine_clk_fcompute\") == 0)\n\t\t\tprops->MaxEngineClockMhzFCompute = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_engine_clk_ccompute\") == 0)\n\t\t\tprops->MaxEngineClockMhzCCompute = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"local_mem_size\") == 0)\n\t\t\tprops->LocalMemSize = prop_val;\n\t\telse if (strcmp(prop_name, \"drm_render_minor\") == 0)\n\t\t\tprops->DrmRenderMinor = (int32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"sdma_fw_version\") == 0)\n\t\t\tprops->uCodeEngineVersions.Value = (uint32_t)prop_val & 0x3ff;\n\t\telse if (strcmp(prop_name, \"hive_id\") == 0)\n\t\t\tprops->HiveID = prop_val;\n\t\telse if (strcmp(prop_name, \"unique_id\") == 0)\n\t\t\tprops->UniqueID = prop_val;\n\t\telse if (strcmp(prop_name, \"num_sdma_engines\") == 0)\n\t\t\tprops->NumSdmaEngines = prop_val;\n\t\telse if (strcmp(prop_name, \"num_sdma_xgmi_engines\") == 0)\n\t\t\tprops->NumSdmaXgmiEngines = prop_val;\n\t\telse if (strcmp(prop_name, \"num_gws\") == 0)\n\t\t\tprops->NumGws = prop_val;\n\t\telse if (strcmp(prop_name, \"num_sdma_queues_per_engine\") == 0)\n\t\t\tprops->NumSdmaQueuesPerEngine = prop_val;\n\t\telse if (strcmp(prop_name, \"num_cp_queues\") == 0)\n\t\t\tprops->NumCpQueues = prop_val;\n\t\telse if (strcmp(prop_name, \"num_xcc\") == 0)\n\t\t\tprops->NumXcc = prop_val;\n\t\telse if (strcmp(prop_name, \"family_id\") == 0)\n\t\t\tprops->FamilyID = prop_val;\n\t\telse if (strcmp(prop_name, \"gfx_target_version\") == 0)\n\t\t\tgfxv = (uint32_t)prop_val;\n\t}\n\n\tif (!hsakmt_is_svm_api_supported)\n\t\tprops->Capability.ui32.SVMAPISupported = 0;\n\n\t/* Bail out early, if a CPU node */\n\tif (!props->NumFComputeCores)\n\t\tgoto out;\n\n\tif (props->NumArrays != 0)\n\t\tprops->NumShaderBanks = simd_arrays_count/props->NumArrays;\n\n\tgfxv_major = HSA_GET_GFX_VERSION_MAJOR(gfxv);\n\tgfxv_minor = HSA_GET_GFX_VERSION_MINOR(gfxv);\n\tgfxv_stepping = HSA_GET_GFX_VERSION_STEP(gfxv);\n\n\thsa_gfxip = find_hsa_gfxip_device(props->DeviceId, gfxv_major);\n\tif (hsa_gfxip || gfxv) {\n\t\tsnprintf(per_node_override, sizeof(per_node_override), \"HSA_OVERRIDE_GFX_VERSION_%d\", node_id);\n\t\tif ((envvar = getenv(per_node_override)) || (envvar = getenv(\"HSA_OVERRIDE_GFX_VERSION\"))) {\n\t\t\t/* HSA_OVERRIDE_GFX_VERSION=major.minor.stepping */\n\t\t\tif ((sscanf(envvar, \"%u.%u.%u%c\",\n\t\t\t\t\t&major, &minor, &step, &dummy) != 3) ||\n\t\t\t\t(major > 63 || minor > 255 || step > 255)) {\n\t\t\t\tpr_err(\"HSA_OVERRIDE_GFX_VERSION %s is invalid\\n\",\n\t\t\t\t\tenvvar);\n\t\t\t\tret = HSAKMT_STATUS_ERROR;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tprops->OverrideEngineId.ui32.Major = major & 0x3f;\n\t\t\tprops->OverrideEngineId.ui32.Minor = minor & 0xff;\n\t\t\tprops->OverrideEngineId.ui32.Stepping = step & 0xff;\n\t\t}\n\n\t\tif (hsa_gfxip) {\n\t\t\tprops->EngineId.ui32.Major = hsa_gfxip->major & 0x3f;\n\t\t\tprops->EngineId.ui32.Minor = hsa_gfxip->minor & 0xff;\n\t\t\tprops->EngineId.ui32.Stepping = hsa_gfxip->stepping & 0xff;\n\t\t} else {\n\t\t\tprops->EngineId.ui32.Major = gfxv_major & 0x3f;\n\t\t\tprops->EngineId.ui32.Minor = gfxv_minor & 0xff;\n\t\t\tprops->EngineId.ui32.Stepping = gfxv_stepping & 0xff;\n\t\t}\n\n\t\t/* Set the CAL name of the node. If DID-based hsa_gfxip lookup was\n\t\t * successful, use that name. Otherwise, set to GFX<GFX_VERSION>.\n\t\t */\n\t\tif (hsa_gfxip && hsa_gfxip->amd_name)\n\t\t\tstrncpy((char *)props->AMDName, hsa_gfxip->amd_name,\n\t\t\t\t\tsizeof(props->AMDName)-1);\n\t\telse\n\t\t\tsnprintf((char *)props->AMDName, sizeof(props->AMDName)-1, \"GFX%06x\",\n\t\t\t\t\tHSA_GET_GFX_VERSION_FULL(props->EngineId.ui32));\n\n\t\t/* Is dGPU Node, not APU\n\t\t * Retrieve the marketing name of the node.\n\t\t */\n\t\tif (topology_get_node_props_from_drm(props))\n\t\t\tpr_info(\"failed to get marketing name for device ID 0x%x\\n\", props->DeviceId);\n\n\t\t/* Get VGPR/SGPR size in byte per CU */\n\t\tprops->SGPRSizePerCU = SGPR_SIZE_PER_CU;\n\t\tprops->VGPRSizePerCU = hsakmt_get_vgpr_size_per_cu(HSA_GET_GFX_VERSION_FULL(props->EngineId.ui32));\n\n\t} else if (props->DeviceId)\n\t\t/* still return success */\n\t\tpr_err(\"device ID 0x%x is not supported in libhsakmt\\n\",\n\t\t\t\tprops->DeviceId);\n\n\tif (props->NumFComputeCores)\n\t\tassert(props->EngineId.ui32.Major && \"HSA_OVERRIDE_GFX_VERSION may be needed\");\n\n\t/* On Older kernels, num_xcc may not be present in system properties.\n\t * Set it to 1 if system properties do not report num_xcc.\n\t */\n\tif (!props->NumXcc)\n\t\tprops->NumXcc = 1;\n\nout:\n\tfree(read_buf);\n\tfclose(fd);\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_get_mem_props(uint32_t node_id,\n\t\t\t\t\t\t  uint32_t mem_id,\n\t\t\t\t\t\t  HsaMemoryProperties *props)\n{\n\tFILE *fd;\n\tchar *read_buf, *p;\n\tchar prop_name[256];\n\tchar path[256];\n\tunsigned long long prop_val;\n\tuint32_t prog;\n\tint read_size;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint32_t sys_node_id;\n\n\tassert(props);\n\tret = topology_sysfs_map_node_id(node_id, &sys_node_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tsnprintf(path, 256, KFD_SYSFS_PATH_NODES \"/%d/mem_banks/%d/properties\", get_topology_dir(), sys_node_id, mem_id);\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err1;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err2;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"heap_type\") == 0)\n\t\t\tprops->HeapType = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"size_in_bytes\") == 0)\n\t\t\tprops->SizeInBytes = (uint64_t)prop_val;\n\t\telse if (strcmp(prop_name, \"flags\") == 0)\n\t\t\tprops->Flags.MemoryProperty = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"width\") == 0)\n\t\t\tprops->Width = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"mem_clk_max\") == 0)\n\t\t\tprops->MemoryClockMax = (uint32_t)prop_val;\n\t}\n\nerr2:\n\tfree(read_buf);\nerr1:\n\tfclose(fd);\n\treturn ret;\n}\n\n/* topology_destroy_temp_cpu_cache_list -\n *\tFree the memory allocated in topology_create_temp_cpu_cache_list().\n */\nstatic void topology_destroy_temp_cpu_cache_list(\n\t\t\t\t\tcpu_cacheinfo_t *temp_cpu_ci_list)\n{\n\tuint32_t n;\n\tcpu_cacheinfo_t *p_temp_cpu_ci_list = temp_cpu_ci_list;\n\tcpu_cacheinfo_t *cpu_ci = p_temp_cpu_ci_list;\n\n\tif (p_temp_cpu_ci_list) {\n\t\tfor (n = 0; n < p_temp_cpu_ci_list->len; n++, cpu_ci++)\n\t\t\tfree(cpu_ci->cache_prop);\n\t\tfree(p_temp_cpu_ci_list);\n\t}\n\n}\n\n/* topology_create_temp_cpu_cache_list - Create a temporary cpu-cache list to\n *\t\tstore cpu cache information. This list will be used to copy\n *\t\tHsaCacheProperties in the CPU node. Two buffers are allocated\n *\t\tinside this function: cpu_ci list and cache_prop under each\n *\t\tcpu_ci. Must call topology_destroy_temp_cpu_cache_list to free\n *\t\tthe memory after the information is copied.\n *\t@node [IN] CPU node number\n *\t@cpuinfo [IN] /proc/cpuinfo data\n *\t@temp_cpu_ci_list [OUT] cpu-cache-info list with data filled\n * Return: total number of caches under this CPU node\n */\nstatic int topology_create_temp_cpu_cache_list(int node,\n\tstruct proc_cpuinfo *cpuinfo, cpu_cacheinfo_t **temp_cpu_ci_list)\n{\n\t/* Get max path size from /sys/devices/system/node/node%d/%s/cache\n\t * below, which will max out according to the largest filename,\n\t * which can be present twice in the string above. 29 is for the prefix\n\t * and the +6 is for the cache suffix\n\t */\n#ifndef MAXNAMLEN\n/* MAXNAMLEN is the BSD name for NAME_MAX. glibc aliases this as NAME_MAX, but not musl */\n#define MAXNAMLEN NAME_MAX\n#endif\n\tconst uint32_t MAXPATHSIZE = 29 + MAXNAMLEN + (MAXNAMLEN + 6);\n\tcpu_cacheinfo_t *p_temp_cpu_ci_list; /* a list of cpu_ci */\n\tchar path[MAXPATHSIZE], node_dir[MAXPATHSIZE];\n\tint max_cpus;\n\tcpu_cacheinfo_t *this_cpu; /* one cpu_ci in cpu_ci_list */\n\tint cache_cnt = 0;\n\tDIR *dirp = NULL;\n\tstruct dirent *dir;\n\tchar *p;\n\n\tif (!temp_cpu_ci_list) {\n\t\tpr_err(\"Invalid temp_cpu_ci_list\\n\");\n\t\tgoto exit;\n\t}\n\t*temp_cpu_ci_list = NULL;\n\n\t/* Get info from /sys/devices/system/node/nodeX/cpuY/cache */\n\tint node_real = node;\n\tif (processor_vendor == IBM_POWER) {\n\t\tif (!strcmp(cpuinfo[0].model_name, \"POWER9\")) {\n\t\t\tnode_real = node * 8;\n\t\t}\n\t}\n\tsnprintf(node_dir, MAXPATHSIZE, \"/sys/devices/system/node/node%d\", node_real);\n\t/* Other than cpuY folders, this dir also has cpulist and cpumap */\n\tmax_cpus = num_subdirs(node_dir, \"cpu\");\n\tif (max_cpus <= 0) {\n\t\t/* If CONFIG_NUMA is not enabled in the kernel,\n\t\t * /sys/devices/system/node doesn't exist.\n\t\t */\n\t\tif (node) { /* CPU node must be 0 or something is wrong */\n\t\t\tpr_err(\"Fail to get cpu* dirs under %s.\", node_dir);\n\t\t\tgoto exit;\n\t\t}\n\t\t/* Fall back to use /sys/devices/system/cpu */\n\t\tsnprintf(node_dir, MAXPATHSIZE, \"/sys/devices/system/cpu\");\n\t\tmax_cpus = num_subdirs(node_dir, \"cpu\");\n\t\tif (max_cpus <= 0) {\n\t\t\tpr_err(\"Fail to get cpu* dirs under %s\\n\", node_dir);\n\t\t\tgoto exit;\n\t\t}\n\t}\n\n\tp_temp_cpu_ci_list = calloc(max_cpus, sizeof(cpu_cacheinfo_t));\n\tif (!p_temp_cpu_ci_list) {\n\t\tpr_err(\"Fail to allocate p_temp_cpu_ci_list\\n\");\n\t\tgoto exit;\n\t}\n\tp_temp_cpu_ci_list->len = 0;\n\n\tthis_cpu = p_temp_cpu_ci_list;\n\tdirp = opendir(node_dir);\n\twhile ((dir = readdir(dirp)) != 0) {\n\t\tif (strncmp(dir->d_name, \"cpu\", 3))\n\t\t\tcontinue;\n\t\tif (!isdigit(dir->d_name[3])) /* ignore files like cpulist */\n\t\t\tcontinue;\n\t\tsnprintf(path, MAXPATHSIZE, \"%s/%s/cache\", node_dir, dir->d_name);\n\t\tthis_cpu->num_caches = num_subdirs(path, \"index\");\n\t\tthis_cpu->cache_prop = calloc(this_cpu->num_caches,\n\t\t\t\t\tsizeof(HsaCacheProperties));\n\t\tif (!this_cpu->cache_prop) {\n\t\t\tpr_err(\"Fail to allocate cache_info\\n\");\n\t\t\tgoto exit;\n\t\t}\n\t\tp = &dir->d_name[3];\n\t\tthis_cpu->proc_num = atoi(p);\n\t\tcache_cnt += get_cpu_cache_info(path, cpuinfo, this_cpu);\n\t\t++p_temp_cpu_ci_list->len;\n\t\t++this_cpu;\n\t}\n\t*temp_cpu_ci_list = p_temp_cpu_ci_list;\n\nexit:\n\tif (dirp)\n\t\tclosedir(dirp);\n\treturn cache_cnt;\n}\n\n/* topology_get_cpu_cache_props - Read CPU cache information from sysfs\n *\t@node [IN] CPU node number\n *\t@cpuinfo [IN] /proc/cpuinfo data\n *\t@tbl [OUT] the node table to fill up\n * Return: HSAKMT_STATUS_SUCCESS in success or error number in failure\n */\nstatic HSAKMT_STATUS topology_get_cpu_cache_props(int node,\n\t\t\tstruct proc_cpuinfo *cpuinfo, node_props_t *tbl)\n{\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tcpu_cacheinfo_t *cpu_ci_list = NULL;\n\tuint32_t n, cache_cnt, i;\n\tcpu_cacheinfo_t *cpu_ci;\n\tHsaCacheProperties *this_cache;\n\n\ttbl->node.NumCaches = topology_create_temp_cpu_cache_list(\n\t\t\t\t\tnode, cpuinfo, &cpu_ci_list);\n\tif (!tbl->node.NumCaches) {\n\t\t/* For \"Intel Meteor lake Mobile\", the cache info is not in sysfs,\n\t\t * That means /sys/devices/system/node/node%d/%s/cache is not exist.\n\t\t * here AMD will not black this issue.\n\t\t */\n\t\tpr_debug(\"CPU cache info is not available for node %d \\n\", node);\n\t\tgoto exit;\n\t}\n\n\ttbl->cache = calloc(tbl->node.NumCaches, sizeof(HsaCacheProperties));\n\tif (!tbl->cache) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto exit;\n\t}\n\n\t/* Now fill in the information to cache properties. */\n\tcache_cnt = 0;\n\tcpu_ci = cpu_ci_list;\n\tfor (n = 0; n < cpu_ci_list->len; n++, cpu_ci++) {\n\t\tthis_cache = cpu_ci->cache_prop;\n\t\tfor (i = 0; i < cpu_ci->num_caches; i++, this_cache++) {\n\t\t\tmemcpy(&tbl->cache[cache_cnt++],\n\t\t\t       this_cache,\n\t\t\t       sizeof(HsaCacheProperties));\n\t\t\tif (cache_cnt >= tbl->node.NumCaches)\n\t\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\ttopology_destroy_temp_cpu_cache_list(cpu_ci_list);\n\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS topology_sysfs_get_cache_props(uint32_t node_id,\n\t\t\t\t\t\t    uint32_t cache_id,\n\t\t\t\t\t\t    HsaCacheProperties *props)\n{\n\tFILE *fd;\n\tchar *read_buf, *p;\n\tchar prop_name[256];\n\tchar path[256];\n\tunsigned long long prop_val;\n\tuint32_t i, prog;\n\tint read_size;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint32_t sys_node_id;\n\n\tassert(props);\n\tret = topology_sysfs_map_node_id(node_id, &sys_node_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tsnprintf(path, 256, KFD_SYSFS_PATH_NODES \"/%d/caches/%d/properties\", get_topology_dir(), sys_node_id, cache_id);\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err1;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = HSAKMT_STATUS_ERROR;\n\t\tgoto err2;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"processor_id_low\") == 0)\n\t\t\tprops->ProcessorIdLow = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"level\") == 0)\n\t\t\tprops->CacheLevel = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"size\") == 0)\n\t\t\tprops->CacheSize = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"cache_line_size\") == 0)\n\t\t\tprops->CacheLineSize = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"cache_lines_per_tag\") == 0)\n\t\t\tprops->CacheLinesPerTag = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"association\") == 0)\n\t\t\tprops->CacheAssociativity = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"latency\") == 0)\n\t\t\tprops->CacheLatency = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"type\") == 0)\n\t\t\tprops->CacheType.Value = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"sibling_map\") == 0)\n\t\t\tbreak;\n\t}\n\n\tprog = 0;\n\tif ((sscanf(p, \"sibling_map %n\", &prog)) == 0 && prog) {\n\t\ti = 0;\n\t\twhile ((i < HSA_CPU_SIBLINGS) &&\n\t\t\t(sscanf(p += prog, \"%u%*[,\\n]%n\", &props->SiblingMap[i++], &prog) == 1))\n\t\t\tcontinue;\n\t}\n\nerr2:\n\tfree(read_buf);\nerr1:\n\tfclose(fd);\n\treturn ret;\n}\n\nstatic HSAKMT_STATUS topology_map_sysfs_to_user_node_id(uint32_t sys_node_id, uint32_t *user_node_id)\n{\n\tuint32_t node_id;\n\n\tfor (node_id = 0; node_id < map_user_to_sysfs_node_id_size; node_id++)\n\t\tif (map_user_to_sysfs_node_id[node_id] == sys_node_id) {\n\t\t\t*user_node_id = node_id;\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n}\n\n\n/* For a give Node @node_id the function gets @iolink_id information i.e. parses sysfs the following sysfs entry\n * ./nodes/@node_id/io_links/@iolink_id/properties. @node_id has to be valid accessible node.\n *\n * If node_to specified by the @iolink_id is not accessible the function returns HSAKMT_STATUS_NOT_SUPPORTED.\n * If node_to is accessible, then node_to is mapped from sysfs_node to user_node and returns HSAKMT_STATUS_SUCCESS.\n */\nstatic HSAKMT_STATUS topology_sysfs_get_iolink_props(uint32_t node_id,\n\t\t\t\t\t\t     uint32_t iolink_id,\n\t\t\t\t\t\t     HsaIoLinkProperties *props, bool p2pLink)\n{\n\tFILE *fd;\n\tchar *read_buf, *p;\n\tchar prop_name[256];\n\tchar path[256];\n\tunsigned long long prop_val;\n\tuint32_t prog;\n\tint read_size;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tuint32_t sys_node_id;\n\n\tassert(props);\n\tret = topology_sysfs_map_node_id(node_id, &sys_node_id);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\tsnprintf(path, 256, KFD_SYSFS_PATH_NODES \"/%d/%s/%d/properties\", get_topology_dir(), sys_node_id, p2pLink ? \"p2p_links\" : \"io_links\", iolink_id);\n\n\tfd = fopen(path, \"r\");\n\tif (!fd)\n\t\treturn HSAKMT_STATUS_ERROR;\n\tread_buf = malloc(PAGE_SIZE);\n\tif (!read_buf) {\n\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\tgoto err1;\n\t}\n\n\tread_size = fread(read_buf, 1, PAGE_SIZE, fd);\n\tif (read_size <= 0) {\n\t\tret = (errno == EPERM) ? HSAKMT_STATUS_NOT_SUPPORTED :\n\t\t\t\t\t HSAKMT_STATUS_ERROR;\n\t\tgoto err2;\n\t}\n\n\t/* Since we're using the buffer as a string, we make sure the string terminates */\n\tif (read_size >= PAGE_SIZE)\n\t\tread_size = PAGE_SIZE - 1;\n\tread_buf[read_size] = 0;\n\n\tprog = 0;\n\tp = read_buf;\n\twhile (sscanf(p += prog, \"%s %llu\\n%n\", prop_name, &prop_val, &prog) == 2) {\n\t\tif (strcmp(prop_name, \"type\") == 0)\n\t\t\tprops->IoLinkType = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"version_major\") == 0)\n\t\t\tprops->VersionMajor = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"version_minor\") == 0)\n\t\t\tprops->VersionMinor = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"node_from\") == 0) {\n\t\t\tif (sys_node_id != (uint32_t)prop_val) {\n\t\t\t\tret = HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t\t\t\tgoto err2;\n\t\t\t}\n\t\t\tprops->NodeFrom = node_id;\n\t\t} else if (strcmp(prop_name, \"node_to\") == 0) {\n\t\t\tbool is_node_supported;\n\t\t\tuint32_t sysfs_node_id;\n\n\t\t\tsysfs_node_id = (uint32_t)prop_val;\n\t\t\tret = topology_sysfs_check_node_supported(sysfs_node_id, &is_node_supported);\n\t\t\tif (!is_node_supported) {\n\t\t\t\tret = HSAKMT_STATUS_NOT_SUPPORTED;\n\t\t\t\tmemset(props, 0, sizeof(*props));\n\t\t\t\tgoto err2;\n\t\t\t}\n\t\t\tret = topology_map_sysfs_to_user_node_id(sysfs_node_id, &props->NodeTo);\n\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\tgoto err2;\n\t\t} else if (strcmp(prop_name, \"weight\") == 0)\n\t\t\tprops->Weight = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"min_latency\") == 0)\n\t\t\tprops->MinimumLatency = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_latency\") == 0)\n\t\t\tprops->MaximumLatency = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"min_bandwidth\") == 0)\n\t\t\tprops->MinimumBandwidth = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"max_bandwidth\") == 0)\n\t\t\tprops->MaximumBandwidth = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"recommended_transfer_size\") == 0)\n\t\t\tprops->RecTransferSize = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"recommended_sdma_engine_id_mask\") == 0)\n\t\t\tprops->RecSdmaEngIdMask = (uint32_t)prop_val;\n\t\telse if (strcmp(prop_name, \"flags\") == 0)\n\t\t\tprops->Flags.LinkProperty = (uint32_t)prop_val;\n\t}\n\n\nerr2:\n\tfree(read_buf);\nerr1:\n\tfclose(fd);\n\treturn ret;\n}\n\n/* topology_get_free_io_link_slot_for_node - For the given node_id, find the\n * next available free slot to add an io_link\n */\nstatic HsaIoLinkProperties *topology_get_free_io_link_slot_for_node(uint32_t node_id,\n\t\t\t\t\t\t\t\t    const HsaSystemProperties *sys_props,\n\t\t\t\t\t\t\t\t    node_props_t *node_props)\n{\n\tHsaIoLinkProperties *props;\n\n\tif (node_id >= sys_props->NumNodes) {\n\t\tpr_err(\"Invalid node [%d]\\n\", node_id);\n\t\treturn NULL;\n\t}\n\n\tprops = node_props[node_id].link;\n\tif (!props) {\n\t\tpr_err(\"No io_link reported for Node [%d]\\n\", node_id);\n\t\treturn NULL;\n\t}\n\n\tif (node_props[node_id].node.NumIOLinks >= sys_props->NumNodes - 1) {\n\t\tpr_err(\"No more space for io_link for Node [%d]\\n\", node_id);\n\t\treturn NULL;\n\t}\n\n\treturn &props[node_props[node_id].node.NumIOLinks];\n}\n\n/* topology_add_io_link_for_node - If a free slot is available,\n * add io_link for the given Node.\n * TODO: Add other members of HsaIoLinkProperties\n */\nstatic HSAKMT_STATUS topology_add_io_link_for_node(uint32_t node_from,\n\t\t\t\t\t\t   const HsaSystemProperties *sys_props,\n\t\t\t\t\t\t   node_props_t *node_props,\n\t\t\t\t\t\t   HSA_IOLINKTYPE IoLinkType,\n\t\t\t\t\t\t   uint32_t node_to,\n\t\t\t\t\t\t   uint32_t Weight)\n{\n\tHsaIoLinkProperties *props;\n\n\tprops = topology_get_free_io_link_slot_for_node(node_from,\n\t\t\tsys_props, node_props);\n\tif (!props)\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\n\tprops->IoLinkType = IoLinkType;\n\tprops->NodeFrom = node_from;\n\tprops->NodeTo = node_to;\n\tprops->Weight = Weight;\n\tnode_props[node_from].node.NumIOLinks++;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\n/* Find the CPU that this GPU (gpu_node) directly connects to */\nstatic int32_t gpu_get_direct_link_cpu(uint32_t gpu_node, node_props_t *node_props)\n{\n\tHsaIoLinkProperties *props = node_props[gpu_node].link;\n\tuint32_t i;\n\n\tif (!node_props[gpu_node].node.KFDGpuID || !props ||\n\t\t\tnode_props[gpu_node].node.NumIOLinks == 0)\n\t\treturn -1;\n\n\tfor (i = 0; i < node_props[gpu_node].node.NumIOLinks; i++)\n\t\tif ((props[i].IoLinkType == HSA_IOLINKTYPE_PCIEXPRESS || props[i].IoLinkType == HSA_IOLINK_TYPE_XGMI) &&\n\t\t\tprops[i].Weight <= 20) /* >20 is GPU->CPU->GPU */{\n\t\t\tif (!node_props[props[i].NodeTo].node.KFDGpuID)\n\t\t\t\treturn props[i].NodeTo;\n\t\t}\n\n\treturn -1;\n}\n\n/* Get node1->node2 IO link information. This should be a direct link that has\n * been created in the kernel.\n */\nstatic HSAKMT_STATUS get_direct_iolink_info(uint32_t node1, uint32_t node2,\n\t\t\t\t\t    node_props_t *node_props, HSAuint32 *weight,\n\t\t\t\t\t    HSA_IOLINKTYPE *type)\n{\n\tHsaIoLinkProperties *props = node_props[node1].link;\n\tuint32_t i;\n\n\tif (!props)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\tfor (i = 0; i < node_props[node1].node.NumIOLinks; i++)\n\t\tif (props[i].NodeTo == node2) {\n\t\t\tif (weight)\n\t\t\t\t*weight = props[i].Weight;\n\t\t\tif (type)\n\t\t\t\t*type = props[i].IoLinkType;\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\n\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n}\n\nstatic HSAKMT_STATUS get_indirect_iolink_info(uint32_t node1, uint32_t node2,\n\t\t\t\t\t      node_props_t *node_props, HSAuint32 *weight,\n\t\t\t\t\t      HSA_IOLINKTYPE *type)\n{\n\tint32_t dir_cpu1 = -1, dir_cpu2 = -1;\n\tHSAuint32 weight1 = 0, weight2 = 0, weight3 = 0;\n\tHSAKMT_STATUS ret;\n\tuint32_t i;\n\n\t*weight = 0;\n\t*type = HSA_IOLINKTYPE_UNDEFINED;\n\n\tif (node1 == node2)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\t/* CPU->CPU is not an indirect link */\n\tif (!node_props[node1].node.KFDGpuID && !node_props[node2].node.KFDGpuID)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n\tif (node_props[node1].node.HiveID &&\n\t    node_props[node2].node.HiveID &&\n\t    node_props[node1].node.HiveID == node_props[node2].node.HiveID)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tif (node_props[node1].node.KFDGpuID)\n\t\tdir_cpu1 = gpu_get_direct_link_cpu(node1, node_props);\n\tif (node_props[node2].node.KFDGpuID)\n\t\tdir_cpu2 = gpu_get_direct_link_cpu(node2, node_props);\n\n\tif (dir_cpu1 < 0 && dir_cpu2 < 0)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t/* if the node2(dst) is GPU , it need to be large bar for host access*/\n\tif (node_props[node2].node.KFDGpuID) {\n\t\tfor (i = 0; i < node_props[node2].node.NumMemoryBanks; ++i)\n\t\t\tif (node_props[node2].mem[i].HeapType ==\n\t\t\t\tHSA_HEAPTYPE_FRAME_BUFFER_PUBLIC)\n\t\t\t\tbreak;\n\t\tif (i >=  node_props[node2].node.NumMemoryBanks)\n\t\t\treturn HSAKMT_STATUS_ERROR;\n\t}\n\t/* Possible topology:\n\t *   GPU --(weight1) -- CPU -- (weight2) -- GPU\n\t *   GPU --(weight1) -- CPU -- (weight2) -- CPU -- (weight3) -- GPU\n\t *   GPU --(weight1) -- CPU -- (weight2) -- CPU\n\t *   CPU -- (weight2) -- CPU -- (weight3) -- GPU\n\t */\n\tif (dir_cpu1 >= 0) { /* GPU->CPU ... */\n\t\tif (dir_cpu2 >= 0) {\n\t\t\tif (dir_cpu1 == dir_cpu2) /* GPU->CPU->GPU*/ {\n\t\t\t\tret = get_direct_iolink_info(node1, dir_cpu1,\n\t\t\t\t\t\tnode_props, &weight1, NULL);\n\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\t\treturn ret;\n\t\t\t\tret = get_direct_iolink_info(dir_cpu1, node2,\n\t\t\t\t\t\tnode_props, &weight2, type);\n\t\t\t} else /* GPU->CPU->CPU->GPU*/ {\n\t\t\t\tret = get_direct_iolink_info(node1, dir_cpu1,\n\t\t\t\t\t\tnode_props, &weight1, NULL);\n\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\t\treturn ret;\n\t\t\t\tret = get_direct_iolink_info(dir_cpu1, dir_cpu2,\n\t\t\t\t\t\tnode_props, &weight2, type);\n\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\t\treturn ret;\n\t\t\t\t/* On QPI interconnection, GPUs can't access\n\t\t\t\t * each other if they are attached to different\n\t\t\t\t * CPU sockets. CPU<->CPU weight larger than 20\n\t\t\t\t * means the two CPUs are in different sockets.\n\t\t\t\t */\n\t\t\t\tif (*type == HSA_IOLINK_TYPE_QPI_1_1\n\t\t\t\t\t&& weight2 > 20)\n\t\t\t\t\treturn HSAKMT_STATUS_NOT_SUPPORTED;\n\t\t\t\tret = get_direct_iolink_info(dir_cpu2, node2,\n\t\t\t\t\t\tnode_props, &weight3, NULL);\n\t\t\t}\n\t\t} else /* GPU->CPU->CPU */ {\n\t\t\tret = get_direct_iolink_info(node1, dir_cpu1, node_props,\n\t\t\t\t\t\t\t&weight1, NULL);\n\t\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\t\treturn ret;\n\t\t\tret = get_direct_iolink_info(dir_cpu1, node2, node_props,\n\t\t\t\t\t\t\t&weight2, type);\n\t\t}\n\t} else { /* CPU->CPU->GPU */\n\t\tret = get_direct_iolink_info(node1, dir_cpu2, node_props, &weight2,\n\t\t\t\t\ttype);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\t\treturn ret;\n\t\tret = get_direct_iolink_info(dir_cpu2, node2, node_props, &weight3,\n\t\t\t\t\t\tNULL);\n\t}\n\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\treturn ret;\n\n\t*weight = weight1 + weight2 + weight3;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nstatic void topology_create_indirect_gpu_links(const HsaSystemProperties *sys_props,\n\t\t\t\t\t       node_props_t *node_props)\n{\n\n\tuint32_t i, j;\n\tHSAuint32 weight;\n\tHSA_IOLINKTYPE type;\n\n\tfor (i = 0; i < sys_props->NumNodes - 1; i++) {\n\t\tfor (j = i + 1; j < sys_props->NumNodes; j++) {\n\t\t\tget_indirect_iolink_info(i, j, node_props, &weight, &type);\n\t\t\tif (!weight)\n\t\t\t\tgoto try_alt_dir;\n\t\t\tif (topology_add_io_link_for_node(i, sys_props, node_props,\n\t\t\t\ttype, j, weight) != HSAKMT_STATUS_SUCCESS)\n\t\t\t\tpr_err(\"Fail to add IO link %d->%d\\n\", i, j);\ntry_alt_dir:\n\t\t\tget_indirect_iolink_info(j, i, node_props, &weight, &type);\n\t\t\tif (!weight)\n\t\t\t\tcontinue;\n\t\t\tif (topology_add_io_link_for_node(j, sys_props, node_props,\n\t\t\t\ttype, i, weight) != HSAKMT_STATUS_SUCCESS)\n\t\t\t\tpr_err(\"Fail to add IO link %d->%d\\n\", j, i);\n\t\t}\n\t}\n}\n\nHSAKMT_STATUS topology_take_snapshot(void)\n{\n\tuint32_t gen_start, gen_end, i, mem_id, cache_id;\n\tHsaSystemProperties sys_props;\n\tnode_props_t *temp_props = 0;\n\tHSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\tstruct proc_cpuinfo *cpuinfo;\n\tconst uint32_t num_procs = get_nprocs();\n\tuint32_t num_ioLinks;\n\tbool p2p_links = false;\n\tuint32_t num_p2pLinks = 0;\n\n\tcpuinfo = calloc(num_procs, sizeof(struct proc_cpuinfo));\n\tif (!cpuinfo) {\n\t\tpr_err(\"Fail to allocate memory for CPU info\\n\");\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\t}\n\ttopology_parse_cpuinfo(cpuinfo, num_procs);\n\nretry:\n\tret = topology_sysfs_get_generation(&gen_start);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\tgoto err;\n\tret = hsakmt_topology_sysfs_get_system_props(&sys_props);\n\tif (ret != HSAKMT_STATUS_SUCCESS)\n\t\tgoto err;\n\tif (sys_props.NumNodes > 0) {\n\t\ttemp_props = calloc(sys_props.NumNodes * sizeof(node_props_t), 1);\n\t\tif (!temp_props) {\n\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\tgoto err;\n\t\t}\n\t\tfor (i = 0; i < sys_props.NumNodes; i++) {\n\t\t\tret = topology_sysfs_get_node_props(i,\n\t\t\t\t\t&temp_props[i].node,\n\t\t\t\t\t&p2p_links, &num_p2pLinks);\n\t\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\tfree_properties(temp_props, i);\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\tif (temp_props[i].node.NumCPUCores)\n\t\t\t\ttopology_get_cpu_model_name(&temp_props[i].node,\n\t\t\t\t\t\t\tcpuinfo, num_procs);\n\n\t\t\tif (temp_props[i].node.NumMemoryBanks) {\n\t\t\t\ttemp_props[i].mem = calloc(temp_props[i].node.NumMemoryBanks * sizeof(HsaMemoryProperties), 1);\n\t\t\t\tif (!temp_props[i].mem) {\n\t\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\t\tfor (mem_id = 0; mem_id < temp_props[i].node.NumMemoryBanks; mem_id++) {\n\t\t\t\t\tret = topology_sysfs_get_mem_props(i, mem_id, &temp_props[i].mem[mem_id]);\n\t\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\t\tgoto err;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (temp_props[i].node.NumCaches) {\n\t\t\t\ttemp_props[i].cache = calloc(temp_props[i].node.NumCaches * sizeof(HsaCacheProperties), 1);\n\t\t\t\tif (!temp_props[i].cache) {\n\t\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\t\tfor (cache_id = 0; cache_id < temp_props[i].node.NumCaches; cache_id++) {\n\t\t\t\t\tret = topology_sysfs_get_cache_props(i, cache_id, &temp_props[i].cache[cache_id]);\n\t\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\t\tgoto err;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!temp_props[i].node.KFDGpuID) { /* a CPU node */\n\t\t\t\tret = topology_get_cpu_cache_props(\n\t\t\t\t\t\ti, cpuinfo, &temp_props[i]);\n\t\t\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* To simplify, allocate maximum needed memory for io_links for each node. This\n\t\t\t * removes the need for realloc when indirect and QPI links are added later\n\t\t\t */\n\t\t\ttemp_props[i].link = calloc(sys_props.NumNodes - 1, sizeof(HsaIoLinkProperties));\n\t\t\tif (!temp_props[i].link) {\n\t\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\tnum_ioLinks = temp_props[i].node.NumIOLinks - num_p2pLinks;\n\t\t\tuint32_t link_id = 0;\n\n\t\t\tif (num_ioLinks) {\n\t\t\t\tuint32_t sys_link_id = 0;\n\n\t\t\t\t/* Parse all the sysfs specified io links. Skip the ones where the\n\t\t\t\t * remote node (node_to) is not accessible\n\t\t\t\t */\n\t\t\t\twhile (sys_link_id < num_ioLinks &&\n\t\t\t\t\tlink_id < sys_props.NumNodes - 1) {\n\t\t\t\t\tret = topology_sysfs_get_iolink_props(i, sys_link_id++,\n\t\t\t\t\t\t\t\t&temp_props[i].link[link_id], false);\n\t\t\t\t\tif (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\t\tgoto err;\n\t\t\t\t\t}\n\t\t\t\t\tlink_id++;\n\t\t\t\t}\n\t\t\t\t/* sysfs specifies all the io links. Limit the number to valid ones */\n\t\t\t\ttemp_props[i].node.NumIOLinks = link_id;\n\t\t\t}\n\n\t\t\tif (num_p2pLinks) {\n\t\t\t\tuint32_t sys_link_id = 0;\n\n\t\t\t\t/* Parse all the sysfs specified p2p links.\n\t\t\t\t */\n\t\t\t\twhile (sys_link_id < num_p2pLinks &&\n\t\t\t\t\tlink_id < sys_props.NumNodes - 1) {\n\t\t\t\t\tret = topology_sysfs_get_iolink_props(i, sys_link_id++,\n\t\t\t\t\t\t\t\t&temp_props[i].link[link_id], true);\n\t\t\t\t\tif (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\t\t\t\tfree_properties(temp_props, i + 1);\n\t\t\t\t\t\tgoto err;\n\t\t\t\t\t}\n\t\t\t\t\tlink_id++;\n\t\t\t\t}\n\t\t\t\ttemp_props[i].node.NumIOLinks = link_id;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!p2p_links) {\n\t\t/* All direct IO links are created in the kernel. Here we need to\n\t\t * connect GPU<->GPU or GPU<->CPU indirect IO links.\n\t\t */\n\t\ttopology_create_indirect_gpu_links(&sys_props, temp_props);\n\t}\n\n\tret = topology_sysfs_get_generation(&gen_end);\n\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\tfree_properties(temp_props, sys_props.NumNodes);\n\t\tgoto err;\n\t}\n\n\tif (gen_start != gen_end) {\n\t\tfree_properties(temp_props, sys_props.NumNodes);\n\t\ttemp_props = 0;\n\t\tgoto retry;\n\t}\n\n\tif (!g_system) {\n\t\tg_system = malloc(sizeof(HsaSystemProperties));\n\t\tif (!g_system) {\n\t\t\tfree_properties(temp_props, sys_props.NumNodes);\n\t\t\tret = HSAKMT_STATUS_NO_MEMORY;\n\t\t\tgoto err;\n\t\t}\n\t}\n\n\t*g_system = sys_props;\n\tif (g_props)\n\t\tfree(g_props);\n\tg_props = temp_props;\nerr:\n\tfree(cpuinfo);\n\treturn ret;\n}\n\n/* Drop the Snapshot of the HSA topology information. Assume lock is held. */\nvoid topology_drop_snapshot(void)\n{\n\tif (!!g_system != !!g_props)\n\t\tpr_warn(\"Probably inconsistency?\\n\");\n\n\tif (g_props) {\n\t\t/* Remove state */\n\t\tfree_properties(g_props, g_system->NumNodes);\n\t\tg_props = NULL;\n\t}\n\n\tfree(g_system);\n\tg_system = NULL;\n\n\tif (map_user_to_sysfs_node_id) {\n\t\tfree(map_user_to_sysfs_node_id);\n\t\tmap_user_to_sysfs_node_id = NULL;\n\t\tmap_user_to_sysfs_node_id_size = 0;\n\t}\n}\n\nHSAKMT_STATUS hsakmt_validate_nodeid(uint32_t nodeid, uint32_t *gpu_id)\n{\n\tif (!g_props || !g_system || g_system->NumNodes <= nodeid)\n\t\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\tif (gpu_id)\n\t\t*gpu_id = g_props[nodeid].node.KFDGpuID;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_gpuid_to_nodeid(uint32_t gpu_id, uint32_t *node_id)\n{\n\tuint64_t node_idx;\n\n\tfor (node_idx = 0; node_idx < g_system->NumNodes; node_idx++) {\n\t\tif (g_props[node_idx].node.KFDGpuID == gpu_id) {\n\t\t\t*node_id = node_idx;\n\t\t\treturn HSAKMT_STATUS_SUCCESS;\n\t\t}\n\t}\n\n\treturn HSAKMT_STATUS_INVALID_NODE_UNIT;\n\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtAcquireSystemProperties(HsaSystemProperties *SystemProperties)\n{\n\tHSAKMT_STATUS err = HSAKMT_STATUS_SUCCESS;\n\n\tCHECK_KFD_OPEN();\n\n\tif (!SystemProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\t/* We already have a valid snapshot. Avoid double initialization that\n\t * would leak memory.\n\t */\n\tif (g_system) {\n\t\t*SystemProperties = *g_system;\n\t\tgoto out;\n\t}\n\n\terr = topology_take_snapshot();\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto out;\n\n\tassert(g_system);\n\n\tif (hsakmt_use_model)\n\t\tmodel_init();\n\n\terr = hsakmt_fmm_init_process_apertures(g_system->NumNodes);\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto init_process_apertures_failed;\n\n\terr = hsakmt_init_process_doorbells(g_system->NumNodes);\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto init_doorbells_failed;\n\n\t*SystemProperties = *g_system;\n\n\tgoto out;\n\ninit_doorbells_failed:\n\thsakmt_fmm_destroy_process_apertures();\ninit_process_apertures_failed:\n\ttopology_drop_snapshot();\n\nout:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn err;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtReleaseSystemProperties(void)\n{\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\thsakmt_destroy_process_doorbells();\n\thsakmt_fmm_destroy_process_apertures();\n\ttopology_drop_snapshot();\n\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_topology_get_node_props(HSAuint32 NodeId,\n\t\t\t\t      HsaNodeProperties *NodeProperties)\n{\n\tif (!g_system || !g_props || NodeId >= g_system->NumNodes)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\t*NodeProperties = g_props[NodeId].node;\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetNodeProperties(HSAuint32 NodeId,\n\t\t\t\t\t\tHsaNodeProperties *NodeProperties)\n{\n\tHSAKMT_STATUS err;\n\tuint32_t gpu_id;\n\n\tif (!NodeProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tCHECK_KFD_OPEN();\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\terr = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto out;\n\n\terr = hsakmt_topology_get_node_props(NodeId, NodeProperties);\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto out;\n\t/* For CPU only node don't add any additional GPU memory banks. */\n\tif (gpu_id) {\n\t\tuint64_t base, limit;\n\t\tif (hsakmt_is_dgpu)\n\t\t\tNodeProperties->NumMemoryBanks += NUM_OF_DGPU_HEAPS;\n\t\telse\n\t\t\tNodeProperties->NumMemoryBanks += NUM_OF_IGPU_HEAPS;\n\t\tif (hsakmt_fmm_get_aperture_base_and_limit(FMM_MMIO, gpu_id, &base,\n\t\t\t\t&limit) == HSAKMT_STATUS_SUCCESS)\n\t\t\tNodeProperties->NumMemoryBanks += 1;\n\t}\n\nout:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn err;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetNodeMemoryProperties(HSAuint32 NodeId,\n\t\t\t\t\t\t      HSAuint32 NumBanks,\n\t\t\t\t\t\t      HsaMemoryProperties *MemoryProperties)\n{\n\tHSAKMT_STATUS err = HSAKMT_STATUS_SUCCESS;\n\tuint32_t i, gpu_id;\n\tHSAuint64 aperture_limit;\n\n\tif (!MemoryProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tCHECK_KFD_OPEN();\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\terr = hsakmt_validate_nodeid(NodeId, &gpu_id);\n\tif (err != HSAKMT_STATUS_SUCCESS)\n\t\tgoto out;\n\n\tmemset(MemoryProperties, 0, NumBanks * sizeof(HsaMemoryProperties));\n\n\tfor (i = 0; i < MIN(g_props[NodeId].node.NumMemoryBanks, NumBanks); i++) {\n\t\tassert(g_props[NodeId].mem);\n\t\tMemoryProperties[i] = g_props[NodeId].mem[i];\n\t}\n\n\t/* The following memory banks does not apply to CPU only node */\n\tif (gpu_id == 0)\n\t\tgoto out;\n\n\t/*Add LDS*/\n\tif (i < NumBanks &&\n\t\thsakmt_fmm_get_aperture_base_and_limit(FMM_LDS, gpu_id,\n\t\t\t\t&MemoryProperties[i].VirtualBaseAddress, &aperture_limit) == HSAKMT_STATUS_SUCCESS) {\n\t\tMemoryProperties[i].HeapType = HSA_HEAPTYPE_GPU_LDS;\n\t\tMemoryProperties[i].SizeInBytes = g_props[NodeId].node.LDSSizeInKB * 1024;\n\t\ti++;\n\t}\n\n\t/* Add Local memory - HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE.\n\t * For dGPU the topology node contains Local Memory and it is added by\n\t * the for loop above\n\t */\n\tif (hsakmt_get_gfxv_by_node_id(NodeId) == GFX_VERSION_KAVERI && i < NumBanks &&\n\t\tg_props[NodeId].node.LocalMemSize > 0 &&\n\t\thsakmt_fmm_get_aperture_base_and_limit(FMM_GPUVM, gpu_id,\n\t\t\t\t&MemoryProperties[i].VirtualBaseAddress, &aperture_limit) == HSAKMT_STATUS_SUCCESS) {\n\t\tMemoryProperties[i].HeapType = HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE;\n\t\tMemoryProperties[i].SizeInBytes = g_props[NodeId].node.LocalMemSize;\n\t\ti++;\n\t}\n\n\t/* Add SCRATCH */\n\tif (i < NumBanks &&\n\t\thsakmt_fmm_get_aperture_base_and_limit(FMM_SCRATCH, gpu_id,\n\t\t\t\t&MemoryProperties[i].VirtualBaseAddress, &aperture_limit) == HSAKMT_STATUS_SUCCESS) {\n\t\tMemoryProperties[i].HeapType = HSA_HEAPTYPE_GPU_SCRATCH;\n\t\tMemoryProperties[i].SizeInBytes = (aperture_limit - MemoryProperties[i].VirtualBaseAddress) + 1;\n\t\ti++;\n\t}\n\n\t/* Add SVM aperture */\n\tif (hsakmt_topology_is_svm_needed(g_props[NodeId].node.EngineId) && i < NumBanks &&\n\t    hsakmt_fmm_get_aperture_base_and_limit(\n\t\t    FMM_SVM, gpu_id, &MemoryProperties[i].VirtualBaseAddress,\n\t\t    &aperture_limit) == HSAKMT_STATUS_SUCCESS) {\n\t\tMemoryProperties[i].HeapType = HSA_HEAPTYPE_DEVICE_SVM;\n\t\tMemoryProperties[i].SizeInBytes = (aperture_limit - MemoryProperties[i].VirtualBaseAddress) + 1;\n\t\ti++;\n\t}\n\n\t/* Add mmio aperture */\n\tif (i < NumBanks &&\n\t\thsakmt_fmm_get_aperture_base_and_limit(FMM_MMIO, gpu_id,\n\t\t\t\t&MemoryProperties[i].VirtualBaseAddress, &aperture_limit) == HSAKMT_STATUS_SUCCESS) {\n\t\tMemoryProperties[i].HeapType = HSA_HEAPTYPE_MMIO_REMAP;\n\t\tMemoryProperties[i].SizeInBytes = (aperture_limit - MemoryProperties[i].VirtualBaseAddress) + 1;\n\t\ti++;\n\t}\n\nout:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn err;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetNodeCacheProperties(HSAuint32 NodeId,\n\t\t\t\t\t\t     HSAuint32 ProcessorId,\n\t\t\t\t\t\t     HSAuint32 NumCaches,\n\t\t\t\t\t\t     HsaCacheProperties *CacheProperties)\n{\n\tHSAKMT_STATUS err;\n\tuint32_t i;\n\n\tif (!CacheProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tCHECK_KFD_OPEN();\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\t/* KFD ADD page 18, snapshot protocol violation */\n\tif (!g_system || NodeId >= g_system->NumNodes) {\n\t\terr = HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t\tgoto out;\n\t}\n\n\tif (NumCaches > g_props[NodeId].node.NumCaches) {\n\t\terr = HSAKMT_STATUS_INVALID_PARAMETER;\n\t\tgoto out;\n\t}\n\n\tfor (i = 0; i < MIN(g_props[NodeId].node.NumCaches, NumCaches); i++) {\n\t\tassert(g_props[NodeId].cache);\n\t\tCacheProperties[i] = g_props[NodeId].cache[i];\n\t}\n\n\terr = HSAKMT_STATUS_SUCCESS;\n\nout:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn err;\n}\n\nHSAKMT_STATUS hsakmt_topology_get_iolink_props(HSAuint32 NodeId,\n\t\t\t\t\tHSAuint32 NumIoLinks,\n\t\t\t\t\tHsaIoLinkProperties *IoLinkProperties)\n{\n\tif (!g_system || !g_props || NodeId >= g_system->NumNodes)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\tmemcpy(IoLinkProperties, g_props[NodeId].link,\n\t       NumIoLinks * sizeof(*IoLinkProperties));\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetNodeIoLinkProperties(HSAuint32 NodeId,\n\t\t\t\t\t\t      HSAuint32 NumIoLinks,\n\t\t\t\t\t\t      HsaIoLinkProperties *IoLinkProperties)\n{\n\tHSAKMT_STATUS err;\n\n\tif (!IoLinkProperties)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\tCHECK_KFD_OPEN();\n\n\tpthread_mutex_lock(&hsakmt_mutex);\n\n\t/* KFD ADD page 18, snapshot protocol violation */\n\tif (!g_system || NodeId >= g_system->NumNodes ) {\n\t\terr = HSAKMT_STATUS_INVALID_NODE_UNIT;\n\t\tgoto out;\n\t}\n\n\tif (NumIoLinks > g_props[NodeId].node.NumIOLinks) {\n\t\terr = HSAKMT_STATUS_INVALID_PARAMETER;\n\t\tgoto out;\n\t}\n\n\tassert(g_props[NodeId].link);\n\terr = hsakmt_topology_get_iolink_props(NodeId, NumIoLinks, IoLinkProperties);\n\nout:\n\tpthread_mutex_unlock(&hsakmt_mutex);\n\treturn err;\n}\n\nuint32_t hsakmt_get_gfxv_by_node_id(HSAuint32 node_id)\n{\n\treturn HSA_GET_GFX_VERSION_FULL(g_props[node_id].node.EngineId.ui32);\n}\n\nuint16_t hsakmt_get_device_id_by_node_id(HSAuint32 node_id)\n{\n\tif (!g_props || !g_system || g_system->NumNodes <= node_id)\n\t\treturn 0;\n\n\treturn g_props[node_id].node.DeviceId;\n}\n\nbool hsakmt_prefer_ats(HSAuint32 node_id)\n{\n\treturn g_props[node_id].node.Capability.ui32.HSAMMUPresent\n\t\t\t&& g_props[node_id].node.NumCPUCores\n\t\t\t&& g_props[node_id].node.NumFComputeCores;\n}\n\nuint16_t hsakmt_get_device_id_by_gpu_id(HSAuint32 gpu_id)\n{\n\tunsigned int i;\n\n\tif (!g_props || !g_system)\n\t\treturn 0;\n\n\tfor (i = 0; i < g_system->NumNodes; i++) {\n\t\tif (g_props[i].node.KFDGpuID == gpu_id)\n\t\t\treturn g_props[i].node.DeviceId;\n\t}\n\n\treturn 0;\n}\n\nuint32_t hsakmt_get_direct_link_cpu(uint32_t gpu_node)\n{\n\tHSAuint64 size = 0;\n\tint32_t cpu_id;\n\tHSAuint32 i;\n\n\tcpu_id = gpu_get_direct_link_cpu(gpu_node, g_props);\n\tif (cpu_id == -1)\n\t\treturn INVALID_NODEID;\n\n\tassert(g_props[cpu_id].mem);\n\n\tfor (i = 0; i < g_props[cpu_id].node.NumMemoryBanks; i++)\n\t\tsize += g_props[cpu_id].mem[i].SizeInBytes;\n\n\treturn size ? (uint32_t)cpu_id : INVALID_NODEID;\n}\n\n\nHSAKMT_STATUS hsakmt_validate_nodeid_array(uint32_t **gpu_id_array,\n\t\tuint32_t NumberOfNodes, uint32_t *NodeArray)\n{\n\tHSAKMT_STATUS ret;\n\tunsigned int i;\n\n\tif (NumberOfNodes == 0 || !NodeArray || !gpu_id_array)\n\t\treturn HSAKMT_STATUS_INVALID_PARAMETER;\n\n\t/* Translate Node IDs to gpu_ids */\n\t*gpu_id_array = malloc(NumberOfNodes * sizeof(uint32_t));\n\tif (!(*gpu_id_array))\n\t\treturn HSAKMT_STATUS_NO_MEMORY;\n\tfor (i = 0; i < NumberOfNodes; i++) {\n\t\tret = hsakmt_validate_nodeid(NodeArray[i], *gpu_id_array + i);\n\t\tif (ret != HSAKMT_STATUS_SUCCESS) {\n\t\t\tfree(*gpu_id_array);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\ninline uint32_t hsakmt_get_num_sysfs_nodes(void)\n{\n\treturn num_sysfs_nodes;\n}\n"
  },
  {
    "path": "libhsakmt/src/version.c",
    "content": "/*\n * Copyright © 2014 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use, copy,\n * modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including\n * the next paragraph) shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n#include \"libhsakmt.h\"\n#include <stdlib.h>\n#include <string.h>\n#include \"hsakmt/linux/kfd_ioctl.h\"\n\nHsaVersionInfo hsakmt_kfd_version_info;\n\nHSAKMT_STATUS HSAKMTAPI hsaKmtGetVersion(HsaVersionInfo *VersionInfo)\n{\n\tCHECK_KFD_OPEN();\n\n\t*VersionInfo = hsakmt_kfd_version_info;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS hsakmt_init_kfd_version(void)\n{\n\tstruct kfd_ioctl_get_version_args args = {0};\n\n\tif (hsakmt_ioctl(hsakmt_kfd_fd, AMDKFD_IOC_GET_VERSION, &args) == -1)\n\t\treturn HSAKMT_STATUS_ERROR;\n\n\thsakmt_kfd_version_info.KernelInterfaceMajorVersion = args.major_version;\n\thsakmt_kfd_version_info.KernelInterfaceMinorVersion = args.minor_version;\n\n\tif (args.major_version != 1)\n\t\treturn HSAKMT_STATUS_DRIVER_MISMATCH;\n\n\treturn HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/CMakeLists.txt",
    "content": "\n# Copyright 2025 Advanced Micro Devices, Inc.\n\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the \"Software\"),\n# to deal in the Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n# and/or sell copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following conditions:\n\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\ncmake_minimum_required ( VERSION 3.7 )\n\nset (CMAKE_VERBOSE_MAKEFILE ON)\n\nset ( HSAKMT_VIRTIO \"hsakmt_virtio\" )\nset ( HSAKMT_VIRTIO_TARGET \"${HSAKMT_VIRTIO}\" )\n\nproject ( ${HSAKMT_VIRTIO_TARGET} VERSION 1.0)\n\n## Compiler flags\nset ( HSAKMT_VIRTIO_C_FLAGS -fPIC -W -Wall -Wextra -Wno-unused-parameter -Wformat-security -Wswitch-default -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wunreachable-code -std=gnu99 -fvisibility=hidden )\nif ( CMAKE_COMPILER_IS_GNUCC )\n    set ( HSAKMT_VIRTIO_C_FLAGS \"${HSAKMT_VIRTIO_C_FLAGS}\" -Wlogical-op )\nendif ()\n\nset ( HSAKMT_VIRTIO_LINKER_SCRIPT \"${CMAKE_CURRENT_SOURCE_DIR}/libhsakmt_virtio.ver\" )\n\nset ( HSAKMT_VIRTIO_LINK_FLAGS \"-Wl,--enable-new-dtags -Wl,--version-script=${HSAKMT_VIRTIO_LINKER_SCRIPT} -Wl,-z,nodelete\")\n\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    set ( HSAKMT_VIRTIO_C_FLAGS \"${HSAKMT_VIRTIO_C_FLAGS}\" -O2 )\nelse ()\n    set ( HSAKMT_VIRTIO_C_FLAGS \"${HSAKMT_VIRTIO_C_FLAGS}\" -g )\nendif ()\n\nset ( HSAKMT_VIRTIO_SRC \"virtio_gpu.c\"\n                        \"hsakmt_virtio_vm.c\"\n                        \"hsakmt_virtio_device.c\"\n                        \"hsakmt_virtio_memory.c\"\n                        \"hsakmt_virtio_amdgpu.c\"\n                        \"hsakmt_virtio_events.c\"\n                        \"hsakmt_virtio_queues.c\"\n                        \"hsakmt_virtio_topology.c\"\n                        \"hsakmt_virtio_openclose.c\"\n                        \"../rbtree.c\" )\n\nadd_library ( ${HSAKMT_VIRTIO_TARGET} STATIC ${HSAKMT_VIRTIO_SRC} )\n\ntarget_sources ( ${HSAKMT_VIRTIO_TARGET} PRIVATE ${HSAKMT_VIRTIO_SRC} )\n\ntarget_compile_options ( ${HSAKMT_VIRTIO_TARGET} PRIVATE ${HSAKMT_VIRTIO_C_FLAGS} )\n\ntarget_include_directories ( ${HSAKMT_VIRTIO_TARGET}\n    PUBLIC\n    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\n    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n    PRIVATE\n    ${CMAKE_CURRENT_SOURCE_DIR}/virtio\n    ${CMAKE_CURRENT_SOURCE_DIR}/../\n    ${CMAKE_CURRENT_SOURCE_DIR}/../../include\n    ${CMAKE_CURRENT_SOURCE_DIR}/include/linux )\n\nset_property(TARGET ${HSAKMT_VIRTIO_TARGET} PROPERTY LINK_FLAGS ${HSAKMT_VIRTIO_LINK_FLAGS})\n\nfind_package ( PkgConfig )\n\n## If environment variable DRM_DIR is set, the script\n## will pick up the corresponding libraries from that path.\nlist ( PREPEND CMAKE_PREFIX_PATH \"${DRM_DIR}\" )\n\npkg_check_modules ( DRM REQUIRED IMPORTED_TARGET libdrm )\npkg_check_modules ( DRM_AMDGPU REQUIRED IMPORTED_TARGET libdrm_amdgpu )\ntarget_include_directories ( ${HSAKMT_VIRTIO_TARGET} PRIVATE ${DRM_AMDGPU_INCLUDE_DIRS} )\ntarget_include_directories ( ${HSAKMT_VIRTIO_TARGET} PRIVATE ${DRM_INCLUDE_DIRS} )\n\ntarget_link_libraries ( ${HSAKMT_VIRTIO_TARGET}\n    PRIVATE ${DRM_LDFLAGS} ${DRM_AMDGPU_LDFLAGS} pthread rt c ${CMAKE_DL_LIBS} )\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_amdgpu.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\nint vamdgpu_query_gpu_info(amdgpu_device_handle handle, void* out) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GPU_INFO,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  int ret = vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  if (!ret) memcpy(out, &rsp->gpu_info, sizeof(struct amdgpu_gpu_info));\n\n  return ret;\n}\n\nHSAKMT_STATUS vhsaKmtGetAMDGPUDeviceHandle(HSAuint32 NodeId, HsaAMDGPUDeviceHandle* DeviceHandle) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  return HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_device.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n * All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * on the rights to use, copy, modify, merge, publish, distribute, sub\n * license, and/or sell copies of the Software, and to permit persons to whom\n * the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including the next\n * paragraph) shall be included in all copies or substantial portions of the\n * Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,\n * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n * USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt_virtio_device.h\"\n\nint vhsakmt_execbuf_cpu(vhsakmt_device_handle dev, struct vhsakmt_ccmd_req* req, const char* from) {\n  return virtio_gpu_exec_cmd(dev->vgdev, req, true);\n}\n\nvoid* vhsakmt_alloc_rsp(vhsakmt_device_handle dev, struct vhsakmt_ccmd_req* req, uint32_t sz) {\n  return virtio_gpu_alloc_rsp(dev->vgdev, req, sz);\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_device.h",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n * All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * on the rights to use, copy, modify, merge, publish, distribute, sub\n * license, and/or sell copies of the Software, and to permit persons to whom\n * the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including the next\n * paragraph) shall be included in all copies or substantial portions of the\n * Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,\n * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n * USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef HSAKMT_VIRTIO_DEVICE_H\n#define HSAKMT_VIRTIO_DEVICE_H\n\n#include \"hsakmt_virtio_proto.h\"\n#include \"rbtree.h\"\n#include \"virtio_gpu.h\"\n#include <stdatomic.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define vhsakmt_atomic_inc_return(ptr) (atomic_fetch_add((ptr), 1) + 1)\n#define vhsakmt_atomic_dec_return(ptr) (atomic_fetch_sub((ptr), 1) - 1)\n\n#define VHSA_VPTR_TO_UINT64(vptr) ((uint64_t)(unsigned long)(vptr))\n#define VHSA_UINT64_TO_VPTR(v) ((void*)(unsigned long)(v))\n\nextern int vhsakmt_debug_level;\n#define vhsakmt_print(level, fmt, ...)                                                             \\\n  do {                                                                                             \\\n    if (level <= vhsakmt_debug_level) fprintf(stderr, fmt, ##__VA_ARGS__);                         \\\n  } while (0)\n#define VHSAKMT_DEBUG_LEVEL_DEFAULT -1\n#define VHSAKMT_DEBUG_LEVEL_ERR 3\n#define VHSAKMT_DEBUG_LEVEL_WARNING 4\n#define VHSAKMT_DEBUG_LEVEL_INFO 6\n#define VHSAKMT_DEBUG_LEVEL_DEBUG 7\n#define vhsa_err(fmt, ...) vhsakmt_print(VHSAKMT_DEBUG_LEVEL_ERR, fmt, ##__VA_ARGS__)\n#define vhsa_warn(fmt, ...) vhsakmt_print(VHSAKMT_DEBUG_LEVEL_WARNING, fmt, ##__VA_ARGS__)\n#define vhsa_info(fmt, ...) vhsakmt_print(VHSAKMT_DEBUG_LEVEL_INFO, fmt, ##__VA_ARGS__)\n#define vhsa_debug(fmt, ...) vhsakmt_print(VHSAKMT_DEBUG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)\n\nstruct vhsakmt_device;\nstruct vhsakmt_bo;\n\ntypedef struct vhsakmt_device* vhsakmt_device_handle;\ntypedef struct vhsakmt_bo* vhsakmt_bo_handle;\ntypedef rbtree_node_t* bo_entry;\n\nextern pthread_mutex_t dev_mutex;\nextern vhsakmt_device_handle dev_list;\n\n#define VHSA_BO_KFD_MEM 1 << 0 /* allocated from KFD (hsaKmtAllocMemory) */\n#define VHSA_BO_USERPTR 1 << 1\n#define VHSA_BO_QUEUE_BUFFER 1 << 2   /* allocated from KFD, but used for queue CMD submit */\n#define VHSA_BO_QUEUE_DOORBELL 1 << 3 /* doorbell memory */\n#define VHSA_BO_QUEUE_RW_PTR 1 << 4   /* queue read write ptr, from host map to guest*/\n/* allocated from KFD, but used for AQL queue read write ptr */\n#define VHSA_BO_QUEUE_AQL_RW_PTR 1 << 5\n#define VHSA_BO_CLGL 1 << 6 /* CLGL memory, imported from mesa GL */\n/* allocated from KFD, but is scratch memory, do not need map and unmap in ioctrl */\n#define VHSA_BO_SCRATCH 1 << 7\n#define VHSA_BO_QUEUE 1 << 8\n#define VHSA_BO_EVENT 1 << 9\n#define VHSA_BO_SCRATCH_MAP 1 << 10\n\n#define VHSA_SDMA_NONE UINT32_MAX\n\n#define CHECK_VIRTIO_KFD_OPEN()                                                                    \\\n  do {                                                                                             \\\n    if (dev_list == NULL) return HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED;                       \\\n  } while (0)\n\nstruct vhsakmt_node {\n  HsaNodeProperties node_props;\n  void* doorbell_base;\n  uint64_t scratch_start;\n  uint64_t scratch_size;\n};\n\nstruct vhsakmt_device {\n  struct virtio_gpu_device* vgdev;\n  int refcount;\n  pthread_mutex_t bo_handles_mutex;\n  rbtree_t bo_rbt;\n\n  struct vhsakmt_bo* shmem_bo;\n\n  uint32_t reqbuf_max;\n  uint32_t next_blob_id;\n\n  uint64_t vm_start;\n  uint64_t vm_size;\n\n  pthread_mutex_t vhsakmt_mutex;\n  struct vhsakmt_node* vhsakmt_nodes;\n  HsaSystemProperties* sys_props;\n};\n\nstruct vhsakmt_bo {\n  rbtree_node_t rbtn;\n  struct vhsakmt_device* dev;\n\n  int refcount;\n  unsigned size;\n  void* cpu_addr;\n  void* host_addr;\n  HsaMemFlags flags;\n  uint32_t bo_type;\n  uint32_t blob_id;\n  pthread_mutex_t map_mutex;\n\n  union {\n    struct {\n      uint32_t handle;\n      uint32_t res_id;\n      uint64_t offset;\n      uint64_t alloc_size;\n      int map_count;\n    } real;\n  };\n\n  vHsaEvent* event;\n  uint64_t queue_id;\n  vhsakmt_bo_handle rw_bo;\n  void* gl_meta_data;\n};\n\n/*hsakmt_virtio_memory.c*/\nvhsakmt_bo_handle vhsakmt_entry_to_bo_handle(bo_entry e);\nbo_entry vhsakmt_bo_handle_to_entry(vhsakmt_bo_handle bo);\n\nvoid vhsakmt_insert_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo, void* addr, uint64_t size);\nvoid vhsakmt_remove_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo);\nvhsakmt_bo_handle vhsakmt_find_bo_by_addr(vhsakmt_device_handle dev, void* addr);\nvoid* vhsakmt_gpu_va(vhsakmt_device_handle dev, void* va);\n\nint vhsakmt_bo_cpu_unmap(vhsakmt_bo_handle bo);\nint vhsakmt_bo_cpu_map(vhsakmt_bo_handle bo_handle, void** cpu, void* fixed_cpu);\nint vhsakmt_create_mappable_blob_bo(vhsakmt_device_handle dev, size_t size, uint32_t blob_id,\n                                    uint32_t bo_type, void* va_handle,\n                                    vhsakmt_bo_handle* bo_handle);\nint vhsakmt_bo_free(vhsakmt_device_handle dev, vhsakmt_bo_handle bo);\nint vhsakmt_init_host_blob(vhsakmt_device_handle dev, size_t size, uint32_t blob_type,\n                           uint32_t blob_flag, uint32_t blob_id, uint32_t bo_type, void* va_handle,\n                           vhsakmt_bo_handle* bo_handle);\n\n/*hsakmt_virtio_openclose.c*/\nvhsakmt_device_handle vhsakmt_dev(void);\n\n/*hsakmt_virtio_vm.c*/\nvoid* vhsakmt_vm_start(void);\nint vhsakmt_reserve_va(uint64_t start, uint64_t size);\nvoid vhsakmt_dereserve_va(uint64_t start, uint64_t size);\nvoid vhsakmt_set_scratch_area(vhsakmt_device_handle dev, uint32_t node, uint64_t start,\n                              uint64_t size);\nvoid vhsakmt_set_vm_area(vhsakmt_device_handle dev, uint64_t start, uint64_t size);\nint vhsakmt_set_node_doorbell(vhsakmt_device_handle dev, uint32_t node, void* doorbell);\nvoid* vhsakmt_node_doorbell(vhsakmt_device_handle dev, uint32_t node);\nbool vhsakmt_is_scratch_mem(vhsakmt_device_handle dev, void* addr);\nbool vhsakmt_is_userptr(vhsakmt_device_handle dev, void* addr);\n\n/*hsakmt_virtio_device.c*/\nint vhsakmt_execbuf_cpu(vhsakmt_device_handle dev, struct vhsakmt_ccmd_req* req, const char* from);\nvoid* vhsakmt_alloc_rsp(vhsakmt_device_handle dev, struct vhsakmt_ccmd_req* req, uint32_t sz);\n\n/*hsakmt_virtio_event.c*/\nvoid* vhsakmt_event_host_handle(HsaEvent* h);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_events.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\nint vhsakmt_debug_level;\n\nvoid* vhsakmt_event_host_handle(HsaEvent* h) { return (void*)((vHsaEvent*)h)->event_handle; }\n\nstatic inline int32_t vhsakmt_event_res_id(HsaEvent* h) { return ((vHsaEvent*)h)->res_id; }\n\nstatic inline vhsakmt_bo_handle vhsakmt_event_bo_handle(HsaEvent* h) {\n  return (vhsakmt_bo_handle)((vHsaEvent*)h)->bo_handle;\n}\n\nstatic int vhsakmt_create_event_blob_bo(vhsakmt_device_handle dev, size_t size, uint32_t blob_id,\n                                        vHsaEvent* vevent_handle, vhsakmt_bo_handle* bo_handle) {\n  int r;\n\n  r = vhsakmt_init_host_blob(dev, size, VIRTGPU_BLOB_MEM_HOST3D, 0, blob_id, VHSA_BO_EVENT,\n                             (void*)vevent_handle->event_handle, bo_handle);\n  if (r) return r;\n\n  (*bo_handle)->event = vevent_handle;\n  vevent_handle->bo_handle = (uint64_t)(*bo_handle);\n  vevent_handle->res_id = (*bo_handle)->real.res_id;\n  vhsakmt_insert_bo(dev, *bo_handle, vevent_handle, size);\n  return r;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateEvent(HsaEventDescriptor* EventDesc, _Bool ManualReset,\n                                           _Bool IsSignaled, HsaEvent** Event) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_event_rsp* rsp;\n  vhsakmt_bo_handle event_bo;\n  vHsaEvent* e;\n  int r;\n  struct vhsakmt_ccmd_event_req req = {\n      .hdr = VHSAKMT_CCMD(EVENT, sizeof(struct vhsakmt_ccmd_event_req)),\n      .type = VHSAKMT_CCMD_EVENT_CREATE,\n      .create_args.EventDesc = *EventDesc,\n      .create_args.ManualReset = ManualReset,\n      .create_args.IsSignaled = IsSignaled,\n      .blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id),\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_event_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (rsp->ret) return rsp->ret;\n\n  e = calloc(1, sizeof(vHsaEvent));\n  if (!e) return -ENOMEM;\n\n  memcpy(e, &rsp->vevent, sizeof(vHsaEvent));\n\n  r = vhsakmt_create_event_blob_bo(dev, sizeof(vHsaEvent), req.blob_id, e, &event_bo);\n  if (r) {\n    free(e);\n    return -ENOMEM;\n  }\n\n  *Event = (HsaEvent*)e;\n\n  vhsa_debug(\n      \"%s: event addr: %p, hw123: %lx, %lx, %x, type: %d, id: %x, host handle: 0x%lx, res id: %d\\n\",\n      __FUNCTION__, e, e->event.EventData.HWData1, e->event.EventData.HWData2,\n      e->event.EventData.HWData3, e->event.EventData.EventType, e->event.EventId, e->event_handle,\n      event_bo->real.res_id);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDestroyEvent(HsaEvent* Event) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_bo* bo;\n\n  if (Event == NULL) return HSAKMT_STATUS_SUCCESS;\n\n  bo = vhsakmt_event_bo_handle(Event);\n  if (!bo) return HSAKMT_STATUS_SUCCESS;\n\n  return vhsakmt_bo_free(dev, bo);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtSetEvent(HsaEvent* Event) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_event_rsp* rsp;\n  struct vhsakmt_ccmd_event_req req = {\n      .hdr = VHSAKMT_CCMD(EVENT, sizeof(struct vhsakmt_ccmd_event_req)),\n      .type = VHSAKMT_CCMD_EVENT_SET,\n      .event_hanele = vhsakmt_event_host_handle(Event),\n      .res_id = vhsakmt_event_res_id(Event),\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_event_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtResetEvent(HsaEvent* Event) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_event_rsp* rsp;\n  struct vhsakmt_ccmd_event_req req = {\n      .hdr = VHSAKMT_CCMD(EVENT, sizeof(struct vhsakmt_ccmd_event_req)),\n      .type = VHSAKMT_CCMD_EVENT_RESET,\n      .event_hanele = vhsakmt_event_host_handle(Event),\n      .res_id = vhsakmt_event_res_id(Event),\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_event_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtQueryEventState(HsaEvent* Event) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_event_rsp* rsp;\n  struct vhsakmt_ccmd_event_req req = {\n      .hdr = VHSAKMT_CCMD(EVENT, sizeof(struct vhsakmt_ccmd_event_req)),\n      .type = VHSAKMT_CCMD_EVENT_QUERY_STATE,\n      .event_hanele = vhsakmt_event_host_handle(Event),\n      .res_id = vhsakmt_event_res_id(Event),\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_event_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnMultipleEvents(HsaEvent* Events[], HSAuint32 NumEvents,\n                                                    bool WaitOnAll, HSAuint32 Milliseconds) {\n  return HSAKMT_STATUS_ERROR;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnEvent(HsaEvent* Event, HSAuint32 Milliseconds) {\n  return vhsaKmtWaitOnMultipleEvents(&Event, 1, true, Milliseconds);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnEvent_Ext(HsaEvent* Event, HSAuint32 Milliseconds,\n                                               uint64_t* event_age) {\n  return vhsaKmtWaitOnMultipleEvents(&Event, 1, true, Milliseconds);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtWaitOnMultipleEvents_Ext(HsaEvent* Events[], HSAuint32 NumEvents,\n                                                        bool WaitOnAll, HSAuint32 Milliseconds,\n                                                        uint64_t* event_age) {\n  return vhsaKmtWaitOnMultipleEvents(Events, NumEvents, WaitOnAll, Milliseconds);\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_memory.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\n#define VHSA_GL_METADATA_MAX_SIZE (0x50)\n\nvhsakmt_bo_handle vhsakmt_entry_to_bo_handle(bo_entry e) { return (vhsakmt_bo_handle)e; }\nbo_entry vhsakmt_bo_handle_to_entry(vhsakmt_bo_handle bo) { return &bo->rbtn; }\nstatic inline bool vhsakmt_is_mem_bo(vhsakmt_bo_handle bo) { return (!bo->queue_id && !bo->event); }\n\nstatic bool vhsakmt_mappable(HsaMemFlags flags) { return (!flags.ui32.Scratch); }\n\nstatic bool vhsakmt_bo_mappable(vhsakmt_bo_handle bo) { return vhsakmt_mappable(bo->flags); }\n\nvoid vhsakmt_insert_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo, void* addr, uint64_t size) {\n  bo->rbtn.key.addr = (unsigned long)addr;\n  bo->rbtn.key.size = (unsigned long)size;\n\n  pthread_mutex_lock(&dev->bo_handles_mutex);\n  hsakmt_rbtree_insert(&dev->bo_rbt, &bo->rbtn);\n  pthread_mutex_unlock(&dev->bo_handles_mutex);\n}\n\nstatic void vhsakmt_remove_entry(vhsakmt_device_handle dev, bo_entry entry) {\n  if (!entry) return;\n\n  pthread_mutex_lock(&dev->bo_handles_mutex);\n  hsakmt_rbtree_delete(&dev->bo_rbt, entry);\n  pthread_mutex_unlock(&dev->bo_handles_mutex);\n}\n\nvoid vhsakmt_remove_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo) {\n  bo_entry entry = vhsakmt_bo_handle_to_entry(bo);\n  if (entry->key.addr == 0 && entry->key.size == 0) return;\n\n  vhsakmt_remove_entry(dev, entry);\n}\n\nstatic bo_entry vhsakmt_rbt_search(vhsakmt_device_handle dev, void* addr) {\n  vhsakmt_bo_handle bo;\n\n  rbtree_key_t key = rbtree_key((uint64_t)addr, 0);\n  pthread_mutex_lock(&dev->bo_handles_mutex);\n  bo_entry n = rbtree_lookup_nearest(&dev->bo_rbt, &key, LKP_ADDR, RIGHT);\n  pthread_mutex_unlock(&dev->bo_handles_mutex);\n  if (n) {\n    bo = vhsakmt_entry_to_bo_handle(n);\n    if (bo->cpu_addr != addr) return NULL;\n    return n;\n  }\n\n  return NULL;\n}\n\nstatic bo_entry vhsakmt_find_entry_by_addr(vhsakmt_device_handle dev, void* addr) {\n  return vhsakmt_rbt_search(dev, addr);\n}\n\nvhsakmt_bo_handle vhsakmt_find_bo_by_addr(vhsakmt_device_handle dev, void* addr) {\n  bo_entry entry = vhsakmt_find_entry_by_addr(dev, addr);\n\n  if (entry) {\n    vhsakmt_bo_handle bo = vhsakmt_entry_to_bo_handle(entry);\n    if (!vhsakmt_is_mem_bo(bo)) return NULL;\n\n    return bo;\n  }\n\n  return NULL;\n}\n\nvoid* vhsakmt_gpu_va(vhsakmt_device_handle dev, void* va) {\n  if (!vhsakmt_is_userptr(dev, va)) return va;\n\n  bo_entry entry = vhsakmt_find_entry_by_addr(dev, va);\n\n  if (!entry) return NULL;\n\n  return vhsakmt_entry_to_bo_handle(entry)->host_addr;\n}\n\nint vhsakmt_bo_cpu_map(vhsakmt_bo_handle bo, void** cpu, void* fixed_cpu) {\n  int r;\n\n  if (!vhsakmt_bo_mappable(bo)) return 0;\n\n  pthread_mutex_lock(&bo->map_mutex);\n\n  if (!bo->cpu_addr) {\n    r = virtio_gpu_map_handle(bo->dev->vgdev, bo->real.handle, bo->size, cpu, fixed_cpu);\n    if (r) {\n      pthread_mutex_unlock(&bo->map_mutex);\n      return r;\n    }\n    bo->cpu_addr = *cpu;\n    atomic_fetch_add(&bo->real.map_count, 1);\n  }\n  pthread_mutex_unlock(&bo->map_mutex);\n\n  return *cpu == MAP_FAILED;\n}\n\nint vhsakmt_bo_cpu_unmap(vhsakmt_bo_handle bo) {\n  int r = 0;\n\n  if (!vhsakmt_bo_mappable(bo)) return 0;\n\n  pthread_mutex_lock(&bo->map_mutex);\n\n  if (!bo->cpu_addr || bo->real.map_count == 0) {\n    pthread_mutex_unlock(&bo->map_mutex);\n    return 0;\n  }\n\n  if (vhsakmt_atomic_dec_return(&bo->real.map_count) <= 0) {\n    if (bo->bo_type & VHSA_BO_KFD_MEM) {\n      virtio_gpu_unmap(bo->cpu_addr, bo->size);\n      vhsakmt_reserve_va(VHSA_VPTR_TO_UINT64(bo->cpu_addr), bo->size);\n      bo->cpu_addr = NULL;\n    }\n  }\n\n  pthread_mutex_unlock(&bo->map_mutex);\n  return r;\n}\n\nstatic int vhsakmt_destroy_handle(vhsakmt_device_handle dev, vhsakmt_bo_handle bo) {\n  int r = virtio_gpu_destroy_handle(dev->vgdev, bo->real.handle);\n  free(bo);\n\n  return r;\n}\n\nint vhsakmt_init_host_blob(vhsakmt_device_handle dev, size_t size, uint32_t blob_type,\n                           uint32_t blob_flag, uint32_t blob_id, uint32_t bo_type, void* va_handle,\n                           vhsakmt_bo_handle* bo_handle) {\n  int r;\n  vhsakmt_bo_handle bo;\n  struct drm_virtgpu_resource_create_blob args = {\n      .blob_mem = blob_type,\n      .size = size,\n      .blob_id = blob_id,\n      .blob_flags = blob_flag,\n  };\n\n  r = virtio_gpu_create_blob(dev->vgdev, &args);\n  if (r) return -EINVAL;\n\n  bo = calloc(1, sizeof(struct vhsakmt_bo));\n  if (!bo) {\n    virtio_gpu_destroy_handle(dev->vgdev, args.bo_handle);\n    return -ENOMEM;\n  }\n\n  bo->dev = dev;\n  bo->size = size;\n  bo->real.alloc_size = size;\n  bo->bo_type = bo_type;\n  bo->host_addr = va_handle;\n  pthread_mutex_init(&bo->map_mutex, NULL);\n  atomic_store(&bo->real.map_count, 0);\n  atomic_store(&bo->refcount, 1);\n  bo->real.handle = args.bo_handle;\n\n  virtio_gpu_res_id(dev->vgdev, bo->real.handle, &bo->real.res_id);\n\n  *bo_handle = bo;\n  return 0;\n}\n\nstatic int vhsakmt_init_userptr_blob(vhsakmt_device_handle dev, void* addr, size_t size,\n                                     vhsakmt_bo_handle* bo_handle, uint64_t* offset) {\n  int r;\n  struct drm_virtgpu_resource_create_blob args = {\n      .blob_mem = VIRTGPU_BLOB_MEM_HOST3D_GUEST,\n      .blob_flags = VIRTGPU_BLOB_FLAG_USE_USERPTR,\n      .size = size,\n      .blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id),\n      .blob_userptr = (uint64_t)addr,\n  };\n\n  r = virtio_gpu_create_blob(dev->vgdev, &args);\n  if (r < 0) return r;\n\n  vhsakmt_bo_handle userptr = calloc(1, sizeof(struct vhsakmt_bo));\n  if (!userptr) {\n    virtio_gpu_destroy_handle(dev->vgdev, args.bo_handle);\n    return -ENOMEM;\n  }\n\n  userptr->dev = dev;\n  userptr->size = size;\n  userptr->real.alloc_size = size;\n  userptr->bo_type = VHSA_BO_USERPTR;\n  userptr->cpu_addr = addr;\n  pthread_mutex_init(&userptr->map_mutex, NULL);\n  atomic_store(&userptr->real.map_count, 0);\n  atomic_store(&userptr->refcount, 1);\n  userptr->real.handle = args.bo_handle;\n\n  virtio_gpu_res_id(dev->vgdev, userptr->real.handle, &userptr->real.res_id);\n\n  *bo_handle = userptr;\n  *offset = args.offset;\n  return r;\n}\n\nint vhsakmt_create_mappable_blob_bo(vhsakmt_device_handle dev, size_t size, uint32_t blob_id,\n                                    uint32_t bo_type, void* va_handle,\n                                    vhsakmt_bo_handle* bo_handle) {\n  int r;\n\n  r = vhsakmt_init_host_blob(dev, size, VIRTGPU_BLOB_MEM_HOST3D, VIRTGPU_BLOB_FLAG_USE_MAPPABLE,\n                             blob_id, bo_type, va_handle, bo_handle);\n  if (r) return r;\n\n  r = vhsakmt_bo_cpu_map(*bo_handle, &((*bo_handle)->cpu_addr), va_handle);\n  if (r) {\n    free(*bo_handle);\n    *bo_handle = NULL;\n    return -EINVAL;\n  }\n\n  if (va_handle && (va_handle != (*bo_handle)->cpu_addr))\n    vhsa_warn(\"%s: target map: %p != real map: %p\\n\", __FUNCTION__, va_handle,\n              (*bo_handle)->cpu_addr);\n\n  vhsakmt_insert_bo(dev, *bo_handle, (*bo_handle)->cpu_addr, (*bo_handle)->size);\n  return r;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAllocMemory(HSAuint32 PreferredNode, HSAuint64 SizeInBytes,\n                                           HsaMemFlags MemFlags, void** MemoryAddress) {\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  vhsakmt_bo_handle bo;\n  int r;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_ALLOC,\n      .blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id),\n      .alloc_args =\n          {\n              .PreferredNode = PreferredNode,\n              .SizeInBytes = SizeInBytes,\n              .MemFlags = MemFlags,\n          },\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (rsp->ret) return rsp->ret;\n\n  if (!rsp->memory_handle) return -ENOMEM;\n\n  r = vhsakmt_init_host_blob(dev, SizeInBytes, VIRTGPU_BLOB_MEM_HOST3D,\n                             vhsakmt_mappable(MemFlags) ? VIRTGPU_BLOB_FLAG_USE_MAPPABLE : 0,\n                             req.blob_id, VHSA_BO_KFD_MEM, (void*)rsp->memory_handle, &bo);\n  if (r) return r;\n\n  if (!vhsakmt_mappable(MemFlags)) {\n    bo->cpu_addr = bo->host_addr;\n    if (MemFlags.ui32.Scratch) {\n      vhsakmt_set_scratch_area(dev, PreferredNode, (uint64_t)bo->cpu_addr, SizeInBytes);\n      bo->bo_type |= VHSA_BO_SCRATCH;\n    }\n  } else {\n    r = vhsakmt_bo_cpu_map(bo, &bo->cpu_addr, bo->host_addr);\n    if (r) {\n      free(bo);\n      return -ENOMEM;\n    }\n  }\n\n  if (!MemFlags.ui32.Scratch) vhsakmt_insert_bo(dev, bo, bo->cpu_addr, bo->size);\n\n  *MemoryAddress = bo->cpu_addr;\n\n  vhsa_debug(\"alloc mem addr: %p, host addr: %p, size: %lx, res-id: %d, handble: %d\\n\",\n             *MemoryAddress, bo->host_addr, SizeInBytes, bo->real.res_id, bo->real.handle);\n\n  return rsp->ret;\n}\n\nint vhsakmt_bo_free(vhsakmt_device_handle dev, vhsakmt_bo_handle bo) {\n  bo_entry entry;\n  int r;\n\n  if (vhsakmt_atomic_dec_return(&bo->refcount) > 0) return 0;\n\n  entry = vhsakmt_bo_handle_to_entry(bo);\n  if (entry->key.addr == 0 && entry->key.size == 0) return -EINVAL;\n\n  /* do not free BOs of queue, let them be freed with queue */\n  if (bo->bo_type & VHSA_BO_QUEUE_DOORBELL) {\n    vhsa_err(\"%s: Try to free VHSA_BO_QUEUE_DOORBELL memory: %p\\n\", __FUNCTION__, bo->cpu_addr);\n    return 0;\n  }\n\n  vhsakmt_remove_bo(dev, bo);\n\n  if (bo->cpu_addr) vhsakmt_bo_cpu_unmap(bo);\n\n  if (bo->event) free(bo->event);\n\n  if (bo->gl_meta_data) free(bo->gl_meta_data);\n\n  pthread_mutex_destroy(&bo->map_mutex);\n\n  r = vhsakmt_destroy_handle(dev, bo);\n\n  return r;\n}\n\n/* Only remove bo in rbtree */\nstatic void vhsakmt_remove_userptr_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo) {\n  vhsakmt_remove_bo(dev, bo);\n  free(bo);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtFreeMemory(void* MemoryAddress, HSAuint64 SizeInBytes) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  vhsakmt_bo_handle bo = vhsakmt_find_bo_by_addr(dev, MemoryAddress);\n  if (!bo) return HSAKMT_STATUS_SUCCESS;\n\n  vhsa_debug(\"%s: addr: %p, size: %lx, res_id: %d\\n\", __FUNCTION__, MemoryAddress, SizeInBytes,\n             bo->real.res_id);\n\n  return vhsakmt_bo_free(dev, bo);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtMapMemoryToGPUNodes(void* MemoryAddress, HSAuint64 MemorySizeInBytes,\n                                                   HSAuint64* AlternateVAGPU,\n                                                   HsaMemMapFlags MemMapFlags,\n                                                   HSAuint64 NumberOfNodes, HSAuint32* NodeArray) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  size_t req_len =\n      VHSA_ALIGN_UP(sizeof(struct vhsakmt_ccmd_memory_req) + NumberOfNodes * sizeof(*NodeArray), 8);\n  struct vhsakmt_ccmd_memory_req* req;\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  vhsakmt_bo_handle bo;\n\n  req = (void*)calloc(1, req_len);\n  if (!req) return -ENOMEM;\n  req->hdr = VHSAKMT_CCMD(MEMORY, req_len);\n  req->type = VHSAKMT_CCMD_MEMORY_MAP_TO_GPU_NODES;\n  req->map_to_GPU_nodes_args.MemorySizeInBytes = MemorySizeInBytes;\n  req->map_to_GPU_nodes_args.MemMapFlags = MemMapFlags;\n  req->map_to_GPU_nodes_args.NumberOfNodes = NumberOfNodes;\n\n  bo = vhsakmt_find_bo_by_addr(dev, MemoryAddress);\n  if (bo) {\n    req->map_to_GPU_nodes_args.MemoryAddress = (uint64_t)bo->host_addr;\n    if (bo->bo_type & VHSA_BO_USERPTR) vhsakmt_remove_userptr_bo(dev, bo);\n  } else\n    req->map_to_GPU_nodes_args.MemoryAddress = (uint64_t)MemoryAddress;\n\n  memcpy(req->payload, NodeArray, NumberOfNodes * sizeof(*NodeArray));\n\n  rsp = vhsakmt_alloc_rsp(dev, &req->hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) {\n    free(req);\n    return -ENOMEM;\n  }\n\n  vhsakmt_execbuf_cpu(dev, &req->hdr, __FUNCTION__);\n\n  *AlternateVAGPU = rsp->alternate_vagpu;\n\n  vhsa_debug(\"%s: gva: %p, hva: 0x%lx, size: %lx, AlternateVAGPU: %lx, ret: %d\\n\", __FUNCTION__,\n             MemoryAddress, req->map_to_GPU_nodes_args.MemoryAddress, MemorySizeInBytes,\n             *AlternateVAGPU, rsp->ret);\n\n  free(req);\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtUnmapMemoryToGPU(void* MemoryAddress) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  vhsakmt_bo_handle bo = vhsakmt_find_bo_by_addr(dev, MemoryAddress);\n  if (!bo) return HSAKMT_STATUS_SUCCESS;\n\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_UNMAP_TO_GPU,\n      .MemoryAddress = (uint64_t)bo->host_addr,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  vhsa_debug(\"%s: gva: %p, hva: 0x%lx\\n\", __FUNCTION__, MemoryAddress, req.MemoryAddress);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAvailableMemory(HSAuint32 Node, HSAuint64* AvailableBytes) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_AVAIL_MEM,\n      .Node = Node,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  *AvailableBytes = rsp->available_bytes;\n\n  return rsp->ret;\n}\n\nstatic int vhsakmt_create_scratch_map_memory(vhsakmt_device_handle dev, void* MemoryAddress,\n                                             HSAuint64 MemorySizeInBytes,\n                                             HSAuint64* AlternateVAGPU) {\n  vhsakmt_bo_handle out;\n  int r;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_MAP_MEM_TO_GPU,\n      .blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id),\n      .map_to_GPU_args =\n          {\n              .MemoryAddress = (uint64_t)MemoryAddress,\n              .MemorySizeInBytes = MemorySizeInBytes,\n              .need_create_bo = true,\n          },\n  };\n\n  struct vhsakmt_ccmd_memory_rsp* rsp =\n      vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  if (rsp->ret) return rsp->ret;\n\n  r = vhsakmt_init_host_blob(dev, MemorySizeInBytes, VIRTGPU_BLOB_MEM_HOST3D, 0, req.blob_id,\n                             VHSA_BO_SCRATCH_MAP, NULL, &out);\n  if (r) return r;\n\n  // TODO: insert scratch bo into rbtree, or insert it in dev nodes.\n\n  out->cpu_addr = MemoryAddress;\n  out->host_addr = (void*)rsp->memory_handle;\n  *AlternateVAGPU = rsp->alternate_vagpu;\n\n  vhsa_debug(\n      \"%s: create scratch memory, gva: %p, memory_handle: 0x%p, alternate_vagpu: %p, size: %lx\\n\",\n      __FUNCTION__, MemoryAddress, (void*)rsp->memory_handle, (void*)rsp->alternate_vagpu,\n      MemorySizeInBytes);\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtMapMemoryToGPU(void* MemoryAddress, HSAuint64 MemorySizeInBytes,\n                                              HSAuint64* AlternateVAGPU) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  vhsakmt_bo_handle bo = vhsakmt_find_bo_by_addr(dev, MemoryAddress);\n  if (!bo && vhsakmt_is_scratch_mem(dev, MemoryAddress))\n    return vhsakmt_create_scratch_map_memory(dev, MemoryAddress, MemorySizeInBytes, AlternateVAGPU);\n\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_MAP_MEM_TO_GPU,\n      .map_to_GPU_args =\n          {\n              .MemoryAddress = bo ? (uint64_t)bo->host_addr : (uint64_t)MemoryAddress,\n              .MemorySizeInBytes = MemorySizeInBytes,\n          },\n  };\n\n  if (bo && (bo->bo_type & VHSA_BO_USERPTR)) vhsakmt_remove_userptr_bo(dev, bo);\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  vhsa_debug(\"%s: gva: %p, hva: 0x%lx, size: %lx\\n\", __FUNCTION__, MemoryAddress, req.MemoryAddress,\n             MemorySizeInBytes);\n\n  *AlternateVAGPU = rsp->alternate_vagpu;\n\n  return rsp->ret;\n}\n\nstatic int vhsakmt_map_userptr(vhsakmt_device_handle dev, void* addr, size_t size, uint32_t res_id,\n                               uint64_t* userptr_handle) {\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_MAP_USERPTR,\n      .res_id = res_id,\n  };\n  struct vhsakmt_ccmd_memory_rsp* rsp =\n      vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  rsp->map_userptr_rsp.userptr_handle = 0;\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  *userptr_handle = rsp->map_userptr_rsp.userptr_handle;\n  return rsp->ret;\n}\n\nstatic void* vhsakmt_map_to_gpu(void* addr, size_t size) {\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  size_t offset = (uint64_t)addr % getpagesize();\n  size_t map_size = (VHSA_ALIGN_UP(size + offset, getpagesize()) / getpagesize()) * getpagesize();\n  uint64_t userptr_offset, userptr_handle = 0;\n  vhsakmt_bo_handle userptr;\n  int r;\n\n  vhsa_debug(\"%s: addr: %p, size: 0x%lx, size + offset: 0x%lx, map_size: 0x%lx\\n\", __FUNCTION__,\n             addr, size, size + offset, map_size);\n\n  r = vhsakmt_init_userptr_blob(dev, addr, size, &userptr, &userptr_offset);\n  if (r < 0) {\n    vhsa_debug(\"%s: userptr create failed at address: %p, ret = %d\\n\", __FUNCTION__, addr, r);\n    return NULL;\n  }\n\n  vhsakmt_map_userptr(dev, addr, size, userptr->real.res_id, &userptr_handle);\n  if (!userptr_handle) {\n    vhsa_debug(\"%s: map userptr failed at address: %p, ret = %d\\n\", __FUNCTION__, addr, r);\n    vhsakmt_destroy_handle(dev, userptr);\n    vhsakmt_remove_userptr_bo(dev, userptr);\n    return NULL;\n  }\n  userptr->host_addr = VHSA_UINT64_TO_VPTR(VHSA_VPTR_TO_UINT64(userptr_handle) + offset);\n\n  if (r > 0) {\n    vhsa_debug(\"%s: userptr: %p already registered, offset: %lx\\n\", __FUNCTION__, addr,\n               userptr_offset);\n    userptr->host_addr =\n        VHSA_UINT64_TO_VPTR(VHSA_VPTR_TO_UINT64(userptr->host_addr) + userptr_offset);\n  }\n  vhsakmt_insert_bo(dev, userptr, userptr->cpu_addr, userptr->size);\n\n  vhsa_debug(\"%s: real gva: %p, gva: %p, hva: %p, size: %lx, offset: %\" PRIu64\n             \", map_size: 0x%lx\\n\",\n             __FUNCTION__, addr, userptr->cpu_addr, userptr->host_addr, size, offset, map_size);\n  return userptr->host_addr;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRegisterMemoryWithFlags(void* MemoryAddress,\n                                                       HSAuint64 MemorySizeInBytes,\n                                                       HsaMemFlags MemFlags) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  void* addr;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_REG_MEM_WITH_FLAG,\n      .reg_mem_with_flag =\n          {\n              .MemorySizeInBytes = MemorySizeInBytes,\n              .MemFlags = MemFlags,\n          },\n  };\n\n  /* no need to register memory from lihsakmt / not a userptr */\n  if (!vhsakmt_is_userptr(dev, MemoryAddress)) return HSAKMT_STATUS_SUCCESS;\n\n  addr = vhsakmt_map_to_gpu(MemoryAddress, MemorySizeInBytes);\n  if (!addr) {\n    vhsa_debug(\"%s: register memory failed, gva: %p, size: %lx\\n\", __FUNCTION__, MemoryAddress,\n               MemorySizeInBytes);\n    return HSAKMT_STATUS_ERROR;\n  }\n\n  req.reg_mem_with_flag.MemoryAddress = (uint64_t)addr;\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  return rsp->ret;\n}\n\nstatic int vhsakmt_remove_clgl_bo(vhsakmt_device_handle dev, vhsakmt_bo_handle bo) {\n  struct vhsakmt_ccmd_memory_rsp* rsp;\n  struct vhsakmt_ccmd_memory_req req = {\n      .hdr = VHSAKMT_CCMD(MEMORY, sizeof(struct vhsakmt_ccmd_memory_req)),\n      .type = VHSAKMT_CCMD_MEMORY_DEREG_MEM,\n      .res_id = bo->real.res_id,\n      .MemoryAddress = (uint64_t)bo->cpu_addr,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_memory_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (rsp->ret) vhsa_err(\"%s: deregister failed clgl memory gva: %p\\n\", __FUNCTION__, bo->cpu_addr);\n\n  vhsakmt_bo_free(dev, bo);\n\n  vhsa_debug(\"%s: deregister clgl memory gva: %p, ret: %d\\n\", __FUNCTION__, bo->cpu_addr, rsp->ret);\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDeregisterMemory(void* MemoryAddress) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  vhsakmt_bo_handle bo = vhsakmt_find_bo_by_addr(dev, MemoryAddress);\n  if (!bo) return HSAKMT_STATUS_SUCCESS;\n\n  vhsa_debug(\"%s: remove userptr %p size: 0x%lx, res id: %d\\n\", __FUNCTION__, MemoryAddress,\n             (size_t)bo->size, bo->real.res_id);\n\n  if (bo->bo_type & VHSA_BO_CLGL)\n    return vhsakmt_remove_clgl_bo(dev, bo);\n  else {\n    vhsakmt_remove_bo(dev, bo);\n    free(bo);\n  }\n\n  return 0;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtQueryPointerInfo(const void* Pointer, HsaPointerInfo* PointerInfo) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  void* gpu_va = vhsakmt_gpu_va(dev, VHSA_UINT64_TO_VPTR(Pointer));\n  if (!gpu_va) return -HSAKMT_STATUS_ERROR;\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_POINTER_INFO,\n      .pointer = VHSA_VPTR_TO_UINT64(gpu_va),\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr,\n                          sizeof(struct vhsakmt_ccmd_query_info_rsp) +\n                              QUERY_PTR_INFO_MAX_MAPPED_NODES * sizeof(uint32_t));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(PointerInfo, &rsp->ptr_info, sizeof(HsaPointerInfo));\n\n  if (PointerInfo->NMappedNodes && PointerInfo->MappedNodes) {\n    if (PointerInfo->NMappedNodes > QUERY_PTR_INFO_MAX_MAPPED_NODES) {\n      PointerInfo->NMappedNodes = QUERY_PTR_INFO_MAX_MAPPED_NODES;\n      vhsa_debug(\n          \"%s: query pointer: %p info mapped nodes greater than QUERY_PTR_INFO_MAX_MAPPED_NODES\\n\",\n          __FUNCTION__, Pointer);\n    }\n\n    PointerInfo->MappedNodes = calloc(PointerInfo->NMappedNodes, sizeof(uint32_t));\n    if (!PointerInfo->MappedNodes) {\n      PointerInfo->NMappedNodes = 0;\n      return -HSAKMT_STATUS_NO_MEMORY;\n    }\n    memcpy(VHSA_UINT64_TO_VPTR(PointerInfo->MappedNodes), rsp->payload,\n           PointerInfo->NMappedNodes * sizeof(uint32_t));\n  }\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetTileConfig(HSAuint32 NodeId, HsaGpuTileConfig* config) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  uint8_t* config_cpy_addr = NULL;\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  unsigned req_len = sizeof(struct vhsakmt_ccmd_query_info_req);\n  unsigned rsp_len = sizeof(struct vhsakmt_ccmd_query_info_rsp) +\n      config->NumTileConfigs * sizeof(HSAuint32) + config->NumMacroTileConfigs * sizeof(HSAuint32);\n\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, req_len),\n      .type = VHSAKMT_CCMD_QUERY_TILE_CONFIG,\n      .tile_config_args.NodeId = NodeId,\n      .tile_config_args.config = *config,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, rsp_len);\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(config, &rsp->tile_config_rsp, sizeof(HsaGpuTileConfig));\n  config_cpy_addr = ((uint8_t*)rsp->payload);\n  memcpy(config->TileConfig, config_cpy_addr, config->NumTileConfigs * sizeof(HSAuint32));\n  config_cpy_addr += config->NumTileConfigs * sizeof(HSAuint32);\n  memcpy(config->MacroTileConfig, config_cpy_addr, config->NumMacroTileConfigs * sizeof(HSAuint32));\n\n  return rsp->ret;\n}\n\nstatic int vhsakmt_create_clgl_bo(vhsakmt_device_handle dev, void* addr, size_t size,\n                                  uint32_t res_id, uint32_t bo_handle, void* meta_data) {\n  vhsakmt_bo_handle out = calloc(1, sizeof(struct vhsakmt_bo));\n  if (!out) return -ENOMEM;\n\n  out->dev = dev;\n  out->size = size;\n  atomic_store(&out->real.map_count, 0);\n  atomic_store(&out->refcount, 1);\n\n#ifdef CLGL_EXPORT_RESID\n  out->real.res_id = GraphicsResourceHandle;\n#else\n  out->real.res_id = res_id;\n#endif\n\n  /* GL bo handle from GL context*/\n  out->real.handle = bo_handle;\n  out->bo_type |= VHSA_BO_CLGL;\n  if (meta_data) out->gl_meta_data = meta_data;\n\n  out->host_addr = addr;\n\n  vhsakmt_insert_bo(dev, out, addr, out->size);\n\n  return 0;\n}\n\nstatic int vhsakmt_gfxhandle_to_resid(vhsakmt_device_handle dev, uint32_t gfx_handle,\n                                      uint32_t* res_id, uint32_t* bo_handle) {\n  int r = drmPrimeFDToHandle(dev->vgdev->fd, gfx_handle, bo_handle);\n  if (r) {\n    vhsa_err(\"%s: drmPrimeFDToHandle failed for handle: %u\\n\", __FUNCTION__, gfx_handle);\n    return r;\n  }\n\n  virtio_gpu_res_id(dev->vgdev, *bo_handle, res_id);\n\n  vhsa_debug(\"%s: register praphics handle: handle: %d, bo_handle: %d, res_id: %d\\n\", __FUNCTION__,\n             gfx_handle, *bo_handle, *res_id);\n\n  return 0;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRegisterGraphicsHandleToNodes(\n    HSAuint64 GraphicsResourceHandle, HsaGraphicsResourceInfo* GraphicsResourceInfo,\n    HSAuint64 NumberOfNodes, HSAuint32* NodeArray) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  uint32_t bo_handle, res_id;\n  uint64_t meta_data_size = VHSA_GL_METADATA_MAX_SIZE;\n  unsigned req_len = sizeof(struct vhsakmt_ccmd_gl_inter_req) + NumberOfNodes * sizeof(NodeArray);\n  struct vhsakmt_ccmd_gl_inter_req* req;\n  struct vhsakmt_ccmd_gl_inter_rsp* rsp;\n  int r;\n\n  req = calloc(1, req_len);\n  if (!req) return -ENOMEM;\n\n  req->hdr = VHSAKMT_CCMD(GL_INTER, req_len);\n  req->type = VHSAKMT_CCMD_GL_REG_GHD_TO_NODES;\n  req->reg_ghd_to_nodes.NumberOfNodes = NumberOfNodes;\n  req->reg_ghd_to_nodes.res_handle = GraphicsResourceHandle;\n\n#ifdef CLGL_EXPORT_RESID\n  req->reg_ghd_to_nodes.GraphicsResourceHandle = GraphicsResourceHandle;\n#else\n  r = vhsakmt_gfxhandle_to_resid(dev, GraphicsResourceHandle, &res_id, &bo_handle);\n  if (r) return r;\n\n  req->reg_ghd_to_nodes.GraphicsResourceHandle = bo_handle;\n  req->reg_ghd_to_nodes.res_handle = res_id;\n#endif\n\n  memcpy(req->payload, NodeArray, NumberOfNodes * sizeof(NodeArray));\n\n  rsp =\n      vhsakmt_alloc_rsp(dev, &req->hdr, sizeof(struct vhsakmt_ccmd_gl_inter_rsp) + meta_data_size);\n  if (!rsp) {\n    r = -ENOMEM;\n    goto free_out;\n  }\n\n  vhsakmt_execbuf_cpu(dev, &req->hdr, __FUNCTION__);\n  if (rsp->ret) return rsp->ret;\n\n  memcpy(GraphicsResourceInfo, &rsp->info, sizeof(HsaGraphicsResourceInfo));\n  if (rsp->info.MetadataSizeInBytes) {\n    GraphicsResourceInfo->Metadata = calloc(1, GraphicsResourceInfo->MetadataSizeInBytes);\n    if (!GraphicsResourceInfo->Metadata) {\n      r = -ENOMEM;\n      goto free_out;\n    }\n\n    memcpy(VHSA_UINT64_TO_VPTR(GraphicsResourceInfo->Metadata), rsp->payload,\n           GraphicsResourceInfo->MetadataSizeInBytes);\n  } else\n    GraphicsResourceInfo->Metadata = NULL;\n\n  vhsa_debug(\"%s: register graphics handle: handle: %ld hva: %p, size: %lx\\n\", __FUNCTION__,\n             GraphicsResourceHandle, GraphicsResourceInfo->MemoryAddress,\n             GraphicsResourceInfo->SizeInBytes);\n\n  r = vhsakmt_create_clgl_bo(dev, GraphicsResourceInfo->MemoryAddress,\n                             GraphicsResourceInfo->SizeInBytes, res_id, bo_handle,\n                             VHSA_UINT64_TO_VPTR(GraphicsResourceInfo->Metadata));\n  if (r) goto free_out;\n\n  r = rsp->ret;\n\nfree_out:\n  /* close exported FD after register or close it when deregistre. Close after register here. */\n  close(GraphicsResourceHandle);\n  free(req);\n  return r;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_openclose.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\npthread_mutex_t dev_mutex = PTHREAD_MUTEX_INITIALIZER;\nvhsakmt_device_handle dev_list = NULL;\n\nvhsakmt_device_handle vhsakmt_dev(void) { return dev_list; }\n\nstatic HSAKMT_STATUS vhsakmt_openKFD_cmd(vhsakmt_device_handle dev) {\n  void* vm_start = vhsakmt_vm_start();\n  if (!vm_start) return -HSAKMT_STATUS_NO_MEMORY;\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_OPEN_KFD,\n      .open_kfd_args =\n          {\n              .cur_vm_start = VHSA_VPTR_TO_UINT64(vm_start),\n          },\n  };\n\n  if (!req.open_kfd_args.cur_vm_start) {\n    vhsa_err(\"%s: failed to get current heap start address\\n\", __FUNCTION__);\n    return -HSAKMT_STATUS_ERROR;\n  }\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -HSAKMT_STATUS_NO_MEMORY;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp->open_kfd_rsp.vm_start || !rsp->open_kfd_rsp.vm_size) {\n    vhsa_err(\"%s: failed to get KFD VM area\\n\", __FUNCTION__);\n    return -HSAKMT_STATUS_ERROR;\n  }\n\n  vhsakmt_set_vm_area(dev, rsp->open_kfd_rsp.vm_start, rsp->open_kfd_rsp.vm_size);\n  if (vhsakmt_reserve_va(dev->vm_start, dev->vm_size)) {\n    vhsa_err(\"%s: failed to reserve VM area: [%lx-%lx]-0x%lx\\n\", __FUNCTION__, dev->vm_start,\n             dev->vm_start + dev->vm_size, dev->vm_size);\n    return -HSAKMT_STATUS_NO_MEMORY;\n  }\n\n  vhsa_debug(\"%s: kfd vm range: [%lx-%lx]-0x%lx\\n\", __FUNCTION__, dev->vm_start,\n             dev->vm_start + dev->vm_size, dev->vm_size);\n  return rsp->ret;\n}\n\nstatic vhsakmt_device_handle vhsakmt_device_init(void) {\n  int fd;\n  vhsakmt_device_handle dev = NULL;\n\n  if (vhsakmt_dev()) return vhsakmt_dev();\n\n  pthread_mutex_lock(&dev_mutex);\n\n  fd = virtio_gpu_kfd_open();\n  if (fd < 0) goto open_failed;\n\n  dev = calloc(1, sizeof(struct vhsakmt_device));\n  if (!dev) goto open_failed;\n\n  dev->vgdev = virtio_gpu_init(fd, 0);\n  if (!dev->vgdev) goto malloc_failed;\n\n  rbtree_init(&dev->bo_rbt);\n  atomic_store(&dev->next_blob_id, 1);\n  atomic_store(&dev->refcount, 1);\n  pthread_mutex_init(&dev->bo_handles_mutex, NULL);\n  pthread_mutex_init(&dev->vhsakmt_mutex, NULL);\n  dev_list = dev;\n\n  pthread_mutex_unlock(&dev_mutex);\n  return dev;\n\nmalloc_failed:\n  free(dev);\n  dev = NULL;\nopen_failed:\n  pthread_mutex_unlock(&dev_mutex);\n  return dev;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtOpenKFD(void) {\n  vhsakmt_device_handle dev;\n  char* d = getenv(\"VHSAKMT_DEBUG_LEVEL\");\n  if (d) vhsakmt_debug_level = atoi(d);\n\n  dev = vhsakmt_device_init();\n  if (!dev) return HSAKMT_STATUS_ERROR;\n\n  return vhsakmt_openKFD_cmd(vhsakmt_dev());\n}\n\nstatic void vhsakmt_device_destroy(struct vhsakmt_device* dev) {\n  pthread_mutex_destroy(&dev->bo_handles_mutex);\n  vhsakmt_dereserve_va(dev->vm_start, dev->vm_size);\n\n  if (dev->sys_props) free(dev->sys_props);\n  if (dev->vhsakmt_nodes) free(dev->vhsakmt_nodes);\n\n  virtio_gpu_close(dev->vgdev);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCloseKFD(void) {\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  pthread_mutex_lock(&dev_mutex);\n  if (vhsakmt_atomic_dec_return(&dev->refcount) <= 0) vhsakmt_device_destroy(dev);\n  pthread_mutex_unlock(&dev_mutex);\n  return 0;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_proto.h",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef VHSAKMT_VIRTIO_PROTO_H\n#define VHSAKMT_VIRTIO_PROTO_H\n\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"hsakmt/hsakmt.h\"\n\n#include <drm/amdgpu_drm.h>\n#include <libdrm/amdgpu.h>\n#include <stdint.h>\n\n#include \"virtio_gpu.h\"\n\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic error \"-Wpadded\"\n#endif\n\n/* defined in other header file in virglrenderer */\n#define VHSAKMT_DEFINE_CAST(parent, child)                                                         \\\n  static inline struct child* to_##child(struct parent* x) { return (struct child*)x; }\n\n#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L\n#define VHSAKMT_STATIC_ASSERT_SIZE(t)                                                              \\\n  static_assert(sizeof(struct t) % 8 == 0, \"sizeof(struct \" #t \") not multiple of 8\");             \\\n  static_assert(_Alignof(struct t) <= 8, \"alignof(struct \" #t \") too large\");\n#else\n#define VHSAKMT_STATIC_ASSERT_SIZE(t)\n#endif\n\nenum vhsakmt_ccmd {\n  VHSAKMT_CCMD_NOP = 1, /* No payload, can be used to sync with host */\n  VHSAKMT_CCMD_QUERY_INFO,\n  VHSAKMT_CCMD_EVENT,\n  VHSAKMT_CCMD_MEMORY,\n  VHSAKMT_CCMD_QUEUE,\n  VHSAKMT_CCMD_GL_INTER,\n};\n\ntypedef struct _vHsaEvent {\n  HsaEvent event;\n  uint64_t event_handle;\n  uint64_t bo_handle;\n  uint32_t res_id;\n  uint32_t pad;\n} vHsaEvent;\nVHSAKMT_STATIC_ASSERT_SIZE(_vHsaEvent)\n\nstruct vhsakmt_event_shmem {\n  uint32_t trigered_events_num;\n  uint32_t pad;\n  HsaEvent trigered_events[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_event_shmem)\n\n#define VHSAKMT_CCMD(_cmd, _len)                                                                   \\\n  ((struct vhsakmt_ccmd_req){                                                                      \\\n      .cmd = VHSAKMT_CCMD_##_cmd,                                                                  \\\n      .len = (_len),                                                                               \\\n  })\n\nstruct vhsakmt_ccmd_nop_req {\n  struct vhsakmt_ccmd_req hdr;\n};\n\n/*\n * VHSAKMT_CCMD_QUERY\n */\nenum vhsakmt_ccmd_query_type {\n  VHSAKMT_CCMD_QUERY_GPU_INFO = 0,\n  VHSAKMT_CCMD_QUERY_OPEN_KFD,\n  VHSAKMT_CCMD_QUERY_GET_VER,\n  VHSAKMT_CCMD_QUERY_REL_SYS_PROP,\n  VHSAKMT_CCMD_QUERY_GET_SYS_PROP,\n  VHSAKMT_CCMD_QUERY_GET_NODE_PROP,\n  VHSAKMT_CCMD_QUERY_GET_XNACK_MODE,\n  VHSAKMT_CCMD_QUERY_RUN_TIME_ENABLE,\n  VHSAKMT_CCMD_QUERY_RUN_TIME_DISABLE,\n  VHSAKMT_CCMD_QUERY_GET_NOD_MEM_PROP,\n  VHSAKMT_CCMD_QUERY_GET_NOD_CACHE_PROP,\n  VHSAKMT_CCMD_QUERY_GET_NOD_IO_LINK_PROP,\n  VHSAKMT_CCMD_QUERY_GET_CLOCK_COUNTERS,\n  VHSAKMT_CCMD_QUERY_POINTER_INFO,\n  VHSAKMT_CCMD_QUERY_TILE_CONFIG,\n  VHSAKMT_CCMD_QUERY_NANO_TIME,\n  VHSAKMT_CCMD_QUERY_GET_RUNTIME_CAPS,\n};\n\n#define QUERY_PTR_INFO_MAX_MAPPED_NODES 3\n\ntypedef struct _query_req_run_time_enable_args {\n  /* void*     rDebug, bypassed by payload */\n  uint8_t pad[3];\n  uint8_t setupTtmp;\n  uint32_t __pad;\n} query_req_run_time_enable_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_req_run_time_enable_args)\n\ntypedef struct _query_req_node_mem_prop_args {\n  uint32_t NodeId;\n  uint32_t NumBanks;\n} query_req_node_mem_prop_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_req_node_mem_prop_args)\n\ntypedef struct _query_req_node_cache_prop_args {\n  uint32_t NodeId;\n  uint32_t ProcessorId;\n  uint32_t NumCaches;\n  uint32_t pad;\n} query_req_node_cache_prop_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_req_node_cache_prop_args)\n\ntypedef struct _query_req_node_io_link_args {\n  uint32_t NodeId;\n  uint32_t NumIoLinks;\n} query_req_node_io_link_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_req_node_io_link_args)\n\ntypedef struct _query_tile_config {\n  HsaGpuTileConfig config;\n  uint32_t NodeId;\n  uint32_t pad;\n} query_tile_config;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_tile_config)\n\ntypedef struct _query_open_kfd_args {\n  uint64_t cur_vm_start;\n} query_open_kfd_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_open_kfd_args)\n\ntypedef struct _query_open_kfd_rsp {\n  uint64_t vm_start;\n  uint64_t vm_size;\n} query_open_kfd_rsp;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_open_kfd_rsp)\n\ntypedef struct _query_nano_time_rsp {\n  uint64_t nano_time;\n} query_nano_time_rsp;\nVHSAKMT_STATIC_ASSERT_SIZE(_query_nano_time_rsp)\n\nstruct vhsakmt_ccmd_query_info_req {\n  struct vhsakmt_ccmd_req hdr;\n  struct drm_amdgpu_info info;\n  uint32_t type;\n  uint32_t pad;\n  union {\n    uint64_t pointer;\n    uint32_t NodeID; /* some query API just need node ID */\n    query_req_run_time_enable_args run_time_enable_args;\n    query_req_node_mem_prop_args node_mem_prop_args;\n    query_req_node_cache_prop_args node_cache_prop_args;\n    query_req_node_io_link_args node_io_link_args;\n    query_tile_config tile_config_args;\n    query_open_kfd_args open_kfd_args;\n  };\n\n  uint8_t payload[];\n};\nVHSAKMT_DEFINE_CAST(vhsakmt_ccmd_req, vhsakmt_ccmd_query_info_req)\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_query_info_req)\n#define VHSAKMT_CCMD_QUERY_MAX_TILE_CONFIG 128\n#define VHSAKMT_CCMD_QUERY_MAX_GET_NOD_MEM_PROP 128\n#define VHSAKMT_CCMD_QUERY_MAX_GET_NOD_CACHE_PROP 128\n#define VHSAKMT_CCMD_QUERY_MAX_GET_NOD_IO_LINK_PROP 128\n\nstruct vhsakmt_ccmd_query_info_rsp {\n  struct vhsakmt_ccmd_rsp hdr;\n  int32_t ret;\n  union {\n    query_open_kfd_rsp open_kfd_rsp;\n    query_nano_time_rsp nano_time_rsp;\n    HsaGpuTileConfig tile_config_rsp;\n    HsaPointerInfo ptr_info;\n    struct amdgpu_gpu_info gpu_info;\n    HsaVersionInfo kfd_version;\n    HsaSystemProperties sys_props;\n    HsaNodeProperties node_props;\n    int32_t xnack_mode;\n    HsaClockCounters clock_counters;\n    uint32_t caps;\n    uint64_t pad[9];\n  };\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_query_info_rsp)\n\n/*\n * VHSAKMT_CCMD_EVENT\n */\nenum vhsakmt_ccmd_event_type {\n  VHSAKMT_CCMD_EVENT_CREATE,\n  VHSAKMT_CCMD_EVENT_DESTROY,\n  VHSAKMT_CCMD_EVENT_SET,\n  VHSAKMT_CCMD_EVENT_RESET,\n  VHSAKMT_CCMD_EVENT_QUERY_STATE,\n  VHSAKMT_CCMD_EVENT_WAIT_ON_MULTI_EVENTS,\n\n  VHSAKMT_CCMD_EVENT_SET_TRAP,\n\n};\ntypedef struct _event_req_create_args {\n  HsaEventDescriptor EventDesc;\n  uint8_t ManualReset;\n  uint8_t IsSignaled;\n  uint8_t pad[6];\n} event_req_create_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_req_create_args)\n\ntypedef struct _event_req_wait_args {\n  HsaEvent Event;\n  uint32_t Milliseconds;\n  uint32_t pad;\n} event_req_wait_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_req_wait_args)\n\ntypedef struct _event_req_wait_ext_args {\n  HsaEvent Event;\n  uint64_t event_age;\n  uint32_t Milliseconds;\n  uint32_t pad;\n} event_req_wait_ext_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_req_wait_ext_args)\n\ntypedef struct _event_req_wait_on_multi_args {\n  /*HsaEvent*   Events[], in playloud*/\n  uint32_t NumEvents;\n  uint32_t Milliseconds;\n  uint8_t WaitOnAll;\n  uint8_t pad[7];\n} event_req_wait_on_multi_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_req_wait_on_multi_args)\n\ntypedef struct _event_req_wait_on_multi_ext_args {\n  /*HsaEvent*   Events[], in playloud*/\n  uint32_t NumEvents;\n  uint32_t Milliseconds;\n  uint64_t event_age;\n  uint8_t WaitOnAll;\n  uint8_t pad[7];\n} event_req_wait_on_multi_ext_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_req_wait_on_multi_ext_args)\n\ntypedef struct _event_set_trap_handler_args {\n  uint64_t TrapHandlerBaseAddress;\n  uint64_t TrapHandlerSizeInBytes;\n  uint64_t TrapBufferBaseAddress;\n  uint64_t TrapBufferSizeInBytes;\n  uint32_t NodeId;\n  uint32_t pad;\n} event_set_trap_handler_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_event_set_trap_handler_args)\n\nstruct vhsakmt_ccmd_event_req {\n  struct vhsakmt_ccmd_req hdr;\n  union {\n    HsaEvent Event; /* For set, reset, query. */\n    HsaEvent* event_hanele;\n    event_req_wait_args wait_args;\n    event_req_create_args create_args;\n    event_req_wait_ext_args wait_ext_args;\n    event_req_wait_on_multi_args wait_on_multi_args;\n    event_req_wait_on_multi_ext_args wait_on_multi_ext_args;\n    event_set_trap_handler_args set_trap_handler_args;\n  };\n  uint32_t type;\n  uint32_t sync_shmem_res_id;\n  uint64_t blob_id;\n  uint32_t res_id;\n  uint32_t pad;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_event_req)\nVHSAKMT_DEFINE_CAST(vhsakmt_ccmd_req, vhsakmt_ccmd_event_req)\n\nstruct vhsakmt_ccmd_event_rsp {\n  struct vhsakmt_ccmd_rsp hdr;\n  int32_t ret;\n  vHsaEvent vevent;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_event_rsp)\n\n/*\n * VHSAKMT_CCMD_MEMORY\n */\nenum vhsakmt_ccmd_memory_type {\n  VHSAKMT_CCMD_MEMORY_ALLOC,\n  VHSAKMT_CCMD_MEMORY_MAP_TO_GPU_NODES,\n  VHSAKMT_CCMD_MEMORY_FREE,\n  VHSAKMT_CCMD_MEMORY_UNMAP_TO_GPU,\n  VHSAKMT_CCMD_MEMORY_AVAIL_MEM,\n  VHSAKMT_CCMD_MEMORY_MAP_MEM_TO_GPU,\n  VHSAKMT_CCMD_MEMORY_REG_MEM_WITH_FLAG,\n  VHSAKMT_CCMD_MEMORY_DEREG_MEM,\n  VHSAKMT_CCMD_MEMORY_MAP_USERPTR,\n};\n\ntypedef struct _memory_req_alloc_args {\n  uint32_t PreferredNode;\n  HsaMemFlags MemFlags;\n  uint64_t SizeInBytes;\n  uint64_t MemoryAddress;\n} memory_req_alloc_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_memory_req_alloc_args)\n\ntypedef struct _memory_req_free_args {\n  uint64_t MemoryAddress;\n  uint64_t SizeInBytes;\n} memory_req_free_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_memory_req_free_args)\n\ntypedef struct _memory_req_map_to_GPU_nodes_args {\n  uint64_t MemoryAddress;\n  uint64_t MemorySizeInBytes;\n  uint64_t AlternateVAGPU;\n  HsaMemMapFlags MemMapFlags;\n  uint32_t pad;\n  uint64_t NumberOfNodes;\n  uint32_t* NodeArray;\n} memory_req_map_to_GPU_nodes_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_memory_req_map_to_GPU_nodes_args)\n\ntypedef struct _memory_map_mem_to_gpu_args {\n  uint64_t MemoryAddress;\n  uint64_t MemorySizeInBytes;\n  uint8_t need_create_bo;\n  uint8_t pad[7];\n} memory_map_mem_to_gpu_args;\nVHSAKMT_STATIC_ASSERT_SIZE(_memory_map_mem_to_gpu_args)\n\ntypedef struct _memory_reg_mem_with_flag {\n  uint64_t MemoryAddress;\n  uint64_t MemorySizeInBytes;\n  HsaMemFlags MemFlags;\n  uint32_t pad;\n} memory_reg_mem_with_flag;\nVHSAKMT_STATIC_ASSERT_SIZE(_memory_reg_mem_with_flag)\n\nstruct vhsakmt_ccmd_memory_req {\n  struct vhsakmt_ccmd_req hdr;\n  union {\n    uint64_t MemoryAddress;\n    uint32_t Node;\n    memory_req_alloc_args alloc_args;\n    memory_req_map_to_GPU_nodes_args map_to_GPU_nodes_args;\n    memory_req_free_args free_args;\n    memory_map_mem_to_gpu_args map_to_GPU_args;\n    memory_reg_mem_with_flag reg_mem_with_flag;\n  };\n  uint64_t blob_id;\n  uint32_t type;\n  uint32_t res_id;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_memory_req)\nVHSAKMT_DEFINE_CAST(vhsakmt_ccmd_req, vhsakmt_ccmd_memory_req)\n\ntypedef struct _vhsakmt_ccmd_memory_map_userptr_rsp {\n  uint64_t userptr_handle;\n  uint32_t npfns;\n  uint32_t pad;\n} vhsakmt_ccmd_memory_map_userptr_rsp;\nVHSAKMT_STATIC_ASSERT_SIZE(_vhsakmt_ccmd_memory_map_userptr_rsp)\n\nstruct vhsakmt_ccmd_memory_rsp {\n  struct vhsakmt_ccmd_rsp hdr;\n  int32_t ret;\n  union {\n    vhsakmt_ccmd_memory_map_userptr_rsp map_userptr_rsp;\n    uint64_t memory_handle;\n    uint64_t alternate_vagpu;\n    uint64_t available_bytes;\n  };\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_memory_rsp)\n\n/*\n * VHSAKMT_CCMD_QUEUE\n */\nenum vhsakmt_ccmd_queue_type {\n  VHSAKMT_CCMD_QUEUE_CREATE,\n  VHSAKMT_CCMD_QUEUE_DESTROY,\n};\n\ntypedef struct _vHsaQueueResource {\n  HsaQueueResource r;\n  uint64_t host_doorbell;\n  uint64_t host_doorbell_offset;\n  uint64_t host_write_offset;\n  uint64_t host_read_offset;\n  uint64_t host_rw_handle;\n  uint64_t queue_handle;\n} vHsaQueueResource;\nVHSAKMT_STATIC_ASSERT_SIZE(_vHsaQueueResource)\n\ntypedef struct _queue_req_create {\n  uint32_t NodeId;\n  HSA_QUEUE_TYPE Type;\n  uint32_t QueuePercentage;\n  uint32_t pad;\n  HSA_QUEUE_PRIORITY Priority;\n  uint32_t pad1;\n  uint32_t SdmaEngineId;\n  uint64_t QueueAddress;\n  uint64_t QueueSizeInBytes;\n  HsaEvent* Event;\n  HsaQueueResource* QueueResource;\n  uint64_t* Queue_write_ptr_aql;\n  uint64_t* Queue_read_ptr_aql;\n} queue_req_create;\nVHSAKMT_STATIC_ASSERT_SIZE(_queue_req_create)\n\nstruct vhsakmt_ccmd_queue_req {\n  struct vhsakmt_ccmd_req hdr;\n  union {\n    HSA_QUEUEID QueueId;\n    queue_req_create create_queue_args;\n  };\n  uint64_t blob_id;          /* For queue create, queue resource */\n  uint64_t rw_ptr_blob_id;   /* For queue create, r/w ptr memory mapping */\n  uint64_t doorbell_blob_id; /* For queue create, doorbell ptr memory mapping */\n  uint32_t res_id;\n  uint32_t type;\n  uint32_t queue_mem_res_id;\n  uint32_t pad;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_queue_req)\nVHSAKMT_DEFINE_CAST(vhsakmt_ccmd_req, vhsakmt_ccmd_queue_req)\n\nstruct vhsakmt_ccmd_queue_rsp {\n  struct vhsakmt_ccmd_rsp hdr;\n  int32_t ret;\n  vHsaQueueResource vqueue_res;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_queue_rsp)\n\n/*\n * VHSAKMT_CCMD_GL_INTER\n */\nenum vhsakmt_ccmd_gl_inter_type {\n  VHSAKMT_CCMD_GL_REG_GHD_TO_NODES,\n};\n\ntypedef struct _gl_inter_req_reg_ghd_to_nodes {\n  uint64_t GraphicsResourceHandle;\n  uint64_t NumberOfNodes;  // NodeArray in payload\n  uint32_t res_handle;\n  uint32_t pad;\n} gl_inter_req_reg_ghd_to_nodes;\nVHSAKMT_STATIC_ASSERT_SIZE(_gl_inter_req_reg_ghd_to_nodes)\n\nstruct vhsakmt_ccmd_gl_inter_req {\n  struct vhsakmt_ccmd_req hdr;\n  union {\n    gl_inter_req_reg_ghd_to_nodes reg_ghd_to_nodes;\n  };\n  uint32_t type;\n  uint32_t pad;\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_gl_inter_req)\nVHSAKMT_DEFINE_CAST(vhsakmt_ccmd_req, vhsakmt_ccmd_gl_inter_req)\n\nstruct vhsakmt_ccmd_gl_inter_rsp {\n  struct vhsakmt_ccmd_rsp hdr;\n  int32_t ret;\n  union {\n    HsaGraphicsResourceInfo info;\n  };\n  uint8_t payload[];\n};\nVHSAKMT_STATIC_ASSERT_SIZE(vhsakmt_ccmd_gl_inter_rsp)\n\n#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif\n\n#endif\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_queues.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\nstatic inline uint64_t vhsakmt_doorbell_page_size(void) { return 0x2000; }\nstatic inline uint64_t vhsakmt_queue_page_size(void) { return getpagesize(); }\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtSetTrapHandler(HSAuint32 NodeId, void* TrapHandlerBaseAddress,\n                                              HSAuint64 TrapHandlerSizeInBytes,\n                                              void* TrapBufferBaseAddress,\n                                              HSAuint64 TrapBufferSizeInBytes) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_event_rsp* rsp;\n  struct vhsakmt_ccmd_event_req req = {\n      .hdr = VHSAKMT_CCMD(EVENT, sizeof(struct vhsakmt_ccmd_event_req)),\n      .type = VHSAKMT_CCMD_EVENT_SET_TRAP,\n      .set_trap_handler_args =\n          {\n              .NodeId = NodeId,\n              .TrapHandlerBaseAddress = (uint64_t)TrapHandlerBaseAddress,\n              .TrapHandlerSizeInBytes = TrapHandlerSizeInBytes,\n              .TrapBufferBaseAddress = (uint64_t)TrapBufferBaseAddress,\n              .TrapBufferSizeInBytes = TrapBufferSizeInBytes,\n          },\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_event_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  return rsp->ret;\n}\n\nstatic int vhsakmt_find_aql_rw_bo(vhsakmt_device_handle dev, uint64_t aql_ptr,\n                                  uint32_t* aql_bo_res_id) {\n  uint64_t aql_base_ptr = VHSA_ALIGN_DOWN(aql_ptr, getpagesize());\n\n  vhsakmt_bo_handle bo = vhsakmt_find_bo_by_addr(dev, (void*)aql_base_ptr);\n  if (!bo) return -EINVAL;\n\n  bo->bo_type |= VHSA_BO_QUEUE_AQL_RW_PTR;\n  *aql_bo_res_id = bo->real.res_id;\n  return 0;\n}\n\nstatic int vhsakmt_create_doorbell_blob_bo(vhsakmt_device_handle dev, uint32_t node, size_t size,\n                                           uint32_t blob_id, uint64_t host_handle,\n                                           vhsakmt_bo_handle* bo_handle) {\n  int r;\n\n  r = vhsakmt_create_mappable_blob_bo(dev, size, blob_id, VHSA_BO_QUEUE_DOORBELL,\n                                      (void*)host_handle, bo_handle);\n  if (r) return r;\n\n  r = vhsakmt_set_node_doorbell(dev, node, (*bo_handle)->cpu_addr);\n\n  return r;\n}\n\nstatic int vhsakmt_create_queue_rw_blob_bo(vhsakmt_device_handle dev, size_t size, uint32_t blob_id,\n                                           uint64_t host_handle, vhsakmt_bo_handle* bo_handle) {\n  int r;\n\n  r = vhsakmt_create_mappable_blob_bo(dev, size, blob_id, VHSA_BO_QUEUE_RW_PTR, NULL, bo_handle);\n  if (r) return r;\n\n  (*bo_handle)->host_addr = (void*)host_handle;\n  return r;\n}\n\nstatic int vhsakmt_create_queue_blob_bo(vhsakmt_device_handle dev, size_t size, uint32_t blob_id,\n                                        uint64_t queue_id, vhsakmt_bo_handle rw_bo_handle,\n                                        vhsakmt_bo_handle* bo_handle) {\n  int r;\n\n  r = vhsakmt_init_host_blob(dev, size, VIRTGPU_BLOB_MEM_HOST3D, 0, blob_id, VHSA_BO_QUEUE, NULL,\n                             bo_handle);\n  if (r) return r;\n\n  vhsakmt_insert_bo(dev, *bo_handle, *bo_handle, (*bo_handle)->size);\n\n  (*bo_handle)->queue_id = queue_id;\n  (*bo_handle)->rw_bo = rw_bo_handle;\n\n  return r;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateQueueExt(HSAuint32 NodeId, HSA_QUEUE_TYPE Type,\n                                              HSAuint32 QueuePercentage,\n                                              HSA_QUEUE_PRIORITY Priority, HSAuint32 SdmaEngineId,\n                                              void* QueueAddress, HSAuint64 QueueSizeInBytes,\n                                              HsaEvent* Event, HsaQueueResource* QueueResource) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  vhsakmt_bo_handle rw_bo_handle = NULL, doorbell_bo, queue_bo, queue_mem_bo;\n  struct vhsakmt_ccmd_queue_rsp* rsp;\n  struct vhsakmt_ccmd_queue_req req = {\n      .hdr = VHSAKMT_CCMD(QUEUE, sizeof(struct vhsakmt_ccmd_queue_req)),\n      .type = VHSAKMT_CCMD_QUEUE_CREATE,\n      .create_queue_args =\n          {\n              .NodeId = NodeId,\n              .Type = Type,\n              .QueuePercentage = QueuePercentage,\n              .Priority = Priority,\n              .SdmaEngineId = SdmaEngineId,\n              .QueueAddress = (uint64_t)QueueAddress,\n              .QueueSizeInBytes = QueueSizeInBytes,\n              .Event = Event ? vhsakmt_event_host_handle(Event) : 0,\n              .Queue_write_ptr_aql = QueueResource->Queue_write_ptr_aql,\n              .Queue_read_ptr_aql = QueueResource->Queue_read_ptr_aql,\n          },\n      .blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id), /* For queue resource */\n      .doorbell_blob_id = vhsakmt_node_doorbell(dev, NodeId)\n          ? 0\n          : vhsakmt_atomic_inc_return(&dev->next_blob_id), /* For queue doorbell memory map */\n  };\n  int r;\n\n  /* Queue ptr memory is allocated by hsakmtallocmemory in host then mapped into guest, but their\n   * address are not aligned. */\n  if (Type == HSA_QUEUE_COMPUTE_AQL) {\n    r = vhsakmt_find_aql_rw_bo(dev, QueueResource->QueueWptrValue, &req.res_id);\n    if (r) {\n      vhsa_debug(\"%s: can not find the AQL queue R/W BO: %p\\n\", __FUNCTION__,\n                 QueueResource->Queue_write_ptr_aql);\n      return HSAKMT_STATUS_NO_MEMORY;\n    }\n\n    vhsa_debug(\"%s: create AQL queue, read ptr: %p, write ptr: %p, res id: %d\\n\", __FUNCTION__,\n               QueueResource->Queue_read_ptr_aql, QueueResource->Queue_write_ptr_aql, req.res_id);\n  } else\n    /* For queue not CP AQL, it use r/w ptr by itself. */\n    req.rw_ptr_blob_id = vhsakmt_atomic_inc_return(&dev->next_blob_id);\n\n  queue_mem_bo = vhsakmt_find_bo_by_addr(dev, QueueAddress);\n  if (!queue_mem_bo) {\n    vhsa_err(\"%s: can not find the queue memory BO: %p\\n\", __FUNCTION__, QueueAddress);\n    return HSAKMT_STATUS_NO_MEMORY;\n  }\n  queue_mem_bo->bo_type |= VHSA_BO_QUEUE_AQL_RW_PTR;\n  req.queue_mem_res_id = queue_mem_bo->real.res_id;\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_queue_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (rsp->ret) {\n    vhsa_err(\"%s: queue create failed, ret: %d\", __FUNCTION__, rsp->ret);\n    return rsp->ret;\n  }\n\n  /* Map doorbell */\n  if (req.doorbell_blob_id) {\n    r = vhsakmt_create_doorbell_blob_bo(\n        dev, NodeId, vhsakmt_doorbell_page_size(), req.doorbell_blob_id,\n        rsp->vqueue_res.host_doorbell - rsp->vqueue_res.host_doorbell_offset, &doorbell_bo);\n    if (r) {\n      vhsa_err(\"%s: doorbell create failed, doorbell: %lx\\n\", __FUNCTION__,\n               rsp->vqueue_res.host_doorbell);\n      return r;\n    }\n    vhsa_debug(\"%s: create doorbell: %p, size: 0x%x\\n\", __FUNCTION__, doorbell_bo->cpu_addr,\n               doorbell_bo->size);\n  }\n\n  QueueResource->Queue_DoorBell_aql = (void*)rsp->vqueue_res.host_doorbell;\n  vhsa_debug(\"%s: queue create, Doorbell: %p\\n\", __FUNCTION__, QueueResource->Queue_DoorBell_aql);\n\n  /* Map R/W pointer.\n   * For a queue is not a COMPUTE AQL, the R/W PTR not using the input address,\n   * uses the queue memory allocated by hsakmtallocmemory, a page align address.\n   */\n  if (Type != HSA_QUEUE_COMPUTE_AQL) {\n    r = vhsakmt_create_queue_rw_blob_bo(dev, vhsakmt_queue_page_size(), req.rw_ptr_blob_id,\n                                        rsp->vqueue_res.host_rw_handle, &rw_bo_handle);\n    if (r) {\n      vhsa_debug(\"%s: queue rw ptr create failed, host addr: %p\\n\", __FUNCTION__,\n                 (void*)rsp->vqueue_res.host_rw_handle);\n      return r;\n    }\n\n    QueueResource->Queue_write_ptr_aql = VHSA_UINT64_TO_VPTR(\n        VHSA_VPTR_TO_UINT64(rw_bo_handle->cpu_addr) + rsp->vqueue_res.host_write_offset);\n    QueueResource->Queue_read_ptr_aql = VHSA_UINT64_TO_VPTR(\n        VHSA_VPTR_TO_UINT64(rw_bo_handle->cpu_addr) + rsp->vqueue_res.host_read_offset);\n\n    vhsa_debug(\"%s: queue create: write ptr gva: %p, read ptr gva: %p, base hva: %lx\\n\",\n               __FUNCTION__, QueueResource->Queue_write_ptr_aql, QueueResource->Queue_read_ptr_aql,\n               rsp->vqueue_res.host_rw_handle);\n  }\n\n  r = vhsakmt_create_queue_blob_bo(dev, QueueSizeInBytes, req.blob_id, rsp->vqueue_res.r.QueueId,\n                                   rw_bo_handle, &queue_bo);\n  if (r) {\n    vhsa_err(\"%s: queue create failed, queue ID: 0x%lx\\n\", __FUNCTION__, rsp->vqueue_res.r.QueueId);\n    return r;\n  }\n  QueueResource->QueueId = (uint64_t)queue_bo;\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtCreateQueue(HSAuint32 NodeId, HSA_QUEUE_TYPE Type,\n                                           HSAuint32 QueuePercentage, HSA_QUEUE_PRIORITY Priority,\n                                           void* QueueAddress, HSAuint64 QueueSizeInBytes,\n                                           HsaEvent* Event, HsaQueueResource* QueueResource) {\n  return vhsaKmtCreateQueueExt(NodeId, Type, QueuePercentage, Priority, VHSA_SDMA_NONE,\n                               QueueAddress, QueueSizeInBytes, Event, QueueResource);\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtDestroyQueue(HSA_QUEUEID QueueId) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  int r;\n\n  /* queue ID: vhsakmt_bo_handle -> real queue ID*/\n  vhsakmt_bo_handle bo = (vhsakmt_bo_handle)QueueId;\n  vhsakmt_bo_handle rw_bo = bo->rw_bo;\n\n  r = vhsakmt_bo_free(dev, bo);\n  if (rw_bo) vhsakmt_bo_free(dev, rw_bo);\n\n  vhsa_debug(\"%s: queue res id: %d, queue ID: %\" PRIu64 \", ret = %d\\n\", __FUNCTION__,\n             bo->real.res_id, bo->queue_id, r);\n\n  return r;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_topology.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include \"hsakmt/hsakmt_virtio.h\"\n#include \"hsakmt_virtio_device.h\"\n\nstatic int vhsakmt_set_sys_props(vhsakmt_device_handle dev, HsaSystemProperties* sys_props) {\n  int r = 0;\n\n  pthread_mutex_lock(&dev->vhsakmt_mutex);\n  if (dev->sys_props) {\n    r = 0;\n    goto out;\n  }\n\n  dev->sys_props = calloc(1, sizeof(HsaSystemProperties));\n  if (!dev->sys_props) {\n    r = -ENOMEM;\n    goto out;\n  }\n\n  memcpy(dev->sys_props, sys_props, sizeof(HsaSystemProperties));\n\nout:\n  pthread_mutex_unlock(&dev->vhsakmt_mutex);\n  return r;\n}\n\nstatic int vhsakmt_set_node_props(vhsakmt_device_handle dev, uint32_t node,\n                                  HsaNodeProperties* node_props) {\n  int r = 0;\n  if (!dev->sys_props) return -EINVAL;\n  if (node >= dev->sys_props->NumNodes) return -EINVAL;\n\n  pthread_mutex_lock(&dev->vhsakmt_mutex);\n\n  if (!dev->vhsakmt_nodes) {\n    dev->vhsakmt_nodes = calloc(dev->sys_props->NumNodes, sizeof(struct vhsakmt_node));\n    if (!dev->vhsakmt_nodes) {\n      r = -ENOMEM;\n      goto out;\n    }\n  }\n\n  memcpy(&dev->vhsakmt_nodes[node].node_props, node_props, sizeof(HsaNodeProperties));\n\nout:\n  pthread_mutex_unlock(&dev->vhsakmt_mutex);\n  return r;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetVersion(HsaVersionInfo* v) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_VER,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  memcpy(v, &rsp->kfd_version, sizeof(HsaVersionInfo));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtAcquireSystemProperties(HsaSystemProperties* SystemProperties) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  int r;\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_SYS_PROP,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  memcpy(SystemProperties, &rsp->sys_props, sizeof(HsaSystemProperties));\n\n  r = vhsakmt_set_sys_props(dev, SystemProperties);\n  if (r) return r;\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtReleaseSystemProperties(void) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_REL_SYS_PROP,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  if (dev->sys_props) {\n    free(dev->sys_props);\n    dev->sys_props = NULL;\n  }\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeProperties(HSAuint32 NodeId,\n                                                 HsaNodeProperties* NodeProperties) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  int r;\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .NodeID = NodeId,\n      .type = VHSAKMT_CCMD_QUERY_GET_NODE_PROP,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  memcpy(NodeProperties, &rsp->node_props, sizeof(HsaNodeProperties));\n\n  r = vhsakmt_set_node_props(dev, NodeId, NodeProperties);\n  if (r) return r;\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetXNACKMode(HSAint32* enable) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_XNACK_MODE,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  memcpy(enable, &rsp->xnack_mode, sizeof(HSAint32));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRuntimeEnable(void* rDebug, bool setupTtmp) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .run_time_enable_args.setupTtmp = setupTtmp,\n      .type = VHSAKMT_CCMD_QUERY_RUN_TIME_ENABLE,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtRuntimeDisable(void) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_RUN_TIME_DISABLE,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n  if (!rsp) return -ENOMEM;\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeMemoryProperties(HSAuint32 NodeId, HSAuint32 NumBanks,\n                                                       HsaMemoryProperties* MemoryProperties) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_NOD_MEM_PROP,\n      .node_mem_prop_args.NodeId = NodeId,\n      .node_mem_prop_args.NumBanks = NumBanks,\n  };\n\n  rsp = vhsakmt_alloc_rsp(\n      dev, &req.hdr,\n      sizeof(struct vhsakmt_ccmd_query_info_rsp) + NumBanks * sizeof(HsaMemoryProperties));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(MemoryProperties, rsp->payload, NumBanks * sizeof(HsaMemoryProperties));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeCacheProperties(HSAuint32 NodeId, HSAuint32 ProcessorId,\n                                                      HSAuint32 NumCaches,\n                                                      HsaCacheProperties* CacheProperties) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_NOD_CACHE_PROP,\n      .node_cache_prop_args.NodeId = NodeId,\n      .node_cache_prop_args.ProcessorId = ProcessorId,\n      .node_cache_prop_args.NumCaches = NumCaches,\n  };\n\n  rsp = vhsakmt_alloc_rsp(\n      dev, &req.hdr,\n      sizeof(struct vhsakmt_ccmd_query_info_rsp) + NumCaches * sizeof(HsaCacheProperties));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(CacheProperties, rsp->payload, NumCaches * sizeof(HsaCacheProperties));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetNodeIoLinkProperties(HSAuint32 NodeId, HSAuint32 NumIoLinks,\n                                                       HsaIoLinkProperties* IoLinkProperties) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_NOD_IO_LINK_PROP,\n      .node_io_link_args.NodeId = NodeId,\n      .node_io_link_args.NumIoLinks = NumIoLinks,\n  };\n\n  rsp = vhsakmt_alloc_rsp(\n      dev, &req.hdr,\n      sizeof(struct vhsakmt_ccmd_query_info_rsp) + NumIoLinks * sizeof(HsaIoLinkProperties));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(IoLinkProperties, rsp->payload, NumIoLinks * sizeof(HsaIoLinkProperties));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetClockCounters(HSAuint32 NodeId, HsaClockCounters* Counters) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_CLOCK_COUNTERS,\n      .NodeID = NodeId,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  memcpy(Counters, &rsp->clock_counters, sizeof(HsaClockCounters));\n\n  return rsp->ret;\n}\n\nHSAKMT_STATUS HSAKMTAPI vhsaKmtGetRuntimeCapabilities(HSAuint32* caps_mask) {\n  CHECK_VIRTIO_KFD_OPEN();\n\n  vhsakmt_device_handle dev = vhsakmt_dev();\n  struct vhsakmt_ccmd_query_info_rsp* rsp;\n  struct vhsakmt_ccmd_query_info_req req = {\n      .hdr = VHSAKMT_CCMD(QUERY_INFO, sizeof(struct vhsakmt_ccmd_query_info_req)),\n      .type = VHSAKMT_CCMD_QUERY_GET_RUNTIME_CAPS,\n  };\n\n  rsp = vhsakmt_alloc_rsp(dev, &req.hdr, sizeof(struct vhsakmt_ccmd_query_info_rsp));\n  if (!rsp) return -ENOMEM;\n\n  vhsakmt_execbuf_cpu(dev, &req.hdr, __FUNCTION__);\n\n  *caps_mask = rsp->caps;\n\n  return rsp->ret;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/hsakmt_virtio_vm.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include <sys/mman.h>\n#include <unistd.h>\n\n#include \"hsakmt_virtio_device.h\"\n\nvoid* vhsakmt_vm_start(void) {\n  void* vm_start = malloc(getpagesize());\n  if (!vm_start) return NULL;\n\n  free(vm_start);\n  return vm_start;\n}\n\nint vhsakmt_reserve_va(uint64_t start, uint64_t size) {\n  int32_t protFlags = PROT_NONE;\n  int32_t mapFlags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;\n  void* va = mmap((void*)start, size, protFlags, mapFlags, -1, 0);\n  if (va == MAP_FAILED) return -ENOMEM;\n\n  if (va != (void*)start) return -ENOMEM;\n\n  madvise(va, size, MADV_DONTFORK);\n\n  return 0;\n}\n\nvoid vhsakmt_dereserve_va(uint64_t start, uint64_t size) { munmap((void*)start, size); }\n\nvoid vhsakmt_set_scratch_area(vhsakmt_device_handle dev, uint32_t node, uint64_t start,\n                              uint64_t size) {\n  if (!dev->vhsakmt_nodes || !dev->sys_props) return;\n  if (node >= dev->sys_props->NumNodes) return;\n\n  pthread_mutex_lock(&dev->vhsakmt_mutex);\n\n  if (dev->vhsakmt_nodes[node].scratch_start && dev->vhsakmt_nodes[node].scratch_size) goto out;\n\n  dev->vhsakmt_nodes[node].scratch_start = start;\n  dev->vhsakmt_nodes[node].scratch_size = size;\n\nout:\n  pthread_mutex_unlock(&dev->vhsakmt_mutex);\n}\n\nbool vhsakmt_is_scratch_mem(vhsakmt_device_handle dev, void* addr) {\n  uint32_t i;\n  if (!dev->vhsakmt_nodes || !dev->sys_props) return false;\n\n  for (i = 0; i < dev->sys_props->NumNodes; i++) {\n    if ((uint64_t)addr >= dev->vhsakmt_nodes[i].scratch_start &&\n        (uint64_t)addr <= dev->vhsakmt_nodes[i].scratch_start + dev->vhsakmt_nodes[i].scratch_size)\n      return true;\n  }\n\n  return false;\n}\n\nvoid vhsakmt_set_vm_area(vhsakmt_device_handle dev, uint64_t start, uint64_t size) {\n  pthread_mutex_lock(&dev->vhsakmt_mutex);\n  if (dev->vm_start && dev->vm_size) goto out;\n\n  dev->vm_start = start;\n  dev->vm_size = size;\n\nout:\n  pthread_mutex_unlock(&dev->vhsakmt_mutex);\n}\n\nbool vhsakmt_is_userptr(vhsakmt_device_handle dev, void* addr) {\n  return !((uint64_t)addr >= dev->vm_start && (uint64_t)addr <= dev->vm_start + dev->vm_size);\n}\n\nint vhsakmt_set_node_doorbell(vhsakmt_device_handle dev, uint32_t node, void* doorbell) {\n  if (!dev->vhsakmt_nodes || !dev->sys_props) return -EINVAL;\n  if (node >= dev->sys_props->NumNodes) return -EINVAL;\n\n  pthread_mutex_lock(&dev->vhsakmt_mutex);\n\n  dev->vhsakmt_nodes[node].doorbell_base = doorbell;\n\n  pthread_mutex_unlock(&dev->vhsakmt_mutex);\n\n  return 0;\n}\n\nvoid* vhsakmt_node_doorbell(vhsakmt_device_handle dev, uint32_t node) {\n  if (!dev->vhsakmt_nodes || !dev->sys_props) return NULL;\n  if (node >= dev->sys_props->NumNodes) return NULL;\n\n  return dev->vhsakmt_nodes[node].doorbell_base;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/include/linux/virtgpu_drm.h",
    "content": "/*\n * Copyright 2013 Red Hat\n * All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice (including the next\n * paragraph) shall be included in all copies or substantial portions of the\n * Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n#ifndef VIRTGPU_DRM_H\n#define VIRTGPU_DRM_H\n\n#include \"drm.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Please note that modifications to all structs defined here are\n * subject to backwards-compatibility constraints.\n *\n * Do not use pointers, use __u64 instead for 32 bit / 64 bit user/kernel\n * compatibility Keep fields aligned to their size\n */\n\n#define DRM_VIRTGPU_MAP         0x01\n#define DRM_VIRTGPU_EXECBUFFER  0x02\n#define DRM_VIRTGPU_GETPARAM    0x03\n#define DRM_VIRTGPU_RESOURCE_CREATE 0x04\n#define DRM_VIRTGPU_RESOURCE_INFO     0x05\n#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x06\n#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07\n#define DRM_VIRTGPU_WAIT     0x08\n#define DRM_VIRTGPU_GET_CAPS  0x09\n#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a\n#define DRM_VIRTGPU_CONTEXT_INIT 0x0b\n\n#define VIRTGPU_EXECBUF_FENCE_FD_IN\t0x01\n#define VIRTGPU_EXECBUF_FENCE_FD_OUT\t0x02\n#define VIRTGPU_EXECBUF_RING_IDX\t0x04\n#define VIRTGPU_EXECBUF_FLAGS  (\\\n\t\tVIRTGPU_EXECBUF_FENCE_FD_IN |\\\n\t\tVIRTGPU_EXECBUF_FENCE_FD_OUT |\\\n\t\tVIRTGPU_EXECBUF_RING_IDX |\\\n\t\t0)\n\nstruct drm_virtgpu_map {\n\t__u64 offset; /* use for mmap system call */\n\t__u32 handle;\n\t__u32 pad;\n};\n\n#define VIRTGPU_EXECBUF_SYNCOBJ_RESET\t\t0x01\n#define VIRTGPU_EXECBUF_SYNCOBJ_FLAGS ( \\\n\t\tVIRTGPU_EXECBUF_SYNCOBJ_RESET | \\\n\t\t0)\nstruct drm_virtgpu_execbuffer_syncobj {\n\t__u32 handle;\n\t__u32 flags;\n\t__u64 point;\n};\n\n/* fence_fd is modified on success if VIRTGPU_EXECBUF_FENCE_FD_OUT flag is set. */\nstruct drm_virtgpu_execbuffer {\n\t__u32 flags;\n\t__u32 size;\n\t__u64 command; /* void* */\n\t__u64 bo_handles;\n\t__u32 num_bo_handles;\n\t__s32 fence_fd; /* in/out fence fd (see VIRTGPU_EXECBUF_FENCE_FD_IN/OUT) */\n\t__u32 ring_idx; /* command ring index (see VIRTGPU_EXECBUF_RING_IDX) */\n\t__u32 syncobj_stride; /* size of @drm_virtgpu_execbuffer_syncobj */\n\t__u32 num_in_syncobjs;\n\t__u32 num_out_syncobjs;\n\t__u64 in_syncobjs;\n\t__u64 out_syncobjs;\n};\n\n#define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */\n#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */\n#define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */\n#define VIRTGPU_PARAM_HOST_VISIBLE 4 /* Host blob resources are mappable */\n#define VIRTGPU_PARAM_CROSS_DEVICE 5 /* Cross virtio-device resource sharing  */\n#define VIRTGPU_PARAM_CONTEXT_INIT 6 /* DRM_VIRTGPU_CONTEXT_INIT */\n#define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7 /* Bitmask of supported capability set ids */\n#define VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME 8 /* Ability to set debug name from userspace */\n\nstruct drm_virtgpu_getparam {\n\t__u64 param;\n\t__u64 value;\n};\n\n/* NO_BO flags? NO resource flag? */\n/* resource flag for y_0_top */\nstruct drm_virtgpu_resource_create {\n\t__u32 target;\n\t__u32 format;\n\t__u32 bind;\n\t__u32 width;\n\t__u32 height;\n\t__u32 depth;\n\t__u32 array_size;\n\t__u32 last_level;\n\t__u32 nr_samples;\n\t__u32 flags;\n\t__u32 bo_handle; /* if this is set - recreate a new resource attached to this bo ? */\n\t__u32 res_handle;  /* returned by kernel */\n\t__u32 size;        /* validate transfer in the host */\n\t__u32 stride;      /* validate transfer in the host */\n};\n\nstruct drm_virtgpu_resource_info {\n\t__u32 bo_handle;\n\t__u32 res_handle;\n\t__u32 size;\n\t__u32 blob_mem;\n};\n\nstruct drm_virtgpu_3d_box {\n\t__u32 x;\n\t__u32 y;\n\t__u32 z;\n\t__u32 w;\n\t__u32 h;\n\t__u32 d;\n};\n\nstruct drm_virtgpu_3d_transfer_to_host {\n\t__u32 bo_handle;\n\tstruct drm_virtgpu_3d_box box;\n\t__u32 level;\n\t__u32 offset;\n\t__u32 stride;\n\t__u32 layer_stride;\n};\n\nstruct drm_virtgpu_3d_transfer_from_host {\n\t__u32 bo_handle;\n\tstruct drm_virtgpu_3d_box box;\n\t__u32 level;\n\t__u32 offset;\n\t__u32 stride;\n\t__u32 layer_stride;\n};\n\n#define VIRTGPU_WAIT_NOWAIT 1 /* like it */\nstruct drm_virtgpu_3d_wait {\n\t__u32 handle; /* 0 is an invalid handle */\n\t__u32 flags;\n};\n\n#define VIRTGPU_DRM_CAPSET_VIRGL 1\n#define VIRTGPU_DRM_CAPSET_VIRGL2 2\n#define VIRTGPU_DRM_CAPSET_GFXSTREAM_VULKAN 3\n#define VIRTGPU_DRM_CAPSET_VENUS 4\n#define VIRTGPU_DRM_CAPSET_CROSS_DOMAIN 5\n#define VIRTGPU_DRM_CAPSET_DRM 6\nstruct drm_virtgpu_get_caps {\n\t__u32 cap_set_id;\n\t__u32 cap_set_ver;\n\t__u64 addr;\n\t__u32 size;\n\t__u32 pad;\n};\n\nstruct drm_virtgpu_resource_create_blob {\n#define VIRTGPU_BLOB_MEM_GUEST             0x0001\n#define VIRTGPU_BLOB_MEM_HOST3D            0x0002\n#define VIRTGPU_BLOB_MEM_HOST3D_GUEST      0x0003\n\n#define VIRTGPU_BLOB_FLAG_USE_MAPPABLE     0x0001\n#define VIRTGPU_BLOB_FLAG_USE_SHAREABLE    0x0002\n#define VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE 0x0004\n#define VIRTGPU_BLOB_FLAG_USE_USERPTR      0x0008\n\t/* zero is invalid blob_mem */\n\t__u32 blob_mem;\n\t__u32 blob_flags;\n\t__u32 bo_handle;\n\t__u32 res_handle;\n\t__u64 size;\n\n\t/*\n\t * for 3D contexts with VIRTGPU_BLOB_MEM_HOST3D_GUEST and\n\t * VIRTGPU_BLOB_MEM_HOST3D otherwise, must be zero.\n\t */\n\t__u32 pad;\n\t__u32 cmd_size;\n\t__u64 cmd;\n\t__u64 blob_id;\n  __u64 blob_userptr;\n  __s64 offset;\n};\n\n#define VIRTGPU_CONTEXT_PARAM_CAPSET_ID       0x0001\n#define VIRTGPU_CONTEXT_PARAM_NUM_RINGS       0x0002\n#define VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK 0x0003\n#define VIRTGPU_CONTEXT_PARAM_DEBUG_NAME      0x0004\nstruct drm_virtgpu_context_set_param {\n\t__u64 param;\n\t__u64 value;\n};\n\nstruct drm_virtgpu_context_init {\n\t__u32 num_params;\n\t__u32 pad;\n\n\t/* pointer to drm_virtgpu_context_set_param array */\n\t__u64 ctx_set_params;\n};\n\n/*\n * Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in\n * effect.  The event size is sizeof(drm_event), since there is no additional\n * payload.\n */\n#define VIRTGPU_EVENT_FENCE_SIGNALED 0x90000000\n\n#define DRM_IOCTL_VIRTGPU_MAP \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)\n\n#define DRM_IOCTL_VIRTGPU_EXECBUFFER \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER,\\\n\t\tstruct drm_virtgpu_execbuffer)\n\n#define DRM_IOCTL_VIRTGPU_GETPARAM \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM,\\\n\t\tstruct drm_virtgpu_getparam)\n\n#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE\t\t\t\\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE,\t\\\n\t\tstruct drm_virtgpu_resource_create)\n\n#define DRM_IOCTL_VIRTGPU_RESOURCE_INFO \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_INFO, \\\n\t\t struct drm_virtgpu_resource_info)\n\n#define DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_FROM_HOST,\t\\\n\t\tstruct drm_virtgpu_3d_transfer_from_host)\n\n#define DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_TRANSFER_TO_HOST,\t\\\n\t\tstruct drm_virtgpu_3d_transfer_to_host)\n\n#define DRM_IOCTL_VIRTGPU_WAIT\t\t\t\t\\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_WAIT,\t\\\n\t\tstruct drm_virtgpu_3d_wait)\n\n#define DRM_IOCTL_VIRTGPU_GET_CAPS \\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, \\\n\tstruct drm_virtgpu_get_caps)\n\n#define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB\t\t\t\t\\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE_BLOB,\t\\\n\t\tstruct drm_virtgpu_resource_create_blob)\n\n#define DRM_IOCTL_VIRTGPU_CONTEXT_INIT\t\t\t\t\t\\\n\tDRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT,\t\t\\\n\t\tstruct drm_virtgpu_context_init)\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "libhsakmt/src/virtio/libhsakmt_virtio.ver",
    "content": "{\nglobal:\nvhsaKmtOpenKFD;\nvhsaKmtCloseKFD;\nvhsaKmtAllocMemory;\nvhsaKmtFreeMemory;\nvhsaKmtMapMemoryToGPUNodes;\nvhsaKmtUnmapMemoryToGPU;\nvhsaKmtAvailableMemory;\nvhsaKmtMapMemoryToGPU;\nvhsaKmtRegisterMemoryWithFlags;\nvhsaKmtDeregisterMemory;\nvhsaKmtGetVersion;\nvhsaKmtAcquireSystemProperties;\nvhsaKmtReleaseSystemProperties;\nvhsaKmtGetNodeProperties;\nvhsaKmtGetXNACKMode;\nvhsaKmtRuntimeEnable;\nvhsaKmtRuntimeDisable;\nvhsaKmtGetNodeMemoryProperties;\nvhsaKmtGetNodeCacheProperties;\nvhsaKmtGetNodeIoLinkProperties;\nvhsaKmtGetClockCounters;\nvhsaKmtGetAMDGPUDeviceHandle;\nvhsaKmtQueryPointerInfo;\nvhsaKmtGetTileConfig;\nvhsaKmtCreateEvent;\nvhsaKmtDestroyEvent;\nvhsaKmtSetEvent;\nvhsaKmtResetEvent;\nvhsaKmtQueryEventState;\nvhsaKmtWaitOnMultipleEvents;\nvhsaKmtWaitOnEvent;\nvhsaKmtWaitOnEvent_Ext;\nvhsaKmtWaitOnMultipleEvents_Ext;\nvhsaKmtSetTrapHandler;\nvhsaKmtCreateQueueExt;\nvhsaKmtCreateQueue;\nvhsaKmtDestroyQueue;\nvhsaKmtRegisterGraphicsHandleToNodes;\nvhsaKmtGetRuntimeCapabilities;\nvamdgpu_query_gpu_info;\nlocal: *;\n};\n\n"
  },
  {
    "path": "libhsakmt/src/virtio/virtio_gpu.c",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include <errno.h>\n#include <libsync.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <fcntl.h>\n\n#include \"virtio_gpu.h\"\n\n#define SHMEM_SZ (25 * 0x1000)\n\nstatic int set_context(int fd) {\n  struct drm_virtgpu_context_set_param params[] = {\n      {VIRTGPU_CONTEXT_PARAM_CAPSET_ID, VIRGL_RENDERER_CAPSET_HSAKMT},\n      {VIRTGPU_CONTEXT_PARAM_NUM_RINGS, 64},\n  };\n  struct drm_virtgpu_context_init args = {\n      .num_params = ARRAY_SIZE(params),\n      .ctx_set_params = (uintptr_t)(params),\n  };\n\n  return virtio_gpu_ioctl(fd, VIRTGPU_CONTEXT_INIT, &args);\n}\n\nint virtio_gpu_map_handle(struct virtio_gpu_device* vgdev, uint32_t handle, uint64_t size,\n                          void** addr, void* fixed_map) {\n  struct drm_virtgpu_map args = {\n      .handle = handle,\n  };\n  int r;\n\n  r = virtio_gpu_ioctl(vgdev->fd, VIRTGPU_MAP, &args);\n  if (r) return r;\n\n  *addr = mmap(fixed_map, size, PROT_READ | PROT_WRITE, MAP_SHARED | (fixed_map ? MAP_FIXED : 0),\n               vgdev->fd, args.offset);\n\n  if (*addr == MAP_FAILED) return -EINVAL;\n\n  return 0;\n}\n\nvoid virtio_gpu_unmap(void* addr, uint64_t size) { munmap(addr, size); }\n\nstatic void virtio_gpu_bo_close(struct virtio_gpu_device* vgdev, uint32_t handle) {\n  struct drm_gem_close args = {\n      .handle = handle,\n  };\n\n  virtio_gpu_ioctl(vgdev->fd, GEM_CLOSE, &args);\n}\n\nstatic int virtio_gpu_shmem_init(struct virtio_gpu_device* vgdev, size_t size) {\n  struct drm_virtgpu_resource_create_blob args = {\n      .blob_mem = VIRTGPU_BLOB_MEM_HOST3D,\n      .blob_flags = VIRTGPU_BLOB_FLAG_USE_MAPPABLE,\n      .size = size,\n      .blob_id = 0,\n  };\n\n  int r = virtio_gpu_ioctl(vgdev->fd, VIRTGPU_RESOURCE_CREATE_BLOB, &args);\n  if (r) return r;\n\n  r = virtio_gpu_map_handle(vgdev, args.bo_handle, size, (void**)&vgdev->shmem, NULL);\n  if (r) {\n    virtio_gpu_bo_close(vgdev, args.bo_handle);\n    return r;\n  }\n\n  vgdev->shmem_handle = args.bo_handle;\n\n  uint32_t offset = vgdev->shmem->base.rsp_mem_offset;\n  vgdev->rsp_mem_len = size - offset;\n  vgdev->rsp_mem = &((uint8_t*)vgdev->shmem)[offset];\n\n  return 0;\n}\n\nstruct virtio_gpu_device* virtio_gpu_init(int fd, uint32_t context_id) {\n  struct virtio_gpu_device* vgdev;\n  int r;\n\n  r = set_context(fd);\n\n  if (r) return NULL;\n\n  vgdev = calloc(1, sizeof(*vgdev));\n  if (!vgdev) return NULL;\n\n  vgdev->fd = fd;\n\n  vgdev->reqbuf = calloc(1, SHMEM_SZ);\n  if (!vgdev->reqbuf) {\n    free(vgdev);\n    return NULL;\n  }\n\n  r = virtio_gpu_shmem_init(vgdev, SHMEM_SZ);\n  if (r) {\n    free(vgdev);\n    return NULL;\n  }\n\n  pthread_mutex_init(&vgdev->rsp_lock, NULL);\n  pthread_mutex_init(&vgdev->eb_lock, NULL);\n\n  return vgdev;\n}\n\nvoid virtio_gpu_close(struct virtio_gpu_device* vgdev) {\n  virtio_gpu_unmap(vgdev->shmem, SHMEM_SZ);\n  virtio_gpu_bo_close(vgdev, vgdev->shmem_handle);\n\n  pthread_mutex_destroy(&vgdev->rsp_lock);\n  pthread_mutex_destroy(&vgdev->eb_lock);\n\n  close(vgdev->fd);\n  free(vgdev->reqbuf);\n  free(vgdev);\n}\n\nvoid* virtio_gpu_alloc_rsp(struct virtio_gpu_device* vgdev, struct virtio_gpu_ccmd_req* req,\n                           uint32_t size) {\n  uint32_t off;\n\n  pthread_mutex_lock(&vgdev->rsp_lock);\n\n  size = VHSA_ALIGN_UP(size, 8);\n\n  if ((vgdev->next_rsp_off + size) >= vgdev->rsp_mem_len) vgdev->next_rsp_off = 0;\n\n  off = vgdev->next_rsp_off;\n  vgdev->next_rsp_off += size;\n\n  pthread_mutex_unlock(&vgdev->rsp_lock);\n\n  req->rsp_off = off;\n  struct virtio_gpu_ccmd_rsp* rsp = (void*)&vgdev->rsp_mem[off];\n  rsp->len = size;\n\n  return rsp;\n}\n\nstatic int virtio_gpu_execbuffer_locked(struct virtio_gpu_device* vgdev, void* cmd,\n                                        uint32_t cmd_size, uint32_t* handles, uint32_t num_handles,\n                                        int* fence_fd, int ring_idx, uint32_t num_in_syncobjs,\n                                        uint32_t num_out_syncobjs,\n                                        struct drm_virtgpu_execbuffer_syncobj* in_syncobjs,\n                                        struct drm_virtgpu_execbuffer_syncobj* out_syncobjs,\n                                        bool in_fence, bool out_fence) {\n  struct drm_virtgpu_execbuffer eb = {\n      .flags = (out_fence ? VIRTGPU_EXECBUF_FENCE_FD_OUT : 0) |\n          (in_fence ? VIRTGPU_EXECBUF_FENCE_FD_IN : 0) | VIRTGPU_EXECBUF_RING_IDX,\n      .size = cmd_size,\n      .command = (uintptr_t)cmd,\n      .bo_handles = (uintptr_t)handles,\n      .num_bo_handles = num_handles,\n      .fence_fd = *fence_fd,\n      .ring_idx = ring_idx,\n      .syncobj_stride = sizeof(struct drm_virtgpu_execbuffer_syncobj),\n      .num_in_syncobjs = num_in_syncobjs,\n      .num_out_syncobjs = num_out_syncobjs,\n      .in_syncobjs = (uintptr_t)in_syncobjs,\n      .out_syncobjs = (uintptr_t)out_syncobjs,\n  };\n  int r = virtio_gpu_ioctl(vgdev->fd, VIRTGPU_EXECBUFFER, &eb);\n  if (r) return r;\n\n  if (out_fence) *fence_fd = eb.fence_fd;\n\n  return 0;\n}\n\nstatic int virtio_gpu_flush_locked(struct virtio_gpu_device* vgdev, int* fence) {\n  int r;\n\n  if (!vgdev->reqbuf_len) return 0;\n\n  r = virtio_gpu_execbuffer_locked(vgdev, vgdev->reqbuf, vgdev->reqbuf_len, NULL, 0, fence, 0, 0, 0,\n                                   NULL, NULL, false, !!fence);\n  if (r) return r;\n\n  vgdev->reqbuf_len = 0;\n  vgdev->reqbuf_cnt = 0;\n\n  return 0;\n}\n\nstatic int virtio_gpu_add_cmd(struct virtio_gpu_device* vgdev, struct virtio_gpu_ccmd_req* req) {\n  req->seqno = ++vgdev->next_seqno;\n  int r;\n\n  if (vgdev->reqbuf_len + req->len > sizeof(vgdev->reqbuf)) {\n    r = virtio_gpu_flush_locked(vgdev, NULL);\n    if (r) return r;\n  }\n\n  memcpy(&vgdev->reqbuf[vgdev->reqbuf_len], req, req->len);\n  vgdev->reqbuf_len += req->len;\n  vgdev->reqbuf_cnt++;\n\n  return 0;\n}\n\nstatic inline bool fence_before(uint32_t a, uint32_t b) { return (int32_t)(a - b) < 0; }\n\nstatic void virtio_gpu_seqno_sync(struct virtio_gpu_device* vgdev,\n                                  struct virtio_gpu_ccmd_req* req) {\n  while (fence_before(vgdev->shmem->base.seqno, req->seqno)) sched_yield();\n}\n\nint virtio_gpu_exec_cmd(struct virtio_gpu_device* vgdev, struct virtio_gpu_ccmd_req* req,\n                        bool sync) {\n  int r = 0;\n  int fence;\n\n  pthread_mutex_lock(&vgdev->eb_lock);\n\n  r = virtio_gpu_add_cmd(vgdev, req);\n\n  if (r || !sync) goto out;\n\n  r = virtio_gpu_flush_locked(vgdev, &fence);\n\nout:\n  pthread_mutex_unlock(&vgdev->eb_lock);\n  if (r) return r;\n\n  if (sync) {\n    sync_wait(fence, -1);\n    close(fence);\n    virtio_gpu_seqno_sync(vgdev, req);\n  }\n\n  return r;\n}\n\nint virtio_gpu_create_blob(struct virtio_gpu_device* vgdev,\n                           struct drm_virtgpu_resource_create_blob* args) {\n  return virtio_gpu_ioctl(vgdev->fd, VIRTGPU_RESOURCE_CREATE_BLOB, args);\n}\n\nint virtio_gpu_destroy_handle(struct virtio_gpu_device* vgdev, uint32_t bo_handle) {\n  struct drm_gem_close args = {\n      .handle = bo_handle,\n  };\n\n  return virtio_gpu_ioctl(vgdev->fd, GEM_CLOSE, &args);\n}\n\nint virtio_gpu_res_id(struct virtio_gpu_device* vgdev, uint32_t handle, uint32_t* res_id) {\n  struct drm_virtgpu_resource_info args = {\n      .bo_handle = handle,\n  };\n  int r = virtio_gpu_ioctl(vgdev->fd, VIRTGPU_RESOURCE_INFO, &args);\n  if (r) return r;\n\n  *res_id = args.res_handle;\n  return 0;\n}\n\nstatic int virtio_gpu_get_capset(int fd, struct virgl_renderer_capset_hsakmt* caps) {\n  struct drm_virtgpu_get_caps args = {\n      .cap_set_id = VIRGL_RENDERER_CAPSET_HSAKMT,\n      .cap_set_ver = 0,\n      .addr = (uintptr_t)caps,\n      .size = sizeof(*caps),\n  };\n\n  memset(caps, 0, sizeof(*caps));\n\n  return virtio_gpu_ioctl(fd, VIRTGPU_GET_CAPS, &args);\n}\n\nint virtio_gpu_kfd_open(void) {\n  drmDevicePtr devices[VHSA_MAX_DEVICES];\n  int num_devices = 0;\n  int i, fd, ret;\n\n  num_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));\n  if (num_devices <= 0) return -1;\n\n  for (i = 0; i < num_devices; i++) {\n    fd = open(devices[i]->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);\n    if (fd < 0) continue;\n\n    struct virgl_renderer_capset_hsakmt caps;\n    ret = virtio_gpu_get_capset(fd, &caps);\n    if (ret || caps.context_type != VIRTGPU_DRM_CONTEXT_AMDGPU) {\n      close(fd);\n      fd = -1;\n      continue;\n    }\n\n    goto out;\n  }\n\nout:\n  drmFreeDevices(devices, num_devices);\n  return fd;\n}\n"
  },
  {
    "path": "libhsakmt/src/virtio/virtio_gpu.h",
    "content": "/*\n * Copyright 2025 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#ifndef VIRTIO_GPU_H\n#define VIRTIO_GPU_H\n\n#include <pthread.h>\n#include <stdint.h>\n#include <xf86drm.h>\n\n#include \"virtgpu_drm.h\"\n\n#define VIRGL_RENDERER_CAPSET_HSAKMT 8\n#define VIRTGPU_DRM_CONTEXT_AMDGPU 1\n#define VHSA_MAX_DEVICES 10\n\n#ifndef ARRAY_SIZE\n#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n#endif\n\n#define VHSA_ALIGN_UP(x, align) (((uint64_t)(x) + (align)-1) & ~(uint64_t)((align)-1))\n#define VHSA_ALIGN_DOWN(x, align) ((uint64_t)(x) & ~(uint64_t)((align)-1))\n\n#define virtio_gpu_ioctl(fd, name, args)                                                           \\\n  ({                                                                                               \\\n    int ret = drmIoctl((fd), DRM_IOCTL_##name, (args));                                            \\\n    ret;                                                                                           \\\n  })\n\nstruct virgl_renderer_capset_hsakmt {\n  uint32_t wire_format_version;\n  /* Underlying drm device version: */\n  uint32_t version_major;\n  uint32_t version_minor;\n  uint32_t version_patchlevel;\n  uint32_t context_type;\n  uint32_t pad;\n};\n\nstruct virtio_gpu_shmem_base {\n  uint32_t seqno;\n  uint32_t rsp_mem_offset;\n};\n\nstruct virtio_gpu_ccmd_req {\n  uint32_t cmd;\n  uint32_t len;\n  uint32_t seqno;\n  uint32_t rsp_off;\n};\n\nstruct virtio_gpu_ccmd_rsp {\n  uint32_t len;\n};\n\nstruct virtio_gpu_shmem {\n  struct virtio_gpu_shmem_base base;\n  uint32_t async_error;\n  uint32_t global_faults;\n};\n\n#define vhsakmt_shmem virtio_gpu_shmem\n#define vhsakmt_ccmd_req virtio_gpu_ccmd_req\n#define vhsakmt_ccmd_rsp virtio_gpu_ccmd_rsp\n\nstruct virtio_gpu_device {\n  int fd;\n\n  struct virtio_gpu_shmem* shmem;\n  uint32_t shmem_handle;\n\n  uint8_t* rsp_mem;\n  uint32_t rsp_mem_len;\n  uint32_t next_rsp_off;\n  pthread_mutex_t rsp_lock;\n  pthread_mutex_t eb_lock;\n\n  uint32_t next_seqno;\n  uint32_t reqbuf_len;\n  uint32_t reqbuf_cnt;\n  uint8_t* reqbuf;\n};\n\nstruct virtio_gpu_device* virtio_gpu_init(int fd, uint32_t context_id);\nvoid virtio_gpu_close(struct virtio_gpu_device* vgdev);\nint virtio_gpu_exec_cmd(struct virtio_gpu_device* vgdev, struct virtio_gpu_ccmd_req* req,\n                        bool sync);\nvoid* virtio_gpu_alloc_rsp(struct virtio_gpu_device* vgdev, struct virtio_gpu_ccmd_req* req,\n                           uint32_t size);\nint virtio_gpu_map_handle(struct virtio_gpu_device* vgdev, uint32_t handle, uint64_t size,\n                          void** addr, void* fixed_map);\nvoid virtio_gpu_unmap(void* addr, uint64_t size);\nint virtio_gpu_create_blob(struct virtio_gpu_device* vgdev,\n                           struct drm_virtgpu_resource_create_blob* args);\nint virtio_gpu_destroy_handle(struct virtio_gpu_device* vgdev, uint32_t bo_handle);\nint virtio_gpu_res_id(struct virtio_gpu_device* vgdev, uint32_t handle, uint32_t* res_id);\nint virtio_gpu_kfd_open(void);\n\n#endif /* VIRTIO_GPU_H */\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/.gitignore",
    "content": ""
  },
  {
    "path": "libhsakmt/tests/kfdtest/CMakeLists.txt",
    "content": "#\n# Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the \"Software\"),\n# to deal in the Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n# and/or sell copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n#\n#\n\n# If environment variable DRM_DIR or LIBHSAKMT_PATH is set, the script\n# will pick up the corresponding libraries from those pathes.\n\ncmake_minimum_required(VERSION 3.5 FATAL_ERROR)\n\nproject(KFDTest)\n\n# For DEB/RPM generation\nset ( CPACK_PACKAGE_NAME \"kfdtest\" )\nset ( CPACK_PACKAGE_CONTACT \"Advanced Micro Devices Inc.\" )\nset ( CPACK_PACKAGE_DESCRIPTION \"This package includes kfdtest, the list of excluded tests for each ASIC, and a convenience script to run the test suite\" )\nset ( CPACK_PACKAGE_DESCRIPTION_SUMMARY \"Test suite for ROCK/KFD\" )\n\n# Make proper version for appending\n# Default Value is 99999, setting it first\nset(ROCM_VERSION_FOR_PACKAGE \"99999\")\nif(DEFINED ENV{ROCM_LIBPATCH_VERSION})\n  set(ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_LIBPATCH_VERSION})\nendif()\n\nset ( CPACK_PACKAGE_VERSION_MAJOR \"1\" )\nset ( CPACK_PACKAGE_VERSION_MINOR \"0\" )\nset ( CPACK_PACKAGE_VERSION_PATCH \"0\" )\nset ( CPACK_PACKAGE_HOMEPAGE_URL \"https://github.com/ROCm/ROCR-Runtime/\" )\nset ( CPACK_DEBIAN_FILE_NAME \"DEB-DEFAULT\")\nset ( CPACK_RPM_FILE_NAME \"RPM-DEFAULT\")\n\n## Debian package values\nset ( CPACK_DEBIAN_PACKAGE_RELEASE \"local\" )\nif( DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE} )\n  set ( CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE} )\nendif()\n## RPM package variables\nset ( CPACK_RPM_PACKAGE_RELEASE \"local\" )\nif( DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE} )\n  set ( CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE} )\nendif()\n\n## Note: rpm --eval %{?dist} will evaluate to NULL in Debian\n## So Debian distros won't append dist tag to CPACK_RPM_PACKAGE_RELEASE.\n## Also for debian package name , the dist tag is added from build env\nexecute_process( COMMAND rpm --eval %{?dist}\n                 RESULT_VARIABLE PROC_RESULT\n                 OUTPUT_VARIABLE EVAL_RESULT\n                 OUTPUT_STRIP_TRAILING_WHITESPACE )\nmessage(\"RESULT_VARIABLE ${PROC_RESULT} OUTPUT_VARIABLE: ${EVAL_RESULT}\")\n## Add distribution tag to rpm package name\nif ( PROC_RESULT EQUAL \"0\" AND NOT EVAL_RESULT STREQUAL \"\" )\n  string ( APPEND CPACK_RPM_PACKAGE_RELEASE \"%{?dist}\" )\nendif()\n\nset(PACKAGE_VERSION_STR \"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${ROCM_VERSION_FOR_PACKAGE}\")\nset(CPACK_PACKAGE_VERSION \"${PACKAGE_VERSION_STR}\")\n\n## Define default variable and variables for the optional build target hsakmt-dev\nset ( SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING \"Location of hsakmt source code.\" )\nset ( CMAKE_INSTALL_PREFIX \"/opt/rocm\"  CACHE STRING \"Default installation directory.\" )\nset ( CPACK_PACKAGING_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"  CACHE STRING \"Default packaging prefix.\" )\nset ( CPACK_GENERATOR \"DEB;RPM\"  CACHE STRING \"Default packaging generators.\" )\n\n# Debian package specific variables\nset ( CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/ROCm/ROCR-Runtime/\" )\nset ( CPACK_DEBIAN_PACKAGE_DEPENDS \"rocm-core\" )\n\n# RPM package specific variables\nset (CPACK_RPM_PACKAGE_REQUIRES \"rocm-core\")\n\n#set ( CMAKE_VERBOSE_MAKEFILE on )\n\nfind_package(PkgConfig)\n\nlist (PREPEND CMAKE_PREFIX_PATH \"${DRM_DIR}\")\n# The module name passed to pkg_check_modules() is determined by the\n# name of file *.pc\npkg_check_modules(DRM REQUIRED libdrm)\npkg_check_modules(DRM_AMDGPU REQUIRED libdrm_amdgpu)\ninclude_directories(${DRM_AMDGPU_INCLUDE_DIRS})\n\nif( DEFINED ENV{LIBHSAKMT_PATH} )\n    set ( LIBHSAKMT_PATH $ENV{LIBHSAKMT_PATH} )\n    message ( \"LIBHSAKMT_PATH environment variable is set\" )\nelse()\n    if ( ${ROCM_INSTALL_PATH} )\n       set ( ENV{PKG_CONFIG_PATH} ${ROCM_INSTALL_PATH}/share/pkgconfig )\n    else()\n       set ( ENV{PKG_CONFIG_PATH} /opt/rocm/share/pkgconfig )\n    endif()\n\n    pkg_check_modules(HSAKMT libhsakmt)\n\n    if( NOT HSAKMT_FOUND )\n       set ( LIBHSAKMT_PATH $ENV{OUT_DIR} )\n    endif()\nendif()\n\nif( DEFINED LIBHSAKMT_PATH )\n    set ( HSAKMT_LIBRARY_DIRS ${LIBHSAKMT_PATH} )\n    set ( HSAKMT_LIBRARIES hsakmt )\nendif()\n\nmessage ( \"Find libhsakmt at ${HSAKMT_LIBRARY_DIRS}\" )\n\nif ( POLICY CMP0074 )\n    cmake_policy( SET CMP0074 NEW )\nendif()\n\nfind_path( LIGHTNING_CMAKE_DIR NAMES LLVMConfig.cmake\n    PATHS $ENV{OUT_DIR}/llvm/lib/cmake/llvm NO_CACHE NO_DEFAULT_PATH)\n\nif ( DEFINED LIGHTNING_CMAKE_DIR AND EXISTS ${LIGHTNING_CMAKE_DIR} )\n    set ( LLVM_DIR ${LIGHTNING_CMAKE_DIR} )\nelse()\n    message( STATUS \"Couldn't find Lightning build in compute directory. \"\n        \"Searching LLVM_DIR then defaulting to system LLVM install if still not found...\" )\nendif()\n\nfind_package( LLVM REQUIRED CONFIG )\n\nif( ${LLVM_PACKAGE_VERSION} VERSION_LESS \"7.0\" )\n    message( FATAL_ERROR \"Requires LLVM 7.0 or greater \"\n        \"(found ${LLVM_PACKAGE_VERSION})\" )\nelseif( ${LLVM_PACKAGE_VERSION} VERSION_LESS \"14.0\" )\n    message( WARNING \"Not using latest LLVM version. \"\n        \"Some ASIC targets may not work!\" )\nendif()\n\nmessage( STATUS \"Found LLVM ${LLVM_PACKAGE_VERSION}\" )\nmessage( STATUS \"Using LLVMConfig.cmake in: ${LLVM_DIR}\" )\n\ninclude_directories(${LLVM_INCLUDE_DIRS})\nseparate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})\nadd_definitions(${LLVM_DEFINITIONS_LIST})\n\nif (LLVM_LINK_LLVM_DYLIB)\n  set(llvm_libs LLVM)\nelse()\n  llvm_map_components_to_libnames(llvm_libs AMDGPUAsmParser Core Support)\nendif()\n\ninclude_directories(${PROJECT_SOURCE_DIR}/gtest-1.6.0)\ninclude_directories(${PROJECT_SOURCE_DIR}/include)\ninclude_directories(${PROJECT_SOURCE_DIR}/../../include)\ninclude_directories(${PROJECT_SOURCE_DIR}/../../libhsakmt/include)\n\ninclude_directories(${DRM_INCLUDE_DIRS})\n\nset (SRC_FILES gtest-1.6.0/gtest-all.cpp\n\n  src/AqlQueue.cpp\n  src/BasePacket.cpp\n  src/BaseDebug.cpp\n  src/BaseQueue.cpp\n  src/Dispatch.cpp\n  src/GoogleTestExtension.cpp\n  src/IndirectBuffer.cpp\n  src/Assemble.cpp\n  src/ShaderStore.cpp\n  src/LinuxOSWrapper.cpp\n  src/PM4Packet.cpp\n  src/PM4Queue.cpp\n  src/RDMAUtil.cpp\n  src/SDMAPacket.cpp\n  src/SDMAQueue.cpp\n  src/KFDBaseComponentTest.cpp\n  src/KFDMultiProcessTest.cpp\n  src/KFDTestMain.cpp\n  src/KFDTestUtil.cpp\n  src/KFDTestUtilQueue.cpp\n\n  src/KFDOpenCloseKFDTest.cpp\n  src/KFDTopologyTest.cpp\n  src/KFDMemoryTest.cpp\n  src/KFDLocalMemoryTest.cpp\n  src/KFDEventTest.cpp\n  src/KFDQMTest.cpp\n  src/KFDCWSRTest.cpp\n  src/KFDExceptionTest.cpp\n  src/KFDGraphicsInterop.cpp\n  src/KFDPerfCounters.cpp\n  src/KFDDBGTest.cpp\n  src/KFDGWSTest.cpp\n  src/KFDIPCTest.cpp\n  src/KFDASMTest.cpp\n\n  src/KFDEvictTest.cpp\n  src/KFDHWSTest.cpp\n  src/KFDPerformanceTest.cpp\n  src/KFDPMTest.cpp\n  src/KFDSVMRangeTest.cpp\n  src/KFDSVMEvictTest.cpp\n  src/KFDRASTest.cpp\n  src/KFDPCSamplingTest.cpp\n  src/KFDNegativeTest.cpp\n  src/RDMATest.cpp)\n\nmessage( STATUS \"PROJECT_SOURCE_DIR:\" ${PROJECT_SOURCE_DIR} )\n#message( STATUS \"SRC_FILES: \")\n#foreach(file ${SRC_FILES})\n#  message(STATUS \"${file}\")\n#endforeach()\n\n#add_definitions(-Wall -std=c++11)\n\nif ( \"${CMAKE_C_COMPILER_VERSION}\" STRGREATER \"4.8.0\")\n## Add --enable-new-dtags to generate DT_RUNPATH\nset ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=gnu++17 -Wl,--enable-new-dtags\" )\nendif()\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O2\" )\nelse ()\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -g\" )\nendif ()\n\n## Address Sanitize Flag\nif ( ${ADDRESS_SANITIZER} )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=address\" )\n    set ( CMAKE_EXE_LINKER_FLAGS -fsanitize=address )\nendif ()\n\n# link_directories() has to be put before add_executable()\n# The modules found by pkg_check_modules() in the default pkg config\n# path do not need to use link_directories() here.\nlink_directories(${HSAKMT_LIBRARY_DIRS})\n\nadd_executable(kfdtest ${SRC_FILES})\n\ntarget_link_libraries(kfdtest ${HSAKMT_LIBRARIES} ${DRM_LDFLAGS} ${DRM_AMDGPU_LDFLAGS} ${llvm_libs} pthread m stdc++ rt numa)\n\nconfigure_file ( scripts/kfdtest.exclude kfdtest.exclude COPYONLY )\nconfigure_file ( scripts/run_kfdtest.sh run_kfdtest.sh COPYONLY )\n\ninstall( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kfdtest ${CMAKE_CURRENT_BINARY_DIR}/run_kfdtest.sh\n\tDESTINATION bin )\ninstall( FILES ${CMAKE_CURRENT_BINARY_DIR}/kfdtest.exclude\n\tDESTINATION share/kfdtest )\n# Remove dependency on rocm-core if -DROCM_DEP_ROCMCORE=ON not given to cmake\nif(NOT ROCM_DEP_ROCMCORE)\n    string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_RPM_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})\n    string(REGEX REPLACE \",? ?rocm-core\" \"\" CPACK_DEBIAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})\nendif()\ninclude ( CPack )\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/LICENSE.kfdtest",
    "content": "KFDTest - KFD unit tests LICENSE\nCopyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n\nMIT LICENSE:\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/README.txt",
    "content": "1. Note on building kfdtest\n\nTo build this kfdtest application, the following libraries should be already\ninstalled on the building machine:\nlibdrm libdrm_amdgpu libhsakmt\n\nIf libhsakmt is not installed, but the headers and libraries are present\nlocally, you can specify its directory by\nexport LIBHSAKMT_PATH=/path/to/libhsakmt.a\nWith that, CMake/make will look for the lib at LIBHSAKMT_PATH/libhsakmt.a\nNote that this assumes that you will be building kfdtest from the same thunk found in ../..\n\n2. How to run kfdtest\n\nJust run \"./run_kfdtest.sh\" under the building output folder. You may need\nto specify library path through:\nexport LD_LIBRARY_PATH=/path/to/libhsakmt.a\n\nNote: you can use \"run_kfdtest.sh -h\" to see more options.\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/gtest-1.6.0/gtest/gtest.h",
    "content": "// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file defines the public API for Google Test.  It should be\n// included by any test program that uses Google Test.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n//\n// Acknowledgment: Google Test borrowed the idea of automatic test\n// registration from Barthelemy Dagenais' (barthelemy@prologique.com)\n// easyUnit framework.\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_H_\n#define GTEST_INCLUDE_GTEST_GTEST_H_\n\n#include <stdint.h>\n#include <limits>\n#include <vector>\n\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file declares functions and macros used internally by\n// Google Test.  They are subject to change without notice.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: wan@google.com (Zhanyong Wan)\n//\n// Low-level types and utilities for porting Google Test to various\n// platforms.  They are subject to change without notice.  DO NOT USE\n// THEM IN USER CODE.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n\n// The user can define the following macros in the build script to\n// control Google Test's behavior.  If the user doesn't define a macro\n// in this list, Google Test will define it.\n//\n//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)\n//                              is/isn't available.\n//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions\n//                              are enabled.\n//   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string\n//                              is/isn't available (some systems define\n//                              ::string, which is different to std::string).\n//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string\n//                              is/isn't available (some systems define\n//                              ::wstring, which is different to std::wstring).\n//   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular\n//                              expressions are/aren't available.\n//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>\n//                              is/isn't available.\n//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't\n//                              enabled.\n//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that\n//                              std::wstring does/doesn't work (Google Test can\n//                              be used where std::wstring is unavailable).\n//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple\n//                              is/isn't available.\n//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the\n//                              compiler supports Microsoft's \"Structured\n//                              Exception Handling\".\n//   GTEST_HAS_STREAM_REDIRECTION\n//                            - Define it to 1/0 to indicate whether the\n//                              platform supports I/O stream redirection using\n//                              dup() and dup2().\n//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google\n//                              Test's own tr1 tuple implementation should be\n//                              used.  Unused when the user sets\n//                              GTEST_HAS_TR1_TUPLE to 0.\n//   GTEST_LINKED_AS_SHARED_LIBRARY\n//                            - Define to 1 when compiling tests that use\n//                              Google Test as a shared library (known as\n//                              DLL on Windows).\n//   GTEST_CREATE_SHARED_LIBRARY\n//                            - Define to 1 when compiling Google Test itself\n//                              as a shared library.\n\n// This header defines the following utilities:\n//\n// Macros indicating the current platform (defined to 1 if compiled on\n// the given platform; otherwise undefined):\n//   GTEST_OS_AIX      - IBM AIX\n//   GTEST_OS_CYGWIN   - Cygwin\n//   GTEST_OS_HPUX     - HP-UX\n//   GTEST_OS_LINUX    - Linux\n//     GTEST_OS_LINUX_ANDROID - Google Android\n//   GTEST_OS_MAC      - Mac OS X\n//   GTEST_OS_NACL     - Google Native Client (NaCl)\n//   GTEST_OS_SOLARIS  - Sun Solaris\n//   GTEST_OS_SYMBIAN  - Symbian\n//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)\n//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop\n//     GTEST_OS_WINDOWS_MINGW    - MinGW\n//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile\n//   GTEST_OS_ZOS      - z/OS\n//\n// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the\n// most stable support.  Since core members of the Google Test project\n// don't have access to other platforms, support for them may be less\n// stable.  If you notice any problems on your platform, please notify\n// googletestframework@googlegroups.com (patches for fixing them are\n// even more welcome!).\n//\n// Note that it is possible that none of the GTEST_OS_* macros are defined.\n//\n// Macros indicating available Google Test features (defined to 1 if\n// the corresponding feature is supported; otherwise undefined):\n//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized\n//                            tests)\n//   GTEST_HAS_DEATH_TEST   - death tests\n//   GTEST_HAS_PARAM_TEST   - value-parameterized tests\n//   GTEST_HAS_TYPED_TEST   - typed tests\n//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests\n//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with\n//                            GTEST_HAS_POSIX_RE (see above) which users can\n//                            define themselves.\n//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;\n//                            the above two are mutually exclusive.\n//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().\n//\n// Macros for basic C++ coding:\n//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.\n//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a\n//                              variable don't have to be used.\n//   GTEST_DISALLOW_ASSIGN_   - disables operator=.\n//   GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.\n//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.\n//\n// Synchronization:\n//   Mutex, MutexLock, ThreadLocal, GetThreadCount()\n//                  - synchronization primitives.\n//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above\n//                         synchronization primitives have real implementations\n//                         and Google Test is thread-safe; or 0 otherwise.\n//\n// Template meta programming:\n//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only.\n//   IteratorTraits - partial implementation of std::iterator_traits, which\n//                    is not available in libCstd when compiled with Sun C++.\n//\n// Smart pointers:\n//   scoped_ptr     - as in TR2.\n//\n// Regular expressions:\n//   RE             - a simple regular expression class using the POSIX\n//                    Extended Regular Expression syntax on UNIX-like\n//                    platforms, or a reduced regular exception syntax on\n//                    other platforms, including Windows.\n//\n// Logging:\n//   GTEST_LOG_()   - logs messages at the specified severity level.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n//\n// Stdout and stderr capturing:\n//   CaptureStdout()     - starts capturing stdout.\n//   GetCapturedStdout() - stops capturing stdout and returns the captured\n//                         string.\n//   CaptureStderr()     - starts capturing stderr.\n//   GetCapturedStderr() - stops capturing stderr and returns the captured\n//                         string.\n//\n// Integer types:\n//   TypeWithSize   - maps an integer to a int type.\n//   Int32, UInt32, Int64, UInt64, TimeInMillis\n//                  - integers of known sizes.\n//   BiggestInt     - the biggest signed integer type.\n//\n// Command-line utilities:\n//   GTEST_FLAG()       - references a flag.\n//   GTEST_DECLARE_*()  - declares a flag.\n//   GTEST_DEFINE_*()   - defines a flag.\n//   GetArgvs()         - returns the command line as a vector of strings.\n//\n// Environment variable utilities:\n//   GetEnv()             - gets the value of an environment variable.\n//   BoolFromGTestEnv()   - parses a bool environment variable.\n//   Int32FromGTestEnv()  - parses an Int32 environment variable.\n//   StringFromGTestEnv() - parses a string environment variable.\n\n#include <ctype.h>   // for isspace, etc\n#include <stddef.h>  // for ptrdiff_t\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#ifndef _WIN32_WCE\n# include <sys/types.h>\n# include <sys/stat.h>\n#endif  // !_WIN32_WCE\n\n#include <iostream>  // NOLINT\n#include <sstream>  // NOLINT\n#include <string>  // NOLINT\n\n#define GTEST_DEV_EMAIL_ \"googletestframework@@googlegroups.com\"\n#define GTEST_FLAG_PREFIX_ \"gtest_\"\n#define GTEST_FLAG_PREFIX_DASH_ \"gtest-\"\n#define GTEST_FLAG_PREFIX_UPPER_ \"GTEST_\"\n#define GTEST_NAME_ \"Google Test\"\n#define GTEST_PROJECT_URL_ \"http://code.google.com/p/googletest/\"\n\n// Determines the version of gcc that is used to compile this.\n#ifdef __GNUC__\n// 40302 means version 4.3.2.\n# define GTEST_GCC_VER_ \\\n    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)\n#endif  // __GNUC__\n\n// Determines the platform on which Google Test is compiled.\n#ifdef __CYGWIN__\n# define GTEST_OS_CYGWIN 1\n#elif defined __SYMBIAN32__\n# define GTEST_OS_SYMBIAN 1\n#elif defined _WIN32\n# define GTEST_OS_WINDOWS 1\n# ifdef _WIN32_WCE\n#  define GTEST_OS_WINDOWS_MOBILE 1\n# elif defined(__MINGW__) || defined(__MINGW32__)\n#  define GTEST_OS_WINDOWS_MINGW 1\n# else\n#  define GTEST_OS_WINDOWS_DESKTOP 1\n# endif  // _WIN32_WCE\n#elif defined __APPLE__\n# define GTEST_OS_MAC 1\n#elif defined __linux__\n# define GTEST_OS_LINUX 1\n# ifdef ANDROID\n#  define GTEST_OS_LINUX_ANDROID 1\n# endif  // ANDROID\n#elif defined __MVS__\n# define GTEST_OS_ZOS 1\n#elif defined(__sun) && defined(__SVR4)\n# define GTEST_OS_SOLARIS 1\n#elif defined(_AIX)\n# define GTEST_OS_AIX 1\n#elif defined(__hpux)\n# define GTEST_OS_HPUX 1\n#elif defined __native_client__\n# define GTEST_OS_NACL 1\n#endif  // __CYGWIN__\n\n// Brings in definitions for functions used in the testing::internal::posix\n// namespace (read, write, close, chdir, isatty, stat). We do not currently\n// use them on Windows Mobile.\n#if !GTEST_OS_WINDOWS\n// This assumes that non-Windows OSes provide unistd.h. For OSes where this\n// is not the case, we need to include headers that provide the functions\n// mentioned above.\n# include <unistd.h>\n# if !GTEST_OS_NACL\n// TODO(vladl@google.com): Remove this condition when Native Client SDK adds\n// strings.h (tracked in\n// http://code.google.com/p/nativeclient/issues/detail?id=1175).\n#  include <strings.h>  // Native Client doesn't provide strings.h.\n# endif\n#elif !GTEST_OS_WINDOWS_MOBILE\n# include <direct.h>\n# include <io.h>\n#endif\n\n#if defined(_MSC_VER)\n# include <windows.h>\n#endif\n\n// Defines this to true iff Google Test can use POSIX regular expressions.\n#ifndef GTEST_HAS_POSIX_RE\n# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS)\n#endif\n\n#if GTEST_HAS_POSIX_RE\n\n// On some platforms, <regex.h> needs someone to define size_t, and\n// won't compile otherwise.  We can #include it here as we already\n// included <stdlib.h>, which is guaranteed to define size_t through\n// <stddef.h>.\n# include <regex.h>  // NOLINT\n\n# define GTEST_USES_POSIX_RE 1\n\n#elif GTEST_OS_WINDOWS\n\n// <regex.h> is not available on Windows.  Use our own simple regex\n// implementation instead.\n# define GTEST_USES_SIMPLE_RE 1\n\n#else\n\n// <regex.h> may not be available on this platform.  Use our own\n// simple regex implementation instead.\n# define GTEST_USES_SIMPLE_RE 1\n\n#endif  // GTEST_HAS_POSIX_RE\n\n#ifndef GTEST_HAS_EXCEPTIONS\n// The user didn't tell us whether exceptions are enabled, so we need\n// to figure it out.\n# if defined(_MSC_VER) || defined(__BORLANDC__)\n// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS\n// macro to enable exceptions, so we'll do the same.\n// Assumes that exceptions are enabled by default.\n#  ifndef _HAS_EXCEPTIONS\n#   define _HAS_EXCEPTIONS 1\n#  endif  // _HAS_EXCEPTIONS\n#  define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS\n# elif defined(__GNUC__) && __EXCEPTIONS\n// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.\n#  define GTEST_HAS_EXCEPTIONS 1\n# elif defined(__SUNPRO_CC)\n// Sun Pro CC supports exceptions.  However, there is no compile-time way of\n// detecting whether they are enabled or not.  Therefore, we assume that\n// they are enabled unless the user tells us otherwise.\n#  define GTEST_HAS_EXCEPTIONS 1\n# elif defined(__IBMCPP__) && __EXCEPTIONS\n// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.\n#  define GTEST_HAS_EXCEPTIONS 1\n# elif defined(__HP_aCC)\n// Exception handling is in effect by default in HP aCC compiler. It has to\n// be turned of by +noeh compiler option if desired.\n#  define GTEST_HAS_EXCEPTIONS 1\n# else\n// For other compilers, we assume exceptions are disabled to be\n// conservative.\n#  define GTEST_HAS_EXCEPTIONS 0\n# endif  // defined(_MSC_VER) || defined(__BORLANDC__)\n#endif  // GTEST_HAS_EXCEPTIONS\n\n#if !defined(GTEST_HAS_STD_STRING)\n// Even though we don't use this macro any longer, we keep it in case\n// some clients still depend on it.\n# define GTEST_HAS_STD_STRING 1\n#elif !GTEST_HAS_STD_STRING\n// The user told us that ::std::string isn't available.\n# error \"Google Test cannot be used where ::std::string isn't available.\"\n#endif  // !defined(GTEST_HAS_STD_STRING)\n\n#ifndef GTEST_HAS_GLOBAL_STRING\n// The user didn't tell us whether ::string is available, so we need\n// to figure it out.\n\n# define GTEST_HAS_GLOBAL_STRING 0\n\n#endif  // GTEST_HAS_GLOBAL_STRING\n\n#ifndef GTEST_HAS_STD_WSTRING\n// The user didn't tell us whether ::std::wstring is available, so we need\n// to figure it out.\n// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring\n//   is available.\n\n// Cygwin 1.7 and below doesn't support ::std::wstring.\n// Solaris' libc++ doesn't support it either.  Android has\n// no support for it at least as recent as Froyo (2.2).\n# define GTEST_HAS_STD_WSTRING \\\n    (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))\n\n#endif  // GTEST_HAS_STD_WSTRING\n\n#ifndef GTEST_HAS_GLOBAL_WSTRING\n// The user didn't tell us whether ::wstring is available, so we need\n// to figure it out.\n# define GTEST_HAS_GLOBAL_WSTRING \\\n    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n// Determines whether RTTI is available.\n#ifndef GTEST_HAS_RTTI\n// The user didn't tell us whether RTTI is enabled, so we need to\n// figure it out.\n\n# ifdef _MSC_VER\n\n#  ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.\n#   define GTEST_HAS_RTTI 1\n#  else\n#   define GTEST_HAS_RTTI 0\n#  endif\n\n// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.\n# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)\n\n#  ifdef __GXX_RTTI\n#   define GTEST_HAS_RTTI 1\n#  else\n#   define GTEST_HAS_RTTI 0\n#  endif  // __GXX_RTTI\n\n// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if\n// both the typeid and dynamic_cast features are present.\n# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)\n\n#  ifdef __RTTI_ALL__\n#   define GTEST_HAS_RTTI 1\n#  else\n#   define GTEST_HAS_RTTI 0\n#  endif\n\n# else\n\n// For all other compilers, we assume RTTI is enabled.\n#  define GTEST_HAS_RTTI 1\n\n# endif  // _MSC_VER\n\n#endif  // GTEST_HAS_RTTI\n\n// It's this header's responsibility to #include <typeinfo> when RTTI\n// is enabled.\n#if GTEST_HAS_RTTI\n# include <typeinfo>\n#endif\n\n// Determines whether Google Test can use the pthreads library.\n#ifndef GTEST_HAS_PTHREAD\n// The user didn't tell us explicitly, so we assume pthreads support is\n// available on Linux and Mac.\n//\n// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0\n// to your compiler flags.\n# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX)\n#endif  // GTEST_HAS_PTHREAD\n\n#if GTEST_HAS_PTHREAD\n// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is\n// true.\n# include <pthread.h>  // NOLINT\n\n// For timespec and nanosleep, used below.\n# include <time.h>  // NOLINT\n#endif\n\n// Determines whether Google Test can use tr1/tuple.  You can define\n// this macro to 0 to prevent Google Test from using tuple (any\n// feature depending on tuple with be disabled in this mode).\n#ifndef GTEST_HAS_TR1_TUPLE\n// The user didn't tell us not to do it, so we assume it's OK.\n# define GTEST_HAS_TR1_TUPLE 0\n#endif  // GTEST_HAS_TR1_TUPLE\n\n// Determines whether Google Test's own tr1 tuple implementation\n// should be used.\n#ifndef GTEST_USE_OWN_TR1_TUPLE\n// The user didn't tell us, so we need to figure it out.\n\n// We use our own TR1 tuple if we aren't sure the user has an\n// implementation of it already.  At this time, GCC 4.0.0+ and MSVC\n// 2010 are the only mainstream compilers that come with a TR1 tuple\n// implementation.  NVIDIA's CUDA NVCC compiler pretends to be GCC by\n// defining __GNUC__ and friends, but cannot compile GCC's tuple\n// implementation.  MSVC 2008 (9.0) provides TR1 tuple in a 323 MB\n// Feature Pack download, which we cannot assume the user has.\n# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \\\n    || _MSC_VER >= 1600\n#  define GTEST_USE_OWN_TR1_TUPLE 0\n# else\n#  define GTEST_USE_OWN_TR1_TUPLE 1\n# endif\n\n#endif  // GTEST_USE_OWN_TR1_TUPLE\n\n// To avoid conditional compilation everywhere, we make it\n// gtest-port.h's responsibility to #include the header implementing\n// tr1/tuple.\n#if GTEST_HAS_TR1_TUPLE\n\n# if GTEST_USE_OWN_TR1_TUPLE\n// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!\n\n// Copyright 2009 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n// Implements a subset of TR1 tuple needed by Google Test and Google Mock.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\n\n#include <utility>  // For ::std::pair.\n\n// The compiler used in Symbian has a bug that prevents us from declaring the\n// tuple template as a friend (it complains that tuple is redefined).  This\n// hack bypasses the bug by declaring the members that should otherwise be\n// private as public.\n// Sun Studio versions < 12 also have the above bug.\n#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:\n#else\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \\\n    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \\\n   private:\n#endif\n\n// GTEST_n_TUPLE_(T) is the type of an n-tuple.\n#define GTEST_0_TUPLE_(T) tuple<>\n#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \\\n    void, void, void>\n#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \\\n    void, void, void>\n#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \\\n    void, void, void>\n#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \\\n    void, void, void>\n#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \\\n    void, void, void>\n#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \\\n    void, void, void>\n#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\n    void, void, void>\n#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\n    T##7, void, void>\n#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\n    T##7, T##8, void>\n#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\n    T##7, T##8, T##9>\n\n// GTEST_n_TYPENAMES_(T) declares a list of n typenames.\n#define GTEST_0_TYPENAMES_(T)\n#define GTEST_1_TYPENAMES_(T) typename T##0\n#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1\n#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2\n#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3\n#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4\n#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4, typename T##5\n#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4, typename T##5, typename T##6\n#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7\n#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4, typename T##5, typename T##6, \\\n    typename T##7, typename T##8\n#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\n    typename T##3, typename T##4, typename T##5, typename T##6, \\\n    typename T##7, typename T##8, typename T##9\n\n// In theory, defining stuff in the ::std namespace is undefined\n// behavior.  We can do this as we are playing the role of a standard\n// library vendor.\nnamespace std {\nnamespace tr1 {\n\ntemplate <typename T0 = void, typename T1 = void, typename T2 = void,\n    typename T3 = void, typename T4 = void, typename T5 = void,\n    typename T6 = void, typename T7 = void, typename T8 = void,\n    typename T9 = void>\nclass tuple;\n\n// Anything in namespace gtest_internal is Google Test's INTERNAL\n// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.\nnamespace gtest_internal {\n\n// ByRef<T>::type is T if T is a reference; otherwise it's const T&.\ntemplate <typename T>\nstruct ByRef { typedef const T& type; };  // NOLINT\ntemplate <typename T>\nstruct ByRef<T&> { typedef T& type; };  // NOLINT\n\n// A handy wrapper for ByRef.\n#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type\n\n// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This\n// is the same as tr1::add_reference<T>::type.\ntemplate <typename T>\nstruct AddRef { typedef T& type; };  // NOLINT\ntemplate <typename T>\nstruct AddRef<T&> { typedef T& type; };  // NOLINT\n\n// A handy wrapper for AddRef.\n#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type\n\n// A helper for implementing get<k>().\ntemplate <int k> class Get;\n\n// A helper for implementing tuple_element<k, T>.  kIndexValid is true\n// iff k < the number of fields in tuple type T.\ntemplate <bool kIndexValid, int kIndex, class Tuple>\nstruct TupleElement;\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };\n\n}  // namespace gtest_internal\n\ntemplate <>\nclass tuple<> {\n public:\n  tuple() {}\n  tuple(const tuple& /* t */)  {}\n  tuple& operator=(const tuple& /* t */) { return *this; }\n};\n\ntemplate <GTEST_1_TYPENAMES_(T)>\nclass GTEST_1_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}\n\n  tuple(const tuple& t) : f0_(t.f0_) {}\n\n  template <GTEST_1_TYPENAMES_(U)>\n  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_1_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_1_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    return *this;\n  }\n\n  T0 f0_;\n};\n\ntemplate <GTEST_2_TYPENAMES_(T)>\nclass GTEST_2_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),\n      f1_(f1) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}\n\n  template <GTEST_2_TYPENAMES_(U)>\n  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}\n  template <typename U0, typename U1>\n  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_2_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n  template <typename U0, typename U1>\n  tuple& operator=(const ::std::pair<U0, U1>& p) {\n    f0_ = p.first;\n    f1_ = p.second;\n    return *this;\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_2_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n};\n\ntemplate <GTEST_3_TYPENAMES_(T)>\nclass GTEST_3_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}\n\n  template <GTEST_3_TYPENAMES_(U)>\n  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_3_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_3_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n};\n\ntemplate <GTEST_4_TYPENAMES_(T)>\nclass GTEST_4_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),\n      f3_(f3) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}\n\n  template <GTEST_4_TYPENAMES_(U)>\n  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_4_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_4_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n};\n\ntemplate <GTEST_5_TYPENAMES_(T)>\nclass GTEST_5_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,\n      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_) {}\n\n  template <GTEST_5_TYPENAMES_(U)>\n  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_5_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_5_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n};\n\ntemplate <GTEST_6_TYPENAMES_(T)>\nclass GTEST_6_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\n      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\n      f5_(f5) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_), f5_(t.f5_) {}\n\n  template <GTEST_6_TYPENAMES_(U)>\n  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_6_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_6_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    f5_ = t.f5_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n  T5 f5_;\n};\n\ntemplate <GTEST_7_TYPENAMES_(T)>\nclass GTEST_7_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\n      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),\n      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}\n\n  template <GTEST_7_TYPENAMES_(U)>\n  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_7_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_7_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    f5_ = t.f5_;\n    f6_ = t.f6_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n  T5 f5_;\n  T6 f6_;\n};\n\ntemplate <GTEST_8_TYPENAMES_(T)>\nclass GTEST_8_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\n      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,\n      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\n      f5_(f5), f6_(f6), f7_(f7) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}\n\n  template <GTEST_8_TYPENAMES_(U)>\n  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_8_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_8_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    f5_ = t.f5_;\n    f6_ = t.f6_;\n    f7_ = t.f7_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n  T5 f5_;\n  T6 f6_;\n  T7 f7_;\n};\n\ntemplate <GTEST_9_TYPENAMES_(T)>\nclass GTEST_9_TUPLE_(T) {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\n      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,\n      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\n      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}\n\n  template <GTEST_9_TYPENAMES_(U)>\n  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_9_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_9_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    f5_ = t.f5_;\n    f6_ = t.f6_;\n    f7_ = t.f7_;\n    f8_ = t.f8_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n  T5 f5_;\n  T6 f6_;\n  T7 f7_;\n  T8 f8_;\n};\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nclass tuple {\n public:\n  template <int k> friend class gtest_internal::Get;\n\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),\n      f9_() {}\n\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\n      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\n      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,\n      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),\n      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}\n\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\n      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}\n\n  template <GTEST_10_TYPENAMES_(U)>\n  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\n      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),\n      f9_(t.f9_) {}\n\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\n\n  template <GTEST_10_TYPENAMES_(U)>\n  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {\n    return CopyFrom(t);\n  }\n\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\n\n  template <GTEST_10_TYPENAMES_(U)>\n  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {\n    f0_ = t.f0_;\n    f1_ = t.f1_;\n    f2_ = t.f2_;\n    f3_ = t.f3_;\n    f4_ = t.f4_;\n    f5_ = t.f5_;\n    f6_ = t.f6_;\n    f7_ = t.f7_;\n    f8_ = t.f8_;\n    f9_ = t.f9_;\n    return *this;\n  }\n\n  T0 f0_;\n  T1 f1_;\n  T2 f2_;\n  T3 f3_;\n  T4 f4_;\n  T5 f5_;\n  T6 f6_;\n  T7 f7_;\n  T8 f8_;\n  T9 f9_;\n};\n\n// 6.1.3.2 Tuple creation functions.\n\n// Known limitations: we don't support passing an\n// std::tr1::reference_wrapper<T> to make_tuple().  And we don't\n// implement tie().\n\ninline tuple<> make_tuple() { return tuple<>(); }\n\ntemplate <GTEST_1_TYPENAMES_(T)>\ninline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {\n  return GTEST_1_TUPLE_(T)(f0);\n}\n\ntemplate <GTEST_2_TYPENAMES_(T)>\ninline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {\n  return GTEST_2_TUPLE_(T)(f0, f1);\n}\n\ntemplate <GTEST_3_TYPENAMES_(T)>\ninline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {\n  return GTEST_3_TUPLE_(T)(f0, f1, f2);\n}\n\ntemplate <GTEST_4_TYPENAMES_(T)>\ninline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3) {\n  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);\n}\n\ntemplate <GTEST_5_TYPENAMES_(T)>\ninline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4) {\n  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);\n}\n\ntemplate <GTEST_6_TYPENAMES_(T)>\ninline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4, const T5& f5) {\n  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);\n}\n\ntemplate <GTEST_7_TYPENAMES_(T)>\ninline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {\n  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);\n}\n\ntemplate <GTEST_8_TYPENAMES_(T)>\ninline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {\n  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);\n}\n\ntemplate <GTEST_9_TYPENAMES_(T)>\ninline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,\n    const T8& f8) {\n  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);\n}\n\ntemplate <GTEST_10_TYPENAMES_(T)>\ninline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\n    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,\n    const T8& f8, const T9& f9) {\n  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);\n}\n\n// 6.1.3.3 Tuple helper classes.\n\ntemplate <typename Tuple> struct tuple_size;\n\ntemplate <GTEST_0_TYPENAMES_(T)>\nstruct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };\n\ntemplate <GTEST_1_TYPENAMES_(T)>\nstruct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };\n\ntemplate <GTEST_2_TYPENAMES_(T)>\nstruct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };\n\ntemplate <GTEST_3_TYPENAMES_(T)>\nstruct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };\n\ntemplate <GTEST_4_TYPENAMES_(T)>\nstruct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };\n\ntemplate <GTEST_5_TYPENAMES_(T)>\nstruct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };\n\ntemplate <GTEST_6_TYPENAMES_(T)>\nstruct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };\n\ntemplate <GTEST_7_TYPENAMES_(T)>\nstruct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };\n\ntemplate <GTEST_8_TYPENAMES_(T)>\nstruct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };\n\ntemplate <GTEST_9_TYPENAMES_(T)>\nstruct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };\n\ntemplate <GTEST_10_TYPENAMES_(T)>\nstruct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };\n\ntemplate <int k, class Tuple>\nstruct tuple_element {\n  typedef typename gtest_internal::TupleElement<\n      k < (tuple_size<Tuple>::value), k, Tuple>::type type;\n};\n\n#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type\n\n// 6.1.3.4 Element access.\n\nnamespace gtest_internal {\n\ntemplate <>\nclass Get<0> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))\n  Field(Tuple& t) { return t.f0_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))\n  ConstField(const Tuple& t) { return t.f0_; }\n};\n\ntemplate <>\nclass Get<1> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))\n  Field(Tuple& t) { return t.f1_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))\n  ConstField(const Tuple& t) { return t.f1_; }\n};\n\ntemplate <>\nclass Get<2> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))\n  Field(Tuple& t) { return t.f2_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))\n  ConstField(const Tuple& t) { return t.f2_; }\n};\n\ntemplate <>\nclass Get<3> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))\n  Field(Tuple& t) { return t.f3_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))\n  ConstField(const Tuple& t) { return t.f3_; }\n};\n\ntemplate <>\nclass Get<4> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))\n  Field(Tuple& t) { return t.f4_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))\n  ConstField(const Tuple& t) { return t.f4_; }\n};\n\ntemplate <>\nclass Get<5> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))\n  Field(Tuple& t) { return t.f5_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))\n  ConstField(const Tuple& t) { return t.f5_; }\n};\n\ntemplate <>\nclass Get<6> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))\n  Field(Tuple& t) { return t.f6_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))\n  ConstField(const Tuple& t) { return t.f6_; }\n};\n\ntemplate <>\nclass Get<7> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))\n  Field(Tuple& t) { return t.f7_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))\n  ConstField(const Tuple& t) { return t.f7_; }\n};\n\ntemplate <>\nclass Get<8> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))\n  Field(Tuple& t) { return t.f8_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))\n  ConstField(const Tuple& t) { return t.f8_; }\n};\n\ntemplate <>\nclass Get<9> {\n public:\n  template <class Tuple>\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))\n  Field(Tuple& t) { return t.f9_; }  // NOLINT\n\n  template <class Tuple>\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))\n  ConstField(const Tuple& t) { return t.f9_; }\n};\n\n}  // namespace gtest_internal\n\ntemplate <int k, GTEST_10_TYPENAMES_(T)>\nGTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))\nget(GTEST_10_TUPLE_(T)& t) {\n  return gtest_internal::Get<k>::Field(t);\n}\n\ntemplate <int k, GTEST_10_TYPENAMES_(T)>\nGTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))\nget(const GTEST_10_TUPLE_(T)& t) {\n  return gtest_internal::Get<k>::ConstField(t);\n}\n\n// 6.1.3.5 Relational operators\n\n// We only implement == and !=, as we don't have a need for the rest yet.\n\nnamespace gtest_internal {\n\n// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the\n// first k fields of t1 equals the first k fields of t2.\n// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if\n// k1 != k2.\ntemplate <int kSize1, int kSize2>\nstruct SameSizeTuplePrefixComparator;\n\ntemplate <>\nstruct SameSizeTuplePrefixComparator<0, 0> {\n  template <class Tuple1, class Tuple2>\n  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {\n    return true;\n  }\n};\n\ntemplate <int k>\nstruct SameSizeTuplePrefixComparator<k, k> {\n  template <class Tuple1, class Tuple2>\n  static bool Eq(const Tuple1& t1, const Tuple2& t2) {\n    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&\n        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);\n  }\n};\n\n}  // namespace gtest_internal\n\ntemplate <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>\ninline bool operator==(const GTEST_10_TUPLE_(T)& t,\n                       const GTEST_10_TUPLE_(U)& u) {\n  return gtest_internal::SameSizeTuplePrefixComparator<\n      tuple_size<GTEST_10_TUPLE_(T)>::value,\n      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);\n}\n\ntemplate <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>\ninline bool operator!=(const GTEST_10_TUPLE_(T)& t,\n                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }\n\n// 6.1.4 Pairs.\n// Unimplemented.\n\n}  // namespace tr1\n}  // namespace std\n\n#undef GTEST_0_TUPLE_\n#undef GTEST_1_TUPLE_\n#undef GTEST_2_TUPLE_\n#undef GTEST_3_TUPLE_\n#undef GTEST_4_TUPLE_\n#undef GTEST_5_TUPLE_\n#undef GTEST_6_TUPLE_\n#undef GTEST_7_TUPLE_\n#undef GTEST_8_TUPLE_\n#undef GTEST_9_TUPLE_\n#undef GTEST_10_TUPLE_\n\n#undef GTEST_0_TYPENAMES_\n#undef GTEST_1_TYPENAMES_\n#undef GTEST_2_TYPENAMES_\n#undef GTEST_3_TYPENAMES_\n#undef GTEST_4_TYPENAMES_\n#undef GTEST_5_TYPENAMES_\n#undef GTEST_6_TYPENAMES_\n#undef GTEST_7_TYPENAMES_\n#undef GTEST_8_TYPENAMES_\n#undef GTEST_9_TYPENAMES_\n#undef GTEST_10_TYPENAMES_\n\n#undef GTEST_DECLARE_TUPLE_AS_FRIEND_\n#undef GTEST_BY_REF_\n#undef GTEST_ADD_REF_\n#undef GTEST_TUPLE_ELEMENT_\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\n# elif GTEST_OS_SYMBIAN\n\n// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to\n// use STLport's tuple implementation, which unfortunately doesn't\n// work as the copy of STLport distributed with Symbian is incomplete.\n// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to\n// use its own tuple implementation.\n#  ifdef BOOST_HAS_TR1_TUPLE\n#   undef BOOST_HAS_TR1_TUPLE\n#  endif  // BOOST_HAS_TR1_TUPLE\n\n// This prevents <boost/tr1/detail/config.hpp>, which defines\n// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.\n#  define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED\n#  include <tuple>\n\n# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)\n// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does\n// not conform to the TR1 spec, which requires the header to be <tuple>.\n\n#  if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302\n// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,\n// which is #included by <tr1/tuple>, to not compile when RTTI is\n// disabled.  _TR1_FUNCTIONAL is the header guard for\n// <tr1/functional>.  Hence the following #define is a hack to prevent\n// <tr1/functional> from being included.\n#   define _TR1_FUNCTIONAL 1\n#   include <tr1/tuple>\n#   undef _TR1_FUNCTIONAL  // Allows the user to #include\n                        // <tr1/functional> if he chooses to.\n#  else\n#   include <tr1/tuple>  // NOLINT\n#  endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302\n\n# else\n// If the compiler is not GCC 4.0+, we assume the user is using a\n// spec-conforming TR1 implementation.\n#  include <tuple>  // NOLINT\n# endif  // GTEST_USE_OWN_TR1_TUPLE\n\n#endif  // GTEST_HAS_TR1_TUPLE\n\n// Determines whether clone(2) is supported.\n// Usually it will only be available on Linux, excluding\n// Linux on the Itanium architecture.\n// Also see http://linux.die.net/man/2/clone.\n#ifndef GTEST_HAS_CLONE\n// The user didn't tell us, so we need to figure it out.\n\n# if GTEST_OS_LINUX && !defined(__ia64__)\n#  define GTEST_HAS_CLONE 1\n# else\n#  define GTEST_HAS_CLONE 0\n# endif  // GTEST_OS_LINUX && !defined(__ia64__)\n\n#endif  // GTEST_HAS_CLONE\n\n// Determines whether to support stream redirection. This is used to test\n// output correctness and to implement death tests.\n#ifndef GTEST_HAS_STREAM_REDIRECTION\n// By default, we assume that stream redirection is supported on all\n// platforms except known mobile ones.\n# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN\n#  define GTEST_HAS_STREAM_REDIRECTION 0\n# else\n#  define GTEST_HAS_STREAM_REDIRECTION 1\n# endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\n// Determines whether to support death tests.\n// Google Test does not support death tests for VC 7.1 and earlier as\n// abort() in a VC 7.1 application compiled as GUI in debug config\n// pops up a dialog window that cannot be suppressed programmatically.\n#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \\\n     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \\\n     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX)\n# define GTEST_HAS_DEATH_TEST 1\n# include <vector>  // NOLINT\n#endif\n\n// We don't support MSVC 7.1 with exceptions disabled now.  Therefore\n// all the compilers we care about are adequate for supporting\n// value-parameterized tests.\n#define GTEST_HAS_PARAM_TEST 1\n\n// Determines whether to support type-driven tests.\n\n// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,\n// Sun Pro CC, IBM Visual Age, and HP aCC support.\n#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \\\n    defined(__IBMCPP__) || defined(__HP_aCC)\n# define GTEST_HAS_TYPED_TEST 1\n# define GTEST_HAS_TYPED_TEST_P 1\n#endif\n\n// Determines whether to support Combine(). This only makes sense when\n// value-parameterized tests are enabled.  The implementation doesn't\n// work on Sun Studio since it doesn't understand templated conversion\n// operators.\n#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)\n# define GTEST_HAS_COMBINE 1\n#endif\n\n// Determines whether the system compiler uses UTF-16 for encoding wide strings.\n#define GTEST_WIDE_STRING_USES_UTF16_ \\\n    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)\n\n// Determines whether test results can be streamed to a socket.\n#if GTEST_OS_LINUX\n# define GTEST_CAN_STREAM_RESULTS_ 1\n#endif\n\n// Defines some utility macros.\n\n// The GNU compiler emits a warning if nested \"if\" statements are followed by\n// an \"else\" statement and braces are not used to explicitly disambiguate the\n// \"else\" binding.  This leads to problems with code like:\n//\n//   if (gate)\n//     ASSERT_*(condition) << \"Some message\";\n//\n// The \"switch (0) case 0:\" idiom is used to suppress this.\n#ifdef __INTEL_COMPILER\n# define GTEST_AMBIGUOUS_ELSE_BLOCKER_\n#else\n# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:  // NOLINT\n#endif\n\n// Use this annotation at the end of a struct/class definition to\n// prevent the compiler from optimizing away instances that are never\n// used.  This is useful when all interesting logic happens inside the\n// c'tor and / or d'tor.  Example:\n//\n//   struct Foo {\n//     Foo() { ... }\n//   } GTEST_ATTRIBUTE_UNUSED_;\n//\n// Also use it after a variable or parameter declaration to tell the\n// compiler the variable/parameter does not have to be used.\n#if defined(__GNUC__) && !defined(COMPILER_ICC)\n# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))\n#else\n# define GTEST_ATTRIBUTE_UNUSED_\n#endif\n\n// A macro to disallow operator=\n// This should be used in the private: declarations for a class.\n#define GTEST_DISALLOW_ASSIGN_(type)\\\n  void operator=(type const &)\n\n// A macro to disallow copy constructor and operator=\n// This should be used in the private: declarations for a class.\n#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\\\n  type(type const &);\\\n  GTEST_DISALLOW_ASSIGN_(type)\n\n// Tell the compiler to warn about unused return values for functions declared\n// with this macro.  The macro should be used on function declarations\n// following the argument list:\n//\n//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;\n#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)\n# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))\n#else\n# define GTEST_MUST_USE_RESULT_\n#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC\n\n// Determine whether the compiler supports Microsoft's Structured Exception\n// Handling.  This is supported by several Windows compilers but generally\n// does not exist on any other system.\n#ifndef GTEST_HAS_SEH\n// The user didn't tell us, so we need to figure it out.\n\n# if defined(_MSC_VER) || defined(__BORLANDC__)\n// These two compilers are known to support SEH.\n#  define GTEST_HAS_SEH 1\n# else\n// Assume no SEH.\n#  define GTEST_HAS_SEH 0\n# endif\n\n#endif  // GTEST_HAS_SEH\n\n#ifdef _MSC_VER\n\n# if GTEST_LINKED_AS_SHARED_LIBRARY\n#  define GTEST_API_ __declspec(dllimport)\n# elif GTEST_CREATE_SHARED_LIBRARY\n#  define GTEST_API_ __declspec(dllexport)\n# endif\n\n#endif  // _MSC_VER\n\n#ifndef GTEST_API_\n# define GTEST_API_\n#endif\n\n#ifdef __GNUC__\n// Ask the compiler to never inline a given function.\n# define GTEST_NO_INLINE_ __attribute__((noinline))\n#else\n# define GTEST_NO_INLINE_\n#endif\n\nnamespace testing {\n\nclass Message;\n\nnamespace internal {\n\nclass String;\n\n// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time\n// expression is true. For example, you could use it to verify the\n// size of a static array:\n//\n//   GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,\n//                         content_type_names_incorrect_size);\n//\n// or to make sure a struct is smaller than a certain size:\n//\n//   GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);\n//\n// The second argument to the macro is the name of the variable. If\n// the expression is false, most compilers will issue a warning/error\n// containing the name of the variable.\n\ntemplate <bool>\nstruct CompileAssert {\n};\n\n#define GTEST_COMPILE_ASSERT_(expr, msg) \\\n  typedef ::testing::internal::CompileAssert<(bool(expr))> \\\n      msg[bool(expr) ? 1 : -1]\n\n// Implementation details of GTEST_COMPILE_ASSERT_:\n//\n// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1\n//   elements (and thus is invalid) when the expression is false.\n//\n// - The simpler definition\n//\n//    #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]\n//\n//   does not work, as gcc supports variable-length arrays whose sizes\n//   are determined at run-time (this is gcc's extension and not part\n//   of the C++ standard).  As a result, gcc fails to reject the\n//   following code with the simple definition:\n//\n//     int foo;\n//     GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is\n//                                      // not a compile-time constant.\n//\n// - By using the type CompileAssert<(bool(expr))>, we ensures that\n//   expr is a compile-time constant.  (Template arguments must be\n//   determined at compile-time.)\n//\n// - The outter parentheses in CompileAssert<(bool(expr))> are necessary\n//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written\n//\n//     CompileAssert<bool(expr)>\n//\n//   instead, these compilers will refuse to compile\n//\n//     GTEST_COMPILE_ASSERT_(5 > 0, some_message);\n//\n//   (They seem to think the \">\" in \"5 > 0\" marks the end of the\n//   template argument list.)\n//\n// - The array size is (bool(expr) ? 1 : -1), instead of simply\n//\n//     ((expr) ? 1 : -1).\n//\n//   This is to avoid running into a bug in MS VC 7.1, which\n//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.\n\n// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.\n//\n// This template is declared, but intentionally undefined.\ntemplate <typename T1, typename T2>\nstruct StaticAssertTypeEqHelper;\n\ntemplate <typename T>\nstruct StaticAssertTypeEqHelper<T, T> {};\n\n#if GTEST_HAS_GLOBAL_STRING\ntypedef ::string string;\n#else\ntypedef ::std::string string;\n#endif  // GTEST_HAS_GLOBAL_STRING\n\n#if GTEST_HAS_GLOBAL_WSTRING\ntypedef ::wstring wstring;\n#elif GTEST_HAS_STD_WSTRING\ntypedef ::std::wstring wstring;\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n// A helper for suppressing warnings on constant condition.  It just\n// returns 'condition'.\nGTEST_API_ bool IsTrue(bool condition);\n\n// Defines scoped_ptr.\n\n// This implementation of scoped_ptr is PARTIAL - it only contains\n// enough stuff to satisfy Google Test's need.\ntemplate <typename T>\nclass scoped_ptr {\n public:\n  typedef T element_type;\n\n  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}\n  ~scoped_ptr() { reset(); }\n\n  T& operator*() const { return *ptr_; }\n  T* operator->() const { return ptr_; }\n  T* get() const { return ptr_; }\n\n  T* release() {\n    T* const ptr = ptr_;\n    ptr_ = NULL;\n    return ptr;\n  }\n\n  void reset(T* p = NULL) {\n    if (p != ptr_) {\n      if (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.\n        delete ptr_;\n      }\n      ptr_ = p;\n    }\n  }\n private:\n  T* ptr_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);\n};\n\n// Defines RE.\n\n// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended\n// Regular Expression syntax.\nclass GTEST_API_ RE {\n public:\n  // A copy constructor is required by the Standard to initialize object\n  // references from r-values.\n  RE(const RE& other) { Init(other.pattern()); }\n\n  // Constructs an RE from a string.\n  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT\n\n#if GTEST_HAS_GLOBAL_STRING\n\n  RE(const ::string& regex) { Init(regex.c_str()); }  // NOLINT\n\n#endif  // GTEST_HAS_GLOBAL_STRING\n\n  RE(const char* regex) { Init(regex); }  // NOLINT\n  ~RE();\n\n  // Returns the string representation of the regex.\n  const char* pattern() const { return pattern_; }\n\n  // FullMatch(str, re) returns true iff regular expression re matches\n  // the entire str.\n  // PartialMatch(str, re) returns true iff regular expression re\n  // matches a substring of str (including str itself).\n  //\n  // TODO(wan@google.com): make FullMatch() and PartialMatch() work\n  // when str contains NUL characters.\n  static bool FullMatch(const ::std::string& str, const RE& re) {\n    return FullMatch(str.c_str(), re);\n  }\n  static bool PartialMatch(const ::std::string& str, const RE& re) {\n    return PartialMatch(str.c_str(), re);\n  }\n\n#if GTEST_HAS_GLOBAL_STRING\n\n  static bool FullMatch(const ::string& str, const RE& re) {\n    return FullMatch(str.c_str(), re);\n  }\n  static bool PartialMatch(const ::string& str, const RE& re) {\n    return PartialMatch(str.c_str(), re);\n  }\n\n#endif  // GTEST_HAS_GLOBAL_STRING\n\n  static bool FullMatch(const char* str, const RE& re);\n  static bool PartialMatch(const char* str, const RE& re);\n\n private:\n  void Init(const char* regex);\n\n  // We use a const char* instead of a string, as Google Test may be used\n  // where string is not available.  We also do not use Google Test's own\n  // String type here, in order to simplify dependencies between the\n  // files.\n  const char* pattern_;\n  bool is_valid_;\n\n#if GTEST_USES_POSIX_RE\n\n  regex_t full_regex_;     // For FullMatch().\n  regex_t partial_regex_;  // For PartialMatch().\n\n#else  // GTEST_USES_SIMPLE_RE\n\n  const char* full_pattern_;  // For FullMatch();\n\n#endif\n\n  GTEST_DISALLOW_ASSIGN_(RE);\n};\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line);\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\n                                                               int line);\n\n// Defines logging utilities:\n//   GTEST_LOG_(severity) - logs messages at the specified severity level. The\n//                          message itself is streamed into the macro.\n//   LogToStderr()  - directs all log messages to stderr.\n//   FlushInfoLog() - flushes informational log messages.\n\nenum GTestLogSeverity {\n  GTEST_INFO,\n  GTEST_WARNING,\n  GTEST_ERROR,\n  GTEST_FATAL\n};\n\n// Formats log entry severity, provides a stream object for streaming the\n// log message, and terminates the message with a newline when going out of\n// scope.\nclass GTEST_API_ GTestLog {\n public:\n  GTestLog(GTestLogSeverity severity, const char* file, int line);\n\n  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\n  ~GTestLog();\n\n  ::std::ostream& GetStream() { return ::std::cerr; }\n\n private:\n  const GTestLogSeverity severity_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);\n};\n\n#define GTEST_LOG_(severity) \\\n    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \\\n                                  __FILE__, __LINE__).GetStream()\n\ninline void LogToStderr() {}\ninline void FlushInfoLog() { fflush(NULL); }\n\n// INTERNAL IMPLEMENTATION - DO NOT USE.\n//\n// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition\n// is not satisfied.\n//  Synopsys:\n//    GTEST_CHECK_(boolean_condition);\n//     or\n//    GTEST_CHECK_(boolean_condition) << \"Additional message\";\n//\n//    This checks the condition and if the condition is not satisfied\n//    it prints message about the condition violation, including the\n//    condition itself, plus additional message streamed into it, if any,\n//    and then it aborts the program. It aborts the program irrespective of\n//    whether it is built in the debug mode or not.\n#define GTEST_CHECK_(condition) \\\n    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n    if (::testing::internal::IsTrue(condition)) \\\n      ; \\\n    else \\\n      GTEST_LOG_(FATAL) << \"Condition \" #condition \" failed. \"\n\n// An all-mode assert to verify that the given POSIX-style function\n// call returns 0 (indicating success).  Known limitation: this\n// doesn't expand to a balanced 'if' statement, so enclose the macro\n// in {} if you need to use it as the only statement in an 'if'\n// branch.\n#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \\\n  if (const int gtest_error = (posix_call)) \\\n    GTEST_LOG_(FATAL) << #posix_call << \"failed with error \" \\\n                      << gtest_error\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Use ImplicitCast_ as a safe version of static_cast for upcasting in\n// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a\n// const Foo*).  When you use ImplicitCast_, the compiler checks that\n// the cast is safe.  Such explicit ImplicitCast_s are necessary in\n// surprisingly many situations where C++ demands an exact type match\n// instead of an argument type convertable to a target type.\n//\n// The syntax for using ImplicitCast_ is the same as for static_cast:\n//\n//   ImplicitCast_<ToType>(expr)\n//\n// ImplicitCast_ would have been part of the C++ standard library,\n// but the proposal was submitted too late.  It will probably make\n// its way into the language in the future.\n//\n// This relatively ugly name is intentional. It prevents clashes with\n// similar functions users may have (e.g., implicit_cast). The internal\n// namespace alone is not enough because the function can be found by ADL.\ntemplate<typename To>\ninline To ImplicitCast_(To x) { return x; }\n\n// When you upcast (that is, cast a pointer from type Foo to type\n// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts\n// always succeed.  When you downcast (that is, cast a pointer from\n// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because\n// how do you know the pointer is really of type SubclassOfFoo?  It\n// could be a bare Foo, or of type DifferentSubclassOfFoo.  Thus,\n// when you downcast, you should use this macro.  In debug mode, we\n// use dynamic_cast<> to double-check the downcast is legal (we die\n// if it's not).  In normal mode, we do the efficient static_cast<>\n// instead.  Thus, it's important to test in debug mode to make sure\n// the cast is legal!\n//    This is the only place in the code we should use dynamic_cast<>.\n// In particular, you SHOULDN'T be using dynamic_cast<> in order to\n// do RTTI (eg code like this:\n//    if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);\n//    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);\n// You should design the code some other way not to need this.\n//\n// This relatively ugly name is intentional. It prevents clashes with\n// similar functions users may have (e.g., down_cast). The internal\n// namespace alone is not enough because the function can be found by ADL.\ntemplate<typename To, typename From>  // use like this: DownCast_<T*>(foo);\ninline To DownCast_(From* f) {  // so we only accept pointers\n  // Ensures that To is a sub-type of From *.  This test is here only\n  // for compile-time type checking, and has no overhead in an\n  // optimized build at run-time, as it will be optimized away\n  // completely.\n  if (false) {\n    const To to = NULL;\n    ::testing::internal::ImplicitCast_<From*>(to);\n  }\n\n#if GTEST_HAS_RTTI\n  // RTTI: debug mode only!\n  GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL);\n#endif\n  return static_cast<To>(f);\n}\n\n// Downcasts the pointer of type Base to Derived.\n// Derived must be a subclass of Base. The parameter MUST\n// point to a class of type Derived, not any subclass of it.\n// When RTTI is available, the function performs a runtime\n// check to enforce this.\ntemplate <class Derived, class Base>\nDerived* CheckedDowncastToActualType(Base* base) {\n#if GTEST_HAS_RTTI\n  GTEST_CHECK_(typeid(*base) == typeid(Derived));\n  return dynamic_cast<Derived*>(base);  // NOLINT\n#else\n  return static_cast<Derived*>(base);  // Poor man's downcast.\n#endif\n}\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Defines the stderr capturer:\n//   CaptureStdout     - starts capturing stdout.\n//   GetCapturedStdout - stops capturing stdout and returns the captured string.\n//   CaptureStderr     - starts capturing stderr.\n//   GetCapturedStderr - stops capturing stderr and returns the captured string.\n//\nGTEST_API_ void CaptureStdout();\nGTEST_API_ String GetCapturedStdout();\nGTEST_API_ void CaptureStderr();\nGTEST_API_ String GetCapturedStderr();\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\n\n#if GTEST_HAS_DEATH_TEST\n\n// A copy of all command line arguments.  Set by InitGoogleTest().\nextern ::std::vector<String> g_argvs;\n\n// GTEST_HAS_DEATH_TEST implies we have ::std::string.\nconst ::std::vector<String>& GetArgvs();\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Defines synchronization primitives.\n\n#if GTEST_HAS_PTHREAD\n\n// Sleeps for (roughly) n milli-seconds.  This function is only for\n// testing Google Test's own constructs.  Don't use it in user tests,\n// either directly or indirectly.\ninline void SleepMilliseconds(int n) {\n  const timespec time = {\n    0,                  // 0 seconds.\n    n * 1000L * 1000L,  // And n ms.\n  };\n  nanosleep(&time, NULL);\n}\n\n// Allows a controller thread to pause execution of newly created\n// threads until notified.  Instances of this class must be created\n// and destroyed in the controller thread.\n//\n// This class is only for testing Google Test's own constructs. Do not\n// use it in user tests, either directly or indirectly.\nclass Notification {\n public:\n  Notification() : notified_(false) {}\n\n  // Notifies all threads created with this notification to start. Must\n  // be called from the controller thread.\n  void Notify() { notified_ = true; }\n\n  // Blocks until the controller thread notifies. Must be called from a test\n  // thread.\n  void WaitForNotification() {\n    while(!notified_) {\n      SleepMilliseconds(10);\n    }\n  }\n\n private:\n  volatile bool notified_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);\n};\n\n// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.\n// Consequently, it cannot select a correct instantiation of ThreadWithParam\n// in order to call its Run(). Introducing ThreadWithParamBase as a\n// non-templated base class for ThreadWithParam allows us to bypass this\n// problem.\nclass ThreadWithParamBase {\n public:\n  virtual ~ThreadWithParamBase() {}\n  virtual void Run() = 0;\n};\n\n// pthread_create() accepts a pointer to a function type with the C linkage.\n// According to the Standard (7.5/1), function types with different linkages\n// are different even if they are otherwise identical.  Some compilers (for\n// example, SunStudio) treat them as different types.  Since class methods\n// cannot be defined with C-linkage we need to define a free C-function to\n// pass into pthread_create().\nextern \"C\" inline void* ThreadFuncWithCLinkage(void* thread) {\n  static_cast<ThreadWithParamBase*>(thread)->Run();\n  return NULL;\n}\n\n// Helper class for testing Google Test's multi-threading constructs.\n// To use it, write:\n//\n//   void ThreadFunc(int param) { /* Do things with param */ }\n//   Notification thread_can_start;\n//   ...\n//   // The thread_can_start parameter is optional; you can supply NULL.\n//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);\n//   thread_can_start.Notify();\n//\n// These classes are only for testing Google Test's own constructs. Do\n// not use them in user tests, either directly or indirectly.\ntemplate <typename T>\nclass ThreadWithParam : public ThreadWithParamBase {\n public:\n  typedef void (*UserThreadFunc)(T);\n\n  ThreadWithParam(\n      UserThreadFunc func, T param, Notification* thread_can_start)\n      : func_(func),\n        param_(param),\n        thread_can_start_(thread_can_start),\n        finished_(false) {\n    ThreadWithParamBase* const base = this;\n    // The thread can be created only after all fields except thread_\n    // have been initialized.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));\n  }\n  ~ThreadWithParam() { Join(); }\n\n  void Join() {\n    if (!finished_) {\n      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));\n      finished_ = true;\n    }\n  }\n\n  virtual void Run() {\n    if (thread_can_start_ != NULL)\n      thread_can_start_->WaitForNotification();\n    func_(param_);\n  }\n\n private:\n  const UserThreadFunc func_;  // User-supplied thread function.\n  const T param_;  // User-supplied parameter to the thread function.\n  // When non-NULL, used to block execution until the controller thread\n  // notifies.\n  Notification* const thread_can_start_;\n  bool finished_;  // true iff we know that the thread function has finished.\n  pthread_t thread_;  // The native thread object.\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);\n};\n\n// MutexBase and Mutex implement mutex on pthreads-based platforms. They\n// are used in conjunction with class MutexLock:\n//\n//   Mutex mutex;\n//   ...\n//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end\n//                            // of the current scope.\n//\n// MutexBase implements behavior for both statically and dynamically\n// allocated mutexes.  Do not use MutexBase directly.  Instead, write\n// the following to define a static mutex:\n//\n//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);\n//\n// You can forward declare a static mutex like this:\n//\n//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);\n//\n// To create a dynamic mutex, just define an object of type Mutex.\nclass MutexBase {\n public:\n  // Acquires this mutex.\n  void Lock() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));\n    owner_ = pthread_self();\n  }\n\n  // Releases this mutex.\n  void Unlock() {\n    // We don't protect writing to owner_ here, as it's the caller's\n    // responsibility to ensure that the current thread holds the\n    // mutex when this is called.\n    owner_ = 0;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));\n  }\n\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\n  // with high probability.\n  void AssertHeld() const {\n    GTEST_CHECK_(owner_ == pthread_self())\n        << \"The current thread is not holding the mutex @\" << this;\n  }\n\n  // A static mutex may be used before main() is entered.  It may even\n  // be used before the dynamic initialization stage.  Therefore we\n  // must be able to initialize a static mutex object at link time.\n  // This means MutexBase has to be a POD and its member variables\n  // have to be public.\n public:\n  pthread_mutex_t mutex_;  // The underlying pthread mutex.\n  pthread_t owner_;  // The thread holding the mutex; 0 means no one holds it.\n};\n\n// Forward-declares a static mutex.\n# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n    extern ::testing::internal::MutexBase mutex\n\n// Defines and statically (i.e. at link time) initializes a static mutex.\n# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\n    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }\n\n// The Mutex class can only be used for mutexes created at runtime. It\n// shares its API with MutexBase otherwise.\nclass Mutex : public MutexBase {\n public:\n  Mutex() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));\n    owner_ = 0;\n  }\n  ~Mutex() {\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));\n  }\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);\n};\n\n// We cannot name this class MutexLock as the ctor declaration would\n// conflict with a macro named MutexLock, which is defined on some\n// platforms.  Hence the typedef trick below.\nclass GTestMutexLock {\n public:\n  explicit GTestMutexLock(MutexBase* mutex)\n      : mutex_(mutex) { mutex_->Lock(); }\n\n  ~GTestMutexLock() { mutex_->Unlock(); }\n\n private:\n  MutexBase* const mutex_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);\n};\n\ntypedef GTestMutexLock MutexLock;\n\n// Helpers for ThreadLocal.\n\n// pthread_key_create() requires DeleteThreadLocalValue() to have\n// C-linkage.  Therefore it cannot be templatized to access\n// ThreadLocal<T>.  Hence the need for class\n// ThreadLocalValueHolderBase.\nclass ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() {}\n};\n\n// Called by pthread to delete thread-local data stored by\n// pthread_setspecific().\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\n}\n\n// Implements thread-local storage on pthreads-based systems.\n//\n//   // Thread 1\n//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.\n//\n//   // Thread 2\n//   tl.set(150);  // Changes the value for thread 2 only.\n//   EXPECT_EQ(150, tl.get());\n//\n//   // Thread 1\n//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.\n//   tl.set(200);\n//   EXPECT_EQ(200, tl.get());\n//\n// The template type argument T must have a public copy constructor.\n// In addition, the default ThreadLocal constructor requires T to have\n// a public default constructor.\n//\n// An object managed for a thread by a ThreadLocal instance is deleted\n// when the thread exits.  Or, if the ThreadLocal instance dies in\n// that thread, when the ThreadLocal dies.  It's the user's\n// responsibility to ensure that all other threads using a ThreadLocal\n// have exited when it dies, or the per-thread objects for those\n// threads will not be deleted.\n//\n// Google Test only uses global ThreadLocal objects.  That means they\n// will die after main() has returned.  Therefore, no per-thread\n// object managed by Google Test will be leaked as long as all threads\n// using Google Test have exited when main() returns.\ntemplate <typename T>\nclass ThreadLocal {\n public:\n  ThreadLocal() : key_(CreateKey()),\n                  default_() {}\n  explicit ThreadLocal(const T& value) : key_(CreateKey()),\n                                         default_(value) {}\n\n  ~ThreadLocal() {\n    // Destroys the managed object for the current thread, if any.\n    DeleteThreadLocalValue(pthread_getspecific(key_));\n\n    // Releases resources associated with the key.  This will *not*\n    // delete managed objects for other threads.\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));\n  }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of type T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);\n  };\n\n  static pthread_key_t CreateKey() {\n    pthread_key_t key;\n    // When a thread exits, DeleteThreadLocalValue() will be called on\n    // the object managed for that thread.\n    GTEST_CHECK_POSIX_SUCCESS_(\n        pthread_key_create(&key, &DeleteThreadLocalValue));\n    return key;\n  }\n\n  T* GetOrCreateValue() const {\n    ThreadLocalValueHolderBase* const holder =\n        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));\n    if (holder != NULL) {\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\n    }\n\n    ValueHolder* const new_holder = new ValueHolder(default_);\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));\n    return new_holder->pointer();\n  }\n\n  // A key pthreads uses for looking up per-thread values.\n  const pthread_key_t key_;\n  const T default_;  // The default value for each thread.\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);\n};\n\n# define GTEST_IS_THREADSAFE 1\n\n#else  // GTEST_HAS_PTHREAD\n\n// A dummy implementation of synchronization primitives (mutex, lock,\n// and thread-local variable).  Necessary for compiling Google Test where\n// mutex is not supported - using Google Test in multiple threads is not\n// supported on such platforms.\n\nclass Mutex {\n public:\n  Mutex():owner_(0), handle_() \n  {\n    ::InitializeCriticalSection(&handle_);\n  }\n  \n  ~Mutex()\n  {\n    ::DeleteCriticalSection(&handle_);\n  }\n  \n  void Lock() \n  {\n    ::EnterCriticalSection(&handle_);\n    owner_ = ::GetCurrentThreadId();\n  }\n  \n  void Unlock() \n  {\n    ::LeaveCriticalSection(&handle_);\n    owner_ = 0;\n  }\n  \n // Does nothing if the current thread holds the mutex. Otherwise, crashes\n// with high probability.\n  void AssertHeld() const {\n    GTEST_CHECK_(owner_ == ::GetCurrentThreadId())\n       << \"The current thread is not holding the mutex @\" << this;\n  }\n  \n  private:\n  DWORD              owner_;\n  CRITICAL_SECTION   handle_;\n};\n\n# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\n  static ::testing::internal::Mutex mutex\n\n# define GTEST_DEFINE_STATIC_MUTEX_(mutex)\n\nclass GTestMutexLock {\n public:\n explicit GTestMutexLock(Mutex* inMutex) : mutex_(inMutex) {\n   mutex_->Lock();\n }\n\n ~GTestMutexLock() {\n   mutex_->Unlock();\n }\n private:\n Mutex* mutex_;\n};\n\ntypedef GTestMutexLock MutexLock;\n\nclass ThreadLocalValueHolderBase {\n public:\n  virtual ~ThreadLocalValueHolderBase() {}\n};\n\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\n}\n\n// Implements thread-local storage on windows system.\ntemplate <typename T>\nclass ThreadLocal {\n public:\n  ThreadLocal() : key_(CreateKey()),\n                  default_() {}\n  explicit ThreadLocal(const T& value) : key_(CreateKey()),\n                                         default_(value) {}\n\n  ~ThreadLocal() {\n    // Destroys the managed object for the current thread, if any.\n    DeleteThreadLocalValue(TlsGetValue(key_));\n\n    // Releases resources associated with the key.  This will *not*\n    // delete managed objects for other threads.\n    GTEST_CHECK_(TlsFree(key_) > 0);\n  }\n\n  T* pointer() { return GetOrCreateValue(); }\n  const T* pointer() const { return GetOrCreateValue(); }\n  const T& get() const { return *pointer(); }\n  void set(const T& value) { *pointer() = value; }\n\n private:\n  // Holds a value of type T.\n  class ValueHolder : public ThreadLocalValueHolderBase {\n   public:\n    explicit ValueHolder(const T& value) : value_(value) {}\n\n    T* pointer() { return &value_; }\n\n   private:\n    T value_;\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);\n  };\n\n  static DWORD CreateKey() {\n    DWORD key;\n    // When a thread exits, DeleteThreadLocalValue() will be called on\n    // the object managed for that thread.\n    GTEST_CHECK_((key = TlsAlloc()) != TLS_OUT_OF_INDEXES);\n    return key;\n  }\n\n  T* GetOrCreateValue() const {\n    ThreadLocalValueHolderBase* const holder =\n        static_cast<ThreadLocalValueHolderBase*>(TlsGetValue(key_));\n    if (holder != NULL) {\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\n    }\n\n    ValueHolder* const new_holder = new ValueHolder(default_);\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\n    GTEST_CHECK_(TlsSetValue(key_, holder_base) != 0);\n    return new_holder->pointer();\n  }\n\n  // A key pthreads uses for looking up per-thread values.\n  const DWORD key_;\n  const T default_;  // The default value for each thread.\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);\n};\n\n// The above synchronization primitives have dummy implementations.\n// Therefore Google Test is not thread-safe.\n# define GTEST_IS_THREADSAFE 0\n\n#endif  // GTEST_HAS_PTHREAD\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nGTEST_API_ size_t GetThreadCount();\n\n// Passing non-POD classes through ellipsis (...) crashes the ARM\n// compiler and generates a warning in Sun Studio.  The Nokia Symbian\n// and the IBM XL C/C++ compiler try to instantiate a copy constructor\n// for objects passed through ellipsis (...), failing for uncopyable\n// objects.  We define this to ensure that only POD is passed through\n// ellipsis on these systems.\n#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)\n// We lose support for NULL detection where the compiler doesn't like\n// passing non-POD classes through ellipsis (...).\n# define GTEST_ELLIPSIS_NEEDS_POD_ 1\n#else\n# define GTEST_CAN_COMPARE_NULL 1\n#endif\n\n// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between\n// const T& and const T* in a function template.  These compilers\n// _can_ decide between class template specializations for T and T*,\n// so a tr1::type_traits-like is_pointer works.\n#if defined(__SYMBIAN32__) || defined(__IBMCPP__)\n# define GTEST_NEEDS_IS_POINTER_ 1\n#endif\n\ntemplate <bool bool_value>\nstruct bool_constant {\n  typedef bool_constant<bool_value> type;\n  static const bool value = bool_value;\n};\ntemplate <bool bool_value> const bool bool_constant<bool_value>::value;\n\ntypedef bool_constant<false> false_type;\ntypedef bool_constant<true> true_type;\n\ntemplate <typename T>\nstruct is_pointer : public false_type {};\n\ntemplate <typename T>\nstruct is_pointer<T*> : public true_type {};\n\ntemplate <typename Iterator>\nstruct IteratorTraits {\n  typedef typename Iterator::value_type value_type;\n};\n\ntemplate <typename T>\nstruct IteratorTraits<T*> {\n  typedef T value_type;\n};\n\ntemplate <typename T>\nstruct IteratorTraits<const T*> {\n  typedef T value_type;\n};\n\n#if GTEST_OS_WINDOWS\n# define GTEST_PATH_SEP_ \"\\\\\"\n# define GTEST_HAS_ALT_PATH_SEP_ 1\n// The biggest signed integer type the compiler supports.\ntypedef __int64 BiggestInt;\n#else\n# define GTEST_PATH_SEP_ \"/\"\n# define GTEST_HAS_ALT_PATH_SEP_ 0\ntypedef long long BiggestInt;  // NOLINT\n#endif  // GTEST_OS_WINDOWS\n\n// Utilities for char.\n\n// isspace(int ch) and friends accept an unsigned char or EOF.  char\n// may be signed, depending on the compiler (or compiler flags).\n// Therefore we need to cast a char to unsigned char before calling\n// isspace(), etc.\n\ninline bool IsAlpha(char ch) {\n  return isalpha(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsAlNum(char ch) {\n  return isalnum(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsDigit(char ch) {\n  return isdigit(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsLower(char ch) {\n  return islower(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsSpace(char ch) {\n  return isspace(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsUpper(char ch) {\n  return isupper(static_cast<unsigned char>(ch)) != 0;\n}\ninline bool IsXDigit(char ch) {\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\n}\n\ninline char ToLower(char ch) {\n  return static_cast<char>(tolower(static_cast<unsigned char>(ch)));\n}\ninline char ToUpper(char ch) {\n  return static_cast<char>(toupper(static_cast<unsigned char>(ch)));\n}\n\n// The testing::internal::posix namespace holds wrappers for common\n// POSIX functions.  These wrappers hide the differences between\n// Windows/MSVC and POSIX systems.  Since some compilers define these\n// standard functions as macros, the wrapper cannot have the same name\n// as the wrapped function.\n\nnamespace posix {\n\n// Functions with a different name on Windows.\n\n#if GTEST_OS_WINDOWS\n\ntypedef struct _stat StatStruct;\n\n# ifdef __BORLANDC__\ninline int IsATTY(int fd) { return isatty(fd); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return stricmp(s1, s2);\n}\ninline char* StrDup(const char* src) { return strdup(src); }\n# else  // !__BORLANDC__\n#  if GTEST_OS_WINDOWS_MOBILE\ninline int IsATTY(int /* fd */) { return 0; }\n#  else\ninline int IsATTY(int fd) { return _isatty(fd); }\n#  endif  // GTEST_OS_WINDOWS_MOBILE\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return _stricmp(s1, s2);\n}\ninline char* StrDup(const char* src) { return _strdup(src); }\n# endif  // __BORLANDC__\n\n# if GTEST_OS_WINDOWS_MOBILE\ninline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }\n// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this\n// time and thus not defined there.\n# else\ninline int FileNo(FILE* file) { return _fileno(file); }\ninline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }\ninline int RmDir(const char* dir) { return _rmdir(dir); }\ninline bool IsDir(const StatStruct& st) {\n  return (_S_IFDIR & st.st_mode) != 0;\n}\n# endif  // GTEST_OS_WINDOWS_MOBILE\n\n#else\n\ntypedef struct stat StatStruct;\n\ninline int FileNo(FILE* file) { return fileno(file); }\ninline int IsATTY(int fd) { return isatty(fd); }\ninline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }\ninline int StrCaseCmp(const char* s1, const char* s2) {\n  return strcasecmp(s1, s2);\n}\ninline char* StrDup(const char* src) { return strdup(src); }\ninline int RmDir(const char* dir) { return rmdir(dir); }\ninline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }\n\n#endif  // GTEST_OS_WINDOWS\n\n// Functions deprecated by MSVC 8.0.\n\n#ifdef _MSC_VER\n// Temporarily disable warning 4996 (deprecated function).\n# pragma warning(push)\n# pragma warning(disable:4996)\n#endif\n\ninline const char* StrNCpy(char* dest, const char* src, size_t n) {\n  return strncpy(dest, src, n);\n}\n\n// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and\n// StrError() aren't needed on Windows CE at this time and thus not\n// defined there.\n\n#if !GTEST_OS_WINDOWS_MOBILE\ninline int ChDir(const char* dir) { return chdir(dir); }\n#endif\ninline FILE* FOpen(const char* path, const char* mode) {\n  return fopen(path, mode);\n}\n#if !GTEST_OS_WINDOWS_MOBILE\ninline FILE *FReopen(const char* path, const char* mode, FILE* stream) {\n  return freopen(path, mode, stream);\n}\ninline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }\n#endif\ninline int FClose(FILE* fp) { return fclose(fp); }\n#if !GTEST_OS_WINDOWS_MOBILE\ninline int Read(int fd, void* buf, unsigned int count) {\n  return static_cast<int>(read(fd, buf, count));\n}\ninline int Write(int fd, const void* buf, unsigned int count) {\n  return static_cast<int>(write(fd, buf, count));\n}\ninline int Close(int fd) { return close(fd); }\ninline const char* StrError(int errnum) { return strerror(errnum); }\n#endif\ninline const char* GetEnv(const char* name) {\n#if GTEST_OS_WINDOWS_MOBILE\n  // We are on Windows CE, which has no environment variables.\n  return NULL;\n#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)\n  // Environment variables which we programmatically clear will be set to the\n  // empty string rather than unset (NULL).  Handle that case.\n  const char* const env = getenv(name);\n  return (env != NULL && env[0] != '\\0') ? env : NULL;\n#else\n  return getenv(name);\n#endif\n}\n\n#ifdef _MSC_VER\n# pragma warning(pop)  // Restores the warning state.\n#endif\n\n#if GTEST_OS_WINDOWS_MOBILE\n// Windows CE has no C library. The abort() function is used in\n// several places in Google Test. This implementation provides a reasonable\n// imitation of standard behaviour.\nvoid Abort();\n#else\ninline void Abort() { abort(); }\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n}  // namespace posix\n\n// The maximum number a BiggestInt can represent.  This definition\n// works no matter BiggestInt is represented in one's complement or\n// two's complement.\n//\n// We cannot rely on numeric_limits in STL, as __int64 and long long\n// are not part of standard C++ and numeric_limits doesn't need to be\n// defined for them.\nconst BiggestInt kMaxBiggestInt =\n    ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));\n\n// This template class serves as a compile-time function from size to\n// type.  It maps a size in bytes to a primitive type with that\n// size. e.g.\n//\n//   TypeWithSize<4>::UInt\n//\n// is typedef-ed to be unsigned int (unsigned integer made up of 4\n// bytes).\n//\n// Such functionality should belong to STL, but I cannot find it\n// there.\n//\n// Google Test uses this class in the implementation of floating-point\n// comparison.\n//\n// For now it only handles UInt (unsigned int) as that's all Google Test\n// needs.  Other types can be easily added in the future if need\n// arises.\ntemplate <size_t size>\nclass TypeWithSize {\n public:\n  // This prevents the user from using TypeWithSize<N> with incorrect\n  // values of N.\n  typedef void UInt;\n};\n\n// The specialization for size 4.\ntemplate <>\nclass TypeWithSize<4> {\n public:\n  // unsigned int has size 4 in both gcc and MSVC.\n  //\n  // As base/basictypes.h doesn't compile on Windows, we cannot use\n  // uint32, uint64, and etc here.\n  typedef int Int;\n  typedef unsigned int UInt;\n};\n\n// The specialization for size 8.\ntemplate <>\nclass TypeWithSize<8> {\n public:\n\n#if GTEST_OS_WINDOWS\n  typedef __int64 Int;\n  typedef unsigned __int64 UInt;\n#else\n  typedef long long Int;  // NOLINT\n  typedef unsigned long long UInt;  // NOLINT\n#endif  // GTEST_OS_WINDOWS\n};\n\n// Integer types of known sizes.\ntypedef TypeWithSize<4>::Int Int32;\ntypedef TypeWithSize<4>::UInt UInt32;\ntypedef TypeWithSize<8>::Int Int64;\ntypedef TypeWithSize<8>::UInt UInt64;\ntypedef TypeWithSize<8>::Int TimeInMillis;  // Represents time in milliseconds.\n\n// Utilities for command line flags and environment variables.\n\n// Macro for referencing flags.\n#define GTEST_FLAG(name) FLAGS_gtest_##name\n\n// Macros for declaring flags.\n#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)\n#define GTEST_DECLARE_int32_(name) \\\n    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)\n#define GTEST_DECLARE_string_(name) \\\n    GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)\n\n// Macros for defining flags.\n#define GTEST_DEFINE_bool_(name, default_val, doc) \\\n    GTEST_API_ bool GTEST_FLAG(name) = (default_val)\n#define GTEST_DEFINE_int32_(name, default_val, doc) \\\n    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)\n#define GTEST_DEFINE_string_(name, default_val, doc) \\\n    GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val)\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes the result\n// to *value and returns true; otherwise leaves *value unchanged and returns\n// false.\n// TODO(chandlerc): Find a better way to refactor flag and environment parsing\n// out of both gtest-port.cc and gtest.cc to avoid exporting this utility\n// function.\nbool ParseInt32(const Message& src_text, const char* str, Int32* value);\n\n// Parses a bool/Int32/string from the environment variable\n// corresponding to the given Google Test flag.\nbool BoolFromGTestEnv(const char* flag, bool default_val);\nGTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);\nconst char* StringFromGTestEnv(const char* flag, const char* default_val);\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\n\n#if GTEST_OS_LINUX\n# include <stdlib.h>\n# include <sys/types.h>\n# include <sys/wait.h>\n# include <unistd.h>\n#endif  // GTEST_OS_LINUX\n\n#include <ctype.h>\n#include <string.h>\n#include <iomanip>\n#include <limits>\n#include <set>\n\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file declares the String class and functions used internally by\n// Google Test.  They are subject to change without notice. They should not used\n// by code external to Google Test.\n//\n// This header file is #included by <gtest/internal/gtest-internal.h>.\n// It should not be #included by other files.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n\n#ifdef __BORLANDC__\n// string.h is not guaranteed to provide strcpy on C++ Builder.\n# include <mem.h>\n#endif\n\n#include <string.h>\n\n#include <string>\n\nnamespace testing {\nnamespace internal {\n\n// String - a UTF-8 string class.\n//\n// For historic reasons, we don't use std::string.\n//\n// TODO(wan@google.com): replace this class with std::string or\n// implement it in terms of the latter.\n//\n// Note that String can represent both NULL and the empty string,\n// while std::string cannot represent NULL.\n//\n// NULL and the empty string are considered different.  NULL is less\n// than anything (including the empty string) except itself.\n//\n// This class only provides minimum functionality necessary for\n// implementing Google Test.  We do not intend to implement a full-fledged\n// string class here.\n//\n// Since the purpose of this class is to provide a substitute for\n// std::string on platforms where it cannot be used, we define a copy\n// constructor and assignment operators such that we don't need\n// conditional compilation in a lot of places.\n//\n// In order to make the representation efficient, the d'tor of String\n// is not virtual.  Therefore DO NOT INHERIT FROM String.\nclass GTEST_API_ String {\n public:\n  // Static utility methods\n\n  // Returns the input enclosed in double quotes if it's not NULL;\n  // otherwise returns \"(null)\".  For example, \"\\\"Hello\\\"\" is returned\n  // for input \"Hello\".\n  //\n  // This is useful for printing a C string in the syntax of a literal.\n  //\n  // Known issue: escape sequences are not handled yet.\n  static String ShowCStringQuoted(const char* c_str);\n\n  // Clones a 0-terminated C string, allocating memory using new.  The\n  // caller is responsible for deleting the return value using\n  // delete[].  Returns the cloned string, or NULL if the input is\n  // NULL.\n  //\n  // This is different from strdup() in string.h, which allocates\n  // memory using malloc().\n  static const char* CloneCString(const char* c_str);\n\n#if GTEST_OS_WINDOWS_MOBILE\n  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be\n  // able to pass strings to Win32 APIs on CE we need to convert them\n  // to 'Unicode', UTF-16.\n\n  // Creates a UTF-16 wide string from the given ANSI string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the wide string, or NULL if the\n  // input is NULL.\n  //\n  // The wide string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static LPCWSTR AnsiToUtf16(const char* c_str);\n\n  // Creates an ANSI string from the given wide string, allocating\n  // memory using new. The caller is responsible for deleting the return\n  // value using delete[]. Returns the ANSI string, or NULL if the\n  // input is NULL.\n  //\n  // The returned string is created using the ANSI codepage (CP_ACP) to\n  // match the behaviour of the ANSI versions of Win32 calls and the\n  // C runtime.\n  static const char* Utf16ToAnsi(LPCWSTR utf16_str);\n#endif\n\n  // Compares two C strings.  Returns true iff they have the same content.\n  //\n  // Unlike strcmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CStringEquals(const char* lhs, const char* rhs);\n\n  // Converts a wide C string to a String using the UTF-8 encoding.\n  // NULL will be converted to \"(null)\".  If an error occurred during\n  // the conversion, \"(failed to convert from wide string)\" is\n  // returned.\n  static String ShowWideCString(const wchar_t* wide_c_str);\n\n  // Similar to ShowWideCString(), except that this function encloses\n  // the converted string in double quotes.\n  static String ShowWideCStringQuoted(const wchar_t* wide_c_str);\n\n  // Compares two wide C strings.  Returns true iff they have the same\n  // content.\n  //\n  // Unlike wcscmp(), this function can handle NULL argument(s).  A\n  // NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);\n\n  // Compares two C strings, ignoring case.  Returns true iff they\n  // have the same content.\n  //\n  // Unlike strcasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL C string,\n  // including the empty string.\n  static bool CaseInsensitiveCStringEquals(const char* lhs,\n                                           const char* rhs);\n\n  // Compares two wide C strings, ignoring case.  Returns true iff they\n  // have the same content.\n  //\n  // Unlike wcscasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL wide C string,\n  // including the empty string.\n  // NB: The implementations on different platforms slightly differ.\n  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n  // environment variable. On GNU platform this method uses wcscasecmp\n  // which compares according to LC_CTYPE category of the current locale.\n  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n  // current locale.\n  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                               const wchar_t* rhs);\n\n  // Formats a list of arguments to a String, using the same format\n  // spec string as for printf.\n  //\n  // We do not use the StringPrintf class as it is not universally\n  // available.\n  //\n  // The result is limited to 4096 characters (including the tailing\n  // 0).  If 4096 characters are not enough to format the input,\n  // \"<buffer exceeded>\" is returned.\n  static String Format(const char* format, ...);\n\n  // C'tors\n\n  // The default c'tor constructs a NULL string.\n  String() : c_str_(NULL), length_(0) {}\n\n  // Constructs a String by cloning a 0-terminated C string.\n  String(const char* a_c_str) {  // NOLINT\n    if (a_c_str == NULL) {\n      c_str_ = NULL;\n      length_ = 0;\n    } else {\n      ConstructNonNull(a_c_str, strlen(a_c_str));\n    }\n  }\n\n  // Constructs a String by copying a given number of chars from a\n  // buffer.  E.g. String(\"hello\", 3) creates the string \"hel\",\n  // String(\"a\\0bcd\", 4) creates \"a\\0bc\", String(NULL, 0) creates \"\",\n  // and String(NULL, 1) results in access violation.\n  String(const char* buffer, size_t a_length) {\n    ConstructNonNull(buffer, a_length);\n  }\n\n  // The copy c'tor creates a new copy of the string.  The two\n  // String objects do not share content.\n  String(const String& str) : c_str_(NULL), length_(0) { *this = str; }\n\n  // D'tor.  String is intended to be a final class, so the d'tor\n  // doesn't need to be virtual.\n  ~String() { delete[] c_str_; }\n\n  // Allows a String to be implicitly converted to an ::std::string or\n  // ::string, and vice versa.  Converting a String containing a NULL\n  // pointer to ::std::string or ::string is undefined behavior.\n  // Converting a ::std::string or ::string containing an embedded NUL\n  // character to a String will result in the prefix up to the first\n  // NUL character.\n  String(const ::std::string& str) {\n    ConstructNonNull(str.c_str(), str.length());\n  }\n\n  operator ::std::string() const { return ::std::string(c_str(), length()); }\n\n#if GTEST_HAS_GLOBAL_STRING\n  String(const ::string& str) {\n    ConstructNonNull(str.c_str(), str.length());\n  }\n\n  operator ::string() const { return ::string(c_str(), length()); }\n#endif  // GTEST_HAS_GLOBAL_STRING\n\n  // Returns true iff this is an empty string (i.e. \"\").\n  bool empty() const { return (c_str() != NULL) && (length() == 0); }\n\n  // Compares this with another String.\n  // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0\n  // if this is greater than rhs.\n  int Compare(const String& rhs) const;\n\n  // Returns true iff this String equals the given C string.  A NULL\n  // string and a non-NULL string are considered not equal.\n  bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; }\n\n  // Returns true iff this String is less than the given String.  A\n  // NULL string is considered less than \"\".\n  bool operator<(const String& rhs) const { return Compare(rhs) < 0; }\n\n  // Returns true iff this String doesn't equal the given C string.  A NULL\n  // string and a non-NULL string are considered not equal.\n  bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); }\n\n  // Returns true iff this String ends with the given suffix.  *Any*\n  // String is considered to end with a NULL or empty suffix.\n  bool EndsWith(const char* suffix) const;\n\n  // Returns true iff this String ends with the given suffix, not considering\n  // case. Any String is considered to end with a NULL or empty suffix.\n  bool EndsWithCaseInsensitive(const char* suffix) const;\n\n  // Returns the length of the encapsulated string, or 0 if the\n  // string is NULL.\n  size_t length() const { return length_; }\n\n  // Gets the 0-terminated C string this String object represents.\n  // The String object still owns the string.  Therefore the caller\n  // should NOT delete the return value.\n  const char* c_str() const { return c_str_; }\n\n  // Assigns a C string to this object.  Self-assignment works.\n  const String& operator=(const char* a_c_str) {\n    return *this = String(a_c_str);\n  }\n\n  // Assigns a String object to this object.  Self-assignment works.\n  const String& operator=(const String& rhs) {\n    if (this != &rhs) {\n      delete[] c_str_;\n      if (rhs.c_str() == NULL) {\n        c_str_ = NULL;\n        length_ = 0;\n      } else {\n        ConstructNonNull(rhs.c_str(), rhs.length());\n      }\n    }\n\n    return *this;\n  }\n\n private:\n  // Constructs a non-NULL String from the given content.  This\n  // function can only be called when c_str_ has not been allocated.\n  // ConstructNonNull(NULL, 0) results in an empty string (\"\").\n  // ConstructNonNull(NULL, non_zero) is undefined behavior.\n  void ConstructNonNull(const char* buffer, size_t a_length) {\n    char* const str = new char[a_length + 1];\n    memcpy(str, buffer, a_length);\n    str[a_length] = '\\0';\n    c_str_ = str;\n    length_ = a_length;\n  }\n\n  const char* c_str_;\n  size_t length_;\n};  // class String\n\n// Streams a String to an ostream.  Each '\\0' character in the String\n// is replaced with \"\\\\0\".\ninline ::std::ostream& operator<<(::std::ostream& os, const String& str) {\n  if (str.c_str() == NULL) {\n    os << \"(null)\";\n  } else {\n    const char* const c_str = str.c_str();\n    for (size_t i = 0; i != str.length(); i++) {\n      if (c_str[i] == '\\0') {\n        os << \"\\\\0\";\n      } else {\n        os << c_str[i];\n      }\n    }\n  }\n  return os;\n}\n\n// Gets the content of the stringstream's buffer as a String.  Each '\\0'\n// character in the buffer is replaced with \"\\\\0\".\nGTEST_API_ String StringStreamToString(::std::stringstream* stream);\n\n// Converts a streamable value to a String.  A NULL pointer is\n// converted to \"(null)\".  When the input value is a ::string,\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\n// character in it is replaced with \"\\\\0\".\n\n// Declared here but defined in gtest.h, so that it has access\n// to the definition of the Message class, required by the ARM\n// compiler.\ntemplate <typename T>\nString StreamableToString(const T& streamable);\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: keith.ray@gmail.com (Keith Ray)\n//\n// Google Test filepath utilities\n//\n// This header file declares classes and functions used internally by\n// Google Test.  They are subject to change without notice.\n//\n// This file is #included in <gtest/internal/gtest-internal.h>.\n// Do not include this header file separately!\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n\n\nnamespace testing {\nnamespace internal {\n\n// FilePath - a class for file and directory pathname manipulation which\n// handles platform-specific conventions (like the pathname separator).\n// Used for helper functions for naming files in a directory for xml output.\n// Except for Set methods, all methods are const or static, which provides an\n// \"immutable value object\" -- useful for peace of mind.\n// A FilePath with a value ending in a path separator (\"like/this/\") represents\n// a directory, otherwise it is assumed to represent a file. In either case,\n// it may or may not represent an actual file or directory in the file system.\n// Names are NOT checked for syntax correctness -- no checking for illegal\n// characters, malformed paths, etc.\n\nclass GTEST_API_ FilePath {\n public:\n  FilePath() : pathname_(\"\") { }\n  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }\n\n  explicit FilePath(const char* pathname) : pathname_(pathname) {\n    Normalize();\n  }\n\n  explicit FilePath(const String& pathname) : pathname_(pathname) {\n    Normalize();\n  }\n\n  FilePath& operator=(const FilePath& rhs) {\n    Set(rhs);\n    return *this;\n  }\n\n  void Set(const FilePath& rhs) {\n    pathname_ = rhs.pathname_;\n  }\n\n  String ToString() const { return pathname_; }\n  const char* c_str() const { return pathname_.c_str(); }\n\n  // Returns the current working directory, or \"\" if unsuccessful.\n  static FilePath GetCurrentDir();\n\n  // Given directory = \"dir\", base_name = \"test\", number = 0,\n  // extension = \"xml\", returns \"dir/test.xml\". If number is greater\n  // than zero (e.g., 12), returns \"dir/test_12.xml\".\n  // On Windows platform, uses \\ as the separator rather than /.\n  static FilePath MakeFileName(const FilePath& directory,\n                               const FilePath& base_name,\n                               int number,\n                               const char* extension);\n\n  // Given directory = \"dir\", relative_path = \"test.xml\",\n  // returns \"dir/test.xml\".\n  // On Windows, uses \\ as the separator rather than /.\n  static FilePath ConcatPaths(const FilePath& directory,\n                              const FilePath& relative_path);\n\n  // Returns a pathname for a file that does not currently exist. The pathname\n  // will be directory/base_name.extension or\n  // directory/base_name_<number>.extension if directory/base_name.extension\n  // already exists. The number will be incremented until a pathname is found\n  // that does not already exist.\n  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n  // There could be a race condition if two or more processes are calling this\n  // function at the same time -- they could both pick the same filename.\n  static FilePath GenerateUniqueFileName(const FilePath& directory,\n                                         const FilePath& base_name,\n                                         const char* extension);\n\n  // Returns true iff the path is NULL or \"\".\n  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\\0'; }\n\n  // If input name has a trailing separator character, removes it and returns\n  // the name, otherwise return the name string unmodified.\n  // On Windows platform, uses \\ as the separator, other platforms use /.\n  FilePath RemoveTrailingPathSeparator() const;\n\n  // Returns a copy of the FilePath with the directory part removed.\n  // Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n  // FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n  // the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n  // returns an empty FilePath (\"\").\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveDirectoryName() const;\n\n  // RemoveFileName returns the directory path with the filename removed.\n  // Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n  // If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n  // FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n  // not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\n  FilePath RemoveFileName() const;\n\n  // Returns a copy of the FilePath with the case-insensitive extension removed.\n  // Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n  // FilePath(\"dir/file\"). If a case-insensitive extension is not\n  // found, returns a copy of the original FilePath.\n  FilePath RemoveExtension(const char* extension) const;\n\n  // Creates directories so that path exists. Returns true if successful or if\n  // the directories already exist; returns false if unable to create\n  // directories for any reason. Will also return false if the FilePath does\n  // not represent a directory (that is, it doesn't end with a path separator).\n  bool CreateDirectoriesRecursively() const;\n\n  // Create the directory so that path exists. Returns true if successful or\n  // if the directory already exists; returns false if unable to create the\n  // directory for any reason, including if the parent directory does not\n  // exist. Not named \"CreateDirectory\" because that's a macro on Windows.\n  bool CreateFolder() const;\n\n  // Returns true if FilePath describes something in the file-system,\n  // either a file, directory, or whatever, and that something exists.\n  bool FileOrDirectoryExists() const;\n\n  // Returns true if pathname describes a directory in the file-system\n  // that exists.\n  bool DirectoryExists() const;\n\n  // Returns true if FilePath ends with a path separator, which indicates that\n  // it is intended to represent a directory. Returns false otherwise.\n  // This does NOT check that a directory (or file) actually exists.\n  bool IsDirectory() const;\n\n  // Returns true if pathname describes a root directory. (Windows has one\n  // root directory per disk drive.)\n  bool IsRootDirectory() const;\n\n  // Returns true if pathname describes an absolute path.\n  bool IsAbsolutePath() const;\n\n private:\n  // Replaces multiple consecutive separators with a single separator.\n  // For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n  // redundancies that might be in a pathname involving \".\" or \"..\".\n  //\n  // A pathname with multiple consecutive separators may occur either through\n  // user error or as a result of some scripts or APIs that generate a pathname\n  // with a trailing separator. On other platforms the same API or script\n  // may NOT generate a pathname with a trailing \"/\". Then elsewhere that\n  // pathname may have another \"/\" and pathname components added to it,\n  // without checking for the separator already being there.\n  // The script language and operating system may allow paths like \"foo//bar\"\n  // but some of the functions in FilePath will not handle that correctly. In\n  // particular, RemoveTrailingPathSeparator() only removes one separator, and\n  // it is called in CreateDirectoriesRecursively() assuming that it will change\n  // a pathname from directory syntax (trailing separator) to filename syntax.\n  //\n  // On Windows this method also replaces the alternate path separator '/' with\n  // the primary path separator '\\\\', so that for example \"bar\\\\/\\\\foo\" becomes\n  // \"bar\\\\foo\".\n\n  void Normalize();\n\n  // Returns a pointer to the last occurence of a valid path separator in\n  // the FilePath. On Windows, for example, both '/' and '\\' are valid path\n  // separators. Returns NULL if no path separator was found.\n  const char* FindLastPathSeparator() const;\n\n  String pathname_;\n};  // class FilePath\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\n// This file was GENERATED by command:\n//     pump.py gtest-type-util.h.pump\n// DO NOT EDIT BY HAND!!!\n\n// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n// Type utilities needed for implementing typed and type-parameterized\n// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\n//\n// Currently we support at most 50 types in a list, and at most 50\n// type-parameterized tests in one type-parameterized test case.\n// Please contact googletestframework@googlegroups.com if you need\n// more.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n\n\n// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using\n// libstdc++ (which is where cxxabi.h comes from).\n# ifdef __GLIBCXX__\n#  include <cxxabi.h>\n# elif defined(__HP_aCC)\n#  include <acxx_demangle.h>\n# endif  // __GLIBCXX__\n\nnamespace testing {\nnamespace internal {\n\n// GetTypeName<T>() returns a human-readable name of type T.\n// NB: This function is also used in Google Mock, so don't move it inside of\n// the typed-test-only section below.\ntemplate <typename T>\nString GetTypeName() {\n# if GTEST_HAS_RTTI\n\n  const char* const name = typeid(T).name();\n#  if defined(__GLIBCXX__) || defined(__HP_aCC)\n  int status = 0;\n  // gcc's implementation of typeid(T).name() mangles the type name,\n  // so we have to demangle it.\n#   ifdef __GLIBCXX__\n  using abi::__cxa_demangle;\n#   endif // __GLIBCXX__\n  char* const readable_name = __cxa_demangle(name, 0, 0, &status);\n  const String name_str(status == 0 ? readable_name : name);\n  free(readable_name);\n  return name_str;\n#  else\n  return name;\n#  endif  // __GLIBCXX__ || __HP_aCC\n\n# else\n\n  return \"<type>\";\n\n# endif  // GTEST_HAS_RTTI\n}\n\n#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\n\n// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same\n// type.  This can be used as a compile-time assertion to ensure that\n// two types are equal.\n\ntemplate <typename T1, typename T2>\nstruct AssertTypeEq;\n\ntemplate <typename T>\nstruct AssertTypeEq<T, T> {\n  typedef bool type;\n};\n\n// A unique type used as the default value for the arguments of class\n// template Types.  This allows us to simulate variadic templates\n// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't\n// support directly.\nstruct None {};\n\n// The following family of struct and struct templates are used to\n// represent type lists.  In particular, TypesN<T1, T2, ..., TN>\n// represents a type list with N types (T1, T2, ..., and TN) in it.\n// Except for Types0, every struct in the family has two member types:\n// Head for the first type in the list, and Tail for the rest of the\n// list.\n\n// The empty type list.\nstruct Types0 {};\n\n// Type lists of length 1, 2, 3, and so on.\n\ntemplate <typename T1>\nstruct Types1 {\n  typedef T1 Head;\n  typedef Types0 Tail;\n};\ntemplate <typename T1, typename T2>\nstruct Types2 {\n  typedef T1 Head;\n  typedef Types1<T2> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3>\nstruct Types3 {\n  typedef T1 Head;\n  typedef Types2<T2, T3> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\nstruct Types4 {\n  typedef T1 Head;\n  typedef Types3<T2, T3, T4> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nstruct Types5 {\n  typedef T1 Head;\n  typedef Types4<T2, T3, T4, T5> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6>\nstruct Types6 {\n  typedef T1 Head;\n  typedef Types5<T2, T3, T4, T5, T6> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7>\nstruct Types7 {\n  typedef T1 Head;\n  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8>\nstruct Types8 {\n  typedef T1 Head;\n  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9>\nstruct Types9 {\n  typedef T1 Head;\n  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10>\nstruct Types10 {\n  typedef T1 Head;\n  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11>\nstruct Types11 {\n  typedef T1 Head;\n  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12>\nstruct Types12 {\n  typedef T1 Head;\n  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13>\nstruct Types13 {\n  typedef T1 Head;\n  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14>\nstruct Types14 {\n  typedef T1 Head;\n  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15>\nstruct Types15 {\n  typedef T1 Head;\n  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16>\nstruct Types16 {\n  typedef T1 Head;\n  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17>\nstruct Types17 {\n  typedef T1 Head;\n  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18>\nstruct Types18 {\n  typedef T1 Head;\n  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19>\nstruct Types19 {\n  typedef T1 Head;\n  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20>\nstruct Types20 {\n  typedef T1 Head;\n  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21>\nstruct Types21 {\n  typedef T1 Head;\n  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22>\nstruct Types22 {\n  typedef T1 Head;\n  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23>\nstruct Types23 {\n  typedef T1 Head;\n  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24>\nstruct Types24 {\n  typedef T1 Head;\n  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25>\nstruct Types25 {\n  typedef T1 Head;\n  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26>\nstruct Types26 {\n  typedef T1 Head;\n  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27>\nstruct Types27 {\n  typedef T1 Head;\n  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28>\nstruct Types28 {\n  typedef T1 Head;\n  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29>\nstruct Types29 {\n  typedef T1 Head;\n  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30>\nstruct Types30 {\n  typedef T1 Head;\n  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31>\nstruct Types31 {\n  typedef T1 Head;\n  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32>\nstruct Types32 {\n  typedef T1 Head;\n  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33>\nstruct Types33 {\n  typedef T1 Head;\n  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34>\nstruct Types34 {\n  typedef T1 Head;\n  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35>\nstruct Types35 {\n  typedef T1 Head;\n  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36>\nstruct Types36 {\n  typedef T1 Head;\n  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37>\nstruct Types37 {\n  typedef T1 Head;\n  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38>\nstruct Types38 {\n  typedef T1 Head;\n  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39>\nstruct Types39 {\n  typedef T1 Head;\n  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40>\nstruct Types40 {\n  typedef T1 Head;\n  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41>\nstruct Types41 {\n  typedef T1 Head;\n  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42>\nstruct Types42 {\n  typedef T1 Head;\n  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43>\nstruct Types43 {\n  typedef T1 Head;\n  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44>\nstruct Types44 {\n  typedef T1 Head;\n  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45>\nstruct Types45 {\n  typedef T1 Head;\n  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46>\nstruct Types46 {\n  typedef T1 Head;\n  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45, T46> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47>\nstruct Types47 {\n  typedef T1 Head;\n  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45, T46, T47> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48>\nstruct Types48 {\n  typedef T1 Head;\n  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45, T46, T47, T48> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49>\nstruct Types49 {\n  typedef T1 Head;\n  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45, T46, T47, T48, T49> Tail;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49, typename T50>\nstruct Types50 {\n  typedef T1 Head;\n  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n      T44, T45, T46, T47, T48, T49, T50> Tail;\n};\n\n\n}  // namespace internal\n\n// We don't want to require the users to write TypesN<...> directly,\n// as that would require them to count the length.  Types<...> is much\n// easier to write, but generates horrible messages when there is a\n// compiler error, as gcc insists on printing out each template\n// argument, even if it has the default value (this means Types<int>\n// will appear as Types<int, None, None, ..., None> in the compiler\n// errors).\n//\n// Our solution is to combine the best part of the two approaches: a\n// user would write Types<T1, ..., TN>, and Google Test will translate\n// that to TypesN<T1, ..., TN> internally to make error messages\n// readable.  The translation is done by the 'type' member of the\n// Types template.\ntemplate <typename T1 = internal::None, typename T2 = internal::None,\n    typename T3 = internal::None, typename T4 = internal::None,\n    typename T5 = internal::None, typename T6 = internal::None,\n    typename T7 = internal::None, typename T8 = internal::None,\n    typename T9 = internal::None, typename T10 = internal::None,\n    typename T11 = internal::None, typename T12 = internal::None,\n    typename T13 = internal::None, typename T14 = internal::None,\n    typename T15 = internal::None, typename T16 = internal::None,\n    typename T17 = internal::None, typename T18 = internal::None,\n    typename T19 = internal::None, typename T20 = internal::None,\n    typename T21 = internal::None, typename T22 = internal::None,\n    typename T23 = internal::None, typename T24 = internal::None,\n    typename T25 = internal::None, typename T26 = internal::None,\n    typename T27 = internal::None, typename T28 = internal::None,\n    typename T29 = internal::None, typename T30 = internal::None,\n    typename T31 = internal::None, typename T32 = internal::None,\n    typename T33 = internal::None, typename T34 = internal::None,\n    typename T35 = internal::None, typename T36 = internal::None,\n    typename T37 = internal::None, typename T38 = internal::None,\n    typename T39 = internal::None, typename T40 = internal::None,\n    typename T41 = internal::None, typename T42 = internal::None,\n    typename T43 = internal::None, typename T44 = internal::None,\n    typename T45 = internal::None, typename T46 = internal::None,\n    typename T47 = internal::None, typename T48 = internal::None,\n    typename T49 = internal::None, typename T50 = internal::None>\nstruct Types {\n  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;\n};\n\ntemplate <>\nstruct Types<internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types0 type;\n};\ntemplate <typename T1>\nstruct Types<T1, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types1<T1> type;\n};\ntemplate <typename T1, typename T2>\nstruct Types<T1, T2, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types2<T1, T2> type;\n};\ntemplate <typename T1, typename T2, typename T3>\nstruct Types<T1, T2, T3, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types3<T1, T2, T3> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4>\nstruct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types4<T1, T2, T3, T4> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nstruct Types<T1, T2, T3, T4, T5, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types5<T1, T2, T3, T4, T5> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6>\nstruct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None, internal::None> {\n  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None, internal::None> {\n  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\n    internal::None, internal::None, internal::None, internal::None,\n    internal::None> {\n  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\n    T46, internal::None, internal::None, internal::None, internal::None> {\n  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\n    T46, T47, internal::None, internal::None, internal::None> {\n  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46, T47> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\n    T46, T47, T48, internal::None, internal::None> {\n  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46, T47, T48> type;\n};\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49>\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\n    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\n    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\n    T46, T47, T48, T49, internal::None> {\n  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46, T47, T48, T49> type;\n};\n\nnamespace internal {\n\n# define GTEST_TEMPLATE_ template <typename T> class\n\n// The template \"selector\" struct TemplateSel<Tmpl> is used to\n// represent Tmpl, which must be a class template with one type\n// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined\n// as the type Tmpl<T>.  This allows us to actually instantiate the\n// template \"selected\" by TemplateSel<Tmpl>.\n//\n// This trick is necessary for simulating typedef for class templates,\n// which C++ doesn't support directly.\ntemplate <GTEST_TEMPLATE_ Tmpl>\nstruct TemplateSel {\n  template <typename T>\n  struct Bind {\n    typedef Tmpl<T> type;\n  };\n};\n\n# define GTEST_BIND_(TmplSel, T) \\\n  TmplSel::template Bind<T>::type\n\n// A unique struct template used as the default value for the\n// arguments of class template Templates.  This allows us to simulate\n// variadic templates (e.g. Templates<int>, Templates<int, double>,\n// and etc), which C++ doesn't support directly.\ntemplate <typename T>\nstruct NoneT {};\n\n// The following family of struct and struct templates are used to\n// represent template lists.  In particular, TemplatesN<T1, T2, ...,\n// TN> represents a list of N templates (T1, T2, ..., and TN).  Except\n// for Templates0, every struct in the family has two member types:\n// Head for the selector of the first template in the list, and Tail\n// for the rest of the list.\n\n// The empty template list.\nstruct Templates0 {};\n\n// Template lists of length 1, 2, 3, and so on.\n\ntemplate <GTEST_TEMPLATE_ T1>\nstruct Templates1 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates0 Tail;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>\nstruct Templates2 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates1<T2> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>\nstruct Templates3 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates2<T2, T3> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4>\nstruct Templates4 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates3<T2, T3, T4> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>\nstruct Templates5 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates4<T2, T3, T4, T5> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>\nstruct Templates6 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates5<T2, T3, T4, T5, T6> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7>\nstruct Templates7 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>\nstruct Templates8 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>\nstruct Templates9 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10>\nstruct Templates10 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>\nstruct Templates11 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>\nstruct Templates12 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13>\nstruct Templates13 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>\nstruct Templates14 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>\nstruct Templates15 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16>\nstruct Templates16 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>\nstruct Templates17 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>\nstruct Templates18 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19>\nstruct Templates19 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>\nstruct Templates20 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>\nstruct Templates21 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22>\nstruct Templates22 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>\nstruct Templates23 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>\nstruct Templates24 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25>\nstruct Templates25 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>\nstruct Templates26 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>\nstruct Templates27 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28>\nstruct Templates28 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>\nstruct Templates29 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>\nstruct Templates30 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31>\nstruct Templates31 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>\nstruct Templates32 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>\nstruct Templates33 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34>\nstruct Templates34 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>\nstruct Templates35 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>\nstruct Templates36 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37>\nstruct Templates37 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>\nstruct Templates38 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>\nstruct Templates39 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40>\nstruct Templates40 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>\nstruct Templates41 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>\nstruct Templates42 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43>\nstruct Templates43 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>\nstruct Templates44 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>\nstruct Templates45 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46>\nstruct Templates46 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45, T46> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>\nstruct Templates47 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45, T46, T47> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>\nstruct Templates48 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45, T46, T47, T48> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\n    GTEST_TEMPLATE_ T49>\nstruct Templates49 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45, T46, T47, T48, T49> Tail;\n};\n\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\n    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>\nstruct Templates50 {\n  typedef TemplateSel<T1> Head;\n  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n      T43, T44, T45, T46, T47, T48, T49, T50> Tail;\n};\n\n\n// We don't want to require the users to write TemplatesN<...> directly,\n// as that would require them to count the length.  Templates<...> is much\n// easier to write, but generates horrible messages when there is a\n// compiler error, as gcc insists on printing out each template\n// argument, even if it has the default value (this means Templates<list>\n// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler\n// errors).\n//\n// Our solution is to combine the best part of the two approaches: a\n// user would write Templates<T1, ..., TN>, and Google Test will translate\n// that to TemplatesN<T1, ..., TN> internally to make error messages\n// readable.  The translation is done by the 'type' member of the\n// Templates template.\ntemplate <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,\n    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,\n    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,\n    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,\n    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,\n    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,\n    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,\n    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,\n    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,\n    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,\n    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,\n    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,\n    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,\n    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,\n    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,\n    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,\n    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,\n    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,\n    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,\n    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,\n    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,\n    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,\n    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,\n    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,\n    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>\nstruct Templates {\n  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45, T46, T47, T48, T49, T50> type;\n};\n\ntemplate <>\nstruct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT> {\n  typedef Templates0 type;\n};\ntemplate <GTEST_TEMPLATE_ T1>\nstruct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT> {\n  typedef Templates1<T1> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>\nstruct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT> {\n  typedef Templates2<T1, T2> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>\nstruct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates3<T1, T2, T3> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4>\nstruct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates4<T1, T2, T3, T4> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>\nstruct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates5<T1, T2, T3, T4, T5> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>\nstruct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates6<T1, T2, T3, T4, T5, T6> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT> {\n  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT> {\n  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT> {\n  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT> {\n  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT> {\n  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT> {\n  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT> {\n  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT> {\n  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    T45, NoneT, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    T45, T46, NoneT, NoneT, NoneT, NoneT> {\n  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45, T46> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    T45, T46, T47, NoneT, NoneT, NoneT> {\n  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45, T46, T47> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    T45, T46, T47, T48, NoneT, NoneT> {\n  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45, T46, T47, T48> type;\n};\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\n    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\n    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\n    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\n    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\n    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\n    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\n    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\n    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\n    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\n    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\n    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\n    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\n    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\n    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\n    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\n    GTEST_TEMPLATE_ T49>\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\n    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\n    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\n    T45, T46, T47, T48, T49, NoneT> {\n  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n      T42, T43, T44, T45, T46, T47, T48, T49> type;\n};\n\n// The TypeList template makes it possible to use either a single type\n// or a Types<...> list in TYPED_TEST_CASE() and\n// INSTANTIATE_TYPED_TEST_CASE_P().\n\ntemplate <typename T>\nstruct TypeList { typedef Types1<T> type; };\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49, typename T50>\nstruct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46, T47, T48, T49, T50> > {\n  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;\n};\n\n#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\n\n// Due to C++ preprocessor weirdness, we need double indirection to\n// concatenate two tokens when one of them is __LINE__.  Writing\n//\n//   foo ## __LINE__\n//\n// will result in the token foo__LINE__, instead of foo followed by\n// the current line number.  For more details, see\n// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6\n#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)\n#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar\n\n// Google Test defines the testing::Message class to allow construction of\n// test messages via the << operator.  The idea is that anything\n// streamable to std::ostream can be streamed to a testing::Message.\n// This allows a user to use his own types in Google Test assertions by\n// overloading the << operator.\n//\n// util/gtl/stl_logging-inl.h overloads << for STL containers.  These\n// overloads cannot be defined in the std namespace, as that will be\n// undefined behavior.  Therefore, they are defined in the global\n// namespace instead.\n//\n// C++'s symbol lookup rule (i.e. Koenig lookup) says that these\n// overloads are visible in either the std namespace or the global\n// namespace, but not other namespaces, including the testing\n// namespace which Google Test's Message class is in.\n//\n// To allow STL containers (and other types that has a << operator\n// defined in the global namespace) to be used in Google Test assertions,\n// testing::Message must access the custom << operator from the global\n// namespace.  Hence this helper function.\n//\n// Note: Jeffrey Yasskin suggested an alternative fix by \"using\n// ::operator<<;\" in the definition of Message's operator<<.  That fix\n// doesn't require a helper function, but unfortunately doesn't\n// compile with MSVC.\ntemplate <typename T>\ninline void GTestStreamToHelper(std::ostream* os, const T& val) {\n  *os << val;\n}\n\nclass ProtocolMessage;\nnamespace proto2 { class Message; }\n\nnamespace testing {\n\n// Forward declarations.\n\nclass AssertionResult;                 // Result of an assertion.\nclass Message;                         // Represents a failure message.\nclass Test;                            // Represents a test.\nclass TestInfo;                        // Information about a test.\nclass TestPartResult;                  // Result of a test part.\nclass UnitTest;                        // A collection of test cases.\n\ntemplate <typename T>\n::std::string PrintToString(const T& value);\n\nnamespace internal {\n\nstruct TraceInfo;                      // Information about a trace point.\nclass ScopedTrace;                     // Implements scoped trace.\nclass TestInfoImpl;                    // Opaque implementation of TestInfo\nclass UnitTestImpl;                    // Opaque implementation of UnitTest\n\n// How many times InitGoogleTest() has been called.\nextern int g_init_gtest_count;\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nGTEST_API_ extern const char kStackTraceMarker[];\n\n// A secret type that Google Test users don't know about.  It has no\n// definition on purpose.  Therefore it's impossible to create a\n// Secret object, which is what we want.\nclass Secret;\n\n// Two overloaded helpers for checking at compile time whether an\n// expression is a null pointer literal (i.e. NULL or any 0-valued\n// compile-time integral constant).  Their return values have\n// different sizes, so we can use sizeof() to test which version is\n// picked by the compiler.  These helpers have no implementations, as\n// we only need their signatures.\n//\n// Given IsNullLiteralHelper(x), the compiler will pick the first\n// version if x can be implicitly converted to Secret*, and pick the\n// second version otherwise.  Since Secret is a secret and incomplete\n// type, the only expression a user can write that has type Secret* is\n// a null pointer literal.  Therefore, we know that x is a null\n// pointer literal if and only if the first version is picked by the\n// compiler.\nchar IsNullLiteralHelper(Secret* p);\nchar (&IsNullLiteralHelper(...))[2];  // NOLINT\n\n// A compile-time bool constant that is true if and only if x is a\n// null pointer literal (i.e. NULL or any 0-valued compile-time\n// integral constant).\n#ifdef GTEST_ELLIPSIS_NEEDS_POD_\n// We lose support for NULL detection where the compiler doesn't like\n// passing non-POD classes through ellipsis (...).\n# define GTEST_IS_NULL_LITERAL_(x) false\n#else\n# define GTEST_IS_NULL_LITERAL_(x) \\\n    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)\n#endif  // GTEST_ELLIPSIS_NEEDS_POD_\n\n// Appends the user-supplied message to the Google-Test-generated message.\nGTEST_API_ String AppendUserMessage(const String& gtest_msg,\n                                    const Message& user_msg);\n\n// A helper class for creating scoped traces in user programs.\nclass GTEST_API_ ScopedTrace {\n public:\n  // The c'tor pushes the given source file location and message onto\n  // a trace stack maintained by Google Test.\n  ScopedTrace(const char* file, int line, const Message& message);\n\n  // The d'tor pops the info pushed by the c'tor.\n  //\n  // Note that the d'tor is not virtual in order to be efficient.\n  // Don't inherit from ScopedTrace!\n  ~ScopedTrace();\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);\n} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its\n                            // c'tor and d'tor.  Therefore it doesn't\n                            // need to be used otherwise.\n\n// Converts a streamable value to a String.  A NULL pointer is\n// converted to \"(null)\".  When the input value is a ::string,\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\n// character in it is replaced with \"\\\\0\".\n// Declared here but defined in gtest.h, so that it has access\n// to the definition of the Message class, required by the ARM\n// compiler.\ntemplate <typename T>\nString StreamableToString(const T& streamable);\n\n// The Symbian compiler has a bug that prevents it from selecting the\n// correct overload of FormatForComparisonFailureMessage (see below)\n// unless we pass the first argument by reference.  If we do that,\n// however, Visual Age C++ 10.1 generates a compiler error.  Therefore\n// we only apply the work-around for Symbian.\n#if defined(__SYMBIAN32__)\n# define GTEST_CREF_WORKAROUND_ const&\n#else\n# define GTEST_CREF_WORKAROUND_\n#endif\n\n// When this operand is a const char* or char*, if the other operand\n// is a ::std::string or ::string, we print this operand as a C string\n// rather than a pointer (we do the same for wide strings); otherwise\n// we print it as a pointer to be safe.\n\n// This internal macro is used to avoid duplicated code.\n#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\\\ninline String FormatForComparisonFailureMessage(\\\n    operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \\\n    const operand2_type& /*operand2*/) {\\\n  return operand1_printer(str);\\\n}\\\ninline String FormatForComparisonFailureMessage(\\\n    const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \\\n    const operand2_type& /*operand2*/) {\\\n  return operand1_printer(str);\\\n}\n\nGTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)\n#if GTEST_HAS_STD_WSTRING\nGTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted)\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_HAS_GLOBAL_STRING\nGTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted)\n#endif  // GTEST_HAS_GLOBAL_STRING\n#if GTEST_HAS_GLOBAL_WSTRING\nGTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted)\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n#undef GTEST_FORMAT_IMPL_\n\n// The next four overloads handle the case where the operand being\n// printed is a char/wchar_t pointer and the other operand is not a\n// string/wstring object.  In such cases, we just print the operand as\n// a pointer to be safe.\n#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType)                       \\\n  template <typename T>                                             \\\n  String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \\\n                                           const T&) { \\\n    return PrintToString(static_cast<const void*>(p));              \\\n  }\n\nGTEST_FORMAT_CHAR_PTR_IMPL_(char)\nGTEST_FORMAT_CHAR_PTR_IMPL_(const char)\nGTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t)\nGTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t)\n\n#undef GTEST_FORMAT_CHAR_PTR_IMPL_\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   expected_expression: \"foo\"\n//   actual_expression:   \"bar\"\n//   expected_value:      \"5\"\n//   actual_value:        \"6\"\n//\n// The ignoring_case parameter is true iff the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\n// be inserted into the message.\nGTEST_API_ AssertionResult EqFailure(const char* expected_expression,\n                                     const char* actual_expression,\n                                     const String& expected_value,\n                                     const String& actual_value,\n                                     bool ignoring_case);\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nGTEST_API_ String GetBoolAssertionFailureMessage(\n    const AssertionResult& assertion_result,\n    const char* expression_text,\n    const char* actual_predicate_value,\n    const char* expected_predicate_value);\n\n// This template class represents an IEEE floating-point number\n// (either single-precision or double-precision, depending on the\n// template parameters).\n//\n// The purpose of this class is to do more sophisticated number\n// comparison.  (Due to round-off error, etc, it's very unlikely that\n// two floating-points will be equal exactly.  Hence a naive\n// comparison by the == operation often doesn't work.)\n//\n// Format of IEEE floating-point:\n//\n//   The most-significant bit being the leftmost, an IEEE\n//   floating-point looks like\n//\n//     sign_bit exponent_bits fraction_bits\n//\n//   Here, sign_bit is a single bit that designates the sign of the\n//   number.\n//\n//   For float, there are 8 exponent bits and 23 fraction bits.\n//\n//   For double, there are 11 exponent bits and 52 fraction bits.\n//\n//   More details can be found at\n//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\ntemplate <typename RawType>\nclass FloatingPoint {\n public:\n  // Defines the unsigned integer type that has the same size as the\n  // floating point number.\n  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;\n\n  // Constants.\n\n  // # of bits in a number.\n  static const size_t kBitCount = 8*sizeof(RawType);\n\n  // # of fraction bits in a number.\n  static const size_t kFractionBitCount =\n    std::numeric_limits<RawType>::digits - 1;\n\n  // # of exponent bits in a number.\n  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;\n\n  // The mask for the sign bit.\n  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);\n\n  // The mask for the fraction bits.\n  static const Bits kFractionBitMask =\n    ~static_cast<Bits>(0) >> (kExponentBitCount + 1);\n\n  // The mask for the exponent bits.\n  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);\n\n  // How many ULP's (Units in the Last Place) we want to tolerate when\n  // comparing two numbers.  The larger the value, the more error we\n  // allow.  A 0 value means that two numbers must be exactly the same\n  // to be considered equal.\n  //\n  // The maximum error of a single floating-point operation is 0.5\n  // units in the last place.  On Intel CPU's, all floating-point\n  // calculations are done with 80-bit precision, while double has 64\n  // bits.  Therefore, 4 should be enough for ordinary use.\n  //\n  // See the following article for more details on ULP:\n  // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.\n  static const size_t kMaxUlps = 4;\n\n  // Constructs a FloatingPoint from a raw floating-point number.\n  //\n  // On an Intel CPU, passing a non-normalized NAN (Not a Number)\n  // around may change its bits, although the new value is guaranteed\n  // to be also a NAN.  Therefore, don't expect this constructor to\n  // preserve the bits in x when x is a NAN.\n  explicit FloatingPoint(const RawType& x) { u_.value_ = x; }\n\n  // Static methods\n\n  // Reinterprets a bit pattern as a floating-point number.\n  //\n  // This function is needed to test the AlmostEquals() method.\n  static RawType ReinterpretBits(const Bits bits) {\n    FloatingPoint fp(0);\n    fp.u_.bits_ = bits;\n    return fp.u_.value_;\n  }\n\n  // Returns the floating-point number that represent positive infinity.\n  static RawType Infinity() {\n    return ReinterpretBits(kExponentBitMask);\n  }\n\n  // Non-static methods\n\n  // Returns the bits that represents this number.\n  const Bits &bits() const { return u_.bits_; }\n\n  // Returns the exponent bits of this number.\n  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }\n\n  // Returns the fraction bits of this number.\n  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }\n\n  // Returns the sign bit of this number.\n  Bits sign_bit() const { return kSignBitMask & u_.bits_; }\n\n  // Returns true iff this is NAN (not a number).\n  bool is_nan() const {\n    // It's a NAN if the exponent bits are all ones and the fraction\n    // bits are not entirely zeros.\n    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);\n  }\n\n  // Returns true iff this number is at most kMaxUlps ULP's away from\n  // rhs.  In particular, this function:\n  //\n  //   - returns false if either number is (or both are) NAN.\n  //   - treats really large numbers as almost equal to infinity.\n  //   - thinks +0.0 and -0.0 are 0 DLP's apart.\n  bool AlmostEquals(const FloatingPoint& rhs) const {\n    // The IEEE standard says that any comparison operation involving\n    // a NAN must return false.\n    if (is_nan() || rhs.is_nan()) return false;\n\n    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)\n        <= kMaxUlps;\n  }\n\n private:\n  // The data type used to store the actual floating-point number.\n  union FloatingPointUnion {\n    RawType value_;  // The raw floating-point number.\n    Bits bits_;      // The bits that represent the number.\n  };\n\n  // Converts an integer from the sign-and-magnitude representation to\n  // the biased representation.  More precisely, let N be 2 to the\n  // power of (kBitCount - 1), an integer x is represented by the\n  // unsigned number x + N.\n  //\n  // For instance,\n  //\n  //   -N + 1 (the most negative number representable using\n  //          sign-and-magnitude) is represented by 1;\n  //   0      is represented by N; and\n  //   N - 1  (the biggest number representable using\n  //          sign-and-magnitude) is represented by 2N - 1.\n  //\n  // Read http://en.wikipedia.org/wiki/Signed_number_representations\n  // for more details on signed number representations.\n  static Bits SignAndMagnitudeToBiased(const Bits &sam) {\n    if (kSignBitMask & sam) {\n      // sam represents a negative number.\n      return ~sam + 1;\n    } else {\n      // sam represents a positive number.\n      return kSignBitMask | sam;\n    }\n  }\n\n  // Given two numbers in the sign-and-magnitude representation,\n  // returns the distance between them as an unsigned number.\n  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,\n                                                     const Bits &sam2) {\n    const Bits biased1 = SignAndMagnitudeToBiased(sam1);\n    const Bits biased2 = SignAndMagnitudeToBiased(sam2);\n    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);\n  }\n\n  FloatingPointUnion u_;\n};\n\n// Typedefs the instances of the FloatingPoint template class that we\n// care to use.\ntypedef FloatingPoint<float> Float;\ntypedef FloatingPoint<double> Double;\n\n// In order to catch the mistake of putting tests that use different\n// test fixture classes in the same test case, we need to assign\n// unique IDs to fixture classes and compare them.  The TypeId type is\n// used to hold such IDs.  The user should treat TypeId as an opaque\n// type: the only operation allowed on TypeId values is to compare\n// them for equality using the == operator.\ntypedef const void* TypeId;\n\ntemplate <typename T>\nclass TypeIdHelper {\n public:\n  // dummy_ must not have a const type.  Otherwise an overly eager\n  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge\n  // TypeIdHelper<T>::dummy_ for different Ts as an \"optimization\".\n  static bool dummy_;\n};\n\ntemplate <typename T>\nbool TypeIdHelper<T>::dummy_ = false;\n\n// GetTypeId<T>() returns the ID of type T.  Different values will be\n// returned for different types.  Calling the function twice with the\n// same type argument is guaranteed to return the same ID.\ntemplate <typename T>\nTypeId GetTypeId() {\n  // The compiler is required to allocate a different\n  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate\n  // the template.  Therefore, the address of dummy_ is guaranteed to\n  // be unique.\n  return &(TypeIdHelper<T>::dummy_);\n}\n\n// Returns the type ID of ::testing::Test.  Always call this instead\n// of GetTypeId< ::testing::Test>() to get the type ID of\n// ::testing::Test, as the latter may give the wrong result due to a\n// suspected linker bug when compiling Google Test as a Mac OS X\n// framework.\nGTEST_API_ TypeId GetTestTypeId();\n\n// Defines the abstract factory interface that creates instances\n// of a Test object.\nclass TestFactoryBase {\n public:\n  virtual ~TestFactoryBase() {}\n\n  // Creates a test instance to run. The instance is both created and destroyed\n  // within TestInfoImpl::Run()\n  virtual Test* CreateTest() = 0;\n\n protected:\n  TestFactoryBase() {}\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);\n};\n\n// This class provides implementation of TeastFactoryBase interface.\n// It is used in TEST and TEST_F macros.\ntemplate <class TestClass>\nclass TestFactoryImpl : public TestFactoryBase {\n public:\n  virtual Test* CreateTest() { return new TestClass; }\n};\n\n#if GTEST_OS_WINDOWS\n\n// Predicate-formatters for implementing the HRESULT checking macros\n// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}\n// We pass a long instead of HRESULT to avoid causing an\n// include dependency for the HRESULT type.\nGTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,\n                                            long hr);  // NOLINT\nGTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,\n                                            long hr);  // NOLINT\n\n#endif  // GTEST_OS_WINDOWS\n\n// Types of SetUpTestCase() and TearDownTestCase() functions.\ntypedef void (*SetUpTestCaseFunc)();\ntypedef void (*TearDownTestCaseFunc)();\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_case_name:   name of the test case\n//   name:             name of the test\n//   type_param        the name of the test's type parameter, or NULL if\n//                     this is not  a typed or a type-parameterized test.\n//   value_param       text representation of the test's value parameter,\n//                     or NULL if this is not a type-parameterized test.\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test case\n//   tear_down_tc:     pointer to the function that tears down the test case\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nGTEST_API_ TestInfo* MakeAndRegisterTestInfo(\n    const char* test_case_name, const char* name,\n    const char* type_param,\n    const char* value_param,\n    TypeId fixture_class_id,\n    SetUpTestCaseFunc set_up_tc,\n    TearDownTestCaseFunc tear_down_tc,\n    TestFactoryBase* factory);\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nGTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);\n\n#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\n\n// State of the definition of a type-parameterized test case.\nclass GTEST_API_ TypedTestCasePState {\n public:\n  TypedTestCasePState() : registered_(false) {}\n\n  // Adds the given test name to defined_test_names_ and return true\n  // if the test case hasn't been registered; otherwise aborts the\n  // program.\n  bool AddTestName(const char* file, int line, const char* case_name,\n                   const char* test_name) {\n    if (registered_) {\n      fprintf(stderr, \"%s Test %s must be defined before \"\n              \"REGISTER_TYPED_TEST_CASE_P(%s, ...).\\n\",\n              FormatFileLocation(file, line).c_str(), test_name, case_name);\n      fflush(stderr);\n      posix::Abort();\n    }\n    defined_test_names_.insert(test_name);\n    return true;\n  }\n\n  // Verifies that registered_tests match the test names in\n  // defined_test_names_; returns registered_tests if successful, or\n  // aborts the program otherwise.\n  const char* VerifyRegisteredTestNames(\n      const char* file, int line, const char* registered_tests);\n\n private:\n  bool registered_;\n  ::std::set<const char*> defined_test_names_;\n};\n\n// Skips to the first non-space char after the first comma in 'str';\n// returns NULL if no comma is found in 'str'.\ninline const char* SkipComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  if (comma == NULL) {\n    return NULL;\n  }\n  while (IsSpace(*(++comma))) {}\n  return comma;\n}\n\n// Returns the prefix of 'str' before the first comma in it; returns\n// the entire string if it contains no comma.\ninline String GetPrefixUntilComma(const char* str) {\n  const char* comma = strchr(str, ',');\n  return comma == NULL ? String(str) : String(str, comma - str);\n}\n\n// TypeParameterizedTest<Fixture, TestSel, Types>::Register()\n// registers a list of type-parameterized tests with Google Test.  The\n// return value is insignificant - we just need to return something\n// such that we can call this function in a namespace scope.\n//\n// Implementation note: The GTEST_TEMPLATE_ macro declares a template\n// template parameter.  It's defined in gtest-type-util.h.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>\nclass TypeParameterizedTest {\n public:\n  // 'index' is the index of the test in the type list 'Types'\n  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,\n  // Types).  Valid values for 'index' are [0, N - 1] where N is the\n  // length of Types.\n  static bool Register(const char* prefix, const char* case_name,\n                       const char* test_names, int index) {\n    typedef typename Types::Head Type;\n    typedef Fixture<Type> FixtureClass;\n    typedef typename GTEST_BIND_(TestSel, Type) TestClass;\n\n    // First, registers the first type-parameterized test in the type\n    // list.\n    MakeAndRegisterTestInfo(\n        String::Format(\"%s%s%s/%d\", prefix, prefix[0] == '\\0' ? \"\" : \"/\",\n                       case_name, index).c_str(),\n        GetPrefixUntilComma(test_names).c_str(),\n        GetTypeName<Type>().c_str(),\n        NULL,  // No value parameter.\n        GetTypeId<FixtureClass>(),\n        TestClass::SetUpTestCase,\n        TestClass::TearDownTestCase,\n        new TestFactoryImpl<TestClass>);\n\n    // Next, recurses (at compile time) with the tail of the type list.\n    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>\n        ::Register(prefix, case_name, test_names, index + 1);\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel>\nclass TypeParameterizedTest<Fixture, TestSel, Types0> {\n public:\n  static bool Register(const char* /*prefix*/, const char* /*case_name*/,\n                       const char* /*test_names*/, int /*index*/) {\n    return true;\n  }\n};\n\n// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()\n// registers *all combinations* of 'Tests' and 'Types' with Google\n// Test.  The return value is insignificant - we just need to return\n// something such that we can call this function in a namespace scope.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>\nclass TypeParameterizedTestCase {\n public:\n  static bool Register(const char* prefix, const char* case_name,\n                       const char* test_names) {\n    typedef typename Tests::Head Head;\n\n    // First, register the first test in 'Test' for each type in 'Types'.\n    TypeParameterizedTest<Fixture, Head, Types>::Register(\n        prefix, case_name, test_names, 0);\n\n    // Next, recurses (at compile time) with the tail of the test list.\n    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>\n        ::Register(prefix, case_name, SkipComma(test_names));\n  }\n};\n\n// The base case for the compile time recursion.\ntemplate <GTEST_TEMPLATE_ Fixture, typename Types>\nclass TypeParameterizedTestCase<Fixture, Templates0, Types> {\n public:\n  static bool Register(const char* /*prefix*/, const char* /*case_name*/,\n                       const char* /*test_names*/) {\n    return true;\n  }\n};\n\n#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\n\n// Returns the current OS stack trace as a String.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nGTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,\n                                                  int skip_count);\n\n// Helpers for suppressing warnings on unreachable code or constant\n// condition.\n\n// Always returns true.\nGTEST_API_ bool AlwaysTrue();\n\n// Always returns false.\ninline bool AlwaysFalse() { return !AlwaysTrue(); }\n\n// Helper for suppressing false warning from Clang on a const char*\n// variable declared in a conditional expression always being NULL in\n// the else branch.\nstruct GTEST_API_ ConstCharPtr {\n  ConstCharPtr(const char* str) : value(str) {}\n  operator bool() const { return true; }\n  const char* value;\n};\n\n// A simple Linear Congruential Generator for generating random\n// numbers with a uniform distribution.  Unlike rand() and srand(), it\n// doesn't use global state (and therefore can't interfere with user\n// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,\n// but it's good enough for our purposes.\nclass GTEST_API_ Random {\n public:\n  static const UInt32 kMaxRange = 1u << 31;\n\n  explicit Random(UInt32 seed) : state_(seed) {}\n\n  void Reseed(UInt32 seed) { state_ = seed; }\n\n  // Generates a random number from [0, range).  Crashes if 'range' is\n  // 0 or greater than kMaxRange.\n  UInt32 Generate(UInt32 range);\n\n private:\n  UInt32 state_;\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);\n};\n\n// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a\n// compiler error iff T1 and T2 are different types.\ntemplate <typename T1, typename T2>\nstruct CompileAssertTypesEqual;\n\ntemplate <typename T>\nstruct CompileAssertTypesEqual<T, T> {\n};\n\n// Removes the reference from a type if it is a reference type,\n// otherwise leaves it unchanged.  This is the same as\n// tr1::remove_reference, which is not widely available yet.\ntemplate <typename T>\nstruct RemoveReference { typedef T type; };  // NOLINT\ntemplate <typename T>\nstruct RemoveReference<T&> { typedef T type; };  // NOLINT\n\n// A handy wrapper around RemoveReference that works when the argument\n// T depends on template parameters.\n#define GTEST_REMOVE_REFERENCE_(T) \\\n    typename ::testing::internal::RemoveReference<T>::type\n\n// Removes const from a type if it is a const type, otherwise leaves\n// it unchanged.  This is the same as tr1::remove_const, which is not\n// widely available yet.\ntemplate <typename T>\nstruct RemoveConst { typedef T type; };  // NOLINT\ntemplate <typename T>\nstruct RemoveConst<const T> { typedef T type; };  // NOLINT\n\n// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above\n// definition to fail to remove the const in 'const int[3]' and 'const\n// char[3][4]'.  The following specialization works around the bug.\n// However, it causes trouble with GCC and thus needs to be\n// conditionally compiled.\n#if defined(_MSC_VER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)\ntemplate <typename T, size_t N>\nstruct RemoveConst<const T[N]> {\n  typedef typename RemoveConst<T>::type type[N];\n};\n#endif\n\n// A handy wrapper around RemoveConst that works when the argument\n// T depends on template parameters.\n#define GTEST_REMOVE_CONST_(T) \\\n    typename ::testing::internal::RemoveConst<T>::type\n\n// Turns const U&, U&, const U, and U all into U.\n#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \\\n    GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))\n\n// Adds reference to a type if it is not a reference type,\n// otherwise leaves it unchanged.  This is the same as\n// tr1::add_reference, which is not widely available yet.\ntemplate <typename T>\nstruct AddReference { typedef T& type; };  // NOLINT\ntemplate <typename T>\nstruct AddReference<T&> { typedef T& type; };  // NOLINT\n\n// A handy wrapper around AddReference that works when the argument T\n// depends on template parameters.\n#define GTEST_ADD_REFERENCE_(T) \\\n    typename ::testing::internal::AddReference<T>::type\n\n// Adds a reference to const on top of T as necessary.  For example,\n// it transforms\n//\n//   char         ==> const char&\n//   const char   ==> const char&\n//   char&        ==> const char&\n//   const char&  ==> const char&\n//\n// The argument T must depend on some template parameters.\n#define GTEST_REFERENCE_TO_CONST_(T) \\\n    GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))\n\n// ImplicitlyConvertible<From, To>::value is a compile-time bool\n// constant that's true iff type From can be implicitly converted to\n// type To.\ntemplate <typename From, typename To>\nclass ImplicitlyConvertible {\n private:\n  // We need the following helper functions only for their types.\n  // They have no implementations.\n\n  // MakeFrom() is an expression whose type is From.  We cannot simply\n  // use From(), as the type From may not have a public default\n  // constructor.\n  static From MakeFrom();\n\n  // These two functions are overloaded.  Given an expression\n  // Helper(x), the compiler will pick the first version if x can be\n  // implicitly converted to type To; otherwise it will pick the\n  // second version.\n  //\n  // The first version returns a value of size 1, and the second\n  // version returns a value of size 2.  Therefore, by checking the\n  // size of Helper(x), which can be done at compile time, we can tell\n  // which version of Helper() is used, and hence whether x can be\n  // implicitly converted to type To.\n  static char Helper(To);\n  static char (&Helper(...))[2];  // NOLINT\n\n  // We have to put the 'public' section after the 'private' section,\n  // or MSVC refuses to compile the code.\n public:\n  // MSVC warns about implicitly converting from double to int for\n  // possible loss of data, so we need to temporarily disable the\n  // warning.\n#ifdef _MSC_VER\n# pragma warning(push)          // Saves the current warning state.\n# pragma warning(disable:4244)  // Temporarily disables warning 4244.\n\n  static const bool value =\n      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;\n# pragma warning(pop)           // Restores the warning state.\n#elif defined(__BORLANDC__)\n  // C++Builder cannot use member overload resolution during template\n  // instantiation.  The simplest workaround is to use its C++0x type traits\n  // functions (C++Builder 2009 and above only).\n  static const bool value = __is_convertible(From, To);\n#else\n  static const bool value =\n      sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;\n#endif  // _MSV_VER\n};\ntemplate <typename From, typename To>\nconst bool ImplicitlyConvertible<From, To>::value;\n\n// IsAProtocolMessage<T>::value is a compile-time bool constant that's\n// true iff T is type ProtocolMessage, proto2::Message, or a subclass\n// of those.\ntemplate <typename T>\nstruct IsAProtocolMessage\n    : public bool_constant<\n  ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||\n  ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {\n};\n\n// When the compiler sees expression IsContainerTest<C>(0), if C is an\n// STL-style container class, the first overload of IsContainerTest\n// will be viable (since both C::iterator* and C::const_iterator* are\n// valid types and NULL can be implicitly converted to them).  It will\n// be picked over the second overload as 'int' is a perfect match for\n// the type of argument 0.  If C::iterator or C::const_iterator is not\n// a valid type, the first overload is not viable, and the second\n// overload will be picked.  Therefore, we can determine whether C is\n// a container class by checking the type of IsContainerTest<C>(0).\n// The value of the expression is insignificant.\n//\n// Note that we look for both C::iterator and C::const_iterator.  The\n// reason is that C++ injects the name of a class as a member of the\n// class itself (e.g. you can refer to class iterator as either\n// 'iterator' or 'iterator::iterator').  If we look for C::iterator\n// only, for example, we would mistakenly think that a class named\n// iterator is an STL container.\n//\n// Also note that the simpler approach of overloading\n// IsContainerTest(typename C::const_iterator*) and\n// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.\ntypedef int IsContainer;\ntemplate <class C>\nIsContainer IsContainerTest(int /* dummy */,\n                            typename C::iterator* /* it */ = NULL,\n                            typename C::const_iterator* /* const_it */ = NULL) {\n  return 0;\n}\n\ntypedef char IsNotContainer;\ntemplate <class C>\nIsNotContainer IsContainerTest(long /* dummy */) { return '\\0'; }\n\n// EnableIf<condition>::type is void when 'Cond' is true, and\n// undefined when 'Cond' is false.  To use SFINAE to make a function\n// overload only apply when a particular expression is true, add\n// \"typename EnableIf<expression>::type* = 0\" as the last parameter.\ntemplate<bool> struct EnableIf;\ntemplate<> struct EnableIf<true> { typedef void type; };  // NOLINT\n\n// Utilities for native arrays.\n\n// ArrayEq() compares two k-dimensional native arrays using the\n// elements' operator==, where k can be any integer >= 0.  When k is\n// 0, ArrayEq() degenerates into comparing a single pair of values.\n\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; }\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) {\n  return internal::ArrayEq(lhs, N, rhs);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous ArrayEq() function, arrays with different sizes would\n// lead to different copies of the template code.\ntemplate <typename T, typename U>\nbool ArrayEq(const T* lhs, size_t size, const U* rhs) {\n  for (size_t i = 0; i != size; i++) {\n    if (!internal::ArrayEq(lhs[i], rhs[i]))\n      return false;\n  }\n  return true;\n}\n\n// Finds the first element in the iterator range [begin, end) that\n// equals elem.  Element may be a native array type itself.\ntemplate <typename Iter, typename Element>\nIter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {\n  for (Iter it = begin; it != end; ++it) {\n    if (internal::ArrayEq(*it, elem))\n      return it;\n  }\n  return end;\n}\n\n// CopyArray() copies a k-dimensional native array using the elements'\n// operator=, where k can be any integer >= 0.  When k is 0,\n// CopyArray() degenerates into copying a single value.\n\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to);\n\n// This generic version is used when k is 0.\ntemplate <typename T, typename U>\ninline void CopyArray(const T& from, U* to) { *to = from; }\n\n// This overload is used when k >= 1.\ntemplate <typename T, typename U, size_t N>\ninline void CopyArray(const T(&from)[N], U(*to)[N]) {\n  internal::CopyArray(from, N, *to);\n}\n\n// This helper reduces code bloat.  If we instead put its logic inside\n// the previous CopyArray() function, arrays with different sizes\n// would lead to different copies of the template code.\ntemplate <typename T, typename U>\nvoid CopyArray(const T* from, size_t size, U* to) {\n  for (size_t i = 0; i != size; i++) {\n    internal::CopyArray(from[i], to + i);\n  }\n}\n\n// The relation between an NativeArray object (see below) and the\n// native array it represents.\nenum RelationToSource {\n  kReference,  // The NativeArray references the native array.\n  kCopy        // The NativeArray makes a copy of the native array and\n               // owns the copy.\n};\n\n// Adapts a native array to a read-only STL-style container.  Instead\n// of the complete STL container concept, this adaptor only implements\n// members useful for Google Mock's container matchers.  New members\n// should be added as needed.  To simplify the implementation, we only\n// support Element being a raw type (i.e. having no top-level const or\n// reference modifier).  It's the client's responsibility to satisfy\n// this requirement.  Element can be an array type itself (hence\n// multi-dimensional arrays are supported).\ntemplate <typename Element>\nclass NativeArray {\n public:\n  // STL-style container typedefs.\n  typedef Element value_type;\n  typedef Element* iterator;\n  typedef const Element* const_iterator;\n\n  // Constructs from a native array.\n  NativeArray(const Element* array, size_t count, RelationToSource relation) {\n    Init(array, count, relation);\n  }\n\n  // Copy constructor.\n  NativeArray(const NativeArray& rhs) {\n    Init(rhs.array_, rhs.size_, rhs.relation_to_source_);\n  }\n\n  ~NativeArray() {\n    // Ensures that the user doesn't instantiate NativeArray with a\n    // const or reference type.\n    static_cast<void>(StaticAssertTypeEqHelper<Element,\n        GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>());\n    if (relation_to_source_ == kCopy)\n      delete[] array_;\n  }\n\n  // STL-style container methods.\n  size_t size() const { return size_; }\n  const_iterator begin() const { return array_; }\n  const_iterator end() const { return array_ + size_; }\n  bool operator==(const NativeArray& rhs) const {\n    return size() == rhs.size() &&\n        ArrayEq(begin(), size(), rhs.begin());\n  }\n\n private:\n  // Initializes this object; makes a copy of the input array if\n  // 'relation' is kCopy.\n  void Init(const Element* array, size_t a_size, RelationToSource relation) {\n    if (relation == kReference) {\n      array_ = array;\n    } else {\n      Element* const copy = new Element[a_size];\n      CopyArray(array, a_size, copy);\n      array_ = copy;\n    }\n    size_ = a_size;\n    relation_to_source_ = relation;\n  }\n\n  const Element* array_;\n  size_t size_;\n  RelationToSource relation_to_source_;\n\n  GTEST_DISALLOW_ASSIGN_(NativeArray);\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#define GTEST_MESSAGE_AT_(file, line, message, result_type) \\\n  ::testing::internal::AssertHelper(result_type, file, line, message) \\\n    = ::testing::Message()\n\n#define GTEST_MESSAGE_(message, result_type) \\\n  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)\n\n#define GTEST_FATAL_FAILURE_(message) \\\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)\n\n#define GTEST_NONFATAL_FAILURE_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)\n\n#define GTEST_SUCCESS_(message) \\\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)\n\n// Suppresses MSVC warnings 4072 (unreachable code) for the code following\n// statement if it returns or throws (or doesn't return or throw in some\n// situations).\n#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \\\n  if (::testing::internal::AlwaysTrue()) { statement; }\n\n#define GTEST_TEST_THROW_(statement, expected_exception, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::internal::ConstCharPtr gtest_msg = \"\") { \\\n    bool gtest_caught_expected = false; \\\n    try { \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n    } \\\n    catch (expected_exception const&) { \\\n      gtest_caught_expected = true; \\\n    } \\\n    catch (...) { \\\n      gtest_msg.value = \\\n          \"Expected: \" #statement \" throws an exception of type \" \\\n          #expected_exception \".\\n  Actual: it throws a different type.\"; \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \\\n    } \\\n    if (!gtest_caught_expected) { \\\n      gtest_msg.value = \\\n          \"Expected: \" #statement \" throws an exception of type \" \\\n          #expected_exception \".\\n  Actual: it throws nothing.\"; \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \\\n    } \\\n  } else \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \\\n      fail(gtest_msg.value)\n\n#define GTEST_TEST_NO_THROW_(statement, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::internal::AlwaysTrue()) { \\\n    try { \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n    } \\\n    catch (...) { \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \\\n    } \\\n  } else \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \\\n      fail(\"Expected: \" #statement \" doesn't throw an exception.\\n\" \\\n           \"  Actual: it throws.\")\n\n#define GTEST_TEST_ANY_THROW_(statement, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::internal::AlwaysTrue()) { \\\n    bool gtest_caught_any = false; \\\n    try { \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n    } \\\n    catch (...) { \\\n      gtest_caught_any = true; \\\n    } \\\n    if (!gtest_caught_any) { \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \\\n    } \\\n  } else \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \\\n      fail(\"Expected: \" #statement \" throws an exception.\\n\" \\\n           \"  Actual: it doesn't.\")\n\n\n// Implements Boolean test assertions such as EXPECT_TRUE. expression can be\n// either a boolean expression or an AssertionResult. text is a textual\n// represenation of expression as it was passed into the EXPECT_TRUE.\n#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (const ::testing::AssertionResult gtest_ar_ = \\\n      ::testing::AssertionResult(expression)) \\\n    ; \\\n  else \\\n    fail(::testing::internal::GetBoolAssertionFailureMessage(\\\n        gtest_ar_, text, #actual, #expected).c_str())\n\n#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::internal::AlwaysTrue()) { \\\n    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \\\n    } \\\n  } else \\\n    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \\\n      fail(\"Expected: \" #statement \" doesn't generate new fatal \" \\\n           \"failures in the current thread.\\n\" \\\n           \"  Actual: it does.\")\n\n// Expands to the name of the class that implements the given test.\n#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \\\n  test_case_name##_##test_name##_Test\n\n// Helper macro for defining tests.\n#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\\\nclass GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\\\n public:\\\n  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\\\n private:\\\n  virtual void TestBody();\\\n  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\\\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(\\\n      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\\\n};\\\n\\\n::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\\\n  ::test_info_ =\\\n    ::testing::internal::MakeAndRegisterTestInfo(\\\n        #test_case_name, #test_name, NULL, NULL, \\\n        (parent_id), \\\n        parent_class::SetUpTestCase, \\\n        parent_class::TearDownTestCase, \\\n        new ::testing::internal::TestFactoryImpl<\\\n            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\\\nvoid GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file defines the public API for death tests.  It is\n// #included by gtest.h so a user doesn't need to include this\n// directly.\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file defines internal utilities needed for implementing\n// death tests.  They are subject to change without notice.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n\n\n#include <stdio.h>\n\nnamespace testing {\nnamespace internal {\n\nGTEST_DECLARE_string_(internal_run_death_test);\n\n// Names of the flags (needed for parsing Google Test flags).\nconst char kDeathTestStyleFlag[] = \"death_test_style\";\nconst char kDeathTestUseFork[] = \"death_test_use_fork\";\nconst char kInternalRunDeathTestFlag[] = \"internal_run_death_test\";\n\n#if GTEST_HAS_DEATH_TEST\n\n// DeathTest is a class that hides much of the complexity of the\n// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method\n// returns a concrete class that depends on the prevailing death test\n// style, as defined by the --gtest_death_test_style and/or\n// --gtest_internal_run_death_test flags.\n\n// In describing the results of death tests, these terms are used with\n// the corresponding definitions:\n//\n// exit status:  The integer exit information in the format specified\n//               by wait(2)\n// exit code:    The integer code passed to exit(3), _exit(2), or\n//               returned from main()\nclass GTEST_API_ DeathTest {\n public:\n  // Create returns false if there was an error determining the\n  // appropriate action to take for the current death test; for example,\n  // if the gtest_death_test_style flag is set to an invalid value.\n  // The LastMessage method will return a more detailed message in that\n  // case.  Otherwise, the DeathTest pointer pointed to by the \"test\"\n  // argument is set.  If the death test should be skipped, the pointer\n  // is set to NULL; otherwise, it is set to the address of a new concrete\n  // DeathTest object that controls the execution of the current test.\n  static bool Create(const char* statement, const RE* regex,\n                     const char* file, int line, DeathTest** test);\n  DeathTest();\n  virtual ~DeathTest() { }\n\n  // A helper class that aborts a death test when it's deleted.\n  class ReturnSentinel {\n   public:\n    explicit ReturnSentinel(DeathTest* test) : test_(test) { }\n    ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }\n   private:\n    DeathTest* const test_;\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);\n  } GTEST_ATTRIBUTE_UNUSED_;\n\n  // An enumeration of possible roles that may be taken when a death\n  // test is encountered.  EXECUTE means that the death test logic should\n  // be executed immediately.  OVERSEE means that the program should prepare\n  // the appropriate environment for a child process to execute the death\n  // test, then wait for it to complete.\n  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };\n\n  // An enumeration of the three reasons that a test might be aborted.\n  enum AbortReason {\n    TEST_ENCOUNTERED_RETURN_STATEMENT,\n    TEST_THREW_EXCEPTION,\n    TEST_DID_NOT_DIE\n  };\n\n  // Assumes one of the above roles.\n  virtual TestRole AssumeRole() = 0;\n\n  // Waits for the death test to finish and returns its status.\n  virtual int Wait() = 0;\n\n  // Returns true if the death test passed; that is, the test process\n  // exited during the test, its exit status matches a user-supplied\n  // predicate, and its stderr output matches a user-supplied regular\n  // expression.\n  // The user-supplied predicate may be a macro expression rather\n  // than a function pointer or functor, or else Wait and Passed could\n  // be combined.\n  virtual bool Passed(bool exit_status_ok) = 0;\n\n  // Signals that the death test did not die as expected.\n  virtual void Abort(AbortReason reason) = 0;\n\n  // Returns a human-readable outcome message regarding the outcome of\n  // the last death test.\n  static const char* LastMessage();\n\n  static void set_last_death_test_message(const String& message);\n\n private:\n  // A string containing a description of the outcome of the last death test.\n  static String last_death_test_message_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);\n};\n\n// Factory interface for death tests.  May be mocked out for testing.\nclass DeathTestFactory {\n public:\n  virtual ~DeathTestFactory() { }\n  virtual bool Create(const char* statement, const RE* regex,\n                      const char* file, int line, DeathTest** test) = 0;\n};\n\n// A concrete DeathTestFactory implementation for normal use.\nclass DefaultDeathTestFactory : public DeathTestFactory {\n public:\n  virtual bool Create(const char* statement, const RE* regex,\n                      const char* file, int line, DeathTest** test);\n};\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nGTEST_API_ bool ExitedUnsuccessfully(int exit_status);\n\n// Traps C++ exceptions escaping statement and reports them as test\n// failures. Note that trapping SEH exceptions is not implemented here.\n# if GTEST_HAS_EXCEPTIONS\n#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\n  try { \\\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n  } catch (const ::std::exception& gtest_exception) { \\\n    fprintf(\\\n        stderr, \\\n        \"\\n%s: Caught std::exception-derived exception escaping the \" \\\n        \"death test statement. Exception message: %s\\n\", \\\n        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \\\n        gtest_exception.what()); \\\n    fflush(stderr); \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  } catch (...) { \\\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\n  }\n\n# else\n#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\n  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n\n# endif\n\n// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,\n// ASSERT_EXIT*, and EXPECT_EXIT*.\n# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::internal::AlwaysTrue()) { \\\n    const ::testing::internal::RE& gtest_regex = (regex); \\\n    ::testing::internal::DeathTest* gtest_dt; \\\n    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \\\n        __FILE__, __LINE__, &gtest_dt)) { \\\n      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \\\n    } \\\n    if (gtest_dt != NULL) { \\\n      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \\\n          gtest_dt_ptr(gtest_dt); \\\n      switch (gtest_dt->AssumeRole()) { \\\n        case ::testing::internal::DeathTest::OVERSEE_TEST: \\\n          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \\\n            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \\\n          } \\\n          break; \\\n        case ::testing::internal::DeathTest::EXECUTE_TEST: { \\\n          ::testing::internal::DeathTest::ReturnSentinel \\\n              gtest_sentinel(gtest_dt); \\\n          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \\\n          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \\\n          break; \\\n        } \\\n        default: \\\n          break; \\\n      } \\\n    } \\\n  } else \\\n    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \\\n      fail(::testing::internal::DeathTest::LastMessage())\n// The symbol \"fail\" here expands to something into which a message\n// can be streamed.\n\n// A class representing the parsed contents of the\n// --gtest_internal_run_death_test flag, as it existed when\n// RUN_ALL_TESTS was called.\nclass InternalRunDeathTestFlag {\n public:\n  InternalRunDeathTestFlag(const String& a_file,\n                           int a_line,\n                           int an_index,\n                           int a_write_fd)\n      : file_(a_file), line_(a_line), index_(an_index),\n        write_fd_(a_write_fd) {}\n\n  ~InternalRunDeathTestFlag() {\n    if (write_fd_ >= 0)\n      posix::Close(write_fd_);\n  }\n\n  String file() const { return file_; }\n  int line() const { return line_; }\n  int index() const { return index_; }\n  int write_fd() const { return write_fd_; }\n\n private:\n  String file_;\n  int line_;\n  int index_;\n  int write_fd_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);\n};\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();\n\n#else  // GTEST_HAS_DEATH_TEST\n\n// This macro is used for implementing macros such as\n// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where\n// death tests are not supported. Those macros must compile on such systems\n// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on\n// systems that support death tests. This allows one to write such a macro\n// on a system that does not support death tests and be sure that it will\n// compile on a death-test supporting system.\n//\n// Parameters:\n//   statement -  A statement that a macro such as EXPECT_DEATH would test\n//                for program termination. This macro has to make sure this\n//                statement is compiled but not executed, to ensure that\n//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain\n//                parameter iff EXPECT_DEATH compiles with it.\n//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test\n//                the output of statement.  This parameter has to be\n//                compiled but not evaluated by this macro, to ensure that\n//                this macro only accepts expressions that a macro such as\n//                EXPECT_DEATH would accept.\n//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED\n//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.\n//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not\n//                compile inside functions where ASSERT_DEATH doesn't\n//                compile.\n//\n//  The branch that has an always false condition is used to ensure that\n//  statement and regex are compiled (and thus syntactically correct) but\n//  never executed. The unreachable code macro protects the terminator\n//  statement from generating an 'unreachable code' warning in case\n//  statement unconditionally returns or throws. The Message constructor at\n//  the end allows the syntax of streaming additional messages into the\n//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.\n# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \\\n    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n    if (::testing::internal::AlwaysTrue()) { \\\n      GTEST_LOG_(WARNING) \\\n          << \"Death tests are not supported on this platform.\\n\" \\\n          << \"Statement '\" #statement \"' cannot be verified.\"; \\\n    } else if (::testing::internal::AlwaysFalse()) { \\\n      ::testing::internal::RE::PartialMatch(\".*\", (regex)); \\\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\n      terminator; \\\n    } else \\\n      ::testing::Message()\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\n\nnamespace testing {\n\n// This flag controls the style of death tests.  Valid values are \"threadsafe\",\n// meaning that the death test child process will re-execute the test binary\n// from the start, running only a single death test, or \"fast\",\n// meaning that the child process will execute the test logic immediately\n// after forking.\nGTEST_DECLARE_string_(death_test_style);\n\n#if GTEST_HAS_DEATH_TEST\n\n// The following macros are useful for writing death tests.\n\n// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is\n// executed:\n//\n//   1. It generates a warning if there is more than one active\n//   thread.  This is because it's safe to fork() or clone() only\n//   when there is a single thread.\n//\n//   2. The parent process clone()s a sub-process and runs the death\n//   test in it; the sub-process exits with code 0 at the end of the\n//   death test, if it hasn't exited already.\n//\n//   3. The parent process waits for the sub-process to terminate.\n//\n//   4. The parent process checks the exit code and error message of\n//   the sub-process.\n//\n// Examples:\n//\n//   ASSERT_DEATH(server.SendMessage(56, \"Hello\"), \"Invalid port number\");\n//   for (int i = 0; i < 5; i++) {\n//     EXPECT_DEATH(server.ProcessRequest(i),\n//                  \"Invalid request .* in ProcessRequest()\")\n//         << \"Failed to die on request \" << i);\n//   }\n//\n//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), \"Exiting\");\n//\n//   bool KilledBySIGHUP(int exit_code) {\n//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;\n//   }\n//\n//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, \"Hanging up!\");\n//\n// On the regular expressions used in death tests:\n//\n//   On POSIX-compliant systems (*nix), we use the <regex.h> library,\n//   which uses the POSIX extended regex syntax.\n//\n//   On other platforms (e.g. Windows), we only support a simple regex\n//   syntax implemented as part of Google Test.  This limited\n//   implementation should be enough most of the time when writing\n//   death tests; though it lacks many features you can find in PCRE\n//   or POSIX extended regex syntax.  For example, we don't support\n//   union (\"x|y\"), grouping (\"(xy)\"), brackets (\"[xy]\"), and\n//   repetition count (\"x{5,7}\"), among others.\n//\n//   Below is the syntax that we do support.  We chose it to be a\n//   subset of both PCRE and POSIX extended regex, so it's easy to\n//   learn wherever you come from.  In the following: 'A' denotes a\n//   literal character, period (.), or a single \\\\ escape sequence;\n//   'x' and 'y' denote regular expressions; 'm' and 'n' are for\n//   natural numbers.\n//\n//     c     matches any literal character c\n//     \\\\d   matches any decimal digit\n//     \\\\D   matches any character that's not a decimal digit\n//     \\\\f   matches \\f\n//     \\\\n   matches \\n\n//     \\\\r   matches \\r\n//     \\\\s   matches any ASCII whitespace, including \\n\n//     \\\\S   matches any character that's not a whitespace\n//     \\\\t   matches \\t\n//     \\\\v   matches \\v\n//     \\\\w   matches any letter, _, or decimal digit\n//     \\\\W   matches any character that \\\\w doesn't match\n//     \\\\c   matches any literal character c, which must be a punctuation\n//     .     matches any single character except \\n\n//     A?    matches 0 or 1 occurrences of A\n//     A*    matches 0 or many occurrences of A\n//     A+    matches 1 or many occurrences of A\n//     ^     matches the beginning of a string (not that of each line)\n//     $     matches the end of a string (not that of each line)\n//     xy    matches x followed by y\n//\n//   If you accidentally use PCRE or POSIX extended regex features\n//   not implemented by us, you will get a run-time failure.  In that\n//   case, please try to rewrite your regular expression within the\n//   above syntax.\n//\n//   This implementation is *not* meant to be as highly tuned or robust\n//   as a compiled regex library, but should perform well enough for a\n//   death test, which already incurs significant overhead by launching\n//   a child process.\n//\n// Known caveats:\n//\n//   A \"threadsafe\" style death test obtains the path to the test\n//   program from argv[0] and re-executes it in the sub-process.  For\n//   simplicity, the current implementation doesn't search the PATH\n//   when launching the sub-process.  This means that the user must\n//   invoke the test program via a path that contains at least one\n//   path separator (e.g. path/to/foo_test and\n//   /absolute/path/to/bar_test are fine, but foo_test is not).  This\n//   is rarely a problem as people usually don't put the test binary\n//   directory in PATH.\n//\n// TODO(wan@google.com): make thread-safe death tests search the PATH.\n\n// Asserts that a given statement causes the program to exit, with an\n// integer exit status that satisfies predicate, and emitting error output\n// that matches regex.\n# define ASSERT_EXIT(statement, predicate, regex) \\\n    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)\n\n// Like ASSERT_EXIT, but continues on to successive tests in the\n// test case, if any:\n# define EXPECT_EXIT(statement, predicate, regex) \\\n    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)\n\n// Asserts that a given statement causes the program to exit, either by\n// explicitly exiting with a nonzero exit code or being killed by a\n// signal, and emitting error output that matches regex.\n# define ASSERT_DEATH(statement, regex) \\\n    ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)\n\n// Like ASSERT_DEATH, but continues on to successive tests in the\n// test case, if any:\n# define EXPECT_DEATH(statement, regex) \\\n    EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)\n\n// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:\n\n// Tests that an exit code describes a normal exit with a given exit code.\nclass GTEST_API_ ExitedWithCode {\n public:\n  explicit ExitedWithCode(int exit_code);\n  bool operator()(int exit_status) const;\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ExitedWithCode& other);\n\n  const int exit_code_;\n};\n\n# if !GTEST_OS_WINDOWS\n// Tests that an exit code describes an exit due to termination by a\n// given signal.\nclass GTEST_API_ KilledBySignal {\n public:\n  explicit KilledBySignal(int signum);\n  bool operator()(int exit_status) const;\n private:\n  const int signum_;\n};\n# endif  // !GTEST_OS_WINDOWS\n\n// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.\n// The death testing framework causes this to have interesting semantics,\n// since the sideeffects of the call are only visible in opt mode, and not\n// in debug mode.\n//\n// In practice, this can be used to test functions that utilize the\n// LOG(DFATAL) macro using the following style:\n//\n// int DieInDebugOr12(int* sideeffect) {\n//   if (sideeffect) {\n//     *sideeffect = 12;\n//   }\n//   LOG(DFATAL) << \"death\";\n//   return 12;\n// }\n//\n// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {\n//   int sideeffect = 0;\n//   // Only asserts in dbg.\n//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), \"death\");\n//\n// #ifdef NDEBUG\n//   // opt-mode has sideeffect visible.\n//   EXPECT_EQ(12, sideeffect);\n// #else\n//   // dbg-mode no visible sideeffect.\n//   EXPECT_EQ(0, sideeffect);\n// #endif\n// }\n//\n// This will assert that DieInDebugReturn12InOpt() crashes in debug\n// mode, usually due to a DCHECK or LOG(DFATAL), but returns the\n// appropriate fallback value (12 in this case) in opt mode. If you\n// need to test that a function has appropriate side-effects in opt\n// mode, include assertions against the side-effects.  A general\n// pattern for this is:\n//\n// EXPECT_DEBUG_DEATH({\n//   // Side-effects here will have an effect after this statement in\n//   // opt mode, but none in debug mode.\n//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));\n// }, \"death\");\n//\n# ifdef NDEBUG\n\n#  define EXPECT_DEBUG_DEATH(statement, regex) \\\n  do { statement; } while (::testing::internal::AlwaysFalse())\n\n#  define ASSERT_DEBUG_DEATH(statement, regex) \\\n  do { statement; } while (::testing::internal::AlwaysFalse())\n\n# else\n\n#  define EXPECT_DEBUG_DEATH(statement, regex) \\\n  EXPECT_DEATH(statement, regex)\n\n#  define ASSERT_DEBUG_DEATH(statement, regex) \\\n  ASSERT_DEATH(statement, regex)\n\n# endif  // NDEBUG for EXPECT_DEBUG_DEATH\n#endif  // GTEST_HAS_DEATH_TEST\n\n// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and\n// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if\n// death tests are supported; otherwise they just issue a warning.  This is\n// useful when you are combining death test assertions with normal test\n// assertions in one test.\n#if GTEST_HAS_DEATH_TEST\n# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n    EXPECT_DEATH(statement, regex)\n# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n    ASSERT_DEATH(statement, regex)\n#else\n# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\n    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )\n# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\n    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)\n#endif\n\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// The Google C++ Testing Framework (Google Test)\n//\n// This header file defines the Message class.\n//\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\n// leave some internal implementation details in this header file.\n// They are clearly marked by comments like this:\n//\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n//\n// Such code is NOT meant to be used by a user directly, and is subject\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\n// program!\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n\n#include <limits>\n\n\nnamespace testing {\n\n// The Message class works like an ostream repeater.\n//\n// Typical usage:\n//\n//   1. You stream a bunch of values to a Message object.\n//      It will remember the text in a stringstream.\n//   2. Then you stream the Message object to an ostream.\n//      This causes the text in the Message to be streamed\n//      to the ostream.\n//\n// For example;\n//\n//   testing::Message foo;\n//   foo << 1 << \" != \" << 2;\n//   std::cout << foo;\n//\n// will print \"1 != 2\".\n//\n// Message is not intended to be inherited from.  In particular, its\n// destructor is not virtual.\n//\n// Note that stringstream behaves differently in gcc and in MSVC.  You\n// can stream a NULL char pointer to it in the former, but not in the\n// latter (it causes an access violation if you do).  The Message\n// class hides this difference by treating a NULL char pointer as\n// \"(null)\".\nclass GTEST_API_ Message {\n private:\n  // The type of basic IO manipulators (endl, ends, and flush) for\n  // narrow streams.\n  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);\n\n public:\n  // Constructs an empty Message.\n  // We allocate the stringstream separately because otherwise each use of\n  // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's\n  // stack frame leading to huge stack frames in some cases; gcc does not reuse\n  // the stack space.\n  Message() : ss_(new ::std::stringstream) {\n    // By default, we want there to be enough precision when printing\n    // a double to a Message.\n    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);\n  }\n\n  // Copy constructor.\n  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT\n    *ss_ << msg.GetString();\n  }\n\n  // Constructs a Message from a C-string.\n  explicit Message(const char* str) : ss_(new ::std::stringstream) {\n    *ss_ << str;\n  }\n\n#if GTEST_OS_SYMBIAN\n  // Streams a value (either a pointer or not) to this object.\n  template <typename T>\n  inline Message& operator <<(const T& value) {\n    StreamHelper(typename internal::is_pointer<T>::type(), value);\n    return *this;\n  }\n#else\n  // Streams a non-pointer value to this object.\n  template <typename T>\n  inline Message& operator <<(const T& val) {\n    ::GTestStreamToHelper(ss_.get(), val);\n    return *this;\n  }\n\n  // Streams a pointer value to this object.\n  //\n  // This function is an overload of the previous one.  When you\n  // stream a pointer to a Message, this definition will be used as it\n  // is more specialized.  (The C++ Standard, section\n  // [temp.func.order].)  If you stream a non-pointer, then the\n  // previous definition will be used.\n  //\n  // The reason for this overload is that streaming a NULL pointer to\n  // ostream is undefined behavior.  Depending on the compiler, you\n  // may get \"0\", \"(nil)\", \"(null)\", or an access violation.  To\n  // ensure consistent result across compilers, we always treat NULL\n  // as \"(null)\".\n  template <typename T>\n  inline Message& operator <<(T* const& pointer) {  // NOLINT\n    if (pointer == NULL) {\n      *ss_ << \"(null)\";\n    } else {\n      ::GTestStreamToHelper(ss_.get(), pointer);\n    }\n    return *this;\n  }\n#endif  // GTEST_OS_SYMBIAN\n\n  // Since the basic IO manipulators are overloaded for both narrow\n  // and wide streams, we have to provide this specialized definition\n  // of operator <<, even though its body is the same as the\n  // templatized version above.  Without this definition, streaming\n  // endl or other basic IO manipulators to Message will confuse the\n  // compiler.\n  Message& operator <<(BasicNarrowIoManip val) {\n    *ss_ << val;\n    return *this;\n  }\n\n  // Instead of 1/0, we want to see true/false for bool values.\n  Message& operator <<(bool b) {\n    return *this << (b ? \"true\" : \"false\");\n  }\n\n  // These two overloads allow streaming a wide C string to a Message\n  // using the UTF-8 encoding.\n  Message& operator <<(const wchar_t* wide_c_str) {\n    return *this << internal::String::ShowWideCString(wide_c_str);\n  }\n  Message& operator <<(wchar_t* wide_c_str) {\n    return *this << internal::String::ShowWideCString(wide_c_str);\n  }\n\n#if GTEST_HAS_STD_WSTRING\n  // Converts the given wide string to a narrow string using the UTF-8\n  // encoding, and streams the result to this Message object.\n  Message& operator <<(const ::std::wstring& wstr);\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_HAS_GLOBAL_WSTRING\n  // Converts the given wide string to a narrow string using the UTF-8\n  // encoding, and streams the result to this Message object.\n  Message& operator <<(const ::wstring& wstr);\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n  // Gets the text streamed to this object so far as a String.\n  // Each '\\0' character in the buffer is replaced with \"\\\\0\".\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  internal::String GetString() const {\n    return internal::StringStreamToString(ss_.get());\n  }\n\n private:\n\n#if GTEST_OS_SYMBIAN\n  // These are needed as the Nokia Symbian Compiler cannot decide between\n  // const T& and const T* in a function template. The Nokia compiler _can_\n  // decide between class template specializations for T and T*, so a\n  // tr1::type_traits-like is_pointer works, and we can overload on that.\n  template <typename T>\n  inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) {\n    if (pointer == NULL) {\n      *ss_ << \"(null)\";\n    } else {\n      ::GTestStreamToHelper(ss_.get(), pointer);\n    }\n  }\n  template <typename T>\n  inline void StreamHelper(internal::false_type /*dummy*/, const T& value) {\n    ::GTestStreamToHelper(ss_.get(), value);\n  }\n#endif  // GTEST_OS_SYMBIAN\n\n  // We'll hold the text streamed to this object here.\n  const internal::scoped_ptr< ::std::stringstream> ss_;\n\n  // We declare (but don't implement) this to prevent the compiler\n  // from implementing the assignment operator.\n  void operator=(const Message&);\n};\n\n// Streams a Message to an ostream.\ninline std::ostream& operator <<(std::ostream& os, const Message& sb) {\n  return os << sb.GetString();\n}\n\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\n// This file was GENERATED by command:\n//     pump.py gtest-param-test.h.pump\n// DO NOT EDIT BY HAND!!!\n\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: vladl@google.com (Vlad Losev)\n//\n// Macros and functions for implementing parameterized tests\n// in Google C++ Testing Framework (Google Test)\n//\n// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\n//\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n\n\n// Value-parameterized tests allow you to test your code with different\n// parameters without writing multiple copies of the same test.\n//\n// Here is how you use value-parameterized tests:\n\n#if 0\n\n// To write value-parameterized tests, first you should define a fixture\n// class. It is usually derived from testing::TestWithParam<T> (see below for\n// another inheritance scheme that's sometimes useful in more complicated\n// class hierarchies), where the type of your parameter values.\n// TestWithParam<T> is itself derived from testing::Test. T can be any\n// copyable type. If it's a raw pointer, you are responsible for managing the\n// lifespan of the pointed values.\n\nclass FooTest : public ::testing::TestWithParam<const char*> {\n  // You can implement all the usual class fixture members here.\n};\n\n// Then, use the TEST_P macro to define as many parameterized tests\n// for this fixture as you want. The _P suffix is for \"parameterized\"\n// or \"pattern\", whichever you prefer to think.\n\nTEST_P(FooTest, DoesBlah) {\n  // Inside a test, access the test parameter with the GetParam() method\n  // of the TestWithParam<T> class:\n  EXPECT_TRUE(foo.Blah(GetParam()));\n  ...\n}\n\nTEST_P(FooTest, HasBlahBlah) {\n  ...\n}\n\n// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test\n// case with any set of parameters you want. Google Test defines a number\n// of functions for generating test parameters. They return what we call\n// (surprise!) parameter generators. Here is a  summary of them, which\n// are all in the testing namespace:\n//\n//\n//  Range(begin, end [, step]) - Yields values {begin, begin+step,\n//                               begin+step+step, ...}. The values do not\n//                               include end. step defaults to 1.\n//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.\n//  ValuesIn(container)        - Yields values from a C-style array, an STL\n//  ValuesIn(begin,end)          container, or an iterator range [begin, end).\n//  Bool()                     - Yields sequence {false, true}.\n//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product\n//                               for the math savvy) of the values generated\n//                               by the N generators.\n//\n// For more details, see comments at the definitions of these functions below\n// in this file.\n//\n// The following statement will instantiate tests from the FooTest test case\n// each with parameter values \"meeny\", \"miny\", and \"moe\".\n\nINSTANTIATE_TEST_CASE_P(InstantiationName,\n                        FooTest,\n                        Values(\"meeny\", \"miny\", \"moe\"));\n\n// To distinguish different instances of the pattern, (yes, you\n// can instantiate it more then once) the first argument to the\n// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the\n// actual test case name. Remember to pick unique prefixes for different\n// instantiations. The tests from the instantiation above will have\n// these names:\n//\n//    * InstantiationName/FooTest.DoesBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.DoesBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.DoesBlah/2 for \"moe\"\n//    * InstantiationName/FooTest.HasBlahBlah/0 for \"meeny\"\n//    * InstantiationName/FooTest.HasBlahBlah/1 for \"miny\"\n//    * InstantiationName/FooTest.HasBlahBlah/2 for \"moe\"\n//\n// You can use these names in --gtest_filter.\n//\n// This statement will instantiate all tests from FooTest again, each\n// with parameter values \"cat\" and \"dog\":\n\nconst char* pets[] = {\"cat\", \"dog\"};\nINSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));\n\n// The tests from the instantiation above will have these names:\n//\n//    * AnotherInstantiationName/FooTest.DoesBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.DoesBlah/1 for \"dog\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for \"cat\"\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for \"dog\"\n//\n// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests\n// in the given test case, whether their definitions come before or\n// AFTER the INSTANTIATE_TEST_CASE_P statement.\n//\n// Please also note that generator expressions (including parameters to the\n// generators) are evaluated in InitGoogleTest(), after main() has started.\n// This allows the user on one hand, to adjust generator parameters in order\n// to dynamically determine a set of tests to run and on the other hand,\n// give the user a chance to inspect the generated tests with Google Test\n// reflection API before RUN_ALL_TESTS() is executed.\n//\n// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc\n// for more examples.\n//\n// In the future, we plan to publish the API for defining new parameter\n// generators. But for now this interface remains part of the internal\n// implementation and is subject to change.\n//\n//\n// A parameterized test fixture must be derived from testing::Test and from\n// testing::WithParamInterface<T>, where T is the type of the parameter\n// values. Inheriting from TestWithParam<T> satisfies that requirement because\n// TestWithParam<T> inherits from both Test and WithParamInterface. In more\n// complicated hierarchies, however, it is occasionally useful to inherit\n// separately from Test and WithParamInterface. For example:\n\nclass BaseTest : public ::testing::Test {\n  // You can inherit all the usual members for a non-parameterized test\n  // fixture here.\n};\n\nclass DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {\n  // The usual test fixture members go here too.\n};\n\nTEST_F(BaseTest, HasFoo) {\n  // This is an ordinary non-parameterized test.\n}\n\nTEST_P(DerivedTest, DoesBlah) {\n  // GetParam works just the same here as if you inherit from TestWithParam.\n  EXPECT_TRUE(foo.Blah(GetParam()));\n}\n\n#endif  // 0\n\n\n#if !GTEST_OS_SYMBIAN\n# include <utility>\n#endif\n\n// scripts/fuse_gtest.py depends on gtest's own header being #included\n// *unconditionally*.  Therefore these #includes cannot be moved\n// inside #if GTEST_HAS_PARAM_TEST.\n// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: vladl@google.com (Vlad Losev)\n\n// Type and function utilities for implementing parameterized tests.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n\n#include <iterator>\n#include <utility>\n#include <vector>\n\n// scripts/fuse_gtest.py depends on gtest's own header being #included\n// *unconditionally*.  Therefore these #includes cannot be moved\n// inside #if GTEST_HAS_PARAM_TEST.\n// Copyright 2003 Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: Dan Egnor (egnor@google.com)\n//\n// A \"smart\" pointer type with reference tracking.  Every pointer to a\n// particular object is kept on a circular linked list.  When the last pointer\n// to an object is destroyed or reassigned, the object is deleted.\n//\n// Used properly, this deletes the object when the last reference goes away.\n// There are several caveats:\n// - Like all reference counting schemes, cycles lead to leaks.\n// - Each smart pointer is actually two pointers (8 bytes instead of 4).\n// - Every time a pointer is assigned, the entire list of pointers to that\n//   object is traversed.  This class is therefore NOT SUITABLE when there\n//   will often be more than two or three pointers to a particular object.\n// - References are only tracked as long as linked_ptr<> objects are copied.\n//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS\n//   will happen (double deletion).\n//\n// A good use of this class is storing object references in STL containers.\n// You can safely put linked_ptr<> in a vector<>.\n// Other uses may not be as good.\n//\n// Note: If you use an incomplete type with linked_ptr<>, the class\n// *containing* linked_ptr<> must have a constructor and destructor (even\n// if they do nothing!).\n//\n// Bill Gibbons suggested we use something like this.\n//\n// Thread Safety:\n//   Unlike other linked_ptr implementations, in this implementation\n//   a linked_ptr object is thread-safe in the sense that:\n//     - it's safe to copy linked_ptr objects concurrently,\n//     - it's safe to copy *from* a linked_ptr and read its underlying\n//       raw pointer (e.g. via get()) concurrently, and\n//     - it's safe to write to two linked_ptrs that point to the same\n//       shared object concurrently.\n// TODO(wan@google.com): rename this to safe_linked_ptr to avoid\n// confusion with normal linked_ptr.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\n\n#include <stdlib.h>\n#include <assert.h>\n\n\nnamespace testing {\nnamespace internal {\n\n// Protects copying of all linked_ptr objects.\nGTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);\n\n// This is used internally by all instances of linked_ptr<>.  It needs to be\n// a non-template class because different types of linked_ptr<> can refer to\n// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).\n// So, it needs to be possible for different types of linked_ptr to participate\n// in the same circular linked list, so we need a single class type here.\n//\n// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.\nclass linked_ptr_internal {\n public:\n  // Create a new circle that includes only this instance.\n  void join_new() {\n    next_ = this;\n  }\n\n  // Many linked_ptr operations may change p.link_ for some linked_ptr\n  // variable p in the same circle as this object.  Therefore we need\n  // to prevent two such operations from occurring concurrently.\n  //\n  // Note that different types of linked_ptr objects can coexist in a\n  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and\n  // linked_ptr<Derived2>).  Therefore we must use a single mutex to\n  // protect all linked_ptr objects.  This can create serious\n  // contention in production code, but is acceptable in a testing\n  // framework.\n\n  // Join an existing circle.\n  // L < g_linked_ptr_mutex\n  void join(linked_ptr_internal const* ptr) {\n    MutexLock lock(&g_linked_ptr_mutex);\n\n    linked_ptr_internal const* p = ptr;\n    while (p->next_ != ptr) p = p->next_;\n    p->next_ = this;\n    next_ = ptr;\n  }\n\n  // Leave whatever circle we're part of.  Returns true if we were the\n  // last member of the circle.  Once this is done, you can join() another.\n  // L < g_linked_ptr_mutex\n  bool depart() {\n    MutexLock lock(&g_linked_ptr_mutex);\n\n    if (next_ == this) return true;\n    linked_ptr_internal const* p = next_;\n    while (p->next_ != this) p = p->next_;\n    p->next_ = next_;\n    return false;\n  }\n\n private:\n  mutable linked_ptr_internal const* next_;\n};\n\ntemplate <typename T>\nclass linked_ptr {\n public:\n  typedef T element_type;\n\n  // Take over ownership of a raw pointer.  This should happen as soon as\n  // possible after the object is created.\n  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }\n  ~linked_ptr() { depart(); }\n\n  // Copy an existing linked_ptr<>, adding ourselves to the list of references.\n  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }\n  linked_ptr(linked_ptr const& ptr) {  // NOLINT\n    assert(&ptr != this);\n    copy(&ptr);\n  }\n\n  // Assignment releases the old value and acquires the new.\n  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {\n    depart();\n    copy(&ptr);\n    return *this;\n  }\n\n  linked_ptr& operator=(linked_ptr const& ptr) {\n    if (&ptr != this) {\n      depart();\n      copy(&ptr);\n    }\n    return *this;\n  }\n\n  // Smart pointer members.\n  void reset(T* ptr = NULL) {\n    depart();\n    capture(ptr);\n  }\n  T* get() const { return value_; }\n  T* operator->() const { return value_; }\n  T& operator*() const { return *value_; }\n\n  bool operator==(T* p) const { return value_ == p; }\n  bool operator!=(T* p) const { return value_ != p; }\n  template <typename U>\n  bool operator==(linked_ptr<U> const& ptr) const {\n    return value_ == ptr.get();\n  }\n  template <typename U>\n  bool operator!=(linked_ptr<U> const& ptr) const {\n    return value_ != ptr.get();\n  }\n\n private:\n  template <typename U>\n  friend class linked_ptr;\n\n  T* value_;\n  linked_ptr_internal link_;\n\n  void depart() {\n    if (link_.depart()) delete value_;\n  }\n\n  void capture(T* ptr) {\n    value_ = ptr;\n    link_.join_new();\n  }\n\n  template <typename U> void copy(linked_ptr<U> const* ptr) {\n    value_ = ptr->get();\n    if (value_)\n      link_.join(&ptr->link_);\n    else\n      link_.join_new();\n  }\n};\n\ntemplate<typename T> inline\nbool operator==(T* ptr, const linked_ptr<T>& x) {\n  return ptr == x.get();\n}\n\ntemplate<typename T> inline\nbool operator!=(T* ptr, const linked_ptr<T>& x) {\n  return ptr != x.get();\n}\n\n// A function to convert T* into linked_ptr<T>\n// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation\n// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))\ntemplate <typename T>\nlinked_ptr<T> make_linked_ptr(T* ptr) {\n  return linked_ptr<T>(ptr);\n}\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\n// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n// Google Test - The Google C++ Testing Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// A user can teach this function how to print a class type T by\n// defining either operator<<() or PrintTo() in the namespace that\n// defines T.  More specifically, the FIRST defined function in the\n// following list will be used (assuming T is defined in namespace\n// foo):\n//\n//   1. foo::PrintTo(const T&, ostream*)\n//   2. operator<<(ostream&, const T&) defined in either foo or the\n//      global namespace.\n//\n// If none of the above is defined, it will print the debug string of\n// the value if it is a protocol buffer, or print the raw bytes in the\n// value otherwise.\n//\n// To aid debugging: when T is a reference type, the address of the\n// value is also printed; when T is a (const) char pointer, both the\n// pointer value and the NUL-terminated string it points to are\n// printed.\n//\n// We also provide some convenient wrappers:\n//\n//   // Prints a value to a string.  For a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   std::string ::testing::PrintToString(const T& value);\n//\n//   // Prints a value tersely: for a reference type, the referenced\n//   // value (but not the address) is printed; for a (const or not) char\n//   // pointer, the NUL-terminated string (but not the pointer) is\n//   // printed.\n//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);\n//\n//   // Prints value using the type inferred by the compiler.  The difference\n//   // from UniversalTersePrint() is that this function prints both the\n//   // pointer and the NUL-terminated string for a (const or not) char pointer.\n//   void ::testing::internal::UniversalPrint(const T& value, ostream*);\n//\n//   // Prints the fields of a tuple tersely to a string vector, one\n//   // element for each field. Tuple support must be enabled in\n//   // gtest-port.h.\n//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(\n//       const Tuple& value);\n//\n// Known limitation:\n//\n// The print primitives print the elements of an STL-style container\n// using the compiler-inferred type of *iter where iter is a\n// const_iterator of the container.  When const_iterator is an input\n// iterator but not a forward iterator, this inferred type may not\n// match value_type, and the print output may be incorrect.  In\n// practice, this is rarely a problem as for most containers\n// const_iterator is a forward iterator.  We'll fix this if there's an\n// actual need for it.  Note that this fix cannot rely on value_type\n// being defined as many user-defined container types don't have\n// value_type.\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace testing {\n\n// Definitions in the 'internal' and 'internal2' name spaces are\n// subject to change without notice.  DO NOT USE THEM IN USER CODE!\nnamespace internal2 {\n\n// Prints the given number of bytes in the given object to the given\n// ostream.\nGTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,\n                                     size_t count,\n                                     ::std::ostream* os);\n\n// For selecting which printer to use when a given type has neither <<\n// nor PrintTo().\nenum TypeKind {\n  kProtobuf,              // a protobuf type\n  kConvertibleToInteger,  // a type implicitly convertible to BiggestInt\n                          // (e.g. a named or unnamed enum type)\n  kOtherType              // anything else\n};\n\n// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called\n// by the universal printer to print a value of type T when neither\n// operator<< nor PrintTo() is defined for T, where kTypeKind is the\n// \"kind\" of T as defined by enum TypeKind.\ntemplate <typename T, TypeKind kTypeKind>\nclass TypeWithoutFormatter {\n public:\n  // This default version is called when kTypeKind is kOtherType.\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),\n                         sizeof(value), os);\n  }\n};\n\n// We print a protobuf using its ShortDebugString() when the string\n// doesn't exceed this many characters; otherwise we print it using\n// DebugString() for better readability.\nconst size_t kProtobufOneLinerMaxLength = 50;\n\ntemplate <typename T>\nclass TypeWithoutFormatter<T, kProtobuf> {\n public:\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    const ::testing::internal::string short_str = value.ShortDebugString();\n    const ::testing::internal::string pretty_str =\n        short_str.length() <= kProtobufOneLinerMaxLength ?\n        short_str : (\"\\n\" + value.DebugString());\n    *os << (\"<\" + pretty_str + \">\");\n  }\n};\n\ntemplate <typename T>\nclass TypeWithoutFormatter<T, kConvertibleToInteger> {\n public:\n  // Since T has no << operator or PrintTo() but can be implicitly\n  // converted to BiggestInt, we print it as a BiggestInt.\n  //\n  // Most likely T is an enum type (either named or unnamed), in which\n  // case printing it as an integer is the desired behavior.  In case\n  // T is not an enum, printing it as an integer is the best we can do\n  // given that it has no user-defined printer.\n  static void PrintValue(const T& value, ::std::ostream* os) {\n    const internal::BiggestInt kBigInt = value;\n    *os << kBigInt;\n  }\n};\n\n// Prints the given value to the given ostream.  If the value is a\n// protocol message, its debug string is printed; if it's an enum or\n// of a type implicitly convertible to BiggestInt, it's printed as an\n// integer; otherwise the bytes in the value are printed.  This is\n// what UniversalPrinter<T>::Print() does when it knows nothing about\n// type T and T has neither << operator nor PrintTo().\n//\n// A user can override this behavior for a class type Foo by defining\n// a << operator in the namespace where Foo is defined.\n//\n// We put this operator in namespace 'internal2' instead of 'internal'\n// to simplify the implementation, as much code in 'internal' needs to\n// use << in STL, which would conflict with our own << were it defined\n// in 'internal'.\n//\n// Note that this operator<< takes a generic std::basic_ostream<Char,\n// CharTraits> type instead of the more restricted std::ostream.  If\n// we define it to take an std::ostream instead, we'll get an\n// \"ambiguous overloads\" compiler error when trying to print a type\n// Foo that supports streaming to std::basic_ostream<Char,\n// CharTraits>, as the compiler cannot tell whether\n// operator<<(std::ostream&, const T&) or\n// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more\n// specific.\ntemplate <typename Char, typename CharTraits, typename T>\n::std::basic_ostream<Char, CharTraits>& operator<<(\n    ::std::basic_ostream<Char, CharTraits>& os, const T& x) {\n  TypeWithoutFormatter<T,\n      (internal::IsAProtocolMessage<T>::value ? kProtobuf :\n       internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?\n       kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);\n  return os;\n}\n\n}  // namespace internal2\n}  // namespace testing\n\n// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up\n// magic needed for implementing UniversalPrinter won't work.\nnamespace testing_internal {\n\n// Used to print a value that is not an STL-style container when the\n// user doesn't define PrintTo() for it.\ntemplate <typename T>\nvoid DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {\n  // With the following statement, during unqualified name lookup,\n  // testing::internal2::operator<< appears as if it was declared in\n  // the nearest enclosing namespace that contains both\n  // ::testing_internal and ::testing::internal2, i.e. the global\n  // namespace.  For more details, refer to the C++ Standard section\n  // 7.3.4-1 [namespace.udir].  This allows us to fall back onto\n  // testing::internal2::operator<< in case T doesn't come with a <<\n  // operator.\n  //\n  // We cannot write 'using ::testing::internal2::operator<<;', which\n  // gcc 3.3 fails to compile due to a compiler bug.\n  using namespace ::testing::internal2;  // NOLINT\n\n  // Assuming T is defined in namespace foo, in the next statement,\n  // the compiler will consider all of:\n  //\n  //   1. foo::operator<< (thanks to Koenig look-up),\n  //   2. ::operator<< (as the current namespace is enclosed in ::),\n  //   3. testing::internal2::operator<< (thanks to the using statement above).\n  //\n  // The operator<< whose type matches T best will be picked.\n  //\n  // We deliberately allow #2 to be a candidate, as sometimes it's\n  // impossible to define #1 (e.g. when foo is ::std, defining\n  // anything in it is undefined behavior unless you are a compiler\n  // vendor.).\n  *os << value;\n}\n\n}  // namespace testing_internal\n\nnamespace testing {\nnamespace internal {\n\n// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given\n// value to the given ostream.  The caller must ensure that\n// 'ostream_ptr' is not NULL, or the behavior is undefined.\n//\n// We define UniversalPrinter as a class template (as opposed to a\n// function template), as we need to partially specialize it for\n// reference types, which cannot be done with function templates.\ntemplate <typename T>\nclass UniversalPrinter;\n\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os);\n\n// Used to print an STL-style container when the user doesn't define\n// a PrintTo() for it.\ntemplate <typename C>\nvoid DefaultPrintTo(IsContainer /* dummy */,\n                    false_type /* is not a pointer */,\n                    const C& container, ::std::ostream* os) {\n  const size_t kMaxCount = 32;  // The maximum number of elements to print.\n  *os << '{';\n  size_t count = 0;\n  for (typename C::const_iterator it = container.begin();\n       it != container.end(); ++it, ++count) {\n    if (count > 0) {\n      *os << ',';\n      if (count == kMaxCount) {  // Enough has been printed.\n        *os << \" ...\";\n        break;\n      }\n    }\n    *os << ' ';\n    // We cannot call PrintTo(*it, os) here as PrintTo() doesn't\n    // handle *it being a native array.\n    internal::UniversalPrint(*it, os);\n  }\n\n  if (count > 0) {\n    *os << ' ';\n  }\n  *os << '}';\n}\n\n// Used to print a pointer that is neither a char pointer nor a member\n// pointer, when the user doesn't define PrintTo() for it.  (A member\n// variable pointer or member function pointer doesn't really point to\n// a location in the address space.  Their representation is\n// implementation-defined.  Therefore they will be printed as raw\n// bytes.)\ntemplate <typename T>\nvoid DefaultPrintTo(IsNotContainer /* dummy */,\n                    true_type /* is a pointer */,\n                    T* p, ::std::ostream* os) {\n  if (p == NULL) {\n    *os << \"NULL\";\n  } else {\n    // C++ doesn't allow casting from a function pointer to any object\n    // pointer.\n    //\n    // IsTrue() silences warnings: \"Condition is always true\",\n    // \"unreachable code\".\n    if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {\n      // T is not a function type.  We just call << to print p,\n      // relying on ADL to pick up user-defined << for their pointer\n      // types, if any.\n      *os << p;\n    } else {\n      // T is a function type, so '*os << p' doesn't do what we want\n      // (it just prints p as bool).  We want to print p as a const\n      // void*.  However, we cannot cast it to const void* directly,\n      // even using reinterpret_cast, as earlier versions of gcc\n      // (e.g. 3.4.5) cannot compile the cast when p is a function\n      // pointer.  Casting to uintptr_t first solves the problem.\n      *os << reinterpret_cast<const void*>(\n          reinterpret_cast<uintptr_t>(p));\n    }\n  }\n}\n\n// Used to print a non-container, non-pointer value when the user\n// doesn't define PrintTo() for it.\ntemplate <typename T>\nvoid DefaultPrintTo(IsNotContainer /* dummy */,\n                    false_type /* is not a pointer */,\n                    const T& value, ::std::ostream* os) {\n  ::testing_internal::DefaultPrintNonContainerTo(value, os);\n}\n\n// Prints the given value using the << operator if it has one;\n// otherwise prints the bytes in it.  This is what\n// UniversalPrinter<T>::Print() does when PrintTo() is not specialized\n// or overloaded for type T.\n//\n// A user can override this behavior for a class type Foo by defining\n// an overload of PrintTo() in the namespace where Foo is defined.  We\n// give the user this option as sometimes defining a << operator for\n// Foo is not desirable (e.g. the coding style may prevent doing it,\n// or there is already a << operator but it doesn't do what the user\n// wants).\ntemplate <typename T>\nvoid PrintTo(const T& value, ::std::ostream* os) {\n  // DefaultPrintTo() is overloaded.  The type of its first two\n  // arguments determine which version will be picked.  If T is an\n  // STL-style container, the version for container will be called; if\n  // T is a pointer, the pointer version will be called; otherwise the\n  // generic version will be called.\n  //\n  // Note that we check for container types here, prior to we check\n  // for protocol message types in our operator<<.  The rationale is:\n  //\n  // For protocol messages, we want to give people a chance to\n  // override Google Mock's format by defining a PrintTo() or\n  // operator<<.  For STL containers, other formats can be\n  // incompatible with Google Mock's format for the container\n  // elements; therefore we check for container types here to ensure\n  // that our format is used.\n  //\n  // The second argument of DefaultPrintTo() is needed to bypass a bug\n  // in Symbian's C++ compiler that prevents it from picking the right\n  // overload between:\n  //\n  //   PrintTo(const T& x, ...);\n  //   PrintTo(T* x, ...);\n  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);\n}\n\n// The following list of PrintTo() overloads tells\n// UniversalPrinter<T>::Print() how to print standard types (built-in\n// types, strings, plain arrays, and pointers).\n\n// Overloads for various char types.\nGTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);\nGTEST_API_ void PrintTo(signed char c, ::std::ostream* os);\ninline void PrintTo(char c, ::std::ostream* os) {\n  // When printing a plain char, we always treat it as unsigned.  This\n  // way, the output won't be affected by whether the compiler thinks\n  // char is signed or not.\n  PrintTo(static_cast<unsigned char>(c), os);\n}\n\n// Overloads for other simple built-in types.\ninline void PrintTo(bool x, ::std::ostream* os) {\n  *os << (x ? \"true\" : \"false\");\n}\n\n// Overload for wchar_t type.\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its decimal code (except for L'\\0').\n// The L'\\0' char is printed as \"L'\\\\0'\". The decimal code is printed\n// as signed integer when wchar_t is implemented by the compiler\n// as a signed type and is printed as an unsigned integer when wchar_t\n// is implemented as an unsigned type.\nGTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);\n\n// Overloads for C strings.\nGTEST_API_ void PrintTo(const char* s, ::std::ostream* os);\ninline void PrintTo(char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const char*>(s), os);\n}\n\n// signed/unsigned char is often used for representing binary data, so\n// we print pointers to it as void* to be safe.\ninline void PrintTo(const signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(signed char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(const unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\ninline void PrintTo(unsigned char* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const void*>(s), os);\n}\n\n// MSVC can be configured to define wchar_t as a typedef of unsigned\n// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native\n// type.  When wchar_t is a typedef, defining an overload for const\n// wchar_t* would cause unsigned short* be printed as a wide string,\n// possibly causing invalid memory accesses.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Overloads for wide C strings\nGTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);\ninline void PrintTo(wchar_t* s, ::std::ostream* os) {\n  PrintTo(ImplicitCast_<const wchar_t*>(s), os);\n}\n#endif\n\n// Overload for C arrays.  Multi-dimensional arrays are printed\n// properly.\n\n// Prints the given number of elements in an array, without printing\n// the curly braces.\ntemplate <typename T>\nvoid PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {\n  UniversalPrint(a[0], os);\n  for (size_t i = 1; i != count; i++) {\n    *os << \", \";\n    UniversalPrint(a[i], os);\n  }\n}\n\n// Overloads for ::string and ::std::string.\n#if GTEST_HAS_GLOBAL_STRING\nGTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);\ninline void PrintTo(const ::string& s, ::std::ostream* os) {\n  PrintStringTo(s, os);\n}\n#endif  // GTEST_HAS_GLOBAL_STRING\n\nGTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);\ninline void PrintTo(const ::std::string& s, ::std::ostream* os) {\n  PrintStringTo(s, os);\n}\n\n// Overloads for ::wstring and ::std::wstring.\n#if GTEST_HAS_GLOBAL_WSTRING\nGTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);\ninline void PrintTo(const ::wstring& s, ::std::ostream* os) {\n  PrintWideStringTo(s, os);\n}\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);\ninline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {\n  PrintWideStringTo(s, os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_HAS_TR1_TUPLE\n// Overload for ::std::tr1::tuple.  Needed for printing function arguments,\n// which are packed as tuples.\n\n// Helper function for printing a tuple.  T must be instantiated with\n// a tuple type.\ntemplate <typename T>\nvoid PrintTupleTo(const T& t, ::std::ostream* os);\n\n// Overloaded PrintTo() for tuples of various arities.  We support\n// tuples of up-to 10 fields.  The following implementation works\n// regardless of whether tr1::tuple is implemented using the\n// non-standard variadic template feature or not.\n\ninline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1>\nvoid PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,\n             ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,\n             ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6, typename T7>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,\n             ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6, typename T7, typename T8>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,\n             ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6, typename T7, typename T8, typename T9>\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,\n             ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n          typename T6, typename T7, typename T8, typename T9, typename T10>\nvoid PrintTo(\n    const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,\n    ::std::ostream* os) {\n  PrintTupleTo(t, os);\n}\n#endif  // GTEST_HAS_TR1_TUPLE\n\n// Overload for std::pair.\ntemplate <typename T1, typename T2>\nvoid PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {\n  *os << '(';\n  // We cannot use UniversalPrint(value.first, os) here, as T1 may be\n  // a reference type.  The same for printing value.second.\n  UniversalPrinter<T1>::Print(value.first, os);\n  *os << \", \";\n  UniversalPrinter<T2>::Print(value.second, os);\n  *os << ')';\n}\n\n// Implements printing a non-reference type T by letting the compiler\n// pick the right overload of PrintTo() for T.\ntemplate <typename T>\nclass UniversalPrinter {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n#ifdef _MSC_VER\n# pragma warning(push)          // Saves the current warning state.\n# pragma warning(disable:4180)  // Temporarily disables warning 4180.\n#endif  // _MSC_VER\n\n  // Note: we deliberately don't call this PrintTo(), as that name\n  // conflicts with ::testing::internal::PrintTo in the body of the\n  // function.\n  static void Print(const T& value, ::std::ostream* os) {\n    // By default, ::testing::internal::PrintTo() is used for printing\n    // the value.\n    //\n    // Thanks to Koenig look-up, if T is a class and has its own\n    // PrintTo() function defined in its namespace, that function will\n    // be visible here.  Since it is more specific than the generic ones\n    // in ::testing::internal, it will be picked by the compiler in the\n    // following statement - exactly what we want.\n    PrintTo(value, os);\n  }\n\n#ifdef _MSC_VER\n# pragma warning(pop)           // Restores the warning state.\n#endif  // _MSC_VER\n};\n\n// UniversalPrintArray(begin, len, os) prints an array of 'len'\n// elements, starting at address 'begin'.\ntemplate <typename T>\nvoid UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {\n  if (len == 0) {\n    *os << \"{}\";\n  } else {\n    *os << \"{ \";\n    const size_t kThreshold = 18;\n    const size_t kChunkSize = 8;\n    // If the array has more than kThreshold elements, we'll have to\n    // omit some details by printing only the first and the last\n    // kChunkSize elements.\n    // TODO(wan@google.com): let the user control the threshold using a flag.\n    if (len <= kThreshold) {\n      PrintRawArrayTo(begin, len, os);\n    } else {\n      PrintRawArrayTo(begin, kChunkSize, os);\n      *os << \", ..., \";\n      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);\n    }\n    *os << \" }\";\n  }\n}\n// This overload prints a (const) char array compactly.\nGTEST_API_ void UniversalPrintArray(const char* begin,\n                                    size_t len,\n                                    ::std::ostream* os);\n\n// Implements printing an array type T[N].\ntemplate <typename T, size_t N>\nclass UniversalPrinter<T[N]> {\n public:\n  // Prints the given array, omitting some elements when there are too\n  // many.\n  static void Print(const T (&a)[N], ::std::ostream* os) {\n    UniversalPrintArray(a, N, os);\n  }\n};\n\n// Implements printing a reference type T&.\ntemplate <typename T>\nclass UniversalPrinter<T&> {\n public:\n  // MSVC warns about adding const to a function type, so we want to\n  // disable the warning.\n#ifdef _MSC_VER\n# pragma warning(push)          // Saves the current warning state.\n# pragma warning(disable:4180)  // Temporarily disables warning 4180.\n#endif  // _MSC_VER\n\n  static void Print(const T& value, ::std::ostream* os) {\n    // Prints the address of the value.  We use reinterpret_cast here\n    // as static_cast doesn't compile when T is a function type.\n    *os << \"@\" << reinterpret_cast<const void*>(&value) << \" \";\n\n    // Then prints the value itself.\n    UniversalPrint(value, os);\n  }\n\n#ifdef _MSC_VER\n# pragma warning(pop)           // Restores the warning state.\n#endif  // _MSC_VER\n};\n\n// Prints a value tersely: for a reference type, the referenced value\n// (but not the address) is printed; for a (const) char pointer, the\n// NUL-terminated string (but not the pointer) is printed.\ntemplate <typename T>\nvoid UniversalTersePrint(const T& value, ::std::ostream* os) {\n  UniversalPrint(value, os);\n}\ninline void UniversalTersePrint(const char* str, ::std::ostream* os) {\n  if (str == NULL) {\n    *os << \"NULL\";\n  } else {\n    UniversalPrint(string(str), os);\n  }\n}\ninline void UniversalTersePrint(char* str, ::std::ostream* os) {\n  UniversalTersePrint(static_cast<const char*>(str), os);\n}\n\n// Prints a value using the type inferred by the compiler.  The\n// difference between this and UniversalTersePrint() is that for a\n// (const) char pointer, this prints both the pointer and the\n// NUL-terminated string.\ntemplate <typename T>\nvoid UniversalPrint(const T& value, ::std::ostream* os) {\n  UniversalPrinter<T>::Print(value, os);\n}\n\n#if GTEST_HAS_TR1_TUPLE\ntypedef ::std::vector<string> Strings;\n\n// This helper template allows PrintTo() for tuples and\n// UniversalTersePrintTupleFieldsToStrings() to be defined by\n// induction on the number of tuple fields.  The idea is that\n// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N\n// fields in tuple t, and can be defined in terms of\n// TuplePrefixPrinter<N - 1>.\n\n// The inductive case.\ntemplate <size_t N>\nstruct TuplePrefixPrinter {\n  // Prints the first N fields of a tuple.\n  template <typename Tuple>\n  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {\n    TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);\n    *os << \", \";\n    UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>\n        ::Print(::std::tr1::get<N - 1>(t), os);\n  }\n\n  // Tersely prints the first N fields of a tuple to a string vector,\n  // one element for each field.\n  template <typename Tuple>\n  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {\n    TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);\n    ::std::stringstream ss;\n    UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);\n    strings->push_back(ss.str());\n  }\n};\n\n// Base cases.\ntemplate <>\nstruct TuplePrefixPrinter<0> {\n  template <typename Tuple>\n  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}\n\n  template <typename Tuple>\n  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}\n};\n// We have to specialize the entire TuplePrefixPrinter<> class\n// template here, even though the definition of\n// TersePrintPrefixToStrings() is the same as the generic version, as\n// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't\n// support specializing a method template of a class template.\ntemplate <>\nstruct TuplePrefixPrinter<1> {\n  template <typename Tuple>\n  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {\n    UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::\n        Print(::std::tr1::get<0>(t), os);\n  }\n\n  template <typename Tuple>\n  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {\n    ::std::stringstream ss;\n    UniversalTersePrint(::std::tr1::get<0>(t), &ss);\n    strings->push_back(ss.str());\n  }\n};\n\n// Helper function for printing a tuple.  T must be instantiated with\n// a tuple type.\ntemplate <typename T>\nvoid PrintTupleTo(const T& t, ::std::ostream* os) {\n  *os << \"(\";\n  TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::\n      PrintPrefixTo(t, os);\n  *os << \")\";\n}\n\n// Prints the fields of a tuple tersely to a string vector, one\n// element for each field.  See the comment before\n// UniversalTersePrint() for how we define \"tersely\".\ntemplate <typename Tuple>\nStrings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {\n  Strings result;\n  TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::\n      TersePrintPrefixToStrings(value, &result);\n  return result;\n}\n#endif  // GTEST_HAS_TR1_TUPLE\n\n}  // namespace internal\n\ntemplate <typename T>\n::std::string PrintToString(const T& value) {\n  ::std::stringstream ss;\n  internal::UniversalTersePrint(value, &ss);\n  return ss.str();\n}\n\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\n\n#if GTEST_HAS_PARAM_TEST\n\nnamespace testing {\nnamespace internal {\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Outputs a message explaining invalid registration of different\n// fixture class for the same test case. This may happen when\n// TEST_P macro is used to define two tests with the same name\n// but in different namespaces.\nGTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,\n                                          const char* file, int line);\n\ntemplate <typename> class ParamGeneratorInterface;\ntemplate <typename> class ParamGenerator;\n\n// Interface for iterating over elements provided by an implementation\n// of ParamGeneratorInterface<T>.\ntemplate <typename T>\nclass ParamIteratorInterface {\n public:\n  virtual ~ParamIteratorInterface() {}\n  // A pointer to the base generator instance.\n  // Used only for the purposes of iterator comparison\n  // to make sure that two iterators belong to the same generator.\n  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;\n  // Advances iterator to point to the next element\n  // provided by the generator. The caller is responsible\n  // for not calling Advance() on an iterator equal to\n  // BaseGenerator()->End().\n  virtual void Advance() = 0;\n  // Clones the iterator object. Used for implementing copy semantics\n  // of ParamIterator<T>.\n  virtual ParamIteratorInterface* Clone() const = 0;\n  // Dereferences the current iterator and provides (read-only) access\n  // to the pointed value. It is the caller's responsibility not to call\n  // Current() on an iterator equal to BaseGenerator()->End().\n  // Used for implementing ParamGenerator<T>::operator*().\n  virtual const T* Current() const = 0;\n  // Determines whether the given iterator and other point to the same\n  // element in the sequence generated by the generator.\n  // Used for implementing ParamGenerator<T>::operator==().\n  virtual bool Equals(const ParamIteratorInterface& other) const = 0;\n};\n\n// Class iterating over elements provided by an implementation of\n// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>\n// and implements the const forward iterator concept.\ntemplate <typename T>\nclass ParamIterator {\n public:\n  typedef T value_type;\n  typedef const T& reference;\n  typedef ptrdiff_t difference_type;\n\n  // ParamIterator assumes ownership of the impl_ pointer.\n  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}\n  ParamIterator& operator=(const ParamIterator& other) {\n    if (this != &other)\n      impl_.reset(other.impl_->Clone());\n    return *this;\n  }\n\n  const T& operator*() const { return *impl_->Current(); }\n  const T* operator->() const { return impl_->Current(); }\n  // Prefix version of operator++.\n  ParamIterator& operator++() {\n    impl_->Advance();\n    return *this;\n  }\n  // Postfix version of operator++.\n  ParamIterator operator++(int /*unused*/) {\n    ParamIteratorInterface<T>* clone = impl_->Clone();\n    impl_->Advance();\n    return ParamIterator(clone);\n  }\n  bool operator==(const ParamIterator& other) const {\n    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);\n  }\n  bool operator!=(const ParamIterator& other) const {\n    return !(*this == other);\n  }\n\n private:\n  friend class ParamGenerator<T>;\n  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}\n  scoped_ptr<ParamIteratorInterface<T> > impl_;\n};\n\n// ParamGeneratorInterface<T> is the binary interface to access generators\n// defined in other translation units.\ntemplate <typename T>\nclass ParamGeneratorInterface {\n public:\n  typedef T ParamType;\n\n  virtual ~ParamGeneratorInterface() {}\n\n  // Generator interface definition\n  virtual ParamIteratorInterface<T>* Begin() const = 0;\n  virtual ParamIteratorInterface<T>* End() const = 0;\n};\n\n// Wraps ParamGeneratorInterface<T> and provides general generator syntax\n// compatible with the STL Container concept.\n// This class implements copy initialization semantics and the contained\n// ParamGeneratorInterface<T> instance is shared among all copies\n// of the original object. This is possible because that instance is immutable.\ntemplate<typename T>\nclass ParamGenerator {\n public:\n  typedef ParamIterator<T> iterator;\n\n  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}\n  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}\n\n  ParamGenerator& operator=(const ParamGenerator& other) {\n    impl_ = other.impl_;\n    return *this;\n  }\n\n  iterator begin() const { return iterator(impl_->Begin()); }\n  iterator end() const { return iterator(impl_->End()); }\n\n private:\n  linked_ptr<const ParamGeneratorInterface<T> > impl_;\n};\n\n// Generates values from a range of two comparable values. Can be used to\n// generate sequences of user-defined types that implement operator+() and\n// operator<().\n// This class is used in the Range() function.\ntemplate <typename T, typename IncrementT>\nclass RangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  RangeGenerator(T begin, T end, IncrementT step)\n      : begin_(begin), end_(end),\n        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}\n  virtual ~RangeGenerator() {}\n\n  virtual ParamIteratorInterface<T>* Begin() const {\n    return new Iterator(this, begin_, 0, step_);\n  }\n  virtual ParamIteratorInterface<T>* End() const {\n    return new Iterator(this, end_, end_index_, step_);\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,\n             IncrementT step)\n        : base_(base), value_(value), index_(index), step_(step) {}\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {\n      return base_;\n    }\n    virtual void Advance() {\n      value_ = value_ + step_;\n      index_++;\n    }\n    virtual ParamIteratorInterface<T>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const T* Current() const { return &value_; }\n    virtual bool Equals(const ParamIteratorInterface<T>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const int other_index =\n          CheckedDowncastToActualType<const Iterator>(&other)->index_;\n      return index_ == other_index;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : ParamIteratorInterface<T>(),\n          base_(other.base_), value_(other.value_), index_(other.index_),\n          step_(other.step_) {}\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<T>* const base_;\n    T value_;\n    int index_;\n    const IncrementT step_;\n  };  // class RangeGenerator::Iterator\n\n  static int CalculateEndIndex(const T& begin,\n                               const T& end,\n                               const IncrementT& step) {\n    int end_index = 0;\n    for (T i = begin; i < end; i = i + step)\n      end_index++;\n    return end_index;\n  }\n\n  // No implementation - assignment is unsupported.\n  void operator=(const RangeGenerator& other);\n\n  const T begin_;\n  const T end_;\n  const IncrementT step_;\n  // The index for the end() iterator. All the elements in the generated\n  // sequence are indexed (0-based) to aid iterator comparison.\n  const int end_index_;\n};  // class RangeGenerator\n\n\n// Generates values from a pair of STL-style iterators. Used in the\n// ValuesIn() function. The elements are copied from the source range\n// since the source can be located on the stack, and the generator\n// is likely to persist beyond that stack frame.\ntemplate <typename T>\nclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {\n public:\n  template <typename ForwardIterator>\n  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)\n      : container_(begin, end) {}\n  virtual ~ValuesInIteratorRangeGenerator() {}\n\n  virtual ParamIteratorInterface<T>* Begin() const {\n    return new Iterator(this, container_.begin());\n  }\n  virtual ParamIteratorInterface<T>* End() const {\n    return new Iterator(this, container_.end());\n  }\n\n private:\n  typedef typename ::std::vector<T> ContainerType;\n\n  class Iterator : public ParamIteratorInterface<T> {\n   public:\n    Iterator(const ParamGeneratorInterface<T>* base,\n             typename ContainerType::const_iterator iterator)\n        : base_(base), iterator_(iterator) {}\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {\n      return base_;\n    }\n    virtual void Advance() {\n      ++iterator_;\n      value_.reset();\n    }\n    virtual ParamIteratorInterface<T>* Clone() const {\n      return new Iterator(*this);\n    }\n    // We need to use cached value referenced by iterator_ because *iterator_\n    // can return a temporary object (and of type other then T), so just\n    // having \"return &*iterator_;\" doesn't work.\n    // value_ is updated here and not in Advance() because Advance()\n    // can advance iterator_ beyond the end of the range, and we cannot\n    // detect that fact. The client code, on the other hand, is\n    // responsible for not calling Current() on an out-of-range iterator.\n    virtual const T* Current() const {\n      if (value_.get() == NULL)\n        value_.reset(new T(*iterator_));\n      return value_.get();\n    }\n    virtual bool Equals(const ParamIteratorInterface<T>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      return iterator_ ==\n          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;\n    }\n\n   private:\n    Iterator(const Iterator& other)\n          // The explicit constructor call suppresses a false warning\n          // emitted by gcc when supplied with the -Wextra option.\n        : ParamIteratorInterface<T>(),\n          base_(other.base_),\n          iterator_(other.iterator_) {}\n\n    const ParamGeneratorInterface<T>* const base_;\n    typename ContainerType::const_iterator iterator_;\n    // A cached value of *iterator_. We keep it here to allow access by\n    // pointer in the wrapping iterator's operator->().\n    // value_ needs to be mutable to be accessed in Current().\n    // Use of scoped_ptr helps manage cached value's lifetime,\n    // which is bound by the lifespan of the iterator itself.\n    mutable scoped_ptr<const T> value_;\n  };  // class ValuesInIteratorRangeGenerator::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const ValuesInIteratorRangeGenerator& other);\n\n  const ContainerType container_;\n};  // class ValuesInIteratorRangeGenerator\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Stores a parameter value and later creates tests parameterized with that\n// value.\ntemplate <class TestClass>\nclass ParameterizedTestFactory : public TestFactoryBase {\n public:\n  typedef typename TestClass::ParamType ParamType;\n  explicit ParameterizedTestFactory(ParamType parameter) :\n      parameter_(parameter) {}\n  virtual Test* CreateTest() {\n    TestClass::SetParam(&parameter_);\n    return new TestClass();\n  }\n\n private:\n  const ParamType parameter_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactoryBase is a base class for meta-factories that create\n// test factories for passing into MakeAndRegisterTestInfo function.\ntemplate <class ParamType>\nclass TestMetaFactoryBase {\n public:\n  virtual ~TestMetaFactoryBase() {}\n\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// TestMetaFactory creates test factories for passing into\n// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives\n// ownership of test factory pointer, same factory object cannot be passed\n// into that method twice. But ParameterizedTestCaseInfo is going to call\n// it for each Test/Parameter value combination. Thus it needs meta factory\n// creator class.\ntemplate <class TestCase>\nclass TestMetaFactory\n    : public TestMetaFactoryBase<typename TestCase::ParamType> {\n public:\n  typedef typename TestCase::ParamType ParamType;\n\n  TestMetaFactory() {}\n\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {\n    return new ParameterizedTestFactory<TestCase>(parameter);\n  }\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestCaseInfoBase is a generic interface\n// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase\n// accumulates test information provided by TEST_P macro invocations\n// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations\n// and uses that information to register all resulting test instances\n// in RegisterTests method. The ParameterizeTestCaseRegistry class holds\n// a collection of pointers to the ParameterizedTestCaseInfo objects\n// and calls RegisterTests() on each of them when asked.\nclass ParameterizedTestCaseInfoBase {\n public:\n  virtual ~ParameterizedTestCaseInfoBase() {}\n\n  // Base part of test case name for display purposes.\n  virtual const string& GetTestCaseName() const = 0;\n  // Test case id to verify identity.\n  virtual TypeId GetTestCaseTypeId() const = 0;\n  // UnitTest class invokes this method to register tests in this\n  // test case right before running them in RUN_ALL_TESTS macro.\n  // This method should not be called more then once on any single\n  // instance of a ParameterizedTestCaseInfoBase derived class.\n  virtual void RegisterTests() = 0;\n\n protected:\n  ParameterizedTestCaseInfoBase() {}\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);\n};\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P\n// macro invocations for a particular test case and generators\n// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that\n// test case. It registers tests with all values generated by all\n// generators when asked.\ntemplate <class TestCase>\nclass ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {\n public:\n  // ParamType and GeneratorCreationFunc are private types but are required\n  // for declarations of public methods AddTestPattern() and\n  // AddTestCaseInstantiation().\n  typedef typename TestCase::ParamType ParamType;\n  // A function that returns an instance of appropriate generator type.\n  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();\n\n  explicit ParameterizedTestCaseInfo(const char* name)\n      : test_case_name_(name) {}\n\n  // Test case base name for display purposes.\n  virtual const string& GetTestCaseName() const { return test_case_name_; }\n  // Test case id to verify identity.\n  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }\n  // TEST_P macro uses AddTestPattern() to record information\n  // about a single test in a LocalTestInfo structure.\n  // test_case_name is the base name of the test case (without invocation\n  // prefix). test_base_name is the name of an individual test without\n  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is\n  // test case base name and DoBar is test base name.\n  void AddTestPattern(const char* test_case_name,\n                      const char* test_base_name,\n                      TestMetaFactoryBase<ParamType>* meta_factory) {\n    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,\n                                                       test_base_name,\n                                                       meta_factory)));\n  }\n  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information\n  // about a generator.\n  int AddTestCaseInstantiation(const string& instantiation_name,\n                               GeneratorCreationFunc* func,\n                               const char* /* file */,\n                               int /* line */) {\n    instantiations_.push_back(::std::make_pair(instantiation_name, func));\n    return 0;  // Return value used only to run this method in namespace scope.\n  }\n  // UnitTest class invokes this method to register tests in this test case\n  // test cases right before running tests in RUN_ALL_TESTS macro.\n  // This method should not be called more then once on any single\n  // instance of a ParameterizedTestCaseInfoBase derived class.\n  // UnitTest has a guard to prevent from calling this method more then once.\n  virtual void RegisterTests() {\n    for (typename TestInfoContainer::iterator test_it = tests_.begin();\n         test_it != tests_.end(); ++test_it) {\n      linked_ptr<TestInfo> test_info = *test_it;\n      for (typename InstantiationContainer::iterator gen_it =\n               instantiations_.begin(); gen_it != instantiations_.end();\n               ++gen_it) {\n        const string& instantiation_name = gen_it->first;\n        ParamGenerator<ParamType> generator((*gen_it->second)());\n\n        Message test_case_name_stream;\n        if ( !instantiation_name.empty() )\n          test_case_name_stream << instantiation_name << \"/\";\n        test_case_name_stream << test_info->test_case_base_name;\n\n        int i = 0;\n        for (typename ParamGenerator<ParamType>::iterator param_it =\n                 generator.begin();\n             param_it != generator.end(); ++param_it, ++i) {\n          Message test_name_stream;\n          test_name_stream << test_info->test_base_name << \"/\" << i;\n          MakeAndRegisterTestInfo(\n              test_case_name_stream.GetString().c_str(),\n              test_name_stream.GetString().c_str(),\n              NULL,  // No type parameter.\n              PrintToString(*param_it).c_str(),\n              GetTestCaseTypeId(),\n              TestCase::SetUpTestCase,\n              TestCase::TearDownTestCase,\n              test_info->test_meta_factory->CreateTestFactory(*param_it));\n        }  // for param_it\n      }  // for gen_it\n    }  // for test_it\n  }  // RegisterTests\n\n private:\n  // LocalTestInfo structure keeps information about a single test registered\n  // with TEST_P macro.\n  struct TestInfo {\n    TestInfo(const char* a_test_case_base_name,\n             const char* a_test_base_name,\n             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :\n        test_case_base_name(a_test_case_base_name),\n        test_base_name(a_test_base_name),\n        test_meta_factory(a_test_meta_factory) {}\n\n    const string test_case_base_name;\n    const string test_base_name;\n    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;\n  };\n  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;\n  // Keeps pairs of <Instantiation name, Sequence generator creation function>\n  // received from INSTANTIATE_TEST_CASE_P macros.\n  typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >\n      InstantiationContainer;\n\n  const string test_case_name_;\n  TestInfoContainer tests_;\n  InstantiationContainer instantiations_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);\n};  // class ParameterizedTestCaseInfo\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase\n// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P\n// macros use it to locate their corresponding ParameterizedTestCaseInfo\n// descriptors.\nclass ParameterizedTestCaseRegistry {\n public:\n  ParameterizedTestCaseRegistry() {}\n  ~ParameterizedTestCaseRegistry() {\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\n         it != test_case_infos_.end(); ++it) {\n      delete *it;\n    }\n  }\n\n  // Looks up or creates and returns a structure containing information about\n  // tests and instantiations of a particular test case.\n  template <class TestCase>\n  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(\n      const char* test_case_name,\n      const char* file,\n      int line) {\n    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\n         it != test_case_infos_.end(); ++it) {\n      if ((*it)->GetTestCaseName() == test_case_name) {\n        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {\n          // Complain about incorrect usage of Google Test facilities\n          // and terminate the program since we cannot guaranty correct\n          // test case setup and tear-down in this case.\n          ReportInvalidTestCaseType(test_case_name,  file, line);\n          posix::Abort();\n        } else {\n          // At this point we are sure that the object we found is of the same\n          // type we are looking for, so we downcast it to that type\n          // without further checks.\n          typed_test_info = CheckedDowncastToActualType<\n              ParameterizedTestCaseInfo<TestCase> >(*it);\n        }\n        break;\n      }\n    }\n    if (typed_test_info == NULL) {\n      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);\n      test_case_infos_.push_back(typed_test_info);\n    }\n    return typed_test_info;\n  }\n  void RegisterTests() {\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\n         it != test_case_infos_.end(); ++it) {\n      (*it)->RegisterTests();\n    }\n  }\n\n private:\n  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;\n\n  TestCaseInfoContainer test_case_infos_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  //  GTEST_HAS_PARAM_TEST\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\n// This file was GENERATED by command:\n//     pump.py gtest-param-util-generated.h.pump\n// DO NOT EDIT BY HAND!!!\n\n// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: vladl@google.com (Vlad Losev)\n\n// Type and function utilities for implementing parameterized tests.\n// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\n//\n// Currently Google Test supports at most 50 arguments in Values,\n// and at most 10 arguments in Combine. Please contact\n// googletestframework@googlegroups.com if you need more.\n// Please note that the number of arguments to Combine is limited\n// by the maximum arity of the implementation of tr1::tuple which is\n// currently set at 10.\n\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\n\n// scripts/fuse_gtest.py depends on gtest's own header being #included\n// *unconditionally*.  Therefore these #includes cannot be moved\n// inside #if GTEST_HAS_PARAM_TEST.\n\n#if GTEST_HAS_PARAM_TEST\n\nnamespace testing {\n\n// Forward declarations of ValuesIn(), which is implemented in\n// include/gtest/gtest-param-test.h.\ntemplate <typename ForwardIterator>\ninternal::ParamGenerator<\n  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>\nValuesIn(ForwardIterator begin, ForwardIterator end);\n\ntemplate <typename T, size_t N>\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]);\n\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container);\n\nnamespace internal {\n\n// Used in the Values() function to provide polymorphic capabilities.\ntemplate <typename T1>\nclass ValueArray1 {\n public:\n  explicit ValueArray1(T1 v1) : v1_(v1) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray1& other);\n\n  const T1 v1_;\n};\n\ntemplate <typename T1, typename T2>\nclass ValueArray2 {\n public:\n  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray2& other);\n\n  const T1 v1_;\n  const T2 v2_;\n};\n\ntemplate <typename T1, typename T2, typename T3>\nclass ValueArray3 {\n public:\n  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray3& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\nclass ValueArray4 {\n public:\n  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray4& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nclass ValueArray5 {\n public:\n  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray5& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6>\nclass ValueArray6 {\n public:\n  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray6& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7>\nclass ValueArray7 {\n public:\n  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray7& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8>\nclass ValueArray8 {\n public:\n  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray8& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9>\nclass ValueArray9 {\n public:\n  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\n      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray9& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10>\nclass ValueArray10 {\n public:\n  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray10& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11>\nclass ValueArray11 {\n public:\n  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\n      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray11& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12>\nclass ValueArray12 {\n public:\n  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\n      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray12& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13>\nclass ValueArray13 {\n public:\n  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\n      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\n      v12_(v12), v13_(v13) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray13& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14>\nclass ValueArray14 {\n public:\n  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray14& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15>\nclass ValueArray15 {\n public:\n  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray15& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16>\nclass ValueArray16 {\n public:\n  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\n      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\n      v16_(v16) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray16& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17>\nclass ValueArray17 {\n public:\n  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\n      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray17& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18>\nclass ValueArray18 {\n public:\n  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray18& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19>\nclass ValueArray19 {\n public:\n  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\n      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\n      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray19& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20>\nclass ValueArray20 {\n public:\n  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\n      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\n      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\n      v19_(v19), v20_(v20) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray20& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21>\nclass ValueArray21 {\n public:\n  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\n      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\n      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\n      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray21& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22>\nclass ValueArray22 {\n public:\n  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray22& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23>\nclass ValueArray23 {\n public:\n  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,\n        v23_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray23& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24>\nclass ValueArray24 {\n public:\n  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\n      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\n      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\n      v22_(v22), v23_(v23), v24_(v24) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray24& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25>\nclass ValueArray25 {\n public:\n  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\n      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray25& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26>\nclass ValueArray26 {\n public:\n  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray26& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27>\nclass ValueArray27 {\n public:\n  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\n      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\n      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\n      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\n      v26_(v26), v27_(v27) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray27& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28>\nclass ValueArray28 {\n public:\n  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\n      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\n      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\n      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\n      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray28& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29>\nclass ValueArray29 {\n public:\n  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\n      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\n      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\n      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\n      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray29& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30>\nclass ValueArray30 {\n public:\n  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray30& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31>\nclass ValueArray31 {\n public:\n  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30), v31_(v31) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray31& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32>\nclass ValueArray32 {\n public:\n  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\n      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\n      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\n      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\n      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray32& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33>\nclass ValueArray33 {\n public:\n  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,\n      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray33& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34>\nclass ValueArray34 {\n public:\n  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33), v34_(v34) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray34& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35>\nclass ValueArray35 {\n public:\n  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\n      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\n      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\n      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\n      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),\n      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,\n        v35_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray35& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36>\nclass ValueArray36 {\n public:\n  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\n      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\n      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\n      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\n      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),\n      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray36& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37>\nclass ValueArray37 {\n public:\n  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\n      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\n      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\n      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\n      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),\n      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),\n      v36_(v36), v37_(v37) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray37& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38>\nclass ValueArray38 {\n public:\n  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\n      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray38& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39>\nclass ValueArray39 {\n public:\n  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\n      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray39& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40>\nclass ValueArray40 {\n public:\n  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\n      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\n      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\n      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\n      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),\n      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),\n      v40_(v40) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray40& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41>\nclass ValueArray41 {\n public:\n  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,\n      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\n      v39_(v39), v40_(v40), v41_(v41) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray41& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42>\nclass ValueArray42 {\n public:\n  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\n      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray42& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43>\nclass ValueArray43 {\n public:\n  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\n      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\n      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\n      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\n      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),\n      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),\n      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray43& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44>\nclass ValueArray44 {\n public:\n  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\n      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\n      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\n      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\n      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),\n      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),\n      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),\n      v43_(v43), v44_(v44) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray44& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45>\nclass ValueArray45 {\n public:\n  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\n      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\n      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\n      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\n      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),\n      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),\n      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),\n      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray45& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46>\nclass ValueArray46 {\n public:\n  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),\n      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\n      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),\n      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray46& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n  const T46 v46_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47>\nclass ValueArray47 {\n public:\n  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),\n      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\n      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\n      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\n      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\n      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\n      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),\n      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),\n      v47_(v47) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,\n        v47_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray47& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n  const T46 v46_;\n  const T47 v47_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48>\nclass ValueArray48 {\n public:\n  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),\n      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\n      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\n      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\n      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\n      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),\n      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),\n      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),\n      v46_(v46), v47_(v47), v48_(v48) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,\n        v48_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray48& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n  const T46 v46_;\n  const T47 v47_;\n  const T48 v48_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49>\nclass ValueArray49 {\n public:\n  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,\n      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\n      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),\n      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,\n        v48_, v49_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray49& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n  const T46 v46_;\n  const T47 v47_;\n  const T48 v48_;\n  const T49 v49_;\n};\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49, typename T50>\nclass ValueArray50 {\n public:\n  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,\n      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\n      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\n      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\n      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\n      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\n      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\n      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),\n      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}\n\n  template <typename T>\n  operator ParamGenerator<T>() const {\n    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,\n        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,\n        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,\n        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,\n        v48_, v49_, v50_};\n    return ValuesIn(array);\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const ValueArray50& other);\n\n  const T1 v1_;\n  const T2 v2_;\n  const T3 v3_;\n  const T4 v4_;\n  const T5 v5_;\n  const T6 v6_;\n  const T7 v7_;\n  const T8 v8_;\n  const T9 v9_;\n  const T10 v10_;\n  const T11 v11_;\n  const T12 v12_;\n  const T13 v13_;\n  const T14 v14_;\n  const T15 v15_;\n  const T16 v16_;\n  const T17 v17_;\n  const T18 v18_;\n  const T19 v19_;\n  const T20 v20_;\n  const T21 v21_;\n  const T22 v22_;\n  const T23 v23_;\n  const T24 v24_;\n  const T25 v25_;\n  const T26 v26_;\n  const T27 v27_;\n  const T28 v28_;\n  const T29 v29_;\n  const T30 v30_;\n  const T31 v31_;\n  const T32 v32_;\n  const T33 v33_;\n  const T34 v34_;\n  const T35 v35_;\n  const T36 v36_;\n  const T37 v37_;\n  const T38 v38_;\n  const T39 v39_;\n  const T40 v40_;\n  const T41 v41_;\n  const T42 v42_;\n  const T43 v43_;\n  const T44 v44_;\n  const T45 v45_;\n  const T46 v46_;\n  const T47 v47_;\n  const T48 v48_;\n  const T49 v49_;\n  const T50 v50_;\n};\n\n# if GTEST_HAS_COMBINE\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Generates values from the Cartesian product of values produced\n// by the argument generators.\n//\ntemplate <typename T1, typename T2>\nclass CartesianProductGenerator2\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2> ParamType;\n\n  CartesianProductGenerator2(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2)\n      : g1_(g1), g2_(g2) {}\n  virtual ~CartesianProductGenerator2() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current2_;\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator2::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator2& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n};  // class CartesianProductGenerator2\n\n\ntemplate <typename T1, typename T2, typename T3>\nclass CartesianProductGenerator3\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;\n\n  CartesianProductGenerator3(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)\n      : g1_(g1), g2_(g2), g3_(g3) {}\n  virtual ~CartesianProductGenerator3() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current3_;\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator3::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator3& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n};  // class CartesianProductGenerator3\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\nclass CartesianProductGenerator4\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;\n\n  CartesianProductGenerator4(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}\n  virtual ~CartesianProductGenerator4() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current4_;\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator4::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator4& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n};  // class CartesianProductGenerator4\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\nclass CartesianProductGenerator5\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;\n\n  CartesianProductGenerator5(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}\n  virtual ~CartesianProductGenerator5() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current5_;\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator5::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator5& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n};  // class CartesianProductGenerator5\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6>\nclass CartesianProductGenerator6\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,\n        T6> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;\n\n  CartesianProductGenerator6(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\n      const ParamGenerator<T6>& g6)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}\n  virtual ~CartesianProductGenerator6() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5,\n      const ParamGenerator<T6>& g6,\n      const typename ParamGenerator<T6>::iterator& current6)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\n          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current6_;\n      if (current6_ == end6_) {\n        current6_ = begin6_;\n        ++current5_;\n      }\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_ &&\n          current6_ == typed_other->current6_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_),\n        begin6_(other.begin6_),\n        end6_(other.end6_),\n        current6_(other.current6_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_, *current6_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_ ||\n          current6_ == end6_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    const typename ParamGenerator<T6>::iterator begin6_;\n    const typename ParamGenerator<T6>::iterator end6_;\n    typename ParamGenerator<T6>::iterator current6_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator6::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator6& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n  const ParamGenerator<T6> g6_;\n};  // class CartesianProductGenerator6\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7>\nclass CartesianProductGenerator7\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\n        T7> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;\n\n  CartesianProductGenerator7(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\n      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}\n  virtual ~CartesianProductGenerator7() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\n        g7_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5,\n      const ParamGenerator<T6>& g6,\n      const typename ParamGenerator<T6>::iterator& current6,\n      const ParamGenerator<T7>& g7,\n      const typename ParamGenerator<T7>::iterator& current7)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\n          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\n          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current7_;\n      if (current7_ == end7_) {\n        current7_ = begin7_;\n        ++current6_;\n      }\n      if (current6_ == end6_) {\n        current6_ = begin6_;\n        ++current5_;\n      }\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_ &&\n          current6_ == typed_other->current6_ &&\n          current7_ == typed_other->current7_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_),\n        begin6_(other.begin6_),\n        end6_(other.end6_),\n        current6_(other.current6_),\n        begin7_(other.begin7_),\n        end7_(other.end7_),\n        current7_(other.current7_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_, *current6_, *current7_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_ ||\n          current6_ == end6_ ||\n          current7_ == end7_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    const typename ParamGenerator<T6>::iterator begin6_;\n    const typename ParamGenerator<T6>::iterator end6_;\n    typename ParamGenerator<T6>::iterator current6_;\n    const typename ParamGenerator<T7>::iterator begin7_;\n    const typename ParamGenerator<T7>::iterator end7_;\n    typename ParamGenerator<T7>::iterator current7_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator7::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator7& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n  const ParamGenerator<T6> g6_;\n  const ParamGenerator<T7> g7_;\n};  // class CartesianProductGenerator7\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8>\nclass CartesianProductGenerator8\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\n        T7, T8> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;\n\n  CartesianProductGenerator8(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\n      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\n      const ParamGenerator<T8>& g8)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),\n          g8_(g8) {}\n  virtual ~CartesianProductGenerator8() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\n        g7_.begin(), g8_, g8_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\n        g8_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5,\n      const ParamGenerator<T6>& g6,\n      const typename ParamGenerator<T6>::iterator& current6,\n      const ParamGenerator<T7>& g7,\n      const typename ParamGenerator<T7>::iterator& current7,\n      const ParamGenerator<T8>& g8,\n      const typename ParamGenerator<T8>::iterator& current8)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\n          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\n          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\n          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current8_;\n      if (current8_ == end8_) {\n        current8_ = begin8_;\n        ++current7_;\n      }\n      if (current7_ == end7_) {\n        current7_ = begin7_;\n        ++current6_;\n      }\n      if (current6_ == end6_) {\n        current6_ = begin6_;\n        ++current5_;\n      }\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_ &&\n          current6_ == typed_other->current6_ &&\n          current7_ == typed_other->current7_ &&\n          current8_ == typed_other->current8_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_),\n        begin6_(other.begin6_),\n        end6_(other.end6_),\n        current6_(other.current6_),\n        begin7_(other.begin7_),\n        end7_(other.end7_),\n        current7_(other.current7_),\n        begin8_(other.begin8_),\n        end8_(other.end8_),\n        current8_(other.current8_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_, *current6_, *current7_, *current8_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_ ||\n          current6_ == end6_ ||\n          current7_ == end7_ ||\n          current8_ == end8_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    const typename ParamGenerator<T6>::iterator begin6_;\n    const typename ParamGenerator<T6>::iterator end6_;\n    typename ParamGenerator<T6>::iterator current6_;\n    const typename ParamGenerator<T7>::iterator begin7_;\n    const typename ParamGenerator<T7>::iterator end7_;\n    typename ParamGenerator<T7>::iterator current7_;\n    const typename ParamGenerator<T8>::iterator begin8_;\n    const typename ParamGenerator<T8>::iterator end8_;\n    typename ParamGenerator<T8>::iterator current8_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator8::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator8& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n  const ParamGenerator<T6> g6_;\n  const ParamGenerator<T7> g7_;\n  const ParamGenerator<T8> g8_;\n};  // class CartesianProductGenerator8\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9>\nclass CartesianProductGenerator9\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\n        T7, T8, T9> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;\n\n  CartesianProductGenerator9(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\n      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\n      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\n          g9_(g9) {}\n  virtual ~CartesianProductGenerator9() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\n        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\n        g8_.end(), g9_, g9_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5,\n      const ParamGenerator<T6>& g6,\n      const typename ParamGenerator<T6>::iterator& current6,\n      const ParamGenerator<T7>& g7,\n      const typename ParamGenerator<T7>::iterator& current7,\n      const ParamGenerator<T8>& g8,\n      const typename ParamGenerator<T8>::iterator& current8,\n      const ParamGenerator<T9>& g9,\n      const typename ParamGenerator<T9>::iterator& current9)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\n          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\n          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\n          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),\n          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current9_;\n      if (current9_ == end9_) {\n        current9_ = begin9_;\n        ++current8_;\n      }\n      if (current8_ == end8_) {\n        current8_ = begin8_;\n        ++current7_;\n      }\n      if (current7_ == end7_) {\n        current7_ = begin7_;\n        ++current6_;\n      }\n      if (current6_ == end6_) {\n        current6_ = begin6_;\n        ++current5_;\n      }\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_ &&\n          current6_ == typed_other->current6_ &&\n          current7_ == typed_other->current7_ &&\n          current8_ == typed_other->current8_ &&\n          current9_ == typed_other->current9_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_),\n        begin6_(other.begin6_),\n        end6_(other.end6_),\n        current6_(other.current6_),\n        begin7_(other.begin7_),\n        end7_(other.end7_),\n        current7_(other.current7_),\n        begin8_(other.begin8_),\n        end8_(other.end8_),\n        current8_(other.current8_),\n        begin9_(other.begin9_),\n        end9_(other.end9_),\n        current9_(other.current9_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_, *current6_, *current7_, *current8_,\n            *current9_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_ ||\n          current6_ == end6_ ||\n          current7_ == end7_ ||\n          current8_ == end8_ ||\n          current9_ == end9_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    const typename ParamGenerator<T6>::iterator begin6_;\n    const typename ParamGenerator<T6>::iterator end6_;\n    typename ParamGenerator<T6>::iterator current6_;\n    const typename ParamGenerator<T7>::iterator begin7_;\n    const typename ParamGenerator<T7>::iterator end7_;\n    typename ParamGenerator<T7>::iterator current7_;\n    const typename ParamGenerator<T8>::iterator begin8_;\n    const typename ParamGenerator<T8>::iterator end8_;\n    typename ParamGenerator<T8>::iterator current8_;\n    const typename ParamGenerator<T9>::iterator begin9_;\n    const typename ParamGenerator<T9>::iterator end9_;\n    typename ParamGenerator<T9>::iterator current9_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator9::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator9& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n  const ParamGenerator<T6> g6_;\n  const ParamGenerator<T7> g7_;\n  const ParamGenerator<T8> g8_;\n  const ParamGenerator<T9> g9_;\n};  // class CartesianProductGenerator9\n\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10>\nclass CartesianProductGenerator10\n    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\n        T7, T8, T9, T10> > {\n public:\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;\n\n  CartesianProductGenerator10(const ParamGenerator<T1>& g1,\n      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\n      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\n      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\n      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,\n      const ParamGenerator<T10>& g10)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\n          g9_(g9), g10_(g10) {}\n  virtual ~CartesianProductGenerator10() {}\n\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\n        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\n        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());\n  }\n  virtual ParamIteratorInterface<ParamType>* End() const {\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\n        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\n        g8_.end(), g9_, g9_.end(), g10_, g10_.end());\n  }\n\n private:\n  class Iterator : public ParamIteratorInterface<ParamType> {\n   public:\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\n      const ParamGenerator<T1>& g1,\n      const typename ParamGenerator<T1>::iterator& current1,\n      const ParamGenerator<T2>& g2,\n      const typename ParamGenerator<T2>::iterator& current2,\n      const ParamGenerator<T3>& g3,\n      const typename ParamGenerator<T3>::iterator& current3,\n      const ParamGenerator<T4>& g4,\n      const typename ParamGenerator<T4>::iterator& current4,\n      const ParamGenerator<T5>& g5,\n      const typename ParamGenerator<T5>::iterator& current5,\n      const ParamGenerator<T6>& g6,\n      const typename ParamGenerator<T6>::iterator& current6,\n      const ParamGenerator<T7>& g7,\n      const typename ParamGenerator<T7>::iterator& current7,\n      const ParamGenerator<T8>& g8,\n      const typename ParamGenerator<T8>::iterator& current8,\n      const ParamGenerator<T9>& g9,\n      const typename ParamGenerator<T9>::iterator& current9,\n      const ParamGenerator<T10>& g10,\n      const typename ParamGenerator<T10>::iterator& current10)\n        : base_(base),\n          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\n          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\n          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\n          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\n          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\n          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\n          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\n          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),\n          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),\n          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {\n      ComputeCurrentValue();\n    }\n    virtual ~Iterator() {}\n\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\n      return base_;\n    }\n    // Advance should not be called on beyond-of-range iterators\n    // so no component iterators must be beyond end of range, either.\n    virtual void Advance() {\n      assert(!AtEnd());\n      ++current10_;\n      if (current10_ == end10_) {\n        current10_ = begin10_;\n        ++current9_;\n      }\n      if (current9_ == end9_) {\n        current9_ = begin9_;\n        ++current8_;\n      }\n      if (current8_ == end8_) {\n        current8_ = begin8_;\n        ++current7_;\n      }\n      if (current7_ == end7_) {\n        current7_ = begin7_;\n        ++current6_;\n      }\n      if (current6_ == end6_) {\n        current6_ = begin6_;\n        ++current5_;\n      }\n      if (current5_ == end5_) {\n        current5_ = begin5_;\n        ++current4_;\n      }\n      if (current4_ == end4_) {\n        current4_ = begin4_;\n        ++current3_;\n      }\n      if (current3_ == end3_) {\n        current3_ = begin3_;\n        ++current2_;\n      }\n      if (current2_ == end2_) {\n        current2_ = begin2_;\n        ++current1_;\n      }\n      ComputeCurrentValue();\n    }\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\n      return new Iterator(*this);\n    }\n    virtual const ParamType* Current() const { return &current_value_; }\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\n      // Having the same base generator guarantees that the other\n      // iterator is of the same type and we can downcast.\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\n          << \"The program attempted to compare iterators \"\n          << \"from different generators.\" << std::endl;\n      const Iterator* typed_other =\n          CheckedDowncastToActualType<const Iterator>(&other);\n      // We must report iterators equal if they both point beyond their\n      // respective ranges. That can happen in a variety of fashions,\n      // so we have to consult AtEnd().\n      return (AtEnd() && typed_other->AtEnd()) ||\n         (\n          current1_ == typed_other->current1_ &&\n          current2_ == typed_other->current2_ &&\n          current3_ == typed_other->current3_ &&\n          current4_ == typed_other->current4_ &&\n          current5_ == typed_other->current5_ &&\n          current6_ == typed_other->current6_ &&\n          current7_ == typed_other->current7_ &&\n          current8_ == typed_other->current8_ &&\n          current9_ == typed_other->current9_ &&\n          current10_ == typed_other->current10_);\n    }\n\n   private:\n    Iterator(const Iterator& other)\n        : base_(other.base_),\n        begin1_(other.begin1_),\n        end1_(other.end1_),\n        current1_(other.current1_),\n        begin2_(other.begin2_),\n        end2_(other.end2_),\n        current2_(other.current2_),\n        begin3_(other.begin3_),\n        end3_(other.end3_),\n        current3_(other.current3_),\n        begin4_(other.begin4_),\n        end4_(other.end4_),\n        current4_(other.current4_),\n        begin5_(other.begin5_),\n        end5_(other.end5_),\n        current5_(other.current5_),\n        begin6_(other.begin6_),\n        end6_(other.end6_),\n        current6_(other.current6_),\n        begin7_(other.begin7_),\n        end7_(other.end7_),\n        current7_(other.current7_),\n        begin8_(other.begin8_),\n        end8_(other.end8_),\n        current8_(other.current8_),\n        begin9_(other.begin9_),\n        end9_(other.end9_),\n        current9_(other.current9_),\n        begin10_(other.begin10_),\n        end10_(other.end10_),\n        current10_(other.current10_) {\n      ComputeCurrentValue();\n    }\n\n    void ComputeCurrentValue() {\n      if (!AtEnd())\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\n            *current4_, *current5_, *current6_, *current7_, *current8_,\n            *current9_, *current10_);\n    }\n    bool AtEnd() const {\n      // We must report iterator past the end of the range when either of the\n      // component iterators has reached the end of its range.\n      return\n          current1_ == end1_ ||\n          current2_ == end2_ ||\n          current3_ == end3_ ||\n          current4_ == end4_ ||\n          current5_ == end5_ ||\n          current6_ == end6_ ||\n          current7_ == end7_ ||\n          current8_ == end8_ ||\n          current9_ == end9_ ||\n          current10_ == end10_;\n    }\n\n    // No implementation - assignment is unsupported.\n    void operator=(const Iterator& other);\n\n    const ParamGeneratorInterface<ParamType>* const base_;\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\n    // current[i]_ is the actual traversing iterator.\n    const typename ParamGenerator<T1>::iterator begin1_;\n    const typename ParamGenerator<T1>::iterator end1_;\n    typename ParamGenerator<T1>::iterator current1_;\n    const typename ParamGenerator<T2>::iterator begin2_;\n    const typename ParamGenerator<T2>::iterator end2_;\n    typename ParamGenerator<T2>::iterator current2_;\n    const typename ParamGenerator<T3>::iterator begin3_;\n    const typename ParamGenerator<T3>::iterator end3_;\n    typename ParamGenerator<T3>::iterator current3_;\n    const typename ParamGenerator<T4>::iterator begin4_;\n    const typename ParamGenerator<T4>::iterator end4_;\n    typename ParamGenerator<T4>::iterator current4_;\n    const typename ParamGenerator<T5>::iterator begin5_;\n    const typename ParamGenerator<T5>::iterator end5_;\n    typename ParamGenerator<T5>::iterator current5_;\n    const typename ParamGenerator<T6>::iterator begin6_;\n    const typename ParamGenerator<T6>::iterator end6_;\n    typename ParamGenerator<T6>::iterator current6_;\n    const typename ParamGenerator<T7>::iterator begin7_;\n    const typename ParamGenerator<T7>::iterator end7_;\n    typename ParamGenerator<T7>::iterator current7_;\n    const typename ParamGenerator<T8>::iterator begin8_;\n    const typename ParamGenerator<T8>::iterator end8_;\n    typename ParamGenerator<T8>::iterator current8_;\n    const typename ParamGenerator<T9>::iterator begin9_;\n    const typename ParamGenerator<T9>::iterator end9_;\n    typename ParamGenerator<T9>::iterator current9_;\n    const typename ParamGenerator<T10>::iterator begin10_;\n    const typename ParamGenerator<T10>::iterator end10_;\n    typename ParamGenerator<T10>::iterator current10_;\n    ParamType current_value_;\n  };  // class CartesianProductGenerator10::Iterator\n\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductGenerator10& other);\n\n  const ParamGenerator<T1> g1_;\n  const ParamGenerator<T2> g2_;\n  const ParamGenerator<T3> g3_;\n  const ParamGenerator<T4> g4_;\n  const ParamGenerator<T5> g5_;\n  const ParamGenerator<T6> g6_;\n  const ParamGenerator<T7> g7_;\n  const ParamGenerator<T8> g8_;\n  const ParamGenerator<T9> g9_;\n  const ParamGenerator<T10> g10_;\n};  // class CartesianProductGenerator10\n\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Helper classes providing Combine() with polymorphic features. They allow\n// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is\n// convertible to U.\n//\ntemplate <class Generator1, class Generator2>\nclass CartesianProductHolder2 {\n public:\nCartesianProductHolder2(const Generator1& g1, const Generator2& g2)\n      : g1_(g1), g2_(g2) {}\n  template <typename T1, typename T2>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(\n        new CartesianProductGenerator2<T1, T2>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder2& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n};  // class CartesianProductHolder2\n\ntemplate <class Generator1, class Generator2, class Generator3>\nclass CartesianProductHolder3 {\n public:\nCartesianProductHolder3(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3)\n      : g1_(g1), g2_(g2), g3_(g3) {}\n  template <typename T1, typename T2, typename T3>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(\n        new CartesianProductGenerator3<T1, T2, T3>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder3& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n};  // class CartesianProductHolder3\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4>\nclass CartesianProductHolder4 {\n public:\nCartesianProductHolder4(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}\n  template <typename T1, typename T2, typename T3, typename T4>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(\n        new CartesianProductGenerator4<T1, T2, T3, T4>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder4& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n};  // class CartesianProductHolder4\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5>\nclass CartesianProductHolder5 {\n public:\nCartesianProductHolder5(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(\n        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder5& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n};  // class CartesianProductHolder5\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5, class Generator6>\nclass CartesianProductHolder6 {\n public:\nCartesianProductHolder6(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5,\n    const Generator6& g6)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\n      typename T6>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(\n        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_),\n        static_cast<ParamGenerator<T6> >(g6_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder6& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n  const Generator6 g6_;\n};  // class CartesianProductHolder6\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5, class Generator6, class Generator7>\nclass CartesianProductHolder7 {\n public:\nCartesianProductHolder7(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5,\n    const Generator6& g6, const Generator7& g7)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\n      typename T6, typename T7>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\n      T7> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(\n        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_),\n        static_cast<ParamGenerator<T6> >(g6_),\n        static_cast<ParamGenerator<T7> >(g7_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder7& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n  const Generator6 g6_;\n  const Generator7 g7_;\n};  // class CartesianProductHolder7\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5, class Generator6, class Generator7,\n    class Generator8>\nclass CartesianProductHolder8 {\n public:\nCartesianProductHolder8(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5,\n    const Generator6& g6, const Generator7& g7, const Generator8& g8)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),\n          g8_(g8) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\n      typename T6, typename T7, typename T8>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,\n      T8> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(\n        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_),\n        static_cast<ParamGenerator<T6> >(g6_),\n        static_cast<ParamGenerator<T7> >(g7_),\n        static_cast<ParamGenerator<T8> >(g8_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder8& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n  const Generator6 g6_;\n  const Generator7 g7_;\n  const Generator8 g8_;\n};  // class CartesianProductHolder8\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5, class Generator6, class Generator7,\n    class Generator8, class Generator9>\nclass CartesianProductHolder9 {\n public:\nCartesianProductHolder9(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5,\n    const Generator6& g6, const Generator7& g7, const Generator8& g8,\n    const Generator9& g9)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\n          g9_(g9) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\n      typename T6, typename T7, typename T8, typename T9>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\n      T9> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\n        T9> >(\n        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_),\n        static_cast<ParamGenerator<T6> >(g6_),\n        static_cast<ParamGenerator<T7> >(g7_),\n        static_cast<ParamGenerator<T8> >(g8_),\n        static_cast<ParamGenerator<T9> >(g9_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder9& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n  const Generator6 g6_;\n  const Generator7 g7_;\n  const Generator8 g8_;\n  const Generator9 g9_;\n};  // class CartesianProductHolder9\n\ntemplate <class Generator1, class Generator2, class Generator3,\n    class Generator4, class Generator5, class Generator6, class Generator7,\n    class Generator8, class Generator9, class Generator10>\nclass CartesianProductHolder10 {\n public:\nCartesianProductHolder10(const Generator1& g1, const Generator2& g2,\n    const Generator3& g3, const Generator4& g4, const Generator5& g5,\n    const Generator6& g6, const Generator7& g7, const Generator8& g8,\n    const Generator9& g9, const Generator10& g10)\n      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\n          g9_(g9), g10_(g10) {}\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\n      typename T6, typename T7, typename T8, typename T9, typename T10>\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\n      T9, T10> >() const {\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\n        T9, T10> >(\n        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,\n            T10>(\n        static_cast<ParamGenerator<T1> >(g1_),\n        static_cast<ParamGenerator<T2> >(g2_),\n        static_cast<ParamGenerator<T3> >(g3_),\n        static_cast<ParamGenerator<T4> >(g4_),\n        static_cast<ParamGenerator<T5> >(g5_),\n        static_cast<ParamGenerator<T6> >(g6_),\n        static_cast<ParamGenerator<T7> >(g7_),\n        static_cast<ParamGenerator<T8> >(g8_),\n        static_cast<ParamGenerator<T9> >(g9_),\n        static_cast<ParamGenerator<T10> >(g10_)));\n  }\n\n private:\n  // No implementation - assignment is unsupported.\n  void operator=(const CartesianProductHolder10& other);\n\n  const Generator1 g1_;\n  const Generator2 g2_;\n  const Generator3 g3_;\n  const Generator4 g4_;\n  const Generator5 g5_;\n  const Generator6 g6_;\n  const Generator7 g7_;\n  const Generator8 g8_;\n  const Generator9 g9_;\n  const Generator10 g10_;\n};  // class CartesianProductHolder10\n\n# endif  // GTEST_HAS_COMBINE\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  //  GTEST_HAS_PARAM_TEST\n\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\n\n#if GTEST_HAS_PARAM_TEST\n\nnamespace testing {\n\n// Functions producing parameter generators.\n//\n// Google Test uses these generators to produce parameters for value-\n// parameterized tests. When a parameterized test case is instantiated\n// with a particular generator, Google Test creates and runs tests\n// for each element in the sequence produced by the generator.\n//\n// In the following sample, tests from test case FooTest are instantiated\n// each three times with parameter values 3, 5, and 8:\n//\n// class FooTest : public TestWithParam<int> { ... };\n//\n// TEST_P(FooTest, TestThis) {\n// }\n// TEST_P(FooTest, TestThat) {\n// }\n// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));\n//\n\n// Range() returns generators providing sequences of values in a range.\n//\n// Synopsis:\n// Range(start, end)\n//   - returns a generator producing a sequence of values {start, start+1,\n//     start+2, ..., }.\n// Range(start, end, step)\n//   - returns a generator producing a sequence of values {start, start+step,\n//     start+step+step, ..., }.\n// Notes:\n//   * The generated sequences never include end. For example, Range(1, 5)\n//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)\n//     returns a generator producing {1, 3, 5, 7}.\n//   * start and end must have the same type. That type may be any integral or\n//     floating-point type or a user defined type satisfying these conditions:\n//     * It must be assignable (have operator=() defined).\n//     * It must have operator+() (operator+(int-compatible type) for\n//       two-operand version).\n//     * It must have operator<() defined.\n//     Elements in the resulting sequences will also have that type.\n//   * Condition start < end must be satisfied in order for resulting sequences\n//     to contain any elements.\n//\ntemplate <typename T, typename IncrementT>\ninternal::ParamGenerator<T> Range(T start, T end, IncrementT step) {\n  return internal::ParamGenerator<T>(\n      new internal::RangeGenerator<T, IncrementT>(start, end, step));\n}\n\ntemplate <typename T>\ninternal::ParamGenerator<T> Range(T start, T end) {\n  return Range(start, end, 1);\n}\n\n// ValuesIn() function allows generation of tests with parameters coming from\n// a container.\n//\n// Synopsis:\n// ValuesIn(const T (&array)[N])\n//   - returns a generator producing sequences with elements from\n//     a C-style array.\n// ValuesIn(const Container& container)\n//   - returns a generator producing sequences with elements from\n//     an STL-style container.\n// ValuesIn(Iterator begin, Iterator end)\n//   - returns a generator producing sequences with elements from\n//     a range [begin, end) defined by a pair of STL-style iterators. These\n//     iterators can also be plain C pointers.\n//\n// Please note that ValuesIn copies the values from the containers\n// passed in and keeps them to generate tests in RUN_ALL_TESTS().\n//\n// Examples:\n//\n// This instantiates tests from test case StringTest\n// each with C-string values of \"foo\", \"bar\", and \"baz\":\n//\n// const char* strings[] = {\"foo\", \"bar\", \"baz\"};\n// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));\n//\n// This instantiates tests from test case StlStringTest\n// each with STL strings with values \"a\" and \"b\":\n//\n// ::std::vector< ::std::string> GetParameterStrings() {\n//   ::std::vector< ::std::string> v;\n//   v.push_back(\"a\");\n//   v.push_back(\"b\");\n//   return v;\n// }\n//\n// INSTANTIATE_TEST_CASE_P(CharSequence,\n//                         StlStringTest,\n//                         ValuesIn(GetParameterStrings()));\n//\n//\n// This will also instantiate tests from CharTest\n// each with parameter values 'a' and 'b':\n//\n// ::std::list<char> GetParameterChars() {\n//   ::std::list<char> list;\n//   list.push_back('a');\n//   list.push_back('b');\n//   return list;\n// }\n// ::std::list<char> l = GetParameterChars();\n// INSTANTIATE_TEST_CASE_P(CharSequence2,\n//                         CharTest,\n//                         ValuesIn(l.begin(), l.end()));\n//\ntemplate <typename ForwardIterator>\ninternal::ParamGenerator<\n  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>\nValuesIn(ForwardIterator begin, ForwardIterator end) {\n  typedef typename ::testing::internal::IteratorTraits<ForwardIterator>\n      ::value_type ParamType;\n  return internal::ParamGenerator<ParamType>(\n      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));\n}\n\ntemplate <typename T, size_t N>\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {\n  return ValuesIn(array, array + N);\n}\n\ntemplate <class Container>\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\n    const Container& container) {\n  return ValuesIn(container.begin(), container.end());\n}\n\n// Values() allows generating tests from explicitly specified list of\n// parameters.\n//\n// Synopsis:\n// Values(T v1, T v2, ..., T vN)\n//   - returns a generator producing sequences with elements v1, v2, ..., vN.\n//\n// For example, this instantiates tests from test case BarTest each\n// with values \"one\", \"two\", and \"three\":\n//\n// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values(\"one\", \"two\", \"three\"));\n//\n// This instantiates tests from test case BazTest each with values 1, 2, 3.5.\n// The exact type of values will depend on the type of parameter in BazTest.\n//\n// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));\n//\n// Currently, Values() supports from 1 to 50 parameters.\n//\ntemplate <typename T1>\ninternal::ValueArray1<T1> Values(T1 v1) {\n  return internal::ValueArray1<T1>(v1);\n}\n\ntemplate <typename T1, typename T2>\ninternal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {\n  return internal::ValueArray2<T1, T2>(v1, v2);\n}\n\ntemplate <typename T1, typename T2, typename T3>\ninternal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {\n  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4>\ninternal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {\n  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\ninternal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5) {\n  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6>\ninternal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,\n    T4 v4, T5 v5, T6 v6) {\n  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7>\ninternal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,\n    T4 v4, T5 v5, T6 v6, T7 v7) {\n  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,\n      v6, v7);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8>\ninternal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {\n  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,\n      v5, v6, v7, v8);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9>\ninternal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {\n  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,\n      v4, v5, v6, v7, v8, v9);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10>\ninternal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,\n    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {\n  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,\n      v2, v3, v4, v5, v6, v7, v8, v9, v10);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11>\ninternal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,\n    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11) {\n  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,\n      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12>\ninternal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12) {\n  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13>\ninternal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\n    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13) {\n  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14>\ninternal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {\n  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\n      v14);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15>\ninternal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\n    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {\n  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\n      v13, v14, v15);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16>\ninternal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16) {\n  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\n      v12, v13, v14, v15, v16);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17>\ninternal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17) {\n  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\n      v11, v12, v13, v14, v15, v16, v17);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18>\ninternal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\n    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18) {\n  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\n      v10, v11, v12, v13, v14, v15, v16, v17, v18);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19>\ninternal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\n    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\n    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {\n  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,\n      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20>\ninternal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\n    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {\n  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,\n      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21>\ninternal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\n    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {\n  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,\n      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22>\ninternal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,\n    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22) {\n  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,\n      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\n      v20, v21, v22);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23>\ninternal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22, T23 v23) {\n  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,\n      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\n      v20, v21, v22, v23);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24>\ninternal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22, T23 v23, T24 v24) {\n  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,\n      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,\n      v19, v20, v21, v22, v23, v24);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25>\ninternal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,\n    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,\n    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,\n    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {\n  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,\n      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,\n      v18, v19, v20, v21, v22, v23, v24, v25);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26>\ninternal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26) {\n  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,\n      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27>\ninternal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\n    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27) {\n  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,\n      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28>\ninternal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\n    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28) {\n  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\n      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,\n      v28);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29>\ninternal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28, T29 v29) {\n  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\n      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,\n      v27, v28, v29);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30>\ninternal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\n    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\n    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\n    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {\n  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\n      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,\n      v26, v27, v28, v29, v30);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31>\ninternal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {\n  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\n      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,\n      v25, v26, v27, v28, v29, v30, v31);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32>\ninternal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\n    T32 v32) {\n  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\n      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\n      v24, v25, v26, v27, v28, v29, v30, v31, v32);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33>\ninternal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\n    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\n    T32 v32, T33 v33) {\n  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,\n      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\n      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34>\ninternal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\n    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\n    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,\n    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,\n    T31 v31, T32 v32, T33 v33, T34 v34) {\n  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,\n      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,\n      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35>\ninternal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\n    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\n    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\n    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {\n  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,\n      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,\n      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36>\ninternal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\n    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\n    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\n    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {\n  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,\n      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\n      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\n      v34, v35, v36);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37>\ninternal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,\n    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\n    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\n    T37 v37) {\n  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,\n      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\n      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\n      v34, v35, v36, v37);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38>\ninternal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\n    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\n    T37 v37, T38 v38) {\n  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,\n      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,\n      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,\n      v33, v34, v35, v36, v37, v38);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39>\ninternal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\n    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\n    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\n    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\n    T37 v37, T38 v38, T39 v39) {\n  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,\n      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,\n      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,\n      v32, v33, v34, v35, v36, v37, v38, v39);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40>\ninternal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,\n    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,\n    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,\n    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,\n    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,\n    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {\n  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,\n      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,\n      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41>\ninternal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\n    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {\n  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,\n      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,\n      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42>\ninternal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\n    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n    T42 v42) {\n  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\n      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,\n      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,\n      v42);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43>\ninternal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\n    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n    T42 v42, T43 v43) {\n  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\n      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,\n      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,\n      v41, v42, v43);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44>\ninternal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\n    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\n    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\n    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\n    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\n    T42 v42, T43 v43, T44 v44) {\n  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\n      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,\n      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,\n      v40, v41, v42, v43, v44);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45>\ninternal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\n    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\n    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\n    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,\n    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,\n    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {\n  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\n      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,\n      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,\n      v39, v40, v41, v42, v43, v44, v45);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46>\ninternal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\n    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\n    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {\n  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\n      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\n      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,\n      v38, v39, v40, v41, v42, v43, v44, v45, v46);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47>\ninternal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\n    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\n    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\n    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {\n  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,\n      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\n      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,\n      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48>\ninternal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\n    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\n    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\n    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\n    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\n    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,\n    T48 v48) {\n  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,\n      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,\n      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,\n      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49>\ninternal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\n    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\n    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,\n    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,\n    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,\n    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,\n    T47 v47, T48 v48, T49 v49) {\n  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,\n      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,\n      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,\n      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);\n}\n\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\n    typename T6, typename T7, typename T8, typename T9, typename T10,\n    typename T11, typename T12, typename T13, typename T14, typename T15,\n    typename T16, typename T17, typename T18, typename T19, typename T20,\n    typename T21, typename T22, typename T23, typename T24, typename T25,\n    typename T26, typename T27, typename T28, typename T29, typename T30,\n    typename T31, typename T32, typename T33, typename T34, typename T35,\n    typename T36, typename T37, typename T38, typename T39, typename T40,\n    typename T41, typename T42, typename T43, typename T44, typename T45,\n    typename T46, typename T47, typename T48, typename T49, typename T50>\ninternal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\n    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\n    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\n    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,\n    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\n    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\n    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\n    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,\n    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,\n    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {\n  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\n      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\n      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\n      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,\n      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\n      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\n      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,\n      v48, v49, v50);\n}\n\n// Bool() allows generating tests with parameters in a set of (false, true).\n//\n// Synopsis:\n// Bool()\n//   - returns a generator producing sequences with elements {false, true}.\n//\n// It is useful when testing code that depends on Boolean flags. Combinations\n// of multiple flags can be tested when several Bool()'s are combined using\n// Combine() function.\n//\n// In the following example all tests in the test case FlagDependentTest\n// will be instantiated twice with parameters false and true.\n//\n// class FlagDependentTest : public testing::TestWithParam<bool> {\n//   virtual void SetUp() {\n//     external_flag = GetParam();\n//   }\n// }\n// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());\n//\ninline internal::ParamGenerator<bool> Bool() {\n  return Values(false, true);\n}\n\n# if GTEST_HAS_COMBINE\n// Combine() allows the user to combine two or more sequences to produce\n// values of a Cartesian product of those sequences' elements.\n//\n// Synopsis:\n// Combine(gen1, gen2, ..., genN)\n//   - returns a generator producing sequences with elements coming from\n//     the Cartesian product of elements from the sequences generated by\n//     gen1, gen2, ..., genN. The sequence elements will have a type of\n//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types\n//     of elements from sequences produces by gen1, gen2, ..., genN.\n//\n// Combine can have up to 10 arguments. This number is currently limited\n// by the maximum number of elements in the tuple implementation used by Google\n// Test.\n//\n// Example:\n//\n// This will instantiate tests in test case AnimalTest each one with\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\n//\n// enum Color { BLACK, GRAY, WHITE };\n// class AnimalTest\n//     : public testing::TestWithParam<tuple<const char*, Color> > {...};\n//\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\n//\n// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,\n//                         Combine(Values(\"cat\", \"dog\"),\n//                                 Values(BLACK, WHITE)));\n//\n// This will instantiate tests in FlagDependentTest with all variations of two\n// Boolean flags:\n//\n// class FlagDependentTest\n//     : public testing::TestWithParam<tuple(bool, bool)> > {\n//   virtual void SetUp() {\n//     // Assigns external_flag_1 and external_flag_2 values from the tuple.\n//     tie(external_flag_1, external_flag_2) = GetParam();\n//   }\n// };\n//\n// TEST_P(FlagDependentTest, TestFeature1) {\n//   // Test your code using external_flag_1 and external_flag_2 here.\n// }\n// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,\n//                         Combine(Bool(), Bool()));\n//\ntemplate <typename Generator1, typename Generator2>\ninternal::CartesianProductHolder2<Generator1, Generator2> Combine(\n    const Generator1& g1, const Generator2& g2) {\n  return internal::CartesianProductHolder2<Generator1, Generator2>(\n      g1, g2);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3>\ninternal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3) {\n  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(\n      g1, g2, g3);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4>\ninternal::CartesianProductHolder4<Generator1, Generator2, Generator3,\n    Generator4> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4) {\n  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,\n      Generator4>(\n      g1, g2, g3, g4);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5>\ninternal::CartesianProductHolder5<Generator1, Generator2, Generator3,\n    Generator4, Generator5> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5) {\n  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,\n      Generator4, Generator5>(\n      g1, g2, g3, g4, g5);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5, typename Generator6>\ninternal::CartesianProductHolder6<Generator1, Generator2, Generator3,\n    Generator4, Generator5, Generator6> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5, const Generator6& g6) {\n  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,\n      Generator4, Generator5, Generator6>(\n      g1, g2, g3, g4, g5, g6);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5, typename Generator6,\n    typename Generator7>\ninternal::CartesianProductHolder7<Generator1, Generator2, Generator3,\n    Generator4, Generator5, Generator6, Generator7> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5, const Generator6& g6,\n        const Generator7& g7) {\n  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,\n      Generator4, Generator5, Generator6, Generator7>(\n      g1, g2, g3, g4, g5, g6, g7);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5, typename Generator6,\n    typename Generator7, typename Generator8>\ninternal::CartesianProductHolder8<Generator1, Generator2, Generator3,\n    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5, const Generator6& g6,\n        const Generator7& g7, const Generator8& g8) {\n  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,\n      Generator4, Generator5, Generator6, Generator7, Generator8>(\n      g1, g2, g3, g4, g5, g6, g7, g8);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5, typename Generator6,\n    typename Generator7, typename Generator8, typename Generator9>\ninternal::CartesianProductHolder9<Generator1, Generator2, Generator3,\n    Generator4, Generator5, Generator6, Generator7, Generator8,\n    Generator9> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5, const Generator6& g6,\n        const Generator7& g7, const Generator8& g8, const Generator9& g9) {\n  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,\n      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(\n      g1, g2, g3, g4, g5, g6, g7, g8, g9);\n}\n\ntemplate <typename Generator1, typename Generator2, typename Generator3,\n    typename Generator4, typename Generator5, typename Generator6,\n    typename Generator7, typename Generator8, typename Generator9,\n    typename Generator10>\ninternal::CartesianProductHolder10<Generator1, Generator2, Generator3,\n    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,\n    Generator10> Combine(\n    const Generator1& g1, const Generator2& g2, const Generator3& g3,\n        const Generator4& g4, const Generator5& g5, const Generator6& g6,\n        const Generator7& g7, const Generator8& g8, const Generator9& g9,\n        const Generator10& g10) {\n  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,\n      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,\n      Generator10>(\n      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);\n}\n# endif  // GTEST_HAS_COMBINE\n\n\n\n# define TEST_P(test_case_name, test_name) \\\n  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \\\n      : public test_case_name { \\\n   public: \\\n    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \\\n    virtual void TestBody(); \\\n   private: \\\n    static int AddToRegistry() { \\\n      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \\\n          GetTestCasePatternHolder<test_case_name>(\\\n              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\\\n                  #test_case_name, \\\n                  #test_name, \\\n                  new ::testing::internal::TestMetaFactory< \\\n                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \\\n      return 0; \\\n    } \\\n    static int gtest_registering_dummy_; \\\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(\\\n        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \\\n  }; \\\n  int GTEST_TEST_CLASS_NAME_(test_case_name, \\\n                             test_name)::gtest_registering_dummy_ = \\\n      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \\\n  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()\n\n# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \\\n  ::testing::internal::ParamGenerator<test_case_name::ParamType> \\\n      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \\\n  int gtest_##prefix##test_case_name##_dummy_ = \\\n      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \\\n          GetTestCasePatternHolder<test_case_name>(\\\n              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\\\n                  #prefix, \\\n                  &gtest_##prefix##test_case_name##_EvalGenerator_, \\\n                  __FILE__, __LINE__)\n\n}  // namespace testing\n\n#endif  // GTEST_HAS_PARAM_TEST\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\n// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// Google C++ Testing Framework definitions useful in production code.\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_\n#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_\n\n// When you need to test the private or protected members of a class,\n// use the FRIEND_TEST macro to declare your tests as friends of the\n// class.  For example:\n//\n// class MyClass {\n//  private:\n//   void MyMethod();\n//   FRIEND_TEST(MyClassTest, MyMethod);\n// };\n//\n// class MyClassTest : public testing::Test {\n//   // ...\n// };\n//\n// TEST_F(MyClassTest, MyMethod) {\n//   // Can call MyClass::MyMethod() here.\n// }\n\n#define FRIEND_TEST(test_case_name, test_name)\\\nfriend class test_case_name##_##test_name##_Test\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: mheule@google.com (Markus Heule)\n//\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n\n#include <iosfwd>\n#include <vector>\n\nnamespace testing {\n\n// A copyable object representing the result of a test part (i.e. an\n// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).\n//\n// Don't inherit from TestPartResult as its destructor is not virtual.\nclass GTEST_API_ TestPartResult {\n public:\n  // The possible outcomes of a test part (i.e. an assertion or an\n  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).\n  enum Type {\n    kSuccess,          // Succeeded.\n    kNonFatalFailure,  // Failed but the test can continue.\n    kFatalFailure      // Failed and the test should be terminated.\n  };\n\n  // C'tor.  TestPartResult does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestPartResult object.\n  TestPartResult(Type a_type,\n                 const char* a_file_name,\n                 int a_line_number,\n                 const char* a_message)\n      : type_(a_type),\n        file_name_(a_file_name),\n        line_number_(a_line_number),\n        summary_(ExtractSummary(a_message)),\n        message_(a_message) {\n  }\n\n  // Gets the outcome of the test part.\n  Type type() const { return type_; }\n\n  // Gets the name of the source file where the test part took place, or\n  // NULL if it's unknown.\n  const char* file_name() const { return file_name_.c_str(); }\n\n  // Gets the line in the source file where the test part took place,\n  // or -1 if it's unknown.\n  int line_number() const { return line_number_; }\n\n  // Gets the summary of the failure message.\n  const char* summary() const { return summary_.c_str(); }\n\n  // Gets the message associated with the test part.\n  const char* message() const { return message_.c_str(); }\n\n  // Returns true iff the test part passed.\n  bool passed() const { return type_ == kSuccess; }\n\n  // Returns true iff the test part failed.\n  bool failed() const { return type_ != kSuccess; }\n\n  // Returns true iff the test part non-fatally failed.\n  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }\n\n  // Returns true iff the test part fatally failed.\n  bool fatally_failed() const { return type_ == kFatalFailure; }\n private:\n  Type type_;\n\n  // Gets the summary of the failure message by omitting the stack\n  // trace in it.\n  static internal::String ExtractSummary(const char* message);\n\n  // The name of the source file where the test part took place, or\n  // NULL if the source file is unknown.\n  internal::String file_name_;\n  // The line in the source file where the test part took place, or -1\n  // if the line number is unknown.\n  int line_number_;\n  internal::String summary_;  // The test failure summary.\n  internal::String message_;  // The test failure message.\n};\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result);\n\n// An array of TestPartResult objects.\n//\n// Don't inherit from TestPartResultArray as its destructor is not\n// virtual.\nclass GTEST_API_ TestPartResultArray {\n public:\n  TestPartResultArray() {}\n\n  // Appends the given TestPartResult to the array.\n  void Append(const TestPartResult& result);\n\n  // Returns the TestPartResult at the given index (0-based).\n  const TestPartResult& GetTestPartResult(int index) const;\n\n  // Returns the number of TestPartResult objects in the array.\n  int size() const;\n\n private:\n  std::vector<TestPartResult> array_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);\n};\n\n// This interface knows how to report a test part result.\nclass TestPartResultReporterInterface {\n public:\n  virtual ~TestPartResultReporterInterface() {}\n\n  virtual void ReportTestPartResult(const TestPartResult& result) = 0;\n};\n\nnamespace internal {\n\n// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a\n// statement generates new fatal failures. To do so it registers itself as the\n// current test part result reporter. Besides checking if fatal failures were\n// reported, it only delegates the reporting to the former result reporter.\n// The original result reporter is restored in the destructor.\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nclass GTEST_API_ HasNewFatalFailureHelper\n    : public TestPartResultReporterInterface {\n public:\n  HasNewFatalFailureHelper();\n  virtual ~HasNewFatalFailureHelper();\n  virtual void ReportTestPartResult(const TestPartResult& result);\n  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }\n private:\n  bool has_new_fatal_failure_;\n  TestPartResultReporterInterface* original_reporter_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\n// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n\n// This header implements typed tests and type-parameterized tests.\n\n// Typed (aka type-driven) tests repeat the same test for types in a\n// list.  You must know which types you want to test with when writing\n// typed tests. Here's how you do it:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n public:\n  ...\n  typedef std::list<T> List;\n  static T shared_;\n  T value_;\n};\n\n// Next, associate a list of types with the test case, which will be\n// repeated for each type in the list.  The typedef is necessary for\n// the macro to parse correctly.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nTYPED_TEST_CASE(FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   TYPED_TEST_CASE(FooTest, int);\n\n// Then, use TYPED_TEST() instead of TEST_F() to define as many typed\n// tests for this test case as you want.\nTYPED_TEST(FooTest, DoesBlah) {\n  // Inside a test, refer to TypeParam to get the type parameter.\n  // Since we are inside a derived class template, C++ requires use to\n  // visit the members of FooTest via 'this'.\n  TypeParam n = this->value_;\n\n  // To visit static members of the fixture, add the TestFixture::\n  // prefix.\n  n += TestFixture::shared_;\n\n  // To refer to typedefs in the fixture, add the \"typename\n  // TestFixture::\" prefix.\n  typename TestFixture::List values;\n  values.push_back(n);\n  ...\n}\n\nTYPED_TEST(FooTest, HasPropertyA) { ... }\n\n#endif  // 0\n\n// Type-parameterized tests are abstract test patterns parameterized\n// by a type.  Compared with typed tests, type-parameterized tests\n// allow you to define the test pattern without knowing what the type\n// parameters are.  The defined pattern can be instantiated with\n// different types any number of times, in any number of translation\n// units.\n//\n// If you are designing an interface or concept, you can define a\n// suite of type-parameterized tests to verify properties that any\n// valid implementation of the interface/concept should have.  Then,\n// each implementation can easily instantiate the test suite to verify\n// that it conforms to the requirements, without having to write\n// similar tests repeatedly.  Here's an example:\n\n#if 0\n\n// First, define a fixture class template.  It should be parameterized\n// by a type.  Remember to derive it from testing::Test.\ntemplate <typename T>\nclass FooTest : public testing::Test {\n  ...\n};\n\n// Next, declare that you will define a type-parameterized test case\n// (the _P suffix is for \"parameterized\" or \"pattern\", whichever you\n// prefer):\nTYPED_TEST_CASE_P(FooTest);\n\n// Then, use TYPED_TEST_P() to define as many type-parameterized tests\n// for this type-parameterized test case as you want.\nTYPED_TEST_P(FooTest, DoesBlah) {\n  // Inside a test, refer to TypeParam to get the type parameter.\n  TypeParam n = 0;\n  ...\n}\n\nTYPED_TEST_P(FooTest, HasPropertyA) { ... }\n\n// Now the tricky part: you need to register all test patterns before\n// you can instantiate them.  The first argument of the macro is the\n// test case name; the rest are the names of the tests in this test\n// case.\nREGISTER_TYPED_TEST_CASE_P(FooTest,\n                           DoesBlah, HasPropertyA);\n\n// Finally, you are free to instantiate the pattern with the types you\n// want.  If you put the above code in a header file, you can #include\n// it in multiple C++ source files and instantiate it multiple times.\n//\n// To distinguish different instances of the pattern, the first\n// argument to the INSTANTIATE_* macro is a prefix that will be added\n// to the actual test case name.  Remember to pick unique prefixes for\n// different instances.\ntypedef testing::Types<char, int, unsigned int> MyTypes;\nINSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);\n\n// If the type list contains only one type, you can write that type\n// directly without Types<...>:\n//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);\n\n#endif  // 0\n\n\n// Implements typed tests.\n\n#if GTEST_HAS_TYPED_TEST\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the typedef for the type parameters of the\n// given test case.\n# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_\n\n// The 'Types' template argument below must have spaces around it\n// since some compilers may choke on '>>' when passing a template\n// instance (e.g. Types<int>)\n# define TYPED_TEST_CASE(CaseName, Types) \\\n  typedef ::testing::internal::TypeList< Types >::type \\\n      GTEST_TYPE_PARAMS_(CaseName)\n\n# define TYPED_TEST(CaseName, TestName) \\\n  template <typename gtest_TypeParam_> \\\n  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \\\n      : public CaseName<gtest_TypeParam_> { \\\n   private: \\\n    typedef CaseName<gtest_TypeParam_> TestFixture; \\\n    typedef gtest_TypeParam_ TypeParam; \\\n    virtual void TestBody(); \\\n  }; \\\n  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \\\n      ::testing::internal::TypeParameterizedTest< \\\n          CaseName, \\\n          ::testing::internal::TemplateSel< \\\n              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \\\n          GTEST_TYPE_PARAMS_(CaseName)>::Register(\\\n              \"\", #CaseName, #TestName, 0); \\\n  template <typename gtest_TypeParam_> \\\n  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()\n\n#endif  // GTEST_HAS_TYPED_TEST\n\n// Implements type-parameterized tests.\n\n#if GTEST_HAS_TYPED_TEST_P\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the namespace name that the type-parameterized tests for\n// the given type-parameterized test case are defined in.  The exact\n// name of the namespace is subject to change without notice.\n# define GTEST_CASE_NAMESPACE_(TestCaseName) \\\n  gtest_case_##TestCaseName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n//\n// Expands to the name of the variable used to remember the names of\n// the defined tests in the given test case.\n# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \\\n  gtest_typed_test_case_p_state_##TestCaseName##_\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.\n//\n// Expands to the name of the variable used to remember the names of\n// the registered tests in the given test case.\n# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \\\n  gtest_registered_test_names_##TestCaseName##_\n\n// The variables defined in the type-parameterized test macros are\n// static as typically these macros are used in a .h file that can be\n// #included in multiple translation units linked together.\n# define TYPED_TEST_CASE_P(CaseName) \\\n  static ::testing::internal::TypedTestCasePState \\\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)\n\n# define TYPED_TEST_P(CaseName, TestName) \\\n  namespace GTEST_CASE_NAMESPACE_(CaseName) { \\\n  template <typename gtest_TypeParam_> \\\n  class TestName : public CaseName<gtest_TypeParam_> { \\\n   private: \\\n    typedef CaseName<gtest_TypeParam_> TestFixture; \\\n    typedef gtest_TypeParam_ TypeParam; \\\n    virtual void TestBody(); \\\n  }; \\\n  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \\\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\\\n          __FILE__, __LINE__, #CaseName, #TestName); \\\n  } \\\n  template <typename gtest_TypeParam_> \\\n  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()\n\n# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \\\n  namespace GTEST_CASE_NAMESPACE_(CaseName) { \\\n  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \\\n  } \\\n  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \\\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\\\n          __FILE__, __LINE__, #__VA_ARGS__)\n\n// The 'Types' template argument below must have spaces around it\n// since some compilers may choke on '>>' when passing a template\n// instance (e.g. Types<int>)\n# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \\\n  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \\\n      ::testing::internal::TypeParameterizedTestCase<CaseName, \\\n          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \\\n          ::testing::internal::TypeList< Types >::type>::Register(\\\n              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))\n\n#endif  // GTEST_HAS_TYPED_TEST_P\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\n\n// Depending on the platform, different string classes are available.\n// On Linux, in addition to ::std::string, Google also makes use of\n// class ::string, which has the same interface as ::std::string, but\n// has a different implementation.\n//\n// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that\n// ::string is available AND is a distinct type to ::std::string, or\n// define it to 0 to indicate otherwise.\n//\n// If the user's ::std::string and ::string are the same class due to\n// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.\n//\n// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined\n// heuristically.\n\nnamespace testing {\n\n// Declares the flags.\n\n// This flag temporary enables the disabled tests.\nGTEST_DECLARE_bool_(also_run_disabled_tests);\n\n// This flag brings the debugger on an assertion failure.\nGTEST_DECLARE_bool_(break_on_failure);\n\n// This flag controls whether Google Test catches all test-thrown exceptions\n// and logs them as failures.\nGTEST_DECLARE_bool_(catch_exceptions);\n\n// This flag enables using colors in terminal output. Available values are\n// \"yes\" to enable colors, \"no\" (disable colors), or \"auto\" (the default)\n// to let Google Test decide.\nGTEST_DECLARE_string_(color);\n\n// This flag sets up the filter to select by name using a glob pattern\n// the tests to run. If the filter is not given all tests are executed.\nGTEST_DECLARE_string_(filter);\n\n// This flag causes the Google Test to list tests. None of the tests listed\n// are actually run if the flag is provided.\nGTEST_DECLARE_bool_(list_tests);\n\n// This flag controls whether Google Test emits a detailed XML report to a file\n// in addition to its normal textual output.\nGTEST_DECLARE_string_(output);\n\n// This flags control whether Google Test prints the elapsed time for each\n// test.\nGTEST_DECLARE_bool_(print_time);\n\n// This flag specifies the random number seed.\nGTEST_DECLARE_int32_(random_seed);\n\n// This flag sets how many times the tests are repeated. The default value\n// is 1. If the value is -1 the tests are repeating forever.\nGTEST_DECLARE_int32_(repeat);\n\n// This flag controls whether Google Test includes Google Test internal\n// stack frames in failure stack traces.\nGTEST_DECLARE_bool_(show_internal_stack_frames);\n\n// When this flag is specified, tests' order is randomized on every iteration.\nGTEST_DECLARE_bool_(shuffle);\n\n// This flag specifies the maximum number of stack frames to be\n// printed in a failure message.\nGTEST_DECLARE_int32_(stack_trace_depth);\n\n// When this flag is specified, a failed assertion will throw an\n// exception if exceptions are enabled, or exit the program with a\n// non-zero code otherwise.\nGTEST_DECLARE_bool_(throw_on_failure);\n\n// When this flag is set with a \"host:port\" string, on supported\n// platforms test results are streamed to the specified port on\n// the specified host machine.\nGTEST_DECLARE_string_(stream_result_to);\n\n// The upper limit for valid stack trace depths.\nconst int kMaxStackTraceDepth = 100;\n\nnamespace internal {\n\nclass AssertHelper;\nclass DefaultGlobalTestPartResultReporter;\nclass ExecDeathTest;\nclass NoExecDeathTest;\nclass FinalSuccessChecker;\nclass GTestFlagSaver;\nclass TestResultAccessor;\nclass TestEventListenersAccessor;\nclass TestEventRepeater;\nclass WindowsDeathTest;\nclass UnitTestImpl* GetUnitTestImpl();\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const String& message);\n\n// Converts a streamable value to a String.  A NULL pointer is\n// converted to \"(null)\".  When the input value is a ::string,\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\n// character in it is replaced with \"\\\\0\".\n// Declared in gtest-internal.h but defined here, so that it has access\n// to the definition of the Message class, required by the ARM\n// compiler.\ntemplate <typename T>\nString StreamableToString(const T& streamable) {\n  return (Message() << streamable).GetString();\n}\n\n}  // namespace internal\n\n// The friend relationship of some of these classes is cyclic.\n// If we don't forward declare them the compiler might confuse the classes\n// in friendship clauses with same named classes on the scope.\nclass Test;\nclass TestCase;\nclass TestInfo;\nclass UnitTest;\n\n// A class for indicating whether an assertion was successful.  When\n// the assertion wasn't successful, the AssertionResult object\n// remembers a non-empty message that describes how it failed.\n//\n// To create an instance of this class, use one of the factory functions\n// (AssertionSuccess() and AssertionFailure()).\n//\n// This class is useful for two purposes:\n//   1. Defining predicate functions to be used with Boolean test assertions\n//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts\n//   2. Defining predicate-format functions to be\n//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).\n//\n// For example, if you define IsEven predicate:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))\n// will print the message\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false (5 is odd)\n//   Expected: true\n//\n// instead of a more opaque\n//\n//   Value of: IsEven(Fib(5))\n//     Actual: false\n//   Expected: true\n//\n// in case IsEven is a simple Boolean predicate.\n//\n// If you expect your predicate to be reused and want to support informative\n// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up\n// about half as often as positive ones in our tests), supply messages for\n// both success and failure cases:\n//\n//   testing::AssertionResult IsEven(int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess() << n << \" is even\";\n//     else\n//       return testing::AssertionFailure() << n << \" is odd\";\n//   }\n//\n// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print\n//\n//   Value of: IsEven(Fib(6))\n//     Actual: true (8 is even)\n//   Expected: false\n//\n// NB: Predicates that support negative Boolean assertions have reduced\n// performance in positive ones so be careful not to use them in tests\n// that have lots (tens of thousands) of positive Boolean assertions.\n//\n// To use this class with EXPECT_PRED_FORMAT assertions such as:\n//\n//   // Verifies that Foo() returns an even number.\n//   EXPECT_PRED_FORMAT1(IsEven, Foo());\n//\n// you need to define:\n//\n//   testing::AssertionResult IsEven(const char* expr, int n) {\n//     if ((n % 2) == 0)\n//       return testing::AssertionSuccess();\n//     else\n//       return testing::AssertionFailure()\n//         << \"Expected: \" << expr << \" is even\\n  Actual: it's \" << n;\n//   }\n//\n// If Foo() returns 5, you will see the following message:\n//\n//   Expected: Foo() is even\n//     Actual: it's 5\n//\nclass GTEST_API_ AssertionResult {\n public:\n  // Copy constructor.\n  // Used in EXPECT_TRUE/FALSE(assertion_result).\n  AssertionResult(const AssertionResult& other);\n  // Used in the EXPECT_TRUE/FALSE(bool_expression).\n  explicit AssertionResult(bool success) : success_(success) {}\n\n  // Returns true iff the assertion succeeded.\n  operator bool() const { return success_; }  // NOLINT\n\n  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\n  AssertionResult operator!() const;\n\n  // Returns the text streamed into this AssertionResult. Test assertions\n  // use it when they fail (i.e., the predicate's outcome doesn't match the\n  // assertion's expectation). When nothing has been streamed into the\n  // object, returns an empty string.\n  const char* message() const {\n    return message_.get() != NULL ?  message_->c_str() : \"\";\n  }\n  // TODO(vladl@google.com): Remove this after making sure no clients use it.\n  // Deprecated; please use message() instead.\n  const char* failure_message() const { return message(); }\n\n  // Streams a custom failure message into this object.\n  template <typename T> AssertionResult& operator<<(const T& value) {\n    AppendMessage(Message() << value);\n    return *this;\n  }\n\n  // Allows streaming basic output manipulators such as endl or flush into\n  // this object.\n  AssertionResult& operator<<(\n      ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {\n    AppendMessage(Message() << basic_manipulator);\n    return *this;\n  }\n\n private:\n  // Appends the contents of message to message_.\n  void AppendMessage(const Message& a_message) {\n    if (message_.get() == NULL)\n      message_.reset(new ::std::string);\n    message_->append(a_message.GetString().c_str());\n  }\n\n  // Stores result of the assertion predicate.\n  bool success_;\n  // Stores the message describing the condition in case the expectation\n  // construct is not satisfied with the predicate's outcome.\n  // Referenced via a pointer to avoid taking too much stack frame space\n  // with test assertions.\n  internal::scoped_ptr< ::std::string> message_;\n\n  GTEST_DISALLOW_ASSIGN_(AssertionResult);\n};\n\n// Makes a successful assertion result.\nGTEST_API_ AssertionResult AssertionSuccess();\n\n// Makes a failed assertion result.\nGTEST_API_ AssertionResult AssertionFailure();\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << msg.\nGTEST_API_ AssertionResult AssertionFailure(const Message& msg);\n\n// The abstract class that all tests inherit from.\n//\n// In Google Test, a unit test program contains one or many TestCases, and\n// each TestCase contains one or many Tests.\n//\n// When you define a test using the TEST macro, you don't need to\n// explicitly derive from Test - the TEST macro automatically does\n// this for you.\n//\n// The only time you derive from Test is when defining a test fixture\n// to be used a TEST_F.  For example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     virtual void SetUp() { ... }\n//     virtual void TearDown() { ... }\n//     ...\n//   };\n//\n//   TEST_F(FooTest, Bar) { ... }\n//   TEST_F(FooTest, Baz) { ... }\n//\n// Test is not copyable.\nclass GTEST_API_ Test {\n public:\n  friend class TestInfo;\n\n  // Defines types for pointers to functions that set up and tear down\n  // a test case.\n  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;\n  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;\n\n  // The d'tor is virtual as we intend to inherit from Test.\n  virtual ~Test();\n\n  // Sets up the stuff shared by all tests in this test case.\n  //\n  // Google Test will call Foo::SetUpTestCase() before running the first\n  // test in test case Foo.  Hence a sub-class can define its own\n  // SetUpTestCase() method to shadow the one defined in the super\n  // class.\n  static void SetUpTestCase() {}\n\n  // Tears down the stuff shared by all tests in this test case.\n  //\n  // Google Test will call Foo::TearDownTestCase() after running the last\n  // test in test case Foo.  Hence a sub-class can define its own\n  // TearDownTestCase() method to shadow the one defined in the super\n  // class.\n  static void TearDownTestCase() {}\n\n  // Returns true iff the current test has a fatal failure.\n  static bool HasFatalFailure();\n\n  // Returns true iff the current test has a non-fatal failure.\n  static bool HasNonfatalFailure();\n\n  // Returns true iff the current test has a (either fatal or\n  // non-fatal) failure.\n  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }\n\n  // Logs a property for the current test.  Only the last value for a given\n  // key is remembered.\n  // These are public static so they can be called from utility functions\n  // that are not members of the test fixture.\n  // The arguments are const char* instead strings, as Google Test is used\n  // on platforms where string doesn't compile.\n  //\n  // Note that a driving consideration for these RecordProperty methods\n  // was to produce xml output suited to the Greenspan charting utility,\n  // which at present will only chart values that fit in a 32-bit int. It\n  // is the user's responsibility to restrict their values to 32-bit ints\n  // if they intend them to be used with Greenspan.\n  static void RecordProperty(const char* key, const char* value);\n  static void RecordProperty(const char* key, int value);\n\n protected:\n  // Creates a Test object.\n  Test();\n\n  // Sets up the test fixture.\n  virtual void SetUp();\n\n  // Tears down the test fixture.\n  virtual void TearDown();\n\n private:\n  // Returns true iff the current test has the same fixture class as\n  // the first test in the current test case.\n  static bool HasSameFixtureClass();\n\n  // Runs the test after the test fixture has been set up.\n  //\n  // A sub-class must implement this to define the test logic.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.\n  // Instead, use the TEST or TEST_F macro.\n  virtual void TestBody() = 0;\n\n  // Sets up, executes, and tears down the test.\n  void Run();\n\n  // Deletes self.  We deliberately pick an unusual name for this\n  // internal method to avoid clashing with names used in user TESTs.\n  void DeleteSelf_() { delete this; }\n\n  // Uses a GTestFlagSaver to save and restore all Google Test flags.\n  const internal::GTestFlagSaver* const gtest_flag_saver_;\n\n  // Often a user mis-spells SetUp() as Setup() and spends a long time\n  // wondering why it is never called by Google Test.  The declaration of\n  // the following method is solely for catching such an error at\n  // compile time:\n  //\n  //   - The return type is deliberately chosen to be not void, so it\n  //   will be a conflict if a user declares void Setup() in his test\n  //   fixture.\n  //\n  //   - This method is private, so it will be another compiler error\n  //   if a user calls it from his test fixture.\n  //\n  // DO NOT OVERRIDE THIS FUNCTION.\n  //\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }\n\n  // We disallow copying Tests.\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);\n};\n\ntypedef internal::TimeInMillis TimeInMillis;\n\n// A copyable object representing a user specified test property which can be\n// output as a key/value string pair.\n//\n// Don't inherit from TestProperty as its destructor is not virtual.\nclass TestProperty {\n public:\n  // C'tor.  TestProperty does NOT have a default constructor.\n  // Always use this constructor (with parameters) to create a\n  // TestProperty object.\n  TestProperty(const char* a_key, const char* a_value) :\n    key_(a_key), value_(a_value) {\n  }\n\n  // Gets the user supplied key.\n  const char* key() const {\n    return key_.c_str();\n  }\n\n  // Gets the user supplied value.\n  const char* value() const {\n    return value_.c_str();\n  }\n\n  // Sets a new value, overriding the one supplied in the constructor.\n  void SetValue(const char* new_value) {\n    value_ = new_value;\n  }\n\n private:\n  // The key supplied by the user.\n  internal::String key_;\n  // The value supplied by the user.\n  internal::String value_;\n};\n\n// The result of a single Test.  This includes a list of\n// TestPartResults, a list of TestProperties, a count of how many\n// death tests there are in the Test, and how much time it took to run\n// the Test.\n//\n// TestResult is not copyable.\nclass GTEST_API_ TestResult {\n public:\n  // Creates an empty TestResult.\n  TestResult();\n\n  // D'tor.  Do not inherit from TestResult.\n  ~TestResult();\n\n  // Gets the number of all test parts.  This is the sum of the number\n  // of successful test parts and the number of failed test parts.\n  int total_part_count() const;\n\n  // Returns the number of the test properties.\n  int test_property_count() const;\n\n  // Returns true iff the test passed (i.e. no test part failed).\n  bool Passed() const { return !Failed(); }\n\n  // Returns true iff the test failed.\n  bool Failed() const;\n\n  // Returns true iff the test fatally failed.\n  bool HasFatalFailure() const;\n\n  // Returns true iff the test has a non-fatal failure.\n  bool HasNonfatalFailure() const;\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Returns the i-th test part result among all the results. i can range\n  // from 0 to test_property_count() - 1. If i is not in that range, aborts\n  // the program.\n  const TestPartResult& GetTestPartResult(int i) const;\n\n  // Returns the i-th test property. i can range from 0 to\n  // test_property_count() - 1. If i is not in that range, aborts the\n  // program.\n  const TestProperty& GetTestProperty(int i) const;\n\n private:\n  friend class TestInfo;\n  friend class UnitTest;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::ExecDeathTest;\n  friend class internal::TestResultAccessor;\n  friend class internal::UnitTestImpl;\n  friend class internal::WindowsDeathTest;\n\n  // Gets the vector of TestPartResults.\n  const std::vector<TestPartResult>& test_part_results() const {\n    return test_part_results_;\n  }\n\n  // Gets the vector of TestProperties.\n  const std::vector<TestProperty>& test_properties() const {\n    return test_properties_;\n  }\n\n  // Sets the elapsed time.\n  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }\n\n  // Adds a test property to the list. The property is validated and may add\n  // a non-fatal failure if invalid (e.g., if it conflicts with reserved\n  // key names). If a property is already recorded for the same key, the\n  // value will be updated, rather than storing multiple values for the same\n  // key.\n  void RecordProperty(const TestProperty& test_property);\n\n  // Adds a failure if the key is a reserved attribute of Google Test\n  // testcase tags.  Returns true if the property is valid.\n  // TODO(russr): Validate attribute names are legal and human readable.\n  static bool ValidateTestProperty(const TestProperty& test_property);\n\n  // Adds a test part result to the list.\n  void AddTestPartResult(const TestPartResult& test_part_result);\n\n  // Returns the death test count.\n  int death_test_count() const { return death_test_count_; }\n\n  // Increments the death test count, returning the new count.\n  int increment_death_test_count() { return ++death_test_count_; }\n\n  // Clears the test part results.\n  void ClearTestPartResults();\n\n  // Clears the object.\n  void Clear();\n\n  // Protects mutable state of the property vector and of owned\n  // properties, whose values may be updated.\n  internal::Mutex test_properites_mutex_;\n\n  // The vector of TestPartResults\n  std::vector<TestPartResult> test_part_results_;\n  // The vector of TestProperties\n  std::vector<TestProperty> test_properties_;\n  // Running count of death tests.\n  int death_test_count_;\n  // The elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n  // We disallow copying TestResult.\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);\n};  // class TestResult\n\n// A TestInfo object stores the following information about a test:\n//\n//   Test case name\n//   Test name\n//   Whether the test should be run\n//   A function pointer that creates the test object when invoked\n//   Test result\n//\n// The constructor of TestInfo registers itself with the UnitTest\n// singleton such that the RUN_ALL_TESTS() macro knows which tests to\n// run.\nclass GTEST_API_ TestInfo {\n public:\n  // Destructs a TestInfo object.  This function is not virtual, so\n  // don't inherit from TestInfo.\n  ~TestInfo();\n\n  // Returns the test case name.\n  const char* test_case_name() const { return test_case_name_.c_str(); }\n\n  // Returns the test name.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a typed\n  // or a type-parameterized test.\n  const char* type_param() const {\n    if (type_param_.get() != NULL)\n      return type_param_->c_str();\n    return NULL;\n  }\n\n  // Returns the text representation of the value parameter, or NULL if this\n  // is not a value-parameterized test.\n  const char* value_param() const {\n    if (value_param_.get() != NULL)\n      return value_param_->c_str();\n    return NULL;\n  }\n\n  // Returns true if this test should run, that is if the test is not disabled\n  // (or it is disabled but the also_run_disabled_tests flag has been specified)\n  // and its full name matches the user-specified filter.\n  //\n  // Google Test allows the user to filter the tests by their full names.\n  // The full name of a test Bar in test case Foo is defined as\n  // \"Foo.Bar\".  Only the tests that match the filter will run.\n  //\n  // A filter is a colon-separated list of glob (not regex) patterns,\n  // optionally followed by a '-' and a colon-separated list of\n  // negative patterns (tests to exclude).  A test is run if it\n  // matches one of the positive patterns and does not match any of\n  // the negative patterns.\n  //\n  // For example, *A*:Foo.* is a filter that matches any string that\n  // contains the character 'A' or starts with \"Foo.\".\n  bool should_run() const { return should_run_; }\n\n  // Returns the result of the test.\n  const TestResult* result() const { return &result_; }\n\n private:\n\n#if GTEST_HAS_DEATH_TEST\n  friend class internal::DefaultDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n  friend class Test;\n  friend class TestCase;\n  friend class internal::UnitTestImpl;\n  friend TestInfo* internal::MakeAndRegisterTestInfo(\n      const char* test_case_name, const char* name,\n      const char* type_param,\n      const char* value_param,\n      internal::TypeId fixture_class_id,\n      Test::SetUpTestCaseFunc set_up_tc,\n      Test::TearDownTestCaseFunc tear_down_tc,\n      internal::TestFactoryBase* factory);\n\n  // Constructs a TestInfo object. The newly constructed instance assumes\n  // ownership of the factory object.\n  TestInfo(const char* test_case_name, const char* name,\n           const char* a_type_param,\n           const char* a_value_param,\n           internal::TypeId fixture_class_id,\n           internal::TestFactoryBase* factory);\n\n  // Increments the number of death tests encountered in this test so\n  // far.\n  int increment_death_test_count() {\n    return result_.increment_death_test_count();\n  }\n\n  // Creates the test object, runs it, records its result, and then\n  // deletes it.\n  void Run();\n\n  static void ClearTestResult(TestInfo* test_info) {\n    test_info->result_.Clear();\n  }\n\n  // These fields are immutable properties of the test.\n  const std::string test_case_name_;     // Test case name\n  const std::string name_;               // Test name\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const internal::scoped_ptr<const ::std::string> type_param_;\n  // Text representation of the value parameter, or NULL if this is not a\n  // value-parameterized test.\n  const internal::scoped_ptr<const ::std::string> value_param_;\n  const internal::TypeId fixture_class_id_;   // ID of the test fixture class\n  bool should_run_;                 // True iff this test should run\n  bool is_disabled_;                // True iff this test is disabled\n  bool matches_filter_;             // True if this test matches the\n                                    // user-specified filter.\n  internal::TestFactoryBase* const factory_;  // The factory that creates\n                                              // the test object\n\n  // This field is mutable and needs to be reset before running the\n  // test for the second time.\n  TestResult result_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);\n};\n\n// A test case, which consists of a vector of TestInfos.\n//\n// TestCase is not copyable.\nclass GTEST_API_ TestCase {\n public:\n  // Creates a TestCase with the given name.\n  //\n  // TestCase does NOT have a default constructor.  Always use this\n  // constructor to create a TestCase object.\n  //\n  // Arguments:\n  //\n  //   name:         name of the test case\n  //   a_type_param: the name of the test's type parameter, or NULL if\n  //                 this is not a type-parameterized test.\n  //   set_up_tc:    pointer to the function that sets up the test case\n  //   tear_down_tc: pointer to the function that tears down the test case\n  TestCase(const char* name, const char* a_type_param,\n           Test::SetUpTestCaseFunc set_up_tc,\n           Test::TearDownTestCaseFunc tear_down_tc);\n\n  // Destructor of TestCase.\n  virtual ~TestCase();\n\n  // Gets the name of the TestCase.\n  const char* name() const { return name_.c_str(); }\n\n  // Returns the name of the parameter type, or NULL if this is not a\n  // type-parameterized test case.\n  const char* type_param() const {\n    if (type_param_.get() != NULL)\n      return type_param_->c_str();\n    return NULL;\n  }\n\n  // Returns true if any test in this test case should run.\n  bool should_run() const { return should_run_; }\n\n  // Gets the number of successful tests in this test case.\n  int successful_test_count() const;\n\n  // Gets the number of failed tests in this test case.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests in this test case.\n  int disabled_test_count() const;\n\n  // Get the number of tests in this test case that should run.\n  int test_to_run_count() const;\n\n  // Gets the number of all tests in this test case.\n  int total_test_count() const;\n\n  // Returns true iff the test case passed.\n  bool Passed() const { return !Failed(); }\n\n  // Returns true iff the test case failed.\n  bool Failed() const { return failed_test_count() > 0; }\n\n  // Returns the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  const TestInfo* GetTestInfo(int i) const;\n\n private:\n  friend class Test;\n  friend class internal::UnitTestImpl;\n\n  // Gets the (mutable) vector of TestInfos in this TestCase.\n  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }\n\n  // Gets the (immutable) vector of TestInfos in this TestCase.\n  const std::vector<TestInfo*>& test_info_list() const {\n    return test_info_list_;\n  }\n\n  // Returns the i-th test among all the tests. i can range from 0 to\n  // total_test_count() - 1. If i is not in that range, returns NULL.\n  TestInfo* GetMutableTestInfo(int i);\n\n  // Sets the should_run member.\n  void set_should_run(bool should) { should_run_ = should; }\n\n  // Adds a TestInfo to this test case.  Will delete the TestInfo upon\n  // destruction of the TestCase object.\n  void AddTestInfo(TestInfo * test_info);\n\n  // Clears the results of all tests in this test case.\n  void ClearResult();\n\n  // Clears the results of all tests in the given test case.\n  static void ClearTestCaseResult(TestCase* test_case) {\n    test_case->ClearResult();\n  }\n\n  // Runs every test in this TestCase.\n  void Run();\n\n  // Runs SetUpTestCase() for this TestCase.  This wrapper is needed\n  // for catching exceptions thrown from SetUpTestCase().\n  void RunSetUpTestCase() { (*set_up_tc_)(); }\n\n  // Runs TearDownTestCase() for this TestCase.  This wrapper is\n  // needed for catching exceptions thrown from TearDownTestCase().\n  void RunTearDownTestCase() { (*tear_down_tc_)(); }\n\n  // Returns true iff test passed.\n  static bool TestPassed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Passed();\n  }\n\n  // Returns true iff test failed.\n  static bool TestFailed(const TestInfo* test_info) {\n    return test_info->should_run() && test_info->result()->Failed();\n  }\n\n  // Returns true iff test is disabled.\n  static bool TestDisabled(const TestInfo* test_info) {\n    return test_info->is_disabled_;\n  }\n\n  // Returns true if the given test should run.\n  static bool ShouldRunTest(const TestInfo* test_info) {\n    return test_info->should_run();\n  }\n\n  // Shuffles the tests in this test case.\n  void ShuffleTests(internal::Random* random);\n\n  // Restores the test order to before the first shuffle.\n  void UnshuffleTests();\n\n  // Name of the test case.\n  internal::String name_;\n  // Name of the parameter type, or NULL if this is not a typed or a\n  // type-parameterized test.\n  const internal::scoped_ptr<const ::std::string> type_param_;\n  // The vector of TestInfos in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestInfo*> test_info_list_;\n  // Provides a level of indirection for the test list to allow easy\n  // shuffling and restoring the test order.  The i-th element in this\n  // vector is the index of the i-th test in the shuffled test list.\n  std::vector<int> test_indices_;\n  // Pointer to the function that sets up the test case.\n  Test::SetUpTestCaseFunc set_up_tc_;\n  // Pointer to the function that tears down the test case.\n  Test::TearDownTestCaseFunc tear_down_tc_;\n  // True iff any test in this test case should run.\n  bool should_run_;\n  // Elapsed time, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n  // We disallow copying TestCases.\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);\n};\n\n// An Environment object is capable of setting up and tearing down an\n// environment.  The user should subclass this to define his own\n// environment(s).\n//\n// An Environment object does the set-up and tear-down in virtual\n// methods SetUp() and TearDown() instead of the constructor and the\n// destructor, as:\n//\n//   1. You cannot safely throw from a destructor.  This is a problem\n//      as in some cases Google Test is used where exceptions are enabled, and\n//      we may want to implement ASSERT_* using exceptions where they are\n//      available.\n//   2. You cannot use ASSERT_* directly in a constructor or\n//      destructor.\nclass Environment {\n public:\n  // The d'tor is virtual as we need to subclass Environment.\n  virtual ~Environment() {}\n\n  // Override this to define how to set up the environment.\n  virtual void SetUp() {}\n\n  // Override this to define how to tear down the environment.\n  virtual void TearDown() {}\n private:\n  // If you see an error about overriding the following function or\n  // about it being private, you have mis-spelled SetUp() as Setup().\n  struct Setup_should_be_spelled_SetUp {};\n  virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }\n};\n\n// The interface for tracing execution of tests. The methods are organized in\n// the order the corresponding events are fired.\nclass TestEventListener {\n public:\n  virtual ~TestEventListener() {}\n\n  // Fired before any test activity starts.\n  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;\n\n  // Fired before each iteration of tests starts.  There may be more than\n  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration\n  // index, starting from 0.\n  virtual void OnTestIterationStart(const UnitTest& unit_test,\n                                    int iteration) = 0;\n\n  // Fired before environment set-up for each iteration of tests starts.\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment set-up for each iteration of tests ends.\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;\n\n  // Fired before the test case starts.\n  virtual void OnTestCaseStart(const TestCase& test_case) = 0;\n\n  // Fired before the test starts.\n  virtual void OnTestStart(const TestInfo& test_info) = 0;\n\n  // Fired after a failed assertion or a SUCCEED() invocation.\n  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;\n\n  // Fired after the test ends.\n  virtual void OnTestEnd(const TestInfo& test_info) = 0;\n\n  // Fired after the test case ends.\n  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;\n\n  // Fired before environment tear-down for each iteration of tests starts.\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;\n\n  // Fired after environment tear-down for each iteration of tests ends.\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;\n\n  // Fired after each iteration of tests finishes.\n  virtual void OnTestIterationEnd(const UnitTest& unit_test,\n                                  int iteration) = 0;\n\n  // Fired after all test activities have ended.\n  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;\n};\n\n// The convenience class for users who need to override just one or two\n// methods and are not concerned that a possible change to a signature of\n// the methods they override will not be caught during the build.  For\n// comments about each method please see the definition of TestEventListener\n// above.\nclass EmptyTestEventListener : public TestEventListener {\n public:\n  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,\n                                    int /*iteration*/) {}\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}\n  virtual void OnTestStart(const TestInfo& /*test_info*/) {}\n  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}\n  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}\n  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,\n                                  int /*iteration*/) {}\n  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}\n};\n\n// TestEventListeners lets users add listeners to track events in Google Test.\nclass GTEST_API_ TestEventListeners {\n public:\n  TestEventListeners();\n  ~TestEventListeners();\n\n  // Appends an event listener to the end of the list. Google Test assumes\n  // the ownership of the listener (i.e. it will delete the listener when\n  // the test program finishes).\n  void Append(TestEventListener* listener);\n\n  // Removes the given event listener from the list and returns it.  It then\n  // becomes the caller's responsibility to delete the listener. Returns\n  // NULL if the listener is not found in the list.\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Returns the standard listener responsible for the default console\n  // output.  Can be removed from the listeners list to shut down default\n  // console output.  Note that removing this object from the listener list\n  // with Release transfers its ownership to the caller and makes this\n  // function return NULL the next time.\n  TestEventListener* default_result_printer() const {\n    return default_result_printer_;\n  }\n\n  // Returns the standard listener responsible for the default XML output\n  // controlled by the --gtest_output=xml flag.  Can be removed from the\n  // listeners list by users who want to shut down the default XML output\n  // controlled by this flag and substitute it with custom one.  Note that\n  // removing this object from the listener list with Release transfers its\n  // ownership to the caller and makes this function return NULL the next\n  // time.\n  TestEventListener* default_xml_generator() const {\n    return default_xml_generator_;\n  }\n\n private:\n  friend class TestCase;\n  friend class TestInfo;\n  friend class internal::DefaultGlobalTestPartResultReporter;\n  friend class internal::NoExecDeathTest;\n  friend class internal::TestEventListenersAccessor;\n  friend class internal::UnitTestImpl;\n\n  // Returns repeater that broadcasts the TestEventListener events to all\n  // subscribers.\n  TestEventListener* repeater();\n\n  // Sets the default_result_printer attribute to the provided listener.\n  // The listener is also added to the listener list and previous\n  // default_result_printer is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultResultPrinter(TestEventListener* listener);\n\n  // Sets the default_xml_generator attribute to the provided listener.  The\n  // listener is also added to the listener list and previous\n  // default_xml_generator is removed from it and deleted. The listener can\n  // also be NULL in which case it will not be added to the list. Does\n  // nothing if the previous and the current listener objects are the same.\n  void SetDefaultXmlGenerator(TestEventListener* listener);\n\n  // Controls whether events will be forwarded by the repeater to the\n  // listeners in the list.\n  bool EventForwardingEnabled() const;\n  void SuppressEventForwarding();\n\n  // The actual list of listeners.\n  internal::TestEventRepeater* repeater_;\n  // Listener responsible for the standard result output.\n  TestEventListener* default_result_printer_;\n  // Listener responsible for the creation of the XML output file.\n  TestEventListener* default_xml_generator_;\n\n  // We disallow copying TestEventListeners.\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);\n};\n\n// A UnitTest consists of a vector of TestCases.\n//\n// This is a singleton class.  The only instance of UnitTest is\n// created when UnitTest::GetInstance() is first called.  This\n// instance is never deleted.\n//\n// UnitTest is not copyable.\n//\n// This class is thread-safe as long as the methods are called\n// according to their specification.\nclass GTEST_API_ UnitTest {\n public:\n  // Gets the singleton UnitTest object.  The first time this method\n  // is called, a UnitTest object is constructed and returned.\n  // Consecutive calls will return the same object.\n  static UnitTest* GetInstance();\n\n  // Runs all tests in this UnitTest object and prints the result.\n  // Returns 0 if successful, or 1 otherwise.\n  //\n  // This method can only be called from the main thread.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  int Run() GTEST_MUST_USE_RESULT_;\n\n  // Returns the working directory when the first TEST() or TEST_F()\n  // was executed.  The UnitTest object owns the string.\n  const char* original_working_dir() const;\n\n  // Returns the TestCase object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestCase* current_test_case() const;\n\n  // Returns the TestInfo object for the test that's currently running,\n  // or NULL if no test is running.\n  const TestInfo* current_test_info() const;\n\n  // Returns the random seed used at the start of the current test run.\n  int random_seed() const;\n\n#if GTEST_HAS_PARAM_TEST\n  // Returns the ParameterizedTestCaseRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  //\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n  internal::ParameterizedTestCaseRegistry& parameterized_test_registry();\n#endif  // GTEST_HAS_PARAM_TEST\n\n  // Gets the number of successful test cases.\n  int successful_test_case_count() const;\n\n  // Gets the number of failed test cases.\n  int failed_test_case_count() const;\n\n  // Gets the number of all test cases.\n  int total_test_case_count() const;\n\n  // Gets the number of all test cases that contain at least one test\n  // that should run.\n  int test_case_to_run_count() const;\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const;\n\n  // Returns true iff the unit test passed (i.e. all test cases passed).\n  bool Passed() const;\n\n  // Returns true iff the unit test failed (i.e. some test case failed\n  // or something outside of all tests failed).\n  bool Failed() const;\n\n  // Gets the i-th test case among all the test cases. i can range from 0 to\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\n  const TestCase* GetTestCase(int i) const;\n\n  // Returns the list of event listeners that can be used to track events\n  // inside Google Test.\n  TestEventListeners& listeners();\n\n private:\n  // Registers and returns a global test environment.  When a test\n  // program is run, all global test environments will be set-up in\n  // the order they were registered.  After all tests in the program\n  // have finished, all global test environments will be torn-down in\n  // the *reverse* order they were registered.\n  //\n  // The UnitTest object takes ownership of the given environment.\n  //\n  // This method can only be called from the main thread.\n  Environment* AddEnvironment(Environment* env);\n\n  // Adds a TestPartResult to the current TestResult object.  All\n  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)\n  // eventually call this to report their results.  The user code\n  // should use the assertion macros instead of calling this directly.\n  void AddTestPartResult(TestPartResult::Type result_type,\n                         const char* file_name,\n                         int line_number,\n                         const internal::String& message,\n                         const internal::String& os_stack_trace);\n\n  // Adds a TestProperty to the current TestResult object. If the result already\n  // contains a property with the same key, the value will be updated.\n  void RecordPropertyForCurrentTest(const char* key, const char* value);\n\n  // Gets the i-th test case among all the test cases. i can range from 0 to\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\n  TestCase* GetMutableTestCase(int i);\n\n  // Accessors for the implementation object.\n  internal::UnitTestImpl* impl() { return impl_; }\n  const internal::UnitTestImpl* impl() const { return impl_; }\n\n  // These classes and funcions are friends as they need to access private\n  // members of UnitTest.\n  friend class Test;\n  friend class internal::AssertHelper;\n  friend class internal::ScopedTrace;\n  friend Environment* AddGlobalTestEnvironment(Environment* env);\n  friend internal::UnitTestImpl* internal::GetUnitTestImpl();\n  friend void internal::ReportFailureInUnknownLocation(\n      TestPartResult::Type result_type,\n      const internal::String& message);\n\n  // Creates an empty UnitTest.\n  UnitTest();\n\n  // D'tor\n  virtual ~UnitTest();\n\n  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n  // Google Test trace stack.\n  void PushGTestTrace(const internal::TraceInfo& trace);\n\n  // Pops a trace from the per-thread Google Test trace stack.\n  void PopGTestTrace();\n\n  // Protects mutable state in *impl_.  This is mutable as some const\n  // methods need to lock it too.\n  mutable internal::Mutex mutex_;\n\n  // Opaque implementation object.  This field is never changed once\n  // the object is constructed.  We don't mark it as const here, as\n  // doing so will cause a warning in the constructor of UnitTest.\n  // Mutable state in *impl_ is protected by mutex_.\n  internal::UnitTestImpl* impl_;\n\n  // We disallow copying UnitTest.\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest);\n};\n\n// A convenient wrapper for adding an environment for the test\n// program.\n//\n// You should call this before RUN_ALL_TESTS() is called, probably in\n// main().  If you use gtest_main, you need to call this before main()\n// starts for it to take effect.  For example, you can define a global\n// variable like this:\n//\n//   testing::Environment* const foo_env =\n//       testing::AddGlobalTestEnvironment(new FooEnvironment);\n//\n// However, we strongly recommend you to write your own main() and\n// call AddGlobalTestEnvironment() there, as relying on initialization\n// of global variables makes the code harder to read and may cause\n// problems when you register multiple environments from different\n// translation units and the environments have dependencies among them\n// (remember that the compiler doesn't guarantee the order in which\n// global variables from different translation units are initialized).\ninline Environment* AddGlobalTestEnvironment(Environment* env) {\n  return UnitTest::GetInstance()->AddEnvironment(env);\n}\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nGTEST_API_ void InitGoogleTest(int* argc, char** argv);\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nGTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);\n\nnamespace internal {\n\n// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)\n// operand to be used in a failure message.  The type (but not value)\n// of the other operand may affect the format.  This allows us to\n// print a char* as a raw pointer when it is compared against another\n// char*, and print it as a C string when it is compared against an\n// std::string object, for example.\n//\n// The default implementation ignores the type of the other operand.\n// Some specialized versions are used to handle formatting wide or\n// narrow C strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename T1, typename T2>\nString FormatForComparisonFailureMessage(const T1& value,\n                                         const T2& /* other_operand */) {\n  // C++Builder compiles this incorrectly if the namespace isn't explicitly\n  // given.\n  return ::testing::PrintToString(value);\n}\n\n// The helper function for {ASSERT|EXPECT}_EQ.\ntemplate <typename T1, typename T2>\nAssertionResult CmpHelperEQ(const char* expected_expression,\n                            const char* actual_expression,\n                            const T1& expected,\n                            const T2& actual) {\n#ifdef _MSC_VER\n# pragma warning(push)          // Saves the current warning state.\n# pragma warning(disable:4389)  // Temporarily disables warning on\n                               // signed/unsigned mismatch.\n#endif\n\n  if (expected == actual) {\n    return AssertionSuccess();\n  }\n\n#ifdef _MSC_VER\n# pragma warning(pop)          // Restores the warning state.\n#endif\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   FormatForComparisonFailureMessage(expected, actual),\n                   FormatForComparisonFailureMessage(actual, expected),\n                   false);\n}\n\n// With this overloaded version, we allow anonymous enums to be used\n// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums\n// can be implicitly cast to BiggestInt.\nGTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,\n                                       const char* actual_expression,\n                                       BiggestInt expected,\n                                       BiggestInt actual);\n\n// The helper class for {ASSERT|EXPECT}_EQ.  The template argument\n// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()\n// is a null pointer literal.  The following default implementation is\n// for lhs_is_null_literal being false.\ntemplate <bool lhs_is_null_literal>\nclass EqHelper {\n public:\n  // This templatized version is for the general case.\n  template <typename T1, typename T2>\n  static AssertionResult Compare(const char* expected_expression,\n                                 const char* actual_expression,\n                                 const T1& expected,\n                                 const T2& actual) {\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\n                       actual);\n  }\n\n  // With this overloaded version, we allow anonymous enums to be used\n  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous\n  // enums can be implicitly cast to BiggestInt.\n  //\n  // Even though its body looks the same as the above version, we\n  // cannot merge the two, as it will make anonymous enums unhappy.\n  static AssertionResult Compare(const char* expected_expression,\n                                 const char* actual_expression,\n                                 BiggestInt expected,\n                                 BiggestInt actual) {\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\n                       actual);\n  }\n};\n\n// This specialization is used when the first argument to ASSERT_EQ()\n// is a null pointer literal, like NULL, false, or 0.\ntemplate <>\nclass EqHelper<true> {\n public:\n  // We define two overloaded versions of Compare().  The first\n  // version will be picked when the second argument to ASSERT_EQ() is\n  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or\n  // EXPECT_EQ(false, a_bool).\n  template <typename T1, typename T2>\n  static AssertionResult Compare(\n      const char* expected_expression,\n      const char* actual_expression,\n      const T1& expected,\n      const T2& actual,\n      // The following line prevents this overload from being considered if T2\n      // is not a pointer type.  We need this because ASSERT_EQ(NULL, my_ptr)\n      // expands to Compare(\"\", \"\", NULL, my_ptr), which requires a conversion\n      // to match the Secret* in the other overload, which would otherwise make\n      // this template match better.\n      typename EnableIf<!is_pointer<T2>::value>::type* = 0) {\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\n                       actual);\n  }\n\n  // This version will be picked when the second argument to ASSERT_EQ() is a\n  // pointer, e.g. ASSERT_EQ(NULL, a_pointer).\n  template <typename T>\n  static AssertionResult Compare(\n      const char* expected_expression,\n      const char* actual_expression,\n      // We used to have a second template parameter instead of Secret*.  That\n      // template parameter would deduce to 'long', making this a better match\n      // than the first overload even without the first overload's EnableIf.\n      // Unfortunately, gcc with -Wconversion-null warns when \"passing NULL to\n      // non-pointer argument\" (even a deduced integral argument), so the old\n      // implementation caused warnings in user code.\n      Secret* /* expected (NULL) */,\n      T* actual) {\n    // We already know that 'expected' is a null pointer.\n    return CmpHelperEQ(expected_expression, actual_expression,\n                       static_cast<T*>(NULL), actual);\n  }\n};\n\n// A macro for implementing the helper functions needed to implement\n// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste\n// of similar code.\n//\n// For each templatized helper function, we also define an overloaded\n// version for BiggestInt in order to reduce code bloat and allow\n// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled\n// with gcc 4.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)\\\ntemplate <typename T1, typename T2>\\\nAssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\n                                   const T1& val1, const T2& val2) {\\\n  if (val1 op val2) {\\\n    return AssertionSuccess();\\\n  } else {\\\n    return AssertionFailure() \\\n        << \"Expected: (\" << expr1 << \") \" #op \" (\" << expr2\\\n        << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\\\n        << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\\\n  }\\\n}\\\nGTEST_API_ AssertionResult CmpHelper##op_name(\\\n    const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\n\n// Implements the helper function for {ASSERT|EXPECT}_NE\nGTEST_IMPL_CMP_HELPER_(NE, !=);\n// Implements the helper function for {ASSERT|EXPECT}_LE\nGTEST_IMPL_CMP_HELPER_(LE, <=);\n// Implements the helper function for {ASSERT|EXPECT}_LT\nGTEST_IMPL_CMP_HELPER_(LT, < );\n// Implements the helper function for {ASSERT|EXPECT}_GE\nGTEST_IMPL_CMP_HELPER_(GE, >=);\n// Implements the helper function for {ASSERT|EXPECT}_GT\nGTEST_IMPL_CMP_HELPER_(GT, > );\n\n#undef GTEST_IMPL_CMP_HELPER_\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,\n                                          const char* actual_expression,\n                                          const char* expected,\n                                          const char* actual);\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,\n                                              const char* actual_expression,\n                                              const char* expected,\n                                              const char* actual);\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const char* s1,\n                                          const char* s2);\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                              const char* s2_expression,\n                                              const char* s1,\n                                              const char* s2);\n\n\n// Helper function for *_STREQ on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,\n                                          const char* actual_expression,\n                                          const wchar_t* expected,\n                                          const wchar_t* actual);\n\n// Helper function for *_STRNE on wide strings.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\n                                          const char* s2_expression,\n                                          const wchar_t* s1,\n                                          const wchar_t* s2);\n\n}  // namespace internal\n\n// IsSubstring() and IsNotSubstring() are intended to be used as the\n// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by\n// themselves.  They check whether needle is a substring of haystack\n// (NULL is considered a substring of itself only), and return an\n// appropriate error message when they fail.\n//\n// The {needle,haystack}_expr arguments are the stringified\n// expressions that generated the two real arguments.\nGTEST_API_ AssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const char* needle, const char* haystack);\nGTEST_API_ AssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const wchar_t* needle, const wchar_t* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const char* needle, const char* haystack);\nGTEST_API_ AssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const wchar_t* needle, const wchar_t* haystack);\nGTEST_API_ AssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::string& needle, const ::std::string& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::string& needle, const ::std::string& haystack);\n\n#if GTEST_HAS_STD_WSTRING\nGTEST_API_ AssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::wstring& needle, const ::std::wstring& haystack);\nGTEST_API_ AssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::wstring& needle, const ::std::wstring& haystack);\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n// Helper template function for comparing floating-points.\n//\n// Template parameter:\n//\n//   RawType: the raw floating-point type (either float or double)\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\ntemplate <typename RawType>\nAssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,\n                                         const char* actual_expression,\n                                         RawType expected,\n                                         RawType actual) {\n  const FloatingPoint<RawType> lhs(expected), rhs(actual);\n\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  ::std::stringstream expected_ss;\n  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n              << expected;\n\n  ::std::stringstream actual_ss;\n  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n            << actual;\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   StringStreamToString(&expected_ss),\n                   StringStreamToString(&actual_ss),\n                   false);\n}\n\n// Helper function for implementing ASSERT_NEAR.\n//\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\nGTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,\n                                                const char* expr2,\n                                                const char* abs_error_expr,\n                                                double val1,\n                                                double val2,\n                                                double abs_error);\n\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\n// A class that enables one to stream messages to assertion macros\nclass GTEST_API_ AssertHelper {\n public:\n  // Constructor.\n  AssertHelper(TestPartResult::Type type,\n               const char* file,\n               int line,\n               const char* message);\n  ~AssertHelper();\n\n  // Message assignment is a semantic trick to enable assertion\n  // streaming; see the GTEST_MESSAGE_ macro below.\n  void operator=(const Message& message) const;\n\n private:\n  // We put our data in a struct so that the size of the AssertHelper class can\n  // be as small as possible.  This is important because gcc is incapable of\n  // re-using stack space even for temporary variables, so every EXPECT_EQ\n  // reserves stack space for another AssertHelper.\n  struct AssertHelperData {\n    AssertHelperData(TestPartResult::Type t,\n                     const char* srcfile,\n                     int line_num,\n                     const char* msg)\n        : type(t), file(srcfile), line(line_num), message(msg) { }\n\n    TestPartResult::Type const type;\n    const char*        const file;\n    int                const line;\n    String             const message;\n\n   private:\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);\n  };\n\n  AssertHelperData* const data_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);\n};\n\n}  // namespace internal\n\n#if GTEST_HAS_PARAM_TEST\n// The pure interface class that all value-parameterized tests inherit from.\n// A value-parameterized class must inherit from both ::testing::Test and\n// ::testing::WithParamInterface. In most cases that just means inheriting\n// from ::testing::TestWithParam, but more complicated test hierarchies\n// may need to inherit from Test and WithParamInterface at different levels.\n//\n// This interface has support for accessing the test parameter value via\n// the GetParam() method.\n//\n// Use it with one of the parameter generator defining functions, like Range(),\n// Values(), ValuesIn(), Bool(), and Combine().\n//\n// class FooTest : public ::testing::TestWithParam<int> {\n//  protected:\n//   FooTest() {\n//     // Can use GetParam() here.\n//   }\n//   virtual ~FooTest() {\n//     // Can use GetParam() here.\n//   }\n//   virtual void SetUp() {\n//     // Can use GetParam() here.\n//   }\n//   virtual void TearDown {\n//     // Can use GetParam() here.\n//   }\n// };\n// TEST_P(FooTest, DoesBar) {\n//   // Can use GetParam() method here.\n//   Foo foo;\n//   ASSERT_TRUE(foo.DoesBar(GetParam()));\n// }\n// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));\n\ntemplate <typename T>\nclass WithParamInterface {\n public:\n  typedef T ParamType;\n  virtual ~WithParamInterface() {}\n\n  // The current parameter value. Is also available in the test fixture's\n  // constructor. This member function is non-static, even though it only\n  // references static data, to reduce the opportunity for incorrect uses\n  // like writing 'WithParamInterface<bool>::GetParam()' for a test that\n  // uses a fixture whose parameter type is int.\n  const ParamType& GetParam() const { return *parameter_; }\n\n private:\n  // Sets parameter value. The caller is responsible for making sure the value\n  // remains alive and unchanged throughout the current test.\n  static void SetParam(const ParamType* parameter) {\n    parameter_ = parameter;\n  }\n\n  // Static value used for accessing parameter during a test lifetime.\n  static const ParamType* parameter_;\n\n  // TestClass must be a subclass of WithParamInterface<T> and Test.\n  template <class TestClass> friend class internal::ParameterizedTestFactory;\n};\n\ntemplate <typename T>\nconst T* WithParamInterface<T>::parameter_ = NULL;\n\n// Most value-parameterized classes can ignore the existence of\n// WithParamInterface, and can just inherit from ::testing::TestWithParam.\n\ntemplate <typename T>\nclass TestWithParam : public Test, public WithParamInterface<T> {\n};\n\n#endif  // GTEST_HAS_PARAM_TEST\n\n// Macros for indicating success/failure in test code.\n\n// ADD_FAILURE unconditionally adds a failure to the current test.\n// SUCCEED generates a success - it doesn't automatically make the\n// current test successful, as a test is only successful when it has\n// no failure.\n//\n// EXPECT_* verifies that a certain condition is satisfied.  If not,\n// it behaves like ADD_FAILURE.  In particular:\n//\n//   EXPECT_TRUE  verifies that a Boolean condition is true.\n//   EXPECT_FALSE verifies that a Boolean condition is false.\n//\n// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except\n// that they will also abort the current function on failure.  People\n// usually want the fail-fast behavior of FAIL and ASSERT_*, but those\n// writing data-driven tests often find themselves using ADD_FAILURE\n// and EXPECT_* more.\n//\n// Examples:\n//\n//   EXPECT_TRUE(server.StatusIsOK());\n//   ASSERT_FALSE(server.HasPendingRequest(port))\n//       << \"There are still pending requests \" << \"on port \" << port;\n\n// Generates a nonfatal failure with a generic message.\n#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_(\"Failed\")\n\n// Generates a nonfatal failure at the given source file location with\n// a generic message.\n#define ADD_FAILURE_AT(file, line) \\\n  GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\n                    ::testing::TestPartResult::kNonFatalFailure)\n\n// Generates a fatal failure with a generic message.\n#define GTEST_FAIL() GTEST_FATAL_FAILURE_(\"Failed\")\n\n// Define this macro to 1 to omit the definition of FAIL(), which is a\n// generic name and clashes with some other libraries.\n#if !GTEST_DONT_DEFINE_FAIL\n# define FAIL() GTEST_FAIL()\n#endif\n\n// Generates a success with a generic message.\n#define GTEST_SUCCEED() GTEST_SUCCESS_(\"Succeeded\")\n\n// Define this macro to 1 to omit the definition of SUCCEED(), which\n// is a generic name and clashes with some other libraries.\n#if !GTEST_DONT_DEFINE_SUCCEED\n# define SUCCEED() GTEST_SUCCEED()\n#endif\n\n// Macros for testing exceptions.\n//\n//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):\n//         Tests that the statement throws the expected exception.\n//    * {ASSERT|EXPECT}_NO_THROW(statement):\n//         Tests that the statement doesn't throw any exception.\n//    * {ASSERT|EXPECT}_ANY_THROW(statement):\n//         Tests that the statement throws an exception.\n\n#define EXPECT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_THROW(statement, expected_exception) \\\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)\n#define ASSERT_NO_THROW(statement) \\\n  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)\n#define ASSERT_ANY_THROW(statement) \\\n  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)\n\n// Boolean assertions. Condition can be either a Boolean expression or an\n// AssertionResult. For more information on how to use AssertionResult with\n// these macros see comments on that class.\n#define EXPECT_TRUE(condition) \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define EXPECT_FALSE(condition) \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_NONFATAL_FAILURE_)\n#define ASSERT_TRUE(condition) \\\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\n                      GTEST_FATAL_FAILURE_)\n#define ASSERT_FALSE(condition) \\\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\n                      GTEST_FATAL_FAILURE_)\n\n// Includes the auto-generated header that implements a family of\n// generic predicate assertion macros.\n// Copyright 2006, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command\n// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!\n//\n// Implements a family of generic predicate assertion macros.\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n\n// Makes sure this header is not included before gtest.h.\n#ifndef GTEST_INCLUDE_GTEST_GTEST_H_\n# error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.\n#endif  // GTEST_INCLUDE_GTEST_GTEST_H_\n\n// This header implements a family of generic predicate assertion\n// macros:\n//\n//   ASSERT_PRED_FORMAT1(pred_format, v1)\n//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)\n//   ...\n//\n// where pred_format is a function or functor that takes n (in the\n// case of ASSERT_PRED_FORMATn) values and their source expression\n// text, and returns a testing::AssertionResult.  See the definition\n// of ASSERT_EQ in gtest.h for an example.\n//\n// If you don't care about formatting, you can use the more\n// restrictive version:\n//\n//   ASSERT_PRED1(pred, v1)\n//   ASSERT_PRED2(pred, v1, v2)\n//   ...\n//\n// where pred is an n-ary function or functor that returns bool,\n// and the values v1, v2, ..., must support the << operator for\n// streaming to std::ostream.\n//\n// We also define the EXPECT_* variations.\n//\n// For now we only support predicates whose arity is at most 5.\n// Please email googletestframework@googlegroups.com if you need\n// support for higher arities.\n\n// GTEST_ASSERT_ is the basic statement to which all of the assertions\n// in this file reduce.  Don't use this in your code.\n\n#define GTEST_ASSERT_(expression, on_failure) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (const ::testing::AssertionResult gtest_ar = (expression)) \\\n    ; \\\n  else \\\n    on_failure(gtest_ar.failure_message())\n\n#define GTEST_ASSERT_MESSAGE(expression, on_failure, message) \\\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\n  if (::testing::AssertionResult gtest_ar = (expression)) \\\n    ; \\\n  else \\\n    on_failure((gtest_ar.failure_message()))\n\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\ntemplate <typename Pred,\n          typename T1>\nAssertionResult AssertPred1Helper(const char* pred_text,\n                                  const char* e1,\n                                  Pred pred,\n                                  const T1& v1) {\n  if (pred(v1)) return AssertionSuccess();\n\n  return AssertionFailure() << pred_text << \"(\"\n                            << e1 << \") evaluates to false, where\"\n                            << \"\\n\" << e1 << \" evaluates to \" << v1;\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\\\n  GTEST_ASSERT_(pred_format(#v1, v1),\\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use\n// this in your code.\n#define GTEST_PRED1_(pred, v1, on_failure)\\\n  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \\\n                                             #v1, \\\n                                             pred, \\\n                                             v1), on_failure)\n\n// Unary predicate assertion macros.\n#define EXPECT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED1(pred, v1) \\\n  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT1(pred_format, v1) \\\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED1(pred, v1) \\\n  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)\n\n\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\ntemplate <typename Pred,\n          typename T1,\n          typename T2>\nAssertionResult AssertPred2Helper(const char* pred_text,\n                                  const char* e1,\n                                  const char* e2,\n                                  Pred pred,\n                                  const T1& v1,\n                                  const T2& v2) {\n  if (pred(v1, v2)) return AssertionSuccess();\n\n  return AssertionFailure() << pred_text << \"(\"\n                            << e1 << \", \"\n                            << e2 << \") evaluates to false, where\"\n                            << \"\\n\" << e1 << \" evaluates to \" << v1\n                            << \"\\n\" << e2 << \" evaluates to \" << v2;\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\\\n  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\\\n                on_failure)\n\n#define GTEST_PRED_FORMAT2_MESSAGE(pred_format, v1, v2, message, on_failure)\\\n  GTEST_ASSERT_MESSAGE(pred_format(#message#v1, #message#v2, v1, v2),\\\n                on_failure, message)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use\n// this in your code.\n#define GTEST_PRED2_(pred, v1, v2, on_failure)\\\n  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \\\n                                             #v1, \\\n                                             #v2, \\\n                                             pred, \\\n                                             v1, \\\n                                             v2), on_failure)\n\n// Binary predicate assertion macros.\n#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED_FORMAT2_MESSAGE(pred_format, v1, v2, message) \\\n  GTEST_PRED_FORMAT2_MESSAGE(pred_format, v1, v2, message, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \\\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)\n\n#define ASSERT_PRED_FORMAT2_MESSAGE(pred_format, v1, v2, message) \\\n  GTEST_PRED_FORMAT2_MESSAGE(pred_format, v1, v2, message, GTEST_FATAL_FAILURE_)\n\n#define ASSERT_PRED2(pred, v1, v2) \\\n  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)\n\n\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\ntemplate <typename Pred,\n          typename T1,\n          typename T2,\n          typename T3>\nAssertionResult AssertPred3Helper(const char* pred_text,\n                                  const char* e1,\n                                  const char* e2,\n                                  const char* e3,\n                                  Pred pred,\n                                  const T1& v1,\n                                  const T2& v2,\n                                  const T3& v3) {\n  if (pred(v1, v2, v3)) return AssertionSuccess();\n\n  return AssertionFailure() << pred_text << \"(\"\n                            << e1 << \", \"\n                            << e2 << \", \"\n                            << e3 << \") evaluates to false, where\"\n                            << \"\\n\" << e1 << \" evaluates to \" << v1\n                            << \"\\n\" << e2 << \" evaluates to \" << v2\n                            << \"\\n\" << e3 << \" evaluates to \" << v3;\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use\n// this in your code.\n#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\\\n  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \\\n                                             #v1, \\\n                                             #v2, \\\n                                             #v3, \\\n                                             pred, \\\n                                             v1, \\\n                                             v2, \\\n                                             v3), on_failure)\n\n// Ternary predicate assertion macros.\n#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED3(pred, v1, v2, v3) \\\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)\n\n\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\ntemplate <typename Pred,\n          typename T1,\n          typename T2,\n          typename T3,\n          typename T4>\nAssertionResult AssertPred4Helper(const char* pred_text,\n                                  const char* e1,\n                                  const char* e2,\n                                  const char* e3,\n                                  const char* e4,\n                                  Pred pred,\n                                  const T1& v1,\n                                  const T2& v2,\n                                  const T3& v3,\n                                  const T4& v4) {\n  if (pred(v1, v2, v3, v4)) return AssertionSuccess();\n\n  return AssertionFailure() << pred_text << \"(\"\n                            << e1 << \", \"\n                            << e2 << \", \"\n                            << e3 << \", \"\n                            << e4 << \") evaluates to false, where\"\n                            << \"\\n\" << e1 << \" evaluates to \" << v1\n                            << \"\\n\" << e2 << \" evaluates to \" << v2\n                            << \"\\n\" << e3 << \" evaluates to \" << v3\n                            << \"\\n\" << e4 << \" evaluates to \" << v4;\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use\n// this in your code.\n#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\\\n  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \\\n                                             #v1, \\\n                                             #v2, \\\n                                             #v3, \\\n                                             #v4, \\\n                                             pred, \\\n                                             v1, \\\n                                             v2, \\\n                                             v3, \\\n                                             v4), on_failure)\n\n// 4-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED4(pred, v1, v2, v3, v4) \\\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\n\n\n\n// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\ntemplate <typename Pred,\n          typename T1,\n          typename T2,\n          typename T3,\n          typename T4,\n          typename T5>\nAssertionResult AssertPred5Helper(const char* pred_text,\n                                  const char* e1,\n                                  const char* e2,\n                                  const char* e3,\n                                  const char* e4,\n                                  const char* e5,\n                                  Pred pred,\n                                  const T1& v1,\n                                  const T2& v2,\n                                  const T3& v3,\n                                  const T4& v4,\n                                  const T5& v5) {\n  if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();\n\n  return AssertionFailure() << pred_text << \"(\"\n                            << e1 << \", \"\n                            << e2 << \", \"\n                            << e3 << \", \"\n                            << e4 << \", \"\n                            << e5 << \") evaluates to false, where\"\n                            << \"\\n\" << e1 << \" evaluates to \" << v1\n                            << \"\\n\" << e2 << \" evaluates to \" << v2\n                            << \"\\n\" << e3 << \" evaluates to \" << v3\n                            << \"\\n\" << e4 << \" evaluates to \" << v4\n                            << \"\\n\" << e5 << \" evaluates to \" << v5;\n}\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.\n// Don't use this in your code.\n#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\\\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\\\n                on_failure)\n\n// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use\n// this in your code.\n#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\\\n  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \\\n                                             #v1, \\\n                                             #v2, \\\n                                             #v3, \\\n                                             #v4, \\\n                                             #v5, \\\n                                             pred, \\\n                                             v1, \\\n                                             v2, \\\n                                             v3, \\\n                                             v4, \\\n                                             v5), on_failure)\n\n// 5-ary predicate assertion macros.\n#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\n#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \\\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\n\n\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\n\n// Macros for testing equalities and inequalities.\n//\n//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual\n//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2\n//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2\n//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2\n//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2\n//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2\n//\n// When they are not, Google Test prints both the tested expressions and\n// their actual values.  The values must be compatible built-in types,\n// or you will get a compiler error.  By \"compatible\" we mean that the\n// values can be compared by the respective operator.\n//\n// Note:\n//\n//   1. It is possible to make a user-defined type work with\n//   {ASSERT|EXPECT}_??(), but that requires overloading the\n//   comparison operators and is thus discouraged by the Google C++\n//   Usage Guide.  Therefore, you are advised to use the\n//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are\n//   equal.\n//\n//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on\n//   pointers (in particular, C strings).  Therefore, if you use it\n//   with two C strings, you are testing how their locations in memory\n//   are related, not how their content is related.  To compare two C\n//   strings by content, use {ASSERT|EXPECT}_STR*().\n//\n//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to\n//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you\n//   what the actual value is when it fails, and similarly for the\n//   other comparisons.\n//\n//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()\n//   evaluate their arguments, which is undefined.\n//\n//   5. These macros evaluate their arguments exactly once.\n//\n// Examples:\n//\n//   EXPECT_NE(5, Foo());\n//   EXPECT_EQ(NULL, a_pointer);\n//   ASSERT_LT(i, array_size);\n//   ASSERT_GT(records.size(), 0) << \"There is no record left.\";\n\n#define EXPECT_EQ(expected, actual) \\\n  EXPECT_PRED_FORMAT2(::testing::internal:: \\\n                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \\\n                      expected, actual)\n#define EXPECT_NE(expected, actual) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)\n#define EXPECT_LE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define EXPECT_LT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define EXPECT_GE(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define EXPECT_GT(val1, val2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n#define GTEST_ASSERT_EQ(expected, actual) \\\n  ASSERT_PRED_FORMAT2(::testing::internal:: \\\n                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \\\n                      expected, actual)\n\n#define GTEST_ASSERT_EQ_MESSAGE(expected, actual, message) \\\n  ASSERT_PRED_FORMAT2_MESSAGE(::testing::internal:: \\\n                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \\\n                      expected, actual, message)\n\n#define GTEST_ASSERT_NE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\n#define GTEST_ASSERT_LE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\n#define GTEST_ASSERT_LT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\n#define GTEST_ASSERT_GE(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\n#define GTEST_ASSERT_GT(val1, val2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\n\n// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of\n// ASSERT_XY(), which clashes with some users' own code.\n\n#if !GTEST_DONT_DEFINE_ASSERT_EQ\n# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)\n# define ASSERT_EQ_MESSAGE(val1, val2, message) GTEST_ASSERT_EQ_MESSAGE(val1, val2, message)\n#endif\n\n#if !GTEST_DONT_DEFINE_ASSERT_NE\n# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)\n#endif\n\n#if !GTEST_DONT_DEFINE_ASSERT_LE\n# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)\n#endif\n\n#if !GTEST_DONT_DEFINE_ASSERT_LT\n# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)\n#endif\n\n#if !GTEST_DONT_DEFINE_ASSERT_GE\n# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)\n#endif\n\n#if !GTEST_DONT_DEFINE_ASSERT_GT\n# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)\n#endif\n\n// C String Comparisons.  All tests treat NULL and any non-NULL string\n// as different.  Two NULLs are equal.\n//\n//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2\n//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2\n//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case\n//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case\n//\n// For wide or narrow string objects, you can use the\n// {ASSERT|EXPECT}_??() macros.\n//\n// Don't depend on the order in which the arguments are evaluated,\n// which is undefined.\n//\n// These macros evaluate their arguments exactly once.\n\n#define EXPECT_STREQ(expected, actual) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)\n#define EXPECT_STRNE(s1, s2) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define EXPECT_STRCASEEQ(expected, actual) \\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)\n#define EXPECT_STRCASENE(s1, s2)\\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n#define ASSERT_STREQ(expected, actual) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)\n#define ASSERT_STRNE(s1, s2) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\n#define ASSERT_STRCASEEQ(expected, actual) \\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)\n#define ASSERT_STRCASENE(s1, s2)\\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\n\n// Macros for comparing floating-point numbers.\n//\n//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):\n//         Tests that two float values are almost equal.\n//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):\n//         Tests that two double values are almost equal.\n//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):\n//         Tests that v1 and v2 are within the given distance to each other.\n//\n// Google Test uses ULP-based comparison to automatically pick a default\n// error bound that is appropriate for the operands.  See the\n// FloatingPoint template class in gtest-internal.h if you are\n// interested in the implementation details.\n\n#define EXPECT_FLOAT_EQ(expected, actual)\\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      expected, actual)\n\n#define EXPECT_DOUBLE_EQ(expected, actual)\\\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      expected, actual)\n\n#define ASSERT_FLOAT_EQ(expected, actual)\\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\n                      expected, actual)\n\n#define ASSERT_DOUBLE_EQ(expected, actual)\\\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\n                      expected, actual)\n\n#define EXPECT_NEAR(val1, val2, abs_error)\\\n  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \\\n                      val1, val2, abs_error)\n\n#define ASSERT_NEAR(val1, val2, abs_error)\\\n  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \\\n                      val1, val2, abs_error)\n\n// These predicate format functions work on floating-point values, and\n// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.\n//\n//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nGTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,\n                                   float val1, float val2);\nGTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,\n                                    double val1, double val2);\n\n\n#if GTEST_OS_WINDOWS\n\n// Macros that test for HRESULT failure and success, these are only useful\n// on Windows, and rely on Windows SDK macros and APIs to compile.\n//\n//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)\n//\n// When expr unexpectedly fails or succeeds, Google Test prints the\n// expected result and the actual result with both a human-readable\n// string representation of the error, if available, as well as the\n// hex result code.\n# define EXPECT_HRESULT_SUCCEEDED(expr) \\\n    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n# define ASSERT_HRESULT_SUCCEEDED(expr) \\\n    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\n\n# define EXPECT_HRESULT_FAILED(expr) \\\n    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n# define ASSERT_HRESULT_FAILED(expr) \\\n    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\n\n#endif  // GTEST_OS_WINDOWS\n\n// Macros that execute statement and check that it doesn't generate new fatal\n// failures in the current thread.\n//\n//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);\n//\n// Examples:\n//\n//   EXPECT_NO_FATAL_FAILURE(Process());\n//   ASSERT_NO_FATAL_FAILURE(Process()) << \"Process() failed\";\n//\n#define ASSERT_NO_FATAL_FAILURE(statement) \\\n    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)\n#define EXPECT_NO_FATAL_FAILURE(statement) \\\n    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)\n\n// Causes a trace (including the source file path, the current line\n// number, and the given message) to be included in every test failure\n// message generated by code in the current scope.  The effect is\n// undone when the control leaves the current scope.\n//\n// The message argument can be anything streamable to std::ostream.\n//\n// In the implementation, we include the current line number as part\n// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s\n// to appear in the same block - as long as they are on different\n// lines.\n#define SCOPED_TRACE(message) \\\n  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\\\n    __FILE__, __LINE__, ::testing::Message() << (message))\n\n// Compile-time assertion for type equality.\n// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are\n// the same type.  The value it returns is not interesting.\n//\n// Instead of making StaticAssertTypeEq a class template, we make it a\n// function template that invokes a helper class template.  This\n// prevents a user from misusing StaticAssertTypeEq<T1, T2> by\n// defining objects of that type.\n//\n// CAVEAT:\n//\n// When used inside a method of a class template,\n// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is\n// instantiated.  For example, given:\n//\n//   template <typename T> class Foo {\n//    public:\n//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }\n//   };\n//\n// the code:\n//\n//   void Test1() { Foo<bool> foo; }\n//\n// will NOT generate a compiler error, as Foo<bool>::Bar() is never\n// actually instantiated.  Instead, you need:\n//\n//   void Test2() { Foo<bool> foo; foo.Bar(); }\n//\n// to cause a compiler error.\ntemplate <typename T1, typename T2>\nbool StaticAssertTypeEq() {\n  (void)internal::StaticAssertTypeEqHelper<T1, T2>();\n  return true;\n}\n\n// Defines a test.\n//\n// The first parameter is the name of the test case, and the second\n// parameter is the name of the test within the test case.\n//\n// The convention is to end the test case name with \"Test\".  For\n// example, a test case for the Foo class can be named FooTest.\n//\n// The user should put his test code between braces after using this\n// macro.  Example:\n//\n//   TEST(FooTest, InitializesCorrectly) {\n//     Foo foo;\n//     EXPECT_TRUE(foo.StatusIsOK());\n//   }\n\n// Note that we call GetTestTypeId() instead of GetTypeId<\n// ::testing::Test>() here to get the type ID of testing::Test.  This\n// is to work around a suspected linker bug when using Google Test as\n// a framework on Mac OS X.  The bug causes GetTypeId<\n// ::testing::Test>() to return different values depending on whether\n// the call is from the Google Test framework itself or from user test\n// code.  GetTestTypeId() is guaranteed to always return the same\n// value, as it always calls GetTypeId<>() from the Google Test\n// framework.\n#define GTEST_TEST(test_case_name, test_name)\\\n  GTEST_TEST_(test_case_name, test_name, \\\n              ::testing::Test, ::testing::internal::GetTestTypeId())\n\n// Define this macro to 1 to omit the definition of TEST(), which\n// is a generic name and clashes with some other libraries.\n#if !GTEST_DONT_DEFINE_TEST\n# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)\n#endif\n\n// Defines a test that uses a test fixture.\n//\n// The first parameter is the name of the test fixture class, which\n// also doubles as the test case name.  The second parameter is the\n// name of the test within the test case.\n//\n// A test fixture class must be declared earlier.  The user should put\n// his test code between braces after using this macro.  Example:\n//\n//   class FooTest : public testing::Test {\n//    protected:\n//     virtual void SetUp() { b_.AddElement(3); }\n//\n//     Foo a_;\n//     Foo b_;\n//   };\n//\n//   TEST_F(FooTest, InitializesCorrectly) {\n//     EXPECT_TRUE(a_.StatusIsOK());\n//   }\n//\n//   TEST_F(FooTest, ReturnsElementCountCorrectly) {\n//     EXPECT_EQ(0, a_.size());\n//     EXPECT_EQ(1, b_.size());\n//   }\n\n#define TEST_F(test_fixture, test_name)\\\n  GTEST_TEST_(test_fixture, test_name, test_fixture, \\\n              ::testing::internal::GetTypeId<test_fixture>())\n\n// Use this macro in main() to run all tests.  It returns 0 if all\n// tests are successful, or 1 otherwise.\n//\n// RUN_ALL_TESTS() should be invoked after the command line has been\n// parsed by InitGoogleTest().\n\n#define RUN_ALL_TESTS()\\\n  (::testing::UnitTest::GetInstance()->Run())\n\n}  // namespace testing\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_H_\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/gtest-1.6.0/gtest-all.cpp",
    "content": "// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: mheule@google.com (Markus Heule)\n//\n// Google C++ Testing Framework (Google Test)\n//\n// Sometimes it's desirable to build Google Test by compiling a single file.\n// This file serves this purpose.\n\n// This line ensures that gtest.h can be compiled on its own, even\n// when it's fused.\n#include \"gtest/gtest.h\"\n\n// The following lines pull in the real gtest *.cc files.\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// The Google C++ Testing Framework (Google Test)\n\n// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// Utilities for testing Google Test itself and code that uses Google Test\n// (e.g. frameworks built on top of Google Test).\n\n#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_\n#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_\n\n\nnamespace testing {\n\n// This helper class can be used to mock out Google Test failure reporting\n// so that we can test Google Test or code that builds on Google Test.\n//\n// An object of this class appends a TestPartResult object to the\n// TestPartResultArray object given in the constructor whenever a Google Test\n// failure is reported. It can either intercept only failures that are\n// generated in the same thread that created this object or it can intercept\n// all generated failures. The scope of this mock object can be controlled with\n// the second argument to the two arguments constructor.\nclass GTEST_API_ ScopedFakeTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  // The two possible mocking modes of this object.\n  enum InterceptMode {\n    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.\n    INTERCEPT_ALL_THREADS           // Intercepts all failures.\n  };\n\n  // The c'tor sets this object as the test part result reporter used\n  // by Google Test.  The 'result' parameter specifies where to report the\n  // results. This reporter will only catch failures generated in the current\n  // thread. DEPRECATED\n  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);\n\n  // Same as above, but you can choose the interception scope of this object.\n  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,\n                                   TestPartResultArray* result);\n\n  // The d'tor restores the previous test part result reporter.\n  virtual ~ScopedFakeTestPartResultReporter();\n\n  // Appends the TestPartResult object to the TestPartResultArray\n  // received in the constructor.\n  //\n  // This method is from the TestPartResultReporterInterface\n  // interface.\n  virtual void ReportTestPartResult(const TestPartResult& result);\n private:\n  void Init();\n\n  const InterceptMode intercept_mode_;\n  TestPartResultReporterInterface* old_reporter_;\n  TestPartResultArray* const result_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);\n};\n\nnamespace internal {\n\n// A helper class for implementing EXPECT_FATAL_FAILURE() and\n// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nclass GTEST_API_ SingleFailureChecker {\n public:\n  // The constructor remembers the arguments.\n  SingleFailureChecker(const TestPartResultArray* results,\n                       TestPartResult::Type type,\n                       const string& substr);\n  ~SingleFailureChecker();\n private:\n  const TestPartResultArray* const results_;\n  const TestPartResult::Type type_;\n  const string substr_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);\n};\n\n}  // namespace internal\n\n}  // namespace testing\n\n// A set of macros for testing Google Test assertions or code that's expected\n// to generate Google Test fatal failures.  It verifies that the given\n// statement will cause exactly one fatal Google Test failure with 'substr'\n// being part of the failure message.\n//\n// There are two different versions of this macro. EXPECT_FATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - 'statement' cannot reference local non-static variables or\n//     non-static members of the current object.\n//   - 'statement' cannot return a value.\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in\n// gtest_unittest.cc will fail to compile if we do that.\n#define EXPECT_FATAL_FAILURE(statement, substr) \\\n  do { \\\n    class GTestExpectFatalFailureHelper {\\\n     public:\\\n      static void Execute() { statement; }\\\n    };\\\n    ::testing::TestPartResultArray gtest_failures;\\\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\\\n    {\\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\n          ::testing::ScopedFakeTestPartResultReporter:: \\\n          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\\\n      GTestExpectFatalFailureHelper::Execute();\\\n    }\\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \\\n  do { \\\n    class GTestExpectFatalFailureHelper {\\\n     public:\\\n      static void Execute() { statement; }\\\n    };\\\n    ::testing::TestPartResultArray gtest_failures;\\\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\\\n    {\\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\n          ::testing::ScopedFakeTestPartResultReporter:: \\\n          INTERCEPT_ALL_THREADS, &gtest_failures);\\\n      GTestExpectFatalFailureHelper::Execute();\\\n    }\\\n  } while (::testing::internal::AlwaysFalse())\n\n// A macro for testing Google Test assertions or code that's expected to\n// generate Google Test non-fatal failures.  It asserts that the given\n// statement will cause exactly one non-fatal Google Test failure with 'substr'\n// being part of the failure message.\n//\n// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only\n// affects and considers failures generated in the current thread and\n// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\n//\n// 'statement' is allowed to reference local variables and members of\n// the current object.\n//\n// The verification of the assertion is done correctly even when the statement\n// throws an exception or aborts the current function.\n//\n// Known restrictions:\n//   - You cannot stream a failure message to this macro.\n//\n// Note that even though the implementations of the following two\n// macros are much alike, we cannot refactor them to use a common\n// helper macro, due to some peculiarity in how the preprocessor\n// works.  If we do that, the code won't compile when the user gives\n// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that\n// expands to code containing an unprotected comma.  The\n// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc\n// catches that.\n//\n// For the same reason, we have to write\n//   if (::testing::internal::AlwaysTrue()) { statement; }\n// instead of\n//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\n// to avoid an MSVC warning on unreachable code.\n#define EXPECT_NONFATAL_FAILURE(statement, substr) \\\n  do {\\\n    ::testing::TestPartResultArray gtest_failures;\\\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\n        (substr));\\\n    {\\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\n          ::testing::ScopedFakeTestPartResultReporter:: \\\n          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\\\n      if (::testing::internal::AlwaysTrue()) { statement; }\\\n    }\\\n  } while (::testing::internal::AlwaysFalse())\n\n#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \\\n  do {\\\n    ::testing::TestPartResultArray gtest_failures;\\\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\n        (substr));\\\n    {\\\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\\\n          &gtest_failures);\\\n      if (::testing::internal::AlwaysTrue()) { statement; }\\\n    }\\\n  } while (::testing::internal::AlwaysFalse())\n\n#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_\n\n#include <ctype.h>\n#include <math.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <wchar.h>\n#include <wctype.h>\n\n#include <algorithm>\n#include <ostream>  // NOLINT\n#include <sstream>\n#include <vector>\n\n#if GTEST_OS_LINUX\n\n// TODO(kenton@google.com): Use autoconf to detect availability of\n// gettimeofday().\n# define GTEST_HAS_GETTIMEOFDAY_ 1\n\n# include <fcntl.h>  // NOLINT\n# include <limits.h>  // NOLINT\n# include <sched.h>  // NOLINT\n// Declares vsnprintf().  This header is not available on Windows.\n# include <strings.h>  // NOLINT\n# include <sys/mman.h>  // NOLINT\n# include <sys/time.h>  // NOLINT\n# include <unistd.h>  // NOLINT\n# include <string>\n\n#elif GTEST_OS_SYMBIAN\n# define GTEST_HAS_GETTIMEOFDAY_ 1\n# include <sys/time.h>  // NOLINT\n\n#elif GTEST_OS_ZOS\n# define GTEST_HAS_GETTIMEOFDAY_ 1\n# include <sys/time.h>  // NOLINT\n\n// On z/OS we additionally need strings.h for strcasecmp.\n# include <strings.h>  // NOLINT\n\n#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.\n\n# include <windows.h>  // NOLINT\n\n#elif GTEST_OS_WINDOWS  // We are on Windows proper.\n\n# include <io.h>  // NOLINT\n# include <sys/timeb.h>  // NOLINT\n# include <sys/types.h>  // NOLINT\n# include <sys/stat.h>  // NOLINT\n\n# if GTEST_OS_WINDOWS_MINGW\n// MinGW has gettimeofday() but not _ftime64().\n// TODO(kenton@google.com): Use autoconf to detect availability of\n//   gettimeofday().\n// TODO(kenton@google.com): There are other ways to get the time on\n//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW\n//   supports these.  consider using them instead.\n#  define GTEST_HAS_GETTIMEOFDAY_ 1\n#  include <sys/time.h>  // NOLINT\n# endif  // GTEST_OS_WINDOWS_MINGW\n\n// cpplint thinks that the header is already included, so we want to\n// silence it.\n# include <windows.h>  // NOLINT\n\n#else\n\n// Assume other platforms have gettimeofday().\n// TODO(kenton@google.com): Use autoconf to detect availability of\n//   gettimeofday().\n# define GTEST_HAS_GETTIMEOFDAY_ 1\n\n// cpplint thinks that the header is already included, so we want to\n// silence it.\n# include <sys/time.h>  // NOLINT\n# include <unistd.h>  // NOLINT\n\n#endif  // GTEST_OS_LINUX\n\n#if GTEST_HAS_EXCEPTIONS\n# include <stdexcept>\n#endif\n\n#if GTEST_CAN_STREAM_RESULTS_\n# include <arpa/inet.h>  // NOLINT\n# include <netdb.h>  // NOLINT\n#endif\n\n// Indicates that this translation unit is part of Google Test's\n// implementation.  It must come before gtest-internal-inl.h is\n// included, or there will be a compiler error.  This trick is to\n// prevent a user from accidentally including gtest-internal-inl.h in\n// his code.\n#define GTEST_IMPLEMENTATION_ 1\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Utility functions and classes used by the Google C++ testing framework.\n//\n// Author: wan@google.com (Zhanyong Wan)\n//\n// This file contains purely Google Test's internal implementation.  Please\n// DO NOT #INCLUDE IT IN A USER PROGRAM.\n\n#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_\n#define GTEST_SRC_GTEST_INTERNAL_INL_H_\n\n// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is\n// part of Google Test's implementation; otherwise it's undefined.\n#if !GTEST_IMPLEMENTATION_\n// A user is trying to include this from his code - just say no.\n# error \"gtest-internal-inl.h is part of Google Test's internal implementation.\"\n# error \"It must not be included except by Google Test itself.\"\n#endif  // GTEST_IMPLEMENTATION_\n\n#ifndef _WIN32_WCE\n# include <errno.h>\n#endif  // !_WIN32_WCE\n#include <stddef.h>\n#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.\n#include <string.h>  // For memmove.\n\n#include <algorithm>\n#include <string>\n#include <vector>\n\n\n#if GTEST_OS_WINDOWS\n# include <windows.h>  // NOLINT\n#endif  // GTEST_OS_WINDOWS\n\n\nnamespace testing {\n\n// Declares the flags.\n//\n// We don't want the users to modify this flag in the code, but want\n// Google Test's own unit tests to be able to access it. Therefore we\n// declare it here as opposed to in gtest.h.\nGTEST_DECLARE_bool_(death_test_use_fork);\n\nnamespace internal {\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nGTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;\n\n// Names of the flags (needed for parsing Google Test flags).\nconst char kAlsoRunDisabledTestsFlag[] = \"also_run_disabled_tests\";\nconst char kBreakOnFailureFlag[] = \"break_on_failure\";\nconst char kCatchExceptionsFlag[] = \"catch_exceptions\";\nconst char kColorFlag[] = \"color\";\nconst char kFilterFlag[] = \"filter\";\nconst char kListTestsFlag[] = \"list_tests\";\nconst char kOutputFlag[] = \"output\";\nconst char kPrintTimeFlag[] = \"print_time\";\nconst char kRandomSeedFlag[] = \"random_seed\";\nconst char kRepeatFlag[] = \"repeat\";\nconst char kShuffleFlag[] = \"shuffle\";\nconst char kStackTraceDepthFlag[] = \"stack_trace_depth\";\nconst char kStreamResultToFlag[] = \"stream_result_to\";\nconst char kThrowOnFailureFlag[] = \"throw_on_failure\";\n\n// A valid random seed must be in [1, kMaxRandomSeed].\nconst int kMaxRandomSeed = 99999;\n\n// g_help_flag is true iff the --help flag or an equivalent form is\n// specified on the command line.\nGTEST_API_ extern bool g_help_flag;\n\n// Returns the current time in milliseconds.\nGTEST_API_ TimeInMillis GetTimeInMillis();\n\n// Returns true iff Google Test should use colors in the output.\nGTEST_API_ bool ShouldUseColor(bool stdout_is_tty);\n\n// Formats the given time in milliseconds as seconds.\nGTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);\n\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nGTEST_API_ bool ParseInt32Flag(\n    const char* str, const char* flag, Int32* value);\n\n// Returns a random seed in range [1, kMaxRandomSeed] based on the\n// given --gtest_random_seed flag value.\ninline int GetRandomSeedFromFlag(Int32 random_seed_flag) {\n  const unsigned int raw_seed = (random_seed_flag == 0) ?\n      static_cast<unsigned int>(GetTimeInMillis()) :\n      static_cast<unsigned int>(random_seed_flag);\n\n  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that\n  // it's easy to type.\n  const int normalized_seed =\n      static_cast<int>((raw_seed - 1U) %\n                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;\n  return normalized_seed;\n}\n\n// Returns the first valid random seed after 'seed'.  The behavior is\n// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is\n// considered to be 1.\ninline int GetNextRandomSeed(int seed) {\n  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)\n      << \"Invalid random seed \" << seed << \" - must be in [1, \"\n      << kMaxRandomSeed << \"].\";\n  const int next_seed = seed + 1;\n  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;\n}\n\n// This class saves the values of all Google Test flags in its c'tor, and\n// restores them in its d'tor.\nclass GTestFlagSaver {\n public:\n  // The c'tor.\n  GTestFlagSaver() {\n    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);\n    break_on_failure_ = GTEST_FLAG(break_on_failure);\n    catch_exceptions_ = GTEST_FLAG(catch_exceptions);\n    color_ = GTEST_FLAG(color);\n    death_test_style_ = GTEST_FLAG(death_test_style);\n    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);\n    filter_ = GTEST_FLAG(filter);\n    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);\n    list_tests_ = GTEST_FLAG(list_tests);\n    output_ = GTEST_FLAG(output);\n    print_time_ = GTEST_FLAG(print_time);\n    random_seed_ = GTEST_FLAG(random_seed);\n    repeat_ = GTEST_FLAG(repeat);\n    shuffle_ = GTEST_FLAG(shuffle);\n    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);\n    stream_result_to_ = GTEST_FLAG(stream_result_to);\n    throw_on_failure_ = GTEST_FLAG(throw_on_failure);\n  }\n\n  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.\n  ~GTestFlagSaver() {\n    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;\n    GTEST_FLAG(break_on_failure) = break_on_failure_;\n    GTEST_FLAG(catch_exceptions) = catch_exceptions_;\n    GTEST_FLAG(color) = color_;\n    GTEST_FLAG(death_test_style) = death_test_style_;\n    GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;\n    GTEST_FLAG(filter) = filter_;\n    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;\n    GTEST_FLAG(list_tests) = list_tests_;\n    GTEST_FLAG(output) = output_;\n    GTEST_FLAG(print_time) = print_time_;\n    GTEST_FLAG(random_seed) = random_seed_;\n    GTEST_FLAG(repeat) = repeat_;\n    GTEST_FLAG(shuffle) = shuffle_;\n    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;\n    GTEST_FLAG(stream_result_to) = stream_result_to_;\n    GTEST_FLAG(throw_on_failure) = throw_on_failure_;\n  }\n private:\n  // Fields for saving the original values of flags.\n  bool also_run_disabled_tests_;\n  bool break_on_failure_;\n  bool catch_exceptions_;\n  String color_;\n  String death_test_style_;\n  bool death_test_use_fork_;\n  String filter_;\n  String internal_run_death_test_;\n  bool list_tests_;\n  String output_;\n  bool print_time_;\n  bool pretty_;\n  internal::Int32 random_seed_;\n  internal::Int32 repeat_;\n  bool shuffle_;\n  internal::Int32 stack_trace_depth_;\n  String stream_result_to_;\n  bool throw_on_failure_;\n} GTEST_ATTRIBUTE_UNUSED_;\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type UInt32 because wchar_t may not be\n// wide enough to contain a code point.\n// The output buffer str must containt at least 32 characters.\n// The function returns the address of the output buffer.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'.\nGTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nGTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);\n\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded();\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (e.g., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nGTEST_API_ bool ShouldShard(const char* total_shards_str,\n                            const char* shard_index_str,\n                            bool in_subprocess_for_death_test);\n\n// Parses the environment variable var as an Int32. If it is unset,\n// returns default_val. If it is not an Int32, prints an error and\n// and aborts.\nGTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true iff the test should be run on this shard. The test id is\n// some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nGTEST_API_ bool ShouldRunTestOnShard(\n    int total_shards, int shard_index, int test_id);\n\n// STL container utilities.\n\n// Returns the number of elements in the given container that satisfy\n// the given predicate.\ntemplate <class Container, typename Predicate>\ninline int CountIf(const Container& c, Predicate predicate) {\n  // Implemented as an explicit loop since std::count_if() in libCstd on\n  // Solaris has a non-standard signature.\n  int count = 0;\n  for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {\n    if (predicate(*it))\n      ++count;\n  }\n  return count;\n}\n\n// Applies a function/functor to each element in the container.\ntemplate <class Container, typename Functor>\nvoid ForEach(const Container& c, Functor functor) {\n  std::for_each(c.begin(), c.end(), functor);\n}\n\n// Returns the i-th element of the vector, or default_value if i is not\n// in range [0, v.size()).\ntemplate <typename E>\ninline E GetElementOr(const std::vector<E>& v, int i, E default_value) {\n  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];\n}\n\n// Performs an in-place shuffle of a range of the vector's elements.\n// 'begin' and 'end' are element indices as an STL-style range;\n// i.e. [begin, end) are shuffled, where 'end' == size() means to\n// shuffle to the end of the vector.\ntemplate <typename E>\nvoid ShuffleRange(internal::Random* random, int begin, int end,\n                  std::vector<E>* v) {\n  const int size = static_cast<int>(v->size());\n  GTEST_CHECK_(0 <= begin && begin <= size)\n      << \"Invalid shuffle range start \" << begin << \": must be in range [0, \"\n      << size << \"].\";\n  GTEST_CHECK_(begin <= end && end <= size)\n      << \"Invalid shuffle range finish \" << end << \": must be in range [\"\n      << begin << \", \" << size << \"].\";\n\n  // Fisher-Yates shuffle, from\n  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle\n  for (int range_width = end - begin; range_width >= 2; range_width--) {\n    const int last_in_range = begin + range_width - 1;\n    const int selected = begin + random->Generate(range_width);\n    std::swap((*v)[selected], (*v)[last_in_range]);\n  }\n}\n\n// Performs an in-place shuffle of the vector's elements.\ntemplate <typename E>\ninline void Shuffle(internal::Random* random, std::vector<E>* v) {\n  ShuffleRange(random, 0, static_cast<int>(v->size()), v);\n}\n\n// A function for deleting an object.  Handy for being used as a\n// functor.\ntemplate <typename T>\nstatic void Delete(T* x) {\n  delete x;\n}\n\n// A predicate that checks the key of a TestProperty against a known key.\n//\n// TestPropertyKeyIs is copyable.\nclass TestPropertyKeyIs {\n public:\n  // Constructor.\n  //\n  // TestPropertyKeyIs has NO default constructor.\n  explicit TestPropertyKeyIs(const char* key)\n      : key_(key) {}\n\n  // Returns true iff the test name of test property matches on key_.\n  bool operator()(const TestProperty& test_property) const {\n    return String(test_property.key()).Compare(key_) == 0;\n  }\n\n private:\n  String key_;\n};\n\n// Class UnitTestOptions.\n//\n// This class contains functions for processing options the user\n// specifies when running the tests.  It has only static members.\n//\n// In most cases, the user can specify an option using either an\n// environment variable or a command line flag.  E.g. you can set the\n// test filter using either GTEST_FILTER or --gtest_filter.  If both\n// the variable and the flag are present, the latter overrides the\n// former.\nclass GTEST_API_ UnitTestOptions {\n public:\n  // Functions for processing the gtest_output flag.\n\n  // Returns the output format, or \"\" for normal printed output.\n  static String GetOutputFormat();\n\n  // Returns the absolute path of the requested output file, or the\n  // default (test_detail.xml in the original working directory) if\n  // none was explicitly specified.\n  static String GetAbsolutePathToOutputFile();\n\n  // Functions for processing the gtest_filter flag.\n\n  // Returns true iff the wildcard pattern matches the string.  The\n  // first ':' or '\\0' character in pattern marks the end of it.\n  //\n  // This recursive algorithm isn't very efficient, but is clear and\n  // works well enough for matching test names, which are short.\n  static bool PatternMatchesString(const char *pattern, const char *str);\n\n  // Returns true iff the user-specified filter matches the test case\n  // name and the test name.\n  static bool FilterMatchesTest(const String &test_case_name,\n                                const String &test_name);\n\n#if GTEST_OS_WINDOWS\n  // Function for supporting the gtest_catch_exception flag.\n\n  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the\n  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.\n  // This function is useful as an __except condition.\n  static int GTestShouldProcessSEH(DWORD exception_code);\n#endif  // GTEST_OS_WINDOWS\n\n  // Returns true if \"name\" matches the ':' separated list of glob-style\n  // filters in \"filter\".\n  static bool MatchesFilter(const String& name, const char* filter);\n};\n\n// Returns the current application's name, removing directory path if that\n// is present.  Used by UnitTestOptions::GetOutputFile.\nGTEST_API_ FilePath GetCurrentExecutableName();\n\n// The role interface for getting the OS stack trace as a string.\nclass OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetterInterface() {}\n  virtual ~OsStackTraceGetterInterface() {}\n\n  // Returns the current OS stack trace as a String.  Parameters:\n  //\n  //   max_depth  - the maximum number of stack frames to be included\n  //                in the trace.\n  //   skip_count - the number of top frames to be skipped; doesn't count\n  //                against max_depth.\n  virtual String CurrentStackTrace(int max_depth, int skip_count) = 0;\n\n  // UponLeavingGTest() should be called immediately before Google Test calls\n  // user code. It saves some information about the current stack that\n  // CurrentStackTrace() will use to find and hide Google Test stack frames.\n  virtual void UponLeavingGTest() = 0;\n\n private:\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);\n};\n\n// A working implementation of the OsStackTraceGetterInterface interface.\nclass OsStackTraceGetter : public OsStackTraceGetterInterface {\n public:\n  OsStackTraceGetter() : caller_frame_(NULL) {}\n  virtual String CurrentStackTrace(int max_depth, int skip_count);\n  virtual void UponLeavingGTest();\n\n  // This string is inserted in place of stack frames that are part of\n  // Google Test's implementation.\n  static const char* const kElidedFramesMarker;\n\n private:\n  Mutex mutex_;  // protects all internal state\n\n  // We save the stack frame below the frame that calls user code.\n  // We do this because the address of the frame immediately below\n  // the user code changes between the call to UponLeavingGTest()\n  // and any calls to CurrentStackTrace() from within the user code.\n  void* caller_frame_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);\n};\n\n// Information about a Google Test trace point.\nstruct TraceInfo {\n  const char* file;\n  int line;\n  String message;\n};\n\n// This is the default global test part result reporter used in UnitTestImpl.\n// This class should only be used by UnitTestImpl.\nclass DefaultGlobalTestPartResultReporter\n  : public TestPartResultReporterInterface {\n public:\n  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. Reports the test part\n  // result in the current test.\n  virtual void ReportTestPartResult(const TestPartResult& result);\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);\n};\n\n// This is the default per thread test part result reporter used in\n// UnitTestImpl. This class should only be used by UnitTestImpl.\nclass DefaultPerThreadTestPartResultReporter\n    : public TestPartResultReporterInterface {\n public:\n  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);\n  // Implements the TestPartResultReporterInterface. The implementation just\n  // delegates to the current global test part result reporter of *unit_test_.\n  virtual void ReportTestPartResult(const TestPartResult& result);\n\n private:\n  UnitTestImpl* const unit_test_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);\n};\n\n// The private implementation of the UnitTest class.  We don't protect\n// the methods under a mutex, as this class is not accessible by a\n// user and the UnitTest class that delegates work to this class does\n// proper locking.\nclass GTEST_API_ UnitTestImpl {\n public:\n  explicit UnitTestImpl(UnitTest* parent);\n  virtual ~UnitTestImpl();\n\n  // There are two different ways to register your own TestPartResultReporter.\n  // You can register your own repoter to listen either only for test results\n  // from the current thread or for results from all threads.\n  // By default, each per-thread test result repoter just passes a new\n  // TestPartResult to the global test result reporter, which registers the\n  // test part result for the currently running test.\n\n  // Returns the global test part result reporter.\n  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();\n\n  // Sets the global test part result reporter.\n  void SetGlobalTestPartResultReporter(\n      TestPartResultReporterInterface* reporter);\n\n  // Returns the test part result reporter for the current thread.\n  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();\n\n  // Sets the test part result reporter for the current thread.\n  void SetTestPartResultReporterForCurrentThread(\n      TestPartResultReporterInterface* reporter);\n\n  // Gets the number of successful test cases.\n  int successful_test_case_count() const;\n\n  // Gets the number of failed test cases.\n  int failed_test_case_count() const;\n\n  // Gets the number of all test cases.\n  int total_test_case_count() const;\n\n  // Gets the number of all test cases that contain at least one test\n  // that should run.\n  int test_case_to_run_count() const;\n\n  // Gets the number of successful tests.\n  int successful_test_count() const;\n\n  // Gets the number of failed tests.\n  int failed_test_count() const;\n\n  // Gets the number of disabled tests.\n  int disabled_test_count() const;\n\n  // Gets the number of all tests.\n  int total_test_count() const;\n\n  // Gets the number of tests that should run.\n  int test_to_run_count() const;\n\n  // Gets the elapsed time, in milliseconds.\n  TimeInMillis elapsed_time() const { return elapsed_time_; }\n\n  // Returns true iff the unit test passed (i.e. all test cases passed).\n  bool Passed() const { return !Failed(); }\n\n  // Returns true iff the unit test failed (i.e. some test case failed\n  // or something outside of all tests failed).\n  bool Failed() const {\n    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();\n  }\n\n  // Gets the i-th test case among all the test cases. i can range from 0 to\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\n  const TestCase* GetTestCase(int i) const {\n    const int index = GetElementOr(test_case_indices_, i, -1);\n    return index < 0 ? NULL : test_cases_[i];\n  }\n\n  // Gets the i-th test case among all the test cases. i can range from 0 to\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\n  TestCase* GetMutableTestCase(int i) {\n    const int index = GetElementOr(test_case_indices_, i, -1);\n    return index < 0 ? NULL : test_cases_[index];\n  }\n\n  // Provides access to the event listener list.\n  TestEventListeners* listeners() { return &listeners_; }\n\n  // Returns the TestResult for the test that's currently running, or\n  // the TestResult for the ad hoc test if no test is running.\n  TestResult* current_test_result();\n\n  // Returns the TestResult for the ad hoc test.\n  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }\n\n  // Sets the OS stack trace getter.\n  //\n  // Does nothing if the input and the current OS stack trace getter\n  // are the same; otherwise, deletes the old getter and makes the\n  // input the current getter.\n  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);\n\n  // Returns the current OS stack trace getter if it is not NULL;\n  // otherwise, creates an OsStackTraceGetter, makes it the current\n  // getter, and returns it.\n  OsStackTraceGetterInterface* os_stack_trace_getter();\n\n  // Returns the current OS stack trace as a String.\n  //\n  // The maximum number of stack frames to be included is specified by\n  // the gtest_stack_trace_depth flag.  The skip_count parameter\n  // specifies the number of top frames to be skipped, which doesn't\n  // count against the number of frames to be included.\n  //\n  // For example, if Foo() calls Bar(), which in turn calls\n  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.\n  String CurrentOsStackTraceExceptTop(int skip_count);\n\n  // Finds and returns a TestCase with the given name.  If one doesn't\n  // exist, creates one and returns it.\n  //\n  // Arguments:\n  //\n  //   test_case_name: name of the test case\n  //   type_param:     the name of the test's type parameter, or NULL if\n  //                   this is not a typed or a type-parameterized test.\n  //   set_up_tc:      pointer to the function that sets up the test case\n  //   tear_down_tc:   pointer to the function that tears down the test case\n  TestCase* GetTestCase(const char* test_case_name,\n                        const char* type_param,\n                        Test::SetUpTestCaseFunc set_up_tc,\n                        Test::TearDownTestCaseFunc tear_down_tc);\n\n  // Adds a TestInfo to the unit test.\n  //\n  // Arguments:\n  //\n  //   set_up_tc:    pointer to the function that sets up the test case\n  //   tear_down_tc: pointer to the function that tears down the test case\n  //   test_info:    the TestInfo object\n  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,\n                   Test::TearDownTestCaseFunc tear_down_tc,\n                   TestInfo* test_info) {\n    // In order to support thread-safe death tests, we need to\n    // remember the original working directory when the test program\n    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as\n    // the user may have changed the current directory before calling\n    // RUN_ALL_TESTS().  Therefore we capture the current directory in\n    // AddTestInfo(), which is called to register a TEST or TEST_F\n    // before main() is reached.\n    if (original_working_dir_.IsEmpty()) {\n      original_working_dir_.Set(FilePath::GetCurrentDir());\n      GTEST_CHECK_(!original_working_dir_.IsEmpty())\n          << \"Failed to get the current working directory.\";\n    }\n\n    GetTestCase(test_info->test_case_name(),\n                test_info->type_param(),\n                set_up_tc,\n                tear_down_tc)->AddTestInfo(test_info);\n  }\n\n#if GTEST_HAS_PARAM_TEST\n  // Returns ParameterizedTestCaseRegistry object used to keep track of\n  // value-parameterized tests and instantiate and register them.\n  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {\n    return parameterized_test_registry_;\n  }\n#endif  // GTEST_HAS_PARAM_TEST\n\n  // Sets the TestCase object for the test that's currently running.\n  void set_current_test_case(TestCase* a_current_test_case) {\n    current_test_case_ = a_current_test_case;\n  }\n\n  // Sets the TestInfo object for the test that's currently running.  If\n  // current_test_info is NULL, the assertion results will be stored in\n  // ad_hoc_test_result_.\n  void set_current_test_info(TestInfo* a_current_test_info) {\n    current_test_info_ = a_current_test_info;\n  }\n\n  // Registers all parameterized tests defined using TEST_P and\n  // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter\n  // combination. This method can be called more then once; it has guards\n  // protecting from registering the tests more then once.  If\n  // value-parameterized tests are disabled, RegisterParameterizedTests is\n  // present but does nothing.\n  void RegisterParameterizedTests();\n\n  // Runs all tests in this UnitTest object, prints the result, and\n  // returns true if all tests are successful.  If any exception is\n  // thrown during a test, this test is considered to be failed, but\n  // the rest of the tests will still be run.\n  bool RunAllTests();\n\n  // Clears the results of all tests, except the ad hoc tests.\n  void ClearNonAdHocTestResult() {\n    ForEach(test_cases_, TestCase::ClearTestCaseResult);\n  }\n\n  // Clears the results of ad-hoc test assertions.\n  void ClearAdHocTestResult() {\n    ad_hoc_test_result_.Clear();\n  }\n\n  enum ReactionToSharding {\n    HONOR_SHARDING_PROTOCOL,\n    IGNORE_SHARDING_PROTOCOL\n  };\n\n  // Matches the full name of each test against the user-specified\n  // filter to decide whether the test should run, then records the\n  // result in each TestCase and TestInfo object.\n  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests\n  // based on sharding variables in the environment.\n  // Returns the number of tests that should run.\n  int FilterTests(ReactionToSharding shard_tests);\n\n  // Prints the names of the tests matching the user-specified filter flag.\n  void ListTestsMatchingFilter();\n\n  const TestCase* current_test_case() const { return current_test_case_; }\n  TestInfo* current_test_info() { return current_test_info_; }\n  const TestInfo* current_test_info() const { return current_test_info_; }\n\n  // Returns the vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*>& environments() { return environments_; }\n\n  // Getters for the per-thread Google Test trace stack.\n  std::vector<TraceInfo>& gtest_trace_stack() {\n    return *(gtest_trace_stack_.pointer());\n  }\n  const std::vector<TraceInfo>& gtest_trace_stack() const {\n    return gtest_trace_stack_.get();\n  }\n\n#if GTEST_HAS_DEATH_TEST\n  void InitDeathTestSubprocessControlInfo() {\n    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());\n  }\n  // Returns a pointer to the parsed --gtest_internal_run_death_test\n  // flag, or NULL if that flag was not specified.\n  // This information is useful only in a death test child process.\n  // Must not be called before a call to InitGoogleTest.\n  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {\n    return internal_run_death_test_flag_.get();\n  }\n\n  // Returns a pointer to the current death test factory.\n  internal::DeathTestFactory* death_test_factory() {\n    return death_test_factory_.get();\n  }\n\n  void SuppressTestEventsIfInSubprocess();\n\n  friend class ReplaceDeathTestFactory;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // Initializes the event listener performing XML output as specified by\n  // UnitTestOptions. Must not be called before InitGoogleTest.\n  void ConfigureXmlOutput();\n\n#if GTEST_CAN_STREAM_RESULTS_\n  // Initializes the event listener for streaming test results to a socket.\n  // Must not be called before InitGoogleTest.\n  void ConfigureStreamingOutput();\n#endif\n\n  // Performs initialization dependent upon flag values obtained in\n  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n  // this function is also called from RunAllTests.  Since this function can be\n  // called more than once, it has to be idempotent.\n  void PostFlagParsingInit();\n\n  // Gets the random seed used at the start of the current test iteration.\n  int random_seed() const { return random_seed_; }\n\n  // Gets the random number generator.\n  internal::Random* random() { return &random_; }\n\n  // Shuffles all test cases, and the tests within each test case,\n  // making sure that death tests are still run first.\n  void ShuffleTests();\n\n  // Restores the test cases and tests to their order before the first shuffle.\n  void UnshuffleTests();\n\n  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment\n  // UnitTest::Run() starts.\n  bool catch_exceptions() const { return catch_exceptions_; }\n\n private:\n  friend class ::testing::UnitTest;\n\n  // Used by UnitTest::Run() to capture the state of\n  // GTEST_FLAG(catch_exceptions) at the moment it starts.\n  void set_catch_exceptions(bool value) { catch_exceptions_ = value; }\n\n  // The UnitTest object that owns this implementation object.\n  UnitTest* const parent_;\n\n  // The working directory when the first TEST() or TEST_F() was\n  // executed.\n  internal::FilePath original_working_dir_;\n\n  // The default test part result reporters.\n  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;\n  DefaultPerThreadTestPartResultReporter\n      default_per_thread_test_part_result_reporter_;\n\n  // Points to (but doesn't own) the global test part result reporter.\n  TestPartResultReporterInterface* global_test_part_result_repoter_;\n\n  // Protects read and write access to global_test_part_result_reporter_.\n  internal::Mutex global_test_part_result_reporter_mutex_;\n\n  // Points to (but doesn't own) the per-thread test part result reporter.\n  internal::ThreadLocal<TestPartResultReporterInterface*>\n      per_thread_test_part_result_reporter_;\n\n  // The vector of environments that need to be set-up/torn-down\n  // before/after the tests are run.\n  std::vector<Environment*> environments_;\n\n  // The vector of TestCases in their original order.  It owns the\n  // elements in the vector.\n  std::vector<TestCase*> test_cases_;\n\n  // Provides a level of indirection for the test case list to allow\n  // easy shuffling and restoring the test case order.  The i-th\n  // element of this vector is the index of the i-th test case in the\n  // shuffled order.\n  std::vector<int> test_case_indices_;\n\n#if GTEST_HAS_PARAM_TEST\n  // ParameterizedTestRegistry object used to register value-parameterized\n  // tests.\n  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;\n\n  // Indicates whether RegisterParameterizedTests() has been called already.\n  bool parameterized_tests_registered_;\n#endif  // GTEST_HAS_PARAM_TEST\n\n  // Index of the last death test case registered.  Initially -1.\n  int last_death_test_case_;\n\n  // This points to the TestCase for the currently running test.  It\n  // changes as Google Test goes through one test case after another.\n  // When no test is running, this is set to NULL and Google Test\n  // stores assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestCase* current_test_case_;\n\n  // This points to the TestInfo for the currently running test.  It\n  // changes as Google Test goes through one test after another.  When\n  // no test is running, this is set to NULL and Google Test stores\n  // assertion results in ad_hoc_test_result_.  Initially NULL.\n  TestInfo* current_test_info_;\n\n  // Normally, a user only writes assertions inside a TEST or TEST_F,\n  // or inside a function called by a TEST or TEST_F.  Since Google\n  // Test keeps track of which test is current running, it can\n  // associate such an assertion with the test it belongs to.\n  //\n  // If an assertion is encountered when no TEST or TEST_F is running,\n  // Google Test attributes the assertion result to an imaginary \"ad hoc\"\n  // test, and records the result in ad_hoc_test_result_.\n  TestResult ad_hoc_test_result_;\n\n  // The list of event listeners that can be used to track events inside\n  // Google Test.\n  TestEventListeners listeners_;\n\n  // The OS stack trace getter.  Will be deleted when the UnitTest\n  // object is destructed.  By default, an OsStackTraceGetter is used,\n  // but the user can set this field to use a custom getter if that is\n  // desired.\n  OsStackTraceGetterInterface* os_stack_trace_getter_;\n\n  // True iff PostFlagParsingInit() has been called.\n  bool post_flag_parse_init_performed_;\n\n  // The random number seed used at the beginning of the test run.\n  int random_seed_;\n\n  // Our random number generator.\n  internal::Random random_;\n\n  // How long the test took to run, in milliseconds.\n  TimeInMillis elapsed_time_;\n\n#if GTEST_HAS_DEATH_TEST\n  // The decomposed components of the gtest_internal_run_death_test flag,\n  // parsed when RUN_ALL_TESTS is called.\n  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;\n  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;\n#endif  // GTEST_HAS_DEATH_TEST\n\n  // A per-thread stack of traces created by the SCOPED_TRACE() macro.\n  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;\n\n  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()\n  // starts.\n  bool catch_exceptions_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);\n};  // class UnitTestImpl\n\n// Convenience function for accessing the global UnitTest\n// implementation object.\ninline UnitTestImpl* GetUnitTestImpl() {\n  return UnitTest::GetInstance()->impl();\n}\n\n#if GTEST_USES_SIMPLE_RE\n\n// Internal helper functions for implementing the simple regular\n// expression matcher.\nGTEST_API_ bool IsInSet(char ch, const char* str);\nGTEST_API_ bool IsAsciiDigit(char ch);\nGTEST_API_ bool IsAsciiPunct(char ch);\nGTEST_API_ bool IsRepeat(char ch);\nGTEST_API_ bool IsAsciiWhiteSpace(char ch);\nGTEST_API_ bool IsAsciiWordChar(char ch);\nGTEST_API_ bool IsValidEscape(char ch);\nGTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);\nGTEST_API_ bool ValidateRegex(const char* regex);\nGTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);\nGTEST_API_ bool MatchRepetitionAndRegexAtHead(\n    bool escaped, char ch, char repeat, const char* regex, const char* str);\nGTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);\n\n#endif  // GTEST_USES_SIMPLE_RE\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);\n\n#if GTEST_HAS_DEATH_TEST\n\n// Returns the message describing the last system error, regardless of the\n// platform.\nGTEST_API_ String GetLastErrnoDescription();\n\n# if GTEST_OS_WINDOWS\n// Provides leak-safe Windows kernel handle ownership.\nclass AutoHandle {\n public:\n  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}\n  explicit AutoHandle(HANDLE handle) : handle_(handle) {}\n\n  ~AutoHandle() { Reset(); }\n\n  HANDLE Get() const { return handle_; }\n  void Reset() { Reset(INVALID_HANDLE_VALUE); }\n  void Reset(HANDLE handle) {\n    if (handle != handle_) {\n      if (handle_ != INVALID_HANDLE_VALUE)\n        ::CloseHandle(handle_);\n      handle_ = handle;\n    }\n  }\n\n private:\n  HANDLE handle_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);\n};\n# endif  // GTEST_OS_WINDOWS\n\n// Attempts to parse a string into a positive integer pointed to by the\n// number parameter.  Returns true if that is possible.\n// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use\n// it here.\ntemplate <typename Integer>\nbool ParseNaturalNumber(const ::std::string& str, Integer* number) {\n  // Fail fast if the given string does not begin with a digit;\n  // this bypasses strtoXXX's \"optional leading whitespace and plus\n  // or minus sign\" semantics, which are undesirable here.\n  if (str.empty() || !IsDigit(str[0])) {\n    return false;\n  }\n  errno = 0;\n\n  char* end;\n  // BiggestConvertible is the largest integer type that system-provided\n  // string-to-number conversion routines can return.\n\n# if GTEST_OS_WINDOWS && !defined(__GNUC__)\n\n  // MSVC and C++ Builder define __int64 instead of the standard long long.\n  typedef unsigned __int64 BiggestConvertible;\n  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);\n\n# else\n\n  typedef unsigned long long BiggestConvertible;  // NOLINT\n  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);\n\n# endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)\n\n  const bool parse_success = *end == '\\0' && errno == 0;\n\n  // TODO(vladl@google.com): Convert this to compile time assertion when it is\n  // available.\n  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));\n\n  const Integer result = static_cast<Integer>(parsed);\n  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {\n    *number = result;\n    return true;\n  }\n  return false;\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// TestResult contains some private methods that should be hidden from\n// Google Test user but are required for testing. This class allow our tests\n// to access them.\n//\n// This class is supplied only for the purpose of testing Google Test's own\n// constructs. Do not use it in user tests, either directly or indirectly.\nclass TestResultAccessor {\n public:\n  static void RecordProperty(TestResult* test_result,\n                             const TestProperty& property) {\n    test_result->RecordProperty(property);\n  }\n\n  static void ClearTestPartResults(TestResult* test_result) {\n    test_result->ClearTestPartResults();\n  }\n\n  static const std::vector<testing::TestPartResult>& test_part_results(\n      const TestResult& test_result) {\n    return test_result.test_part_results();\n  }\n};\n\n}  // namespace internal\n}  // namespace testing\n\n#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_\n#undef GTEST_IMPLEMENTATION_\n\n#if GTEST_OS_WINDOWS\n# define vsnprintf _vsnprintf\n#endif  // GTEST_OS_WINDOWS\n\nnamespace testing {\n\nusing internal::CountIf;\nusing internal::ForEach;\nusing internal::GetElementOr;\nusing internal::Shuffle;\n\n// Constants.\n\n// A test whose test case name or test name matches this filter is\n// disabled and not run.\nstatic const char kDisableTestFilter[] = \"DISABLED_*:*/DISABLED_*\";\n\n// A test case whose name matches this filter is considered a death\n// test case and will be run before test cases whose name doesn't\n// match this filter.\nstatic const char kDeathTestCaseFilter[] = \"*DeathTest:*DeathTest/*\";\n\n// A test filter that matches everything.\nstatic const char kUniversalFilter[] = \"*\";\n\n// The default output file for XML output.\nstatic const char kDefaultOutputFile[] = \"test_detail.xml\";\n\n// The environment variable name for the test shard index.\nstatic const char kTestShardIndex[] = \"GTEST_SHARD_INDEX\";\n// The environment variable name for the total number of test shards.\nstatic const char kTestTotalShards[] = \"GTEST_TOTAL_SHARDS\";\n// The environment variable name for the test shard status file.\nstatic const char kTestShardStatusFile[] = \"GTEST_SHARD_STATUS_FILE\";\n\nnamespace internal {\n\n// The text used in failure messages to indicate the start of the\n// stack trace.\nconst char kStackTraceMarker[] = \"\\nStack trace:\\n\";\n\n// g_help_flag is true iff the --help flag or an equivalent form is\n// specified on the command line.\nbool g_help_flag = false;\n\n}  // namespace internal\n\nGTEST_DEFINE_bool_(\n    also_run_disabled_tests,\n    internal::BoolFromGTestEnv(\"also_run_disabled_tests\", false),\n    \"Run disabled tests too, in addition to the tests normally being run.\");\n\nGTEST_DEFINE_bool_(\n    break_on_failure,\n    internal::BoolFromGTestEnv(\"break_on_failure\", false),\n    \"True iff a failed assertion should be a debugger break-point.\");\n\nGTEST_DEFINE_bool_(\n    catch_exceptions,\n    internal::BoolFromGTestEnv(\"catch_exceptions\", true),\n    \"True iff \" GTEST_NAME_\n    \" should catch exceptions and treat them as test failures.\");\n\nGTEST_DEFINE_string_(\n    color,\n    internal::StringFromGTestEnv(\"color\", \"auto\"),\n    \"Whether to use colors in the output.  Valid values: yes, no, \"\n    \"and auto.  'auto' means to use colors if the output is \"\n    \"being sent to a terminal and the TERM environment variable \"\n    \"is set to xterm, xterm-color, xterm-256color, linux or cygwin.\");\n\nGTEST_DEFINE_string_(\n    filter,\n    internal::StringFromGTestEnv(\"filter\", kUniversalFilter),\n    \"A colon-separated list of glob (not regex) patterns \"\n    \"for filtering the tests to run, optionally followed by a \"\n    \"'-' and a : separated list of negative patterns (tests to \"\n    \"exclude).  A test is run if it matches one of the positive \"\n    \"patterns and does not match any of the negative patterns.\");\n\nGTEST_DEFINE_bool_(list_tests, false,\n                   \"List all tests without running them.\");\n\nGTEST_DEFINE_string_(\n    output,\n    internal::StringFromGTestEnv(\"output\", \"\"),\n    \"A format (currently must be \\\"xml\\\"), optionally followed \"\n    \"by a colon and an output file name or directory. A directory \"\n    \"is indicated by a trailing pathname separator. \"\n    \"Examples: \\\"xml:filename.xml\\\", \\\"xml::directoryname/\\\". \"\n    \"If a directory is specified, output files will be created \"\n    \"within that directory, with file-names based on the test \"\n    \"executable's name and, if necessary, made unique by adding \"\n    \"digits.\");\n\nGTEST_DEFINE_bool_(\n    print_time,\n    internal::BoolFromGTestEnv(\"print_time\", true),\n    \"True iff \" GTEST_NAME_\n    \" should display elapsed time in text output.\");\n\nGTEST_DEFINE_int32_(\n    random_seed,\n    internal::Int32FromGTestEnv(\"random_seed\", 0),\n    \"Random number seed to use when shuffling test orders.  Must be in range \"\n    \"[1, 99999], or 0 to use a seed based on the current time.\");\n\nGTEST_DEFINE_int32_(\n    repeat,\n    internal::Int32FromGTestEnv(\"repeat\", 1),\n    \"How many times to repeat each test.  Specify a negative number \"\n    \"for repeating forever.  Useful for shaking out flaky tests.\");\n\nGTEST_DEFINE_bool_(\n    show_internal_stack_frames, false,\n    \"True iff \" GTEST_NAME_ \" should include internal stack frames when \"\n    \"printing test failure stack traces.\");\n\nGTEST_DEFINE_bool_(\n    shuffle,\n    internal::BoolFromGTestEnv(\"shuffle\", false),\n    \"True iff \" GTEST_NAME_\n    \" should randomize tests' order on every run.\");\n\nGTEST_DEFINE_int32_(\n    stack_trace_depth,\n    internal::Int32FromGTestEnv(\"stack_trace_depth\", kMaxStackTraceDepth),\n    \"The maximum number of stack frames to print when an \"\n    \"assertion fails.  The valid range is 0 through 100, inclusive.\");\n\nGTEST_DEFINE_string_(\n    stream_result_to,\n    internal::StringFromGTestEnv(\"stream_result_to\", \"\"),\n    \"This flag specifies the host name and the port number on which to stream \"\n    \"test results. Example: \\\"localhost:555\\\". The flag is effective only on \"\n    \"Linux.\");\n\nGTEST_DEFINE_bool_(\n    throw_on_failure,\n    internal::BoolFromGTestEnv(\"throw_on_failure\", false),\n    \"When this flag is specified, a failed assertion will throw an exception \"\n    \"if exceptions are enabled or exit the program with a non-zero code \"\n    \"otherwise.\");\n\nnamespace internal {\n\n// Generates a random number from [0, range), using a Linear\n// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater\n// than kMaxRange.\nUInt32 Random::Generate(UInt32 range) {\n  // These constants are the same as are used in glibc's rand(3).\n  state_ = (1103515245U*state_ + 12345U) % kMaxRange;\n\n  GTEST_CHECK_(range > 0)\n      << \"Cannot generate a number in the range [0, 0).\";\n  GTEST_CHECK_(range <= kMaxRange)\n      << \"Generation of a number in [0, \" << range << \") was requested, \"\n      << \"but this can only generate numbers in [0, \" << kMaxRange << \").\";\n\n  // Converting via modulus introduces a bit of downward bias, but\n  // it's simple, and a linear congruential generator isn't too good\n  // to begin with.\n  return state_ % range;\n}\n\n// GTestIsInitialized() returns true iff the user has initialized\n// Google Test.  Useful for catching the user mistake of not initializing\n// Google Test before calling RUN_ALL_TESTS().\n//\n// A user must call testing::InitGoogleTest() to initialize Google\n// Test.  g_init_gtest_count is set to the number of times\n// InitGoogleTest() has been called.  We don't protect this variable\n// under a mutex as it is only accessed in the main thread.\nint g_init_gtest_count = 0;\nstatic bool GTestIsInitialized() { return g_init_gtest_count != 0; }\n\n// Iterates over a vector of TestCases, keeping a running sum of the\n// results of calling a given int-returning method on each.\n// Returns the sum.\nstatic int SumOverTestCaseList(const std::vector<TestCase*>& case_list,\n                               int (TestCase::*method)() const) {\n  int sum = 0;\n  for (size_t i = 0; i < case_list.size(); i++) {\n    sum += (case_list[i]->*method)();\n  }\n  return sum;\n}\n\n// Returns true iff the test case passed.\nstatic bool TestCasePassed(const TestCase* test_case) {\n  return test_case->should_run() && test_case->Passed();\n}\n\n// Returns true iff the test case failed.\nstatic bool TestCaseFailed(const TestCase* test_case) {\n  return test_case->should_run() && test_case->Failed();\n}\n\n// Returns true iff test_case contains at least one test that should\n// run.\nstatic bool ShouldRunTestCase(const TestCase* test_case) {\n  return test_case->should_run();\n}\n\n// AssertHelper constructor.\nAssertHelper::AssertHelper(TestPartResult::Type type,\n                           const char* file,\n                           int line,\n                           const char* message)\n    : data_(new AssertHelperData(type, file, line, message)) {\n}\n\nAssertHelper::~AssertHelper() {\n  delete data_;\n}\n\n// Message assignment, for assertion streaming support.\nvoid AssertHelper::operator=(const Message& message) const {\n  UnitTest::GetInstance()->\n    AddTestPartResult(data_->type, data_->file, data_->line,\n                      AppendUserMessage(data_->message, message),\n                      UnitTest::GetInstance()->impl()\n                      ->CurrentOsStackTraceExceptTop(1)\n                      // Skips the stack frame for this function itself.\n                      );  // NOLINT\n}\n\n// Mutex for linked pointers.\nGTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);\n\n// Application pathname gotten in InitGoogleTest.\nString g_executable_path;\n\n// Returns the current application's name, removing directory path if that\n// is present.\nFilePath GetCurrentExecutableName() {\n  FilePath result;\n\n#if GTEST_OS_WINDOWS\n  result.Set(FilePath(g_executable_path).RemoveExtension(\"exe\"));\n#else\n  result.Set(FilePath(g_executable_path));\n#endif  // GTEST_OS_WINDOWS\n\n  return result.RemoveDirectoryName();\n}\n\n// Functions for processing the gtest_output flag.\n\n// Returns the output format, or \"\" for normal printed output.\nString UnitTestOptions::GetOutputFormat() {\n  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();\n  if (gtest_output_flag == NULL) return String(\"\");\n\n  const char* const colon = strchr(gtest_output_flag, ':');\n  return (colon == NULL) ?\n      String(gtest_output_flag) :\n      String(gtest_output_flag, colon - gtest_output_flag);\n}\n\n// Returns the name of the requested output file, or the default if none\n// was explicitly specified.\nString UnitTestOptions::GetAbsolutePathToOutputFile() {\n  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();\n  if (gtest_output_flag == NULL)\n    return String(\"\");\n\n  const char* const colon = strchr(gtest_output_flag, ':');\n  if (colon == NULL)\n    return String(internal::FilePath::ConcatPaths(\n               internal::FilePath(\n                   UnitTest::GetInstance()->original_working_dir()),\n               internal::FilePath(kDefaultOutputFile)).ToString() );\n\n  internal::FilePath output_name(colon + 1);\n  if (!output_name.IsAbsolutePath())\n    // TODO(wan@google.com): on Windows \\some\\path is not an absolute\n    // path (as its meaning depends on the current drive), yet the\n    // following logic for turning it into an absolute path is wrong.\n    // Fix it.\n    output_name = internal::FilePath::ConcatPaths(\n        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),\n        internal::FilePath(colon + 1));\n\n  if (!output_name.IsDirectory())\n    return output_name.ToString();\n\n  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(\n      output_name, internal::GetCurrentExecutableName(),\n      GetOutputFormat().c_str()));\n  return result.ToString();\n}\n\n// Returns true iff the wildcard pattern matches the string.  The\n// first ':' or '\\0' character in pattern marks the end of it.\n//\n// This recursive algorithm isn't very efficient, but is clear and\n// works well enough for matching test names, which are short.\nbool UnitTestOptions::PatternMatchesString(const char *pattern,\n                                           const char *str) {\n  switch (*pattern) {\n    case '\\0':\n    case ':':  // Either ':' or '\\0' marks the end of the pattern.\n      return *str == '\\0';\n    case '?':  // Matches any single character.\n      return *str != '\\0' && PatternMatchesString(pattern + 1, str + 1);\n    case '*':  // Matches any string (possibly empty) of characters.\n      return (*str != '\\0' && PatternMatchesString(pattern, str + 1)) ||\n          PatternMatchesString(pattern + 1, str);\n    default:  // Non-special character.  Matches itself.\n      return *pattern == *str &&\n          PatternMatchesString(pattern + 1, str + 1);\n  }\n}\n\nbool UnitTestOptions::MatchesFilter(const String& name, const char* filter) {\n  const char *cur_pattern = filter;\n  for (;;) {\n    if (PatternMatchesString(cur_pattern, name.c_str())) {\n      return true;\n    }\n\n    // Finds the next pattern in the filter.\n    cur_pattern = strchr(cur_pattern, ':');\n\n    // Returns if no more pattern can be found.\n    if (cur_pattern == NULL) {\n      return false;\n    }\n\n    // Skips the pattern separater (the ':' character).\n    cur_pattern++;\n  }\n}\n\n// TODO(keithray): move String function implementations to gtest-string.cc.\n\n// Returns true iff the user-specified filter matches the test case\n// name and the test name.\nbool UnitTestOptions::FilterMatchesTest(const String &test_case_name,\n                                        const String &test_name) {\n  const String& full_name = String::Format(\"%s.%s\",\n                                           test_case_name.c_str(),\n                                           test_name.c_str());\n\n  // Split --gtest_filter at '-', if there is one, to separate into\n  // positive filter and negative filter portions\n  const char* const p = GTEST_FLAG(filter).c_str();\n  const char* const dash = strchr(p, '-');\n  String positive;\n  String negative;\n  if (dash == NULL) {\n    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter\n    negative = String(\"\");\n  } else {\n    positive = String(p, dash - p);  // Everything up to the dash\n    negative = String(dash+1);       // Everything after the dash\n    if (positive.empty()) {\n      // Treat '-test1' as the same as '*-test1'\n      positive = kUniversalFilter;\n    }\n  }\n\n  // A filter is a colon-separated list of patterns.  It matches a\n  // test if any pattern in it matches the test.\n  return (MatchesFilter(full_name, positive.c_str()) &&\n          !MatchesFilter(full_name, negative.c_str()));\n}\n\n#if GTEST_HAS_SEH\n// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the\n// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.\n// This function is useful as an __except condition.\nint UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {\n  // Google Test should handle a SEH exception if:\n  //   1. the user wants it to, AND\n  //   2. this is not a breakpoint exception, AND\n  //   3. this is not a C++ exception (VC++ implements them via SEH,\n  //      apparently).\n  //\n  // SEH exception code for C++ exceptions.\n  // (see http://support.microsoft.com/kb/185294 for more information).\n  const DWORD kCxxExceptionCode = 0xe06d7363;\n\n  bool should_handle = true;\n\n  if (!GTEST_FLAG(catch_exceptions))\n    should_handle = false;\n  else if (exception_code == EXCEPTION_BREAKPOINT)\n    should_handle = false;\n  else if (exception_code == kCxxExceptionCode)\n    should_handle = false;\n\n  return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;\n}\n#endif  // GTEST_HAS_SEH\n\n}  // namespace internal\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results. Intercepts only failures from the current thread.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    TestPartResultArray* result)\n    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),\n      result_(result) {\n  Init();\n}\n\n// The c'tor sets this object as the test part result reporter used by\n// Google Test.  The 'result' parameter specifies where to report the\n// results.\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\n    InterceptMode intercept_mode, TestPartResultArray* result)\n    : intercept_mode_(intercept_mode),\n      result_(result) {\n  Init();\n}\n\nvoid ScopedFakeTestPartResultReporter::Init() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    old_reporter_ = impl->GetGlobalTestPartResultReporter();\n    impl->SetGlobalTestPartResultReporter(this);\n  } else {\n    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();\n    impl->SetTestPartResultReporterForCurrentThread(this);\n  }\n}\n\n// The d'tor restores the test part result reporter used by Google Test\n// before.\nScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\n    impl->SetGlobalTestPartResultReporter(old_reporter_);\n  } else {\n    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);\n  }\n}\n\n// Increments the test part result count and remembers the result.\n// This method is from the TestPartResultReporterInterface interface.\nvoid ScopedFakeTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  result_->Append(result);\n}\n\nnamespace internal {\n\n// Returns the type ID of ::testing::Test.  We should always call this\n// instead of GetTypeId< ::testing::Test>() to get the type ID of\n// testing::Test.  This is to work around a suspected linker bug when\n// using Google Test as a framework on Mac OS X.  The bug causes\n// GetTypeId< ::testing::Test>() to return different values depending\n// on whether the call is from the Google Test framework itself or\n// from user test code.  GetTestTypeId() is guaranteed to always\n// return the same value, as it always calls GetTypeId<>() from the\n// gtest.cc, which is within the Google Test framework.\nTypeId GetTestTypeId() {\n  return GetTypeId<Test>();\n}\n\n// The value of GetTestTypeId() as seen from within the Google Test\n// library.  This is solely for testing GetTestTypeId().\nextern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();\n\n// This predicate-formatter checks that 'results' contains a test part\n// failure of the given type and that the failure message contains the\n// given substring.\nAssertionResult HasOneFailure(const char* /* results_expr */,\n                              const char* /* type_expr */,\n                              const char* /* substr_expr */,\n                              const TestPartResultArray& results,\n                              TestPartResult::Type type,\n                              const string& substr) {\n  const String expected(type == TestPartResult::kFatalFailure ?\n                        \"1 fatal failure\" :\n                        \"1 non-fatal failure\");\n  Message msg;\n  if (results.size() != 1) {\n    msg << \"Expected: \" << expected << \"\\n\"\n        << \"  Actual: \" << results.size() << \" failures\";\n    for (int i = 0; i < results.size(); i++) {\n      msg << \"\\n\" << results.GetTestPartResult(i);\n    }\n    return AssertionFailure() << msg;\n  }\n\n  const TestPartResult& r = results.GetTestPartResult(0);\n  if (r.type() != type) {\n    return AssertionFailure() << \"Expected: \" << expected << \"\\n\"\n                              << \"  Actual:\\n\"\n                              << r;\n  }\n\n  if (strstr(r.message(), substr.c_str()) == NULL) {\n    return AssertionFailure() << \"Expected: \" << expected << \" containing \\\"\"\n                              << substr << \"\\\"\\n\"\n                              << \"  Actual:\\n\"\n                              << r;\n  }\n\n  return AssertionSuccess();\n}\n\n// The constructor of SingleFailureChecker remembers where to look up\n// test part results, what type of failure we expect, and what\n// substring the failure message should contain.\nSingleFailureChecker:: SingleFailureChecker(\n    const TestPartResultArray* results,\n    TestPartResult::Type type,\n    const string& substr)\n    : results_(results),\n      type_(type),\n      substr_(substr) {}\n\n// The destructor of SingleFailureChecker verifies that the given\n// TestPartResultArray contains exactly one failure that has the given\n// type and contains the given substring.  If that's not the case, a\n// non-fatal failure will be generated.\nSingleFailureChecker::~SingleFailureChecker() {\n  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);\n}\n\nDefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(\n    UnitTestImpl* unit_test) : unit_test_(unit_test) {}\n\nvoid DefaultGlobalTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->current_test_result()->AddTestPartResult(result);\n  unit_test_->listeners()->repeater()->OnTestPartResult(result);\n}\n\nDefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(\n    UnitTestImpl* unit_test) : unit_test_(unit_test) {}\n\nvoid DefaultPerThreadTestPartResultReporter::ReportTestPartResult(\n    const TestPartResult& result) {\n  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);\n}\n\n// Returns the global test part result reporter.\nTestPartResultReporterInterface*\nUnitTestImpl::GetGlobalTestPartResultReporter() {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  return global_test_part_result_repoter_;\n}\n\n// Sets the global test part result reporter.\nvoid UnitTestImpl::SetGlobalTestPartResultReporter(\n    TestPartResultReporterInterface* reporter) {\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\n  global_test_part_result_repoter_ = reporter;\n}\n\n// Returns the test part result reporter for the current thread.\nTestPartResultReporterInterface*\nUnitTestImpl::GetTestPartResultReporterForCurrentThread() {\n  return per_thread_test_part_result_reporter_.get();\n}\n\n// Sets the test part result reporter for the current thread.\nvoid UnitTestImpl::SetTestPartResultReporterForCurrentThread(\n    TestPartResultReporterInterface* reporter) {\n  per_thread_test_part_result_reporter_.set(reporter);\n}\n\n// Gets the number of successful test cases.\nint UnitTestImpl::successful_test_case_count() const {\n  return CountIf(test_cases_, TestCasePassed);\n}\n\n// Gets the number of failed test cases.\nint UnitTestImpl::failed_test_case_count() const {\n  return CountIf(test_cases_, TestCaseFailed);\n}\n\n// Gets the number of all test cases.\nint UnitTestImpl::total_test_case_count() const {\n  return static_cast<int>(test_cases_.size());\n}\n\n// Gets the number of all test cases that contain at least one test\n// that should run.\nint UnitTestImpl::test_case_to_run_count() const {\n  return CountIf(test_cases_, ShouldRunTestCase);\n}\n\n// Gets the number of successful tests.\nint UnitTestImpl::successful_test_count() const {\n  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);\n}\n\n// Gets the number of failed tests.\nint UnitTestImpl::failed_test_count() const {\n  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);\n}\n\n// Gets the number of disabled tests.\nint UnitTestImpl::disabled_test_count() const {\n  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);\n}\n\n// Gets the number of all tests.\nint UnitTestImpl::total_test_count() const {\n  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);\n}\n\n// Gets the number of tests that should run.\nint UnitTestImpl::test_to_run_count() const {\n  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);\n}\n\n// Returns the current OS stack trace as a String.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// CurrentOsStackTraceExceptTop(1), Foo() will be included in the\n// trace but Bar() and CurrentOsStackTraceExceptTop() won't.\nString UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {\n  (void)skip_count;\n  return String(\"\");\n}\n\n// Returns the current time in milliseconds.\nTimeInMillis GetTimeInMillis() {\n#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)\n  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.\n  // http://analogous.blogspot.com/2005/04/epoch.html\n  const TimeInMillis kJavaEpochToWinFileTimeDelta =\n    static_cast<TimeInMillis>(116444736UL) * 100000UL;\n  const DWORD kTenthMicrosInMilliSecond = 10000;\n\n  SYSTEMTIME now_systime;\n  FILETIME now_filetime;\n  ULARGE_INTEGER now_int64;\n  // TODO(kenton@google.com): Shouldn't this just use\n  //   GetSystemTimeAsFileTime()?\n  GetSystemTime(&now_systime);\n  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {\n    now_int64.LowPart = now_filetime.dwLowDateTime;\n    now_int64.HighPart = now_filetime.dwHighDateTime;\n    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -\n      kJavaEpochToWinFileTimeDelta;\n    return now_int64.QuadPart;\n  }\n  return 0;\n#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_\n  __timeb64 now;\n\n# ifdef _MSC_VER\n\n  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996\n  // (deprecated function) there.\n  // TODO(kenton@google.com): Use GetTickCount()?  Or use\n  //   SystemTimeToFileTime()\n#  pragma warning(push)          // Saves the current warning state.\n#  pragma warning(disable:4996)  // Temporarily disables warning 4996.\n  _ftime64(&now);\n#  pragma warning(pop)           // Restores the warning state.\n# else\n\n  _ftime64(&now);\n\n# endif  // _MSC_VER\n\n  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;\n#elif GTEST_HAS_GETTIMEOFDAY_\n  struct timeval now;\n  gettimeofday(&now, NULL);\n  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;\n#else\n# error \"Don't know how to get the current time on your system.\"\n#endif\n}\n\n// Utilities\n\n// class String\n\n// Returns the input enclosed in double quotes if it's not NULL;\n// otherwise returns \"(null)\".  For example, \"\\\"Hello\\\"\" is returned\n// for input \"Hello\".\n//\n// This is useful for printing a C string in the syntax of a literal.\n//\n// Known issue: escape sequences are not handled yet.\nString String::ShowCStringQuoted(const char* c_str) {\n  return c_str ? String::Format(\"\\\"%s\\\"\", c_str) : String(\"(null)\");\n}\n\n// Copies at most length characters from str into a newly-allocated\n// piece of memory of size length+1.  The memory is allocated with new[].\n// A terminating null byte is written to the memory, and a pointer to it\n// is returned.  If str is NULL, NULL is returned.\nstatic char* CloneString(const char* str, size_t length) {\n  if (str == NULL) {\n    return NULL;\n  } else {\n    char* const clone = new char[length + 1];\n    posix::StrNCpy(clone, str, length);\n    clone[length] = '\\0';\n    return clone;\n  }\n}\n\n// Clones a 0-terminated C string, allocating memory using new.  The\n// caller is responsible for deleting[] the return value.  Returns the\n// cloned string, or NULL if the input is NULL.\nconst char * String::CloneCString(const char* c_str) {\n  return (c_str == NULL) ?\n                    NULL : CloneString(c_str, strlen(c_str));\n}\n\n#if GTEST_OS_WINDOWS_MOBILE\n// Creates a UTF-16 wide string from the given ANSI string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the wide string, or NULL if the\n// input is NULL.\nLPCWSTR String::AnsiToUtf16(const char* ansi) {\n  if (!ansi) return NULL;\n  const int length = strlen(ansi);\n  const int unicode_length =\n      MultiByteToWideChar(CP_ACP, 0, ansi, length,\n                          NULL, 0);\n  WCHAR* unicode = new WCHAR[unicode_length + 1];\n  MultiByteToWideChar(CP_ACP, 0, ansi, length,\n                      unicode, unicode_length);\n  unicode[unicode_length] = 0;\n  return unicode;\n}\n\n// Creates an ANSI string from the given wide string, allocating\n// memory using new. The caller is responsible for deleting the return\n// value using delete[]. Returns the ANSI string, or NULL if the\n// input is NULL.\nconst char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {\n  if (!utf16_str) return NULL;\n  const int ansi_length =\n      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,\n                          NULL, 0, NULL, NULL);\n  char* ansi = new char[ansi_length + 1];\n  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,\n                      ansi, ansi_length, NULL, NULL);\n  ansi[ansi_length] = 0;\n  return ansi;\n}\n\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Compares two C strings.  Returns true iff they have the same content.\n//\n// Unlike strcmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CStringEquals(const char * lhs, const char * rhs) {\n  if ( lhs == NULL ) return rhs == NULL;\n\n  if ( rhs == NULL ) return false;\n\n  return strcmp(lhs, rhs) == 0;\n}\n\n#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING\n\n// Converts an array of wide chars to a narrow string using the UTF-8\n// encoding, and streams the result to the given Message object.\nstatic void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,\n                                     Message* msg) {\n  // TODO(wan): consider allowing a testing::String object to\n  // contain '\\0'.  This will make it behave more like std::string,\n  // and will allow ToUtf8String() to return the correct encoding\n  // for '\\0' s.t. we can get rid of the conditional here (and in\n  // several other places).\n  for (size_t i = 0; i != length; ) {  // NOLINT\n    if (wstr[i] != L'\\0') {\n      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));\n      while (i != length && wstr[i] != L'\\0')\n        i++;\n    } else {\n      *msg << '\\0';\n      i++;\n    }\n  }\n}\n\n#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING\n\n}  // namespace internal\n\n#if GTEST_HAS_STD_WSTRING\n// Converts the given wide string to a narrow string using the UTF-8\n// encoding, and streams the result to this Message object.\nMessage& Message::operator <<(const ::std::wstring& wstr) {\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\n  return *this;\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n#if GTEST_HAS_GLOBAL_WSTRING\n// Converts the given wide string to a narrow string using the UTF-8\n// encoding, and streams the result to this Message object.\nMessage& Message::operator <<(const ::wstring& wstr) {\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\n  return *this;\n}\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n// AssertionResult constructors.\n// Used in EXPECT_TRUE/FALSE(assertion_result).\nAssertionResult::AssertionResult(const AssertionResult& other)\n    : success_(other.success_),\n      message_(other.message_.get() != NULL ?\n               new ::std::string(*other.message_) :\n               static_cast< ::std::string*>(NULL)) {\n}\n\n// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\nAssertionResult AssertionResult::operator!() const {\n  AssertionResult negation(!success_);\n  if (message_.get() != NULL)\n    negation << *message_;\n  return negation;\n}\n\n// Makes a successful assertion result.\nAssertionResult AssertionSuccess() {\n  return AssertionResult(true);\n}\n\n// Makes a failed assertion result.\nAssertionResult AssertionFailure() {\n  return AssertionResult(false);\n}\n\n// Makes a failed assertion result with the given failure message.\n// Deprecated; use AssertionFailure() << message.\nAssertionResult AssertionFailure(const Message& message) {\n  return AssertionFailure() << message;\n}\n\nnamespace internal {\n\n// Constructs and returns the message for an equality assertion\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\n//\n// The first four parameters are the expressions used in the assertion\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\n// where foo is 5 and bar is 6, we have:\n//\n//   expected_expression: \"foo\"\n//   actual_expression:   \"bar\"\n//   expected_value:      \"5\"\n//   actual_value:        \"6\"\n//\n// The ignoring_case parameter is true iff the assertion is a\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\n// be inserted into the message.\nAssertionResult EqFailure(const char* expected_expression,\n                          const char* actual_expression,\n                          const String& expected_value,\n                          const String& actual_value,\n                          bool ignoring_case) {\n  Message msg;\n  msg << \"Value of: \" << actual_expression;\n  if (actual_value != actual_expression) {\n    msg << \"\\n  Actual: \" << actual_value;\n  }\n\n  msg << \"\\nExpected: \" << expected_expression;\n  if (ignoring_case) {\n    msg << \" (ignoring case)\";\n  }\n  if (expected_value != expected_expression) {\n    msg << \"\\nWhich is: \" << expected_value;\n  }\n\n  return AssertionFailure() << msg;\n}\n\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\nString GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,\n                                      const char* expression_text,\n                                      const char* actual_predicate_value,\n                                      const char* expected_predicate_value) {\n  const char* actual_message = assertion_result.message();\n  Message msg;\n  msg << \"Value of: \" << expression_text\n      << \"\\n  Actual: \" << actual_predicate_value;\n  if (actual_message[0] != '\\0')\n    msg << \" (\" << actual_message << \")\";\n  msg << \"\\nExpected: \" << expected_predicate_value;\n  return msg.GetString();\n}\n\n// Helper function for implementing ASSERT_NEAR.\nAssertionResult DoubleNearPredFormat(const char* expr1,\n                                     const char* expr2,\n                                     const char* abs_error_expr,\n                                     double val1,\n                                     double val2,\n                                     double abs_error) {\n  const double diff = fabs(val1 - val2);\n  if (diff <= abs_error) return AssertionSuccess();\n\n  // TODO(wan): do not print the value of an expression if it's\n  // already a literal.\n  return AssertionFailure()\n      << \"The difference between \" << expr1 << \" and \" << expr2\n      << \" is \" << diff << \", which exceeds \" << abs_error_expr << \", where\\n\"\n      << expr1 << \" evaluates to \" << val1 << \",\\n\"\n      << expr2 << \" evaluates to \" << val2 << \", and\\n\"\n      << abs_error_expr << \" evaluates to \" << abs_error << \".\";\n}\n\n\n// Helper template for implementing FloatLE() and DoubleLE().\ntemplate <typename RawType>\nAssertionResult FloatingPointLE(const char* expr1,\n                                const char* expr2,\n                                RawType val1,\n                                RawType val2) {\n  // Returns success if val1 is less than val2,\n  if (val1 < val2) {\n    return AssertionSuccess();\n  }\n\n  // or if val1 is almost equal to val2.\n  const FloatingPoint<RawType> lhs(val1), rhs(val2);\n  if (lhs.AlmostEquals(rhs)) {\n    return AssertionSuccess();\n  }\n\n  // Note that the above two checks will both fail if either val1 or\n  // val2 is NaN, as the IEEE floating-point standard requires that\n  // any predicate involving a NaN must return false.\n\n  ::std::stringstream val1_ss;\n  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val1;\n\n  ::std::stringstream val2_ss;\n  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\n          << val2;\n\n  return AssertionFailure()\n      << \"Expected: (\" << expr1 << \") <= (\" << expr2 << \")\\n\"\n      << \"  Actual: \" << StringStreamToString(&val1_ss) << \" vs \"\n      << StringStreamToString(&val2_ss);\n}\n\n}  // namespace internal\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult FloatLE(const char* expr1, const char* expr2,\n                        float val1, float val2) {\n  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);\n}\n\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\nAssertionResult DoubleLE(const char* expr1, const char* expr2,\n                         double val1, double val2) {\n  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);\n}\n\nnamespace internal {\n\n// The helper function for {ASSERT|EXPECT}_EQ with int or enum\n// arguments.\nAssertionResult CmpHelperEQ(const char* expected_expression,\n                            const char* actual_expression,\n                            BiggestInt expected,\n                            BiggestInt actual) {\n  if (expected == actual) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   FormatForComparisonFailureMessage(expected, actual),\n                   FormatForComparisonFailureMessage(actual, expected),\n                   false);\n}\n\n// A macro for implementing the helper functions needed to implement\n// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here\n// just to avoid copy-and-paste of similar code.\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)\\\nAssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\n                                   BiggestInt val1, BiggestInt val2) {\\\n  if (val1 op val2) {\\\n    return AssertionSuccess();\\\n  } else {\\\n    return AssertionFailure() \\\n        << \"Expected: (\" << expr1 << \") \" #op \" (\" << expr2\\\n        << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\\\n        << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\\\n  }\\\n}\n\n// Implements the helper function for {ASSERT|EXPECT}_NE with int or\n// enum arguments.\nGTEST_IMPL_CMP_HELPER_(NE, !=)\n// Implements the helper function for {ASSERT|EXPECT}_LE with int or\n// enum arguments.\nGTEST_IMPL_CMP_HELPER_(LE, <=)\n// Implements the helper function for {ASSERT|EXPECT}_LT with int or\n// enum arguments.\nGTEST_IMPL_CMP_HELPER_(LT, < )\n// Implements the helper function for {ASSERT|EXPECT}_GE with int or\n// enum arguments.\nGTEST_IMPL_CMP_HELPER_(GE, >=)\n// Implements the helper function for {ASSERT|EXPECT}_GT with int or\n// enum arguments.\nGTEST_IMPL_CMP_HELPER_(GT, > )\n\n#undef GTEST_IMPL_CMP_HELPER_\n\n// The helper function for {ASSERT|EXPECT}_STREQ.\nAssertionResult CmpHelperSTREQ(const char* expected_expression,\n                               const char* actual_expression,\n                               const char* expected,\n                               const char* actual) {\n  if (String::CStringEquals(expected, actual)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   String::ShowCStringQuoted(expected),\n                   String::ShowCStringQuoted(actual),\n                   false);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\nAssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,\n                                   const char* actual_expression,\n                                   const char* expected,\n                                   const char* actual) {\n  if (String::CaseInsensitiveCStringEquals(expected, actual)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   String::ShowCStringQuoted(expected),\n                   String::ShowCStringQuoted(actual),\n                   true);\n}\n\n// The helper function for {ASSERT|EXPECT}_STRNE.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression,\n                               const char* s1,\n                               const char* s2) {\n  if (!String::CStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure() << \"Expected: (\" << s1_expression << \") != (\"\n                              << s2_expression << \"), actual: \\\"\"\n                              << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\nAssertionResult CmpHelperSTRCASENE(const char* s1_expression,\n                                   const char* s2_expression,\n                                   const char* s1,\n                                   const char* s2) {\n  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  } else {\n    return AssertionFailure()\n        << \"Expected: (\" << s1_expression << \") != (\"\n        << s2_expression << \") (ignoring case), actual: \\\"\"\n        << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\n  }\n}\n\n}  // namespace internal\n\nnamespace {\n\n// Helper functions for implementing IsSubString() and IsNotSubstring().\n\n// This group of overloaded functions return true iff needle is a\n// substring of haystack.  NULL is considered a substring of itself\n// only.\n\nbool IsSubstringPred(const char* needle, const char* haystack) {\n  if (needle == NULL || haystack == NULL)\n    return needle == haystack;\n\n  return strstr(haystack, needle) != NULL;\n}\n\nbool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {\n  if (needle == NULL || haystack == NULL)\n    return needle == haystack;\n\n  return wcsstr(haystack, needle) != NULL;\n}\n\n// StringType here can be either ::std::string or ::std::wstring.\ntemplate <typename StringType>\nbool IsSubstringPred(const StringType& needle,\n                     const StringType& haystack) {\n  return haystack.find(needle) != StringType::npos;\n}\n\n// This function implements either IsSubstring() or IsNotSubstring(),\n// depending on the value of the expected_to_be_substring parameter.\n// StringType here can be const char*, const wchar_t*, ::std::string,\n// or ::std::wstring.\ntemplate <typename StringType>\nAssertionResult IsSubstringImpl(\n    bool expected_to_be_substring,\n    const char* needle_expr, const char* haystack_expr,\n    const StringType& needle, const StringType& haystack) {\n  if (IsSubstringPred(needle, haystack) == expected_to_be_substring)\n    return AssertionSuccess();\n\n  const bool is_wide_string = sizeof(needle[0]) > 1;\n  const char* const begin_string_quote = is_wide_string ? \"L\\\"\" : \"\\\"\";\n  return AssertionFailure()\n      << \"Value of: \" << needle_expr << \"\\n\"\n      << \"  Actual: \" << begin_string_quote << needle << \"\\\"\\n\"\n      << \"Expected: \" << (expected_to_be_substring ? \"\" : \"not \")\n      << \"a substring of \" << haystack_expr << \"\\n\"\n      << \"Which is: \" << begin_string_quote << haystack << \"\\\"\";\n}\n\n}  // namespace\n\n// IsSubstring() and IsNotSubstring() check whether needle is a\n// substring of haystack (NULL is considered a substring of itself\n// only), and return an appropriate error message when they fail.\n\nAssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const char* needle, const char* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const wchar_t* needle, const wchar_t* haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const char* needle, const char* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const wchar_t* needle, const wchar_t* haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::string& needle, const ::std::string& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::string& needle, const ::std::string& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n\n#if GTEST_HAS_STD_WSTRING\nAssertionResult IsSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::wstring& needle, const ::std::wstring& haystack) {\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\n}\n\nAssertionResult IsNotSubstring(\n    const char* needle_expr, const char* haystack_expr,\n    const ::std::wstring& needle, const ::std::wstring& haystack) {\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\nnamespace internal {\n\n#if GTEST_OS_WINDOWS\n\nnamespace {\n\n// Helper function for IsHRESULT{SuccessFailure} predicates\nAssertionResult HRESULTFailureHelper(const char* expr,\n                                     const char* expected,\n                                     long hr) {  // NOLINT\n# if GTEST_OS_WINDOWS_MOBILE\n\n  // Windows CE doesn't support FormatMessage.\n  const char error_text[] = \"\";\n\n# else\n\n  // Looks up the human-readable system message for the HRESULT code\n  // and since we're not passing any params to FormatMessage, we don't\n  // want inserts expanded.\n  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |\n                       FORMAT_MESSAGE_IGNORE_INSERTS;\n  const DWORD kBufSize = 4096;  // String::Format can't exceed this length.\n  // Gets the system's human readable message string for this HRESULT.\n  char error_text[kBufSize] = { '\\0' };\n  DWORD message_length = ::FormatMessageA(kFlags,\n                                          0,  // no source, we're asking system\n                                          hr,  // the error\n                                          0,  // no line width restrictions\n                                          error_text,  // output buffer\n                                          kBufSize,  // buf size\n                                          NULL);  // no arguments for inserts\n  // Trims tailing white space (FormatMessage leaves a trailing cr-lf)\n  for (; message_length && IsSpace(error_text[message_length - 1]);\n          --message_length) {\n    error_text[message_length - 1] = '\\0';\n  }\n\n# endif  // GTEST_OS_WINDOWS_MOBILE\n\n  const String error_hex(String::Format(\"0x%08X \", hr));\n  return ::testing::AssertionFailure()\n      << \"Expected: \" << expr << \" \" << expected << \".\\n\"\n      << \"  Actual: \" << error_hex << error_text << \"\\n\";\n}\n\n}  // namespace\n\nAssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT\n  if (SUCCEEDED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"succeeds\", hr);\n}\n\nAssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT\n  if (FAILED(hr)) {\n    return AssertionSuccess();\n  }\n  return HRESULTFailureHelper(expr, \"fails\", hr);\n}\n\n#endif  // GTEST_OS_WINDOWS\n\n// Utility functions for encoding Unicode text (wide strings) in\n// UTF-8.\n\n// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8\n// like this:\n//\n// Code-point length   Encoding\n//   0 -  7 bits       0xxxxxxx\n//   8 - 11 bits       110xxxxx 10xxxxxx\n//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx\n//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n\n// The maximum code-point a one-byte UTF-8 sequence can represent.\nconst UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;\n\n// The maximum code-point a two-byte UTF-8 sequence can represent.\nconst UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;\n\n// The maximum code-point a three-byte UTF-8 sequence can represent.\nconst UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1;\n\n// The maximum code-point a four-byte UTF-8 sequence can represent.\nconst UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1;\n\n// Chops off the n lowest bits from a bit pattern.  Returns the n\n// lowest bits.  As a side effect, the original bit pattern will be\n// shifted to the right by n bits.\ninline UInt32 ChopLowBits(UInt32* bits, int n) {\n  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);\n  *bits >>= n;\n  return low_bits;\n}\n\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\n// code_point parameter is of type UInt32 because wchar_t may not be\n// wide enough to contain a code point.\n// The output buffer str must containt at least 32 characters.\n// The function returns the address of the output buffer.\n// If the code_point is not a valid Unicode code point\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'.\nchar* CodePointToUtf8(UInt32 code_point, char* str) {\n  if (code_point <= kMaxCodePoint1) {\n    str[1] = '\\0';\n    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx\n  } else if (code_point <= kMaxCodePoint2) {\n    str[2] = '\\0';\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx\n  } else if (code_point <= kMaxCodePoint3) {\n    str[3] = '\\0';\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx\n  } else if (code_point <= kMaxCodePoint4) {\n    str[4] = '\\0';\n    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\n    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx\n  } else {\n    // The longest string String::Format can produce when invoked\n    // with these parameters is 28 character long (not including\n    // the terminating nul character). We are asking for 32 character\n    // buffer just in case. This is also enough for strncpy to\n    // null-terminate the destination string.\n    posix::StrNCpy(\n        str, String::Format(\"(Invalid Unicode 0x%X)\", code_point).c_str(), 32);\n    str[31] = '\\0';  // Makes sure no change in the format to strncpy leaves\n                     // the result unterminated.\n  }\n  return str;\n}\n\n// The following two functions only make sense if the the system\n// uses UTF-16 for wide string encoding. All supported systems\n// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.\n\n// Determines if the arguments constitute UTF-16 surrogate pair\n// and thus should be combined into a single Unicode code point\n// using CreateCodePointFromUtf16SurrogatePair.\ninline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {\n  return sizeof(wchar_t) == 2 &&\n      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;\n}\n\n// Creates a Unicode code point from UTF16 surrogate pair.\ninline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,\n                                                    wchar_t second) {\n  const UInt32 mask = (1 << 10) - 1;\n  return (sizeof(wchar_t) == 2) ?\n      (((first & mask) << 10) | (second & mask)) + 0x10000 :\n      // This function should not be called when the condition is\n      // false, but we provide a sensible default in case it is.\n      static_cast<UInt32>(first);\n}\n\n// Converts a wide string to a narrow string in UTF-8 encoding.\n// The wide string is assumed to have the following encoding:\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\n// Parameter str points to a null-terminated wide string.\n// Parameter num_chars may additionally limit the number\n// of wchar_t characters processed. -1 is used when the entire string\n// should be processed.\n// If the string contains code points that are not valid Unicode code points\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\n// will be encoded as individual Unicode characters from Basic Normal Plane.\nString WideStringToUtf8(const wchar_t* str, int num_chars) {\n  if (num_chars == -1)\n    num_chars = static_cast<int>(wcslen(str));\n\n  ::std::stringstream stream;\n  for (int i = 0; i < num_chars; ++i) {\n    UInt32 unicode_code_point;\n\n    if (str[i] == L'\\0') {\n      break;\n    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {\n      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],\n                                                                 str[i + 1]);\n      i++;\n    } else {\n      unicode_code_point = static_cast<UInt32>(str[i]);\n    }\n\n    char buffer[32];  // CodePointToUtf8 requires a buffer this big.\n    stream << CodePointToUtf8(unicode_code_point, buffer);\n  }\n  return StringStreamToString(&stream);\n}\n\n// Converts a wide C string to a String using the UTF-8 encoding.\n// NULL will be converted to \"(null)\".\nString String::ShowWideCString(const wchar_t * wide_c_str) {\n  if (wide_c_str == NULL) return String(\"(null)\");\n\n  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());\n}\n\n// Similar to ShowWideCString(), except that this function encloses\n// the converted string in double quotes.\nString String::ShowWideCStringQuoted(const wchar_t* wide_c_str) {\n  if (wide_c_str == NULL) return String(\"(null)\");\n\n  return String::Format(\"L\\\"%s\\\"\",\n                        String::ShowWideCString(wide_c_str).c_str());\n}\n\n// Compares two wide C strings.  Returns true iff they have the same\n// content.\n//\n// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL\n// C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {\n  if (lhs == NULL) return rhs == NULL;\n\n  if (rhs == NULL) return false;\n\n  return wcscmp(lhs, rhs) == 0;\n}\n\n// Helper function for *_STREQ on wide strings.\nAssertionResult CmpHelperSTREQ(const char* expected_expression,\n                               const char* actual_expression,\n                               const wchar_t* expected,\n                               const wchar_t* actual) {\n  if (String::WideCStringEquals(expected, actual)) {\n    return AssertionSuccess();\n  }\n\n  return EqFailure(expected_expression,\n                   actual_expression,\n                   String::ShowWideCStringQuoted(expected),\n                   String::ShowWideCStringQuoted(actual),\n                   false);\n}\n\n// Helper function for *_STRNE on wide strings.\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\n                               const char* s2_expression,\n                               const wchar_t* s1,\n                               const wchar_t* s2) {\n  if (!String::WideCStringEquals(s1, s2)) {\n    return AssertionSuccess();\n  }\n\n  return AssertionFailure() << \"Expected: (\" << s1_expression << \") != (\"\n                            << s2_expression << \"), actual: \"\n                            << String::ShowWideCStringQuoted(s1)\n                            << \" vs \" << String::ShowWideCStringQuoted(s2);\n}\n\n// Compares two C strings, ignoring case.  Returns true iff they have\n// the same content.\n//\n// Unlike strcasecmp(), this function can handle NULL argument(s).  A\n// NULL C string is considered different to any non-NULL C string,\n// including the empty string.\nbool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {\n  if (lhs == NULL)\n    return rhs == NULL;\n  if (rhs == NULL)\n    return false;\n  return posix::StrCaseCmp(lhs, rhs) == 0;\n}\n\n  // Compares two wide C strings, ignoring case.  Returns true iff they\n  // have the same content.\n  //\n  // Unlike wcscasecmp(), this function can handle NULL argument(s).\n  // A NULL C string is considered different to any non-NULL wide C string,\n  // including the empty string.\n  // NB: The implementations on different platforms slightly differ.\n  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE\n  // environment variable. On GNU platform this method uses wcscasecmp\n  // which compares according to LC_CTYPE category of the current locale.\n  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\n  // current locale.\nbool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\n                                              const wchar_t* rhs) {\n  if (lhs == NULL) return rhs == NULL;\n\n  if (rhs == NULL) return false;\n\n#if GTEST_OS_WINDOWS\n  return _wcsicmp(lhs, rhs) == 0;\n#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID\n  return wcscasecmp(lhs, rhs) == 0;\n#else\n  // Android, Mac OS X and Cygwin don't define wcscasecmp.\n  // Other unknown OSes may not define it either.\n  wint_t left, right;\n  do {\n    left = towlower(*lhs++);\n    right = towlower(*rhs++);\n  } while (left && left == right);\n  return left == right;\n#endif  // OS selector\n}\n\n// Compares this with another String.\n// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0\n// if this is greater than rhs.\nint String::Compare(const String & rhs) const {\n  const char* const lhs_c_str = c_str();\n  const char* const rhs_c_str = rhs.c_str();\n\n  if (lhs_c_str == NULL) {\n    return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL\n  } else if (rhs_c_str == NULL) {\n    return 1;\n  }\n\n  const size_t shorter_str_len =\n      length() <= rhs.length() ? length() : rhs.length();\n  for (size_t i = 0; i != shorter_str_len; i++) {\n    if (lhs_c_str[i] < rhs_c_str[i]) {\n      return -1;\n    } else if (lhs_c_str[i] > rhs_c_str[i]) {\n      return 1;\n    }\n  }\n  return (length() < rhs.length()) ? -1 :\n      (length() > rhs.length()) ? 1 : 0;\n}\n\n// Returns true iff this String ends with the given suffix.  *Any*\n// String is considered to end with a NULL or empty suffix.\nbool String::EndsWith(const char* suffix) const {\n  if (suffix == NULL || CStringEquals(suffix, \"\")) return true;\n\n  if (c_str() == NULL) return false;\n\n  const size_t this_len = strlen(c_str());\n  const size_t suffix_len = strlen(suffix);\n  return (this_len >= suffix_len) &&\n         CStringEquals(c_str() + this_len - suffix_len, suffix);\n}\n\n// Returns true iff this String ends with the given suffix, ignoring case.\n// Any String is considered to end with a NULL or empty suffix.\nbool String::EndsWithCaseInsensitive(const char* suffix) const {\n  if (suffix == NULL || CStringEquals(suffix, \"\")) return true;\n\n  if (c_str() == NULL) return false;\n\n  const size_t this_len = strlen(c_str());\n  const size_t suffix_len = strlen(suffix);\n  return (this_len >= suffix_len) &&\n         CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix);\n}\n\n// Formats a list of arguments to a String, using the same format\n// spec string as for printf.\n//\n// We do not use the StringPrintf class as it is not universally\n// available.\n//\n// The result is limited to 4096 characters (including the tailing 0).\n// If 4096 characters are not enough to format the input, or if\n// there's an error, \"<formatting error or buffer exceeded>\" is\n// returned.\nString String::Format(const char * format, ...) {\n  va_list args;\n  va_start(args, format);\n\n  char buffer[4096];\n  const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);\n\n  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning\n  // 4996 (deprecated function) there.\n#ifdef _MSC_VER  // We are using MSVC.\n# pragma warning(push)          // Saves the current warning state.\n# pragma warning(disable:4996)  // Temporarily disables warning 4996.\n\n  const int size = vsnprintf(buffer, kBufferSize, format, args);\n\n# pragma warning(pop)           // Restores the warning state.\n#else  // We are not using MSVC.\n  const int size = vsnprintf(buffer, kBufferSize, format, args);\n#endif  // _MSC_VER\n  va_end(args);\n\n  // vsnprintf()'s behavior is not portable.  When the buffer is not\n  // big enough, it returns a negative value in MSVC, and returns the\n  // needed buffer size on Linux.  When there is an output error, it\n  // always returns a negative value.  For simplicity, we lump the two\n  // error cases together.\n  if (size < 0 || size >= kBufferSize) {\n    return String(\"<formatting error or buffer exceeded>\");\n  } else {\n    return String(buffer, size);\n  }\n}\n\n// Converts the buffer in a stringstream to a String, converting NUL\n// bytes to \"\\\\0\" along the way.\nString StringStreamToString(::std::stringstream* ss) {\n  const ::std::string& str = ss->str();\n  const char* const start = str.c_str();\n  const char* const end = start + str.length();\n\n  // We need to use a helper stringstream to do this transformation\n  // because String doesn't support push_back().\n  ::std::stringstream helper;\n  for (const char* ch = start; ch != end; ++ch) {\n    if (*ch == '\\0') {\n      helper << \"\\\\0\";  // Replaces NUL with \"\\\\0\";\n    } else {\n      helper.put(*ch);\n    }\n  }\n\n  return String(helper.str().c_str());\n}\n\n// Appends the user-supplied message to the Google-Test-generated message.\nString AppendUserMessage(const String& gtest_msg,\n                         const Message& user_msg) {\n  // Appends the user message if it's non-empty.\n  const String user_msg_string = user_msg.GetString();\n  if (user_msg_string.empty()) {\n    return gtest_msg;\n  }\n\n  Message msg;\n  msg << gtest_msg << \"\\n\" << user_msg_string;\n\n  return msg.GetString();\n}\n\n}  // namespace internal\n\n// class TestResult\n\n// Creates an empty TestResult.\nTestResult::TestResult()\n    : death_test_count_(0),\n      elapsed_time_(0) {\n}\n\n// D'tor.\nTestResult::~TestResult() {\n}\n\n// Returns the i-th test part result among all the results. i can\n// range from 0 to total_part_count() - 1. If i is not in that range,\n// aborts the program.\nconst TestPartResult& TestResult::GetTestPartResult(int i) const {\n  if (i < 0 || i >= total_part_count())\n    internal::posix::Abort();\n  return test_part_results_.at(i);\n}\n\n// Returns the i-th test property. i can range from 0 to\n// test_property_count() - 1. If i is not in that range, aborts the\n// program.\nconst TestProperty& TestResult::GetTestProperty(int i) const {\n  if (i < 0 || i >= test_property_count())\n    internal::posix::Abort();\n  return test_properties_.at(i);\n}\n\n// Clears the test part results.\nvoid TestResult::ClearTestPartResults() {\n  test_part_results_.clear();\n}\n\n// Adds a test part result to the list.\nvoid TestResult::AddTestPartResult(const TestPartResult& test_part_result) {\n  test_part_results_.push_back(test_part_result);\n}\n\n// Adds a test property to the list. If a property with the same key as the\n// supplied property is already represented, the value of this test_property\n// replaces the old value for that key.\nvoid TestResult::RecordProperty(const TestProperty& test_property) {\n  if (!ValidateTestProperty(test_property)) {\n    return;\n  }\n  internal::MutexLock lock(&test_properites_mutex_);\n  const std::vector<TestProperty>::iterator property_with_matching_key =\n      std::find_if(test_properties_.begin(), test_properties_.end(),\n                   internal::TestPropertyKeyIs(test_property.key()));\n  if (property_with_matching_key == test_properties_.end()) {\n    test_properties_.push_back(test_property);\n    return;\n  }\n  property_with_matching_key->SetValue(test_property.value());\n}\n\n// Adds a failure if the key is a reserved attribute of Google Test\n// testcase tags.  Returns true if the property is valid.\nbool TestResult::ValidateTestProperty(const TestProperty& test_property) {\n  internal::String key(test_property.key());\n  if (key == \"name\" || key == \"status\" || key == \"time\" || key == \"classname\") {\n    ADD_FAILURE()\n        << \"Reserved key used in RecordProperty(): \"\n        << key\n        << \" ('name', 'status', 'time', and 'classname' are reserved by \"\n        << GTEST_NAME_ << \")\";\n    return false;\n  }\n  return true;\n}\n\n// Clears the object.\nvoid TestResult::Clear() {\n  test_part_results_.clear();\n  test_properties_.clear();\n  death_test_count_ = 0;\n  elapsed_time_ = 0;\n}\n\n// Returns true iff the test failed.\nbool TestResult::Failed() const {\n  for (int i = 0; i < total_part_count(); ++i) {\n    if (GetTestPartResult(i).failed())\n      return true;\n  }\n  return false;\n}\n\n// Returns true iff the test part fatally failed.\nstatic bool TestPartFatallyFailed(const TestPartResult& result) {\n  return result.fatally_failed();\n}\n\n// Returns true iff the test fatally failed.\nbool TestResult::HasFatalFailure() const {\n  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;\n}\n\n// Returns true iff the test part non-fatally failed.\nstatic bool TestPartNonfatallyFailed(const TestPartResult& result) {\n  return result.nonfatally_failed();\n}\n\n// Returns true iff the test has a non-fatal failure.\nbool TestResult::HasNonfatalFailure() const {\n  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;\n}\n\n// Gets the number of all test parts.  This is the sum of the number\n// of successful test parts and the number of failed test parts.\nint TestResult::total_part_count() const {\n  return static_cast<int>(test_part_results_.size());\n}\n\n// Returns the number of the test properties.\nint TestResult::test_property_count() const {\n  return static_cast<int>(test_properties_.size());\n}\n\n// class Test\n\n// Creates a Test object.\n\n// The c'tor saves the values of all Google Test flags.\nTest::Test()\n    : gtest_flag_saver_(new internal::GTestFlagSaver) {\n}\n\n// The d'tor restores the values of all Google Test flags.\nTest::~Test() {\n  delete gtest_flag_saver_;\n}\n\n// Sets up the test fixture.\n//\n// A sub-class may override this.\nvoid Test::SetUp() {\n}\n\n// Tears down the test fixture.\n//\n// A sub-class may override this.\nvoid Test::TearDown() {\n}\n\n// Allows user supplied key value pairs to be recorded for later output.\nvoid Test::RecordProperty(const char* key, const char* value) {\n  UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value);\n}\n\n// Allows user supplied key value pairs to be recorded for later output.\nvoid Test::RecordProperty(const char* key, int value) {\n  Message value_message;\n  value_message << value;\n  RecordProperty(key, value_message.GetString().c_str());\n}\n\nnamespace internal {\n\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\n                                    const String& message) {\n  // This function is a friend of UnitTest and as such has access to\n  // AddTestPartResult.\n  UnitTest::GetInstance()->AddTestPartResult(\n      result_type,\n      NULL,  // No info about the source file where the exception occurred.\n      -1,    // We have no info on which line caused the exception.\n      message,\n      String());  // No stack trace, either.\n}\n\n}  // namespace internal\n\n// Google Test requires all tests in the same test case to use the same test\n// fixture class.  This function checks if the current test has the\n// same fixture class as the first test in the current test case.  If\n// yes, it returns true; otherwise it generates a Google Test failure and\n// returns false.\nbool Test::HasSameFixtureClass() {\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  const TestCase* const test_case = impl->current_test_case();\n\n  // Info about the first test in the current test case.\n  const TestInfo* const first_test_info = test_case->test_info_list()[0];\n  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;\n  const char* const first_test_name = first_test_info->name();\n\n  // Info about the current test.\n  const TestInfo* const this_test_info = impl->current_test_info();\n  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;\n  const char* const this_test_name = this_test_info->name();\n\n  if (this_fixture_id != first_fixture_id) {\n    // Is the first test defined using TEST?\n    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();\n    // Is this test defined using TEST?\n    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();\n\n    if (first_is_TEST || this_is_TEST) {\n      // The user mixed TEST and TEST_F in this test case - we'll tell\n      // him/her how to fix it.\n\n      // Gets the name of the TEST and the name of the TEST_F.  Note\n      // that first_is_TEST and this_is_TEST cannot both be true, as\n      // the fixture IDs are different for the two tests.\n      const char* const TEST_name =\n          first_is_TEST ? first_test_name : this_test_name;\n      const char* const TEST_F_name =\n          first_is_TEST ? this_test_name : first_test_name;\n\n      ADD_FAILURE()\n          << \"All tests in the same test case must use the same test fixture\\n\"\n          << \"class, so mixing TEST_F and TEST in the same test case is\\n\"\n          << \"illegal.  In test case \" << this_test_info->test_case_name()\n          << \",\\n\"\n          << \"test \" << TEST_F_name << \" is defined using TEST_F but\\n\"\n          << \"test \" << TEST_name << \" is defined using TEST.  You probably\\n\"\n          << \"want to change the TEST to TEST_F or move it to another test\\n\"\n          << \"case.\";\n    } else {\n      // The user defined two fixture classes with the same name in\n      // two namespaces - we'll tell him/her how to fix it.\n      ADD_FAILURE()\n          << \"All tests in the same test case must use the same test fixture\\n\"\n          << \"class.  However, in test case \"\n          << this_test_info->test_case_name() << \",\\n\"\n          << \"you defined test \" << first_test_name\n          << \" and test \" << this_test_name << \"\\n\"\n          << \"using two different test fixture classes.  This can happen if\\n\"\n          << \"the two classes are from different namespaces or translation\\n\"\n          << \"units and have the same name.  You should probably rename one\\n\"\n          << \"of the classes to put the tests into different test cases.\";\n    }\n    return false;\n  }\n\n  return true;\n}\n\n#if GTEST_HAS_SEH\n\n// Adds an \"exception thrown\" fatal failure to the current test.  This\n// function returns its result via an output parameter pointer because VC++\n// prohibits creation of objects with destructors on stack in functions\n// using __try (see error C2712).\nstatic internal::String* FormatSehExceptionMessage(DWORD exception_code,\n                                                   const char* location) {\n  Message message;\n  message << \"SEH exception with code 0x\" << std::setbase(16) <<\n    exception_code << std::setbase(10) << \" thrown in \" << location << \".\";\n\n  return new internal::String(message.GetString());\n}\n\n#endif  // GTEST_HAS_SEH\n\n#if GTEST_HAS_EXCEPTIONS\n\n// Adds an \"exception thrown\" fatal failure to the current test.\nstatic internal::String FormatCxxExceptionMessage(const char* description,\n                                                  const char* location) {\n  Message message;\n  if (description != NULL) {\n    message << \"C++ exception with description \\\"\" << description << \"\\\"\";\n  } else {\n    message << \"Unknown C++ exception\";\n  }\n  message << \" thrown in \" << location << \".\";\n\n  return message.GetString();\n}\n\nstatic internal::String PrintTestPartResultToString(\n    const TestPartResult& test_part_result);\n\n// A failed Google Test assertion will throw an exception of this type when\n// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled).  We\n// derive it from std::runtime_error, which is for errors presumably\n// detectable only at run time.  Since std::runtime_error inherits from\n// std::exception, many testing frameworks know how to extract and print the\n// message inside it.\nclass GoogleTestFailureException : public ::std::runtime_error {\n public:\n  explicit GoogleTestFailureException(const TestPartResult& failure)\n      : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}\n};\n#endif  // GTEST_HAS_EXCEPTIONS\n\nnamespace internal {\n// We put these helper functions in the internal namespace as IBM's xlC\n// compiler rejects the code if they were declared static.\n\n// Runs the given method and handles SEH exceptions it throws, when\n// SEH is supported; returns the 0-value for type Result in case of an\n// SEH exception.  (Microsoft compilers cannot handle SEH and C++\n// exceptions in the same function.  Therefore, we provide a separate\n// wrapper function for handling SEH exceptions.)\ntemplate <class T, typename Result>\nResult HandleSehExceptionsInMethodIfSupported(\n    T* object, Result (T::*method)(), const char* location) {\n#if GTEST_HAS_SEH\n  __try {\n    return (object->*method)();\n  } __except (internal::UnitTestOptions::GTestShouldProcessSEH(  // NOLINT\n      GetExceptionCode())) {\n    // We create the exception message on the heap because VC++ prohibits\n    // creation of objects with destructors on stack in functions using __try\n    // (see error C2712).\n    internal::String* exception_message = FormatSehExceptionMessage(\n        GetExceptionCode(), location);\n    internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,\n                                             *exception_message);\n    delete exception_message;\n    return static_cast<Result>(0);\n  }\n#else\n  (void)location;\n  return (object->*method)();\n#endif  // GTEST_HAS_SEH\n}\n\n// Runs the given method and catches and reports C++ and/or SEH-style\n// exceptions, if they are supported; returns the 0-value for type\n// Result in case of an SEH exception.\ntemplate <class T, typename Result>\nResult HandleExceptionsInMethodIfSupported(\n    T* object, Result (T::*method)(), const char* location) {\n  // NOTE: The user code can affect the way in which Google Test handles\n  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before\n  // RUN_ALL_TESTS() starts. It is technically possible to check the flag\n  // after the exception is caught and either report or re-throw the\n  // exception based on the flag's value:\n  //\n  // try {\n  //   // Perform the test method.\n  // } catch (...) {\n  //   if (GTEST_FLAG(catch_exceptions))\n  //     // Report the exception as failure.\n  //   else\n  //     throw;  // Re-throws the original exception.\n  // }\n  //\n  // However, the purpose of this flag is to allow the program to drop into\n  // the debugger when the exception is thrown. On most platforms, once the\n  // control enters the catch block, the exception origin information is\n  // lost and the debugger will stop the program at the point of the\n  // re-throw in this function -- instead of at the point of the original\n  // throw statement in the code under test.  For this reason, we perform\n  // the check early, sacrificing the ability to affect Google Test's\n  // exception handling in the method where the exception is thrown.\n  if (internal::GetUnitTestImpl()->catch_exceptions()) {\n#if GTEST_HAS_EXCEPTIONS\n    try {\n      return HandleSehExceptionsInMethodIfSupported(object, method, location);\n    } catch (const GoogleTestFailureException&) {  // NOLINT\n      // This exception doesn't originate in code under test. It makes no\n      // sense to report it as a test failure.\n      throw;\n    } catch (const std::exception& e) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(e.what(), location));\n    } catch (...) {  // NOLINT\n      internal::ReportFailureInUnknownLocation(\n          TestPartResult::kFatalFailure,\n          FormatCxxExceptionMessage(NULL, location));\n    }\n    return static_cast<Result>(0);\n#else\n    return HandleSehExceptionsInMethodIfSupported(object, method, location);\n#endif  // GTEST_HAS_EXCEPTIONS\n  } else {\n    return (object->*method)();\n  }\n}\n\n}  // namespace internal\n\n// Runs the test and updates the test result.\nvoid Test::Run() {\n  if (!HasSameFixtureClass()) return;\n\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, \"SetUp()\");\n  // We will run the test only if SetUp() was successful.\n  if (!HasFatalFailure()) {\n    impl->os_stack_trace_getter()->UponLeavingGTest();\n    internal::HandleExceptionsInMethodIfSupported(\n        this, &Test::TestBody, \"the test body\");\n  }\n\n  // However, we want to clean up as much as possible.  Hence we will\n  // always call TearDown(), even if SetUp() or the test body has\n  // failed.\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &Test::TearDown, \"TearDown()\");\n}\n\n// Returns true iff the current test has a fatal failure.\nbool Test::HasFatalFailure() {\n  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();\n}\n\n// Returns true iff the current test has a non-fatal failure.\nbool Test::HasNonfatalFailure() {\n  return internal::GetUnitTestImpl()->current_test_result()->\n      HasNonfatalFailure();\n}\n\n// class TestInfo\n\n// Constructs a TestInfo object. It assumes ownership of the test factory\n// object.\n// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s\n// to signify they cannot be NULLs.\nTestInfo::TestInfo(const char* a_test_case_name,\n                   const char* a_name,\n                   const char* a_type_param,\n                   const char* a_value_param,\n                   internal::TypeId fixture_class_id,\n                   internal::TestFactoryBase* factory)\n    : test_case_name_(a_test_case_name),\n      name_(a_name),\n      type_param_(a_type_param ? new std::string(a_type_param) : NULL),\n      value_param_(a_value_param ? new std::string(a_value_param) : NULL),\n      fixture_class_id_(fixture_class_id),\n      should_run_(false),\n      is_disabled_(false),\n      matches_filter_(false),\n      factory_(factory),\n      result_() {}\n\n// Destructs a TestInfo object.\nTestInfo::~TestInfo() { delete factory_; }\n\nnamespace internal {\n\n// Creates a new TestInfo object and registers it with Google Test;\n// returns the created object.\n//\n// Arguments:\n//\n//   test_case_name:   name of the test case\n//   name:             name of the test\n//   type_param:       the name of the test's type parameter, or NULL if\n//                     this is not a typed or a type-parameterized test.\n//   value_param:      text representation of the test's value parameter,\n//                     or NULL if this is not a value-parameterized test.\n//   fixture_class_id: ID of the test fixture class\n//   set_up_tc:        pointer to the function that sets up the test case\n//   tear_down_tc:     pointer to the function that tears down the test case\n//   factory:          pointer to the factory that creates a test object.\n//                     The newly created TestInfo instance will assume\n//                     ownership of the factory object.\nTestInfo* MakeAndRegisterTestInfo(\n    const char* test_case_name, const char* name,\n    const char* type_param,\n    const char* value_param,\n    TypeId fixture_class_id,\n    SetUpTestCaseFunc set_up_tc,\n    TearDownTestCaseFunc tear_down_tc,\n    TestFactoryBase* factory) {\n  TestInfo* const test_info =\n      new TestInfo(test_case_name, name, type_param, value_param,\n                   fixture_class_id, factory);\n  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);\n  return test_info;\n}\n\n#if GTEST_HAS_PARAM_TEST\nvoid ReportInvalidTestCaseType(const char* test_case_name,\n                               const char* file, int line) {\n  Message errors;\n  errors\n      << \"Attempted redefinition of test case \" << test_case_name << \".\\n\"\n      << \"All tests in the same test case must use the same test fixture\\n\"\n      << \"class.  However, in test case \" << test_case_name << \", you tried\\n\"\n      << \"to define a test using a fixture class different from the one\\n\"\n      << \"used earlier. This can happen if the two fixture classes are\\n\"\n      << \"from different namespaces and have the same name. You should\\n\"\n      << \"probably rename one of the classes to put the tests into different\\n\"\n      << \"test cases.\";\n\n  fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\n          errors.GetString().c_str());\n}\n#endif  // GTEST_HAS_PARAM_TEST\n\n}  // namespace internal\n\nnamespace {\n\n// A predicate that checks the test name of a TestInfo against a known\n// value.\n//\n// This is used for implementation of the TestCase class only.  We put\n// it in the anonymous namespace to prevent polluting the outer\n// namespace.\n//\n// TestNameIs is copyable.\nclass TestNameIs {\n public:\n  // Constructor.\n  //\n  // TestNameIs has NO default constructor.\n  explicit TestNameIs(const char* name)\n      : name_(name) {}\n\n  // Returns true iff the test name of test_info matches name_.\n  bool operator()(const TestInfo * test_info) const {\n    return test_info && internal::String(test_info->name()).Compare(name_) == 0;\n  }\n\n private:\n  internal::String name_;\n};\n\n}  // namespace\n\nnamespace internal {\n\n// This method expands all parameterized tests registered with macros TEST_P\n// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.\n// This will be done just once during the program runtime.\nvoid UnitTestImpl::RegisterParameterizedTests() {\n#if GTEST_HAS_PARAM_TEST\n  if (!parameterized_tests_registered_) {\n    parameterized_test_registry_.RegisterTests();\n    parameterized_tests_registered_ = true;\n  }\n#endif\n}\n\n}  // namespace internal\n\n// Creates the test object, runs it, records its result, and then\n// deletes it.\nvoid TestInfo::Run() {\n  if (!should_run_) return;\n\n  // Tells UnitTest where to store test result.\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  impl->set_current_test_info(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  // Notifies the unit test event listeners that a test is about to start.\n  repeater->OnTestStart(*this);\n\n  const TimeInMillis start = internal::GetTimeInMillis();\n\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n\n  // Creates the test object.\n  Test* const test = internal::HandleExceptionsInMethodIfSupported(\n      factory_, &internal::TestFactoryBase::CreateTest,\n      \"the test fixture's constructor\");\n\n  // Runs the test only if the test object was created and its\n  // constructor didn't generate a fatal failure.\n  if ((test != NULL) && !Test::HasFatalFailure()) {\n    // This doesn't throw as all user code that can throw are wrapped into\n    // exception handling code.\n    test->Run();\n  }\n\n  // Deletes the test object.\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      test, &Test::DeleteSelf_, \"the test fixture's destructor\");\n\n  result_.set_elapsed_time(internal::GetTimeInMillis() - start);\n\n  // Notifies the unit test event listener that a test has just finished.\n  repeater->OnTestEnd(*this);\n\n  // Tells UnitTest to stop associating assertion results to this\n  // test.\n  impl->set_current_test_info(NULL);\n}\n\n// class TestCase\n\n// Gets the number of successful tests in this test case.\nint TestCase::successful_test_count() const {\n  return CountIf(test_info_list_, TestPassed);\n}\n\n// Gets the number of failed tests in this test case.\nint TestCase::failed_test_count() const {\n  return CountIf(test_info_list_, TestFailed);\n}\n\nint TestCase::disabled_test_count() const {\n  return CountIf(test_info_list_, TestDisabled);\n}\n\n// Get the number of tests in this test case that should run.\nint TestCase::test_to_run_count() const {\n  return CountIf(test_info_list_, ShouldRunTest);\n}\n\n// Gets the number of all tests.\nint TestCase::total_test_count() const {\n  return static_cast<int>(test_info_list_.size());\n}\n\n// Creates a TestCase with the given name.\n//\n// Arguments:\n//\n//   name:         name of the test case\n//   a_type_param: the name of the test case's type parameter, or NULL if\n//                 this is not a typed or a type-parameterized test case.\n//   set_up_tc:    pointer to the function that sets up the test case\n//   tear_down_tc: pointer to the function that tears down the test case\nTestCase::TestCase(const char* a_name, const char* a_type_param,\n                   Test::SetUpTestCaseFunc set_up_tc,\n                   Test::TearDownTestCaseFunc tear_down_tc)\n    : name_(a_name),\n      type_param_(a_type_param ? new std::string(a_type_param) : NULL),\n      set_up_tc_(set_up_tc),\n      tear_down_tc_(tear_down_tc),\n      should_run_(false),\n      elapsed_time_(0) {\n}\n\n// Destructor of TestCase.\nTestCase::~TestCase() {\n  // Deletes every Test in the collection.\n  ForEach(test_info_list_, internal::Delete<TestInfo>);\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nconst TestInfo* TestCase::GetTestInfo(int i) const {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? NULL : test_info_list_[index];\n}\n\n// Returns the i-th test among all the tests. i can range from 0 to\n// total_test_count() - 1. If i is not in that range, returns NULL.\nTestInfo* TestCase::GetMutableTestInfo(int i) {\n  const int index = GetElementOr(test_indices_, i, -1);\n  return index < 0 ? NULL : test_info_list_[index];\n}\n\n// Adds a test to this test case.  Will delete the test upon\n// destruction of the TestCase object.\nvoid TestCase::AddTestInfo(TestInfo * test_info) {\n  test_info_list_.push_back(test_info);\n  test_indices_.push_back(static_cast<int>(test_indices_.size()));\n}\n\n// Runs every test in this TestCase.\nvoid TestCase::Run() {\n  if (!should_run_) return;\n\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\n  impl->set_current_test_case(this);\n\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\n\n  repeater->OnTestCaseStart(*this);\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestCase::RunSetUpTestCase, \"SetUpTestCase()\");\n\n  const internal::TimeInMillis start = internal::GetTimeInMillis();\n  for (int i = 0; i < total_test_count(); i++) {\n    GetMutableTestInfo(i)->Run();\n  }\n  elapsed_time_ = internal::GetTimeInMillis() - start;\n\n  impl->os_stack_trace_getter()->UponLeavingGTest();\n  internal::HandleExceptionsInMethodIfSupported(\n      this, &TestCase::RunTearDownTestCase, \"TearDownTestCase()\");\n\n  repeater->OnTestCaseEnd(*this);\n  impl->set_current_test_case(NULL);\n}\n\n// Clears the results of all tests in this test case.\nvoid TestCase::ClearResult() {\n  ForEach(test_info_list_, TestInfo::ClearTestResult);\n}\n\n// Shuffles the tests in this test case.\nvoid TestCase::ShuffleTests(internal::Random* random) {\n  Shuffle(random, &test_indices_);\n}\n\n// Restores the test order to before the first shuffle.\nvoid TestCase::UnshuffleTests() {\n  for (size_t i = 0; i < test_indices_.size(); i++) {\n    test_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Formats a countable noun.  Depending on its quantity, either the\n// singular form or the plural form is used. e.g.\n//\n// FormatCountableNoun(1, \"formula\", \"formuli\") returns \"1 formula\".\n// FormatCountableNoun(5, \"book\", \"books\") returns \"5 books\".\nstatic internal::String FormatCountableNoun(int count,\n                                            const char * singular_form,\n                                            const char * plural_form) {\n  return internal::String::Format(\"%d %s\", count,\n                                  count == 1 ? singular_form : plural_form);\n}\n\n// Formats the count of tests.\nstatic internal::String FormatTestCount(int test_count) {\n  return FormatCountableNoun(test_count, \"test\", \"tests\");\n}\n\n// Formats the count of test cases.\nstatic internal::String FormatTestCaseCount(int test_case_count) {\n  return FormatCountableNoun(test_case_count, \"test case\", \"test cases\");\n}\n\n// Converts a TestPartResult::Type enum to human-friendly string\n// representation.  Both kNonFatalFailure and kFatalFailure are translated\n// to \"Failure\", as the user usually doesn't care about the difference\n// between the two when viewing the test result.\nstatic const char * TestPartResultTypeToString(TestPartResult::Type type) {\n  switch (type) {\n    case TestPartResult::kSuccess:\n      return \"Success\";\n\n    case TestPartResult::kNonFatalFailure:\n    case TestPartResult::kFatalFailure:\n#ifdef _MSC_VER\n      return \"error: \";\n#else\n      return \"Failure\\n\";\n#endif\n    default:\n      return \"Unknown result type\";\n  }\n}\n\n// Prints a TestPartResult to a String.\nstatic internal::String PrintTestPartResultToString(\n    const TestPartResult& test_part_result) {\n  return (Message()\n          << internal::FormatFileLocation(test_part_result.file_name(),\n                                          test_part_result.line_number())\n          << \" \" << TestPartResultTypeToString(test_part_result.type())\n          << test_part_result.message()).GetString();\n}\n\n// Prints a TestPartResult.\nstatic void PrintTestPartResult(const TestPartResult& test_part_result) {\n  const internal::String& result =\n      PrintTestPartResultToString(test_part_result);\n  printf(\"%s\\n\", result.c_str());\n  fflush(stdout);\n  // If the test program runs in Visual Studio or a debugger, the\n  // following statements add the test part result message to the Output\n  // window such that the user can double-click on it to jump to the\n  // corresponding source code location; otherwise they do nothing.\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n  // We don't call OutputDebugString*() on Windows Mobile, as printing\n  // to stdout is done by OutputDebugString() there already - we don't\n  // want the same message printed twice.\n  ::OutputDebugStringA(result.c_str());\n  ::OutputDebugStringA(\"\\n\");\n#endif\n}\n\n// class PrettyUnitTestResultPrinter\n\nnamespace internal {\n\nenum GTestColor {\n  COLOR_DEFAULT,\n  COLOR_RED,\n  COLOR_GREEN,\n  COLOR_YELLOW\n};\n\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n\n// Returns the character attribute for the given color.\nWORD GetColorAttribute(GTestColor color) {\n  switch (color) {\n    case COLOR_RED:    return FOREGROUND_RED;\n    case COLOR_GREEN:  return FOREGROUND_GREEN;\n    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;\n    default:           return 0;\n  }\n}\n\n#else\n\n// Returns the ANSI color code for the given color.  COLOR_DEFAULT is\n// an invalid input.\nconst char* GetAnsiColorCode(GTestColor color) {\n  switch (color) {\n    case COLOR_RED:     return \"1\";\n    case COLOR_GREEN:   return \"2\";\n    case COLOR_YELLOW:  return \"3\";\n    default:            return NULL;\n  };\n}\n\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n\n// Returns true iff Google Test should use colors in the output.\nbool ShouldUseColor(bool stdout_is_tty) {\n  const char* const gtest_color = GTEST_FLAG(color).c_str();\n\n  if (String::CaseInsensitiveCStringEquals(gtest_color, \"auto\")) {\n#if GTEST_OS_WINDOWS\n    // On Windows the TERM variable is usually not set, but the\n    // console there does support colors.\n    return stdout_is_tty;\n#else\n    // On non-Windows platforms, we rely on the TERM variable.\n    const char* const term = posix::GetEnv(\"TERM\");\n    const bool term_supports_color =\n        String::CStringEquals(term, \"xterm\") ||\n        String::CStringEquals(term, \"xterm-color\") ||\n        String::CStringEquals(term, \"xterm-256color\") ||\n        String::CStringEquals(term, \"screen\") ||\n        String::CStringEquals(term, \"linux\") ||\n        String::CStringEquals(term, \"cygwin\");\n    return stdout_is_tty && term_supports_color;\n#endif  // GTEST_OS_WINDOWS\n  }\n\n  return String::CaseInsensitiveCStringEquals(gtest_color, \"yes\") ||\n      String::CaseInsensitiveCStringEquals(gtest_color, \"true\") ||\n      String::CaseInsensitiveCStringEquals(gtest_color, \"t\") ||\n      String::CStringEquals(gtest_color, \"1\");\n  // We take \"yes\", \"true\", \"t\", and \"1\" as meaning \"yes\".  If the\n  // value is neither one of these nor \"auto\", we treat it as \"no\" to\n  // be conservative.\n}\n\n// Helpers for printing colored strings to stdout. Note that on Windows, we\n// cannot simply emit special characters and have the terminal change colors.\n// This routine must actually emit the characters rather than return a string\n// that would be colored when printed, as can be done on Linux.\nvoid ColoredPrintf(GTestColor color, const char* fmt, ...) {\n  va_list args;\n  va_start(args, fmt);\n\n#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS\n  const bool use_color = false;\n#else\n  static const bool in_color_mode =\n      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);\n  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);\n#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS\n  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.\n\n  if (!use_color) {\n    vprintf(fmt, args);\n    va_end(args);\n    return;\n  }\n\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\n\n  // Gets the current text color.\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\n  const WORD old_color_attrs = buffer_info.wAttributes;\n\n  // We need to flush the stream buffers into the console before each\n  // SetConsoleTextAttribute call lest it affect the text that is already\n  // printed but has not yet reached the console.\n  fflush(stdout);\n  SetConsoleTextAttribute(stdout_handle,\n                          GetColorAttribute(color) | FOREGROUND_INTENSITY);\n  vprintf(fmt, args);\n\n  fflush(stdout);\n  // Restores the text color.\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\n#else\n  printf(\"\\033[0;3%sm\", GetAnsiColorCode(color));\n  vprintf(fmt, args);\n  printf(\"\\033[m\");  // Resets the terminal to default.\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\n  va_end(args);\n}\n\nvoid PrintFullTestCommentIfPresent(const TestInfo& test_info) {\n  const char* const type_param = test_info.type_param();\n  const char* const value_param = test_info.value_param();\n\n  if (type_param != NULL || value_param != NULL) {\n    printf(\", where \");\n    if (type_param != NULL) {\n      printf(\"TypeParam = %s\", type_param);\n      if (value_param != NULL)\n        printf(\" and \");\n    }\n    if (value_param != NULL) {\n      printf(\"GetParam() = %s\", value_param);\n    }\n  }\n}\n\n// This class implements the TestEventListener interface.\n//\n// Class PrettyUnitTestResultPrinter is copyable.\nclass PrettyUnitTestResultPrinter : public TestEventListener {\n public:\n  PrettyUnitTestResultPrinter() {}\n  static void PrintTestName(const char * test_case, const char * test) {\n    printf(\"%s.%s\", test_case, test);\n  }\n\n  // The following methods override what's in the TestEventListener class.\n  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestCaseStart(const TestCase& test_case);\n  virtual void OnTestStart(const TestInfo& test_info);\n  virtual void OnTestPartResult(const TestPartResult& result);\n  virtual void OnTestEnd(const TestInfo& test_info);\n  virtual void OnTestCaseEnd(const TestCase& test_case);\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\n  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}\n\n private:\n  static void PrintFailedTests(const UnitTest& unit_test);\n\n  internal::String test_case_name_;\n};\n\n  // Fired before each iteration of tests starts.\nvoid PrettyUnitTestResultPrinter::OnTestIterationStart(\n    const UnitTest& unit_test, int iteration) {\n  if (GTEST_FLAG(repeat) != 1)\n    printf(\"\\nRepeating all tests (iteration %d) . . .\\n\\n\", iteration + 1);\n\n  const char* const filter = GTEST_FLAG(filter).c_str();\n\n  // Prints the filter if it's not *.  This reminds the user that some\n  // tests may be skipped.\n  if (!internal::String::CStringEquals(filter, kUniversalFilter)) {\n    ColoredPrintf(COLOR_YELLOW,\n                  \"Note: %s filter = %s\\n\", GTEST_NAME_, filter);\n  }\n\n  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {\n    const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);\n    ColoredPrintf(COLOR_YELLOW,\n                  \"Note: This is test shard %d of %s.\\n\",\n                  static_cast<int>(shard_index) + 1,\n                  internal::posix::GetEnv(kTestTotalShards));\n  }\n\n  if (GTEST_FLAG(shuffle)) {\n    ColoredPrintf(COLOR_YELLOW,\n                  \"Note: Randomizing tests' orders with a seed of %d .\\n\",\n                  unit_test.random_seed());\n  }\n\n  ColoredPrintf(COLOR_GREEN,  \"[==========] \");\n  printf(\"Running %s from %s.\\n\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(COLOR_GREEN,  \"[----------] \");\n  printf(\"Global test environment set-up.\\n\");\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {\n  test_case_name_ = test_case.name();\n  const internal::String counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(COLOR_GREEN, \"[----------] \");\n  printf(\"%s from %s\", counts.c_str(), test_case_name_.c_str());\n  if (test_case.type_param() == NULL) {\n    printf(\"\\n\");\n  } else {\n    printf(\", where TypeParam = %s\\n\", test_case.type_param());\n  }\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {\n  ColoredPrintf(COLOR_GREEN,  \"[ RUN      ] \");\n  PrintTestName(test_case_name_.c_str(), test_info.name());\n  printf(\"\\n\");\n  fflush(stdout);\n}\n\n// Called after an assertion failure.\nvoid PrettyUnitTestResultPrinter::OnTestPartResult(\n    const TestPartResult& result) {\n  // If the test part succeeded, we don't need to do anything.\n  if (result.type() == TestPartResult::kSuccess)\n    return;\n\n  // Print failure message from the assertion (e.g. expected this and got that).\n  PrintTestPartResult(result);\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\n  if (test_info.result()->Passed()) {\n    ColoredPrintf(COLOR_GREEN, \"[       OK ] \");\n  } else {\n    ColoredPrintf(COLOR_RED, \"[  FAILED  ] \");\n  }\n  PrintTestName(test_case_name_.c_str(), test_info.name());\n  if (test_info.result()->Failed())\n    PrintFullTestCommentIfPresent(test_info);\n\n  if (GTEST_FLAG(print_time)) {\n    printf(\" (%s ms)\\n\", internal::StreamableToString(\n           test_info.result()->elapsed_time()).c_str());\n  } else {\n    printf(\"\\n\");\n  }\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {\n  if (!GTEST_FLAG(print_time)) return;\n\n  test_case_name_ = test_case.name();\n  const internal::String counts =\n      FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\n  ColoredPrintf(COLOR_GREEN, \"[----------] \");\n  printf(\"%s from %s (%s ms total)\\n\\n\",\n         counts.c_str(), test_case_name_.c_str(),\n         internal::StreamableToString(test_case.elapsed_time()).c_str());\n  fflush(stdout);\n}\n\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(\n    const UnitTest& /*unit_test*/) {\n  ColoredPrintf(COLOR_GREEN,  \"[----------] \");\n  printf(\"Global test environment tear-down\\n\");\n  fflush(stdout);\n}\n\n// Internal helper for printing the list of failed tests.\nvoid PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {\n  const int failed_test_count = unit_test.failed_test_count();\n  if (failed_test_count == 0) {\n    return;\n  }\n\n  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {\n    const TestCase& test_case = *unit_test.GetTestCase(i);\n    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {\n      continue;\n    }\n    for (int j = 0; j < test_case.total_test_count(); ++j) {\n      const TestInfo& test_info = *test_case.GetTestInfo(j);\n      if (!test_info.should_run() || test_info.result()->Passed()) {\n        continue;\n      }\n      ColoredPrintf(COLOR_RED, \"[  FAILED  ] \");\n      printf(\"%s.%s\", test_case.name(), test_info.name());\n      PrintFullTestCommentIfPresent(test_info);\n      printf(\"\\n\");\n    }\n  }\n}\n\nvoid PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                     int /*iteration*/) {\n  ColoredPrintf(COLOR_GREEN,  \"[==========] \");\n  printf(\"%s from %s ran.\",\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\n         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());\n  if (GTEST_FLAG(print_time)) {\n    printf(\" (%s ms total)\",\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\n  }\n  printf(\"\\n\");\n  ColoredPrintf(COLOR_GREEN,  \"[  PASSED  ] \");\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\n\n  int num_failures = unit_test.failed_test_count();\n  if (!unit_test.Passed()) {\n    const int failed_test_count = unit_test.failed_test_count();\n    ColoredPrintf(COLOR_RED,  \"[  FAILED  ] \");\n    printf(\"%s, listed below:\\n\", FormatTestCount(failed_test_count).c_str());\n    PrintFailedTests(unit_test);\n    printf(\"\\n%2d FAILED %s\\n\", num_failures,\n                        num_failures == 1 ? \"TEST\" : \"TESTS\");\n  }\n\n  int num_disabled = unit_test.disabled_test_count();\n  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {\n    if (!num_failures) {\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\n    }\n    ColoredPrintf(COLOR_YELLOW,\n                  \"  YOU HAVE %d DISABLED %s\\n\\n\",\n                  num_disabled,\n                  num_disabled == 1 ? \"TEST\" : \"TESTS\");\n  }\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\n  fflush(stdout);\n}\n\n// End PrettyUnitTestResultPrinter\n\n// class TestEventRepeater\n//\n// This class forwards events to other event listeners.\nclass TestEventRepeater : public TestEventListener {\n public:\n  TestEventRepeater() : forwarding_enabled_(true) {}\n  virtual ~TestEventRepeater();\n  void Append(TestEventListener *listener);\n  TestEventListener* Release(TestEventListener* listener);\n\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled() const { return forwarding_enabled_; }\n  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }\n\n  virtual void OnTestProgramStart(const UnitTest& unit_test);\n  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);\n  virtual void OnTestCaseStart(const TestCase& test_case);\n  virtual void OnTestStart(const TestInfo& test_info);\n  virtual void OnTestPartResult(const TestPartResult& result);\n  virtual void OnTestEnd(const TestInfo& test_info);\n  virtual void OnTestCaseEnd(const TestCase& test_case);\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\n  virtual void OnTestProgramEnd(const UnitTest& unit_test);\n\n private:\n  // Controls whether events will be forwarded to listeners_. Set to false\n  // in death test child processes.\n  bool forwarding_enabled_;\n  // The list of listeners that receive events.\n  std::vector<TestEventListener*> listeners_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);\n};\n\nTestEventRepeater::~TestEventRepeater() {\n  ForEach(listeners_, Delete<TestEventListener>);\n}\n\nvoid TestEventRepeater::Append(TestEventListener *listener) {\n  listeners_.push_back(listener);\n}\n\n// TODO(vladl@google.com): Factor the search functionality into Vector::Find.\nTestEventListener* TestEventRepeater::Release(TestEventListener *listener) {\n  for (size_t i = 0; i < listeners_.size(); ++i) {\n    if (listeners_[i] == listener) {\n      listeners_.erase(listeners_.begin() + i);\n      return listener;\n    }\n  }\n\n  return NULL;\n}\n\n// Since most methods are very similar, use macros to reduce boilerplate.\n// This defines a member that forwards the call to all listeners.\n#define GTEST_REPEATER_METHOD_(Name, Type) \\\nvoid TestEventRepeater::Name(const Type& parameter) { \\\n  if (forwarding_enabled_) { \\\n    for (size_t i = 0; i < listeners_.size(); i++) { \\\n      listeners_[i]->Name(parameter); \\\n    } \\\n  } \\\n}\n// This defines a member that forwards the call to all listeners in reverse\n// order.\n#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \\\nvoid TestEventRepeater::Name(const Type& parameter) { \\\n  if (forwarding_enabled_) { \\\n    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \\\n      listeners_[i]->Name(parameter); \\\n    } \\\n  } \\\n}\n\nGTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)\nGTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)\nGTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)\nGTEST_REPEATER_METHOD_(OnTestStart, TestInfo)\nGTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)\nGTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)\nGTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)\n\n#undef GTEST_REPEATER_METHOD_\n#undef GTEST_REVERSE_REPEATER_METHOD_\n\nvoid TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,\n                                             int iteration) {\n  if (forwarding_enabled_) {\n    for (size_t i = 0; i < listeners_.size(); i++) {\n      listeners_[i]->OnTestIterationStart(unit_test, iteration);\n    }\n  }\n}\n\nvoid TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,\n                                           int iteration) {\n  if (forwarding_enabled_) {\n    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {\n      listeners_[i]->OnTestIterationEnd(unit_test, iteration);\n    }\n  }\n}\n\n// End TestEventRepeater\n\n// This class generates an XML output file.\nclass XmlUnitTestResultPrinter : public EmptyTestEventListener {\n public:\n  explicit XmlUnitTestResultPrinter(const char* output_file);\n\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\n\n private:\n  // Is c a whitespace character that is normalized to a space character\n  // when it appears in an XML attribute value?\n  static bool IsNormalizableWhitespace(char c) {\n    return c == 0x9 || c == 0xA || c == 0xD;\n  }\n\n  // May c appear in a well-formed XML document?\n  static bool IsValidXmlCharacter(char c) {\n    return IsNormalizableWhitespace(c) || c >= 0x20;\n  }\n\n  // Returns an XML-escaped copy of the input string str.  If\n  // is_attribute is true, the text is meant to appear as an attribute\n  // value, and normalizable whitespace is preserved by replacing it\n  // with character references.\n  static String EscapeXml(const char* str, bool is_attribute);\n\n  // Returns the given string with all characters invalid in XML removed.\n  static string RemoveInvalidXmlCharacters(const string& str);\n\n  // Convenience wrapper around EscapeXml when str is an attribute value.\n  static String EscapeXmlAttribute(const char* str) {\n    return EscapeXml(str, true);\n  }\n\n  // Convenience wrapper around EscapeXml when str is not an attribute value.\n  static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }\n\n  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\n  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);\n\n  // Streams an XML representation of a TestInfo object.\n  static void OutputXmlTestInfo(::std::ostream* stream,\n                                const char* test_case_name,\n                                const TestInfo& test_info);\n\n  // Prints an XML representation of a TestCase object\n  static void PrintXmlTestCase(FILE* out, const TestCase& test_case);\n\n  // Prints an XML summary of unit_test to output stream out.\n  static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);\n\n  // Produces a string representing the test properties in a result as space\n  // delimited XML attributes based on the property key=\"value\" pairs.\n  // When the String is not empty, it includes a space at the beginning,\n  // to delimit this attribute from prior attributes.\n  static String TestPropertiesAsXmlAttributes(const TestResult& result);\n\n  // The output file.\n  const String output_file_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);\n};\n\n// Creates a new XmlUnitTestResultPrinter.\nXmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)\n    : output_file_(output_file) {\n  if (output_file_.c_str() == NULL || output_file_.empty()) {\n    fprintf(stderr, \"XML output file may not be null\\n\");\n    fflush(stderr);\n    exit(EXIT_FAILURE);\n  }\n}\n\n// Called after the unit test ends.\nvoid XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\n                                                  int /*iteration*/) {\n  FILE* xmlout = NULL;\n  FilePath output_file(output_file_);\n  FilePath output_dir(output_file.RemoveFileName());\n\n  if (output_dir.CreateDirectoriesRecursively()) {\n    xmlout = posix::FOpen(output_file_.c_str(), \"w\");\n  }\n  if (xmlout == NULL) {\n    // TODO(wan): report the reason of the failure.\n    //\n    // We don't do it for now as:\n    //\n    //   1. There is no urgent need for it.\n    //   2. It's a bit involved to make the errno variable thread-safe on\n    //      all three operating systems (Linux, Windows, and Mac OS).\n    //   3. To interpret the meaning of errno in a thread-safe way,\n    //      we need the strerror_r() function, which is not available on\n    //      Windows.\n    fprintf(stderr,\n            \"Unable to open file \\\"%s\\\"\\n\",\n            output_file_.c_str());\n    fflush(stderr);\n    exit(EXIT_FAILURE);\n  }\n  PrintXmlUnitTest(xmlout, unit_test);\n  fclose(xmlout);\n}\n\n// Returns an XML-escaped copy of the input string str.  If is_attribute\n// is true, the text is meant to appear as an attribute value, and\n// normalizable whitespace is preserved by replacing it with character\n// references.\n//\n// Invalid XML characters in str, if any, are stripped from the output.\n// It is expected that most, if not all, of the text processed by this\n// module will consist of ordinary English text.\n// If this module is ever modified to produce version 1.1 XML output,\n// most invalid characters can be retained using character references.\n// TODO(wan): It might be nice to have a minimally invasive, human-readable\n// escaping scheme for invalid characters, rather than dropping them.\nString XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) {\n  Message m;\n\n  if (str != NULL) {\n    for (const char* src = str; *src; ++src) {\n      switch (*src) {\n        case '<':\n          m << \"&lt;\";\n          break;\n        case '>':\n          m << \"&gt;\";\n          break;\n        case '&':\n          m << \"&amp;\";\n          break;\n        case '\\'':\n          if (is_attribute)\n            m << \"&apos;\";\n          else\n            m << '\\'';\n          break;\n        case '\"':\n          if (is_attribute)\n            m << \"&quot;\";\n          else\n            m << '\"';\n          break;\n        default:\n          if (IsValidXmlCharacter(*src)) {\n            if (is_attribute && IsNormalizableWhitespace(*src))\n              m << String::Format(\"&#x%02X;\", unsigned(*src));\n            else\n              m << *src;\n          }\n          break;\n      }\n    }\n  }\n\n  return m.GetString();\n}\n\n// Returns the given string with all characters invalid in XML removed.\n// Currently invalid characters are dropped from the string. An\n// alternative is to replace them with certain characters such as . or ?.\nstring XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) {\n  string output;\n  output.reserve(str.size());\n  for (string::const_iterator it = str.begin(); it != str.end(); ++it)\n    if (IsValidXmlCharacter(*it))\n      output.push_back(*it);\n\n  return output;\n}\n\n// The following routines generate an XML representation of a UnitTest\n// object.\n//\n// This is how Google Test concepts map to the DTD:\n//\n// <testsuites name=\"AllTests\">        <-- corresponds to a UnitTest object\n//   <testsuite name=\"testcase-name\">  <-- corresponds to a TestCase object\n//     <testcase name=\"test-name\">     <-- corresponds to a TestInfo object\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//       <failure message=\"...\">...</failure>\n//                                     <-- individual assertion failures\n//     </testcase>\n//   </testsuite>\n// </testsuites>\n\n// Formats the given time in milliseconds as seconds.\nstd::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {\n  ::std::stringstream ss;\n  ss << ms/1000.0;\n  return ss.str();\n}\n\n// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\nvoid XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,\n                                                     const char* data) {\n  const char* segment = data;\n  *stream << \"<![CDATA[\";\n  for (;;) {\n    const char* const next_segment = strstr(segment, \"]]>\");\n    if (next_segment != NULL) {\n      stream->write(\n          segment, static_cast<std::streamsize>(next_segment - segment));\n      *stream << \"]]>]]&gt;<![CDATA[\";\n      segment = next_segment + strlen(\"]]>\");\n    } else {\n      *stream << segment;\n      break;\n    }\n  }\n  *stream << \"]]>\";\n}\n\n// Prints an XML representation of a TestInfo object.\n// TODO(wan): There is also value in printing properties with the plain printer.\nvoid XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,\n                                                 const char* test_case_name,\n                                                 const TestInfo& test_info) {\n  const TestResult& result = *test_info.result();\n  *stream << \"    <testcase name=\\\"\"\n          << EscapeXmlAttribute(test_info.name()).c_str() << \"\\\"\";\n\n  if (test_info.value_param() != NULL) {\n    *stream << \" value_param=\\\"\" << EscapeXmlAttribute(test_info.value_param())\n            << \"\\\"\";\n  }\n  if (test_info.type_param() != NULL) {\n    *stream << \" type_param=\\\"\" << EscapeXmlAttribute(test_info.type_param())\n            << \"\\\"\";\n  }\n\n  *stream << \" status=\\\"\"\n          << (test_info.should_run() ? \"run\" : \"notrun\")\n          << \"\\\" time=\\\"\"\n          << FormatTimeInMillisAsSeconds(result.elapsed_time())\n          << \"\\\" classname=\\\"\" << EscapeXmlAttribute(test_case_name).c_str()\n          << \"\\\"\" << TestPropertiesAsXmlAttributes(result).c_str();\n\n  int failures = 0;\n  for (int i = 0; i < result.total_part_count(); ++i) {\n    const TestPartResult& part = result.GetTestPartResult(i);\n    if (part.failed()) {\n      if (++failures == 1)\n        *stream << \">\\n\";\n      *stream << \"      <failure message=\\\"\"\n              << EscapeXmlAttribute(part.summary()).c_str()\n              << \"\\\" type=\\\"\\\">\";\n      const string location = internal::FormatCompilerIndependentFileLocation(\n          part.file_name(), part.line_number());\n      const string message = location + \"\\n\" + part.message();\n      OutputXmlCDataSection(stream,\n                            RemoveInvalidXmlCharacters(message).c_str());\n      *stream << \"</failure>\\n\";\n    }\n  }\n\n  if (failures == 0)\n    *stream << \" />\\n\";\n  else\n    *stream << \"    </testcase>\\n\";\n}\n\n// Prints an XML representation of a TestCase object\nvoid XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,\n                                                const TestCase& test_case) {\n  fprintf(out,\n          \"  <testsuite name=\\\"%s\\\" tests=\\\"%d\\\" failures=\\\"%d\\\" \"\n          \"disabled=\\\"%d\\\" \",\n          EscapeXmlAttribute(test_case.name()).c_str(),\n          test_case.total_test_count(),\n          test_case.failed_test_count(),\n          test_case.disabled_test_count());\n  fprintf(out,\n          \"errors=\\\"0\\\" time=\\\"%s\\\">\\n\",\n          FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());\n  for (int i = 0; i < test_case.total_test_count(); ++i) {\n    ::std::stringstream stream;\n    OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));\n    fprintf(out, \"%s\", StringStreamToString(&stream).c_str());\n  }\n  fprintf(out, \"  </testsuite>\\n\");\n}\n\n// Prints an XML summary of unit_test to output stream out.\nvoid XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,\n                                                const UnitTest& unit_test) {\n  fprintf(out, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n  fprintf(out,\n          \"<testsuites tests=\\\"%d\\\" failures=\\\"%d\\\" disabled=\\\"%d\\\" \"\n          \"errors=\\\"0\\\" time=\\\"%s\\\" \",\n          unit_test.total_test_count(),\n          unit_test.failed_test_count(),\n          unit_test.disabled_test_count(),\n          FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());\n  if (GTEST_FLAG(shuffle)) {\n    fprintf(out, \"random_seed=\\\"%d\\\" \", unit_test.random_seed());\n  }\n  fprintf(out, \"name=\\\"AllTests\\\">\\n\");\n  for (int i = 0; i < unit_test.total_test_case_count(); ++i)\n    PrintXmlTestCase(out, *unit_test.GetTestCase(i));\n  fprintf(out, \"</testsuites>\\n\");\n}\n\n// Produces a string representing the test properties in a result as space\n// delimited XML attributes based on the property key=\"value\" pairs.\nString XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(\n    const TestResult& result) {\n  Message attributes;\n  for (int i = 0; i < result.test_property_count(); ++i) {\n    const TestProperty& property = result.GetTestProperty(i);\n    attributes << \" \" << property.key() << \"=\"\n        << \"\\\"\" << EscapeXmlAttribute(property.value()) << \"\\\"\";\n  }\n  return attributes.GetString();\n}\n\n// End XmlUnitTestResultPrinter\n\n#if GTEST_CAN_STREAM_RESULTS_\n\n// Streams test results to the given port on the given host machine.\nclass StreamingListener : public EmptyTestEventListener {\n public:\n  // Escapes '=', '&', '%', and '\\n' characters in str as \"%xx\".\n  static string UrlEncode(const char* str);\n\n  StreamingListener(const string& host, const string& port)\n      : sockfd_(-1), host_name_(host), port_num_(port) {\n    MakeConnection();\n    Send(\"gtest_streaming_protocol_version=1.0\\n\");\n  }\n\n  virtual ~StreamingListener() {\n    if (sockfd_ != -1)\n      CloseConnection();\n  }\n\n  void OnTestProgramStart(const UnitTest& /* unit_test */) {\n    Send(\"event=TestProgramStart\\n\");\n  }\n\n  void OnTestProgramEnd(const UnitTest& unit_test) {\n    // Note that Google Test current only report elapsed time for each\n    // test iteration, not for the entire test program.\n    Send(String::Format(\"event=TestProgramEnd&passed=%d\\n\",\n                        unit_test.Passed()));\n\n    // Notify the streaming server to stop.\n    CloseConnection();\n  }\n\n  void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {\n    Send(String::Format(\"event=TestIterationStart&iteration=%d\\n\",\n                        iteration));\n  }\n\n  void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {\n    Send(String::Format(\"event=TestIterationEnd&passed=%d&elapsed_time=%sms\\n\",\n                        unit_test.Passed(),\n                        StreamableToString(unit_test.elapsed_time()).c_str()));\n  }\n\n  void OnTestCaseStart(const TestCase& test_case) {\n    Send(String::Format(\"event=TestCaseStart&name=%s\\n\", test_case.name()));\n  }\n\n  void OnTestCaseEnd(const TestCase& test_case) {\n    Send(String::Format(\"event=TestCaseEnd&passed=%d&elapsed_time=%sms\\n\",\n                        test_case.Passed(),\n                        StreamableToString(test_case.elapsed_time()).c_str()));\n  }\n\n  void OnTestStart(const TestInfo& test_info) {\n    Send(String::Format(\"event=TestStart&name=%s\\n\", test_info.name()));\n  }\n\n  void OnTestEnd(const TestInfo& test_info) {\n    Send(String::Format(\n        \"event=TestEnd&passed=%d&elapsed_time=%sms\\n\",\n        (test_info.result())->Passed(),\n        StreamableToString((test_info.result())->elapsed_time()).c_str()));\n  }\n\n  void OnTestPartResult(const TestPartResult& test_part_result) {\n    const char* file_name = test_part_result.file_name();\n    if (file_name == NULL)\n      file_name = \"\";\n    Send(String::Format(\"event=TestPartResult&file=%s&line=%d&message=\",\n                        UrlEncode(file_name).c_str(),\n                        test_part_result.line_number()));\n    Send(UrlEncode(test_part_result.message()) + \"\\n\");\n  }\n\n private:\n  // Creates a client socket and connects to the server.\n  void MakeConnection();\n\n  // Closes the socket.\n  void CloseConnection() {\n    GTEST_CHECK_(sockfd_ != -1)\n        << \"CloseConnection() can be called only when there is a connection.\";\n\n    close(sockfd_);\n    sockfd_ = -1;\n  }\n\n  // Sends a string to the socket.\n  void Send(const string& message) {\n    GTEST_CHECK_(sockfd_ != -1)\n        << \"Send() can be called only when there is a connection.\";\n\n    const int len = static_cast<int>(message.length());\n    if (write(sockfd_, message.c_str(), len) != len) {\n      GTEST_LOG_(WARNING)\n          << \"stream_result_to: failed to stream to \"\n          << host_name_ << \":\" << port_num_;\n    }\n  }\n\n  int sockfd_;   // socket file descriptor\n  const string host_name_;\n  const string port_num_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);\n};  // class StreamingListener\n\n// Checks if str contains '=', '&', '%' or '\\n' characters. If yes,\n// replaces them by \"%xx\" where xx is their hexadecimal value. For\n// example, replaces \"=\" with \"%3D\".  This algorithm is O(strlen(str))\n// in both time and space -- important as the input str may contain an\n// arbitrarily long test failure message and stack trace.\nstring StreamingListener::UrlEncode(const char* str) {\n  string result;\n  result.reserve(strlen(str) + 1);\n  for (char ch = *str; ch != '\\0'; ch = *++str) {\n    switch (ch) {\n      case '%':\n      case '=':\n      case '&':\n      case '\\n':\n        result.append(String::Format(\"%%%02x\", static_cast<unsigned char>(ch)));\n        break;\n      default:\n        result.push_back(ch);\n        break;\n    }\n  }\n  return result;\n}\n\nvoid StreamingListener::MakeConnection() {\n  GTEST_CHECK_(sockfd_ == -1)\n      << \"MakeConnection() can't be called when there is already a connection.\";\n\n  addrinfo hints;\n  memset(&hints, 0, sizeof(hints));\n  hints.ai_family = AF_UNSPEC;    // To allow both IPv4 and IPv6 addresses.\n  hints.ai_socktype = SOCK_STREAM;\n  addrinfo* servinfo = NULL;\n\n  // Use the getaddrinfo() to get a linked list of IP addresses for\n  // the given host name.\n  const int error_num = getaddrinfo(\n      host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);\n  if (error_num != 0) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: getaddrinfo() failed: \"\n                        << gai_strerror(error_num);\n  }\n\n  // Loop through all the results and connect to the first we can.\n  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;\n       cur_addr = cur_addr->ai_next) {\n    sockfd_ = socket(\n        cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);\n    if (sockfd_ != -1) {\n      // Connect the client socket to the server socket.\n      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {\n        close(sockfd_);\n        sockfd_ = -1;\n      }\n    }\n  }\n\n  freeaddrinfo(servinfo);  // all done with this structure\n\n  if (sockfd_ == -1) {\n    GTEST_LOG_(WARNING) << \"stream_result_to: failed to connect to \"\n                        << host_name_ << \":\" << port_num_;\n  }\n}\n\n// End of class Streaming Listener\n#endif  // GTEST_CAN_STREAM_RESULTS__\n\n// Class ScopedTrace\n\n// Pushes the given source file location and message onto a per-thread\n// trace stack maintained by Google Test.\n// L < UnitTest::mutex_\nScopedTrace::ScopedTrace(const char* file, int line, const Message& message) {\n  TraceInfo trace;\n  trace.file = file;\n  trace.line = line;\n  trace.message = message.GetString();\n\n  UnitTest::GetInstance()->PushGTestTrace(trace);\n}\n\n// Pops the info pushed by the c'tor.\n// L < UnitTest::mutex_\nScopedTrace::~ScopedTrace() {\n  UnitTest::GetInstance()->PopGTestTrace();\n}\n\n\n// class OsStackTraceGetter\n\n// Returns the current OS stack trace as a String.  Parameters:\n//\n//   max_depth  - the maximum number of stack frames to be included\n//                in the trace.\n//   skip_count - the number of top frames to be skipped; doesn't count\n//                against max_depth.\n//\n// L < mutex_\n// We use \"L < mutex_\" to denote that the function may acquire mutex_.\nString OsStackTraceGetter::CurrentStackTrace(int, int) {\n  return String(\"\");\n}\n\n// L < mutex_\nvoid OsStackTraceGetter::UponLeavingGTest() {\n}\n\nconst char* const\nOsStackTraceGetter::kElidedFramesMarker =\n    \"... \" GTEST_NAME_ \" internal frames ...\";\n\n}  // namespace internal\n\n// class TestEventListeners\n\nTestEventListeners::TestEventListeners()\n    : repeater_(new internal::TestEventRepeater()),\n      default_result_printer_(NULL),\n      default_xml_generator_(NULL) {\n}\n\nTestEventListeners::~TestEventListeners() { delete repeater_; }\n\n// Returns the standard listener responsible for the default console\n// output.  Can be removed from the listeners list to shut down default\n// console output.  Note that removing this object from the listener list\n// with Release transfers its ownership to the user.\nvoid TestEventListeners::Append(TestEventListener* listener) {\n  repeater_->Append(listener);\n}\n\n// Removes the given event listener from the list and returns it.  It then\n// becomes the caller's responsibility to delete the listener. Returns\n// NULL if the listener is not found in the list.\nTestEventListener* TestEventListeners::Release(TestEventListener* listener) {\n  if (listener == default_result_printer_)\n    default_result_printer_ = NULL;\n  else if (listener == default_xml_generator_)\n    default_xml_generator_ = NULL;\n  return repeater_->Release(listener);\n}\n\n// Returns repeater that broadcasts the TestEventListener events to all\n// subscribers.\nTestEventListener* TestEventListeners::repeater() { return repeater_; }\n\n// Sets the default_result_printer attribute to the provided listener.\n// The listener is also added to the listener list and previous\n// default_result_printer is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {\n  if (default_result_printer_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_result_printer_);\n    default_result_printer_ = listener;\n    if (listener != NULL)\n      Append(listener);\n  }\n}\n\n// Sets the default_xml_generator attribute to the provided listener.  The\n// listener is also added to the listener list and previous\n// default_xml_generator is removed from it and deleted. The listener can\n// also be NULL in which case it will not be added to the list. Does\n// nothing if the previous and the current listener objects are the same.\nvoid TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {\n  if (default_xml_generator_ != listener) {\n    // It is an error to pass this method a listener that is already in the\n    // list.\n    delete Release(default_xml_generator_);\n    default_xml_generator_ = listener;\n    if (listener != NULL)\n      Append(listener);\n  }\n}\n\n// Controls whether events will be forwarded by the repeater to the\n// listeners in the list.\nbool TestEventListeners::EventForwardingEnabled() const {\n  return repeater_->forwarding_enabled();\n}\n\nvoid TestEventListeners::SuppressEventForwarding() {\n  repeater_->set_forwarding_enabled(false);\n}\n\n// class UnitTest\n\n// Gets the singleton UnitTest object.  The first time this method is\n// called, a UnitTest object is constructed and returned.  Consecutive\n// calls will return the same object.\n//\n// We don't protect this under mutex_ as a user is not supposed to\n// call this before main() starts, from which point on the return\n// value will never change.\nUnitTest * UnitTest::GetInstance() {\n  // When compiled with MSVC 7.1 in optimized mode, destroying the\n  // UnitTest object upon exiting the program messes up the exit code,\n  // causing successful tests to appear failed.  We have to use a\n  // different implementation in this case to bypass the compiler bug.\n  // This implementation makes the compiler happy, at the cost of\n  // leaking the UnitTest object.\n\n  // CodeGear C++Builder insists on a public destructor for the\n  // default implementation.  Use this implementation to keep good OO\n  // design with private destructor.\n\n#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)\n  static UnitTest* const instance = new UnitTest;\n  return instance;\n#else\n  static UnitTest instance;\n  return &instance;\n#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)\n}\n\n// Gets the number of successful test cases.\nint UnitTest::successful_test_case_count() const {\n  return impl()->successful_test_case_count();\n}\n\n// Gets the number of failed test cases.\nint UnitTest::failed_test_case_count() const {\n  return impl()->failed_test_case_count();\n}\n\n// Gets the number of all test cases.\nint UnitTest::total_test_case_count() const {\n  return impl()->total_test_case_count();\n}\n\n// Gets the number of all test cases that contain at least one test\n// that should run.\nint UnitTest::test_case_to_run_count() const {\n  return impl()->test_case_to_run_count();\n}\n\n// Gets the number of successful tests.\nint UnitTest::successful_test_count() const {\n  return impl()->successful_test_count();\n}\n\n// Gets the number of failed tests.\nint UnitTest::failed_test_count() const { return impl()->failed_test_count(); }\n\n// Gets the number of disabled tests.\nint UnitTest::disabled_test_count() const {\n  return impl()->disabled_test_count();\n}\n\n// Gets the number of all tests.\nint UnitTest::total_test_count() const { return impl()->total_test_count(); }\n\n// Gets the number of tests that should run.\nint UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }\n\n// Gets the elapsed time, in milliseconds.\ninternal::TimeInMillis UnitTest::elapsed_time() const {\n  return impl()->elapsed_time();\n}\n\n// Returns true iff the unit test passed (i.e. all test cases passed).\nbool UnitTest::Passed() const { return impl()->Passed(); }\n\n// Returns true iff the unit test failed (i.e. some test case failed\n// or something outside of all tests failed).\nbool UnitTest::Failed() const { return impl()->Failed(); }\n\n// Gets the i-th test case among all the test cases. i can range from 0 to\n// total_test_case_count() - 1. If i is not in that range, returns NULL.\nconst TestCase* UnitTest::GetTestCase(int i) const {\n  return impl()->GetTestCase(i);\n}\n\n// Gets the i-th test case among all the test cases. i can range from 0 to\n// total_test_case_count() - 1. If i is not in that range, returns NULL.\nTestCase* UnitTest::GetMutableTestCase(int i) {\n  return impl()->GetMutableTestCase(i);\n}\n\n// Returns the list of event listeners that can be used to track events\n// inside Google Test.\nTestEventListeners& UnitTest::listeners() {\n  return *impl()->listeners();\n}\n\n// Registers and returns a global test environment.  When a test\n// program is run, all global test environments will be set-up in the\n// order they were registered.  After all tests in the program have\n// finished, all global test environments will be torn-down in the\n// *reverse* order they were registered.\n//\n// The UnitTest object takes ownership of the given environment.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nEnvironment* UnitTest::AddEnvironment(Environment* env) {\n  if (env == NULL) {\n    return NULL;\n  }\n\n  impl_->environments().push_back(env);\n  return env;\n}\n\n// Adds a TestPartResult to the current TestResult object.  All Google Test\n// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call\n// this to report their results.  The user code should use the\n// assertion macros instead of calling this directly.\n// L < mutex_\nvoid UnitTest::AddTestPartResult(TestPartResult::Type result_type,\n                                 const char* file_name,\n                                 int line_number,\n                                 const internal::String& message,\n                                 const internal::String& os_stack_trace) {\n  Message msg;\n  msg << message;\n\n  internal::MutexLock lock(&mutex_);\n  if (impl_->gtest_trace_stack().size() > 0) {\n    msg << \"\\n\" << GTEST_NAME_ << \" trace:\";\n\n    for (int i = static_cast<int>(impl_->gtest_trace_stack().size());\n         i > 0; --i) {\n      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];\n      msg << \"\\n\" << internal::FormatFileLocation(trace.file, trace.line)\n          << \" \" << trace.message;\n    }\n  }\n\n  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {\n    msg << internal::kStackTraceMarker << os_stack_trace;\n  }\n\n  const TestPartResult result =\n    TestPartResult(result_type, file_name, line_number,\n                   msg.GetString().c_str());\n  impl_->GetTestPartResultReporterForCurrentThread()->\n      ReportTestPartResult(result);\n\n  if (result_type != TestPartResult::kSuccess) {\n    // gtest_break_on_failure takes precedence over\n    // gtest_throw_on_failure.  This allows a user to set the latter\n    // in the code (perhaps in order to use Google Test assertions\n    // with another testing framework) and specify the former on the\n    // command line for debugging.\n    if (GTEST_FLAG(break_on_failure)) {\n#if GTEST_OS_WINDOWS\n      // Using DebugBreak on Windows allows gtest to still break into a debugger\n      // when a failure happens and both the --gtest_break_on_failure and\n      // the --gtest_catch_exceptions flags are specified.\n      DebugBreak();\n#else\n      // Dereference NULL through a volatile pointer to prevent the compiler\n      // from removing. We use this rather than abort() or __builtin_trap() for\n      // portability: Symbian doesn't implement abort() well, and some debuggers\n      // don't correctly trap abort().\n      *static_cast<volatile int*>(NULL) = 1;\n#endif  // GTEST_OS_WINDOWS\n    } else if (GTEST_FLAG(throw_on_failure)) {\n#if GTEST_HAS_EXCEPTIONS\n      throw GoogleTestFailureException(result);\n#else\n      // We cannot call abort() as it generates a pop-up in debug mode\n      // that cannot be suppressed in VC 7.1 or below.\n      exit(1);\n#endif\n    }\n  }\n}\n\n// Creates and adds a property to the current TestResult. If a property matching\n// the supplied value already exists, updates its value instead.\nvoid UnitTest::RecordPropertyForCurrentTest(const char* key,\n                                            const char* value) {\n  const TestProperty test_property(key, value);\n  impl_->current_test_result()->RecordProperty(test_property);\n}\n\n// Runs all tests in this UnitTest object and prints the result.\n// Returns 0 if successful, or 1 otherwise.\n//\n// We don't protect this under mutex_, as we only support calling it\n// from the main thread.\nint UnitTest::Run() {\n  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be\n  // used for the duration of the program.\n  impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));\n\n#if GTEST_HAS_SEH\n  const bool in_death_test_child_process =\n      internal::GTEST_FLAG(internal_run_death_test).length() > 0;\n\n  // Either the user wants Google Test to catch exceptions thrown by the\n  // tests or this is executing in the context of death test child\n  // process. In either case the user does not want to see pop-up dialogs\n  // about crashes - they are expected.\n  if (impl()->catch_exceptions() || in_death_test_child_process) {\n\n# if !GTEST_OS_WINDOWS_MOBILE\n    // SetErrorMode doesn't exist on CE.\n    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |\n                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\n# endif  // !GTEST_OS_WINDOWS_MOBILE\n\n# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE\n    // Death test children can be terminated with _abort().  On Windows,\n    // _abort() can show a dialog with a warning message.  This forces the\n    // abort message to go to stderr instead.\n    _set_error_mode(_OUT_TO_STDERR);\n# endif\n\n# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE\n    // In the debug version, Visual Studio pops up a separate dialog\n    // offering a choice to debug the aborted program. We need to suppress\n    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement\n    // executed. Google Test will notify the user of any unexpected\n    // failure via stderr.\n    //\n    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.\n    // Users of prior VC versions shall suffer the agony and pain of\n    // clicking through the countless debug dialogs.\n    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the\n    // debug mode when compiled with VC 7.1 or lower.\n    if (!GTEST_FLAG(break_on_failure))\n      _set_abort_behavior(\n          0x0,                                    // Clear the following flags:\n          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.\n# endif\n\n#if _MSC_VER >= 1310 && !GTEST_OS_WINDOWS_MOBILE\n    // Suppress the \"Debug Assertion Failed\" dialog in the debug mode. (As far\n    // as I know, these functions are available on Visual Studio .NET 2003 or\n    // later.)\n    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);\n    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);\n    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);\n#endif\n\n  }\n#endif  // GTEST_HAS_SEH\n\n  return internal::HandleExceptionsInMethodIfSupported(\n      impl(),\n      &internal::UnitTestImpl::RunAllTests,\n      \"auxiliary test code (environments or event listeners)\") ? 0 : 1;\n}\n\n// Returns the working directory when the first TEST() or TEST_F() was\n// executed.\nconst char* UnitTest::original_working_dir() const {\n  return impl_->original_working_dir_.c_str();\n}\n\n// Returns the TestCase object for the test that's currently running,\n// or NULL if no test is running.\n// L < mutex_\nconst TestCase* UnitTest::current_test_case() const {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_case();\n}\n\n// Returns the TestInfo object for the test that's currently running,\n// or NULL if no test is running.\n// L < mutex_\nconst TestInfo* UnitTest::current_test_info() const {\n  internal::MutexLock lock(&mutex_);\n  return impl_->current_test_info();\n}\n\n// Returns the random seed used at the start of the current test run.\nint UnitTest::random_seed() const { return impl_->random_seed(); }\n\n#if GTEST_HAS_PARAM_TEST\n// Returns ParameterizedTestCaseRegistry object used to keep track of\n// value-parameterized tests and instantiate and register them.\n// L < mutex_\ninternal::ParameterizedTestCaseRegistry&\n    UnitTest::parameterized_test_registry() {\n  return impl_->parameterized_test_registry();\n}\n#endif  // GTEST_HAS_PARAM_TEST\n\n// Creates an empty UnitTest.\nUnitTest::UnitTest() {\n  impl_ = new internal::UnitTestImpl(this);\n}\n\n// Destructor of UnitTest.\nUnitTest::~UnitTest() {\n  delete impl_;\n}\n\n// Pushes a trace defined by SCOPED_TRACE() on to the per-thread\n// Google Test trace stack.\n// L < mutex_\nvoid UnitTest::PushGTestTrace(const internal::TraceInfo& trace) {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().push_back(trace);\n}\n\n// Pops a trace from the per-thread Google Test trace stack.\n// L < mutex_\nvoid UnitTest::PopGTestTrace() {\n  internal::MutexLock lock(&mutex_);\n  impl_->gtest_trace_stack().pop_back();\n}\n\nnamespace internal {\n\nUnitTestImpl::UnitTestImpl(UnitTest* parent)\n    : parent_(parent),\n#ifdef _MSC_VER\n# pragma warning(push)                    // Saves the current warning state.\n# pragma warning(disable:4355)            // Temporarily disables warning 4355\n                                         // (using this in initializer).\n      default_global_test_part_result_reporter_(this),\n      default_per_thread_test_part_result_reporter_(this),\n# pragma warning(pop)                     // Restores the warning state again.\n#else\n      default_global_test_part_result_reporter_(this),\n      default_per_thread_test_part_result_reporter_(this),\n#endif  // _MSC_VER\n      global_test_part_result_repoter_(\n          &default_global_test_part_result_reporter_),\n      per_thread_test_part_result_reporter_(\n          &default_per_thread_test_part_result_reporter_),\n#if GTEST_HAS_PARAM_TEST\n      parameterized_test_registry_(),\n      parameterized_tests_registered_(false),\n#endif  // GTEST_HAS_PARAM_TEST\n      last_death_test_case_(-1),\n      current_test_case_(NULL),\n      current_test_info_(NULL),\n      ad_hoc_test_result_(),\n      os_stack_trace_getter_(NULL),\n      post_flag_parse_init_performed_(false),\n      random_seed_(0),  // Will be overridden by the flag before first use.\n      random_(0),  // Will be reseeded before first use.\n      elapsed_time_(0),\n#if GTEST_HAS_DEATH_TEST\n      internal_run_death_test_flag_(NULL),\n      death_test_factory_(new DefaultDeathTestFactory),\n#endif\n      // Will be overridden by the flag before first use.\n      catch_exceptions_(false) {\n  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);\n}\n\nUnitTestImpl::~UnitTestImpl() {\n  // Deletes every TestCase.\n  ForEach(test_cases_, internal::Delete<TestCase>);\n\n  // Deletes every Environment.\n  ForEach(environments_, internal::Delete<Environment>);\n\n  delete os_stack_trace_getter_;\n}\n\n#if GTEST_HAS_DEATH_TEST\n// Disables event forwarding if the control is currently in a death test\n// subprocess. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::SuppressTestEventsIfInSubprocess() {\n  if (internal_run_death_test_flag_.get() != NULL)\n    listeners()->SuppressEventForwarding();\n}\n#endif  // GTEST_HAS_DEATH_TEST\n\n// Initializes event listeners performing XML output as specified by\n// UnitTestOptions. Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureXmlOutput() {\n  const String& output_format = UnitTestOptions::GetOutputFormat();\n  if (output_format == \"xml\") {\n    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(\n        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\n  } else if (output_format != \"\") {\n    printf(\"WARNING: unrecognized output format \\\"%s\\\" ignored.\\n\",\n           output_format.c_str());\n    fflush(stdout);\n  }\n}\n\n#if GTEST_CAN_STREAM_RESULTS_\n// Initializes event listeners for streaming test results in String form.\n// Must not be called before InitGoogleTest.\nvoid UnitTestImpl::ConfigureStreamingOutput() {\n  const string& target = GTEST_FLAG(stream_result_to);\n  if (!target.empty()) {\n    const size_t pos = target.find(':');\n    if (pos != string::npos) {\n      listeners()->Append(new StreamingListener(target.substr(0, pos),\n                                                target.substr(pos+1)));\n    } else {\n      printf(\"WARNING: unrecognized streaming target \\\"%s\\\" ignored.\\n\",\n             target.c_str());\n      fflush(stdout);\n    }\n  }\n}\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\n// Performs initialization dependent upon flag values obtained in\n// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\n// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\n// this function is also called from RunAllTests.  Since this function can be\n// called more than once, it has to be idempotent.\nvoid UnitTestImpl::PostFlagParsingInit() {\n  // Ensures that this function does not execute more than once.\n  if (!post_flag_parse_init_performed_) {\n    post_flag_parse_init_performed_ = true;\n\n#if GTEST_HAS_DEATH_TEST\n    InitDeathTestSubprocessControlInfo();\n    SuppressTestEventsIfInSubprocess();\n#endif  // GTEST_HAS_DEATH_TEST\n\n    // Registers parameterized tests. This makes parameterized tests\n    // available to the UnitTest reflection API without running\n    // RUN_ALL_TESTS.\n    RegisterParameterizedTests();\n\n    // Configures listeners for XML output. This makes it possible for users\n    // to shut down the default XML output before invoking RUN_ALL_TESTS.\n    ConfigureXmlOutput();\n\n#if GTEST_CAN_STREAM_RESULTS_\n    // Configures listeners for streaming test results to the specified server.\n    ConfigureStreamingOutput();\n#endif  // GTEST_CAN_STREAM_RESULTS_\n  }\n}\n\n// A predicate that checks the name of a TestCase against a known\n// value.\n//\n// This is used for implementation of the UnitTest class only.  We put\n// it in the anonymous namespace to prevent polluting the outer\n// namespace.\n//\n// TestCaseNameIs is copyable.\nclass TestCaseNameIs {\n public:\n  // Constructor.\n  explicit TestCaseNameIs(const String& name)\n      : name_(name) {}\n\n  // Returns true iff the name of test_case matches name_.\n  bool operator()(const TestCase* test_case) const {\n    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;\n  }\n\n private:\n  String name_;\n};\n\n// Finds and returns a TestCase with the given name.  If one doesn't\n// exist, creates one and returns it.  It's the CALLER'S\n// RESPONSIBILITY to ensure that this function is only called WHEN THE\n// TESTS ARE NOT SHUFFLED.\n//\n// Arguments:\n//\n//   test_case_name: name of the test case\n//   type_param:     the name of the test case's type parameter, or NULL if\n//                   this is not a typed or a type-parameterized test case.\n//   set_up_tc:      pointer to the function that sets up the test case\n//   tear_down_tc:   pointer to the function that tears down the test case\nTestCase* UnitTestImpl::GetTestCase(const char* test_case_name,\n                                    const char* type_param,\n                                    Test::SetUpTestCaseFunc set_up_tc,\n                                    Test::TearDownTestCaseFunc tear_down_tc) {\n  // Can we find a TestCase with the given name?\n  const std::vector<TestCase*>::const_iterator test_case =\n      std::find_if(test_cases_.begin(), test_cases_.end(),\n                   TestCaseNameIs(test_case_name));\n\n  if (test_case != test_cases_.end())\n    return *test_case;\n\n  // No.  Let's create one.\n  TestCase* const new_test_case =\n      new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);\n\n  // Is this a death test case?\n  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),\n                                               kDeathTestCaseFilter)) {\n    // Yes.  Inserts the test case after the last death test case\n    // defined so far.  This only works when the test cases haven't\n    // been shuffled.  Otherwise we may end up running a death test\n    // after a non-death test.\n    ++last_death_test_case_;\n    test_cases_.insert(test_cases_.begin() + last_death_test_case_,\n                       new_test_case);\n  } else {\n    // No.  Appends to the end of the list.\n    test_cases_.push_back(new_test_case);\n  }\n\n  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));\n  return new_test_case;\n}\n\n// Helpers for setting up / tearing down the given environment.  They\n// are for use in the ForEach() function.\nstatic void SetUpEnvironment(Environment* env) { env->SetUp(); }\nstatic void TearDownEnvironment(Environment* env) { env->TearDown(); }\n\n// Runs all tests in this UnitTest object, prints the result, and\n// returns true if all tests are successful.  If any exception is\n// thrown during a test, the test is considered to be failed, but the\n// rest of the tests will still be run.\n//\n// When parameterized tests are enabled, it expands and registers\n// parameterized tests first in RegisterParameterizedTests().\n// All other functions called from RunAllTests() may safely assume that\n// parameterized tests are ready to be counted and run.\nbool UnitTestImpl::RunAllTests() {\n  // Makes sure InitGoogleTest() was called.\n  if (!GTestIsInitialized()) {\n    printf(\"%s\",\n           \"\\nThis test program did NOT call ::testing::InitGoogleTest \"\n           \"before calling RUN_ALL_TESTS().  Please fix it.\\n\");\n    return false;\n  }\n\n  // Do not run any test if the --help flag was specified.\n  if (g_help_flag)\n    return true;\n\n  // Repeats the call to the post-flag parsing initialization in case the\n  // user didn't call InitGoogleTest.\n  PostFlagParsingInit();\n\n  // Even if sharding is not on, test runners may want to use the\n  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding\n  // protocol.\n  internal::WriteToShardStatusFileIfNeeded();\n\n  // True iff we are in a subprocess for running a thread-safe-style\n  // death test.\n  bool in_subprocess_for_death_test = false;\n\n#if GTEST_HAS_DEATH_TEST\n  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);\n#endif  // GTEST_HAS_DEATH_TEST\n\n  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,\n                                        in_subprocess_for_death_test);\n\n  // Compares the full test names with the filter to decide which\n  // tests to run.\n  const bool has_tests_to_run = FilterTests(should_shard\n                                              ? HONOR_SHARDING_PROTOCOL\n                                              : IGNORE_SHARDING_PROTOCOL) > 0;\n\n  // Lists the tests and exits if the --gtest_list_tests flag was specified.\n  if (GTEST_FLAG(list_tests)) {\n    // This must be called *after* FilterTests() has been called.\n    ListTestsMatchingFilter();\n    return true;\n  }\n\n  random_seed_ = GTEST_FLAG(shuffle) ?\n      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;\n\n  // True iff at least one test has failed.\n  bool failed = false;\n\n  TestEventListener* repeater = listeners()->repeater();\n\n  repeater->OnTestProgramStart(*parent_);\n\n  // How many times to repeat the tests?  We don't want to repeat them\n  // when we are inside the subprocess of a death test.\n  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);\n  // Repeats forever if the repeat count is negative.\n  const bool forever = repeat < 0;\n  for (int i = 0; forever || i != repeat; i++) {\n    // We want to preserve failures generated by ad-hoc test\n    // assertions executed before RUN_ALL_TESTS().\n    ClearNonAdHocTestResult();\n\n    const TimeInMillis start = GetTimeInMillis();\n\n    // Shuffles test cases and tests if requested.\n    if (has_tests_to_run && GTEST_FLAG(shuffle)) {\n      random()->Reseed(random_seed_);\n      // This should be done before calling OnTestIterationStart(),\n      // such that a test event listener can see the actual test order\n      // in the event.\n      ShuffleTests();\n    }\n\n    // Tells the unit test event listeners that the tests are about to start.\n    repeater->OnTestIterationStart(*parent_, i);\n\n    // Runs each test case if there is at least one test to run.\n    if (has_tests_to_run) {\n      // Sets up all environments beforehand.\n      repeater->OnEnvironmentsSetUpStart(*parent_);\n      ForEach(environments_, SetUpEnvironment);\n      repeater->OnEnvironmentsSetUpEnd(*parent_);\n\n      // Runs the tests only if there was no fatal failure during global\n      // set-up.\n      if (!Test::HasFatalFailure()) {\n        for (int test_index = 0; test_index < total_test_case_count();\n             test_index++) {\n          GetMutableTestCase(test_index)->Run();\n        }\n      }\n\n      // Tears down all environments in reverse order afterwards.\n      repeater->OnEnvironmentsTearDownStart(*parent_);\n      std::for_each(environments_.rbegin(), environments_.rend(),\n                    TearDownEnvironment);\n      repeater->OnEnvironmentsTearDownEnd(*parent_);\n    }\n\n    elapsed_time_ = GetTimeInMillis() - start;\n\n    // Tells the unit test event listener that the tests have just finished.\n    repeater->OnTestIterationEnd(*parent_, i);\n\n    // Gets the result and clears it.\n    if (!Passed()) {\n      failed = true;\n    }\n\n    // Restores the original test order after the iteration.  This\n    // allows the user to quickly repro a failure that happens in the\n    // N-th iteration without repeating the first (N - 1) iterations.\n    // This is not enclosed in \"if (GTEST_FLAG(shuffle)) { ... }\", in\n    // case the user somehow changes the value of the flag somewhere\n    // (it's always safe to unshuffle the tests).\n    UnshuffleTests();\n\n    if (GTEST_FLAG(shuffle)) {\n      // Picks a new random seed for each iteration.\n      random_seed_ = GetNextRandomSeed(random_seed_);\n    }\n  }\n\n  repeater->OnTestProgramEnd(*parent_);\n\n  return !failed;\n}\n\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\n// if the variable is present. If a file already exists at this location, this\n// function will write over it. If the variable is present, but the file cannot\n// be created, prints an error and exits.\nvoid WriteToShardStatusFileIfNeeded() {\n  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);\n  if (test_shard_file != NULL) {\n    FILE* const file = posix::FOpen(test_shard_file, \"w\");\n    if (file == NULL) {\n      ColoredPrintf(COLOR_RED,\n                    \"Could not write to the test shard status file \\\"%s\\\" \"\n                    \"specified by the %s environment variable.\\n\",\n                    test_shard_file, kTestShardStatusFile);\n      fflush(stdout);\n      exit(EXIT_FAILURE);\n    }\n    fclose(file);\n  }\n}\n\n// Checks whether sharding is enabled by examining the relevant\n// environment variable values. If the variables are present,\n// but inconsistent (i.e., shard_index >= total_shards), prints\n// an error and exits. If in_subprocess_for_death_test, sharding is\n// disabled because it must only be applied to the original test\n// process. Otherwise, we could filter out death tests we intended to execute.\nbool ShouldShard(const char* total_shards_env,\n                 const char* shard_index_env,\n                 bool in_subprocess_for_death_test) {\n  if (in_subprocess_for_death_test) {\n    return false;\n  }\n\n  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);\n  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);\n\n  if (total_shards == -1 && shard_index == -1) {\n    return false;\n  } else if (total_shards == -1 && shard_index != -1) {\n    const Message msg = Message()\n      << \"Invalid environment variables: you have \"\n      << kTestShardIndex << \" = \" << shard_index\n      << \", but have left \" << kTestTotalShards << \" unset.\\n\";\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (total_shards != -1 && shard_index == -1) {\n    const Message msg = Message()\n      << \"Invalid environment variables: you have \"\n      << kTestTotalShards << \" = \" << total_shards\n      << \", but have left \" << kTestShardIndex << \" unset.\\n\";\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  } else if (shard_index < 0 || shard_index >= total_shards) {\n    const Message msg = Message()\n      << \"Invalid environment variables: we require 0 <= \"\n      << kTestShardIndex << \" < \" << kTestTotalShards\n      << \", but you have \" << kTestShardIndex << \"=\" << shard_index\n      << \", \" << kTestTotalShards << \"=\" << total_shards << \".\\n\";\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\n    fflush(stdout);\n    exit(EXIT_FAILURE);\n  }\n\n  return total_shards > 1;\n}\n\n// Parses the environment variable var as an Int32. If it is unset,\n// returns default_val. If it is not an Int32, prints an error\n// and aborts.\nInt32 Int32FromEnvOrDie(const char* var, Int32 default_val) {\n  const char* str_val = posix::GetEnv(var);\n  if (str_val == NULL) {\n    return default_val;\n  }\n\n  Int32 result;\n  if (!ParseInt32(Message() << \"The value of environment variable \" << var,\n                  str_val, &result)) {\n    exit(EXIT_FAILURE);\n  }\n  return result;\n}\n\n// Given the total number of shards, the shard index, and the test id,\n// returns true iff the test should be run on this shard. The test id is\n// some arbitrary but unique non-negative integer assigned to each test\n// method. Assumes that 0 <= shard_index < total_shards.\nbool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {\n  return (test_id % total_shards) == shard_index;\n}\n\n// Compares the name of each test with the user-specified filter to\n// decide whether the test should be run, then records the result in\n// each TestCase and TestInfo object.\n// If shard_tests == true, further filters tests based on sharding\n// variables in the environment - see\n// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.\n// Returns the number of tests that should run.\nint UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {\n  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?\n      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;\n  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?\n      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;\n\n  // num_runnable_tests are the number of tests that will\n  // run across all shards (i.e., match filter and are not disabled).\n  // num_selected_tests are the number of tests to be run on\n  // this shard.\n  int num_runnable_tests = 0;\n  int num_selected_tests = 0;\n  for (size_t i = 0; i < test_cases_.size(); i++) {\n    TestCase* const test_case = test_cases_[i];\n    const String &test_case_name = test_case->name();\n    test_case->set_should_run(false);\n\n    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {\n      TestInfo* const test_info = test_case->test_info_list()[j];\n      const String test_name(test_info->name());\n      // A test is disabled if test case name or test name matches\n      // kDisableTestFilter.\n      const bool is_disabled =\n          internal::UnitTestOptions::MatchesFilter(test_case_name,\n                                                   kDisableTestFilter) ||\n          internal::UnitTestOptions::MatchesFilter(test_name,\n                                                   kDisableTestFilter);\n      test_info->is_disabled_ = is_disabled;\n\n      const bool matches_filter =\n          internal::UnitTestOptions::FilterMatchesTest(test_case_name,\n                                                       test_name);\n      test_info->matches_filter_ = matches_filter;\n\n      const bool is_runnable =\n          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&\n          matches_filter;\n\n      const bool is_selected = is_runnable &&\n          (shard_tests == IGNORE_SHARDING_PROTOCOL ||\n           ShouldRunTestOnShard(total_shards, shard_index,\n                                num_runnable_tests));\n\n      num_runnable_tests += is_runnable;\n      num_selected_tests += is_selected;\n\n      test_info->should_run_ = is_selected;\n      test_case->set_should_run(test_case->should_run() || is_selected);\n    }\n  }\n  return num_selected_tests;\n}\n\n// Prints the names of the tests matching the user-specified filter flag.\nvoid UnitTestImpl::ListTestsMatchingFilter() {\n  for (size_t i = 0; i < test_cases_.size(); i++) {\n    const TestCase* const test_case = test_cases_[i];\n    bool printed_test_case_name = false;\n\n    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {\n      const TestInfo* const test_info =\n          test_case->test_info_list()[j];\n      if (test_info->matches_filter_) {\n        if (!printed_test_case_name) {\n          printed_test_case_name = true;\n          printf(\"%s.\\n\", test_case->name());\n        }\n        printf(\"  %s\\n\", test_info->name());\n      }\n    }\n  }\n  fflush(stdout);\n}\n\n// Sets the OS stack trace getter.\n//\n// Does nothing if the input and the current OS stack trace getter are\n// the same; otherwise, deletes the old getter and makes the input the\n// current getter.\nvoid UnitTestImpl::set_os_stack_trace_getter(\n    OsStackTraceGetterInterface* getter) {\n  if (os_stack_trace_getter_ != getter) {\n    delete os_stack_trace_getter_;\n    os_stack_trace_getter_ = getter;\n  }\n}\n\n// Returns the current OS stack trace getter if it is not NULL;\n// otherwise, creates an OsStackTraceGetter, makes it the current\n// getter, and returns it.\nOsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {\n  if (os_stack_trace_getter_ == NULL) {\n    os_stack_trace_getter_ = new OsStackTraceGetter;\n  }\n\n  return os_stack_trace_getter_;\n}\n\n// Returns the TestResult for the test that's currently running, or\n// the TestResult for the ad hoc test if no test is running.\nTestResult* UnitTestImpl::current_test_result() {\n  return current_test_info_ ?\n      &(current_test_info_->result_) : &ad_hoc_test_result_;\n}\n\n// Shuffles all test cases, and the tests within each test case,\n// making sure that death tests are still run first.\nvoid UnitTestImpl::ShuffleTests() {\n  // Shuffles the death test cases.\n  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);\n\n  // Shuffles the non-death test cases.\n  ShuffleRange(random(), last_death_test_case_ + 1,\n               static_cast<int>(test_cases_.size()), &test_case_indices_);\n\n  // Shuffles the tests inside each test case.\n  for (size_t i = 0; i < test_cases_.size(); i++) {\n    test_cases_[i]->ShuffleTests(random());\n  }\n}\n\n// Restores the test cases and tests to their order before the first shuffle.\nvoid UnitTestImpl::UnshuffleTests() {\n  for (size_t i = 0; i < test_cases_.size(); i++) {\n    // Unshuffles the tests in each test case.\n    test_cases_[i]->UnshuffleTests();\n    // Resets the index of each test case.\n    test_case_indices_[i] = static_cast<int>(i);\n  }\n}\n\n// Returns the current OS stack trace as a String.\n//\n// The maximum number of stack frames to be included is specified by\n// the gtest_stack_trace_depth flag.  The skip_count parameter\n// specifies the number of top frames to be skipped, which doesn't\n// count against the number of frames to be included.\n//\n// For example, if Foo() calls Bar(), which in turn calls\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\nString GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,\n                                       int skip_count) {\n  // We pass skip_count + 1 to skip this wrapper function in addition\n  // to what the user really wants to skip.\n  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);\n}\n\n// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to\n// suppress unreachable code warnings.\nnamespace {\nclass ClassUniqueToAlwaysTrue {};\n}\n\nbool IsTrue(bool condition) { return condition; }\n\nbool AlwaysTrue() {\n#if GTEST_HAS_EXCEPTIONS\n  // This condition is always false so AlwaysTrue() never actually throws,\n  // but it makes the compiler think that it may throw.\n  if (IsTrue(false))\n    throw ClassUniqueToAlwaysTrue();\n#endif  // GTEST_HAS_EXCEPTIONS\n  return true;\n}\n\n// If *pstr starts with the given prefix, modifies *pstr to be right\n// past the prefix and returns true; otherwise leaves *pstr unchanged\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\nbool SkipPrefix(const char* prefix, const char** pstr) {\n  const size_t prefix_len = strlen(prefix);\n  if (strncmp(*pstr, prefix, prefix_len) == 0) {\n    *pstr += prefix_len;\n    return true;\n  }\n  return false;\n}\n\n// Parses a string as a command line flag.  The string should have\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\n// part can be omitted.\n//\n// Returns the value of the flag, or NULL if the parsing failed.\nconst char* ParseFlagValue(const char* str,\n                           const char* flag,\n                           bool def_optional) {\n  // str and flag must not be NULL.\n  if (str == NULL || flag == NULL) return NULL;\n\n  // The flag must start with \"--\" followed by GTEST_FLAG_PREFIX_.\n  const String flag_str = String::Format(\"--%s%s\", GTEST_FLAG_PREFIX_, flag);\n  const size_t flag_len = flag_str.length();\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;\n\n  // Skips the flag name.\n  const char* flag_end = str + flag_len;\n\n  // When def_optional is true, it's OK to not have a \"=value\" part.\n  if (def_optional && (flag_end[0] == '\\0')) {\n    return flag_end;\n  }\n\n  // If def_optional is true and there are more characters after the\n  // flag name, or if def_optional is false, there must be a '=' after\n  // the flag name.\n  if (flag_end[0] != '=') return NULL;\n\n  // Returns the string after \"=\".\n  return flag_end + 1;\n}\n\n// Parses a string for a bool flag, in the form of either\n// \"--flag=value\" or \"--flag\".\n//\n// In the former case, the value is taken as true as long as it does\n// not start with '0', 'f', or 'F'.\n//\n// In the latter case, the value is taken as true.\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nbool ParseBoolFlag(const char* str, const char* flag, bool* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, true);\n\n  // Aborts if the parsing failed.\n  if (value_str == NULL) return false;\n\n  // Converts the string value to a bool.\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\n  return true;\n}\n\n// Parses a string for an Int32 flag, in the form of\n// \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nbool ParseInt32Flag(const char* str, const char* flag, Int32* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == NULL) return false;\n\n  // Sets *value to the value of the flag.\n  return ParseInt32(Message() << \"The value of flag --\" << flag,\n                    value_str, value);\n}\n\n// Parses a string for a string flag, in the form of\n// \"--flag=value\".\n//\n// On success, stores the value of the flag in *value, and returns\n// true.  On failure, returns false without changing *value.\nbool ParseStringFlag(const char* str, const char* flag, String* value) {\n  // Gets the value of the flag as a string.\n  const char* const value_str = ParseFlagValue(str, flag, false);\n\n  // Aborts if the parsing failed.\n  if (value_str == NULL) return false;\n\n  // Sets *value to the value of the flag.\n  *value = value_str;\n  return true;\n}\n\n// Determines whether a string has a prefix that Google Test uses for its\n// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.\n// If Google Test detects that a command line flag has its prefix but is not\n// recognized, it will print its help message. Flags starting with\n// GTEST_INTERNAL_PREFIX_ followed by \"internal_\" are considered Google Test\n// internal flags and do not trigger the help message.\nstatic bool HasGoogleTestFlagPrefix(const char* str) {\n  return (SkipPrefix(\"--\", &str) ||\n          SkipPrefix(\"-\", &str) ||\n          SkipPrefix(\"/\", &str)) &&\n         !SkipPrefix(GTEST_FLAG_PREFIX_ \"internal_\", &str) &&\n         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||\n          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));\n}\n\n// Prints a string containing code-encoded text.  The following escape\n// sequences can be used in the string to control the text color:\n//\n//   @@    prints a single '@' character.\n//   @R    changes the color to red.\n//   @G    changes the color to green.\n//   @Y    changes the color to yellow.\n//   @D    changes to the default terminal text color.\n//\n// TODO(wan@google.com): Write tests for this once we add stdout\n// capturing to Google Test.\nstatic void PrintColorEncoded(const char* str) {\n  GTestColor color = COLOR_DEFAULT;  // The current color.\n\n  // Conceptually, we split the string into segments divided by escape\n  // sequences.  Then we print one segment at a time.  At the end of\n  // each iteration, the str pointer advances to the beginning of the\n  // next segment.\n  for (;;) {\n    const char* p = strchr(str, '@');\n    if (p == NULL) {\n      ColoredPrintf(color, \"%s\", str);\n      return;\n    }\n\n    ColoredPrintf(color, \"%s\", String(str, p - str).c_str());\n\n    const char ch = p[1];\n    str = p + 2;\n    if (ch == '@') {\n      ColoredPrintf(color, \"@\");\n    } else if (ch == 'D') {\n      color = COLOR_DEFAULT;\n    } else if (ch == 'R') {\n      color = COLOR_RED;\n    } else if (ch == 'G') {\n      color = COLOR_GREEN;\n    } else if (ch == 'Y') {\n      color = COLOR_YELLOW;\n    } else {\n      --str;\n    }\n  }\n}\n\nstatic const char kColorEncodedHelpMessage[] =\n\"This program contains tests written using \" GTEST_NAME_ \". You can use the\\n\"\n\"following command line flags to control its behavior:\\n\"\n\"\\n\"\n\"Test Selection:\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"list_tests@D\\n\"\n\"      List the names of all tests instead of running them. The name of\\n\"\n\"      TEST(Foo, Bar) is \\\"Foo.Bar\\\".\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"filter=@YPOSTIVE_PATTERNS\"\n    \"[@G-@YNEGATIVE_PATTERNS]@D\\n\"\n\"      Run only the tests whose name matches one of the positive patterns but\\n\"\n\"      none of the negative patterns. '?' matches any single character; '*'\\n\"\n\"      matches any substring; ':' separates two patterns.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"also_run_disabled_tests@D\\n\"\n\"      Run all disabled tests too.\\n\"\n\"\\n\"\n\"Test Execution:\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"repeat=@Y[COUNT]@D\\n\"\n\"      Run the tests repeatedly; use a negative count to repeat forever.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"shuffle@D\\n\"\n\"      Randomize tests' orders on every iteration.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"random_seed=@Y[NUMBER]@D\\n\"\n\"      Random number seed to use for shuffling test orders (between 1 and\\n\"\n\"      99999, or 0 to use a seed based on the current time).\\n\"\n\"\\n\"\n\"Test Output:\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\\n\"\n\"      Enable/disable colored output. The default is @Gauto@D.\\n\"\n\"  -@G-\" GTEST_FLAG_PREFIX_ \"print_time=0@D\\n\"\n\"      Don't print the elapsed time of each test.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"output=xml@Y[@G:@YDIRECTORY_PATH@G\"\n    GTEST_PATH_SEP_ \"@Y|@G:@YFILE_PATH]@D\\n\"\n\"      Generate an XML report in the given directory or with the given file\\n\"\n\"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\\n\"\n#if GTEST_CAN_STREAM_RESULTS_\n\"  @G--\" GTEST_FLAG_PREFIX_ \"stream_result_to=@YHOST@G:@YPORT@D\\n\"\n\"      Stream test results to the given server.\\n\"\n#endif  // GTEST_CAN_STREAM_RESULTS_\n\"\\n\"\n\"Assertion Behavior:\\n\"\n#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\n\"  @G--\" GTEST_FLAG_PREFIX_ \"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\\n\"\n\"      Set the default death test style.\\n\"\n#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\n\"  @G--\" GTEST_FLAG_PREFIX_ \"break_on_failure@D\\n\"\n\"      Turn assertion failures into debugger break-points.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"throw_on_failure@D\\n\"\n\"      Turn assertion failures into C++ exceptions.\\n\"\n\"  @G--\" GTEST_FLAG_PREFIX_ \"catch_exceptions=0@D\\n\"\n\"      Do not report exceptions as test failures. Instead, allow them\\n\"\n\"      to crash the program or throw a pop-up (on Windows).\\n\"\n\"\\n\"\n\"Except for @G--\" GTEST_FLAG_PREFIX_ \"list_tests@D, you can alternatively set \"\n    \"the corresponding\\n\"\n\"environment variable of a flag (all letters in upper-case). For example, to\\n\"\n\"disable colored text output, you can either specify @G--\" GTEST_FLAG_PREFIX_\n    \"color=no@D or set\\n\"\n\"the @G\" GTEST_FLAG_PREFIX_UPPER_ \"COLOR@D environment variable to @Gno@D.\\n\"\n\"\\n\"\n\"For more information, please read the \" GTEST_NAME_ \" documentation at\\n\"\n\"@G\" GTEST_PROJECT_URL_ \"@D. If you find a bug in \" GTEST_NAME_ \"\\n\"\n\"(not one in your own code or tests), please report it to\\n\"\n\"@G<\" GTEST_DEV_EMAIL_ \">@D.\\n\";\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.  The type parameter CharType can be\n// instantiated to either char or wchar_t.\ntemplate <typename CharType>\nvoid ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {\n  for (int i = 1; i < *argc; i++) {\n    const String arg_string = StreamableToString(argv[i]);\n    const char* const arg = arg_string.c_str();\n\n    using internal::ParseBoolFlag;\n    using internal::ParseInt32Flag;\n    using internal::ParseStringFlag;\n\n    // Do we see a Google Test flag?\n    if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,\n                      &GTEST_FLAG(also_run_disabled_tests)) ||\n        ParseBoolFlag(arg, kBreakOnFailureFlag,\n                      &GTEST_FLAG(break_on_failure)) ||\n        ParseBoolFlag(arg, kCatchExceptionsFlag,\n                      &GTEST_FLAG(catch_exceptions)) ||\n        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||\n        ParseStringFlag(arg, kDeathTestStyleFlag,\n                        &GTEST_FLAG(death_test_style)) ||\n        ParseBoolFlag(arg, kDeathTestUseFork,\n                      &GTEST_FLAG(death_test_use_fork)) ||\n        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||\n        ParseStringFlag(arg, kInternalRunDeathTestFlag,\n                        &GTEST_FLAG(internal_run_death_test)) ||\n        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||\n        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||\n        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||\n        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||\n        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||\n        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||\n        ParseInt32Flag(arg, kStackTraceDepthFlag,\n                       &GTEST_FLAG(stack_trace_depth)) ||\n        ParseStringFlag(arg, kStreamResultToFlag,\n                        &GTEST_FLAG(stream_result_to)) ||\n        ParseBoolFlag(arg, kThrowOnFailureFlag,\n                      &GTEST_FLAG(throw_on_failure))\n        ) {\n      // Yes.  Shift the remainder of the argv list left by one.  Note\n      // that argv has (*argc + 1) elements, the last one always being\n      // NULL.  The following loop moves the trailing NULL element as\n      // well.\n      for (int j = i; j != *argc; j++) {\n        argv[j] = argv[j + 1];\n      }\n\n      // Decrements the argument count.\n      (*argc)--;\n\n      // We also need to decrement the iterator as we just removed\n      // an element.\n      i--;\n    } else if (arg_string == \"--help\" || arg_string == \"-h\" ||\n               arg_string == \"-?\" || arg_string == \"/?\" ||\n               HasGoogleTestFlagPrefix(arg)) {\n      // Both help flag and unrecognized Google Test flags (excluding\n      // internal ones) trigger help display.\n      g_help_flag = true;\n    }\n  }\n\n  if (g_help_flag) {\n    // We print the help here instead of in RUN_ALL_TESTS(), as the\n    // latter may not be called at all if the user is using Google\n    // Test with another testing framework.\n    PrintColorEncoded(kColorEncodedHelpMessage);\n  }\n}\n\n// Parses the command line for Google Test flags, without initializing\n// other parts of Google Test.\nvoid ParseGoogleTestFlagsOnly(int* argc, char** argv) {\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n}\nvoid ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\n}\n\n// The internal implementation of InitGoogleTest().\n//\n// The type parameter CharType can be instantiated to either char or\n// wchar_t.\ntemplate <typename CharType>\nvoid InitGoogleTestImpl(int* argc, CharType** argv) {\n  g_init_gtest_count++;\n\n  // We don't want to run the initialization code twice.\n  if (g_init_gtest_count != 1) return;\n\n  if (*argc <= 0) return;\n\n  internal::g_executable_path = internal::StreamableToString(argv[0]);\n\n#if GTEST_HAS_DEATH_TEST\n\n  g_argvs.clear();\n  for (int i = 0; i != *argc; i++) {\n    g_argvs.push_back(StreamableToString(argv[i]));\n  }\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n  ParseGoogleTestFlagsOnly(argc, argv);\n  GetUnitTestImpl()->PostFlagParsingInit();\n}\n\n}  // namespace internal\n\n// Initializes Google Test.  This must be called before calling\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\n// flags that Google Test recognizes.  Whenever a Google Test flag is\n// seen, it is removed from argv, and *argc is decremented.\n//\n// No value is returned.  Instead, the Google Test flag variables are\n// updated.\n//\n// Calling the function for the second time has no user-visible effect.\nvoid InitGoogleTest(int* argc, char** argv) {\n  internal::InitGoogleTestImpl(argc, argv);\n}\n\n// This overloaded version can be used in Windows programs compiled in\n// UNICODE mode.\nvoid InitGoogleTest(int* argc, wchar_t** argv) {\n  internal::InitGoogleTestImpl(argc, argv);\n}\n\n}  // namespace testing\n// Copyright 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)\n//\n// This file implements death tests.\n\n\n#if GTEST_HAS_DEATH_TEST\n\n# if GTEST_OS_MAC\n#  include <crt_externs.h>\n# endif  // GTEST_OS_MAC\n\n# include <errno.h>\n# include <fcntl.h>\n# include <limits.h>\n# include <stdarg.h>\n\n# if GTEST_OS_WINDOWS\n#  include <windows.h>\n# else\n#  include <sys/mman.h>\n#  include <sys/wait.h>\n# endif  // GTEST_OS_WINDOWS\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n\n// Indicates that this translation unit is part of Google Test's\n// implementation.  It must come before gtest-internal-inl.h is\n// included, or there will be a compiler error.  This trick is to\n// prevent a user from accidentally including gtest-internal-inl.h in\n// his code.\n#define GTEST_IMPLEMENTATION_ 1\n#undef GTEST_IMPLEMENTATION_\n\nnamespace testing {\n\n// Constants.\n\n// The default death test style.\nstatic const char kDefaultDeathTestStyle[] = \"fast\";\n\nGTEST_DEFINE_string_(\n    death_test_style,\n    internal::StringFromGTestEnv(\"death_test_style\", kDefaultDeathTestStyle),\n    \"Indicates how to run a death test in a forked child process: \"\n    \"\\\"threadsafe\\\" (child process re-executes the test binary \"\n    \"from the beginning, running only the specific death test) or \"\n    \"\\\"fast\\\" (child process runs the death test immediately \"\n    \"after forking).\");\n\nGTEST_DEFINE_bool_(\n    death_test_use_fork,\n    internal::BoolFromGTestEnv(\"death_test_use_fork\", false),\n    \"Instructs to use fork()/_exit() instead of clone() in death tests. \"\n    \"Ignored and always uses fork() on POSIX systems where clone() is not \"\n    \"implemented. Useful when running under valgrind or similar tools if \"\n    \"those do not support clone(). Valgrind 3.3.1 will just fail if \"\n    \"it sees an unsupported combination of clone() flags. \"\n    \"It is not recommended to use this flag w/o valgrind though it will \"\n    \"work in 99% of the cases. Once valgrind is fixed, this flag will \"\n    \"most likely be removed.\");\n\nnamespace internal {\nGTEST_DEFINE_string_(\n    internal_run_death_test, \"\",\n    \"Indicates the file, line number, temporal index of \"\n    \"the single death test to run, and a file descriptor to \"\n    \"which a success code may be sent, all separated by \"\n    \"colons.  This flag is specified if and only if the current \"\n    \"process is a sub-process launched for running a thread-safe \"\n    \"death test.  FOR INTERNAL USE ONLY.\");\n}  // namespace internal\n\n#if GTEST_HAS_DEATH_TEST\n\n// ExitedWithCode constructor.\nExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {\n}\n\n// ExitedWithCode function-call operator.\nbool ExitedWithCode::operator()(int exit_status) const {\n# if GTEST_OS_WINDOWS\n\n  return exit_status == exit_code_;\n\n# else\n\n  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;\n\n# endif  // GTEST_OS_WINDOWS\n}\n\n# if !GTEST_OS_WINDOWS\n// KilledBySignal constructor.\nKilledBySignal::KilledBySignal(int signum) : signum_(signum) {\n}\n\n// KilledBySignal function-call operator.\nbool KilledBySignal::operator()(int exit_status) const {\n  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;\n}\n# endif  // !GTEST_OS_WINDOWS\n\nnamespace internal {\n\n// Utilities needed for death tests.\n\n// Generates a textual description of a given exit code, in the format\n// specified by wait(2).\nstatic String ExitSummary(int exit_code) {\n  Message m;\n\n# if GTEST_OS_WINDOWS\n\n  m << \"Exited with exit status \" << exit_code;\n\n# else\n\n  if (WIFEXITED(exit_code)) {\n    m << \"Exited with exit status \" << WEXITSTATUS(exit_code);\n  } else if (WIFSIGNALED(exit_code)) {\n    m << \"Terminated by signal \" << WTERMSIG(exit_code);\n  }\n#  ifdef WCOREDUMP\n  if (WCOREDUMP(exit_code)) {\n    m << \" (core dumped)\";\n  }\n#  endif\n# endif  // GTEST_OS_WINDOWS\n\n  return m.GetString();\n}\n\n// Returns true if exit_status describes a process that was terminated\n// by a signal, or exited normally with a nonzero exit code.\nbool ExitedUnsuccessfully(int exit_status) {\n  return !ExitedWithCode(0)(exit_status);\n}\n\n# if !GTEST_OS_WINDOWS\n// Generates a textual failure message when a death test finds more than\n// one thread running, or cannot determine the number of threads, prior\n// to executing the given statement.  It is the responsibility of the\n// caller not to pass a thread_count of 1.\nstatic String DeathTestThreadWarning(size_t thread_count) {\n  Message msg;\n  msg << \"Death tests use fork(), which is unsafe particularly\"\n      << \" in a threaded context. For this test, \" << GTEST_NAME_ << \" \";\n  if (thread_count == 0)\n    msg << \"couldn't detect the number of threads.\";\n  else\n    msg << \"detected \" << thread_count << \" threads.\";\n  return msg.GetString();\n}\n# endif  // !GTEST_OS_WINDOWS\n\n// Flag characters for reporting a death test that did not die.\nstatic const char kDeathTestLived = 'L';\nstatic const char kDeathTestReturned = 'R';\nstatic const char kDeathTestThrew = 'T';\nstatic const char kDeathTestInternalError = 'I';\n\n// An enumeration describing all of the possible ways that a death test can\n// conclude.  DIED means that the process died while executing the test\n// code; LIVED means that process lived beyond the end of the test code;\n// RETURNED means that the test statement attempted to execute a return\n// statement, which is not allowed; THREW means that the test statement\n// returned control by throwing an exception.  IN_PROGRESS means the test\n// has not yet concluded.\n// TODO(vladl@google.com): Unify names and possibly values for\n// AbortReason, DeathTestOutcome, and flag characters above.\nenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };\n\n// Routine for aborting the program which is safe to call from an\n// exec-style death test child process, in which case the error\n// message is propagated back to the parent process.  Otherwise, the\n// message is simply printed to stderr.  In either case, the program\n// then exits with status 1.\nvoid DeathTestAbort(const String& message) {\n  // On a POSIX system, this function may be called from a threadsafe-style\n  // death test child process, which operates on a very small stack.  Use\n  // the heap for any additional non-minuscule memory requirements.\n  const InternalRunDeathTestFlag* const flag =\n      GetUnitTestImpl()->internal_run_death_test_flag();\n  if (flag != NULL) {\n    FILE* parent = posix::FDOpen(flag->write_fd(), \"w\");\n    fputc(kDeathTestInternalError, parent);\n    fprintf(parent, \"%s\", message.c_str());\n    fflush(parent);\n    _exit(1);\n  } else {\n    fprintf(stderr, \"%s\", message.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n\n// A replacement for CHECK that calls DeathTestAbort if the assertion\n// fails.\n# define GTEST_DEATH_TEST_CHECK_(expression) \\\n  do { \\\n    if (!::testing::internal::IsTrue(expression)) { \\\n      DeathTestAbort(::testing::internal::String::Format( \\\n          \"CHECK failed: File %s, line %d: %s\", \\\n          __FILE__, __LINE__, #expression)); \\\n    } \\\n  } while (::testing::internal::AlwaysFalse())\n\n// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for\n// evaluating any system call that fulfills two conditions: it must return\n// -1 on failure, and set errno to EINTR when it is interrupted and\n// should be tried again.  The macro expands to a loop that repeatedly\n// evaluates the expression as long as it evaluates to -1 and sets\n// errno to EINTR.  If the expression evaluates to -1 but errno is\n// something other than EINTR, DeathTestAbort is called.\n# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \\\n  do { \\\n    int gtest_retval; \\\n    do { \\\n      gtest_retval = (expression); \\\n    } while (gtest_retval == -1 && errno == EINTR); \\\n    if (gtest_retval == -1) { \\\n      DeathTestAbort(::testing::internal::String::Format( \\\n          \"CHECK failed: File %s, line %d: %s != -1\", \\\n          __FILE__, __LINE__, #expression)); \\\n    } \\\n  } while (::testing::internal::AlwaysFalse())\n\n// Returns the message describing the last system error in errno.\nString GetLastErrnoDescription() {\n    return String(errno == 0 ? \"\" : posix::StrError(errno));\n}\n\n// This is called from a death test parent process to read a failure\n// message from the death test child process and log it with the FATAL\n// severity. On Windows, the message is read from a pipe handle. On other\n// platforms, it is read from a file descriptor.\nstatic void FailFromInternalError(int fd) {\n  Message error;\n  char buffer[256];\n  int num_read;\n\n  do {\n    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {\n      buffer[num_read] = '\\0';\n      error << buffer;\n    }\n  } while (num_read == -1 && errno == EINTR);\n\n  if (num_read == 0) {\n    GTEST_LOG_(FATAL) << error.GetString();\n  } else {\n    const int last_error = errno;\n    GTEST_LOG_(FATAL) << \"Error while reading death test internal: \"\n                      << GetLastErrnoDescription() << \" [\" << last_error << \"]\";\n  }\n}\n\n// Death test constructor.  Increments the running death test count\n// for the current test.\nDeathTest::DeathTest() {\n  TestInfo* const info = GetUnitTestImpl()->current_test_info();\n  if (info == NULL) {\n    DeathTestAbort(\"Cannot run a death test outside of a TEST or \"\n                   \"TEST_F construct\");\n  }\n}\n\n// Creates and returns a death test by dispatching to the current\n// death test factory.\nbool DeathTest::Create(const char* statement, const RE* regex,\n                       const char* file, int line, DeathTest** test) {\n  return GetUnitTestImpl()->death_test_factory()->Create(\n      statement, regex, file, line, test);\n}\n\nconst char* DeathTest::LastMessage() {\n  return last_death_test_message_.c_str();\n}\n\nvoid DeathTest::set_last_death_test_message(const String& message) {\n  last_death_test_message_ = message;\n}\n\nString DeathTest::last_death_test_message_;\n\n// Provides cross platform implementation for some death functionality.\nclass DeathTestImpl : public DeathTest {\n protected:\n  DeathTestImpl(const char* a_statement, const RE* a_regex)\n      : statement_(a_statement),\n        regex_(a_regex),\n        spawned_(false),\n        status_(-1),\n        outcome_(IN_PROGRESS),\n        read_fd_(-1),\n        write_fd_(-1) {}\n\n  // read_fd_ is expected to be closed and cleared by a derived class.\n  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }\n\n  void Abort(AbortReason reason);\n  virtual bool Passed(bool status_ok);\n\n  const char* statement() const { return statement_; }\n  const RE* regex() const { return regex_; }\n  bool spawned() const { return spawned_; }\n  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }\n  int status() const { return status_; }\n  void set_status(int a_status) { status_ = a_status; }\n  DeathTestOutcome outcome() const { return outcome_; }\n  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }\n  int read_fd() const { return read_fd_; }\n  void set_read_fd(int fd) { read_fd_ = fd; }\n  int write_fd() const { return write_fd_; }\n  void set_write_fd(int fd) { write_fd_ = fd; }\n\n  // Called in the parent process only. Reads the result code of the death\n  // test child process via a pipe, interprets it to set the outcome_\n  // member, and closes read_fd_.  Outputs diagnostics and terminates in\n  // case of unexpected codes.\n  void ReadAndInterpretStatusByte();\n\n private:\n  // The textual content of the code this object is testing.  This class\n  // doesn't own this string and should not attempt to delete it.\n  const char* const statement_;\n  // The regular expression which test output must match.  DeathTestImpl\n  // doesn't own this object and should not attempt to delete it.\n  const RE* const regex_;\n  // True if the death test child process has been successfully spawned.\n  bool spawned_;\n  // The exit status of the child process.\n  int status_;\n  // How the death test concluded.\n  DeathTestOutcome outcome_;\n  // Descriptor to the read end of the pipe to the child process.  It is\n  // always -1 in the child process.  The child keeps its write end of the\n  // pipe in write_fd_.\n  int read_fd_;\n  // Descriptor to the child's write end of the pipe to the parent process.\n  // It is always -1 in the parent process.  The parent keeps its end of the\n  // pipe in read_fd_.\n  int write_fd_;\n};\n\n// Called in the parent process only. Reads the result code of the death\n// test child process via a pipe, interprets it to set the outcome_\n// member, and closes read_fd_.  Outputs diagnostics and terminates in\n// case of unexpected codes.\nvoid DeathTestImpl::ReadAndInterpretStatusByte() {\n  char flag;\n  int bytes_read;\n\n  // The read() here blocks until data is available (signifying the\n  // failure of the death test) or until the pipe is closed (signifying\n  // its success), so it's okay to call this in the parent before\n  // the child process has exited.\n  do {\n    bytes_read = posix::Read(read_fd(), &flag, 1);\n  } while (bytes_read == -1 && errno == EINTR);\n\n  if (bytes_read == 0) {\n    set_outcome(DIED);\n  } else if (bytes_read == 1) {\n    switch (flag) {\n      case kDeathTestReturned:\n        set_outcome(RETURNED);\n        break;\n      case kDeathTestThrew:\n        set_outcome(THREW);\n        break;\n      case kDeathTestLived:\n        set_outcome(LIVED);\n        break;\n      case kDeathTestInternalError:\n        FailFromInternalError(read_fd());  // Does not return.\n        break;\n      default:\n        GTEST_LOG_(FATAL) << \"Death test child process reported \"\n                          << \"unexpected status byte (\"\n                          << static_cast<unsigned int>(flag) << \")\";\n    }\n  } else {\n    GTEST_LOG_(FATAL) << \"Read from death test child process failed: \"\n                      << GetLastErrnoDescription();\n  }\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));\n  set_read_fd(-1);\n}\n\n// Signals that the death test code which should have exited, didn't.\n// Should be called only in a death test child process.\n// Writes a status byte to the child's status file descriptor, then\n// calls _exit(1).\nvoid DeathTestImpl::Abort(AbortReason reason) {\n  // The parent process considers the death test to be a failure if\n  // it finds any data in our pipe.  So, here we write a single flag byte\n  // to the pipe, then exit.\n  const char status_ch =\n      reason == TEST_DID_NOT_DIE ? kDeathTestLived :\n      reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned;\n\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));\n  // We are leaking the descriptor here because on some platforms (i.e.,\n  // when built as Windows DLL), destructors of global objects will still\n  // run after calling _exit(). On such systems, write_fd_ will be\n  // indirectly closed from the destructor of UnitTestImpl, causing double\n  // close if it is also closed here. On debug configurations, double close\n  // may assert. As there are no in-process buffers to flush here, we are\n  // relying on the OS to close the descriptor after the process terminates\n  // when the destructors are not run.\n  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)\n}\n\n// Returns an indented copy of stderr output for a death test.\n// This makes distinguishing death test output lines from regular log lines\n// much easier.\nstatic ::std::string FormatDeathTestOutput(const ::std::string& output) {\n  ::std::string ret;\n  for (size_t at = 0; ; ) {\n    const size_t line_end = output.find('\\n', at);\n    ret += \"[  DEATH   ] \";\n    if (line_end == ::std::string::npos) {\n      ret += output.substr(at);\n      break;\n    }\n    ret += output.substr(at, line_end + 1 - at);\n    at = line_end + 1;\n  }\n  return ret;\n}\n\n// Assesses the success or failure of a death test, using both private\n// members which have previously been set, and one argument:\n//\n// Private data members:\n//   outcome:  An enumeration describing how the death test\n//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test\n//             fails in the latter three cases.\n//   status:   The exit status of the child process. On *nix, it is in the\n//             in the format specified by wait(2). On Windows, this is the\n//             value supplied to the ExitProcess() API or a numeric code\n//             of the exception that terminated the program.\n//   regex:    A regular expression object to be applied to\n//             the test's captured standard error output; the death test\n//             fails if it does not match.\n//\n// Argument:\n//   status_ok: true if exit_status is acceptable in the context of\n//              this particular death test, which fails if it is false\n//\n// Returns true iff all of the above conditions are met.  Otherwise, the\n// first failing condition, in the order given above, is the one that is\n// reported. Also sets the last death test message string.\nbool DeathTestImpl::Passed(bool status_ok) {\n  if (!spawned())\n    return false;\n\n  const String error_message = GetCapturedStderr();\n\n  bool success = false;\n  Message buffer;\n\n  buffer << \"Death test: \" << statement() << \"\\n\";\n  switch (outcome()) {\n    case LIVED:\n      buffer << \"    Result: failed to die.\\n\"\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\n      break;\n    case THREW:\n      buffer << \"    Result: threw an exception.\\n\"\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\n      break;\n    case RETURNED:\n      buffer << \"    Result: illegal return in test statement.\\n\"\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\n      break;\n    case DIED:\n      if (status_ok) {\n        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());\n        if (matched) {\n          success = true;\n        } else {\n          buffer << \"    Result: died but not with expected error.\\n\"\n                 << \"  Expected: \" << regex()->pattern() << \"\\n\"\n                 << \"Actual msg:\\n\" << FormatDeathTestOutput(error_message);\n        }\n      } else {\n        buffer << \"    Result: died but not with expected exit code:\\n\"\n               << \"            \" << ExitSummary(status()) << \"\\n\"\n               << \"Actual msg:\\n\" << FormatDeathTestOutput(error_message);\n      }\n      break;\n    case IN_PROGRESS:\n    default:\n      GTEST_LOG_(FATAL)\n          << \"DeathTest::Passed somehow called before conclusion of test\";\n  }\n\n  DeathTest::set_last_death_test_message(buffer.GetString());\n  return success;\n}\n\n# if GTEST_OS_WINDOWS\n// WindowsDeathTest implements death tests on Windows. Due to the\n// specifics of starting new processes on Windows, death tests there are\n// always threadsafe, and Google Test considers the\n// --gtest_death_test_style=fast setting to be equivalent to\n// --gtest_death_test_style=threadsafe there.\n//\n// A few implementation notes:  Like the Linux version, the Windows\n// implementation uses pipes for child-to-parent communication. But due to\n// the specifics of pipes on Windows, some extra steps are required:\n//\n// 1. The parent creates a communication pipe and stores handles to both\n//    ends of it.\n// 2. The parent starts the child and provides it with the information\n//    necessary to acquire the handle to the write end of the pipe.\n// 3. The child acquires the write end of the pipe and signals the parent\n//    using a Windows event.\n// 4. Now the parent can release the write end of the pipe on its side. If\n//    this is done before step 3, the object's reference count goes down to\n//    0 and it is destroyed, preventing the child from acquiring it. The\n//    parent now has to release it, or read operations on the read end of\n//    the pipe will not return when the child terminates.\n// 5. The parent reads child's output through the pipe (outcome code and\n//    any possible error messages) from the pipe, and its stderr and then\n//    determines whether to fail the test.\n//\n// Note: to distinguish Win32 API calls from the local method and function\n// calls, the former are explicitly resolved in the global namespace.\n//\nclass WindowsDeathTest : public DeathTestImpl {\n public:\n  WindowsDeathTest(const char* a_statement,\n                   const RE* a_regex,\n                   const char* file,\n                   int line)\n      : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}\n\n  // All of these virtual functions are inherited from DeathTest.\n  virtual int Wait();\n  virtual TestRole AssumeRole();\n\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n  // Handle to the write end of the pipe to the child process.\n  AutoHandle write_handle_;\n  // Child process handle.\n  AutoHandle child_handle_;\n  // Event the child process uses to signal the parent that it has\n  // acquired the handle to the write end of the pipe. After seeing this\n  // event the parent can release its own handles to make sure its\n  // ReadFile() calls return when the child terminates.\n  AutoHandle event_handle_;\n};\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint WindowsDeathTest::Wait() {\n  if (!spawned())\n    return 0;\n\n  // Wait until the child either signals that it has acquired the write end\n  // of the pipe or it dies.\n  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };\n  switch (::WaitForMultipleObjects(2,\n                                   wait_handles,\n                                   FALSE,  // Waits for any of the handles.\n                                   INFINITE)) {\n    case WAIT_OBJECT_0:\n    case WAIT_OBJECT_0 + 1:\n      break;\n    default:\n      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.\n  }\n\n  // The child has acquired the write end of the pipe or exited.\n  // We release the handle on our side and continue.\n  write_handle_.Reset();\n  event_handle_.Reset();\n\n  ReadAndInterpretStatusByte();\n\n  // Waits for the child process to exit if it haven't already. This\n  // returns immediately if the child has already exited, regardless of\n  // whether previous calls to WaitForMultipleObjects synchronized on this\n  // handle or not.\n  GTEST_DEATH_TEST_CHECK_(\n      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),\n                                             INFINITE));\n  DWORD status_code;\n  GTEST_DEATH_TEST_CHECK_(\n      ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);\n  child_handle_.Reset();\n  set_status(static_cast<int>(status_code));\n  return status();\n}\n\n// The AssumeRole process for a Windows death test.  It creates a child\n// process with the same executable as the current process to run the\n// death test.  The child process is given the --gtest_filter and\n// --gtest_internal_run_death_test flags such that it knows to run the\n// current death test only.\nDeathTest::TestRole WindowsDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != NULL) {\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\n    // processing.\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  // WindowsDeathTest uses an anonymous pipe to communicate results of\n  // a death test.\n  SECURITY_ATTRIBUTES handles_are_inheritable = {\n    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };\n  HANDLE read_handle, write_handle;\n  GTEST_DEATH_TEST_CHECK_(\n      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,\n                   0)  // Default buffer size.\n      != FALSE);\n  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),\n                                O_RDONLY));\n  write_handle_.Reset(write_handle);\n  event_handle_.Reset(::CreateEvent(\n      &handles_are_inheritable,\n      TRUE,    // The event will automatically reset to non-signaled state.\n      FALSE,   // The initial state is non-signalled.\n      NULL));  // The even is unnamed.\n  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);\n  const String filter_flag = String::Format(\"--%s%s=%s.%s\",\n                                            GTEST_FLAG_PREFIX_, kFilterFlag,\n                                            info->test_case_name(),\n                                            info->name());\n  const String internal_flag = String::Format(\n    \"--%s%s=%s|%d|%d|%u|%Iu|%Iu\",\n      GTEST_FLAG_PREFIX_,\n      kInternalRunDeathTestFlag,\n      file_, line_,\n      death_test_index,\n      static_cast<unsigned int>(::GetCurrentProcessId()),\n      // size_t has the same with as pointers on both 32-bit and 64-bit\n      // Windows platforms.\n      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.\n      reinterpret_cast<size_t>(write_handle),\n      reinterpret_cast<size_t>(event_handle_.Get()));\n\n  char executable_path[_MAX_PATH + 1];  // NOLINT\n  GTEST_DEATH_TEST_CHECK_(\n      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,\n                                            executable_path,\n                                            _MAX_PATH));\n\n  String command_line = String::Format(\"%s %s \\\"%s\\\"\",\n                                       ::GetCommandLineA(),\n                                       filter_flag.c_str(),\n                                       internal_flag.c_str());\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // Flush the log buffers since the log streams are shared with the child.\n  FlushInfoLog();\n\n  // The child process will share the standard handles with the parent.\n  STARTUPINFOA startup_info;\n  memset(&startup_info, 0, sizeof(STARTUPINFO));\n  startup_info.dwFlags = STARTF_USESTDHANDLES;\n  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);\n  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);\n  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);\n\n  PROCESS_INFORMATION process_info;\n  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(\n      executable_path,\n      const_cast<char*>(command_line.c_str()),\n      NULL,   // Retuned process handle is not inheritable.\n      NULL,   // Retuned thread handle is not inheritable.\n      TRUE,   // Child inherits all inheritable handles (for write_handle_).\n      0x0,    // Default creation flags.\n      NULL,   // Inherit the parent's environment.\n      UnitTest::GetInstance()->original_working_dir(),\n      &startup_info,\n      &process_info) != FALSE);\n  child_handle_.Reset(process_info.hProcess);\n  ::CloseHandle(process_info.hThread);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n# else  // We are not on Windows.\n\n// ForkingDeathTest provides implementations for most of the abstract\n// methods of the DeathTest interface.  Only the AssumeRole method is\n// left undefined.\nclass ForkingDeathTest : public DeathTestImpl {\n public:\n  ForkingDeathTest(const char* statement, const RE* regex);\n\n  // All of these virtual functions are inherited from DeathTest.\n  virtual int Wait();\n\n protected:\n  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }\n\n private:\n  // PID of child process during death test; 0 in the child process itself.\n  pid_t child_pid_;\n};\n\n// Constructs a ForkingDeathTest.\nForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)\n    : DeathTestImpl(a_statement, a_regex),\n      child_pid_(-1) {}\n\n// Waits for the child in a death test to exit, returning its exit\n// status, or 0 if no child process exists.  As a side effect, sets the\n// outcome data member.\nint ForkingDeathTest::Wait() {\n  if (!spawned())\n    return 0;\n\n  ReadAndInterpretStatusByte();\n\n  int status_value;\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));\n  set_status(status_value);\n  return status_value;\n}\n\n// A concrete death test class that forks, then immediately runs the test\n// in the child process.\nclass NoExecDeathTest : public ForkingDeathTest {\n public:\n  NoExecDeathTest(const char* a_statement, const RE* a_regex) :\n      ForkingDeathTest(a_statement, a_regex) { }\n  virtual TestRole AssumeRole();\n};\n\n// The AssumeRole process for a fork-and-run death test.  It implements a\n// straightforward fork, with a simple pipe to transmit the status byte.\nDeathTest::TestRole NoExecDeathTest::AssumeRole() {\n  const size_t thread_count = GetThreadCount();\n  if (thread_count != 1) {\n    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n\n  DeathTest::set_last_death_test_message(\"\");\n  CaptureStderr();\n  // When we fork the process below, the log file buffers are copied, but the\n  // file descriptors are shared.  We flush all log files here so that closing\n  // the file descriptors in the child process doesn't throw off the\n  // synchronization between descriptors and buffers in the parent process.\n  // This is as close to the fork as possible to avoid a race condition in case\n  // there are multiple threads running before the death test, and another\n  // thread writes to the log file.\n  FlushInfoLog();\n\n  const pid_t child_pid = fork();\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  set_child_pid(child_pid);\n  if (child_pid == 0) {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));\n    set_write_fd(pipe_fd[1]);\n    // Redirects all logging to stderr in the child process to prevent\n    // concurrent writes to the log files.  We capture stderr in the parent\n    // process and append the child process' output to a log.\n    LogToStderr();\n    // Event forwarding to the listeners of event listener API mush be shut\n    // down in death test subprocesses.\n    GetUnitTestImpl()->listeners()->SuppressEventForwarding();\n    return EXECUTE_TEST;\n  } else {\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n    set_read_fd(pipe_fd[0]);\n    set_spawned(true);\n    return OVERSEE_TEST;\n  }\n}\n\n// A concrete death test class that forks and re-executes the main\n// program from the beginning, with command-line flags set that cause\n// only this specific death test to be run.\nclass ExecDeathTest : public ForkingDeathTest {\n public:\n  ExecDeathTest(const char* a_statement, const RE* a_regex,\n                const char* file, int line) :\n      ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }\n  virtual TestRole AssumeRole();\n private:\n  // The name of the file in which the death test is located.\n  const char* const file_;\n  // The line number on which the death test is located.\n  const int line_;\n};\n\n// Utility class for accumulating command-line arguments.\nclass Arguments {\n public:\n  Arguments() {\n    args_.push_back(NULL);\n  }\n\n  ~Arguments() {\n    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();\n         ++i) {\n      free(*i);\n    }\n  }\n  void AddArgument(const char* argument) {\n    args_.insert(args_.end() - 1, posix::StrDup(argument));\n  }\n\n  template <typename Str>\n  void AddArguments(const ::std::vector<Str>& arguments) {\n    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();\n         i != arguments.end();\n         ++i) {\n      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));\n    }\n  }\n  char* const* Argv() {\n    return &args_[0];\n  }\n private:\n  std::vector<char*> args_;\n};\n\n// A struct that encompasses the arguments to the child process of a\n// threadsafe-style death test process.\nstruct ExecDeathTestArgs {\n  char* const* argv;  // Command-line arguments for the child's call to exec\n  int close_fd;       // File descriptor to close; the read end of a pipe\n};\n\n#  if GTEST_OS_MAC\ninline char** GetEnviron() {\n  // When Google Test is built as a framework on MacOS X, the environ variable\n  // is unavailable. Apple's documentation (man environ) recommends using\n  // _NSGetEnviron() instead.\n  return *_NSGetEnviron();\n}\n#  else\n// Some POSIX platforms expect you to declare environ. extern \"C\" makes\n// it reside in the global namespace.\nextern \"C\" char** environ;\ninline char** GetEnviron() { return environ; }\n#  endif  // GTEST_OS_MAC\n\n// The main function for a threadsafe-style death test child process.\n// This function is called in a clone()-ed process and thus must avoid\n// any potentially unsafe operations like malloc or libc functions.\nstatic int ExecDeathTestChildMain(void* child_arg) {\n  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));\n\n  // We need to execute the test program in the same environment where\n  // it was originally invoked.  Therefore we change to the original\n  // working directory first.\n  const char* const original_dir =\n      UnitTest::GetInstance()->original_working_dir();\n  // We can safely call chdir() as it's a direct system call.\n  if (chdir(original_dir) != 0) {\n    DeathTestAbort(String::Format(\"chdir(\\\"%s\\\") failed: %s\",\n                                  original_dir,\n                                  GetLastErrnoDescription().c_str()));\n    return EXIT_FAILURE;\n  }\n\n  // We can safely call execve() as it's a direct system call.  We\n  // cannot use execvp() as it's a libc function and thus potentially\n  // unsafe.  Since execve() doesn't search the PATH, the user must\n  // invoke the test program via a valid path that contains at least\n  // one path separator.\n  execve(args->argv[0], args->argv, GetEnviron());\n  DeathTestAbort(String::Format(\"execve(%s, ...) in %s failed: %s\",\n                                args->argv[0],\n                                original_dir,\n                                GetLastErrnoDescription().c_str()));\n  return EXIT_FAILURE;\n}\n\n// Two utility routines that together determine the direction the stack\n// grows.\n// This could be accomplished more elegantly by a single recursive\n// function, but we want to guard against the unlikely possibility of\n// a smart compiler optimizing the recursion away.\n//\n// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining\n// StackLowerThanAddress into StackGrowsDown, which then doesn't give\n// correct answer.\nbool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_;\nbool StackLowerThanAddress(const void* ptr) {\n  int dummy;\n  return &dummy < ptr;\n}\n\nbool StackGrowsDown() {\n  int dummy;\n  return StackLowerThanAddress(&dummy);\n}\n\n// A threadsafe implementation of fork(2) for threadsafe-style death tests\n// that uses clone(2).  It dies with an error message if anything goes\n// wrong.\nstatic pid_t ExecDeathTestFork(char* const* argv, int close_fd) {\n  ExecDeathTestArgs args = { argv, close_fd };\n  pid_t child_pid = -1;\n\n#  if GTEST_HAS_CLONE\n  const bool use_fork = GTEST_FLAG(death_test_use_fork);\n\n  if (!use_fork) {\n    static const bool stack_grows_down = StackGrowsDown();\n    const size_t stack_size = getpagesize();\n    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.\n    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,\n                             MAP_ANON | MAP_PRIVATE, -1, 0);\n    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);\n    void* const stack_top =\n        static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);\n\n    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);\n\n    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);\n  }\n#  else\n  const bool use_fork = true;\n#  endif  // GTEST_HAS_CLONE\n\n  if (use_fork && (child_pid = fork()) == 0) {\n      ExecDeathTestChildMain(&args);\n      _exit(0);\n  }\n\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\n  return child_pid;\n}\n\n// The AssumeRole process for a fork-and-exec death test.  It re-executes the\n// main program from the beginning, setting the --gtest_filter\n// and --gtest_internal_run_death_test flags to cause only the current\n// death test to be re-run.\nDeathTest::TestRole ExecDeathTest::AssumeRole() {\n  const UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const TestInfo* const info = impl->current_test_info();\n  const int death_test_index = info->result()->death_test_count();\n\n  if (flag != NULL) {\n    set_write_fd(flag->write_fd());\n    return EXECUTE_TEST;\n  }\n\n  int pipe_fd[2];\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\n  // Clear the close-on-exec flag on the write end of the pipe, lest\n  // it be closed when the child process does an exec:\n  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);\n\n  const String filter_flag =\n      String::Format(\"--%s%s=%s.%s\",\n                     GTEST_FLAG_PREFIX_, kFilterFlag,\n                     info->test_case_name(), info->name());\n  const String internal_flag =\n      String::Format(\"--%s%s=%s|%d|%d|%d\",\n                     GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag,\n                     file_, line_, death_test_index, pipe_fd[1]);\n  Arguments args;\n  args.AddArguments(GetArgvs());\n  args.AddArgument(filter_flag.c_str());\n  args.AddArgument(internal_flag.c_str());\n\n  DeathTest::set_last_death_test_message(\"\");\n\n  CaptureStderr();\n  // See the comment in NoExecDeathTest::AssumeRole for why the next line\n  // is necessary.\n  FlushInfoLog();\n\n  const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]);\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\n  set_child_pid(child_pid);\n  set_read_fd(pipe_fd[0]);\n  set_spawned(true);\n  return OVERSEE_TEST;\n}\n\n# endif  // !GTEST_OS_WINDOWS\n\n// Creates a concrete DeathTest-derived class that depends on the\n// --gtest_death_test_style flag, and sets the pointer pointed to\n// by the \"test\" argument to its address.  If the test should be\n// skipped, sets that pointer to NULL.  Returns true, unless the\n// flag is set to an invalid value.\nbool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,\n                                     const char* file, int line,\n                                     DeathTest** test) {\n  UnitTestImpl* const impl = GetUnitTestImpl();\n  const InternalRunDeathTestFlag* const flag =\n      impl->internal_run_death_test_flag();\n  const int death_test_index = impl->current_test_info()\n      ->increment_death_test_count();\n\n  if (flag != NULL) {\n    if (death_test_index > flag->index()) {\n      DeathTest::set_last_death_test_message(String::Format(\n          \"Death test count (%d) somehow exceeded expected maximum (%d)\",\n          death_test_index, flag->index()));\n      return false;\n    }\n\n    if (!(flag->file() == file && flag->line() == line &&\n          flag->index() == death_test_index)) {\n      *test = NULL;\n      return true;\n    }\n  }\n\n# if GTEST_OS_WINDOWS\n\n  if (GTEST_FLAG(death_test_style) == \"threadsafe\" ||\n      GTEST_FLAG(death_test_style) == \"fast\") {\n    *test = new WindowsDeathTest(statement, regex, file, line);\n  }\n\n# else\n\n  if (GTEST_FLAG(death_test_style) == \"threadsafe\") {\n    *test = new ExecDeathTest(statement, regex, file, line);\n  } else if (GTEST_FLAG(death_test_style) == \"fast\") {\n    *test = new NoExecDeathTest(statement, regex);\n  }\n\n# endif  // GTEST_OS_WINDOWS\n\n  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.\n    DeathTest::set_last_death_test_message(String::Format(\n        \"Unknown death test style \\\"%s\\\" encountered\",\n        GTEST_FLAG(death_test_style).c_str()));\n    return false;\n  }\n\n  return true;\n}\n\n// Splits a given string on a given delimiter, populating a given\n// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have\n// ::std::string, so we can use it here.\nstatic void SplitString(const ::std::string& str, char delimiter,\n                        ::std::vector< ::std::string>* dest) {\n  ::std::vector< ::std::string> parsed;\n  ::std::string::size_type pos = 0;\n  while (::testing::internal::AlwaysTrue()) {\n    const ::std::string::size_type colon = str.find(delimiter, pos);\n    if (colon == ::std::string::npos) {\n      parsed.push_back(str.substr(pos));\n      break;\n    } else {\n      parsed.push_back(str.substr(pos, colon - pos));\n      pos = colon + 1;\n    }\n  }\n  dest->swap(parsed);\n}\n\n# if GTEST_OS_WINDOWS\n// Recreates the pipe and event handles from the provided parameters,\n// signals the event, and returns a file descriptor wrapped around the pipe\n// handle. This function is called in the child process only.\nint GetStatusFileDescriptor(unsigned int parent_process_id,\n                            size_t write_handle_as_size_t,\n                            size_t event_handle_as_size_t) {\n  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,\n                                                   FALSE,  // Non-inheritable.\n                                                   parent_process_id));\n  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {\n    DeathTestAbort(String::Format(\"Unable to open parent process %u\",\n                                  parent_process_id));\n  }\n\n  // TODO(vladl@google.com): Replace the following check with a\n  // compile-time assertion when available.\n  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));\n\n  const HANDLE write_handle =\n      reinterpret_cast<HANDLE>(write_handle_as_size_t);\n  HANDLE dup_write_handle;\n\n  // The newly initialized handle is accessible only in in the parent\n  // process. To obtain one accessible within the child, we need to use\n  // DuplicateHandle.\n  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,\n                         ::GetCurrentProcess(), &dup_write_handle,\n                         0x0,    // Requested privileges ignored since\n                                 // DUPLICATE_SAME_ACCESS is used.\n                         FALSE,  // Request non-inheritable handler.\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(String::Format(\n        \"Unable to duplicate the pipe handle %Iu from the parent process %u\",\n        write_handle_as_size_t, parent_process_id));\n  }\n\n  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);\n  HANDLE dup_event_handle;\n\n  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,\n                         ::GetCurrentProcess(), &dup_event_handle,\n                         0x0,\n                         FALSE,\n                         DUPLICATE_SAME_ACCESS)) {\n    DeathTestAbort(String::Format(\n        \"Unable to duplicate the event handle %Iu from the parent process %u\",\n        event_handle_as_size_t, parent_process_id));\n  }\n\n  const int write_fd =\n      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);\n  if (write_fd == -1) {\n    DeathTestAbort(String::Format(\n        \"Unable to convert pipe handle %Iu to a file descriptor\",\n        write_handle_as_size_t));\n  }\n\n  // Signals the parent that the write end of the pipe has been acquired\n  // so the parent can release its own write end.\n  ::SetEvent(dup_event_handle);\n\n  return write_fd;\n}\n# endif  // GTEST_OS_WINDOWS\n\n// Returns a newly created InternalRunDeathTestFlag object with fields\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\n// the flag is specified; otherwise returns NULL.\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {\n  if (GTEST_FLAG(internal_run_death_test) == \"\") return NULL;\n\n  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we\n  // can use it here.\n  int line = -1;\n  int index = -1;\n  ::std::vector< ::std::string> fields;\n  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);\n  int write_fd = -1;\n\n# if GTEST_OS_WINDOWS\n\n  unsigned int parent_process_id = 0;\n  size_t write_handle_as_size_t = 0;\n  size_t event_handle_as_size_t = 0;\n\n  if (fields.size() != 6\n      || !ParseNaturalNumber(fields[1], &line)\n      || !ParseNaturalNumber(fields[2], &index)\n      || !ParseNaturalNumber(fields[3], &parent_process_id)\n      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)\n      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {\n    DeathTestAbort(String::Format(\n        \"Bad --gtest_internal_run_death_test flag: %s\",\n        GTEST_FLAG(internal_run_death_test).c_str()));\n  }\n  write_fd = GetStatusFileDescriptor(parent_process_id,\n                                     write_handle_as_size_t,\n                                     event_handle_as_size_t);\n# else\n\n  if (fields.size() != 4\n      || !ParseNaturalNumber(fields[1], &line)\n      || !ParseNaturalNumber(fields[2], &index)\n      || !ParseNaturalNumber(fields[3], &write_fd)) {\n    DeathTestAbort(String::Format(\n        \"Bad --gtest_internal_run_death_test flag: %s\",\n        GTEST_FLAG(internal_run_death_test).c_str()));\n  }\n\n# endif  // GTEST_OS_WINDOWS\n\n  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);\n}\n\n}  // namespace internal\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n}  // namespace testing\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Authors: keith.ray@gmail.com (Keith Ray)\n\n\n#include <stdlib.h>\n\n#if GTEST_OS_WINDOWS_MOBILE\n# include <windows.h>\n#elif GTEST_OS_WINDOWS\n# include <direct.h>\n# include <io.h>\n#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL\n// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h\n# include <sys/syslimits.h>\n#else\n# include <limits.h>\n# include <climits>  // Some Linux distributions define PATH_MAX here.\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n#if GTEST_OS_WINDOWS\n# define GTEST_PATH_MAX_ _MAX_PATH\n#elif defined(PATH_MAX)\n# define GTEST_PATH_MAX_ PATH_MAX\n#elif defined(_XOPEN_PATH_MAX)\n# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX\n#elif defined(_POSIX_PATH_MAX)\n# define GTEST_PATH_MAX_ _POSIX_PATH_MAX\n#else // conservately set to 256\n#define GTEST_PATH_MAX_ 256\n#endif  // GTEST_OS_WINDOWS\n\n\nnamespace testing {\nnamespace internal {\n\n#if GTEST_OS_WINDOWS\n// On Windows, '\\\\' is the standard path separator, but many tools and the\n// Windows API also accept '/' as an alternate path separator. Unless otherwise\n// noted, a file path can contain either kind of path separators, or a mixture\n// of them.\nconst char kPathSeparator = '\\\\';\nconst char kAlternatePathSeparator = '/';\nconst char kPathSeparatorString[] = \"\\\\\";\nconst char kAlternatePathSeparatorString[] = \"/\";\n# if GTEST_OS_WINDOWS_MOBILE\n// Windows CE doesn't have a current directory. You should not use\n// the current directory in tests on Windows CE, but this at least\n// provides a reasonable fallback.\nconst char kCurrentDirectoryString[] = \"\\\\\";\n// Windows CE doesn't define INVALID_FILE_ATTRIBUTES\nconst DWORD kInvalidFileAttributes = 0xffffffff;\n# else\nconst char kCurrentDirectoryString[] = \".\\\\\";\n# endif  // GTEST_OS_WINDOWS_MOBILE\n#else\nconst char kPathSeparator = '/';\nconst char kPathSeparatorString[] = \"/\";\nconst char kCurrentDirectoryString[] = \"./\";\n#endif  // GTEST_OS_WINDOWS\n\n// Returns whether the given character is a valid path separator.\nstatic bool IsPathSeparator(char c) {\n#if GTEST_HAS_ALT_PATH_SEP_\n  return (c == kPathSeparator) || (c == kAlternatePathSeparator);\n#else\n  return c == kPathSeparator;\n#endif\n}\n\n// Returns the current working directory, or \"\" if unsuccessful.\nFilePath FilePath::GetCurrentDir() {\n#if GTEST_OS_WINDOWS_MOBILE\n  // Windows CE doesn't have a current directory, so we just return\n  // something reasonable.\n  return FilePath(kCurrentDirectoryString);\n#elif GTEST_OS_WINDOWS\n  char cwd[GTEST_PATH_MAX_ + 1] = { '\\0' };\n  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? \"\" : cwd);\n#else\n  char cwd[GTEST_PATH_MAX_ + 1] = { '\\0' };\n  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? \"\" : cwd);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns a copy of the FilePath with the case-insensitive extension removed.\n// Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\n// FilePath(\"dir/file\"). If a case-insensitive extension is not\n// found, returns a copy of the original FilePath.\nFilePath FilePath::RemoveExtension(const char* extension) const {\n  String dot_extension(String::Format(\".%s\", extension));\n  if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) {\n    return FilePath(String(pathname_.c_str(), pathname_.length() - 4));\n  }\n  return *this;\n}\n\n// Returns a pointer to the last occurence of a valid path separator in\n// the FilePath. On Windows, for example, both '/' and '\\' are valid path\n// separators. Returns NULL if no path separator was found.\nconst char* FilePath::FindLastPathSeparator() const {\n  const char* const last_sep = strrchr(c_str(), kPathSeparator);\n#if GTEST_HAS_ALT_PATH_SEP_\n  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);\n  // Comparing two pointers of which only one is NULL is undefined.\n  if (last_alt_sep != NULL &&\n      (last_sep == NULL || last_alt_sep > last_sep)) {\n    return last_alt_sep;\n  }\n#endif\n  return last_sep;\n}\n\n// Returns a copy of the FilePath with the directory part removed.\n// Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\n// FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\n// the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\n// returns an empty FilePath (\"\").\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveDirectoryName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  return last_sep ? FilePath(String(last_sep + 1)) : *this;\n}\n\n// RemoveFileName returns the directory path with the filename removed.\n// Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\n// If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\n// FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\n// not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\nFilePath FilePath::RemoveFileName() const {\n  const char* const last_sep = FindLastPathSeparator();\n  String dir;\n  if (last_sep) {\n    dir = String(c_str(), last_sep + 1 - c_str());\n  } else {\n    dir = kCurrentDirectoryString;\n  }\n  return FilePath(dir);\n}\n\n// Helper functions for naming files in a directory for xml output.\n\n// Given directory = \"dir\", base_name = \"test\", number = 0,\n// extension = \"xml\", returns \"dir/test.xml\". If number is greater\n// than zero (e.g., 12), returns \"dir/test_12.xml\".\n// On Windows platform, uses \\ as the separator rather than /.\nFilePath FilePath::MakeFileName(const FilePath& directory,\n                                const FilePath& base_name,\n                                int number,\n                                const char* extension) {\n  String file;\n  if (number == 0) {\n    file = String::Format(\"%s.%s\", base_name.c_str(), extension);\n  } else {\n    file = String::Format(\"%s_%d.%s\", base_name.c_str(), number, extension);\n  }\n  return ConcatPaths(directory, FilePath(file));\n}\n\n// Given directory = \"dir\", relative_path = \"test.xml\", returns \"dir/test.xml\".\n// On Windows, uses \\ as the separator rather than /.\nFilePath FilePath::ConcatPaths(const FilePath& directory,\n                               const FilePath& relative_path) {\n  if (directory.IsEmpty())\n    return relative_path;\n  const FilePath dir(directory.RemoveTrailingPathSeparator());\n  return FilePath(String::Format(\"%s%c%s\", dir.c_str(), kPathSeparator,\n                                 relative_path.c_str()));\n}\n\n// Returns true if pathname describes something findable in the file-system,\n// either a file, directory, or whatever.\nbool FilePath::FileOrDirectoryExists() const {\n#if GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete [] unicode;\n  return attributes != kInvalidFileAttributes;\n#else\n  posix::StatStruct file_stat;\n  return posix::Stat(pathname_.c_str(), &file_stat) == 0;\n#endif  // GTEST_OS_WINDOWS_MOBILE\n}\n\n// Returns true if pathname describes a directory in the file-system\n// that exists.\nbool FilePath::DirectoryExists() const {\n  bool result = false;\n#if GTEST_OS_WINDOWS\n  // Don't strip off trailing separator if path is a root directory on\n  // Windows (like \"C:\\\\\").\n  const FilePath& path(IsRootDirectory() ? *this :\n                                           RemoveTrailingPathSeparator());\n#else\n  const FilePath& path(*this);\n#endif\n\n#if GTEST_OS_WINDOWS_MOBILE\n  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());\n  const DWORD attributes = GetFileAttributes(unicode);\n  delete [] unicode;\n  if ((attributes != kInvalidFileAttributes) &&\n      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {\n    result = true;\n  }\n#else\n  posix::StatStruct file_stat;\n  result = posix::Stat(path.c_str(), &file_stat) == 0 &&\n      posix::IsDir(file_stat);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  return result;\n}\n\n// Returns true if pathname describes a root directory. (Windows has one\n// root directory per disk drive.)\nbool FilePath::IsRootDirectory() const {\n#if GTEST_OS_WINDOWS\n  // TODO(wan@google.com): on Windows a network share like\n  // \\\\server\\share can be a root directory, although it cannot be the\n  // current directory.  Handle this properly.\n  return pathname_.length() == 3 && IsAbsolutePath();\n#else\n  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);\n#endif\n}\n\n// Returns true if pathname describes an absolute path.\nbool FilePath::IsAbsolutePath() const {\n  const char* const name = pathname_.c_str();\n#if GTEST_OS_WINDOWS\n  return pathname_.length() >= 3 &&\n     ((name[0] >= 'a' && name[0] <= 'z') ||\n      (name[0] >= 'A' && name[0] <= 'Z')) &&\n     name[1] == ':' &&\n     IsPathSeparator(name[2]);\n#else\n  return IsPathSeparator(name[0]);\n#endif\n}\n\n// Returns a pathname for a file that does not currently exist. The pathname\n// will be directory/base_name.extension or\n// directory/base_name_<number>.extension if directory/base_name.extension\n// already exists. The number will be incremented until a pathname is found\n// that does not already exist.\n// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\n// There could be a race condition if two or more processes are calling this\n// function at the same time -- they could both pick the same filename.\nFilePath FilePath::GenerateUniqueFileName(const FilePath& directory,\n                                          const FilePath& base_name,\n                                          const char* extension) {\n  FilePath full_pathname;\n  int number = 0;\n  do {\n    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));\n  } while (full_pathname.FileOrDirectoryExists());\n  return full_pathname;\n}\n\n// Returns true if FilePath ends with a path separator, which indicates that\n// it is intended to represent a directory. Returns false otherwise.\n// This does NOT check that a directory (or file) actually exists.\nbool FilePath::IsDirectory() const {\n  return !pathname_.empty() &&\n         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);\n}\n\n// Create directories so that path exists. Returns true if successful or if\n// the directories already exist; returns false if unable to create directories\n// for any reason.\nbool FilePath::CreateDirectoriesRecursively() const {\n  if (!this->IsDirectory()) {\n    return false;\n  }\n\n  if (pathname_.length() == 0 || this->DirectoryExists()) {\n    return true;\n  }\n\n  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());\n  return parent.CreateDirectoriesRecursively() && this->CreateFolder();\n}\n\n// Create the directory so that path exists. Returns true if successful or\n// if the directory already exists; returns false if unable to create the\n// directory for any reason, including if the parent directory does not\n// exist. Not named \"CreateDirectory\" because that's a macro on Windows.\nbool FilePath::CreateFolder() const {\n#if GTEST_OS_WINDOWS_MOBILE\n  FilePath removed_sep(this->RemoveTrailingPathSeparator());\n  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());\n  int result = CreateDirectory(unicode, NULL) ? 0 : -1;\n  delete [] unicode;\n#elif GTEST_OS_WINDOWS\n  int result = _mkdir(pathname_.c_str());\n#else\n  int result = mkdir(pathname_.c_str(), 0777);\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n  if (result == -1) {\n    return this->DirectoryExists();  // An error is OK if the directory exists.\n  }\n  return true;  // No error.\n}\n\n// If input name has a trailing separator character, remove it and return the\n// name, otherwise return the name string unmodified.\n// On Windows platform, uses \\ as the separator, other platforms use /.\nFilePath FilePath::RemoveTrailingPathSeparator() const {\n  return IsDirectory()\n      ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))\n      : *this;\n}\n\n// Removes any redundant separators that might be in the pathname.\n// For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\n// redundancies that might be in a pathname involving \".\" or \"..\".\n// TODO(wan@google.com): handle Windows network shares (e.g. \\\\server\\share).\nvoid FilePath::Normalize() {\n  if (pathname_.c_str() == NULL) {\n    pathname_ = \"\";\n    return;\n  }\n  const char* src = pathname_.c_str();\n  char* const dest = new char[pathname_.length() + 1];\n  char* dest_ptr = dest;\n  memset(dest_ptr, 0, pathname_.length() + 1);\n\n  while (*src != '\\0') {\n    *dest_ptr = *src;\n    if (!IsPathSeparator(*src)) {\n      src++;\n    } else {\n#if GTEST_HAS_ALT_PATH_SEP_\n      if (*dest_ptr == kAlternatePathSeparator) {\n        *dest_ptr = kPathSeparator;\n      }\n#endif\n      while (IsPathSeparator(*src))\n        src++;\n    }\n    dest_ptr++;\n  }\n  *dest_ptr = '\\0';\n  pathname_ = dest;\n  delete[] dest;\n}\n\n}  // namespace internal\n}  // namespace testing\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n\n#include <limits.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n#if GTEST_OS_WINDOWS_MOBILE\n# include <windows.h>  // For TerminateProcess()\n#elif GTEST_OS_WINDOWS\n# include <io.h>\n# include <sys/stat.h>\n#else\n# include <unistd.h>\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n#if GTEST_OS_MAC\n# include <mach/mach_init.h>\n# include <mach/task.h>\n# include <mach/vm_map.h>\n#endif  // GTEST_OS_MAC\n\n\n// Indicates that this translation unit is part of Google Test's\n// implementation.  It must come before gtest-internal-inl.h is\n// included, or there will be a compiler error.  This trick is to\n// prevent a user from accidentally including gtest-internal-inl.h in\n// his code.\n#define GTEST_IMPLEMENTATION_ 1\n#undef GTEST_IMPLEMENTATION_\n\nnamespace testing {\nnamespace internal {\n\n#if defined(_MSC_VER) || defined(__BORLANDC__)\n// MSVC and C++Builder do not provide a definition of STDERR_FILENO.\nconst int kStdOutFileno = 1;\nconst int kStdErrFileno = 2;\n#else\nconst int kStdOutFileno = STDOUT_FILENO;\nconst int kStdErrFileno = STDERR_FILENO;\n#endif  // _MSC_VER\n\n#if GTEST_OS_MAC\n\n// Returns the number of threads running in the process, or 0 to indicate that\n// we cannot detect it.\nsize_t GetThreadCount() {\n  const task_t task = mach_task_self();\n  mach_msg_type_number_t thread_count;\n  thread_act_array_t thread_list;\n  const kern_return_t status = task_threads(task, &thread_list, &thread_count);\n  if (status == KERN_SUCCESS) {\n    // task_threads allocates resources in thread_list and we need to free them\n    // to avoid leaks.\n    vm_deallocate(task,\n                  reinterpret_cast<vm_address_t>(thread_list),\n                  sizeof(thread_t) * thread_count);\n    return static_cast<size_t>(thread_count);\n  } else {\n    return 0;\n  }\n}\n\n#else\n\nsize_t GetThreadCount() {\n  // There's no portable way to detect the number of threads, so we just\n  // return 0 to indicate that we cannot detect it.\n  return 0;\n}\n\n#endif  // GTEST_OS_MAC\n\n#if GTEST_USES_POSIX_RE\n\n// Implements RE.  Currently only needed for death tests.\n\nRE::~RE() {\n  if (is_valid_) {\n    // regfree'ing an invalid regex might crash because the content\n    // of the regex is undefined. Since the regex's are essentially\n    // the same, one cannot be valid (or invalid) without the other\n    // being so too.\n    regfree(&partial_regex_);\n    regfree(&full_regex_);\n  }\n  free(const_cast<char*>(pattern_));\n}\n\n// Returns true iff regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;\n}\n\n// Returns true iff regular expression re matches a substring of str\n// (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  if (!re.is_valid_) return false;\n\n  regmatch_t match;\n  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  pattern_ = posix::StrDup(regex);\n\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match.\n  const size_t full_regex_len = strlen(regex) + 10;\n  char* const full_pattern = new char[full_regex_len];\n\n  snprintf(full_pattern, full_regex_len, \"^(%s)$\", regex);\n  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;\n  // We want to call regcomp(&partial_regex_, ...) even if the\n  // previous expression returns false.  Otherwise partial_regex_ may\n  // not be properly initialized can may cause trouble when it's\n  // freed.\n  //\n  // Some implementation of POSIX regex (e.g. on at least some\n  // versions of Cygwin) doesn't accept the empty string as a valid\n  // regex.  We change it to an equivalent form \"()\" to be safe.\n  if (is_valid_) {\n    const char* const partial_regex = (*regex == '\\0') ? \"()\" : regex;\n    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;\n  }\n  EXPECT_TRUE(is_valid_)\n      << \"Regular expression \\\"\" << regex\n      << \"\\\" is not a valid POSIX Extended regular expression.\";\n\n  delete[] full_pattern;\n}\n\n#elif GTEST_USES_SIMPLE_RE\n\n// Returns true iff ch appears anywhere in str (excluding the\n// terminating '\\0' character).\nbool IsInSet(char ch, const char* str) {\n  return ch != '\\0' && strchr(str, ch) != NULL;\n}\n\n// Returns true iff ch belongs to the given classification.  Unlike\n// similar functions in <ctype.h>, these aren't affected by the\n// current locale.\nbool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }\nbool IsAsciiPunct(char ch) {\n  return IsInSet(ch, \"^-!\\\"#$%&'()*+,./:;<=>?@[\\\\]_`{|}~\");\n}\nbool IsRepeat(char ch) { return IsInSet(ch, \"?*+\"); }\nbool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, \" \\f\\n\\r\\t\\v\"); }\nbool IsAsciiWordChar(char ch) {\n  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||\n      ('0' <= ch && ch <= '9') || ch == '_';\n}\n\n// Returns true iff \"\\\\c\" is a supported escape sequence.\nbool IsValidEscape(char c) {\n  return (IsAsciiPunct(c) || IsInSet(c, \"dDfnrsStvwW\"));\n}\n\n// Returns true iff the given atom (specified by escaped and pattern)\n// matches ch.  The result is undefined if the atom is invalid.\nbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {\n  if (escaped) {  // \"\\\\p\" where p is pattern_char.\n    switch (pattern_char) {\n      case 'd': return IsAsciiDigit(ch);\n      case 'D': return !IsAsciiDigit(ch);\n      case 'f': return ch == '\\f';\n      case 'n': return ch == '\\n';\n      case 'r': return ch == '\\r';\n      case 's': return IsAsciiWhiteSpace(ch);\n      case 'S': return !IsAsciiWhiteSpace(ch);\n      case 't': return ch == '\\t';\n      case 'v': return ch == '\\v';\n      case 'w': return IsAsciiWordChar(ch);\n      case 'W': return !IsAsciiWordChar(ch);\n    }\n    return IsAsciiPunct(pattern_char) && pattern_char == ch;\n  }\n\n  return (pattern_char == '.' && ch != '\\n') || pattern_char == ch;\n}\n\n// Helper function used by ValidateRegex() to format error messages.\nString FormatRegexSyntaxError(const char* regex, int index) {\n  return (Message() << \"Syntax error at index \" << index\n          << \" in simple regular expression \\\"\" << regex << \"\\\": \").GetString();\n}\n\n// Generates non-fatal failures and returns false if regex is invalid;\n// otherwise returns true.\nbool ValidateRegex(const char* regex) {\n  if (regex == NULL) {\n    // TODO(wan@google.com): fix the source file location in the\n    // assertion failures to match where the regex is used in user\n    // code.\n    ADD_FAILURE() << \"NULL is not a valid simple regular expression.\";\n    return false;\n  }\n\n  bool is_valid = true;\n\n  // True iff ?, *, or + can follow the previous atom.\n  bool prev_repeatable = false;\n  for (int i = 0; regex[i]; i++) {\n    if (regex[i] == '\\\\') {  // An escape sequence\n      i++;\n      if (regex[i] == '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"'\\\\' cannot appear at the end.\";\n        return false;\n      }\n\n      if (!IsValidEscape(regex[i])) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\n                      << \"invalid escape sequence \\\"\\\\\" << regex[i] << \"\\\".\";\n        is_valid = false;\n      }\n      prev_repeatable = true;\n    } else {  // Not an escape sequence.\n      const char ch = regex[i];\n\n      if (ch == '^' && i > 0) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'^' can only appear at the beginning.\";\n        is_valid = false;\n      } else if (ch == '$' && regex[i + 1] != '\\0') {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'$' can only appear at the end.\";\n        is_valid = false;\n      } else if (IsInSet(ch, \"()[]{}|\")) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'\" << ch << \"' is unsupported.\";\n        is_valid = false;\n      } else if (IsRepeat(ch) && !prev_repeatable) {\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\n                      << \"'\" << ch << \"' can only follow a repeatable token.\";\n        is_valid = false;\n      }\n\n      prev_repeatable = !IsInSet(ch, \"^$?*+\");\n    }\n  }\n\n  return is_valid;\n}\n\n// Matches a repeated regex atom followed by a valid simple regular\n// expression.  The regex atom is defined as c if escaped is false,\n// or \\c otherwise.  repeat is the repetition meta character (?, *,\n// or +).  The behavior is undefined if str contains too many\n// characters to be indexable by size_t, in which case the test will\n// probably time out anyway.  We are fine with this limitation as\n// std::string has it too.\nbool MatchRepetitionAndRegexAtHead(\n    bool escaped, char c, char repeat, const char* regex,\n    const char* str) {\n  const size_t min_count = (repeat == '+') ? 1 : 0;\n  const size_t max_count = (repeat == '?') ? 1 :\n      static_cast<size_t>(-1) - 1;\n  // We cannot call numeric_limits::max() as it conflicts with the\n  // max() macro on Windows.\n\n  for (size_t i = 0; i <= max_count; ++i) {\n    // We know that the atom matches each of the first i characters in str.\n    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {\n      // We have enough matches at the head, and the tail matches too.\n      // Since we only care about *whether* the pattern matches str\n      // (as opposed to *how* it matches), there is no need to find a\n      // greedy match.\n      return true;\n    }\n    if (str[i] == '\\0' || !AtomMatchesChar(escaped, c, str[i]))\n      return false;\n  }\n  return false;\n}\n\n// Returns true iff regex matches a prefix of str.  regex must be a\n// valid simple regular expression and not start with \"^\", or the\n// result is undefined.\nbool MatchRegexAtHead(const char* regex, const char* str) {\n  if (*regex == '\\0')  // An empty regex matches a prefix of anything.\n    return true;\n\n  // \"$\" only matches the end of a string.  Note that regex being\n  // valid guarantees that there's nothing after \"$\" in it.\n  if (*regex == '$')\n    return *str == '\\0';\n\n  // Is the first thing in regex an escape sequence?\n  const bool escaped = *regex == '\\\\';\n  if (escaped)\n    ++regex;\n  if (IsRepeat(regex[1])) {\n    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so\n    // here's an indirect recursion.  It terminates as the regex gets\n    // shorter in each recursion.\n    return MatchRepetitionAndRegexAtHead(\n        escaped, regex[0], regex[1], regex + 2, str);\n  } else {\n    // regex isn't empty, isn't \"$\", and doesn't start with a\n    // repetition.  We match the first atom of regex with the first\n    // character of str and recurse.\n    return (*str != '\\0') && AtomMatchesChar(escaped, *regex, *str) &&\n        MatchRegexAtHead(regex + 1, str + 1);\n  }\n}\n\n// Returns true iff regex matches any substring of str.  regex must be\n// a valid simple regular expression, or the result is undefined.\n//\n// The algorithm is recursive, but the recursion depth doesn't exceed\n// the regex length, so we won't need to worry about running out of\n// stack space normally.  In rare cases the time complexity can be\n// exponential with respect to the regex length + the string length,\n// but usually it's must faster (often close to linear).\nbool MatchRegexAnywhere(const char* regex, const char* str) {\n  if (regex == NULL || str == NULL)\n    return false;\n\n  if (*regex == '^')\n    return MatchRegexAtHead(regex + 1, str);\n\n  // A successful match can be anywhere in str.\n  do {\n    if (MatchRegexAtHead(regex, str))\n      return true;\n  } while (*str++ != '\\0');\n  return false;\n}\n\n// Implements the RE class.\n\nRE::~RE() {\n  free(const_cast<char*>(pattern_));\n  free(const_cast<char*>(full_pattern_));\n}\n\n// Returns true iff regular expression re matches the entire str.\nbool RE::FullMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);\n}\n\n// Returns true iff regular expression re matches a substring of str\n// (including str itself).\nbool RE::PartialMatch(const char* str, const RE& re) {\n  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);\n}\n\n// Initializes an RE from its string representation.\nvoid RE::Init(const char* regex) {\n  pattern_ = full_pattern_ = NULL;\n  if (regex != NULL) {\n    pattern_ = posix::StrDup(regex);\n  }\n\n  is_valid_ = ValidateRegex(regex);\n  if (!is_valid_) {\n    // No need to calculate the full pattern when the regex is invalid.\n    return;\n  }\n\n  const size_t len = strlen(regex);\n  // Reserves enough bytes to hold the regular expression used for a\n  // full match: we need space to prepend a '^', append a '$', and\n  // terminate the string with '\\0'.\n  char* buffer = static_cast<char*>(malloc(len + 3));\n  full_pattern_ = buffer;\n\n  if (*regex != '^')\n    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.\n\n  // We don't use snprintf or strncpy, as they trigger a warning when\n  // compiled with VC++ 8.0.\n  memcpy(buffer, regex, len);\n  buffer += len;\n\n  if (len == 0 || regex[len - 1] != '$')\n    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.\n\n  *buffer = '\\0';\n}\n\n#endif  // GTEST_USES_POSIX_RE\n\nconst char kUnknownFile[] = \"unknown file\";\n\n// Formats a source file path and a line number as they would appear\n// in an error message from the compiler used to compile this code.\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {\n  const char* const file_name = file == NULL ? kUnknownFile : file;\n\n  if (line < 0) {\n    return String::Format(\"%s:\", file_name).c_str();\n  }\n#ifdef _MSC_VER\n  return String::Format(\"%s(%d):\", file_name, line).c_str();\n#else\n  return String::Format(\"%s:%d:\", file_name, line).c_str();\n#endif  // _MSC_VER\n}\n\n// Formats a file location for compiler-independent XML output.\n// Although this function is not platform dependent, we put it next to\n// FormatFileLocation in order to contrast the two functions.\n// Note that FormatCompilerIndependentFileLocation() does NOT append colon\n// to the file location it produces, unlike FormatFileLocation().\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(\n    const char* file, int line) {\n  const char* const file_name = file == NULL ? kUnknownFile : file;\n\n  if (line < 0)\n    return file_name;\n  else\n    return String::Format(\"%s:%d\", file_name, line).c_str();\n}\n\n\nGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)\n    : severity_(severity) {\n  const char* const marker =\n      severity == GTEST_INFO ?    \"[  INFO ]\" :\n      severity == GTEST_WARNING ? \"[WARNING]\" :\n      severity == GTEST_ERROR ?   \"[ ERROR ]\" : \"[ FATAL ]\";\n  GetStream() << ::std::endl << marker << \" \"\n              << FormatFileLocation(file, line).c_str() << \": \";\n}\n\n// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\nGTestLog::~GTestLog() {\n  GetStream() << ::std::endl;\n  if (severity_ == GTEST_FATAL) {\n    fflush(stderr);\n    posix::Abort();\n  }\n}\n// Disable Microsoft deprecation warnings for POSIX functions called from\n// this class (creat, dup, dup2, and close)\n#ifdef _MSC_VER\n# pragma warning(push)\n# pragma warning(disable: 4996)\n#endif  // _MSC_VER\n\n#if GTEST_HAS_STREAM_REDIRECTION\n\n// Object that captures an output stream (stdout/stderr).\nclass CapturedStream {\n public:\n  // The ctor redirects the stream to a temporary file.\n  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {\n\n# if GTEST_OS_WINDOWS\n    char temp_dir_path[MAX_PATH + 1] = { '\\0' };  // NOLINT\n    char temp_file_path[MAX_PATH + 1] = { '\\0' };  // NOLINT\n\n    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);\n    const UINT success = ::GetTempFileNameA(temp_dir_path,\n                                            \"gtest_redir\",\n                                            0,  // Generate unique file name.\n                                            temp_file_path);\n    GTEST_CHECK_(success != 0)\n        << \"Unable to create a temporary file in \" << temp_dir_path;\n    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);\n    GTEST_CHECK_(captured_fd != -1) << \"Unable to open temporary file \"\n                                    << temp_file_path;\n    filename_ = temp_file_path;\n# else\n    // There's no guarantee that a test has write access to the\n    // current directory, so we create the temporary file in the /tmp\n    // directory instead.\n    char name_template[] = \"/tmp/captured_stream.XXXXXX\";\n    const int captured_fd = mkstemp(name_template);\n    filename_ = name_template;\n# endif  // GTEST_OS_WINDOWS\n    fflush(NULL);\n    dup2(captured_fd, fd_);\n    close(captured_fd);\n  }\n\n  ~CapturedStream() {\n    remove(filename_.c_str());\n  }\n\n  String GetCapturedString() {\n    if (uncaptured_fd_ != -1) {\n      // Restores the original stream.\n      fflush(NULL);\n      dup2(uncaptured_fd_, fd_);\n      close(uncaptured_fd_);\n      uncaptured_fd_ = -1;\n    }\n\n    FILE* const file = posix::FOpen(filename_.c_str(), \"r\");\n    const String content = ReadEntireFile(file);\n    posix::FClose(file);\n    return content;\n  }\n\n private:\n  // Reads the entire content of a file as a String.\n  static String ReadEntireFile(FILE* file);\n\n  // Returns the size (in bytes) of a file.\n  static size_t GetFileSize(FILE* file);\n\n  const int fd_;  // A stream to capture.\n  int uncaptured_fd_;\n  // Name of the temporary file holding the stderr output.\n  ::std::string filename_;\n\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);\n};\n\n// Returns the size (in bytes) of a file.\nsize_t CapturedStream::GetFileSize(FILE* file) {\n  fseek(file, 0, SEEK_END);\n  return static_cast<size_t>(ftell(file));\n}\n\n// Reads the entire content of a file as a string.\nString CapturedStream::ReadEntireFile(FILE* file) {\n  const size_t file_size = GetFileSize(file);\n  char* const buffer = new char[file_size];\n\n  size_t bytes_last_read = 0;  // # of bytes read in the last fread()\n  size_t bytes_read = 0;       // # of bytes read so far\n\n  fseek(file, 0, SEEK_SET);\n\n  // Keeps reading the file until we cannot read further or the\n  // pre-determined file size is reached.\n  do {\n    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);\n    bytes_read += bytes_last_read;\n  } while (bytes_last_read > 0 && bytes_read < file_size);\n\n  const String content(buffer, bytes_read);\n  delete[] buffer;\n\n  return content;\n}\n\n# ifdef _MSC_VER\n#  pragma warning(pop)\n# endif  // _MSC_VER\n\nstatic CapturedStream* g_captured_stderr = NULL;\nstatic CapturedStream* g_captured_stdout = NULL;\n\n// Starts capturing an output stream (stdout/stderr).\nvoid CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {\n  if (*stream != NULL) {\n    GTEST_LOG_(FATAL) << \"Only one \" << stream_name\n                      << \" capturer can exist at a time.\";\n  }\n  *stream = new CapturedStream(fd);\n}\n\n// Stops capturing the output stream and returns the captured string.\nString GetCapturedStream(CapturedStream** captured_stream) {\n  const String content = (*captured_stream)->GetCapturedString();\n\n  delete *captured_stream;\n  *captured_stream = NULL;\n\n  return content;\n}\n\n// Starts capturing stdout.\nvoid CaptureStdout() {\n  CaptureStream(kStdOutFileno, \"stdout\", &g_captured_stdout);\n}\n\n// Starts capturing stderr.\nvoid CaptureStderr() {\n  CaptureStream(kStdErrFileno, \"stderr\", &g_captured_stderr);\n}\n\n// Stops capturing stdout and returns the captured string.\nString GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }\n\n// Stops capturing stderr and returns the captured string.\nString GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }\n\n#endif  // GTEST_HAS_STREAM_REDIRECTION\n\n#if GTEST_HAS_DEATH_TEST\n\n// A copy of all command line arguments.  Set by InitGoogleTest().\n::std::vector<String> g_argvs;\n\n// Returns the command line as a vector of strings.\nconst ::std::vector<String>& GetArgvs() { return g_argvs; }\n\n#endif  // GTEST_HAS_DEATH_TEST\n\n#if GTEST_OS_WINDOWS_MOBILE\nnamespace posix {\nvoid Abort() {\n  DebugBreak();\n  TerminateProcess(GetCurrentProcess(), 1);\n}\n}  // namespace posix\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Returns the name of the environment variable corresponding to the\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\n// \"GTEST_FOO\" in the open-source version.\nstatic String FlagToEnvVar(const char* flag) {\n  const String full_flag =\n      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();\n\n  Message env_var;\n  for (size_t i = 0; i != full_flag.length(); i++) {\n    env_var << ToUpper(full_flag.c_str()[i]);\n  }\n\n  return env_var.GetString();\n}\n\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\n// the result to *value and returns true; otherwise leaves *value\n// unchanged and returns false.\nbool ParseInt32(const Message& src_text, const char* str, Int32* value) {\n  // Parses the environment variable as a decimal integer.\n  char* end = NULL;\n  const long long_value = strtol(str, &end, 10);  // NOLINT\n\n  // Has strtol() consumed all characters in the string?\n  if (*end != '\\0') {\n    // No - an invalid character was encountered.\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\"\n        << \" has value \\\"\" << str << \"\\\".\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  // Is the parsed value in the range of an Int32?\n  const Int32 result = static_cast<Int32>(long_value);\n  if (long_value == LONG_MAX || long_value == LONG_MIN ||\n      // The parsed value overflows as a long.  (strtol() returns\n      // LONG_MAX or LONG_MIN when the input overflows.)\n      result != long_value\n      // The parsed value overflows as an Int32.\n      ) {\n    Message msg;\n    msg << \"WARNING: \" << src_text\n        << \" is expected to be a 32-bit integer, but actually\"\n        << \" has value \" << str << \", which overflows.\\n\";\n    printf(\"%s\", msg.GetString().c_str());\n    fflush(stdout);\n    return false;\n  }\n\n  *value = result;\n  return true;\n}\n\n// Reads and returns the Boolean environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\n//\n// The value is considered true iff it's not \"0\".\nbool BoolFromGTestEnv(const char* flag, bool default_value) {\n  const String env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  return string_value == NULL ?\n      default_value : strcmp(string_value, \"0\") != 0;\n}\n\n// Reads and returns a 32-bit integer stored in the environment\n// variable corresponding to the given flag; if it isn't set or\n// doesn't represent a valid 32-bit integer, returns default_value.\nInt32 Int32FromGTestEnv(const char* flag, Int32 default_value) {\n  const String env_var = FlagToEnvVar(flag);\n  const char* const string_value = posix::GetEnv(env_var.c_str());\n  if (string_value == NULL) {\n    // The environment variable is not set.\n    return default_value;\n  }\n\n  Int32 result = default_value;\n  if (!ParseInt32(Message() << \"Environment variable \" << env_var,\n                  string_value, &result)) {\n    printf(\"The default value %s is used.\\n\",\n           (Message() << default_value).GetString().c_str());\n    fflush(stdout);\n    return default_value;\n  }\n\n  return result;\n}\n\n// Reads and returns the string environment variable corresponding to\n// the given flag; if it's not set, returns default_value.\nconst char* StringFromGTestEnv(const char* flag, const char* default_value) {\n  const String env_var = FlagToEnvVar(flag);\n  const char* const value = posix::GetEnv(env_var.c_str());\n  return value == NULL ? default_value : value;\n}\n\n}  // namespace internal\n}  // namespace testing\n// Copyright 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n// Google Test - The Google C++ Testing Framework\n//\n// This file implements a universal value printer that can print a\n// value of any type T:\n//\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\n//\n// It uses the << operator when possible, and prints the bytes in the\n// object otherwise.  A user can override its behavior for a class\n// type Foo by defining either operator<<(::std::ostream&, const Foo&)\n// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that\n// defines Foo.\n\n#include <ctype.h>\n#include <stdio.h>\n#include <ostream>  // NOLINT\n#include <string>\n\nnamespace testing {\n\nnamespace {\n\nusing ::std::ostream;\n\n#if GTEST_OS_WINDOWS_MOBILE  // Windows CE does not define _snprintf_s.\n# define snprintf _snprintf\n#elif _MSC_VER >= 1400  // VC 8.0 and later deprecate snprintf and _snprintf.\n# define snprintf _snprintf_s\n#elif _MSC_VER\n# define snprintf _snprintf\n#endif  // GTEST_OS_WINDOWS_MOBILE\n\n// Prints a segment of bytes in the given object.\nvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,\n                                size_t count, ostream* os) {\n  char text[5] = \"\";\n  for (size_t i = 0; i != count; i++) {\n    const size_t j = start + i;\n    if (i != 0) {\n      // Organizes the bytes into groups of 2 for easy parsing by\n      // human.\n      if ((j % 2) == 0)\n        *os << ' ';\n      else\n        *os << '-';\n    }\n    snprintf(text, sizeof(text), \"%02X\", obj_bytes[j]);\n    *os << text;\n  }\n}\n\n// Prints the bytes in the given value to the given ostream.\nvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,\n                              ostream* os) {\n  // Tells the user how big the object is.\n  *os << count << \"-byte object <\";\n\n  const size_t kThreshold = 132;\n  const size_t kChunkSize = 64;\n  // If the object size is bigger than kThreshold, we'll have to omit\n  // some details by printing only the first and the last kChunkSize\n  // bytes.\n  // TODO(wan): let the user control the threshold using a flag.\n  if (count < kThreshold) {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);\n  } else {\n    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);\n    *os << \" ... \";\n    // Rounds up to 2-byte boundary.\n    const size_t resume_pos = (count - kChunkSize + 1)/2*2;\n    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);\n  }\n  *os << \">\";\n}\n\n}  // namespace\n\nnamespace internal2 {\n\n// Delegates to PrintBytesInObjectToImpl() to print the bytes in the\n// given object.  The delegation simplifies the implementation, which\n// uses the << operator and thus is easier done outside of the\n// ::testing::internal namespace, which contains a << operator that\n// sometimes conflicts with the one in STL.\nvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,\n                          ostream* os) {\n  PrintBytesInObjectToImpl(obj_bytes, count, os);\n}\n\n}  // namespace internal2\n\nnamespace internal {\n\n// Depending on the value of a char (or wchar_t), we print it in one\n// of three formats:\n//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),\n//   - as a hexidecimal escape sequence (e.g. '\\x7F'), or\n//   - as a special escape sequence (e.g. '\\r', '\\n').\nenum CharFormat {\n  kAsIs,\n  kHexEscape,\n  kSpecialEscape\n};\n\n// Returns true if c is a printable ASCII character.  We test the\n// value of c directly instead of calling isprint(), which is buggy on\n// Windows Mobile.\ninline bool IsPrintableAscii(wchar_t c) {\n  return 0x20 <= c && c <= 0x7E;\n}\n\n// Prints a wide or narrow char c as a character literal without the\n// quotes, escaping it when necessary; returns how c was formatted.\n// The template argument UnsignedChar is the unsigned version of Char,\n// which is the type of c.\ntemplate <typename UnsignedChar, typename Char>\nstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {\n  switch (static_cast<wchar_t>(c)) {\n    case L'\\0':\n      *os << \"\\\\0\";\n      break;\n    case L'\\'':\n      *os << \"\\\\'\";\n      break;\n    case L'\\\\':\n      *os << \"\\\\\\\\\";\n      break;\n    case L'\\a':\n      *os << \"\\\\a\";\n      break;\n    case L'\\b':\n      *os << \"\\\\b\";\n      break;\n    case L'\\f':\n      *os << \"\\\\f\";\n      break;\n    case L'\\n':\n      *os << \"\\\\n\";\n      break;\n    case L'\\r':\n      *os << \"\\\\r\";\n      break;\n    case L'\\t':\n      *os << \"\\\\t\";\n      break;\n    case L'\\v':\n      *os << \"\\\\v\";\n      break;\n    default:\n      if (IsPrintableAscii(c)) {\n        *os << static_cast<char>(c);\n        return kAsIs;\n      } else {\n        *os << String::Format(\"\\\\x%X\", static_cast<UnsignedChar>(c));\n        return kHexEscape;\n      }\n  }\n  return kSpecialEscape;\n}\n\n// Prints a char c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) {\n  switch (c) {\n    case L'\\'':\n      *os << \"'\";\n      return kAsIs;\n    case L'\"':\n      *os << \"\\\\\\\"\";\n      return kSpecialEscape;\n    default:\n      return PrintAsCharLiteralTo<wchar_t>(c, os);\n  }\n}\n\n// Prints a char c as if it's part of a string literal, escaping it when\n// necessary; returns how c was formatted.\nstatic CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) {\n  return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os);\n}\n\n// Prints a wide or narrow character c and its code.  '\\0' is printed\n// as \"'\\\\0'\", other unprintable characters are also properly escaped\n// using the standard C++ escape sequence.  The template argument\n// UnsignedChar is the unsigned version of Char, which is the type of c.\ntemplate <typename UnsignedChar, typename Char>\nvoid PrintCharAndCodeTo(Char c, ostream* os) {\n  // First, print c as a literal in the most readable form we can find.\n  *os << ((sizeof(c) > 1) ? \"L'\" : \"'\");\n  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);\n  *os << \"'\";\n\n  // To aid user debugging, we also print c's code in decimal, unless\n  // it's 0 (in which case c was printed as '\\\\0', making the code\n  // obvious).\n  if (c == 0)\n    return;\n  *os << \" (\" << String::Format(\"%d\", c).c_str();\n\n  // For more convenience, we print c's code again in hexidecimal,\n  // unless c was already printed in the form '\\x##' or the code is in\n  // [1, 9].\n  if (format == kHexEscape || (1 <= c && c <= 9)) {\n    // Do nothing.\n  } else {\n    *os << String::Format(\", 0x%X\",\n                          static_cast<UnsignedChar>(c)).c_str();\n  }\n  *os << \")\";\n}\n\nvoid PrintTo(unsigned char c, ::std::ostream* os) {\n  PrintCharAndCodeTo<unsigned char>(c, os);\n}\nvoid PrintTo(signed char c, ::std::ostream* os) {\n  PrintCharAndCodeTo<unsigned char>(c, os);\n}\n\n// Prints a wchar_t as a symbol if it is printable or as its internal\n// code otherwise and also as its code.  L'\\0' is printed as \"L'\\\\0'\".\nvoid PrintTo(wchar_t wc, ostream* os) {\n  PrintCharAndCodeTo<wchar_t>(wc, os);\n}\n\n// Prints the given array of characters to the ostream.\n// The array starts at *begin, the length is len, it may include '\\0' characters\n// and may not be null-terminated.\nstatic void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) {\n  *os << \"\\\"\";\n  bool is_previous_hex = false;\n  for (size_t index = 0; index < len; ++index) {\n    const char cur = begin[index];\n    if (is_previous_hex && IsXDigit(cur)) {\n      // Previous character is of '\\x..' form and this character can be\n      // interpreted as another hexadecimal digit in its number. Break string to\n      // disambiguate.\n      *os << \"\\\" \\\"\";\n    }\n    is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape;\n  }\n  *os << \"\\\"\";\n}\n\n// Prints a (const) char array of 'len' elements, starting at address 'begin'.\nvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) {\n  PrintCharsAsStringTo(begin, len, os);\n}\n\n// Prints the given array of wide characters to the ostream.\n// The array starts at *begin, the length is len, it may include L'\\0'\n// characters and may not be null-terminated.\nstatic void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len,\n                                     ostream* os) {\n  *os << \"L\\\"\";\n  bool is_previous_hex = false;\n  for (size_t index = 0; index < len; ++index) {\n    const wchar_t cur = begin[index];\n    if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) {\n      // Previous character is of '\\x..' form and this character can be\n      // interpreted as another hexadecimal digit in its number. Break string to\n      // disambiguate.\n      *os << \"\\\" L\\\"\";\n    }\n    is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape;\n  }\n  *os << \"\\\"\";\n}\n\n// Prints the given C string to the ostream.\nvoid PrintTo(const char* s, ostream* os) {\n  if (s == NULL) {\n    *os << \"NULL\";\n  } else {\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\n    PrintCharsAsStringTo(s, strlen(s), os);\n  }\n}\n\n// MSVC compiler can be configured to define whar_t as a typedef\n// of unsigned short. Defining an overload for const wchar_t* in that case\n// would cause pointers to unsigned shorts be printed as wide strings,\n// possibly accessing more memory than intended and causing invalid\n// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when\n// wchar_t is implemented as a native type.\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\n// Prints the given wide C string to the ostream.\nvoid PrintTo(const wchar_t* s, ostream* os) {\n  if (s == NULL) {\n    *os << \"NULL\";\n  } else {\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\n    PrintWideCharsAsStringTo(s, wcslen(s), os);\n  }\n}\n#endif  // wchar_t is native\n\n// Prints a ::string object.\n#if GTEST_HAS_GLOBAL_STRING\nvoid PrintStringTo(const ::string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif  // GTEST_HAS_GLOBAL_STRING\n\nvoid PrintStringTo(const ::std::string& s, ostream* os) {\n  PrintCharsAsStringTo(s.data(), s.size(), os);\n}\n\n// Prints a ::wstring object.\n#if GTEST_HAS_GLOBAL_WSTRING\nvoid PrintWideStringTo(const ::wstring& s, ostream* os) {\n  PrintWideCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif  // GTEST_HAS_GLOBAL_WSTRING\n\n#if GTEST_HAS_STD_WSTRING\nvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) {\n  PrintWideCharsAsStringTo(s.data(), s.size(), os);\n}\n#endif  // GTEST_HAS_STD_WSTRING\n\n}  // namespace internal\n\n}  // namespace testing\n// Copyright 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: mheule@google.com (Markus Heule)\n//\n// The Google C++ Testing Framework (Google Test)\n\n\n// Indicates that this translation unit is part of Google Test's\n// implementation.  It must come before gtest-internal-inl.h is\n// included, or there will be a compiler error.  This trick is to\n// prevent a user from accidentally including gtest-internal-inl.h in\n// his code.\n#define GTEST_IMPLEMENTATION_ 1\n#undef GTEST_IMPLEMENTATION_\n\nnamespace testing {\n\nusing internal::GetUnitTestImpl;\n\n// Gets the summary of the failure message by omitting the stack trace\n// in it.\ninternal::String TestPartResult::ExtractSummary(const char* message) {\n  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);\n  return stack_trace == NULL ? internal::String(message) :\n      internal::String(message, stack_trace - message);\n}\n\n// Prints a TestPartResult object.\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result) {\n  return os\n      << result.file_name() << \":\" << result.line_number() << \": \"\n      << (result.type() == TestPartResult::kSuccess ? \"Success\" :\n          result.type() == TestPartResult::kFatalFailure ? \"Fatal failure\" :\n          \"Non-fatal failure\") << \":\\n\"\n      << result.message() << std::endl;\n}\n\n// Appends a TestPartResult to the array.\nvoid TestPartResultArray::Append(const TestPartResult& result) {\n  array_.push_back(result);\n}\n\n// Returns the TestPartResult at the given index (0-based).\nconst TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {\n  if (index < 0 || index >= size()) {\n    printf(\"\\nInvalid index (%d) into TestPartResultArray.\\n\", index);\n    internal::posix::Abort();\n  }\n\n  return array_[index];\n}\n\n// Returns the number of TestPartResult objects in the array.\nint TestPartResultArray::size() const {\n  return static_cast<int>(array_.size());\n}\n\nnamespace internal {\n\nHasNewFatalFailureHelper::HasNewFatalFailureHelper()\n    : has_new_fatal_failure_(false),\n      original_reporter_(GetUnitTestImpl()->\n                         GetTestPartResultReporterForCurrentThread()) {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);\n}\n\nHasNewFatalFailureHelper::~HasNewFatalFailureHelper() {\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(\n      original_reporter_);\n}\n\nvoid HasNewFatalFailureHelper::ReportTestPartResult(\n    const TestPartResult& result) {\n  if (result.fatally_failed())\n    has_new_fatal_failure_ = true;\n  original_reporter_->ReportTestPartResult(result);\n}\n\n}  // namespace internal\n\n}  // namespace testing\n// Copyright 2008 Google Inc.\n// All Rights Reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Author: wan@google.com (Zhanyong Wan)\n\n\nnamespace testing {\nnamespace internal {\n\n#if GTEST_HAS_TYPED_TEST_P\n\n// Skips to the first non-space char in str. Returns an empty string if str\n// contains only whitespace characters.\nstatic const char* SkipSpaces(const char* str) {\n  while (IsSpace(*str))\n    str++;\n  return str;\n}\n\n// Verifies that registered_tests match the test names in\n// defined_test_names_; returns registered_tests if successful, or\n// aborts the program otherwise.\nconst char* TypedTestCasePState::VerifyRegisteredTestNames(\n    const char* file, int line, const char* registered_tests) {\n  typedef ::std::set<const char*>::const_iterator DefinedTestIter;\n  registered_ = true;\n\n  // Skip initial whitespace in registered_tests since some\n  // preprocessors prefix stringizied literals with whitespace.\n  registered_tests = SkipSpaces(registered_tests);\n\n  Message errors;\n  ::std::set<String> tests;\n  for (const char* names = registered_tests; names != NULL;\n       names = SkipComma(names)) {\n    const String name = GetPrefixUntilComma(names);\n    if (tests.count(name) != 0) {\n      errors << \"Test \" << name << \" is listed more than once.\\n\";\n      continue;\n    }\n\n    bool found = false;\n    for (DefinedTestIter it = defined_test_names_.begin();\n         it != defined_test_names_.end();\n         ++it) {\n      if (name == *it) {\n        found = true;\n        break;\n      }\n    }\n\n    if (found) {\n      tests.insert(name);\n    } else {\n      errors << \"No test named \" << name\n             << \" can be found in this test case.\\n\";\n    }\n  }\n\n  for (DefinedTestIter it = defined_test_names_.begin();\n       it != defined_test_names_.end();\n       ++it) {\n    if (tests.count(*it) == 0) {\n      errors << \"You forgot to list test \" << *it << \".\\n\";\n    }\n  }\n\n  const String& errors_str = errors.GetString();\n  if (errors_str != \"\") {\n    fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\n            errors_str.c_str());\n    fflush(stderr);\n    posix::Abort();\n  }\n\n  return registered_tests;\n}\n\n#endif  // GTEST_HAS_TYPED_TEST_P\n\n}  // namespace internal\n}  // namespace testing\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/amdp2ptest.h",
    "content": "/*\n * Copyright 2015-2024 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n#ifndef AMDP2PTEST_H_\n#define AMDP2PTEST_H_\n\n#include <linux/ioctl.h>\n\n#define AMDP2PTEST_IOCTL_MAGIC 'A'\n\n\n#define AMDP2PTEST_DEVICE_NAME \"amdp2ptest\"\n#define AMDP2PTEST_DEVICE_PATH \"/dev/amdp2ptest\"\n\nstruct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n\n\t/* Output parameters */\n\tuint64_t page_size;\n};\n\nstruct AMDRDMA_IOCTL_GET_PAGES_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n\tuint64_t is_local;\t/* 1 if this is the pointer to local\n\t\t\t\t   allocation */\n\n\t/* Output parameters */\n\tuint64_t cpu_ptr;\n};\n\n\nstruct AMDRDMA_IOCTL_PUT_PAGES_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n};\n\n\n#define AMD2P2PTEST_IOCTL_GET_PAGE_SIZE\t\\\n_IOWR(AMDP2PTEST_IOCTL_MAGIC, 1, struct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM *)\n\n#define AMD2P2PTEST_IOCTL_GET_PAGES \\\n_IOWR(AMDP2PTEST_IOCTL_MAGIC, 2, struct AMDRDMA_IOCTL_GET_PAGES_PARAM *)\n\n#define AMD2P2PTEST_IOCTL_PUT_PAGES\t\\\n_IOW(AMDP2PTEST_IOCTL_MAGIC, 3, struct AMDRDMA_IOCTL_PUT_PAGES_PARAM *)\n\n\n#endif  /* AMDP2PTEST_H */\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/asic_reg/gfx_7_2_d.h",
    "content": "/*\n * Copyright (C) 2014  Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef GFX_7_2_D_H\n#define GFX_7_2_D_H\n\n#define mmCB_BLEND_RED                                                          0xa105\n#define mmCB_BLEND_GREEN                                                        0xa106\n#define mmCB_BLEND_BLUE                                                         0xa107\n#define mmCB_BLEND_ALPHA                                                        0xa108\n#define mmCB_COLOR_CONTROL                                                      0xa202\n#define mmCB_BLEND0_CONTROL                                                     0xa1e0\n#define mmCB_BLEND1_CONTROL                                                     0xa1e1\n#define mmCB_BLEND2_CONTROL                                                     0xa1e2\n#define mmCB_BLEND3_CONTROL                                                     0xa1e3\n#define mmCB_BLEND4_CONTROL                                                     0xa1e4\n#define mmCB_BLEND5_CONTROL                                                     0xa1e5\n#define mmCB_BLEND6_CONTROL                                                     0xa1e6\n#define mmCB_BLEND7_CONTROL                                                     0xa1e7\n#define mmCB_COLOR0_BASE                                                        0xa318\n#define mmCB_COLOR1_BASE                                                        0xa327\n#define mmCB_COLOR2_BASE                                                        0xa336\n#define mmCB_COLOR3_BASE                                                        0xa345\n#define mmCB_COLOR4_BASE                                                        0xa354\n#define mmCB_COLOR5_BASE                                                        0xa363\n#define mmCB_COLOR6_BASE                                                        0xa372\n#define mmCB_COLOR7_BASE                                                        0xa381\n#define mmCB_COLOR0_PITCH                                                       0xa319\n#define mmCB_COLOR1_PITCH                                                       0xa328\n#define mmCB_COLOR2_PITCH                                                       0xa337\n#define mmCB_COLOR3_PITCH                                                       0xa346\n#define mmCB_COLOR4_PITCH                                                       0xa355\n#define mmCB_COLOR5_PITCH                                                       0xa364\n#define mmCB_COLOR6_PITCH                                                       0xa373\n#define mmCB_COLOR7_PITCH                                                       0xa382\n#define mmCB_COLOR0_SLICE                                                       0xa31a\n#define mmCB_COLOR1_SLICE                                                       0xa329\n#define mmCB_COLOR2_SLICE                                                       0xa338\n#define mmCB_COLOR3_SLICE                                                       0xa347\n#define mmCB_COLOR4_SLICE                                                       0xa356\n#define mmCB_COLOR5_SLICE                                                       0xa365\n#define mmCB_COLOR6_SLICE                                                       0xa374\n#define mmCB_COLOR7_SLICE                                                       0xa383\n#define mmCB_COLOR0_VIEW                                                        0xa31b\n#define mmCB_COLOR1_VIEW                                                        0xa32a\n#define mmCB_COLOR2_VIEW                                                        0xa339\n#define mmCB_COLOR3_VIEW                                                        0xa348\n#define mmCB_COLOR4_VIEW                                                        0xa357\n#define mmCB_COLOR5_VIEW                                                        0xa366\n#define mmCB_COLOR6_VIEW                                                        0xa375\n#define mmCB_COLOR7_VIEW                                                        0xa384\n#define mmCB_COLOR0_INFO                                                        0xa31c\n#define mmCB_COLOR1_INFO                                                        0xa32b\n#define mmCB_COLOR2_INFO                                                        0xa33a\n#define mmCB_COLOR3_INFO                                                        0xa349\n#define mmCB_COLOR4_INFO                                                        0xa358\n#define mmCB_COLOR5_INFO                                                        0xa367\n#define mmCB_COLOR6_INFO                                                        0xa376\n#define mmCB_COLOR7_INFO                                                        0xa385\n#define mmCB_COLOR0_ATTRIB                                                      0xa31d\n#define mmCB_COLOR1_ATTRIB                                                      0xa32c\n#define mmCB_COLOR2_ATTRIB                                                      0xa33b\n#define mmCB_COLOR3_ATTRIB                                                      0xa34a\n#define mmCB_COLOR4_ATTRIB                                                      0xa359\n#define mmCB_COLOR5_ATTRIB                                                      0xa368\n#define mmCB_COLOR6_ATTRIB                                                      0xa377\n#define mmCB_COLOR7_ATTRIB                                                      0xa386\n#define mmCB_COLOR0_CMASK                                                       0xa31f\n#define mmCB_COLOR1_CMASK                                                       0xa32e\n#define mmCB_COLOR2_CMASK                                                       0xa33d\n#define mmCB_COLOR3_CMASK                                                       0xa34c\n#define mmCB_COLOR4_CMASK                                                       0xa35b\n#define mmCB_COLOR5_CMASK                                                       0xa36a\n#define mmCB_COLOR6_CMASK                                                       0xa379\n#define mmCB_COLOR7_CMASK                                                       0xa388\n#define mmCB_COLOR0_CMASK_SLICE                                                 0xa320\n#define mmCB_COLOR1_CMASK_SLICE                                                 0xa32f\n#define mmCB_COLOR2_CMASK_SLICE                                                 0xa33e\n#define mmCB_COLOR3_CMASK_SLICE                                                 0xa34d\n#define mmCB_COLOR4_CMASK_SLICE                                                 0xa35c\n#define mmCB_COLOR5_CMASK_SLICE                                                 0xa36b\n#define mmCB_COLOR6_CMASK_SLICE                                                 0xa37a\n#define mmCB_COLOR7_CMASK_SLICE                                                 0xa389\n#define mmCB_COLOR0_FMASK                                                       0xa321\n#define mmCB_COLOR1_FMASK                                                       0xa330\n#define mmCB_COLOR2_FMASK                                                       0xa33f\n#define mmCB_COLOR3_FMASK                                                       0xa34e\n#define mmCB_COLOR4_FMASK                                                       0xa35d\n#define mmCB_COLOR5_FMASK                                                       0xa36c\n#define mmCB_COLOR6_FMASK                                                       0xa37b\n#define mmCB_COLOR7_FMASK                                                       0xa38a\n#define mmCB_COLOR0_FMASK_SLICE                                                 0xa322\n#define mmCB_COLOR1_FMASK_SLICE                                                 0xa331\n#define mmCB_COLOR2_FMASK_SLICE                                                 0xa340\n#define mmCB_COLOR3_FMASK_SLICE                                                 0xa34f\n#define mmCB_COLOR4_FMASK_SLICE                                                 0xa35e\n#define mmCB_COLOR5_FMASK_SLICE                                                 0xa36d\n#define mmCB_COLOR6_FMASK_SLICE                                                 0xa37c\n#define mmCB_COLOR7_FMASK_SLICE                                                 0xa38b\n#define mmCB_COLOR0_CLEAR_WORD0                                                 0xa323\n#define mmCB_COLOR1_CLEAR_WORD0                                                 0xa332\n#define mmCB_COLOR2_CLEAR_WORD0                                                 0xa341\n#define mmCB_COLOR3_CLEAR_WORD0                                                 0xa350\n#define mmCB_COLOR4_CLEAR_WORD0                                                 0xa35f\n#define mmCB_COLOR5_CLEAR_WORD0                                                 0xa36e\n#define mmCB_COLOR6_CLEAR_WORD0                                                 0xa37d\n#define mmCB_COLOR7_CLEAR_WORD0                                                 0xa38c\n#define mmCB_COLOR0_CLEAR_WORD1                                                 0xa324\n#define mmCB_COLOR1_CLEAR_WORD1                                                 0xa333\n#define mmCB_COLOR2_CLEAR_WORD1                                                 0xa342\n#define mmCB_COLOR3_CLEAR_WORD1                                                 0xa351\n#define mmCB_COLOR4_CLEAR_WORD1                                                 0xa360\n#define mmCB_COLOR5_CLEAR_WORD1                                                 0xa36f\n#define mmCB_COLOR6_CLEAR_WORD1                                                 0xa37e\n#define mmCB_COLOR7_CLEAR_WORD1                                                 0xa38d\n#define mmCB_TARGET_MASK                                                        0xa08e\n#define mmCB_SHADER_MASK                                                        0xa08f\n#define mmCB_HW_CONTROL                                                         0x2684\n#define mmCB_HW_CONTROL_1                                                       0x2685\n#define mmCB_HW_CONTROL_2                                                       0x2686\n#define mmCB_HW_CONTROL_3                                                       0x2683\n#define mmCB_PERFCOUNTER_FILTER                                                 0xdc00\n#define mmCB_PERFCOUNTER0_SELECT                                                0xdc01\n#define mmCB_PERFCOUNTER0_SELECT1                                               0xdc02\n#define mmCB_PERFCOUNTER1_SELECT                                                0xdc03\n#define mmCB_PERFCOUNTER2_SELECT                                                0xdc04\n#define mmCB_PERFCOUNTER3_SELECT                                                0xdc05\n#define mmCB_PERFCOUNTER0_LO                                                    0xd406\n#define mmCB_PERFCOUNTER1_LO                                                    0xd408\n#define mmCB_PERFCOUNTER2_LO                                                    0xd40a\n#define mmCB_PERFCOUNTER3_LO                                                    0xd40c\n#define mmCB_PERFCOUNTER0_HI                                                    0xd407\n#define mmCB_PERFCOUNTER1_HI                                                    0xd409\n#define mmCB_PERFCOUNTER2_HI                                                    0xd40b\n#define mmCB_PERFCOUNTER3_HI                                                    0xd40d\n#define mmCB_CGTT_SCLK_CTRL                                                     0xf0a8\n#define mmCB_DEBUG_BUS_1                                                        0x2699\n#define mmCB_DEBUG_BUS_2                                                        0x269a\n#define mmCB_DEBUG_BUS_3                                                        0x269b\n#define mmCB_DEBUG_BUS_4                                                        0x269c\n#define mmCB_DEBUG_BUS_5                                                        0x269d\n#define mmCB_DEBUG_BUS_6                                                        0x269e\n#define mmCB_DEBUG_BUS_7                                                        0x269f\n#define mmCB_DEBUG_BUS_8                                                        0x26a0\n#define mmCB_DEBUG_BUS_9                                                        0x26a1\n#define mmCB_DEBUG_BUS_10                                                       0x26a2\n#define mmCB_DEBUG_BUS_11                                                       0x26a3\n#define mmCB_DEBUG_BUS_12                                                       0x26a4\n#define mmCB_DEBUG_BUS_13                                                       0x26a5\n#define mmCB_DEBUG_BUS_14                                                       0x26a6\n#define mmCB_DEBUG_BUS_15                                                       0x26a7\n#define mmCB_DEBUG_BUS_16                                                       0x26a8\n#define mmCB_DEBUG_BUS_17                                                       0x26a9\n#define mmCB_DEBUG_BUS_18                                                       0x26aa\n#define mmCP_DFY_CNTL                                                           0x3020\n#define mmCP_DFY_STAT                                                           0x3021\n#define mmCP_DFY_ADDR_HI                                                        0x3022\n#define mmCP_DFY_ADDR_LO                                                        0x3023\n#define mmCP_DFY_DATA_0                                                         0x3024\n#define mmCP_DFY_DATA_1                                                         0x3025\n#define mmCP_DFY_DATA_2                                                         0x3026\n#define mmCP_DFY_DATA_3                                                         0x3027\n#define mmCP_DFY_DATA_4                                                         0x3028\n#define mmCP_DFY_DATA_5                                                         0x3029\n#define mmCP_DFY_DATA_6                                                         0x302a\n#define mmCP_DFY_DATA_7                                                         0x302b\n#define mmCP_DFY_DATA_8                                                         0x302c\n#define mmCP_DFY_DATA_9                                                         0x302d\n#define mmCP_DFY_DATA_10                                                        0x302e\n#define mmCP_DFY_DATA_11                                                        0x302f\n#define mmCP_DFY_DATA_12                                                        0x3030\n#define mmCP_DFY_DATA_13                                                        0x3031\n#define mmCP_DFY_DATA_14                                                        0x3032\n#define mmCP_DFY_DATA_15                                                        0x3033\n#define mmCP_RB0_BASE                                                           0x3040\n#define mmCP_RB0_BASE_HI                                                        0x30b1\n#define mmCP_RB_BASE                                                            0x3040\n#define mmCP_RB1_BASE                                                           0x3060\n#define mmCP_RB1_BASE_HI                                                        0x30b2\n#define mmCP_RB2_BASE                                                           0x3065\n#define mmCP_RB0_CNTL                                                           0x3041\n#define mmCP_RB_CNTL                                                            0x3041\n#define mmCP_RB1_CNTL                                                           0x3061\n#define mmCP_RB2_CNTL                                                           0x3066\n#define mmCP_RB_RPTR_WR                                                         0x3042\n#define mmCP_RB0_RPTR_ADDR                                                      0x3043\n#define mmCP_RB_RPTR_ADDR                                                       0x3043\n#define mmCP_RB1_RPTR_ADDR                                                      0x3062\n#define mmCP_RB2_RPTR_ADDR                                                      0x3067\n#define mmCP_RB0_RPTR_ADDR_HI                                                   0x3044\n#define mmCP_RB_RPTR_ADDR_HI                                                    0x3044\n#define mmCP_RB1_RPTR_ADDR_HI                                                   0x3063\n#define mmCP_RB2_RPTR_ADDR_HI                                                   0x3068\n#define mmCP_RB0_WPTR                                                           0x3045\n#define mmCP_RB_WPTR                                                            0x3045\n#define mmCP_RB1_WPTR                                                           0x3064\n#define mmCP_RB2_WPTR                                                           0x3069\n#define mmCP_RB_WPTR_POLL_ADDR_LO                                               0x3046\n#define mmCP_RB_WPTR_POLL_ADDR_HI                                               0x3047\n#define mmGC_PRIV_MODE                                                          0x3048\n#define mmCP_INT_CNTL                                                           0x3049\n#define mmCP_INT_CNTL_RING0                                                     0x306a\n#define mmCP_INT_CNTL_RING1                                                     0x306b\n#define mmCP_INT_CNTL_RING2                                                     0x306c\n#define mmCP_INT_STATUS                                                         0x304a\n#define mmCP_INT_STATUS_RING0                                                   0x306d\n#define mmCP_INT_STATUS_RING1                                                   0x306e\n#define mmCP_INT_STATUS_RING2                                                   0x306f\n#define mmCP_DEVICE_ID                                                          0x304b\n#define mmCP_RING_PRIORITY_CNTS                                                 0x304c\n#define mmCP_ME0_PIPE_PRIORITY_CNTS                                             0x304c\n#define mmCP_RING0_PRIORITY                                                     0x304d\n#define mmCP_ME0_PIPE0_PRIORITY                                                 0x304d\n#define mmCP_RING1_PRIORITY                                                     0x304e\n#define mmCP_ME0_PIPE1_PRIORITY                                                 0x304e\n#define mmCP_RING2_PRIORITY                                                     0x304f\n#define mmCP_ME0_PIPE2_PRIORITY                                                 0x304f\n#define mmCP_ENDIAN_SWAP                                                        0x3050\n#define mmCP_RB_VMID                                                            0x3051\n#define mmCP_ME0_PIPE0_VMID                                                     0x3052\n#define mmCP_ME0_PIPE1_VMID                                                     0x3053\n#define mmCP_PFP_UCODE_ADDR                                                     0x3054\n#define mmCP_PFP_UCODE_DATA                                                     0x3055\n#define mmCP_ME_RAM_RADDR                                                       0x3056\n#define mmCP_ME_RAM_WADDR                                                       0x3057\n#define mmCP_ME_RAM_DATA                                                        0x3058\n#define mmCGTT_CPC_CLK_CTRL                                                     0xf0b2\n#define mmCGTT_CPF_CLK_CTRL                                                     0xf0b1\n#define mmCGTT_CP_CLK_CTRL                                                      0xf0b0\n#define mmCP_CE_UCODE_ADDR                                                      0x305a\n#define mmCP_CE_UCODE_DATA                                                      0x305b\n#define mmCP_MEC_ME1_UCODE_ADDR                                                 0x305c\n#define mmCP_MEC_ME1_UCODE_DATA                                                 0x305d\n#define mmCP_MEC_ME2_UCODE_ADDR                                                 0x305e\n#define mmCP_MEC_ME2_UCODE_DATA                                                 0x305f\n#define mmCP_PWR_CNTL                                                           0x3078\n#define mmCP_MEM_SLP_CNTL                                                       0x3079\n#define mmCP_ECC_FIRSTOCCURRENCE                                                0x307a\n#define mmCP_ECC_FIRSTOCCURRENCE_RING0                                          0x307b\n#define mmCP_ECC_FIRSTOCCURRENCE_RING1                                          0x307c\n#define mmCP_ECC_FIRSTOCCURRENCE_RING2                                          0x307d\n#define mmCP_CPF_DEBUG                                                          0x3080\n#define mmCP_FETCHER_SOURCE                                                     0x3082\n#define mmCP_PQ_WPTR_POLL_CNTL                                                  0x3083\n#define mmCP_PQ_WPTR_POLL_CNTL1                                                 0x3084\n#define mmCPC_INT_CNTL                                                          0x30b4\n#define mmCP_ME1_PIPE0_INT_CNTL                                                 0x3085\n#define mmCP_ME1_PIPE1_INT_CNTL                                                 0x3086\n#define mmCP_ME1_PIPE2_INT_CNTL                                                 0x3087\n#define mmCP_ME1_PIPE3_INT_CNTL                                                 0x3088\n#define mmCP_ME2_PIPE0_INT_CNTL                                                 0x3089\n#define mmCP_ME2_PIPE1_INT_CNTL                                                 0x308a\n#define mmCP_ME2_PIPE2_INT_CNTL                                                 0x308b\n#define mmCP_ME2_PIPE3_INT_CNTL                                                 0x308c\n#define mmCPC_INT_STATUS                                                        0x30b5\n#define mmCP_ME1_PIPE0_INT_STATUS                                               0x308d\n#define mmCP_ME1_PIPE1_INT_STATUS                                               0x308e\n#define mmCP_ME1_PIPE2_INT_STATUS                                               0x308f\n#define mmCP_ME1_PIPE3_INT_STATUS                                               0x3090\n#define mmCP_ME2_PIPE0_INT_STATUS                                               0x3091\n#define mmCP_ME2_PIPE1_INT_STATUS                                               0x3092\n#define mmCP_ME2_PIPE2_INT_STATUS                                               0x3093\n#define mmCP_ME2_PIPE3_INT_STATUS                                               0x3094\n#define mmCP_ME1_INT_STAT_DEBUG                                                 0x3095\n#define mmCP_ME2_INT_STAT_DEBUG                                                 0x3096\n#define mmCP_ME1_PIPE_PRIORITY_CNTS                                             0x3099\n#define mmCP_ME1_PIPE0_PRIORITY                                                 0x309a\n#define mmCP_ME1_PIPE1_PRIORITY                                                 0x309b\n#define mmCP_ME1_PIPE2_PRIORITY                                                 0x309c\n#define mmCP_ME1_PIPE3_PRIORITY                                                 0x309d\n#define mmCP_ME2_PIPE_PRIORITY_CNTS                                             0x309e\n#define mmCP_ME2_PIPE0_PRIORITY                                                 0x309f\n#define mmCP_ME2_PIPE1_PRIORITY                                                 0x30a0\n#define mmCP_ME2_PIPE2_PRIORITY                                                 0x30a1\n#define mmCP_ME2_PIPE3_PRIORITY                                                 0x30a2\n#define mmCP_CE_PRGRM_CNTR_START                                                0x30a3\n#define mmCP_PFP_PRGRM_CNTR_START                                               0x30a4\n#define mmCP_ME_PRGRM_CNTR_START                                                0x30a5\n#define mmCP_MEC1_PRGRM_CNTR_START                                              0x30a6\n#define mmCP_MEC2_PRGRM_CNTR_START                                              0x30a7\n#define mmCP_CE_INTR_ROUTINE_START                                              0x30a8\n#define mmCP_PFP_INTR_ROUTINE_START                                             0x30a9\n#define mmCP_ME_INTR_ROUTINE_START                                              0x30aa\n#define mmCP_MEC1_INTR_ROUTINE_START                                            0x30ab\n#define mmCP_MEC2_INTR_ROUTINE_START                                            0x30ac\n#define mmCP_CONTEXT_CNTL                                                       0x30ad\n#define mmCP_MAX_CONTEXT                                                        0x30ae\n#define mmCP_IQ_WAIT_TIME1                                                      0x30af\n#define mmCP_IQ_WAIT_TIME2                                                      0x30b0\n#define mmCP_VMID_RESET                                                         0x30b3\n#define mmCP_VMID_PREEMPT                                                       0x30b6\n#define mmCPC_INT_CNTX_ID                                                       0x30b7\n#define mmCP_PQ_STATUS                                                          0x30b8\n#define mmCP_CPC_STATUS                                                         0x2084\n#define mmCP_CPC_BUSY_STAT                                                      0x2085\n#define mmCP_CPC_STALLED_STAT1                                                  0x2086\n#define mmCP_CPF_STATUS                                                         0x2087\n#define mmCP_CPF_BUSY_STAT                                                      0x2088\n#define mmCP_CPF_STALLED_STAT1                                                  0x2089\n#define mmCP_CPC_MC_CNTL                                                        0x208a\n#define mmCP_CPC_GRBM_FREE_COUNT                                                0x208b\n#define mmCP_MEC_CNTL                                                           0x208d\n#define mmCP_MEC_ME1_HEADER_DUMP                                                0x208e\n#define mmCP_MEC_ME2_HEADER_DUMP                                                0x208f\n#define mmCP_CPC_SCRATCH_INDEX                                                  0x2090\n#define mmCP_CPC_SCRATCH_DATA                                                   0x2091\n#define mmCPG_PERFCOUNTER1_SELECT                                               0xd800\n#define mmCPG_PERFCOUNTER1_LO                                                   0xd000\n#define mmCPG_PERFCOUNTER1_HI                                                   0xd001\n#define mmCPG_PERFCOUNTER0_SELECT1                                              0xd801\n#define mmCPG_PERFCOUNTER0_SELECT                                               0xd802\n#define mmCPG_PERFCOUNTER0_LO                                                   0xd002\n#define mmCPG_PERFCOUNTER0_HI                                                   0xd003\n#define mmCPC_PERFCOUNTER1_SELECT                                               0xd803\n#define mmCPC_PERFCOUNTER1_LO                                                   0xd004\n#define mmCPC_PERFCOUNTER1_HI                                                   0xd005\n#define mmCPC_PERFCOUNTER0_SELECT1                                              0xd804\n#define mmCPC_PERFCOUNTER0_SELECT                                               0xd809\n#define mmCPC_PERFCOUNTER0_LO                                                   0xd006\n#define mmCPC_PERFCOUNTER0_HI                                                   0xd007\n#define mmCPF_PERFCOUNTER1_SELECT                                               0xd805\n#define mmCPF_PERFCOUNTER1_LO                                                   0xd008\n#define mmCPF_PERFCOUNTER1_HI                                                   0xd009\n#define mmCPF_PERFCOUNTER0_SELECT1                                              0xd806\n#define mmCPF_PERFCOUNTER0_SELECT                                               0xd807\n#define mmCPF_PERFCOUNTER0_LO                                                   0xd00a\n#define mmCPF_PERFCOUNTER0_HI                                                   0xd00b\n#define mmCP_CPC_HALT_HYST_COUNT                                                0x20a7\n#define mmCP_DRAW_OBJECT                                                        0xd810\n#define mmCP_DRAW_OBJECT_COUNTER                                                0xd811\n#define mmCP_DRAW_WINDOW_MASK_HI                                                0xd812\n#define mmCP_DRAW_WINDOW_HI                                                     0xd813\n#define mmCP_DRAW_WINDOW_LO                                                     0xd814\n#define mmCP_DRAW_WINDOW_CNTL                                                   0xd815\n#define mmCP_PRT_LOD_STATS_CNTL0                                                0x20ad\n#define mmCP_PRT_LOD_STATS_CNTL1                                                0x20ae\n#define mmCP_PRT_LOD_STATS_CNTL2                                                0x20af\n#define mmCP_CE_COMPARE_COUNT                                                   0x20c0\n#define mmCP_CE_DE_COUNT                                                        0x20c1\n#define mmCP_DE_CE_COUNT                                                        0x20c2\n#define mmCP_DE_LAST_INVAL_COUNT                                                0x20c3\n#define mmCP_DE_DE_COUNT                                                        0x20c4\n#define mmCP_EOP_DONE_EVENT_CNTL                                                0xc0d5\n#define mmCP_EOP_DONE_DATA_CNTL                                                 0xc0d6\n#define mmCP_EOP_DONE_ADDR_LO                                                   0xc000\n#define mmCP_EOP_DONE_ADDR_HI                                                   0xc001\n#define mmCP_EOP_DONE_DATA_LO                                                   0xc002\n#define mmCP_EOP_DONE_DATA_HI                                                   0xc003\n#define mmCP_EOP_LAST_FENCE_LO                                                  0xc004\n#define mmCP_EOP_LAST_FENCE_HI                                                  0xc005\n#define mmCP_STREAM_OUT_ADDR_LO                                                 0xc006\n#define mmCP_STREAM_OUT_ADDR_HI                                                 0xc007\n#define mmCP_NUM_PRIM_WRITTEN_COUNT0_LO                                         0xc008\n#define mmCP_NUM_PRIM_WRITTEN_COUNT0_HI                                         0xc009\n#define mmCP_NUM_PRIM_NEEDED_COUNT0_LO                                          0xc00a\n#define mmCP_NUM_PRIM_NEEDED_COUNT0_HI                                          0xc00b\n#define mmCP_NUM_PRIM_WRITTEN_COUNT1_LO                                         0xc00c\n#define mmCP_NUM_PRIM_WRITTEN_COUNT1_HI                                         0xc00d\n#define mmCP_NUM_PRIM_NEEDED_COUNT1_LO                                          0xc00e\n#define mmCP_NUM_PRIM_NEEDED_COUNT1_HI                                          0xc00f\n#define mmCP_NUM_PRIM_WRITTEN_COUNT2_LO                                         0xc010\n#define mmCP_NUM_PRIM_WRITTEN_COUNT2_HI                                         0xc011\n#define mmCP_NUM_PRIM_NEEDED_COUNT2_LO                                          0xc012\n#define mmCP_NUM_PRIM_NEEDED_COUNT2_HI                                          0xc013\n#define mmCP_NUM_PRIM_WRITTEN_COUNT3_LO                                         0xc014\n#define mmCP_NUM_PRIM_WRITTEN_COUNT3_HI                                         0xc015\n#define mmCP_NUM_PRIM_NEEDED_COUNT3_LO                                          0xc016\n#define mmCP_NUM_PRIM_NEEDED_COUNT3_HI                                          0xc017\n#define mmCP_PIPE_STATS_ADDR_LO                                                 0xc018\n#define mmCP_PIPE_STATS_ADDR_HI                                                 0xc019\n#define mmCP_VGT_IAVERT_COUNT_LO                                                0xc01a\n#define mmCP_VGT_IAVERT_COUNT_HI                                                0xc01b\n#define mmCP_VGT_IAPRIM_COUNT_LO                                                0xc01c\n#define mmCP_VGT_IAPRIM_COUNT_HI                                                0xc01d\n#define mmCP_VGT_GSPRIM_COUNT_LO                                                0xc01e\n#define mmCP_VGT_GSPRIM_COUNT_HI                                                0xc01f\n#define mmCP_VGT_VSINVOC_COUNT_LO                                               0xc020\n#define mmCP_VGT_VSINVOC_COUNT_HI                                               0xc021\n#define mmCP_VGT_GSINVOC_COUNT_LO                                               0xc022\n#define mmCP_VGT_GSINVOC_COUNT_HI                                               0xc023\n#define mmCP_VGT_HSINVOC_COUNT_LO                                               0xc024\n#define mmCP_VGT_HSINVOC_COUNT_HI                                               0xc025\n#define mmCP_VGT_DSINVOC_COUNT_LO                                               0xc026\n#define mmCP_VGT_DSINVOC_COUNT_HI                                               0xc027\n#define mmCP_PA_CINVOC_COUNT_LO                                                 0xc028\n#define mmCP_PA_CINVOC_COUNT_HI                                                 0xc029\n#define mmCP_PA_CPRIM_COUNT_LO                                                  0xc02a\n#define mmCP_PA_CPRIM_COUNT_HI                                                  0xc02b\n#define mmCP_SC_PSINVOC_COUNT0_LO                                               0xc02c\n#define mmCP_SC_PSINVOC_COUNT0_HI                                               0xc02d\n#define mmCP_SC_PSINVOC_COUNT1_LO                                               0xc02e\n#define mmCP_SC_PSINVOC_COUNT1_HI                                               0xc02f\n#define mmCP_VGT_CSINVOC_COUNT_LO                                               0xc030\n#define mmCP_VGT_CSINVOC_COUNT_HI                                               0xc031\n#define mmCP_STRMOUT_CNTL                                                       0xc03f\n#define mmSCRATCH_REG0                                                          0xc040\n#define mmSCRATCH_REG1                                                          0xc041\n#define mmSCRATCH_REG2                                                          0xc042\n#define mmSCRATCH_REG3                                                          0xc043\n#define mmSCRATCH_REG4                                                          0xc044\n#define mmSCRATCH_REG5                                                          0xc045\n#define mmSCRATCH_REG6                                                          0xc046\n#define mmSCRATCH_REG7                                                          0xc047\n#define mmSCRATCH_UMSK                                                          0xc050\n#define mmSCRATCH_ADDR                                                          0xc051\n#define mmCP_PFP_ATOMIC_PREOP_LO                                                0xc052\n#define mmCP_PFP_ATOMIC_PREOP_HI                                                0xc053\n#define mmCP_PFP_GDS_ATOMIC0_PREOP_LO                                           0xc054\n#define mmCP_PFP_GDS_ATOMIC0_PREOP_HI                                           0xc055\n#define mmCP_PFP_GDS_ATOMIC1_PREOP_LO                                           0xc056\n#define mmCP_PFP_GDS_ATOMIC1_PREOP_HI                                           0xc057\n#define mmCP_APPEND_ADDR_LO                                                     0xc058\n#define mmCP_APPEND_ADDR_HI                                                     0xc059\n#define mmCP_APPEND_DATA                                                        0xc05a\n#define mmCP_APPEND_LAST_CS_FENCE                                               0xc05b\n#define mmCP_APPEND_LAST_PS_FENCE                                               0xc05c\n#define mmCP_ATOMIC_PREOP_LO                                                    0xc05d\n#define mmCP_ME_ATOMIC_PREOP_LO                                                 0xc05d\n#define mmCP_ATOMIC_PREOP_HI                                                    0xc05e\n#define mmCP_ME_ATOMIC_PREOP_HI                                                 0xc05e\n#define mmCP_GDS_ATOMIC0_PREOP_LO                                               0xc05f\n#define mmCP_ME_GDS_ATOMIC0_PREOP_LO                                            0xc05f\n#define mmCP_GDS_ATOMIC0_PREOP_HI                                               0xc060\n#define mmCP_ME_GDS_ATOMIC0_PREOP_HI                                            0xc060\n#define mmCP_GDS_ATOMIC1_PREOP_LO                                               0xc061\n#define mmCP_ME_GDS_ATOMIC1_PREOP_LO                                            0xc061\n#define mmCP_GDS_ATOMIC1_PREOP_HI                                               0xc062\n#define mmCP_ME_GDS_ATOMIC1_PREOP_HI                                            0xc062\n#define mmCP_ME_MC_WADDR_LO                                                     0xc069\n#define mmCP_ME_MC_WADDR_HI                                                     0xc06a\n#define mmCP_ME_MC_WDATA_LO                                                     0xc06b\n#define mmCP_ME_MC_WDATA_HI                                                     0xc06c\n#define mmCP_ME_MC_RADDR_LO                                                     0xc06d\n#define mmCP_ME_MC_RADDR_HI                                                     0xc06e\n#define mmCP_SEM_WAIT_TIMER                                                     0xc06f\n#define mmCP_SIG_SEM_ADDR_LO                                                    0xc070\n#define mmCP_SIG_SEM_ADDR_HI                                                    0xc071\n#define mmCP_WAIT_SEM_ADDR_LO                                                   0xc075\n#define mmCP_WAIT_SEM_ADDR_HI                                                   0xc076\n#define mmCP_WAIT_REG_MEM_TIMEOUT                                               0xc074\n#define mmCP_COHER_START_DELAY                                                  0xc07b\n#define mmCP_COHER_CNTL                                                         0xc07c\n#define mmCP_COHER_SIZE                                                         0xc07d\n#define mmCP_COHER_SIZE_HI                                                      0xc08c\n#define mmCP_COHER_BASE                                                         0xc07e\n#define mmCP_COHER_BASE_HI                                                      0xc079\n#define mmCP_COHER_STATUS                                                       0xc07f\n#define mmCOHER_DEST_BASE_0                                                     0xa092\n#define mmCOHER_DEST_BASE_1                                                     0xa093\n#define mmCOHER_DEST_BASE_2                                                     0xa07e\n#define mmCOHER_DEST_BASE_3                                                     0xa07f\n#define mmCOHER_DEST_BASE_HI_0                                                  0xa07a\n#define mmCOHER_DEST_BASE_HI_1                                                  0xa07b\n#define mmCOHER_DEST_BASE_HI_2                                                  0xa07c\n#define mmCOHER_DEST_BASE_HI_3                                                  0xa07d\n#define mmCP_DMA_ME_SRC_ADDR                                                    0xc080\n#define mmCP_DMA_ME_SRC_ADDR_HI                                                 0xc081\n#define mmCP_DMA_ME_DST_ADDR                                                    0xc082\n#define mmCP_DMA_ME_DST_ADDR_HI                                                 0xc083\n#define mmCP_DMA_ME_CONTROL                                                     0xc078\n#define mmCP_DMA_ME_COMMAND                                                     0xc084\n#define mmCP_DMA_PFP_SRC_ADDR                                                   0xc085\n#define mmCP_DMA_PFP_SRC_ADDR_HI                                                0xc086\n#define mmCP_DMA_PFP_DST_ADDR                                                   0xc087\n#define mmCP_DMA_PFP_DST_ADDR_HI                                                0xc088\n#define mmCP_DMA_PFP_CONTROL                                                    0xc077\n#define mmCP_DMA_PFP_COMMAND                                                    0xc089\n#define mmCP_DMA_CNTL                                                           0xc08a\n#define mmCP_DMA_READ_TAGS                                                      0xc08b\n#define mmCP_PFP_IB_CONTROL                                                     0xc08d\n#define mmCP_PFP_LOAD_CONTROL                                                   0xc08e\n#define mmCP_SCRATCH_INDEX                                                      0xc08f\n#define mmCP_SCRATCH_DATA                                                       0xc090\n#define mmCP_RB_OFFSET                                                          0xc091\n#define mmCP_IB1_OFFSET                                                         0xc092\n#define mmCP_IB2_OFFSET                                                         0xc093\n#define mmCP_IB1_PREAMBLE_BEGIN                                                 0xc094\n#define mmCP_IB1_PREAMBLE_END                                                   0xc095\n#define mmCP_IB2_PREAMBLE_BEGIN                                                 0xc096\n#define mmCP_IB2_PREAMBLE_END                                                   0xc097\n#define mmCP_CE_IB1_OFFSET                                                      0xc098\n#define mmCP_CE_IB2_OFFSET                                                      0xc099\n#define mmCP_CE_COUNTER                                                         0xc09a\n#define mmCP_STALLED_STAT1                                                      0x219d\n#define mmCP_STALLED_STAT2                                                      0x219e\n#define mmCP_STALLED_STAT3                                                      0x219c\n#define mmCP_BUSY_STAT                                                          0x219f\n#define mmCP_STAT                                                               0x21a0\n#define mmCP_ME_HEADER_DUMP                                                     0x21a1\n#define mmCP_PFP_HEADER_DUMP                                                    0x21a2\n#define mmCP_GRBM_FREE_COUNT                                                    0x21a3\n#define mmCP_CE_HEADER_DUMP                                                     0x21a4\n#define mmCP_MC_PACK_DELAY_CNT                                                  0x21a7\n#define mmCP_MC_TAG_CNTL                                                        0x21a8\n#define mmCP_MC_TAG_DATA                                                        0x21a9\n#define mmCP_CSF_STAT                                                           0x21b4\n#define mmCP_CSF_CNTL                                                           0x21b5\n#define mmCP_ME_CNTL                                                            0x21b6\n#define mmCP_CNTX_STAT                                                          0x21b8\n#define mmCP_ME_PREEMPTION                                                      0x21b9\n#define mmCP_RB0_RPTR                                                           0x21c0\n#define mmCP_RB_RPTR                                                            0x21c0\n#define mmCP_RB1_RPTR                                                           0x21bf\n#define mmCP_RB2_RPTR                                                           0x21be\n#define mmCP_RB_WPTR_DELAY                                                      0x21c1\n#define mmCP_RB_WPTR_POLL_CNTL                                                  0x21c2\n#define mmCP_CE_INIT_BASE_LO                                                    0xc0c3\n#define mmCP_CE_INIT_BASE_HI                                                    0xc0c4\n#define mmCP_CE_INIT_BUFSZ                                                      0xc0c5\n#define mmCP_CE_IB1_BASE_LO                                                     0xc0c6\n#define mmCP_CE_IB1_BASE_HI                                                     0xc0c7\n#define mmCP_CE_IB1_BUFSZ                                                       0xc0c8\n#define mmCP_CE_IB2_BASE_LO                                                     0xc0c9\n#define mmCP_CE_IB2_BASE_HI                                                     0xc0ca\n#define mmCP_CE_IB2_BUFSZ                                                       0xc0cb\n#define mmCP_IB1_BASE_LO                                                        0xc0cc\n#define mmCP_IB1_BASE_HI                                                        0xc0cd\n#define mmCP_IB1_BUFSZ                                                          0xc0ce\n#define mmCP_IB2_BASE_LO                                                        0xc0cf\n#define mmCP_IB2_BASE_HI                                                        0xc0d0\n#define mmCP_IB2_BUFSZ                                                          0xc0d1\n#define mmCP_ST_BASE_LO                                                         0xc0d2\n#define mmCP_ST_BASE_HI                                                         0xc0d3\n#define mmCP_ST_BUFSZ                                                           0xc0d4\n#define mmCP_ROQ_THRESHOLDS                                                     0x21bc\n#define mmCP_MEQ_STQ_THRESHOLD                                                  0x21bd\n#define mmCP_ROQ1_THRESHOLDS                                                    0x21d5\n#define mmCP_ROQ2_THRESHOLDS                                                    0x21d6\n#define mmCP_STQ_THRESHOLDS                                                     0x21d7\n#define mmCP_QUEUE_THRESHOLDS                                                   0x21d8\n#define mmCP_MEQ_THRESHOLDS                                                     0x21d9\n#define mmCP_ROQ_AVAIL                                                          0x21da\n#define mmCP_STQ_AVAIL                                                          0x21db\n#define mmCP_ROQ2_AVAIL                                                         0x21dc\n#define mmCP_MEQ_AVAIL                                                          0x21dd\n#define mmCP_CMD_INDEX                                                          0x21de\n#define mmCP_CMD_DATA                                                           0x21df\n#define mmCP_ROQ_RB_STAT                                                        0x21e0\n#define mmCP_ROQ_IB1_STAT                                                       0x21e1\n#define mmCP_ROQ_IB2_STAT                                                       0x21e2\n#define mmCP_STQ_STAT                                                           0x21e3\n#define mmCP_STQ_WR_STAT                                                        0x21e4\n#define mmCP_MEQ_STAT                                                           0x21e5\n#define mmCP_CEQ1_AVAIL                                                         0x21e6\n#define mmCP_CEQ2_AVAIL                                                         0x21e7\n#define mmCP_CE_ROQ_RB_STAT                                                     0x21e8\n#define mmCP_CE_ROQ_IB1_STAT                                                    0x21e9\n#define mmCP_CE_ROQ_IB2_STAT                                                    0x21ea\n#define mmCP_INT_STAT_DEBUG                                                     0x21f7\n#define mmCP_PERFMON_CNTL                                                       0xd808\n#define mmCP_PERFMON_CNTX_CNTL                                                  0xa0d8\n#define mmCP_RINGID                                                             0xa0d9\n#define mmCP_PIPEID                                                             0xa0d9\n#define mmCP_VMID                                                               0xa0da\n#define mmCP_HPD_ROQ_OFFSETS                                                    0x3240\n#define mmCP_HPD_EOP_BASE_ADDR                                                  0x3241\n#define mmCP_HPD_EOP_BASE_ADDR_HI                                               0x3242\n#define mmCP_HPD_EOP_VMID                                                       0x3243\n#define mmCP_HPD_EOP_CONTROL                                                    0x3244\n#define mmCP_MQD_BASE_ADDR                                                      0x3245\n#define mmCP_MQD_BASE_ADDR_HI                                                   0x3246\n#define mmCP_HQD_ACTIVE                                                         0x3247\n#define mmCP_HQD_VMID                                                           0x3248\n#define mmCP_HQD_PERSISTENT_STATE                                               0x3249\n#define mmCP_HQD_PIPE_PRIORITY                                                  0x324a\n#define mmCP_HQD_QUEUE_PRIORITY                                                 0x324b\n#define mmCP_HQD_QUANTUM                                                        0x324c\n#define mmCP_HQD_PQ_BASE                                                        0x324d\n#define mmCP_HQD_PQ_BASE_HI                                                     0x324e\n#define mmCP_HQD_PQ_RPTR                                                        0x324f\n#define mmCP_HQD_PQ_RPTR_REPORT_ADDR                                            0x3250\n#define mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI                                         0x3251\n#define mmCP_HQD_PQ_WPTR_POLL_ADDR                                              0x3252\n#define mmCP_HQD_PQ_WPTR_POLL_ADDR_HI                                           0x3253\n#define mmCP_HQD_PQ_DOORBELL_CONTROL                                            0x3254\n#define mmCP_HQD_PQ_WPTR                                                        0x3255\n#define mmCP_HQD_PQ_CONTROL                                                     0x3256\n#define mmCP_HQD_IB_BASE_ADDR                                                   0x3257\n#define mmCP_HQD_IB_BASE_ADDR_HI                                                0x3258\n#define mmCP_HQD_IB_RPTR                                                        0x3259\n#define mmCP_HQD_IB_CONTROL                                                     0x325a\n#define mmCP_HQD_IQ_TIMER                                                       0x325b\n#define mmCP_HQD_IQ_RPTR                                                        0x325c\n#define mmCP_HQD_DEQUEUE_REQUEST                                                0x325d\n#define mmCP_HQD_DMA_OFFLOAD                                                    0x325e\n#define mmCP_HQD_SEMA_CMD                                                       0x325f\n#define mmCP_HQD_MSG_TYPE                                                       0x3260\n#define mmCP_HQD_ATOMIC0_PREOP_LO                                               0x3261\n#define mmCP_HQD_ATOMIC0_PREOP_HI                                               0x3262\n#define mmCP_HQD_ATOMIC1_PREOP_LO                                               0x3263\n#define mmCP_HQD_ATOMIC1_PREOP_HI                                               0x3264\n#define mmCP_HQD_HQ_SCHEDULER0                                                  0x3265\n#define mmCP_HQD_HQ_SCHEDULER1                                                  0x3266\n#define mmCP_MQD_CONTROL                                                        0x3267\n#define mmDB_Z_READ_BASE                                                        0xa012\n#define mmDB_STENCIL_READ_BASE                                                  0xa013\n#define mmDB_Z_WRITE_BASE                                                       0xa014\n#define mmDB_STENCIL_WRITE_BASE                                                 0xa015\n#define mmDB_DEPTH_INFO                                                         0xa00f\n#define mmDB_Z_INFO                                                             0xa010\n#define mmDB_STENCIL_INFO                                                       0xa011\n#define mmDB_DEPTH_SIZE                                                         0xa016\n#define mmDB_DEPTH_SLICE                                                        0xa017\n#define mmDB_DEPTH_VIEW                                                         0xa002\n#define mmDB_RENDER_CONTROL                                                     0xa000\n#define mmDB_COUNT_CONTROL                                                      0xa001\n#define mmDB_RENDER_OVERRIDE                                                    0xa003\n#define mmDB_RENDER_OVERRIDE2                                                   0xa004\n#define mmDB_EQAA                                                               0xa201\n#define mmDB_SHADER_CONTROL                                                     0xa203\n#define mmDB_DEPTH_BOUNDS_MIN                                                   0xa008\n#define mmDB_DEPTH_BOUNDS_MAX                                                   0xa009\n#define mmDB_STENCIL_CLEAR                                                      0xa00a\n#define mmDB_DEPTH_CLEAR                                                        0xa00b\n#define mmDB_HTILE_DATA_BASE                                                    0xa005\n#define mmDB_HTILE_SURFACE                                                      0xa2af\n#define mmDB_PRELOAD_CONTROL                                                    0xa2b2\n#define mmDB_STENCILREFMASK                                                     0xa10c\n#define mmDB_STENCILREFMASK_BF                                                  0xa10d\n#define mmDB_SRESULTS_COMPARE_STATE0                                            0xa2b0\n#define mmDB_SRESULTS_COMPARE_STATE1                                            0xa2b1\n#define mmDB_DEPTH_CONTROL                                                      0xa200\n#define mmDB_STENCIL_CONTROL                                                    0xa10b\n#define mmDB_ALPHA_TO_MASK                                                      0xa2dc\n#define mmDB_PERFCOUNTER0_SELECT                                                0xdc40\n#define mmDB_PERFCOUNTER1_SELECT                                                0xdc42\n#define mmDB_PERFCOUNTER2_SELECT                                                0xdc44\n#define mmDB_PERFCOUNTER3_SELECT                                                0xdc46\n#define mmDB_PERFCOUNTER0_SELECT1                                               0xdc41\n#define mmDB_PERFCOUNTER1_SELECT1                                               0xdc43\n#define mmDB_PERFCOUNTER0_LO                                                    0xd440\n#define mmDB_PERFCOUNTER1_LO                                                    0xd442\n#define mmDB_PERFCOUNTER2_LO                                                    0xd444\n#define mmDB_PERFCOUNTER3_LO                                                    0xd446\n#define mmDB_PERFCOUNTER0_HI                                                    0xd441\n#define mmDB_PERFCOUNTER1_HI                                                    0xd443\n#define mmDB_PERFCOUNTER2_HI                                                    0xd445\n#define mmDB_PERFCOUNTER3_HI                                                    0xd447\n#define mmDB_DEBUG                                                              0x260c\n#define mmDB_DEBUG2                                                             0x260d\n#define mmDB_DEBUG3                                                             0x260e\n#define mmDB_DEBUG4                                                             0x260f\n#define mmDB_CREDIT_LIMIT                                                       0x2614\n#define mmDB_WATERMARKS                                                         0x2615\n#define mmDB_SUBTILE_CONTROL                                                    0x2616\n#define mmDB_FREE_CACHELINES                                                    0x2617\n#define mmDB_FIFO_DEPTH1                                                        0x2618\n#define mmDB_FIFO_DEPTH2                                                        0x2619\n#define mmDB_CGTT_CLK_CTRL_0                                                    0xf0a4\n#define mmDB_ZPASS_COUNT_LOW                                                    0xc3fe\n#define mmDB_ZPASS_COUNT_HI                                                     0xc3ff\n#define mmDB_RING_CONTROL                                                       0x261b\n#define mmDB_READ_DEBUG_0                                                       0x2620\n#define mmDB_READ_DEBUG_1                                                       0x2621\n#define mmDB_READ_DEBUG_2                                                       0x2622\n#define mmDB_READ_DEBUG_3                                                       0x2623\n#define mmDB_READ_DEBUG_4                                                       0x2624\n#define mmDB_READ_DEBUG_5                                                       0x2625\n#define mmDB_READ_DEBUG_6                                                       0x2626\n#define mmDB_READ_DEBUG_7                                                       0x2627\n#define mmDB_READ_DEBUG_8                                                       0x2628\n#define mmDB_READ_DEBUG_9                                                       0x2629\n#define mmDB_READ_DEBUG_A                                                       0x262a\n#define mmDB_READ_DEBUG_B                                                       0x262b\n#define mmDB_READ_DEBUG_C                                                       0x262c\n#define mmDB_READ_DEBUG_D                                                       0x262d\n#define mmDB_READ_DEBUG_E                                                       0x262e\n#define mmDB_READ_DEBUG_F                                                       0x262f\n#define mmDB_OCCLUSION_COUNT0_LOW                                               0xc3c0\n#define mmDB_OCCLUSION_COUNT0_HI                                                0xc3c1\n#define mmDB_OCCLUSION_COUNT1_LOW                                               0xc3c2\n#define mmDB_OCCLUSION_COUNT1_HI                                                0xc3c3\n#define mmDB_OCCLUSION_COUNT2_LOW                                               0xc3c4\n#define mmDB_OCCLUSION_COUNT2_HI                                                0xc3c5\n#define mmDB_OCCLUSION_COUNT3_LOW                                               0xc3c6\n#define mmDB_OCCLUSION_COUNT3_HI                                                0xc3c7\n#define mmCC_RB_REDUNDANCY                                                      0x263c\n#define mmCC_RB_BACKEND_DISABLE                                                 0x263d\n#define mmGC_USER_RB_REDUNDANCY                                                 0x26de\n#define mmGC_USER_RB_BACKEND_DISABLE                                            0x26df\n#define mmGB_ADDR_CONFIG                                                        0x263e\n#define mmGB_BACKEND_MAP                                                        0x263f\n#define mmGB_GPU_ID                                                             0x2640\n#define mmCC_RB_DAISY_CHAIN                                                     0x2641\n#define mmGB_TILE_MODE0                                                         0x2644\n#define mmGB_TILE_MODE1                                                         0x2645\n#define mmGB_TILE_MODE2                                                         0x2646\n#define mmGB_TILE_MODE3                                                         0x2647\n#define mmGB_TILE_MODE4                                                         0x2648\n#define mmGB_TILE_MODE5                                                         0x2649\n#define mmGB_TILE_MODE6                                                         0x264a\n#define mmGB_TILE_MODE7                                                         0x264b\n#define mmGB_TILE_MODE8                                                         0x264c\n#define mmGB_TILE_MODE9                                                         0x264d\n#define mmGB_TILE_MODE10                                                        0x264e\n#define mmGB_TILE_MODE11                                                        0x264f\n#define mmGB_TILE_MODE12                                                        0x2650\n#define mmGB_TILE_MODE13                                                        0x2651\n#define mmGB_TILE_MODE14                                                        0x2652\n#define mmGB_TILE_MODE15                                                        0x2653\n#define mmGB_TILE_MODE16                                                        0x2654\n#define mmGB_TILE_MODE17                                                        0x2655\n#define mmGB_TILE_MODE18                                                        0x2656\n#define mmGB_TILE_MODE19                                                        0x2657\n#define mmGB_TILE_MODE20                                                        0x2658\n#define mmGB_TILE_MODE21                                                        0x2659\n#define mmGB_TILE_MODE22                                                        0x265a\n#define mmGB_TILE_MODE23                                                        0x265b\n#define mmGB_TILE_MODE24                                                        0x265c\n#define mmGB_TILE_MODE25                                                        0x265d\n#define mmGB_TILE_MODE26                                                        0x265e\n#define mmGB_TILE_MODE27                                                        0x265f\n#define mmGB_TILE_MODE28                                                        0x2660\n#define mmGB_TILE_MODE29                                                        0x2661\n#define mmGB_TILE_MODE30                                                        0x2662\n#define mmGB_TILE_MODE31                                                        0x2663\n#define mmGB_MACROTILE_MODE0                                                    0x2664\n#define mmGB_MACROTILE_MODE1                                                    0x2665\n#define mmGB_MACROTILE_MODE2                                                    0x2666\n#define mmGB_MACROTILE_MODE3                                                    0x2667\n#define mmGB_MACROTILE_MODE4                                                    0x2668\n#define mmGB_MACROTILE_MODE5                                                    0x2669\n#define mmGB_MACROTILE_MODE6                                                    0x266a\n#define mmGB_MACROTILE_MODE7                                                    0x266b\n#define mmGB_MACROTILE_MODE8                                                    0x266c\n#define mmGB_MACROTILE_MODE9                                                    0x266d\n#define mmGB_MACROTILE_MODE10                                                   0x266e\n#define mmGB_MACROTILE_MODE11                                                   0x266f\n#define mmGB_MACROTILE_MODE12                                                   0x2670\n#define mmGB_MACROTILE_MODE13                                                   0x2671\n#define mmGB_MACROTILE_MODE14                                                   0x2672\n#define mmGB_MACROTILE_MODE15                                                   0x2673\n#define mmGB_EDC_MODE                                                           0x307e\n#define mmCC_GC_EDC_CONFIG                                                      0x3098\n#define mmRAS_SIGNATURE_CONTROL                                                 0x3380\n#define mmRAS_SIGNATURE_MASK                                                    0x3381\n#define mmRAS_SX_SIGNATURE0                                                     0x3382\n#define mmRAS_SX_SIGNATURE1                                                     0x3383\n#define mmRAS_SX_SIGNATURE2                                                     0x3384\n#define mmRAS_SX_SIGNATURE3                                                     0x3385\n#define mmRAS_DB_SIGNATURE0                                                     0x338b\n#define mmRAS_PA_SIGNATURE0                                                     0x338c\n#define mmRAS_VGT_SIGNATURE0                                                    0x338d\n#define mmRAS_SQ_SIGNATURE0                                                     0x338e\n#define mmRAS_SC_SIGNATURE0                                                     0x338f\n#define mmRAS_SC_SIGNATURE1                                                     0x3390\n#define mmRAS_SC_SIGNATURE2                                                     0x3391\n#define mmRAS_SC_SIGNATURE3                                                     0x3392\n#define mmRAS_SC_SIGNATURE4                                                     0x3393\n#define mmRAS_SC_SIGNATURE5                                                     0x3394\n#define mmRAS_SC_SIGNATURE6                                                     0x3395\n#define mmRAS_SC_SIGNATURE7                                                     0x3396\n#define mmRAS_IA_SIGNATURE0                                                     0x3397\n#define mmRAS_IA_SIGNATURE1                                                     0x3398\n#define mmRAS_SPI_SIGNATURE0                                                    0x3399\n#define mmRAS_SPI_SIGNATURE1                                                    0x339a\n#define mmRAS_TA_SIGNATURE0                                                     0x339b\n#define mmRAS_TD_SIGNATURE0                                                     0x339c\n#define mmRAS_CB_SIGNATURE0                                                     0x339d\n#define mmRAS_BCI_SIGNATURE0                                                    0x339e\n#define mmRAS_BCI_SIGNATURE1                                                    0x339f\n#define mmGRBM_CAM_INDEX                                                        0x3000\n#define mmGRBM_CAM_DATA                                                         0x3001\n#define mmGRBM_CNTL                                                             0x2000\n#define mmGRBM_SKEW_CNTL                                                        0x2001\n#define mmGRBM_PWR_CNTL                                                         0x2003\n#define mmGRBM_STATUS                                                           0x2004\n#define mmGRBM_STATUS2                                                          0x2002\n#define mmGRBM_STATUS_SE0                                                       0x2005\n#define mmGRBM_STATUS_SE1                                                       0x2006\n#define mmGRBM_STATUS_SE2                                                       0x200e\n#define mmGRBM_STATUS_SE3                                                       0x200f\n#define mmGRBM_SOFT_RESET                                                       0x2008\n#define mmGRBM_DEBUG_CNTL                                                       0x2009\n#define mmGRBM_DEBUG_DATA                                                       0x200a\n#define mmGRBM_GFX_INDEX                                                        0xc200\n#define mmGRBM_GFX_CLKEN_CNTL                                                   0x200c\n#define mmGRBM_WAIT_IDLE_CLOCKS                                                 0x200d\n#define mmGRBM_DEBUG                                                            0x2014\n#define mmGRBM_DEBUG_SNAPSHOT                                                   0x2015\n#define mmGRBM_READ_ERROR                                                       0x2016\n#define mmGRBM_READ_ERROR2                                                      0x2017\n#define mmGRBM_INT_CNTL                                                         0x2018\n#define mmGRBM_PERFCOUNTER0_SELECT                                              0xd840\n#define mmGRBM_PERFCOUNTER1_SELECT                                              0xd841\n#define mmGRBM_SE0_PERFCOUNTER_SELECT                                           0xd842\n#define mmGRBM_SE1_PERFCOUNTER_SELECT                                           0xd843\n#define mmGRBM_SE2_PERFCOUNTER_SELECT                                           0xd844\n#define mmGRBM_SE3_PERFCOUNTER_SELECT                                           0xd845\n#define mmGRBM_PERFCOUNTER0_LO                                                  0xd040\n#define mmGRBM_PERFCOUNTER0_HI                                                  0xd041\n#define mmGRBM_PERFCOUNTER1_LO                                                  0xd043\n#define mmGRBM_PERFCOUNTER1_HI                                                  0xd044\n#define mmGRBM_SE0_PERFCOUNTER_LO                                               0xd045\n#define mmGRBM_SE0_PERFCOUNTER_HI                                               0xd046\n#define mmGRBM_SE1_PERFCOUNTER_LO                                               0xd047\n#define mmGRBM_SE1_PERFCOUNTER_HI                                               0xd048\n#define mmGRBM_SE2_PERFCOUNTER_LO                                               0xd049\n#define mmGRBM_SE2_PERFCOUNTER_HI                                               0xd04a\n#define mmGRBM_SE3_PERFCOUNTER_LO                                               0xd04b\n#define mmGRBM_SE3_PERFCOUNTER_HI                                               0xd04c\n#define mmGRBM_SCRATCH_REG0                                                     0x2040\n#define mmGRBM_SCRATCH_REG1                                                     0x2041\n#define mmGRBM_SCRATCH_REG2                                                     0x2042\n#define mmGRBM_SCRATCH_REG3                                                     0x2043\n#define mmGRBM_SCRATCH_REG4                                                     0x2044\n#define mmGRBM_SCRATCH_REG5                                                     0x2045\n#define mmGRBM_SCRATCH_REG6                                                     0x2046\n#define mmGRBM_SCRATCH_REG7                                                     0x2047\n#define mmDEBUG_INDEX                                                           0x203c\n#define mmDEBUG_DATA                                                            0x203d\n#define mmGRBM_NOWHERE                                                          0x203f\n#define mmPA_CL_VPORT_XSCALE                                                    0xa10f\n#define mmPA_CL_VPORT_XOFFSET                                                   0xa110\n#define mmPA_CL_VPORT_YSCALE                                                    0xa111\n#define mmPA_CL_VPORT_YOFFSET                                                   0xa112\n#define mmPA_CL_VPORT_ZSCALE                                                    0xa113\n#define mmPA_CL_VPORT_ZOFFSET                                                   0xa114\n#define mmPA_CL_VPORT_XSCALE_1                                                  0xa115\n#define mmPA_CL_VPORT_XSCALE_2                                                  0xa11b\n#define mmPA_CL_VPORT_XSCALE_3                                                  0xa121\n#define mmPA_CL_VPORT_XSCALE_4                                                  0xa127\n#define mmPA_CL_VPORT_XSCALE_5                                                  0xa12d\n#define mmPA_CL_VPORT_XSCALE_6                                                  0xa133\n#define mmPA_CL_VPORT_XSCALE_7                                                  0xa139\n#define mmPA_CL_VPORT_XSCALE_8                                                  0xa13f\n#define mmPA_CL_VPORT_XSCALE_9                                                  0xa145\n#define mmPA_CL_VPORT_XSCALE_10                                                 0xa14b\n#define mmPA_CL_VPORT_XSCALE_11                                                 0xa151\n#define mmPA_CL_VPORT_XSCALE_12                                                 0xa157\n#define mmPA_CL_VPORT_XSCALE_13                                                 0xa15d\n#define mmPA_CL_VPORT_XSCALE_14                                                 0xa163\n#define mmPA_CL_VPORT_XSCALE_15                                                 0xa169\n#define mmPA_CL_VPORT_XOFFSET_1                                                 0xa116\n#define mmPA_CL_VPORT_XOFFSET_2                                                 0xa11c\n#define mmPA_CL_VPORT_XOFFSET_3                                                 0xa122\n#define mmPA_CL_VPORT_XOFFSET_4                                                 0xa128\n#define mmPA_CL_VPORT_XOFFSET_5                                                 0xa12e\n#define mmPA_CL_VPORT_XOFFSET_6                                                 0xa134\n#define mmPA_CL_VPORT_XOFFSET_7                                                 0xa13a\n#define mmPA_CL_VPORT_XOFFSET_8                                                 0xa140\n#define mmPA_CL_VPORT_XOFFSET_9                                                 0xa146\n#define mmPA_CL_VPORT_XOFFSET_10                                                0xa14c\n#define mmPA_CL_VPORT_XOFFSET_11                                                0xa152\n#define mmPA_CL_VPORT_XOFFSET_12                                                0xa158\n#define mmPA_CL_VPORT_XOFFSET_13                                                0xa15e\n#define mmPA_CL_VPORT_XOFFSET_14                                                0xa164\n#define mmPA_CL_VPORT_XOFFSET_15                                                0xa16a\n#define mmPA_CL_VPORT_YSCALE_1                                                  0xa117\n#define mmPA_CL_VPORT_YSCALE_2                                                  0xa11d\n#define mmPA_CL_VPORT_YSCALE_3                                                  0xa123\n#define mmPA_CL_VPORT_YSCALE_4                                                  0xa129\n#define mmPA_CL_VPORT_YSCALE_5                                                  0xa12f\n#define mmPA_CL_VPORT_YSCALE_6                                                  0xa135\n#define mmPA_CL_VPORT_YSCALE_7                                                  0xa13b\n#define mmPA_CL_VPORT_YSCALE_8                                                  0xa141\n#define mmPA_CL_VPORT_YSCALE_9                                                  0xa147\n#define mmPA_CL_VPORT_YSCALE_10                                                 0xa14d\n#define mmPA_CL_VPORT_YSCALE_11                                                 0xa153\n#define mmPA_CL_VPORT_YSCALE_12                                                 0xa159\n#define mmPA_CL_VPORT_YSCALE_13                                                 0xa15f\n#define mmPA_CL_VPORT_YSCALE_14                                                 0xa165\n#define mmPA_CL_VPORT_YSCALE_15                                                 0xa16b\n#define mmPA_CL_VPORT_YOFFSET_1                                                 0xa118\n#define mmPA_CL_VPORT_YOFFSET_2                                                 0xa11e\n#define mmPA_CL_VPORT_YOFFSET_3                                                 0xa124\n#define mmPA_CL_VPORT_YOFFSET_4                                                 0xa12a\n#define mmPA_CL_VPORT_YOFFSET_5                                                 0xa130\n#define mmPA_CL_VPORT_YOFFSET_6                                                 0xa136\n#define mmPA_CL_VPORT_YOFFSET_7                                                 0xa13c\n#define mmPA_CL_VPORT_YOFFSET_8                                                 0xa142\n#define mmPA_CL_VPORT_YOFFSET_9                                                 0xa148\n#define mmPA_CL_VPORT_YOFFSET_10                                                0xa14e\n#define mmPA_CL_VPORT_YOFFSET_11                                                0xa154\n#define mmPA_CL_VPORT_YOFFSET_12                                                0xa15a\n#define mmPA_CL_VPORT_YOFFSET_13                                                0xa160\n#define mmPA_CL_VPORT_YOFFSET_14                                                0xa166\n#define mmPA_CL_VPORT_YOFFSET_15                                                0xa16c\n#define mmPA_CL_VPORT_ZSCALE_1                                                  0xa119\n#define mmPA_CL_VPORT_ZSCALE_2                                                  0xa11f\n#define mmPA_CL_VPORT_ZSCALE_3                                                  0xa125\n#define mmPA_CL_VPORT_ZSCALE_4                                                  0xa12b\n#define mmPA_CL_VPORT_ZSCALE_5                                                  0xa131\n#define mmPA_CL_VPORT_ZSCALE_6                                                  0xa137\n#define mmPA_CL_VPORT_ZSCALE_7                                                  0xa13d\n#define mmPA_CL_VPORT_ZSCALE_8                                                  0xa143\n#define mmPA_CL_VPORT_ZSCALE_9                                                  0xa149\n#define mmPA_CL_VPORT_ZSCALE_10                                                 0xa14f\n#define mmPA_CL_VPORT_ZSCALE_11                                                 0xa155\n#define mmPA_CL_VPORT_ZSCALE_12                                                 0xa15b\n#define mmPA_CL_VPORT_ZSCALE_13                                                 0xa161\n#define mmPA_CL_VPORT_ZSCALE_14                                                 0xa167\n#define mmPA_CL_VPORT_ZSCALE_15                                                 0xa16d\n#define mmPA_CL_VPORT_ZOFFSET_1                                                 0xa11a\n#define mmPA_CL_VPORT_ZOFFSET_2                                                 0xa120\n#define mmPA_CL_VPORT_ZOFFSET_3                                                 0xa126\n#define mmPA_CL_VPORT_ZOFFSET_4                                                 0xa12c\n#define mmPA_CL_VPORT_ZOFFSET_5                                                 0xa132\n#define mmPA_CL_VPORT_ZOFFSET_6                                                 0xa138\n#define mmPA_CL_VPORT_ZOFFSET_7                                                 0xa13e\n#define mmPA_CL_VPORT_ZOFFSET_8                                                 0xa144\n#define mmPA_CL_VPORT_ZOFFSET_9                                                 0xa14a\n#define mmPA_CL_VPORT_ZOFFSET_10                                                0xa150\n#define mmPA_CL_VPORT_ZOFFSET_11                                                0xa156\n#define mmPA_CL_VPORT_ZOFFSET_12                                                0xa15c\n#define mmPA_CL_VPORT_ZOFFSET_13                                                0xa162\n#define mmPA_CL_VPORT_ZOFFSET_14                                                0xa168\n#define mmPA_CL_VPORT_ZOFFSET_15                                                0xa16e\n#define mmPA_CL_VTE_CNTL                                                        0xa206\n#define mmPA_CL_VS_OUT_CNTL                                                     0xa207\n#define mmPA_CL_NANINF_CNTL                                                     0xa208\n#define mmPA_CL_CLIP_CNTL                                                       0xa204\n#define mmPA_CL_GB_VERT_CLIP_ADJ                                                0xa2fa\n#define mmPA_CL_GB_VERT_DISC_ADJ                                                0xa2fb\n#define mmPA_CL_GB_HORZ_CLIP_ADJ                                                0xa2fc\n#define mmPA_CL_GB_HORZ_DISC_ADJ                                                0xa2fd\n#define mmPA_CL_UCP_0_X                                                         0xa16f\n#define mmPA_CL_UCP_0_Y                                                         0xa170\n#define mmPA_CL_UCP_0_Z                                                         0xa171\n#define mmPA_CL_UCP_0_W                                                         0xa172\n#define mmPA_CL_UCP_1_X                                                         0xa173\n#define mmPA_CL_UCP_1_Y                                                         0xa174\n#define mmPA_CL_UCP_1_Z                                                         0xa175\n#define mmPA_CL_UCP_1_W                                                         0xa176\n#define mmPA_CL_UCP_2_X                                                         0xa177\n#define mmPA_CL_UCP_2_Y                                                         0xa178\n#define mmPA_CL_UCP_2_Z                                                         0xa179\n#define mmPA_CL_UCP_2_W                                                         0xa17a\n#define mmPA_CL_UCP_3_X                                                         0xa17b\n#define mmPA_CL_UCP_3_Y                                                         0xa17c\n#define mmPA_CL_UCP_3_Z                                                         0xa17d\n#define mmPA_CL_UCP_3_W                                                         0xa17e\n#define mmPA_CL_UCP_4_X                                                         0xa17f\n#define mmPA_CL_UCP_4_Y                                                         0xa180\n#define mmPA_CL_UCP_4_Z                                                         0xa181\n#define mmPA_CL_UCP_4_W                                                         0xa182\n#define mmPA_CL_UCP_5_X                                                         0xa183\n#define mmPA_CL_UCP_5_Y                                                         0xa184\n#define mmPA_CL_UCP_5_Z                                                         0xa185\n#define mmPA_CL_UCP_5_W                                                         0xa186\n#define mmPA_CL_POINT_X_RAD                                                     0xa1f5\n#define mmPA_CL_POINT_Y_RAD                                                     0xa1f6\n#define mmPA_CL_POINT_SIZE                                                      0xa1f7\n#define mmPA_CL_POINT_CULL_RAD                                                  0xa1f8\n#define mmPA_CL_ENHANCE                                                         0x2285\n#define mmPA_CL_RESET_DEBUG                                                     0x2286\n#define mmPA_SU_VTX_CNTL                                                        0xa2f9\n#define mmPA_SU_POINT_SIZE                                                      0xa280\n#define mmPA_SU_POINT_MINMAX                                                    0xa281\n#define mmPA_SU_LINE_CNTL                                                       0xa282\n#define mmPA_SU_LINE_STIPPLE_CNTL                                               0xa209\n#define mmPA_SU_LINE_STIPPLE_SCALE                                              0xa20a\n#define mmPA_SU_PRIM_FILTER_CNTL                                                0xa20b\n#define mmPA_SU_SC_MODE_CNTL                                                    0xa205\n#define mmPA_SU_POLY_OFFSET_DB_FMT_CNTL                                         0xa2de\n#define mmPA_SU_POLY_OFFSET_CLAMP                                               0xa2df\n#define mmPA_SU_POLY_OFFSET_FRONT_SCALE                                         0xa2e0\n#define mmPA_SU_POLY_OFFSET_FRONT_OFFSET                                        0xa2e1\n#define mmPA_SU_POLY_OFFSET_BACK_SCALE                                          0xa2e2\n#define mmPA_SU_POLY_OFFSET_BACK_OFFSET                                         0xa2e3\n#define mmPA_SU_HARDWARE_SCREEN_OFFSET                                          0xa08d\n#define mmPA_SU_LINE_STIPPLE_VALUE                                              0xc280\n#define mmPA_SU_PERFCOUNTER0_SELECT                                             0xd900\n#define mmPA_SU_PERFCOUNTER0_SELECT1                                            0xd901\n#define mmPA_SU_PERFCOUNTER1_SELECT                                             0xd902\n#define mmPA_SU_PERFCOUNTER1_SELECT1                                            0xd903\n#define mmPA_SU_PERFCOUNTER2_SELECT                                             0xd904\n#define mmPA_SU_PERFCOUNTER3_SELECT                                             0xd905\n#define mmPA_SU_PERFCOUNTER0_LO                                                 0xd100\n#define mmPA_SU_PERFCOUNTER0_HI                                                 0xd101\n#define mmPA_SU_PERFCOUNTER1_LO                                                 0xd102\n#define mmPA_SU_PERFCOUNTER1_HI                                                 0xd103\n#define mmPA_SU_PERFCOUNTER2_LO                                                 0xd104\n#define mmPA_SU_PERFCOUNTER2_HI                                                 0xd105\n#define mmPA_SU_PERFCOUNTER3_LO                                                 0xd106\n#define mmPA_SU_PERFCOUNTER3_HI                                                 0xd107\n#define mmPA_SC_AA_CONFIG                                                       0xa2f8\n#define mmPA_SC_AA_MASK_X0Y0_X1Y0                                               0xa30e\n#define mmPA_SC_AA_MASK_X0Y1_X1Y1                                               0xa30f\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0                                     0xa2fe\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1                                     0xa2ff\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2                                     0xa300\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3                                     0xa301\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0                                     0xa302\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1                                     0xa303\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2                                     0xa304\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3                                     0xa305\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0                                     0xa306\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1                                     0xa307\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2                                     0xa308\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3                                     0xa309\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0                                     0xa30a\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1                                     0xa30b\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2                                     0xa30c\n#define mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3                                     0xa30d\n#define mmPA_SC_CENTROID_PRIORITY_0                                             0xa2f5\n#define mmPA_SC_CENTROID_PRIORITY_1                                             0xa2f6\n#define mmPA_SC_CLIPRECT_0_TL                                                   0xa084\n#define mmPA_SC_CLIPRECT_0_BR                                                   0xa085\n#define mmPA_SC_CLIPRECT_1_TL                                                   0xa086\n#define mmPA_SC_CLIPRECT_1_BR                                                   0xa087\n#define mmPA_SC_CLIPRECT_2_TL                                                   0xa088\n#define mmPA_SC_CLIPRECT_2_BR                                                   0xa089\n#define mmPA_SC_CLIPRECT_3_TL                                                   0xa08a\n#define mmPA_SC_CLIPRECT_3_BR                                                   0xa08b\n#define mmPA_SC_CLIPRECT_RULE                                                   0xa083\n#define mmPA_SC_EDGERULE                                                        0xa08c\n#define mmPA_SC_LINE_CNTL                                                       0xa2f7\n#define mmPA_SC_LINE_STIPPLE                                                    0xa283\n#define mmPA_SC_MODE_CNTL_0                                                     0xa292\n#define mmPA_SC_MODE_CNTL_1                                                     0xa293\n#define mmPA_SC_RASTER_CONFIG                                                   0xa0d4\n#define mmPA_SC_RASTER_CONFIG_1                                                 0xa0d5\n#define mmPA_SC_SCREEN_EXTENT_CONTROL                                           0xa0d6\n#define mmPA_SC_GENERIC_SCISSOR_TL                                              0xa090\n#define mmPA_SC_GENERIC_SCISSOR_BR                                              0xa091\n#define mmPA_SC_SCREEN_SCISSOR_TL                                               0xa00c\n#define mmPA_SC_SCREEN_SCISSOR_BR                                               0xa00d\n#define mmPA_SC_WINDOW_OFFSET                                                   0xa080\n#define mmPA_SC_WINDOW_SCISSOR_TL                                               0xa081\n#define mmPA_SC_WINDOW_SCISSOR_BR                                               0xa082\n#define mmPA_SC_VPORT_SCISSOR_0_TL                                              0xa094\n#define mmPA_SC_VPORT_SCISSOR_1_TL                                              0xa096\n#define mmPA_SC_VPORT_SCISSOR_2_TL                                              0xa098\n#define mmPA_SC_VPORT_SCISSOR_3_TL                                              0xa09a\n#define mmPA_SC_VPORT_SCISSOR_4_TL                                              0xa09c\n#define mmPA_SC_VPORT_SCISSOR_5_TL                                              0xa09e\n#define mmPA_SC_VPORT_SCISSOR_6_TL                                              0xa0a0\n#define mmPA_SC_VPORT_SCISSOR_7_TL                                              0xa0a2\n#define mmPA_SC_VPORT_SCISSOR_8_TL                                              0xa0a4\n#define mmPA_SC_VPORT_SCISSOR_9_TL                                              0xa0a6\n#define mmPA_SC_VPORT_SCISSOR_10_TL                                             0xa0a8\n#define mmPA_SC_VPORT_SCISSOR_11_TL                                             0xa0aa\n#define mmPA_SC_VPORT_SCISSOR_12_TL                                             0xa0ac\n#define mmPA_SC_VPORT_SCISSOR_13_TL                                             0xa0ae\n#define mmPA_SC_VPORT_SCISSOR_14_TL                                             0xa0b0\n#define mmPA_SC_VPORT_SCISSOR_15_TL                                             0xa0b2\n#define mmPA_SC_VPORT_SCISSOR_0_BR                                              0xa095\n#define mmPA_SC_VPORT_SCISSOR_1_BR                                              0xa097\n#define mmPA_SC_VPORT_SCISSOR_2_BR                                              0xa099\n#define mmPA_SC_VPORT_SCISSOR_3_BR                                              0xa09b\n#define mmPA_SC_VPORT_SCISSOR_4_BR                                              0xa09d\n#define mmPA_SC_VPORT_SCISSOR_5_BR                                              0xa09f\n#define mmPA_SC_VPORT_SCISSOR_6_BR                                              0xa0a1\n#define mmPA_SC_VPORT_SCISSOR_7_BR                                              0xa0a3\n#define mmPA_SC_VPORT_SCISSOR_8_BR                                              0xa0a5\n#define mmPA_SC_VPORT_SCISSOR_9_BR                                              0xa0a7\n#define mmPA_SC_VPORT_SCISSOR_10_BR                                             0xa0a9\n#define mmPA_SC_VPORT_SCISSOR_11_BR                                             0xa0ab\n#define mmPA_SC_VPORT_SCISSOR_12_BR                                             0xa0ad\n#define mmPA_SC_VPORT_SCISSOR_13_BR                                             0xa0af\n#define mmPA_SC_VPORT_SCISSOR_14_BR                                             0xa0b1\n#define mmPA_SC_VPORT_SCISSOR_15_BR                                             0xa0b3\n#define mmPA_SC_VPORT_ZMIN_0                                                    0xa0b4\n#define mmPA_SC_VPORT_ZMIN_1                                                    0xa0b6\n#define mmPA_SC_VPORT_ZMIN_2                                                    0xa0b8\n#define mmPA_SC_VPORT_ZMIN_3                                                    0xa0ba\n#define mmPA_SC_VPORT_ZMIN_4                                                    0xa0bc\n#define mmPA_SC_VPORT_ZMIN_5                                                    0xa0be\n#define mmPA_SC_VPORT_ZMIN_6                                                    0xa0c0\n#define mmPA_SC_VPORT_ZMIN_7                                                    0xa0c2\n#define mmPA_SC_VPORT_ZMIN_8                                                    0xa0c4\n#define mmPA_SC_VPORT_ZMIN_9                                                    0xa0c6\n#define mmPA_SC_VPORT_ZMIN_10                                                   0xa0c8\n#define mmPA_SC_VPORT_ZMIN_11                                                   0xa0ca\n#define mmPA_SC_VPORT_ZMIN_12                                                   0xa0cc\n#define mmPA_SC_VPORT_ZMIN_13                                                   0xa0ce\n#define mmPA_SC_VPORT_ZMIN_14                                                   0xa0d0\n#define mmPA_SC_VPORT_ZMIN_15                                                   0xa0d2\n#define mmPA_SC_VPORT_ZMAX_0                                                    0xa0b5\n#define mmPA_SC_VPORT_ZMAX_1                                                    0xa0b7\n#define mmPA_SC_VPORT_ZMAX_2                                                    0xa0b9\n#define mmPA_SC_VPORT_ZMAX_3                                                    0xa0bb\n#define mmPA_SC_VPORT_ZMAX_4                                                    0xa0bd\n#define mmPA_SC_VPORT_ZMAX_5                                                    0xa0bf\n#define mmPA_SC_VPORT_ZMAX_6                                                    0xa0c1\n#define mmPA_SC_VPORT_ZMAX_7                                                    0xa0c3\n#define mmPA_SC_VPORT_ZMAX_8                                                    0xa0c5\n#define mmPA_SC_VPORT_ZMAX_9                                                    0xa0c7\n#define mmPA_SC_VPORT_ZMAX_10                                                   0xa0c9\n#define mmPA_SC_VPORT_ZMAX_11                                                   0xa0cb\n#define mmPA_SC_VPORT_ZMAX_12                                                   0xa0cd\n#define mmPA_SC_VPORT_ZMAX_13                                                   0xa0cf\n#define mmPA_SC_VPORT_ZMAX_14                                                   0xa0d1\n#define mmPA_SC_VPORT_ZMAX_15                                                   0xa0d3\n#define mmPA_SC_ENHANCE                                                         0x22fc\n#define mmPA_SC_FIFO_SIZE                                                       0x22f3\n#define mmPA_SC_IF_FIFO_SIZE                                                    0x22f5\n#define mmPA_SC_FORCE_EOV_MAX_CNTS                                              0x22c9\n#define mmPA_SC_LINE_STIPPLE_STATE                                              0xc281\n#define mmPA_SC_SCREEN_EXTENT_MIN_0                                             0xc284\n#define mmPA_SC_SCREEN_EXTENT_MAX_0                                             0xc285\n#define mmPA_SC_SCREEN_EXTENT_MIN_1                                             0xc286\n#define mmPA_SC_SCREEN_EXTENT_MAX_1                                             0xc28b\n#define mmPA_SC_PERFCOUNTER0_SELECT                                             0xd940\n#define mmPA_SC_PERFCOUNTER0_SELECT1                                            0xd941\n#define mmPA_SC_PERFCOUNTER1_SELECT                                             0xd942\n#define mmPA_SC_PERFCOUNTER2_SELECT                                             0xd943\n#define mmPA_SC_PERFCOUNTER3_SELECT                                             0xd944\n#define mmPA_SC_PERFCOUNTER4_SELECT                                             0xd945\n#define mmPA_SC_PERFCOUNTER5_SELECT                                             0xd946\n#define mmPA_SC_PERFCOUNTER6_SELECT                                             0xd947\n#define mmPA_SC_PERFCOUNTER7_SELECT                                             0xd948\n#define mmPA_SC_PERFCOUNTER0_LO                                                 0xd140\n#define mmPA_SC_PERFCOUNTER0_HI                                                 0xd141\n#define mmPA_SC_PERFCOUNTER1_LO                                                 0xd142\n#define mmPA_SC_PERFCOUNTER1_HI                                                 0xd143\n#define mmPA_SC_PERFCOUNTER2_LO                                                 0xd144\n#define mmPA_SC_PERFCOUNTER2_HI                                                 0xd145\n#define mmPA_SC_PERFCOUNTER3_LO                                                 0xd146\n#define mmPA_SC_PERFCOUNTER3_HI                                                 0xd147\n#define mmPA_SC_PERFCOUNTER4_LO                                                 0xd148\n#define mmPA_SC_PERFCOUNTER4_HI                                                 0xd149\n#define mmPA_SC_PERFCOUNTER5_LO                                                 0xd14a\n#define mmPA_SC_PERFCOUNTER5_HI                                                 0xd14b\n#define mmPA_SC_PERFCOUNTER6_LO                                                 0xd14c\n#define mmPA_SC_PERFCOUNTER6_HI                                                 0xd14d\n#define mmPA_SC_PERFCOUNTER7_LO                                                 0xd14e\n#define mmPA_SC_PERFCOUNTER7_HI                                                 0xd14f\n#define mmPA_SC_P3D_TRAP_SCREEN_HV_EN                                           0xc2a0\n#define mmPA_SC_P3D_TRAP_SCREEN_H                                               0xc2a1\n#define mmPA_SC_P3D_TRAP_SCREEN_V                                               0xc2a2\n#define mmPA_SC_P3D_TRAP_SCREEN_OCCURRENCE                                      0xc2a3\n#define mmPA_SC_P3D_TRAP_SCREEN_COUNT                                           0xc2a4\n#define mmPA_SC_HP3D_TRAP_SCREEN_HV_EN                                          0xc2a8\n#define mmPA_SC_HP3D_TRAP_SCREEN_H                                              0xc2a9\n#define mmPA_SC_HP3D_TRAP_SCREEN_V                                              0xc2aa\n#define mmPA_SC_HP3D_TRAP_SCREEN_OCCURRENCE                                     0xc2ab\n#define mmPA_SC_HP3D_TRAP_SCREEN_COUNT                                          0xc2ac\n#define mmPA_SC_TRAP_SCREEN_HV_EN                                               0xc2b0\n#define mmPA_SC_TRAP_SCREEN_H                                                   0xc2b1\n#define mmPA_SC_TRAP_SCREEN_V                                                   0xc2b2\n#define mmPA_SC_TRAP_SCREEN_OCCURRENCE                                          0xc2b3\n#define mmPA_SC_TRAP_SCREEN_COUNT                                               0xc2b4\n#define mmPA_SC_P3D_TRAP_SCREEN_HV_LOCK                                         0x22c0\n#define mmPA_SC_HP3D_TRAP_SCREEN_HV_LOCK                                        0x22c1\n#define mmPA_SC_TRAP_SCREEN_HV_LOCK                                             0x22c2\n#define mmPA_CL_CNTL_STATUS                                                     0x2284\n#define mmPA_SU_CNTL_STATUS                                                     0x2294\n#define mmPA_SC_FIFO_DEPTH_CNTL                                                 0x2295\n#define mmCGTT_PA_CLK_CTRL                                                      0xf088\n#define mmCGTT_SC_CLK_CTRL                                                      0xf089\n#define mmPA_SU_DEBUG_CNTL                                                      0x2280\n#define mmPA_SU_DEBUG_DATA                                                      0x2281\n#define mmPA_SC_DEBUG_CNTL                                                      0x22f6\n#define mmPA_SC_DEBUG_DATA                                                      0x22f7\n#define ixCLIPPER_DEBUG_REG00                                                   0x0\n#define ixCLIPPER_DEBUG_REG01                                                   0x1\n#define ixCLIPPER_DEBUG_REG02                                                   0x2\n#define ixCLIPPER_DEBUG_REG03                                                   0x3\n#define ixCLIPPER_DEBUG_REG04                                                   0x4\n#define ixCLIPPER_DEBUG_REG05                                                   0x5\n#define ixCLIPPER_DEBUG_REG06                                                   0x6\n#define ixCLIPPER_DEBUG_REG07                                                   0x7\n#define ixCLIPPER_DEBUG_REG08                                                   0x8\n#define ixCLIPPER_DEBUG_REG09                                                   0x9\n#define ixCLIPPER_DEBUG_REG10                                                   0xa\n#define ixCLIPPER_DEBUG_REG11                                                   0xb\n#define ixCLIPPER_DEBUG_REG12                                                   0xc\n#define ixCLIPPER_DEBUG_REG13                                                   0xd\n#define ixCLIPPER_DEBUG_REG14                                                   0xe\n#define ixCLIPPER_DEBUG_REG15                                                   0xf\n#define ixCLIPPER_DEBUG_REG16                                                   0x10\n#define ixCLIPPER_DEBUG_REG17                                                   0x11\n#define ixCLIPPER_DEBUG_REG18                                                   0x12\n#define ixCLIPPER_DEBUG_REG19                                                   0x13\n#define ixSXIFCCG_DEBUG_REG0                                                    0x14\n#define ixSXIFCCG_DEBUG_REG1                                                    0x15\n#define ixSXIFCCG_DEBUG_REG2                                                    0x16\n#define ixSXIFCCG_DEBUG_REG3                                                    0x17\n#define ixSETUP_DEBUG_REG0                                                      0x18\n#define ixSETUP_DEBUG_REG1                                                      0x19\n#define ixSETUP_DEBUG_REG2                                                      0x1a\n#define ixSETUP_DEBUG_REG3                                                      0x1b\n#define ixSETUP_DEBUG_REG4                                                      0x1c\n#define ixSETUP_DEBUG_REG5                                                      0x1d\n#define ixPA_SC_DEBUG_REG0                                                      0x0\n#define ixPA_SC_DEBUG_REG1                                                      0x1\n#define mmCOMPUTE_DISPATCH_INITIATOR                                            0x2e00\n#define mmCOMPUTE_DIM_X                                                         0x2e01\n#define mmCOMPUTE_DIM_Y                                                         0x2e02\n#define mmCOMPUTE_DIM_Z                                                         0x2e03\n#define mmCOMPUTE_START_X                                                       0x2e04\n#define mmCOMPUTE_START_Y                                                       0x2e05\n#define mmCOMPUTE_START_Z                                                       0x2e06\n#define mmCOMPUTE_NUM_THREAD_X                                                  0x2e07\n#define mmCOMPUTE_NUM_THREAD_Y                                                  0x2e08\n#define mmCOMPUTE_NUM_THREAD_Z                                                  0x2e09\n#define mmCOMPUTE_PIPELINESTAT_ENABLE                                           0x2e0a\n#define mmCOMPUTE_PERFCOUNT_ENABLE                                              0x2e0b\n#define mmCOMPUTE_PGM_LO                                                        0x2e0c\n#define mmCOMPUTE_PGM_HI                                                        0x2e0d\n#define mmCOMPUTE_TBA_LO                                                        0x2e0e\n#define mmCOMPUTE_TBA_HI                                                        0x2e0f\n#define mmCOMPUTE_TMA_LO                                                        0x2e10\n#define mmCOMPUTE_TMA_HI                                                        0x2e11\n#define mmCOMPUTE_PGM_RSRC1                                                     0x2e12\n#define mmCOMPUTE_PGM_RSRC2                                                     0x2e13\n#define mmCOMPUTE_VMID                                                          0x2e14\n#define mmCOMPUTE_RESOURCE_LIMITS                                               0x2e15\n#define mmCOMPUTE_STATIC_THREAD_MGMT_SE0                                        0x2e16\n#define mmCOMPUTE_STATIC_THREAD_MGMT_SE1                                        0x2e17\n#define mmCOMPUTE_TMPRING_SIZE                                                  0x2e18\n#define mmCOMPUTE_STATIC_THREAD_MGMT_SE2                                        0x2e19\n#define mmCOMPUTE_STATIC_THREAD_MGMT_SE3                                        0x2e1a\n#define mmCOMPUTE_RESTART_X                                                     0x2e1b\n#define mmCOMPUTE_RESTART_Y                                                     0x2e1c\n#define mmCOMPUTE_RESTART_Z                                                     0x2e1d\n#define mmCOMPUTE_THREAD_TRACE_ENABLE                                           0x2e1e\n#define mmCOMPUTE_MISC_RESERVED                                                 0x2e1f\n#define mmCOMPUTE_USER_DATA_0                                                   0x2e40\n#define mmCOMPUTE_USER_DATA_1                                                   0x2e41\n#define mmCOMPUTE_USER_DATA_2                                                   0x2e42\n#define mmCOMPUTE_USER_DATA_3                                                   0x2e43\n#define mmCOMPUTE_USER_DATA_4                                                   0x2e44\n#define mmCOMPUTE_USER_DATA_5                                                   0x2e45\n#define mmCOMPUTE_USER_DATA_6                                                   0x2e46\n#define mmCOMPUTE_USER_DATA_7                                                   0x2e47\n#define mmCOMPUTE_USER_DATA_8                                                   0x2e48\n#define mmCOMPUTE_USER_DATA_9                                                   0x2e49\n#define mmCOMPUTE_USER_DATA_10                                                  0x2e4a\n#define mmCOMPUTE_USER_DATA_11                                                  0x2e4b\n#define mmCOMPUTE_USER_DATA_12                                                  0x2e4c\n#define mmCOMPUTE_USER_DATA_13                                                  0x2e4d\n#define mmCOMPUTE_USER_DATA_14                                                  0x2e4e\n#define mmCOMPUTE_USER_DATA_15                                                  0x2e4f\n#define mmCSPRIV_CONNECT                                                        0x0\n#define mmCSPRIV_THREAD_TRACE_TG0                                               0x1e\n#define mmCSPRIV_THREAD_TRACE_TG1                                               0x1e\n#define mmCSPRIV_THREAD_TRACE_TG2                                               0x1e\n#define mmCSPRIV_THREAD_TRACE_TG3                                               0x1e\n#define mmCSPRIV_THREAD_TRACE_EVENT                                             0x1f\n#define mmRLC_CNTL                                                              0x30c0\n#define mmRLC_DEBUG_SELECT                                                      0x30c1\n#define mmRLC_DEBUG                                                             0x30c2\n#define mmRLC_MC_CNTL                                                           0x30c3\n#define mmRLC_STAT                                                              0x30c4\n#define mmRLC_SAFE_MODE                                                         0x313a\n#define mmRLC_SOFT_RESET_GPU                                                    0x30c5\n#define mmRLC_MEM_SLP_CNTL                                                      0x30c6\n#define mmRLC_PERFMON_CNTL                                                      0xdcc0\n#define mmRLC_PERFCOUNTER0_SELECT                                               0xdcc1\n#define mmRLC_PERFCOUNTER1_SELECT                                               0xdcc2\n#define mmRLC_PERFCOUNTER0_LO                                                   0xd480\n#define mmRLC_PERFCOUNTER1_LO                                                   0xd482\n#define mmRLC_PERFCOUNTER0_HI                                                   0xd481\n#define mmRLC_PERFCOUNTER1_HI                                                   0xd483\n#define mmCGTT_RLC_CLK_CTRL                                                     0xf0b8\n#define mmRLC_LB_CNTL                                                           0x30d9\n#define mmRLC_LB_CNTR_MAX                                                       0x30d2\n#define mmRLC_LB_CNTR_INIT                                                      0x30db\n#define mmRLC_LOAD_BALANCE_CNTR                                                 0x30dc\n#define mmRLC_SAVE_AND_RESTORE_BASE                                             0x30dd\n#define mmRLC_JUMP_TABLE_RESTORE                                                0x30de\n#define mmRLC_DRIVER_CPDMA_STATUS                                               0x30de\n#define mmRLC_PG_DELAY_2                                                        0x30df\n#define mmRLC_GPM_DEBUG_SELECT                                                  0x30e0\n#define mmRLC_GPM_DEBUG                                                         0x30e1\n#define mmRLC_GPM_UCODE_ADDR                                                    0x30e2\n#define mmRLC_GPM_UCODE_DATA                                                    0x30e3\n#define mmRLC_GPU_CLOCK_COUNT_LSB                                               0x30e4\n#define mmRLC_GPU_CLOCK_COUNT_MSB                                               0x30e5\n#define mmRLC_CAPTURE_GPU_CLOCK_COUNT                                           0x30e6\n#define mmRLC_UCODE_CNTL                                                        0x30e7\n#define mmRLC_GPM_STAT                                                          0x3100\n#define mmRLC_GPU_CLOCK_32_RES_SEL                                              0x3101\n#define mmRLC_GPU_CLOCK_32                                                      0x3102\n#define mmRLC_PG_CNTL                                                           0x3103\n#define mmRLC_GPM_THREAD_PRIORITY                                               0x3104\n#define mmRLC_GPM_THREAD_ENABLE                                                 0x3105\n#define mmRLC_GPM_VMID_THREAD0                                                  0x3106\n#define mmRLC_GPM_VMID_THREAD1                                                  0x3107\n#define mmRLC_CGTT_MGCG_OVERRIDE                                                0x3108\n#define mmRLC_CGCG_CGLS_CTRL                                                    0x3109\n#define mmRLC_CGCG_RAMP_CTRL                                                    0x310a\n#define mmRLC_DYN_PG_STATUS                                                     0x310b\n#define mmRLC_DYN_PG_REQUEST                                                    0x310c\n#define mmRLC_PG_DELAY                                                          0x310d\n#define mmRLC_CU_STATUS                                                         0x310e\n#define mmRLC_LB_INIT_CU_MASK                                                   0x310f\n#define mmRLC_LB_ALWAYS_ACTIVE_CU_MASK                                          0x3110\n#define mmRLC_LB_PARAMS                                                         0x3111\n#define mmRLC_THREAD1_DELAY                                                     0x3112\n#define mmRLC_PG_ALWAYS_ON_CU_MASK                                              0x3113\n#define mmRLC_MAX_PG_CU                                                         0x3114\n#define mmRLC_AUTO_PG_CTRL                                                      0x3115\n#define mmRLC_SMU_GRBM_REG_SAVE_CTRL                                            0x3116\n#define mmRLC_SMU_PG_CTRL                                                       0x3117\n#define mmRLC_SMU_PG_WAKE_UP_CTRL                                               0x3118\n#define mmRLC_SERDES_RD_MASTER_INDEX                                            0x3119\n#define mmRLC_SERDES_RD_DATA_0                                                  0x311a\n#define mmRLC_SERDES_RD_DATA_1                                                  0x311b\n#define mmRLC_SERDES_RD_DATA_2                                                  0x311c\n#define mmRLC_SERDES_WR_CU_MASTER_MASK                                          0x311d\n#define mmRLC_SERDES_WR_NONCU_MASTER_MASK                                       0x311e\n#define mmRLC_SERDES_WR_CTRL                                                    0x311f\n#define mmRLC_SERDES_WR_DATA                                                    0x3120\n#define mmRLC_SERDES_CU_MASTER_BUSY                                             0x3121\n#define mmRLC_SERDES_NONCU_MASTER_BUSY                                          0x3122\n#define mmRLC_GPM_GENERAL_0                                                     0x3123\n#define mmRLC_GPM_GENERAL_1                                                     0x3124\n#define mmRLC_GPM_GENERAL_2                                                     0x3125\n#define mmRLC_GPM_GENERAL_3                                                     0x3126\n#define mmRLC_GPM_GENERAL_4                                                     0x3127\n#define mmRLC_GPM_GENERAL_5                                                     0x3128\n#define mmRLC_GPM_GENERAL_6                                                     0x3129\n#define mmRLC_GPM_GENERAL_7                                                     0x312a\n#define mmRLC_GPM_CU_PD_TIMEOUT                                                 0x312b\n#define mmRLC_GPM_SCRATCH_ADDR                                                  0x312c\n#define mmRLC_GPM_SCRATCH_DATA                                                  0x312d\n#define mmRLC_STATIC_PG_STATUS                                                  0x312e\n#define mmRLC_GPM_PERF_COUNT_0                                                  0x312f\n#define mmRLC_GPM_PERF_COUNT_1                                                  0x3130\n#define mmRLC_GPR_REG1                                                          0x3139\n#define mmRLC_GPR_REG2                                                          0x313a\n#define mmRLC_SPM_VMID                                                          0x3131\n#define mmRLC_SPM_INT_CNTL                                                      0x3132\n#define mmRLC_SPM_INT_STATUS                                                    0x3133\n#define mmRLC_SPM_DEBUG_SELECT                                                  0x3134\n#define mmRLC_SPM_DEBUG                                                         0x3135\n#define mmRLC_GPM_LOG_ADDR                                                      0x3136\n#define mmRLC_GPM_LOG_SIZE                                                      0x3137\n#define mmRLC_GPM_LOG_CONT                                                      0x3138\n#define mmRLC_SPM_PERFMON_CNTL                                                  0xdc80\n#define mmRLC_SPM_PERFMON_RING_BASE_LO                                          0xdc81\n#define mmRLC_SPM_PERFMON_RING_BASE_HI                                          0xdc82\n#define mmRLC_SPM_PERFMON_RING_SIZE                                             0xdc83\n#define mmRLC_SPM_PERFMON_SEGMENT_SIZE                                          0xdc84\n#define mmRLC_SPM_SE_MUXSEL_ADDR                                                0xdc85\n#define mmRLC_SPM_SE_MUXSEL_DATA                                                0xdc86\n#define mmRLC_SPM_CPG_PERFMON_SAMPLE_DELAY                                      0xdc87\n#define mmRLC_SPM_CPC_PERFMON_SAMPLE_DELAY                                      0xdc88\n#define mmRLC_SPM_CPF_PERFMON_SAMPLE_DELAY                                      0xdc89\n#define mmRLC_SPM_CB_PERFMON_SAMPLE_DELAY                                       0xdc8a\n#define mmRLC_SPM_DB_PERFMON_SAMPLE_DELAY                                       0xdc8b\n#define mmRLC_SPM_PA_PERFMON_SAMPLE_DELAY                                       0xdc8c\n#define mmRLC_SPM_GDS_PERFMON_SAMPLE_DELAY                                      0xdc8d\n#define mmRLC_SPM_IA_PERFMON_SAMPLE_DELAY                                       0xdc8e\n#define mmRLC_SPM_SC_PERFMON_SAMPLE_DELAY                                       0xdc90\n#define mmRLC_SPM_TCC_PERFMON_SAMPLE_DELAY                                      0xdc91\n#define mmRLC_SPM_TCA_PERFMON_SAMPLE_DELAY                                      0xdc92\n#define mmRLC_SPM_TCP_PERFMON_SAMPLE_DELAY                                      0xdc93\n#define mmRLC_SPM_TA_PERFMON_SAMPLE_DELAY                                       0xdc94\n#define mmRLC_SPM_TD_PERFMON_SAMPLE_DELAY                                       0xdc95\n#define mmRLC_SPM_VGT_PERFMON_SAMPLE_DELAY                                      0xdc96\n#define mmRLC_SPM_SPI_PERFMON_SAMPLE_DELAY                                      0xdc97\n#define mmRLC_SPM_SQG_PERFMON_SAMPLE_DELAY                                      0xdc98\n#define mmRLC_SPM_TCS_PERFMON_SAMPLE_DELAY                                      0xdc99\n#define mmRLC_SPM_SX_PERFMON_SAMPLE_DELAY                                       0xdc9a\n#define mmRLC_SPM_GLOBAL_MUXSEL_ADDR                                            0xdc9b\n#define mmRLC_SPM_GLOBAL_MUXSEL_DATA                                            0xdc9c\n#define mmRLC_SPM_RING_RDPTR                                                    0xdc9d\n#define mmRLC_SPM_SEGMENT_THRESHOLD                                             0xdc9e\n#define mmRLC_SPM_DBR0_PERFMON_SAMPLE_DELAY                                     0xdc9f\n#define mmRLC_SPM_DBR1_PERFMON_SAMPLE_DELAY                                     0xdca0\n#define mmRLC_SPM_CBR0_PERFMON_SAMPLE_DELAY                                     0xdca1\n#define mmRLC_SPM_CBR1_PERFMON_SAMPLE_DELAY                                     0xdca2\n#define mmSPI_PS_INPUT_CNTL_0                                                   0xa191\n#define mmSPI_PS_INPUT_CNTL_1                                                   0xa192\n#define mmSPI_PS_INPUT_CNTL_2                                                   0xa193\n#define mmSPI_PS_INPUT_CNTL_3                                                   0xa194\n#define mmSPI_PS_INPUT_CNTL_4                                                   0xa195\n#define mmSPI_PS_INPUT_CNTL_5                                                   0xa196\n#define mmSPI_PS_INPUT_CNTL_6                                                   0xa197\n#define mmSPI_PS_INPUT_CNTL_7                                                   0xa198\n#define mmSPI_PS_INPUT_CNTL_8                                                   0xa199\n#define mmSPI_PS_INPUT_CNTL_9                                                   0xa19a\n#define mmSPI_PS_INPUT_CNTL_10                                                  0xa19b\n#define mmSPI_PS_INPUT_CNTL_11                                                  0xa19c\n#define mmSPI_PS_INPUT_CNTL_12                                                  0xa19d\n#define mmSPI_PS_INPUT_CNTL_13                                                  0xa19e\n#define mmSPI_PS_INPUT_CNTL_14                                                  0xa19f\n#define mmSPI_PS_INPUT_CNTL_15                                                  0xa1a0\n#define mmSPI_PS_INPUT_CNTL_16                                                  0xa1a1\n#define mmSPI_PS_INPUT_CNTL_17                                                  0xa1a2\n#define mmSPI_PS_INPUT_CNTL_18                                                  0xa1a3\n#define mmSPI_PS_INPUT_CNTL_19                                                  0xa1a4\n#define mmSPI_PS_INPUT_CNTL_20                                                  0xa1a5\n#define mmSPI_PS_INPUT_CNTL_21                                                  0xa1a6\n#define mmSPI_PS_INPUT_CNTL_22                                                  0xa1a7\n#define mmSPI_PS_INPUT_CNTL_23                                                  0xa1a8\n#define mmSPI_PS_INPUT_CNTL_24                                                  0xa1a9\n#define mmSPI_PS_INPUT_CNTL_25                                                  0xa1aa\n#define mmSPI_PS_INPUT_CNTL_26                                                  0xa1ab\n#define mmSPI_PS_INPUT_CNTL_27                                                  0xa1ac\n#define mmSPI_PS_INPUT_CNTL_28                                                  0xa1ad\n#define mmSPI_PS_INPUT_CNTL_29                                                  0xa1ae\n#define mmSPI_PS_INPUT_CNTL_30                                                  0xa1af\n#define mmSPI_PS_INPUT_CNTL_31                                                  0xa1b0\n#define mmSPI_VS_OUT_CONFIG                                                     0xa1b1\n#define mmSPI_PS_INPUT_ENA                                                      0xa1b3\n#define mmSPI_PS_INPUT_ADDR                                                     0xa1b4\n#define mmSPI_INTERP_CONTROL_0                                                  0xa1b5\n#define mmSPI_PS_IN_CONTROL                                                     0xa1b6\n#define mmSPI_BARYC_CNTL                                                        0xa1b8\n#define mmSPI_TMPRING_SIZE                                                      0xa1ba\n#define mmSPI_SHADER_POS_FORMAT                                                 0xa1c3\n#define mmSPI_SHADER_Z_FORMAT                                                   0xa1c4\n#define mmSPI_SHADER_COL_FORMAT                                                 0xa1c5\n#define mmSPI_ARB_PRIORITY                                                      0x31c0\n#define mmSPI_ARB_CYCLES_0                                                      0x31c1\n#define mmSPI_ARB_CYCLES_1                                                      0x31c2\n#define mmSPI_CDBG_SYS_GFX                                                      0x31c3\n#define mmSPI_CDBG_SYS_HP3D                                                     0x31c4\n#define mmSPI_CDBG_SYS_CS0                                                      0x31c5\n#define mmSPI_CDBG_SYS_CS1                                                      0x31c6\n#define mmSPI_WCL_PIPE_PERCENT_GFX                                              0x31c7\n#define mmSPI_WCL_PIPE_PERCENT_HP3D                                             0x31c8\n#define mmSPI_WCL_PIPE_PERCENT_CS0                                              0x31c9\n#define mmSPI_WCL_PIPE_PERCENT_CS1                                              0x31ca\n#define mmSPI_WCL_PIPE_PERCENT_CS2                                              0x31cb\n#define mmSPI_WCL_PIPE_PERCENT_CS3                                              0x31cc\n#define mmSPI_WCL_PIPE_PERCENT_CS4                                              0x31cd\n#define mmSPI_WCL_PIPE_PERCENT_CS5                                              0x31ce\n#define mmSPI_WCL_PIPE_PERCENT_CS6                                              0x31cf\n#define mmSPI_WCL_PIPE_PERCENT_CS7                                              0x31d0\n#define mmSPI_GDBG_WAVE_CNTL                                                    0x31d1\n#define mmSPI_GDBG_TRAP_CONFIG                                                  0x31d2\n#define mmSPI_GDBG_TRAP_MASK                                                    0x31d3\n#define mmSPI_GDBG_TBA_LO                                                       0x31d4\n#define mmSPI_GDBG_TBA_HI                                                       0x31d5\n#define mmSPI_GDBG_TMA_LO                                                       0x31d6\n#define mmSPI_GDBG_TMA_HI                                                       0x31d7\n#define mmSPI_GDBG_TRAP_DATA0                                                   0x31d8\n#define mmSPI_GDBG_TRAP_DATA1                                                   0x31d9\n#define mmSPI_RESET_DEBUG                                                       0x31da\n#define mmSPI_COMPUTE_QUEUE_RESET                                               0x31db\n#define mmSPI_RESOURCE_RESERVE_CU_0                                             0x31dc\n#define mmSPI_RESOURCE_RESERVE_CU_1                                             0x31dd\n#define mmSPI_RESOURCE_RESERVE_CU_2                                             0x31de\n#define mmSPI_RESOURCE_RESERVE_CU_3                                             0x31df\n#define mmSPI_RESOURCE_RESERVE_CU_4                                             0x31e0\n#define mmSPI_RESOURCE_RESERVE_CU_5                                             0x31e1\n#define mmSPI_RESOURCE_RESERVE_CU_6                                             0x31e2\n#define mmSPI_RESOURCE_RESERVE_CU_7                                             0x31e3\n#define mmSPI_RESOURCE_RESERVE_CU_8                                             0x31e4\n#define mmSPI_RESOURCE_RESERVE_CU_9                                             0x31e5\n#define mmSPI_RESOURCE_RESERVE_CU_10                                            0x31f0\n#define mmSPI_RESOURCE_RESERVE_CU_11                                            0x31f1\n#define mmSPI_RESOURCE_RESERVE_EN_CU_0                                          0x31e6\n#define mmSPI_RESOURCE_RESERVE_EN_CU_1                                          0x31e7\n#define mmSPI_RESOURCE_RESERVE_EN_CU_2                                          0x31e8\n#define mmSPI_RESOURCE_RESERVE_EN_CU_3                                          0x31e9\n#define mmSPI_RESOURCE_RESERVE_EN_CU_4                                          0x31ea\n#define mmSPI_RESOURCE_RESERVE_EN_CU_5                                          0x31eb\n#define mmSPI_RESOURCE_RESERVE_EN_CU_6                                          0x31ec\n#define mmSPI_RESOURCE_RESERVE_EN_CU_7                                          0x31ed\n#define mmSPI_RESOURCE_RESERVE_EN_CU_8                                          0x31ee\n#define mmSPI_RESOURCE_RESERVE_EN_CU_9                                          0x31ef\n#define mmSPI_RESOURCE_RESERVE_EN_CU_10                                         0x31f2\n#define mmSPI_RESOURCE_RESERVE_EN_CU_11                                         0x31f3\n#define mmSPI_PS_MAX_WAVE_ID                                                    0x243a\n#define mmSPI_CONFIG_CNTL                                                       0x2440\n#define mmSPI_DEBUG_CNTL                                                        0x2441\n#define mmSPI_DEBUG_READ                                                        0x2442\n#define mmSPI_PERFCOUNTER0_SELECT                                               0xd980\n#define mmSPI_PERFCOUNTER1_SELECT                                               0xd981\n#define mmSPI_PERFCOUNTER2_SELECT                                               0xd982\n#define mmSPI_PERFCOUNTER3_SELECT                                               0xd983\n#define mmSPI_PERFCOUNTER0_SELECT1                                              0xd984\n#define mmSPI_PERFCOUNTER1_SELECT1                                              0xd985\n#define mmSPI_PERFCOUNTER2_SELECT1                                              0xd986\n#define mmSPI_PERFCOUNTER3_SELECT1                                              0xd987\n#define mmSPI_PERFCOUNTER4_SELECT                                               0xd988\n#define mmSPI_PERFCOUNTER5_SELECT                                               0xd989\n#define mmSPI_PERFCOUNTER_BINS                                                  0xd98a\n#define mmSPI_PERFCOUNTER0_HI                                                   0xd180\n#define mmSPI_PERFCOUNTER0_LO                                                   0xd181\n#define mmSPI_PERFCOUNTER1_HI                                                   0xd182\n#define mmSPI_PERFCOUNTER1_LO                                                   0xd183\n#define mmSPI_PERFCOUNTER2_HI                                                   0xd184\n#define mmSPI_PERFCOUNTER2_LO                                                   0xd185\n#define mmSPI_PERFCOUNTER3_HI                                                   0xd186\n#define mmSPI_PERFCOUNTER3_LO                                                   0xd187\n#define mmSPI_PERFCOUNTER4_HI                                                   0xd188\n#define mmSPI_PERFCOUNTER4_LO                                                   0xd189\n#define mmSPI_PERFCOUNTER5_HI                                                   0xd18a\n#define mmSPI_PERFCOUNTER5_LO                                                   0xd18b\n#define mmSPI_CONFIG_CNTL_1                                                     0x244f\n#define mmSPI_DEBUG_BUSY                                                        0x2450\n#define mmCGTS_SM_CTRL_REG                                                      0xf000\n#define mmCGTS_RD_CTRL_REG                                                      0xf001\n#define mmCGTS_RD_REG                                                           0xf002\n#define mmCGTS_TCC_DISABLE                                                      0xf003\n#define mmCGTS_USER_TCC_DISABLE                                                 0xf004\n#define mmCGTS_CU0_SP0_CTRL_REG                                                 0xf008\n#define mmCGTS_CU0_LDS_SQ_CTRL_REG                                              0xf009\n#define mmCGTS_CU0_TA_SQC_CTRL_REG                                              0xf00a\n#define mmCGTS_CU0_SP1_CTRL_REG                                                 0xf00b\n#define mmCGTS_CU0_TD_TCP_CTRL_REG                                              0xf00c\n#define mmCGTS_CU1_SP0_CTRL_REG                                                 0xf00d\n#define mmCGTS_CU1_LDS_SQ_CTRL_REG                                              0xf00e\n#define mmCGTS_CU1_TA_CTRL_REG                                                  0xf00f\n#define mmCGTS_CU1_SP1_CTRL_REG                                                 0xf010\n#define mmCGTS_CU1_TD_TCP_CTRL_REG                                              0xf011\n#define mmCGTS_CU2_SP0_CTRL_REG                                                 0xf012\n#define mmCGTS_CU2_LDS_SQ_CTRL_REG                                              0xf013\n#define mmCGTS_CU2_TA_CTRL_REG                                                  0xf014\n#define mmCGTS_CU2_SP1_CTRL_REG                                                 0xf015\n#define mmCGTS_CU2_TD_TCP_CTRL_REG                                              0xf016\n#define mmCGTS_CU3_SP0_CTRL_REG                                                 0xf017\n#define mmCGTS_CU3_LDS_SQ_CTRL_REG                                              0xf018\n#define mmCGTS_CU3_TA_CTRL_REG                                                  0xf019\n#define mmCGTS_CU3_SP1_CTRL_REG                                                 0xf01a\n#define mmCGTS_CU3_TD_TCP_CTRL_REG                                              0xf01b\n#define mmCGTS_CU4_SP0_CTRL_REG                                                 0xf01c\n#define mmCGTS_CU4_LDS_SQ_CTRL_REG                                              0xf01d\n#define mmCGTS_CU4_TA_SQC_CTRL_REG                                              0xf01e\n#define mmCGTS_CU4_SP1_CTRL_REG                                                 0xf01f\n#define mmCGTS_CU4_TD_TCP_CTRL_REG                                              0xf020\n#define mmCGTS_CU5_SP0_CTRL_REG                                                 0xf021\n#define mmCGTS_CU5_LDS_SQ_CTRL_REG                                              0xf022\n#define mmCGTS_CU5_TA_CTRL_REG                                                  0xf023\n#define mmCGTS_CU5_SP1_CTRL_REG                                                 0xf024\n#define mmCGTS_CU5_TD_TCP_CTRL_REG                                              0xf025\n#define mmCGTS_CU6_SP0_CTRL_REG                                                 0xf026\n#define mmCGTS_CU6_LDS_SQ_CTRL_REG                                              0xf027\n#define mmCGTS_CU6_TA_CTRL_REG                                                  0xf028\n#define mmCGTS_CU6_SP1_CTRL_REG                                                 0xf029\n#define mmCGTS_CU6_TD_TCP_CTRL_REG                                              0xf02a\n#define mmCGTS_CU7_SP0_CTRL_REG                                                 0xf02b\n#define mmCGTS_CU7_LDS_SQ_CTRL_REG                                              0xf02c\n#define mmCGTS_CU7_TA_CTRL_REG                                                  0xf02d\n#define mmCGTS_CU7_SP1_CTRL_REG                                                 0xf02e\n#define mmCGTS_CU7_TD_TCP_CTRL_REG                                              0xf02f\n#define mmCGTS_CU8_SP0_CTRL_REG                                                 0xf030\n#define mmCGTS_CU8_LDS_SQ_CTRL_REG                                              0xf031\n#define mmCGTS_CU8_TA_SQC_CTRL_REG                                              0xf032\n#define mmCGTS_CU8_SP1_CTRL_REG                                                 0xf033\n#define mmCGTS_CU8_TD_TCP_CTRL_REG                                              0xf034\n#define mmCGTS_CU9_SP0_CTRL_REG                                                 0xf035\n#define mmCGTS_CU9_LDS_SQ_CTRL_REG                                              0xf036\n#define mmCGTS_CU9_TA_CTRL_REG                                                  0xf037\n#define mmCGTS_CU9_SP1_CTRL_REG                                                 0xf038\n#define mmCGTS_CU9_TD_TCP_CTRL_REG                                              0xf039\n#define mmCGTS_CU10_SP0_CTRL_REG                                                0xf03a\n#define mmCGTS_CU10_LDS_SQ_CTRL_REG                                             0xf03b\n#define mmCGTS_CU10_TA_CTRL_REG                                                 0xf03c\n#define mmCGTS_CU10_SP1_CTRL_REG                                                0xf03d\n#define mmCGTS_CU10_TD_TCP_CTRL_REG                                             0xf03e\n#define mmCGTS_CU11_SP0_CTRL_REG                                                0xf03f\n#define mmCGTS_CU11_LDS_SQ_CTRL_REG                                             0xf040\n#define mmCGTS_CU11_TA_CTRL_REG                                                 0xf041\n#define mmCGTS_CU11_SP1_CTRL_REG                                                0xf042\n#define mmCGTS_CU11_TD_TCP_CTRL_REG                                             0xf043\n#define mmCGTS_CU12_SP0_CTRL_REG                                                0xf044\n#define mmCGTS_CU12_LDS_SQ_CTRL_REG                                             0xf045\n#define mmCGTS_CU12_TA_SQC_CTRL_REG                                             0xf046\n#define mmCGTS_CU12_SP1_CTRL_REG                                                0xf047\n#define mmCGTS_CU12_TD_TCP_CTRL_REG                                             0xf048\n#define mmCGTS_CU13_SP0_CTRL_REG                                                0xf049\n#define mmCGTS_CU13_LDS_SQ_CTRL_REG                                             0xf04a\n#define mmCGTS_CU13_TA_CTRL_REG                                                 0xf04b\n#define mmCGTS_CU13_SP1_CTRL_REG                                                0xf04c\n#define mmCGTS_CU13_TD_TCP_CTRL_REG                                             0xf04d\n#define mmCGTS_CU14_SP0_CTRL_REG                                                0xf04e\n#define mmCGTS_CU14_LDS_SQ_CTRL_REG                                             0xf04f\n#define mmCGTS_CU14_TA_CTRL_REG                                                 0xf050\n#define mmCGTS_CU14_SP1_CTRL_REG                                                0xf051\n#define mmCGTS_CU14_TD_TCP_CTRL_REG                                             0xf052\n#define mmCGTS_CU15_SP0_CTRL_REG                                                0xf053\n#define mmCGTS_CU15_LDS_SQ_CTRL_REG                                             0xf054\n#define mmCGTS_CU15_TA_CTRL_REG                                                 0xf055\n#define mmCGTS_CU15_SP1_CTRL_REG                                                0xf056\n#define mmCGTS_CU15_TD_TCP_CTRL_REG                                             0xf057\n#define mmCGTT_SPI_CLK_CTRL                                                     0xf080\n#define mmCGTT_PC_CLK_CTRL                                                      0xf081\n#define mmCGTT_BCI_CLK_CTRL                                                     0xf082\n#define mmSPI_WF_LIFETIME_CNTL                                                  0x24aa\n#define mmSPI_WF_LIFETIME_LIMIT_0                                               0x24ab\n#define mmSPI_WF_LIFETIME_LIMIT_1                                               0x24ac\n#define mmSPI_WF_LIFETIME_LIMIT_2                                               0x24ad\n#define mmSPI_WF_LIFETIME_LIMIT_3                                               0x24ae\n#define mmSPI_WF_LIFETIME_LIMIT_4                                               0x24af\n#define mmSPI_WF_LIFETIME_LIMIT_5                                               0x24b0\n#define mmSPI_WF_LIFETIME_LIMIT_6                                               0x24b1\n#define mmSPI_WF_LIFETIME_LIMIT_7                                               0x24b2\n#define mmSPI_WF_LIFETIME_LIMIT_8                                               0x24b3\n#define mmSPI_WF_LIFETIME_LIMIT_9                                               0x24b4\n#define mmSPI_WF_LIFETIME_STATUS_0                                              0x24b5\n#define mmSPI_WF_LIFETIME_STATUS_1                                              0x24b6\n#define mmSPI_WF_LIFETIME_STATUS_2                                              0x24b7\n#define mmSPI_WF_LIFETIME_STATUS_3                                              0x24b8\n#define mmSPI_WF_LIFETIME_STATUS_4                                              0x24b9\n#define mmSPI_WF_LIFETIME_STATUS_5                                              0x24ba\n#define mmSPI_WF_LIFETIME_STATUS_6                                              0x24bb\n#define mmSPI_WF_LIFETIME_STATUS_7                                              0x24bc\n#define mmSPI_WF_LIFETIME_STATUS_8                                              0x24bd\n#define mmSPI_WF_LIFETIME_STATUS_9                                              0x24be\n#define mmSPI_WF_LIFETIME_STATUS_10                                             0x24bf\n#define mmSPI_WF_LIFETIME_STATUS_11                                             0x24c0\n#define mmSPI_WF_LIFETIME_STATUS_12                                             0x24c1\n#define mmSPI_WF_LIFETIME_STATUS_13                                             0x24c2\n#define mmSPI_WF_LIFETIME_STATUS_14                                             0x24c3\n#define mmSPI_WF_LIFETIME_STATUS_15                                             0x24c4\n#define mmSPI_WF_LIFETIME_STATUS_16                                             0x24c5\n#define mmSPI_WF_LIFETIME_STATUS_17                                             0x24c6\n#define mmSPI_WF_LIFETIME_STATUS_18                                             0x24c7\n#define mmSPI_WF_LIFETIME_STATUS_19                                             0x24c8\n#define mmSPI_WF_LIFETIME_STATUS_20                                             0x24c9\n#define mmSPI_WF_LIFETIME_DEBUG                                                 0x24ca\n#define mmSPI_SLAVE_DEBUG_BUSY                                                  0x24d3\n#define mmSPI_LB_CTR_CTRL                                                       0x24d4\n#define mmSPI_LB_CU_MASK                                                        0x24d5\n#define mmSPI_LB_DATA_REG                                                       0x24d6\n#define mmSPI_PG_ENABLE_STATIC_CU_MASK                                          0x24d7\n#define mmSPI_GDS_CREDITS                                                       0x24d8\n#define mmSPI_SX_EXPORT_BUFFER_SIZES                                            0x24d9\n#define mmSPI_SX_SCOREBOARD_BUFFER_SIZES                                        0x24da\n#define mmSPI_CSQ_WF_ACTIVE_STATUS                                              0x24db\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_0                                             0x24dc\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_1                                             0x24dd\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_2                                             0x24de\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_3                                             0x24df\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_4                                             0x24e0\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_5                                             0x24e1\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_6                                             0x24e2\n#define mmSPI_CSQ_WF_ACTIVE_COUNT_7                                             0x24e3\n#define mmBCI_DEBUG_READ                                                        0x24eb\n#define mmSPI_P0_TRAP_SCREEN_PSBA_LO                                            0x24ec\n#define mmSPI_P0_TRAP_SCREEN_PSBA_HI                                            0x24ed\n#define mmSPI_P0_TRAP_SCREEN_PSMA_LO                                            0x24ee\n#define mmSPI_P0_TRAP_SCREEN_PSMA_HI                                            0x24ef\n#define mmSPI_P0_TRAP_SCREEN_GPR_MIN                                            0x24f0\n#define mmSPI_P1_TRAP_SCREEN_PSBA_LO                                            0x24f1\n#define mmSPI_P1_TRAP_SCREEN_PSBA_HI                                            0x24f2\n#define mmSPI_P1_TRAP_SCREEN_PSMA_LO                                            0x24f3\n#define mmSPI_P1_TRAP_SCREEN_PSMA_HI                                            0x24f4\n#define mmSPI_P1_TRAP_SCREEN_GPR_MIN                                            0x24f5\n#define mmSPI_SHADER_TBA_LO_PS                                                  0x2c00\n#define mmSPI_SHADER_TBA_HI_PS                                                  0x2c01\n#define mmSPI_SHADER_TMA_LO_PS                                                  0x2c02\n#define mmSPI_SHADER_TMA_HI_PS                                                  0x2c03\n#define mmSPI_SHADER_PGM_LO_PS                                                  0x2c08\n#define mmSPI_SHADER_PGM_HI_PS                                                  0x2c09\n#define mmSPI_SHADER_PGM_RSRC1_PS                                               0x2c0a\n#define mmSPI_SHADER_PGM_RSRC2_PS                                               0x2c0b\n#define mmSPI_SHADER_PGM_RSRC3_PS                                               0x2c07\n#define mmSPI_SHADER_USER_DATA_PS_0                                             0x2c0c\n#define mmSPI_SHADER_USER_DATA_PS_1                                             0x2c0d\n#define mmSPI_SHADER_USER_DATA_PS_2                                             0x2c0e\n#define mmSPI_SHADER_USER_DATA_PS_3                                             0x2c0f\n#define mmSPI_SHADER_USER_DATA_PS_4                                             0x2c10\n#define mmSPI_SHADER_USER_DATA_PS_5                                             0x2c11\n#define mmSPI_SHADER_USER_DATA_PS_6                                             0x2c12\n#define mmSPI_SHADER_USER_DATA_PS_7                                             0x2c13\n#define mmSPI_SHADER_USER_DATA_PS_8                                             0x2c14\n#define mmSPI_SHADER_USER_DATA_PS_9                                             0x2c15\n#define mmSPI_SHADER_USER_DATA_PS_10                                            0x2c16\n#define mmSPI_SHADER_USER_DATA_PS_11                                            0x2c17\n#define mmSPI_SHADER_USER_DATA_PS_12                                            0x2c18\n#define mmSPI_SHADER_USER_DATA_PS_13                                            0x2c19\n#define mmSPI_SHADER_USER_DATA_PS_14                                            0x2c1a\n#define mmSPI_SHADER_USER_DATA_PS_15                                            0x2c1b\n#define mmSPI_SHADER_TBA_LO_VS                                                  0x2c40\n#define mmSPI_SHADER_TBA_HI_VS                                                  0x2c41\n#define mmSPI_SHADER_TMA_LO_VS                                                  0x2c42\n#define mmSPI_SHADER_TMA_HI_VS                                                  0x2c43\n#define mmSPI_SHADER_PGM_LO_VS                                                  0x2c48\n#define mmSPI_SHADER_PGM_HI_VS                                                  0x2c49\n#define mmSPI_SHADER_PGM_RSRC1_VS                                               0x2c4a\n#define mmSPI_SHADER_PGM_RSRC2_VS                                               0x2c4b\n#define mmSPI_SHADER_PGM_RSRC3_VS                                               0x2c46\n#define mmSPI_SHADER_LATE_ALLOC_VS                                              0x2c47\n#define mmSPI_SHADER_USER_DATA_VS_0                                             0x2c4c\n#define mmSPI_SHADER_USER_DATA_VS_1                                             0x2c4d\n#define mmSPI_SHADER_USER_DATA_VS_2                                             0x2c4e\n#define mmSPI_SHADER_USER_DATA_VS_3                                             0x2c4f\n#define mmSPI_SHADER_USER_DATA_VS_4                                             0x2c50\n#define mmSPI_SHADER_USER_DATA_VS_5                                             0x2c51\n#define mmSPI_SHADER_USER_DATA_VS_6                                             0x2c52\n#define mmSPI_SHADER_USER_DATA_VS_7                                             0x2c53\n#define mmSPI_SHADER_USER_DATA_VS_8                                             0x2c54\n#define mmSPI_SHADER_USER_DATA_VS_9                                             0x2c55\n#define mmSPI_SHADER_USER_DATA_VS_10                                            0x2c56\n#define mmSPI_SHADER_USER_DATA_VS_11                                            0x2c57\n#define mmSPI_SHADER_USER_DATA_VS_12                                            0x2c58\n#define mmSPI_SHADER_USER_DATA_VS_13                                            0x2c59\n#define mmSPI_SHADER_USER_DATA_VS_14                                            0x2c5a\n#define mmSPI_SHADER_USER_DATA_VS_15                                            0x2c5b\n#define mmSPI_SHADER_PGM_RSRC2_ES_VS                                            0x2c7c\n#define mmSPI_SHADER_PGM_RSRC2_LS_VS                                            0x2c7d\n#define mmSPI_SHADER_TBA_LO_GS                                                  0x2c80\n#define mmSPI_SHADER_TBA_HI_GS                                                  0x2c81\n#define mmSPI_SHADER_TMA_LO_GS                                                  0x2c82\n#define mmSPI_SHADER_TMA_HI_GS                                                  0x2c83\n#define mmSPI_SHADER_PGM_LO_GS                                                  0x2c88\n#define mmSPI_SHADER_PGM_HI_GS                                                  0x2c89\n#define mmSPI_SHADER_PGM_RSRC1_GS                                               0x2c8a\n#define mmSPI_SHADER_PGM_RSRC2_GS                                               0x2c8b\n#define mmSPI_SHADER_PGM_RSRC3_GS                                               0x2c87\n#define mmSPI_SHADER_USER_DATA_GS_0                                             0x2c8c\n#define mmSPI_SHADER_USER_DATA_GS_1                                             0x2c8d\n#define mmSPI_SHADER_USER_DATA_GS_2                                             0x2c8e\n#define mmSPI_SHADER_USER_DATA_GS_3                                             0x2c8f\n#define mmSPI_SHADER_USER_DATA_GS_4                                             0x2c90\n#define mmSPI_SHADER_USER_DATA_GS_5                                             0x2c91\n#define mmSPI_SHADER_USER_DATA_GS_6                                             0x2c92\n#define mmSPI_SHADER_USER_DATA_GS_7                                             0x2c93\n#define mmSPI_SHADER_USER_DATA_GS_8                                             0x2c94\n#define mmSPI_SHADER_USER_DATA_GS_9                                             0x2c95\n#define mmSPI_SHADER_USER_DATA_GS_10                                            0x2c96\n#define mmSPI_SHADER_USER_DATA_GS_11                                            0x2c97\n#define mmSPI_SHADER_USER_DATA_GS_12                                            0x2c98\n#define mmSPI_SHADER_USER_DATA_GS_13                                            0x2c99\n#define mmSPI_SHADER_USER_DATA_GS_14                                            0x2c9a\n#define mmSPI_SHADER_USER_DATA_GS_15                                            0x2c9b\n#define mmSPI_SHADER_PGM_RSRC2_ES_GS                                            0x2cbc\n#define mmSPI_SHADER_TBA_LO_ES                                                  0x2cc0\n#define mmSPI_SHADER_TBA_HI_ES                                                  0x2cc1\n#define mmSPI_SHADER_TMA_LO_ES                                                  0x2cc2\n#define mmSPI_SHADER_TMA_HI_ES                                                  0x2cc3\n#define mmSPI_SHADER_PGM_LO_ES                                                  0x2cc8\n#define mmSPI_SHADER_PGM_HI_ES                                                  0x2cc9\n#define mmSPI_SHADER_PGM_RSRC1_ES                                               0x2cca\n#define mmSPI_SHADER_PGM_RSRC2_ES                                               0x2ccb\n#define mmSPI_SHADER_PGM_RSRC3_ES                                               0x2cc7\n#define mmSPI_SHADER_USER_DATA_ES_0                                             0x2ccc\n#define mmSPI_SHADER_USER_DATA_ES_1                                             0x2ccd\n#define mmSPI_SHADER_USER_DATA_ES_2                                             0x2cce\n#define mmSPI_SHADER_USER_DATA_ES_3                                             0x2ccf\n#define mmSPI_SHADER_USER_DATA_ES_4                                             0x2cd0\n#define mmSPI_SHADER_USER_DATA_ES_5                                             0x2cd1\n#define mmSPI_SHADER_USER_DATA_ES_6                                             0x2cd2\n#define mmSPI_SHADER_USER_DATA_ES_7                                             0x2cd3\n#define mmSPI_SHADER_USER_DATA_ES_8                                             0x2cd4\n#define mmSPI_SHADER_USER_DATA_ES_9                                             0x2cd5\n#define mmSPI_SHADER_USER_DATA_ES_10                                            0x2cd6\n#define mmSPI_SHADER_USER_DATA_ES_11                                            0x2cd7\n#define mmSPI_SHADER_USER_DATA_ES_12                                            0x2cd8\n#define mmSPI_SHADER_USER_DATA_ES_13                                            0x2cd9\n#define mmSPI_SHADER_USER_DATA_ES_14                                            0x2cda\n#define mmSPI_SHADER_USER_DATA_ES_15                                            0x2cdb\n#define mmSPI_SHADER_PGM_RSRC2_LS_ES                                            0x2cfd\n#define mmSPI_SHADER_TBA_LO_HS                                                  0x2d00\n#define mmSPI_SHADER_TBA_HI_HS                                                  0x2d01\n#define mmSPI_SHADER_TMA_LO_HS                                                  0x2d02\n#define mmSPI_SHADER_TMA_HI_HS                                                  0x2d03\n#define mmSPI_SHADER_PGM_LO_HS                                                  0x2d08\n#define mmSPI_SHADER_PGM_HI_HS                                                  0x2d09\n#define mmSPI_SHADER_PGM_RSRC1_HS                                               0x2d0a\n#define mmSPI_SHADER_PGM_RSRC2_HS                                               0x2d0b\n#define mmSPI_SHADER_PGM_RSRC3_HS                                               0x2d07\n#define mmSPI_SHADER_USER_DATA_HS_0                                             0x2d0c\n#define mmSPI_SHADER_USER_DATA_HS_1                                             0x2d0d\n#define mmSPI_SHADER_USER_DATA_HS_2                                             0x2d0e\n#define mmSPI_SHADER_USER_DATA_HS_3                                             0x2d0f\n#define mmSPI_SHADER_USER_DATA_HS_4                                             0x2d10\n#define mmSPI_SHADER_USER_DATA_HS_5                                             0x2d11\n#define mmSPI_SHADER_USER_DATA_HS_6                                             0x2d12\n#define mmSPI_SHADER_USER_DATA_HS_7                                             0x2d13\n#define mmSPI_SHADER_USER_DATA_HS_8                                             0x2d14\n#define mmSPI_SHADER_USER_DATA_HS_9                                             0x2d15\n#define mmSPI_SHADER_USER_DATA_HS_10                                            0x2d16\n#define mmSPI_SHADER_USER_DATA_HS_11                                            0x2d17\n#define mmSPI_SHADER_USER_DATA_HS_12                                            0x2d18\n#define mmSPI_SHADER_USER_DATA_HS_13                                            0x2d19\n#define mmSPI_SHADER_USER_DATA_HS_14                                            0x2d1a\n#define mmSPI_SHADER_USER_DATA_HS_15                                            0x2d1b\n#define mmSPI_SHADER_PGM_RSRC2_LS_HS                                            0x2d3d\n#define mmSPI_SHADER_TBA_LO_LS                                                  0x2d40\n#define mmSPI_SHADER_TBA_HI_LS                                                  0x2d41\n#define mmSPI_SHADER_TMA_LO_LS                                                  0x2d42\n#define mmSPI_SHADER_TMA_HI_LS                                                  0x2d43\n#define mmSPI_SHADER_PGM_LO_LS                                                  0x2d48\n#define mmSPI_SHADER_PGM_HI_LS                                                  0x2d49\n#define mmSPI_SHADER_PGM_RSRC1_LS                                               0x2d4a\n#define mmSPI_SHADER_PGM_RSRC2_LS                                               0x2d4b\n#define mmSPI_SHADER_PGM_RSRC3_LS                                               0x2d47\n#define mmSPI_SHADER_USER_DATA_LS_0                                             0x2d4c\n#define mmSPI_SHADER_USER_DATA_LS_1                                             0x2d4d\n#define mmSPI_SHADER_USER_DATA_LS_2                                             0x2d4e\n#define mmSPI_SHADER_USER_DATA_LS_3                                             0x2d4f\n#define mmSPI_SHADER_USER_DATA_LS_4                                             0x2d50\n#define mmSPI_SHADER_USER_DATA_LS_5                                             0x2d51\n#define mmSPI_SHADER_USER_DATA_LS_6                                             0x2d52\n#define mmSPI_SHADER_USER_DATA_LS_7                                             0x2d53\n#define mmSPI_SHADER_USER_DATA_LS_8                                             0x2d54\n#define mmSPI_SHADER_USER_DATA_LS_9                                             0x2d55\n#define mmSPI_SHADER_USER_DATA_LS_10                                            0x2d56\n#define mmSPI_SHADER_USER_DATA_LS_11                                            0x2d57\n#define mmSPI_SHADER_USER_DATA_LS_12                                            0x2d58\n#define mmSPI_SHADER_USER_DATA_LS_13                                            0x2d59\n#define mmSPI_SHADER_USER_DATA_LS_14                                            0x2d5a\n#define mmSPI_SHADER_USER_DATA_LS_15                                            0x2d5b\n#define mmSQ_CONFIG                                                             0x2300\n#define mmSQC_CONFIG                                                            0x2301\n#define mmSQC_CACHES                                                            0xc348\n#define mmSQ_RANDOM_WAVE_PRI                                                    0x2303\n#define mmSQ_REG_CREDITS                                                        0x2304\n#define mmSQ_FIFO_SIZES                                                         0x2305\n#define mmSQ_INTERRUPT_AUTO_MASK                                                0x2314\n#define mmSQ_INTERRUPT_MSG_CTRL                                                 0x2315\n#define mmSQ_PERFCOUNTER_CTRL                                                   0xd9e0\n#define mmSQ_PERFCOUNTER_MASK                                                   0xd9e1\n#define mmSQ_PERFCOUNTER_CTRL2                                                  0xd9e2\n#define mmCC_SQC_BANK_DISABLE                                                   0x2307\n#define mmUSER_SQC_BANK_DISABLE                                                 0x2308\n#define mmSQ_PERFCOUNTER0_LO                                                    0xd1c0\n#define mmSQ_PERFCOUNTER1_LO                                                    0xd1c2\n#define mmSQ_PERFCOUNTER2_LO                                                    0xd1c4\n#define mmSQ_PERFCOUNTER3_LO                                                    0xd1c6\n#define mmSQ_PERFCOUNTER4_LO                                                    0xd1c8\n#define mmSQ_PERFCOUNTER5_LO                                                    0xd1ca\n#define mmSQ_PERFCOUNTER6_LO                                                    0xd1cc\n#define mmSQ_PERFCOUNTER7_LO                                                    0xd1ce\n#define mmSQ_PERFCOUNTER8_LO                                                    0xd1d0\n#define mmSQ_PERFCOUNTER9_LO                                                    0xd1d2\n#define mmSQ_PERFCOUNTER10_LO                                                   0xd1d4\n#define mmSQ_PERFCOUNTER11_LO                                                   0xd1d6\n#define mmSQ_PERFCOUNTER12_LO                                                   0xd1d8\n#define mmSQ_PERFCOUNTER13_LO                                                   0xd1da\n#define mmSQ_PERFCOUNTER14_LO                                                   0xd1dc\n#define mmSQ_PERFCOUNTER15_LO                                                   0xd1de\n#define mmSQ_PERFCOUNTER0_HI                                                    0xd1c1\n#define mmSQ_PERFCOUNTER1_HI                                                    0xd1c3\n#define mmSQ_PERFCOUNTER2_HI                                                    0xd1c5\n#define mmSQ_PERFCOUNTER3_HI                                                    0xd1c7\n#define mmSQ_PERFCOUNTER4_HI                                                    0xd1c9\n#define mmSQ_PERFCOUNTER5_HI                                                    0xd1cb\n#define mmSQ_PERFCOUNTER6_HI                                                    0xd1cd\n#define mmSQ_PERFCOUNTER7_HI                                                    0xd1cf\n#define mmSQ_PERFCOUNTER8_HI                                                    0xd1d1\n#define mmSQ_PERFCOUNTER9_HI                                                    0xd1d3\n#define mmSQ_PERFCOUNTER10_HI                                                   0xd1d5\n#define mmSQ_PERFCOUNTER11_HI                                                   0xd1d7\n#define mmSQ_PERFCOUNTER12_HI                                                   0xd1d9\n#define mmSQ_PERFCOUNTER13_HI                                                   0xd1db\n#define mmSQ_PERFCOUNTER14_HI                                                   0xd1dd\n#define mmSQ_PERFCOUNTER15_HI                                                   0xd1df\n#define mmSQ_PERFCOUNTER0_SELECT                                                0xd9c0\n#define mmSQ_PERFCOUNTER1_SELECT                                                0xd9c1\n#define mmSQ_PERFCOUNTER2_SELECT                                                0xd9c2\n#define mmSQ_PERFCOUNTER3_SELECT                                                0xd9c3\n#define mmSQ_PERFCOUNTER4_SELECT                                                0xd9c4\n#define mmSQ_PERFCOUNTER5_SELECT                                                0xd9c5\n#define mmSQ_PERFCOUNTER6_SELECT                                                0xd9c6\n#define mmSQ_PERFCOUNTER7_SELECT                                                0xd9c7\n#define mmSQ_PERFCOUNTER8_SELECT                                                0xd9c8\n#define mmSQ_PERFCOUNTER9_SELECT                                                0xd9c9\n#define mmSQ_PERFCOUNTER10_SELECT                                               0xd9ca\n#define mmSQ_PERFCOUNTER11_SELECT                                               0xd9cb\n#define mmSQ_PERFCOUNTER12_SELECT                                               0xd9cc\n#define mmSQ_PERFCOUNTER13_SELECT                                               0xd9cd\n#define mmSQ_PERFCOUNTER14_SELECT                                               0xd9ce\n#define mmSQ_PERFCOUNTER15_SELECT                                               0xd9cf\n#define mmCGTT_SQ_CLK_CTRL                                                      0xf08c\n#define mmCGTT_SQG_CLK_CTRL                                                     0xf08d\n#define mmSQ_ALU_CLK_CTRL                                                       0xf08e\n#define mmSQ_TEX_CLK_CTRL                                                       0xf08f\n#define mmSQ_LDS_CLK_CTRL                                                       0xf090\n#define mmSQ_POWER_THROTTLE                                                     0xf091\n#define mmSQ_POWER_THROTTLE2                                                    0xf092\n#define mmSQ_TIME_HI                                                            0x237c\n#define mmSQ_TIME_LO                                                            0x237d\n#define mmSQ_THREAD_TRACE_BASE                                                  0x2380\n#define mmSQ_THREAD_TRACE_BASE2                                                 0x2385\n#define mmSQ_THREAD_TRACE_SIZE                                                  0x2381\n#define mmSQ_THREAD_TRACE_MASK                                                  0x2382\n#define mmSQ_THREAD_TRACE_USERDATA_0                                            0xc340\n#define mmSQ_THREAD_TRACE_USERDATA_1                                            0xc341\n#define mmSQ_THREAD_TRACE_USERDATA_2                                            0xc342\n#define mmSQ_THREAD_TRACE_USERDATA_3                                            0xc343\n#define mmSQ_THREAD_TRACE_MODE                                                  0x238e\n#define mmSQ_THREAD_TRACE_CTRL                                                  0x238f\n#define mmSQ_THREAD_TRACE_TOKEN_MASK                                            0x2383\n#define mmSQ_THREAD_TRACE_TOKEN_MASK2                                           0x2386\n#define mmSQ_THREAD_TRACE_PERF_MASK                                             0x2384\n#define mmSQ_THREAD_TRACE_WPTR                                                  0x238c\n#define mmSQ_THREAD_TRACE_STATUS                                                0x238d\n#define mmSQ_THREAD_TRACE_CNTR                                                  0x2390\n#define mmSQ_THREAD_TRACE_HIWATER                                               0x2392\n#define mmSQ_LB_CTR_CTRL                                                        0x2398\n#define mmSQ_LB_DATA_ALU_CYCLES                                                 0x2399\n#define mmSQ_LB_DATA_TEX_CYCLES                                                 0x239a\n#define mmSQ_LB_DATA_ALU_STALLS                                                 0x239b\n#define mmSQ_LB_DATA_TEX_STALLS                                                 0x239c\n#define mmSQC_SECDED_CNT                                                        0x23a0\n#define mmSQ_SEC_CNT                                                            0x23a1\n#define mmSQ_DED_CNT                                                            0x23a2\n#define mmSQ_DED_INFO                                                           0x23a3\n#define mmSQ_BUF_RSRC_WORD0                                                     0x23c0\n#define mmSQ_BUF_RSRC_WORD1                                                     0x23c1\n#define mmSQ_BUF_RSRC_WORD2                                                     0x23c2\n#define mmSQ_BUF_RSRC_WORD3                                                     0x23c3\n#define mmSQ_IMG_RSRC_WORD0                                                     0x23c4\n#define mmSQ_IMG_RSRC_WORD1                                                     0x23c5\n#define mmSQ_IMG_RSRC_WORD2                                                     0x23c6\n#define mmSQ_IMG_RSRC_WORD3                                                     0x23c7\n#define mmSQ_IMG_RSRC_WORD4                                                     0x23c8\n#define mmSQ_IMG_RSRC_WORD5                                                     0x23c9\n#define mmSQ_IMG_RSRC_WORD6                                                     0x23ca\n#define mmSQ_IMG_RSRC_WORD7                                                     0x23cb\n#define mmSQ_IMG_SAMP_WORD0                                                     0x23cc\n#define mmSQ_IMG_SAMP_WORD1                                                     0x23cd\n#define mmSQ_IMG_SAMP_WORD2                                                     0x23ce\n#define mmSQ_IMG_SAMP_WORD3                                                     0x23cf\n#define mmSQ_FLAT_SCRATCH_WORD0                                                 0x23d0\n#define mmSQ_FLAT_SCRATCH_WORD1                                                 0x23d1\n#define mmSQ_IND_INDEX                                                          0x2378\n#define mmSQ_IND_CMD                                                            0x237a\n#define mmSQ_CMD                                                                0x237b\n#define mmSQ_IND_DATA                                                           0x2379\n#define mmSQ_REG_TIMESTAMP                                                      0x2374\n#define mmSQ_CMD_TIMESTAMP                                                      0x2375\n#define mmSQ_HV_VMID_CTRL                                                       0xf840\n#define ixSQ_WAVE_INST_DW0                                                      0x1a\n#define ixSQ_WAVE_INST_DW1                                                      0x1b\n#define ixSQ_WAVE_PC_LO                                                         0x18\n#define ixSQ_WAVE_PC_HI                                                         0x19\n#define ixSQ_WAVE_IB_DBG0                                                       0x1c\n#define ixSQ_WAVE_EXEC_LO                                                       0x27e\n#define ixSQ_WAVE_EXEC_HI                                                       0x27f\n#define ixSQ_WAVE_STATUS                                                        0x12\n#define ixSQ_WAVE_MODE                                                          0x11\n#define ixSQ_WAVE_TRAPSTS                                                       0x13\n#define ixSQ_WAVE_HW_ID                                                         0x14\n#define ixSQ_WAVE_GPR_ALLOC                                                     0x15\n#define ixSQ_WAVE_LDS_ALLOC                                                     0x16\n#define ixSQ_WAVE_IB_STS                                                        0x17\n#define ixSQ_WAVE_M0                                                            0x27c\n#define ixSQ_WAVE_TBA_LO                                                        0x26c\n#define ixSQ_WAVE_TBA_HI                                                        0x26d\n#define ixSQ_WAVE_TMA_LO                                                        0x26e\n#define ixSQ_WAVE_TMA_HI                                                        0x26f\n#define ixSQ_WAVE_TTMP0                                                         0x270\n#define ixSQ_WAVE_TTMP1                                                         0x271\n#define ixSQ_WAVE_TTMP2                                                         0x272\n#define ixSQ_WAVE_TTMP3                                                         0x273\n#define ixSQ_WAVE_TTMP4                                                         0x274\n#define ixSQ_WAVE_TTMP5                                                         0x275\n#define ixSQ_WAVE_TTMP6                                                         0x276\n#define ixSQ_WAVE_TTMP7                                                         0x277\n#define ixSQ_WAVE_TTMP8                                                         0x278\n#define ixSQ_WAVE_TTMP9                                                         0x279\n#define ixSQ_WAVE_TTMP10                                                        0x27a\n#define ixSQ_WAVE_TTMP11                                                        0x27b\n#define mmSQ_DEBUG_STS_GLOBAL                                                   0x2309\n#define mmSQ_DEBUG_STS_GLOBAL2                                                  0x2310\n#define mmSQ_DEBUG_STS_GLOBAL3                                                  0x2311\n#define ixSQ_DEBUG_STS_LOCAL                                                    0x8\n#define ixSQ_DEBUG_CTRL_LOCAL                                                   0x9\n#define mmSH_MEM_BASES                                                          0x230a\n#define mmSH_MEM_APE1_BASE                                                      0x230b\n#define mmSH_MEM_APE1_LIMIT                                                     0x230c\n#define mmSH_MEM_CONFIG                                                         0x230d\n#define mmSQC_POLICY                                                            0x230e\n#define mmSQC_VOLATILE                                                          0x230f\n#define mmSQ_THREAD_TRACE_WORD_CMN                                              0x23b0\n#define mmSQ_THREAD_TRACE_WORD_INST                                             0x23b0\n#define mmSQ_THREAD_TRACE_WORD_INST_PC_1_OF_2                                   0x23b0\n#define mmSQ_THREAD_TRACE_WORD_INST_PC_2_OF_2                                   0x23b1\n#define mmSQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2                             0x23b0\n#define mmSQ_THREAD_TRACE_WORD_INST_USERDATA_2_OF_2                             0x23b1\n#define mmSQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2                                 0x23b0\n#define mmSQ_THREAD_TRACE_WORD_TIMESTAMP_2_OF_2                                 0x23b1\n#define mmSQ_THREAD_TRACE_WORD_WAVE                                             0x23b0\n#define mmSQ_THREAD_TRACE_WORD_MISC                                             0x23b0\n#define mmSQ_THREAD_TRACE_WORD_WAVE_START                                       0x23b0\n#define mmSQ_THREAD_TRACE_WORD_REG_1_OF_2                                       0x23b0\n#define mmSQ_THREAD_TRACE_WORD_REG_2_OF_2                                       0x23b0\n#define mmSQ_THREAD_TRACE_WORD_REG_CS_1_OF_2                                    0x23b0\n#define mmSQ_THREAD_TRACE_WORD_REG_CS_2_OF_2                                    0x23b0\n#define mmSQ_THREAD_TRACE_WORD_EVENT                                            0x23b0\n#define mmSQ_THREAD_TRACE_WORD_ISSUE                                            0x23b0\n#define mmSQ_THREAD_TRACE_WORD_PERF_1_OF_2                                      0x23b0\n#define mmSQ_THREAD_TRACE_WORD_PERF_2_OF_2                                      0x23b1\n#define ixSQ_INTERRUPT_WORD_CMN                                                 0x20c0\n#define ixSQ_INTERRUPT_WORD_AUTO                                                0x20c0\n#define ixSQ_INTERRUPT_WORD_WAVE                                                0x20c0\n#define mmSQ_SOP2                                                               0x237f\n#define mmSQ_VOP1                                                               0x237f\n#define mmSQ_MTBUF_1                                                            0x237f\n#define mmSQ_EXP_1                                                              0x237f\n#define mmSQ_MUBUF_1                                                            0x237f\n#define mmSQ_INST                                                               0x237f\n#define mmSQ_EXP_0                                                              0x237f\n#define mmSQ_MUBUF_0                                                            0x237f\n#define mmSQ_VOP3_0                                                             0x237f\n#define mmSQ_VOP2                                                               0x237f\n#define mmSQ_MTBUF_0                                                            0x237f\n#define mmSQ_SOPP                                                               0x237f\n#define mmSQ_FLAT_0                                                             0x237f\n#define mmSQ_VOP3_0_SDST_ENC                                                    0x237f\n#define mmSQ_MIMG_1                                                             0x237f\n#define mmSQ_SMRD                                                               0x237f\n#define mmSQ_SOP1                                                               0x237f\n#define mmSQ_SOPC                                                               0x237f\n#define mmSQ_FLAT_1                                                             0x237f\n#define mmSQ_DS_1                                                               0x237f\n#define mmSQ_VOP3_1                                                             0x237f\n#define mmSQ_MIMG_0                                                             0x237f\n#define mmSQ_SOPK                                                               0x237f\n#define mmSQ_DS_0                                                               0x237f\n#define mmSQ_VOPC                                                               0x237f\n#define mmSQ_VINTRP                                                             0x237f\n#define mmCGTT_SX_CLK_CTRL0                                                     0xf094\n#define mmCGTT_SX_CLK_CTRL1                                                     0xf095\n#define mmCGTT_SX_CLK_CTRL2                                                     0xf096\n#define mmCGTT_SX_CLK_CTRL3                                                     0xf097\n#define mmCGTT_SX_CLK_CTRL4                                                     0xf098\n#define mmSX_DEBUG_BUSY                                                         0x2414\n#define mmSX_DEBUG_BUSY_2                                                       0x2415\n#define mmSX_DEBUG_BUSY_3                                                       0x2416\n#define mmSX_DEBUG_BUSY_4                                                       0x2417\n#define mmSX_DEBUG_1                                                            0x2418\n#define mmSX_PERFCOUNTER0_SELECT                                                0xda40\n#define mmSX_PERFCOUNTER1_SELECT                                                0xda41\n#define mmSX_PERFCOUNTER2_SELECT                                                0xda42\n#define mmSX_PERFCOUNTER3_SELECT                                                0xda43\n#define mmSX_PERFCOUNTER0_SELECT1                                               0xda44\n#define mmSX_PERFCOUNTER1_SELECT1                                               0xda45\n#define mmSX_PERFCOUNTER0_LO                                                    0xd240\n#define mmSX_PERFCOUNTER0_HI                                                    0xd241\n#define mmSX_PERFCOUNTER1_LO                                                    0xd242\n#define mmSX_PERFCOUNTER1_HI                                                    0xd243\n#define mmSX_PERFCOUNTER2_LO                                                    0xd244\n#define mmSX_PERFCOUNTER2_HI                                                    0xd245\n#define mmSX_PERFCOUNTER3_LO                                                    0xd246\n#define mmSX_PERFCOUNTER3_HI                                                    0xd247\n#define mmTCC_CTRL                                                              0x2b80\n#define mmTCC_EDC_COUNTER                                                       0x2b82\n#define mmTCC_REDUNDANCY                                                        0x2b83\n#define mmTCC_CGTT_SCLK_CTRL                                                    0xf0ac\n#define mmTCA_CGTT_SCLK_CTRL                                                    0xf0ad\n#define mmTCS_CGTT_SCLK_CTRL                                                    0xf0ae\n#define mmTCC_PERFCOUNTER0_SELECT                                               0xdb80\n#define mmTCC_PERFCOUNTER1_SELECT                                               0xdb82\n#define mmTCC_PERFCOUNTER0_SELECT1                                              0xdb81\n#define mmTCC_PERFCOUNTER1_SELECT1                                              0xdb83\n#define mmTCC_PERFCOUNTER2_SELECT                                               0xdb84\n#define mmTCC_PERFCOUNTER3_SELECT                                               0xdb85\n#define mmTCC_PERFCOUNTER0_LO                                                   0xd380\n#define mmTCC_PERFCOUNTER1_LO                                                   0xd382\n#define mmTCC_PERFCOUNTER2_LO                                                   0xd384\n#define mmTCC_PERFCOUNTER3_LO                                                   0xd386\n#define mmTCC_PERFCOUNTER0_HI                                                   0xd381\n#define mmTCC_PERFCOUNTER1_HI                                                   0xd383\n#define mmTCC_PERFCOUNTER2_HI                                                   0xd385\n#define mmTCC_PERFCOUNTER3_HI                                                   0xd387\n#define mmTCA_CTRL                                                              0x2bc0\n#define mmTCA_PERFCOUNTER0_SELECT                                               0xdb90\n#define mmTCA_PERFCOUNTER1_SELECT                                               0xdb92\n#define mmTCA_PERFCOUNTER0_SELECT1                                              0xdb91\n#define mmTCA_PERFCOUNTER1_SELECT1                                              0xdb93\n#define mmTCA_PERFCOUNTER2_SELECT                                               0xdb94\n#define mmTCA_PERFCOUNTER3_SELECT                                               0xdb95\n#define mmTCA_PERFCOUNTER0_LO                                                   0xd390\n#define mmTCA_PERFCOUNTER1_LO                                                   0xd392\n#define mmTCA_PERFCOUNTER2_LO                                                   0xd394\n#define mmTCA_PERFCOUNTER3_LO                                                   0xd396\n#define mmTCA_PERFCOUNTER0_HI                                                   0xd391\n#define mmTCA_PERFCOUNTER1_HI                                                   0xd393\n#define mmTCA_PERFCOUNTER2_HI                                                   0xd395\n#define mmTCA_PERFCOUNTER3_HI                                                   0xd397\n#define mmTCS_CTRL                                                              0x2be0\n#define mmTCS_PERFCOUNTER0_SELECT                                               0xdba0\n#define mmTCS_PERFCOUNTER0_SELECT1                                              0xdba1\n#define mmTCS_PERFCOUNTER1_SELECT                                               0xdba2\n#define mmTCS_PERFCOUNTER2_SELECT                                               0xdba3\n#define mmTCS_PERFCOUNTER3_SELECT                                               0xdba4\n#define mmTCS_PERFCOUNTER0_LO                                                   0xd3a0\n#define mmTCS_PERFCOUNTER1_LO                                                   0xd3a2\n#define mmTCS_PERFCOUNTER2_LO                                                   0xd3a4\n#define mmTCS_PERFCOUNTER3_LO                                                   0xd3a6\n#define mmTCS_PERFCOUNTER0_HI                                                   0xd3a1\n#define mmTCS_PERFCOUNTER1_HI                                                   0xd3a3\n#define mmTCS_PERFCOUNTER2_HI                                                   0xd3a5\n#define mmTCS_PERFCOUNTER3_HI                                                   0xd3a7\n#define mmTA_BC_BASE_ADDR                                                       0xa020\n#define mmTA_BC_BASE_ADDR_HI                                                    0xa021\n#define mmTD_CNTL                                                               0x2525\n#define mmTD_STATUS                                                             0x2526\n#define mmTD_DEBUG_INDEX                                                        0x2528\n#define mmTD_DEBUG_DATA                                                         0x2529\n#define mmTD_PERFCOUNTER0_SELECT                                                0xdb00\n#define mmTD_PERFCOUNTER1_SELECT                                                0xdb02\n#define mmTD_PERFCOUNTER0_SELECT1                                               0xdb01\n#define mmTD_PERFCOUNTER0_LO                                                    0xd300\n#define mmTD_PERFCOUNTER1_LO                                                    0xd302\n#define mmTD_PERFCOUNTER0_HI                                                    0xd301\n#define mmTD_PERFCOUNTER1_HI                                                    0xd303\n#define mmTD_SCRATCH                                                            0x2533\n#define mmTA_CNTL                                                               0x2541\n#define mmTA_CNTL_AUX                                                           0x2542\n#define mmTA_RESERVED_010C                                                      0x2543\n#define mmTA_CS_BC_BASE_ADDR                                                    0xc380\n#define mmTA_CS_BC_BASE_ADDR_HI                                                 0xc381\n#define mmTA_STATUS                                                             0x2548\n#define mmTA_DEBUG_INDEX                                                        0x254c\n#define mmTA_DEBUG_DATA                                                         0x254d\n#define mmTA_PERFCOUNTER0_SELECT                                                0xdac0\n#define mmTA_PERFCOUNTER1_SELECT                                                0xdac2\n#define mmTA_PERFCOUNTER0_SELECT1                                               0xdac1\n#define mmTA_PERFCOUNTER0_LO                                                    0xd2c0\n#define mmTA_PERFCOUNTER1_LO                                                    0xd2c2\n#define mmTA_PERFCOUNTER0_HI                                                    0xd2c1\n#define mmTA_PERFCOUNTER1_HI                                                    0xd2c3\n#define mmTA_SCRATCH                                                            0x2564\n#define mmSH_HIDDEN_PRIVATE_BASE_VMID                                           0x2580\n#define mmSH_STATIC_MEM_CONFIG                                                  0x2581\n#define mmTCP_INVALIDATE                                                        0x2b00\n#define mmTCP_STATUS                                                            0x2b01\n#define mmTCP_CNTL                                                              0x2b02\n#define mmTCP_CHAN_STEER_LO                                                     0x2b03\n#define mmTCP_CHAN_STEER_HI                                                     0x2b04\n#define mmTCP_ADDR_CONFIG                                                       0x2b05\n#define mmTCP_CREDIT                                                            0x2b06\n#define mmTCP_PERFCOUNTER0_SELECT                                               0xdb40\n#define mmTCP_PERFCOUNTER1_SELECT                                               0xdb42\n#define mmTCP_PERFCOUNTER0_SELECT1                                              0xdb41\n#define mmTCP_PERFCOUNTER1_SELECT1                                              0xdb43\n#define mmTCP_PERFCOUNTER2_SELECT                                               0xdb44\n#define mmTCP_PERFCOUNTER3_SELECT                                               0xdb45\n#define mmTCP_PERFCOUNTER0_LO                                                   0xd340\n#define mmTCP_PERFCOUNTER1_LO                                                   0xd342\n#define mmTCP_PERFCOUNTER2_LO                                                   0xd344\n#define mmTCP_PERFCOUNTER3_LO                                                   0xd346\n#define mmTCP_PERFCOUNTER0_HI                                                   0xd341\n#define mmTCP_PERFCOUNTER1_HI                                                   0xd343\n#define mmTCP_PERFCOUNTER2_HI                                                   0xd345\n#define mmTCP_PERFCOUNTER3_HI                                                   0xd347\n#define mmTCP_BUFFER_ADDR_HASH_CNTL                                             0x2b16\n#define mmTCP_EDC_COUNTER                                                       0x2b17\n#define mmTC_CFG_L1_LOAD_POLICY0                                                0x2b1a\n#define mmTC_CFG_L1_LOAD_POLICY1                                                0x2b1b\n#define mmTC_CFG_L1_STORE_POLICY                                                0x2b1c\n#define mmTC_CFG_L2_LOAD_POLICY0                                                0x2b1d\n#define mmTC_CFG_L2_LOAD_POLICY1                                                0x2b1e\n#define mmTC_CFG_L2_STORE_POLICY0                                               0x2b1f\n#define mmTC_CFG_L2_STORE_POLICY1                                               0x2b20\n#define mmTC_CFG_L2_ATOMIC_POLICY                                               0x2b21\n#define mmTC_CFG_L1_VOLATILE                                                    0x2b22\n#define mmTC_CFG_L2_VOLATILE                                                    0x2b23\n#define mmTCP_WATCH0_ADDR_H                                                     0x32a0\n#define mmTCP_WATCH1_ADDR_H                                                     0x32a3\n#define mmTCP_WATCH2_ADDR_H                                                     0x32a6\n#define mmTCP_WATCH3_ADDR_H                                                     0x32a9\n#define mmTCP_WATCH0_ADDR_L                                                     0x32a1\n#define mmTCP_WATCH1_ADDR_L                                                     0x32a4\n#define mmTCP_WATCH2_ADDR_L                                                     0x32a7\n#define mmTCP_WATCH3_ADDR_L                                                     0x32aa\n#define mmTCP_WATCH0_CNTL                                                       0x32a2\n#define mmTCP_WATCH1_CNTL                                                       0x32a5\n#define mmTCP_WATCH2_CNTL                                                       0x32a8\n#define mmTCP_WATCH3_CNTL                                                       0x32ab\n#define mmTD_CGTT_CTRL                                                          0xf09c\n#define mmTA_CGTT_CTRL                                                          0xf09d\n#define mmCGTT_TCP_CLK_CTRL                                                     0xf09e\n#define mmCGTT_TCI_CLK_CTRL                                                     0xf09f\n#define mmTCI_STATUS                                                            0x2b61\n#define mmTCI_CNTL_1                                                            0x2b62\n#define mmTCI_CNTL_2                                                            0x2b63\n#define mmGDS_CONFIG                                                            0x25c0\n#define mmGDS_CNTL_STATUS                                                       0x25c1\n#define mmGDS_ENHANCE2                                                          0x25c2\n#define mmGDS_PROTECTION_FAULT                                                  0x25c3\n#define mmGDS_VM_PROTECTION_FAULT                                               0x25c4\n#define mmGDS_SECDED_CNT                                                        0x25c5\n#define mmGDS_GRBM_SECDED_CNT                                                   0x25c6\n#define mmGDS_OA_DED                                                            0x25c7\n#define mmGDS_DEBUG_CNTL                                                        0x25c8\n#define mmGDS_DEBUG_DATA                                                        0x25c9\n#define mmCGTT_GDS_CLK_CTRL                                                     0xf0a0\n#define mmGDS_RD_ADDR                                                           0xc400\n#define mmGDS_RD_DATA                                                           0xc401\n#define mmGDS_RD_BURST_ADDR                                                     0xc402\n#define mmGDS_RD_BURST_COUNT                                                    0xc403\n#define mmGDS_RD_BURST_DATA                                                     0xc404\n#define mmGDS_WR_ADDR                                                           0xc405\n#define mmGDS_WR_DATA                                                           0xc406\n#define mmGDS_WR_BURST_ADDR                                                     0xc407\n#define mmGDS_WR_BURST_DATA                                                     0xc408\n#define mmGDS_WRITE_COMPLETE                                                    0xc409\n#define mmGDS_ATOM_CNTL                                                         0xc40a\n#define mmGDS_ATOM_COMPLETE                                                     0xc40b\n#define mmGDS_ATOM_BASE                                                         0xc40c\n#define mmGDS_ATOM_SIZE                                                         0xc40d\n#define mmGDS_ATOM_OFFSET0                                                      0xc40e\n#define mmGDS_ATOM_OFFSET1                                                      0xc40f\n#define mmGDS_ATOM_DST                                                          0xc410\n#define mmGDS_ATOM_OP                                                           0xc411\n#define mmGDS_ATOM_SRC0                                                         0xc412\n#define mmGDS_ATOM_SRC0_U                                                       0xc413\n#define mmGDS_ATOM_SRC1                                                         0xc414\n#define mmGDS_ATOM_SRC1_U                                                       0xc415\n#define mmGDS_ATOM_READ0                                                        0xc416\n#define mmGDS_ATOM_READ0_U                                                      0xc417\n#define mmGDS_ATOM_READ1                                                        0xc418\n#define mmGDS_ATOM_READ1_U                                                      0xc419\n#define mmGDS_GWS_RESOURCE_CNTL                                                 0xc41a\n#define mmGDS_GWS_RESOURCE                                                      0xc41b\n#define mmGDS_GWS_RESOURCE_CNT                                                  0xc41c\n#define mmGDS_OA_CNTL                                                           0xc41d\n#define mmGDS_OA_COUNTER                                                        0xc41e\n#define mmGDS_OA_ADDRESS                                                        0xc41f\n#define mmGDS_OA_INCDEC                                                         0xc420\n#define mmGDS_OA_RING_SIZE                                                      0xc421\n#define ixGDS_DEBUG_REG0                                                        0x0\n#define ixGDS_DEBUG_REG1                                                        0x1\n#define ixGDS_DEBUG_REG2                                                        0x2\n#define ixGDS_DEBUG_REG3                                                        0x3\n#define ixGDS_DEBUG_REG4                                                        0x4\n#define ixGDS_DEBUG_REG5                                                        0x5\n#define ixGDS_DEBUG_REG6                                                        0x6\n#define mmGDS_PERFCOUNTER0_SELECT                                               0xda80\n#define mmGDS_PERFCOUNTER1_SELECT                                               0xda81\n#define mmGDS_PERFCOUNTER2_SELECT                                               0xda82\n#define mmGDS_PERFCOUNTER3_SELECT                                               0xda83\n#define mmGDS_PERFCOUNTER0_LO                                                   0xd280\n#define mmGDS_PERFCOUNTER1_LO                                                   0xd282\n#define mmGDS_PERFCOUNTER2_LO                                                   0xd284\n#define mmGDS_PERFCOUNTER3_LO                                                   0xd286\n#define mmGDS_PERFCOUNTER0_HI                                                   0xd281\n#define mmGDS_PERFCOUNTER1_HI                                                   0xd283\n#define mmGDS_PERFCOUNTER2_HI                                                   0xd285\n#define mmGDS_PERFCOUNTER3_HI                                                   0xd287\n#define mmGDS_PERFCOUNTER0_SELECT1                                              0xda84\n#define mmGDS_VMID0_BASE                                                        0x3300\n#define mmGDS_VMID1_BASE                                                        0x3302\n#define mmGDS_VMID2_BASE                                                        0x3304\n#define mmGDS_VMID3_BASE                                                        0x3306\n#define mmGDS_VMID4_BASE                                                        0x3308\n#define mmGDS_VMID5_BASE                                                        0x330a\n#define mmGDS_VMID6_BASE                                                        0x330c\n#define mmGDS_VMID7_BASE                                                        0x330e\n#define mmGDS_VMID8_BASE                                                        0x3310\n#define mmGDS_VMID9_BASE                                                        0x3312\n#define mmGDS_VMID10_BASE                                                       0x3314\n#define mmGDS_VMID11_BASE                                                       0x3316\n#define mmGDS_VMID12_BASE                                                       0x3318\n#define mmGDS_VMID13_BASE                                                       0x331a\n#define mmGDS_VMID14_BASE                                                       0x331c\n#define mmGDS_VMID15_BASE                                                       0x331e\n#define mmGDS_VMID0_SIZE                                                        0x3301\n#define mmGDS_VMID1_SIZE                                                        0x3303\n#define mmGDS_VMID2_SIZE                                                        0x3305\n#define mmGDS_VMID3_SIZE                                                        0x3307\n#define mmGDS_VMID4_SIZE                                                        0x3309\n#define mmGDS_VMID5_SIZE                                                        0x330b\n#define mmGDS_VMID6_SIZE                                                        0x330d\n#define mmGDS_VMID7_SIZE                                                        0x330f\n#define mmGDS_VMID8_SIZE                                                        0x3311\n#define mmGDS_VMID9_SIZE                                                        0x3313\n#define mmGDS_VMID10_SIZE                                                       0x3315\n#define mmGDS_VMID11_SIZE                                                       0x3317\n#define mmGDS_VMID12_SIZE                                                       0x3319\n#define mmGDS_VMID13_SIZE                                                       0x331b\n#define mmGDS_VMID14_SIZE                                                       0x331d\n#define mmGDS_VMID15_SIZE                                                       0x331f\n#define mmGDS_GWS_VMID0                                                         0x3320\n#define mmGDS_GWS_VMID1                                                         0x3321\n#define mmGDS_GWS_VMID2                                                         0x3322\n#define mmGDS_GWS_VMID3                                                         0x3323\n#define mmGDS_GWS_VMID4                                                         0x3324\n#define mmGDS_GWS_VMID5                                                         0x3325\n#define mmGDS_GWS_VMID6                                                         0x3326\n#define mmGDS_GWS_VMID7                                                         0x3327\n#define mmGDS_GWS_VMID8                                                         0x3328\n#define mmGDS_GWS_VMID9                                                         0x3329\n#define mmGDS_GWS_VMID10                                                        0x332a\n#define mmGDS_GWS_VMID11                                                        0x332b\n#define mmGDS_GWS_VMID12                                                        0x332c\n#define mmGDS_GWS_VMID13                                                        0x332d\n#define mmGDS_GWS_VMID14                                                        0x332e\n#define mmGDS_GWS_VMID15                                                        0x332f\n#define mmGDS_OA_VMID0                                                          0x3330\n#define mmGDS_OA_VMID1                                                          0x3331\n#define mmGDS_OA_VMID2                                                          0x3332\n#define mmGDS_OA_VMID3                                                          0x3333\n#define mmGDS_OA_VMID4                                                          0x3334\n#define mmGDS_OA_VMID5                                                          0x3335\n#define mmGDS_OA_VMID6                                                          0x3336\n#define mmGDS_OA_VMID7                                                          0x3337\n#define mmGDS_OA_VMID8                                                          0x3338\n#define mmGDS_OA_VMID9                                                          0x3339\n#define mmGDS_OA_VMID10                                                         0x333a\n#define mmGDS_OA_VMID11                                                         0x333b\n#define mmGDS_OA_VMID12                                                         0x333c\n#define mmGDS_OA_VMID13                                                         0x333d\n#define mmGDS_OA_VMID14                                                         0x333e\n#define mmGDS_OA_VMID15                                                         0x333f\n#define mmGDS_GWS_RESET0                                                        0x3344\n#define mmGDS_GWS_RESET1                                                        0x3345\n#define mmGDS_GWS_RESOURCE_RESET                                                0x3346\n#define mmGDS_COMPUTE_MAX_WAVE_ID                                               0x3348\n#define mmGDS_OA_RESET_MASK                                                     0x3349\n#define mmGDS_OA_RESET                                                          0x334a\n#define mmGDS_ENHANCE                                                           0x334b\n#define mmGDS_OA_CGPG_RESTORE                                                   0x334c\n#define mmCS_COPY_STATE                                                         0xa1f3\n#define mmGFX_COPY_STATE                                                        0xa1f4\n#define mmVGT_DRAW_INITIATOR                                                    0xa1fc\n#define mmVGT_EVENT_INITIATOR                                                   0xa2a4\n#define mmVGT_EVENT_ADDRESS_REG                                                 0xa1fe\n#define mmVGT_DMA_BASE_HI                                                       0xa1f9\n#define mmVGT_DMA_BASE                                                          0xa1fa\n#define mmVGT_DMA_INDEX_TYPE                                                    0xa29f\n#define mmVGT_DMA_NUM_INSTANCES                                                 0xa2a2\n#define mmIA_ENHANCE                                                            0xa29c\n#define mmVGT_DMA_SIZE                                                          0xa29d\n#define mmVGT_DMA_MAX_SIZE                                                      0xa29e\n#define mmVGT_DMA_PRIMITIVE_TYPE                                                0x2271\n#define mmVGT_DMA_CONTROL                                                       0x2272\n#define mmVGT_IMMED_DATA                                                        0xa1fd\n#define mmVGT_INDEX_TYPE                                                        0xc243\n#define mmVGT_NUM_INDICES                                                       0xc24c\n#define mmVGT_NUM_INSTANCES                                                     0xc24d\n#define mmVGT_PRIMITIVE_TYPE                                                    0xc242\n#define mmVGT_PRIMITIVEID_EN                                                    0xa2a1\n#define mmVGT_PRIMITIVEID_RESET                                                 0xa2a3\n#define mmVGT_VTX_CNT_EN                                                        0xa2ae\n#define mmVGT_REUSE_OFF                                                         0xa2ad\n#define mmVGT_INSTANCE_STEP_RATE_0                                              0xa2a8\n#define mmVGT_INSTANCE_STEP_RATE_1                                              0xa2a9\n#define mmVGT_MAX_VTX_INDX                                                      0xa100\n#define mmVGT_MIN_VTX_INDX                                                      0xa101\n#define mmVGT_INDX_OFFSET                                                       0xa102\n#define mmVGT_VERTEX_REUSE_BLOCK_CNTL                                           0xa316\n#define mmVGT_OUT_DEALLOC_CNTL                                                  0xa317\n#define mmVGT_MULTI_PRIM_IB_RESET_INDX                                          0xa103\n#define mmVGT_MULTI_PRIM_IB_RESET_EN                                            0xa2a5\n#define mmVGT_ENHANCE                                                           0xa294\n#define mmVGT_OUTPUT_PATH_CNTL                                                  0xa284\n#define mmVGT_HOS_CNTL                                                          0xa285\n#define mmVGT_HOS_MAX_TESS_LEVEL                                                0xa286\n#define mmVGT_HOS_MIN_TESS_LEVEL                                                0xa287\n#define mmVGT_HOS_REUSE_DEPTH                                                   0xa288\n#define mmVGT_GROUP_PRIM_TYPE                                                   0xa289\n#define mmVGT_GROUP_FIRST_DECR                                                  0xa28a\n#define mmVGT_GROUP_DECR                                                        0xa28b\n#define mmVGT_GROUP_VECT_0_CNTL                                                 0xa28c\n#define mmVGT_GROUP_VECT_1_CNTL                                                 0xa28d\n#define mmVGT_GROUP_VECT_0_FMT_CNTL                                             0xa28e\n#define mmVGT_GROUP_VECT_1_FMT_CNTL                                             0xa28f\n#define mmVGT_VTX_VECT_EJECT_REG                                                0x222c\n#define mmVGT_DMA_DATA_FIFO_DEPTH                                               0x222d\n#define mmVGT_DMA_REQ_FIFO_DEPTH                                                0x222e\n#define mmVGT_DRAW_INIT_FIFO_DEPTH                                              0x222f\n#define mmVGT_LAST_COPY_STATE                                                   0x2230\n#define mmCC_GC_SHADER_ARRAY_CONFIG                                             0x226f\n#define mmGC_USER_SHADER_ARRAY_CONFIG                                           0x2270\n#define mmVGT_GS_MODE                                                           0xa290\n#define mmVGT_GS_ONCHIP_CNTL                                                    0xa291\n#define mmVGT_GS_OUT_PRIM_TYPE                                                  0xa29b\n#define mmVGT_CACHE_INVALIDATION                                                0x2231\n#define mmVGT_RESET_DEBUG                                                       0x2232\n#define mmVGT_STRMOUT_DELAY                                                     0x2233\n#define mmVGT_FIFO_DEPTHS                                                       0x2234\n#define mmVGT_GS_PER_ES                                                         0xa295\n#define mmVGT_ES_PER_GS                                                         0xa296\n#define mmVGT_GS_PER_VS                                                         0xa297\n#define mmVGT_GS_VERTEX_REUSE                                                   0x2235\n#define mmVGT_MC_LAT_CNTL                                                       0x2236\n#define mmIA_CNTL_STATUS                                                        0x2237\n#define mmVGT_STRMOUT_CONFIG                                                    0xa2e5\n#define mmVGT_STRMOUT_BUFFER_SIZE_0                                             0xa2b4\n#define mmVGT_STRMOUT_BUFFER_SIZE_1                                             0xa2b8\n#define mmVGT_STRMOUT_BUFFER_SIZE_2                                             0xa2bc\n#define mmVGT_STRMOUT_BUFFER_SIZE_3                                             0xa2c0\n#define mmVGT_STRMOUT_BUFFER_OFFSET_0                                           0xa2b7\n#define mmVGT_STRMOUT_BUFFER_OFFSET_1                                           0xa2bb\n#define mmVGT_STRMOUT_BUFFER_OFFSET_2                                           0xa2bf\n#define mmVGT_STRMOUT_BUFFER_OFFSET_3                                           0xa2c3\n#define mmVGT_STRMOUT_VTX_STRIDE_0                                              0xa2b5\n#define mmVGT_STRMOUT_VTX_STRIDE_1                                              0xa2b9\n#define mmVGT_STRMOUT_VTX_STRIDE_2                                              0xa2bd\n#define mmVGT_STRMOUT_VTX_STRIDE_3                                              0xa2c1\n#define mmVGT_STRMOUT_BUFFER_CONFIG                                             0xa2e6\n#define mmVGT_STRMOUT_BUFFER_FILLED_SIZE_0                                      0xc244\n#define mmVGT_STRMOUT_BUFFER_FILLED_SIZE_1                                      0xc245\n#define mmVGT_STRMOUT_BUFFER_FILLED_SIZE_2                                      0xc246\n#define mmVGT_STRMOUT_BUFFER_FILLED_SIZE_3                                      0xc247\n#define mmVGT_STRMOUT_DRAW_OPAQUE_OFFSET                                        0xa2ca\n#define mmVGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE                            0xa2cb\n#define mmVGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE                                 0xa2cc\n#define mmVGT_GS_MAX_VERT_OUT                                                   0xa2ce\n#define mmIA_VMID_OVERRIDE                                                      0x2260\n#define mmVGT_SHADER_STAGES_EN                                                  0xa2d5\n#define mmVGT_DISPATCH_DRAW_INDEX                                               0xa2dd\n#define mmVGT_LS_HS_CONFIG                                                      0xa2d6\n#define mmVGT_DMA_LS_HS_CONFIG                                                  0x2273\n#define mmVGT_TF_PARAM                                                          0xa2db\n#define mmVGT_TF_RING_SIZE                                                      0xc24e\n#define mmVGT_SYS_CONFIG                                                        0x2263\n#define mmVGT_HS_OFFCHIP_PARAM                                                  0xc24f\n#define mmVGT_TF_MEMORY_BASE                                                    0xc250\n#define mmVGT_GS_INSTANCE_CNT                                                   0xa2e4\n#define mmIA_MULTI_VGT_PARAM                                                    0xa2aa\n#define mmVGT_VS_MAX_WAVE_ID                                                    0x2268\n#define mmVGT_ESGS_RING_SIZE                                                    0xc240\n#define mmVGT_GSVS_RING_SIZE                                                    0xc241\n#define mmVGT_GSVS_RING_OFFSET_1                                                0xa298\n#define mmVGT_GSVS_RING_OFFSET_2                                                0xa299\n#define mmVGT_GSVS_RING_OFFSET_3                                                0xa29a\n#define mmVGT_ESGS_RING_ITEMSIZE                                                0xa2ab\n#define mmVGT_GSVS_RING_ITEMSIZE                                                0xa2ac\n#define mmVGT_GS_VERT_ITEMSIZE                                                  0xa2d7\n#define mmVGT_GS_VERT_ITEMSIZE_1                                                0xa2d8\n#define mmVGT_GS_VERT_ITEMSIZE_2                                                0xa2d9\n#define mmVGT_GS_VERT_ITEMSIZE_3                                                0xa2da\n#define mmWD_CNTL_STATUS                                                        0x223f\n#define mmWD_ENHANCE                                                            0xa2a0\n#define mmGFX_PIPE_CONTROL                                                      0x226d\n#define mmGFX_PIPE_PRIORITY                                                     0xf87f\n#define mmCGTT_VGT_CLK_CTRL                                                     0xf084\n#define mmCGTT_IA_CLK_CTRL                                                      0xf085\n#define mmCGTT_WD_CLK_CTRL                                                      0xf086\n#define mmVGT_DEBUG_CNTL                                                        0x2238\n#define mmVGT_DEBUG_DATA                                                        0x2239\n#define mmIA_DEBUG_CNTL                                                         0x223a\n#define mmIA_DEBUG_DATA                                                         0x223b\n#define mmVGT_CNTL_STATUS                                                       0x223c\n#define mmWD_DEBUG_CNTL                                                         0x223d\n#define mmWD_DEBUG_DATA                                                         0x223e\n#define mmCC_GC_PRIM_CONFIG                                                     0x2240\n#define mmGC_USER_PRIM_CONFIG                                                   0x2241\n#define ixWD_DEBUG_REG0                                                         0x0\n#define ixWD_DEBUG_REG1                                                         0x1\n#define ixWD_DEBUG_REG2                                                         0x2\n#define ixWD_DEBUG_REG3                                                         0x3\n#define ixWD_DEBUG_REG4                                                         0x4\n#define ixWD_DEBUG_REG5                                                         0x5\n#define ixIA_DEBUG_REG0                                                         0x0\n#define ixIA_DEBUG_REG1                                                         0x1\n#define ixIA_DEBUG_REG2                                                         0x2\n#define ixIA_DEBUG_REG3                                                         0x3\n#define ixIA_DEBUG_REG4                                                         0x4\n#define ixIA_DEBUG_REG5                                                         0x5\n#define ixIA_DEBUG_REG6                                                         0x6\n#define ixIA_DEBUG_REG7                                                         0x7\n#define ixIA_DEBUG_REG8                                                         0x8\n#define ixIA_DEBUG_REG9                                                         0x9\n#define ixVGT_DEBUG_REG0                                                        0x0\n#define ixVGT_DEBUG_REG1                                                        0x1\n#define ixVGT_DEBUG_REG2                                                        0x1e\n#define ixVGT_DEBUG_REG3                                                        0x1f\n#define ixVGT_DEBUG_REG4                                                        0x20\n#define ixVGT_DEBUG_REG5                                                        0x21\n#define ixVGT_DEBUG_REG6                                                        0x22\n#define ixVGT_DEBUG_REG7                                                        0x23\n#define ixVGT_DEBUG_REG8                                                        0x8\n#define ixVGT_DEBUG_REG9                                                        0x9\n#define ixVGT_DEBUG_REG10                                                       0xa\n#define ixVGT_DEBUG_REG11                                                       0xb\n#define ixVGT_DEBUG_REG12                                                       0xc\n#define ixVGT_DEBUG_REG13                                                       0xd\n#define ixVGT_DEBUG_REG14                                                       0xe\n#define ixVGT_DEBUG_REG15                                                       0xf\n#define ixVGT_DEBUG_REG16                                                       0x10\n#define ixVGT_DEBUG_REG17                                                       0x11\n#define ixVGT_DEBUG_REG18                                                       0x7\n#define ixVGT_DEBUG_REG19                                                       0x13\n#define ixVGT_DEBUG_REG20                                                       0x14\n#define ixVGT_DEBUG_REG21                                                       0x15\n#define ixVGT_DEBUG_REG22                                                       0x16\n#define ixVGT_DEBUG_REG23                                                       0x17\n#define ixVGT_DEBUG_REG24                                                       0x18\n#define ixVGT_DEBUG_REG25                                                       0x19\n#define ixVGT_DEBUG_REG26                                                       0x24\n#define ixVGT_DEBUG_REG27                                                       0x1b\n#define ixVGT_DEBUG_REG28                                                       0x1c\n#define ixVGT_DEBUG_REG29                                                       0x1d\n#define ixVGT_DEBUG_REG30                                                       0x25\n#define ixVGT_DEBUG_REG31                                                       0x26\n#define ixVGT_DEBUG_REG32                                                       0x27\n#define ixVGT_DEBUG_REG33                                                       0x28\n#define ixVGT_DEBUG_REG34                                                       0x29\n#define ixVGT_DEBUG_REG35                                                       0x2a\n#define mmVGT_PERFCOUNTER_SEID_MASK                                             0xd894\n#define mmVGT_PERFCOUNTER0_SELECT                                               0xd88c\n#define mmVGT_PERFCOUNTER1_SELECT                                               0xd88d\n#define mmVGT_PERFCOUNTER2_SELECT                                               0xd88e\n#define mmVGT_PERFCOUNTER3_SELECT                                               0xd88f\n#define mmVGT_PERFCOUNTER0_SELECT1                                              0xd890\n#define mmVGT_PERFCOUNTER1_SELECT1                                              0xd891\n#define mmVGT_PERFCOUNTER0_LO                                                   0xd090\n#define mmVGT_PERFCOUNTER1_LO                                                   0xd092\n#define mmVGT_PERFCOUNTER2_LO                                                   0xd094\n#define mmVGT_PERFCOUNTER3_LO                                                   0xd096\n#define mmVGT_PERFCOUNTER0_HI                                                   0xd091\n#define mmVGT_PERFCOUNTER1_HI                                                   0xd093\n#define mmVGT_PERFCOUNTER2_HI                                                   0xd095\n#define mmVGT_PERFCOUNTER3_HI                                                   0xd097\n#define mmIA_PERFCOUNTER0_SELECT                                                0xd884\n#define mmIA_PERFCOUNTER1_SELECT                                                0xd885\n#define mmIA_PERFCOUNTER2_SELECT                                                0xd886\n#define mmIA_PERFCOUNTER3_SELECT                                                0xd887\n#define mmIA_PERFCOUNTER0_SELECT1                                               0xd888\n#define mmIA_PERFCOUNTER0_LO                                                    0xd088\n#define mmIA_PERFCOUNTER1_LO                                                    0xd08a\n#define mmIA_PERFCOUNTER2_LO                                                    0xd08c\n#define mmIA_PERFCOUNTER3_LO                                                    0xd08e\n#define mmIA_PERFCOUNTER0_HI                                                    0xd089\n#define mmIA_PERFCOUNTER1_HI                                                    0xd08b\n#define mmIA_PERFCOUNTER2_HI                                                    0xd08d\n#define mmIA_PERFCOUNTER3_HI                                                    0xd08f\n#define mmWD_PERFCOUNTER0_SELECT                                                0xd880\n#define mmWD_PERFCOUNTER1_SELECT                                                0xd881\n#define mmWD_PERFCOUNTER2_SELECT                                                0xd882\n#define mmWD_PERFCOUNTER3_SELECT                                                0xd883\n#define mmWD_PERFCOUNTER0_LO                                                    0xd080\n#define mmWD_PERFCOUNTER1_LO                                                    0xd082\n#define mmWD_PERFCOUNTER2_LO                                                    0xd084\n#define mmWD_PERFCOUNTER3_LO                                                    0xd086\n#define mmWD_PERFCOUNTER0_HI                                                    0xd081\n#define mmWD_PERFCOUNTER1_HI                                                    0xd083\n#define mmWD_PERFCOUNTER2_HI                                                    0xd085\n#define mmWD_PERFCOUNTER3_HI                                                    0xd087\n#define mmDIDT_IND_INDEX                                                        0x3280\n#define mmDIDT_IND_DATA                                                         0x3281\n#define ixDIDT_SQ_CTRL0                                                         0x0\n#define ixDIDT_SQ_CTRL1                                                         0x1\n#define ixDIDT_SQ_CTRL2                                                         0x2\n#define ixDIDT_SQ_WEIGHT0_3                                                     0x10\n#define ixDIDT_SQ_WEIGHT4_7                                                     0x11\n#define ixDIDT_SQ_WEIGHT8_11                                                    0x12\n#define ixDIDT_DB_CTRL0                                                         0x20\n#define ixDIDT_DB_CTRL1                                                         0x21\n#define ixDIDT_DB_CTRL2                                                         0x22\n#define ixDIDT_DB_WEIGHT0_3                                                     0x30\n#define ixDIDT_DB_WEIGHT4_7                                                     0x31\n#define ixDIDT_DB_WEIGHT8_11                                                    0x32\n#define ixDIDT_TD_CTRL0                                                         0x40\n#define ixDIDT_TD_CTRL1                                                         0x41\n#define ixDIDT_TD_CTRL2                                                         0x42\n#define ixDIDT_TD_WEIGHT0_3                                                     0x50\n#define ixDIDT_TD_WEIGHT4_7                                                     0x51\n#define ixDIDT_TD_WEIGHT8_11                                                    0x52\n#define ixDIDT_TCP_CTRL0                                                        0x60\n#define ixDIDT_TCP_CTRL1                                                        0x61\n#define ixDIDT_TCP_CTRL2                                                        0x62\n#define ixDIDT_TCP_WEIGHT0_3                                                    0x70\n#define ixDIDT_TCP_WEIGHT4_7                                                    0x71\n#define ixDIDT_TCP_WEIGHT8_11                                                   0x72\n\n#endif /* GFX_7_2_D_H */\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/asic_reg/gfx_7_2_enum.h",
    "content": "/*\n * Copyright (C) 2014  Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef GFX_7_2_ENUM_H\n#define GFX_7_2_ENUM_H\n\ntypedef enum SurfaceNumber {\n\tNUMBER_UNORM                                     = 0x0,\n\tNUMBER_SNORM                                     = 0x1,\n\tNUMBER_USCALED                                   = 0x2,\n\tNUMBER_SSCALED                                   = 0x3,\n\tNUMBER_UINT                                      = 0x4,\n\tNUMBER_SINT                                      = 0x5,\n\tNUMBER_SRGB                                      = 0x6,\n\tNUMBER_FLOAT                                     = 0x7,\n} SurfaceNumber;\ntypedef enum SurfaceSwap {\n\tSWAP_STD                                         = 0x0,\n\tSWAP_ALT                                         = 0x1,\n\tSWAP_STD_REV                                     = 0x2,\n\tSWAP_ALT_REV                                     = 0x3,\n} SurfaceSwap;\ntypedef enum CBMode {\n\tCB_DISABLE                                       = 0x0,\n\tCB_NORMAL                                        = 0x1,\n\tCB_ELIMINATE_FAST_CLEAR                          = 0x2,\n\tCB_RESOLVE                                       = 0x3,\n\tCB_DECOMPRESS                                    = 0x4,\n\tCB_FMASK_DECOMPRESS                              = 0x5,\n} CBMode;\ntypedef enum RoundMode {\n\tROUND_BY_HALF                                    = 0x0,\n\tROUND_TRUNCATE                                   = 0x1,\n} RoundMode;\ntypedef enum SourceFormat {\n\tEXPORT_4C_32BPC                                  = 0x0,\n\tEXPORT_4C_16BPC                                  = 0x1,\n\tEXPORT_2C_32BPC_GR                               = 0x2,\n\tEXPORT_2C_32BPC_AR                               = 0x3,\n} SourceFormat;\ntypedef enum BlendOp {\n\tBLEND_ZERO                                       = 0x0,\n\tBLEND_ONE                                        = 0x1,\n\tBLEND_SRC_COLOR                                  = 0x2,\n\tBLEND_ONE_MINUS_SRC_COLOR                        = 0x3,\n\tBLEND_SRC_ALPHA                                  = 0x4,\n\tBLEND_ONE_MINUS_SRC_ALPHA                        = 0x5,\n\tBLEND_DST_ALPHA                                  = 0x6,\n\tBLEND_ONE_MINUS_DST_ALPHA                        = 0x7,\n\tBLEND_DST_COLOR                                  = 0x8,\n\tBLEND_ONE_MINUS_DST_COLOR                        = 0x9,\n\tBLEND_SRC_ALPHA_SATURATE                         = 0xa,\n\tBLEND_BOTH_SRC_ALPHA                             = 0xb,\n\tBLEND_BOTH_INV_SRC_ALPHA                         = 0xc,\n\tBLEND_CONSTANT_COLOR                             = 0xd,\n\tBLEND_ONE_MINUS_CONSTANT_COLOR                   = 0xe,\n\tBLEND_SRC1_COLOR                                 = 0xf,\n\tBLEND_INV_SRC1_COLOR                             = 0x10,\n\tBLEND_SRC1_ALPHA                                 = 0x11,\n\tBLEND_INV_SRC1_ALPHA                             = 0x12,\n\tBLEND_CONSTANT_ALPHA                             = 0x13,\n\tBLEND_ONE_MINUS_CONSTANT_ALPHA                   = 0x14,\n} BlendOp;\ntypedef enum CombFunc {\n\tCOMB_DST_PLUS_SRC                                = 0x0,\n\tCOMB_SRC_MINUS_DST                               = 0x1,\n\tCOMB_MIN_DST_SRC                                 = 0x2,\n\tCOMB_MAX_DST_SRC                                 = 0x3,\n\tCOMB_DST_MINUS_SRC                               = 0x4,\n} CombFunc;\ntypedef enum BlendOpt {\n\tFORCE_OPT_AUTO                                   = 0x0,\n\tFORCE_OPT_DISABLE                                = 0x1,\n\tFORCE_OPT_ENABLE_IF_SRC_A_0                      = 0x2,\n\tFORCE_OPT_ENABLE_IF_SRC_RGB_0                    = 0x3,\n\tFORCE_OPT_ENABLE_IF_SRC_ARGB_0                   = 0x4,\n\tFORCE_OPT_ENABLE_IF_SRC_A_1                      = 0x5,\n\tFORCE_OPT_ENABLE_IF_SRC_RGB_1                    = 0x6,\n\tFORCE_OPT_ENABLE_IF_SRC_ARGB_1                   = 0x7,\n} BlendOpt;\ntypedef enum CmaskCode {\n\tCMASK_CLR00_F0                                   = 0x0,\n\tCMASK_CLR00_F1                                   = 0x1,\n\tCMASK_CLR00_F2                                   = 0x2,\n\tCMASK_CLR00_FX                                   = 0x3,\n\tCMASK_CLR01_F0                                   = 0x4,\n\tCMASK_CLR01_F1                                   = 0x5,\n\tCMASK_CLR01_F2                                   = 0x6,\n\tCMASK_CLR01_FX                                   = 0x7,\n\tCMASK_CLR10_F0                                   = 0x8,\n\tCMASK_CLR10_F1                                   = 0x9,\n\tCMASK_CLR10_F2                                   = 0xa,\n\tCMASK_CLR10_FX                                   = 0xb,\n\tCMASK_CLR11_F0                                   = 0xc,\n\tCMASK_CLR11_F1                                   = 0xd,\n\tCMASK_CLR11_F2                                   = 0xe,\n\tCMASK_CLR11_FX                                   = 0xf,\n} CmaskCode;\ntypedef enum CBPerfSel {\n\tCB_PERF_SEL_NONE                                 = 0x0,\n\tCB_PERF_SEL_BUSY                                 = 0x1,\n\tCB_PERF_SEL_CORE_SCLK_VLD                        = 0x2,\n\tCB_PERF_SEL_REG_SCLK0_VLD                        = 0x3,\n\tCB_PERF_SEL_REG_SCLK1_VLD                        = 0x4,\n\tCB_PERF_SEL_DRAWN_QUAD                           = 0x5,\n\tCB_PERF_SEL_DRAWN_PIXEL                          = 0x6,\n\tCB_PERF_SEL_DRAWN_QUAD_FRAGMENT                  = 0x7,\n\tCB_PERF_SEL_DRAWN_TILE                           = 0x8,\n\tCB_PERF_SEL_DB_CB_TILE_VALID_READY               = 0x9,\n\tCB_PERF_SEL_DB_CB_TILE_VALID_READYB              = 0xa,\n\tCB_PERF_SEL_DB_CB_TILE_VALIDB_READY              = 0xb,\n\tCB_PERF_SEL_DB_CB_TILE_VALIDB_READYB             = 0xc,\n\tCB_PERF_SEL_CM_FC_TILE_VALID_READY               = 0xd,\n\tCB_PERF_SEL_CM_FC_TILE_VALID_READYB              = 0xe,\n\tCB_PERF_SEL_CM_FC_TILE_VALIDB_READY              = 0xf,\n\tCB_PERF_SEL_CM_FC_TILE_VALIDB_READYB             = 0x10,\n\tCB_PERF_SEL_MERGE_TILE_ONLY_VALID_READY          = 0x11,\n\tCB_PERF_SEL_MERGE_TILE_ONLY_VALID_READYB         = 0x12,\n\tCB_PERF_SEL_DB_CB_LQUAD_VALID_READY              = 0x13,\n\tCB_PERF_SEL_DB_CB_LQUAD_VALID_READYB             = 0x14,\n\tCB_PERF_SEL_DB_CB_LQUAD_VALIDB_READY             = 0x15,\n\tCB_PERF_SEL_DB_CB_LQUAD_VALIDB_READYB            = 0x16,\n\tCB_PERF_SEL_LQUAD_NO_TILE                        = 0x17,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_32_R          = 0x18,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_32_AR         = 0x19,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_32_GR         = 0x1a,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_32_ABGR       = 0x1b,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_FP16_ABGR     = 0x1c,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_SIGNED16_ABGR = 0x1d,\n\tCB_PERF_SEL_LQUAD_FORMAT_IS_EXPORT_UNSIGNED16_ABGR= 0x1e,\n\tCB_PERF_SEL_QUAD_KILLED_BY_EXTRA_PIXEL_EXPORT    = 0x1f,\n\tCB_PERF_SEL_QUAD_KILLED_BY_COLOR_INVALID         = 0x20,\n\tCB_PERF_SEL_QUAD_KILLED_BY_NULL_TARGET_SHADER_MASK= 0x21,\n\tCB_PERF_SEL_QUAD_KILLED_BY_NULL_SAMPLE_MASK      = 0x22,\n\tCB_PERF_SEL_QUAD_KILLED_BY_DISCARD_PIXEL         = 0x23,\n\tCB_PERF_SEL_FC_CLEAR_QUAD_VALID_READY            = 0x24,\n\tCB_PERF_SEL_FC_CLEAR_QUAD_VALID_READYB           = 0x25,\n\tCB_PERF_SEL_FC_CLEAR_QUAD_VALIDB_READY           = 0x26,\n\tCB_PERF_SEL_FC_CLEAR_QUAD_VALIDB_READYB          = 0x27,\n\tCB_PERF_SEL_FOP_IN_VALID_READY                   = 0x28,\n\tCB_PERF_SEL_FOP_IN_VALID_READYB                  = 0x29,\n\tCB_PERF_SEL_FOP_IN_VALIDB_READY                  = 0x2a,\n\tCB_PERF_SEL_FOP_IN_VALIDB_READYB                 = 0x2b,\n\tCB_PERF_SEL_FC_CC_QUADFRAG_VALID_READY           = 0x2c,\n\tCB_PERF_SEL_FC_CC_QUADFRAG_VALID_READYB          = 0x2d,\n\tCB_PERF_SEL_FC_CC_QUADFRAG_VALIDB_READY          = 0x2e,\n\tCB_PERF_SEL_FC_CC_QUADFRAG_VALIDB_READYB         = 0x2f,\n\tCB_PERF_SEL_CC_IB_SR_FRAG_VALID_READY            = 0x30,\n\tCB_PERF_SEL_CC_IB_SR_FRAG_VALID_READYB           = 0x31,\n\tCB_PERF_SEL_CC_IB_SR_FRAG_VALIDB_READY           = 0x32,\n\tCB_PERF_SEL_CC_IB_SR_FRAG_VALIDB_READYB          = 0x33,\n\tCB_PERF_SEL_CC_IB_TB_FRAG_VALID_READY            = 0x34,\n\tCB_PERF_SEL_CC_IB_TB_FRAG_VALID_READYB           = 0x35,\n\tCB_PERF_SEL_CC_IB_TB_FRAG_VALIDB_READY           = 0x36,\n\tCB_PERF_SEL_CC_IB_TB_FRAG_VALIDB_READYB          = 0x37,\n\tCB_PERF_SEL_CC_RB_BC_EVENFRAG_VALID_READY        = 0x38,\n\tCB_PERF_SEL_CC_RB_BC_EVENFRAG_VALID_READYB       = 0x39,\n\tCB_PERF_SEL_CC_RB_BC_EVENFRAG_VALIDB_READY       = 0x3a,\n\tCB_PERF_SEL_CC_RB_BC_EVENFRAG_VALIDB_READYB      = 0x3b,\n\tCB_PERF_SEL_CC_RB_BC_ODDFRAG_VALID_READY         = 0x3c,\n\tCB_PERF_SEL_CC_RB_BC_ODDFRAG_VALID_READYB        = 0x3d,\n\tCB_PERF_SEL_CC_RB_BC_ODDFRAG_VALIDB_READY        = 0x3e,\n\tCB_PERF_SEL_CC_RB_BC_ODDFRAG_VALIDB_READYB       = 0x3f,\n\tCB_PERF_SEL_CC_BC_CS_FRAG_VALID                  = 0x40,\n\tCB_PERF_SEL_CM_CACHE_HIT                         = 0x41,\n\tCB_PERF_SEL_CM_CACHE_TAG_MISS                    = 0x42,\n\tCB_PERF_SEL_CM_CACHE_SECTOR_MISS                 = 0x43,\n\tCB_PERF_SEL_CM_CACHE_REEVICTION_STALL            = 0x44,\n\tCB_PERF_SEL_CM_CACHE_EVICT_NONZERO_INFLIGHT_STALL= 0x45,\n\tCB_PERF_SEL_CM_CACHE_REPLACE_PENDING_EVICT_STALL = 0x46,\n\tCB_PERF_SEL_CM_CACHE_INFLIGHT_COUNTER_MAXIMUM_STALL= 0x47,\n\tCB_PERF_SEL_CM_CACHE_READ_OUTPUT_STALL           = 0x48,\n\tCB_PERF_SEL_CM_CACHE_WRITE_OUTPUT_STALL          = 0x49,\n\tCB_PERF_SEL_CM_CACHE_ACK_OUTPUT_STALL            = 0x4a,\n\tCB_PERF_SEL_CM_CACHE_STALL                       = 0x4b,\n\tCB_PERF_SEL_CM_CACHE_FLUSH                       = 0x4c,\n\tCB_PERF_SEL_CM_CACHE_TAGS_FLUSHED                = 0x4d,\n\tCB_PERF_SEL_CM_CACHE_SECTORS_FLUSHED             = 0x4e,\n\tCB_PERF_SEL_CM_CACHE_DIRTY_SECTORS_FLUSHED       = 0x4f,\n\tCB_PERF_SEL_FC_CACHE_HIT                         = 0x50,\n\tCB_PERF_SEL_FC_CACHE_TAG_MISS                    = 0x51,\n\tCB_PERF_SEL_FC_CACHE_SECTOR_MISS                 = 0x52,\n\tCB_PERF_SEL_FC_CACHE_REEVICTION_STALL            = 0x53,\n\tCB_PERF_SEL_FC_CACHE_EVICT_NONZERO_INFLIGHT_STALL= 0x54,\n\tCB_PERF_SEL_FC_CACHE_REPLACE_PENDING_EVICT_STALL = 0x55,\n\tCB_PERF_SEL_FC_CACHE_INFLIGHT_COUNTER_MAXIMUM_STALL= 0x56,\n\tCB_PERF_SEL_FC_CACHE_READ_OUTPUT_STALL           = 0x57,\n\tCB_PERF_SEL_FC_CACHE_WRITE_OUTPUT_STALL          = 0x58,\n\tCB_PERF_SEL_FC_CACHE_ACK_OUTPUT_STALL            = 0x59,\n\tCB_PERF_SEL_FC_CACHE_STALL                       = 0x5a,\n\tCB_PERF_SEL_FC_CACHE_FLUSH                       = 0x5b,\n\tCB_PERF_SEL_FC_CACHE_TAGS_FLUSHED                = 0x5c,\n\tCB_PERF_SEL_FC_CACHE_SECTORS_FLUSHED             = 0x5d,\n\tCB_PERF_SEL_FC_CACHE_DIRTY_SECTORS_FLUSHED       = 0x5e,\n\tCB_PERF_SEL_CC_CACHE_HIT                         = 0x5f,\n\tCB_PERF_SEL_CC_CACHE_TAG_MISS                    = 0x60,\n\tCB_PERF_SEL_CC_CACHE_SECTOR_MISS                 = 0x61,\n\tCB_PERF_SEL_CC_CACHE_REEVICTION_STALL            = 0x62,\n\tCB_PERF_SEL_CC_CACHE_EVICT_NONZERO_INFLIGHT_STALL= 0x63,\n\tCB_PERF_SEL_CC_CACHE_REPLACE_PENDING_EVICT_STALL = 0x64,\n\tCB_PERF_SEL_CC_CACHE_INFLIGHT_COUNTER_MAXIMUM_STALL= 0x65,\n\tCB_PERF_SEL_CC_CACHE_READ_OUTPUT_STALL           = 0x66,\n\tCB_PERF_SEL_CC_CACHE_WRITE_OUTPUT_STALL          = 0x67,\n\tCB_PERF_SEL_CC_CACHE_ACK_OUTPUT_STALL            = 0x68,\n\tCB_PERF_SEL_CC_CACHE_STALL                       = 0x69,\n\tCB_PERF_SEL_CC_CACHE_FLUSH                       = 0x6a,\n\tCB_PERF_SEL_CC_CACHE_TAGS_FLUSHED                = 0x6b,\n\tCB_PERF_SEL_CC_CACHE_SECTORS_FLUSHED             = 0x6c,\n\tCB_PERF_SEL_CC_CACHE_DIRTY_SECTORS_FLUSHED       = 0x6d,\n\tCB_PERF_SEL_CC_CACHE_WA_TO_RMW_CONVERSION        = 0x6e,\n\tCB_PERF_SEL_CB_TAP_WRREQ_VALID_READY             = 0x6f,\n\tCB_PERF_SEL_CB_TAP_WRREQ_VALID_READYB            = 0x70,\n\tCB_PERF_SEL_CB_TAP_WRREQ_VALIDB_READY            = 0x71,\n\tCB_PERF_SEL_CB_TAP_WRREQ_VALIDB_READYB           = 0x72,\n\tCB_PERF_SEL_CM_MC_WRITE_REQUEST                  = 0x73,\n\tCB_PERF_SEL_FC_MC_WRITE_REQUEST                  = 0x74,\n\tCB_PERF_SEL_CC_MC_WRITE_REQUEST                  = 0x75,\n\tCB_PERF_SEL_CM_MC_WRITE_REQUESTS_IN_FLIGHT       = 0x76,\n\tCB_PERF_SEL_FC_MC_WRITE_REQUESTS_IN_FLIGHT       = 0x77,\n\tCB_PERF_SEL_CC_MC_WRITE_REQUESTS_IN_FLIGHT       = 0x78,\n\tCB_PERF_SEL_CB_TAP_RDREQ_VALID_READY             = 0x79,\n\tCB_PERF_SEL_CB_TAP_RDREQ_VALID_READYB            = 0x7a,\n\tCB_PERF_SEL_CB_TAP_RDREQ_VALIDB_READY            = 0x7b,\n\tCB_PERF_SEL_CB_TAP_RDREQ_VALIDB_READYB           = 0x7c,\n\tCB_PERF_SEL_CM_MC_READ_REQUEST                   = 0x7d,\n\tCB_PERF_SEL_FC_MC_READ_REQUEST                   = 0x7e,\n\tCB_PERF_SEL_CC_MC_READ_REQUEST                   = 0x7f,\n\tCB_PERF_SEL_CM_MC_READ_REQUESTS_IN_FLIGHT        = 0x80,\n\tCB_PERF_SEL_FC_MC_READ_REQUESTS_IN_FLIGHT        = 0x81,\n\tCB_PERF_SEL_CC_MC_READ_REQUESTS_IN_FLIGHT        = 0x82,\n\tCB_PERF_SEL_CM_TQ_FULL                           = 0x83,\n\tCB_PERF_SEL_CM_TQ_FIFO_TILE_RESIDENCY_STALL      = 0x84,\n\tCB_PERF_SEL_FC_QUAD_RDLAT_FIFO_FULL              = 0x85,\n\tCB_PERF_SEL_FC_TILE_RDLAT_FIFO_FULL              = 0x86,\n\tCB_PERF_SEL_FC_RDLAT_FIFO_QUAD_RESIDENCY_STALL   = 0x87,\n\tCB_PERF_SEL_FOP_FMASK_RAW_STALL                  = 0x88,\n\tCB_PERF_SEL_FOP_FMASK_BYPASS_STALL               = 0x89,\n\tCB_PERF_SEL_CC_SF_FULL                           = 0x8a,\n\tCB_PERF_SEL_CC_RB_FULL                           = 0x8b,\n\tCB_PERF_SEL_CC_EVENFIFO_QUAD_RESIDENCY_STALL     = 0x8c,\n\tCB_PERF_SEL_CC_ODDFIFO_QUAD_RESIDENCY_STALL      = 0x8d,\n\tCB_PERF_SEL_BLENDER_RAW_HAZARD_STALL             = 0x8e,\n\tCB_PERF_SEL_EVENT                                = 0x8f,\n\tCB_PERF_SEL_EVENT_CACHE_FLUSH_TS                 = 0x90,\n\tCB_PERF_SEL_EVENT_CONTEXT_DONE                   = 0x91,\n\tCB_PERF_SEL_EVENT_CACHE_FLUSH                    = 0x92,\n\tCB_PERF_SEL_EVENT_CACHE_FLUSH_AND_INV_TS_EVENT   = 0x93,\n\tCB_PERF_SEL_EVENT_CACHE_FLUSH_AND_INV_EVENT      = 0x94,\n\tCB_PERF_SEL_EVENT_FLUSH_AND_INV_CB_DATA_TS       = 0x95,\n\tCB_PERF_SEL_EVENT_FLUSH_AND_INV_CB_META          = 0x96,\n\tCB_PERF_SEL_CC_SURFACE_SYNC                      = 0x97,\n\tCB_PERF_SEL_CMASK_READ_DATA_0xC                  = 0x98,\n\tCB_PERF_SEL_CMASK_READ_DATA_0xD                  = 0x99,\n\tCB_PERF_SEL_CMASK_READ_DATA_0xE                  = 0x9a,\n\tCB_PERF_SEL_CMASK_READ_DATA_0xF                  = 0x9b,\n\tCB_PERF_SEL_CMASK_WRITE_DATA_0xC                 = 0x9c,\n\tCB_PERF_SEL_CMASK_WRITE_DATA_0xD                 = 0x9d,\n\tCB_PERF_SEL_CMASK_WRITE_DATA_0xE                 = 0x9e,\n\tCB_PERF_SEL_CMASK_WRITE_DATA_0xF                 = 0x9f,\n\tCB_PERF_SEL_TWO_PROBE_QUAD_FRAGMENT              = 0xa0,\n\tCB_PERF_SEL_EXPORT_32_ABGR_QUAD_FRAGMENT         = 0xa1,\n\tCB_PERF_SEL_DUAL_SOURCE_COLOR_QUAD_FRAGMENT      = 0xa2,\n\tCB_PERF_SEL_QUAD_HAS_1_FRAGMENT_BEFORE_UPDATE    = 0xa3,\n\tCB_PERF_SEL_QUAD_HAS_2_FRAGMENTS_BEFORE_UPDATE   = 0xa4,\n\tCB_PERF_SEL_QUAD_HAS_3_FRAGMENTS_BEFORE_UPDATE   = 0xa5,\n\tCB_PERF_SEL_QUAD_HAS_4_FRAGMENTS_BEFORE_UPDATE   = 0xa6,\n\tCB_PERF_SEL_QUAD_HAS_5_FRAGMENTS_BEFORE_UPDATE   = 0xa7,\n\tCB_PERF_SEL_QUAD_HAS_6_FRAGMENTS_BEFORE_UPDATE   = 0xa8,\n\tCB_PERF_SEL_QUAD_HAS_7_FRAGMENTS_BEFORE_UPDATE   = 0xa9,\n\tCB_PERF_SEL_QUAD_HAS_8_FRAGMENTS_BEFORE_UPDATE   = 0xaa,\n\tCB_PERF_SEL_QUAD_HAS_1_FRAGMENT_AFTER_UPDATE     = 0xab,\n\tCB_PERF_SEL_QUAD_HAS_2_FRAGMENTS_AFTER_UPDATE    = 0xac,\n\tCB_PERF_SEL_QUAD_HAS_3_FRAGMENTS_AFTER_UPDATE    = 0xad,\n\tCB_PERF_SEL_QUAD_HAS_4_FRAGMENTS_AFTER_UPDATE    = 0xae,\n\tCB_PERF_SEL_QUAD_HAS_5_FRAGMENTS_AFTER_UPDATE    = 0xaf,\n\tCB_PERF_SEL_QUAD_HAS_6_FRAGMENTS_AFTER_UPDATE    = 0xb0,\n\tCB_PERF_SEL_QUAD_HAS_7_FRAGMENTS_AFTER_UPDATE    = 0xb1,\n\tCB_PERF_SEL_QUAD_HAS_8_FRAGMENTS_AFTER_UPDATE    = 0xb2,\n\tCB_PERF_SEL_QUAD_ADDED_1_FRAGMENT                = 0xb3,\n\tCB_PERF_SEL_QUAD_ADDED_2_FRAGMENTS               = 0xb4,\n\tCB_PERF_SEL_QUAD_ADDED_3_FRAGMENTS               = 0xb5,\n\tCB_PERF_SEL_QUAD_ADDED_4_FRAGMENTS               = 0xb6,\n\tCB_PERF_SEL_QUAD_ADDED_5_FRAGMENTS               = 0xb7,\n\tCB_PERF_SEL_QUAD_ADDED_6_FRAGMENTS               = 0xb8,\n\tCB_PERF_SEL_QUAD_ADDED_7_FRAGMENTS               = 0xb9,\n\tCB_PERF_SEL_QUAD_REMOVED_1_FRAGMENT              = 0xba,\n\tCB_PERF_SEL_QUAD_REMOVED_2_FRAGMENTS             = 0xbb,\n\tCB_PERF_SEL_QUAD_REMOVED_3_FRAGMENTS             = 0xbc,\n\tCB_PERF_SEL_QUAD_REMOVED_4_FRAGMENTS             = 0xbd,\n\tCB_PERF_SEL_QUAD_REMOVED_5_FRAGMENTS             = 0xbe,\n\tCB_PERF_SEL_QUAD_REMOVED_6_FRAGMENTS             = 0xbf,\n\tCB_PERF_SEL_QUAD_REMOVED_7_FRAGMENTS             = 0xc0,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_0                = 0xc1,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_1                = 0xc2,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_2                = 0xc3,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_3                = 0xc4,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_4                = 0xc5,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_5                = 0xc6,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_6                = 0xc7,\n\tCB_PERF_SEL_QUAD_READS_FRAGMENT_7                = 0xc8,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_0               = 0xc9,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_1               = 0xca,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_2               = 0xcb,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_3               = 0xcc,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_4               = 0xcd,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_5               = 0xce,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_6               = 0xcf,\n\tCB_PERF_SEL_QUAD_WRITES_FRAGMENT_7               = 0xd0,\n\tCB_PERF_SEL_QUAD_BLEND_OPT_DONT_READ_DST         = 0xd1,\n\tCB_PERF_SEL_QUAD_BLEND_OPT_BLEND_BYPASS          = 0xd2,\n\tCB_PERF_SEL_QUAD_BLEND_OPT_DISCARD_PIXELS        = 0xd3,\n\tCB_PERF_SEL_QUAD_DST_READ_COULD_HAVE_BEEN_OPTIMIZED= 0xd4,\n\tCB_PERF_SEL_QUAD_BLENDING_COULD_HAVE_BEEN_BYPASSED= 0xd5,\n\tCB_PERF_SEL_QUAD_COULD_HAVE_BEEN_DISCARDED       = 0xd6,\n\tCB_PERF_SEL_BLEND_OPT_PIXELS_RESULT_EQ_DEST      = 0xd7,\n\tCB_PERF_SEL_DRAWN_BUSY                           = 0xd8,\n\tCB_PERF_SEL_TILE_TO_CMR_REGION_BUSY              = 0xd9,\n\tCB_PERF_SEL_CMR_TO_FCR_REGION_BUSY               = 0xda,\n\tCB_PERF_SEL_FCR_TO_CCR_REGION_BUSY               = 0xdb,\n\tCB_PERF_SEL_CCR_TO_CCW_REGION_BUSY               = 0xdc,\n\tCB_PERF_SEL_FC_PF_SLOW_MODE_QUAD_EMPTY_HALF_DROPPED= 0xdd,\n\tCB_PERF_SEL_FC_SEQUENCER_CLEAR                   = 0xde,\n\tCB_PERF_SEL_FC_SEQUENCER_ELIMINATE_FAST_CLEAR    = 0xdf,\n\tCB_PERF_SEL_FC_SEQUENCER_FMASK_DECOMPRESS        = 0xe0,\n\tCB_PERF_SEL_FC_SEQUENCER_FMASK_COMPRESSION_DISABLE= 0xe1,\n} CBPerfSel;\ntypedef enum CBPerfOpFilterSel {\n\tCB_PERF_OP_FILTER_SEL_WRITE_ONLY                 = 0x0,\n\tCB_PERF_OP_FILTER_SEL_NEEDS_DESTINATION          = 0x1,\n\tCB_PERF_OP_FILTER_SEL_RESOLVE                    = 0x2,\n\tCB_PERF_OP_FILTER_SEL_DECOMPRESS                 = 0x3,\n\tCB_PERF_OP_FILTER_SEL_FMASK_DECOMPRESS           = 0x4,\n\tCB_PERF_OP_FILTER_SEL_ELIMINATE_FAST_CLEAR       = 0x5,\n} CBPerfOpFilterSel;\ntypedef enum CBPerfClearFilterSel {\n\tCB_PERF_CLEAR_FILTER_SEL_NONCLEAR                = 0x0,\n\tCB_PERF_CLEAR_FILTER_SEL_CLEAR                   = 0x1,\n} CBPerfClearFilterSel;\ntypedef enum CP_RING_ID {\n\tRINGID0                                          = 0x0,\n\tRINGID1                                          = 0x1,\n\tRINGID2                                          = 0x2,\n\tRINGID3                                          = 0x3,\n} CP_RING_ID;\ntypedef enum CP_PIPE_ID {\n\tPIPE_ID0                                         = 0x0,\n\tPIPE_ID1                                         = 0x1,\n\tPIPE_ID2                                         = 0x2,\n\tPIPE_ID3                                         = 0x3,\n} CP_PIPE_ID;\ntypedef enum CP_ME_ID {\n\tME_ID0                                           = 0x0,\n\tME_ID1                                           = 0x1,\n\tME_ID2                                           = 0x2,\n\tME_ID3                                           = 0x3,\n} CP_ME_ID;\ntypedef enum SPM_PERFMON_STATE {\n\tSTRM_PERFMON_STATE_DISABLE_AND_RESET             = 0x0,\n\tSTRM_PERFMON_STATE_START_COUNTING                = 0x1,\n\tSTRM_PERFMON_STATE_STOP_COUNTING                 = 0x2,\n\tSTRM_PERFMON_STATE_RESERVED_3                    = 0x3,\n\tSTRM_PERFMON_STATE_DISABLE_AND_RESET_PHANTOM     = 0x4,\n\tSTRM_PERFMON_STATE_COUNT_AND_DUMP_PHANTOM        = 0x5,\n} SPM_PERFMON_STATE;\ntypedef enum CP_PERFMON_STATE {\n\tCP_PERFMON_STATE_DISABLE_AND_RESET               = 0x0,\n\tCP_PERFMON_STATE_START_COUNTING                  = 0x1,\n\tCP_PERFMON_STATE_STOP_COUNTING                   = 0x2,\n\tCP_PERFMON_STATE_RESERVED_3                      = 0x3,\n\tCP_PERFMON_STATE_DISABLE_AND_RESET_PHANTOM       = 0x4,\n\tCP_PERFMON_STATE_COUNT_AND_DUMP_PHANTOM          = 0x5,\n} CP_PERFMON_STATE;\ntypedef enum CP_PERFMON_ENABLE_MODE {\n\tCP_PERFMON_ENABLE_MODE_ALWAYS_COUNT              = 0x0,\n\tCP_PERFMON_ENABLE_MODE_RESERVED_1                = 0x1,\n\tCP_PERFMON_ENABLE_MODE_COUNT_CONTEXT_TRUE        = 0x2,\n\tCP_PERFMON_ENABLE_MODE_COUNT_CONTEXT_FALSE       = 0x3,\n} CP_PERFMON_ENABLE_MODE;\ntypedef enum CPG_PERFCOUNT_SEL {\n\tCPG_PERF_SEL_ALWAYS_COUNT                        = 0x0,\n\tCPG_PERF_SEL_RBIU_FIFO_FULL                      = 0x1,\n\tCPG_PERF_SEL_CSF_RTS_BUT_MIU_NOT_RTR             = 0x2,\n\tCPG_PERF_SEL_CSF_ST_BASE_SIZE_FIFO_FULL          = 0x3,\n\tCPG_PERF_SEL_CP_GRBM_DWORDS_SENT                 = 0x4,\n\tCPG_PERF_SEL_ME_PARSER_BUSY                      = 0x5,\n\tCPG_PERF_SEL_COUNT_TYPE0_PACKETS                 = 0x6,\n\tCPG_PERF_SEL_COUNT_TYPE3_PACKETS                 = 0x7,\n\tCPG_PERF_SEL_CSF_FETCHING_CMD_BUFFERS            = 0x8,\n\tCPG_PERF_SEL_CP_GRBM_OUT_OF_CREDITS              = 0x9,\n\tCPG_PERF_SEL_CP_PFP_GRBM_OUT_OF_CREDITS          = 0xa,\n\tCPG_PERF_SEL_CP_GDS_GRBM_OUT_OF_CREDITS          = 0xb,\n\tCPG_PERF_SEL_RCIU_STALLED_ON_ME_READ             = 0xc,\n\tCPG_PERF_SEL_RCIU_STALLED_ON_DMA_READ            = 0xd,\n\tCPG_PERF_SEL_SSU_STALLED_ON_ACTIVE_CNTX          = 0xe,\n\tCPG_PERF_SEL_SSU_STALLED_ON_CLEAN_SIGNALS        = 0xf,\n\tCPG_PERF_SEL_QU_STALLED_ON_EOP_DONE_PULSE        = 0x10,\n\tCPG_PERF_SEL_QU_STALLED_ON_EOP_DONE_WR_CONFIRM   = 0x11,\n\tCPG_PERF_SEL_PFP_STALLED_ON_CSF_READY            = 0x12,\n\tCPG_PERF_SEL_PFP_STALLED_ON_MEQ_READY            = 0x13,\n\tCPG_PERF_SEL_PFP_STALLED_ON_RCIU_READY           = 0x14,\n\tCPG_PERF_SEL_PFP_STALLED_FOR_DATA_FROM_ROQ       = 0x15,\n\tCPG_PERF_SEL_ME_STALLED_FOR_DATA_FROM_PFP        = 0x16,\n\tCPG_PERF_SEL_ME_STALLED_FOR_DATA_FROM_STQ        = 0x17,\n\tCPG_PERF_SEL_ME_STALLED_ON_NO_AVAIL_GFX_CNTX     = 0x18,\n\tCPG_PERF_SEL_ME_STALLED_WRITING_TO_RCIU          = 0x19,\n\tCPG_PERF_SEL_ME_STALLED_WRITING_CONSTANTS        = 0x1a,\n\tCPG_PERF_SEL_ME_STALLED_ON_PARTIAL_FLUSH         = 0x1b,\n\tCPG_PERF_SEL_ME_WAIT_ON_CE_COUNTER               = 0x1c,\n\tCPG_PERF_SEL_ME_WAIT_ON_AVAIL_BUFFER             = 0x1d,\n\tCPG_PERF_SEL_SEMAPHORE_BUSY_POLLING_FOR_PASS     = 0x1e,\n\tCPG_PERF_SEL_LOAD_STALLED_ON_SET_COHERENCY       = 0x1f,\n\tCPG_PERF_SEL_DYNAMIC_CLK_VALID                   = 0x20,\n\tCPG_PERF_SEL_REGISTER_CLK_VALID                  = 0x21,\n\tCPG_PERF_SEL_MIU_WRITE_REQUEST_SENT              = 0x22,\n\tCPG_PERF_SEL_MIU_READ_REQUEST_SENT               = 0x23,\n\tCPG_PERF_SEL_CE_STALL_RAM_DUMP                   = 0x24,\n\tCPG_PERF_SEL_CE_STALL_RAM_WRITE                  = 0x25,\n\tCPG_PERF_SEL_CE_STALL_ON_INC_FIFO                = 0x26,\n\tCPG_PERF_SEL_CE_STALL_ON_WR_RAM_FIFO             = 0x27,\n\tCPG_PERF_SEL_CE_STALL_ON_DATA_FROM_MIU           = 0x28,\n\tCPG_PERF_SEL_CE_STALL_ON_DATA_FROM_ROQ           = 0x29,\n\tCPG_PERF_SEL_CE_STALL_ON_CE_BUFFER_FLAG          = 0x2a,\n\tCPG_PERF_SEL_CE_STALL_ON_DE_COUNTER              = 0x2b,\n\tCPG_PERF_SEL_TCIU_STALL_WAIT_ON_FREE             = 0x2c,\n\tCPG_PERF_SEL_TCIU_STALL_WAIT_ON_TAGS             = 0x2d,\n} CPG_PERFCOUNT_SEL;\ntypedef enum CPF_PERFCOUNT_SEL {\n\tCPF_PERF_SEL_ALWAYS_COUNT                        = 0x0,\n\tCPF_PERF_SEL_MIU_STALLED_WAITING_RDREQ_FREE      = 0x1,\n\tCPF_PERF_SEL_TCIU_STALLED_WAITING_ON_FREE        = 0x2,\n\tCPF_PERF_SEL_TCIU_STALLED_WAITING_ON_TAGS        = 0x3,\n\tCPF_PERF_SEL_CSF_BUSY_FOR_FETCHING_RING          = 0x4,\n\tCPF_PERF_SEL_CSF_BUSY_FOR_FETCHING_IB1           = 0x5,\n\tCPF_PERF_SEL_CSF_BUSY_FOR_FETCHING_IB2           = 0x6,\n\tCPF_PERF_SEL_CSF_BUSY_FOR_FECTHINC_STATE         = 0x7,\n\tCPF_PERF_SEL_MIU_BUSY_FOR_OUTSTANDING_TAGS       = 0x8,\n\tCPF_PERF_SEL_CSF_RTS_MIU_NOT_RTR                 = 0x9,\n\tCPF_PERF_SEL_CSF_STATE_FIFO_NOT_RTR              = 0xa,\n\tCPF_PERF_SEL_CSF_FETCHING_CMD_BUFFERS            = 0xb,\n\tCPF_PERF_SEL_GRBM_DWORDS_SENT                    = 0xc,\n\tCPF_PERF_SEL_DYNAMIC_CLOCK_VALID                 = 0xd,\n\tCPF_PERF_SEL_REGISTER_CLOCK_VALID                = 0xe,\n\tCPF_PERF_SEL_MIU_WRITE_REQUEST_SEND              = 0xf,\n\tCPF_PERF_SEL_MIU_READ_REQUEST_SEND               = 0x10,\n} CPF_PERFCOUNT_SEL;\ntypedef enum CPC_PERFCOUNT_SEL {\n\tCPC_PERF_SEL_ALWAYS_COUNT                        = 0x0,\n\tCPC_PERF_SEL_RCIU_STALL_WAIT_ON_FREE             = 0x1,\n\tCPC_PERF_SEL_RCIU_STALL_PRIV_VIOLATION           = 0x2,\n\tCPC_PERF_SEL_MIU_STALL_ON_RDREQ_FREE             = 0x3,\n\tCPC_PERF_SEL_MIU_STALL_ON_WRREQ_FREE             = 0x4,\n\tCPC_PERF_SEL_TCIU_STALL_WAIT_ON_FREE             = 0x5,\n\tCPC_PERF_SEL_ME1_STALL_WAIT_ON_RCIU_READY        = 0x6,\n\tCPC_PERF_SEL_ME1_STALL_WAIT_ON_RCIU_READY_PERF   = 0x7,\n\tCPC_PERF_SEL_ME1_STALL_WAIT_ON_RCIU_READ         = 0x8,\n\tCPC_PERF_SEL_ME1_STALL_WAIT_ON_MIU_READ          = 0x9,\n\tCPC_PERF_SEL_ME1_STALL_WAIT_ON_MIU_WRITE         = 0xa,\n\tCPC_PERF_SEL_ME1_STALL_ON_DATA_FROM_ROQ          = 0xb,\n\tCPC_PERF_SEL_ME1_STALL_ON_DATA_FROM_ROQ_PERF     = 0xc,\n\tCPC_PERF_SEL_ME1_BUSY_FOR_PACKET_DECODE          = 0xd,\n\tCPC_PERF_SEL_ME2_STALL_WAIT_ON_RCIU_READY        = 0xe,\n\tCPC_PERF_SEL_ME2_STALL_WAIT_ON_RCIU_READY_PERF   = 0xf,\n\tCPC_PERF_SEL_ME2_STALL_WAIT_ON_RCIU_READ         = 0x10,\n\tCPC_PERF_SEL_ME2_STALL_WAIT_ON_MIU_READ          = 0x11,\n\tCPC_PERF_SEL_ME2_STALL_WAIT_ON_MIU_WRITE         = 0x12,\n\tCPC_PERF_SEL_ME2_STALL_ON_DATA_FROM_ROQ          = 0x13,\n\tCPC_PERF_SEL_ME2_STALL_ON_DATA_FROM_ROQ_PERF     = 0x14,\n\tCPC_PERF_SEL_ME2_BUSY_FOR_PACKET_DECODE          = 0x15,\n} CPC_PERFCOUNT_SEL;\ntypedef enum CP_ALPHA_TAG_RAM_SEL {\n\tCPG_TAG_RAM                                      = 0x0,\n\tCPC_TAG_RAM                                      = 0x1,\n\tCPF_TAG_RAM                                      = 0x2,\n\tRSV_TAG_RAM                                      = 0x3,\n} CP_ALPHA_TAG_RAM_SEL;\n#define SEM_ECC_ERROR                             0x0\n#define SEM_RESERVED                              0x1\n#define SEM_FAILED                                0x2\n#define SEM_PASSED                                0x3\n#define IQ_QUEUE_SLEEP                            0x0\n#define IQ_OFFLOAD_RETRY                          0x1\n#define IQ_SCH_WAVE_MSG                           0x2\n#define IQ_SEM_REARM                              0x3\n#define IQ_DEQUEUE_RETRY                          0x4\n#define IQ_INTR_TYPE_PQ                           0x0\n#define IQ_INTR_TYPE_IB                           0x1\n#define IQ_INTR_TYPE_MQD                          0x2\n#define VMID_SZ                                   0x4\n#define CONFIG_SPACE_START                        0x2000\n#define CONFIG_SPACE_END                          0x9fff\n#define CONFIG_SPACE1_START                       0x2000\n#define CONFIG_SPACE1_END                         0x2bff\n#define CONFIG_SPACE2_START                       0x3000\n#define CONFIG_SPACE2_END                         0x9fff\n#define UCONFIG_SPACE_START                       0xc000\n#define UCONFIG_SPACE_END                         0xffff\n#define PERSISTENT_SPACE_START                    0x2c00\n#define PERSISTENT_SPACE_END                      0x2fff\n#define CONTEXT_SPACE_START                       0xa000\n#define CONTEXT_SPACE_END                         0xbfff\ntypedef enum ForceControl {\n\tFORCE_OFF                                        = 0x0,\n\tFORCE_ENABLE                                     = 0x1,\n\tFORCE_DISABLE                                    = 0x2,\n\tFORCE_RESERVED                                   = 0x3,\n} ForceControl;\ntypedef enum ZSamplePosition {\n\tZ_SAMPLE_CENTER                                  = 0x0,\n\tZ_SAMPLE_CENTROID                                = 0x1,\n} ZSamplePosition;\ntypedef enum ZOrder {\n\tLATE_Z                                           = 0x0,\n\tEARLY_Z_THEN_LATE_Z                              = 0x1,\n\tRE_Z                                             = 0x2,\n\tEARLY_Z_THEN_RE_Z                                = 0x3,\n} ZOrder;\ntypedef enum ZpassControl {\n\tZPASS_DISABLE                                    = 0x0,\n\tZPASS_SAMPLES                                    = 0x1,\n\tZPASS_PIXELS                                     = 0x2,\n} ZpassControl;\ntypedef enum ZModeForce {\n\tNO_FORCE                                         = 0x0,\n\tFORCE_EARLY_Z                                    = 0x1,\n\tFORCE_LATE_Z                                     = 0x2,\n\tFORCE_RE_Z                                       = 0x3,\n} ZModeForce;\ntypedef enum ZLimitSumm {\n\tFORCE_SUMM_OFF                                   = 0x0,\n\tFORCE_SUMM_MINZ                                  = 0x1,\n\tFORCE_SUMM_MAXZ                                  = 0x2,\n\tFORCE_SUMM_BOTH                                  = 0x3,\n} ZLimitSumm;\ntypedef enum CompareFrag {\n\tFRAG_NEVER                                       = 0x0,\n\tFRAG_LESS                                        = 0x1,\n\tFRAG_EQUAL                                       = 0x2,\n\tFRAG_LEQUAL                                      = 0x3,\n\tFRAG_GREATER                                     = 0x4,\n\tFRAG_NOTEQUAL                                    = 0x5,\n\tFRAG_GEQUAL                                      = 0x6,\n\tFRAG_ALWAYS                                      = 0x7,\n} CompareFrag;\ntypedef enum StencilOp {\n\tSTENCIL_KEEP                                     = 0x0,\n\tSTENCIL_ZERO                                     = 0x1,\n\tSTENCIL_ONES                                     = 0x2,\n\tSTENCIL_REPLACE_TEST                             = 0x3,\n\tSTENCIL_REPLACE_OP                               = 0x4,\n\tSTENCIL_ADD_CLAMP                                = 0x5,\n\tSTENCIL_SUB_CLAMP                                = 0x6,\n\tSTENCIL_INVERT                                   = 0x7,\n\tSTENCIL_ADD_WRAP                                 = 0x8,\n\tSTENCIL_SUB_WRAP                                 = 0x9,\n\tSTENCIL_AND                                      = 0xa,\n\tSTENCIL_OR                                       = 0xb,\n\tSTENCIL_XOR                                      = 0xc,\n\tSTENCIL_NAND                                     = 0xd,\n\tSTENCIL_NOR                                      = 0xe,\n\tSTENCIL_XNOR                                     = 0xf,\n} StencilOp;\ntypedef enum ConservativeZExport {\n\tEXPORT_ANY_Z                                     = 0x0,\n\tEXPORT_LESS_THAN_Z                               = 0x1,\n\tEXPORT_GREATER_THAN_Z                            = 0x2,\n\tEXPORT_RESERVED                                  = 0x3,\n} ConservativeZExport;\ntypedef enum DbPSLControl {\n\tPSLC_AUTO                                        = 0x0,\n\tPSLC_ON_HANG_ONLY                                = 0x1,\n\tPSLC_ASAP                                        = 0x2,\n\tPSLC_COUNTDOWN                                   = 0x3,\n} DbPSLControl;\ntypedef enum PerfCounter_Vals {\n\tDB_PERF_SEL_SC_DB_tile_sends                     = 0x0,\n\tDB_PERF_SEL_SC_DB_tile_busy                      = 0x1,\n\tDB_PERF_SEL_SC_DB_tile_stalls                    = 0x2,\n\tDB_PERF_SEL_SC_DB_tile_events                    = 0x3,\n\tDB_PERF_SEL_SC_DB_tile_tiles                     = 0x4,\n\tDB_PERF_SEL_SC_DB_tile_covered                   = 0x5,\n\tDB_PERF_SEL_hiz_tc_read_starved                  = 0x6,\n\tDB_PERF_SEL_hiz_tc_write_stall                   = 0x7,\n\tDB_PERF_SEL_hiz_qtiles_culled                    = 0x8,\n\tDB_PERF_SEL_his_qtiles_culled                    = 0x9,\n\tDB_PERF_SEL_DB_SC_tile_sends                     = 0xa,\n\tDB_PERF_SEL_DB_SC_tile_busy                      = 0xb,\n\tDB_PERF_SEL_DB_SC_tile_stalls                    = 0xc,\n\tDB_PERF_SEL_DB_SC_tile_df_stalls                 = 0xd,\n\tDB_PERF_SEL_DB_SC_tile_tiles                     = 0xe,\n\tDB_PERF_SEL_DB_SC_tile_culled                    = 0xf,\n\tDB_PERF_SEL_DB_SC_tile_hier_kill                 = 0x10,\n\tDB_PERF_SEL_DB_SC_tile_fast_ops                  = 0x11,\n\tDB_PERF_SEL_DB_SC_tile_no_ops                    = 0x12,\n\tDB_PERF_SEL_DB_SC_tile_tile_rate                 = 0x13,\n\tDB_PERF_SEL_DB_SC_tile_ssaa_kill                 = 0x14,\n\tDB_PERF_SEL_DB_SC_tile_fast_z_ops                = 0x15,\n\tDB_PERF_SEL_DB_SC_tile_fast_stencil_ops          = 0x16,\n\tDB_PERF_SEL_SC_DB_quad_sends                     = 0x17,\n\tDB_PERF_SEL_SC_DB_quad_busy                      = 0x18,\n\tDB_PERF_SEL_SC_DB_quad_squads                    = 0x19,\n\tDB_PERF_SEL_SC_DB_quad_tiles                     = 0x1a,\n\tDB_PERF_SEL_SC_DB_quad_pixels                    = 0x1b,\n\tDB_PERF_SEL_SC_DB_quad_killed_tiles              = 0x1c,\n\tDB_PERF_SEL_DB_SC_quad_sends                     = 0x1d,\n\tDB_PERF_SEL_DB_SC_quad_busy                      = 0x1e,\n\tDB_PERF_SEL_DB_SC_quad_stalls                    = 0x1f,\n\tDB_PERF_SEL_DB_SC_quad_tiles                     = 0x20,\n\tDB_PERF_SEL_DB_SC_quad_lit_quad                  = 0x21,\n\tDB_PERF_SEL_DB_CB_tile_sends                     = 0x22,\n\tDB_PERF_SEL_DB_CB_tile_busy                      = 0x23,\n\tDB_PERF_SEL_DB_CB_tile_stalls                    = 0x24,\n\tDB_PERF_SEL_SX_DB_quad_sends                     = 0x25,\n\tDB_PERF_SEL_SX_DB_quad_busy                      = 0x26,\n\tDB_PERF_SEL_SX_DB_quad_stalls                    = 0x27,\n\tDB_PERF_SEL_SX_DB_quad_quads                     = 0x28,\n\tDB_PERF_SEL_SX_DB_quad_pixels                    = 0x29,\n\tDB_PERF_SEL_SX_DB_quad_exports                   = 0x2a,\n\tDB_PERF_SEL_SH_quads_outstanding_sum             = 0x2b,\n\tDB_PERF_SEL_DB_CB_lquad_sends                    = 0x2c,\n\tDB_PERF_SEL_DB_CB_lquad_busy                     = 0x2d,\n\tDB_PERF_SEL_DB_CB_lquad_stalls                   = 0x2e,\n\tDB_PERF_SEL_DB_CB_lquad_quads                    = 0x2f,\n\tDB_PERF_SEL_tile_rd_sends                        = 0x30,\n\tDB_PERF_SEL_mi_tile_rd_outstanding_sum           = 0x31,\n\tDB_PERF_SEL_quad_rd_sends                        = 0x32,\n\tDB_PERF_SEL_quad_rd_busy                         = 0x33,\n\tDB_PERF_SEL_quad_rd_mi_stall                     = 0x34,\n\tDB_PERF_SEL_quad_rd_rw_collision                 = 0x35,\n\tDB_PERF_SEL_quad_rd_tag_stall                    = 0x36,\n\tDB_PERF_SEL_quad_rd_32byte_reqs                  = 0x37,\n\tDB_PERF_SEL_quad_rd_panic                        = 0x38,\n\tDB_PERF_SEL_mi_quad_rd_outstanding_sum           = 0x39,\n\tDB_PERF_SEL_quad_rdret_sends                     = 0x3a,\n\tDB_PERF_SEL_quad_rdret_busy                      = 0x3b,\n\tDB_PERF_SEL_tile_wr_sends                        = 0x3c,\n\tDB_PERF_SEL_tile_wr_acks                         = 0x3d,\n\tDB_PERF_SEL_mi_tile_wr_outstanding_sum           = 0x3e,\n\tDB_PERF_SEL_quad_wr_sends                        = 0x3f,\n\tDB_PERF_SEL_quad_wr_busy                         = 0x40,\n\tDB_PERF_SEL_quad_wr_mi_stall                     = 0x41,\n\tDB_PERF_SEL_quad_wr_coherency_stall              = 0x42,\n\tDB_PERF_SEL_quad_wr_acks                         = 0x43,\n\tDB_PERF_SEL_mi_quad_wr_outstanding_sum           = 0x44,\n\tDB_PERF_SEL_Tile_Cache_misses                    = 0x45,\n\tDB_PERF_SEL_Tile_Cache_hits                      = 0x46,\n\tDB_PERF_SEL_Tile_Cache_flushes                   = 0x47,\n\tDB_PERF_SEL_Tile_Cache_surface_stall             = 0x48,\n\tDB_PERF_SEL_Tile_Cache_starves                   = 0x49,\n\tDB_PERF_SEL_Tile_Cache_mem_return_starve         = 0x4a,\n\tDB_PERF_SEL_tcp_dispatcher_reads                 = 0x4b,\n\tDB_PERF_SEL_tcp_prefetcher_reads                 = 0x4c,\n\tDB_PERF_SEL_tcp_preloader_reads                  = 0x4d,\n\tDB_PERF_SEL_tcp_dispatcher_flushes               = 0x4e,\n\tDB_PERF_SEL_tcp_prefetcher_flushes               = 0x4f,\n\tDB_PERF_SEL_tcp_preloader_flushes                = 0x50,\n\tDB_PERF_SEL_Depth_Tile_Cache_sends               = 0x51,\n\tDB_PERF_SEL_Depth_Tile_Cache_busy                = 0x52,\n\tDB_PERF_SEL_Depth_Tile_Cache_starves             = 0x53,\n\tDB_PERF_SEL_Depth_Tile_Cache_dtile_locked        = 0x54,\n\tDB_PERF_SEL_Depth_Tile_Cache_alloc_stall         = 0x55,\n\tDB_PERF_SEL_Depth_Tile_Cache_misses              = 0x56,\n\tDB_PERF_SEL_Depth_Tile_Cache_hits                = 0x57,\n\tDB_PERF_SEL_Depth_Tile_Cache_flushes             = 0x58,\n\tDB_PERF_SEL_Depth_Tile_Cache_noop_tile           = 0x59,\n\tDB_PERF_SEL_Depth_Tile_Cache_detailed_noop       = 0x5a,\n\tDB_PERF_SEL_Depth_Tile_Cache_event               = 0x5b,\n\tDB_PERF_SEL_Depth_Tile_Cache_tile_frees          = 0x5c,\n\tDB_PERF_SEL_Depth_Tile_Cache_data_frees          = 0x5d,\n\tDB_PERF_SEL_Depth_Tile_Cache_mem_return_starve   = 0x5e,\n\tDB_PERF_SEL_Stencil_Cache_misses                 = 0x5f,\n\tDB_PERF_SEL_Stencil_Cache_hits                   = 0x60,\n\tDB_PERF_SEL_Stencil_Cache_flushes                = 0x61,\n\tDB_PERF_SEL_Stencil_Cache_starves                = 0x62,\n\tDB_PERF_SEL_Stencil_Cache_frees                  = 0x63,\n\tDB_PERF_SEL_Z_Cache_separate_Z_misses            = 0x64,\n\tDB_PERF_SEL_Z_Cache_separate_Z_hits              = 0x65,\n\tDB_PERF_SEL_Z_Cache_separate_Z_flushes           = 0x66,\n\tDB_PERF_SEL_Z_Cache_separate_Z_starves           = 0x67,\n\tDB_PERF_SEL_Z_Cache_pmask_misses                 = 0x68,\n\tDB_PERF_SEL_Z_Cache_pmask_hits                   = 0x69,\n\tDB_PERF_SEL_Z_Cache_pmask_flushes                = 0x6a,\n\tDB_PERF_SEL_Z_Cache_pmask_starves                = 0x6b,\n\tDB_PERF_SEL_Z_Cache_frees                        = 0x6c,\n\tDB_PERF_SEL_Plane_Cache_misses                   = 0x6d,\n\tDB_PERF_SEL_Plane_Cache_hits                     = 0x6e,\n\tDB_PERF_SEL_Plane_Cache_flushes                  = 0x6f,\n\tDB_PERF_SEL_Plane_Cache_starves                  = 0x70,\n\tDB_PERF_SEL_Plane_Cache_frees                    = 0x71,\n\tDB_PERF_SEL_flush_expanded_stencil               = 0x72,\n\tDB_PERF_SEL_flush_compressed_stencil             = 0x73,\n\tDB_PERF_SEL_flush_single_stencil                 = 0x74,\n\tDB_PERF_SEL_planes_flushed                       = 0x75,\n\tDB_PERF_SEL_flush_1plane                         = 0x76,\n\tDB_PERF_SEL_flush_2plane                         = 0x77,\n\tDB_PERF_SEL_flush_3plane                         = 0x78,\n\tDB_PERF_SEL_flush_4plane                         = 0x79,\n\tDB_PERF_SEL_flush_5plane                         = 0x7a,\n\tDB_PERF_SEL_flush_6plane                         = 0x7b,\n\tDB_PERF_SEL_flush_7plane                         = 0x7c,\n\tDB_PERF_SEL_flush_8plane                         = 0x7d,\n\tDB_PERF_SEL_flush_9plane                         = 0x7e,\n\tDB_PERF_SEL_flush_10plane                        = 0x7f,\n\tDB_PERF_SEL_flush_11plane                        = 0x80,\n\tDB_PERF_SEL_flush_12plane                        = 0x81,\n\tDB_PERF_SEL_flush_13plane                        = 0x82,\n\tDB_PERF_SEL_flush_14plane                        = 0x83,\n\tDB_PERF_SEL_flush_15plane                        = 0x84,\n\tDB_PERF_SEL_flush_16plane                        = 0x85,\n\tDB_PERF_SEL_flush_expanded_z                     = 0x86,\n\tDB_PERF_SEL_earlyZ_waiting_for_postZ_done        = 0x87,\n\tDB_PERF_SEL_reZ_waiting_for_postZ_done           = 0x88,\n\tDB_PERF_SEL_dk_tile_sends                        = 0x89,\n\tDB_PERF_SEL_dk_tile_busy                         = 0x8a,\n\tDB_PERF_SEL_dk_tile_quad_starves                 = 0x8b,\n\tDB_PERF_SEL_dk_tile_stalls                       = 0x8c,\n\tDB_PERF_SEL_dk_squad_sends                       = 0x8d,\n\tDB_PERF_SEL_dk_squad_busy                        = 0x8e,\n\tDB_PERF_SEL_dk_squad_stalls                      = 0x8f,\n\tDB_PERF_SEL_Op_Pipe_Busy                         = 0x90,\n\tDB_PERF_SEL_Op_Pipe_MC_Read_stall                = 0x91,\n\tDB_PERF_SEL_qc_busy                              = 0x92,\n\tDB_PERF_SEL_qc_xfc                               = 0x93,\n\tDB_PERF_SEL_qc_conflicts                         = 0x94,\n\tDB_PERF_SEL_qc_full_stall                        = 0x95,\n\tDB_PERF_SEL_qc_in_preZ_tile_stalls_postZ         = 0x96,\n\tDB_PERF_SEL_qc_in_postZ_tile_stalls_preZ         = 0x97,\n\tDB_PERF_SEL_tsc_insert_summarize_stall           = 0x98,\n\tDB_PERF_SEL_tl_busy                              = 0x99,\n\tDB_PERF_SEL_tl_dtc_read_starved                  = 0x9a,\n\tDB_PERF_SEL_tl_z_fetch_stall                     = 0x9b,\n\tDB_PERF_SEL_tl_stencil_stall                     = 0x9c,\n\tDB_PERF_SEL_tl_z_decompress_stall                = 0x9d,\n\tDB_PERF_SEL_tl_stencil_locked_stall              = 0x9e,\n\tDB_PERF_SEL_tl_events                            = 0x9f,\n\tDB_PERF_SEL_tl_summarize_squads                  = 0xa0,\n\tDB_PERF_SEL_tl_flush_expand_squads               = 0xa1,\n\tDB_PERF_SEL_tl_expand_squads                     = 0xa2,\n\tDB_PERF_SEL_tl_preZ_squads                       = 0xa3,\n\tDB_PERF_SEL_tl_postZ_squads                      = 0xa4,\n\tDB_PERF_SEL_tl_preZ_noop_squads                  = 0xa5,\n\tDB_PERF_SEL_tl_postZ_noop_squads                 = 0xa6,\n\tDB_PERF_SEL_tl_tile_ops                          = 0xa7,\n\tDB_PERF_SEL_tl_in_xfc                            = 0xa8,\n\tDB_PERF_SEL_tl_in_single_stencil_expand_stall    = 0xa9,\n\tDB_PERF_SEL_tl_in_fast_z_stall                   = 0xaa,\n\tDB_PERF_SEL_tl_out_xfc                           = 0xab,\n\tDB_PERF_SEL_tl_out_squads                        = 0xac,\n\tDB_PERF_SEL_zf_plane_multicycle                  = 0xad,\n\tDB_PERF_SEL_PostZ_Samples_passing_Z              = 0xae,\n\tDB_PERF_SEL_PostZ_Samples_failing_Z              = 0xaf,\n\tDB_PERF_SEL_PostZ_Samples_failing_S              = 0xb0,\n\tDB_PERF_SEL_PreZ_Samples_passing_Z               = 0xb1,\n\tDB_PERF_SEL_PreZ_Samples_failing_Z               = 0xb2,\n\tDB_PERF_SEL_PreZ_Samples_failing_S               = 0xb3,\n\tDB_PERF_SEL_ts_tc_update_stall                   = 0xb4,\n\tDB_PERF_SEL_sc_kick_start                        = 0xb5,\n\tDB_PERF_SEL_sc_kick_end                          = 0xb6,\n\tDB_PERF_SEL_clock_reg_active                     = 0xb7,\n\tDB_PERF_SEL_clock_main_active                    = 0xb8,\n\tDB_PERF_SEL_clock_mem_export_active              = 0xb9,\n\tDB_PERF_SEL_esr_ps_out_busy                      = 0xba,\n\tDB_PERF_SEL_esr_ps_lqf_busy                      = 0xbb,\n\tDB_PERF_SEL_esr_ps_lqf_stall                     = 0xbc,\n\tDB_PERF_SEL_etr_out_send                         = 0xbd,\n\tDB_PERF_SEL_etr_out_busy                         = 0xbe,\n\tDB_PERF_SEL_etr_out_ltile_probe_fifo_full_stall  = 0xbf,\n\tDB_PERF_SEL_etr_out_cb_tile_stall                = 0xc0,\n\tDB_PERF_SEL_etr_out_esr_stall                    = 0xc1,\n\tDB_PERF_SEL_esr_ps_sqq_busy                      = 0xc2,\n\tDB_PERF_SEL_esr_ps_sqq_stall                     = 0xc3,\n\tDB_PERF_SEL_esr_eot_fwd_busy                     = 0xc4,\n\tDB_PERF_SEL_esr_eot_fwd_holding_squad            = 0xc5,\n\tDB_PERF_SEL_esr_eot_fwd_forward                  = 0xc6,\n\tDB_PERF_SEL_esr_sqq_zi_busy                      = 0xc7,\n\tDB_PERF_SEL_esr_sqq_zi_stall                     = 0xc8,\n\tDB_PERF_SEL_postzl_sq_pt_busy                    = 0xc9,\n\tDB_PERF_SEL_postzl_sq_pt_stall                   = 0xca,\n\tDB_PERF_SEL_postzl_se_busy                       = 0xcb,\n\tDB_PERF_SEL_postzl_se_stall                      = 0xcc,\n\tDB_PERF_SEL_postzl_partial_launch                = 0xcd,\n\tDB_PERF_SEL_postzl_full_launch                   = 0xce,\n\tDB_PERF_SEL_postzl_partial_waiting               = 0xcf,\n\tDB_PERF_SEL_postzl_tile_mem_stall                = 0xd0,\n\tDB_PERF_SEL_postzl_tile_init_stall               = 0xd1,\n\tDB_PEFF_SEL_prezl_tile_mem_stall                 = 0xd2,\n\tDB_PERF_SEL_prezl_tile_init_stall                = 0xd3,\n\tDB_PERF_SEL_dtt_sm_clash_stall                   = 0xd4,\n\tDB_PERF_SEL_dtt_sm_slot_stall                    = 0xd5,\n\tDB_PERF_SEL_dtt_sm_miss_stall                    = 0xd6,\n\tDB_PERF_SEL_mi_rdreq_busy                        = 0xd7,\n\tDB_PERF_SEL_mi_rdreq_stall                       = 0xd8,\n\tDB_PERF_SEL_mi_wrreq_busy                        = 0xd9,\n\tDB_PERF_SEL_mi_wrreq_stall                       = 0xda,\n\tDB_PERF_SEL_recomp_tile_to_1zplane_no_fastop     = 0xdb,\n\tDB_PERF_SEL_dkg_tile_rate_tile                   = 0xdc,\n\tDB_PERF_SEL_prezl_src_in_sends                   = 0xdd,\n\tDB_PERF_SEL_prezl_src_in_stall                   = 0xde,\n\tDB_PERF_SEL_prezl_src_in_squads                  = 0xdf,\n\tDB_PERF_SEL_prezl_src_in_squads_unrolled         = 0xe0,\n\tDB_PERF_SEL_prezl_src_in_tile_rate               = 0xe1,\n\tDB_PERF_SEL_prezl_src_in_tile_rate_unrolled      = 0xe2,\n\tDB_PERF_SEL_prezl_src_out_stall                  = 0xe3,\n\tDB_PERF_SEL_postzl_src_in_sends                  = 0xe4,\n\tDB_PERF_SEL_postzl_src_in_stall                  = 0xe5,\n\tDB_PERF_SEL_postzl_src_in_squads                 = 0xe6,\n\tDB_PERF_SEL_postzl_src_in_squads_unrolled        = 0xe7,\n\tDB_PERF_SEL_postzl_src_in_tile_rate              = 0xe8,\n\tDB_PERF_SEL_postzl_src_in_tile_rate_unrolled     = 0xe9,\n\tDB_PERF_SEL_postzl_src_out_stall                 = 0xea,\n\tDB_PERF_SEL_esr_ps_src_in_sends                  = 0xeb,\n\tDB_PERF_SEL_esr_ps_src_in_stall                  = 0xec,\n\tDB_PERF_SEL_esr_ps_src_in_squads                 = 0xed,\n\tDB_PERF_SEL_esr_ps_src_in_squads_unrolled        = 0xee,\n\tDB_PERF_SEL_esr_ps_src_in_tile_rate              = 0xef,\n\tDB_PERF_SEL_esr_ps_src_in_tile_rate_unrolled     = 0xf0,\n\tDB_PERF_SEL_esr_ps_src_in_tile_rate_unrolled_to_pixel_rate= 0xf1,\n\tDB_PERF_SEL_esr_ps_src_out_stall                 = 0xf2,\n\tDB_PERF_SEL_depth_bounds_qtiles_culled           = 0xf3,\n\tDB_PERF_SEL_PreZ_Samples_failing_DB              = 0xf4,\n\tDB_PERF_SEL_PostZ_Samples_failing_DB             = 0xf5,\n\tDB_PERF_SEL_flush_compressed                     = 0xf6,\n\tDB_PERF_SEL_flush_plane_le4                      = 0xf7,\n\tDB_PERF_SEL_tiles_z_fully_summarized             = 0xf8,\n\tDB_PERF_SEL_tiles_stencil_fully_summarized       = 0xf9,\n\tDB_PERF_SEL_tiles_z_clear_on_expclear            = 0xfa,\n\tDB_PERF_SEL_tiles_s_clear_on_expclear            = 0xfb,\n\tDB_PERF_SEL_tiles_decomp_on_expclear             = 0xfc,\n\tDB_PERF_SEL_tiles_compressed_to_decompressed     = 0xfd,\n\tDB_PERF_SEL_Op_Pipe_Prez_Busy                    = 0xfe,\n\tDB_PERF_SEL_Op_Pipe_Postz_Busy                   = 0xff,\n\tDB_PERF_SEL_di_dt_stall                          = 0x100,\n} PerfCounter_Vals;\ntypedef enum RingCounterControl {\n\tCOUNTER_RING_SPLIT                               = 0x0,\n\tCOUNTER_RING_0                                   = 0x1,\n\tCOUNTER_RING_1                                   = 0x2,\n} RingCounterControl;\ntypedef enum PixelPipeCounterId {\n\tPIXEL_PIPE_OCCLUSION_COUNT_0                     = 0x0,\n\tPIXEL_PIPE_OCCLUSION_COUNT_1                     = 0x1,\n\tPIXEL_PIPE_OCCLUSION_COUNT_2                     = 0x2,\n\tPIXEL_PIPE_OCCLUSION_COUNT_3                     = 0x3,\n\tPIXEL_PIPE_SCREEN_MIN_EXTENTS_0                  = 0x4,\n\tPIXEL_PIPE_SCREEN_MAX_EXTENTS_0                  = 0x5,\n\tPIXEL_PIPE_SCREEN_MIN_EXTENTS_1                  = 0x6,\n\tPIXEL_PIPE_SCREEN_MAX_EXTENTS_1                  = 0x7,\n} PixelPipeCounterId;\ntypedef enum PixelPipeStride {\n\tPIXEL_PIPE_STRIDE_32_BITS                        = 0x0,\n\tPIXEL_PIPE_STRIDE_64_BITS                        = 0x1,\n\tPIXEL_PIPE_STRIDE_128_BITS                       = 0x2,\n\tPIXEL_PIPE_STRIDE_256_BITS                       = 0x3,\n} PixelPipeStride;\ntypedef enum GB_EDC_DED_MODE {\n\tGB_EDC_DED_MODE_LOG                              = 0x0,\n\tGB_EDC_DED_MODE_HALT                             = 0x1,\n\tGB_EDC_DED_MODE_INT_HALT                         = 0x2,\n} GB_EDC_DED_MODE;\n#define GB_TILING_CONFIG_TABLE_SIZE               0x20\n#define GB_TILING_CONFIG_MACROTABLE_SIZE          0x10\ntypedef enum GRBM_PERF_SEL {\n\tGRBM_PERF_SEL_COUNT                              = 0x0,\n\tGRBM_PERF_SEL_USER_DEFINED                       = 0x1,\n\tGRBM_PERF_SEL_GUI_ACTIVE                         = 0x2,\n\tGRBM_PERF_SEL_CP_BUSY                            = 0x3,\n\tGRBM_PERF_SEL_CP_COHER_BUSY                      = 0x4,\n\tGRBM_PERF_SEL_CP_DMA_BUSY                        = 0x5,\n\tGRBM_PERF_SEL_CB_BUSY                            = 0x6,\n\tGRBM_PERF_SEL_DB_BUSY                            = 0x7,\n\tGRBM_PERF_SEL_PA_BUSY                            = 0x8,\n\tGRBM_PERF_SEL_SC_BUSY                            = 0x9,\n\tGRBM_PERF_SEL_RESERVED_6                         = 0xa,\n\tGRBM_PERF_SEL_SPI_BUSY                           = 0xb,\n\tGRBM_PERF_SEL_SX_BUSY                            = 0xc,\n\tGRBM_PERF_SEL_TA_BUSY                            = 0xd,\n\tGRBM_PERF_SEL_CB_CLEAN                           = 0xe,\n\tGRBM_PERF_SEL_DB_CLEAN                           = 0xf,\n\tGRBM_PERF_SEL_RESERVED_5                         = 0x10,\n\tGRBM_PERF_SEL_VGT_BUSY                           = 0x11,\n\tGRBM_PERF_SEL_RESERVED_4                         = 0x12,\n\tGRBM_PERF_SEL_RESERVED_3                         = 0x13,\n\tGRBM_PERF_SEL_RESERVED_2                         = 0x14,\n\tGRBM_PERF_SEL_RESERVED_1                         = 0x15,\n\tGRBM_PERF_SEL_RESERVED_0                         = 0x16,\n\tGRBM_PERF_SEL_IA_BUSY                            = 0x17,\n\tGRBM_PERF_SEL_IA_NO_DMA_BUSY                     = 0x18,\n\tGRBM_PERF_SEL_GDS_BUSY                           = 0x19,\n\tGRBM_PERF_SEL_BCI_BUSY                           = 0x1a,\n\tGRBM_PERF_SEL_RLC_BUSY                           = 0x1b,\n\tGRBM_PERF_SEL_TC_BUSY                            = 0x1c,\n\tGRBM_PERF_SEL_CPG_BUSY                           = 0x1d,\n\tGRBM_PERF_SEL_CPC_BUSY                           = 0x1e,\n\tGRBM_PERF_SEL_CPF_BUSY                           = 0x1f,\n\tGRBM_PERF_SEL_WD_BUSY                            = 0x20,\n\tGRBM_PERF_SEL_WD_NO_DMA_BUSY                     = 0x21,\n} GRBM_PERF_SEL;\ntypedef enum GRBM_SE0_PERF_SEL {\n\tGRBM_SE0_PERF_SEL_COUNT                          = 0x0,\n\tGRBM_SE0_PERF_SEL_USER_DEFINED                   = 0x1,\n\tGRBM_SE0_PERF_SEL_CB_BUSY                        = 0x2,\n\tGRBM_SE0_PERF_SEL_DB_BUSY                        = 0x3,\n\tGRBM_SE0_PERF_SEL_SC_BUSY                        = 0x4,\n\tGRBM_SE0_PERF_SEL_RESERVED_1                     = 0x5,\n\tGRBM_SE0_PERF_SEL_SPI_BUSY                       = 0x6,\n\tGRBM_SE0_PERF_SEL_SX_BUSY                        = 0x7,\n\tGRBM_SE0_PERF_SEL_TA_BUSY                        = 0x8,\n\tGRBM_SE0_PERF_SEL_CB_CLEAN                       = 0x9,\n\tGRBM_SE0_PERF_SEL_DB_CLEAN                       = 0xa,\n\tGRBM_SE0_PERF_SEL_RESERVED_0                     = 0xb,\n\tGRBM_SE0_PERF_SEL_PA_BUSY                        = 0xc,\n\tGRBM_SE0_PERF_SEL_VGT_BUSY                       = 0xd,\n\tGRBM_SE0_PERF_SEL_BCI_BUSY                       = 0xe,\n} GRBM_SE0_PERF_SEL;\ntypedef enum GRBM_SE1_PERF_SEL {\n\tGRBM_SE1_PERF_SEL_COUNT                          = 0x0,\n\tGRBM_SE1_PERF_SEL_USER_DEFINED                   = 0x1,\n\tGRBM_SE1_PERF_SEL_CB_BUSY                        = 0x2,\n\tGRBM_SE1_PERF_SEL_DB_BUSY                        = 0x3,\n\tGRBM_SE1_PERF_SEL_SC_BUSY                        = 0x4,\n\tGRBM_SE1_PERF_SEL_RESERVED_1                     = 0x5,\n\tGRBM_SE1_PERF_SEL_SPI_BUSY                       = 0x6,\n\tGRBM_SE1_PERF_SEL_SX_BUSY                        = 0x7,\n\tGRBM_SE1_PERF_SEL_TA_BUSY                        = 0x8,\n\tGRBM_SE1_PERF_SEL_CB_CLEAN                       = 0x9,\n\tGRBM_SE1_PERF_SEL_DB_CLEAN                       = 0xa,\n\tGRBM_SE1_PERF_SEL_RESERVED_0                     = 0xb,\n\tGRBM_SE1_PERF_SEL_PA_BUSY                        = 0xc,\n\tGRBM_SE1_PERF_SEL_VGT_BUSY                       = 0xd,\n\tGRBM_SE1_PERF_SEL_BCI_BUSY                       = 0xe,\n} GRBM_SE1_PERF_SEL;\ntypedef enum GRBM_SE2_PERF_SEL {\n\tGRBM_SE2_PERF_SEL_COUNT                          = 0x0,\n\tGRBM_SE2_PERF_SEL_USER_DEFINED                   = 0x1,\n\tGRBM_SE2_PERF_SEL_CB_BUSY                        = 0x2,\n\tGRBM_SE2_PERF_SEL_DB_BUSY                        = 0x3,\n\tGRBM_SE2_PERF_SEL_SC_BUSY                        = 0x4,\n\tGRBM_SE2_PERF_SEL_RESERVED_1                     = 0x5,\n\tGRBM_SE2_PERF_SEL_SPI_BUSY                       = 0x6,\n\tGRBM_SE2_PERF_SEL_SX_BUSY                        = 0x7,\n\tGRBM_SE2_PERF_SEL_TA_BUSY                        = 0x8,\n\tGRBM_SE2_PERF_SEL_CB_CLEAN                       = 0x9,\n\tGRBM_SE2_PERF_SEL_DB_CLEAN                       = 0xa,\n\tGRBM_SE2_PERF_SEL_RESERVED_0                     = 0xb,\n\tGRBM_SE2_PERF_SEL_PA_BUSY                        = 0xc,\n\tGRBM_SE2_PERF_SEL_VGT_BUSY                       = 0xd,\n\tGRBM_SE2_PERF_SEL_BCI_BUSY                       = 0xe,\n} GRBM_SE2_PERF_SEL;\ntypedef enum GRBM_SE3_PERF_SEL {\n\tGRBM_SE3_PERF_SEL_COUNT                          = 0x0,\n\tGRBM_SE3_PERF_SEL_USER_DEFINED                   = 0x1,\n\tGRBM_SE3_PERF_SEL_CB_BUSY                        = 0x2,\n\tGRBM_SE3_PERF_SEL_DB_BUSY                        = 0x3,\n\tGRBM_SE3_PERF_SEL_SC_BUSY                        = 0x4,\n\tGRBM_SE3_PERF_SEL_RESERVED_1                     = 0x5,\n\tGRBM_SE3_PERF_SEL_SPI_BUSY                       = 0x6,\n\tGRBM_SE3_PERF_SEL_SX_BUSY                        = 0x7,\n\tGRBM_SE3_PERF_SEL_TA_BUSY                        = 0x8,\n\tGRBM_SE3_PERF_SEL_CB_CLEAN                       = 0x9,\n\tGRBM_SE3_PERF_SEL_DB_CLEAN                       = 0xa,\n\tGRBM_SE3_PERF_SEL_RESERVED_0                     = 0xb,\n\tGRBM_SE3_PERF_SEL_PA_BUSY                        = 0xc,\n\tGRBM_SE3_PERF_SEL_VGT_BUSY                       = 0xd,\n\tGRBM_SE3_PERF_SEL_BCI_BUSY                       = 0xe,\n} GRBM_SE3_PERF_SEL;\ntypedef enum SU_PERFCNT_SEL {\n\tPERF_PAPC_PASX_REQ                               = 0x0,\n\tPERF_PAPC_PASX_DISABLE_PIPE                      = 0x1,\n\tPERF_PAPC_PASX_FIRST_VECTOR                      = 0x2,\n\tPERF_PAPC_PASX_SECOND_VECTOR                     = 0x3,\n\tPERF_PAPC_PASX_FIRST_DEAD                        = 0x4,\n\tPERF_PAPC_PASX_SECOND_DEAD                       = 0x5,\n\tPERF_PAPC_PASX_VTX_KILL_DISCARD                  = 0x6,\n\tPERF_PAPC_PASX_VTX_NAN_DISCARD                   = 0x7,\n\tPERF_PAPC_PA_INPUT_PRIM                          = 0x8,\n\tPERF_PAPC_PA_INPUT_NULL_PRIM                     = 0x9,\n\tPERF_PAPC_PA_INPUT_EVENT_FLAG                    = 0xa,\n\tPERF_PAPC_PA_INPUT_FIRST_PRIM_SLOT               = 0xb,\n\tPERF_PAPC_PA_INPUT_END_OF_PACKET                 = 0xc,\n\tPERF_PAPC_PA_INPUT_EXTENDED_EVENT                = 0xd,\n\tPERF_PAPC_CLPR_CULL_PRIM                         = 0xe,\n\tPERF_PAPC_CLPR_VVUCP_CULL_PRIM                   = 0xf,\n\tPERF_PAPC_CLPR_VV_CULL_PRIM                      = 0x10,\n\tPERF_PAPC_CLPR_UCP_CULL_PRIM                     = 0x11,\n\tPERF_PAPC_CLPR_VTX_KILL_CULL_PRIM                = 0x12,\n\tPERF_PAPC_CLPR_VTX_NAN_CULL_PRIM                 = 0x13,\n\tPERF_PAPC_CLPR_CULL_TO_NULL_PRIM                 = 0x14,\n\tPERF_PAPC_CLPR_VVUCP_CLIP_PRIM                   = 0x15,\n\tPERF_PAPC_CLPR_VV_CLIP_PRIM                      = 0x16,\n\tPERF_PAPC_CLPR_UCP_CLIP_PRIM                     = 0x17,\n\tPERF_PAPC_CLPR_POINT_CLIP_CANDIDATE              = 0x18,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_1                  = 0x19,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_2                  = 0x1a,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_3                  = 0x1b,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_4                  = 0x1c,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_5_8                = 0x1d,\n\tPERF_PAPC_CLPR_CLIP_PLANE_CNT_9_12               = 0x1e,\n\tPERF_PAPC_CLPR_CLIP_PLANE_NEAR                   = 0x1f,\n\tPERF_PAPC_CLPR_CLIP_PLANE_FAR                    = 0x20,\n\tPERF_PAPC_CLPR_CLIP_PLANE_LEFT                   = 0x21,\n\tPERF_PAPC_CLPR_CLIP_PLANE_RIGHT                  = 0x22,\n\tPERF_PAPC_CLPR_CLIP_PLANE_TOP                    = 0x23,\n\tPERF_PAPC_CLPR_CLIP_PLANE_BOTTOM                 = 0x24,\n\tPERF_PAPC_CLPR_GSC_KILL_CULL_PRIM                = 0x25,\n\tPERF_PAPC_CLPR_RASTER_KILL_CULL_PRIM             = 0x26,\n\tPERF_PAPC_CLSM_NULL_PRIM                         = 0x27,\n\tPERF_PAPC_CLSM_TOTALLY_VISIBLE_PRIM              = 0x28,\n\tPERF_PAPC_CLSM_CULL_TO_NULL_PRIM                 = 0x29,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_1                    = 0x2a,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_2                    = 0x2b,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_3                    = 0x2c,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_4                    = 0x2d,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_5_8                  = 0x2e,\n\tPERF_PAPC_CLSM_OUT_PRIM_CNT_9_13                 = 0x2f,\n\tPERF_PAPC_CLIPGA_VTE_KILL_PRIM                   = 0x30,\n\tPERF_PAPC_SU_INPUT_PRIM                          = 0x31,\n\tPERF_PAPC_SU_INPUT_CLIP_PRIM                     = 0x32,\n\tPERF_PAPC_SU_INPUT_NULL_PRIM                     = 0x33,\n\tPERF_PAPC_SU_INPUT_PRIM_DUAL                     = 0x34,\n\tPERF_PAPC_SU_INPUT_CLIP_PRIM_DUAL                = 0x35,\n\tPERF_PAPC_SU_ZERO_AREA_CULL_PRIM                 = 0x36,\n\tPERF_PAPC_SU_BACK_FACE_CULL_PRIM                 = 0x37,\n\tPERF_PAPC_SU_FRONT_FACE_CULL_PRIM                = 0x38,\n\tPERF_PAPC_SU_POLYMODE_FACE_CULL                  = 0x39,\n\tPERF_PAPC_SU_POLYMODE_BACK_CULL                  = 0x3a,\n\tPERF_PAPC_SU_POLYMODE_FRONT_CULL                 = 0x3b,\n\tPERF_PAPC_SU_POLYMODE_INVALID_FILL               = 0x3c,\n\tPERF_PAPC_SU_OUTPUT_PRIM                         = 0x3d,\n\tPERF_PAPC_SU_OUTPUT_CLIP_PRIM                    = 0x3e,\n\tPERF_PAPC_SU_OUTPUT_NULL_PRIM                    = 0x3f,\n\tPERF_PAPC_SU_OUTPUT_EVENT_FLAG                   = 0x40,\n\tPERF_PAPC_SU_OUTPUT_FIRST_PRIM_SLOT              = 0x41,\n\tPERF_PAPC_SU_OUTPUT_END_OF_PACKET                = 0x42,\n\tPERF_PAPC_SU_OUTPUT_POLYMODE_FACE                = 0x43,\n\tPERF_PAPC_SU_OUTPUT_POLYMODE_BACK                = 0x44,\n\tPERF_PAPC_SU_OUTPUT_POLYMODE_FRONT               = 0x45,\n\tPERF_PAPC_SU_OUT_CLIP_POLYMODE_FACE              = 0x46,\n\tPERF_PAPC_SU_OUT_CLIP_POLYMODE_BACK              = 0x47,\n\tPERF_PAPC_SU_OUT_CLIP_POLYMODE_FRONT             = 0x48,\n\tPERF_PAPC_SU_OUTPUT_PRIM_DUAL                    = 0x49,\n\tPERF_PAPC_SU_OUTPUT_CLIP_PRIM_DUAL               = 0x4a,\n\tPERF_PAPC_SU_OUTPUT_POLYMODE_DUAL                = 0x4b,\n\tPERF_PAPC_SU_OUTPUT_CLIP_POLYMODE_DUAL           = 0x4c,\n\tPERF_PAPC_PASX_REQ_IDLE                          = 0x4d,\n\tPERF_PAPC_PASX_REQ_BUSY                          = 0x4e,\n\tPERF_PAPC_PASX_REQ_STALLED                       = 0x4f,\n\tPERF_PAPC_PASX_REC_IDLE                          = 0x50,\n\tPERF_PAPC_PASX_REC_BUSY                          = 0x51,\n\tPERF_PAPC_PASX_REC_STARVED_SX                    = 0x52,\n\tPERF_PAPC_PASX_REC_STALLED                       = 0x53,\n\tPERF_PAPC_PASX_REC_STALLED_POS_MEM               = 0x54,\n\tPERF_PAPC_PASX_REC_STALLED_CCGSM_IN              = 0x55,\n\tPERF_PAPC_CCGSM_IDLE                             = 0x56,\n\tPERF_PAPC_CCGSM_BUSY                             = 0x57,\n\tPERF_PAPC_CCGSM_STALLED                          = 0x58,\n\tPERF_PAPC_CLPRIM_IDLE                            = 0x59,\n\tPERF_PAPC_CLPRIM_BUSY                            = 0x5a,\n\tPERF_PAPC_CLPRIM_STALLED                         = 0x5b,\n\tPERF_PAPC_CLPRIM_STARVED_CCGSM                   = 0x5c,\n\tPERF_PAPC_CLIPSM_IDLE                            = 0x5d,\n\tPERF_PAPC_CLIPSM_BUSY                            = 0x5e,\n\tPERF_PAPC_CLIPSM_WAIT_CLIP_VERT_ENGH             = 0x5f,\n\tPERF_PAPC_CLIPSM_WAIT_HIGH_PRI_SEQ               = 0x60,\n\tPERF_PAPC_CLIPSM_WAIT_CLIPGA                     = 0x61,\n\tPERF_PAPC_CLIPSM_WAIT_AVAIL_VTE_CLIP             = 0x62,\n\tPERF_PAPC_CLIPSM_WAIT_CLIP_OUTSM                 = 0x63,\n\tPERF_PAPC_CLIPGA_IDLE                            = 0x64,\n\tPERF_PAPC_CLIPGA_BUSY                            = 0x65,\n\tPERF_PAPC_CLIPGA_STARVED_VTE_CLIP                = 0x66,\n\tPERF_PAPC_CLIPGA_STALLED                         = 0x67,\n\tPERF_PAPC_CLIP_IDLE                              = 0x68,\n\tPERF_PAPC_CLIP_BUSY                              = 0x69,\n\tPERF_PAPC_SU_IDLE                                = 0x6a,\n\tPERF_PAPC_SU_BUSY                                = 0x6b,\n\tPERF_PAPC_SU_STARVED_CLIP                        = 0x6c,\n\tPERF_PAPC_SU_STALLED_SC                          = 0x6d,\n\tPERF_PAPC_CL_DYN_SCLK_VLD                        = 0x6e,\n\tPERF_PAPC_SU_DYN_SCLK_VLD                        = 0x6f,\n\tPERF_PAPC_PA_REG_SCLK_VLD                        = 0x70,\n\tPERF_PAPC_SU_MULTI_GPU_PRIM_FILTER_CULL          = 0x71,\n\tPERF_PAPC_PASX_SE0_REQ                           = 0x72,\n\tPERF_PAPC_PASX_SE1_REQ                           = 0x73,\n\tPERF_PAPC_PASX_SE0_FIRST_VECTOR                  = 0x74,\n\tPERF_PAPC_PASX_SE0_SECOND_VECTOR                 = 0x75,\n\tPERF_PAPC_PASX_SE1_FIRST_VECTOR                  = 0x76,\n\tPERF_PAPC_PASX_SE1_SECOND_VECTOR                 = 0x77,\n\tPERF_PAPC_SU_SE0_PRIM_FILTER_CULL                = 0x78,\n\tPERF_PAPC_SU_SE1_PRIM_FILTER_CULL                = 0x79,\n\tPERF_PAPC_SU_SE01_PRIM_FILTER_CULL               = 0x7a,\n\tPERF_PAPC_SU_SE0_OUTPUT_PRIM                     = 0x7b,\n\tPERF_PAPC_SU_SE1_OUTPUT_PRIM                     = 0x7c,\n\tPERF_PAPC_SU_SE01_OUTPUT_PRIM                    = 0x7d,\n\tPERF_PAPC_SU_SE0_OUTPUT_NULL_PRIM                = 0x7e,\n\tPERF_PAPC_SU_SE1_OUTPUT_NULL_PRIM                = 0x7f,\n\tPERF_PAPC_SU_SE01_OUTPUT_NULL_PRIM               = 0x80,\n\tPERF_PAPC_SU_SE0_OUTPUT_FIRST_PRIM_SLOT          = 0x81,\n\tPERF_PAPC_SU_SE1_OUTPUT_FIRST_PRIM_SLOT          = 0x82,\n\tPERF_PAPC_SU_SE0_STALLED_SC                      = 0x83,\n\tPERF_PAPC_SU_SE1_STALLED_SC                      = 0x84,\n\tPERF_PAPC_SU_SE01_STALLED_SC                     = 0x85,\n\tPERF_PAPC_CLSM_CLIPPING_PRIM                     = 0x86,\n\tPERF_PAPC_SU_CULLED_PRIM                         = 0x87,\n\tPERF_PAPC_SU_OUTPUT_EOPG                         = 0x88,\n\tPERF_PAPC_SU_SE2_PRIM_FILTER_CULL                = 0x89,\n\tPERF_PAPC_SU_SE3_PRIM_FILTER_CULL                = 0x8a,\n\tPERF_PAPC_SU_SE2_OUTPUT_PRIM                     = 0x8b,\n\tPERF_PAPC_SU_SE3_OUTPUT_PRIM                     = 0x8c,\n\tPERF_PAPC_SU_SE2_OUTPUT_NULL_PRIM                = 0x8d,\n\tPERF_PAPC_SU_SE3_OUTPUT_NULL_PRIM                = 0x8e,\n\tPERF_PAPC_SU_SE0_OUTPUT_END_OF_PACKET            = 0x8f,\n\tPERF_PAPC_SU_SE1_OUTPUT_END_OF_PACKET            = 0x90,\n\tPERF_PAPC_SU_SE2_OUTPUT_END_OF_PACKET            = 0x91,\n\tPERF_PAPC_SU_SE3_OUTPUT_END_OF_PACKET            = 0x92,\n\tPERF_PAPC_SU_SE0_OUTPUT_EOPG                     = 0x93,\n\tPERF_PAPC_SU_SE1_OUTPUT_EOPG                     = 0x94,\n\tPERF_PAPC_SU_SE2_OUTPUT_EOPG                     = 0x95,\n\tPERF_PAPC_SU_SE3_OUTPUT_EOPG                     = 0x96,\n\tPERF_PAPC_SU_SE2_STALLED_SC                      = 0x97,\n\tPERF_PAPC_SU_SE3_STALLED_SC                      = 0x98,\n} SU_PERFCNT_SEL;\ntypedef enum SC_PERFCNT_SEL {\n\tSC_SRPS_WINDOW_VALID                             = 0x0,\n\tSC_PSSW_WINDOW_VALID                             = 0x1,\n\tSC_TPQZ_WINDOW_VALID                             = 0x2,\n\tSC_QZQP_WINDOW_VALID                             = 0x3,\n\tSC_TRPK_WINDOW_VALID                             = 0x4,\n\tSC_SRPS_WINDOW_VALID_BUSY                        = 0x5,\n\tSC_PSSW_WINDOW_VALID_BUSY                        = 0x6,\n\tSC_TPQZ_WINDOW_VALID_BUSY                        = 0x7,\n\tSC_QZQP_WINDOW_VALID_BUSY                        = 0x8,\n\tSC_TRPK_WINDOW_VALID_BUSY                        = 0x9,\n\tSC_STARVED_BY_PA                                 = 0xa,\n\tSC_STALLED_BY_PRIMFIFO                           = 0xb,\n\tSC_STALLED_BY_DB_TILE                            = 0xc,\n\tSC_STARVED_BY_DB_TILE                            = 0xd,\n\tSC_STALLED_BY_TILEORDERFIFO                      = 0xe,\n\tSC_STALLED_BY_TILEFIFO                           = 0xf,\n\tSC_STALLED_BY_DB_QUAD                            = 0x10,\n\tSC_STARVED_BY_DB_QUAD                            = 0x11,\n\tSC_STALLED_BY_QUADFIFO                           = 0x12,\n\tSC_STALLED_BY_BCI                                = 0x13,\n\tSC_STALLED_BY_SPI                                = 0x14,\n\tSC_SCISSOR_DISCARD                               = 0x15,\n\tSC_BB_DISCARD                                    = 0x16,\n\tSC_SUPERTILE_COUNT                               = 0x17,\n\tSC_SUPERTILE_PER_PRIM_H0                         = 0x18,\n\tSC_SUPERTILE_PER_PRIM_H1                         = 0x19,\n\tSC_SUPERTILE_PER_PRIM_H2                         = 0x1a,\n\tSC_SUPERTILE_PER_PRIM_H3                         = 0x1b,\n\tSC_SUPERTILE_PER_PRIM_H4                         = 0x1c,\n\tSC_SUPERTILE_PER_PRIM_H5                         = 0x1d,\n\tSC_SUPERTILE_PER_PRIM_H6                         = 0x1e,\n\tSC_SUPERTILE_PER_PRIM_H7                         = 0x1f,\n\tSC_SUPERTILE_PER_PRIM_H8                         = 0x20,\n\tSC_SUPERTILE_PER_PRIM_H9                         = 0x21,\n\tSC_SUPERTILE_PER_PRIM_H10                        = 0x22,\n\tSC_SUPERTILE_PER_PRIM_H11                        = 0x23,\n\tSC_SUPERTILE_PER_PRIM_H12                        = 0x24,\n\tSC_SUPERTILE_PER_PRIM_H13                        = 0x25,\n\tSC_SUPERTILE_PER_PRIM_H14                        = 0x26,\n\tSC_SUPERTILE_PER_PRIM_H15                        = 0x27,\n\tSC_SUPERTILE_PER_PRIM_H16                        = 0x28,\n\tSC_TILE_PER_PRIM_H0                              = 0x29,\n\tSC_TILE_PER_PRIM_H1                              = 0x2a,\n\tSC_TILE_PER_PRIM_H2                              = 0x2b,\n\tSC_TILE_PER_PRIM_H3                              = 0x2c,\n\tSC_TILE_PER_PRIM_H4                              = 0x2d,\n\tSC_TILE_PER_PRIM_H5                              = 0x2e,\n\tSC_TILE_PER_PRIM_H6                              = 0x2f,\n\tSC_TILE_PER_PRIM_H7                              = 0x30,\n\tSC_TILE_PER_PRIM_H8                              = 0x31,\n\tSC_TILE_PER_PRIM_H9                              = 0x32,\n\tSC_TILE_PER_PRIM_H10                             = 0x33,\n\tSC_TILE_PER_PRIM_H11                             = 0x34,\n\tSC_TILE_PER_PRIM_H12                             = 0x35,\n\tSC_TILE_PER_PRIM_H13                             = 0x36,\n\tSC_TILE_PER_PRIM_H14                             = 0x37,\n\tSC_TILE_PER_PRIM_H15                             = 0x38,\n\tSC_TILE_PER_PRIM_H16                             = 0x39,\n\tSC_TILE_PER_SUPERTILE_H0                         = 0x3a,\n\tSC_TILE_PER_SUPERTILE_H1                         = 0x3b,\n\tSC_TILE_PER_SUPERTILE_H2                         = 0x3c,\n\tSC_TILE_PER_SUPERTILE_H3                         = 0x3d,\n\tSC_TILE_PER_SUPERTILE_H4                         = 0x3e,\n\tSC_TILE_PER_SUPERTILE_H5                         = 0x3f,\n\tSC_TILE_PER_SUPERTILE_H6                         = 0x40,\n\tSC_TILE_PER_SUPERTILE_H7                         = 0x41,\n\tSC_TILE_PER_SUPERTILE_H8                         = 0x42,\n\tSC_TILE_PER_SUPERTILE_H9                         = 0x43,\n\tSC_TILE_PER_SUPERTILE_H10                        = 0x44,\n\tSC_TILE_PER_SUPERTILE_H11                        = 0x45,\n\tSC_TILE_PER_SUPERTILE_H12                        = 0x46,\n\tSC_TILE_PER_SUPERTILE_H13                        = 0x47,\n\tSC_TILE_PER_SUPERTILE_H14                        = 0x48,\n\tSC_TILE_PER_SUPERTILE_H15                        = 0x49,\n\tSC_TILE_PER_SUPERTILE_H16                        = 0x4a,\n\tSC_TILE_PICKED_H1                                = 0x4b,\n\tSC_TILE_PICKED_H2                                = 0x4c,\n\tSC_TILE_PICKED_H3                                = 0x4d,\n\tSC_TILE_PICKED_H4                                = 0x4e,\n\tSC_QZ0_MULTI_GPU_TILE_DISCARD                    = 0x4f,\n\tSC_QZ1_MULTI_GPU_TILE_DISCARD                    = 0x50,\n\tSC_QZ2_MULTI_GPU_TILE_DISCARD                    = 0x51,\n\tSC_QZ3_MULTI_GPU_TILE_DISCARD                    = 0x52,\n\tSC_QZ0_TILE_COUNT                                = 0x53,\n\tSC_QZ1_TILE_COUNT                                = 0x54,\n\tSC_QZ2_TILE_COUNT                                = 0x55,\n\tSC_QZ3_TILE_COUNT                                = 0x56,\n\tSC_QZ0_TILE_COVERED_COUNT                        = 0x57,\n\tSC_QZ1_TILE_COVERED_COUNT                        = 0x58,\n\tSC_QZ2_TILE_COVERED_COUNT                        = 0x59,\n\tSC_QZ3_TILE_COVERED_COUNT                        = 0x5a,\n\tSC_QZ0_TILE_NOT_COVERED_COUNT                    = 0x5b,\n\tSC_QZ1_TILE_NOT_COVERED_COUNT                    = 0x5c,\n\tSC_QZ2_TILE_NOT_COVERED_COUNT                    = 0x5d,\n\tSC_QZ3_TILE_NOT_COVERED_COUNT                    = 0x5e,\n\tSC_QZ0_QUAD_PER_TILE_H0                          = 0x5f,\n\tSC_QZ0_QUAD_PER_TILE_H1                          = 0x60,\n\tSC_QZ0_QUAD_PER_TILE_H2                          = 0x61,\n\tSC_QZ0_QUAD_PER_TILE_H3                          = 0x62,\n\tSC_QZ0_QUAD_PER_TILE_H4                          = 0x63,\n\tSC_QZ0_QUAD_PER_TILE_H5                          = 0x64,\n\tSC_QZ0_QUAD_PER_TILE_H6                          = 0x65,\n\tSC_QZ0_QUAD_PER_TILE_H7                          = 0x66,\n\tSC_QZ0_QUAD_PER_TILE_H8                          = 0x67,\n\tSC_QZ0_QUAD_PER_TILE_H9                          = 0x68,\n\tSC_QZ0_QUAD_PER_TILE_H10                         = 0x69,\n\tSC_QZ0_QUAD_PER_TILE_H11                         = 0x6a,\n\tSC_QZ0_QUAD_PER_TILE_H12                         = 0x6b,\n\tSC_QZ0_QUAD_PER_TILE_H13                         = 0x6c,\n\tSC_QZ0_QUAD_PER_TILE_H14                         = 0x6d,\n\tSC_QZ0_QUAD_PER_TILE_H15                         = 0x6e,\n\tSC_QZ0_QUAD_PER_TILE_H16                         = 0x6f,\n\tSC_QZ1_QUAD_PER_TILE_H0                          = 0x70,\n\tSC_QZ1_QUAD_PER_TILE_H1                          = 0x71,\n\tSC_QZ1_QUAD_PER_TILE_H2                          = 0x72,\n\tSC_QZ1_QUAD_PER_TILE_H3                          = 0x73,\n\tSC_QZ1_QUAD_PER_TILE_H4                          = 0x74,\n\tSC_QZ1_QUAD_PER_TILE_H5                          = 0x75,\n\tSC_QZ1_QUAD_PER_TILE_H6                          = 0x76,\n\tSC_QZ1_QUAD_PER_TILE_H7                          = 0x77,\n\tSC_QZ1_QUAD_PER_TILE_H8                          = 0x78,\n\tSC_QZ1_QUAD_PER_TILE_H9                          = 0x79,\n\tSC_QZ1_QUAD_PER_TILE_H10                         = 0x7a,\n\tSC_QZ1_QUAD_PER_TILE_H11                         = 0x7b,\n\tSC_QZ1_QUAD_PER_TILE_H12                         = 0x7c,\n\tSC_QZ1_QUAD_PER_TILE_H13                         = 0x7d,\n\tSC_QZ1_QUAD_PER_TILE_H14                         = 0x7e,\n\tSC_QZ1_QUAD_PER_TILE_H15                         = 0x7f,\n\tSC_QZ1_QUAD_PER_TILE_H16                         = 0x80,\n\tSC_QZ2_QUAD_PER_TILE_H0                          = 0x81,\n\tSC_QZ2_QUAD_PER_TILE_H1                          = 0x82,\n\tSC_QZ2_QUAD_PER_TILE_H2                          = 0x83,\n\tSC_QZ2_QUAD_PER_TILE_H3                          = 0x84,\n\tSC_QZ2_QUAD_PER_TILE_H4                          = 0x85,\n\tSC_QZ2_QUAD_PER_TILE_H5                          = 0x86,\n\tSC_QZ2_QUAD_PER_TILE_H6                          = 0x87,\n\tSC_QZ2_QUAD_PER_TILE_H7                          = 0x88,\n\tSC_QZ2_QUAD_PER_TILE_H8                          = 0x89,\n\tSC_QZ2_QUAD_PER_TILE_H9                          = 0x8a,\n\tSC_QZ2_QUAD_PER_TILE_H10                         = 0x8b,\n\tSC_QZ2_QUAD_PER_TILE_H11                         = 0x8c,\n\tSC_QZ2_QUAD_PER_TILE_H12                         = 0x8d,\n\tSC_QZ2_QUAD_PER_TILE_H13                         = 0x8e,\n\tSC_QZ2_QUAD_PER_TILE_H14                         = 0x8f,\n\tSC_QZ2_QUAD_PER_TILE_H15                         = 0x90,\n\tSC_QZ2_QUAD_PER_TILE_H16                         = 0x91,\n\tSC_QZ3_QUAD_PER_TILE_H0                          = 0x92,\n\tSC_QZ3_QUAD_PER_TILE_H1                          = 0x93,\n\tSC_QZ3_QUAD_PER_TILE_H2                          = 0x94,\n\tSC_QZ3_QUAD_PER_TILE_H3                          = 0x95,\n\tSC_QZ3_QUAD_PER_TILE_H4                          = 0x96,\n\tSC_QZ3_QUAD_PER_TILE_H5                          = 0x97,\n\tSC_QZ3_QUAD_PER_TILE_H6                          = 0x98,\n\tSC_QZ3_QUAD_PER_TILE_H7                          = 0x99,\n\tSC_QZ3_QUAD_PER_TILE_H8                          = 0x9a,\n\tSC_QZ3_QUAD_PER_TILE_H9                          = 0x9b,\n\tSC_QZ3_QUAD_PER_TILE_H10                         = 0x9c,\n\tSC_QZ3_QUAD_PER_TILE_H11                         = 0x9d,\n\tSC_QZ3_QUAD_PER_TILE_H12                         = 0x9e,\n\tSC_QZ3_QUAD_PER_TILE_H13                         = 0x9f,\n\tSC_QZ3_QUAD_PER_TILE_H14                         = 0xa0,\n\tSC_QZ3_QUAD_PER_TILE_H15                         = 0xa1,\n\tSC_QZ3_QUAD_PER_TILE_H16                         = 0xa2,\n\tSC_QZ0_QUAD_COUNT                                = 0xa3,\n\tSC_QZ1_QUAD_COUNT                                = 0xa4,\n\tSC_QZ2_QUAD_COUNT                                = 0xa5,\n\tSC_QZ3_QUAD_COUNT                                = 0xa6,\n\tSC_P0_HIZ_TILE_COUNT                             = 0xa7,\n\tSC_P1_HIZ_TILE_COUNT                             = 0xa8,\n\tSC_P2_HIZ_TILE_COUNT                             = 0xa9,\n\tSC_P3_HIZ_TILE_COUNT                             = 0xaa,\n\tSC_P0_HIZ_QUAD_PER_TILE_H0                       = 0xab,\n\tSC_P0_HIZ_QUAD_PER_TILE_H1                       = 0xac,\n\tSC_P0_HIZ_QUAD_PER_TILE_H2                       = 0xad,\n\tSC_P0_HIZ_QUAD_PER_TILE_H3                       = 0xae,\n\tSC_P0_HIZ_QUAD_PER_TILE_H4                       = 0xaf,\n\tSC_P0_HIZ_QUAD_PER_TILE_H5                       = 0xb0,\n\tSC_P0_HIZ_QUAD_PER_TILE_H6                       = 0xb1,\n\tSC_P0_HIZ_QUAD_PER_TILE_H7                       = 0xb2,\n\tSC_P0_HIZ_QUAD_PER_TILE_H8                       = 0xb3,\n\tSC_P0_HIZ_QUAD_PER_TILE_H9                       = 0xb4,\n\tSC_P0_HIZ_QUAD_PER_TILE_H10                      = 0xb5,\n\tSC_P0_HIZ_QUAD_PER_TILE_H11                      = 0xb6,\n\tSC_P0_HIZ_QUAD_PER_TILE_H12                      = 0xb7,\n\tSC_P0_HIZ_QUAD_PER_TILE_H13                      = 0xb8,\n\tSC_P0_HIZ_QUAD_PER_TILE_H14                      = 0xb9,\n\tSC_P0_HIZ_QUAD_PER_TILE_H15                      = 0xba,\n\tSC_P0_HIZ_QUAD_PER_TILE_H16                      = 0xbb,\n\tSC_P1_HIZ_QUAD_PER_TILE_H0                       = 0xbc,\n\tSC_P1_HIZ_QUAD_PER_TILE_H1                       = 0xbd,\n\tSC_P1_HIZ_QUAD_PER_TILE_H2                       = 0xbe,\n\tSC_P1_HIZ_QUAD_PER_TILE_H3                       = 0xbf,\n\tSC_P1_HIZ_QUAD_PER_TILE_H4                       = 0xc0,\n\tSC_P1_HIZ_QUAD_PER_TILE_H5                       = 0xc1,\n\tSC_P1_HIZ_QUAD_PER_TILE_H6                       = 0xc2,\n\tSC_P1_HIZ_QUAD_PER_TILE_H7                       = 0xc3,\n\tSC_P1_HIZ_QUAD_PER_TILE_H8                       = 0xc4,\n\tSC_P1_HIZ_QUAD_PER_TILE_H9                       = 0xc5,\n\tSC_P1_HIZ_QUAD_PER_TILE_H10                      = 0xc6,\n\tSC_P1_HIZ_QUAD_PER_TILE_H11                      = 0xc7,\n\tSC_P1_HIZ_QUAD_PER_TILE_H12                      = 0xc8,\n\tSC_P1_HIZ_QUAD_PER_TILE_H13                      = 0xc9,\n\tSC_P1_HIZ_QUAD_PER_TILE_H14                      = 0xca,\n\tSC_P1_HIZ_QUAD_PER_TILE_H15                      = 0xcb,\n\tSC_P1_HIZ_QUAD_PER_TILE_H16                      = 0xcc,\n\tSC_P2_HIZ_QUAD_PER_TILE_H0                       = 0xcd,\n\tSC_P2_HIZ_QUAD_PER_TILE_H1                       = 0xce,\n\tSC_P2_HIZ_QUAD_PER_TILE_H2                       = 0xcf,\n\tSC_P2_HIZ_QUAD_PER_TILE_H3                       = 0xd0,\n\tSC_P2_HIZ_QUAD_PER_TILE_H4                       = 0xd1,\n\tSC_P2_HIZ_QUAD_PER_TILE_H5                       = 0xd2,\n\tSC_P2_HIZ_QUAD_PER_TILE_H6                       = 0xd3,\n\tSC_P2_HIZ_QUAD_PER_TILE_H7                       = 0xd4,\n\tSC_P2_HIZ_QUAD_PER_TILE_H8                       = 0xd5,\n\tSC_P2_HIZ_QUAD_PER_TILE_H9                       = 0xd6,\n\tSC_P2_HIZ_QUAD_PER_TILE_H10                      = 0xd7,\n\tSC_P2_HIZ_QUAD_PER_TILE_H11                      = 0xd8,\n\tSC_P2_HIZ_QUAD_PER_TILE_H12                      = 0xd9,\n\tSC_P2_HIZ_QUAD_PER_TILE_H13                      = 0xda,\n\tSC_P2_HIZ_QUAD_PER_TILE_H14                      = 0xdb,\n\tSC_P2_HIZ_QUAD_PER_TILE_H15                      = 0xdc,\n\tSC_P2_HIZ_QUAD_PER_TILE_H16                      = 0xdd,\n\tSC_P3_HIZ_QUAD_PER_TILE_H0                       = 0xde,\n\tSC_P3_HIZ_QUAD_PER_TILE_H1                       = 0xdf,\n\tSC_P3_HIZ_QUAD_PER_TILE_H2                       = 0xe0,\n\tSC_P3_HIZ_QUAD_PER_TILE_H3                       = 0xe1,\n\tSC_P3_HIZ_QUAD_PER_TILE_H4                       = 0xe2,\n\tSC_P3_HIZ_QUAD_PER_TILE_H5                       = 0xe3,\n\tSC_P3_HIZ_QUAD_PER_TILE_H6                       = 0xe4,\n\tSC_P3_HIZ_QUAD_PER_TILE_H7                       = 0xe5,\n\tSC_P3_HIZ_QUAD_PER_TILE_H8                       = 0xe6,\n\tSC_P3_HIZ_QUAD_PER_TILE_H9                       = 0xe7,\n\tSC_P3_HIZ_QUAD_PER_TILE_H10                      = 0xe8,\n\tSC_P3_HIZ_QUAD_PER_TILE_H11                      = 0xe9,\n\tSC_P3_HIZ_QUAD_PER_TILE_H12                      = 0xea,\n\tSC_P3_HIZ_QUAD_PER_TILE_H13                      = 0xeb,\n\tSC_P3_HIZ_QUAD_PER_TILE_H14                      = 0xec,\n\tSC_P3_HIZ_QUAD_PER_TILE_H15                      = 0xed,\n\tSC_P3_HIZ_QUAD_PER_TILE_H16                      = 0xee,\n\tSC_P0_HIZ_QUAD_COUNT                             = 0xef,\n\tSC_P1_HIZ_QUAD_COUNT                             = 0xf0,\n\tSC_P2_HIZ_QUAD_COUNT                             = 0xf1,\n\tSC_P3_HIZ_QUAD_COUNT                             = 0xf2,\n\tSC_P0_DETAIL_QUAD_COUNT                          = 0xf3,\n\tSC_P1_DETAIL_QUAD_COUNT                          = 0xf4,\n\tSC_P2_DETAIL_QUAD_COUNT                          = 0xf5,\n\tSC_P3_DETAIL_QUAD_COUNT                          = 0xf6,\n\tSC_P0_DETAIL_QUAD_WITH_1_PIX                     = 0xf7,\n\tSC_P0_DETAIL_QUAD_WITH_2_PIX                     = 0xf8,\n\tSC_P0_DETAIL_QUAD_WITH_3_PIX                     = 0xf9,\n\tSC_P0_DETAIL_QUAD_WITH_4_PIX                     = 0xfa,\n\tSC_P1_DETAIL_QUAD_WITH_1_PIX                     = 0xfb,\n\tSC_P1_DETAIL_QUAD_WITH_2_PIX                     = 0xfc,\n\tSC_P1_DETAIL_QUAD_WITH_3_PIX                     = 0xfd,\n\tSC_P1_DETAIL_QUAD_WITH_4_PIX                     = 0xfe,\n\tSC_P2_DETAIL_QUAD_WITH_1_PIX                     = 0xff,\n\tSC_P2_DETAIL_QUAD_WITH_2_PIX                     = 0x100,\n\tSC_P2_DETAIL_QUAD_WITH_3_PIX                     = 0x101,\n\tSC_P2_DETAIL_QUAD_WITH_4_PIX                     = 0x102,\n\tSC_P3_DETAIL_QUAD_WITH_1_PIX                     = 0x103,\n\tSC_P3_DETAIL_QUAD_WITH_2_PIX                     = 0x104,\n\tSC_P3_DETAIL_QUAD_WITH_3_PIX                     = 0x105,\n\tSC_P3_DETAIL_QUAD_WITH_4_PIX                     = 0x106,\n\tSC_EARLYZ_QUAD_COUNT                             = 0x107,\n\tSC_EARLYZ_QUAD_WITH_1_PIX                        = 0x108,\n\tSC_EARLYZ_QUAD_WITH_2_PIX                        = 0x109,\n\tSC_EARLYZ_QUAD_WITH_3_PIX                        = 0x10a,\n\tSC_EARLYZ_QUAD_WITH_4_PIX                        = 0x10b,\n\tSC_PKR_QUAD_PER_ROW_H1                           = 0x10c,\n\tSC_PKR_QUAD_PER_ROW_H2                           = 0x10d,\n\tSC_PKR_QUAD_PER_ROW_H3                           = 0x10e,\n\tSC_PKR_QUAD_PER_ROW_H4                           = 0x10f,\n\tSC_PKR_END_OF_VECTOR                             = 0x110,\n\tSC_PKR_CONTROL_XFER                              = 0x111,\n\tSC_PKR_DBHANG_FORCE_EOV                          = 0x112,\n\tSC_REG_SCLK_BUSY                                 = 0x113,\n\tSC_GRP0_DYN_SCLK_BUSY                            = 0x114,\n\tSC_GRP1_DYN_SCLK_BUSY                            = 0x115,\n\tSC_GRP2_DYN_SCLK_BUSY                            = 0x116,\n\tSC_GRP3_DYN_SCLK_BUSY                            = 0x117,\n\tSC_GRP4_DYN_SCLK_BUSY                            = 0x118,\n\tSC_PA0_SC_DATA_FIFO_RD                           = 0x119,\n\tSC_PA0_SC_DATA_FIFO_WE                           = 0x11a,\n\tSC_PA1_SC_DATA_FIFO_RD                           = 0x11b,\n\tSC_PA1_SC_DATA_FIFO_WE                           = 0x11c,\n\tSC_PS_ARB_XFC_ALL_EVENT_OR_PRIM_CYCLES           = 0x11d,\n\tSC_PS_ARB_XFC_ONLY_PRIM_CYCLES                   = 0x11e,\n\tSC_PS_ARB_XFC_ONLY_ONE_INC_PER_PRIM              = 0x11f,\n\tSC_PS_ARB_STALLED_FROM_BELOW                     = 0x120,\n\tSC_PS_ARB_STARVED_FROM_ABOVE                     = 0x121,\n\tSC_PS_ARB_SC_BUSY                                = 0x122,\n\tSC_PS_ARB_PA_SC_BUSY                             = 0x123,\n\tSC_PA2_SC_DATA_FIFO_RD                           = 0x124,\n\tSC_PA2_SC_DATA_FIFO_WE                           = 0x125,\n\tSC_PA3_SC_DATA_FIFO_RD                           = 0x126,\n\tSC_PA3_SC_DATA_FIFO_WE                           = 0x127,\n\tSC_PA_SC_DEALLOC_0_0_WE                          = 0x128,\n\tSC_PA_SC_DEALLOC_0_1_WE                          = 0x129,\n\tSC_PA_SC_DEALLOC_1_0_WE                          = 0x12a,\n\tSC_PA_SC_DEALLOC_1_1_WE                          = 0x12b,\n\tSC_PA_SC_DEALLOC_2_0_WE                          = 0x12c,\n\tSC_PA_SC_DEALLOC_2_1_WE                          = 0x12d,\n\tSC_PA_SC_DEALLOC_3_0_WE                          = 0x12e,\n\tSC_PA_SC_DEALLOC_3_1_WE                          = 0x12f,\n\tSC_PA0_SC_EOP_WE                                 = 0x130,\n\tSC_PA0_SC_EOPG_WE                                = 0x131,\n\tSC_PA0_SC_EVENT_WE                               = 0x132,\n\tSC_PA1_SC_EOP_WE                                 = 0x133,\n\tSC_PA1_SC_EOPG_WE                                = 0x134,\n\tSC_PA1_SC_EVENT_WE                               = 0x135,\n\tSC_PA2_SC_EOP_WE                                 = 0x136,\n\tSC_PA2_SC_EOPG_WE                                = 0x137,\n\tSC_PA2_SC_EVENT_WE                               = 0x138,\n\tSC_PA3_SC_EOP_WE                                 = 0x139,\n\tSC_PA3_SC_EOPG_WE                                = 0x13a,\n\tSC_PA3_SC_EVENT_WE                               = 0x13b,\n\tSC_PS_ARB_OOO_THRESHOLD_SWITCH_TO_DESIRED_FIFO   = 0x13c,\n\tSC_PS_ARB_OOO_FIFO_EMPTY_SWITCH                  = 0x13d,\n\tSC_PS_ARB_NULL_PRIM_BUBBLE_POP                   = 0x13e,\n\tSC_PS_ARB_EOP_POP_SYNC_POP                       = 0x13f,\n\tSC_PS_ARB_EVENT_SYNC_POP                         = 0x140,\n\tSC_SC_PS_ENG_MULTICYCLE_BUBBLE                   = 0x141,\n\tSC_PA0_SC_FPOV_WE                                = 0x142,\n\tSC_PA1_SC_FPOV_WE                                = 0x143,\n\tSC_PA2_SC_FPOV_WE                                = 0x144,\n\tSC_PA3_SC_FPOV_WE                                = 0x145,\n\tSC_PA0_SC_LPOV_WE                                = 0x146,\n\tSC_PA1_SC_LPOV_WE                                = 0x147,\n\tSC_PA2_SC_LPOV_WE                                = 0x148,\n\tSC_PA3_SC_LPOV_WE                                = 0x149,\n\tSC_SC_SPI_DEALLOC_0_0                            = 0x14a,\n\tSC_SC_SPI_DEALLOC_0_1                            = 0x14b,\n\tSC_SC_SPI_DEALLOC_0_2                            = 0x14c,\n\tSC_SC_SPI_DEALLOC_1_0                            = 0x14d,\n\tSC_SC_SPI_DEALLOC_1_1                            = 0x14e,\n\tSC_SC_SPI_DEALLOC_1_2                            = 0x14f,\n\tSC_SC_SPI_DEALLOC_2_0                            = 0x150,\n\tSC_SC_SPI_DEALLOC_2_1                            = 0x151,\n\tSC_SC_SPI_DEALLOC_2_2                            = 0x152,\n\tSC_SC_SPI_DEALLOC_3_0                            = 0x153,\n\tSC_SC_SPI_DEALLOC_3_1                            = 0x154,\n\tSC_SC_SPI_DEALLOC_3_2                            = 0x155,\n\tSC_SC_SPI_FPOV_0                                 = 0x156,\n\tSC_SC_SPI_FPOV_1                                 = 0x157,\n\tSC_SC_SPI_FPOV_2                                 = 0x158,\n\tSC_SC_SPI_FPOV_3                                 = 0x159,\n\tSC_SC_SPI_EVENT                                  = 0x15a,\n\tSC_PS_TS_EVENT_FIFO_PUSH                         = 0x15b,\n\tSC_PS_TS_EVENT_FIFO_POP                          = 0x15c,\n\tSC_PS_CTX_DONE_FIFO_PUSH                         = 0x15d,\n\tSC_PS_CTX_DONE_FIFO_POP                          = 0x15e,\n\tSC_MULTICYCLE_BUBBLE_FREEZE                      = 0x15f,\n\tSC_EOP_SYNC_WINDOW                               = 0x160,\n\tSC_PA0_SC_NULL_WE                                = 0x161,\n\tSC_PA0_SC_NULL_DEALLOC_WE                        = 0x162,\n\tSC_PA0_SC_DATA_FIFO_EOPG_RD                      = 0x163,\n\tSC_PA0_SC_DATA_FIFO_EOP_RD                       = 0x164,\n\tSC_PA0_SC_DEALLOC_0_RD                           = 0x165,\n\tSC_PA0_SC_DEALLOC_1_RD                           = 0x166,\n\tSC_PA1_SC_DATA_FIFO_EOPG_RD                      = 0x167,\n\tSC_PA1_SC_DATA_FIFO_EOP_RD                       = 0x168,\n\tSC_PA1_SC_DEALLOC_0_RD                           = 0x169,\n\tSC_PA1_SC_DEALLOC_1_RD                           = 0x16a,\n\tSC_PA1_SC_NULL_WE                                = 0x16b,\n\tSC_PA1_SC_NULL_DEALLOC_WE                        = 0x16c,\n\tSC_PA2_SC_DATA_FIFO_EOPG_RD                      = 0x16d,\n\tSC_PA2_SC_DATA_FIFO_EOP_RD                       = 0x16e,\n\tSC_PA2_SC_DEALLOC_0_RD                           = 0x16f,\n\tSC_PA2_SC_DEALLOC_1_RD                           = 0x170,\n\tSC_PA2_SC_NULL_WE                                = 0x171,\n\tSC_PA2_SC_NULL_DEALLOC_WE                        = 0x172,\n\tSC_PA3_SC_DATA_FIFO_EOPG_RD                      = 0x173,\n\tSC_PA3_SC_DATA_FIFO_EOP_RD                       = 0x174,\n\tSC_PA3_SC_DEALLOC_0_RD                           = 0x175,\n\tSC_PA3_SC_DEALLOC_1_RD                           = 0x176,\n\tSC_PA3_SC_NULL_WE                                = 0x177,\n\tSC_PA3_SC_NULL_DEALLOC_WE                        = 0x178,\n\tSC_PS_PA0_SC_FIFO_EMPTY                          = 0x179,\n\tSC_PS_PA0_SC_FIFO_FULL                           = 0x17a,\n\tSC_PA0_PS_DATA_SEND                              = 0x17b,\n\tSC_PS_PA1_SC_FIFO_EMPTY                          = 0x17c,\n\tSC_PS_PA1_SC_FIFO_FULL                           = 0x17d,\n\tSC_PA1_PS_DATA_SEND                              = 0x17e,\n\tSC_PS_PA2_SC_FIFO_EMPTY                          = 0x17f,\n\tSC_PS_PA2_SC_FIFO_FULL                           = 0x180,\n\tSC_PA2_PS_DATA_SEND                              = 0x181,\n\tSC_PS_PA3_SC_FIFO_EMPTY                          = 0x182,\n\tSC_PS_PA3_SC_FIFO_FULL                           = 0x183,\n\tSC_PA3_PS_DATA_SEND                              = 0x184,\n\tSC_BUSY_PROCESSING_MULTICYCLE_PRIM               = 0x185,\n\tSC_BUSY_CNT_NOT_ZERO                             = 0x186,\n\tSC_BM_BUSY                                       = 0x187,\n\tSC_BACKEND_BUSY                                  = 0x188,\n\tSC_SCF_SCB_INTERFACE_BUSY                        = 0x189,\n\tSC_SCB_BUSY                                      = 0x18a,\n} SC_PERFCNT_SEL;\ntypedef enum SePairXsel {\n\tRASTER_CONFIG_SE_PAIR_XSEL_8_WIDE_TILE           = 0x0,\n\tRASTER_CONFIG_SE_PAIR_XSEL_16_WIDE_TILE          = 0x1,\n\tRASTER_CONFIG_SE_PAIR_XSEL_32_WIDE_TILE          = 0x2,\n\tRASTER_CONFIG_SE_PAIR_XSEL_64_WIDE_TILE          = 0x3,\n} SePairXsel;\ntypedef enum SePairYsel {\n\tRASTER_CONFIG_SE_PAIR_YSEL_8_WIDE_TILE           = 0x0,\n\tRASTER_CONFIG_SE_PAIR_YSEL_16_WIDE_TILE          = 0x1,\n\tRASTER_CONFIG_SE_PAIR_YSEL_32_WIDE_TILE          = 0x2,\n\tRASTER_CONFIG_SE_PAIR_YSEL_64_WIDE_TILE          = 0x3,\n} SePairYsel;\ntypedef enum SePairMap {\n\tRASTER_CONFIG_SE_PAIR_MAP_0                      = 0x0,\n\tRASTER_CONFIG_SE_PAIR_MAP_1                      = 0x1,\n\tRASTER_CONFIG_SE_PAIR_MAP_2                      = 0x2,\n\tRASTER_CONFIG_SE_PAIR_MAP_3                      = 0x3,\n} SePairMap;\ntypedef enum SeXsel {\n\tRASTER_CONFIG_SE_XSEL_8_WIDE_TILE                = 0x0,\n\tRASTER_CONFIG_SE_XSEL_16_WIDE_TILE               = 0x1,\n\tRASTER_CONFIG_SE_XSEL_32_WIDE_TILE               = 0x2,\n\tRASTER_CONFIG_SE_XSEL_64_WIDE_TILE               = 0x3,\n} SeXsel;\ntypedef enum SeYsel {\n\tRASTER_CONFIG_SE_YSEL_8_WIDE_TILE                = 0x0,\n\tRASTER_CONFIG_SE_YSEL_16_WIDE_TILE               = 0x1,\n\tRASTER_CONFIG_SE_YSEL_32_WIDE_TILE               = 0x2,\n\tRASTER_CONFIG_SE_YSEL_64_WIDE_TILE               = 0x3,\n} SeYsel;\ntypedef enum SeMap {\n\tRASTER_CONFIG_SE_MAP_0                           = 0x0,\n\tRASTER_CONFIG_SE_MAP_1                           = 0x1,\n\tRASTER_CONFIG_SE_MAP_2                           = 0x2,\n\tRASTER_CONFIG_SE_MAP_3                           = 0x3,\n} SeMap;\ntypedef enum ScXsel {\n\tRASTER_CONFIG_SC_XSEL_8_WIDE_TILE                = 0x0,\n\tRASTER_CONFIG_SC_XSEL_16_WIDE_TILE               = 0x1,\n\tRASTER_CONFIG_SC_XSEL_32_WIDE_TILE               = 0x2,\n\tRASTER_CONFIG_SC_XSEL_64_WIDE_TILE               = 0x3,\n} ScXsel;\ntypedef enum ScYsel {\n\tRASTER_CONFIG_SC_YSEL_8_WIDE_TILE                = 0x0,\n\tRASTER_CONFIG_SC_YSEL_16_WIDE_TILE               = 0x1,\n\tRASTER_CONFIG_SC_YSEL_32_WIDE_TILE               = 0x2,\n\tRASTER_CONFIG_SC_YSEL_64_WIDE_TILE               = 0x3,\n} ScYsel;\ntypedef enum ScMap {\n\tRASTER_CONFIG_SC_MAP_0                           = 0x0,\n\tRASTER_CONFIG_SC_MAP_1                           = 0x1,\n\tRASTER_CONFIG_SC_MAP_2                           = 0x2,\n\tRASTER_CONFIG_SC_MAP_3                           = 0x3,\n} ScMap;\ntypedef enum PkrXsel2 {\n\tRASTER_CONFIG_PKR_XSEL2_0                        = 0x0,\n\tRASTER_CONFIG_PKR_XSEL2_1                        = 0x1,\n\tRASTER_CONFIG_PKR_XSEL2_2                        = 0x2,\n\tRASTER_CONFIG_PKR_XSEL2_3                        = 0x3,\n} PkrXsel2;\ntypedef enum PkrXsel {\n\tRASTER_CONFIG_PKR_XSEL_0                         = 0x0,\n\tRASTER_CONFIG_PKR_XSEL_1                         = 0x1,\n\tRASTER_CONFIG_PKR_XSEL_2                         = 0x2,\n\tRASTER_CONFIG_PKR_XSEL_3                         = 0x3,\n} PkrXsel;\ntypedef enum PkrYsel {\n\tRASTER_CONFIG_PKR_YSEL_0                         = 0x0,\n\tRASTER_CONFIG_PKR_YSEL_1                         = 0x1,\n\tRASTER_CONFIG_PKR_YSEL_2                         = 0x2,\n\tRASTER_CONFIG_PKR_YSEL_3                         = 0x3,\n} PkrYsel;\ntypedef enum PkrMap {\n\tRASTER_CONFIG_PKR_MAP_0                          = 0x0,\n\tRASTER_CONFIG_PKR_MAP_1                          = 0x1,\n\tRASTER_CONFIG_PKR_MAP_2                          = 0x2,\n\tRASTER_CONFIG_PKR_MAP_3                          = 0x3,\n} PkrMap;\ntypedef enum RbXsel {\n\tRASTER_CONFIG_RB_XSEL_0                          = 0x0,\n\tRASTER_CONFIG_RB_XSEL_1                          = 0x1,\n} RbXsel;\ntypedef enum RbYsel {\n\tRASTER_CONFIG_RB_YSEL_0                          = 0x0,\n\tRASTER_CONFIG_RB_YSEL_1                          = 0x1,\n} RbYsel;\ntypedef enum RbXsel2 {\n\tRASTER_CONFIG_RB_XSEL2_0                         = 0x0,\n\tRASTER_CONFIG_RB_XSEL2_1                         = 0x1,\n\tRASTER_CONFIG_RB_XSEL2_2                         = 0x2,\n\tRASTER_CONFIG_RB_XSEL2_3                         = 0x3,\n} RbXsel2;\ntypedef enum RbMap {\n\tRASTER_CONFIG_RB_MAP_0                           = 0x0,\n\tRASTER_CONFIG_RB_MAP_1                           = 0x1,\n\tRASTER_CONFIG_RB_MAP_2                           = 0x2,\n\tRASTER_CONFIG_RB_MAP_3                           = 0x3,\n} RbMap;\ntypedef enum CSDATA_TYPE {\n\tCSDATA_TYPE_TG                                   = 0x0,\n\tCSDATA_TYPE_STATE                                = 0x1,\n\tCSDATA_TYPE_EVENT                                = 0x2,\n\tCSDATA_TYPE_PRIVATE                              = 0x3,\n} CSDATA_TYPE;\n#define CSDATA_TYPE_WIDTH                         0x2\n#define CSDATA_ADDR_WIDTH                         0x7\n#define CSDATA_DATA_WIDTH                         0x20\ntypedef enum SPI_SAMPLE_CNTL {\n\tCENTROIDS_ONLY                                   = 0x0,\n\tCENTERS_ONLY                                     = 0x1,\n\tCENTROIDS_AND_CENTERS                            = 0x2,\n\tUNDEF                                            = 0x3,\n} SPI_SAMPLE_CNTL;\ntypedef enum SPI_FOG_MODE {\n\tSPI_FOG_NONE                                     = 0x0,\n\tSPI_FOG_EXP                                      = 0x1,\n\tSPI_FOG_EXP2                                     = 0x2,\n\tSPI_FOG_LINEAR                                   = 0x3,\n} SPI_FOG_MODE;\ntypedef enum SPI_PNT_SPRITE_OVERRIDE {\n\tSPI_PNT_SPRITE_SEL_0                             = 0x0,\n\tSPI_PNT_SPRITE_SEL_1                             = 0x1,\n\tSPI_PNT_SPRITE_SEL_S                             = 0x2,\n\tSPI_PNT_SPRITE_SEL_T                             = 0x3,\n\tSPI_PNT_SPRITE_SEL_NONE                          = 0x4,\n} SPI_PNT_SPRITE_OVERRIDE;\ntypedef enum SPI_PERFCNT_SEL {\n\tSPI_PERF_VS_WINDOW_VALID                         = 0x0,\n\tSPI_PERF_VS_BUSY                                 = 0x1,\n\tSPI_PERF_VS_FIRST_WAVE                           = 0x2,\n\tSPI_PERF_VS_LAST_WAVE                            = 0x3,\n\tSPI_PERF_VS_LSHS_DEALLOC                         = 0x4,\n\tSPI_PERF_VS_PC_STALL                             = 0x5,\n\tSPI_PERF_VS_POS0_STALL                           = 0x6,\n\tSPI_PERF_VS_POS1_STALL                           = 0x7,\n\tSPI_PERF_VS_CRAWLER_STALL                        = 0x8,\n\tSPI_PERF_VS_EVENT_WAVE                           = 0x9,\n\tSPI_PERF_VS_WAVE                                 = 0xa,\n\tSPI_PERF_VS_PERS_UPD_FULL0                       = 0xb,\n\tSPI_PERF_VS_PERS_UPD_FULL1                       = 0xc,\n\tSPI_PERF_VS_LATE_ALLOC_FULL                      = 0xd,\n\tSPI_PERF_VS_FIRST_SUBGRP                         = 0xe,\n\tSPI_PERF_VS_LAST_SUBGRP                          = 0xf,\n\tSPI_PERF_GS_WINDOW_VALID                         = 0x10,\n\tSPI_PERF_GS_BUSY                                 = 0x11,\n\tSPI_PERF_GS_CRAWLER_STALL                        = 0x12,\n\tSPI_PERF_GS_EVENT_WAVE                           = 0x13,\n\tSPI_PERF_GS_WAVE                                 = 0x14,\n\tSPI_PERF_GS_PERS_UPD_FULL0                       = 0x15,\n\tSPI_PERF_GS_PERS_UPD_FULL1                       = 0x16,\n\tSPI_PERF_GS_FIRST_SUBGRP                         = 0x17,\n\tSPI_PERF_GS_LAST_SUBGRP                          = 0x18,\n\tSPI_PERF_ES_WINDOW_VALID                         = 0x19,\n\tSPI_PERF_ES_BUSY                                 = 0x1a,\n\tSPI_PERF_ES_CRAWLER_STALL                        = 0x1b,\n\tSPI_PERF_ES_FIRST_WAVE                           = 0x1c,\n\tSPI_PERF_ES_LAST_WAVE                            = 0x1d,\n\tSPI_PERF_ES_LSHS_DEALLOC                         = 0x1e,\n\tSPI_PERF_ES_EVENT_WAVE                           = 0x1f,\n\tSPI_PERF_ES_WAVE                                 = 0x20,\n\tSPI_PERF_ES_PERS_UPD_FULL0                       = 0x21,\n\tSPI_PERF_ES_PERS_UPD_FULL1                       = 0x22,\n\tSPI_PERF_ES_FIRST_SUBGRP                         = 0x23,\n\tSPI_PERF_ES_LAST_SUBGRP                          = 0x24,\n\tSPI_PERF_HS_WINDOW_VALID                         = 0x25,\n\tSPI_PERF_HS_BUSY                                 = 0x26,\n\tSPI_PERF_HS_CRAWLER_STALL                        = 0x27,\n\tSPI_PERF_HS_FIRST_WAVE                           = 0x28,\n\tSPI_PERF_HS_LAST_WAVE                            = 0x29,\n\tSPI_PERF_HS_LSHS_DEALLOC                         = 0x2a,\n\tSPI_PERF_HS_EVENT_WAVE                           = 0x2b,\n\tSPI_PERF_HS_WAVE                                 = 0x2c,\n\tSPI_PERF_HS_PERS_UPD_FULL0                       = 0x2d,\n\tSPI_PERF_HS_PERS_UPD_FULL1                       = 0x2e,\n\tSPI_PERF_LS_WINDOW_VALID                         = 0x2f,\n\tSPI_PERF_LS_BUSY                                 = 0x30,\n\tSPI_PERF_LS_CRAWLER_STALL                        = 0x31,\n\tSPI_PERF_LS_FIRST_WAVE                           = 0x32,\n\tSPI_PERF_LS_LAST_WAVE                            = 0x33,\n\tSPI_PERF_OFFCHIP_LDS_STALL_LS                    = 0x34,\n\tSPI_PERF_LS_EVENT_WAVE                           = 0x35,\n\tSPI_PERF_LS_WAVE                                 = 0x36,\n\tSPI_PERF_LS_PERS_UPD_FULL0                       = 0x37,\n\tSPI_PERF_LS_PERS_UPD_FULL1                       = 0x38,\n\tSPI_PERF_CSG_WINDOW_VALID                        = 0x39,\n\tSPI_PERF_CSG_BUSY                                = 0x3a,\n\tSPI_PERF_CSG_NUM_THREADGROUPS                    = 0x3b,\n\tSPI_PERF_CSG_CRAWLER_STALL                       = 0x3c,\n\tSPI_PERF_CSG_EVENT_WAVE                          = 0x3d,\n\tSPI_PERF_CSG_WAVE                                = 0x3e,\n\tSPI_PERF_CSN_WINDOW_VALID                        = 0x3f,\n\tSPI_PERF_CSN_BUSY                                = 0x40,\n\tSPI_PERF_CSN_NUM_THREADGROUPS                    = 0x41,\n\tSPI_PERF_CSN_CRAWLER_STALL                       = 0x42,\n\tSPI_PERF_CSN_EVENT_WAVE                          = 0x43,\n\tSPI_PERF_CSN_WAVE                                = 0x44,\n\tSPI_PERF_PS_CTL_WINDOW_VALID                     = 0x45,\n\tSPI_PERF_PS_CTL_BUSY                             = 0x46,\n\tSPI_PERF_PS_CTL_ACTIVE                           = 0x47,\n\tSPI_PERF_PS_CTL_DEALLOC_BIN0                     = 0x48,\n\tSPI_PERF_PS_CTL_FPOS_BIN1_STALL                  = 0x49,\n\tSPI_PERF_PS_CTL_EVENT_WAVE                       = 0x4a,\n\tSPI_PERF_PS_CTL_WAVE                             = 0x4b,\n\tSPI_PERF_PS_CTL_OPT_WAVE                         = 0x4c,\n\tSPI_PERF_PS_CTL_PASS_BIN0                        = 0x4d,\n\tSPI_PERF_PS_CTL_PASS_BIN1                        = 0x4e,\n\tSPI_PERF_PS_CTL_FPOS_BIN2                        = 0x4f,\n\tSPI_PERF_PS_CTL_PRIM_BIN0                        = 0x50,\n\tSPI_PERF_PS_CTL_PRIM_BIN1                        = 0x51,\n\tSPI_PERF_PS_CTL_CNF_BIN2                         = 0x52,\n\tSPI_PERF_PS_CTL_CNF_BIN3                         = 0x53,\n\tSPI_PERF_PS_CTL_CRAWLER_STALL                    = 0x54,\n\tSPI_PERF_PS_CTL_LDS_RES_FULL                     = 0x55,\n\tSPI_PERF_PS_PERS_UPD_FULL0                       = 0x56,\n\tSPI_PERF_PS_PERS_UPD_FULL1                       = 0x57,\n\tSPI_PERF_PIX_ALLOC_PEND_CNT                      = 0x58,\n\tSPI_PERF_PIX_ALLOC_SCB_STALL                     = 0x59,\n\tSPI_PERF_PIX_ALLOC_DB0_STALL                     = 0x5a,\n\tSPI_PERF_PIX_ALLOC_DB1_STALL                     = 0x5b,\n\tSPI_PERF_PIX_ALLOC_DB2_STALL                     = 0x5c,\n\tSPI_PERF_PIX_ALLOC_DB3_STALL                     = 0x5d,\n\tSPI_PERF_LDS0_PC_VALID                           = 0x5e,\n\tSPI_PERF_LDS1_PC_VALID                           = 0x5f,\n\tSPI_PERF_RA_PIPE_REQ_BIN2                        = 0x60,\n\tSPI_PERF_RA_TASK_REQ_BIN3                        = 0x61,\n\tSPI_PERF_RA_WR_CTL_FULL                          = 0x62,\n\tSPI_PERF_RA_REQ_NO_ALLOC                         = 0x63,\n\tSPI_PERF_RA_REQ_NO_ALLOC_PS                      = 0x64,\n\tSPI_PERF_RA_REQ_NO_ALLOC_VS                      = 0x65,\n\tSPI_PERF_RA_REQ_NO_ALLOC_GS                      = 0x66,\n\tSPI_PERF_RA_REQ_NO_ALLOC_ES                      = 0x67,\n\tSPI_PERF_RA_REQ_NO_ALLOC_HS                      = 0x68,\n\tSPI_PERF_RA_REQ_NO_ALLOC_LS                      = 0x69,\n\tSPI_PERF_RA_REQ_NO_ALLOC_CSG                     = 0x6a,\n\tSPI_PERF_RA_REQ_NO_ALLOC_CSN                     = 0x6b,\n\tSPI_PERF_RA_RES_STALL_PS                         = 0x6c,\n\tSPI_PERF_RA_RES_STALL_VS                         = 0x6d,\n\tSPI_PERF_RA_RES_STALL_GS                         = 0x6e,\n\tSPI_PERF_RA_RES_STALL_ES                         = 0x6f,\n\tSPI_PERF_RA_RES_STALL_HS                         = 0x70,\n\tSPI_PERF_RA_RES_STALL_LS                         = 0x71,\n\tSPI_PERF_RA_RES_STALL_CSG                        = 0x72,\n\tSPI_PERF_RA_RES_STALL_CSN                        = 0x73,\n\tSPI_PERF_RA_TMP_STALL_PS                         = 0x74,\n\tSPI_PERF_RA_TMP_STALL_VS                         = 0x75,\n\tSPI_PERF_RA_TMP_STALL_GS                         = 0x76,\n\tSPI_PERF_RA_TMP_STALL_ES                         = 0x77,\n\tSPI_PERF_RA_TMP_STALL_HS                         = 0x78,\n\tSPI_PERF_RA_TMP_STALL_LS                         = 0x79,\n\tSPI_PERF_RA_TMP_STALL_CSG                        = 0x7a,\n\tSPI_PERF_RA_TMP_STALL_CSN                        = 0x7b,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_PS                    = 0x7c,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_VS                    = 0x7d,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_GS                    = 0x7e,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_ES                    = 0x7f,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_HS                    = 0x80,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_LS                    = 0x81,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_CSG                   = 0x82,\n\tSPI_PERF_RA_WAVE_SIMD_FULL_CSN                   = 0x83,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_PS                    = 0x84,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_VS                    = 0x85,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_GS                    = 0x86,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_ES                    = 0x87,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_HS                    = 0x88,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_LS                    = 0x89,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_CSG                   = 0x8a,\n\tSPI_PERF_RA_VGPR_SIMD_FULL_CSN                   = 0x8b,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_PS                    = 0x8c,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_VS                    = 0x8d,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_GS                    = 0x8e,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_ES                    = 0x8f,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_HS                    = 0x90,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_LS                    = 0x91,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_CSG                   = 0x92,\n\tSPI_PERF_RA_SGPR_SIMD_FULL_CSN                   = 0x93,\n\tSPI_PERF_RA_LDS_CU_FULL_PS                       = 0x94,\n\tSPI_PERF_RA_LDS_CU_FULL_LS                       = 0x95,\n\tSPI_PERF_RA_LDS_CU_FULL_ES                       = 0x96,\n\tSPI_PERF_RA_LDS_CU_FULL_CSG                      = 0x97,\n\tSPI_PERF_RA_LDS_CU_FULL_CSN                      = 0x98,\n\tSPI_PERF_RA_BAR_CU_FULL_HS                       = 0x99,\n\tSPI_PERF_RA_BAR_CU_FULL_CSG                      = 0x9a,\n\tSPI_PERF_RA_BAR_CU_FULL_CSN                      = 0x9b,\n\tSPI_PERF_RA_BULKY_CU_FULL_CSG                    = 0x9c,\n\tSPI_PERF_RA_BULKY_CU_FULL_CSN                    = 0x9d,\n\tSPI_PERF_RA_TGLIM_CU_FULL_CSG                    = 0x9e,\n\tSPI_PERF_RA_TGLIM_CU_FULL_CSN                    = 0x9f,\n\tSPI_PERF_RA_WVLIM_STALL_PS                       = 0xa0,\n\tSPI_PERF_RA_WVLIM_STALL_VS                       = 0xa1,\n\tSPI_PERF_RA_WVLIM_STALL_GS                       = 0xa2,\n\tSPI_PERF_RA_WVLIM_STALL_ES                       = 0xa3,\n\tSPI_PERF_RA_WVLIM_STALL_HS                       = 0xa4,\n\tSPI_PERF_RA_WVLIM_STALL_LS                       = 0xa5,\n\tSPI_PERF_RA_WVLIM_STALL_CSG                      = 0xa6,\n\tSPI_PERF_RA_WVLIM_STALL_CSN                      = 0xa7,\n\tSPI_PERF_RA_PS_LOCK                              = 0xa8,\n\tSPI_PERF_RA_VS_LOCK                              = 0xa9,\n\tSPI_PERF_RA_GS_LOCK                              = 0xaa,\n\tSPI_PERF_RA_ES_LOCK                              = 0xab,\n\tSPI_PERF_RA_HS_LOCK                              = 0xac,\n\tSPI_PERF_RA_LS_LOCK                              = 0xad,\n\tSPI_PERF_RA_CSG_LOCK                             = 0xae,\n\tSPI_PERF_RA_CSN_LOCK                             = 0xaf,\n\tSPI_PERF_RA_RSV_UPD                              = 0xb0,\n\tSPI_PERF_EXP_ARB_COL_CNT                         = 0xb1,\n\tSPI_PERF_EXP_ARB_PAR_CNT                         = 0xb2,\n\tSPI_PERF_EXP_ARB_POS_CNT                         = 0xb3,\n\tSPI_PERF_EXP_ARB_GDS_CNT                         = 0xb4,\n\tSPI_PERF_CLKGATE_BUSY_STALL                      = 0xb5,\n\tSPI_PERF_CLKGATE_ACTIVE_STALL                    = 0xb6,\n\tSPI_PERF_CLKGATE_ALL_CLOCKS_ON                   = 0xb7,\n\tSPI_PERF_CLKGATE_CGTT_DYN_ON                     = 0xb8,\n\tSPI_PERF_CLKGATE_CGTT_REG_ON                     = 0xb9,\n} SPI_PERFCNT_SEL;\ntypedef enum SPI_SHADER_FORMAT {\n\tSPI_SHADER_NONE                                  = 0x0,\n\tSPI_SHADER_1COMP                                 = 0x1,\n\tSPI_SHADER_2COMP                                 = 0x2,\n\tSPI_SHADER_4COMPRESS                             = 0x3,\n\tSPI_SHADER_4COMP                                 = 0x4,\n} SPI_SHADER_FORMAT;\ntypedef enum SPI_SHADER_EX_FORMAT {\n\tSPI_SHADER_ZERO                                  = 0x0,\n\tSPI_SHADER_32_R                                  = 0x1,\n\tSPI_SHADER_32_GR                                 = 0x2,\n\tSPI_SHADER_32_AR                                 = 0x3,\n\tSPI_SHADER_FP16_ABGR                             = 0x4,\n\tSPI_SHADER_UNORM16_ABGR                          = 0x5,\n\tSPI_SHADER_SNORM16_ABGR                          = 0x6,\n\tSPI_SHADER_UINT16_ABGR                           = 0x7,\n\tSPI_SHADER_SINT16_ABGR                           = 0x8,\n\tSPI_SHADER_32_ABGR                               = 0x9,\n} SPI_SHADER_EX_FORMAT;\ntypedef enum CLKGATE_SM_MODE {\n\tON_SEQ                                           = 0x0,\n\tOFF_SEQ                                          = 0x1,\n\tPROG_SEQ                                         = 0x2,\n\tREAD_SEQ                                         = 0x3,\n\tSM_MODE_RESERVED                                 = 0x4,\n} CLKGATE_SM_MODE;\ntypedef enum CLKGATE_BASE_MODE {\n\tMULT_8                                           = 0x0,\n\tMULT_16                                          = 0x1,\n} CLKGATE_BASE_MODE;\ntypedef enum SQ_TEX_CLAMP {\n\tSQ_TEX_WRAP                                      = 0x0,\n\tSQ_TEX_MIRROR                                    = 0x1,\n\tSQ_TEX_CLAMP_LAST_TEXEL                          = 0x2,\n\tSQ_TEX_MIRROR_ONCE_LAST_TEXEL                    = 0x3,\n\tSQ_TEX_CLAMP_HALF_BORDER                         = 0x4,\n\tSQ_TEX_MIRROR_ONCE_HALF_BORDER                   = 0x5,\n\tSQ_TEX_CLAMP_BORDER                              = 0x6,\n\tSQ_TEX_MIRROR_ONCE_BORDER                        = 0x7,\n} SQ_TEX_CLAMP;\ntypedef enum SQ_TEX_XY_FILTER {\n\tSQ_TEX_XY_FILTER_POINT                           = 0x0,\n\tSQ_TEX_XY_FILTER_BILINEAR                        = 0x1,\n\tSQ_TEX_XY_FILTER_ANISO_POINT                     = 0x2,\n\tSQ_TEX_XY_FILTER_ANISO_BILINEAR                  = 0x3,\n} SQ_TEX_XY_FILTER;\ntypedef enum SQ_TEX_Z_FILTER {\n\tSQ_TEX_Z_FILTER_NONE                             = 0x0,\n\tSQ_TEX_Z_FILTER_POINT                            = 0x1,\n\tSQ_TEX_Z_FILTER_LINEAR                           = 0x2,\n} SQ_TEX_Z_FILTER;\ntypedef enum SQ_TEX_MIP_FILTER {\n\tSQ_TEX_MIP_FILTER_NONE                           = 0x0,\n\tSQ_TEX_MIP_FILTER_POINT                          = 0x1,\n\tSQ_TEX_MIP_FILTER_LINEAR                         = 0x2,\n} SQ_TEX_MIP_FILTER;\ntypedef enum SQ_TEX_ANISO_RATIO {\n\tSQ_TEX_ANISO_RATIO_1                             = 0x0,\n\tSQ_TEX_ANISO_RATIO_2                             = 0x1,\n\tSQ_TEX_ANISO_RATIO_4                             = 0x2,\n\tSQ_TEX_ANISO_RATIO_8                             = 0x3,\n\tSQ_TEX_ANISO_RATIO_16                            = 0x4,\n} SQ_TEX_ANISO_RATIO;\ntypedef enum SQ_TEX_DEPTH_COMPARE {\n\tSQ_TEX_DEPTH_COMPARE_NEVER                       = 0x0,\n\tSQ_TEX_DEPTH_COMPARE_LESS                        = 0x1,\n\tSQ_TEX_DEPTH_COMPARE_EQUAL                       = 0x2,\n\tSQ_TEX_DEPTH_COMPARE_LESSEQUAL                   = 0x3,\n\tSQ_TEX_DEPTH_COMPARE_GREATER                     = 0x4,\n\tSQ_TEX_DEPTH_COMPARE_NOTEQUAL                    = 0x5,\n\tSQ_TEX_DEPTH_COMPARE_GREATEREQUAL                = 0x6,\n\tSQ_TEX_DEPTH_COMPARE_ALWAYS                      = 0x7,\n} SQ_TEX_DEPTH_COMPARE;\ntypedef enum SQ_TEX_BORDER_COLOR {\n\tSQ_TEX_BORDER_COLOR_TRANS_BLACK                  = 0x0,\n\tSQ_TEX_BORDER_COLOR_OPAQUE_BLACK                 = 0x1,\n\tSQ_TEX_BORDER_COLOR_OPAQUE_WHITE                 = 0x2,\n\tSQ_TEX_BORDER_COLOR_REGISTER                     = 0x3,\n} SQ_TEX_BORDER_COLOR;\ntypedef enum SQ_RSRC_BUF_TYPE {\n\tSQ_RSRC_BUF                                      = 0x0,\n\tSQ_RSRC_BUF_RSVD_1                               = 0x1,\n\tSQ_RSRC_BUF_RSVD_2                               = 0x2,\n\tSQ_RSRC_BUF_RSVD_3                               = 0x3,\n} SQ_RSRC_BUF_TYPE;\ntypedef enum SQ_RSRC_IMG_TYPE {\n\tSQ_RSRC_IMG_RSVD_0                               = 0x0,\n\tSQ_RSRC_IMG_RSVD_1                               = 0x1,\n\tSQ_RSRC_IMG_RSVD_2                               = 0x2,\n\tSQ_RSRC_IMG_RSVD_3                               = 0x3,\n\tSQ_RSRC_IMG_RSVD_4                               = 0x4,\n\tSQ_RSRC_IMG_RSVD_5                               = 0x5,\n\tSQ_RSRC_IMG_RSVD_6                               = 0x6,\n\tSQ_RSRC_IMG_RSVD_7                               = 0x7,\n\tSQ_RSRC_IMG_1D                                   = 0x8,\n\tSQ_RSRC_IMG_2D                                   = 0x9,\n\tSQ_RSRC_IMG_3D                                   = 0xa,\n\tSQ_RSRC_IMG_CUBE                                 = 0xb,\n\tSQ_RSRC_IMG_1D_ARRAY                             = 0xc,\n\tSQ_RSRC_IMG_2D_ARRAY                             = 0xd,\n\tSQ_RSRC_IMG_2D_MSAA                              = 0xe,\n\tSQ_RSRC_IMG_2D_MSAA_ARRAY                        = 0xf,\n} SQ_RSRC_IMG_TYPE;\ntypedef enum SQ_RSRC_FLAT_TYPE {\n\tSQ_RSRC_FLAT_RSVD_0                              = 0x0,\n\tSQ_RSRC_FLAT                                     = 0x1,\n\tSQ_RSRC_FLAT_RSVD_2                              = 0x2,\n\tSQ_RSRC_FLAT_RSVD_3                              = 0x3,\n} SQ_RSRC_FLAT_TYPE;\ntypedef enum SQ_IMG_FILTER_TYPE {\n\tSQ_IMG_FILTER_MODE_BLEND                         = 0x0,\n\tSQ_IMG_FILTER_MODE_MIN                           = 0x1,\n\tSQ_IMG_FILTER_MODE_MAX                           = 0x2,\n} SQ_IMG_FILTER_TYPE;\ntypedef enum SQ_SEL_XYZW01 {\n\tSQ_SEL_0                                         = 0x0,\n\tSQ_SEL_1                                         = 0x1,\n\tSQ_SEL_RESERVED_0                                = 0x2,\n\tSQ_SEL_RESERVED_1                                = 0x3,\n\tSQ_SEL_X                                         = 0x4,\n\tSQ_SEL_Y                                         = 0x5,\n\tSQ_SEL_Z                                         = 0x6,\n\tSQ_SEL_W                                         = 0x7,\n} SQ_SEL_XYZW01;\ntypedef enum SQ_WAVE_TYPE {\n\tSQ_WAVE_TYPE_PS                                  = 0x0,\n\tSQ_WAVE_TYPE_VS                                  = 0x1,\n\tSQ_WAVE_TYPE_GS                                  = 0x2,\n\tSQ_WAVE_TYPE_ES                                  = 0x3,\n\tSQ_WAVE_TYPE_HS                                  = 0x4,\n\tSQ_WAVE_TYPE_LS                                  = 0x5,\n\tSQ_WAVE_TYPE_CS                                  = 0x6,\n\tSQ_WAVE_TYPE_PS1                                 = 0x7,\n} SQ_WAVE_TYPE;\ntypedef enum SQ_THREAD_TRACE_TOKEN_TYPE {\n\tSQ_THREAD_TRACE_TOKEN_MISC                       = 0x0,\n\tSQ_THREAD_TRACE_TOKEN_TIMESTAMP                  = 0x1,\n\tSQ_THREAD_TRACE_TOKEN_REG                        = 0x2,\n\tSQ_THREAD_TRACE_TOKEN_WAVE_START                 = 0x3,\n\tSQ_THREAD_TRACE_TOKEN_WAVE_ALLOC                 = 0x4,\n\tSQ_THREAD_TRACE_TOKEN_REG_CSPRIV                 = 0x5,\n\tSQ_THREAD_TRACE_TOKEN_WAVE_END                   = 0x6,\n\tSQ_THREAD_TRACE_TOKEN_EVENT                      = 0x7,\n\tSQ_THREAD_TRACE_TOKEN_EVENT_CS                   = 0x8,\n\tSQ_THREAD_TRACE_TOKEN_EVENT_GFX1                 = 0x9,\n\tSQ_THREAD_TRACE_TOKEN_INST                       = 0xa,\n\tSQ_THREAD_TRACE_TOKEN_INST_PC                    = 0xb,\n\tSQ_THREAD_TRACE_TOKEN_INST_USERDATA              = 0xc,\n\tSQ_THREAD_TRACE_TOKEN_ISSUE                      = 0xd,\n\tSQ_THREAD_TRACE_TOKEN_PERF                       = 0xe,\n\tSQ_THREAD_TRACE_TOKEN_REG_CS                     = 0xf,\n} SQ_THREAD_TRACE_TOKEN_TYPE;\ntypedef enum SQ_THREAD_TRACE_MISC_TOKEN_TYPE {\n\tSQ_THREAD_TRACE_MISC_TOKEN_TIME                  = 0x0,\n\tSQ_THREAD_TRACE_MISC_TOKEN_TIME_RESET            = 0x1,\n\tSQ_THREAD_TRACE_MISC_TOKEN_PACKET_LOST           = 0x2,\n\tSQ_THREAD_TRACE_MISC_TOKEN_SURF_SYNC             = 0x3,\n\tSQ_THREAD_TRACE_MISC_TOKEN_TTRACE_STALL_BEGIN    = 0x4,\n\tSQ_THREAD_TRACE_MISC_TOKEN_TTRACE_STALL_END      = 0x5,\n} SQ_THREAD_TRACE_MISC_TOKEN_TYPE;\ntypedef enum SQ_THREAD_TRACE_INST_TYPE {\n\tSQ_THREAD_TRACE_INST_TYPE_SMEM                   = 0x0,\n\tSQ_THREAD_TRACE_INST_TYPE_SALU                   = 0x1,\n\tSQ_THREAD_TRACE_INST_TYPE_VMEM_RD                = 0x2,\n\tSQ_THREAD_TRACE_INST_TYPE_VMEM_WR                = 0x3,\n\tSQ_THREAD_TRACE_INST_TYPE_FLAT_WR                = 0x4,\n\tSQ_THREAD_TRACE_INST_TYPE_VALU                   = 0x5,\n\tSQ_THREAD_TRACE_INST_TYPE_LDS                    = 0x6,\n\tSQ_THREAD_TRACE_INST_TYPE_PC                     = 0x7,\n\tSQ_THREAD_TRACE_INST_TYPE_EXPREQ_GDS             = 0x8,\n\tSQ_THREAD_TRACE_INST_TYPE_EXPREQ_GFX             = 0x9,\n\tSQ_THREAD_TRACE_INST_TYPE_EXPGNT_PAR_COL         = 0xa,\n\tSQ_THREAD_TRACE_INST_TYPE_EXPGNT_POS_GDS         = 0xb,\n\tSQ_THREAD_TRACE_INST_TYPE_JUMP                   = 0xc,\n\tSQ_THREAD_TRACE_INST_TYPE_NEXT                   = 0xd,\n\tSQ_THREAD_TRACE_INST_TYPE_FLAT_RD                = 0xe,\n\tSQ_THREAD_TRACE_INST_TYPE_OTHER_MSG              = 0xf,\n} SQ_THREAD_TRACE_INST_TYPE;\ntypedef enum SQ_THREAD_TRACE_REG_TYPE {\n\tSQ_THREAD_TRACE_REG_TYPE_EVENT                   = 0x0,\n\tSQ_THREAD_TRACE_REG_TYPE_DRAW                    = 0x1,\n\tSQ_THREAD_TRACE_REG_TYPE_DISPATCH                = 0x2,\n\tSQ_THREAD_TRACE_REG_TYPE_USERDATA                = 0x3,\n\tSQ_THREAD_TRACE_REG_TYPE_MARKER                  = 0x4,\n\tSQ_THREAD_TRACE_REG_TYPE_GFXDEC                  = 0x5,\n\tSQ_THREAD_TRACE_REG_TYPE_SHDEC                   = 0x6,\n\tSQ_THREAD_TRACE_REG_TYPE_OTHER                   = 0x7,\n} SQ_THREAD_TRACE_REG_TYPE;\ntypedef enum SQ_THREAD_TRACE_REG_OP {\n\tSQ_THREAD_TRACE_REG_OP_READ                      = 0x0,\n\tSQ_THREAD_TRACE_REG_OP_WRITE                     = 0x1,\n} SQ_THREAD_TRACE_REG_OP;\ntypedef enum SQ_THREAD_TRACE_MODE_SEL {\n\tSQ_THREAD_TRACE_MODE_OFF                         = 0x0,\n\tSQ_THREAD_TRACE_MODE_ON                          = 0x1,\n\tSQ_THREAD_TRACE_MODE_RANDOM                      = 0x2,\n} SQ_THREAD_TRACE_MODE_SEL;\ntypedef enum SQ_THREAD_TRACE_CAPTURE_MODE {\n\tSQ_THREAD_TRACE_CAPTURE_MODE_ALL                 = 0x0,\n\tSQ_THREAD_TRACE_CAPTURE_MODE_SELECT              = 0x1,\n\tSQ_THREAD_TRACE_CAPTURE_MODE_SELECT_DETAIL       = 0x2,\n} SQ_THREAD_TRACE_CAPTURE_MODE;\ntypedef enum SQ_THREAD_TRACE_VM_ID_MASK {\n\tSQ_THREAD_TRACE_VM_ID_MASK_SINGLE                = 0x0,\n\tSQ_THREAD_TRACE_VM_ID_MASK_ALL                   = 0x1,\n\tSQ_THREAD_TRACE_VM_ID_MASK_SINGLE_DETAIL         = 0x2,\n} SQ_THREAD_TRACE_VM_ID_MASK;\ntypedef enum SQ_THREAD_TRACE_WAVE_MASK {\n\tSQ_THREAD_TRACE_WAVE_MASK_NONE                   = 0x0,\n\tSQ_THREAD_TRACE_WAVE_MASK_ALL                    = 0x1,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_2                    = 0x2,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_4                    = 0x3,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_8                    = 0x4,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_16                   = 0x5,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_32                   = 0x6,\n\tSQ_THREAD_TRACE_WAVE_MASK_1_64                   = 0x7,\n} SQ_THREAD_TRACE_WAVE_MASK;\ntypedef enum SQ_THREAD_TRACE_ISSUE {\n\tSQ_THREAD_TRACE_ISSUE_NULL                       = 0x0,\n\tSQ_THREAD_TRACE_ISSUE_STALL                      = 0x1,\n\tSQ_THREAD_TRACE_ISSUE_INST                       = 0x2,\n\tSQ_THREAD_TRACE_ISSUE_IMMED                      = 0x3,\n} SQ_THREAD_TRACE_ISSUE;\ntypedef enum SQ_THREAD_TRACE_ISSUE_MASK {\n\tSQ_THREAD_TRACE_ISSUE_MASK_ALL                   = 0x0,\n\tSQ_THREAD_TRACE_ISSUE_MASK_STALLED               = 0x1,\n\tSQ_THREAD_TRACE_ISSUE_MASK_STALLED_AND_IMMED     = 0x2,\n\tSQ_THREAD_TRACE_ISSUE_MASK_IMMED                 = 0x3,\n} SQ_THREAD_TRACE_ISSUE_MASK;\ntypedef enum SQ_PERF_SEL {\n\tSQ_PERF_SEL_NONE                                 = 0x0,\n\tSQ_PERF_SEL_ACCUM_PREV                           = 0x1,\n\tSQ_PERF_SEL_CYCLES                               = 0x2,\n\tSQ_PERF_SEL_BUSY_CYCLES                          = 0x3,\n\tSQ_PERF_SEL_WAVES                                = 0x4,\n\tSQ_PERF_SEL_LEVEL_WAVES                          = 0x5,\n\tSQ_PERF_SEL_WAVES_EQ_64                          = 0x6,\n\tSQ_PERF_SEL_WAVES_LT_64                          = 0x7,\n\tSQ_PERF_SEL_WAVES_LT_48                          = 0x8,\n\tSQ_PERF_SEL_WAVES_LT_32                          = 0x9,\n\tSQ_PERF_SEL_WAVES_LT_16                          = 0xa,\n\tSQ_PERF_SEL_WAVES_CU                             = 0xb,\n\tSQ_PERF_SEL_LEVEL_WAVES_CU                       = 0xc,\n\tSQ_PERF_SEL_BUSY_CU_CYCLES                       = 0xd,\n\tSQ_PERF_SEL_ITEMS                                = 0xe,\n\tSQ_PERF_SEL_QUADS                                = 0xf,\n\tSQ_PERF_SEL_EVENTS                               = 0x10,\n\tSQ_PERF_SEL_SURF_SYNCS                           = 0x11,\n\tSQ_PERF_SEL_TTRACE_REQS                          = 0x12,\n\tSQ_PERF_SEL_TTRACE_INFLIGHT_REQS                 = 0x13,\n\tSQ_PERF_SEL_TTRACE_STALL                         = 0x14,\n\tSQ_PERF_SEL_MSG_CNTR                             = 0x15,\n\tSQ_PERF_SEL_MSG_PERF                             = 0x16,\n\tSQ_PERF_SEL_MSG_GSCNT                            = 0x17,\n\tSQ_PERF_SEL_MSG_INTERRUPT                        = 0x18,\n\tSQ_PERF_SEL_INSTS                                = 0x19,\n\tSQ_PERF_SEL_INSTS_VALU                           = 0x1a,\n\tSQ_PERF_SEL_INSTS_VMEM_WR                        = 0x1b,\n\tSQ_PERF_SEL_INSTS_VMEM_RD                        = 0x1c,\n\tSQ_PERF_SEL_INSTS_VMEM                           = 0x1d,\n\tSQ_PERF_SEL_INSTS_SALU                           = 0x1e,\n\tSQ_PERF_SEL_INSTS_SMEM                           = 0x1f,\n\tSQ_PERF_SEL_INSTS_FLAT                           = 0x20,\n\tSQ_PERF_SEL_INSTS_FLAT_LDS_ONLY                  = 0x21,\n\tSQ_PERF_SEL_INSTS_LDS                            = 0x22,\n\tSQ_PERF_SEL_INSTS_GDS                            = 0x23,\n\tSQ_PERF_SEL_INSTS_EXP                            = 0x24,\n\tSQ_PERF_SEL_INSTS_EXP_GDS                        = 0x25,\n\tSQ_PERF_SEL_INSTS_BRANCH                         = 0x26,\n\tSQ_PERF_SEL_INSTS_SENDMSG                        = 0x27,\n\tSQ_PERF_SEL_INSTS_VSKIPPED                       = 0x28,\n\tSQ_PERF_SEL_INST_LEVEL_VMEM                      = 0x29,\n\tSQ_PERF_SEL_INST_LEVEL_SMEM                      = 0x2a,\n\tSQ_PERF_SEL_INST_LEVEL_LDS                       = 0x2b,\n\tSQ_PERF_SEL_INST_LEVEL_GDS                       = 0x2c,\n\tSQ_PERF_SEL_INST_LEVEL_EXP                       = 0x2d,\n\tSQ_PERF_SEL_WAVE_CYCLES                          = 0x2e,\n\tSQ_PERF_SEL_WAVE_READY                           = 0x2f,\n\tSQ_PERF_SEL_WAIT_CNT_VM                          = 0x30,\n\tSQ_PERF_SEL_WAIT_CNT_LGKM                        = 0x31,\n\tSQ_PERF_SEL_WAIT_CNT_EXP                         = 0x32,\n\tSQ_PERF_SEL_WAIT_CNT_ANY                         = 0x33,\n\tSQ_PERF_SEL_WAIT_BARRIER                         = 0x34,\n\tSQ_PERF_SEL_WAIT_EXP_ALLOC                       = 0x35,\n\tSQ_PERF_SEL_WAIT_SLEEP                           = 0x36,\n\tSQ_PERF_SEL_WAIT_OTHER                           = 0x37,\n\tSQ_PERF_SEL_WAIT_ANY                             = 0x38,\n\tSQ_PERF_SEL_WAIT_TTRACE                          = 0x39,\n\tSQ_PERF_SEL_WAIT_IFETCH                          = 0x3a,\n\tSQ_PERF_SEL_WAIT_INST_VMEM                       = 0x3b,\n\tSQ_PERF_SEL_WAIT_INST_SCA                        = 0x3c,\n\tSQ_PERF_SEL_WAIT_INST_LDS                        = 0x3d,\n\tSQ_PERF_SEL_WAIT_INST_VALU                       = 0x3e,\n\tSQ_PERF_SEL_WAIT_INST_EXP_GDS                    = 0x3f,\n\tSQ_PERF_SEL_WAIT_INST_MISC                       = 0x40,\n\tSQ_PERF_SEL_WAIT_INST_FLAT                       = 0x41,\n\tSQ_PERF_SEL_ACTIVE_INST_ANY                      = 0x42,\n\tSQ_PERF_SEL_ACTIVE_INST_VMEM                     = 0x43,\n\tSQ_PERF_SEL_ACTIVE_INST_LDS                      = 0x44,\n\tSQ_PERF_SEL_ACTIVE_INST_VALU                     = 0x45,\n\tSQ_PERF_SEL_ACTIVE_INST_SCA                      = 0x46,\n\tSQ_PERF_SEL_ACTIVE_INST_EXP_GDS                  = 0x47,\n\tSQ_PERF_SEL_ACTIVE_INST_MISC                     = 0x48,\n\tSQ_PERF_SEL_ACTIVE_INST_FLAT                     = 0x49,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM_WR                  = 0x4a,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM_RD                  = 0x4b,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM_ADDR                = 0x4c,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM_DATA                = 0x4d,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM_CMD                 = 0x4e,\n\tSQ_PERF_SEL_INST_CYCLES_VMEM                     = 0x4f,\n\tSQ_PERF_SEL_INST_CYCLES_LDS                      = 0x50,\n\tSQ_PERF_SEL_INST_CYCLES_VALU                     = 0x51,\n\tSQ_PERF_SEL_INST_CYCLES_EXP                      = 0x52,\n\tSQ_PERF_SEL_INST_CYCLES_GDS                      = 0x53,\n\tSQ_PERF_SEL_INST_CYCLES_SCA                      = 0x54,\n\tSQ_PERF_SEL_INST_CYCLES_SMEM                     = 0x55,\n\tSQ_PERF_SEL_INST_CYCLES_SALU                     = 0x56,\n\tSQ_PERF_SEL_INST_CYCLES_EXP_GDS                  = 0x57,\n\tSQ_PERF_SEL_INST_CYCLES_MISC                     = 0x58,\n\tSQ_PERF_SEL_THREAD_CYCLES_VALU                   = 0x59,\n\tSQ_PERF_SEL_THREAD_CYCLES_VALU_MAX               = 0x5a,\n\tSQ_PERF_SEL_IFETCH                               = 0x5b,\n\tSQ_PERF_SEL_IFETCH_LEVEL                         = 0x5c,\n\tSQ_PERF_SEL_CBRANCH_FORK                         = 0x5d,\n\tSQ_PERF_SEL_CBRANCH_FORK_SPLIT                   = 0x5e,\n\tSQ_PERF_SEL_VALU_LDS_DIRECT_RD                   = 0x5f,\n\tSQ_PERF_SEL_VALU_LDS_INTERP_OP                   = 0x60,\n\tSQ_PERF_SEL_LDS_BANK_CONFLICT                    = 0x61,\n\tSQ_PERF_SEL_LDS_ADDR_CONFLICT                    = 0x62,\n\tSQ_PERF_SEL_LDS_UNALIGNED_STALL                  = 0x63,\n\tSQ_PERF_SEL_LDS_MEM_VIOLATIONS                   = 0x64,\n\tSQ_PERF_SEL_LDS_ATOMIC_RETURN                    = 0x65,\n\tSQ_PERF_SEL_LDS_IDX_ACTIVE                       = 0x66,\n\tSQ_PERF_SEL_VALU_DEP_STALL                       = 0x67,\n\tSQ_PERF_SEL_VALU_STARVE                          = 0x68,\n\tSQ_PERF_SEL_EXP_REQ_FIFO_FULL                    = 0x69,\n\tSQ_PERF_SEL_LDS_BACK2BACK_STALL                  = 0x6a,\n\tSQ_PERF_SEL_LDS_DATA_FIFO_FULL                   = 0x6b,\n\tSQ_PERF_SEL_LDS_CMD_FIFO_FULL                    = 0x6c,\n\tSQ_PERF_SEL_VMEM_BACK2BACK_STALL                 = 0x6d,\n\tSQ_PERF_SEL_VMEM_TA_ADDR_FIFO_FULL               = 0x6e,\n\tSQ_PERF_SEL_VMEM_TA_CMD_FIFO_FULL                = 0x6f,\n\tSQ_PERF_SEL_VMEM_EX_DATA_REG_BUSY                = 0x70,\n\tSQ_PERF_SEL_VMEM_WR_BACK2BACK_STALL              = 0x71,\n\tSQ_PERF_SEL_VMEM_WR_TA_DATA_FIFO_FULL            = 0x72,\n\tSQ_PERF_SEL_VALU_SRC_C_CONFLICT                  = 0x73,\n\tSQ_PERF_SEL_VMEM_RD_SRC_CD_CONFLICT              = 0x74,\n\tSQ_PERF_SEL_VMEM_WR_SRC_CD_CONFLICT              = 0x75,\n\tSQ_PERF_SEL_FLAT_SRC_CD_CONFLICT                 = 0x76,\n\tSQ_PERF_SEL_LDS_SRC_CD_CONFLICT                  = 0x77,\n\tSQ_PERF_SEL_SRC_CD_BUSY                          = 0x78,\n\tSQ_PERF_SEL_PT_POWER_STALL                       = 0x79,\n\tSQ_PERF_SEL_USER0                                = 0x7a,\n\tSQ_PERF_SEL_USER1                                = 0x7b,\n\tSQ_PERF_SEL_USER2                                = 0x7c,\n\tSQ_PERF_SEL_USER3                                = 0x7d,\n\tSQ_PERF_SEL_USER4                                = 0x7e,\n\tSQ_PERF_SEL_USER5                                = 0x7f,\n\tSQ_PERF_SEL_USER6                                = 0x80,\n\tSQ_PERF_SEL_USER7                                = 0x81,\n\tSQ_PERF_SEL_USER8                                = 0x82,\n\tSQ_PERF_SEL_USER9                                = 0x83,\n\tSQ_PERF_SEL_USER10                               = 0x84,\n\tSQ_PERF_SEL_USER11                               = 0x85,\n\tSQ_PERF_SEL_USER12                               = 0x86,\n\tSQ_PERF_SEL_USER13                               = 0x87,\n\tSQ_PERF_SEL_USER14                               = 0x88,\n\tSQ_PERF_SEL_USER15                               = 0x89,\n\tSQ_PERF_SEL_USER_LEVEL0                          = 0x8a,\n\tSQ_PERF_SEL_USER_LEVEL1                          = 0x8b,\n\tSQ_PERF_SEL_USER_LEVEL2                          = 0x8c,\n\tSQ_PERF_SEL_USER_LEVEL3                          = 0x8d,\n\tSQ_PERF_SEL_USER_LEVEL4                          = 0x8e,\n\tSQ_PERF_SEL_USER_LEVEL5                          = 0x8f,\n\tSQ_PERF_SEL_USER_LEVEL6                          = 0x90,\n\tSQ_PERF_SEL_USER_LEVEL7                          = 0x91,\n\tSQ_PERF_SEL_USER_LEVEL8                          = 0x92,\n\tSQ_PERF_SEL_USER_LEVEL9                          = 0x93,\n\tSQ_PERF_SEL_USER_LEVEL10                         = 0x94,\n\tSQ_PERF_SEL_USER_LEVEL11                         = 0x95,\n\tSQ_PERF_SEL_USER_LEVEL12                         = 0x96,\n\tSQ_PERF_SEL_USER_LEVEL13                         = 0x97,\n\tSQ_PERF_SEL_USER_LEVEL14                         = 0x98,\n\tSQ_PERF_SEL_USER_LEVEL15                         = 0x99,\n\tSQ_PERF_SEL_POWER_VALU                           = 0x9a,\n\tSQ_PERF_SEL_POWER_VALU0                          = 0x9b,\n\tSQ_PERF_SEL_POWER_VALU1                          = 0x9c,\n\tSQ_PERF_SEL_POWER_VALU2                          = 0x9d,\n\tSQ_PERF_SEL_POWER_GPR_RD                         = 0x9e,\n\tSQ_PERF_SEL_POWER_GPR_WR                         = 0x9f,\n\tSQ_PERF_SEL_POWER_LDS_BUSY                       = 0xa0,\n\tSQ_PERF_SEL_POWER_ALU_BUSY                       = 0xa1,\n\tSQ_PERF_SEL_POWER_TEX_BUSY                       = 0xa2,\n\tSQ_PERF_SEL_ACCUM_PREV_HIRES                     = 0xa3,\n\tSQ_PERF_SEL_DUMMY_LAST                           = 0xa7,\n\tSQC_PERF_SEL_ICACHE_INPUT_VALID_READY            = 0xa8,\n\tSQC_PERF_SEL_ICACHE_INPUT_VALID_READYB           = 0xa9,\n\tSQC_PERF_SEL_ICACHE_INPUT_VALIDB                 = 0xaa,\n\tSQC_PERF_SEL_DCACHE_INPUT_VALID_READY            = 0xab,\n\tSQC_PERF_SEL_DCACHE_INPUT_VALID_READYB           = 0xac,\n\tSQC_PERF_SEL_DCACHE_INPUT_VALIDB                 = 0xad,\n\tSQC_PERF_SEL_TC_REQ                              = 0xae,\n\tSQC_PERF_SEL_TC_INST_REQ                         = 0xaf,\n\tSQC_PERF_SEL_TC_DATA_REQ                         = 0xb0,\n\tSQC_PERF_SEL_TC_STALL                            = 0xb1,\n\tSQC_PERF_SEL_TC_STARVE                           = 0xb2,\n\tSQC_PERF_SEL_ICACHE_BUSY_CYCLES                  = 0xb3,\n\tSQC_PERF_SEL_ICACHE_REQ                          = 0xb4,\n\tSQC_PERF_SEL_ICACHE_HITS                         = 0xb5,\n\tSQC_PERF_SEL_ICACHE_MISSES                       = 0xb6,\n\tSQC_PERF_SEL_ICACHE_MISSES_DUPLICATE             = 0xb7,\n\tSQC_PERF_SEL_ICACHE_UNCACHED                     = 0xb8,\n\tSQC_PERF_SEL_ICACHE_VOLATILE                     = 0xb9,\n\tSQC_PERF_SEL_ICACHE_INVAL_INST                   = 0xba,\n\tSQC_PERF_SEL_ICACHE_INVAL_ASYNC                  = 0xbb,\n\tSQC_PERF_SEL_ICACHE_INVAL_VOLATILE_INST          = 0xbc,\n\tSQC_PERF_SEL_ICACHE_INVAL_VOLATILE_ASYNC         = 0xbd,\n\tSQC_PERF_SEL_ICACHE_INPUT_STALL_ARB_NO_GRANT     = 0xbe,\n\tSQC_PERF_SEL_ICACHE_INPUT_STALL_BANK_READYB      = 0xbf,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALLED                = 0xc0,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_INFLIGHT_NONZERO = 0xc1,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_INFLIGHT_MAX     = 0xc2,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_VOLATILE_MISMATCH= 0xc3,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_UNCACHED_HIT     = 0xc4,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_OUTPUT           = 0xc5,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_OUTPUT_MISS_FIFO = 0xc6,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_OUTPUT_HIT_FIFO  = 0xc7,\n\tSQC_PERF_SEL_ICACHE_CACHE_STALL_OUTPUT_TC_IF     = 0xc8,\n\tSQC_PERF_SEL_ICACHE_STALL_OUTXBAR_ARB_NO_GRANT   = 0xc9,\n\tSQC_PERF_SEL_DCACHE_BUSY_CYCLES                  = 0xca,\n\tSQC_PERF_SEL_DCACHE_REQ                          = 0xcb,\n\tSQC_PERF_SEL_DCACHE_HITS                         = 0xcc,\n\tSQC_PERF_SEL_DCACHE_MISSES                       = 0xcd,\n\tSQC_PERF_SEL_DCACHE_MISSES_DUPLICATE             = 0xce,\n\tSQC_PERF_SEL_DCACHE_UNCACHED                     = 0xcf,\n\tSQC_PERF_SEL_DCACHE_VOLATILE                     = 0xd0,\n\tSQC_PERF_SEL_DCACHE_INVAL_INST                   = 0xd1,\n\tSQC_PERF_SEL_DCACHE_INVAL_ASYNC                  = 0xd2,\n\tSQC_PERF_SEL_DCACHE_INVAL_VOLATILE_INST          = 0xd3,\n\tSQC_PERF_SEL_DCACHE_INVAL_VOLATILE_ASYNC         = 0xd4,\n\tSQC_PERF_SEL_DCACHE_INPUT_STALL_ARB_NO_GRANT     = 0xd5,\n\tSQC_PERF_SEL_DCACHE_INPUT_STALL_BANK_READYB      = 0xd6,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALLED                = 0xd7,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_INFLIGHT_NONZERO = 0xd8,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_INFLIGHT_MAX     = 0xd9,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_VOLATILE_MISMATCH= 0xda,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_UNCACHED_HIT     = 0xdb,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_OUTPUT           = 0xdc,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_OUTPUT_MISS_FIFO = 0xdd,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_OUTPUT_HIT_FIFO  = 0xde,\n\tSQC_PERF_SEL_DCACHE_CACHE_STALL_OUTPUT_TC_IF     = 0xdf,\n\tSQC_PERF_SEL_DCACHE_STALL_OUTXBAR_ARB_NO_GRANT   = 0xe0,\n\tSQC_PERF_SEL_DCACHE_REQ_1                        = 0xe1,\n\tSQC_PERF_SEL_DCACHE_REQ_2                        = 0xe2,\n\tSQC_PERF_SEL_DCACHE_REQ_4                        = 0xe3,\n\tSQC_PERF_SEL_DCACHE_REQ_8                        = 0xe4,\n\tSQC_PERF_SEL_DCACHE_REQ_16                       = 0xe5,\n\tSQC_PERF_SEL_DCACHE_REQ_TIME                     = 0xe6,\n\tSQC_PERF_SEL_SQ_DCACHE_REQS                      = 0xe7,\n\tSQC_PERF_SEL_DCACHE_FLAT_REQ                     = 0xe8,\n\tSQC_PERF_SEL_DCACHE_NONFLAT_REQ                  = 0xe9,\n\tSQC_PERF_SEL_ICACHE_INFLIGHT_LEVEL               = 0xea,\n\tSQC_PERF_SEL_ICACHE_PRE_CC_LEVEL                 = 0xeb,\n\tSQC_PERF_SEL_ICACHE_POST_CC_LEVEL                = 0xec,\n\tSQC_PERF_SEL_ICACHE_POST_CC_HIT_LEVEL            = 0xed,\n\tSQC_PERF_SEL_ICACHE_POST_CC_MISS_LEVEL           = 0xee,\n\tSQC_PERF_SEL_DCACHE_INFLIGHT_LEVEL               = 0xef,\n\tSQC_PERF_SEL_DCACHE_PRE_CC_LEVEL                 = 0xf0,\n\tSQC_PERF_SEL_DCACHE_POST_CC_LEVEL                = 0xf1,\n\tSQC_PERF_SEL_DCACHE_POST_CC_HIT_LEVEL            = 0xf2,\n\tSQC_PERF_SEL_DCACHE_POST_CC_MISS_LEVEL           = 0xf3,\n\tSQC_PERF_SEL_TC_INFLIGHT_LEVEL                   = 0xf4,\n\tSQC_PERF_SEL_ICACHE_TC_INFLIGHT_LEVEL            = 0xf5,\n\tSQC_PERF_SEL_DCACHE_TC_INFLIGHT_LEVEL            = 0xf6,\n\tSQC_PERF_SEL_ERR_DCACHE_REQ_2_GPR_ADDR_UNALIGNED = 0xf7,\n\tSQC_PERF_SEL_ERR_DCACHE_REQ_4_GPR_ADDR_UNALIGNED = 0xf8,\n\tSQC_PERF_SEL_ERR_DCACHE_REQ_8_GPR_ADDR_UNALIGNED = 0xf9,\n\tSQC_PERF_SEL_ERR_DCACHE_REQ_16_GPR_ADDR_UNALIGNED= 0xfa,\n\tSQC_PERF_SEL_DUMMY_LAST                          = 0xfb,\n} SQ_PERF_SEL;\ntypedef enum SQC_DATA_CACHE_POLICIES {\n\tSQC_DATA_CACHE_POLICY_HIT_LRU                    = 0x0,\n\tSQC_DATA_CACHE_POLICY_MISS_EVICT                 = 0x1,\n} SQC_DATA_CACHE_POLICIES;\ntypedef enum SQ_CAC_POWER_SEL {\n\tSQ_CAC_POWER_VALU                                = 0x0,\n\tSQ_CAC_POWER_VALU0                               = 0x1,\n\tSQ_CAC_POWER_VALU1                               = 0x2,\n\tSQ_CAC_POWER_VALU2                               = 0x3,\n\tSQ_CAC_POWER_GPR_RD                              = 0x4,\n\tSQ_CAC_POWER_GPR_WR                              = 0x5,\n\tSQ_CAC_POWER_LDS_BUSY                            = 0x6,\n\tSQ_CAC_POWER_ALU_BUSY                            = 0x7,\n\tSQ_CAC_POWER_TEX_BUSY                            = 0x8,\n} SQ_CAC_POWER_SEL;\ntypedef enum SQ_IND_CMD_CMD {\n\tSQ_IND_CMD_CMD_NULL                              = 0x0,\n\tSQ_IND_CMD_CMD_HALT                              = 0x1,\n\tSQ_IND_CMD_CMD_RESUME                            = 0x2,\n\tSQ_IND_CMD_CMD_KILL                              = 0x3,\n\tSQ_IND_CMD_CMD_DEBUG                             = 0x4,\n\tSQ_IND_CMD_CMD_TRAP                              = 0x5,\n} SQ_IND_CMD_CMD;\ntypedef enum SQ_IND_CMD_MODE {\n\tSQ_IND_CMD_MODE_SINGLE                           = 0x0,\n\tSQ_IND_CMD_MODE_BROADCAST                        = 0x1,\n\tSQ_IND_CMD_MODE_BROADCAST_QUEUE                  = 0x2,\n\tSQ_IND_CMD_MODE_BROADCAST_PIPE                   = 0x3,\n\tSQ_IND_CMD_MODE_BROADCAST_ME                     = 0x4,\n} SQ_IND_CMD_MODE;\ntypedef enum SQ_DED_INFO_SOURCE {\n\tSQ_DED_INFO_SOURCE_INVALID                       = 0x0,\n\tSQ_DED_INFO_SOURCE_INST                          = 0x1,\n\tSQ_DED_INFO_SOURCE_SGPR                          = 0x2,\n\tSQ_DED_INFO_SOURCE_VGPR                          = 0x3,\n\tSQ_DED_INFO_SOURCE_LDS                           = 0x4,\n\tSQ_DED_INFO_SOURCE_GDS                           = 0x5,\n\tSQ_DED_INFO_SOURCE_TA                            = 0x6,\n} SQ_DED_INFO_SOURCE;\ntypedef enum SQ_ROUND_MODE {\n\tSQ_ROUND_NEAREST_EVEN                            = 0x0,\n\tSQ_ROUND_PLUS_INFINITY                           = 0x1,\n\tSQ_ROUND_MINUS_INFINITY                          = 0x2,\n\tSQ_ROUND_TO_ZERO                                 = 0x3,\n} SQ_ROUND_MODE;\ntypedef enum SQ_INTERRUPT_WORD_ENCODING {\n\tSQ_INTERRUPT_WORD_ENCODING_AUTO                  = 0x0,\n\tSQ_INTERRUPT_WORD_ENCODING_INST                  = 0x1,\n\tSQ_INTERRUPT_WORD_ENCODING_ERROR                 = 0x2,\n} SQ_INTERRUPT_WORD_ENCODING;\ntypedef enum ENUM_SQ_EXPORT_RAT_INST {\n\tSQ_EXPORT_RAT_INST_NOP                           = 0x0,\n\tSQ_EXPORT_RAT_INST_STORE_TYPED                   = 0x1,\n\tSQ_EXPORT_RAT_INST_STORE_RAW                     = 0x2,\n\tSQ_EXPORT_RAT_INST_STORE_RAW_FDENORM             = 0x3,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_INT                   = 0x4,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_FLT                   = 0x5,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_FDENORM               = 0x6,\n\tSQ_EXPORT_RAT_INST_ADD                           = 0x7,\n\tSQ_EXPORT_RAT_INST_SUB                           = 0x8,\n\tSQ_EXPORT_RAT_INST_RSUB                          = 0x9,\n\tSQ_EXPORT_RAT_INST_MIN_INT                       = 0xa,\n\tSQ_EXPORT_RAT_INST_MIN_UINT                      = 0xb,\n\tSQ_EXPORT_RAT_INST_MAX_INT                       = 0xc,\n\tSQ_EXPORT_RAT_INST_MAX_UINT                      = 0xd,\n\tSQ_EXPORT_RAT_INST_AND                           = 0xe,\n\tSQ_EXPORT_RAT_INST_OR                            = 0xf,\n\tSQ_EXPORT_RAT_INST_XOR                           = 0x10,\n\tSQ_EXPORT_RAT_INST_MSKOR                         = 0x11,\n\tSQ_EXPORT_RAT_INST_INC_UINT                      = 0x12,\n\tSQ_EXPORT_RAT_INST_DEC_UINT                      = 0x13,\n\tSQ_EXPORT_RAT_INST_STORE_DWORD                   = 0x14,\n\tSQ_EXPORT_RAT_INST_STORE_SHORT                   = 0x15,\n\tSQ_EXPORT_RAT_INST_STORE_BYTE                    = 0x16,\n\tSQ_EXPORT_RAT_INST_NOP_RTN                       = 0x20,\n\tSQ_EXPORT_RAT_INST_XCHG_RTN                      = 0x22,\n\tSQ_EXPORT_RAT_INST_XCHG_FDENORM_RTN              = 0x23,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_INT_RTN               = 0x24,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_FLT_RTN               = 0x25,\n\tSQ_EXPORT_RAT_INST_CMPXCHG_FDENORM_RTN           = 0x26,\n\tSQ_EXPORT_RAT_INST_ADD_RTN                       = 0x27,\n\tSQ_EXPORT_RAT_INST_SUB_RTN                       = 0x28,\n\tSQ_EXPORT_RAT_INST_RSUB_RTN                      = 0x29,\n\tSQ_EXPORT_RAT_INST_MIN_INT_RTN                   = 0x2a,\n\tSQ_EXPORT_RAT_INST_MIN_UINT_RTN                  = 0x2b,\n\tSQ_EXPORT_RAT_INST_MAX_INT_RTN                   = 0x2c,\n\tSQ_EXPORT_RAT_INST_MAX_UINT_RTN                  = 0x2d,\n\tSQ_EXPORT_RAT_INST_AND_RTN                       = 0x2e,\n\tSQ_EXPORT_RAT_INST_OR_RTN                        = 0x2f,\n\tSQ_EXPORT_RAT_INST_XOR_RTN                       = 0x30,\n\tSQ_EXPORT_RAT_INST_MSKOR_RTN                     = 0x31,\n\tSQ_EXPORT_RAT_INST_INC_UINT_RTN                  = 0x32,\n\tSQ_EXPORT_RAT_INST_DEC_UINT_RTN                  = 0x33,\n} ENUM_SQ_EXPORT_RAT_INST;\ntypedef enum SQ_IBUF_ST {\n\tSQ_IBUF_IB_IDLE                                  = 0x0,\n\tSQ_IBUF_IB_INI_WAIT_GNT                          = 0x1,\n\tSQ_IBUF_IB_INI_WAIT_DRET                         = 0x2,\n\tSQ_IBUF_IB_LE_4DW                                = 0x3,\n\tSQ_IBUF_IB_WAIT_DRET                             = 0x4,\n\tSQ_IBUF_IB_EMPTY_WAIT_DRET                       = 0x5,\n\tSQ_IBUF_IB_DRET                                  = 0x6,\n\tSQ_IBUF_IB_EMPTY_WAIT_GNT                        = 0x7,\n} SQ_IBUF_ST;\ntypedef enum SQ_INST_STR_ST {\n\tSQ_INST_STR_IB_WAVE_NORML                        = 0x0,\n\tSQ_INST_STR_IB_WAVE2ID_NORMAL_INST_AV            = 0x1,\n\tSQ_INST_STR_IB_WAVE_INTERNAL_INST_AV             = 0x2,\n\tSQ_INST_STR_IB_WAVE_INST_SKIP_AV                 = 0x3,\n\tSQ_INST_STR_IB_WAVE_SETVSKIP_ST0                 = 0x4,\n\tSQ_INST_STR_IB_WAVE_SETVSKIP_ST1                 = 0x5,\n\tSQ_INST_STR_IB_WAVE_NOP_SLEEP_WAIT               = 0x6,\n\tSQ_INST_STR_IB_WAVE_PC_FROM_SGPR_MSG_WAIT        = 0x7,\n} SQ_INST_STR_ST;\ntypedef enum SQ_WAVE_IB_ECC_ST {\n\tSQ_WAVE_IB_ECC_CLEAN                             = 0x0,\n\tSQ_WAVE_IB_ECC_ERR_CONTINUE                      = 0x1,\n\tSQ_WAVE_IB_ECC_ERR_HALT                          = 0x2,\n\tSQ_WAVE_IB_ECC_WITH_ERR_MSG                      = 0x3,\n} SQ_WAVE_IB_ECC_ST;\ntypedef enum SH_MEM_ALIGNMENT_MODE {\n\tSH_MEM_ALIGNMENT_MODE_DWORD                      = 0x0,\n\tSH_MEM_ALIGNMENT_MODE_DWORD_STRICT               = 0x1,\n\tSH_MEM_ALIGNMENT_MODE_STRICT                     = 0x2,\n\tSH_MEM_ALIGNMENT_MODE_UNALIGNED                  = 0x3,\n} SH_MEM_ALIGNMENT_MODE;\n#define SQ_WAVE_TYPE_PS0                          0x0\n#define SQ_THREAD_TRACE_LFSR_PS                   0x8016\n#define SQ_THREAD_TRACE_LFSR_VS                   0x801c\n#define SQ_THREAD_TRACE_LFSR_GS                   0x801f\n#define SQ_THREAD_TRACE_LFSR_ES                   0x8029\n#define SQ_THREAD_TRACE_LFSR_HS                   0x805e\n#define SQ_THREAD_TRACE_LFSR_LS                   0x806b\n#define SQ_THREAD_TRACE_LFSR_CS                   0x8097\n#define SQIND_GLOBAL_REGS_OFFSET                  0x0\n#define SQIND_GLOBAL_REGS_SIZE                    0x8\n#define SQIND_LOCAL_REGS_OFFSET                   0x8\n#define SQIND_LOCAL_REGS_SIZE                     0x8\n#define SQIND_WAVE_HWREGS_OFFSET                  0x10\n#define SQIND_WAVE_HWREGS_SIZE                    0x1f0\n#define SQIND_WAVE_SGPRS_OFFSET                   0x200\n#define SQIND_WAVE_SGPRS_SIZE                     0x200\n#define SQ_GFXDEC_BEGIN                           0xa000\n#define SQ_GFXDEC_END                             0xc000\n#define SQ_GFXDEC_STATE_ID_SHIFT                  0xa\n#define SQDEC_BEGIN                               0x2300\n#define SQDEC_END                                 0x23ff\n#define SQPERFSDEC_BEGIN                          0xd9c0\n#define SQPERFSDEC_END                            0xda40\n#define SQPERFDDEC_BEGIN                          0xd1c0\n#define SQPERFDDEC_END                            0xd240\n#define SQGFXUDEC_BEGIN                           0xc340\n#define SQGFXUDEC_END                             0xc380\n#define SQPWRDEC_BEGIN                            0xf08c\n#define SQPWRDEC_END                              0xf094\n#define SQ_DISPATCHER_GFX_MIN                     0x10\n#define SQ_DISPATCHER_GFX_CNT_PER_RING            0x8\n#define SQ_MAX_PGM_SGPRS                          0x68\n#define SQ_MAX_PGM_VGPRS                          0x100\n#define SQ_THREAD_TRACE_TIME_UNIT                 0x4\n#define SQ_INTERRUPT_ID                           0xef\n#define SQ_EX_MODE_EXCP_VALU_BASE                 0x0\n#define SQ_EX_MODE_EXCP_VALU_SIZE                 0x7\n#define SQ_EX_MODE_EXCP_INVALID                   0x0\n#define SQ_EX_MODE_EXCP_INPUT_DENORM              0x1\n#define SQ_EX_MODE_EXCP_DIV0                      0x2\n#define SQ_EX_MODE_EXCP_OVERFLOW                  0x3\n#define SQ_EX_MODE_EXCP_UNDERFLOW                 0x4\n#define SQ_EX_MODE_EXCP_INEXACT                   0x5\n#define SQ_EX_MODE_EXCP_INT_DIV0                  0x6\n#define SQ_EX_MODE_EXCP_ADDR_WATCH                0x7\n#define SQ_EX_MODE_EXCP_MEM_VIOL                  0x8\n#define INST_ID_ECC_INTERRUPT_MSG                 0xfffffff0\n#define INST_ID_TTRACE_NEW_PC_MSG                 0xfffffff1\n#define INST_ID_HW_TRAP                           0xfffffff2\n#define INST_ID_KILL_SEQ                          0xfffffff3\n#define INST_ID_HOST_REG_TRAP_MSG                 0xfffffffe\n#define SQ_ENC_SOP1_BITS                          0xbe800000\n#define SQ_ENC_SOP1_MASK                          0xff800000\n#define SQ_ENC_SOP1_FIELD                         0x17d\n#define SQ_ENC_SOPC_BITS                          0xbf000000\n#define SQ_ENC_SOPC_MASK                          0xff800000\n#define SQ_ENC_SOPC_FIELD                         0x17e\n#define SQ_ENC_SOPP_BITS                          0xbf800000\n#define SQ_ENC_SOPP_MASK                          0xff800000\n#define SQ_ENC_SOPP_FIELD                         0x17f\n#define SQ_ENC_SOPK_BITS                          0xb0000000\n#define SQ_ENC_SOPK_MASK                          0xf0000000\n#define SQ_ENC_SOPK_FIELD                         0xb\n#define SQ_ENC_SOP2_BITS                          0x80000000\n#define SQ_ENC_SOP2_MASK                          0xc0000000\n#define SQ_ENC_SOP2_FIELD                         0x2\n#define SQ_ENC_SMRD_BITS                          0xc0000000\n#define SQ_ENC_SMRD_MASK                          0xf8000000\n#define SQ_ENC_SMRD_FIELD                         0x18\n#define SQ_ENC_VOP1_BITS                          0x7e000000\n#define SQ_ENC_VOP1_MASK                          0xfe000000\n#define SQ_ENC_VOP1_FIELD                         0x3f\n#define SQ_ENC_VOPC_BITS                          0x7c000000\n#define SQ_ENC_VOPC_MASK                          0xfe000000\n#define SQ_ENC_VOPC_FIELD                         0x3e\n#define SQ_ENC_VOP2_BITS                          0x0\n#define SQ_ENC_VOP2_MASK                          0x80000000\n#define SQ_ENC_VOP2_FIELD                         0x0\n#define SQ_ENC_VINTRP_BITS                        0xc8000000\n#define SQ_ENC_VINTRP_MASK                        0xfc000000\n#define SQ_ENC_VINTRP_FIELD                       0x32\n#define SQ_ENC_VOP3_BITS                          0xd0000000\n#define SQ_ENC_VOP3_MASK                          0xfc000000\n#define SQ_ENC_VOP3_FIELD                         0x34\n#define SQ_ENC_DS_BITS                            0xd8000000\n#define SQ_ENC_DS_MASK                            0xfc000000\n#define SQ_ENC_DS_FIELD                           0x36\n#define SQ_ENC_MUBUF_BITS                         0xe0000000\n#define SQ_ENC_MUBUF_MASK                         0xfc000000\n#define SQ_ENC_MUBUF_FIELD                        0x38\n#define SQ_ENC_MTBUF_BITS                         0xe8000000\n#define SQ_ENC_MTBUF_MASK                         0xfc000000\n#define SQ_ENC_MTBUF_FIELD                        0x3a\n#define SQ_ENC_MIMG_BITS                          0xf0000000\n#define SQ_ENC_MIMG_MASK                          0xfc000000\n#define SQ_ENC_MIMG_FIELD                         0x3c\n#define SQ_ENC_EXP_BITS                           0xf8000000\n#define SQ_ENC_EXP_MASK                           0xfc000000\n#define SQ_ENC_EXP_FIELD                          0x3e\n#define SQ_ENC_FLAT_BITS                          0xdc000000\n#define SQ_ENC_FLAT_MASK                          0xfc000000\n#define SQ_ENC_FLAT_FIELD                         0x37\n#define SQ_WAITCNT_VM_SHIFT                       0x0\n#define SQ_SENDMSG_STREAMID_SIZE                  0x2\n#define SQ_V_OPC_COUNT                            0x100\n#define SQ_HWREG_OFFSET_SIZE                      0x5\n#define SQ_HWREG_OFFSET_SHIFT                     0x6\n#define SQ_NUM_ATTR                               0x21\n#define SQ_NUM_VGPR                               0x100\n#define SQ_SENDMSG_MSG_SIZE                       0x4\n#define SQ_NUM_TTMP                               0xc\n#define SQ_HWREG_ID_SIZE                          0x6\n#define SQ_SENDMSG_GSOP_SIZE                      0x2\n#define SQ_NUM_SGPR                               0x68\n#define SQ_EXP_NUM_MRT                            0x8\n#define SQ_SENDMSG_SYSTEM_SIZE                    0x3\n#define SQ_WAITCNT_LGKM_SHIFT                     0x8\n#define SQ_WAITCNT_EXP_SIZE                       0x3\n#define SQ_SENDMSG_SYSTEM_SHIFT                   0x4\n#define SQ_HWREG_SIZE_SHIFT                       0xb\n#define SQ_EXP_NUM_GDS                            0x5\n#define SQ_SENDMSG_MSG_SHIFT                      0x0\n#define SQ_WAITCNT_EXP_SHIFT                      0x4\n#define SQ_WAITCNT_VM_SIZE                        0x4\n#define SQ_SENDMSG_GSOP_SHIFT                     0x4\n#define SQ_SRC_VGPR_BIT                           0x100\n#define SQ_V_OP2_COUNT                            0x40\n#define SQ_EXP_NUM_PARAM                          0x20\n#define SQ_SENDMSG_STREAMID_SHIFT                 0x8\n#define SQ_V_OP1_COUNT                            0x80\n#define SQ_WAITCNT_LGKM_SIZE                      0x5\n#define SQ_EXP_NUM_POS                            0x4\n#define SQ_HWREG_SIZE_SIZE                        0x5\n#define SQ_HWREG_ID_SHIFT                         0x0\n#define SQ_S_MOV_B32                              0x3\n#define SQ_S_MOV_B64                              0x4\n#define SQ_S_CMOV_B32                             0x5\n#define SQ_S_CMOV_B64                             0x6\n#define SQ_S_NOT_B32                              0x7\n#define SQ_S_NOT_B64                              0x8\n#define SQ_S_WQM_B32                              0x9\n#define SQ_S_WQM_B64                              0xa\n#define SQ_S_BREV_B32                             0xb\n#define SQ_S_BREV_B64                             0xc\n#define SQ_S_BCNT0_I32_B32                        0xd\n#define SQ_S_BCNT0_I32_B64                        0xe\n#define SQ_S_BCNT1_I32_B32                        0xf\n#define SQ_S_BCNT1_I32_B64                        0x10\n#define SQ_S_FF0_I32_B32                          0x11\n#define SQ_S_FF0_I32_B64                          0x12\n#define SQ_S_FF1_I32_B32                          0x13\n#define SQ_S_FF1_I32_B64                          0x14\n#define SQ_S_FLBIT_I32_B32                        0x15\n#define SQ_S_FLBIT_I32_B64                        0x16\n#define SQ_S_FLBIT_I32                            0x17\n#define SQ_S_FLBIT_I32_I64                        0x18\n#define SQ_S_SEXT_I32_I8                          0x19\n#define SQ_S_SEXT_I32_I16                         0x1a\n#define SQ_S_BITSET0_B32                          0x1b\n#define SQ_S_BITSET0_B64                          0x1c\n#define SQ_S_BITSET1_B32                          0x1d\n#define SQ_S_BITSET1_B64                          0x1e\n#define SQ_S_GETPC_B64                            0x1f\n#define SQ_S_SETPC_B64                            0x20\n#define SQ_S_SWAPPC_B64                           0x21\n#define SQ_S_RFE_B64                              0x22\n#define SQ_S_AND_SAVEEXEC_B64                     0x24\n#define SQ_S_OR_SAVEEXEC_B64                      0x25\n#define SQ_S_XOR_SAVEEXEC_B64                     0x26\n#define SQ_S_ANDN2_SAVEEXEC_B64                   0x27\n#define SQ_S_ORN2_SAVEEXEC_B64                    0x28\n#define SQ_S_NAND_SAVEEXEC_B64                    0x29\n#define SQ_S_NOR_SAVEEXEC_B64                     0x2a\n#define SQ_S_XNOR_SAVEEXEC_B64                    0x2b\n#define SQ_S_QUADMASK_B32                         0x2c\n#define SQ_S_QUADMASK_B64                         0x2d\n#define SQ_S_MOVRELS_B32                          0x2e\n#define SQ_S_MOVRELS_B64                          0x2f\n#define SQ_S_MOVRELD_B32                          0x30\n#define SQ_S_MOVRELD_B64                          0x31\n#define SQ_S_CBRANCH_JOIN                         0x32\n#define SQ_S_MOV_REGRD_B32                        0x33\n#define SQ_S_ABS_I32                              0x34\n#define SQ_S_MOV_FED_B32                          0x35\n#define SQ_ATTR0                                  0x0\n#define SQ_S_MOVK_I32                             0x0\n#define SQ_S_CMOVK_I32                            0x2\n#define SQ_S_CMPK_EQ_I32                          0x3\n#define SQ_S_CMPK_LG_I32                          0x4\n#define SQ_S_CMPK_GT_I32                          0x5\n#define SQ_S_CMPK_GE_I32                          0x6\n#define SQ_S_CMPK_LT_I32                          0x7\n#define SQ_S_CMPK_LE_I32                          0x8\n#define SQ_S_CMPK_EQ_U32                          0x9\n#define SQ_S_CMPK_LG_U32                          0xa\n#define SQ_S_CMPK_GT_U32                          0xb\n#define SQ_S_CMPK_GE_U32                          0xc\n#define SQ_S_CMPK_LT_U32                          0xd\n#define SQ_S_CMPK_LE_U32                          0xe\n#define SQ_S_ADDK_I32                             0xf\n#define SQ_S_MULK_I32                             0x10\n#define SQ_S_CBRANCH_I_FORK                       0x11\n#define SQ_S_GETREG_B32                           0x12\n#define SQ_S_SETREG_B32                           0x13\n#define SQ_S_GETREG_REGRD_B32                     0x14\n#define SQ_S_SETREG_IMM32_B32                     0x15\n#define SQ_TBA_LO                                 0x6c\n#define SQ_TBA_HI                                 0x6d\n#define SQ_TMA_LO                                 0x6e\n#define SQ_TMA_HI                                 0x6f\n#define SQ_TTMP0                                  0x70\n#define SQ_TTMP1                                  0x71\n#define SQ_TTMP2                                  0x72\n#define SQ_TTMP3                                  0x73\n#define SQ_TTMP4                                  0x74\n#define SQ_TTMP5                                  0x75\n#define SQ_TTMP6                                  0x76\n#define SQ_TTMP7                                  0x77\n#define SQ_TTMP8                                  0x78\n#define SQ_TTMP9                                  0x79\n#define SQ_TTMP10                                 0x7a\n#define SQ_TTMP11                                 0x7b\n#define SQ_VGPR0                                  0x0\n#define SQ_EXP                                    0x0\n#define SQ_EXP_MRT0                               0x0\n#define SQ_EXP_MRTZ                               0x8\n#define SQ_EXP_NULL                               0x9\n#define SQ_EXP_POS0                               0xc\n#define SQ_EXP_PARAM0                             0x20\n#define SQ_CNT1                                   0x0\n#define SQ_CNT2                                   0x1\n#define SQ_CNT3                                   0x2\n#define SQ_CNT4                                   0x3\n#define SQ_F                                      0x0\n#define SQ_LT                                     0x1\n#define SQ_EQ                                     0x2\n#define SQ_LE                                     0x3\n#define SQ_GT                                     0x4\n#define SQ_LG                                     0x5\n#define SQ_GE                                     0x6\n#define SQ_O                                      0x7\n#define SQ_U                                      0x8\n#define SQ_NGE                                    0x9\n#define SQ_NLG                                    0xa\n#define SQ_NGT                                    0xb\n#define SQ_NLE                                    0xc\n#define SQ_NEQ                                    0xd\n#define SQ_NLT                                    0xe\n#define SQ_TRU                                    0xf\n#define SQ_V_CMP_F_F32                            0x0\n#define SQ_V_CMP_LT_F32                           0x1\n#define SQ_V_CMP_EQ_F32                           0x2\n#define SQ_V_CMP_LE_F32                           0x3\n#define SQ_V_CMP_GT_F32                           0x4\n#define SQ_V_CMP_LG_F32                           0x5\n#define SQ_V_CMP_GE_F32                           0x6\n#define SQ_V_CMP_O_F32                            0x7\n#define SQ_V_CMP_U_F32                            0x8\n#define SQ_V_CMP_NGE_F32                          0x9\n#define SQ_V_CMP_NLG_F32                          0xa\n#define SQ_V_CMP_NGT_F32                          0xb\n#define SQ_V_CMP_NLE_F32                          0xc\n#define SQ_V_CMP_NEQ_F32                          0xd\n#define SQ_V_CMP_NLT_F32                          0xe\n#define SQ_V_CMP_TRU_F32                          0xf\n#define SQ_V_CMPX_F_F32                           0x10\n#define SQ_V_CMPX_LT_F32                          0x11\n#define SQ_V_CMPX_EQ_F32                          0x12\n#define SQ_V_CMPX_LE_F32                          0x13\n#define SQ_V_CMPX_GT_F32                          0x14\n#define SQ_V_CMPX_LG_F32                          0x15\n#define SQ_V_CMPX_GE_F32                          0x16\n#define SQ_V_CMPX_O_F32                           0x17\n#define SQ_V_CMPX_U_F32                           0x18\n#define SQ_V_CMPX_NGE_F32                         0x19\n#define SQ_V_CMPX_NLG_F32                         0x1a\n#define SQ_V_CMPX_NGT_F32                         0x1b\n#define SQ_V_CMPX_NLE_F32                         0x1c\n#define SQ_V_CMPX_NEQ_F32                         0x1d\n#define SQ_V_CMPX_NLT_F32                         0x1e\n#define SQ_V_CMPX_TRU_F32                         0x1f\n#define SQ_V_CMP_F_F64                            0x20\n#define SQ_V_CMP_LT_F64                           0x21\n#define SQ_V_CMP_EQ_F64                           0x22\n#define SQ_V_CMP_LE_F64                           0x23\n#define SQ_V_CMP_GT_F64                           0x24\n#define SQ_V_CMP_LG_F64                           0x25\n#define SQ_V_CMP_GE_F64                           0x26\n#define SQ_V_CMP_O_F64                            0x27\n#define SQ_V_CMP_U_F64                            0x28\n#define SQ_V_CMP_NGE_F64                          0x29\n#define SQ_V_CMP_NLG_F64                          0x2a\n#define SQ_V_CMP_NGT_F64                          0x2b\n#define SQ_V_CMP_NLE_F64                          0x2c\n#define SQ_V_CMP_NEQ_F64                          0x2d\n#define SQ_V_CMP_NLT_F64                          0x2e\n#define SQ_V_CMP_TRU_F64                          0x2f\n#define SQ_V_CMPX_F_F64                           0x30\n#define SQ_V_CMPX_LT_F64                          0x31\n#define SQ_V_CMPX_EQ_F64                          0x32\n#define SQ_V_CMPX_LE_F64                          0x33\n#define SQ_V_CMPX_GT_F64                          0x34\n#define SQ_V_CMPX_LG_F64                          0x35\n#define SQ_V_CMPX_GE_F64                          0x36\n#define SQ_V_CMPX_O_F64                           0x37\n#define SQ_V_CMPX_U_F64                           0x38\n#define SQ_V_CMPX_NGE_F64                         0x39\n#define SQ_V_CMPX_NLG_F64                         0x3a\n#define SQ_V_CMPX_NGT_F64                         0x3b\n#define SQ_V_CMPX_NLE_F64                         0x3c\n#define SQ_V_CMPX_NEQ_F64                         0x3d\n#define SQ_V_CMPX_NLT_F64                         0x3e\n#define SQ_V_CMPX_TRU_F64                         0x3f\n#define SQ_V_CMPS_F_F32                           0x40\n#define SQ_V_CMPS_LT_F32                          0x41\n#define SQ_V_CMPS_EQ_F32                          0x42\n#define SQ_V_CMPS_LE_F32                          0x43\n#define SQ_V_CMPS_GT_F32                          0x44\n#define SQ_V_CMPS_LG_F32                          0x45\n#define SQ_V_CMPS_GE_F32                          0x46\n#define SQ_V_CMPS_O_F32                           0x47\n#define SQ_V_CMPS_U_F32                           0x48\n#define SQ_V_CMPS_NGE_F32                         0x49\n#define SQ_V_CMPS_NLG_F32                         0x4a\n#define SQ_V_CMPS_NGT_F32                         0x4b\n#define SQ_V_CMPS_NLE_F32                         0x4c\n#define SQ_V_CMPS_NEQ_F32                         0x4d\n#define SQ_V_CMPS_NLT_F32                         0x4e\n#define SQ_V_CMPS_TRU_F32                         0x4f\n#define SQ_V_CMPSX_F_F32                          0x50\n#define SQ_V_CMPSX_LT_F32                         0x51\n#define SQ_V_CMPSX_EQ_F32                         0x52\n#define SQ_V_CMPSX_LE_F32                         0x53\n#define SQ_V_CMPSX_GT_F32                         0x54\n#define SQ_V_CMPSX_LG_F32                         0x55\n#define SQ_V_CMPSX_GE_F32                         0x56\n#define SQ_V_CMPSX_O_F32                          0x57\n#define SQ_V_CMPSX_U_F32                          0x58\n#define SQ_V_CMPSX_NGE_F32                        0x59\n#define SQ_V_CMPSX_NLG_F32                        0x5a\n#define SQ_V_CMPSX_NGT_F32                        0x5b\n#define SQ_V_CMPSX_NLE_F32                        0x5c\n#define SQ_V_CMPSX_NEQ_F32                        0x5d\n#define SQ_V_CMPSX_NLT_F32                        0x5e\n#define SQ_V_CMPSX_TRU_F32                        0x5f\n#define SQ_V_CMPS_F_F64                           0x60\n#define SQ_V_CMPS_LT_F64                          0x61\n#define SQ_V_CMPS_EQ_F64                          0x62\n#define SQ_V_CMPS_LE_F64                          0x63\n#define SQ_V_CMPS_GT_F64                          0x64\n#define SQ_V_CMPS_LG_F64                          0x65\n#define SQ_V_CMPS_GE_F64                          0x66\n#define SQ_V_CMPS_O_F64                           0x67\n#define SQ_V_CMPS_U_F64                           0x68\n#define SQ_V_CMPS_NGE_F64                         0x69\n#define SQ_V_CMPS_NLG_F64                         0x6a\n#define SQ_V_CMPS_NGT_F64                         0x6b\n#define SQ_V_CMPS_NLE_F64                         0x6c\n#define SQ_V_CMPS_NEQ_F64                         0x6d\n#define SQ_V_CMPS_NLT_F64                         0x6e\n#define SQ_V_CMPS_TRU_F64                         0x6f\n#define SQ_V_CMPSX_F_F64                          0x70\n#define SQ_V_CMPSX_LT_F64                         0x71\n#define SQ_V_CMPSX_EQ_F64                         0x72\n#define SQ_V_CMPSX_LE_F64                         0x73\n#define SQ_V_CMPSX_GT_F64                         0x74\n#define SQ_V_CMPSX_LG_F64                         0x75\n#define SQ_V_CMPSX_GE_F64                         0x76\n#define SQ_V_CMPSX_O_F64                          0x77\n#define SQ_V_CMPSX_U_F64                          0x78\n#define SQ_V_CMPSX_NGE_F64                        0x79\n#define SQ_V_CMPSX_NLG_F64                        0x7a\n#define SQ_V_CMPSX_NGT_F64                        0x7b\n#define SQ_V_CMPSX_NLE_F64                        0x7c\n#define SQ_V_CMPSX_NEQ_F64                        0x7d\n#define SQ_V_CMPSX_NLT_F64                        0x7e\n#define SQ_V_CMPSX_TRU_F64                        0x7f\n#define SQ_V_CMP_F_I32                            0x80\n#define SQ_V_CMP_LT_I32                           0x81\n#define SQ_V_CMP_EQ_I32                           0x82\n#define SQ_V_CMP_LE_I32                           0x83\n#define SQ_V_CMP_GT_I32                           0x84\n#define SQ_V_CMP_NE_I32                           0x85\n#define SQ_V_CMP_GE_I32                           0x86\n#define SQ_V_CMP_T_I32                            0x87\n#define SQ_V_CMPX_F_I32                           0x90\n#define SQ_V_CMPX_LT_I32                          0x91\n#define SQ_V_CMPX_EQ_I32                          0x92\n#define SQ_V_CMPX_LE_I32                          0x93\n#define SQ_V_CMPX_GT_I32                          0x94\n#define SQ_V_CMPX_NE_I32                          0x95\n#define SQ_V_CMPX_GE_I32                          0x96\n#define SQ_V_CMPX_T_I32                           0x97\n#define SQ_V_CMP_F_I64                            0xa0\n#define SQ_V_CMP_LT_I64                           0xa1\n#define SQ_V_CMP_EQ_I64                           0xa2\n#define SQ_V_CMP_LE_I64                           0xa3\n#define SQ_V_CMP_GT_I64                           0xa4\n#define SQ_V_CMP_NE_I64                           0xa5\n#define SQ_V_CMP_GE_I64                           0xa6\n#define SQ_V_CMP_T_I64                            0xa7\n#define SQ_V_CMPX_F_I64                           0xb0\n#define SQ_V_CMPX_LT_I64                          0xb1\n#define SQ_V_CMPX_EQ_I64                          0xb2\n#define SQ_V_CMPX_LE_I64                          0xb3\n#define SQ_V_CMPX_GT_I64                          0xb4\n#define SQ_V_CMPX_NE_I64                          0xb5\n#define SQ_V_CMPX_GE_I64                          0xb6\n#define SQ_V_CMPX_T_I64                           0xb7\n#define SQ_V_CMP_F_U32                            0xc0\n#define SQ_V_CMP_LT_U32                           0xc1\n#define SQ_V_CMP_EQ_U32                           0xc2\n#define SQ_V_CMP_LE_U32                           0xc3\n#define SQ_V_CMP_GT_U32                           0xc4\n#define SQ_V_CMP_NE_U32                           0xc5\n#define SQ_V_CMP_GE_U32                           0xc6\n#define SQ_V_CMP_T_U32                            0xc7\n#define SQ_V_CMPX_F_U32                           0xd0\n#define SQ_V_CMPX_LT_U32                          0xd1\n#define SQ_V_CMPX_EQ_U32                          0xd2\n#define SQ_V_CMPX_LE_U32                          0xd3\n#define SQ_V_CMPX_GT_U32                          0xd4\n#define SQ_V_CMPX_NE_U32                          0xd5\n#define SQ_V_CMPX_GE_U32                          0xd6\n#define SQ_V_CMPX_T_U32                           0xd7\n#define SQ_V_CMP_F_U64                            0xe0\n#define SQ_V_CMP_LT_U64                           0xe1\n#define SQ_V_CMP_EQ_U64                           0xe2\n#define SQ_V_CMP_LE_U64                           0xe3\n#define SQ_V_CMP_GT_U64                           0xe4\n#define SQ_V_CMP_NE_U64                           0xe5\n#define SQ_V_CMP_GE_U64                           0xe6\n#define SQ_V_CMP_T_U64                            0xe7\n#define SQ_V_CMPX_F_U64                           0xf0\n#define SQ_V_CMPX_LT_U64                          0xf1\n#define SQ_V_CMPX_EQ_U64                          0xf2\n#define SQ_V_CMPX_LE_U64                          0xf3\n#define SQ_V_CMPX_GT_U64                          0xf4\n#define SQ_V_CMPX_NE_U64                          0xf5\n#define SQ_V_CMPX_GE_U64                          0xf6\n#define SQ_V_CMPX_T_U64                           0xf7\n#define SQ_V_CMP_CLASS_F32                        0x88\n#define SQ_V_CMPX_CLASS_F32                       0x98\n#define SQ_V_CMP_CLASS_F64                        0xa8\n#define SQ_V_CMPX_CLASS_F64                       0xb8\n#define SQ_SGPR0                                  0x0\n#define SQ_F                                      0x0\n#define SQ_LT                                     0x1\n#define SQ_EQ                                     0x2\n#define SQ_LE                                     0x3\n#define SQ_GT                                     0x4\n#define SQ_NE                                     0x5\n#define SQ_GE                                     0x6\n#define SQ_T                                      0x7\n#define SQ_SRC_64_INT                             0xc0\n#define SQ_SRC_M_1_INT                            0xc1\n#define SQ_SRC_M_2_INT                            0xc2\n#define SQ_SRC_M_3_INT                            0xc3\n#define SQ_SRC_M_4_INT                            0xc4\n#define SQ_SRC_M_5_INT                            0xc5\n#define SQ_SRC_M_6_INT                            0xc6\n#define SQ_SRC_M_7_INT                            0xc7\n#define SQ_SRC_M_8_INT                            0xc8\n#define SQ_SRC_M_9_INT                            0xc9\n#define SQ_SRC_M_10_INT                           0xca\n#define SQ_SRC_M_11_INT                           0xcb\n#define SQ_SRC_M_12_INT                           0xcc\n#define SQ_SRC_M_13_INT                           0xcd\n#define SQ_SRC_M_14_INT                           0xce\n#define SQ_SRC_M_15_INT                           0xcf\n#define SQ_SRC_M_16_INT                           0xd0\n#define SQ_SRC_0_5                                0xf0\n#define SQ_SRC_M_0_5                              0xf1\n#define SQ_SRC_1                                  0xf2\n#define SQ_SRC_M_1                                0xf3\n#define SQ_SRC_2                                  0xf4\n#define SQ_SRC_M_2                                0xf5\n#define SQ_SRC_4                                  0xf6\n#define SQ_SRC_M_4                                0xf7\n#define SQ_SRC_0                                  0x80\n#define SQ_SRC_1_INT                              0x81\n#define SQ_SRC_2_INT                              0x82\n#define SQ_SRC_3_INT                              0x83\n#define SQ_SRC_4_INT                              0x84\n#define SQ_SRC_5_INT                              0x85\n#define SQ_SRC_6_INT                              0x86\n#define SQ_SRC_7_INT                              0x87\n#define SQ_SRC_8_INT                              0x88\n#define SQ_SRC_9_INT                              0x89\n#define SQ_SRC_10_INT                             0x8a\n#define SQ_SRC_11_INT                             0x8b\n#define SQ_SRC_12_INT                             0x8c\n#define SQ_SRC_13_INT                             0x8d\n#define SQ_SRC_14_INT                             0x8e\n#define SQ_SRC_15_INT                             0x8f\n#define SQ_SRC_16_INT                             0x90\n#define SQ_SRC_17_INT                             0x91\n#define SQ_SRC_18_INT                             0x92\n#define SQ_SRC_19_INT                             0x93\n#define SQ_SRC_20_INT                             0x94\n#define SQ_SRC_21_INT                             0x95\n#define SQ_SRC_22_INT                             0x96\n#define SQ_SRC_23_INT                             0x97\n#define SQ_SRC_24_INT                             0x98\n#define SQ_SRC_25_INT                             0x99\n#define SQ_SRC_26_INT                             0x9a\n#define SQ_SRC_27_INT                             0x9b\n#define SQ_SRC_28_INT                             0x9c\n#define SQ_SRC_29_INT                             0x9d\n#define SQ_SRC_30_INT                             0x9e\n#define SQ_SRC_31_INT                             0x9f\n#define SQ_SRC_32_INT                             0xa0\n#define SQ_SRC_33_INT                             0xa1\n#define SQ_SRC_34_INT                             0xa2\n#define SQ_SRC_35_INT                             0xa3\n#define SQ_SRC_36_INT                             0xa4\n#define SQ_SRC_37_INT                             0xa5\n#define SQ_SRC_38_INT                             0xa6\n#define SQ_SRC_39_INT                             0xa7\n#define SQ_SRC_40_INT                             0xa8\n#define SQ_SRC_41_INT                             0xa9\n#define SQ_SRC_42_INT                             0xaa\n#define SQ_SRC_43_INT                             0xab\n#define SQ_SRC_44_INT                             0xac\n#define SQ_SRC_45_INT                             0xad\n#define SQ_SRC_46_INT                             0xae\n#define SQ_SRC_47_INT                             0xaf\n#define SQ_SRC_48_INT                             0xb0\n#define SQ_SRC_49_INT                             0xb1\n#define SQ_SRC_50_INT                             0xb2\n#define SQ_SRC_51_INT                             0xb3\n#define SQ_SRC_52_INT                             0xb4\n#define SQ_SRC_53_INT                             0xb5\n#define SQ_SRC_54_INT                             0xb6\n#define SQ_SRC_55_INT                             0xb7\n#define SQ_SRC_56_INT                             0xb8\n#define SQ_SRC_57_INT                             0xb9\n#define SQ_SRC_58_INT                             0xba\n#define SQ_SRC_59_INT                             0xbb\n#define SQ_SRC_60_INT                             0xbc\n#define SQ_SRC_61_INT                             0xbd\n#define SQ_SRC_62_INT                             0xbe\n#define SQ_SRC_63_INT                             0xbf\n#define SQ_BUFFER_LOAD_FORMAT_X                   0x0\n#define SQ_BUFFER_LOAD_FORMAT_XY                  0x1\n#define SQ_BUFFER_LOAD_FORMAT_XYZ                 0x2\n#define SQ_BUFFER_LOAD_FORMAT_XYZW                0x3\n#define SQ_BUFFER_STORE_FORMAT_X                  0x4\n#define SQ_BUFFER_STORE_FORMAT_XY                 0x5\n#define SQ_BUFFER_STORE_FORMAT_XYZ                0x6\n#define SQ_BUFFER_STORE_FORMAT_XYZW               0x7\n#define SQ_BUFFER_LOAD_UBYTE                      0x8\n#define SQ_BUFFER_LOAD_SBYTE                      0x9\n#define SQ_BUFFER_LOAD_USHORT                     0xa\n#define SQ_BUFFER_LOAD_SSHORT                     0xb\n#define SQ_BUFFER_LOAD_DWORD                      0xc\n#define SQ_BUFFER_LOAD_DWORDX2                    0xd\n#define SQ_BUFFER_LOAD_DWORDX4                    0xe\n#define SQ_BUFFER_LOAD_DWORDX3                    0xf\n#define SQ_BUFFER_STORE_BYTE                      0x18\n#define SQ_BUFFER_STORE_SHORT                     0x1a\n#define SQ_BUFFER_STORE_DWORD                     0x1c\n#define SQ_BUFFER_STORE_DWORDX2                   0x1d\n#define SQ_BUFFER_STORE_DWORDX4                   0x1e\n#define SQ_BUFFER_STORE_DWORDX3                   0x1f\n#define SQ_BUFFER_ATOMIC_SWAP                     0x30\n#define SQ_BUFFER_ATOMIC_CMPSWAP                  0x31\n#define SQ_BUFFER_ATOMIC_ADD                      0x32\n#define SQ_BUFFER_ATOMIC_SUB                      0x33\n#define SQ_BUFFER_ATOMIC_SMIN                     0x35\n#define SQ_BUFFER_ATOMIC_UMIN                     0x36\n#define SQ_BUFFER_ATOMIC_SMAX                     0x37\n#define SQ_BUFFER_ATOMIC_UMAX                     0x38\n#define SQ_BUFFER_ATOMIC_AND                      0x39\n#define SQ_BUFFER_ATOMIC_OR                       0x3a\n#define SQ_BUFFER_ATOMIC_XOR                      0x3b\n#define SQ_BUFFER_ATOMIC_INC                      0x3c\n#define SQ_BUFFER_ATOMIC_DEC                      0x3d\n#define SQ_BUFFER_ATOMIC_FCMPSWAP                 0x3e\n#define SQ_BUFFER_ATOMIC_FMIN                     0x3f\n#define SQ_BUFFER_ATOMIC_FMAX                     0x40\n#define SQ_BUFFER_ATOMIC_SWAP_X2                  0x50\n#define SQ_BUFFER_ATOMIC_CMPSWAP_X2               0x51\n#define SQ_BUFFER_ATOMIC_ADD_X2                   0x52\n#define SQ_BUFFER_ATOMIC_SUB_X2                   0x53\n#define SQ_BUFFER_ATOMIC_SMIN_X2                  0x55\n#define SQ_BUFFER_ATOMIC_UMIN_X2                  0x56\n#define SQ_BUFFER_ATOMIC_SMAX_X2                  0x57\n#define SQ_BUFFER_ATOMIC_UMAX_X2                  0x58\n#define SQ_BUFFER_ATOMIC_AND_X2                   0x59\n#define SQ_BUFFER_ATOMIC_OR_X2                    0x5a\n#define SQ_BUFFER_ATOMIC_XOR_X2                   0x5b\n#define SQ_BUFFER_ATOMIC_INC_X2                   0x5c\n#define SQ_BUFFER_ATOMIC_DEC_X2                   0x5d\n#define SQ_BUFFER_ATOMIC_FCMPSWAP_X2              0x5e\n#define SQ_BUFFER_ATOMIC_FMIN_X2                  0x5f\n#define SQ_BUFFER_ATOMIC_FMAX_X2                  0x60\n#define SQ_BUFFER_WBINVL1_VOL                     0x70\n#define SQ_BUFFER_WBINVL1                         0x71\n#define SQ_DS_ADD_U32                             0x0\n#define SQ_DS_SUB_U32                             0x1\n#define SQ_DS_RSUB_U32                            0x2\n#define SQ_DS_INC_U32                             0x3\n#define SQ_DS_DEC_U32                             0x4\n#define SQ_DS_MIN_I32                             0x5\n#define SQ_DS_MAX_I32                             0x6\n#define SQ_DS_MIN_U32                             0x7\n#define SQ_DS_MAX_U32                             0x8\n#define SQ_DS_AND_B32                             0x9\n#define SQ_DS_OR_B32                              0xa\n#define SQ_DS_XOR_B32                             0xb\n#define SQ_DS_MSKOR_B32                           0xc\n#define SQ_DS_WRITE_B32                           0xd\n#define SQ_DS_WRITE2_B32                          0xe\n#define SQ_DS_WRITE2ST64_B32                      0xf\n#define SQ_DS_CMPST_B32                           0x10\n#define SQ_DS_CMPST_F32                           0x11\n#define SQ_DS_MIN_F32                             0x12\n#define SQ_DS_MAX_F32                             0x13\n#define SQ_DS_NOP                                 0x14\n#define SQ_DS_GWS_SEMA_RELEASE_ALL                0x18\n#define SQ_DS_GWS_INIT                            0x19\n#define SQ_DS_GWS_SEMA_V                          0x1a\n#define SQ_DS_GWS_SEMA_BR                         0x1b\n#define SQ_DS_GWS_SEMA_P                          0x1c\n#define SQ_DS_GWS_BARRIER                         0x1d\n#define SQ_DS_WRITE_B8                            0x1e\n#define SQ_DS_WRITE_B16                           0x1f\n#define SQ_DS_ADD_RTN_U32                         0x20\n#define SQ_DS_SUB_RTN_U32                         0x21\n#define SQ_DS_RSUB_RTN_U32                        0x22\n#define SQ_DS_INC_RTN_U32                         0x23\n#define SQ_DS_DEC_RTN_U32                         0x24\n#define SQ_DS_MIN_RTN_I32                         0x25\n#define SQ_DS_MAX_RTN_I32                         0x26\n#define SQ_DS_MIN_RTN_U32                         0x27\n#define SQ_DS_MAX_RTN_U32                         0x28\n#define SQ_DS_AND_RTN_B32                         0x29\n#define SQ_DS_OR_RTN_B32                          0x2a\n#define SQ_DS_XOR_RTN_B32                         0x2b\n#define SQ_DS_MSKOR_RTN_B32                       0x2c\n#define SQ_DS_WRXCHG_RTN_B32                      0x2d\n#define SQ_DS_WRXCHG2_RTN_B32                     0x2e\n#define SQ_DS_WRXCHG2ST64_RTN_B32                 0x2f\n#define SQ_DS_CMPST_RTN_B32                       0x30\n#define SQ_DS_CMPST_RTN_F32                       0x31\n#define SQ_DS_MIN_RTN_F32                         0x32\n#define SQ_DS_MAX_RTN_F32                         0x33\n#define SQ_DS_WRAP_RTN_B32                        0x34\n#define SQ_DS_SWIZZLE_B32                         0x35\n#define SQ_DS_READ_B32                            0x36\n#define SQ_DS_READ2_B32                           0x37\n#define SQ_DS_READ2ST64_B32                       0x38\n#define SQ_DS_READ_I8                             0x39\n#define SQ_DS_READ_U8                             0x3a\n#define SQ_DS_READ_I16                            0x3b\n#define SQ_DS_READ_U16                            0x3c\n#define SQ_DS_CONSUME                             0x3d\n#define SQ_DS_APPEND                              0x3e\n#define SQ_DS_ORDERED_COUNT                       0x3f\n#define SQ_DS_ADD_U64                             0x40\n#define SQ_DS_SUB_U64                             0x41\n#define SQ_DS_RSUB_U64                            0x42\n#define SQ_DS_INC_U64                             0x43\n#define SQ_DS_DEC_U64                             0x44\n#define SQ_DS_MIN_I64                             0x45\n#define SQ_DS_MAX_I64                             0x46\n#define SQ_DS_MIN_U64                             0x47\n#define SQ_DS_MAX_U64                             0x48\n#define SQ_DS_AND_B64                             0x49\n#define SQ_DS_OR_B64                              0x4a\n#define SQ_DS_XOR_B64                             0x4b\n#define SQ_DS_MSKOR_B64                           0x4c\n#define SQ_DS_WRITE_B64                           0x4d\n#define SQ_DS_WRITE2_B64                          0x4e\n#define SQ_DS_WRITE2ST64_B64                      0x4f\n#define SQ_DS_CMPST_B64                           0x50\n#define SQ_DS_CMPST_F64                           0x51\n#define SQ_DS_MIN_F64                             0x52\n#define SQ_DS_MAX_F64                             0x53\n#define SQ_DS_ADD_RTN_U64                         0x60\n#define SQ_DS_SUB_RTN_U64                         0x61\n#define SQ_DS_RSUB_RTN_U64                        0x62\n#define SQ_DS_INC_RTN_U64                         0x63\n#define SQ_DS_DEC_RTN_U64                         0x64\n#define SQ_DS_MIN_RTN_I64                         0x65\n#define SQ_DS_MAX_RTN_I64                         0x66\n#define SQ_DS_MIN_RTN_U64                         0x67\n#define SQ_DS_MAX_RTN_U64                         0x68\n#define SQ_DS_AND_RTN_B64                         0x69\n#define SQ_DS_OR_RTN_B64                          0x6a\n#define SQ_DS_XOR_RTN_B64                         0x6b\n#define SQ_DS_MSKOR_RTN_B64                       0x6c\n#define SQ_DS_WRXCHG_RTN_B64                      0x6d\n#define SQ_DS_WRXCHG2_RTN_B64                     0x6e\n#define SQ_DS_WRXCHG2ST64_RTN_B64                 0x6f\n#define SQ_DS_CMPST_RTN_B64                       0x70\n#define SQ_DS_CMPST_RTN_F64                       0x71\n#define SQ_DS_MIN_RTN_F64                         0x72\n#define SQ_DS_MAX_RTN_F64                         0x73\n#define SQ_DS_READ_B64                            0x76\n#define SQ_DS_READ2_B64                           0x77\n#define SQ_DS_READ2ST64_B64                       0x78\n#define SQ_DS_CONDXCHG32_RTN_B64                  0x7e\n#define SQ_DS_ADD_SRC2_U32                        0x80\n#define SQ_DS_SUB_SRC2_U32                        0x81\n#define SQ_DS_RSUB_SRC2_U32                       0x82\n#define SQ_DS_INC_SRC2_U32                        0x83\n#define SQ_DS_DEC_SRC2_U32                        0x84\n#define SQ_DS_MIN_SRC2_I32                        0x85\n#define SQ_DS_MAX_SRC2_I32                        0x86\n#define SQ_DS_MIN_SRC2_U32                        0x87\n#define SQ_DS_MAX_SRC2_U32                        0x88\n#define SQ_DS_AND_SRC2_B32                        0x89\n#define SQ_DS_OR_SRC2_B32                         0x8a\n#define SQ_DS_XOR_SRC2_B32                        0x8b\n#define SQ_DS_WRITE_SRC2_B32                      0x8d\n#define SQ_DS_MIN_SRC2_F32                        0x92\n#define SQ_DS_MAX_SRC2_F32                        0x93\n#define SQ_DS_ADD_SRC2_U64                        0xc0\n#define SQ_DS_SUB_SRC2_U64                        0xc1\n#define SQ_DS_RSUB_SRC2_U64                       0xc2\n#define SQ_DS_INC_SRC2_U64                        0xc3\n#define SQ_DS_DEC_SRC2_U64                        0xc4\n#define SQ_DS_MIN_SRC2_I64                        0xc5\n#define SQ_DS_MAX_SRC2_I64                        0xc6\n#define SQ_DS_MIN_SRC2_U64                        0xc7\n#define SQ_DS_MAX_SRC2_U64                        0xc8\n#define SQ_DS_AND_SRC2_B64                        0xc9\n#define SQ_DS_OR_SRC2_B64                         0xca\n#define SQ_DS_XOR_SRC2_B64                        0xcb\n#define SQ_DS_WRITE_SRC2_B64                      0xcd\n#define SQ_DS_MIN_SRC2_F64                        0xd2\n#define SQ_DS_MAX_SRC2_F64                        0xd3\n#define SQ_DS_WRITE_B96                           0xde\n#define SQ_DS_WRITE_B128                          0xdf\n#define SQ_DS_CONDXCHG32_RTN_B128                 0xfd\n#define SQ_DS_READ_B96                            0xfe\n#define SQ_DS_READ_B128                           0xff\n#define SQ_SRC_SCC                                0xfd\n#define SQ_OMOD_OFF                               0x0\n#define SQ_OMOD_M2                                0x1\n#define SQ_OMOD_M4                                0x2\n#define SQ_OMOD_D2                                0x3\n#define SQ_EXP_GDS0                               0x18\n#define SQ_GS_OP_NOP                              0x0\n#define SQ_GS_OP_CUT                              0x1\n#define SQ_GS_OP_EMIT                             0x2\n#define SQ_GS_OP_EMIT_CUT                         0x3\n#define SQ_IMAGE_LOAD                             0x0\n#define SQ_IMAGE_LOAD_MIP                         0x1\n#define SQ_IMAGE_LOAD_PCK                         0x2\n#define SQ_IMAGE_LOAD_PCK_SGN                     0x3\n#define SQ_IMAGE_LOAD_MIP_PCK                     0x4\n#define SQ_IMAGE_LOAD_MIP_PCK_SGN                 0x5\n#define SQ_IMAGE_STORE                            0x8\n#define SQ_IMAGE_STORE_MIP                        0x9\n#define SQ_IMAGE_STORE_PCK                        0xa\n#define SQ_IMAGE_STORE_MIP_PCK                    0xb\n#define SQ_IMAGE_GET_RESINFO                      0xe\n#define SQ_IMAGE_ATOMIC_SWAP                      0xf\n#define SQ_IMAGE_ATOMIC_CMPSWAP                   0x10\n#define SQ_IMAGE_ATOMIC_ADD                       0x11\n#define SQ_IMAGE_ATOMIC_SUB                       0x12\n#define SQ_IMAGE_ATOMIC_SMIN                      0x14\n#define SQ_IMAGE_ATOMIC_UMIN                      0x15\n#define SQ_IMAGE_ATOMIC_SMAX                      0x16\n#define SQ_IMAGE_ATOMIC_UMAX                      0x17\n#define SQ_IMAGE_ATOMIC_AND                       0x18\n#define SQ_IMAGE_ATOMIC_OR                        0x19\n#define SQ_IMAGE_ATOMIC_XOR                       0x1a\n#define SQ_IMAGE_ATOMIC_INC                       0x1b\n#define SQ_IMAGE_ATOMIC_DEC                       0x1c\n#define SQ_IMAGE_ATOMIC_FCMPSWAP                  0x1d\n#define SQ_IMAGE_ATOMIC_FMIN                      0x1e\n#define SQ_IMAGE_ATOMIC_FMAX                      0x1f\n#define SQ_IMAGE_SAMPLE                           0x20\n#define SQ_IMAGE_SAMPLE_CL                        0x21\n#define SQ_IMAGE_SAMPLE_D                         0x22\n#define SQ_IMAGE_SAMPLE_D_CL                      0x23\n#define SQ_IMAGE_SAMPLE_L                         0x24\n#define SQ_IMAGE_SAMPLE_B                         0x25\n#define SQ_IMAGE_SAMPLE_B_CL                      0x26\n#define SQ_IMAGE_SAMPLE_LZ                        0x27\n#define SQ_IMAGE_SAMPLE_C                         0x28\n#define SQ_IMAGE_SAMPLE_C_CL                      0x29\n#define SQ_IMAGE_SAMPLE_C_D                       0x2a\n#define SQ_IMAGE_SAMPLE_C_D_CL                    0x2b\n#define SQ_IMAGE_SAMPLE_C_L                       0x2c\n#define SQ_IMAGE_SAMPLE_C_B                       0x2d\n#define SQ_IMAGE_SAMPLE_C_B_CL                    0x2e\n#define SQ_IMAGE_SAMPLE_C_LZ                      0x2f\n#define SQ_IMAGE_SAMPLE_O                         0x30\n#define SQ_IMAGE_SAMPLE_CL_O                      0x31\n#define SQ_IMAGE_SAMPLE_D_O                       0x32\n#define SQ_IMAGE_SAMPLE_D_CL_O                    0x33\n#define SQ_IMAGE_SAMPLE_L_O                       0x34\n#define SQ_IMAGE_SAMPLE_B_O                       0x35\n#define SQ_IMAGE_SAMPLE_B_CL_O                    0x36\n#define SQ_IMAGE_SAMPLE_LZ_O                      0x37\n#define SQ_IMAGE_SAMPLE_C_O                       0x38\n#define SQ_IMAGE_SAMPLE_C_CL_O                    0x39\n#define SQ_IMAGE_SAMPLE_C_D_O                     0x3a\n#define SQ_IMAGE_SAMPLE_C_D_CL_O                  0x3b\n#define SQ_IMAGE_SAMPLE_C_L_O                     0x3c\n#define SQ_IMAGE_SAMPLE_C_B_O                     0x3d\n#define SQ_IMAGE_SAMPLE_C_B_CL_O                  0x3e\n#define SQ_IMAGE_SAMPLE_C_LZ_O                    0x3f\n#define SQ_IMAGE_GATHER4                          0x40\n#define SQ_IMAGE_GATHER4_CL                       0x41\n#define SQ_IMAGE_GATHER4_L                        0x44\n#define SQ_IMAGE_GATHER4_B                        0x45\n#define SQ_IMAGE_GATHER4_B_CL                     0x46\n#define SQ_IMAGE_GATHER4_LZ                       0x47\n#define SQ_IMAGE_GATHER4_C                        0x48\n#define SQ_IMAGE_GATHER4_C_CL                     0x49\n#define SQ_IMAGE_GATHER4_C_L                      0x4c\n#define SQ_IMAGE_GATHER4_C_B                      0x4d\n#define SQ_IMAGE_GATHER4_C_B_CL                   0x4e\n#define SQ_IMAGE_GATHER4_C_LZ                     0x4f\n#define SQ_IMAGE_GATHER4_O                        0x50\n#define SQ_IMAGE_GATHER4_CL_O                     0x51\n#define SQ_IMAGE_GATHER4_L_O                      0x54\n#define SQ_IMAGE_GATHER4_B_O                      0x55\n#define SQ_IMAGE_GATHER4_B_CL_O                   0x56\n#define SQ_IMAGE_GATHER4_LZ_O                     0x57\n#define SQ_IMAGE_GATHER4_C_O                      0x58\n#define SQ_IMAGE_GATHER4_C_CL_O                   0x59\n#define SQ_IMAGE_GATHER4_C_L_O                    0x5c\n#define SQ_IMAGE_GATHER4_C_B_O                    0x5d\n#define SQ_IMAGE_GATHER4_C_B_CL_O                 0x5e\n#define SQ_IMAGE_GATHER4_C_LZ_O                   0x5f\n#define SQ_IMAGE_GET_LOD                          0x60\n#define SQ_IMAGE_SAMPLE_CD                        0x68\n#define SQ_IMAGE_SAMPLE_CD_CL                     0x69\n#define SQ_IMAGE_SAMPLE_C_CD                      0x6a\n#define SQ_IMAGE_SAMPLE_C_CD_CL                   0x6b\n#define SQ_IMAGE_SAMPLE_CD_O                      0x6c\n#define SQ_IMAGE_SAMPLE_CD_CL_O                   0x6d\n#define SQ_IMAGE_SAMPLE_C_CD_O                    0x6e\n#define SQ_IMAGE_SAMPLE_C_CD_CL_O                 0x6f\n#define SQ_IMAGE_RSRC256                          0x7e\n#define SQ_IMAGE_SAMPLER                          0x7f\n#define SQ_SRC_VCCZ                               0xfb\n#define SQ_SRC_VGPR0                              0x100\n#define SQ_DFMT_INVALID                           0x0\n#define SQ_DFMT_8                                 0x1\n#define SQ_DFMT_16                                0x2\n#define SQ_DFMT_8_8                               0x3\n#define SQ_DFMT_32                                0x4\n#define SQ_DFMT_16_16                             0x5\n#define SQ_DFMT_10_11_11                          0x6\n#define SQ_DFMT_11_11_10                          0x7\n#define SQ_DFMT_10_10_10_2                        0x8\n#define SQ_DFMT_2_10_10_10                        0x9\n#define SQ_DFMT_8_8_8_8                           0xa\n#define SQ_DFMT_32_32                             0xb\n#define SQ_DFMT_16_16_16_16                       0xc\n#define SQ_DFMT_32_32_32                          0xd\n#define SQ_DFMT_32_32_32_32                       0xe\n#define SQ_TBUFFER_LOAD_FORMAT_X                  0x0\n#define SQ_TBUFFER_LOAD_FORMAT_XY                 0x1\n#define SQ_TBUFFER_LOAD_FORMAT_XYZ                0x2\n#define SQ_TBUFFER_LOAD_FORMAT_XYZW               0x3\n#define SQ_TBUFFER_STORE_FORMAT_X                 0x4\n#define SQ_TBUFFER_STORE_FORMAT_XY                0x5\n#define SQ_TBUFFER_STORE_FORMAT_XYZ               0x6\n#define SQ_TBUFFER_STORE_FORMAT_XYZW              0x7\n#define SQ_CHAN_X                                 0x0\n#define SQ_CHAN_Y                                 0x1\n#define SQ_CHAN_Z                                 0x2\n#define SQ_CHAN_W                                 0x3\n#define SQ_EXEC_LO                                0x7e\n#define SQ_EXEC_HI                                0x7f\n#define SQ_S_LOAD_DWORD                           0x0\n#define SQ_S_LOAD_DWORDX2                         0x1\n#define SQ_S_LOAD_DWORDX4                         0x2\n#define SQ_S_LOAD_DWORDX8                         0x3\n#define SQ_S_LOAD_DWORDX16                        0x4\n#define SQ_S_BUFFER_LOAD_DWORD                    0x8\n#define SQ_S_BUFFER_LOAD_DWORDX2                  0x9\n#define SQ_S_BUFFER_LOAD_DWORDX4                  0xa\n#define SQ_S_BUFFER_LOAD_DWORDX8                  0xb\n#define SQ_S_BUFFER_LOAD_DWORDX16                 0xc\n#define SQ_S_DCACHE_INV_VOL                       0x1d\n#define SQ_S_MEMTIME                              0x1e\n#define SQ_S_DCACHE_INV                           0x1f\n#define SQ_V_NOP                                  0x0\n#define SQ_V_MOV_B32                              0x1\n#define SQ_V_READFIRSTLANE_B32                    0x2\n#define SQ_V_CVT_I32_F64                          0x3\n#define SQ_V_CVT_F64_I32                          0x4\n#define SQ_V_CVT_F32_I32                          0x5\n#define SQ_V_CVT_F32_U32                          0x6\n#define SQ_V_CVT_U32_F32                          0x7\n#define SQ_V_CVT_I32_F32                          0x8\n#define SQ_V_MOV_FED_B32                          0x9\n#define SQ_V_CVT_F16_F32                          0xa\n#define SQ_V_CVT_F32_F16                          0xb\n#define SQ_V_CVT_RPI_I32_F32                      0xc\n#define SQ_V_CVT_FLR_I32_F32                      0xd\n#define SQ_V_CVT_OFF_F32_I4                       0xe\n#define SQ_V_CVT_F32_F64                          0xf\n#define SQ_V_CVT_F64_F32                          0x10\n#define SQ_V_CVT_F32_UBYTE0                       0x11\n#define SQ_V_CVT_F32_UBYTE1                       0x12\n#define SQ_V_CVT_F32_UBYTE2                       0x13\n#define SQ_V_CVT_F32_UBYTE3                       0x14\n#define SQ_V_CVT_U32_F64                          0x15\n#define SQ_V_CVT_F64_U32                          0x16\n#define SQ_V_TRUNC_F64                            0x17\n#define SQ_V_CEIL_F64                             0x18\n#define SQ_V_RNDNE_F64                            0x19\n#define SQ_V_FLOOR_F64                            0x1a\n#define SQ_V_FRACT_F32                            0x20\n#define SQ_V_TRUNC_F32                            0x21\n#define SQ_V_CEIL_F32                             0x22\n#define SQ_V_RNDNE_F32                            0x23\n#define SQ_V_FLOOR_F32                            0x24\n#define SQ_V_EXP_F32                              0x25\n#define SQ_V_LOG_CLAMP_F32                        0x26\n#define SQ_V_LOG_F32                              0x27\n#define SQ_V_RCP_CLAMP_F32                        0x28\n#define SQ_V_RCP_LEGACY_F32                       0x29\n#define SQ_V_RCP_F32                              0x2a\n#define SQ_V_RCP_IFLAG_F32                        0x2b\n#define SQ_V_RSQ_CLAMP_F32                        0x2c\n#define SQ_V_RSQ_LEGACY_F32                       0x2d\n#define SQ_V_RSQ_F32                              0x2e\n#define SQ_V_RCP_F64                              0x2f\n#define SQ_V_RCP_CLAMP_F64                        0x30\n#define SQ_V_RSQ_F64                              0x31\n#define SQ_V_RSQ_CLAMP_F64                        0x32\n#define SQ_V_SQRT_F32                             0x33\n#define SQ_V_SQRT_F64                             0x34\n#define SQ_V_SIN_F32                              0x35\n#define SQ_V_COS_F32                              0x36\n#define SQ_V_NOT_B32                              0x37\n#define SQ_V_BFREV_B32                            0x38\n#define SQ_V_FFBH_U32                             0x39\n#define SQ_V_FFBL_B32                             0x3a\n#define SQ_V_FFBH_I32                             0x3b\n#define SQ_V_FREXP_EXP_I32_F64                    0x3c\n#define SQ_V_FREXP_MANT_F64                       0x3d\n#define SQ_V_FRACT_F64                            0x3e\n#define SQ_V_FREXP_EXP_I32_F32                    0x3f\n#define SQ_V_FREXP_MANT_F32                       0x40\n#define SQ_V_CLREXCP                              0x41\n#define SQ_V_MOVRELD_B32                          0x42\n#define SQ_V_MOVRELS_B32                          0x43\n#define SQ_V_MOVRELSD_B32                         0x44\n#define SQ_V_LOG_LEGACY_F32                       0x45\n#define SQ_V_EXP_LEGACY_F32                       0x46\n#define SQ_NFMT_UNORM                             0x0\n#define SQ_NFMT_SNORM                             0x1\n#define SQ_NFMT_USCALED                           0x2\n#define SQ_NFMT_SSCALED                           0x3\n#define SQ_NFMT_UINT                              0x4\n#define SQ_NFMT_SINT                              0x5\n#define SQ_NFMT_SNORM_OGL                         0x6\n#define SQ_NFMT_FLOAT                             0x7\n#define SQ_V_OP1_OFFSET                           0x180\n#define SQ_V_OP2_OFFSET                           0x100\n#define SQ_V_OPC_OFFSET                           0x0\n#define SQ_V_INTERP_P1_F32                        0x0\n#define SQ_V_INTERP_P2_F32                        0x1\n#define SQ_V_INTERP_MOV_F32                       0x2\n#define SQ_S_NOP                                  0x0\n#define SQ_S_ENDPGM                               0x1\n#define SQ_S_BRANCH                               0x2\n#define SQ_S_CBRANCH_SCC0                         0x4\n#define SQ_S_CBRANCH_SCC1                         0x5\n#define SQ_S_CBRANCH_VCCZ                         0x6\n#define SQ_S_CBRANCH_VCCNZ                        0x7\n#define SQ_S_CBRANCH_EXECZ                        0x8\n#define SQ_S_CBRANCH_EXECNZ                       0x9\n#define SQ_S_BARRIER                              0xa\n#define SQ_S_SETKILL                              0xb\n#define SQ_S_WAITCNT                              0xc\n#define SQ_S_SETHALT                              0xd\n#define SQ_S_SLEEP                                0xe\n#define SQ_S_SETPRIO                              0xf\n#define SQ_S_SENDMSG                              0x10\n#define SQ_S_SENDMSGHALT                          0x11\n#define SQ_S_TRAP                                 0x12\n#define SQ_S_ICACHE_INV                           0x13\n#define SQ_S_INCPERFLEVEL                         0x14\n#define SQ_S_DECPERFLEVEL                         0x15\n#define SQ_S_TTRACEDATA                           0x16\n#define SQ_S_CBRANCH_CDBGSYS                      0x17\n#define SQ_S_CBRANCH_CDBGUSER                     0x18\n#define SQ_S_CBRANCH_CDBGSYS_OR_USER              0x19\n#define SQ_S_CBRANCH_CDBGSYS_AND_USER             0x1a\n#define SQ_SRC_LITERAL                            0xff\n#define SQ_VCC_LO                                 0x6a\n#define SQ_VCC_HI                                 0x6b\n#define SQ_PARAM_P10                              0x0\n#define SQ_PARAM_P20                              0x1\n#define SQ_PARAM_P0                               0x2\n#define SQ_SRC_LDS_DIRECT                         0xfe\n#define SQ_FLAT_SCRATCH_LO                        0x68\n#define SQ_FLAT_SCRATCH_HI                        0x69\n#define SQ_V_CNDMASK_B32                          0x0\n#define SQ_V_READLANE_B32                         0x1\n#define SQ_V_WRITELANE_B32                        0x2\n#define SQ_V_ADD_F32                              0x3\n#define SQ_V_SUB_F32                              0x4\n#define SQ_V_SUBREV_F32                           0x5\n#define SQ_V_MAC_LEGACY_F32                       0x6\n#define SQ_V_MUL_LEGACY_F32                       0x7\n#define SQ_V_MUL_F32                              0x8\n#define SQ_V_MUL_I32_I24                          0x9\n#define SQ_V_MUL_HI_I32_I24                       0xa\n#define SQ_V_MUL_U32_U24                          0xb\n#define SQ_V_MUL_HI_U32_U24                       0xc\n#define SQ_V_MIN_LEGACY_F32                       0xd\n#define SQ_V_MAX_LEGACY_F32                       0xe\n#define SQ_V_MIN_F32                              0xf\n#define SQ_V_MAX_F32                              0x10\n#define SQ_V_MIN_I32                              0x11\n#define SQ_V_MAX_I32                              0x12\n#define SQ_V_MIN_U32                              0x13\n#define SQ_V_MAX_U32                              0x14\n#define SQ_V_LSHR_B32                             0x15\n#define SQ_V_LSHRREV_B32                          0x16\n#define SQ_V_ASHR_I32                             0x17\n#define SQ_V_ASHRREV_I32                          0x18\n#define SQ_V_LSHL_B32                             0x19\n#define SQ_V_LSHLREV_B32                          0x1a\n#define SQ_V_AND_B32                              0x1b\n#define SQ_V_OR_B32                               0x1c\n#define SQ_V_XOR_B32                              0x1d\n#define SQ_V_BFM_B32                              0x1e\n#define SQ_V_MAC_F32                              0x1f\n#define SQ_V_MADMK_F32                            0x20\n#define SQ_V_MADAK_F32                            0x21\n#define SQ_V_BCNT_U32_B32                         0x22\n#define SQ_V_MBCNT_LO_U32_B32                     0x23\n#define SQ_V_MBCNT_HI_U32_B32                     0x24\n#define SQ_V_ADD_I32                              0x25\n#define SQ_V_SUB_I32                              0x26\n#define SQ_V_SUBREV_I32                           0x27\n#define SQ_V_ADDC_U32                             0x28\n#define SQ_V_SUBB_U32                             0x29\n#define SQ_V_SUBBREV_U32                          0x2a\n#define SQ_V_LDEXP_F32                            0x2b\n#define SQ_V_CVT_PKACCUM_U8_F32                   0x2c\n#define SQ_V_CVT_PKNORM_I16_F32                   0x2d\n#define SQ_V_CVT_PKNORM_U16_F32                   0x2e\n#define SQ_V_CVT_PKRTZ_F16_F32                    0x2f\n#define SQ_V_CVT_PK_U16_U32                       0x30\n#define SQ_V_CVT_PK_I16_I32                       0x31\n#define SQ_FLAT_LOAD_UBYTE                        0x8\n#define SQ_FLAT_LOAD_SBYTE                        0x9\n#define SQ_FLAT_LOAD_USHORT                       0xa\n#define SQ_FLAT_LOAD_SSHORT                       0xb\n#define SQ_FLAT_LOAD_DWORD                        0xc\n#define SQ_FLAT_LOAD_DWORDX2                      0xd\n#define SQ_FLAT_LOAD_DWORDX4                      0xe\n#define SQ_FLAT_LOAD_DWORDX3                      0xf\n#define SQ_FLAT_STORE_BYTE                        0x18\n#define SQ_FLAT_STORE_SHORT                       0x1a\n#define SQ_FLAT_STORE_DWORD                       0x1c\n#define SQ_FLAT_STORE_DWORDX2                     0x1d\n#define SQ_FLAT_STORE_DWORDX4                     0x1e\n#define SQ_FLAT_STORE_DWORDX3                     0x1f\n#define SQ_FLAT_ATOMIC_SWAP                       0x30\n#define SQ_FLAT_ATOMIC_CMPSWAP                    0x31\n#define SQ_FLAT_ATOMIC_ADD                        0x32\n#define SQ_FLAT_ATOMIC_SUB                        0x33\n#define SQ_FLAT_ATOMIC_SMIN                       0x35\n#define SQ_FLAT_ATOMIC_UMIN                       0x36\n#define SQ_FLAT_ATOMIC_SMAX                       0x37\n#define SQ_FLAT_ATOMIC_UMAX                       0x38\n#define SQ_FLAT_ATOMIC_AND                        0x39\n#define SQ_FLAT_ATOMIC_OR                         0x3a\n#define SQ_FLAT_ATOMIC_XOR                        0x3b\n#define SQ_FLAT_ATOMIC_INC                        0x3c\n#define SQ_FLAT_ATOMIC_DEC                        0x3d\n#define SQ_FLAT_ATOMIC_FCMPSWAP                   0x3e\n#define SQ_FLAT_ATOMIC_FMIN                       0x3f\n#define SQ_FLAT_ATOMIC_FMAX                       0x40\n#define SQ_FLAT_ATOMIC_SWAP_X2                    0x50\n#define SQ_FLAT_ATOMIC_CMPSWAP_X2                 0x51\n#define SQ_FLAT_ATOMIC_ADD_X2                     0x52\n#define SQ_FLAT_ATOMIC_SUB_X2                     0x53\n#define SQ_FLAT_ATOMIC_SMIN_X2                    0x55\n#define SQ_FLAT_ATOMIC_UMIN_X2                    0x56\n#define SQ_FLAT_ATOMIC_SMAX_X2                    0x57\n#define SQ_FLAT_ATOMIC_UMAX_X2                    0x58\n#define SQ_FLAT_ATOMIC_AND_X2                     0x59\n#define SQ_FLAT_ATOMIC_OR_X2                      0x5a\n#define SQ_FLAT_ATOMIC_XOR_X2                     0x5b\n#define SQ_FLAT_ATOMIC_INC_X2                     0x5c\n#define SQ_FLAT_ATOMIC_DEC_X2                     0x5d\n#define SQ_FLAT_ATOMIC_FCMPSWAP_X2                0x5e\n#define SQ_FLAT_ATOMIC_FMIN_X2                    0x5f\n#define SQ_FLAT_ATOMIC_FMAX_X2                    0x60\n#define SQ_S_CMP_EQ_I32                           0x0\n#define SQ_S_CMP_LG_I32                           0x1\n#define SQ_S_CMP_GT_I32                           0x2\n#define SQ_S_CMP_GE_I32                           0x3\n#define SQ_S_CMP_LT_I32                           0x4\n#define SQ_S_CMP_LE_I32                           0x5\n#define SQ_S_CMP_EQ_U32                           0x6\n#define SQ_S_CMP_LG_U32                           0x7\n#define SQ_S_CMP_GT_U32                           0x8\n#define SQ_S_CMP_GE_U32                           0x9\n#define SQ_S_CMP_LT_U32                           0xa\n#define SQ_S_CMP_LE_U32                           0xb\n#define SQ_S_BITCMP0_B32                          0xc\n#define SQ_S_BITCMP1_B32                          0xd\n#define SQ_S_BITCMP0_B64                          0xe\n#define SQ_S_BITCMP1_B64                          0xf\n#define SQ_S_SETVSKIP                             0x10\n#define SQ_M0                                     0x7c\n#define SQ_V_MAD_LEGACY_F32                       0x140\n#define SQ_V_MAD_F32                              0x141\n#define SQ_V_MAD_I32_I24                          0x142\n#define SQ_V_MAD_U32_U24                          0x143\n#define SQ_V_CUBEID_F32                           0x144\n#define SQ_V_CUBESC_F32                           0x145\n#define SQ_V_CUBETC_F32                           0x146\n#define SQ_V_CUBEMA_F32                           0x147\n#define SQ_V_BFE_U32                              0x148\n#define SQ_V_BFE_I32                              0x149\n#define SQ_V_BFI_B32                              0x14a\n#define SQ_V_FMA_F32                              0x14b\n#define SQ_V_FMA_F64                              0x14c\n#define SQ_V_LERP_U8                              0x14d\n#define SQ_V_ALIGNBIT_B32                         0x14e\n#define SQ_V_ALIGNBYTE_B32                        0x14f\n#define SQ_V_MULLIT_F32                           0x150\n#define SQ_V_MIN3_F32                             0x151\n#define SQ_V_MIN3_I32                             0x152\n#define SQ_V_MIN3_U32                             0x153\n#define SQ_V_MAX3_F32                             0x154\n#define SQ_V_MAX3_I32                             0x155\n#define SQ_V_MAX3_U32                             0x156\n#define SQ_V_MED3_F32                             0x157\n#define SQ_V_MED3_I32                             0x158\n#define SQ_V_MED3_U32                             0x159\n#define SQ_V_SAD_U8                               0x15a\n#define SQ_V_SAD_HI_U8                            0x15b\n#define SQ_V_SAD_U16                              0x15c\n#define SQ_V_SAD_U32                              0x15d\n#define SQ_V_CVT_PK_U8_F32                        0x15e\n#define SQ_V_DIV_FIXUP_F32                        0x15f\n#define SQ_V_DIV_FIXUP_F64                        0x160\n#define SQ_V_LSHL_B64                             0x161\n#define SQ_V_LSHR_B64                             0x162\n#define SQ_V_ASHR_I64                             0x163\n#define SQ_V_ADD_F64                              0x164\n#define SQ_V_MUL_F64                              0x165\n#define SQ_V_MIN_F64                              0x166\n#define SQ_V_MAX_F64                              0x167\n#define SQ_V_LDEXP_F64                            0x168\n#define SQ_V_MUL_LO_U32                           0x169\n#define SQ_V_MUL_HI_U32                           0x16a\n#define SQ_V_MUL_LO_I32                           0x16b\n#define SQ_V_MUL_HI_I32                           0x16c\n#define SQ_V_DIV_SCALE_F32                        0x16d\n#define SQ_V_DIV_SCALE_F64                        0x16e\n#define SQ_V_DIV_FMAS_F32                         0x16f\n#define SQ_V_DIV_FMAS_F64                         0x170\n#define SQ_V_MSAD_U8                              0x171\n#define SQ_V_QSAD_PK_U16_U8                       0x172\n#define SQ_V_MQSAD_PK_U16_U8                      0x173\n#define SQ_V_TRIG_PREOP_F64                       0x174\n#define SQ_V_MQSAD_U32_U8                         0x175\n#define SQ_V_MAD_U64_U32                          0x176\n#define SQ_V_MAD_I64_I32                          0x177\n#define SQ_VCC_ALL                                0x0\n#define SQ_SRC_EXECZ                              0xfc\n#define SQ_SYSMSG_OP_ECC_ERR_INTERRUPT            0x1\n#define SQ_SYSMSG_OP_REG_RD                       0x2\n#define SQ_SYSMSG_OP_HOST_TRAP_ACK                0x3\n#define SQ_SYSMSG_OP_TTRACE_PC                    0x4\n#define SQ_HW_REG_MODE                            0x1\n#define SQ_HW_REG_STATUS                          0x2\n#define SQ_HW_REG_TRAPSTS                         0x3\n#define SQ_HW_REG_HW_ID                           0x4\n#define SQ_HW_REG_GPR_ALLOC                       0x5\n#define SQ_HW_REG_LDS_ALLOC                       0x6\n#define SQ_HW_REG_IB_STS                          0x7\n#define SQ_HW_REG_PC_LO                           0x8\n#define SQ_HW_REG_PC_HI                           0x9\n#define SQ_HW_REG_INST_DW0                        0xa\n#define SQ_HW_REG_INST_DW1                        0xb\n#define SQ_HW_REG_IB_DBG0                         0xc\n#define SQ_S_ADD_U32                              0x0\n#define SQ_S_SUB_U32                              0x1\n#define SQ_S_ADD_I32                              0x2\n#define SQ_S_SUB_I32                              0x3\n#define SQ_S_ADDC_U32                             0x4\n#define SQ_S_SUBB_U32                             0x5\n#define SQ_S_MIN_I32                              0x6\n#define SQ_S_MIN_U32                              0x7\n#define SQ_S_MAX_I32                              0x8\n#define SQ_S_MAX_U32                              0x9\n#define SQ_S_CSELECT_B32                          0xa\n#define SQ_S_CSELECT_B64                          0xb\n#define SQ_S_AND_B32                              0xe\n#define SQ_S_AND_B64                              0xf\n#define SQ_S_OR_B32                               0x10\n#define SQ_S_OR_B64                               0x11\n#define SQ_S_XOR_B32                              0x12\n#define SQ_S_XOR_B64                              0x13\n#define SQ_S_ANDN2_B32                            0x14\n#define SQ_S_ANDN2_B64                            0x15\n#define SQ_S_ORN2_B32                             0x16\n#define SQ_S_ORN2_B64                             0x17\n#define SQ_S_NAND_B32                             0x18\n#define SQ_S_NAND_B64                             0x19\n#define SQ_S_NOR_B32                              0x1a\n#define SQ_S_NOR_B64                              0x1b\n#define SQ_S_XNOR_B32                             0x1c\n#define SQ_S_XNOR_B64                             0x1d\n#define SQ_S_LSHL_B32                             0x1e\n#define SQ_S_LSHL_B64                             0x1f\n#define SQ_S_LSHR_B32                             0x20\n#define SQ_S_LSHR_B64                             0x21\n#define SQ_S_ASHR_I32                             0x22\n#define SQ_S_ASHR_I64                             0x23\n#define SQ_S_BFM_B32                              0x24\n#define SQ_S_BFM_B64                              0x25\n#define SQ_S_MUL_I32                              0x26\n#define SQ_S_BFE_U32                              0x27\n#define SQ_S_BFE_I32                              0x28\n#define SQ_S_BFE_U64                              0x29\n#define SQ_S_BFE_I64                              0x2a\n#define SQ_S_CBRANCH_G_FORK                       0x2b\n#define SQ_S_ABSDIFF_I32                          0x2c\n#define SQ_MSG_INTERRUPT                          0x1\n#define SQ_MSG_GS                                 0x2\n#define SQ_MSG_GS_DONE                            0x3\n#define SQ_MSG_SYSMSG                             0xf\ntypedef enum TEX_BORDER_COLOR_TYPE {\n\tTEX_BorderColor_TransparentBlack                 = 0x0,\n\tTEX_BorderColor_OpaqueBlack                      = 0x1,\n\tTEX_BorderColor_OpaqueWhite                      = 0x2,\n\tTEX_BorderColor_Register                         = 0x3,\n} TEX_BORDER_COLOR_TYPE;\ntypedef enum TEX_CHROMA_KEY {\n\tTEX_ChromaKey_Disabled                           = 0x0,\n\tTEX_ChromaKey_Kill                               = 0x1,\n\tTEX_ChromaKey_Blend                              = 0x2,\n\tTEX_ChromaKey_RESERVED_3                         = 0x3,\n} TEX_CHROMA_KEY;\ntypedef enum TEX_CLAMP {\n\tTEX_Clamp_Repeat                                 = 0x0,\n\tTEX_Clamp_Mirror                                 = 0x1,\n\tTEX_Clamp_ClampToLast                            = 0x2,\n\tTEX_Clamp_MirrorOnceToLast                       = 0x3,\n\tTEX_Clamp_ClampHalfToBorder                      = 0x4,\n\tTEX_Clamp_MirrorOnceHalfToBorder                 = 0x5,\n\tTEX_Clamp_ClampToBorder                          = 0x6,\n\tTEX_Clamp_MirrorOnceToBorder                     = 0x7,\n} TEX_CLAMP;\ntypedef enum TEX_COORD_TYPE {\n\tTEX_CoordType_Unnormalized                       = 0x0,\n\tTEX_CoordType_Normalized                         = 0x1,\n} TEX_COORD_TYPE;\ntypedef enum TEX_DEPTH_COMPARE_FUNCTION {\n\tTEX_DepthCompareFunction_Never                   = 0x0,\n\tTEX_DepthCompareFunction_Less                    = 0x1,\n\tTEX_DepthCompareFunction_Equal                   = 0x2,\n\tTEX_DepthCompareFunction_LessEqual               = 0x3,\n\tTEX_DepthCompareFunction_Greater                 = 0x4,\n\tTEX_DepthCompareFunction_NotEqual                = 0x5,\n\tTEX_DepthCompareFunction_GreaterEqual            = 0x6,\n\tTEX_DepthCompareFunction_Always                  = 0x7,\n} TEX_DEPTH_COMPARE_FUNCTION;\ntypedef enum TEX_DIM {\n\tTEX_Dim_1D                                       = 0x0,\n\tTEX_Dim_2D                                       = 0x1,\n\tTEX_Dim_3D                                       = 0x2,\n\tTEX_Dim_CubeMap                                  = 0x3,\n\tTEX_Dim_1DArray                                  = 0x4,\n\tTEX_Dim_2DArray                                  = 0x5,\n\tTEX_Dim_2D_MSAA                                  = 0x6,\n\tTEX_Dim_2DArray_MSAA                             = 0x7,\n} TEX_DIM;\ntypedef enum TEX_FORMAT_COMP {\n\tTEX_FormatComp_Unsigned                          = 0x0,\n\tTEX_FormatComp_Signed                            = 0x1,\n\tTEX_FormatComp_UnsignedBiased                    = 0x2,\n\tTEX_FormatComp_RESERVED_3                        = 0x3,\n} TEX_FORMAT_COMP;\ntypedef enum TEX_MAX_ANISO_RATIO {\n\tTEX_MaxAnisoRatio_1to1                           = 0x0,\n\tTEX_MaxAnisoRatio_2to1                           = 0x1,\n\tTEX_MaxAnisoRatio_4to1                           = 0x2,\n\tTEX_MaxAnisoRatio_8to1                           = 0x3,\n\tTEX_MaxAnisoRatio_16to1                          = 0x4,\n\tTEX_MaxAnisoRatio_RESERVED_5                     = 0x5,\n\tTEX_MaxAnisoRatio_RESERVED_6                     = 0x6,\n\tTEX_MaxAnisoRatio_RESERVED_7                     = 0x7,\n} TEX_MAX_ANISO_RATIO;\ntypedef enum TEX_MIP_FILTER {\n\tTEX_MipFilter_None                               = 0x0,\n\tTEX_MipFilter_Point                              = 0x1,\n\tTEX_MipFilter_Linear                             = 0x2,\n\tTEX_MipFilter_RESERVED_3                         = 0x3,\n} TEX_MIP_FILTER;\ntypedef enum TEX_REQUEST_SIZE {\n\tTEX_RequestSize_32B                              = 0x0,\n\tTEX_RequestSize_64B                              = 0x1,\n\tTEX_RequestSize_128B                             = 0x2,\n\tTEX_RequestSize_2X64B                            = 0x3,\n} TEX_REQUEST_SIZE;\ntypedef enum TEX_SAMPLER_TYPE {\n\tTEX_SamplerType_Invalid                          = 0x0,\n\tTEX_SamplerType_Valid                            = 0x1,\n} TEX_SAMPLER_TYPE;\ntypedef enum TEX_XY_FILTER {\n\tTEX_XYFilter_Point                               = 0x0,\n\tTEX_XYFilter_Linear                              = 0x1,\n\tTEX_XYFilter_AnisoPoint                          = 0x2,\n\tTEX_XYFilter_AnisoLinear                         = 0x3,\n} TEX_XY_FILTER;\ntypedef enum TEX_Z_FILTER {\n\tTEX_ZFilter_None                                 = 0x0,\n\tTEX_ZFilter_Point                                = 0x1,\n\tTEX_ZFilter_Linear                               = 0x2,\n\tTEX_ZFilter_RESERVED_3                           = 0x3,\n} TEX_Z_FILTER;\ntypedef enum VTX_CLAMP {\n\tVTX_Clamp_ClampToZero                            = 0x0,\n\tVTX_Clamp_ClampToNAN                             = 0x1,\n} VTX_CLAMP;\ntypedef enum VTX_FETCH_TYPE {\n\tVTX_FetchType_VertexData                         = 0x0,\n\tVTX_FetchType_InstanceData                       = 0x1,\n\tVTX_FetchType_NoIndexOffset                      = 0x2,\n\tVTX_FetchType_RESERVED_3                         = 0x3,\n} VTX_FETCH_TYPE;\ntypedef enum VTX_FORMAT_COMP_ALL {\n\tVTX_FormatCompAll_Unsigned                       = 0x0,\n\tVTX_FormatCompAll_Signed                         = 0x1,\n} VTX_FORMAT_COMP_ALL;\ntypedef enum VTX_MEM_REQUEST_SIZE {\n\tVTX_MemRequestSize_32B                           = 0x0,\n\tVTX_MemRequestSize_64B                           = 0x1,\n} VTX_MEM_REQUEST_SIZE;\ntypedef enum TVX_DATA_FORMAT {\n\tTVX_FMT_INVALID                                  = 0x0,\n\tTVX_FMT_8                                        = 0x1,\n\tTVX_FMT_4_4                                      = 0x2,\n\tTVX_FMT_3_3_2                                    = 0x3,\n\tTVX_FMT_RESERVED_4                               = 0x4,\n\tTVX_FMT_16                                       = 0x5,\n\tTVX_FMT_16_FLOAT                                 = 0x6,\n\tTVX_FMT_8_8                                      = 0x7,\n\tTVX_FMT_5_6_5                                    = 0x8,\n\tTVX_FMT_6_5_5                                    = 0x9,\n\tTVX_FMT_1_5_5_5                                  = 0xa,\n\tTVX_FMT_4_4_4_4                                  = 0xb,\n\tTVX_FMT_5_5_5_1                                  = 0xc,\n\tTVX_FMT_32                                       = 0xd,\n\tTVX_FMT_32_FLOAT                                 = 0xe,\n\tTVX_FMT_16_16                                    = 0xf,\n\tTVX_FMT_16_16_FLOAT                              = 0x10,\n\tTVX_FMT_8_24                                     = 0x11,\n\tTVX_FMT_8_24_FLOAT                               = 0x12,\n\tTVX_FMT_24_8                                     = 0x13,\n\tTVX_FMT_24_8_FLOAT                               = 0x14,\n\tTVX_FMT_10_11_11                                 = 0x15,\n\tTVX_FMT_10_11_11_FLOAT                           = 0x16,\n\tTVX_FMT_11_11_10                                 = 0x17,\n\tTVX_FMT_11_11_10_FLOAT                           = 0x18,\n\tTVX_FMT_2_10_10_10                               = 0x19,\n\tTVX_FMT_8_8_8_8                                  = 0x1a,\n\tTVX_FMT_10_10_10_2                               = 0x1b,\n\tTVX_FMT_X24_8_32_FLOAT                           = 0x1c,\n\tTVX_FMT_32_32                                    = 0x1d,\n\tTVX_FMT_32_32_FLOAT                              = 0x1e,\n\tTVX_FMT_16_16_16_16                              = 0x1f,\n\tTVX_FMT_16_16_16_16_FLOAT                        = 0x20,\n\tTVX_FMT_RESERVED_33                              = 0x21,\n\tTVX_FMT_32_32_32_32                              = 0x22,\n\tTVX_FMT_32_32_32_32_FLOAT                        = 0x23,\n\tTVX_FMT_RESERVED_36                              = 0x24,\n\tTVX_FMT_1                                        = 0x25,\n\tTVX_FMT_1_REVERSED                               = 0x26,\n\tTVX_FMT_GB_GR                                    = 0x27,\n\tTVX_FMT_BG_RG                                    = 0x28,\n\tTVX_FMT_32_AS_8                                  = 0x29,\n\tTVX_FMT_32_AS_8_8                                = 0x2a,\n\tTVX_FMT_5_9_9_9_SHAREDEXP                        = 0x2b,\n\tTVX_FMT_8_8_8                                    = 0x2c,\n\tTVX_FMT_16_16_16                                 = 0x2d,\n\tTVX_FMT_16_16_16_FLOAT                           = 0x2e,\n\tTVX_FMT_32_32_32                                 = 0x2f,\n\tTVX_FMT_32_32_32_FLOAT                           = 0x30,\n\tTVX_FMT_BC1                                      = 0x31,\n\tTVX_FMT_BC2                                      = 0x32,\n\tTVX_FMT_BC3                                      = 0x33,\n\tTVX_FMT_BC4                                      = 0x34,\n\tTVX_FMT_BC5                                      = 0x35,\n\tTVX_FMT_APC0                                     = 0x36,\n\tTVX_FMT_APC1                                     = 0x37,\n\tTVX_FMT_APC2                                     = 0x38,\n\tTVX_FMT_APC3                                     = 0x39,\n\tTVX_FMT_APC4                                     = 0x3a,\n\tTVX_FMT_APC5                                     = 0x3b,\n\tTVX_FMT_APC6                                     = 0x3c,\n\tTVX_FMT_APC7                                     = 0x3d,\n\tTVX_FMT_CTX1                                     = 0x3e,\n\tTVX_FMT_RESERVED_63                              = 0x3f,\n} TVX_DATA_FORMAT;\ntypedef enum TVX_DST_SEL {\n\tTVX_DstSel_X                                     = 0x0,\n\tTVX_DstSel_Y                                     = 0x1,\n\tTVX_DstSel_Z                                     = 0x2,\n\tTVX_DstSel_W                                     = 0x3,\n\tTVX_DstSel_0f                                    = 0x4,\n\tTVX_DstSel_1f                                    = 0x5,\n\tTVX_DstSel_RESERVED_6                            = 0x6,\n\tTVX_DstSel_Mask                                  = 0x7,\n} TVX_DST_SEL;\ntypedef enum TVX_ENDIAN_SWAP {\n\tTVX_EndianSwap_None                              = 0x0,\n\tTVX_EndianSwap_8in16                             = 0x1,\n\tTVX_EndianSwap_8in32                             = 0x2,\n\tTVX_EndianSwap_8in64                             = 0x3,\n} TVX_ENDIAN_SWAP;\ntypedef enum TVX_INST {\n\tTVX_Inst_NormalVertexFetch                       = 0x0,\n\tTVX_Inst_SemanticVertexFetch                     = 0x1,\n\tTVX_Inst_RESERVED_2                              = 0x2,\n\tTVX_Inst_LD                                      = 0x3,\n\tTVX_Inst_GetTextureResInfo                       = 0x4,\n\tTVX_Inst_GetNumberOfSamples                      = 0x5,\n\tTVX_Inst_GetLOD                                  = 0x6,\n\tTVX_Inst_GetGradientsH                           = 0x7,\n\tTVX_Inst_GetGradientsV                           = 0x8,\n\tTVX_Inst_SetTextureOffsets                       = 0x9,\n\tTVX_Inst_KeepGradients                           = 0xa,\n\tTVX_Inst_SetGradientsH                           = 0xb,\n\tTVX_Inst_SetGradientsV                           = 0xc,\n\tTVX_Inst_Pass                                    = 0xd,\n\tTVX_Inst_GetBufferResInfo                        = 0xe,\n\tTVX_Inst_RESERVED_15                             = 0xf,\n\tTVX_Inst_Sample                                  = 0x10,\n\tTVX_Inst_Sample_L                                = 0x11,\n\tTVX_Inst_Sample_LB                               = 0x12,\n\tTVX_Inst_Sample_LZ                               = 0x13,\n\tTVX_Inst_Sample_G                                = 0x14,\n\tTVX_Inst_Gather4                                 = 0x15,\n\tTVX_Inst_Sample_G_LB                             = 0x16,\n\tTVX_Inst_Gather4_O                               = 0x17,\n\tTVX_Inst_Sample_C                                = 0x18,\n\tTVX_Inst_Sample_C_L                              = 0x19,\n\tTVX_Inst_Sample_C_LB                             = 0x1a,\n\tTVX_Inst_Sample_C_LZ                             = 0x1b,\n\tTVX_Inst_Sample_C_G                              = 0x1c,\n\tTVX_Inst_Gather4_C                               = 0x1d,\n\tTVX_Inst_Sample_C_G_LB                           = 0x1e,\n\tTVX_Inst_Gather4_C_O                             = 0x1f,\n} TVX_INST;\ntypedef enum TVX_NUM_FORMAT_ALL {\n\tTVX_NumFormatAll_Norm                            = 0x0,\n\tTVX_NumFormatAll_Int                             = 0x1,\n\tTVX_NumFormatAll_Scaled                          = 0x2,\n\tTVX_NumFormatAll_RESERVED_3                      = 0x3,\n} TVX_NUM_FORMAT_ALL;\ntypedef enum TVX_SRC_SEL {\n\tTVX_SrcSel_X                                     = 0x0,\n\tTVX_SrcSel_Y                                     = 0x1,\n\tTVX_SrcSel_Z                                     = 0x2,\n\tTVX_SrcSel_W                                     = 0x3,\n\tTVX_SrcSel_0f                                    = 0x4,\n\tTVX_SrcSel_1f                                    = 0x5,\n} TVX_SRC_SEL;\ntypedef enum TVX_SRF_MODE_ALL {\n\tTVX_SRFModeAll_ZCMO                              = 0x0,\n\tTVX_SRFModeAll_NZ                                = 0x1,\n} TVX_SRF_MODE_ALL;\ntypedef enum TVX_TYPE {\n\tTVX_Type_InvalidTextureResource                  = 0x0,\n\tTVX_Type_InvalidVertexBuffer                     = 0x1,\n\tTVX_Type_ValidTextureResource                    = 0x2,\n\tTVX_Type_ValidVertexBuffer                       = 0x3,\n} TVX_TYPE;\ntypedef enum TC_OP_MASKS {\n\tTC_OP_MASK_FLUSH_DENROM                          = 0x8,\n\tTC_OP_MASK_64                                    = 0x20,\n\tTC_OP_MASK_NO_RTN                                = 0x40,\n} TC_OP_MASKS;\ntypedef enum TC_OP {\n\tTC_OP_READ                                       = 0x0,\n\tTC_OP_ATOMIC_FCMPSWAP_RTN_32                     = 0x1,\n\tTC_OP_ATOMIC_FMIN_RTN_32                         = 0x2,\n\tTC_OP_ATOMIC_FMAX_RTN_32                         = 0x3,\n\tTC_OP_RESERVED_FOP_RTN_32_0                      = 0x4,\n\tTC_OP_RESERVED_FOP_RTN_32_1                      = 0x5,\n\tTC_OP_RESERVED_FOP_RTN_32_2                      = 0x6,\n\tTC_OP_ATOMIC_SWAP_RTN_32                         = 0x7,\n\tTC_OP_ATOMIC_CMPSWAP_RTN_32                      = 0x8,\n\tTC_OP_ATOMIC_FCMPSWAP_FLUSH_DENORM_RTN_32        = 0x9,\n\tTC_OP_ATOMIC_FMIN_FLUSH_DENORM_RTN_32            = 0xa,\n\tTC_OP_ATOMIC_FMAX_FLUSH_DENORM_RTN_32            = 0xb,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_32_0         = 0xc,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_32_1         = 0xd,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_32_2         = 0xe,\n\tTC_OP_ATOMIC_ADD_RTN_32                          = 0xf,\n\tTC_OP_ATOMIC_SUB_RTN_32                          = 0x10,\n\tTC_OP_ATOMIC_SMIN_RTN_32                         = 0x11,\n\tTC_OP_ATOMIC_UMIN_RTN_32                         = 0x12,\n\tTC_OP_ATOMIC_SMAX_RTN_32                         = 0x13,\n\tTC_OP_ATOMIC_UMAX_RTN_32                         = 0x14,\n\tTC_OP_ATOMIC_AND_RTN_32                          = 0x15,\n\tTC_OP_ATOMIC_OR_RTN_32                           = 0x16,\n\tTC_OP_ATOMIC_XOR_RTN_32                          = 0x17,\n\tTC_OP_ATOMIC_INC_RTN_32                          = 0x18,\n\tTC_OP_ATOMIC_DEC_RTN_32                          = 0x19,\n\tTC_OP_WBINVL1_VOL                                = 0x1a,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_32_0                = 0x1b,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_32_1                = 0x1c,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_32_2                = 0x1d,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_32_3                = 0x1e,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_32_4                = 0x1f,\n\tTC_OP_WRITE                                      = 0x20,\n\tTC_OP_ATOMIC_FCMPSWAP_RTN_64                     = 0x21,\n\tTC_OP_ATOMIC_FMIN_RTN_64                         = 0x22,\n\tTC_OP_ATOMIC_FMAX_RTN_64                         = 0x23,\n\tTC_OP_RESERVED_FOP_RTN_64_0                      = 0x24,\n\tTC_OP_RESERVED_FOP_RTN_64_1                      = 0x25,\n\tTC_OP_RESERVED_FOP_RTN_64_2                      = 0x26,\n\tTC_OP_ATOMIC_SWAP_RTN_64                         = 0x27,\n\tTC_OP_ATOMIC_CMPSWAP_RTN_64                      = 0x28,\n\tTC_OP_ATOMIC_FCMPSWAP_FLUSH_DENORM_RTN_64        = 0x29,\n\tTC_OP_ATOMIC_FMIN_FLUSH_DENORM_RTN_64            = 0x2a,\n\tTC_OP_ATOMIC_FMAX_FLUSH_DENORM_RTN_64            = 0x2b,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_64_0         = 0x2c,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_64_1         = 0x2d,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_RTN_64_2         = 0x2e,\n\tTC_OP_ATOMIC_ADD_RTN_64                          = 0x2f,\n\tTC_OP_ATOMIC_SUB_RTN_64                          = 0x30,\n\tTC_OP_ATOMIC_SMIN_RTN_64                         = 0x31,\n\tTC_OP_ATOMIC_UMIN_RTN_64                         = 0x32,\n\tTC_OP_ATOMIC_SMAX_RTN_64                         = 0x33,\n\tTC_OP_ATOMIC_UMAX_RTN_64                         = 0x34,\n\tTC_OP_ATOMIC_AND_RTN_64                          = 0x35,\n\tTC_OP_ATOMIC_OR_RTN_64                           = 0x36,\n\tTC_OP_ATOMIC_XOR_RTN_64                          = 0x37,\n\tTC_OP_ATOMIC_INC_RTN_64                          = 0x38,\n\tTC_OP_ATOMIC_DEC_RTN_64                          = 0x39,\n\tTC_OP_WBL2_VOL                                   = 0x3a,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_64_0                = 0x3b,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_64_1                = 0x3c,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_64_2                = 0x3d,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_64_3                = 0x3e,\n\tTC_OP_RESERVED_NON_FLOAT_RTN_64_4                = 0x3f,\n\tTC_OP_WBINVL1                                    = 0x40,\n\tTC_OP_ATOMIC_FCMPSWAP_32                         = 0x41,\n\tTC_OP_ATOMIC_FMIN_32                             = 0x42,\n\tTC_OP_ATOMIC_FMAX_32                             = 0x43,\n\tTC_OP_RESERVED_FOP_32_0                          = 0x44,\n\tTC_OP_RESERVED_FOP_32_1                          = 0x45,\n\tTC_OP_RESERVED_FOP_32_2                          = 0x46,\n\tTC_OP_ATOMIC_SWAP_32                             = 0x47,\n\tTC_OP_ATOMIC_CMPSWAP_32                          = 0x48,\n\tTC_OP_ATOMIC_FCMPSWAP_FLUSH_DENORM_32            = 0x49,\n\tTC_OP_ATOMIC_FMIN_FLUSH_DENORM_32                = 0x4a,\n\tTC_OP_ATOMIC_FMAX_FLUSH_DENORM_32                = 0x4b,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_32_0             = 0x4c,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_32_1             = 0x4d,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_32_2             = 0x4e,\n\tTC_OP_ATOMIC_ADD_32                              = 0x4f,\n\tTC_OP_ATOMIC_SUB_32                              = 0x50,\n\tTC_OP_ATOMIC_SMIN_32                             = 0x51,\n\tTC_OP_ATOMIC_UMIN_32                             = 0x52,\n\tTC_OP_ATOMIC_SMAX_32                             = 0x53,\n\tTC_OP_ATOMIC_UMAX_32                             = 0x54,\n\tTC_OP_ATOMIC_AND_32                              = 0x55,\n\tTC_OP_ATOMIC_OR_32                               = 0x56,\n\tTC_OP_ATOMIC_XOR_32                              = 0x57,\n\tTC_OP_ATOMIC_INC_32                              = 0x58,\n\tTC_OP_ATOMIC_DEC_32                              = 0x59,\n\tTC_OP_INVL2_VOL                                  = 0x5a,\n\tTC_OP_RESERVED_NON_FLOAT_32_0                    = 0x5b,\n\tTC_OP_RESERVED_NON_FLOAT_32_1                    = 0x5c,\n\tTC_OP_RESERVED_NON_FLOAT_32_2                    = 0x5d,\n\tTC_OP_RESERVED_NON_FLOAT_32_3                    = 0x5e,\n\tTC_OP_RESERVED_NON_FLOAT_32_4                    = 0x5f,\n\tTC_OP_WBINVL2                                    = 0x60,\n\tTC_OP_ATOMIC_FCMPSWAP_64                         = 0x61,\n\tTC_OP_ATOMIC_FMIN_64                             = 0x62,\n\tTC_OP_ATOMIC_FMAX_64                             = 0x63,\n\tTC_OP_RESERVED_FOP_64_0                          = 0x64,\n\tTC_OP_RESERVED_FOP_64_1                          = 0x65,\n\tTC_OP_RESERVED_FOP_64_2                          = 0x66,\n\tTC_OP_ATOMIC_SWAP_64                             = 0x67,\n\tTC_OP_ATOMIC_CMPSWAP_64                          = 0x68,\n\tTC_OP_ATOMIC_FCMPSWAP_FLUSH_DENORM_64            = 0x69,\n\tTC_OP_ATOMIC_FMIN_FLUSH_DENORM_64                = 0x6a,\n\tTC_OP_ATOMIC_FMAX_FLUSH_DENORM_64                = 0x6b,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_64_0             = 0x6c,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_64_1             = 0x6d,\n\tTC_OP_RESERVED_FOP_FLUSH_DENORM_64_2             = 0x6e,\n\tTC_OP_ATOMIC_ADD_64                              = 0x6f,\n\tTC_OP_ATOMIC_SUB_64                              = 0x70,\n\tTC_OP_ATOMIC_SMIN_64                             = 0x71,\n\tTC_OP_ATOMIC_UMIN_64                             = 0x72,\n\tTC_OP_ATOMIC_SMAX_64                             = 0x73,\n\tTC_OP_ATOMIC_UMAX_64                             = 0x74,\n\tTC_OP_ATOMIC_AND_64                              = 0x75,\n\tTC_OP_ATOMIC_OR_64                               = 0x76,\n\tTC_OP_ATOMIC_XOR_64                              = 0x77,\n\tTC_OP_ATOMIC_INC_64                              = 0x78,\n\tTC_OP_ATOMIC_DEC_64                              = 0x79,\n\tTC_OP_INVL1L2_VOL                                = 0x7a,\n\tTC_OP_RESERVED_NON_FLOAT_64_0                    = 0x7b,\n\tTC_OP_RESERVED_NON_FLOAT_64_1                    = 0x7c,\n\tTC_OP_RESERVED_NON_FLOAT_64_2                    = 0x7d,\n\tTC_OP_RESERVED_NON_FLOAT_64_3                    = 0x7e,\n\tTC_OP_RESERVED_NON_FLOAT_64_4                    = 0x7f,\n} TC_OP;\ntypedef enum TC_CHUB_REQ_CREDITS_ENUM {\n\tTC_CHUB_REQ_CREDITS                              = 0x10,\n} TC_CHUB_REQ_CREDITS_ENUM;\ntypedef enum CHUB_TC_RET_CREDITS_ENUM {\n\tCHUB_TC_RET_CREDITS                              = 0x20,\n} CHUB_TC_RET_CREDITS_ENUM;\ntypedef enum TC_NACKS {\n\tTC_NACK_NO_FAULT                                 = 0x0,\n\tTC_NACK_PAGE_FAULT                               = 0x1,\n\tTC_NACK_PROTECTION_FAULT                         = 0x2,\n\tTC_NACK_DATA_ERROR                               = 0x3,\n} TC_NACKS;\ntypedef enum TCC_PERF_SEL {\n\tTCC_PERF_SEL_NONE                                = 0x0,\n\tTCC_PERF_SEL_CYCLE                               = 0x1,\n\tTCC_PERF_SEL_BUSY                                = 0x2,\n\tTCC_PERF_SEL_REQ                                 = 0x3,\n\tTCC_PERF_SEL_STREAMING_REQ                       = 0x4,\n\tTCC_PERF_SEL_READ                                = 0x5,\n\tTCC_PERF_SEL_WRITE                               = 0x6,\n\tTCC_PERF_SEL_ATOMIC                              = 0x7,\n\tTCC_PERF_SEL_WBINVL2                             = 0x8,\n\tTCC_PERF_SEL_WBINVL2_CYCLE                       = 0x9,\n\tTCC_PERF_SEL_HIT                                 = 0xa,\n\tTCC_PERF_SEL_MISS                                = 0xb,\n\tTCC_PERF_SEL_DEWRITE_ALLOCATE_HIT                = 0xc,\n\tTCC_PERF_SEL_FULLY_WRITTEN_HIT                   = 0xd,\n\tTCC_PERF_SEL_WRITEBACK                           = 0xe,\n\tTCC_PERF_SEL_LATENCY_FIFO_FULL                   = 0xf,\n\tTCC_PERF_SEL_SRC_FIFO_FULL                       = 0x10,\n\tTCC_PERF_SEL_HOLE_FIFO_FULL                      = 0x11,\n\tTCC_PERF_SEL_MC_WRREQ                            = 0x12,\n\tTCC_PERF_SEL_MC_WRREQ_STALL                      = 0x13,\n\tTCC_PERF_SEL_MC_WRREQ_CREDIT_STALL               = 0x14,\n\tTCC_PERF_SEL_MC_WRREQ_MC_HALT_STALL              = 0x15,\n\tTCC_PERF_SEL_TOO_MANY_MC_WRREQS_STALL            = 0x16,\n\tTCC_PERF_SEL_MC_WRREQ_LEVEL                      = 0x17,\n\tTCC_PERF_SEL_MC_RDREQ                            = 0x18,\n\tTCC_PERF_SEL_MC_RDREQ_CREDIT_STALL               = 0x19,\n\tTCC_PERF_SEL_MC_RDREQ_MC_HALT_STALL              = 0x1a,\n\tTCC_PERF_SEL_MC_RDREQ_LEVEL                      = 0x1b,\n\tTCC_PERF_SEL_TAG_STALL                           = 0x1c,\n\tTCC_PERF_SEL_TAG_WRITEBACK_FIFO_FULL             = 0x1d,\n\tTCC_PERF_SEL_TAG_MISS_NOTHING_REPLACEABLE_STALL  = 0x1e,\n\tTCC_PERF_SEL_READ_RETURN_TIMEOUT                 = 0x1f,\n\tTCC_PERF_SEL_WRITEBACK_READ_TIMEOUT              = 0x20,\n\tTCC_PERF_SEL_READ_RETURN_FULL_BUBBLE             = 0x21,\n\tTCC_PERF_SEL_BUBBLE                              = 0x22,\n\tTCC_PERF_SEL_RETURN_ACK                          = 0x23,\n\tTCC_PERF_SEL_RETURN_DATA                         = 0x24,\n\tTCC_PERF_SEL_RETURN_HOLE                         = 0x25,\n\tTCC_PERF_SEL_RETURN_ACK_HOLE                     = 0x26,\n\tTCC_PERF_SEL_IB_STALL                            = 0x27,\n\tTCC_PERF_SEL_TCA_LEVEL                           = 0x28,\n\tTCC_PERF_SEL_HOLE_LEVEL                          = 0x29,\n\tTCC_PERF_SEL_MC_RDRET_NACK                       = 0x2a,\n\tTCC_PERF_SEL_MC_WRRET_NACK                       = 0x2b,\n\tTCC_PERF_SEL_EXE_REQ                             = 0x2c,\n\tTCC_PERF_SEL_CLIENT0_REQ                         = 0x40,\n\tTCC_PERF_SEL_CLIENT1_REQ                         = 0x41,\n\tTCC_PERF_SEL_CLIENT2_REQ                         = 0x42,\n\tTCC_PERF_SEL_CLIENT3_REQ                         = 0x43,\n\tTCC_PERF_SEL_CLIENT4_REQ                         = 0x44,\n\tTCC_PERF_SEL_CLIENT5_REQ                         = 0x45,\n\tTCC_PERF_SEL_CLIENT6_REQ                         = 0x46,\n\tTCC_PERF_SEL_CLIENT7_REQ                         = 0x47,\n\tTCC_PERF_SEL_CLIENT8_REQ                         = 0x48,\n\tTCC_PERF_SEL_CLIENT9_REQ                         = 0x49,\n\tTCC_PERF_SEL_CLIENT10_REQ                        = 0x4a,\n\tTCC_PERF_SEL_CLIENT11_REQ                        = 0x4b,\n\tTCC_PERF_SEL_CLIENT12_REQ                        = 0x4c,\n\tTCC_PERF_SEL_CLIENT13_REQ                        = 0x4d,\n\tTCC_PERF_SEL_CLIENT14_REQ                        = 0x4e,\n\tTCC_PERF_SEL_CLIENT15_REQ                        = 0x4f,\n\tTCC_PERF_SEL_CLIENT16_REQ                        = 0x50,\n\tTCC_PERF_SEL_CLIENT17_REQ                        = 0x51,\n\tTCC_PERF_SEL_CLIENT18_REQ                        = 0x52,\n\tTCC_PERF_SEL_CLIENT19_REQ                        = 0x53,\n\tTCC_PERF_SEL_CLIENT20_REQ                        = 0x54,\n\tTCC_PERF_SEL_CLIENT21_REQ                        = 0x55,\n\tTCC_PERF_SEL_CLIENT22_REQ                        = 0x56,\n\tTCC_PERF_SEL_CLIENT23_REQ                        = 0x57,\n\tTCC_PERF_SEL_CLIENT24_REQ                        = 0x58,\n\tTCC_PERF_SEL_CLIENT25_REQ                        = 0x59,\n\tTCC_PERF_SEL_CLIENT26_REQ                        = 0x5a,\n\tTCC_PERF_SEL_CLIENT27_REQ                        = 0x5b,\n\tTCC_PERF_SEL_CLIENT28_REQ                        = 0x5c,\n\tTCC_PERF_SEL_CLIENT29_REQ                        = 0x5d,\n\tTCC_PERF_SEL_CLIENT30_REQ                        = 0x5e,\n\tTCC_PERF_SEL_CLIENT31_REQ                        = 0x5f,\n\tTCC_PERF_SEL_CLIENT32_REQ                        = 0x60,\n\tTCC_PERF_SEL_CLIENT33_REQ                        = 0x61,\n\tTCC_PERF_SEL_CLIENT34_REQ                        = 0x62,\n\tTCC_PERF_SEL_CLIENT35_REQ                        = 0x63,\n\tTCC_PERF_SEL_CLIENT36_REQ                        = 0x64,\n\tTCC_PERF_SEL_CLIENT37_REQ                        = 0x65,\n\tTCC_PERF_SEL_CLIENT38_REQ                        = 0x66,\n\tTCC_PERF_SEL_CLIENT39_REQ                        = 0x67,\n\tTCC_PERF_SEL_CLIENT40_REQ                        = 0x68,\n\tTCC_PERF_SEL_CLIENT41_REQ                        = 0x69,\n\tTCC_PERF_SEL_CLIENT42_REQ                        = 0x6a,\n\tTCC_PERF_SEL_CLIENT43_REQ                        = 0x6b,\n\tTCC_PERF_SEL_CLIENT44_REQ                        = 0x6c,\n\tTCC_PERF_SEL_CLIENT45_REQ                        = 0x6d,\n\tTCC_PERF_SEL_CLIENT46_REQ                        = 0x6e,\n\tTCC_PERF_SEL_CLIENT47_REQ                        = 0x6f,\n\tTCC_PERF_SEL_CLIENT48_REQ                        = 0x70,\n\tTCC_PERF_SEL_CLIENT49_REQ                        = 0x71,\n\tTCC_PERF_SEL_CLIENT50_REQ                        = 0x72,\n\tTCC_PERF_SEL_CLIENT51_REQ                        = 0x73,\n\tTCC_PERF_SEL_CLIENT52_REQ                        = 0x74,\n\tTCC_PERF_SEL_CLIENT53_REQ                        = 0x75,\n\tTCC_PERF_SEL_CLIENT54_REQ                        = 0x76,\n\tTCC_PERF_SEL_CLIENT55_REQ                        = 0x77,\n\tTCC_PERF_SEL_CLIENT56_REQ                        = 0x78,\n\tTCC_PERF_SEL_CLIENT57_REQ                        = 0x79,\n\tTCC_PERF_SEL_CLIENT58_REQ                        = 0x7a,\n\tTCC_PERF_SEL_CLIENT59_REQ                        = 0x7b,\n\tTCC_PERF_SEL_CLIENT60_REQ                        = 0x7c,\n\tTCC_PERF_SEL_CLIENT61_REQ                        = 0x7d,\n\tTCC_PERF_SEL_CLIENT62_REQ                        = 0x7e,\n\tTCC_PERF_SEL_CLIENT63_REQ                        = 0x7f,\n\tTCC_PERF_SEL_NORMAL_WRITEBACK                    = 0x80,\n\tTCC_PERF_SEL_TC_OP_WBL2_VOL_WRITEBACK            = 0x81,\n\tTCC_PERF_SEL_TC_OP_WBINVL2_WRITEBACK             = 0x82,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_WRITEBACK              = 0x83,\n\tTCC_PERF_SEL_NORMAL_EVICT                        = 0x84,\n\tTCC_PERF_SEL_TC_OP_INVL2_VOL_EVICT               = 0x85,\n\tTCC_PERF_SEL_TC_OP_INVL1L2_VOL_EVICT             = 0x86,\n\tTCC_PERF_SEL_TC_OP_WBL2_VOL_EVICT                = 0x87,\n\tTCC_PERF_SEL_TC_OP_WBINVL2_EVICT                 = 0x88,\n\tTCC_PERF_SEL_ALL_TC_OP_INV_EVICT                 = 0x89,\n\tTCC_PERF_SEL_ALL_TC_OP_INV_VOL_EVICT             = 0x8a,\n\tTCC_PERF_SEL_TC_OP_WBL2_VOL_CYCLE                = 0x8b,\n\tTCC_PERF_SEL_TC_OP_INVL2_VOL_CYCLE               = 0x8c,\n\tTCC_PERF_SEL_TC_OP_INVL1L2_VOL_CYCLE             = 0x8d,\n\tTCC_PERF_SEL_TC_OP_WBINVL2_CYCLE                 = 0x8e,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_CYCLE           = 0x8f,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_VOL_CYCLE       = 0x90,\n\tTCC_PERF_SEL_TC_OP_WBL2_VOL_START                = 0x91,\n\tTCC_PERF_SEL_TC_OP_INVL2_VOL_START               = 0x92,\n\tTCC_PERF_SEL_TC_OP_INVL1L2_VOL_START             = 0x93,\n\tTCC_PERF_SEL_TC_OP_WBINVL2_START                 = 0x94,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_START           = 0x95,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_VOL_START       = 0x96,\n\tTCC_PERF_SEL_TC_OP_WBL2_VOL_FINISH               = 0x97,\n\tTCC_PERF_SEL_TC_OP_INVL2_VOL_FINISH              = 0x98,\n\tTCC_PERF_SEL_TC_OP_INVL1L2_VOL_FINISH            = 0x99,\n\tTCC_PERF_SEL_TC_OP_WBINVL2_FINISH                = 0x9a,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_FINISH          = 0x9b,\n\tTCC_PERF_SEL_ALL_TC_OP_WB_OR_INV_VOL_FINISH      = 0x9c,\n\tTCC_PERF_SEL_VOL_MC_WRREQ                        = 0x9d,\n\tTCC_PERF_SEL_VOL_MC_RDREQ                        = 0x9e,\n\tTCC_PERF_SEL_VOL_REQ                             = 0x9f,\n} TCC_PERF_SEL;\ntypedef enum TCA_PERF_SEL {\n\tTCA_PERF_SEL_NONE                                = 0x0,\n\tTCA_PERF_SEL_CYCLE                               = 0x1,\n\tTCA_PERF_SEL_BUSY                                = 0x2,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC0                    = 0x3,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC1                    = 0x4,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC2                    = 0x5,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC3                    = 0x6,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC4                    = 0x7,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC5                    = 0x8,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC6                    = 0x9,\n\tTCA_PERF_SEL_FORCED_HOLE_TCC7                    = 0xa,\n\tTCA_PERF_SEL_REQ_TCC0                            = 0xb,\n\tTCA_PERF_SEL_REQ_TCC1                            = 0xc,\n\tTCA_PERF_SEL_REQ_TCC2                            = 0xd,\n\tTCA_PERF_SEL_REQ_TCC3                            = 0xe,\n\tTCA_PERF_SEL_REQ_TCC4                            = 0xf,\n\tTCA_PERF_SEL_REQ_TCC5                            = 0x10,\n\tTCA_PERF_SEL_REQ_TCC6                            = 0x11,\n\tTCA_PERF_SEL_REQ_TCC7                            = 0x12,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC0            = 0x13,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC1            = 0x14,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC2            = 0x15,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC3            = 0x16,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC4            = 0x17,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC5            = 0x18,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC6            = 0x19,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCC7            = 0x1a,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC0                 = 0x1b,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC1                 = 0x1c,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC2                 = 0x1d,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC3                 = 0x1e,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC4                 = 0x1f,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC5                 = 0x20,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC6                 = 0x21,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCC7                 = 0x22,\n\tTCA_PERF_SEL_FORCED_HOLE_TCS                     = 0x23,\n\tTCA_PERF_SEL_REQ_TCS                             = 0x24,\n\tTCA_PERF_SEL_CROSSBAR_DOUBLE_ARB_TCS             = 0x25,\n\tTCA_PERF_SEL_CROSSBAR_STALL_TCS                  = 0x26,\n} TCA_PERF_SEL;\ntypedef enum TCS_PERF_SEL {\n\tTCS_PERF_SEL_NONE                                = 0x0,\n\tTCS_PERF_SEL_CYCLE                               = 0x1,\n\tTCS_PERF_SEL_BUSY                                = 0x2,\n\tTCS_PERF_SEL_REQ                                 = 0x3,\n\tTCS_PERF_SEL_READ                                = 0x4,\n\tTCS_PERF_SEL_WRITE                               = 0x5,\n\tTCS_PERF_SEL_ATOMIC                              = 0x6,\n\tTCS_PERF_SEL_HOLE_FIFO_FULL                      = 0x7,\n\tTCS_PERF_SEL_REQ_FIFO_FULL                       = 0x8,\n\tTCS_PERF_SEL_REQ_CREDIT_STALL                    = 0x9,\n\tTCS_PERF_SEL_REQ_NO_SRC_DATA_STALL               = 0xa,\n\tTCS_PERF_SEL_REQ_STALL                           = 0xb,\n\tTCS_PERF_SEL_TCS_CHUB_REQ_SEND                   = 0xc,\n\tTCS_PERF_SEL_CHUB_TCS_RET_SEND                   = 0xd,\n\tTCS_PERF_SEL_RETURN_ACK                          = 0xe,\n\tTCS_PERF_SEL_RETURN_DATA                         = 0xf,\n\tTCS_PERF_SEL_IB_TOTAL_REQUESTS_STALL             = 0x10,\n\tTCS_PERF_SEL_IB_STALL                            = 0x11,\n\tTCS_PERF_SEL_TCA_LEVEL                           = 0x12,\n\tTCS_PERF_SEL_HOLE_LEVEL                          = 0x13,\n\tTCS_PERF_SEL_CHUB_LEVEL                          = 0x14,\n\tTCS_PERF_SEL_CLIENT0_REQ                         = 0x40,\n\tTCS_PERF_SEL_CLIENT1_REQ                         = 0x41,\n\tTCS_PERF_SEL_CLIENT2_REQ                         = 0x42,\n\tTCS_PERF_SEL_CLIENT3_REQ                         = 0x43,\n\tTCS_PERF_SEL_CLIENT4_REQ                         = 0x44,\n\tTCS_PERF_SEL_CLIENT5_REQ                         = 0x45,\n\tTCS_PERF_SEL_CLIENT6_REQ                         = 0x46,\n\tTCS_PERF_SEL_CLIENT7_REQ                         = 0x47,\n\tTCS_PERF_SEL_CLIENT8_REQ                         = 0x48,\n\tTCS_PERF_SEL_CLIENT9_REQ                         = 0x49,\n\tTCS_PERF_SEL_CLIENT10_REQ                        = 0x4a,\n\tTCS_PERF_SEL_CLIENT11_REQ                        = 0x4b,\n\tTCS_PERF_SEL_CLIENT12_REQ                        = 0x4c,\n\tTCS_PERF_SEL_CLIENT13_REQ                        = 0x4d,\n\tTCS_PERF_SEL_CLIENT14_REQ                        = 0x4e,\n\tTCS_PERF_SEL_CLIENT15_REQ                        = 0x4f,\n\tTCS_PERF_SEL_CLIENT16_REQ                        = 0x50,\n\tTCS_PERF_SEL_CLIENT17_REQ                        = 0x51,\n\tTCS_PERF_SEL_CLIENT18_REQ                        = 0x52,\n\tTCS_PERF_SEL_CLIENT19_REQ                        = 0x53,\n\tTCS_PERF_SEL_CLIENT20_REQ                        = 0x54,\n\tTCS_PERF_SEL_CLIENT21_REQ                        = 0x55,\n\tTCS_PERF_SEL_CLIENT22_REQ                        = 0x56,\n\tTCS_PERF_SEL_CLIENT23_REQ                        = 0x57,\n\tTCS_PERF_SEL_CLIENT24_REQ                        = 0x58,\n\tTCS_PERF_SEL_CLIENT25_REQ                        = 0x59,\n\tTCS_PERF_SEL_CLIENT26_REQ                        = 0x5a,\n\tTCS_PERF_SEL_CLIENT27_REQ                        = 0x5b,\n\tTCS_PERF_SEL_CLIENT28_REQ                        = 0x5c,\n\tTCS_PERF_SEL_CLIENT29_REQ                        = 0x5d,\n\tTCS_PERF_SEL_CLIENT30_REQ                        = 0x5e,\n\tTCS_PERF_SEL_CLIENT31_REQ                        = 0x5f,\n\tTCS_PERF_SEL_CLIENT32_REQ                        = 0x60,\n\tTCS_PERF_SEL_CLIENT33_REQ                        = 0x61,\n\tTCS_PERF_SEL_CLIENT34_REQ                        = 0x62,\n\tTCS_PERF_SEL_CLIENT35_REQ                        = 0x63,\n\tTCS_PERF_SEL_CLIENT36_REQ                        = 0x64,\n\tTCS_PERF_SEL_CLIENT37_REQ                        = 0x65,\n\tTCS_PERF_SEL_CLIENT38_REQ                        = 0x66,\n\tTCS_PERF_SEL_CLIENT39_REQ                        = 0x67,\n\tTCS_PERF_SEL_CLIENT40_REQ                        = 0x68,\n\tTCS_PERF_SEL_CLIENT41_REQ                        = 0x69,\n\tTCS_PERF_SEL_CLIENT42_REQ                        = 0x6a,\n\tTCS_PERF_SEL_CLIENT43_REQ                        = 0x6b,\n\tTCS_PERF_SEL_CLIENT44_REQ                        = 0x6c,\n\tTCS_PERF_SEL_CLIENT45_REQ                        = 0x6d,\n\tTCS_PERF_SEL_CLIENT46_REQ                        = 0x6e,\n\tTCS_PERF_SEL_CLIENT47_REQ                        = 0x6f,\n\tTCS_PERF_SEL_CLIENT48_REQ                        = 0x70,\n\tTCS_PERF_SEL_CLIENT49_REQ                        = 0x71,\n\tTCS_PERF_SEL_CLIENT50_REQ                        = 0x72,\n\tTCS_PERF_SEL_CLIENT51_REQ                        = 0x73,\n\tTCS_PERF_SEL_CLIENT52_REQ                        = 0x74,\n\tTCS_PERF_SEL_CLIENT53_REQ                        = 0x75,\n\tTCS_PERF_SEL_CLIENT54_REQ                        = 0x76,\n\tTCS_PERF_SEL_CLIENT55_REQ                        = 0x77,\n\tTCS_PERF_SEL_CLIENT56_REQ                        = 0x78,\n\tTCS_PERF_SEL_CLIENT57_REQ                        = 0x79,\n\tTCS_PERF_SEL_CLIENT58_REQ                        = 0x7a,\n\tTCS_PERF_SEL_CLIENT59_REQ                        = 0x7b,\n\tTCS_PERF_SEL_CLIENT60_REQ                        = 0x7c,\n\tTCS_PERF_SEL_CLIENT61_REQ                        = 0x7d,\n\tTCS_PERF_SEL_CLIENT62_REQ                        = 0x7e,\n\tTCS_PERF_SEL_CLIENT63_REQ                        = 0x7f,\n} TCS_PERF_SEL;\ntypedef enum TA_TC_ADDR_MODES {\n\tTA_TC_ADDR_MODE_DEFAULT                          = 0x0,\n\tTA_TC_ADDR_MODE_COMP0                            = 0x1,\n\tTA_TC_ADDR_MODE_COMP1                            = 0x2,\n\tTA_TC_ADDR_MODE_COMP2                            = 0x3,\n\tTA_TC_ADDR_MODE_COMP3                            = 0x4,\n\tTA_TC_ADDR_MODE_UNALIGNED                        = 0x5,\n\tTA_TC_ADDR_MODE_BORDER_COLOR                     = 0x6,\n} TA_TC_ADDR_MODES;\ntypedef enum TA_PERFCOUNT_SEL {\n\tTA_PERF_SEL_ta_busy                              = 0x0,\n\tTA_PERF_SEL_sh_fifo_busy                         = 0x1,\n\tTA_PERF_SEL_sh_fifo_cmd_busy                     = 0x2,\n\tTA_PERF_SEL_sh_fifo_addr_busy                    = 0x3,\n\tTA_PERF_SEL_sh_fifo_data_busy                    = 0x4,\n\tTA_PERF_SEL_sh_fifo_data_sfifo_busy              = 0x5,\n\tTA_PERF_SEL_sh_fifo_data_tfifo_busy              = 0x6,\n\tTA_PERF_SEL_gradient_busy                        = 0x7,\n\tTA_PERF_SEL_gradient_fifo_busy                   = 0x8,\n\tTA_PERF_SEL_lod_busy                             = 0x9,\n\tTA_PERF_SEL_lod_fifo_busy                        = 0xa,\n\tTA_PERF_SEL_addresser_busy                       = 0xb,\n\tTA_PERF_SEL_addresser_fifo_busy                  = 0xc,\n\tTA_PERF_SEL_aligner_busy                         = 0xd,\n\tTA_PERF_SEL_write_path_busy                      = 0xe,\n\tTA_PERF_SEL_RESERVED_15                          = 0xf,\n\tTA_PERF_SEL_sq_ta_cmd_cycles                     = 0x10,\n\tTA_PERF_SEL_sp_ta_addr_cycles                    = 0x11,\n\tTA_PERF_SEL_sp_ta_data_cycles                    = 0x12,\n\tTA_PERF_SEL_ta_fa_data_state_cycles              = 0x13,\n\tTA_PERF_SEL_sh_fifo_addr_waiting_on_cmd_cycles   = 0x14,\n\tTA_PERF_SEL_sh_fifo_cmd_waiting_on_addr_cycles   = 0x15,\n\tTA_PERF_SEL_sh_fifo_addr_starved_while_busy_cycles= 0x16,\n\tTA_PERF_SEL_sh_fifo_cmd_starved_while_busy_cycles= 0x17,\n\tTA_PERF_SEL_sh_fifo_data_waiting_on_data_state_cycles= 0x18,\n\tTA_PERF_SEL_sh_fifo_data_state_waiting_on_data_cycles= 0x19,\n\tTA_PERF_SEL_sh_fifo_data_starved_while_busy_cycles= 0x1a,\n\tTA_PERF_SEL_sh_fifo_data_state_starved_while_busy_cycles= 0x1b,\n\tTA_PERF_SEL_RESERVED_28                          = 0x1c,\n\tTA_PERF_SEL_RESERVED_29                          = 0x1d,\n\tTA_PERF_SEL_sh_fifo_addr_cycles                  = 0x1e,\n\tTA_PERF_SEL_sh_fifo_data_cycles                  = 0x1f,\n\tTA_PERF_SEL_total_wavefronts                     = 0x20,\n\tTA_PERF_SEL_gradient_cycles                      = 0x21,\n\tTA_PERF_SEL_walker_cycles                        = 0x22,\n\tTA_PERF_SEL_aligner_cycles                       = 0x23,\n\tTA_PERF_SEL_image_wavefronts                     = 0x24,\n\tTA_PERF_SEL_image_read_wavefronts                = 0x25,\n\tTA_PERF_SEL_image_write_wavefronts               = 0x26,\n\tTA_PERF_SEL_image_atomic_wavefronts              = 0x27,\n\tTA_PERF_SEL_image_total_cycles                   = 0x28,\n\tTA_PERF_SEL_RESERVED_41                          = 0x29,\n\tTA_PERF_SEL_RESERVED_42                          = 0x2a,\n\tTA_PERF_SEL_RESERVED_43                          = 0x2b,\n\tTA_PERF_SEL_buffer_wavefronts                    = 0x2c,\n\tTA_PERF_SEL_buffer_read_wavefronts               = 0x2d,\n\tTA_PERF_SEL_buffer_write_wavefronts              = 0x2e,\n\tTA_PERF_SEL_buffer_atomic_wavefronts             = 0x2f,\n\tTA_PERF_SEL_buffer_coalescable_wavefronts        = 0x30,\n\tTA_PERF_SEL_buffer_total_cycles                  = 0x31,\n\tTA_PERF_SEL_buffer_coalescable_addr_multicycled_cycles= 0x32,\n\tTA_PERF_SEL_buffer_coalescable_clamp_16kdword_multicycled_cycles= 0x33,\n\tTA_PERF_SEL_buffer_coalesced_read_cycles         = 0x34,\n\tTA_PERF_SEL_buffer_coalesced_write_cycles        = 0x35,\n\tTA_PERF_SEL_addr_stalled_by_tc_cycles            = 0x36,\n\tTA_PERF_SEL_addr_stalled_by_td_cycles            = 0x37,\n\tTA_PERF_SEL_data_stalled_by_tc_cycles            = 0x38,\n\tTA_PERF_SEL_addresser_stalled_by_aligner_only_cycles= 0x39,\n\tTA_PERF_SEL_addresser_stalled_cycles             = 0x3a,\n\tTA_PERF_SEL_aniso_stalled_by_addresser_only_cycles= 0x3b,\n\tTA_PERF_SEL_aniso_stalled_cycles                 = 0x3c,\n\tTA_PERF_SEL_deriv_stalled_by_aniso_only_cycles   = 0x3d,\n\tTA_PERF_SEL_deriv_stalled_cycles                 = 0x3e,\n\tTA_PERF_SEL_aniso_gt1_cycle_quads                = 0x3f,\n\tTA_PERF_SEL_color_1_cycle_pixels                 = 0x40,\n\tTA_PERF_SEL_color_2_cycle_pixels                 = 0x41,\n\tTA_PERF_SEL_color_3_cycle_pixels                 = 0x42,\n\tTA_PERF_SEL_color_4_cycle_pixels                 = 0x43,\n\tTA_PERF_SEL_mip_1_cycle_pixels                   = 0x44,\n\tTA_PERF_SEL_mip_2_cycle_pixels                   = 0x45,\n\tTA_PERF_SEL_vol_1_cycle_pixels                   = 0x46,\n\tTA_PERF_SEL_vol_2_cycle_pixels                   = 0x47,\n\tTA_PERF_SEL_bilin_point_1_cycle_pixels           = 0x48,\n\tTA_PERF_SEL_mipmap_lod_0_samples                 = 0x49,\n\tTA_PERF_SEL_mipmap_lod_1_samples                 = 0x4a,\n\tTA_PERF_SEL_mipmap_lod_2_samples                 = 0x4b,\n\tTA_PERF_SEL_mipmap_lod_3_samples                 = 0x4c,\n\tTA_PERF_SEL_mipmap_lod_4_samples                 = 0x4d,\n\tTA_PERF_SEL_mipmap_lod_5_samples                 = 0x4e,\n\tTA_PERF_SEL_mipmap_lod_6_samples                 = 0x4f,\n\tTA_PERF_SEL_mipmap_lod_7_samples                 = 0x50,\n\tTA_PERF_SEL_mipmap_lod_8_samples                 = 0x51,\n\tTA_PERF_SEL_mipmap_lod_9_samples                 = 0x52,\n\tTA_PERF_SEL_mipmap_lod_10_samples                = 0x53,\n\tTA_PERF_SEL_mipmap_lod_11_samples                = 0x54,\n\tTA_PERF_SEL_mipmap_lod_12_samples                = 0x55,\n\tTA_PERF_SEL_mipmap_lod_13_samples                = 0x56,\n\tTA_PERF_SEL_mipmap_lod_14_samples                = 0x57,\n\tTA_PERF_SEL_mipmap_invalid_samples               = 0x58,\n\tTA_PERF_SEL_aniso_1_cycle_quads                  = 0x59,\n\tTA_PERF_SEL_aniso_2_cycle_quads                  = 0x5a,\n\tTA_PERF_SEL_aniso_4_cycle_quads                  = 0x5b,\n\tTA_PERF_SEL_aniso_6_cycle_quads                  = 0x5c,\n\tTA_PERF_SEL_aniso_8_cycle_quads                  = 0x5d,\n\tTA_PERF_SEL_aniso_10_cycle_quads                 = 0x5e,\n\tTA_PERF_SEL_aniso_12_cycle_quads                 = 0x5f,\n\tTA_PERF_SEL_aniso_14_cycle_quads                 = 0x60,\n\tTA_PERF_SEL_aniso_16_cycle_quads                 = 0x61,\n\tTA_PERF_SEL_write_path_input_cycles              = 0x62,\n\tTA_PERF_SEL_write_path_output_cycles             = 0x63,\n\tTA_PERF_SEL_flat_wavefronts                      = 0x64,\n\tTA_PERF_SEL_flat_read_wavefronts                 = 0x65,\n\tTA_PERF_SEL_flat_write_wavefronts                = 0x66,\n\tTA_PERF_SEL_flat_atomic_wavefronts               = 0x67,\n\tTA_PERF_SEL_flat_coalesceable_wavefronts         = 0x68,\n\tTA_PERF_SEL_reg_sclk_vld                         = 0x69,\n\tTA_PERF_SEL_local_cg_dyn_sclk_grp0_en            = 0x6a,\n\tTA_PERF_SEL_local_cg_dyn_sclk_grp1_en            = 0x6b,\n\tTA_PERF_SEL_local_cg_dyn_sclk_grp1_mems_en       = 0x6c,\n\tTA_PERF_SEL_local_cg_dyn_sclk_grp4_en            = 0x6d,\n\tTA_PERF_SEL_local_cg_dyn_sclk_grp5_en            = 0x6e,\n} TA_PERFCOUNT_SEL;\ntypedef enum TD_PERFCOUNT_SEL {\n\tTD_PERF_SEL_td_busy                              = 0x0,\n\tTD_PERF_SEL_input_busy                           = 0x1,\n\tTD_PERF_SEL_output_busy                          = 0x2,\n\tTD_PERF_SEL_lerp_busy                            = 0x3,\n\tTD_PERF_SEL_RESERVED_4                           = 0x4,\n\tTD_PERF_SEL_reg_sclk_vld                         = 0x5,\n\tTD_PERF_SEL_local_cg_dyn_sclk_grp0_en            = 0x6,\n\tTD_PERF_SEL_local_cg_dyn_sclk_grp1_en            = 0x7,\n\tTD_PERF_SEL_local_cg_dyn_sclk_grp4_en            = 0x8,\n\tTD_PERF_SEL_local_cg_dyn_sclk_grp5_en            = 0x9,\n\tTD_PERF_SEL_tc_td_fifo_full                      = 0xa,\n\tTD_PERF_SEL_constant_state_full                  = 0xb,\n\tTD_PERF_SEL_sample_state_full                    = 0xc,\n\tTD_PERF_SEL_output_fifo_full                     = 0xd,\n\tTD_PERF_SEL_RESERVED_14                          = 0xe,\n\tTD_PERF_SEL_tc_stall                             = 0xf,\n\tTD_PERF_SEL_pc_stall                             = 0x10,\n\tTD_PERF_SEL_gds_stall                            = 0x11,\n\tTD_PERF_SEL_RESERVED_18                          = 0x12,\n\tTD_PERF_SEL_RESERVED_19                          = 0x13,\n\tTD_PERF_SEL_gather4_wavefront                    = 0x14,\n\tTD_PERF_SEL_sample_c_wavefront                   = 0x15,\n\tTD_PERF_SEL_load_wavefront                       = 0x16,\n\tTD_PERF_SEL_atomic_wavefront                     = 0x17,\n\tTD_PERF_SEL_store_wavefront                      = 0x18,\n\tTD_PERF_SEL_ldfptr_wavefront                     = 0x19,\n\tTD_PERF_SEL_RESERVED_26                          = 0x1a,\n\tTD_PERF_SEL_RESERVED_27                          = 0x1b,\n\tTD_PERF_SEL_RESERVED_28                          = 0x1c,\n\tTD_PERF_SEL_RESERVED_29                          = 0x1d,\n\tTD_PERF_SEL_bypass_filter_wavefront              = 0x1e,\n\tTD_PERF_SEL_min_max_filter_wavefront             = 0x1f,\n\tTD_PERF_SEL_coalescable_wavefront                = 0x20,\n\tTD_PERF_SEL_coalesced_phase                      = 0x21,\n\tTD_PERF_SEL_four_phase_wavefront                 = 0x22,\n\tTD_PERF_SEL_eight_phase_wavefront                = 0x23,\n\tTD_PERF_SEL_sixteen_phase_wavefront              = 0x24,\n\tTD_PERF_SEL_four_phase_forward_wavefront         = 0x25,\n\tTD_PERF_SEL_write_ack_wavefront                  = 0x26,\n\tTD_PERF_SEL_RESERVED_39                          = 0x27,\n\tTD_PERF_SEL_user_defined_border                  = 0x28,\n\tTD_PERF_SEL_white_border                         = 0x29,\n\tTD_PERF_SEL_opaque_black_border                  = 0x2a,\n\tTD_PERF_SEL_RESERVED_43                          = 0x2b,\n\tTD_PERF_SEL_RESERVED_44                          = 0x2c,\n\tTD_PERF_SEL_nack                                 = 0x2d,\n\tTD_PERF_SEL_td_sp_traffic                        = 0x2e,\n\tTD_PERF_SEL_consume_gds_traffic                  = 0x2f,\n\tTD_PERF_SEL_addresscmd_poison                    = 0x30,\n\tTD_PERF_SEL_data_poison                          = 0x31,\n\tTD_PERF_SEL_start_cycle_0                        = 0x32,\n\tTD_PERF_SEL_start_cycle_1                        = 0x33,\n\tTD_PERF_SEL_start_cycle_2                        = 0x34,\n\tTD_PERF_SEL_start_cycle_3                        = 0x35,\n\tTD_PERF_SEL_null_cycle_output                    = 0x36,\n} TD_PERFCOUNT_SEL;\ntypedef enum TCP_PERFCOUNT_SELECT {\n\tTCP_PERF_SEL_TA_TCP_ADDR_STARVE_CYCLES           = 0x0,\n\tTCP_PERF_SEL_TA_TCP_DATA_STARVE_CYCLES           = 0x1,\n\tTCP_PERF_SEL_TCP_TA_ADDR_STALL_CYCLES            = 0x2,\n\tTCP_PERF_SEL_TCP_TA_DATA_STALL_CYCLES            = 0x3,\n\tTCP_PERF_SEL_TD_TCP_STALL_CYCLES                 = 0x4,\n\tTCP_PERF_SEL_TCR_TCP_STALL_CYCLES                = 0x5,\n\tTCP_PERF_SEL_LOD_STALL_CYCLES                    = 0x6,\n\tTCP_PERF_SEL_READ_TAGCONFLICT_STALL_CYCLES       = 0x7,\n\tTCP_PERF_SEL_WRITE_TAGCONFLICT_STALL_CYCLES      = 0x8,\n\tTCP_PERF_SEL_ATOMIC_TAGCONFLICT_STALL_CYCLES     = 0x9,\n\tTCP_PERF_SEL_ALLOC_STALL_CYCLES                  = 0xa,\n\tTCP_PERF_SEL_LFIFO_STALL_CYCLES                  = 0xb,\n\tTCP_PERF_SEL_RFIFO_STALL_CYCLES                  = 0xc,\n\tTCP_PERF_SEL_TCR_RDRET_STALL                     = 0xd,\n\tTCP_PERF_SEL_WRITE_CONFLICT_STALL                = 0xe,\n\tTCP_PERF_SEL_HOLE_READ_STALL                     = 0xf,\n\tTCP_PERF_SEL_READCONFLICT_STALL_CYCLES           = 0x10,\n\tTCP_PERF_SEL_PENDING_STALL_CYCLES                = 0x11,\n\tTCP_PERF_SEL_READFIFO_STALL_CYCLES               = 0x12,\n\tTCP_PERF_SEL_TCP_LATENCY                         = 0x13,\n\tTCP_PERF_SEL_TCC_READ_REQ_LATENCY                = 0x14,\n\tTCP_PERF_SEL_TCC_WRITE_REQ_LATENCY               = 0x15,\n\tTCP_PERF_SEL_TCC_WRITE_REQ_HOLE_LATENCY          = 0x16,\n\tTCP_PERF_SEL_TCC_READ_REQ                        = 0x17,\n\tTCP_PERF_SEL_TCC_WRITE_REQ                       = 0x18,\n\tTCP_PERF_SEL_TCC_ATOMIC_WITH_RET_REQ             = 0x19,\n\tTCP_PERF_SEL_TCC_ATOMIC_WITHOUT_RET_REQ          = 0x1a,\n\tTCP_PERF_SEL_TOTAL_LOCAL_READ                    = 0x1b,\n\tTCP_PERF_SEL_TOTAL_GLOBAL_READ                   = 0x1c,\n\tTCP_PERF_SEL_TOTAL_LOCAL_WRITE                   = 0x1d,\n\tTCP_PERF_SEL_TOTAL_GLOBAL_WRITE                  = 0x1e,\n\tTCP_PERF_SEL_TOTAL_ATOMIC_WITH_RET               = 0x1f,\n\tTCP_PERF_SEL_TOTAL_ATOMIC_WITHOUT_RET            = 0x20,\n\tTCP_PERF_SEL_TOTAL_WBINVL1                       = 0x21,\n\tTCP_PERF_SEL_IMG_READ_FMT_1                      = 0x22,\n\tTCP_PERF_SEL_IMG_READ_FMT_8                      = 0x23,\n\tTCP_PERF_SEL_IMG_READ_FMT_16                     = 0x24,\n\tTCP_PERF_SEL_IMG_READ_FMT_32                     = 0x25,\n\tTCP_PERF_SEL_IMG_READ_FMT_32_AS_8                = 0x26,\n\tTCP_PERF_SEL_IMG_READ_FMT_32_AS_16               = 0x27,\n\tTCP_PERF_SEL_IMG_READ_FMT_32_AS_128              = 0x28,\n\tTCP_PERF_SEL_IMG_READ_FMT_64_2_CYCLE             = 0x29,\n\tTCP_PERF_SEL_IMG_READ_FMT_64_1_CYCLE             = 0x2a,\n\tTCP_PERF_SEL_IMG_READ_FMT_96                     = 0x2b,\n\tTCP_PERF_SEL_IMG_READ_FMT_128_4_CYCLE            = 0x2c,\n\tTCP_PERF_SEL_IMG_READ_FMT_128_1_CYCLE            = 0x2d,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC1                    = 0x2e,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC2                    = 0x2f,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC3                    = 0x30,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC4                    = 0x31,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC5                    = 0x32,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC6                    = 0x33,\n\tTCP_PERF_SEL_IMG_READ_FMT_BC7                    = 0x34,\n\tTCP_PERF_SEL_IMG_READ_FMT_I8                     = 0x35,\n\tTCP_PERF_SEL_IMG_READ_FMT_I16                    = 0x36,\n\tTCP_PERF_SEL_IMG_READ_FMT_I32                    = 0x37,\n\tTCP_PERF_SEL_IMG_READ_FMT_I32_AS_8               = 0x38,\n\tTCP_PERF_SEL_IMG_READ_FMT_I32_AS_16              = 0x39,\n\tTCP_PERF_SEL_IMG_READ_FMT_D8                     = 0x3a,\n\tTCP_PERF_SEL_IMG_READ_FMT_D16                    = 0x3b,\n\tTCP_PERF_SEL_IMG_READ_FMT_D32                    = 0x3c,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_8                     = 0x3d,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_16                    = 0x3e,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_32                    = 0x3f,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_64                    = 0x40,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_128                   = 0x41,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_D8                    = 0x42,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_D16                   = 0x43,\n\tTCP_PERF_SEL_IMG_WRITE_FMT_D32                   = 0x44,\n\tTCP_PERF_SEL_IMG_ATOMIC_WITH_RET_FMT_32          = 0x45,\n\tTCP_PERF_SEL_IMG_ATOMIC_WITHOUT_RET_FMT_32       = 0x46,\n\tTCP_PERF_SEL_IMG_ATOMIC_WITH_RET_FMT_64          = 0x47,\n\tTCP_PERF_SEL_IMG_ATOMIC_WITHOUT_RET_FMT_64       = 0x48,\n\tTCP_PERF_SEL_BUF_READ_FMT_8                      = 0x49,\n\tTCP_PERF_SEL_BUF_READ_FMT_16                     = 0x4a,\n\tTCP_PERF_SEL_BUF_READ_FMT_32                     = 0x4b,\n\tTCP_PERF_SEL_BUF_WRITE_FMT_8                     = 0x4c,\n\tTCP_PERF_SEL_BUF_WRITE_FMT_16                    = 0x4d,\n\tTCP_PERF_SEL_BUF_WRITE_FMT_32                    = 0x4e,\n\tTCP_PERF_SEL_BUF_ATOMIC_WITH_RET_FMT_32          = 0x4f,\n\tTCP_PERF_SEL_BUF_ATOMIC_WITHOUT_RET_FMT_32       = 0x50,\n\tTCP_PERF_SEL_BUF_ATOMIC_WITH_RET_FMT_64          = 0x51,\n\tTCP_PERF_SEL_BUF_ATOMIC_WITHOUT_RET_FMT_64       = 0x52,\n\tTCP_PERF_SEL_ARR_LINEAR_GENERAL                  = 0x53,\n\tTCP_PERF_SEL_ARR_LINEAR_ALIGNED                  = 0x54,\n\tTCP_PERF_SEL_ARR_1D_THIN1                        = 0x55,\n\tTCP_PERF_SEL_ARR_1D_THICK                        = 0x56,\n\tTCP_PERF_SEL_ARR_2D_THIN1                        = 0x57,\n\tTCP_PERF_SEL_ARR_2D_THICK                        = 0x58,\n\tTCP_PERF_SEL_ARR_2D_XTHICK                       = 0x59,\n\tTCP_PERF_SEL_ARR_3D_THIN1                        = 0x5a,\n\tTCP_PERF_SEL_ARR_3D_THICK                        = 0x5b,\n\tTCP_PERF_SEL_ARR_3D_XTHICK                       = 0x5c,\n\tTCP_PERF_SEL_DIM_1D                              = 0x5d,\n\tTCP_PERF_SEL_DIM_2D                              = 0x5e,\n\tTCP_PERF_SEL_DIM_3D                              = 0x5f,\n\tTCP_PERF_SEL_DIM_1D_ARRAY                        = 0x60,\n\tTCP_PERF_SEL_DIM_2D_ARRAY                        = 0x61,\n\tTCP_PERF_SEL_DIM_2D_MSAA                         = 0x62,\n\tTCP_PERF_SEL_DIM_2D_ARRAY_MSAA                   = 0x63,\n\tTCP_PERF_SEL_DIM_CUBE_ARRAY                      = 0x64,\n\tTCP_PERF_SEL_CP_TCP_INVALIDATE                   = 0x65,\n\tTCP_PERF_SEL_TA_TCP_STATE_READ                   = 0x66,\n\tTCP_PERF_SEL_TAGRAM0_REQ                         = 0x67,\n\tTCP_PERF_SEL_TAGRAM1_REQ                         = 0x68,\n\tTCP_PERF_SEL_TAGRAM2_REQ                         = 0x69,\n\tTCP_PERF_SEL_TAGRAM3_REQ                         = 0x6a,\n\tTCP_PERF_SEL_GATE_EN1                            = 0x6b,\n\tTCP_PERF_SEL_GATE_EN2                            = 0x6c,\n\tTCP_PERF_SEL_CORE_REG_SCLK_VLD                   = 0x6d,\n\tTCP_PERF_SEL_TCC_REQ                             = 0x6e,\n\tTCP_PERF_SEL_TCC_NON_READ_REQ                    = 0x6f,\n\tTCP_PERF_SEL_TCC_BYPASS_READ_REQ                 = 0x70,\n\tTCP_PERF_SEL_TCC_MISS_EVICT_READ_REQ             = 0x71,\n\tTCP_PERF_SEL_TCC_VOLATILE_READ_REQ               = 0x72,\n\tTCP_PERF_SEL_TCC_VOLATILE_BYPASS_READ_REQ        = 0x73,\n\tTCP_PERF_SEL_TCC_VOLATILE_MISS_EVICT_READ_REQ    = 0x74,\n\tTCP_PERF_SEL_TCC_BYPASS_WRITE_REQ                = 0x75,\n\tTCP_PERF_SEL_TCC_MISS_EVICT_WRITE_REQ            = 0x76,\n\tTCP_PERF_SEL_TCC_VOLATILE_BYPASS_WRITE_REQ       = 0x77,\n\tTCP_PERF_SEL_TCC_VOLATILE_WRITE_REQ              = 0x78,\n\tTCP_PERF_SEL_TCC_VOLATILE_MISS_EVICT_WRITE_REQ   = 0x79,\n\tTCP_PERF_SEL_TCC_BYPASS_ATOMIC_REQ               = 0x7a,\n\tTCP_PERF_SEL_TCC_ATOMIC_REQ                      = 0x7b,\n\tTCP_PERF_SEL_TCC_VOLATILE_ATOMIC_REQ             = 0x7c,\n\tTCP_PERF_SEL_TCC_DATA_BUS_BUSY                   = 0x7d,\n\tTCP_PERF_SEL_TOTAL_ACCESSES                      = 0x7e,\n\tTCP_PERF_SEL_TOTAL_READ                          = 0x7f,\n\tTCP_PERF_SEL_TOTAL_HIT_LRU_READ                  = 0x80,\n\tTCP_PERF_SEL_TOTAL_HIT_EVICT_READ                = 0x81,\n\tTCP_PERF_SEL_TOTAL_MISS_LRU_READ                 = 0x82,\n\tTCP_PERF_SEL_TOTAL_MISS_EVICT_READ               = 0x83,\n\tTCP_PERF_SEL_TOTAL_NON_READ                      = 0x84,\n\tTCP_PERF_SEL_TOTAL_WRITE                         = 0x85,\n\tTCP_PERF_SEL_TOTAL_MISS_LRU_WRITE                = 0x86,\n\tTCP_PERF_SEL_TOTAL_MISS_EVICT_WRITE              = 0x87,\n\tTCP_PERF_SEL_TOTAL_WBINVL1_VOL                   = 0x88,\n\tTCP_PERF_SEL_TOTAL_WRITEBACK_INVALIDATES         = 0x89,\n\tTCP_PERF_SEL_DISPLAY_MICROTILING                 = 0x8a,\n\tTCP_PERF_SEL_THIN_MICROTILING                    = 0x8b,\n\tTCP_PERF_SEL_DEPTH_MICROTILING                   = 0x8c,\n\tTCP_PERF_SEL_ARR_PRT_THIN1                       = 0x8d,\n\tTCP_PERF_SEL_ARR_PRT_2D_THIN1                    = 0x8e,\n\tTCP_PERF_SEL_ARR_PRT_3D_THIN1                    = 0x8f,\n\tTCP_PERF_SEL_ARR_PRT_THICK                       = 0x90,\n\tTCP_PERF_SEL_ARR_PRT_2D_THICK                    = 0x91,\n\tTCP_PERF_SEL_ARR_PRT_3D_THICK                    = 0x92,\n\tTCP_PERF_SEL_CP_TCP_INVALIDATE_VOL               = 0x93,\n\tTCP_PERF_SEL_SQ_TCP_INVALIDATE_VOL               = 0x94,\n\tTCP_PERF_SEL_UNALIGNED                           = 0x95,\n\tTCP_PERF_SEL_ROTATED_MICROTILING                 = 0x96,\n\tTCP_PERF_SEL_THICK_MICROTILING                   = 0x97,\n\tTCP_PERF_SEL_ATC                                 = 0x98,\n\tTCP_PERF_SEL_POWER_STALL                         = 0x99,\n} TCP_PERFCOUNT_SELECT;\ntypedef enum TCP_CACHE_POLICIES {\n\tTCP_CACHE_POLICY_MISS_LRU                        = 0x0,\n\tTCP_CACHE_POLICY_MISS_EVICT                      = 0x1,\n\tTCP_CACHE_POLICY_HIT_LRU                         = 0x2,\n\tTCP_CACHE_POLICY_HIT_EVICT                       = 0x3,\n} TCP_CACHE_POLICIES;\ntypedef enum TCP_CACHE_STORE_POLICIES {\n\tTCP_CACHE_STORE_POLICY_MISS_LRU                  = 0x0,\n\tTCP_CACHE_STORE_POLICY_MISS_EVICT                = 0x1,\n} TCP_CACHE_STORE_POLICIES;\ntypedef enum TCP_WATCH_MODES {\n\tTCP_WATCH_MODE_READ                              = 0x0,\n\tTCP_WATCH_MODE_NONREAD                           = 0x1,\n\tTCP_WATCH_MODE_ATOMIC                            = 0x2,\n\tTCP_WATCH_MODE_ALL                               = 0x3,\n} TCP_WATCH_MODES;\ntypedef enum VGT_OUT_PRIM_TYPE {\n\tVGT_OUT_POINT                                    = 0x0,\n\tVGT_OUT_LINE                                     = 0x1,\n\tVGT_OUT_TRI                                      = 0x2,\n\tVGT_OUT_RECT_V0                                  = 0x3,\n\tVGT_OUT_RECT_V1                                  = 0x4,\n\tVGT_OUT_RECT_V2                                  = 0x5,\n\tVGT_OUT_RECT_V3                                  = 0x6,\n\tVGT_OUT_RESERVED                                 = 0x7,\n\tVGT_TE_QUAD                                      = 0x8,\n\tVGT_TE_PRIM_INDEX_LINE                           = 0x9,\n\tVGT_TE_PRIM_INDEX_TRI                            = 0xa,\n\tVGT_TE_PRIM_INDEX_QUAD                           = 0xb,\n\tVGT_OUT_LINE_ADJ                                 = 0xc,\n\tVGT_OUT_TRI_ADJ                                  = 0xd,\n\tVGT_OUT_PATCH                                    = 0xe,\n} VGT_OUT_PRIM_TYPE;\ntypedef enum VGT_DI_PRIM_TYPE {\n\tDI_PT_NONE                                       = 0x0,\n\tDI_PT_POINTLIST                                  = 0x1,\n\tDI_PT_LINELIST                                   = 0x2,\n\tDI_PT_LINESTRIP                                  = 0x3,\n\tDI_PT_TRILIST                                    = 0x4,\n\tDI_PT_TRIFAN                                     = 0x5,\n\tDI_PT_TRISTRIP                                   = 0x6,\n\tDI_PT_UNUSED_0                                   = 0x7,\n\tDI_PT_UNUSED_1                                   = 0x8,\n\tDI_PT_PATCH                                      = 0x9,\n\tDI_PT_LINELIST_ADJ                               = 0xa,\n\tDI_PT_LINESTRIP_ADJ                              = 0xb,\n\tDI_PT_TRILIST_ADJ                                = 0xc,\n\tDI_PT_TRISTRIP_ADJ                               = 0xd,\n\tDI_PT_UNUSED_3                                   = 0xe,\n\tDI_PT_UNUSED_4                                   = 0xf,\n\tDI_PT_TRI_WITH_WFLAGS                            = 0x10,\n\tDI_PT_RECTLIST                                   = 0x11,\n\tDI_PT_LINELOOP                                   = 0x12,\n\tDI_PT_QUADLIST                                   = 0x13,\n\tDI_PT_QUADSTRIP                                  = 0x14,\n\tDI_PT_POLYGON                                    = 0x15,\n\tDI_PT_2D_COPY_RECT_LIST_V0                       = 0x16,\n\tDI_PT_2D_COPY_RECT_LIST_V1                       = 0x17,\n\tDI_PT_2D_COPY_RECT_LIST_V2                       = 0x18,\n\tDI_PT_2D_COPY_RECT_LIST_V3                       = 0x19,\n\tDI_PT_2D_FILL_RECT_LIST                          = 0x1a,\n\tDI_PT_2D_LINE_STRIP                              = 0x1b,\n\tDI_PT_2D_TRI_STRIP                               = 0x1c,\n} VGT_DI_PRIM_TYPE;\ntypedef enum VGT_DI_SOURCE_SELECT {\n\tDI_SRC_SEL_DMA                                   = 0x0,\n\tDI_SRC_SEL_IMMEDIATE                             = 0x1,\n\tDI_SRC_SEL_AUTO_INDEX                            = 0x2,\n\tDI_SRC_SEL_RESERVED                              = 0x3,\n} VGT_DI_SOURCE_SELECT;\ntypedef enum VGT_DI_MAJOR_MODE_SELECT {\n\tDI_MAJOR_MODE_0                                  = 0x0,\n\tDI_MAJOR_MODE_1                                  = 0x1,\n} VGT_DI_MAJOR_MODE_SELECT;\ntypedef enum VGT_DI_INDEX_SIZE {\n\tDI_INDEX_SIZE_16_BIT                             = 0x0,\n\tDI_INDEX_SIZE_32_BIT                             = 0x1,\n} VGT_DI_INDEX_SIZE;\ntypedef enum VGT_EVENT_TYPE {\n\tReserved_0x00                                    = 0x0,\n\tSAMPLE_STREAMOUTSTATS1                           = 0x1,\n\tSAMPLE_STREAMOUTSTATS2                           = 0x2,\n\tSAMPLE_STREAMOUTSTATS3                           = 0x3,\n\tCACHE_FLUSH_TS                                   = 0x4,\n\tCONTEXT_DONE                                     = 0x5,\n\tCACHE_FLUSH                                      = 0x6,\n\tCS_PARTIAL_FLUSH                                 = 0x7,\n\tVGT_STREAMOUT_SYNC                               = 0x8,\n\tReserved_0x09                                    = 0x9,\n\tVGT_STREAMOUT_RESET                              = 0xa,\n\tEND_OF_PIPE_INCR_DE                              = 0xb,\n\tEND_OF_PIPE_IB_END                               = 0xc,\n\tRST_PIX_CNT                                      = 0xd,\n\tReserved_0x0E                                    = 0xe,\n\tVS_PARTIAL_FLUSH                                 = 0xf,\n\tPS_PARTIAL_FLUSH                                 = 0x10,\n\tFLUSH_HS_OUTPUT                                  = 0x11,\n\tFLUSH_LS_OUTPUT                                  = 0x12,\n\tReserved_0x13                                    = 0x13,\n\tCACHE_FLUSH_AND_INV_TS_EVENT                     = 0x14,\n\tZPASS_DONE                                       = 0x15,\n\tCACHE_FLUSH_AND_INV_EVENT                        = 0x16,\n\tPERFCOUNTER_START                                = 0x17,\n\tPERFCOUNTER_STOP                                 = 0x18,\n\tPIPELINESTAT_START                               = 0x19,\n\tPIPELINESTAT_STOP                                = 0x1a,\n\tPERFCOUNTER_SAMPLE                               = 0x1b,\n\tFLUSH_ES_OUTPUT                                  = 0x1c,\n\tFLUSH_GS_OUTPUT                                  = 0x1d,\n\tSAMPLE_PIPELINESTAT                              = 0x1e,\n\tSO_VGTSTREAMOUT_FLUSH                            = 0x1f,\n\tSAMPLE_STREAMOUTSTATS                            = 0x20,\n\tRESET_VTX_CNT                                    = 0x21,\n\tBLOCK_CONTEXT_DONE                               = 0x22,\n\tCS_CONTEXT_DONE                                  = 0x23,\n\tVGT_FLUSH                                        = 0x24,\n\tReserved_0x25                                    = 0x25,\n\tSQ_NON_EVENT                                     = 0x26,\n\tSC_SEND_DB_VPZ                                   = 0x27,\n\tBOTTOM_OF_PIPE_TS                                = 0x28,\n\tFLUSH_SX_TS                                      = 0x29,\n\tDB_CACHE_FLUSH_AND_INV                           = 0x2a,\n\tFLUSH_AND_INV_DB_DATA_TS                         = 0x2b,\n\tFLUSH_AND_INV_DB_META                            = 0x2c,\n\tFLUSH_AND_INV_CB_DATA_TS                         = 0x2d,\n\tFLUSH_AND_INV_CB_META                            = 0x2e,\n\tCS_DONE                                          = 0x2f,\n\tPS_DONE                                          = 0x30,\n\tFLUSH_AND_INV_CB_PIXEL_DATA                      = 0x31,\n\tSX_CB_RAT_ACK_REQUEST                            = 0x32,\n\tTHREAD_TRACE_START                               = 0x33,\n\tTHREAD_TRACE_STOP                                = 0x34,\n\tTHREAD_TRACE_MARKER                              = 0x35,\n\tTHREAD_TRACE_FLUSH                               = 0x36,\n\tTHREAD_TRACE_FINISH                              = 0x37,\n\tPIXEL_PIPE_STAT_CONTROL                          = 0x38,\n\tPIXEL_PIPE_STAT_DUMP                             = 0x39,\n\tPIXEL_PIPE_STAT_RESET                            = 0x3a,\n\tCONTEXT_SUSPEND                                  = 0x3b,\n} VGT_EVENT_TYPE;\ntypedef enum VGT_DMA_SWAP_MODE {\n\tVGT_DMA_SWAP_NONE                                = 0x0,\n\tVGT_DMA_SWAP_16_BIT                              = 0x1,\n\tVGT_DMA_SWAP_32_BIT                              = 0x2,\n\tVGT_DMA_SWAP_WORD                                = 0x3,\n} VGT_DMA_SWAP_MODE;\ntypedef enum VGT_INDEX_TYPE_MODE {\n\tVGT_INDEX_16                                     = 0x0,\n\tVGT_INDEX_32                                     = 0x1,\n} VGT_INDEX_TYPE_MODE;\ntypedef enum VGT_DMA_BUF_TYPE {\n\tVGT_DMA_BUF_MEM                                  = 0x0,\n\tVGT_DMA_BUF_RING                                 = 0x1,\n\tVGT_DMA_BUF_SETUP                                = 0x2,\n} VGT_DMA_BUF_TYPE;\ntypedef enum VGT_OUTPATH_SELECT {\n\tVGT_OUTPATH_VTX_REUSE                            = 0x0,\n\tVGT_OUTPATH_TESS_EN                              = 0x1,\n\tVGT_OUTPATH_PASSTHRU                             = 0x2,\n\tVGT_OUTPATH_GS_BLOCK                             = 0x3,\n\tVGT_OUTPATH_HS_BLOCK                             = 0x4,\n} VGT_OUTPATH_SELECT;\ntypedef enum VGT_GRP_PRIM_TYPE {\n\tVGT_GRP_3D_POINT                                 = 0x0,\n\tVGT_GRP_3D_LINE                                  = 0x1,\n\tVGT_GRP_3D_TRI                                   = 0x2,\n\tVGT_GRP_3D_RECT                                  = 0x3,\n\tVGT_GRP_3D_QUAD                                  = 0x4,\n\tVGT_GRP_2D_COPY_RECT_V0                          = 0x5,\n\tVGT_GRP_2D_COPY_RECT_V1                          = 0x6,\n\tVGT_GRP_2D_COPY_RECT_V2                          = 0x7,\n\tVGT_GRP_2D_COPY_RECT_V3                          = 0x8,\n\tVGT_GRP_2D_FILL_RECT                             = 0x9,\n\tVGT_GRP_2D_LINE                                  = 0xa,\n\tVGT_GRP_2D_TRI                                   = 0xb,\n\tVGT_GRP_PRIM_INDEX_LINE                          = 0xc,\n\tVGT_GRP_PRIM_INDEX_TRI                           = 0xd,\n\tVGT_GRP_PRIM_INDEX_QUAD                          = 0xe,\n\tVGT_GRP_3D_LINE_ADJ                              = 0xf,\n\tVGT_GRP_3D_TRI_ADJ                               = 0x10,\n\tVGT_GRP_3D_PATCH                                 = 0x11,\n} VGT_GRP_PRIM_TYPE;\ntypedef enum VGT_GRP_PRIM_ORDER {\n\tVGT_GRP_LIST                                     = 0x0,\n\tVGT_GRP_STRIP                                    = 0x1,\n\tVGT_GRP_FAN                                      = 0x2,\n\tVGT_GRP_LOOP                                     = 0x3,\n\tVGT_GRP_POLYGON                                  = 0x4,\n} VGT_GRP_PRIM_ORDER;\ntypedef enum VGT_GROUP_CONV_SEL {\n\tVGT_GRP_INDEX_16                                 = 0x0,\n\tVGT_GRP_INDEX_32                                 = 0x1,\n\tVGT_GRP_UINT_16                                  = 0x2,\n\tVGT_GRP_UINT_32                                  = 0x3,\n\tVGT_GRP_SINT_16                                  = 0x4,\n\tVGT_GRP_SINT_32                                  = 0x5,\n\tVGT_GRP_FLOAT_32                                 = 0x6,\n\tVGT_GRP_AUTO_PRIM                                = 0x7,\n\tVGT_GRP_FIX_1_23_TO_FLOAT                        = 0x8,\n} VGT_GROUP_CONV_SEL;\ntypedef enum VGT_GS_MODE_TYPE {\n\tGS_OFF                                           = 0x0,\n\tGS_SCENARIO_A                                    = 0x1,\n\tGS_SCENARIO_B                                    = 0x2,\n\tGS_SCENARIO_G                                    = 0x3,\n\tGS_SCENARIO_C                                    = 0x4,\n\tSPRITE_EN                                        = 0x5,\n} VGT_GS_MODE_TYPE;\ntypedef enum VGT_GS_CUT_MODE {\n\tGS_CUT_1024                                      = 0x0,\n\tGS_CUT_512                                       = 0x1,\n\tGS_CUT_256                                       = 0x2,\n\tGS_CUT_128                                       = 0x3,\n} VGT_GS_CUT_MODE;\ntypedef enum VGT_GS_OUTPRIM_TYPE {\n\tPOINTLIST                                        = 0x0,\n\tLINESTRIP                                        = 0x1,\n\tTRISTRIP                                         = 0x2,\n} VGT_GS_OUTPRIM_TYPE;\ntypedef enum VGT_CACHE_INVALID_MODE {\n\tVC_ONLY                                          = 0x0,\n\tTC_ONLY                                          = 0x1,\n\tVC_AND_TC                                        = 0x2,\n} VGT_CACHE_INVALID_MODE;\ntypedef enum VGT_TESS_TYPE {\n\tTESS_ISOLINE                                     = 0x0,\n\tTESS_TRIANGLE                                    = 0x1,\n\tTESS_QUAD                                        = 0x2,\n} VGT_TESS_TYPE;\ntypedef enum VGT_TESS_PARTITION {\n\tPART_INTEGER                                     = 0x0,\n\tPART_POW2                                        = 0x1,\n\tPART_FRAC_ODD                                    = 0x2,\n\tPART_FRAC_EVEN                                   = 0x3,\n} VGT_TESS_PARTITION;\ntypedef enum VGT_TESS_TOPOLOGY {\n\tOUTPUT_POINT                                     = 0x0,\n\tOUTPUT_LINE                                      = 0x1,\n\tOUTPUT_TRIANGLE_CW                               = 0x2,\n\tOUTPUT_TRIANGLE_CCW                              = 0x3,\n} VGT_TESS_TOPOLOGY;\ntypedef enum VGT_RDREQ_POLICY {\n\tVGT_POLICY_LRU                                   = 0x0,\n\tVGT_POLICY_STREAM                                = 0x1,\n\tVGT_POLICY_BYPASS                                = 0x2,\n\tVGT_POLICY_RESERVED                              = 0x3,\n} VGT_RDREQ_POLICY;\ntypedef enum VGT_STAGES_LS_EN {\n\tLS_STAGE_OFF                                     = 0x0,\n\tLS_STAGE_ON                                      = 0x1,\n\tCS_STAGE_ON                                      = 0x2,\n\tRESERVED_LS                                      = 0x3,\n} VGT_STAGES_LS_EN;\ntypedef enum VGT_STAGES_HS_EN {\n\tHS_STAGE_OFF                                     = 0x0,\n\tHS_STAGE_ON                                      = 0x1,\n} VGT_STAGES_HS_EN;\ntypedef enum VGT_STAGES_ES_EN {\n\tES_STAGE_OFF                                     = 0x0,\n\tES_STAGE_DS                                      = 0x1,\n\tES_STAGE_REAL                                    = 0x2,\n\tRESERVED_ES                                      = 0x3,\n} VGT_STAGES_ES_EN;\ntypedef enum VGT_STAGES_GS_EN {\n\tGS_STAGE_OFF                                     = 0x0,\n\tGS_STAGE_ON                                      = 0x1,\n} VGT_STAGES_GS_EN;\ntypedef enum VGT_STAGES_VS_EN {\n\tVS_STAGE_REAL                                    = 0x0,\n\tVS_STAGE_DS                                      = 0x1,\n\tVS_STAGE_COPY_SHADER                             = 0x2,\n\tRESERVED_VS                                      = 0x3,\n} VGT_STAGES_VS_EN;\ntypedef enum VGT_PERFCOUNT_SELECT {\n\tvgt_perf_VGT_SPI_ESTHREAD_EVENT_WINDOW_ACTIVE    = 0x0,\n\tvgt_perf_VGT_SPI_ESVERT_VALID                    = 0x1,\n\tvgt_perf_VGT_SPI_ESVERT_EOV                      = 0x2,\n\tvgt_perf_VGT_SPI_ESVERT_STALLED                  = 0x3,\n\tvgt_perf_VGT_SPI_ESVERT_STARVED_BUSY             = 0x4,\n\tvgt_perf_VGT_SPI_ESVERT_STARVED_IDLE             = 0x5,\n\tvgt_perf_VGT_SPI_ESVERT_STATIC                   = 0x6,\n\tvgt_perf_VGT_SPI_ESTHREAD_IS_EVENT               = 0x7,\n\tvgt_perf_VGT_SPI_ESTHREAD_SEND                   = 0x8,\n\tvgt_perf_VGT_SPI_GSPRIM_VALID                    = 0x9,\n\tvgt_perf_VGT_SPI_GSPRIM_EOV                      = 0xa,\n\tvgt_perf_VGT_SPI_GSPRIM_CONT                     = 0xb,\n\tvgt_perf_VGT_SPI_GSPRIM_STALLED                  = 0xc,\n\tvgt_perf_VGT_SPI_GSPRIM_STARVED_BUSY             = 0xd,\n\tvgt_perf_VGT_SPI_GSPRIM_STARVED_IDLE             = 0xe,\n\tvgt_perf_VGT_SPI_GSPRIM_STATIC                   = 0xf,\n\tvgt_perf_VGT_SPI_GSTHREAD_EVENT_WINDOW_ACTIVE    = 0x10,\n\tvgt_perf_VGT_SPI_GSTHREAD_IS_EVENT               = 0x11,\n\tvgt_perf_VGT_SPI_GSTHREAD_SEND                   = 0x12,\n\tvgt_perf_VGT_SPI_VSTHREAD_EVENT_WINDOW_ACTIVE    = 0x13,\n\tvgt_perf_VGT_SPI_VSVERT_SEND                     = 0x14,\n\tvgt_perf_VGT_SPI_VSVERT_EOV                      = 0x15,\n\tvgt_perf_VGT_SPI_VSVERT_STALLED                  = 0x16,\n\tvgt_perf_VGT_SPI_VSVERT_STARVED_BUSY             = 0x17,\n\tvgt_perf_VGT_SPI_VSVERT_STARVED_IDLE             = 0x18,\n\tvgt_perf_VGT_SPI_VSVERT_STATIC                   = 0x19,\n\tvgt_perf_VGT_SPI_VSTHREAD_IS_EVENT               = 0x1a,\n\tvgt_perf_VGT_SPI_VSTHREAD_SEND                   = 0x1b,\n\tvgt_perf_VGT_PA_EVENT_WINDOW_ACTIVE              = 0x1c,\n\tvgt_perf_VGT_PA_CLIPV_SEND                       = 0x1d,\n\tvgt_perf_VGT_PA_CLIPV_FIRSTVERT                  = 0x1e,\n\tvgt_perf_VGT_PA_CLIPV_STALLED                    = 0x1f,\n\tvgt_perf_VGT_PA_CLIPV_STARVED_BUSY               = 0x20,\n\tvgt_perf_VGT_PA_CLIPV_STARVED_IDLE               = 0x21,\n\tvgt_perf_VGT_PA_CLIPV_STATIC                     = 0x22,\n\tvgt_perf_VGT_PA_CLIPP_SEND                       = 0x23,\n\tvgt_perf_VGT_PA_CLIPP_EOP                        = 0x24,\n\tvgt_perf_VGT_PA_CLIPP_IS_EVENT                   = 0x25,\n\tvgt_perf_VGT_PA_CLIPP_NULL_PRIM                  = 0x26,\n\tvgt_perf_VGT_PA_CLIPP_NEW_VTX_VECT               = 0x27,\n\tvgt_perf_VGT_PA_CLIPP_STALLED                    = 0x28,\n\tvgt_perf_VGT_PA_CLIPP_STARVED_BUSY               = 0x29,\n\tvgt_perf_VGT_PA_CLIPP_STARVED_IDLE               = 0x2a,\n\tvgt_perf_VGT_PA_CLIPP_STATIC                     = 0x2b,\n\tvgt_perf_VGT_PA_CLIPS_SEND                       = 0x2c,\n\tvgt_perf_VGT_PA_CLIPS_STALLED                    = 0x2d,\n\tvgt_perf_VGT_PA_CLIPS_STARVED_BUSY               = 0x2e,\n\tvgt_perf_VGT_PA_CLIPS_STARVED_IDLE               = 0x2f,\n\tvgt_perf_VGT_PA_CLIPS_STATIC                     = 0x30,\n\tvgt_perf_vsvert_ds_send                          = 0x31,\n\tvgt_perf_vsvert_api_send                         = 0x32,\n\tvgt_perf_hs_tif_stall                            = 0x33,\n\tvgt_perf_hs_input_stall                          = 0x34,\n\tvgt_perf_hs_interface_stall                      = 0x35,\n\tvgt_perf_hs_tfm_stall                            = 0x36,\n\tvgt_perf_te11_starved                            = 0x37,\n\tvgt_perf_gs_event_stall                          = 0x38,\n\tvgt_perf_vgt_pa_clipp_send_not_event             = 0x39,\n\tvgt_perf_vgt_pa_clipp_valid_prim                 = 0x3a,\n\tvgt_perf_reused_es_indices                       = 0x3b,\n\tvgt_perf_vs_cache_hits                           = 0x3c,\n\tvgt_perf_gs_cache_hits                           = 0x3d,\n\tvgt_perf_ds_cache_hits                           = 0x3e,\n\tvgt_perf_total_cache_hits                        = 0x3f,\n\tvgt_perf_vgt_busy                                = 0x40,\n\tvgt_perf_vgt_gs_busy                             = 0x41,\n\tvgt_perf_esvert_stalled_es_tbl                   = 0x42,\n\tvgt_perf_esvert_stalled_gs_tbl                   = 0x43,\n\tvgt_perf_esvert_stalled_gs_event                 = 0x44,\n\tvgt_perf_esvert_stalled_gsprim                   = 0x45,\n\tvgt_perf_gsprim_stalled_es_tbl                   = 0x46,\n\tvgt_perf_gsprim_stalled_gs_tbl                   = 0x47,\n\tvgt_perf_gsprim_stalled_gs_event                 = 0x48,\n\tvgt_perf_gsprim_stalled_esvert                   = 0x49,\n\tvgt_perf_esthread_stalled_es_rb_full             = 0x4a,\n\tvgt_perf_esthread_stalled_spi_bp                 = 0x4b,\n\tvgt_perf_counters_avail_stalled                  = 0x4c,\n\tvgt_perf_gs_rb_space_avail_stalled               = 0x4d,\n\tvgt_perf_gs_issue_rtr_stalled                    = 0x4e,\n\tvgt_perf_gsthread_stalled                        = 0x4f,\n\tvgt_perf_strmout_stalled                         = 0x50,\n\tvgt_perf_wait_for_es_done_stalled                = 0x51,\n\tvgt_perf_cm_stalled_by_gog                       = 0x52,\n\tvgt_perf_cm_reading_stalled                      = 0x53,\n\tvgt_perf_cm_stalled_by_gsfetch_done              = 0x54,\n\tvgt_perf_gog_vs_tbl_stalled                      = 0x55,\n\tvgt_perf_gog_out_indx_stalled                    = 0x56,\n\tvgt_perf_gog_out_prim_stalled                    = 0x57,\n\tvgt_perf_waveid_stalled                          = 0x58,\n\tvgt_perf_gog_busy                                = 0x59,\n\tvgt_perf_reused_vs_indices                       = 0x5a,\n\tvgt_perf_sclk_reg_vld_event                      = 0x5b,\n\tvgt_perf_RESERVED0                               = 0x5c,\n\tvgt_perf_sclk_core_vld_event                     = 0x5d,\n\tvgt_perf_RESERVED1                               = 0x5e,\n\tvgt_perf_sclk_gs_vld_event                       = 0x5f,\n\tvgt_perf_VGT_SPI_LSVERT_VALID                    = 0x60,\n\tvgt_perf_VGT_SPI_LSVERT_EOV                      = 0x61,\n\tvgt_perf_VGT_SPI_LSVERT_STALLED                  = 0x62,\n\tvgt_perf_VGT_SPI_LSVERT_STARVED_BUSY             = 0x63,\n\tvgt_perf_VGT_SPI_LSVERT_STARVED_IDLE             = 0x64,\n\tvgt_perf_VGT_SPI_LSVERT_STATIC                   = 0x65,\n\tvgt_perf_VGT_SPI_LSWAVE_EVENT_WINDOW_ACTIVE      = 0x66,\n\tvgt_perf_VGT_SPI_LSWAVE_IS_EVENT                 = 0x67,\n\tvgt_perf_VGT_SPI_LSWAVE_SEND                     = 0x68,\n\tvgt_perf_VGT_SPI_HSVERT_VALID                    = 0x69,\n\tvgt_perf_VGT_SPI_HSVERT_EOV                      = 0x6a,\n\tvgt_perf_VGT_SPI_HSVERT_STALLED                  = 0x6b,\n\tvgt_perf_VGT_SPI_HSVERT_STARVED_BUSY             = 0x6c,\n\tvgt_perf_VGT_SPI_HSVERT_STARVED_IDLE             = 0x6d,\n\tvgt_perf_VGT_SPI_HSVERT_STATIC                   = 0x6e,\n\tvgt_perf_VGT_SPI_HSWAVE_EVENT_WINDOW_ACTIVE      = 0x6f,\n\tvgt_perf_VGT_SPI_HSWAVE_IS_EVENT                 = 0x70,\n\tvgt_perf_VGT_SPI_HSWAVE_SEND                     = 0x71,\n\tvgt_perf_ds_prims                                = 0x72,\n\tvgt_perf_null_tess_patches                       = 0x73,\n\tvgt_perf_ls_thread_groups                        = 0x74,\n\tvgt_perf_hs_thread_groups                        = 0x75,\n\tvgt_perf_es_thread_groups                        = 0x76,\n\tvgt_perf_vs_thread_groups                        = 0x77,\n\tvgt_perf_ls_done_latency                         = 0x78,\n\tvgt_perf_hs_done_latency                         = 0x79,\n\tvgt_perf_es_done_latency                         = 0x7a,\n\tvgt_perf_gs_done_latency                         = 0x7b,\n\tvgt_perf_vgt_hs_busy                             = 0x7c,\n\tvgt_perf_vgt_te11_busy                           = 0x7d,\n\tvgt_perf_ls_flush                                = 0x7e,\n\tvgt_perf_hs_flush                                = 0x7f,\n\tvgt_perf_es_flush                                = 0x80,\n\tvgt_perf_gs_flush                                = 0x81,\n\tvgt_perf_ls_done                                 = 0x82,\n\tvgt_perf_hs_done                                 = 0x83,\n\tvgt_perf_es_done                                 = 0x84,\n\tvgt_perf_gs_done                                 = 0x85,\n\tvgt_perf_vsfetch_done                            = 0x86,\n\tvgt_perf_RESERVED2                               = 0x87,\n\tvgt_perf_es_ring_high_water_mark                 = 0x88,\n\tvgt_perf_gs_ring_high_water_mark                 = 0x89,\n\tvgt_perf_vs_table_high_water_mark                = 0x8a,\n\tvgt_perf_hs_tgs_active_high_water_mark           = 0x8b,\n} VGT_PERFCOUNT_SELECT;\ntypedef enum IA_PERFCOUNT_SELECT {\n\tia_perf_GRP_INPUT_EVENT_WINDOW_ACTIVE            = 0x0,\n\tia_perf_MC_LAT_BIN_0                             = 0x1,\n\tia_perf_MC_LAT_BIN_1                             = 0x2,\n\tia_perf_MC_LAT_BIN_2                             = 0x3,\n\tia_perf_MC_LAT_BIN_3                             = 0x4,\n\tia_perf_MC_LAT_BIN_4                             = 0x5,\n\tia_perf_MC_LAT_BIN_5                             = 0x6,\n\tia_perf_MC_LAT_BIN_6                             = 0x7,\n\tia_perf_MC_LAT_BIN_7                             = 0x8,\n\tia_perf_ia_busy                                  = 0x9,\n\tia_perf_ia_sclk_reg_vld_event                    = 0xa,\n\tia_perf_RESERVED0                                = 0xb,\n\tia_perf_ia_sclk_core_vld_event                   = 0xc,\n\tia_perf_RESERVED1                                = 0xd,\n\tia_perf_ia_dma_return                            = 0xe,\n\tia_perf_shift_starved_pipe1_event                = 0xf,\n\tia_perf_shift_starved_pipe0_event                = 0x10,\n\tia_perf_ia_stalled                               = 0x11,\n} IA_PERFCOUNT_SELECT;\ntypedef enum WD_PERFCOUNT_SELECT {\n\twd_perf_RBIU_FIFOS_EVENT_WINDOW_ACTIVE           = 0x0,\n\twd_perf_RBIU_DR_FIFO_STARVED                     = 0x1,\n\twd_perf_RBIU_DR_FIFO_STALLED                     = 0x2,\n\twd_perf_RBIU_DI_FIFO_STARVED                     = 0x3,\n\twd_perf_RBIU_DI_FIFO_STALLED                     = 0x4,\n\twd_perf_wd_busy                                  = 0x5,\n\twd_perf_wd_sclk_reg_vld_event                    = 0x6,\n\twd_perf_wd_sclk_input_vld_event                  = 0x7,\n\twd_perf_wd_sclk_core_vld_event                   = 0x8,\n\twd_perf_wd_stalled                               = 0x9,\n} WD_PERFCOUNT_SELECT;\ntypedef enum WD_IA_DRAW_TYPE {\n\tWD_IA_DRAW_TYPE_DI_MM0                           = 0x0,\n\tWD_IA_DRAW_TYPE_DI_MM1                           = 0x1,\n\tWD_IA_DRAW_TYPE_EVENT_INIT                       = 0x2,\n\tWD_IA_DRAW_TYPE_EVENT_ADDR                       = 0x3,\n\tWD_IA_DRAW_TYPE_MIN_INDX                         = 0x4,\n\tWD_IA_DRAW_TYPE_MAX_INDX                         = 0x5,\n\tWD_IA_DRAW_TYPE_INDX_OFF                         = 0x6,\n\tWD_IA_DRAW_TYPE_IMM_DATA                         = 0x7,\n} WD_IA_DRAW_TYPE;\n#define GSTHREADID_SIZE                           0x2\ntypedef enum SurfaceEndian {\n\tENDIAN_NONE                                      = 0x0,\n\tENDIAN_8IN16                                     = 0x1,\n\tENDIAN_8IN32                                     = 0x2,\n\tENDIAN_8IN64                                     = 0x3,\n} SurfaceEndian;\ntypedef enum ArrayMode {\n\tARRAY_LINEAR_GENERAL                             = 0x0,\n\tARRAY_LINEAR_ALIGNED                             = 0x1,\n\tARRAY_1D_TILED_THIN1                             = 0x2,\n\tARRAY_1D_TILED_THICK                             = 0x3,\n\tARRAY_2D_TILED_THIN1                             = 0x4,\n\tARRAY_PRT_TILED_THIN1                            = 0x5,\n\tARRAY_PRT_2D_TILED_THIN1                         = 0x6,\n\tARRAY_2D_TILED_THICK                             = 0x7,\n\tARRAY_2D_TILED_XTHICK                            = 0x8,\n\tARRAY_PRT_TILED_THICK                            = 0x9,\n\tARRAY_PRT_2D_TILED_THICK                         = 0xa,\n\tARRAY_PRT_3D_TILED_THIN1                         = 0xb,\n\tARRAY_3D_TILED_THIN1                             = 0xc,\n\tARRAY_3D_TILED_THICK                             = 0xd,\n\tARRAY_3D_TILED_XTHICK                            = 0xe,\n\tARRAY_PRT_3D_TILED_THICK                         = 0xf,\n} ArrayMode;\ntypedef enum PipeTiling {\n\tCONFIG_1_PIPE                                    = 0x0,\n\tCONFIG_2_PIPE                                    = 0x1,\n\tCONFIG_4_PIPE                                    = 0x2,\n\tCONFIG_8_PIPE                                    = 0x3,\n} PipeTiling;\ntypedef enum BankTiling {\n\tCONFIG_4_BANK                                    = 0x0,\n\tCONFIG_8_BANK                                    = 0x1,\n} BankTiling;\ntypedef enum GroupInterleave {\n\tCONFIG_256B_GROUP                                = 0x0,\n\tCONFIG_512B_GROUP                                = 0x1,\n} GroupInterleave;\ntypedef enum RowTiling {\n\tCONFIG_1KB_ROW                                   = 0x0,\n\tCONFIG_2KB_ROW                                   = 0x1,\n\tCONFIG_4KB_ROW                                   = 0x2,\n\tCONFIG_8KB_ROW                                   = 0x3,\n\tCONFIG_1KB_ROW_OPT                               = 0x4,\n\tCONFIG_2KB_ROW_OPT                               = 0x5,\n\tCONFIG_4KB_ROW_OPT                               = 0x6,\n\tCONFIG_8KB_ROW_OPT                               = 0x7,\n} RowTiling;\ntypedef enum BankSwapBytes {\n\tCONFIG_128B_SWAPS                                = 0x0,\n\tCONFIG_256B_SWAPS                                = 0x1,\n\tCONFIG_512B_SWAPS                                = 0x2,\n\tCONFIG_1KB_SWAPS                                 = 0x3,\n} BankSwapBytes;\ntypedef enum SampleSplitBytes {\n\tCONFIG_1KB_SPLIT                                 = 0x0,\n\tCONFIG_2KB_SPLIT                                 = 0x1,\n\tCONFIG_4KB_SPLIT                                 = 0x2,\n\tCONFIG_8KB_SPLIT                                 = 0x3,\n} SampleSplitBytes;\ntypedef enum NumPipes {\n\tADDR_CONFIG_1_PIPE                               = 0x0,\n\tADDR_CONFIG_2_PIPE                               = 0x1,\n\tADDR_CONFIG_4_PIPE                               = 0x2,\n\tADDR_CONFIG_8_PIPE                               = 0x3,\n\tADDR_CONFIG_16_PIPE                              = 0x4,\n} NumPipes;\ntypedef enum PipeInterleaveSize {\n\tADDR_CONFIG_PIPE_INTERLEAVE_256B                 = 0x0,\n\tADDR_CONFIG_PIPE_INTERLEAVE_512B                 = 0x1,\n} PipeInterleaveSize;\ntypedef enum BankInterleaveSize {\n\tADDR_CONFIG_BANK_INTERLEAVE_1                    = 0x0,\n\tADDR_CONFIG_BANK_INTERLEAVE_2                    = 0x1,\n\tADDR_CONFIG_BANK_INTERLEAVE_4                    = 0x2,\n\tADDR_CONFIG_BANK_INTERLEAVE_8                    = 0x3,\n} BankInterleaveSize;\ntypedef enum NumShaderEngines {\n\tADDR_CONFIG_1_SHADER_ENGINE                      = 0x0,\n\tADDR_CONFIG_2_SHADER_ENGINE                      = 0x1,\n} NumShaderEngines;\ntypedef enum ShaderEngineTileSize {\n\tADDR_CONFIG_SE_TILE_16                           = 0x0,\n\tADDR_CONFIG_SE_TILE_32                           = 0x1,\n} ShaderEngineTileSize;\ntypedef enum NumGPUs {\n\tADDR_CONFIG_1_GPU                                = 0x0,\n\tADDR_CONFIG_2_GPU                                = 0x1,\n\tADDR_CONFIG_4_GPU                                = 0x2,\n} NumGPUs;\ntypedef enum MultiGPUTileSize {\n\tADDR_CONFIG_GPU_TILE_16                          = 0x0,\n\tADDR_CONFIG_GPU_TILE_32                          = 0x1,\n\tADDR_CONFIG_GPU_TILE_64                          = 0x2,\n\tADDR_CONFIG_GPU_TILE_128                         = 0x3,\n} MultiGPUTileSize;\ntypedef enum RowSize {\n\tADDR_CONFIG_1KB_ROW                              = 0x0,\n\tADDR_CONFIG_2KB_ROW                              = 0x1,\n\tADDR_CONFIG_4KB_ROW                              = 0x2,\n} RowSize;\ntypedef enum NumLowerPipes {\n\tADDR_CONFIG_1_LOWER_PIPES                        = 0x0,\n\tADDR_CONFIG_2_LOWER_PIPES                        = 0x1,\n} NumLowerPipes;\ntypedef enum DebugBlockId {\n\tDBG_CLIENT_BLKID_RESERVED                        = 0x0,\n\tDBG_CLIENT_BLKID_dbg                             = 0x1,\n\tDBG_CLIENT_BLKID_dco0                            = 0x2,\n\tDBG_CLIENT_BLKID_wd                              = 0x3,\n\tDBG_CLIENT_BLKID_vmc                             = 0x4,\n\tDBG_CLIENT_BLKID_scf2                            = 0x5,\n\tDBG_CLIENT_BLKID_spim3                           = 0x6,\n\tDBG_CLIENT_BLKID_cb3                             = 0x7,\n\tDBG_CLIENT_BLKID_sx0                             = 0x8,\n\tDBG_CLIENT_BLKID_cb2                             = 0x9,\n\tDBG_CLIENT_BLKID_bci1                            = 0xa,\n\tDBG_CLIENT_BLKID_xdma                            = 0xb,\n\tDBG_CLIENT_BLKID_bci0                            = 0xc,\n\tDBG_CLIENT_BLKID_spim0                           = 0xd,\n\tDBG_CLIENT_BLKID_mcd0                            = 0xe,\n\tDBG_CLIENT_BLKID_mcc0                            = 0xf,\n\tDBG_CLIENT_BLKID_cb0                             = 0x10,\n\tDBG_CLIENT_BLKID_cb1                             = 0x11,\n\tDBG_CLIENT_BLKID_cpc_0                           = 0x12,\n\tDBG_CLIENT_BLKID_cpc_1                           = 0x13,\n\tDBG_CLIENT_BLKID_cpf                             = 0x14,\n\tDBG_CLIENT_BLKID_rlc                             = 0x15,\n\tDBG_CLIENT_BLKID_grbm                            = 0x16,\n\tDBG_CLIENT_BLKID_bif                             = 0x17,\n\tDBG_CLIENT_BLKID_scf1                            = 0x18,\n\tDBG_CLIENT_BLKID_sam                             = 0x19,\n\tDBG_CLIENT_BLKID_mcd4                            = 0x1a,\n\tDBG_CLIENT_BLKID_mcc4                            = 0x1b,\n\tDBG_CLIENT_BLKID_gmcon                           = 0x1c,\n\tDBG_CLIENT_BLKID_mcb                             = 0x1d,\n\tDBG_CLIENT_BLKID_vgt0                            = 0x1e,\n\tDBG_CLIENT_BLKID_pc0                             = 0x1f,\n\tDBG_CLIENT_BLKID_spim1                           = 0x20,\n\tDBG_CLIENT_BLKID_bci2                            = 0x21,\n\tDBG_CLIENT_BLKID_mcd6                            = 0x22,\n\tDBG_CLIENT_BLKID_mcc6                            = 0x23,\n\tDBG_CLIENT_BLKID_mcd3                            = 0x24,\n\tDBG_CLIENT_BLKID_mcc3                            = 0x25,\n\tDBG_CLIENT_BLKID_uvdm_0                          = 0x26,\n\tDBG_CLIENT_BLKID_uvdm_1                          = 0x27,\n\tDBG_CLIENT_BLKID_uvdm_2                          = 0x28,\n\tDBG_CLIENT_BLKID_uvdm_3                          = 0x29,\n\tDBG_CLIENT_BLKID_spim2                           = 0x2a,\n\tDBG_CLIENT_BLKID_ds                              = 0x2b,\n\tDBG_CLIENT_BLKID_srbm                            = 0x2c,\n\tDBG_CLIENT_BLKID_ih                              = 0x2d,\n\tDBG_CLIENT_BLKID_sem                             = 0x2e,\n\tDBG_CLIENT_BLKID_sdma_0                          = 0x2f,\n\tDBG_CLIENT_BLKID_sdma_1                          = 0x30,\n\tDBG_CLIENT_BLKID_hdp                             = 0x31,\n\tDBG_CLIENT_BLKID_acp_0                           = 0x32,\n\tDBG_CLIENT_BLKID_acp_1                           = 0x33,\n\tDBG_CLIENT_BLKID_vceb_0                          = 0x34,\n\tDBG_CLIENT_BLKID_vceb_1                          = 0x35,\n\tDBG_CLIENT_BLKID_vceb_2                          = 0x36,\n\tDBG_CLIENT_BLKID_mcd2                            = 0x37,\n\tDBG_CLIENT_BLKID_mcc2                            = 0x38,\n\tDBG_CLIENT_BLKID_scf3                            = 0x39,\n\tDBG_CLIENT_BLKID_bci3                            = 0x3a,\n\tDBG_CLIENT_BLKID_mcd5                            = 0x3b,\n\tDBG_CLIENT_BLKID_mcc5                            = 0x3c,\n\tDBG_CLIENT_BLKID_vgt2                            = 0x3d,\n\tDBG_CLIENT_BLKID_pc2                             = 0x3e,\n\tDBG_CLIENT_BLKID_smu_0                           = 0x3f,\n\tDBG_CLIENT_BLKID_smu_1                           = 0x40,\n\tDBG_CLIENT_BLKID_smu_2                           = 0x41,\n\tDBG_CLIENT_BLKID_vcea_0                          = 0x42,\n\tDBG_CLIENT_BLKID_vcea_1                          = 0x43,\n\tDBG_CLIENT_BLKID_vcea_2                          = 0x44,\n\tDBG_CLIENT_BLKID_vcea_3                          = 0x45,\n\tDBG_CLIENT_BLKID_vcea_4                          = 0x46,\n\tDBG_CLIENT_BLKID_vcea_5                          = 0x47,\n\tDBG_CLIENT_BLKID_vcea_6                          = 0x48,\n\tDBG_CLIENT_BLKID_scf0                            = 0x49,\n\tDBG_CLIENT_BLKID_vgt1                            = 0x4a,\n\tDBG_CLIENT_BLKID_pc1                             = 0x4b,\n\tDBG_CLIENT_BLKID_gdc_0                           = 0x4c,\n\tDBG_CLIENT_BLKID_gdc_1                           = 0x4d,\n\tDBG_CLIENT_BLKID_gdc_2                           = 0x4e,\n\tDBG_CLIENT_BLKID_gdc_3                           = 0x4f,\n\tDBG_CLIENT_BLKID_gdc_4                           = 0x50,\n\tDBG_CLIENT_BLKID_gdc_5                           = 0x51,\n\tDBG_CLIENT_BLKID_gdc_6                           = 0x52,\n\tDBG_CLIENT_BLKID_gdc_7                           = 0x53,\n\tDBG_CLIENT_BLKID_gdc_8                           = 0x54,\n\tDBG_CLIENT_BLKID_gdc_9                           = 0x55,\n\tDBG_CLIENT_BLKID_gdc_10                          = 0x56,\n\tDBG_CLIENT_BLKID_gdc_11                          = 0x57,\n\tDBG_CLIENT_BLKID_gdc_12                          = 0x58,\n\tDBG_CLIENT_BLKID_gdc_13                          = 0x59,\n\tDBG_CLIENT_BLKID_gdc_14                          = 0x5a,\n\tDBG_CLIENT_BLKID_gdc_15                          = 0x5b,\n\tDBG_CLIENT_BLKID_gdc_16                          = 0x5c,\n\tDBG_CLIENT_BLKID_gdc_17                          = 0x5d,\n\tDBG_CLIENT_BLKID_gdc_18                          = 0x5e,\n\tDBG_CLIENT_BLKID_gdc_19                          = 0x5f,\n\tDBG_CLIENT_BLKID_gdc_20                          = 0x60,\n\tDBG_CLIENT_BLKID_gdc_21                          = 0x61,\n\tDBG_CLIENT_BLKID_gdc_22                          = 0x62,\n\tDBG_CLIENT_BLKID_vgt3                            = 0x63,\n\tDBG_CLIENT_BLKID_pc3                             = 0x64,\n\tDBG_CLIENT_BLKID_uvdu_0                          = 0x65,\n\tDBG_CLIENT_BLKID_uvdu_1                          = 0x66,\n\tDBG_CLIENT_BLKID_uvdu_2                          = 0x67,\n\tDBG_CLIENT_BLKID_uvdu_3                          = 0x68,\n\tDBG_CLIENT_BLKID_uvdu_4                          = 0x69,\n\tDBG_CLIENT_BLKID_uvdu_5                          = 0x6a,\n\tDBG_CLIENT_BLKID_uvdu_6                          = 0x6b,\n\tDBG_CLIENT_BLKID_mcd7                            = 0x6c,\n\tDBG_CLIENT_BLKID_mcc7                            = 0x6d,\n\tDBG_CLIENT_BLKID_cpg_0                           = 0x6e,\n\tDBG_CLIENT_BLKID_cpg_1                           = 0x6f,\n\tDBG_CLIENT_BLKID_gck                             = 0x70,\n\tDBG_CLIENT_BLKID_mcd1                            = 0x71,\n\tDBG_CLIENT_BLKID_mcc1                            = 0x72,\n\tDBG_CLIENT_BLKID_cb101                           = 0x73,\n\tDBG_CLIENT_BLKID_cb103                           = 0x74,\n\tDBG_CLIENT_BLKID_sx10                            = 0x75,\n\tDBG_CLIENT_BLKID_cb102                           = 0x76,\n\tDBG_CLIENT_BLKID_cb002                           = 0x77,\n\tDBG_CLIENT_BLKID_cb100                           = 0x78,\n\tDBG_CLIENT_BLKID_cb000                           = 0x79,\n\tDBG_CLIENT_BLKID_pa00                            = 0x7a,\n\tDBG_CLIENT_BLKID_pa10                            = 0x7b,\n\tDBG_CLIENT_BLKID_ia0                             = 0x7c,\n\tDBG_CLIENT_BLKID_ia1                             = 0x7d,\n\tDBG_CLIENT_BLKID_tmonw00                         = 0x7e,\n\tDBG_CLIENT_BLKID_cb001                           = 0x7f,\n\tDBG_CLIENT_BLKID_cb003                           = 0x80,\n\tDBG_CLIENT_BLKID_sx00                            = 0x81,\n\tDBG_CLIENT_BLKID_sx20                            = 0x82,\n\tDBG_CLIENT_BLKID_cb203                           = 0x83,\n\tDBG_CLIENT_BLKID_cb201                           = 0x84,\n\tDBG_CLIENT_BLKID_cb302                           = 0x85,\n\tDBG_CLIENT_BLKID_cb202                           = 0x86,\n\tDBG_CLIENT_BLKID_cb300                           = 0x87,\n\tDBG_CLIENT_BLKID_cb200                           = 0x88,\n\tDBG_CLIENT_BLKID_pa01                            = 0x89,\n\tDBG_CLIENT_BLKID_pa11                            = 0x8a,\n\tDBG_CLIENT_BLKID_sx30                            = 0x8b,\n\tDBG_CLIENT_BLKID_cb303                           = 0x8c,\n\tDBG_CLIENT_BLKID_cb301                           = 0x8d,\n\tDBG_CLIENT_BLKID_dco                             = 0x8e,\n\tDBG_CLIENT_BLKID_scb0                            = 0x8f,\n\tDBG_CLIENT_BLKID_scb1                            = 0x90,\n\tDBG_CLIENT_BLKID_scb2                            = 0x91,\n\tDBG_CLIENT_BLKID_scb3                            = 0x92,\n\tDBG_CLIENT_BLKID_tmonw01                         = 0x93,\n\tDBG_CLIENT_BLKID_RESERVED_LAST                   = 0x94,\n} DebugBlockId;\ntypedef enum DebugBlockId_OLD {\n\tDBG_BLOCK_ID_RESERVED                            = 0x0,\n\tDBG_BLOCK_ID_DBG                                 = 0x1,\n\tDBG_BLOCK_ID_VMC                                 = 0x2,\n\tDBG_BLOCK_ID_PDMA                                = 0x3,\n\tDBG_BLOCK_ID_CG                                  = 0x4,\n\tDBG_BLOCK_ID_SRBM                                = 0x5,\n\tDBG_BLOCK_ID_GRBM                                = 0x6,\n\tDBG_BLOCK_ID_RLC                                 = 0x7,\n\tDBG_BLOCK_ID_CSC                                 = 0x8,\n\tDBG_BLOCK_ID_SEM                                 = 0x9,\n\tDBG_BLOCK_ID_IH                                  = 0xa,\n\tDBG_BLOCK_ID_SC                                  = 0xb,\n\tDBG_BLOCK_ID_SQ                                  = 0xc,\n\tDBG_BLOCK_ID_AVP                                 = 0xd,\n\tDBG_BLOCK_ID_GMCON                               = 0xe,\n\tDBG_BLOCK_ID_SMU                                 = 0xf,\n\tDBG_BLOCK_ID_DMA0                                = 0x10,\n\tDBG_BLOCK_ID_DMA1                                = 0x11,\n\tDBG_BLOCK_ID_SPIM                                = 0x12,\n\tDBG_BLOCK_ID_GDS                                 = 0x13,\n\tDBG_BLOCK_ID_SPIS                                = 0x14,\n\tDBG_BLOCK_ID_UNUSED0                             = 0x15,\n\tDBG_BLOCK_ID_PA0                                 = 0x16,\n\tDBG_BLOCK_ID_PA1                                 = 0x17,\n\tDBG_BLOCK_ID_CP0                                 = 0x18,\n\tDBG_BLOCK_ID_CP1                                 = 0x19,\n\tDBG_BLOCK_ID_CP2                                 = 0x1a,\n\tDBG_BLOCK_ID_UNUSED1                             = 0x1b,\n\tDBG_BLOCK_ID_UVDU                                = 0x1c,\n\tDBG_BLOCK_ID_UVDM                                = 0x1d,\n\tDBG_BLOCK_ID_VCE                                 = 0x1e,\n\tDBG_BLOCK_ID_UNUSED2                             = 0x1f,\n\tDBG_BLOCK_ID_VGT0                                = 0x20,\n\tDBG_BLOCK_ID_VGT1                                = 0x21,\n\tDBG_BLOCK_ID_IA                                  = 0x22,\n\tDBG_BLOCK_ID_UNUSED3                             = 0x23,\n\tDBG_BLOCK_ID_SCT0                                = 0x24,\n\tDBG_BLOCK_ID_SCT1                                = 0x25,\n\tDBG_BLOCK_ID_SPM0                                = 0x26,\n\tDBG_BLOCK_ID_SPM1                                = 0x27,\n\tDBG_BLOCK_ID_TCAA                                = 0x28,\n\tDBG_BLOCK_ID_TCAB                                = 0x29,\n\tDBG_BLOCK_ID_TCCA                                = 0x2a,\n\tDBG_BLOCK_ID_TCCB                                = 0x2b,\n\tDBG_BLOCK_ID_MCC0                                = 0x2c,\n\tDBG_BLOCK_ID_MCC1                                = 0x2d,\n\tDBG_BLOCK_ID_MCC2                                = 0x2e,\n\tDBG_BLOCK_ID_MCC3                                = 0x2f,\n\tDBG_BLOCK_ID_SX0                                 = 0x30,\n\tDBG_BLOCK_ID_SX1                                 = 0x31,\n\tDBG_BLOCK_ID_SX2                                 = 0x32,\n\tDBG_BLOCK_ID_SX3                                 = 0x33,\n\tDBG_BLOCK_ID_UNUSED4                             = 0x34,\n\tDBG_BLOCK_ID_UNUSED5                             = 0x35,\n\tDBG_BLOCK_ID_UNUSED6                             = 0x36,\n\tDBG_BLOCK_ID_UNUSED7                             = 0x37,\n\tDBG_BLOCK_ID_PC0                                 = 0x38,\n\tDBG_BLOCK_ID_PC1                                 = 0x39,\n\tDBG_BLOCK_ID_UNUSED8                             = 0x3a,\n\tDBG_BLOCK_ID_UNUSED9                             = 0x3b,\n\tDBG_BLOCK_ID_UNUSED10                            = 0x3c,\n\tDBG_BLOCK_ID_UNUSED11                            = 0x3d,\n\tDBG_BLOCK_ID_MCB                                 = 0x3e,\n\tDBG_BLOCK_ID_UNUSED12                            = 0x3f,\n\tDBG_BLOCK_ID_SCB0                                = 0x40,\n\tDBG_BLOCK_ID_SCB1                                = 0x41,\n\tDBG_BLOCK_ID_UNUSED13                            = 0x42,\n\tDBG_BLOCK_ID_UNUSED14                            = 0x43,\n\tDBG_BLOCK_ID_SCF0                                = 0x44,\n\tDBG_BLOCK_ID_SCF1                                = 0x45,\n\tDBG_BLOCK_ID_UNUSED15                            = 0x46,\n\tDBG_BLOCK_ID_UNUSED16                            = 0x47,\n\tDBG_BLOCK_ID_BCI0                                = 0x48,\n\tDBG_BLOCK_ID_BCI1                                = 0x49,\n\tDBG_BLOCK_ID_BCI2                                = 0x4a,\n\tDBG_BLOCK_ID_BCI3                                = 0x4b,\n\tDBG_BLOCK_ID_UNUSED17                            = 0x4c,\n\tDBG_BLOCK_ID_UNUSED18                            = 0x4d,\n\tDBG_BLOCK_ID_UNUSED19                            = 0x4e,\n\tDBG_BLOCK_ID_UNUSED20                            = 0x4f,\n\tDBG_BLOCK_ID_CB00                                = 0x50,\n\tDBG_BLOCK_ID_CB01                                = 0x51,\n\tDBG_BLOCK_ID_CB02                                = 0x52,\n\tDBG_BLOCK_ID_CB03                                = 0x53,\n\tDBG_BLOCK_ID_CB04                                = 0x54,\n\tDBG_BLOCK_ID_UNUSED21                            = 0x55,\n\tDBG_BLOCK_ID_UNUSED22                            = 0x56,\n\tDBG_BLOCK_ID_UNUSED23                            = 0x57,\n\tDBG_BLOCK_ID_CB10                                = 0x58,\n\tDBG_BLOCK_ID_CB11                                = 0x59,\n\tDBG_BLOCK_ID_CB12                                = 0x5a,\n\tDBG_BLOCK_ID_CB13                                = 0x5b,\n\tDBG_BLOCK_ID_CB14                                = 0x5c,\n\tDBG_BLOCK_ID_UNUSED24                            = 0x5d,\n\tDBG_BLOCK_ID_UNUSED25                            = 0x5e,\n\tDBG_BLOCK_ID_UNUSED26                            = 0x5f,\n\tDBG_BLOCK_ID_TCP0                                = 0x60,\n\tDBG_BLOCK_ID_TCP1                                = 0x61,\n\tDBG_BLOCK_ID_TCP2                                = 0x62,\n\tDBG_BLOCK_ID_TCP3                                = 0x63,\n\tDBG_BLOCK_ID_TCP4                                = 0x64,\n\tDBG_BLOCK_ID_TCP5                                = 0x65,\n\tDBG_BLOCK_ID_TCP6                                = 0x66,\n\tDBG_BLOCK_ID_TCP7                                = 0x67,\n\tDBG_BLOCK_ID_TCP8                                = 0x68,\n\tDBG_BLOCK_ID_TCP9                                = 0x69,\n\tDBG_BLOCK_ID_TCP10                               = 0x6a,\n\tDBG_BLOCK_ID_TCP11                               = 0x6b,\n\tDBG_BLOCK_ID_TCP12                               = 0x6c,\n\tDBG_BLOCK_ID_TCP13                               = 0x6d,\n\tDBG_BLOCK_ID_TCP14                               = 0x6e,\n\tDBG_BLOCK_ID_TCP15                               = 0x6f,\n\tDBG_BLOCK_ID_TCP16                               = 0x70,\n\tDBG_BLOCK_ID_TCP17                               = 0x71,\n\tDBG_BLOCK_ID_TCP18                               = 0x72,\n\tDBG_BLOCK_ID_TCP19                               = 0x73,\n\tDBG_BLOCK_ID_TCP20                               = 0x74,\n\tDBG_BLOCK_ID_TCP21                               = 0x75,\n\tDBG_BLOCK_ID_TCP22                               = 0x76,\n\tDBG_BLOCK_ID_TCP23                               = 0x77,\n\tDBG_BLOCK_ID_TCP_RESERVED0                       = 0x78,\n\tDBG_BLOCK_ID_TCP_RESERVED1                       = 0x79,\n\tDBG_BLOCK_ID_TCP_RESERVED2                       = 0x7a,\n\tDBG_BLOCK_ID_TCP_RESERVED3                       = 0x7b,\n\tDBG_BLOCK_ID_TCP_RESERVED4                       = 0x7c,\n\tDBG_BLOCK_ID_TCP_RESERVED5                       = 0x7d,\n\tDBG_BLOCK_ID_TCP_RESERVED6                       = 0x7e,\n\tDBG_BLOCK_ID_TCP_RESERVED7                       = 0x7f,\n\tDBG_BLOCK_ID_DB00                                = 0x80,\n\tDBG_BLOCK_ID_DB01                                = 0x81,\n\tDBG_BLOCK_ID_DB02                                = 0x82,\n\tDBG_BLOCK_ID_DB03                                = 0x83,\n\tDBG_BLOCK_ID_DB04                                = 0x84,\n\tDBG_BLOCK_ID_UNUSED27                            = 0x85,\n\tDBG_BLOCK_ID_UNUSED28                            = 0x86,\n\tDBG_BLOCK_ID_UNUSED29                            = 0x87,\n\tDBG_BLOCK_ID_DB10                                = 0x88,\n\tDBG_BLOCK_ID_DB11                                = 0x89,\n\tDBG_BLOCK_ID_DB12                                = 0x8a,\n\tDBG_BLOCK_ID_DB13                                = 0x8b,\n\tDBG_BLOCK_ID_DB14                                = 0x8c,\n\tDBG_BLOCK_ID_UNUSED30                            = 0x8d,\n\tDBG_BLOCK_ID_UNUSED31                            = 0x8e,\n\tDBG_BLOCK_ID_UNUSED32                            = 0x8f,\n\tDBG_BLOCK_ID_TCC0                                = 0x90,\n\tDBG_BLOCK_ID_TCC1                                = 0x91,\n\tDBG_BLOCK_ID_TCC2                                = 0x92,\n\tDBG_BLOCK_ID_TCC3                                = 0x93,\n\tDBG_BLOCK_ID_TCC4                                = 0x94,\n\tDBG_BLOCK_ID_TCC5                                = 0x95,\n\tDBG_BLOCK_ID_TCC6                                = 0x96,\n\tDBG_BLOCK_ID_TCC7                                = 0x97,\n\tDBG_BLOCK_ID_SPS00                               = 0x98,\n\tDBG_BLOCK_ID_SPS01                               = 0x99,\n\tDBG_BLOCK_ID_SPS02                               = 0x9a,\n\tDBG_BLOCK_ID_SPS10                               = 0x9b,\n\tDBG_BLOCK_ID_SPS11                               = 0x9c,\n\tDBG_BLOCK_ID_SPS12                               = 0x9d,\n\tDBG_BLOCK_ID_UNUSED33                            = 0x9e,\n\tDBG_BLOCK_ID_UNUSED34                            = 0x9f,\n\tDBG_BLOCK_ID_TA00                                = 0xa0,\n\tDBG_BLOCK_ID_TA01                                = 0xa1,\n\tDBG_BLOCK_ID_TA02                                = 0xa2,\n\tDBG_BLOCK_ID_TA03                                = 0xa3,\n\tDBG_BLOCK_ID_TA04                                = 0xa4,\n\tDBG_BLOCK_ID_TA05                                = 0xa5,\n\tDBG_BLOCK_ID_TA06                                = 0xa6,\n\tDBG_BLOCK_ID_TA07                                = 0xa7,\n\tDBG_BLOCK_ID_TA08                                = 0xa8,\n\tDBG_BLOCK_ID_TA09                                = 0xa9,\n\tDBG_BLOCK_ID_TA0A                                = 0xaa,\n\tDBG_BLOCK_ID_TA0B                                = 0xab,\n\tDBG_BLOCK_ID_UNUSED35                            = 0xac,\n\tDBG_BLOCK_ID_UNUSED36                            = 0xad,\n\tDBG_BLOCK_ID_UNUSED37                            = 0xae,\n\tDBG_BLOCK_ID_UNUSED38                            = 0xaf,\n\tDBG_BLOCK_ID_TA10                                = 0xb0,\n\tDBG_BLOCK_ID_TA11                                = 0xb1,\n\tDBG_BLOCK_ID_TA12                                = 0xb2,\n\tDBG_BLOCK_ID_TA13                                = 0xb3,\n\tDBG_BLOCK_ID_TA14                                = 0xb4,\n\tDBG_BLOCK_ID_TA15                                = 0xb5,\n\tDBG_BLOCK_ID_TA16                                = 0xb6,\n\tDBG_BLOCK_ID_TA17                                = 0xb7,\n\tDBG_BLOCK_ID_TA18                                = 0xb8,\n\tDBG_BLOCK_ID_TA19                                = 0xb9,\n\tDBG_BLOCK_ID_TA1A                                = 0xba,\n\tDBG_BLOCK_ID_TA1B                                = 0xbb,\n\tDBG_BLOCK_ID_UNUSED39                            = 0xbc,\n\tDBG_BLOCK_ID_UNUSED40                            = 0xbd,\n\tDBG_BLOCK_ID_UNUSED41                            = 0xbe,\n\tDBG_BLOCK_ID_UNUSED42                            = 0xbf,\n\tDBG_BLOCK_ID_TD00                                = 0xc0,\n\tDBG_BLOCK_ID_TD01                                = 0xc1,\n\tDBG_BLOCK_ID_TD02                                = 0xc2,\n\tDBG_BLOCK_ID_TD03                                = 0xc3,\n\tDBG_BLOCK_ID_TD04                                = 0xc4,\n\tDBG_BLOCK_ID_TD05                                = 0xc5,\n\tDBG_BLOCK_ID_TD06                                = 0xc6,\n\tDBG_BLOCK_ID_TD07                                = 0xc7,\n\tDBG_BLOCK_ID_TD08                                = 0xc8,\n\tDBG_BLOCK_ID_TD09                                = 0xc9,\n\tDBG_BLOCK_ID_TD0A                                = 0xca,\n\tDBG_BLOCK_ID_TD0B                                = 0xcb,\n\tDBG_BLOCK_ID_UNUSED43                            = 0xcc,\n\tDBG_BLOCK_ID_UNUSED44                            = 0xcd,\n\tDBG_BLOCK_ID_UNUSED45                            = 0xce,\n\tDBG_BLOCK_ID_UNUSED46                            = 0xcf,\n\tDBG_BLOCK_ID_TD10                                = 0xd0,\n\tDBG_BLOCK_ID_TD11                                = 0xd1,\n\tDBG_BLOCK_ID_TD12                                = 0xd2,\n\tDBG_BLOCK_ID_TD13                                = 0xd3,\n\tDBG_BLOCK_ID_TD14                                = 0xd4,\n\tDBG_BLOCK_ID_TD15                                = 0xd5,\n\tDBG_BLOCK_ID_TD16                                = 0xd6,\n\tDBG_BLOCK_ID_TD17                                = 0xd7,\n\tDBG_BLOCK_ID_TD18                                = 0xd8,\n\tDBG_BLOCK_ID_TD19                                = 0xd9,\n\tDBG_BLOCK_ID_TD1A                                = 0xda,\n\tDBG_BLOCK_ID_TD1B                                = 0xdb,\n\tDBG_BLOCK_ID_UNUSED47                            = 0xdc,\n\tDBG_BLOCK_ID_UNUSED48                            = 0xdd,\n\tDBG_BLOCK_ID_UNUSED49                            = 0xde,\n\tDBG_BLOCK_ID_UNUSED50                            = 0xdf,\n\tDBG_BLOCK_ID_MCD0                                = 0xe0,\n\tDBG_BLOCK_ID_MCD1                                = 0xe1,\n\tDBG_BLOCK_ID_MCD2                                = 0xe2,\n\tDBG_BLOCK_ID_MCD3                                = 0xe3,\n\tDBG_BLOCK_ID_MCD4                                = 0xe4,\n\tDBG_BLOCK_ID_MCD5                                = 0xe5,\n\tDBG_BLOCK_ID_UNUSED51                            = 0xe6,\n\tDBG_BLOCK_ID_UNUSED52                            = 0xe7,\n} DebugBlockId_OLD;\ntypedef enum DebugBlockId_BY2 {\n\tDBG_BLOCK_ID_RESERVED_BY2                        = 0x0,\n\tDBG_BLOCK_ID_VMC_BY2                             = 0x1,\n\tDBG_BLOCK_ID_CG_BY2                              = 0x2,\n\tDBG_BLOCK_ID_GRBM_BY2                            = 0x3,\n\tDBG_BLOCK_ID_CSC_BY2                             = 0x4,\n\tDBG_BLOCK_ID_IH_BY2                              = 0x5,\n\tDBG_BLOCK_ID_SQ_BY2                              = 0x6,\n\tDBG_BLOCK_ID_GMCON_BY2                           = 0x7,\n\tDBG_BLOCK_ID_DMA0_BY2                            = 0x8,\n\tDBG_BLOCK_ID_SPIM_BY2                            = 0x9,\n\tDBG_BLOCK_ID_SPIS_BY2                            = 0xa,\n\tDBG_BLOCK_ID_PA0_BY2                             = 0xb,\n\tDBG_BLOCK_ID_CP0_BY2                             = 0xc,\n\tDBG_BLOCK_ID_CP2_BY2                             = 0xd,\n\tDBG_BLOCK_ID_UVDU_BY2                            = 0xe,\n\tDBG_BLOCK_ID_VCE_BY2                             = 0xf,\n\tDBG_BLOCK_ID_VGT0_BY2                            = 0x10,\n\tDBG_BLOCK_ID_IA_BY2                              = 0x11,\n\tDBG_BLOCK_ID_SCT0_BY2                            = 0x12,\n\tDBG_BLOCK_ID_SPM0_BY2                            = 0x13,\n\tDBG_BLOCK_ID_TCAA_BY2                            = 0x14,\n\tDBG_BLOCK_ID_TCCA_BY2                            = 0x15,\n\tDBG_BLOCK_ID_MCC0_BY2                            = 0x16,\n\tDBG_BLOCK_ID_MCC2_BY2                            = 0x17,\n\tDBG_BLOCK_ID_SX0_BY2                             = 0x18,\n\tDBG_BLOCK_ID_SX2_BY2                             = 0x19,\n\tDBG_BLOCK_ID_UNUSED4_BY2                         = 0x1a,\n\tDBG_BLOCK_ID_UNUSED6_BY2                         = 0x1b,\n\tDBG_BLOCK_ID_PC0_BY2                             = 0x1c,\n\tDBG_BLOCK_ID_UNUSED8_BY2                         = 0x1d,\n\tDBG_BLOCK_ID_UNUSED10_BY2                        = 0x1e,\n\tDBG_BLOCK_ID_MCB_BY2                             = 0x1f,\n\tDBG_BLOCK_ID_SCB0_BY2                            = 0x20,\n\tDBG_BLOCK_ID_UNUSED13_BY2                        = 0x21,\n\tDBG_BLOCK_ID_SCF0_BY2                            = 0x22,\n\tDBG_BLOCK_ID_UNUSED15_BY2                        = 0x23,\n\tDBG_BLOCK_ID_BCI0_BY2                            = 0x24,\n\tDBG_BLOCK_ID_BCI2_BY2                            = 0x25,\n\tDBG_BLOCK_ID_UNUSED17_BY2                        = 0x26,\n\tDBG_BLOCK_ID_UNUSED19_BY2                        = 0x27,\n\tDBG_BLOCK_ID_CB00_BY2                            = 0x28,\n\tDBG_BLOCK_ID_CB02_BY2                            = 0x29,\n\tDBG_BLOCK_ID_CB04_BY2                            = 0x2a,\n\tDBG_BLOCK_ID_UNUSED22_BY2                        = 0x2b,\n\tDBG_BLOCK_ID_CB10_BY2                            = 0x2c,\n\tDBG_BLOCK_ID_CB12_BY2                            = 0x2d,\n\tDBG_BLOCK_ID_CB14_BY2                            = 0x2e,\n\tDBG_BLOCK_ID_UNUSED25_BY2                        = 0x2f,\n\tDBG_BLOCK_ID_TCP0_BY2                            = 0x30,\n\tDBG_BLOCK_ID_TCP2_BY2                            = 0x31,\n\tDBG_BLOCK_ID_TCP4_BY2                            = 0x32,\n\tDBG_BLOCK_ID_TCP6_BY2                            = 0x33,\n\tDBG_BLOCK_ID_TCP8_BY2                            = 0x34,\n\tDBG_BLOCK_ID_TCP10_BY2                           = 0x35,\n\tDBG_BLOCK_ID_TCP12_BY2                           = 0x36,\n\tDBG_BLOCK_ID_TCP14_BY2                           = 0x37,\n\tDBG_BLOCK_ID_TCP16_BY2                           = 0x38,\n\tDBG_BLOCK_ID_TCP18_BY2                           = 0x39,\n\tDBG_BLOCK_ID_TCP20_BY2                           = 0x3a,\n\tDBG_BLOCK_ID_TCP22_BY2                           = 0x3b,\n\tDBG_BLOCK_ID_TCP_RESERVED0_BY2                   = 0x3c,\n\tDBG_BLOCK_ID_TCP_RESERVED2_BY2                   = 0x3d,\n\tDBG_BLOCK_ID_TCP_RESERVED4_BY2                   = 0x3e,\n\tDBG_BLOCK_ID_TCP_RESERVED6_BY2                   = 0x3f,\n\tDBG_BLOCK_ID_DB00_BY2                            = 0x40,\n\tDBG_BLOCK_ID_DB02_BY2                            = 0x41,\n\tDBG_BLOCK_ID_DB04_BY2                            = 0x42,\n\tDBG_BLOCK_ID_UNUSED28_BY2                        = 0x43,\n\tDBG_BLOCK_ID_DB10_BY2                            = 0x44,\n\tDBG_BLOCK_ID_DB12_BY2                            = 0x45,\n\tDBG_BLOCK_ID_DB14_BY2                            = 0x46,\n\tDBG_BLOCK_ID_UNUSED31_BY2                        = 0x47,\n\tDBG_BLOCK_ID_TCC0_BY2                            = 0x48,\n\tDBG_BLOCK_ID_TCC2_BY2                            = 0x49,\n\tDBG_BLOCK_ID_TCC4_BY2                            = 0x4a,\n\tDBG_BLOCK_ID_TCC6_BY2                            = 0x4b,\n\tDBG_BLOCK_ID_SPS00_BY2                           = 0x4c,\n\tDBG_BLOCK_ID_SPS02_BY2                           = 0x4d,\n\tDBG_BLOCK_ID_SPS11_BY2                           = 0x4e,\n\tDBG_BLOCK_ID_UNUSED33_BY2                        = 0x4f,\n\tDBG_BLOCK_ID_TA00_BY2                            = 0x50,\n\tDBG_BLOCK_ID_TA02_BY2                            = 0x51,\n\tDBG_BLOCK_ID_TA04_BY2                            = 0x52,\n\tDBG_BLOCK_ID_TA06_BY2                            = 0x53,\n\tDBG_BLOCK_ID_TA08_BY2                            = 0x54,\n\tDBG_BLOCK_ID_TA0A_BY2                            = 0x55,\n\tDBG_BLOCK_ID_UNUSED35_BY2                        = 0x56,\n\tDBG_BLOCK_ID_UNUSED37_BY2                        = 0x57,\n\tDBG_BLOCK_ID_TA10_BY2                            = 0x58,\n\tDBG_BLOCK_ID_TA12_BY2                            = 0x59,\n\tDBG_BLOCK_ID_TA14_BY2                            = 0x5a,\n\tDBG_BLOCK_ID_TA16_BY2                            = 0x5b,\n\tDBG_BLOCK_ID_TA18_BY2                            = 0x5c,\n\tDBG_BLOCK_ID_TA1A_BY2                            = 0x5d,\n\tDBG_BLOCK_ID_UNUSED39_BY2                        = 0x5e,\n\tDBG_BLOCK_ID_UNUSED41_BY2                        = 0x5f,\n\tDBG_BLOCK_ID_TD00_BY2                            = 0x60,\n\tDBG_BLOCK_ID_TD02_BY2                            = 0x61,\n\tDBG_BLOCK_ID_TD04_BY2                            = 0x62,\n\tDBG_BLOCK_ID_TD06_BY2                            = 0x63,\n\tDBG_BLOCK_ID_TD08_BY2                            = 0x64,\n\tDBG_BLOCK_ID_TD0A_BY2                            = 0x65,\n\tDBG_BLOCK_ID_UNUSED43_BY2                        = 0x66,\n\tDBG_BLOCK_ID_UNUSED45_BY2                        = 0x67,\n\tDBG_BLOCK_ID_TD10_BY2                            = 0x68,\n\tDBG_BLOCK_ID_TD12_BY2                            = 0x69,\n\tDBG_BLOCK_ID_TD14_BY2                            = 0x6a,\n\tDBG_BLOCK_ID_TD16_BY2                            = 0x6b,\n\tDBG_BLOCK_ID_TD18_BY2                            = 0x6c,\n\tDBG_BLOCK_ID_TD1A_BY2                            = 0x6d,\n\tDBG_BLOCK_ID_UNUSED47_BY2                        = 0x6e,\n\tDBG_BLOCK_ID_UNUSED49_BY2                        = 0x6f,\n\tDBG_BLOCK_ID_MCD0_BY2                            = 0x70,\n\tDBG_BLOCK_ID_MCD2_BY2                            = 0x71,\n\tDBG_BLOCK_ID_MCD4_BY2                            = 0x72,\n\tDBG_BLOCK_ID_UNUSED51_BY2                        = 0x73,\n} DebugBlockId_BY2;\ntypedef enum DebugBlockId_BY4 {\n\tDBG_BLOCK_ID_RESERVED_BY4                        = 0x0,\n\tDBG_BLOCK_ID_CG_BY4                              = 0x1,\n\tDBG_BLOCK_ID_CSC_BY4                             = 0x2,\n\tDBG_BLOCK_ID_SQ_BY4                              = 0x3,\n\tDBG_BLOCK_ID_DMA0_BY4                            = 0x4,\n\tDBG_BLOCK_ID_SPIS_BY4                            = 0x5,\n\tDBG_BLOCK_ID_CP0_BY4                             = 0x6,\n\tDBG_BLOCK_ID_UVDU_BY4                            = 0x7,\n\tDBG_BLOCK_ID_VGT0_BY4                            = 0x8,\n\tDBG_BLOCK_ID_SCT0_BY4                            = 0x9,\n\tDBG_BLOCK_ID_TCAA_BY4                            = 0xa,\n\tDBG_BLOCK_ID_MCC0_BY4                            = 0xb,\n\tDBG_BLOCK_ID_SX0_BY4                             = 0xc,\n\tDBG_BLOCK_ID_UNUSED4_BY4                         = 0xd,\n\tDBG_BLOCK_ID_PC0_BY4                             = 0xe,\n\tDBG_BLOCK_ID_UNUSED10_BY4                        = 0xf,\n\tDBG_BLOCK_ID_SCB0_BY4                            = 0x10,\n\tDBG_BLOCK_ID_SCF0_BY4                            = 0x11,\n\tDBG_BLOCK_ID_BCI0_BY4                            = 0x12,\n\tDBG_BLOCK_ID_UNUSED17_BY4                        = 0x13,\n\tDBG_BLOCK_ID_CB00_BY4                            = 0x14,\n\tDBG_BLOCK_ID_CB04_BY4                            = 0x15,\n\tDBG_BLOCK_ID_CB10_BY4                            = 0x16,\n\tDBG_BLOCK_ID_CB14_BY4                            = 0x17,\n\tDBG_BLOCK_ID_TCP0_BY4                            = 0x18,\n\tDBG_BLOCK_ID_TCP4_BY4                            = 0x19,\n\tDBG_BLOCK_ID_TCP8_BY4                            = 0x1a,\n\tDBG_BLOCK_ID_TCP12_BY4                           = 0x1b,\n\tDBG_BLOCK_ID_TCP16_BY4                           = 0x1c,\n\tDBG_BLOCK_ID_TCP20_BY4                           = 0x1d,\n\tDBG_BLOCK_ID_TCP_RESERVED0_BY4                   = 0x1e,\n\tDBG_BLOCK_ID_TCP_RESERVED4_BY4                   = 0x1f,\n\tDBG_BLOCK_ID_DB_BY4                              = 0x20,\n\tDBG_BLOCK_ID_DB04_BY4                            = 0x21,\n\tDBG_BLOCK_ID_DB10_BY4                            = 0x22,\n\tDBG_BLOCK_ID_DB14_BY4                            = 0x23,\n\tDBG_BLOCK_ID_TCC0_BY4                            = 0x24,\n\tDBG_BLOCK_ID_TCC4_BY4                            = 0x25,\n\tDBG_BLOCK_ID_SPS00_BY4                           = 0x26,\n\tDBG_BLOCK_ID_SPS11_BY4                           = 0x27,\n\tDBG_BLOCK_ID_TA00_BY4                            = 0x28,\n\tDBG_BLOCK_ID_TA04_BY4                            = 0x29,\n\tDBG_BLOCK_ID_TA08_BY4                            = 0x2a,\n\tDBG_BLOCK_ID_UNUSED35_BY4                        = 0x2b,\n\tDBG_BLOCK_ID_TA10_BY4                            = 0x2c,\n\tDBG_BLOCK_ID_TA14_BY4                            = 0x2d,\n\tDBG_BLOCK_ID_TA18_BY4                            = 0x2e,\n\tDBG_BLOCK_ID_UNUSED39_BY4                        = 0x2f,\n\tDBG_BLOCK_ID_TD00_BY4                            = 0x30,\n\tDBG_BLOCK_ID_TD04_BY4                            = 0x31,\n\tDBG_BLOCK_ID_TD08_BY4                            = 0x32,\n\tDBG_BLOCK_ID_UNUSED43_BY4                        = 0x33,\n\tDBG_BLOCK_ID_TD10_BY4                            = 0x34,\n\tDBG_BLOCK_ID_TD14_BY4                            = 0x35,\n\tDBG_BLOCK_ID_TD18_BY4                            = 0x36,\n\tDBG_BLOCK_ID_UNUSED47_BY4                        = 0x37,\n\tDBG_BLOCK_ID_MCD0_BY4                            = 0x38,\n\tDBG_BLOCK_ID_MCD4_BY4                            = 0x39,\n} DebugBlockId_BY4;\ntypedef enum DebugBlockId_BY8 {\n\tDBG_BLOCK_ID_RESERVED_BY8                        = 0x0,\n\tDBG_BLOCK_ID_CSC_BY8                             = 0x1,\n\tDBG_BLOCK_ID_DMA0_BY8                            = 0x2,\n\tDBG_BLOCK_ID_CP0_BY8                             = 0x3,\n\tDBG_BLOCK_ID_VGT0_BY8                            = 0x4,\n\tDBG_BLOCK_ID_TCAA_BY8                            = 0x5,\n\tDBG_BLOCK_ID_SX0_BY8                             = 0x6,\n\tDBG_BLOCK_ID_PC0_BY8                             = 0x7,\n\tDBG_BLOCK_ID_SCB0_BY8                            = 0x8,\n\tDBG_BLOCK_ID_BCI0_BY8                            = 0x9,\n\tDBG_BLOCK_ID_CB00_BY8                            = 0xa,\n\tDBG_BLOCK_ID_CB10_BY8                            = 0xb,\n\tDBG_BLOCK_ID_TCP0_BY8                            = 0xc,\n\tDBG_BLOCK_ID_TCP8_BY8                            = 0xd,\n\tDBG_BLOCK_ID_TCP16_BY8                           = 0xe,\n\tDBG_BLOCK_ID_TCP_RESERVED0_BY8                   = 0xf,\n\tDBG_BLOCK_ID_DB00_BY8                            = 0x10,\n\tDBG_BLOCK_ID_DB10_BY8                            = 0x11,\n\tDBG_BLOCK_ID_TCC0_BY8                            = 0x12,\n\tDBG_BLOCK_ID_SPS00_BY8                           = 0x13,\n\tDBG_BLOCK_ID_TA00_BY8                            = 0x14,\n\tDBG_BLOCK_ID_TA08_BY8                            = 0x15,\n\tDBG_BLOCK_ID_TA10_BY8                            = 0x16,\n\tDBG_BLOCK_ID_TA18_BY8                            = 0x17,\n\tDBG_BLOCK_ID_TD00_BY8                            = 0x18,\n\tDBG_BLOCK_ID_TD08_BY8                            = 0x19,\n\tDBG_BLOCK_ID_TD10_BY8                            = 0x1a,\n\tDBG_BLOCK_ID_TD18_BY8                            = 0x1b,\n\tDBG_BLOCK_ID_MCD0_BY8                            = 0x1c,\n} DebugBlockId_BY8;\ntypedef enum DebugBlockId_BY16 {\n\tDBG_BLOCK_ID_RESERVED_BY16                       = 0x0,\n\tDBG_BLOCK_ID_DMA0_BY16                           = 0x1,\n\tDBG_BLOCK_ID_VGT0_BY16                           = 0x2,\n\tDBG_BLOCK_ID_SX0_BY16                            = 0x3,\n\tDBG_BLOCK_ID_SCB0_BY16                           = 0x4,\n\tDBG_BLOCK_ID_CB00_BY16                           = 0x5,\n\tDBG_BLOCK_ID_TCP0_BY16                           = 0x6,\n\tDBG_BLOCK_ID_TCP16_BY16                          = 0x7,\n\tDBG_BLOCK_ID_DB00_BY16                           = 0x8,\n\tDBG_BLOCK_ID_TCC0_BY16                           = 0x9,\n\tDBG_BLOCK_ID_TA00_BY16                           = 0xa,\n\tDBG_BLOCK_ID_TA10_BY16                           = 0xb,\n\tDBG_BLOCK_ID_TD00_BY16                           = 0xc,\n\tDBG_BLOCK_ID_TD10_BY16                           = 0xd,\n\tDBG_BLOCK_ID_MCD0_BY16                           = 0xe,\n} DebugBlockId_BY16;\ntypedef enum CompareRef {\n\tREF_NEVER                                        = 0x0,\n\tREF_LESS                                         = 0x1,\n\tREF_EQUAL                                        = 0x2,\n\tREF_LEQUAL                                       = 0x3,\n\tREF_GREATER                                      = 0x4,\n\tREF_NOTEQUAL                                     = 0x5,\n\tREF_GEQUAL                                       = 0x6,\n\tREF_ALWAYS                                       = 0x7,\n} CompareRef;\ntypedef enum ReadSize {\n\tREAD_256_BITS                                    = 0x0,\n\tREAD_512_BITS                                    = 0x1,\n} ReadSize;\ntypedef enum DepthFormat {\n\tDEPTH_INVALID                                    = 0x0,\n\tDEPTH_16                                         = 0x1,\n\tDEPTH_X8_24                                      = 0x2,\n\tDEPTH_8_24                                       = 0x3,\n\tDEPTH_X8_24_FLOAT                                = 0x4,\n\tDEPTH_8_24_FLOAT                                 = 0x5,\n\tDEPTH_32_FLOAT                                   = 0x6,\n\tDEPTH_X24_8_32_FLOAT                             = 0x7,\n} DepthFormat;\ntypedef enum ZFormat {\n\tZ_INVALID                                        = 0x0,\n\tZ_16                                             = 0x1,\n\tZ_24                                             = 0x2,\n\tZ_32_FLOAT                                       = 0x3,\n} ZFormat;\ntypedef enum StencilFormat {\n\tSTENCIL_INVALID                                  = 0x0,\n\tSTENCIL_8                                        = 0x1,\n} StencilFormat;\ntypedef enum CmaskMode {\n\tCMASK_CLEAR_NONE                                 = 0x0,\n\tCMASK_CLEAR_ONE                                  = 0x1,\n\tCMASK_CLEAR_ALL                                  = 0x2,\n\tCMASK_ANY_EXPANDED                               = 0x3,\n\tCMASK_ALPHA0_FRAG1                               = 0x4,\n\tCMASK_ALPHA0_FRAG2                               = 0x5,\n\tCMASK_ALPHA0_FRAG4                               = 0x6,\n\tCMASK_ALPHA0_FRAGS                               = 0x7,\n\tCMASK_ALPHA1_FRAG1                               = 0x8,\n\tCMASK_ALPHA1_FRAG2                               = 0x9,\n\tCMASK_ALPHA1_FRAG4                               = 0xa,\n\tCMASK_ALPHA1_FRAGS                               = 0xb,\n\tCMASK_ALPHAX_FRAG1                               = 0xc,\n\tCMASK_ALPHAX_FRAG2                               = 0xd,\n\tCMASK_ALPHAX_FRAG4                               = 0xe,\n\tCMASK_ALPHAX_FRAGS                               = 0xf,\n} CmaskMode;\ntypedef enum QuadExportFormat {\n\tEXPORT_UNUSED                                    = 0x0,\n\tEXPORT_32_R                                      = 0x1,\n\tEXPORT_32_GR                                     = 0x2,\n\tEXPORT_32_AR                                     = 0x3,\n\tEXPORT_FP16_ABGR                                 = 0x4,\n\tEXPORT_UNSIGNED16_ABGR                           = 0x5,\n\tEXPORT_SIGNED16_ABGR                             = 0x6,\n\tEXPORT_32_ABGR                                   = 0x7,\n} QuadExportFormat;\ntypedef enum QuadExportFormatOld {\n\tEXPORT_4P_32BPC_ABGR                             = 0x0,\n\tEXPORT_4P_16BPC_ABGR                             = 0x1,\n\tEXPORT_4P_32BPC_GR                               = 0x2,\n\tEXPORT_4P_32BPC_AR                               = 0x3,\n\tEXPORT_2P_32BPC_ABGR                             = 0x4,\n\tEXPORT_8P_32BPC_R                                = 0x5,\n} QuadExportFormatOld;\ntypedef enum ColorFormat {\n\tCOLOR_INVALID                                    = 0x0,\n\tCOLOR_8                                          = 0x1,\n\tCOLOR_16                                         = 0x2,\n\tCOLOR_8_8                                        = 0x3,\n\tCOLOR_32                                         = 0x4,\n\tCOLOR_16_16                                      = 0x5,\n\tCOLOR_10_11_11                                   = 0x6,\n\tCOLOR_11_11_10                                   = 0x7,\n\tCOLOR_10_10_10_2                                 = 0x8,\n\tCOLOR_2_10_10_10                                 = 0x9,\n\tCOLOR_8_8_8_8                                    = 0xa,\n\tCOLOR_32_32                                      = 0xb,\n\tCOLOR_16_16_16_16                                = 0xc,\n\tCOLOR_RESERVED_13                                = 0xd,\n\tCOLOR_32_32_32_32                                = 0xe,\n\tCOLOR_RESERVED_15                                = 0xf,\n\tCOLOR_5_6_5                                      = 0x10,\n\tCOLOR_1_5_5_5                                    = 0x11,\n\tCOLOR_5_5_5_1                                    = 0x12,\n\tCOLOR_4_4_4_4                                    = 0x13,\n\tCOLOR_8_24                                       = 0x14,\n\tCOLOR_24_8                                       = 0x15,\n\tCOLOR_X24_8_32_FLOAT                             = 0x16,\n\tCOLOR_RESERVED_23                                = 0x17,\n} ColorFormat;\ntypedef enum SurfaceFormat {\n\tFMT_INVALID                                      = 0x0,\n\tFMT_8                                            = 0x1,\n\tFMT_16                                           = 0x2,\n\tFMT_8_8                                          = 0x3,\n\tFMT_32                                           = 0x4,\n\tFMT_16_16                                        = 0x5,\n\tFMT_10_11_11                                     = 0x6,\n\tFMT_11_11_10                                     = 0x7,\n\tFMT_10_10_10_2                                   = 0x8,\n\tFMT_2_10_10_10                                   = 0x9,\n\tFMT_8_8_8_8                                      = 0xa,\n\tFMT_32_32                                        = 0xb,\n\tFMT_16_16_16_16                                  = 0xc,\n\tFMT_32_32_32                                     = 0xd,\n\tFMT_32_32_32_32                                  = 0xe,\n\tFMT_RESERVED_4                                   = 0xf,\n\tFMT_5_6_5                                        = 0x10,\n\tFMT_1_5_5_5                                      = 0x11,\n\tFMT_5_5_5_1                                      = 0x12,\n\tFMT_4_4_4_4                                      = 0x13,\n\tFMT_8_24                                         = 0x14,\n\tFMT_24_8                                         = 0x15,\n\tFMT_X24_8_32_FLOAT                               = 0x16,\n\tFMT_RESERVED_33                                  = 0x17,\n\tFMT_11_11_10_FLOAT                               = 0x18,\n\tFMT_16_FLOAT                                     = 0x19,\n\tFMT_32_FLOAT                                     = 0x1a,\n\tFMT_16_16_FLOAT                                  = 0x1b,\n\tFMT_8_24_FLOAT                                   = 0x1c,\n\tFMT_24_8_FLOAT                                   = 0x1d,\n\tFMT_32_32_FLOAT                                  = 0x1e,\n\tFMT_10_11_11_FLOAT                               = 0x1f,\n\tFMT_16_16_16_16_FLOAT                            = 0x20,\n\tFMT_3_3_2                                        = 0x21,\n\tFMT_6_5_5                                        = 0x22,\n\tFMT_32_32_32_32_FLOAT                            = 0x23,\n\tFMT_RESERVED_36                                  = 0x24,\n\tFMT_1                                            = 0x25,\n\tFMT_1_REVERSED                                   = 0x26,\n\tFMT_GB_GR                                        = 0x27,\n\tFMT_BG_RG                                        = 0x28,\n\tFMT_32_AS_8                                      = 0x29,\n\tFMT_32_AS_8_8                                    = 0x2a,\n\tFMT_5_9_9_9_SHAREDEXP                            = 0x2b,\n\tFMT_8_8_8                                        = 0x2c,\n\tFMT_16_16_16                                     = 0x2d,\n\tFMT_16_16_16_FLOAT                               = 0x2e,\n\tFMT_4_4                                          = 0x2f,\n\tFMT_32_32_32_FLOAT                               = 0x30,\n\tFMT_BC1                                          = 0x31,\n\tFMT_BC2                                          = 0x32,\n\tFMT_BC3                                          = 0x33,\n\tFMT_BC4                                          = 0x34,\n\tFMT_BC5                                          = 0x35,\n\tFMT_BC6                                          = 0x36,\n\tFMT_BC7                                          = 0x37,\n\tFMT_32_AS_32_32_32_32                            = 0x38,\n\tFMT_APC3                                         = 0x39,\n\tFMT_APC4                                         = 0x3a,\n\tFMT_APC5                                         = 0x3b,\n\tFMT_APC6                                         = 0x3c,\n\tFMT_APC7                                         = 0x3d,\n\tFMT_CTX1                                         = 0x3e,\n\tFMT_RESERVED_63                                  = 0x3f,\n} SurfaceFormat;\ntypedef enum BUF_DATA_FORMAT {\n\tBUF_DATA_FORMAT_INVALID                          = 0x0,\n\tBUF_DATA_FORMAT_8                                = 0x1,\n\tBUF_DATA_FORMAT_16                               = 0x2,\n\tBUF_DATA_FORMAT_8_8                              = 0x3,\n\tBUF_DATA_FORMAT_32                               = 0x4,\n\tBUF_DATA_FORMAT_16_16                            = 0x5,\n\tBUF_DATA_FORMAT_10_11_11                         = 0x6,\n\tBUF_DATA_FORMAT_11_11_10                         = 0x7,\n\tBUF_DATA_FORMAT_10_10_10_2                       = 0x8,\n\tBUF_DATA_FORMAT_2_10_10_10                       = 0x9,\n\tBUF_DATA_FORMAT_8_8_8_8                          = 0xa,\n\tBUF_DATA_FORMAT_32_32                            = 0xb,\n\tBUF_DATA_FORMAT_16_16_16_16                      = 0xc,\n\tBUF_DATA_FORMAT_32_32_32                         = 0xd,\n\tBUF_DATA_FORMAT_32_32_32_32                      = 0xe,\n\tBUF_DATA_FORMAT_RESERVED_15                      = 0xf,\n} BUF_DATA_FORMAT;\ntypedef enum IMG_DATA_FORMAT {\n\tIMG_DATA_FORMAT_INVALID                          = 0x0,\n\tIMG_DATA_FORMAT_8                                = 0x1,\n\tIMG_DATA_FORMAT_16                               = 0x2,\n\tIMG_DATA_FORMAT_8_8                              = 0x3,\n\tIMG_DATA_FORMAT_32                               = 0x4,\n\tIMG_DATA_FORMAT_16_16                            = 0x5,\n\tIMG_DATA_FORMAT_10_11_11                         = 0x6,\n\tIMG_DATA_FORMAT_11_11_10                         = 0x7,\n\tIMG_DATA_FORMAT_10_10_10_2                       = 0x8,\n\tIMG_DATA_FORMAT_2_10_10_10                       = 0x9,\n\tIMG_DATA_FORMAT_8_8_8_8                          = 0xa,\n\tIMG_DATA_FORMAT_32_32                            = 0xb,\n\tIMG_DATA_FORMAT_16_16_16_16                      = 0xc,\n\tIMG_DATA_FORMAT_32_32_32                         = 0xd,\n\tIMG_DATA_FORMAT_32_32_32_32                      = 0xe,\n\tIMG_DATA_FORMAT_RESERVED_15                      = 0xf,\n\tIMG_DATA_FORMAT_5_6_5                            = 0x10,\n\tIMG_DATA_FORMAT_1_5_5_5                          = 0x11,\n\tIMG_DATA_FORMAT_5_5_5_1                          = 0x12,\n\tIMG_DATA_FORMAT_4_4_4_4                          = 0x13,\n\tIMG_DATA_FORMAT_8_24                             = 0x14,\n\tIMG_DATA_FORMAT_24_8                             = 0x15,\n\tIMG_DATA_FORMAT_X24_8_32                         = 0x16,\n\tIMG_DATA_FORMAT_RESERVED_23                      = 0x17,\n\tIMG_DATA_FORMAT_RESERVED_24                      = 0x18,\n\tIMG_DATA_FORMAT_RESERVED_25                      = 0x19,\n\tIMG_DATA_FORMAT_RESERVED_26                      = 0x1a,\n\tIMG_DATA_FORMAT_RESERVED_27                      = 0x1b,\n\tIMG_DATA_FORMAT_RESERVED_28                      = 0x1c,\n\tIMG_DATA_FORMAT_RESERVED_29                      = 0x1d,\n\tIMG_DATA_FORMAT_RESERVED_30                      = 0x1e,\n\tIMG_DATA_FORMAT_RESERVED_31                      = 0x1f,\n\tIMG_DATA_FORMAT_GB_GR                            = 0x20,\n\tIMG_DATA_FORMAT_BG_RG                            = 0x21,\n\tIMG_DATA_FORMAT_5_9_9_9                          = 0x22,\n\tIMG_DATA_FORMAT_BC1                              = 0x23,\n\tIMG_DATA_FORMAT_BC2                              = 0x24,\n\tIMG_DATA_FORMAT_BC3                              = 0x25,\n\tIMG_DATA_FORMAT_BC4                              = 0x26,\n\tIMG_DATA_FORMAT_BC5                              = 0x27,\n\tIMG_DATA_FORMAT_BC6                              = 0x28,\n\tIMG_DATA_FORMAT_BC7                              = 0x29,\n\tIMG_DATA_FORMAT_RESERVED_42                      = 0x2a,\n\tIMG_DATA_FORMAT_RESERVED_43                      = 0x2b,\n\tIMG_DATA_FORMAT_FMASK8_S2_F1                     = 0x2c,\n\tIMG_DATA_FORMAT_FMASK8_S4_F1                     = 0x2d,\n\tIMG_DATA_FORMAT_FMASK8_S8_F1                     = 0x2e,\n\tIMG_DATA_FORMAT_FMASK8_S2_F2                     = 0x2f,\n\tIMG_DATA_FORMAT_FMASK8_S4_F2                     = 0x30,\n\tIMG_DATA_FORMAT_FMASK8_S4_F4                     = 0x31,\n\tIMG_DATA_FORMAT_FMASK16_S16_F1                   = 0x32,\n\tIMG_DATA_FORMAT_FMASK16_S8_F2                    = 0x33,\n\tIMG_DATA_FORMAT_FMASK32_S16_F2                   = 0x34,\n\tIMG_DATA_FORMAT_FMASK32_S8_F4                    = 0x35,\n\tIMG_DATA_FORMAT_FMASK32_S8_F8                    = 0x36,\n\tIMG_DATA_FORMAT_FMASK64_S16_F4                   = 0x37,\n\tIMG_DATA_FORMAT_FMASK64_S16_F8                   = 0x38,\n\tIMG_DATA_FORMAT_4_4                              = 0x39,\n\tIMG_DATA_FORMAT_6_5_5                            = 0x3a,\n\tIMG_DATA_FORMAT_1                                = 0x3b,\n\tIMG_DATA_FORMAT_1_REVERSED                       = 0x3c,\n\tIMG_DATA_FORMAT_32_AS_8                          = 0x3d,\n\tIMG_DATA_FORMAT_32_AS_8_8                        = 0x3e,\n\tIMG_DATA_FORMAT_32_AS_32_32_32_32                = 0x3f,\n} IMG_DATA_FORMAT;\ntypedef enum BUF_NUM_FORMAT {\n\tBUF_NUM_FORMAT_UNORM                             = 0x0,\n\tBUF_NUM_FORMAT_SNORM                             = 0x1,\n\tBUF_NUM_FORMAT_USCALED                           = 0x2,\n\tBUF_NUM_FORMAT_SSCALED                           = 0x3,\n\tBUF_NUM_FORMAT_UINT                              = 0x4,\n\tBUF_NUM_FORMAT_SINT                              = 0x5,\n\tBUF_NUM_FORMAT_SNORM_OGL                         = 0x6,\n\tBUF_NUM_FORMAT_FLOAT                             = 0x7,\n} BUF_NUM_FORMAT;\ntypedef enum IMG_NUM_FORMAT {\n\tIMG_NUM_FORMAT_UNORM                             = 0x0,\n\tIMG_NUM_FORMAT_SNORM                             = 0x1,\n\tIMG_NUM_FORMAT_USCALED                           = 0x2,\n\tIMG_NUM_FORMAT_SSCALED                           = 0x3,\n\tIMG_NUM_FORMAT_UINT                              = 0x4,\n\tIMG_NUM_FORMAT_SINT                              = 0x5,\n\tIMG_NUM_FORMAT_SNORM_OGL                         = 0x6,\n\tIMG_NUM_FORMAT_FLOAT                             = 0x7,\n\tIMG_NUM_FORMAT_RESERVED_8                        = 0x8,\n\tIMG_NUM_FORMAT_SRGB                              = 0x9,\n\tIMG_NUM_FORMAT_UBNORM                            = 0xa,\n\tIMG_NUM_FORMAT_UBNORM_OGL                        = 0xb,\n\tIMG_NUM_FORMAT_UBINT                             = 0xc,\n\tIMG_NUM_FORMAT_UBSCALED                          = 0xd,\n\tIMG_NUM_FORMAT_RESERVED_14                       = 0xe,\n\tIMG_NUM_FORMAT_RESERVED_15                       = 0xf,\n} IMG_NUM_FORMAT;\ntypedef enum TileType {\n\tARRAY_COLOR_TILE                                 = 0x0,\n\tARRAY_DEPTH_TILE                                 = 0x1,\n} TileType;\ntypedef enum NonDispTilingOrder {\n\tADDR_SURF_MICRO_TILING_DISPLAY                   = 0x0,\n\tADDR_SURF_MICRO_TILING_NON_DISPLAY               = 0x1,\n} NonDispTilingOrder;\ntypedef enum MicroTileMode {\n\tADDR_SURF_DISPLAY_MICRO_TILING                   = 0x0,\n\tADDR_SURF_THIN_MICRO_TILING                      = 0x1,\n\tADDR_SURF_DEPTH_MICRO_TILING                     = 0x2,\n\tADDR_SURF_ROTATED_MICRO_TILING                   = 0x3,\n\tADDR_SURF_THICK_MICRO_TILING                     = 0x4,\n} MicroTileMode;\ntypedef enum TileSplit {\n\tADDR_SURF_TILE_SPLIT_64B                         = 0x0,\n\tADDR_SURF_TILE_SPLIT_128B                        = 0x1,\n\tADDR_SURF_TILE_SPLIT_256B                        = 0x2,\n\tADDR_SURF_TILE_SPLIT_512B                        = 0x3,\n\tADDR_SURF_TILE_SPLIT_1KB                         = 0x4,\n\tADDR_SURF_TILE_SPLIT_2KB                         = 0x5,\n\tADDR_SURF_TILE_SPLIT_4KB                         = 0x6,\n} TileSplit;\ntypedef enum SampleSplit {\n\tADDR_SURF_SAMPLE_SPLIT_1                         = 0x0,\n\tADDR_SURF_SAMPLE_SPLIT_2                         = 0x1,\n\tADDR_SURF_SAMPLE_SPLIT_4                         = 0x2,\n\tADDR_SURF_SAMPLE_SPLIT_8                         = 0x3,\n} SampleSplit;\ntypedef enum PipeConfig {\n\tADDR_SURF_P2                                     = 0x0,\n\tADDR_SURF_P2_RESERVED0                           = 0x1,\n\tADDR_SURF_P2_RESERVED1                           = 0x2,\n\tADDR_SURF_P2_RESERVED2                           = 0x3,\n\tADDR_SURF_P4_8x16                                = 0x4,\n\tADDR_SURF_P4_16x16                               = 0x5,\n\tADDR_SURF_P4_16x32                               = 0x6,\n\tADDR_SURF_P4_32x32                               = 0x7,\n\tADDR_SURF_P8_16x16_8x16                          = 0x8,\n\tADDR_SURF_P8_16x32_8x16                          = 0x9,\n\tADDR_SURF_P8_32x32_8x16                          = 0xa,\n\tADDR_SURF_P8_16x32_16x16                         = 0xb,\n\tADDR_SURF_P8_32x32_16x16                         = 0xc,\n\tADDR_SURF_P8_32x32_16x32                         = 0xd,\n\tADDR_SURF_P8_32x64_32x32                         = 0xe,\n\tADDR_SURF_P8_RESERVED0                           = 0xf,\n\tADDR_SURF_P16_32x32_8x16                         = 0x10,\n\tADDR_SURF_P16_32x32_16x16                        = 0x11,\n} PipeConfig;\ntypedef enum NumBanks {\n\tADDR_SURF_2_BANK                                 = 0x0,\n\tADDR_SURF_4_BANK                                 = 0x1,\n\tADDR_SURF_8_BANK                                 = 0x2,\n\tADDR_SURF_16_BANK                                = 0x3,\n} NumBanks;\ntypedef enum BankWidth {\n\tADDR_SURF_BANK_WIDTH_1                           = 0x0,\n\tADDR_SURF_BANK_WIDTH_2                           = 0x1,\n\tADDR_SURF_BANK_WIDTH_4                           = 0x2,\n\tADDR_SURF_BANK_WIDTH_8                           = 0x3,\n} BankWidth;\ntypedef enum BankHeight {\n\tADDR_SURF_BANK_HEIGHT_1                          = 0x0,\n\tADDR_SURF_BANK_HEIGHT_2                          = 0x1,\n\tADDR_SURF_BANK_HEIGHT_4                          = 0x2,\n\tADDR_SURF_BANK_HEIGHT_8                          = 0x3,\n} BankHeight;\ntypedef enum BankWidthHeight {\n\tADDR_SURF_BANK_WH_1                              = 0x0,\n\tADDR_SURF_BANK_WH_2                              = 0x1,\n\tADDR_SURF_BANK_WH_4                              = 0x2,\n\tADDR_SURF_BANK_WH_8                              = 0x3,\n} BankWidthHeight;\ntypedef enum MacroTileAspect {\n\tADDR_SURF_MACRO_ASPECT_1                         = 0x0,\n\tADDR_SURF_MACRO_ASPECT_2                         = 0x1,\n\tADDR_SURF_MACRO_ASPECT_4                         = 0x2,\n\tADDR_SURF_MACRO_ASPECT_8                         = 0x3,\n} MacroTileAspect;\ntypedef enum TCC_CACHE_POLICIES {\n\tTCC_CACHE_POLICY_LRU                             = 0x0,\n\tTCC_CACHE_POLICY_STREAM                          = 0x1,\n\tTCC_CACHE_POLICY_BYPASS                          = 0x2,\n} TCC_CACHE_POLICIES;\ntypedef enum MTYPE {\n\tMTYPE_NC_NV                                      = 0x0,\n\tMTYPE_NC                                         = 0x1,\n\tMTYPE_CC                                         = 0x2,\n\tMTYPE_UC                                         = 0x3,\n} MTYPE;\ntypedef enum PERFMON_COUNTER_MODE {\n\tPERFMON_COUNTER_MODE_ACCUM                       = 0x0,\n\tPERFMON_COUNTER_MODE_ACTIVE_CYCLES               = 0x1,\n\tPERFMON_COUNTER_MODE_MAX                         = 0x2,\n\tPERFMON_COUNTER_MODE_DIRTY                       = 0x3,\n\tPERFMON_COUNTER_MODE_SAMPLE                      = 0x4,\n\tPERFMON_COUNTER_MODE_CYCLES_SINCE_FIRST_EVENT    = 0x5,\n\tPERFMON_COUNTER_MODE_CYCLES_SINCE_LAST_EVENT     = 0x6,\n\tPERFMON_COUNTER_MODE_CYCLES_GE_HI                = 0x7,\n\tPERFMON_COUNTER_MODE_CYCLES_EQ_HI                = 0x8,\n\tPERFMON_COUNTER_MODE_INACTIVE_CYCLES             = 0x9,\n\tPERFMON_COUNTER_MODE_RESERVED                    = 0xf,\n} PERFMON_COUNTER_MODE;\ntypedef enum PERFMON_SPM_MODE {\n\tPERFMON_SPM_MODE_OFF                             = 0x0,\n\tPERFMON_SPM_MODE_16BIT_CLAMP                     = 0x1,\n\tPERFMON_SPM_MODE_16BIT_NO_CLAMP                  = 0x2,\n\tPERFMON_SPM_MODE_32BIT_CLAMP                     = 0x3,\n\tPERFMON_SPM_MODE_32BIT_NO_CLAMP                  = 0x4,\n\tPERFMON_SPM_MODE_RESERVED_5                      = 0x5,\n\tPERFMON_SPM_MODE_RESERVED_6                      = 0x6,\n\tPERFMON_SPM_MODE_RESERVED_7                      = 0x7,\n\tPERFMON_SPM_MODE_TEST_MODE_0                     = 0x8,\n\tPERFMON_SPM_MODE_TEST_MODE_1                     = 0x9,\n\tPERFMON_SPM_MODE_TEST_MODE_2                     = 0xa,\n} PERFMON_SPM_MODE;\ntypedef enum SurfaceTiling {\n\tARRAY_LINEAR                                     = 0x0,\n\tARRAY_TILED                                      = 0x1,\n} SurfaceTiling;\ntypedef enum SurfaceArray {\n\tARRAY_1D                                         = 0x0,\n\tARRAY_2D                                         = 0x1,\n\tARRAY_3D                                         = 0x2,\n\tARRAY_3D_SLICE                                   = 0x3,\n} SurfaceArray;\ntypedef enum ColorArray {\n\tARRAY_2D_ALT_COLOR                               = 0x0,\n\tARRAY_2D_COLOR                                   = 0x1,\n\tARRAY_3D_SLICE_COLOR                             = 0x3,\n} ColorArray;\ntypedef enum DepthArray {\n\tARRAY_2D_ALT_DEPTH                               = 0x0,\n\tARRAY_2D_DEPTH                                   = 0x1,\n} DepthArray;\n\n#endif /* GFX_7_2_ENUM_H */\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/asic_reg/gfx_7_2_sh_mask.h",
    "content": "/*\n * Copyright (C) 2014  Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included\n * in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef GFX_7_2_SH_MASK_H\n#define GFX_7_2_SH_MASK_H\n\n#define CB_BLEND_RED__BLEND_RED_MASK 0xffffffff\n#define CB_BLEND_RED__BLEND_RED__SHIFT 0x0\n#define CB_BLEND_GREEN__BLEND_GREEN_MASK 0xffffffff\n#define CB_BLEND_GREEN__BLEND_GREEN__SHIFT 0x0\n#define CB_BLEND_BLUE__BLEND_BLUE_MASK 0xffffffff\n#define CB_BLEND_BLUE__BLEND_BLUE__SHIFT 0x0\n#define CB_BLEND_ALPHA__BLEND_ALPHA_MASK 0xffffffff\n#define CB_BLEND_ALPHA__BLEND_ALPHA__SHIFT 0x0\n#define CB_COLOR_CONTROL__DEGAMMA_ENABLE_MASK 0x8\n#define CB_COLOR_CONTROL__DEGAMMA_ENABLE__SHIFT 0x3\n#define CB_COLOR_CONTROL__MODE_MASK 0x70\n#define CB_COLOR_CONTROL__MODE__SHIFT 0x4\n#define CB_COLOR_CONTROL__ROP3_MASK 0xff0000\n#define CB_COLOR_CONTROL__ROP3__SHIFT 0x10\n#define CB_BLEND0_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND0_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND0_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND0_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND0_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND0_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND0_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND0_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND0_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND0_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND0_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND0_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND0_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND0_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND0_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND0_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND0_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND0_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND1_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND1_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND1_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND1_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND1_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND1_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND1_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND1_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND1_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND1_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND1_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND1_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND1_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND1_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND1_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND1_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND1_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND1_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND2_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND2_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND2_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND2_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND2_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND2_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND2_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND2_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND2_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND2_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND2_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND2_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND2_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND2_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND2_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND2_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND2_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND2_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND3_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND3_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND3_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND3_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND3_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND3_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND3_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND3_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND3_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND3_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND3_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND3_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND3_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND3_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND3_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND3_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND3_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND3_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND4_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND4_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND4_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND4_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND4_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND4_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND4_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND4_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND4_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND4_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND4_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND4_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND4_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND4_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND4_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND4_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND4_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND4_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND5_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND5_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND5_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND5_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND5_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND5_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND5_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND5_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND5_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND5_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND5_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND5_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND5_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND5_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND5_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND5_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND5_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND5_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND6_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND6_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND6_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND6_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND6_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND6_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND6_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND6_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND6_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND6_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND6_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND6_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND6_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND6_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND6_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND6_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND6_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND6_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_BLEND7_CONTROL__COLOR_SRCBLEND_MASK 0x1f\n#define CB_BLEND7_CONTROL__COLOR_SRCBLEND__SHIFT 0x0\n#define CB_BLEND7_CONTROL__COLOR_COMB_FCN_MASK 0xe0\n#define CB_BLEND7_CONTROL__COLOR_COMB_FCN__SHIFT 0x5\n#define CB_BLEND7_CONTROL__COLOR_DESTBLEND_MASK 0x1f00\n#define CB_BLEND7_CONTROL__COLOR_DESTBLEND__SHIFT 0x8\n#define CB_BLEND7_CONTROL__ALPHA_SRCBLEND_MASK 0x1f0000\n#define CB_BLEND7_CONTROL__ALPHA_SRCBLEND__SHIFT 0x10\n#define CB_BLEND7_CONTROL__ALPHA_COMB_FCN_MASK 0xe00000\n#define CB_BLEND7_CONTROL__ALPHA_COMB_FCN__SHIFT 0x15\n#define CB_BLEND7_CONTROL__ALPHA_DESTBLEND_MASK 0x1f000000\n#define CB_BLEND7_CONTROL__ALPHA_DESTBLEND__SHIFT 0x18\n#define CB_BLEND7_CONTROL__SEPARATE_ALPHA_BLEND_MASK 0x20000000\n#define CB_BLEND7_CONTROL__SEPARATE_ALPHA_BLEND__SHIFT 0x1d\n#define CB_BLEND7_CONTROL__ENABLE_MASK 0x40000000\n#define CB_BLEND7_CONTROL__ENABLE__SHIFT 0x1e\n#define CB_BLEND7_CONTROL__DISABLE_ROP3_MASK 0x80000000\n#define CB_BLEND7_CONTROL__DISABLE_ROP3__SHIFT 0x1f\n#define CB_COLOR0_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR0_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR1_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR1_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR2_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR2_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR3_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR3_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR4_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR4_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR5_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR5_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR6_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR6_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR7_BASE__BASE_256B_MASK 0xffffffff\n#define CB_COLOR7_BASE__BASE_256B__SHIFT 0x0\n#define CB_COLOR0_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR0_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR0_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR0_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR1_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR1_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR1_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR1_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR2_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR2_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR2_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR2_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR3_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR3_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR3_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR3_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR4_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR4_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR4_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR4_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR5_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR5_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR5_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR5_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR6_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR6_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR6_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR6_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR7_PITCH__TILE_MAX_MASK 0x7ff\n#define CB_COLOR7_PITCH__TILE_MAX__SHIFT 0x0\n#define CB_COLOR7_PITCH__FMASK_TILE_MAX_MASK 0x7ff00000\n#define CB_COLOR7_PITCH__FMASK_TILE_MAX__SHIFT 0x14\n#define CB_COLOR0_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR0_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR1_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR1_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR2_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR2_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR3_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR3_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR4_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR4_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR5_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR5_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR6_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR6_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR7_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR7_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR0_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR0_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR0_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR0_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR1_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR1_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR1_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR1_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR2_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR2_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR2_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR2_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR3_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR3_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR3_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR3_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR4_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR4_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR4_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR4_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR5_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR5_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR5_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR5_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR6_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR6_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR6_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR6_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR7_VIEW__SLICE_START_MASK 0x7ff\n#define CB_COLOR7_VIEW__SLICE_START__SHIFT 0x0\n#define CB_COLOR7_VIEW__SLICE_MAX_MASK 0xffe000\n#define CB_COLOR7_VIEW__SLICE_MAX__SHIFT 0xd\n#define CB_COLOR0_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR0_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR0_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR0_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR0_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR0_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR0_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR0_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR0_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR0_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR0_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR0_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR0_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR0_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR0_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR0_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR0_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR0_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR0_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR0_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR0_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR0_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR0_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR0_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR0_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR0_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR0_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR0_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR0_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR0_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR1_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR1_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR1_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR1_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR1_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR1_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR1_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR1_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR1_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR1_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR1_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR1_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR1_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR1_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR1_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR1_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR1_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR1_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR1_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR1_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR1_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR1_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR1_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR1_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR1_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR1_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR1_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR1_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR1_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR1_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR2_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR2_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR2_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR2_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR2_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR2_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR2_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR2_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR2_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR2_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR2_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR2_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR2_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR2_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR2_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR2_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR2_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR2_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR2_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR2_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR2_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR2_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR2_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR2_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR2_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR2_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR2_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR2_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR2_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR2_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR3_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR3_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR3_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR3_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR3_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR3_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR3_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR3_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR3_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR3_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR3_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR3_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR3_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR3_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR3_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR3_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR3_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR3_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR3_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR3_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR3_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR3_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR3_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR3_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR3_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR3_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR3_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR3_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR3_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR3_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR4_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR4_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR4_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR4_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR4_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR4_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR4_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR4_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR4_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR4_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR4_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR4_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR4_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR4_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR4_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR4_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR4_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR4_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR4_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR4_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR4_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR4_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR4_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR4_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR4_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR4_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR4_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR4_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR4_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR4_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR5_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR5_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR5_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR5_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR5_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR5_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR5_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR5_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR5_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR5_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR5_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR5_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR5_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR5_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR5_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR5_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR5_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR5_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR5_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR5_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR5_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR5_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR5_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR5_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR5_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR5_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR5_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR5_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR5_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR5_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR6_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR6_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR6_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR6_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR6_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR6_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR6_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR6_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR6_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR6_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR6_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR6_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR6_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR6_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR6_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR6_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR6_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR6_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR6_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR6_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR6_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR6_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR6_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR6_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR6_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR6_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR6_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR6_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR6_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR6_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR7_INFO__ENDIAN_MASK 0x3\n#define CB_COLOR7_INFO__ENDIAN__SHIFT 0x0\n#define CB_COLOR7_INFO__FORMAT_MASK 0x7c\n#define CB_COLOR7_INFO__FORMAT__SHIFT 0x2\n#define CB_COLOR7_INFO__LINEAR_GENERAL_MASK 0x80\n#define CB_COLOR7_INFO__LINEAR_GENERAL__SHIFT 0x7\n#define CB_COLOR7_INFO__NUMBER_TYPE_MASK 0x700\n#define CB_COLOR7_INFO__NUMBER_TYPE__SHIFT 0x8\n#define CB_COLOR7_INFO__COMP_SWAP_MASK 0x1800\n#define CB_COLOR7_INFO__COMP_SWAP__SHIFT 0xb\n#define CB_COLOR7_INFO__FAST_CLEAR_MASK 0x2000\n#define CB_COLOR7_INFO__FAST_CLEAR__SHIFT 0xd\n#define CB_COLOR7_INFO__COMPRESSION_MASK 0x4000\n#define CB_COLOR7_INFO__COMPRESSION__SHIFT 0xe\n#define CB_COLOR7_INFO__BLEND_CLAMP_MASK 0x8000\n#define CB_COLOR7_INFO__BLEND_CLAMP__SHIFT 0xf\n#define CB_COLOR7_INFO__BLEND_BYPASS_MASK 0x10000\n#define CB_COLOR7_INFO__BLEND_BYPASS__SHIFT 0x10\n#define CB_COLOR7_INFO__SIMPLE_FLOAT_MASK 0x20000\n#define CB_COLOR7_INFO__SIMPLE_FLOAT__SHIFT 0x11\n#define CB_COLOR7_INFO__ROUND_MODE_MASK 0x40000\n#define CB_COLOR7_INFO__ROUND_MODE__SHIFT 0x12\n#define CB_COLOR7_INFO__CMASK_IS_LINEAR_MASK 0x80000\n#define CB_COLOR7_INFO__CMASK_IS_LINEAR__SHIFT 0x13\n#define CB_COLOR7_INFO__BLEND_OPT_DONT_RD_DST_MASK 0x700000\n#define CB_COLOR7_INFO__BLEND_OPT_DONT_RD_DST__SHIFT 0x14\n#define CB_COLOR7_INFO__BLEND_OPT_DISCARD_PIXEL_MASK 0x3800000\n#define CB_COLOR7_INFO__BLEND_OPT_DISCARD_PIXEL__SHIFT 0x17\n#define CB_COLOR7_INFO__FMASK_COMPRESSION_DISABLE_MASK 0x4000000\n#define CB_COLOR7_INFO__FMASK_COMPRESSION_DISABLE__SHIFT 0x1a\n#define CB_COLOR0_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR0_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR0_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR0_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR0_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR0_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR0_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR0_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR0_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR0_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR0_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR0_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR1_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR1_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR1_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR1_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR1_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR1_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR1_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR1_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR1_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR1_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR1_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR1_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR2_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR2_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR2_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR2_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR2_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR2_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR2_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR2_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR2_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR2_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR2_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR2_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR3_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR3_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR3_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR3_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR3_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR3_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR3_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR3_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR3_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR3_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR3_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR3_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR4_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR4_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR4_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR4_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR4_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR4_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR4_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR4_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR4_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR4_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR4_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR4_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR5_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR5_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR5_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR5_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR5_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR5_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR5_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR5_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR5_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR5_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR5_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR5_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR6_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR6_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR6_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR6_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR6_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR6_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR6_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR6_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR6_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR6_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR6_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR6_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR7_ATTRIB__TILE_MODE_INDEX_MASK 0x1f\n#define CB_COLOR7_ATTRIB__TILE_MODE_INDEX__SHIFT 0x0\n#define CB_COLOR7_ATTRIB__FMASK_TILE_MODE_INDEX_MASK 0x3e0\n#define CB_COLOR7_ATTRIB__FMASK_TILE_MODE_INDEX__SHIFT 0x5\n#define CB_COLOR7_ATTRIB__FMASK_BANK_HEIGHT_MASK 0xc00\n#define CB_COLOR7_ATTRIB__FMASK_BANK_HEIGHT__SHIFT 0xa\n#define CB_COLOR7_ATTRIB__NUM_SAMPLES_MASK 0x7000\n#define CB_COLOR7_ATTRIB__NUM_SAMPLES__SHIFT 0xc\n#define CB_COLOR7_ATTRIB__NUM_FRAGMENTS_MASK 0x18000\n#define CB_COLOR7_ATTRIB__NUM_FRAGMENTS__SHIFT 0xf\n#define CB_COLOR7_ATTRIB__FORCE_DST_ALPHA_1_MASK 0x20000\n#define CB_COLOR7_ATTRIB__FORCE_DST_ALPHA_1__SHIFT 0x11\n#define CB_COLOR0_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR0_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR1_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR1_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR2_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR2_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR3_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR3_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR4_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR4_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR5_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR5_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR6_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR6_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR7_CMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR7_CMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR0_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR0_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR1_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR1_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR2_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR2_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR3_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR3_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR4_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR4_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR5_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR5_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR6_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR6_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR7_CMASK_SLICE__TILE_MAX_MASK 0x3fff\n#define CB_COLOR7_CMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR0_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR0_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR1_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR1_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR2_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR2_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR3_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR3_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR4_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR4_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR5_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR5_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR6_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR6_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR7_FMASK__BASE_256B_MASK 0xffffffff\n#define CB_COLOR7_FMASK__BASE_256B__SHIFT 0x0\n#define CB_COLOR0_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR0_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR1_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR1_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR2_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR2_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR3_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR3_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR4_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR4_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR5_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR5_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR6_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR6_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR7_FMASK_SLICE__TILE_MAX_MASK 0x3fffff\n#define CB_COLOR7_FMASK_SLICE__TILE_MAX__SHIFT 0x0\n#define CB_COLOR0_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR0_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR1_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR1_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR2_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR2_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR3_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR3_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR4_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR4_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR5_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR5_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR6_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR6_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR7_CLEAR_WORD0__CLEAR_WORD0_MASK 0xffffffff\n#define CB_COLOR7_CLEAR_WORD0__CLEAR_WORD0__SHIFT 0x0\n#define CB_COLOR0_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR0_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR1_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR1_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR2_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR2_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR3_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR3_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR4_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR4_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR5_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR5_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR6_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR6_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_COLOR7_CLEAR_WORD1__CLEAR_WORD1_MASK 0xffffffff\n#define CB_COLOR7_CLEAR_WORD1__CLEAR_WORD1__SHIFT 0x0\n#define CB_TARGET_MASK__TARGET0_ENABLE_MASK 0xf\n#define CB_TARGET_MASK__TARGET0_ENABLE__SHIFT 0x0\n#define CB_TARGET_MASK__TARGET1_ENABLE_MASK 0xf0\n#define CB_TARGET_MASK__TARGET1_ENABLE__SHIFT 0x4\n#define CB_TARGET_MASK__TARGET2_ENABLE_MASK 0xf00\n#define CB_TARGET_MASK__TARGET2_ENABLE__SHIFT 0x8\n#define CB_TARGET_MASK__TARGET3_ENABLE_MASK 0xf000\n#define CB_TARGET_MASK__TARGET3_ENABLE__SHIFT 0xc\n#define CB_TARGET_MASK__TARGET4_ENABLE_MASK 0xf0000\n#define CB_TARGET_MASK__TARGET4_ENABLE__SHIFT 0x10\n#define CB_TARGET_MASK__TARGET5_ENABLE_MASK 0xf00000\n#define CB_TARGET_MASK__TARGET5_ENABLE__SHIFT 0x14\n#define CB_TARGET_MASK__TARGET6_ENABLE_MASK 0xf000000\n#define CB_TARGET_MASK__TARGET6_ENABLE__SHIFT 0x18\n#define CB_TARGET_MASK__TARGET7_ENABLE_MASK 0xf0000000\n#define CB_TARGET_MASK__TARGET7_ENABLE__SHIFT 0x1c\n#define CB_SHADER_MASK__OUTPUT0_ENABLE_MASK 0xf\n#define CB_SHADER_MASK__OUTPUT0_ENABLE__SHIFT 0x0\n#define CB_SHADER_MASK__OUTPUT1_ENABLE_MASK 0xf0\n#define CB_SHADER_MASK__OUTPUT1_ENABLE__SHIFT 0x4\n#define CB_SHADER_MASK__OUTPUT2_ENABLE_MASK 0xf00\n#define CB_SHADER_MASK__OUTPUT2_ENABLE__SHIFT 0x8\n#define CB_SHADER_MASK__OUTPUT3_ENABLE_MASK 0xf000\n#define CB_SHADER_MASK__OUTPUT3_ENABLE__SHIFT 0xc\n#define CB_SHADER_MASK__OUTPUT4_ENABLE_MASK 0xf0000\n#define CB_SHADER_MASK__OUTPUT4_ENABLE__SHIFT 0x10\n#define CB_SHADER_MASK__OUTPUT5_ENABLE_MASK 0xf00000\n#define CB_SHADER_MASK__OUTPUT5_ENABLE__SHIFT 0x14\n#define CB_SHADER_MASK__OUTPUT6_ENABLE_MASK 0xf000000\n#define CB_SHADER_MASK__OUTPUT6_ENABLE__SHIFT 0x18\n#define CB_SHADER_MASK__OUTPUT7_ENABLE_MASK 0xf0000000\n#define CB_SHADER_MASK__OUTPUT7_ENABLE__SHIFT 0x1c\n#define CB_HW_CONTROL__CM_CACHE_EVICT_POINT_MASK 0xf\n#define CB_HW_CONTROL__CM_CACHE_EVICT_POINT__SHIFT 0x0\n#define CB_HW_CONTROL__FC_CACHE_EVICT_POINT_MASK 0x3c0\n#define CB_HW_CONTROL__FC_CACHE_EVICT_POINT__SHIFT 0x6\n#define CB_HW_CONTROL__CC_CACHE_EVICT_POINT_MASK 0xf000\n#define CB_HW_CONTROL__CC_CACHE_EVICT_POINT__SHIFT 0xc\n#define CB_HW_CONTROL__ALLOW_MRT_WITH_DUAL_SOURCE_MASK 0x10000\n#define CB_HW_CONTROL__ALLOW_MRT_WITH_DUAL_SOURCE__SHIFT 0x10\n#define CB_HW_CONTROL__DISABLE_INTNORM_LE11BPC_CLAMPING_MASK 0x40000\n#define CB_HW_CONTROL__DISABLE_INTNORM_LE11BPC_CLAMPING__SHIFT 0x12\n#define CB_HW_CONTROL__FORCE_NEEDS_DST_MASK 0x80000\n#define CB_HW_CONTROL__FORCE_NEEDS_DST__SHIFT 0x13\n#define CB_HW_CONTROL__FORCE_ALWAYS_TOGGLE_MASK 0x100000\n#define CB_HW_CONTROL__FORCE_ALWAYS_TOGGLE__SHIFT 0x14\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_RESULT_EQ_DEST_MASK 0x200000\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_RESULT_EQ_DEST__SHIFT 0x15\n#define CB_HW_CONTROL__DISABLE_FULL_WRITE_MASK_MASK 0x400000\n#define CB_HW_CONTROL__DISABLE_FULL_WRITE_MASK__SHIFT 0x16\n#define CB_HW_CONTROL__DISABLE_RESOLVE_OPT_FOR_SINGLE_FRAG_MASK 0x800000\n#define CB_HW_CONTROL__DISABLE_RESOLVE_OPT_FOR_SINGLE_FRAG__SHIFT 0x17\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_DONT_RD_DST_MASK 0x1000000\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_DONT_RD_DST__SHIFT 0x18\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_BYPASS_MASK 0x2000000\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_BYPASS__SHIFT 0x19\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_DISCARD_PIXEL_MASK 0x4000000\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_DISCARD_PIXEL__SHIFT 0x1a\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_WHEN_DISABLED_SRCALPHA_IS_USED_MASK 0x8000000\n#define CB_HW_CONTROL__DISABLE_BLEND_OPT_WHEN_DISABLED_SRCALPHA_IS_USED__SHIFT 0x1b\n#define CB_HW_CONTROL__PRIORITIZE_FC_WR_OVER_FC_RD_ON_CMASK_CONFLICT_MASK 0x10000000\n#define CB_HW_CONTROL__PRIORITIZE_FC_WR_OVER_FC_RD_ON_CMASK_CONFLICT__SHIFT 0x1c\n#define CB_HW_CONTROL__PRIORITIZE_FC_EVICT_OVER_FOP_RD_ON_BANK_CONFLICT_MASK 0x20000000\n#define CB_HW_CONTROL__PRIORITIZE_FC_EVICT_OVER_FOP_RD_ON_BANK_CONFLICT__SHIFT 0x1d\n#define CB_HW_CONTROL__DISABLE_CC_IB_SERIALIZER_STATE_OPT_MASK 0x40000000\n#define CB_HW_CONTROL__DISABLE_CC_IB_SERIALIZER_STATE_OPT__SHIFT 0x1e\n#define CB_HW_CONTROL__DISABLE_PIXEL_IN_QUAD_FIX_FOR_LINEAR_SURFACE_MASK 0x80000000\n#define CB_HW_CONTROL__DISABLE_PIXEL_IN_QUAD_FIX_FOR_LINEAR_SURFACE__SHIFT 0x1f\n#define CB_HW_CONTROL_1__CM_CACHE_NUM_TAGS_MASK 0x1f\n#define CB_HW_CONTROL_1__CM_CACHE_NUM_TAGS__SHIFT 0x0\n#define CB_HW_CONTROL_1__FC_CACHE_NUM_TAGS_MASK 0x7e0\n#define CB_HW_CONTROL_1__FC_CACHE_NUM_TAGS__SHIFT 0x5\n#define CB_HW_CONTROL_1__CC_CACHE_NUM_TAGS_MASK 0x1f800\n#define CB_HW_CONTROL_1__CC_CACHE_NUM_TAGS__SHIFT 0xb\n#define CB_HW_CONTROL_1__CM_TILE_FIFO_DEPTH_MASK 0x3fe0000\n#define CB_HW_CONTROL_1__CM_TILE_FIFO_DEPTH__SHIFT 0x11\n#define CB_HW_CONTROL_1__CHICKEN_BITS_MASK 0xfc000000\n#define CB_HW_CONTROL_1__CHICKEN_BITS__SHIFT 0x1a\n#define CB_HW_CONTROL_2__CC_EVEN_ODD_FIFO_DEPTH_MASK 0xff\n#define CB_HW_CONTROL_2__CC_EVEN_ODD_FIFO_DEPTH__SHIFT 0x0\n#define CB_HW_CONTROL_2__FC_RDLAT_TILE_FIFO_DEPTH_MASK 0x7f00\n#define CB_HW_CONTROL_2__FC_RDLAT_TILE_FIFO_DEPTH__SHIFT 0x8\n#define CB_HW_CONTROL_2__FC_RDLAT_QUAD_FIFO_DEPTH_MASK 0x7f8000\n#define CB_HW_CONTROL_2__FC_RDLAT_QUAD_FIFO_DEPTH__SHIFT 0xf\n#define CB_HW_CONTROL_2__CHICKEN_BITS_MASK 0xff000000\n#define CB_HW_CONTROL_2__CHICKEN_BITS__SHIFT 0x18\n#define CB_HW_CONTROL_3__DISABLE_SLOW_MODE_EMPTY_HALF_QUAD_KILL_MASK 0x1\n#define CB_HW_CONTROL_3__DISABLE_SLOW_MODE_EMPTY_HALF_QUAD_KILL__SHIFT 0x0\n#define CB_PERFCOUNTER_FILTER__OP_FILTER_ENABLE_MASK 0x1\n#define CB_PERFCOUNTER_FILTER__OP_FILTER_ENABLE__SHIFT 0x0\n#define CB_PERFCOUNTER_FILTER__OP_FILTER_SEL_MASK 0xe\n#define CB_PERFCOUNTER_FILTER__OP_FILTER_SEL__SHIFT 0x1\n#define CB_PERFCOUNTER_FILTER__FORMAT_FILTER_ENABLE_MASK 0x10\n#define CB_PERFCOUNTER_FILTER__FORMAT_FILTER_ENABLE__SHIFT 0x4\n#define CB_PERFCOUNTER_FILTER__FORMAT_FILTER_SEL_MASK 0x3e0\n#define CB_PERFCOUNTER_FILTER__FORMAT_FILTER_SEL__SHIFT 0x5\n#define CB_PERFCOUNTER_FILTER__CLEAR_FILTER_ENABLE_MASK 0x400\n#define CB_PERFCOUNTER_FILTER__CLEAR_FILTER_ENABLE__SHIFT 0xa\n#define CB_PERFCOUNTER_FILTER__CLEAR_FILTER_SEL_MASK 0x800\n#define CB_PERFCOUNTER_FILTER__CLEAR_FILTER_SEL__SHIFT 0xb\n#define CB_PERFCOUNTER_FILTER__MRT_FILTER_ENABLE_MASK 0x1000\n#define CB_PERFCOUNTER_FILTER__MRT_FILTER_ENABLE__SHIFT 0xc\n#define CB_PERFCOUNTER_FILTER__MRT_FILTER_SEL_MASK 0xe000\n#define CB_PERFCOUNTER_FILTER__MRT_FILTER_SEL__SHIFT 0xd\n#define CB_PERFCOUNTER_FILTER__NUM_SAMPLES_FILTER_ENABLE_MASK 0x20000\n#define CB_PERFCOUNTER_FILTER__NUM_SAMPLES_FILTER_ENABLE__SHIFT 0x11\n#define CB_PERFCOUNTER_FILTER__NUM_SAMPLES_FILTER_SEL_MASK 0x1c0000\n#define CB_PERFCOUNTER_FILTER__NUM_SAMPLES_FILTER_SEL__SHIFT 0x12\n#define CB_PERFCOUNTER_FILTER__NUM_FRAGMENTS_FILTER_ENABLE_MASK 0x200000\n#define CB_PERFCOUNTER_FILTER__NUM_FRAGMENTS_FILTER_ENABLE__SHIFT 0x15\n#define CB_PERFCOUNTER_FILTER__NUM_FRAGMENTS_FILTER_SEL_MASK 0xc00000\n#define CB_PERFCOUNTER_FILTER__NUM_FRAGMENTS_FILTER_SEL__SHIFT 0x16\n#define CB_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x1ff\n#define CB_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define CB_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0x7fc00\n#define CB_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define CB_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define CB_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define CB_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define CB_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define CB_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define CB_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define CB_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x1ff\n#define CB_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define CB_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0x7fc00\n#define CB_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define CB_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define CB_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define CB_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define CB_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define CB_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x1ff\n#define CB_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define CB_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define CB_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define CB_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x1ff\n#define CB_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define CB_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define CB_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define CB_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x1ff\n#define CB_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define CB_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define CB_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define CB_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CB_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CB_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CB_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CB_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CB_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CB_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CB_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CB_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CB_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CB_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CB_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CB_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CB_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CB_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CB_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CB_CGTT_SCLK_CTRL__ON_DELAY_MASK 0xf\n#define CB_CGTT_SCLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CB_CGTT_SCLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CB_CGTT_SCLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define CB_CGTT_SCLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CB_DEBUG_BUS_13__TILE_INTFC_BUSY_MASK 0x1\n#define CB_DEBUG_BUS_13__TILE_INTFC_BUSY__SHIFT 0x0\n#define CB_DEBUG_BUS_13__MU_BUSY_MASK 0x2\n#define CB_DEBUG_BUS_13__MU_BUSY__SHIFT 0x1\n#define CB_DEBUG_BUS_13__TQ_BUSY_MASK 0x4\n#define CB_DEBUG_BUS_13__TQ_BUSY__SHIFT 0x2\n#define CB_DEBUG_BUS_13__AC_BUSY_MASK 0x8\n#define CB_DEBUG_BUS_13__AC_BUSY__SHIFT 0x3\n#define CB_DEBUG_BUS_13__CRW_BUSY_MASK 0x10\n#define CB_DEBUG_BUS_13__CRW_BUSY__SHIFT 0x4\n#define CB_DEBUG_BUS_13__CACHE_CTRL_BUSY_MASK 0x20\n#define CB_DEBUG_BUS_13__CACHE_CTRL_BUSY__SHIFT 0x5\n#define CB_DEBUG_BUS_13__MC_WR_PENDING_MASK 0x40\n#define CB_DEBUG_BUS_13__MC_WR_PENDING__SHIFT 0x6\n#define CB_DEBUG_BUS_13__FC_WR_PENDING_MASK 0x80\n#define CB_DEBUG_BUS_13__FC_WR_PENDING__SHIFT 0x7\n#define CB_DEBUG_BUS_13__FC_RD_PENDING_MASK 0x100\n#define CB_DEBUG_BUS_13__FC_RD_PENDING__SHIFT 0x8\n#define CB_DEBUG_BUS_13__EVICT_PENDING_MASK 0x200\n#define CB_DEBUG_BUS_13__EVICT_PENDING__SHIFT 0x9\n#define CB_DEBUG_BUS_13__LAST_RD_ARB_WINNER_MASK 0x400\n#define CB_DEBUG_BUS_13__LAST_RD_ARB_WINNER__SHIFT 0xa\n#define CB_DEBUG_BUS_13__MU_STATE_MASK 0x7f800\n#define CB_DEBUG_BUS_13__MU_STATE__SHIFT 0xb\n#define CB_DEBUG_BUS_14__TILE_RETIREMENT_BUSY_MASK 0x1\n#define CB_DEBUG_BUS_14__TILE_RETIREMENT_BUSY__SHIFT 0x0\n#define CB_DEBUG_BUS_14__FOP_BUSY_MASK 0x2\n#define CB_DEBUG_BUS_14__FOP_BUSY__SHIFT 0x1\n#define CB_DEBUG_BUS_14__LAT_BUSY_MASK 0x4\n#define CB_DEBUG_BUS_14__LAT_BUSY__SHIFT 0x2\n#define CB_DEBUG_BUS_14__CACHE_CTL_BUSY_MASK 0x8\n#define CB_DEBUG_BUS_14__CACHE_CTL_BUSY__SHIFT 0x3\n#define CB_DEBUG_BUS_14__ADDR_BUSY_MASK 0x10\n#define CB_DEBUG_BUS_14__ADDR_BUSY__SHIFT 0x4\n#define CB_DEBUG_BUS_14__MERGE_BUSY_MASK 0x20\n#define CB_DEBUG_BUS_14__MERGE_BUSY__SHIFT 0x5\n#define CB_DEBUG_BUS_14__QUAD_BUSY_MASK 0x40\n#define CB_DEBUG_BUS_14__QUAD_BUSY__SHIFT 0x6\n#define CB_DEBUG_BUS_14__TILE_BUSY_MASK 0x80\n#define CB_DEBUG_BUS_14__TILE_BUSY__SHIFT 0x7\n#define CB_DEBUG_BUS_14__CLEAR_BUSY_MASK 0x100\n#define CB_DEBUG_BUS_14__CLEAR_BUSY__SHIFT 0x8\n#define CB_DEBUG_BUS_15__SURF_SYNC_STATE_MASK 0x3\n#define CB_DEBUG_BUS_15__SURF_SYNC_STATE__SHIFT 0x0\n#define CB_DEBUG_BUS_15__SURF_SYNC_START_MASK 0x4\n#define CB_DEBUG_BUS_15__SURF_SYNC_START__SHIFT 0x2\n#define CB_DEBUG_BUS_15__SF_BUSY_MASK 0x8\n#define CB_DEBUG_BUS_15__SF_BUSY__SHIFT 0x3\n#define CB_DEBUG_BUS_15__CS_BUSY_MASK 0x10\n#define CB_DEBUG_BUS_15__CS_BUSY__SHIFT 0x4\n#define CB_DEBUG_BUS_15__RB_BUSY_MASK 0x20\n#define CB_DEBUG_BUS_15__RB_BUSY__SHIFT 0x5\n#define CB_DEBUG_BUS_15__DS_BUSY_MASK 0x40\n#define CB_DEBUG_BUS_15__DS_BUSY__SHIFT 0x6\n#define CB_DEBUG_BUS_15__TB_BUSY_MASK 0x80\n#define CB_DEBUG_BUS_15__TB_BUSY__SHIFT 0x7\n#define CB_DEBUG_BUS_15__IB_BUSY_MASK 0x100\n#define CB_DEBUG_BUS_15__IB_BUSY__SHIFT 0x8\n#define CB_DEBUG_BUS_16__MC_RDREQ_CREDITS_MASK 0x3f\n#define CB_DEBUG_BUS_16__MC_RDREQ_CREDITS__SHIFT 0x0\n#define CB_DEBUG_BUS_16__LAST_RD_GRANT_VEC_MASK 0x3c0\n#define CB_DEBUG_BUS_16__LAST_RD_GRANT_VEC__SHIFT 0x6\n#define CB_DEBUG_BUS_16__MC_WRREQ_CREDITS_MASK 0xfc00\n#define CB_DEBUG_BUS_16__MC_WRREQ_CREDITS__SHIFT 0xa\n#define CB_DEBUG_BUS_16__LAST_WR_GRANT_VEC_MASK 0xf0000\n#define CB_DEBUG_BUS_16__LAST_WR_GRANT_VEC__SHIFT 0x10\n#define CB_DEBUG_BUS_16__CC_WRREQ_FIFO_EMPTY_MASK 0x100000\n#define CB_DEBUG_BUS_16__CC_WRREQ_FIFO_EMPTY__SHIFT 0x14\n#define CB_DEBUG_BUS_16__FC_WRREQ_FIFO_EMPTY_MASK 0x200000\n#define CB_DEBUG_BUS_16__FC_WRREQ_FIFO_EMPTY__SHIFT 0x15\n#define CB_DEBUG_BUS_16__CM_WRREQ_FIFO_EMPTY_MASK 0x400000\n#define CB_DEBUG_BUS_16__CM_WRREQ_FIFO_EMPTY__SHIFT 0x16\n#define CB_DEBUG_BUS_17__CM_BUSY_MASK 0x1\n#define CB_DEBUG_BUS_17__CM_BUSY__SHIFT 0x0\n#define CB_DEBUG_BUS_17__FC_BUSY_MASK 0x2\n#define CB_DEBUG_BUS_17__FC_BUSY__SHIFT 0x1\n#define CB_DEBUG_BUS_17__CC_BUSY_MASK 0x4\n#define CB_DEBUG_BUS_17__CC_BUSY__SHIFT 0x2\n#define CB_DEBUG_BUS_17__BB_BUSY_MASK 0x8\n#define CB_DEBUG_BUS_17__BB_BUSY__SHIFT 0x3\n#define CB_DEBUG_BUS_17__MA_BUSY_MASK 0x10\n#define CB_DEBUG_BUS_17__MA_BUSY__SHIFT 0x4\n#define CB_DEBUG_BUS_17__CORE_SCLK_VLD_MASK 0x20\n#define CB_DEBUG_BUS_17__CORE_SCLK_VLD__SHIFT 0x5\n#define CB_DEBUG_BUS_17__REG_SCLK1_VLD_MASK 0x40\n#define CB_DEBUG_BUS_17__REG_SCLK1_VLD__SHIFT 0x6\n#define CB_DEBUG_BUS_17__REG_SCLK0_VLD_MASK 0x80\n#define CB_DEBUG_BUS_17__REG_SCLK0_VLD__SHIFT 0x7\n#define CB_DEBUG_BUS_18__NOT_USED_MASK 0xffffff\n#define CB_DEBUG_BUS_18__NOT_USED__SHIFT 0x0\n#define CP_DFY_CNTL__POLICY_MASK 0x300\n#define CP_DFY_CNTL__POLICY__SHIFT 0x8\n#define CP_DFY_CNTL__VOL_MASK 0x400\n#define CP_DFY_CNTL__VOL__SHIFT 0xa\n#define CP_DFY_CNTL__ATC_MASK 0x800\n#define CP_DFY_CNTL__ATC__SHIFT 0xb\n#define CP_DFY_STAT__BURST_COUNT_MASK 0xffff\n#define CP_DFY_STAT__BURST_COUNT__SHIFT 0x0\n#define CP_DFY_STAT__TAGS_PENDING_MASK 0xff0000\n#define CP_DFY_STAT__TAGS_PENDING__SHIFT 0x10\n#define CP_DFY_STAT__BUSY_MASK 0x80000000\n#define CP_DFY_STAT__BUSY__SHIFT 0x1f\n#define CP_DFY_ADDR_HI__ADDR_HI_MASK 0xffffffff\n#define CP_DFY_ADDR_HI__ADDR_HI__SHIFT 0x0\n#define CP_DFY_ADDR_LO__ADDR_LO_MASK 0xffffffe0\n#define CP_DFY_ADDR_LO__ADDR_LO__SHIFT 0x5\n#define CP_DFY_DATA_0__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_0__DATA__SHIFT 0x0\n#define CP_DFY_DATA_1__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_1__DATA__SHIFT 0x0\n#define CP_DFY_DATA_2__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_2__DATA__SHIFT 0x0\n#define CP_DFY_DATA_3__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_3__DATA__SHIFT 0x0\n#define CP_DFY_DATA_4__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_4__DATA__SHIFT 0x0\n#define CP_DFY_DATA_5__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_5__DATA__SHIFT 0x0\n#define CP_DFY_DATA_6__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_6__DATA__SHIFT 0x0\n#define CP_DFY_DATA_7__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_7__DATA__SHIFT 0x0\n#define CP_DFY_DATA_8__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_8__DATA__SHIFT 0x0\n#define CP_DFY_DATA_9__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_9__DATA__SHIFT 0x0\n#define CP_DFY_DATA_10__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_10__DATA__SHIFT 0x0\n#define CP_DFY_DATA_11__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_11__DATA__SHIFT 0x0\n#define CP_DFY_DATA_12__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_12__DATA__SHIFT 0x0\n#define CP_DFY_DATA_13__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_13__DATA__SHIFT 0x0\n#define CP_DFY_DATA_14__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_14__DATA__SHIFT 0x0\n#define CP_DFY_DATA_15__DATA_MASK 0xffffffff\n#define CP_DFY_DATA_15__DATA__SHIFT 0x0\n#define CP_RB0_BASE__RB_BASE_MASK 0xffffffff\n#define CP_RB0_BASE__RB_BASE__SHIFT 0x0\n#define CP_RB0_BASE_HI__RB_BASE_HI_MASK 0xff\n#define CP_RB0_BASE_HI__RB_BASE_HI__SHIFT 0x0\n#define CP_RB_BASE__RB_BASE_MASK 0xffffffff\n#define CP_RB_BASE__RB_BASE__SHIFT 0x0\n#define CP_RB1_BASE__RB_BASE_MASK 0xffffffff\n#define CP_RB1_BASE__RB_BASE__SHIFT 0x0\n#define CP_RB1_BASE_HI__RB_BASE_HI_MASK 0xff\n#define CP_RB1_BASE_HI__RB_BASE_HI__SHIFT 0x0\n#define CP_RB2_BASE__RB_BASE_MASK 0xffffffff\n#define CP_RB2_BASE__RB_BASE__SHIFT 0x0\n#define CP_RB0_CNTL__RB_BUFSZ_MASK 0x3f\n#define CP_RB0_CNTL__RB_BUFSZ__SHIFT 0x0\n#define CP_RB0_CNTL__RB_BLKSZ_MASK 0x3f00\n#define CP_RB0_CNTL__RB_BLKSZ__SHIFT 0x8\n#define CP_RB0_CNTL__BUF_SWAP_MASK 0x30000\n#define CP_RB0_CNTL__BUF_SWAP__SHIFT 0x10\n#define CP_RB0_CNTL__MIN_AVAILSZ_MASK 0x300000\n#define CP_RB0_CNTL__MIN_AVAILSZ__SHIFT 0x14\n#define CP_RB0_CNTL__MIN_IB_AVAILSZ_MASK 0xc00000\n#define CP_RB0_CNTL__MIN_IB_AVAILSZ__SHIFT 0x16\n#define CP_RB0_CNTL__CACHE_POLICY_MASK 0x3000000\n#define CP_RB0_CNTL__CACHE_POLICY__SHIFT 0x18\n#define CP_RB0_CNTL__RB_VOLATILE_MASK 0x4000000\n#define CP_RB0_CNTL__RB_VOLATILE__SHIFT 0x1a\n#define CP_RB0_CNTL__RB_NO_UPDATE_MASK 0x8000000\n#define CP_RB0_CNTL__RB_NO_UPDATE__SHIFT 0x1b\n#define CP_RB0_CNTL__RB_RPTR_WR_ENA_MASK 0x80000000\n#define CP_RB0_CNTL__RB_RPTR_WR_ENA__SHIFT 0x1f\n#define CP_RB_CNTL__RB_BUFSZ_MASK 0x3f\n#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0x0\n#define CP_RB_CNTL__RB_BLKSZ_MASK 0x3f00\n#define CP_RB_CNTL__RB_BLKSZ__SHIFT 0x8\n#define CP_RB_CNTL__BUF_SWAP_MASK 0x30000\n#define CP_RB_CNTL__BUF_SWAP__SHIFT 0x10\n#define CP_RB_CNTL__MIN_AVAILSZ_MASK 0x300000\n#define CP_RB_CNTL__MIN_AVAILSZ__SHIFT 0x14\n#define CP_RB_CNTL__MIN_IB_AVAILSZ_MASK 0xc00000\n#define CP_RB_CNTL__MIN_IB_AVAILSZ__SHIFT 0x16\n#define CP_RB_CNTL__CACHE_POLICY_MASK 0x3000000\n#define CP_RB_CNTL__CACHE_POLICY__SHIFT 0x18\n#define CP_RB_CNTL__RB_VOLATILE_MASK 0x4000000\n#define CP_RB_CNTL__RB_VOLATILE__SHIFT 0x1a\n#define CP_RB_CNTL__RB_NO_UPDATE_MASK 0x8000000\n#define CP_RB_CNTL__RB_NO_UPDATE__SHIFT 0x1b\n#define CP_RB_CNTL__RB_RPTR_WR_ENA_MASK 0x80000000\n#define CP_RB_CNTL__RB_RPTR_WR_ENA__SHIFT 0x1f\n#define CP_RB1_CNTL__RB_BUFSZ_MASK 0x3f\n#define CP_RB1_CNTL__RB_BUFSZ__SHIFT 0x0\n#define CP_RB1_CNTL__RB_BLKSZ_MASK 0x3f00\n#define CP_RB1_CNTL__RB_BLKSZ__SHIFT 0x8\n#define CP_RB1_CNTL__MIN_AVAILSZ_MASK 0x300000\n#define CP_RB1_CNTL__MIN_AVAILSZ__SHIFT 0x14\n#define CP_RB1_CNTL__MIN_IB_AVAILSZ_MASK 0xc00000\n#define CP_RB1_CNTL__MIN_IB_AVAILSZ__SHIFT 0x16\n#define CP_RB1_CNTL__CACHE_POLICY_MASK 0x3000000\n#define CP_RB1_CNTL__CACHE_POLICY__SHIFT 0x18\n#define CP_RB1_CNTL__RB_VOLATILE_MASK 0x4000000\n#define CP_RB1_CNTL__RB_VOLATILE__SHIFT 0x1a\n#define CP_RB1_CNTL__RB_NO_UPDATE_MASK 0x8000000\n#define CP_RB1_CNTL__RB_NO_UPDATE__SHIFT 0x1b\n#define CP_RB1_CNTL__RB_RPTR_WR_ENA_MASK 0x80000000\n#define CP_RB1_CNTL__RB_RPTR_WR_ENA__SHIFT 0x1f\n#define CP_RB2_CNTL__RB_BUFSZ_MASK 0x3f\n#define CP_RB2_CNTL__RB_BUFSZ__SHIFT 0x0\n#define CP_RB2_CNTL__RB_BLKSZ_MASK 0x3f00\n#define CP_RB2_CNTL__RB_BLKSZ__SHIFT 0x8\n#define CP_RB2_CNTL__MIN_AVAILSZ_MASK 0x300000\n#define CP_RB2_CNTL__MIN_AVAILSZ__SHIFT 0x14\n#define CP_RB2_CNTL__MIN_IB_AVAILSZ_MASK 0xc00000\n#define CP_RB2_CNTL__MIN_IB_AVAILSZ__SHIFT 0x16\n#define CP_RB2_CNTL__CACHE_POLICY_MASK 0x3000000\n#define CP_RB2_CNTL__CACHE_POLICY__SHIFT 0x18\n#define CP_RB2_CNTL__RB_VOLATILE_MASK 0x4000000\n#define CP_RB2_CNTL__RB_VOLATILE__SHIFT 0x1a\n#define CP_RB2_CNTL__RB_NO_UPDATE_MASK 0x8000000\n#define CP_RB2_CNTL__RB_NO_UPDATE__SHIFT 0x1b\n#define CP_RB2_CNTL__RB_RPTR_WR_ENA_MASK 0x80000000\n#define CP_RB2_CNTL__RB_RPTR_WR_ENA__SHIFT 0x1f\n#define CP_RB_RPTR_WR__RB_RPTR_WR_MASK 0xfffff\n#define CP_RB_RPTR_WR__RB_RPTR_WR__SHIFT 0x0\n#define CP_RB0_RPTR_ADDR__RB_RPTR_SWAP_MASK 0x3\n#define CP_RB0_RPTR_ADDR__RB_RPTR_SWAP__SHIFT 0x0\n#define CP_RB0_RPTR_ADDR__RB_RPTR_ADDR_MASK 0xfffffffc\n#define CP_RB0_RPTR_ADDR__RB_RPTR_ADDR__SHIFT 0x2\n#define CP_RB_RPTR_ADDR__RB_RPTR_SWAP_MASK 0x3\n#define CP_RB_RPTR_ADDR__RB_RPTR_SWAP__SHIFT 0x0\n#define CP_RB_RPTR_ADDR__RB_RPTR_ADDR_MASK 0xfffffffc\n#define CP_RB_RPTR_ADDR__RB_RPTR_ADDR__SHIFT 0x2\n#define CP_RB1_RPTR_ADDR__RB_RPTR_SWAP_MASK 0x3\n#define CP_RB1_RPTR_ADDR__RB_RPTR_SWAP__SHIFT 0x0\n#define CP_RB1_RPTR_ADDR__RB_RPTR_ADDR_MASK 0xfffffffc\n#define CP_RB1_RPTR_ADDR__RB_RPTR_ADDR__SHIFT 0x2\n#define CP_RB2_RPTR_ADDR__RB_RPTR_SWAP_MASK 0x3\n#define CP_RB2_RPTR_ADDR__RB_RPTR_SWAP__SHIFT 0x0\n#define CP_RB2_RPTR_ADDR__RB_RPTR_ADDR_MASK 0xfffffffc\n#define CP_RB2_RPTR_ADDR__RB_RPTR_ADDR__SHIFT 0x2\n#define CP_RB0_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK 0xffff\n#define CP_RB0_RPTR_ADDR_HI__RB_RPTR_ADDR_HI__SHIFT 0x0\n#define CP_RB_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK 0xffff\n#define CP_RB_RPTR_ADDR_HI__RB_RPTR_ADDR_HI__SHIFT 0x0\n#define CP_RB1_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK 0xffff\n#define CP_RB1_RPTR_ADDR_HI__RB_RPTR_ADDR_HI__SHIFT 0x0\n#define CP_RB2_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK 0xffff\n#define CP_RB2_RPTR_ADDR_HI__RB_RPTR_ADDR_HI__SHIFT 0x0\n#define CP_RB0_WPTR__RB_WPTR_MASK 0xfffff\n#define CP_RB0_WPTR__RB_WPTR__SHIFT 0x0\n#define CP_RB_WPTR__RB_WPTR_MASK 0xfffff\n#define CP_RB_WPTR__RB_WPTR__SHIFT 0x0\n#define CP_RB1_WPTR__RB_WPTR_MASK 0xfffff\n#define CP_RB1_WPTR__RB_WPTR__SHIFT 0x0\n#define CP_RB2_WPTR__RB_WPTR_MASK 0xfffff\n#define CP_RB2_WPTR__RB_WPTR__SHIFT 0x0\n#define CP_RB_WPTR_POLL_ADDR_LO__OBSOLETE_MASK 0xfffffffc\n#define CP_RB_WPTR_POLL_ADDR_LO__OBSOLETE__SHIFT 0x2\n#define CP_RB_WPTR_POLL_ADDR_HI__OBSOLETE_MASK 0xff\n#define CP_RB_WPTR_POLL_ADDR_HI__OBSOLETE__SHIFT 0x0\n#define CP_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_INT_CNTL__CNTX_BUSY_INT_ENABLE_MASK 0x80000\n#define CP_INT_CNTL__CNTX_BUSY_INT_ENABLE__SHIFT 0x13\n#define CP_INT_CNTL__CNTX_EMPTY_INT_ENABLE_MASK 0x100000\n#define CP_INT_CNTL__CNTX_EMPTY_INT_ENABLE__SHIFT 0x14\n#define CP_INT_CNTL__PRIV_INSTR_INT_ENABLE_MASK 0x400000\n#define CP_INT_CNTL__PRIV_INSTR_INT_ENABLE__SHIFT 0x16\n#define CP_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_INT_CNTL_RING0__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_INT_CNTL_RING0__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_INT_CNTL_RING0__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_INT_CNTL_RING0__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_INT_CNTL_RING0__CNTX_BUSY_INT_ENABLE_MASK 0x80000\n#define CP_INT_CNTL_RING0__CNTX_BUSY_INT_ENABLE__SHIFT 0x13\n#define CP_INT_CNTL_RING0__CNTX_EMPTY_INT_ENABLE_MASK 0x100000\n#define CP_INT_CNTL_RING0__CNTX_EMPTY_INT_ENABLE__SHIFT 0x14\n#define CP_INT_CNTL_RING0__PRIV_INSTR_INT_ENABLE_MASK 0x400000\n#define CP_INT_CNTL_RING0__PRIV_INSTR_INT_ENABLE__SHIFT 0x16\n#define CP_INT_CNTL_RING0__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_INT_CNTL_RING0__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_INT_CNTL_RING0__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_INT_CNTL_RING0__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_INT_CNTL_RING0__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_INT_CNTL_RING0__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_INT_CNTL_RING0__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_INT_CNTL_RING0__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_INT_CNTL_RING0__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_INT_CNTL_RING0__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_INT_CNTL_RING1__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_INT_CNTL_RING1__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_INT_CNTL_RING1__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_INT_CNTL_RING1__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_INT_CNTL_RING1__CNTX_BUSY_INT_ENABLE_MASK 0x80000\n#define CP_INT_CNTL_RING1__CNTX_BUSY_INT_ENABLE__SHIFT 0x13\n#define CP_INT_CNTL_RING1__CNTX_EMPTY_INT_ENABLE_MASK 0x100000\n#define CP_INT_CNTL_RING1__CNTX_EMPTY_INT_ENABLE__SHIFT 0x14\n#define CP_INT_CNTL_RING1__PRIV_INSTR_INT_ENABLE_MASK 0x400000\n#define CP_INT_CNTL_RING1__PRIV_INSTR_INT_ENABLE__SHIFT 0x16\n#define CP_INT_CNTL_RING1__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_INT_CNTL_RING1__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_INT_CNTL_RING1__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_INT_CNTL_RING1__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_INT_CNTL_RING1__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_INT_CNTL_RING1__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_INT_CNTL_RING1__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_INT_CNTL_RING1__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_INT_CNTL_RING1__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_INT_CNTL_RING1__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_INT_CNTL_RING1__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_INT_CNTL_RING1__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_INT_CNTL_RING1__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_INT_CNTL_RING1__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_INT_CNTL_RING2__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_INT_CNTL_RING2__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_INT_CNTL_RING2__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_INT_CNTL_RING2__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_INT_CNTL_RING2__CNTX_BUSY_INT_ENABLE_MASK 0x80000\n#define CP_INT_CNTL_RING2__CNTX_BUSY_INT_ENABLE__SHIFT 0x13\n#define CP_INT_CNTL_RING2__CNTX_EMPTY_INT_ENABLE_MASK 0x100000\n#define CP_INT_CNTL_RING2__CNTX_EMPTY_INT_ENABLE__SHIFT 0x14\n#define CP_INT_CNTL_RING2__PRIV_INSTR_INT_ENABLE_MASK 0x400000\n#define CP_INT_CNTL_RING2__PRIV_INSTR_INT_ENABLE__SHIFT 0x16\n#define CP_INT_CNTL_RING2__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_INT_CNTL_RING2__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_INT_CNTL_RING2__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_INT_CNTL_RING2__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_INT_CNTL_RING2__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_INT_CNTL_RING2__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_INT_CNTL_RING2__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_INT_CNTL_RING2__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_INT_CNTL_RING2__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_INT_CNTL_RING2__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_INT_CNTL_RING2__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_INT_CNTL_RING2__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_INT_CNTL_RING2__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_INT_CNTL_RING2__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_INT_STATUS__CP_ECC_ERROR_INT_STAT_MASK 0x4000\n#define CP_INT_STATUS__CP_ECC_ERROR_INT_STAT__SHIFT 0xe\n#define CP_INT_STATUS__WRM_POLL_TIMEOUT_INT_STAT_MASK 0x20000\n#define CP_INT_STATUS__WRM_POLL_TIMEOUT_INT_STAT__SHIFT 0x11\n#define CP_INT_STATUS__CNTX_BUSY_INT_STAT_MASK 0x80000\n#define CP_INT_STATUS__CNTX_BUSY_INT_STAT__SHIFT 0x13\n#define CP_INT_STATUS__CNTX_EMPTY_INT_STAT_MASK 0x100000\n#define CP_INT_STATUS__CNTX_EMPTY_INT_STAT__SHIFT 0x14\n#define CP_INT_STATUS__PRIV_INSTR_INT_STAT_MASK 0x400000\n#define CP_INT_STATUS__PRIV_INSTR_INT_STAT__SHIFT 0x16\n#define CP_INT_STATUS__PRIV_REG_INT_STAT_MASK 0x800000\n#define CP_INT_STATUS__PRIV_REG_INT_STAT__SHIFT 0x17\n#define CP_INT_STATUS__OPCODE_ERROR_INT_STAT_MASK 0x1000000\n#define CP_INT_STATUS__OPCODE_ERROR_INT_STAT__SHIFT 0x18\n#define CP_INT_STATUS__TIME_STAMP_INT_STAT_MASK 0x4000000\n#define CP_INT_STATUS__TIME_STAMP_INT_STAT__SHIFT 0x1a\n#define CP_INT_STATUS__RESERVED_BIT_ERROR_INT_STAT_MASK 0x8000000\n#define CP_INT_STATUS__RESERVED_BIT_ERROR_INT_STAT__SHIFT 0x1b\n#define CP_INT_STATUS__GENERIC2_INT_STAT_MASK 0x20000000\n#define CP_INT_STATUS__GENERIC2_INT_STAT__SHIFT 0x1d\n#define CP_INT_STATUS__GENERIC1_INT_STAT_MASK 0x40000000\n#define CP_INT_STATUS__GENERIC1_INT_STAT__SHIFT 0x1e\n#define CP_INT_STATUS__GENERIC0_INT_STAT_MASK 0x80000000\n#define CP_INT_STATUS__GENERIC0_INT_STAT__SHIFT 0x1f\n#define CP_INT_STATUS_RING0__CP_ECC_ERROR_INT_STAT_MASK 0x4000\n#define CP_INT_STATUS_RING0__CP_ECC_ERROR_INT_STAT__SHIFT 0xe\n#define CP_INT_STATUS_RING0__WRM_POLL_TIMEOUT_INT_STAT_MASK 0x20000\n#define CP_INT_STATUS_RING0__WRM_POLL_TIMEOUT_INT_STAT__SHIFT 0x11\n#define CP_INT_STATUS_RING0__CNTX_BUSY_INT_STAT_MASK 0x80000\n#define CP_INT_STATUS_RING0__CNTX_BUSY_INT_STAT__SHIFT 0x13\n#define CP_INT_STATUS_RING0__CNTX_EMPTY_INT_STAT_MASK 0x100000\n#define CP_INT_STATUS_RING0__CNTX_EMPTY_INT_STAT__SHIFT 0x14\n#define CP_INT_STATUS_RING0__PRIV_INSTR_INT_STAT_MASK 0x400000\n#define CP_INT_STATUS_RING0__PRIV_INSTR_INT_STAT__SHIFT 0x16\n#define CP_INT_STATUS_RING0__PRIV_REG_INT_STAT_MASK 0x800000\n#define CP_INT_STATUS_RING0__PRIV_REG_INT_STAT__SHIFT 0x17\n#define CP_INT_STATUS_RING0__OPCODE_ERROR_INT_STAT_MASK 0x1000000\n#define CP_INT_STATUS_RING0__OPCODE_ERROR_INT_STAT__SHIFT 0x18\n#define CP_INT_STATUS_RING0__TIME_STAMP_INT_STAT_MASK 0x4000000\n#define CP_INT_STATUS_RING0__TIME_STAMP_INT_STAT__SHIFT 0x1a\n#define CP_INT_STATUS_RING0__RESERVED_BIT_ERROR_INT_STAT_MASK 0x8000000\n#define CP_INT_STATUS_RING0__RESERVED_BIT_ERROR_INT_STAT__SHIFT 0x1b\n#define CP_INT_STATUS_RING0__GENERIC2_INT_STAT_MASK 0x20000000\n#define CP_INT_STATUS_RING0__GENERIC2_INT_STAT__SHIFT 0x1d\n#define CP_INT_STATUS_RING0__GENERIC1_INT_STAT_MASK 0x40000000\n#define CP_INT_STATUS_RING0__GENERIC1_INT_STAT__SHIFT 0x1e\n#define CP_INT_STATUS_RING0__GENERIC0_INT_STAT_MASK 0x80000000\n#define CP_INT_STATUS_RING0__GENERIC0_INT_STAT__SHIFT 0x1f\n#define CP_INT_STATUS_RING1__CP_ECC_ERROR_INT_STAT_MASK 0x4000\n#define CP_INT_STATUS_RING1__CP_ECC_ERROR_INT_STAT__SHIFT 0xe\n#define CP_INT_STATUS_RING1__WRM_POLL_TIMEOUT_INT_STAT_MASK 0x20000\n#define CP_INT_STATUS_RING1__WRM_POLL_TIMEOUT_INT_STAT__SHIFT 0x11\n#define CP_INT_STATUS_RING1__CNTX_BUSY_INT_STAT_MASK 0x80000\n#define CP_INT_STATUS_RING1__CNTX_BUSY_INT_STAT__SHIFT 0x13\n#define CP_INT_STATUS_RING1__CNTX_EMPTY_INT_STAT_MASK 0x100000\n#define CP_INT_STATUS_RING1__CNTX_EMPTY_INT_STAT__SHIFT 0x14\n#define CP_INT_STATUS_RING1__PRIV_INSTR_INT_STAT_MASK 0x400000\n#define CP_INT_STATUS_RING1__PRIV_INSTR_INT_STAT__SHIFT 0x16\n#define CP_INT_STATUS_RING1__PRIV_REG_INT_STAT_MASK 0x800000\n#define CP_INT_STATUS_RING1__PRIV_REG_INT_STAT__SHIFT 0x17\n#define CP_INT_STATUS_RING1__OPCODE_ERROR_INT_STAT_MASK 0x1000000\n#define CP_INT_STATUS_RING1__OPCODE_ERROR_INT_STAT__SHIFT 0x18\n#define CP_INT_STATUS_RING1__TIME_STAMP_INT_STAT_MASK 0x4000000\n#define CP_INT_STATUS_RING1__TIME_STAMP_INT_STAT__SHIFT 0x1a\n#define CP_INT_STATUS_RING1__RESERVED_BIT_ERROR_INT_STAT_MASK 0x8000000\n#define CP_INT_STATUS_RING1__RESERVED_BIT_ERROR_INT_STAT__SHIFT 0x1b\n#define CP_INT_STATUS_RING1__GENERIC2_INT_STAT_MASK 0x20000000\n#define CP_INT_STATUS_RING1__GENERIC2_INT_STAT__SHIFT 0x1d\n#define CP_INT_STATUS_RING1__GENERIC1_INT_STAT_MASK 0x40000000\n#define CP_INT_STATUS_RING1__GENERIC1_INT_STAT__SHIFT 0x1e\n#define CP_INT_STATUS_RING1__GENERIC0_INT_STAT_MASK 0x80000000\n#define CP_INT_STATUS_RING1__GENERIC0_INT_STAT__SHIFT 0x1f\n#define CP_INT_STATUS_RING2__CP_ECC_ERROR_INT_STAT_MASK 0x4000\n#define CP_INT_STATUS_RING2__CP_ECC_ERROR_INT_STAT__SHIFT 0xe\n#define CP_INT_STATUS_RING2__WRM_POLL_TIMEOUT_INT_STAT_MASK 0x20000\n#define CP_INT_STATUS_RING2__WRM_POLL_TIMEOUT_INT_STAT__SHIFT 0x11\n#define CP_INT_STATUS_RING2__CNTX_BUSY_INT_STAT_MASK 0x80000\n#define CP_INT_STATUS_RING2__CNTX_BUSY_INT_STAT__SHIFT 0x13\n#define CP_INT_STATUS_RING2__CNTX_EMPTY_INT_STAT_MASK 0x100000\n#define CP_INT_STATUS_RING2__CNTX_EMPTY_INT_STAT__SHIFT 0x14\n#define CP_INT_STATUS_RING2__PRIV_INSTR_INT_STAT_MASK 0x400000\n#define CP_INT_STATUS_RING2__PRIV_INSTR_INT_STAT__SHIFT 0x16\n#define CP_INT_STATUS_RING2__PRIV_REG_INT_STAT_MASK 0x800000\n#define CP_INT_STATUS_RING2__PRIV_REG_INT_STAT__SHIFT 0x17\n#define CP_INT_STATUS_RING2__OPCODE_ERROR_INT_STAT_MASK 0x1000000\n#define CP_INT_STATUS_RING2__OPCODE_ERROR_INT_STAT__SHIFT 0x18\n#define CP_INT_STATUS_RING2__TIME_STAMP_INT_STAT_MASK 0x4000000\n#define CP_INT_STATUS_RING2__TIME_STAMP_INT_STAT__SHIFT 0x1a\n#define CP_INT_STATUS_RING2__RESERVED_BIT_ERROR_INT_STAT_MASK 0x8000000\n#define CP_INT_STATUS_RING2__RESERVED_BIT_ERROR_INT_STAT__SHIFT 0x1b\n#define CP_INT_STATUS_RING2__GENERIC2_INT_STAT_MASK 0x20000000\n#define CP_INT_STATUS_RING2__GENERIC2_INT_STAT__SHIFT 0x1d\n#define CP_INT_STATUS_RING2__GENERIC1_INT_STAT_MASK 0x40000000\n#define CP_INT_STATUS_RING2__GENERIC1_INT_STAT__SHIFT 0x1e\n#define CP_INT_STATUS_RING2__GENERIC0_INT_STAT_MASK 0x80000000\n#define CP_INT_STATUS_RING2__GENERIC0_INT_STAT__SHIFT 0x1f\n#define CP_DEVICE_ID__DEVICE_ID_MASK 0xff\n#define CP_DEVICE_ID__DEVICE_ID__SHIFT 0x0\n#define CP_RING_PRIORITY_CNTS__PRIORITY1_CNT_MASK 0xff\n#define CP_RING_PRIORITY_CNTS__PRIORITY1_CNT__SHIFT 0x0\n#define CP_RING_PRIORITY_CNTS__PRIORITY2A_CNT_MASK 0xff00\n#define CP_RING_PRIORITY_CNTS__PRIORITY2A_CNT__SHIFT 0x8\n#define CP_RING_PRIORITY_CNTS__PRIORITY2B_CNT_MASK 0xff0000\n#define CP_RING_PRIORITY_CNTS__PRIORITY2B_CNT__SHIFT 0x10\n#define CP_RING_PRIORITY_CNTS__PRIORITY3_CNT_MASK 0xff000000\n#define CP_RING_PRIORITY_CNTS__PRIORITY3_CNT__SHIFT 0x18\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY1_CNT_MASK 0xff\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY1_CNT__SHIFT 0x0\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT_MASK 0xff00\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT__SHIFT 0x8\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT_MASK 0xff0000\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT__SHIFT 0x10\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY3_CNT_MASK 0xff000000\n#define CP_ME0_PIPE_PRIORITY_CNTS__PRIORITY3_CNT__SHIFT 0x18\n#define CP_RING0_PRIORITY__PRIORITY_MASK 0x3\n#define CP_RING0_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME0_PIPE0_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME0_PIPE0_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_RING1_PRIORITY__PRIORITY_MASK 0x3\n#define CP_RING1_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME0_PIPE1_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME0_PIPE1_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_RING2_PRIORITY__PRIORITY_MASK 0x3\n#define CP_RING2_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME0_PIPE2_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME0_PIPE2_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ENDIAN_SWAP__ENDIAN_SWAP_MASK 0x3\n#define CP_ENDIAN_SWAP__ENDIAN_SWAP__SHIFT 0x0\n#define CP_RB_VMID__RB0_VMID_MASK 0xf\n#define CP_RB_VMID__RB0_VMID__SHIFT 0x0\n#define CP_RB_VMID__RB1_VMID_MASK 0xf00\n#define CP_RB_VMID__RB1_VMID__SHIFT 0x8\n#define CP_RB_VMID__RB2_VMID_MASK 0xf0000\n#define CP_RB_VMID__RB2_VMID__SHIFT 0x10\n#define CP_ME0_PIPE0_VMID__VMID_MASK 0xf\n#define CP_ME0_PIPE0_VMID__VMID__SHIFT 0x0\n#define CP_ME0_PIPE1_VMID__VMID_MASK 0xf\n#define CP_ME0_PIPE1_VMID__VMID__SHIFT 0x0\n#define CP_PFP_UCODE_ADDR__UCODE_ADDR_MASK 0xfff\n#define CP_PFP_UCODE_ADDR__UCODE_ADDR__SHIFT 0x0\n#define CP_PFP_UCODE_DATA__UCODE_DATA_MASK 0xffffffff\n#define CP_PFP_UCODE_DATA__UCODE_DATA__SHIFT 0x0\n#define CP_ME_RAM_RADDR__ME_RAM_RADDR_MASK 0xfff\n#define CP_ME_RAM_RADDR__ME_RAM_RADDR__SHIFT 0x0\n#define CP_ME_RAM_WADDR__ME_RAM_WADDR_MASK 0xfff\n#define CP_ME_RAM_WADDR__ME_RAM_WADDR__SHIFT 0x0\n#define CP_ME_RAM_DATA__ME_RAM_DATA_MASK 0xffffffff\n#define CP_ME_RAM_DATA__ME_RAM_DATA__SHIFT 0x0\n#define CGTT_CPC_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_CPC_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_CPC_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_CPC_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_CPC_CLK_CTRL__SOFT_OVERRIDE_DYN_MASK 0x40000000\n#define CGTT_CPC_CLK_CTRL__SOFT_OVERRIDE_DYN__SHIFT 0x1e\n#define CGTT_CPC_CLK_CTRL__SOFT_OVERRIDE_REG_MASK 0x80000000\n#define CGTT_CPC_CLK_CTRL__SOFT_OVERRIDE_REG__SHIFT 0x1f\n#define CGTT_CPF_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_CPF_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_CPF_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_CPF_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_CPF_CLK_CTRL__SOFT_OVERRIDE_DYN_MASK 0x40000000\n#define CGTT_CPF_CLK_CTRL__SOFT_OVERRIDE_DYN__SHIFT 0x1e\n#define CGTT_CPF_CLK_CTRL__SOFT_OVERRIDE_REG_MASK 0x80000000\n#define CGTT_CPF_CLK_CTRL__SOFT_OVERRIDE_REG__SHIFT 0x1f\n#define CGTT_CP_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_CP_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_CP_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_CP_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_CP_CLK_CTRL__SOFT_OVERRIDE_DYN_MASK 0x40000000\n#define CGTT_CP_CLK_CTRL__SOFT_OVERRIDE_DYN__SHIFT 0x1e\n#define CGTT_CP_CLK_CTRL__SOFT_OVERRIDE_REG_MASK 0x80000000\n#define CGTT_CP_CLK_CTRL__SOFT_OVERRIDE_REG__SHIFT 0x1f\n#define CP_CE_UCODE_ADDR__UCODE_ADDR_MASK 0xfff\n#define CP_CE_UCODE_ADDR__UCODE_ADDR__SHIFT 0x0\n#define CP_CE_UCODE_DATA__UCODE_DATA_MASK 0xffffffff\n#define CP_CE_UCODE_DATA__UCODE_DATA__SHIFT 0x0\n#define CP_MEC_ME1_UCODE_ADDR__UCODE_ADDR_MASK 0x1fff\n#define CP_MEC_ME1_UCODE_ADDR__UCODE_ADDR__SHIFT 0x0\n#define CP_MEC_ME1_UCODE_DATA__UCODE_DATA_MASK 0xffffffff\n#define CP_MEC_ME1_UCODE_DATA__UCODE_DATA__SHIFT 0x0\n#define CP_MEC_ME2_UCODE_ADDR__UCODE_ADDR_MASK 0x1fff\n#define CP_MEC_ME2_UCODE_ADDR__UCODE_ADDR__SHIFT 0x0\n#define CP_MEC_ME2_UCODE_DATA__UCODE_DATA_MASK 0xffffffff\n#define CP_MEC_ME2_UCODE_DATA__UCODE_DATA__SHIFT 0x0\n#define CP_PFP_F32_INTERRUPT__PRIV_REG_INT_MASK 0x2\n#define CP_PFP_F32_INTERRUPT__PRIV_REG_INT__SHIFT 0x1\n#define CP_MEC1_F32_INTERRUPT__PRIV_REG_INT_MASK 0x2\n#define CP_MEC1_F32_INTERRUPT__PRIV_REG_INT__SHIFT 0x1\n#define CP_MEC2_F32_INTERRUPT__PRIV_REG_INT_MASK 0x2\n#define CP_MEC2_F32_INTERRUPT__PRIV_REG_INT__SHIFT 0x1\n#define CP_PWR_CNTL__GFX_CLK_HALT_MASK 0x1\n#define CP_PWR_CNTL__GFX_CLK_HALT__SHIFT 0x0\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK 0x1\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_EN__SHIFT 0x0\n#define CP_MEM_SLP_CNTL__CP_MEM_DS_EN_MASK 0x2\n#define CP_MEM_SLP_CNTL__CP_MEM_DS_EN__SHIFT 0x1\n#define CP_MEM_SLP_CNTL__RESERVED_MASK 0xfc\n#define CP_MEM_SLP_CNTL__RESERVED__SHIFT 0x2\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_ON_DELAY_MASK 0xff00\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_ON_DELAY__SHIFT 0x8\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_OFF_DELAY_MASK 0xff0000\n#define CP_MEM_SLP_CNTL__CP_MEM_LS_OFF_DELAY__SHIFT 0x10\n#define CP_MEM_SLP_CNTL__RESERVED1_MASK 0xff000000\n#define CP_MEM_SLP_CNTL__RESERVED1__SHIFT 0x18\n#define CP_ECC_FIRSTOCCURRENCE__INTERFACE_MASK 0x3\n#define CP_ECC_FIRSTOCCURRENCE__INTERFACE__SHIFT 0x0\n#define CP_ECC_FIRSTOCCURRENCE__REQUEST_CLIENT_MASK 0xf0\n#define CP_ECC_FIRSTOCCURRENCE__REQUEST_CLIENT__SHIFT 0x4\n#define CP_ECC_FIRSTOCCURRENCE__RING_ID_MASK 0x3c00\n#define CP_ECC_FIRSTOCCURRENCE__RING_ID__SHIFT 0xa\n#define CP_ECC_FIRSTOCCURRENCE__VMID_MASK 0xf0000\n#define CP_ECC_FIRSTOCCURRENCE__VMID__SHIFT 0x10\n#define CP_ECC_FIRSTOCCURRENCE_RING0__INTERFACE_MASK 0x3\n#define CP_ECC_FIRSTOCCURRENCE_RING0__INTERFACE__SHIFT 0x0\n#define CP_ECC_FIRSTOCCURRENCE_RING0__REQUEST_CLIENT_MASK 0xf0\n#define CP_ECC_FIRSTOCCURRENCE_RING0__REQUEST_CLIENT__SHIFT 0x4\n#define CP_ECC_FIRSTOCCURRENCE_RING0__RING_ID_MASK 0x3c00\n#define CP_ECC_FIRSTOCCURRENCE_RING0__RING_ID__SHIFT 0xa\n#define CP_ECC_FIRSTOCCURRENCE_RING0__VMID_MASK 0xf0000\n#define CP_ECC_FIRSTOCCURRENCE_RING0__VMID__SHIFT 0x10\n#define CP_ECC_FIRSTOCCURRENCE_RING1__INTERFACE_MASK 0x3\n#define CP_ECC_FIRSTOCCURRENCE_RING1__INTERFACE__SHIFT 0x0\n#define CP_ECC_FIRSTOCCURRENCE_RING1__REQUEST_CLIENT_MASK 0xf0\n#define CP_ECC_FIRSTOCCURRENCE_RING1__REQUEST_CLIENT__SHIFT 0x4\n#define CP_ECC_FIRSTOCCURRENCE_RING1__RING_ID_MASK 0x3c00\n#define CP_ECC_FIRSTOCCURRENCE_RING1__RING_ID__SHIFT 0xa\n#define CP_ECC_FIRSTOCCURRENCE_RING1__VMID_MASK 0xf0000\n#define CP_ECC_FIRSTOCCURRENCE_RING1__VMID__SHIFT 0x10\n#define CP_ECC_FIRSTOCCURRENCE_RING2__INTERFACE_MASK 0x3\n#define CP_ECC_FIRSTOCCURRENCE_RING2__INTERFACE__SHIFT 0x0\n#define CP_ECC_FIRSTOCCURRENCE_RING2__REQUEST_CLIENT_MASK 0xf0\n#define CP_ECC_FIRSTOCCURRENCE_RING2__REQUEST_CLIENT__SHIFT 0x4\n#define CP_ECC_FIRSTOCCURRENCE_RING2__RING_ID_MASK 0x3c00\n#define CP_ECC_FIRSTOCCURRENCE_RING2__RING_ID__SHIFT 0xa\n#define CP_ECC_FIRSTOCCURRENCE_RING2__VMID_MASK 0xf0000\n#define CP_ECC_FIRSTOCCURRENCE_RING2__VMID__SHIFT 0x10\n#define CP_FETCHER_SOURCE__ME_SRC_MASK 0x1\n#define CP_FETCHER_SOURCE__ME_SRC__SHIFT 0x0\n#define CP_PQ_WPTR_POLL_CNTL__PERIOD_MASK 0xff\n#define CP_PQ_WPTR_POLL_CNTL__PERIOD__SHIFT 0x0\n#define CP_PQ_WPTR_POLL_CNTL__POLL_ACTIVE_MASK 0x40000000\n#define CP_PQ_WPTR_POLL_CNTL__POLL_ACTIVE__SHIFT 0x1e\n#define CP_PQ_WPTR_POLL_CNTL__EN_MASK 0x80000000\n#define CP_PQ_WPTR_POLL_CNTL__EN__SHIFT 0x1f\n#define CP_PQ_WPTR_POLL_CNTL1__QUEUE_MASK_MASK 0xffffffff\n#define CP_PQ_WPTR_POLL_CNTL1__QUEUE_MASK__SHIFT 0x0\n#define CPC_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CPC_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CPC_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CPC_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CPC_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CPC_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CPC_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CPC_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CPC_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CPC_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CPC_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CPC_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CPC_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CPC_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CPC_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CPC_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CPC_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CPC_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CPC_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CPC_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME1_PIPE0_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME1_PIPE0_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME1_PIPE0_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME1_PIPE0_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME1_PIPE0_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME1_PIPE0_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME1_PIPE0_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME1_PIPE0_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME1_PIPE0_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME1_PIPE0_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME1_PIPE0_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME1_PIPE0_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME1_PIPE0_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME1_PIPE0_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME1_PIPE0_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME1_PIPE1_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME1_PIPE1_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME1_PIPE1_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME1_PIPE1_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME1_PIPE1_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME1_PIPE1_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME1_PIPE1_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME1_PIPE1_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME1_PIPE1_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME1_PIPE1_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME1_PIPE1_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME1_PIPE1_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME1_PIPE1_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME1_PIPE1_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME1_PIPE1_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME1_PIPE2_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME1_PIPE2_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME1_PIPE2_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME1_PIPE2_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME1_PIPE2_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME1_PIPE2_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME1_PIPE2_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME1_PIPE2_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME1_PIPE2_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME1_PIPE2_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME1_PIPE2_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME1_PIPE2_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME1_PIPE2_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME1_PIPE2_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME1_PIPE2_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME1_PIPE3_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME1_PIPE3_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME1_PIPE3_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME1_PIPE3_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME1_PIPE3_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME1_PIPE3_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME1_PIPE3_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME1_PIPE3_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME1_PIPE3_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME1_PIPE3_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME1_PIPE3_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME1_PIPE3_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME1_PIPE3_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME1_PIPE3_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME1_PIPE3_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME2_PIPE0_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME2_PIPE0_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME2_PIPE0_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME2_PIPE0_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME2_PIPE0_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME2_PIPE0_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME2_PIPE0_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME2_PIPE0_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME2_PIPE0_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME2_PIPE0_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME2_PIPE0_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME2_PIPE0_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME2_PIPE0_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME2_PIPE0_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME2_PIPE0_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME2_PIPE1_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME2_PIPE1_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME2_PIPE1_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME2_PIPE1_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME2_PIPE1_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME2_PIPE1_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME2_PIPE1_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME2_PIPE1_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME2_PIPE1_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME2_PIPE1_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME2_PIPE1_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME2_PIPE1_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME2_PIPE1_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME2_PIPE1_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME2_PIPE1_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME2_PIPE2_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME2_PIPE2_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME2_PIPE2_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME2_PIPE2_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME2_PIPE2_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME2_PIPE2_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME2_PIPE2_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME2_PIPE2_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME2_PIPE2_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME2_PIPE2_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME2_PIPE2_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME2_PIPE2_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME2_PIPE2_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME2_PIPE2_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME2_PIPE2_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CP_ME2_PIPE3_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE_MASK 0x2000\n#define CP_ME2_PIPE3_INT_CNTL__DEQUEUE_REQUEST_INT_ENABLE__SHIFT 0xd\n#define CP_ME2_PIPE3_INT_CNTL__CP_ECC_ERROR_INT_ENABLE_MASK 0x4000\n#define CP_ME2_PIPE3_INT_CNTL__CP_ECC_ERROR_INT_ENABLE__SHIFT 0xe\n#define CP_ME2_PIPE3_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE_MASK 0x20000\n#define CP_ME2_PIPE3_INT_CNTL__WRM_POLL_TIMEOUT_INT_ENABLE__SHIFT 0x11\n#define CP_ME2_PIPE3_INT_CNTL__PRIV_REG_INT_ENABLE_MASK 0x800000\n#define CP_ME2_PIPE3_INT_CNTL__PRIV_REG_INT_ENABLE__SHIFT 0x17\n#define CP_ME2_PIPE3_INT_CNTL__OPCODE_ERROR_INT_ENABLE_MASK 0x1000000\n#define CP_ME2_PIPE3_INT_CNTL__OPCODE_ERROR_INT_ENABLE__SHIFT 0x18\n#define CP_ME2_PIPE3_INT_CNTL__TIME_STAMP_INT_ENABLE_MASK 0x4000000\n#define CP_ME2_PIPE3_INT_CNTL__TIME_STAMP_INT_ENABLE__SHIFT 0x1a\n#define CP_ME2_PIPE3_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE_MASK 0x8000000\n#define CP_ME2_PIPE3_INT_CNTL__RESERVED_BIT_ERROR_INT_ENABLE__SHIFT 0x1b\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC2_INT_ENABLE_MASK 0x20000000\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC2_INT_ENABLE__SHIFT 0x1d\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC1_INT_ENABLE_MASK 0x40000000\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC1_INT_ENABLE__SHIFT 0x1e\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC0_INT_ENABLE_MASK 0x80000000\n#define CP_ME2_PIPE3_INT_CNTL__GENERIC0_INT_ENABLE__SHIFT 0x1f\n#define CPC_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CPC_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CPC_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CPC_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CPC_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CPC_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CPC_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CPC_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CPC_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CPC_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CPC_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CPC_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CPC_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CPC_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CPC_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CPC_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CPC_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CPC_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CPC_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CPC_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME1_PIPE0_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME1_PIPE0_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME1_PIPE0_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME1_PIPE0_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME1_PIPE0_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME1_PIPE0_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME1_PIPE0_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME1_PIPE0_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME1_PIPE0_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME1_PIPE0_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME1_PIPE0_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME1_PIPE0_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME1_PIPE0_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME1_PIPE0_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME1_PIPE0_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME1_PIPE1_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME1_PIPE1_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME1_PIPE1_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME1_PIPE1_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME1_PIPE1_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME1_PIPE1_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME1_PIPE1_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME1_PIPE1_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME1_PIPE1_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME1_PIPE1_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME1_PIPE1_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME1_PIPE1_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME1_PIPE1_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME1_PIPE1_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME1_PIPE1_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME1_PIPE2_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME1_PIPE2_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME1_PIPE2_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME1_PIPE2_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME1_PIPE2_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME1_PIPE2_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME1_PIPE2_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME1_PIPE2_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME1_PIPE2_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME1_PIPE2_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME1_PIPE2_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME1_PIPE2_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME1_PIPE2_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME1_PIPE2_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME1_PIPE2_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME1_PIPE3_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME1_PIPE3_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME1_PIPE3_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME1_PIPE3_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME1_PIPE3_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME1_PIPE3_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME1_PIPE3_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME1_PIPE3_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME1_PIPE3_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME1_PIPE3_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME1_PIPE3_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME1_PIPE3_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME1_PIPE3_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME1_PIPE3_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME1_PIPE3_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME2_PIPE0_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME2_PIPE0_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME2_PIPE0_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME2_PIPE0_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME2_PIPE0_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME2_PIPE0_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME2_PIPE0_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME2_PIPE0_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME2_PIPE0_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME2_PIPE0_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME2_PIPE0_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME2_PIPE0_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME2_PIPE0_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME2_PIPE0_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME2_PIPE0_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME2_PIPE1_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME2_PIPE1_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME2_PIPE1_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME2_PIPE1_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME2_PIPE1_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME2_PIPE1_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME2_PIPE1_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME2_PIPE1_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME2_PIPE1_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME2_PIPE1_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME2_PIPE1_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME2_PIPE1_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME2_PIPE1_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME2_PIPE1_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME2_PIPE1_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME2_PIPE2_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME2_PIPE2_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME2_PIPE2_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME2_PIPE2_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME2_PIPE2_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME2_PIPE2_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME2_PIPE2_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME2_PIPE2_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME2_PIPE2_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME2_PIPE2_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME2_PIPE2_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME2_PIPE2_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME2_PIPE2_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME2_PIPE2_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME2_PIPE2_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME2_PIPE3_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS_MASK 0x2000\n#define CP_ME2_PIPE3_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd\n#define CP_ME2_PIPE3_INT_STATUS__CP_ECC_ERROR_INT_STATUS_MASK 0x4000\n#define CP_ME2_PIPE3_INT_STATUS__CP_ECC_ERROR_INT_STATUS__SHIFT 0xe\n#define CP_ME2_PIPE3_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS_MASK 0x20000\n#define CP_ME2_PIPE3_INT_STATUS__WRM_POLL_TIMEOUT_INT_STATUS__SHIFT 0x11\n#define CP_ME2_PIPE3_INT_STATUS__PRIV_REG_INT_STATUS_MASK 0x800000\n#define CP_ME2_PIPE3_INT_STATUS__PRIV_REG_INT_STATUS__SHIFT 0x17\n#define CP_ME2_PIPE3_INT_STATUS__OPCODE_ERROR_INT_STATUS_MASK 0x1000000\n#define CP_ME2_PIPE3_INT_STATUS__OPCODE_ERROR_INT_STATUS__SHIFT 0x18\n#define CP_ME2_PIPE3_INT_STATUS__TIME_STAMP_INT_STATUS_MASK 0x4000000\n#define CP_ME2_PIPE3_INT_STATUS__TIME_STAMP_INT_STATUS__SHIFT 0x1a\n#define CP_ME2_PIPE3_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS_MASK 0x8000000\n#define CP_ME2_PIPE3_INT_STATUS__RESERVED_BIT_ERROR_INT_STATUS__SHIFT 0x1b\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC2_INT_STATUS__SHIFT 0x1d\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC1_INT_STATUS__SHIFT 0x1e\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000\n#define CP_ME2_PIPE3_INT_STATUS__GENERIC0_INT_STATUS__SHIFT 0x1f\n#define CP_ME1_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED_MASK 0x2000\n#define CP_ME1_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED__SHIFT 0xd\n#define CP_ME1_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED_MASK 0x4000\n#define CP_ME1_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED__SHIFT 0xe\n#define CP_ME1_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED_MASK 0x20000\n#define CP_ME1_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED__SHIFT 0x11\n#define CP_ME1_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED_MASK 0x800000\n#define CP_ME1_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED__SHIFT 0x17\n#define CP_ME1_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED_MASK 0x1000000\n#define CP_ME1_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED__SHIFT 0x18\n#define CP_ME1_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED_MASK 0x4000000\n#define CP_ME1_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED__SHIFT 0x1a\n#define CP_ME1_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED_MASK 0x8000000\n#define CP_ME1_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED__SHIFT 0x1b\n#define CP_ME1_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED_MASK 0x20000000\n#define CP_ME1_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED__SHIFT 0x1d\n#define CP_ME1_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED_MASK 0x40000000\n#define CP_ME1_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED__SHIFT 0x1e\n#define CP_ME1_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED_MASK 0x80000000\n#define CP_ME1_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED__SHIFT 0x1f\n#define CP_ME2_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED_MASK 0x2000\n#define CP_ME2_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED__SHIFT 0xd\n#define CP_ME2_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED_MASK 0x4000\n#define CP_ME2_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED__SHIFT 0xe\n#define CP_ME2_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED_MASK 0x20000\n#define CP_ME2_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED__SHIFT 0x11\n#define CP_ME2_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED_MASK 0x800000\n#define CP_ME2_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED__SHIFT 0x17\n#define CP_ME2_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED_MASK 0x1000000\n#define CP_ME2_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED__SHIFT 0x18\n#define CP_ME2_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED_MASK 0x4000000\n#define CP_ME2_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED__SHIFT 0x1a\n#define CP_ME2_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED_MASK 0x8000000\n#define CP_ME2_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED__SHIFT 0x1b\n#define CP_ME2_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED_MASK 0x20000000\n#define CP_ME2_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED__SHIFT 0x1d\n#define CP_ME2_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED_MASK 0x40000000\n#define CP_ME2_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED__SHIFT 0x1e\n#define CP_ME2_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED_MASK 0x80000000\n#define CP_ME2_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED__SHIFT 0x1f\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY1_CNT_MASK 0xff\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY1_CNT__SHIFT 0x0\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT_MASK 0xff00\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT__SHIFT 0x8\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT_MASK 0xff0000\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT__SHIFT 0x10\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY3_CNT_MASK 0xff000000\n#define CP_ME1_PIPE_PRIORITY_CNTS__PRIORITY3_CNT__SHIFT 0x18\n#define CP_ME1_PIPE0_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME1_PIPE0_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME1_PIPE1_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME1_PIPE1_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME1_PIPE2_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME1_PIPE2_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME1_PIPE3_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME1_PIPE3_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY1_CNT_MASK 0xff\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY1_CNT__SHIFT 0x0\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT_MASK 0xff00\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY2A_CNT__SHIFT 0x8\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT_MASK 0xff0000\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY2B_CNT__SHIFT 0x10\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY3_CNT_MASK 0xff000000\n#define CP_ME2_PIPE_PRIORITY_CNTS__PRIORITY3_CNT__SHIFT 0x18\n#define CP_ME2_PIPE0_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME2_PIPE0_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME2_PIPE1_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME2_PIPE1_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME2_PIPE2_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME2_PIPE2_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_ME2_PIPE3_PRIORITY__PRIORITY_MASK 0x3\n#define CP_ME2_PIPE3_PRIORITY__PRIORITY__SHIFT 0x0\n#define CP_CE_PRGRM_CNTR_START__IP_START_MASK 0x7ff\n#define CP_CE_PRGRM_CNTR_START__IP_START__SHIFT 0x0\n#define CP_PFP_PRGRM_CNTR_START__IP_START_MASK 0x7ff\n#define CP_PFP_PRGRM_CNTR_START__IP_START__SHIFT 0x0\n#define CP_ME_PRGRM_CNTR_START__IP_START_MASK 0x7ff\n#define CP_ME_PRGRM_CNTR_START__IP_START__SHIFT 0x0\n#define CP_MEC1_PRGRM_CNTR_START__IP_START_MASK 0xfff\n#define CP_MEC1_PRGRM_CNTR_START__IP_START__SHIFT 0x0\n#define CP_MEC2_PRGRM_CNTR_START__IP_START_MASK 0xfff\n#define CP_MEC2_PRGRM_CNTR_START__IP_START__SHIFT 0x0\n#define CP_CE_INTR_ROUTINE_START__IR_START_MASK 0x7ff\n#define CP_CE_INTR_ROUTINE_START__IR_START__SHIFT 0x0\n#define CP_PFP_INTR_ROUTINE_START__IR_START_MASK 0x7ff\n#define CP_PFP_INTR_ROUTINE_START__IR_START__SHIFT 0x0\n#define CP_ME_INTR_ROUTINE_START__IR_START_MASK 0x7ff\n#define CP_ME_INTR_ROUTINE_START__IR_START__SHIFT 0x0\n#define CP_MEC1_INTR_ROUTINE_START__IR_START_MASK 0xfff\n#define CP_MEC1_INTR_ROUTINE_START__IR_START__SHIFT 0x0\n#define CP_MEC2_INTR_ROUTINE_START__IR_START_MASK 0xfff\n#define CP_MEC2_INTR_ROUTINE_START__IR_START__SHIFT 0x0\n#define CP_CONTEXT_CNTL__ME0PIPE0_MAX_WD_CNTX_MASK 0x7\n#define CP_CONTEXT_CNTL__ME0PIPE0_MAX_WD_CNTX__SHIFT 0x0\n#define CP_CONTEXT_CNTL__ME0PIPE0_MAX_PIPE_CNTX_MASK 0x70\n#define CP_CONTEXT_CNTL__ME0PIPE0_MAX_PIPE_CNTX__SHIFT 0x4\n#define CP_CONTEXT_CNTL__ME0PIPE1_MAX_WD_CNTX_MASK 0x70000\n#define CP_CONTEXT_CNTL__ME0PIPE1_MAX_WD_CNTX__SHIFT 0x10\n#define CP_CONTEXT_CNTL__ME0PIPE1_MAX_PIPE_CNTX_MASK 0x700000\n#define CP_CONTEXT_CNTL__ME0PIPE1_MAX_PIPE_CNTX__SHIFT 0x14\n#define CP_MAX_CONTEXT__MAX_CONTEXT_MASK 0x7\n#define CP_MAX_CONTEXT__MAX_CONTEXT__SHIFT 0x0\n#define CP_IQ_WAIT_TIME1__IB_OFFLOAD_MASK 0xff\n#define CP_IQ_WAIT_TIME1__IB_OFFLOAD__SHIFT 0x0\n#define CP_IQ_WAIT_TIME1__ATOMIC_OFFLOAD_MASK 0xff00\n#define CP_IQ_WAIT_TIME1__ATOMIC_OFFLOAD__SHIFT 0x8\n#define CP_IQ_WAIT_TIME1__WRM_OFFLOAD_MASK 0xff0000\n#define CP_IQ_WAIT_TIME1__WRM_OFFLOAD__SHIFT 0x10\n#define CP_IQ_WAIT_TIME1__GWS_MASK 0xff000000\n#define CP_IQ_WAIT_TIME1__GWS__SHIFT 0x18\n#define CP_IQ_WAIT_TIME2__QUE_SLEEP_MASK 0xff\n#define CP_IQ_WAIT_TIME2__QUE_SLEEP__SHIFT 0x0\n#define CP_IQ_WAIT_TIME2__SCH_WAVE_MASK 0xff00\n#define CP_IQ_WAIT_TIME2__SCH_WAVE__SHIFT 0x8\n#define CP_IQ_WAIT_TIME2__SEM_REARM_MASK 0xff0000\n#define CP_IQ_WAIT_TIME2__SEM_REARM__SHIFT 0x10\n#define CP_IQ_WAIT_TIME2__DEQ_RETRY_MASK 0xff000000\n#define CP_IQ_WAIT_TIME2__DEQ_RETRY__SHIFT 0x18\n#define CP_VMID_RESET__RESET_REQUEST_MASK 0xffff\n#define CP_VMID_RESET__RESET_REQUEST__SHIFT 0x0\n#define CP_VMID_RESET__RESET_STATUS_MASK 0xffff0000\n#define CP_VMID_RESET__RESET_STATUS__SHIFT 0x10\n#define CP_VMID_PREEMPT__PREEMPT_REQUEST_MASK 0xffff\n#define CP_VMID_PREEMPT__PREEMPT_REQUEST__SHIFT 0x0\n#define CP_VMID_PREEMPT__PREEMPT_STATUS_MASK 0xffff0000\n#define CP_VMID_PREEMPT__PREEMPT_STATUS__SHIFT 0x10\n#define CPC_INT_CNTX_ID__CNTX_ID_MASK 0xffff\n#define CPC_INT_CNTX_ID__CNTX_ID__SHIFT 0x0\n#define CP_PQ_STATUS__DOORBELL_UPDATED_MASK 0x1\n#define CP_PQ_STATUS__DOORBELL_UPDATED__SHIFT 0x0\n#define CP_PQ_STATUS__DOORBELL_ENABLE_MASK 0x2\n#define CP_PQ_STATUS__DOORBELL_ENABLE__SHIFT 0x1\n#define CP_CPC_STATUS__MEC1_BUSY_MASK 0x1\n#define CP_CPC_STATUS__MEC1_BUSY__SHIFT 0x0\n#define CP_CPC_STATUS__MEC2_BUSY_MASK 0x2\n#define CP_CPC_STATUS__MEC2_BUSY__SHIFT 0x1\n#define CP_CPC_STATUS__DC0_BUSY_MASK 0x4\n#define CP_CPC_STATUS__DC0_BUSY__SHIFT 0x2\n#define CP_CPC_STATUS__DC1_BUSY_MASK 0x8\n#define CP_CPC_STATUS__DC1_BUSY__SHIFT 0x3\n#define CP_CPC_STATUS__RCIU1_BUSY_MASK 0x10\n#define CP_CPC_STATUS__RCIU1_BUSY__SHIFT 0x4\n#define CP_CPC_STATUS__RCIU2_BUSY_MASK 0x20\n#define CP_CPC_STATUS__RCIU2_BUSY__SHIFT 0x5\n#define CP_CPC_STATUS__ROQ1_BUSY_MASK 0x40\n#define CP_CPC_STATUS__ROQ1_BUSY__SHIFT 0x6\n#define CP_CPC_STATUS__ROQ2_BUSY_MASK 0x80\n#define CP_CPC_STATUS__ROQ2_BUSY__SHIFT 0x7\n#define CP_CPC_STATUS__MIU_RDREQ_BUSY_MASK 0x100\n#define CP_CPC_STATUS__MIU_RDREQ_BUSY__SHIFT 0x8\n#define CP_CPC_STATUS__MIU_WRREQ_BUSY_MASK 0x200\n#define CP_CPC_STATUS__MIU_WRREQ_BUSY__SHIFT 0x9\n#define CP_CPC_STATUS__TCIU_BUSY_MASK 0x400\n#define CP_CPC_STATUS__TCIU_BUSY__SHIFT 0xa\n#define CP_CPC_STATUS__SCRATCH_RAM_BUSY_MASK 0x800\n#define CP_CPC_STATUS__SCRATCH_RAM_BUSY__SHIFT 0xb\n#define CP_CPC_STATUS__QU_BUSY_MASK 0x1000\n#define CP_CPC_STATUS__QU_BUSY__SHIFT 0xc\n#define CP_CPC_STATUS__CPG_CPC_BUSY_MASK 0x20000000\n#define CP_CPC_STATUS__CPG_CPC_BUSY__SHIFT 0x1d\n#define CP_CPC_STATUS__CPF_CPC_BUSY_MASK 0x40000000\n#define CP_CPC_STATUS__CPF_CPC_BUSY__SHIFT 0x1e\n#define CP_CPC_STATUS__CPC_BUSY_MASK 0x80000000\n#define CP_CPC_STATUS__CPC_BUSY__SHIFT 0x1f\n#define CP_CPC_BUSY_STAT__MEC1_LOAD_BUSY_MASK 0x1\n#define CP_CPC_BUSY_STAT__MEC1_LOAD_BUSY__SHIFT 0x0\n#define CP_CPC_BUSY_STAT__MEC1_SEMAPOHRE_BUSY_MASK 0x2\n#define CP_CPC_BUSY_STAT__MEC1_SEMAPOHRE_BUSY__SHIFT 0x1\n#define CP_CPC_BUSY_STAT__MEC1_MUTEX_BUSY_MASK 0x4\n#define CP_CPC_BUSY_STAT__MEC1_MUTEX_BUSY__SHIFT 0x2\n#define CP_CPC_BUSY_STAT__MEC1_MESSAGE_BUSY_MASK 0x8\n#define CP_CPC_BUSY_STAT__MEC1_MESSAGE_BUSY__SHIFT 0x3\n#define CP_CPC_BUSY_STAT__MEC1_EOP_QUEUE_BUSY_MASK 0x10\n#define CP_CPC_BUSY_STAT__MEC1_EOP_QUEUE_BUSY__SHIFT 0x4\n#define CP_CPC_BUSY_STAT__MEC1_IQ_QUEUE_BUSY_MASK 0x20\n#define CP_CPC_BUSY_STAT__MEC1_IQ_QUEUE_BUSY__SHIFT 0x5\n#define CP_CPC_BUSY_STAT__MEC1_IB_QUEUE_BUSY_MASK 0x40\n#define CP_CPC_BUSY_STAT__MEC1_IB_QUEUE_BUSY__SHIFT 0x6\n#define CP_CPC_BUSY_STAT__MEC1_TC_BUSY_MASK 0x80\n#define CP_CPC_BUSY_STAT__MEC1_TC_BUSY__SHIFT 0x7\n#define CP_CPC_BUSY_STAT__MEC1_DMA_BUSY_MASK 0x100\n#define CP_CPC_BUSY_STAT__MEC1_DMA_BUSY__SHIFT 0x8\n#define CP_CPC_BUSY_STAT__MEC1_PARTIAL_FLUSH_BUSY_MASK 0x200\n#define CP_CPC_BUSY_STAT__MEC1_PARTIAL_FLUSH_BUSY__SHIFT 0x9\n#define CP_CPC_BUSY_STAT__MEC1_PIPE0_BUSY_MASK 0x400\n#define CP_CPC_BUSY_STAT__MEC1_PIPE0_BUSY__SHIFT 0xa\n#define CP_CPC_BUSY_STAT__MEC1_PIPE1_BUSY_MASK 0x800\n#define CP_CPC_BUSY_STAT__MEC1_PIPE1_BUSY__SHIFT 0xb\n#define CP_CPC_BUSY_STAT__MEC1_PIPE2_BUSY_MASK 0x1000\n#define CP_CPC_BUSY_STAT__MEC1_PIPE2_BUSY__SHIFT 0xc\n#define CP_CPC_BUSY_STAT__MEC1_PIPE3_BUSY_MASK 0x2000\n#define CP_CPC_BUSY_STAT__MEC1_PIPE3_BUSY__SHIFT 0xd\n#define CP_CPC_BUSY_STAT__MEC2_LOAD_BUSY_MASK 0x10000\n#define CP_CPC_BUSY_STAT__MEC2_LOAD_BUSY__SHIFT 0x10\n#define CP_CPC_BUSY_STAT__MEC2_SEMAPOHRE_BUSY_MASK 0x20000\n#define CP_CPC_BUSY_STAT__MEC2_SEMAPOHRE_BUSY__SHIFT 0x11\n#define CP_CPC_BUSY_STAT__MEC2_MUTEX_BUSY_MASK 0x40000\n#define CP_CPC_BUSY_STAT__MEC2_MUTEX_BUSY__SHIFT 0x12\n#define CP_CPC_BUSY_STAT__MEC2_MESSAGE_BUSY_MASK 0x80000\n#define CP_CPC_BUSY_STAT__MEC2_MESSAGE_BUSY__SHIFT 0x13\n#define CP_CPC_BUSY_STAT__MEC2_EOP_QUEUE_BUSY_MASK 0x100000\n#define CP_CPC_BUSY_STAT__MEC2_EOP_QUEUE_BUSY__SHIFT 0x14\n#define CP_CPC_BUSY_STAT__MEC2_IQ_QUEUE_BUSY_MASK 0x200000\n#define CP_CPC_BUSY_STAT__MEC2_IQ_QUEUE_BUSY__SHIFT 0x15\n#define CP_CPC_BUSY_STAT__MEC2_IB_QUEUE_BUSY_MASK 0x400000\n#define CP_CPC_BUSY_STAT__MEC2_IB_QUEUE_BUSY__SHIFT 0x16\n#define CP_CPC_BUSY_STAT__MEC2_TC_BUSY_MASK 0x800000\n#define CP_CPC_BUSY_STAT__MEC2_TC_BUSY__SHIFT 0x17\n#define CP_CPC_BUSY_STAT__MEC2_DMA_BUSY_MASK 0x1000000\n#define CP_CPC_BUSY_STAT__MEC2_DMA_BUSY__SHIFT 0x18\n#define CP_CPC_BUSY_STAT__MEC2_PARTIAL_FLUSH_BUSY_MASK 0x2000000\n#define CP_CPC_BUSY_STAT__MEC2_PARTIAL_FLUSH_BUSY__SHIFT 0x19\n#define CP_CPC_BUSY_STAT__MEC2_PIPE0_BUSY_MASK 0x4000000\n#define CP_CPC_BUSY_STAT__MEC2_PIPE0_BUSY__SHIFT 0x1a\n#define CP_CPC_BUSY_STAT__MEC2_PIPE1_BUSY_MASK 0x8000000\n#define CP_CPC_BUSY_STAT__MEC2_PIPE1_BUSY__SHIFT 0x1b\n#define CP_CPC_BUSY_STAT__MEC2_PIPE2_BUSY_MASK 0x10000000\n#define CP_CPC_BUSY_STAT__MEC2_PIPE2_BUSY__SHIFT 0x1c\n#define CP_CPC_BUSY_STAT__MEC2_PIPE3_BUSY_MASK 0x20000000\n#define CP_CPC_BUSY_STAT__MEC2_PIPE3_BUSY__SHIFT 0x1d\n#define CP_CPC_STALLED_STAT1__MIU_RDREQ_FREE_STALL_MASK 0x1\n#define CP_CPC_STALLED_STAT1__MIU_RDREQ_FREE_STALL__SHIFT 0x0\n#define CP_CPC_STALLED_STAT1__MIU_WRREQ_FREE_STALL_MASK 0x2\n#define CP_CPC_STALLED_STAT1__MIU_WRREQ_FREE_STALL__SHIFT 0x1\n#define CP_CPC_STALLED_STAT1__RCIU_TX_FREE_STALL_MASK 0x8\n#define CP_CPC_STALLED_STAT1__RCIU_TX_FREE_STALL__SHIFT 0x3\n#define CP_CPC_STALLED_STAT1__RCIU_PRIV_VIOLATION_MASK 0x10\n#define CP_CPC_STALLED_STAT1__RCIU_PRIV_VIOLATION__SHIFT 0x4\n#define CP_CPC_STALLED_STAT1__TCIU_TX_FREE_STALL_MASK 0x40\n#define CP_CPC_STALLED_STAT1__TCIU_TX_FREE_STALL__SHIFT 0x6\n#define CP_CPC_STALLED_STAT1__MEC1_DECODING_PACKET_MASK 0x100\n#define CP_CPC_STALLED_STAT1__MEC1_DECODING_PACKET__SHIFT 0x8\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_RCIU_MASK 0x200\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_RCIU__SHIFT 0x9\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_RCIU_READ_MASK 0x400\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_RCIU_READ__SHIFT 0xa\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_MC_READ_MASK 0x800\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_MC_READ__SHIFT 0xb\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_MC_WR_ACK_MASK 0x1000\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_MC_WR_ACK__SHIFT 0xc\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_ROQ_DATA_MASK 0x2000\n#define CP_CPC_STALLED_STAT1__MEC1_WAIT_ON_ROQ_DATA__SHIFT 0xd\n#define CP_CPC_STALLED_STAT1__MEC2_DECODING_PACKET_MASK 0x10000\n#define CP_CPC_STALLED_STAT1__MEC2_DECODING_PACKET__SHIFT 0x10\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_RCIU_MASK 0x20000\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_RCIU__SHIFT 0x11\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_RCIU_READ_MASK 0x40000\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_RCIU_READ__SHIFT 0x12\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_MC_READ_MASK 0x80000\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_MC_READ__SHIFT 0x13\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_MC_WR_ACK_MASK 0x100000\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_MC_WR_ACK__SHIFT 0x14\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_ROQ_DATA_MASK 0x200000\n#define CP_CPC_STALLED_STAT1__MEC2_WAIT_ON_ROQ_DATA__SHIFT 0x15\n#define CP_CPF_STATUS__POST_WPTR_GFX_BUSY_MASK 0x1\n#define CP_CPF_STATUS__POST_WPTR_GFX_BUSY__SHIFT 0x0\n#define CP_CPF_STATUS__CSF_BUSY_MASK 0x2\n#define CP_CPF_STATUS__CSF_BUSY__SHIFT 0x1\n#define CP_CPF_STATUS__MIU_RDREQ_BUSY_MASK 0x4\n#define CP_CPF_STATUS__MIU_RDREQ_BUSY__SHIFT 0x2\n#define CP_CPF_STATUS__MIU_WRREQ_BUSY_MASK 0x8\n#define CP_CPF_STATUS__MIU_WRREQ_BUSY__SHIFT 0x3\n#define CP_CPF_STATUS__ROQ_ALIGN_BUSY_MASK 0x10\n#define CP_CPF_STATUS__ROQ_ALIGN_BUSY__SHIFT 0x4\n#define CP_CPF_STATUS__ROQ_RING_BUSY_MASK 0x20\n#define CP_CPF_STATUS__ROQ_RING_BUSY__SHIFT 0x5\n#define CP_CPF_STATUS__ROQ_INDIRECT1_BUSY_MASK 0x40\n#define CP_CPF_STATUS__ROQ_INDIRECT1_BUSY__SHIFT 0x6\n#define CP_CPF_STATUS__ROQ_INDIRECT2_BUSY_MASK 0x80\n#define CP_CPF_STATUS__ROQ_INDIRECT2_BUSY__SHIFT 0x7\n#define CP_CPF_STATUS__ROQ_STATE_BUSY_MASK 0x100\n#define CP_CPF_STATUS__ROQ_STATE_BUSY__SHIFT 0x8\n#define CP_CPF_STATUS__ROQ_CE_RING_BUSY_MASK 0x200\n#define CP_CPF_STATUS__ROQ_CE_RING_BUSY__SHIFT 0x9\n#define CP_CPF_STATUS__ROQ_CE_INDIRECT1_BUSY_MASK 0x400\n#define CP_CPF_STATUS__ROQ_CE_INDIRECT1_BUSY__SHIFT 0xa\n#define CP_CPF_STATUS__ROQ_CE_INDIRECT2_BUSY_MASK 0x800\n#define CP_CPF_STATUS__ROQ_CE_INDIRECT2_BUSY__SHIFT 0xb\n#define CP_CPF_STATUS__SEMAPHORE_BUSY_MASK 0x1000\n#define CP_CPF_STATUS__SEMAPHORE_BUSY__SHIFT 0xc\n#define CP_CPF_STATUS__INTERRUPT_BUSY_MASK 0x2000\n#define CP_CPF_STATUS__INTERRUPT_BUSY__SHIFT 0xd\n#define CP_CPF_STATUS__TCIU_BUSY_MASK 0x4000\n#define CP_CPF_STATUS__TCIU_BUSY__SHIFT 0xe\n#define CP_CPF_STATUS__HQD_BUSY_MASK 0x8000\n#define CP_CPF_STATUS__HQD_BUSY__SHIFT 0xf\n#define CP_CPF_STATUS__CPC_CPF_BUSY_MASK 0x40000000\n#define CP_CPF_STATUS__CPC_CPF_BUSY__SHIFT 0x1e\n#define CP_CPF_STATUS__CPF_BUSY_MASK 0x80000000\n#define CP_CPF_STATUS__CPF_BUSY__SHIFT 0x1f\n#define CP_CPF_BUSY_STAT__REG_BUS_FIFO_BUSY_MASK 0x1\n#define CP_CPF_BUSY_STAT__REG_BUS_FIFO_BUSY__SHIFT 0x0\n#define CP_CPF_BUSY_STAT__CSF_RING_BUSY_MASK 0x2\n#define CP_CPF_BUSY_STAT__CSF_RING_BUSY__SHIFT 0x1\n#define CP_CPF_BUSY_STAT__CSF_INDIRECT1_BUSY_MASK 0x4\n#define CP_CPF_BUSY_STAT__CSF_INDIRECT1_BUSY__SHIFT 0x2\n#define CP_CPF_BUSY_STAT__CSF_INDIRECT2_BUSY_MASK 0x8\n#define CP_CPF_BUSY_STAT__CSF_INDIRECT2_BUSY__SHIFT 0x3\n#define CP_CPF_BUSY_STAT__CSF_STATE_BUSY_MASK 0x10\n#define CP_CPF_BUSY_STAT__CSF_STATE_BUSY__SHIFT 0x4\n#define CP_CPF_BUSY_STAT__CSF_CE_INDR1_BUSY_MASK 0x20\n#define CP_CPF_BUSY_STAT__CSF_CE_INDR1_BUSY__SHIFT 0x5\n#define CP_CPF_BUSY_STAT__CSF_CE_INDR2_BUSY_MASK 0x40\n#define CP_CPF_BUSY_STAT__CSF_CE_INDR2_BUSY__SHIFT 0x6\n#define CP_CPF_BUSY_STAT__CSF_ARBITER_BUSY_MASK 0x80\n#define CP_CPF_BUSY_STAT__CSF_ARBITER_BUSY__SHIFT 0x7\n#define CP_CPF_BUSY_STAT__CSF_INPUT_BUSY_MASK 0x100\n#define CP_CPF_BUSY_STAT__CSF_INPUT_BUSY__SHIFT 0x8\n#define CP_CPF_BUSY_STAT__OUTSTANDING_READ_TAGS_MASK 0x200\n#define CP_CPF_BUSY_STAT__OUTSTANDING_READ_TAGS__SHIFT 0x9\n#define CP_CPF_BUSY_STAT__HPD_PROCESSING_EOP_BUSY_MASK 0x800\n#define CP_CPF_BUSY_STAT__HPD_PROCESSING_EOP_BUSY__SHIFT 0xb\n#define CP_CPF_BUSY_STAT__HQD_DISPATCH_BUSY_MASK 0x1000\n#define CP_CPF_BUSY_STAT__HQD_DISPATCH_BUSY__SHIFT 0xc\n#define CP_CPF_BUSY_STAT__HQD_IQ_TIMER_BUSY_MASK 0x2000\n#define CP_CPF_BUSY_STAT__HQD_IQ_TIMER_BUSY__SHIFT 0xd\n#define CP_CPF_BUSY_STAT__HQD_DMA_OFFLOAD_BUSY_MASK 0x4000\n#define CP_CPF_BUSY_STAT__HQD_DMA_OFFLOAD_BUSY__SHIFT 0xe\n#define CP_CPF_BUSY_STAT__HQD_WAIT_SEMAPHORE_BUSY_MASK 0x8000\n#define CP_CPF_BUSY_STAT__HQD_WAIT_SEMAPHORE_BUSY__SHIFT 0xf\n#define CP_CPF_BUSY_STAT__HQD_SIGNAL_SEMAPHORE_BUSY_MASK 0x10000\n#define CP_CPF_BUSY_STAT__HQD_SIGNAL_SEMAPHORE_BUSY__SHIFT 0x10\n#define CP_CPF_BUSY_STAT__HQD_MESSAGE_BUSY_MASK 0x20000\n#define CP_CPF_BUSY_STAT__HQD_MESSAGE_BUSY__SHIFT 0x11\n#define CP_CPF_BUSY_STAT__HQD_PQ_FETCHER_BUSY_MASK 0x40000\n#define CP_CPF_BUSY_STAT__HQD_PQ_FETCHER_BUSY__SHIFT 0x12\n#define CP_CPF_BUSY_STAT__HQD_IB_FETCHER_BUSY_MASK 0x80000\n#define CP_CPF_BUSY_STAT__HQD_IB_FETCHER_BUSY__SHIFT 0x13\n#define CP_CPF_BUSY_STAT__HQD_IQ_FETCHER_BUSY_MASK 0x100000\n#define CP_CPF_BUSY_STAT__HQD_IQ_FETCHER_BUSY__SHIFT 0x14\n#define CP_CPF_BUSY_STAT__HQD_EOP_FETCHER_BUSY_MASK 0x200000\n#define CP_CPF_BUSY_STAT__HQD_EOP_FETCHER_BUSY__SHIFT 0x15\n#define CP_CPF_BUSY_STAT__HQD_CONSUMED_RPTR_BUSY_MASK 0x400000\n#define CP_CPF_BUSY_STAT__HQD_CONSUMED_RPTR_BUSY__SHIFT 0x16\n#define CP_CPF_BUSY_STAT__HQD_FETCHER_ARB_BUSY_MASK 0x800000\n#define CP_CPF_BUSY_STAT__HQD_FETCHER_ARB_BUSY__SHIFT 0x17\n#define CP_CPF_BUSY_STAT__HQD_ROQ_ALIGN_BUSY_MASK 0x1000000\n#define CP_CPF_BUSY_STAT__HQD_ROQ_ALIGN_BUSY__SHIFT 0x18\n#define CP_CPF_BUSY_STAT__HQD_ROQ_EOP_BUSY_MASK 0x2000000\n#define CP_CPF_BUSY_STAT__HQD_ROQ_EOP_BUSY__SHIFT 0x19\n#define CP_CPF_BUSY_STAT__HQD_ROQ_IQ_BUSY_MASK 0x4000000\n#define CP_CPF_BUSY_STAT__HQD_ROQ_IQ_BUSY__SHIFT 0x1a\n#define CP_CPF_BUSY_STAT__HQD_ROQ_PQ_BUSY_MASK 0x8000000\n#define CP_CPF_BUSY_STAT__HQD_ROQ_PQ_BUSY__SHIFT 0x1b\n#define CP_CPF_BUSY_STAT__HQD_ROQ_IB_BUSY_MASK 0x10000000\n#define CP_CPF_BUSY_STAT__HQD_ROQ_IB_BUSY__SHIFT 0x1c\n#define CP_CPF_BUSY_STAT__HQD_WPTR_POLL_BUSY_MASK 0x20000000\n#define CP_CPF_BUSY_STAT__HQD_WPTR_POLL_BUSY__SHIFT 0x1d\n#define CP_CPF_BUSY_STAT__HQD_PQ_BUSY_MASK 0x40000000\n#define CP_CPF_BUSY_STAT__HQD_PQ_BUSY__SHIFT 0x1e\n#define CP_CPF_BUSY_STAT__HQD_IB_BUSY_MASK 0x80000000\n#define CP_CPF_BUSY_STAT__HQD_IB_BUSY__SHIFT 0x1f\n#define CP_CPF_STALLED_STAT1__RING_FETCHING_DATA_MASK 0x1\n#define CP_CPF_STALLED_STAT1__RING_FETCHING_DATA__SHIFT 0x0\n#define CP_CPF_STALLED_STAT1__INDR1_FETCHING_DATA_MASK 0x2\n#define CP_CPF_STALLED_STAT1__INDR1_FETCHING_DATA__SHIFT 0x1\n#define CP_CPF_STALLED_STAT1__INDR2_FETCHING_DATA_MASK 0x4\n#define CP_CPF_STALLED_STAT1__INDR2_FETCHING_DATA__SHIFT 0x2\n#define CP_CPF_STALLED_STAT1__STATE_FETCHING_DATA_MASK 0x8\n#define CP_CPF_STALLED_STAT1__STATE_FETCHING_DATA__SHIFT 0x3\n#define CP_CPF_STALLED_STAT1__MIU_WAITING_ON_RDREQ_FREE_MASK 0x10\n#define CP_CPF_STALLED_STAT1__MIU_WAITING_ON_RDREQ_FREE__SHIFT 0x4\n#define CP_CPF_STALLED_STAT1__TCIU_WAITING_ON_FREE_MASK 0x20\n#define CP_CPF_STALLED_STAT1__TCIU_WAITING_ON_FREE__SHIFT 0x5\n#define CP_CPF_STALLED_STAT1__TCIU_WAITING_ON_TAGS_MASK 0x40\n#define CP_CPF_STALLED_STAT1__TCIU_WAITING_ON_TAGS__SHIFT 0x6\n#define CP_CPC_MC_CNTL__PACK_DELAY_CNT_MASK 0x1f\n#define CP_CPC_MC_CNTL__PACK_DELAY_CNT__SHIFT 0x0\n#define CP_CPC_GRBM_FREE_COUNT__FREE_COUNT_MASK 0x3f\n#define CP_CPC_GRBM_FREE_COUNT__FREE_COUNT__SHIFT 0x0\n#define CP_MEC_CNTL__MEC_INVALIDATE_ICACHE_MASK 0x10\n#define CP_MEC_CNTL__MEC_INVALIDATE_ICACHE__SHIFT 0x4\n#define CP_MEC_CNTL__MEC_ME2_HALT_MASK 0x10000000\n#define CP_MEC_CNTL__MEC_ME2_HALT__SHIFT 0x1c\n#define CP_MEC_CNTL__MEC_ME2_STEP_MASK 0x20000000\n#define CP_MEC_CNTL__MEC_ME2_STEP__SHIFT 0x1d\n#define CP_MEC_CNTL__MEC_ME1_HALT_MASK 0x40000000\n#define CP_MEC_CNTL__MEC_ME1_HALT__SHIFT 0x1e\n#define CP_MEC_CNTL__MEC_ME1_STEP_MASK 0x80000000\n#define CP_MEC_CNTL__MEC_ME1_STEP__SHIFT 0x1f\n#define CP_MEC_ME1_HEADER_DUMP__HEADER_DUMP_MASK 0xffffffff\n#define CP_MEC_ME1_HEADER_DUMP__HEADER_DUMP__SHIFT 0x0\n#define CP_MEC_ME2_HEADER_DUMP__HEADER_DUMP_MASK 0xffffffff\n#define CP_MEC_ME2_HEADER_DUMP__HEADER_DUMP__SHIFT 0x0\n#define CP_CPC_SCRATCH_INDEX__SCRATCH_INDEX_MASK 0xff\n#define CP_CPC_SCRATCH_INDEX__SCRATCH_INDEX__SHIFT 0x0\n#define CP_CPC_SCRATCH_DATA__SCRATCH_DATA_MASK 0xffffffff\n#define CP_CPC_SCRATCH_DATA__SCRATCH_DATA__SHIFT 0x0\n#define CPG_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3f\n#define CPG_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define CPG_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPG_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPG_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPG_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CPG_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3f\n#define CPG_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define CPG_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xfc00\n#define CPG_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define CPG_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3f\n#define CPG_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define CPG_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xfc00\n#define CPG_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define CPG_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define CPG_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define CPG_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPG_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPG_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPG_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CPC_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3f\n#define CPC_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define CPC_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPC_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPC_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPC_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CPC_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3f\n#define CPC_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define CPC_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xfc00\n#define CPC_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define CPC_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3f\n#define CPC_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define CPC_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xfc00\n#define CPC_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define CPC_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define CPC_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define CPC_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPC_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPC_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPC_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CPF_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3f\n#define CPF_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define CPF_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPF_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPF_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPF_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CPF_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3f\n#define CPF_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define CPF_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xfc00\n#define CPF_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define CPF_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3f\n#define CPF_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define CPF_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xfc00\n#define CPF_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define CPF_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define CPF_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define CPF_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define CPF_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define CPF_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define CPF_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CP_CPC_HALT_HYST_COUNT__COUNT_MASK 0xf\n#define CP_CPC_HALT_HYST_COUNT__COUNT__SHIFT 0x0\n#define CP_DRAW_OBJECT__OBJECT_MASK 0xffffffff\n#define CP_DRAW_OBJECT__OBJECT__SHIFT 0x0\n#define CP_DRAW_OBJECT_COUNTER__COUNT_MASK 0xffff\n#define CP_DRAW_OBJECT_COUNTER__COUNT__SHIFT 0x0\n#define CP_DRAW_WINDOW_MASK_HI__WINDOW_MASK_HI_MASK 0xffffffff\n#define CP_DRAW_WINDOW_MASK_HI__WINDOW_MASK_HI__SHIFT 0x0\n#define CP_DRAW_WINDOW_HI__WINDOW_HI_MASK 0xffffffff\n#define CP_DRAW_WINDOW_HI__WINDOW_HI__SHIFT 0x0\n#define CP_DRAW_WINDOW_LO__MIN_MASK 0xffff\n#define CP_DRAW_WINDOW_LO__MIN__SHIFT 0x0\n#define CP_DRAW_WINDOW_LO__MAX_MASK 0xffff0000\n#define CP_DRAW_WINDOW_LO__MAX__SHIFT 0x10\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_LO_MAX_MASK 0x1\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_LO_MAX__SHIFT 0x0\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_LO_MIN_MASK 0x2\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_LO_MIN__SHIFT 0x1\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_HI_MASK 0x4\n#define CP_DRAW_WINDOW_CNTL__DISABLE_DRAW_WINDOW_HI__SHIFT 0x2\n#define CP_DRAW_WINDOW_CNTL__MODE_MASK 0x100\n#define CP_DRAW_WINDOW_CNTL__MODE__SHIFT 0x8\n#define CP_PRT_LOD_STATS_CNTL0__BU_SIZE_MASK 0xffffffff\n#define CP_PRT_LOD_STATS_CNTL0__BU_SIZE__SHIFT 0x0\n#define CP_PRT_LOD_STATS_CNTL1__BASE_LO_MASK 0xffffffff\n#define CP_PRT_LOD_STATS_CNTL1__BASE_LO__SHIFT 0x0\n#define CP_PRT_LOD_STATS_CNTL2__BASE_HI_MASK 0x3\n#define CP_PRT_LOD_STATS_CNTL2__BASE_HI__SHIFT 0x0\n#define CP_PRT_LOD_STATS_CNTL2__INTERVAL_MASK 0x3fc\n#define CP_PRT_LOD_STATS_CNTL2__INTERVAL__SHIFT 0x2\n#define CP_PRT_LOD_STATS_CNTL2__RESET_CNT_MASK 0x3fc00\n#define CP_PRT_LOD_STATS_CNTL2__RESET_CNT__SHIFT 0xa\n#define CP_PRT_LOD_STATS_CNTL2__RESET_FORCE_MASK 0x40000\n#define CP_PRT_LOD_STATS_CNTL2__RESET_FORCE__SHIFT 0x12\n#define CP_PRT_LOD_STATS_CNTL2__REPORT_AND_RESET_MASK 0x80000\n#define CP_PRT_LOD_STATS_CNTL2__REPORT_AND_RESET__SHIFT 0x13\n#define CP_PRT_LOD_STATS_CNTL2__MC_ENDIAN_SWAP_MASK 0x300000\n#define CP_PRT_LOD_STATS_CNTL2__MC_ENDIAN_SWAP__SHIFT 0x14\n#define CP_PRT_LOD_STATS_CNTL2__MC_VMID_MASK 0x7800000\n#define CP_PRT_LOD_STATS_CNTL2__MC_VMID__SHIFT 0x17\n#define CP_CE_COMPARE_COUNT__COMPARE_COUNT_MASK 0xffffffff\n#define CP_CE_COMPARE_COUNT__COMPARE_COUNT__SHIFT 0x0\n#define CP_CE_DE_COUNT__DRAW_ENGINE_COUNT_MASK 0xffffffff\n#define CP_CE_DE_COUNT__DRAW_ENGINE_COUNT__SHIFT 0x0\n#define CP_DE_CE_COUNT__CONST_ENGINE_COUNT_MASK 0xffffffff\n#define CP_DE_CE_COUNT__CONST_ENGINE_COUNT__SHIFT 0x0\n#define CP_DE_LAST_INVAL_COUNT__LAST_INVAL_COUNT_MASK 0xffffffff\n#define CP_DE_LAST_INVAL_COUNT__LAST_INVAL_COUNT__SHIFT 0x0\n#define CP_DE_DE_COUNT__DRAW_ENGINE_COUNT_MASK 0xffffffff\n#define CP_DE_DE_COUNT__DRAW_ENGINE_COUNT__SHIFT 0x0\n#define CP_EOP_DONE_EVENT_CNTL__WBINV_TC_OP_MASK 0x7f\n#define CP_EOP_DONE_EVENT_CNTL__WBINV_TC_OP__SHIFT 0x0\n#define CP_EOP_DONE_EVENT_CNTL__WBINV_ACTION_ENA_MASK 0x3f000\n#define CP_EOP_DONE_EVENT_CNTL__WBINV_ACTION_ENA__SHIFT 0xc\n#define CP_EOP_DONE_EVENT_CNTL__CACHE_CONTROL_MASK 0x6000000\n#define CP_EOP_DONE_EVENT_CNTL__CACHE_CONTROL__SHIFT 0x19\n#define CP_EOP_DONE_EVENT_CNTL__EOP_VOLATILE_MASK 0x8000000\n#define CP_EOP_DONE_EVENT_CNTL__EOP_VOLATILE__SHIFT 0x1b\n#define CP_EOP_DONE_DATA_CNTL__CNTX_ID_MASK 0xffff\n#define CP_EOP_DONE_DATA_CNTL__CNTX_ID__SHIFT 0x0\n#define CP_EOP_DONE_DATA_CNTL__DST_SEL_MASK 0x30000\n#define CP_EOP_DONE_DATA_CNTL__DST_SEL__SHIFT 0x10\n#define CP_EOP_DONE_DATA_CNTL__INT_SEL_MASK 0x7000000\n#define CP_EOP_DONE_DATA_CNTL__INT_SEL__SHIFT 0x18\n#define CP_EOP_DONE_DATA_CNTL__DATA_SEL_MASK 0xe0000000\n#define CP_EOP_DONE_DATA_CNTL__DATA_SEL__SHIFT 0x1d\n#define CP_EOP_DONE_ADDR_LO__ADDR_SWAP_MASK 0x3\n#define CP_EOP_DONE_ADDR_LO__ADDR_SWAP__SHIFT 0x0\n#define CP_EOP_DONE_ADDR_LO__ADDR_LO_MASK 0xfffffffc\n#define CP_EOP_DONE_ADDR_LO__ADDR_LO__SHIFT 0x2\n#define CP_EOP_DONE_ADDR_HI__ADDR_HI_MASK 0xffff\n#define CP_EOP_DONE_ADDR_HI__ADDR_HI__SHIFT 0x0\n#define CP_EOP_DONE_DATA_LO__DATA_LO_MASK 0xffffffff\n#define CP_EOP_DONE_DATA_LO__DATA_LO__SHIFT 0x0\n#define CP_EOP_DONE_DATA_HI__DATA_HI_MASK 0xffffffff\n#define CP_EOP_DONE_DATA_HI__DATA_HI__SHIFT 0x0\n#define CP_EOP_LAST_FENCE_LO__LAST_FENCE_LO_MASK 0xffffffff\n#define CP_EOP_LAST_FENCE_LO__LAST_FENCE_LO__SHIFT 0x0\n#define CP_EOP_LAST_FENCE_HI__LAST_FENCE_HI_MASK 0xffffffff\n#define CP_EOP_LAST_FENCE_HI__LAST_FENCE_HI__SHIFT 0x0\n#define CP_STREAM_OUT_ADDR_LO__STREAM_OUT_ADDR_SWAP_MASK 0x3\n#define CP_STREAM_OUT_ADDR_LO__STREAM_OUT_ADDR_SWAP__SHIFT 0x0\n#define CP_STREAM_OUT_ADDR_LO__STREAM_OUT_ADDR_LO_MASK 0xfffffffc\n#define CP_STREAM_OUT_ADDR_LO__STREAM_OUT_ADDR_LO__SHIFT 0x2\n#define CP_STREAM_OUT_ADDR_HI__STREAM_OUT_ADDR_HI_MASK 0xffff\n#define CP_STREAM_OUT_ADDR_HI__STREAM_OUT_ADDR_HI__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT0_LO__NUM_PRIM_WRITTEN_CNT0_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT0_LO__NUM_PRIM_WRITTEN_CNT0_LO__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT0_HI__NUM_PRIM_WRITTEN_CNT0_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT0_HI__NUM_PRIM_WRITTEN_CNT0_HI__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT0_LO__NUM_PRIM_NEEDED_CNT0_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT0_LO__NUM_PRIM_NEEDED_CNT0_LO__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT0_HI__NUM_PRIM_NEEDED_CNT0_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT0_HI__NUM_PRIM_NEEDED_CNT0_HI__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT1_LO__NUM_PRIM_WRITTEN_CNT1_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT1_LO__NUM_PRIM_WRITTEN_CNT1_LO__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT1_HI__NUM_PRIM_WRITTEN_CNT1_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT1_HI__NUM_PRIM_WRITTEN_CNT1_HI__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT1_LO__NUM_PRIM_NEEDED_CNT1_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT1_LO__NUM_PRIM_NEEDED_CNT1_LO__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT1_HI__NUM_PRIM_NEEDED_CNT1_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT1_HI__NUM_PRIM_NEEDED_CNT1_HI__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT2_LO__NUM_PRIM_WRITTEN_CNT2_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT2_LO__NUM_PRIM_WRITTEN_CNT2_LO__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT2_HI__NUM_PRIM_WRITTEN_CNT2_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT2_HI__NUM_PRIM_WRITTEN_CNT2_HI__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT2_LO__NUM_PRIM_NEEDED_CNT2_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT2_LO__NUM_PRIM_NEEDED_CNT2_LO__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT2_HI__NUM_PRIM_NEEDED_CNT2_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT2_HI__NUM_PRIM_NEEDED_CNT2_HI__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT3_LO__NUM_PRIM_WRITTEN_CNT3_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT3_LO__NUM_PRIM_WRITTEN_CNT3_LO__SHIFT 0x0\n#define CP_NUM_PRIM_WRITTEN_COUNT3_HI__NUM_PRIM_WRITTEN_CNT3_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_WRITTEN_COUNT3_HI__NUM_PRIM_WRITTEN_CNT3_HI__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT3_LO__NUM_PRIM_NEEDED_CNT3_LO_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT3_LO__NUM_PRIM_NEEDED_CNT3_LO__SHIFT 0x0\n#define CP_NUM_PRIM_NEEDED_COUNT3_HI__NUM_PRIM_NEEDED_CNT3_HI_MASK 0xffffffff\n#define CP_NUM_PRIM_NEEDED_COUNT3_HI__NUM_PRIM_NEEDED_CNT3_HI__SHIFT 0x0\n#define CP_PIPE_STATS_ADDR_LO__PIPE_STATS_ADDR_SWAP_MASK 0x3\n#define CP_PIPE_STATS_ADDR_LO__PIPE_STATS_ADDR_SWAP__SHIFT 0x0\n#define CP_PIPE_STATS_ADDR_LO__PIPE_STATS_ADDR_LO_MASK 0xfffffffc\n#define CP_PIPE_STATS_ADDR_LO__PIPE_STATS_ADDR_LO__SHIFT 0x2\n#define CP_PIPE_STATS_ADDR_HI__PIPE_STATS_ADDR_HI_MASK 0xffff\n#define CP_PIPE_STATS_ADDR_HI__PIPE_STATS_ADDR_HI__SHIFT 0x0\n#define CP_VGT_IAVERT_COUNT_LO__IAVERT_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_IAVERT_COUNT_LO__IAVERT_COUNT_LO__SHIFT 0x0\n#define CP_VGT_IAVERT_COUNT_HI__IAVERT_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_IAVERT_COUNT_HI__IAVERT_COUNT_HI__SHIFT 0x0\n#define CP_VGT_IAPRIM_COUNT_LO__IAPRIM_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_IAPRIM_COUNT_LO__IAPRIM_COUNT_LO__SHIFT 0x0\n#define CP_VGT_IAPRIM_COUNT_HI__IAPRIM_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_IAPRIM_COUNT_HI__IAPRIM_COUNT_HI__SHIFT 0x0\n#define CP_VGT_GSPRIM_COUNT_LO__GSPRIM_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_GSPRIM_COUNT_LO__GSPRIM_COUNT_LO__SHIFT 0x0\n#define CP_VGT_GSPRIM_COUNT_HI__GSPRIM_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_GSPRIM_COUNT_HI__GSPRIM_COUNT_HI__SHIFT 0x0\n#define CP_VGT_VSINVOC_COUNT_LO__VSINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_VSINVOC_COUNT_LO__VSINVOC_COUNT_LO__SHIFT 0x0\n#define CP_VGT_VSINVOC_COUNT_HI__VSINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_VSINVOC_COUNT_HI__VSINVOC_COUNT_HI__SHIFT 0x0\n#define CP_VGT_GSINVOC_COUNT_LO__GSINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_GSINVOC_COUNT_LO__GSINVOC_COUNT_LO__SHIFT 0x0\n#define CP_VGT_GSINVOC_COUNT_HI__GSINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_GSINVOC_COUNT_HI__GSINVOC_COUNT_HI__SHIFT 0x0\n#define CP_VGT_HSINVOC_COUNT_LO__HSINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_HSINVOC_COUNT_LO__HSINVOC_COUNT_LO__SHIFT 0x0\n#define CP_VGT_HSINVOC_COUNT_HI__HSINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_HSINVOC_COUNT_HI__HSINVOC_COUNT_HI__SHIFT 0x0\n#define CP_VGT_DSINVOC_COUNT_LO__DSINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_DSINVOC_COUNT_LO__DSINVOC_COUNT_LO__SHIFT 0x0\n#define CP_VGT_DSINVOC_COUNT_HI__DSINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_DSINVOC_COUNT_HI__DSINVOC_COUNT_HI__SHIFT 0x0\n#define CP_PA_CINVOC_COUNT_LO__CINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_PA_CINVOC_COUNT_LO__CINVOC_COUNT_LO__SHIFT 0x0\n#define CP_PA_CINVOC_COUNT_HI__CINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_PA_CINVOC_COUNT_HI__CINVOC_COUNT_HI__SHIFT 0x0\n#define CP_PA_CPRIM_COUNT_LO__CPRIM_COUNT_LO_MASK 0xffffffff\n#define CP_PA_CPRIM_COUNT_LO__CPRIM_COUNT_LO__SHIFT 0x0\n#define CP_PA_CPRIM_COUNT_HI__CPRIM_COUNT_HI_MASK 0xffffffff\n#define CP_PA_CPRIM_COUNT_HI__CPRIM_COUNT_HI__SHIFT 0x0\n#define CP_SC_PSINVOC_COUNT0_LO__PSINVOC_COUNT0_LO_MASK 0xffffffff\n#define CP_SC_PSINVOC_COUNT0_LO__PSINVOC_COUNT0_LO__SHIFT 0x0\n#define CP_SC_PSINVOC_COUNT0_HI__PSINVOC_COUNT0_HI_MASK 0xffffffff\n#define CP_SC_PSINVOC_COUNT0_HI__PSINVOC_COUNT0_HI__SHIFT 0x0\n#define CP_SC_PSINVOC_COUNT1_LO__OBSOLETE_MASK 0xffffffff\n#define CP_SC_PSINVOC_COUNT1_LO__OBSOLETE__SHIFT 0x0\n#define CP_SC_PSINVOC_COUNT1_HI__OBSOLETE_MASK 0xffffffff\n#define CP_SC_PSINVOC_COUNT1_HI__OBSOLETE__SHIFT 0x0\n#define CP_VGT_CSINVOC_COUNT_LO__CSINVOC_COUNT_LO_MASK 0xffffffff\n#define CP_VGT_CSINVOC_COUNT_LO__CSINVOC_COUNT_LO__SHIFT 0x0\n#define CP_VGT_CSINVOC_COUNT_HI__CSINVOC_COUNT_HI_MASK 0xffffffff\n#define CP_VGT_CSINVOC_COUNT_HI__CSINVOC_COUNT_HI__SHIFT 0x0\n#define CP_STRMOUT_CNTL__OFFSET_UPDATE_DONE_MASK 0x1\n#define CP_STRMOUT_CNTL__OFFSET_UPDATE_DONE__SHIFT 0x0\n#define SCRATCH_REG0__SCRATCH_REG0_MASK 0xffffffff\n#define SCRATCH_REG0__SCRATCH_REG0__SHIFT 0x0\n#define SCRATCH_REG1__SCRATCH_REG1_MASK 0xffffffff\n#define SCRATCH_REG1__SCRATCH_REG1__SHIFT 0x0\n#define SCRATCH_REG2__SCRATCH_REG2_MASK 0xffffffff\n#define SCRATCH_REG2__SCRATCH_REG2__SHIFT 0x0\n#define SCRATCH_REG3__SCRATCH_REG3_MASK 0xffffffff\n#define SCRATCH_REG3__SCRATCH_REG3__SHIFT 0x0\n#define SCRATCH_REG4__SCRATCH_REG4_MASK 0xffffffff\n#define SCRATCH_REG4__SCRATCH_REG4__SHIFT 0x0\n#define SCRATCH_REG5__SCRATCH_REG5_MASK 0xffffffff\n#define SCRATCH_REG5__SCRATCH_REG5__SHIFT 0x0\n#define SCRATCH_REG6__SCRATCH_REG6_MASK 0xffffffff\n#define SCRATCH_REG6__SCRATCH_REG6__SHIFT 0x0\n#define SCRATCH_REG7__SCRATCH_REG7_MASK 0xffffffff\n#define SCRATCH_REG7__SCRATCH_REG7__SHIFT 0x0\n#define SCRATCH_UMSK__OBSOLETE_UMSK_MASK 0xff\n#define SCRATCH_UMSK__OBSOLETE_UMSK__SHIFT 0x0\n#define SCRATCH_UMSK__OBSOLETE_SWAP_MASK 0x30000\n#define SCRATCH_UMSK__OBSOLETE_SWAP__SHIFT 0x10\n#define SCRATCH_ADDR__OBSOLETE_ADDR_MASK 0xffffffff\n#define SCRATCH_ADDR__OBSOLETE_ADDR__SHIFT 0x0\n#define CP_PFP_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO_MASK 0xffffffff\n#define CP_PFP_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO__SHIFT 0x0\n#define CP_PFP_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI_MASK 0xffffffff\n#define CP_PFP_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI__SHIFT 0x0\n#define CP_PFP_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO_MASK 0xffffffff\n#define CP_PFP_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO__SHIFT 0x0\n#define CP_PFP_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI_MASK 0xffffffff\n#define CP_PFP_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI__SHIFT 0x0\n#define CP_PFP_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO_MASK 0xffffffff\n#define CP_PFP_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO__SHIFT 0x0\n#define CP_PFP_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI_MASK 0xffffffff\n#define CP_PFP_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI__SHIFT 0x0\n#define CP_APPEND_ADDR_LO__MEM_ADDR_LO_MASK 0xfffffffc\n#define CP_APPEND_ADDR_LO__MEM_ADDR_LO__SHIFT 0x2\n#define CP_APPEND_ADDR_HI__MEM_ADDR_HI_MASK 0xffff\n#define CP_APPEND_ADDR_HI__MEM_ADDR_HI__SHIFT 0x0\n#define CP_APPEND_ADDR_HI__CS_PS_SEL_MASK 0x10000\n#define CP_APPEND_ADDR_HI__CS_PS_SEL__SHIFT 0x10\n#define CP_APPEND_ADDR_HI__COMMAND_MASK 0xe0000000\n#define CP_APPEND_ADDR_HI__COMMAND__SHIFT 0x1d\n#define CP_APPEND_DATA__DATA_MASK 0xffffffff\n#define CP_APPEND_DATA__DATA__SHIFT 0x0\n#define CP_APPEND_LAST_CS_FENCE__LAST_FENCE_MASK 0xffffffff\n#define CP_APPEND_LAST_CS_FENCE__LAST_FENCE__SHIFT 0x0\n#define CP_APPEND_LAST_PS_FENCE__LAST_FENCE_MASK 0xffffffff\n#define CP_APPEND_LAST_PS_FENCE__LAST_FENCE__SHIFT 0x0\n#define CP_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO_MASK 0xffffffff\n#define CP_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO__SHIFT 0x0\n#define CP_ME_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO_MASK 0xffffffff\n#define CP_ME_ATOMIC_PREOP_LO__ATOMIC_PREOP_LO__SHIFT 0x0\n#define CP_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI_MASK 0xffffffff\n#define CP_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI__SHIFT 0x0\n#define CP_ME_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI_MASK 0xffffffff\n#define CP_ME_ATOMIC_PREOP_HI__ATOMIC_PREOP_HI__SHIFT 0x0\n#define CP_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO_MASK 0xffffffff\n#define CP_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO__SHIFT 0x0\n#define CP_ME_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO_MASK 0xffffffff\n#define CP_ME_GDS_ATOMIC0_PREOP_LO__GDS_ATOMIC0_PREOP_LO__SHIFT 0x0\n#define CP_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI_MASK 0xffffffff\n#define CP_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI__SHIFT 0x0\n#define CP_ME_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI_MASK 0xffffffff\n#define CP_ME_GDS_ATOMIC0_PREOP_HI__GDS_ATOMIC0_PREOP_HI__SHIFT 0x0\n#define CP_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO_MASK 0xffffffff\n#define CP_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO__SHIFT 0x0\n#define CP_ME_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO_MASK 0xffffffff\n#define CP_ME_GDS_ATOMIC1_PREOP_LO__GDS_ATOMIC1_PREOP_LO__SHIFT 0x0\n#define CP_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI_MASK 0xffffffff\n#define CP_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI__SHIFT 0x0\n#define CP_ME_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI_MASK 0xffffffff\n#define CP_ME_GDS_ATOMIC1_PREOP_HI__GDS_ATOMIC1_PREOP_HI__SHIFT 0x0\n#define CP_ME_MC_WADDR_LO__ME_MC_WADDR_SWAP_MASK 0x3\n#define CP_ME_MC_WADDR_LO__ME_MC_WADDR_SWAP__SHIFT 0x0\n#define CP_ME_MC_WADDR_LO__ME_MC_WADDR_LO_MASK 0xfffffffc\n#define CP_ME_MC_WADDR_LO__ME_MC_WADDR_LO__SHIFT 0x2\n#define CP_ME_MC_WADDR_HI__ME_MC_WADDR_HI_MASK 0xffff\n#define CP_ME_MC_WADDR_HI__ME_MC_WADDR_HI__SHIFT 0x0\n#define CP_ME_MC_WDATA_LO__ME_MC_WDATA_LO_MASK 0xffffffff\n#define CP_ME_MC_WDATA_LO__ME_MC_WDATA_LO__SHIFT 0x0\n#define CP_ME_MC_WDATA_HI__ME_MC_WDATA_HI_MASK 0xffffffff\n#define CP_ME_MC_WDATA_HI__ME_MC_WDATA_HI__SHIFT 0x0\n#define CP_ME_MC_RADDR_LO__ME_MC_RADDR_SWAP_MASK 0x3\n#define CP_ME_MC_RADDR_LO__ME_MC_RADDR_SWAP__SHIFT 0x0\n#define CP_ME_MC_RADDR_LO__ME_MC_RADDR_LO_MASK 0xfffffffc\n#define CP_ME_MC_RADDR_LO__ME_MC_RADDR_LO__SHIFT 0x2\n#define CP_ME_MC_RADDR_HI__ME_MC_RADDR_HI_MASK 0xffff\n#define CP_ME_MC_RADDR_HI__ME_MC_RADDR_HI__SHIFT 0x0\n#define CP_SEM_WAIT_TIMER__SEM_WAIT_TIMER_MASK 0xffffffff\n#define CP_SEM_WAIT_TIMER__SEM_WAIT_TIMER__SHIFT 0x0\n#define CP_SIG_SEM_ADDR_LO__SEM_ADDR_SWAP_MASK 0x3\n#define CP_SIG_SEM_ADDR_LO__SEM_ADDR_SWAP__SHIFT 0x0\n#define CP_SIG_SEM_ADDR_LO__SEM_ADDR_LO_MASK 0xfffffff8\n#define CP_SIG_SEM_ADDR_LO__SEM_ADDR_LO__SHIFT 0x3\n#define CP_SIG_SEM_ADDR_HI__SEM_ADDR_HI_MASK 0xffff\n#define CP_SIG_SEM_ADDR_HI__SEM_ADDR_HI__SHIFT 0x0\n#define CP_SIG_SEM_ADDR_HI__SEM_USE_MAILBOX_MASK 0x10000\n#define CP_SIG_SEM_ADDR_HI__SEM_USE_MAILBOX__SHIFT 0x10\n#define CP_SIG_SEM_ADDR_HI__SEM_SIGNAL_TYPE_MASK 0x100000\n#define CP_SIG_SEM_ADDR_HI__SEM_SIGNAL_TYPE__SHIFT 0x14\n#define CP_SIG_SEM_ADDR_HI__SEM_CLIENT_CODE_MASK 0x3000000\n#define CP_SIG_SEM_ADDR_HI__SEM_CLIENT_CODE__SHIFT 0x18\n#define CP_SIG_SEM_ADDR_HI__SEM_SELECT_MASK 0xe0000000\n#define CP_SIG_SEM_ADDR_HI__SEM_SELECT__SHIFT 0x1d\n#define CP_WAIT_SEM_ADDR_LO__SEM_ADDR_SWAP_MASK 0x3\n#define CP_WAIT_SEM_ADDR_LO__SEM_ADDR_SWAP__SHIFT 0x0\n#define CP_WAIT_SEM_ADDR_LO__SEM_ADDR_LO_MASK 0xfffffff8\n#define CP_WAIT_SEM_ADDR_LO__SEM_ADDR_LO__SHIFT 0x3\n#define CP_WAIT_SEM_ADDR_HI__SEM_ADDR_HI_MASK 0xffff\n#define CP_WAIT_SEM_ADDR_HI__SEM_ADDR_HI__SHIFT 0x0\n#define CP_WAIT_SEM_ADDR_HI__SEM_USE_MAILBOX_MASK 0x10000\n#define CP_WAIT_SEM_ADDR_HI__SEM_USE_MAILBOX__SHIFT 0x10\n#define CP_WAIT_SEM_ADDR_HI__SEM_SIGNAL_TYPE_MASK 0x100000\n#define CP_WAIT_SEM_ADDR_HI__SEM_SIGNAL_TYPE__SHIFT 0x14\n#define CP_WAIT_SEM_ADDR_HI__SEM_CLIENT_CODE_MASK 0x3000000\n#define CP_WAIT_SEM_ADDR_HI__SEM_CLIENT_CODE__SHIFT 0x18\n#define CP_WAIT_SEM_ADDR_HI__SEM_SELECT_MASK 0xe0000000\n#define CP_WAIT_SEM_ADDR_HI__SEM_SELECT__SHIFT 0x1d\n#define CP_WAIT_REG_MEM_TIMEOUT__WAIT_REG_MEM_TIMEOUT_MASK 0xffffffff\n#define CP_WAIT_REG_MEM_TIMEOUT__WAIT_REG_MEM_TIMEOUT__SHIFT 0x0\n#define CP_COHER_START_DELAY__START_DELAY_COUNT_MASK 0x3f\n#define CP_COHER_START_DELAY__START_DELAY_COUNT__SHIFT 0x0\n#define CP_COHER_CNTL__DEST_BASE_0_ENA_MASK 0x1\n#define CP_COHER_CNTL__DEST_BASE_0_ENA__SHIFT 0x0\n#define CP_COHER_CNTL__DEST_BASE_1_ENA_MASK 0x2\n#define CP_COHER_CNTL__DEST_BASE_1_ENA__SHIFT 0x1\n#define CP_COHER_CNTL__CB0_DEST_BASE_ENA_MASK 0x40\n#define CP_COHER_CNTL__CB0_DEST_BASE_ENA__SHIFT 0x6\n#define CP_COHER_CNTL__CB1_DEST_BASE_ENA_MASK 0x80\n#define CP_COHER_CNTL__CB1_DEST_BASE_ENA__SHIFT 0x7\n#define CP_COHER_CNTL__CB2_DEST_BASE_ENA_MASK 0x100\n#define CP_COHER_CNTL__CB2_DEST_BASE_ENA__SHIFT 0x8\n#define CP_COHER_CNTL__CB3_DEST_BASE_ENA_MASK 0x200\n#define CP_COHER_CNTL__CB3_DEST_BASE_ENA__SHIFT 0x9\n#define CP_COHER_CNTL__CB4_DEST_BASE_ENA_MASK 0x400\n#define CP_COHER_CNTL__CB4_DEST_BASE_ENA__SHIFT 0xa\n#define CP_COHER_CNTL__CB5_DEST_BASE_ENA_MASK 0x800\n#define CP_COHER_CNTL__CB5_DEST_BASE_ENA__SHIFT 0xb\n#define CP_COHER_CNTL__CB6_DEST_BASE_ENA_MASK 0x1000\n#define CP_COHER_CNTL__CB6_DEST_BASE_ENA__SHIFT 0xc\n#define CP_COHER_CNTL__CB7_DEST_BASE_ENA_MASK 0x2000\n#define CP_COHER_CNTL__CB7_DEST_BASE_ENA__SHIFT 0xd\n#define CP_COHER_CNTL__DB_DEST_BASE_ENA_MASK 0x4000\n#define CP_COHER_CNTL__DB_DEST_BASE_ENA__SHIFT 0xe\n#define CP_COHER_CNTL__TCL1_VOL_ACTION_ENA_MASK 0x8000\n#define CP_COHER_CNTL__TCL1_VOL_ACTION_ENA__SHIFT 0xf\n#define CP_COHER_CNTL__TC_VOL_ACTION_ENA_MASK 0x10000\n#define CP_COHER_CNTL__TC_VOL_ACTION_ENA__SHIFT 0x10\n#define CP_COHER_CNTL__TC_WB_ACTION_ENA_MASK 0x40000\n#define CP_COHER_CNTL__TC_WB_ACTION_ENA__SHIFT 0x12\n#define CP_COHER_CNTL__DEST_BASE_2_ENA_MASK 0x80000\n#define CP_COHER_CNTL__DEST_BASE_2_ENA__SHIFT 0x13\n#define CP_COHER_CNTL__DEST_BASE_3_ENA_MASK 0x200000\n#define CP_COHER_CNTL__DEST_BASE_3_ENA__SHIFT 0x15\n#define CP_COHER_CNTL__TCL1_ACTION_ENA_MASK 0x400000\n#define CP_COHER_CNTL__TCL1_ACTION_ENA__SHIFT 0x16\n#define CP_COHER_CNTL__TC_ACTION_ENA_MASK 0x800000\n#define CP_COHER_CNTL__TC_ACTION_ENA__SHIFT 0x17\n#define CP_COHER_CNTL__CB_ACTION_ENA_MASK 0x2000000\n#define CP_COHER_CNTL__CB_ACTION_ENA__SHIFT 0x19\n#define CP_COHER_CNTL__DB_ACTION_ENA_MASK 0x4000000\n#define CP_COHER_CNTL__DB_ACTION_ENA__SHIFT 0x1a\n#define CP_COHER_CNTL__SH_KCACHE_ACTION_ENA_MASK 0x8000000\n#define CP_COHER_CNTL__SH_KCACHE_ACTION_ENA__SHIFT 0x1b\n#define CP_COHER_CNTL__SH_KCACHE_VOL_ACTION_ENA_MASK 0x10000000\n#define CP_COHER_CNTL__SH_KCACHE_VOL_ACTION_ENA__SHIFT 0x1c\n#define CP_COHER_CNTL__SH_ICACHE_ACTION_ENA_MASK 0x20000000\n#define CP_COHER_CNTL__SH_ICACHE_ACTION_ENA__SHIFT 0x1d\n#define CP_COHER_SIZE__COHER_SIZE_256B_MASK 0xffffffff\n#define CP_COHER_SIZE__COHER_SIZE_256B__SHIFT 0x0\n#define CP_COHER_SIZE_HI__COHER_SIZE_HI_256B_MASK 0xff\n#define CP_COHER_SIZE_HI__COHER_SIZE_HI_256B__SHIFT 0x0\n#define CP_COHER_BASE__COHER_BASE_256B_MASK 0xffffffff\n#define CP_COHER_BASE__COHER_BASE_256B__SHIFT 0x0\n#define CP_COHER_BASE_HI__COHER_BASE_HI_256B_MASK 0xff\n#define CP_COHER_BASE_HI__COHER_BASE_HI_256B__SHIFT 0x0\n#define CP_COHER_STATUS__MATCHING_GFX_CNTX_MASK 0xff\n#define CP_COHER_STATUS__MATCHING_GFX_CNTX__SHIFT 0x0\n#define CP_COHER_STATUS__MEID_MASK 0x3000000\n#define CP_COHER_STATUS__MEID__SHIFT 0x18\n#define CP_COHER_STATUS__PHASE1_STATUS_MASK 0x40000000\n#define CP_COHER_STATUS__PHASE1_STATUS__SHIFT 0x1e\n#define CP_COHER_STATUS__STATUS_MASK 0x80000000\n#define CP_COHER_STATUS__STATUS__SHIFT 0x1f\n#define COHER_DEST_BASE_0__DEST_BASE_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_0__DEST_BASE_256B__SHIFT 0x0\n#define COHER_DEST_BASE_1__DEST_BASE_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_1__DEST_BASE_256B__SHIFT 0x0\n#define COHER_DEST_BASE_2__DEST_BASE_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_2__DEST_BASE_256B__SHIFT 0x0\n#define COHER_DEST_BASE_3__DEST_BASE_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_3__DEST_BASE_256B__SHIFT 0x0\n#define COHER_DEST_BASE_HI_0__DEST_BASE_HI_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_HI_0__DEST_BASE_HI_256B__SHIFT 0x0\n#define COHER_DEST_BASE_HI_1__DEST_BASE_HI_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_HI_1__DEST_BASE_HI_256B__SHIFT 0x0\n#define COHER_DEST_BASE_HI_2__DEST_BASE_HI_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_HI_2__DEST_BASE_HI_256B__SHIFT 0x0\n#define COHER_DEST_BASE_HI_3__DEST_BASE_HI_256B_MASK 0xffffffff\n#define COHER_DEST_BASE_HI_3__DEST_BASE_HI_256B__SHIFT 0x0\n#define CP_DMA_ME_SRC_ADDR__SRC_ADDR_MASK 0xffffffff\n#define CP_DMA_ME_SRC_ADDR__SRC_ADDR__SHIFT 0x0\n#define CP_DMA_ME_SRC_ADDR_HI__SRC_ADDR_HI_MASK 0xffff\n#define CP_DMA_ME_SRC_ADDR_HI__SRC_ADDR_HI__SHIFT 0x0\n#define CP_DMA_ME_DST_ADDR__DST_ADDR_MASK 0xffffffff\n#define CP_DMA_ME_DST_ADDR__DST_ADDR__SHIFT 0x0\n#define CP_DMA_ME_DST_ADDR_HI__DST_ADDR_HI_MASK 0xffff\n#define CP_DMA_ME_DST_ADDR_HI__DST_ADDR_HI__SHIFT 0x0\n#define CP_DMA_ME_CONTROL__SRC_ATC_MASK 0x1000\n#define CP_DMA_ME_CONTROL__SRC_ATC__SHIFT 0xc\n#define CP_DMA_ME_CONTROL__SRC_CACHE_POLICY_MASK 0x6000\n#define CP_DMA_ME_CONTROL__SRC_CACHE_POLICY__SHIFT 0xd\n#define CP_DMA_ME_CONTROL__SRC_VOLATILE_MASK 0x8000\n#define CP_DMA_ME_CONTROL__SRC_VOLATILE__SHIFT 0xf\n#define CP_DMA_ME_CONTROL__DST_SELECT_MASK 0x300000\n#define CP_DMA_ME_CONTROL__DST_SELECT__SHIFT 0x14\n#define CP_DMA_ME_CONTROL__DST_ATC_MASK 0x1000000\n#define CP_DMA_ME_CONTROL__DST_ATC__SHIFT 0x18\n#define CP_DMA_ME_CONTROL__DST_CACHE_POLICY_MASK 0x6000000\n#define CP_DMA_ME_CONTROL__DST_CACHE_POLICY__SHIFT 0x19\n#define CP_DMA_ME_CONTROL__DST_VOLATILE_MASK 0x8000000\n#define CP_DMA_ME_CONTROL__DST_VOLATILE__SHIFT 0x1b\n#define CP_DMA_ME_CONTROL__SRC_SELECT_MASK 0x60000000\n#define CP_DMA_ME_CONTROL__SRC_SELECT__SHIFT 0x1d\n#define CP_DMA_ME_COMMAND__BYTE_COUNT_MASK 0x1fffff\n#define CP_DMA_ME_COMMAND__BYTE_COUNT__SHIFT 0x0\n#define CP_DMA_ME_COMMAND__DIS_WC_MASK 0x200000\n#define CP_DMA_ME_COMMAND__DIS_WC__SHIFT 0x15\n#define CP_DMA_ME_COMMAND__SRC_SWAP_MASK 0xc00000\n#define CP_DMA_ME_COMMAND__SRC_SWAP__SHIFT 0x16\n#define CP_DMA_ME_COMMAND__DST_SWAP_MASK 0x3000000\n#define CP_DMA_ME_COMMAND__DST_SWAP__SHIFT 0x18\n#define CP_DMA_ME_COMMAND__SAS_MASK 0x4000000\n#define CP_DMA_ME_COMMAND__SAS__SHIFT 0x1a\n#define CP_DMA_ME_COMMAND__DAS_MASK 0x8000000\n#define CP_DMA_ME_COMMAND__DAS__SHIFT 0x1b\n#define CP_DMA_ME_COMMAND__SAIC_MASK 0x10000000\n#define CP_DMA_ME_COMMAND__SAIC__SHIFT 0x1c\n#define CP_DMA_ME_COMMAND__DAIC_MASK 0x20000000\n#define CP_DMA_ME_COMMAND__DAIC__SHIFT 0x1d\n#define CP_DMA_ME_COMMAND__RAW_WAIT_MASK 0x40000000\n#define CP_DMA_ME_COMMAND__RAW_WAIT__SHIFT 0x1e\n#define CP_DMA_PFP_SRC_ADDR__SRC_ADDR_MASK 0xffffffff\n#define CP_DMA_PFP_SRC_ADDR__SRC_ADDR__SHIFT 0x0\n#define CP_DMA_PFP_SRC_ADDR_HI__SRC_ADDR_HI_MASK 0xffff\n#define CP_DMA_PFP_SRC_ADDR_HI__SRC_ADDR_HI__SHIFT 0x0\n#define CP_DMA_PFP_DST_ADDR__DST_ADDR_MASK 0xffffffff\n#define CP_DMA_PFP_DST_ADDR__DST_ADDR__SHIFT 0x0\n#define CP_DMA_PFP_DST_ADDR_HI__DST_ADDR_HI_MASK 0xffff\n#define CP_DMA_PFP_DST_ADDR_HI__DST_ADDR_HI__SHIFT 0x0\n#define CP_DMA_PFP_CONTROL__SRC_ATC_MASK 0x1000\n#define CP_DMA_PFP_CONTROL__SRC_ATC__SHIFT 0xc\n#define CP_DMA_PFP_CONTROL__SRC_CACHE_POLICY_MASK 0x6000\n#define CP_DMA_PFP_CONTROL__SRC_CACHE_POLICY__SHIFT 0xd\n#define CP_DMA_PFP_CONTROL__SRC_VOLATILE_MASK 0x8000\n#define CP_DMA_PFP_CONTROL__SRC_VOLATILE__SHIFT 0xf\n#define CP_DMA_PFP_CONTROL__DST_SELECT_MASK 0x300000\n#define CP_DMA_PFP_CONTROL__DST_SELECT__SHIFT 0x14\n#define CP_DMA_PFP_CONTROL__DST_ATC_MASK 0x1000000\n#define CP_DMA_PFP_CONTROL__DST_ATC__SHIFT 0x18\n#define CP_DMA_PFP_CONTROL__DST_CACHE_POLICY_MASK 0x6000000\n#define CP_DMA_PFP_CONTROL__DST_CACHE_POLICY__SHIFT 0x19\n#define CP_DMA_PFP_CONTROL__DST_VOLATILE_MASK 0x8000000\n#define CP_DMA_PFP_CONTROL__DST_VOLATILE__SHIFT 0x1b\n#define CP_DMA_PFP_CONTROL__SRC_SELECT_MASK 0x60000000\n#define CP_DMA_PFP_CONTROL__SRC_SELECT__SHIFT 0x1d\n#define CP_DMA_PFP_COMMAND__BYTE_COUNT_MASK 0x1fffff\n#define CP_DMA_PFP_COMMAND__BYTE_COUNT__SHIFT 0x0\n#define CP_DMA_PFP_COMMAND__DIS_WC_MASK 0x200000\n#define CP_DMA_PFP_COMMAND__DIS_WC__SHIFT 0x15\n#define CP_DMA_PFP_COMMAND__SRC_SWAP_MASK 0xc00000\n#define CP_DMA_PFP_COMMAND__SRC_SWAP__SHIFT 0x16\n#define CP_DMA_PFP_COMMAND__DST_SWAP_MASK 0x3000000\n#define CP_DMA_PFP_COMMAND__DST_SWAP__SHIFT 0x18\n#define CP_DMA_PFP_COMMAND__SAS_MASK 0x4000000\n#define CP_DMA_PFP_COMMAND__SAS__SHIFT 0x1a\n#define CP_DMA_PFP_COMMAND__DAS_MASK 0x8000000\n#define CP_DMA_PFP_COMMAND__DAS__SHIFT 0x1b\n#define CP_DMA_PFP_COMMAND__SAIC_MASK 0x10000000\n#define CP_DMA_PFP_COMMAND__SAIC__SHIFT 0x1c\n#define CP_DMA_PFP_COMMAND__DAIC_MASK 0x20000000\n#define CP_DMA_PFP_COMMAND__DAIC__SHIFT 0x1d\n#define CP_DMA_PFP_COMMAND__RAW_WAIT_MASK 0x40000000\n#define CP_DMA_PFP_COMMAND__RAW_WAIT__SHIFT 0x1e\n#define CP_DMA_CNTL__MIN_AVAILSZ_MASK 0x30\n#define CP_DMA_CNTL__MIN_AVAILSZ__SHIFT 0x4\n#define CP_DMA_CNTL__BUFFER_DEPTH_MASK 0xf0000\n#define CP_DMA_CNTL__BUFFER_DEPTH__SHIFT 0x10\n#define CP_DMA_CNTL__PIO_FIFO_EMPTY_MASK 0x10000000\n#define CP_DMA_CNTL__PIO_FIFO_EMPTY__SHIFT 0x1c\n#define CP_DMA_CNTL__PIO_FIFO_FULL_MASK 0x20000000\n#define CP_DMA_CNTL__PIO_FIFO_FULL__SHIFT 0x1d\n#define CP_DMA_CNTL__PIO_COUNT_MASK 0xc0000000\n#define CP_DMA_CNTL__PIO_COUNT__SHIFT 0x1e\n#define CP_DMA_READ_TAGS__DMA_READ_TAG_MASK 0x3ffffff\n#define CP_DMA_READ_TAGS__DMA_READ_TAG__SHIFT 0x0\n#define CP_DMA_READ_TAGS__DMA_READ_TAG_VALID_MASK 0x10000000\n#define CP_DMA_READ_TAGS__DMA_READ_TAG_VALID__SHIFT 0x1c\n#define CP_PFP_IB_CONTROL__IB_EN_MASK 0xff\n#define CP_PFP_IB_CONTROL__IB_EN__SHIFT 0x0\n#define CP_PFP_LOAD_CONTROL__CONFIG_REG_EN_MASK 0x1\n#define CP_PFP_LOAD_CONTROL__CONFIG_REG_EN__SHIFT 0x0\n#define CP_PFP_LOAD_CONTROL__CNTX_REG_EN_MASK 0x2\n#define CP_PFP_LOAD_CONTROL__CNTX_REG_EN__SHIFT 0x1\n#define CP_PFP_LOAD_CONTROL__UCONFIG_REG_EN_MASK 0x8000\n#define CP_PFP_LOAD_CONTROL__UCONFIG_REG_EN__SHIFT 0xf\n#define CP_PFP_LOAD_CONTROL__SH_GFX_REG_EN_MASK 0x10000\n#define CP_PFP_LOAD_CONTROL__SH_GFX_REG_EN__SHIFT 0x10\n#define CP_PFP_LOAD_CONTROL__SH_CS_REG_EN_MASK 0x1000000\n#define CP_PFP_LOAD_CONTROL__SH_CS_REG_EN__SHIFT 0x18\n#define CP_SCRATCH_INDEX__SCRATCH_INDEX_MASK 0xff\n#define CP_SCRATCH_INDEX__SCRATCH_INDEX__SHIFT 0x0\n#define CP_SCRATCH_DATA__SCRATCH_DATA_MASK 0xffffffff\n#define CP_SCRATCH_DATA__SCRATCH_DATA__SHIFT 0x0\n#define CP_RB_OFFSET__RB_OFFSET_MASK 0xfffff\n#define CP_RB_OFFSET__RB_OFFSET__SHIFT 0x0\n#define CP_IB1_OFFSET__IB1_OFFSET_MASK 0xfffff\n#define CP_IB1_OFFSET__IB1_OFFSET__SHIFT 0x0\n#define CP_IB2_OFFSET__IB2_OFFSET_MASK 0xfffff\n#define CP_IB2_OFFSET__IB2_OFFSET__SHIFT 0x0\n#define CP_IB1_PREAMBLE_BEGIN__IB1_PREAMBLE_BEGIN_MASK 0xfffff\n#define CP_IB1_PREAMBLE_BEGIN__IB1_PREAMBLE_BEGIN__SHIFT 0x0\n#define CP_IB1_PREAMBLE_END__IB1_PREAMBLE_END_MASK 0xfffff\n#define CP_IB1_PREAMBLE_END__IB1_PREAMBLE_END__SHIFT 0x0\n#define CP_IB2_PREAMBLE_BEGIN__IB2_PREAMBLE_BEGIN_MASK 0xfffff\n#define CP_IB2_PREAMBLE_BEGIN__IB2_PREAMBLE_BEGIN__SHIFT 0x0\n#define CP_IB2_PREAMBLE_END__IB2_PREAMBLE_END_MASK 0xfffff\n#define CP_IB2_PREAMBLE_END__IB2_PREAMBLE_END__SHIFT 0x0\n#define CP_CE_IB1_OFFSET__IB1_OFFSET_MASK 0xfffff\n#define CP_CE_IB1_OFFSET__IB1_OFFSET__SHIFT 0x0\n#define CP_CE_IB2_OFFSET__IB2_OFFSET_MASK 0xfffff\n#define CP_CE_IB2_OFFSET__IB2_OFFSET__SHIFT 0x0\n#define CP_CE_COUNTER__CONST_ENGINE_COUNT_MASK 0xffffffff\n#define CP_CE_COUNTER__CONST_ENGINE_COUNT__SHIFT 0x0\n#define CP_STALLED_STAT1__RBIU_TO_DMA_NOT_RDY_TO_RCV_MASK 0x1\n#define CP_STALLED_STAT1__RBIU_TO_DMA_NOT_RDY_TO_RCV__SHIFT 0x0\n#define CP_STALLED_STAT1__RBIU_TO_SEM_NOT_RDY_TO_RCV_MASK 0x4\n#define CP_STALLED_STAT1__RBIU_TO_SEM_NOT_RDY_TO_RCV__SHIFT 0x2\n#define CP_STALLED_STAT1__RBIU_TO_MEMWR_NOT_RDY_TO_RCV_MASK 0x10\n#define CP_STALLED_STAT1__RBIU_TO_MEMWR_NOT_RDY_TO_RCV__SHIFT 0x4\n#define CP_STALLED_STAT1__ME_HAS_ACTIVE_CE_BUFFER_FLAG_MASK 0x400\n#define CP_STALLED_STAT1__ME_HAS_ACTIVE_CE_BUFFER_FLAG__SHIFT 0xa\n#define CP_STALLED_STAT1__ME_HAS_ACTIVE_DE_BUFFER_FLAG_MASK 0x800\n#define CP_STALLED_STAT1__ME_HAS_ACTIVE_DE_BUFFER_FLAG__SHIFT 0xb\n#define CP_STALLED_STAT1__ME_STALLED_ON_TC_WR_CONFIRM_MASK 0x1000\n#define CP_STALLED_STAT1__ME_STALLED_ON_TC_WR_CONFIRM__SHIFT 0xc\n#define CP_STALLED_STAT1__ME_STALLED_ON_ATOMIC_RTN_DATA_MASK 0x2000\n#define CP_STALLED_STAT1__ME_STALLED_ON_ATOMIC_RTN_DATA__SHIFT 0xd\n#define CP_STALLED_STAT1__ME_WAITING_ON_MC_READ_DATA_MASK 0x4000\n#define CP_STALLED_STAT1__ME_WAITING_ON_MC_READ_DATA__SHIFT 0xe\n#define CP_STALLED_STAT1__ME_WAITING_ON_REG_READ_DATA_MASK 0x8000\n#define CP_STALLED_STAT1__ME_WAITING_ON_REG_READ_DATA__SHIFT 0xf\n#define CP_STALLED_STAT1__MIU_WAITING_ON_RDREQ_FREE_MASK 0x10000\n#define CP_STALLED_STAT1__MIU_WAITING_ON_RDREQ_FREE__SHIFT 0x10\n#define CP_STALLED_STAT1__MIU_WAITING_ON_WRREQ_FREE_MASK 0x20000\n#define CP_STALLED_STAT1__MIU_WAITING_ON_WRREQ_FREE__SHIFT 0x11\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_GDS_FREE_MASK 0x800000\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_GDS_FREE__SHIFT 0x17\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_GRBM_FREE_MASK 0x1000000\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_GRBM_FREE__SHIFT 0x18\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_VGT_FREE_MASK 0x2000000\n#define CP_STALLED_STAT1__RCIU_WAITING_ON_VGT_FREE__SHIFT 0x19\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_ME_READ_MASK 0x4000000\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_ME_READ__SHIFT 0x1a\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_DMA_READ_MASK 0x8000000\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_DMA_READ__SHIFT 0x1b\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_APPEND_READ_MASK 0x10000000\n#define CP_STALLED_STAT1__RCIU_STALLED_ON_APPEND_READ__SHIFT 0x1c\n#define CP_STALLED_STAT1__RCIU_HALTED_BY_REG_VIOLATION_MASK 0x20000000\n#define CP_STALLED_STAT1__RCIU_HALTED_BY_REG_VIOLATION__SHIFT 0x1d\n#define CP_STALLED_STAT2__PFP_TO_CSF_NOT_RDY_TO_RCV_MASK 0x1\n#define CP_STALLED_STAT2__PFP_TO_CSF_NOT_RDY_TO_RCV__SHIFT 0x0\n#define CP_STALLED_STAT2__PFP_TO_MEQ_NOT_RDY_TO_RCV_MASK 0x2\n#define CP_STALLED_STAT2__PFP_TO_MEQ_NOT_RDY_TO_RCV__SHIFT 0x1\n#define CP_STALLED_STAT2__PFP_TO_RCIU_NOT_RDY_TO_RCV_MASK 0x4\n#define CP_STALLED_STAT2__PFP_TO_RCIU_NOT_RDY_TO_RCV__SHIFT 0x2\n#define CP_STALLED_STAT2__PFP_TO_VGT_WRITES_PENDING_MASK 0x10\n#define CP_STALLED_STAT2__PFP_TO_VGT_WRITES_PENDING__SHIFT 0x4\n#define CP_STALLED_STAT2__PFP_RCIU_READ_PENDING_MASK 0x20\n#define CP_STALLED_STAT2__PFP_RCIU_READ_PENDING__SHIFT 0x5\n#define CP_STALLED_STAT2__PFP_MIU_READ_PENDING_MASK 0x40\n#define CP_STALLED_STAT2__PFP_MIU_READ_PENDING__SHIFT 0x6\n#define CP_STALLED_STAT2__PFP_TO_MIU_WRITE_NOT_RDY_TO_RCV_MASK 0x80\n#define CP_STALLED_STAT2__PFP_TO_MIU_WRITE_NOT_RDY_TO_RCV__SHIFT 0x7\n#define CP_STALLED_STAT2__PFP_WAITING_ON_BUFFER_DATA_MASK 0x100\n#define CP_STALLED_STAT2__PFP_WAITING_ON_BUFFER_DATA__SHIFT 0x8\n#define CP_STALLED_STAT2__ME_WAIT_ON_CE_COUNTER_MASK 0x200\n#define CP_STALLED_STAT2__ME_WAIT_ON_CE_COUNTER__SHIFT 0x9\n#define CP_STALLED_STAT2__ME_WAIT_ON_AVAIL_BUFFER_MASK 0x400\n#define CP_STALLED_STAT2__ME_WAIT_ON_AVAIL_BUFFER__SHIFT 0xa\n#define CP_STALLED_STAT2__GFX_CNTX_NOT_AVAIL_TO_ME_MASK 0x800\n#define CP_STALLED_STAT2__GFX_CNTX_NOT_AVAIL_TO_ME__SHIFT 0xb\n#define CP_STALLED_STAT2__ME_RCIU_NOT_RDY_TO_RCV_MASK 0x1000\n#define CP_STALLED_STAT2__ME_RCIU_NOT_RDY_TO_RCV__SHIFT 0xc\n#define CP_STALLED_STAT2__ME_TO_CONST_NOT_RDY_TO_RCV_MASK 0x2000\n#define CP_STALLED_STAT2__ME_TO_CONST_NOT_RDY_TO_RCV__SHIFT 0xd\n#define CP_STALLED_STAT2__ME_WAITING_DATA_FROM_PFP_MASK 0x4000\n#define CP_STALLED_STAT2__ME_WAITING_DATA_FROM_PFP__SHIFT 0xe\n#define CP_STALLED_STAT2__ME_WAITING_ON_PARTIAL_FLUSH_MASK 0x8000\n#define CP_STALLED_STAT2__ME_WAITING_ON_PARTIAL_FLUSH__SHIFT 0xf\n#define CP_STALLED_STAT2__MEQ_TO_ME_NOT_RDY_TO_RCV_MASK 0x10000\n#define CP_STALLED_STAT2__MEQ_TO_ME_NOT_RDY_TO_RCV__SHIFT 0x10\n#define CP_STALLED_STAT2__STQ_TO_ME_NOT_RDY_TO_RCV_MASK 0x20000\n#define CP_STALLED_STAT2__STQ_TO_ME_NOT_RDY_TO_RCV__SHIFT 0x11\n#define CP_STALLED_STAT2__ME_WAITING_DATA_FROM_STQ_MASK 0x40000\n#define CP_STALLED_STAT2__ME_WAITING_DATA_FROM_STQ__SHIFT 0x12\n#define CP_STALLED_STAT2__PFP_STALLED_ON_TC_WR_CONFIRM_MASK 0x80000\n#define CP_STALLED_STAT2__PFP_STALLED_ON_TC_WR_CONFIRM__SHIFT 0x13\n#define CP_STALLED_STAT2__PFP_STALLED_ON_ATOMIC_RTN_DATA_MASK 0x100000\n#define CP_STALLED_STAT2__PFP_STALLED_ON_ATOMIC_RTN_DATA__SHIFT 0x14\n#define CP_STALLED_STAT2__EOPD_FIFO_NEEDS_SC_EOP_DONE_MASK 0x200000\n#define CP_STALLED_STAT2__EOPD_FIFO_NEEDS_SC_EOP_DONE__SHIFT 0x15\n#define CP_STALLED_STAT2__EOPD_FIFO_NEEDS_WR_CONFIRM_MASK 0x400000\n#define CP_STALLED_STAT2__EOPD_FIFO_NEEDS_WR_CONFIRM__SHIFT 0x16\n#define CP_STALLED_STAT2__STRMO_WR_OF_PRIM_DATA_PENDING_MASK 0x800000\n#define CP_STALLED_STAT2__STRMO_WR_OF_PRIM_DATA_PENDING__SHIFT 0x17\n#define CP_STALLED_STAT2__PIPE_STATS_WR_DATA_PENDING_MASK 0x1000000\n#define CP_STALLED_STAT2__PIPE_STATS_WR_DATA_PENDING__SHIFT 0x18\n#define CP_STALLED_STAT2__APPEND_RDY_WAIT_ON_CS_DONE_MASK 0x2000000\n#define CP_STALLED_STAT2__APPEND_RDY_WAIT_ON_CS_DONE__SHIFT 0x19\n#define CP_STALLED_STAT2__APPEND_RDY_WAIT_ON_PS_DONE_MASK 0x4000000\n#define CP_STALLED_STAT2__APPEND_RDY_WAIT_ON_PS_DONE__SHIFT 0x1a\n#define CP_STALLED_STAT2__APPEND_WAIT_ON_WR_CONFIRM_MASK 0x8000000\n#define CP_STALLED_STAT2__APPEND_WAIT_ON_WR_CONFIRM__SHIFT 0x1b\n#define CP_STALLED_STAT2__APPEND_ACTIVE_PARTITION_MASK 0x10000000\n#define CP_STALLED_STAT2__APPEND_ACTIVE_PARTITION__SHIFT 0x1c\n#define CP_STALLED_STAT2__APPEND_WAITING_TO_SEND_MEMWRITE_MASK 0x20000000\n#define CP_STALLED_STAT2__APPEND_WAITING_TO_SEND_MEMWRITE__SHIFT 0x1d\n#define CP_STALLED_STAT2__SURF_SYNC_NEEDS_IDLE_CNTXS_MASK 0x40000000\n#define CP_STALLED_STAT2__SURF_SYNC_NEEDS_IDLE_CNTXS__SHIFT 0x1e\n#define CP_STALLED_STAT2__SURF_SYNC_NEEDS_ALL_CLEAN_MASK 0x80000000\n#define CP_STALLED_STAT2__SURF_SYNC_NEEDS_ALL_CLEAN__SHIFT 0x1f\n#define CP_STALLED_STAT3__CE_TO_CSF_NOT_RDY_TO_RCV_MASK 0x1\n#define CP_STALLED_STAT3__CE_TO_CSF_NOT_RDY_TO_RCV__SHIFT 0x0\n#define CP_STALLED_STAT3__CE_TO_RAM_INIT_FETCHER_NOT_RDY_TO_RCV_MASK 0x2\n#define CP_STALLED_STAT3__CE_TO_RAM_INIT_FETCHER_NOT_RDY_TO_RCV__SHIFT 0x1\n#define CP_STALLED_STAT3__CE_WAITING_ON_DATA_FROM_RAM_INIT_FETCHER_MASK 0x4\n#define CP_STALLED_STAT3__CE_WAITING_ON_DATA_FROM_RAM_INIT_FETCHER__SHIFT 0x2\n#define CP_STALLED_STAT3__CE_TO_RAM_INIT_NOT_RDY_MASK 0x8\n#define CP_STALLED_STAT3__CE_TO_RAM_INIT_NOT_RDY__SHIFT 0x3\n#define CP_STALLED_STAT3__CE_TO_RAM_DUMP_NOT_RDY_MASK 0x10\n#define CP_STALLED_STAT3__CE_TO_RAM_DUMP_NOT_RDY__SHIFT 0x4\n#define CP_STALLED_STAT3__CE_TO_RAM_WRITE_NOT_RDY_MASK 0x20\n#define CP_STALLED_STAT3__CE_TO_RAM_WRITE_NOT_RDY__SHIFT 0x5\n#define CP_STALLED_STAT3__CE_TO_INC_FIFO_NOT_RDY_TO_RCV_MASK 0x40\n#define CP_STALLED_STAT3__CE_TO_INC_FIFO_NOT_RDY_TO_RCV__SHIFT 0x6\n#define CP_STALLED_STAT3__CE_TO_WR_FIFO_NOT_RDY_TO_RCV_MASK 0x80\n#define CP_STALLED_STAT3__CE_TO_WR_FIFO_NOT_RDY_TO_RCV__SHIFT 0x7\n#define CP_STALLED_STAT3__CE_TO_MIU_WRITE_NOT_RDY_TO_RCV_MASK 0x100\n#define CP_STALLED_STAT3__CE_TO_MIU_WRITE_NOT_RDY_TO_RCV__SHIFT 0x8\n#define CP_STALLED_STAT3__CE_WAITING_ON_BUFFER_DATA_MASK 0x400\n#define CP_STALLED_STAT3__CE_WAITING_ON_BUFFER_DATA__SHIFT 0xa\n#define CP_STALLED_STAT3__CE_WAITING_ON_CE_BUFFER_FLAG_MASK 0x800\n#define CP_STALLED_STAT3__CE_WAITING_ON_CE_BUFFER_FLAG__SHIFT 0xb\n#define CP_STALLED_STAT3__CE_WAITING_ON_DE_COUNTER_MASK 0x1000\n#define CP_STALLED_STAT3__CE_WAITING_ON_DE_COUNTER__SHIFT 0xc\n#define CP_STALLED_STAT3__CE_WAITING_ON_DE_COUNTER_UNDERFLOW_MASK 0x2000\n#define CP_STALLED_STAT3__CE_WAITING_ON_DE_COUNTER_UNDERFLOW__SHIFT 0xd\n#define CP_STALLED_STAT3__TCIU_WAITING_ON_FREE_MASK 0x4000\n#define CP_STALLED_STAT3__TCIU_WAITING_ON_FREE__SHIFT 0xe\n#define CP_STALLED_STAT3__TCIU_WAITING_ON_TAGS_MASK 0x8000\n#define CP_STALLED_STAT3__TCIU_WAITING_ON_TAGS__SHIFT 0xf\n#define CP_BUSY_STAT__REG_BUS_FIFO_BUSY_MASK 0x1\n#define CP_BUSY_STAT__REG_BUS_FIFO_BUSY__SHIFT 0x0\n#define CP_BUSY_STAT__COHER_CNT_NEQ_ZERO_MASK 0x40\n#define CP_BUSY_STAT__COHER_CNT_NEQ_ZERO__SHIFT 0x6\n#define CP_BUSY_STAT__PFP_PARSING_PACKETS_MASK 0x80\n#define CP_BUSY_STAT__PFP_PARSING_PACKETS__SHIFT 0x7\n#define CP_BUSY_STAT__ME_PARSING_PACKETS_MASK 0x100\n#define CP_BUSY_STAT__ME_PARSING_PACKETS__SHIFT 0x8\n#define CP_BUSY_STAT__RCIU_PFP_BUSY_MASK 0x200\n#define CP_BUSY_STAT__RCIU_PFP_BUSY__SHIFT 0x9\n#define CP_BUSY_STAT__RCIU_ME_BUSY_MASK 0x400\n#define CP_BUSY_STAT__RCIU_ME_BUSY__SHIFT 0xa\n#define CP_BUSY_STAT__SEM_CMDFIFO_NOT_EMPTY_MASK 0x1000\n#define CP_BUSY_STAT__SEM_CMDFIFO_NOT_EMPTY__SHIFT 0xc\n#define CP_BUSY_STAT__SEM_FAILED_AND_HOLDING_MASK 0x2000\n#define CP_BUSY_STAT__SEM_FAILED_AND_HOLDING__SHIFT 0xd\n#define CP_BUSY_STAT__SEM_POLLING_FOR_PASS_MASK 0x4000\n#define CP_BUSY_STAT__SEM_POLLING_FOR_PASS__SHIFT 0xe\n#define CP_BUSY_STAT__GFX_CONTEXT_BUSY_MASK 0x8000\n#define CP_BUSY_STAT__GFX_CONTEXT_BUSY__SHIFT 0xf\n#define CP_BUSY_STAT__ME_PARSER_BUSY_MASK 0x20000\n#define CP_BUSY_STAT__ME_PARSER_BUSY__SHIFT 0x11\n#define CP_BUSY_STAT__EOP_DONE_BUSY_MASK 0x40000\n#define CP_BUSY_STAT__EOP_DONE_BUSY__SHIFT 0x12\n#define CP_BUSY_STAT__STRM_OUT_BUSY_MASK 0x80000\n#define CP_BUSY_STAT__STRM_OUT_BUSY__SHIFT 0x13\n#define CP_BUSY_STAT__PIPE_STATS_BUSY_MASK 0x100000\n#define CP_BUSY_STAT__PIPE_STATS_BUSY__SHIFT 0x14\n#define CP_BUSY_STAT__RCIU_CE_BUSY_MASK 0x200000\n#define CP_BUSY_STAT__RCIU_CE_BUSY__SHIFT 0x15\n#define CP_BUSY_STAT__CE_PARSING_PACKETS_MASK 0x400000\n#define CP_BUSY_STAT__CE_PARSING_PACKETS__SHIFT 0x16\n#define CP_STAT__MIU_RDREQ_BUSY_MASK 0x80\n#define CP_STAT__MIU_RDREQ_BUSY__SHIFT 0x7\n#define CP_STAT__MIU_WRREQ_BUSY_MASK 0x100\n#define CP_STAT__MIU_WRREQ_BUSY__SHIFT 0x8\n#define CP_STAT__ROQ_RING_BUSY_MASK 0x200\n#define CP_STAT__ROQ_RING_BUSY__SHIFT 0x9\n#define CP_STAT__ROQ_INDIRECT1_BUSY_MASK 0x400\n#define CP_STAT__ROQ_INDIRECT1_BUSY__SHIFT 0xa\n#define CP_STAT__ROQ_INDIRECT2_BUSY_MASK 0x800\n#define CP_STAT__ROQ_INDIRECT2_BUSY__SHIFT 0xb\n#define CP_STAT__ROQ_STATE_BUSY_MASK 0x1000\n#define CP_STAT__ROQ_STATE_BUSY__SHIFT 0xc\n#define CP_STAT__DC_BUSY_MASK 0x2000\n#define CP_STAT__DC_BUSY__SHIFT 0xd\n#define CP_STAT__PFP_BUSY_MASK 0x8000\n#define CP_STAT__PFP_BUSY__SHIFT 0xf\n#define CP_STAT__MEQ_BUSY_MASK 0x10000\n#define CP_STAT__MEQ_BUSY__SHIFT 0x10\n#define CP_STAT__ME_BUSY_MASK 0x20000\n#define CP_STAT__ME_BUSY__SHIFT 0x11\n#define CP_STAT__QUERY_BUSY_MASK 0x40000\n#define CP_STAT__QUERY_BUSY__SHIFT 0x12\n#define CP_STAT__SEMAPHORE_BUSY_MASK 0x80000\n#define CP_STAT__SEMAPHORE_BUSY__SHIFT 0x13\n#define CP_STAT__INTERRUPT_BUSY_MASK 0x100000\n#define CP_STAT__INTERRUPT_BUSY__SHIFT 0x14\n#define CP_STAT__SURFACE_SYNC_BUSY_MASK 0x200000\n#define CP_STAT__SURFACE_SYNC_BUSY__SHIFT 0x15\n#define CP_STAT__DMA_BUSY_MASK 0x400000\n#define CP_STAT__DMA_BUSY__SHIFT 0x16\n#define CP_STAT__RCIU_BUSY_MASK 0x800000\n#define CP_STAT__RCIU_BUSY__SHIFT 0x17\n#define CP_STAT__SCRATCH_RAM_BUSY_MASK 0x1000000\n#define CP_STAT__SCRATCH_RAM_BUSY__SHIFT 0x18\n#define CP_STAT__CPC_CPG_BUSY_MASK 0x2000000\n#define CP_STAT__CPC_CPG_BUSY__SHIFT 0x19\n#define CP_STAT__CE_BUSY_MASK 0x4000000\n#define CP_STAT__CE_BUSY__SHIFT 0x1a\n#define CP_STAT__TCIU_BUSY_MASK 0x8000000\n#define CP_STAT__TCIU_BUSY__SHIFT 0x1b\n#define CP_STAT__ROQ_CE_RING_BUSY_MASK 0x10000000\n#define CP_STAT__ROQ_CE_RING_BUSY__SHIFT 0x1c\n#define CP_STAT__ROQ_CE_INDIRECT1_BUSY_MASK 0x20000000\n#define CP_STAT__ROQ_CE_INDIRECT1_BUSY__SHIFT 0x1d\n#define CP_STAT__ROQ_CE_INDIRECT2_BUSY_MASK 0x40000000\n#define CP_STAT__ROQ_CE_INDIRECT2_BUSY__SHIFT 0x1e\n#define CP_STAT__CP_BUSY_MASK 0x80000000\n#define CP_STAT__CP_BUSY__SHIFT 0x1f\n#define CP_ME_HEADER_DUMP__ME_HEADER_DUMP_MASK 0xffffffff\n#define CP_ME_HEADER_DUMP__ME_HEADER_DUMP__SHIFT 0x0\n#define CP_PFP_HEADER_DUMP__PFP_HEADER_DUMP_MASK 0xffffffff\n#define CP_PFP_HEADER_DUMP__PFP_HEADER_DUMP__SHIFT 0x0\n#define CP_GRBM_FREE_COUNT__FREE_COUNT_MASK 0x3f\n#define CP_GRBM_FREE_COUNT__FREE_COUNT__SHIFT 0x0\n#define CP_GRBM_FREE_COUNT__FREE_COUNT_GDS_MASK 0x3f00\n#define CP_GRBM_FREE_COUNT__FREE_COUNT_GDS__SHIFT 0x8\n#define CP_GRBM_FREE_COUNT__FREE_COUNT_PFP_MASK 0x3f0000\n#define CP_GRBM_FREE_COUNT__FREE_COUNT_PFP__SHIFT 0x10\n#define CP_CE_HEADER_DUMP__CE_HEADER_DUMP_MASK 0xffffffff\n#define CP_CE_HEADER_DUMP__CE_HEADER_DUMP__SHIFT 0x0\n#define CP_MC_PACK_DELAY_CNT__PACK_DELAY_CNT_MASK 0x1f\n#define CP_MC_PACK_DELAY_CNT__PACK_DELAY_CNT__SHIFT 0x0\n#define CP_MC_TAG_CNTL__TAG_RAM_INDEX_MASK 0x3f\n#define CP_MC_TAG_CNTL__TAG_RAM_INDEX__SHIFT 0x0\n#define CP_MC_TAG_CNTL__TAG_RAM_SEL_MASK 0x30000\n#define CP_MC_TAG_CNTL__TAG_RAM_SEL__SHIFT 0x10\n#define CP_MC_TAG_DATA__TAG_RAM_DATA_MASK 0xffffffff\n#define CP_MC_TAG_DATA__TAG_RAM_DATA__SHIFT 0x0\n#define CP_CSF_STAT__BUFFER_SLOTS_ALLOCATED_MASK 0xf\n#define CP_CSF_STAT__BUFFER_SLOTS_ALLOCATED__SHIFT 0x0\n#define CP_CSF_STAT__BUFFER_REQUEST_COUNT_MASK 0x3f00\n#define CP_CSF_STAT__BUFFER_REQUEST_COUNT__SHIFT 0x8\n#define CP_CSF_CNTL__FETCH_BUFFER_DEPTH_MASK 0xf\n#define CP_CSF_CNTL__FETCH_BUFFER_DEPTH__SHIFT 0x0\n#define CP_ME_CNTL__CE_INVALIDATE_ICACHE_MASK 0x10\n#define CP_ME_CNTL__CE_INVALIDATE_ICACHE__SHIFT 0x4\n#define CP_ME_CNTL__PFP_INVALIDATE_ICACHE_MASK 0x40\n#define CP_ME_CNTL__PFP_INVALIDATE_ICACHE__SHIFT 0x6\n#define CP_ME_CNTL__ME_INVALIDATE_ICACHE_MASK 0x100\n#define CP_ME_CNTL__ME_INVALIDATE_ICACHE__SHIFT 0x8\n#define CP_ME_CNTL__CE_HALT_MASK 0x1000000\n#define CP_ME_CNTL__CE_HALT__SHIFT 0x18\n#define CP_ME_CNTL__CE_STEP_MASK 0x2000000\n#define CP_ME_CNTL__CE_STEP__SHIFT 0x19\n#define CP_ME_CNTL__PFP_HALT_MASK 0x4000000\n#define CP_ME_CNTL__PFP_HALT__SHIFT 0x1a\n#define CP_ME_CNTL__PFP_STEP_MASK 0x8000000\n#define CP_ME_CNTL__PFP_STEP__SHIFT 0x1b\n#define CP_ME_CNTL__ME_HALT_MASK 0x10000000\n#define CP_ME_CNTL__ME_HALT__SHIFT 0x1c\n#define CP_ME_CNTL__ME_STEP_MASK 0x20000000\n#define CP_ME_CNTL__ME_STEP__SHIFT 0x1d\n#define CP_CNTX_STAT__ACTIVE_HP3D_CONTEXTS_MASK 0xff\n#define CP_CNTX_STAT__ACTIVE_HP3D_CONTEXTS__SHIFT 0x0\n#define CP_CNTX_STAT__CURRENT_HP3D_CONTEXT_MASK 0x700\n#define CP_CNTX_STAT__CURRENT_HP3D_CONTEXT__SHIFT 0x8\n#define CP_CNTX_STAT__ACTIVE_GFX_CONTEXTS_MASK 0xff00000\n#define CP_CNTX_STAT__ACTIVE_GFX_CONTEXTS__SHIFT 0x14\n#define CP_CNTX_STAT__CURRENT_GFX_CONTEXT_MASK 0x70000000\n#define CP_CNTX_STAT__CURRENT_GFX_CONTEXT__SHIFT 0x1c\n#define CP_ME_PREEMPTION__ME_CNTXSW_PREEMPTION_MASK 0x1\n#define CP_ME_PREEMPTION__ME_CNTXSW_PREEMPTION__SHIFT 0x0\n#define CP_RB0_RPTR__RB_RPTR_MASK 0xfffff\n#define CP_RB0_RPTR__RB_RPTR__SHIFT 0x0\n#define CP_RB_RPTR__RB_RPTR_MASK 0xfffff\n#define CP_RB_RPTR__RB_RPTR__SHIFT 0x0\n#define CP_RB1_RPTR__RB_RPTR_MASK 0xfffff\n#define CP_RB1_RPTR__RB_RPTR__SHIFT 0x0\n#define CP_RB2_RPTR__RB_RPTR_MASK 0xfffff\n#define CP_RB2_RPTR__RB_RPTR__SHIFT 0x0\n#define CP_RB_WPTR_DELAY__PRE_WRITE_TIMER_MASK 0xfffffff\n#define CP_RB_WPTR_DELAY__PRE_WRITE_TIMER__SHIFT 0x0\n#define CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT_MASK 0xf0000000\n#define CP_RB_WPTR_DELAY__PRE_WRITE_LIMIT__SHIFT 0x1c\n#define CP_RB_WPTR_POLL_CNTL__POLL_FREQUENCY_MASK 0xffff\n#define CP_RB_WPTR_POLL_CNTL__POLL_FREQUENCY__SHIFT 0x0\n#define CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT_MASK 0xffff0000\n#define CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT 0x10\n#define CP_CE_INIT_BASE_LO__INIT_BASE_LO_MASK 0xffffffe0\n#define CP_CE_INIT_BASE_LO__INIT_BASE_LO__SHIFT 0x5\n#define CP_CE_INIT_BASE_HI__INIT_BASE_HI_MASK 0xffff\n#define CP_CE_INIT_BASE_HI__INIT_BASE_HI__SHIFT 0x0\n#define CP_CE_INIT_BUFSZ__INIT_BUFSZ_MASK 0xfff\n#define CP_CE_INIT_BUFSZ__INIT_BUFSZ__SHIFT 0x0\n#define CP_CE_IB1_BASE_LO__IB1_BASE_LO_MASK 0xfffffffc\n#define CP_CE_IB1_BASE_LO__IB1_BASE_LO__SHIFT 0x2\n#define CP_CE_IB1_BASE_HI__IB1_BASE_HI_MASK 0xffff\n#define CP_CE_IB1_BASE_HI__IB1_BASE_HI__SHIFT 0x0\n#define CP_CE_IB1_BUFSZ__IB1_BUFSZ_MASK 0xfffff\n#define CP_CE_IB1_BUFSZ__IB1_BUFSZ__SHIFT 0x0\n#define CP_CE_IB2_BASE_LO__IB2_BASE_LO_MASK 0xfffffffc\n#define CP_CE_IB2_BASE_LO__IB2_BASE_LO__SHIFT 0x2\n#define CP_CE_IB2_BASE_HI__IB2_BASE_HI_MASK 0xffff\n#define CP_CE_IB2_BASE_HI__IB2_BASE_HI__SHIFT 0x0\n#define CP_CE_IB2_BUFSZ__IB2_BUFSZ_MASK 0xfffff\n#define CP_CE_IB2_BUFSZ__IB2_BUFSZ__SHIFT 0x0\n#define CP_IB1_BASE_LO__IB1_BASE_LO_MASK 0xfffffffc\n#define CP_IB1_BASE_LO__IB1_BASE_LO__SHIFT 0x2\n#define CP_IB1_BASE_HI__IB1_BASE_HI_MASK 0xffff\n#define CP_IB1_BASE_HI__IB1_BASE_HI__SHIFT 0x0\n#define CP_IB1_BUFSZ__IB1_BUFSZ_MASK 0xfffff\n#define CP_IB1_BUFSZ__IB1_BUFSZ__SHIFT 0x0\n#define CP_IB2_BASE_LO__IB2_BASE_LO_MASK 0xfffffffc\n#define CP_IB2_BASE_LO__IB2_BASE_LO__SHIFT 0x2\n#define CP_IB2_BASE_HI__IB2_BASE_HI_MASK 0xffff\n#define CP_IB2_BASE_HI__IB2_BASE_HI__SHIFT 0x0\n#define CP_IB2_BUFSZ__IB2_BUFSZ_MASK 0xfffff\n#define CP_IB2_BUFSZ__IB2_BUFSZ__SHIFT 0x0\n#define CP_ST_BASE_LO__ST_BASE_LO_MASK 0xfffffffc\n#define CP_ST_BASE_LO__ST_BASE_LO__SHIFT 0x2\n#define CP_ST_BASE_HI__ST_BASE_HI_MASK 0xffff\n#define CP_ST_BASE_HI__ST_BASE_HI__SHIFT 0x0\n#define CP_ST_BUFSZ__ST_BUFSZ_MASK 0xfffff\n#define CP_ST_BUFSZ__ST_BUFSZ__SHIFT 0x0\n#define CP_ROQ_THRESHOLDS__IB1_START_MASK 0xff\n#define CP_ROQ_THRESHOLDS__IB1_START__SHIFT 0x0\n#define CP_ROQ_THRESHOLDS__IB2_START_MASK 0xff00\n#define CP_ROQ_THRESHOLDS__IB2_START__SHIFT 0x8\n#define CP_MEQ_STQ_THRESHOLD__STQ_START_MASK 0xff\n#define CP_MEQ_STQ_THRESHOLD__STQ_START__SHIFT 0x0\n#define CP_ROQ1_THRESHOLDS__RB1_START_MASK 0xff\n#define CP_ROQ1_THRESHOLDS__RB1_START__SHIFT 0x0\n#define CP_ROQ1_THRESHOLDS__RB2_START_MASK 0xff00\n#define CP_ROQ1_THRESHOLDS__RB2_START__SHIFT 0x8\n#define CP_ROQ1_THRESHOLDS__R0_IB1_START_MASK 0xff0000\n#define CP_ROQ1_THRESHOLDS__R0_IB1_START__SHIFT 0x10\n#define CP_ROQ1_THRESHOLDS__R1_IB1_START_MASK 0xff000000\n#define CP_ROQ1_THRESHOLDS__R1_IB1_START__SHIFT 0x18\n#define CP_ROQ2_THRESHOLDS__R2_IB1_START_MASK 0xff\n#define CP_ROQ2_THRESHOLDS__R2_IB1_START__SHIFT 0x0\n#define CP_ROQ2_THRESHOLDS__R0_IB2_START_MASK 0xff00\n#define CP_ROQ2_THRESHOLDS__R0_IB2_START__SHIFT 0x8\n#define CP_ROQ2_THRESHOLDS__R1_IB2_START_MASK 0xff0000\n#define CP_ROQ2_THRESHOLDS__R1_IB2_START__SHIFT 0x10\n#define CP_ROQ2_THRESHOLDS__R2_IB2_START_MASK 0xff000000\n#define CP_ROQ2_THRESHOLDS__R2_IB2_START__SHIFT 0x18\n#define CP_STQ_THRESHOLDS__STQ0_START_MASK 0xff\n#define CP_STQ_THRESHOLDS__STQ0_START__SHIFT 0x0\n#define CP_STQ_THRESHOLDS__STQ1_START_MASK 0xff00\n#define CP_STQ_THRESHOLDS__STQ1_START__SHIFT 0x8\n#define CP_STQ_THRESHOLDS__STQ2_START_MASK 0xff0000\n#define CP_STQ_THRESHOLDS__STQ2_START__SHIFT 0x10\n#define CP_QUEUE_THRESHOLDS__ROQ_IB1_START_MASK 0x3f\n#define CP_QUEUE_THRESHOLDS__ROQ_IB1_START__SHIFT 0x0\n#define CP_QUEUE_THRESHOLDS__ROQ_IB2_START_MASK 0x3f00\n#define CP_QUEUE_THRESHOLDS__ROQ_IB2_START__SHIFT 0x8\n#define CP_MEQ_THRESHOLDS__MEQ1_START_MASK 0xff\n#define CP_MEQ_THRESHOLDS__MEQ1_START__SHIFT 0x0\n#define CP_MEQ_THRESHOLDS__MEQ2_START_MASK 0xff00\n#define CP_MEQ_THRESHOLDS__MEQ2_START__SHIFT 0x8\n#define CP_ROQ_AVAIL__ROQ_CNT_RING_MASK 0x7ff\n#define CP_ROQ_AVAIL__ROQ_CNT_RING__SHIFT 0x0\n#define CP_ROQ_AVAIL__ROQ_CNT_IB1_MASK 0x7ff0000\n#define CP_ROQ_AVAIL__ROQ_CNT_IB1__SHIFT 0x10\n#define CP_STQ_AVAIL__STQ_CNT_MASK 0x1ff\n#define CP_STQ_AVAIL__STQ_CNT__SHIFT 0x0\n#define CP_ROQ2_AVAIL__ROQ_CNT_IB2_MASK 0x7ff\n#define CP_ROQ2_AVAIL__ROQ_CNT_IB2__SHIFT 0x0\n#define CP_MEQ_AVAIL__MEQ_CNT_MASK 0x3ff\n#define CP_MEQ_AVAIL__MEQ_CNT__SHIFT 0x0\n#define CP_CMD_INDEX__CMD_INDEX_MASK 0x7ff\n#define CP_CMD_INDEX__CMD_INDEX__SHIFT 0x0\n#define CP_CMD_INDEX__CMD_ME_SEL_MASK 0x3000\n#define CP_CMD_INDEX__CMD_ME_SEL__SHIFT 0xc\n#define CP_CMD_INDEX__CMD_QUEUE_SEL_MASK 0x30000\n#define CP_CMD_INDEX__CMD_QUEUE_SEL__SHIFT 0x10\n#define CP_CMD_DATA__CMD_DATA_MASK 0xffffffff\n#define CP_CMD_DATA__CMD_DATA__SHIFT 0x0\n#define CP_ROQ_RB_STAT__ROQ_RPTR_PRIMARY_MASK 0x3ff\n#define CP_ROQ_RB_STAT__ROQ_RPTR_PRIMARY__SHIFT 0x0\n#define CP_ROQ_RB_STAT__ROQ_WPTR_PRIMARY_MASK 0x3ff0000\n#define CP_ROQ_RB_STAT__ROQ_WPTR_PRIMARY__SHIFT 0x10\n#define CP_ROQ_IB1_STAT__ROQ_RPTR_INDIRECT1_MASK 0x3ff\n#define CP_ROQ_IB1_STAT__ROQ_RPTR_INDIRECT1__SHIFT 0x0\n#define CP_ROQ_IB1_STAT__ROQ_WPTR_INDIRECT1_MASK 0x3ff0000\n#define CP_ROQ_IB1_STAT__ROQ_WPTR_INDIRECT1__SHIFT 0x10\n#define CP_ROQ_IB2_STAT__ROQ_RPTR_INDIRECT2_MASK 0x3ff\n#define CP_ROQ_IB2_STAT__ROQ_RPTR_INDIRECT2__SHIFT 0x0\n#define CP_ROQ_IB2_STAT__ROQ_WPTR_INDIRECT2_MASK 0x3ff0000\n#define CP_ROQ_IB2_STAT__ROQ_WPTR_INDIRECT2__SHIFT 0x10\n#define CP_STQ_STAT__STQ_RPTR_MASK 0x3ff\n#define CP_STQ_STAT__STQ_RPTR__SHIFT 0x0\n#define CP_STQ_WR_STAT__STQ_WPTR_MASK 0x3ff\n#define CP_STQ_WR_STAT__STQ_WPTR__SHIFT 0x0\n#define CP_MEQ_STAT__MEQ_RPTR_MASK 0x3ff\n#define CP_MEQ_STAT__MEQ_RPTR__SHIFT 0x0\n#define CP_MEQ_STAT__MEQ_WPTR_MASK 0x3ff0000\n#define CP_MEQ_STAT__MEQ_WPTR__SHIFT 0x10\n#define CP_CEQ1_AVAIL__CEQ_CNT_RING_MASK 0x7ff\n#define CP_CEQ1_AVAIL__CEQ_CNT_RING__SHIFT 0x0\n#define CP_CEQ1_AVAIL__CEQ_CNT_IB1_MASK 0x7ff0000\n#define CP_CEQ1_AVAIL__CEQ_CNT_IB1__SHIFT 0x10\n#define CP_CEQ2_AVAIL__CEQ_CNT_IB2_MASK 0x7ff\n#define CP_CEQ2_AVAIL__CEQ_CNT_IB2__SHIFT 0x0\n#define CP_CE_ROQ_RB_STAT__CEQ_RPTR_PRIMARY_MASK 0x3ff\n#define CP_CE_ROQ_RB_STAT__CEQ_RPTR_PRIMARY__SHIFT 0x0\n#define CP_CE_ROQ_RB_STAT__CEQ_WPTR_PRIMARY_MASK 0x3ff0000\n#define CP_CE_ROQ_RB_STAT__CEQ_WPTR_PRIMARY__SHIFT 0x10\n#define CP_CE_ROQ_IB1_STAT__CEQ_RPTR_INDIRECT1_MASK 0x3ff\n#define CP_CE_ROQ_IB1_STAT__CEQ_RPTR_INDIRECT1__SHIFT 0x0\n#define CP_CE_ROQ_IB1_STAT__CEQ_WPTR_INDIRECT1_MASK 0x3ff0000\n#define CP_CE_ROQ_IB1_STAT__CEQ_WPTR_INDIRECT1__SHIFT 0x10\n#define CP_CE_ROQ_IB2_STAT__CEQ_RPTR_INDIRECT2_MASK 0x3ff\n#define CP_CE_ROQ_IB2_STAT__CEQ_RPTR_INDIRECT2__SHIFT 0x0\n#define CP_CE_ROQ_IB2_STAT__CEQ_WPTR_INDIRECT2_MASK 0x3ff0000\n#define CP_CE_ROQ_IB2_STAT__CEQ_WPTR_INDIRECT2__SHIFT 0x10\n#define CP_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED_MASK 0x4000\n#define CP_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED__SHIFT 0xe\n#define CP_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED_MASK 0x20000\n#define CP_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED__SHIFT 0x11\n#define CP_INT_STAT_DEBUG__CNTX_BUSY_INT_ASSERTED_MASK 0x80000\n#define CP_INT_STAT_DEBUG__CNTX_BUSY_INT_ASSERTED__SHIFT 0x13\n#define CP_INT_STAT_DEBUG__CNTX_EMPTY_INT_ASSERTED_MASK 0x100000\n#define CP_INT_STAT_DEBUG__CNTX_EMPTY_INT_ASSERTED__SHIFT 0x14\n#define CP_INT_STAT_DEBUG__PRIV_INSTR_INT_ASSERTED_MASK 0x400000\n#define CP_INT_STAT_DEBUG__PRIV_INSTR_INT_ASSERTED__SHIFT 0x16\n#define CP_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED_MASK 0x800000\n#define CP_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED__SHIFT 0x17\n#define CP_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED_MASK 0x1000000\n#define CP_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED__SHIFT 0x18\n#define CP_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED_MASK 0x4000000\n#define CP_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED__SHIFT 0x1a\n#define CP_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED_MASK 0x8000000\n#define CP_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED__SHIFT 0x1b\n#define CP_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED_MASK 0x20000000\n#define CP_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED__SHIFT 0x1d\n#define CP_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED_MASK 0x40000000\n#define CP_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED__SHIFT 0x1e\n#define CP_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED_MASK 0x80000000\n#define CP_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED__SHIFT 0x1f\n#define CP_PERFMON_CNTL__PERFMON_STATE_MASK 0xf\n#define CP_PERFMON_CNTL__PERFMON_STATE__SHIFT 0x0\n#define CP_PERFMON_CNTL__SPM_PERFMON_STATE_MASK 0xf0\n#define CP_PERFMON_CNTL__SPM_PERFMON_STATE__SHIFT 0x4\n#define CP_PERFMON_CNTL__PERFMON_ENABLE_MODE_MASK 0x300\n#define CP_PERFMON_CNTL__PERFMON_ENABLE_MODE__SHIFT 0x8\n#define CP_PERFMON_CNTL__PERFMON_SAMPLE_ENABLE_MASK 0x400\n#define CP_PERFMON_CNTL__PERFMON_SAMPLE_ENABLE__SHIFT 0xa\n#define CP_PERFMON_CNTX_CNTL__PERFMON_ENABLE_MASK 0x80000000\n#define CP_PERFMON_CNTX_CNTL__PERFMON_ENABLE__SHIFT 0x1f\n#define CP_RINGID__RINGID_MASK 0x3\n#define CP_RINGID__RINGID__SHIFT 0x0\n#define CP_PIPEID__PIPE_ID_MASK 0x3\n#define CP_PIPEID__PIPE_ID__SHIFT 0x0\n#define CP_VMID__VMID_MASK 0xf\n#define CP_VMID__VMID__SHIFT 0x0\n#define CP_HPD_ROQ_OFFSETS__IQ_OFFSET_MASK 0x7\n#define CP_HPD_ROQ_OFFSETS__IQ_OFFSET__SHIFT 0x0\n#define CP_HPD_ROQ_OFFSETS__PQ_OFFSET_MASK 0x3f00\n#define CP_HPD_ROQ_OFFSETS__PQ_OFFSET__SHIFT 0x8\n#define CP_HPD_ROQ_OFFSETS__IB_OFFSET_MASK 0x3f0000\n#define CP_HPD_ROQ_OFFSETS__IB_OFFSET__SHIFT 0x10\n#define CP_HPD_EOP_BASE_ADDR__BASE_ADDR_MASK 0xffffffff\n#define CP_HPD_EOP_BASE_ADDR__BASE_ADDR__SHIFT 0x0\n#define CP_HPD_EOP_BASE_ADDR_HI__BASE_ADDR_HI_MASK 0xff\n#define CP_HPD_EOP_BASE_ADDR_HI__BASE_ADDR_HI__SHIFT 0x0\n#define CP_HPD_EOP_VMID__VMID_MASK 0xf\n#define CP_HPD_EOP_VMID__VMID__SHIFT 0x0\n#define CP_HPD_EOP_CONTROL__EOP_SIZE_MASK 0x3f\n#define CP_HPD_EOP_CONTROL__EOP_SIZE__SHIFT 0x0\n#define CP_HPD_EOP_CONTROL__PROCESSING_EOP_MASK 0x100\n#define CP_HPD_EOP_CONTROL__PROCESSING_EOP__SHIFT 0x8\n#define CP_HPD_EOP_CONTROL__PROCESSING_QID_MASK 0xe00\n#define CP_HPD_EOP_CONTROL__PROCESSING_QID__SHIFT 0x9\n#define CP_HPD_EOP_CONTROL__PROCESS_EOP_EN_MASK 0x1000\n#define CP_HPD_EOP_CONTROL__PROCESS_EOP_EN__SHIFT 0xc\n#define CP_HPD_EOP_CONTROL__PROCESSING_EOPIB_MASK 0x2000\n#define CP_HPD_EOP_CONTROL__PROCESSING_EOPIB__SHIFT 0xd\n#define CP_HPD_EOP_CONTROL__PROCESS_EOPIB_EN_MASK 0x4000\n#define CP_HPD_EOP_CONTROL__PROCESS_EOPIB_EN__SHIFT 0xe\n#define CP_HPD_EOP_CONTROL__EOP_ATC_MASK 0x800000\n#define CP_HPD_EOP_CONTROL__EOP_ATC__SHIFT 0x17\n#define CP_HPD_EOP_CONTROL__CACHE_POLICY_MASK 0x3000000\n#define CP_HPD_EOP_CONTROL__CACHE_POLICY__SHIFT 0x18\n#define CP_HPD_EOP_CONTROL__EOP_VOLATILE_MASK 0x4000000\n#define CP_HPD_EOP_CONTROL__EOP_VOLATILE__SHIFT 0x1a\n#define CP_HPD_EOP_CONTROL__PEND_Q_SEM_MASK 0x70000000\n#define CP_HPD_EOP_CONTROL__PEND_Q_SEM__SHIFT 0x1c\n#define CP_HPD_EOP_CONTROL__PEND_SIG_SEM_MASK 0x80000000\n#define CP_HPD_EOP_CONTROL__PEND_SIG_SEM__SHIFT 0x1f\n#define CP_MQD_BASE_ADDR__BASE_ADDR_MASK 0xfffffffc\n#define CP_MQD_BASE_ADDR__BASE_ADDR__SHIFT 0x2\n#define CP_MQD_BASE_ADDR_HI__BASE_ADDR_HI_MASK 0xffff\n#define CP_MQD_BASE_ADDR_HI__BASE_ADDR_HI__SHIFT 0x0\n#define CP_HQD_ACTIVE__ACTIVE_MASK 0x1\n#define CP_HQD_ACTIVE__ACTIVE__SHIFT 0x0\n#define CP_HQD_VMID__VMID_MASK 0xf\n#define CP_HQD_VMID__VMID__SHIFT 0x0\n#define CP_HQD_VMID__IB_VMID_MASK 0xf00\n#define CP_HQD_VMID__IB_VMID__SHIFT 0x8\n#define CP_HQD_VMID__VQID_MASK 0x3ff0000\n#define CP_HQD_VMID__VQID__SHIFT 0x10\n#define CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK 0x1\n#define CP_HQD_PERSISTENT_STATE__PRELOAD_REQ__SHIFT 0x0\n#define CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE_MASK 0x3ff00\n#define CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT 0x8\n#define CP_HQD_PERSISTENT_STATE__DISP_ACTIVE_MASK 0x80000000\n#define CP_HQD_PERSISTENT_STATE__DISP_ACTIVE__SHIFT 0x1f\n#define CP_HQD_PIPE_PRIORITY__PIPE_PRIORITY_MASK 0x3\n#define CP_HQD_PIPE_PRIORITY__PIPE_PRIORITY__SHIFT 0x0\n#define CP_HQD_QUEUE_PRIORITY__PRIORITY_LEVEL_MASK 0xf\n#define CP_HQD_QUEUE_PRIORITY__PRIORITY_LEVEL__SHIFT 0x0\n#define CP_HQD_QUANTUM__QUANTUM_EN_MASK 0x1\n#define CP_HQD_QUANTUM__QUANTUM_EN__SHIFT 0x0\n#define CP_HQD_QUANTUM__QUANTUM_SCALE_MASK 0x10\n#define CP_HQD_QUANTUM__QUANTUM_SCALE__SHIFT 0x4\n#define CP_HQD_QUANTUM__QUANTUM_DURATION_MASK 0x3f00\n#define CP_HQD_QUANTUM__QUANTUM_DURATION__SHIFT 0x8\n#define CP_HQD_PQ_BASE__ADDR_MASK 0xffffffff\n#define CP_HQD_PQ_BASE__ADDR__SHIFT 0x0\n#define CP_HQD_PQ_BASE_HI__ADDR_HI_MASK 0xff\n#define CP_HQD_PQ_BASE_HI__ADDR_HI__SHIFT 0x0\n#define CP_HQD_PQ_RPTR__CONSUMED_OFFSET_MASK 0xffffffff\n#define CP_HQD_PQ_RPTR__CONSUMED_OFFSET__SHIFT 0x0\n#define CP_HQD_PQ_RPTR_REPORT_ADDR__RPTR_REPORT_ADDR_MASK 0xfffffffc\n#define CP_HQD_PQ_RPTR_REPORT_ADDR__RPTR_REPORT_ADDR__SHIFT 0x2\n#define CP_HQD_PQ_RPTR_REPORT_ADDR_HI__RPTR_REPORT_ADDR_HI_MASK 0xffff\n#define CP_HQD_PQ_RPTR_REPORT_ADDR_HI__RPTR_REPORT_ADDR_HI__SHIFT 0x0\n#define CP_HQD_PQ_WPTR_POLL_ADDR__WPTR_ADDR_MASK 0xfffffffc\n#define CP_HQD_PQ_WPTR_POLL_ADDR__WPTR_ADDR__SHIFT 0x2\n#define CP_HQD_PQ_WPTR_POLL_ADDR_HI__WPTR_ADDR_HI_MASK 0xffff\n#define CP_HQD_PQ_WPTR_POLL_ADDR_HI__WPTR_ADDR_HI__SHIFT 0x0\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK 0x7ffffc\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT 0x2\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SOURCE_MASK 0x10000000\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SOURCE__SHIFT 0x1c\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SCHD_HIT_MASK 0x20000000\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SCHD_HIT__SHIFT 0x1d\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK 0x40000000\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN__SHIFT 0x1e\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_HIT_MASK 0x80000000\n#define CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_HIT__SHIFT 0x1f\n#define CP_HQD_PQ_WPTR__OFFSET_MASK 0xffffffff\n#define CP_HQD_PQ_WPTR__OFFSET__SHIFT 0x0\n#define CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK 0x3f\n#define CP_HQD_PQ_CONTROL__QUEUE_SIZE__SHIFT 0x0\n#define CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE_MASK 0x3f00\n#define CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT 0x8\n#define CP_HQD_PQ_CONTROL__ENDIAN_SWAP_MASK 0x30000\n#define CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT 0x10\n#define CP_HQD_PQ_CONTROL__MIN_AVAIL_SIZE_MASK 0x300000\n#define CP_HQD_PQ_CONTROL__MIN_AVAIL_SIZE__SHIFT 0x14\n#define CP_HQD_PQ_CONTROL__PQ_ATC_MASK 0x800000\n#define CP_HQD_PQ_CONTROL__PQ_ATC__SHIFT 0x17\n#define CP_HQD_PQ_CONTROL__CACHE_POLICY_MASK 0x3000000\n#define CP_HQD_PQ_CONTROL__CACHE_POLICY__SHIFT 0x18\n#define CP_HQD_PQ_CONTROL__PQ_VOLATILE_MASK 0x4000000\n#define CP_HQD_PQ_CONTROL__PQ_VOLATILE__SHIFT 0x1a\n#define CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR_MASK 0x8000000\n#define CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR__SHIFT 0x1b\n#define CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK 0x10000000\n#define CP_HQD_PQ_CONTROL__UNORD_DISPATCH__SHIFT 0x1c\n#define CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP_MASK 0x20000000\n#define CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP__SHIFT 0x1d\n#define CP_HQD_PQ_CONTROL__PRIV_STATE_MASK 0x40000000\n#define CP_HQD_PQ_CONTROL__PRIV_STATE__SHIFT 0x1e\n#define CP_HQD_PQ_CONTROL__KMD_QUEUE_MASK 0x80000000\n#define CP_HQD_PQ_CONTROL__KMD_QUEUE__SHIFT 0x1f\n#define CP_HQD_IB_BASE_ADDR__IB_BASE_ADDR_MASK 0xfffffffc\n#define CP_HQD_IB_BASE_ADDR__IB_BASE_ADDR__SHIFT 0x2\n#define CP_HQD_IB_BASE_ADDR_HI__IB_BASE_ADDR_HI_MASK 0xffff\n#define CP_HQD_IB_BASE_ADDR_HI__IB_BASE_ADDR_HI__SHIFT 0x0\n#define CP_HQD_IB_RPTR__CONSUMED_OFFSET_MASK 0xfffff\n#define CP_HQD_IB_RPTR__CONSUMED_OFFSET__SHIFT 0x0\n#define CP_HQD_IB_CONTROL__IB_SIZE_MASK 0xfffff\n#define CP_HQD_IB_CONTROL__IB_SIZE__SHIFT 0x0\n#define CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE_MASK 0x300000\n#define CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT 0x14\n#define CP_HQD_IB_CONTROL__IB_ATC_MASK 0x800000\n#define CP_HQD_IB_CONTROL__IB_ATC__SHIFT 0x17\n#define CP_HQD_IB_CONTROL__IB_CACHE_POLICY_MASK 0x3000000\n#define CP_HQD_IB_CONTROL__IB_CACHE_POLICY__SHIFT 0x18\n#define CP_HQD_IB_CONTROL__IB_VOLATILE_MASK 0x4000000\n#define CP_HQD_IB_CONTROL__IB_VOLATILE__SHIFT 0x1a\n#define CP_HQD_IB_CONTROL__PROCESSING_IB_MASK 0x80000000\n#define CP_HQD_IB_CONTROL__PROCESSING_IB__SHIFT 0x1f\n#define CP_HQD_IQ_TIMER__WAIT_TIME_MASK 0xff\n#define CP_HQD_IQ_TIMER__WAIT_TIME__SHIFT 0x0\n#define CP_HQD_IQ_TIMER__RETRY_TYPE_MASK 0x700\n#define CP_HQD_IQ_TIMER__RETRY_TYPE__SHIFT 0x8\n#define CP_HQD_IQ_TIMER__INTERRUPT_TYPE_MASK 0x3000\n#define CP_HQD_IQ_TIMER__INTERRUPT_TYPE__SHIFT 0xc\n#define CP_HQD_IQ_TIMER__INTERRUPT_SIZE_MASK 0x3f0000\n#define CP_HQD_IQ_TIMER__INTERRUPT_SIZE__SHIFT 0x10\n#define CP_HQD_IQ_TIMER__IQ_ATC_MASK 0x800000\n#define CP_HQD_IQ_TIMER__IQ_ATC__SHIFT 0x17\n#define CP_HQD_IQ_TIMER__CACHE_POLICY_MASK 0x3000000\n#define CP_HQD_IQ_TIMER__CACHE_POLICY__SHIFT 0x18\n#define CP_HQD_IQ_TIMER__IQ_VOLATILE_MASK 0x4000000\n#define CP_HQD_IQ_TIMER__IQ_VOLATILE__SHIFT 0x1a\n#define CP_HQD_IQ_TIMER__PROCESS_IQ_EN_MASK 0x20000000\n#define CP_HQD_IQ_TIMER__PROCESS_IQ_EN__SHIFT 0x1d\n#define CP_HQD_IQ_TIMER__PROCESSING_IQ_MASK 0x40000000\n#define CP_HQD_IQ_TIMER__PROCESSING_IQ__SHIFT 0x1e\n#define CP_HQD_IQ_TIMER__ACTIVE_MASK 0x80000000\n#define CP_HQD_IQ_TIMER__ACTIVE__SHIFT 0x1f\n#define CP_HQD_IQ_RPTR__OFFSET_MASK 0x3f\n#define CP_HQD_IQ_RPTR__OFFSET__SHIFT 0x0\n#define CP_HQD_DEQUEUE_REQUEST__DEQUEUE_REQ_MASK 0x3\n#define CP_HQD_DEQUEUE_REQUEST__DEQUEUE_REQ__SHIFT 0x0\n#define CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND_MASK 0x10\n#define CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND__SHIFT 0x4\n#define CP_HQD_DEQUEUE_REQUEST__DEQUEUE_INT_MASK 0x100\n#define CP_HQD_DEQUEUE_REQUEST__DEQUEUE_INT__SHIFT 0x8\n#define CP_HQD_DMA_OFFLOAD__DMA_OFFLOAD_MASK 0x1\n#define CP_HQD_DMA_OFFLOAD__DMA_OFFLOAD__SHIFT 0x0\n#define CP_HQD_SEMA_CMD__RETRY_MASK 0x1\n#define CP_HQD_SEMA_CMD__RETRY__SHIFT 0x0\n#define CP_HQD_SEMA_CMD__RESULT_MASK 0x6\n#define CP_HQD_SEMA_CMD__RESULT__SHIFT 0x1\n#define CP_HQD_MSG_TYPE__ACTION_MASK 0x3\n#define CP_HQD_MSG_TYPE__ACTION__SHIFT 0x0\n#define CP_HQD_ATOMIC0_PREOP_LO__ATOMIC0_PREOP_LO_MASK 0xffffffff\n#define CP_HQD_ATOMIC0_PREOP_LO__ATOMIC0_PREOP_LO__SHIFT 0x0\n#define CP_HQD_ATOMIC0_PREOP_HI__ATOMIC0_PREOP_HI_MASK 0xffffffff\n#define CP_HQD_ATOMIC0_PREOP_HI__ATOMIC0_PREOP_HI__SHIFT 0x0\n#define CP_HQD_ATOMIC1_PREOP_LO__ATOMIC1_PREOP_LO_MASK 0xffffffff\n#define CP_HQD_ATOMIC1_PREOP_LO__ATOMIC1_PREOP_LO__SHIFT 0x0\n#define CP_HQD_ATOMIC1_PREOP_HI__ATOMIC1_PREOP_HI_MASK 0xffffffff\n#define CP_HQD_ATOMIC1_PREOP_HI__ATOMIC1_PREOP_HI__SHIFT 0x0\n#define CP_HQD_HQ_SCHEDULER0__DEQUEUE_STATUS_MASK 0x3\n#define CP_HQD_HQ_SCHEDULER0__DEQUEUE_STATUS__SHIFT 0x0\n#define CP_HQD_HQ_SCHEDULER0__DEQUEUE_RETRY_CNT_MASK 0xc\n#define CP_HQD_HQ_SCHEDULER0__DEQUEUE_RETRY_CNT__SHIFT 0x2\n#define CP_HQD_HQ_SCHEDULER0__RSV_5_4_MASK 0x30\n#define CP_HQD_HQ_SCHEDULER0__RSV_5_4__SHIFT 0x4\n#define CP_HQD_HQ_SCHEDULER0__QUEUE_RUN_ONCE_MASK 0x40\n#define CP_HQD_HQ_SCHEDULER0__QUEUE_RUN_ONCE__SHIFT 0x6\n#define CP_HQD_HQ_SCHEDULER0__SCRATCH_RAM_INIT_MASK 0x80\n#define CP_HQD_HQ_SCHEDULER0__SCRATCH_RAM_INIT__SHIFT 0x7\n#define CP_HQD_HQ_SCHEDULER0__TCL2_DIRTY_MASK 0x100\n#define CP_HQD_HQ_SCHEDULER0__TCL2_DIRTY__SHIFT 0x8\n#define CP_HQD_HQ_SCHEDULER0__PG_ACTIVATED_MASK 0x200\n#define CP_HQD_HQ_SCHEDULER0__PG_ACTIVATED__SHIFT 0x9\n#define CP_HQD_HQ_SCHEDULER0__CG_ACTIVATED_MASK 0x400\n#define CP_HQD_HQ_SCHEDULER0__CG_ACTIVATED__SHIFT 0xa\n#define CP_HQD_HQ_SCHEDULER0__RSVR_31_11_MASK 0xfffff800\n#define CP_HQD_HQ_SCHEDULER0__RSVR_31_11__SHIFT 0xb\n#define CP_HQD_HQ_SCHEDULER1__SCHEDULER_MASK 0xffffffff\n#define CP_HQD_HQ_SCHEDULER1__SCHEDULER__SHIFT 0x0\n#define CP_MQD_CONTROL__VMID_MASK 0xf\n#define CP_MQD_CONTROL__VMID__SHIFT 0x0\n#define CP_MQD_CONTROL__MQD_ATC_MASK 0x800000\n#define CP_MQD_CONTROL__MQD_ATC__SHIFT 0x17\n#define CP_MQD_CONTROL__CACHE_POLICY_MASK 0x3000000\n#define CP_MQD_CONTROL__CACHE_POLICY__SHIFT 0x18\n#define CP_MQD_CONTROL__MQD_VOLATILE_MASK 0x4000000\n#define CP_MQD_CONTROL__MQD_VOLATILE__SHIFT 0x1a\n#define DB_Z_READ_BASE__BASE_256B_MASK 0xffffffff\n#define DB_Z_READ_BASE__BASE_256B__SHIFT 0x0\n#define DB_STENCIL_READ_BASE__BASE_256B_MASK 0xffffffff\n#define DB_STENCIL_READ_BASE__BASE_256B__SHIFT 0x0\n#define DB_Z_WRITE_BASE__BASE_256B_MASK 0xffffffff\n#define DB_Z_WRITE_BASE__BASE_256B__SHIFT 0x0\n#define DB_STENCIL_WRITE_BASE__BASE_256B_MASK 0xffffffff\n#define DB_STENCIL_WRITE_BASE__BASE_256B__SHIFT 0x0\n#define DB_DEPTH_INFO__ADDR5_SWIZZLE_MASK_MASK 0xf\n#define DB_DEPTH_INFO__ADDR5_SWIZZLE_MASK__SHIFT 0x0\n#define DB_DEPTH_INFO__ARRAY_MODE_MASK 0xf0\n#define DB_DEPTH_INFO__ARRAY_MODE__SHIFT 0x4\n#define DB_DEPTH_INFO__PIPE_CONFIG_MASK 0x1f00\n#define DB_DEPTH_INFO__PIPE_CONFIG__SHIFT 0x8\n#define DB_DEPTH_INFO__BANK_WIDTH_MASK 0x6000\n#define DB_DEPTH_INFO__BANK_WIDTH__SHIFT 0xd\n#define DB_DEPTH_INFO__BANK_HEIGHT_MASK 0x18000\n#define DB_DEPTH_INFO__BANK_HEIGHT__SHIFT 0xf\n#define DB_DEPTH_INFO__MACRO_TILE_ASPECT_MASK 0x60000\n#define DB_DEPTH_INFO__MACRO_TILE_ASPECT__SHIFT 0x11\n#define DB_DEPTH_INFO__NUM_BANKS_MASK 0x180000\n#define DB_DEPTH_INFO__NUM_BANKS__SHIFT 0x13\n#define DB_Z_INFO__FORMAT_MASK 0x3\n#define DB_Z_INFO__FORMAT__SHIFT 0x0\n#define DB_Z_INFO__NUM_SAMPLES_MASK 0xc\n#define DB_Z_INFO__NUM_SAMPLES__SHIFT 0x2\n#define DB_Z_INFO__TILE_SPLIT_MASK 0xe000\n#define DB_Z_INFO__TILE_SPLIT__SHIFT 0xd\n#define DB_Z_INFO__TILE_MODE_INDEX_MASK 0x700000\n#define DB_Z_INFO__TILE_MODE_INDEX__SHIFT 0x14\n#define DB_Z_INFO__ALLOW_EXPCLEAR_MASK 0x8000000\n#define DB_Z_INFO__ALLOW_EXPCLEAR__SHIFT 0x1b\n#define DB_Z_INFO__READ_SIZE_MASK 0x10000000\n#define DB_Z_INFO__READ_SIZE__SHIFT 0x1c\n#define DB_Z_INFO__TILE_SURFACE_ENABLE_MASK 0x20000000\n#define DB_Z_INFO__TILE_SURFACE_ENABLE__SHIFT 0x1d\n#define DB_Z_INFO__ZRANGE_PRECISION_MASK 0x80000000\n#define DB_Z_INFO__ZRANGE_PRECISION__SHIFT 0x1f\n#define DB_STENCIL_INFO__FORMAT_MASK 0x1\n#define DB_STENCIL_INFO__FORMAT__SHIFT 0x0\n#define DB_STENCIL_INFO__TILE_SPLIT_MASK 0xe000\n#define DB_STENCIL_INFO__TILE_SPLIT__SHIFT 0xd\n#define DB_STENCIL_INFO__TILE_MODE_INDEX_MASK 0x700000\n#define DB_STENCIL_INFO__TILE_MODE_INDEX__SHIFT 0x14\n#define DB_STENCIL_INFO__ALLOW_EXPCLEAR_MASK 0x8000000\n#define DB_STENCIL_INFO__ALLOW_EXPCLEAR__SHIFT 0x1b\n#define DB_STENCIL_INFO__TILE_STENCIL_DISABLE_MASK 0x20000000\n#define DB_STENCIL_INFO__TILE_STENCIL_DISABLE__SHIFT 0x1d\n#define DB_DEPTH_SIZE__PITCH_TILE_MAX_MASK 0x7ff\n#define DB_DEPTH_SIZE__PITCH_TILE_MAX__SHIFT 0x0\n#define DB_DEPTH_SIZE__HEIGHT_TILE_MAX_MASK 0x3ff800\n#define DB_DEPTH_SIZE__HEIGHT_TILE_MAX__SHIFT 0xb\n#define DB_DEPTH_SLICE__SLICE_TILE_MAX_MASK 0x3fffff\n#define DB_DEPTH_SLICE__SLICE_TILE_MAX__SHIFT 0x0\n#define DB_DEPTH_VIEW__SLICE_START_MASK 0x7ff\n#define DB_DEPTH_VIEW__SLICE_START__SHIFT 0x0\n#define DB_DEPTH_VIEW__SLICE_MAX_MASK 0xffe000\n#define DB_DEPTH_VIEW__SLICE_MAX__SHIFT 0xd\n#define DB_DEPTH_VIEW__Z_READ_ONLY_MASK 0x1000000\n#define DB_DEPTH_VIEW__Z_READ_ONLY__SHIFT 0x18\n#define DB_DEPTH_VIEW__STENCIL_READ_ONLY_MASK 0x2000000\n#define DB_DEPTH_VIEW__STENCIL_READ_ONLY__SHIFT 0x19\n#define DB_RENDER_CONTROL__DEPTH_CLEAR_ENABLE_MASK 0x1\n#define DB_RENDER_CONTROL__DEPTH_CLEAR_ENABLE__SHIFT 0x0\n#define DB_RENDER_CONTROL__STENCIL_CLEAR_ENABLE_MASK 0x2\n#define DB_RENDER_CONTROL__STENCIL_CLEAR_ENABLE__SHIFT 0x1\n#define DB_RENDER_CONTROL__DEPTH_COPY_MASK 0x4\n#define DB_RENDER_CONTROL__DEPTH_COPY__SHIFT 0x2\n#define DB_RENDER_CONTROL__STENCIL_COPY_MASK 0x8\n#define DB_RENDER_CONTROL__STENCIL_COPY__SHIFT 0x3\n#define DB_RENDER_CONTROL__RESUMMARIZE_ENABLE_MASK 0x10\n#define DB_RENDER_CONTROL__RESUMMARIZE_ENABLE__SHIFT 0x4\n#define DB_RENDER_CONTROL__STENCIL_COMPRESS_DISABLE_MASK 0x20\n#define DB_RENDER_CONTROL__STENCIL_COMPRESS_DISABLE__SHIFT 0x5\n#define DB_RENDER_CONTROL__DEPTH_COMPRESS_DISABLE_MASK 0x40\n#define DB_RENDER_CONTROL__DEPTH_COMPRESS_DISABLE__SHIFT 0x6\n#define DB_RENDER_CONTROL__COPY_CENTROID_MASK 0x80\n#define DB_RENDER_CONTROL__COPY_CENTROID__SHIFT 0x7\n#define DB_RENDER_CONTROL__COPY_SAMPLE_MASK 0xf00\n#define DB_RENDER_CONTROL__COPY_SAMPLE__SHIFT 0x8\n#define DB_COUNT_CONTROL__ZPASS_INCREMENT_DISABLE_MASK 0x1\n#define DB_COUNT_CONTROL__ZPASS_INCREMENT_DISABLE__SHIFT 0x0\n#define DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS_MASK 0x2\n#define DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS__SHIFT 0x1\n#define DB_COUNT_CONTROL__SAMPLE_RATE_MASK 0x70\n#define DB_COUNT_CONTROL__SAMPLE_RATE__SHIFT 0x4\n#define DB_COUNT_CONTROL__ZPASS_ENABLE_MASK 0xf00\n#define DB_COUNT_CONTROL__ZPASS_ENABLE__SHIFT 0x8\n#define DB_COUNT_CONTROL__ZFAIL_ENABLE_MASK 0xf000\n#define DB_COUNT_CONTROL__ZFAIL_ENABLE__SHIFT 0xc\n#define DB_COUNT_CONTROL__SFAIL_ENABLE_MASK 0xf0000\n#define DB_COUNT_CONTROL__SFAIL_ENABLE__SHIFT 0x10\n#define DB_COUNT_CONTROL__DBFAIL_ENABLE_MASK 0xf00000\n#define DB_COUNT_CONTROL__DBFAIL_ENABLE__SHIFT 0x14\n#define DB_COUNT_CONTROL__SLICE_EVEN_ENABLE_MASK 0xf000000\n#define DB_COUNT_CONTROL__SLICE_EVEN_ENABLE__SHIFT 0x18\n#define DB_COUNT_CONTROL__SLICE_ODD_ENABLE_MASK 0xf0000000\n#define DB_COUNT_CONTROL__SLICE_ODD_ENABLE__SHIFT 0x1c\n#define DB_RENDER_OVERRIDE__FORCE_HIZ_ENABLE_MASK 0x3\n#define DB_RENDER_OVERRIDE__FORCE_HIZ_ENABLE__SHIFT 0x0\n#define DB_RENDER_OVERRIDE__FORCE_HIS_ENABLE0_MASK 0xc\n#define DB_RENDER_OVERRIDE__FORCE_HIS_ENABLE0__SHIFT 0x2\n#define DB_RENDER_OVERRIDE__FORCE_HIS_ENABLE1_MASK 0x30\n#define DB_RENDER_OVERRIDE__FORCE_HIS_ENABLE1__SHIFT 0x4\n#define DB_RENDER_OVERRIDE__FORCE_SHADER_Z_ORDER_MASK 0x40\n#define DB_RENDER_OVERRIDE__FORCE_SHADER_Z_ORDER__SHIFT 0x6\n#define DB_RENDER_OVERRIDE__FAST_Z_DISABLE_MASK 0x80\n#define DB_RENDER_OVERRIDE__FAST_Z_DISABLE__SHIFT 0x7\n#define DB_RENDER_OVERRIDE__FAST_STENCIL_DISABLE_MASK 0x100\n#define DB_RENDER_OVERRIDE__FAST_STENCIL_DISABLE__SHIFT 0x8\n#define DB_RENDER_OVERRIDE__NOOP_CULL_DISABLE_MASK 0x200\n#define DB_RENDER_OVERRIDE__NOOP_CULL_DISABLE__SHIFT 0x9\n#define DB_RENDER_OVERRIDE__FORCE_COLOR_KILL_MASK 0x400\n#define DB_RENDER_OVERRIDE__FORCE_COLOR_KILL__SHIFT 0xa\n#define DB_RENDER_OVERRIDE__FORCE_Z_READ_MASK 0x800\n#define DB_RENDER_OVERRIDE__FORCE_Z_READ__SHIFT 0xb\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_READ_MASK 0x1000\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_READ__SHIFT 0xc\n#define DB_RENDER_OVERRIDE__FORCE_FULL_Z_RANGE_MASK 0x6000\n#define DB_RENDER_OVERRIDE__FORCE_FULL_Z_RANGE__SHIFT 0xd\n#define DB_RENDER_OVERRIDE__FORCE_QC_SMASK_CONFLICT_MASK 0x8000\n#define DB_RENDER_OVERRIDE__FORCE_QC_SMASK_CONFLICT__SHIFT 0xf\n#define DB_RENDER_OVERRIDE__DISABLE_VIEWPORT_CLAMP_MASK 0x10000\n#define DB_RENDER_OVERRIDE__DISABLE_VIEWPORT_CLAMP__SHIFT 0x10\n#define DB_RENDER_OVERRIDE__IGNORE_SC_ZRANGE_MASK 0x20000\n#define DB_RENDER_OVERRIDE__IGNORE_SC_ZRANGE__SHIFT 0x11\n#define DB_RENDER_OVERRIDE__DISABLE_FULLY_COVERED_MASK 0x40000\n#define DB_RENDER_OVERRIDE__DISABLE_FULLY_COVERED__SHIFT 0x12\n#define DB_RENDER_OVERRIDE__FORCE_Z_LIMIT_SUMM_MASK 0x180000\n#define DB_RENDER_OVERRIDE__FORCE_Z_LIMIT_SUMM__SHIFT 0x13\n#define DB_RENDER_OVERRIDE__MAX_TILES_IN_DTT_MASK 0x3e00000\n#define DB_RENDER_OVERRIDE__MAX_TILES_IN_DTT__SHIFT 0x15\n#define DB_RENDER_OVERRIDE__DISABLE_TILE_RATE_TILES_MASK 0x4000000\n#define DB_RENDER_OVERRIDE__DISABLE_TILE_RATE_TILES__SHIFT 0x1a\n#define DB_RENDER_OVERRIDE__FORCE_Z_DIRTY_MASK 0x8000000\n#define DB_RENDER_OVERRIDE__FORCE_Z_DIRTY__SHIFT 0x1b\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_DIRTY_MASK 0x10000000\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_DIRTY__SHIFT 0x1c\n#define DB_RENDER_OVERRIDE__FORCE_Z_VALID_MASK 0x20000000\n#define DB_RENDER_OVERRIDE__FORCE_Z_VALID__SHIFT 0x1d\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_VALID_MASK 0x40000000\n#define DB_RENDER_OVERRIDE__FORCE_STENCIL_VALID__SHIFT 0x1e\n#define DB_RENDER_OVERRIDE__PRESERVE_COMPRESSION_MASK 0x80000000\n#define DB_RENDER_OVERRIDE__PRESERVE_COMPRESSION__SHIFT 0x1f\n#define DB_RENDER_OVERRIDE2__PARTIAL_SQUAD_LAUNCH_CONTROL_MASK 0x3\n#define DB_RENDER_OVERRIDE2__PARTIAL_SQUAD_LAUNCH_CONTROL__SHIFT 0x0\n#define DB_RENDER_OVERRIDE2__PARTIAL_SQUAD_LAUNCH_COUNTDOWN_MASK 0x1c\n#define DB_RENDER_OVERRIDE2__PARTIAL_SQUAD_LAUNCH_COUNTDOWN__SHIFT 0x2\n#define DB_RENDER_OVERRIDE2__DISABLE_ZMASK_EXPCLEAR_OPTIMIZATION_MASK 0x20\n#define DB_RENDER_OVERRIDE2__DISABLE_ZMASK_EXPCLEAR_OPTIMIZATION__SHIFT 0x5\n#define DB_RENDER_OVERRIDE2__DISABLE_SMEM_EXPCLEAR_OPTIMIZATION_MASK 0x40\n#define DB_RENDER_OVERRIDE2__DISABLE_SMEM_EXPCLEAR_OPTIMIZATION__SHIFT 0x6\n#define DB_RENDER_OVERRIDE2__DISABLE_COLOR_ON_VALIDATION_MASK 0x80\n#define DB_RENDER_OVERRIDE2__DISABLE_COLOR_ON_VALIDATION__SHIFT 0x7\n#define DB_RENDER_OVERRIDE2__DECOMPRESS_Z_ON_FLUSH_MASK 0x100\n#define DB_RENDER_OVERRIDE2__DECOMPRESS_Z_ON_FLUSH__SHIFT 0x8\n#define DB_RENDER_OVERRIDE2__DISABLE_REG_SNOOP_MASK 0x200\n#define DB_RENDER_OVERRIDE2__DISABLE_REG_SNOOP__SHIFT 0x9\n#define DB_RENDER_OVERRIDE2__DEPTH_BOUNDS_HIER_DEPTH_DISABLE_MASK 0x400\n#define DB_RENDER_OVERRIDE2__DEPTH_BOUNDS_HIER_DEPTH_DISABLE__SHIFT 0xa\n#define DB_RENDER_OVERRIDE2__SEPARATE_HIZS_FUNC_ENABLE_MASK 0x800\n#define DB_RENDER_OVERRIDE2__SEPARATE_HIZS_FUNC_ENABLE__SHIFT 0xb\n#define DB_RENDER_OVERRIDE2__HIZ_ZFUNC_MASK 0x7000\n#define DB_RENDER_OVERRIDE2__HIZ_ZFUNC__SHIFT 0xc\n#define DB_RENDER_OVERRIDE2__HIS_SFUNC_FF_MASK 0x38000\n#define DB_RENDER_OVERRIDE2__HIS_SFUNC_FF__SHIFT 0xf\n#define DB_RENDER_OVERRIDE2__HIS_SFUNC_BF_MASK 0x1c0000\n#define DB_RENDER_OVERRIDE2__HIS_SFUNC_BF__SHIFT 0x12\n#define DB_RENDER_OVERRIDE2__PRESERVE_ZRANGE_MASK 0x200000\n#define DB_RENDER_OVERRIDE2__PRESERVE_ZRANGE__SHIFT 0x15\n#define DB_RENDER_OVERRIDE2__PRESERVE_SRESULTS_MASK 0x400000\n#define DB_RENDER_OVERRIDE2__PRESERVE_SRESULTS__SHIFT 0x16\n#define DB_RENDER_OVERRIDE2__DISABLE_FAST_PASS_MASK 0x800000\n#define DB_RENDER_OVERRIDE2__DISABLE_FAST_PASS__SHIFT 0x17\n#define DB_EQAA__MAX_ANCHOR_SAMPLES_MASK 0x7\n#define DB_EQAA__MAX_ANCHOR_SAMPLES__SHIFT 0x0\n#define DB_EQAA__PS_ITER_SAMPLES_MASK 0x70\n#define DB_EQAA__PS_ITER_SAMPLES__SHIFT 0x4\n#define DB_EQAA__MASK_EXPORT_NUM_SAMPLES_MASK 0x700\n#define DB_EQAA__MASK_EXPORT_NUM_SAMPLES__SHIFT 0x8\n#define DB_EQAA__ALPHA_TO_MASK_NUM_SAMPLES_MASK 0x7000\n#define DB_EQAA__ALPHA_TO_MASK_NUM_SAMPLES__SHIFT 0xc\n#define DB_EQAA__HIGH_QUALITY_INTERSECTIONS_MASK 0x10000\n#define DB_EQAA__HIGH_QUALITY_INTERSECTIONS__SHIFT 0x10\n#define DB_EQAA__INCOHERENT_EQAA_READS_MASK 0x20000\n#define DB_EQAA__INCOHERENT_EQAA_READS__SHIFT 0x11\n#define DB_EQAA__INTERPOLATE_COMP_Z_MASK 0x40000\n#define DB_EQAA__INTERPOLATE_COMP_Z__SHIFT 0x12\n#define DB_EQAA__INTERPOLATE_SRC_Z_MASK 0x80000\n#define DB_EQAA__INTERPOLATE_SRC_Z__SHIFT 0x13\n#define DB_EQAA__STATIC_ANCHOR_ASSOCIATIONS_MASK 0x100000\n#define DB_EQAA__STATIC_ANCHOR_ASSOCIATIONS__SHIFT 0x14\n#define DB_EQAA__ALPHA_TO_MASK_EQAA_DISABLE_MASK 0x200000\n#define DB_EQAA__ALPHA_TO_MASK_EQAA_DISABLE__SHIFT 0x15\n#define DB_EQAA__OVERRASTERIZATION_AMOUNT_MASK 0x7000000\n#define DB_EQAA__OVERRASTERIZATION_AMOUNT__SHIFT 0x18\n#define DB_EQAA__ENABLE_POSTZ_OVERRASTERIZATION_MASK 0x8000000\n#define DB_EQAA__ENABLE_POSTZ_OVERRASTERIZATION__SHIFT 0x1b\n#define DB_SHADER_CONTROL__Z_EXPORT_ENABLE_MASK 0x1\n#define DB_SHADER_CONTROL__Z_EXPORT_ENABLE__SHIFT 0x0\n#define DB_SHADER_CONTROL__STENCIL_TEST_VAL_EXPORT_ENABLE_MASK 0x2\n#define DB_SHADER_CONTROL__STENCIL_TEST_VAL_EXPORT_ENABLE__SHIFT 0x1\n#define DB_SHADER_CONTROL__STENCIL_OP_VAL_EXPORT_ENABLE_MASK 0x4\n#define DB_SHADER_CONTROL__STENCIL_OP_VAL_EXPORT_ENABLE__SHIFT 0x2\n#define DB_SHADER_CONTROL__Z_ORDER_MASK 0x30\n#define DB_SHADER_CONTROL__Z_ORDER__SHIFT 0x4\n#define DB_SHADER_CONTROL__KILL_ENABLE_MASK 0x40\n#define DB_SHADER_CONTROL__KILL_ENABLE__SHIFT 0x6\n#define DB_SHADER_CONTROL__COVERAGE_TO_MASK_ENABLE_MASK 0x80\n#define DB_SHADER_CONTROL__COVERAGE_TO_MASK_ENABLE__SHIFT 0x7\n#define DB_SHADER_CONTROL__MASK_EXPORT_ENABLE_MASK 0x100\n#define DB_SHADER_CONTROL__MASK_EXPORT_ENABLE__SHIFT 0x8\n#define DB_SHADER_CONTROL__EXEC_ON_HIER_FAIL_MASK 0x200\n#define DB_SHADER_CONTROL__EXEC_ON_HIER_FAIL__SHIFT 0x9\n#define DB_SHADER_CONTROL__EXEC_ON_NOOP_MASK 0x400\n#define DB_SHADER_CONTROL__EXEC_ON_NOOP__SHIFT 0xa\n#define DB_SHADER_CONTROL__ALPHA_TO_MASK_DISABLE_MASK 0x800\n#define DB_SHADER_CONTROL__ALPHA_TO_MASK_DISABLE__SHIFT 0xb\n#define DB_SHADER_CONTROL__DEPTH_BEFORE_SHADER_MASK 0x1000\n#define DB_SHADER_CONTROL__DEPTH_BEFORE_SHADER__SHIFT 0xc\n#define DB_SHADER_CONTROL__CONSERVATIVE_Z_EXPORT_MASK 0x6000\n#define DB_SHADER_CONTROL__CONSERVATIVE_Z_EXPORT__SHIFT 0xd\n#define DB_DEPTH_BOUNDS_MIN__MIN_MASK 0xffffffff\n#define DB_DEPTH_BOUNDS_MIN__MIN__SHIFT 0x0\n#define DB_DEPTH_BOUNDS_MAX__MAX_MASK 0xffffffff\n#define DB_DEPTH_BOUNDS_MAX__MAX__SHIFT 0x0\n#define DB_STENCIL_CLEAR__CLEAR_MASK 0xff\n#define DB_STENCIL_CLEAR__CLEAR__SHIFT 0x0\n#define DB_DEPTH_CLEAR__DEPTH_CLEAR_MASK 0xffffffff\n#define DB_DEPTH_CLEAR__DEPTH_CLEAR__SHIFT 0x0\n#define DB_HTILE_DATA_BASE__BASE_256B_MASK 0xffffffff\n#define DB_HTILE_DATA_BASE__BASE_256B__SHIFT 0x0\n#define DB_HTILE_SURFACE__LINEAR_MASK 0x1\n#define DB_HTILE_SURFACE__LINEAR__SHIFT 0x0\n#define DB_HTILE_SURFACE__FULL_CACHE_MASK 0x2\n#define DB_HTILE_SURFACE__FULL_CACHE__SHIFT 0x1\n#define DB_HTILE_SURFACE__HTILE_USES_PRELOAD_WIN_MASK 0x4\n#define DB_HTILE_SURFACE__HTILE_USES_PRELOAD_WIN__SHIFT 0x2\n#define DB_HTILE_SURFACE__PRELOAD_MASK 0x8\n#define DB_HTILE_SURFACE__PRELOAD__SHIFT 0x3\n#define DB_HTILE_SURFACE__PREFETCH_WIDTH_MASK 0x3f0\n#define DB_HTILE_SURFACE__PREFETCH_WIDTH__SHIFT 0x4\n#define DB_HTILE_SURFACE__PREFETCH_HEIGHT_MASK 0xfc00\n#define DB_HTILE_SURFACE__PREFETCH_HEIGHT__SHIFT 0xa\n#define DB_HTILE_SURFACE__DST_OUTSIDE_ZERO_TO_ONE_MASK 0x10000\n#define DB_HTILE_SURFACE__DST_OUTSIDE_ZERO_TO_ONE__SHIFT 0x10\n#define DB_PRELOAD_CONTROL__START_X_MASK 0xff\n#define DB_PRELOAD_CONTROL__START_X__SHIFT 0x0\n#define DB_PRELOAD_CONTROL__START_Y_MASK 0xff00\n#define DB_PRELOAD_CONTROL__START_Y__SHIFT 0x8\n#define DB_PRELOAD_CONTROL__MAX_X_MASK 0xff0000\n#define DB_PRELOAD_CONTROL__MAX_X__SHIFT 0x10\n#define DB_PRELOAD_CONTROL__MAX_Y_MASK 0xff000000\n#define DB_PRELOAD_CONTROL__MAX_Y__SHIFT 0x18\n#define DB_STENCILREFMASK__STENCILTESTVAL_MASK 0xff\n#define DB_STENCILREFMASK__STENCILTESTVAL__SHIFT 0x0\n#define DB_STENCILREFMASK__STENCILMASK_MASK 0xff00\n#define DB_STENCILREFMASK__STENCILMASK__SHIFT 0x8\n#define DB_STENCILREFMASK__STENCILWRITEMASK_MASK 0xff0000\n#define DB_STENCILREFMASK__STENCILWRITEMASK__SHIFT 0x10\n#define DB_STENCILREFMASK__STENCILOPVAL_MASK 0xff000000\n#define DB_STENCILREFMASK__STENCILOPVAL__SHIFT 0x18\n#define DB_STENCILREFMASK_BF__STENCILTESTVAL_BF_MASK 0xff\n#define DB_STENCILREFMASK_BF__STENCILTESTVAL_BF__SHIFT 0x0\n#define DB_STENCILREFMASK_BF__STENCILMASK_BF_MASK 0xff00\n#define DB_STENCILREFMASK_BF__STENCILMASK_BF__SHIFT 0x8\n#define DB_STENCILREFMASK_BF__STENCILWRITEMASK_BF_MASK 0xff0000\n#define DB_STENCILREFMASK_BF__STENCILWRITEMASK_BF__SHIFT 0x10\n#define DB_STENCILREFMASK_BF__STENCILOPVAL_BF_MASK 0xff000000\n#define DB_STENCILREFMASK_BF__STENCILOPVAL_BF__SHIFT 0x18\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREFUNC0_MASK 0x7\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREFUNC0__SHIFT 0x0\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREVALUE0_MASK 0xff0\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREVALUE0__SHIFT 0x4\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREMASK0_MASK 0xff000\n#define DB_SRESULTS_COMPARE_STATE0__COMPAREMASK0__SHIFT 0xc\n#define DB_SRESULTS_COMPARE_STATE0__ENABLE0_MASK 0x1000000\n#define DB_SRESULTS_COMPARE_STATE0__ENABLE0__SHIFT 0x18\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREFUNC1_MASK 0x7\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREFUNC1__SHIFT 0x0\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREVALUE1_MASK 0xff0\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREVALUE1__SHIFT 0x4\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREMASK1_MASK 0xff000\n#define DB_SRESULTS_COMPARE_STATE1__COMPAREMASK1__SHIFT 0xc\n#define DB_SRESULTS_COMPARE_STATE1__ENABLE1_MASK 0x1000000\n#define DB_SRESULTS_COMPARE_STATE1__ENABLE1__SHIFT 0x18\n#define DB_DEPTH_CONTROL__STENCIL_ENABLE_MASK 0x1\n#define DB_DEPTH_CONTROL__STENCIL_ENABLE__SHIFT 0x0\n#define DB_DEPTH_CONTROL__Z_ENABLE_MASK 0x2\n#define DB_DEPTH_CONTROL__Z_ENABLE__SHIFT 0x1\n#define DB_DEPTH_CONTROL__Z_WRITE_ENABLE_MASK 0x4\n#define DB_DEPTH_CONTROL__Z_WRITE_ENABLE__SHIFT 0x2\n#define DB_DEPTH_CONTROL__DEPTH_BOUNDS_ENABLE_MASK 0x8\n#define DB_DEPTH_CONTROL__DEPTH_BOUNDS_ENABLE__SHIFT 0x3\n#define DB_DEPTH_CONTROL__ZFUNC_MASK 0x70\n#define DB_DEPTH_CONTROL__ZFUNC__SHIFT 0x4\n#define DB_DEPTH_CONTROL__BACKFACE_ENABLE_MASK 0x80\n#define DB_DEPTH_CONTROL__BACKFACE_ENABLE__SHIFT 0x7\n#define DB_DEPTH_CONTROL__STENCILFUNC_MASK 0x700\n#define DB_DEPTH_CONTROL__STENCILFUNC__SHIFT 0x8\n#define DB_DEPTH_CONTROL__STENCILFUNC_BF_MASK 0x700000\n#define DB_DEPTH_CONTROL__STENCILFUNC_BF__SHIFT 0x14\n#define DB_DEPTH_CONTROL__ENABLE_COLOR_WRITES_ON_DEPTH_FAIL_MASK 0x40000000\n#define DB_DEPTH_CONTROL__ENABLE_COLOR_WRITES_ON_DEPTH_FAIL__SHIFT 0x1e\n#define DB_DEPTH_CONTROL__DISABLE_COLOR_WRITES_ON_DEPTH_PASS_MASK 0x80000000\n#define DB_DEPTH_CONTROL__DISABLE_COLOR_WRITES_ON_DEPTH_PASS__SHIFT 0x1f\n#define DB_STENCIL_CONTROL__STENCILFAIL_MASK 0xf\n#define DB_STENCIL_CONTROL__STENCILFAIL__SHIFT 0x0\n#define DB_STENCIL_CONTROL__STENCILZPASS_MASK 0xf0\n#define DB_STENCIL_CONTROL__STENCILZPASS__SHIFT 0x4\n#define DB_STENCIL_CONTROL__STENCILZFAIL_MASK 0xf00\n#define DB_STENCIL_CONTROL__STENCILZFAIL__SHIFT 0x8\n#define DB_STENCIL_CONTROL__STENCILFAIL_BF_MASK 0xf000\n#define DB_STENCIL_CONTROL__STENCILFAIL_BF__SHIFT 0xc\n#define DB_STENCIL_CONTROL__STENCILZPASS_BF_MASK 0xf0000\n#define DB_STENCIL_CONTROL__STENCILZPASS_BF__SHIFT 0x10\n#define DB_STENCIL_CONTROL__STENCILZFAIL_BF_MASK 0xf00000\n#define DB_STENCIL_CONTROL__STENCILZFAIL_BF__SHIFT 0x14\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_ENABLE_MASK 0x1\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_ENABLE__SHIFT 0x0\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET0_MASK 0x300\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET0__SHIFT 0x8\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET1_MASK 0xc00\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET1__SHIFT 0xa\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET2_MASK 0x3000\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET2__SHIFT 0xc\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET3_MASK 0xc000\n#define DB_ALPHA_TO_MASK__ALPHA_TO_MASK_OFFSET3__SHIFT 0xe\n#define DB_ALPHA_TO_MASK__OFFSET_ROUND_MASK 0x10000\n#define DB_ALPHA_TO_MASK__OFFSET_ROUND__SHIFT 0x10\n#define DB_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define DB_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define DB_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define DB_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define DB_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define DB_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define DB_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define DB_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define DB_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define DB_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define DB_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define DB_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define DB_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define DB_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define DB_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define DB_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define DB_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define DB_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define DB_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define DB_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define DB_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define DB_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define DB_PERFCOUNTER2_SELECT__PERF_SEL1_MASK 0xffc00\n#define DB_PERFCOUNTER2_SELECT__PERF_SEL1__SHIFT 0xa\n#define DB_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define DB_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define DB_PERFCOUNTER2_SELECT__PERF_MODE1_MASK 0xf000000\n#define DB_PERFCOUNTER2_SELECT__PERF_MODE1__SHIFT 0x18\n#define DB_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define DB_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define DB_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define DB_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define DB_PERFCOUNTER3_SELECT__PERF_SEL1_MASK 0xffc00\n#define DB_PERFCOUNTER3_SELECT__PERF_SEL1__SHIFT 0xa\n#define DB_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define DB_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define DB_PERFCOUNTER3_SELECT__PERF_MODE1_MASK 0xf000000\n#define DB_PERFCOUNTER3_SELECT__PERF_MODE1__SHIFT 0x18\n#define DB_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define DB_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define DB_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define DB_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define DB_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define DB_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define DB_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define DB_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define DB_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define DB_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define DB_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define DB_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define DB_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define DB_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define DB_PERFCOUNTER1_SELECT1__PERF_MODE3_MASK 0xf000000\n#define DB_PERFCOUNTER1_SELECT1__PERF_MODE3__SHIFT 0x18\n#define DB_PERFCOUNTER1_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define DB_PERFCOUNTER1_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define DB_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define DB_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define DB_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define DB_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define DB_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define DB_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define DB_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define DB_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define DB_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define DB_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define DB_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define DB_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define DB_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define DB_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define DB_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define DB_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define DB_DEBUG__DEBUG_STENCIL_COMPRESS_DISABLE_MASK 0x1\n#define DB_DEBUG__DEBUG_STENCIL_COMPRESS_DISABLE__SHIFT 0x0\n#define DB_DEBUG__DEBUG_DEPTH_COMPRESS_DISABLE_MASK 0x2\n#define DB_DEBUG__DEBUG_DEPTH_COMPRESS_DISABLE__SHIFT 0x1\n#define DB_DEBUG__FETCH_FULL_Z_TILE_MASK 0x4\n#define DB_DEBUG__FETCH_FULL_Z_TILE__SHIFT 0x2\n#define DB_DEBUG__FETCH_FULL_STENCIL_TILE_MASK 0x8\n#define DB_DEBUG__FETCH_FULL_STENCIL_TILE__SHIFT 0x3\n#define DB_DEBUG__FORCE_Z_MODE_MASK 0x30\n#define DB_DEBUG__FORCE_Z_MODE__SHIFT 0x4\n#define DB_DEBUG__DEBUG_FORCE_DEPTH_READ_MASK 0x40\n#define DB_DEBUG__DEBUG_FORCE_DEPTH_READ__SHIFT 0x6\n#define DB_DEBUG__DEBUG_FORCE_STENCIL_READ_MASK 0x80\n#define DB_DEBUG__DEBUG_FORCE_STENCIL_READ__SHIFT 0x7\n#define DB_DEBUG__DEBUG_FORCE_HIZ_ENABLE_MASK 0x300\n#define DB_DEBUG__DEBUG_FORCE_HIZ_ENABLE__SHIFT 0x8\n#define DB_DEBUG__DEBUG_FORCE_HIS_ENABLE0_MASK 0xc00\n#define DB_DEBUG__DEBUG_FORCE_HIS_ENABLE0__SHIFT 0xa\n#define DB_DEBUG__DEBUG_FORCE_HIS_ENABLE1_MASK 0x3000\n#define DB_DEBUG__DEBUG_FORCE_HIS_ENABLE1__SHIFT 0xc\n#define DB_DEBUG__DEBUG_FAST_Z_DISABLE_MASK 0x4000\n#define DB_DEBUG__DEBUG_FAST_Z_DISABLE__SHIFT 0xe\n#define DB_DEBUG__DEBUG_FAST_STENCIL_DISABLE_MASK 0x8000\n#define DB_DEBUG__DEBUG_FAST_STENCIL_DISABLE__SHIFT 0xf\n#define DB_DEBUG__DEBUG_NOOP_CULL_DISABLE_MASK 0x10000\n#define DB_DEBUG__DEBUG_NOOP_CULL_DISABLE__SHIFT 0x10\n#define DB_DEBUG__DISABLE_SUMM_SQUADS_MASK 0x20000\n#define DB_DEBUG__DISABLE_SUMM_SQUADS__SHIFT 0x11\n#define DB_DEBUG__DEPTH_CACHE_FORCE_MISS_MASK 0x40000\n#define DB_DEBUG__DEPTH_CACHE_FORCE_MISS__SHIFT 0x12\n#define DB_DEBUG__DEBUG_FORCE_FULL_Z_RANGE_MASK 0x180000\n#define DB_DEBUG__DEBUG_FORCE_FULL_Z_RANGE__SHIFT 0x13\n#define DB_DEBUG__NEVER_FREE_Z_ONLY_MASK 0x200000\n#define DB_DEBUG__NEVER_FREE_Z_ONLY__SHIFT 0x15\n#define DB_DEBUG__ZPASS_COUNTS_LOOK_AT_PIPE_STAT_EVENTS_MASK 0x400000\n#define DB_DEBUG__ZPASS_COUNTS_LOOK_AT_PIPE_STAT_EVENTS__SHIFT 0x16\n#define DB_DEBUG__DISABLE_VPORT_ZPLANE_OPTIMIZATION_MASK 0x800000\n#define DB_DEBUG__DISABLE_VPORT_ZPLANE_OPTIMIZATION__SHIFT 0x17\n#define DB_DEBUG__DECOMPRESS_AFTER_N_ZPLANES_MASK 0xf000000\n#define DB_DEBUG__DECOMPRESS_AFTER_N_ZPLANES__SHIFT 0x18\n#define DB_DEBUG__ONE_FREE_IN_FLIGHT_MASK 0x10000000\n#define DB_DEBUG__ONE_FREE_IN_FLIGHT__SHIFT 0x1c\n#define DB_DEBUG__FORCE_MISS_IF_NOT_INFLIGHT_MASK 0x20000000\n#define DB_DEBUG__FORCE_MISS_IF_NOT_INFLIGHT__SHIFT 0x1d\n#define DB_DEBUG__DISABLE_DEPTH_SURFACE_SYNC_MASK 0x40000000\n#define DB_DEBUG__DISABLE_DEPTH_SURFACE_SYNC__SHIFT 0x1e\n#define DB_DEBUG__DISABLE_HTILE_SURFACE_SYNC_MASK 0x80000000\n#define DB_DEBUG__DISABLE_HTILE_SURFACE_SYNC__SHIFT 0x1f\n#define DB_DEBUG2__ALLOW_COMPZ_BYTE_MASKING_MASK 0x1\n#define DB_DEBUG2__ALLOW_COMPZ_BYTE_MASKING__SHIFT 0x0\n#define DB_DEBUG2__DISABLE_TC_ZRANGE_L0_CACHE_MASK 0x2\n#define DB_DEBUG2__DISABLE_TC_ZRANGE_L0_CACHE__SHIFT 0x1\n#define DB_DEBUG2__DISABLE_TC_MASK_L0_CACHE_MASK 0x4\n#define DB_DEBUG2__DISABLE_TC_MASK_L0_CACHE__SHIFT 0x2\n#define DB_DEBUG2__DTR_ROUND_ROBIN_ARB_MASK 0x8\n#define DB_DEBUG2__DTR_ROUND_ROBIN_ARB__SHIFT 0x3\n#define DB_DEBUG2__DTR_PREZ_STALLS_FOR_ETF_ROOM_MASK 0x10\n#define DB_DEBUG2__DTR_PREZ_STALLS_FOR_ETF_ROOM__SHIFT 0x4\n#define DB_DEBUG2__DISABLE_PREZL_LPF_STALL_MASK 0x20\n#define DB_DEBUG2__DISABLE_PREZL_LPF_STALL__SHIFT 0x5\n#define DB_DEBUG2__ENABLE_PREZL_CB_STALL_MASK 0x40\n#define DB_DEBUG2__ENABLE_PREZL_CB_STALL__SHIFT 0x6\n#define DB_DEBUG2__DISABLE_PREZL_LPF_STALL_REZ_MASK 0x80\n#define DB_DEBUG2__DISABLE_PREZL_LPF_STALL_REZ__SHIFT 0x7\n#define DB_DEBUG2__DISABLE_PREZL_CB_STALL_REZ_MASK 0x100\n#define DB_DEBUG2__DISABLE_PREZL_CB_STALL_REZ__SHIFT 0x8\n#define DB_DEBUG2__CLK_OFF_DELAY_MASK 0x3e00\n#define DB_DEBUG2__CLK_OFF_DELAY__SHIFT 0x9\n#define DB_DEBUG2__DISABLE_TILE_COVERED_FOR_PS_ITER_MASK 0x4000\n#define DB_DEBUG2__DISABLE_TILE_COVERED_FOR_PS_ITER__SHIFT 0xe\n#define DB_DEBUG2__ENABLE_SUBTILE_GROUPING_MASK 0x8000\n#define DB_DEBUG2__ENABLE_SUBTILE_GROUPING__SHIFT 0xf\n#define DB_DEBUG2__DISABLE_HTILE_PAIRED_PIPES_MASK 0x10000\n#define DB_DEBUG2__DISABLE_HTILE_PAIRED_PIPES__SHIFT 0x10\n#define DB_DEBUG2__DISABLE_NULL_EOT_FORWARDING_MASK 0x20000\n#define DB_DEBUG2__DISABLE_NULL_EOT_FORWARDING__SHIFT 0x11\n#define DB_DEBUG2__DISABLE_DTT_DATA_FORWARDING_MASK 0x40000\n#define DB_DEBUG2__DISABLE_DTT_DATA_FORWARDING__SHIFT 0x12\n#define DB_DEBUG2__DISABLE_QUAD_COHERENCY_STALL_MASK 0x80000\n#define DB_DEBUG2__DISABLE_QUAD_COHERENCY_STALL__SHIFT 0x13\n#define DB_DEBUG2__ENABLE_PREZ_OF_REZ_SUMM_MASK 0x10000000\n#define DB_DEBUG2__ENABLE_PREZ_OF_REZ_SUMM__SHIFT 0x1c\n#define DB_DEBUG2__DISABLE_PREZL_VIEWPORT_STALL_MASK 0x20000000\n#define DB_DEBUG2__DISABLE_PREZL_VIEWPORT_STALL__SHIFT 0x1d\n#define DB_DEBUG2__DISABLE_SINGLE_STENCIL_QUAD_SUMM_MASK 0x40000000\n#define DB_DEBUG2__DISABLE_SINGLE_STENCIL_QUAD_SUMM__SHIFT 0x1e\n#define DB_DEBUG2__DISABLE_WRITE_STALL_ON_RDWR_CONFLICT_MASK 0x80000000\n#define DB_DEBUG2__DISABLE_WRITE_STALL_ON_RDWR_CONFLICT__SHIFT 0x1f\n#define DB_DEBUG3__FORCE_DB_IS_GOOD_MASK 0x4\n#define DB_DEBUG3__FORCE_DB_IS_GOOD__SHIFT 0x2\n#define DB_DEBUG3__DISABLE_TL_SSO_NULL_SUPPRESSION_MASK 0x8\n#define DB_DEBUG3__DISABLE_TL_SSO_NULL_SUPPRESSION__SHIFT 0x3\n#define DB_DEBUG3__DISABLE_HIZ_ON_VPORT_CLAMP_MASK 0x10\n#define DB_DEBUG3__DISABLE_HIZ_ON_VPORT_CLAMP__SHIFT 0x4\n#define DB_DEBUG3__EQAA_INTERPOLATE_COMP_Z_MASK 0x20\n#define DB_DEBUG3__EQAA_INTERPOLATE_COMP_Z__SHIFT 0x5\n#define DB_DEBUG3__EQAA_INTERPOLATE_SRC_Z_MASK 0x40\n#define DB_DEBUG3__EQAA_INTERPOLATE_SRC_Z__SHIFT 0x6\n#define DB_DEBUG3__DISABLE_TCP_CAM_BYPASS_MASK 0x80\n#define DB_DEBUG3__DISABLE_TCP_CAM_BYPASS__SHIFT 0x7\n#define DB_DEBUG3__DISABLE_ZCMP_DIRTY_SUPPRESSION_MASK 0x100\n#define DB_DEBUG3__DISABLE_ZCMP_DIRTY_SUPPRESSION__SHIFT 0x8\n#define DB_DEBUG3__DISABLE_REDUNDANT_PLANE_FLUSHES_OPT_MASK 0x200\n#define DB_DEBUG3__DISABLE_REDUNDANT_PLANE_FLUSHES_OPT__SHIFT 0x9\n#define DB_DEBUG3__DISABLE_RECOMP_TO_1ZPLANE_WITHOUT_FASTOP_MASK 0x400\n#define DB_DEBUG3__DISABLE_RECOMP_TO_1ZPLANE_WITHOUT_FASTOP__SHIFT 0xa\n#define DB_DEBUG3__ENABLE_INCOHERENT_EQAA_READS_MASK 0x800\n#define DB_DEBUG3__ENABLE_INCOHERENT_EQAA_READS__SHIFT 0xb\n#define DB_DEBUG3__DISABLE_OP_Z_DATA_FORWARDING_MASK 0x1000\n#define DB_DEBUG3__DISABLE_OP_Z_DATA_FORWARDING__SHIFT 0xc\n#define DB_DEBUG3__DISABLE_OP_DF_BYPASS_MASK 0x2000\n#define DB_DEBUG3__DISABLE_OP_DF_BYPASS__SHIFT 0xd\n#define DB_DEBUG3__DISABLE_OP_DF_WRITE_COMBINE_MASK 0x4000\n#define DB_DEBUG3__DISABLE_OP_DF_WRITE_COMBINE__SHIFT 0xe\n#define DB_DEBUG3__DISABLE_OP_DF_DIRECT_FEEDBACK_MASK 0x8000\n#define DB_DEBUG3__DISABLE_OP_DF_DIRECT_FEEDBACK__SHIFT 0xf\n#define DB_DEBUG3__ALLOW_RF2P_RW_COLLISION_MASK 0x10000\n#define DB_DEBUG3__ALLOW_RF2P_RW_COLLISION__SHIFT 0x10\n#define DB_DEBUG3__SLOW_PREZ_TO_A2M_OMASK_RATE_MASK 0x20000\n#define DB_DEBUG3__SLOW_PREZ_TO_A2M_OMASK_RATE__SHIFT 0x11\n#define DB_DEBUG3__DISABLE_OP_S_DATA_FORWARDING_MASK 0x40000\n#define DB_DEBUG3__DISABLE_OP_S_DATA_FORWARDING__SHIFT 0x12\n#define DB_DEBUG3__DISABLE_TC_UPDATE_WRITE_COMBINE_MASK 0x80000\n#define DB_DEBUG3__DISABLE_TC_UPDATE_WRITE_COMBINE__SHIFT 0x13\n#define DB_DEBUG3__DISABLE_HZ_TC_WRITE_COMBINE_MASK 0x100000\n#define DB_DEBUG3__DISABLE_HZ_TC_WRITE_COMBINE__SHIFT 0x14\n#define DB_DEBUG3__ENABLE_RECOMP_ZDIRTY_SUPPRESSION_OPT_MASK 0x200000\n#define DB_DEBUG3__ENABLE_RECOMP_ZDIRTY_SUPPRESSION_OPT__SHIFT 0x15\n#define DB_DEBUG3__ENABLE_TC_MA_ROUND_ROBIN_ARB_MASK 0x400000\n#define DB_DEBUG3__ENABLE_TC_MA_ROUND_ROBIN_ARB__SHIFT 0x16\n#define DB_DEBUG3__DISABLE_RAM_READ_SUPPRESION_ON_FWD_MASK 0x800000\n#define DB_DEBUG3__DISABLE_RAM_READ_SUPPRESION_ON_FWD__SHIFT 0x17\n#define DB_DEBUG3__DISABLE_EQAA_A2M_PERF_OPT_MASK 0x1000000\n#define DB_DEBUG3__DISABLE_EQAA_A2M_PERF_OPT__SHIFT 0x18\n#define DB_DEBUG3__DISABLE_DI_DT_STALL_MASK 0x2000000\n#define DB_DEBUG3__DISABLE_DI_DT_STALL__SHIFT 0x19\n#define DB_DEBUG3__ENABLE_DB_PROCESS_RESET_MASK 0x4000000\n#define DB_DEBUG3__ENABLE_DB_PROCESS_RESET__SHIFT 0x1a\n#define DB_DEBUG3__DISABLE_OVERRASTERIZATION_FIX_MASK 0x8000000\n#define DB_DEBUG3__DISABLE_OVERRASTERIZATION_FIX__SHIFT 0x1b\n#define DB_DEBUG3__DONT_INSERT_CONTEXT_SUSPEND_MASK 0x10000000\n#define DB_DEBUG3__DONT_INSERT_CONTEXT_SUSPEND__SHIFT 0x1c\n#define DB_DEBUG3__DONT_DELETE_CONTEXT_SUSPEND_MASK 0x20000000\n#define DB_DEBUG3__DONT_DELETE_CONTEXT_SUSPEND__SHIFT 0x1d\n#define DB_DEBUG3__DB_EXTRA_DEBUG3_MASK 0xc0000000\n#define DB_DEBUG3__DB_EXTRA_DEBUG3__SHIFT 0x1e\n#define DB_DEBUG4__DISABLE_QC_Z_MASK_SUMMATION_MASK 0x1\n#define DB_DEBUG4__DISABLE_QC_Z_MASK_SUMMATION__SHIFT 0x0\n#define DB_DEBUG4__DISABLE_QC_STENCIL_MASK_SUMMATION_MASK 0x2\n#define DB_DEBUG4__DISABLE_QC_STENCIL_MASK_SUMMATION__SHIFT 0x1\n#define DB_DEBUG4__DISABLE_RESUMM_TO_SINGLE_STENCIL_MASK 0x4\n#define DB_DEBUG4__DISABLE_RESUMM_TO_SINGLE_STENCIL__SHIFT 0x2\n#define DB_DEBUG4__DISABLE_PREZ_POSTZ_DTILE_CONFLICT_STALL_MASK 0x8\n#define DB_DEBUG4__DISABLE_PREZ_POSTZ_DTILE_CONFLICT_STALL__SHIFT 0x3\n#define DB_DEBUG4__DB_EXTRA_DEBUG4_MASK 0xfffffff0\n#define DB_DEBUG4__DB_EXTRA_DEBUG4__SHIFT 0x4\n#define DB_CREDIT_LIMIT__DB_SC_TILE_CREDITS_MASK 0x1f\n#define DB_CREDIT_LIMIT__DB_SC_TILE_CREDITS__SHIFT 0x0\n#define DB_CREDIT_LIMIT__DB_SC_QUAD_CREDITS_MASK 0x3e0\n#define DB_CREDIT_LIMIT__DB_SC_QUAD_CREDITS__SHIFT 0x5\n#define DB_CREDIT_LIMIT__DB_CB_LQUAD_CREDITS_MASK 0x1c00\n#define DB_CREDIT_LIMIT__DB_CB_LQUAD_CREDITS__SHIFT 0xa\n#define DB_CREDIT_LIMIT__DB_CB_TILE_CREDITS_MASK 0x7f000000\n#define DB_CREDIT_LIMIT__DB_CB_TILE_CREDITS__SHIFT 0x18\n#define DB_WATERMARKS__DEPTH_FREE_MASK 0x1f\n#define DB_WATERMARKS__DEPTH_FREE__SHIFT 0x0\n#define DB_WATERMARKS__DEPTH_FLUSH_MASK 0x7e0\n#define DB_WATERMARKS__DEPTH_FLUSH__SHIFT 0x5\n#define DB_WATERMARKS__FORCE_SUMMARIZE_MASK 0x7800\n#define DB_WATERMARKS__FORCE_SUMMARIZE__SHIFT 0xb\n#define DB_WATERMARKS__DEPTH_PENDING_FREE_MASK 0xf8000\n#define DB_WATERMARKS__DEPTH_PENDING_FREE__SHIFT 0xf\n#define DB_WATERMARKS__DEPTH_CACHELINE_FREE_MASK 0x7f00000\n#define DB_WATERMARKS__DEPTH_CACHELINE_FREE__SHIFT 0x14\n#define DB_WATERMARKS__EARLY_Z_PANIC_DISABLE_MASK 0x8000000\n#define DB_WATERMARKS__EARLY_Z_PANIC_DISABLE__SHIFT 0x1b\n#define DB_WATERMARKS__LATE_Z_PANIC_DISABLE_MASK 0x10000000\n#define DB_WATERMARKS__LATE_Z_PANIC_DISABLE__SHIFT 0x1c\n#define DB_WATERMARKS__RE_Z_PANIC_DISABLE_MASK 0x20000000\n#define DB_WATERMARKS__RE_Z_PANIC_DISABLE__SHIFT 0x1d\n#define DB_WATERMARKS__AUTO_FLUSH_HTILE_MASK 0x40000000\n#define DB_WATERMARKS__AUTO_FLUSH_HTILE__SHIFT 0x1e\n#define DB_WATERMARKS__AUTO_FLUSH_QUAD_MASK 0x80000000\n#define DB_WATERMARKS__AUTO_FLUSH_QUAD__SHIFT 0x1f\n#define DB_SUBTILE_CONTROL__MSAA1_X_MASK 0x3\n#define DB_SUBTILE_CONTROL__MSAA1_X__SHIFT 0x0\n#define DB_SUBTILE_CONTROL__MSAA1_Y_MASK 0xc\n#define DB_SUBTILE_CONTROL__MSAA1_Y__SHIFT 0x2\n#define DB_SUBTILE_CONTROL__MSAA2_X_MASK 0x30\n#define DB_SUBTILE_CONTROL__MSAA2_X__SHIFT 0x4\n#define DB_SUBTILE_CONTROL__MSAA2_Y_MASK 0xc0\n#define DB_SUBTILE_CONTROL__MSAA2_Y__SHIFT 0x6\n#define DB_SUBTILE_CONTROL__MSAA4_X_MASK 0x300\n#define DB_SUBTILE_CONTROL__MSAA4_X__SHIFT 0x8\n#define DB_SUBTILE_CONTROL__MSAA4_Y_MASK 0xc00\n#define DB_SUBTILE_CONTROL__MSAA4_Y__SHIFT 0xa\n#define DB_SUBTILE_CONTROL__MSAA8_X_MASK 0x3000\n#define DB_SUBTILE_CONTROL__MSAA8_X__SHIFT 0xc\n#define DB_SUBTILE_CONTROL__MSAA8_Y_MASK 0xc000\n#define DB_SUBTILE_CONTROL__MSAA8_Y__SHIFT 0xe\n#define DB_SUBTILE_CONTROL__MSAA16_X_MASK 0x30000\n#define DB_SUBTILE_CONTROL__MSAA16_X__SHIFT 0x10\n#define DB_SUBTILE_CONTROL__MSAA16_Y_MASK 0xc0000\n#define DB_SUBTILE_CONTROL__MSAA16_Y__SHIFT 0x12\n#define DB_FREE_CACHELINES__FREE_DTILE_DEPTH_MASK 0x7f\n#define DB_FREE_CACHELINES__FREE_DTILE_DEPTH__SHIFT 0x0\n#define DB_FREE_CACHELINES__FREE_PLANE_DEPTH_MASK 0x3f80\n#define DB_FREE_CACHELINES__FREE_PLANE_DEPTH__SHIFT 0x7\n#define DB_FREE_CACHELINES__FREE_Z_DEPTH_MASK 0x1fc000\n#define DB_FREE_CACHELINES__FREE_Z_DEPTH__SHIFT 0xe\n#define DB_FREE_CACHELINES__FREE_HTILE_DEPTH_MASK 0x1e00000\n#define DB_FREE_CACHELINES__FREE_HTILE_DEPTH__SHIFT 0x15\n#define DB_FREE_CACHELINES__QUAD_READ_REQS_MASK 0xfe000000\n#define DB_FREE_CACHELINES__QUAD_READ_REQS__SHIFT 0x19\n#define DB_FIFO_DEPTH1__MI_RDREQ_FIFO_DEPTH_MASK 0x1f\n#define DB_FIFO_DEPTH1__MI_RDREQ_FIFO_DEPTH__SHIFT 0x0\n#define DB_FIFO_DEPTH1__MI_WRREQ_FIFO_DEPTH_MASK 0x3e0\n#define DB_FIFO_DEPTH1__MI_WRREQ_FIFO_DEPTH__SHIFT 0x5\n#define DB_FIFO_DEPTH1__MCC_DEPTH_MASK 0xfc00\n#define DB_FIFO_DEPTH1__MCC_DEPTH__SHIFT 0xa\n#define DB_FIFO_DEPTH1__QC_DEPTH_MASK 0x1f0000\n#define DB_FIFO_DEPTH1__QC_DEPTH__SHIFT 0x10\n#define DB_FIFO_DEPTH1__LTILE_PROBE_FIFO_DEPTH_MASK 0x1fe00000\n#define DB_FIFO_DEPTH1__LTILE_PROBE_FIFO_DEPTH__SHIFT 0x15\n#define DB_FIFO_DEPTH2__EQUAD_FIFO_DEPTH_MASK 0xff\n#define DB_FIFO_DEPTH2__EQUAD_FIFO_DEPTH__SHIFT 0x0\n#define DB_FIFO_DEPTH2__ETILE_OP_FIFO_DEPTH_MASK 0x7f00\n#define DB_FIFO_DEPTH2__ETILE_OP_FIFO_DEPTH__SHIFT 0x8\n#define DB_FIFO_DEPTH2__LQUAD_FIFO_DEPTH_MASK 0x1ff8000\n#define DB_FIFO_DEPTH2__LQUAD_FIFO_DEPTH__SHIFT 0xf\n#define DB_FIFO_DEPTH2__LTILE_OP_FIFO_DEPTH_MASK 0xfe000000\n#define DB_FIFO_DEPTH2__LTILE_OP_FIFO_DEPTH__SHIFT 0x19\n#define DB_CGTT_CLK_CTRL_0__ON_DELAY_MASK 0xf\n#define DB_CGTT_CLK_CTRL_0__ON_DELAY__SHIFT 0x0\n#define DB_CGTT_CLK_CTRL_0__OFF_HYSTERESIS_MASK 0xff0\n#define DB_CGTT_CLK_CTRL_0__OFF_HYSTERESIS__SHIFT 0x4\n#define DB_CGTT_CLK_CTRL_0__RESERVED_MASK 0xfff000\n#define DB_CGTT_CLK_CTRL_0__RESERVED__SHIFT 0xc\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE7_MASK 0x1000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE7__SHIFT 0x18\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE6_MASK 0x2000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE6__SHIFT 0x19\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE5_MASK 0x4000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE5__SHIFT 0x1a\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE4_MASK 0x8000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE4__SHIFT 0x1b\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE3_MASK 0x10000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE3__SHIFT 0x1c\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE2_MASK 0x20000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE2__SHIFT 0x1d\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE1_MASK 0x40000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE1__SHIFT 0x1e\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE0_MASK 0x80000000\n#define DB_CGTT_CLK_CTRL_0__SOFT_OVERRIDE0__SHIFT 0x1f\n#define DB_ZPASS_COUNT_LOW__COUNT_LOW_MASK 0xffffffff\n#define DB_ZPASS_COUNT_LOW__COUNT_LOW__SHIFT 0x0\n#define DB_ZPASS_COUNT_HI__COUNT_HI_MASK 0x7fffffff\n#define DB_ZPASS_COUNT_HI__COUNT_HI__SHIFT 0x0\n#define DB_RING_CONTROL__COUNTER_CONTROL_MASK 0x3\n#define DB_RING_CONTROL__COUNTER_CONTROL__SHIFT 0x0\n#define DB_READ_DEBUG_0__BUSY_DATA0_MASK 0xffffffff\n#define DB_READ_DEBUG_0__BUSY_DATA0__SHIFT 0x0\n#define DB_READ_DEBUG_1__BUSY_DATA1_MASK 0xffffffff\n#define DB_READ_DEBUG_1__BUSY_DATA1__SHIFT 0x0\n#define DB_READ_DEBUG_2__BUSY_DATA2_MASK 0xffffffff\n#define DB_READ_DEBUG_2__BUSY_DATA2__SHIFT 0x0\n#define DB_READ_DEBUG_3__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_3__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_4__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_4__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_5__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_5__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_6__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_6__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_7__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_7__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_8__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_8__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_9__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_9__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_A__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_A__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_B__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_B__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_C__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_C__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_D__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_D__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_E__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_E__DEBUG_DATA__SHIFT 0x0\n#define DB_READ_DEBUG_F__DEBUG_DATA_MASK 0xffffffff\n#define DB_READ_DEBUG_F__DEBUG_DATA__SHIFT 0x0\n#define DB_OCCLUSION_COUNT0_LOW__COUNT_LOW_MASK 0xffffffff\n#define DB_OCCLUSION_COUNT0_LOW__COUNT_LOW__SHIFT 0x0\n#define DB_OCCLUSION_COUNT0_HI__COUNT_HI_MASK 0x7fffffff\n#define DB_OCCLUSION_COUNT0_HI__COUNT_HI__SHIFT 0x0\n#define DB_OCCLUSION_COUNT1_LOW__COUNT_LOW_MASK 0xffffffff\n#define DB_OCCLUSION_COUNT1_LOW__COUNT_LOW__SHIFT 0x0\n#define DB_OCCLUSION_COUNT1_HI__COUNT_HI_MASK 0x7fffffff\n#define DB_OCCLUSION_COUNT1_HI__COUNT_HI__SHIFT 0x0\n#define DB_OCCLUSION_COUNT2_LOW__COUNT_LOW_MASK 0xffffffff\n#define DB_OCCLUSION_COUNT2_LOW__COUNT_LOW__SHIFT 0x0\n#define DB_OCCLUSION_COUNT2_HI__COUNT_HI_MASK 0x7fffffff\n#define DB_OCCLUSION_COUNT2_HI__COUNT_HI__SHIFT 0x0\n#define DB_OCCLUSION_COUNT3_LOW__COUNT_LOW_MASK 0xffffffff\n#define DB_OCCLUSION_COUNT3_LOW__COUNT_LOW__SHIFT 0x0\n#define DB_OCCLUSION_COUNT3_HI__COUNT_HI_MASK 0x7fffffff\n#define DB_OCCLUSION_COUNT3_HI__COUNT_HI__SHIFT 0x0\n#define CC_RB_REDUNDANCY__FAILED_RB0_MASK 0xf00\n#define CC_RB_REDUNDANCY__FAILED_RB0__SHIFT 0x8\n#define CC_RB_REDUNDANCY__EN_REDUNDANCY0_MASK 0x1000\n#define CC_RB_REDUNDANCY__EN_REDUNDANCY0__SHIFT 0xc\n#define CC_RB_REDUNDANCY__FAILED_RB1_MASK 0xf0000\n#define CC_RB_REDUNDANCY__FAILED_RB1__SHIFT 0x10\n#define CC_RB_REDUNDANCY__EN_REDUNDANCY1_MASK 0x100000\n#define CC_RB_REDUNDANCY__EN_REDUNDANCY1__SHIFT 0x14\n#define CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK 0xff0000\n#define CC_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT 0x10\n#define GC_USER_RB_REDUNDANCY__FAILED_RB0_MASK 0xf00\n#define GC_USER_RB_REDUNDANCY__FAILED_RB0__SHIFT 0x8\n#define GC_USER_RB_REDUNDANCY__EN_REDUNDANCY0_MASK 0x1000\n#define GC_USER_RB_REDUNDANCY__EN_REDUNDANCY0__SHIFT 0xc\n#define GC_USER_RB_REDUNDANCY__FAILED_RB1_MASK 0xf0000\n#define GC_USER_RB_REDUNDANCY__FAILED_RB1__SHIFT 0x10\n#define GC_USER_RB_REDUNDANCY__EN_REDUNDANCY1_MASK 0x100000\n#define GC_USER_RB_REDUNDANCY__EN_REDUNDANCY1__SHIFT 0x14\n#define GC_USER_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK 0xff0000\n#define GC_USER_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT 0x10\n#define GB_ADDR_CONFIG__NUM_PIPES_MASK 0x7\n#define GB_ADDR_CONFIG__NUM_PIPES__SHIFT 0x0\n#define GB_ADDR_CONFIG__PIPE_INTERLEAVE_SIZE_MASK 0x70\n#define GB_ADDR_CONFIG__PIPE_INTERLEAVE_SIZE__SHIFT 0x4\n#define GB_ADDR_CONFIG__BANK_INTERLEAVE_SIZE_MASK 0x700\n#define GB_ADDR_CONFIG__BANK_INTERLEAVE_SIZE__SHIFT 0x8\n#define GB_ADDR_CONFIG__NUM_SHADER_ENGINES_MASK 0x3000\n#define GB_ADDR_CONFIG__NUM_SHADER_ENGINES__SHIFT 0xc\n#define GB_ADDR_CONFIG__SHADER_ENGINE_TILE_SIZE_MASK 0x70000\n#define GB_ADDR_CONFIG__SHADER_ENGINE_TILE_SIZE__SHIFT 0x10\n#define GB_ADDR_CONFIG__NUM_GPUS_MASK 0x700000\n#define GB_ADDR_CONFIG__NUM_GPUS__SHIFT 0x14\n#define GB_ADDR_CONFIG__MULTI_GPU_TILE_SIZE_MASK 0x3000000\n#define GB_ADDR_CONFIG__MULTI_GPU_TILE_SIZE__SHIFT 0x18\n#define GB_ADDR_CONFIG__ROW_SIZE_MASK 0x30000000\n#define GB_ADDR_CONFIG__ROW_SIZE__SHIFT 0x1c\n#define GB_ADDR_CONFIG__NUM_LOWER_PIPES_MASK 0x40000000\n#define GB_ADDR_CONFIG__NUM_LOWER_PIPES__SHIFT 0x1e\n#define GB_BACKEND_MAP__BACKEND_MAP_MASK 0xffffffff\n#define GB_BACKEND_MAP__BACKEND_MAP__SHIFT 0x0\n#define GB_GPU_ID__GPU_ID_MASK 0xf\n#define GB_GPU_ID__GPU_ID__SHIFT 0x0\n#define CC_RB_DAISY_CHAIN__RB_0_MASK 0xf\n#define CC_RB_DAISY_CHAIN__RB_0__SHIFT 0x0\n#define CC_RB_DAISY_CHAIN__RB_1_MASK 0xf0\n#define CC_RB_DAISY_CHAIN__RB_1__SHIFT 0x4\n#define CC_RB_DAISY_CHAIN__RB_2_MASK 0xf00\n#define CC_RB_DAISY_CHAIN__RB_2__SHIFT 0x8\n#define CC_RB_DAISY_CHAIN__RB_3_MASK 0xf000\n#define CC_RB_DAISY_CHAIN__RB_3__SHIFT 0xc\n#define CC_RB_DAISY_CHAIN__RB_4_MASK 0xf0000\n#define CC_RB_DAISY_CHAIN__RB_4__SHIFT 0x10\n#define CC_RB_DAISY_CHAIN__RB_5_MASK 0xf00000\n#define CC_RB_DAISY_CHAIN__RB_5__SHIFT 0x14\n#define CC_RB_DAISY_CHAIN__RB_6_MASK 0xf000000\n#define CC_RB_DAISY_CHAIN__RB_6__SHIFT 0x18\n#define CC_RB_DAISY_CHAIN__RB_7_MASK 0xf0000000\n#define CC_RB_DAISY_CHAIN__RB_7__SHIFT 0x1c\n#define GB_TILE_MODE0__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE0__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE0__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE0__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE0__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE0__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE0__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE0__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE0__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE0__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE1__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE1__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE1__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE1__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE1__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE1__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE1__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE1__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE1__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE1__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE2__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE2__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE2__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE2__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE2__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE2__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE2__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE2__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE2__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE2__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE3__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE3__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE3__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE3__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE3__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE3__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE3__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE3__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE3__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE3__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE4__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE4__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE4__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE4__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE4__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE4__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE4__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE4__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE4__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE4__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE5__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE5__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE5__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE5__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE5__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE5__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE5__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE5__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE5__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE5__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE6__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE6__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE6__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE6__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE6__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE6__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE6__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE6__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE6__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE6__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE7__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE7__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE7__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE7__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE7__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE7__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE7__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE7__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE7__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE7__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE8__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE8__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE8__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE8__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE8__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE8__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE8__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE8__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE8__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE8__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE9__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE9__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE9__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE9__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE9__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE9__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE9__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE9__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE9__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE9__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE10__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE10__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE10__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE10__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE10__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE10__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE10__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE10__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE10__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE10__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE11__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE11__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE11__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE11__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE11__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE11__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE11__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE11__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE11__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE11__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE12__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE12__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE12__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE12__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE12__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE12__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE12__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE12__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE12__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE12__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE13__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE13__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE13__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE13__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE13__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE13__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE13__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE13__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE13__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE13__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE14__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE14__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE14__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE14__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE14__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE14__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE14__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE14__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE14__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE14__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE15__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE15__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE15__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE15__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE15__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE15__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE15__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE15__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE15__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE15__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE16__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE16__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE16__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE16__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE16__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE16__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE16__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE16__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE16__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE16__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE17__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE17__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE17__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE17__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE17__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE17__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE17__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE17__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE17__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE17__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE18__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE18__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE18__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE18__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE18__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE18__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE18__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE18__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE18__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE18__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE19__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE19__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE19__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE19__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE19__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE19__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE19__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE19__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE19__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE19__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE20__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE20__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE20__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE20__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE20__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE20__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE20__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE20__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE20__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE20__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE21__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE21__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE21__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE21__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE21__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE21__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE21__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE21__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE21__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE21__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE22__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE22__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE22__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE22__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE22__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE22__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE22__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE22__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE22__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE22__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE23__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE23__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE23__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE23__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE23__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE23__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE23__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE23__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE23__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE23__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE24__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE24__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE24__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE24__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE24__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE24__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE24__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE24__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE24__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE24__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE25__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE25__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE25__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE25__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE25__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE25__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE25__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE25__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE25__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE25__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE26__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE26__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE26__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE26__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE26__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE26__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE26__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE26__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE26__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE26__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE27__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE27__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE27__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE27__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE27__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE27__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE27__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE27__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE27__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE27__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE28__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE28__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE28__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE28__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE28__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE28__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE28__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE28__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE28__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE28__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE29__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE29__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE29__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE29__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE29__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE29__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE29__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE29__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE29__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE29__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE30__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE30__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE30__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE30__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE30__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE30__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE30__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE30__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE30__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE30__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_TILE_MODE31__ARRAY_MODE_MASK 0x3c\n#define GB_TILE_MODE31__ARRAY_MODE__SHIFT 0x2\n#define GB_TILE_MODE31__PIPE_CONFIG_MASK 0x7c0\n#define GB_TILE_MODE31__PIPE_CONFIG__SHIFT 0x6\n#define GB_TILE_MODE31__TILE_SPLIT_MASK 0x3800\n#define GB_TILE_MODE31__TILE_SPLIT__SHIFT 0xb\n#define GB_TILE_MODE31__MICRO_TILE_MODE_NEW_MASK 0x1c00000\n#define GB_TILE_MODE31__MICRO_TILE_MODE_NEW__SHIFT 0x16\n#define GB_TILE_MODE31__SAMPLE_SPLIT_MASK 0x6000000\n#define GB_TILE_MODE31__SAMPLE_SPLIT__SHIFT 0x19\n#define GB_MACROTILE_MODE0__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE0__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE0__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE0__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE0__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE0__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE0__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE0__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE1__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE1__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE1__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE1__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE1__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE1__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE1__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE1__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE2__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE2__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE2__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE2__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE2__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE2__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE2__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE2__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE3__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE3__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE3__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE3__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE3__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE3__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE3__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE3__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE4__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE4__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE4__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE4__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE4__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE4__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE4__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE4__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE5__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE5__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE5__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE5__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE5__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE5__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE5__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE5__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE6__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE6__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE6__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE6__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE6__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE6__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE6__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE6__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE7__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE7__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE7__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE7__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE7__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE7__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE7__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE7__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE8__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE8__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE8__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE8__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE8__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE8__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE8__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE8__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE9__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE9__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE9__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE9__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE9__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE9__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE9__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE9__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE10__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE10__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE10__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE10__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE10__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE10__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE10__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE10__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE11__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE11__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE11__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE11__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE11__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE11__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE11__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE11__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE12__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE12__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE12__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE12__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE12__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE12__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE12__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE12__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE13__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE13__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE13__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE13__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE13__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE13__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE13__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE13__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE14__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE14__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE14__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE14__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE14__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE14__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE14__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE14__NUM_BANKS__SHIFT 0x6\n#define GB_MACROTILE_MODE15__BANK_WIDTH_MASK 0x3\n#define GB_MACROTILE_MODE15__BANK_WIDTH__SHIFT 0x0\n#define GB_MACROTILE_MODE15__BANK_HEIGHT_MASK 0xc\n#define GB_MACROTILE_MODE15__BANK_HEIGHT__SHIFT 0x2\n#define GB_MACROTILE_MODE15__MACRO_TILE_ASPECT_MASK 0x30\n#define GB_MACROTILE_MODE15__MACRO_TILE_ASPECT__SHIFT 0x4\n#define GB_MACROTILE_MODE15__NUM_BANKS_MASK 0xc0\n#define GB_MACROTILE_MODE15__NUM_BANKS__SHIFT 0x6\n#define GB_EDC_MODE__FORCE_SEC_ON_DED_MASK 0x10000\n#define GB_EDC_MODE__FORCE_SEC_ON_DED__SHIFT 0x10\n#define GB_EDC_MODE__DED_MODE_MASK 0x300000\n#define GB_EDC_MODE__DED_MODE__SHIFT 0x14\n#define GB_EDC_MODE__PROP_FED_MASK 0x20000000\n#define GB_EDC_MODE__PROP_FED__SHIFT 0x1d\n#define GB_EDC_MODE__BYPASS_MASK 0x80000000\n#define GB_EDC_MODE__BYPASS__SHIFT 0x1f\n#define CC_GC_EDC_CONFIG__DIS_EDC_MASK 0x2\n#define CC_GC_EDC_CONFIG__DIS_EDC__SHIFT 0x1\n#define RAS_SIGNATURE_CONTROL__ENABLE_MASK 0x1\n#define RAS_SIGNATURE_CONTROL__ENABLE__SHIFT 0x0\n#define RAS_SIGNATURE_MASK__INPUT_BUS_MASK_MASK 0xffffffff\n#define RAS_SIGNATURE_MASK__INPUT_BUS_MASK__SHIFT 0x0\n#define RAS_SX_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_SX_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_SX_SIGNATURE1__SIGNATURE_MASK 0xffffffff\n#define RAS_SX_SIGNATURE1__SIGNATURE__SHIFT 0x0\n#define RAS_SX_SIGNATURE2__SIGNATURE_MASK 0xffffffff\n#define RAS_SX_SIGNATURE2__SIGNATURE__SHIFT 0x0\n#define RAS_SX_SIGNATURE3__SIGNATURE_MASK 0xffffffff\n#define RAS_SX_SIGNATURE3__SIGNATURE__SHIFT 0x0\n#define RAS_DB_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_DB_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_PA_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_PA_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_VGT_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_VGT_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_SQ_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_SQ_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE1__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE1__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE2__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE2__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE3__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE3__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE4__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE4__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE5__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE5__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE6__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE6__SIGNATURE__SHIFT 0x0\n#define RAS_SC_SIGNATURE7__SIGNATURE_MASK 0xffffffff\n#define RAS_SC_SIGNATURE7__SIGNATURE__SHIFT 0x0\n#define RAS_IA_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_IA_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_IA_SIGNATURE1__SIGNATURE_MASK 0xffffffff\n#define RAS_IA_SIGNATURE1__SIGNATURE__SHIFT 0x0\n#define RAS_SPI_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_SPI_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_SPI_SIGNATURE1__SIGNATURE_MASK 0xffffffff\n#define RAS_SPI_SIGNATURE1__SIGNATURE__SHIFT 0x0\n#define RAS_TA_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_TA_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_TD_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_TD_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_CB_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_CB_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_BCI_SIGNATURE0__SIGNATURE_MASK 0xffffffff\n#define RAS_BCI_SIGNATURE0__SIGNATURE__SHIFT 0x0\n#define RAS_BCI_SIGNATURE1__SIGNATURE_MASK 0xffffffff\n#define RAS_BCI_SIGNATURE1__SIGNATURE__SHIFT 0x0\n#define GRBM_CAM_INDEX__CAM_INDEX_MASK 0x7\n#define GRBM_CAM_INDEX__CAM_INDEX__SHIFT 0x0\n#define GRBM_CAM_DATA__CAM_ADDR_MASK 0xffff\n#define GRBM_CAM_DATA__CAM_ADDR__SHIFT 0x0\n#define GRBM_CAM_DATA__CAM_REMAPADDR_MASK 0xffff0000\n#define GRBM_CAM_DATA__CAM_REMAPADDR__SHIFT 0x10\n#define GRBM_CNTL__READ_TIMEOUT_MASK 0xff\n#define GRBM_CNTL__READ_TIMEOUT__SHIFT 0x0\n#define GRBM_SKEW_CNTL__SKEW_TOP_THRESHOLD_MASK 0x3f\n#define GRBM_SKEW_CNTL__SKEW_TOP_THRESHOLD__SHIFT 0x0\n#define GRBM_SKEW_CNTL__SKEW_COUNT_MASK 0xfc0\n#define GRBM_SKEW_CNTL__SKEW_COUNT__SHIFT 0x6\n#define GRBM_PWR_CNTL__REQ_TYPE_MASK 0xf\n#define GRBM_PWR_CNTL__REQ_TYPE__SHIFT 0x0\n#define GRBM_PWR_CNTL__RSP_TYPE_MASK 0xf0\n#define GRBM_PWR_CNTL__RSP_TYPE__SHIFT 0x4\n#define GRBM_STATUS__ME0PIPE0_CMDFIFO_AVAIL_MASK 0xf\n#define GRBM_STATUS__ME0PIPE0_CMDFIFO_AVAIL__SHIFT 0x0\n#define GRBM_STATUS__SRBM_RQ_PENDING_MASK 0x20\n#define GRBM_STATUS__SRBM_RQ_PENDING__SHIFT 0x5\n#define GRBM_STATUS__ME0PIPE0_CF_RQ_PENDING_MASK 0x80\n#define GRBM_STATUS__ME0PIPE0_CF_RQ_PENDING__SHIFT 0x7\n#define GRBM_STATUS__ME0PIPE0_PF_RQ_PENDING_MASK 0x100\n#define GRBM_STATUS__ME0PIPE0_PF_RQ_PENDING__SHIFT 0x8\n#define GRBM_STATUS__GDS_DMA_RQ_PENDING_MASK 0x200\n#define GRBM_STATUS__GDS_DMA_RQ_PENDING__SHIFT 0x9\n#define GRBM_STATUS__DB_CLEAN_MASK 0x1000\n#define GRBM_STATUS__DB_CLEAN__SHIFT 0xc\n#define GRBM_STATUS__CB_CLEAN_MASK 0x2000\n#define GRBM_STATUS__CB_CLEAN__SHIFT 0xd\n#define GRBM_STATUS__TA_BUSY_MASK 0x4000\n#define GRBM_STATUS__TA_BUSY__SHIFT 0xe\n#define GRBM_STATUS__GDS_BUSY_MASK 0x8000\n#define GRBM_STATUS__GDS_BUSY__SHIFT 0xf\n#define GRBM_STATUS__WD_BUSY_NO_DMA_MASK 0x10000\n#define GRBM_STATUS__WD_BUSY_NO_DMA__SHIFT 0x10\n#define GRBM_STATUS__VGT_BUSY_MASK 0x20000\n#define GRBM_STATUS__VGT_BUSY__SHIFT 0x11\n#define GRBM_STATUS__IA_BUSY_NO_DMA_MASK 0x40000\n#define GRBM_STATUS__IA_BUSY_NO_DMA__SHIFT 0x12\n#define GRBM_STATUS__IA_BUSY_MASK 0x80000\n#define GRBM_STATUS__IA_BUSY__SHIFT 0x13\n#define GRBM_STATUS__SX_BUSY_MASK 0x100000\n#define GRBM_STATUS__SX_BUSY__SHIFT 0x14\n#define GRBM_STATUS__WD_BUSY_MASK 0x200000\n#define GRBM_STATUS__WD_BUSY__SHIFT 0x15\n#define GRBM_STATUS__SPI_BUSY_MASK 0x400000\n#define GRBM_STATUS__SPI_BUSY__SHIFT 0x16\n#define GRBM_STATUS__BCI_BUSY_MASK 0x800000\n#define GRBM_STATUS__BCI_BUSY__SHIFT 0x17\n#define GRBM_STATUS__SC_BUSY_MASK 0x1000000\n#define GRBM_STATUS__SC_BUSY__SHIFT 0x18\n#define GRBM_STATUS__PA_BUSY_MASK 0x2000000\n#define GRBM_STATUS__PA_BUSY__SHIFT 0x19\n#define GRBM_STATUS__DB_BUSY_MASK 0x4000000\n#define GRBM_STATUS__DB_BUSY__SHIFT 0x1a\n#define GRBM_STATUS__CP_COHERENCY_BUSY_MASK 0x10000000\n#define GRBM_STATUS__CP_COHERENCY_BUSY__SHIFT 0x1c\n#define GRBM_STATUS__CP_BUSY_MASK 0x20000000\n#define GRBM_STATUS__CP_BUSY__SHIFT 0x1d\n#define GRBM_STATUS__CB_BUSY_MASK 0x40000000\n#define GRBM_STATUS__CB_BUSY__SHIFT 0x1e\n#define GRBM_STATUS__GUI_ACTIVE_MASK 0x80000000\n#define GRBM_STATUS__GUI_ACTIVE__SHIFT 0x1f\n#define GRBM_STATUS2__ME0PIPE1_CMDFIFO_AVAIL_MASK 0xf\n#define GRBM_STATUS2__ME0PIPE1_CMDFIFO_AVAIL__SHIFT 0x0\n#define GRBM_STATUS2__ME0PIPE1_CF_RQ_PENDING_MASK 0x10\n#define GRBM_STATUS2__ME0PIPE1_CF_RQ_PENDING__SHIFT 0x4\n#define GRBM_STATUS2__ME0PIPE1_PF_RQ_PENDING_MASK 0x20\n#define GRBM_STATUS2__ME0PIPE1_PF_RQ_PENDING__SHIFT 0x5\n#define GRBM_STATUS2__ME1PIPE0_RQ_PENDING_MASK 0x40\n#define GRBM_STATUS2__ME1PIPE0_RQ_PENDING__SHIFT 0x6\n#define GRBM_STATUS2__ME1PIPE1_RQ_PENDING_MASK 0x80\n#define GRBM_STATUS2__ME1PIPE1_RQ_PENDING__SHIFT 0x7\n#define GRBM_STATUS2__ME1PIPE2_RQ_PENDING_MASK 0x100\n#define GRBM_STATUS2__ME1PIPE2_RQ_PENDING__SHIFT 0x8\n#define GRBM_STATUS2__ME1PIPE3_RQ_PENDING_MASK 0x200\n#define GRBM_STATUS2__ME1PIPE3_RQ_PENDING__SHIFT 0x9\n#define GRBM_STATUS2__ME2PIPE0_RQ_PENDING_MASK 0x400\n#define GRBM_STATUS2__ME2PIPE0_RQ_PENDING__SHIFT 0xa\n#define GRBM_STATUS2__ME2PIPE1_RQ_PENDING_MASK 0x800\n#define GRBM_STATUS2__ME2PIPE1_RQ_PENDING__SHIFT 0xb\n#define GRBM_STATUS2__ME2PIPE2_RQ_PENDING_MASK 0x1000\n#define GRBM_STATUS2__ME2PIPE2_RQ_PENDING__SHIFT 0xc\n#define GRBM_STATUS2__ME2PIPE3_RQ_PENDING_MASK 0x2000\n#define GRBM_STATUS2__ME2PIPE3_RQ_PENDING__SHIFT 0xd\n#define GRBM_STATUS2__RLC_RQ_PENDING_MASK 0x4000\n#define GRBM_STATUS2__RLC_RQ_PENDING__SHIFT 0xe\n#define GRBM_STATUS2__RLC_BUSY_MASK 0x1000000\n#define GRBM_STATUS2__RLC_BUSY__SHIFT 0x18\n#define GRBM_STATUS2__TC_BUSY_MASK 0x2000000\n#define GRBM_STATUS2__TC_BUSY__SHIFT 0x19\n#define GRBM_STATUS2__CPF_BUSY_MASK 0x10000000\n#define GRBM_STATUS2__CPF_BUSY__SHIFT 0x1c\n#define GRBM_STATUS2__CPC_BUSY_MASK 0x20000000\n#define GRBM_STATUS2__CPC_BUSY__SHIFT 0x1d\n#define GRBM_STATUS2__CPG_BUSY_MASK 0x40000000\n#define GRBM_STATUS2__CPG_BUSY__SHIFT 0x1e\n#define GRBM_STATUS_SE0__DB_CLEAN_MASK 0x2\n#define GRBM_STATUS_SE0__DB_CLEAN__SHIFT 0x1\n#define GRBM_STATUS_SE0__CB_CLEAN_MASK 0x4\n#define GRBM_STATUS_SE0__CB_CLEAN__SHIFT 0x2\n#define GRBM_STATUS_SE0__BCI_BUSY_MASK 0x400000\n#define GRBM_STATUS_SE0__BCI_BUSY__SHIFT 0x16\n#define GRBM_STATUS_SE0__VGT_BUSY_MASK 0x800000\n#define GRBM_STATUS_SE0__VGT_BUSY__SHIFT 0x17\n#define GRBM_STATUS_SE0__PA_BUSY_MASK 0x1000000\n#define GRBM_STATUS_SE0__PA_BUSY__SHIFT 0x18\n#define GRBM_STATUS_SE0__TA_BUSY_MASK 0x2000000\n#define GRBM_STATUS_SE0__TA_BUSY__SHIFT 0x19\n#define GRBM_STATUS_SE0__SX_BUSY_MASK 0x4000000\n#define GRBM_STATUS_SE0__SX_BUSY__SHIFT 0x1a\n#define GRBM_STATUS_SE0__SPI_BUSY_MASK 0x8000000\n#define GRBM_STATUS_SE0__SPI_BUSY__SHIFT 0x1b\n#define GRBM_STATUS_SE0__SC_BUSY_MASK 0x20000000\n#define GRBM_STATUS_SE0__SC_BUSY__SHIFT 0x1d\n#define GRBM_STATUS_SE0__DB_BUSY_MASK 0x40000000\n#define GRBM_STATUS_SE0__DB_BUSY__SHIFT 0x1e\n#define GRBM_STATUS_SE0__CB_BUSY_MASK 0x80000000\n#define GRBM_STATUS_SE0__CB_BUSY__SHIFT 0x1f\n#define GRBM_STATUS_SE1__DB_CLEAN_MASK 0x2\n#define GRBM_STATUS_SE1__DB_CLEAN__SHIFT 0x1\n#define GRBM_STATUS_SE1__CB_CLEAN_MASK 0x4\n#define GRBM_STATUS_SE1__CB_CLEAN__SHIFT 0x2\n#define GRBM_STATUS_SE1__BCI_BUSY_MASK 0x400000\n#define GRBM_STATUS_SE1__BCI_BUSY__SHIFT 0x16\n#define GRBM_STATUS_SE1__VGT_BUSY_MASK 0x800000\n#define GRBM_STATUS_SE1__VGT_BUSY__SHIFT 0x17\n#define GRBM_STATUS_SE1__PA_BUSY_MASK 0x1000000\n#define GRBM_STATUS_SE1__PA_BUSY__SHIFT 0x18\n#define GRBM_STATUS_SE1__TA_BUSY_MASK 0x2000000\n#define GRBM_STATUS_SE1__TA_BUSY__SHIFT 0x19\n#define GRBM_STATUS_SE1__SX_BUSY_MASK 0x4000000\n#define GRBM_STATUS_SE1__SX_BUSY__SHIFT 0x1a\n#define GRBM_STATUS_SE1__SPI_BUSY_MASK 0x8000000\n#define GRBM_STATUS_SE1__SPI_BUSY__SHIFT 0x1b\n#define GRBM_STATUS_SE1__SC_BUSY_MASK 0x20000000\n#define GRBM_STATUS_SE1__SC_BUSY__SHIFT 0x1d\n#define GRBM_STATUS_SE1__DB_BUSY_MASK 0x40000000\n#define GRBM_STATUS_SE1__DB_BUSY__SHIFT 0x1e\n#define GRBM_STATUS_SE1__CB_BUSY_MASK 0x80000000\n#define GRBM_STATUS_SE1__CB_BUSY__SHIFT 0x1f\n#define GRBM_STATUS_SE2__DB_CLEAN_MASK 0x2\n#define GRBM_STATUS_SE2__DB_CLEAN__SHIFT 0x1\n#define GRBM_STATUS_SE2__CB_CLEAN_MASK 0x4\n#define GRBM_STATUS_SE2__CB_CLEAN__SHIFT 0x2\n#define GRBM_STATUS_SE2__BCI_BUSY_MASK 0x400000\n#define GRBM_STATUS_SE2__BCI_BUSY__SHIFT 0x16\n#define GRBM_STATUS_SE2__VGT_BUSY_MASK 0x800000\n#define GRBM_STATUS_SE2__VGT_BUSY__SHIFT 0x17\n#define GRBM_STATUS_SE2__PA_BUSY_MASK 0x1000000\n#define GRBM_STATUS_SE2__PA_BUSY__SHIFT 0x18\n#define GRBM_STATUS_SE2__TA_BUSY_MASK 0x2000000\n#define GRBM_STATUS_SE2__TA_BUSY__SHIFT 0x19\n#define GRBM_STATUS_SE2__SX_BUSY_MASK 0x4000000\n#define GRBM_STATUS_SE2__SX_BUSY__SHIFT 0x1a\n#define GRBM_STATUS_SE2__SPI_BUSY_MASK 0x8000000\n#define GRBM_STATUS_SE2__SPI_BUSY__SHIFT 0x1b\n#define GRBM_STATUS_SE2__SC_BUSY_MASK 0x20000000\n#define GRBM_STATUS_SE2__SC_BUSY__SHIFT 0x1d\n#define GRBM_STATUS_SE2__DB_BUSY_MASK 0x40000000\n#define GRBM_STATUS_SE2__DB_BUSY__SHIFT 0x1e\n#define GRBM_STATUS_SE2__CB_BUSY_MASK 0x80000000\n#define GRBM_STATUS_SE2__CB_BUSY__SHIFT 0x1f\n#define GRBM_STATUS_SE3__DB_CLEAN_MASK 0x2\n#define GRBM_STATUS_SE3__DB_CLEAN__SHIFT 0x1\n#define GRBM_STATUS_SE3__CB_CLEAN_MASK 0x4\n#define GRBM_STATUS_SE3__CB_CLEAN__SHIFT 0x2\n#define GRBM_STATUS_SE3__BCI_BUSY_MASK 0x400000\n#define GRBM_STATUS_SE3__BCI_BUSY__SHIFT 0x16\n#define GRBM_STATUS_SE3__VGT_BUSY_MASK 0x800000\n#define GRBM_STATUS_SE3__VGT_BUSY__SHIFT 0x17\n#define GRBM_STATUS_SE3__PA_BUSY_MASK 0x1000000\n#define GRBM_STATUS_SE3__PA_BUSY__SHIFT 0x18\n#define GRBM_STATUS_SE3__TA_BUSY_MASK 0x2000000\n#define GRBM_STATUS_SE3__TA_BUSY__SHIFT 0x19\n#define GRBM_STATUS_SE3__SX_BUSY_MASK 0x4000000\n#define GRBM_STATUS_SE3__SX_BUSY__SHIFT 0x1a\n#define GRBM_STATUS_SE3__SPI_BUSY_MASK 0x8000000\n#define GRBM_STATUS_SE3__SPI_BUSY__SHIFT 0x1b\n#define GRBM_STATUS_SE3__SC_BUSY_MASK 0x20000000\n#define GRBM_STATUS_SE3__SC_BUSY__SHIFT 0x1d\n#define GRBM_STATUS_SE3__DB_BUSY_MASK 0x40000000\n#define GRBM_STATUS_SE3__DB_BUSY__SHIFT 0x1e\n#define GRBM_STATUS_SE3__CB_BUSY_MASK 0x80000000\n#define GRBM_STATUS_SE3__CB_BUSY__SHIFT 0x1f\n#define GRBM_SOFT_RESET__SOFT_RESET_CP_MASK 0x1\n#define GRBM_SOFT_RESET__SOFT_RESET_CP__SHIFT 0x0\n#define GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK 0x4\n#define GRBM_SOFT_RESET__SOFT_RESET_RLC__SHIFT 0x2\n#define GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK 0x10000\n#define GRBM_SOFT_RESET__SOFT_RESET_GFX__SHIFT 0x10\n#define GRBM_SOFT_RESET__SOFT_RESET_CPF_MASK 0x20000\n#define GRBM_SOFT_RESET__SOFT_RESET_CPF__SHIFT 0x11\n#define GRBM_SOFT_RESET__SOFT_RESET_CPC_MASK 0x40000\n#define GRBM_SOFT_RESET__SOFT_RESET_CPC__SHIFT 0x12\n#define GRBM_SOFT_RESET__SOFT_RESET_CPG_MASK 0x80000\n#define GRBM_SOFT_RESET__SOFT_RESET_CPG__SHIFT 0x13\n#define GRBM_DEBUG_CNTL__GRBM_DEBUG_INDEX_MASK 0x3f\n#define GRBM_DEBUG_CNTL__GRBM_DEBUG_INDEX__SHIFT 0x0\n#define GRBM_DEBUG_DATA__DATA_MASK 0xffffffff\n#define GRBM_DEBUG_DATA__DATA__SHIFT 0x0\n#define GRBM_GFX_INDEX__INSTANCE_INDEX_MASK 0xff\n#define GRBM_GFX_INDEX__INSTANCE_INDEX__SHIFT 0x0\n#define GRBM_GFX_INDEX__SH_INDEX_MASK 0xff00\n#define GRBM_GFX_INDEX__SH_INDEX__SHIFT 0x8\n#define GRBM_GFX_INDEX__SE_INDEX_MASK 0xff0000\n#define GRBM_GFX_INDEX__SE_INDEX__SHIFT 0x10\n#define GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK 0x20000000\n#define GRBM_GFX_INDEX__SH_BROADCAST_WRITES__SHIFT 0x1d\n#define GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK 0x40000000\n#define GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES__SHIFT 0x1e\n#define GRBM_GFX_INDEX__SE_BROADCAST_WRITES_MASK 0x80000000\n#define GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT 0x1f\n#define GRBM_GFX_CLKEN_CNTL__PREFIX_DELAY_CNT_MASK 0xf\n#define GRBM_GFX_CLKEN_CNTL__PREFIX_DELAY_CNT__SHIFT 0x0\n#define GRBM_GFX_CLKEN_CNTL__POST_DELAY_CNT_MASK 0x1f00\n#define GRBM_GFX_CLKEN_CNTL__POST_DELAY_CNT__SHIFT 0x8\n#define GRBM_WAIT_IDLE_CLOCKS__WAIT_IDLE_CLOCKS_MASK 0xff\n#define GRBM_WAIT_IDLE_CLOCKS__WAIT_IDLE_CLOCKS__SHIFT 0x0\n#define GRBM_DEBUG__IGNORE_RDY_MASK 0x2\n#define GRBM_DEBUG__IGNORE_RDY__SHIFT 0x1\n#define GRBM_DEBUG__IGNORE_FAO_MASK 0x20\n#define GRBM_DEBUG__IGNORE_FAO__SHIFT 0x5\n#define GRBM_DEBUG__DISABLE_READ_TIMEOUT_MASK 0x40\n#define GRBM_DEBUG__DISABLE_READ_TIMEOUT__SHIFT 0x6\n#define GRBM_DEBUG__SNAPSHOT_FREE_CNTRS_MASK 0x80\n#define GRBM_DEBUG__SNAPSHOT_FREE_CNTRS__SHIFT 0x7\n#define GRBM_DEBUG__HYSTERESIS_GUI_ACTIVE_MASK 0xf00\n#define GRBM_DEBUG__HYSTERESIS_GUI_ACTIVE__SHIFT 0x8\n#define GRBM_DEBUG__GFX_CLOCK_DOMAIN_OVERRIDE_MASK 0x1000\n#define GRBM_DEBUG__GFX_CLOCK_DOMAIN_OVERRIDE__SHIFT 0xc\n#define GRBM_DEBUG_SNAPSHOT__CPF_RDY_MASK 0x1\n#define GRBM_DEBUG_SNAPSHOT__CPF_RDY__SHIFT 0x0\n#define GRBM_DEBUG_SNAPSHOT__CPG_RDY_MASK 0x2\n#define GRBM_DEBUG_SNAPSHOT__CPG_RDY__SHIFT 0x1\n#define GRBM_DEBUG_SNAPSHOT__SRBM_RDY_MASK 0x4\n#define GRBM_DEBUG_SNAPSHOT__SRBM_RDY__SHIFT 0x2\n#define GRBM_DEBUG_SNAPSHOT__WD_ME0PIPE0_RDY_MASK 0x8\n#define GRBM_DEBUG_SNAPSHOT__WD_ME0PIPE0_RDY__SHIFT 0x3\n#define GRBM_DEBUG_SNAPSHOT__WD_ME0PIPE1_RDY_MASK 0x10\n#define GRBM_DEBUG_SNAPSHOT__WD_ME0PIPE1_RDY__SHIFT 0x4\n#define GRBM_DEBUG_SNAPSHOT__GDS_RDY_MASK 0x20\n#define GRBM_DEBUG_SNAPSHOT__GDS_RDY__SHIFT 0x5\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE0_RDY0_MASK 0x40\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE0_RDY0__SHIFT 0x6\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE1_RDY0_MASK 0x80\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE1_RDY0__SHIFT 0x7\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE0_RDY0_MASK 0x100\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE0_RDY0__SHIFT 0x8\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE1_RDY0_MASK 0x200\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE1_RDY0__SHIFT 0x9\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE0_RDY0_MASK 0x400\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE0_RDY0__SHIFT 0xa\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE1_RDY0_MASK 0x800\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE1_RDY0__SHIFT 0xb\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE0_RDY0_MASK 0x1000\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE0_RDY0__SHIFT 0xc\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE1_RDY0_MASK 0x2000\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE1_RDY0__SHIFT 0xd\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE0_RDY1_MASK 0x4000\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE0_RDY1__SHIFT 0xe\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE1_RDY1_MASK 0x8000\n#define GRBM_DEBUG_SNAPSHOT__SE0SPI_ME0PIPE1_RDY1__SHIFT 0xf\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE0_RDY1_MASK 0x10000\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE0_RDY1__SHIFT 0x10\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE1_RDY1_MASK 0x20000\n#define GRBM_DEBUG_SNAPSHOT__SE1SPI_ME0PIPE1_RDY1__SHIFT 0x11\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE0_RDY1_MASK 0x40000\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE0_RDY1__SHIFT 0x12\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE1_RDY1_MASK 0x80000\n#define GRBM_DEBUG_SNAPSHOT__SE2SPI_ME0PIPE1_RDY1__SHIFT 0x13\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE0_RDY1_MASK 0x100000\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE0_RDY1__SHIFT 0x14\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE1_RDY1_MASK 0x200000\n#define GRBM_DEBUG_SNAPSHOT__SE3SPI_ME0PIPE1_RDY1__SHIFT 0x15\n#define GRBM_READ_ERROR__READ_ADDRESS_MASK 0x3fffc\n#define GRBM_READ_ERROR__READ_ADDRESS__SHIFT 0x2\n#define GRBM_READ_ERROR__READ_PIPEID_MASK 0x300000\n#define GRBM_READ_ERROR__READ_PIPEID__SHIFT 0x14\n#define GRBM_READ_ERROR__READ_MEID_MASK 0xc00000\n#define GRBM_READ_ERROR__READ_MEID__SHIFT 0x16\n#define GRBM_READ_ERROR__READ_ERROR_MASK 0x80000000\n#define GRBM_READ_ERROR__READ_ERROR__SHIFT 0x1f\n#define GRBM_READ_ERROR2__READ_REQUESTER_SRBM_MASK 0x20000\n#define GRBM_READ_ERROR2__READ_REQUESTER_SRBM__SHIFT 0x11\n#define GRBM_READ_ERROR2__READ_REQUESTER_RLC_MASK 0x40000\n#define GRBM_READ_ERROR2__READ_REQUESTER_RLC__SHIFT 0x12\n#define GRBM_READ_ERROR2__READ_REQUESTER_GDS_DMA_MASK 0x80000\n#define GRBM_READ_ERROR2__READ_REQUESTER_GDS_DMA__SHIFT 0x13\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE0_CF_MASK 0x100000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE0_CF__SHIFT 0x14\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE0_PF_MASK 0x200000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE0_PF__SHIFT 0x15\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE1_CF_MASK 0x400000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE1_CF__SHIFT 0x16\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE1_PF_MASK 0x800000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME0PIPE1_PF__SHIFT 0x17\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE0_MASK 0x1000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE0__SHIFT 0x18\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE1_MASK 0x2000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE1__SHIFT 0x19\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE2_MASK 0x4000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE2__SHIFT 0x1a\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE3_MASK 0x8000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME1PIPE3__SHIFT 0x1b\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE0_MASK 0x10000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE0__SHIFT 0x1c\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE1_MASK 0x20000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE1__SHIFT 0x1d\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE2_MASK 0x40000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE2__SHIFT 0x1e\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE3_MASK 0x80000000\n#define GRBM_READ_ERROR2__READ_REQUESTER_ME2PIPE3__SHIFT 0x1f\n#define GRBM_INT_CNTL__RDERR_INT_ENABLE_MASK 0x1\n#define GRBM_INT_CNTL__RDERR_INT_ENABLE__SHIFT 0x0\n#define GRBM_INT_CNTL__GUI_IDLE_INT_ENABLE_MASK 0x80000\n#define GRBM_INT_CNTL__GUI_IDLE_INT_ENABLE__SHIFT 0x13\n#define GRBM_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_PERFCOUNTER0_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_PERFCOUNTER0_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_PERFCOUNTER0_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_PERFCOUNTER0_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_PERFCOUNTER0_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_PERFCOUNTER0_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_PERFCOUNTER0_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_PERFCOUNTER0_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_PERFCOUNTER0_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x4000\n#define GRBM_PERFCOUNTER0_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xe\n#define GRBM_PERFCOUNTER0_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_PERFCOUNTER0_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_PERFCOUNTER0_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_PERFCOUNTER0_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_PERFCOUNTER0_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_PERFCOUNTER0_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_PERFCOUNTER0_SELECT__GRBM_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_PERFCOUNTER0_SELECT__GRBM_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_PERFCOUNTER0_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_PERFCOUNTER0_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_PERFCOUNTER0_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_PERFCOUNTER0_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_PERFCOUNTER0_SELECT__CP_BUSY_USER_DEFINED_MASK_MASK 0x400000\n#define GRBM_PERFCOUNTER0_SELECT__CP_BUSY_USER_DEFINED_MASK__SHIFT 0x16\n#define GRBM_PERFCOUNTER0_SELECT__IA_BUSY_USER_DEFINED_MASK_MASK 0x800000\n#define GRBM_PERFCOUNTER0_SELECT__IA_BUSY_USER_DEFINED_MASK__SHIFT 0x17\n#define GRBM_PERFCOUNTER0_SELECT__GDS_BUSY_USER_DEFINED_MASK_MASK 0x1000000\n#define GRBM_PERFCOUNTER0_SELECT__GDS_BUSY_USER_DEFINED_MASK__SHIFT 0x18\n#define GRBM_PERFCOUNTER0_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x2000000\n#define GRBM_PERFCOUNTER0_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x19\n#define GRBM_PERFCOUNTER0_SELECT__RLC_BUSY_USER_DEFINED_MASK_MASK 0x4000000\n#define GRBM_PERFCOUNTER0_SELECT__RLC_BUSY_USER_DEFINED_MASK__SHIFT 0x1a\n#define GRBM_PERFCOUNTER0_SELECT__TC_BUSY_USER_DEFINED_MASK_MASK 0x8000000\n#define GRBM_PERFCOUNTER0_SELECT__TC_BUSY_USER_DEFINED_MASK__SHIFT 0x1b\n#define GRBM_PERFCOUNTER0_SELECT__WD_BUSY_USER_DEFINED_MASK_MASK 0x10000000\n#define GRBM_PERFCOUNTER0_SELECT__WD_BUSY_USER_DEFINED_MASK__SHIFT 0x1c\n#define GRBM_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_PERFCOUNTER1_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_PERFCOUNTER1_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_PERFCOUNTER1_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_PERFCOUNTER1_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_PERFCOUNTER1_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_PERFCOUNTER1_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_PERFCOUNTER1_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_PERFCOUNTER1_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_PERFCOUNTER1_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x4000\n#define GRBM_PERFCOUNTER1_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xe\n#define GRBM_PERFCOUNTER1_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_PERFCOUNTER1_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_PERFCOUNTER1_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_PERFCOUNTER1_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_PERFCOUNTER1_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_PERFCOUNTER1_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_PERFCOUNTER1_SELECT__GRBM_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_PERFCOUNTER1_SELECT__GRBM_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_PERFCOUNTER1_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_PERFCOUNTER1_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_PERFCOUNTER1_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_PERFCOUNTER1_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_PERFCOUNTER1_SELECT__CP_BUSY_USER_DEFINED_MASK_MASK 0x400000\n#define GRBM_PERFCOUNTER1_SELECT__CP_BUSY_USER_DEFINED_MASK__SHIFT 0x16\n#define GRBM_PERFCOUNTER1_SELECT__IA_BUSY_USER_DEFINED_MASK_MASK 0x800000\n#define GRBM_PERFCOUNTER1_SELECT__IA_BUSY_USER_DEFINED_MASK__SHIFT 0x17\n#define GRBM_PERFCOUNTER1_SELECT__GDS_BUSY_USER_DEFINED_MASK_MASK 0x1000000\n#define GRBM_PERFCOUNTER1_SELECT__GDS_BUSY_USER_DEFINED_MASK__SHIFT 0x18\n#define GRBM_PERFCOUNTER1_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x2000000\n#define GRBM_PERFCOUNTER1_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x19\n#define GRBM_PERFCOUNTER1_SELECT__RLC_BUSY_USER_DEFINED_MASK_MASK 0x4000000\n#define GRBM_PERFCOUNTER1_SELECT__RLC_BUSY_USER_DEFINED_MASK__SHIFT 0x1a\n#define GRBM_PERFCOUNTER1_SELECT__TC_BUSY_USER_DEFINED_MASK_MASK 0x8000000\n#define GRBM_PERFCOUNTER1_SELECT__TC_BUSY_USER_DEFINED_MASK__SHIFT 0x1b\n#define GRBM_PERFCOUNTER1_SELECT__WD_BUSY_USER_DEFINED_MASK_MASK 0x10000000\n#define GRBM_PERFCOUNTER1_SELECT__WD_BUSY_USER_DEFINED_MASK__SHIFT 0x1c\n#define GRBM_SE0_PERFCOUNTER_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_SE0_PERFCOUNTER_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_SE0_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_SE0_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_SE0_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_SE0_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_SE0_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_SE0_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_SE0_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_SE0_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_SE0_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x8000\n#define GRBM_SE0_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0xf\n#define GRBM_SE0_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_SE0_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_SE0_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_SE0_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_SE0_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_SE0_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_SE0_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_SE0_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_SE0_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_SE0_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_SE0_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_SE0_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_SE1_PERFCOUNTER_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_SE1_PERFCOUNTER_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_SE1_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_SE1_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_SE1_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_SE1_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_SE1_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_SE1_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_SE1_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_SE1_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_SE1_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x8000\n#define GRBM_SE1_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0xf\n#define GRBM_SE1_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_SE1_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_SE1_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_SE1_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_SE1_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_SE1_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_SE1_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_SE1_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_SE1_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_SE1_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_SE1_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_SE1_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_SE2_PERFCOUNTER_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_SE2_PERFCOUNTER_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_SE2_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_SE2_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_SE2_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_SE2_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_SE2_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_SE2_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_SE2_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_SE2_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_SE2_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x8000\n#define GRBM_SE2_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0xf\n#define GRBM_SE2_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_SE2_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_SE2_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_SE2_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_SE2_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_SE2_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_SE2_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_SE2_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_SE2_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_SE2_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_SE2_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_SE2_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_SE3_PERFCOUNTER_SELECT__PERF_SEL_MASK 0x3f\n#define GRBM_SE3_PERFCOUNTER_SELECT__PERF_SEL__SHIFT 0x0\n#define GRBM_SE3_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK_MASK 0x400\n#define GRBM_SE3_PERFCOUNTER_SELECT__DB_CLEAN_USER_DEFINED_MASK__SHIFT 0xa\n#define GRBM_SE3_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK_MASK 0x800\n#define GRBM_SE3_PERFCOUNTER_SELECT__CB_CLEAN_USER_DEFINED_MASK__SHIFT 0xb\n#define GRBM_SE3_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK_MASK 0x1000\n#define GRBM_SE3_PERFCOUNTER_SELECT__TA_BUSY_USER_DEFINED_MASK__SHIFT 0xc\n#define GRBM_SE3_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK_MASK 0x2000\n#define GRBM_SE3_PERFCOUNTER_SELECT__SX_BUSY_USER_DEFINED_MASK__SHIFT 0xd\n#define GRBM_SE3_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK_MASK 0x8000\n#define GRBM_SE3_PERFCOUNTER_SELECT__SPI_BUSY_USER_DEFINED_MASK__SHIFT 0xf\n#define GRBM_SE3_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK_MASK 0x10000\n#define GRBM_SE3_PERFCOUNTER_SELECT__SC_BUSY_USER_DEFINED_MASK__SHIFT 0x10\n#define GRBM_SE3_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK_MASK 0x20000\n#define GRBM_SE3_PERFCOUNTER_SELECT__DB_BUSY_USER_DEFINED_MASK__SHIFT 0x11\n#define GRBM_SE3_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK_MASK 0x40000\n#define GRBM_SE3_PERFCOUNTER_SELECT__CB_BUSY_USER_DEFINED_MASK__SHIFT 0x12\n#define GRBM_SE3_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK_MASK 0x80000\n#define GRBM_SE3_PERFCOUNTER_SELECT__VGT_BUSY_USER_DEFINED_MASK__SHIFT 0x13\n#define GRBM_SE3_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK_MASK 0x100000\n#define GRBM_SE3_PERFCOUNTER_SELECT__PA_BUSY_USER_DEFINED_MASK__SHIFT 0x14\n#define GRBM_SE3_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK_MASK 0x200000\n#define GRBM_SE3_PERFCOUNTER_SELECT__BCI_BUSY_USER_DEFINED_MASK__SHIFT 0x15\n#define GRBM_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_SE0_PERFCOUNTER_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_SE0_PERFCOUNTER_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_SE0_PERFCOUNTER_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_SE0_PERFCOUNTER_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_SE1_PERFCOUNTER_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_SE1_PERFCOUNTER_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_SE1_PERFCOUNTER_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_SE1_PERFCOUNTER_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_SE2_PERFCOUNTER_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_SE2_PERFCOUNTER_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_SE2_PERFCOUNTER_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_SE2_PERFCOUNTER_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_SE3_PERFCOUNTER_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GRBM_SE3_PERFCOUNTER_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GRBM_SE3_PERFCOUNTER_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GRBM_SE3_PERFCOUNTER_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GRBM_SCRATCH_REG0__SCRATCH_REG0_MASK 0xffffffff\n#define GRBM_SCRATCH_REG0__SCRATCH_REG0__SHIFT 0x0\n#define GRBM_SCRATCH_REG1__SCRATCH_REG1_MASK 0xffffffff\n#define GRBM_SCRATCH_REG1__SCRATCH_REG1__SHIFT 0x0\n#define GRBM_SCRATCH_REG2__SCRATCH_REG2_MASK 0xffffffff\n#define GRBM_SCRATCH_REG2__SCRATCH_REG2__SHIFT 0x0\n#define GRBM_SCRATCH_REG3__SCRATCH_REG3_MASK 0xffffffff\n#define GRBM_SCRATCH_REG3__SCRATCH_REG3__SHIFT 0x0\n#define GRBM_SCRATCH_REG4__SCRATCH_REG4_MASK 0xffffffff\n#define GRBM_SCRATCH_REG4__SCRATCH_REG4__SHIFT 0x0\n#define GRBM_SCRATCH_REG5__SCRATCH_REG5_MASK 0xffffffff\n#define GRBM_SCRATCH_REG5__SCRATCH_REG5__SHIFT 0x0\n#define GRBM_SCRATCH_REG6__SCRATCH_REG6_MASK 0xffffffff\n#define GRBM_SCRATCH_REG6__SCRATCH_REG6__SHIFT 0x0\n#define GRBM_SCRATCH_REG7__SCRATCH_REG7_MASK 0xffffffff\n#define GRBM_SCRATCH_REG7__SCRATCH_REG7__SHIFT 0x0\n#define DEBUG_INDEX__DEBUG_INDEX_MASK 0x3ffff\n#define DEBUG_INDEX__DEBUG_INDEX__SHIFT 0x0\n#define DEBUG_DATA__DEBUG_DATA_MASK 0xffffffff\n#define DEBUG_DATA__DEBUG_DATA__SHIFT 0x0\n#define GRBM_NOWHERE__DATA_MASK 0xffffffff\n#define GRBM_NOWHERE__DATA__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_1__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_1__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_2__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_2__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_3__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_3__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_4__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_4__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_5__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_5__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_6__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_6__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_7__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_7__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_8__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_8__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_9__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_9__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_10__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_10__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_11__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_11__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_12__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_12__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_13__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_13__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_14__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_14__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XSCALE_15__VPORT_XSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_XSCALE_15__VPORT_XSCALE__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_1__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_1__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_2__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_2__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_3__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_3__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_4__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_4__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_5__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_5__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_6__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_6__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_7__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_7__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_8__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_8__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_9__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_9__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_10__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_10__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_11__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_11__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_12__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_12__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_13__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_13__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_14__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_14__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_XOFFSET_15__VPORT_XOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_XOFFSET_15__VPORT_XOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_1__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_1__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_2__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_2__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_3__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_3__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_4__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_4__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_5__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_5__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_6__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_6__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_7__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_7__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_8__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_8__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_9__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_9__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_10__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_10__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_11__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_11__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_12__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_12__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_13__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_13__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_14__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_14__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YSCALE_15__VPORT_YSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_YSCALE_15__VPORT_YSCALE__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_1__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_1__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_2__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_2__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_3__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_3__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_4__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_4__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_5__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_5__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_6__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_6__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_7__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_7__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_8__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_8__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_9__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_9__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_10__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_10__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_11__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_11__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_12__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_12__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_13__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_13__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_14__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_14__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_YOFFSET_15__VPORT_YOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_YOFFSET_15__VPORT_YOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_1__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_1__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_2__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_2__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_3__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_3__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_4__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_4__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_5__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_5__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_6__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_6__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_7__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_7__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_8__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_8__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_9__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_9__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_10__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_10__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_11__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_11__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_12__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_12__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_13__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_13__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_14__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_14__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZSCALE_15__VPORT_ZSCALE_MASK 0xffffffff\n#define PA_CL_VPORT_ZSCALE_15__VPORT_ZSCALE__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_1__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_1__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_2__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_2__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_3__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_3__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_4__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_4__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_5__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_5__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_6__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_6__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_7__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_7__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_8__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_8__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_9__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_9__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_10__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_10__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_11__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_11__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_12__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_12__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_13__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_13__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_14__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_14__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VPORT_ZOFFSET_15__VPORT_ZOFFSET_MASK 0xffffffff\n#define PA_CL_VPORT_ZOFFSET_15__VPORT_ZOFFSET__SHIFT 0x0\n#define PA_CL_VTE_CNTL__VPORT_X_SCALE_ENA_MASK 0x1\n#define PA_CL_VTE_CNTL__VPORT_X_SCALE_ENA__SHIFT 0x0\n#define PA_CL_VTE_CNTL__VPORT_X_OFFSET_ENA_MASK 0x2\n#define PA_CL_VTE_CNTL__VPORT_X_OFFSET_ENA__SHIFT 0x1\n#define PA_CL_VTE_CNTL__VPORT_Y_SCALE_ENA_MASK 0x4\n#define PA_CL_VTE_CNTL__VPORT_Y_SCALE_ENA__SHIFT 0x2\n#define PA_CL_VTE_CNTL__VPORT_Y_OFFSET_ENA_MASK 0x8\n#define PA_CL_VTE_CNTL__VPORT_Y_OFFSET_ENA__SHIFT 0x3\n#define PA_CL_VTE_CNTL__VPORT_Z_SCALE_ENA_MASK 0x10\n#define PA_CL_VTE_CNTL__VPORT_Z_SCALE_ENA__SHIFT 0x4\n#define PA_CL_VTE_CNTL__VPORT_Z_OFFSET_ENA_MASK 0x20\n#define PA_CL_VTE_CNTL__VPORT_Z_OFFSET_ENA__SHIFT 0x5\n#define PA_CL_VTE_CNTL__VTX_XY_FMT_MASK 0x100\n#define PA_CL_VTE_CNTL__VTX_XY_FMT__SHIFT 0x8\n#define PA_CL_VTE_CNTL__VTX_Z_FMT_MASK 0x200\n#define PA_CL_VTE_CNTL__VTX_Z_FMT__SHIFT 0x9\n#define PA_CL_VTE_CNTL__VTX_W0_FMT_MASK 0x400\n#define PA_CL_VTE_CNTL__VTX_W0_FMT__SHIFT 0xa\n#define PA_CL_VTE_CNTL__PERFCOUNTER_REF_MASK 0x800\n#define PA_CL_VTE_CNTL__PERFCOUNTER_REF__SHIFT 0xb\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_0_MASK 0x1\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_0__SHIFT 0x0\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_1_MASK 0x2\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_1__SHIFT 0x1\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_2_MASK 0x4\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_2__SHIFT 0x2\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_3_MASK 0x8\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_3__SHIFT 0x3\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_4_MASK 0x10\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_4__SHIFT 0x4\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_5_MASK 0x20\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_5__SHIFT 0x5\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_6_MASK 0x40\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_6__SHIFT 0x6\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_7_MASK 0x80\n#define PA_CL_VS_OUT_CNTL__CLIP_DIST_ENA_7__SHIFT 0x7\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_0_MASK 0x100\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_0__SHIFT 0x8\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_1_MASK 0x200\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_1__SHIFT 0x9\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_2_MASK 0x400\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_2__SHIFT 0xa\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_3_MASK 0x800\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_3__SHIFT 0xb\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_4_MASK 0x1000\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_4__SHIFT 0xc\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_5_MASK 0x2000\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_5__SHIFT 0xd\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_6_MASK 0x4000\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_6__SHIFT 0xe\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_7_MASK 0x8000\n#define PA_CL_VS_OUT_CNTL__CULL_DIST_ENA_7__SHIFT 0xf\n#define PA_CL_VS_OUT_CNTL__USE_VTX_POINT_SIZE_MASK 0x10000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_POINT_SIZE__SHIFT 0x10\n#define PA_CL_VS_OUT_CNTL__USE_VTX_EDGE_FLAG_MASK 0x20000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_EDGE_FLAG__SHIFT 0x11\n#define PA_CL_VS_OUT_CNTL__USE_VTX_RENDER_TARGET_INDX_MASK 0x40000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_RENDER_TARGET_INDX__SHIFT 0x12\n#define PA_CL_VS_OUT_CNTL__USE_VTX_VIEWPORT_INDX_MASK 0x80000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_VIEWPORT_INDX__SHIFT 0x13\n#define PA_CL_VS_OUT_CNTL__USE_VTX_KILL_FLAG_MASK 0x100000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_KILL_FLAG__SHIFT 0x14\n#define PA_CL_VS_OUT_CNTL__VS_OUT_MISC_VEC_ENA_MASK 0x200000\n#define PA_CL_VS_OUT_CNTL__VS_OUT_MISC_VEC_ENA__SHIFT 0x15\n#define PA_CL_VS_OUT_CNTL__VS_OUT_CCDIST0_VEC_ENA_MASK 0x400000\n#define PA_CL_VS_OUT_CNTL__VS_OUT_CCDIST0_VEC_ENA__SHIFT 0x16\n#define PA_CL_VS_OUT_CNTL__VS_OUT_CCDIST1_VEC_ENA_MASK 0x800000\n#define PA_CL_VS_OUT_CNTL__VS_OUT_CCDIST1_VEC_ENA__SHIFT 0x17\n#define PA_CL_VS_OUT_CNTL__VS_OUT_MISC_SIDE_BUS_ENA_MASK 0x1000000\n#define PA_CL_VS_OUT_CNTL__VS_OUT_MISC_SIDE_BUS_ENA__SHIFT 0x18\n#define PA_CL_VS_OUT_CNTL__USE_VTX_GS_CUT_FLAG_MASK 0x2000000\n#define PA_CL_VS_OUT_CNTL__USE_VTX_GS_CUT_FLAG__SHIFT 0x19\n#define PA_CL_NANINF_CNTL__VTE_XY_INF_DISCARD_MASK 0x1\n#define PA_CL_NANINF_CNTL__VTE_XY_INF_DISCARD__SHIFT 0x0\n#define PA_CL_NANINF_CNTL__VTE_Z_INF_DISCARD_MASK 0x2\n#define PA_CL_NANINF_CNTL__VTE_Z_INF_DISCARD__SHIFT 0x1\n#define PA_CL_NANINF_CNTL__VTE_W_INF_DISCARD_MASK 0x4\n#define PA_CL_NANINF_CNTL__VTE_W_INF_DISCARD__SHIFT 0x2\n#define PA_CL_NANINF_CNTL__VTE_0XNANINF_IS_0_MASK 0x8\n#define PA_CL_NANINF_CNTL__VTE_0XNANINF_IS_0__SHIFT 0x3\n#define PA_CL_NANINF_CNTL__VTE_XY_NAN_RETAIN_MASK 0x10\n#define PA_CL_NANINF_CNTL__VTE_XY_NAN_RETAIN__SHIFT 0x4\n#define PA_CL_NANINF_CNTL__VTE_Z_NAN_RETAIN_MASK 0x20\n#define PA_CL_NANINF_CNTL__VTE_Z_NAN_RETAIN__SHIFT 0x5\n#define PA_CL_NANINF_CNTL__VTE_W_NAN_RETAIN_MASK 0x40\n#define PA_CL_NANINF_CNTL__VTE_W_NAN_RETAIN__SHIFT 0x6\n#define PA_CL_NANINF_CNTL__VTE_W_RECIP_NAN_IS_0_MASK 0x80\n#define PA_CL_NANINF_CNTL__VTE_W_RECIP_NAN_IS_0__SHIFT 0x7\n#define PA_CL_NANINF_CNTL__VS_XY_NAN_TO_INF_MASK 0x100\n#define PA_CL_NANINF_CNTL__VS_XY_NAN_TO_INF__SHIFT 0x8\n#define PA_CL_NANINF_CNTL__VS_XY_INF_RETAIN_MASK 0x200\n#define PA_CL_NANINF_CNTL__VS_XY_INF_RETAIN__SHIFT 0x9\n#define PA_CL_NANINF_CNTL__VS_Z_NAN_TO_INF_MASK 0x400\n#define PA_CL_NANINF_CNTL__VS_Z_NAN_TO_INF__SHIFT 0xa\n#define PA_CL_NANINF_CNTL__VS_Z_INF_RETAIN_MASK 0x800\n#define PA_CL_NANINF_CNTL__VS_Z_INF_RETAIN__SHIFT 0xb\n#define PA_CL_NANINF_CNTL__VS_W_NAN_TO_INF_MASK 0x1000\n#define PA_CL_NANINF_CNTL__VS_W_NAN_TO_INF__SHIFT 0xc\n#define PA_CL_NANINF_CNTL__VS_W_INF_RETAIN_MASK 0x2000\n#define PA_CL_NANINF_CNTL__VS_W_INF_RETAIN__SHIFT 0xd\n#define PA_CL_NANINF_CNTL__VS_CLIP_DIST_INF_DISCARD_MASK 0x4000\n#define PA_CL_NANINF_CNTL__VS_CLIP_DIST_INF_DISCARD__SHIFT 0xe\n#define PA_CL_NANINF_CNTL__VTE_NO_OUTPUT_NEG_0_MASK 0x100000\n#define PA_CL_NANINF_CNTL__VTE_NO_OUTPUT_NEG_0__SHIFT 0x14\n#define PA_CL_CLIP_CNTL__UCP_ENA_0_MASK 0x1\n#define PA_CL_CLIP_CNTL__UCP_ENA_0__SHIFT 0x0\n#define PA_CL_CLIP_CNTL__UCP_ENA_1_MASK 0x2\n#define PA_CL_CLIP_CNTL__UCP_ENA_1__SHIFT 0x1\n#define PA_CL_CLIP_CNTL__UCP_ENA_2_MASK 0x4\n#define PA_CL_CLIP_CNTL__UCP_ENA_2__SHIFT 0x2\n#define PA_CL_CLIP_CNTL__UCP_ENA_3_MASK 0x8\n#define PA_CL_CLIP_CNTL__UCP_ENA_3__SHIFT 0x3\n#define PA_CL_CLIP_CNTL__UCP_ENA_4_MASK 0x10\n#define PA_CL_CLIP_CNTL__UCP_ENA_4__SHIFT 0x4\n#define PA_CL_CLIP_CNTL__UCP_ENA_5_MASK 0x20\n#define PA_CL_CLIP_CNTL__UCP_ENA_5__SHIFT 0x5\n#define PA_CL_CLIP_CNTL__PS_UCP_Y_SCALE_NEG_MASK 0x2000\n#define PA_CL_CLIP_CNTL__PS_UCP_Y_SCALE_NEG__SHIFT 0xd\n#define PA_CL_CLIP_CNTL__PS_UCP_MODE_MASK 0xc000\n#define PA_CL_CLIP_CNTL__PS_UCP_MODE__SHIFT 0xe\n#define PA_CL_CLIP_CNTL__CLIP_DISABLE_MASK 0x10000\n#define PA_CL_CLIP_CNTL__CLIP_DISABLE__SHIFT 0x10\n#define PA_CL_CLIP_CNTL__UCP_CULL_ONLY_ENA_MASK 0x20000\n#define PA_CL_CLIP_CNTL__UCP_CULL_ONLY_ENA__SHIFT 0x11\n#define PA_CL_CLIP_CNTL__BOUNDARY_EDGE_FLAG_ENA_MASK 0x40000\n#define PA_CL_CLIP_CNTL__BOUNDARY_EDGE_FLAG_ENA__SHIFT 0x12\n#define PA_CL_CLIP_CNTL__DX_CLIP_SPACE_DEF_MASK 0x80000\n#define PA_CL_CLIP_CNTL__DX_CLIP_SPACE_DEF__SHIFT 0x13\n#define PA_CL_CLIP_CNTL__DIS_CLIP_ERR_DETECT_MASK 0x100000\n#define PA_CL_CLIP_CNTL__DIS_CLIP_ERR_DETECT__SHIFT 0x14\n#define PA_CL_CLIP_CNTL__VTX_KILL_OR_MASK 0x200000\n#define PA_CL_CLIP_CNTL__VTX_KILL_OR__SHIFT 0x15\n#define PA_CL_CLIP_CNTL__DX_RASTERIZATION_KILL_MASK 0x400000\n#define PA_CL_CLIP_CNTL__DX_RASTERIZATION_KILL__SHIFT 0x16\n#define PA_CL_CLIP_CNTL__DX_LINEAR_ATTR_CLIP_ENA_MASK 0x1000000\n#define PA_CL_CLIP_CNTL__DX_LINEAR_ATTR_CLIP_ENA__SHIFT 0x18\n#define PA_CL_CLIP_CNTL__VTE_VPORT_PROVOKE_DISABLE_MASK 0x2000000\n#define PA_CL_CLIP_CNTL__VTE_VPORT_PROVOKE_DISABLE__SHIFT 0x19\n#define PA_CL_CLIP_CNTL__ZCLIP_NEAR_DISABLE_MASK 0x4000000\n#define PA_CL_CLIP_CNTL__ZCLIP_NEAR_DISABLE__SHIFT 0x1a\n#define PA_CL_CLIP_CNTL__ZCLIP_FAR_DISABLE_MASK 0x8000000\n#define PA_CL_CLIP_CNTL__ZCLIP_FAR_DISABLE__SHIFT 0x1b\n#define PA_CL_GB_VERT_CLIP_ADJ__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_GB_VERT_CLIP_ADJ__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_GB_VERT_DISC_ADJ__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_GB_VERT_DISC_ADJ__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_GB_HORZ_CLIP_ADJ__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_GB_HORZ_CLIP_ADJ__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_GB_HORZ_DISC_ADJ__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_GB_HORZ_DISC_ADJ__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_0_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_0_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_0_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_0_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_0_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_0_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_0_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_0_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_1_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_1_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_1_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_1_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_1_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_1_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_1_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_1_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_2_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_2_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_2_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_2_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_2_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_2_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_2_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_2_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_3_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_3_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_3_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_3_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_3_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_3_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_3_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_3_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_4_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_4_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_4_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_4_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_4_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_4_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_4_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_4_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_5_X__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_5_X__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_5_Y__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_5_Y__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_5_Z__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_5_Z__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_UCP_5_W__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_UCP_5_W__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_POINT_X_RAD__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_POINT_X_RAD__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_POINT_Y_RAD__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_POINT_Y_RAD__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_POINT_SIZE__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_POINT_SIZE__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_POINT_CULL_RAD__DATA_REGISTER_MASK 0xffffffff\n#define PA_CL_POINT_CULL_RAD__DATA_REGISTER__SHIFT 0x0\n#define PA_CL_ENHANCE__CLIP_VTX_REORDER_ENA_MASK 0x1\n#define PA_CL_ENHANCE__CLIP_VTX_REORDER_ENA__SHIFT 0x0\n#define PA_CL_ENHANCE__NUM_CLIP_SEQ_MASK 0x6\n#define PA_CL_ENHANCE__NUM_CLIP_SEQ__SHIFT 0x1\n#define PA_CL_ENHANCE__CLIPPED_PRIM_SEQ_STALL_MASK 0x8\n#define PA_CL_ENHANCE__CLIPPED_PRIM_SEQ_STALL__SHIFT 0x3\n#define PA_CL_ENHANCE__VE_NAN_PROC_DISABLE_MASK 0x10\n#define PA_CL_ENHANCE__VE_NAN_PROC_DISABLE__SHIFT 0x4\n#define PA_CL_ENHANCE__XTRA_DEBUG_REG_SEL_MASK 0x20\n#define PA_CL_ENHANCE__XTRA_DEBUG_REG_SEL__SHIFT 0x5\n#define PA_CL_ENHANCE__ECO_SPARE3_MASK 0x10000000\n#define PA_CL_ENHANCE__ECO_SPARE3__SHIFT 0x1c\n#define PA_CL_ENHANCE__ECO_SPARE2_MASK 0x20000000\n#define PA_CL_ENHANCE__ECO_SPARE2__SHIFT 0x1d\n#define PA_CL_ENHANCE__ECO_SPARE1_MASK 0x40000000\n#define PA_CL_ENHANCE__ECO_SPARE1__SHIFT 0x1e\n#define PA_CL_ENHANCE__ECO_SPARE0_MASK 0x80000000\n#define PA_CL_ENHANCE__ECO_SPARE0__SHIFT 0x1f\n#define PA_CL_RESET_DEBUG__CL_TRIV_DISC_DISABLE_MASK 0x1\n#define PA_CL_RESET_DEBUG__CL_TRIV_DISC_DISABLE__SHIFT 0x0\n#define PA_SU_VTX_CNTL__PIX_CENTER_MASK 0x1\n#define PA_SU_VTX_CNTL__PIX_CENTER__SHIFT 0x0\n#define PA_SU_VTX_CNTL__ROUND_MODE_MASK 0x6\n#define PA_SU_VTX_CNTL__ROUND_MODE__SHIFT 0x1\n#define PA_SU_VTX_CNTL__QUANT_MODE_MASK 0x38\n#define PA_SU_VTX_CNTL__QUANT_MODE__SHIFT 0x3\n#define PA_SU_POINT_SIZE__HEIGHT_MASK 0xffff\n#define PA_SU_POINT_SIZE__HEIGHT__SHIFT 0x0\n#define PA_SU_POINT_SIZE__WIDTH_MASK 0xffff0000\n#define PA_SU_POINT_SIZE__WIDTH__SHIFT 0x10\n#define PA_SU_POINT_MINMAX__MIN_SIZE_MASK 0xffff\n#define PA_SU_POINT_MINMAX__MIN_SIZE__SHIFT 0x0\n#define PA_SU_POINT_MINMAX__MAX_SIZE_MASK 0xffff0000\n#define PA_SU_POINT_MINMAX__MAX_SIZE__SHIFT 0x10\n#define PA_SU_LINE_CNTL__WIDTH_MASK 0xffff\n#define PA_SU_LINE_CNTL__WIDTH__SHIFT 0x0\n#define PA_SU_LINE_STIPPLE_CNTL__LINE_STIPPLE_RESET_MASK 0x3\n#define PA_SU_LINE_STIPPLE_CNTL__LINE_STIPPLE_RESET__SHIFT 0x0\n#define PA_SU_LINE_STIPPLE_CNTL__EXPAND_FULL_LENGTH_MASK 0x4\n#define PA_SU_LINE_STIPPLE_CNTL__EXPAND_FULL_LENGTH__SHIFT 0x2\n#define PA_SU_LINE_STIPPLE_CNTL__FRACTIONAL_ACCUM_MASK 0x8\n#define PA_SU_LINE_STIPPLE_CNTL__FRACTIONAL_ACCUM__SHIFT 0x3\n#define PA_SU_LINE_STIPPLE_CNTL__DIAMOND_ADJUST_MASK 0x10\n#define PA_SU_LINE_STIPPLE_CNTL__DIAMOND_ADJUST__SHIFT 0x4\n#define PA_SU_LINE_STIPPLE_SCALE__LINE_STIPPLE_SCALE_MASK 0xffffffff\n#define PA_SU_LINE_STIPPLE_SCALE__LINE_STIPPLE_SCALE__SHIFT 0x0\n#define PA_SU_PRIM_FILTER_CNTL__TRIANGLE_FILTER_DISABLE_MASK 0x1\n#define PA_SU_PRIM_FILTER_CNTL__TRIANGLE_FILTER_DISABLE__SHIFT 0x0\n#define PA_SU_PRIM_FILTER_CNTL__LINE_FILTER_DISABLE_MASK 0x2\n#define PA_SU_PRIM_FILTER_CNTL__LINE_FILTER_DISABLE__SHIFT 0x1\n#define PA_SU_PRIM_FILTER_CNTL__POINT_FILTER_DISABLE_MASK 0x4\n#define PA_SU_PRIM_FILTER_CNTL__POINT_FILTER_DISABLE__SHIFT 0x2\n#define PA_SU_PRIM_FILTER_CNTL__RECTANGLE_FILTER_DISABLE_MASK 0x8\n#define PA_SU_PRIM_FILTER_CNTL__RECTANGLE_FILTER_DISABLE__SHIFT 0x3\n#define PA_SU_PRIM_FILTER_CNTL__TRIANGLE_EXPAND_ENA_MASK 0x10\n#define PA_SU_PRIM_FILTER_CNTL__TRIANGLE_EXPAND_ENA__SHIFT 0x4\n#define PA_SU_PRIM_FILTER_CNTL__LINE_EXPAND_ENA_MASK 0x20\n#define PA_SU_PRIM_FILTER_CNTL__LINE_EXPAND_ENA__SHIFT 0x5\n#define PA_SU_PRIM_FILTER_CNTL__POINT_EXPAND_ENA_MASK 0x40\n#define PA_SU_PRIM_FILTER_CNTL__POINT_EXPAND_ENA__SHIFT 0x6\n#define PA_SU_PRIM_FILTER_CNTL__RECTANGLE_EXPAND_ENA_MASK 0x80\n#define PA_SU_PRIM_FILTER_CNTL__RECTANGLE_EXPAND_ENA__SHIFT 0x7\n#define PA_SU_PRIM_FILTER_CNTL__PRIM_EXPAND_CONSTANT_MASK 0xff00\n#define PA_SU_PRIM_FILTER_CNTL__PRIM_EXPAND_CONSTANT__SHIFT 0x8\n#define PA_SU_PRIM_FILTER_CNTL__XMAX_RIGHT_EXCLUSION_MASK 0x40000000\n#define PA_SU_PRIM_FILTER_CNTL__XMAX_RIGHT_EXCLUSION__SHIFT 0x1e\n#define PA_SU_PRIM_FILTER_CNTL__YMAX_BOTTOM_EXCLUSION_MASK 0x80000000\n#define PA_SU_PRIM_FILTER_CNTL__YMAX_BOTTOM_EXCLUSION__SHIFT 0x1f\n#define PA_SU_SC_MODE_CNTL__CULL_FRONT_MASK 0x1\n#define PA_SU_SC_MODE_CNTL__CULL_FRONT__SHIFT 0x0\n#define PA_SU_SC_MODE_CNTL__CULL_BACK_MASK 0x2\n#define PA_SU_SC_MODE_CNTL__CULL_BACK__SHIFT 0x1\n#define PA_SU_SC_MODE_CNTL__FACE_MASK 0x4\n#define PA_SU_SC_MODE_CNTL__FACE__SHIFT 0x2\n#define PA_SU_SC_MODE_CNTL__POLY_MODE_MASK 0x18\n#define PA_SU_SC_MODE_CNTL__POLY_MODE__SHIFT 0x3\n#define PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE_MASK 0xe0\n#define PA_SU_SC_MODE_CNTL__POLYMODE_FRONT_PTYPE__SHIFT 0x5\n#define PA_SU_SC_MODE_CNTL__POLYMODE_BACK_PTYPE_MASK 0x700\n#define PA_SU_SC_MODE_CNTL__POLYMODE_BACK_PTYPE__SHIFT 0x8\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_FRONT_ENABLE_MASK 0x800\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_FRONT_ENABLE__SHIFT 0xb\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_BACK_ENABLE_MASK 0x1000\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_BACK_ENABLE__SHIFT 0xc\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_PARA_ENABLE_MASK 0x2000\n#define PA_SU_SC_MODE_CNTL__POLY_OFFSET_PARA_ENABLE__SHIFT 0xd\n#define PA_SU_SC_MODE_CNTL__VTX_WINDOW_OFFSET_ENABLE_MASK 0x10000\n#define PA_SU_SC_MODE_CNTL__VTX_WINDOW_OFFSET_ENABLE__SHIFT 0x10\n#define PA_SU_SC_MODE_CNTL__PROVOKING_VTX_LAST_MASK 0x80000\n#define PA_SU_SC_MODE_CNTL__PROVOKING_VTX_LAST__SHIFT 0x13\n#define PA_SU_SC_MODE_CNTL__PERSP_CORR_DIS_MASK 0x100000\n#define PA_SU_SC_MODE_CNTL__PERSP_CORR_DIS__SHIFT 0x14\n#define PA_SU_SC_MODE_CNTL__MULTI_PRIM_IB_ENA_MASK 0x200000\n#define PA_SU_SC_MODE_CNTL__MULTI_PRIM_IB_ENA__SHIFT 0x15\n#define PA_SU_POLY_OFFSET_DB_FMT_CNTL__POLY_OFFSET_NEG_NUM_DB_BITS_MASK 0xff\n#define PA_SU_POLY_OFFSET_DB_FMT_CNTL__POLY_OFFSET_NEG_NUM_DB_BITS__SHIFT 0x0\n#define PA_SU_POLY_OFFSET_DB_FMT_CNTL__POLY_OFFSET_DB_IS_FLOAT_FMT_MASK 0x100\n#define PA_SU_POLY_OFFSET_DB_FMT_CNTL__POLY_OFFSET_DB_IS_FLOAT_FMT__SHIFT 0x8\n#define PA_SU_POLY_OFFSET_CLAMP__CLAMP_MASK 0xffffffff\n#define PA_SU_POLY_OFFSET_CLAMP__CLAMP__SHIFT 0x0\n#define PA_SU_POLY_OFFSET_FRONT_SCALE__SCALE_MASK 0xffffffff\n#define PA_SU_POLY_OFFSET_FRONT_SCALE__SCALE__SHIFT 0x0\n#define PA_SU_POLY_OFFSET_FRONT_OFFSET__OFFSET_MASK 0xffffffff\n#define PA_SU_POLY_OFFSET_FRONT_OFFSET__OFFSET__SHIFT 0x0\n#define PA_SU_POLY_OFFSET_BACK_SCALE__SCALE_MASK 0xffffffff\n#define PA_SU_POLY_OFFSET_BACK_SCALE__SCALE__SHIFT 0x0\n#define PA_SU_POLY_OFFSET_BACK_OFFSET__OFFSET_MASK 0xffffffff\n#define PA_SU_POLY_OFFSET_BACK_OFFSET__OFFSET__SHIFT 0x0\n#define PA_SU_HARDWARE_SCREEN_OFFSET__HW_SCREEN_OFFSET_X_MASK 0x1ff\n#define PA_SU_HARDWARE_SCREEN_OFFSET__HW_SCREEN_OFFSET_X__SHIFT 0x0\n#define PA_SU_HARDWARE_SCREEN_OFFSET__HW_SCREEN_OFFSET_Y_MASK 0x1ff0000\n#define PA_SU_HARDWARE_SCREEN_OFFSET__HW_SCREEN_OFFSET_Y__SHIFT 0x10\n#define PA_SU_LINE_STIPPLE_VALUE__LINE_STIPPLE_VALUE_MASK 0xffffff\n#define PA_SU_LINE_STIPPLE_VALUE__LINE_STIPPLE_VALUE__SHIFT 0x0\n#define PA_SU_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SU_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SU_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define PA_SU_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define PA_SU_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define PA_SU_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define PA_SU_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define PA_SU_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define PA_SU_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define PA_SU_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define PA_SU_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SU_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SU_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define PA_SU_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define PA_SU_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define PA_SU_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define PA_SU_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define PA_SU_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define PA_SU_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define PA_SU_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define PA_SU_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SU_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SU_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define PA_SU_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define PA_SU_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SU_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SU_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define PA_SU_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define PA_SU_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SU_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SU_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffff\n#define PA_SU_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SU_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SU_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SU_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffff\n#define PA_SU_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SU_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SU_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SU_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffff\n#define PA_SU_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SU_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SU_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SU_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffff\n#define PA_SU_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_AA_CONFIG__MSAA_NUM_SAMPLES_MASK 0x7\n#define PA_SC_AA_CONFIG__MSAA_NUM_SAMPLES__SHIFT 0x0\n#define PA_SC_AA_CONFIG__AA_MASK_CENTROID_DTMN_MASK 0x10\n#define PA_SC_AA_CONFIG__AA_MASK_CENTROID_DTMN__SHIFT 0x4\n#define PA_SC_AA_CONFIG__MAX_SAMPLE_DIST_MASK 0x1e000\n#define PA_SC_AA_CONFIG__MAX_SAMPLE_DIST__SHIFT 0xd\n#define PA_SC_AA_CONFIG__MSAA_EXPOSED_SAMPLES_MASK 0x700000\n#define PA_SC_AA_CONFIG__MSAA_EXPOSED_SAMPLES__SHIFT 0x14\n#define PA_SC_AA_CONFIG__DETAIL_TO_EXPOSED_MODE_MASK 0x3000000\n#define PA_SC_AA_CONFIG__DETAIL_TO_EXPOSED_MODE__SHIFT 0x18\n#define PA_SC_AA_MASK_X0Y0_X1Y0__AA_MASK_X0Y0_MASK 0xffff\n#define PA_SC_AA_MASK_X0Y0_X1Y0__AA_MASK_X0Y0__SHIFT 0x0\n#define PA_SC_AA_MASK_X0Y0_X1Y0__AA_MASK_X1Y0_MASK 0xffff0000\n#define PA_SC_AA_MASK_X0Y0_X1Y0__AA_MASK_X1Y0__SHIFT 0x10\n#define PA_SC_AA_MASK_X0Y1_X1Y1__AA_MASK_X0Y1_MASK 0xffff\n#define PA_SC_AA_MASK_X0Y1_X1Y1__AA_MASK_X0Y1__SHIFT 0x0\n#define PA_SC_AA_MASK_X0Y1_X1Y1__AA_MASK_X1Y1_MASK 0xffff0000\n#define PA_SC_AA_MASK_X0Y1_X1Y1__AA_MASK_X1Y1__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S0_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S0_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S0_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S0_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S1_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S1_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S1_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S1_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S2_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S2_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S2_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S2_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S3_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S3_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S3_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0__S3_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S4_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S4_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S4_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S4_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S5_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S5_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S5_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S5_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S6_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S6_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S6_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S6_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S7_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S7_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S7_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1__S7_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S8_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S8_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S8_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S8_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S9_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S9_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S9_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S9_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S10_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S10_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S10_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S10_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S11_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S11_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S11_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2__S11_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S12_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S12_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S12_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S12_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S13_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S13_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S13_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S13_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S14_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S14_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S14_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S14_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S15_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S15_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S15_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3__S15_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S0_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S0_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S0_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S0_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S1_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S1_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S1_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S1_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S2_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S2_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S2_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S2_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S3_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S3_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S3_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0__S3_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S4_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S4_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S4_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S4_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S5_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S5_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S5_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S5_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S6_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S6_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S6_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S6_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S7_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S7_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S7_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1__S7_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S8_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S8_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S8_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S8_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S9_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S9_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S9_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S9_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S10_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S10_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S10_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S10_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S11_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S11_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S11_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2__S11_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S12_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S12_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S12_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S12_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S13_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S13_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S13_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S13_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S14_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S14_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S14_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S14_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S15_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S15_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S15_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3__S15_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S0_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S0_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S0_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S0_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S1_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S1_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S1_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S1_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S2_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S2_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S2_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S2_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S3_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S3_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S3_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0__S3_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S4_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S4_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S4_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S4_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S5_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S5_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S5_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S5_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S6_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S6_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S6_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S6_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S7_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S7_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S7_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1__S7_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S8_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S8_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S8_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S8_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S9_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S9_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S9_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S9_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S10_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S10_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S10_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S10_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S11_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S11_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S11_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2__S11_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S12_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S12_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S12_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S12_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S13_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S13_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S13_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S13_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S14_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S14_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S14_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S14_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S15_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S15_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S15_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3__S15_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S0_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S0_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S0_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S0_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S1_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S1_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S1_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S1_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S2_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S2_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S2_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S2_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S3_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S3_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S3_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0__S3_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S4_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S4_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S4_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S4_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S5_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S5_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S5_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S5_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S6_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S6_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S6_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S6_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S7_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S7_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S7_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1__S7_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S8_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S8_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S8_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S8_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S9_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S9_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S9_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S9_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S10_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S10_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S10_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S10_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S11_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S11_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S11_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2__S11_Y__SHIFT 0x1c\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S12_X_MASK 0xf\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S12_X__SHIFT 0x0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S12_Y_MASK 0xf0\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S12_Y__SHIFT 0x4\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S13_X_MASK 0xf00\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S13_X__SHIFT 0x8\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S13_Y_MASK 0xf000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S13_Y__SHIFT 0xc\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S14_X_MASK 0xf0000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S14_X__SHIFT 0x10\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S14_Y_MASK 0xf00000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S14_Y__SHIFT 0x14\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S15_X_MASK 0xf000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S15_X__SHIFT 0x18\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S15_Y_MASK 0xf0000000\n#define PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3__S15_Y__SHIFT 0x1c\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_0_MASK 0xf\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_0__SHIFT 0x0\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_1_MASK 0xf0\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_1__SHIFT 0x4\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_2_MASK 0xf00\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_2__SHIFT 0x8\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_3_MASK 0xf000\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_3__SHIFT 0xc\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_4_MASK 0xf0000\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_4__SHIFT 0x10\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_5_MASK 0xf00000\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_5__SHIFT 0x14\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_6_MASK 0xf000000\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_6__SHIFT 0x18\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_7_MASK 0xf0000000\n#define PA_SC_CENTROID_PRIORITY_0__DISTANCE_7__SHIFT 0x1c\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_8_MASK 0xf\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_8__SHIFT 0x0\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_9_MASK 0xf0\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_9__SHIFT 0x4\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_10_MASK 0xf00\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_10__SHIFT 0x8\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_11_MASK 0xf000\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_11__SHIFT 0xc\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_12_MASK 0xf0000\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_12__SHIFT 0x10\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_13_MASK 0xf00000\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_13__SHIFT 0x14\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_14_MASK 0xf000000\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_14__SHIFT 0x18\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_15_MASK 0xf0000000\n#define PA_SC_CENTROID_PRIORITY_1__DISTANCE_15__SHIFT 0x1c\n#define PA_SC_CLIPRECT_0_TL__TL_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_0_TL__TL_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_0_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_0_TL__TL_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_0_BR__BR_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_0_BR__BR_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_0_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_0_BR__BR_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_1_TL__TL_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_1_TL__TL_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_1_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_1_TL__TL_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_1_BR__BR_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_1_BR__BR_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_1_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_1_BR__BR_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_2_TL__TL_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_2_TL__TL_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_2_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_2_TL__TL_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_2_BR__BR_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_2_BR__BR_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_2_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_2_BR__BR_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_3_TL__TL_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_3_TL__TL_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_3_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_3_TL__TL_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_3_BR__BR_X_MASK 0x7fff\n#define PA_SC_CLIPRECT_3_BR__BR_X__SHIFT 0x0\n#define PA_SC_CLIPRECT_3_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_CLIPRECT_3_BR__BR_Y__SHIFT 0x10\n#define PA_SC_CLIPRECT_RULE__CLIP_RULE_MASK 0xffff\n#define PA_SC_CLIPRECT_RULE__CLIP_RULE__SHIFT 0x0\n#define PA_SC_EDGERULE__ER_TRI_MASK 0xf\n#define PA_SC_EDGERULE__ER_TRI__SHIFT 0x0\n#define PA_SC_EDGERULE__ER_POINT_MASK 0xf0\n#define PA_SC_EDGERULE__ER_POINT__SHIFT 0x4\n#define PA_SC_EDGERULE__ER_RECT_MASK 0xf00\n#define PA_SC_EDGERULE__ER_RECT__SHIFT 0x8\n#define PA_SC_EDGERULE__ER_LINE_LR_MASK 0x3f000\n#define PA_SC_EDGERULE__ER_LINE_LR__SHIFT 0xc\n#define PA_SC_EDGERULE__ER_LINE_RL_MASK 0xfc0000\n#define PA_SC_EDGERULE__ER_LINE_RL__SHIFT 0x12\n#define PA_SC_EDGERULE__ER_LINE_TB_MASK 0xf000000\n#define PA_SC_EDGERULE__ER_LINE_TB__SHIFT 0x18\n#define PA_SC_EDGERULE__ER_LINE_BT_MASK 0xf0000000\n#define PA_SC_EDGERULE__ER_LINE_BT__SHIFT 0x1c\n#define PA_SC_LINE_CNTL__EXPAND_LINE_WIDTH_MASK 0x200\n#define PA_SC_LINE_CNTL__EXPAND_LINE_WIDTH__SHIFT 0x9\n#define PA_SC_LINE_CNTL__LAST_PIXEL_MASK 0x400\n#define PA_SC_LINE_CNTL__LAST_PIXEL__SHIFT 0xa\n#define PA_SC_LINE_CNTL__PERPENDICULAR_ENDCAP_ENA_MASK 0x800\n#define PA_SC_LINE_CNTL__PERPENDICULAR_ENDCAP_ENA__SHIFT 0xb\n#define PA_SC_LINE_CNTL__DX10_DIAMOND_TEST_ENA_MASK 0x1000\n#define PA_SC_LINE_CNTL__DX10_DIAMOND_TEST_ENA__SHIFT 0xc\n#define PA_SC_LINE_STIPPLE__LINE_PATTERN_MASK 0xffff\n#define PA_SC_LINE_STIPPLE__LINE_PATTERN__SHIFT 0x0\n#define PA_SC_LINE_STIPPLE__REPEAT_COUNT_MASK 0xff0000\n#define PA_SC_LINE_STIPPLE__REPEAT_COUNT__SHIFT 0x10\n#define PA_SC_LINE_STIPPLE__PATTERN_BIT_ORDER_MASK 0x10000000\n#define PA_SC_LINE_STIPPLE__PATTERN_BIT_ORDER__SHIFT 0x1c\n#define PA_SC_LINE_STIPPLE__AUTO_RESET_CNTL_MASK 0x60000000\n#define PA_SC_LINE_STIPPLE__AUTO_RESET_CNTL__SHIFT 0x1d\n#define PA_SC_MODE_CNTL_0__MSAA_ENABLE_MASK 0x1\n#define PA_SC_MODE_CNTL_0__MSAA_ENABLE__SHIFT 0x0\n#define PA_SC_MODE_CNTL_0__VPORT_SCISSOR_ENABLE_MASK 0x2\n#define PA_SC_MODE_CNTL_0__VPORT_SCISSOR_ENABLE__SHIFT 0x1\n#define PA_SC_MODE_CNTL_0__LINE_STIPPLE_ENABLE_MASK 0x4\n#define PA_SC_MODE_CNTL_0__LINE_STIPPLE_ENABLE__SHIFT 0x2\n#define PA_SC_MODE_CNTL_0__SEND_UNLIT_STILES_TO_PKR_MASK 0x8\n#define PA_SC_MODE_CNTL_0__SEND_UNLIT_STILES_TO_PKR__SHIFT 0x3\n#define PA_SC_MODE_CNTL_1__WALK_SIZE_MASK 0x1\n#define PA_SC_MODE_CNTL_1__WALK_SIZE__SHIFT 0x0\n#define PA_SC_MODE_CNTL_1__WALK_ALIGNMENT_MASK 0x2\n#define PA_SC_MODE_CNTL_1__WALK_ALIGNMENT__SHIFT 0x1\n#define PA_SC_MODE_CNTL_1__WALK_ALIGN8_PRIM_FITS_ST_MASK 0x4\n#define PA_SC_MODE_CNTL_1__WALK_ALIGN8_PRIM_FITS_ST__SHIFT 0x2\n#define PA_SC_MODE_CNTL_1__WALK_FENCE_ENABLE_MASK 0x8\n#define PA_SC_MODE_CNTL_1__WALK_FENCE_ENABLE__SHIFT 0x3\n#define PA_SC_MODE_CNTL_1__WALK_FENCE_SIZE_MASK 0x70\n#define PA_SC_MODE_CNTL_1__WALK_FENCE_SIZE__SHIFT 0x4\n#define PA_SC_MODE_CNTL_1__SUPERTILE_WALK_ORDER_ENABLE_MASK 0x80\n#define PA_SC_MODE_CNTL_1__SUPERTILE_WALK_ORDER_ENABLE__SHIFT 0x7\n#define PA_SC_MODE_CNTL_1__TILE_WALK_ORDER_ENABLE_MASK 0x100\n#define PA_SC_MODE_CNTL_1__TILE_WALK_ORDER_ENABLE__SHIFT 0x8\n#define PA_SC_MODE_CNTL_1__TILE_COVER_DISABLE_MASK 0x200\n#define PA_SC_MODE_CNTL_1__TILE_COVER_DISABLE__SHIFT 0x9\n#define PA_SC_MODE_CNTL_1__TILE_COVER_NO_SCISSOR_MASK 0x400\n#define PA_SC_MODE_CNTL_1__TILE_COVER_NO_SCISSOR__SHIFT 0xa\n#define PA_SC_MODE_CNTL_1__ZMM_LINE_EXTENT_MASK 0x800\n#define PA_SC_MODE_CNTL_1__ZMM_LINE_EXTENT__SHIFT 0xb\n#define PA_SC_MODE_CNTL_1__ZMM_LINE_OFFSET_MASK 0x1000\n#define PA_SC_MODE_CNTL_1__ZMM_LINE_OFFSET__SHIFT 0xc\n#define PA_SC_MODE_CNTL_1__ZMM_RECT_EXTENT_MASK 0x2000\n#define PA_SC_MODE_CNTL_1__ZMM_RECT_EXTENT__SHIFT 0xd\n#define PA_SC_MODE_CNTL_1__KILL_PIX_POST_HI_Z_MASK 0x4000\n#define PA_SC_MODE_CNTL_1__KILL_PIX_POST_HI_Z__SHIFT 0xe\n#define PA_SC_MODE_CNTL_1__KILL_PIX_POST_DETAIL_MASK_MASK 0x8000\n#define PA_SC_MODE_CNTL_1__KILL_PIX_POST_DETAIL_MASK__SHIFT 0xf\n#define PA_SC_MODE_CNTL_1__PS_ITER_SAMPLE_MASK 0x10000\n#define PA_SC_MODE_CNTL_1__PS_ITER_SAMPLE__SHIFT 0x10\n#define PA_SC_MODE_CNTL_1__MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE_MASK 0x20000\n#define PA_SC_MODE_CNTL_1__MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE__SHIFT 0x11\n#define PA_SC_MODE_CNTL_1__MULTI_GPU_SUPERTILE_ENABLE_MASK 0x40000\n#define PA_SC_MODE_CNTL_1__MULTI_GPU_SUPERTILE_ENABLE__SHIFT 0x12\n#define PA_SC_MODE_CNTL_1__GPU_ID_OVERRIDE_ENABLE_MASK 0x80000\n#define PA_SC_MODE_CNTL_1__GPU_ID_OVERRIDE_ENABLE__SHIFT 0x13\n#define PA_SC_MODE_CNTL_1__GPU_ID_OVERRIDE_MASK 0xf00000\n#define PA_SC_MODE_CNTL_1__GPU_ID_OVERRIDE__SHIFT 0x14\n#define PA_SC_MODE_CNTL_1__MULTI_GPU_PRIM_DISCARD_ENABLE_MASK 0x1000000\n#define PA_SC_MODE_CNTL_1__MULTI_GPU_PRIM_DISCARD_ENABLE__SHIFT 0x18\n#define PA_SC_MODE_CNTL_1__FORCE_EOV_CNTDWN_ENABLE_MASK 0x2000000\n#define PA_SC_MODE_CNTL_1__FORCE_EOV_CNTDWN_ENABLE__SHIFT 0x19\n#define PA_SC_MODE_CNTL_1__FORCE_EOV_REZ_ENABLE_MASK 0x4000000\n#define PA_SC_MODE_CNTL_1__FORCE_EOV_REZ_ENABLE__SHIFT 0x1a\n#define PA_SC_MODE_CNTL_1__OUT_OF_ORDER_PRIMITIVE_ENABLE_MASK 0x8000000\n#define PA_SC_MODE_CNTL_1__OUT_OF_ORDER_PRIMITIVE_ENABLE__SHIFT 0x1b\n#define PA_SC_MODE_CNTL_1__OUT_OF_ORDER_WATER_MARK_MASK 0x70000000\n#define PA_SC_MODE_CNTL_1__OUT_OF_ORDER_WATER_MARK__SHIFT 0x1c\n#define PA_SC_RASTER_CONFIG__RB_MAP_PKR0_MASK 0x3\n#define PA_SC_RASTER_CONFIG__RB_MAP_PKR0__SHIFT 0x0\n#define PA_SC_RASTER_CONFIG__RB_MAP_PKR1_MASK 0xc\n#define PA_SC_RASTER_CONFIG__RB_MAP_PKR1__SHIFT 0x2\n#define PA_SC_RASTER_CONFIG__RB_XSEL2_MASK 0x30\n#define PA_SC_RASTER_CONFIG__RB_XSEL2__SHIFT 0x4\n#define PA_SC_RASTER_CONFIG__RB_XSEL_MASK 0x40\n#define PA_SC_RASTER_CONFIG__RB_XSEL__SHIFT 0x6\n#define PA_SC_RASTER_CONFIG__RB_YSEL_MASK 0x80\n#define PA_SC_RASTER_CONFIG__RB_YSEL__SHIFT 0x7\n#define PA_SC_RASTER_CONFIG__PKR_MAP_MASK 0x300\n#define PA_SC_RASTER_CONFIG__PKR_MAP__SHIFT 0x8\n#define PA_SC_RASTER_CONFIG__PKR_XSEL_MASK 0xc00\n#define PA_SC_RASTER_CONFIG__PKR_XSEL__SHIFT 0xa\n#define PA_SC_RASTER_CONFIG__PKR_YSEL_MASK 0x3000\n#define PA_SC_RASTER_CONFIG__PKR_YSEL__SHIFT 0xc\n#define PA_SC_RASTER_CONFIG__PKR_XSEL2_MASK 0xc000\n#define PA_SC_RASTER_CONFIG__PKR_XSEL2__SHIFT 0xe\n#define PA_SC_RASTER_CONFIG__SC_MAP_MASK 0x30000\n#define PA_SC_RASTER_CONFIG__SC_MAP__SHIFT 0x10\n#define PA_SC_RASTER_CONFIG__SC_XSEL_MASK 0xc0000\n#define PA_SC_RASTER_CONFIG__SC_XSEL__SHIFT 0x12\n#define PA_SC_RASTER_CONFIG__SC_YSEL_MASK 0x300000\n#define PA_SC_RASTER_CONFIG__SC_YSEL__SHIFT 0x14\n#define PA_SC_RASTER_CONFIG__SE_MAP_MASK 0x3000000\n#define PA_SC_RASTER_CONFIG__SE_MAP__SHIFT 0x18\n#define PA_SC_RASTER_CONFIG__SE_XSEL_MASK 0xc000000\n#define PA_SC_RASTER_CONFIG__SE_XSEL__SHIFT 0x1a\n#define PA_SC_RASTER_CONFIG__SE_YSEL_MASK 0x30000000\n#define PA_SC_RASTER_CONFIG__SE_YSEL__SHIFT 0x1c\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_MAP_MASK 0x3\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_MAP__SHIFT 0x0\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_XSEL_MASK 0xc\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_XSEL__SHIFT 0x2\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_YSEL_MASK 0x30\n#define PA_SC_RASTER_CONFIG_1__SE_PAIR_YSEL__SHIFT 0x4\n#define PA_SC_SCREEN_EXTENT_CONTROL__SLICE_EVEN_ENABLE_MASK 0x3\n#define PA_SC_SCREEN_EXTENT_CONTROL__SLICE_EVEN_ENABLE__SHIFT 0x0\n#define PA_SC_SCREEN_EXTENT_CONTROL__SLICE_ODD_ENABLE_MASK 0xc\n#define PA_SC_SCREEN_EXTENT_CONTROL__SLICE_ODD_ENABLE__SHIFT 0x2\n#define PA_SC_GENERIC_SCISSOR_TL__TL_X_MASK 0x7fff\n#define PA_SC_GENERIC_SCISSOR_TL__TL_X__SHIFT 0x0\n#define PA_SC_GENERIC_SCISSOR_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_GENERIC_SCISSOR_TL__TL_Y__SHIFT 0x10\n#define PA_SC_GENERIC_SCISSOR_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_GENERIC_SCISSOR_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_GENERIC_SCISSOR_BR__BR_X_MASK 0x7fff\n#define PA_SC_GENERIC_SCISSOR_BR__BR_X__SHIFT 0x0\n#define PA_SC_GENERIC_SCISSOR_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_GENERIC_SCISSOR_BR__BR_Y__SHIFT 0x10\n#define PA_SC_SCREEN_SCISSOR_TL__TL_X_MASK 0xffff\n#define PA_SC_SCREEN_SCISSOR_TL__TL_X__SHIFT 0x0\n#define PA_SC_SCREEN_SCISSOR_TL__TL_Y_MASK 0xffff0000\n#define PA_SC_SCREEN_SCISSOR_TL__TL_Y__SHIFT 0x10\n#define PA_SC_SCREEN_SCISSOR_BR__BR_X_MASK 0xffff\n#define PA_SC_SCREEN_SCISSOR_BR__BR_X__SHIFT 0x0\n#define PA_SC_SCREEN_SCISSOR_BR__BR_Y_MASK 0xffff0000\n#define PA_SC_SCREEN_SCISSOR_BR__BR_Y__SHIFT 0x10\n#define PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET_MASK 0xffff\n#define PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET__SHIFT 0x0\n#define PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET_MASK 0xffff0000\n#define PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET__SHIFT 0x10\n#define PA_SC_WINDOW_SCISSOR_TL__TL_X_MASK 0x7fff\n#define PA_SC_WINDOW_SCISSOR_TL__TL_X__SHIFT 0x0\n#define PA_SC_WINDOW_SCISSOR_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_WINDOW_SCISSOR_TL__TL_Y__SHIFT 0x10\n#define PA_SC_WINDOW_SCISSOR_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_WINDOW_SCISSOR_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_WINDOW_SCISSOR_BR__BR_X_MASK 0x7fff\n#define PA_SC_WINDOW_SCISSOR_BR__BR_X__SHIFT 0x0\n#define PA_SC_WINDOW_SCISSOR_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_WINDOW_SCISSOR_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_0_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_0_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_0_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_0_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_0_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_0_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_1_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_1_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_1_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_1_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_1_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_1_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_2_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_2_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_2_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_2_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_2_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_2_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_3_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_3_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_3_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_3_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_3_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_3_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_4_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_4_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_4_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_4_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_4_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_4_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_5_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_5_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_5_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_5_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_5_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_5_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_6_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_6_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_6_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_6_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_6_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_6_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_7_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_7_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_7_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_7_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_7_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_7_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_8_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_8_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_8_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_8_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_8_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_8_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_9_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_9_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_9_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_9_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_9_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_9_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_10_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_10_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_10_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_10_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_10_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_10_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_11_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_11_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_11_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_11_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_11_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_11_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_12_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_12_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_12_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_12_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_12_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_12_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_13_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_13_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_13_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_13_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_13_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_13_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_14_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_14_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_14_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_14_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_14_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_14_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_15_TL__TL_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_15_TL__TL_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_15_TL__TL_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_15_TL__TL_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_15_TL__WINDOW_OFFSET_DISABLE_MASK 0x80000000\n#define PA_SC_VPORT_SCISSOR_15_TL__WINDOW_OFFSET_DISABLE__SHIFT 0x1f\n#define PA_SC_VPORT_SCISSOR_0_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_0_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_0_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_0_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_1_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_1_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_1_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_1_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_2_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_2_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_2_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_2_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_3_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_3_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_3_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_3_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_4_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_4_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_4_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_4_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_5_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_5_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_5_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_5_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_6_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_6_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_6_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_6_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_7_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_7_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_7_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_7_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_8_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_8_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_8_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_8_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_9_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_9_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_9_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_9_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_10_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_10_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_10_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_10_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_11_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_11_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_11_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_11_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_12_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_12_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_12_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_12_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_13_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_13_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_13_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_13_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_14_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_14_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_14_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_14_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_SCISSOR_15_BR__BR_X_MASK 0x7fff\n#define PA_SC_VPORT_SCISSOR_15_BR__BR_X__SHIFT 0x0\n#define PA_SC_VPORT_SCISSOR_15_BR__BR_Y_MASK 0x7fff0000\n#define PA_SC_VPORT_SCISSOR_15_BR__BR_Y__SHIFT 0x10\n#define PA_SC_VPORT_ZMIN_0__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_0__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_1__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_1__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_2__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_2__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_3__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_3__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_4__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_4__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_5__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_5__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_6__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_6__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_7__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_7__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_8__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_8__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_9__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_9__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_10__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_10__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_11__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_11__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_12__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_12__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_13__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_13__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_14__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_14__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMIN_15__VPORT_ZMIN_MASK 0xffffffff\n#define PA_SC_VPORT_ZMIN_15__VPORT_ZMIN__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_0__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_0__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_1__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_1__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_2__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_2__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_3__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_3__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_4__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_4__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_5__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_5__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_6__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_6__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_7__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_7__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_8__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_8__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_9__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_9__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_10__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_10__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_11__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_11__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_12__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_12__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_13__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_13__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_14__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_14__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_VPORT_ZMAX_15__VPORT_ZMAX_MASK 0xffffffff\n#define PA_SC_VPORT_ZMAX_15__VPORT_ZMAX__SHIFT 0x0\n#define PA_SC_ENHANCE__ENABLE_PA_SC_OUT_OF_ORDER_MASK 0x1\n#define PA_SC_ENHANCE__ENABLE_PA_SC_OUT_OF_ORDER__SHIFT 0x0\n#define PA_SC_ENHANCE__DISABLE_SC_DB_TILE_FIX_MASK 0x2\n#define PA_SC_ENHANCE__DISABLE_SC_DB_TILE_FIX__SHIFT 0x1\n#define PA_SC_ENHANCE__DISABLE_AA_MASK_FULL_FIX_MASK 0x4\n#define PA_SC_ENHANCE__DISABLE_AA_MASK_FULL_FIX__SHIFT 0x2\n#define PA_SC_ENHANCE__ENABLE_1XMSAA_SAMPLE_LOCATIONS_MASK 0x8\n#define PA_SC_ENHANCE__ENABLE_1XMSAA_SAMPLE_LOCATIONS__SHIFT 0x3\n#define PA_SC_ENHANCE__ENABLE_1XMSAA_SAMPLE_LOC_CENTROID_MASK 0x10\n#define PA_SC_ENHANCE__ENABLE_1XMSAA_SAMPLE_LOC_CENTROID__SHIFT 0x4\n#define PA_SC_ENHANCE__DISABLE_SCISSOR_FIX_MASK 0x20\n#define PA_SC_ENHANCE__DISABLE_SCISSOR_FIX__SHIFT 0x5\n#define PA_SC_ENHANCE__DISABLE_PW_BUBBLE_COLLAPSE_MASK 0xc0\n#define PA_SC_ENHANCE__DISABLE_PW_BUBBLE_COLLAPSE__SHIFT 0x6\n#define PA_SC_ENHANCE__SEND_UNLIT_STILES_TO_PACKER_MASK 0x100\n#define PA_SC_ENHANCE__SEND_UNLIT_STILES_TO_PACKER__SHIFT 0x8\n#define PA_SC_ENHANCE__DISABLE_DUALGRAD_PERF_OPTIMIZATION_MASK 0x200\n#define PA_SC_ENHANCE__DISABLE_DUALGRAD_PERF_OPTIMIZATION__SHIFT 0x9\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_PRIM_MASK 0x400\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_PRIM__SHIFT 0xa\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_SUPERTILE_MASK 0x800\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_SUPERTILE__SHIFT 0xb\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_TILE_MASK 0x1000\n#define PA_SC_ENHANCE__DISABLE_SC_PROCESS_RESET_TILE__SHIFT 0xc\n#define PA_SC_ENHANCE__DISABLE_PA_SC_GUIDANCE_MASK 0x2000\n#define PA_SC_ENHANCE__DISABLE_PA_SC_GUIDANCE__SHIFT 0xd\n#define PA_SC_ENHANCE__DISABLE_EOV_ALL_CTRL_ONLY_COMBINATIONS_MASK 0x4000\n#define PA_SC_ENHANCE__DISABLE_EOV_ALL_CTRL_ONLY_COMBINATIONS__SHIFT 0xe\n#define PA_SC_ENHANCE__ENABLE_MULTICYCLE_BUBBLE_FREEZE_MASK 0x8000\n#define PA_SC_ENHANCE__ENABLE_MULTICYCLE_BUBBLE_FREEZE__SHIFT 0xf\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_PA_SC_GUIDANCE_MASK 0x10000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_PA_SC_GUIDANCE__SHIFT 0x10\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_POLY_MODE_MASK 0x20000\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_POLY_MODE__SHIFT 0x11\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_EOP_SYNC_NULL_PRIMS_LAST_MASK 0x40000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_EOP_SYNC_NULL_PRIMS_LAST__SHIFT 0x12\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_THRESHOLD_SWITCHING_MASK 0x80000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_THRESHOLD_SWITCHING__SHIFT 0x13\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_THRESHOLD_SWITCH_AT_EOPG_ONLY_MASK 0x100000\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_THRESHOLD_SWITCH_AT_EOPG_ONLY__SHIFT 0x14\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_DESIRED_FIFO_EMPTY_SWITCHING_MASK 0x200000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_DESIRED_FIFO_EMPTY_SWITCHING__SHIFT 0x15\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_SELECTED_FIFO_EMPTY_SWITCHING_MASK 0x400000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_SELECTED_FIFO_EMPTY_SWITCHING__SHIFT 0x16\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_EMPTY_SWITCHING_HYSTERYSIS_MASK 0x800000\n#define PA_SC_ENHANCE__DISABLE_OUT_OF_ORDER_EMPTY_SWITCHING_HYSTERYSIS__SHIFT 0x17\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_DESIRED_FIFO_IS_NEXT_FEID_MASK 0x1000000\n#define PA_SC_ENHANCE__ENABLE_OUT_OF_ORDER_DESIRED_FIFO_IS_NEXT_FEID__SHIFT 0x18\n#define PA_SC_ENHANCE__DISABLE_OOO_NO_EOPG_SKEW_DESIRED_FIFO_IS_CURRENT_FIFO_MASK 0x2000000\n#define PA_SC_ENHANCE__DISABLE_OOO_NO_EOPG_SKEW_DESIRED_FIFO_IS_CURRENT_FIFO__SHIFT 0x19\n#define PA_SC_ENHANCE__OOO_DISABLE_EOP_ON_FIRST_LIVE_PRIM_HIT_MASK 0x4000000\n#define PA_SC_ENHANCE__OOO_DISABLE_EOP_ON_FIRST_LIVE_PRIM_HIT__SHIFT 0x1a\n#define PA_SC_ENHANCE__OOO_DISABLE_EOPG_SKEW_THRESHOLD_SWITCHING_MASK 0x8000000\n#define PA_SC_ENHANCE__OOO_DISABLE_EOPG_SKEW_THRESHOLD_SWITCHING__SHIFT 0x1b\n#define PA_SC_ENHANCE__DISABLE_EOP_LINE_STIPPLE_RESET_MASK 0x10000000\n#define PA_SC_ENHANCE__DISABLE_EOP_LINE_STIPPLE_RESET__SHIFT 0x1c\n#define PA_SC_ENHANCE__DISABLE_VPZ_EOP_LINE_STIPPLE_RESET_MASK 0x20000000\n#define PA_SC_ENHANCE__DISABLE_VPZ_EOP_LINE_STIPPLE_RESET__SHIFT 0x1d\n#define PA_SC_ENHANCE__ECO_SPARE1_MASK 0x40000000\n#define PA_SC_ENHANCE__ECO_SPARE1__SHIFT 0x1e\n#define PA_SC_ENHANCE__ECO_SPARE0_MASK 0x80000000\n#define PA_SC_ENHANCE__ECO_SPARE0__SHIFT 0x1f\n#define PA_SC_FIFO_SIZE__SC_FRONTEND_PRIM_FIFO_SIZE_MASK 0x3f\n#define PA_SC_FIFO_SIZE__SC_FRONTEND_PRIM_FIFO_SIZE__SHIFT 0x0\n#define PA_SC_FIFO_SIZE__SC_BACKEND_PRIM_FIFO_SIZE_MASK 0x7fc0\n#define PA_SC_FIFO_SIZE__SC_BACKEND_PRIM_FIFO_SIZE__SHIFT 0x6\n#define PA_SC_FIFO_SIZE__SC_HIZ_TILE_FIFO_SIZE_MASK 0x1f8000\n#define PA_SC_FIFO_SIZE__SC_HIZ_TILE_FIFO_SIZE__SHIFT 0xf\n#define PA_SC_FIFO_SIZE__SC_EARLYZ_TILE_FIFO_SIZE_MASK 0xff800000\n#define PA_SC_FIFO_SIZE__SC_EARLYZ_TILE_FIFO_SIZE__SHIFT 0x17\n#define PA_SC_IF_FIFO_SIZE__SC_DB_TILE_IF_FIFO_SIZE_MASK 0x3f\n#define PA_SC_IF_FIFO_SIZE__SC_DB_TILE_IF_FIFO_SIZE__SHIFT 0x0\n#define PA_SC_IF_FIFO_SIZE__SC_DB_QUAD_IF_FIFO_SIZE_MASK 0xfc0\n#define PA_SC_IF_FIFO_SIZE__SC_DB_QUAD_IF_FIFO_SIZE__SHIFT 0x6\n#define PA_SC_IF_FIFO_SIZE__SC_SPI_IF_FIFO_SIZE_MASK 0x3f000\n#define PA_SC_IF_FIFO_SIZE__SC_SPI_IF_FIFO_SIZE__SHIFT 0xc\n#define PA_SC_IF_FIFO_SIZE__SC_BCI_IF_FIFO_SIZE_MASK 0xfc0000\n#define PA_SC_IF_FIFO_SIZE__SC_BCI_IF_FIFO_SIZE__SHIFT 0x12\n#define PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT_MASK 0xffff\n#define PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT__SHIFT 0x0\n#define PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT_MASK 0xffff0000\n#define PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT__SHIFT 0x10\n#define PA_SC_LINE_STIPPLE_STATE__CURRENT_PTR_MASK 0xf\n#define PA_SC_LINE_STIPPLE_STATE__CURRENT_PTR__SHIFT 0x0\n#define PA_SC_LINE_STIPPLE_STATE__CURRENT_COUNT_MASK 0xff00\n#define PA_SC_LINE_STIPPLE_STATE__CURRENT_COUNT__SHIFT 0x8\n#define PA_SC_SCREEN_EXTENT_MIN_0__X_MASK 0xffff\n#define PA_SC_SCREEN_EXTENT_MIN_0__X__SHIFT 0x0\n#define PA_SC_SCREEN_EXTENT_MIN_0__Y_MASK 0xffff0000\n#define PA_SC_SCREEN_EXTENT_MIN_0__Y__SHIFT 0x10\n#define PA_SC_SCREEN_EXTENT_MAX_0__X_MASK 0xffff\n#define PA_SC_SCREEN_EXTENT_MAX_0__X__SHIFT 0x0\n#define PA_SC_SCREEN_EXTENT_MAX_0__Y_MASK 0xffff0000\n#define PA_SC_SCREEN_EXTENT_MAX_0__Y__SHIFT 0x10\n#define PA_SC_SCREEN_EXTENT_MIN_1__X_MASK 0xffff\n#define PA_SC_SCREEN_EXTENT_MIN_1__X__SHIFT 0x0\n#define PA_SC_SCREEN_EXTENT_MIN_1__Y_MASK 0xffff0000\n#define PA_SC_SCREEN_EXTENT_MIN_1__Y__SHIFT 0x10\n#define PA_SC_SCREEN_EXTENT_MAX_1__X_MASK 0xffff\n#define PA_SC_SCREEN_EXTENT_MAX_1__X__SHIFT 0x0\n#define PA_SC_SCREEN_EXTENT_MAX_1__Y_MASK 0xffff0000\n#define PA_SC_SCREEN_EXTENT_MAX_1__Y__SHIFT 0x10\n#define PA_SC_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define PA_SC_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define PA_SC_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define PA_SC_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define PA_SC_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define PA_SC_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define PA_SC_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define PA_SC_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define PA_SC_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER4_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER4_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER5_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER5_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER6_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER6_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER7_SELECT__PERF_SEL_MASK 0x3ff\n#define PA_SC_PERFCOUNTER7_SELECT__PERF_SEL__SHIFT 0x0\n#define PA_SC_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER4_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER4_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER4_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER4_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER5_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER5_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER5_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER5_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER6_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER6_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER6_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER6_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_PERFCOUNTER7_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER7_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define PA_SC_PERFCOUNTER7_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define PA_SC_PERFCOUNTER7_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER_MASK 0x1\n#define PA_SC_P3D_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS_MASK 0x2\n#define PA_SC_P3D_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS__SHIFT 0x1\n#define PA_SC_P3D_TRAP_SCREEN_H__X_COORD_MASK 0x3fff\n#define PA_SC_P3D_TRAP_SCREEN_H__X_COORD__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_V__Y_COORD_MASK 0x3fff\n#define PA_SC_P3D_TRAP_SCREEN_V__Y_COORD__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_OCCURRENCE__COUNT_MASK 0xffff\n#define PA_SC_P3D_TRAP_SCREEN_OCCURRENCE__COUNT__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_COUNT__COUNT_MASK 0xffff\n#define PA_SC_P3D_TRAP_SCREEN_COUNT__COUNT__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER_MASK 0x1\n#define PA_SC_HP3D_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS_MASK 0x2\n#define PA_SC_HP3D_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS__SHIFT 0x1\n#define PA_SC_HP3D_TRAP_SCREEN_H__X_COORD_MASK 0x3fff\n#define PA_SC_HP3D_TRAP_SCREEN_H__X_COORD__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_V__Y_COORD_MASK 0x3fff\n#define PA_SC_HP3D_TRAP_SCREEN_V__Y_COORD__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_OCCURRENCE__COUNT_MASK 0xffff\n#define PA_SC_HP3D_TRAP_SCREEN_OCCURRENCE__COUNT__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_COUNT__COUNT_MASK 0xffff\n#define PA_SC_HP3D_TRAP_SCREEN_COUNT__COUNT__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER_MASK 0x1\n#define PA_SC_TRAP_SCREEN_HV_EN__ENABLE_HV_PRE_SHADER__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS_MASK 0x2\n#define PA_SC_TRAP_SCREEN_HV_EN__FORCE_PRE_SHADER_ALL_PIXELS__SHIFT 0x1\n#define PA_SC_TRAP_SCREEN_H__X_COORD_MASK 0x3fff\n#define PA_SC_TRAP_SCREEN_H__X_COORD__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_V__Y_COORD_MASK 0x3fff\n#define PA_SC_TRAP_SCREEN_V__Y_COORD__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_OCCURRENCE__COUNT_MASK 0xffff\n#define PA_SC_TRAP_SCREEN_OCCURRENCE__COUNT__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_COUNT__COUNT_MASK 0xffff\n#define PA_SC_TRAP_SCREEN_COUNT__COUNT__SHIFT 0x0\n#define PA_SC_P3D_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES_MASK 0x1\n#define PA_SC_P3D_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES__SHIFT 0x0\n#define PA_SC_HP3D_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES_MASK 0x1\n#define PA_SC_HP3D_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES__SHIFT 0x0\n#define PA_SC_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES_MASK 0x1\n#define PA_SC_TRAP_SCREEN_HV_LOCK__DISABLE_NON_PRIV_WRITES__SHIFT 0x0\n#define PA_CL_CNTL_STATUS__CL_BUSY_MASK 0x80000000\n#define PA_CL_CNTL_STATUS__CL_BUSY__SHIFT 0x1f\n#define PA_SU_CNTL_STATUS__SU_BUSY_MASK 0x80000000\n#define PA_SU_CNTL_STATUS__SU_BUSY__SHIFT 0x1f\n#define PA_SC_FIFO_DEPTH_CNTL__DEPTH_MASK 0x3ff\n#define PA_SC_FIFO_DEPTH_CNTL__DEPTH__SHIFT 0x0\n#define CGTT_PA_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_PA_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_PA_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_PA_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_PA_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_PA_CLK_CTRL__SU_CLK_OVERRIDE_MASK 0x20000000\n#define CGTT_PA_CLK_CTRL__SU_CLK_OVERRIDE__SHIFT 0x1d\n#define CGTT_PA_CLK_CTRL__CL_CLK_OVERRIDE_MASK 0x40000000\n#define CGTT_PA_CLK_CTRL__CL_CLK_OVERRIDE__SHIFT 0x1e\n#define CGTT_PA_CLK_CTRL__REG_CLK_OVERRIDE_MASK 0x80000000\n#define CGTT_PA_CLK_CTRL__REG_CLK_OVERRIDE__SHIFT 0x1f\n#define CGTT_SC_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_SC_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_SC_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SC_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SC_CLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define PA_SU_DEBUG_CNTL__SU_DEBUG_INDX_MASK 0x1f\n#define PA_SU_DEBUG_CNTL__SU_DEBUG_INDX__SHIFT 0x0\n#define PA_SU_DEBUG_DATA__DATA_MASK 0xffffffff\n#define PA_SU_DEBUG_DATA__DATA__SHIFT 0x0\n#define PA_SC_DEBUG_CNTL__SC_DEBUG_INDX_MASK 0x3f\n#define PA_SC_DEBUG_CNTL__SC_DEBUG_INDX__SHIFT 0x0\n#define PA_SC_DEBUG_DATA__DATA_MASK 0xffffffff\n#define PA_SC_DEBUG_DATA__DATA__SHIFT 0x0\n#define CLIPPER_DEBUG_REG00__ALWAYS_ZERO_MASK 0xff\n#define CLIPPER_DEBUG_REG00__ALWAYS_ZERO__SHIFT 0x0\n#define CLIPPER_DEBUG_REG00__clip_ga_bc_fifo_write_MASK 0x100\n#define CLIPPER_DEBUG_REG00__clip_ga_bc_fifo_write__SHIFT 0x8\n#define CLIPPER_DEBUG_REG00__su_clip_baryc_free_MASK 0x600\n#define CLIPPER_DEBUG_REG00__su_clip_baryc_free__SHIFT 0x9\n#define CLIPPER_DEBUG_REG00__clip_to_ga_fifo_write_MASK 0x800\n#define CLIPPER_DEBUG_REG00__clip_to_ga_fifo_write__SHIFT 0xb\n#define CLIPPER_DEBUG_REG00__clip_to_ga_fifo_full_MASK 0x1000\n#define CLIPPER_DEBUG_REG00__clip_to_ga_fifo_full__SHIFT 0xc\n#define CLIPPER_DEBUG_REG00__primic_to_clprim_fifo_empty_MASK 0x2000\n#define CLIPPER_DEBUG_REG00__primic_to_clprim_fifo_empty__SHIFT 0xd\n#define CLIPPER_DEBUG_REG00__primic_to_clprim_fifo_full_MASK 0x4000\n#define CLIPPER_DEBUG_REG00__primic_to_clprim_fifo_full__SHIFT 0xe\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_empty_MASK 0x8000\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_empty__SHIFT 0xf\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_full_MASK 0x10000\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_full__SHIFT 0x10\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_empty_MASK 0x20000\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_empty__SHIFT 0x11\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_full_MASK 0x40000\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_full__SHIFT 0x12\n#define CLIPPER_DEBUG_REG00__vgt_to_clips_fifo_empty_MASK 0x80000\n#define CLIPPER_DEBUG_REG00__vgt_to_clips_fifo_empty__SHIFT 0x13\n#define CLIPPER_DEBUG_REG00__vgt_to_clips_fifo_full_MASK 0x100000\n#define CLIPPER_DEBUG_REG00__vgt_to_clips_fifo_full__SHIFT 0x14\n#define CLIPPER_DEBUG_REG00__clipcode_fifo_fifo_empty_MASK 0x200000\n#define CLIPPER_DEBUG_REG00__clipcode_fifo_fifo_empty__SHIFT 0x15\n#define CLIPPER_DEBUG_REG00__clipcode_fifo_full_MASK 0x400000\n#define CLIPPER_DEBUG_REG00__clipcode_fifo_full__SHIFT 0x16\n#define CLIPPER_DEBUG_REG00__vte_out_clip_fifo_fifo_empty_MASK 0x800000\n#define CLIPPER_DEBUG_REG00__vte_out_clip_fifo_fifo_empty__SHIFT 0x17\n#define CLIPPER_DEBUG_REG00__vte_out_clip_fifo_fifo_full_MASK 0x1000000\n#define CLIPPER_DEBUG_REG00__vte_out_clip_fifo_fifo_full__SHIFT 0x18\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_empty_MASK 0x2000000\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_empty__SHIFT 0x19\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_full_MASK 0x4000000\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_full__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG00__ccgen_to_clipcc_fifo_empty_MASK 0x8000000\n#define CLIPPER_DEBUG_REG00__ccgen_to_clipcc_fifo_empty__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG00__ccgen_to_clipcc_fifo_full_MASK 0x10000000\n#define CLIPPER_DEBUG_REG00__ccgen_to_clipcc_fifo_full__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_write_MASK 0x20000000\n#define CLIPPER_DEBUG_REG00__clip_to_outsm_fifo_write__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_write_MASK 0x40000000\n#define CLIPPER_DEBUG_REG00__vte_out_orig_fifo_fifo_write__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_write_MASK 0x80000000\n#define CLIPPER_DEBUG_REG00__vgt_to_clipp_fifo_write__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG01__ALWAYS_ZERO_MASK 0xff\n#define CLIPPER_DEBUG_REG01__ALWAYS_ZERO__SHIFT 0x0\n#define CLIPPER_DEBUG_REG01__clip_extra_bc_valid_MASK 0x700\n#define CLIPPER_DEBUG_REG01__clip_extra_bc_valid__SHIFT 0x8\n#define CLIPPER_DEBUG_REG01__clip_vert_vte_valid_MASK 0x3800\n#define CLIPPER_DEBUG_REG01__clip_vert_vte_valid__SHIFT 0xb\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_vertex_deallocate_MASK 0x1c000\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_vertex_deallocate__SHIFT 0xe\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_deallocate_slot_MASK 0xe0000\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_deallocate_slot__SHIFT 0x11\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_null_primitive_MASK 0x100000\n#define CLIPPER_DEBUG_REG01__clip_to_outsm_null_primitive__SHIFT 0x14\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_2_MASK 0x200000\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_2__SHIFT 0x15\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_1_MASK 0x400000\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_1__SHIFT 0x16\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_0_MASK 0x800000\n#define CLIPPER_DEBUG_REG01__vte_positions_vte_clip_vte_naninf_kill_0__SHIFT 0x17\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_extra_bc_valid_MASK 0x1000000\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_extra_bc_valid__SHIFT 0x18\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_vte_naninf_kill_MASK 0x2000000\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_vte_naninf_kill__SHIFT 0x19\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_vertex_store_indx_MASK 0xc000000\n#define CLIPPER_DEBUG_REG01__vte_out_clip_rd_vertex_store_indx__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG01__clip_ga_bc_fifo_write_MASK 0x10000000\n#define CLIPPER_DEBUG_REG01__clip_ga_bc_fifo_write__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG01__clip_to_ga_fifo_write_MASK 0x20000000\n#define CLIPPER_DEBUG_REG01__clip_to_ga_fifo_write__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG01__vte_out_clip_fifo_fifo_advanceread_MASK 0x40000000\n#define CLIPPER_DEBUG_REG01__vte_out_clip_fifo_fifo_advanceread__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG01__vte_out_clip_fifo_fifo_empty_MASK 0x80000000\n#define CLIPPER_DEBUG_REG01__vte_out_clip_fifo_fifo_empty__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG02__clip_extra_bc_valid_MASK 0x7\n#define CLIPPER_DEBUG_REG02__clip_extra_bc_valid__SHIFT 0x0\n#define CLIPPER_DEBUG_REG02__clip_vert_vte_valid_MASK 0x38\n#define CLIPPER_DEBUG_REG02__clip_vert_vte_valid__SHIFT 0x3\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_clip_seq_indx_MASK 0xc0\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_clip_seq_indx__SHIFT 0x6\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_2_MASK 0xf00\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_2__SHIFT 0x8\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_1_MASK 0xf000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_1__SHIFT 0xc\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_0_MASK 0xf0000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_vertex_store_indx_0__SHIFT 0x10\n#define CLIPPER_DEBUG_REG02__clip_to_clipga_extra_bc_coords_MASK 0x100000\n#define CLIPPER_DEBUG_REG02__clip_to_clipga_extra_bc_coords__SHIFT 0x14\n#define CLIPPER_DEBUG_REG02__clip_to_clipga_vte_naninf_kill_MASK 0x200000\n#define CLIPPER_DEBUG_REG02__clip_to_clipga_vte_naninf_kill__SHIFT 0x15\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_end_of_packet_MASK 0x400000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_end_of_packet__SHIFT 0x16\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_first_prim_of_slot_MASK 0x800000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_first_prim_of_slot__SHIFT 0x17\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_clipped_prim_MASK 0x1000000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_clipped_prim__SHIFT 0x18\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_null_primitive_MASK 0x2000000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_null_primitive__SHIFT 0x19\n#define CLIPPER_DEBUG_REG02__clip_ga_bc_fifo_full_MASK 0x4000000\n#define CLIPPER_DEBUG_REG02__clip_ga_bc_fifo_full__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG02__clip_to_ga_fifo_full_MASK 0x8000000\n#define CLIPPER_DEBUG_REG02__clip_to_ga_fifo_full__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG02__clip_ga_bc_fifo_write_MASK 0x10000000\n#define CLIPPER_DEBUG_REG02__clip_ga_bc_fifo_write__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG02__clip_to_ga_fifo_write_MASK 0x20000000\n#define CLIPPER_DEBUG_REG02__clip_to_ga_fifo_write__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_fifo_advanceread_MASK 0x40000000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_fifo_advanceread__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_fifo_empty_MASK 0x80000000\n#define CLIPPER_DEBUG_REG02__clip_to_outsm_fifo_empty__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_clip_code_or_MASK 0x3fff\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_clip_code_or__SHIFT 0x0\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_event_id_MASK 0xfc000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_event_id__SHIFT 0xe\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_state_var_indx_MASK 0x700000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_state_var_indx__SHIFT 0x14\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_clip_primitive_MASK 0x800000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_clip_primitive__SHIFT 0x17\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_deallocate_slot_MASK 0x7000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_deallocate_slot__SHIFT 0x18\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_first_prim_of_slot_MASK 0x8000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_first_prim_of_slot__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_end_of_packet_MASK 0x10000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_end_of_packet__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG03__clipsm0_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_param_cache_indx_0_MASK 0x7fe\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_param_cache_indx_0__SHIFT 0x1\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_2_MASK 0x1f800\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_2__SHIFT 0xb\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_1_MASK 0x7e0000\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_1__SHIFT 0x11\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_0_MASK 0x1f800000\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_vertex_store_indx_0__SHIFT 0x17\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG04__clipsm0_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_clip_code_or_MASK 0x3fff\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_clip_code_or__SHIFT 0x0\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_event_id_MASK 0xfc000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_event_id__SHIFT 0xe\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_state_var_indx_MASK 0x700000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_state_var_indx__SHIFT 0x14\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_clip_primitive_MASK 0x800000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_clip_primitive__SHIFT 0x17\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_deallocate_slot_MASK 0x7000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_deallocate_slot__SHIFT 0x18\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_first_prim_of_slot_MASK 0x8000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_first_prim_of_slot__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_end_of_packet_MASK 0x10000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_end_of_packet__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG05__clipsm1_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_param_cache_indx_0_MASK 0x7fe\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_param_cache_indx_0__SHIFT 0x1\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_2_MASK 0x1f800\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_2__SHIFT 0xb\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_1_MASK 0x7e0000\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_1__SHIFT 0x11\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_0_MASK 0x1f800000\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_vertex_store_indx_0__SHIFT 0x17\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG06__clipsm1_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_clip_code_or_MASK 0x3fff\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_clip_code_or__SHIFT 0x0\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_event_id_MASK 0xfc000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_event_id__SHIFT 0xe\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_state_var_indx_MASK 0x700000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_state_var_indx__SHIFT 0x14\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_clip_primitive_MASK 0x800000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_clip_primitive__SHIFT 0x17\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_deallocate_slot_MASK 0x7000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_deallocate_slot__SHIFT 0x18\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_first_prim_of_slot_MASK 0x8000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_first_prim_of_slot__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_end_of_packet_MASK 0x10000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_end_of_packet__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG07__clipsm2_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_param_cache_indx_0_MASK 0x7fe\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_param_cache_indx_0__SHIFT 0x1\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_2_MASK 0x1f800\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_2__SHIFT 0xb\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_1_MASK 0x7e0000\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_1__SHIFT 0x11\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_0_MASK 0x1f800000\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_vertex_store_indx_0__SHIFT 0x17\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG08__clipsm2_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_clip_code_or_MASK 0x3fff\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_clip_code_or__SHIFT 0x0\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_event_id_MASK 0xfc000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_event_id__SHIFT 0xe\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_state_var_indx_MASK 0x700000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_state_var_indx__SHIFT 0x14\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_clip_primitive_MASK 0x800000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_clip_primitive__SHIFT 0x17\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_deallocate_slot_MASK 0x7000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_deallocate_slot__SHIFT 0x18\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_first_prim_of_slot_MASK 0x8000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_first_prim_of_slot__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_end_of_packet_MASK 0x10000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_end_of_packet__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG09__clipsm3_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_param_cache_indx_0_MASK 0x7fe\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_param_cache_indx_0__SHIFT 0x1\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_2_MASK 0x1f800\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_2__SHIFT 0xb\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_1_MASK 0x7e0000\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_1__SHIFT 0x11\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_0_MASK 0x1f800000\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_vertex_store_indx_0__SHIFT 0x17\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_event_MASK 0x20000000\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_event__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_null_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_null_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG10__clipsm3_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_event_MASK 0x1\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_event__SHIFT 0x0\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_event_MASK 0x2\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_event__SHIFT 0x1\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_event_MASK 0x4\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_event__SHIFT 0x2\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_event_MASK 0x8\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_event__SHIFT 0x3\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_clip_primitive_MASK 0x10\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_clip_primitive__SHIFT 0x4\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_clip_primitive_MASK 0x20\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_clip_primitive__SHIFT 0x5\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_clip_primitive_MASK 0x40\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_clip_primitive__SHIFT 0x6\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_clip_primitive_MASK 0x80\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_clip_primitive__SHIFT 0x7\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_clip_to_outsm_cnt_MASK 0xf00\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x8\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_clip_to_outsm_cnt_MASK 0xf000\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0xc\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_clip_to_outsm_cnt_MASK 0xf0000\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x10\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_clip_to_outsm_cnt_MASK 0xf00000\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x14\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_prim_valid_MASK 0x1000000\n#define CLIPPER_DEBUG_REG11__clipsm3_clip_to_clipga_prim_valid__SHIFT 0x18\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_prim_valid_MASK 0x2000000\n#define CLIPPER_DEBUG_REG11__clipsm2_clip_to_clipga_prim_valid__SHIFT 0x19\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_prim_valid_MASK 0x4000000\n#define CLIPPER_DEBUG_REG11__clipsm1_clip_to_clipga_prim_valid__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_prim_valid_MASK 0x8000000\n#define CLIPPER_DEBUG_REG11__clipsm0_clip_to_clipga_prim_valid__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG11__clipsm3_inc_clip_to_clipga_clip_to_outsm_cnt_MASK 0x10000000\n#define CLIPPER_DEBUG_REG11__clipsm3_inc_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG11__clipsm2_inc_clip_to_clipga_clip_to_outsm_cnt_MASK 0x20000000\n#define CLIPPER_DEBUG_REG11__clipsm2_inc_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG11__clipsm1_inc_clip_to_clipga_clip_to_outsm_cnt_MASK 0x40000000\n#define CLIPPER_DEBUG_REG11__clipsm1_inc_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG11__clipsm0_inc_clip_to_clipga_clip_to_outsm_cnt_MASK 0x80000000\n#define CLIPPER_DEBUG_REG11__clipsm0_inc_clip_to_clipga_clip_to_outsm_cnt__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG12__ALWAYS_ZERO_MASK 0xff\n#define CLIPPER_DEBUG_REG12__ALWAYS_ZERO__SHIFT 0x0\n#define CLIPPER_DEBUG_REG12__clip_priority_available_vte_out_clip_MASK 0x1f00\n#define CLIPPER_DEBUG_REG12__clip_priority_available_vte_out_clip__SHIFT 0x8\n#define CLIPPER_DEBUG_REG12__clip_priority_available_clip_verts_MASK 0x3e000\n#define CLIPPER_DEBUG_REG12__clip_priority_available_clip_verts__SHIFT 0xd\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_out_MASK 0xc0000\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_out__SHIFT 0x12\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_vert_MASK 0x300000\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_vert__SHIFT 0x14\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_load_MASK 0xc00000\n#define CLIPPER_DEBUG_REG12__clip_priority_seq_indx_load__SHIFT 0x16\n#define CLIPPER_DEBUG_REG12__clipsm3_clprim_to_clip_clip_primitive_MASK 0x1000000\n#define CLIPPER_DEBUG_REG12__clipsm3_clprim_to_clip_clip_primitive__SHIFT 0x18\n#define CLIPPER_DEBUG_REG12__clipsm3_clprim_to_clip_prim_valid_MASK 0x2000000\n#define CLIPPER_DEBUG_REG12__clipsm3_clprim_to_clip_prim_valid__SHIFT 0x19\n#define CLIPPER_DEBUG_REG12__clipsm2_clprim_to_clip_clip_primitive_MASK 0x4000000\n#define CLIPPER_DEBUG_REG12__clipsm2_clprim_to_clip_clip_primitive__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG12__clipsm2_clprim_to_clip_prim_valid_MASK 0x8000000\n#define CLIPPER_DEBUG_REG12__clipsm2_clprim_to_clip_prim_valid__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG12__clipsm1_clprim_to_clip_clip_primitive_MASK 0x10000000\n#define CLIPPER_DEBUG_REG12__clipsm1_clprim_to_clip_clip_primitive__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG12__clipsm1_clprim_to_clip_prim_valid_MASK 0x20000000\n#define CLIPPER_DEBUG_REG12__clipsm1_clprim_to_clip_prim_valid__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG12__clipsm0_clprim_to_clip_clip_primitive_MASK 0x40000000\n#define CLIPPER_DEBUG_REG12__clipsm0_clprim_to_clip_clip_primitive__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG12__clipsm0_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG12__clipsm0_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG13__clprim_in_back_state_var_indx_MASK 0x7\n#define CLIPPER_DEBUG_REG13__clprim_in_back_state_var_indx__SHIFT 0x0\n#define CLIPPER_DEBUG_REG13__point_clip_candidate_MASK 0x8\n#define CLIPPER_DEBUG_REG13__point_clip_candidate__SHIFT 0x3\n#define CLIPPER_DEBUG_REG13__prim_nan_kill_MASK 0x10\n#define CLIPPER_DEBUG_REG13__prim_nan_kill__SHIFT 0x4\n#define CLIPPER_DEBUG_REG13__clprim_clip_primitive_MASK 0x20\n#define CLIPPER_DEBUG_REG13__clprim_clip_primitive__SHIFT 0x5\n#define CLIPPER_DEBUG_REG13__clprim_cull_primitive_MASK 0x40\n#define CLIPPER_DEBUG_REG13__clprim_cull_primitive__SHIFT 0x6\n#define CLIPPER_DEBUG_REG13__prim_back_valid_MASK 0x80\n#define CLIPPER_DEBUG_REG13__prim_back_valid__SHIFT 0x7\n#define CLIPPER_DEBUG_REG13__vertval_bits_vertex_cc_next_valid_MASK 0xf00\n#define CLIPPER_DEBUG_REG13__vertval_bits_vertex_cc_next_valid__SHIFT 0x8\n#define CLIPPER_DEBUG_REG13__clipcc_vertex_store_indx_MASK 0x3000\n#define CLIPPER_DEBUG_REG13__clipcc_vertex_store_indx__SHIFT 0xc\n#define CLIPPER_DEBUG_REG13__vte_out_orig_fifo_fifo_empty_MASK 0x4000\n#define CLIPPER_DEBUG_REG13__vte_out_orig_fifo_fifo_empty__SHIFT 0xe\n#define CLIPPER_DEBUG_REG13__clipcode_fifo_fifo_empty_MASK 0x8000\n#define CLIPPER_DEBUG_REG13__clipcode_fifo_fifo_empty__SHIFT 0xf\n#define CLIPPER_DEBUG_REG13__ccgen_to_clipcc_fifo_empty_MASK 0x10000\n#define CLIPPER_DEBUG_REG13__ccgen_to_clipcc_fifo_empty__SHIFT 0x10\n#define CLIPPER_DEBUG_REG13__clip_priority_seq_indx_out_cnt_MASK 0x1e0000\n#define CLIPPER_DEBUG_REG13__clip_priority_seq_indx_out_cnt__SHIFT 0x11\n#define CLIPPER_DEBUG_REG13__outsm_clr_rd_orig_vertices_MASK 0x600000\n#define CLIPPER_DEBUG_REG13__outsm_clr_rd_orig_vertices__SHIFT 0x15\n#define CLIPPER_DEBUG_REG13__outsm_clr_rd_clipsm_wait_MASK 0x800000\n#define CLIPPER_DEBUG_REG13__outsm_clr_rd_clipsm_wait__SHIFT 0x17\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_contents_MASK 0x1f000000\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_contents__SHIFT 0x18\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_full_MASK 0x20000000\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_full__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_advanceread_MASK 0x40000000\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_advanceread__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_write_MASK 0x80000000\n#define CLIPPER_DEBUG_REG13__outsm_clr_fifo_write__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_2_MASK 0x3f\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_2__SHIFT 0x0\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_1_MASK 0xfc0\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_1__SHIFT 0x6\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_0_MASK 0x3f000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_vertex_store_indx_0__SHIFT 0xc\n#define CLIPPER_DEBUG_REG14__outputclprimtoclip_null_primitive_MASK 0x40000\n#define CLIPPER_DEBUG_REG14__outputclprimtoclip_null_primitive__SHIFT 0x12\n#define CLIPPER_DEBUG_REG14__clprim_in_back_end_of_packet_MASK 0x80000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_end_of_packet__SHIFT 0x13\n#define CLIPPER_DEBUG_REG14__clprim_in_back_first_prim_of_slot_MASK 0x100000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_first_prim_of_slot__SHIFT 0x14\n#define CLIPPER_DEBUG_REG14__clprim_in_back_deallocate_slot_MASK 0xe00000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_deallocate_slot__SHIFT 0x15\n#define CLIPPER_DEBUG_REG14__clprim_in_back_event_id_MASK 0x3f000000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_event_id__SHIFT 0x18\n#define CLIPPER_DEBUG_REG14__clprim_in_back_event_MASK 0x40000000\n#define CLIPPER_DEBUG_REG14__clprim_in_back_event__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG14__prim_back_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG14__prim_back_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG15__vertval_bits_vertex_vertex_store_msb_MASK 0xffff\n#define CLIPPER_DEBUG_REG15__vertval_bits_vertex_vertex_store_msb__SHIFT 0x0\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_2_MASK 0x1f0000\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_2__SHIFT 0x10\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_1_MASK 0x3e00000\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_1__SHIFT 0x15\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_0_MASK 0x7c000000\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_fifo_vertex_store_indx_0__SHIFT 0x1a\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG15__primic_to_clprim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG16__sm0_prim_end_state_MASK 0x7f\n#define CLIPPER_DEBUG_REG16__sm0_prim_end_state__SHIFT 0x0\n#define CLIPPER_DEBUG_REG16__sm0_ps_expand_MASK 0x80\n#define CLIPPER_DEBUG_REG16__sm0_ps_expand__SHIFT 0x7\n#define CLIPPER_DEBUG_REG16__sm0_clip_vert_cnt_MASK 0x1f00\n#define CLIPPER_DEBUG_REG16__sm0_clip_vert_cnt__SHIFT 0x8\n#define CLIPPER_DEBUG_REG16__sm0_vertex_clip_cnt_MASK 0x3e000\n#define CLIPPER_DEBUG_REG16__sm0_vertex_clip_cnt__SHIFT 0xd\n#define CLIPPER_DEBUG_REG16__sm0_inv_to_clip_data_valid_1_MASK 0x40000\n#define CLIPPER_DEBUG_REG16__sm0_inv_to_clip_data_valid_1__SHIFT 0x12\n#define CLIPPER_DEBUG_REG16__sm0_inv_to_clip_data_valid_0_MASK 0x80000\n#define CLIPPER_DEBUG_REG16__sm0_inv_to_clip_data_valid_0__SHIFT 0x13\n#define CLIPPER_DEBUG_REG16__sm0_current_state_MASK 0x7f00000\n#define CLIPPER_DEBUG_REG16__sm0_current_state__SHIFT 0x14\n#define CLIPPER_DEBUG_REG16__sm0_clip_to_clipga_clip_to_outsm_cnt_eq0_MASK 0x8000000\n#define CLIPPER_DEBUG_REG16__sm0_clip_to_clipga_clip_to_outsm_cnt_eq0__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG16__sm0_clip_to_outsm_fifo_full_MASK 0x10000000\n#define CLIPPER_DEBUG_REG16__sm0_clip_to_outsm_fifo_full__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG16__sm0_highest_priority_seq_MASK 0x20000000\n#define CLIPPER_DEBUG_REG16__sm0_highest_priority_seq__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG16__sm0_outputcliptoclipga_0_MASK 0x40000000\n#define CLIPPER_DEBUG_REG16__sm0_outputcliptoclipga_0__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG16__sm0_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG16__sm0_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG17__sm1_prim_end_state_MASK 0x7f\n#define CLIPPER_DEBUG_REG17__sm1_prim_end_state__SHIFT 0x0\n#define CLIPPER_DEBUG_REG17__sm1_ps_expand_MASK 0x80\n#define CLIPPER_DEBUG_REG17__sm1_ps_expand__SHIFT 0x7\n#define CLIPPER_DEBUG_REG17__sm1_clip_vert_cnt_MASK 0x1f00\n#define CLIPPER_DEBUG_REG17__sm1_clip_vert_cnt__SHIFT 0x8\n#define CLIPPER_DEBUG_REG17__sm1_vertex_clip_cnt_MASK 0x3e000\n#define CLIPPER_DEBUG_REG17__sm1_vertex_clip_cnt__SHIFT 0xd\n#define CLIPPER_DEBUG_REG17__sm1_inv_to_clip_data_valid_1_MASK 0x40000\n#define CLIPPER_DEBUG_REG17__sm1_inv_to_clip_data_valid_1__SHIFT 0x12\n#define CLIPPER_DEBUG_REG17__sm1_inv_to_clip_data_valid_0_MASK 0x80000\n#define CLIPPER_DEBUG_REG17__sm1_inv_to_clip_data_valid_0__SHIFT 0x13\n#define CLIPPER_DEBUG_REG17__sm1_current_state_MASK 0x7f00000\n#define CLIPPER_DEBUG_REG17__sm1_current_state__SHIFT 0x14\n#define CLIPPER_DEBUG_REG17__sm1_clip_to_clipga_clip_to_outsm_cnt_eq0_MASK 0x8000000\n#define CLIPPER_DEBUG_REG17__sm1_clip_to_clipga_clip_to_outsm_cnt_eq0__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG17__sm1_clip_to_outsm_fifo_full_MASK 0x10000000\n#define CLIPPER_DEBUG_REG17__sm1_clip_to_outsm_fifo_full__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG17__sm1_highest_priority_seq_MASK 0x20000000\n#define CLIPPER_DEBUG_REG17__sm1_highest_priority_seq__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG17__sm1_outputcliptoclipga_0_MASK 0x40000000\n#define CLIPPER_DEBUG_REG17__sm1_outputcliptoclipga_0__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG17__sm1_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG17__sm1_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG18__sm2_prim_end_state_MASK 0x7f\n#define CLIPPER_DEBUG_REG18__sm2_prim_end_state__SHIFT 0x0\n#define CLIPPER_DEBUG_REG18__sm2_ps_expand_MASK 0x80\n#define CLIPPER_DEBUG_REG18__sm2_ps_expand__SHIFT 0x7\n#define CLIPPER_DEBUG_REG18__sm2_clip_vert_cnt_MASK 0x1f00\n#define CLIPPER_DEBUG_REG18__sm2_clip_vert_cnt__SHIFT 0x8\n#define CLIPPER_DEBUG_REG18__sm2_vertex_clip_cnt_MASK 0x3e000\n#define CLIPPER_DEBUG_REG18__sm2_vertex_clip_cnt__SHIFT 0xd\n#define CLIPPER_DEBUG_REG18__sm2_inv_to_clip_data_valid_1_MASK 0x40000\n#define CLIPPER_DEBUG_REG18__sm2_inv_to_clip_data_valid_1__SHIFT 0x12\n#define CLIPPER_DEBUG_REG18__sm2_inv_to_clip_data_valid_0_MASK 0x80000\n#define CLIPPER_DEBUG_REG18__sm2_inv_to_clip_data_valid_0__SHIFT 0x13\n#define CLIPPER_DEBUG_REG18__sm2_current_state_MASK 0x7f00000\n#define CLIPPER_DEBUG_REG18__sm2_current_state__SHIFT 0x14\n#define CLIPPER_DEBUG_REG18__sm2_clip_to_clipga_clip_to_outsm_cnt_eq0_MASK 0x8000000\n#define CLIPPER_DEBUG_REG18__sm2_clip_to_clipga_clip_to_outsm_cnt_eq0__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG18__sm2_clip_to_outsm_fifo_full_MASK 0x10000000\n#define CLIPPER_DEBUG_REG18__sm2_clip_to_outsm_fifo_full__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG18__sm2_highest_priority_seq_MASK 0x20000000\n#define CLIPPER_DEBUG_REG18__sm2_highest_priority_seq__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG18__sm2_outputcliptoclipga_0_MASK 0x40000000\n#define CLIPPER_DEBUG_REG18__sm2_outputcliptoclipga_0__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG18__sm2_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG18__sm2_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define CLIPPER_DEBUG_REG19__sm3_prim_end_state_MASK 0x7f\n#define CLIPPER_DEBUG_REG19__sm3_prim_end_state__SHIFT 0x0\n#define CLIPPER_DEBUG_REG19__sm3_ps_expand_MASK 0x80\n#define CLIPPER_DEBUG_REG19__sm3_ps_expand__SHIFT 0x7\n#define CLIPPER_DEBUG_REG19__sm3_clip_vert_cnt_MASK 0x1f00\n#define CLIPPER_DEBUG_REG19__sm3_clip_vert_cnt__SHIFT 0x8\n#define CLIPPER_DEBUG_REG19__sm3_vertex_clip_cnt_MASK 0x3e000\n#define CLIPPER_DEBUG_REG19__sm3_vertex_clip_cnt__SHIFT 0xd\n#define CLIPPER_DEBUG_REG19__sm3_inv_to_clip_data_valid_1_MASK 0x40000\n#define CLIPPER_DEBUG_REG19__sm3_inv_to_clip_data_valid_1__SHIFT 0x12\n#define CLIPPER_DEBUG_REG19__sm3_inv_to_clip_data_valid_0_MASK 0x80000\n#define CLIPPER_DEBUG_REG19__sm3_inv_to_clip_data_valid_0__SHIFT 0x13\n#define CLIPPER_DEBUG_REG19__sm3_current_state_MASK 0x7f00000\n#define CLIPPER_DEBUG_REG19__sm3_current_state__SHIFT 0x14\n#define CLIPPER_DEBUG_REG19__sm3_clip_to_clipga_clip_to_outsm_cnt_eq0_MASK 0x8000000\n#define CLIPPER_DEBUG_REG19__sm3_clip_to_clipga_clip_to_outsm_cnt_eq0__SHIFT 0x1b\n#define CLIPPER_DEBUG_REG19__sm3_clip_to_outsm_fifo_full_MASK 0x10000000\n#define CLIPPER_DEBUG_REG19__sm3_clip_to_outsm_fifo_full__SHIFT 0x1c\n#define CLIPPER_DEBUG_REG19__sm3_highest_priority_seq_MASK 0x20000000\n#define CLIPPER_DEBUG_REG19__sm3_highest_priority_seq__SHIFT 0x1d\n#define CLIPPER_DEBUG_REG19__sm3_outputcliptoclipga_0_MASK 0x40000000\n#define CLIPPER_DEBUG_REG19__sm3_outputcliptoclipga_0__SHIFT 0x1e\n#define CLIPPER_DEBUG_REG19__sm3_clprim_to_clip_prim_valid_MASK 0x80000000\n#define CLIPPER_DEBUG_REG19__sm3_clprim_to_clip_prim_valid__SHIFT 0x1f\n#define SXIFCCG_DEBUG_REG0__position_address_MASK 0x3f\n#define SXIFCCG_DEBUG_REG0__position_address__SHIFT 0x0\n#define SXIFCCG_DEBUG_REG0__point_address_MASK 0x1c0\n#define SXIFCCG_DEBUG_REG0__point_address__SHIFT 0x6\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_state_var_indx_MASK 0xe00\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_state_var_indx__SHIFT 0x9\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_req_mask_MASK 0xf000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_req_mask__SHIFT 0xc\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_pci_MASK 0x3ff0000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_pci__SHIFT 0x10\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_aux_sel_MASK 0xc000000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_aux_sel__SHIFT 0x1a\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_sp_id_MASK 0x30000000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_sp_id__SHIFT 0x1c\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_aux_inc_MASK 0x40000000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_aux_inc__SHIFT 0x1e\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_advance_MASK 0x80000000\n#define SXIFCCG_DEBUG_REG0__sx_pending_rd_advance__SHIFT 0x1f\n#define SXIFCCG_DEBUG_REG1__available_positions_MASK 0x7f\n#define SXIFCCG_DEBUG_REG1__available_positions__SHIFT 0x0\n#define SXIFCCG_DEBUG_REG1__sx_receive_indx_MASK 0x380\n#define SXIFCCG_DEBUG_REG1__sx_receive_indx__SHIFT 0x7\n#define SXIFCCG_DEBUG_REG1__sx_pending_fifo_contents_MASK 0x7c00\n#define SXIFCCG_DEBUG_REG1__sx_pending_fifo_contents__SHIFT 0xa\n#define SXIFCCG_DEBUG_REG1__statevar_bits_vs_out_misc_vec_ena_MASK 0x8000\n#define SXIFCCG_DEBUG_REG1__statevar_bits_vs_out_misc_vec_ena__SHIFT 0xf\n#define SXIFCCG_DEBUG_REG1__statevar_bits_disable_sp_MASK 0xf0000\n#define SXIFCCG_DEBUG_REG1__statevar_bits_disable_sp__SHIFT 0x10\n#define SXIFCCG_DEBUG_REG1__aux_sel_MASK 0x300000\n#define SXIFCCG_DEBUG_REG1__aux_sel__SHIFT 0x14\n#define SXIFCCG_DEBUG_REG1__sx_to_pa_empty_1_MASK 0x400000\n#define SXIFCCG_DEBUG_REG1__sx_to_pa_empty_1__SHIFT 0x16\n#define SXIFCCG_DEBUG_REG1__sx_to_pa_empty_0_MASK 0x800000\n#define SXIFCCG_DEBUG_REG1__sx_to_pa_empty_0__SHIFT 0x17\n#define SXIFCCG_DEBUG_REG1__pasx_req_cnt_1_MASK 0xf000000\n#define SXIFCCG_DEBUG_REG1__pasx_req_cnt_1__SHIFT 0x18\n#define SXIFCCG_DEBUG_REG1__pasx_req_cnt_0_MASK 0xf0000000\n#define SXIFCCG_DEBUG_REG1__pasx_req_cnt_0__SHIFT 0x1c\n#define SXIFCCG_DEBUG_REG2__param_cache_base_MASK 0x7f\n#define SXIFCCG_DEBUG_REG2__param_cache_base__SHIFT 0x0\n#define SXIFCCG_DEBUG_REG2__sx_aux_MASK 0x180\n#define SXIFCCG_DEBUG_REG2__sx_aux__SHIFT 0x7\n#define SXIFCCG_DEBUG_REG2__sx_request_indx_MASK 0x7e00\n#define SXIFCCG_DEBUG_REG2__sx_request_indx__SHIFT 0x9\n#define SXIFCCG_DEBUG_REG2__req_active_verts_loaded_MASK 0x8000\n#define SXIFCCG_DEBUG_REG2__req_active_verts_loaded__SHIFT 0xf\n#define SXIFCCG_DEBUG_REG2__req_active_verts_MASK 0x7f0000\n#define SXIFCCG_DEBUG_REG2__req_active_verts__SHIFT 0x10\n#define SXIFCCG_DEBUG_REG2__vgt_to_ccgen_state_var_indx_MASK 0x3800000\n#define SXIFCCG_DEBUG_REG2__vgt_to_ccgen_state_var_indx__SHIFT 0x17\n#define SXIFCCG_DEBUG_REG2__vgt_to_ccgen_active_verts_MASK 0xfc000000\n#define SXIFCCG_DEBUG_REG2__vgt_to_ccgen_active_verts__SHIFT 0x1a\n#define SXIFCCG_DEBUG_REG3__ALWAYS_ZERO_MASK 0xff\n#define SXIFCCG_DEBUG_REG3__ALWAYS_ZERO__SHIFT 0x0\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_entriesavailable_MASK 0xf00\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_entriesavailable__SHIFT 0x8\n#define SXIFCCG_DEBUG_REG3__statevar_bits_vs_out_ccdist1_vec_ena_MASK 0x1000\n#define SXIFCCG_DEBUG_REG3__statevar_bits_vs_out_ccdist1_vec_ena__SHIFT 0xc\n#define SXIFCCG_DEBUG_REG3__statevar_bits_vs_out_ccdist0_vec_ena_MASK 0x2000\n#define SXIFCCG_DEBUG_REG3__statevar_bits_vs_out_ccdist0_vec_ena__SHIFT 0xd\n#define SXIFCCG_DEBUG_REG3__available_positions_MASK 0x1fc000\n#define SXIFCCG_DEBUG_REG3__available_positions__SHIFT 0xe\n#define SXIFCCG_DEBUG_REG3__current_state_MASK 0x600000\n#define SXIFCCG_DEBUG_REG3__current_state__SHIFT 0x15\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_empty_MASK 0x800000\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_empty__SHIFT 0x17\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_full_MASK 0x1000000\n#define SXIFCCG_DEBUG_REG3__vertex_fifo_full__SHIFT 0x18\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_empty_MASK 0x2000000\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_empty__SHIFT 0x19\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_full_MASK 0x4000000\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_full__SHIFT 0x1a\n#define SXIFCCG_DEBUG_REG3__vgt_to_ccgen_fifo_empty_MASK 0x8000000\n#define SXIFCCG_DEBUG_REG3__vgt_to_ccgen_fifo_empty__SHIFT 0x1b\n#define SXIFCCG_DEBUG_REG3__vgt_to_ccgen_fifo_full_MASK 0x10000000\n#define SXIFCCG_DEBUG_REG3__vgt_to_ccgen_fifo_full__SHIFT 0x1c\n#define SXIFCCG_DEBUG_REG3__ccgen_to_clipcc_fifo_full_MASK 0x20000000\n#define SXIFCCG_DEBUG_REG3__ccgen_to_clipcc_fifo_full__SHIFT 0x1d\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_write_MASK 0x40000000\n#define SXIFCCG_DEBUG_REG3__sx0_receive_fifo_write__SHIFT 0x1e\n#define SXIFCCG_DEBUG_REG3__ccgen_to_clipcc_write_MASK 0x80000000\n#define SXIFCCG_DEBUG_REG3__ccgen_to_clipcc_write__SHIFT 0x1f\n#define SETUP_DEBUG_REG0__su_baryc_cntl_state_MASK 0x3\n#define SETUP_DEBUG_REG0__su_baryc_cntl_state__SHIFT 0x0\n#define SETUP_DEBUG_REG0__su_cntl_state_MASK 0x3c\n#define SETUP_DEBUG_REG0__su_cntl_state__SHIFT 0x2\n#define SETUP_DEBUG_REG0__pmode_state_MASK 0x3f00\n#define SETUP_DEBUG_REG0__pmode_state__SHIFT 0x8\n#define SETUP_DEBUG_REG0__ge_stallb_MASK 0x4000\n#define SETUP_DEBUG_REG0__ge_stallb__SHIFT 0xe\n#define SETUP_DEBUG_REG0__geom_enable_MASK 0x8000\n#define SETUP_DEBUG_REG0__geom_enable__SHIFT 0xf\n#define SETUP_DEBUG_REG0__su_clip_baryc_free_MASK 0x30000\n#define SETUP_DEBUG_REG0__su_clip_baryc_free__SHIFT 0x10\n#define SETUP_DEBUG_REG0__su_clip_rtr_MASK 0x40000\n#define SETUP_DEBUG_REG0__su_clip_rtr__SHIFT 0x12\n#define SETUP_DEBUG_REG0__pfifo_busy_MASK 0x80000\n#define SETUP_DEBUG_REG0__pfifo_busy__SHIFT 0x13\n#define SETUP_DEBUG_REG0__su_cntl_busy_MASK 0x100000\n#define SETUP_DEBUG_REG0__su_cntl_busy__SHIFT 0x14\n#define SETUP_DEBUG_REG0__geom_busy_MASK 0x200000\n#define SETUP_DEBUG_REG0__geom_busy__SHIFT 0x15\n#define SETUP_DEBUG_REG0__event_id_gated_MASK 0xfc00000\n#define SETUP_DEBUG_REG0__event_id_gated__SHIFT 0x16\n#define SETUP_DEBUG_REG0__event_gated_MASK 0x10000000\n#define SETUP_DEBUG_REG0__event_gated__SHIFT 0x1c\n#define SETUP_DEBUG_REG0__pmode_prim_gated_MASK 0x20000000\n#define SETUP_DEBUG_REG0__pmode_prim_gated__SHIFT 0x1d\n#define SETUP_DEBUG_REG0__su_dyn_sclk_vld_MASK 0x40000000\n#define SETUP_DEBUG_REG0__su_dyn_sclk_vld__SHIFT 0x1e\n#define SETUP_DEBUG_REG0__cl_dyn_sclk_vld_MASK 0x80000000\n#define SETUP_DEBUG_REG0__cl_dyn_sclk_vld__SHIFT 0x1f\n#define SETUP_DEBUG_REG1__y_sort0_gated_23_8_MASK 0xffff\n#define SETUP_DEBUG_REG1__y_sort0_gated_23_8__SHIFT 0x0\n#define SETUP_DEBUG_REG1__x_sort0_gated_23_8_MASK 0xffff0000\n#define SETUP_DEBUG_REG1__x_sort0_gated_23_8__SHIFT 0x10\n#define SETUP_DEBUG_REG2__y_sort1_gated_23_8_MASK 0xffff\n#define SETUP_DEBUG_REG2__y_sort1_gated_23_8__SHIFT 0x0\n#define SETUP_DEBUG_REG2__x_sort1_gated_23_8_MASK 0xffff0000\n#define SETUP_DEBUG_REG2__x_sort1_gated_23_8__SHIFT 0x10\n#define SETUP_DEBUG_REG3__y_sort2_gated_23_8_MASK 0xffff\n#define SETUP_DEBUG_REG3__y_sort2_gated_23_8__SHIFT 0x0\n#define SETUP_DEBUG_REG3__x_sort2_gated_23_8_MASK 0xffff0000\n#define SETUP_DEBUG_REG3__x_sort2_gated_23_8__SHIFT 0x10\n#define SETUP_DEBUG_REG4__attr_indx_sort0_gated_MASK 0x3fff\n#define SETUP_DEBUG_REG4__attr_indx_sort0_gated__SHIFT 0x0\n#define SETUP_DEBUG_REG4__null_prim_gated_MASK 0x4000\n#define SETUP_DEBUG_REG4__null_prim_gated__SHIFT 0xe\n#define SETUP_DEBUG_REG4__backfacing_gated_MASK 0x8000\n#define SETUP_DEBUG_REG4__backfacing_gated__SHIFT 0xf\n#define SETUP_DEBUG_REG4__st_indx_gated_MASK 0x70000\n#define SETUP_DEBUG_REG4__st_indx_gated__SHIFT 0x10\n#define SETUP_DEBUG_REG4__clipped_gated_MASK 0x80000\n#define SETUP_DEBUG_REG4__clipped_gated__SHIFT 0x13\n#define SETUP_DEBUG_REG4__dealloc_slot_gated_MASK 0x700000\n#define SETUP_DEBUG_REG4__dealloc_slot_gated__SHIFT 0x14\n#define SETUP_DEBUG_REG4__xmajor_gated_MASK 0x800000\n#define SETUP_DEBUG_REG4__xmajor_gated__SHIFT 0x17\n#define SETUP_DEBUG_REG4__diamond_rule_gated_MASK 0x3000000\n#define SETUP_DEBUG_REG4__diamond_rule_gated__SHIFT 0x18\n#define SETUP_DEBUG_REG4__type_gated_MASK 0x1c000000\n#define SETUP_DEBUG_REG4__type_gated__SHIFT 0x1a\n#define SETUP_DEBUG_REG4__fpov_gated_MASK 0x60000000\n#define SETUP_DEBUG_REG4__fpov_gated__SHIFT 0x1d\n#define SETUP_DEBUG_REG4__eop_gated_MASK 0x80000000\n#define SETUP_DEBUG_REG4__eop_gated__SHIFT 0x1f\n#define SETUP_DEBUG_REG5__attr_indx_sort2_gated_MASK 0x3fff\n#define SETUP_DEBUG_REG5__attr_indx_sort2_gated__SHIFT 0x0\n#define SETUP_DEBUG_REG5__attr_indx_sort1_gated_MASK 0xfffc000\n#define SETUP_DEBUG_REG5__attr_indx_sort1_gated__SHIFT 0xe\n#define SETUP_DEBUG_REG5__provoking_vtx_gated_MASK 0x30000000\n#define SETUP_DEBUG_REG5__provoking_vtx_gated__SHIFT 0x1c\n#define SETUP_DEBUG_REG5__valid_prim_gated_MASK 0x40000000\n#define SETUP_DEBUG_REG5__valid_prim_gated__SHIFT 0x1e\n#define SETUP_DEBUG_REG5__pa_reg_sclk_vld_MASK 0x80000000\n#define SETUP_DEBUG_REG5__pa_reg_sclk_vld__SHIFT 0x1f\n#define PA_SC_DEBUG_REG0__REG0_FIELD0_MASK 0x3\n#define PA_SC_DEBUG_REG0__REG0_FIELD0__SHIFT 0x0\n#define PA_SC_DEBUG_REG0__REG0_FIELD1_MASK 0xc\n#define PA_SC_DEBUG_REG0__REG0_FIELD1__SHIFT 0x2\n#define PA_SC_DEBUG_REG1__REG1_FIELD0_MASK 0x3\n#define PA_SC_DEBUG_REG1__REG1_FIELD0__SHIFT 0x0\n#define PA_SC_DEBUG_REG1__REG1_FIELD1_MASK 0xc\n#define PA_SC_DEBUG_REG1__REG1_FIELD1__SHIFT 0x2\n#define COMPUTE_DISPATCH_INITIATOR__COMPUTE_SHADER_EN_MASK 0x1\n#define COMPUTE_DISPATCH_INITIATOR__COMPUTE_SHADER_EN__SHIFT 0x0\n#define COMPUTE_DISPATCH_INITIATOR__PARTIAL_TG_EN_MASK 0x2\n#define COMPUTE_DISPATCH_INITIATOR__PARTIAL_TG_EN__SHIFT 0x1\n#define COMPUTE_DISPATCH_INITIATOR__FORCE_START_AT_000_MASK 0x4\n#define COMPUTE_DISPATCH_INITIATOR__FORCE_START_AT_000__SHIFT 0x2\n#define COMPUTE_DISPATCH_INITIATOR__ORDERED_APPEND_ENBL_MASK 0x8\n#define COMPUTE_DISPATCH_INITIATOR__ORDERED_APPEND_ENBL__SHIFT 0x3\n#define COMPUTE_DISPATCH_INITIATOR__ORDERED_APPEND_MODE_MASK 0x10\n#define COMPUTE_DISPATCH_INITIATOR__ORDERED_APPEND_MODE__SHIFT 0x4\n#define COMPUTE_DISPATCH_INITIATOR__USE_THREAD_DIMENSIONS_MASK 0x20\n#define COMPUTE_DISPATCH_INITIATOR__USE_THREAD_DIMENSIONS__SHIFT 0x5\n#define COMPUTE_DISPATCH_INITIATOR__ORDER_MODE_MASK 0x40\n#define COMPUTE_DISPATCH_INITIATOR__ORDER_MODE__SHIFT 0x6\n#define COMPUTE_DISPATCH_INITIATOR__DISPATCH_CACHE_CNTL_MASK 0x380\n#define COMPUTE_DISPATCH_INITIATOR__DISPATCH_CACHE_CNTL__SHIFT 0x7\n#define COMPUTE_DISPATCH_INITIATOR__SCALAR_L1_INV_VOL_MASK 0x400\n#define COMPUTE_DISPATCH_INITIATOR__SCALAR_L1_INV_VOL__SHIFT 0xa\n#define COMPUTE_DISPATCH_INITIATOR__VECTOR_L1_INV_VOL_MASK 0x800\n#define COMPUTE_DISPATCH_INITIATOR__VECTOR_L1_INV_VOL__SHIFT 0xb\n#define COMPUTE_DISPATCH_INITIATOR__DATA_ATC_MASK 0x1000\n#define COMPUTE_DISPATCH_INITIATOR__DATA_ATC__SHIFT 0xc\n#define COMPUTE_DISPATCH_INITIATOR__RESTORE_MASK 0x4000\n#define COMPUTE_DISPATCH_INITIATOR__RESTORE__SHIFT 0xe\n#define COMPUTE_DIM_X__SIZE_MASK 0xffffffff\n#define COMPUTE_DIM_X__SIZE__SHIFT 0x0\n#define COMPUTE_DIM_Y__SIZE_MASK 0xffffffff\n#define COMPUTE_DIM_Y__SIZE__SHIFT 0x0\n#define COMPUTE_DIM_Z__SIZE_MASK 0xffffffff\n#define COMPUTE_DIM_Z__SIZE__SHIFT 0x0\n#define COMPUTE_START_X__START_MASK 0xffffffff\n#define COMPUTE_START_X__START__SHIFT 0x0\n#define COMPUTE_START_Y__START_MASK 0xffffffff\n#define COMPUTE_START_Y__START__SHIFT 0x0\n#define COMPUTE_START_Z__START_MASK 0xffffffff\n#define COMPUTE_START_Z__START__SHIFT 0x0\n#define COMPUTE_NUM_THREAD_X__NUM_THREAD_FULL_MASK 0xffff\n#define COMPUTE_NUM_THREAD_X__NUM_THREAD_FULL__SHIFT 0x0\n#define COMPUTE_NUM_THREAD_X__NUM_THREAD_PARTIAL_MASK 0xffff0000\n#define COMPUTE_NUM_THREAD_X__NUM_THREAD_PARTIAL__SHIFT 0x10\n#define COMPUTE_NUM_THREAD_Y__NUM_THREAD_FULL_MASK 0xffff\n#define COMPUTE_NUM_THREAD_Y__NUM_THREAD_FULL__SHIFT 0x0\n#define COMPUTE_NUM_THREAD_Y__NUM_THREAD_PARTIAL_MASK 0xffff0000\n#define COMPUTE_NUM_THREAD_Y__NUM_THREAD_PARTIAL__SHIFT 0x10\n#define COMPUTE_NUM_THREAD_Z__NUM_THREAD_FULL_MASK 0xffff\n#define COMPUTE_NUM_THREAD_Z__NUM_THREAD_FULL__SHIFT 0x0\n#define COMPUTE_NUM_THREAD_Z__NUM_THREAD_PARTIAL_MASK 0xffff0000\n#define COMPUTE_NUM_THREAD_Z__NUM_THREAD_PARTIAL__SHIFT 0x10\n#define COMPUTE_PIPELINESTAT_ENABLE__PIPELINESTAT_ENABLE_MASK 0x1\n#define COMPUTE_PIPELINESTAT_ENABLE__PIPELINESTAT_ENABLE__SHIFT 0x0\n#define COMPUTE_PERFCOUNT_ENABLE__PERFCOUNT_ENABLE_MASK 0x1\n#define COMPUTE_PERFCOUNT_ENABLE__PERFCOUNT_ENABLE__SHIFT 0x0\n#define COMPUTE_PGM_LO__DATA_MASK 0xffffffff\n#define COMPUTE_PGM_LO__DATA__SHIFT 0x0\n#define COMPUTE_PGM_HI__DATA_MASK 0xff\n#define COMPUTE_PGM_HI__DATA__SHIFT 0x0\n#define COMPUTE_PGM_HI__INST_ATC_MASK 0x100\n#define COMPUTE_PGM_HI__INST_ATC__SHIFT 0x8\n#define COMPUTE_TBA_LO__DATA_MASK 0xffffffff\n#define COMPUTE_TBA_LO__DATA__SHIFT 0x0\n#define COMPUTE_TBA_HI__DATA_MASK 0xff\n#define COMPUTE_TBA_HI__DATA__SHIFT 0x0\n#define COMPUTE_TMA_LO__DATA_MASK 0xffffffff\n#define COMPUTE_TMA_LO__DATA__SHIFT 0x0\n#define COMPUTE_TMA_HI__DATA_MASK 0xff\n#define COMPUTE_TMA_HI__DATA__SHIFT 0x0\n#define COMPUTE_PGM_RSRC1__VGPRS_MASK 0x3f\n#define COMPUTE_PGM_RSRC1__VGPRS__SHIFT 0x0\n#define COMPUTE_PGM_RSRC1__SGPRS_MASK 0x3c0\n#define COMPUTE_PGM_RSRC1__SGPRS__SHIFT 0x6\n#define COMPUTE_PGM_RSRC1__PRIORITY_MASK 0xc00\n#define COMPUTE_PGM_RSRC1__PRIORITY__SHIFT 0xa\n#define COMPUTE_PGM_RSRC1__FLOAT_MODE_MASK 0xff000\n#define COMPUTE_PGM_RSRC1__FLOAT_MODE__SHIFT 0xc\n#define COMPUTE_PGM_RSRC1__PRIV_MASK 0x100000\n#define COMPUTE_PGM_RSRC1__PRIV__SHIFT 0x14\n#define COMPUTE_PGM_RSRC1__DX10_CLAMP_MASK 0x200000\n#define COMPUTE_PGM_RSRC1__DX10_CLAMP__SHIFT 0x15\n#define COMPUTE_PGM_RSRC1__DEBUG_MODE_MASK 0x400000\n#define COMPUTE_PGM_RSRC1__DEBUG_MODE__SHIFT 0x16\n#define COMPUTE_PGM_RSRC1__IEEE_MODE_MASK 0x800000\n#define COMPUTE_PGM_RSRC1__IEEE_MODE__SHIFT 0x17\n#define COMPUTE_PGM_RSRC1__BULKY_MASK 0x1000000\n#define COMPUTE_PGM_RSRC1__BULKY__SHIFT 0x18\n#define COMPUTE_PGM_RSRC1__CDBG_USER_MASK 0x2000000\n#define COMPUTE_PGM_RSRC1__CDBG_USER__SHIFT 0x19\n#define COMPUTE_PGM_RSRC2__SCRATCH_EN_MASK 0x1\n#define COMPUTE_PGM_RSRC2__SCRATCH_EN__SHIFT 0x0\n#define COMPUTE_PGM_RSRC2__USER_SGPR_MASK 0x3e\n#define COMPUTE_PGM_RSRC2__USER_SGPR__SHIFT 0x1\n#define COMPUTE_PGM_RSRC2__TRAP_PRESENT_MASK 0x40\n#define COMPUTE_PGM_RSRC2__TRAP_PRESENT__SHIFT 0x6\n#define COMPUTE_PGM_RSRC2__TGID_X_EN_MASK 0x80\n#define COMPUTE_PGM_RSRC2__TGID_X_EN__SHIFT 0x7\n#define COMPUTE_PGM_RSRC2__TGID_Y_EN_MASK 0x100\n#define COMPUTE_PGM_RSRC2__TGID_Y_EN__SHIFT 0x8\n#define COMPUTE_PGM_RSRC2__TGID_Z_EN_MASK 0x200\n#define COMPUTE_PGM_RSRC2__TGID_Z_EN__SHIFT 0x9\n#define COMPUTE_PGM_RSRC2__TG_SIZE_EN_MASK 0x400\n#define COMPUTE_PGM_RSRC2__TG_SIZE_EN__SHIFT 0xa\n#define COMPUTE_PGM_RSRC2__TIDIG_COMP_CNT_MASK 0x1800\n#define COMPUTE_PGM_RSRC2__TIDIG_COMP_CNT__SHIFT 0xb\n#define COMPUTE_PGM_RSRC2__EXCP_EN_MSB_MASK 0x6000\n#define COMPUTE_PGM_RSRC2__EXCP_EN_MSB__SHIFT 0xd\n#define COMPUTE_PGM_RSRC2__LDS_SIZE_MASK 0xff8000\n#define COMPUTE_PGM_RSRC2__LDS_SIZE__SHIFT 0xf\n#define COMPUTE_PGM_RSRC2__EXCP_EN_MASK 0x7f000000\n#define COMPUTE_PGM_RSRC2__EXCP_EN__SHIFT 0x18\n#define COMPUTE_VMID__DATA_MASK 0xf\n#define COMPUTE_VMID__DATA__SHIFT 0x0\n#define COMPUTE_RESOURCE_LIMITS__WAVES_PER_SH_MASK 0x3ff\n#define COMPUTE_RESOURCE_LIMITS__WAVES_PER_SH__SHIFT 0x0\n#define COMPUTE_RESOURCE_LIMITS__TG_PER_CU_MASK 0xf000\n#define COMPUTE_RESOURCE_LIMITS__TG_PER_CU__SHIFT 0xc\n#define COMPUTE_RESOURCE_LIMITS__LOCK_THRESHOLD_MASK 0x3f0000\n#define COMPUTE_RESOURCE_LIMITS__LOCK_THRESHOLD__SHIFT 0x10\n#define COMPUTE_RESOURCE_LIMITS__SIMD_DEST_CNTL_MASK 0x400000\n#define COMPUTE_RESOURCE_LIMITS__SIMD_DEST_CNTL__SHIFT 0x16\n#define COMPUTE_RESOURCE_LIMITS__FORCE_SIMD_DIST_MASK 0x800000\n#define COMPUTE_RESOURCE_LIMITS__FORCE_SIMD_DIST__SHIFT 0x17\n#define COMPUTE_RESOURCE_LIMITS__CU_GROUP_COUNT_MASK 0x7000000\n#define COMPUTE_RESOURCE_LIMITS__CU_GROUP_COUNT__SHIFT 0x18\n#define COMPUTE_STATIC_THREAD_MGMT_SE0__SH0_CU_EN_MASK 0xffff\n#define COMPUTE_STATIC_THREAD_MGMT_SE0__SH0_CU_EN__SHIFT 0x0\n#define COMPUTE_STATIC_THREAD_MGMT_SE0__SH1_CU_EN_MASK 0xffff0000\n#define COMPUTE_STATIC_THREAD_MGMT_SE0__SH1_CU_EN__SHIFT 0x10\n#define COMPUTE_STATIC_THREAD_MGMT_SE1__SH0_CU_EN_MASK 0xffff\n#define COMPUTE_STATIC_THREAD_MGMT_SE1__SH0_CU_EN__SHIFT 0x0\n#define COMPUTE_STATIC_THREAD_MGMT_SE1__SH1_CU_EN_MASK 0xffff0000\n#define COMPUTE_STATIC_THREAD_MGMT_SE1__SH1_CU_EN__SHIFT 0x10\n#define COMPUTE_TMPRING_SIZE__WAVES_MASK 0xfff\n#define COMPUTE_TMPRING_SIZE__WAVES__SHIFT 0x0\n#define COMPUTE_TMPRING_SIZE__WAVESIZE_MASK 0x1fff000\n#define COMPUTE_TMPRING_SIZE__WAVESIZE__SHIFT 0xc\n#define COMPUTE_STATIC_THREAD_MGMT_SE2__SH0_CU_EN_MASK 0xffff\n#define COMPUTE_STATIC_THREAD_MGMT_SE2__SH0_CU_EN__SHIFT 0x0\n#define COMPUTE_STATIC_THREAD_MGMT_SE2__SH1_CU_EN_MASK 0xffff0000\n#define COMPUTE_STATIC_THREAD_MGMT_SE2__SH1_CU_EN__SHIFT 0x10\n#define COMPUTE_STATIC_THREAD_MGMT_SE3__SH0_CU_EN_MASK 0xffff\n#define COMPUTE_STATIC_THREAD_MGMT_SE3__SH0_CU_EN__SHIFT 0x0\n#define COMPUTE_STATIC_THREAD_MGMT_SE3__SH1_CU_EN_MASK 0xffff0000\n#define COMPUTE_STATIC_THREAD_MGMT_SE3__SH1_CU_EN__SHIFT 0x10\n#define COMPUTE_RESTART_X__RESTART_MASK 0xffffffff\n#define COMPUTE_RESTART_X__RESTART__SHIFT 0x0\n#define COMPUTE_RESTART_Y__RESTART_MASK 0xffffffff\n#define COMPUTE_RESTART_Y__RESTART__SHIFT 0x0\n#define COMPUTE_RESTART_Z__RESTART_MASK 0xffffffff\n#define COMPUTE_RESTART_Z__RESTART__SHIFT 0x0\n#define COMPUTE_THREAD_TRACE_ENABLE__THREAD_TRACE_ENABLE_MASK 0x1\n#define COMPUTE_THREAD_TRACE_ENABLE__THREAD_TRACE_ENABLE__SHIFT 0x0\n#define COMPUTE_MISC_RESERVED__SEND_SEID_MASK 0x3\n#define COMPUTE_MISC_RESERVED__SEND_SEID__SHIFT 0x0\n#define COMPUTE_MISC_RESERVED__RESERVED2_MASK 0x4\n#define COMPUTE_MISC_RESERVED__RESERVED2__SHIFT 0x2\n#define COMPUTE_MISC_RESERVED__RESERVED3_MASK 0x8\n#define COMPUTE_MISC_RESERVED__RESERVED3__SHIFT 0x3\n#define COMPUTE_MISC_RESERVED__RESERVED4_MASK 0x10\n#define COMPUTE_MISC_RESERVED__RESERVED4__SHIFT 0x4\n#define COMPUTE_USER_DATA_0__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_0__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_1__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_1__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_2__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_2__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_3__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_3__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_4__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_4__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_5__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_5__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_6__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_6__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_7__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_7__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_8__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_8__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_9__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_9__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_10__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_10__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_11__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_11__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_12__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_12__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_13__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_13__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_14__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_14__DATA__SHIFT 0x0\n#define COMPUTE_USER_DATA_15__DATA_MASK 0xffffffff\n#define COMPUTE_USER_DATA_15__DATA__SHIFT 0x0\n#define CSPRIV_CONNECT__DOORBELL_OFFSET_MASK 0x1fffff\n#define CSPRIV_CONNECT__DOORBELL_OFFSET__SHIFT 0x0\n#define CSPRIV_CONNECT__QUEUE_ID_MASK 0xe00000\n#define CSPRIV_CONNECT__QUEUE_ID__SHIFT 0x15\n#define CSPRIV_CONNECT__VMID_MASK 0x3c000000\n#define CSPRIV_CONNECT__VMID__SHIFT 0x1a\n#define CSPRIV_CONNECT__UNORD_DISP_MASK 0x80000000\n#define CSPRIV_CONNECT__UNORD_DISP__SHIFT 0x1f\n#define CSPRIV_THREAD_TRACE_TG0__TGID_X_MASK 0xffffffff\n#define CSPRIV_THREAD_TRACE_TG0__TGID_X__SHIFT 0x0\n#define CSPRIV_THREAD_TRACE_TG1__TGID_Y_MASK 0xffffffff\n#define CSPRIV_THREAD_TRACE_TG1__TGID_Y__SHIFT 0x0\n#define CSPRIV_THREAD_TRACE_TG2__TGID_Z_MASK 0xffffffff\n#define CSPRIV_THREAD_TRACE_TG2__TGID_Z__SHIFT 0x0\n#define CSPRIV_THREAD_TRACE_TG3__WAVE_ID_BASE_MASK 0xfff\n#define CSPRIV_THREAD_TRACE_TG3__WAVE_ID_BASE__SHIFT 0x0\n#define CSPRIV_THREAD_TRACE_TG3__THREADS_IN_GROUP_MASK 0xfff000\n#define CSPRIV_THREAD_TRACE_TG3__THREADS_IN_GROUP__SHIFT 0xc\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_X_FLAG_MASK 0x1000000\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_X_FLAG__SHIFT 0x18\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_Y_FLAG_MASK 0x2000000\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_Y_FLAG__SHIFT 0x19\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_Z_FLAG_MASK 0x4000000\n#define CSPRIV_THREAD_TRACE_TG3__PARTIAL_Z_FLAG__SHIFT 0x1a\n#define CSPRIV_THREAD_TRACE_TG3__LAST_TG_MASK 0x8000000\n#define CSPRIV_THREAD_TRACE_TG3__LAST_TG__SHIFT 0x1b\n#define CSPRIV_THREAD_TRACE_TG3__FIRST_TG_MASK 0x10000000\n#define CSPRIV_THREAD_TRACE_TG3__FIRST_TG__SHIFT 0x1c\n#define CSPRIV_THREAD_TRACE_EVENT__EVENT_ID_MASK 0x1f\n#define CSPRIV_THREAD_TRACE_EVENT__EVENT_ID__SHIFT 0x0\n#define RLC_CNTL__RLC_ENABLE_F32_MASK 0x1\n#define RLC_CNTL__RLC_ENABLE_F32__SHIFT 0x0\n#define RLC_CNTL__FORCE_RETRY_MASK 0x2\n#define RLC_CNTL__FORCE_RETRY__SHIFT 0x1\n#define RLC_CNTL__READ_CACHE_DISABLE_MASK 0x4\n#define RLC_CNTL__READ_CACHE_DISABLE__SHIFT 0x2\n#define RLC_CNTL__RLC_STEP_F32_MASK 0x8\n#define RLC_CNTL__RLC_STEP_F32__SHIFT 0x3\n#define RLC_CNTL__SOFT_RESET_DEBUG_MODE_MASK 0x10\n#define RLC_CNTL__SOFT_RESET_DEBUG_MODE__SHIFT 0x4\n#define RLC_CNTL__RESERVED_MASK 0xffffff00\n#define RLC_CNTL__RESERVED__SHIFT 0x8\n#define RLC_DEBUG_SELECT__SELECT_MASK 0xff\n#define RLC_DEBUG_SELECT__SELECT__SHIFT 0x0\n#define RLC_DEBUG_SELECT__RESERVED_MASK 0xffffff00\n#define RLC_DEBUG_SELECT__RESERVED__SHIFT 0x8\n#define RLC_DEBUG__DATA_MASK 0xffffffff\n#define RLC_DEBUG__DATA__SHIFT 0x0\n#define RLC_MC_CNTL__WRREQ_SWAP_MASK 0x3\n#define RLC_MC_CNTL__WRREQ_SWAP__SHIFT 0x0\n#define RLC_MC_CNTL__WRREQ_TRAN_MASK 0x4\n#define RLC_MC_CNTL__WRREQ_TRAN__SHIFT 0x2\n#define RLC_MC_CNTL__WRREQ_PRIV_MASK 0x8\n#define RLC_MC_CNTL__WRREQ_PRIV__SHIFT 0x3\n#define RLC_MC_CNTL__WRNFO_STALL_MASK 0x10\n#define RLC_MC_CNTL__WRNFO_STALL__SHIFT 0x4\n#define RLC_MC_CNTL__WRNFO_URG_MASK 0x1e0\n#define RLC_MC_CNTL__WRNFO_URG__SHIFT 0x5\n#define RLC_MC_CNTL__WRREQ_DW_IMASK_MASK 0x1e00\n#define RLC_MC_CNTL__WRREQ_DW_IMASK__SHIFT 0x9\n#define RLC_MC_CNTL__RESERVED_B_MASK 0xfe000\n#define RLC_MC_CNTL__RESERVED_B__SHIFT 0xd\n#define RLC_MC_CNTL__RDNFO_URG_MASK 0xf00000\n#define RLC_MC_CNTL__RDNFO_URG__SHIFT 0x14\n#define RLC_MC_CNTL__RDREQ_SWAP_MASK 0x3000000\n#define RLC_MC_CNTL__RDREQ_SWAP__SHIFT 0x18\n#define RLC_MC_CNTL__RDREQ_TRAN_MASK 0x4000000\n#define RLC_MC_CNTL__RDREQ_TRAN__SHIFT 0x1a\n#define RLC_MC_CNTL__RDREQ_PRIV_MASK 0x8000000\n#define RLC_MC_CNTL__RDREQ_PRIV__SHIFT 0x1b\n#define RLC_MC_CNTL__RDNFO_STALL_MASK 0x10000000\n#define RLC_MC_CNTL__RDNFO_STALL__SHIFT 0x1c\n#define RLC_MC_CNTL__RESERVED_MASK 0xe0000000\n#define RLC_MC_CNTL__RESERVED__SHIFT 0x1d\n#define RLC_STAT__RLC_BUSY_MASK 0x1\n#define RLC_STAT__RLC_BUSY__SHIFT 0x0\n#define RLC_STAT__RLC_GPM_BUSY_MASK 0x2\n#define RLC_STAT__RLC_GPM_BUSY__SHIFT 0x1\n#define RLC_STAT__RLC_SPM_BUSY_MASK 0x4\n#define RLC_STAT__RLC_SPM_BUSY__SHIFT 0x2\n#define RLC_STAT__RESERVED_MASK 0xfffffff8\n#define RLC_STAT__RESERVED__SHIFT 0x3\n#define RLC_SAFE_MODE__REQ_MASK 0x1\n#define RLC_SAFE_MODE__REQ__SHIFT 0x0\n#define RLC_SAFE_MODE__MESSAGE_MASK 0x1e\n#define RLC_SAFE_MODE__MESSAGE__SHIFT 0x1\n#define RLC_SAFE_MODE__RESERVED_MASK 0xffffffe0\n#define RLC_SAFE_MODE__RESERVED__SHIFT 0x5\n#define RLC_SOFT_RESET_GPU__SOFT_RESET_GPU_MASK 0x1\n#define RLC_SOFT_RESET_GPU__SOFT_RESET_GPU__SHIFT 0x0\n#define RLC_SOFT_RESET_GPU__RESERVED_MASK 0xfffffffe\n#define RLC_SOFT_RESET_GPU__RESERVED__SHIFT 0x1\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK 0x1\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN__SHIFT 0x0\n#define RLC_MEM_SLP_CNTL__RLC_MEM_DS_EN_MASK 0x2\n#define RLC_MEM_SLP_CNTL__RLC_MEM_DS_EN__SHIFT 0x1\n#define RLC_MEM_SLP_CNTL__RESERVED_MASK 0xfc\n#define RLC_MEM_SLP_CNTL__RESERVED__SHIFT 0x2\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_ON_DELAY_MASK 0xff00\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_ON_DELAY__SHIFT 0x8\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_OFF_DELAY_MASK 0xff0000\n#define RLC_MEM_SLP_CNTL__RLC_MEM_LS_OFF_DELAY__SHIFT 0x10\n#define RLC_MEM_SLP_CNTL__RESERVED1_MASK 0xff000000\n#define RLC_MEM_SLP_CNTL__RESERVED1__SHIFT 0x18\n#define RLC_PERFMON_CNTL__PERFMON_STATE_MASK 0x7\n#define RLC_PERFMON_CNTL__PERFMON_STATE__SHIFT 0x0\n#define RLC_PERFMON_CNTL__PERFMON_SAMPLE_ENABLE_MASK 0x400\n#define RLC_PERFMON_CNTL__PERFMON_SAMPLE_ENABLE__SHIFT 0xa\n#define RLC_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT_MASK 0xff\n#define RLC_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define RLC_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT_MASK 0xff\n#define RLC_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define RLC_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define RLC_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define RLC_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define RLC_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define RLC_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define RLC_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define RLC_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define RLC_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define CGTT_RLC_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_RLC_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_RLC_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_RLC_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_RLC_CLK_CTRL__SOFT_OVERRIDE_DYN_MASK 0x40000000\n#define CGTT_RLC_CLK_CTRL__SOFT_OVERRIDE_DYN__SHIFT 0x1e\n#define CGTT_RLC_CLK_CTRL__SOFT_OVERRIDE_REG_MASK 0x80000000\n#define CGTT_RLC_CLK_CTRL__SOFT_OVERRIDE_REG__SHIFT 0x1f\n#define RLC_LB_CNTL__LOAD_BALANCE_ENABLE_MASK 0x1\n#define RLC_LB_CNTL__LOAD_BALANCE_ENABLE__SHIFT 0x0\n#define RLC_LB_CNTL__LB_CNT_CP_BUSY_MASK 0x2\n#define RLC_LB_CNTL__LB_CNT_CP_BUSY__SHIFT 0x1\n#define RLC_LB_CNTL__LB_CNT_SPIM_ACTIVE_MASK 0x4\n#define RLC_LB_CNTL__LB_CNT_SPIM_ACTIVE__SHIFT 0x2\n#define RLC_LB_CNTL__LB_CNT_REG_INC_MASK 0x8\n#define RLC_LB_CNTL__LB_CNT_REG_INC__SHIFT 0x3\n#define RLC_LB_CNTL__CU_MASK_USED_OFF_HYST_MASK 0xff0\n#define RLC_LB_CNTL__CU_MASK_USED_OFF_HYST__SHIFT 0x4\n#define RLC_LB_CNTL__RESERVED_MASK 0xfffff000\n#define RLC_LB_CNTL__RESERVED__SHIFT 0xc\n#define RLC_LB_CNTR_MAX__LB_CNTR_MAX_MASK 0xffffffff\n#define RLC_LB_CNTR_MAX__LB_CNTR_MAX__SHIFT 0x0\n#define RLC_LB_CNTR_INIT__LB_CNTR_INIT_MASK 0xffffffff\n#define RLC_LB_CNTR_INIT__LB_CNTR_INIT__SHIFT 0x0\n#define RLC_LOAD_BALANCE_CNTR__RLC_LOAD_BALANCE_CNTR_MASK 0xffffffff\n#define RLC_LOAD_BALANCE_CNTR__RLC_LOAD_BALANCE_CNTR__SHIFT 0x0\n#define RLC_SAVE_AND_RESTORE_BASE__BASE_MASK 0xffffffff\n#define RLC_SAVE_AND_RESTORE_BASE__BASE__SHIFT 0x0\n#define RLC_JUMP_TABLE_RESTORE__ADDR_MASK 0xffffffff\n#define RLC_JUMP_TABLE_RESTORE__ADDR__SHIFT 0x0\n#define RLC_DRIVER_CPDMA_STATUS__DRIVER_REQUEST_MASK 0x1\n#define RLC_DRIVER_CPDMA_STATUS__DRIVER_REQUEST__SHIFT 0x0\n#define RLC_DRIVER_CPDMA_STATUS__RESERVED1_MASK 0xe\n#define RLC_DRIVER_CPDMA_STATUS__RESERVED1__SHIFT 0x1\n#define RLC_DRIVER_CPDMA_STATUS__DRIVER_ACK_MASK 0x10\n#define RLC_DRIVER_CPDMA_STATUS__DRIVER_ACK__SHIFT 0x4\n#define RLC_DRIVER_CPDMA_STATUS__RESERVED_MASK 0xffffffe0\n#define RLC_DRIVER_CPDMA_STATUS__RESERVED__SHIFT 0x5\n#define RLC_PG_DELAY_2__SERDES_TIMEOUT_VALUE_MASK 0xff\n#define RLC_PG_DELAY_2__SERDES_TIMEOUT_VALUE__SHIFT 0x0\n#define RLC_PG_DELAY_2__SERDES_CMD_DELAY_MASK 0xff00\n#define RLC_PG_DELAY_2__SERDES_CMD_DELAY__SHIFT 0x8\n#define RLC_PG_DELAY_2__PERCU_TIMEOUT_VALUE_MASK 0xffff0000\n#define RLC_PG_DELAY_2__PERCU_TIMEOUT_VALUE__SHIFT 0x10\n#define RLC_GPM_DEBUG_SELECT__SELECT_MASK 0xff\n#define RLC_GPM_DEBUG_SELECT__SELECT__SHIFT 0x0\n#define RLC_GPM_DEBUG_SELECT__RESERVED_MASK 0xffffff00\n#define RLC_GPM_DEBUG_SELECT__RESERVED__SHIFT 0x8\n#define RLC_GPM_DEBUG__DATA_MASK 0xffffffff\n#define RLC_GPM_DEBUG__DATA__SHIFT 0x0\n#define RLC_GPM_UCODE_ADDR__UCODE_ADDR_MASK 0xfff\n#define RLC_GPM_UCODE_ADDR__UCODE_ADDR__SHIFT 0x0\n#define RLC_GPM_UCODE_ADDR__RESERVED_MASK 0xfffff000\n#define RLC_GPM_UCODE_ADDR__RESERVED__SHIFT 0xc\n#define RLC_GPM_UCODE_DATA__UCODE_DATA_MASK 0xffffffff\n#define RLC_GPM_UCODE_DATA__UCODE_DATA__SHIFT 0x0\n#define RLC_GPU_CLOCK_COUNT_LSB__GPU_CLOCKS_LSB_MASK 0xffffffff\n#define RLC_GPU_CLOCK_COUNT_LSB__GPU_CLOCKS_LSB__SHIFT 0x0\n#define RLC_GPU_CLOCK_COUNT_MSB__GPU_CLOCKS_MSB_MASK 0xffffffff\n#define RLC_GPU_CLOCK_COUNT_MSB__GPU_CLOCKS_MSB__SHIFT 0x0\n#define RLC_CAPTURE_GPU_CLOCK_COUNT__CAPTURE_MASK 0x1\n#define RLC_CAPTURE_GPU_CLOCK_COUNT__CAPTURE__SHIFT 0x0\n#define RLC_CAPTURE_GPU_CLOCK_COUNT__RESERVED_MASK 0xfffffffe\n#define RLC_CAPTURE_GPU_CLOCK_COUNT__RESERVED__SHIFT 0x1\n#define RLC_UCODE_CNTL__RLC_UCODE_FLAGS_MASK 0xffffffff\n#define RLC_UCODE_CNTL__RLC_UCODE_FLAGS__SHIFT 0x0\n#define RLC_GPM_STAT__RLC_BUSY_MASK 0x1\n#define RLC_GPM_STAT__RLC_BUSY__SHIFT 0x0\n#define RLC_GPM_STAT__GFX_POWER_STATUS_MASK 0x2\n#define RLC_GPM_STAT__GFX_POWER_STATUS__SHIFT 0x1\n#define RLC_GPM_STAT__GFX_CLOCK_STATUS_MASK 0x4\n#define RLC_GPM_STAT__GFX_CLOCK_STATUS__SHIFT 0x2\n#define RLC_GPM_STAT__GFX_LS_STATUS_MASK 0x8\n#define RLC_GPM_STAT__GFX_LS_STATUS__SHIFT 0x3\n#define RLC_GPM_STAT__RESERVED_MASK 0xfffffff0\n#define RLC_GPM_STAT__RESERVED__SHIFT 0x4\n#define RLC_GPU_CLOCK_32_RES_SEL__RES_SEL_MASK 0x3f\n#define RLC_GPU_CLOCK_32_RES_SEL__RES_SEL__SHIFT 0x0\n#define RLC_GPU_CLOCK_32_RES_SEL__RESERVED_MASK 0xffffffc0\n#define RLC_GPU_CLOCK_32_RES_SEL__RESERVED__SHIFT 0x6\n#define RLC_GPU_CLOCK_32__GPU_CLOCK_32_MASK 0xffffffff\n#define RLC_GPU_CLOCK_32__GPU_CLOCK_32__SHIFT 0x0\n#define RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK 0x1\n#define RLC_PG_CNTL__GFX_POWER_GATING_ENABLE__SHIFT 0x0\n#define RLC_PG_CNTL__GFX_POWER_GATING_SRC_MASK 0x2\n#define RLC_PG_CNTL__GFX_POWER_GATING_SRC__SHIFT 0x1\n#define RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK 0x4\n#define RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE__SHIFT 0x2\n#define RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK 0x8\n#define RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE__SHIFT 0x3\n#define RLC_PG_CNTL__RESERVED_MASK 0xfff0\n#define RLC_PG_CNTL__RESERVED__SHIFT 0x4\n#define RLC_PG_CNTL__CHUB_HANDSHAKE_ENABLE_MASK 0x10000\n#define RLC_PG_CNTL__CHUB_HANDSHAKE_ENABLE__SHIFT 0x10\n#define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE_MASK 0x20000\n#define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PU_ENABLE__SHIFT 0x11\n#define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE_MASK 0x40000\n#define RLC_PG_CNTL__SMU_CLK_SLOWDOWN_ON_PD_ENABLE__SHIFT 0x12\n#define RLC_PG_CNTL__RESERVED1_MASK 0xf80000\n#define RLC_PG_CNTL__RESERVED1__SHIFT 0x13\n#define RLC_PG_CNTL__PG_ERROR_STATUS_MASK 0xff000000\n#define RLC_PG_CNTL__PG_ERROR_STATUS__SHIFT 0x18\n#define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY_MASK 0xff\n#define RLC_GPM_THREAD_PRIORITY__THREAD0_PRIORITY__SHIFT 0x0\n#define RLC_GPM_THREAD_PRIORITY__THREAD1_PRIORITY_MASK 0xff00\n#define RLC_GPM_THREAD_PRIORITY__THREAD1_PRIORITY__SHIFT 0x8\n#define RLC_GPM_THREAD_PRIORITY__THREAD2_PRIORITY_MASK 0xff0000\n#define RLC_GPM_THREAD_PRIORITY__THREAD2_PRIORITY__SHIFT 0x10\n#define RLC_GPM_THREAD_PRIORITY__THREAD3_PRIORITY_MASK 0xff000000\n#define RLC_GPM_THREAD_PRIORITY__THREAD3_PRIORITY__SHIFT 0x18\n#define RLC_GPM_THREAD_ENABLE__THREAD0_ENABLE_MASK 0x1\n#define RLC_GPM_THREAD_ENABLE__THREAD0_ENABLE__SHIFT 0x0\n#define RLC_GPM_THREAD_ENABLE__THREAD1_ENABLE_MASK 0x2\n#define RLC_GPM_THREAD_ENABLE__THREAD1_ENABLE__SHIFT 0x1\n#define RLC_GPM_THREAD_ENABLE__THREAD2_ENABLE_MASK 0x4\n#define RLC_GPM_THREAD_ENABLE__THREAD2_ENABLE__SHIFT 0x2\n#define RLC_GPM_THREAD_ENABLE__THREAD3_ENABLE_MASK 0x8\n#define RLC_GPM_THREAD_ENABLE__THREAD3_ENABLE__SHIFT 0x3\n#define RLC_GPM_THREAD_ENABLE__RESERVED_MASK 0xfffffff0\n#define RLC_GPM_THREAD_ENABLE__RESERVED__SHIFT 0x4\n#define RLC_GPM_VMID_THREAD0__RLC_VMID_MASK 0xf\n#define RLC_GPM_VMID_THREAD0__RLC_VMID__SHIFT 0x0\n#define RLC_GPM_VMID_THREAD0__RESERVED_MASK 0xfffffff0\n#define RLC_GPM_VMID_THREAD0__RESERVED__SHIFT 0x4\n#define RLC_GPM_VMID_THREAD1__RLC_VMID_MASK 0xf\n#define RLC_GPM_VMID_THREAD1__RLC_VMID__SHIFT 0x0\n#define RLC_GPM_VMID_THREAD1__RESERVED_MASK 0xfffffff0\n#define RLC_GPM_VMID_THREAD1__RESERVED__SHIFT 0x4\n#define RLC_CGTT_MGCG_OVERRIDE__OVERRIDE_MASK 0xffffffff\n#define RLC_CGTT_MGCG_OVERRIDE__OVERRIDE__SHIFT 0x0\n#define RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK 0x1\n#define RLC_CGCG_CGLS_CTRL__CGCG_EN__SHIFT 0x0\n#define RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK 0x2\n#define RLC_CGCG_CGLS_CTRL__CGLS_EN__SHIFT 0x1\n#define RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY_MASK 0xfc\n#define RLC_CGCG_CGLS_CTRL__CGLS_REP_COMPANSAT_DELAY__SHIFT 0x2\n#define RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD_MASK 0x7ffff00\n#define RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT 0x8\n#define RLC_CGCG_CGLS_CTRL__CGCG_CONTROLLER_MASK 0x8000000\n#define RLC_CGCG_CGLS_CTRL__CGCG_CONTROLLER__SHIFT 0x1b\n#define RLC_CGCG_CGLS_CTRL__CGCG_REG_CTRL_MASK 0x10000000\n#define RLC_CGCG_CGLS_CTRL__CGCG_REG_CTRL__SHIFT 0x1c\n#define RLC_CGCG_CGLS_CTRL__SLEEP_MODE_MASK 0x60000000\n#define RLC_CGCG_CGLS_CTRL__SLEEP_MODE__SHIFT 0x1d\n#define RLC_CGCG_CGLS_CTRL__SPARE_MASK 0x80000000\n#define RLC_CGCG_CGLS_CTRL__SPARE__SHIFT 0x1f\n#define RLC_CGCG_RAMP_CTRL__DOWN_DIV_START_UNIT_MASK 0xf\n#define RLC_CGCG_RAMP_CTRL__DOWN_DIV_START_UNIT__SHIFT 0x0\n#define RLC_CGCG_RAMP_CTRL__DOWN_DIV_STEP_UNIT_MASK 0xf0\n#define RLC_CGCG_RAMP_CTRL__DOWN_DIV_STEP_UNIT__SHIFT 0x4\n#define RLC_CGCG_RAMP_CTRL__UP_DIV_START_UNIT_MASK 0xf00\n#define RLC_CGCG_RAMP_CTRL__UP_DIV_START_UNIT__SHIFT 0x8\n#define RLC_CGCG_RAMP_CTRL__UP_DIV_STEP_UNIT_MASK 0xf000\n#define RLC_CGCG_RAMP_CTRL__UP_DIV_STEP_UNIT__SHIFT 0xc\n#define RLC_CGCG_RAMP_CTRL__STEP_DELAY_CNT_MASK 0xfff0000\n#define RLC_CGCG_RAMP_CTRL__STEP_DELAY_CNT__SHIFT 0x10\n#define RLC_CGCG_RAMP_CTRL__STEP_DELAY_UNIT_MASK 0xf0000000\n#define RLC_CGCG_RAMP_CTRL__STEP_DELAY_UNIT__SHIFT 0x1c\n#define RLC_DYN_PG_STATUS__PG_STATUS_CU_MASK_MASK 0xffffffff\n#define RLC_DYN_PG_STATUS__PG_STATUS_CU_MASK__SHIFT 0x0\n#define RLC_DYN_PG_REQUEST__PG_REQUEST_CU_MASK_MASK 0xffffffff\n#define RLC_DYN_PG_REQUEST__PG_REQUEST_CU_MASK__SHIFT 0x0\n#define RLC_PG_DELAY__POWER_UP_DELAY_MASK 0xff\n#define RLC_PG_DELAY__POWER_UP_DELAY__SHIFT 0x0\n#define RLC_PG_DELAY__POWER_DOWN_DELAY_MASK 0xff00\n#define RLC_PG_DELAY__POWER_DOWN_DELAY__SHIFT 0x8\n#define RLC_PG_DELAY__CMD_PROPAGATE_DELAY_MASK 0xff0000\n#define RLC_PG_DELAY__CMD_PROPAGATE_DELAY__SHIFT 0x10\n#define RLC_PG_DELAY__MEM_SLEEP_DELAY_MASK 0xff000000\n#define RLC_PG_DELAY__MEM_SLEEP_DELAY__SHIFT 0x18\n#define RLC_CU_STATUS__WORK_PENDING_MASK 0xffffffff\n#define RLC_CU_STATUS__WORK_PENDING__SHIFT 0x0\n#define RLC_LB_INIT_CU_MASK__INIT_CU_MASK_MASK 0xffffffff\n#define RLC_LB_INIT_CU_MASK__INIT_CU_MASK__SHIFT 0x0\n#define RLC_LB_ALWAYS_ACTIVE_CU_MASK__ALWAYS_ACTIVE_CU_MASK_MASK 0xffffffff\n#define RLC_LB_ALWAYS_ACTIVE_CU_MASK__ALWAYS_ACTIVE_CU_MASK__SHIFT 0x0\n#define RLC_LB_PARAMS__SKIP_L2_CHECK_MASK 0x1\n#define RLC_LB_PARAMS__SKIP_L2_CHECK__SHIFT 0x0\n#define RLC_LB_PARAMS__FIFO_SAMPLES_MASK 0xfe\n#define RLC_LB_PARAMS__FIFO_SAMPLES__SHIFT 0x1\n#define RLC_LB_PARAMS__PG_IDLE_SAMPLES_MASK 0xff00\n#define RLC_LB_PARAMS__PG_IDLE_SAMPLES__SHIFT 0x8\n#define RLC_LB_PARAMS__PG_IDLE_SAMPLE_INTERVAL_MASK 0xffff0000\n#define RLC_LB_PARAMS__PG_IDLE_SAMPLE_INTERVAL__SHIFT 0x10\n#define RLC_THREAD1_DELAY__CU_IDEL_DELAY_MASK 0xff\n#define RLC_THREAD1_DELAY__CU_IDEL_DELAY__SHIFT 0x0\n#define RLC_THREAD1_DELAY__LBPW_INNER_LOOP_DELAY_MASK 0xff00\n#define RLC_THREAD1_DELAY__LBPW_INNER_LOOP_DELAY__SHIFT 0x8\n#define RLC_THREAD1_DELAY__LBPW_OUTER_LOOP_DELAY_MASK 0xff0000\n#define RLC_THREAD1_DELAY__LBPW_OUTER_LOOP_DELAY__SHIFT 0x10\n#define RLC_THREAD1_DELAY__SPARE_MASK 0xff000000\n#define RLC_THREAD1_DELAY__SPARE__SHIFT 0x18\n#define RLC_PG_ALWAYS_ON_CU_MASK__AON_CU_MASK_MASK 0xffffffff\n#define RLC_PG_ALWAYS_ON_CU_MASK__AON_CU_MASK__SHIFT 0x0\n#define RLC_MAX_PG_CU__MAX_POWERED_UP_CU_MASK 0xff\n#define RLC_MAX_PG_CU__MAX_POWERED_UP_CU__SHIFT 0x0\n#define RLC_MAX_PG_CU__SPARE_MASK 0xffffff00\n#define RLC_MAX_PG_CU__SPARE__SHIFT 0x8\n#define RLC_AUTO_PG_CTRL__AUTO_PG_EN_MASK 0x1\n#define RLC_AUTO_PG_CTRL__AUTO_PG_EN__SHIFT 0x0\n#define RLC_AUTO_PG_CTRL__AUTO_GRBM_REG_SAVE_ON_IDLE_EN_MASK 0x2\n#define RLC_AUTO_PG_CTRL__AUTO_GRBM_REG_SAVE_ON_IDLE_EN__SHIFT 0x1\n#define RLC_AUTO_PG_CTRL__AUTO_WAKE_UP_EN_MASK 0x4\n#define RLC_AUTO_PG_CTRL__AUTO_WAKE_UP_EN__SHIFT 0x2\n#define RLC_AUTO_PG_CTRL__GRBM_REG_SAVE_GFX_IDLE_THRESHOLD_MASK 0x7fff8\n#define RLC_AUTO_PG_CTRL__GRBM_REG_SAVE_GFX_IDLE_THRESHOLD__SHIFT 0x3\n#define RLC_AUTO_PG_CTRL__PG_AFTER_GRBM_REG_SAVE_THRESHOLD_MASK 0xfff80000\n#define RLC_AUTO_PG_CTRL__PG_AFTER_GRBM_REG_SAVE_THRESHOLD__SHIFT 0x13\n#define RLC_SMU_GRBM_REG_SAVE_CTRL__START_GRBM_REG_SAVE_MASK 0x1\n#define RLC_SMU_GRBM_REG_SAVE_CTRL__START_GRBM_REG_SAVE__SHIFT 0x0\n#define RLC_SMU_GRBM_REG_SAVE_CTRL__SPARE_MASK 0xfffffffe\n#define RLC_SMU_GRBM_REG_SAVE_CTRL__SPARE__SHIFT 0x1\n#define RLC_SMU_PG_CTRL__START_PG_MASK 0x1\n#define RLC_SMU_PG_CTRL__START_PG__SHIFT 0x0\n#define RLC_SMU_PG_CTRL__SPARE_MASK 0xfffffffe\n#define RLC_SMU_PG_CTRL__SPARE__SHIFT 0x1\n#define RLC_SMU_PG_WAKE_UP_CTRL__START_PG_WAKE_UP_MASK 0x1\n#define RLC_SMU_PG_WAKE_UP_CTRL__START_PG_WAKE_UP__SHIFT 0x0\n#define RLC_SMU_PG_WAKE_UP_CTRL__SPARE_MASK 0xfffffffe\n#define RLC_SMU_PG_WAKE_UP_CTRL__SPARE__SHIFT 0x1\n#define RLC_SERDES_RD_MASTER_INDEX__CU_ID_MASK 0xf\n#define RLC_SERDES_RD_MASTER_INDEX__CU_ID__SHIFT 0x0\n#define RLC_SERDES_RD_MASTER_INDEX__SH_ID_MASK 0x30\n#define RLC_SERDES_RD_MASTER_INDEX__SH_ID__SHIFT 0x4\n#define RLC_SERDES_RD_MASTER_INDEX__SE_ID_MASK 0x1c0\n#define RLC_SERDES_RD_MASTER_INDEX__SE_ID__SHIFT 0x6\n#define RLC_SERDES_RD_MASTER_INDEX__SE_NONCU_ID_MASK 0x200\n#define RLC_SERDES_RD_MASTER_INDEX__SE_NONCU_ID__SHIFT 0x9\n#define RLC_SERDES_RD_MASTER_INDEX__SE_NONCU_MASK 0x400\n#define RLC_SERDES_RD_MASTER_INDEX__SE_NONCU__SHIFT 0xa\n#define RLC_SERDES_RD_MASTER_INDEX__NON_SE_MASK 0x3800\n#define RLC_SERDES_RD_MASTER_INDEX__NON_SE__SHIFT 0xb\n#define RLC_SERDES_RD_MASTER_INDEX__DATA_REG_ID_MASK 0xc000\n#define RLC_SERDES_RD_MASTER_INDEX__DATA_REG_ID__SHIFT 0xe\n#define RLC_SERDES_RD_MASTER_INDEX__SPARE_MASK 0xffff0000\n#define RLC_SERDES_RD_MASTER_INDEX__SPARE__SHIFT 0x10\n#define RLC_SERDES_RD_DATA_0__DATA_MASK 0xffffffff\n#define RLC_SERDES_RD_DATA_0__DATA__SHIFT 0x0\n#define RLC_SERDES_RD_DATA_1__DATA_MASK 0xffffffff\n#define RLC_SERDES_RD_DATA_1__DATA__SHIFT 0x0\n#define RLC_SERDES_RD_DATA_2__DATA_MASK 0xffffffff\n#define RLC_SERDES_RD_DATA_2__DATA__SHIFT 0x0\n#define RLC_SERDES_WR_CU_MASTER_MASK__MASTER_MASK_MASK 0xffffffff\n#define RLC_SERDES_WR_CU_MASTER_MASK__MASTER_MASK__SHIFT 0x0\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SE_MASTER_MASK_MASK 0xffff\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SE_MASTER_MASK__SHIFT 0x0\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__GC_MASTER_MASK_MASK 0x10000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__GC_MASTER_MASK__SHIFT 0x10\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__TC0_MASTER_MASK_MASK 0x20000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__TC0_MASTER_MASK__SHIFT 0x11\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__TC1_MASTER_MASK_MASK 0x40000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__TC1_MASTER_MASK__SHIFT 0x12\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE0_MASTER_MASK_MASK 0x80000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE0_MASTER_MASK__SHIFT 0x13\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE1_MASTER_MASK_MASK 0x100000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE1_MASTER_MASK__SHIFT 0x14\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE2_MASTER_MASK_MASK 0x200000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE2_MASTER_MASK__SHIFT 0x15\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE3_MASTER_MASK_MASK 0x400000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__SPARE3_MASTER_MASK__SHIFT 0x16\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__RESERVED_MASK 0xff800000\n#define RLC_SERDES_WR_NONCU_MASTER_MASK__RESERVED__SHIFT 0x17\n#define RLC_SERDES_WR_CTRL__BPM_ADDR_MASK 0xff\n#define RLC_SERDES_WR_CTRL__BPM_ADDR__SHIFT 0x0\n#define RLC_SERDES_WR_CTRL__POWER_DOWN_MASK 0x100\n#define RLC_SERDES_WR_CTRL__POWER_DOWN__SHIFT 0x8\n#define RLC_SERDES_WR_CTRL__POWER_UP_MASK 0x200\n#define RLC_SERDES_WR_CTRL__POWER_UP__SHIFT 0x9\n#define RLC_SERDES_WR_CTRL__P1_SELECT_MASK 0x400\n#define RLC_SERDES_WR_CTRL__P1_SELECT__SHIFT 0xa\n#define RLC_SERDES_WR_CTRL__P2_SELECT_MASK 0x800\n#define RLC_SERDES_WR_CTRL__P2_SELECT__SHIFT 0xb\n#define RLC_SERDES_WR_CTRL__WRITE_COMMAND_MASK 0x1000\n#define RLC_SERDES_WR_CTRL__WRITE_COMMAND__SHIFT 0xc\n#define RLC_SERDES_WR_CTRL__READ_COMMAND_MASK 0x2000\n#define RLC_SERDES_WR_CTRL__READ_COMMAND__SHIFT 0xd\n#define RLC_SERDES_WR_CTRL__RESERVED_1_MASK 0xc000\n#define RLC_SERDES_WR_CTRL__RESERVED_1__SHIFT 0xe\n#define RLC_SERDES_WR_CTRL__CGLS_ENABLE_MASK 0x10000\n#define RLC_SERDES_WR_CTRL__CGLS_ENABLE__SHIFT 0x10\n#define RLC_SERDES_WR_CTRL__CGLS_DISABLE_MASK 0x20000\n#define RLC_SERDES_WR_CTRL__CGLS_DISABLE__SHIFT 0x11\n#define RLC_SERDES_WR_CTRL__CGLS_ON_MASK 0x40000\n#define RLC_SERDES_WR_CTRL__CGLS_ON__SHIFT 0x12\n#define RLC_SERDES_WR_CTRL__CGLS_OFF_MASK 0x80000\n#define RLC_SERDES_WR_CTRL__CGLS_OFF__SHIFT 0x13\n#define RLC_SERDES_WR_CTRL__CGCG_OVERRIDE_0_MASK 0x100000\n#define RLC_SERDES_WR_CTRL__CGCG_OVERRIDE_0__SHIFT 0x14\n#define RLC_SERDES_WR_CTRL__CGCG_OVERRIDE_1_MASK 0x200000\n#define RLC_SERDES_WR_CTRL__CGCG_OVERRIDE_1__SHIFT 0x15\n#define RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_0_MASK 0x400000\n#define RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_0__SHIFT 0x16\n#define RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_1_MASK 0x800000\n#define RLC_SERDES_WR_CTRL__MGCG_OVERRIDE_1__SHIFT 0x17\n#define RLC_SERDES_WR_CTRL__RESERVED_2_MASK 0xf000000\n#define RLC_SERDES_WR_CTRL__RESERVED_2__SHIFT 0x18\n#define RLC_SERDES_WR_CTRL__REG_ADDR_MASK 0xf0000000\n#define RLC_SERDES_WR_CTRL__REG_ADDR__SHIFT 0x1c\n#define RLC_SERDES_WR_DATA__DATA_MASK 0xffffffff\n#define RLC_SERDES_WR_DATA__DATA__SHIFT 0x0\n#define RLC_SERDES_CU_MASTER_BUSY__BUSY_BUSY_MASK 0xffffffff\n#define RLC_SERDES_CU_MASTER_BUSY__BUSY_BUSY__SHIFT 0x0\n#define RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY_MASK 0xffff\n#define RLC_SERDES_NONCU_MASTER_BUSY__SE_MASTER_BUSY__SHIFT 0x0\n#define RLC_SERDES_NONCU_MASTER_BUSY__GC_MASTER_BUSY_MASK 0x10000\n#define RLC_SERDES_NONCU_MASTER_BUSY__GC_MASTER_BUSY__SHIFT 0x10\n#define RLC_SERDES_NONCU_MASTER_BUSY__TC0_MASTER_BUSY_MASK 0x20000\n#define RLC_SERDES_NONCU_MASTER_BUSY__TC0_MASTER_BUSY__SHIFT 0x11\n#define RLC_SERDES_NONCU_MASTER_BUSY__TC1_MASTER_BUSY_MASK 0x40000\n#define RLC_SERDES_NONCU_MASTER_BUSY__TC1_MASTER_BUSY__SHIFT 0x12\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE0_MASTER_BUSY_MASK 0x80000\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE0_MASTER_BUSY__SHIFT 0x13\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE1_MASTER_BUSY_MASK 0x100000\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE1_MASTER_BUSY__SHIFT 0x14\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE2_MASTER_BUSY_MASK 0x200000\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE2_MASTER_BUSY__SHIFT 0x15\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE3_MASTER_BUSY_MASK 0x400000\n#define RLC_SERDES_NONCU_MASTER_BUSY__SPARE3_MASTER_BUSY__SHIFT 0x16\n#define RLC_SERDES_NONCU_MASTER_BUSY__RESERVED_MASK 0xff800000\n#define RLC_SERDES_NONCU_MASTER_BUSY__RESERVED__SHIFT 0x17\n#define RLC_GPM_GENERAL_0__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_0__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_1__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_1__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_2__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_2__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_3__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_3__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_4__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_4__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_5__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_5__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_6__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_6__DATA__SHIFT 0x0\n#define RLC_GPM_GENERAL_7__DATA_MASK 0xffffffff\n#define RLC_GPM_GENERAL_7__DATA__SHIFT 0x0\n#define RLC_GPM_CU_PD_TIMEOUT__TIMEOUT_MASK 0xffffffff\n#define RLC_GPM_CU_PD_TIMEOUT__TIMEOUT__SHIFT 0x0\n#define RLC_GPM_SCRATCH_ADDR__ADDR_MASK 0x1ff\n#define RLC_GPM_SCRATCH_ADDR__ADDR__SHIFT 0x0\n#define RLC_GPM_SCRATCH_ADDR__RESERVED_MASK 0xfffffe00\n#define RLC_GPM_SCRATCH_ADDR__RESERVED__SHIFT 0x9\n#define RLC_GPM_SCRATCH_DATA__DATA_MASK 0xffffffff\n#define RLC_GPM_SCRATCH_DATA__DATA__SHIFT 0x0\n#define RLC_STATIC_PG_STATUS__PG_STATUS_CU_MASK_MASK 0xffffffff\n#define RLC_STATIC_PG_STATUS__PG_STATUS_CU_MASK__SHIFT 0x0\n#define RLC_GPM_PERF_COUNT_0__FEATURE_SEL_MASK 0xf\n#define RLC_GPM_PERF_COUNT_0__FEATURE_SEL__SHIFT 0x0\n#define RLC_GPM_PERF_COUNT_0__SE_INDEX_MASK 0xf0\n#define RLC_GPM_PERF_COUNT_0__SE_INDEX__SHIFT 0x4\n#define RLC_GPM_PERF_COUNT_0__SH_INDEX_MASK 0xf00\n#define RLC_GPM_PERF_COUNT_0__SH_INDEX__SHIFT 0x8\n#define RLC_GPM_PERF_COUNT_0__CU_INDEX_MASK 0xf000\n#define RLC_GPM_PERF_COUNT_0__CU_INDEX__SHIFT 0xc\n#define RLC_GPM_PERF_COUNT_0__EVENT_SEL_MASK 0x30000\n#define RLC_GPM_PERF_COUNT_0__EVENT_SEL__SHIFT 0x10\n#define RLC_GPM_PERF_COUNT_0__UNUSED_MASK 0xc0000\n#define RLC_GPM_PERF_COUNT_0__UNUSED__SHIFT 0x12\n#define RLC_GPM_PERF_COUNT_0__ENABLE_MASK 0x100000\n#define RLC_GPM_PERF_COUNT_0__ENABLE__SHIFT 0x14\n#define RLC_GPM_PERF_COUNT_0__RESERVED_MASK 0xffe00000\n#define RLC_GPM_PERF_COUNT_0__RESERVED__SHIFT 0x15\n#define RLC_GPM_PERF_COUNT_1__FEATURE_SEL_MASK 0xf\n#define RLC_GPM_PERF_COUNT_1__FEATURE_SEL__SHIFT 0x0\n#define RLC_GPM_PERF_COUNT_1__SE_INDEX_MASK 0xf0\n#define RLC_GPM_PERF_COUNT_1__SE_INDEX__SHIFT 0x4\n#define RLC_GPM_PERF_COUNT_1__SH_INDEX_MASK 0xf00\n#define RLC_GPM_PERF_COUNT_1__SH_INDEX__SHIFT 0x8\n#define RLC_GPM_PERF_COUNT_1__CU_INDEX_MASK 0xf000\n#define RLC_GPM_PERF_COUNT_1__CU_INDEX__SHIFT 0xc\n#define RLC_GPM_PERF_COUNT_1__EVENT_SEL_MASK 0x30000\n#define RLC_GPM_PERF_COUNT_1__EVENT_SEL__SHIFT 0x10\n#define RLC_GPM_PERF_COUNT_1__UNUSED_MASK 0xc0000\n#define RLC_GPM_PERF_COUNT_1__UNUSED__SHIFT 0x12\n#define RLC_GPM_PERF_COUNT_1__ENABLE_MASK 0x100000\n#define RLC_GPM_PERF_COUNT_1__ENABLE__SHIFT 0x14\n#define RLC_GPM_PERF_COUNT_1__RESERVED_MASK 0xffe00000\n#define RLC_GPM_PERF_COUNT_1__RESERVED__SHIFT 0x15\n#define RLC_GPR_REG1__DATA_MASK 0xffffffff\n#define RLC_GPR_REG1__DATA__SHIFT 0x0\n#define RLC_GPR_REG2__DATA_MASK 0xffffffff\n#define RLC_GPR_REG2__DATA__SHIFT 0x0\n#define RLC_SPM_VMID__RLC_SPM_VMID_MASK 0xf\n#define RLC_SPM_VMID__RLC_SPM_VMID__SHIFT 0x0\n#define RLC_SPM_VMID__RESERVED_MASK 0xfffffff0\n#define RLC_SPM_VMID__RESERVED__SHIFT 0x4\n#define RLC_SPM_INT_CNTL__RLC_SPM_INT_CNTL_MASK 0x1\n#define RLC_SPM_INT_CNTL__RLC_SPM_INT_CNTL__SHIFT 0x0\n#define RLC_SPM_INT_CNTL__RESERVED_MASK 0xfffffffe\n#define RLC_SPM_INT_CNTL__RESERVED__SHIFT 0x1\n#define RLC_SPM_INT_STATUS__RLC_SPM_INT_STATUS_MASK 0x1\n#define RLC_SPM_INT_STATUS__RLC_SPM_INT_STATUS__SHIFT 0x0\n#define RLC_SPM_INT_STATUS__RESERVED_MASK 0xfffffffe\n#define RLC_SPM_INT_STATUS__RESERVED__SHIFT 0x1\n#define RLC_SPM_DEBUG_SELECT__SELECT_MASK 0xff\n#define RLC_SPM_DEBUG_SELECT__SELECT__SHIFT 0x0\n#define RLC_SPM_DEBUG_SELECT__RESERVED_MASK 0x7f00\n#define RLC_SPM_DEBUG_SELECT__RESERVED__SHIFT 0x8\n#define RLC_SPM_DEBUG_SELECT__RLC_SPM_DEBUG_MODE_MASK 0x8000\n#define RLC_SPM_DEBUG_SELECT__RLC_SPM_DEBUG_MODE__SHIFT 0xf\n#define RLC_SPM_DEBUG_SELECT__RLC_SPM_NUM_SAMPLE_MASK 0xffff0000\n#define RLC_SPM_DEBUG_SELECT__RLC_SPM_NUM_SAMPLE__SHIFT 0x10\n#define RLC_SPM_DEBUG__DATA_MASK 0xffffffff\n#define RLC_SPM_DEBUG__DATA__SHIFT 0x0\n#define RLC_GPM_LOG_ADDR__ADDR_MASK 0xffffffff\n#define RLC_GPM_LOG_ADDR__ADDR__SHIFT 0x0\n#define RLC_GPM_LOG_SIZE__SIZE_MASK 0xffffffff\n#define RLC_GPM_LOG_SIZE__SIZE__SHIFT 0x0\n#define RLC_GPM_LOG_CONT__CONT_MASK 0xffffffff\n#define RLC_GPM_LOG_CONT__CONT__SHIFT 0x0\n#define RLC_SPM_PERFMON_CNTL__RESERVED1_MASK 0xfff\n#define RLC_SPM_PERFMON_CNTL__RESERVED1__SHIFT 0x0\n#define RLC_SPM_PERFMON_CNTL__PERFMON_RING_MODE_MASK 0x3000\n#define RLC_SPM_PERFMON_CNTL__PERFMON_RING_MODE__SHIFT 0xc\n#define RLC_SPM_PERFMON_CNTL__RESERVED_MASK 0xc000\n#define RLC_SPM_PERFMON_CNTL__RESERVED__SHIFT 0xe\n#define RLC_SPM_PERFMON_CNTL__PERFMON_SAMPLE_INTERVAL_MASK 0xffff0000\n#define RLC_SPM_PERFMON_CNTL__PERFMON_SAMPLE_INTERVAL__SHIFT 0x10\n#define RLC_SPM_PERFMON_RING_BASE_LO__RING_BASE_LO_MASK 0xffffffff\n#define RLC_SPM_PERFMON_RING_BASE_LO__RING_BASE_LO__SHIFT 0x0\n#define RLC_SPM_PERFMON_RING_BASE_HI__RING_BASE_HI_MASK 0xffff\n#define RLC_SPM_PERFMON_RING_BASE_HI__RING_BASE_HI__SHIFT 0x0\n#define RLC_SPM_PERFMON_RING_BASE_HI__RESERVED_MASK 0xffff0000\n#define RLC_SPM_PERFMON_RING_BASE_HI__RESERVED__SHIFT 0x10\n#define RLC_SPM_PERFMON_RING_SIZE__RING_BASE_SIZE_MASK 0xffffffff\n#define RLC_SPM_PERFMON_RING_SIZE__RING_BASE_SIZE__SHIFT 0x0\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__PERFMON_SEGMENT_SIZE_MASK 0xff\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__PERFMON_SEGMENT_SIZE__SHIFT 0x0\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__RESERVED1_MASK 0x700\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__RESERVED1__SHIFT 0x8\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__GLOBAL_NUM_LINE_MASK 0xf800\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__GLOBAL_NUM_LINE__SHIFT 0xb\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE0_NUM_LINE_MASK 0x1f0000\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE0_NUM_LINE__SHIFT 0x10\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE1_NUM_LINE_MASK 0x3e00000\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE1_NUM_LINE__SHIFT 0x15\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE2_NUM_LINE_MASK 0x7c000000\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__SE2_NUM_LINE__SHIFT 0x1a\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__RESERVED_MASK 0x80000000\n#define RLC_SPM_PERFMON_SEGMENT_SIZE__RESERVED__SHIFT 0x1f\n#define RLC_SPM_SE_MUXSEL_ADDR__PERFMON_SEL_ADDR_MASK 0xffffffff\n#define RLC_SPM_SE_MUXSEL_ADDR__PERFMON_SEL_ADDR__SHIFT 0x0\n#define RLC_SPM_SE_MUXSEL_DATA__PERFMON_SEL_DATA_MASK 0xffffffff\n#define RLC_SPM_SE_MUXSEL_DATA__PERFMON_SEL_DATA__SHIFT 0x0\n#define RLC_SPM_CPG_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CPG_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CPG_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CPG_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_CPC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CPC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CPC_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CPC_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_CPF_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CPF_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CPF_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CPF_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_CB_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CB_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CB_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CB_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_DB_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_DB_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_DB_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_DB_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_PA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_PA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_PA_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_PA_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_GDS_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_GDS_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_GDS_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_GDS_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_IA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_IA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_IA_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_IA_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_SC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_SC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_SC_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_SC_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TCC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TCC_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TCC_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TCC_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TCA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TCA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TCA_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TCA_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TCP_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TCP_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TCP_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TCP_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TA_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TA_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TA_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TD_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TD_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TD_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TD_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_VGT_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_VGT_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_VGT_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_VGT_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_SPI_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_SPI_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_SPI_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_SPI_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_SQG_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_SQG_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_SQG_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_SQG_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_TCS_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_TCS_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_TCS_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_TCS_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_SX_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_SX_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_SX_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_SX_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_GLOBAL_MUXSEL_ADDR__PERFMON_SEL_ADDR_MASK 0xffffffff\n#define RLC_SPM_GLOBAL_MUXSEL_ADDR__PERFMON_SEL_ADDR__SHIFT 0x0\n#define RLC_SPM_GLOBAL_MUXSEL_DATA__PERFMON_SEL_DATA_MASK 0xffffffff\n#define RLC_SPM_GLOBAL_MUXSEL_DATA__PERFMON_SEL_DATA__SHIFT 0x0\n#define RLC_SPM_RING_RDPTR__PERFMON_RING_RDPTR_MASK 0xffffffff\n#define RLC_SPM_RING_RDPTR__PERFMON_RING_RDPTR__SHIFT 0x0\n#define RLC_SPM_SEGMENT_THRESHOLD__NUM_SEGMENT_THRESHOLD_MASK 0xffffffff\n#define RLC_SPM_SEGMENT_THRESHOLD__NUM_SEGMENT_THRESHOLD__SHIFT 0x0\n#define RLC_SPM_DBR0_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_DBR0_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_DBR0_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_DBR0_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_DBR1_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_DBR1_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_DBR1_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_DBR1_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_CBR0_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CBR0_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CBR0_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CBR0_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define RLC_SPM_CBR1_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY_MASK 0xff\n#define RLC_SPM_CBR1_PERFMON_SAMPLE_DELAY__PERFMON_SAMPLE_DELAY__SHIFT 0x0\n#define RLC_SPM_CBR1_PERFMON_SAMPLE_DELAY__RESERVED_MASK 0xffffff00\n#define RLC_SPM_CBR1_PERFMON_SAMPLE_DELAY__RESERVED__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_0__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_0__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_0__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_0__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_0__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_0__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_0__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_0__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_0__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_0__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_0__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_0__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_1__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_1__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_1__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_1__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_1__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_1__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_1__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_1__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_1__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_1__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_1__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_1__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_2__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_2__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_2__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_2__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_2__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_2__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_2__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_2__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_2__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_2__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_2__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_2__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_3__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_3__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_3__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_3__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_3__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_3__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_3__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_3__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_3__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_3__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_3__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_3__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_4__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_4__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_4__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_4__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_4__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_4__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_4__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_4__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_4__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_4__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_4__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_4__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_5__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_5__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_5__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_5__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_5__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_5__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_5__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_5__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_5__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_5__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_5__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_5__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_6__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_6__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_6__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_6__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_6__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_6__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_6__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_6__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_6__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_6__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_6__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_6__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_7__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_7__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_7__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_7__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_7__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_7__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_7__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_7__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_7__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_7__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_7__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_7__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_8__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_8__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_8__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_8__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_8__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_8__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_8__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_8__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_8__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_8__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_8__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_8__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_9__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_9__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_9__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_9__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_9__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_9__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_9__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_9__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_9__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_9__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_9__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_9__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_10__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_10__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_10__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_10__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_10__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_10__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_10__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_10__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_10__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_10__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_10__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_10__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_11__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_11__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_11__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_11__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_11__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_11__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_11__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_11__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_11__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_11__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_11__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_11__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_12__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_12__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_12__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_12__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_12__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_12__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_12__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_12__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_12__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_12__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_12__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_12__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_13__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_13__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_13__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_13__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_13__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_13__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_13__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_13__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_13__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_13__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_13__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_13__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_14__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_14__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_14__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_14__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_14__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_14__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_14__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_14__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_14__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_14__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_14__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_14__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_15__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_15__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_15__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_15__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_15__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_15__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_15__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_15__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_15__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_15__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_15__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_15__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_16__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_16__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_16__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_16__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_16__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_16__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_16__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_16__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_16__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_16__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_16__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_16__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_17__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_17__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_17__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_17__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_17__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_17__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_17__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_17__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_17__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_17__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_17__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_17__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_18__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_18__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_18__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_18__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_18__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_18__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_18__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_18__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_18__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_18__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_18__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_18__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_19__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_19__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_19__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_19__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_19__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_19__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_19__CYL_WRAP_MASK 0x1e000\n#define SPI_PS_INPUT_CNTL_19__CYL_WRAP__SHIFT 0xd\n#define SPI_PS_INPUT_CNTL_19__PT_SPRITE_TEX_MASK 0x20000\n#define SPI_PS_INPUT_CNTL_19__PT_SPRITE_TEX__SHIFT 0x11\n#define SPI_PS_INPUT_CNTL_19__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_19__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_20__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_20__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_20__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_20__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_20__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_20__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_20__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_20__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_21__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_21__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_21__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_21__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_21__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_21__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_21__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_21__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_22__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_22__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_22__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_22__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_22__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_22__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_22__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_22__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_23__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_23__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_23__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_23__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_23__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_23__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_23__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_23__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_24__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_24__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_24__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_24__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_24__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_24__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_24__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_24__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_25__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_25__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_25__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_25__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_25__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_25__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_25__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_25__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_26__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_26__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_26__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_26__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_26__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_26__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_26__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_26__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_27__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_27__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_27__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_27__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_27__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_27__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_27__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_27__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_28__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_28__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_28__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_28__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_28__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_28__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_28__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_28__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_29__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_29__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_29__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_29__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_29__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_29__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_29__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_29__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_30__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_30__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_30__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_30__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_30__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_30__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_30__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_30__DUP__SHIFT 0x12\n#define SPI_PS_INPUT_CNTL_31__OFFSET_MASK 0x3f\n#define SPI_PS_INPUT_CNTL_31__OFFSET__SHIFT 0x0\n#define SPI_PS_INPUT_CNTL_31__DEFAULT_VAL_MASK 0x300\n#define SPI_PS_INPUT_CNTL_31__DEFAULT_VAL__SHIFT 0x8\n#define SPI_PS_INPUT_CNTL_31__FLAT_SHADE_MASK 0x400\n#define SPI_PS_INPUT_CNTL_31__FLAT_SHADE__SHIFT 0xa\n#define SPI_PS_INPUT_CNTL_31__DUP_MASK 0x40000\n#define SPI_PS_INPUT_CNTL_31__DUP__SHIFT 0x12\n#define SPI_VS_OUT_CONFIG__VS_EXPORT_COUNT_MASK 0x3e\n#define SPI_VS_OUT_CONFIG__VS_EXPORT_COUNT__SHIFT 0x1\n#define SPI_VS_OUT_CONFIG__VS_HALF_PACK_MASK 0x40\n#define SPI_VS_OUT_CONFIG__VS_HALF_PACK__SHIFT 0x6\n#define SPI_PS_INPUT_ENA__PERSP_SAMPLE_ENA_MASK 0x1\n#define SPI_PS_INPUT_ENA__PERSP_SAMPLE_ENA__SHIFT 0x0\n#define SPI_PS_INPUT_ENA__PERSP_CENTER_ENA_MASK 0x2\n#define SPI_PS_INPUT_ENA__PERSP_CENTER_ENA__SHIFT 0x1\n#define SPI_PS_INPUT_ENA__PERSP_CENTROID_ENA_MASK 0x4\n#define SPI_PS_INPUT_ENA__PERSP_CENTROID_ENA__SHIFT 0x2\n#define SPI_PS_INPUT_ENA__PERSP_PULL_MODEL_ENA_MASK 0x8\n#define SPI_PS_INPUT_ENA__PERSP_PULL_MODEL_ENA__SHIFT 0x3\n#define SPI_PS_INPUT_ENA__LINEAR_SAMPLE_ENA_MASK 0x10\n#define SPI_PS_INPUT_ENA__LINEAR_SAMPLE_ENA__SHIFT 0x4\n#define SPI_PS_INPUT_ENA__LINEAR_CENTER_ENA_MASK 0x20\n#define SPI_PS_INPUT_ENA__LINEAR_CENTER_ENA__SHIFT 0x5\n#define SPI_PS_INPUT_ENA__LINEAR_CENTROID_ENA_MASK 0x40\n#define SPI_PS_INPUT_ENA__LINEAR_CENTROID_ENA__SHIFT 0x6\n#define SPI_PS_INPUT_ENA__LINE_STIPPLE_TEX_ENA_MASK 0x80\n#define SPI_PS_INPUT_ENA__LINE_STIPPLE_TEX_ENA__SHIFT 0x7\n#define SPI_PS_INPUT_ENA__POS_X_FLOAT_ENA_MASK 0x100\n#define SPI_PS_INPUT_ENA__POS_X_FLOAT_ENA__SHIFT 0x8\n#define SPI_PS_INPUT_ENA__POS_Y_FLOAT_ENA_MASK 0x200\n#define SPI_PS_INPUT_ENA__POS_Y_FLOAT_ENA__SHIFT 0x9\n#define SPI_PS_INPUT_ENA__POS_Z_FLOAT_ENA_MASK 0x400\n#define SPI_PS_INPUT_ENA__POS_Z_FLOAT_ENA__SHIFT 0xa\n#define SPI_PS_INPUT_ENA__POS_W_FLOAT_ENA_MASK 0x800\n#define SPI_PS_INPUT_ENA__POS_W_FLOAT_ENA__SHIFT 0xb\n#define SPI_PS_INPUT_ENA__FRONT_FACE_ENA_MASK 0x1000\n#define SPI_PS_INPUT_ENA__FRONT_FACE_ENA__SHIFT 0xc\n#define SPI_PS_INPUT_ENA__ANCILLARY_ENA_MASK 0x2000\n#define SPI_PS_INPUT_ENA__ANCILLARY_ENA__SHIFT 0xd\n#define SPI_PS_INPUT_ENA__SAMPLE_COVERAGE_ENA_MASK 0x4000\n#define SPI_PS_INPUT_ENA__SAMPLE_COVERAGE_ENA__SHIFT 0xe\n#define SPI_PS_INPUT_ENA__POS_FIXED_PT_ENA_MASK 0x8000\n#define SPI_PS_INPUT_ENA__POS_FIXED_PT_ENA__SHIFT 0xf\n#define SPI_PS_INPUT_ADDR__PERSP_SAMPLE_ENA_MASK 0x1\n#define SPI_PS_INPUT_ADDR__PERSP_SAMPLE_ENA__SHIFT 0x0\n#define SPI_PS_INPUT_ADDR__PERSP_CENTER_ENA_MASK 0x2\n#define SPI_PS_INPUT_ADDR__PERSP_CENTER_ENA__SHIFT 0x1\n#define SPI_PS_INPUT_ADDR__PERSP_CENTROID_ENA_MASK 0x4\n#define SPI_PS_INPUT_ADDR__PERSP_CENTROID_ENA__SHIFT 0x2\n#define SPI_PS_INPUT_ADDR__PERSP_PULL_MODEL_ENA_MASK 0x8\n#define SPI_PS_INPUT_ADDR__PERSP_PULL_MODEL_ENA__SHIFT 0x3\n#define SPI_PS_INPUT_ADDR__LINEAR_SAMPLE_ENA_MASK 0x10\n#define SPI_PS_INPUT_ADDR__LINEAR_SAMPLE_ENA__SHIFT 0x4\n#define SPI_PS_INPUT_ADDR__LINEAR_CENTER_ENA_MASK 0x20\n#define SPI_PS_INPUT_ADDR__LINEAR_CENTER_ENA__SHIFT 0x5\n#define SPI_PS_INPUT_ADDR__LINEAR_CENTROID_ENA_MASK 0x40\n#define SPI_PS_INPUT_ADDR__LINEAR_CENTROID_ENA__SHIFT 0x6\n#define SPI_PS_INPUT_ADDR__LINE_STIPPLE_TEX_ENA_MASK 0x80\n#define SPI_PS_INPUT_ADDR__LINE_STIPPLE_TEX_ENA__SHIFT 0x7\n#define SPI_PS_INPUT_ADDR__POS_X_FLOAT_ENA_MASK 0x100\n#define SPI_PS_INPUT_ADDR__POS_X_FLOAT_ENA__SHIFT 0x8\n#define SPI_PS_INPUT_ADDR__POS_Y_FLOAT_ENA_MASK 0x200\n#define SPI_PS_INPUT_ADDR__POS_Y_FLOAT_ENA__SHIFT 0x9\n#define SPI_PS_INPUT_ADDR__POS_Z_FLOAT_ENA_MASK 0x400\n#define SPI_PS_INPUT_ADDR__POS_Z_FLOAT_ENA__SHIFT 0xa\n#define SPI_PS_INPUT_ADDR__POS_W_FLOAT_ENA_MASK 0x800\n#define SPI_PS_INPUT_ADDR__POS_W_FLOAT_ENA__SHIFT 0xb\n#define SPI_PS_INPUT_ADDR__FRONT_FACE_ENA_MASK 0x1000\n#define SPI_PS_INPUT_ADDR__FRONT_FACE_ENA__SHIFT 0xc\n#define SPI_PS_INPUT_ADDR__ANCILLARY_ENA_MASK 0x2000\n#define SPI_PS_INPUT_ADDR__ANCILLARY_ENA__SHIFT 0xd\n#define SPI_PS_INPUT_ADDR__SAMPLE_COVERAGE_ENA_MASK 0x4000\n#define SPI_PS_INPUT_ADDR__SAMPLE_COVERAGE_ENA__SHIFT 0xe\n#define SPI_PS_INPUT_ADDR__POS_FIXED_PT_ENA_MASK 0x8000\n#define SPI_PS_INPUT_ADDR__POS_FIXED_PT_ENA__SHIFT 0xf\n#define SPI_INTERP_CONTROL_0__FLAT_SHADE_ENA_MASK 0x1\n#define SPI_INTERP_CONTROL_0__FLAT_SHADE_ENA__SHIFT 0x0\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_ENA_MASK 0x2\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_ENA__SHIFT 0x1\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_X_MASK 0x1c\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_X__SHIFT 0x2\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_Y_MASK 0xe0\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_Y__SHIFT 0x5\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_Z_MASK 0x700\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_Z__SHIFT 0x8\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_W_MASK 0x3800\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_OVRD_W__SHIFT 0xb\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_TOP_1_MASK 0x4000\n#define SPI_INTERP_CONTROL_0__PNT_SPRITE_TOP_1__SHIFT 0xe\n#define SPI_PS_IN_CONTROL__NUM_INTERP_MASK 0x3f\n#define SPI_PS_IN_CONTROL__NUM_INTERP__SHIFT 0x0\n#define SPI_PS_IN_CONTROL__PARAM_GEN_MASK 0x40\n#define SPI_PS_IN_CONTROL__PARAM_GEN__SHIFT 0x6\n#define SPI_PS_IN_CONTROL__BC_OPTIMIZE_DISABLE_MASK 0x4000\n#define SPI_PS_IN_CONTROL__BC_OPTIMIZE_DISABLE__SHIFT 0xe\n#define SPI_BARYC_CNTL__PERSP_CENTER_CNTL_MASK 0x1\n#define SPI_BARYC_CNTL__PERSP_CENTER_CNTL__SHIFT 0x0\n#define SPI_BARYC_CNTL__PERSP_CENTROID_CNTL_MASK 0x10\n#define SPI_BARYC_CNTL__PERSP_CENTROID_CNTL__SHIFT 0x4\n#define SPI_BARYC_CNTL__LINEAR_CENTER_CNTL_MASK 0x100\n#define SPI_BARYC_CNTL__LINEAR_CENTER_CNTL__SHIFT 0x8\n#define SPI_BARYC_CNTL__LINEAR_CENTROID_CNTL_MASK 0x1000\n#define SPI_BARYC_CNTL__LINEAR_CENTROID_CNTL__SHIFT 0xc\n#define SPI_BARYC_CNTL__POS_FLOAT_LOCATION_MASK 0x30000\n#define SPI_BARYC_CNTL__POS_FLOAT_LOCATION__SHIFT 0x10\n#define SPI_BARYC_CNTL__POS_FLOAT_ULC_MASK 0x100000\n#define SPI_BARYC_CNTL__POS_FLOAT_ULC__SHIFT 0x14\n#define SPI_BARYC_CNTL__FRONT_FACE_ALL_BITS_MASK 0x1000000\n#define SPI_BARYC_CNTL__FRONT_FACE_ALL_BITS__SHIFT 0x18\n#define SPI_TMPRING_SIZE__WAVES_MASK 0xfff\n#define SPI_TMPRING_SIZE__WAVES__SHIFT 0x0\n#define SPI_TMPRING_SIZE__WAVESIZE_MASK 0x1fff000\n#define SPI_TMPRING_SIZE__WAVESIZE__SHIFT 0xc\n#define SPI_SHADER_POS_FORMAT__POS0_EXPORT_FORMAT_MASK 0xf\n#define SPI_SHADER_POS_FORMAT__POS0_EXPORT_FORMAT__SHIFT 0x0\n#define SPI_SHADER_POS_FORMAT__POS1_EXPORT_FORMAT_MASK 0xf0\n#define SPI_SHADER_POS_FORMAT__POS1_EXPORT_FORMAT__SHIFT 0x4\n#define SPI_SHADER_POS_FORMAT__POS2_EXPORT_FORMAT_MASK 0xf00\n#define SPI_SHADER_POS_FORMAT__POS2_EXPORT_FORMAT__SHIFT 0x8\n#define SPI_SHADER_POS_FORMAT__POS3_EXPORT_FORMAT_MASK 0xf000\n#define SPI_SHADER_POS_FORMAT__POS3_EXPORT_FORMAT__SHIFT 0xc\n#define SPI_SHADER_Z_FORMAT__Z_EXPORT_FORMAT_MASK 0xf\n#define SPI_SHADER_Z_FORMAT__Z_EXPORT_FORMAT__SHIFT 0x0\n#define SPI_SHADER_COL_FORMAT__COL0_EXPORT_FORMAT_MASK 0xf\n#define SPI_SHADER_COL_FORMAT__COL0_EXPORT_FORMAT__SHIFT 0x0\n#define SPI_SHADER_COL_FORMAT__COL1_EXPORT_FORMAT_MASK 0xf0\n#define SPI_SHADER_COL_FORMAT__COL1_EXPORT_FORMAT__SHIFT 0x4\n#define SPI_SHADER_COL_FORMAT__COL2_EXPORT_FORMAT_MASK 0xf00\n#define SPI_SHADER_COL_FORMAT__COL2_EXPORT_FORMAT__SHIFT 0x8\n#define SPI_SHADER_COL_FORMAT__COL3_EXPORT_FORMAT_MASK 0xf000\n#define SPI_SHADER_COL_FORMAT__COL3_EXPORT_FORMAT__SHIFT 0xc\n#define SPI_SHADER_COL_FORMAT__COL4_EXPORT_FORMAT_MASK 0xf0000\n#define SPI_SHADER_COL_FORMAT__COL4_EXPORT_FORMAT__SHIFT 0x10\n#define SPI_SHADER_COL_FORMAT__COL5_EXPORT_FORMAT_MASK 0xf00000\n#define SPI_SHADER_COL_FORMAT__COL5_EXPORT_FORMAT__SHIFT 0x14\n#define SPI_SHADER_COL_FORMAT__COL6_EXPORT_FORMAT_MASK 0xf000000\n#define SPI_SHADER_COL_FORMAT__COL6_EXPORT_FORMAT__SHIFT 0x18\n#define SPI_SHADER_COL_FORMAT__COL7_EXPORT_FORMAT_MASK 0xf0000000\n#define SPI_SHADER_COL_FORMAT__COL7_EXPORT_FORMAT__SHIFT 0x1c\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS0_MASK 0x7\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS0__SHIFT 0x0\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS1_MASK 0x38\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS1__SHIFT 0x3\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS2_MASK 0x1c0\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS2__SHIFT 0x6\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS3_MASK 0xe00\n#define SPI_ARB_PRIORITY__PIPE_ORDER_TS3__SHIFT 0x9\n#define SPI_ARB_PRIORITY__TS0_DUR_MULT_MASK 0x3000\n#define SPI_ARB_PRIORITY__TS0_DUR_MULT__SHIFT 0xc\n#define SPI_ARB_PRIORITY__TS1_DUR_MULT_MASK 0xc000\n#define SPI_ARB_PRIORITY__TS1_DUR_MULT__SHIFT 0xe\n#define SPI_ARB_PRIORITY__TS2_DUR_MULT_MASK 0x30000\n#define SPI_ARB_PRIORITY__TS2_DUR_MULT__SHIFT 0x10\n#define SPI_ARB_PRIORITY__TS3_DUR_MULT_MASK 0xc0000\n#define SPI_ARB_PRIORITY__TS3_DUR_MULT__SHIFT 0x12\n#define SPI_ARB_CYCLES_0__TS0_DURATION_MASK 0xffff\n#define SPI_ARB_CYCLES_0__TS0_DURATION__SHIFT 0x0\n#define SPI_ARB_CYCLES_0__TS1_DURATION_MASK 0xffff0000\n#define SPI_ARB_CYCLES_0__TS1_DURATION__SHIFT 0x10\n#define SPI_ARB_CYCLES_1__TS2_DURATION_MASK 0xffff\n#define SPI_ARB_CYCLES_1__TS2_DURATION__SHIFT 0x0\n#define SPI_ARB_CYCLES_1__TS3_DURATION_MASK 0xffff0000\n#define SPI_ARB_CYCLES_1__TS3_DURATION__SHIFT 0x10\n#define SPI_CDBG_SYS_GFX__PS_EN_MASK 0x1\n#define SPI_CDBG_SYS_GFX__PS_EN__SHIFT 0x0\n#define SPI_CDBG_SYS_GFX__VS_EN_MASK 0x2\n#define SPI_CDBG_SYS_GFX__VS_EN__SHIFT 0x1\n#define SPI_CDBG_SYS_GFX__GS_EN_MASK 0x4\n#define SPI_CDBG_SYS_GFX__GS_EN__SHIFT 0x2\n#define SPI_CDBG_SYS_GFX__ES_EN_MASK 0x8\n#define SPI_CDBG_SYS_GFX__ES_EN__SHIFT 0x3\n#define SPI_CDBG_SYS_GFX__HS_EN_MASK 0x10\n#define SPI_CDBG_SYS_GFX__HS_EN__SHIFT 0x4\n#define SPI_CDBG_SYS_GFX__LS_EN_MASK 0x20\n#define SPI_CDBG_SYS_GFX__LS_EN__SHIFT 0x5\n#define SPI_CDBG_SYS_GFX__CS_EN_MASK 0x40\n#define SPI_CDBG_SYS_GFX__CS_EN__SHIFT 0x6\n#define SPI_CDBG_SYS_HP3D__PS_EN_MASK 0x1\n#define SPI_CDBG_SYS_HP3D__PS_EN__SHIFT 0x0\n#define SPI_CDBG_SYS_HP3D__VS_EN_MASK 0x2\n#define SPI_CDBG_SYS_HP3D__VS_EN__SHIFT 0x1\n#define SPI_CDBG_SYS_HP3D__GS_EN_MASK 0x4\n#define SPI_CDBG_SYS_HP3D__GS_EN__SHIFT 0x2\n#define SPI_CDBG_SYS_HP3D__ES_EN_MASK 0x8\n#define SPI_CDBG_SYS_HP3D__ES_EN__SHIFT 0x3\n#define SPI_CDBG_SYS_HP3D__HS_EN_MASK 0x10\n#define SPI_CDBG_SYS_HP3D__HS_EN__SHIFT 0x4\n#define SPI_CDBG_SYS_HP3D__LS_EN_MASK 0x20\n#define SPI_CDBG_SYS_HP3D__LS_EN__SHIFT 0x5\n#define SPI_CDBG_SYS_CS0__PIPE0_MASK 0xff\n#define SPI_CDBG_SYS_CS0__PIPE0__SHIFT 0x0\n#define SPI_CDBG_SYS_CS0__PIPE1_MASK 0xff00\n#define SPI_CDBG_SYS_CS0__PIPE1__SHIFT 0x8\n#define SPI_CDBG_SYS_CS0__PIPE2_MASK 0xff0000\n#define SPI_CDBG_SYS_CS0__PIPE2__SHIFT 0x10\n#define SPI_CDBG_SYS_CS0__PIPE3_MASK 0xff000000\n#define SPI_CDBG_SYS_CS0__PIPE3__SHIFT 0x18\n#define SPI_CDBG_SYS_CS1__PIPE0_MASK 0xff\n#define SPI_CDBG_SYS_CS1__PIPE0__SHIFT 0x0\n#define SPI_CDBG_SYS_CS1__PIPE1_MASK 0xff00\n#define SPI_CDBG_SYS_CS1__PIPE1__SHIFT 0x8\n#define SPI_CDBG_SYS_CS1__PIPE2_MASK 0xff0000\n#define SPI_CDBG_SYS_CS1__PIPE2__SHIFT 0x10\n#define SPI_CDBG_SYS_CS1__PIPE3_MASK 0xff000000\n#define SPI_CDBG_SYS_CS1__PIPE3__SHIFT 0x18\n#define SPI_WCL_PIPE_PERCENT_GFX__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_GFX__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_HP3D__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_HP3D__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS0__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS0__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS1__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS1__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS2__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS2__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS3__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS3__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS4__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS4__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS5__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS5__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS6__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS6__VALUE__SHIFT 0x0\n#define SPI_WCL_PIPE_PERCENT_CS7__VALUE_MASK 0x1f\n#define SPI_WCL_PIPE_PERCENT_CS7__VALUE__SHIFT 0x0\n#define SPI_GDBG_WAVE_CNTL__STALL_RA_MASK 0x1\n#define SPI_GDBG_WAVE_CNTL__STALL_RA__SHIFT 0x0\n#define SPI_GDBG_TRAP_CONFIG__ME_SEL_MASK 0x3\n#define SPI_GDBG_TRAP_CONFIG__ME_SEL__SHIFT 0x0\n#define SPI_GDBG_TRAP_CONFIG__PIPE_SEL_MASK 0xc\n#define SPI_GDBG_TRAP_CONFIG__PIPE_SEL__SHIFT 0x2\n#define SPI_GDBG_TRAP_CONFIG__QUEUE_SEL_MASK 0x70\n#define SPI_GDBG_TRAP_CONFIG__QUEUE_SEL__SHIFT 0x4\n#define SPI_GDBG_TRAP_CONFIG__ME_MATCH_MASK 0x80\n#define SPI_GDBG_TRAP_CONFIG__ME_MATCH__SHIFT 0x7\n#define SPI_GDBG_TRAP_CONFIG__PIPE_MATCH_MASK 0x100\n#define SPI_GDBG_TRAP_CONFIG__PIPE_MATCH__SHIFT 0x8\n#define SPI_GDBG_TRAP_CONFIG__QUEUE_MATCH_MASK 0x200\n#define SPI_GDBG_TRAP_CONFIG__QUEUE_MATCH__SHIFT 0x9\n#define SPI_GDBG_TRAP_CONFIG__TRAP_EN_MASK 0x8000\n#define SPI_GDBG_TRAP_CONFIG__TRAP_EN__SHIFT 0xf\n#define SPI_GDBG_TRAP_CONFIG__VMID_SEL_MASK 0xffff0000\n#define SPI_GDBG_TRAP_CONFIG__VMID_SEL__SHIFT 0x10\n#define SPI_GDBG_TRAP_MASK__EXCP_EN_MASK 0x1ff\n#define SPI_GDBG_TRAP_MASK__EXCP_EN__SHIFT 0x0\n#define SPI_GDBG_TRAP_MASK__REPLACE_MASK 0x200\n#define SPI_GDBG_TRAP_MASK__REPLACE__SHIFT 0x9\n#define SPI_GDBG_TBA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_GDBG_TBA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_GDBG_TBA_HI__MEM_BASE_MASK 0xff\n#define SPI_GDBG_TBA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_GDBG_TMA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_GDBG_TMA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_GDBG_TMA_HI__MEM_BASE_MASK 0xff\n#define SPI_GDBG_TMA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_GDBG_TRAP_DATA0__DATA_MASK 0xffffffff\n#define SPI_GDBG_TRAP_DATA0__DATA__SHIFT 0x0\n#define SPI_GDBG_TRAP_DATA1__DATA_MASK 0xffffffff\n#define SPI_GDBG_TRAP_DATA1__DATA__SHIFT 0x0\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_MASK 0x1\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET__SHIFT 0x0\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_PER_VMID_MASK 0x2\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_PER_VMID__SHIFT 0x1\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_ALL_VMID_MASK 0x4\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_ALL_VMID__SHIFT 0x2\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_RESOURCE_MASK 0x8\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_RESOURCE__SHIFT 0x3\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_PRIORITY_MASK 0x10\n#define SPI_RESET_DEBUG__DISABLE_GFX_RESET_PRIORITY__SHIFT 0x4\n#define SPI_COMPUTE_QUEUE_RESET__RESET_MASK 0x1\n#define SPI_COMPUTE_QUEUE_RESET__RESET__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_0__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_0__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_0__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_0__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_0__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_0__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_0__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_0__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_0__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_0__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_1__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_1__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_1__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_1__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_1__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_1__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_1__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_1__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_1__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_1__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_2__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_2__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_2__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_2__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_2__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_2__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_2__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_2__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_2__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_2__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_3__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_3__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_3__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_3__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_3__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_3__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_3__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_3__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_3__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_3__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_4__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_4__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_4__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_4__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_4__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_4__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_4__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_4__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_4__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_4__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_5__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_5__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_5__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_5__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_5__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_5__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_5__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_5__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_5__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_5__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_6__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_6__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_6__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_6__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_6__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_6__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_6__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_6__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_6__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_6__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_7__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_7__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_7__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_7__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_7__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_7__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_7__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_7__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_7__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_7__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_8__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_8__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_8__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_8__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_8__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_8__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_8__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_8__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_8__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_8__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_9__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_9__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_9__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_9__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_9__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_9__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_9__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_9__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_9__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_9__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_10__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_10__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_10__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_10__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_10__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_10__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_10__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_10__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_10__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_10__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_CU_11__VGPR_MASK 0xf\n#define SPI_RESOURCE_RESERVE_CU_11__VGPR__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_CU_11__SGPR_MASK 0xf0\n#define SPI_RESOURCE_RESERVE_CU_11__SGPR__SHIFT 0x4\n#define SPI_RESOURCE_RESERVE_CU_11__LDS_MASK 0xf00\n#define SPI_RESOURCE_RESERVE_CU_11__LDS__SHIFT 0x8\n#define SPI_RESOURCE_RESERVE_CU_11__WAVES_MASK 0x7000\n#define SPI_RESOURCE_RESERVE_CU_11__WAVES__SHIFT 0xc\n#define SPI_RESOURCE_RESERVE_CU_11__BARRIERS_MASK 0x78000\n#define SPI_RESOURCE_RESERVE_CU_11__BARRIERS__SHIFT 0xf\n#define SPI_RESOURCE_RESERVE_EN_CU_0__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_0__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_0__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_0__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_0__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_0__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_0__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_0__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_1__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_1__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_1__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_1__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_1__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_1__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_1__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_1__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_2__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_2__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_2__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_2__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_2__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_2__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_2__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_2__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_3__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_3__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_3__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_3__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_3__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_3__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_3__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_3__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_4__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_4__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_4__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_4__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_4__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_4__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_4__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_4__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_5__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_5__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_5__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_5__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_5__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_5__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_5__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_5__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_6__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_6__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_6__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_6__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_6__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_6__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_6__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_6__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_7__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_7__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_7__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_7__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_7__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_7__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_7__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_7__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_8__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_8__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_8__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_8__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_8__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_8__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_8__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_8__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_9__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_9__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_9__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_9__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_9__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_9__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_9__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_9__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_10__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_10__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_10__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_10__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_10__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_10__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_10__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_10__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_RESOURCE_RESERVE_EN_CU_11__EN_MASK 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_11__EN__SHIFT 0x0\n#define SPI_RESOURCE_RESERVE_EN_CU_11__TYPE_MASK_MASK 0xfffe\n#define SPI_RESOURCE_RESERVE_EN_CU_11__TYPE_MASK__SHIFT 0x1\n#define SPI_RESOURCE_RESERVE_EN_CU_11__QUEUE_MASK_MASK 0xff0000\n#define SPI_RESOURCE_RESERVE_EN_CU_11__QUEUE_MASK__SHIFT 0x10\n#define SPI_RESOURCE_RESERVE_EN_CU_11__RESERVE_SPACE_ONLY_MASK 0x1000000\n#define SPI_RESOURCE_RESERVE_EN_CU_11__RESERVE_SPACE_ONLY__SHIFT 0x18\n#define SPI_PS_MAX_WAVE_ID__MAX_WAVE_ID_MASK 0xfff\n#define SPI_PS_MAX_WAVE_ID__MAX_WAVE_ID__SHIFT 0x0\n#define SPI_CONFIG_CNTL__GPR_WRITE_PRIORITY_MASK 0x1fffff\n#define SPI_CONFIG_CNTL__GPR_WRITE_PRIORITY__SHIFT 0x0\n#define SPI_CONFIG_CNTL__EXP_PRIORITY_ORDER_MASK 0xe00000\n#define SPI_CONFIG_CNTL__EXP_PRIORITY_ORDER__SHIFT 0x15\n#define SPI_CONFIG_CNTL__ENABLE_SQG_TOP_EVENTS_MASK 0x1000000\n#define SPI_CONFIG_CNTL__ENABLE_SQG_TOP_EVENTS__SHIFT 0x18\n#define SPI_CONFIG_CNTL__ENABLE_SQG_BOP_EVENTS_MASK 0x2000000\n#define SPI_CONFIG_CNTL__ENABLE_SQG_BOP_EVENTS__SHIFT 0x19\n#define SPI_CONFIG_CNTL__RSRC_MGMT_RESET_MASK 0x4000000\n#define SPI_CONFIG_CNTL__RSRC_MGMT_RESET__SHIFT 0x1a\n#define SPI_CONFIG_CNTL__TTRACE_STALL_ALL_MASK 0x8000000\n#define SPI_CONFIG_CNTL__TTRACE_STALL_ALL__SHIFT 0x1b\n#define SPI_DEBUG_CNTL__DEBUG_GRBM_OVERRIDE_MASK 0x1\n#define SPI_DEBUG_CNTL__DEBUG_GRBM_OVERRIDE__SHIFT 0x0\n#define SPI_DEBUG_CNTL__DEBUG_THREAD_TYPE_SEL_MASK 0xe\n#define SPI_DEBUG_CNTL__DEBUG_THREAD_TYPE_SEL__SHIFT 0x1\n#define SPI_DEBUG_CNTL__DEBUG_GROUP_SEL_MASK 0x3f0\n#define SPI_DEBUG_CNTL__DEBUG_GROUP_SEL__SHIFT 0x4\n#define SPI_DEBUG_CNTL__DEBUG_SIMD_SEL_MASK 0xfc00\n#define SPI_DEBUG_CNTL__DEBUG_SIMD_SEL__SHIFT 0xa\n#define SPI_DEBUG_CNTL__DEBUG_SH_SEL_MASK 0x10000\n#define SPI_DEBUG_CNTL__DEBUG_SH_SEL__SHIFT 0x10\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_0_MASK 0x20000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_0__SHIFT 0x11\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_1_MASK 0x40000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_1__SHIFT 0x12\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_2_MASK 0x80000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_2__SHIFT 0x13\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_3_MASK 0x100000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_3__SHIFT 0x14\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_4_MASK 0x200000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_4__SHIFT 0x15\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_5_MASK 0x400000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_5__SHIFT 0x16\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_6_MASK 0x800000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_6__SHIFT 0x17\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_7_MASK 0x1000000\n#define SPI_DEBUG_CNTL__SPI_ECO_SPARE_7__SHIFT 0x18\n#define SPI_DEBUG_CNTL__DEBUG_PIPE_SEL_MASK 0xe000000\n#define SPI_DEBUG_CNTL__DEBUG_PIPE_SEL__SHIFT 0x19\n#define SPI_DEBUG_CNTL__DEBUG_REG_EN_MASK 0x80000000\n#define SPI_DEBUG_CNTL__DEBUG_REG_EN__SHIFT 0x1f\n#define SPI_DEBUG_READ__DATA_MASK 0xffffff\n#define SPI_DEBUG_READ__DATA__SHIFT 0x0\n#define SPI_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define SPI_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define SPI_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define SPI_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define SPI_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define SPI_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define SPI_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define SPI_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define SPI_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define SPI_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define SPI_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define SPI_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER2_SELECT__PERF_SEL1_MASK 0xffc00\n#define SPI_PERFCOUNTER2_SELECT__PERF_SEL1__SHIFT 0xa\n#define SPI_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define SPI_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define SPI_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define SPI_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER3_SELECT__PERF_SEL1_MASK 0xffc00\n#define SPI_PERFCOUNTER3_SELECT__PERF_SEL1__SHIFT 0xa\n#define SPI_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define SPI_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define SPI_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define SPI_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define SPI_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define SPI_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define SPI_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define SPI_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define SPI_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define SPI_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define SPI_PERFCOUNTER2_SELECT1__PERF_SEL2_MASK 0x3ff\n#define SPI_PERFCOUNTER2_SELECT1__PERF_SEL2__SHIFT 0x0\n#define SPI_PERFCOUNTER2_SELECT1__PERF_SEL3_MASK 0xffc00\n#define SPI_PERFCOUNTER2_SELECT1__PERF_SEL3__SHIFT 0xa\n#define SPI_PERFCOUNTER3_SELECT1__PERF_SEL2_MASK 0x3ff\n#define SPI_PERFCOUNTER3_SELECT1__PERF_SEL2__SHIFT 0x0\n#define SPI_PERFCOUNTER3_SELECT1__PERF_SEL3_MASK 0xffc00\n#define SPI_PERFCOUNTER3_SELECT1__PERF_SEL3__SHIFT 0xa\n#define SPI_PERFCOUNTER4_SELECT__PERF_SEL_MASK 0xff\n#define SPI_PERFCOUNTER4_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER5_SELECT__PERF_SEL_MASK 0xff\n#define SPI_PERFCOUNTER5_SELECT__PERF_SEL__SHIFT 0x0\n#define SPI_PERFCOUNTER_BINS__BIN0_MIN_MASK 0xf\n#define SPI_PERFCOUNTER_BINS__BIN0_MIN__SHIFT 0x0\n#define SPI_PERFCOUNTER_BINS__BIN0_MAX_MASK 0xf0\n#define SPI_PERFCOUNTER_BINS__BIN0_MAX__SHIFT 0x4\n#define SPI_PERFCOUNTER_BINS__BIN1_MIN_MASK 0xf00\n#define SPI_PERFCOUNTER_BINS__BIN1_MIN__SHIFT 0x8\n#define SPI_PERFCOUNTER_BINS__BIN1_MAX_MASK 0xf000\n#define SPI_PERFCOUNTER_BINS__BIN1_MAX__SHIFT 0xc\n#define SPI_PERFCOUNTER_BINS__BIN2_MIN_MASK 0xf0000\n#define SPI_PERFCOUNTER_BINS__BIN2_MIN__SHIFT 0x10\n#define SPI_PERFCOUNTER_BINS__BIN2_MAX_MASK 0xf00000\n#define SPI_PERFCOUNTER_BINS__BIN2_MAX__SHIFT 0x14\n#define SPI_PERFCOUNTER_BINS__BIN3_MIN_MASK 0xf000000\n#define SPI_PERFCOUNTER_BINS__BIN3_MIN__SHIFT 0x18\n#define SPI_PERFCOUNTER_BINS__BIN3_MAX_MASK 0xf0000000\n#define SPI_PERFCOUNTER_BINS__BIN3_MAX__SHIFT 0x1c\n#define SPI_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_PERFCOUNTER4_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER4_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER4_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER4_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_PERFCOUNTER5_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SPI_PERFCOUNTER5_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SPI_PERFCOUNTER5_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SPI_PERFCOUNTER5_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SPI_CONFIG_CNTL_1__VTX_DONE_DELAY_MASK 0xf\n#define SPI_CONFIG_CNTL_1__VTX_DONE_DELAY__SHIFT 0x0\n#define SPI_CONFIG_CNTL_1__INTERP_ONE_PRIM_PER_ROW_MASK 0x10\n#define SPI_CONFIG_CNTL_1__INTERP_ONE_PRIM_PER_ROW__SHIFT 0x4\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_ENABLE_MASK 0x40\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_ENABLE__SHIFT 0x6\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_STRICT_MASK 0x80\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_STRICT__SHIFT 0x7\n#define SPI_CONFIG_CNTL_1__CRC_SIMD_ID_WADDR_DISABLE_MASK 0x100\n#define SPI_CONFIG_CNTL_1__CRC_SIMD_ID_WADDR_DISABLE__SHIFT 0x8\n#define SPI_CONFIG_CNTL_1__LBPW_CU_CHK_MODE_MASK 0x200\n#define SPI_CONFIG_CNTL_1__LBPW_CU_CHK_MODE__SHIFT 0x9\n#define SPI_CONFIG_CNTL_1__LBPW_CU_CHK_CNT_MASK 0x3c00\n#define SPI_CONFIG_CNTL_1__LBPW_CU_CHK_CNT__SHIFT 0xa\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_SIZE_MASK 0xffff0000\n#define SPI_CONFIG_CNTL_1__PC_LIMIT_SIZE__SHIFT 0x10\n#define SPI_DEBUG_BUSY__LS_BUSY_MASK 0x1\n#define SPI_DEBUG_BUSY__LS_BUSY__SHIFT 0x0\n#define SPI_DEBUG_BUSY__HS_BUSY_MASK 0x2\n#define SPI_DEBUG_BUSY__HS_BUSY__SHIFT 0x1\n#define SPI_DEBUG_BUSY__ES_BUSY_MASK 0x4\n#define SPI_DEBUG_BUSY__ES_BUSY__SHIFT 0x2\n#define SPI_DEBUG_BUSY__GS_BUSY_MASK 0x8\n#define SPI_DEBUG_BUSY__GS_BUSY__SHIFT 0x3\n#define SPI_DEBUG_BUSY__VS_BUSY_MASK 0x10\n#define SPI_DEBUG_BUSY__VS_BUSY__SHIFT 0x4\n#define SPI_DEBUG_BUSY__PS0_BUSY_MASK 0x20\n#define SPI_DEBUG_BUSY__PS0_BUSY__SHIFT 0x5\n#define SPI_DEBUG_BUSY__PS1_BUSY_MASK 0x40\n#define SPI_DEBUG_BUSY__PS1_BUSY__SHIFT 0x6\n#define SPI_DEBUG_BUSY__CSG_BUSY_MASK 0x80\n#define SPI_DEBUG_BUSY__CSG_BUSY__SHIFT 0x7\n#define SPI_DEBUG_BUSY__CS0_BUSY_MASK 0x100\n#define SPI_DEBUG_BUSY__CS0_BUSY__SHIFT 0x8\n#define SPI_DEBUG_BUSY__CS1_BUSY_MASK 0x200\n#define SPI_DEBUG_BUSY__CS1_BUSY__SHIFT 0x9\n#define SPI_DEBUG_BUSY__CS2_BUSY_MASK 0x400\n#define SPI_DEBUG_BUSY__CS2_BUSY__SHIFT 0xa\n#define SPI_DEBUG_BUSY__CS3_BUSY_MASK 0x800\n#define SPI_DEBUG_BUSY__CS3_BUSY__SHIFT 0xb\n#define SPI_DEBUG_BUSY__CS4_BUSY_MASK 0x1000\n#define SPI_DEBUG_BUSY__CS4_BUSY__SHIFT 0xc\n#define SPI_DEBUG_BUSY__CS5_BUSY_MASK 0x2000\n#define SPI_DEBUG_BUSY__CS5_BUSY__SHIFT 0xd\n#define SPI_DEBUG_BUSY__CS6_BUSY_MASK 0x4000\n#define SPI_DEBUG_BUSY__CS6_BUSY__SHIFT 0xe\n#define SPI_DEBUG_BUSY__CS7_BUSY_MASK 0x8000\n#define SPI_DEBUG_BUSY__CS7_BUSY__SHIFT 0xf\n#define SPI_DEBUG_BUSY__LDS_WR_CTL0_BUSY_MASK 0x10000\n#define SPI_DEBUG_BUSY__LDS_WR_CTL0_BUSY__SHIFT 0x10\n#define SPI_DEBUG_BUSY__LDS_WR_CTL1_BUSY_MASK 0x20000\n#define SPI_DEBUG_BUSY__LDS_WR_CTL1_BUSY__SHIFT 0x11\n#define SPI_DEBUG_BUSY__RSRC_ALLOC0_BUSY_MASK 0x40000\n#define SPI_DEBUG_BUSY__RSRC_ALLOC0_BUSY__SHIFT 0x12\n#define SPI_DEBUG_BUSY__RSRC_ALLOC1_BUSY_MASK 0x80000\n#define SPI_DEBUG_BUSY__RSRC_ALLOC1_BUSY__SHIFT 0x13\n#define SPI_DEBUG_BUSY__PC_DEALLOC_BUSY_MASK 0x100000\n#define SPI_DEBUG_BUSY__PC_DEALLOC_BUSY__SHIFT 0x14\n#define SPI_DEBUG_BUSY__EVENT_CLCTR_BUSY_MASK 0x200000\n#define SPI_DEBUG_BUSY__EVENT_CLCTR_BUSY__SHIFT 0x15\n#define SPI_DEBUG_BUSY__GRBM_BUSY_MASK 0x400000\n#define SPI_DEBUG_BUSY__GRBM_BUSY__SHIFT 0x16\n#define SPI_DEBUG_BUSY__SPIS_BUSY_MASK 0x800000\n#define SPI_DEBUG_BUSY__SPIS_BUSY__SHIFT 0x17\n#define CGTS_SM_CTRL_REG__ON_SEQ_DELAY_MASK 0xf\n#define CGTS_SM_CTRL_REG__ON_SEQ_DELAY__SHIFT 0x0\n#define CGTS_SM_CTRL_REG__OFF_SEQ_DELAY_MASK 0xff0\n#define CGTS_SM_CTRL_REG__OFF_SEQ_DELAY__SHIFT 0x4\n#define CGTS_SM_CTRL_REG__MGCG_ENABLED_MASK 0x1000\n#define CGTS_SM_CTRL_REG__MGCG_ENABLED__SHIFT 0xc\n#define CGTS_SM_CTRL_REG__BASE_MODE_MASK 0x10000\n#define CGTS_SM_CTRL_REG__BASE_MODE__SHIFT 0x10\n#define CGTS_SM_CTRL_REG__SM_MODE_MASK 0xe0000\n#define CGTS_SM_CTRL_REG__SM_MODE__SHIFT 0x11\n#define CGTS_SM_CTRL_REG__SM_MODE_ENABLE_MASK 0x100000\n#define CGTS_SM_CTRL_REG__SM_MODE_ENABLE__SHIFT 0x14\n#define CGTS_SM_CTRL_REG__OVERRIDE_MASK 0x200000\n#define CGTS_SM_CTRL_REG__OVERRIDE__SHIFT 0x15\n#define CGTS_SM_CTRL_REG__LS_OVERRIDE_MASK 0x400000\n#define CGTS_SM_CTRL_REG__LS_OVERRIDE__SHIFT 0x16\n#define CGTS_SM_CTRL_REG__ON_MONITOR_ADD_EN_MASK 0x800000\n#define CGTS_SM_CTRL_REG__ON_MONITOR_ADD_EN__SHIFT 0x17\n#define CGTS_SM_CTRL_REG__ON_MONITOR_ADD_MASK 0xff000000\n#define CGTS_SM_CTRL_REG__ON_MONITOR_ADD__SHIFT 0x18\n#define CGTS_RD_CTRL_REG__ROW_MUX_SEL_MASK 0x1f\n#define CGTS_RD_CTRL_REG__ROW_MUX_SEL__SHIFT 0x0\n#define CGTS_RD_CTRL_REG__REG_MUX_SEL_MASK 0x1f00\n#define CGTS_RD_CTRL_REG__REG_MUX_SEL__SHIFT 0x8\n#define CGTS_RD_REG__READ_DATA_MASK 0x3fff\n#define CGTS_RD_REG__READ_DATA__SHIFT 0x0\n#define CGTS_TCC_DISABLE__TCC_DISABLE_MASK 0xffff0000\n#define CGTS_TCC_DISABLE__TCC_DISABLE__SHIFT 0x10\n#define CGTS_USER_TCC_DISABLE__TCC_DISABLE_MASK 0xffff0000\n#define CGTS_USER_TCC_DISABLE__TCC_DISABLE__SHIFT 0x10\n#define CGTS_CU0_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU0_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU0_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU0_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU0_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU0_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU0_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU0_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU0_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU0_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU0_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU0_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU0_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU0_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU0_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU0_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU0_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU0_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU0_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU0_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU0_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU0_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU0_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_MASK 0x7f0000\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC__SHIFT 0x10\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_OVERRIDE_MASK 0x800000\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_OVERRIDE__SHIFT 0x17\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU0_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU0_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU0_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU0_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU0_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU0_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU0_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU0_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU0_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU0_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU0_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU0_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU0_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU0_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU0_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU0_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU0_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU0_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU0_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU0_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU0_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU0_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU0_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU1_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU1_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU1_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU1_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU1_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU1_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU1_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU1_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU1_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU1_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU1_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU1_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU1_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU1_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU1_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU1_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU1_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU1_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU1_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU1_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU1_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU1_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU1_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU1_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU1_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU1_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU1_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU1_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU1_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU1_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU1_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU1_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU1_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU1_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU1_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU1_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU1_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU1_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU1_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU1_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU1_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU1_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU1_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU1_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU1_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU1_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU1_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU1_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU1_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU1_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU1_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU1_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU1_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU1_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU2_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU2_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU2_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU2_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU2_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU2_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU2_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU2_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU2_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU2_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU2_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU2_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU2_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU2_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU2_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU2_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU2_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU2_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU2_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU2_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU2_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU2_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU2_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU2_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU2_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU2_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU2_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU2_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU2_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU2_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU2_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU2_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU2_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU2_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU2_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU2_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU2_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU2_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU2_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU2_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU2_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU2_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU2_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU2_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU2_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU2_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU2_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU2_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU2_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU2_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU2_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU2_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU2_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU2_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU3_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU3_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU3_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU3_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU3_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU3_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU3_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU3_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU3_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU3_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU3_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU3_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU3_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU3_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU3_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU3_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU3_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU3_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU3_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU3_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU3_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU3_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU3_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU3_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU3_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU3_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU3_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU3_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU3_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU3_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU3_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU3_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU3_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU3_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU3_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU3_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU3_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU3_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU3_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU3_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU3_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU3_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU3_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU3_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU3_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU3_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU3_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU3_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU3_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU3_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU3_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU3_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU3_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU3_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU4_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU4_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU4_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU4_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU4_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU4_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU4_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU4_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU4_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU4_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU4_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU4_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU4_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU4_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU4_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU4_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU4_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU4_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU4_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU4_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU4_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU4_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU4_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_MASK 0x7f0000\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC__SHIFT 0x10\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_OVERRIDE_MASK 0x800000\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_OVERRIDE__SHIFT 0x17\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU4_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU4_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU4_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU4_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU4_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU4_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU4_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU4_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU4_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU4_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU4_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU4_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU4_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU4_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU4_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU4_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU4_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU4_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU4_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU4_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU4_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU4_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU4_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU5_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU5_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU5_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU5_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU5_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU5_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU5_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU5_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU5_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU5_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU5_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU5_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU5_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU5_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU5_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU5_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU5_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU5_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU5_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU5_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU5_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU5_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU5_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU5_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU5_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU5_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU5_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU5_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU5_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU5_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU5_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU5_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU5_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU5_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU5_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU5_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU5_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU5_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU5_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU5_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU5_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU5_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU5_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU5_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU5_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU5_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU5_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU5_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU5_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU5_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU5_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU5_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU5_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU5_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU6_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU6_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU6_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU6_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU6_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU6_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU6_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU6_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU6_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU6_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU6_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU6_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU6_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU6_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU6_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU6_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU6_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU6_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU6_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU6_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU6_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU6_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU6_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU6_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU6_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU6_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU6_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU6_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU6_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU6_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU6_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU6_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU6_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU6_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU6_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU6_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU6_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU6_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU6_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU6_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU6_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU6_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU6_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU6_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU6_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU6_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU6_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU6_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU6_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU6_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU6_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU6_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU6_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU6_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU7_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU7_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU7_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU7_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU7_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU7_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU7_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU7_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU7_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU7_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU7_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU7_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU7_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU7_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU7_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU7_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU7_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU7_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU7_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU7_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU7_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU7_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU7_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU7_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU7_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU7_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU7_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU7_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU7_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU7_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU7_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU7_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU7_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU7_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU7_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU7_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU7_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU7_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU7_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU7_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU7_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU7_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU7_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU7_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU7_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU7_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU7_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU7_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU7_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU7_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU7_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU7_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU7_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU7_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU8_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU8_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU8_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU8_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU8_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU8_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU8_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU8_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU8_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU8_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU8_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU8_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU8_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU8_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU8_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU8_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU8_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU8_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU8_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU8_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU8_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU8_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU8_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_MASK 0x7f0000\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC__SHIFT 0x10\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_OVERRIDE_MASK 0x800000\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_OVERRIDE__SHIFT 0x17\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU8_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU8_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU8_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU8_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU8_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU8_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU8_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU8_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU8_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU8_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU8_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU8_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU8_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU8_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU8_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU8_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU8_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU8_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU8_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU8_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU8_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU8_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU8_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU9_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU9_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU9_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU9_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU9_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU9_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU9_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU9_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU9_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU9_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU9_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU9_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU9_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU9_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU9_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU9_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU9_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU9_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU9_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU9_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU9_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU9_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU9_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU9_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU9_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU9_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU9_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU9_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU9_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU9_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU9_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU9_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU9_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU9_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU9_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU9_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU9_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU9_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU9_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU9_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU9_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU9_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU9_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU9_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU9_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU9_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU9_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU9_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU9_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU9_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU9_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU9_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU9_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU9_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU10_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU10_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU10_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU10_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU10_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU10_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU10_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU10_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU10_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU10_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU10_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU10_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU10_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU10_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU10_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU10_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU10_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU10_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU10_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU10_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU10_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU10_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU10_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU10_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU10_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU10_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU10_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU10_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU10_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU10_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU10_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU10_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU10_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU10_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU10_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU10_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU10_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU10_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU10_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU10_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU10_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU10_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU10_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU10_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU10_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU10_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU10_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU10_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU10_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU10_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU10_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU10_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU10_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU10_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU11_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU11_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU11_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU11_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU11_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU11_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU11_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU11_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU11_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU11_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU11_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU11_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU11_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU11_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU11_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU11_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU11_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU11_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU11_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU11_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU11_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU11_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU11_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU11_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU11_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU11_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU11_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU11_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU11_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU11_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU11_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU11_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU11_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU11_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU11_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU11_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU11_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU11_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU11_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU11_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU11_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU11_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU11_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU11_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU11_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU11_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU11_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU11_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU11_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU11_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU11_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU11_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU11_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU11_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU12_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU12_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU12_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU12_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU12_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU12_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU12_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU12_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU12_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU12_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU12_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU12_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU12_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU12_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU12_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU12_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU12_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU12_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU12_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU12_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU12_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU12_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU12_TA_SQC_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_MASK 0x7f0000\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC__SHIFT 0x10\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_OVERRIDE_MASK 0x800000\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_OVERRIDE__SHIFT 0x17\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU12_TA_SQC_CTRL_REG__SQC_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU12_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU12_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU12_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU12_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU12_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU12_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU12_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU12_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU12_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU12_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU12_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU12_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU12_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU12_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU12_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU12_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU12_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU12_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU12_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU12_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU12_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU12_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU13_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU13_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU13_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU13_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU13_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU13_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU13_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU13_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU13_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU13_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU13_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU13_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU13_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU13_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU13_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU13_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU13_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU13_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU13_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU13_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU13_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU13_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU13_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU13_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU13_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU13_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU13_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU13_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU13_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU13_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU13_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU13_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU13_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU13_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU13_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU13_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU13_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU13_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU13_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU13_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU13_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU13_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU13_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU13_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU13_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU13_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU13_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU13_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU13_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU13_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU13_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU13_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU13_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU13_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU14_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU14_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU14_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU14_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU14_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU14_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU14_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU14_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU14_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU14_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU14_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU14_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU14_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU14_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU14_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU14_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU14_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU14_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU14_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU14_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU14_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU14_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU14_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU14_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU14_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU14_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU14_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU14_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU14_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU14_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU14_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU14_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU14_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU14_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU14_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU14_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU14_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU14_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU14_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU14_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU14_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU14_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU14_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU14_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU14_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU14_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU14_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU14_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU14_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU14_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU14_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU14_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU14_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU14_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU15_SP0_CTRL_REG__SP00_MASK 0x7f\n#define CGTS_CU15_SP0_CTRL_REG__SP00__SHIFT 0x0\n#define CGTS_CU15_SP0_CTRL_REG__SP00_OVERRIDE_MASK 0x80\n#define CGTS_CU15_SP0_CTRL_REG__SP00_OVERRIDE__SHIFT 0x7\n#define CGTS_CU15_SP0_CTRL_REG__SP00_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU15_SP0_CTRL_REG__SP00_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU15_SP0_CTRL_REG__SP00_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU15_SP0_CTRL_REG__SP00_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU15_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU15_SP0_CTRL_REG__SP00_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU15_SP0_CTRL_REG__SP01_MASK 0x7f0000\n#define CGTS_CU15_SP0_CTRL_REG__SP01__SHIFT 0x10\n#define CGTS_CU15_SP0_CTRL_REG__SP01_OVERRIDE_MASK 0x800000\n#define CGTS_CU15_SP0_CTRL_REG__SP01_OVERRIDE__SHIFT 0x17\n#define CGTS_CU15_SP0_CTRL_REG__SP01_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU15_SP0_CTRL_REG__SP01_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU15_SP0_CTRL_REG__SP01_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU15_SP0_CTRL_REG__SP01_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU15_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU15_SP0_CTRL_REG__SP01_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_MASK 0x7f\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS__SHIFT 0x0\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_OVERRIDE_MASK 0x80\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_OVERRIDE__SHIFT 0x7\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU15_LDS_SQ_CTRL_REG__LDS_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_MASK 0x7f0000\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ__SHIFT 0x10\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_OVERRIDE_MASK 0x800000\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_OVERRIDE__SHIFT 0x17\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU15_LDS_SQ_CTRL_REG__SQ_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU15_TA_CTRL_REG__TA_MASK 0x7f\n#define CGTS_CU15_TA_CTRL_REG__TA__SHIFT 0x0\n#define CGTS_CU15_TA_CTRL_REG__TA_OVERRIDE_MASK 0x80\n#define CGTS_CU15_TA_CTRL_REG__TA_OVERRIDE__SHIFT 0x7\n#define CGTS_CU15_TA_CTRL_REG__TA_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU15_TA_CTRL_REG__TA_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU15_TA_CTRL_REG__TA_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU15_TA_CTRL_REG__TA_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU15_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU15_TA_CTRL_REG__TA_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU15_SP1_CTRL_REG__SP10_MASK 0x7f\n#define CGTS_CU15_SP1_CTRL_REG__SP10__SHIFT 0x0\n#define CGTS_CU15_SP1_CTRL_REG__SP10_OVERRIDE_MASK 0x80\n#define CGTS_CU15_SP1_CTRL_REG__SP10_OVERRIDE__SHIFT 0x7\n#define CGTS_CU15_SP1_CTRL_REG__SP10_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU15_SP1_CTRL_REG__SP10_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU15_SP1_CTRL_REG__SP10_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU15_SP1_CTRL_REG__SP10_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU15_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU15_SP1_CTRL_REG__SP10_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU15_SP1_CTRL_REG__SP11_MASK 0x7f0000\n#define CGTS_CU15_SP1_CTRL_REG__SP11__SHIFT 0x10\n#define CGTS_CU15_SP1_CTRL_REG__SP11_OVERRIDE_MASK 0x800000\n#define CGTS_CU15_SP1_CTRL_REG__SP11_OVERRIDE__SHIFT 0x17\n#define CGTS_CU15_SP1_CTRL_REG__SP11_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU15_SP1_CTRL_REG__SP11_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU15_SP1_CTRL_REG__SP11_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU15_SP1_CTRL_REG__SP11_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU15_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU15_SP1_CTRL_REG__SP11_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_MASK 0x7f\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD__SHIFT 0x0\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_OVERRIDE_MASK 0x80\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_OVERRIDE__SHIFT 0x7\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE_MASK 0x300\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_BUSY_OVERRIDE__SHIFT 0x8\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_LS_OVERRIDE_MASK 0x400\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_LS_OVERRIDE__SHIFT 0xa\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE_MASK 0x800\n#define CGTS_CU15_TD_TCP_CTRL_REG__TD_SIMDBUSY_OVERRIDE__SHIFT 0xb\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_MASK 0x7f0000\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP__SHIFT 0x10\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_OVERRIDE_MASK 0x800000\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_OVERRIDE__SHIFT 0x17\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE_MASK 0x3000000\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_BUSY_OVERRIDE__SHIFT 0x18\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE_MASK 0x4000000\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_LS_OVERRIDE__SHIFT 0x1a\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE_MASK 0x8000000\n#define CGTS_CU15_TD_TCP_CTRL_REG__TCP_SIMDBUSY_OVERRIDE__SHIFT 0x1b\n#define CGTT_SPI_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_SPI_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_SPI_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SPI_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SPI_CLK_CTRL__GRP5_CG_OFF_HYST_MASK 0xfc0000\n#define CGTT_SPI_CLK_CTRL__GRP5_CG_OFF_HYST__SHIFT 0x12\n#define CGTT_SPI_CLK_CTRL__GRP5_CG_OVERRIDE_MASK 0x1000000\n#define CGTT_SPI_CLK_CTRL__GRP5_CG_OVERRIDE__SHIFT 0x18\n#define CGTT_SPI_CLK_CTRL__ALL_CLK_ON_OVERRIDE_MASK 0x4000000\n#define CGTT_SPI_CLK_CTRL__ALL_CLK_ON_OVERRIDE__SHIFT 0x1a\n#define CGTT_SPI_CLK_CTRL__GRP3_OVERRIDE_MASK 0x8000000\n#define CGTT_SPI_CLK_CTRL__GRP3_OVERRIDE__SHIFT 0x1b\n#define CGTT_SPI_CLK_CTRL__GRP2_OVERRIDE_MASK 0x10000000\n#define CGTT_SPI_CLK_CTRL__GRP2_OVERRIDE__SHIFT 0x1c\n#define CGTT_SPI_CLK_CTRL__GRP1_OVERRIDE_MASK 0x20000000\n#define CGTT_SPI_CLK_CTRL__GRP1_OVERRIDE__SHIFT 0x1d\n#define CGTT_SPI_CLK_CTRL__GRP0_OVERRIDE_MASK 0x40000000\n#define CGTT_SPI_CLK_CTRL__GRP0_OVERRIDE__SHIFT 0x1e\n#define CGTT_SPI_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_SPI_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define CGTT_PC_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_PC_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_PC_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_PC_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_PC_CLK_CTRL__GRP5_CG_OFF_HYST_MASK 0xfc0000\n#define CGTT_PC_CLK_CTRL__GRP5_CG_OFF_HYST__SHIFT 0x12\n#define CGTT_PC_CLK_CTRL__GRP5_CG_OVERRIDE_MASK 0x1000000\n#define CGTT_PC_CLK_CTRL__GRP5_CG_OVERRIDE__SHIFT 0x18\n#define CGTT_PC_CLK_CTRL__BACK_CLK_ON_OVERRIDE_MASK 0x2000000\n#define CGTT_PC_CLK_CTRL__BACK_CLK_ON_OVERRIDE__SHIFT 0x19\n#define CGTT_PC_CLK_CTRL__FRONT_CLK_ON_OVERRIDE_MASK 0x4000000\n#define CGTT_PC_CLK_CTRL__FRONT_CLK_ON_OVERRIDE__SHIFT 0x1a\n#define CGTT_PC_CLK_CTRL__CORE3_OVERRIDE_MASK 0x8000000\n#define CGTT_PC_CLK_CTRL__CORE3_OVERRIDE__SHIFT 0x1b\n#define CGTT_PC_CLK_CTRL__CORE2_OVERRIDE_MASK 0x10000000\n#define CGTT_PC_CLK_CTRL__CORE2_OVERRIDE__SHIFT 0x1c\n#define CGTT_PC_CLK_CTRL__CORE1_OVERRIDE_MASK 0x20000000\n#define CGTT_PC_CLK_CTRL__CORE1_OVERRIDE__SHIFT 0x1d\n#define CGTT_PC_CLK_CTRL__CORE0_OVERRIDE_MASK 0x40000000\n#define CGTT_PC_CLK_CTRL__CORE0_OVERRIDE__SHIFT 0x1e\n#define CGTT_PC_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_PC_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define CGTT_BCI_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_BCI_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_BCI_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_BCI_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_BCI_CLK_CTRL__RESERVED_MASK 0xfff000\n#define CGTT_BCI_CLK_CTRL__RESERVED__SHIFT 0xc\n#define CGTT_BCI_CLK_CTRL__CORE6_OVERRIDE_MASK 0x1000000\n#define CGTT_BCI_CLK_CTRL__CORE6_OVERRIDE__SHIFT 0x18\n#define CGTT_BCI_CLK_CTRL__CORE5_OVERRIDE_MASK 0x2000000\n#define CGTT_BCI_CLK_CTRL__CORE5_OVERRIDE__SHIFT 0x19\n#define CGTT_BCI_CLK_CTRL__CORE4_OVERRIDE_MASK 0x4000000\n#define CGTT_BCI_CLK_CTRL__CORE4_OVERRIDE__SHIFT 0x1a\n#define CGTT_BCI_CLK_CTRL__CORE3_OVERRIDE_MASK 0x8000000\n#define CGTT_BCI_CLK_CTRL__CORE3_OVERRIDE__SHIFT 0x1b\n#define CGTT_BCI_CLK_CTRL__CORE2_OVERRIDE_MASK 0x10000000\n#define CGTT_BCI_CLK_CTRL__CORE2_OVERRIDE__SHIFT 0x1c\n#define CGTT_BCI_CLK_CTRL__CORE1_OVERRIDE_MASK 0x20000000\n#define CGTT_BCI_CLK_CTRL__CORE1_OVERRIDE__SHIFT 0x1d\n#define CGTT_BCI_CLK_CTRL__CORE0_OVERRIDE_MASK 0x40000000\n#define CGTT_BCI_CLK_CTRL__CORE0_OVERRIDE__SHIFT 0x1e\n#define CGTT_BCI_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_BCI_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define SPI_WF_LIFETIME_CNTL__SAMPLE_PERIOD_MASK 0xf\n#define SPI_WF_LIFETIME_CNTL__SAMPLE_PERIOD__SHIFT 0x0\n#define SPI_WF_LIFETIME_CNTL__EN_MASK 0x10\n#define SPI_WF_LIFETIME_CNTL__EN__SHIFT 0x4\n#define SPI_WF_LIFETIME_LIMIT_0__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_0__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_0__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_0__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_1__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_1__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_1__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_1__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_2__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_2__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_2__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_2__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_3__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_3__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_3__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_3__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_4__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_4__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_4__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_4__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_5__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_5__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_5__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_5__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_6__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_6__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_6__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_6__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_7__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_7__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_7__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_7__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_8__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_8__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_8__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_8__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_LIMIT_9__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_LIMIT_9__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_LIMIT_9__EN_WARN_MASK 0x80000000\n#define SPI_WF_LIFETIME_LIMIT_9__EN_WARN__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_0__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_0__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_0__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_0__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_1__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_1__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_1__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_1__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_2__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_2__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_2__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_2__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_3__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_3__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_3__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_3__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_4__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_4__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_4__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_4__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_5__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_5__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_5__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_5__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_6__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_6__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_6__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_6__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_7__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_7__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_7__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_7__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_8__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_8__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_8__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_8__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_9__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_9__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_9__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_9__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_10__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_10__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_10__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_10__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_11__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_11__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_11__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_11__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_12__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_12__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_12__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_12__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_13__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_13__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_13__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_13__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_14__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_14__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_14__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_14__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_15__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_15__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_15__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_15__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_16__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_16__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_16__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_16__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_17__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_17__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_17__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_17__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_18__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_18__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_18__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_18__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_19__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_19__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_19__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_19__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_STATUS_20__MAX_CNT_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_STATUS_20__MAX_CNT__SHIFT 0x0\n#define SPI_WF_LIFETIME_STATUS_20__INT_SENT_MASK 0x80000000\n#define SPI_WF_LIFETIME_STATUS_20__INT_SENT__SHIFT 0x1f\n#define SPI_WF_LIFETIME_DEBUG__START_VALUE_MASK 0x7fffffff\n#define SPI_WF_LIFETIME_DEBUG__START_VALUE__SHIFT 0x0\n#define SPI_WF_LIFETIME_DEBUG__OVERRIDE_EN_MASK 0x80000000\n#define SPI_WF_LIFETIME_DEBUG__OVERRIDE_EN__SHIFT 0x1f\n#define SPI_SLAVE_DEBUG_BUSY__LS_VTX_BUSY_MASK 0x1\n#define SPI_SLAVE_DEBUG_BUSY__LS_VTX_BUSY__SHIFT 0x0\n#define SPI_SLAVE_DEBUG_BUSY__HS_VTX_BUSY_MASK 0x2\n#define SPI_SLAVE_DEBUG_BUSY__HS_VTX_BUSY__SHIFT 0x1\n#define SPI_SLAVE_DEBUG_BUSY__ES_VTX_BUSY_MASK 0x4\n#define SPI_SLAVE_DEBUG_BUSY__ES_VTX_BUSY__SHIFT 0x2\n#define SPI_SLAVE_DEBUG_BUSY__GS_VTX_BUSY_MASK 0x8\n#define SPI_SLAVE_DEBUG_BUSY__GS_VTX_BUSY__SHIFT 0x3\n#define SPI_SLAVE_DEBUG_BUSY__VS_VTX_BUSY_MASK 0x10\n#define SPI_SLAVE_DEBUG_BUSY__VS_VTX_BUSY__SHIFT 0x4\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC00_BUSY_MASK 0x20\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC00_BUSY__SHIFT 0x5\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC01_BUSY_MASK 0x40\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC01_BUSY__SHIFT 0x6\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC10_BUSY_MASK 0x80\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC10_BUSY__SHIFT 0x7\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC11_BUSY_MASK 0x100\n#define SPI_SLAVE_DEBUG_BUSY__VGPR_WC11_BUSY__SHIFT 0x8\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC00_BUSY_MASK 0x200\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC00_BUSY__SHIFT 0x9\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC01_BUSY_MASK 0x400\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC01_BUSY__SHIFT 0xa\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC02_BUSY_MASK 0x800\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC02_BUSY__SHIFT 0xb\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC03_BUSY_MASK 0x1000\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC03_BUSY__SHIFT 0xc\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC10_BUSY_MASK 0x2000\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC10_BUSY__SHIFT 0xd\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC11_BUSY_MASK 0x4000\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC11_BUSY__SHIFT 0xe\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC12_BUSY_MASK 0x8000\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC12_BUSY__SHIFT 0xf\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC13_BUSY_MASK 0x10000\n#define SPI_SLAVE_DEBUG_BUSY__SGPR_WC13_BUSY__SHIFT 0x10\n#define SPI_SLAVE_DEBUG_BUSY__WAVEBUFFER0_BUSY_MASK 0x20000\n#define SPI_SLAVE_DEBUG_BUSY__WAVEBUFFER0_BUSY__SHIFT 0x11\n#define SPI_SLAVE_DEBUG_BUSY__WAVEBUFFER1_BUSY_MASK 0x40000\n#define SPI_SLAVE_DEBUG_BUSY__WAVEBUFFER1_BUSY__SHIFT 0x12\n#define SPI_SLAVE_DEBUG_BUSY__WAVE_WC0_BUSY_MASK 0x80000\n#define SPI_SLAVE_DEBUG_BUSY__WAVE_WC0_BUSY__SHIFT 0x13\n#define SPI_SLAVE_DEBUG_BUSY__WAVE_WC1_BUSY_MASK 0x100000\n#define SPI_SLAVE_DEBUG_BUSY__WAVE_WC1_BUSY__SHIFT 0x14\n#define SPI_SLAVE_DEBUG_BUSY__EVENT_CNTL_BUSY_MASK 0x200000\n#define SPI_SLAVE_DEBUG_BUSY__EVENT_CNTL_BUSY__SHIFT 0x15\n#define SPI_LB_CTR_CTRL__LOAD_MASK 0x1\n#define SPI_LB_CTR_CTRL__LOAD__SHIFT 0x0\n#define SPI_LB_CU_MASK__CU_MASK_MASK 0xffff\n#define SPI_LB_CU_MASK__CU_MASK__SHIFT 0x0\n#define SPI_LB_DATA_REG__CNT_DATA_MASK 0xffffffff\n#define SPI_LB_DATA_REG__CNT_DATA__SHIFT 0x0\n#define SPI_PG_ENABLE_STATIC_CU_MASK__CU_MASK_MASK 0xffff\n#define SPI_PG_ENABLE_STATIC_CU_MASK__CU_MASK__SHIFT 0x0\n#define SPI_GDS_CREDITS__DS_DATA_CREDITS_MASK 0xff\n#define SPI_GDS_CREDITS__DS_DATA_CREDITS__SHIFT 0x0\n#define SPI_GDS_CREDITS__DS_CMD_CREDITS_MASK 0xff00\n#define SPI_GDS_CREDITS__DS_CMD_CREDITS__SHIFT 0x8\n#define SPI_GDS_CREDITS__UNUSED_MASK 0xffff0000\n#define SPI_GDS_CREDITS__UNUSED__SHIFT 0x10\n#define SPI_SX_EXPORT_BUFFER_SIZES__COLOR_BUFFER_SIZE_MASK 0xffff\n#define SPI_SX_EXPORT_BUFFER_SIZES__COLOR_BUFFER_SIZE__SHIFT 0x0\n#define SPI_SX_EXPORT_BUFFER_SIZES__POSITION_BUFFER_SIZE_MASK 0xffff0000\n#define SPI_SX_EXPORT_BUFFER_SIZES__POSITION_BUFFER_SIZE__SHIFT 0x10\n#define SPI_SX_SCOREBOARD_BUFFER_SIZES__COLOR_SCOREBOARD_SIZE_MASK 0xffff\n#define SPI_SX_SCOREBOARD_BUFFER_SIZES__COLOR_SCOREBOARD_SIZE__SHIFT 0x0\n#define SPI_SX_SCOREBOARD_BUFFER_SIZES__POSITION_SCOREBOARD_SIZE_MASK 0xffff0000\n#define SPI_SX_SCOREBOARD_BUFFER_SIZES__POSITION_SCOREBOARD_SIZE__SHIFT 0x10\n#define SPI_CSQ_WF_ACTIVE_STATUS__ACTIVE_MASK 0xffffffff\n#define SPI_CSQ_WF_ACTIVE_STATUS__ACTIVE__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_0__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_0__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_1__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_1__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_2__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_2__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_3__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_3__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_4__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_4__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_5__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_5__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_6__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_6__COUNT__SHIFT 0x0\n#define SPI_CSQ_WF_ACTIVE_COUNT_7__COUNT_MASK 0x7ff\n#define SPI_CSQ_WF_ACTIVE_COUNT_7__COUNT__SHIFT 0x0\n#define BCI_DEBUG_READ__DATA_MASK 0xffffff\n#define BCI_DEBUG_READ__DATA__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_PSBA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_P0_TRAP_SCREEN_PSBA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_PSBA_HI__MEM_BASE_MASK 0xff\n#define SPI_P0_TRAP_SCREEN_PSBA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_PSMA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_P0_TRAP_SCREEN_PSMA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_PSMA_HI__MEM_BASE_MASK 0xff\n#define SPI_P0_TRAP_SCREEN_PSMA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_GPR_MIN__VGPR_MIN_MASK 0x3f\n#define SPI_P0_TRAP_SCREEN_GPR_MIN__VGPR_MIN__SHIFT 0x0\n#define SPI_P0_TRAP_SCREEN_GPR_MIN__SGPR_MIN_MASK 0x3c0\n#define SPI_P0_TRAP_SCREEN_GPR_MIN__SGPR_MIN__SHIFT 0x6\n#define SPI_P1_TRAP_SCREEN_PSBA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_P1_TRAP_SCREEN_PSBA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_P1_TRAP_SCREEN_PSBA_HI__MEM_BASE_MASK 0xff\n#define SPI_P1_TRAP_SCREEN_PSBA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_P1_TRAP_SCREEN_PSMA_LO__MEM_BASE_MASK 0xffffffff\n#define SPI_P1_TRAP_SCREEN_PSMA_LO__MEM_BASE__SHIFT 0x0\n#define SPI_P1_TRAP_SCREEN_PSMA_HI__MEM_BASE_MASK 0xff\n#define SPI_P1_TRAP_SCREEN_PSMA_HI__MEM_BASE__SHIFT 0x0\n#define SPI_P1_TRAP_SCREEN_GPR_MIN__VGPR_MIN_MASK 0x3f\n#define SPI_P1_TRAP_SCREEN_GPR_MIN__VGPR_MIN__SHIFT 0x0\n#define SPI_P1_TRAP_SCREEN_GPR_MIN__SGPR_MIN_MASK 0x3c0\n#define SPI_P1_TRAP_SCREEN_GPR_MIN__SGPR_MIN__SHIFT 0x6\n#define SPI_SHADER_TBA_LO_PS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_PS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_PS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_PS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_PS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_PS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_PS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_PS__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_PS__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_PS__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_PS__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_PS__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_PS__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_PS__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_PS__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_PS__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_PS__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_PS__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_PS__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_PS__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_PS__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_PS__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_PS__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_PS__CU_GROUP_DISABLE_MASK 0x1000000\n#define SPI_SHADER_PGM_RSRC1_PS__CU_GROUP_DISABLE__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_PS__CACHE_CTL_MASK 0xe000000\n#define SPI_SHADER_PGM_RSRC1_PS__CACHE_CTL__SHIFT 0x19\n#define SPI_SHADER_PGM_RSRC1_PS__CDBG_USER_MASK 0x10000000\n#define SPI_SHADER_PGM_RSRC1_PS__CDBG_USER__SHIFT 0x1c\n#define SPI_SHADER_PGM_RSRC2_PS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_PS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_PS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_PS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_PS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_PS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_PS__WAVE_CNT_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_PS__WAVE_CNT_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_PS__EXTRA_LDS_SIZE_MASK 0xff00\n#define SPI_SHADER_PGM_RSRC2_PS__EXTRA_LDS_SIZE__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_PS__EXCP_EN_MASK 0x1ff0000\n#define SPI_SHADER_PGM_RSRC2_PS__EXCP_EN__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_PS__CU_EN_MASK 0xffff\n#define SPI_SHADER_PGM_RSRC3_PS__CU_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_PS__WAVE_LIMIT_MASK 0x3f0000\n#define SPI_SHADER_PGM_RSRC3_PS__WAVE_LIMIT__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_PS__LOCK_LOW_THRESHOLD_MASK 0x3c00000\n#define SPI_SHADER_PGM_RSRC3_PS__LOCK_LOW_THRESHOLD__SHIFT 0x16\n#define SPI_SHADER_USER_DATA_PS_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_PS_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_PS_15__DATA__SHIFT 0x0\n#define SPI_SHADER_TBA_LO_VS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_VS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_VS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_VS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_VS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_VS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_VS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_VS__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_VS__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_VS__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_VS__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_VS__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_VS__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_VS__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_VS__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_VS__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_VS__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_VS__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_VS__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_VS__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_VS__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_VS__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_VS__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_VS__VGPR_COMP_CNT_MASK 0x3000000\n#define SPI_SHADER_PGM_RSRC1_VS__VGPR_COMP_CNT__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_VS__CU_GROUP_ENABLE_MASK 0x4000000\n#define SPI_SHADER_PGM_RSRC1_VS__CU_GROUP_ENABLE__SHIFT 0x1a\n#define SPI_SHADER_PGM_RSRC1_VS__CACHE_CTL_MASK 0x38000000\n#define SPI_SHADER_PGM_RSRC1_VS__CACHE_CTL__SHIFT 0x1b\n#define SPI_SHADER_PGM_RSRC1_VS__CDBG_USER_MASK 0x40000000\n#define SPI_SHADER_PGM_RSRC1_VS__CDBG_USER__SHIFT 0x1e\n#define SPI_SHADER_PGM_RSRC2_VS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_VS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_VS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_VS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_VS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_VS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_VS__OC_LDS_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_VS__OC_LDS_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE0_EN_MASK 0x100\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE0_EN__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE1_EN_MASK 0x200\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE1_EN__SHIFT 0x9\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE2_EN_MASK 0x400\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE2_EN__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE3_EN_MASK 0x800\n#define SPI_SHADER_PGM_RSRC2_VS__SO_BASE3_EN__SHIFT 0xb\n#define SPI_SHADER_PGM_RSRC2_VS__SO_EN_MASK 0x1000\n#define SPI_SHADER_PGM_RSRC2_VS__SO_EN__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC2_VS__EXCP_EN_MASK 0x3fe000\n#define SPI_SHADER_PGM_RSRC2_VS__EXCP_EN__SHIFT 0xd\n#define SPI_SHADER_PGM_RSRC3_VS__CU_EN_MASK 0xffff\n#define SPI_SHADER_PGM_RSRC3_VS__CU_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_VS__WAVE_LIMIT_MASK 0x3f0000\n#define SPI_SHADER_PGM_RSRC3_VS__WAVE_LIMIT__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_VS__LOCK_LOW_THRESHOLD_MASK 0x3c00000\n#define SPI_SHADER_PGM_RSRC3_VS__LOCK_LOW_THRESHOLD__SHIFT 0x16\n#define SPI_SHADER_LATE_ALLOC_VS__LIMIT_MASK 0x3f\n#define SPI_SHADER_LATE_ALLOC_VS__LIMIT__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_VS_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_VS_15__DATA__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_ES_VS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_ES_VS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_ES_VS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_ES_VS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_ES_VS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_ES_VS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_ES_VS__OC_LDS_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_ES_VS__OC_LDS_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_ES_VS__EXCP_EN_MASK 0x1ff00\n#define SPI_SHADER_PGM_RSRC2_ES_VS__EXCP_EN__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_ES_VS__LDS_SIZE_MASK 0x1ff00000\n#define SPI_SHADER_PGM_RSRC2_ES_VS__LDS_SIZE__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC2_LS_VS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_VS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS_VS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_LS_VS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_VS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_LS_VS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_LS_VS__LDS_SIZE_MASK 0xff80\n#define SPI_SHADER_PGM_RSRC2_LS_VS__LDS_SIZE__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_LS_VS__EXCP_EN_MASK 0x1ff0000\n#define SPI_SHADER_PGM_RSRC2_LS_VS__EXCP_EN__SHIFT 0x10\n#define SPI_SHADER_TBA_LO_GS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_GS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_GS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_GS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_GS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_GS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_GS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_GS__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_GS__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_GS__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_GS__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_GS__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_GS__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_GS__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_GS__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_GS__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_GS__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_GS__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_GS__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_GS__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_GS__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_GS__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_GS__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_GS__CU_GROUP_ENABLE_MASK 0x1000000\n#define SPI_SHADER_PGM_RSRC1_GS__CU_GROUP_ENABLE__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_GS__CACHE_CTL_MASK 0xe000000\n#define SPI_SHADER_PGM_RSRC1_GS__CACHE_CTL__SHIFT 0x19\n#define SPI_SHADER_PGM_RSRC1_GS__CDBG_USER_MASK 0x10000000\n#define SPI_SHADER_PGM_RSRC1_GS__CDBG_USER__SHIFT 0x1c\n#define SPI_SHADER_PGM_RSRC2_GS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_GS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_GS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_GS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_GS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_GS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_GS__EXCP_EN_MASK 0xff80\n#define SPI_SHADER_PGM_RSRC2_GS__EXCP_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC3_GS__CU_EN_MASK 0xffff\n#define SPI_SHADER_PGM_RSRC3_GS__CU_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_GS__WAVE_LIMIT_MASK 0x3f0000\n#define SPI_SHADER_PGM_RSRC3_GS__WAVE_LIMIT__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_GS__LOCK_LOW_THRESHOLD_MASK 0x3c00000\n#define SPI_SHADER_PGM_RSRC3_GS__LOCK_LOW_THRESHOLD__SHIFT 0x16\n#define SPI_SHADER_USER_DATA_GS_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_GS_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_GS_15__DATA__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_ES_GS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_ES_GS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_ES_GS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_ES_GS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_ES_GS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_ES_GS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_ES_GS__OC_LDS_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_ES_GS__OC_LDS_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_ES_GS__EXCP_EN_MASK 0x1ff00\n#define SPI_SHADER_PGM_RSRC2_ES_GS__EXCP_EN__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_ES_GS__LDS_SIZE_MASK 0x1ff00000\n#define SPI_SHADER_PGM_RSRC2_ES_GS__LDS_SIZE__SHIFT 0x14\n#define SPI_SHADER_TBA_LO_ES__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_ES__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_ES__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_ES__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_ES__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_ES__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_ES__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_ES__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_ES__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_ES__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_ES__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_ES__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_ES__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_ES__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_ES__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_ES__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_ES__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_ES__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_ES__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_ES__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_ES__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_ES__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_ES__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_ES__VGPR_COMP_CNT_MASK 0x3000000\n#define SPI_SHADER_PGM_RSRC1_ES__VGPR_COMP_CNT__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_ES__CU_GROUP_ENABLE_MASK 0x4000000\n#define SPI_SHADER_PGM_RSRC1_ES__CU_GROUP_ENABLE__SHIFT 0x1a\n#define SPI_SHADER_PGM_RSRC1_ES__CACHE_CTL_MASK 0x38000000\n#define SPI_SHADER_PGM_RSRC1_ES__CACHE_CTL__SHIFT 0x1b\n#define SPI_SHADER_PGM_RSRC1_ES__CDBG_USER_MASK 0x40000000\n#define SPI_SHADER_PGM_RSRC1_ES__CDBG_USER__SHIFT 0x1e\n#define SPI_SHADER_PGM_RSRC2_ES__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_ES__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_ES__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_ES__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_ES__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_ES__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_ES__OC_LDS_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_ES__OC_LDS_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_ES__EXCP_EN_MASK 0x1ff00\n#define SPI_SHADER_PGM_RSRC2_ES__EXCP_EN__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_ES__LDS_SIZE_MASK 0x1ff00000\n#define SPI_SHADER_PGM_RSRC2_ES__LDS_SIZE__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC3_ES__CU_EN_MASK 0xffff\n#define SPI_SHADER_PGM_RSRC3_ES__CU_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_ES__WAVE_LIMIT_MASK 0x3f0000\n#define SPI_SHADER_PGM_RSRC3_ES__WAVE_LIMIT__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_ES__LOCK_LOW_THRESHOLD_MASK 0x3c00000\n#define SPI_SHADER_PGM_RSRC3_ES__LOCK_LOW_THRESHOLD__SHIFT 0x16\n#define SPI_SHADER_USER_DATA_ES_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_ES_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_ES_15__DATA__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS_ES__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_ES__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS_ES__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_LS_ES__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_ES__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_LS_ES__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_LS_ES__LDS_SIZE_MASK 0xff80\n#define SPI_SHADER_PGM_RSRC2_LS_ES__LDS_SIZE__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_LS_ES__EXCP_EN_MASK 0x1ff0000\n#define SPI_SHADER_PGM_RSRC2_LS_ES__EXCP_EN__SHIFT 0x10\n#define SPI_SHADER_TBA_LO_HS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_HS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_HS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_HS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_HS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_HS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_HS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_HS__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_HS__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_HS__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_HS__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_HS__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_HS__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_HS__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_HS__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_HS__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_HS__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_HS__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_HS__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_HS__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_HS__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_HS__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_HS__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_HS__CACHE_CTL_MASK 0x7000000\n#define SPI_SHADER_PGM_RSRC1_HS__CACHE_CTL__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_HS__CDBG_USER_MASK 0x8000000\n#define SPI_SHADER_PGM_RSRC1_HS__CDBG_USER__SHIFT 0x1b\n#define SPI_SHADER_PGM_RSRC2_HS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_HS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_HS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_HS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_HS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_HS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_HS__OC_LDS_EN_MASK 0x80\n#define SPI_SHADER_PGM_RSRC2_HS__OC_LDS_EN__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_HS__TG_SIZE_EN_MASK 0x100\n#define SPI_SHADER_PGM_RSRC2_HS__TG_SIZE_EN__SHIFT 0x8\n#define SPI_SHADER_PGM_RSRC2_HS__EXCP_EN_MASK 0x3fe00\n#define SPI_SHADER_PGM_RSRC2_HS__EXCP_EN__SHIFT 0x9\n#define SPI_SHADER_PGM_RSRC3_HS__WAVE_LIMIT_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC3_HS__WAVE_LIMIT__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_HS__LOCK_LOW_THRESHOLD_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC3_HS__LOCK_LOW_THRESHOLD__SHIFT 0x6\n#define SPI_SHADER_USER_DATA_HS_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_HS_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_HS_15__DATA__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS_HS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_HS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS_HS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_LS_HS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_LS_HS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_LS_HS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_LS_HS__LDS_SIZE_MASK 0xff80\n#define SPI_SHADER_PGM_RSRC2_LS_HS__LDS_SIZE__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_LS_HS__EXCP_EN_MASK 0x1ff0000\n#define SPI_SHADER_PGM_RSRC2_LS_HS__EXCP_EN__SHIFT 0x10\n#define SPI_SHADER_TBA_LO_LS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TBA_LO_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TBA_HI_LS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TBA_HI_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_LO_LS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_TMA_LO_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_TMA_HI_LS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_TMA_HI_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_LO_LS__MEM_BASE_MASK 0xffffffff\n#define SPI_SHADER_PGM_LO_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_HI_LS__MEM_BASE_MASK 0xff\n#define SPI_SHADER_PGM_HI_LS__MEM_BASE__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_LS__VGPRS_MASK 0x3f\n#define SPI_SHADER_PGM_RSRC1_LS__VGPRS__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC1_LS__SGPRS_MASK 0x3c0\n#define SPI_SHADER_PGM_RSRC1_LS__SGPRS__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC1_LS__PRIORITY_MASK 0xc00\n#define SPI_SHADER_PGM_RSRC1_LS__PRIORITY__SHIFT 0xa\n#define SPI_SHADER_PGM_RSRC1_LS__FLOAT_MODE_MASK 0xff000\n#define SPI_SHADER_PGM_RSRC1_LS__FLOAT_MODE__SHIFT 0xc\n#define SPI_SHADER_PGM_RSRC1_LS__PRIV_MASK 0x100000\n#define SPI_SHADER_PGM_RSRC1_LS__PRIV__SHIFT 0x14\n#define SPI_SHADER_PGM_RSRC1_LS__DX10_CLAMP_MASK 0x200000\n#define SPI_SHADER_PGM_RSRC1_LS__DX10_CLAMP__SHIFT 0x15\n#define SPI_SHADER_PGM_RSRC1_LS__DEBUG_MODE_MASK 0x400000\n#define SPI_SHADER_PGM_RSRC1_LS__DEBUG_MODE__SHIFT 0x16\n#define SPI_SHADER_PGM_RSRC1_LS__IEEE_MODE_MASK 0x800000\n#define SPI_SHADER_PGM_RSRC1_LS__IEEE_MODE__SHIFT 0x17\n#define SPI_SHADER_PGM_RSRC1_LS__VGPR_COMP_CNT_MASK 0x3000000\n#define SPI_SHADER_PGM_RSRC1_LS__VGPR_COMP_CNT__SHIFT 0x18\n#define SPI_SHADER_PGM_RSRC1_LS__CACHE_CTL_MASK 0x1c000000\n#define SPI_SHADER_PGM_RSRC1_LS__CACHE_CTL__SHIFT 0x1a\n#define SPI_SHADER_PGM_RSRC1_LS__CDBG_USER_MASK 0x20000000\n#define SPI_SHADER_PGM_RSRC1_LS__CDBG_USER__SHIFT 0x1d\n#define SPI_SHADER_PGM_RSRC2_LS__SCRATCH_EN_MASK 0x1\n#define SPI_SHADER_PGM_RSRC2_LS__SCRATCH_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC2_LS__USER_SGPR_MASK 0x3e\n#define SPI_SHADER_PGM_RSRC2_LS__USER_SGPR__SHIFT 0x1\n#define SPI_SHADER_PGM_RSRC2_LS__TRAP_PRESENT_MASK 0x40\n#define SPI_SHADER_PGM_RSRC2_LS__TRAP_PRESENT__SHIFT 0x6\n#define SPI_SHADER_PGM_RSRC2_LS__LDS_SIZE_MASK 0xff80\n#define SPI_SHADER_PGM_RSRC2_LS__LDS_SIZE__SHIFT 0x7\n#define SPI_SHADER_PGM_RSRC2_LS__EXCP_EN_MASK 0x1ff0000\n#define SPI_SHADER_PGM_RSRC2_LS__EXCP_EN__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_LS__CU_EN_MASK 0xffff\n#define SPI_SHADER_PGM_RSRC3_LS__CU_EN__SHIFT 0x0\n#define SPI_SHADER_PGM_RSRC3_LS__WAVE_LIMIT_MASK 0x3f0000\n#define SPI_SHADER_PGM_RSRC3_LS__WAVE_LIMIT__SHIFT 0x10\n#define SPI_SHADER_PGM_RSRC3_LS__LOCK_LOW_THRESHOLD_MASK 0x3c00000\n#define SPI_SHADER_PGM_RSRC3_LS__LOCK_LOW_THRESHOLD__SHIFT 0x16\n#define SPI_SHADER_USER_DATA_LS_0__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_0__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_1__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_1__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_2__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_2__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_3__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_3__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_4__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_4__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_5__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_5__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_6__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_6__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_7__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_7__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_8__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_8__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_9__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_9__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_10__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_10__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_11__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_11__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_12__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_12__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_13__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_13__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_14__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_14__DATA__SHIFT 0x0\n#define SPI_SHADER_USER_DATA_LS_15__DATA_MASK 0xffffffff\n#define SPI_SHADER_USER_DATA_LS_15__DATA__SHIFT 0x0\n#define SQ_CONFIG__UNUSED_MASK 0xff\n#define SQ_CONFIG__UNUSED__SHIFT 0x0\n#define SQ_CONFIG__DEBUG_EN_MASK 0x100\n#define SQ_CONFIG__DEBUG_EN__SHIFT 0x8\n#define SQ_CONFIG__DISABLE_SCA_BYPASS_MASK 0x200\n#define SQ_CONFIG__DISABLE_SCA_BYPASS__SHIFT 0x9\n#define SQ_CONFIG__DISABLE_IB_DEP_CHECK_MASK 0x400\n#define SQ_CONFIG__DISABLE_IB_DEP_CHECK__SHIFT 0xa\n#define SQ_CONFIG__ENABLE_SOFT_CLAUSE_MASK 0x800\n#define SQ_CONFIG__ENABLE_SOFT_CLAUSE__SHIFT 0xb\n#define SQ_CONFIG__EARLY_TA_DONE_DISABLE_MASK 0x1000\n#define SQ_CONFIG__EARLY_TA_DONE_DISABLE__SHIFT 0xc\n#define SQ_CONFIG__DUA_FLAT_LOCK_ENABLE_MASK 0x2000\n#define SQ_CONFIG__DUA_FLAT_LOCK_ENABLE__SHIFT 0xd\n#define SQ_CONFIG__DUA_LDS_BYPASS_DISABLE_MASK 0x4000\n#define SQ_CONFIG__DUA_LDS_BYPASS_DISABLE__SHIFT 0xe\n#define SQ_CONFIG__DUA_FLAT_LDS_PINGPONG_DISABLE_MASK 0x8000\n#define SQ_CONFIG__DUA_FLAT_LDS_PINGPONG_DISABLE__SHIFT 0xf\n#define SQC_CONFIG__INST_CACHE_SIZE_MASK 0x3\n#define SQC_CONFIG__INST_CACHE_SIZE__SHIFT 0x0\n#define SQC_CONFIG__DATA_CACHE_SIZE_MASK 0xc\n#define SQC_CONFIG__DATA_CACHE_SIZE__SHIFT 0x2\n#define SQC_CONFIG__MISS_FIFO_DEPTH_MASK 0x30\n#define SQC_CONFIG__MISS_FIFO_DEPTH__SHIFT 0x4\n#define SQC_CONFIG__HIT_FIFO_DEPTH_MASK 0x40\n#define SQC_CONFIG__HIT_FIFO_DEPTH__SHIFT 0x6\n#define SQC_CONFIG__FORCE_ALWAYS_MISS_MASK 0x80\n#define SQC_CONFIG__FORCE_ALWAYS_MISS__SHIFT 0x7\n#define SQC_CONFIG__FORCE_IN_ORDER_MASK 0x100\n#define SQC_CONFIG__FORCE_IN_ORDER__SHIFT 0x8\n#define SQC_CONFIG__IDENTITY_HASH_BANK_MASK 0x200\n#define SQC_CONFIG__IDENTITY_HASH_BANK__SHIFT 0x9\n#define SQC_CONFIG__IDENTITY_HASH_SET_MASK 0x400\n#define SQC_CONFIG__IDENTITY_HASH_SET__SHIFT 0xa\n#define SQC_CONFIG__PER_VMID_INV_DISABLE_MASK 0x800\n#define SQC_CONFIG__PER_VMID_INV_DISABLE__SHIFT 0xb\n#define SQC_CACHES__INST_INVALIDATE_MASK 0x1\n#define SQC_CACHES__INST_INVALIDATE__SHIFT 0x0\n#define SQC_CACHES__DATA_INVALIDATE_MASK 0x2\n#define SQC_CACHES__DATA_INVALIDATE__SHIFT 0x1\n#define SQC_CACHES__INVALIDATE_VOLATILE_MASK 0x4\n#define SQC_CACHES__INVALIDATE_VOLATILE__SHIFT 0x2\n#define SQ_RANDOM_WAVE_PRI__RET_MASK 0x7f\n#define SQ_RANDOM_WAVE_PRI__RET__SHIFT 0x0\n#define SQ_RANDOM_WAVE_PRI__RUI_MASK 0x380\n#define SQ_RANDOM_WAVE_PRI__RUI__SHIFT 0x7\n#define SQ_RANDOM_WAVE_PRI__RNG_MASK 0x1ffc00\n#define SQ_RANDOM_WAVE_PRI__RNG__SHIFT 0xa\n#define SQ_REG_CREDITS__SRBM_CREDITS_MASK 0x3f\n#define SQ_REG_CREDITS__SRBM_CREDITS__SHIFT 0x0\n#define SQ_REG_CREDITS__CMD_CREDITS_MASK 0xf00\n#define SQ_REG_CREDITS__CMD_CREDITS__SHIFT 0x8\n#define SQ_REG_CREDITS__REG_BUSY_MASK 0x10000000\n#define SQ_REG_CREDITS__REG_BUSY__SHIFT 0x1c\n#define SQ_REG_CREDITS__SRBM_OVERFLOW_MASK 0x20000000\n#define SQ_REG_CREDITS__SRBM_OVERFLOW__SHIFT 0x1d\n#define SQ_REG_CREDITS__IMMED_OVERFLOW_MASK 0x40000000\n#define SQ_REG_CREDITS__IMMED_OVERFLOW__SHIFT 0x1e\n#define SQ_REG_CREDITS__CMD_OVERFLOW_MASK 0x80000000\n#define SQ_REG_CREDITS__CMD_OVERFLOW__SHIFT 0x1f\n#define SQ_FIFO_SIZES__INTERRUPT_FIFO_SIZE_MASK 0xf\n#define SQ_FIFO_SIZES__INTERRUPT_FIFO_SIZE__SHIFT 0x0\n#define SQ_FIFO_SIZES__TTRACE_FIFO_SIZE_MASK 0xf00\n#define SQ_FIFO_SIZES__TTRACE_FIFO_SIZE__SHIFT 0x8\n#define SQ_FIFO_SIZES__EXPORT_BUF_SIZE_MASK 0x30000\n#define SQ_FIFO_SIZES__EXPORT_BUF_SIZE__SHIFT 0x10\n#define SQ_FIFO_SIZES__VMEM_DATA_FIFO_SIZE_MASK 0xc0000\n#define SQ_FIFO_SIZES__VMEM_DATA_FIFO_SIZE__SHIFT 0x12\n#define SQ_INTERRUPT_AUTO_MASK__MASK_MASK 0xffffff\n#define SQ_INTERRUPT_AUTO_MASK__MASK__SHIFT 0x0\n#define SQ_INTERRUPT_MSG_CTRL__STALL_MASK 0x1\n#define SQ_INTERRUPT_MSG_CTRL__STALL__SHIFT 0x0\n#define SQ_PERFCOUNTER_CTRL__PS_EN_MASK 0x1\n#define SQ_PERFCOUNTER_CTRL__PS_EN__SHIFT 0x0\n#define SQ_PERFCOUNTER_CTRL__VS_EN_MASK 0x2\n#define SQ_PERFCOUNTER_CTRL__VS_EN__SHIFT 0x1\n#define SQ_PERFCOUNTER_CTRL__GS_EN_MASK 0x4\n#define SQ_PERFCOUNTER_CTRL__GS_EN__SHIFT 0x2\n#define SQ_PERFCOUNTER_CTRL__ES_EN_MASK 0x8\n#define SQ_PERFCOUNTER_CTRL__ES_EN__SHIFT 0x3\n#define SQ_PERFCOUNTER_CTRL__HS_EN_MASK 0x10\n#define SQ_PERFCOUNTER_CTRL__HS_EN__SHIFT 0x4\n#define SQ_PERFCOUNTER_CTRL__LS_EN_MASK 0x20\n#define SQ_PERFCOUNTER_CTRL__LS_EN__SHIFT 0x5\n#define SQ_PERFCOUNTER_CTRL__CS_EN_MASK 0x40\n#define SQ_PERFCOUNTER_CTRL__CS_EN__SHIFT 0x6\n#define SQ_PERFCOUNTER_CTRL__CNTR_RATE_MASK 0x1f00\n#define SQ_PERFCOUNTER_CTRL__CNTR_RATE__SHIFT 0x8\n#define SQ_PERFCOUNTER_CTRL__DISABLE_FLUSH_MASK 0x2000\n#define SQ_PERFCOUNTER_CTRL__DISABLE_FLUSH__SHIFT 0xd\n#define SQ_PERFCOUNTER_MASK__SH0_MASK_MASK 0xffff\n#define SQ_PERFCOUNTER_MASK__SH0_MASK__SHIFT 0x0\n#define SQ_PERFCOUNTER_MASK__SH1_MASK_MASK 0xffff0000\n#define SQ_PERFCOUNTER_MASK__SH1_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER_CTRL2__FORCE_EN_MASK 0x1\n#define SQ_PERFCOUNTER_CTRL2__FORCE_EN__SHIFT 0x0\n#define CC_SQC_BANK_DISABLE__SQC0_BANK_DISABLE_MASK 0xf0000\n#define CC_SQC_BANK_DISABLE__SQC0_BANK_DISABLE__SHIFT 0x10\n#define CC_SQC_BANK_DISABLE__SQC1_BANK_DISABLE_MASK 0xf00000\n#define CC_SQC_BANK_DISABLE__SQC1_BANK_DISABLE__SHIFT 0x14\n#define CC_SQC_BANK_DISABLE__SQC2_BANK_DISABLE_MASK 0xf000000\n#define CC_SQC_BANK_DISABLE__SQC2_BANK_DISABLE__SHIFT 0x18\n#define CC_SQC_BANK_DISABLE__SQC3_BANK_DISABLE_MASK 0xf0000000\n#define CC_SQC_BANK_DISABLE__SQC3_BANK_DISABLE__SHIFT 0x1c\n#define USER_SQC_BANK_DISABLE__SQC0_BANK_DISABLE_MASK 0xf0000\n#define USER_SQC_BANK_DISABLE__SQC0_BANK_DISABLE__SHIFT 0x10\n#define USER_SQC_BANK_DISABLE__SQC1_BANK_DISABLE_MASK 0xf00000\n#define USER_SQC_BANK_DISABLE__SQC1_BANK_DISABLE__SHIFT 0x14\n#define USER_SQC_BANK_DISABLE__SQC2_BANK_DISABLE_MASK 0xf000000\n#define USER_SQC_BANK_DISABLE__SQC2_BANK_DISABLE__SHIFT 0x18\n#define USER_SQC_BANK_DISABLE__SQC3_BANK_DISABLE_MASK 0xf0000000\n#define USER_SQC_BANK_DISABLE__SQC3_BANK_DISABLE__SHIFT 0x1c\n#define SQ_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER4_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER4_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER5_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER5_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER6_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER6_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER7_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER7_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER8_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER8_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER9_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER9_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER10_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER10_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER11_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER11_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER12_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER12_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER13_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER13_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER14_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER14_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER15_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SQ_PERFCOUNTER15_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SQ_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER4_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER4_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER5_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER5_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER6_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER6_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER7_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER7_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER8_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER8_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER9_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER9_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER10_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER10_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER11_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER11_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER12_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER12_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER13_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER13_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER14_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER14_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER15_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SQ_PERFCOUNTER15_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SQ_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER0_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER0_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER0_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER0_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER0_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER0_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER0_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER0_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER1_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER1_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER1_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER1_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER1_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER1_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER1_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER1_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER2_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER2_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER2_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER2_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER2_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER2_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER2_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER2_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER3_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER3_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER3_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER3_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER3_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER3_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER3_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER3_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER4_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER4_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER4_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER4_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER4_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER4_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER4_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER4_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER4_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER4_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER4_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER4_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER5_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER5_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER5_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER5_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER5_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER5_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER5_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER5_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER5_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER5_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER5_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER5_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER6_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER6_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER6_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER6_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER6_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER6_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER6_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER6_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER6_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER6_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER6_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER6_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER7_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER7_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER7_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER7_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER7_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER7_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER7_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER7_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER7_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER7_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER7_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER7_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER8_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER8_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER8_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER8_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER8_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER8_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER8_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER8_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER8_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER8_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER8_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER8_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER9_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER9_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER9_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER9_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER9_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER9_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER9_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER9_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER9_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER9_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER9_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER9_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER10_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER10_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER10_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER10_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER10_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER10_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER10_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER10_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER10_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER10_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER10_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER10_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER11_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER11_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER11_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER11_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER11_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER11_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER11_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER11_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER11_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER11_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER11_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER11_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER12_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER12_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER12_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER12_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER12_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER12_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER12_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER12_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER12_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER12_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER12_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER12_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER13_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER13_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER13_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER13_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER13_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER13_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER13_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER13_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER13_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER13_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER13_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER13_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER14_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER14_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER14_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER14_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER14_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER14_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER14_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER14_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER14_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER14_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER14_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER14_SELECT__PERF_MODE__SHIFT 0x1c\n#define SQ_PERFCOUNTER15_SELECT__PERF_SEL_MASK 0xff\n#define SQ_PERFCOUNTER15_SELECT__PERF_SEL__SHIFT 0x0\n#define SQ_PERFCOUNTER15_SELECT__SQC_BANK_MASK_MASK 0xf000\n#define SQ_PERFCOUNTER15_SELECT__SQC_BANK_MASK__SHIFT 0xc\n#define SQ_PERFCOUNTER15_SELECT__SQC_CLIENT_MASK_MASK 0xf0000\n#define SQ_PERFCOUNTER15_SELECT__SQC_CLIENT_MASK__SHIFT 0x10\n#define SQ_PERFCOUNTER15_SELECT__SPM_MODE_MASK 0xf00000\n#define SQ_PERFCOUNTER15_SELECT__SPM_MODE__SHIFT 0x14\n#define SQ_PERFCOUNTER15_SELECT__SIMD_MASK_MASK 0xf000000\n#define SQ_PERFCOUNTER15_SELECT__SIMD_MASK__SHIFT 0x18\n#define SQ_PERFCOUNTER15_SELECT__PERF_MODE_MASK 0xf0000000\n#define SQ_PERFCOUNTER15_SELECT__PERF_MODE__SHIFT 0x1c\n#define CGTT_SQ_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_SQ_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_SQ_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SQ_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SQ_CLK_CTRL__CORE_OVERRIDE_MASK 0x40000000\n#define CGTT_SQ_CLK_CTRL__CORE_OVERRIDE__SHIFT 0x1e\n#define CGTT_SQ_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_SQ_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define CGTT_SQG_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_SQG_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_SQG_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SQG_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SQG_CLK_CTRL__CORE_OVERRIDE_MASK 0x40000000\n#define CGTT_SQG_CLK_CTRL__CORE_OVERRIDE__SHIFT 0x1e\n#define CGTT_SQG_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_SQG_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define SQ_ALU_CLK_CTRL__FORCE_CU_ON_SH0_MASK 0xffff\n#define SQ_ALU_CLK_CTRL__FORCE_CU_ON_SH0__SHIFT 0x0\n#define SQ_ALU_CLK_CTRL__FORCE_CU_ON_SH1_MASK 0xffff0000\n#define SQ_ALU_CLK_CTRL__FORCE_CU_ON_SH1__SHIFT 0x10\n#define SQ_TEX_CLK_CTRL__FORCE_CU_ON_SH0_MASK 0xffff\n#define SQ_TEX_CLK_CTRL__FORCE_CU_ON_SH0__SHIFT 0x0\n#define SQ_TEX_CLK_CTRL__FORCE_CU_ON_SH1_MASK 0xffff0000\n#define SQ_TEX_CLK_CTRL__FORCE_CU_ON_SH1__SHIFT 0x10\n#define SQ_LDS_CLK_CTRL__FORCE_CU_ON_SH0_MASK 0xffff\n#define SQ_LDS_CLK_CTRL__FORCE_CU_ON_SH0__SHIFT 0x0\n#define SQ_LDS_CLK_CTRL__FORCE_CU_ON_SH1_MASK 0xffff0000\n#define SQ_LDS_CLK_CTRL__FORCE_CU_ON_SH1__SHIFT 0x10\n#define SQ_POWER_THROTTLE__MIN_POWER_MASK 0x3fff\n#define SQ_POWER_THROTTLE__MIN_POWER__SHIFT 0x0\n#define SQ_POWER_THROTTLE__MAX_POWER_MASK 0x3fff0000\n#define SQ_POWER_THROTTLE__MAX_POWER__SHIFT 0x10\n#define SQ_POWER_THROTTLE__PHASE_OFFSET_MASK 0xc0000000\n#define SQ_POWER_THROTTLE__PHASE_OFFSET__SHIFT 0x1e\n#define SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK 0x3fff\n#define SQ_POWER_THROTTLE2__MAX_POWER_DELTA__SHIFT 0x0\n#define SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK 0x3ff0000\n#define SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE__SHIFT 0x10\n#define SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK 0x78000000\n#define SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO__SHIFT 0x1b\n#define SQ_POWER_THROTTLE2__USE_REF_CLOCK_MASK 0x80000000\n#define SQ_POWER_THROTTLE2__USE_REF_CLOCK__SHIFT 0x1f\n#define SQ_TIME_HI__TIME_MASK 0xffffffff\n#define SQ_TIME_HI__TIME__SHIFT 0x0\n#define SQ_TIME_LO__TIME_MASK 0xffffffff\n#define SQ_TIME_LO__TIME__SHIFT 0x0\n#define SQ_THREAD_TRACE_BASE__ADDR_MASK 0xffffffff\n#define SQ_THREAD_TRACE_BASE__ADDR__SHIFT 0x0\n#define SQ_THREAD_TRACE_BASE2__ADDR_HI_MASK 0xf\n#define SQ_THREAD_TRACE_BASE2__ADDR_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_BASE2__ATC_MASK 0x10\n#define SQ_THREAD_TRACE_BASE2__ATC__SHIFT 0x4\n#define SQ_THREAD_TRACE_SIZE__SIZE_MASK 0x3fffff\n#define SQ_THREAD_TRACE_SIZE__SIZE__SHIFT 0x0\n#define SQ_THREAD_TRACE_MASK__CU_SEL_MASK 0x1f\n#define SQ_THREAD_TRACE_MASK__CU_SEL__SHIFT 0x0\n#define SQ_THREAD_TRACE_MASK__SH_SEL_MASK 0x20\n#define SQ_THREAD_TRACE_MASK__SH_SEL__SHIFT 0x5\n#define SQ_THREAD_TRACE_MASK__REG_STALL_EN_MASK 0x80\n#define SQ_THREAD_TRACE_MASK__REG_STALL_EN__SHIFT 0x7\n#define SQ_THREAD_TRACE_MASK__SIMD_EN_MASK 0xf00\n#define SQ_THREAD_TRACE_MASK__SIMD_EN__SHIFT 0x8\n#define SQ_THREAD_TRACE_MASK__VM_ID_MASK_MASK 0x3000\n#define SQ_THREAD_TRACE_MASK__VM_ID_MASK__SHIFT 0xc\n#define SQ_THREAD_TRACE_MASK__SPI_STALL_EN_MASK 0x4000\n#define SQ_THREAD_TRACE_MASK__SPI_STALL_EN__SHIFT 0xe\n#define SQ_THREAD_TRACE_MASK__SQ_STALL_EN_MASK 0x8000\n#define SQ_THREAD_TRACE_MASK__SQ_STALL_EN__SHIFT 0xf\n#define SQ_THREAD_TRACE_MASK__RANDOM_SEED_MASK 0xffff0000\n#define SQ_THREAD_TRACE_MASK__RANDOM_SEED__SHIFT 0x10\n#define SQ_THREAD_TRACE_USERDATA_0__DATA_MASK 0xffffffff\n#define SQ_THREAD_TRACE_USERDATA_0__DATA__SHIFT 0x0\n#define SQ_THREAD_TRACE_USERDATA_1__DATA_MASK 0xffffffff\n#define SQ_THREAD_TRACE_USERDATA_1__DATA__SHIFT 0x0\n#define SQ_THREAD_TRACE_USERDATA_2__DATA_MASK 0xffffffff\n#define SQ_THREAD_TRACE_USERDATA_2__DATA__SHIFT 0x0\n#define SQ_THREAD_TRACE_USERDATA_3__DATA_MASK 0xffffffff\n#define SQ_THREAD_TRACE_USERDATA_3__DATA__SHIFT 0x0\n#define SQ_THREAD_TRACE_MODE__MASK_PS_MASK 0x7\n#define SQ_THREAD_TRACE_MODE__MASK_PS__SHIFT 0x0\n#define SQ_THREAD_TRACE_MODE__MASK_VS_MASK 0x38\n#define SQ_THREAD_TRACE_MODE__MASK_VS__SHIFT 0x3\n#define SQ_THREAD_TRACE_MODE__MASK_GS_MASK 0x1c0\n#define SQ_THREAD_TRACE_MODE__MASK_GS__SHIFT 0x6\n#define SQ_THREAD_TRACE_MODE__MASK_ES_MASK 0xe00\n#define SQ_THREAD_TRACE_MODE__MASK_ES__SHIFT 0x9\n#define SQ_THREAD_TRACE_MODE__MASK_HS_MASK 0x7000\n#define SQ_THREAD_TRACE_MODE__MASK_HS__SHIFT 0xc\n#define SQ_THREAD_TRACE_MODE__MASK_LS_MASK 0x38000\n#define SQ_THREAD_TRACE_MODE__MASK_LS__SHIFT 0xf\n#define SQ_THREAD_TRACE_MODE__MASK_CS_MASK 0x1c0000\n#define SQ_THREAD_TRACE_MODE__MASK_CS__SHIFT 0x12\n#define SQ_THREAD_TRACE_MODE__MODE_MASK 0x600000\n#define SQ_THREAD_TRACE_MODE__MODE__SHIFT 0x15\n#define SQ_THREAD_TRACE_MODE__CAPTURE_MODE_MASK 0x1800000\n#define SQ_THREAD_TRACE_MODE__CAPTURE_MODE__SHIFT 0x17\n#define SQ_THREAD_TRACE_MODE__AUTOFLUSH_EN_MASK 0x2000000\n#define SQ_THREAD_TRACE_MODE__AUTOFLUSH_EN__SHIFT 0x19\n#define SQ_THREAD_TRACE_MODE__PRIV_MASK 0x4000000\n#define SQ_THREAD_TRACE_MODE__PRIV__SHIFT 0x1a\n#define SQ_THREAD_TRACE_MODE__ISSUE_MASK_MASK 0x18000000\n#define SQ_THREAD_TRACE_MODE__ISSUE_MASK__SHIFT 0x1b\n#define SQ_THREAD_TRACE_MODE__TEST_MODE_MASK 0x20000000\n#define SQ_THREAD_TRACE_MODE__TEST_MODE__SHIFT 0x1d\n#define SQ_THREAD_TRACE_MODE__INTERRUPT_EN_MASK 0x40000000\n#define SQ_THREAD_TRACE_MODE__INTERRUPT_EN__SHIFT 0x1e\n#define SQ_THREAD_TRACE_MODE__WRAP_MASK 0x80000000\n#define SQ_THREAD_TRACE_MODE__WRAP__SHIFT 0x1f\n#define SQ_THREAD_TRACE_CTRL__RESET_BUFFER_MASK 0x80000000\n#define SQ_THREAD_TRACE_CTRL__RESET_BUFFER__SHIFT 0x1f\n#define SQ_THREAD_TRACE_TOKEN_MASK__TOKEN_MASK_MASK 0xffff\n#define SQ_THREAD_TRACE_TOKEN_MASK__TOKEN_MASK__SHIFT 0x0\n#define SQ_THREAD_TRACE_TOKEN_MASK__REG_MASK_MASK 0xff0000\n#define SQ_THREAD_TRACE_TOKEN_MASK__REG_MASK__SHIFT 0x10\n#define SQ_THREAD_TRACE_TOKEN_MASK__REG_DROP_ON_STALL_MASK 0x1000000\n#define SQ_THREAD_TRACE_TOKEN_MASK__REG_DROP_ON_STALL__SHIFT 0x18\n#define SQ_THREAD_TRACE_TOKEN_MASK2__INST_MASK_MASK 0xffff\n#define SQ_THREAD_TRACE_TOKEN_MASK2__INST_MASK__SHIFT 0x0\n#define SQ_THREAD_TRACE_PERF_MASK__SH0_MASK_MASK 0xffff\n#define SQ_THREAD_TRACE_PERF_MASK__SH0_MASK__SHIFT 0x0\n#define SQ_THREAD_TRACE_PERF_MASK__SH1_MASK_MASK 0xffff0000\n#define SQ_THREAD_TRACE_PERF_MASK__SH1_MASK__SHIFT 0x10\n#define SQ_THREAD_TRACE_WPTR__WPTR_MASK 0x3fffffff\n#define SQ_THREAD_TRACE_WPTR__WPTR__SHIFT 0x0\n#define SQ_THREAD_TRACE_WPTR__READ_OFFSET_MASK 0xc0000000\n#define SQ_THREAD_TRACE_WPTR__READ_OFFSET__SHIFT 0x1e\n#define SQ_THREAD_TRACE_STATUS__FINISH_PENDING_MASK 0x3ff\n#define SQ_THREAD_TRACE_STATUS__FINISH_PENDING__SHIFT 0x0\n#define SQ_THREAD_TRACE_STATUS__FINISH_DONE_MASK 0x3ff0000\n#define SQ_THREAD_TRACE_STATUS__FINISH_DONE__SHIFT 0x10\n#define SQ_THREAD_TRACE_STATUS__NEW_BUF_MASK 0x20000000\n#define SQ_THREAD_TRACE_STATUS__NEW_BUF__SHIFT 0x1d\n#define SQ_THREAD_TRACE_STATUS__BUSY_MASK 0x40000000\n#define SQ_THREAD_TRACE_STATUS__BUSY__SHIFT 0x1e\n#define SQ_THREAD_TRACE_STATUS__FULL_MASK 0x80000000\n#define SQ_THREAD_TRACE_STATUS__FULL__SHIFT 0x1f\n#define SQ_THREAD_TRACE_CNTR__CNTR_MASK 0xffffffff\n#define SQ_THREAD_TRACE_CNTR__CNTR__SHIFT 0x0\n#define SQ_THREAD_TRACE_HIWATER__HIWATER_MASK 0x7\n#define SQ_THREAD_TRACE_HIWATER__HIWATER__SHIFT 0x0\n#define SQ_LB_CTR_CTRL__START_MASK 0x1\n#define SQ_LB_CTR_CTRL__START__SHIFT 0x0\n#define SQ_LB_CTR_CTRL__LOAD_MASK 0x2\n#define SQ_LB_CTR_CTRL__LOAD__SHIFT 0x1\n#define SQ_LB_CTR_CTRL__CLEAR_MASK 0x4\n#define SQ_LB_CTR_CTRL__CLEAR__SHIFT 0x2\n#define SQ_LB_DATA_ALU_CYCLES__DATA_MASK 0xffffffff\n#define SQ_LB_DATA_ALU_CYCLES__DATA__SHIFT 0x0\n#define SQ_LB_DATA_TEX_CYCLES__DATA_MASK 0xffffffff\n#define SQ_LB_DATA_TEX_CYCLES__DATA__SHIFT 0x0\n#define SQ_LB_DATA_ALU_STALLS__DATA_MASK 0xffffffff\n#define SQ_LB_DATA_ALU_STALLS__DATA__SHIFT 0x0\n#define SQ_LB_DATA_TEX_STALLS__DATA_MASK 0xffffffff\n#define SQ_LB_DATA_TEX_STALLS__DATA__SHIFT 0x0\n#define SQC_SECDED_CNT__INST_SEC_MASK 0xff\n#define SQC_SECDED_CNT__INST_SEC__SHIFT 0x0\n#define SQC_SECDED_CNT__INST_DED_MASK 0xff00\n#define SQC_SECDED_CNT__INST_DED__SHIFT 0x8\n#define SQC_SECDED_CNT__DATA_SEC_MASK 0xff0000\n#define SQC_SECDED_CNT__DATA_SEC__SHIFT 0x10\n#define SQC_SECDED_CNT__DATA_DED_MASK 0xff000000\n#define SQC_SECDED_CNT__DATA_DED__SHIFT 0x18\n#define SQ_SEC_CNT__LDS_SEC_MASK 0x3f\n#define SQ_SEC_CNT__LDS_SEC__SHIFT 0x0\n#define SQ_SEC_CNT__SGPR_SEC_MASK 0x1f00\n#define SQ_SEC_CNT__SGPR_SEC__SHIFT 0x8\n#define SQ_SEC_CNT__VGPR_SEC_MASK 0x1ff0000\n#define SQ_SEC_CNT__VGPR_SEC__SHIFT 0x10\n#define SQ_DED_CNT__LDS_DED_MASK 0x3f\n#define SQ_DED_CNT__LDS_DED__SHIFT 0x0\n#define SQ_DED_CNT__SGPR_DED_MASK 0x1f00\n#define SQ_DED_CNT__SGPR_DED__SHIFT 0x8\n#define SQ_DED_CNT__VGPR_DED_MASK 0x1ff0000\n#define SQ_DED_CNT__VGPR_DED__SHIFT 0x10\n#define SQ_DED_INFO__WAVE_ID_MASK 0xf\n#define SQ_DED_INFO__WAVE_ID__SHIFT 0x0\n#define SQ_DED_INFO__SIMD_ID_MASK 0x30\n#define SQ_DED_INFO__SIMD_ID__SHIFT 0x4\n#define SQ_DED_INFO__SOURCE_MASK 0x1c0\n#define SQ_DED_INFO__SOURCE__SHIFT 0x6\n#define SQ_DED_INFO__VM_ID_MASK 0x1e00\n#define SQ_DED_INFO__VM_ID__SHIFT 0x9\n#define SQ_BUF_RSRC_WORD0__BASE_ADDRESS_MASK 0xffffffff\n#define SQ_BUF_RSRC_WORD0__BASE_ADDRESS__SHIFT 0x0\n#define SQ_BUF_RSRC_WORD1__BASE_ADDRESS_HI_MASK 0xffff\n#define SQ_BUF_RSRC_WORD1__BASE_ADDRESS_HI__SHIFT 0x0\n#define SQ_BUF_RSRC_WORD1__STRIDE_MASK 0x3fff0000\n#define SQ_BUF_RSRC_WORD1__STRIDE__SHIFT 0x10\n#define SQ_BUF_RSRC_WORD1__CACHE_SWIZZLE_MASK 0x40000000\n#define SQ_BUF_RSRC_WORD1__CACHE_SWIZZLE__SHIFT 0x1e\n#define SQ_BUF_RSRC_WORD1__SWIZZLE_ENABLE_MASK 0x80000000\n#define SQ_BUF_RSRC_WORD1__SWIZZLE_ENABLE__SHIFT 0x1f\n#define SQ_BUF_RSRC_WORD2__NUM_RECORDS_MASK 0xffffffff\n#define SQ_BUF_RSRC_WORD2__NUM_RECORDS__SHIFT 0x0\n#define SQ_BUF_RSRC_WORD3__DST_SEL_X_MASK 0x7\n#define SQ_BUF_RSRC_WORD3__DST_SEL_X__SHIFT 0x0\n#define SQ_BUF_RSRC_WORD3__DST_SEL_Y_MASK 0x38\n#define SQ_BUF_RSRC_WORD3__DST_SEL_Y__SHIFT 0x3\n#define SQ_BUF_RSRC_WORD3__DST_SEL_Z_MASK 0x1c0\n#define SQ_BUF_RSRC_WORD3__DST_SEL_Z__SHIFT 0x6\n#define SQ_BUF_RSRC_WORD3__DST_SEL_W_MASK 0xe00\n#define SQ_BUF_RSRC_WORD3__DST_SEL_W__SHIFT 0x9\n#define SQ_BUF_RSRC_WORD3__NUM_FORMAT_MASK 0x7000\n#define SQ_BUF_RSRC_WORD3__NUM_FORMAT__SHIFT 0xc\n#define SQ_BUF_RSRC_WORD3__DATA_FORMAT_MASK 0x78000\n#define SQ_BUF_RSRC_WORD3__DATA_FORMAT__SHIFT 0xf\n#define SQ_BUF_RSRC_WORD3__ELEMENT_SIZE_MASK 0x180000\n#define SQ_BUF_RSRC_WORD3__ELEMENT_SIZE__SHIFT 0x13\n#define SQ_BUF_RSRC_WORD3__INDEX_STRIDE_MASK 0x600000\n#define SQ_BUF_RSRC_WORD3__INDEX_STRIDE__SHIFT 0x15\n#define SQ_BUF_RSRC_WORD3__ADD_TID_ENABLE_MASK 0x800000\n#define SQ_BUF_RSRC_WORD3__ADD_TID_ENABLE__SHIFT 0x17\n#define SQ_BUF_RSRC_WORD3__ATC_MASK 0x1000000\n#define SQ_BUF_RSRC_WORD3__ATC__SHIFT 0x18\n#define SQ_BUF_RSRC_WORD3__HASH_ENABLE_MASK 0x2000000\n#define SQ_BUF_RSRC_WORD3__HASH_ENABLE__SHIFT 0x19\n#define SQ_BUF_RSRC_WORD3__HEAP_MASK 0x4000000\n#define SQ_BUF_RSRC_WORD3__HEAP__SHIFT 0x1a\n#define SQ_BUF_RSRC_WORD3__MTYPE_MASK 0x38000000\n#define SQ_BUF_RSRC_WORD3__MTYPE__SHIFT 0x1b\n#define SQ_BUF_RSRC_WORD3__TYPE_MASK 0xc0000000\n#define SQ_BUF_RSRC_WORD3__TYPE__SHIFT 0x1e\n#define SQ_IMG_RSRC_WORD0__BASE_ADDRESS_MASK 0xffffffff\n#define SQ_IMG_RSRC_WORD0__BASE_ADDRESS__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD1__BASE_ADDRESS_HI_MASK 0xff\n#define SQ_IMG_RSRC_WORD1__BASE_ADDRESS_HI__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD1__MIN_LOD_MASK 0xfff00\n#define SQ_IMG_RSRC_WORD1__MIN_LOD__SHIFT 0x8\n#define SQ_IMG_RSRC_WORD1__DATA_FORMAT_MASK 0x3f00000\n#define SQ_IMG_RSRC_WORD1__DATA_FORMAT__SHIFT 0x14\n#define SQ_IMG_RSRC_WORD1__NUM_FORMAT_MASK 0x3c000000\n#define SQ_IMG_RSRC_WORD1__NUM_FORMAT__SHIFT 0x1a\n#define SQ_IMG_RSRC_WORD1__MTYPE_MASK 0xc0000000\n#define SQ_IMG_RSRC_WORD1__MTYPE__SHIFT 0x1e\n#define SQ_IMG_RSRC_WORD2__WIDTH_MASK 0x3fff\n#define SQ_IMG_RSRC_WORD2__WIDTH__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD2__HEIGHT_MASK 0xfffc000\n#define SQ_IMG_RSRC_WORD2__HEIGHT__SHIFT 0xe\n#define SQ_IMG_RSRC_WORD2__PERF_MOD_MASK 0x70000000\n#define SQ_IMG_RSRC_WORD2__PERF_MOD__SHIFT 0x1c\n#define SQ_IMG_RSRC_WORD2__INTERLACED_MASK 0x80000000\n#define SQ_IMG_RSRC_WORD2__INTERLACED__SHIFT 0x1f\n#define SQ_IMG_RSRC_WORD3__DST_SEL_X_MASK 0x7\n#define SQ_IMG_RSRC_WORD3__DST_SEL_X__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD3__DST_SEL_Y_MASK 0x38\n#define SQ_IMG_RSRC_WORD3__DST_SEL_Y__SHIFT 0x3\n#define SQ_IMG_RSRC_WORD3__DST_SEL_Z_MASK 0x1c0\n#define SQ_IMG_RSRC_WORD3__DST_SEL_Z__SHIFT 0x6\n#define SQ_IMG_RSRC_WORD3__DST_SEL_W_MASK 0xe00\n#define SQ_IMG_RSRC_WORD3__DST_SEL_W__SHIFT 0x9\n#define SQ_IMG_RSRC_WORD3__BASE_LEVEL_MASK 0xf000\n#define SQ_IMG_RSRC_WORD3__BASE_LEVEL__SHIFT 0xc\n#define SQ_IMG_RSRC_WORD3__LAST_LEVEL_MASK 0xf0000\n#define SQ_IMG_RSRC_WORD3__LAST_LEVEL__SHIFT 0x10\n#define SQ_IMG_RSRC_WORD3__TILING_INDEX_MASK 0x1f00000\n#define SQ_IMG_RSRC_WORD3__TILING_INDEX__SHIFT 0x14\n#define SQ_IMG_RSRC_WORD3__POW2_PAD_MASK 0x2000000\n#define SQ_IMG_RSRC_WORD3__POW2_PAD__SHIFT 0x19\n#define SQ_IMG_RSRC_WORD3__MTYPE_MASK 0x4000000\n#define SQ_IMG_RSRC_WORD3__MTYPE__SHIFT 0x1a\n#define SQ_IMG_RSRC_WORD3__ATC_MASK 0x8000000\n#define SQ_IMG_RSRC_WORD3__ATC__SHIFT 0x1b\n#define SQ_IMG_RSRC_WORD3__TYPE_MASK 0xf0000000\n#define SQ_IMG_RSRC_WORD3__TYPE__SHIFT 0x1c\n#define SQ_IMG_RSRC_WORD4__DEPTH_MASK 0x1fff\n#define SQ_IMG_RSRC_WORD4__DEPTH__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD4__PITCH_MASK 0x7ffe000\n#define SQ_IMG_RSRC_WORD4__PITCH__SHIFT 0xd\n#define SQ_IMG_RSRC_WORD5__BASE_ARRAY_MASK 0x1fff\n#define SQ_IMG_RSRC_WORD5__BASE_ARRAY__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD5__LAST_ARRAY_MASK 0x3ffe000\n#define SQ_IMG_RSRC_WORD5__LAST_ARRAY__SHIFT 0xd\n#define SQ_IMG_RSRC_WORD6__MIN_LOD_WARN_MASK 0xfff\n#define SQ_IMG_RSRC_WORD6__MIN_LOD_WARN__SHIFT 0x0\n#define SQ_IMG_RSRC_WORD6__COUNTER_BANK_ID_MASK 0xff000\n#define SQ_IMG_RSRC_WORD6__COUNTER_BANK_ID__SHIFT 0xc\n#define SQ_IMG_RSRC_WORD6__LOD_HDW_CNT_EN_MASK 0x100000\n#define SQ_IMG_RSRC_WORD6__LOD_HDW_CNT_EN__SHIFT 0x14\n#define SQ_IMG_RSRC_WORD6__UNUNSED_MASK 0xffe00000\n#define SQ_IMG_RSRC_WORD6__UNUNSED__SHIFT 0x15\n#define SQ_IMG_RSRC_WORD7__UNUNSED_MASK 0xffffffff\n#define SQ_IMG_RSRC_WORD7__UNUNSED__SHIFT 0x0\n#define SQ_IMG_SAMP_WORD0__CLAMP_X_MASK 0x7\n#define SQ_IMG_SAMP_WORD0__CLAMP_X__SHIFT 0x0\n#define SQ_IMG_SAMP_WORD0__CLAMP_Y_MASK 0x38\n#define SQ_IMG_SAMP_WORD0__CLAMP_Y__SHIFT 0x3\n#define SQ_IMG_SAMP_WORD0__CLAMP_Z_MASK 0x1c0\n#define SQ_IMG_SAMP_WORD0__CLAMP_Z__SHIFT 0x6\n#define SQ_IMG_SAMP_WORD0__MAX_ANISO_RATIO_MASK 0xe00\n#define SQ_IMG_SAMP_WORD0__MAX_ANISO_RATIO__SHIFT 0x9\n#define SQ_IMG_SAMP_WORD0__DEPTH_COMPARE_FUNC_MASK 0x7000\n#define SQ_IMG_SAMP_WORD0__DEPTH_COMPARE_FUNC__SHIFT 0xc\n#define SQ_IMG_SAMP_WORD0__FORCE_UNNORMALIZED_MASK 0x8000\n#define SQ_IMG_SAMP_WORD0__FORCE_UNNORMALIZED__SHIFT 0xf\n#define SQ_IMG_SAMP_WORD0__ANISO_THRESHOLD_MASK 0x70000\n#define SQ_IMG_SAMP_WORD0__ANISO_THRESHOLD__SHIFT 0x10\n#define SQ_IMG_SAMP_WORD0__MC_COORD_TRUNC_MASK 0x80000\n#define SQ_IMG_SAMP_WORD0__MC_COORD_TRUNC__SHIFT 0x13\n#define SQ_IMG_SAMP_WORD0__FORCE_DEGAMMA_MASK 0x100000\n#define SQ_IMG_SAMP_WORD0__FORCE_DEGAMMA__SHIFT 0x14\n#define SQ_IMG_SAMP_WORD0__ANISO_BIAS_MASK 0x7e00000\n#define SQ_IMG_SAMP_WORD0__ANISO_BIAS__SHIFT 0x15\n#define SQ_IMG_SAMP_WORD0__TRUNC_COORD_MASK 0x8000000\n#define SQ_IMG_SAMP_WORD0__TRUNC_COORD__SHIFT 0x1b\n#define SQ_IMG_SAMP_WORD0__DISABLE_CUBE_WRAP_MASK 0x10000000\n#define SQ_IMG_SAMP_WORD0__DISABLE_CUBE_WRAP__SHIFT 0x1c\n#define SQ_IMG_SAMP_WORD0__FILTER_MODE_MASK 0x60000000\n#define SQ_IMG_SAMP_WORD0__FILTER_MODE__SHIFT 0x1d\n#define SQ_IMG_SAMP_WORD1__MIN_LOD_MASK 0xfff\n#define SQ_IMG_SAMP_WORD1__MIN_LOD__SHIFT 0x0\n#define SQ_IMG_SAMP_WORD1__MAX_LOD_MASK 0xfff000\n#define SQ_IMG_SAMP_WORD1__MAX_LOD__SHIFT 0xc\n#define SQ_IMG_SAMP_WORD1__PERF_MIP_MASK 0xf000000\n#define SQ_IMG_SAMP_WORD1__PERF_MIP__SHIFT 0x18\n#define SQ_IMG_SAMP_WORD1__PERF_Z_MASK 0xf0000000\n#define SQ_IMG_SAMP_WORD1__PERF_Z__SHIFT 0x1c\n#define SQ_IMG_SAMP_WORD2__LOD_BIAS_MASK 0x3fff\n#define SQ_IMG_SAMP_WORD2__LOD_BIAS__SHIFT 0x0\n#define SQ_IMG_SAMP_WORD2__LOD_BIAS_SEC_MASK 0xfc000\n#define SQ_IMG_SAMP_WORD2__LOD_BIAS_SEC__SHIFT 0xe\n#define SQ_IMG_SAMP_WORD2__XY_MAG_FILTER_MASK 0x300000\n#define SQ_IMG_SAMP_WORD2__XY_MAG_FILTER__SHIFT 0x14\n#define SQ_IMG_SAMP_WORD2__XY_MIN_FILTER_MASK 0xc00000\n#define SQ_IMG_SAMP_WORD2__XY_MIN_FILTER__SHIFT 0x16\n#define SQ_IMG_SAMP_WORD2__Z_FILTER_MASK 0x3000000\n#define SQ_IMG_SAMP_WORD2__Z_FILTER__SHIFT 0x18\n#define SQ_IMG_SAMP_WORD2__MIP_FILTER_MASK 0xc000000\n#define SQ_IMG_SAMP_WORD2__MIP_FILTER__SHIFT 0x1a\n#define SQ_IMG_SAMP_WORD2__MIP_POINT_PRECLAMP_MASK 0x10000000\n#define SQ_IMG_SAMP_WORD2__MIP_POINT_PRECLAMP__SHIFT 0x1c\n#define SQ_IMG_SAMP_WORD2__DISABLE_LSB_CEIL_MASK 0x20000000\n#define SQ_IMG_SAMP_WORD2__DISABLE_LSB_CEIL__SHIFT 0x1d\n#define SQ_IMG_SAMP_WORD2__FILTER_PREC_FIX_MASK 0x40000000\n#define SQ_IMG_SAMP_WORD2__FILTER_PREC_FIX__SHIFT 0x1e\n#define SQ_IMG_SAMP_WORD3__BORDER_COLOR_PTR_MASK 0xfff\n#define SQ_IMG_SAMP_WORD3__BORDER_COLOR_PTR__SHIFT 0x0\n#define SQ_IMG_SAMP_WORD3__BORDER_COLOR_TYPE_MASK 0xc0000000\n#define SQ_IMG_SAMP_WORD3__BORDER_COLOR_TYPE__SHIFT 0x1e\n#define SQ_FLAT_SCRATCH_WORD0__SIZE_MASK 0x7ffff\n#define SQ_FLAT_SCRATCH_WORD0__SIZE__SHIFT 0x0\n#define SQ_FLAT_SCRATCH_WORD1__OFFSET_MASK 0xffffff\n#define SQ_FLAT_SCRATCH_WORD1__OFFSET__SHIFT 0x0\n#define SQ_IND_INDEX__WAVE_ID_MASK 0xf\n#define SQ_IND_INDEX__WAVE_ID__SHIFT 0x0\n#define SQ_IND_INDEX__SIMD_ID_MASK 0x30\n#define SQ_IND_INDEX__SIMD_ID__SHIFT 0x4\n#define SQ_IND_INDEX__THREAD_ID_MASK 0xfc0\n#define SQ_IND_INDEX__THREAD_ID__SHIFT 0x6\n#define SQ_IND_INDEX__AUTO_INCR_MASK 0x1000\n#define SQ_IND_INDEX__AUTO_INCR__SHIFT 0xc\n#define SQ_IND_INDEX__FORCE_READ_MASK 0x2000\n#define SQ_IND_INDEX__FORCE_READ__SHIFT 0xd\n#define SQ_IND_INDEX__READ_TIMEOUT_MASK 0x4000\n#define SQ_IND_INDEX__READ_TIMEOUT__SHIFT 0xe\n#define SQ_IND_INDEX__UNINDEXED_MASK 0x8000\n#define SQ_IND_INDEX__UNINDEXED__SHIFT 0xf\n#define SQ_IND_INDEX__INDEX_MASK 0xffff0000\n#define SQ_IND_INDEX__INDEX__SHIFT 0x10\n#define SQ_CMD__CMD_MASK 0x7\n#define SQ_CMD__CMD__SHIFT 0x0\n#define SQ_CMD__MODE_MASK 0x70\n#define SQ_CMD__MODE__SHIFT 0x4\n#define SQ_CMD__CHECK_VMID_MASK 0x80\n#define SQ_CMD__CHECK_VMID__SHIFT 0x7\n#define SQ_CMD__TRAP_ID_MASK 0x700\n#define SQ_CMD__TRAP_ID__SHIFT 0x8\n#define SQ_CMD__WAVE_ID_MASK 0xf0000\n#define SQ_CMD__WAVE_ID__SHIFT 0x10\n#define SQ_CMD__SIMD_ID_MASK 0x300000\n#define SQ_CMD__SIMD_ID__SHIFT 0x14\n#define SQ_CMD__QUEUE_ID_MASK 0x7000000\n#define SQ_CMD__QUEUE_ID__SHIFT 0x18\n#define SQ_CMD__VM_ID_MASK 0xf0000000\n#define SQ_CMD__VM_ID__SHIFT 0x1c\n#define SQ_IND_DATA__DATA_MASK 0xffffffff\n#define SQ_IND_DATA__DATA__SHIFT 0x0\n#define SQ_REG_TIMESTAMP__TIMESTAMP_MASK 0xff\n#define SQ_REG_TIMESTAMP__TIMESTAMP__SHIFT 0x0\n#define SQ_CMD_TIMESTAMP__TIMESTAMP_MASK 0xff\n#define SQ_CMD_TIMESTAMP__TIMESTAMP__SHIFT 0x0\n#define SQ_HV_VMID_CTRL__DEFAULT_VMID_MASK 0xf\n#define SQ_HV_VMID_CTRL__DEFAULT_VMID__SHIFT 0x0\n#define SQ_HV_VMID_CTRL__ALLOWED_VMID_MASK_MASK 0xffff0\n#define SQ_HV_VMID_CTRL__ALLOWED_VMID_MASK__SHIFT 0x4\n#define SQ_WAVE_INST_DW0__INST_DW0_MASK 0xffffffff\n#define SQ_WAVE_INST_DW0__INST_DW0__SHIFT 0x0\n#define SQ_WAVE_INST_DW1__INST_DW1_MASK 0xffffffff\n#define SQ_WAVE_INST_DW1__INST_DW1__SHIFT 0x0\n#define SQ_WAVE_PC_LO__PC_LO_MASK 0xffffffff\n#define SQ_WAVE_PC_LO__PC_LO__SHIFT 0x0\n#define SQ_WAVE_PC_HI__PC_HI_MASK 0xff\n#define SQ_WAVE_PC_HI__PC_HI__SHIFT 0x0\n#define SQ_WAVE_IB_DBG0__IBUF_ST_MASK 0x7\n#define SQ_WAVE_IB_DBG0__IBUF_ST__SHIFT 0x0\n#define SQ_WAVE_IB_DBG0__PC_INVALID_MASK 0x8\n#define SQ_WAVE_IB_DBG0__PC_INVALID__SHIFT 0x3\n#define SQ_WAVE_IB_DBG0__NEED_NEXT_DW_MASK 0x10\n#define SQ_WAVE_IB_DBG0__NEED_NEXT_DW__SHIFT 0x4\n#define SQ_WAVE_IB_DBG0__NO_PREFETCH_CNT_MASK 0xe0\n#define SQ_WAVE_IB_DBG0__NO_PREFETCH_CNT__SHIFT 0x5\n#define SQ_WAVE_IB_DBG0__IBUF_RPTR_MASK 0x300\n#define SQ_WAVE_IB_DBG0__IBUF_RPTR__SHIFT 0x8\n#define SQ_WAVE_IB_DBG0__IBUF_WPTR_MASK 0xc00\n#define SQ_WAVE_IB_DBG0__IBUF_WPTR__SHIFT 0xa\n#define SQ_WAVE_IB_DBG0__INST_STR_ST_MASK 0x70000\n#define SQ_WAVE_IB_DBG0__INST_STR_ST__SHIFT 0x10\n#define SQ_WAVE_IB_DBG0__MISC_CNT_MASK 0x380000\n#define SQ_WAVE_IB_DBG0__MISC_CNT__SHIFT 0x13\n#define SQ_WAVE_IB_DBG0__ECC_ST_MASK 0xc00000\n#define SQ_WAVE_IB_DBG0__ECC_ST__SHIFT 0x16\n#define SQ_WAVE_IB_DBG0__IS_HYB_MASK 0x1000000\n#define SQ_WAVE_IB_DBG0__IS_HYB__SHIFT 0x18\n#define SQ_WAVE_IB_DBG0__HYB_CNT_MASK 0x6000000\n#define SQ_WAVE_IB_DBG0__HYB_CNT__SHIFT 0x19\n#define SQ_WAVE_IB_DBG0__KILL_MASK 0x8000000\n#define SQ_WAVE_IB_DBG0__KILL__SHIFT 0x1b\n#define SQ_WAVE_IB_DBG0__NEED_KILL_IFETCH_MASK 0x10000000\n#define SQ_WAVE_IB_DBG0__NEED_KILL_IFETCH__SHIFT 0x1c\n#define SQ_WAVE_EXEC_LO__EXEC_LO_MASK 0xffffffff\n#define SQ_WAVE_EXEC_LO__EXEC_LO__SHIFT 0x0\n#define SQ_WAVE_EXEC_HI__EXEC_HI_MASK 0xffffffff\n#define SQ_WAVE_EXEC_HI__EXEC_HI__SHIFT 0x0\n#define SQ_WAVE_STATUS__SCC_MASK 0x1\n#define SQ_WAVE_STATUS__SCC__SHIFT 0x0\n#define SQ_WAVE_STATUS__SPI_PRIO_MASK 0x6\n#define SQ_WAVE_STATUS__SPI_PRIO__SHIFT 0x1\n#define SQ_WAVE_STATUS__WAVE_PRIO_MASK 0x18\n#define SQ_WAVE_STATUS__WAVE_PRIO__SHIFT 0x3\n#define SQ_WAVE_STATUS__PRIV_MASK 0x20\n#define SQ_WAVE_STATUS__PRIV__SHIFT 0x5\n#define SQ_WAVE_STATUS__TRAP_EN_MASK 0x40\n#define SQ_WAVE_STATUS__TRAP_EN__SHIFT 0x6\n#define SQ_WAVE_STATUS__TTRACE_EN_MASK 0x80\n#define SQ_WAVE_STATUS__TTRACE_EN__SHIFT 0x7\n#define SQ_WAVE_STATUS__EXPORT_RDY_MASK 0x100\n#define SQ_WAVE_STATUS__EXPORT_RDY__SHIFT 0x8\n#define SQ_WAVE_STATUS__EXECZ_MASK 0x200\n#define SQ_WAVE_STATUS__EXECZ__SHIFT 0x9\n#define SQ_WAVE_STATUS__VCCZ_MASK 0x400\n#define SQ_WAVE_STATUS__VCCZ__SHIFT 0xa\n#define SQ_WAVE_STATUS__IN_TG_MASK 0x800\n#define SQ_WAVE_STATUS__IN_TG__SHIFT 0xb\n#define SQ_WAVE_STATUS__IN_BARRIER_MASK 0x1000\n#define SQ_WAVE_STATUS__IN_BARRIER__SHIFT 0xc\n#define SQ_WAVE_STATUS__HALT_MASK 0x2000\n#define SQ_WAVE_STATUS__HALT__SHIFT 0xd\n#define SQ_WAVE_STATUS__TRAP_MASK 0x4000\n#define SQ_WAVE_STATUS__TRAP__SHIFT 0xe\n#define SQ_WAVE_STATUS__TTRACE_CU_EN_MASK 0x8000\n#define SQ_WAVE_STATUS__TTRACE_CU_EN__SHIFT 0xf\n#define SQ_WAVE_STATUS__VALID_MASK 0x10000\n#define SQ_WAVE_STATUS__VALID__SHIFT 0x10\n#define SQ_WAVE_STATUS__ECC_ERR_MASK 0x20000\n#define SQ_WAVE_STATUS__ECC_ERR__SHIFT 0x11\n#define SQ_WAVE_STATUS__SKIP_EXPORT_MASK 0x40000\n#define SQ_WAVE_STATUS__SKIP_EXPORT__SHIFT 0x12\n#define SQ_WAVE_STATUS__PERF_EN_MASK 0x80000\n#define SQ_WAVE_STATUS__PERF_EN__SHIFT 0x13\n#define SQ_WAVE_STATUS__COND_DBG_USER_MASK 0x100000\n#define SQ_WAVE_STATUS__COND_DBG_USER__SHIFT 0x14\n#define SQ_WAVE_STATUS__COND_DBG_SYS_MASK 0x200000\n#define SQ_WAVE_STATUS__COND_DBG_SYS__SHIFT 0x15\n#define SQ_WAVE_STATUS__DATA_ATC_MASK 0x400000\n#define SQ_WAVE_STATUS__DATA_ATC__SHIFT 0x16\n#define SQ_WAVE_STATUS__INST_ATC_MASK 0x800000\n#define SQ_WAVE_STATUS__INST_ATC__SHIFT 0x17\n#define SQ_WAVE_STATUS__DISPATCH_CACHE_CTRL_MASK 0x7000000\n#define SQ_WAVE_STATUS__DISPATCH_CACHE_CTRL__SHIFT 0x18\n#define SQ_WAVE_STATUS__MUST_EXPORT_MASK 0x8000000\n#define SQ_WAVE_STATUS__MUST_EXPORT__SHIFT 0x1b\n#define SQ_WAVE_MODE__FP_ROUND_MASK 0xf\n#define SQ_WAVE_MODE__FP_ROUND__SHIFT 0x0\n#define SQ_WAVE_MODE__FP_DENORM_MASK 0xf0\n#define SQ_WAVE_MODE__FP_DENORM__SHIFT 0x4\n#define SQ_WAVE_MODE__DX10_CLAMP_MASK 0x100\n#define SQ_WAVE_MODE__DX10_CLAMP__SHIFT 0x8\n#define SQ_WAVE_MODE__IEEE_MASK 0x200\n#define SQ_WAVE_MODE__IEEE__SHIFT 0x9\n#define SQ_WAVE_MODE__LOD_CLAMPED_MASK 0x400\n#define SQ_WAVE_MODE__LOD_CLAMPED__SHIFT 0xa\n#define SQ_WAVE_MODE__DEBUG_EN_MASK 0x800\n#define SQ_WAVE_MODE__DEBUG_EN__SHIFT 0xb\n#define SQ_WAVE_MODE__EXCP_EN_MASK 0x1ff000\n#define SQ_WAVE_MODE__EXCP_EN__SHIFT 0xc\n#define SQ_WAVE_MODE__VSKIP_MASK 0x10000000\n#define SQ_WAVE_MODE__VSKIP__SHIFT 0x1c\n#define SQ_WAVE_MODE__CSP_MASK 0xe0000000\n#define SQ_WAVE_MODE__CSP__SHIFT 0x1d\n#define SQ_WAVE_TRAPSTS__EXCP_MASK 0x1ff\n#define SQ_WAVE_TRAPSTS__EXCP__SHIFT 0x0\n#define SQ_WAVE_TRAPSTS__EXCP_CYCLE_MASK 0x3f0000\n#define SQ_WAVE_TRAPSTS__EXCP_CYCLE__SHIFT 0x10\n#define SQ_WAVE_TRAPSTS__DP_RATE_MASK 0xe0000000\n#define SQ_WAVE_TRAPSTS__DP_RATE__SHIFT 0x1d\n#define SQ_WAVE_HW_ID__WAVE_ID_MASK 0xf\n#define SQ_WAVE_HW_ID__WAVE_ID__SHIFT 0x0\n#define SQ_WAVE_HW_ID__SIMD_ID_MASK 0x30\n#define SQ_WAVE_HW_ID__SIMD_ID__SHIFT 0x4\n#define SQ_WAVE_HW_ID__PIPE_ID_MASK 0xc0\n#define SQ_WAVE_HW_ID__PIPE_ID__SHIFT 0x6\n#define SQ_WAVE_HW_ID__CU_ID_MASK 0xf00\n#define SQ_WAVE_HW_ID__CU_ID__SHIFT 0x8\n#define SQ_WAVE_HW_ID__SH_ID_MASK 0x1000\n#define SQ_WAVE_HW_ID__SH_ID__SHIFT 0xc\n#define SQ_WAVE_HW_ID__SE_ID_MASK 0x6000\n#define SQ_WAVE_HW_ID__SE_ID__SHIFT 0xd\n#define SQ_WAVE_HW_ID__TG_ID_MASK 0xf0000\n#define SQ_WAVE_HW_ID__TG_ID__SHIFT 0x10\n#define SQ_WAVE_HW_ID__VM_ID_MASK 0xf00000\n#define SQ_WAVE_HW_ID__VM_ID__SHIFT 0x14\n#define SQ_WAVE_HW_ID__QUEUE_ID_MASK 0x7000000\n#define SQ_WAVE_HW_ID__QUEUE_ID__SHIFT 0x18\n#define SQ_WAVE_HW_ID__STATE_ID_MASK 0x38000000\n#define SQ_WAVE_HW_ID__STATE_ID__SHIFT 0x1b\n#define SQ_WAVE_HW_ID__ME_ID_MASK 0xc0000000\n#define SQ_WAVE_HW_ID__ME_ID__SHIFT 0x1e\n#define SQ_WAVE_GPR_ALLOC__VGPR_BASE_MASK 0x3f\n#define SQ_WAVE_GPR_ALLOC__VGPR_BASE__SHIFT 0x0\n#define SQ_WAVE_GPR_ALLOC__VGPR_SIZE_MASK 0x3f00\n#define SQ_WAVE_GPR_ALLOC__VGPR_SIZE__SHIFT 0x8\n#define SQ_WAVE_GPR_ALLOC__SGPR_BASE_MASK 0x3f0000\n#define SQ_WAVE_GPR_ALLOC__SGPR_BASE__SHIFT 0x10\n#define SQ_WAVE_GPR_ALLOC__SGPR_SIZE_MASK 0xf000000\n#define SQ_WAVE_GPR_ALLOC__SGPR_SIZE__SHIFT 0x18\n#define SQ_WAVE_LDS_ALLOC__LDS_BASE_MASK 0xff\n#define SQ_WAVE_LDS_ALLOC__LDS_BASE__SHIFT 0x0\n#define SQ_WAVE_LDS_ALLOC__LDS_SIZE_MASK 0x1ff000\n#define SQ_WAVE_LDS_ALLOC__LDS_SIZE__SHIFT 0xc\n#define SQ_WAVE_IB_STS__VM_CNT_MASK 0xf\n#define SQ_WAVE_IB_STS__VM_CNT__SHIFT 0x0\n#define SQ_WAVE_IB_STS__EXP_CNT_MASK 0x70\n#define SQ_WAVE_IB_STS__EXP_CNT__SHIFT 0x4\n#define SQ_WAVE_IB_STS__LGKM_CNT_MASK 0xf00\n#define SQ_WAVE_IB_STS__LGKM_CNT__SHIFT 0x8\n#define SQ_WAVE_IB_STS__VALU_CNT_MASK 0x7000\n#define SQ_WAVE_IB_STS__VALU_CNT__SHIFT 0xc\n#define SQ_WAVE_M0__M0_MASK 0xffffffff\n#define SQ_WAVE_M0__M0__SHIFT 0x0\n#define SQ_WAVE_TBA_LO__ADDR_LO_MASK 0xffffffff\n#define SQ_WAVE_TBA_LO__ADDR_LO__SHIFT 0x0\n#define SQ_WAVE_TBA_HI__ADDR_HI_MASK 0xff\n#define SQ_WAVE_TBA_HI__ADDR_HI__SHIFT 0x0\n#define SQ_WAVE_TMA_LO__ADDR_LO_MASK 0xffffffff\n#define SQ_WAVE_TMA_LO__ADDR_LO__SHIFT 0x0\n#define SQ_WAVE_TMA_HI__ADDR_HI_MASK 0xff\n#define SQ_WAVE_TMA_HI__ADDR_HI__SHIFT 0x0\n#define SQ_WAVE_TTMP0__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP0__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP1__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP1__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP2__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP2__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP3__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP3__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP4__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP4__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP5__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP5__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP6__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP6__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP7__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP7__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP8__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP8__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP9__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP9__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP10__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP10__DATA__SHIFT 0x0\n#define SQ_WAVE_TTMP11__DATA_MASK 0xffffffff\n#define SQ_WAVE_TTMP11__DATA__SHIFT 0x0\n#define SQ_DEBUG_STS_GLOBAL__BUSY_MASK 0x1\n#define SQ_DEBUG_STS_GLOBAL__BUSY__SHIFT 0x0\n#define SQ_DEBUG_STS_GLOBAL__INTERRUPT_MSG_BUSY_MASK 0x2\n#define SQ_DEBUG_STS_GLOBAL__INTERRUPT_MSG_BUSY__SHIFT 0x1\n#define SQ_DEBUG_STS_GLOBAL__WAVE_LEVEL_SH0_MASK 0xfff0\n#define SQ_DEBUG_STS_GLOBAL__WAVE_LEVEL_SH0__SHIFT 0x4\n#define SQ_DEBUG_STS_GLOBAL__WAVE_LEVEL_SH1_MASK 0xfff0000\n#define SQ_DEBUG_STS_GLOBAL__WAVE_LEVEL_SH1__SHIFT 0x10\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_GFX0_MASK 0xff\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_GFX0__SHIFT 0x0\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_GFX1_MASK 0xff00\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_GFX1__SHIFT 0x8\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_IMMED_MASK 0xff0000\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_IMMED__SHIFT 0x10\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_HOST_MASK 0xff000000\n#define SQ_DEBUG_STS_GLOBAL2__FIFO_LEVEL_HOST__SHIFT 0x18\n#define SQ_DEBUG_STS_GLOBAL3__FIFO_LEVEL_HOST_CMD_MASK 0xf\n#define SQ_DEBUG_STS_GLOBAL3__FIFO_LEVEL_HOST_CMD__SHIFT 0x0\n#define SQ_DEBUG_STS_GLOBAL3__FIFO_LEVEL_HOST_REG_MASK 0xf0\n#define SQ_DEBUG_STS_GLOBAL3__FIFO_LEVEL_HOST_REG__SHIFT 0x4\n#define SQ_DEBUG_STS_LOCAL__BUSY_MASK 0x1\n#define SQ_DEBUG_STS_LOCAL__BUSY__SHIFT 0x0\n#define SQ_DEBUG_STS_LOCAL__WAVE_LEVEL_MASK 0x3f0\n#define SQ_DEBUG_STS_LOCAL__WAVE_LEVEL__SHIFT 0x4\n#define SQ_DEBUG_CTRL_LOCAL__UNUSED_MASK 0xff\n#define SQ_DEBUG_CTRL_LOCAL__UNUSED__SHIFT 0x0\n#define SH_MEM_BASES__PRIVATE_BASE_MASK 0xffff\n#define SH_MEM_BASES__PRIVATE_BASE__SHIFT 0x0\n#define SH_MEM_BASES__SHARED_BASE_MASK 0xffff0000\n#define SH_MEM_BASES__SHARED_BASE__SHIFT 0x10\n#define SH_MEM_APE1_BASE__BASE_MASK 0xffffffff\n#define SH_MEM_APE1_BASE__BASE__SHIFT 0x0\n#define SH_MEM_APE1_LIMIT__LIMIT_MASK 0xffffffff\n#define SH_MEM_APE1_LIMIT__LIMIT__SHIFT 0x0\n#define SH_MEM_CONFIG__PTR32_MASK 0x1\n#define SH_MEM_CONFIG__PTR32__SHIFT 0x0\n#define SH_MEM_CONFIG__PRIVATE_ATC_MASK 0x2\n#define SH_MEM_CONFIG__PRIVATE_ATC__SHIFT 0x1\n#define SH_MEM_CONFIG__ALIGNMENT_MODE_MASK 0xc\n#define SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT 0x2\n#define SH_MEM_CONFIG__DEFAULT_MTYPE_MASK 0x70\n#define SH_MEM_CONFIG__DEFAULT_MTYPE__SHIFT 0x4\n#define SH_MEM_CONFIG__APE1_MTYPE_MASK 0x380\n#define SH_MEM_CONFIG__APE1_MTYPE__SHIFT 0x7\n#define SQC_POLICY__DATA_L1_POLICY_0_MASK 0x1\n#define SQC_POLICY__DATA_L1_POLICY_0__SHIFT 0x0\n#define SQC_POLICY__DATA_L1_POLICY_1_MASK 0x2\n#define SQC_POLICY__DATA_L1_POLICY_1__SHIFT 0x1\n#define SQC_POLICY__DATA_L1_POLICY_2_MASK 0x4\n#define SQC_POLICY__DATA_L1_POLICY_2__SHIFT 0x2\n#define SQC_POLICY__DATA_L1_POLICY_3_MASK 0x8\n#define SQC_POLICY__DATA_L1_POLICY_3__SHIFT 0x3\n#define SQC_POLICY__DATA_L1_POLICY_4_MASK 0x10\n#define SQC_POLICY__DATA_L1_POLICY_4__SHIFT 0x4\n#define SQC_POLICY__DATA_L1_POLICY_5_MASK 0x20\n#define SQC_POLICY__DATA_L1_POLICY_5__SHIFT 0x5\n#define SQC_POLICY__DATA_L1_POLICY_6_MASK 0x40\n#define SQC_POLICY__DATA_L1_POLICY_6__SHIFT 0x6\n#define SQC_POLICY__DATA_L1_POLICY_7_MASK 0x80\n#define SQC_POLICY__DATA_L1_POLICY_7__SHIFT 0x7\n#define SQC_POLICY__DATA_L2_POLICY_0_MASK 0x300\n#define SQC_POLICY__DATA_L2_POLICY_0__SHIFT 0x8\n#define SQC_POLICY__DATA_L2_POLICY_1_MASK 0xc00\n#define SQC_POLICY__DATA_L2_POLICY_1__SHIFT 0xa\n#define SQC_POLICY__DATA_L2_POLICY_2_MASK 0x3000\n#define SQC_POLICY__DATA_L2_POLICY_2__SHIFT 0xc\n#define SQC_POLICY__DATA_L2_POLICY_3_MASK 0xc000\n#define SQC_POLICY__DATA_L2_POLICY_3__SHIFT 0xe\n#define SQC_POLICY__DATA_L2_POLICY_4_MASK 0x30000\n#define SQC_POLICY__DATA_L2_POLICY_4__SHIFT 0x10\n#define SQC_POLICY__DATA_L2_POLICY_5_MASK 0xc0000\n#define SQC_POLICY__DATA_L2_POLICY_5__SHIFT 0x12\n#define SQC_POLICY__DATA_L2_POLICY_6_MASK 0x300000\n#define SQC_POLICY__DATA_L2_POLICY_6__SHIFT 0x14\n#define SQC_POLICY__DATA_L2_POLICY_7_MASK 0xc00000\n#define SQC_POLICY__DATA_L2_POLICY_7__SHIFT 0x16\n#define SQC_POLICY__INST_L2_POLICY_MASK 0x3000000\n#define SQC_POLICY__INST_L2_POLICY__SHIFT 0x18\n#define SQC_VOLATILE__DATA_L1_MASK 0xf\n#define SQC_VOLATILE__DATA_L1__SHIFT 0x0\n#define SQC_VOLATILE__DATA_L2_MASK 0xf0\n#define SQC_VOLATILE__DATA_L2__SHIFT 0x4\n#define SQC_VOLATILE__INST_L2_MASK 0x100\n#define SQC_VOLATILE__INST_L2__SHIFT 0x8\n#define SQ_THREAD_TRACE_WORD_CMN__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_CMN__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_CMN__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_CMN__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_INST__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_INST__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_INST__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_INST__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_INST__WAVE_ID_MASK 0x1e0\n#define SQ_THREAD_TRACE_WORD_INST__WAVE_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_INST__SIMD_ID_MASK 0x600\n#define SQ_THREAD_TRACE_WORD_INST__SIMD_ID__SHIFT 0x9\n#define SQ_THREAD_TRACE_WORD_INST__SIZE_MASK 0x800\n#define SQ_THREAD_TRACE_WORD_INST__SIZE__SHIFT 0xb\n#define SQ_THREAD_TRACE_WORD_INST__INST_TYPE_MASK 0xf000\n#define SQ_THREAD_TRACE_WORD_INST__INST_TYPE__SHIFT 0xc\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__WAVE_ID_MASK 0x1e0\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__WAVE_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__SIMD_ID_MASK 0x600\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__SIMD_ID__SHIFT 0x9\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__PC_LO_MASK 0xffff0000\n#define SQ_THREAD_TRACE_WORD_INST_PC_1_OF_2__PC_LO__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_INST_PC_2_OF_2__PC_HI_MASK 0xffffff\n#define SQ_THREAD_TRACE_WORD_INST_PC_2_OF_2__PC_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__SH_ID_MASK 0x20\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__SH_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__CU_ID_MASK 0x3c0\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__CU_ID__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__WAVE_ID_MASK 0x3c00\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__WAVE_ID__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__SIMD_ID_MASK 0xc000\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__SIMD_ID__SHIFT 0xe\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__DATA_LO_MASK 0xffff0000\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_1_OF_2__DATA_LO__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_2_OF_2__DATA_HI_MASK 0xffff\n#define SQ_THREAD_TRACE_WORD_INST_USERDATA_2_OF_2__DATA_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2__TIME_LO_MASK 0xffff0000\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_1_OF_2__TIME_LO__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_2_OF_2__TIME_HI_MASK 0xffffffff\n#define SQ_THREAD_TRACE_WORD_TIMESTAMP_2_OF_2__TIME_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_WAVE__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_WAVE__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_WAVE__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_WAVE__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_WAVE__SH_ID_MASK 0x20\n#define SQ_THREAD_TRACE_WORD_WAVE__SH_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_WAVE__CU_ID_MASK 0x3c0\n#define SQ_THREAD_TRACE_WORD_WAVE__CU_ID__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_WAVE__WAVE_ID_MASK 0x3c00\n#define SQ_THREAD_TRACE_WORD_WAVE__WAVE_ID__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_WAVE__SIMD_ID_MASK 0xc000\n#define SQ_THREAD_TRACE_WORD_WAVE__SIMD_ID__SHIFT 0xe\n#define SQ_THREAD_TRACE_WORD_MISC__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_MISC__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_MISC__TIME_DELTA_MASK 0xff0\n#define SQ_THREAD_TRACE_WORD_MISC__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_MISC__SH_ID_MASK 0x1000\n#define SQ_THREAD_TRACE_WORD_MISC__SH_ID__SHIFT 0xc\n#define SQ_THREAD_TRACE_WORD_MISC__MISC_TOKEN_TYPE_MASK 0xe000\n#define SQ_THREAD_TRACE_WORD_MISC__MISC_TOKEN_TYPE__SHIFT 0xd\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_WAVE_START__SH_ID_MASK 0x20\n#define SQ_THREAD_TRACE_WORD_WAVE_START__SH_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_WAVE_START__CU_ID_MASK 0x3c0\n#define SQ_THREAD_TRACE_WORD_WAVE_START__CU_ID__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_WAVE_START__WAVE_ID_MASK 0x3c00\n#define SQ_THREAD_TRACE_WORD_WAVE_START__WAVE_ID__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_WAVE_START__SIMD_ID_MASK 0xc000\n#define SQ_THREAD_TRACE_WORD_WAVE_START__SIMD_ID__SHIFT 0xe\n#define SQ_THREAD_TRACE_WORD_WAVE_START__DISPATCHER_MASK 0x1f0000\n#define SQ_THREAD_TRACE_WORD_WAVE_START__DISPATCHER__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_WAVE_START__VS_NO_ALLOC_OR_GROUPED_MASK 0x200000\n#define SQ_THREAD_TRACE_WORD_WAVE_START__VS_NO_ALLOC_OR_GROUPED__SHIFT 0x15\n#define SQ_THREAD_TRACE_WORD_WAVE_START__COUNT_MASK 0x1fc00000\n#define SQ_THREAD_TRACE_WORD_WAVE_START__COUNT__SHIFT 0x16\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TG_ID_MASK 0xe0000000\n#define SQ_THREAD_TRACE_WORD_WAVE_START__TG_ID__SHIFT 0x1d\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__PIPE_ID_MASK 0x60\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__PIPE_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__ME_ID_MASK 0x180\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__ME_ID__SHIFT 0x7\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_DROPPED_PREV_MASK 0x200\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_DROPPED_PREV__SHIFT 0x9\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_TYPE_MASK 0x1c00\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_TYPE__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_PRIV_MASK 0x4000\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_PRIV__SHIFT 0xe\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_OP_MASK 0x8000\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_OP__SHIFT 0xf\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_ADDR_MASK 0xffff0000\n#define SQ_THREAD_TRACE_WORD_REG_1_OF_2__REG_ADDR__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_REG_2_OF_2__DATA_MASK 0xffffffff\n#define SQ_THREAD_TRACE_WORD_REG_2_OF_2__DATA__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__PIPE_ID_MASK 0x60\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__PIPE_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__ME_ID_MASK 0x180\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__ME_ID__SHIFT 0x7\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__REG_ADDR_MASK 0xfe00\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__REG_ADDR__SHIFT 0x9\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__DATA_LO_MASK 0xffff0000\n#define SQ_THREAD_TRACE_WORD_REG_CS_1_OF_2__DATA_LO__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_REG_CS_2_OF_2__DATA_HI_MASK 0xffff\n#define SQ_THREAD_TRACE_WORD_REG_CS_2_OF_2__DATA_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_EVENT__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_EVENT__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_EVENT__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_EVENT__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_EVENT__SH_ID_MASK 0x20\n#define SQ_THREAD_TRACE_WORD_EVENT__SH_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_EVENT__STAGE_MASK 0x1c0\n#define SQ_THREAD_TRACE_WORD_EVENT__STAGE__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_EVENT__EVENT_TYPE_MASK 0xfc00\n#define SQ_THREAD_TRACE_WORD_EVENT__EVENT_TYPE__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_ISSUE__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_ISSUE__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_ISSUE__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_ISSUE__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_ISSUE__SIMD_ID_MASK 0x60\n#define SQ_THREAD_TRACE_WORD_ISSUE__SIMD_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST0_MASK 0x300\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST0__SHIFT 0x8\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST1_MASK 0xc00\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST1__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST2_MASK 0x3000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST2__SHIFT 0xc\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST3_MASK 0xc000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST3__SHIFT 0xe\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST4_MASK 0x30000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST4__SHIFT 0x10\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST5_MASK 0xc0000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST5__SHIFT 0x12\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST6_MASK 0x300000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST6__SHIFT 0x14\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST7_MASK 0xc00000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST7__SHIFT 0x16\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST8_MASK 0x3000000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST8__SHIFT 0x18\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST9_MASK 0xc000000\n#define SQ_THREAD_TRACE_WORD_ISSUE__INST9__SHIFT 0x1a\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__TOKEN_TYPE_MASK 0xf\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__TOKEN_TYPE__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__TIME_DELTA_MASK 0x10\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__TIME_DELTA__SHIFT 0x4\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__SH_ID_MASK 0x20\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__SH_ID__SHIFT 0x5\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CU_ID_MASK 0x3c0\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CU_ID__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR_BANK_MASK 0xc00\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR_BANK__SHIFT 0xa\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR0_MASK 0x1fff000\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR0__SHIFT 0xc\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR1_LO_MASK 0xfe000000\n#define SQ_THREAD_TRACE_WORD_PERF_1_OF_2__CNTR1_LO__SHIFT 0x19\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR1_HI_MASK 0x3f\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR1_HI__SHIFT 0x0\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR2_MASK 0x7ffc0\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR2__SHIFT 0x6\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR3_MASK 0xfff80000\n#define SQ_THREAD_TRACE_WORD_PERF_2_OF_2__CNTR3__SHIFT 0x13\n#define SQ_INTERRUPT_WORD_CMN__SE_ID_MASK 0x3000000\n#define SQ_INTERRUPT_WORD_CMN__SE_ID__SHIFT 0x18\n#define SQ_INTERRUPT_WORD_CMN__ENCODING_MASK 0xc000000\n#define SQ_INTERRUPT_WORD_CMN__ENCODING__SHIFT 0x1a\n#define SQ_INTERRUPT_WORD_AUTO__THREAD_TRACE_MASK 0x1\n#define SQ_INTERRUPT_WORD_AUTO__THREAD_TRACE__SHIFT 0x0\n#define SQ_INTERRUPT_WORD_AUTO__WLT_MASK 0x2\n#define SQ_INTERRUPT_WORD_AUTO__WLT__SHIFT 0x1\n#define SQ_INTERRUPT_WORD_AUTO__THREAD_TRACE_BUF_FULL_MASK 0x4\n#define SQ_INTERRUPT_WORD_AUTO__THREAD_TRACE_BUF_FULL__SHIFT 0x2\n#define SQ_INTERRUPT_WORD_AUTO__REG_TIMESTAMP_MASK 0x8\n#define SQ_INTERRUPT_WORD_AUTO__REG_TIMESTAMP__SHIFT 0x3\n#define SQ_INTERRUPT_WORD_AUTO__CMD_TIMESTAMP_MASK 0x10\n#define SQ_INTERRUPT_WORD_AUTO__CMD_TIMESTAMP__SHIFT 0x4\n#define SQ_INTERRUPT_WORD_AUTO__HOST_CMD_OVERFLOW_MASK 0x20\n#define SQ_INTERRUPT_WORD_AUTO__HOST_CMD_OVERFLOW__SHIFT 0x5\n#define SQ_INTERRUPT_WORD_AUTO__HOST_REG_OVERFLOW_MASK 0x40\n#define SQ_INTERRUPT_WORD_AUTO__HOST_REG_OVERFLOW__SHIFT 0x6\n#define SQ_INTERRUPT_WORD_AUTO__IMMED_OVERFLOW_MASK 0x80\n#define SQ_INTERRUPT_WORD_AUTO__IMMED_OVERFLOW__SHIFT 0x7\n#define SQ_INTERRUPT_WORD_AUTO__SE_ID_MASK 0x3000000\n#define SQ_INTERRUPT_WORD_AUTO__SE_ID__SHIFT 0x18\n#define SQ_INTERRUPT_WORD_AUTO__ENCODING_MASK 0xc000000\n#define SQ_INTERRUPT_WORD_AUTO__ENCODING__SHIFT 0x1a\n#define SQ_INTERRUPT_WORD_WAVE__DATA_MASK 0xff\n#define SQ_INTERRUPT_WORD_WAVE__DATA__SHIFT 0x0\n#define SQ_INTERRUPT_WORD_WAVE__SH_ID_MASK 0x100\n#define SQ_INTERRUPT_WORD_WAVE__SH_ID__SHIFT 0x8\n#define SQ_INTERRUPT_WORD_WAVE__PRIV_MASK 0x200\n#define SQ_INTERRUPT_WORD_WAVE__PRIV__SHIFT 0x9\n#define SQ_INTERRUPT_WORD_WAVE__VM_ID_MASK 0x3c00\n#define SQ_INTERRUPT_WORD_WAVE__VM_ID__SHIFT 0xa\n#define SQ_INTERRUPT_WORD_WAVE__WAVE_ID_MASK 0x3c000\n#define SQ_INTERRUPT_WORD_WAVE__WAVE_ID__SHIFT 0xe\n#define SQ_INTERRUPT_WORD_WAVE__SIMD_ID_MASK 0xc0000\n#define SQ_INTERRUPT_WORD_WAVE__SIMD_ID__SHIFT 0x12\n#define SQ_INTERRUPT_WORD_WAVE__CU_ID_MASK 0xf00000\n#define SQ_INTERRUPT_WORD_WAVE__CU_ID__SHIFT 0x14\n#define SQ_INTERRUPT_WORD_WAVE__SE_ID_MASK 0x3000000\n#define SQ_INTERRUPT_WORD_WAVE__SE_ID__SHIFT 0x18\n#define SQ_INTERRUPT_WORD_WAVE__ENCODING_MASK 0xc000000\n#define SQ_INTERRUPT_WORD_WAVE__ENCODING__SHIFT 0x1a\n#define SQ_SOP2__SSRC0_MASK 0xff\n#define SQ_SOP2__SSRC0__SHIFT 0x0\n#define SQ_SOP2__SSRC1_MASK 0xff00\n#define SQ_SOP2__SSRC1__SHIFT 0x8\n#define SQ_SOP2__SDST_MASK 0x7f0000\n#define SQ_SOP2__SDST__SHIFT 0x10\n#define SQ_SOP2__OP_MASK 0x3f800000\n#define SQ_SOP2__OP__SHIFT 0x17\n#define SQ_SOP2__ENCODING_MASK 0xc0000000\n#define SQ_SOP2__ENCODING__SHIFT 0x1e\n#define SQ_VOP1__SRC0_MASK 0x1ff\n#define SQ_VOP1__SRC0__SHIFT 0x0\n#define SQ_VOP1__OP_MASK 0x1fe00\n#define SQ_VOP1__OP__SHIFT 0x9\n#define SQ_VOP1__VDST_MASK 0x1fe0000\n#define SQ_VOP1__VDST__SHIFT 0x11\n#define SQ_VOP1__ENCODING_MASK 0xfe000000\n#define SQ_VOP1__ENCODING__SHIFT 0x19\n#define SQ_MTBUF_1__VADDR_MASK 0xff\n#define SQ_MTBUF_1__VADDR__SHIFT 0x0\n#define SQ_MTBUF_1__VDATA_MASK 0xff00\n#define SQ_MTBUF_1__VDATA__SHIFT 0x8\n#define SQ_MTBUF_1__SRSRC_MASK 0x1f0000\n#define SQ_MTBUF_1__SRSRC__SHIFT 0x10\n#define SQ_MTBUF_1__SLC_MASK 0x400000\n#define SQ_MTBUF_1__SLC__SHIFT 0x16\n#define SQ_MTBUF_1__TFE_MASK 0x800000\n#define SQ_MTBUF_1__TFE__SHIFT 0x17\n#define SQ_MTBUF_1__SOFFSET_MASK 0xff000000\n#define SQ_MTBUF_1__SOFFSET__SHIFT 0x18\n#define SQ_EXP_1__VSRC0_MASK 0xff\n#define SQ_EXP_1__VSRC0__SHIFT 0x0\n#define SQ_EXP_1__VSRC1_MASK 0xff00\n#define SQ_EXP_1__VSRC1__SHIFT 0x8\n#define SQ_EXP_1__VSRC2_MASK 0xff0000\n#define SQ_EXP_1__VSRC2__SHIFT 0x10\n#define SQ_EXP_1__VSRC3_MASK 0xff000000\n#define SQ_EXP_1__VSRC3__SHIFT 0x18\n#define SQ_MUBUF_1__VADDR_MASK 0xff\n#define SQ_MUBUF_1__VADDR__SHIFT 0x0\n#define SQ_MUBUF_1__VDATA_MASK 0xff00\n#define SQ_MUBUF_1__VDATA__SHIFT 0x8\n#define SQ_MUBUF_1__SRSRC_MASK 0x1f0000\n#define SQ_MUBUF_1__SRSRC__SHIFT 0x10\n#define SQ_MUBUF_1__SLC_MASK 0x400000\n#define SQ_MUBUF_1__SLC__SHIFT 0x16\n#define SQ_MUBUF_1__TFE_MASK 0x800000\n#define SQ_MUBUF_1__TFE__SHIFT 0x17\n#define SQ_MUBUF_1__SOFFSET_MASK 0xff000000\n#define SQ_MUBUF_1__SOFFSET__SHIFT 0x18\n#define SQ_INST__ENCODING_MASK 0xffffffff\n#define SQ_INST__ENCODING__SHIFT 0x0\n#define SQ_EXP_0__EN_MASK 0xf\n#define SQ_EXP_0__EN__SHIFT 0x0\n#define SQ_EXP_0__TGT_MASK 0x3f0\n#define SQ_EXP_0__TGT__SHIFT 0x4\n#define SQ_EXP_0__COMPR_MASK 0x400\n#define SQ_EXP_0__COMPR__SHIFT 0xa\n#define SQ_EXP_0__DONE_MASK 0x800\n#define SQ_EXP_0__DONE__SHIFT 0xb\n#define SQ_EXP_0__VM_MASK 0x1000\n#define SQ_EXP_0__VM__SHIFT 0xc\n#define SQ_EXP_0__ENCODING_MASK 0xfc000000\n#define SQ_EXP_0__ENCODING__SHIFT 0x1a\n#define SQ_MUBUF_0__OFFSET_MASK 0xfff\n#define SQ_MUBUF_0__OFFSET__SHIFT 0x0\n#define SQ_MUBUF_0__OFFEN_MASK 0x1000\n#define SQ_MUBUF_0__OFFEN__SHIFT 0xc\n#define SQ_MUBUF_0__IDXEN_MASK 0x2000\n#define SQ_MUBUF_0__IDXEN__SHIFT 0xd\n#define SQ_MUBUF_0__GLC_MASK 0x4000\n#define SQ_MUBUF_0__GLC__SHIFT 0xe\n#define SQ_MUBUF_0__ADDR64_MASK 0x8000\n#define SQ_MUBUF_0__ADDR64__SHIFT 0xf\n#define SQ_MUBUF_0__LDS_MASK 0x10000\n#define SQ_MUBUF_0__LDS__SHIFT 0x10\n#define SQ_MUBUF_0__OP_MASK 0x1fc0000\n#define SQ_MUBUF_0__OP__SHIFT 0x12\n#define SQ_MUBUF_0__ENCODING_MASK 0xfc000000\n#define SQ_MUBUF_0__ENCODING__SHIFT 0x1a\n#define SQ_VOP3_0__VDST_MASK 0xff\n#define SQ_VOP3_0__VDST__SHIFT 0x0\n#define SQ_VOP3_0__ABS_MASK 0x700\n#define SQ_VOP3_0__ABS__SHIFT 0x8\n#define SQ_VOP3_0__CLAMP_MASK 0x800\n#define SQ_VOP3_0__CLAMP__SHIFT 0xb\n#define SQ_VOP3_0__OP_MASK 0x3fe0000\n#define SQ_VOP3_0__OP__SHIFT 0x11\n#define SQ_VOP3_0__ENCODING_MASK 0xfc000000\n#define SQ_VOP3_0__ENCODING__SHIFT 0x1a\n#define SQ_VOP2__SRC0_MASK 0x1ff\n#define SQ_VOP2__SRC0__SHIFT 0x0\n#define SQ_VOP2__VSRC1_MASK 0x1fe00\n#define SQ_VOP2__VSRC1__SHIFT 0x9\n#define SQ_VOP2__VDST_MASK 0x1fe0000\n#define SQ_VOP2__VDST__SHIFT 0x11\n#define SQ_VOP2__OP_MASK 0x7e000000\n#define SQ_VOP2__OP__SHIFT 0x19\n#define SQ_VOP2__ENCODING_MASK 0x80000000\n#define SQ_VOP2__ENCODING__SHIFT 0x1f\n#define SQ_MTBUF_0__OFFSET_MASK 0xfff\n#define SQ_MTBUF_0__OFFSET__SHIFT 0x0\n#define SQ_MTBUF_0__OFFEN_MASK 0x1000\n#define SQ_MTBUF_0__OFFEN__SHIFT 0xc\n#define SQ_MTBUF_0__IDXEN_MASK 0x2000\n#define SQ_MTBUF_0__IDXEN__SHIFT 0xd\n#define SQ_MTBUF_0__GLC_MASK 0x4000\n#define SQ_MTBUF_0__GLC__SHIFT 0xe\n#define SQ_MTBUF_0__ADDR64_MASK 0x8000\n#define SQ_MTBUF_0__ADDR64__SHIFT 0xf\n#define SQ_MTBUF_0__OP_MASK 0x70000\n#define SQ_MTBUF_0__OP__SHIFT 0x10\n#define SQ_MTBUF_0__DFMT_MASK 0x780000\n#define SQ_MTBUF_0__DFMT__SHIFT 0x13\n#define SQ_MTBUF_0__NFMT_MASK 0x3800000\n#define SQ_MTBUF_0__NFMT__SHIFT 0x17\n#define SQ_MTBUF_0__ENCODING_MASK 0xfc000000\n#define SQ_MTBUF_0__ENCODING__SHIFT 0x1a\n#define SQ_SOPP__SIMM16_MASK 0xffff\n#define SQ_SOPP__SIMM16__SHIFT 0x0\n#define SQ_SOPP__OP_MASK 0x7f0000\n#define SQ_SOPP__OP__SHIFT 0x10\n#define SQ_SOPP__ENCODING_MASK 0xff800000\n#define SQ_SOPP__ENCODING__SHIFT 0x17\n#define SQ_FLAT_0__GLC_MASK 0x10000\n#define SQ_FLAT_0__GLC__SHIFT 0x10\n#define SQ_FLAT_0__SLC_MASK 0x20000\n#define SQ_FLAT_0__SLC__SHIFT 0x11\n#define SQ_FLAT_0__OP_MASK 0x1fc0000\n#define SQ_FLAT_0__OP__SHIFT 0x12\n#define SQ_FLAT_0__ENCODING_MASK 0xfc000000\n#define SQ_FLAT_0__ENCODING__SHIFT 0x1a\n#define SQ_VOP3_0_SDST_ENC__VDST_MASK 0xff\n#define SQ_VOP3_0_SDST_ENC__VDST__SHIFT 0x0\n#define SQ_VOP3_0_SDST_ENC__SDST_MASK 0x7f00\n#define SQ_VOP3_0_SDST_ENC__SDST__SHIFT 0x8\n#define SQ_VOP3_0_SDST_ENC__OP_MASK 0x3fe0000\n#define SQ_VOP3_0_SDST_ENC__OP__SHIFT 0x11\n#define SQ_VOP3_0_SDST_ENC__ENCODING_MASK 0xfc000000\n#define SQ_VOP3_0_SDST_ENC__ENCODING__SHIFT 0x1a\n#define SQ_MIMG_1__VADDR_MASK 0xff\n#define SQ_MIMG_1__VADDR__SHIFT 0x0\n#define SQ_MIMG_1__VDATA_MASK 0xff00\n#define SQ_MIMG_1__VDATA__SHIFT 0x8\n#define SQ_MIMG_1__SRSRC_MASK 0x1f0000\n#define SQ_MIMG_1__SRSRC__SHIFT 0x10\n#define SQ_MIMG_1__SSAMP_MASK 0x3e00000\n#define SQ_MIMG_1__SSAMP__SHIFT 0x15\n#define SQ_SMRD__OFFSET_MASK 0xff\n#define SQ_SMRD__OFFSET__SHIFT 0x0\n#define SQ_SMRD__IMM_MASK 0x100\n#define SQ_SMRD__IMM__SHIFT 0x8\n#define SQ_SMRD__SBASE_MASK 0x7e00\n#define SQ_SMRD__SBASE__SHIFT 0x9\n#define SQ_SMRD__SDST_MASK 0x3f8000\n#define SQ_SMRD__SDST__SHIFT 0xf\n#define SQ_SMRD__OP_MASK 0x7c00000\n#define SQ_SMRD__OP__SHIFT 0x16\n#define SQ_SMRD__ENCODING_MASK 0xf8000000\n#define SQ_SMRD__ENCODING__SHIFT 0x1b\n#define SQ_SOP1__SSRC0_MASK 0xff\n#define SQ_SOP1__SSRC0__SHIFT 0x0\n#define SQ_SOP1__OP_MASK 0xff00\n#define SQ_SOP1__OP__SHIFT 0x8\n#define SQ_SOP1__SDST_MASK 0x7f0000\n#define SQ_SOP1__SDST__SHIFT 0x10\n#define SQ_SOP1__ENCODING_MASK 0xff800000\n#define SQ_SOP1__ENCODING__SHIFT 0x17\n#define SQ_SOPC__SSRC0_MASK 0xff\n#define SQ_SOPC__SSRC0__SHIFT 0x0\n#define SQ_SOPC__SSRC1_MASK 0xff00\n#define SQ_SOPC__SSRC1__SHIFT 0x8\n#define SQ_SOPC__OP_MASK 0x7f0000\n#define SQ_SOPC__OP__SHIFT 0x10\n#define SQ_SOPC__ENCODING_MASK 0xff800000\n#define SQ_SOPC__ENCODING__SHIFT 0x17\n#define SQ_FLAT_1__ADDR_MASK 0xff\n#define SQ_FLAT_1__ADDR__SHIFT 0x0\n#define SQ_FLAT_1__DATA_MASK 0xff00\n#define SQ_FLAT_1__DATA__SHIFT 0x8\n#define SQ_FLAT_1__TFE_MASK 0x800000\n#define SQ_FLAT_1__TFE__SHIFT 0x17\n#define SQ_FLAT_1__VDST_MASK 0xff000000\n#define SQ_FLAT_1__VDST__SHIFT 0x18\n#define SQ_DS_1__ADDR_MASK 0xff\n#define SQ_DS_1__ADDR__SHIFT 0x0\n#define SQ_DS_1__DATA0_MASK 0xff00\n#define SQ_DS_1__DATA0__SHIFT 0x8\n#define SQ_DS_1__DATA1_MASK 0xff0000\n#define SQ_DS_1__DATA1__SHIFT 0x10\n#define SQ_DS_1__VDST_MASK 0xff000000\n#define SQ_DS_1__VDST__SHIFT 0x18\n#define SQ_VOP3_1__SRC0_MASK 0x1ff\n#define SQ_VOP3_1__SRC0__SHIFT 0x0\n#define SQ_VOP3_1__SRC1_MASK 0x3fe00\n#define SQ_VOP3_1__SRC1__SHIFT 0x9\n#define SQ_VOP3_1__SRC2_MASK 0x7fc0000\n#define SQ_VOP3_1__SRC2__SHIFT 0x12\n#define SQ_VOP3_1__OMOD_MASK 0x18000000\n#define SQ_VOP3_1__OMOD__SHIFT 0x1b\n#define SQ_VOP3_1__NEG_MASK 0xe0000000\n#define SQ_VOP3_1__NEG__SHIFT 0x1d\n#define SQ_MIMG_0__DMASK_MASK 0xf00\n#define SQ_MIMG_0__DMASK__SHIFT 0x8\n#define SQ_MIMG_0__UNORM_MASK 0x1000\n#define SQ_MIMG_0__UNORM__SHIFT 0xc\n#define SQ_MIMG_0__GLC_MASK 0x2000\n#define SQ_MIMG_0__GLC__SHIFT 0xd\n#define SQ_MIMG_0__DA_MASK 0x4000\n#define SQ_MIMG_0__DA__SHIFT 0xe\n#define SQ_MIMG_0__R128_MASK 0x8000\n#define SQ_MIMG_0__R128__SHIFT 0xf\n#define SQ_MIMG_0__TFE_MASK 0x10000\n#define SQ_MIMG_0__TFE__SHIFT 0x10\n#define SQ_MIMG_0__LWE_MASK 0x20000\n#define SQ_MIMG_0__LWE__SHIFT 0x11\n#define SQ_MIMG_0__OP_MASK 0x1fc0000\n#define SQ_MIMG_0__OP__SHIFT 0x12\n#define SQ_MIMG_0__SLC_MASK 0x2000000\n#define SQ_MIMG_0__SLC__SHIFT 0x19\n#define SQ_MIMG_0__ENCODING_MASK 0xfc000000\n#define SQ_MIMG_0__ENCODING__SHIFT 0x1a\n#define SQ_SOPK__SIMM16_MASK 0xffff\n#define SQ_SOPK__SIMM16__SHIFT 0x0\n#define SQ_SOPK__SDST_MASK 0x7f0000\n#define SQ_SOPK__SDST__SHIFT 0x10\n#define SQ_SOPK__OP_MASK 0xf800000\n#define SQ_SOPK__OP__SHIFT 0x17\n#define SQ_SOPK__ENCODING_MASK 0xf0000000\n#define SQ_SOPK__ENCODING__SHIFT 0x1c\n#define SQ_DS_0__OFFSET0_MASK 0xff\n#define SQ_DS_0__OFFSET0__SHIFT 0x0\n#define SQ_DS_0__OFFSET1_MASK 0xff00\n#define SQ_DS_0__OFFSET1__SHIFT 0x8\n#define SQ_DS_0__GDS_MASK 0x20000\n#define SQ_DS_0__GDS__SHIFT 0x11\n#define SQ_DS_0__OP_MASK 0x3fc0000\n#define SQ_DS_0__OP__SHIFT 0x12\n#define SQ_DS_0__ENCODING_MASK 0xfc000000\n#define SQ_DS_0__ENCODING__SHIFT 0x1a\n#define SQ_VOPC__SRC0_MASK 0x1ff\n#define SQ_VOPC__SRC0__SHIFT 0x0\n#define SQ_VOPC__VSRC1_MASK 0x1fe00\n#define SQ_VOPC__VSRC1__SHIFT 0x9\n#define SQ_VOPC__OP_MASK 0x1fe0000\n#define SQ_VOPC__OP__SHIFT 0x11\n#define SQ_VOPC__ENCODING_MASK 0xfe000000\n#define SQ_VOPC__ENCODING__SHIFT 0x19\n#define SQ_VINTRP__VSRC_MASK 0xff\n#define SQ_VINTRP__VSRC__SHIFT 0x0\n#define SQ_VINTRP__ATTRCHAN_MASK 0x300\n#define SQ_VINTRP__ATTRCHAN__SHIFT 0x8\n#define SQ_VINTRP__ATTR_MASK 0xfc00\n#define SQ_VINTRP__ATTR__SHIFT 0xa\n#define SQ_VINTRP__OP_MASK 0x30000\n#define SQ_VINTRP__OP__SHIFT 0x10\n#define SQ_VINTRP__VDST_MASK 0x3fc0000\n#define SQ_VINTRP__VDST__SHIFT 0x12\n#define SQ_VINTRP__ENCODING_MASK 0xfc000000\n#define SQ_VINTRP__ENCODING__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL0__ON_DELAY_MASK 0xf\n#define CGTT_SX_CLK_CTRL0__ON_DELAY__SHIFT 0x0\n#define CGTT_SX_CLK_CTRL0__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SX_CLK_CTRL0__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SX_CLK_CTRL0__RESERVED_MASK 0xfff000\n#define CGTT_SX_CLK_CTRL0__RESERVED__SHIFT 0xc\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SX_CLK_CTRL0__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_SX_CLK_CTRL1__ON_DELAY_MASK 0xf\n#define CGTT_SX_CLK_CTRL1__ON_DELAY__SHIFT 0x0\n#define CGTT_SX_CLK_CTRL1__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SX_CLK_CTRL1__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SX_CLK_CTRL1__RESERVED_MASK 0xfff000\n#define CGTT_SX_CLK_CTRL1__RESERVED__SHIFT 0xc\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SX_CLK_CTRL1__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_SX_CLK_CTRL2__ON_DELAY_MASK 0xf\n#define CGTT_SX_CLK_CTRL2__ON_DELAY__SHIFT 0x0\n#define CGTT_SX_CLK_CTRL2__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SX_CLK_CTRL2__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SX_CLK_CTRL2__RESERVED_MASK 0xfff000\n#define CGTT_SX_CLK_CTRL2__RESERVED__SHIFT 0xc\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SX_CLK_CTRL2__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_SX_CLK_CTRL3__ON_DELAY_MASK 0xf\n#define CGTT_SX_CLK_CTRL3__ON_DELAY__SHIFT 0x0\n#define CGTT_SX_CLK_CTRL3__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SX_CLK_CTRL3__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SX_CLK_CTRL3__RESERVED_MASK 0xfff000\n#define CGTT_SX_CLK_CTRL3__RESERVED__SHIFT 0xc\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SX_CLK_CTRL3__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_SX_CLK_CTRL4__ON_DELAY_MASK 0xf\n#define CGTT_SX_CLK_CTRL4__ON_DELAY__SHIFT 0x0\n#define CGTT_SX_CLK_CTRL4__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_SX_CLK_CTRL4__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_SX_CLK_CTRL4__RESERVED_MASK 0xfff000\n#define CGTT_SX_CLK_CTRL4__RESERVED__SHIFT 0xc\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_SX_CLK_CTRL4__SOFT_OVERRIDE0__SHIFT 0x1f\n#define SX_DEBUG_BUSY__POS_FREE_OR_VALIDS_MASK 0x1\n#define SX_DEBUG_BUSY__POS_FREE_OR_VALIDS__SHIFT 0x0\n#define SX_DEBUG_BUSY__POS_REQUESTER_BUSY_MASK 0x2\n#define SX_DEBUG_BUSY__POS_REQUESTER_BUSY__SHIFT 0x1\n#define SX_DEBUG_BUSY__PA_SX_BUSY_MASK 0x4\n#define SX_DEBUG_BUSY__PA_SX_BUSY__SHIFT 0x2\n#define SX_DEBUG_BUSY__POS_SCBD_BUSY_MASK 0x8\n#define SX_DEBUG_BUSY__POS_SCBD_BUSY__SHIFT 0x3\n#define SX_DEBUG_BUSY__POS_BANK3VAL3_BUSY_MASK 0x10\n#define SX_DEBUG_BUSY__POS_BANK3VAL3_BUSY__SHIFT 0x4\n#define SX_DEBUG_BUSY__POS_BANK3VAL2_BUSY_MASK 0x20\n#define SX_DEBUG_BUSY__POS_BANK3VAL2_BUSY__SHIFT 0x5\n#define SX_DEBUG_BUSY__POS_BANK3VAL1_BUSY_MASK 0x40\n#define SX_DEBUG_BUSY__POS_BANK3VAL1_BUSY__SHIFT 0x6\n#define SX_DEBUG_BUSY__POS_BANK3VAL0_BUSY_MASK 0x80\n#define SX_DEBUG_BUSY__POS_BANK3VAL0_BUSY__SHIFT 0x7\n#define SX_DEBUG_BUSY__POS_BANK2VAL3_BUSY_MASK 0x100\n#define SX_DEBUG_BUSY__POS_BANK2VAL3_BUSY__SHIFT 0x8\n#define SX_DEBUG_BUSY__POS_BANK2VAL2_BUSY_MASK 0x200\n#define SX_DEBUG_BUSY__POS_BANK2VAL2_BUSY__SHIFT 0x9\n#define SX_DEBUG_BUSY__POS_BANK2VAL1_BUSY_MASK 0x400\n#define SX_DEBUG_BUSY__POS_BANK2VAL1_BUSY__SHIFT 0xa\n#define SX_DEBUG_BUSY__POS_BANK2VAL0_BUSY_MASK 0x800\n#define SX_DEBUG_BUSY__POS_BANK2VAL0_BUSY__SHIFT 0xb\n#define SX_DEBUG_BUSY__POS_BANK1VAL3_BUSY_MASK 0x1000\n#define SX_DEBUG_BUSY__POS_BANK1VAL3_BUSY__SHIFT 0xc\n#define SX_DEBUG_BUSY__POS_BANK1VAL2_BUSY_MASK 0x2000\n#define SX_DEBUG_BUSY__POS_BANK1VAL2_BUSY__SHIFT 0xd\n#define SX_DEBUG_BUSY__POS_BANK1VAL1_BUSY_MASK 0x4000\n#define SX_DEBUG_BUSY__POS_BANK1VAL1_BUSY__SHIFT 0xe\n#define SX_DEBUG_BUSY__POS_BANK1VAL0_BUSY_MASK 0x8000\n#define SX_DEBUG_BUSY__POS_BANK1VAL0_BUSY__SHIFT 0xf\n#define SX_DEBUG_BUSY__POS_BANK0VAL3_BUSY_MASK 0x10000\n#define SX_DEBUG_BUSY__POS_BANK0VAL3_BUSY__SHIFT 0x10\n#define SX_DEBUG_BUSY__POS_BANK0VAL2_BUSY_MASK 0x20000\n#define SX_DEBUG_BUSY__POS_BANK0VAL2_BUSY__SHIFT 0x11\n#define SX_DEBUG_BUSY__POS_BANK0VAL1_BUSY_MASK 0x40000\n#define SX_DEBUG_BUSY__POS_BANK0VAL1_BUSY__SHIFT 0x12\n#define SX_DEBUG_BUSY__POS_BANK0VAL0_BUSY_MASK 0x80000\n#define SX_DEBUG_BUSY__POS_BANK0VAL0_BUSY__SHIFT 0x13\n#define SX_DEBUG_BUSY__POS_INMUX_VALID_MASK 0x100000\n#define SX_DEBUG_BUSY__POS_INMUX_VALID__SHIFT 0x14\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ3_MASK 0x200000\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ3__SHIFT 0x15\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ2_MASK 0x400000\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ2__SHIFT 0x16\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ1_MASK 0x800000\n#define SX_DEBUG_BUSY__WRCTRL1_VALIDQ1__SHIFT 0x17\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ3_MASK 0x1000000\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ3__SHIFT 0x18\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ2_MASK 0x2000000\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ2__SHIFT 0x19\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ1_MASK 0x4000000\n#define SX_DEBUG_BUSY__WRCTRL0_VALIDQ1__SHIFT 0x1a\n#define SX_DEBUG_BUSY__PCCMD_VALID_MASK 0x8000000\n#define SX_DEBUG_BUSY__PCCMD_VALID__SHIFT 0x1b\n#define SX_DEBUG_BUSY__VDATA1_VALID_MASK 0x10000000\n#define SX_DEBUG_BUSY__VDATA1_VALID__SHIFT 0x1c\n#define SX_DEBUG_BUSY__VDATA0_VALID_MASK 0x20000000\n#define SX_DEBUG_BUSY__VDATA0_VALID__SHIFT 0x1d\n#define SX_DEBUG_BUSY__CMD_BUSYORVAL_MASK 0x40000000\n#define SX_DEBUG_BUSY__CMD_BUSYORVAL__SHIFT 0x1e\n#define SX_DEBUG_BUSY__ADDR_BUSYORVAL_MASK 0x80000000\n#define SX_DEBUG_BUSY__ADDR_BUSYORVAL__SHIFT 0x1f\n#define SX_DEBUG_BUSY_2__COL_SCBD_BUSY_MASK 0x1\n#define SX_DEBUG_BUSY_2__COL_SCBD_BUSY__SHIFT 0x0\n#define SX_DEBUG_BUSY_2__COL_REQ3_FREECNT_NE0_MASK 0x2\n#define SX_DEBUG_BUSY_2__COL_REQ3_FREECNT_NE0__SHIFT 0x1\n#define SX_DEBUG_BUSY_2__COL_REQ3_IDLE_MASK 0x4\n#define SX_DEBUG_BUSY_2__COL_REQ3_IDLE__SHIFT 0x2\n#define SX_DEBUG_BUSY_2__COL_REQ3_BUSY_MASK 0x8\n#define SX_DEBUG_BUSY_2__COL_REQ3_BUSY__SHIFT 0x3\n#define SX_DEBUG_BUSY_2__COL_REQ2_FREECNT_NE0_MASK 0x10\n#define SX_DEBUG_BUSY_2__COL_REQ2_FREECNT_NE0__SHIFT 0x4\n#define SX_DEBUG_BUSY_2__COL_REQ2_IDLE_MASK 0x20\n#define SX_DEBUG_BUSY_2__COL_REQ2_IDLE__SHIFT 0x5\n#define SX_DEBUG_BUSY_2__COL_REQ2_BUSY_MASK 0x40\n#define SX_DEBUG_BUSY_2__COL_REQ2_BUSY__SHIFT 0x6\n#define SX_DEBUG_BUSY_2__COL_REQ1_FREECNT_NE0_MASK 0x80\n#define SX_DEBUG_BUSY_2__COL_REQ1_FREECNT_NE0__SHIFT 0x7\n#define SX_DEBUG_BUSY_2__COL_REQ1_IDLE_MASK 0x100\n#define SX_DEBUG_BUSY_2__COL_REQ1_IDLE__SHIFT 0x8\n#define SX_DEBUG_BUSY_2__COL_REQ1_BUSY_MASK 0x200\n#define SX_DEBUG_BUSY_2__COL_REQ1_BUSY__SHIFT 0x9\n#define SX_DEBUG_BUSY_2__COL_REQ0_FREECNT_NE0_MASK 0x400\n#define SX_DEBUG_BUSY_2__COL_REQ0_FREECNT_NE0__SHIFT 0xa\n#define SX_DEBUG_BUSY_2__COL_REQ0_IDLE_MASK 0x800\n#define SX_DEBUG_BUSY_2__COL_REQ0_IDLE__SHIFT 0xb\n#define SX_DEBUG_BUSY_2__COL_REQ0_BUSY_MASK 0x1000\n#define SX_DEBUG_BUSY_2__COL_REQ0_BUSY__SHIFT 0xc\n#define SX_DEBUG_BUSY_2__COL_DBIF3_SENDFREE_BUSY_MASK 0x2000\n#define SX_DEBUG_BUSY_2__COL_DBIF3_SENDFREE_BUSY__SHIFT 0xd\n#define SX_DEBUG_BUSY_2__COL_DBIF3_FIFO_BUSY_MASK 0x4000\n#define SX_DEBUG_BUSY_2__COL_DBIF3_FIFO_BUSY__SHIFT 0xe\n#define SX_DEBUG_BUSY_2__COL_DBIF3_READ_VALID_MASK 0x8000\n#define SX_DEBUG_BUSY_2__COL_DBIF3_READ_VALID__SHIFT 0xf\n#define SX_DEBUG_BUSY_2__COL_DBIF2_SENDFREE_BUSY_MASK 0x10000\n#define SX_DEBUG_BUSY_2__COL_DBIF2_SENDFREE_BUSY__SHIFT 0x10\n#define SX_DEBUG_BUSY_2__COL_DBIF2_FIFO_BUSY_MASK 0x20000\n#define SX_DEBUG_BUSY_2__COL_DBIF2_FIFO_BUSY__SHIFT 0x11\n#define SX_DEBUG_BUSY_2__COL_DBIF2_READ_VALID_MASK 0x40000\n#define SX_DEBUG_BUSY_2__COL_DBIF2_READ_VALID__SHIFT 0x12\n#define SX_DEBUG_BUSY_2__COL_DBIF1_SENDFREE_BUSY_MASK 0x80000\n#define SX_DEBUG_BUSY_2__COL_DBIF1_SENDFREE_BUSY__SHIFT 0x13\n#define SX_DEBUG_BUSY_2__COL_DBIF1_FIFO_BUSY_MASK 0x100000\n#define SX_DEBUG_BUSY_2__COL_DBIF1_FIFO_BUSY__SHIFT 0x14\n#define SX_DEBUG_BUSY_2__COL_DBIF1_READ_VALID_MASK 0x200000\n#define SX_DEBUG_BUSY_2__COL_DBIF1_READ_VALID__SHIFT 0x15\n#define SX_DEBUG_BUSY_2__COL_DBIF0_SENDFREE_BUSY_MASK 0x400000\n#define SX_DEBUG_BUSY_2__COL_DBIF0_SENDFREE_BUSY__SHIFT 0x16\n#define SX_DEBUG_BUSY_2__COL_DBIF0_FIFO_BUSY_MASK 0x800000\n#define SX_DEBUG_BUSY_2__COL_DBIF0_FIFO_BUSY__SHIFT 0x17\n#define SX_DEBUG_BUSY_2__COL_DBIF0_READ_VALID_MASK 0x1000000\n#define SX_DEBUG_BUSY_2__COL_DBIF0_READ_VALID__SHIFT 0x18\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL3_BUSY_MASK 0x2000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL3_BUSY__SHIFT 0x19\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL2_BUSY_MASK 0x4000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL2_BUSY__SHIFT 0x1a\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL1_BUSY_MASK 0x8000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL1_BUSY__SHIFT 0x1b\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL0_BUSY_MASK 0x10000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK3_VAL0_BUSY__SHIFT 0x1c\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL3_BUSY_MASK 0x20000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL3_BUSY__SHIFT 0x1d\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL2_BUSY_MASK 0x40000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL2_BUSY__SHIFT 0x1e\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL1_BUSY_MASK 0x80000000\n#define SX_DEBUG_BUSY_2__COL_BUFF3_BANK2_VAL1_BUSY__SHIFT 0x1f\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK2_VAL0_BUSY_MASK 0x1\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK2_VAL0_BUSY__SHIFT 0x0\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL3_BUSY_MASK 0x2\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL3_BUSY__SHIFT 0x1\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL2_BUSY_MASK 0x4\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL2_BUSY__SHIFT 0x2\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL1_BUSY_MASK 0x8\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL1_BUSY__SHIFT 0x3\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL0_BUSY_MASK 0x10\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK1_VAL0_BUSY__SHIFT 0x4\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL3_BUSY_MASK 0x20\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL3_BUSY__SHIFT 0x5\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL2_BUSY_MASK 0x40\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL2_BUSY__SHIFT 0x6\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL1_BUSY_MASK 0x80\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL1_BUSY__SHIFT 0x7\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL0_BUSY_MASK 0x100\n#define SX_DEBUG_BUSY_3__COL_BUFF3_BANK0_VAL0_BUSY__SHIFT 0x8\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL3_BUSY_MASK 0x200\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL3_BUSY__SHIFT 0x9\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL2_BUSY_MASK 0x400\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL2_BUSY__SHIFT 0xa\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL1_BUSY_MASK 0x800\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL1_BUSY__SHIFT 0xb\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL0_BUSY_MASK 0x1000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK3_VAL0_BUSY__SHIFT 0xc\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL3_BUSY_MASK 0x2000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL3_BUSY__SHIFT 0xd\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL2_BUSY_MASK 0x4000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL2_BUSY__SHIFT 0xe\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL1_BUSY_MASK 0x8000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL1_BUSY__SHIFT 0xf\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL0_BUSY_MASK 0x10000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK2_VAL0_BUSY__SHIFT 0x10\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL3_BUSY_MASK 0x20000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL3_BUSY__SHIFT 0x11\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL2_BUSY_MASK 0x40000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL2_BUSY__SHIFT 0x12\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL1_BUSY_MASK 0x80000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL1_BUSY__SHIFT 0x13\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL0_BUSY_MASK 0x100000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK1_VAL0_BUSY__SHIFT 0x14\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL3_BUSY_MASK 0x200000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL3_BUSY__SHIFT 0x15\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL2_BUSY_MASK 0x400000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL2_BUSY__SHIFT 0x16\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL1_BUSY_MASK 0x800000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL1_BUSY__SHIFT 0x17\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL0_BUSY_MASK 0x1000000\n#define SX_DEBUG_BUSY_3__COL_BUFF2_BANK0_VAL0_BUSY__SHIFT 0x18\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL3_BUSY_MASK 0x2000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL3_BUSY__SHIFT 0x19\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL2_BUSY_MASK 0x4000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL2_BUSY__SHIFT 0x1a\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL1_BUSY_MASK 0x8000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL1_BUSY__SHIFT 0x1b\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL0_BUSY_MASK 0x10000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK3_VAL0_BUSY__SHIFT 0x1c\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL3_BUSY_MASK 0x20000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL3_BUSY__SHIFT 0x1d\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL2_BUSY_MASK 0x40000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL2_BUSY__SHIFT 0x1e\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL1_BUSY_MASK 0x80000000\n#define SX_DEBUG_BUSY_3__COL_BUFF1_BANK2_VAL1_BUSY__SHIFT 0x1f\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK2_VAL0_BUSY_MASK 0x1\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK2_VAL0_BUSY__SHIFT 0x0\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL3_BUSY_MASK 0x2\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL3_BUSY__SHIFT 0x1\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL2_BUSY_MASK 0x4\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL2_BUSY__SHIFT 0x2\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL1_BUSY_MASK 0x8\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL1_BUSY__SHIFT 0x3\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL0_BUSY_MASK 0x10\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK1_VAL0_BUSY__SHIFT 0x4\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL3_BUSY_MASK 0x20\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL3_BUSY__SHIFT 0x5\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL2_BUSY_MASK 0x40\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL2_BUSY__SHIFT 0x6\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL1_BUSY_MASK 0x80\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL1_BUSY__SHIFT 0x7\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL0_BUSY_MASK 0x100\n#define SX_DEBUG_BUSY_4__COL_BUFF1_BANK0_VAL0_BUSY__SHIFT 0x8\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL3_BUSY_MASK 0x200\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL3_BUSY__SHIFT 0x9\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL2_BUSY_MASK 0x400\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL2_BUSY__SHIFT 0xa\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL1_BUSY_MASK 0x800\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL1_BUSY__SHIFT 0xb\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL0_BUSY_MASK 0x1000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK3_VAL0_BUSY__SHIFT 0xc\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL3_BUSY_MASK 0x2000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL3_BUSY__SHIFT 0xd\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL2_BUSY_MASK 0x4000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL2_BUSY__SHIFT 0xe\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL1_BUSY_MASK 0x8000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL1_BUSY__SHIFT 0xf\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL0_BUSY_MASK 0x10000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK2_VAL0_BUSY__SHIFT 0x10\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL3_BUSY_MASK 0x20000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL3_BUSY__SHIFT 0x11\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL2_BUSY_MASK 0x40000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL2_BUSY__SHIFT 0x12\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL1_BUSY_MASK 0x80000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL1_BUSY__SHIFT 0x13\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL0_BUSY_MASK 0x100000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK1_VAL0_BUSY__SHIFT 0x14\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL3_BUSY_MASK 0x200000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL3_BUSY__SHIFT 0x15\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL2_BUSY_MASK 0x400000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL2_BUSY__SHIFT 0x16\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL1_BUSY_MASK 0x800000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL1_BUSY__SHIFT 0x17\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL0_BUSY_MASK 0x1000000\n#define SX_DEBUG_BUSY_4__COL_BUFF0_BANK0_VAL0_BUSY__SHIFT 0x18\n#define SX_DEBUG_BUSY_4__RESERVED_MASK 0xfe000000\n#define SX_DEBUG_BUSY_4__RESERVED__SHIFT 0x19\n#define SX_DEBUG_1__SX_DB_QUAD_CREDIT_MASK 0x7f\n#define SX_DEBUG_1__SX_DB_QUAD_CREDIT__SHIFT 0x0\n#define SX_DEBUG_1__DEBUG_DATA_MASK 0xffffff80\n#define SX_DEBUG_1__DEBUG_DATA__SHIFT 0x7\n#define SX_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define SX_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define SX_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define SX_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define SX_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define SX_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define SX_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define SX_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define SX_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define SX_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define SX_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define SX_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define SX_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define SX_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define SX_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define SX_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define SX_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define SX_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define SX_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define SX_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define SX_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define SX_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define SX_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define SX_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define SX_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT2_MASK 0x3ff\n#define SX_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT2__SHIFT 0x0\n#define SX_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT3_MASK 0xffc00\n#define SX_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT3__SHIFT 0xa\n#define SX_PERFCOUNTER1_SELECT1__PERFCOUNTER_SELECT2_MASK 0x3ff\n#define SX_PERFCOUNTER1_SELECT1__PERFCOUNTER_SELECT2__SHIFT 0x0\n#define SX_PERFCOUNTER1_SELECT1__PERFCOUNTER_SELECT3_MASK 0xffc00\n#define SX_PERFCOUNTER1_SELECT1__PERFCOUNTER_SELECT3__SHIFT 0xa\n#define SX_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SX_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SX_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SX_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SX_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SX_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SX_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SX_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SX_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SX_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SX_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SX_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define SX_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define SX_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define SX_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define SX_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCC_CTRL__CACHE_SIZE_MASK 0x3\n#define TCC_CTRL__CACHE_SIZE__SHIFT 0x0\n#define TCC_CTRL__RATE_MASK 0xc\n#define TCC_CTRL__RATE__SHIFT 0x2\n#define TCC_CTRL__WRITEBACK_MARGIN_MASK 0xf0\n#define TCC_CTRL__WRITEBACK_MARGIN__SHIFT 0x4\n#define TCC_CTRL__SRC_FIFO_SIZE_MASK 0xf000\n#define TCC_CTRL__SRC_FIFO_SIZE__SHIFT 0xc\n#define TCC_CTRL__LATENCY_FIFO_SIZE_MASK 0xf0000\n#define TCC_CTRL__LATENCY_FIFO_SIZE__SHIFT 0x10\n#define TCC_CTRL__WB_OR_INV_ALL_VMIDS_MASK 0x100000\n#define TCC_CTRL__WB_OR_INV_ALL_VMIDS__SHIFT 0x14\n#define TCC_EDC_COUNTER__SEC_COUNT_MASK 0xf\n#define TCC_EDC_COUNTER__SEC_COUNT__SHIFT 0x0\n#define TCC_EDC_COUNTER__DED_COUNT_MASK 0xf0000\n#define TCC_EDC_COUNTER__DED_COUNT__SHIFT 0x10\n#define TCC_REDUNDANCY__MC_SEL0_MASK 0x1\n#define TCC_REDUNDANCY__MC_SEL0__SHIFT 0x0\n#define TCC_REDUNDANCY__MC_SEL1_MASK 0x2\n#define TCC_REDUNDANCY__MC_SEL1__SHIFT 0x1\n#define TCC_CGTT_SCLK_CTRL__ON_DELAY_MASK 0xf\n#define TCC_CGTT_SCLK_CTRL__ON_DELAY__SHIFT 0x0\n#define TCC_CGTT_SCLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define TCC_CGTT_SCLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define TCC_CGTT_SCLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define TCA_CGTT_SCLK_CTRL__ON_DELAY_MASK 0xf\n#define TCA_CGTT_SCLK_CTRL__ON_DELAY__SHIFT 0x0\n#define TCA_CGTT_SCLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define TCA_CGTT_SCLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define TCA_CGTT_SCLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define TCS_CGTT_SCLK_CTRL__ON_DELAY_MASK 0xf\n#define TCS_CGTT_SCLK_CTRL__ON_DELAY__SHIFT 0x0\n#define TCS_CGTT_SCLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define TCS_CGTT_SCLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define TCS_CGTT_SCLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define TCC_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define TCC_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TCC_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCC_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCC_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCC_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCC_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCC_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCC_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCC_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCC_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define TCC_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TCC_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCC_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCC_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCC_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCC_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCC_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCC_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCC_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCC_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCC_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCC_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCC_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCC_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf000000\n#define TCC_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x18\n#define TCC_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf0000000\n#define TCC_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x1c\n#define TCC_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCC_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCC_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCC_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCC_PERFCOUNTER1_SELECT1__PERF_MODE2_MASK 0xf000000\n#define TCC_PERFCOUNTER1_SELECT1__PERF_MODE2__SHIFT 0x18\n#define TCC_PERFCOUNTER1_SELECT1__PERF_MODE3_MASK 0xf0000000\n#define TCC_PERFCOUNTER1_SELECT1__PERF_MODE3__SHIFT 0x1c\n#define TCC_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define TCC_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define TCC_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCC_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCC_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCC_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCC_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define TCC_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define TCC_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCC_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCC_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCC_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCC_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCC_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCC_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCC_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCC_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCC_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCC_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCC_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCC_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCC_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCC_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCC_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCC_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCC_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCC_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCC_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCA_CTRL__HOLE_TIMEOUT_MASK 0xf\n#define TCA_CTRL__HOLE_TIMEOUT__SHIFT 0x0\n#define TCA_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define TCA_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TCA_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCA_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCA_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCA_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCA_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCA_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCA_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCA_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCA_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define TCA_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TCA_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCA_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCA_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCA_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCA_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCA_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCA_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCA_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCA_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCA_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCA_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCA_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCA_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf000000\n#define TCA_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x18\n#define TCA_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf0000000\n#define TCA_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x1c\n#define TCA_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCA_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCA_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCA_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCA_PERFCOUNTER1_SELECT1__PERF_MODE2_MASK 0xf000000\n#define TCA_PERFCOUNTER1_SELECT1__PERF_MODE2__SHIFT 0x18\n#define TCA_PERFCOUNTER1_SELECT1__PERF_MODE3_MASK 0xf0000000\n#define TCA_PERFCOUNTER1_SELECT1__PERF_MODE3__SHIFT 0x1c\n#define TCA_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define TCA_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define TCA_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCA_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCA_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCA_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCA_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define TCA_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define TCA_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCA_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCA_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCA_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCA_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCA_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCA_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCA_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCA_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCA_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCA_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCA_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCA_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCA_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCA_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCA_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCA_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCA_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCA_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCA_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCS_CTRL__RATE_MASK 0x3\n#define TCS_CTRL__RATE__SHIFT 0x0\n#define TCS_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define TCS_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TCS_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCS_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCS_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCS_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCS_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCS_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCS_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCS_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCS_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCS_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCS_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCS_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCS_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf000000\n#define TCS_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x18\n#define TCS_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf0000000\n#define TCS_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x1c\n#define TCS_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define TCS_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TCS_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCS_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCS_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCS_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCS_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define TCS_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define TCS_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCS_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCS_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCS_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCS_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define TCS_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define TCS_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCS_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCS_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCS_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCS_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCS_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCS_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCS_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCS_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCS_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCS_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCS_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCS_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCS_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCS_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCS_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCS_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCS_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCS_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCS_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TA_BC_BASE_ADDR__ADDRESS_MASK 0xffffffff\n#define TA_BC_BASE_ADDR__ADDRESS__SHIFT 0x0\n#define TA_BC_BASE_ADDR_HI__ADDRESS_MASK 0xff\n#define TA_BC_BASE_ADDR_HI__ADDRESS__SHIFT 0x0\n#define TD_CNTL__SYNC_PHASE_SH_MASK 0x3\n#define TD_CNTL__SYNC_PHASE_SH__SHIFT 0x0\n#define TD_CNTL__SYNC_PHASE_VC_SMX_MASK 0x30\n#define TD_CNTL__SYNC_PHASE_VC_SMX__SHIFT 0x4\n#define TD_CNTL__PAD_STALL_EN_MASK 0x100\n#define TD_CNTL__PAD_STALL_EN__SHIFT 0x8\n#define TD_CNTL__EXTEND_LDS_STALL_MASK 0x600\n#define TD_CNTL__EXTEND_LDS_STALL__SHIFT 0x9\n#define TD_CNTL__LDS_STALL_PHASE_ADJUST_MASK 0x1800\n#define TD_CNTL__LDS_STALL_PHASE_ADJUST__SHIFT 0xb\n#define TD_CNTL__PRECISION_COMPATIBILITY_MASK 0x8000\n#define TD_CNTL__PRECISION_COMPATIBILITY__SHIFT 0xf\n#define TD_CNTL__GATHER4_FLOAT_MODE_MASK 0x10000\n#define TD_CNTL__GATHER4_FLOAT_MODE__SHIFT 0x10\n#define TD_CNTL__LD_FLOAT_MODE_MASK 0x40000\n#define TD_CNTL__LD_FLOAT_MODE__SHIFT 0x12\n#define TD_CNTL__GATHER4_DX9_MODE_MASK 0x80000\n#define TD_CNTL__GATHER4_DX9_MODE__SHIFT 0x13\n#define TD_CNTL__DISABLE_POWER_THROTTLE_MASK 0x100000\n#define TD_CNTL__DISABLE_POWER_THROTTLE__SHIFT 0x14\n#define TD_STATUS__BUSY_MASK 0x80000000\n#define TD_STATUS__BUSY__SHIFT 0x1f\n#define TD_DEBUG_INDEX__INDEX_MASK 0x1f\n#define TD_DEBUG_INDEX__INDEX__SHIFT 0x0\n#define TD_DEBUG_DATA__DATA_MASK 0xffffffff\n#define TD_DEBUG_DATA__DATA__SHIFT 0x0\n#define TD_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0xff\n#define TD_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TD_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0x3fc00\n#define TD_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TD_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TD_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TD_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TD_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TD_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TD_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TD_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0xff\n#define TD_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TD_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0x3fc00\n#define TD_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define TD_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TD_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TD_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define TD_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define TD_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TD_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TD_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0xff\n#define TD_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TD_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0x3fc00\n#define TD_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TD_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define TD_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define TD_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define TD_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define TD_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TD_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TD_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TD_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TD_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TD_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TD_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TD_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TD_SCRATCH__SCRATCH_MASK 0xffffffff\n#define TD_SCRATCH__SCRATCH__SHIFT 0x0\n#define TA_CNTL__TC_DATA_CREDIT_MASK 0xe000\n#define TA_CNTL__TC_DATA_CREDIT__SHIFT 0xd\n#define TA_CNTL__ALIGNER_CREDIT_MASK 0x1f0000\n#define TA_CNTL__ALIGNER_CREDIT__SHIFT 0x10\n#define TA_CNTL__TD_FIFO_CREDIT_MASK 0xffc00000\n#define TA_CNTL__TD_FIFO_CREDIT__SHIFT 0x16\n#define TA_CNTL_AUX__SCOAL_DSWIZZLE_N_MASK 0x1\n#define TA_CNTL_AUX__SCOAL_DSWIZZLE_N__SHIFT 0x0\n#define TA_CNTL_AUX__RESERVED_MASK 0xe\n#define TA_CNTL_AUX__RESERVED__SHIFT 0x1\n#define TA_CNTL_AUX__ANISO_WEIGHT_MODE_MASK 0x10000\n#define TA_CNTL_AUX__ANISO_WEIGHT_MODE__SHIFT 0x10\n#define TA_RESERVED_010C__Unused_MASK 0xffffffff\n#define TA_RESERVED_010C__Unused__SHIFT 0x0\n#define TA_CS_BC_BASE_ADDR__ADDRESS_MASK 0xffffffff\n#define TA_CS_BC_BASE_ADDR__ADDRESS__SHIFT 0x0\n#define TA_CS_BC_BASE_ADDR_HI__ADDRESS_MASK 0xff\n#define TA_CS_BC_BASE_ADDR_HI__ADDRESS__SHIFT 0x0\n#define TA_STATUS__FG_PFIFO_EMPTYB_MASK 0x1000\n#define TA_STATUS__FG_PFIFO_EMPTYB__SHIFT 0xc\n#define TA_STATUS__FG_LFIFO_EMPTYB_MASK 0x2000\n#define TA_STATUS__FG_LFIFO_EMPTYB__SHIFT 0xd\n#define TA_STATUS__FG_SFIFO_EMPTYB_MASK 0x4000\n#define TA_STATUS__FG_SFIFO_EMPTYB__SHIFT 0xe\n#define TA_STATUS__FL_PFIFO_EMPTYB_MASK 0x10000\n#define TA_STATUS__FL_PFIFO_EMPTYB__SHIFT 0x10\n#define TA_STATUS__FL_LFIFO_EMPTYB_MASK 0x20000\n#define TA_STATUS__FL_LFIFO_EMPTYB__SHIFT 0x11\n#define TA_STATUS__FL_SFIFO_EMPTYB_MASK 0x40000\n#define TA_STATUS__FL_SFIFO_EMPTYB__SHIFT 0x12\n#define TA_STATUS__FA_PFIFO_EMPTYB_MASK 0x100000\n#define TA_STATUS__FA_PFIFO_EMPTYB__SHIFT 0x14\n#define TA_STATUS__FA_LFIFO_EMPTYB_MASK 0x200000\n#define TA_STATUS__FA_LFIFO_EMPTYB__SHIFT 0x15\n#define TA_STATUS__FA_SFIFO_EMPTYB_MASK 0x400000\n#define TA_STATUS__FA_SFIFO_EMPTYB__SHIFT 0x16\n#define TA_STATUS__IN_BUSY_MASK 0x1000000\n#define TA_STATUS__IN_BUSY__SHIFT 0x18\n#define TA_STATUS__FG_BUSY_MASK 0x2000000\n#define TA_STATUS__FG_BUSY__SHIFT 0x19\n#define TA_STATUS__LA_BUSY_MASK 0x4000000\n#define TA_STATUS__LA_BUSY__SHIFT 0x1a\n#define TA_STATUS__FL_BUSY_MASK 0x8000000\n#define TA_STATUS__FL_BUSY__SHIFT 0x1b\n#define TA_STATUS__TA_BUSY_MASK 0x10000000\n#define TA_STATUS__TA_BUSY__SHIFT 0x1c\n#define TA_STATUS__FA_BUSY_MASK 0x20000000\n#define TA_STATUS__FA_BUSY__SHIFT 0x1d\n#define TA_STATUS__AL_BUSY_MASK 0x40000000\n#define TA_STATUS__AL_BUSY__SHIFT 0x1e\n#define TA_STATUS__BUSY_MASK 0x80000000\n#define TA_STATUS__BUSY__SHIFT 0x1f\n#define TA_DEBUG_INDEX__INDEX_MASK 0x1f\n#define TA_DEBUG_INDEX__INDEX__SHIFT 0x0\n#define TA_DEBUG_DATA__DATA_MASK 0xffffffff\n#define TA_DEBUG_DATA__DATA__SHIFT 0x0\n#define TA_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0xff\n#define TA_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TA_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0x3fc00\n#define TA_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TA_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TA_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TA_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TA_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TA_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TA_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TA_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0xff\n#define TA_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TA_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0x3fc00\n#define TA_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define TA_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TA_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TA_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define TA_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define TA_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TA_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TA_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0xff\n#define TA_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TA_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0x3fc00\n#define TA_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TA_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define TA_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define TA_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define TA_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define TA_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TA_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TA_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TA_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TA_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TA_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TA_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TA_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TA_SCRATCH__SCRATCH_MASK 0xffffffff\n#define TA_SCRATCH__SCRATCH__SHIFT 0x0\n#define SH_HIDDEN_PRIVATE_BASE_VMID__ADDRESS_MASK 0xffffffff\n#define SH_HIDDEN_PRIVATE_BASE_VMID__ADDRESS__SHIFT 0x0\n#define SH_STATIC_MEM_CONFIG__SWIZZLE_ENABLE_MASK 0x1\n#define SH_STATIC_MEM_CONFIG__SWIZZLE_ENABLE__SHIFT 0x0\n#define SH_STATIC_MEM_CONFIG__ELEMENT_SIZE_MASK 0x6\n#define SH_STATIC_MEM_CONFIG__ELEMENT_SIZE__SHIFT 0x1\n#define SH_STATIC_MEM_CONFIG__INDEX_STRIDE_MASK 0x18\n#define SH_STATIC_MEM_CONFIG__INDEX_STRIDE__SHIFT 0x3\n#define SH_STATIC_MEM_CONFIG__PRIVATE_MTYPE_MASK 0xe0\n#define SH_STATIC_MEM_CONFIG__PRIVATE_MTYPE__SHIFT 0x5\n#define SH_STATIC_MEM_CONFIG__READ_ONLY_CNTL_MASK 0xff00\n#define SH_STATIC_MEM_CONFIG__READ_ONLY_CNTL__SHIFT 0x8\n#define TCP_INVALIDATE__START_MASK 0x1\n#define TCP_INVALIDATE__START__SHIFT 0x0\n#define TCP_STATUS__TCP_BUSY_MASK 0x1\n#define TCP_STATUS__TCP_BUSY__SHIFT 0x0\n#define TCP_CNTL__FORCE_HIT_MASK 0x1\n#define TCP_CNTL__FORCE_HIT__SHIFT 0x0\n#define TCP_CNTL__FORCE_MISS_MASK 0x2\n#define TCP_CNTL__FORCE_MISS__SHIFT 0x1\n#define TCP_CNTL__L1_SIZE_MASK 0xc\n#define TCP_CNTL__L1_SIZE__SHIFT 0x2\n#define TCP_CNTL__FLAT_BUF_HASH_ENABLE_MASK 0x10\n#define TCP_CNTL__FLAT_BUF_HASH_ENABLE__SHIFT 0x4\n#define TCP_CNTL__FLAT_BUF_CACHE_SWIZZLE_MASK 0x20\n#define TCP_CNTL__FLAT_BUF_CACHE_SWIZZLE__SHIFT 0x5\n#define TCP_CNTL__FORCE_EOW_TOTAL_CNT_MASK 0x1f8000\n#define TCP_CNTL__FORCE_EOW_TOTAL_CNT__SHIFT 0xf\n#define TCP_CNTL__FORCE_EOW_TAGRAM_CNT_MASK 0xfc00000\n#define TCP_CNTL__FORCE_EOW_TAGRAM_CNT__SHIFT 0x16\n#define TCP_CNTL__DISABLE_Z_MAP_MASK 0x10000000\n#define TCP_CNTL__DISABLE_Z_MAP__SHIFT 0x1c\n#define TCP_CNTL__INV_ALL_VMIDS_MASK 0x20000000\n#define TCP_CNTL__INV_ALL_VMIDS__SHIFT 0x1d\n#define TCP_CHAN_STEER_LO__CHAN0_MASK 0xf\n#define TCP_CHAN_STEER_LO__CHAN0__SHIFT 0x0\n#define TCP_CHAN_STEER_LO__CHAN1_MASK 0xf0\n#define TCP_CHAN_STEER_LO__CHAN1__SHIFT 0x4\n#define TCP_CHAN_STEER_LO__CHAN2_MASK 0xf00\n#define TCP_CHAN_STEER_LO__CHAN2__SHIFT 0x8\n#define TCP_CHAN_STEER_LO__CHAN3_MASK 0xf000\n#define TCP_CHAN_STEER_LO__CHAN3__SHIFT 0xc\n#define TCP_CHAN_STEER_LO__CHAN4_MASK 0xf0000\n#define TCP_CHAN_STEER_LO__CHAN4__SHIFT 0x10\n#define TCP_CHAN_STEER_LO__CHAN5_MASK 0xf00000\n#define TCP_CHAN_STEER_LO__CHAN5__SHIFT 0x14\n#define TCP_CHAN_STEER_LO__CHAN6_MASK 0xf000000\n#define TCP_CHAN_STEER_LO__CHAN6__SHIFT 0x18\n#define TCP_CHAN_STEER_LO__CHAN7_MASK 0xf0000000\n#define TCP_CHAN_STEER_LO__CHAN7__SHIFT 0x1c\n#define TCP_CHAN_STEER_HI__CHAN8_MASK 0xf\n#define TCP_CHAN_STEER_HI__CHAN8__SHIFT 0x0\n#define TCP_CHAN_STEER_HI__CHAN9_MASK 0xf0\n#define TCP_CHAN_STEER_HI__CHAN9__SHIFT 0x4\n#define TCP_CHAN_STEER_HI__CHANA_MASK 0xf00\n#define TCP_CHAN_STEER_HI__CHANA__SHIFT 0x8\n#define TCP_CHAN_STEER_HI__CHANB_MASK 0xf000\n#define TCP_CHAN_STEER_HI__CHANB__SHIFT 0xc\n#define TCP_CHAN_STEER_HI__CHANC_MASK 0xf0000\n#define TCP_CHAN_STEER_HI__CHANC__SHIFT 0x10\n#define TCP_CHAN_STEER_HI__CHAND_MASK 0xf00000\n#define TCP_CHAN_STEER_HI__CHAND__SHIFT 0x14\n#define TCP_CHAN_STEER_HI__CHANE_MASK 0xf000000\n#define TCP_CHAN_STEER_HI__CHANE__SHIFT 0x18\n#define TCP_CHAN_STEER_HI__CHANF_MASK 0xf0000000\n#define TCP_CHAN_STEER_HI__CHANF__SHIFT 0x1c\n#define TCP_ADDR_CONFIG__NUM_TCC_BANKS_MASK 0xf\n#define TCP_ADDR_CONFIG__NUM_TCC_BANKS__SHIFT 0x0\n#define TCP_ADDR_CONFIG__NUM_BANKS_MASK 0x30\n#define TCP_ADDR_CONFIG__NUM_BANKS__SHIFT 0x4\n#define TCP_ADDR_CONFIG__COLHI_WIDTH_MASK 0x1c0\n#define TCP_ADDR_CONFIG__COLHI_WIDTH__SHIFT 0x6\n#define TCP_ADDR_CONFIG__RB_SPLIT_COLHI_MASK 0x200\n#define TCP_ADDR_CONFIG__RB_SPLIT_COLHI__SHIFT 0x9\n#define TCP_CREDIT__LFIFO_CREDIT_MASK 0x3ff\n#define TCP_CREDIT__LFIFO_CREDIT__SHIFT 0x0\n#define TCP_CREDIT__REQ_FIFO_CREDIT_MASK 0x7f0000\n#define TCP_CREDIT__REQ_FIFO_CREDIT__SHIFT 0x10\n#define TCP_CREDIT__TD_CREDIT_MASK 0xe0000000\n#define TCP_CREDIT__TD_CREDIT__SHIFT 0x1d\n#define TCP_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define TCP_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define TCP_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCP_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCP_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCP_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCP_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCP_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCP_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCP_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCP_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define TCP_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define TCP_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define TCP_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define TCP_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCP_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCP_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define TCP_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define TCP_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCP_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCP_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCP_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCP_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCP_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCP_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define TCP_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define TCP_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define TCP_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define TCP_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define TCP_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define TCP_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define TCP_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define TCP_PERFCOUNTER1_SELECT1__PERF_MODE3_MASK 0xf000000\n#define TCP_PERFCOUNTER1_SELECT1__PERF_MODE3__SHIFT 0x18\n#define TCP_PERFCOUNTER1_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define TCP_PERFCOUNTER1_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define TCP_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0x3ff\n#define TCP_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define TCP_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCP_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCP_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCP_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCP_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0x3ff\n#define TCP_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define TCP_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define TCP_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define TCP_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define TCP_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define TCP_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCP_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCP_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCP_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCP_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCP_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCP_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define TCP_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define TCP_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCP_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCP_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCP_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCP_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCP_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCP_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define TCP_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define TCP_BUFFER_ADDR_HASH_CNTL__CHANNEL_BITS_MASK 0x7\n#define TCP_BUFFER_ADDR_HASH_CNTL__CHANNEL_BITS__SHIFT 0x0\n#define TCP_BUFFER_ADDR_HASH_CNTL__BANK_BITS_MASK 0x700\n#define TCP_BUFFER_ADDR_HASH_CNTL__BANK_BITS__SHIFT 0x8\n#define TCP_BUFFER_ADDR_HASH_CNTL__CHANNEL_XOR_COUNT_MASK 0x70000\n#define TCP_BUFFER_ADDR_HASH_CNTL__CHANNEL_XOR_COUNT__SHIFT 0x10\n#define TCP_BUFFER_ADDR_HASH_CNTL__BANK_XOR_COUNT_MASK 0x7000000\n#define TCP_BUFFER_ADDR_HASH_CNTL__BANK_XOR_COUNT__SHIFT 0x18\n#define TCP_EDC_COUNTER__SEC_COUNT_MASK 0xf\n#define TCP_EDC_COUNTER__SEC_COUNT__SHIFT 0x0\n#define TCP_EDC_COUNTER__DED_COUNT_MASK 0xf0000\n#define TCP_EDC_COUNTER__DED_COUNT__SHIFT 0x10\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_0_MASK 0x3\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_0__SHIFT 0x0\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_1_MASK 0xc\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_1__SHIFT 0x2\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_2_MASK 0x30\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_2__SHIFT 0x4\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_3_MASK 0xc0\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_3__SHIFT 0x6\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_4_MASK 0x300\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_4__SHIFT 0x8\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_5_MASK 0xc00\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_5__SHIFT 0xa\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_6_MASK 0x3000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_6__SHIFT 0xc\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_7_MASK 0xc000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_7__SHIFT 0xe\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_8_MASK 0x30000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_8__SHIFT 0x10\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_9_MASK 0xc0000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_9__SHIFT 0x12\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_10_MASK 0x300000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_10__SHIFT 0x14\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_11_MASK 0xc00000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_11__SHIFT 0x16\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_12_MASK 0x3000000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_12__SHIFT 0x18\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_13_MASK 0xc000000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_13__SHIFT 0x1a\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_14_MASK 0x30000000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_14__SHIFT 0x1c\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_15_MASK 0xc0000000\n#define TC_CFG_L1_LOAD_POLICY0__POLICY_15__SHIFT 0x1e\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_16_MASK 0x3\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_16__SHIFT 0x0\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_17_MASK 0xc\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_17__SHIFT 0x2\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_18_MASK 0x30\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_18__SHIFT 0x4\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_19_MASK 0xc0\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_19__SHIFT 0x6\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_20_MASK 0x300\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_20__SHIFT 0x8\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_21_MASK 0xc00\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_21__SHIFT 0xa\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_22_MASK 0x3000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_22__SHIFT 0xc\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_23_MASK 0xc000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_23__SHIFT 0xe\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_24_MASK 0x30000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_24__SHIFT 0x10\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_25_MASK 0xc0000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_25__SHIFT 0x12\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_26_MASK 0x300000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_26__SHIFT 0x14\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_27_MASK 0xc00000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_27__SHIFT 0x16\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_28_MASK 0x3000000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_28__SHIFT 0x18\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_29_MASK 0xc000000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_29__SHIFT 0x1a\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_30_MASK 0x30000000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_30__SHIFT 0x1c\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_31_MASK 0xc0000000\n#define TC_CFG_L1_LOAD_POLICY1__POLICY_31__SHIFT 0x1e\n#define TC_CFG_L1_STORE_POLICY__POLICY_0_MASK 0x1\n#define TC_CFG_L1_STORE_POLICY__POLICY_0__SHIFT 0x0\n#define TC_CFG_L1_STORE_POLICY__POLICY_1_MASK 0x2\n#define TC_CFG_L1_STORE_POLICY__POLICY_1__SHIFT 0x1\n#define TC_CFG_L1_STORE_POLICY__POLICY_2_MASK 0x4\n#define TC_CFG_L1_STORE_POLICY__POLICY_2__SHIFT 0x2\n#define TC_CFG_L1_STORE_POLICY__POLICY_3_MASK 0x8\n#define TC_CFG_L1_STORE_POLICY__POLICY_3__SHIFT 0x3\n#define TC_CFG_L1_STORE_POLICY__POLICY_4_MASK 0x10\n#define TC_CFG_L1_STORE_POLICY__POLICY_4__SHIFT 0x4\n#define TC_CFG_L1_STORE_POLICY__POLICY_5_MASK 0x20\n#define TC_CFG_L1_STORE_POLICY__POLICY_5__SHIFT 0x5\n#define TC_CFG_L1_STORE_POLICY__POLICY_6_MASK 0x40\n#define TC_CFG_L1_STORE_POLICY__POLICY_6__SHIFT 0x6\n#define TC_CFG_L1_STORE_POLICY__POLICY_7_MASK 0x80\n#define TC_CFG_L1_STORE_POLICY__POLICY_7__SHIFT 0x7\n#define TC_CFG_L1_STORE_POLICY__POLICY_8_MASK 0x100\n#define TC_CFG_L1_STORE_POLICY__POLICY_8__SHIFT 0x8\n#define TC_CFG_L1_STORE_POLICY__POLICY_9_MASK 0x200\n#define TC_CFG_L1_STORE_POLICY__POLICY_9__SHIFT 0x9\n#define TC_CFG_L1_STORE_POLICY__POLICY_10_MASK 0x400\n#define TC_CFG_L1_STORE_POLICY__POLICY_10__SHIFT 0xa\n#define TC_CFG_L1_STORE_POLICY__POLICY_11_MASK 0x800\n#define TC_CFG_L1_STORE_POLICY__POLICY_11__SHIFT 0xb\n#define TC_CFG_L1_STORE_POLICY__POLICY_12_MASK 0x1000\n#define TC_CFG_L1_STORE_POLICY__POLICY_12__SHIFT 0xc\n#define TC_CFG_L1_STORE_POLICY__POLICY_13_MASK 0x2000\n#define TC_CFG_L1_STORE_POLICY__POLICY_13__SHIFT 0xd\n#define TC_CFG_L1_STORE_POLICY__POLICY_14_MASK 0x4000\n#define TC_CFG_L1_STORE_POLICY__POLICY_14__SHIFT 0xe\n#define TC_CFG_L1_STORE_POLICY__POLICY_15_MASK 0x8000\n#define TC_CFG_L1_STORE_POLICY__POLICY_15__SHIFT 0xf\n#define TC_CFG_L1_STORE_POLICY__POLICY_16_MASK 0x10000\n#define TC_CFG_L1_STORE_POLICY__POLICY_16__SHIFT 0x10\n#define TC_CFG_L1_STORE_POLICY__POLICY_17_MASK 0x20000\n#define TC_CFG_L1_STORE_POLICY__POLICY_17__SHIFT 0x11\n#define TC_CFG_L1_STORE_POLICY__POLICY_18_MASK 0x40000\n#define TC_CFG_L1_STORE_POLICY__POLICY_18__SHIFT 0x12\n#define TC_CFG_L1_STORE_POLICY__POLICY_19_MASK 0x80000\n#define TC_CFG_L1_STORE_POLICY__POLICY_19__SHIFT 0x13\n#define TC_CFG_L1_STORE_POLICY__POLICY_20_MASK 0x100000\n#define TC_CFG_L1_STORE_POLICY__POLICY_20__SHIFT 0x14\n#define TC_CFG_L1_STORE_POLICY__POLICY_21_MASK 0x200000\n#define TC_CFG_L1_STORE_POLICY__POLICY_21__SHIFT 0x15\n#define TC_CFG_L1_STORE_POLICY__POLICY_22_MASK 0x400000\n#define TC_CFG_L1_STORE_POLICY__POLICY_22__SHIFT 0x16\n#define TC_CFG_L1_STORE_POLICY__POLICY_23_MASK 0x800000\n#define TC_CFG_L1_STORE_POLICY__POLICY_23__SHIFT 0x17\n#define TC_CFG_L1_STORE_POLICY__POLICY_24_MASK 0x1000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_24__SHIFT 0x18\n#define TC_CFG_L1_STORE_POLICY__POLICY_25_MASK 0x2000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_25__SHIFT 0x19\n#define TC_CFG_L1_STORE_POLICY__POLICY_26_MASK 0x4000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_26__SHIFT 0x1a\n#define TC_CFG_L1_STORE_POLICY__POLICY_27_MASK 0x8000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_27__SHIFT 0x1b\n#define TC_CFG_L1_STORE_POLICY__POLICY_28_MASK 0x10000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_28__SHIFT 0x1c\n#define TC_CFG_L1_STORE_POLICY__POLICY_29_MASK 0x20000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_29__SHIFT 0x1d\n#define TC_CFG_L1_STORE_POLICY__POLICY_30_MASK 0x40000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_30__SHIFT 0x1e\n#define TC_CFG_L1_STORE_POLICY__POLICY_31_MASK 0x80000000\n#define TC_CFG_L1_STORE_POLICY__POLICY_31__SHIFT 0x1f\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_0_MASK 0x3\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_0__SHIFT 0x0\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_1_MASK 0xc\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_1__SHIFT 0x2\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_2_MASK 0x30\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_2__SHIFT 0x4\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_3_MASK 0xc0\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_3__SHIFT 0x6\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_4_MASK 0x300\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_4__SHIFT 0x8\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_5_MASK 0xc00\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_5__SHIFT 0xa\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_6_MASK 0x3000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_6__SHIFT 0xc\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_7_MASK 0xc000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_7__SHIFT 0xe\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_8_MASK 0x30000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_8__SHIFT 0x10\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_9_MASK 0xc0000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_9__SHIFT 0x12\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_10_MASK 0x300000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_10__SHIFT 0x14\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_11_MASK 0xc00000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_11__SHIFT 0x16\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_12_MASK 0x3000000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_12__SHIFT 0x18\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_13_MASK 0xc000000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_13__SHIFT 0x1a\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_14_MASK 0x30000000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_14__SHIFT 0x1c\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_15_MASK 0xc0000000\n#define TC_CFG_L2_LOAD_POLICY0__POLICY_15__SHIFT 0x1e\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_16_MASK 0x3\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_16__SHIFT 0x0\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_17_MASK 0xc\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_17__SHIFT 0x2\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_18_MASK 0x30\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_18__SHIFT 0x4\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_19_MASK 0xc0\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_19__SHIFT 0x6\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_20_MASK 0x300\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_20__SHIFT 0x8\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_21_MASK 0xc00\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_21__SHIFT 0xa\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_22_MASK 0x3000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_22__SHIFT 0xc\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_23_MASK 0xc000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_23__SHIFT 0xe\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_24_MASK 0x30000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_24__SHIFT 0x10\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_25_MASK 0xc0000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_25__SHIFT 0x12\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_26_MASK 0x300000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_26__SHIFT 0x14\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_27_MASK 0xc00000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_27__SHIFT 0x16\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_28_MASK 0x3000000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_28__SHIFT 0x18\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_29_MASK 0xc000000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_29__SHIFT 0x1a\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_30_MASK 0x30000000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_30__SHIFT 0x1c\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_31_MASK 0xc0000000\n#define TC_CFG_L2_LOAD_POLICY1__POLICY_31__SHIFT 0x1e\n#define TC_CFG_L2_STORE_POLICY0__POLICY_0_MASK 0x3\n#define TC_CFG_L2_STORE_POLICY0__POLICY_0__SHIFT 0x0\n#define TC_CFG_L2_STORE_POLICY0__POLICY_1_MASK 0xc\n#define TC_CFG_L2_STORE_POLICY0__POLICY_1__SHIFT 0x2\n#define TC_CFG_L2_STORE_POLICY0__POLICY_2_MASK 0x30\n#define TC_CFG_L2_STORE_POLICY0__POLICY_2__SHIFT 0x4\n#define TC_CFG_L2_STORE_POLICY0__POLICY_3_MASK 0xc0\n#define TC_CFG_L2_STORE_POLICY0__POLICY_3__SHIFT 0x6\n#define TC_CFG_L2_STORE_POLICY0__POLICY_4_MASK 0x300\n#define TC_CFG_L2_STORE_POLICY0__POLICY_4__SHIFT 0x8\n#define TC_CFG_L2_STORE_POLICY0__POLICY_5_MASK 0xc00\n#define TC_CFG_L2_STORE_POLICY0__POLICY_5__SHIFT 0xa\n#define TC_CFG_L2_STORE_POLICY0__POLICY_6_MASK 0x3000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_6__SHIFT 0xc\n#define TC_CFG_L2_STORE_POLICY0__POLICY_7_MASK 0xc000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_7__SHIFT 0xe\n#define TC_CFG_L2_STORE_POLICY0__POLICY_8_MASK 0x30000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_8__SHIFT 0x10\n#define TC_CFG_L2_STORE_POLICY0__POLICY_9_MASK 0xc0000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_9__SHIFT 0x12\n#define TC_CFG_L2_STORE_POLICY0__POLICY_10_MASK 0x300000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_10__SHIFT 0x14\n#define TC_CFG_L2_STORE_POLICY0__POLICY_11_MASK 0xc00000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_11__SHIFT 0x16\n#define TC_CFG_L2_STORE_POLICY0__POLICY_12_MASK 0x3000000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_12__SHIFT 0x18\n#define TC_CFG_L2_STORE_POLICY0__POLICY_13_MASK 0xc000000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_13__SHIFT 0x1a\n#define TC_CFG_L2_STORE_POLICY0__POLICY_14_MASK 0x30000000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_14__SHIFT 0x1c\n#define TC_CFG_L2_STORE_POLICY0__POLICY_15_MASK 0xc0000000\n#define TC_CFG_L2_STORE_POLICY0__POLICY_15__SHIFT 0x1e\n#define TC_CFG_L2_STORE_POLICY1__POLICY_16_MASK 0x3\n#define TC_CFG_L2_STORE_POLICY1__POLICY_16__SHIFT 0x0\n#define TC_CFG_L2_STORE_POLICY1__POLICY_17_MASK 0xc\n#define TC_CFG_L2_STORE_POLICY1__POLICY_17__SHIFT 0x2\n#define TC_CFG_L2_STORE_POLICY1__POLICY_18_MASK 0x30\n#define TC_CFG_L2_STORE_POLICY1__POLICY_18__SHIFT 0x4\n#define TC_CFG_L2_STORE_POLICY1__POLICY_19_MASK 0xc0\n#define TC_CFG_L2_STORE_POLICY1__POLICY_19__SHIFT 0x6\n#define TC_CFG_L2_STORE_POLICY1__POLICY_20_MASK 0x300\n#define TC_CFG_L2_STORE_POLICY1__POLICY_20__SHIFT 0x8\n#define TC_CFG_L2_STORE_POLICY1__POLICY_21_MASK 0xc00\n#define TC_CFG_L2_STORE_POLICY1__POLICY_21__SHIFT 0xa\n#define TC_CFG_L2_STORE_POLICY1__POLICY_22_MASK 0x3000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_22__SHIFT 0xc\n#define TC_CFG_L2_STORE_POLICY1__POLICY_23_MASK 0xc000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_23__SHIFT 0xe\n#define TC_CFG_L2_STORE_POLICY1__POLICY_24_MASK 0x30000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_24__SHIFT 0x10\n#define TC_CFG_L2_STORE_POLICY1__POLICY_25_MASK 0xc0000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_25__SHIFT 0x12\n#define TC_CFG_L2_STORE_POLICY1__POLICY_26_MASK 0x300000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_26__SHIFT 0x14\n#define TC_CFG_L2_STORE_POLICY1__POLICY_27_MASK 0xc00000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_27__SHIFT 0x16\n#define TC_CFG_L2_STORE_POLICY1__POLICY_28_MASK 0x3000000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_28__SHIFT 0x18\n#define TC_CFG_L2_STORE_POLICY1__POLICY_29_MASK 0xc000000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_29__SHIFT 0x1a\n#define TC_CFG_L2_STORE_POLICY1__POLICY_30_MASK 0x30000000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_30__SHIFT 0x1c\n#define TC_CFG_L2_STORE_POLICY1__POLICY_31_MASK 0xc0000000\n#define TC_CFG_L2_STORE_POLICY1__POLICY_31__SHIFT 0x1e\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_0_MASK 0x3\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_0__SHIFT 0x0\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_1_MASK 0xc\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_1__SHIFT 0x2\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_2_MASK 0x30\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_2__SHIFT 0x4\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_3_MASK 0xc0\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_3__SHIFT 0x6\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_4_MASK 0x300\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_4__SHIFT 0x8\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_5_MASK 0xc00\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_5__SHIFT 0xa\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_6_MASK 0x3000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_6__SHIFT 0xc\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_7_MASK 0xc000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_7__SHIFT 0xe\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_8_MASK 0x30000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_8__SHIFT 0x10\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_9_MASK 0xc0000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_9__SHIFT 0x12\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_10_MASK 0x300000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_10__SHIFT 0x14\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_11_MASK 0xc00000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_11__SHIFT 0x16\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_12_MASK 0x3000000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_12__SHIFT 0x18\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_13_MASK 0xc000000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_13__SHIFT 0x1a\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_14_MASK 0x30000000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_14__SHIFT 0x1c\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_15_MASK 0xc0000000\n#define TC_CFG_L2_ATOMIC_POLICY__POLICY_15__SHIFT 0x1e\n#define TC_CFG_L1_VOLATILE__VOL_MASK 0xf\n#define TC_CFG_L1_VOLATILE__VOL__SHIFT 0x0\n#define TC_CFG_L2_VOLATILE__VOL_MASK 0xf\n#define TC_CFG_L2_VOLATILE__VOL__SHIFT 0x0\n#define TCP_WATCH0_ADDR_H__ADDR_MASK 0xffff\n#define TCP_WATCH0_ADDR_H__ADDR__SHIFT 0x0\n#define TCP_WATCH1_ADDR_H__ADDR_MASK 0xffff\n#define TCP_WATCH1_ADDR_H__ADDR__SHIFT 0x0\n#define TCP_WATCH2_ADDR_H__ADDR_MASK 0xffff\n#define TCP_WATCH2_ADDR_H__ADDR__SHIFT 0x0\n#define TCP_WATCH3_ADDR_H__ADDR_MASK 0xffff\n#define TCP_WATCH3_ADDR_H__ADDR__SHIFT 0x0\n#define TCP_WATCH0_ADDR_L__ADDR_MASK 0xffffffc0\n#define TCP_WATCH0_ADDR_L__ADDR__SHIFT 0x6\n#define TCP_WATCH1_ADDR_L__ADDR_MASK 0xffffffc0\n#define TCP_WATCH1_ADDR_L__ADDR__SHIFT 0x6\n#define TCP_WATCH2_ADDR_L__ADDR_MASK 0xffffffc0\n#define TCP_WATCH2_ADDR_L__ADDR__SHIFT 0x6\n#define TCP_WATCH3_ADDR_L__ADDR_MASK 0xffffffc0\n#define TCP_WATCH3_ADDR_L__ADDR__SHIFT 0x6\n#define TCP_WATCH0_CNTL__MASK_MASK 0xffffff\n#define TCP_WATCH0_CNTL__MASK__SHIFT 0x0\n#define TCP_WATCH0_CNTL__VMID_MASK 0xf000000\n#define TCP_WATCH0_CNTL__VMID__SHIFT 0x18\n#define TCP_WATCH0_CNTL__MODE_MASK 0x60000000\n#define TCP_WATCH0_CNTL__MODE__SHIFT 0x1d\n#define TCP_WATCH0_CNTL__VALID_MASK 0x80000000\n#define TCP_WATCH0_CNTL__VALID__SHIFT 0x1f\n#define TCP_WATCH1_CNTL__MASK_MASK 0xffffff\n#define TCP_WATCH1_CNTL__MASK__SHIFT 0x0\n#define TCP_WATCH1_CNTL__VMID_MASK 0xf000000\n#define TCP_WATCH1_CNTL__VMID__SHIFT 0x18\n#define TCP_WATCH1_CNTL__MODE_MASK 0x60000000\n#define TCP_WATCH1_CNTL__MODE__SHIFT 0x1d\n#define TCP_WATCH1_CNTL__VALID_MASK 0x80000000\n#define TCP_WATCH1_CNTL__VALID__SHIFT 0x1f\n#define TCP_WATCH2_CNTL__MASK_MASK 0xffffff\n#define TCP_WATCH2_CNTL__MASK__SHIFT 0x0\n#define TCP_WATCH2_CNTL__VMID_MASK 0xf000000\n#define TCP_WATCH2_CNTL__VMID__SHIFT 0x18\n#define TCP_WATCH2_CNTL__MODE_MASK 0x60000000\n#define TCP_WATCH2_CNTL__MODE__SHIFT 0x1d\n#define TCP_WATCH2_CNTL__VALID_MASK 0x80000000\n#define TCP_WATCH2_CNTL__VALID__SHIFT 0x1f\n#define TCP_WATCH3_CNTL__MASK_MASK 0xffffff\n#define TCP_WATCH3_CNTL__MASK__SHIFT 0x0\n#define TCP_WATCH3_CNTL__VMID_MASK 0xf000000\n#define TCP_WATCH3_CNTL__VMID__SHIFT 0x18\n#define TCP_WATCH3_CNTL__MODE_MASK 0x60000000\n#define TCP_WATCH3_CNTL__MODE__SHIFT 0x1d\n#define TCP_WATCH3_CNTL__VALID_MASK 0x80000000\n#define TCP_WATCH3_CNTL__VALID__SHIFT 0x1f\n#define TD_CGTT_CTRL__ON_DELAY_MASK 0xf\n#define TD_CGTT_CTRL__ON_DELAY__SHIFT 0x0\n#define TD_CGTT_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define TD_CGTT_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define TD_CGTT_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define TD_CGTT_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define TD_CGTT_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define TD_CGTT_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define TD_CGTT_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define TD_CGTT_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define TD_CGTT_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define TD_CGTT_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define TD_CGTT_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define TA_CGTT_CTRL__ON_DELAY_MASK 0xf\n#define TA_CGTT_CTRL__ON_DELAY__SHIFT 0x0\n#define TA_CGTT_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define TA_CGTT_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define TA_CGTT_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define TA_CGTT_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define TA_CGTT_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define TA_CGTT_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define TA_CGTT_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define TA_CGTT_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define TA_CGTT_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define TA_CGTT_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define TA_CGTT_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_TCP_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_TCP_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_TCP_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_TCP_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_TCP_CLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define CGTT_TCI_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_TCI_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_TCI_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_TCI_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_TCI_CLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define TCI_STATUS__TCI_BUSY_MASK 0x1\n#define TCI_STATUS__TCI_BUSY__SHIFT 0x0\n#define TCI_CNTL_1__WBINVL1_NUM_CYCLES_MASK 0xffff\n#define TCI_CNTL_1__WBINVL1_NUM_CYCLES__SHIFT 0x0\n#define TCI_CNTL_1__REQ_FIFO_DEPTH_MASK 0xff0000\n#define TCI_CNTL_1__REQ_FIFO_DEPTH__SHIFT 0x10\n#define TCI_CNTL_1__WDATA_RAM_DEPTH_MASK 0xff000000\n#define TCI_CNTL_1__WDATA_RAM_DEPTH__SHIFT 0x18\n#define TCI_CNTL_2__L1_INVAL_ON_WBINVL2_MASK 0x1\n#define TCI_CNTL_2__L1_INVAL_ON_WBINVL2__SHIFT 0x0\n#define TCI_CNTL_2__TCA_MAX_CREDIT_MASK 0x1fe\n#define TCI_CNTL_2__TCA_MAX_CREDIT__SHIFT 0x1\n#define GDS_CONFIG__SH0_GPR_PHASE_SEL_MASK 0x6\n#define GDS_CONFIG__SH0_GPR_PHASE_SEL__SHIFT 0x1\n#define GDS_CONFIG__SH1_GPR_PHASE_SEL_MASK 0x18\n#define GDS_CONFIG__SH1_GPR_PHASE_SEL__SHIFT 0x3\n#define GDS_CONFIG__SH2_GPR_PHASE_SEL_MASK 0x60\n#define GDS_CONFIG__SH2_GPR_PHASE_SEL__SHIFT 0x5\n#define GDS_CONFIG__SH3_GPR_PHASE_SEL_MASK 0x180\n#define GDS_CONFIG__SH3_GPR_PHASE_SEL__SHIFT 0x7\n#define GDS_CNTL_STATUS__GDS_BUSY_MASK 0x1\n#define GDS_CNTL_STATUS__GDS_BUSY__SHIFT 0x0\n#define GDS_CNTL_STATUS__GRBM_WBUF_BUSY_MASK 0x2\n#define GDS_CNTL_STATUS__GRBM_WBUF_BUSY__SHIFT 0x1\n#define GDS_CNTL_STATUS__ORD_APP_BUSY_MASK 0x4\n#define GDS_CNTL_STATUS__ORD_APP_BUSY__SHIFT 0x2\n#define GDS_CNTL_STATUS__DS_BANK_CONFLICT_MASK 0x8\n#define GDS_CNTL_STATUS__DS_BANK_CONFLICT__SHIFT 0x3\n#define GDS_CNTL_STATUS__DS_ADDR_CONFLICT_MASK 0x10\n#define GDS_CNTL_STATUS__DS_ADDR_CONFLICT__SHIFT 0x4\n#define GDS_CNTL_STATUS__DS_WR_CLAMP_MASK 0x20\n#define GDS_CNTL_STATUS__DS_WR_CLAMP__SHIFT 0x5\n#define GDS_CNTL_STATUS__DS_RD_CLAMP_MASK 0x40\n#define GDS_CNTL_STATUS__DS_RD_CLAMP__SHIFT 0x6\n#define GDS_ENHANCE2__MISC_MASK 0xffff\n#define GDS_ENHANCE2__MISC__SHIFT 0x0\n#define GDS_ENHANCE2__UNUSED_MASK 0xffff0000\n#define GDS_ENHANCE2__UNUSED__SHIFT 0x10\n#define GDS_PROTECTION_FAULT__WRITE_DIS_MASK 0x1\n#define GDS_PROTECTION_FAULT__WRITE_DIS__SHIFT 0x0\n#define GDS_PROTECTION_FAULT__FAULT_DETECTED_MASK 0x2\n#define GDS_PROTECTION_FAULT__FAULT_DETECTED__SHIFT 0x1\n#define GDS_PROTECTION_FAULT__GRBM_MASK 0x4\n#define GDS_PROTECTION_FAULT__GRBM__SHIFT 0x2\n#define GDS_PROTECTION_FAULT__SH_ID_MASK 0x38\n#define GDS_PROTECTION_FAULT__SH_ID__SHIFT 0x3\n#define GDS_PROTECTION_FAULT__CU_ID_MASK 0x3c0\n#define GDS_PROTECTION_FAULT__CU_ID__SHIFT 0x6\n#define GDS_PROTECTION_FAULT__SIMD_ID_MASK 0xc00\n#define GDS_PROTECTION_FAULT__SIMD_ID__SHIFT 0xa\n#define GDS_PROTECTION_FAULT__WAVE_ID_MASK 0xf000\n#define GDS_PROTECTION_FAULT__WAVE_ID__SHIFT 0xc\n#define GDS_PROTECTION_FAULT__ADDRESS_MASK 0xffff0000\n#define GDS_PROTECTION_FAULT__ADDRESS__SHIFT 0x10\n#define GDS_VM_PROTECTION_FAULT__WRITE_DIS_MASK 0x1\n#define GDS_VM_PROTECTION_FAULT__WRITE_DIS__SHIFT 0x0\n#define GDS_VM_PROTECTION_FAULT__FAULT_DETECTED_MASK 0x2\n#define GDS_VM_PROTECTION_FAULT__FAULT_DETECTED__SHIFT 0x1\n#define GDS_VM_PROTECTION_FAULT__GWS_MASK 0x4\n#define GDS_VM_PROTECTION_FAULT__GWS__SHIFT 0x2\n#define GDS_VM_PROTECTION_FAULT__OA_MASK 0x8\n#define GDS_VM_PROTECTION_FAULT__OA__SHIFT 0x3\n#define GDS_VM_PROTECTION_FAULT__GRBM_MASK 0x10\n#define GDS_VM_PROTECTION_FAULT__GRBM__SHIFT 0x4\n#define GDS_VM_PROTECTION_FAULT__VMID_MASK 0xf00\n#define GDS_VM_PROTECTION_FAULT__VMID__SHIFT 0x8\n#define GDS_VM_PROTECTION_FAULT__ADDRESS_MASK 0xffff0000\n#define GDS_VM_PROTECTION_FAULT__ADDRESS__SHIFT 0x10\n#define GDS_SECDED_CNT__DED_MASK 0xffff\n#define GDS_SECDED_CNT__DED__SHIFT 0x0\n#define GDS_SECDED_CNT__SEC_MASK 0xffff0000\n#define GDS_SECDED_CNT__SEC__SHIFT 0x10\n#define GDS_GRBM_SECDED_CNT__DED_MASK 0xffff\n#define GDS_GRBM_SECDED_CNT__DED__SHIFT 0x0\n#define GDS_GRBM_SECDED_CNT__SEC_MASK 0xffff0000\n#define GDS_GRBM_SECDED_CNT__SEC__SHIFT 0x10\n#define GDS_OA_DED__ME0_GFXHP3D_PIX_DED_MASK 0x1\n#define GDS_OA_DED__ME0_GFXHP3D_PIX_DED__SHIFT 0x0\n#define GDS_OA_DED__ME0_GFXHP3D_VTX_DED_MASK 0x2\n#define GDS_OA_DED__ME0_GFXHP3D_VTX_DED__SHIFT 0x1\n#define GDS_OA_DED__ME0_CS_DED_MASK 0x4\n#define GDS_OA_DED__ME0_CS_DED__SHIFT 0x2\n#define GDS_OA_DED__UNUSED0_MASK 0x8\n#define GDS_OA_DED__UNUSED0__SHIFT 0x3\n#define GDS_OA_DED__ME1_PIPE0_DED_MASK 0x10\n#define GDS_OA_DED__ME1_PIPE0_DED__SHIFT 0x4\n#define GDS_OA_DED__ME1_PIPE1_DED_MASK 0x20\n#define GDS_OA_DED__ME1_PIPE1_DED__SHIFT 0x5\n#define GDS_OA_DED__ME1_PIPE2_DED_MASK 0x40\n#define GDS_OA_DED__ME1_PIPE2_DED__SHIFT 0x6\n#define GDS_OA_DED__ME1_PIPE3_DED_MASK 0x80\n#define GDS_OA_DED__ME1_PIPE3_DED__SHIFT 0x7\n#define GDS_OA_DED__ME2_PIPE0_DED_MASK 0x100\n#define GDS_OA_DED__ME2_PIPE0_DED__SHIFT 0x8\n#define GDS_OA_DED__ME2_PIPE1_DED_MASK 0x200\n#define GDS_OA_DED__ME2_PIPE1_DED__SHIFT 0x9\n#define GDS_OA_DED__ME2_PIPE2_DED_MASK 0x400\n#define GDS_OA_DED__ME2_PIPE2_DED__SHIFT 0xa\n#define GDS_OA_DED__ME2_PIPE3_DED_MASK 0x800\n#define GDS_OA_DED__ME2_PIPE3_DED__SHIFT 0xb\n#define GDS_OA_DED__UNUSED1_MASK 0xfffff000\n#define GDS_OA_DED__UNUSED1__SHIFT 0xc\n#define GDS_DEBUG_CNTL__GDS_DEBUG_INDX_MASK 0x1f\n#define GDS_DEBUG_CNTL__GDS_DEBUG_INDX__SHIFT 0x0\n#define GDS_DEBUG_CNTL__UNUSED_MASK 0xffffffe0\n#define GDS_DEBUG_CNTL__UNUSED__SHIFT 0x5\n#define GDS_DEBUG_DATA__DATA_MASK 0xffffffff\n#define GDS_DEBUG_DATA__DATA__SHIFT 0x0\n#define CGTT_GDS_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_GDS_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_GDS_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_GDS_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE6_MASK 0x2000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE6__SHIFT 0x19\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE5_MASK 0x4000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE5__SHIFT 0x1a\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE1_MASK 0x40000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE1__SHIFT 0x1e\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE0_MASK 0x80000000\n#define CGTT_GDS_CLK_CTRL__SOFT_OVERRIDE0__SHIFT 0x1f\n#define GDS_RD_ADDR__READ_ADDR_MASK 0xffffffff\n#define GDS_RD_ADDR__READ_ADDR__SHIFT 0x0\n#define GDS_RD_DATA__READ_DATA_MASK 0xffffffff\n#define GDS_RD_DATA__READ_DATA__SHIFT 0x0\n#define GDS_RD_BURST_ADDR__BURST_ADDR_MASK 0xffffffff\n#define GDS_RD_BURST_ADDR__BURST_ADDR__SHIFT 0x0\n#define GDS_RD_BURST_COUNT__BURST_COUNT_MASK 0xffffffff\n#define GDS_RD_BURST_COUNT__BURST_COUNT__SHIFT 0x0\n#define GDS_RD_BURST_DATA__BURST_DATA_MASK 0xffffffff\n#define GDS_RD_BURST_DATA__BURST_DATA__SHIFT 0x0\n#define GDS_WR_ADDR__WRITE_ADDR_MASK 0xffffffff\n#define GDS_WR_ADDR__WRITE_ADDR__SHIFT 0x0\n#define GDS_WR_DATA__WRITE_DATA_MASK 0xffffffff\n#define GDS_WR_DATA__WRITE_DATA__SHIFT 0x0\n#define GDS_WR_BURST_ADDR__WRITE_ADDR_MASK 0xffffffff\n#define GDS_WR_BURST_ADDR__WRITE_ADDR__SHIFT 0x0\n#define GDS_WR_BURST_DATA__WRITE_DATA_MASK 0xffffffff\n#define GDS_WR_BURST_DATA__WRITE_DATA__SHIFT 0x0\n#define GDS_WRITE_COMPLETE__WRITE_COMPLETE_MASK 0xffffffff\n#define GDS_WRITE_COMPLETE__WRITE_COMPLETE__SHIFT 0x0\n#define GDS_ATOM_CNTL__AINC_MASK 0x3f\n#define GDS_ATOM_CNTL__AINC__SHIFT 0x0\n#define GDS_ATOM_CNTL__UNUSED1_MASK 0xc0\n#define GDS_ATOM_CNTL__UNUSED1__SHIFT 0x6\n#define GDS_ATOM_CNTL__DMODE_MASK 0x100\n#define GDS_ATOM_CNTL__DMODE__SHIFT 0x8\n#define GDS_ATOM_CNTL__UNUSED2_MASK 0xfffffe00\n#define GDS_ATOM_CNTL__UNUSED2__SHIFT 0x9\n#define GDS_ATOM_COMPLETE__COMPLETE_MASK 0x1\n#define GDS_ATOM_COMPLETE__COMPLETE__SHIFT 0x0\n#define GDS_ATOM_COMPLETE__UNUSED_MASK 0xfffffffe\n#define GDS_ATOM_COMPLETE__UNUSED__SHIFT 0x1\n#define GDS_ATOM_BASE__BASE_MASK 0xffff\n#define GDS_ATOM_BASE__BASE__SHIFT 0x0\n#define GDS_ATOM_BASE__UNUSED_MASK 0xffff0000\n#define GDS_ATOM_BASE__UNUSED__SHIFT 0x10\n#define GDS_ATOM_SIZE__SIZE_MASK 0xffff\n#define GDS_ATOM_SIZE__SIZE__SHIFT 0x0\n#define GDS_ATOM_SIZE__UNUSED_MASK 0xffff0000\n#define GDS_ATOM_SIZE__UNUSED__SHIFT 0x10\n#define GDS_ATOM_OFFSET0__OFFSET0_MASK 0xff\n#define GDS_ATOM_OFFSET0__OFFSET0__SHIFT 0x0\n#define GDS_ATOM_OFFSET0__UNUSED_MASK 0xffffff00\n#define GDS_ATOM_OFFSET0__UNUSED__SHIFT 0x8\n#define GDS_ATOM_OFFSET1__OFFSET1_MASK 0xff\n#define GDS_ATOM_OFFSET1__OFFSET1__SHIFT 0x0\n#define GDS_ATOM_OFFSET1__UNUSED_MASK 0xffffff00\n#define GDS_ATOM_OFFSET1__UNUSED__SHIFT 0x8\n#define GDS_ATOM_DST__DST_MASK 0xffffffff\n#define GDS_ATOM_DST__DST__SHIFT 0x0\n#define GDS_ATOM_OP__OP_MASK 0xff\n#define GDS_ATOM_OP__OP__SHIFT 0x0\n#define GDS_ATOM_OP__UNUSED_MASK 0xffffff00\n#define GDS_ATOM_OP__UNUSED__SHIFT 0x8\n#define GDS_ATOM_SRC0__DATA_MASK 0xffffffff\n#define GDS_ATOM_SRC0__DATA__SHIFT 0x0\n#define GDS_ATOM_SRC0_U__DATA_MASK 0xffffffff\n#define GDS_ATOM_SRC0_U__DATA__SHIFT 0x0\n#define GDS_ATOM_SRC1__DATA_MASK 0xffffffff\n#define GDS_ATOM_SRC1__DATA__SHIFT 0x0\n#define GDS_ATOM_SRC1_U__DATA_MASK 0xffffffff\n#define GDS_ATOM_SRC1_U__DATA__SHIFT 0x0\n#define GDS_ATOM_READ0__DATA_MASK 0xffffffff\n#define GDS_ATOM_READ0__DATA__SHIFT 0x0\n#define GDS_ATOM_READ0_U__DATA_MASK 0xffffffff\n#define GDS_ATOM_READ0_U__DATA__SHIFT 0x0\n#define GDS_ATOM_READ1__DATA_MASK 0xffffffff\n#define GDS_ATOM_READ1__DATA__SHIFT 0x0\n#define GDS_ATOM_READ1_U__DATA_MASK 0xffffffff\n#define GDS_ATOM_READ1_U__DATA__SHIFT 0x0\n#define GDS_GWS_RESOURCE_CNTL__INDEX_MASK 0x3f\n#define GDS_GWS_RESOURCE_CNTL__INDEX__SHIFT 0x0\n#define GDS_GWS_RESOURCE_CNTL__UNUSED_MASK 0xffffffc0\n#define GDS_GWS_RESOURCE_CNTL__UNUSED__SHIFT 0x6\n#define GDS_GWS_RESOURCE__FLAG_MASK 0x1\n#define GDS_GWS_RESOURCE__FLAG__SHIFT 0x0\n#define GDS_GWS_RESOURCE__COUNTER_MASK 0x1ffe\n#define GDS_GWS_RESOURCE__COUNTER__SHIFT 0x1\n#define GDS_GWS_RESOURCE__TYPE_MASK 0x2000\n#define GDS_GWS_RESOURCE__TYPE__SHIFT 0xd\n#define GDS_GWS_RESOURCE__DED_MASK 0x4000\n#define GDS_GWS_RESOURCE__DED__SHIFT 0xe\n#define GDS_GWS_RESOURCE__RELEASE_ALL_MASK 0x8000\n#define GDS_GWS_RESOURCE__RELEASE_ALL__SHIFT 0xf\n#define GDS_GWS_RESOURCE__HEAD_QUEUE_MASK 0x7ff0000\n#define GDS_GWS_RESOURCE__HEAD_QUEUE__SHIFT 0x10\n#define GDS_GWS_RESOURCE__HEAD_VALID_MASK 0x8000000\n#define GDS_GWS_RESOURCE__HEAD_VALID__SHIFT 0x1b\n#define GDS_GWS_RESOURCE__HEAD_FLAG_MASK 0x10000000\n#define GDS_GWS_RESOURCE__HEAD_FLAG__SHIFT 0x1c\n#define GDS_GWS_RESOURCE__UNUSED1_MASK 0xe0000000\n#define GDS_GWS_RESOURCE__UNUSED1__SHIFT 0x1d\n#define GDS_GWS_RESOURCE_CNT__RESOURCE_CNT_MASK 0xffff\n#define GDS_GWS_RESOURCE_CNT__RESOURCE_CNT__SHIFT 0x0\n#define GDS_GWS_RESOURCE_CNT__UNUSED_MASK 0xffff0000\n#define GDS_GWS_RESOURCE_CNT__UNUSED__SHIFT 0x10\n#define GDS_OA_CNTL__INDEX_MASK 0xf\n#define GDS_OA_CNTL__INDEX__SHIFT 0x0\n#define GDS_OA_CNTL__UNUSED_MASK 0xfffffff0\n#define GDS_OA_CNTL__UNUSED__SHIFT 0x4\n#define GDS_OA_COUNTER__SPACE_AVAILABLE_MASK 0xffffffff\n#define GDS_OA_COUNTER__SPACE_AVAILABLE__SHIFT 0x0\n#define GDS_OA_ADDRESS__DS_ADDRESS_MASK 0xffff\n#define GDS_OA_ADDRESS__DS_ADDRESS__SHIFT 0x0\n#define GDS_OA_ADDRESS__CRAWLER_TYPE_MASK 0xf0000\n#define GDS_OA_ADDRESS__CRAWLER_TYPE__SHIFT 0x10\n#define GDS_OA_ADDRESS__CRAWLER_MASK 0xf00000\n#define GDS_OA_ADDRESS__CRAWLER__SHIFT 0x14\n#define GDS_OA_ADDRESS__UNUSED_MASK 0x3f000000\n#define GDS_OA_ADDRESS__UNUSED__SHIFT 0x18\n#define GDS_OA_ADDRESS__NO_ALLOC_MASK 0x40000000\n#define GDS_OA_ADDRESS__NO_ALLOC__SHIFT 0x1e\n#define GDS_OA_ADDRESS__ENABLE_MASK 0x80000000\n#define GDS_OA_ADDRESS__ENABLE__SHIFT 0x1f\n#define GDS_OA_INCDEC__VALUE_MASK 0x7fffffff\n#define GDS_OA_INCDEC__VALUE__SHIFT 0x0\n#define GDS_OA_INCDEC__INCDEC_MASK 0x80000000\n#define GDS_OA_INCDEC__INCDEC__SHIFT 0x1f\n#define GDS_OA_RING_SIZE__RING_SIZE_MASK 0xffffffff\n#define GDS_OA_RING_SIZE__RING_SIZE__SHIFT 0x0\n#define GDS_DEBUG_REG0__spare1_MASK 0x3f\n#define GDS_DEBUG_REG0__spare1__SHIFT 0x0\n#define GDS_DEBUG_REG0__write_buff_valid_MASK 0x40\n#define GDS_DEBUG_REG0__write_buff_valid__SHIFT 0x6\n#define GDS_DEBUG_REG0__wr_pixel_nxt_ptr_MASK 0xf80\n#define GDS_DEBUG_REG0__wr_pixel_nxt_ptr__SHIFT 0x7\n#define GDS_DEBUG_REG0__last_pixel_ptr_MASK 0x1000\n#define GDS_DEBUG_REG0__last_pixel_ptr__SHIFT 0xc\n#define GDS_DEBUG_REG0__cstate_MASK 0x1e000\n#define GDS_DEBUG_REG0__cstate__SHIFT 0xd\n#define GDS_DEBUG_REG0__buff_write_MASK 0x20000\n#define GDS_DEBUG_REG0__buff_write__SHIFT 0x11\n#define GDS_DEBUG_REG0__flush_request_MASK 0x40000\n#define GDS_DEBUG_REG0__flush_request__SHIFT 0x12\n#define GDS_DEBUG_REG0__wr_buffer_wr_complete_MASK 0x80000\n#define GDS_DEBUG_REG0__wr_buffer_wr_complete__SHIFT 0x13\n#define GDS_DEBUG_REG0__wbuf_fifo_empty_MASK 0x100000\n#define GDS_DEBUG_REG0__wbuf_fifo_empty__SHIFT 0x14\n#define GDS_DEBUG_REG0__wbuf_fifo_full_MASK 0x200000\n#define GDS_DEBUG_REG0__wbuf_fifo_full__SHIFT 0x15\n#define GDS_DEBUG_REG0__spare_MASK 0xffc00000\n#define GDS_DEBUG_REG0__spare__SHIFT 0x16\n#define GDS_DEBUG_REG1__tag_hit_MASK 0x1\n#define GDS_DEBUG_REG1__tag_hit__SHIFT 0x0\n#define GDS_DEBUG_REG1__tag_miss_MASK 0x2\n#define GDS_DEBUG_REG1__tag_miss__SHIFT 0x1\n#define GDS_DEBUG_REG1__pixel_addr_MASK 0x1fffc\n#define GDS_DEBUG_REG1__pixel_addr__SHIFT 0x2\n#define GDS_DEBUG_REG1__pixel_vld_MASK 0x20000\n#define GDS_DEBUG_REG1__pixel_vld__SHIFT 0x11\n#define GDS_DEBUG_REG1__data_ready_MASK 0x40000\n#define GDS_DEBUG_REG1__data_ready__SHIFT 0x12\n#define GDS_DEBUG_REG1__awaiting_data_MASK 0x80000\n#define GDS_DEBUG_REG1__awaiting_data__SHIFT 0x13\n#define GDS_DEBUG_REG1__addr_fifo_full_MASK 0x100000\n#define GDS_DEBUG_REG1__addr_fifo_full__SHIFT 0x14\n#define GDS_DEBUG_REG1__addr_fifo_empty_MASK 0x200000\n#define GDS_DEBUG_REG1__addr_fifo_empty__SHIFT 0x15\n#define GDS_DEBUG_REG1__buffer_loaded_MASK 0x400000\n#define GDS_DEBUG_REG1__buffer_loaded__SHIFT 0x16\n#define GDS_DEBUG_REG1__buffer_invalid_MASK 0x800000\n#define GDS_DEBUG_REG1__buffer_invalid__SHIFT 0x17\n#define GDS_DEBUG_REG1__spare_MASK 0xff000000\n#define GDS_DEBUG_REG1__spare__SHIFT 0x18\n#define GDS_DEBUG_REG2__ds_full_MASK 0x1\n#define GDS_DEBUG_REG2__ds_full__SHIFT 0x0\n#define GDS_DEBUG_REG2__ds_credit_avail_MASK 0x2\n#define GDS_DEBUG_REG2__ds_credit_avail__SHIFT 0x1\n#define GDS_DEBUG_REG2__ord_idx_free_MASK 0x4\n#define GDS_DEBUG_REG2__ord_idx_free__SHIFT 0x2\n#define GDS_DEBUG_REG2__cmd_write_MASK 0x8\n#define GDS_DEBUG_REG2__cmd_write__SHIFT 0x3\n#define GDS_DEBUG_REG2__app_sel_MASK 0xf0\n#define GDS_DEBUG_REG2__app_sel__SHIFT 0x4\n#define GDS_DEBUG_REG2__req_MASK 0x7fff00\n#define GDS_DEBUG_REG2__req__SHIFT 0x8\n#define GDS_DEBUG_REG2__spare_MASK 0xff800000\n#define GDS_DEBUG_REG2__spare__SHIFT 0x17\n#define GDS_DEBUG_REG3__pipe_num_busy_MASK 0x7ff\n#define GDS_DEBUG_REG3__pipe_num_busy__SHIFT 0x0\n#define GDS_DEBUG_REG3__pipe0_busy_num_MASK 0x7800\n#define GDS_DEBUG_REG3__pipe0_busy_num__SHIFT 0xb\n#define GDS_DEBUG_REG3__spare_MASK 0xffff8000\n#define GDS_DEBUG_REG3__spare__SHIFT 0xf\n#define GDS_DEBUG_REG4__gws_busy_MASK 0x1\n#define GDS_DEBUG_REG4__gws_busy__SHIFT 0x0\n#define GDS_DEBUG_REG4__gws_req_MASK 0x2\n#define GDS_DEBUG_REG4__gws_req__SHIFT 0x1\n#define GDS_DEBUG_REG4__gws_out_stall_MASK 0x4\n#define GDS_DEBUG_REG4__gws_out_stall__SHIFT 0x2\n#define GDS_DEBUG_REG4__cur_reso_MASK 0x1f8\n#define GDS_DEBUG_REG4__cur_reso__SHIFT 0x3\n#define GDS_DEBUG_REG4__cur_reso_head_valid_MASK 0x200\n#define GDS_DEBUG_REG4__cur_reso_head_valid__SHIFT 0x9\n#define GDS_DEBUG_REG4__cur_reso_head_dirty_MASK 0x400\n#define GDS_DEBUG_REG4__cur_reso_head_dirty__SHIFT 0xa\n#define GDS_DEBUG_REG4__cur_reso_head_flag_MASK 0x800\n#define GDS_DEBUG_REG4__cur_reso_head_flag__SHIFT 0xb\n#define GDS_DEBUG_REG4__cur_reso_fed_MASK 0x1000\n#define GDS_DEBUG_REG4__cur_reso_fed__SHIFT 0xc\n#define GDS_DEBUG_REG4__cur_reso_barrier_MASK 0x2000\n#define GDS_DEBUG_REG4__cur_reso_barrier__SHIFT 0xd\n#define GDS_DEBUG_REG4__cur_reso_flag_MASK 0x4000\n#define GDS_DEBUG_REG4__cur_reso_flag__SHIFT 0xe\n#define GDS_DEBUG_REG4__cur_reso_cnt_gt0_MASK 0x8000\n#define GDS_DEBUG_REG4__cur_reso_cnt_gt0__SHIFT 0xf\n#define GDS_DEBUG_REG4__credit_cnt_gt0_MASK 0x10000\n#define GDS_DEBUG_REG4__credit_cnt_gt0__SHIFT 0x10\n#define GDS_DEBUG_REG4__cmd_write_MASK 0x20000\n#define GDS_DEBUG_REG4__cmd_write__SHIFT 0x11\n#define GDS_DEBUG_REG4__grbm_gws_reso_wr_MASK 0x40000\n#define GDS_DEBUG_REG4__grbm_gws_reso_wr__SHIFT 0x12\n#define GDS_DEBUG_REG4__grbm_gws_reso_rd_MASK 0x80000\n#define GDS_DEBUG_REG4__grbm_gws_reso_rd__SHIFT 0x13\n#define GDS_DEBUG_REG4__ram_read_busy_MASK 0x100000\n#define GDS_DEBUG_REG4__ram_read_busy__SHIFT 0x14\n#define GDS_DEBUG_REG4__gws_bulkfree_MASK 0x200000\n#define GDS_DEBUG_REG4__gws_bulkfree__SHIFT 0x15\n#define GDS_DEBUG_REG4__ram_gws_re_MASK 0x400000\n#define GDS_DEBUG_REG4__ram_gws_re__SHIFT 0x16\n#define GDS_DEBUG_REG4__ram_gws_we_MASK 0x800000\n#define GDS_DEBUG_REG4__ram_gws_we__SHIFT 0x17\n#define GDS_DEBUG_REG4__spare_MASK 0xff000000\n#define GDS_DEBUG_REG4__spare__SHIFT 0x18\n#define GDS_DEBUG_REG5__write_dis_MASK 0x1\n#define GDS_DEBUG_REG5__write_dis__SHIFT 0x0\n#define GDS_DEBUG_REG5__dec_error_MASK 0x2\n#define GDS_DEBUG_REG5__dec_error__SHIFT 0x1\n#define GDS_DEBUG_REG5__alloc_opco_error_MASK 0x4\n#define GDS_DEBUG_REG5__alloc_opco_error__SHIFT 0x2\n#define GDS_DEBUG_REG5__dealloc_opco_error_MASK 0x8\n#define GDS_DEBUG_REG5__dealloc_opco_error__SHIFT 0x3\n#define GDS_DEBUG_REG5__wrap_opco_error_MASK 0x10\n#define GDS_DEBUG_REG5__wrap_opco_error__SHIFT 0x4\n#define GDS_DEBUG_REG5__spare_MASK 0xe0\n#define GDS_DEBUG_REG5__spare__SHIFT 0x5\n#define GDS_DEBUG_REG5__error_ds_address_MASK 0x3fff00\n#define GDS_DEBUG_REG5__error_ds_address__SHIFT 0x8\n#define GDS_DEBUG_REG5__spare1_MASK 0xffc00000\n#define GDS_DEBUG_REG5__spare1__SHIFT 0x16\n#define GDS_DEBUG_REG6__oa_busy_MASK 0x1\n#define GDS_DEBUG_REG6__oa_busy__SHIFT 0x0\n#define GDS_DEBUG_REG6__counters_enabled_MASK 0x1e\n#define GDS_DEBUG_REG6__counters_enabled__SHIFT 0x1\n#define GDS_DEBUG_REG6__counters_busy_MASK 0x1fffe0\n#define GDS_DEBUG_REG6__counters_busy__SHIFT 0x5\n#define GDS_DEBUG_REG6__spare_MASK 0xffe00000\n#define GDS_DEBUG_REG6__spare__SHIFT 0x15\n#define GDS_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define GDS_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define GDS_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define GDS_PERFCOUNTER0_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define GDS_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define GDS_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define GDS_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define GDS_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define GDS_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define GDS_PERFCOUNTER1_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define GDS_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define GDS_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define GDS_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define GDS_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define GDS_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define GDS_PERFCOUNTER2_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define GDS_PERFCOUNTER2_SELECT__CNTR_MODE_MASK 0xf00000\n#define GDS_PERFCOUNTER2_SELECT__CNTR_MODE__SHIFT 0x14\n#define GDS_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT_MASK 0x3ff\n#define GDS_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT__SHIFT 0x0\n#define GDS_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT1_MASK 0xffc00\n#define GDS_PERFCOUNTER3_SELECT__PERFCOUNTER_SELECT1__SHIFT 0xa\n#define GDS_PERFCOUNTER3_SELECT__CNTR_MODE_MASK 0xf00000\n#define GDS_PERFCOUNTER3_SELECT__CNTR_MODE__SHIFT 0x14\n#define GDS_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GDS_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GDS_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GDS_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GDS_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GDS_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GDS_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define GDS_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define GDS_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GDS_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GDS_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GDS_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GDS_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GDS_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GDS_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define GDS_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define GDS_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT2_MASK 0x3ff\n#define GDS_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT2__SHIFT 0x0\n#define GDS_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT3_MASK 0xffc00\n#define GDS_PERFCOUNTER0_SELECT1__PERFCOUNTER_SELECT3__SHIFT 0xa\n#define GDS_VMID0_BASE__BASE_MASK 0xffff\n#define GDS_VMID0_BASE__BASE__SHIFT 0x0\n#define GDS_VMID1_BASE__BASE_MASK 0xffff\n#define GDS_VMID1_BASE__BASE__SHIFT 0x0\n#define GDS_VMID2_BASE__BASE_MASK 0xffff\n#define GDS_VMID2_BASE__BASE__SHIFT 0x0\n#define GDS_VMID3_BASE__BASE_MASK 0xffff\n#define GDS_VMID3_BASE__BASE__SHIFT 0x0\n#define GDS_VMID4_BASE__BASE_MASK 0xffff\n#define GDS_VMID4_BASE__BASE__SHIFT 0x0\n#define GDS_VMID5_BASE__BASE_MASK 0xffff\n#define GDS_VMID5_BASE__BASE__SHIFT 0x0\n#define GDS_VMID6_BASE__BASE_MASK 0xffff\n#define GDS_VMID6_BASE__BASE__SHIFT 0x0\n#define GDS_VMID7_BASE__BASE_MASK 0xffff\n#define GDS_VMID7_BASE__BASE__SHIFT 0x0\n#define GDS_VMID8_BASE__BASE_MASK 0xffff\n#define GDS_VMID8_BASE__BASE__SHIFT 0x0\n#define GDS_VMID9_BASE__BASE_MASK 0xffff\n#define GDS_VMID9_BASE__BASE__SHIFT 0x0\n#define GDS_VMID10_BASE__BASE_MASK 0xffff\n#define GDS_VMID10_BASE__BASE__SHIFT 0x0\n#define GDS_VMID11_BASE__BASE_MASK 0xffff\n#define GDS_VMID11_BASE__BASE__SHIFT 0x0\n#define GDS_VMID12_BASE__BASE_MASK 0xffff\n#define GDS_VMID12_BASE__BASE__SHIFT 0x0\n#define GDS_VMID13_BASE__BASE_MASK 0xffff\n#define GDS_VMID13_BASE__BASE__SHIFT 0x0\n#define GDS_VMID14_BASE__BASE_MASK 0xffff\n#define GDS_VMID14_BASE__BASE__SHIFT 0x0\n#define GDS_VMID15_BASE__BASE_MASK 0xffff\n#define GDS_VMID15_BASE__BASE__SHIFT 0x0\n#define GDS_VMID0_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID0_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID1_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID1_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID2_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID2_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID3_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID3_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID4_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID4_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID5_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID5_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID6_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID6_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID7_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID7_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID8_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID8_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID9_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID9_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID10_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID10_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID11_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID11_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID12_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID12_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID13_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID13_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID14_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID14_SIZE__SIZE__SHIFT 0x0\n#define GDS_VMID15_SIZE__SIZE_MASK 0x1ffff\n#define GDS_VMID15_SIZE__SIZE__SHIFT 0x0\n#define GDS_GWS_VMID0__BASE_MASK 0x3f\n#define GDS_GWS_VMID0__BASE__SHIFT 0x0\n#define GDS_GWS_VMID0__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID0__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID1__BASE_MASK 0x3f\n#define GDS_GWS_VMID1__BASE__SHIFT 0x0\n#define GDS_GWS_VMID1__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID1__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID2__BASE_MASK 0x3f\n#define GDS_GWS_VMID2__BASE__SHIFT 0x0\n#define GDS_GWS_VMID2__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID2__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID3__BASE_MASK 0x3f\n#define GDS_GWS_VMID3__BASE__SHIFT 0x0\n#define GDS_GWS_VMID3__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID3__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID4__BASE_MASK 0x3f\n#define GDS_GWS_VMID4__BASE__SHIFT 0x0\n#define GDS_GWS_VMID4__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID4__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID5__BASE_MASK 0x3f\n#define GDS_GWS_VMID5__BASE__SHIFT 0x0\n#define GDS_GWS_VMID5__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID5__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID6__BASE_MASK 0x3f\n#define GDS_GWS_VMID6__BASE__SHIFT 0x0\n#define GDS_GWS_VMID6__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID6__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID7__BASE_MASK 0x3f\n#define GDS_GWS_VMID7__BASE__SHIFT 0x0\n#define GDS_GWS_VMID7__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID7__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID8__BASE_MASK 0x3f\n#define GDS_GWS_VMID8__BASE__SHIFT 0x0\n#define GDS_GWS_VMID8__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID8__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID9__BASE_MASK 0x3f\n#define GDS_GWS_VMID9__BASE__SHIFT 0x0\n#define GDS_GWS_VMID9__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID9__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID10__BASE_MASK 0x3f\n#define GDS_GWS_VMID10__BASE__SHIFT 0x0\n#define GDS_GWS_VMID10__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID10__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID11__BASE_MASK 0x3f\n#define GDS_GWS_VMID11__BASE__SHIFT 0x0\n#define GDS_GWS_VMID11__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID11__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID12__BASE_MASK 0x3f\n#define GDS_GWS_VMID12__BASE__SHIFT 0x0\n#define GDS_GWS_VMID12__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID12__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID13__BASE_MASK 0x3f\n#define GDS_GWS_VMID13__BASE__SHIFT 0x0\n#define GDS_GWS_VMID13__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID13__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID14__BASE_MASK 0x3f\n#define GDS_GWS_VMID14__BASE__SHIFT 0x0\n#define GDS_GWS_VMID14__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID14__SIZE__SHIFT 0x10\n#define GDS_GWS_VMID15__BASE_MASK 0x3f\n#define GDS_GWS_VMID15__BASE__SHIFT 0x0\n#define GDS_GWS_VMID15__SIZE_MASK 0x7f0000\n#define GDS_GWS_VMID15__SIZE__SHIFT 0x10\n#define GDS_OA_VMID0__MASK_MASK 0xffff\n#define GDS_OA_VMID0__MASK__SHIFT 0x0\n#define GDS_OA_VMID0__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID0__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID1__MASK_MASK 0xffff\n#define GDS_OA_VMID1__MASK__SHIFT 0x0\n#define GDS_OA_VMID1__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID1__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID2__MASK_MASK 0xffff\n#define GDS_OA_VMID2__MASK__SHIFT 0x0\n#define GDS_OA_VMID2__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID2__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID3__MASK_MASK 0xffff\n#define GDS_OA_VMID3__MASK__SHIFT 0x0\n#define GDS_OA_VMID3__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID3__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID4__MASK_MASK 0xffff\n#define GDS_OA_VMID4__MASK__SHIFT 0x0\n#define GDS_OA_VMID4__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID4__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID5__MASK_MASK 0xffff\n#define GDS_OA_VMID5__MASK__SHIFT 0x0\n#define GDS_OA_VMID5__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID5__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID6__MASK_MASK 0xffff\n#define GDS_OA_VMID6__MASK__SHIFT 0x0\n#define GDS_OA_VMID6__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID6__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID7__MASK_MASK 0xffff\n#define GDS_OA_VMID7__MASK__SHIFT 0x0\n#define GDS_OA_VMID7__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID7__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID8__MASK_MASK 0xffff\n#define GDS_OA_VMID8__MASK__SHIFT 0x0\n#define GDS_OA_VMID8__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID8__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID9__MASK_MASK 0xffff\n#define GDS_OA_VMID9__MASK__SHIFT 0x0\n#define GDS_OA_VMID9__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID9__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID10__MASK_MASK 0xffff\n#define GDS_OA_VMID10__MASK__SHIFT 0x0\n#define GDS_OA_VMID10__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID10__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID11__MASK_MASK 0xffff\n#define GDS_OA_VMID11__MASK__SHIFT 0x0\n#define GDS_OA_VMID11__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID11__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID12__MASK_MASK 0xffff\n#define GDS_OA_VMID12__MASK__SHIFT 0x0\n#define GDS_OA_VMID12__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID12__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID13__MASK_MASK 0xffff\n#define GDS_OA_VMID13__MASK__SHIFT 0x0\n#define GDS_OA_VMID13__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID13__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID14__MASK_MASK 0xffff\n#define GDS_OA_VMID14__MASK__SHIFT 0x0\n#define GDS_OA_VMID14__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID14__UNUSED__SHIFT 0x10\n#define GDS_OA_VMID15__MASK_MASK 0xffff\n#define GDS_OA_VMID15__MASK__SHIFT 0x0\n#define GDS_OA_VMID15__UNUSED_MASK 0xffff0000\n#define GDS_OA_VMID15__UNUSED__SHIFT 0x10\n#define GDS_GWS_RESET0__RESOURCE0_RESET_MASK 0x1\n#define GDS_GWS_RESET0__RESOURCE0_RESET__SHIFT 0x0\n#define GDS_GWS_RESET0__RESOURCE1_RESET_MASK 0x2\n#define GDS_GWS_RESET0__RESOURCE1_RESET__SHIFT 0x1\n#define GDS_GWS_RESET0__RESOURCE2_RESET_MASK 0x4\n#define GDS_GWS_RESET0__RESOURCE2_RESET__SHIFT 0x2\n#define GDS_GWS_RESET0__RESOURCE3_RESET_MASK 0x8\n#define GDS_GWS_RESET0__RESOURCE3_RESET__SHIFT 0x3\n#define GDS_GWS_RESET0__RESOURCE4_RESET_MASK 0x10\n#define GDS_GWS_RESET0__RESOURCE4_RESET__SHIFT 0x4\n#define GDS_GWS_RESET0__RESOURCE5_RESET_MASK 0x20\n#define GDS_GWS_RESET0__RESOURCE5_RESET__SHIFT 0x5\n#define GDS_GWS_RESET0__RESOURCE6_RESET_MASK 0x40\n#define GDS_GWS_RESET0__RESOURCE6_RESET__SHIFT 0x6\n#define GDS_GWS_RESET0__RESOURCE7_RESET_MASK 0x80\n#define GDS_GWS_RESET0__RESOURCE7_RESET__SHIFT 0x7\n#define GDS_GWS_RESET0__RESOURCE8_RESET_MASK 0x100\n#define GDS_GWS_RESET0__RESOURCE8_RESET__SHIFT 0x8\n#define GDS_GWS_RESET0__RESOURCE9_RESET_MASK 0x200\n#define GDS_GWS_RESET0__RESOURCE9_RESET__SHIFT 0x9\n#define GDS_GWS_RESET0__RESOURCE10_RESET_MASK 0x400\n#define GDS_GWS_RESET0__RESOURCE10_RESET__SHIFT 0xa\n#define GDS_GWS_RESET0__RESOURCE11_RESET_MASK 0x800\n#define GDS_GWS_RESET0__RESOURCE11_RESET__SHIFT 0xb\n#define GDS_GWS_RESET0__RESOURCE12_RESET_MASK 0x1000\n#define GDS_GWS_RESET0__RESOURCE12_RESET__SHIFT 0xc\n#define GDS_GWS_RESET0__RESOURCE13_RESET_MASK 0x2000\n#define GDS_GWS_RESET0__RESOURCE13_RESET__SHIFT 0xd\n#define GDS_GWS_RESET0__RESOURCE14_RESET_MASK 0x4000\n#define GDS_GWS_RESET0__RESOURCE14_RESET__SHIFT 0xe\n#define GDS_GWS_RESET0__RESOURCE15_RESET_MASK 0x8000\n#define GDS_GWS_RESET0__RESOURCE15_RESET__SHIFT 0xf\n#define GDS_GWS_RESET0__RESOURCE16_RESET_MASK 0x10000\n#define GDS_GWS_RESET0__RESOURCE16_RESET__SHIFT 0x10\n#define GDS_GWS_RESET0__RESOURCE17_RESET_MASK 0x20000\n#define GDS_GWS_RESET0__RESOURCE17_RESET__SHIFT 0x11\n#define GDS_GWS_RESET0__RESOURCE18_RESET_MASK 0x40000\n#define GDS_GWS_RESET0__RESOURCE18_RESET__SHIFT 0x12\n#define GDS_GWS_RESET0__RESOURCE19_RESET_MASK 0x80000\n#define GDS_GWS_RESET0__RESOURCE19_RESET__SHIFT 0x13\n#define GDS_GWS_RESET0__RESOURCE20_RESET_MASK 0x100000\n#define GDS_GWS_RESET0__RESOURCE20_RESET__SHIFT 0x14\n#define GDS_GWS_RESET0__RESOURCE21_RESET_MASK 0x200000\n#define GDS_GWS_RESET0__RESOURCE21_RESET__SHIFT 0x15\n#define GDS_GWS_RESET0__RESOURCE22_RESET_MASK 0x400000\n#define GDS_GWS_RESET0__RESOURCE22_RESET__SHIFT 0x16\n#define GDS_GWS_RESET0__RESOURCE23_RESET_MASK 0x800000\n#define GDS_GWS_RESET0__RESOURCE23_RESET__SHIFT 0x17\n#define GDS_GWS_RESET0__RESOURCE24_RESET_MASK 0x1000000\n#define GDS_GWS_RESET0__RESOURCE24_RESET__SHIFT 0x18\n#define GDS_GWS_RESET0__RESOURCE25_RESET_MASK 0x2000000\n#define GDS_GWS_RESET0__RESOURCE25_RESET__SHIFT 0x19\n#define GDS_GWS_RESET0__RESOURCE26_RESET_MASK 0x4000000\n#define GDS_GWS_RESET0__RESOURCE26_RESET__SHIFT 0x1a\n#define GDS_GWS_RESET0__RESOURCE27_RESET_MASK 0x8000000\n#define GDS_GWS_RESET0__RESOURCE27_RESET__SHIFT 0x1b\n#define GDS_GWS_RESET0__RESOURCE28_RESET_MASK 0x10000000\n#define GDS_GWS_RESET0__RESOURCE28_RESET__SHIFT 0x1c\n#define GDS_GWS_RESET0__RESOURCE29_RESET_MASK 0x20000000\n#define GDS_GWS_RESET0__RESOURCE29_RESET__SHIFT 0x1d\n#define GDS_GWS_RESET0__RESOURCE30_RESET_MASK 0x40000000\n#define GDS_GWS_RESET0__RESOURCE30_RESET__SHIFT 0x1e\n#define GDS_GWS_RESET0__RESOURCE31_RESET_MASK 0x80000000\n#define GDS_GWS_RESET0__RESOURCE31_RESET__SHIFT 0x1f\n#define GDS_GWS_RESET1__RESOURCE32_RESET_MASK 0x1\n#define GDS_GWS_RESET1__RESOURCE32_RESET__SHIFT 0x0\n#define GDS_GWS_RESET1__RESOURCE33_RESET_MASK 0x2\n#define GDS_GWS_RESET1__RESOURCE33_RESET__SHIFT 0x1\n#define GDS_GWS_RESET1__RESOURCE34_RESET_MASK 0x4\n#define GDS_GWS_RESET1__RESOURCE34_RESET__SHIFT 0x2\n#define GDS_GWS_RESET1__RESOURCE35_RESET_MASK 0x8\n#define GDS_GWS_RESET1__RESOURCE35_RESET__SHIFT 0x3\n#define GDS_GWS_RESET1__RESOURCE36_RESET_MASK 0x10\n#define GDS_GWS_RESET1__RESOURCE36_RESET__SHIFT 0x4\n#define GDS_GWS_RESET1__RESOURCE37_RESET_MASK 0x20\n#define GDS_GWS_RESET1__RESOURCE37_RESET__SHIFT 0x5\n#define GDS_GWS_RESET1__RESOURCE38_RESET_MASK 0x40\n#define GDS_GWS_RESET1__RESOURCE38_RESET__SHIFT 0x6\n#define GDS_GWS_RESET1__RESOURCE39_RESET_MASK 0x80\n#define GDS_GWS_RESET1__RESOURCE39_RESET__SHIFT 0x7\n#define GDS_GWS_RESET1__RESOURCE40_RESET_MASK 0x100\n#define GDS_GWS_RESET1__RESOURCE40_RESET__SHIFT 0x8\n#define GDS_GWS_RESET1__RESOURCE41_RESET_MASK 0x200\n#define GDS_GWS_RESET1__RESOURCE41_RESET__SHIFT 0x9\n#define GDS_GWS_RESET1__RESOURCE42_RESET_MASK 0x400\n#define GDS_GWS_RESET1__RESOURCE42_RESET__SHIFT 0xa\n#define GDS_GWS_RESET1__RESOURCE43_RESET_MASK 0x800\n#define GDS_GWS_RESET1__RESOURCE43_RESET__SHIFT 0xb\n#define GDS_GWS_RESET1__RESOURCE44_RESET_MASK 0x1000\n#define GDS_GWS_RESET1__RESOURCE44_RESET__SHIFT 0xc\n#define GDS_GWS_RESET1__RESOURCE45_RESET_MASK 0x2000\n#define GDS_GWS_RESET1__RESOURCE45_RESET__SHIFT 0xd\n#define GDS_GWS_RESET1__RESOURCE46_RESET_MASK 0x4000\n#define GDS_GWS_RESET1__RESOURCE46_RESET__SHIFT 0xe\n#define GDS_GWS_RESET1__RESOURCE47_RESET_MASK 0x8000\n#define GDS_GWS_RESET1__RESOURCE47_RESET__SHIFT 0xf\n#define GDS_GWS_RESET1__RESOURCE48_RESET_MASK 0x10000\n#define GDS_GWS_RESET1__RESOURCE48_RESET__SHIFT 0x10\n#define GDS_GWS_RESET1__RESOURCE49_RESET_MASK 0x20000\n#define GDS_GWS_RESET1__RESOURCE49_RESET__SHIFT 0x11\n#define GDS_GWS_RESET1__RESOURCE50_RESET_MASK 0x40000\n#define GDS_GWS_RESET1__RESOURCE50_RESET__SHIFT 0x12\n#define GDS_GWS_RESET1__RESOURCE51_RESET_MASK 0x80000\n#define GDS_GWS_RESET1__RESOURCE51_RESET__SHIFT 0x13\n#define GDS_GWS_RESET1__RESOURCE52_RESET_MASK 0x100000\n#define GDS_GWS_RESET1__RESOURCE52_RESET__SHIFT 0x14\n#define GDS_GWS_RESET1__RESOURCE53_RESET_MASK 0x200000\n#define GDS_GWS_RESET1__RESOURCE53_RESET__SHIFT 0x15\n#define GDS_GWS_RESET1__RESOURCE54_RESET_MASK 0x400000\n#define GDS_GWS_RESET1__RESOURCE54_RESET__SHIFT 0x16\n#define GDS_GWS_RESET1__RESOURCE55_RESET_MASK 0x800000\n#define GDS_GWS_RESET1__RESOURCE55_RESET__SHIFT 0x17\n#define GDS_GWS_RESET1__RESOURCE56_RESET_MASK 0x1000000\n#define GDS_GWS_RESET1__RESOURCE56_RESET__SHIFT 0x18\n#define GDS_GWS_RESET1__RESOURCE57_RESET_MASK 0x2000000\n#define GDS_GWS_RESET1__RESOURCE57_RESET__SHIFT 0x19\n#define GDS_GWS_RESET1__RESOURCE58_RESET_MASK 0x4000000\n#define GDS_GWS_RESET1__RESOURCE58_RESET__SHIFT 0x1a\n#define GDS_GWS_RESET1__RESOURCE59_RESET_MASK 0x8000000\n#define GDS_GWS_RESET1__RESOURCE59_RESET__SHIFT 0x1b\n#define GDS_GWS_RESET1__RESOURCE60_RESET_MASK 0x10000000\n#define GDS_GWS_RESET1__RESOURCE60_RESET__SHIFT 0x1c\n#define GDS_GWS_RESET1__RESOURCE61_RESET_MASK 0x20000000\n#define GDS_GWS_RESET1__RESOURCE61_RESET__SHIFT 0x1d\n#define GDS_GWS_RESET1__RESOURCE62_RESET_MASK 0x40000000\n#define GDS_GWS_RESET1__RESOURCE62_RESET__SHIFT 0x1e\n#define GDS_GWS_RESET1__RESOURCE63_RESET_MASK 0x80000000\n#define GDS_GWS_RESET1__RESOURCE63_RESET__SHIFT 0x1f\n#define GDS_GWS_RESOURCE_RESET__RESET_MASK 0x1\n#define GDS_GWS_RESOURCE_RESET__RESET__SHIFT 0x0\n#define GDS_GWS_RESOURCE_RESET__RESOURCE_ID_MASK 0xff00\n#define GDS_GWS_RESOURCE_RESET__RESOURCE_ID__SHIFT 0x8\n#define GDS_COMPUTE_MAX_WAVE_ID__MAX_WAVE_ID_MASK 0xfff\n#define GDS_COMPUTE_MAX_WAVE_ID__MAX_WAVE_ID__SHIFT 0x0\n#define GDS_OA_RESET_MASK__ME0_GFXHP3D_PIX_RESET_MASK 0x1\n#define GDS_OA_RESET_MASK__ME0_GFXHP3D_PIX_RESET__SHIFT 0x0\n#define GDS_OA_RESET_MASK__ME0_GFXHP3D_VTX_RESET_MASK 0x2\n#define GDS_OA_RESET_MASK__ME0_GFXHP3D_VTX_RESET__SHIFT 0x1\n#define GDS_OA_RESET_MASK__ME0_CS_RESET_MASK 0x4\n#define GDS_OA_RESET_MASK__ME0_CS_RESET__SHIFT 0x2\n#define GDS_OA_RESET_MASK__UNUSED0_MASK 0x8\n#define GDS_OA_RESET_MASK__UNUSED0__SHIFT 0x3\n#define GDS_OA_RESET_MASK__ME1_PIPE0_RESET_MASK 0x10\n#define GDS_OA_RESET_MASK__ME1_PIPE0_RESET__SHIFT 0x4\n#define GDS_OA_RESET_MASK__ME1_PIPE1_RESET_MASK 0x20\n#define GDS_OA_RESET_MASK__ME1_PIPE1_RESET__SHIFT 0x5\n#define GDS_OA_RESET_MASK__ME1_PIPE2_RESET_MASK 0x40\n#define GDS_OA_RESET_MASK__ME1_PIPE2_RESET__SHIFT 0x6\n#define GDS_OA_RESET_MASK__ME1_PIPE3_RESET_MASK 0x80\n#define GDS_OA_RESET_MASK__ME1_PIPE3_RESET__SHIFT 0x7\n#define GDS_OA_RESET_MASK__ME2_PIPE0_RESET_MASK 0x100\n#define GDS_OA_RESET_MASK__ME2_PIPE0_RESET__SHIFT 0x8\n#define GDS_OA_RESET_MASK__ME2_PIPE1_RESET_MASK 0x200\n#define GDS_OA_RESET_MASK__ME2_PIPE1_RESET__SHIFT 0x9\n#define GDS_OA_RESET_MASK__ME2_PIPE2_RESET_MASK 0x400\n#define GDS_OA_RESET_MASK__ME2_PIPE2_RESET__SHIFT 0xa\n#define GDS_OA_RESET_MASK__ME2_PIPE3_RESET_MASK 0x800\n#define GDS_OA_RESET_MASK__ME2_PIPE3_RESET__SHIFT 0xb\n#define GDS_OA_RESET_MASK__UNUSED1_MASK 0xfffff000\n#define GDS_OA_RESET_MASK__UNUSED1__SHIFT 0xc\n#define GDS_OA_RESET__RESET_MASK 0x1\n#define GDS_OA_RESET__RESET__SHIFT 0x0\n#define GDS_OA_RESET__PIPE_ID_MASK 0xff00\n#define GDS_OA_RESET__PIPE_ID__SHIFT 0x8\n#define GDS_ENHANCE__MISC_MASK 0xffff\n#define GDS_ENHANCE__MISC__SHIFT 0x0\n#define GDS_ENHANCE__AUTO_INC_INDEX_MASK 0x10000\n#define GDS_ENHANCE__AUTO_INC_INDEX__SHIFT 0x10\n#define GDS_ENHANCE__CGPG_RESTORE_MASK 0x20000\n#define GDS_ENHANCE__CGPG_RESTORE__SHIFT 0x11\n#define GDS_ENHANCE__UNUSED_MASK 0xfffc0000\n#define GDS_ENHANCE__UNUSED__SHIFT 0x12\n#define GDS_OA_CGPG_RESTORE__VMID_MASK 0xff\n#define GDS_OA_CGPG_RESTORE__VMID__SHIFT 0x0\n#define GDS_OA_CGPG_RESTORE__MEID_MASK 0xf00\n#define GDS_OA_CGPG_RESTORE__MEID__SHIFT 0x8\n#define GDS_OA_CGPG_RESTORE__PIPEID_MASK 0xf000\n#define GDS_OA_CGPG_RESTORE__PIPEID__SHIFT 0xc\n#define GDS_OA_CGPG_RESTORE__UNUSED_MASK 0xffff0000\n#define GDS_OA_CGPG_RESTORE__UNUSED__SHIFT 0x10\n#define CS_COPY_STATE__SRC_STATE_ID_MASK 0x7\n#define CS_COPY_STATE__SRC_STATE_ID__SHIFT 0x0\n#define GFX_COPY_STATE__SRC_STATE_ID_MASK 0x7\n#define GFX_COPY_STATE__SRC_STATE_ID__SHIFT 0x0\n#define VGT_DRAW_INITIATOR__SOURCE_SELECT_MASK 0x3\n#define VGT_DRAW_INITIATOR__SOURCE_SELECT__SHIFT 0x0\n#define VGT_DRAW_INITIATOR__MAJOR_MODE_MASK 0xc\n#define VGT_DRAW_INITIATOR__MAJOR_MODE__SHIFT 0x2\n#define VGT_DRAW_INITIATOR__SPRITE_EN_R6XX_MASK 0x10\n#define VGT_DRAW_INITIATOR__SPRITE_EN_R6XX__SHIFT 0x4\n#define VGT_DRAW_INITIATOR__NOT_EOP_MASK 0x20\n#define VGT_DRAW_INITIATOR__NOT_EOP__SHIFT 0x5\n#define VGT_DRAW_INITIATOR__USE_OPAQUE_MASK 0x40\n#define VGT_DRAW_INITIATOR__USE_OPAQUE__SHIFT 0x6\n#define VGT_EVENT_INITIATOR__EVENT_TYPE_MASK 0x3f\n#define VGT_EVENT_INITIATOR__EVENT_TYPE__SHIFT 0x0\n#define VGT_EVENT_INITIATOR__ADDRESS_HI_MASK 0x7fc0000\n#define VGT_EVENT_INITIATOR__ADDRESS_HI__SHIFT 0x12\n#define VGT_EVENT_INITIATOR__EXTENDED_EVENT_MASK 0x8000000\n#define VGT_EVENT_INITIATOR__EXTENDED_EVENT__SHIFT 0x1b\n#define VGT_EVENT_ADDRESS_REG__ADDRESS_LOW_MASK 0xfffffff\n#define VGT_EVENT_ADDRESS_REG__ADDRESS_LOW__SHIFT 0x0\n#define VGT_DMA_BASE_HI__BASE_ADDR_MASK 0xff\n#define VGT_DMA_BASE_HI__BASE_ADDR__SHIFT 0x0\n#define VGT_DMA_BASE__BASE_ADDR_MASK 0xffffffff\n#define VGT_DMA_BASE__BASE_ADDR__SHIFT 0x0\n#define VGT_DMA_INDEX_TYPE__INDEX_TYPE_MASK 0x3\n#define VGT_DMA_INDEX_TYPE__INDEX_TYPE__SHIFT 0x0\n#define VGT_DMA_INDEX_TYPE__SWAP_MODE_MASK 0xc\n#define VGT_DMA_INDEX_TYPE__SWAP_MODE__SHIFT 0x2\n#define VGT_DMA_INDEX_TYPE__BUF_TYPE_MASK 0x30\n#define VGT_DMA_INDEX_TYPE__BUF_TYPE__SHIFT 0x4\n#define VGT_DMA_INDEX_TYPE__RDREQ_POLICY_MASK 0xc0\n#define VGT_DMA_INDEX_TYPE__RDREQ_POLICY__SHIFT 0x6\n#define VGT_DMA_INDEX_TYPE__ATC_MASK 0x100\n#define VGT_DMA_INDEX_TYPE__ATC__SHIFT 0x8\n#define VGT_DMA_INDEX_TYPE__NOT_EOP_MASK 0x200\n#define VGT_DMA_INDEX_TYPE__NOT_EOP__SHIFT 0x9\n#define VGT_DMA_INDEX_TYPE__REQ_PATH_MASK 0x400\n#define VGT_DMA_INDEX_TYPE__REQ_PATH__SHIFT 0xa\n#define VGT_DMA_NUM_INSTANCES__NUM_INSTANCES_MASK 0xffffffff\n#define VGT_DMA_NUM_INSTANCES__NUM_INSTANCES__SHIFT 0x0\n#define IA_ENHANCE__MISC_MASK 0xffffffff\n#define IA_ENHANCE__MISC__SHIFT 0x0\n#define VGT_DMA_SIZE__NUM_INDICES_MASK 0xffffffff\n#define VGT_DMA_SIZE__NUM_INDICES__SHIFT 0x0\n#define VGT_DMA_MAX_SIZE__MAX_SIZE_MASK 0xffffffff\n#define VGT_DMA_MAX_SIZE__MAX_SIZE__SHIFT 0x0\n#define VGT_DMA_PRIMITIVE_TYPE__PRIM_TYPE_MASK 0x3f\n#define VGT_DMA_PRIMITIVE_TYPE__PRIM_TYPE__SHIFT 0x0\n#define VGT_DMA_CONTROL__PRIMGROUP_SIZE_MASK 0xffff\n#define VGT_DMA_CONTROL__PRIMGROUP_SIZE__SHIFT 0x0\n#define VGT_DMA_CONTROL__IA_SWITCH_ON_EOP_MASK 0x20000\n#define VGT_DMA_CONTROL__IA_SWITCH_ON_EOP__SHIFT 0x11\n#define VGT_DMA_CONTROL__WD_SWITCH_ON_EOP_MASK 0x100000\n#define VGT_DMA_CONTROL__WD_SWITCH_ON_EOP__SHIFT 0x14\n#define VGT_IMMED_DATA__DATA_MASK 0xffffffff\n#define VGT_IMMED_DATA__DATA__SHIFT 0x0\n#define VGT_INDEX_TYPE__INDEX_TYPE_MASK 0x3\n#define VGT_INDEX_TYPE__INDEX_TYPE__SHIFT 0x0\n#define VGT_NUM_INDICES__NUM_INDICES_MASK 0xffffffff\n#define VGT_NUM_INDICES__NUM_INDICES__SHIFT 0x0\n#define VGT_NUM_INSTANCES__NUM_INSTANCES_MASK 0xffffffff\n#define VGT_NUM_INSTANCES__NUM_INSTANCES__SHIFT 0x0\n#define VGT_PRIMITIVE_TYPE__PRIM_TYPE_MASK 0x3f\n#define VGT_PRIMITIVE_TYPE__PRIM_TYPE__SHIFT 0x0\n#define VGT_PRIMITIVEID_EN__PRIMITIVEID_EN_MASK 0x1\n#define VGT_PRIMITIVEID_EN__PRIMITIVEID_EN__SHIFT 0x0\n#define VGT_PRIMITIVEID_EN__DISABLE_RESET_ON_EOI_MASK 0x2\n#define VGT_PRIMITIVEID_EN__DISABLE_RESET_ON_EOI__SHIFT 0x1\n#define VGT_PRIMITIVEID_RESET__VALUE_MASK 0xffffffff\n#define VGT_PRIMITIVEID_RESET__VALUE__SHIFT 0x0\n#define VGT_VTX_CNT_EN__VTX_CNT_EN_MASK 0x1\n#define VGT_VTX_CNT_EN__VTX_CNT_EN__SHIFT 0x0\n#define VGT_REUSE_OFF__REUSE_OFF_MASK 0x1\n#define VGT_REUSE_OFF__REUSE_OFF__SHIFT 0x0\n#define VGT_INSTANCE_STEP_RATE_0__STEP_RATE_MASK 0xffffffff\n#define VGT_INSTANCE_STEP_RATE_0__STEP_RATE__SHIFT 0x0\n#define VGT_INSTANCE_STEP_RATE_1__STEP_RATE_MASK 0xffffffff\n#define VGT_INSTANCE_STEP_RATE_1__STEP_RATE__SHIFT 0x0\n#define VGT_MAX_VTX_INDX__MAX_INDX_MASK 0xffffffff\n#define VGT_MAX_VTX_INDX__MAX_INDX__SHIFT 0x0\n#define VGT_MIN_VTX_INDX__MIN_INDX_MASK 0xffffffff\n#define VGT_MIN_VTX_INDX__MIN_INDX__SHIFT 0x0\n#define VGT_INDX_OFFSET__INDX_OFFSET_MASK 0xffffffff\n#define VGT_INDX_OFFSET__INDX_OFFSET__SHIFT 0x0\n#define VGT_VERTEX_REUSE_BLOCK_CNTL__VTX_REUSE_DEPTH_MASK 0xff\n#define VGT_VERTEX_REUSE_BLOCK_CNTL__VTX_REUSE_DEPTH__SHIFT 0x0\n#define VGT_OUT_DEALLOC_CNTL__DEALLOC_DIST_MASK 0x7f\n#define VGT_OUT_DEALLOC_CNTL__DEALLOC_DIST__SHIFT 0x0\n#define VGT_MULTI_PRIM_IB_RESET_INDX__RESET_INDX_MASK 0xffffffff\n#define VGT_MULTI_PRIM_IB_RESET_INDX__RESET_INDX__SHIFT 0x0\n#define VGT_MULTI_PRIM_IB_RESET_EN__RESET_EN_MASK 0x1\n#define VGT_MULTI_PRIM_IB_RESET_EN__RESET_EN__SHIFT 0x0\n#define VGT_ENHANCE__MISC_MASK 0xffffffff\n#define VGT_ENHANCE__MISC__SHIFT 0x0\n#define VGT_OUTPUT_PATH_CNTL__PATH_SELECT_MASK 0x7\n#define VGT_OUTPUT_PATH_CNTL__PATH_SELECT__SHIFT 0x0\n#define VGT_HOS_CNTL__TESS_MODE_MASK 0x3\n#define VGT_HOS_CNTL__TESS_MODE__SHIFT 0x0\n#define VGT_HOS_MAX_TESS_LEVEL__MAX_TESS_MASK 0xffffffff\n#define VGT_HOS_MAX_TESS_LEVEL__MAX_TESS__SHIFT 0x0\n#define VGT_HOS_MIN_TESS_LEVEL__MIN_TESS_MASK 0xffffffff\n#define VGT_HOS_MIN_TESS_LEVEL__MIN_TESS__SHIFT 0x0\n#define VGT_HOS_REUSE_DEPTH__REUSE_DEPTH_MASK 0xff\n#define VGT_HOS_REUSE_DEPTH__REUSE_DEPTH__SHIFT 0x0\n#define VGT_GROUP_PRIM_TYPE__PRIM_TYPE_MASK 0x1f\n#define VGT_GROUP_PRIM_TYPE__PRIM_TYPE__SHIFT 0x0\n#define VGT_GROUP_PRIM_TYPE__RETAIN_ORDER_MASK 0x4000\n#define VGT_GROUP_PRIM_TYPE__RETAIN_ORDER__SHIFT 0xe\n#define VGT_GROUP_PRIM_TYPE__RETAIN_QUADS_MASK 0x8000\n#define VGT_GROUP_PRIM_TYPE__RETAIN_QUADS__SHIFT 0xf\n#define VGT_GROUP_PRIM_TYPE__PRIM_ORDER_MASK 0x70000\n#define VGT_GROUP_PRIM_TYPE__PRIM_ORDER__SHIFT 0x10\n#define VGT_GROUP_FIRST_DECR__FIRST_DECR_MASK 0xf\n#define VGT_GROUP_FIRST_DECR__FIRST_DECR__SHIFT 0x0\n#define VGT_GROUP_DECR__DECR_MASK 0xf\n#define VGT_GROUP_DECR__DECR__SHIFT 0x0\n#define VGT_GROUP_VECT_0_CNTL__COMP_X_EN_MASK 0x1\n#define VGT_GROUP_VECT_0_CNTL__COMP_X_EN__SHIFT 0x0\n#define VGT_GROUP_VECT_0_CNTL__COMP_Y_EN_MASK 0x2\n#define VGT_GROUP_VECT_0_CNTL__COMP_Y_EN__SHIFT 0x1\n#define VGT_GROUP_VECT_0_CNTL__COMP_Z_EN_MASK 0x4\n#define VGT_GROUP_VECT_0_CNTL__COMP_Z_EN__SHIFT 0x2\n#define VGT_GROUP_VECT_0_CNTL__COMP_W_EN_MASK 0x8\n#define VGT_GROUP_VECT_0_CNTL__COMP_W_EN__SHIFT 0x3\n#define VGT_GROUP_VECT_0_CNTL__STRIDE_MASK 0xff00\n#define VGT_GROUP_VECT_0_CNTL__STRIDE__SHIFT 0x8\n#define VGT_GROUP_VECT_0_CNTL__SHIFT_MASK 0xff0000\n#define VGT_GROUP_VECT_0_CNTL__SHIFT__SHIFT 0x10\n#define VGT_GROUP_VECT_1_CNTL__COMP_X_EN_MASK 0x1\n#define VGT_GROUP_VECT_1_CNTL__COMP_X_EN__SHIFT 0x0\n#define VGT_GROUP_VECT_1_CNTL__COMP_Y_EN_MASK 0x2\n#define VGT_GROUP_VECT_1_CNTL__COMP_Y_EN__SHIFT 0x1\n#define VGT_GROUP_VECT_1_CNTL__COMP_Z_EN_MASK 0x4\n#define VGT_GROUP_VECT_1_CNTL__COMP_Z_EN__SHIFT 0x2\n#define VGT_GROUP_VECT_1_CNTL__COMP_W_EN_MASK 0x8\n#define VGT_GROUP_VECT_1_CNTL__COMP_W_EN__SHIFT 0x3\n#define VGT_GROUP_VECT_1_CNTL__STRIDE_MASK 0xff00\n#define VGT_GROUP_VECT_1_CNTL__STRIDE__SHIFT 0x8\n#define VGT_GROUP_VECT_1_CNTL__SHIFT_MASK 0xff0000\n#define VGT_GROUP_VECT_1_CNTL__SHIFT__SHIFT 0x10\n#define VGT_GROUP_VECT_0_FMT_CNTL__X_CONV_MASK 0xf\n#define VGT_GROUP_VECT_0_FMT_CNTL__X_CONV__SHIFT 0x0\n#define VGT_GROUP_VECT_0_FMT_CNTL__X_OFFSET_MASK 0xf0\n#define VGT_GROUP_VECT_0_FMT_CNTL__X_OFFSET__SHIFT 0x4\n#define VGT_GROUP_VECT_0_FMT_CNTL__Y_CONV_MASK 0xf00\n#define VGT_GROUP_VECT_0_FMT_CNTL__Y_CONV__SHIFT 0x8\n#define VGT_GROUP_VECT_0_FMT_CNTL__Y_OFFSET_MASK 0xf000\n#define VGT_GROUP_VECT_0_FMT_CNTL__Y_OFFSET__SHIFT 0xc\n#define VGT_GROUP_VECT_0_FMT_CNTL__Z_CONV_MASK 0xf0000\n#define VGT_GROUP_VECT_0_FMT_CNTL__Z_CONV__SHIFT 0x10\n#define VGT_GROUP_VECT_0_FMT_CNTL__Z_OFFSET_MASK 0xf00000\n#define VGT_GROUP_VECT_0_FMT_CNTL__Z_OFFSET__SHIFT 0x14\n#define VGT_GROUP_VECT_0_FMT_CNTL__W_CONV_MASK 0xf000000\n#define VGT_GROUP_VECT_0_FMT_CNTL__W_CONV__SHIFT 0x18\n#define VGT_GROUP_VECT_0_FMT_CNTL__W_OFFSET_MASK 0xf0000000\n#define VGT_GROUP_VECT_0_FMT_CNTL__W_OFFSET__SHIFT 0x1c\n#define VGT_GROUP_VECT_1_FMT_CNTL__X_CONV_MASK 0xf\n#define VGT_GROUP_VECT_1_FMT_CNTL__X_CONV__SHIFT 0x0\n#define VGT_GROUP_VECT_1_FMT_CNTL__X_OFFSET_MASK 0xf0\n#define VGT_GROUP_VECT_1_FMT_CNTL__X_OFFSET__SHIFT 0x4\n#define VGT_GROUP_VECT_1_FMT_CNTL__Y_CONV_MASK 0xf00\n#define VGT_GROUP_VECT_1_FMT_CNTL__Y_CONV__SHIFT 0x8\n#define VGT_GROUP_VECT_1_FMT_CNTL__Y_OFFSET_MASK 0xf000\n#define VGT_GROUP_VECT_1_FMT_CNTL__Y_OFFSET__SHIFT 0xc\n#define VGT_GROUP_VECT_1_FMT_CNTL__Z_CONV_MASK 0xf0000\n#define VGT_GROUP_VECT_1_FMT_CNTL__Z_CONV__SHIFT 0x10\n#define VGT_GROUP_VECT_1_FMT_CNTL__Z_OFFSET_MASK 0xf00000\n#define VGT_GROUP_VECT_1_FMT_CNTL__Z_OFFSET__SHIFT 0x14\n#define VGT_GROUP_VECT_1_FMT_CNTL__W_CONV_MASK 0xf000000\n#define VGT_GROUP_VECT_1_FMT_CNTL__W_CONV__SHIFT 0x18\n#define VGT_GROUP_VECT_1_FMT_CNTL__W_OFFSET_MASK 0xf0000000\n#define VGT_GROUP_VECT_1_FMT_CNTL__W_OFFSET__SHIFT 0x1c\n#define VGT_VTX_VECT_EJECT_REG__PRIM_COUNT_MASK 0x3ff\n#define VGT_VTX_VECT_EJECT_REG__PRIM_COUNT__SHIFT 0x0\n#define VGT_DMA_DATA_FIFO_DEPTH__DMA_DATA_FIFO_DEPTH_MASK 0x1ff\n#define VGT_DMA_DATA_FIFO_DEPTH__DMA_DATA_FIFO_DEPTH__SHIFT 0x0\n#define VGT_DMA_REQ_FIFO_DEPTH__DMA_REQ_FIFO_DEPTH_MASK 0x3f\n#define VGT_DMA_REQ_FIFO_DEPTH__DMA_REQ_FIFO_DEPTH__SHIFT 0x0\n#define VGT_DRAW_INIT_FIFO_DEPTH__DRAW_INIT_FIFO_DEPTH_MASK 0x3f\n#define VGT_DRAW_INIT_FIFO_DEPTH__DRAW_INIT_FIFO_DEPTH__SHIFT 0x0\n#define VGT_LAST_COPY_STATE__SRC_STATE_ID_MASK 0x7\n#define VGT_LAST_COPY_STATE__SRC_STATE_ID__SHIFT 0x0\n#define VGT_LAST_COPY_STATE__DST_STATE_ID_MASK 0x70000\n#define VGT_LAST_COPY_STATE__DST_STATE_ID__SHIFT 0x10\n#define CC_GC_SHADER_ARRAY_CONFIG__DPFP_RATE_MASK 0x6\n#define CC_GC_SHADER_ARRAY_CONFIG__DPFP_RATE__SHIFT 0x1\n#define CC_GC_SHADER_ARRAY_CONFIG__SQC_BALANCE_DISABLE_MASK 0x8\n#define CC_GC_SHADER_ARRAY_CONFIG__SQC_BALANCE_DISABLE__SHIFT 0x3\n#define CC_GC_SHADER_ARRAY_CONFIG__HALF_LDS_MASK 0x10\n#define CC_GC_SHADER_ARRAY_CONFIG__HALF_LDS__SHIFT 0x4\n#define CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK 0xffff0000\n#define CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT 0x10\n#define GC_USER_SHADER_ARRAY_CONFIG__DPFP_RATE_MASK 0x6\n#define GC_USER_SHADER_ARRAY_CONFIG__DPFP_RATE__SHIFT 0x1\n#define GC_USER_SHADER_ARRAY_CONFIG__SQC_BALANCE_DISABLE_MASK 0x8\n#define GC_USER_SHADER_ARRAY_CONFIG__SQC_BALANCE_DISABLE__SHIFT 0x3\n#define GC_USER_SHADER_ARRAY_CONFIG__HALF_LDS_MASK 0x10\n#define GC_USER_SHADER_ARRAY_CONFIG__HALF_LDS__SHIFT 0x4\n#define GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK 0xffff0000\n#define GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT 0x10\n#define VGT_GS_MODE__MODE_MASK 0x7\n#define VGT_GS_MODE__MODE__SHIFT 0x0\n#define VGT_GS_MODE__RESERVED_0_MASK 0x8\n#define VGT_GS_MODE__RESERVED_0__SHIFT 0x3\n#define VGT_GS_MODE__CUT_MODE_MASK 0x30\n#define VGT_GS_MODE__CUT_MODE__SHIFT 0x4\n#define VGT_GS_MODE__RESERVED_1_MASK 0x7c0\n#define VGT_GS_MODE__RESERVED_1__SHIFT 0x6\n#define VGT_GS_MODE__GS_C_PACK_EN_MASK 0x800\n#define VGT_GS_MODE__GS_C_PACK_EN__SHIFT 0xb\n#define VGT_GS_MODE__RESERVED_2_MASK 0x1000\n#define VGT_GS_MODE__RESERVED_2__SHIFT 0xc\n#define VGT_GS_MODE__ES_PASSTHRU_MASK 0x2000\n#define VGT_GS_MODE__ES_PASSTHRU__SHIFT 0xd\n#define VGT_GS_MODE__COMPUTE_MODE_MASK 0x4000\n#define VGT_GS_MODE__COMPUTE_MODE__SHIFT 0xe\n#define VGT_GS_MODE__FAST_COMPUTE_MODE_MASK 0x8000\n#define VGT_GS_MODE__FAST_COMPUTE_MODE__SHIFT 0xf\n#define VGT_GS_MODE__ELEMENT_INFO_EN_MASK 0x10000\n#define VGT_GS_MODE__ELEMENT_INFO_EN__SHIFT 0x10\n#define VGT_GS_MODE__PARTIAL_THD_AT_EOI_MASK 0x20000\n#define VGT_GS_MODE__PARTIAL_THD_AT_EOI__SHIFT 0x11\n#define VGT_GS_MODE__SUPPRESS_CUTS_MASK 0x40000\n#define VGT_GS_MODE__SUPPRESS_CUTS__SHIFT 0x12\n#define VGT_GS_MODE__ES_WRITE_OPTIMIZE_MASK 0x80000\n#define VGT_GS_MODE__ES_WRITE_OPTIMIZE__SHIFT 0x13\n#define VGT_GS_MODE__GS_WRITE_OPTIMIZE_MASK 0x100000\n#define VGT_GS_MODE__GS_WRITE_OPTIMIZE__SHIFT 0x14\n#define VGT_GS_MODE__ONCHIP_MASK 0x600000\n#define VGT_GS_MODE__ONCHIP__SHIFT 0x15\n#define VGT_GS_ONCHIP_CNTL__ES_VERTS_PER_SUBGRP_MASK 0x7ff\n#define VGT_GS_ONCHIP_CNTL__ES_VERTS_PER_SUBGRP__SHIFT 0x0\n#define VGT_GS_ONCHIP_CNTL__GS_PRIMS_PER_SUBGRP_MASK 0x3ff800\n#define VGT_GS_ONCHIP_CNTL__GS_PRIMS_PER_SUBGRP__SHIFT 0xb\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_MASK 0x3f\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE__SHIFT 0x0\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_1_MASK 0x3f00\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_1__SHIFT 0x8\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_2_MASK 0x3f0000\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_2__SHIFT 0x10\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_3_MASK 0xfc00000\n#define VGT_GS_OUT_PRIM_TYPE__OUTPRIM_TYPE_3__SHIFT 0x16\n#define VGT_GS_OUT_PRIM_TYPE__UNIQUE_TYPE_PER_STREAM_MASK 0x80000000\n#define VGT_GS_OUT_PRIM_TYPE__UNIQUE_TYPE_PER_STREAM__SHIFT 0x1f\n#define VGT_CACHE_INVALIDATION__CACHE_INVALIDATION_MASK 0x3\n#define VGT_CACHE_INVALIDATION__CACHE_INVALIDATION__SHIFT 0x0\n#define VGT_CACHE_INVALIDATION__VS_NO_EXTRA_BUFFER_MASK 0x20\n#define VGT_CACHE_INVALIDATION__VS_NO_EXTRA_BUFFER__SHIFT 0x5\n#define VGT_CACHE_INVALIDATION__AUTO_INVLD_EN_MASK 0xc0\n#define VGT_CACHE_INVALIDATION__AUTO_INVLD_EN__SHIFT 0x6\n#define VGT_CACHE_INVALIDATION__USE_GS_DONE_MASK 0x200\n#define VGT_CACHE_INVALIDATION__USE_GS_DONE__SHIFT 0x9\n#define VGT_CACHE_INVALIDATION__DIS_RANGE_FULL_INVLD_MASK 0x800\n#define VGT_CACHE_INVALIDATION__DIS_RANGE_FULL_INVLD__SHIFT 0xb\n#define VGT_CACHE_INVALIDATION__GS_LATE_ALLOC_EN_MASK 0x1000\n#define VGT_CACHE_INVALIDATION__GS_LATE_ALLOC_EN__SHIFT 0xc\n#define VGT_CACHE_INVALIDATION__STREAMOUT_FULL_FLUSH_MASK 0x2000\n#define VGT_CACHE_INVALIDATION__STREAMOUT_FULL_FLUSH__SHIFT 0xd\n#define VGT_CACHE_INVALIDATION__ES_LIMIT_MASK 0x1f0000\n#define VGT_CACHE_INVALIDATION__ES_LIMIT__SHIFT 0x10\n#define VGT_RESET_DEBUG__GS_DISABLE_MASK 0x1\n#define VGT_RESET_DEBUG__GS_DISABLE__SHIFT 0x0\n#define VGT_RESET_DEBUG__TESS_DISABLE_MASK 0x2\n#define VGT_RESET_DEBUG__TESS_DISABLE__SHIFT 0x1\n#define VGT_RESET_DEBUG__WD_DISABLE_MASK 0x4\n#define VGT_RESET_DEBUG__WD_DISABLE__SHIFT 0x2\n#define VGT_STRMOUT_DELAY__SKIP_DELAY_MASK 0xff\n#define VGT_STRMOUT_DELAY__SKIP_DELAY__SHIFT 0x0\n#define VGT_STRMOUT_DELAY__SE0_WD_DELAY_MASK 0x700\n#define VGT_STRMOUT_DELAY__SE0_WD_DELAY__SHIFT 0x8\n#define VGT_STRMOUT_DELAY__SE1_WD_DELAY_MASK 0x3800\n#define VGT_STRMOUT_DELAY__SE1_WD_DELAY__SHIFT 0xb\n#define VGT_STRMOUT_DELAY__SE2_WD_DELAY_MASK 0x1c000\n#define VGT_STRMOUT_DELAY__SE2_WD_DELAY__SHIFT 0xe\n#define VGT_STRMOUT_DELAY__SE3_WD_DELAY_MASK 0xe0000\n#define VGT_STRMOUT_DELAY__SE3_WD_DELAY__SHIFT 0x11\n#define VGT_FIFO_DEPTHS__VS_DEALLOC_TBL_DEPTH_MASK 0x7f\n#define VGT_FIFO_DEPTHS__VS_DEALLOC_TBL_DEPTH__SHIFT 0x0\n#define VGT_FIFO_DEPTHS__RESERVED_0_MASK 0x80\n#define VGT_FIFO_DEPTHS__RESERVED_0__SHIFT 0x7\n#define VGT_FIFO_DEPTHS__CLIPP_FIFO_DEPTH_MASK 0x3fff00\n#define VGT_FIFO_DEPTHS__CLIPP_FIFO_DEPTH__SHIFT 0x8\n#define VGT_FIFO_DEPTHS__RESERVED_1_MASK 0x400000\n#define VGT_FIFO_DEPTHS__RESERVED_1__SHIFT 0x16\n#define VGT_GS_PER_ES__GS_PER_ES_MASK 0x7ff\n#define VGT_GS_PER_ES__GS_PER_ES__SHIFT 0x0\n#define VGT_ES_PER_GS__ES_PER_GS_MASK 0x7ff\n#define VGT_ES_PER_GS__ES_PER_GS__SHIFT 0x0\n#define VGT_GS_PER_VS__GS_PER_VS_MASK 0xf\n#define VGT_GS_PER_VS__GS_PER_VS__SHIFT 0x0\n#define VGT_GS_VERTEX_REUSE__VERT_REUSE_MASK 0x1f\n#define VGT_GS_VERTEX_REUSE__VERT_REUSE__SHIFT 0x0\n#define VGT_MC_LAT_CNTL__MC_TIME_STAMP_RES_MASK 0x3\n#define VGT_MC_LAT_CNTL__MC_TIME_STAMP_RES__SHIFT 0x0\n#define IA_CNTL_STATUS__IA_BUSY_MASK 0x1\n#define IA_CNTL_STATUS__IA_BUSY__SHIFT 0x0\n#define IA_CNTL_STATUS__IA_DMA_BUSY_MASK 0x2\n#define IA_CNTL_STATUS__IA_DMA_BUSY__SHIFT 0x1\n#define IA_CNTL_STATUS__IA_DMA_REQ_BUSY_MASK 0x4\n#define IA_CNTL_STATUS__IA_DMA_REQ_BUSY__SHIFT 0x2\n#define IA_CNTL_STATUS__IA_GRP_BUSY_MASK 0x8\n#define IA_CNTL_STATUS__IA_GRP_BUSY__SHIFT 0x3\n#define IA_CNTL_STATUS__IA_ADC_BUSY_MASK 0x10\n#define IA_CNTL_STATUS__IA_ADC_BUSY__SHIFT 0x4\n#define VGT_STRMOUT_CONFIG__STREAMOUT_0_EN_MASK 0x1\n#define VGT_STRMOUT_CONFIG__STREAMOUT_0_EN__SHIFT 0x0\n#define VGT_STRMOUT_CONFIG__STREAMOUT_1_EN_MASK 0x2\n#define VGT_STRMOUT_CONFIG__STREAMOUT_1_EN__SHIFT 0x1\n#define VGT_STRMOUT_CONFIG__STREAMOUT_2_EN_MASK 0x4\n#define VGT_STRMOUT_CONFIG__STREAMOUT_2_EN__SHIFT 0x2\n#define VGT_STRMOUT_CONFIG__STREAMOUT_3_EN_MASK 0x8\n#define VGT_STRMOUT_CONFIG__STREAMOUT_3_EN__SHIFT 0x3\n#define VGT_STRMOUT_CONFIG__RAST_STREAM_MASK 0x70\n#define VGT_STRMOUT_CONFIG__RAST_STREAM__SHIFT 0x4\n#define VGT_STRMOUT_CONFIG__RAST_STREAM_MASK_MASK 0xf00\n#define VGT_STRMOUT_CONFIG__RAST_STREAM_MASK__SHIFT 0x8\n#define VGT_STRMOUT_CONFIG__USE_RAST_STREAM_MASK_MASK 0x80000000\n#define VGT_STRMOUT_CONFIG__USE_RAST_STREAM_MASK__SHIFT 0x1f\n#define VGT_STRMOUT_BUFFER_SIZE_0__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_SIZE_0__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_SIZE_1__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_SIZE_1__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_SIZE_2__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_SIZE_2__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_SIZE_3__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_SIZE_3__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_OFFSET_0__OFFSET_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_OFFSET_0__OFFSET__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_OFFSET_1__OFFSET_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_OFFSET_1__OFFSET__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_OFFSET_2__OFFSET_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_OFFSET_2__OFFSET__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_OFFSET_3__OFFSET_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_OFFSET_3__OFFSET__SHIFT 0x0\n#define VGT_STRMOUT_VTX_STRIDE_0__STRIDE_MASK 0x3ff\n#define VGT_STRMOUT_VTX_STRIDE_0__STRIDE__SHIFT 0x0\n#define VGT_STRMOUT_VTX_STRIDE_1__STRIDE_MASK 0x3ff\n#define VGT_STRMOUT_VTX_STRIDE_1__STRIDE__SHIFT 0x0\n#define VGT_STRMOUT_VTX_STRIDE_2__STRIDE_MASK 0x3ff\n#define VGT_STRMOUT_VTX_STRIDE_2__STRIDE__SHIFT 0x0\n#define VGT_STRMOUT_VTX_STRIDE_3__STRIDE_MASK 0x3ff\n#define VGT_STRMOUT_VTX_STRIDE_3__STRIDE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_0_BUFFER_EN_MASK 0xf\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_0_BUFFER_EN__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_1_BUFFER_EN_MASK 0xf0\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_1_BUFFER_EN__SHIFT 0x4\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_2_BUFFER_EN_MASK 0xf00\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_2_BUFFER_EN__SHIFT 0x8\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_3_BUFFER_EN_MASK 0xf000\n#define VGT_STRMOUT_BUFFER_CONFIG__STREAM_3_BUFFER_EN__SHIFT 0xc\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_0__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_0__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_1__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_1__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_2__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_2__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_3__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_BUFFER_FILLED_SIZE_3__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_DRAW_OPAQUE_OFFSET__OFFSET_MASK 0xffffffff\n#define VGT_STRMOUT_DRAW_OPAQUE_OFFSET__OFFSET__SHIFT 0x0\n#define VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE__SIZE_MASK 0xffffffff\n#define VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE__SIZE__SHIFT 0x0\n#define VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE__VERTEX_STRIDE_MASK 0x1ff\n#define VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE__VERTEX_STRIDE__SHIFT 0x0\n#define VGT_GS_MAX_VERT_OUT__MAX_VERT_OUT_MASK 0x7ff\n#define VGT_GS_MAX_VERT_OUT__MAX_VERT_OUT__SHIFT 0x0\n#define IA_VMID_OVERRIDE__ENABLE_MASK 0x1\n#define IA_VMID_OVERRIDE__ENABLE__SHIFT 0x0\n#define IA_VMID_OVERRIDE__VMID_MASK 0x1e\n#define IA_VMID_OVERRIDE__VMID__SHIFT 0x1\n#define VGT_SHADER_STAGES_EN__LS_EN_MASK 0x3\n#define VGT_SHADER_STAGES_EN__LS_EN__SHIFT 0x0\n#define VGT_SHADER_STAGES_EN__HS_EN_MASK 0x4\n#define VGT_SHADER_STAGES_EN__HS_EN__SHIFT 0x2\n#define VGT_SHADER_STAGES_EN__ES_EN_MASK 0x18\n#define VGT_SHADER_STAGES_EN__ES_EN__SHIFT 0x3\n#define VGT_SHADER_STAGES_EN__GS_EN_MASK 0x20\n#define VGT_SHADER_STAGES_EN__GS_EN__SHIFT 0x5\n#define VGT_SHADER_STAGES_EN__VS_EN_MASK 0xc0\n#define VGT_SHADER_STAGES_EN__VS_EN__SHIFT 0x6\n#define VGT_SHADER_STAGES_EN__DYNAMIC_HS_MASK 0x100\n#define VGT_SHADER_STAGES_EN__DYNAMIC_HS__SHIFT 0x8\n#define VGT_DISPATCH_DRAW_INDEX__MATCH_INDEX_MASK 0xffffffff\n#define VGT_DISPATCH_DRAW_INDEX__MATCH_INDEX__SHIFT 0x0\n#define VGT_LS_HS_CONFIG__NUM_PATCHES_MASK 0xff\n#define VGT_LS_HS_CONFIG__NUM_PATCHES__SHIFT 0x0\n#define VGT_LS_HS_CONFIG__HS_NUM_INPUT_CP_MASK 0x3f00\n#define VGT_LS_HS_CONFIG__HS_NUM_INPUT_CP__SHIFT 0x8\n#define VGT_LS_HS_CONFIG__HS_NUM_OUTPUT_CP_MASK 0xfc000\n#define VGT_LS_HS_CONFIG__HS_NUM_OUTPUT_CP__SHIFT 0xe\n#define VGT_DMA_LS_HS_CONFIG__HS_NUM_INPUT_CP_MASK 0x3f00\n#define VGT_DMA_LS_HS_CONFIG__HS_NUM_INPUT_CP__SHIFT 0x8\n#define VGT_TF_PARAM__TYPE_MASK 0x3\n#define VGT_TF_PARAM__TYPE__SHIFT 0x0\n#define VGT_TF_PARAM__PARTITIONING_MASK 0x1c\n#define VGT_TF_PARAM__PARTITIONING__SHIFT 0x2\n#define VGT_TF_PARAM__TOPOLOGY_MASK 0xe0\n#define VGT_TF_PARAM__TOPOLOGY__SHIFT 0x5\n#define VGT_TF_PARAM__RESERVED_REDUC_AXIS_MASK 0x100\n#define VGT_TF_PARAM__RESERVED_REDUC_AXIS__SHIFT 0x8\n#define VGT_TF_PARAM__DEPRECATED_MASK 0x200\n#define VGT_TF_PARAM__DEPRECATED__SHIFT 0x9\n#define VGT_TF_PARAM__NUM_DS_WAVES_PER_SIMD_MASK 0x3c00\n#define VGT_TF_PARAM__NUM_DS_WAVES_PER_SIMD__SHIFT 0xa\n#define VGT_TF_PARAM__DISABLE_DONUTS_MASK 0x4000\n#define VGT_TF_PARAM__DISABLE_DONUTS__SHIFT 0xe\n#define VGT_TF_PARAM__RDREQ_POLICY_MASK 0x18000\n#define VGT_TF_PARAM__RDREQ_POLICY__SHIFT 0xf\n#define VGT_TF_RING_SIZE__SIZE_MASK 0xffff\n#define VGT_TF_RING_SIZE__SIZE__SHIFT 0x0\n#define VGT_SYS_CONFIG__DUAL_CORE_EN_MASK 0x1\n#define VGT_SYS_CONFIG__DUAL_CORE_EN__SHIFT 0x0\n#define VGT_SYS_CONFIG__MAX_LS_HS_THDGRP_MASK 0x7e\n#define VGT_SYS_CONFIG__MAX_LS_HS_THDGRP__SHIFT 0x1\n#define VGT_SYS_CONFIG__ADC_EVENT_FILTER_DISABLE_MASK 0x80\n#define VGT_SYS_CONFIG__ADC_EVENT_FILTER_DISABLE__SHIFT 0x7\n#define VGT_HS_OFFCHIP_PARAM__OFFCHIP_BUFFERING_MASK 0x1ff\n#define VGT_HS_OFFCHIP_PARAM__OFFCHIP_BUFFERING__SHIFT 0x0\n#define VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY_MASK 0x600\n#define VGT_HS_OFFCHIP_PARAM__OFFCHIP_GRANULARITY__SHIFT 0x9\n#define VGT_TF_MEMORY_BASE__BASE_MASK 0xffffffff\n#define VGT_TF_MEMORY_BASE__BASE__SHIFT 0x0\n#define VGT_GS_INSTANCE_CNT__ENABLE_MASK 0x1\n#define VGT_GS_INSTANCE_CNT__ENABLE__SHIFT 0x0\n#define VGT_GS_INSTANCE_CNT__CNT_MASK 0x1fc\n#define VGT_GS_INSTANCE_CNT__CNT__SHIFT 0x2\n#define IA_MULTI_VGT_PARAM__PRIMGROUP_SIZE_MASK 0xffff\n#define IA_MULTI_VGT_PARAM__PRIMGROUP_SIZE__SHIFT 0x0\n#define IA_MULTI_VGT_PARAM__PARTIAL_VS_WAVE_ON_MASK 0x10000\n#define IA_MULTI_VGT_PARAM__PARTIAL_VS_WAVE_ON__SHIFT 0x10\n#define IA_MULTI_VGT_PARAM__SWITCH_ON_EOP_MASK 0x20000\n#define IA_MULTI_VGT_PARAM__SWITCH_ON_EOP__SHIFT 0x11\n#define IA_MULTI_VGT_PARAM__PARTIAL_ES_WAVE_ON_MASK 0x40000\n#define IA_MULTI_VGT_PARAM__PARTIAL_ES_WAVE_ON__SHIFT 0x12\n#define IA_MULTI_VGT_PARAM__SWITCH_ON_EOI_MASK 0x80000\n#define IA_MULTI_VGT_PARAM__SWITCH_ON_EOI__SHIFT 0x13\n#define IA_MULTI_VGT_PARAM__WD_SWITCH_ON_EOP_MASK 0x100000\n#define IA_MULTI_VGT_PARAM__WD_SWITCH_ON_EOP__SHIFT 0x14\n#define VGT_VS_MAX_WAVE_ID__MAX_WAVE_ID_MASK 0xfff\n#define VGT_VS_MAX_WAVE_ID__MAX_WAVE_ID__SHIFT 0x0\n#define VGT_ESGS_RING_SIZE__MEM_SIZE_MASK 0xffffffff\n#define VGT_ESGS_RING_SIZE__MEM_SIZE__SHIFT 0x0\n#define VGT_GSVS_RING_SIZE__MEM_SIZE_MASK 0xffffffff\n#define VGT_GSVS_RING_SIZE__MEM_SIZE__SHIFT 0x0\n#define VGT_GSVS_RING_OFFSET_1__OFFSET_MASK 0x7fff\n#define VGT_GSVS_RING_OFFSET_1__OFFSET__SHIFT 0x0\n#define VGT_GSVS_RING_OFFSET_2__OFFSET_MASK 0x7fff\n#define VGT_GSVS_RING_OFFSET_2__OFFSET__SHIFT 0x0\n#define VGT_GSVS_RING_OFFSET_3__OFFSET_MASK 0x7fff\n#define VGT_GSVS_RING_OFFSET_3__OFFSET__SHIFT 0x0\n#define VGT_ESGS_RING_ITEMSIZE__ITEMSIZE_MASK 0x7fff\n#define VGT_ESGS_RING_ITEMSIZE__ITEMSIZE__SHIFT 0x0\n#define VGT_GSVS_RING_ITEMSIZE__ITEMSIZE_MASK 0x7fff\n#define VGT_GSVS_RING_ITEMSIZE__ITEMSIZE__SHIFT 0x0\n#define VGT_GS_VERT_ITEMSIZE__ITEMSIZE_MASK 0x7fff\n#define VGT_GS_VERT_ITEMSIZE__ITEMSIZE__SHIFT 0x0\n#define VGT_GS_VERT_ITEMSIZE_1__ITEMSIZE_MASK 0x7fff\n#define VGT_GS_VERT_ITEMSIZE_1__ITEMSIZE__SHIFT 0x0\n#define VGT_GS_VERT_ITEMSIZE_2__ITEMSIZE_MASK 0x7fff\n#define VGT_GS_VERT_ITEMSIZE_2__ITEMSIZE__SHIFT 0x0\n#define VGT_GS_VERT_ITEMSIZE_3__ITEMSIZE_MASK 0x7fff\n#define VGT_GS_VERT_ITEMSIZE_3__ITEMSIZE__SHIFT 0x0\n#define WD_CNTL_STATUS__WD_BUSY_MASK 0x1\n#define WD_CNTL_STATUS__WD_BUSY__SHIFT 0x0\n#define WD_CNTL_STATUS__WD_SPL_DMA_BUSY_MASK 0x2\n#define WD_CNTL_STATUS__WD_SPL_DMA_BUSY__SHIFT 0x1\n#define WD_CNTL_STATUS__WD_SPL_DI_BUSY_MASK 0x4\n#define WD_CNTL_STATUS__WD_SPL_DI_BUSY__SHIFT 0x2\n#define WD_CNTL_STATUS__WD_ADC_BUSY_MASK 0x8\n#define WD_CNTL_STATUS__WD_ADC_BUSY__SHIFT 0x3\n#define WD_ENHANCE__MISC_MASK 0xffffffff\n#define WD_ENHANCE__MISC__SHIFT 0x0\n#define GFX_PIPE_CONTROL__HYSTERESIS_CNT_MASK 0x1fff\n#define GFX_PIPE_CONTROL__HYSTERESIS_CNT__SHIFT 0x0\n#define GFX_PIPE_CONTROL__RESERVED_MASK 0xe000\n#define GFX_PIPE_CONTROL__RESERVED__SHIFT 0xd\n#define GFX_PIPE_CONTROL__CONTEXT_SUSPEND_EN_MASK 0x10000\n#define GFX_PIPE_CONTROL__CONTEXT_SUSPEND_EN__SHIFT 0x10\n#define GFX_PIPE_PRIORITY__HP_PIPE_SELECT_MASK 0x1\n#define GFX_PIPE_PRIORITY__HP_PIPE_SELECT__SHIFT 0x0\n#define CGTT_VGT_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_VGT_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_VGT_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_VGT_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_VGT_CLK_CTRL__PERF_ENABLE_MASK 0x2000000\n#define CGTT_VGT_CLK_CTRL__PERF_ENABLE__SHIFT 0x19\n#define CGTT_VGT_CLK_CTRL__DBG_ENABLE_MASK 0x4000000\n#define CGTT_VGT_CLK_CTRL__DBG_ENABLE__SHIFT 0x1a\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_VGT_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_VGT_CLK_CTRL__GS_OVERRIDE_MASK 0x20000000\n#define CGTT_VGT_CLK_CTRL__GS_OVERRIDE__SHIFT 0x1d\n#define CGTT_VGT_CLK_CTRL__CORE_OVERRIDE_MASK 0x40000000\n#define CGTT_VGT_CLK_CTRL__CORE_OVERRIDE__SHIFT 0x1e\n#define CGTT_VGT_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_VGT_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define CGTT_IA_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_IA_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_IA_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_IA_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_IA_CLK_CTRL__PERF_ENABLE_MASK 0x2000000\n#define CGTT_IA_CLK_CTRL__PERF_ENABLE__SHIFT 0x19\n#define CGTT_IA_CLK_CTRL__DBG_ENABLE_MASK 0x4000000\n#define CGTT_IA_CLK_CTRL__DBG_ENABLE__SHIFT 0x1a\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE3_MASK 0x10000000\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE3__SHIFT 0x1c\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE2_MASK 0x20000000\n#define CGTT_IA_CLK_CTRL__SOFT_OVERRIDE2__SHIFT 0x1d\n#define CGTT_IA_CLK_CTRL__CORE_OVERRIDE_MASK 0x40000000\n#define CGTT_IA_CLK_CTRL__CORE_OVERRIDE__SHIFT 0x1e\n#define CGTT_IA_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_IA_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define CGTT_WD_CLK_CTRL__ON_DELAY_MASK 0xf\n#define CGTT_WD_CLK_CTRL__ON_DELAY__SHIFT 0x0\n#define CGTT_WD_CLK_CTRL__OFF_HYSTERESIS_MASK 0xff0\n#define CGTT_WD_CLK_CTRL__OFF_HYSTERESIS__SHIFT 0x4\n#define CGTT_WD_CLK_CTRL__SOFT_OVERRIDE7_MASK 0x1000000\n#define CGTT_WD_CLK_CTRL__SOFT_OVERRIDE7__SHIFT 0x18\n#define CGTT_WD_CLK_CTRL__PERF_ENABLE_MASK 0x2000000\n#define CGTT_WD_CLK_CTRL__PERF_ENABLE__SHIFT 0x19\n#define CGTT_WD_CLK_CTRL__DBG_ENABLE_MASK 0x4000000\n#define CGTT_WD_CLK_CTRL__DBG_ENABLE__SHIFT 0x1a\n#define CGTT_WD_CLK_CTRL__SOFT_OVERRIDE4_MASK 0x8000000\n#define CGTT_WD_CLK_CTRL__SOFT_OVERRIDE4__SHIFT 0x1b\n#define CGTT_WD_CLK_CTRL__ADC_OVERRIDE_MASK 0x10000000\n#define CGTT_WD_CLK_CTRL__ADC_OVERRIDE__SHIFT 0x1c\n#define CGTT_WD_CLK_CTRL__CORE_OVERRIDE_MASK 0x20000000\n#define CGTT_WD_CLK_CTRL__CORE_OVERRIDE__SHIFT 0x1d\n#define CGTT_WD_CLK_CTRL__RBIU_INPUT_OVERRIDE_MASK 0x40000000\n#define CGTT_WD_CLK_CTRL__RBIU_INPUT_OVERRIDE__SHIFT 0x1e\n#define CGTT_WD_CLK_CTRL__REG_OVERRIDE_MASK 0x80000000\n#define CGTT_WD_CLK_CTRL__REG_OVERRIDE__SHIFT 0x1f\n#define VGT_DEBUG_CNTL__VGT_DEBUG_INDX_MASK 0x3f\n#define VGT_DEBUG_CNTL__VGT_DEBUG_INDX__SHIFT 0x0\n#define VGT_DEBUG_CNTL__VGT_DEBUG_SEL_BUS_B_MASK 0x40\n#define VGT_DEBUG_CNTL__VGT_DEBUG_SEL_BUS_B__SHIFT 0x6\n#define VGT_DEBUG_DATA__DATA_MASK 0xffffffff\n#define VGT_DEBUG_DATA__DATA__SHIFT 0x0\n#define IA_DEBUG_CNTL__IA_DEBUG_INDX_MASK 0x3f\n#define IA_DEBUG_CNTL__IA_DEBUG_INDX__SHIFT 0x0\n#define IA_DEBUG_CNTL__IA_DEBUG_SEL_BUS_B_MASK 0x40\n#define IA_DEBUG_CNTL__IA_DEBUG_SEL_BUS_B__SHIFT 0x6\n#define IA_DEBUG_DATA__DATA_MASK 0xffffffff\n#define IA_DEBUG_DATA__DATA__SHIFT 0x0\n#define VGT_CNTL_STATUS__VGT_BUSY_MASK 0x1\n#define VGT_CNTL_STATUS__VGT_BUSY__SHIFT 0x0\n#define VGT_CNTL_STATUS__VGT_OUT_INDX_BUSY_MASK 0x2\n#define VGT_CNTL_STATUS__VGT_OUT_INDX_BUSY__SHIFT 0x1\n#define VGT_CNTL_STATUS__VGT_OUT_BUSY_MASK 0x4\n#define VGT_CNTL_STATUS__VGT_OUT_BUSY__SHIFT 0x2\n#define VGT_CNTL_STATUS__VGT_PT_BUSY_MASK 0x8\n#define VGT_CNTL_STATUS__VGT_PT_BUSY__SHIFT 0x3\n#define VGT_CNTL_STATUS__VGT_TE_BUSY_MASK 0x10\n#define VGT_CNTL_STATUS__VGT_TE_BUSY__SHIFT 0x4\n#define VGT_CNTL_STATUS__VGT_VR_BUSY_MASK 0x20\n#define VGT_CNTL_STATUS__VGT_VR_BUSY__SHIFT 0x5\n#define VGT_CNTL_STATUS__VGT_PI_BUSY_MASK 0x40\n#define VGT_CNTL_STATUS__VGT_PI_BUSY__SHIFT 0x6\n#define VGT_CNTL_STATUS__VGT_GS_BUSY_MASK 0x80\n#define VGT_CNTL_STATUS__VGT_GS_BUSY__SHIFT 0x7\n#define VGT_CNTL_STATUS__VGT_HS_BUSY_MASK 0x100\n#define VGT_CNTL_STATUS__VGT_HS_BUSY__SHIFT 0x8\n#define VGT_CNTL_STATUS__VGT_TE11_BUSY_MASK 0x200\n#define VGT_CNTL_STATUS__VGT_TE11_BUSY__SHIFT 0x9\n#define WD_DEBUG_CNTL__WD_DEBUG_INDX_MASK 0x3f\n#define WD_DEBUG_CNTL__WD_DEBUG_INDX__SHIFT 0x0\n#define WD_DEBUG_CNTL__WD_DEBUG_SEL_BUS_B_MASK 0x40\n#define WD_DEBUG_CNTL__WD_DEBUG_SEL_BUS_B__SHIFT 0x6\n#define WD_DEBUG_DATA__DATA_MASK 0xffffffff\n#define WD_DEBUG_DATA__DATA__SHIFT 0x0\n#define CC_GC_PRIM_CONFIG__INACTIVE_IA_MASK 0x30000\n#define CC_GC_PRIM_CONFIG__INACTIVE_IA__SHIFT 0x10\n#define CC_GC_PRIM_CONFIG__INACTIVE_VGT_PA_MASK 0xf000000\n#define CC_GC_PRIM_CONFIG__INACTIVE_VGT_PA__SHIFT 0x18\n#define GC_USER_PRIM_CONFIG__INACTIVE_IA_MASK 0x30000\n#define GC_USER_PRIM_CONFIG__INACTIVE_IA__SHIFT 0x10\n#define GC_USER_PRIM_CONFIG__INACTIVE_VGT_PA_MASK 0xf000000\n#define GC_USER_PRIM_CONFIG__INACTIVE_VGT_PA__SHIFT 0x18\n#define WD_DEBUG_REG0__wd_busy_extended_MASK 0x1\n#define WD_DEBUG_REG0__wd_busy_extended__SHIFT 0x0\n#define WD_DEBUG_REG0__wd_nodma_busy_extended_MASK 0x2\n#define WD_DEBUG_REG0__wd_nodma_busy_extended__SHIFT 0x1\n#define WD_DEBUG_REG0__wd_busy_MASK 0x4\n#define WD_DEBUG_REG0__wd_busy__SHIFT 0x2\n#define WD_DEBUG_REG0__wd_nodma_busy_MASK 0x8\n#define WD_DEBUG_REG0__wd_nodma_busy__SHIFT 0x3\n#define WD_DEBUG_REG0__rbiu_busy_MASK 0x10\n#define WD_DEBUG_REG0__rbiu_busy__SHIFT 0x4\n#define WD_DEBUG_REG0__spl_dma_busy_MASK 0x20\n#define WD_DEBUG_REG0__spl_dma_busy__SHIFT 0x5\n#define WD_DEBUG_REG0__spl_di_busy_MASK 0x40\n#define WD_DEBUG_REG0__spl_di_busy__SHIFT 0x6\n#define WD_DEBUG_REG0__vgt0_active_q_MASK 0x80\n#define WD_DEBUG_REG0__vgt0_active_q__SHIFT 0x7\n#define WD_DEBUG_REG0__vgt1_active_q_MASK 0x100\n#define WD_DEBUG_REG0__vgt1_active_q__SHIFT 0x8\n#define WD_DEBUG_REG0__spl_dma_p1_busy_MASK 0x200\n#define WD_DEBUG_REG0__spl_dma_p1_busy__SHIFT 0x9\n#define WD_DEBUG_REG0__rbiu_dr_p1_fifo_busy_MASK 0x400\n#define WD_DEBUG_REG0__rbiu_dr_p1_fifo_busy__SHIFT 0xa\n#define WD_DEBUG_REG0__rbiu_di_p1_fifo_busy_MASK 0x800\n#define WD_DEBUG_REG0__rbiu_di_p1_fifo_busy__SHIFT 0xb\n#define WD_DEBUG_REG0__SPARE2_MASK 0x1000\n#define WD_DEBUG_REG0__SPARE2__SHIFT 0xc\n#define WD_DEBUG_REG0__rbiu_dr_fifo_busy_MASK 0x2000\n#define WD_DEBUG_REG0__rbiu_dr_fifo_busy__SHIFT 0xd\n#define WD_DEBUG_REG0__rbiu_spl_dr_valid_MASK 0x4000\n#define WD_DEBUG_REG0__rbiu_spl_dr_valid__SHIFT 0xe\n#define WD_DEBUG_REG0__spl_rbiu_dr_read_MASK 0x8000\n#define WD_DEBUG_REG0__spl_rbiu_dr_read__SHIFT 0xf\n#define WD_DEBUG_REG0__SPARE3_MASK 0x10000\n#define WD_DEBUG_REG0__SPARE3__SHIFT 0x10\n#define WD_DEBUG_REG0__rbiu_di_fifo_busy_MASK 0x20000\n#define WD_DEBUG_REG0__rbiu_di_fifo_busy__SHIFT 0x11\n#define WD_DEBUG_REG0__rbiu_spl_di_valid_MASK 0x40000\n#define WD_DEBUG_REG0__rbiu_spl_di_valid__SHIFT 0x12\n#define WD_DEBUG_REG0__spl_rbiu_di_read_MASK 0x80000\n#define WD_DEBUG_REG0__spl_rbiu_di_read__SHIFT 0x13\n#define WD_DEBUG_REG0__se0_synced_q_MASK 0x100000\n#define WD_DEBUG_REG0__se0_synced_q__SHIFT 0x14\n#define WD_DEBUG_REG0__se1_synced_q_MASK 0x200000\n#define WD_DEBUG_REG0__se1_synced_q__SHIFT 0x15\n#define WD_DEBUG_REG0__se2_synced_q_MASK 0x400000\n#define WD_DEBUG_REG0__se2_synced_q__SHIFT 0x16\n#define WD_DEBUG_REG0__se3_synced_q_MASK 0x800000\n#define WD_DEBUG_REG0__se3_synced_q__SHIFT 0x17\n#define WD_DEBUG_REG0__reg_clk_busy_MASK 0x1000000\n#define WD_DEBUG_REG0__reg_clk_busy__SHIFT 0x18\n#define WD_DEBUG_REG0__input_clk_busy_MASK 0x2000000\n#define WD_DEBUG_REG0__input_clk_busy__SHIFT 0x19\n#define WD_DEBUG_REG0__core_clk_busy_MASK 0x4000000\n#define WD_DEBUG_REG0__core_clk_busy__SHIFT 0x1a\n#define WD_DEBUG_REG0__vgt2_active_q_MASK 0x8000000\n#define WD_DEBUG_REG0__vgt2_active_q__SHIFT 0x1b\n#define WD_DEBUG_REG0__sclk_reg_vld_MASK 0x10000000\n#define WD_DEBUG_REG0__sclk_reg_vld__SHIFT 0x1c\n#define WD_DEBUG_REG0__sclk_input_vld_MASK 0x20000000\n#define WD_DEBUG_REG0__sclk_input_vld__SHIFT 0x1d\n#define WD_DEBUG_REG0__sclk_core_vld_MASK 0x40000000\n#define WD_DEBUG_REG0__sclk_core_vld__SHIFT 0x1e\n#define WD_DEBUG_REG0__vgt3_active_q_MASK 0x80000000\n#define WD_DEBUG_REG0__vgt3_active_q__SHIFT 0x1f\n#define WD_DEBUG_REG1__grbm_fifo_empty_MASK 0x1\n#define WD_DEBUG_REG1__grbm_fifo_empty__SHIFT 0x0\n#define WD_DEBUG_REG1__grbm_fifo_full_MASK 0x2\n#define WD_DEBUG_REG1__grbm_fifo_full__SHIFT 0x1\n#define WD_DEBUG_REG1__grbm_fifo_we_MASK 0x4\n#define WD_DEBUG_REG1__grbm_fifo_we__SHIFT 0x2\n#define WD_DEBUG_REG1__grbm_fifo_re_MASK 0x8\n#define WD_DEBUG_REG1__grbm_fifo_re__SHIFT 0x3\n#define WD_DEBUG_REG1__draw_initiator_valid_q_MASK 0x10\n#define WD_DEBUG_REG1__draw_initiator_valid_q__SHIFT 0x4\n#define WD_DEBUG_REG1__event_initiator_valid_q_MASK 0x20\n#define WD_DEBUG_REG1__event_initiator_valid_q__SHIFT 0x5\n#define WD_DEBUG_REG1__event_addr_valid_q_MASK 0x40\n#define WD_DEBUG_REG1__event_addr_valid_q__SHIFT 0x6\n#define WD_DEBUG_REG1__dma_request_valid_q_MASK 0x80\n#define WD_DEBUG_REG1__dma_request_valid_q__SHIFT 0x7\n#define WD_DEBUG_REG1__SPARE0_MASK 0x100\n#define WD_DEBUG_REG1__SPARE0__SHIFT 0x8\n#define WD_DEBUG_REG1__min_indx_valid_q_MASK 0x200\n#define WD_DEBUG_REG1__min_indx_valid_q__SHIFT 0x9\n#define WD_DEBUG_REG1__max_indx_valid_q_MASK 0x400\n#define WD_DEBUG_REG1__max_indx_valid_q__SHIFT 0xa\n#define WD_DEBUG_REG1__indx_offset_valid_q_MASK 0x800\n#define WD_DEBUG_REG1__indx_offset_valid_q__SHIFT 0xb\n#define WD_DEBUG_REG1__grbm_fifo_rdata_reg_id_MASK 0x1f000\n#define WD_DEBUG_REG1__grbm_fifo_rdata_reg_id__SHIFT 0xc\n#define WD_DEBUG_REG1__grbm_fifo_rdata_state_MASK 0xe0000\n#define WD_DEBUG_REG1__grbm_fifo_rdata_state__SHIFT 0x11\n#define WD_DEBUG_REG1__free_cnt_q_MASK 0x3f00000\n#define WD_DEBUG_REG1__free_cnt_q__SHIFT 0x14\n#define WD_DEBUG_REG1__rbiu_di_fifo_we_MASK 0x4000000\n#define WD_DEBUG_REG1__rbiu_di_fifo_we__SHIFT 0x1a\n#define WD_DEBUG_REG1__rbiu_dr_fifo_we_MASK 0x8000000\n#define WD_DEBUG_REG1__rbiu_dr_fifo_we__SHIFT 0x1b\n#define WD_DEBUG_REG1__rbiu_di_fifo_empty_MASK 0x10000000\n#define WD_DEBUG_REG1__rbiu_di_fifo_empty__SHIFT 0x1c\n#define WD_DEBUG_REG1__rbiu_di_fifo_full_MASK 0x20000000\n#define WD_DEBUG_REG1__rbiu_di_fifo_full__SHIFT 0x1d\n#define WD_DEBUG_REG1__rbiu_dr_fifo_empty_MASK 0x40000000\n#define WD_DEBUG_REG1__rbiu_dr_fifo_empty__SHIFT 0x1e\n#define WD_DEBUG_REG1__rbiu_dr_fifo_full_MASK 0x80000000\n#define WD_DEBUG_REG1__rbiu_dr_fifo_full__SHIFT 0x1f\n#define WD_DEBUG_REG2__p1_grbm_fifo_empty_MASK 0x1\n#define WD_DEBUG_REG2__p1_grbm_fifo_empty__SHIFT 0x0\n#define WD_DEBUG_REG2__p1_grbm_fifo_full_MASK 0x2\n#define WD_DEBUG_REG2__p1_grbm_fifo_full__SHIFT 0x1\n#define WD_DEBUG_REG2__p1_grbm_fifo_we_MASK 0x4\n#define WD_DEBUG_REG2__p1_grbm_fifo_we__SHIFT 0x2\n#define WD_DEBUG_REG2__p1_grbm_fifo_re_MASK 0x8\n#define WD_DEBUG_REG2__p1_grbm_fifo_re__SHIFT 0x3\n#define WD_DEBUG_REG2__p1_draw_initiator_valid_q_MASK 0x10\n#define WD_DEBUG_REG2__p1_draw_initiator_valid_q__SHIFT 0x4\n#define WD_DEBUG_REG2__p1_event_initiator_valid_q_MASK 0x20\n#define WD_DEBUG_REG2__p1_event_initiator_valid_q__SHIFT 0x5\n#define WD_DEBUG_REG2__p1_event_addr_valid_q_MASK 0x40\n#define WD_DEBUG_REG2__p1_event_addr_valid_q__SHIFT 0x6\n#define WD_DEBUG_REG2__p1_dma_request_valid_q_MASK 0x80\n#define WD_DEBUG_REG2__p1_dma_request_valid_q__SHIFT 0x7\n#define WD_DEBUG_REG2__SPARE0_MASK 0x100\n#define WD_DEBUG_REG2__SPARE0__SHIFT 0x8\n#define WD_DEBUG_REG2__p1_min_indx_valid_q_MASK 0x200\n#define WD_DEBUG_REG2__p1_min_indx_valid_q__SHIFT 0x9\n#define WD_DEBUG_REG2__p1_max_indx_valid_q_MASK 0x400\n#define WD_DEBUG_REG2__p1_max_indx_valid_q__SHIFT 0xa\n#define WD_DEBUG_REG2__p1_indx_offset_valid_q_MASK 0x800\n#define WD_DEBUG_REG2__p1_indx_offset_valid_q__SHIFT 0xb\n#define WD_DEBUG_REG2__p1_grbm_fifo_rdata_reg_id_MASK 0x1f000\n#define WD_DEBUG_REG2__p1_grbm_fifo_rdata_reg_id__SHIFT 0xc\n#define WD_DEBUG_REG2__p1_grbm_fifo_rdata_state_MASK 0xe0000\n#define WD_DEBUG_REG2__p1_grbm_fifo_rdata_state__SHIFT 0x11\n#define WD_DEBUG_REG2__p1_free_cnt_q_MASK 0x3f00000\n#define WD_DEBUG_REG2__p1_free_cnt_q__SHIFT 0x14\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_we_MASK 0x4000000\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_we__SHIFT 0x1a\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_we_MASK 0x8000000\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_we__SHIFT 0x1b\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_empty_MASK 0x10000000\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_empty__SHIFT 0x1c\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_full_MASK 0x20000000\n#define WD_DEBUG_REG2__p1_rbiu_di_fifo_full__SHIFT 0x1d\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_empty_MASK 0x40000000\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_empty__SHIFT 0x1e\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_full_MASK 0x80000000\n#define WD_DEBUG_REG2__p1_rbiu_dr_fifo_full__SHIFT 0x1f\n#define WD_DEBUG_REG3__rbiu_spl_dr_valid_MASK 0x1\n#define WD_DEBUG_REG3__rbiu_spl_dr_valid__SHIFT 0x0\n#define WD_DEBUG_REG3__SPARE0_MASK 0x2\n#define WD_DEBUG_REG3__SPARE0__SHIFT 0x1\n#define WD_DEBUG_REG3__pipe0_dr_MASK 0x4\n#define WD_DEBUG_REG3__pipe0_dr__SHIFT 0x2\n#define WD_DEBUG_REG3__pipe0_rtr_MASK 0x8\n#define WD_DEBUG_REG3__pipe0_rtr__SHIFT 0x3\n#define WD_DEBUG_REG3__pipe1_dr_MASK 0x10\n#define WD_DEBUG_REG3__pipe1_dr__SHIFT 0x4\n#define WD_DEBUG_REG3__pipe1_rtr_MASK 0x20\n#define WD_DEBUG_REG3__pipe1_rtr__SHIFT 0x5\n#define WD_DEBUG_REG3__wd_subdma_fifo_empty_MASK 0x40\n#define WD_DEBUG_REG3__wd_subdma_fifo_empty__SHIFT 0x6\n#define WD_DEBUG_REG3__wd_subdma_fifo_full_MASK 0x80\n#define WD_DEBUG_REG3__wd_subdma_fifo_full__SHIFT 0x7\n#define WD_DEBUG_REG3__dma_buf_type_p0_q_MASK 0x300\n#define WD_DEBUG_REG3__dma_buf_type_p0_q__SHIFT 0x8\n#define WD_DEBUG_REG3__dma_zero_indices_p0_q_MASK 0x400\n#define WD_DEBUG_REG3__dma_zero_indices_p0_q__SHIFT 0xa\n#define WD_DEBUG_REG3__dma_req_path_p3_q_MASK 0x800\n#define WD_DEBUG_REG3__dma_req_path_p3_q__SHIFT 0xb\n#define WD_DEBUG_REG3__dma_not_eop_p1_q_MASK 0x1000\n#define WD_DEBUG_REG3__dma_not_eop_p1_q__SHIFT 0xc\n#define WD_DEBUG_REG3__out_of_range_p4_MASK 0x2000\n#define WD_DEBUG_REG3__out_of_range_p4__SHIFT 0xd\n#define WD_DEBUG_REG3__last_sub_dma_p3_q_MASK 0x4000\n#define WD_DEBUG_REG3__last_sub_dma_p3_q__SHIFT 0xe\n#define WD_DEBUG_REG3__last_rdreq_of_sub_dma_p4_MASK 0x8000\n#define WD_DEBUG_REG3__last_rdreq_of_sub_dma_p4__SHIFT 0xf\n#define WD_DEBUG_REG3__WD_IA_dma_send_d_MASK 0x10000\n#define WD_DEBUG_REG3__WD_IA_dma_send_d__SHIFT 0x10\n#define WD_DEBUG_REG3__WD_IA_dma_rtr_MASK 0x20000\n#define WD_DEBUG_REG3__WD_IA_dma_rtr__SHIFT 0x11\n#define WD_DEBUG_REG3__WD_IA1_dma_send_d_MASK 0x40000\n#define WD_DEBUG_REG3__WD_IA1_dma_send_d__SHIFT 0x12\n#define WD_DEBUG_REG3__WD_IA1_dma_rtr_MASK 0x80000\n#define WD_DEBUG_REG3__WD_IA1_dma_rtr__SHIFT 0x13\n#define WD_DEBUG_REG3__last_inst_of_dma_p2_MASK 0x100000\n#define WD_DEBUG_REG3__last_inst_of_dma_p2__SHIFT 0x14\n#define WD_DEBUG_REG3__last_sd_of_inst_p2_MASK 0x200000\n#define WD_DEBUG_REG3__last_sd_of_inst_p2__SHIFT 0x15\n#define WD_DEBUG_REG3__last_sd_of_dma_p2_MASK 0x400000\n#define WD_DEBUG_REG3__last_sd_of_dma_p2__SHIFT 0x16\n#define WD_DEBUG_REG3__SPARE1_MASK 0x800000\n#define WD_DEBUG_REG3__SPARE1__SHIFT 0x17\n#define WD_DEBUG_REG3__WD_IA_dma_busy_MASK 0x1000000\n#define WD_DEBUG_REG3__WD_IA_dma_busy__SHIFT 0x18\n#define WD_DEBUG_REG3__WD_IA1_dma_busy_MASK 0x2000000\n#define WD_DEBUG_REG3__WD_IA1_dma_busy__SHIFT 0x19\n#define WD_DEBUG_REG3__send_to_ia1_p3_q_MASK 0x4000000\n#define WD_DEBUG_REG3__send_to_ia1_p3_q__SHIFT 0x1a\n#define WD_DEBUG_REG3__dma_wd_switch_on_eop_p3_q_MASK 0x8000000\n#define WD_DEBUG_REG3__dma_wd_switch_on_eop_p3_q__SHIFT 0x1b\n#define WD_DEBUG_REG3__pipe3_dr_MASK 0x10000000\n#define WD_DEBUG_REG3__pipe3_dr__SHIFT 0x1c\n#define WD_DEBUG_REG3__pipe3_rtr_MASK 0x20000000\n#define WD_DEBUG_REG3__pipe3_rtr__SHIFT 0x1d\n#define WD_DEBUG_REG3__wd_dma2draw_fifo_empty_MASK 0x40000000\n#define WD_DEBUG_REG3__wd_dma2draw_fifo_empty__SHIFT 0x1e\n#define WD_DEBUG_REG3__wd_dma2draw_fifo_full_MASK 0x80000000\n#define WD_DEBUG_REG3__wd_dma2draw_fifo_full__SHIFT 0x1f\n#define WD_DEBUG_REG4__rbiu_spl_di_valid_MASK 0x1\n#define WD_DEBUG_REG4__rbiu_spl_di_valid__SHIFT 0x0\n#define WD_DEBUG_REG4__spl_rbiu_di_read_MASK 0x2\n#define WD_DEBUG_REG4__spl_rbiu_di_read__SHIFT 0x1\n#define WD_DEBUG_REG4__rbiu_spl_p1_di_valid_MASK 0x4\n#define WD_DEBUG_REG4__rbiu_spl_p1_di_valid__SHIFT 0x2\n#define WD_DEBUG_REG4__spl_rbiu_p1_di_read_MASK 0x8\n#define WD_DEBUG_REG4__spl_rbiu_p1_di_read__SHIFT 0x3\n#define WD_DEBUG_REG4__pipe0_dr_MASK 0x10\n#define WD_DEBUG_REG4__pipe0_dr__SHIFT 0x4\n#define WD_DEBUG_REG4__pipe0_rtr_MASK 0x20\n#define WD_DEBUG_REG4__pipe0_rtr__SHIFT 0x5\n#define WD_DEBUG_REG4__pipe1_dr_MASK 0x40\n#define WD_DEBUG_REG4__pipe1_dr__SHIFT 0x6\n#define WD_DEBUG_REG4__pipe1_rtr_MASK 0x80\n#define WD_DEBUG_REG4__pipe1_rtr__SHIFT 0x7\n#define WD_DEBUG_REG4__pipe2_dr_MASK 0x100\n#define WD_DEBUG_REG4__pipe2_dr__SHIFT 0x8\n#define WD_DEBUG_REG4__pipe2_rtr_MASK 0x200\n#define WD_DEBUG_REG4__pipe2_rtr__SHIFT 0x9\n#define WD_DEBUG_REG4__pipe3_ld_MASK 0x400\n#define WD_DEBUG_REG4__pipe3_ld__SHIFT 0xa\n#define WD_DEBUG_REG4__pipe3_rtr_MASK 0x800\n#define WD_DEBUG_REG4__pipe3_rtr__SHIFT 0xb\n#define WD_DEBUG_REG4__WD_IA_draw_send_d_MASK 0x1000\n#define WD_DEBUG_REG4__WD_IA_draw_send_d__SHIFT 0xc\n#define WD_DEBUG_REG4__WD_IA_draw_rtr_MASK 0x2000\n#define WD_DEBUG_REG4__WD_IA_draw_rtr__SHIFT 0xd\n#define WD_DEBUG_REG4__di_type_p0_MASK 0xc000\n#define WD_DEBUG_REG4__di_type_p0__SHIFT 0xe\n#define WD_DEBUG_REG4__di_state_sel_p1_q_MASK 0x70000\n#define WD_DEBUG_REG4__di_state_sel_p1_q__SHIFT 0x10\n#define WD_DEBUG_REG4__di_wd_switch_on_eop_p1_q_MASK 0x80000\n#define WD_DEBUG_REG4__di_wd_switch_on_eop_p1_q__SHIFT 0x13\n#define WD_DEBUG_REG4__rbiu_spl_pipe0_lockout_MASK 0x100000\n#define WD_DEBUG_REG4__rbiu_spl_pipe0_lockout__SHIFT 0x14\n#define WD_DEBUG_REG4__last_inst_of_di_p2_MASK 0x200000\n#define WD_DEBUG_REG4__last_inst_of_di_p2__SHIFT 0x15\n#define WD_DEBUG_REG4__last_sd_of_inst_p2_MASK 0x400000\n#define WD_DEBUG_REG4__last_sd_of_inst_p2__SHIFT 0x16\n#define WD_DEBUG_REG4__last_sd_of_di_p2_MASK 0x800000\n#define WD_DEBUG_REG4__last_sd_of_di_p2__SHIFT 0x17\n#define WD_DEBUG_REG4__not_eop_wait_p1_q_MASK 0x1000000\n#define WD_DEBUG_REG4__not_eop_wait_p1_q__SHIFT 0x18\n#define WD_DEBUG_REG4__not_eop_wait_q_MASK 0x2000000\n#define WD_DEBUG_REG4__not_eop_wait_q__SHIFT 0x19\n#define WD_DEBUG_REG4__ext_event_wait_p1_q_MASK 0x4000000\n#define WD_DEBUG_REG4__ext_event_wait_p1_q__SHIFT 0x1a\n#define WD_DEBUG_REG4__ext_event_wait_q_MASK 0x8000000\n#define WD_DEBUG_REG4__ext_event_wait_q__SHIFT 0x1b\n#define WD_DEBUG_REG4__WD_IA1_draw_send_d_MASK 0x10000000\n#define WD_DEBUG_REG4__WD_IA1_draw_send_d__SHIFT 0x1c\n#define WD_DEBUG_REG4__WD_IA1_draw_rtr_MASK 0x20000000\n#define WD_DEBUG_REG4__WD_IA1_draw_rtr__SHIFT 0x1d\n#define WD_DEBUG_REG4__send_to_ia1_q_MASK 0x40000000\n#define WD_DEBUG_REG4__send_to_ia1_q__SHIFT 0x1e\n#define WD_DEBUG_REG4__dual_ia_mode_MASK 0x80000000\n#define WD_DEBUG_REG4__dual_ia_mode__SHIFT 0x1f\n#define WD_DEBUG_REG5__p1_rbiu_spl_dr_valid_MASK 0x1\n#define WD_DEBUG_REG5__p1_rbiu_spl_dr_valid__SHIFT 0x0\n#define WD_DEBUG_REG5__SPARE0_MASK 0x2\n#define WD_DEBUG_REG5__SPARE0__SHIFT 0x1\n#define WD_DEBUG_REG5__p1_pipe0_dr_MASK 0x4\n#define WD_DEBUG_REG5__p1_pipe0_dr__SHIFT 0x2\n#define WD_DEBUG_REG5__p1_pipe0_rtr_MASK 0x8\n#define WD_DEBUG_REG5__p1_pipe0_rtr__SHIFT 0x3\n#define WD_DEBUG_REG5__p1_pipe1_dr_MASK 0x10\n#define WD_DEBUG_REG5__p1_pipe1_dr__SHIFT 0x4\n#define WD_DEBUG_REG5__p1_pipe1_rtr_MASK 0x20\n#define WD_DEBUG_REG5__p1_pipe1_rtr__SHIFT 0x5\n#define WD_DEBUG_REG5__p1_wd_subdma_fifo_empty_MASK 0x40\n#define WD_DEBUG_REG5__p1_wd_subdma_fifo_empty__SHIFT 0x6\n#define WD_DEBUG_REG5__p1_wd_subdma_fifo_full_MASK 0x80\n#define WD_DEBUG_REG5__p1_wd_subdma_fifo_full__SHIFT 0x7\n#define WD_DEBUG_REG5__p1_dma_buf_type_p0_q_MASK 0x300\n#define WD_DEBUG_REG5__p1_dma_buf_type_p0_q__SHIFT 0x8\n#define WD_DEBUG_REG5__p1_dma_zero_indices_p0_q_MASK 0x400\n#define WD_DEBUG_REG5__p1_dma_zero_indices_p0_q__SHIFT 0xa\n#define WD_DEBUG_REG5__p1_dma_req_path_p3_q_MASK 0x800\n#define WD_DEBUG_REG5__p1_dma_req_path_p3_q__SHIFT 0xb\n#define WD_DEBUG_REG5__p1_dma_not_eop_p1_q_MASK 0x1000\n#define WD_DEBUG_REG5__p1_dma_not_eop_p1_q__SHIFT 0xc\n#define WD_DEBUG_REG5__p1_out_of_range_p4_MASK 0x2000\n#define WD_DEBUG_REG5__p1_out_of_range_p4__SHIFT 0xd\n#define WD_DEBUG_REG5__p1_last_sub_dma_p3_q_MASK 0x4000\n#define WD_DEBUG_REG5__p1_last_sub_dma_p3_q__SHIFT 0xe\n#define WD_DEBUG_REG5__p1_last_rdreq_of_sub_dma_p4_MASK 0x8000\n#define WD_DEBUG_REG5__p1_last_rdreq_of_sub_dma_p4__SHIFT 0xf\n#define WD_DEBUG_REG5__p1_WD_IA_dma_send_d_MASK 0x10000\n#define WD_DEBUG_REG5__p1_WD_IA_dma_send_d__SHIFT 0x10\n#define WD_DEBUG_REG5__p1_WD_IA_dma_rtr_MASK 0x20000\n#define WD_DEBUG_REG5__p1_WD_IA_dma_rtr__SHIFT 0x11\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_send_d_MASK 0x40000\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_send_d__SHIFT 0x12\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_rtr_MASK 0x80000\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_rtr__SHIFT 0x13\n#define WD_DEBUG_REG5__p1_last_inst_of_dma_p2_MASK 0x100000\n#define WD_DEBUG_REG5__p1_last_inst_of_dma_p2__SHIFT 0x14\n#define WD_DEBUG_REG5__p1_last_sd_of_inst_p2_MASK 0x200000\n#define WD_DEBUG_REG5__p1_last_sd_of_inst_p2__SHIFT 0x15\n#define WD_DEBUG_REG5__p1_last_sd_of_dma_p2_MASK 0x400000\n#define WD_DEBUG_REG5__p1_last_sd_of_dma_p2__SHIFT 0x16\n#define WD_DEBUG_REG5__SPARE1_MASK 0x800000\n#define WD_DEBUG_REG5__SPARE1__SHIFT 0x17\n#define WD_DEBUG_REG5__p1_WD_IA_dma_busy_MASK 0x1000000\n#define WD_DEBUG_REG5__p1_WD_IA_dma_busy__SHIFT 0x18\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_busy_MASK 0x2000000\n#define WD_DEBUG_REG5__p1_WD_IA1_dma_busy__SHIFT 0x19\n#define WD_DEBUG_REG5__p1_send_to_ia1_p3_q_MASK 0x4000000\n#define WD_DEBUG_REG5__p1_send_to_ia1_p3_q__SHIFT 0x1a\n#define WD_DEBUG_REG5__p1_dma_wd_switch_on_eop_p3_q_MASK 0x8000000\n#define WD_DEBUG_REG5__p1_dma_wd_switch_on_eop_p3_q__SHIFT 0x1b\n#define WD_DEBUG_REG5__p1_pipe3_dr_MASK 0x10000000\n#define WD_DEBUG_REG5__p1_pipe3_dr__SHIFT 0x1c\n#define WD_DEBUG_REG5__p1_pipe3_rtr_MASK 0x20000000\n#define WD_DEBUG_REG5__p1_pipe3_rtr__SHIFT 0x1d\n#define WD_DEBUG_REG5__p1_wd_dma2draw_fifo_empty_MASK 0x40000000\n#define WD_DEBUG_REG5__p1_wd_dma2draw_fifo_empty__SHIFT 0x1e\n#define WD_DEBUG_REG5__p1_wd_dma2draw_fifo_full_MASK 0x80000000\n#define WD_DEBUG_REG5__p1_wd_dma2draw_fifo_full__SHIFT 0x1f\n#define IA_DEBUG_REG0__ia_busy_extended_MASK 0x1\n#define IA_DEBUG_REG0__ia_busy_extended__SHIFT 0x0\n#define IA_DEBUG_REG0__ia_nodma_busy_extended_MASK 0x2\n#define IA_DEBUG_REG0__ia_nodma_busy_extended__SHIFT 0x1\n#define IA_DEBUG_REG0__ia_busy_MASK 0x4\n#define IA_DEBUG_REG0__ia_busy__SHIFT 0x2\n#define IA_DEBUG_REG0__ia_nodma_busy_MASK 0x8\n#define IA_DEBUG_REG0__ia_nodma_busy__SHIFT 0x3\n#define IA_DEBUG_REG0__SPARE0_MASK 0x10\n#define IA_DEBUG_REG0__SPARE0__SHIFT 0x4\n#define IA_DEBUG_REG0__dma_req_busy_MASK 0x20\n#define IA_DEBUG_REG0__dma_req_busy__SHIFT 0x5\n#define IA_DEBUG_REG0__dma_busy_MASK 0x40\n#define IA_DEBUG_REG0__dma_busy__SHIFT 0x6\n#define IA_DEBUG_REG0__mc_xl8r_busy_MASK 0x80\n#define IA_DEBUG_REG0__mc_xl8r_busy__SHIFT 0x7\n#define IA_DEBUG_REG0__grp_busy_MASK 0x100\n#define IA_DEBUG_REG0__grp_busy__SHIFT 0x8\n#define IA_DEBUG_REG0__SPARE1_MASK 0x200\n#define IA_DEBUG_REG0__SPARE1__SHIFT 0x9\n#define IA_DEBUG_REG0__dma_grp_valid_MASK 0x400\n#define IA_DEBUG_REG0__dma_grp_valid__SHIFT 0xa\n#define IA_DEBUG_REG0__grp_dma_read_MASK 0x800\n#define IA_DEBUG_REG0__grp_dma_read__SHIFT 0xb\n#define IA_DEBUG_REG0__dma_grp_hp_valid_MASK 0x1000\n#define IA_DEBUG_REG0__dma_grp_hp_valid__SHIFT 0xc\n#define IA_DEBUG_REG0__grp_dma_hp_read_MASK 0x2000\n#define IA_DEBUG_REG0__grp_dma_hp_read__SHIFT 0xd\n#define IA_DEBUG_REG0__SPARE2_MASK 0xffc000\n#define IA_DEBUG_REG0__SPARE2__SHIFT 0xe\n#define IA_DEBUG_REG0__reg_clk_busy_MASK 0x1000000\n#define IA_DEBUG_REG0__reg_clk_busy__SHIFT 0x18\n#define IA_DEBUG_REG0__core_clk_busy_MASK 0x2000000\n#define IA_DEBUG_REG0__core_clk_busy__SHIFT 0x19\n#define IA_DEBUG_REG0__SPARE3_MASK 0x4000000\n#define IA_DEBUG_REG0__SPARE3__SHIFT 0x1a\n#define IA_DEBUG_REG0__SPARE4_MASK 0x8000000\n#define IA_DEBUG_REG0__SPARE4__SHIFT 0x1b\n#define IA_DEBUG_REG0__sclk_reg_vld_MASK 0x10000000\n#define IA_DEBUG_REG0__sclk_reg_vld__SHIFT 0x1c\n#define IA_DEBUG_REG0__sclk_core_vld_MASK 0x20000000\n#define IA_DEBUG_REG0__sclk_core_vld__SHIFT 0x1d\n#define IA_DEBUG_REG0__SPARE5_MASK 0x40000000\n#define IA_DEBUG_REG0__SPARE5__SHIFT 0x1e\n#define IA_DEBUG_REG0__SPARE6_MASK 0x80000000\n#define IA_DEBUG_REG0__SPARE6__SHIFT 0x1f\n#define IA_DEBUG_REG1__dma_input_fifo_empty_MASK 0x1\n#define IA_DEBUG_REG1__dma_input_fifo_empty__SHIFT 0x0\n#define IA_DEBUG_REG1__dma_input_fifo_full_MASK 0x2\n#define IA_DEBUG_REG1__dma_input_fifo_full__SHIFT 0x1\n#define IA_DEBUG_REG1__start_new_packet_MASK 0x4\n#define IA_DEBUG_REG1__start_new_packet__SHIFT 0x2\n#define IA_DEBUG_REG1__dma_rdreq_dr_q_MASK 0x8\n#define IA_DEBUG_REG1__dma_rdreq_dr_q__SHIFT 0x3\n#define IA_DEBUG_REG1__dma_zero_indices_q_MASK 0x10\n#define IA_DEBUG_REG1__dma_zero_indices_q__SHIFT 0x4\n#define IA_DEBUG_REG1__dma_buf_type_q_MASK 0x60\n#define IA_DEBUG_REG1__dma_buf_type_q__SHIFT 0x5\n#define IA_DEBUG_REG1__dma_req_path_q_MASK 0x80\n#define IA_DEBUG_REG1__dma_req_path_q__SHIFT 0x7\n#define IA_DEBUG_REG1__discard_1st_chunk_MASK 0x100\n#define IA_DEBUG_REG1__discard_1st_chunk__SHIFT 0x8\n#define IA_DEBUG_REG1__discard_2nd_chunk_MASK 0x200\n#define IA_DEBUG_REG1__discard_2nd_chunk__SHIFT 0x9\n#define IA_DEBUG_REG1__second_tc_ret_data_q_MASK 0x400\n#define IA_DEBUG_REG1__second_tc_ret_data_q__SHIFT 0xa\n#define IA_DEBUG_REG1__dma_tc_ret_sel_q_MASK 0x800\n#define IA_DEBUG_REG1__dma_tc_ret_sel_q__SHIFT 0xb\n#define IA_DEBUG_REG1__last_rdreq_in_dma_op_MASK 0x1000\n#define IA_DEBUG_REG1__last_rdreq_in_dma_op__SHIFT 0xc\n#define IA_DEBUG_REG1__dma_mask_fifo_empty_MASK 0x2000\n#define IA_DEBUG_REG1__dma_mask_fifo_empty__SHIFT 0xd\n#define IA_DEBUG_REG1__dma_data_fifo_empty_q_MASK 0x4000\n#define IA_DEBUG_REG1__dma_data_fifo_empty_q__SHIFT 0xe\n#define IA_DEBUG_REG1__dma_data_fifo_full_MASK 0x8000\n#define IA_DEBUG_REG1__dma_data_fifo_full__SHIFT 0xf\n#define IA_DEBUG_REG1__dma_req_fifo_empty_MASK 0x10000\n#define IA_DEBUG_REG1__dma_req_fifo_empty__SHIFT 0x10\n#define IA_DEBUG_REG1__dma_req_fifo_full_MASK 0x20000\n#define IA_DEBUG_REG1__dma_req_fifo_full__SHIFT 0x11\n#define IA_DEBUG_REG1__stage2_dr_MASK 0x40000\n#define IA_DEBUG_REG1__stage2_dr__SHIFT 0x12\n#define IA_DEBUG_REG1__stage2_rtr_MASK 0x80000\n#define IA_DEBUG_REG1__stage2_rtr__SHIFT 0x13\n#define IA_DEBUG_REG1__stage3_dr_MASK 0x100000\n#define IA_DEBUG_REG1__stage3_dr__SHIFT 0x14\n#define IA_DEBUG_REG1__stage3_rtr_MASK 0x200000\n#define IA_DEBUG_REG1__stage3_rtr__SHIFT 0x15\n#define IA_DEBUG_REG1__stage4_dr_MASK 0x400000\n#define IA_DEBUG_REG1__stage4_dr__SHIFT 0x16\n#define IA_DEBUG_REG1__stage4_rtr_MASK 0x800000\n#define IA_DEBUG_REG1__stage4_rtr__SHIFT 0x17\n#define IA_DEBUG_REG1__dma_skid_fifo_empty_MASK 0x1000000\n#define IA_DEBUG_REG1__dma_skid_fifo_empty__SHIFT 0x18\n#define IA_DEBUG_REG1__dma_skid_fifo_full_MASK 0x2000000\n#define IA_DEBUG_REG1__dma_skid_fifo_full__SHIFT 0x19\n#define IA_DEBUG_REG1__dma_grp_valid_MASK 0x4000000\n#define IA_DEBUG_REG1__dma_grp_valid__SHIFT 0x1a\n#define IA_DEBUG_REG1__grp_dma_read_MASK 0x8000000\n#define IA_DEBUG_REG1__grp_dma_read__SHIFT 0x1b\n#define IA_DEBUG_REG1__current_data_valid_MASK 0x10000000\n#define IA_DEBUG_REG1__current_data_valid__SHIFT 0x1c\n#define IA_DEBUG_REG1__out_of_range_r2_q_MASK 0x20000000\n#define IA_DEBUG_REG1__out_of_range_r2_q__SHIFT 0x1d\n#define IA_DEBUG_REG1__dma_mask_fifo_we_MASK 0x40000000\n#define IA_DEBUG_REG1__dma_mask_fifo_we__SHIFT 0x1e\n#define IA_DEBUG_REG1__dma_ret_data_we_q_MASK 0x80000000\n#define IA_DEBUG_REG1__dma_ret_data_we_q__SHIFT 0x1f\n#define IA_DEBUG_REG2__hp_dma_input_fifo_empty_MASK 0x1\n#define IA_DEBUG_REG2__hp_dma_input_fifo_empty__SHIFT 0x0\n#define IA_DEBUG_REG2__hp_dma_input_fifo_full_MASK 0x2\n#define IA_DEBUG_REG2__hp_dma_input_fifo_full__SHIFT 0x1\n#define IA_DEBUG_REG2__hp_start_new_packet_MASK 0x4\n#define IA_DEBUG_REG2__hp_start_new_packet__SHIFT 0x2\n#define IA_DEBUG_REG2__hp_dma_rdreq_dr_q_MASK 0x8\n#define IA_DEBUG_REG2__hp_dma_rdreq_dr_q__SHIFT 0x3\n#define IA_DEBUG_REG2__hp_dma_zero_indices_q_MASK 0x10\n#define IA_DEBUG_REG2__hp_dma_zero_indices_q__SHIFT 0x4\n#define IA_DEBUG_REG2__hp_dma_buf_type_q_MASK 0x60\n#define IA_DEBUG_REG2__hp_dma_buf_type_q__SHIFT 0x5\n#define IA_DEBUG_REG2__hp_dma_req_path_q_MASK 0x80\n#define IA_DEBUG_REG2__hp_dma_req_path_q__SHIFT 0x7\n#define IA_DEBUG_REG2__hp_discard_1st_chunk_MASK 0x100\n#define IA_DEBUG_REG2__hp_discard_1st_chunk__SHIFT 0x8\n#define IA_DEBUG_REG2__hp_discard_2nd_chunk_MASK 0x200\n#define IA_DEBUG_REG2__hp_discard_2nd_chunk__SHIFT 0x9\n#define IA_DEBUG_REG2__hp_second_tc_ret_data_q_MASK 0x400\n#define IA_DEBUG_REG2__hp_second_tc_ret_data_q__SHIFT 0xa\n#define IA_DEBUG_REG2__hp_dma_tc_ret_sel_q_MASK 0x800\n#define IA_DEBUG_REG2__hp_dma_tc_ret_sel_q__SHIFT 0xb\n#define IA_DEBUG_REG2__hp_last_rdreq_in_dma_op_MASK 0x1000\n#define IA_DEBUG_REG2__hp_last_rdreq_in_dma_op__SHIFT 0xc\n#define IA_DEBUG_REG2__hp_dma_mask_fifo_empty_MASK 0x2000\n#define IA_DEBUG_REG2__hp_dma_mask_fifo_empty__SHIFT 0xd\n#define IA_DEBUG_REG2__hp_dma_data_fifo_empty_q_MASK 0x4000\n#define IA_DEBUG_REG2__hp_dma_data_fifo_empty_q__SHIFT 0xe\n#define IA_DEBUG_REG2__hp_dma_data_fifo_full_MASK 0x8000\n#define IA_DEBUG_REG2__hp_dma_data_fifo_full__SHIFT 0xf\n#define IA_DEBUG_REG2__hp_dma_req_fifo_empty_MASK 0x10000\n#define IA_DEBUG_REG2__hp_dma_req_fifo_empty__SHIFT 0x10\n#define IA_DEBUG_REG2__hp_dma_req_fifo_full_MASK 0x20000\n#define IA_DEBUG_REG2__hp_dma_req_fifo_full__SHIFT 0x11\n#define IA_DEBUG_REG2__hp_stage2_dr_MASK 0x40000\n#define IA_DEBUG_REG2__hp_stage2_dr__SHIFT 0x12\n#define IA_DEBUG_REG2__hp_stage2_rtr_MASK 0x80000\n#define IA_DEBUG_REG2__hp_stage2_rtr__SHIFT 0x13\n#define IA_DEBUG_REG2__hp_stage3_dr_MASK 0x100000\n#define IA_DEBUG_REG2__hp_stage3_dr__SHIFT 0x14\n#define IA_DEBUG_REG2__hp_stage3_rtr_MASK 0x200000\n#define IA_DEBUG_REG2__hp_stage3_rtr__SHIFT 0x15\n#define IA_DEBUG_REG2__hp_stage4_dr_MASK 0x400000\n#define IA_DEBUG_REG2__hp_stage4_dr__SHIFT 0x16\n#define IA_DEBUG_REG2__hp_stage4_rtr_MASK 0x800000\n#define IA_DEBUG_REG2__hp_stage4_rtr__SHIFT 0x17\n#define IA_DEBUG_REG2__hp_dma_skid_fifo_empty_MASK 0x1000000\n#define IA_DEBUG_REG2__hp_dma_skid_fifo_empty__SHIFT 0x18\n#define IA_DEBUG_REG2__hp_dma_skid_fifo_full_MASK 0x2000000\n#define IA_DEBUG_REG2__hp_dma_skid_fifo_full__SHIFT 0x19\n#define IA_DEBUG_REG2__hp_dma_grp_valid_MASK 0x4000000\n#define IA_DEBUG_REG2__hp_dma_grp_valid__SHIFT 0x1a\n#define IA_DEBUG_REG2__hp_grp_dma_read_MASK 0x8000000\n#define IA_DEBUG_REG2__hp_grp_dma_read__SHIFT 0x1b\n#define IA_DEBUG_REG2__hp_current_data_valid_MASK 0x10000000\n#define IA_DEBUG_REG2__hp_current_data_valid__SHIFT 0x1c\n#define IA_DEBUG_REG2__hp_out_of_range_r2_q_MASK 0x20000000\n#define IA_DEBUG_REG2__hp_out_of_range_r2_q__SHIFT 0x1d\n#define IA_DEBUG_REG2__hp_dma_mask_fifo_we_MASK 0x40000000\n#define IA_DEBUG_REG2__hp_dma_mask_fifo_we__SHIFT 0x1e\n#define IA_DEBUG_REG2__hp_dma_ret_data_we_q_MASK 0x80000000\n#define IA_DEBUG_REG2__hp_dma_ret_data_we_q__SHIFT 0x1f\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_valid_MASK 0x1\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_valid__SHIFT 0x0\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_read_MASK 0x2\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_read__SHIFT 0x1\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_null_out_MASK 0x4\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_null_out__SHIFT 0x2\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_eop_out_MASK 0x8\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_eop_out__SHIFT 0x3\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_use_tc_out_MASK 0x10\n#define IA_DEBUG_REG3__dma_pipe0_rdreq_use_tc_out__SHIFT 0x4\n#define IA_DEBUG_REG3__grp_dma_draw_is_pipe0_MASK 0x20\n#define IA_DEBUG_REG3__grp_dma_draw_is_pipe0__SHIFT 0x5\n#define IA_DEBUG_REG3__must_service_pipe0_req_MASK 0x40\n#define IA_DEBUG_REG3__must_service_pipe0_req__SHIFT 0x6\n#define IA_DEBUG_REG3__send_pipe1_req_MASK 0x80\n#define IA_DEBUG_REG3__send_pipe1_req__SHIFT 0x7\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_valid_MASK 0x100\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_valid__SHIFT 0x8\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_read_MASK 0x200\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_read__SHIFT 0x9\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_null_out_MASK 0x400\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_null_out__SHIFT 0xa\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_eop_out_MASK 0x800\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_eop_out__SHIFT 0xb\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_use_tc_out_MASK 0x1000\n#define IA_DEBUG_REG3__dma_pipe1_rdreq_use_tc_out__SHIFT 0xc\n#define IA_DEBUG_REG3__ia_mc_rdreq_rtr_q_MASK 0x2000\n#define IA_DEBUG_REG3__ia_mc_rdreq_rtr_q__SHIFT 0xd\n#define IA_DEBUG_REG3__mc_out_rtr_MASK 0x4000\n#define IA_DEBUG_REG3__mc_out_rtr__SHIFT 0xe\n#define IA_DEBUG_REG3__dma_rdreq_send_out_MASK 0x8000\n#define IA_DEBUG_REG3__dma_rdreq_send_out__SHIFT 0xf\n#define IA_DEBUG_REG3__pipe0_dr_MASK 0x10000\n#define IA_DEBUG_REG3__pipe0_dr__SHIFT 0x10\n#define IA_DEBUG_REG3__pipe0_rtr_MASK 0x20000\n#define IA_DEBUG_REG3__pipe0_rtr__SHIFT 0x11\n#define IA_DEBUG_REG3__ia_tc_rdreq_rtr_q_MASK 0x40000\n#define IA_DEBUG_REG3__ia_tc_rdreq_rtr_q__SHIFT 0x12\n#define IA_DEBUG_REG3__tc_out_rtr_MASK 0x80000\n#define IA_DEBUG_REG3__tc_out_rtr__SHIFT 0x13\n#define IA_DEBUG_REG3__pair0_valid_p1_MASK 0x100000\n#define IA_DEBUG_REG3__pair0_valid_p1__SHIFT 0x14\n#define IA_DEBUG_REG3__pair1_valid_p1_MASK 0x200000\n#define IA_DEBUG_REG3__pair1_valid_p1__SHIFT 0x15\n#define IA_DEBUG_REG3__pair2_valid_p1_MASK 0x400000\n#define IA_DEBUG_REG3__pair2_valid_p1__SHIFT 0x16\n#define IA_DEBUG_REG3__pair3_valid_p1_MASK 0x800000\n#define IA_DEBUG_REG3__pair3_valid_p1__SHIFT 0x17\n#define IA_DEBUG_REG3__tc_req_count_q_MASK 0x3000000\n#define IA_DEBUG_REG3__tc_req_count_q__SHIFT 0x18\n#define IA_DEBUG_REG3__discard_1st_chunk_MASK 0x4000000\n#define IA_DEBUG_REG3__discard_1st_chunk__SHIFT 0x1a\n#define IA_DEBUG_REG3__discard_2nd_chunk_MASK 0x8000000\n#define IA_DEBUG_REG3__discard_2nd_chunk__SHIFT 0x1b\n#define IA_DEBUG_REG3__last_tc_req_p1_MASK 0x10000000\n#define IA_DEBUG_REG3__last_tc_req_p1__SHIFT 0x1c\n#define IA_DEBUG_REG3__IA_TC_rdreq_send_out_MASK 0x20000000\n#define IA_DEBUG_REG3__IA_TC_rdreq_send_out__SHIFT 0x1d\n#define IA_DEBUG_REG3__TC_IA_rdret_valid_in_MASK 0x40000000\n#define IA_DEBUG_REG3__TC_IA_rdret_valid_in__SHIFT 0x1e\n#define IA_DEBUG_REG3__TAP_IA_rdret_vld_in_MASK 0x80000000\n#define IA_DEBUG_REG3__TAP_IA_rdret_vld_in__SHIFT 0x1f\n#define IA_DEBUG_REG4__pipe0_dr_MASK 0x1\n#define IA_DEBUG_REG4__pipe0_dr__SHIFT 0x0\n#define IA_DEBUG_REG4__pipe1_dr_MASK 0x2\n#define IA_DEBUG_REG4__pipe1_dr__SHIFT 0x1\n#define IA_DEBUG_REG4__pipe2_dr_MASK 0x4\n#define IA_DEBUG_REG4__pipe2_dr__SHIFT 0x2\n#define IA_DEBUG_REG4__pipe3_dr_MASK 0x8\n#define IA_DEBUG_REG4__pipe3_dr__SHIFT 0x3\n#define IA_DEBUG_REG4__pipe4_dr_MASK 0x10\n#define IA_DEBUG_REG4__pipe4_dr__SHIFT 0x4\n#define IA_DEBUG_REG4__pipe5_dr_MASK 0x20\n#define IA_DEBUG_REG4__pipe5_dr__SHIFT 0x5\n#define IA_DEBUG_REG4__grp_se0_fifo_empty_MASK 0x40\n#define IA_DEBUG_REG4__grp_se0_fifo_empty__SHIFT 0x6\n#define IA_DEBUG_REG4__grp_se0_fifo_full_MASK 0x80\n#define IA_DEBUG_REG4__grp_se0_fifo_full__SHIFT 0x7\n#define IA_DEBUG_REG4__pipe0_rtr_MASK 0x100\n#define IA_DEBUG_REG4__pipe0_rtr__SHIFT 0x8\n#define IA_DEBUG_REG4__pipe1_rtr_MASK 0x200\n#define IA_DEBUG_REG4__pipe1_rtr__SHIFT 0x9\n#define IA_DEBUG_REG4__pipe2_rtr_MASK 0x400\n#define IA_DEBUG_REG4__pipe2_rtr__SHIFT 0xa\n#define IA_DEBUG_REG4__pipe3_rtr_MASK 0x800\n#define IA_DEBUG_REG4__pipe3_rtr__SHIFT 0xb\n#define IA_DEBUG_REG4__pipe4_rtr_MASK 0x1000\n#define IA_DEBUG_REG4__pipe4_rtr__SHIFT 0xc\n#define IA_DEBUG_REG4__pipe5_rtr_MASK 0x2000\n#define IA_DEBUG_REG4__pipe5_rtr__SHIFT 0xd\n#define IA_DEBUG_REG4__ia_vgt_prim_rtr_q_MASK 0x4000\n#define IA_DEBUG_REG4__ia_vgt_prim_rtr_q__SHIFT 0xe\n#define IA_DEBUG_REG4__ia_se1vgt_prim_rtr_q_MASK 0x8000\n#define IA_DEBUG_REG4__ia_se1vgt_prim_rtr_q__SHIFT 0xf\n#define IA_DEBUG_REG4__di_major_mode_p1_q_MASK 0x10000\n#define IA_DEBUG_REG4__di_major_mode_p1_q__SHIFT 0x10\n#define IA_DEBUG_REG4__gs_mode_p1_q_MASK 0xe0000\n#define IA_DEBUG_REG4__gs_mode_p1_q__SHIFT 0x11\n#define IA_DEBUG_REG4__di_event_flag_p1_q_MASK 0x100000\n#define IA_DEBUG_REG4__di_event_flag_p1_q__SHIFT 0x14\n#define IA_DEBUG_REG4__di_state_sel_p1_q_MASK 0xe00000\n#define IA_DEBUG_REG4__di_state_sel_p1_q__SHIFT 0x15\n#define IA_DEBUG_REG4__draw_opaq_en_p1_q_MASK 0x1000000\n#define IA_DEBUG_REG4__draw_opaq_en_p1_q__SHIFT 0x18\n#define IA_DEBUG_REG4__draw_opaq_active_q_MASK 0x2000000\n#define IA_DEBUG_REG4__draw_opaq_active_q__SHIFT 0x19\n#define IA_DEBUG_REG4__di_source_select_p1_q_MASK 0xc000000\n#define IA_DEBUG_REG4__di_source_select_p1_q__SHIFT 0x1a\n#define IA_DEBUG_REG4__ready_to_read_di_MASK 0x10000000\n#define IA_DEBUG_REG4__ready_to_read_di__SHIFT 0x1c\n#define IA_DEBUG_REG4__di_first_group_of_draw_q_MASK 0x20000000\n#define IA_DEBUG_REG4__di_first_group_of_draw_q__SHIFT 0x1d\n#define IA_DEBUG_REG4__last_shift_of_draw_MASK 0x40000000\n#define IA_DEBUG_REG4__last_shift_of_draw__SHIFT 0x1e\n#define IA_DEBUG_REG4__current_shift_is_vect1_q_MASK 0x80000000\n#define IA_DEBUG_REG4__current_shift_is_vect1_q__SHIFT 0x1f\n#define IA_DEBUG_REG5__di_index_counter_q_15_0_MASK 0xffff\n#define IA_DEBUG_REG5__di_index_counter_q_15_0__SHIFT 0x0\n#define IA_DEBUG_REG5__instanceid_13_0_MASK 0x3fff0000\n#define IA_DEBUG_REG5__instanceid_13_0__SHIFT 0x10\n#define IA_DEBUG_REG5__draw_input_fifo_full_MASK 0x40000000\n#define IA_DEBUG_REG5__draw_input_fifo_full__SHIFT 0x1e\n#define IA_DEBUG_REG5__draw_input_fifo_empty_MASK 0x80000000\n#define IA_DEBUG_REG5__draw_input_fifo_empty__SHIFT 0x1f\n#define IA_DEBUG_REG6__current_shift_q_MASK 0xf\n#define IA_DEBUG_REG6__current_shift_q__SHIFT 0x0\n#define IA_DEBUG_REG6__current_stride_pre_MASK 0xf0\n#define IA_DEBUG_REG6__current_stride_pre__SHIFT 0x4\n#define IA_DEBUG_REG6__current_stride_q_MASK 0x1f00\n#define IA_DEBUG_REG6__current_stride_q__SHIFT 0x8\n#define IA_DEBUG_REG6__first_group_partial_MASK 0x2000\n#define IA_DEBUG_REG6__first_group_partial__SHIFT 0xd\n#define IA_DEBUG_REG6__second_group_partial_MASK 0x4000\n#define IA_DEBUG_REG6__second_group_partial__SHIFT 0xe\n#define IA_DEBUG_REG6__curr_prim_partial_MASK 0x8000\n#define IA_DEBUG_REG6__curr_prim_partial__SHIFT 0xf\n#define IA_DEBUG_REG6__next_stride_q_MASK 0x1f0000\n#define IA_DEBUG_REG6__next_stride_q__SHIFT 0x10\n#define IA_DEBUG_REG6__next_group_partial_MASK 0x200000\n#define IA_DEBUG_REG6__next_group_partial__SHIFT 0x15\n#define IA_DEBUG_REG6__after_group_partial_MASK 0x400000\n#define IA_DEBUG_REG6__after_group_partial__SHIFT 0x16\n#define IA_DEBUG_REG6__extract_group_MASK 0x800000\n#define IA_DEBUG_REG6__extract_group__SHIFT 0x17\n#define IA_DEBUG_REG6__grp_shift_debug_data_MASK 0xff000000\n#define IA_DEBUG_REG6__grp_shift_debug_data__SHIFT 0x18\n#define IA_DEBUG_REG7__reset_indx_state_q_MASK 0xf\n#define IA_DEBUG_REG7__reset_indx_state_q__SHIFT 0x0\n#define IA_DEBUG_REG7__shift_vect_valid_p2_q_MASK 0xf0\n#define IA_DEBUG_REG7__shift_vect_valid_p2_q__SHIFT 0x4\n#define IA_DEBUG_REG7__shift_vect1_valid_p2_q_MASK 0xf00\n#define IA_DEBUG_REG7__shift_vect1_valid_p2_q__SHIFT 0x8\n#define IA_DEBUG_REG7__shift_vect0_reset_match_p2_q_MASK 0xf000\n#define IA_DEBUG_REG7__shift_vect0_reset_match_p2_q__SHIFT 0xc\n#define IA_DEBUG_REG7__shift_vect1_reset_match_p2_q_MASK 0xf0000\n#define IA_DEBUG_REG7__shift_vect1_reset_match_p2_q__SHIFT 0x10\n#define IA_DEBUG_REG7__num_indx_in_group_p2_q_MASK 0x700000\n#define IA_DEBUG_REG7__num_indx_in_group_p2_q__SHIFT 0x14\n#define IA_DEBUG_REG7__last_group_of_draw_p2_q_MASK 0x800000\n#define IA_DEBUG_REG7__last_group_of_draw_p2_q__SHIFT 0x17\n#define IA_DEBUG_REG7__shift_event_flag_p2_q_MASK 0x1000000\n#define IA_DEBUG_REG7__shift_event_flag_p2_q__SHIFT 0x18\n#define IA_DEBUG_REG7__indx_shift_is_one_p2_q_MASK 0x2000000\n#define IA_DEBUG_REG7__indx_shift_is_one_p2_q__SHIFT 0x19\n#define IA_DEBUG_REG7__indx_shift_is_two_p2_q_MASK 0x4000000\n#define IA_DEBUG_REG7__indx_shift_is_two_p2_q__SHIFT 0x1a\n#define IA_DEBUG_REG7__indx_stride_is_four_p2_q_MASK 0x8000000\n#define IA_DEBUG_REG7__indx_stride_is_four_p2_q__SHIFT 0x1b\n#define IA_DEBUG_REG7__shift_prim1_reset_p3_q_MASK 0x10000000\n#define IA_DEBUG_REG7__shift_prim1_reset_p3_q__SHIFT 0x1c\n#define IA_DEBUG_REG7__shift_prim1_partial_p3_q_MASK 0x20000000\n#define IA_DEBUG_REG7__shift_prim1_partial_p3_q__SHIFT 0x1d\n#define IA_DEBUG_REG7__shift_prim0_reset_p3_q_MASK 0x40000000\n#define IA_DEBUG_REG7__shift_prim0_reset_p3_q__SHIFT 0x1e\n#define IA_DEBUG_REG7__shift_prim0_partial_p3_q_MASK 0x80000000\n#define IA_DEBUG_REG7__shift_prim0_partial_p3_q__SHIFT 0x1f\n#define IA_DEBUG_REG8__di_prim_type_p1_q_MASK 0x1f\n#define IA_DEBUG_REG8__di_prim_type_p1_q__SHIFT 0x0\n#define IA_DEBUG_REG8__two_cycle_xfer_p1_q_MASK 0x20\n#define IA_DEBUG_REG8__two_cycle_xfer_p1_q__SHIFT 0x5\n#define IA_DEBUG_REG8__two_prim_input_p1_q_MASK 0x40\n#define IA_DEBUG_REG8__two_prim_input_p1_q__SHIFT 0x6\n#define IA_DEBUG_REG8__shift_vect_end_of_packet_p5_q_MASK 0x80\n#define IA_DEBUG_REG8__shift_vect_end_of_packet_p5_q__SHIFT 0x7\n#define IA_DEBUG_REG8__last_group_of_inst_p5_q_MASK 0x100\n#define IA_DEBUG_REG8__last_group_of_inst_p5_q__SHIFT 0x8\n#define IA_DEBUG_REG8__shift_prim1_null_flag_p5_q_MASK 0x200\n#define IA_DEBUG_REG8__shift_prim1_null_flag_p5_q__SHIFT 0x9\n#define IA_DEBUG_REG8__shift_prim0_null_flag_p5_q_MASK 0x400\n#define IA_DEBUG_REG8__shift_prim0_null_flag_p5_q__SHIFT 0xa\n#define IA_DEBUG_REG8__grp_continued_MASK 0x800\n#define IA_DEBUG_REG8__grp_continued__SHIFT 0xb\n#define IA_DEBUG_REG8__grp_state_sel_MASK 0x7000\n#define IA_DEBUG_REG8__grp_state_sel__SHIFT 0xc\n#define IA_DEBUG_REG8__grp_sub_prim_type_MASK 0x1f8000\n#define IA_DEBUG_REG8__grp_sub_prim_type__SHIFT 0xf\n#define IA_DEBUG_REG8__grp_output_path_MASK 0xe00000\n#define IA_DEBUG_REG8__grp_output_path__SHIFT 0x15\n#define IA_DEBUG_REG8__grp_null_primitive_MASK 0x1000000\n#define IA_DEBUG_REG8__grp_null_primitive__SHIFT 0x18\n#define IA_DEBUG_REG8__grp_eop_MASK 0x2000000\n#define IA_DEBUG_REG8__grp_eop__SHIFT 0x19\n#define IA_DEBUG_REG8__grp_eopg_MASK 0x4000000\n#define IA_DEBUG_REG8__grp_eopg__SHIFT 0x1a\n#define IA_DEBUG_REG8__grp_event_flag_MASK 0x8000000\n#define IA_DEBUG_REG8__grp_event_flag__SHIFT 0x1b\n#define IA_DEBUG_REG8__grp_components_valid_MASK 0xf0000000\n#define IA_DEBUG_REG8__grp_components_valid__SHIFT 0x1c\n#define IA_DEBUG_REG9__send_to_se1_p6_MASK 0x1\n#define IA_DEBUG_REG9__send_to_se1_p6__SHIFT 0x0\n#define IA_DEBUG_REG9__gfx_se_switch_p6_MASK 0x2\n#define IA_DEBUG_REG9__gfx_se_switch_p6__SHIFT 0x1\n#define IA_DEBUG_REG9__null_eoi_xfer_prim1_p6_MASK 0x4\n#define IA_DEBUG_REG9__null_eoi_xfer_prim1_p6__SHIFT 0x2\n#define IA_DEBUG_REG9__null_eoi_xfer_prim0_p6_MASK 0x8\n#define IA_DEBUG_REG9__null_eoi_xfer_prim0_p6__SHIFT 0x3\n#define IA_DEBUG_REG9__prim1_eoi_p6_MASK 0x10\n#define IA_DEBUG_REG9__prim1_eoi_p6__SHIFT 0x4\n#define IA_DEBUG_REG9__prim0_eoi_p6_MASK 0x20\n#define IA_DEBUG_REG9__prim0_eoi_p6__SHIFT 0x5\n#define IA_DEBUG_REG9__prim1_valid_eopg_p6_MASK 0x40\n#define IA_DEBUG_REG9__prim1_valid_eopg_p6__SHIFT 0x6\n#define IA_DEBUG_REG9__prim0_valid_eopg_p6_MASK 0x80\n#define IA_DEBUG_REG9__prim0_valid_eopg_p6__SHIFT 0x7\n#define IA_DEBUG_REG9__prim1_to_other_se_p6_MASK 0x100\n#define IA_DEBUG_REG9__prim1_to_other_se_p6__SHIFT 0x8\n#define IA_DEBUG_REG9__eopg_on_last_prim_p6_MASK 0x200\n#define IA_DEBUG_REG9__eopg_on_last_prim_p6__SHIFT 0x9\n#define IA_DEBUG_REG9__eopg_between_prims_p6_MASK 0x400\n#define IA_DEBUG_REG9__eopg_between_prims_p6__SHIFT 0xa\n#define IA_DEBUG_REG9__prim_count_eq_group_size_p6_MASK 0x800\n#define IA_DEBUG_REG9__prim_count_eq_group_size_p6__SHIFT 0xb\n#define IA_DEBUG_REG9__prim_count_gt_group_size_p6_MASK 0x1000\n#define IA_DEBUG_REG9__prim_count_gt_group_size_p6__SHIFT 0xc\n#define IA_DEBUG_REG9__two_prim_output_p5_q_MASK 0x2000\n#define IA_DEBUG_REG9__two_prim_output_p5_q__SHIFT 0xd\n#define IA_DEBUG_REG9__SPARE0_MASK 0x4000\n#define IA_DEBUG_REG9__SPARE0__SHIFT 0xe\n#define IA_DEBUG_REG9__SPARE1_MASK 0x8000\n#define IA_DEBUG_REG9__SPARE1__SHIFT 0xf\n#define IA_DEBUG_REG9__shift_vect_end_of_packet_p5_q_MASK 0x10000\n#define IA_DEBUG_REG9__shift_vect_end_of_packet_p5_q__SHIFT 0x10\n#define IA_DEBUG_REG9__prim1_xfer_p6_MASK 0x20000\n#define IA_DEBUG_REG9__prim1_xfer_p6__SHIFT 0x11\n#define IA_DEBUG_REG9__grp_se1_fifo_empty_MASK 0x40000\n#define IA_DEBUG_REG9__grp_se1_fifo_empty__SHIFT 0x12\n#define IA_DEBUG_REG9__grp_se1_fifo_full_MASK 0x80000\n#define IA_DEBUG_REG9__grp_se1_fifo_full__SHIFT 0x13\n#define IA_DEBUG_REG9__prim_counter_q_MASK 0xfff00000\n#define IA_DEBUG_REG9__prim_counter_q__SHIFT 0x14\n#define VGT_DEBUG_REG0__vgt_busy_extended_MASK 0x1\n#define VGT_DEBUG_REG0__vgt_busy_extended__SHIFT 0x0\n#define VGT_DEBUG_REG0__SPARE9_MASK 0x2\n#define VGT_DEBUG_REG0__SPARE9__SHIFT 0x1\n#define VGT_DEBUG_REG0__vgt_busy_MASK 0x4\n#define VGT_DEBUG_REG0__vgt_busy__SHIFT 0x2\n#define VGT_DEBUG_REG0__SPARE8_MASK 0x8\n#define VGT_DEBUG_REG0__SPARE8__SHIFT 0x3\n#define VGT_DEBUG_REG0__SPARE7_MASK 0x10\n#define VGT_DEBUG_REG0__SPARE7__SHIFT 0x4\n#define VGT_DEBUG_REG0__SPARE6_MASK 0x20\n#define VGT_DEBUG_REG0__SPARE6__SHIFT 0x5\n#define VGT_DEBUG_REG0__SPARE5_MASK 0x40\n#define VGT_DEBUG_REG0__SPARE5__SHIFT 0x6\n#define VGT_DEBUG_REG0__SPARE4_MASK 0x80\n#define VGT_DEBUG_REG0__SPARE4__SHIFT 0x7\n#define VGT_DEBUG_REG0__pi_busy_MASK 0x100\n#define VGT_DEBUG_REG0__pi_busy__SHIFT 0x8\n#define VGT_DEBUG_REG0__vr_pi_busy_MASK 0x200\n#define VGT_DEBUG_REG0__vr_pi_busy__SHIFT 0x9\n#define VGT_DEBUG_REG0__pt_pi_busy_MASK 0x400\n#define VGT_DEBUG_REG0__pt_pi_busy__SHIFT 0xa\n#define VGT_DEBUG_REG0__te_pi_busy_MASK 0x800\n#define VGT_DEBUG_REG0__te_pi_busy__SHIFT 0xb\n#define VGT_DEBUG_REG0__gs_busy_MASK 0x1000\n#define VGT_DEBUG_REG0__gs_busy__SHIFT 0xc\n#define VGT_DEBUG_REG0__rcm_busy_MASK 0x2000\n#define VGT_DEBUG_REG0__rcm_busy__SHIFT 0xd\n#define VGT_DEBUG_REG0__tm_busy_MASK 0x4000\n#define VGT_DEBUG_REG0__tm_busy__SHIFT 0xe\n#define VGT_DEBUG_REG0__cm_busy_MASK 0x8000\n#define VGT_DEBUG_REG0__cm_busy__SHIFT 0xf\n#define VGT_DEBUG_REG0__gog_busy_MASK 0x10000\n#define VGT_DEBUG_REG0__gog_busy__SHIFT 0x10\n#define VGT_DEBUG_REG0__frmt_busy_MASK 0x20000\n#define VGT_DEBUG_REG0__frmt_busy__SHIFT 0x11\n#define VGT_DEBUG_REG0__SPARE10_MASK 0x40000\n#define VGT_DEBUG_REG0__SPARE10__SHIFT 0x12\n#define VGT_DEBUG_REG0__te11_pi_busy_MASK 0x80000\n#define VGT_DEBUG_REG0__te11_pi_busy__SHIFT 0x13\n#define VGT_DEBUG_REG0__SPARE3_MASK 0x100000\n#define VGT_DEBUG_REG0__SPARE3__SHIFT 0x14\n#define VGT_DEBUG_REG0__combined_out_busy_MASK 0x200000\n#define VGT_DEBUG_REG0__combined_out_busy__SHIFT 0x15\n#define VGT_DEBUG_REG0__spi_vs_interfaces_busy_MASK 0x400000\n#define VGT_DEBUG_REG0__spi_vs_interfaces_busy__SHIFT 0x16\n#define VGT_DEBUG_REG0__pa_interfaces_busy_MASK 0x800000\n#define VGT_DEBUG_REG0__pa_interfaces_busy__SHIFT 0x17\n#define VGT_DEBUG_REG0__reg_clk_busy_MASK 0x1000000\n#define VGT_DEBUG_REG0__reg_clk_busy__SHIFT 0x18\n#define VGT_DEBUG_REG0__SPARE2_MASK 0x2000000\n#define VGT_DEBUG_REG0__SPARE2__SHIFT 0x19\n#define VGT_DEBUG_REG0__core_clk_busy_MASK 0x4000000\n#define VGT_DEBUG_REG0__core_clk_busy__SHIFT 0x1a\n#define VGT_DEBUG_REG0__gs_clk_busy_MASK 0x8000000\n#define VGT_DEBUG_REG0__gs_clk_busy__SHIFT 0x1b\n#define VGT_DEBUG_REG0__SPARE1_MASK 0x10000000\n#define VGT_DEBUG_REG0__SPARE1__SHIFT 0x1c\n#define VGT_DEBUG_REG0__sclk_core_vld_MASK 0x20000000\n#define VGT_DEBUG_REG0__sclk_core_vld__SHIFT 0x1d\n#define VGT_DEBUG_REG0__sclk_gs_vld_MASK 0x40000000\n#define VGT_DEBUG_REG0__sclk_gs_vld__SHIFT 0x1e\n#define VGT_DEBUG_REG0__SPARE0_MASK 0x80000000\n#define VGT_DEBUG_REG0__SPARE0__SHIFT 0x1f\n#define VGT_DEBUG_REG1__SPARE9_MASK 0x1\n#define VGT_DEBUG_REG1__SPARE9__SHIFT 0x0\n#define VGT_DEBUG_REG1__SPARE8_MASK 0x2\n#define VGT_DEBUG_REG1__SPARE8__SHIFT 0x1\n#define VGT_DEBUG_REG1__SPARE7_MASK 0x4\n#define VGT_DEBUG_REG1__SPARE7__SHIFT 0x2\n#define VGT_DEBUG_REG1__SPARE6_MASK 0x8\n#define VGT_DEBUG_REG1__SPARE6__SHIFT 0x3\n#define VGT_DEBUG_REG1__SPARE5_MASK 0x10\n#define VGT_DEBUG_REG1__SPARE5__SHIFT 0x4\n#define VGT_DEBUG_REG1__SPARE4_MASK 0x20\n#define VGT_DEBUG_REG1__SPARE4__SHIFT 0x5\n#define VGT_DEBUG_REG1__SPARE3_MASK 0x40\n#define VGT_DEBUG_REG1__SPARE3__SHIFT 0x6\n#define VGT_DEBUG_REG1__SPARE2_MASK 0x80\n#define VGT_DEBUG_REG1__SPARE2__SHIFT 0x7\n#define VGT_DEBUG_REG1__SPARE1_MASK 0x100\n#define VGT_DEBUG_REG1__SPARE1__SHIFT 0x8\n#define VGT_DEBUG_REG1__SPARE0_MASK 0x200\n#define VGT_DEBUG_REG1__SPARE0__SHIFT 0x9\n#define VGT_DEBUG_REG1__pi_vr_valid_MASK 0x400\n#define VGT_DEBUG_REG1__pi_vr_valid__SHIFT 0xa\n#define VGT_DEBUG_REG1__vr_pi_read_MASK 0x800\n#define VGT_DEBUG_REG1__vr_pi_read__SHIFT 0xb\n#define VGT_DEBUG_REG1__pi_pt_valid_MASK 0x1000\n#define VGT_DEBUG_REG1__pi_pt_valid__SHIFT 0xc\n#define VGT_DEBUG_REG1__pt_pi_read_MASK 0x2000\n#define VGT_DEBUG_REG1__pt_pi_read__SHIFT 0xd\n#define VGT_DEBUG_REG1__pi_te_valid_MASK 0x4000\n#define VGT_DEBUG_REG1__pi_te_valid__SHIFT 0xe\n#define VGT_DEBUG_REG1__te_grp_read_MASK 0x8000\n#define VGT_DEBUG_REG1__te_grp_read__SHIFT 0xf\n#define VGT_DEBUG_REG1__vr_out_indx_valid_MASK 0x10000\n#define VGT_DEBUG_REG1__vr_out_indx_valid__SHIFT 0x10\n#define VGT_DEBUG_REG1__SPARE12_MASK 0x20000\n#define VGT_DEBUG_REG1__SPARE12__SHIFT 0x11\n#define VGT_DEBUG_REG1__vr_out_prim_valid_MASK 0x40000\n#define VGT_DEBUG_REG1__vr_out_prim_valid__SHIFT 0x12\n#define VGT_DEBUG_REG1__SPARE11_MASK 0x80000\n#define VGT_DEBUG_REG1__SPARE11__SHIFT 0x13\n#define VGT_DEBUG_REG1__pt_out_indx_valid_MASK 0x100000\n#define VGT_DEBUG_REG1__pt_out_indx_valid__SHIFT 0x14\n#define VGT_DEBUG_REG1__SPARE10_MASK 0x200000\n#define VGT_DEBUG_REG1__SPARE10__SHIFT 0x15\n#define VGT_DEBUG_REG1__pt_out_prim_valid_MASK 0x400000\n#define VGT_DEBUG_REG1__pt_out_prim_valid__SHIFT 0x16\n#define VGT_DEBUG_REG1__SPARE23_MASK 0x800000\n#define VGT_DEBUG_REG1__SPARE23__SHIFT 0x17\n#define VGT_DEBUG_REG1__te_out_data_valid_MASK 0x1000000\n#define VGT_DEBUG_REG1__te_out_data_valid__SHIFT 0x18\n#define VGT_DEBUG_REG1__SPARE25_MASK 0x2000000\n#define VGT_DEBUG_REG1__SPARE25__SHIFT 0x19\n#define VGT_DEBUG_REG1__pi_gs_valid_MASK 0x4000000\n#define VGT_DEBUG_REG1__pi_gs_valid__SHIFT 0x1a\n#define VGT_DEBUG_REG1__gs_pi_read_MASK 0x8000000\n#define VGT_DEBUG_REG1__gs_pi_read__SHIFT 0x1b\n#define VGT_DEBUG_REG1__gog_out_indx_valid_MASK 0x10000000\n#define VGT_DEBUG_REG1__gog_out_indx_valid__SHIFT 0x1c\n#define VGT_DEBUG_REG1__out_indx_read_MASK 0x20000000\n#define VGT_DEBUG_REG1__out_indx_read__SHIFT 0x1d\n#define VGT_DEBUG_REG1__gog_out_prim_valid_MASK 0x40000000\n#define VGT_DEBUG_REG1__gog_out_prim_valid__SHIFT 0x1e\n#define VGT_DEBUG_REG1__out_prim_read_MASK 0x80000000\n#define VGT_DEBUG_REG1__out_prim_read__SHIFT 0x1f\n#define VGT_DEBUG_REG2__hs_grp_busy_MASK 0x1\n#define VGT_DEBUG_REG2__hs_grp_busy__SHIFT 0x0\n#define VGT_DEBUG_REG2__hs_noif_busy_MASK 0x2\n#define VGT_DEBUG_REG2__hs_noif_busy__SHIFT 0x1\n#define VGT_DEBUG_REG2__tfmmIsBusy_MASK 0x4\n#define VGT_DEBUG_REG2__tfmmIsBusy__SHIFT 0x2\n#define VGT_DEBUG_REG2__lsVertIfBusy_0_MASK 0x8\n#define VGT_DEBUG_REG2__lsVertIfBusy_0__SHIFT 0x3\n#define VGT_DEBUG_REG2__te11_hs_tess_input_rtr_MASK 0x10\n#define VGT_DEBUG_REG2__te11_hs_tess_input_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG2__lsWaveIfBusy_0_MASK 0x20\n#define VGT_DEBUG_REG2__lsWaveIfBusy_0__SHIFT 0x5\n#define VGT_DEBUG_REG2__hs_te11_tess_input_rts_MASK 0x40\n#define VGT_DEBUG_REG2__hs_te11_tess_input_rts__SHIFT 0x6\n#define VGT_DEBUG_REG2__grpModBusy_MASK 0x80\n#define VGT_DEBUG_REG2__grpModBusy__SHIFT 0x7\n#define VGT_DEBUG_REG2__lsVertFifoEmpty_MASK 0x100\n#define VGT_DEBUG_REG2__lsVertFifoEmpty__SHIFT 0x8\n#define VGT_DEBUG_REG2__lsWaveFifoEmpty_MASK 0x200\n#define VGT_DEBUG_REG2__lsWaveFifoEmpty__SHIFT 0x9\n#define VGT_DEBUG_REG2__hsVertFifoEmpty_MASK 0x400\n#define VGT_DEBUG_REG2__hsVertFifoEmpty__SHIFT 0xa\n#define VGT_DEBUG_REG2__hsWaveFifoEmpty_MASK 0x800\n#define VGT_DEBUG_REG2__hsWaveFifoEmpty__SHIFT 0xb\n#define VGT_DEBUG_REG2__hsInputFifoEmpty_MASK 0x1000\n#define VGT_DEBUG_REG2__hsInputFifoEmpty__SHIFT 0xc\n#define VGT_DEBUG_REG2__hsTifFifoEmpty_MASK 0x2000\n#define VGT_DEBUG_REG2__hsTifFifoEmpty__SHIFT 0xd\n#define VGT_DEBUG_REG2__lsVertFifoFull_MASK 0x4000\n#define VGT_DEBUG_REG2__lsVertFifoFull__SHIFT 0xe\n#define VGT_DEBUG_REG2__lsWaveFifoFull_MASK 0x8000\n#define VGT_DEBUG_REG2__lsWaveFifoFull__SHIFT 0xf\n#define VGT_DEBUG_REG2__hsVertFifoFull_MASK 0x10000\n#define VGT_DEBUG_REG2__hsVertFifoFull__SHIFT 0x10\n#define VGT_DEBUG_REG2__hsWaveFifoFull_MASK 0x20000\n#define VGT_DEBUG_REG2__hsWaveFifoFull__SHIFT 0x11\n#define VGT_DEBUG_REG2__hsInputFifoFull_MASK 0x40000\n#define VGT_DEBUG_REG2__hsInputFifoFull__SHIFT 0x12\n#define VGT_DEBUG_REG2__hsTifFifoFull_MASK 0x80000\n#define VGT_DEBUG_REG2__hsTifFifoFull__SHIFT 0x13\n#define VGT_DEBUG_REG2__p0_rtr_MASK 0x100000\n#define VGT_DEBUG_REG2__p0_rtr__SHIFT 0x14\n#define VGT_DEBUG_REG2__p1_rtr_MASK 0x200000\n#define VGT_DEBUG_REG2__p1_rtr__SHIFT 0x15\n#define VGT_DEBUG_REG2__p0_dr_MASK 0x400000\n#define VGT_DEBUG_REG2__p0_dr__SHIFT 0x16\n#define VGT_DEBUG_REG2__p1_dr_MASK 0x800000\n#define VGT_DEBUG_REG2__p1_dr__SHIFT 0x17\n#define VGT_DEBUG_REG2__p0_rts_MASK 0x1000000\n#define VGT_DEBUG_REG2__p0_rts__SHIFT 0x18\n#define VGT_DEBUG_REG2__p1_rts_MASK 0x2000000\n#define VGT_DEBUG_REG2__p1_rts__SHIFT 0x19\n#define VGT_DEBUG_REG2__ls_sh_id_MASK 0x4000000\n#define VGT_DEBUG_REG2__ls_sh_id__SHIFT 0x1a\n#define VGT_DEBUG_REG2__lsFwaveFlag_MASK 0x8000000\n#define VGT_DEBUG_REG2__lsFwaveFlag__SHIFT 0x1b\n#define VGT_DEBUG_REG2__lsWaveSendFlush_MASK 0x10000000\n#define VGT_DEBUG_REG2__lsWaveSendFlush__SHIFT 0x1c\n#define VGT_DEBUG_REG2__SPARE_MASK 0xe0000000\n#define VGT_DEBUG_REG2__SPARE__SHIFT 0x1d\n#define VGT_DEBUG_REG3__lsTgRelInd_MASK 0xfff\n#define VGT_DEBUG_REG3__lsTgRelInd__SHIFT 0x0\n#define VGT_DEBUG_REG3__lsWaveRelInd_MASK 0x3f000\n#define VGT_DEBUG_REG3__lsWaveRelInd__SHIFT 0xc\n#define VGT_DEBUG_REG3__lsPatchCnt_MASK 0x3fc0000\n#define VGT_DEBUG_REG3__lsPatchCnt__SHIFT 0x12\n#define VGT_DEBUG_REG3__hsWaveRelInd_MASK 0xfc000000\n#define VGT_DEBUG_REG3__hsWaveRelInd__SHIFT 0x1a\n#define VGT_DEBUG_REG4__hsPatchCnt_MASK 0xff\n#define VGT_DEBUG_REG4__hsPatchCnt__SHIFT 0x0\n#define VGT_DEBUG_REG4__hsPrimId_15_0_MASK 0xffff00\n#define VGT_DEBUG_REG4__hsPrimId_15_0__SHIFT 0x8\n#define VGT_DEBUG_REG4__hsCpCnt_MASK 0x1f000000\n#define VGT_DEBUG_REG4__hsCpCnt__SHIFT 0x18\n#define VGT_DEBUG_REG4__hsWaveSendFlush_MASK 0x20000000\n#define VGT_DEBUG_REG4__hsWaveSendFlush__SHIFT 0x1d\n#define VGT_DEBUG_REG4__hsFwaveFlag_MASK 0x40000000\n#define VGT_DEBUG_REG4__hsFwaveFlag__SHIFT 0x1e\n#define VGT_DEBUG_REG4__SPARE_MASK 0x80000000\n#define VGT_DEBUG_REG4__SPARE__SHIFT 0x1f\n#define VGT_DEBUG_REG5__SPARE4_MASK 0x7\n#define VGT_DEBUG_REG5__SPARE4__SHIFT 0x0\n#define VGT_DEBUG_REG5__hsWaveCreditCnt_0_MASK 0xf8\n#define VGT_DEBUG_REG5__hsWaveCreditCnt_0__SHIFT 0x3\n#define VGT_DEBUG_REG5__SPARE3_MASK 0x700\n#define VGT_DEBUG_REG5__SPARE3__SHIFT 0x8\n#define VGT_DEBUG_REG5__hsVertCreditCnt_0_MASK 0xf800\n#define VGT_DEBUG_REG5__hsVertCreditCnt_0__SHIFT 0xb\n#define VGT_DEBUG_REG5__SPARE2_MASK 0x70000\n#define VGT_DEBUG_REG5__SPARE2__SHIFT 0x10\n#define VGT_DEBUG_REG5__lsWaveCreditCnt_0_MASK 0xf80000\n#define VGT_DEBUG_REG5__lsWaveCreditCnt_0__SHIFT 0x13\n#define VGT_DEBUG_REG5__SPARE1_MASK 0x7000000\n#define VGT_DEBUG_REG5__SPARE1__SHIFT 0x18\n#define VGT_DEBUG_REG5__lsVertCreditCnt_0_MASK 0xf8000000\n#define VGT_DEBUG_REG5__lsVertCreditCnt_0__SHIFT 0x1b\n#define VGT_DEBUG_REG6__debug_BASE_MASK 0xffff\n#define VGT_DEBUG_REG6__debug_BASE__SHIFT 0x0\n#define VGT_DEBUG_REG6__debug_SIZE_MASK 0xffff0000\n#define VGT_DEBUG_REG6__debug_SIZE__SHIFT 0x10\n#define VGT_DEBUG_REG7__debug_tfmmFifoEmpty_MASK 0x1\n#define VGT_DEBUG_REG7__debug_tfmmFifoEmpty__SHIFT 0x0\n#define VGT_DEBUG_REG7__debug_tfmmFifoFull_MASK 0x2\n#define VGT_DEBUG_REG7__debug_tfmmFifoFull__SHIFT 0x1\n#define VGT_DEBUG_REG7__hs_pipe0_dr_MASK 0x4\n#define VGT_DEBUG_REG7__hs_pipe0_dr__SHIFT 0x2\n#define VGT_DEBUG_REG7__hs_pipe0_rtr_MASK 0x8\n#define VGT_DEBUG_REG7__hs_pipe0_rtr__SHIFT 0x3\n#define VGT_DEBUG_REG7__hs_pipe1_rtr_MASK 0x10\n#define VGT_DEBUG_REG7__hs_pipe1_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG7__SPARE_MASK 0xffe0\n#define VGT_DEBUG_REG7__SPARE__SHIFT 0x5\n#define VGT_DEBUG_REG7__TF_addr_MASK 0xffff0000\n#define VGT_DEBUG_REG7__TF_addr__SHIFT 0x10\n#define VGT_DEBUG_REG8__rcm_busy_q_MASK 0x1\n#define VGT_DEBUG_REG8__rcm_busy_q__SHIFT 0x0\n#define VGT_DEBUG_REG8__rcm_noif_busy_q_MASK 0x2\n#define VGT_DEBUG_REG8__rcm_noif_busy_q__SHIFT 0x1\n#define VGT_DEBUG_REG8__r1_inst_rtr_MASK 0x4\n#define VGT_DEBUG_REG8__r1_inst_rtr__SHIFT 0x2\n#define VGT_DEBUG_REG8__spi_gsprim_fifo_busy_q_MASK 0x8\n#define VGT_DEBUG_REG8__spi_gsprim_fifo_busy_q__SHIFT 0x3\n#define VGT_DEBUG_REG8__spi_esvert_fifo_busy_q_MASK 0x10\n#define VGT_DEBUG_REG8__spi_esvert_fifo_busy_q__SHIFT 0x4\n#define VGT_DEBUG_REG8__gs_tbl_valid_r3_q_MASK 0x20\n#define VGT_DEBUG_REG8__gs_tbl_valid_r3_q__SHIFT 0x5\n#define VGT_DEBUG_REG8__valid_r0_q_MASK 0x40\n#define VGT_DEBUG_REG8__valid_r0_q__SHIFT 0x6\n#define VGT_DEBUG_REG8__valid_r1_q_MASK 0x80\n#define VGT_DEBUG_REG8__valid_r1_q__SHIFT 0x7\n#define VGT_DEBUG_REG8__valid_r2_MASK 0x100\n#define VGT_DEBUG_REG8__valid_r2__SHIFT 0x8\n#define VGT_DEBUG_REG8__valid_r2_q_MASK 0x200\n#define VGT_DEBUG_REG8__valid_r2_q__SHIFT 0x9\n#define VGT_DEBUG_REG8__r0_rtr_MASK 0x400\n#define VGT_DEBUG_REG8__r0_rtr__SHIFT 0xa\n#define VGT_DEBUG_REG8__r1_rtr_MASK 0x800\n#define VGT_DEBUG_REG8__r1_rtr__SHIFT 0xb\n#define VGT_DEBUG_REG8__r2_indx_rtr_MASK 0x1000\n#define VGT_DEBUG_REG8__r2_indx_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG8__r2_rtr_MASK 0x2000\n#define VGT_DEBUG_REG8__r2_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG8__es_gs_rtr_MASK 0x4000\n#define VGT_DEBUG_REG8__es_gs_rtr__SHIFT 0xe\n#define VGT_DEBUG_REG8__gs_event_fifo_rtr_MASK 0x8000\n#define VGT_DEBUG_REG8__gs_event_fifo_rtr__SHIFT 0xf\n#define VGT_DEBUG_REG8__tm_rcm_gs_event_rtr_MASK 0x10000\n#define VGT_DEBUG_REG8__tm_rcm_gs_event_rtr__SHIFT 0x10\n#define VGT_DEBUG_REG8__gs_tbl_r3_rtr_MASK 0x20000\n#define VGT_DEBUG_REG8__gs_tbl_r3_rtr__SHIFT 0x11\n#define VGT_DEBUG_REG8__prim_skid_fifo_empty_MASK 0x40000\n#define VGT_DEBUG_REG8__prim_skid_fifo_empty__SHIFT 0x12\n#define VGT_DEBUG_REG8__VGT_SPI_gsprim_rtr_q_MASK 0x80000\n#define VGT_DEBUG_REG8__VGT_SPI_gsprim_rtr_q__SHIFT 0x13\n#define VGT_DEBUG_REG8__tm_rcm_gs_tbl_rtr_MASK 0x100000\n#define VGT_DEBUG_REG8__tm_rcm_gs_tbl_rtr__SHIFT 0x14\n#define VGT_DEBUG_REG8__tm_rcm_es_tbl_rtr_MASK 0x200000\n#define VGT_DEBUG_REG8__tm_rcm_es_tbl_rtr__SHIFT 0x15\n#define VGT_DEBUG_REG8__VGT_SPI_esvert_rtr_q_MASK 0x400000\n#define VGT_DEBUG_REG8__VGT_SPI_esvert_rtr_q__SHIFT 0x16\n#define VGT_DEBUG_REG8__r2_no_bp_rtr_MASK 0x800000\n#define VGT_DEBUG_REG8__r2_no_bp_rtr__SHIFT 0x17\n#define VGT_DEBUG_REG8__hold_for_es_flush_MASK 0x1000000\n#define VGT_DEBUG_REG8__hold_for_es_flush__SHIFT 0x18\n#define VGT_DEBUG_REG8__gs_event_fifo_empty_MASK 0x2000000\n#define VGT_DEBUG_REG8__gs_event_fifo_empty__SHIFT 0x19\n#define VGT_DEBUG_REG8__gsprim_buff_empty_q_MASK 0x4000000\n#define VGT_DEBUG_REG8__gsprim_buff_empty_q__SHIFT 0x1a\n#define VGT_DEBUG_REG8__gsprim_buff_full_q_MASK 0x8000000\n#define VGT_DEBUG_REG8__gsprim_buff_full_q__SHIFT 0x1b\n#define VGT_DEBUG_REG8__te_prim_fifo_empty_MASK 0x10000000\n#define VGT_DEBUG_REG8__te_prim_fifo_empty__SHIFT 0x1c\n#define VGT_DEBUG_REG8__te_prim_fifo_full_MASK 0x20000000\n#define VGT_DEBUG_REG8__te_prim_fifo_full__SHIFT 0x1d\n#define VGT_DEBUG_REG8__te_vert_fifo_empty_MASK 0x40000000\n#define VGT_DEBUG_REG8__te_vert_fifo_empty__SHIFT 0x1e\n#define VGT_DEBUG_REG8__te_vert_fifo_full_MASK 0x80000000\n#define VGT_DEBUG_REG8__te_vert_fifo_full__SHIFT 0x1f\n#define VGT_DEBUG_REG9__indices_to_send_r2_q_MASK 0x3\n#define VGT_DEBUG_REG9__indices_to_send_r2_q__SHIFT 0x0\n#define VGT_DEBUG_REG9__valid_indices_r3_MASK 0x4\n#define VGT_DEBUG_REG9__valid_indices_r3__SHIFT 0x2\n#define VGT_DEBUG_REG9__gs_eov_r3_MASK 0x8\n#define VGT_DEBUG_REG9__gs_eov_r3__SHIFT 0x3\n#define VGT_DEBUG_REG9__eop_indx_r3_MASK 0x10\n#define VGT_DEBUG_REG9__eop_indx_r3__SHIFT 0x4\n#define VGT_DEBUG_REG9__eop_prim_r3_MASK 0x20\n#define VGT_DEBUG_REG9__eop_prim_r3__SHIFT 0x5\n#define VGT_DEBUG_REG9__es_eov_r3_MASK 0x40\n#define VGT_DEBUG_REG9__es_eov_r3__SHIFT 0x6\n#define VGT_DEBUG_REG9__es_tbl_state_r3_q_0_MASK 0x80\n#define VGT_DEBUG_REG9__es_tbl_state_r3_q_0__SHIFT 0x7\n#define VGT_DEBUG_REG9__pending_es_send_r3_q_MASK 0x100\n#define VGT_DEBUG_REG9__pending_es_send_r3_q__SHIFT 0x8\n#define VGT_DEBUG_REG9__pending_es_flush_r3_MASK 0x200\n#define VGT_DEBUG_REG9__pending_es_flush_r3__SHIFT 0x9\n#define VGT_DEBUG_REG9__gs_tbl_num_es_per_gs_r3_q_not_0_MASK 0x400\n#define VGT_DEBUG_REG9__gs_tbl_num_es_per_gs_r3_q_not_0__SHIFT 0xa\n#define VGT_DEBUG_REG9__gs_tbl_prim_cnt_r3_q_MASK 0x3f800\n#define VGT_DEBUG_REG9__gs_tbl_prim_cnt_r3_q__SHIFT 0xb\n#define VGT_DEBUG_REG9__gs_tbl_eop_r3_q_MASK 0x40000\n#define VGT_DEBUG_REG9__gs_tbl_eop_r3_q__SHIFT 0x12\n#define VGT_DEBUG_REG9__gs_tbl_state_r3_q_MASK 0x380000\n#define VGT_DEBUG_REG9__gs_tbl_state_r3_q__SHIFT 0x13\n#define VGT_DEBUG_REG9__gs_pending_state_r3_q_MASK 0x400000\n#define VGT_DEBUG_REG9__gs_pending_state_r3_q__SHIFT 0x16\n#define VGT_DEBUG_REG9__invalidate_rb_roll_over_q_MASK 0x800000\n#define VGT_DEBUG_REG9__invalidate_rb_roll_over_q__SHIFT 0x17\n#define VGT_DEBUG_REG9__gs_instancing_state_q_MASK 0x1000000\n#define VGT_DEBUG_REG9__gs_instancing_state_q__SHIFT 0x18\n#define VGT_DEBUG_REG9__es_per_gs_vert_cnt_r3_q_not_0_MASK 0x2000000\n#define VGT_DEBUG_REG9__es_per_gs_vert_cnt_r3_q_not_0__SHIFT 0x19\n#define VGT_DEBUG_REG9__gs_prim_per_es_ctr_r3_q_not_0_MASK 0x4000000\n#define VGT_DEBUG_REG9__gs_prim_per_es_ctr_r3_q_not_0__SHIFT 0x1a\n#define VGT_DEBUG_REG9__pre_r0_rtr_MASK 0x8000000\n#define VGT_DEBUG_REG9__pre_r0_rtr__SHIFT 0x1b\n#define VGT_DEBUG_REG9__valid_r3_q_MASK 0x10000000\n#define VGT_DEBUG_REG9__valid_r3_q__SHIFT 0x1c\n#define VGT_DEBUG_REG9__valid_pre_r0_q_MASK 0x20000000\n#define VGT_DEBUG_REG9__valid_pre_r0_q__SHIFT 0x1d\n#define VGT_DEBUG_REG9__SPARE0_MASK 0x40000000\n#define VGT_DEBUG_REG9__SPARE0__SHIFT 0x1e\n#define VGT_DEBUG_REG9__off_chip_hs_r2_q_MASK 0x80000000\n#define VGT_DEBUG_REG9__off_chip_hs_r2_q__SHIFT 0x1f\n#define VGT_DEBUG_REG10__index_buffer_depth_r1_q_MASK 0x1f\n#define VGT_DEBUG_REG10__index_buffer_depth_r1_q__SHIFT 0x0\n#define VGT_DEBUG_REG10__eopg_r2_q_MASK 0x20\n#define VGT_DEBUG_REG10__eopg_r2_q__SHIFT 0x5\n#define VGT_DEBUG_REG10__eotg_r2_q_MASK 0x40\n#define VGT_DEBUG_REG10__eotg_r2_q__SHIFT 0x6\n#define VGT_DEBUG_REG10__onchip_gs_en_r0_q_MASK 0x180\n#define VGT_DEBUG_REG10__onchip_gs_en_r0_q__SHIFT 0x7\n#define VGT_DEBUG_REG10__SPARE2_MASK 0x600\n#define VGT_DEBUG_REG10__SPARE2__SHIFT 0x9\n#define VGT_DEBUG_REG10__rcm_mem_gsprim_re_qq_MASK 0x800\n#define VGT_DEBUG_REG10__rcm_mem_gsprim_re_qq__SHIFT 0xb\n#define VGT_DEBUG_REG10__rcm_mem_gsprim_re_q_MASK 0x1000\n#define VGT_DEBUG_REG10__rcm_mem_gsprim_re_q__SHIFT 0xc\n#define VGT_DEBUG_REG10__gs_rb_space_avail_r3_q_9_0_MASK 0x7fe000\n#define VGT_DEBUG_REG10__gs_rb_space_avail_r3_q_9_0__SHIFT 0xd\n#define VGT_DEBUG_REG10__es_rb_space_avail_r2_q_8_0_MASK 0xff800000\n#define VGT_DEBUG_REG10__es_rb_space_avail_r2_q_8_0__SHIFT 0x17\n#define VGT_DEBUG_REG11__tm_busy_q_MASK 0x1\n#define VGT_DEBUG_REG11__tm_busy_q__SHIFT 0x0\n#define VGT_DEBUG_REG11__tm_noif_busy_q_MASK 0x2\n#define VGT_DEBUG_REG11__tm_noif_busy_q__SHIFT 0x1\n#define VGT_DEBUG_REG11__tm_out_busy_q_MASK 0x4\n#define VGT_DEBUG_REG11__tm_out_busy_q__SHIFT 0x2\n#define VGT_DEBUG_REG11__es_rb_dealloc_fifo_busy_MASK 0x8\n#define VGT_DEBUG_REG11__es_rb_dealloc_fifo_busy__SHIFT 0x3\n#define VGT_DEBUG_REG11__vs_dealloc_tbl_busy_MASK 0x10\n#define VGT_DEBUG_REG11__vs_dealloc_tbl_busy__SHIFT 0x4\n#define VGT_DEBUG_REG11__SPARE1_MASK 0x20\n#define VGT_DEBUG_REG11__SPARE1__SHIFT 0x5\n#define VGT_DEBUG_REG11__spi_gsthread_fifo_busy_MASK 0x40\n#define VGT_DEBUG_REG11__spi_gsthread_fifo_busy__SHIFT 0x6\n#define VGT_DEBUG_REG11__spi_esthread_fifo_busy_MASK 0x80\n#define VGT_DEBUG_REG11__spi_esthread_fifo_busy__SHIFT 0x7\n#define VGT_DEBUG_REG11__hold_eswave_MASK 0x100\n#define VGT_DEBUG_REG11__hold_eswave__SHIFT 0x8\n#define VGT_DEBUG_REG11__es_rb_roll_over_r3_MASK 0x200\n#define VGT_DEBUG_REG11__es_rb_roll_over_r3__SHIFT 0x9\n#define VGT_DEBUG_REG11__counters_busy_r0_MASK 0x400\n#define VGT_DEBUG_REG11__counters_busy_r0__SHIFT 0xa\n#define VGT_DEBUG_REG11__counters_avail_r0_MASK 0x800\n#define VGT_DEBUG_REG11__counters_avail_r0__SHIFT 0xb\n#define VGT_DEBUG_REG11__counters_available_r0_MASK 0x1000\n#define VGT_DEBUG_REG11__counters_available_r0__SHIFT 0xc\n#define VGT_DEBUG_REG11__vs_event_fifo_rtr_MASK 0x2000\n#define VGT_DEBUG_REG11__vs_event_fifo_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG11__VGT_SPI_gsthread_rtr_q_MASK 0x4000\n#define VGT_DEBUG_REG11__VGT_SPI_gsthread_rtr_q__SHIFT 0xe\n#define VGT_DEBUG_REG11__VGT_SPI_esthread_rtr_q_MASK 0x8000\n#define VGT_DEBUG_REG11__VGT_SPI_esthread_rtr_q__SHIFT 0xf\n#define VGT_DEBUG_REG11__gs_issue_rtr_MASK 0x10000\n#define VGT_DEBUG_REG11__gs_issue_rtr__SHIFT 0x10\n#define VGT_DEBUG_REG11__tm_pt_event_rtr_MASK 0x20000\n#define VGT_DEBUG_REG11__tm_pt_event_rtr__SHIFT 0x11\n#define VGT_DEBUG_REG11__SPARE0_MASK 0x40000\n#define VGT_DEBUG_REG11__SPARE0__SHIFT 0x12\n#define VGT_DEBUG_REG11__gs_r0_rtr_MASK 0x80000\n#define VGT_DEBUG_REG11__gs_r0_rtr__SHIFT 0x13\n#define VGT_DEBUG_REG11__es_r0_rtr_MASK 0x100000\n#define VGT_DEBUG_REG11__es_r0_rtr__SHIFT 0x14\n#define VGT_DEBUG_REG11__gog_tm_vs_event_rtr_MASK 0x200000\n#define VGT_DEBUG_REG11__gog_tm_vs_event_rtr__SHIFT 0x15\n#define VGT_DEBUG_REG11__tm_rcm_gs_event_rtr_MASK 0x400000\n#define VGT_DEBUG_REG11__tm_rcm_gs_event_rtr__SHIFT 0x16\n#define VGT_DEBUG_REG11__tm_rcm_gs_tbl_rtr_MASK 0x800000\n#define VGT_DEBUG_REG11__tm_rcm_gs_tbl_rtr__SHIFT 0x17\n#define VGT_DEBUG_REG11__tm_rcm_es_tbl_rtr_MASK 0x1000000\n#define VGT_DEBUG_REG11__tm_rcm_es_tbl_rtr__SHIFT 0x18\n#define VGT_DEBUG_REG11__vs_event_fifo_empty_MASK 0x2000000\n#define VGT_DEBUG_REG11__vs_event_fifo_empty__SHIFT 0x19\n#define VGT_DEBUG_REG11__vs_event_fifo_full_MASK 0x4000000\n#define VGT_DEBUG_REG11__vs_event_fifo_full__SHIFT 0x1a\n#define VGT_DEBUG_REG11__es_rb_dealloc_fifo_full_MASK 0x8000000\n#define VGT_DEBUG_REG11__es_rb_dealloc_fifo_full__SHIFT 0x1b\n#define VGT_DEBUG_REG11__vs_dealloc_tbl_full_MASK 0x10000000\n#define VGT_DEBUG_REG11__vs_dealloc_tbl_full__SHIFT 0x1c\n#define VGT_DEBUG_REG11__send_event_q_MASK 0x20000000\n#define VGT_DEBUG_REG11__send_event_q__SHIFT 0x1d\n#define VGT_DEBUG_REG11__es_tbl_empty_MASK 0x40000000\n#define VGT_DEBUG_REG11__es_tbl_empty__SHIFT 0x1e\n#define VGT_DEBUG_REG11__no_active_states_r0_MASK 0x80000000\n#define VGT_DEBUG_REG11__no_active_states_r0__SHIFT 0x1f\n#define VGT_DEBUG_REG12__gs_state0_r0_q_MASK 0x7\n#define VGT_DEBUG_REG12__gs_state0_r0_q__SHIFT 0x0\n#define VGT_DEBUG_REG12__gs_state1_r0_q_MASK 0x38\n#define VGT_DEBUG_REG12__gs_state1_r0_q__SHIFT 0x3\n#define VGT_DEBUG_REG12__gs_state2_r0_q_MASK 0x1c0\n#define VGT_DEBUG_REG12__gs_state2_r0_q__SHIFT 0x6\n#define VGT_DEBUG_REG12__gs_state3_r0_q_MASK 0xe00\n#define VGT_DEBUG_REG12__gs_state3_r0_q__SHIFT 0x9\n#define VGT_DEBUG_REG12__gs_state4_r0_q_MASK 0x7000\n#define VGT_DEBUG_REG12__gs_state4_r0_q__SHIFT 0xc\n#define VGT_DEBUG_REG12__gs_state5_r0_q_MASK 0x38000\n#define VGT_DEBUG_REG12__gs_state5_r0_q__SHIFT 0xf\n#define VGT_DEBUG_REG12__gs_state6_r0_q_MASK 0x1c0000\n#define VGT_DEBUG_REG12__gs_state6_r0_q__SHIFT 0x12\n#define VGT_DEBUG_REG12__gs_state7_r0_q_MASK 0xe00000\n#define VGT_DEBUG_REG12__gs_state7_r0_q__SHIFT 0x15\n#define VGT_DEBUG_REG12__gs_state8_r0_q_MASK 0x7000000\n#define VGT_DEBUG_REG12__gs_state8_r0_q__SHIFT 0x18\n#define VGT_DEBUG_REG12__gs_state9_r0_q_MASK 0x38000000\n#define VGT_DEBUG_REG12__gs_state9_r0_q__SHIFT 0x1b\n#define VGT_DEBUG_REG12__hold_eswave_eop_MASK 0x40000000\n#define VGT_DEBUG_REG12__hold_eswave_eop__SHIFT 0x1e\n#define VGT_DEBUG_REG12__SPARE0_MASK 0x80000000\n#define VGT_DEBUG_REG12__SPARE0__SHIFT 0x1f\n#define VGT_DEBUG_REG13__gs_state10_r0_q_MASK 0x7\n#define VGT_DEBUG_REG13__gs_state10_r0_q__SHIFT 0x0\n#define VGT_DEBUG_REG13__gs_state11_r0_q_MASK 0x38\n#define VGT_DEBUG_REG13__gs_state11_r0_q__SHIFT 0x3\n#define VGT_DEBUG_REG13__gs_state12_r0_q_MASK 0x1c0\n#define VGT_DEBUG_REG13__gs_state12_r0_q__SHIFT 0x6\n#define VGT_DEBUG_REG13__gs_state13_r0_q_MASK 0xe00\n#define VGT_DEBUG_REG13__gs_state13_r0_q__SHIFT 0x9\n#define VGT_DEBUG_REG13__gs_state14_r0_q_MASK 0x7000\n#define VGT_DEBUG_REG13__gs_state14_r0_q__SHIFT 0xc\n#define VGT_DEBUG_REG13__gs_state15_r0_q_MASK 0x38000\n#define VGT_DEBUG_REG13__gs_state15_r0_q__SHIFT 0xf\n#define VGT_DEBUG_REG13__gs_tbl_wrptr_r0_q_3_0_MASK 0x3c0000\n#define VGT_DEBUG_REG13__gs_tbl_wrptr_r0_q_3_0__SHIFT 0x12\n#define VGT_DEBUG_REG13__gsfetch_done_fifo_cnt_q_not_0_MASK 0x400000\n#define VGT_DEBUG_REG13__gsfetch_done_fifo_cnt_q_not_0__SHIFT 0x16\n#define VGT_DEBUG_REG13__gsfetch_done_cnt_q_not_0_MASK 0x800000\n#define VGT_DEBUG_REG13__gsfetch_done_cnt_q_not_0__SHIFT 0x17\n#define VGT_DEBUG_REG13__es_tbl_full_MASK 0x1000000\n#define VGT_DEBUG_REG13__es_tbl_full__SHIFT 0x18\n#define VGT_DEBUG_REG13__SPARE1_MASK 0x2000000\n#define VGT_DEBUG_REG13__SPARE1__SHIFT 0x19\n#define VGT_DEBUG_REG13__SPARE0_MASK 0x4000000\n#define VGT_DEBUG_REG13__SPARE0__SHIFT 0x1a\n#define VGT_DEBUG_REG13__active_cm_sm_r0_q_MASK 0xf8000000\n#define VGT_DEBUG_REG13__active_cm_sm_r0_q__SHIFT 0x1b\n#define VGT_DEBUG_REG14__SPARE3_MASK 0xf\n#define VGT_DEBUG_REG14__SPARE3__SHIFT 0x0\n#define VGT_DEBUG_REG14__gsfetch_done_fifo_full_MASK 0x10\n#define VGT_DEBUG_REG14__gsfetch_done_fifo_full__SHIFT 0x4\n#define VGT_DEBUG_REG14__gs_rb_space_avail_r0_MASK 0x20\n#define VGT_DEBUG_REG14__gs_rb_space_avail_r0__SHIFT 0x5\n#define VGT_DEBUG_REG14__smx_es_done_cnt_r0_q_not_0_MASK 0x40\n#define VGT_DEBUG_REG14__smx_es_done_cnt_r0_q_not_0__SHIFT 0x6\n#define VGT_DEBUG_REG14__SPARE8_MASK 0x180\n#define VGT_DEBUG_REG14__SPARE8__SHIFT 0x7\n#define VGT_DEBUG_REG14__vs_done_cnt_q_not_0_MASK 0x200\n#define VGT_DEBUG_REG14__vs_done_cnt_q_not_0__SHIFT 0x9\n#define VGT_DEBUG_REG14__es_flush_cnt_busy_q_MASK 0x400\n#define VGT_DEBUG_REG14__es_flush_cnt_busy_q__SHIFT 0xa\n#define VGT_DEBUG_REG14__gs_tbl_full_r0_MASK 0x800\n#define VGT_DEBUG_REG14__gs_tbl_full_r0__SHIFT 0xb\n#define VGT_DEBUG_REG14__SPARE2_MASK 0x1ff000\n#define VGT_DEBUG_REG14__SPARE2__SHIFT 0xc\n#define VGT_DEBUG_REG14__se1spi_gsthread_fifo_busy_MASK 0x200000\n#define VGT_DEBUG_REG14__se1spi_gsthread_fifo_busy__SHIFT 0x15\n#define VGT_DEBUG_REG14__SPARE_MASK 0x1c00000\n#define VGT_DEBUG_REG14__SPARE__SHIFT 0x16\n#define VGT_DEBUG_REG14__VGT_SE1SPI_gsthread_rtr_q_MASK 0x2000000\n#define VGT_DEBUG_REG14__VGT_SE1SPI_gsthread_rtr_q__SHIFT 0x19\n#define VGT_DEBUG_REG14__smx1_es_done_cnt_r0_q_not_0_MASK 0x4000000\n#define VGT_DEBUG_REG14__smx1_es_done_cnt_r0_q_not_0__SHIFT 0x1a\n#define VGT_DEBUG_REG14__se1spi_esthread_fifo_busy_MASK 0x8000000\n#define VGT_DEBUG_REG14__se1spi_esthread_fifo_busy__SHIFT 0x1b\n#define VGT_DEBUG_REG14__SPARE1_MASK 0x10000000\n#define VGT_DEBUG_REG14__SPARE1__SHIFT 0x1c\n#define VGT_DEBUG_REG14__gsfetch_done_se1_cnt_q_not_0_MASK 0x20000000\n#define VGT_DEBUG_REG14__gsfetch_done_se1_cnt_q_not_0__SHIFT 0x1d\n#define VGT_DEBUG_REG14__SPARE0_MASK 0x40000000\n#define VGT_DEBUG_REG14__SPARE0__SHIFT 0x1e\n#define VGT_DEBUG_REG14__VGT_SE1SPI_esthread_rtr_q_MASK 0x80000000\n#define VGT_DEBUG_REG14__VGT_SE1SPI_esthread_rtr_q__SHIFT 0x1f\n#define VGT_DEBUG_REG15__cm_busy_q_MASK 0x1\n#define VGT_DEBUG_REG15__cm_busy_q__SHIFT 0x0\n#define VGT_DEBUG_REG15__counters_busy_q_MASK 0x2\n#define VGT_DEBUG_REG15__counters_busy_q__SHIFT 0x1\n#define VGT_DEBUG_REG15__output_fifo_empty_MASK 0x4\n#define VGT_DEBUG_REG15__output_fifo_empty__SHIFT 0x2\n#define VGT_DEBUG_REG15__output_fifo_full_MASK 0x8\n#define VGT_DEBUG_REG15__output_fifo_full__SHIFT 0x3\n#define VGT_DEBUG_REG15__counters_full_MASK 0x10\n#define VGT_DEBUG_REG15__counters_full__SHIFT 0x4\n#define VGT_DEBUG_REG15__active_sm_q_MASK 0x3e0\n#define VGT_DEBUG_REG15__active_sm_q__SHIFT 0x5\n#define VGT_DEBUG_REG15__entry_rdptr_q_MASK 0x7c00\n#define VGT_DEBUG_REG15__entry_rdptr_q__SHIFT 0xa\n#define VGT_DEBUG_REG15__cntr_tbl_wrptr_q_MASK 0xf8000\n#define VGT_DEBUG_REG15__cntr_tbl_wrptr_q__SHIFT 0xf\n#define VGT_DEBUG_REG15__SPARE25_MASK 0x3f00000\n#define VGT_DEBUG_REG15__SPARE25__SHIFT 0x14\n#define VGT_DEBUG_REG15__st_cut_mode_q_MASK 0xc000000\n#define VGT_DEBUG_REG15__st_cut_mode_q__SHIFT 0x1a\n#define VGT_DEBUG_REG15__gs_done_array_q_not_0_MASK 0x10000000\n#define VGT_DEBUG_REG15__gs_done_array_q_not_0__SHIFT 0x1c\n#define VGT_DEBUG_REG15__SPARE31_MASK 0xe0000000\n#define VGT_DEBUG_REG15__SPARE31__SHIFT 0x1d\n#define VGT_DEBUG_REG16__gog_busy_MASK 0x1\n#define VGT_DEBUG_REG16__gog_busy__SHIFT 0x0\n#define VGT_DEBUG_REG16__gog_state_q_MASK 0xe\n#define VGT_DEBUG_REG16__gog_state_q__SHIFT 0x1\n#define VGT_DEBUG_REG16__r0_rtr_MASK 0x10\n#define VGT_DEBUG_REG16__r0_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG16__r1_rtr_MASK 0x20\n#define VGT_DEBUG_REG16__r1_rtr__SHIFT 0x5\n#define VGT_DEBUG_REG16__r1_upstream_rtr_MASK 0x40\n#define VGT_DEBUG_REG16__r1_upstream_rtr__SHIFT 0x6\n#define VGT_DEBUG_REG16__r2_vs_tbl_rtr_MASK 0x80\n#define VGT_DEBUG_REG16__r2_vs_tbl_rtr__SHIFT 0x7\n#define VGT_DEBUG_REG16__r2_prim_rtr_MASK 0x100\n#define VGT_DEBUG_REG16__r2_prim_rtr__SHIFT 0x8\n#define VGT_DEBUG_REG16__r2_indx_rtr_MASK 0x200\n#define VGT_DEBUG_REG16__r2_indx_rtr__SHIFT 0x9\n#define VGT_DEBUG_REG16__r2_rtr_MASK 0x400\n#define VGT_DEBUG_REG16__r2_rtr__SHIFT 0xa\n#define VGT_DEBUG_REG16__gog_tm_vs_event_rtr_MASK 0x800\n#define VGT_DEBUG_REG16__gog_tm_vs_event_rtr__SHIFT 0xb\n#define VGT_DEBUG_REG16__r3_force_vs_tbl_we_rtr_MASK 0x1000\n#define VGT_DEBUG_REG16__r3_force_vs_tbl_we_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG16__indx_valid_r2_q_MASK 0x2000\n#define VGT_DEBUG_REG16__indx_valid_r2_q__SHIFT 0xd\n#define VGT_DEBUG_REG16__prim_valid_r2_q_MASK 0x4000\n#define VGT_DEBUG_REG16__prim_valid_r2_q__SHIFT 0xe\n#define VGT_DEBUG_REG16__valid_r2_q_MASK 0x8000\n#define VGT_DEBUG_REG16__valid_r2_q__SHIFT 0xf\n#define VGT_DEBUG_REG16__prim_valid_r1_q_MASK 0x10000\n#define VGT_DEBUG_REG16__prim_valid_r1_q__SHIFT 0x10\n#define VGT_DEBUG_REG16__indx_valid_r1_q_MASK 0x20000\n#define VGT_DEBUG_REG16__indx_valid_r1_q__SHIFT 0x11\n#define VGT_DEBUG_REG16__valid_r1_q_MASK 0x40000\n#define VGT_DEBUG_REG16__valid_r1_q__SHIFT 0x12\n#define VGT_DEBUG_REG16__indx_valid_r0_q_MASK 0x80000\n#define VGT_DEBUG_REG16__indx_valid_r0_q__SHIFT 0x13\n#define VGT_DEBUG_REG16__prim_valid_r0_q_MASK 0x100000\n#define VGT_DEBUG_REG16__prim_valid_r0_q__SHIFT 0x14\n#define VGT_DEBUG_REG16__valid_r0_q_MASK 0x200000\n#define VGT_DEBUG_REG16__valid_r0_q__SHIFT 0x15\n#define VGT_DEBUG_REG16__send_event_q_MASK 0x400000\n#define VGT_DEBUG_REG16__send_event_q__SHIFT 0x16\n#define VGT_DEBUG_REG16__SPARE24_MASK 0x800000\n#define VGT_DEBUG_REG16__SPARE24__SHIFT 0x17\n#define VGT_DEBUG_REG16__vert_seen_since_sopg_r2_q_MASK 0x1000000\n#define VGT_DEBUG_REG16__vert_seen_since_sopg_r2_q__SHIFT 0x18\n#define VGT_DEBUG_REG16__gog_out_prim_state_sel_MASK 0xe000000\n#define VGT_DEBUG_REG16__gog_out_prim_state_sel__SHIFT 0x19\n#define VGT_DEBUG_REG16__multiple_streams_en_r1_q_MASK 0x10000000\n#define VGT_DEBUG_REG16__multiple_streams_en_r1_q__SHIFT 0x1c\n#define VGT_DEBUG_REG16__vs_vert_count_r2_q_not_0_MASK 0x20000000\n#define VGT_DEBUG_REG16__vs_vert_count_r2_q_not_0__SHIFT 0x1d\n#define VGT_DEBUG_REG16__num_gs_r2_q_not_0_MASK 0x40000000\n#define VGT_DEBUG_REG16__num_gs_r2_q_not_0__SHIFT 0x1e\n#define VGT_DEBUG_REG16__new_vs_thread_r2_MASK 0x80000000\n#define VGT_DEBUG_REG16__new_vs_thread_r2__SHIFT 0x1f\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx2_5_0_MASK 0x3f\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx2_5_0__SHIFT 0x0\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx1_5_0_MASK 0xfc0\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx1_5_0__SHIFT 0x6\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx0_5_0_MASK 0x3f000\n#define VGT_DEBUG_REG17__gog_out_prim_rel_indx0_5_0__SHIFT 0xc\n#define VGT_DEBUG_REG17__gog_out_indx_13_0_MASK 0xfffc0000\n#define VGT_DEBUG_REG17__gog_out_indx_13_0__SHIFT 0x12\n#define VGT_DEBUG_REG18__grp_vr_valid_MASK 0x1\n#define VGT_DEBUG_REG18__grp_vr_valid__SHIFT 0x0\n#define VGT_DEBUG_REG18__pipe0_dr_MASK 0x2\n#define VGT_DEBUG_REG18__pipe0_dr__SHIFT 0x1\n#define VGT_DEBUG_REG18__pipe1_dr_MASK 0x4\n#define VGT_DEBUG_REG18__pipe1_dr__SHIFT 0x2\n#define VGT_DEBUG_REG18__vr_grp_read_MASK 0x8\n#define VGT_DEBUG_REG18__vr_grp_read__SHIFT 0x3\n#define VGT_DEBUG_REG18__pipe0_rtr_MASK 0x10\n#define VGT_DEBUG_REG18__pipe0_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG18__pipe1_rtr_MASK 0x20\n#define VGT_DEBUG_REG18__pipe1_rtr__SHIFT 0x5\n#define VGT_DEBUG_REG18__out_vr_indx_read_MASK 0x40\n#define VGT_DEBUG_REG18__out_vr_indx_read__SHIFT 0x6\n#define VGT_DEBUG_REG18__out_vr_prim_read_MASK 0x80\n#define VGT_DEBUG_REG18__out_vr_prim_read__SHIFT 0x7\n#define VGT_DEBUG_REG18__indices_to_send_q_MASK 0x700\n#define VGT_DEBUG_REG18__indices_to_send_q__SHIFT 0x8\n#define VGT_DEBUG_REG18__valid_indices_MASK 0x800\n#define VGT_DEBUG_REG18__valid_indices__SHIFT 0xb\n#define VGT_DEBUG_REG18__last_indx_of_prim_MASK 0x1000\n#define VGT_DEBUG_REG18__last_indx_of_prim__SHIFT 0xc\n#define VGT_DEBUG_REG18__indx0_new_d_MASK 0x2000\n#define VGT_DEBUG_REG18__indx0_new_d__SHIFT 0xd\n#define VGT_DEBUG_REG18__indx1_new_d_MASK 0x4000\n#define VGT_DEBUG_REG18__indx1_new_d__SHIFT 0xe\n#define VGT_DEBUG_REG18__indx2_new_d_MASK 0x8000\n#define VGT_DEBUG_REG18__indx2_new_d__SHIFT 0xf\n#define VGT_DEBUG_REG18__indx2_hit_d_MASK 0x10000\n#define VGT_DEBUG_REG18__indx2_hit_d__SHIFT 0x10\n#define VGT_DEBUG_REG18__indx1_hit_d_MASK 0x20000\n#define VGT_DEBUG_REG18__indx1_hit_d__SHIFT 0x11\n#define VGT_DEBUG_REG18__indx0_hit_d_MASK 0x40000\n#define VGT_DEBUG_REG18__indx0_hit_d__SHIFT 0x12\n#define VGT_DEBUG_REG18__st_vertex_reuse_off_r0_q_MASK 0x80000\n#define VGT_DEBUG_REG18__st_vertex_reuse_off_r0_q__SHIFT 0x13\n#define VGT_DEBUG_REG18__last_group_of_instance_r0_q_MASK 0x100000\n#define VGT_DEBUG_REG18__last_group_of_instance_r0_q__SHIFT 0x14\n#define VGT_DEBUG_REG18__null_primitive_r0_q_MASK 0x200000\n#define VGT_DEBUG_REG18__null_primitive_r0_q__SHIFT 0x15\n#define VGT_DEBUG_REG18__eop_r0_q_MASK 0x400000\n#define VGT_DEBUG_REG18__eop_r0_q__SHIFT 0x16\n#define VGT_DEBUG_REG18__eject_vtx_vect_r1_d_MASK 0x800000\n#define VGT_DEBUG_REG18__eject_vtx_vect_r1_d__SHIFT 0x17\n#define VGT_DEBUG_REG18__sub_prim_type_r0_q_MASK 0x7000000\n#define VGT_DEBUG_REG18__sub_prim_type_r0_q__SHIFT 0x18\n#define VGT_DEBUG_REG18__gs_scenario_a_r0_q_MASK 0x8000000\n#define VGT_DEBUG_REG18__gs_scenario_a_r0_q__SHIFT 0x1b\n#define VGT_DEBUG_REG18__gs_scenario_b_r0_q_MASK 0x10000000\n#define VGT_DEBUG_REG18__gs_scenario_b_r0_q__SHIFT 0x1c\n#define VGT_DEBUG_REG18__components_valid_r0_q_MASK 0xe0000000\n#define VGT_DEBUG_REG18__components_valid_r0_q__SHIFT 0x1d\n#define VGT_DEBUG_REG19__separate_out_busy_q_MASK 0x1\n#define VGT_DEBUG_REG19__separate_out_busy_q__SHIFT 0x0\n#define VGT_DEBUG_REG19__separate_out_indx_busy_q_MASK 0x2\n#define VGT_DEBUG_REG19__separate_out_indx_busy_q__SHIFT 0x1\n#define VGT_DEBUG_REG19__prim_buffer_empty_MASK 0x4\n#define VGT_DEBUG_REG19__prim_buffer_empty__SHIFT 0x2\n#define VGT_DEBUG_REG19__prim_buffer_full_MASK 0x8\n#define VGT_DEBUG_REG19__prim_buffer_full__SHIFT 0x3\n#define VGT_DEBUG_REG19__pa_clips_fifo_busy_q_MASK 0x10\n#define VGT_DEBUG_REG19__pa_clips_fifo_busy_q__SHIFT 0x4\n#define VGT_DEBUG_REG19__pa_clipp_fifo_busy_q_MASK 0x20\n#define VGT_DEBUG_REG19__pa_clipp_fifo_busy_q__SHIFT 0x5\n#define VGT_DEBUG_REG19__VGT_PA_clips_rtr_q_MASK 0x40\n#define VGT_DEBUG_REG19__VGT_PA_clips_rtr_q__SHIFT 0x6\n#define VGT_DEBUG_REG19__VGT_PA_clipp_rtr_q_MASK 0x80\n#define VGT_DEBUG_REG19__VGT_PA_clipp_rtr_q__SHIFT 0x7\n#define VGT_DEBUG_REG19__spi_vsthread_fifo_busy_q_MASK 0x100\n#define VGT_DEBUG_REG19__spi_vsthread_fifo_busy_q__SHIFT 0x8\n#define VGT_DEBUG_REG19__spi_vsvert_fifo_busy_q_MASK 0x200\n#define VGT_DEBUG_REG19__spi_vsvert_fifo_busy_q__SHIFT 0x9\n#define VGT_DEBUG_REG19__pa_clipv_fifo_busy_q_MASK 0x400\n#define VGT_DEBUG_REG19__pa_clipv_fifo_busy_q__SHIFT 0xa\n#define VGT_DEBUG_REG19__hold_prim_MASK 0x800\n#define VGT_DEBUG_REG19__hold_prim__SHIFT 0xb\n#define VGT_DEBUG_REG19__VGT_SPI_vsthread_rtr_q_MASK 0x1000\n#define VGT_DEBUG_REG19__VGT_SPI_vsthread_rtr_q__SHIFT 0xc\n#define VGT_DEBUG_REG19__VGT_SPI_vsvert_rtr_q_MASK 0x2000\n#define VGT_DEBUG_REG19__VGT_SPI_vsvert_rtr_q__SHIFT 0xd\n#define VGT_DEBUG_REG19__VGT_PA_clipv_rtr_q_MASK 0x4000\n#define VGT_DEBUG_REG19__VGT_PA_clipv_rtr_q__SHIFT 0xe\n#define VGT_DEBUG_REG19__new_packet_q_MASK 0x8000\n#define VGT_DEBUG_REG19__new_packet_q__SHIFT 0xf\n#define VGT_DEBUG_REG19__buffered_prim_event_MASK 0x10000\n#define VGT_DEBUG_REG19__buffered_prim_event__SHIFT 0x10\n#define VGT_DEBUG_REG19__buffered_prim_null_primitive_MASK 0x20000\n#define VGT_DEBUG_REG19__buffered_prim_null_primitive__SHIFT 0x11\n#define VGT_DEBUG_REG19__buffered_prim_eop_MASK 0x40000\n#define VGT_DEBUG_REG19__buffered_prim_eop__SHIFT 0x12\n#define VGT_DEBUG_REG19__buffered_prim_eject_vtx_vect_MASK 0x80000\n#define VGT_DEBUG_REG19__buffered_prim_eject_vtx_vect__SHIFT 0x13\n#define VGT_DEBUG_REG19__buffered_prim_type_event_MASK 0x3f00000\n#define VGT_DEBUG_REG19__buffered_prim_type_event__SHIFT 0x14\n#define VGT_DEBUG_REG19__VGT_SE1SPI_vswave_rtr_q_MASK 0x4000000\n#define VGT_DEBUG_REG19__VGT_SE1SPI_vswave_rtr_q__SHIFT 0x1a\n#define VGT_DEBUG_REG19__VGT_SE1SPI_vsvert_rtr_q_MASK 0x8000000\n#define VGT_DEBUG_REG19__VGT_SE1SPI_vsvert_rtr_q__SHIFT 0x1b\n#define VGT_DEBUG_REG19__num_new_unique_rel_indx_MASK 0x30000000\n#define VGT_DEBUG_REG19__num_new_unique_rel_indx__SHIFT 0x1c\n#define VGT_DEBUG_REG19__null_terminate_vtx_vector_MASK 0x40000000\n#define VGT_DEBUG_REG19__null_terminate_vtx_vector__SHIFT 0x1e\n#define VGT_DEBUG_REG19__filter_event_MASK 0x80000000\n#define VGT_DEBUG_REG19__filter_event__SHIFT 0x1f\n#define VGT_DEBUG_REG20__dbg_VGT_SPI_vsthread_sovertexindex_MASK 0xffff\n#define VGT_DEBUG_REG20__dbg_VGT_SPI_vsthread_sovertexindex__SHIFT 0x0\n#define VGT_DEBUG_REG20__dbg_VGT_SPI_vsthread_sovertexcount_not_0_MASK 0x10000\n#define VGT_DEBUG_REG20__dbg_VGT_SPI_vsthread_sovertexcount_not_0__SHIFT 0x10\n#define VGT_DEBUG_REG20__SPARE17_MASK 0x20000\n#define VGT_DEBUG_REG20__SPARE17__SHIFT 0x11\n#define VGT_DEBUG_REG20__alloc_counter_q_MASK 0x3c0000\n#define VGT_DEBUG_REG20__alloc_counter_q__SHIFT 0x12\n#define VGT_DEBUG_REG20__curr_dealloc_distance_q_MASK 0x1fc00000\n#define VGT_DEBUG_REG20__curr_dealloc_distance_q__SHIFT 0x16\n#define VGT_DEBUG_REG20__new_allocate_q_MASK 0x20000000\n#define VGT_DEBUG_REG20__new_allocate_q__SHIFT 0x1d\n#define VGT_DEBUG_REG20__curr_slot_in_vtx_vect_q_not_0_MASK 0x40000000\n#define VGT_DEBUG_REG20__curr_slot_in_vtx_vect_q_not_0__SHIFT 0x1e\n#define VGT_DEBUG_REG20__int_vtx_counter_q_not_0_MASK 0x80000000\n#define VGT_DEBUG_REG20__int_vtx_counter_q_not_0__SHIFT 0x1f\n#define VGT_DEBUG_REG21__out_indx_fifo_empty_MASK 0x1\n#define VGT_DEBUG_REG21__out_indx_fifo_empty__SHIFT 0x0\n#define VGT_DEBUG_REG21__indx_side_fifo_empty_MASK 0x2\n#define VGT_DEBUG_REG21__indx_side_fifo_empty__SHIFT 0x1\n#define VGT_DEBUG_REG21__pipe0_dr_MASK 0x4\n#define VGT_DEBUG_REG21__pipe0_dr__SHIFT 0x2\n#define VGT_DEBUG_REG21__pipe1_dr_MASK 0x8\n#define VGT_DEBUG_REG21__pipe1_dr__SHIFT 0x3\n#define VGT_DEBUG_REG21__pipe2_dr_MASK 0x10\n#define VGT_DEBUG_REG21__pipe2_dr__SHIFT 0x4\n#define VGT_DEBUG_REG21__vsthread_buff_empty_MASK 0x20\n#define VGT_DEBUG_REG21__vsthread_buff_empty__SHIFT 0x5\n#define VGT_DEBUG_REG21__out_indx_fifo_full_MASK 0x40\n#define VGT_DEBUG_REG21__out_indx_fifo_full__SHIFT 0x6\n#define VGT_DEBUG_REG21__indx_side_fifo_full_MASK 0x80\n#define VGT_DEBUG_REG21__indx_side_fifo_full__SHIFT 0x7\n#define VGT_DEBUG_REG21__pipe0_rtr_MASK 0x100\n#define VGT_DEBUG_REG21__pipe0_rtr__SHIFT 0x8\n#define VGT_DEBUG_REG21__pipe1_rtr_MASK 0x200\n#define VGT_DEBUG_REG21__pipe1_rtr__SHIFT 0x9\n#define VGT_DEBUG_REG21__pipe2_rtr_MASK 0x400\n#define VGT_DEBUG_REG21__pipe2_rtr__SHIFT 0xa\n#define VGT_DEBUG_REG21__vsthread_buff_full_MASK 0x800\n#define VGT_DEBUG_REG21__vsthread_buff_full__SHIFT 0xb\n#define VGT_DEBUG_REG21__interfaces_rtr_MASK 0x1000\n#define VGT_DEBUG_REG21__interfaces_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG21__indx_count_q_not_0_MASK 0x2000\n#define VGT_DEBUG_REG21__indx_count_q_not_0__SHIFT 0xd\n#define VGT_DEBUG_REG21__wait_for_external_eopg_q_MASK 0x4000\n#define VGT_DEBUG_REG21__wait_for_external_eopg_q__SHIFT 0xe\n#define VGT_DEBUG_REG21__full_state_p1_q_MASK 0x8000\n#define VGT_DEBUG_REG21__full_state_p1_q__SHIFT 0xf\n#define VGT_DEBUG_REG21__indx_side_indx_valid_MASK 0x10000\n#define VGT_DEBUG_REG21__indx_side_indx_valid__SHIFT 0x10\n#define VGT_DEBUG_REG21__stateid_p0_q_MASK 0xe0000\n#define VGT_DEBUG_REG21__stateid_p0_q__SHIFT 0x11\n#define VGT_DEBUG_REG21__is_event_p0_q_MASK 0x100000\n#define VGT_DEBUG_REG21__is_event_p0_q__SHIFT 0x14\n#define VGT_DEBUG_REG21__lshs_dealloc_p1_MASK 0x200000\n#define VGT_DEBUG_REG21__lshs_dealloc_p1__SHIFT 0x15\n#define VGT_DEBUG_REG21__stream_id_r2_q_MASK 0x400000\n#define VGT_DEBUG_REG21__stream_id_r2_q__SHIFT 0x16\n#define VGT_DEBUG_REG21__vtx_vect_counter_q_not_0_MASK 0x800000\n#define VGT_DEBUG_REG21__vtx_vect_counter_q_not_0__SHIFT 0x17\n#define VGT_DEBUG_REG21__buff_full_p1_MASK 0x1000000\n#define VGT_DEBUG_REG21__buff_full_p1__SHIFT 0x18\n#define VGT_DEBUG_REG21__strmout_valid_p1_MASK 0x2000000\n#define VGT_DEBUG_REG21__strmout_valid_p1__SHIFT 0x19\n#define VGT_DEBUG_REG21__eotg_r2_q_MASK 0x4000000\n#define VGT_DEBUG_REG21__eotg_r2_q__SHIFT 0x1a\n#define VGT_DEBUG_REG21__null_r2_q_MASK 0x8000000\n#define VGT_DEBUG_REG21__null_r2_q__SHIFT 0x1b\n#define VGT_DEBUG_REG21__p0_dr_MASK 0x10000000\n#define VGT_DEBUG_REG21__p0_dr__SHIFT 0x1c\n#define VGT_DEBUG_REG21__p0_rtr_MASK 0x20000000\n#define VGT_DEBUG_REG21__p0_rtr__SHIFT 0x1d\n#define VGT_DEBUG_REG21__eopg_p0_q_MASK 0x40000000\n#define VGT_DEBUG_REG21__eopg_p0_q__SHIFT 0x1e\n#define VGT_DEBUG_REG21__p0_nobp_MASK 0x80000000\n#define VGT_DEBUG_REG21__p0_nobp__SHIFT 0x1f\n#define VGT_DEBUG_REG22__cm_state16_MASK 0x3\n#define VGT_DEBUG_REG22__cm_state16__SHIFT 0x0\n#define VGT_DEBUG_REG22__cm_state17_MASK 0xc\n#define VGT_DEBUG_REG22__cm_state17__SHIFT 0x2\n#define VGT_DEBUG_REG22__cm_state18_MASK 0x30\n#define VGT_DEBUG_REG22__cm_state18__SHIFT 0x4\n#define VGT_DEBUG_REG22__cm_state19_MASK 0xc0\n#define VGT_DEBUG_REG22__cm_state19__SHIFT 0x6\n#define VGT_DEBUG_REG22__cm_state20_MASK 0x300\n#define VGT_DEBUG_REG22__cm_state20__SHIFT 0x8\n#define VGT_DEBUG_REG22__cm_state21_MASK 0xc00\n#define VGT_DEBUG_REG22__cm_state21__SHIFT 0xa\n#define VGT_DEBUG_REG22__cm_state22_MASK 0x3000\n#define VGT_DEBUG_REG22__cm_state22__SHIFT 0xc\n#define VGT_DEBUG_REG22__cm_state23_MASK 0xc000\n#define VGT_DEBUG_REG22__cm_state23__SHIFT 0xe\n#define VGT_DEBUG_REG22__cm_state24_MASK 0x30000\n#define VGT_DEBUG_REG22__cm_state24__SHIFT 0x10\n#define VGT_DEBUG_REG22__cm_state25_MASK 0xc0000\n#define VGT_DEBUG_REG22__cm_state25__SHIFT 0x12\n#define VGT_DEBUG_REG22__cm_state26_MASK 0x300000\n#define VGT_DEBUG_REG22__cm_state26__SHIFT 0x14\n#define VGT_DEBUG_REG22__cm_state27_MASK 0xc00000\n#define VGT_DEBUG_REG22__cm_state27__SHIFT 0x16\n#define VGT_DEBUG_REG22__cm_state28_MASK 0x3000000\n#define VGT_DEBUG_REG22__cm_state28__SHIFT 0x18\n#define VGT_DEBUG_REG22__cm_state29_MASK 0xc000000\n#define VGT_DEBUG_REG22__cm_state29__SHIFT 0x1a\n#define VGT_DEBUG_REG22__cm_state30_MASK 0x30000000\n#define VGT_DEBUG_REG22__cm_state30__SHIFT 0x1c\n#define VGT_DEBUG_REG22__cm_state31_MASK 0xc0000000\n#define VGT_DEBUG_REG22__cm_state31__SHIFT 0x1e\n#define VGT_DEBUG_REG23__frmt_busy_MASK 0x1\n#define VGT_DEBUG_REG23__frmt_busy__SHIFT 0x0\n#define VGT_DEBUG_REG23__rcm_frmt_vert_rtr_MASK 0x2\n#define VGT_DEBUG_REG23__rcm_frmt_vert_rtr__SHIFT 0x1\n#define VGT_DEBUG_REG23__rcm_frmt_prim_rtr_MASK 0x4\n#define VGT_DEBUG_REG23__rcm_frmt_prim_rtr__SHIFT 0x2\n#define VGT_DEBUG_REG23__prim_r3_rtr_MASK 0x8\n#define VGT_DEBUG_REG23__prim_r3_rtr__SHIFT 0x3\n#define VGT_DEBUG_REG23__prim_r2_rtr_MASK 0x10\n#define VGT_DEBUG_REG23__prim_r2_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG23__vert_r3_rtr_MASK 0x20\n#define VGT_DEBUG_REG23__vert_r3_rtr__SHIFT 0x5\n#define VGT_DEBUG_REG23__vert_r2_rtr_MASK 0x40\n#define VGT_DEBUG_REG23__vert_r2_rtr__SHIFT 0x6\n#define VGT_DEBUG_REG23__vert_r1_rtr_MASK 0x80\n#define VGT_DEBUG_REG23__vert_r1_rtr__SHIFT 0x7\n#define VGT_DEBUG_REG23__vert_r0_rtr_MASK 0x100\n#define VGT_DEBUG_REG23__vert_r0_rtr__SHIFT 0x8\n#define VGT_DEBUG_REG23__prim_fifo_empty_MASK 0x200\n#define VGT_DEBUG_REG23__prim_fifo_empty__SHIFT 0x9\n#define VGT_DEBUG_REG23__prim_fifo_full_MASK 0x400\n#define VGT_DEBUG_REG23__prim_fifo_full__SHIFT 0xa\n#define VGT_DEBUG_REG23__vert_dr_r2_q_MASK 0x800\n#define VGT_DEBUG_REG23__vert_dr_r2_q__SHIFT 0xb\n#define VGT_DEBUG_REG23__prim_dr_r2_q_MASK 0x1000\n#define VGT_DEBUG_REG23__prim_dr_r2_q__SHIFT 0xc\n#define VGT_DEBUG_REG23__vert_dr_r1_q_MASK 0x2000\n#define VGT_DEBUG_REG23__vert_dr_r1_q__SHIFT 0xd\n#define VGT_DEBUG_REG23__vert_dr_r0_q_MASK 0x4000\n#define VGT_DEBUG_REG23__vert_dr_r0_q__SHIFT 0xe\n#define VGT_DEBUG_REG23__new_verts_r2_q_MASK 0x18000\n#define VGT_DEBUG_REG23__new_verts_r2_q__SHIFT 0xf\n#define VGT_DEBUG_REG23__verts_sent_r2_q_MASK 0x1e0000\n#define VGT_DEBUG_REG23__verts_sent_r2_q__SHIFT 0x11\n#define VGT_DEBUG_REG23__prim_state_sel_r2_q_MASK 0xe00000\n#define VGT_DEBUG_REG23__prim_state_sel_r2_q__SHIFT 0x15\n#define VGT_DEBUG_REG23__SPARE_MASK 0xff000000\n#define VGT_DEBUG_REG23__SPARE__SHIFT 0x18\n#define VGT_DEBUG_REG24__avail_es_rb_space_r0_q_23_0_MASK 0xffffff\n#define VGT_DEBUG_REG24__avail_es_rb_space_r0_q_23_0__SHIFT 0x0\n#define VGT_DEBUG_REG24__dependent_st_cut_mode_q_MASK 0x3000000\n#define VGT_DEBUG_REG24__dependent_st_cut_mode_q__SHIFT 0x18\n#define VGT_DEBUG_REG24__SPARE31_MASK 0xfc000000\n#define VGT_DEBUG_REG24__SPARE31__SHIFT 0x1a\n#define VGT_DEBUG_REG25__avail_gs_rb_space_r0_q_25_0_MASK 0x3ffffff\n#define VGT_DEBUG_REG25__avail_gs_rb_space_r0_q_25_0__SHIFT 0x0\n#define VGT_DEBUG_REG25__active_sm_r0_q_MASK 0x3c000000\n#define VGT_DEBUG_REG25__active_sm_r0_q__SHIFT 0x1a\n#define VGT_DEBUG_REG25__add_gs_rb_space_r1_q_MASK 0x40000000\n#define VGT_DEBUG_REG25__add_gs_rb_space_r1_q__SHIFT 0x1e\n#define VGT_DEBUG_REG25__add_gs_rb_space_r0_q_MASK 0x80000000\n#define VGT_DEBUG_REG25__add_gs_rb_space_r0_q__SHIFT 0x1f\n#define VGT_DEBUG_REG26__cm_state0_MASK 0x3\n#define VGT_DEBUG_REG26__cm_state0__SHIFT 0x0\n#define VGT_DEBUG_REG26__cm_state1_MASK 0xc\n#define VGT_DEBUG_REG26__cm_state1__SHIFT 0x2\n#define VGT_DEBUG_REG26__cm_state2_MASK 0x30\n#define VGT_DEBUG_REG26__cm_state2__SHIFT 0x4\n#define VGT_DEBUG_REG26__cm_state3_MASK 0xc0\n#define VGT_DEBUG_REG26__cm_state3__SHIFT 0x6\n#define VGT_DEBUG_REG26__cm_state4_MASK 0x300\n#define VGT_DEBUG_REG26__cm_state4__SHIFT 0x8\n#define VGT_DEBUG_REG26__cm_state5_MASK 0xc00\n#define VGT_DEBUG_REG26__cm_state5__SHIFT 0xa\n#define VGT_DEBUG_REG26__cm_state6_MASK 0x3000\n#define VGT_DEBUG_REG26__cm_state6__SHIFT 0xc\n#define VGT_DEBUG_REG26__cm_state7_MASK 0xc000\n#define VGT_DEBUG_REG26__cm_state7__SHIFT 0xe\n#define VGT_DEBUG_REG26__cm_state8_MASK 0x30000\n#define VGT_DEBUG_REG26__cm_state8__SHIFT 0x10\n#define VGT_DEBUG_REG26__cm_state9_MASK 0xc0000\n#define VGT_DEBUG_REG26__cm_state9__SHIFT 0x12\n#define VGT_DEBUG_REG26__cm_state10_MASK 0x300000\n#define VGT_DEBUG_REG26__cm_state10__SHIFT 0x14\n#define VGT_DEBUG_REG26__cm_state11_MASK 0xc00000\n#define VGT_DEBUG_REG26__cm_state11__SHIFT 0x16\n#define VGT_DEBUG_REG26__cm_state12_MASK 0x3000000\n#define VGT_DEBUG_REG26__cm_state12__SHIFT 0x18\n#define VGT_DEBUG_REG26__cm_state13_MASK 0xc000000\n#define VGT_DEBUG_REG26__cm_state13__SHIFT 0x1a\n#define VGT_DEBUG_REG26__cm_state14_MASK 0x30000000\n#define VGT_DEBUG_REG26__cm_state14__SHIFT 0x1c\n#define VGT_DEBUG_REG26__cm_state15_MASK 0xc0000000\n#define VGT_DEBUG_REG26__cm_state15__SHIFT 0x1e\n#define VGT_DEBUG_REG27__pipe0_dr_MASK 0x1\n#define VGT_DEBUG_REG27__pipe0_dr__SHIFT 0x0\n#define VGT_DEBUG_REG27__gsc0_dr_MASK 0x2\n#define VGT_DEBUG_REG27__gsc0_dr__SHIFT 0x1\n#define VGT_DEBUG_REG27__pipe1_dr_MASK 0x4\n#define VGT_DEBUG_REG27__pipe1_dr__SHIFT 0x2\n#define VGT_DEBUG_REG27__tm_pt_event_rtr_MASK 0x8\n#define VGT_DEBUG_REG27__tm_pt_event_rtr__SHIFT 0x3\n#define VGT_DEBUG_REG27__pipe0_rtr_MASK 0x10\n#define VGT_DEBUG_REG27__pipe0_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG27__gsc0_rtr_MASK 0x20\n#define VGT_DEBUG_REG27__gsc0_rtr__SHIFT 0x5\n#define VGT_DEBUG_REG27__pipe1_rtr_MASK 0x40\n#define VGT_DEBUG_REG27__pipe1_rtr__SHIFT 0x6\n#define VGT_DEBUG_REG27__last_indx_of_prim_p1_q_MASK 0x80\n#define VGT_DEBUG_REG27__last_indx_of_prim_p1_q__SHIFT 0x7\n#define VGT_DEBUG_REG27__indices_to_send_p0_q_MASK 0x300\n#define VGT_DEBUG_REG27__indices_to_send_p0_q__SHIFT 0x8\n#define VGT_DEBUG_REG27__event_flag_p1_q_MASK 0x400\n#define VGT_DEBUG_REG27__event_flag_p1_q__SHIFT 0xa\n#define VGT_DEBUG_REG27__eop_p1_q_MASK 0x800\n#define VGT_DEBUG_REG27__eop_p1_q__SHIFT 0xb\n#define VGT_DEBUG_REG27__gs_out_prim_type_p0_q_MASK 0x3000\n#define VGT_DEBUG_REG27__gs_out_prim_type_p0_q__SHIFT 0xc\n#define VGT_DEBUG_REG27__gsc_null_primitive_p0_q_MASK 0x4000\n#define VGT_DEBUG_REG27__gsc_null_primitive_p0_q__SHIFT 0xe\n#define VGT_DEBUG_REG27__gsc_eop_p0_q_MASK 0x8000\n#define VGT_DEBUG_REG27__gsc_eop_p0_q__SHIFT 0xf\n#define VGT_DEBUG_REG27__gsc_2cycle_output_MASK 0x10000\n#define VGT_DEBUG_REG27__gsc_2cycle_output__SHIFT 0x10\n#define VGT_DEBUG_REG27__gsc_2nd_cycle_p0_q_MASK 0x20000\n#define VGT_DEBUG_REG27__gsc_2nd_cycle_p0_q__SHIFT 0x11\n#define VGT_DEBUG_REG27__last_indx_of_vsprim_MASK 0x40000\n#define VGT_DEBUG_REG27__last_indx_of_vsprim__SHIFT 0x12\n#define VGT_DEBUG_REG27__first_vsprim_of_gsprim_p0_q_MASK 0x80000\n#define VGT_DEBUG_REG27__first_vsprim_of_gsprim_p0_q__SHIFT 0x13\n#define VGT_DEBUG_REG27__gsc_indx_count_p0_q_MASK 0x7ff00000\n#define VGT_DEBUG_REG27__gsc_indx_count_p0_q__SHIFT 0x14\n#define VGT_DEBUG_REG27__last_vsprim_of_gsprim_MASK 0x80000000\n#define VGT_DEBUG_REG27__last_vsprim_of_gsprim__SHIFT 0x1f\n#define VGT_DEBUG_REG28__con_state_q_MASK 0xf\n#define VGT_DEBUG_REG28__con_state_q__SHIFT 0x0\n#define VGT_DEBUG_REG28__second_cycle_q_MASK 0x10\n#define VGT_DEBUG_REG28__second_cycle_q__SHIFT 0x4\n#define VGT_DEBUG_REG28__process_tri_middle_p0_q_MASK 0x20\n#define VGT_DEBUG_REG28__process_tri_middle_p0_q__SHIFT 0x5\n#define VGT_DEBUG_REG28__process_tri_1st_2nd_half_p0_q_MASK 0x40\n#define VGT_DEBUG_REG28__process_tri_1st_2nd_half_p0_q__SHIFT 0x6\n#define VGT_DEBUG_REG28__process_tri_center_poly_p0_q_MASK 0x80\n#define VGT_DEBUG_REG28__process_tri_center_poly_p0_q__SHIFT 0x7\n#define VGT_DEBUG_REG28__pipe0_patch_dr_MASK 0x100\n#define VGT_DEBUG_REG28__pipe0_patch_dr__SHIFT 0x8\n#define VGT_DEBUG_REG28__pipe0_edge_dr_MASK 0x200\n#define VGT_DEBUG_REG28__pipe0_edge_dr__SHIFT 0x9\n#define VGT_DEBUG_REG28__pipe1_dr_MASK 0x400\n#define VGT_DEBUG_REG28__pipe1_dr__SHIFT 0xa\n#define VGT_DEBUG_REG28__pipe0_patch_rtr_MASK 0x800\n#define VGT_DEBUG_REG28__pipe0_patch_rtr__SHIFT 0xb\n#define VGT_DEBUG_REG28__pipe0_edge_rtr_MASK 0x1000\n#define VGT_DEBUG_REG28__pipe0_edge_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG28__pipe1_rtr_MASK 0x2000\n#define VGT_DEBUG_REG28__pipe1_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG28__outer_parity_p0_q_MASK 0x4000\n#define VGT_DEBUG_REG28__outer_parity_p0_q__SHIFT 0xe\n#define VGT_DEBUG_REG28__parallel_parity_p0_q_MASK 0x8000\n#define VGT_DEBUG_REG28__parallel_parity_p0_q__SHIFT 0xf\n#define VGT_DEBUG_REG28__first_ring_of_patch_p0_q_MASK 0x10000\n#define VGT_DEBUG_REG28__first_ring_of_patch_p0_q__SHIFT 0x10\n#define VGT_DEBUG_REG28__last_ring_of_patch_p0_q_MASK 0x20000\n#define VGT_DEBUG_REG28__last_ring_of_patch_p0_q__SHIFT 0x11\n#define VGT_DEBUG_REG28__last_edge_of_outer_ring_p0_q_MASK 0x40000\n#define VGT_DEBUG_REG28__last_edge_of_outer_ring_p0_q__SHIFT 0x12\n#define VGT_DEBUG_REG28__last_point_of_outer_ring_p1_MASK 0x80000\n#define VGT_DEBUG_REG28__last_point_of_outer_ring_p1__SHIFT 0x13\n#define VGT_DEBUG_REG28__last_point_of_inner_ring_p1_MASK 0x100000\n#define VGT_DEBUG_REG28__last_point_of_inner_ring_p1__SHIFT 0x14\n#define VGT_DEBUG_REG28__outer_edge_tf_eq_one_p0_q_MASK 0x200000\n#define VGT_DEBUG_REG28__outer_edge_tf_eq_one_p0_q__SHIFT 0x15\n#define VGT_DEBUG_REG28__advance_outer_point_p1_MASK 0x400000\n#define VGT_DEBUG_REG28__advance_outer_point_p1__SHIFT 0x16\n#define VGT_DEBUG_REG28__advance_inner_point_p1_MASK 0x800000\n#define VGT_DEBUG_REG28__advance_inner_point_p1__SHIFT 0x17\n#define VGT_DEBUG_REG28__next_ring_is_rect_p0_q_MASK 0x1000000\n#define VGT_DEBUG_REG28__next_ring_is_rect_p0_q__SHIFT 0x18\n#define VGT_DEBUG_REG28__pipe1_outer1_rtr_MASK 0x2000000\n#define VGT_DEBUG_REG28__pipe1_outer1_rtr__SHIFT 0x19\n#define VGT_DEBUG_REG28__pipe1_outer2_rtr_MASK 0x4000000\n#define VGT_DEBUG_REG28__pipe1_outer2_rtr__SHIFT 0x1a\n#define VGT_DEBUG_REG28__pipe1_inner1_rtr_MASK 0x8000000\n#define VGT_DEBUG_REG28__pipe1_inner1_rtr__SHIFT 0x1b\n#define VGT_DEBUG_REG28__pipe1_inner2_rtr_MASK 0x10000000\n#define VGT_DEBUG_REG28__pipe1_inner2_rtr__SHIFT 0x1c\n#define VGT_DEBUG_REG28__pipe1_patch_rtr_MASK 0x20000000\n#define VGT_DEBUG_REG28__pipe1_patch_rtr__SHIFT 0x1d\n#define VGT_DEBUG_REG28__pipe1_edge_rtr_MASK 0x40000000\n#define VGT_DEBUG_REG28__pipe1_edge_rtr__SHIFT 0x1e\n#define VGT_DEBUG_REG28__use_stored_inner_q_ring2_MASK 0x80000000\n#define VGT_DEBUG_REG28__use_stored_inner_q_ring2__SHIFT 0x1f\n#define VGT_DEBUG_REG29__con_state_q_MASK 0xf\n#define VGT_DEBUG_REG29__con_state_q__SHIFT 0x0\n#define VGT_DEBUG_REG29__second_cycle_q_MASK 0x10\n#define VGT_DEBUG_REG29__second_cycle_q__SHIFT 0x4\n#define VGT_DEBUG_REG29__process_tri_middle_p0_q_MASK 0x20\n#define VGT_DEBUG_REG29__process_tri_middle_p0_q__SHIFT 0x5\n#define VGT_DEBUG_REG29__process_tri_1st_2nd_half_p0_q_MASK 0x40\n#define VGT_DEBUG_REG29__process_tri_1st_2nd_half_p0_q__SHIFT 0x6\n#define VGT_DEBUG_REG29__process_tri_center_poly_p0_q_MASK 0x80\n#define VGT_DEBUG_REG29__process_tri_center_poly_p0_q__SHIFT 0x7\n#define VGT_DEBUG_REG29__pipe0_patch_dr_MASK 0x100\n#define VGT_DEBUG_REG29__pipe0_patch_dr__SHIFT 0x8\n#define VGT_DEBUG_REG29__pipe0_edge_dr_MASK 0x200\n#define VGT_DEBUG_REG29__pipe0_edge_dr__SHIFT 0x9\n#define VGT_DEBUG_REG29__pipe1_dr_MASK 0x400\n#define VGT_DEBUG_REG29__pipe1_dr__SHIFT 0xa\n#define VGT_DEBUG_REG29__pipe0_patch_rtr_MASK 0x800\n#define VGT_DEBUG_REG29__pipe0_patch_rtr__SHIFT 0xb\n#define VGT_DEBUG_REG29__pipe0_edge_rtr_MASK 0x1000\n#define VGT_DEBUG_REG29__pipe0_edge_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG29__pipe1_rtr_MASK 0x2000\n#define VGT_DEBUG_REG29__pipe1_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG29__outer_parity_p0_q_MASK 0x4000\n#define VGT_DEBUG_REG29__outer_parity_p0_q__SHIFT 0xe\n#define VGT_DEBUG_REG29__parallel_parity_p0_q_MASK 0x8000\n#define VGT_DEBUG_REG29__parallel_parity_p0_q__SHIFT 0xf\n#define VGT_DEBUG_REG29__first_ring_of_patch_p0_q_MASK 0x10000\n#define VGT_DEBUG_REG29__first_ring_of_patch_p0_q__SHIFT 0x10\n#define VGT_DEBUG_REG29__last_ring_of_patch_p0_q_MASK 0x20000\n#define VGT_DEBUG_REG29__last_ring_of_patch_p0_q__SHIFT 0x11\n#define VGT_DEBUG_REG29__last_edge_of_outer_ring_p0_q_MASK 0x40000\n#define VGT_DEBUG_REG29__last_edge_of_outer_ring_p0_q__SHIFT 0x12\n#define VGT_DEBUG_REG29__last_point_of_outer_ring_p1_MASK 0x80000\n#define VGT_DEBUG_REG29__last_point_of_outer_ring_p1__SHIFT 0x13\n#define VGT_DEBUG_REG29__last_point_of_inner_ring_p1_MASK 0x100000\n#define VGT_DEBUG_REG29__last_point_of_inner_ring_p1__SHIFT 0x14\n#define VGT_DEBUG_REG29__outer_edge_tf_eq_one_p0_q_MASK 0x200000\n#define VGT_DEBUG_REG29__outer_edge_tf_eq_one_p0_q__SHIFT 0x15\n#define VGT_DEBUG_REG29__advance_outer_point_p1_MASK 0x400000\n#define VGT_DEBUG_REG29__advance_outer_point_p1__SHIFT 0x16\n#define VGT_DEBUG_REG29__advance_inner_point_p1_MASK 0x800000\n#define VGT_DEBUG_REG29__advance_inner_point_p1__SHIFT 0x17\n#define VGT_DEBUG_REG29__next_ring_is_rect_p0_q_MASK 0x1000000\n#define VGT_DEBUG_REG29__next_ring_is_rect_p0_q__SHIFT 0x18\n#define VGT_DEBUG_REG29__pipe1_outer1_rtr_MASK 0x2000000\n#define VGT_DEBUG_REG29__pipe1_outer1_rtr__SHIFT 0x19\n#define VGT_DEBUG_REG29__pipe1_outer2_rtr_MASK 0x4000000\n#define VGT_DEBUG_REG29__pipe1_outer2_rtr__SHIFT 0x1a\n#define VGT_DEBUG_REG29__pipe1_inner1_rtr_MASK 0x8000000\n#define VGT_DEBUG_REG29__pipe1_inner1_rtr__SHIFT 0x1b\n#define VGT_DEBUG_REG29__pipe1_inner2_rtr_MASK 0x10000000\n#define VGT_DEBUG_REG29__pipe1_inner2_rtr__SHIFT 0x1c\n#define VGT_DEBUG_REG29__pipe1_patch_rtr_MASK 0x20000000\n#define VGT_DEBUG_REG29__pipe1_patch_rtr__SHIFT 0x1d\n#define VGT_DEBUG_REG29__pipe1_edge_rtr_MASK 0x40000000\n#define VGT_DEBUG_REG29__pipe1_edge_rtr__SHIFT 0x1e\n#define VGT_DEBUG_REG29__use_stored_inner_q_ring3_MASK 0x80000000\n#define VGT_DEBUG_REG29__use_stored_inner_q_ring3__SHIFT 0x1f\n#define VGT_DEBUG_REG30__pipe0_dr_MASK 0x1\n#define VGT_DEBUG_REG30__pipe0_dr__SHIFT 0x0\n#define VGT_DEBUG_REG30__pipe0_tf_dr_MASK 0x2\n#define VGT_DEBUG_REG30__pipe0_tf_dr__SHIFT 0x1\n#define VGT_DEBUG_REG30__pipe2_dr_MASK 0x4\n#define VGT_DEBUG_REG30__pipe2_dr__SHIFT 0x2\n#define VGT_DEBUG_REG30__event_or_null_p0_q_MASK 0x8\n#define VGT_DEBUG_REG30__event_or_null_p0_q__SHIFT 0x3\n#define VGT_DEBUG_REG30__pipe0_rtr_MASK 0x10\n#define VGT_DEBUG_REG30__pipe0_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG30__pipe1_rtr_MASK 0x20\n#define VGT_DEBUG_REG30__pipe1_rtr__SHIFT 0x5\n#define VGT_DEBUG_REG30__pipe1_tf_rtr_MASK 0x40\n#define VGT_DEBUG_REG30__pipe1_tf_rtr__SHIFT 0x6\n#define VGT_DEBUG_REG30__pipe2_rtr_MASK 0x80\n#define VGT_DEBUG_REG30__pipe2_rtr__SHIFT 0x7\n#define VGT_DEBUG_REG30__ttp_patch_fifo_full_MASK 0x100\n#define VGT_DEBUG_REG30__ttp_patch_fifo_full__SHIFT 0x8\n#define VGT_DEBUG_REG30__ttp_patch_fifo_empty_MASK 0x200\n#define VGT_DEBUG_REG30__ttp_patch_fifo_empty__SHIFT 0x9\n#define VGT_DEBUG_REG30__ttp_tf0_fifo_empty_MASK 0x400\n#define VGT_DEBUG_REG30__ttp_tf0_fifo_empty__SHIFT 0xa\n#define VGT_DEBUG_REG30__ttp_tf1_fifo_empty_MASK 0x800\n#define VGT_DEBUG_REG30__ttp_tf1_fifo_empty__SHIFT 0xb\n#define VGT_DEBUG_REG30__ttp_tf2_fifo_empty_MASK 0x1000\n#define VGT_DEBUG_REG30__ttp_tf2_fifo_empty__SHIFT 0xc\n#define VGT_DEBUG_REG30__ttp_tf3_fifo_empty_MASK 0x2000\n#define VGT_DEBUG_REG30__ttp_tf3_fifo_empty__SHIFT 0xd\n#define VGT_DEBUG_REG30__ttp_tf4_fifo_empty_MASK 0x4000\n#define VGT_DEBUG_REG30__ttp_tf4_fifo_empty__SHIFT 0xe\n#define VGT_DEBUG_REG30__ttp_tf5_fifo_empty_MASK 0x8000\n#define VGT_DEBUG_REG30__ttp_tf5_fifo_empty__SHIFT 0xf\n#define VGT_DEBUG_REG30__tf_fetch_state_q_MASK 0x70000\n#define VGT_DEBUG_REG30__tf_fetch_state_q__SHIFT 0x10\n#define VGT_DEBUG_REG30__last_tf_of_tg_MASK 0x80000\n#define VGT_DEBUG_REG30__last_tf_of_tg__SHIFT 0x13\n#define VGT_DEBUG_REG30__tf_pointer_p0_q_MASK 0xf00000\n#define VGT_DEBUG_REG30__tf_pointer_p0_q__SHIFT 0x14\n#define VGT_DEBUG_REG30__dynamic_hs_p0_q_MASK 0x1000000\n#define VGT_DEBUG_REG30__dynamic_hs_p0_q__SHIFT 0x18\n#define VGT_DEBUG_REG30__first_fetch_of_tg_p0_q_MASK 0x2000000\n#define VGT_DEBUG_REG30__first_fetch_of_tg_p0_q__SHIFT 0x19\n#define VGT_DEBUG_REG30__first_data_ret_of_req_p0_q_MASK 0x4000000\n#define VGT_DEBUG_REG30__first_data_ret_of_req_p0_q__SHIFT 0x1a\n#define VGT_DEBUG_REG30__first_data_chunk_invalid_p0_q_MASK 0x8000000\n#define VGT_DEBUG_REG30__first_data_chunk_invalid_p0_q__SHIFT 0x1b\n#define VGT_DEBUG_REG30__tf_xfer_count_p2_q_MASK 0x30000000\n#define VGT_DEBUG_REG30__tf_xfer_count_p2_q__SHIFT 0x1c\n#define VGT_DEBUG_REG30__pipe4_dr_MASK 0x40000000\n#define VGT_DEBUG_REG30__pipe4_dr__SHIFT 0x1e\n#define VGT_DEBUG_REG30__pipe4_rtr_MASK 0x80000000\n#define VGT_DEBUG_REG30__pipe4_rtr__SHIFT 0x1f\n#define VGT_DEBUG_REG31__pipe0_dr_MASK 0x1\n#define VGT_DEBUG_REG31__pipe0_dr__SHIFT 0x0\n#define VGT_DEBUG_REG31__pipe0_rtr_MASK 0x2\n#define VGT_DEBUG_REG31__pipe0_rtr__SHIFT 0x1\n#define VGT_DEBUG_REG31__pipe1_outer_dr_MASK 0x4\n#define VGT_DEBUG_REG31__pipe1_outer_dr__SHIFT 0x2\n#define VGT_DEBUG_REG31__pipe1_inner_dr_MASK 0x8\n#define VGT_DEBUG_REG31__pipe1_inner_dr__SHIFT 0x3\n#define VGT_DEBUG_REG31__pipe2_outer_dr_MASK 0x10\n#define VGT_DEBUG_REG31__pipe2_outer_dr__SHIFT 0x4\n#define VGT_DEBUG_REG31__pipe2_inner_dr_MASK 0x20\n#define VGT_DEBUG_REG31__pipe2_inner_dr__SHIFT 0x5\n#define VGT_DEBUG_REG31__pipe3_outer_dr_MASK 0x40\n#define VGT_DEBUG_REG31__pipe3_outer_dr__SHIFT 0x6\n#define VGT_DEBUG_REG31__pipe3_inner_dr_MASK 0x80\n#define VGT_DEBUG_REG31__pipe3_inner_dr__SHIFT 0x7\n#define VGT_DEBUG_REG31__pipe4_outer_dr_MASK 0x100\n#define VGT_DEBUG_REG31__pipe4_outer_dr__SHIFT 0x8\n#define VGT_DEBUG_REG31__pipe4_inner_dr_MASK 0x200\n#define VGT_DEBUG_REG31__pipe4_inner_dr__SHIFT 0x9\n#define VGT_DEBUG_REG31__pipe5_outer_dr_MASK 0x400\n#define VGT_DEBUG_REG31__pipe5_outer_dr__SHIFT 0xa\n#define VGT_DEBUG_REG31__pipe5_inner_dr_MASK 0x800\n#define VGT_DEBUG_REG31__pipe5_inner_dr__SHIFT 0xb\n#define VGT_DEBUG_REG31__pipe2_outer_rtr_MASK 0x1000\n#define VGT_DEBUG_REG31__pipe2_outer_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG31__pipe2_inner_rtr_MASK 0x2000\n#define VGT_DEBUG_REG31__pipe2_inner_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG31__pipe3_outer_rtr_MASK 0x4000\n#define VGT_DEBUG_REG31__pipe3_outer_rtr__SHIFT 0xe\n#define VGT_DEBUG_REG31__pipe3_inner_rtr_MASK 0x8000\n#define VGT_DEBUG_REG31__pipe3_inner_rtr__SHIFT 0xf\n#define VGT_DEBUG_REG31__pipe4_outer_rtr_MASK 0x10000\n#define VGT_DEBUG_REG31__pipe4_outer_rtr__SHIFT 0x10\n#define VGT_DEBUG_REG31__pipe4_inner_rtr_MASK 0x20000\n#define VGT_DEBUG_REG31__pipe4_inner_rtr__SHIFT 0x11\n#define VGT_DEBUG_REG31__pipe5_outer_rtr_MASK 0x40000\n#define VGT_DEBUG_REG31__pipe5_outer_rtr__SHIFT 0x12\n#define VGT_DEBUG_REG31__pipe5_inner_rtr_MASK 0x80000\n#define VGT_DEBUG_REG31__pipe5_inner_rtr__SHIFT 0x13\n#define VGT_DEBUG_REG31__pg_con_outer_point1_rts_MASK 0x100000\n#define VGT_DEBUG_REG31__pg_con_outer_point1_rts__SHIFT 0x14\n#define VGT_DEBUG_REG31__pg_con_outer_point2_rts_MASK 0x200000\n#define VGT_DEBUG_REG31__pg_con_outer_point2_rts__SHIFT 0x15\n#define VGT_DEBUG_REG31__pg_con_inner_point1_rts_MASK 0x400000\n#define VGT_DEBUG_REG31__pg_con_inner_point1_rts__SHIFT 0x16\n#define VGT_DEBUG_REG31__pg_con_inner_point2_rts_MASK 0x800000\n#define VGT_DEBUG_REG31__pg_con_inner_point2_rts__SHIFT 0x17\n#define VGT_DEBUG_REG31__pg_patch_fifo_empty_MASK 0x1000000\n#define VGT_DEBUG_REG31__pg_patch_fifo_empty__SHIFT 0x18\n#define VGT_DEBUG_REG31__pg_edge_fifo_empty_MASK 0x2000000\n#define VGT_DEBUG_REG31__pg_edge_fifo_empty__SHIFT 0x19\n#define VGT_DEBUG_REG31__pg_inner3_perp_fifo_empty_MASK 0x4000000\n#define VGT_DEBUG_REG31__pg_inner3_perp_fifo_empty__SHIFT 0x1a\n#define VGT_DEBUG_REG31__pg_patch_fifo_full_MASK 0x8000000\n#define VGT_DEBUG_REG31__pg_patch_fifo_full__SHIFT 0x1b\n#define VGT_DEBUG_REG31__pg_edge_fifo_full_MASK 0x10000000\n#define VGT_DEBUG_REG31__pg_edge_fifo_full__SHIFT 0x1c\n#define VGT_DEBUG_REG31__pg_inner_perp_fifo_full_MASK 0x20000000\n#define VGT_DEBUG_REG31__pg_inner_perp_fifo_full__SHIFT 0x1d\n#define VGT_DEBUG_REG31__outer_ring_done_q_MASK 0x40000000\n#define VGT_DEBUG_REG31__outer_ring_done_q__SHIFT 0x1e\n#define VGT_DEBUG_REG31__inner_ring_done_q_MASK 0x80000000\n#define VGT_DEBUG_REG31__inner_ring_done_q__SHIFT 0x1f\n#define VGT_DEBUG_REG32__first_ring_of_patch_MASK 0x1\n#define VGT_DEBUG_REG32__first_ring_of_patch__SHIFT 0x0\n#define VGT_DEBUG_REG32__last_ring_of_patch_MASK 0x2\n#define VGT_DEBUG_REG32__last_ring_of_patch__SHIFT 0x1\n#define VGT_DEBUG_REG32__last_edge_of_outer_ring_MASK 0x4\n#define VGT_DEBUG_REG32__last_edge_of_outer_ring__SHIFT 0x2\n#define VGT_DEBUG_REG32__last_point_of_outer_edge_MASK 0x8\n#define VGT_DEBUG_REG32__last_point_of_outer_edge__SHIFT 0x3\n#define VGT_DEBUG_REG32__last_edge_of_inner_ring_MASK 0x10\n#define VGT_DEBUG_REG32__last_edge_of_inner_ring__SHIFT 0x4\n#define VGT_DEBUG_REG32__last_point_of_inner_edge_MASK 0x20\n#define VGT_DEBUG_REG32__last_point_of_inner_edge__SHIFT 0x5\n#define VGT_DEBUG_REG32__last_patch_of_tg_p0_q_MASK 0x40\n#define VGT_DEBUG_REG32__last_patch_of_tg_p0_q__SHIFT 0x6\n#define VGT_DEBUG_REG32__event_null_special_p0_q_MASK 0x80\n#define VGT_DEBUG_REG32__event_null_special_p0_q__SHIFT 0x7\n#define VGT_DEBUG_REG32__event_flag_p5_q_MASK 0x100\n#define VGT_DEBUG_REG32__event_flag_p5_q__SHIFT 0x8\n#define VGT_DEBUG_REG32__first_point_of_patch_p5_q_MASK 0x200\n#define VGT_DEBUG_REG32__first_point_of_patch_p5_q__SHIFT 0x9\n#define VGT_DEBUG_REG32__first_point_of_edge_p5_q_MASK 0x400\n#define VGT_DEBUG_REG32__first_point_of_edge_p5_q__SHIFT 0xa\n#define VGT_DEBUG_REG32__last_patch_of_tg_p5_q_MASK 0x800\n#define VGT_DEBUG_REG32__last_patch_of_tg_p5_q__SHIFT 0xb\n#define VGT_DEBUG_REG32__tess_topology_p5_q_MASK 0x3000\n#define VGT_DEBUG_REG32__tess_topology_p5_q__SHIFT 0xc\n#define VGT_DEBUG_REG32__pipe5_inner3_rtr_MASK 0x4000\n#define VGT_DEBUG_REG32__pipe5_inner3_rtr__SHIFT 0xe\n#define VGT_DEBUG_REG32__pipe5_inner2_rtr_MASK 0x8000\n#define VGT_DEBUG_REG32__pipe5_inner2_rtr__SHIFT 0xf\n#define VGT_DEBUG_REG32__pg_edge_fifo3_full_MASK 0x10000\n#define VGT_DEBUG_REG32__pg_edge_fifo3_full__SHIFT 0x10\n#define VGT_DEBUG_REG32__pg_edge_fifo2_full_MASK 0x20000\n#define VGT_DEBUG_REG32__pg_edge_fifo2_full__SHIFT 0x11\n#define VGT_DEBUG_REG32__pg_inner3_point_fifo_full_MASK 0x40000\n#define VGT_DEBUG_REG32__pg_inner3_point_fifo_full__SHIFT 0x12\n#define VGT_DEBUG_REG32__pg_outer3_point_fifo_full_MASK 0x80000\n#define VGT_DEBUG_REG32__pg_outer3_point_fifo_full__SHIFT 0x13\n#define VGT_DEBUG_REG32__pg_inner2_point_fifo_full_MASK 0x100000\n#define VGT_DEBUG_REG32__pg_inner2_point_fifo_full__SHIFT 0x14\n#define VGT_DEBUG_REG32__pg_outer2_point_fifo_full_MASK 0x200000\n#define VGT_DEBUG_REG32__pg_outer2_point_fifo_full__SHIFT 0x15\n#define VGT_DEBUG_REG32__pg_inner_point_fifo_full_MASK 0x400000\n#define VGT_DEBUG_REG32__pg_inner_point_fifo_full__SHIFT 0x16\n#define VGT_DEBUG_REG32__pg_outer_point_fifo_full_MASK 0x800000\n#define VGT_DEBUG_REG32__pg_outer_point_fifo_full__SHIFT 0x17\n#define VGT_DEBUG_REG32__inner2_fifos_rtr_MASK 0x1000000\n#define VGT_DEBUG_REG32__inner2_fifos_rtr__SHIFT 0x18\n#define VGT_DEBUG_REG32__inner_fifos_rtr_MASK 0x2000000\n#define VGT_DEBUG_REG32__inner_fifos_rtr__SHIFT 0x19\n#define VGT_DEBUG_REG32__outer_fifos_rtr_MASK 0x4000000\n#define VGT_DEBUG_REG32__outer_fifos_rtr__SHIFT 0x1a\n#define VGT_DEBUG_REG32__fifos_rtr_MASK 0x8000000\n#define VGT_DEBUG_REG32__fifos_rtr__SHIFT 0x1b\n#define VGT_DEBUG_REG32__SPARE_MASK 0xf0000000\n#define VGT_DEBUG_REG32__SPARE__SHIFT 0x1c\n#define VGT_DEBUG_REG33__pipe0_patch_dr_MASK 0x1\n#define VGT_DEBUG_REG33__pipe0_patch_dr__SHIFT 0x0\n#define VGT_DEBUG_REG33__ring3_pipe1_dr_MASK 0x2\n#define VGT_DEBUG_REG33__ring3_pipe1_dr__SHIFT 0x1\n#define VGT_DEBUG_REG33__pipe1_dr_MASK 0x4\n#define VGT_DEBUG_REG33__pipe1_dr__SHIFT 0x2\n#define VGT_DEBUG_REG33__pipe2_dr_MASK 0x8\n#define VGT_DEBUG_REG33__pipe2_dr__SHIFT 0x3\n#define VGT_DEBUG_REG33__pipe0_patch_rtr_MASK 0x10\n#define VGT_DEBUG_REG33__pipe0_patch_rtr__SHIFT 0x4\n#define VGT_DEBUG_REG33__ring2_pipe1_dr_MASK 0x20\n#define VGT_DEBUG_REG33__ring2_pipe1_dr__SHIFT 0x5\n#define VGT_DEBUG_REG33__ring1_pipe1_dr_MASK 0x40\n#define VGT_DEBUG_REG33__ring1_pipe1_dr__SHIFT 0x6\n#define VGT_DEBUG_REG33__pipe2_rtr_MASK 0x80\n#define VGT_DEBUG_REG33__pipe2_rtr__SHIFT 0x7\n#define VGT_DEBUG_REG33__pipe3_dr_MASK 0x100\n#define VGT_DEBUG_REG33__pipe3_dr__SHIFT 0x8\n#define VGT_DEBUG_REG33__pipe3_rtr_MASK 0x200\n#define VGT_DEBUG_REG33__pipe3_rtr__SHIFT 0x9\n#define VGT_DEBUG_REG33__ring2_in_sync_q_MASK 0x400\n#define VGT_DEBUG_REG33__ring2_in_sync_q__SHIFT 0xa\n#define VGT_DEBUG_REG33__ring1_in_sync_q_MASK 0x800\n#define VGT_DEBUG_REG33__ring1_in_sync_q__SHIFT 0xb\n#define VGT_DEBUG_REG33__pipe1_patch_rtr_MASK 0x1000\n#define VGT_DEBUG_REG33__pipe1_patch_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG33__ring3_in_sync_q_MASK 0x2000\n#define VGT_DEBUG_REG33__ring3_in_sync_q__SHIFT 0xd\n#define VGT_DEBUG_REG33__tm_te11_event_rtr_MASK 0x4000\n#define VGT_DEBUG_REG33__tm_te11_event_rtr__SHIFT 0xe\n#define VGT_DEBUG_REG33__first_prim_of_patch_q_MASK 0x8000\n#define VGT_DEBUG_REG33__first_prim_of_patch_q__SHIFT 0xf\n#define VGT_DEBUG_REG33__con_prim_fifo_full_MASK 0x10000\n#define VGT_DEBUG_REG33__con_prim_fifo_full__SHIFT 0x10\n#define VGT_DEBUG_REG33__con_vert_fifo_full_MASK 0x20000\n#define VGT_DEBUG_REG33__con_vert_fifo_full__SHIFT 0x11\n#define VGT_DEBUG_REG33__con_prim_fifo_empty_MASK 0x40000\n#define VGT_DEBUG_REG33__con_prim_fifo_empty__SHIFT 0x12\n#define VGT_DEBUG_REG33__con_vert_fifo_empty_MASK 0x80000\n#define VGT_DEBUG_REG33__con_vert_fifo_empty__SHIFT 0x13\n#define VGT_DEBUG_REG33__last_patch_of_tg_p0_q_MASK 0x100000\n#define VGT_DEBUG_REG33__last_patch_of_tg_p0_q__SHIFT 0x14\n#define VGT_DEBUG_REG33__ring3_valid_p2_MASK 0x200000\n#define VGT_DEBUG_REG33__ring3_valid_p2__SHIFT 0x15\n#define VGT_DEBUG_REG33__ring2_valid_p2_MASK 0x400000\n#define VGT_DEBUG_REG33__ring2_valid_p2__SHIFT 0x16\n#define VGT_DEBUG_REG33__ring1_valid_p2_MASK 0x800000\n#define VGT_DEBUG_REG33__ring1_valid_p2__SHIFT 0x17\n#define VGT_DEBUG_REG33__tess_type_p0_q_MASK 0x3000000\n#define VGT_DEBUG_REG33__tess_type_p0_q__SHIFT 0x18\n#define VGT_DEBUG_REG33__tess_topology_p0_q_MASK 0xc000000\n#define VGT_DEBUG_REG33__tess_topology_p0_q__SHIFT 0x1a\n#define VGT_DEBUG_REG33__te11_out_vert_gs_en_MASK 0x10000000\n#define VGT_DEBUG_REG33__te11_out_vert_gs_en__SHIFT 0x1c\n#define VGT_DEBUG_REG33__con_ring3_busy_MASK 0x20000000\n#define VGT_DEBUG_REG33__con_ring3_busy__SHIFT 0x1d\n#define VGT_DEBUG_REG33__con_ring2_busy_MASK 0x40000000\n#define VGT_DEBUG_REG33__con_ring2_busy__SHIFT 0x1e\n#define VGT_DEBUG_REG33__con_ring1_busy_MASK 0x80000000\n#define VGT_DEBUG_REG33__con_ring1_busy__SHIFT 0x1f\n#define VGT_DEBUG_REG34__con_state_q_MASK 0xf\n#define VGT_DEBUG_REG34__con_state_q__SHIFT 0x0\n#define VGT_DEBUG_REG34__second_cycle_q_MASK 0x10\n#define VGT_DEBUG_REG34__second_cycle_q__SHIFT 0x4\n#define VGT_DEBUG_REG34__process_tri_middle_p0_q_MASK 0x20\n#define VGT_DEBUG_REG34__process_tri_middle_p0_q__SHIFT 0x5\n#define VGT_DEBUG_REG34__process_tri_1st_2nd_half_p0_q_MASK 0x40\n#define VGT_DEBUG_REG34__process_tri_1st_2nd_half_p0_q__SHIFT 0x6\n#define VGT_DEBUG_REG34__process_tri_center_poly_p0_q_MASK 0x80\n#define VGT_DEBUG_REG34__process_tri_center_poly_p0_q__SHIFT 0x7\n#define VGT_DEBUG_REG34__pipe0_patch_dr_MASK 0x100\n#define VGT_DEBUG_REG34__pipe0_patch_dr__SHIFT 0x8\n#define VGT_DEBUG_REG34__pipe0_edge_dr_MASK 0x200\n#define VGT_DEBUG_REG34__pipe0_edge_dr__SHIFT 0x9\n#define VGT_DEBUG_REG34__pipe1_dr_MASK 0x400\n#define VGT_DEBUG_REG34__pipe1_dr__SHIFT 0xa\n#define VGT_DEBUG_REG34__pipe0_patch_rtr_MASK 0x800\n#define VGT_DEBUG_REG34__pipe0_patch_rtr__SHIFT 0xb\n#define VGT_DEBUG_REG34__pipe0_edge_rtr_MASK 0x1000\n#define VGT_DEBUG_REG34__pipe0_edge_rtr__SHIFT 0xc\n#define VGT_DEBUG_REG34__pipe1_rtr_MASK 0x2000\n#define VGT_DEBUG_REG34__pipe1_rtr__SHIFT 0xd\n#define VGT_DEBUG_REG34__outer_parity_p0_q_MASK 0x4000\n#define VGT_DEBUG_REG34__outer_parity_p0_q__SHIFT 0xe\n#define VGT_DEBUG_REG34__parallel_parity_p0_q_MASK 0x8000\n#define VGT_DEBUG_REG34__parallel_parity_p0_q__SHIFT 0xf\n#define VGT_DEBUG_REG34__first_ring_of_patch_p0_q_MASK 0x10000\n#define VGT_DEBUG_REG34__first_ring_of_patch_p0_q__SHIFT 0x10\n#define VGT_DEBUG_REG34__last_ring_of_patch_p0_q_MASK 0x20000\n#define VGT_DEBUG_REG34__last_ring_of_patch_p0_q__SHIFT 0x11\n#define VGT_DEBUG_REG34__last_edge_of_outer_ring_p0_q_MASK 0x40000\n#define VGT_DEBUG_REG34__last_edge_of_outer_ring_p0_q__SHIFT 0x12\n#define VGT_DEBUG_REG34__last_point_of_outer_ring_p1_MASK 0x80000\n#define VGT_DEBUG_REG34__last_point_of_outer_ring_p1__SHIFT 0x13\n#define VGT_DEBUG_REG34__last_point_of_inner_ring_p1_MASK 0x100000\n#define VGT_DEBUG_REG34__last_point_of_inner_ring_p1__SHIFT 0x14\n#define VGT_DEBUG_REG34__outer_edge_tf_eq_one_p0_q_MASK 0x200000\n#define VGT_DEBUG_REG34__outer_edge_tf_eq_one_p0_q__SHIFT 0x15\n#define VGT_DEBUG_REG34__advance_outer_point_p1_MASK 0x400000\n#define VGT_DEBUG_REG34__advance_outer_point_p1__SHIFT 0x16\n#define VGT_DEBUG_REG34__advance_inner_point_p1_MASK 0x800000\n#define VGT_DEBUG_REG34__advance_inner_point_p1__SHIFT 0x17\n#define VGT_DEBUG_REG34__next_ring_is_rect_p0_q_MASK 0x1000000\n#define VGT_DEBUG_REG34__next_ring_is_rect_p0_q__SHIFT 0x18\n#define VGT_DEBUG_REG34__pipe1_outer1_rtr_MASK 0x2000000\n#define VGT_DEBUG_REG34__pipe1_outer1_rtr__SHIFT 0x19\n#define VGT_DEBUG_REG34__pipe1_outer2_rtr_MASK 0x4000000\n#define VGT_DEBUG_REG34__pipe1_outer2_rtr__SHIFT 0x1a\n#define VGT_DEBUG_REG34__pipe1_inner1_rtr_MASK 0x8000000\n#define VGT_DEBUG_REG34__pipe1_inner1_rtr__SHIFT 0x1b\n#define VGT_DEBUG_REG34__pipe1_inner2_rtr_MASK 0x10000000\n#define VGT_DEBUG_REG34__pipe1_inner2_rtr__SHIFT 0x1c\n#define VGT_DEBUG_REG34__pipe1_patch_rtr_MASK 0x20000000\n#define VGT_DEBUG_REG34__pipe1_patch_rtr__SHIFT 0x1d\n#define VGT_DEBUG_REG34__pipe1_edge_rtr_MASK 0x40000000\n#define VGT_DEBUG_REG34__pipe1_edge_rtr__SHIFT 0x1e\n#define VGT_DEBUG_REG34__use_stored_inner_q_ring1_MASK 0x80000000\n#define VGT_DEBUG_REG34__use_stored_inner_q_ring1__SHIFT 0x1f\n#define VGT_DEBUG_REG35__pipe0_dr_MASK 0x1\n#define VGT_DEBUG_REG35__pipe0_dr__SHIFT 0x0\n#define VGT_DEBUG_REG35__pipe1_dr_MASK 0x2\n#define VGT_DEBUG_REG35__pipe1_dr__SHIFT 0x1\n#define VGT_DEBUG_REG35__pipe0_rtr_MASK 0x4\n#define VGT_DEBUG_REG35__pipe0_rtr__SHIFT 0x2\n#define VGT_DEBUG_REG35__pipe1_rtr_MASK 0x8\n#define VGT_DEBUG_REG35__pipe1_rtr__SHIFT 0x3\n#define VGT_DEBUG_REG35__tfreq_tg_fifo_empty_MASK 0x10\n#define VGT_DEBUG_REG35__tfreq_tg_fifo_empty__SHIFT 0x4\n#define VGT_DEBUG_REG35__tfreq_tg_fifo_full_MASK 0x20\n#define VGT_DEBUG_REG35__tfreq_tg_fifo_full__SHIFT 0x5\n#define VGT_DEBUG_REG35__tf_data_fifo_busy_q_MASK 0x40\n#define VGT_DEBUG_REG35__tf_data_fifo_busy_q__SHIFT 0x6\n#define VGT_DEBUG_REG35__tf_data_fifo_rtr_q_MASK 0x80\n#define VGT_DEBUG_REG35__tf_data_fifo_rtr_q__SHIFT 0x7\n#define VGT_DEBUG_REG35__tf_skid_fifo_empty_MASK 0x100\n#define VGT_DEBUG_REG35__tf_skid_fifo_empty__SHIFT 0x8\n#define VGT_DEBUG_REG35__tf_skid_fifo_full_MASK 0x200\n#define VGT_DEBUG_REG35__tf_skid_fifo_full__SHIFT 0x9\n#define VGT_DEBUG_REG35__vgt_tc_rdreq_rtr_q_MASK 0x400\n#define VGT_DEBUG_REG35__vgt_tc_rdreq_rtr_q__SHIFT 0xa\n#define VGT_DEBUG_REG35__last_req_of_tg_p2_MASK 0x800\n#define VGT_DEBUG_REG35__last_req_of_tg_p2__SHIFT 0xb\n#define VGT_DEBUG_REG35__spi_vgt_hs_done_cnt_q_MASK 0x3f000\n#define VGT_DEBUG_REG35__spi_vgt_hs_done_cnt_q__SHIFT 0xc\n#define VGT_DEBUG_REG35__event_flag_p1_q_MASK 0x40000\n#define VGT_DEBUG_REG35__event_flag_p1_q__SHIFT 0x12\n#define VGT_DEBUG_REG35__null_flag_p1_q_MASK 0x80000\n#define VGT_DEBUG_REG35__null_flag_p1_q__SHIFT 0x13\n#define VGT_DEBUG_REG35__tf_data_fifo_cnt_q_MASK 0x7f00000\n#define VGT_DEBUG_REG35__tf_data_fifo_cnt_q__SHIFT 0x14\n#define VGT_DEBUG_REG35__second_tf_ret_data_q_MASK 0x8000000\n#define VGT_DEBUG_REG35__second_tf_ret_data_q__SHIFT 0x1b\n#define VGT_DEBUG_REG35__first_req_of_tg_p1_q_MASK 0x10000000\n#define VGT_DEBUG_REG35__first_req_of_tg_p1_q__SHIFT 0x1c\n#define VGT_DEBUG_REG35__VGT_TC_rdreq_send_out_MASK 0x20000000\n#define VGT_DEBUG_REG35__VGT_TC_rdreq_send_out__SHIFT 0x1d\n#define VGT_DEBUG_REG35__VGT_TC_rdnfo_stall_out_MASK 0x40000000\n#define VGT_DEBUG_REG35__VGT_TC_rdnfo_stall_out__SHIFT 0x1e\n#define VGT_DEBUG_REG35__TC_VGT_rdret_data_in_MASK 0x80000000\n#define VGT_DEBUG_REG35__TC_VGT_rdret_data_in__SHIFT 0x1f\n#define VGT_PERFCOUNTER_SEID_MASK__PERF_SEID_IGNORE_MASK_MASK 0xff\n#define VGT_PERFCOUNTER_SEID_MASK__PERF_SEID_IGNORE_MASK__SHIFT 0x0\n#define VGT_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define VGT_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define VGT_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define VGT_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define VGT_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define VGT_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define VGT_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define VGT_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define VGT_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define VGT_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define VGT_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0x3ff\n#define VGT_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define VGT_PERFCOUNTER1_SELECT__PERF_SEL1_MASK 0xffc00\n#define VGT_PERFCOUNTER1_SELECT__PERF_SEL1__SHIFT 0xa\n#define VGT_PERFCOUNTER1_SELECT__CNTR_MODE_MASK 0xf00000\n#define VGT_PERFCOUNTER1_SELECT__CNTR_MODE__SHIFT 0x14\n#define VGT_PERFCOUNTER1_SELECT__PERF_MODE1_MASK 0xf000000\n#define VGT_PERFCOUNTER1_SELECT__PERF_MODE1__SHIFT 0x18\n#define VGT_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define VGT_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define VGT_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0xff\n#define VGT_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define VGT_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define VGT_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define VGT_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0xff\n#define VGT_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define VGT_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define VGT_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define VGT_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define VGT_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define VGT_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define VGT_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define VGT_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define VGT_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define VGT_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define VGT_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define VGT_PERFCOUNTER1_SELECT1__PERF_SEL2_MASK 0x3ff\n#define VGT_PERFCOUNTER1_SELECT1__PERF_SEL2__SHIFT 0x0\n#define VGT_PERFCOUNTER1_SELECT1__PERF_SEL3_MASK 0xffc00\n#define VGT_PERFCOUNTER1_SELECT1__PERF_SEL3__SHIFT 0xa\n#define VGT_PERFCOUNTER1_SELECT1__PERF_MODE3_MASK 0xf000000\n#define VGT_PERFCOUNTER1_SELECT1__PERF_MODE3__SHIFT 0x18\n#define VGT_PERFCOUNTER1_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define VGT_PERFCOUNTER1_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define VGT_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define VGT_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define VGT_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define VGT_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define VGT_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define VGT_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define VGT_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define VGT_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define VGT_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define VGT_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define VGT_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define VGT_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define VGT_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define VGT_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define VGT_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define VGT_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define IA_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0x3ff\n#define IA_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define IA_PERFCOUNTER0_SELECT__PERF_SEL1_MASK 0xffc00\n#define IA_PERFCOUNTER0_SELECT__PERF_SEL1__SHIFT 0xa\n#define IA_PERFCOUNTER0_SELECT__CNTR_MODE_MASK 0xf00000\n#define IA_PERFCOUNTER0_SELECT__CNTR_MODE__SHIFT 0x14\n#define IA_PERFCOUNTER0_SELECT__PERF_MODE1_MASK 0xf000000\n#define IA_PERFCOUNTER0_SELECT__PERF_MODE1__SHIFT 0x18\n#define IA_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define IA_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define IA_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0xff\n#define IA_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define IA_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define IA_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define IA_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0xff\n#define IA_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define IA_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define IA_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define IA_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0xff\n#define IA_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define IA_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define IA_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define IA_PERFCOUNTER0_SELECT1__PERF_SEL2_MASK 0x3ff\n#define IA_PERFCOUNTER0_SELECT1__PERF_SEL2__SHIFT 0x0\n#define IA_PERFCOUNTER0_SELECT1__PERF_SEL3_MASK 0xffc00\n#define IA_PERFCOUNTER0_SELECT1__PERF_SEL3__SHIFT 0xa\n#define IA_PERFCOUNTER0_SELECT1__PERF_MODE3_MASK 0xf000000\n#define IA_PERFCOUNTER0_SELECT1__PERF_MODE3__SHIFT 0x18\n#define IA_PERFCOUNTER0_SELECT1__PERF_MODE2_MASK 0xf0000000\n#define IA_PERFCOUNTER0_SELECT1__PERF_MODE2__SHIFT 0x1c\n#define IA_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define IA_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define IA_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define IA_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define IA_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define IA_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define IA_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define IA_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define IA_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define IA_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define IA_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define IA_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define IA_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define IA_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define IA_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define IA_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define WD_PERFCOUNTER0_SELECT__PERF_SEL_MASK 0xff\n#define WD_PERFCOUNTER0_SELECT__PERF_SEL__SHIFT 0x0\n#define WD_PERFCOUNTER0_SELECT__PERF_MODE_MASK 0xf0000000\n#define WD_PERFCOUNTER0_SELECT__PERF_MODE__SHIFT 0x1c\n#define WD_PERFCOUNTER1_SELECT__PERF_SEL_MASK 0xff\n#define WD_PERFCOUNTER1_SELECT__PERF_SEL__SHIFT 0x0\n#define WD_PERFCOUNTER1_SELECT__PERF_MODE_MASK 0xf0000000\n#define WD_PERFCOUNTER1_SELECT__PERF_MODE__SHIFT 0x1c\n#define WD_PERFCOUNTER2_SELECT__PERF_SEL_MASK 0xff\n#define WD_PERFCOUNTER2_SELECT__PERF_SEL__SHIFT 0x0\n#define WD_PERFCOUNTER2_SELECT__PERF_MODE_MASK 0xf0000000\n#define WD_PERFCOUNTER2_SELECT__PERF_MODE__SHIFT 0x1c\n#define WD_PERFCOUNTER3_SELECT__PERF_SEL_MASK 0xff\n#define WD_PERFCOUNTER3_SELECT__PERF_SEL__SHIFT 0x0\n#define WD_PERFCOUNTER3_SELECT__PERF_MODE_MASK 0xf0000000\n#define WD_PERFCOUNTER3_SELECT__PERF_MODE__SHIFT 0x1c\n#define WD_PERFCOUNTER0_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define WD_PERFCOUNTER0_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define WD_PERFCOUNTER1_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define WD_PERFCOUNTER1_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define WD_PERFCOUNTER2_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define WD_PERFCOUNTER2_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define WD_PERFCOUNTER3_LO__PERFCOUNTER_LO_MASK 0xffffffff\n#define WD_PERFCOUNTER3_LO__PERFCOUNTER_LO__SHIFT 0x0\n#define WD_PERFCOUNTER0_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define WD_PERFCOUNTER0_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define WD_PERFCOUNTER1_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define WD_PERFCOUNTER1_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define WD_PERFCOUNTER2_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define WD_PERFCOUNTER2_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define WD_PERFCOUNTER3_HI__PERFCOUNTER_HI_MASK 0xffffffff\n#define WD_PERFCOUNTER3_HI__PERFCOUNTER_HI__SHIFT 0x0\n#define DIDT_IND_INDEX__DIDT_IND_INDEX_MASK 0xffffffff\n#define DIDT_IND_INDEX__DIDT_IND_INDEX__SHIFT 0x0\n#define DIDT_IND_DATA__DIDT_IND_DATA_MASK 0xffffffff\n#define DIDT_IND_DATA__DIDT_IND_DATA__SHIFT 0x0\n#define DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK 0x1\n#define DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT 0x0\n#define DIDT_SQ_CTRL0__USE_REF_CLOCK_MASK 0x2\n#define DIDT_SQ_CTRL0__USE_REF_CLOCK__SHIFT 0x1\n#define DIDT_SQ_CTRL0__PHASE_OFFSET_MASK 0xc\n#define DIDT_SQ_CTRL0__PHASE_OFFSET__SHIFT 0x2\n#define DIDT_SQ_CTRL0__DIDT_CTRL_RST_MASK 0x10\n#define DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT 0x4\n#define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20\n#define DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5\n#define DIDT_SQ_CTRL1__MIN_POWER_MASK 0xffff\n#define DIDT_SQ_CTRL1__MIN_POWER__SHIFT 0x0\n#define DIDT_SQ_CTRL1__MAX_POWER_MASK 0xffff0000\n#define DIDT_SQ_CTRL1__MAX_POWER__SHIFT 0x10\n#define DIDT_SQ_CTRL2__MAX_POWER_DELTA_MASK 0x3fff\n#define DIDT_SQ_CTRL2__MAX_POWER_DELTA__SHIFT 0x0\n#define DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK 0x3ff0000\n#define DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT 0x10\n#define DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK 0x78000000\n#define DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT 0x1b\n#define DIDT_SQ_WEIGHT0_3__WEIGHT0_MASK 0xff\n#define DIDT_SQ_WEIGHT0_3__WEIGHT0__SHIFT 0x0\n#define DIDT_SQ_WEIGHT0_3__WEIGHT1_MASK 0xff00\n#define DIDT_SQ_WEIGHT0_3__WEIGHT1__SHIFT 0x8\n#define DIDT_SQ_WEIGHT0_3__WEIGHT2_MASK 0xff0000\n#define DIDT_SQ_WEIGHT0_3__WEIGHT2__SHIFT 0x10\n#define DIDT_SQ_WEIGHT0_3__WEIGHT3_MASK 0xff000000\n#define DIDT_SQ_WEIGHT0_3__WEIGHT3__SHIFT 0x18\n#define DIDT_SQ_WEIGHT4_7__WEIGHT4_MASK 0xff\n#define DIDT_SQ_WEIGHT4_7__WEIGHT4__SHIFT 0x0\n#define DIDT_SQ_WEIGHT4_7__WEIGHT5_MASK 0xff00\n#define DIDT_SQ_WEIGHT4_7__WEIGHT5__SHIFT 0x8\n#define DIDT_SQ_WEIGHT4_7__WEIGHT6_MASK 0xff0000\n#define DIDT_SQ_WEIGHT4_7__WEIGHT6__SHIFT 0x10\n#define DIDT_SQ_WEIGHT4_7__WEIGHT7_MASK 0xff000000\n#define DIDT_SQ_WEIGHT4_7__WEIGHT7__SHIFT 0x18\n#define DIDT_SQ_WEIGHT8_11__WEIGHT8_MASK 0xff\n#define DIDT_SQ_WEIGHT8_11__WEIGHT8__SHIFT 0x0\n#define DIDT_SQ_WEIGHT8_11__WEIGHT9_MASK 0xff00\n#define DIDT_SQ_WEIGHT8_11__WEIGHT9__SHIFT 0x8\n#define DIDT_SQ_WEIGHT8_11__WEIGHT10_MASK 0xff0000\n#define DIDT_SQ_WEIGHT8_11__WEIGHT10__SHIFT 0x10\n#define DIDT_SQ_WEIGHT8_11__WEIGHT11_MASK 0xff000000\n#define DIDT_SQ_WEIGHT8_11__WEIGHT11__SHIFT 0x18\n#define DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK 0x1\n#define DIDT_DB_CTRL0__DIDT_CTRL_EN__SHIFT 0x0\n#define DIDT_DB_CTRL0__USE_REF_CLOCK_MASK 0x2\n#define DIDT_DB_CTRL0__USE_REF_CLOCK__SHIFT 0x1\n#define DIDT_DB_CTRL0__PHASE_OFFSET_MASK 0xc\n#define DIDT_DB_CTRL0__PHASE_OFFSET__SHIFT 0x2\n#define DIDT_DB_CTRL0__DIDT_CTRL_RST_MASK 0x10\n#define DIDT_DB_CTRL0__DIDT_CTRL_RST__SHIFT 0x4\n#define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20\n#define DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5\n#define DIDT_DB_CTRL1__MIN_POWER_MASK 0xffff\n#define DIDT_DB_CTRL1__MIN_POWER__SHIFT 0x0\n#define DIDT_DB_CTRL1__MAX_POWER_MASK 0xffff0000\n#define DIDT_DB_CTRL1__MAX_POWER__SHIFT 0x10\n#define DIDT_DB_CTRL2__MAX_POWER_DELTA_MASK 0x3fff\n#define DIDT_DB_CTRL2__MAX_POWER_DELTA__SHIFT 0x0\n#define DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK 0x3ff0000\n#define DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT 0x10\n#define DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK 0x78000000\n#define DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT 0x1b\n#define DIDT_DB_WEIGHT0_3__WEIGHT0_MASK 0xff\n#define DIDT_DB_WEIGHT0_3__WEIGHT0__SHIFT 0x0\n#define DIDT_DB_WEIGHT0_3__WEIGHT1_MASK 0xff00\n#define DIDT_DB_WEIGHT0_3__WEIGHT1__SHIFT 0x8\n#define DIDT_DB_WEIGHT0_3__WEIGHT2_MASK 0xff0000\n#define DIDT_DB_WEIGHT0_3__WEIGHT2__SHIFT 0x10\n#define DIDT_DB_WEIGHT0_3__WEIGHT3_MASK 0xff000000\n#define DIDT_DB_WEIGHT0_3__WEIGHT3__SHIFT 0x18\n#define DIDT_DB_WEIGHT4_7__WEIGHT4_MASK 0xff\n#define DIDT_DB_WEIGHT4_7__WEIGHT4__SHIFT 0x0\n#define DIDT_DB_WEIGHT4_7__WEIGHT5_MASK 0xff00\n#define DIDT_DB_WEIGHT4_7__WEIGHT5__SHIFT 0x8\n#define DIDT_DB_WEIGHT4_7__WEIGHT6_MASK 0xff0000\n#define DIDT_DB_WEIGHT4_7__WEIGHT6__SHIFT 0x10\n#define DIDT_DB_WEIGHT4_7__WEIGHT7_MASK 0xff000000\n#define DIDT_DB_WEIGHT4_7__WEIGHT7__SHIFT 0x18\n#define DIDT_DB_WEIGHT8_11__WEIGHT8_MASK 0xff\n#define DIDT_DB_WEIGHT8_11__WEIGHT8__SHIFT 0x0\n#define DIDT_DB_WEIGHT8_11__WEIGHT9_MASK 0xff00\n#define DIDT_DB_WEIGHT8_11__WEIGHT9__SHIFT 0x8\n#define DIDT_DB_WEIGHT8_11__WEIGHT10_MASK 0xff0000\n#define DIDT_DB_WEIGHT8_11__WEIGHT10__SHIFT 0x10\n#define DIDT_DB_WEIGHT8_11__WEIGHT11_MASK 0xff000000\n#define DIDT_DB_WEIGHT8_11__WEIGHT11__SHIFT 0x18\n#define DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK 0x1\n#define DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT 0x0\n#define DIDT_TD_CTRL0__USE_REF_CLOCK_MASK 0x2\n#define DIDT_TD_CTRL0__USE_REF_CLOCK__SHIFT 0x1\n#define DIDT_TD_CTRL0__PHASE_OFFSET_MASK 0xc\n#define DIDT_TD_CTRL0__PHASE_OFFSET__SHIFT 0x2\n#define DIDT_TD_CTRL0__DIDT_CTRL_RST_MASK 0x10\n#define DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT 0x4\n#define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20\n#define DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5\n#define DIDT_TD_CTRL1__MIN_POWER_MASK 0xffff\n#define DIDT_TD_CTRL1__MIN_POWER__SHIFT 0x0\n#define DIDT_TD_CTRL1__MAX_POWER_MASK 0xffff0000\n#define DIDT_TD_CTRL1__MAX_POWER__SHIFT 0x10\n#define DIDT_TD_CTRL2__MAX_POWER_DELTA_MASK 0x3fff\n#define DIDT_TD_CTRL2__MAX_POWER_DELTA__SHIFT 0x0\n#define DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK 0x3ff0000\n#define DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT 0x10\n#define DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK 0x78000000\n#define DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT 0x1b\n#define DIDT_TD_WEIGHT0_3__WEIGHT0_MASK 0xff\n#define DIDT_TD_WEIGHT0_3__WEIGHT0__SHIFT 0x0\n#define DIDT_TD_WEIGHT0_3__WEIGHT1_MASK 0xff00\n#define DIDT_TD_WEIGHT0_3__WEIGHT1__SHIFT 0x8\n#define DIDT_TD_WEIGHT0_3__WEIGHT2_MASK 0xff0000\n#define DIDT_TD_WEIGHT0_3__WEIGHT2__SHIFT 0x10\n#define DIDT_TD_WEIGHT0_3__WEIGHT3_MASK 0xff000000\n#define DIDT_TD_WEIGHT0_3__WEIGHT3__SHIFT 0x18\n#define DIDT_TD_WEIGHT4_7__WEIGHT4_MASK 0xff\n#define DIDT_TD_WEIGHT4_7__WEIGHT4__SHIFT 0x0\n#define DIDT_TD_WEIGHT4_7__WEIGHT5_MASK 0xff00\n#define DIDT_TD_WEIGHT4_7__WEIGHT5__SHIFT 0x8\n#define DIDT_TD_WEIGHT4_7__WEIGHT6_MASK 0xff0000\n#define DIDT_TD_WEIGHT4_7__WEIGHT6__SHIFT 0x10\n#define DIDT_TD_WEIGHT4_7__WEIGHT7_MASK 0xff000000\n#define DIDT_TD_WEIGHT4_7__WEIGHT7__SHIFT 0x18\n#define DIDT_TD_WEIGHT8_11__WEIGHT8_MASK 0xff\n#define DIDT_TD_WEIGHT8_11__WEIGHT8__SHIFT 0x0\n#define DIDT_TD_WEIGHT8_11__WEIGHT9_MASK 0xff00\n#define DIDT_TD_WEIGHT8_11__WEIGHT9__SHIFT 0x8\n#define DIDT_TD_WEIGHT8_11__WEIGHT10_MASK 0xff0000\n#define DIDT_TD_WEIGHT8_11__WEIGHT10__SHIFT 0x10\n#define DIDT_TD_WEIGHT8_11__WEIGHT11_MASK 0xff000000\n#define DIDT_TD_WEIGHT8_11__WEIGHT11__SHIFT 0x18\n#define DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK 0x1\n#define DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT 0x0\n#define DIDT_TCP_CTRL0__USE_REF_CLOCK_MASK 0x2\n#define DIDT_TCP_CTRL0__USE_REF_CLOCK__SHIFT 0x1\n#define DIDT_TCP_CTRL0__PHASE_OFFSET_MASK 0xc\n#define DIDT_TCP_CTRL0__PHASE_OFFSET__SHIFT 0x2\n#define DIDT_TCP_CTRL0__DIDT_CTRL_RST_MASK 0x10\n#define DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT 0x4\n#define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK 0x20\n#define DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT 0x5\n#define DIDT_TCP_CTRL1__MIN_POWER_MASK 0xffff\n#define DIDT_TCP_CTRL1__MIN_POWER__SHIFT 0x0\n#define DIDT_TCP_CTRL1__MAX_POWER_MASK 0xffff0000\n#define DIDT_TCP_CTRL1__MAX_POWER__SHIFT 0x10\n#define DIDT_TCP_CTRL2__MAX_POWER_DELTA_MASK 0x3fff\n#define DIDT_TCP_CTRL2__MAX_POWER_DELTA__SHIFT 0x0\n#define DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK 0x3ff0000\n#define DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT 0x10\n#define DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK 0x78000000\n#define DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT 0x1b\n#define DIDT_TCP_WEIGHT0_3__WEIGHT0_MASK 0xff\n#define DIDT_TCP_WEIGHT0_3__WEIGHT0__SHIFT 0x0\n#define DIDT_TCP_WEIGHT0_3__WEIGHT1_MASK 0xff00\n#define DIDT_TCP_WEIGHT0_3__WEIGHT1__SHIFT 0x8\n#define DIDT_TCP_WEIGHT0_3__WEIGHT2_MASK 0xff0000\n#define DIDT_TCP_WEIGHT0_3__WEIGHT2__SHIFT 0x10\n#define DIDT_TCP_WEIGHT0_3__WEIGHT3_MASK 0xff000000\n#define DIDT_TCP_WEIGHT0_3__WEIGHT3__SHIFT 0x18\n#define DIDT_TCP_WEIGHT4_7__WEIGHT4_MASK 0xff\n#define DIDT_TCP_WEIGHT4_7__WEIGHT4__SHIFT 0x0\n#define DIDT_TCP_WEIGHT4_7__WEIGHT5_MASK 0xff00\n#define DIDT_TCP_WEIGHT4_7__WEIGHT5__SHIFT 0x8\n#define DIDT_TCP_WEIGHT4_7__WEIGHT6_MASK 0xff0000\n#define DIDT_TCP_WEIGHT4_7__WEIGHT6__SHIFT 0x10\n#define DIDT_TCP_WEIGHT4_7__WEIGHT7_MASK 0xff000000\n#define DIDT_TCP_WEIGHT4_7__WEIGHT7__SHIFT 0x18\n#define DIDT_TCP_WEIGHT8_11__WEIGHT8_MASK 0xff\n#define DIDT_TCP_WEIGHT8_11__WEIGHT8__SHIFT 0x0\n#define DIDT_TCP_WEIGHT8_11__WEIGHT9_MASK 0xff00\n#define DIDT_TCP_WEIGHT8_11__WEIGHT9__SHIFT 0x8\n#define DIDT_TCP_WEIGHT8_11__WEIGHT10_MASK 0xff0000\n#define DIDT_TCP_WEIGHT8_11__WEIGHT10__SHIFT 0x10\n#define DIDT_TCP_WEIGHT8_11__WEIGHT11_MASK 0xff000000\n#define DIDT_TCP_WEIGHT8_11__WEIGHT11__SHIFT 0x18\n\n#endif /* GFX_7_2_SH_MASK_H */\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/kfd_pm4_opcodes.h",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n\n#ifndef KFD_PM4_OPCODES_H\n#define KFD_PM4_OPCODES_H\n\nenum it_opcode_type {\n\tIT_NOP                               = 0x10,\n\tIT_SET_BASE                          = 0x11,\n\tIT_CLEAR_STATE                       = 0x12,\n\tIT_INDEX_BUFFER_SIZE                 = 0x13,\n\tIT_DISPATCH_DIRECT                   = 0x15,\n\tIT_DISPATCH_INDIRECT                 = 0x16,\n\tIT_ATOMIC_GDS                        = 0x1D,\n\tIT_OCCLUSION_QUERY                   = 0x1F,\n\tIT_SET_PREDICATION                   = 0x20,\n\tIT_REG_RMW                           = 0x21,\n\tIT_COND_EXEC                         = 0x22,\n\tIT_PRED_EXEC                         = 0x23,\n\tIT_DRAW_INDIRECT                     = 0x24,\n\tIT_DRAW_INDEX_INDIRECT               = 0x25,\n\tIT_INDEX_BASE                        = 0x26,\n\tIT_DRAW_INDEX_2                      = 0x27,\n\tIT_CONTEXT_CONTROL                   = 0x28,\n\tIT_INDEX_TYPE                        = 0x2A,\n\tIT_DRAW_INDIRECT_MULTI               = 0x2C,\n\tIT_DRAW_INDEX_AUTO                   = 0x2D,\n\tIT_NUM_INSTANCES                     = 0x2F,\n\tIT_DRAW_INDEX_MULTI_AUTO             = 0x30,\n\tIT_INDIRECT_BUFFER_CNST              = 0x33,\n\tIT_STRMOUT_BUFFER_UPDATE             = 0x34,\n\tIT_DRAW_INDEX_OFFSET_2               = 0x35,\n\tIT_DRAW_PREAMBLE                     = 0x36,\n\tIT_WRITE_DATA                        = 0x37,\n\tIT_DRAW_INDEX_INDIRECT_MULTI         = 0x38,\n\tIT_MEM_SEMAPHORE                     = 0x39,\n\tIT_COPY_DW                           = 0x3B,\n\tIT_WAIT_REG_MEM                      = 0x3C,\n\tIT_INDIRECT_BUFFER                   = 0x3F,\n\tIT_COPY_DATA                         = 0x40,\n\tIT_PFP_SYNC_ME                       = 0x42,\n\tIT_SURFACE_SYNC                      = 0x43,\n\tIT_COND_WRITE                        = 0x45,\n\tIT_EVENT_WRITE                       = 0x46,\n\tIT_EVENT_WRITE_EOP                   = 0x47,\n\tIT_EVENT_WRITE_EOS                   = 0x48,\n\tIT_RELEASE_MEM                       = 0x49,\n\tIT_PREAMBLE_CNTL                     = 0x4A,\n\tIT_DMA_DATA                          = 0x50,\n\tIT_ACQUIRE_MEM                       = 0x58,\n\tIT_REWIND                            = 0x59,\n\tIT_LOAD_UCONFIG_REG                  = 0x5E,\n\tIT_LOAD_SH_REG                       = 0x5F,\n\tIT_LOAD_CONFIG_REG                   = 0x60,\n\tIT_LOAD_CONTEXT_REG                  = 0x61,\n\tIT_SET_CONFIG_REG                    = 0x68,\n\tIT_SET_CONTEXT_REG                   = 0x69,\n\tIT_SET_CONTEXT_REG_INDIRECT          = 0x73,\n\tIT_SET_SH_REG                        = 0x76,\n\tIT_SET_SH_REG_OFFSET                 = 0x77,\n\tIT_SET_QUEUE_REG                     = 0x78,\n\tIT_SET_UCONFIG_REG                   = 0x79,\n\tIT_SCRATCH_RAM_WRITE                 = 0x7D,\n\tIT_SCRATCH_RAM_READ                  = 0x7E,\n\tIT_LOAD_CONST_RAM                    = 0x80,\n\tIT_WRITE_CONST_RAM                   = 0x81,\n\tIT_DUMP_CONST_RAM                    = 0x83,\n\tIT_INCREMENT_CE_COUNTER              = 0x84,\n\tIT_INCREMENT_DE_COUNTER              = 0x85,\n\tIT_WAIT_ON_CE_COUNTER                = 0x86,\n\tIT_WAIT_ON_DE_COUNTER_DIFF           = 0x88,\n\tIT_SWITCH_BUFFER                     = 0x8B,\n\tIT_SET_RESOURCES                     = 0xA0,\n\tIT_MAP_PROCESS                       = 0xA1,\n\tIT_MAP_QUEUES                        = 0xA2,\n\tIT_UNMAP_QUEUES                      = 0xA3,\n\tIT_QUERY_STATUS                      = 0xA4,\n\tIT_RUN_LIST                          = 0xA5,\n};\n\n#define PM4_TYPE_0 0\n#define PM4_TYPE_2 2\n#define PM4_TYPE_3 3\n\n#endif /* KFD_PM4_OPCODES_H */\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/pm4_pkt_struct_ai.h",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __PM4_PKT_STRUCT_AI_H__\n#define __PM4_PKT_STRUCT_AI_H__\n\n#ifndef PM4_MEC_RELEASE_MEM_AI_DEFINED\n#define PM4_MEC_RELEASE_MEM_AI_DEFINED\n\nenum AI_MEC_RELEASE_MEM_event_index_enum {\n     event_index__mec_release_mem__end_of_pipe = 5,\n     event_index__mec_release_mem__shader_done = 6 };\n\nenum AI_MEC_RELEASE_MEM_cache_policy_enum {\n     cache_policy__mec_release_mem__lru = 0,\n     cache_policy__mec_release_mem__stream = 1 };\n\nenum AI_MEC_RELEASE_MEM_pq_exe_status_enum {\n     pq_exe_status__mec_release_mem__default = 0,\n     pq_exe_status__mec_release_mem__phase_update = 1 };\n\nenum AI_MEC_RELEASE_MEM_dst_sel_enum {\n     dst_sel__mec_release_mem__memory_controller = 0,\n     dst_sel__mec_release_mem__tc_l2 = 1,\n     dst_sel__mec_release_mem__queue_write_pointer_register = 2,\n     dst_sel__mec_release_mem__queue_write_pointer_poll_mask_bit = 3 };\n\nenum AI_MEC_RELEASE_MEM_int_sel_enum {\n     int_sel__mec_release_mem__none = 0,\n     int_sel__mec_release_mem__send_interrupt_only = 1,\n     int_sel__mec_release_mem__send_interrupt_after_write_confirm = 2,\n     int_sel__mec_release_mem__send_data_after_write_confirm = 3,\n     int_sel__mec_release_mem__unconditionally_send_int_ctxid = 4,\n     int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_32_bit_compare = 5,\n     int_sel__mec_release_mem__conditionally_send_int_ctxid_based_on_64_bit_compare = 6 };\n\nenum AI_MEC_RELEASE_MEM_data_sel_enum {\n     data_sel__mec_release_mem__none = 0,\n     data_sel__mec_release_mem__send_32_bit_low = 1,\n     data_sel__mec_release_mem__send_64_bit_data = 2,\n     data_sel__mec_release_mem__send_gpu_clock_counter = 3,\n     data_sel__mec_release_mem__send_cp_perfcounter_hi_lo = 4,\n     data_sel__mec_release_mem__store_gds_data_to_memory = 5 };\n\n\ntypedef struct PM4_MEC_RELEASE_MEM_AI {\n    union {\n        PM4_TYPE_3_HEADER   header;\n        unsigned int        ordinal1;\n    };\n\n    union {\n        struct {\n            unsigned int event_type:6;\n            unsigned int reserved1:2;\n            AI_MEC_RELEASE_MEM_event_index_enum event_index:4;\n            unsigned int tcl1_vol_action_ena:1;\n            unsigned int tc_vol_action_ena:1;\n            unsigned int reserved2:1;\n            unsigned int tc_wb_action_ena:1;\n            unsigned int tcl1_action_ena:1;\n            unsigned int tc_action_ena:1;\n            unsigned int reserved3:1;\n            unsigned int tc_nc_action_ena:1;\n            unsigned int tc_wc_action_ena:1;\n            unsigned int tc_md_action_ena:1;\n            unsigned int reserved4:3;\n            AI_MEC_RELEASE_MEM_cache_policy_enum cache_policy:2;\n            unsigned int reserved5:2;\n            AI_MEC_RELEASE_MEM_pq_exe_status_enum pq_exe_status:1;\n            unsigned int reserved6:2;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    union {\n        struct {\n            unsigned int reserved7:16;\n            AI_MEC_RELEASE_MEM_dst_sel_enum dst_sel:2;\n            unsigned int reserved8:6;\n            AI_MEC_RELEASE_MEM_int_sel_enum int_sel:3;\n            unsigned int reserved9:2;\n            AI_MEC_RELEASE_MEM_data_sel_enum data_sel:3;\n        } bitfields3;\n        unsigned int ordinal3;\n    };\n\n    union {\n        struct {\n            unsigned int reserved10:2;\n            unsigned int address_lo_32b:30;\n        } bitfields4a;\n        struct {\n            unsigned int reserved11:3;\n            unsigned int address_lo_64b:29;\n        } bitfields4b;\n        unsigned int reserved12;\n\n        unsigned int ordinal4;\n    };\n\n    union {\n        unsigned int address_hi;\n\n        unsigned int reserved13;\n\n        unsigned int ordinal5;\n    };\n\n    union {\n        unsigned int data_lo;\n\n        unsigned int cmp_data_lo;\n\n        struct {\n            unsigned int dw_offset:16;\n            unsigned int num_dwords:16;\n        } bitfields6c;\n        unsigned int reserved14;\n\n        unsigned int ordinal6;\n    };\n\n    union {\n        unsigned int data_hi;\n\n        unsigned int cmp_data_hi;\n\n        unsigned int reserved15;\n\n        unsigned int reserved16;\n\n        unsigned int ordinal7;\n    };\n\n    unsigned int int_ctxid;\n} PM4MEC_RELEASE_MEM_AI, *PPM4MEC_RELEASE_MEM_AI;\n\n#endif  // PM4_MEC_RELEASE_MEM_AI_DEFINED\n#endif  // __PM4_PKT_STRUCT_AI_H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/pm4_pkt_struct_ci.h",
    "content": "/*\n * Copyright (C) 2012-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __PM4_PKT_STRUCT_CI_H__\n#define __PM4_PKT_STRUCT_CI_H__\n\n\nenum WRITE_DATA_CI_atc_enum { atc_write_data_NOT_USE_ATC_0 = 0, atc_write_data_USE_ATC_1 = 1 };\nenum WRITE_DATA_CI_engine_sel { engine_sel_write_data_ci_MICRO_ENGINE_0 = 0, engine_sel_write_data_ci_PREFETCH_PARSER_1 = 1, engine_sel_write_data_ci_CONST_ENG_2 = 2 };\n\ntypedef struct _PM4WRITE_DATA_CI {\n    union {\n        PM4_TYPE_3_HEADER   header;\n        unsigned int        ordinal1;\n    };\n\n    union {\n        struct {\n            unsigned int reserved1:8;\n            MEC_WRITE_DATA_dst_sel_enum dst_sel:4;\n            unsigned int reserved2:4;\n            MEC_WRITE_DATA_addr_incr_enum addr_incr:1;\n            unsigned int reserved3:3;\n            MEC_WRITE_DATA_wr_confirm_enum wr_confirm:1;\n            unsigned int reserved4:3;\n            WRITE_DATA_CI_atc_enum atc:1;\n            MEC_WRITE_DATA_cache_policy_enum cache_policy:2;\n            unsigned int volatile_setting:1;\n            unsigned int reserved5:2;\n            WRITE_DATA_CI_engine_sel engine_sel:2;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    unsigned int dst_addr_lo;\n\n    unsigned int dst_address_hi;\n\n    unsigned int data[1];    // 1..N of these fields\n}  PM4WRITE_DATA_CI, *PPM4WRITE_DATA_CI;\n\n\nenum MEC_RELEASE_MEM_CI_atc_enum { atc_mec_release_mem_ci_NOT_USE_ATC_0 = 0, atc_mec_release_mem_ci_USE_ATC_1 = 1 };\n\ntypedef struct _PM4_RELEASE_MEM_CI {\n    union {\n        PM4_TYPE_3_HEADER   header;\n        unsigned int        ordinal1;\n    };\n\n    union {\n        struct {\n            unsigned int event_type:6;\n            unsigned int reserved1:2;\n            MEC_RELEASE_MEM_event_index_enum event_index:4;\n            unsigned int l1_vol:1;\n            unsigned int l2_vol:1;\n            unsigned int reserved:1;\n            unsigned int l2_wb:1;\n            unsigned int l1_inv:1;\n            unsigned int l2_inv:1;\n            unsigned int reserved2:6;\n            MEC_RELEASE_MEM_CI_atc_enum atc:1;\n            MEC_RELEASE_MEM_cache_policy_enum cache_policy:2;\n            unsigned int volatile_setting:1;\n            unsigned int reserved3:4;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    union {\n        struct {\n            unsigned int reserved4:16;\n            MEC_RELEASE_MEM_dst_sel_enum dst_sel:2;\n            unsigned int reserved5:6;\n            MEC_RELEASE_MEM_int_sel_enum int_sel:3;\n            unsigned int reserved6:2;\n            MEC_RELEASE_MEM_data_sel_enum data_sel:3;\n        } bitfields3;\n        unsigned int ordinal3;\n    };\n\n    union {\n        struct {\n            unsigned int reserved7:2;\n            unsigned int address_lo_dword_aligned:30;\n        } bitfields4a;\n        struct {\n            unsigned int reserved8:3;\n            unsigned int address_lo_qword_aligned:29;\n        } bitfields4b;\n        unsigned int ordinal4;\n    };\n\n    unsigned int addr_hi;\n\n    union {\n        unsigned int data_lo;\n        struct {\n            unsigned int offset:16;\n            unsigned int num_dwords:16;\n        } bitfields5b;\n        unsigned int ordinal6;\n    };\n\n    unsigned int data_hi;\n}  PM4_RELEASE_MEM_CI, *PPM4_RELEASE_MEM_CI;\n\n#endif  // __PM4_PKT_STRUCT_CI_H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/pm4_pkt_struct_common.h",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __PM4_PKT_STRUCT_COMMON_H__\n#define __PM4_PKT_STRUCT_COMMON_H__\n\n#ifndef PM4_HEADER_DEFINED\n#define PM4_HEADER_DEFINED\ntypedef union PM4_TYPE_3_HEADER\n{\n    struct\n    {\n        unsigned int predicate : 1; ///< predicated version of packet when set\n        unsigned int shaderType: 1; ///< 0: Graphics, 1: Compute Shader\n        unsigned int reserved1 : 6; ///< reserved\n        unsigned int opcode    : 8; ///< IT opcode\n        unsigned int count     : 14;///< number of DWORDs - 1 in the information body.\n        unsigned int type      : 2; ///< packet identifier. It should be 3 for type 3 packets\n    };\n    unsigned int u32All;\n} PM4_TYPE_3_HEADER;\n#endif // PM4_HEADER_DEFINED\n\n//--------------------DISPATCH_DIRECT--------------------\n\n\ntypedef struct _PM4_DISPATCH_DIRECT\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    unsigned int dim_x;\n\n\n    unsigned int dim_y;\n\n\n    unsigned int dim_z;\n\n\n    unsigned int dispatch_initiator;\n\n\n}  PM4DISPATCH_DIRECT, *PPM4DISPATCH_DIRECT;\n\n//--------------------INDIRECT_BUFFER--------------------\n\nenum INDIRECT_BUFFER_cache_policy_enum { cache_policy_indirect_buffer_LRU_0 = 0, cache_policy_indirect_buffer_STREAM_1 = 1, cache_policy_indirect_buffer_BYPASS_2 = 2 };\n\n\n//--------------------EVENT_WRITE--------------------\n\nenum EVENT_WRITE_event_index_enum { event_index_event_write_OTHER_0 = 0, event_index_event_write_ZPASS_DONE_1 = 1, event_index_event_write_SAMPLE_PIPELINESTAT_2 = 2, event_index_event_write_SAMPLE_STREAMOUTSTAT_3 = 3, event_index_event_write_CS_VS_PS_PARTIAL_FLUSH_4 = 4, event_index_event_write_RESERVED_EOP_5 = 5, event_index_event_write_RESERVED_EOS_6 = 6, event_index_event_write_CACHE_FLUSH_7 = 7 };\n\ntypedef struct _PM4_EVENT_WRITE\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int event_type:6;\n            unsigned int reserved1:2;\n            EVENT_WRITE_event_index_enum event_index:4;\n            unsigned int reserved2:20;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int reserved3:3;\n            unsigned int address_lo:29;\n        } bitfields3;\n        unsigned int ordinal3;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int address_hi:16;\n            unsigned int reserved4:16;\n        } bitfields4;\n        unsigned int ordinal4;\n    };\n\n}  PM4EVENT_WRITE, *PPM4EVENT_WRITE;\n\n\n//--------------------SET_SH_REG--------------------\n\n\ntypedef struct _PM4_SET_SH_REG\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int reg_offset:16;\n            unsigned int reserved1:16;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    unsigned int reg_data[1];    //1..N of these fields\n\n\n}  PM4SET_SH_REG, *PPM4SET_SH_REG;\n\n\n//--------------------ACQUIRE_MEM--------------------\n\nenum ACQUIRE_MEM_engine_enum { engine_acquire_mem_PFP_0 = 0, engine_acquire_mem_ME_1 = 1 };\n\n\ntypedef struct _PM4_ACQUIRE_MEM\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int coher_cntl:31;\n            ACQUIRE_MEM_engine_enum engine:1;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    unsigned int coher_size;\n\n\n    union\n    {\n        struct\n        {\n            unsigned int coher_size_hi:8;\n            unsigned int reserved1:24;\n        } bitfields3;\n        unsigned int ordinal4;\n    };\n\n    unsigned int coher_base_lo;\n\n\n    union\n    {\n        struct\n        {\n            unsigned int coher_base_hi:25;\n            unsigned int reserved2:7;\n        } bitfields4;\n        unsigned int ordinal6;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int poll_interval:16;\n            unsigned int reserved3:16;\n        } bitfields5;\n        unsigned int ordinal7;\n    };\n\n}  PM4ACQUIRE_MEM, *PPM4ACQUIRE_MEM;\n\n\n//--------------------MEC_INDIRECT_BUFFER--------------------\n\ntypedef struct _PM4_MEC_INDIRECT_BUFFER\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int swap_function:2;\n            unsigned int ib_base_lo:30;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int ib_base_hi:16;\n            unsigned int reserved1:16;\n        } bitfields3;\n        unsigned int ordinal3;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int ib_size:20;\n            unsigned int chain:1;\n            unsigned int offload_polling:1;\n            unsigned int volatile_setting:1;\n            unsigned int valid:1;\n            unsigned int vmid:4;\n            INDIRECT_BUFFER_cache_policy_enum cache_policy:2;\n            unsigned int reserved4:2;\n        } bitfields4;\n        unsigned int ordinal4;\n    };\n\n}  PM4MEC_INDIRECT_BUFFER, *PPM4MEC_INDIRECT_BUFFER;\n\n//--------------------MEC_WAIT_REG_MEM--------------------\n\nenum MEC_WAIT_REG_MEM_function_enum {\n     function__mec_wait_reg_mem__always_pass = 0,\n     function__mec_wait_reg_mem__less_than_ref_value = 1,\n     function__mec_wait_reg_mem__less_than_equal_to_the_ref_value = 2,\n     function__mec_wait_reg_mem__equal_to_the_reference_value = 3,\n     function__mec_wait_reg_mem__not_equal_reference_value = 4,\n     function__mec_wait_reg_mem__greater_than_or_equal_reference_value = 5,\n     function__mec_wait_reg_mem__greater_than_reference_value = 6 };\n\nenum MEC_WAIT_REG_MEM_mem_space_enum {\n     mem_space__mec_wait_reg_mem__register_space = 0,\n     mem_space__mec_wait_reg_mem__memory_space = 1 };\n\nenum MEC_WAIT_REG_MEM_operation_enum {\n     operation__mec_wait_reg_mem__wait_reg_mem = 0,\n     operation__mec_wait_reg_mem__wr_wait_wr_reg = 1,\n     operation__mec_wait_reg_mem__wait_mem_preemptable = 3 };\n\n\ntypedef struct PM4_MEC_WAIT_REG_MEM\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        uint32_t            ordinal1;\n    };\n\n    union\n    {\n        struct\n        {\n            MEC_WAIT_REG_MEM_function_enum function:3;\n            uint32_t reserved1:1;\n            MEC_WAIT_REG_MEM_mem_space_enum mem_space:2;\n            MEC_WAIT_REG_MEM_operation_enum operation:2;\n            uint32_t reserved2:24;\n        } bitfields2;\n        uint32_t ordinal2;\n    };\n\n    union\n    {\n        struct\n        {\n            uint32_t reserved3:2;\n            uint32_t mem_poll_addr_lo:30;\n        } bitfields3a;\n        struct\n        {\n            uint32_t reg_poll_addr:18;\n            uint32_t reserved4:14;\n        } bitfields3b;\n        struct\n        {\n            uint32_t reg_write_addr1:18;\n            uint32_t reserved5:14;\n        } bitfields3c;\n        uint32_t ordinal3;\n    };\n\n    union\n    {\n        uint32_t mem_poll_addr_hi;\n\n        struct\n        {\n            uint32_t reg_write_addr2:18;\n            uint32_t reserved6:14;\n        } bitfields4b;\n        uint32_t ordinal4;\n    };\n\n    uint32_t reference;\n\n    uint32_t mask;\n\n    union\n    {\n        struct\n        {\n            uint32_t poll_interval:16;\n            uint32_t reserved7:15;\n            uint32_t optimize_ace_offload_mode:1;\n        } bitfields7;\n        uint32_t ordinal7;\n    };\n\n} PM4MEC_WAIT_REG_MEM, *PPM4MEC_WAIT_REG_MEM;\n\n//--------------------MEC_WRITE_DATA--------------------\n\nenum MEC_WRITE_DATA_dst_sel_enum { dst_sel_mec_write_data_MEM_MAPPED_REGISTER_0 = 0, dst_sel_mec_write_data_TC_L2_2 = 2, dst_sel_mec_write_data_GDS_3 = 3, dst_sel_mec_write_data_MEMORY_5 = 5 };\nenum MEC_WRITE_DATA_addr_incr_enum { addr_incr_mec_write_data_INCREMENT_ADDR_0 = 0, addr_incr_mec_write_data_DO_NOT_INCREMENT_ADDR_1 = 1 };\nenum MEC_WRITE_DATA_wr_confirm_enum { wr_confirm_mec_write_data_DO_NOT_WAIT_FOR_CONFIRMATION_0 = 0, wr_confirm_mec_write_data_WAIT_FOR_CONFIRMATION_1 = 1 };\nenum MEC_WRITE_DATA_cache_policy_enum { cache_policy_mec_write_data_LRU_0 = 0, cache_policy_mec_write_data_STREAM_1 = 1, cache_policy_mec_write_data_BYPASS_2 = 2 };\n\n//--------------------MEC_RELEASE_MEM--------------------\n\nenum MEC_RELEASE_MEM_event_index_enum { event_index_mec_release_mem_EVENT_WRITE_EOP_5 = 5, event_index_mec_release_mem_CS_Done_6 = 6 };\nenum MEC_RELEASE_MEM_cache_policy_enum { cache_policy_mec_release_mem_LRU_0 = 0, cache_policy_mec_release_mem_STREAM_1 = 1, cache_policy_mec_release_mem_BYPASS_2 = 2 };\nenum MEC_RELEASE_MEM_dst_sel_enum { dst_sel_mec_release_mem_MEMORY_CONTROLLER_0 = 0, dst_sel_mec_release_mem_TC_L2_1 = 1 };\nenum MEC_RELEASE_MEM_int_sel_enum { int_sel_mec_release_mem_NONE_0 = 0, int_sel_mec_release_mem_SEND_INTERRUPT_ONLY_1 = 1, int_sel_mec_release_mem_SEND_INTERRUPT_AFTER_WRITE_CONFIRM_2 = 2, int_sel_mec_release_mem_SEND_DATA_AFTER_WRITE_CONFIRM_3 = 3 };\nenum MEC_RELEASE_MEM_data_sel_enum { data_sel_mec_release_mem_NONE_0 = 0, data_sel_mec_release_mem_SEND_32_BIT_LOW_1 = 1, data_sel_mec_release_mem_SEND_64_BIT_DATA_2 = 2, data_sel_mec_release_mem_SEND_GPU_CLOCK_COUNTER_3 = 3, data_sel_mec_release_mem_SEND_CP_PERFCOUNTER_HI_LO_4 = 4, data_sel_mec_release_mem_STORE_GDS_DATA_TO_MEMORY_5 = 5 };\n\n\n#endif\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/pm4_pkt_struct_nv.h",
    "content": "/*\n * Copyright 2018 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __PM4__PKT__STRUCT__NV__HPP__\n#define __PM4__PKT__STRUCT__NV__HPP__\n\n#include \"pm4_pkt_struct_ai.h\"\n\ntypedef struct _PM4_ACQUIRE_MEM_NV\n{\n    union\n    {\n        PM4_TYPE_3_HEADER   header;            ///header\n        unsigned int        ordinal1;\n    };\n\n    unsigned int reserved;\n\n    unsigned int coher_size;\n\n\n    union\n    {\n        struct\n        {\n            unsigned int coher_size_hi:8;\n            unsigned int reserved1:24;\n        } bitfields3;\n        unsigned int ordinal4;\n    };\n\n    unsigned int coher_base_lo;\n\n\n    union\n    {\n        struct\n        {\n            unsigned int coher_base_hi:24;\n            unsigned int reserved2:8;\n        } bitfields4;\n        unsigned int ordinal6;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int poll_interval:16;\n            unsigned int reserved3:16;\n        } bitfields5;\n        unsigned int ordinal7;\n    };\n\n    union\n    {\n        struct\n        {\n            unsigned int gcr_cntl:18;\n            unsigned int reserved4:14;\n        } bitfields6;\n        unsigned int ordinal8;\n    };\n\n\n}  PM4ACQUIRE_MEM_NV, *PPM4ACQUIRE_MEM_NV;\n\ntypedef struct PM4_MEC_RELEASE_MEM_NV {\n    union {\n        PM4_TYPE_3_HEADER   header;\n        unsigned int        ordinal1;\n    };\n\n    union {\n        struct {\n            unsigned int event_type:6;\n            unsigned int reserved1:2;\n            AI_MEC_RELEASE_MEM_event_index_enum event_index:4;\n            unsigned int gcr_cntl:12;\n            unsigned int reserved4:1;\n            AI_MEC_RELEASE_MEM_cache_policy_enum cache_policy:2;\n            unsigned int reserved5:1;\n            AI_MEC_RELEASE_MEM_pq_exe_status_enum pq_exe_status:1;\n            unsigned int reserved6:3;\n        } bitfields2;\n        unsigned int ordinal2;\n    };\n\n    union {\n        struct {\n            unsigned int reserved7:16;\n            AI_MEC_RELEASE_MEM_dst_sel_enum dst_sel:2;\n            unsigned int reserved8:6;\n            AI_MEC_RELEASE_MEM_int_sel_enum int_sel:3;\n            unsigned int reserved9:2;\n            AI_MEC_RELEASE_MEM_data_sel_enum data_sel:3;\n        } bitfields3;\n        unsigned int ordinal3;\n    };\n\n    union {\n        struct {\n            unsigned int reserved10:2;\n            unsigned int address_lo_32b:30;\n        } bitfields4a;\n        struct {\n            unsigned int reserved11:3;\n            unsigned int address_lo_64b:29;\n        } bitfields4b;\n        unsigned int reserved12;\n\n        unsigned int ordinal4;\n    };\n\n    union {\n        unsigned int address_hi;\n\n        unsigned int reserved13;\n\n        unsigned int ordinal5;\n    };\n\n    union {\n        unsigned int data_lo;\n\n        unsigned int cmp_data_lo;\n\n        struct {\n            unsigned int dw_offset:16;\n            unsigned int num_dwords:16;\n        } bitfields6c;\n        unsigned int reserved14;\n\n        unsigned int ordinal6;\n    };\n\n    union {\n        unsigned int data_hi;\n\n        unsigned int cmp_data_hi;\n\n        unsigned int reserved15;\n\n        unsigned int reserved16;\n\n        unsigned int ordinal7;\n    };\n\n    unsigned int int_ctxid;\n} PM4MEC_RELEASE_MEM_NV, *PPM4MEC_RELEASE_MEM_NV;\n\n\n#endif // __PM4__PKT__STRUCT__NV__HPP__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/include/sdma_pkt_struct.h",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __SDMA_PKT_STRUCT_H__\n#define __SDMA_PKT_STRUCT_H__\n\n\nconst unsigned int SDMA_OP_NOP = 0;\nconst unsigned int SDMA_OP_COPY = 1;\nconst unsigned int SDMA_OP_WRITE = 2;\n\nconst unsigned int SDMA_OP_FENCE = 5;\nconst unsigned int SDMA_OP_TRAP = 6;\nconst unsigned int SDMA_OP_POLL_REGMEM = 8;\nconst unsigned int SDMA_OP_TIMESTAMP = 13;\n\nconst unsigned int SDMA_OP_CONST_FILL = 11;\n\nconst unsigned int SDMA_SUBOP_COPY_LINEAR = 0;\n\nconst unsigned int SDMA_SUBOP_WRITE_LINEAR = 0;\n\n/*\n** Definitions for SDMA_PKT_COPY_LINEAR packet\n*/\n\ntypedef struct SDMA_PKT_COPY_LINEAR_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int reserved_0:11;\n            unsigned int broadcast:1;\n            unsigned int reserved_1:4;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int count:22;\n            unsigned int reserved_0:10;\n        };\n        unsigned int DW_1_DATA;\n    } COUNT_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int reserved_0:16;\n            unsigned int dst_sw:2;\n            unsigned int reserved_1:4;\n            unsigned int dst_ha:1;\n            unsigned int reserved_2:1;\n            unsigned int src_sw:2;\n            unsigned int reserved_3:4;\n            unsigned int src_ha:1;\n            unsigned int reserved_4:1;\n        };\n        unsigned int DW_2_DATA;\n    } PARAMETER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int src_addr_31_0:32;\n        };\n        unsigned int DW_3_DATA;\n    } SRC_ADDR_LO_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int src_addr_63_32:32;\n        };\n        unsigned int DW_4_DATA;\n    } SRC_ADDR_HI_UNION;\n\n    struct\n    {\n        union\n        {\n            struct\n            {\n                unsigned int dst_addr_31_0:32;\n            };\n            unsigned int DW_5_DATA;\n        } DST_ADDR_LO_UNION;\n\n        union\n        {\n            struct\n            {\n                unsigned int dst_addr_63_32:32;\n            };\n            unsigned int DW_6_DATA;\n        } DST_ADDR_HI_UNION;\n    } DST_ADDR[0];\n} SDMA_PKT_COPY_LINEAR, *PSDMA_PKT_COPY_LINEAR;\n\n/*\n** Definitions for SDMA_PKT_WRITE_UNTILED packet\n*/\n\ntypedef struct SDMA_PKT_WRITE_UNTILED_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int reserved_0:16;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int dst_addr_31_0:32;\n        };\n        unsigned int DW_1_DATA;\n    } DST_ADDR_LO_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int dst_addr_63_32:32;\n        };\n        unsigned int DW_2_DATA;\n    } DST_ADDR_HI_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int count:22;\n            unsigned int reserved_0:2;\n            unsigned int sw:2;\n            unsigned int reserved_1:6;\n        };\n        unsigned int DW_3_DATA;\n    } DW_3_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int data0:32;\n        };\n        unsigned int DW_4_DATA;\n    } DATA0_UNION;\n} SDMA_PKT_WRITE_UNTILED, *PSDMA_PKT_WRITE_UNTILED;\n\n/*\n** Definitions for SDMA_PKT_FENCE packet\n*/\n\ntypedef struct SDMA_PKT_FENCE_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int reserved_0:16;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int addr_31_0:32;\n        };\n        unsigned int DW_1_DATA;\n    } ADDR_LO_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int addr_63_32:32;\n        };\n        unsigned int DW_2_DATA;\n    } ADDR_HI_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int data:32;\n        };\n        unsigned int DW_3_DATA;\n    } DATA_UNION;\n} SDMA_PKT_FENCE, *PSDMA_PKT_FENCE;\n\n/*\n** Definitions for SDMA_PKT_CONSTANT_FILL packet\n*/\n\ntypedef struct SDMA_PKT_CONSTANT_FILL_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int sw:2;\n            unsigned int reserved_0:12;\n            unsigned int fillsize:2;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int dst_addr_31_0:32;\n        };\n        unsigned int DW_1_DATA;\n    } DST_ADDR_LO_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int dst_addr_63_32:32;\n        };\n        unsigned int DW_2_DATA;\n    } DST_ADDR_HI_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int src_data_31_0:32;\n        };\n        unsigned int DW_3_DATA;\n    } DATA_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int count:22;\n            unsigned int reserved_0:10;\n        };\n        unsigned int DW_4_DATA;\n    } COUNT_UNION;\n} SDMA_PKT_CONSTANT_FILL, *PSDMA_PKT_CONSTANT_FILL;\n\n/*\n** Definitions for SDMA_PKT_TRAP packet\n*/\n\ntypedef struct SDMA_PKT_TRAP_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int reserved_0:16;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int int_context:28;\n            unsigned int reserved_0:4;\n        };\n        unsigned int DW_1_DATA;\n    } INT_CONTEXT_UNION;\n} SDMA_PKT_TRAP, *PSDMA_PKT_TRAP;\n\n/*\n** Definitions for SDMA_PKT_POLL_REGMEM_TAG packet\n*/\n\ntypedef struct SDMA_PKT_POLL_REGMEM_TAG {\n    union {\n        struct {\n            unsigned int op : 8;\n            unsigned int sub_op : 8;\n            unsigned int reserved_0 : 10;\n            unsigned int hdp_flush : 1;\n            unsigned int reserved_1 : 1;\n            unsigned int func : 3;\n            unsigned int mem_poll : 1;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union {\n        struct {\n            unsigned int addr_31_0 : 32;\n        };\n        unsigned int DW_1_DATA;\n    } ADDR_LO_UNION;\n\n    union {\n        struct {\n            unsigned int addr_63_32 : 32;\n        };\n        unsigned int DW_2_DATA;\n    } ADDR_HI_UNION;\n\n    union {\n        struct {\n            unsigned int value : 32;\n        };\n        unsigned int DW_3_DATA;\n    } VALUE_UNION;\n\n    union {\n        struct {\n            unsigned int mask : 32;\n        };\n        unsigned int DW_4_DATA;\n    } MASK_UNION;\n\n    union {\n        struct {\n            unsigned int interval : 16;\n            unsigned int retry_count : 12;\n            unsigned int reserved_0 : 4;\n        };\n        unsigned int DW_5_DATA;\n    } DW5_UNION;\n} SDMA_PKT_POLL_REGMEM, *PSDMA_PKT_POLL_REGMEM;\n\n/*\n** Definitions for SDMA_PKT_TIMESTAMP packet\n*/\n\ntypedef struct SDMA_PKT_TIMESTAMP_TAG\n{\n\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int reserved_0:16;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int addr_31_0:32;\n        };\n        unsigned int DW_1_DATA;\n    } ADDR_LO_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int addr_63_32:32;\n        };\n        unsigned int DW_2_DATA;\n    } ADDR_HI_UNION;\n} SDMA_PKT_TIMESTAMP, *PSDMA_PKT_TIMESTAMP;\n\n\n/*\n** Definitions for SDMA_PKT_NOP packet\n*/\n\ntypedef struct SDMA_PKT_NOP_TAG\n{\n    union\n    {\n        struct\n        {\n            unsigned int op:8;\n            unsigned int sub_op:8;\n            unsigned int count:14;\n            unsigned int reserved_0:2;\n        };\n        unsigned int DW_0_DATA;\n    } HEADER_UNION;\n\n    union\n    {\n        struct\n        {\n            unsigned int data0:32;\n        };\n        unsigned int DW_1_DATA;\n    } DATA0_UNION;\n} SDMA_PKT_NOP, *PSDMA_PKT_NOP;\n\n#endif // __SDMA_PKT_STRUCT_H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/scripts/kfdtest.exclude",
    "content": "declare -A FILTER\n\n# Power management tests\nFILTER[pm]=\\\n\"KFDPMTest.SuspendWithActiveProcess:\"\\\n\"KFDPMTest.SuspendWithIdleQueue:\"\\\n\"KFDPMTest.SuspendWithIdleQueueAfterWork\"\n\n\n# Core tests, used in scenarios like bringup\n# Software scheduler mode, i. e. non HWS mode\nFILTER[core_sws]=\\\n\"KFDQMTest.CreateDestroyCpQueue:\"\\\n\"KFDQMTest.SubmitNopCpQueue:\"\\\n\"KFDQMTest.SubmitPacketCpQueue:\"\\\n\"KFDQMTest.AllCpQueues:\"\\\n\"KFDQMTest.CreateDestroySdmaQueue:\"\\\n\"KFDQMTest.SubmitNopSdmaQueue:\"\\\n\"KFDQMTest.SubmitPacketSdmaQueue:\"\\\n\"KFDQMTest.AllSdmaQueues:\"\\\n\"KFDQMTest.AllXgmiSdmaQueues:\"\\\n\"KFDQMTest.AllQueues:\"\\\n\"KFDLocalMemoryTest.AccessLocalMem:\"\\\n\"KFDEventTest.SignalEvent\"\n\n# HWS mode\nFILTER[core]=\\\n\"${FILTER[core_sws]}:\"\\\n\"KFDCWSRTest.BasicTest\"\n\n# Permanent exclusions\n# These tests are included for debugging, but are not executed in normal execution on any ASIC:\n# FILTER[pm] need human intervention, so put it here. Developers can run them\n# manually through \"-p pm\" option.\n#\n# CU Masking Linear are not working correctly due to how the HW distributes work over CUs.\n# They are available for testing but are not currently expected to pass on CI/VI/AI.\n#\n# CU Masking Even is added here due to some non-obvious baseline measurements. Though\n# using wallclock to measure performance is always risky, there are just too many ASICs\n# where this test is failing. Ideally we'll get better CU Masking coverage via rocrtst\n#\n# The CheckZeroInitializationVram test is no longer expected to pass as KFD no longer\n# clears memory at allocation time.\nPERMANENT_BLACKLIST_ALL_ASICS=\\\n\"-${FILTER[pm]}:\"\\\n\"KFDQMTest.BasicCuMaskingLinear:\"\\\n\"KFDQMTest.BasicCuMaskingEven:\"\\\n\"RDMATest.GPUDirect:\"\\\n\"KFDLocalMemoryTest.CheckZeroInitializationVram\"\n\n# This is the temporary blacklist for all ASICs. This is to be used when a test is failing consistently\n# on every ASIC (Kaveri, Carrizo, Hawaii, Tonga, Fiji, Polaris10, Polaris11 and Vega10 .\n# TODO means that a JIRA ticket needs to be created for this issue, as no documentation regarding\n# failures can be found\n# NOTE: If you update this alphabetical listing, add the corresponding JIRA ticket for reference\n#\n# KFDQMTest.GPUDoorbellWrite fails intermittently (KFD-318)\n# KFDQMTest.mGPUShareBO (KFD-334)\n# KFDHWSTest.* (SWDEV-193035)\n# KFDEvictTest.BurstyTest (ROCMOPS-464)\n# KFDEvictTest.BurstyTest (SWDEV-291256)\n# KFDEvictTest.BurstyTest (KFD-425)\n# KFDDBGTest.SuspendQueues (SWDEV-417850)\n# KFDDBGTest.HitAddressWatch (SWDEV-420281)\nTEMPORARY_BLACKLIST_ALL_ASICS=\\\n\"KFDQMTest.GPUDoorbellWrite:\"\\\n\"KFDQMTest.mGPUShareBO:\"\\\n\"KFDQMTest.SdmaEventInterrupt:\"\\\n\"KFDMemoryTest.CacheInvalidateOnRemoteWrite:\"\\\n\"KFDEvictTest.BurstyTest:\"\\\n\"KFDHWSTest.*:\"\\\n\"KFDSVMRangeTest.ReadOnlyRangeTest*:\"\\\n\"KFDDBGTest.SuspendQueues:\"\\\n\"KFDDBGTest.HitAddressWatch\"\n\nBLACKLIST_ALL_ASICS=\\\n\"$PERMANENT_BLACKLIST_ALL_ASICS:\"\\\n\"$TEMPORARY_BLACKLIST_ALL_ASICS\"\n\n# SDMA-based tests (KFDIPCTest.BasicTest, KFDQM.*Sdma*, KFDMemoryTest.MMBench) are all\n# disabled on non-Hawaii due to SDMA instability - SWDEV-101666\nSDMA_BLACKLIST=\\\n\"KFDIPCTest.*:\"\\\n\"KFDLocalMemoryTest.CheckZeroInitializationVram:\"\\\n\"KFDMemoryTest.MemoryRegister:\"\\\n\"KFDMemoryTest.MMBench:\"\\\n\"KFDMemoryTest.SignalHandling:\"\\\n\"KFDQMTest.AllQueues:\"\\\n\"KFDQMTest.*Sdma*:\"\\\n\"KFDQMTest.CreateQueueStressSingleThreaded:\"\\\n\"KFDQMTest.GPUDoorbellWrite:\"\\\n\"KFDQMTest.P2PTest:\"\\\n\"KFDPerformanceTest.P2PBandWidthTest:\"\\\n\"KFDPerformanceTest.P2POverheadTest\"\n\n# Anything involving CP queue creation is failing on Kaveri. Separate them here for convenience (KFD-336)\nKV_QUEUE_BLACKLIST=\\\n\"KFDExceptionTest.AddressFault:\"\\\n\"KFDExceptionTest.PermissionFault:\"\\\n\"KFDLocalMemoryTest.*:\"\\\n\"KFDEventTest.Signal*Event*:\"\\\n\"KFDQMTest.CreateQueueStressSingleThreaded:\"\\\n\"KFDQMTest.*CpQueue*:\"\\\n\"KFDQMTest.*Dispatch*:\"\\\n\"KFDQMTest.Atomics:\"\\\n\"KFDQMTest.GPUDoorbellWrite\"\n\n# KFDCWSRTest.BasicTest*: SWDEV-353206\nBLACKLIST_GFX10=\\\n\"KFDMemoryTest.DeviceHdpFlush:\"\\\n\"KFDSVMEvictTest.*:\"\\\n\"KFDCWSRTest.BasicTest*\"\n\nBLACKLIST_GFX10_NV2X=\\\n\"$BLACKLIST_GFX10:\"\\\n\"KFDPerfCountersTest.*\"\n\n# KFDMemoryTest.FlatScratchAccess           - SWDEV-329877\n# KFDGWSTest.*: GFX11 will no longer use global wave sync\nBLACKLIST_GFX11=\\\n\"KFDQMTest.CreateAqlCpQueue:\"\\\n\"KFDCWSRTest.InterruptRestore:\"\\\n\"KFDPerfCountersTest.*:\"\\\n\"KFDMemoryTest.FlatScratchAccess:\"\\\n\"KFDGWSTest.*\"\n\nBLACKLIST_GFX12=\\\n\"KFDQMTest.CreateAqlCpQueue:\"\\\n\"KFDPerfCountersTest.*:\"\\\n\"KFDMemoryTest.FlatScratchAccess:\"\\\n\"KFDGWSTest.*\"\n\n# KFDQMTest.CpuWriteCoherence fails. 0 dwordsAvailable (KFD-338)\n# KFDMemoryTest.MemoryRegister fails on SDMA queue creation (KFD-337)\nFILTER[kaveri]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"$KV_QUEUE_BLACKLIST:\"\\\n\"KFDMemoryTest.MemoryRegister:\"\\\n\"KFDQMTest.CpuWriteCoherence\"\n\n# KFDLocalMemoryTest.BasicTest is failing intermittently (KFD-368)\n# KFDMemoryTest.BigSysBufferStressTest was failing intermittently on 4.9\n# and hangs when executed twice (KFD-312)\n# KFDQMTest.GPUDoorbellWrite fails on Hawaii. Could be HW-related (KFD-342)\nFILTER[hawaii]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDLocalMemoryTest.BasicTest:\"\\\n\"KFDMemoryTest.BigSysBufferStressTest:\"\\\n\"KFDQMTest.GPUDoorbellWrite\"\n\nFILTER[carrizo]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"KFDExceptionTest.PermissionFault\"\n\n# KFDPerfCountersTest.*Trace fail (KFD-339)\n# KFDMemoryTest.QueryPointerInfo/MemoryRegister* (KFD-341)\n# The remaining tests listed here fail on map memory to GPU with a VA conflict (KFD-340)\nFILTER[tonga]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"KFDCWSRTest.BasicTest:\"\\\n\"KFDPerfCountersTest.*:\"\\\n\"KFDQMTest.OverSubscribeCpQueues\"\n\n# Since Navi10 was merged, the PM4Event test takes 6min to run\nFILTER[fiji]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDQMTest.PM4EventInterrupt:\"\\\n\"$SDMA_BLACKLIST\"\n\nFILTER[polaris10]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST\"\n\nFILTER[polaris11]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST\"\n\nFILTER[polaris12]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST\"\n\n# KFDIPCTest.BasicTest (ROCMOPS-459) .CMABasicTest (ROCMOPS-460) .CrossMemoryAttachTest (ROCMOPS-461)\n# KFDQMTest.AllSdmaQueues (ROCMOPS-463)\nFILTER[vega10]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDIPCTest.BasicTest:\"\\\n\"KFDIPCTest.CMABasicTest:\"\\\n\"KFDIPCTest.CrossMemoryAttachTest:\"\\\n\"KFDQMTest.AllSdmaQueues\"\n\nFILTER[vega12]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST\"\\\n\nFILTER[vega20]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"KFDQMTest.GPUDoorbellWrite\"\n\nFILTER[raven_dgpuFallback]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"KFDEvictTest.*:\"\\\n\"KFDMemoryTest.MemoryRegister:\"\\\n\"KFDSVMRangeTest.BasicSystemMemTest:\"\\\n\"KFDSVMRangeTest.BasicVramTest:\"\\\n\"KFDSVMRangeTest.EvictSystemRangeTest:\"\\\n\"KFDSVMRangeTest.PartialUnmapSysMemTest:\"\\\n\"KFDSVMRangeTest.MigrateTest:\"\\\n\"KFDSVMRangeTest.MigratePolicyTest:\"\\\n\"KFDSVMRangeTest.MigrateGranularityTest:\"\\\n\"KFDSVMRangeTest.MigrateLargeBufTest:\"\\\n\"KFDSVMRangeTest.MultiThreadMigrationTest:\"\\\n\"KFDSVMRangeTest.MigrateAccessInPlaceTest:\"\\\n\"KFDSVMEvictTest.QueueTest\"\n\nFILTER[raven]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$SDMA_BLACKLIST:\"\\\n\"KFDEvictTest.*:\"\\\n\"KFDSVMRangeTest.EvictSystemRangeTest:\"\\\n\"KFDSVMRangeTest.PartialUnmapSysMemTest:\"\\\n\"KFDSVMRangeTest.PrefetchTest:\"\\\n\"KFDSVMRangeTest.MultiThreadMigrationTest:\"\\\n\"KFDSVMEvictTest.QueueTest:\"\\\n\"KFDQMTest.MultipleCpQueuesStressDispatch\"\n\nFILTER[renoir]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDEvictTest.*:\"\\\n\"KFDMemoryTest.LargestSysBufferTest:\"\\\n\"KFDMemoryTest.SignalHandling\"\n\n# KFDExceptionTest.* (KFD-435)\nFILTER[arcturus]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDExceptionTest.FaultStorm:\"\\\n\"KFDNegativeTest.*\"\n\nFILTER[aldebaran]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDExceptionTest.FaultStorm:\"\\\n\"KFDMemoryTest.PtraceAccess:\"\\\n\"KFDMemoryTest.DeviceHdpFlush\"\n\nFILTER[navi10]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10:\"\\\n\"KFDMemoryTest.MMBench\"\n\n# Need to verify the following failed tests on another machine:\n# Exceptions not being received during exception tests\n# PerfCounters return HSAKMT_STATUS_INVALID_PARAMETER\n# P2PBandwidth failing (wait times out) on node-to-multiple-nodes by [push, NONE]\nFILTER[navi12]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10:\"\\\n\"KFDExceptionTest.*:\"\\\n\"KFDPerfCountersTest.*:\"\\\n\"KFDPerformanceTest.P2PBandWidthTest\"\n\nFILTER[navi14]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10\"\n\nFILTER[sienna_cichlid]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[navy_flounder]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[dimgrey_cavefish]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[beige_goby]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[yellow_carp]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[gfx1100]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\n# SWDEV-384028\nFILTER[gfx1101]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11:\"\\\n\"KFDExceptionTest.SdmaQueueException\"\n\nFILTER[gfx1102]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1103]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1150]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1151]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1152]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1153]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11\"\n\nFILTER[gfx1036]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX10_NV2X\"\n\nFILTER[gfx942]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDMemoryTest.LargestSysBufferTest:\"\\\n\"KFDMemoryTest.BigSysBufferStressTest:\"\\\n\"KFDMemoryTest.FlatScratchAccess:\"\\\n\"KFDIPCTest.BasicTest:\"\\\n\"KFDQMTest.QueueLatency\"\n\nFILTER[gfx950]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"KFDMemoryTest.LargestSysBufferTest:\"\\\n\"KFDMemoryTest.BigSysBufferStressTest:\"\\\n\"KFDMemoryTest.FlatScratchAccess:\"\\\n\"KFDIPCTest.BasicTest:\"\\\n\"KFDQMTest.QueueLatency:\"\\\n\"KFDEvictTest.*:\"\\\n\"KFDSVMEvictTest.QueueTest*:\"\\\n\"KFDGWSTest.Semaphore\"\n\nFILTER[gfx1200]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX12\"\n\nFILTER[gfx1201]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX12\"\n\nFILTER[RHEL9]=\\\n\"$BLACKLIST_ALL_ASICS:\"\\\n\"$BLACKLIST_GFX11:\"\\\n\"KFDQMTest.ExtendedCuMasking:\"\\\n\"KFDEvictTest.QueueTest:\"\\\n\"KFDPCSamplingTest.*\"\n\nFILTER[upstream]=\\\n\"KFDIPCTest.*\"\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/scripts/run_kfdtest.sh",
    "content": "#!/bin/bash\n#\n# Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the \"Software\"),\n# to deal in the Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n# and/or sell copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n#\n#\n\n# See if we can find the SHARE/BIN dirs in their expected locations\nCWD=\"${BASH_SOURCE%/*}\"\nwhile read candidate; do\n    if [ -e \"$candidate/kfdtest.exclude\" ]; then\n        source \"$candidate/kfdtest.exclude\"\n        break\n    fi\ndone <<EOF\n$KFDTEST_SHARE_DIR\n$CWD\n$CWD/../share/kfdtest\n/opt/rocm/share/kfdtest\nEOF\n\n# Keep these checks until automation starts using the package install\nif [ -z \"${FILTER[core]}\" ]; then\n    if [ -e \"$CWD/../bin/kfdtest/kfdtest.exclude\" ]; then\n        source \"$CWD/../bin/kfdtest/kfdtest.exclude\"\n    elif [ -e \"$CWD/../../share/kfdtest.exclude\" ]; then\n        source \"$CWD/../../share/kfdtest.exclude\"\n    fi\nfi\n\n# This filter will always exist if we sourced a valid kfdtest.exclude\nif [ -z \"${FILTER[core]}\" ]; then\n    echo \"Unable to locate kfdtest.exclude.\"\n    echo \"Please set KFDTEST_SHARE_DIR or ensure that kfdtest.exclude is present inside $CWD, $CWD/../share/kfdtest or /opt/rocm/share/kfdtest\"\n    exit 1\nfi\n\n# Using \"which\" produces different results in different\n# OSes so use command -v instead. It returns \"\" if the\n# command isn't in the PATH\nif [ -z \"$(command -v kfdtest)\" ]; then\n    if [ -z \"$BIN_DIR\" ]; then\n        if [ -e \"${0%/*}/kfdtest\" ]; then\n            BIN_DIR=\"${0%/*}\"\n        else\n            # The default location\n            BIN_DIR=\"/opt/rocm/bin\"\n        fi\n    fi\n    if [ -e \"$BIN_DIR/kfdtest\" ]; then\n        KFDTEST=\"$BIN_DIR/kfdtest\"\n    else\n        echo \"Unable to locate kfdtest.\"\n        echo \"Please set BIN_DIR, ensure that kfdtest is in $PATH, or ensure that kfdtest is present inside ${0%/*} or /opt/rocm/bin\"\n        exit 1\n    fi\nelse\n    KFDTEST=\"kfdtest\"\nfi\n\nPLATFORM=\"\"\nGDB=\"\"\nNODE=\"\"\nFORCE_HIGH=\"\"\nRUN_IN_DOCKER=\"\"\nADDITIONAL_EXCLUDE=\"\"\n\nprintUsage() {\n    echo\n    echo \"Usage: $(basename $0) [options ...] [gtest arguments]\"\n    echo\n    echo \"Options:\"\n    echo \"  -p <platform> , --platform <platform>    Only run tests that\"\\\n                               \"pass on the specified platform. Usually you\"\\\n                               \"don't need this option\"\n    echo \"  -g            , --gdb                    Run in debugger\"\n    echo \"  -n <node(s)>  , --node <node(s)>         NodeId(s) to test. Takes a single integer, or a\"\\\n                               \"quoted, space-separated string as an argument\"\\\n                               \"(e.g. -n 1 OR -n \\\"1 2 3\\\")\"\\\n                               \"NOTE: Node numbers come from /sys/class/kfd/kfd/topology/nodes/#\"\n    echo \"  -l            , --list                   List available nodes\"\n    echo \"  --high                                   Force clocks to high for test execution\"\n    echo \"  -d            , --docker                 Run in docker container\"\n    echo \"  -e <list>     , --exclude <list>         Additional tests to exclude, in addition to kfdtest.exclude.\"\\\n                               \"Takes a colon-separated string as an argument\"\\\n                               \"(e.g. -e KFDEvictTest.*:KFDSVMEvictTest.*)\"\n    echo \"  -h            , --help                   Prints this help\"\n    echo\n    echo \"Gtest arguments will be forwarded to the app\"\n    echo\n    echo \"Valid platform options: core_sws, core, polaris10, vega10, vega20, pm, all, and so on\"\n    echo \"'all' option runs all tests\"\n\n    return 0\n}\n# Print gtest_filter for the given Platform\n#    param - Platform.\ngetFilter() {\n# For regular platforms such as vega10, this will automatically generate\n# the valid variable BLACKLIST based on the variable platform.\n    local platform=$1;\n\n    case \"$platform\" in\n        all ) gtestFilter=\"\" ;;\n        * )\n            if [ -z \"${FILTER[$platform]}\" ]; then\n                echo \"Unsupported platform $platform. Exiting\"\n                exit 1\n            fi\n\n            gtestFilter=\"--gtest_filter=${FILTER[$platform]}\"\n            ;;\n    esac\n\n    # Check if the loaded driver is upstream (in-box) or DKMS\n    rdma_get_pages_func=$(cat /proc/kallsyms | grep rdma_get_pages)\n    if [ -z \"$rdma_get_pages_func\" ]; then\n\t    gtestFilter=\"$gtestFilter:${FILTER[upstream]}\"\n    fi\n\n    if [ -n \"$ADDITIONAL_EXCLUDE\" ]; then\n\t    gtestFilter=\"$gtestFilter:$ADDITIONAL_EXCLUDE\"\n    fi\n}\n\nTOPOLOGY_SYSFS_DIR=/sys/devices/virtual/kfd/kfd/topology/nodes\n\n# Prints list of HSA Nodes. HSA Nodes are identified from sysfs KFD topology. The nodes\n# should have valid SIMD count\ngetHsaNodes() {\n    for i in $(find $TOPOLOGY_SYSFS_DIR  -maxdepth 1 -mindepth 1 -type d); do\n        simdcount=$(cat $i/properties | grep simd_count | awk '{print $2}')\n        if [ $simdcount != 0 ]; then\n            hsaNodeList+=\"$(basename $i) \"\n        fi\n    done\n    echo \"$hsaNodeList\"\n}\n\n\n# Prints GPU Name for the given Node ID. If transitioned to IP discovery,\n# use target gfx version\n#   param - Node ID\ngetNodeName() {\n    local nodeId=$1; shift;\n    local gpuName=$(cat $TOPOLOGY_SYSFS_DIR/$nodeId/name)\n    if [ \"$gpuName\" == \"raven\" ]; then\n      local CpuCoresCount=$(cat $TOPOLOGY_SYSFS_DIR/$nodeId/properties | grep cpu_cores_count | awk '{print $2}')\n      local SimdCount=$(cat $TOPOLOGY_SYSFS_DIR/$nodeId/properties | grep simd_count | awk '{print $2}')\n      if [ \"$CpuCoresCount\" -eq 0 ] && [ \"$SimdCount\" -gt 0 ]; then\n        gpuName=\"raven_dgpuFallback\"\n      fi\n    elif [ \"$gpuName\" == \"ip discovery\" ]; then\n      if [ -n \"$HSA_OVERRIDE_GFX_VERSION\" ]; then\n          gpuName=\"gfx$(echo \"$HSA_OVERRIDE_GFX_VERSION\" | awk 'BEGIN {FS=\".\"; RS=\"\"} {printf \"%d%x%x\", $1, $2, $3 }')\"\n      else\n          local GfxVersionDec=$(cat $TOPOLOGY_SYSFS_DIR/$nodeId/properties | grep gfx_target_version | awk '{print $2}')\n          if [[ ${#GfxVersionDec} = 5 ]]; then\n              GfxVersionDec=\"0${GfxVersionDec}\"\n          fi\n          gpuName=\"gfx$(printf \"$GfxVersionDec\" | fold -w2 | awk 'BEGIN {FS=\"\\n\"; RS=\"\"} {printf \"%d%x%x\", $1, $2, $3}')\"\n      fi\n    fi\n    echo \"$gpuName\"\n}\n\n# Run KfdTest independently. Two global variables set by command-line\n# will influence the tests as indicated below\n#   PLATFORM - If set all tests will run with this platform filter\n#   NODE - If set tests will be run only on this NODE, else it will be\n#           run on all available HSA Nodes\nrunKfdTest() {\n    if [ \"$RUN_IN_DOCKER\" == \"true\" ]; then\n        if [ `sudo systemctl is-active docker` != \"active\" ]; then\n            echo \"docker isn't active, install and setup docker first!!!!\"\n            exit 0\n        fi\n        PKG_ROOT=\"$(getPackageRoot)\"\n    fi\n\n    if [ -n \"$GTEST_ARGS\" ] && [ -n \"$ADDITIONAL_EXCLUDE\" ]; then\n\t    echo \"Cannot use -e and --gtest_filter flags together\"\n\t    exit 0\n    fi\n\n    if [ \"$NODE\" == \"\" ]; then\n        hsaNodes=$(getHsaNodes)\n\n        if [ \"$hsaNodes\" == \"\" ]; then\n            echo \"No GPU found in the system.\"\n            exit 1\n        fi\n    else\n        hsaNodes=$NODE\n    fi\n\n    for hsaNode in $hsaNodes; do\n        nodeName=$(getNodeName $hsaNode)\n        if [ \"$PLATFORM\" != \"\" ] && [ \"$PLATFORM\" != \"$nodeName\" ]; then\n            echo \"WARNING: Actual ASIC $nodeName treated as $PLATFORM\"\n            nodeName=\"$PLATFORM\"\n        fi\n\n        getFilter $nodeName\n\n        if [ \"$RUN_IN_DOCKER\" == \"true\" ]; then\n            if [ \"$NODE\" == \"\" ]; then\n                DEVICE_NODE=\"/dev/dri\"\n            else\n                RENDER_NODE=$(($hsaNode + 127))\n                DEVICE_NODE=\"/dev/dri/renderD${RENDER_NODE}\"\n            fi\n\n            echo \"Starting testing node $hsaNode ($nodeName) in docker container\"\n            sudo docker run -it --name kfdtest_docker --user=\"jenkins\" --network=host \\\n            --device=/dev/kfd --device=${DEVICE_NODE} --group-add video --cap-add=SYS_PTRACE \\\n            --security-opt seccomp=unconfined -v $PKG_ROOT:/home/jenkins/rocm \\\n            compute-artifactory.amd.com:5000/yuho/tianli-ubuntu1604-kfdtest:01 \\\n            /home/jenkins/rocm/utils/run_kfdtest.sh -n $hsaNode $gtestFilter $GTEST_ARGS\n            if [ \"$?\" = \"0\" ]; then\n                echo \"Finished node $hsaNode ($nodeName) successfully in docker container\"\n            else\n                echo \"Testing failed for node $hsaNode ($nodeName) in docker container\"\n            fi\n            sudo docker rm kfdtest_docker\n        else\n            if [ \"$HSA_TEST_GPUS_NUM\" != \"\" ]; then\n                echo \"++++ Starting parallel testing on $HSA_TEST_GPUS_NUM gpu(s) ++++\"\n                $GDB $KFDTEST $gtestFilter $GTEST_ARGS\n                echo \"++++ Finished parallel testing on $HSA_TEST_GPUS_NUM gpu(s) ++++\"\n                exit 0;\n            else\n                echo \"\"\n                echo \"++++ Starting testing node $hsaNode ($nodeName) ++++\"\n                $GDB $KFDTEST \"--node=$hsaNode\" $gtestFilter $GTEST_ARGS\n                echo \"---- Finished testing node $hsaNode ($nodeName) ----\"\n            fi\n\n        fi\n\n\n    done\n\n}\n\n# Prints number of GPUs present in the system\ngetGPUCount() {\n    gNodes=$(getHsaNodes)\n    gNodes=( $gNodes )\n    gpuCount=${#gNodes[@]}\n    echo \"$gpuCount\"\n}\n\nwhile [ \"$1\" != \"\" ]; do\n    case \"$1\" in\n        -p  | --platform )\n            shift 1; PLATFORM=$1 ;;\n        -g  | --gdb )\n            GDB=\"gdb --args\" ;;\n        -l  | --list )\n            printGpuNodelist; exit 0 ;;\n        -n  | --node )\n            shift 1; NODE=$1 ;;\n        --high)\n            FORCE_HIGH=\"true\" ;;\n        -d  | --docker )\n            RUN_IN_DOCKER=\"true\" ;;\n        -e  | --exclude )\n            shift 1; ADDITIONAL_EXCLUDE=\"$1\" ;;\n        -h  | --help )\n            printUsage; exit 0 ;;\n        *)\n            GTEST_ARGS=$@; break;;\n    esac\n    shift 1\ndone\n\n# If the SMI is missing, try to find it\nSMI=\"$(find /opt/rocm* -type l -name rocm-smi 2>/dev/null | tail -1)\"\nif [ -z ${SMI} ]; then\n    if [ -x ${BIN_DIR}/rocm-smi ]; then\n\tSMI=${BIN_DIR}/rocm-smi\n    else\n\tSMI=`which rocm-smi`\n    fi\nfi\n# If the SMI is still missing, just report and continue\nif [ \"$FORCE_HIGH\" == \"true\" ]; then\n    if [ -e \"$SMI\" ]; then\n        OLDPERF=$($SMI -p | awk '/Performance Level:/ {print $NF; exit}')\n\t$($SMI --setperflevel high &> /dev/null)\n\tif [ $? != 0 ]; then\n            echo \"SMI failed to set perf level\"\n\t    OLDPERF=\"\"\n        fi\n    else\n        echo \"Unable to set clocks to high, cannot find rocm-smi\"\n    fi\nfi\n\n# Set HSA_DEBUG env to run KFDMemoryTest.PtraceAccessInvisibleVram\nexport HSA_DEBUG=1\nrunKfdTest\n\n# OLDPERF is only set if FORCE_HIGH and SMI both exist\nif [ -n \"$OLDPERF\" ]; then\n    $SMI --setperflevel $OLDPERF &> /dev/null\nfi\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/AqlQueue.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"AqlQueue.hpp\"\n#include \"GoogleTestExtension.hpp\"\n\n\nAqlQueue::AqlQueue(void) {\n}\n\n\nAqlQueue::~AqlQueue(void) {\n}\n\nunsigned int AqlQueue::Wptr() {\n    return *m_Resources.Queue_write_ptr;\n}\n\nunsigned int AqlQueue::Rptr() {\n    return *m_Resources.Queue_read_ptr;\n}\n\nunsigned int AqlQueue::RptrWhenConsumed() {\n    return Wptr();\n}\n\nvoid AqlQueue::SubmitPacket() {\n    // m_pending Wptr is in dwords\n    *m_Resources.Queue_write_ptr = m_pendingWptr;\n    *(m_Resources.Queue_DoorBell) = Wptr();\n}\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/AqlQueue.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_AQL_QUEUE__H__\n#define __KFD_AQL_QUEUE__H__\n\n#include \"BaseQueue.hpp\"\n\nclass AqlQueue : public BaseQueue {\n public:\n    AqlQueue();\n    virtual ~AqlQueue();\n\n    // @brief Updates queue write pointer and sets the queue doorbell to the queue write pointer\n    virtual void SubmitPacket();\n\n    // @return Read pointer in dwords\n    virtual unsigned int Rptr();\n    // @return Write pointer in dwords\n    virtual unsigned int Wptr();\n    // @return Expected m_Resources.Queue_read_ptr when all packets are consumed\n    virtual unsigned int RptrWhenConsumed();\n\n protected:\n    virtual PACKETTYPE PacketTypeSupported() { return PACKETTYPE_AQL; }\n\n    virtual _HSA_QUEUE_TYPE GetQueueType() { return HSA_QUEUE_COMPUTE_AQL; }\n};\n\n#endif  // __KFD_AQL_QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/Assemble.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n/**\n * Self-contained assembler that uses the LLVM MC API to assemble AMDGCN\n * instructions\n */\n\n#include <llvm/Config/llvm-config.h>\n#include <llvm/MC/MCAsmBackend.h>\n#include <llvm/MC/MCAsmInfo.h>\n#include <llvm/MC/MCCodeEmitter.h>\n#include <llvm/MC/MCContext.h>\n#include <llvm/MC/MCInstPrinter.h>\n#include <llvm/MC/MCInstrInfo.h>\n#include <llvm/MC/MCObjectFileInfo.h>\n#include <llvm/MC/MCObjectWriter.h>\n#include <llvm/MC/MCParser/AsmLexer.h>\n#include <llvm/MC/MCParser/MCTargetAsmParser.h>\n#include <llvm/MC/MCRegisterInfo.h>\n#include <llvm/MC/MCStreamer.h>\n#include <llvm/MC/MCSubtargetInfo.h>\n#include <llvm/Support/CommandLine.h>\n#include <llvm/Support/InitLLVM.h>\n#include <llvm/Support/MemoryBuffer.h>\n#include <llvm/Support/SourceMgr.h>\n#include <llvm/Support/TargetSelect.h>\n#if LLVM_VERSION_MAJOR > 13\n#include <llvm/MC/TargetRegistry.h>\n#else\n#include <llvm/Support/TargetRegistry.h>\n#endif\n#if LLVM_VERSION_MAJOR > 18\n#include \"llvm/Support/ManagedStatic.h\"\n#endif\n\n#include <linux/elf.h>\n#include \"OSWrapper.hpp\"\n#include \"Assemble.hpp\"\n\nusing namespace llvm;\n\n/* Assembler implementation is not multi-thread safe and is\n * asic type dependent. Instantiate it per thread/gpu use case,\n * delete each assembler after assembling\n */\n\nvoid Init_LLVM() {\n    LLVMInitializeAMDGPUTargetInfo();\n    LLVMInitializeAMDGPUTargetMC();\n    LLVMInitializeAMDGPUAsmParser();\n}\n\nvoid Shutdown_LLVM() {\n    llvm_shutdown();\n}\n\nAssembler::Assembler(const uint32_t Gfxv) {\n    SetTargetAsic(Gfxv);\n    TextData = nullptr;\n    TextSize = 0;\n}\n\nAssembler::~Assembler() {\n    FlushText();\n}\n\nconst char* Assembler::GetInstrStream() {\n    return TextData;\n}\n\nconst size_t Assembler::GetInstrStreamSize() {\n    return TextSize;\n}\n\nint Assembler::CopyInstrStream(char* OutBuf, const size_t BufSize) {\n    if (TextSize > BufSize)\n        return -2;\n\n    std::copy(TextData, TextData + TextSize, OutBuf);\n    return 0;\n}\n\nconst char* Assembler::GetTargetAsic() {\n    return MCPU;\n}\n\n/**\n * Set MCPU via GFX Version from Thunk\n * LLVM Target IDs use decimal for Maj/Min, hex for Step\n */\nvoid Assembler::SetTargetAsic(const uint32_t Gfxv) {\n    const uint8_t Major = (Gfxv >> 16) & 0xff;\n    const uint8_t Minor = (Gfxv >> 8) & 0xff;\n    const uint8_t Step = Gfxv & 0xff;\n\n    snprintf(MCPU, ASM_MCPU_LEN, \"gfx%d%d%x\", Major, Minor, Step);\n}\n\n/**\n * Flush/reset TextData and TextSize to initial state\n */\nvoid Assembler::FlushText() {\n    if (TextData)\n        delete[] TextData;\n    TextData = nullptr;\n    TextSize = 0;\n}\n\n/**\n * Print hex of ELF object to stdout (debug)\n */\nvoid Assembler::PrintELFHex(const std::string Data) {\n    outs() << \"ASM Info: assembled ELF hex data (length \" << Data.length() << \"):\\n\";\n    outs() << \"0x00:\\t\";\n    for (size_t i = 0; i < Data.length(); ++i) {\n        char c = Data[i];\n        outs() << format_hex(static_cast<uint8_t>(c), 4);\n        if ((i+1) % 16 == 0)\n            outs() << \"\\n\" << format_hex(i+1, 4) << \":\\t\";\n        else\n            outs() << \" \";\n    }\n    outs() << \"\\n\";\n}\n\n/**\n * Print hex of raw instruction stream to stdout (debug)\n */\nvoid Assembler::PrintTextHex() {\n    outs() << \"ASM Info: assembled .text hex data (length \" << TextSize << \"):\\n\";\n    outs() << \"0x00:\\t\";\n    for (size_t i = 0; i < TextSize; i++) {\n        outs() << format_hex(static_cast<uint8_t>(TextData[i]), 4);\n        if ((i+1) % 16 == 0)\n            outs() << \"\\n\" << format_hex(i+1, 4) << \":\\t\";\n        else\n            outs() << \" \";\n    }\n    outs() << \"\\n\";\n}\n\n/**\n * Extract raw instruction stream from .text section in ELF object\n *\n * @param RawData Raw C string of ELF object\n * @return 0 on success\n */\nint Assembler::ExtractELFText(const char* RawData) {\n    const Elf64_Ehdr* ElfHeader;\n    const Elf64_Shdr* SectHeader;\n    const Elf64_Shdr* SectStrTable;\n    const char* SectStrAddr;\n    unsigned NumSects, SectIdx;\n\n    if (!(ElfHeader = reinterpret_cast<const Elf64_Ehdr*>(RawData))) {\n        outs() << \"ASM Error: elf data is invalid or corrupted\\n\";\n        return -1;\n    }\n    if (ElfHeader->e_ident[EI_CLASS] != ELFCLASS64) {\n        outs() << \"ASM Error: elf object must be of 64-bit type\\n\";\n        return -1;\n    }\n\n    SectHeader = reinterpret_cast<const Elf64_Shdr*>(RawData + ElfHeader->e_shoff);\n    SectStrTable = &SectHeader[ElfHeader->e_shstrndx];\n    SectStrAddr = static_cast<const char*>(RawData + SectStrTable->sh_offset);\n\n    // Loop through sections, break on .text\n    NumSects = ElfHeader->e_shnum;\n    for (SectIdx = 0; SectIdx < NumSects; SectIdx++) {\n        std::string SectName = std::string(SectStrAddr + SectHeader[SectIdx].sh_name);\n        if (SectName == std::string(\".text\")) {\n            TextSize = SectHeader[SectIdx].sh_size;\n            TextData = new char[TextSize];\n            memcpy(TextData, RawData + SectHeader[SectIdx].sh_offset, TextSize);\n            break;\n        }\n    }\n\n    if (SectIdx >= NumSects) {\n        outs() << \"ASM Error: couldn't locate .text section\\n\";\n        return -1;\n    }\n\n    return 0;\n}\n\n/**\n * Assemble shader, fill member vars, and copy to output buffer\n *\n * @param AssemblySource Shader source represented as a raw C string\n * @param OutBuf Raw instruction stream output buffer\n * @param BufSize Size of OutBuf (defaults to PAGE_SIZE)\n * @param Gfxv Optional overload to temporarily set target ASIC\n * @return Value of RunAssemble() (0 on success)\n */\nint Assembler::RunAssembleBuf(const char* const AssemblySource, char* OutBuf,\n                              const size_t BufSize) {\n    int ret = RunAssemble(AssemblySource);\n    return ret ? ret : CopyInstrStream(OutBuf, BufSize);\n}\nint Assembler::RunAssembleBuf(const char* const AssemblySource, char* OutBuf,\n                              const size_t BufSize, const uint32_t Gfxv) {\n    const char* defaultMCPU = GetTargetAsic();\n    SetTargetAsic(Gfxv);\n    int ret = RunAssemble(AssemblySource);\n    strncpy(MCPU, defaultMCPU, ASM_MCPU_LEN);\n    return ret ? ret : CopyInstrStream(OutBuf, BufSize);\n}\n\n/**\n * Assemble shader and fill member vars\n *\n * @param AssemblySource Shader source represented as a raw C string\n * @return 0 on success\n */\nint Assembler::RunAssemble(const char* const AssemblySource) {\n    // Ensure target ASIC has been set\n    if (!*MCPU) {\n        outs() << \"ASM Error: target asic is uninitialized\\n\";\n        return -1;\n    }\n\n    // Delete TextData for any previous runs\n    FlushText();\n\n#if 0\n    outs() << \"ASM Info: running assembly for target: \" << MCPU << \"\\n\";\n    outs() << \"ASM Info: source:\\n\";\n    outs() << AssemblySource << \"\\n\";\n#endif\n\n    // Initialize MCOptions and target triple\n    const MCTargetOptions MCOptions;\n    Triple TheTriple;\n\n    const Target* TheTarget =\n        TargetRegistry::lookupTarget(ArchName, TheTriple, Error);\n    if (!TheTarget) {\n        outs() << Error;\n        return -1;\n    }\n\n    TheTriple.setArchName(ArchName);\n    TheTriple.setVendorName(VendorName);\n    TheTriple.setOSName(OSName);\n\n    TripleName = TheTriple.getTriple();\n    TheTriple.setTriple(Triple::normalize(TripleName));\n\n    // Create MemoryBuffer for assembly source\n    StringRef AssemblyRef(AssemblySource);\n    std::unique_ptr<MemoryBuffer> BufferPtr =\n        MemoryBuffer::getMemBuffer(AssemblyRef, \"\", false);\n    if (!BufferPtr->getBufferSize()) {\n        outs() << \"ASM Error: assembly source is empty\\n\";\n        return -1;\n    }\n\n    // Instantiate SrcMgr and transfer BufferPtr ownership\n    SourceMgr SrcMgr;\n    SrcMgr.AddNewSourceBuffer(std::move(BufferPtr), SMLoc());\n\n    // Initialize MC interfaces and base class objects\n    std::unique_ptr<const MCRegisterInfo> MRI(\n            TheTarget->createMCRegInfo(TripleName));\n    if (!MRI) {\n        outs() << \"ASM Error: no register info for target \" << MCPU << \"\\n\";\n        return -1;\n    }\n#if LLVM_VERSION_MAJOR > 9\n    std::unique_ptr<const MCAsmInfo> MAI(\n            TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));\n#else\n    std::unique_ptr<const MCAsmInfo> MAI(\n            TheTarget->createMCAsmInfo(*MRI, TripleName));\n#endif\n    if (!MAI) {\n        outs() << \"ASM Error: no assembly info for target \" << MCPU << \"\\n\";\n        return -1;\n    }\n    std::unique_ptr<MCInstrInfo> MCII(\n            TheTarget->createMCInstrInfo());\n    if (!MCII) {\n        outs() << \"ASM Error: no instruction info for target \" << MCPU << \"\\n\";\n        return -1;\n    }\n    std::unique_ptr<MCSubtargetInfo> STI(\n            TheTarget->createMCSubtargetInfo(TripleName, MCPU, std::string()));\n    if (!STI || !STI->isCPUStringValid(MCPU)) {\n        outs() << \"ASM Error: no subtarget info for target \" << MCPU << \"\\n\";\n        return -1;\n    }\n\n    // Set up the MCContext for creating symbols and MCExpr's\n#if LLVM_VERSION_MAJOR > 12\n    MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr, &MCOptions);\n#else\n    MCObjectFileInfo MOFI;\n    MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions);\n    MOFI.InitMCObjectFileInfo(TheTriple, true, Ctx);\n#endif\n\n    // Finalize setup for output object code stream\n    std::string Data;\n    std::unique_ptr<raw_string_ostream> DataStream(std::make_unique<raw_string_ostream>(Data));\n    std::unique_ptr<buffer_ostream> BOS(std::make_unique<buffer_ostream>(*DataStream));\n    raw_pwrite_stream* OS = BOS.get();\n\n#if LLVM_VERSION_MAJOR > 14\n    MCCodeEmitter* CE = TheTarget->createMCCodeEmitter(*MCII, Ctx);\n#else\n    MCCodeEmitter* CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);\n#endif\n    MCAsmBackend* MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions);\n\n    if (!MAB) {\n\t    outs() << \"ASM Error: Unable to create MCA Backend\\n\";\n\t    return -1;\n    }\n\n#if LLVM_VERSION_MAJOR > 20\n    std::unique_ptr<MCStreamer> Streamer(TheTarget->createMCObjectStreamer(\n        TheTriple, Ctx,\n\tstd::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(*OS),\n        std::unique_ptr<MCCodeEmitter>(CE), *STI));\n#else\n    std::unique_ptr<MCStreamer> Streamer(TheTarget->createMCObjectStreamer(\n        TheTriple, Ctx,\n        std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(*OS),\n        std::unique_ptr<MCCodeEmitter>(CE), *STI, MCOptions.MCRelaxAll,\n        MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false));\n#endif\n\n    std::unique_ptr<MCAsmParser> Parser(\n            createMCAsmParser(SrcMgr, Ctx, *Streamer, *MAI));\n\n    // Set parser to target parser and run\n    std::unique_ptr<MCTargetAsmParser> TAP(\n            TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));\n    if (!TAP) {\n        outs() << \"ASM Error: no assembly parsing support for target \" << MCPU << \"\\n\";\n        return -1;\n    }\n    Parser->setTargetParser(*TAP);\n\n    if (Parser->Run(true)) {\n        outs() << \"ASM Error: assembly parser failed\\n\";\n        return -1;\n    }\n\n    BOS.reset();\n    DataStream->flush();\n\n    int ret = ExtractELFText(Data.data());\n    if (ret < 0 || !TextData) {\n        outs() << \"ASM Error: .text extraction failed\\n\";\n        return ret;\n    }\n\n#if 0\n    PrintELFHex(Data);\n    PrintTextHex();\n#endif\n\n    return 0;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/Assemble.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef _ASSEMBLE_H_\n#define _ASSEMBLE_H_\n\n#include \"OSWrapper.hpp\"\n\n#define ASM_MCPU_LEN 16\n\n/* initialize LLVM targets and assembly printers/parsers */\nvoid Init_LLVM();\n/* shutdown LLVM */\nvoid Shutdown_LLVM();\n\nclass Assembler {\n  private:\n      const char* ArchName = \"amdgcn\";\n      const char* VendorName = \"amd\";\n      const char* OSName = \"amdhsa\";\n      char MCPU[ASM_MCPU_LEN];\n\n      std::string TripleName;\n      std::string Error;\n\n      char* TextData;\n      size_t TextSize;\n\n      void SetTargetAsic(const uint32_t Gfxv);\n\n      void FlushText();\n      void PrintELFHex(const std::string Data);\n      int ExtractELFText(const char* RawData);\n\n  public:\n      Assembler(const uint32_t Gfxv);\n      ~Assembler();\n\n      void PrintTextHex();\n      const char* GetTargetAsic();\n\n      const char* GetInstrStream();\n      const size_t GetInstrStreamSize();\n      int CopyInstrStream(char* OutBuf, const size_t BufSize = PAGE_SIZE);\n\n      int RunAssemble(const char* const AssemblySource);\n      int RunAssembleBuf(const char* const AssemblySource, char* OutBuf,\n                         const size_t BufSize = PAGE_SIZE);\n      int RunAssembleBuf(const char* const AssemblySource, char* OutBuf,\n                         const size_t BufSize, const uint32_t Gfxv);\n};\n\n#endif  // _ASSEMBLE_H_\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BaseDebug.cpp",
    "content": "/*\n * Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"BaseDebug.hpp\"\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <hsakmt/linux/kfd_ioctl.h>\n#include <fcntl.h>\n#include \"unistd.h\"\n\nBaseDebug::BaseDebug(void) {\n}\n\nBaseDebug::~BaseDebug(void) {\n    /*\n     * If the process is still attached, close and destroy the polling file\n     * descriptor.  Note that on process termination, the KFD automatically\n     * disables processes that are still runtime enabled and debug enabled\n     * so we don't do it here.\n     */\n    if (m_Pid) {\n        close(m_Fd.fd);\n        unlink(m_Fd_Name);\n    }\n}\n\n// Creates temp file descriptor and debug attaches.\nHSAKMT_STATUS BaseDebug::Attach(struct kfd_runtime_info *rInfo,\n                                int rInfoSize,\n                                unsigned int pid,\n                                uint64_t exceptionEnable) {\n    struct kfd_ioctl_dbg_trap_args args = {0};\n    char fd_name[32];\n\n    memset(&args, 0x00, sizeof(args));\n\n    mkfifo(m_Fd_Name, 0666);\n    m_Fd.fd = open(m_Fd_Name, O_CLOEXEC | O_NONBLOCK | O_RDWR);\n    m_Fd.events = POLLIN | POLLRDNORM;\n\n    args.pid = pid;\n    args.op = KFD_IOC_DBG_TRAP_ENABLE;\n    args.enable.rinfo_ptr = (uint64_t)rInfo;\n    args.enable.rinfo_size = rInfoSize;\n    args.enable.dbg_fd = m_Fd.fd;\n    args.enable.exception_mask = exceptionEnable;\n\n    if (hsaKmtDebugTrapIoctl(&args, NULL, NULL)) {\n        close(m_Fd.fd);\n        unlink(m_Fd_Name);\n        return HSAKMT_STATUS_ERROR;\n    }\n\n    m_Pid = pid;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\n\nvoid BaseDebug::Detach(void) {\n    struct kfd_ioctl_dbg_trap_args args = {0};\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_DISABLE;\n\n    hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    close(m_Fd.fd);\n    unlink(m_Fd_Name);\n\n    m_Pid = 0;\n    m_Fd.fd = 0;\n    m_Fd.events = 0;\n}\n\nHSAKMT_STATUS BaseDebug::SendRuntimeEvent(uint64_t exceptions, int gpuId, int queueId)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT;\n    args.send_runtime_event.exception_mask = exceptions;\n    args.send_runtime_event.gpu_id = gpuId;\n    args.send_runtime_event.queue_id = queueId;\n\n    return hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n}\n\nHSAKMT_STATUS BaseDebug::QueryDebugEvent(uint64_t *exceptions,\n                                         uint32_t *gpuId, uint32_t *queueId,\n                                         int timeoutMsec)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n    HSAKMT_STATUS result;\n    int r = poll(&m_Fd, 1, timeoutMsec);\n\n    if (r > 0) {\n        char tmp[r];\n\n        read(m_Fd.fd, tmp, sizeof(tmp));\n    } else {\n        return HSAKMT_STATUS_ERROR;\n    }\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT;\n    args.query_debug_event.exception_mask = *exceptions;\n\n    result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *exceptions = args.query_debug_event.exception_mask;\n\n    if (gpuId)\n        *gpuId = args.query_debug_event.gpu_id;\n\n    if (queueId)\n        *queueId = args.query_debug_event.queue_id;\n\n    return result;\n}\n\nvoid BaseDebug::SetExceptionsEnabled(uint64_t exceptions)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED;\n    args.set_exceptions_enabled.exception_mask = exceptions;\n\n    hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n}\n\nHSAKMT_STATUS BaseDebug::SuspendQueues(unsigned int *numQueues,\n                                       HSA_QUEUEID *queues,\n                                       uint32_t *queueIds,\n                                       uint64_t exceptionsToClear)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SUSPEND_QUEUES;\n    args.suspend_queues.num_queues = *numQueues;\n    args.suspend_queues.queue_array_ptr = (uint64_t)queueIds;\n    args.suspend_queues.exception_mask = exceptionsToClear;\n\n    return hsaKmtDebugTrapIoctl(&args, queues, (HSAuint64 *)numQueues);\n}\n\nHSAKMT_STATUS BaseDebug::ResumeQueues(unsigned int *numQueues,\n                                       HSA_QUEUEID *queues,\n                                       uint32_t *queueIds)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_RESUME_QUEUES;\n    args.resume_queues.num_queues = *numQueues;\n    args.resume_queues.queue_array_ptr = (uint64_t)queueIds;\n\n    return hsaKmtDebugTrapIoctl(&args, queues, (HSAuint64 *)numQueues);\n}\n\nHSAKMT_STATUS BaseDebug::QueueSnapshot(uint64_t exceptionsToClear,\n                                  uint64_t snapshotBufAddr,\n                                  uint32_t *numSnapshots)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n    HSAKMT_STATUS result;\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT;\n    args.queue_snapshot.exception_mask = exceptionsToClear;\n    args.queue_snapshot.snapshot_buf_ptr = snapshotBufAddr;\n    args.queue_snapshot.num_queues = *numSnapshots;\n    args.queue_snapshot.entry_size = sizeof(struct kfd_queue_snapshot_entry);\n\n    result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *numSnapshots = args.queue_snapshot.num_queues;\n\n    return result;\n}\n\nHSAKMT_STATUS BaseDebug::DeviceSnapshot(uint64_t exceptionsToClear,\n                                  uint64_t snapshotBufAddr,\n                                  uint32_t *numSnapshots)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n    HSAKMT_STATUS result;\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT;\n    args.device_snapshot.exception_mask = exceptionsToClear;\n    args.device_snapshot.snapshot_buf_ptr = snapshotBufAddr;\n    args.device_snapshot.num_devices = *numSnapshots;\n    args.device_snapshot.entry_size = sizeof(struct kfd_dbg_device_info_entry);\n\n    result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *numSnapshots = args.device_snapshot.num_devices;\n\n    return result;\n}\n\nHSAKMT_STATUS BaseDebug::SetWaveLaunchOverride(int mode,\n                                               uint32_t *enableMask,\n                                               uint32_t *supportMask)\n{\n    struct kfd_ioctl_dbg_trap_args args = {0};\n    HSAKMT_STATUS Result;\n\n    memset(&args, 0x00, sizeof(args));\n\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE;\n    args.launch_override.override_mode = mode;\n    args.launch_override.enable_mask = *enableMask;\n    args.launch_override.support_request_mask = *supportMask;\n\n    Result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *enableMask = args.launch_override.enable_mask;\n    *supportMask = args.launch_override.support_request_mask;\n\n    return Result;\n}\n\nHSAKMT_STATUS BaseDebug::SetAddressWatch(uint64_t address,\n                                         int mode,\n                                         uint64_t mask,\n                                         uint32_t gpuId,\n                                         uint32_t *id)\n{\n    struct kfd_ioctl_dbg_trap_args args = {};\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH;\n    args.set_node_address_watch.address = address;\n    args.set_node_address_watch.mode = mode;\n    args.set_node_address_watch.mask = mask;\n    args.set_node_address_watch.gpu_id = gpuId;\n\n    HSAKMT_STATUS result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *id = args.set_node_address_watch.id;\n\n    return result;\n}\n\nHSAKMT_STATUS BaseDebug::ClearAddressWatch(uint32_t gpuId,\n                                           uint32_t id)\n{\n    struct kfd_ioctl_dbg_trap_args args = {};\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH;\n    args.clear_node_address_watch.gpu_id = gpuId;\n    args.clear_node_address_watch.id = id;\n\n    return hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n}\n\nHSAKMT_STATUS BaseDebug::SetFlags(uint32_t *flags)\n{\n    struct kfd_ioctl_dbg_trap_args args = {};\n    args.pid = m_Pid;\n    args.op = KFD_IOC_DBG_TRAP_SET_FLAGS;\n    args.set_flags.flags = *flags;\n\n    HSAKMT_STATUS result = hsaKmtDebugTrapIoctl(&args, NULL, NULL);\n\n    *flags = args.set_flags.flags;\n\n    return result;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BaseDebug.hpp",
    "content": "/*\n * Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_BASE_DEBUG__H__\n#define __KFD_BASE_DEBUG__H__\n\n#include \"hsakmt/hsakmt.h\"\n#include <poll.h>\n#include <stdlib.h>\n\n// @class BaseDebug\nclass BaseDebug {\n public:\n    BaseDebug(void);\n    virtual ~BaseDebug(void);\n\n    HSAKMT_STATUS Attach(struct kfd_runtime_info *rInfo,\n                         int rInfoSize,\n                         unsigned int pid,\n                         uint64_t exceptionEnable);\n\n    void Detach(void);\n    HSAKMT_STATUS SendRuntimeEvent(uint64_t exceptions, int gpuId, int queueId);\n    HSAKMT_STATUS QueryDebugEvent(uint64_t *exceptions,\n                                  uint32_t *gpuId, uint32_t *queueId,\n                                  int timeoutMsec);\n    void SetExceptionsEnabled(uint64_t exceptions);\n    HSAKMT_STATUS SuspendQueues(unsigned int *numQueues, HSA_QUEUEID *queues, uint32_t *queueIds,\n                                uint64_t exceptionsToClear);\n    HSAKMT_STATUS ResumeQueues(unsigned int *numQueues, HSA_QUEUEID *queues, uint32_t *queueIds);\n    HSAKMT_STATUS QueueSnapshot(uint64_t exceptionsToClear, uint64_t snapshotBufAddr,\n                                uint32_t *numSnapshots);\n    HSAKMT_STATUS DeviceSnapshot(uint64_t exceptionsToClear, uint64_t snapshotBuffAddr,\n                                 uint32_t *numSnapshots);\n    HSAKMT_STATUS SetWaveLaunchOverride(int mode, uint32_t *enableMask, uint32_t *supportMask);\n    HSAKMT_STATUS SetAddressWatch(uint64_t address, int mode, uint64_t mask, uint32_t gpuId, uint32_t *id);\n    HSAKMT_STATUS ClearAddressWatch(uint32_t gpuId, uint32_t id);\n    HSAKMT_STATUS SetFlags(uint32_t *flags);\n\n private:\n    unsigned int m_Pid;\n    struct pollfd m_Fd;\n    const char *m_Fd_Name = \"/tmp/dbg_fifo\";\n};\n\n#endif  // __KFD_BASE_DEBUG__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BasePacket.cpp",
    "content": "/*\n * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"BasePacket.hpp\"\n#include \"KFDTestUtil.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n\nBasePacket::BasePacket(void): m_packetAllocation(NULL) {\n    m_FamilyId = g_baseTest->GetFamilyIdFromDefaultNode();\n}\n\nBasePacket::~BasePacket(void) {\n    if (m_packetAllocation)\n        free(m_packetAllocation);\n}\n\nvoid BasePacket::Dump() const {\n    unsigned int size = SizeInDWords();\n    const HSAuint32 *packet = (const HSAuint32 *)GetPacket();\n    std::ostream &log = LOG();\n    unsigned int i;\n\n    log << \"Packet dump:\" << std::hex;\n    for (i = 0; i < size; i++)\n        log << \" \" << std::setw(8) << std::setfill('0') << packet[i];\n    log << std::endl;\n}\n\nvoid *BasePacket::AllocPacket(void) {\n    unsigned int size = SizeInBytes();\n\n    EXPECT_NE(0, size);\n    if (!size)\n        return NULL;\n\n    m_packetAllocation = calloc(1, size);\n    EXPECT_NOTNULL(m_packetAllocation);\n\n    return m_packetAllocation;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BasePacket.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_BASE_PACKET__H__\n#define __KFD_BASE_PACKET__H__\n\n/**\n * All packets profiles must be defined here\n * Every type defined here has sub-types\n */\nenum PACKETTYPE {\n    PACKETTYPE_PM4,\n    PACKETTYPE_SDMA,\n    PACKETTYPE_AQL\n};\n\n// @class BasePacket\nclass BasePacket {\n public:\n    BasePacket(void);\n    virtual ~BasePacket(void);\n\n    // @returns Packet type\n    virtual PACKETTYPE PacketType() const = 0;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const = 0;\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const = 0;\n    // @returns Packet size in dwordS\n    unsigned int SizeInDWords() const { return SizeInBytes()/sizeof(unsigned int); }\n\n    void Dump() const;\n\n protected:\n    unsigned int m_FamilyId;\n    void *m_packetAllocation;\n\n    void *AllocPacket(void);\n};\n\n#endif  // __KFD_BASE_PACKET__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BaseQueue.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"BaseQueue.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"AqlQueue.hpp\"\n#include \"hsakmt/hsakmt.h\"\n#include \"KFDBaseComponentTest.hpp\"\n\nBaseQueue::BaseQueue()\n    :m_QueueBuf(NULL),\n    m_SkipWaitConsumption(true) {\n}\n\nBaseQueue::~BaseQueue(void) {\n    Destroy();\n}\n\nHSAKMT_STATUS BaseQueue::Create(unsigned int NodeId, unsigned int size, HSAuint64 *pointers) {\n    HSAKMT_STATUS status;\n    HSA_QUEUE_TYPE type = GetQueueType();\n\n    if (m_QueueBuf != NULL) {\n        // Queue already exists, one queue per object\n        Destroy();\n    }\n\n    memset(&m_Resources, 0, sizeof(m_Resources));\n\n    m_QueueBuf = new HsaMemoryBuffer(size, NodeId, true/*zero*/, false/*local*/, true/*exec*/,\n                        /*isScratch */ false, /* isReadOnly */false, /* isUncached */true);\n\n    if (type == HSA_QUEUE_COMPUTE_AQL) {\n        m_Resources.Queue_read_ptr_aql = &pointers[0];\n        m_Resources.Queue_write_ptr_aql = &pointers[1];\n    }\n\n    if (type == HSA_QUEUE_SDMA_BY_ENG_ID)\n        status = hsaKmtCreateQueueExt(NodeId,\n                                      type,\n                                      DEFAULT_QUEUE_PERCENTAGE,\n                                      DEFAULT_PRIORITY,\n                                      m_SdmaEngineId,\n                                      m_QueueBuf->As<unsigned int*>(),\n                                      m_QueueBuf->Size(),\n                                      NULL,\n                                      &m_Resources);\n    else\n        status = hsaKmtCreateQueue(NodeId,\n                                   type,\n                                   DEFAULT_QUEUE_PERCENTAGE,\n                                   DEFAULT_PRIORITY,\n                                   m_QueueBuf->As<unsigned int*>(),\n                                   m_QueueBuf->Size(),\n                                   NULL,\n                                   &m_Resources);\n\n    if (status != HSAKMT_STATUS_SUCCESS) {\n        return status;\n    }\n\n    if (m_Resources.Queue_read_ptr  == NULL) {\n        WARN() << \"CreateQueue: read pointer value should be 0\" << std::endl;\n        status = HSAKMT_STATUS_ERROR;\n    }\n\n    if (m_Resources.Queue_write_ptr  == NULL) {\n        WARN() << \"CreateQueue: write pointer value should be 0\" << std::endl;\n        status = HSAKMT_STATUS_ERROR;\n    }\n\n    // Needs to match the queue write ptr\n    m_pendingWptr = 0;\n    m_pendingWptr64 = 0;\n    m_Node = NodeId;\n    m_FamilyId = g_baseTest->GetFamilyIdFromNodeId(NodeId);\n    return status;\n}\n\nHSAKMT_STATUS BaseQueue::Update(unsigned int percent, HSA_QUEUE_PRIORITY priority, bool nullifyBuffer) {\n    void* pNewBuffer = (nullifyBuffer ? NULL : m_QueueBuf->As<void*>());\n    HSAuint64 newSize = (nullifyBuffer ? 0 : m_QueueBuf->Size());\n\n    return hsaKmtUpdateQueue(m_Resources.QueueId, percent, priority, pNewBuffer, newSize, NULL);\n}\n\nHSAKMT_STATUS BaseQueue::SetCUMask(unsigned int *mask, unsigned int mask_count) {\n    return hsaKmtSetQueueCUMask(m_Resources.QueueId, mask_count, mask);\n}\n\nHSAKMT_STATUS BaseQueue::Destroy() {\n    HSAKMT_STATUS status =  HSAKMT_STATUS_SUCCESS;\n\n    if (m_QueueBuf != NULL) {\n        status = hsaKmtDestroyQueue(m_Resources.QueueId);\n\n        if (status == HSAKMT_STATUS_SUCCESS) {\n            delete m_QueueBuf;\n            m_QueueBuf = NULL;\n        }\n    }\n\n    return status;\n}\n\nvoid BaseQueue::PlaceAndSubmitPacket(const BasePacket &packet) {\n    PlacePacket(packet);\n    SubmitPacket();\n}\n\nvoid BaseQueue::Wait4PacketConsumption(HsaEvent *event, unsigned int timeOut) {\n    ASSERT_TRUE(!event) << \"Not supported!\" << std::endl;\n    ASSERT_TRUE(WaitOnValue(m_Resources.Queue_read_ptr, RptrWhenConsumed(), timeOut));\n}\n\nbool BaseQueue::AllPacketsSubmitted() {\n    return Wptr() == Rptr();\n}\n\nvoid BaseQueue::PlacePacket(const BasePacket &packet) {\n    ASSERT_EQ(packet.PacketType(), PacketTypeSupported())\n        << \"Cannot add a packet since packet type doesn't match queue\";\n\n    unsigned int readPtr = Rptr();\n    unsigned int writePtr = m_pendingWptr;\n    HSAuint64 writePtr64 = m_pendingWptr64;\n\n    unsigned int packetSizeInDwords = packet.SizeInDWords();\n    unsigned int dwordsRequired = packetSizeInDwords;\n    unsigned int queueSizeInDWord = m_QueueBuf->Size() / sizeof(uint32_t);\n\n    if (writePtr + packetSizeInDwords > queueSizeInDWord) {\n        // Wraparound expected. We need enough room to also place NOPs to avoid crossing the buffer end.\n        dwordsRequired +=  queueSizeInDWord - writePtr;\n    }\n\n    unsigned int dwordsAvailable = (readPtr - 1 - writePtr + queueSizeInDWord) % queueSizeInDWord;\n    ASSERT_GE(dwordsAvailable, dwordsRequired) << \"Cannot add a packet, buffer overrun\";\n\n    ASSERT_GE(queueSizeInDWord, packetSizeInDwords) << \"Cannot add a packet, packet size too large\";\n\n    if (writePtr + packetSizeInDwords >= queueSizeInDWord) {\n        // Wraparound\n        while (writePtr + packetSizeInDwords > queueSizeInDWord) {\n            m_QueueBuf->As<unsigned int *>()[writePtr] = CMD_NOP;\n            writePtr = (writePtr + 1) % queueSizeInDWord;\n            writePtr64++;\n        }\n\n        // Not updating Wptr since we might want to place the packet without submission\n        m_pendingWptr = (writePtr % queueSizeInDWord);\n        m_pendingWptr64 = writePtr64;\n    }\n\n    memcpy(m_pendingWptr + m_QueueBuf->As<unsigned int*>(), packet.GetPacket(), packetSizeInDwords * 4);\n\n    m_pendingWptr = (m_pendingWptr + packetSizeInDwords) % queueSizeInDWord;\n    m_pendingWptr64 += packetSizeInDwords;\n}\n\nBaseQueue* QueueArray::GetQueue(unsigned int Node) {\n    // If a queue exists for that node then return, else create one\n    for (unsigned int i = 0; i < m_QueueList.size(); i++) {\n        if (Node == m_QueueList.at(i)->GetNodeId())\n            return m_QueueList.at(i);\n    }\n\n    BaseQueue *pQueue = NULL;\n\n    switch (m_QueueType) {\n    case HSA_QUEUE_COMPUTE:\n        pQueue = new PM4Queue();\n        break;\n    case HSA_QUEUE_SDMA:\n        pQueue = new SDMAQueue();\n        break;\n    case HSA_QUEUE_COMPUTE_AQL:\n        pQueue = new AqlQueue();\n        break;\n    default:\n        return NULL;\n    }\n\n    if (pQueue) {\n        pQueue->Create(Node);\n        m_QueueList.push_back(pQueue);\n    }\n    return pQueue;\n}\n\nvoid QueueArray::Destroy() {\n    for (unsigned int i = 0; i < m_QueueList.size(); i++)\n        delete m_QueueList.at(i);\n\n    m_QueueList.clear();\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/BaseQueue.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_BASE_QUEUE__H__\n#define __KFD_BASE_QUEUE__H__\n\n#include <vector>\n#include \"KFDTestUtil.hpp\"\n#include \"BasePacket.hpp\"\n\n// @class BasePacket\nclass BaseQueue {\n public:\n    static const unsigned int DEFAULT_QUEUE_SIZE = PAGE_SIZE;\n    static const HSA_QUEUE_PRIORITY DEFAULT_PRIORITY = HSA_QUEUE_PRIORITY_NORMAL;\n    static const unsigned int DEFAULT_QUEUE_PERCENTAGE  = 100;\n    static const unsigned int ZERO_QUEUE_PERCENTAGE     = 0;\n    static const unsigned int     FLUSH_GPU_CACHES_TO   = 1000;\n\n    BaseQueue(void);\n    virtual ~BaseQueue(void);\n\n    /** Create the queue.\n     *  @see hsaKmtCreateQueue\n     *  @param pointers is used only for creating AQL queues. Otherwise it is omitted.\n     */\n    virtual HSAKMT_STATUS Create(unsigned int NodeId, unsigned int size = DEFAULT_QUEUE_SIZE,\n                                 HSAuint64 *pointers = NULL);\n    /** Update the queue.\n     *  @see hsaKmtUpdateQueue\n     *  @param percent New queue percentage\n     *  @param priority New queue priority\n     *  @param nullifyBuffer\n     *      If 'true', set the new buffer address to NULL and the size to 0. Otherwise\n     *      don't change the queue buffer address/size.\n     */\n    virtual HSAKMT_STATUS Update(unsigned int percent, HSA_QUEUE_PRIORITY priority, bool nullifyBuffer);\n    virtual HSAKMT_STATUS SetCUMask(unsigned int *mask, unsigned int mask_count);\n    /** Destroy the queue.\n     *  @see hsaKmtDestroyQueue\n     */\n    virtual HSAKMT_STATUS Destroy();\n    /** Wait for all the packets submitted to the queue to be consumed. (i.e. wait until RPTR=WPTR).\n     *  Note that all packets being consumed is not the same as all packets being processed.\n     */\n    virtual void Wait4PacketConsumption(HsaEvent *event = NULL, unsigned int timeOut = g_TestTimeOut);\n    /** @brief Place packet and submit it in one function\n     */\n    virtual void PlaceAndSubmitPacket(const BasePacket &packet);\n    /** @brief Copy packet to queue and update write pointer\n     */\n    virtual void PlacePacket(const BasePacket &packet);\n    /** @brief Update queue write pointer and set the queue doorbell to the queue write pointer\n     */\n    virtual void SubmitPacket() = 0;\n    /** @brief Check if all packets in queue are already processed\n     *  Compare queue read and write pointers\n     */\n    bool AllPacketsSubmitted();\n\n    void SetSkipWaitConsump(int val) { m_SkipWaitConsumption = val; }\n    int GetSkipWaitConsump() { return m_SkipWaitConsumption; }\n    int Size() { return m_QueueBuf->Size(); }\n\n    HsaQueueResource *GetResource() { return &m_Resources; }\n    unsigned int GetPendingWptr() { return m_pendingWptr; }\n    HSAuint64 GetPendingWptr64() { return m_pendingWptr64; }\n    virtual _HSA_QUEUE_TYPE GetQueueType() = 0;\n    unsigned int GetNodeId() { return m_Node; }\n    unsigned int GetFamilyId() { return m_FamilyId; }\n    int GetSDMAEngineId() { return m_SdmaEngineId; }\n\n protected:\n    static const unsigned int CMD_NOP_TYPE_2        = 0x80000000;\n    static const unsigned int CMD_NOP_TYPE_3        = 0xFFFF1002;\n\n    unsigned int CMD_NOP;\n    unsigned int m_pendingWptr;\n    HSAuint64 m_pendingWptr64;\n    HsaQueueResource m_Resources;\n    HsaMemoryBuffer *m_QueueBuf;\n    unsigned int m_Node;\n    unsigned int m_FamilyId;\n    int m_SdmaEngineId;\n\n    // @return Write pointer modulo queue size in dwords\n    virtual unsigned int Wptr() = 0;\n    // @return Read pointer modulo queue size in dwords\n    virtual unsigned int Rptr() = 0;\n    // @return Expected m_Resources.Queue_read_ptr when all packets consumed\n    virtual unsigned int RptrWhenConsumed() = 0;\n    virtual PACKETTYPE PacketTypeSupported() = 0;\n\n private:\n    // Some tests(such as exception) may not need wait pm4 packet consumption on CZ.\n    int m_SkipWaitConsumption;\n};\n\n\n// @class QueueArray\n// Managed QueueArray for different GPU Nodes\nclass QueueArray {\n    // List of Queues. One for each GPU\n    std::vector<BaseQueue*> m_QueueList;\n    _HSA_QUEUE_TYPE m_QueueType;\n\n public:\n    QueueArray(_HSA_QUEUE_TYPE type): m_QueueType(type) {}\n    ~QueueArray() {\n        Destroy();\n    }\n\n    BaseQueue* GetQueue(unsigned int Node);\n    void Destroy();\n};\n\n#endif  // __KFD_BASE_QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/Dispatch.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"Dispatch.hpp\"\n\n#include \"PM4Packet.hpp\"\n\n#include \"asic_reg/gfx_7_2_d.h\"\n#include \"asic_reg/gfx_7_2_sh_mask.h\"\n\n#include \"KFDBaseComponentTest.hpp\"\n\n#define mmCOMPUTE_PGM_RSRC3                                                     0x2e2d\n\nDispatch::Dispatch(const HsaMemoryBuffer& isaBuf, const bool eventAutoReset)\n    :m_IsaBuf(isaBuf), m_IndirectBuf(PACKETTYPE_PM4, PAGE_SIZE / sizeof(unsigned int), isaBuf.Node()),\n    m_DimX(1), m_DimY(1), m_DimZ(1), m_pArg1(NULL), m_pArg2(NULL), m_pEop(NULL), m_ScratchEn(false),\n    m_ComputeTmpringSize(0), m_scratch_base(0ll), m_SpiPriority(0) {\n    HsaEventDescriptor eventDesc;\n    eventDesc.EventType = HSA_EVENTTYPE_SIGNAL;\n    eventDesc.NodeId = isaBuf.Node();\n    eventDesc.SyncVar.SyncVar.UserData = NULL;\n    eventDesc.SyncVar.SyncVarSize = 0;\n\n    hsaKmtCreateEvent(&eventDesc, !eventAutoReset, false, &m_pEop);\n\n    m_FamilyId  = g_baseTest->GetFamilyIdFromNodeId(isaBuf.Node());\n    m_NeedCwsrWA = g_baseTest->NeedCwsrWA(isaBuf.Node());\n}\n\nDispatch::~Dispatch() {\n    if (m_pEop != NULL)\n        hsaKmtDestroyEvent(m_pEop);\n}\n\nvoid Dispatch::SetArgs(void* pArg1, void* pArg2) {\n    m_pArg1 = pArg1;\n    m_pArg2 = pArg2;\n}\n\nvoid Dispatch::SetDim(unsigned int x, unsigned int y, unsigned int z) {\n    m_DimX = x;\n    m_DimY = y;\n    m_DimZ = z;\n}\n\nvoid Dispatch::SetScratch(int numWaves, int waveSize, HSAuint64 scratch_base) {\n    m_ComputeTmpringSize = ((waveSize << 12) | (numWaves));\n    m_ScratchEn = true;\n    m_scratch_base = scratch_base;\n}\n\nvoid Dispatch::SetSpiPriority(unsigned int priority) {\n    m_SpiPriority = priority;\n}\n\nvoid Dispatch::SetPriv(bool priv) {\n    m_NeedCwsrWA = priv;\n}\n\nvoid Dispatch::Submit(BaseQueue& queue) {\n    ASSERT_NE(m_pEop, (void*)0);\n    EXPECT_EQ(m_FamilyId, queue.GetFamilyId());\n\n    BuildIb();\n\n    queue.PlaceAndSubmitPacket(PM4IndirectBufPacket(&m_IndirectBuf));\n\n    // Write data to SyncVar for synchronization purpose\n    if (m_pEop->EventData.EventData.SyncVar.SyncVar.UserData != NULL) {\n        queue.PlaceAndSubmitPacket(PM4WriteDataPacket((unsigned int*)m_pEop->\n            EventData.EventData.SyncVar.SyncVar.UserData, m_pEop->EventId));\n    }\n\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, m_pEop->EventData.HWData2, m_pEop->EventId));\n\n    if (!queue.GetSkipWaitConsump())\n        queue.Wait4PacketConsumption();\n}\n\nvoid Dispatch::Sync(unsigned int timeout) {\n    ASSERT_SUCCESS(hsaKmtWaitOnEvent(m_pEop, timeout));\n}\n\n// Returning with status in order to allow actions to be performed before process termination\nint Dispatch::SyncWithStatus(unsigned int timeout) {\n    int stat;\n\n    return ((stat = hsaKmtWaitOnEvent(m_pEop, timeout)) != HSAKMT_STATUS_SUCCESS);\n}\n\nvoid Dispatch::BuildIb() {\n    HSAuint64 shiftedIsaAddr = m_IsaBuf.As<uint64_t>() >> 8;\n    unsigned int arg0, arg1, arg2, arg3;\n    SplitU64(reinterpret_cast<uint64_t>(m_pArg1), arg0, arg1);\n    SplitU64(reinterpret_cast<uint64_t>(m_pArg2), arg2, arg3);\n\n    // Starts at COMPUTE_START_X\n    const unsigned int COMPUTE_DISPATCH_DIMS_VALUES[] = {\n        0,      // START_X\n        0,      // START_Y\n        0,      // START_Z\n        1,      // NUM_THREADS_X - this is actually the number of threads in a thread group\n        1,      // NUM_THREADS_Y\n        1,      // NUM_THREADS_Z\n        0,      // COMPUTE_PIPELINESTAT_ENABLE\n        0,      // COMPUTE_PERFCOUNT_ENABLE\n    };\n\n    /*\n     * For some special asics in the list of DEGFX11_12113\n     * COMPUTE_PGM_RSRC needs priv=1 to prevent hardware traps\n     */\n    const bool priv = m_NeedCwsrWA;\n\n    unsigned int pgmRsrc1 =\n        (0xc0 << COMPUTE_PGM_RSRC1__FLOAT_MODE__SHIFT) |\n        ((m_SpiPriority & 3) << COMPUTE_PGM_RSRC1__PRIORITY__SHIFT) |\n        (priv << COMPUTE_PGM_RSRC1__PRIV__SHIFT) |\n        ((m_FamilyId < FAMILY_GFX12) ? (0x2 << COMPUTE_PGM_RSRC1__SGPRS__SHIFT) : 0) |\n        (0x4 << COMPUTE_PGM_RSRC1__VGPRS__SHIFT);  // 4 * 8 = 32 VGPRs\n\n    unsigned int pgmRsrc2 = 0;\n    pgmRsrc2 |= (m_ScratchEn << COMPUTE_PGM_RSRC2__SCRATCH_EN__SHIFT)\n            & COMPUTE_PGM_RSRC2__SCRATCH_EN_MASK;\n    pgmRsrc2 |= ((m_scratch_base ? 6 : 4) << COMPUTE_PGM_RSRC2__USER_SGPR__SHIFT)\n            & COMPUTE_PGM_RSRC2__USER_SGPR_MASK;\n\n    if (m_FamilyId < FAMILY_GFX12) {\n        pgmRsrc2 |= (1 << COMPUTE_PGM_RSRC2__TRAP_PRESENT__SHIFT)\n            & COMPUTE_PGM_RSRC2__TRAP_PRESENT_MASK;\n    }\n\n    pgmRsrc2 |= (1 << COMPUTE_PGM_RSRC2__TGID_X_EN__SHIFT)\n            & COMPUTE_PGM_RSRC2__TGID_X_EN_MASK;\n    pgmRsrc2 |= (1 << COMPUTE_PGM_RSRC2__TIDIG_COMP_CNT__SHIFT)\n            & COMPUTE_PGM_RSRC2__TIDIG_COMP_CNT_MASK;\n    pgmRsrc2 |= (0 << COMPUTE_PGM_RSRC2__EXCP_EN__SHIFT)\n            & COMPUTE_PGM_RSRC2__EXCP_EN_MASK;\n    pgmRsrc2 |= (1 << COMPUTE_PGM_RSRC2__EXCP_EN_MSB__SHIFT)\n            & COMPUTE_PGM_RSRC2__EXCP_EN_MSB_MASK;\n\n    const unsigned int COMPUTE_PGM_RSRC[] = {\n        pgmRsrc1,\n        pgmRsrc2\n    };\n\n    // Starts at COMPUTE_PGM_LO\n    const unsigned int COMPUTE_PGM_VALUES_GFX8[] = {\n        static_cast<uint32_t>(shiftedIsaAddr),                  // PGM_LO\n        static_cast<uint32_t>(shiftedIsaAddr >> 32)             // PGM_HI\n            | (hsakmt_is_dgpu() ? 0 : (1<<8))                          // including PGM_ATC=?\n    };\n\n    // Starts at COMPUTE_PGM_LO\n    const unsigned int COMPUTE_PGM_VALUES_GFX9[] = {\n        static_cast<uint32_t>(shiftedIsaAddr),                  // PGM_LO\n        static_cast<uint32_t>(shiftedIsaAddr >> 32)             // PGM_HI\n            | (hsakmt_is_dgpu() ? 0 : (1<<8)),                         // including PGM_ATC=?\n        0,\n        0,\n        static_cast<uint32_t>(m_scratch_base >> 8),              // compute_dispatch_scratch_base\n        static_cast<uint32_t>(m_scratch_base >> 40)\n    };\n\n    // Starts at COMPUTE_RESOURCE_LIMITS\n    const unsigned int COMPUTE_RESOURCE_LIMITS[] = {\n        0,                      // COMPUTE_RESOURCE_LIMITS\n    };\n\n    // Starts at COMPUTE_TMPRING_SIZE\n    const unsigned int COMPUTE_TMPRING_SIZE[] = {\n        m_ComputeTmpringSize,   // COMPUTE_TMPRING_SIZE\n    };\n\n    // Starts at COMPUTE_RESTART_X\n    const unsigned int COMPUTE_RESTART_VALUES[] = {\n        0,                      // COMPUTE_RESTART_X\n        0,                      // COMPUTE_RESTART_Y\n        0,                      // COMPUTE_RESTART_Z\n        0                       // COMPUTE_THREAD_TRACE_ENABLE\n    };\n\n    // Starts at COMPUTE_USER_DATA_0\n    const unsigned int COMPUTE_USER_DATA_VALUES[] = {\n                // Reg name             - use in KFDtest - use in ABI\n        arg0,   // COMPUTE_USER_DATA_0  - arg0           - resource descriptor for the scratch buffer - 1st dword\n        arg1,   // COMPUTE_USER_DATA_1  - arg1           - resource descriptor for the scratch buffer - 2nd dword\n        arg2,   // COMPUTE_USER_DATA_2  - arg2           - resource descriptor for the scratch buffer - 3rd dword\n        arg3,   // COMPUTE_USER_DATA_3  - arg3           - resource descriptor for the scratch buffer - 4th dword\n        static_cast<uint32_t>(m_scratch_base),  // COMPUTE_USER_DATA_4  - flat_scratch_lo\n        static_cast<uint32_t>(m_scratch_base >> 32),  // COMPUTE_USER_DATA_4  - flat_scratch_hi\n        0,      // COMPUTE_USER_DATA_6  -                - AQL queue address, low part\n        0,      // COMPUTE_USER_DATA_7  -                - AQL queue address, high part\n        0,      // COMPUTE_USER_DATA_8  -                - kernel arguments block, low part\n        0,      // COMPUTE_USER_DATA_9  -                - kernel arguments block, high part\n        0,      // COMPUTE_USER_DATA_10 -                - unused\n        0,      // COMPUTE_USER_DATA_11 -                - unused\n        0,      // COMPUTE_USER_DATA_12 -                - unused\n        0,      // COMPUTE_USER_DATA_13 -                - unused\n        0,      // COMPUTE_USER_DATA_14 -                - unused\n        0,      // COMPUTE_USER_DATA_15 -                - unused\n    };\n\n    const unsigned int DISPATCH_INIT_VALUE = 0x00000021 | (hsakmt_is_dgpu() ? 0 : 0x1000) |\n                ((m_FamilyId >= FAMILY_NV) ? 0x8000 : 0);\n    // {COMPUTE_SHADER_EN=1, PARTIAL_TG_EN=0, FORCE_START_AT_000=0, ORDERED_APPEND_ENBL=0,\n    // ORDERED_APPEND_MODE=0, USE_THREAD_DIMENSIONS=1, ORDER_MODE=0, DISPATCH_CACHE_CNTL=0,\n    // SCALAR_L1_INV_VOL=0, VECTOR_L1_INV_VOL=0, DATA_ATC=?, RESTORE=0}\n    // Set CS_W32_EN for wave32 workloads for gfx10 since all the shaders used in KFDTest is 32 bit .\n\n    m_IndirectBuf.AddPacket(PM4AcquireMemoryPacket(m_FamilyId));\n\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_START_X, COMPUTE_DISPATCH_DIMS_VALUES,\n                                                  ARRAY_SIZE(COMPUTE_DISPATCH_DIMS_VALUES)));\n\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_PGM_LO,\n        (m_FamilyId >= FAMILY_AI) ? COMPUTE_PGM_VALUES_GFX9 : COMPUTE_PGM_VALUES_GFX8,\n        (m_FamilyId >= FAMILY_AI) ? ARRAY_SIZE(COMPUTE_PGM_VALUES_GFX9) : ARRAY_SIZE(COMPUTE_PGM_VALUES_GFX8)));\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_PGM_RSRC1, COMPUTE_PGM_RSRC,\n                                                  ARRAY_SIZE(COMPUTE_PGM_RSRC)));\n\n    if (m_FamilyId == FAMILY_AL || m_FamilyId == FAMILY_AV) {\n        const unsigned int COMPUTE_PGM_RSRC3[] = {9};\n        m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_PGM_RSRC3, COMPUTE_PGM_RSRC3,\n                                                      ARRAY_SIZE(COMPUTE_PGM_RSRC3)));\n    }\n\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_RESOURCE_LIMITS, COMPUTE_RESOURCE_LIMITS,\n                                                  ARRAY_SIZE(COMPUTE_RESOURCE_LIMITS)));\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_TMPRING_SIZE, COMPUTE_TMPRING_SIZE,\n                                                  ARRAY_SIZE(COMPUTE_TMPRING_SIZE)));\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_RESTART_X, COMPUTE_RESTART_VALUES,\n                                                  ARRAY_SIZE(COMPUTE_RESTART_VALUES)));\n\n    m_IndirectBuf.AddPacket(PM4SetShaderRegPacket(mmCOMPUTE_USER_DATA_0, COMPUTE_USER_DATA_VALUES,\n                                                  ARRAY_SIZE(COMPUTE_USER_DATA_VALUES)));\n\n    m_IndirectBuf.AddPacket(PM4DispatchDirectPacket(m_DimX, m_DimY, m_DimZ, DISPATCH_INIT_VALUE));\n\n    // EVENT_WRITE.partial_flush causes problems with preemptions in\n    // GWS testing. Since this is specific to this PM4 command and\n    // doesn't affect AQL, it's easier to fix KFDTest than the\n    // firmware.\n    //\n    // Replace PartialFlush with an ReleaseMem (with no interrupt) + WaitRegMem\n    //\n    // Original: m_IndirectBuf.AddPacket(PM4PartialFlushPacket());\n    uint32_t *nop = m_IndirectBuf.AddPacket(PM4NopPacket(2)); // NOP packet with one dword payload for the release-mem fence\n    m_IndirectBuf.AddPacket(PM4ReleaseMemoryPacket(m_FamilyId, true, (uint64_t)&nop[1], 0xdeadbeef));\n    m_IndirectBuf.AddPacket(PM4WaitRegMemPacket(true, (uint64_t)&nop[1], 0xdeadbeef, 4));\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/Dispatch.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_DISPATCH__H__\n#define __KFD_DISPATCH__H__\n#include \"KFDTestUtil.hpp\"\n#include \"IndirectBuffer.hpp\"\n#include \"BaseQueue.hpp\"\n\nclass Dispatch {\n public:\n    Dispatch(const HsaMemoryBuffer& isaBuf, const bool eventAutoReset = false);\n    ~Dispatch();\n\n    void SetArgs(void* pArg1, void* pArg2);\n\n    void SetDim(unsigned int x, unsigned int y, unsigned int z);\n\n    void Submit(BaseQueue& queue);\n\n    void Sync(unsigned int timeout = HSA_EVENTTIMEOUT_INFINITE);\n\n    int  SyncWithStatus(unsigned int timeout);\n\n    void SetScratch(int numWaves, int waveSize, HSAuint64 scratch_base);\n\n    void SetSpiPriority(unsigned int priority);\n    \n    void SetPriv(bool priv);\n\n    HsaEvent *GetHsaEvent() { return m_pEop; }\n\n private:\n    void BuildIb();\n\n private:\n    const HsaMemoryBuffer& m_IsaBuf;\n\n    IndirectBuffer m_IndirectBuf;\n\n    unsigned int m_DimX;\n    unsigned int m_DimY;\n    unsigned int m_DimZ;\n\n    void* m_pArg1;\n    void* m_pArg2;\n\n    HsaEvent* m_pEop;\n\n    bool            m_ScratchEn;\n    unsigned int    m_ComputeTmpringSize;\n\n    HSAuint64  m_scratch_base;\n    unsigned int m_SpiPriority;\n    unsigned int  m_FamilyId;\n    bool  m_NeedCwsrWA;\n};\n\n#endif  // __KFD_DISPATCH__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/GoogleTestExtension.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"GoogleTestExtension.hpp\"\n#include \"OSWrapper.hpp\"\n\nbool Ok2Run(unsigned int testProfile) {\n    bool testMatchProfile = true;\n    if ((testProfile & g_TestRunProfile) == 0) {\n        WARN() << \"Test is skipped beacuse profile does not match current run mode\" << std::endl;\n        testMatchProfile = false;\n    }\n\n    return testMatchProfile;\n}\n\n// This predication is used when specific HW capabilities must exist for the test to succeed.\nbool TestReqEnvCaps(unsigned int envCaps) {\n    bool testMatchEnv = true;\n    if ((envCaps & g_TestENVCaps) != envCaps) {\n        WARN() << \"Test is skipped due to HW capability issues\" << std::endl;\n        testMatchEnv = false;\n    }\n\n    return testMatchEnv;\n}\n\n// This predication is used when specific HW capabilities must be absent for the test to succeed.\n// e.g Testing capabilities not supported by HW scheduling\nbool TestReqNoEnvCaps(unsigned int envCaps) {\n    bool testMatchEnv = true;\n    if ((envCaps & g_TestENVCaps) != 0) {\n        WARN() << \"Test is skipped due to HW capability issues\" << std::endl;\n        testMatchEnv = false;\n    }\n\n    return testMatchEnv;\n}\n\nstd::ostream& operator<< (KFDLog log, LOGTYPE level) {\n    const char *heading;\n\n    if (level == LOGTYPE_WARNING) {\n        SetConsoleTextColor(TEXTCOLOR_YELLOW);\n        heading = \"[----------] \";\n    } else {\n        SetConsoleTextColor(TEXTCOLOR_GREEN);\n        heading = \"[          ] \";\n    }\n\n    std::clog << heading;\n    SetConsoleTextColor(TEXTCOLOR_WHITE);\n\n    return std::clog;\n}\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/GoogleTestExtension.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __GOOGLETEST_EXTENSION__H__\n#define __GOOGLETEST_EXTENSION__H__\n\n#include <gtest/gtest.h>\n#include \"hsakmt/hsakmt.h\"\n#include \"KFDTestFlags.hpp\"\n\nenum LOGTYPE {\n    LOGTYPE_INFO,      // msg header in green\n    LOGTYPE_WARNING    // msg header in yellow\n};\n\nclass KFDLog{};\nstd::ostream& operator << (KFDLog log, LOGTYPE level);\n\n// @brief  Log additional details, to be displayed in the same format as other google test outputs\n// Currently not supported by gtest\n// Should be used like cout: LOG() << \"message\" << value << std::endl;\n#define LOG()      KFDLog() << LOGTYPE_INFO\n#define WARN()     KFDLog() << LOGTYPE_WARNING\n\nclass KFDRecord: public testing::Test {\npublic:\n    KFDRecord(const char *val): m_val(val) {}\n    KFDRecord(std::string &val): m_val(val) {}\n    KFDRecord(HSAint64 val): m_val(std::to_string(val)) {}\n    KFDRecord(HSAuint64 val): m_val(std::to_string(val)) {}\n    KFDRecord(double val): m_val(std::to_string(val)) {}\n    ~KFDRecord() {\n        RecordProperty(m_key.str().c_str(), m_val.c_str());\n    }\n    std::stringstream &get_key_stream() {\n        return m_key;\n    }\n    virtual void TestBody() {};\nprivate:\n    std::string m_val;\n    std::stringstream m_key;\n};\n\n#define RECORD(val)     (KFDRecord(val).get_key_stream())\n\n// All tests MUST be in a try catch since the gtest flag to throw an exception on any fatal failure is enabled\n#define TEST_START(testProfile)   if (Ok2Run(testProfile)) try {\n#define TEST_END       } catch (...) {}\n\n// Used to wrap setup and teardown functions, anything that is built-in gtest and is not a test\n#define ROUTINE_START   try {\n#define ROUTINE_END       }catch(...) {}\n\n#define TEST_REQUIRE_ENV_CAPABILITIES(envCaps)          if (!TestReqEnvCaps(envCaps))  return;\n#define TEST_REQUIRE_NO_ENV_CAPABILITIES(envCaps)  if (!TestReqNoEnvCaps(envCaps))  return;\n\n#define ASSERT_SUCCESS(_val) ASSERT_EQ(HSAKMT_STATUS_SUCCESS, (_val))\n#define EXPECT_SUCCESS(_val) EXPECT_EQ(HSAKMT_STATUS_SUCCESS, (_val))\n\n#define EXPECT_EQ_GPU(expected, actual , gpuNode) EXPECT_EQ((expected), (actual)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define ASSERT_SUCCESS_GPU(_val, gpuNode) ASSERT_EQ(HSAKMT_STATUS_SUCCESS, (_val)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define EXPECT_SUCCESS_GPU(_val, gpuNode) EXPECT_EQ(HSAKMT_STATUS_SUCCESS, (_val)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n\n#define ASSERT_NOTNULL(_val) ASSERT_NE((void *)NULL, _val)\n#define EXPECT_NOTNULL(_val) EXPECT_NE((void *)NULL, _val)\n\n#define ASSERT_NOTNULL_GPU(_val, gpuNode) ASSERT_NE((void *)NULL, _val) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define EXPECT_NOTNULL_GPU(_val, gpuNode) EXPECT_NE((void *)NULL, _val) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n\n#define EXPECT_NE_GPU(expected, actual, gpuNode) EXPECT_NE((expected), (actual)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define EXPECT_GE_GPU(expected, actual, gpuNode) EXPECT_GE((expected), (actual)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n\n#define ASSERT_GE_GPU(val1, val2, gpuNode) ASSERT_GE((val1), (val2)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define ASSERT_NE_GPU(val1, val2, gpuNode) ASSERT_NE((val1), (val2)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n#define ASSERT_EQ_GPU(val1, val2, gpuNode) ASSERT_EQ((val1), (val2)) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n\n#define EXPECT_TRUE_GPU(condition, gpuNode) EXPECT_TRUE(condition) << \"gpuNodeID: \" << std::to_string(gpuNode) << \"\\n\"\n\n// @brief  Determines if it is ok to run a test given input flags\nbool Ok2Run(unsigned int testProfile);\n\n// @brief  Checks if all HW capabilities needed for a test to run exist\nbool TestReqEnvCaps(unsigned int hwCaps);\n\n// @brief  Checks if all HW capabilities that prevents a test from running are absent\nbool TestReqNoEnvCaps(unsigned int hwCaps);\n\n#endif\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/IndirectBuffer.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"IndirectBuffer.hpp\"\n#include \"GoogleTestExtension.hpp\"\n#include \"pm4_pkt_struct_common.h\"\n#include \"PM4Packet.hpp\"\n\n\nIndirectBuffer::IndirectBuffer(PACKETTYPE type,  unsigned int sizeInDWords, unsigned int NodeId)\n    :m_NumOfPackets(0), m_MaxSize(sizeInDWords), m_ActualSize(0), m_PacketTypeAllowed(type) {\n    m_IndirectBuf = new HsaMemoryBuffer(sizeInDWords*sizeof(unsigned int), NodeId, true/*zero*/,\n                                        false/*local*/, true/*exec*/, false/*isScratch*/,\n                                        false/*isReadOnly*/, true/*isUncached*/);\n}\n\nIndirectBuffer::~IndirectBuffer(void) {\n    delete m_IndirectBuf;\n}\n\nuint32_t *IndirectBuffer::AddPacket(const BasePacket &packet) {\n    EXPECT_EQ(packet.PacketType(), m_PacketTypeAllowed) << \"Cannot add a packet since packet type doesn't match queue\";\n\n    unsigned int writePtr = m_ActualSize;\n\n    EXPECT_GE(m_MaxSize, packet.SizeInDWords() + writePtr) << \"Cannot add a packet, not enough room\";\n\n    memcpy(m_IndirectBuf->As<unsigned int*>() + writePtr , packet.GetPacket(),  packet.SizeInBytes());\n    m_ActualSize += packet.SizeInDWords();\n    m_NumOfPackets++;\n\n    return m_IndirectBuf->As<HSAuint32 *>() + writePtr;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/IndirectBuffer.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __INDIRECT_BUFFER__H__\n#define __INDIRECT_BUFFER__H__\n\n#include \"BasePacket.hpp\"\n#include \"KFDTestUtil.hpp\"\n\n/** @class IndirectBuffer\n *  When working with an indirect buffer, create IndirectBuffer, fill it with all the packets you want,\n *  create an indirect packet to point to it, and submit the packet to queue\n */\nclass IndirectBuffer {\n public:\n    // @param[size] Queue max size in DWords\n    // @param[type] Packet type allowed in queue\n    IndirectBuffer(PACKETTYPE type, unsigned int sizeInDWords, unsigned int NodeId);\n    ~IndirectBuffer(void);\n\n    // @brief Add packet to queue, all validations are done with gtest ASSERT and EXPECT\n    uint32_t *AddPacket(const BasePacket &packet);\n    // @returns Actual size of the indirect queue in DWords, equivalent to write pointer\n    unsigned int SizeInDWord() { return m_ActualSize; }\n    // @returns Indirect queue address\n    unsigned int *Addr() { return m_IndirectBuf->As<unsigned int*>(); }\n\n protected:\n    // Number of packets in the queue\n    unsigned int m_NumOfPackets;\n    // Max size of queue in DWords\n    unsigned int m_MaxSize;\n    // Current size of queue in DWords\n    unsigned int m_ActualSize;\n    HsaMemoryBuffer *m_IndirectBuf;\n    // What packets are supported in this queue\n    PACKETTYPE m_PacketTypeAllowed;\n};\n\n#endif  //  __INDIRECT_BUFFER__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDASMTest.cpp",
    "content": "/*\n * Copyright (C) 2022 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"GoogleTestExtension.hpp\"\n#include \"KFDASMTest.hpp\"\n#include \"ShaderStore.hpp\"\n#include \"Assemble.hpp\"\n\nvoid KFDASMTest::SetUp() {}\nvoid KFDASMTest::TearDown() {}\n\nstatic const std::vector<uint32_t> TargetList = {\n    0x080001,\n    0x080002,\n    0x080003,\n    0x080005,\n    0x080100,\n    0x090000,\n    0x090002,\n    0x090004,\n    0x090006,\n    0x090008,\n    0x090009,\n    0x09000a,\n    0x09000c,\n    0x090402,\n    0x0a0100,\n    0x0a0101,\n    0x0a0102,\n    0x0a0103,\n    0x0a0300,\n    0x0a0301,\n    0x0a0302,\n    0x0a0303,\n    0x0a0304,\n    0x0a0305,\n    0x0a0306,\n    0x0c0000,\n};\n\nTEST_F(KFDASMTest, AssembleShaders) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    for (auto &t : TargetList) {\n        Assembler asmblr(t);\n\n        LOG() << \"Running ASM test for target \" << asmblr.GetTargetAsic() << std::endl;\n\n        for (auto &s : ShaderList) {\n            EXPECT_SUCCESS(asmblr.RunAssemble(s));\n        }\n    }\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDASMTest.hpp",
    "content": "/*\n * Copyright (C) 2022 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_ASM_TEST__H__\n#define __KFD_ASM_TEST__H__\n\n#include <gtest/gtest.h>\n\nclass KFDASMTest : public testing::Test {\n public:\n    KFDASMTest() {}\n    ~KFDASMTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_ASM_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDBaseComponentTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <syslog.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n#include \"KFDTestUtil.hpp\"\n\nextern unsigned int g_TestGPUsNum;\n\nvoid KFDBaseComponentTest::SetUpTestCase() {\n}\n\nvoid KFDBaseComponentTest::TearDownTestCase() {\n}\n\nvoid KFDBaseComponentTest::SetUp() {\n    ROUTINE_START\n\n    ASSERT_SUCCESS(hsaKmtOpenKFD());\n    EXPECT_SUCCESS(hsaKmtGetVersion(&m_VersionInfo));\n    memset( &m_SystemProperties, 0, sizeof(m_SystemProperties) );\n    memset(m_RenderNodes, 0, sizeof(m_RenderNodes));\n\n    /** In order to be correctly testing the KFD interfaces and ensure\n     *  that the KFD acknowledges relevant node parameters\n     *  for the rest of the tests and used for more specific topology tests,\n     *  call to GetSystemProperties for a system snapshot of the topology here\n     */\n    ASSERT_SUCCESS(hsaKmtAcquireSystemProperties(&m_SystemProperties));\n    ASSERT_GT(m_SystemProperties.NumNodes, HSAuint32(0)) << \"HSA has no nodes.\";\n\n    m_NodeInfo.Init(m_SystemProperties.NumNodes);\n\n    // setting memory flags with default values , can be modified according to needs\n    m_MemoryFlags.ui32.NonPaged = 0;                         // Paged\n    m_MemoryFlags.ui32.CachePolicy = HSA_CACHING_NONCACHED;  // Non cached\n    m_MemoryFlags.ui32.ReadOnly = 0;                         // Read/Write\n    m_MemoryFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;         // 4KB page\n    m_MemoryFlags.ui32.HostAccess = 1;                       // Host accessible\n    m_MemoryFlags.ui32.NoSubstitute = 0;                     // Fall back to node 0 if needed\n    m_MemoryFlags.ui32.GDSMemory = 0;\n    m_MemoryFlags.ui32.Scratch = 0;\n\n    /* nodeProperties is default gpu property, keep it to support old test method */\n    const HsaNodeProperties *nodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n    ASSERT_NOTNULL(nodeProperties) << \"failed to get HSA default GPU Node properties\";\n\n    /* m_FamilyId is default gpu family id, keep it to support old test method */\n    m_FamilyId = FamilyIdFromNode(nodeProperties);\n\n    /* these values are for default gpu, keep them to support old test method */\n    GetHwQueueInfo(nodeProperties, &m_numCpQueues, &m_numSdmaEngines,\n                    &m_numSdmaXgmiEngines, &m_numSdmaQueuesPerEngine);\n\n    g_baseTest = this;\n\n    /* m_pAsm is default gpu assembler, keep it to support old test method */\n    m_pAsm = new Assembler(GetGfxVersion(nodeProperties));\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    int gpuNode;\n    for (int i = 0; i < gpuNodes.size(); i++) {\n        gpuNode = gpuNodes.at(i);\n        const HsaNodeProperties *nodeProperties = m_NodeInfo.GetNodeProperties(gpuNode);\n\n        m_pAsmGPU[i] = new Assembler(GetGfxVersion(nodeProperties));\n        GetHwQueueInfo(nodeProperties, &m_numCpQueues_GPU[i], &m_numSdmaEngines_GPU[i],\n                    &m_numSdmaXgmiEngines_GPU[i], &m_numSdmaQueuesPerEngine_GPU[i]);\n    }\n\n    /* adjust g_TestGPUsNum not above MAX_GPU and gpu number at system */\n    g_TestGPUsNum = std::min(g_TestGPUsNum, (unsigned int)gpuNodes.size());\n    g_TestGPUsNum = (g_TestGPUsNum <= MAX_GPU) ? g_TestGPUsNum : MAX_GPU;\n\n    const testing::TestInfo* curr_test_info =\n                ::testing::UnitTest::GetInstance()->current_test_info();\n\n    openlog(\"KFDTEST\", LOG_CONS , LOG_USER);\n    if (g_TestGPUsNum == 1)\n        syslog(LOG_INFO, \"[Test on Node#%03d] \"\n                    \"STARTED ========== %s.%s ==========\",\n                    m_NodeInfo.HsaDefaultGPUNode(),\n                    curr_test_info->test_case_name(), curr_test_info->name());\n    else\n        syslog(LOG_INFO, \"[Test on %03d Node(s)] \"\n                    \"STARTED ========== %s.%s ==========\",\n                    g_TestGPUsNum,\n                    curr_test_info->test_case_name(), curr_test_info->name());\n\n    ROUTINE_END\n}\n\nvoid KFDBaseComponentTest::TearDown() {\n    ROUTINE_START\n\n    for (int i = 0; i < MAX_RENDER_NODES; i++) {\n        if (m_RenderNodes[i].fd <= 0)\n            continue;\n\n        amdgpu_device_deinitialize(m_RenderNodes[i].device_handle);\n        drmClose(m_RenderNodes[i].fd);\n    }\n\n    EXPECT_SUCCESS(hsaKmtReleaseSystemProperties());\n    EXPECT_SUCCESS(hsaKmtCloseKFD());\n    g_baseTest = NULL;\n\n    if (m_pAsm)\n        delete m_pAsm;\n    m_pAsm = nullptr;\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    for (int i = 0; i < gpuNodes.size(); i++) {\n        if ( m_pAsmGPU[i]) {\n            delete  m_pAsmGPU[i];\n            m_pAsmGPU[i] = NULL;\n        }\n    }\n\n    const testing::TestInfo* curr_test_info =\n                ::testing::UnitTest::GetInstance()->current_test_info();\n\n    if (curr_test_info->result()->Passed())\n        if (g_TestGPUsNum == 1)\n            syslog(LOG_INFO, \"[Test on Node#%03d] PASSED\"\n                             \"  ========== %s.%s ==========\",\n                m_NodeInfo.HsaDefaultGPUNode(),\n                curr_test_info->test_case_name(), curr_test_info->name());\n        else\n            syslog(LOG_INFO, \"[Tested on %03d Node(s)] PASSED\"\n                             \"  ========== %s.%s ==========\",\n                g_TestGPUsNum,\n                curr_test_info->test_case_name(), curr_test_info->name());\n\n    else\n        if (g_TestGPUsNum == 1)\n             syslog(LOG_WARNING, \"[Test on Node#%03d] FAILED\"\n                                 \"  ========== %s.%s ==========\",\n                m_NodeInfo.HsaDefaultGPUNode(),\n                curr_test_info->test_case_name(), curr_test_info->name());\n        else\n             syslog(LOG_WARNING, \"[Test on %03d Node(s)] FAILED\"\n                                 \"  ========== %s.%s ==========\",\n                g_TestGPUsNum,\n                curr_test_info->test_case_name(), curr_test_info->name());\n\n    closelog();\n\n    m_NodeInfo.Delete();\n    ROUTINE_END\n}\n\nHSAuint64 KFDBaseComponentTest::GetSysMemSize() {\n    const HsaNodeProperties *nodeProps;\n    HsaMemoryProperties cpuMemoryProps;\n    HSAuint64 systemMemSize = 0;\n\n    /* Find System Memory size */\n    for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {\n        nodeProps = m_NodeInfo.GetNodeProperties(node);\n        if (nodeProps != NULL && nodeProps->NumCPUCores > 0 && nodeProps->NumMemoryBanks > 0) {\n            /* For NUMA nodes, memory is distributed among different nodes.\n             * Compute total system memory size. KFD driver also computes\n             * the system memory (si_meminfo) similarly\n             */\n            EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(node, 1, &cpuMemoryProps));\n            systemMemSize += cpuMemoryProps.SizeInBytes;\n        }\n    }\n\n    return systemMemSize;\n}\n\nHSAuint64 KFDBaseComponentTest::GetVramSize(int gpuNode) {\n    const HsaNodeProperties *nodeProps;\n\n    /* Find framebuffer size */\n    nodeProps = m_NodeInfo.GetNodeProperties(gpuNode);\n    EXPECT_NE((const HsaNodeProperties *)NULL, nodeProps);\n    HSAuint32 numBanks = nodeProps->NumMemoryBanks;\n    HsaMemoryProperties memoryProps[numBanks];\n    EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(gpuNode, numBanks, memoryProps));\n    unsigned bank;\n    for (bank = 0; bank < numBanks; bank++) {\n        if (memoryProps[bank].HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE\n                || memoryProps[bank].HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC)\n            return memoryProps[bank].SizeInBytes;\n    }\n\n    return 0;\n}\n\nunsigned int KFDBaseComponentTest::GetFamilyIdFromNodeId(unsigned int nodeId)\n{\n    return  FamilyIdFromNode(m_NodeInfo.GetNodeProperties(nodeId));\n}\n\nAssembler* KFDBaseComponentTest::GetAssemblerFromNodeId(unsigned int nodeId)\n{\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(nodeId);\n\n    if (gpuIndex < 0)\n        return NULL;\n\n    return m_pAsmGPU[gpuIndex];\n}\n\nbool KFDBaseComponentTest::SVMAPISupported_GPU(unsigned int gpuNode) {\n\n    bool supported = m_NodeInfo.GetNodeProperties(gpuNode)\n                         ->Capability.ui32.SVMAPISupported;\n\n    if (!supported)\n        LOG() << \"SVM API not supported on gpuNode\" << gpuNode << std::endl;\n\n    return supported;\n}\n\n\n/*\n * Some asics need CWSR workround for DEGFX11_12113\n */\nbool KFDBaseComponentTest::NeedCwsrWA(unsigned int nodeId)\n{\n    bool needCwsrWA = false;\n    const HsaNodeProperties *props = m_NodeInfo.GetNodeProperties(nodeId);\n\n    needCwsrWA = props->EngineId.ui32.Major == 11 &&\n                  props->EngineId.ui32.Minor == 0 &&\n                  (props->EngineId.ui32.Stepping == 0 ||\n                   props->EngineId.ui32.Stepping == 1 ||\n                   props->EngineId.ui32.Stepping == 2 ||\n                   props->EngineId.ui32.Stepping == 5 ||\n                   (props->EngineId.ui32.Stepping == 3 && props->NumArrays > 1));\n\n    return needCwsrWA;\n}\n\nbool KFDBaseComponentTest::NeedNonPagedWptr(unsigned int nodeId)\n{\n    return GetFamilyIdFromNodeId(nodeId) >= FAMILY_GFX11;\n}\n\nint KFDBaseComponentTest::FindDRMRenderNode(int gpuNode) {\n    HsaNodeProperties *nodeProperties;\n    _HSAKMT_STATUS status;\n\n    nodeProperties = new HsaNodeProperties();\n\n    status = hsaKmtGetNodeProperties(gpuNode, nodeProperties);\n    EXPECT_SUCCESS(status) << \"Node index: \" << gpuNode << \"hsaKmtGetNodeProperties returned status \" << status;\n\n    if (status != HSAKMT_STATUS_SUCCESS) {\n        delete nodeProperties;\n        return -EINVAL;\n    }\n\n    int minor = nodeProperties->DrmRenderMinor;\n    if (minor < 128) {\n        LOG() << \"Failed to get minor number \" << minor << std::endl;\n        return -EINVAL;\n    }\n\n    int index = minor - 128;\n\n    if (m_RenderNodes[index].fd == 0) {\n        m_RenderNodes[index].fd = drmOpenRender(minor);\n\n        if (m_RenderNodes[index].fd < 0) {\n            LOG() << \"Failed to open render node\" << std::endl;\n            return -EINVAL;\n        }\n\n        if (amdgpu_device_initialize(m_RenderNodes[index].fd,\n                &m_RenderNodes[index].major_version,\n                &m_RenderNodes[index].minor_version,\n                &m_RenderNodes[index].device_handle) != 0) {\n            drmClose(m_RenderNodes[index].fd);\n            m_RenderNodes[index].fd = 0;\n            LOG() << \"Failed to initialize amdgpu device\" << std::endl;\n            return -EINVAL;\n        }\n    }\n\n    return index;\n}\n\nHsaVersionInfo* KFDBaseComponentTest::Get_Version() {\n    return &m_VersionInfo;\n}\n\nHsaNodeInfo* KFDBaseComponentTest::Get_NodeInfo() {\n    return &m_NodeInfo;\n}\n\nHsaMemFlags& KFDBaseComponentTest::GetHsaMemFlags() {\n    return m_MemoryFlags;\n}\n\nstatic void* KFDTest_GPU(void* ptr) {\n\n    KFDTEST_GPUPARAMETERS* pKFDTest_GPUParameters = (KFDTEST_GPUPARAMETERS*)ptr;\n\n    Test_Function test_function        = pKFDTest_GPUParameters->pTest_Function;\n    KFDTEST_PARAMETERS* pTestParamters = pKFDTest_GPUParameters->pKFDTest_Parameters;\n\n    try {\n\n        test_function(pTestParamters);\n\n    } catch (...) {\n        LOG() << \"test failed at gpu\" << pTestParamters->gpuNode << std::endl;\n    }\n\n    pthread_exit(NULL);\n}\n\nHSAKMT_STATUS KFDBaseComponentTest::KFDTestMultiGPU(Test_Function test_function,\n                                                     unsigned int gpu_num) {\n\n    HSAKMT_STATUS r = HSAKMT_STATUS_SUCCESS;\n    int gpu_node;\n    int err = 0;\n    int i, j;\n\n    KFDTEST_GPUPARAMETERS kfdtest_GpuParameters[gpu_num];\n    KFDTEST_PARAMETERS kfdTest_Parameters[gpu_num];\n    pthread_t pThreadGPU[gpu_num];\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n\n    for (i = 0; i < gpu_num; i++) {\n\n        gpu_node = gpuNodes.at(i);\n\n        kfdTest_Parameters[i].pTestObject = this;\n        kfdTest_Parameters[i].gpuNode = gpu_node;\n\n        kfdtest_GpuParameters[i].pKFDTest_Parameters = &kfdTest_Parameters[i];\n        kfdtest_GpuParameters[i].pTest_Function = test_function;\n\n        err = pthread_create(&pThreadGPU[i], NULL, KFDTest_GPU,\n                             (void *)&kfdtest_GpuParameters[i]);\n        if (err) {\n            std::cout << \"Thread creation for gpu node failed : \" << gpu_node\n                      << strerror(err) << std::endl;\n            r = HSAKMT_STATUS_ERROR;\n            goto err_out;\n        }\n    }\n\nerr_out:\n   /* wait threads created successully to finish */\n   for (j = 0; j < i; j++) {\n       err = pthread_join(pThreadGPU[j], NULL);\n       if (err) {\n           std::cout << \"pthread_join at gpu node failed : \" << gpuNodes.at(j)\n                     << strerror(err) << std::endl;\n           r = HSAKMT_STATUS_ERROR;\n       }\n   }\n\n   return r;\n}\n\nHSAKMT_STATUS KFDBaseComponentTest::KFDTest_Launch(Test_Function test_function) {\n\n    /* test on default GPU only */\n    if (g_TestGPUsNum == 1) {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n        if (defaultGPUNode < 0) {\n            LOG() << \"defaultGPUNode is invalid.\" << defaultGPUNode <<std::endl;\n            return HSAKMT_STATUS_INVALID_PARAMETER;\n        }\n\n        KFDTEST_PARAMETERS TestParamters;\n        TestParamters.pTestObject = this;\n        TestParamters.gpuNode = defaultGPUNode;\n        try {\n            test_function(&TestParamters);\n        } catch (...) {\n            LOG() << \"test failed at gpu\" << defaultGPUNode << std::endl;\n        }\n\n        return HSAKMT_STATUS_SUCCESS;\n    }\n\n    /* run test_function on all available GPUs */\n    HSAKMT_STATUS err = HSAKMT_STATUS_SUCCESS;\n    err = KFDTestMultiGPU(test_function, g_TestGPUsNum);\n\n    return err;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDBaseComponentTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n#ifndef __KFD_BASE_COMPONENT_TEST__H__\n#define __KFD_BASE_COMPONENT_TEST__H__\n\n#include <gtest/gtest.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <xf86drm.h>\n#include <amdgpu.h>\n#include <amdgpu_drm.h>\n#include <sys/param.h>\n#include \"hsakmt/hsakmt.h\"\n#include \"OSWrapper.hpp\"\n#include \"KFDTestUtil.hpp\"\n#include \"Assemble.hpp\"\n#include \"ShaderStore.hpp\"\n\n#define MAX_GPU 64\n\ntypedef struct _KFDTEST_PARAMETERS\n{\n    void*   pTestObject;\n    int     gpuNode;\n} KFDTEST_PARAMETERS;\n\ntypedef void (* Test_Function)(KFDTEST_PARAMETERS*);\n\ntypedef struct _KFDTESTGPU_PARAMETERS\n{\n    KFDTEST_PARAMETERS*   pKFDTest_Parameters;\n    Test_Function         pTest_Function;\n} KFDTEST_GPUPARAMETERS;\n\n//  @class KFDBaseComponentTest\nclass KFDBaseComponentTest : public testing::Test {\n public:\n    KFDBaseComponentTest(void) { m_MemoryFlags.Value = 0; }\n    ~KFDBaseComponentTest(void) {}\n\n    HSAuint64 GetSysMemSize();\n    HSAuint64 GetVramSize(int gpuNode);\n#define MAX_RENDER_NODES 64\n    struct {\n        int fd;\n        uint32_t major_version;\n        uint32_t minor_version;\n        amdgpu_device_handle device_handle;\n        uint32_t bdf;\n    } m_RenderNodes[MAX_RENDER_NODES];\n\n// @brief Finds DRM Render node corresponding to gpuNode\n// @return DRM Render Node if successful or -1 on failure\n    int FindDRMRenderNode(int gpuNode);\n    unsigned int GetFamilyIdFromNodeId(unsigned int nodeId);\n    Assembler* GetAssemblerFromNodeId(unsigned int nodeId);\n    bool NeedCwsrWA(unsigned int nodeId);\n    bool NeedNonPagedWptr(unsigned int nodeId);\n    unsigned int GetFamilyIdFromDefaultNode(){ return m_FamilyId; }\n\n    // @brief Executed before the first test that uses KFDBaseComponentTest.\n    static  void SetUpTestCase();\n    // @brief Executed after the last test from KFDBaseComponentTest.\n    static  void TearDownTestCase();\n\n    HsaVersionInfo*  Get_Version();\n    HsaNodeInfo* Get_NodeInfo();\n    HsaMemFlags& GetHsaMemFlags();\n    bool SVMAPISupported_GPU(unsigned int nodeId);\n\n    inline unsigned int Get_NumCpQueues(int gpuIndex){\n        return m_numCpQueues_GPU[gpuIndex];\n    }\n\n    inline unsigned int Get_NumSdmaEngines(int gpuIndex){\n        return m_numSdmaEngines_GPU[gpuIndex];\n    }\n\n    inline unsigned int Get_NumSdmaSdmaQueuesPerEngine(int gpuIndex){\n        return m_numSdmaQueuesPerEngine_GPU[gpuIndex];\n    }\n\n    inline unsigned int Get_NumSdmaSdmaXgmiEngines(int gpuIndex){\n        return m_numSdmaXgmiEngines_GPU[gpuIndex];\n    }\n\n    HSAKMT_STATUS KFDTestMultiGPU(Test_Function test_function,\n\t\t\t\t    unsigned int gpu_num);\n\n    HSAKMT_STATUS KFDTest_Launch(Test_Function test_function);\n\n protected:\n    HsaVersionInfo  m_VersionInfo;\n    HsaSystemProperties m_SystemProperties;\n    unsigned int m_FamilyId;\n    unsigned int m_numCpQueues;\n    unsigned int m_numSdmaEngines;\n    unsigned int m_numSdmaXgmiEngines;\n    unsigned int m_numSdmaQueuesPerEngine;\n    HsaMemFlags m_MemoryFlags;\n    HsaNodeInfo m_NodeInfo;\n    HSAint32 m_xnack;\n    Assembler* m_pAsm;\n\n    Assembler* m_pAsmGPU[MAX_GPU];\n\n    unsigned int m_numCpQueues_GPU[MAX_GPU];\n    unsigned int m_numSdmaEngines_GPU[MAX_GPU];\n    unsigned int m_numSdmaXgmiEngines_GPU[MAX_GPU];\n    unsigned int m_numSdmaQueuesPerEngine_GPU[MAX_GPU];\n\n    // @brief Executed before every test that uses KFDBaseComponentTest class and sets all common settings for the tests.\n    virtual void SetUp();\n    // @brief Executed after every test that uses KFDBaseComponentTest class.\n    virtual void TearDown();\n\n    /* TO DO: check all gpu support svm api */\n    bool SVMAPISupported() {\n        bool supported = m_NodeInfo.HsaDefaultGPUNodeProperties()\n                        ->Capability.ui32.SVMAPISupported;\n        if (!supported)\n            LOG() << \"SVM API not supported\" << std::endl;\n        return supported;\n    }\n\n    // Set xnack_override to -1 if parameter is not passed in, to avoid unnecessary code churn\n    void SVMSetXNACKMode(int xnack_override = -1) {\n        if (!SVMAPISupported())\n            return;\n\n        m_xnack = -1;\n        HSAKMT_STATUS ret = hsaKmtGetXNACKMode(&m_xnack);\n        if (ret != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"Failed \" << ret << \" to get XNACK mode\" << std::endl;\n            return;\n        }\n\n        HSAint32 xnack_on = -1;\n        char *hsa_xnack = getenv(\"HSA_XNACK\");\n\n        // HSA_XNACK takes priority over kfdtest parameters\n        if (hsa_xnack)\n                xnack_on = strncmp(hsa_xnack, \"0\", 1);\n        else if (xnack_override > -1)\n                xnack_on = xnack_override;\n        else\n                return;\n\n\t// No need to set XNACK if it's already the current value\n\tif (xnack_on == m_xnack)\n\t\treturn;\n\n        ret = hsaKmtSetXNACKMode(xnack_on);\n        if (ret != HSAKMT_STATUS_SUCCESS)\n            LOG() << \"Failed \" << ret << \" to set XNACK mode \" << xnack_on << std::endl;\n        else\n            LOG() << \"Setting XNACK mode to \" << xnack_on << std::endl;\n    }\n\n    void SVMRestoreXNACKMode() {\n        if (!SVMAPISupported())\n             return;\n\n        if (m_xnack == -1)\n            return;\n\n        hsaKmtSetXNACKMode(m_xnack);\n    }\n};\n\nextern KFDBaseComponentTest* g_baseTest;\n#endif  //  __KFD_BASE_COMPONENT_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDCWSRTest.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <tuple>\n#include \"KFDCWSRTest.hpp\"\n#include \"Dispatch.hpp\"\n\nvoid KFDCWSRTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDCWSRTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic inline uint32_t checkCWSREnabled() {\n    uint32_t cwsr_enable = 0;\n\n    fscanf_dec(\"/sys/module/amdgpu/parameters/cwsr_enable\", &cwsr_enable);\n\n    return cwsr_enable;\n}\n\n/**\n * KFDCWSRTest.BasicTest\n *\n * This test dispatches the PersistentIterateIsa shader, which continuously increments a vgpr for\n * (num_witems / WAVE_SIZE) waves. While this shader is running, dequeue/requeue requests\n * are sent in a loop to trigger CWSRs.\n *\n * This is a paremeterized test. See the INSTANTIATE_TEST_CASE_P below for an explanation\n * on the parameters.\n *\n * This test defines a CWSR threshold. The shader will continuously loop until inputBuf is\n * filled with the known stop value, which occurs once cwsr_thresh CWSRs have been\n * successfully triggered.\n *\n * 4 parameterized tests are defined:\n *\n * KFDCWSRTest.BasicTest/0\n * KFDCWSRTest.BasicTest/1\n * KFDCWSRTest.BasicTest/2\n * KFDCWSRTest.BasicTest/3\n *\n * 0: 1 work-item, CWSR threshold of 10\n * 1: 256 work-items (multi-wave), CWSR threshold of 50\n * 2: 512 work-items (multi-wave), CWSR threshold of 100\n * 3: 1024 work-items (multi-wave), CWSR threshold of 1000\n */\n\nstatic void BasicTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDCWSRTest* pKFDCWSRTest = (KFDCWSRTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDCWSRTest->GetFamilyIdFromNodeId(gpuNode);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDCWSRTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    int num_witems = std::get<0>(pKFDCWSRTest->GetParam());\n    int cwsr_thresh = std::get<1>(pKFDCWSRTest->GetParam());\n    // Increase delay on emulator by this factor.\n    const int delayMult = (g_IsEmuMode ? 20 : 1);\n\n    if ((m_FamilyId >= FAMILY_VI) && (checkCWSREnabled())) {\n        HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true, false, true);\n        ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PersistentIterateIsa, isaBuffer.As<char*>()), gpuNode);\n\n        unsigned stopval = 0x1234'5678;\n        unsigned outval  = 0x8765'4321;\n\n        // 4B per work-item ==> 1 page per 1024 work-items (take ceiling)\n        unsigned bufSize = PAGE_SIZE * ((num_witems / 1024) + (num_witems % 1024 != 0));\n\n        HsaMemoryBuffer inputBuf(bufSize, gpuNode, true, false, false);\n        HsaMemoryBuffer outputBuf(bufSize, gpuNode, true, false, false);\n        unsigned int* input = inputBuf.As<unsigned int*>();\n        unsigned int* output = outputBuf.As<unsigned int*>();\n        inputBuf.Fill(0);\n        outputBuf.Fill(outval);\n\n        PM4Queue queue;\n        ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n        Dispatch dispatch(isaBuffer);\n        dispatch.SetArgs(input, output);\n        dispatch.SetDim(num_witems, 1, 1);\n        dispatch.Submit(queue);\n\n        Delay(5 * delayMult);\n\n        LOG() << \"Starting iteration for \" << std::dec << num_witems\n              << \" work items(s) (targeting \" << std::dec << cwsr_thresh\n              << \" CWSRs)\" << std::endl;\n\n        for (int num_cwsrs = 0; num_cwsrs < cwsr_thresh; num_cwsrs++) {\n\n            // Send dequeue request\n            EXPECT_SUCCESS_GPU(queue.Update(0, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n            Delay(5 * delayMult);\n\n            // Send requeue request\n            EXPECT_SUCCESS_GPU(queue.Update(100, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n            Delay(50 * delayMult);\n\n            // Check for reg mangling\n            for (int i = 0; i < num_witems; i++) {\n                EXPECT_EQ_GPU(outval, output[i], gpuNode);\n            }\n        }\n\n        LOG() << \"Successful completion for \" << std::dec << num_witems\n              << \" work item(s) (CWSRs triggered: \" << std::dec << cwsr_thresh\n              << \")\" << std::endl;\n        LOG() << \"Signalling shader stop...\" << std::endl;\n\n        inputBuf.Fill(stopval);\n\n        // Wait for shader to finish or timeout if shader has vm page fault\n        EXPECT_EQ_GPU(0, dispatch.SyncWithStatus(180000), gpuNode);\n        EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    } else {\n        LOG() << \"Skipping test: No CWSR present for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n    }\n\n}\n\nTEST_P(KFDCWSRTest, BasicTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicTest));\n\n    TEST_END\n}\n\n/**\n * Instantiates various KFDCWSRTest.BasicTest parameterizations\n * Tuple Format: (num_witems, cwsr_thresh)\n *\n * num_witems:    Defines the number of work-items.\n * cwsr_thresh:   Defines the number of CWSRs to trigger.\n */\nINSTANTIATE_TEST_CASE_P(\n    , KFDCWSRTest,\n    ::testing::Values(\n            std::make_tuple(1, 10),     /* Single Wave Test,  10 CWSR Triggers */\n            std::make_tuple(256, 50),   /* Multi Wave Test,   50 CWSR Triggers */\n            std::make_tuple(512, 100),  /* Multi Wave Test,  100 CWSR Triggers */\n            std::make_tuple(1024, 1000) /* Multi Wave Test, 1000 CWSR Triggers */\n    )\n);\n\n/**\n * KFDCWSRTest.InterruptRestore\n *\n * This test verifies that CP can preempt an HQD while it is restoring a dispatch.\n * Create queue 1.\n * Start a dispatch on queue 1 which runs indefinitely and fills all CU wave slots.\n * Create queue 2, triggering context save on queue 1.\n * Start a dispatch on queue 2 which runs indefinitely and fills all CU wave slots.\n * Create queue 3, triggering context save and restore on queues 1 and 2.\n * Preempt runlist. One or both queues must interrupt context restore to preempt.\n */\n\nstatic void InterruptRestore(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDCWSRTest* pKFDCWSRTest = (KFDCWSRTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDCWSRTest->GetFamilyIdFromNodeId(gpuNode);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDCWSRTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n   if ((m_FamilyId >= FAMILY_VI) && (checkCWSREnabled())) {\n        HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n        ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(InfiniteLoopIsa, isaBuffer.As<char*>()), gpuNode);\n\n        PM4Queue queue1, queue2, queue3;\n\n        ASSERT_SUCCESS_GPU(queue1.Create(gpuNode), gpuNode);\n\n        Dispatch *dispatch1, *dispatch2;\n\n        dispatch1 = new Dispatch(isaBuffer);\n        dispatch2 = new Dispatch(isaBuffer);\n\n        dispatch1->SetDim(0x10000, 1, 1);\n        dispatch2->SetDim(0x10000, 1, 1);\n\n        dispatch1->Submit(queue1);\n\n        ASSERT_SUCCESS_GPU(queue2.Create(gpuNode), gpuNode);\n\n        dispatch2->Submit(queue2);\n\n        // Give waves time to launch.\n        Delay(1);\n\n        ASSERT_SUCCESS_GPU(queue3.Create(gpuNode), gpuNode);\n\n        EXPECT_SUCCESS_GPU(queue1.Destroy(), gpuNode);\n        EXPECT_SUCCESS_GPU(queue2.Destroy(), gpuNode);\n        EXPECT_SUCCESS_GPU(queue3.Destroy(), gpuNode);\n\n        delete dispatch1;\n        delete dispatch2;\n\n    } else {\n        LOG() << \"Skipping test: No CWSR present for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n    }\n}\n\nTEST_F(KFDCWSRTest, InterruptRestore) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(InterruptRestore));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDCWSRTest.hpp",
    "content": "/*\n * Copyright (C) 2015-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_CWSR_TEST__H__\n#define __KFD_CWSR_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"PM4Queue.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDCWSRTest : public KFDBaseComponentTest,\n                    public ::testing::WithParamInterface<std::tuple<int, int>> {\n public:\n    KFDCWSRTest() {}\n    ~KFDCWSRTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_CWSR_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDDBGTest.cpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"BaseDebug.hpp\"\n#include \"KFDDBGTest.hpp\"\n#include <sys/ptrace.h>\n#include <poll.h>\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"KFDQMTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"Dispatch.hpp\"\n#include <string>\n\nvoid KFDDBGTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDDBGTest::TearDown() {\n    ROUTINE_START\n\n    /* Reset the user trap handler */\n    hsaKmtSetTrapHandler(m_NodeInfo.HsaDefaultGPUNode(), 0, 0, 0, 0);\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\n/*\n * To test debug attaching to a spawned process (i.e. attach prior to the tracee\n * opening a KFD device), have the child request the parent to PTRACE attach and\n * wait for the parent to debug attach then allow the child to runtime enable.\n *\n * The following will be exercised:\n * - The KFD shall create a KFD process on behalf of the tracee during debug\n *   attach since the tracee has not opened a KFD device.\n * - Runtime enable on the tracee shall raise an event to the debugging parent\n *   and block until parent has signalled that it has recieved the runtime\n *   enable event.\n * - Tracee should follow a similar hand shake for runtime disable and debug\n *   detach should follow.\n *\n * */\nTEST_F(KFDDBGTest, AttachToSpawnedProcess) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        pid_t childPid = fork();\n\n        if (childPid == 0) { /* Debugged process */\n            uint32_t rDebug;\n            int r;\n\n            /* Let parent become the debugger and wait for attach. */\n            ptrace(PTRACE_TRACEME);\n            raise(SIGSTOP);\n\n            r = hsaKmtOpenKFD();\n\n            if (r != HSAKMT_STATUS_SUCCESS) {\n                WARN() << \"KFD open failed in debugged process\" << std::endl;\n                exit(1);\n            }\n\n            LOG() << std::dec << \"--- Debugged PID \" << getpid() << \" runtime enable\" << std::endl;\n\n            r = hsaKmtRuntimeEnable(&rDebug, true);\n\n            if (r != HSAKMT_STATUS_SUCCESS) {\n                WARN() << \"Runtime enabled failed\" << std::endl;\n                exit(1);\n            }\n\n            LOG() << std::dec << \"--- Debugged PID \" << getpid() << \" runtime disable and exit\" << std::endl;\n\n            hsaKmtRuntimeDisable();\n\n            exit(0);\n        } else {\n            BaseDebug *debug = new BaseDebug();\n            struct kfd_runtime_info r_info;\n            memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n            uint64_t runtimeMask = KFD_EC_MASK(EC_PROCESS_RUNTIME);\n            int childStatus;\n\n            waitpid(childPid, &childStatus, 0);\n            while (!WIFSTOPPED(childStatus));\n\n            /* Attach and let new debugged process continue with runtime enable */\n            LOG() << std::dec << \"Attaching to PID \" << childPid  << std::endl;\n            ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), childPid, runtimeMask));\n            ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_DISABLED);\n            ASSERT_EQ(r_info.ttmp_setup, false);\n\n            ptrace(PTRACE_CONT, childPid, NULL, NULL);\n\n            /* Wait and unblock runtime enable */\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));\n            ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));\n            ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));\n\n            /* Wait and unblock runtime disable */\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));\n            ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));\n            ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));\n\n            LOG() << std::dec << \"Detaching from PID \" << childPid << std::endl;\n            debug->Detach();\n\n            ptrace(PTRACE_DETACH, childPid, NULL, NULL);\n\n            LOG() << std::dec << \"Waiting on PID \" << childPid << \" to exit\" << std::endl;\n            waitpid(childPid, &childStatus, 0);\n            EXPECT_EQ(WIFEXITED(childStatus), true);\n            EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);\n        }\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\n/*\n * Unlike AttachToSpawnedProcess, the debug parent will only attach after\n * a non-blocked runtime enable by the tracee.  The parent should expect\n * a status update that the tracee is runtime enabled on debug attach.\n * Cleanup with appropriate runtime disable and debug detach handshake.\n */\nTEST_F(KFDDBGTest, AttachToRunningProcess) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n    pid_t childPid = fork();\n\n    if (childPid == 0) { /* Debugged process */\n            uint32_t rDebug;\n            int r;\n\n            r = hsaKmtOpenKFD();\n\n            if (r != HSAKMT_STATUS_SUCCESS) {\n                WARN() << \"KFD open failed in debugged process\" << std::endl;\n                exit(1);\n             }\n\n             LOG() << std::dec << \"--- Debugged PID \" << getpid() << \" runtime enable\" << std::endl;\n\n             r = hsaKmtRuntimeEnable(&rDebug, true);\n             if (r != HSAKMT_STATUS_SUCCESS) {\n                 WARN() << \"Runtime enabled failed\" << std::endl;\n                 exit(1);\n             }\n\n             /* Let parent become the debugger and wait for attach. */\n             ptrace(PTRACE_TRACEME);\n             raise(SIGSTOP);\n\n             LOG() << std::dec << \"--- Debugged PID \" << getpid() << \" runtime disable and exit\" << std::endl;\n\n             hsaKmtRuntimeDisable();\n\n             exit(0);\n        } else {\n            BaseDebug *debug = new BaseDebug();\n            struct kfd_runtime_info r_info;\n            memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n            uint64_t runtimeMask = KFD_EC_MASK(EC_PROCESS_RUNTIME);\n            int childStatus;\n\n            waitpid(childPid, &childStatus, 0);\n            while (!WIFSTOPPED(childStatus));\n\n            /* Attach to running process and let it continue */\n            LOG() << std::dec << \"Attaching to PID \" << childPid  << std::endl;\n            ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), childPid, runtimeMask));\n            ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);\n            ASSERT_EQ(r_info.ttmp_setup, true);\n\n            ptrace(PTRACE_CONT, childPid, NULL, NULL);\n\n            /* Wait and unblock runtime disable */\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));\n            ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));\n            ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));\n\n            LOG() << std::dec << \"Detaching from PID \" << childPid << std::endl;\n            debug->Detach();\n\n            ptrace(PTRACE_DETACH, childPid, NULL, NULL);\n\n            LOG() << std::dec << \"Waiting on PID \" << childPid << \" to exit\" << std::endl;\n            waitpid(childPid, &childStatus, 0);\n            EXPECT_EQ(WIFEXITED(childStatus), true);\n            EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);\n        }\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\nTEST_F(KFDDBGTest, HitTrapEvent) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n        // create shader and trap bufs then enable 2nd level trap\n        HsaMemoryBuffer isaBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer trapStatusBuf(PAGE_SIZE, defaultGPUNode, true, false, false);\n\n        HsaMemoryBuffer trap(PAGE_SIZE*2, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer tmaBuf(PAGE_SIZE, defaultGPUNode, false, false, false);\n\n        ASSERT_SUCCESS(hsaKmtSetTrapHandler(defaultGPUNode,\n                                            trap.As<void *>(),\n                                            0x1000,\n                                            tmaBuf.As<void*>(),\n                                            0x1000));\n\n        // compile and dispatch shader\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(JumpToTrapIsa, isaBuf.As<char*>()));\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(TrapHandlerIsa, trap.As<char*>()));\n\n        uint32_t rDebug;\n        ASSERT_SUCCESS(hsaKmtRuntimeEnable(&rDebug, true));\n\n        BaseDebug *debug = new BaseDebug();\n        struct kfd_runtime_info r_info;\n        memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n        ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), getpid(), 0));\n        ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);\n\n        PM4Queue queue;\n        HsaQueueResource *qResources;\n        ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n        unsigned int* trapStatus = trapStatusBuf.As<unsigned int*>();\n        trapStatus[0] = 0;\n        Dispatch *dispatch;\n        dispatch = new Dispatch(isaBuf);\n        dispatch->SetArgs(&trapStatus[0], NULL);\n        dispatch->SetDim(1, 1, 1);\n\n        /* Subscribe to trap events and submit the queue */\n        uint64_t trapMask = KFD_EC_MASK(EC_QUEUE_WAVE_TRAP);\n        debug->SetExceptionsEnabled(trapMask);\n        dispatch->Submit(queue);\n\n        /* Wait for trap event */\n        uint32_t QueueId = -1;\n        ASSERT_SUCCESS(debug->QueryDebugEvent(&trapMask, NULL, &QueueId, 5000));\n        ASSERT_NE(QueueId, -1);\n        ASSERT_EQ(trapMask, KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | KFD_EC_MASK(EC_QUEUE_NEW));\n\n        dispatch->Sync();\n        EXPECT_SUCCESS(queue.Destroy());\n\n        ASSERT_NE(trapStatus[0], 0);\n\n        debug->Detach();\n        hsaKmtRuntimeDisable();\n\n        delete dispatch;\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\nTEST_F(KFDDBGTest, HitTrapOnWaveStartEndEvent) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n        // create shader and trap bufs then enable 2nd level trap\n        HsaMemoryBuffer isaBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer trap(PAGE_SIZE*2, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer tmaBuf(PAGE_SIZE, defaultGPUNode, false, false, false);\n\n        ASSERT_SUCCESS(hsaKmtSetTrapHandler(defaultGPUNode,\n                                            trap.As<void *>(),\n                                            0x1000,\n                                            tmaBuf.As<void*>(),\n                                            0x1000));\n\n        // compile and dispatch shader\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(NoopIsa, isaBuf.As<char*>()));\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(TrapHandlerIsa, trap.As<char*>()));\n\n        uint32_t rDebug;\n        ASSERT_SUCCESS(hsaKmtRuntimeEnable(&rDebug, true));\n\n        BaseDebug *debug = new BaseDebug();\n        struct kfd_runtime_info r_info;\n        memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n        ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), getpid(), 0));\n        ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);\n\n        PM4Queue queue;\n        HsaQueueResource *qResources;\n        ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n        for (int i = 0; i < 2; i++) {\n            uint32_t enableMask = !!!(i % 2) ? KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START :\n                                               KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END;\n            uint32_t supportedMask = enableMask, reqMask = enableMask;\n            debug->SetWaveLaunchOverride(KFD_DBG_TRAP_OVERRIDE_OR, &reqMask, &supportedMask);\n\n            if (!!!(supportedMask & enableMask)) {\n                EXPECT_SUCCESS(queue.Destroy());\n                debug->Detach();\n                hsaKmtRuntimeDisable();\n                LOG() << \"Skipping test: Trap on start/end override not supported.\" << std::endl;\n                goto exit;\n            }\n\n\t    // previous set mask\n            ASSERT_EQ(reqMask, !!!(i % 2) ? 0 : KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START);\n\n            Dispatch *dispatch;\n            dispatch = new Dispatch(isaBuf);\n            dispatch->SetArgs(NULL, NULL);\n            dispatch->SetDim(1, 1, 1);\n\n            /* Subscribe to trap events and submit the queue */\n            uint64_t trapMask = KFD_EC_MASK(EC_QUEUE_WAVE_TRAP);\n            debug->SetExceptionsEnabled(trapMask);\n            dispatch->Submit(queue);\n\n            /* Wait for trap event */\n            uint32_t QueueId = -1;\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&trapMask, NULL, &QueueId, 5000));\n            ASSERT_NE(QueueId, -1);\n            ASSERT_EQ(trapMask, KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | KFD_EC_MASK(EC_QUEUE_NEW));\n\n            dispatch->Sync();\n            delete dispatch;\n        }\n\n        EXPECT_SUCCESS(queue.Destroy());\n\n        debug->Detach();\n        hsaKmtRuntimeDisable();\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\nTEST_F(KFDDBGTest, SuspendQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n        // create shader and trap bufs then enable 2nd level trap\n        HsaMemoryBuffer isaBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n\n        // compile and dispatch shader\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(JumpToTrapIsa, isaBuf.As<char*>()));\n\n        uint32_t rDebug;\n        ASSERT_SUCCESS(hsaKmtRuntimeEnable(&rDebug, true));\n\n        BaseDebug *debug = new BaseDebug();\n        struct kfd_runtime_info r_info;\n        memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n        ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), getpid(), 0));\n        ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);\n\n        PM4Queue queue;\n        HsaQueueResource *qResources;\n        ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n        qResources = queue.GetResource();\n        HSA_QUEUEID Queues[] = { qResources->QueueId };\n\n        Dispatch *dispatch;\n        dispatch = new Dispatch(isaBuf);\n        dispatch->SetDim(1, 1, 1);\n        dispatch->Submit(queue);\n\n        uint32_t NumQueues = 1;\n        uint32_t QueueIds[NumQueues];\n        struct kfd_queue_snapshot_entry Snapshots[NumQueues];\n        memset(Snapshots, 0, NumQueues * sizeof(struct kfd_queue_snapshot_entry));\n        ASSERT_SUCCESS(debug->SuspendQueues(&NumQueues, Queues, &QueueIds[0], 0));\n\n        // Suspend should fail as new queues cannot be suspended\n        ASSERT_EQ(NumQueues, 0);\n        ASSERT_NE(QueueIds[0] & KFD_DBG_QUEUE_INVALID_MASK, 0);\n\n        // Snapshot queue, clear new queue status and suspend successfully.\n        ASSERT_SUCCESS(debug->QueueSnapshot(0, (uint64_t)(&(Snapshots[0])), &NumQueues));\n        ASSERT_EQ(NumQueues, 1);\n        ASSERT_EQ(Snapshots[0].ctx_save_restore_area_size, 0);\n\n        ASSERT_SUCCESS(debug->QueueSnapshot(KFD_EC_MASK(EC_QUEUE_NEW), (uint64_t)(&(Snapshots[0])),\n                                            &NumQueues));\n        ASSERT_EQ(NumQueues, 1);\n        ASSERT_GT(Snapshots[0].ctx_save_restore_area_size, 0);\n\n        ASSERT_SUCCESS(debug->SuspendQueues(&NumQueues, Queues, &QueueIds[0], 0));\n        ASSERT_EQ(NumQueues, 1);\n        ASSERT_EQ(QueueIds[0] & KFD_DBG_QUEUE_INVALID_MASK, 0);\n\n        // Resume and destroy queue then clean up.\n        ASSERT_SUCCESS(debug->ResumeQueues(&NumQueues, Queues, &QueueIds[0]));\n        ASSERT_EQ(NumQueues, 1);\n        ASSERT_EQ(QueueIds[0] & KFD_DBG_QUEUE_INVALID_MASK, 0);\n\n        EXPECT_SUCCESS(queue.Destroy());\n\n        debug->Detach();\n        hsaKmtRuntimeDisable();\n\n        delete dispatch;\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\nTEST_F(KFDDBGTest, HitMemoryViolation) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_AI) {\n\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        pid_t childPid = fork();\n\n        if (childPid == 0) { // Debugged process\n            uint32_t rDebug;\n            int r;\n\n            // Refresh setup for HSA device and mem buffer use in child\n            KFDBaseComponentTest::TearDown();\n            KFDBaseComponentTest::SetUp();\n\n            // Let parent become the debugger and wait for attach.\n            ptrace(PTRACE_TRACEME);\n            raise(SIGSTOP);\n\n            r = hsaKmtRuntimeEnable(&rDebug, true);\n\n            if (r != HSAKMT_STATUS_SUCCESS) {\n                WARN() << \"Runtime enabled failed\" << std::endl;\n                exit(1);\n            }\n\n            HsaMemoryBuffer isaBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n            ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(PersistentIterateIsa, isaBuf.As<char*>()));\n            PM4Queue queue;\n            HsaQueueResource *qResources;\n            ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n            // Create memory violation event on dispatch\n            HsaEvent *vmFaultEvent;\n            HsaEventDescriptor eventDesc;\n            eventDesc.EventType = HSA_EVENTTYPE_MEMORY;\n            eventDesc.NodeId = defaultGPUNode;\n            eventDesc.SyncVar.SyncVar.UserData = NULL;\n            eventDesc.SyncVar.SyncVarSize = 0;\n            r = hsaKmtCreateEvent(&eventDesc, true, false, &vmFaultEvent);\n\n            if (r != HSAKMT_STATUS_SUCCESS) {\n                WARN() << \"Creating VM fault event failed\" << std::endl;\n                exit(1);\n            }\n\n            Dispatch dispatch(isaBuf);\n            dispatch.SetDim(1, 1, 1);\n            dispatch.SetPriv(false); //Override GFX11 CWSR WA\n            dispatch.Submit(queue);\n\n            // Queue immediately dies so halt process for tracer device inspection.\n            raise(SIGSTOP);\n\n            exit(0);\n        } else {\n            BaseDebug *debug = new BaseDebug();\n            struct kfd_runtime_info r_info;\n            memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n            uint64_t runtimeMask = KFD_EC_MASK(EC_PROCESS_RUNTIME);\n            uint64_t memViolMask = KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION);\n            uint64_t subscribeMask = runtimeMask | memViolMask;\n            uint64_t queryMask = 0;\n            int childStatus;\n\n            waitpid(childPid, &childStatus, 0);\n            while (!WIFSTOPPED(childStatus));\n\n            ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), childPid, subscribeMask));\n            ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_DISABLED);\n            ASSERT_EQ(r_info.ttmp_setup, false);\n\n            ptrace(PTRACE_CONT, childPid, NULL, NULL);\n\n            // Wait and unblock runtime enable\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&runtimeMask, NULL, NULL, 5000));\n            ASSERT_EQ(runtimeMask, KFD_EC_MASK(EC_PROCESS_RUNTIME));\n            ASSERT_SUCCESS(debug->SendRuntimeEvent(runtimeMask, 0, 0));\n\n            // Wait for memory violation\n            uint32_t deviceId = -1;\n            ASSERT_SUCCESS(debug->QueryDebugEvent(&queryMask, &deviceId, NULL, 5000));\n            ASSERT_NE(deviceId, -1);\n            ASSERT_EQ(queryMask, memViolMask);\n\n            const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n            uint32_t snapshotSize = gpuNodes.size();\n            struct kfd_dbg_device_info_entry deviceInfo[snapshotSize];\n            memset(deviceInfo, 0, snapshotSize * sizeof(struct kfd_dbg_device_info_entry));\n\n            // Check device snapshot aligns with memory violation on target device.\n            ASSERT_SUCCESS(debug->DeviceSnapshot(memViolMask, (uint64_t)(&deviceInfo[0]),\n                                                 &snapshotSize));\n            ASSERT_EQ(snapshotSize, gpuNodes.size());\n            for (int i = 0; i < snapshotSize; i++) {\n                if (deviceInfo[i].exception_status & memViolMask) {\n                    ASSERT_EQ(deviceInfo[i].gpu_id, deviceId);\n                    break;\n                }\n            }\n            waitpid(childPid, &childStatus, 0);\n            while (!WIFSTOPPED(childStatus));\n\n            // Assume tracee queue has died and halted process\n            ptrace(PTRACE_CONT, childPid, NULL, NULL);\n\n            debug->Detach();\n\n            ptrace(PTRACE_DETACH, childPid, NULL, NULL);\n\n            waitpid(childPid, &childStatus, 0);\n            EXPECT_EQ(WIFEXITED(childStatus), true);\n            EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);\n        }\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n\nTEST_F(KFDDBGTest, HitAddressWatch) {\n    TEST_START(TESTPROFILE_RUNALL)\n    if (m_FamilyId >= FAMILY_VI) {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        if (hsaKmtCheckRuntimeDebugSupport()) {\n            LOG() << \"Skip test as debug API not supported\";\n            goto exit;\n        }\n\n        ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n        HsaNodeProperties nodeProps;\n        ASSERT_SUCCESS(hsaKmtGetNodeProperties(defaultGPUNode, &nodeProps));\n\n        HsaMemoryBuffer readerBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer writerBuf(PAGE_SIZE, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer trap(PAGE_SIZE*2, defaultGPUNode, true, false, true);\n        HsaMemoryBuffer tmaBuf(PAGE_SIZE, defaultGPUNode, false, false, false);\n\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(WatchReadIsa, readerBuf.As<char*>()));\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(WatchWriteIsa, writerBuf.As<char*>()));\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(TrapHandlerIsa, trap.As<char*>()));\n        ASSERT_SUCCESS(hsaKmtSetTrapHandler(defaultGPUNode,\n                                            trap.As<void *>(),\n                                            0x1000,\n                                            tmaBuf.As<void*>(),\n                                            0x1000));\n\n        uint32_t rDebug;\n        ASSERT_SUCCESS(hsaKmtRuntimeEnable(&rDebug, true));\n\n        struct kfd_runtime_info r_info;\n        memset(&r_info, 0, sizeof(struct kfd_runtime_info));\n        BaseDebug *debug = new BaseDebug();\n        ASSERT_SUCCESS(debug->Attach(&r_info, sizeof(r_info), getpid(), 0));\n        ASSERT_EQ(r_info.runtime_state, DEBUG_RUNTIME_STATE_ENABLED);\n\n        const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n        uint32_t numDevices = gpuNodes.size();\n        struct kfd_dbg_device_info_entry deviceInfo[numDevices];\n        memset(deviceInfo, 0, numDevices * sizeof(struct kfd_dbg_device_info_entry));\n        ASSERT_SUCCESS(debug->DeviceSnapshot(0, (uint64_t)(&deviceInfo[0]), &numDevices));\n        ASSERT_EQ(numDevices, gpuNodes.size());\n        bool is_precise = nodeProps.Capability.ui32.PreciseMemoryOperationsSupported;\n\n        if (is_precise) {\n            uint32_t trapFlags = KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP;\n            ASSERT_SUCCESS(debug->SetFlags(&trapFlags));\n        }\n\n        uint32_t enableMask = KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH;\n        uint32_t supportedMask = enableMask;\n        ASSERT_SUCCESS(debug->SetWaveLaunchOverride(KFD_DBG_TRAP_OVERRIDE_OR,\n                                                    &enableMask,\n                                                    &supportedMask));\n        ASSERT_NE(supportedMask & KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH, 0);\n        ASSERT_EQ(enableMask & KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH, 0); // previous set mask\n\n        PM4Queue queue;\n        ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n        const uint32_t watchMask = -1 & UINT_MAX;\n\n        HsaMemoryBuffer targetBuf(PAGE_SIZE, defaultGPUNode, true, false, false);\n        HsaMemoryBuffer resultBuf(PAGE_SIZE, defaultGPUNode, true, false, false);\n        unsigned int *target = targetBuf.As<unsigned int*>();\n        unsigned int *result = resultBuf.As<unsigned int*>();\n\n        for (int mode = KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ;\n                 mode < KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ALL; mode++) {\n\n            // atomics may not be supported on all devices so skip for now.\n            if (mode != KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ &&\n                mode != KFD_DBG_TRAP_ADDRESS_WATCH_MODE_NONREAD)\n                continue;\n\n            uint32_t watchId = -1;\n            ASSERT_SUCCESS(debug->SetAddressWatch((uint64_t)(&target[0]), mode,\n                                                  watchMask, deviceInfo[0].gpu_id, &watchId));\n            ASSERT_EQ(watchId, 0);\n\n            const HsaMemoryBuffer &shaderBuf =\n                mode == KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ ? readerBuf : writerBuf;\n            uint32_t preciseMask = 0x1;\n            uint32_t watchStsMask = m_FamilyId >= FAMILY_GFX12 ? 0x1 : 0x80;\n            result[0] = preciseMask;\n            Dispatch dispatch(shaderBuf);\n            dispatch.SetDim(1, 1, 1);\n            dispatch.SetArgs(&target[0], &result[0]);\n            dispatch.SetPriv(false); // Override GFX11 CWSR WA\n            dispatch.Submit(queue);\n            dispatch.Sync();\n\n            /*\n             * result[0] contains both the HW watch status result mask and the\n             * precise memory operation value check (precise = 1, non-precise = 2)\n             * For devices before GFX12, these masks did not bit wise overlap and\n             * are added into result[0].\n             * In GFX12 and above, they overlap and must be subtracted instead of masked\n             * to assert the correct value.\n             */\n            if (m_FamilyId < FAMILY_GFX12) {\n                ASSERT_EQ(result[0] & watchStsMask, watchStsMask);\n\n                if (is_precise)\n                    ASSERT_EQ(result[0] & preciseMask, preciseMask);\n            } else {\n                uint32_t maskCheck = result[0] - watchStsMask - preciseMask;\n                ASSERT_EQ(maskCheck, is_precise ? 0 : 1);\n            }\n\n            ASSERT_SUCCESS(debug->ClearAddressWatch(deviceInfo[0].gpu_id, watchId));\n            resultBuf.Fill(0);\n            targetBuf.Fill(0);\n        }\n\n        ASSERT_SUCCESS(queue.Destroy());\n        debug->Detach();\n        hsaKmtRuntimeDisable();\n    } else {\n        LOG() << \"Skipping test: Test not supported on family ID 0x\"\n              << m_FamilyId << \".\" << std::endl;\n    }\nexit:\n    LOG() << std::endl;\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDDBGTest.hpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_DBG_TEST__H__\n#define __KFD_DBG_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDDBGTest : public KFDBaseComponentTest {\n public:\n    KFDDBGTest() {}\n    ~KFDDBGTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_DBG_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDEventTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <math.h>\n#include <limits.h>\n\n#include \"KFDEventTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n\n\nvoid KFDEventTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    for (int i = 0; i < MAX_GPU; i++)\n        m_pHsaEventGPU[i] = NULL;\n\n    ROUTINE_END\n}\n\nvoid KFDEventTest::TearDown() {\n    ROUTINE_START\n\n    // Not all tests create an event, destroy only if there is one\n    for (int i = 0; i < MAX_GPU; i++) {\n        if (m_pHsaEventGPU[i] != NULL) {\n            // hsaKmtDestroyEvent moved to TearDown to make sure it is being called\n            EXPECT_SUCCESS(hsaKmtDestroyEvent(m_pHsaEventGPU[i]));\n        }\n    }\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic void CreateDestroyEvent(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex];\n\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode);\n    EXPECT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode);\n\n}\n\nTEST_F(KFDEventTest, CreateDestroyEvent) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CreateDestroyEvent));\n\n    // Destroy event is being called in test TearDown\n    TEST_END;\n}\n\n\nstatic void CreateMaxEvents(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    static const unsigned int MAX_EVENT_NUMBER = 256;\n\n    HsaEvent* pHsaEvent[MAX_EVENT_NUMBER];\n\n    unsigned int i = 0;\n\n    for (i = 0; i < MAX_EVENT_NUMBER; i++) {\n        pHsaEvent[i] = NULL;\n        ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode);\n    }\n\n    for (i = 0; i < MAX_EVENT_NUMBER; i++) {\n        EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode);\n    }\n}\n\nTEST_F(KFDEventTest, CreateMaxEvents) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CreateMaxEvents));\n\n    TEST_END;\n}\n\nstatic void SignalEvent(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex];\n    HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode);\n\n    PM4Queue queue;\n    HsaEvent *tmp_event;\n\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, gpuNode, &tmp_event));\n\n    /* Intentionally let event id for m_pHsaEvent be non zero */\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent));\n    ASSERT_NE(0, m_pHsaEvent->EventData.HWData2);\n\n    ASSERT_SUCCESS(queue.Create(gpuNode));\n\n    /* From gfx9 onward, m_pHsaEvent->EventId will also be passed to int_ctxid in\n     * the Release Mem packet, which is used as context id in ISR.\n     */\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                    m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n\n    queue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut), gpuNode);\n\n    EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(tmp_event), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDEventTest, SignalEvent) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalEvent));\n\n    TEST_END;\n}\n\n/* test event signaling with event age enabled wait */\nstatic void SignalEventExt(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex];\n    HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode);\n\n    PM4Queue queue;\n    HsaEvent *tmp_event;\n    uint64_t event_age;\n\n    if (pKFDEventTest->Get_Version()->KernelInterfaceMajorVersion == 1 &&\n        pKFDEventTest->Get_Version()->KernelInterfaceMinorVersion < 14) {\n        LOG() << \"event age tracking isn't supported in KFD. Exiting.\" << std::endl;\n        return;\n    }\n\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &tmp_event), gpuNode);\n\n    /* Intentionally let event id for m_pHsaEvent be non zero */\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode);\n    ASSERT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    /* 1. event_age gets incremented every time when the event signals */\n    event_age = 1;\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                    m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode);\n    ASSERT_EQ_GPU(event_age, 2, gpuNode);\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                    m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode);\n    ASSERT_EQ_GPU(event_age, 3, gpuNode);\n\n    /* 2. event wait return without sleep after the event signals */\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                    m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n    sleep(1); /* wait for event signaling */\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode);\n    ASSERT_EQ_GPU(event_age, 4, gpuNode);\n\n    /* 3. signaling from CPU */\n    hsaKmtSetEvent(m_pHsaEvent);\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode);\n    ASSERT_EQ_GPU(event_age, 5, gpuNode);\n\n    /* 4. when event_age is 0, hsaKmtWaitOnEvent_Ext always sleeps */\n    event_age = 0;\n    ASSERT_EQ_GPU(HSAKMT_STATUS_WAIT_TIMEOUT, hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age), gpuNode);\n\n    /* 5. when event_age is 0, it always stays 0 after the event signals */\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                    m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n    EXPECT_SUCCESS(hsaKmtWaitOnEvent_Ext(m_pHsaEvent, g_TestTimeOut, &event_age));\n    ASSERT_EQ(event_age, 0);\n\n    EXPECT_SUCCESS(hsaKmtDestroyEvent(tmp_event));\n\n    EXPECT_SUCCESS(queue.Destroy());\n\n}\n\nTEST_F(KFDEventTest, SignalEventExt) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalEventExt));\n\n    TEST_END;\n}\n\nstatic uint64_t gettime() {\n    struct timespec ts;\n    clock_gettime(CLOCK_MONOTONIC, &ts);\n    return ((int64_t)ts.tv_sec) * 1000 * 1000 * 1000 + ts.tv_nsec;\n}\n\nstatic inline double pow2_round_up(int num) {\n    return pow(2, ceil(log(num)/log(2)));\n}\n\nclass QueueAndSignalBenchmark {\n private:\n    static const int HISTORY_SIZE = 100;\n\n    int mNumEvents;\n    int mHistorySlot;\n    uint64_t mTimeHistory[HISTORY_SIZE];\n    uint64_t mLatHistory[HISTORY_SIZE];\n\n public:\n    QueueAndSignalBenchmark(int events) : mNumEvents(events), mHistorySlot(0) {\n        memset(mTimeHistory, 0, sizeof(mTimeHistory));\n        memset(mLatHistory, 0, sizeof(mLatHistory));\n    }\n\n    int queueAndSignalEvents(int node, int eventCount, uint64_t &time, uint64_t &latency) {\n        int r;\n        uint64_t startTime;\n        PM4Queue queue;\n\n        unsigned int familyId = g_baseTest->GetFamilyIdFromNodeId(node);\n        HsaEvent** pHsaEvent = reinterpret_cast<HsaEvent**>(calloc(eventCount, sizeof(HsaEvent*)));\n        size_t packetSize = PM4ReleaseMemoryPacket(familyId, false, 0, 0).SizeInBytes();\n        int qSize = fmax(PAGE_SIZE, pow2_round_up(packetSize*eventCount + 1));\n\n        time = 0;\n\n        r = queue.Create(node, qSize);\n        if (r != HSAKMT_STATUS_SUCCESS)\n            goto exit;\n\n        for (int i = 0; i < eventCount; i++) {\n            r = CreateQueueTypeEvent(false, false, node, &pHsaEvent[i]);\n            if (r != HSAKMT_STATUS_SUCCESS)\n                goto exit;\n\n            queue.PlacePacket(PM4ReleaseMemoryPacket(familyId, false, pHsaEvent[i]->EventData.HWData2, pHsaEvent[i]->EventId));\n        }\n\n        startTime = gettime();\n        queue.SubmitPacket();\n        for (int i = 0; i < eventCount; i++) {\n            r = hsaKmtWaitOnEvent(pHsaEvent[i], g_TestTimeOut);\n\n            if (r != HSAKMT_STATUS_SUCCESS)\n                goto exit;\n\n            if (i == 0)\n                latency = gettime() - startTime;\n        }\n        time = gettime() - startTime;\n\nexit:\n        for (int i = 0; i < eventCount; i++) {\n            if (pHsaEvent[i])\n                hsaKmtDestroyEvent(pHsaEvent[i]);\n        }\n        queue.Destroy();\n\n        return r;\n    }\n\n    void run(int node) {\n        int r = 0;\n        uint64_t time = 0, latency = 0;\n        uint64_t avgLat = 0, avgTime = 0;\n        uint64_t minTime = ULONG_MAX, maxTime = 0;\n        uint64_t minLat = ULONG_MAX, maxLat = 0;\n\n        ASSERT_EQ(queueAndSignalEvents(node, mNumEvents, time, latency), HSAKMT_STATUS_SUCCESS);\n\n        mTimeHistory[mHistorySlot%HISTORY_SIZE] = time;\n        mLatHistory[mHistorySlot%HISTORY_SIZE] = latency;\n\n        for (int i = 0; i < HISTORY_SIZE; i++) {\n            minTime = mTimeHistory[i] < minTime ? mTimeHistory[i] : minTime;\n            maxTime = mTimeHistory[i] > maxTime ? mTimeHistory[i] : maxTime;\n            avgTime += mTimeHistory[i];\n\n            minLat = mLatHistory[i] < minLat ? mLatHistory[i] : minLat;\n            maxLat = mLatHistory[i] > maxLat ? mLatHistory[i] : maxLat;\n            avgLat += mLatHistory[i];\n        }\n\n        avgTime /= HISTORY_SIZE;\n        avgLat /= HISTORY_SIZE;\n        mHistorySlot++;\n\n        printf(\"\\033[KEvents: %d History: %d/%d\\n\", mNumEvents, mHistorySlot, HISTORY_SIZE);\n        printf(\"\\033[KMin Latency: %f ms\\n\", (float)minLat/1000000);\n        printf(\"\\033[KMax Latency: %f ms\\n\", (float)maxLat/1000000);\n        printf(\"\\033[KAvg Latency: %f ms\\n\", (float)avgLat/1000000);\n        printf(\"\\033[K   Min Rate: %f IH/ms\\n\", ((float)mNumEvents)/maxTime*1000000);\n        printf(\"\\033[K   Max Rate: %f IH/ms\\n\", ((float)mNumEvents)/minTime*1000000);\n        printf(\"\\033[K   Avg Rate: %f IH/ms\\n\", ((float)mNumEvents)/avgTime*1000000);\n    }\n};\n\nTEST_F(KFDEventTest, DISABLED_MeasureInterruptConsumption) {\n    TEST_START(TESTPROFILE_RUNALL);\n    QueueAndSignalBenchmark latencyBench(128);\n    QueueAndSignalBenchmark sustainedBench(4095);\n\n    printf(\"\\033[2J\");\n    while (true) {\n        printf(\"\\033[H\");\n        printf(\"--------------------------\\n\");\n        latencyBench.run(m_NodeInfo.HsaDefaultGPUNode());\n        printf(\"--------------------------\\n\");\n        sustainedBench.run(m_NodeInfo.HsaDefaultGPUNode());\n        printf(\"--------------------------\\n\");\n    }\n\n    TEST_END;\n}\n\nstatic void SignalMaxEvents(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    static const unsigned int MAX_EVENT_NUMBER = 4095;\n    uint64_t time, latency;\n\n    QueueAndSignalBenchmark maxEventTest(MAX_EVENT_NUMBER);\n    maxEventTest.queueAndSignalEvents(gpuNode, MAX_EVENT_NUMBER,\n            time, latency);\n}\n\nTEST_F(KFDEventTest, SignalMaxEvents) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalMaxEvents));\n\n    TEST_END;\n}\n\nstatic void SignalMultipleEventsWaitForAll(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode);\n\n    static const unsigned int EVENT_NUMBER = 64;  // 64 is the maximum for hsaKmtWaitOnMultipleEvents\n    static const unsigned int WAIT_BETWEEN_SUBMISSIONS_MS = 50;\n\n    HsaEvent* pHsaEvent[EVENT_NUMBER];\n    unsigned int i = 0;\n\n    for (i = 0; i < EVENT_NUMBER; i++) {\n        pHsaEvent[i] = NULL;\n        ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode);\n    }\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    unsigned int pktSizeDwords = 0;\n    for (i = 0; i < EVENT_NUMBER; i++) {\n        queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false, pHsaEvent[i]->EventData.HWData2,\n                                   pHsaEvent[i]->EventId));\n        queue.Wait4PacketConsumption();\n\n        Delay(WAIT_BETWEEN_SUBMISSIONS_MS);\n    }\n\n    EXPECT_SUCCESS_GPU(hsaKmtWaitOnMultipleEvents(pHsaEvent, EVENT_NUMBER, true, g_TestTimeOut), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    for (i = 0; i < EVENT_NUMBER; i++)\n        EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode);\n}\n\nTEST_F(KFDEventTest, SignalMultipleEventsWaitForAll) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalMultipleEventsWaitForAll));\n\n    TEST_END;\n}\n\n/* Send an event interrupt with 0 context ID. Test that KFD handles it\n * gracefully and with good performance. On current GPUs and firmware it\n * should be handled on a fast path.\n */\nstatic void SignalInvalidEvent(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDEventTest* pKFDEventTest = (KFDEventTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDEventTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HsaEvent* m_pHsaEvent = pKFDEventTest->m_pHsaEventGPU[gpuIndex];\n    HSAuint32 m_FamilyId = pKFDEventTest->GetFamilyIdFromNodeId(gpuNode);\n\n    PM4Queue queue;\n\n    // Create some dummy events, to make the slow path a bit slower\n    static const unsigned int EVENT_NUMBER = 64;//4094;\n    HsaEvent* pHsaEvent[EVENT_NUMBER];\n    for (int i = 0; i < EVENT_NUMBER; i++) {\n        pHsaEvent[i] = NULL;\n        ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &pHsaEvent[i]), gpuNode);\n    }\n\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &m_pHsaEvent), gpuNode);\n    ASSERT_NE_GPU(0, m_pHsaEvent->EventData.HWData2, gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    static const unsigned int REPS = 2000;\n    HSAuint64 duration[REPS];\n    HSAuint64 total = 0, min = 1000000, max = 0;\n    for (int i = 0; i < REPS; i++) {\n        // Invalid signal packet\n        queue.PlacePacket(PM4ReleaseMemoryPacket(m_FamilyId, false, 0, 0));\n        // Submit valid signal packet\n        queue.PlacePacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n                        m_pHsaEvent->EventData.HWData2, m_pHsaEvent->EventId));\n\n        HSAuint64 startTime = GetSystemTickCountInMicroSec();\n        queue.SubmitPacket();\n\n        EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent(m_pHsaEvent, g_TestTimeOut), gpuNode);\n\n        duration[i] = GetSystemTickCountInMicroSec() - startTime;\n        total += duration[i];\n        if (duration[i] < min)\n            min = duration[i];\n        if (duration[i] > max)\n            max = duration[i];\n    }\n\n    double mean = (double)(total - min - max) / (REPS - 2);\n    double variance = 0;\n    bool skippedMin = false, skippedMax = false;\n    HSAuint64 newMin = max, newMax = min;\n    for (int i = 0; i < REPS; i++) {\n        if (!skippedMin && duration[i] == min) {\n            skippedMin = true;\n            continue;\n        }\n        if (!skippedMax && duration[i] == max) {\n            skippedMax = true;\n            continue;\n        }\n        if (duration[i] < newMin)\n            newMin = duration[i];\n        if (duration[i] > newMax)\n            newMax = duration[i];\n        double diff = mean - duration[i];\n        variance += diff*diff;\n    }\n    variance /= REPS - 2;\n    double stdDev = sqrt(variance);\n\n    LOG() << \"Time for event handling (min/avg/max [std.dev] in us) \" << std::dec\n          << newMin << \"/\" << mean << \"/\" << newMax << \" [\" << stdDev << \"]\\n\";\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    for (int i = 0; i < EVENT_NUMBER; i++)\n        EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(pHsaEvent[i]), gpuNode);\n\n}\n\nTEST_F(KFDEventTest, SignalInvalidEvent) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalInvalidEvent));\n\n    TEST_END;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDEventTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDBaseComponentTest.hpp\"\n\n#ifndef __KFD_EVENT_TEST__H__\n#define __KFD_EVENT_TEST__H__\n\nclass KFDEventTest :  public KFDBaseComponentTest {\n public:\n    KFDEventTest(void) {}\n    ~KFDEventTest(void) {}\n\n    // @brief Executed before every test in KFDEventTest.\n    virtual void SetUp();\n    // @brief Executed after every test in KFDEventTest.\n    virtual void TearDown();\n\n    HsaEvent* m_pHsaEventGPU[MAX_GPU];\n protected:\n    static const unsigned int EVENT_TIMEOUT = 5000;  // 5 seconds\n};\n\n#endif  // __KFD_EVENT_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDEvictTest.cpp",
    "content": "/*\n * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <vector>\n#include <string>\n#include \"KFDEvictTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n\n#define N_PROCESSES             (2)     /* Number of processes running in parallel, must be at least 2 */\n#define ALLOCATE_BUF_SIZE_MB    (64)\n#define ALLOCATE_RETRY_TIMES    (3)\n#define MAX_WAVEFRONTS          (512)\n\n#define SDMA_NOP  0x0\n\nvoid KFDEvictTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDEvictTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nvoid KFDEvictTest::AllocBuffers(bool m_IsParent, HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize,\n                                std::vector<void *> &pBuffers) {\n    HSAuint64   totalMB;\n\n    totalMB = N_PROCESSES*count*(vramBufSize>>20);\n    if (m_IsParent) {\n        LOG() << \"Allocating \" << N_PROCESSES << \"*\" << count << \"*\" << (vramBufSize>>20) << \"(=\"\n              << totalMB << \")MB VRAM in KFD\" << std::endl;\n    }\n\n    HsaMemMapFlags mapFlags = {0};\n    HSAKMT_STATUS ret;\n    HSAuint32 retry = 0;\n\n    m_Flags.Value = 0;\n    m_Flags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    m_Flags.ui32.HostAccess = 0;\n    m_Flags.ui32.NonPaged = 1;\n\n    for (HSAuint32 i = 0; i < count; ) {\n        ret = hsaKmtAllocMemory(defaultGPUNode, vramBufSize, m_Flags, &m_pBuf);\n        if (ret == HSAKMT_STATUS_SUCCESS) {\n            if (hsakmt_is_dgpu()) {\n                if (hsaKmtMapMemoryToGPUNodes(m_pBuf, vramBufSize, NULL,\n                       mapFlags, 1, reinterpret_cast<HSAuint32 *>(&defaultGPUNode)) == HSAKMT_STATUS_ERROR) {\n                    EXPECT_SUCCESS(hsaKmtFreeMemory(m_pBuf, vramBufSize));\n                    LOG() << \"Map failed for \" << i << \"/\" << count << \" buffer. Retrying allocation\" << std::endl;\n                    goto retry;\n                }\n            }\n            pBuffers.push_back(m_pBuf);\n\n            i++;\n            retry = 0;\n            continue;\n        }\nretry:\n        if (retry++ > ALLOCATE_RETRY_TIMES) {\n            break;\n        }\n\n        /* Wait for 1 second to try allocate again */\n        sleep(1);\n    }\n}\n\nvoid KFDEvictTest::FreeBuffers(std::vector<void *> &pBuffers, HSAuint64 vramBufSize) {\n    for (HSAuint32 i = 0; i < pBuffers.size(); i++) {\n        m_pBuf = pBuffers[i];\n        if (m_pBuf != NULL) {\n            if (hsakmt_is_dgpu())\n                EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(m_pBuf));\n            EXPECT_SUCCESS(hsaKmtFreeMemory(m_pBuf, vramBufSize));\n        }\n    }\n}\n\nvoid KFDEvictTest::AllocAmdgpuBo(bool m_IsParent, int rn, HSAuint64 vramBufSize, amdgpu_bo_handle &handle) {\n    struct amdgpu_bo_alloc_request alloc;\n\n    alloc.alloc_size = vramBufSize / N_PROCESSES;\n    alloc.phys_alignment = PAGE_SIZE;\n    alloc.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;\n    alloc.flags = AMDGPU_GEM_CREATE_VRAM_CLEARED;\n\n    if (m_IsParent) {\n        LOG() << \"Allocating \" << N_PROCESSES << \"*\" << (vramBufSize >> 20) / N_PROCESSES << \"(=\"\n              << (vramBufSize >> 20)  << \")MB VRAM in GFX\" << std::endl;\n    }\n    ASSERT_EQ(0, amdgpu_bo_alloc(m_RenderNodes[rn].device_handle, &alloc, &handle));\n}\n\nvoid KFDEvictTest::FreeAmdgpuBo(amdgpu_bo_handle handle) {\n    ASSERT_EQ(0, amdgpu_bo_free(handle));\n}\n\nstatic int amdgpu_bo_alloc_and_map(amdgpu_device_handle dev, unsigned size,\n                                   unsigned alignment, unsigned heap, uint64_t flags,\n                                   amdgpu_bo_handle *bo, void **cpu, uint64_t *mc_address,\n                                   amdgpu_va_handle *va_handle) {\n    struct amdgpu_bo_alloc_request request = {};\n    amdgpu_bo_handle buf_handle;\n    amdgpu_va_handle handle;\n    uint64_t vmc_addr;\n    int r;\n\n    request.alloc_size = size;\n    request.phys_alignment = alignment;\n    request.preferred_heap = heap;\n    request.flags = flags;\n\n    r = amdgpu_bo_alloc(dev, &request, &buf_handle);\n    if (r)\n        return r;\n\n    r = amdgpu_va_range_alloc(dev,\n                  amdgpu_gpu_va_range_general,\n                  size, alignment, 0, &vmc_addr,\n                  &handle, 0);\n    if (r)\n        goto error_va_alloc;\n\n    r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_MAP);\n    if (r)\n        goto error_va_map;\n\n    r = amdgpu_bo_cpu_map(buf_handle, cpu);\n    if (r)\n        goto error_cpu_map;\n\n    *bo = buf_handle;\n    *mc_address = vmc_addr;\n    *va_handle = handle;\n\n    return 0;\n\nerror_cpu_map:\n    amdgpu_bo_cpu_unmap(buf_handle);\n\nerror_va_map:\n    amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP);\n\nerror_va_alloc:\n    amdgpu_bo_free(buf_handle);\n    return r;\n}\n\nstatic inline int amdgpu_bo_unmap_and_free(amdgpu_bo_handle bo, amdgpu_va_handle va_handle,\n                                           uint64_t mc_addr, uint64_t size) {\n    amdgpu_bo_cpu_unmap(bo);\n    amdgpu_bo_va_op(bo, 0, size, mc_addr, 0, AMDGPU_VA_OP_UNMAP);\n    amdgpu_va_range_free(va_handle);\n    amdgpu_bo_free(bo);\n\n    return 0;\n}\n\nstatic inline int amdgpu_get_bo_list(amdgpu_device_handle dev, amdgpu_bo_handle bo1,\n                                     amdgpu_bo_handle bo2, amdgpu_bo_list_handle *list) {\n    amdgpu_bo_handle resources[] = {bo1, bo2};\n\n    return amdgpu_bo_list_create(dev, bo2 ? 2 : 1, resources, NULL, list);\n}\n\nvoid KFDEvictTest::AmdgpuCommandSubmissionSdmaNop(int rn, amdgpu_bo_handle handle,\n                                                     PM4Queue *computeQueue = NULL) {\n    amdgpu_context_handle contextHandle;\n    amdgpu_bo_handle ibResultHandle;\n    void *ibResultCpu;\n    uint64_t ibResultMcAddress;\n    struct amdgpu_cs_request ibsRequest;\n    struct amdgpu_cs_ib_info ibInfo;\n    struct amdgpu_cs_fence fenceStatus;\n    amdgpu_bo_list_handle boList;\n    amdgpu_va_handle vaHandle;\n    uint32_t *ptr;\n    uint32_t expired;\n    unsigned failCount = 0;\n\n    ASSERT_EQ(0, amdgpu_cs_ctx_create(m_RenderNodes[rn].device_handle, &contextHandle));\n\n    ASSERT_EQ(0, amdgpu_bo_alloc_and_map(m_RenderNodes[rn].device_handle,\n        PAGE_SIZE, PAGE_SIZE,\n        AMDGPU_GEM_DOMAIN_GTT, 0,\n        &ibResultHandle, &ibResultCpu,\n        &ibResultMcAddress, &vaHandle));\n\n    ASSERT_EQ(0, amdgpu_get_bo_list(m_RenderNodes[rn].device_handle, ibResultHandle, handle,\n        &boList));\n\n    /* Fill Nop cammands in IB */\n    ptr = reinterpret_cast<uint32_t *>(ibResultCpu);\n    for (int i = 0; i < 16; i++)\n        ptr[i] = SDMA_NOP;\n\n    memset(&ibInfo, 0, sizeof(struct amdgpu_cs_ib_info));\n    ibInfo.ib_mc_address = ibResultMcAddress;\n    ibInfo.size = 16;\n\n    memset(&ibsRequest, 0, sizeof(struct amdgpu_cs_request));\n    ibsRequest.ip_type = AMDGPU_HW_IP_DMA;\n    ibsRequest.ring = 0;\n    ibsRequest.number_of_ibs = 1;\n    ibsRequest.ibs = &ibInfo;\n    ibsRequest.resources = boList;\n    ibsRequest.fence_info.handle = NULL;\n\n    memset(&fenceStatus, 0, sizeof(struct amdgpu_cs_fence));\n    for (int i = 0; i < 100; i++) {\n        int r = amdgpu_cs_submit(contextHandle, 0, &ibsRequest, 1);\n\n        Delay(50);\n        if (r) {\n            failCount++;\n            ASSERT_LE(failCount, 2);\n            continue;\n        }\n\n        fenceStatus.context = contextHandle;\n        fenceStatus.ip_type = AMDGPU_HW_IP_DMA;\n        fenceStatus.ip_instance = 0;\n        fenceStatus.ring = 0;\n        fenceStatus.fence = ibsRequest.seq_no;\n\n        EXPECT_EQ(0, amdgpu_cs_query_fence_status(&fenceStatus,\n                                                  g_TestTimeOut*1000000,\n                                                  0, &expired));\n        if (!expired)\n            WARN() << \"CS did not signal completion\" << std::endl;\n\n        /* If a compute queue is given, submit a short compute job\n         * every 16 loops (about once a second). If the process was\n         * evicted, restore can take quite long.\n         */\n        if (computeQueue && (i & 0xf) == 0) {\n            computeQueue->PlaceAndSubmitPacket(PM4NopPacket());\n            computeQueue->Wait4PacketConsumption(NULL, 10000);\n        }\n    }\n\n    EXPECT_EQ(0, amdgpu_bo_list_destroy(boList));\n\n    EXPECT_EQ(0, amdgpu_bo_unmap_and_free(ibResultHandle, vaHandle,\n        ibResultMcAddress, PAGE_SIZE));\n\n    EXPECT_EQ(0, amdgpu_cs_ctx_free(contextHandle));\n}\n\n/* Evict and restore procedure basic test\n *\n * Use N_PROCESSES processes to allocate vram buf size larger than total vram size\n *\n * ALLOCATE_BUF_SIZE_MB buf allocation size\n *\n * buf is equal to (vramSizeMB / (vramBufSizeMB * N_PROCESSES) ) + 8\n * Total vram all processes allocated: 8GB for 4GB Fiji, and 20GB for 16GB Vega10\n *\n * Eviction and restore will happen many times:\n * ttm will evict buffers of another process if there is not enough free vram\n * process restore will evict buffers of another process\n *\n * Sometimes the allocation may fail (maybe that is normal)\n * ALLOCATE_RETRY_TIMES max retry times to allocate\n *\n * This is basic test with no queue, so vram is not used by the GPU during test\n *\n * TODO:\n *    - Synchronization between the processes, so they know for sure when\n *        they are done allocating memory\n */\nTEST_F(KFDEvictTest, BasicTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n    HSAuint64 vramBufSize = ALLOCATE_BUF_SIZE_MB * 1024 * 1024;\n\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n    HSAuint64 sysMemSize = GetSysMemSize();\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(defaultGPUNode);\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    LOG() << \"Found VRAM of \" << std::dec << (vramSize >> 20) << \"MB\" << std::endl;\n    LOG() << \"Found System RAM of \" << std::dec << (sysMemSize >> 20) << \"MB\" << std::endl;\n\n    // Use 7/8 of VRAM between all processes\n    HSAuint64 testSize = vramSize * 7 / 8;\n    HSAuint32 count = testSize / (vramBufSize * N_PROCESSES);\n\n    if (count == 0) {\n        LOG() << \"Skipping test: Not enough system memory available.\" << std::endl;\n        return;\n    }\n\n    /* Fork the child processes */\n    ForkChildProcesses(defaultGPUNode, N_PROCESSES);\n\n    int rn = FindDRMRenderNode(defaultGPUNode);\n    if (rn < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU.\" << std::endl;\n        WaitChildProcesses(defaultGPUNode);\n        return;\n    }\n\n    std::vector<void *> pBuffers;\n    AllocBuffers(m_IsParent[gpuIndex], defaultGPUNode, count, vramBufSize, pBuffers);\n\n    /* Allocate gfx vram size of at most one-fourth system memory */\n    HSAuint64 size = sysMemSize / 4 < testSize / 3 ? sysMemSize / 4 : testSize / 3;\n    amdgpu_bo_handle handle;\n    AllocAmdgpuBo(m_IsParent[gpuIndex], rn, size, handle);\n\n    AmdgpuCommandSubmissionSdmaNop(rn, handle);\n\n    FreeAmdgpuBo(handle);\n    LOG() << m_psName[gpuIndex] << \"free buffer\" << std::endl;\n    FreeBuffers(pBuffers, vramBufSize);\n\n    WaitChildProcesses(defaultGPUNode);\n\n    TEST_END\n}\n\n/* Evict and restore queue test\n *\n * N_PROCESSES processes read all local buffers in parallel while buffers are evicted and restored\n * If GPU vm page fault happens, then test shader will stop and failed to write specific value\n * at dest buffer. Test will report failed.\n *\n * Steps:\n *    - fork N_PROCESSES processes, each process does the same below\n *    - allocate local buffers, each buffer size is 64MB\n *    - allocate zero initialized host access address buffer and result buffer\n *        address buffer to pass address of local buffers to shader\n *        result buffer to store shader output result\n *    - submit queue to run ReadMemory shader\n *    - shader start m_DimX wavefronts, each wavefront keep reading one local buffer\n *    - notify shader to quit\n *    - check result buffer with specific value to confirm all wavefronts quit normally\n */\nTEST_F(KFDEvictTest, QueueTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n    unsigned int count = MAX_WAVEFRONTS;\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(defaultGPUNode);\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n\n    /* Skip test for chip if it doesn't have CWSR, which the test depends on */\n    if (m_FamilyId < FAMILY_VI || isTonga(pNodeProperties)) {\n        LOG() << std::hex << \"Skipping test: No CWSR present for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 i;\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n    HSAuint64 sysMemSize = GetSysMemSize();\n\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    LOG() << \"Found VRAM of \" << std::dec << (vramSize >> 20) << \"MB\" << std::endl;\n    LOG() << \"Found System RAM of \" << std::dec << (sysMemSize >> 20) << \"MB\" << std::endl;\n\n    // Use 7/8 of VRAM between all processes\n    HSAuint64 testSize = vramSize * 7 / 8;\n    HSAuint32 vramBufSize = testSize / (count * N_PROCESSES);\n    vramBufSize = (vramBufSize / (1024 * 1024)) * (1024 * 1024);\n\n    if (vramBufSize == 0) {\n        LOG() << \"Skipping test: Not enough system memory available.\" << std::endl;\n        return;\n    }\n    /* Assert all buffer address can be stored within one page\n     * because only one page host memory srcBuf is allocated\n     */\n    ASSERT_LE(count, PAGE_SIZE/sizeof(unsigned int *));\n\n    /* Fork the child processes */\n    ForkChildProcesses(defaultGPUNode, N_PROCESSES);\n\n    int rn = FindDRMRenderNode(defaultGPUNode);\n    if (rn < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU.\" << std::endl;\n        WaitChildProcesses(defaultGPUNode);\n        return;\n    }\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, defaultGPUNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer addrBuffer(PAGE_SIZE, defaultGPUNode);\n    HsaMemoryBuffer resultBuffer(PAGE_SIZE, defaultGPUNode);\n\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadMemoryIsa, isaBuffer.As<char*>()));\n\n    PM4Queue pm4Queue;\n    ASSERT_SUCCESS(pm4Queue.Create(defaultGPUNode));\n\n    Dispatch dispatch0(isaBuffer);\n\n    std::vector<void *> pBuffers;\n    AllocBuffers(m_IsParent[gpuIndex], defaultGPUNode, count, vramBufSize, pBuffers);\n\n    /* Allocate gfx vram size of at most one-fourth system memory */\n    HSAuint64 size = sysMemSize / 4 < testSize / 3 ? sysMemSize / 4 : testSize / 3;\n    amdgpu_bo_handle handle;\n    AllocAmdgpuBo(m_IsParent[gpuIndex], rn, size, handle);\n\n    unsigned int wavefront_num = pBuffers.size();\n    LOG() << m_psName[gpuIndex] << \"wavefront number \" << wavefront_num << std::endl;\n\n    void **localBufAddr = addrBuffer.As<void **>();\n    unsigned int *result = resultBuffer.As<uint32_t *>();\n\n    for (i = 0; i < wavefront_num; i++)\n        *(localBufAddr + i) = pBuffers[i];\n\n    for (i = 0; i < wavefront_num; i++)\n        *(result + i) = vramBufSize;\n\n    dispatch0.SetArgs(localBufAddr, result);\n    dispatch0.SetDim(wavefront_num, 1, 1);\n    /* Submit the packet and start shader */\n    dispatch0.Submit(pm4Queue);\n\n    AmdgpuCommandSubmissionSdmaNop(rn, handle);\n\n    /* Uncomment this line for debugging */\n    // LOG() << m_psName << \"notify shader to quit\" << std::endl;\n\n    /* Fill address buffer so shader quits */\n    addrBuffer.Fill(0x5678);\n\n    /* Wait for shader to finish or timeout if shader has vm page fault */\n    EXPECT_EQ(0, dispatch0.SyncWithStatus(g_TestTimeOut * 5));\n\n    EXPECT_SUCCESS(pm4Queue.Destroy());\n\n    FreeAmdgpuBo(handle);\n\n    /* Uncomment this line for debugging */\n    // LOG() << m_psName << \"free buffer\" << std::endl;\n\n    /* Cleanup */\n    FreeBuffers(pBuffers, vramBufSize);\n\n    /* Check if all wavefronts finished successfully */\n    for (i = 0; i < wavefront_num; i++)\n        EXPECT_EQ(0x5678, *(result + i));\n\n    WaitChildProcesses(defaultGPUNode);\n\n    TEST_END\n}\n\n/* Evict a queue running in bursts, so that the process has a chance\n * to be idle when restored but the queue needs to resume to perform\n * more work later. This test is designed to stress the idle process\n * eviction optimization in KFD that leaves idle processes evicted\n * until the next time the doorbell page is accessed.\n */\nTEST_F(KFDEvictTest, BurstyTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n    HSAuint64 vramBufSize = ALLOCATE_BUF_SIZE_MB * 1024 * 1024;\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(defaultGPUNode);\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n    HSAuint64 sysMemSize = GetSysMemSize();\n\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    LOG() << \"Found VRAM of \" << std::dec << (vramSize >> 20) << \"MB\" << std::endl;\n    LOG() << \"Found System RAM of \" << std::dec << (sysMemSize >> 20) << \"MB\" << std::endl;\n\n    // Use 7/8 of VRAM between all processes\n    HSAuint64 testSize = vramSize * 7 / 8;\n    HSAuint32 count = testSize / (vramBufSize * N_PROCESSES);\n\n    if (count == 0) {\n        LOG() << \"Skipping test: Not enough system memory available.\" << std::endl;\n        return;\n    }\n\n    /* Fork the child processes */\n    ForkChildProcesses(defaultGPUNode, N_PROCESSES);\n\n    int rn = FindDRMRenderNode(defaultGPUNode);\n    if (rn < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU.\" << std::endl;\n        WaitChildProcesses(defaultGPUNode);\n        return;\n    }\n\n    PM4Queue pm4Queue;\n    ASSERT_SUCCESS(pm4Queue.Create(defaultGPUNode));\n\n    std::vector<void *> pBuffers;\n    AllocBuffers(m_IsParent[gpuIndex], defaultGPUNode, count, vramBufSize, pBuffers);\n\n    /* Allocate gfx vram size of at most one third system memory */\n    HSAuint64 size = sysMemSize / 3 < testSize / 2 ? sysMemSize / 3 : testSize / 2;\n    amdgpu_bo_handle handle;\n    AllocAmdgpuBo(m_IsParent[gpuIndex], rn, size, handle);\n\n    AmdgpuCommandSubmissionSdmaNop(rn, handle, &pm4Queue);\n\n    FreeAmdgpuBo(handle);\n    LOG() << m_psName[gpuIndex] << \"free buffer\" << std::endl;\n    FreeBuffers(pBuffers, vramBufSize);\n\n    EXPECT_SUCCESS(pm4Queue.Destroy());\n\n    WaitChildProcesses(defaultGPUNode);\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDEvictTest.hpp",
    "content": "/*\n * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_EVICT_TEST__H__\n#define __KFD_EVICT_TEST__H__\n\n#include <string>\n#include <vector>\n#include \"KFDMultiProcessTest.hpp\"\n#include \"PM4Queue.hpp\"\n\n// @class KFDEvictTest\n// Test eviction and restore procedure using two processes\nclass KFDEvictTest :  public KFDMultiProcessTest {\n public:\n    KFDEvictTest(void) {}\n    ~KFDEvictTest(void) {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n    void AllocBuffers(bool m_IsParent, HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize,\n                      std::vector<void *> &pBuffers);\n    void FreeBuffers(std::vector<void *> &pBuffers, HSAuint64 vramBufSize);\n    void AllocAmdgpuBo(bool m_IsParent, int rn, HSAuint64 vramBufSize, amdgpu_bo_handle &handle);\n    void FreeAmdgpuBo(amdgpu_bo_handle handle);\n    void AmdgpuCommandSubmissionSdmaNop(int rn, amdgpu_bo_handle handle,\n                                           PM4Queue *computeQueue);\n\n protected:  // Members\n    HsaMemFlags     m_Flags;\n    void*           m_pBuf;\n};\n\n#endif  // __KFD_EVICT_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDExceptionTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDExceptionTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n#include <sys/mman.h>\n\nvoid KFDExceptionTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    LOG() << \"This Exception test might cause expected page fault \"\n             \"error logs at kernel level.\" << std::endl;\n\n    ROUTINE_END\n}\n\nvoid KFDExceptionTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    // WORKAROUND: This needs to be fixed in the kernel\n    // Wait 500ms for the kernel to process any fault storms before the\n    // next test to avoid reporting incorrect faults in the next test.\n    Delay(500);\n\n    ROUTINE_END\n}\n\n/* Test for memory exception. The function expects a Memory Fault to be\n * triggered by the GPU when it tries to copy dword from pSrc to pDst.\n * Should be called from a Child Process since the Memory Fault causes\n * all the queues to be halted.\n*/\nvoid KFDExceptionTest::TestMemoryException(int gpuNode, HSAuint64 pSrc,\n                                           HSAuint64 pDst, unsigned int dimX,\n                                           unsigned int dimY, unsigned int dimZ) {\n    PM4Queue queue;\n    HsaEvent *vmFaultEvent;\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HSAuint64 faultAddress, page_mask = ~((HSAuint64)PAGE_SIZE - 1);\n    Dispatch dispatch(isaBuffer, false);\n\n    HsaEventDescriptor eventDesc;\n    eventDesc.EventType = HSA_EVENTTYPE_MEMORY;\n    eventDesc.NodeId = gpuNode;\n    eventDesc.SyncVar.SyncVar.UserData = NULL;\n    eventDesc.SyncVar.SyncVarSize = 0;\n\n    ASSERT_SUCCESS_GPU(GetAssemblerFromNodeId(\n       gpuNode)->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    m_ChildStatus = queue.Create(gpuNode);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Queue create failed, on gpuNode: \" << gpuNode << std::endl;\n        return;\n    }\n    m_ChildStatus = hsaKmtCreateEvent(&eventDesc, true, false, &vmFaultEvent);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Event create failed on gpuNode: \" << gpuNode << std::endl;\n        goto queuefail;\n    }\n\n    dispatch.SetDim(dimX, dimY, dimZ);\n    dispatch.SetArgs(reinterpret_cast<void *>(pSrc), reinterpret_cast<void *>(pDst));\n    dispatch.Submit(queue);\n\n    m_ChildStatus = hsaKmtWaitOnEvent(vmFaultEvent, g_TestTimeOut);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Wait failed. No Exception triggered on gpuNode: \" << gpuNode << std::endl;\n        goto eventfail;\n    }\n\n    if (vmFaultEvent->EventData.EventType != HSA_EVENTTYPE_MEMORY) {\n        WARN() << \"Unexpected Event Received on gpuNode: \" << gpuNode << vmFaultEvent->EventData.EventType\n               << std::endl;\n        m_ChildStatus = HSAKMT_STATUS_ERROR;\n        goto eventfail;\n    }\n    faultAddress = vmFaultEvent->EventData.EventData.MemoryAccessFault.VirtualAddress;\n    if (faultAddress != (pSrc & page_mask) &&\n        faultAddress != (pDst & page_mask) ) {\n        WARN() << \"gpuNode: \" << gpuNode << \" Unexpected Fault Address \" << faultAddress\n               << \" expected \" << (pSrc & page_mask) << \" or \"\n               << (pDst & page_mask) << std::endl;\n        m_ChildStatus = HSAKMT_STATUS_ERROR;\n    }\n\neventfail:\n    hsaKmtDestroyEvent(vmFaultEvent);\nqueuefail:\n    queue.Destroy();\n}\n\nvoid KFDExceptionTest::TestSdmaException(int gpuNode, void *pDst) {\n    SDMAQueue queue;\n    HsaEvent *vmFaultEvent;\n    HSAuint64 faultAddress, page_mask = ~((HSAuint64)PAGE_SIZE - 1);\n\n\n    HsaEventDescriptor eventDesc;\n    eventDesc.EventType = HSA_EVENTTYPE_MEMORY;\n    eventDesc.NodeId = gpuNode;\n    eventDesc.SyncVar.SyncVar.UserData = NULL;\n    eventDesc.SyncVar.SyncVarSize = 0;\n\n    m_ChildStatus = queue.Create(gpuNode);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Queue create failed on gpuNode: \" << gpuNode << std::endl;\n        return;\n    }\n\n    m_ChildStatus = hsaKmtCreateEvent(&eventDesc, true, false, &vmFaultEvent);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Event create failed on gpuNode: \" << gpuNode << std::endl;\n        goto queuefail;\n    }\n\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(),\n                                                   reinterpret_cast<void *>(pDst),\n                                                   0x02020202));\n\n    m_ChildStatus = hsaKmtWaitOnEvent(vmFaultEvent, g_TestTimeOut);\n    if (m_ChildStatus != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Wait failed. No Exception triggered on gpuNode: \" << gpuNode << std::endl;\n        goto eventfail;\n    }\n\n    if (vmFaultEvent->EventData.EventType != HSA_EVENTTYPE_MEMORY) {\n        WARN() << \"Unexpected Event Received \" << vmFaultEvent->EventData.EventType\n               << std::endl;\n        m_ChildStatus = HSAKMT_STATUS_ERROR;\n        goto eventfail;\n    }\n    faultAddress = vmFaultEvent->EventData.EventData.MemoryAccessFault.VirtualAddress;\n    if (faultAddress != ((HSAuint64)pDst & page_mask) ) {\n        WARN() << \"gpuNode: \" << gpuNode << \"Unexpected Fault Address \" << faultAddress\n               << \" expected \" << ((HSAuint64)pDst & page_mask) << std::endl;\n        m_ChildStatus = HSAKMT_STATUS_ERROR;\n    }\n\neventfail:\n    hsaKmtDestroyEvent(vmFaultEvent);\nqueuefail:\n    queue.Destroy();\n}\n\nvoid AddressFault(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDExceptionTest* pKFDExceptionTest = (KFDExceptionTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDExceptionTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_RV) {\n        LOG() << \"Skipping test: IOMMU issues on Raven.\" << std::endl;\n        return;\n    }\n\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        pKFDExceptionTest->TearDown();\n        pKFDExceptionTest->SetUp();\n\n        HsaMemoryBuffer srcBuffer(PAGE_SIZE, gpuNode, false);\n\n        srcBuffer.Fill(0xAA55AA55);\n        pKFDExceptionTest->TestMemoryException(gpuNode, srcBuffer.As<HSAuint64>(),\n                                               0x12345678ULL);\n        exit(0);\n\n\t} else {\n        int childStatus;\n\n        waitpid(m_ChildPid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ_GPU(WIFEXITED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS, gpuNode);\n        } else {\n            EXPECT_EQ_GPU(WIFSIGNALED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WTERMSIG(childStatus), SIGSEGV, gpuNode);\n        }\n   }\n}\n\n/* Test Bad Address access in a child process */\nTEST_F(KFDExceptionTest, AddressFault) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(AddressFault));\n\n    TEST_END\n}\n\n/* Allocate Read Only buffer. Test Memory Exception failure by\n * attempting to write to that buffer in the child process.\n */\nvoid PermissionFault(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDExceptionTest* pKFDExceptionTest = (KFDExceptionTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDExceptionTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_RV) {\n        LOG() << \"Skipping test: IOMMU issues on Raven.\" << std::endl;\n        return;\n    }\n\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        pKFDExceptionTest->TearDown();\n        pKFDExceptionTest->SetUp();\n\n        HsaMemoryBuffer readOnlyBuffer(PAGE_SIZE, gpuNode, false /*zero*/,\n                                       false /*isLocal*/, true /*isExec*/,\n                                       false /*isScratch*/, true /*isReadOnly*/);\n        HsaMemoryBuffer srcSysBuffer(PAGE_SIZE, gpuNode, false);\n\n        srcSysBuffer.Fill(0xAA55AA55);\n\n        pKFDExceptionTest->TestMemoryException(gpuNode, srcSysBuffer.As<HSAuint64>(),\n                            readOnlyBuffer.As<HSAuint64>());\n\n        exit(0);\n    } else {\n        int childStatus;\n\n        waitpid(m_ChildPid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ(WIFEXITED(childStatus), true);\n            EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);\n        } else {\n            EXPECT_EQ(WIFSIGNALED(childStatus), true);\n            EXPECT_EQ(WTERMSIG(childStatus), SIGSEGV);\n        }\n    }\n\n}\n\nTEST_F(KFDExceptionTest, PermissionFault) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(PermissionFault));\n\n    TEST_END\n}\n\n/* Allocate Read Only user pointer buffer. Test Memory Exception failure by\n * attempting to write to that buffer in the child process.\n */\nvoid PermissionFaultUserPointer(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDExceptionTest* pKFDExceptionTest = (KFDExceptionTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDExceptionTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_RV) {\n        LOG() << \"Skipping test: IOMMU issues on Raven.\" << std::endl;\n        return;\n    }\n\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        pKFDExceptionTest->TearDown();\n        pKFDExceptionTest->SetUp();\n\n         void *pBuf = mmap(NULL, PAGE_SIZE, PROT_READ,\n                      MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n         ASSERT_NE(pBuf, MAP_FAILED);\n         EXPECT_SUCCESS(hsaKmtRegisterMemory(pBuf, PAGE_SIZE));\n         EXPECT_SUCCESS(hsaKmtMapMemoryToGPU(pBuf, PAGE_SIZE, NULL));\n         HsaMemoryBuffer srcSysBuffer(PAGE_SIZE, gpuNode, false);\n\n         srcSysBuffer.Fill(0xAA55AA55);\n\n         pKFDExceptionTest->TestMemoryException(gpuNode, srcSysBuffer.As<HSAuint64>(),\n                                                (HSAuint64)pBuf);\n\n        exit(0);\n    } else {\n        int childStatus;\n\n        waitpid(m_ChildPid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ(WIFEXITED(childStatus), true);\n            EXPECT_EQ(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS);\n        } else {\n            EXPECT_EQ(WIFSIGNALED(childStatus), true);\n            EXPECT_EQ(WTERMSIG(childStatus), SIGSEGV);\n        }\n   }\n\n}\n\nTEST_F(KFDExceptionTest, PermissionFaultUserPointer) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(PermissionFault));\n\n    TEST_END\n}\n\n/* Test VM fault storm handling by copying to/from invalid pointers\n * with lots of work items at the same time\n */\nvoid FaultStorm(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDExceptionTest* pKFDExceptionTest = (KFDExceptionTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDExceptionTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_RV) {\n        LOG() << \"Skipping test: IOMMU issues on Raven.\" << std::endl;\n        return;\n    }\n\n    HSAKMT_STATUS status;\n\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        pKFDExceptionTest->TearDown();\n        pKFDExceptionTest->SetUp();\n\n        pKFDExceptionTest->TestMemoryException(gpuNode, 0x12345678, 0x76543210, 1024, 1024, 1);\n\n        exit(0);\n    } else {\n        int childStatus;\n\n        waitpid(m_ChildPid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ_GPU(WIFEXITED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS, gpuNode);\n        } else {\n            EXPECT_EQ_GPU(WIFSIGNALED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WTERMSIG(childStatus), SIGSEGV, gpuNode);\n        }\n    }\n\n}\n\nTEST_F(KFDExceptionTest, FaultStorm) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(FaultStorm));\n\n    TEST_END\n}\n\n/*\n */\nvoid SdmaQueueException(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDExceptionTest* pKFDExceptionTest = (KFDExceptionTest*)pTestParamters->pTestObject;\n\n    const HSAuint32 m_FamilyId = pKFDExceptionTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_RV) {\n        LOG() << \"Skipping test: IOMMU issues on Raven.\" << std::endl;\n        return;\n    }\n\n    HSAKMT_STATUS status;\n\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        unsigned int* pDb = NULL;\n        unsigned int *nullPtr = NULL;\n\n        pKFDExceptionTest->TearDown();\n        pKFDExceptionTest->SetUp();\n\n        HsaMemFlags m_MemoryFlags;\n        m_MemoryFlags.Value = 0;\n       // setting memory flags with default values , can be modified according to needs\n        m_MemoryFlags.ui32.NonPaged = 1;                         // Paged\n        m_MemoryFlags.ui32.HostAccess = 0;                       // Host accessible\n        ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, m_MemoryFlags,\n                                  reinterpret_cast<void**>(&pDb)), gpuNode);\n        // verify that pDb is not null before it's being used\n        ASSERT_NE_GPU(nullPtr, pDb, gpuNode) << \"hsaKmtAllocMemory returned a null pointer\";\n        ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(pDb, PAGE_SIZE, NULL), gpuNode);\n        EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pDb), gpuNode);\n\n        pKFDExceptionTest->TestSdmaException(gpuNode, pDb);\n        EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, PAGE_SIZE), gpuNode);\n\n        exit(0);\n    } else {\n        int childStatus;\n\n        waitpid(m_ChildPid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ_GPU(WIFEXITED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WEXITSTATUS(childStatus), HSAKMT_STATUS_SUCCESS, gpuNode);\n        } else {\n            EXPECT_EQ_GPU(WIFSIGNALED(childStatus), true, gpuNode);\n            EXPECT_EQ_GPU(WTERMSIG(childStatus), SIGSEGV, gpuNode);\n        }\n    }\n}\n\nTEST_F(KFDExceptionTest, SdmaQueueException) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SdmaQueueException));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDExceptionTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_EXCEPTION_TEST__H__\n#define __KFD_EXCEPTION_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDExceptionTest : public KFDBaseComponentTest {\n public:\n    KFDExceptionTest() : m_ChildPid(-1) {\n        /* Because there could be early return before m_ChildPid is set\n         * by fork(), we should initialize m_ChildPid to a non-zero value\n         * to avoid possible exit of the main process.\n         */\n    }\n\n    ~KFDExceptionTest() {\n        /* exit() is necessary for the child process. Otherwise when the\n         * child process finishes, gtest assumes the test has finished and\n         * starts the next test while the parent is still active.\n         */\n        if (m_ChildPid == 0) {\n            if (!m_ChildStatus && HasFatalFailure())\n                m_ChildStatus = HSAKMT_STATUS_ERROR;\n            exit(m_ChildStatus);\n        }\n    }\n\n    friend void AddressFault(KFDTEST_PARAMETERS* pTestParamters);\n    friend void PermissionFault(KFDTEST_PARAMETERS* pTestParamters);\n    friend void PermissionFaultUserPointer(KFDTEST_PARAMETERS* pTestParamters);\n    friend void FaultStorm(KFDTEST_PARAMETERS* pTestParamters);\n    friend void SdmaQueueException(KFDTEST_PARAMETERS* pTestParamters);\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n    void TestMemoryException(int gpuNode, HSAuint64 pSrc, HSAuint64 pDst,\n                             unsigned int dimX = 1, unsigned int dimY = 1,\n                             unsigned int dimZ = 1);\n    void TestSdmaException(int gpuNode, void *pDst);\n\n protected:  // Members\n    pid_t m_ChildPid;\n    HSAKMT_STATUS m_ChildStatus;\n};\n\n#endif  // __KFD_EXCEPTION_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDGWSTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDGWSTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"Dispatch.hpp\"\n\nvoid KFDGWSTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDGWSTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic void Allocate(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDGWSTest* pKFDGWSTest = (KFDGWSTest*)pTestParamters->pTestObject;\n\n    HSAuint32 firstGWS;\n    PM4Queue queue;\n    HsaNodeInfo* m_NodeInfo = pKFDGWSTest->Get_NodeInfo();\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo->GetNodeProperties(gpuNode);\n\n    if (!pNodeProperties || !pNodeProperties->NumGws) {\n        LOG() << \"Skip test: GPU node doesn't support GWS\" << std::endl;\n        return;\n    }\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtAllocQueueGWS(queue.GetResource()->QueueId,\n                       pNodeProperties->NumGws,&firstGWS), gpuNode);\n    EXPECT_EQ_GPU(0, firstGWS, gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\nTEST_F(KFDGWSTest, Allocate) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(Allocate));\n\n    TEST_END\n}\n\nstatic void Semaphore(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDGWSTest* pKFDGWSTest = (KFDGWSTest*)pTestParamters->pTestObject;\n\n    HsaNodeInfo* m_NodeInfo = pKFDGWSTest->Get_NodeInfo();\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo->GetNodeProperties(gpuNode);\n\n    HSAuint32 firstGWS;\n    HSAuint32 numResources = 1;\n    PM4Queue queue;\n\n    if (!pNodeProperties || !pNodeProperties->NumGws) {\n        LOG() << \"Skip test: GPU node doesn't support GWS\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer buffer(PAGE_SIZE, gpuNode, true, false, false);\n    ASSERT_SUCCESS(queue.Create(gpuNode));\n    ASSERT_SUCCESS_GPU(hsaKmtAllocQueueGWS(queue.GetResource()->QueueId,\n                       pNodeProperties->NumGws,&firstGWS), gpuNode);\n    EXPECT_EQ_GPU(0, firstGWS, gpuNode);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDGWSTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(GwsInitIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch0(isaBuffer);\n    buffer.Fill(numResources, 0, 4);\n    dispatch0.SetArgs(buffer.As<void*>(), NULL);\n    dispatch0.Submit(queue);\n    dispatch0.Sync();\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(GwsAtomicIncreaseIsa, isaBuffer.As<char*>()),gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer.As<void*>(), NULL);\n    dispatch.SetDim(1024, 16, 16);\n\n    dispatch.Submit(queue);\n    dispatch.Sync();\n\n    EXPECT_EQ_GPU(1024*16*16+1, *buffer.As<uint32_t *>(), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(),gpuNode);\n\n}\n\nTEST_F(KFDGWSTest, Semaphore) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(Semaphore));\n\n    TEST_END\n}\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDGWSTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_GWS_TEST__H__\n#define __KFD_GWS_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDGWSTest : public KFDBaseComponentTest {\n public:\n    KFDGWSTest() {}\n    ~KFDGWSTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_GWS_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDGraphicsInterop.cpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDGraphicsInterop.hpp\"\n\n#include \"Dispatch.hpp\"\n#include \"PM4Queue.hpp\"\n\nstatic void RegisterGraphicsHandle(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDGraphicsInterop* pKFDGraphicsInterop = (KFDGraphicsInterop*)pTestParamters->pTestObject;\n\n    HsaNodeInfo* m_NodeInfo = pKFDGraphicsInterop->Get_NodeInfo();\n    const HsaNodeProperties *pNodeProps = m_NodeInfo->GetNodeProperties(gpuNode);\n    const HSAuint32 familyID = FamilyIdFromNode(pNodeProps);\n\n    if (isTonga(pNodeProps)) {\n        LOG() << \"Skipping test: Tonga workaround in thunk returns incorrect allocation size.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 nodes[1] = {(uint32_t)gpuNode};\n\n    const char metadata[] = \"This data is really meta.\";\n    unsigned metadata_size = strlen(metadata)+1;\n    int rn = pKFDGraphicsInterop->FindDRMRenderNode(gpuNode);\n\n    if (rn < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU node.\" << std::endl;\n        return;\n    }\n\n    // Create the buffer with metadata and get a dmabuf handle to it\n    struct amdgpu_bo_alloc_request alloc;\n    amdgpu_bo_handle handle;\n    if (familyID == FAMILY_CZ || isTonga(pNodeProps))\n        alloc.alloc_size = PAGE_SIZE * 8;\n    else\n        alloc.alloc_size = PAGE_SIZE;\n    alloc.phys_alignment = PAGE_SIZE;\n    alloc.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;\n    alloc.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;\n    ASSERT_EQ_GPU(0, amdgpu_bo_alloc(pKFDGraphicsInterop->m_RenderNodes[rn].device_handle, &alloc, &handle), gpuNode);\n\n    void *pCpuMap;\n    ASSERT_EQ_GPU(0, amdgpu_bo_cpu_map(handle, &pCpuMap), gpuNode);\n    memset(pCpuMap, 0xaa, PAGE_SIZE);\n    EXPECT_EQ_GPU(0, amdgpu_bo_cpu_unmap(handle), gpuNode);\n\n    struct amdgpu_bo_metadata meta;\n    meta.flags = 0;\n    meta.tiling_info = 0;\n    meta.size_metadata = metadata_size;\n    memcpy(meta.umd_metadata, metadata, metadata_size);\n    EXPECT_EQ_GPU(0, amdgpu_bo_set_metadata(handle, &meta), gpuNode);\n\n    uint32_t dmabufFd;\n    EXPECT_EQ_GPU(0, amdgpu_bo_export(handle, amdgpu_bo_handle_type_dma_buf_fd, &dmabufFd), gpuNode);\n\n    // Register it with HSA\n    HsaGraphicsResourceInfo info;\n    ASSERT_SUCCESS_GPU(hsaKmtRegisterGraphicsHandleToNodes(dmabufFd, &info,\n                                                       1, nodes), gpuNode);\n\n    /* DMA buffer handle and GEM handle are no longer needed, KFD\n     * should have taken a reference to the BO\n     */\n    EXPECT_EQ_GPU(0, close(dmabufFd), gpuNode);\n    EXPECT_EQ_GPU(0, amdgpu_bo_free(handle), gpuNode);\n\n    // Check that buffer size and metadata match\n    EXPECT_EQ_GPU(info.SizeInBytes, alloc.alloc_size, gpuNode);\n    EXPECT_EQ_GPU(info.MetadataSizeInBytes, metadata_size, gpuNode);\n    EXPECT_EQ_GPU(0, strcmp(metadata, (const char *)info.Metadata), gpuNode);\n\n    // Map the buffer\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(info.MemoryAddress,\n                                        info.SizeInBytes,\n                                        NULL), gpuNode);\n\n    // Copy contents to a system memory buffer for comparison\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDGraphicsInterop->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()));\n\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, gpuNode, true/*zero*/);\n\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    Dispatch dispatch(isaBuffer);\n\n    dispatch.SetArgs(info.MemoryAddress, dstBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    EXPECT_EQ_GPU(dstBuffer.As<unsigned int *>()[0], 0xaaaaaaaa, gpuNode);\n\n    // Test QueryMem before the cleanup\n    HsaPointerInfo ptrInfo;\n    EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo((const void *)info.MemoryAddress, &ptrInfo), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_REGISTERED_GRAPHICS, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.Node, (HSAuint32)gpuNode, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.GPUAddress, (HSAuint64)info.MemoryAddress, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.SizeInBytes, alloc.alloc_size, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.MemFlags.ui32.CoarseGrain, 1, gpuNode);\n\n    // Cleanup\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(info.MemoryAddress), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtDeregisterMemory(info.MemoryAddress), gpuNode);\n\n}\nTEST_F(KFDGraphicsInterop, RegisterGraphicsHandle) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(RegisterGraphicsHandle));\n\n    TEST_END\n}\n\n#if 0\n/* This test isn't testing things the way we wanted it to. It is flaky and\n * will end up failing if the memory is evicted, which isn't possible for what \n * it is intended to test. It needs a rework\n */\n\n/* Third-party device memory can be registered for GPU access in\n * ROCm stack. Test this feature. Third party device is mimicked\n * in multi-GPU system using Graphics stack (libdrm). CPU accessible\n * device memory is allocated using Graphics stack on gpuNode2 and\n * this memory will be registered on gpuNode1 for GPU access.\n */\nTEST_F(KFDGraphicsInterop, RegisterForeignDeviceMem) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Only supported on multi-dGPU system.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n\n    /* gpuNode2 must have public memory (large bar) to allocate CPU accessible\n     * device memory.\n     */\n    HSAint32 gpuNode1 = m_NodeInfo.HsaDefaultGPUNode(), gpuNode2 = 0;\n    const HsaNodeProperties *pNodeProperties;\n\n    gpuNode2 = m_NodeInfo.FindLargeBarGPUNode();\n    if (gpuNode2 < 0) {\n        LOG() << \"Skipping test: At least one large bar GPU is required.\" << std::endl;\n        return;\n    }\n    if (gpuNode1 == gpuNode2) {\n        for (unsigned i = 0; i < gpuNodes.size(); i++) {\n            if (gpuNodes.at(i) != gpuNode2) {\n                gpuNode1 = gpuNodes.at(i);\n                break;\n            }\n        }\n    }\n\n    const HsaNodeProperties *pNodeProps =\n        m_NodeInfo.GetNodeProperties(gpuNode2);\n    const HSAuint32 familyID = FamilyIdFromNode(pNodeProps);\n\n    int rn = FindDRMRenderNode(gpuNode2);\n    if (rn < 0) {\n        LOG() << \"Skipping test: Cound not find render node for 2nd GPU.\" << std::endl;\n        return;\n    }\n\n    // Allocate CPU accessible device memory on gpuNode2\n    struct amdgpu_bo_alloc_request alloc;\n    amdgpu_bo_handle handle;\n    if (familyID == FAMILY_CZ || isTonga(pNodeProps))\n        alloc.alloc_size = PAGE_SIZE * 8;\n    else\n        alloc.alloc_size = PAGE_SIZE;\n    alloc.phys_alignment = PAGE_SIZE;\n    alloc.preferred_heap = AMDGPU_GEM_DOMAIN_VRAM;\n    alloc.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;\n    ASSERT_EQ(0, amdgpu_bo_alloc(m_RenderNodes[rn].device_handle, &alloc, &handle));\n\n    void *pCpuMap;\n    ASSERT_EQ(0, amdgpu_bo_cpu_map(handle, &pCpuMap));\n    memset(pCpuMap, 0xAA, PAGE_SIZE);\n\n    /* Register third-party device memory in KFD. Test GPU access\n     * by carrying out a simple copy test\n     */\n    HsaMemoryBuffer lockDeviceMemory(pCpuMap, PAGE_SIZE);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode1, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, gpuNode1, true/*zero*/);\n    PM4Queue queue;\n    Dispatch dispatch(isaBuffer);\n\n    m_pIsaGen->GetCopyDwordIsa(isaBuffer);\n    ASSERT_SUCCESS(queue.Create(gpuNode1));\n\n    dispatch.SetArgs(lockDeviceMemory.As<void*>(), dstBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS(queue.Destroy());\n    EXPECT_EQ(dstBuffer.As<HSAuint32*>()[0], 0xAAAAAAAA);\n\n    EXPECT_EQ(0, amdgpu_bo_cpu_unmap(handle));\n    EXPECT_EQ(0, amdgpu_bo_free(handle));\n\n    TEST_END\n}\n#endif\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDGraphicsInterop.hpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDMemoryTest.hpp\"\n\n#ifndef __KFD_GRAPHICS_INTEROP_TEST__H__\n#define __KFD_GRAPHICS_INTEROP_TEST__H__\n\n// @class KFDGraphicsInteropTest\n// Adds access to graphics device for interoperability testing\nclass KFDGraphicsInterop :  public KFDMemoryTest {\n public:\n    KFDGraphicsInterop(void) {}\n    ~KFDGraphicsInterop(void) {}\n};\n\n#endif\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDHWSTest.cpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDHWSTest.hpp\"\n\nvoid KFDHWSTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDHWSTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nvoid KFDHWSTest::RunTest_GPU(int gpuNode, unsigned nProcesses, unsigned nQueues, unsigned nLoops) {\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(gpuNode);\n\n    unsigned q, l;\n    bool timeout = false;\n\n    /* Fork the child processes for gpuNode */\n    ForkChildProcesses(gpuNode, nProcesses);\n\n    // Create queues\n    PM4Queue *queues = new PM4Queue[nQueues];\n    for (q = 0; q < nQueues; q++)\n        ASSERT_SUCCESS_GPU(queues[q].Create(gpuNode), gpuNode);\n\n    // Create dispatch pointers. Each loop iteration creates fresh dispatches\n    Dispatch **dispatch = new Dispatch*[nQueues];\n    for (q = 0; q < nQueues; q++)\n        dispatch[q] = NULL;\n\n    // Logging: Each process prints its index after each loop iteration, all in one line.\n    std::ostream &log = LOG() << std::dec << \"gpuNode: \" << gpuNode << \" Process: \" << m_ProcessIndex[gpuIndex] << \" starting.\" << std::endl;\n\n    // Run work on all queues\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    Assembler* m_pAsm;\n    m_pAsm = GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(NoopIsa, isaBuffer.As<char*>()));\n\n    for (l = 0; l < nLoops; l++) {\n        for (q = 0; q < nQueues; q++) {\n            if (dispatch[q])\n                delete dispatch[q];\n            dispatch[q] = new Dispatch(isaBuffer);\n            dispatch[q]->SetArgs(NULL, NULL);\n            dispatch[q]->SetDim(1, 1, 1);\n            dispatch[q]->Submit(queues[q]);\n        }\n        for (q = 0; q < nQueues; q++) {\n            timeout = dispatch[q]->SyncWithStatus(g_TestTimeOut);\n            if (timeout)\n                goto timeout;\n        }\n        log << m_ProcessIndex[gpuIndex];\n    }\n\ntimeout:\n    log << std::endl;\n    if (timeout) {\n        WARN() << \"gpuNode: \" << gpuNode << \" Process: \" <<  m_ProcessIndex[gpuIndex] << \" timeout.\" << std::endl;\n    } else {\n        LOG() << \"gpuNode: \" << gpuNode << \" Process \" << m_ProcessIndex[gpuIndex] << \" done. Waiting ...\" << std::endl;\n\n        // Wait here before destroying queues. If another process' queues\n        // are soft-hanging, destroying queues can resolve the soft-hang\n        // by changing the run list. Make sure the other process's\n        // dispatches have a chance to time out first.\n        Delay(g_TestTimeOut+1000);\n    }\n\n    // Destroy queues and dispatches. Destroying the queues first\n    // ensures that the memory allocated by the Dispatch is no longer\n    // accessed by the GPU.\n    LOG() << \"gpuNode: \" << gpuNode << \" Process \" << m_ProcessIndex[gpuIndex] << \" cleaning up.\" << std::endl;\n    for (q = 0; q < nQueues; q++) {\n        EXPECT_SUCCESS_GPU(queues[q].Destroy(), gpuNode);\n        if (dispatch[q])\n            delete dispatch[q];\n    }\n    delete[] queues;\n    delete[] dispatch;\n\n    // This is after all the cleanup to avoid leaving any garbage\n    // behind, but before WaitChildProcesses to ensure a child process\n    // with a timeout exits with an error that can be detected by the\n    // parent.\n    ASSERT_FALSE(timeout);\n\n    WaitChildProcesses(gpuNode);\n\n}\n\nvoid RunTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDHWSTest* pKKFDHWSTest = (KFDHWSTest*)pTestParamters->pTestObject;\n\n    pKKFDHWSTest->RunTest_GPU(gpuNode, 3, 13, 40);\n}\n\nTEST_F(KFDHWSTest, MultiProcessOversubscribed) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(RunTest));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDHWSTest.hpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_HWS_TEST__H__\n#define __KFD_HWS_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"PM4Queue.hpp\"\n#include \"KFDMultiProcessTest.hpp\"\n#include \"Dispatch.hpp\"\n\nclass KFDHWSTest : public KFDMultiProcessTest {\n public:\n    KFDHWSTest() {}\n    ~KFDHWSTest() {}\n\n    friend void RunTest(KFDTEST_PARAMETERS* pTestParamters);\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n    void RunTest_GPU(int gpuNode, unsigned nProcesses, unsigned nQueues, unsigned nLoops);\n\n};\n\n#endif  // __KFD_QCM_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDIPCTest.cpp",
    "content": "/*\n * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDIPCTest.hpp\"\n#include <sys/types.h>\n#include <sys/mman.h>\n#include <sys/stat.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <vector>\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"SDMAPacket.hpp\"\n\nvoid KFDIPCTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDIPCTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nKFDIPCTest::~KFDIPCTest(void) {\n    /* exit() is necessary for the child process. Otherwise when the\n     * child process finishes, gtest assumes the test has finished and\n     * starts the next test while the parent is still active.\n     */\n    if (m_ChildPid == 0)\n        exit(::testing::UnitTest::GetInstance()->current_test_info()->result()->Failed());\n}\n\n/* Import shared Local Memory from parent process. Check for the pattern\n * filled in by the parent process. Then fill a new pattern.\n *\n * Check import handle has same HsaMemFlags as export handle to verify thunk and KFD\n * import export handle ioctl pass HsaMemFlags correctly.\n */\nvoid KFDIPCTest::BasicTestChildProcess(int defaultGPUNode, int *pipefd, HsaMemFlags mflags) {\n    /* Open KFD device for child process. This needs to called before\n     * any memory definitions\n     */\n    TearDown();\n    SetUp();\n\n    SDMAQueue sdmaQueue;\n    HsaSharedMemoryHandle sharedHandleLM;\n    HSAuint64 size = PAGE_SIZE, sharedSize;\n    HsaMemoryBuffer tempSysBuffer(size, defaultGPUNode, false);\n    HSAuint32 *sharedLocalBuffer = NULL;\n    HsaMemMapFlags mapFlags = {0};\n\n    /* Read from Pipe the shared Handle. Import shared Local Memory */\n    ASSERT_GE(read(pipefd[0], reinterpret_cast<void*>(&sharedHandleLM), sizeof(sharedHandleLM)), 0);\n\n    ASSERT_SUCCESS(hsaKmtRegisterSharedHandle(&sharedHandleLM,\n                  reinterpret_cast<void**>(&sharedLocalBuffer), &sharedSize));\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPUNodes(sharedLocalBuffer, sharedSize, NULL,\n                  mapFlags, 1, reinterpret_cast<HSAuint32 *>(&defaultGPUNode)));\n\n    /* Check for pattern in the shared Local Memory */\n    ASSERT_SUCCESS(sdmaQueue.Create(defaultGPUNode));\n    size = size < sharedSize ? size : sharedSize;\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(), tempSysBuffer.As<HSAuint32*>(),\n        sharedLocalBuffer, size));\n    sdmaQueue.Wait4PacketConsumption();\n    EXPECT_TRUE(WaitOnValue(tempSysBuffer.As<HSAuint32*>(), 0xAAAAAAAA));\n\n    /* Fill in the Local Memory with different pattern */\n    sdmaQueue.PlaceAndSubmitPacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(), sharedLocalBuffer, 0xBBBBBBBB));\n    sdmaQueue.Wait4PacketConsumption();\n\n    HsaPointerInfo ptrInfo;\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(sharedLocalBuffer, &ptrInfo));\n    EXPECT_EQ(ptrInfo.Type, HSA_POINTER_REGISTERED_SHARED);\n    EXPECT_EQ(ptrInfo.Node, (HSAuint32)defaultGPUNode);\n    EXPECT_EQ(ptrInfo.GPUAddress, (HSAuint64)sharedLocalBuffer);\n    EXPECT_EQ(ptrInfo.SizeInBytes, sharedSize);\n    EXPECT_EQ(ptrInfo.MemFlags.Value, mflags.Value);\n\n    /* Clean up */\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(sharedLocalBuffer));\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(sharedLocalBuffer));\n}\n\n/* Fill a pattern into Local Memory and share with the child process.\n * Then wait until Child process to exit and check for the new pattern\n * filled in by the child process.\n */\n\nvoid KFDIPCTest::BasicTestParentProcess(int defaultGPUNode, pid_t cpid, int *pipefd, HsaMemFlags mflags) {\n    HSAuint64 size = PAGE_SIZE, sharedSize;\n    int status;\n    HSAuint64 AlternateVAGPU;\n    void *toShareLocalBuffer;\n    HsaMemoryBuffer tempSysBuffer(PAGE_SIZE, defaultGPUNode, false);\n    SDMAQueue sdmaQueue;\n    HsaSharedMemoryHandle sharedHandleLM;\n    HsaMemMapFlags mapFlags = {0};\n\n    ASSERT_SUCCESS(hsaKmtAllocMemory(defaultGPUNode, size, mflags, &toShareLocalBuffer));\n    /* Fill a Local Buffer with a pattern */\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPUNodes(toShareLocalBuffer, size, &AlternateVAGPU,\n                       mapFlags, 1, reinterpret_cast<HSAuint32 *>(&defaultGPUNode)));\n    tempSysBuffer.Fill(0xAAAAAAAA);\n\n    /* Copy pattern in Local Memory before sharing it */\n    ASSERT_SUCCESS(sdmaQueue.Create(defaultGPUNode));\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(), toShareLocalBuffer,\n        tempSysBuffer.As<HSAuint32*>(), size));\n    sdmaQueue.Wait4PacketConsumption();\n\n    /* Share it with the child process */\n    ASSERT_SUCCESS(hsaKmtShareMemory(toShareLocalBuffer, size, &sharedHandleLM));\n\n    ASSERT_GE(write(pipefd[1], reinterpret_cast<void*>(&sharedHandleLM), sizeof(sharedHandleLM)), 0);\n\n    /* Wait for the child to finish */\n    waitpid(cpid, &status, 0);\n\n    EXPECT_EQ(WIFEXITED(status), 1);\n    EXPECT_EQ(WEXITSTATUS(status), 0);\n\n    /* Check for the new pattern filled in by child process */\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(), tempSysBuffer.As<HSAuint32*>(),\n        toShareLocalBuffer, size));\n    sdmaQueue.Wait4PacketConsumption();\n    EXPECT_TRUE(WaitOnValue(tempSysBuffer.As<HSAuint32*>(), 0xBBBBBBBB));\n\n    /* Clean up */\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(toShareLocalBuffer));\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\n}\n\n/* Test IPC memory.\n * 1. Parent Process [Create/Fill] LocalMemory (LM) --share--> Child Process\n * 2. Child Process import LM and check for the pattern.\n * 3. Child Process fill in a new pattern and quit.\n * 4. Parent Process wait for the Child process to finish and then check for\n * the new pattern in LM\n *\n * IPC support is limited to Local Memory.\n */\n\nTEST_F(KFDIPCTest, BasicTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    const std::vector<int>& GpuNodes = m_NodeInfo.GetNodesWithGPU();\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    int pipefd[2];\n    HsaMemFlags mflags = {0};\n\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (!GetVramSize(defaultGPUNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    /* Test libhsakmt fork() clean up by defining some buffers. These\n     * buffers gets duplicated in the child process but not are not valid\n     * as it doesn't have proper mapping in GPU. The clean up code in libhsakmt\n     * should handle it\n     */\n    volatile HSAuint32 stackData[1];\n    HsaMemoryBuffer tmpSysBuffer(PAGE_SIZE, defaultGPUNode, false);\n    HsaMemoryBuffer tmpUserptrBuffer((void *)&stackData[0], sizeof(HSAuint32));\n\n    /* Create Pipes for communicating shared handles */\n    ASSERT_EQ(pipe(pipefd), 0);\n\n    /* Create a child process and share the above Local Memory with it */\n    mflags.ui32.NonPaged = 1;\n    mflags.ui32.CoarseGrain = 1;\n\n    m_ChildPid = fork();\n    if (m_ChildPid == 0)\n        BasicTestChildProcess(defaultGPUNode, pipefd, mflags); /* Child Process */\n    else\n        BasicTestParentProcess(defaultGPUNode, m_ChildPid, pipefd, mflags); /* Parent proces */\n\n    /* Code path executed by both parent and child with respective fds */\n    close(pipefd[1]);\n    close(pipefd[0]);\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDIPCTest.hpp",
    "content": "/*\n * Copyright (C) 2017-2018 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDBaseComponentTest.hpp\"\n#include \"BaseQueue.hpp\"\n\n#ifndef __KFD_MEMORY_TEST__H__\n#define __KFD_MEMORY_TEST__H__\n\n#define CMA_MEMORY_TEST_ARRAY_SIZE 4\n#define CMA_TEST_COUNT 3\n\nenum CMA_MEM_TYPE {\n    CMA_MEM_TYPE_SYSTEM = 0,\n    CMA_MEM_TYPE_USERPTR,\n    CMA_MEM_TYPE_LOCAL_MEM,\n};\n\nenum CMA_TEST_TYPE {\n    CMA_READ_TEST = 0,\n    CMA_WRITE_TEST\n};\n\nenum CMA_TEST_STATUS {\n    CMA_TEST_SUCCESS = 0,\n    CMA_IPC_PIPE_ERROR = 1,\n    CMA_CHECK_PATTERN_ERROR,\n    CMA_TEST_ABORT,\n    CMA_TEST_NOMEM,\n    CMA_PARENT_FAIL,\n    CMA_TEST_HSA_READ_FAIL,\n    CMA_TEST_HSA_WRITE_FAIL\n};\n\n/* @struct testMemoryDescriptor\n * @brief Describes test buffers for Cross Memory Attach Test.\n */\nstruct testMemoryDescriptor {\n    CMA_MEM_TYPE m_MemType;\n    HSAuint64 m_MemSize;\n    /* The buffer will be initialized with this pattern */\n    HSAuint32 m_FillPattern;\n    /* After CMA test, this pattern is expected in the first word */\n    HSAuint32 m_CheckFirstWordPattern;\n    /* After CMA test, this pattern is expected in the last word */\n    HSAuint32 m_CheckLastWordPattern;\n\n    testMemoryDescriptor(CMA_MEM_TYPE memType, HSAuint64 memSize,\n        HSAuint32 fillPattern, HSAuint32 firstCheckPattern,\n        HSAuint32 lastCheckPattern) :\n        m_MemType(memType),\n        m_MemSize(memSize),\n        m_FillPattern(fillPattern),\n        m_CheckFirstWordPattern(firstCheckPattern),\n        m_CheckLastWordPattern(lastCheckPattern) {}\n    ~testMemoryDescriptor(){}\n};\n\n/* @class KFDCMAArray\n * @brief Array of buffers that will be passed between the parent and child\n *        process for Cross memory read and write tests\n */\nclass KFDCMAArray {\n    /* Used to store the actual buffer array */\n    HsaMemoryBuffer* m_MemArray[CMA_MEMORY_TEST_ARRAY_SIZE];\n    /* Used for passing to thunk CMA functions */\n    HsaMemoryRange m_HsaMemoryRange[CMA_MEMORY_TEST_ARRAY_SIZE];\n    /* Though previous arrays are fixed sizes only m_ValidCount\n     * ones are valid\n     */\n    HSAuint64 m_ValidCount;\n    QueueArray m_QueueArray;\n\n public:\n    KFDCMAArray();\n    ~KFDCMAArray() {\n        Destroy();\n    }\n\n    CMA_TEST_STATUS Init(testMemoryDescriptor(*memDescriptor)[CMA_MEMORY_TEST_ARRAY_SIZE], int node);\n    CMA_TEST_STATUS Destroy();\n\n    HsaMemoryRange*  getMemoryRange() { return m_HsaMemoryRange; }\n    HSAuint64 getValidRangeCount() { return m_ValidCount; }\n    void FillPattern(testMemoryDescriptor(*memDescriptor)[CMA_MEMORY_TEST_ARRAY_SIZE]);\n    CMA_TEST_STATUS checkPattern(testMemoryDescriptor(*memDescriptor)[CMA_MEMORY_TEST_ARRAY_SIZE]);\n    CMA_TEST_STATUS sendCMAArray(int writePipe);\n    CMA_TEST_STATUS recvCMAArray(int readPipe);\n};\n\n\n// @class KFDIPCTest\nclass KFDIPCTest :  public KFDBaseComponentTest {\n public:\n    KFDIPCTest(void) : m_ChildPid(-1) {}\n    ~KFDIPCTest(void);\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n    /* For IPC testing */\n    void BasicTestChildProcess(int defaultGPUNode, int *pipefd, HsaMemFlags mflags);\n    void BasicTestParentProcess(int defaultGPUNode, pid_t childPid, int *pipefd, HsaMemFlags mflags);\n\n    /* For CMA testing */\n    CMA_TEST_STATUS CrossMemoryAttachChildProcess(int defaultGPUNode, int writePipe,\n                                                  int readPipe, CMA_TEST_TYPE testType);\n    CMA_TEST_STATUS CrossMemoryAttachParentProcess(int defaultGPUNode, pid_t cid,\n                                                   int writePipe, int readPipe, CMA_TEST_TYPE testType);\n protected:\n    pid_t m_ChildPid;\n};\n\n#endif  // __KFD_MEMORY_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDLocalMemoryTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDLocalMemoryTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n\nvoid KFDLocalMemoryTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDLocalMemoryTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic void AccessLocalMem(KFDTEST_PARAMETERS* pTestParamters) {\n\n    /* Skip test if not on dGPU path, which the test depends on */\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Not dGPU path, skipping the test\" << std::endl;\n        return;\n    }\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    //local memory\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false, true);\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0, 0));\n\n    queue.Wait4PacketConsumption(event);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDLocalMemoryTest, AccessLocalMem) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AccessLocalMem));\n\n    TEST_END\n}\n\nstatic void BasicTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    PM4Queue queue;\n    HSAuint64 AlternateVAGPU;\n    unsigned int BufferSize = PAGE_SIZE;\n    HsaMemMapFlags mapFlags = {0};\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDLocalMemoryTest* pKFDLocalMemoryTest = (KFDLocalMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDLocalMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcSysBuffer(BufferSize, gpuNode, false);\n    HsaMemoryBuffer destSysBuffer(BufferSize, gpuNode);\n    HsaMemoryBuffer srcLocalBuffer(BufferSize, gpuNode, false, true);\n    HsaMemoryBuffer dstLocalBuffer(BufferSize, gpuNode, false, true);\n\n    srcSysBuffer.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(srcLocalBuffer.As<void*>(), srcLocalBuffer.Size(), &AlternateVAGPU,\n                       mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(dstLocalBuffer.As<void*>(), dstLocalBuffer.Size(), &AlternateVAGPU,\n                       mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    queue.SetSkipWaitConsump(0);\n\n    Dispatch dispatch(isaBuffer);\n\n    dispatch.SetArgs(srcSysBuffer.As<void*>(), srcLocalBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    dispatch.SetArgs(srcLocalBuffer.As<void*>(), dstLocalBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    dispatch.SetArgs(dstLocalBuffer.As<void*>(), destSysBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    ASSERT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(srcLocalBuffer.As<void*>()), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(dstLocalBuffer.As<void*>()), gpuNode);\n    EXPECT_EQ_GPU(destSysBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n\n}\n\nTEST_F(KFDLocalMemoryTest, BasicTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicTest));\n\n    TEST_END\n}\n\nstatic void VerifyContentsAfterUnmapAndMap(KFDTEST_PARAMETERS* pTestParamters)\n{\n    PM4Queue queue;\n    HSAuint64 AlternateVAGPU;\n    unsigned int BufferSize = PAGE_SIZE;\n    HsaMemMapFlags mapFlags = {0};\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDLocalMemoryTest* pKFDLocalMemoryTest = (KFDLocalMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDLocalMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer SysBufferA(BufferSize, gpuNode, false);\n    HsaMemoryBuffer SysBufferB(BufferSize, gpuNode, true);\n    HsaMemoryBuffer LocalBuffer(BufferSize, gpuNode, false, true);\n\n    SysBufferA.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    queue.SetSkipWaitConsump(0);\n\n    if (!hsakmt_is_dgpu())\n        ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(LocalBuffer.As<void*>(), LocalBuffer.Size(), &AlternateVAGPU,\n                           mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n\n    dispatch.SetArgs(SysBufferA.As<void*>(), LocalBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(LocalBuffer.As<void*>()), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(LocalBuffer.As<void*>(), LocalBuffer.Size(), &AlternateVAGPU,\n                       mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)), gpuNode);\n\n    dispatch.SetArgs(LocalBuffer.As<void*>(), SysBufferB.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    EXPECT_EQ_GPU(SysBufferB.As<unsigned int*>()[0], 0x01010101, gpuNode);\n    if (!hsakmt_is_dgpu())\n        EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(LocalBuffer.As<void*>()), gpuNode);\n}\n\nTEST_F(KFDLocalMemoryTest, VerifyContentsAfterUnmapAndMap) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(VerifyContentsAfterUnmapAndMap));\n\n    TEST_END\n}\n\n/* Deliberately fragment GPUVM aperture to fill up address space\n *\n * General idea: Allocate buffers, but don't map them to GPU. This\n * will reserve virtual address space without pinning physical\n * memory. It should allow using more address space than physically\n * available memory.\n *\n * Even without pinning memory, TTM will still commit memory at\n * allocation time and swap out movable buffers to system memory or\n * even the hard drive, if it needs to. So we can't allocate arbitrary\n * amounts of virtual memory.\n *\n * Strategy to maximize the amount of allocated, fragmented address\n * space while keeping the amount of committed memory bounded at all\n * times:\n *\n * 1. Allocate N blocks of a given size, initially 1 page\n * 2. Free every other block, creating holes in the address space.\n *    This frees up half the memory\n * 3. Allocate N/4 blocks of 2-pages each. This requires as much\n *    memory as was freed in step 2. The block size is bigger than\n *    the 1-page holes, so new address space will be used.\n * 4. Free half the blocks just allocated, and half of the\n *    remaining blocks of step 1. This creates 3-page holes between\n *    the 1-page blocks from step 1, and 2-page holes between the\n *    2-page blocks from step 3. It frees up half of the total\n *    memory.\n * 5. Double the block size to 4, devide number of blocks by 2.\n *    Again, this will require the amount of memory freed in step 4.\n *    The block size 4 is bigger than the biggest hole (3 pages).\n * 6. Free half the memory again, creating 7-page holes between\n *    1-page blocks, 6-page holes between 2-page blocks, and 4-page\n *    holes between 4-page blocks.\n *\n * Repeat, doubling block size and halving number of blocks in each\n * iteration. Each iteration starts and ends with half the total\n * memory free. Because the block size is always bigger than the\n * biggest hole, each iteration increases the amount of address space\n * occupied by half the total memory size. Once the block size reaches\n * half of the free memory (1/4 of total memory) the limit is reached.\n *\n * With 2^n pages available memory, n * 2^(n-1) pages of address space\n * can be reserved. At the end of that process, half the memory will\n * be free.\n *\n *     Total memory     | Fragmented address space\n * order | pages | size | pages |  size | ratio\n * ------+-------+------+-------+-------+-------\n *     2 |    4  |  16K |    4  |   16K |   1\n *     3 |    8  |  32K |   12  |   48K |   1.5\n *     4 |   16  |  64K |   32  |  128K |   2\n *     5 |   32  | 128K |   80  |  320K |   2.5\n *     6 |   64  | 256K |  192  |  768K |   3\n *     7 |  128  | 512K |  448  | 1.75M |   3.5\n *     8 |  256  |   1M |    1M |    4M |   4\n *     9 |  512  |   2M | 2.25M |    9M |   4.5\n *    10 |    1K |   4M |    5M |   20M |   5\n *    11 |    2K |   8M |   11M |   44M |   5.5\n *    12 |    4K |  16M |   24M |   96M |   6\n *    13 |    8K |  32M |   52M |  208M |   6.5\n *    14 |   16K |  64M |  112M |  448M |   7\n *    15 |   32K | 128M |  240M |  960M |   7.5\n *    16 |   64K | 256M |  512M |    2G |   8\n *    17 |  128K | 512M | 1088M | 4.25G |   8.5\n *    18 |  256K |   1G | 2.25G |    9G |   9\n *    19 |  512K |   2G | 4.75G |   19G |   9.5\n *    20 |    1M |   4G |   10G |   40G |  10\n */\n\nstatic void Fragmentation(KFDTEST_PARAMETERS* pTestParamters){\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDLocalMemoryTest* pKFDLocalMemoryTest = (KFDLocalMemoryTest*)pTestParamters->pTestObject;\n\n    HSAuint64 fbSize;\n\n    fbSize = pKFDLocalMemoryTest->GetVramSize(gpuNode);\n\n    if (!fbSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    } else {\n        LOG() << \"Found VRAM of \" << std::dec << (fbSize >> 20) << \"MB.\" << std::endl;\n    }\n\n    /* Use up to half of available memory. Using more results in\n     * excessive memory movement in TTM and slows down the test too\n     * much. maxOrder is the size of the biggest block that will be\n     * allocated. It's 1/4 of the usable memory, so 1/8 the total FB\n     * size in pages.\n     *\n     * Use 8x bigger page size on dGPU to match Tonga alignment\n     * workaround. Also nicely matches the 8x bigger GPUVM address\n     * space on AMDGPU compared to RADEON.\n     */\n    unsigned pageSize = hsakmt_is_dgpu() ? PAGE_SIZE*8 : PAGE_SIZE;\n    fbSize /= pageSize;\n    unsigned maxOrder = 0;\n    // Limit maxOrder up to 14 so this test doesn't run longer than 10 mins\n    while (((fbSize >> maxOrder) >= 16) && (maxOrder < 14))\n        maxOrder++;\n\n    /* Queue and memory used by the shader copy tests */\n    HsaMemoryBuffer sysBuffer(PAGE_SIZE, gpuNode, false);\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    /* instantiate Assembler for gpuNode */\n    HsaNodeInfo* m_NodeInfo = pKFDLocalMemoryTest->Get_NodeInfo();\n    const HsaNodeProperties *nodeProperties = m_NodeInfo->GetNodeProperties(gpuNode);\n    Assembler* m_pAsm = new Assembler(GetGfxVersion(nodeProperties));\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n   /* not need assember now */\n    if (m_pAsm)\n        delete m_pAsm;\n\n    /* Allocate and test memory using the strategy explained at the top */\n    HSAKMT_STATUS status;\n    HsaMemFlags memFlags = {0};\n    HsaMemMapFlags mapFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 0;\n    memFlags.ui32.NonPaged = 1;\n    struct {\n        void **pointers;\n        unsigned long nPages;\n    } pages[maxOrder+1];\n    unsigned order, o;\n    unsigned long p;\n    HSAuint64 size;\n    unsigned value = 0;\n    memset(pages, 0, sizeof(pages));\n    for (order = 0; order <= maxOrder; order++) {\n        // At maxOrder, block size is 1/4 of available memory\n        pages[order].nPages = 1UL << (maxOrder - order + 2);\n        // At order != 0, 1/2 the memory is already allocated\n        if (order > 0)\n            pages[order].nPages >>= 1;\n        // Allocate page pointers\n        pages[order].pointers = new void *[pages[order].nPages];\n        EXPECT_NE_GPU((void **)NULL, pages[order].pointers, gpuNode)\n            << \"Couldn't allocate memory for \" << pages[order].nPages\n            << \" pointers at order \" << order << std::endl;\n        if (!pages[order].pointers) {\n            pages[order].nPages = 0;\n            break;\n        }\n        /* Allocate buffers and access the start and end of every one:\n         * 1. Copy from sysBuffer[0] to start of block\n         * 2. Copy from start of block to end of block\n         * 3. Copy from end of block to sysBuffer[1]\n         * 4. Compare results */\n        size = (HSAuint64)(1 << order) * pageSize;\n        LOG() << std::dec << \"Trying to allocate \" << pages[order].nPages\n              << \" order \" << order << \" blocks \" << std::endl;\n        for (p = 0; p < pages[order].nPages; p++) {\n            status = hsaKmtAllocMemory(gpuNode, size,\n                                       memFlags, &pages[order].pointers[p]);\n            if (status != HSAKMT_STATUS_SUCCESS) {\n                EXPECT_EQ_GPU(HSAKMT_STATUS_NO_MEMORY, status, gpuNode);\n                pages[order].nPages = p;\n                break;\n            }\n\n            void *bufferEnd = reinterpret_cast<void *>(reinterpret_cast<unsigned long>(pages[order].pointers[p])\n                                       + size - sizeof(unsigned));\n            sysBuffer.As<unsigned *>()[0] = ++value;\n\n            status = hsaKmtMapMemoryToGPUNodes(pages[order].pointers[p], size, NULL,\n                               mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode));\n            if (status != HSAKMT_STATUS_SUCCESS) {\n                ASSERT_SUCCESS_GPU(hsaKmtFreeMemory(pages[order].pointers[p],\n                                                size), gpuNode);\n                pages[order].nPages = p;\n                break;\n            }\n            Dispatch dispatch1(isaBuffer);\n            dispatch1.SetArgs(sysBuffer.As<void*>(), pages[order].pointers[p]);\n            dispatch1.Submit(queue);\n            // no sync needed for multiple GPU dispatches to the same queue\n\n            Dispatch dispatch2(isaBuffer);\n            dispatch2.SetArgs(pages[order].pointers[p], bufferEnd);\n            dispatch2.Submit(queue);\n            // no sync needed for multiple GPU dispatches to the same queue\n\n            Dispatch dispatch3(isaBuffer);\n            dispatch3.SetArgs(bufferEnd,\n                              reinterpret_cast<void *>(&(sysBuffer.As<unsigned*>()[1])));\n            dispatch3.Submit(queue);\n            dispatch3.Sync(g_TestTimeOut);\n            EXPECT_EQ_GPU(value, sysBuffer.As<unsigned *>()[1], gpuNode);\n\n            EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pages[order].pointers[p]), gpuNode);\n        }\n        LOG() << \"  Got \" << pages[order].nPages\n              << \", end of last block addr: \"\n              << reinterpret_cast<void *>(reinterpret_cast<unsigned long>(pages[order].pointers[p-1]) + size - 1)\n              << std::endl;\n\n        // Now free half the memory\n        for (o = 0; o <= order; o++) {\n            unsigned long step = 1UL << (order - o + 1);\n            unsigned long offset = (step >> 1) - 1;\n            size = (HSAuint64)(1 << o) * pageSize;\n            LOG() << \"  Freeing every \" << step << \"th order \"\n                  << o << \" block starting with \" << offset << std::endl;\n            for (p = offset; p < pages[o].nPages; p += step) {\n                ASSERT_NE_GPU((void **)NULL, pages[o].pointers[p], gpuNode);\n                EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pages[o].pointers[p], size), gpuNode);\n                pages[o].pointers[p] = NULL;\n            }\n        }\n    }\n\n    /* Clean up */\n    for (order = 0; order <= maxOrder; order++) {\n        if (pages[order].pointers == NULL)\n            continue;\n\n        size = (HSAuint64)(1 << order) * pageSize;\n        for (p = 0; p < pages[order].nPages; p++)\n            if (pages[order].pointers[p] != NULL)\n                EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pages[order].pointers[p], size), gpuNode);\n\n        delete[] pages[order].pointers;\n    }\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDLocalMemoryTest, DISABLED_Fragmentation) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(Fragmentation));\n\n    TEST_END\n}\n\nstatic void CheckZeroInitializationVram(KFDTEST_PARAMETERS* pTestParamters){\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDLocalMemoryTest* pKFDLocalMemoryTest = (KFDLocalMemoryTest*)pTestParamters->pTestObject;\n\n    /* Testing VRAM */\n    HSAuint64 vramSizeMB = pKFDLocalMemoryTest->GetVramSize(gpuNode) >> 20;\n\n   if (!vramSizeMB) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n   }\n\n    HSAuint64 vramBufSizeMB = vramSizeMB >> 2;\n    /* limit the buffer size in order not to overflow the SDMA queue buffer. */\n    if (vramBufSizeMB > 1024) {\n        vramBufSizeMB = 1024;\n    }\n    HSAuint64 vramBufSize = vramBufSizeMB * 1024 * 1024;\n\n    /* Make sure the entire VRAM is used at least once */\n    int count = (vramSizeMB + vramBufSizeMB - 1) / vramBufSizeMB + 1;\n\n    LOG() << \"Using \" << std::dec << vramBufSizeMB\n            << \"MB VRAM buffer to test \" << std::dec << count\n            << \" times\"<< std::endl;\n\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode, 8 * PAGE_SIZE), gpuNode);\n\n    HsaMemoryBuffer tmpBuffer(PAGE_SIZE, 0, true /* zero */);\n    volatile HSAuint32 *tmp = tmpBuffer.As<volatile HSAuint32 *>();\n\n    unsigned int offset = 2060;  // a constant offset, should be 4 aligned.\n\n    while (count--) {\n        HsaMemoryBuffer localBuffer(vramBufSize, gpuNode, false, true);\n\n        EXPECT_TRUE_GPU(localBuffer.IsPattern(0, 0, sdmaQueue, tmp), gpuNode);\n\n        for (HSAuint64 i = offset; i < vramBufSize;) {\n            EXPECT_TRUE_GPU(localBuffer.IsPattern(i, 0, sdmaQueue, tmp), gpuNode);\n            i += 4096;\n        }\n\n        /* Checking last 4 bytes */\n        EXPECT_TRUE_GPU(localBuffer.IsPattern(vramBufSize - 4, 0, sdmaQueue, tmp), gpuNode);\n\n        localBuffer.Fill(0xABCDEFFF, sdmaQueue);\n    }\n\n}\n\nTEST_F(KFDLocalMemoryTest, CheckZeroInitializationVram) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CheckZeroInitializationVram));\n\n    TEST_END\n}\n\nTEST_F(KFDLocalMemoryTest, MapVramToGPUNodesTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    HSAint32 src_node;\n    HSAint32 dst_node;\n    HsaPointerInfo info;\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: Test requires at least two GPUs.\" << std::endl;\n        return;\n    }\n\n    if (g_TestDstNodeId != -1 && g_TestNodeId != -1) {\n        src_node = g_TestNodeId;\n        dst_node = g_TestDstNodeId;\n    } else {\n        int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n        dst_node = m_NodeInfo.FindLargeBarGPUNode();\n        if (dst_node < 0) {\n            LOG() << \"Skipping test: Test requires at least one large bar GPU.\" << std::endl;\n            return;\n        }\n\n        if (dst_node != defaultGPUNode) {\n            /* At least one node should be defaultGPUNode */\n            src_node = defaultGPUNode;\n        } else {\n            for (auto node : gpuNodes) {\n                if (node != dst_node) {\n                    src_node = node;\n                    break;\n                }\n            }\n        }\n    }\n\n    if (!m_NodeInfo.IsPeerAccessibleByNode(dst_node, src_node)) {\n        LOG() << \"Skipping test: GPUs are not peer-accessible\" << std::endl;\n        return;\n    }\n\n    LOG() << \"Testing from GPU \" << src_node << \" to GPU \" << dst_node << std::endl;\n\n    void *shared_addr;\n    HSAuint32 nodes[] = { (HSAuint32)src_node, (HSAuint32)dst_node };\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 1;\n    memFlags.ui32.NonPaged = 1;\n    memFlags.ui32.ExecuteAccess = 1;\n\n    HsaMemMapFlags mapFlags = {0};\n\n    EXPECT_SUCCESS(hsaKmtAllocMemory(nodes[1], PAGE_SIZE, memFlags, &shared_addr));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(shared_addr, PAGE_SIZE, NULL, mapFlags, 2, nodes));\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(shared_addr, &info));\n    EXPECT_EQ(info.NMappedNodes, 2);\n\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(shared_addr, PAGE_SIZE, NULL, mapFlags, 1, &nodes[0]));\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(shared_addr, &info));\n    EXPECT_EQ(info.NMappedNodes, 1);\n    EXPECT_EQ(info.MappedNodes[0], nodes[0]);\n\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(shared_addr, PAGE_SIZE, NULL, mapFlags, 1, &nodes[1]));\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(shared_addr, &info));\n    EXPECT_EQ(info.NMappedNodes, 1);\n    EXPECT_EQ(info.MappedNodes[0], nodes[1]);\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(shared_addr));\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(shared_addr, &info));\n    EXPECT_EQ(info.NMappedNodes, 0);\n\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(shared_addr, PAGE_SIZE, NULL, mapFlags, 1, &nodes[0]));\n    EXPECT_SUCCESS(hsaKmtQueryPointerInfo(shared_addr, &info));\n    EXPECT_EQ(info.NMappedNodes, 1);\n    EXPECT_EQ(info.MappedNodes[0], nodes[0]);\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(shared_addr));\n    EXPECT_SUCCESS(hsaKmtFreeMemory(shared_addr, PAGE_SIZE));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDLocalMemoryTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_LOCALMEMORY_TEST__H__\n#define __KFD_LOCALMEMORY_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDLocalMemoryTest : public KFDBaseComponentTest {\n public:\n    KFDLocalMemoryTest() {}\n    ~KFDLocalMemoryTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_LOCALMEMORY_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDMemoryTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDMemoryTest.hpp\"\n#include <sys/prctl.h>\n#include <sys/ptrace.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <signal.h>\n#include <numa.h>\n#include <vector>\n#include \"Dispatch.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n\n/* Captures user specified time (seconds) to sleep */\nextern unsigned int g_SleepTime;\n\nstatic pthread_mutex_t ptrace_mtx;\n\nvoid KFDMemoryTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDMemoryTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\n#include <sys/mman.h>\n#define GB(x) ((x) << 30)\n\n/*\n * Try to map as much as possible system memory to gpu\n * to see if KFD supports 1TB memory correctly or not.\n * After this test case, we can observe if there are any side effects.\n * NOTICE: There are memory usage limit checks in hsa/kfd according to the total\n * physical system memory.\n */\nstatic void MMapLarge(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Test not supported on APU.\" << std::endl;\n        return;\n    }\n\n\tconst HSAuint64 nObjects = 1<<14;\n    HSAuint64 *AlternateVAGPU = new HSAuint64[nObjects];\n    ASSERT_NE_GPU((HSAuint64)AlternateVAGPU, 0, gpuNode);\n    HsaMemMapFlags mapFlags = {0};\n    HSAuint64 s;\n    char *addr;\n    HSAuint64 flags = MAP_ANONYMOUS | MAP_PRIVATE;\n\n    /* Test up to 1TB memory*/\n    s = GB(1024ULL) / nObjects;\n    addr = reinterpret_cast<char*>(mmap(0, s, PROT_READ | PROT_WRITE, flags, -1, 0));\n    ASSERT_NE_GPU(addr, MAP_FAILED, gpuNode);\n    memset(addr, 0, s);\n\n    int i = 0;\n    /* Allocate 1024GB, aka 1TB*/\n    for (; i < nObjects; i++) {\n\n        /* Code snippet to allow CRIU checkpointing */\n        if (i == (1 << 6)) {\n            if (g_SleepTime > 0) {\n                LOG() << \"Pause for: \" << g_SleepTime << \" seconds\" <<  std::endl;\n                sleep(g_SleepTime);\n            }\n        }\n\n        if (hsaKmtRegisterMemory(addr + i, s - i))\n            break;\n        if (hsaKmtMapMemoryToGPUNodes(addr + i, s - i,\n                    &AlternateVAGPU[i], mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode))) {\n            hsaKmtDeregisterMemory(addr + i);\n            break;\n        }\n    }\n\n    LOG() << \"Successfully registered and mapped \" << (i * s >> 30)\n            << \"GB system memory to gpu\" << std::endl;\n\n    RECORD(i * s >> 30) << \"Mmap-SysMem-Size\";\n\n    while (i--) {\n        EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void*>(AlternateVAGPU[i])), gpuNode);\n        EXPECT_SUCCESS_GPU(hsaKmtDeregisterMemory(reinterpret_cast<void*>(AlternateVAGPU[i])), gpuNode);\n    }\n\n    munmap(addr, s);\n    delete []AlternateVAGPU;\n\n}\n\nTEST_F(KFDMemoryTest, MMapLarge) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MMapLarge));\n\n    TEST_END\n}\n\n/* Keep memory mapped to default node\n * Keep mapping/unmapping memory to/from non-default node\n * A shader running on default node consistantly accesses\n * memory - make sure memory is always accessible by default,\n * i.e. there is no gpu vm fault.\n * Synchronization b/t host program and shader:\n * 1. Host initializes src and dst buffer to 0\n * 2. Shader keeps reading src buffer and check value\n * 3. Host writes src buffer to 0x5678 to indicate quit, polling dst until it becomes 0x5678\n * 4. Shader write dst buffer to 0x5678 after src changes to 0x5678, then quits\n * 5. Host program quits after dst becomes 0x5678\n * Need at least two gpu nodes to run the test. The default node has to be a gfx9 node,\n * otherwise, test is skipped. Use kfdtest --node=$$ to specify the default node\n * This test case is introduced as a side-result of investigation of SWDEV-134798, which\n * is a gpu vm fault while running rocr conformance test. Here we try to simulate the\n * same test behaviour.\n */\nstatic void MapUnmapToNodes(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\tHSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << \"Skipping test: Test requires gfx9 and later asics.\" << std::endl;\n        return;\n    }\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 nondefaultNode;\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        if (gpuNodes.at(i) != gpuNode) {\n            nondefaultNode = gpuNodes.at(i);\n            break;\n        }\n    }\n    HSAuint32 mapNodes[2] = {HSAuint32(gpuNode), nondefaultNode};\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcBuffer(PAGE_SIZE, gpuNode);\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, gpuNode);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollMemoryIsa, isaBuffer.As<char*>()), gpuNode);\n\n    PM4Queue pm4Queue;\n    ASSERT_SUCCESS_GPU(pm4Queue.Create(gpuNode), gpuNode);\n\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(srcBuffer.As<void*>(), dstBuffer.As<void*>());\n    dispatch0.Submit(pm4Queue);\n\n    HsaMemMapFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 1;\n\n    for (unsigned i = 0; i < 1<<14; i ++) {\n        hsaKmtMapMemoryToGPUNodes(srcBuffer.As<void*>(), PAGE_SIZE, NULL, memFlags, (i>>5)&1+1, mapNodes);\n    }\n\n    /* Fill src buffer so shader quits */\n    srcBuffer.Fill(0x5678);\n    WaitOnValue(dstBuffer.As<uint32_t *>(), 0x5678);\n    EXPECT_EQ_GPU(*dstBuffer.As<uint32_t *>(), 0x5678, gpuNode);\n    EXPECT_SUCCESS_GPU(pm4Queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, MapUnmapToNodes) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MapUnmapToNodes));\n\n    TEST_END\n}\n\n// Basic test of hsaKmtMapMemoryToGPU and hsaKmtUnmapMemoryToGPU\nstatic void MapMemoryToGPU(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    unsigned int *nullPtr = NULL;\n    unsigned int* pDb = NULL;\n\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode /* system */, PAGE_SIZE, pKFDMemoryTest->GetHsaMemFlags(),\n                   reinterpret_cast<void**>(&pDb)), gpuNode);\n    // verify that pDb is not null before it's being used\n    ASSERT_NE_GPU(nullPtr, pDb, gpuNode) << \"hsaKmtAllocMemory returned a null pointer\";\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(pDb, PAGE_SIZE, NULL), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pDb), gpuNode);\n    // Release the buffers\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, PAGE_SIZE), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, MapMemoryToGPU) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MapMemoryToGPU));\n\n    TEST_END\n}\n\n\n// Following tests are for hsaKmtAllocMemory with invalid params\nTEST_F(KFDMemoryTest, InvalidMemoryPointerAlloc) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    m_MemoryFlags.ui32.NoNUMABind = 1;\n    EXPECT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtAllocMemory(0 /* system */, PAGE_SIZE, m_MemoryFlags, NULL));\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, ZeroMemorySizeAlloc) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    unsigned int* pDb = NULL;\n    EXPECT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtAllocMemory(0 /* system */, 0, m_MemoryFlags,\n              reinterpret_cast<void**>(&pDb)));\n\n    TEST_END\n}\n\n// Basic test for hsaKmtAllocMemory\nTEST_F(KFDMemoryTest, MemoryAlloc) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    unsigned int* pDb = NULL;\n    m_MemoryFlags.ui32.NoNUMABind = 1;\n    EXPECT_SUCCESS(hsaKmtAllocMemory(0 /* system */, PAGE_SIZE, m_MemoryFlags, reinterpret_cast<void**>(&pDb)));\n\n    TEST_END\n}\n\n// Basic test for hsaKmtAllocMemory\nstatic void MemoryAllocAll(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.NonPaged = 1; // sys mem vs vram\n    HSAuint64 available;\n\n    if (pKFDMemoryTest->Get_Version()->KernelInterfaceMinorVersion < 9) {\n        LOG() << \"Available memory IOCTL not present in KFD. Exiting.\" << std::endl;\n        return;\n    }\n\n    void *object = NULL;\n    int shrink = 21, success = HSAKMT_STATUS_NO_MEMORY;\n    EXPECT_SUCCESS_GPU(hsaKmtAvailableMemory(gpuNode, &available), gpuNode);\n    LOG() << \"Available: \" << available << \" bytes\" << std::endl;\n    HSAuint64 leeway = (10 << shrink), size = available + leeway;\n    for (int i = 0; i < available >> shrink; i++) {\n        if (hsaKmtAllocMemory(gpuNode, size, memFlags, &object) == HSAKMT_STATUS_SUCCESS) {\n            success = hsaKmtFreeMemory(object, available);\n            break;\n        }\n        size -= (1 << shrink);\n    }\n    if (success == HSAKMT_STATUS_SUCCESS) {\n        LOG() << \"Allocated: \" << size << \" bytes\" << std::endl;\n        if (size > available + leeway) {\n            LOG() << \"Under-reported available memory!\" << std::endl;\n        }\n        if (size < available - leeway) {\n            LOG() << \"Over-reported available memory!\" << std::endl;\n        }\n    }\n    EXPECT_SUCCESS_GPU(success, gpuNode);\n}\n\nTEST_F(KFDMemoryTest, MemoryAllocAll) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MemoryAllocAll));\n\n    TEST_END\n}\n\nstatic void AccessPPRMem(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Test requires APU.\" << std::endl;\n        return;\n    }\n\n    unsigned int *destBuf = (unsigned int *)VirtualAllocMemory(NULL, PAGE_SIZE,\n                                            MEM_READ | MEM_WRITE);\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf,\n                                0xABCDEF09, 0x12345678));\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf, 0xABCDEF09);\n    WaitOnValue(destBuf + 1, 0x12345678);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    /* This sleep hides the dmesg PPR message storm on Raven, which happens\n     * when the CPU buffer is freed before the excessive PPRs are all\n     * consumed by IOMMU HW. Because of that, a kernel driver workaround\n     * is put in place to address that, so we don't need to wait here.\n     */\n    // sleep(5);\n\n    VirtualFreeMemory(destBuf, PAGE_SIZE);\n}\n\nTEST_F(KFDMemoryTest, AccessPPRMem) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AccessPPRMem));\n\n    TEST_END\n}\n\n// Linux OS-specific Test for registering OS allocated memory\nstatic void MemoryRegister(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n\tconst HsaNodeProperties *pNodeProperties = pKFDMemoryTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n\n    /* Different unaligned memory locations to be mapped for GPU\n     * access:\n     *\n     * - initialized data segment (file backed)\n     * - stack (anonymous memory)\n     *\n     * Separate them enough so they are in different cache lines\n     * (64-byte = 16-dword).\n     */\n    static volatile HSAuint32 globalData = 0xdeadbeef;\n    volatile HSAuint32 stackData[17] = {0};\n    const unsigned dstOffset = 0;\n    const unsigned sdmaOffset = 16;\n\n    HsaMemoryBuffer srcBuffer((void *)&globalData, sizeof(HSAuint32));\n    HsaMemoryBuffer dstBuffer((void *)&stackData[dstOffset], sizeof(HSAuint32));\n    HsaMemoryBuffer sdmaBuffer((void *)&stackData[sdmaOffset], sizeof(HSAuint32));\n\n    /* Create PM4 and SDMA queues before fork+COW to test queue\n     * eviction and restore\n     */\n    PM4Queue pm4Queue;\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(pm4Queue.Create(gpuNode), gpuNode);\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    /* First submit just so the queues are not empty, and to get the\n     * TLB populated (in case we need to flush TLBs somewhere after\n     * updating the page tables)\n     */\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(srcBuffer.As<void*>(), dstBuffer.As<void*>());\n    dispatch0.Submit(pm4Queue);\n    dispatch0.Sync(g_TestTimeOut);\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(), sdmaBuffer.As<HSAuint32 *>(), 0x12345678));\n    sdmaQueue.Wait4PacketConsumption();\n    EXPECT_TRUE_GPU(WaitOnValue(&stackData[sdmaOffset], 0x12345678), gpuNode);\n\n    /* Fork a child process to mark pages as COW */\n    pid_t pid = fork();\n    ASSERT_GE_GPU(pid, 0, gpuNode);\n    if (pid == 0) {\n        /* Child process waits for a SIGTERM from the parent. It can't\n         * make any write access to the stack because we want the\n         * parent to make the first write access and get a new copy. A\n         * busy loop is the safest way to do that, since any function\n         * call (e.g. sleep) would write to the stack.\n         */\n        while (1)\n        {}\n        WARN() << \"Shouldn't get here!\" << std::endl;\n        exit(0);\n    }\n\n    /* Parent process writes to COW page(s) and gets a new copy. MMU\n     * notifier needs to update the GPU mapping(s) for the test to\n     * pass.\n     */\n    globalData = 0xD00BED00;\n    stackData[dstOffset] = 0xdeadbeef;\n    stackData[sdmaOffset] = 0xdeadbeef;\n\n    /* Terminate the child process before a possible test failure that\n     * would leave it spinning in the background indefinitely.\n     */\n    int status;\n    EXPECT_EQ_GPU(0, kill(pid, SIGTERM), gpuNode);\n    EXPECT_EQ_GPU(pid, waitpid(pid, &status, 0), gpuNode);\n    EXPECT_NE_GPU(0, WIFSIGNALED(status), gpuNode);\n    EXPECT_EQ_GPU(SIGTERM, WTERMSIG(status), gpuNode);\n\n    /* Now check that the GPU is accessing the correct page */\n    Dispatch dispatch1(isaBuffer);\n    dispatch1.SetArgs(srcBuffer.As<void*>(), dstBuffer.As<void*>());\n    dispatch1.Submit(pm4Queue);\n    dispatch1.Sync(g_TestTimeOut);\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(), sdmaBuffer.As<HSAuint32 *>(), 0xD0BED0BE));\n    sdmaQueue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS_GPU(pm4Queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n\n    EXPECT_EQ_GPU(0xD00BED00, globalData, gpuNode);\n    EXPECT_EQ_GPU(0xD00BED00, stackData[dstOffset], gpuNode);\n    EXPECT_EQ_GPU(0xD0BED0BE, stackData[sdmaOffset], gpuNode);\n}\n\nTEST_F(KFDMemoryTest, MemoryRegister) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MemoryRegister));\n\n    TEST_END\n}\n\nstatic void MemoryRegisterSamePtr(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n\tHSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Will run on APU once APU+dGPU supported.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    HSAuint64 nGPU = gpuNodes.size();  // number of gpu nodes\n    static volatile HSAuint32 mem[4];\n    HSAuint64 gpuva1, gpuva2;\n\n    /* Same address, different size */\n    EXPECT_SUCCESS(hsaKmtRegisterMemory((void *)&mem[0], sizeof(HSAuint32)*2));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPU((void *)&mem[0], sizeof(HSAuint32)*2,\n                                        &gpuva1));\n    EXPECT_SUCCESS(hsaKmtRegisterMemory((void *)&mem[0], sizeof(HSAuint32)));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPU((void *)&mem[0], sizeof(HSAuint32),\n                                        &gpuva2));\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void *>(gpuva1)));\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(reinterpret_cast<void *>(gpuva1)));\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void *>(gpuva2)));\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(reinterpret_cast<void *>(gpuva2)));\n\n    /* Same address, same size */\n    HsaMemMapFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 1;\n\n    HSAuint32 nodes[nGPU];\n    for (unsigned int i = 0; i < nGPU; i++)\n        nodes[i] = gpuNodes.at(i);\n    EXPECT_SUCCESS(hsaKmtRegisterMemoryToNodes((void *)&mem[2],\n                            sizeof(HSAuint32)*2, nGPU, nodes));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes((void *)&mem[2],\n                                        sizeof(HSAuint32) * 2,\n                                        &gpuva1, memFlags, nGPU, nodes));\n    EXPECT_SUCCESS(hsaKmtRegisterMemoryToNodes((void *)&mem[2],\n                                        sizeof(HSAuint32) * 2, nGPU, nodes));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes((void *)&mem[2],\n                                        sizeof(HSAuint32) * 2,\n                                        &gpuva2, memFlags, nGPU, nodes));\n    EXPECT_EQ(gpuva1, gpuva2);\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void *>(gpuva1)));\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(reinterpret_cast<void *>(gpuva1)));\n    /* Confirm that we still have access to the memory, mem[2] */\n    PM4Queue queue;\n    ASSERT_SUCCESS(queue.Create(gpuNode));\n    mem[2] = 0x0;\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(reinterpret_cast<unsigned int *>(gpuva2),\n                                                  0xdeadbeef));\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, true, 0, 0));\n    queue.Wait4PacketConsumption();\n    EXPECT_EQ(true, WaitOnValue((unsigned int *)(&mem[2]), 0xdeadbeef));\n    EXPECT_SUCCESS(queue.Destroy());\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void *>(gpuva2)));\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(reinterpret_cast<void *>(gpuva2)));\n}\n\nTEST_F(KFDMemoryTest, MemoryRegisterSamePtr) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MemoryRegisterSamePtr));\n\n    TEST_END\n}\n\n/* FlatScratchAccess\n * Since HsaMemoryBuffer has to be associated with a specific GPU node, this function in the current form\n * will not work for multiple GPU nodes. For now test only one default GPU node.\n * TODO: Generalize it to support multiple nodes\n */\n\n#define SCRATCH_SLICE_SIZE 0x10000\n#define SCRATCH_SLICE_NUM 3\n#define SCRATCH_SIZE (SCRATCH_SLICE_NUM * SCRATCH_SLICE_SIZE)\n#define SCRATCH_SLICE_OFFSET(i) ((i) * SCRATCH_SLICE_SIZE)\n\nstatic void FlatScratchAccess(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n\tHSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId == FAMILY_CI || m_FamilyId == FAMILY_KV) {\n        LOG() << \"Skipping test: VI-based shader not supported on other ASICs.\" << std::endl;\n        return;\n    }\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer scratchBuffer(SCRATCH_SIZE, gpuNode, false/*zero*/, false/*local*/,\n                                  false/*exec*/, true /*scratch*/);\n\n    // Unmap scratch for sub-allocation mapping tests\n    ASSERT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(scratchBuffer.As<void*>()), gpuNode);\n\n    // Map and unmap a few slices in different order: 2-0-1, 0-2-1\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(2),\n                                        SCRATCH_SLICE_SIZE, NULL), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(0),\n                                        SCRATCH_SLICE_SIZE, NULL), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(1),\n                                        SCRATCH_SLICE_SIZE, NULL), gpuNode);\n\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(1)), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(2)), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(scratchBuffer.As<char*>() + SCRATCH_SLICE_OFFSET(0)), gpuNode);\n\n    // Map everything for test below\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(scratchBuffer.As<char*>(), SCRATCH_SIZE, NULL), gpuNode);\n\n    HsaMemoryBuffer srcMemBuffer(PAGE_SIZE, gpuNode);\n    HsaMemoryBuffer dstMemBuffer(PAGE_SIZE, gpuNode);\n\n    // Initialize the srcBuffer to some fixed value\n    srcMemBuffer.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(ScratchCopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    const HsaNodeProperties *pNodeProperties = pKFDMemoryTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n\n    /* TODO: Add support to all GPU Nodes.\n     * The loop over the system nodes is removed as the test can be executed only on GPU nodes. This\n     * also requires changes to be made to all the HsaMemoryBuffer variables defined above, as\n     * HsaMemoryBuffer is now associated with a Node.\n     */\n    if (pNodeProperties != NULL) {\n        // Get the aperture of the scratch buffer\n        HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n        EXPECT_SUCCESS_GPU(hsaKmtGetNodeMemoryProperties(gpuNode, pNodeProperties->NumMemoryBanks,\n                       memoryProperties), gpuNode);\n\n        for (unsigned int bank = 0; bank < pNodeProperties->NumMemoryBanks; bank++) {\n            if (memoryProperties[bank].HeapType == HSA_HEAPTYPE_GPU_SCRATCH) {\n                int numWaves = pNodeProperties->NumShaderBanks;  // WAVES must be >= # SE\n                int waveSize = 1;  // Amount of space used by each wave in units of 256 dwords\n\n                PM4Queue queue;\n                ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n                HSAuint64 scratchApertureAddr = memoryProperties[bank].VirtualBaseAddress;\n\n                // Create a dispatch packet to copy\n                Dispatch dispatchSrcToScratch(isaBuffer);\n\n                // Setup the dispatch packet\n                // Copying from the source Memory Buffer to the scratch buffer\n                dispatchSrcToScratch.SetArgs(srcMemBuffer.As<void*>(), reinterpret_cast<void*>(scratchApertureAddr));\n                dispatchSrcToScratch.SetDim(1, 1, 1);\n                dispatchSrcToScratch.SetScratch(numWaves, waveSize, scratchBuffer.As<uint64_t>());\n                // Submit the packet\n                dispatchSrcToScratch.Submit(queue);\n                dispatchSrcToScratch.Sync();\n\n                // Create another dispatch packet to copy scratch buffer contents to destination buffer.\n                Dispatch dispatchScratchToDst(isaBuffer);\n\n                // Set the arguments to copy from the scratch buffer to the destination buffer\n                dispatchScratchToDst.SetArgs(reinterpret_cast<void*>(scratchApertureAddr), dstMemBuffer.As<void*>());\n                dispatchScratchToDst.SetDim(1, 1, 1);\n                dispatchScratchToDst.SetScratch(numWaves, waveSize, scratchBuffer.As<uint64_t>());\n\n                // Submit the packet\n                dispatchScratchToDst.Submit(queue);\n                dispatchScratchToDst.Sync();\n\n                // Check that the scratch buffer contents were correctly copied over to the system memory buffer\n                EXPECT_EQ_GPU(dstMemBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n            }\n        }\n\n        delete [] memoryProperties;\n    }\n}\n\nTEST_F(KFDMemoryTest, FlatScratchAccess) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(FlatScratchAccess));\n\n    TEST_END\n}\n\nstatic void GetTileConfigTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    HSAuint32 tile_config[32] = {0};\n    HSAuint32 macro_tile_config[16] = {0};\n    unsigned int i;\n    HsaGpuTileConfig config = {0};\n\n    config.TileConfig = tile_config;\n    config.MacroTileConfig = macro_tile_config;\n    config.NumTileConfigs = 32;\n    config.NumMacroTileConfigs = 16;\n\n    ASSERT_SUCCESS(hsaKmtGetTileConfig(gpuNode, &config));\n\n    LOG() << \"tile_config:\" << std::endl;\n    for (i = 0; i < config.NumTileConfigs; i++)\n        LOG() << \"\\t\" << std::dec << i << \": 0x\" << std::hex\n                << tile_config[i] << std::endl;\n\n    LOG() << \"macro_tile_config:\" << std::endl;\n    for (i = 0; i < config.NumMacroTileConfigs; i++)\n        LOG() << \"\\t\" << std::dec << i << \": 0x\" << std::hex\n                << macro_tile_config[i] << std::endl;\n\n    LOG() << \"gb_addr_config: 0x\" << std::hex << config.GbAddrConfig\n            << std::endl;\n    LOG() << \"num_banks: 0x\" << std::hex << config.NumBanks << std::endl;\n    LOG() << \"num_ranks: 0x\" << std::hex << config.NumRanks << std::endl;\n}\n\nTEST_F(KFDMemoryTest, GetTileConfigTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(GetTileConfigTest));\n\n    TEST_END\n}\n\nvoid SearchLargestBuffer(int allocNode, const HsaMemFlags &memFlags,\n                                        HSAuint64 highMB, int nodeToMap,\n                                        HSAuint64 *lastSizeMB) {\n    int ret;\n\n    HsaMemMapFlags mapFlags = {0};\n    HSAuint64 granularityMB = 8;\n\n    /* Testing big buffers in VRAM */\n    unsigned int * pDb = NULL;\n\n    highMB = (highMB + granularityMB - 1) & ~(granularityMB - 1);\n\n    HSAuint64 sizeMB;\n    HSAuint64 size = 0;\n\n    while (highMB > granularityMB) {\n        sizeMB = highMB - granularityMB;\n        size = sizeMB * 1024 * 1024;\n        ret = hsaKmtAllocMemory(allocNode, size, memFlags,\n                                reinterpret_cast<void**>(&pDb));\n        if (ret) {\n            highMB = sizeMB;\n            continue;\n        }\n\n        /* Code snippet to allow CRIU checkpointing */\n        if (g_SleepTime > 0) {\n            LOG() << \"Pause for: \" << g_SleepTime << \" seconds\" <<  std::endl;\n            sleep(g_SleepTime);\n        }\n\n        ret = hsaKmtMapMemoryToGPUNodes(pDb, size, NULL,\n                        mapFlags, 1, reinterpret_cast<HSAuint32 *>(&nodeToMap));\n        if (ret) {\n            EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, size), nodeToMap);\n            highMB = sizeMB;\n            continue;\n        }\n        EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pDb), nodeToMap);\n        EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, size), nodeToMap);\n\n        if (lastSizeMB)\n           *lastSizeMB = sizeMB;\n        break;\n    }\n}\n\n/*\n * Largest*BufferTest allocates, maps/unmaps, and frees the largest possible\n * buffers. Its size is found using binary search in the range\n * (0, RAM SIZE) with a granularity of 8M. Also, the similar logic is\n * repeated on local buffers (VRAM).\n * Please note we limit the largest possible system buffer to be smaller than\n * the RAM size. The reason is that the system buffer can make use of virtual\n * memory so that a system buffer could be very large even though the RAM size\n * is small. For example, on a typical Carrizo platform, the largest allocated\n * system buffer could be more than 14G even though it only has 4G memory.\n * In that situation, it will take too much time to finish the test because of\n * the onerous memory swap operation. So we limit the buffer size that way.\n */\nstatic void LargestSysBufferTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Running on APU fails and locks the system.\" << std::endl;\n        return;\n    }\n\n    int gpuNum = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU().size();\n\n\t/* if no gpu node */\n\tif (gpuNum <= 0)\n\t\treturn;\n\n    HSAuint64 lastTestedSizeMB = 0;\n\n    HSAuint64 sysMemSizeMB;\n    sysMemSizeMB = pKFDMemoryTest->GetSysMemSize() >> 20;\n\n    sysMemSizeMB/=gpuNum;\n\n    LOG() << \"Found System Memory of \" << std::dec << sysMemSizeMB\n                    << \"MB. Using 95% of that for the test\" << std::endl;\n\n    SearchLargestBuffer(0, pKFDMemoryTest->GetHsaMemFlags(), sysMemSizeMB*0.95, gpuNode,\n                    &lastTestedSizeMB);\n\n    LOG() << \"The largest allocated system buffer is \" << std::dec\n            << lastTestedSizeMB << \"MB\" << std::endl;\n}\n\nTEST_F(KFDMemoryTest, LargestSysBufferTest) {\n     TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\t TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(LargestSysBufferTest));\n\n    TEST_END\n}\n\nstatic void LargestVramBufferTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n   int gpuNode = pTestParamters->gpuNode;\n   KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Running on APU fails and locks the system.\" << std::endl;\n        return;\n    }\n\n    HSAuint64 lastTestedSizeMB = 0;\n\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.HostAccess = 0;\n    memFlags.ui32.NonPaged = 1;\n\n    HSAuint64 vramSizeMB;\n    vramSizeMB = pKFDMemoryTest->GetVramSize(gpuNode) >> 20;\n\n    LOG() << \"Found VRAM of \" << std::dec << vramSizeMB << \"MB.\" << std::endl;\n\n    SearchLargestBuffer(gpuNode, memFlags, vramSizeMB, gpuNode,\n                    &lastTestedSizeMB);\n\n    LOG() << \"The largest allocated VRAM buffer is \" << std::dec\n            << lastTestedSizeMB << \"MB\" << std::endl;\n\n    /* Make sure 3/5 vram can be allocated.*/\n    if (vramSizeMB <= 512)\n        EXPECT_GE_GPU(lastTestedSizeMB * 5, vramSizeMB * 3, gpuNode);\n    else\n        EXPECT_GE_GPU(lastTestedSizeMB * 4, vramSizeMB * 3, gpuNode);\n\n    if (lastTestedSizeMB * 16 < vramSizeMB * 15)\n        WARN() << \"The largest allocated VRAM buffer size is smaller than the expected \"\n            << vramSizeMB * 15 / 16 << \"MB\" << std::endl;\n}\n\nTEST_F(KFDMemoryTest, LargestVramBufferTest) {\n     TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\t TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(LargestVramBufferTest));\n\n    TEST_END\n}\n/*\n * BigSysBufferStressTest allocates and maps 128M system buffers in a loop until it\n * fails, then unmaps and frees them afterwards. Meanwhile, a queue task is\n * performed on each buffer.\n */\nstatic void BigSysBufferStressTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n   int gpuNode = pTestParamters->gpuNode;\n   KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Running on APU fails and locks the system.\" << std::endl;\n        return;\n    }\n\n    HSAuint64 AlternateVAGPU;\n    HsaMemMapFlags mapFlags = {0};\n    int ret;\n\n    /* Repeatedly allocate and map big buffers in system memory until it fails,\n     * then unmap and free them.\n     */\n#define ARRAY_ENTRIES 2048\n\n    int i = 0, allocationCount = 0;\n    unsigned int* pDb_array[ARRAY_ENTRIES];\n    HSAuint64 block_size_mb = 128;\n    HSAuint64 block_size = block_size_mb * 1024 * 1024;\n\n    /* Test 4 times to see if there is any memory leak.*/\n    for (int repeat = 1; repeat < 5; repeat++) {\n\n        for (i = 0; i < ARRAY_ENTRIES; i++) {\n            ret = hsaKmtAllocMemory(0 /* system */, block_size, pKFDMemoryTest->GetHsaMemFlags(),\n                    reinterpret_cast<void**>(&pDb_array[i]));\n            if (ret)\n                break;\n\n            ret = hsaKmtMapMemoryToGPUNodes(pDb_array[i], block_size,\n                    &AlternateVAGPU, mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode));\n            if (ret) {\n                EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb_array[i], block_size), gpuNode);\n                break;\n            }\n        }\n\n        LOG() << \"Allocated system buffers time \" << std::dec << repeat << \": \"\n            << i << \" * \" << block_size_mb << \"MB\" << std::endl;\n\n        if (allocationCount == 0)\n            allocationCount = i;\n        EXPECT_GE_GPU(i, allocationCount, gpuNode) << \"There might be memory leak!\" << std::endl;\n\n        for (int j = 0; j < i; j++) {\n            EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pDb_array[j]), gpuNode);\n            EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb_array[j], block_size), gpuNode);\n        }\n    }\n}\n\nTEST_F(KFDMemoryTest, BigSysBufferStressTest) {\n     TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\t TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(LargestVramBufferTest));\n\n    TEST_END\n}\n\n#define VRAM_ALLOCATION_ALIGN (1 << 21)  //Align VRAM allocations to 2MB\nstatic void MMBench(KFDTEST_PARAMETERS* pTestParamters) {\n\n   int gpuNode = pTestParamters->gpuNode;\n   KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    unsigned testIndex, sizeIndex, memType, nMemTypes;\n    const char *memTypeStrings[2] = {\"SysMem\", \"VRAM\"};\n    const struct {\n        unsigned size;\n        unsigned num;\n    } bufParams[] = {\n        /* Buffer sizes in x16 increments. Limit memory usage to about\n         * 1GB. For small sizes we use 1000 buffers, which means we\n         * conveniently measure microseconds and report nanoseconds.\n         */\n        {PAGE_SIZE      , 1000},  /*  4KB */\n        {PAGE_SIZE <<  4, 1000},  /* 64KB */\n        {PAGE_SIZE <<  9,  500},  /*  2MB */\n        {PAGE_SIZE << 13,   32},  /* 32MB */\n        {PAGE_SIZE << 18,    1},  /*  1GB */\n    };\n    const unsigned nSizes = sizeof(bufParams) / sizeof(bufParams[0]);\n    const unsigned nTests = nSizes << 2;\n#define TEST_BUFSIZE(index) (bufParams[(index) % nSizes].size)\n#define TEST_NBUFS(index)  (bufParams[(index) % nSizes].num)\n#define TEST_MEMTYPE(index) ((index / nSizes) & 0x1)\n#define TEST_SDMA(index)    (((index / nSizes) >> 1) & 0x1)\n\n    void *bufs[1000];\n    HSAuint64 start, end;\n    unsigned i;\n    HSAKMT_STATUS ret;\n    HsaMemFlags memFlags = {0};\n    HsaMemMapFlags mapFlags = {0};\n    HSAuint64 altVa;\n\n    HSAuint64 vramSizeMB = pKFDMemoryTest->GetVramSize(gpuNode) >> 20;\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    bool is_all_large_bar = true;\n\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        if (!pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(gpuNodes.at(i))) {\n                is_all_large_bar = false;\n                break;\n        }\n    }\n\n    LOG() << \"Found VRAM of \" << std::dec << vramSizeMB << \"MB.\" << std::endl;\n\n    if (vramSizeMB == 0)\n        nMemTypes = 1;\n    else\n        nMemTypes = 2;\n\n    /* Two SDMA queues to interleave user mode SDMA with memory\n     * management on either SDMA engine. Make the queues long enough\n     * to buffer at least nBufs x WriteData packets (7 dwords per\n     * packet).\n     */\n    SDMAQueue sdmaQueue[2];\n    ASSERT_SUCCESS_GPU(sdmaQueue[0].Create(gpuNode, PAGE_SIZE*8), gpuNode);\n    ASSERT_SUCCESS_GPU(sdmaQueue[1].Create(gpuNode, PAGE_SIZE*8), gpuNode);\n    HsaMemoryBuffer sdmaBuffer(PAGE_SIZE, 0); /* system memory */\n#define INTERLEAVE_SDMA() do {                                          \\\n        if (interleaveSDMA) {                                           \\\n            sdmaQueue[0].PlaceAndSubmitPacket(                          \\\n                SDMAWriteDataPacket(sdmaQueue[0].GetFamilyId(), sdmaBuffer.As<HSAuint32 *>(),       \\\n                                    0x12345678));                       \\\n            sdmaQueue[1].PlaceAndSubmitPacket(                          \\\n                SDMAWriteDataPacket(sdmaQueue[1].GetFamilyId(), sdmaBuffer.As<HSAuint32 *>()+16,    \\\n                                    0x12345678));                       \\\n        }                                                               \\\n    } while (0)\n#define IDLE_SDMA() do {                                                \\\n        if (interleaveSDMA) {                                           \\\n            sdmaQueue[0].Wait4PacketConsumption();                      \\\n            sdmaQueue[1].Wait4PacketConsumption();                      \\\n        }                                                               \\\n    } while (0)\n\n    LOG() << \"Test (avg. ns)\\t    alloc   mapOne  umapOne   mapAll  umapAll     free\" << std::endl;\n    for (testIndex = 0; testIndex < nTests; testIndex++) {\n        unsigned bufSize = TEST_BUFSIZE(testIndex);\n        unsigned nBufs = TEST_NBUFS(testIndex);\n        unsigned memType = TEST_MEMTYPE(testIndex);\n        bool interleaveSDMA = TEST_SDMA(testIndex);\n        unsigned bufLimit;\n        HSAuint64 allocTime, map1Time, unmap1Time, mapAllTime, unmapAllTime, freeTime;\n        HSAuint32 allocNode;\n\n        /* Code snippet to allow CRIU checkpointing */\n        if (testIndex == 3) {\n            if (g_SleepTime > 0) {\n                LOG() << \"Pause for: \" << g_SleepTime << \" seconds\" <<  std::endl;\n                sleep(g_SleepTime);\n            }\n        }\n\n        if ((testIndex % nSizes) == 0)\n            LOG() << \"--------------------------------------------------------------------------\" << std::endl;\n\n        if (memType >= nMemTypes)\n            continue;  // skip unsupported mem types\n\n        if (memType == 0) {\n            allocNode = 0;\n            memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n            memFlags.ui32.HostAccess = 1;\n            memFlags.ui32.NonPaged = 0;\n            memFlags.ui32.NoNUMABind = 1;\n        } else {\n            allocNode = gpuNode;\n            memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n            memFlags.ui32.HostAccess = 0;\n            memFlags.ui32.NonPaged = 1;\n\n            /* Buffer sizes are 2MB aligned to match new allocation policy.\n             * Upper limit of buffer number to fit 80% vram size. APUs w/\n\t\t\t * smaller VRAM needs different criteria.\n             */\n            if (vramSizeMB <= 512)\n                bufLimit = ((vramSizeMB << 20) * 6 / 10) / ALIGN_UP(bufSize, VRAM_ALLOCATION_ALIGN);\n            else\n                bufLimit = ((vramSizeMB << 20) * 8 / 10) / ALIGN_UP(bufSize, VRAM_ALLOCATION_ALIGN);\n\n            if (bufLimit == 0)\n                continue; // skip when bufSize > vram\n\n            /* When vram is too small to fit all the buffers, fill 90% vram size*/\n            nBufs = (nBufs < bufLimit) ? nBufs : bufLimit;\n        }\n\n        /* Allocation */\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(allocNode, bufSize, memFlags,\n                                             &bufs[i]), gpuNode);\n            INTERLEAVE_SDMA();\n        }\n        allocTime = GetSystemTickCountInMicroSec() - start;\n        IDLE_SDMA();\n\n        /* Map to one GPU */\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(bufs[i], bufSize,\n                                                     &altVa, mapFlags, 1,\n                                                     (HSAuint32*)&gpuNode),  gpuNode);\n            INTERLEAVE_SDMA();\n        }\n        map1Time = GetSystemTickCountInMicroSec() - start;\n        IDLE_SDMA();\n\n        /* Unmap from GPU */\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(bufs[i]), gpuNode);\n            INTERLEAVE_SDMA();\n        }\n        unmap1Time = GetSystemTickCountInMicroSec() - start;\n        IDLE_SDMA();\n\n        /* Map to all GPUs */\n        if (is_all_large_bar) {\n            start = GetSystemTickCountInMicroSec();\n            for (i = 0; i < nBufs; i++) {\n                ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(bufs[i], bufSize, &altVa), gpuNode);\n                INTERLEAVE_SDMA();\n            }\n            mapAllTime = GetSystemTickCountInMicroSec() - start;\n            IDLE_SDMA();\n\n            /* Unmap from all GPUs */\n            start = GetSystemTickCountInMicroSec();\n            for (i = 0; i < nBufs; i++) {\n                EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(bufs[i]));\n                INTERLEAVE_SDMA();\n            }\n            unmapAllTime = GetSystemTickCountInMicroSec() - start;\n            IDLE_SDMA();\n        }\n\n        /* Free */\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(bufs[i], bufSize), gpuNode);\n            INTERLEAVE_SDMA();\n        }\n        freeTime = GetSystemTickCountInMicroSec() - start;\n        IDLE_SDMA();\n\n        allocTime = allocTime * 1000 / nBufs;\n        map1Time = map1Time * 1000 / nBufs;\n        unmap1Time = unmap1Time * 1000 / nBufs;\n        mapAllTime = mapAllTime * 1000 / nBufs;\n        unmapAllTime = unmapAllTime * 1000 / nBufs;\n        freeTime = freeTime * 1000 / nBufs;\n\n        unsigned bufSizeLog;\n        char bufSizeUnit;\n        if (bufSize < (1 << 20)) {\n            bufSizeLog = bufSize >> 10;\n            bufSizeUnit = 'K';\n        } else if (bufSize < (1 << 30)) {\n            bufSizeLog = bufSize >> 20;\n            bufSizeUnit = 'M';\n        } else {\n            bufSizeLog = bufSize >> 30;\n            bufSizeUnit = 'G';\n        }\n\n        LOG() << std::dec << std::setiosflags(std::ios::right)\n              << std::setw(3) << bufSizeLog << bufSizeUnit << \"-\"\n              << memTypeStrings[memType] << \"-\"\n              << (interleaveSDMA ? \"SDMA\\t\" : \"noSDMA\\t\")\n              << std::setw(9) << allocTime\n              << std::setw(9) << map1Time\n              << std::setw(9) << unmap1Time\n              << std::setw(9) << mapAllTime\n              << std::setw(9) << unmapAllTime\n              << std::setw(9) << freeTime << std::endl;\n\n#define MMBENCH_KEY_PREFIX memTypeStrings[memType] << \"-\" \\\n                           << (interleaveSDMA ? \"SDMA\" : \"noSDMA\") << \"-\" \\\n                           << (bufSize >> 10) << \"K-\"\n        RECORD(allocTime) << MMBENCH_KEY_PREFIX << \"alloc\";\n        RECORD(map1Time) << MMBENCH_KEY_PREFIX << \"mapOne\";\n        RECORD(unmap1Time) << MMBENCH_KEY_PREFIX << \"unmapOne\";\n        RECORD(mapAllTime) << MMBENCH_KEY_PREFIX << \"mapAll\";\n        RECORD(unmapAllTime) << MMBENCH_KEY_PREFIX << \"unmapAll\";\n        RECORD(freeTime) << MMBENCH_KEY_PREFIX << \"free\";\n    }\n}\n\nTEST_F(KFDMemoryTest, MMBench) {\n     TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\t TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MMBench));\n\n    TEST_END\n}\n\nstatic void QueryPointerInfo(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    unsigned int bufSize = PAGE_SIZE * 8;  // CZ and Tonga need 8 pages\n    HsaPointerInfo ptrInfo;\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    HSAuint64 nGPU = gpuNodes.size();  // number of gpu nodes\n\n    /* GraphicHandle is tested at KFDGraphicsInterop.RegisterGraphicsHandle */\n\n    /*** Memory allocated on CPU node ***/\n    HsaMemoryBuffer hostBuffer(bufSize, 0/*node*/, false, false/*local*/);\n    EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo(hostBuffer.As<void*>(), &ptrInfo), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_ALLOCATED, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.Node, 0, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.MemFlags.Value, hostBuffer.Flags().Value, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.CPUAddress, hostBuffer.As<void*>(), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.GPUAddress, (HSAuint64)hostBuffer.As<void*>(), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.SizeInBytes, (HSAuint64)hostBuffer.Size(), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.MemFlags.ui32.CoarseGrain, 0, gpuNode);\n    if (hsakmt_is_dgpu()) {\n        EXPECT_EQ_GPU((HSAuint64)ptrInfo.NMappedNodes, nGPU, gpuNode);\n        // Check NMappedNodes again after unmapping the memory\n        hsaKmtUnmapMemoryToGPU(hostBuffer.As<void*>());\n        hsaKmtQueryPointerInfo(hostBuffer.As<void*>(), &ptrInfo);\n    }\n    EXPECT_EQ_GPU((HSAuint64)ptrInfo.NMappedNodes, 0, gpuNode);\n\n    /* Skip testing local memory if the platform does not have it */\n    if (pKFDMemoryTest->GetVramSize(gpuNode)) {\n        HsaMemoryBuffer localBuffer(bufSize, gpuNode, false, true);\n        EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo(localBuffer.As<void*>(), &ptrInfo), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_ALLOCATED, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.Node, gpuNode, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.MemFlags.Value, localBuffer.Flags().Value, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.CPUAddress, localBuffer.As<void*>(), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.GPUAddress, (HSAuint64)localBuffer.As<void*>(), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.SizeInBytes, (HSAuint64)localBuffer.Size(), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.MemFlags.ui32.CoarseGrain, 1, gpuNode);\n\n        HSAuint32 *addr = localBuffer.As<HSAuint32 *>() + 4;\n        EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo(reinterpret_cast<void *>(addr), &ptrInfo), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.GPUAddress, (HSAuint64)localBuffer.As<void*>(), gpuNode);\n    }\n\n    /** Registered memory: user pointer */\n    static volatile HSAuint32 mem[4];  // 8 bytes for register only and\n                                       // 8 bytes for register to nodes\n    HsaMemoryBuffer hsaBuffer((void *)(&mem[0]), sizeof(HSAuint32)*2);\n    /*\n     * APU doesn't use userptr.\n     * User pointers registered with SVM API, does not create vm_object_t.\n     * Therefore, pointer info can not be queried.\n     */\n    if (hsakmt_is_dgpu() && mem != hsaBuffer.As<void*>()) {\n        EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo((void *)(&mem[0]), &ptrInfo), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_REGISTERED_USER, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.CPUAddress, &mem[0], gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.GPUAddress, (HSAuint64)hsaBuffer.As<void*>(), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.SizeInBytes, sizeof(HSAuint32)*2, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.NRegisteredNodes, 0, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.NMappedNodes, nGPU, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.MemFlags.ui32.CoarseGrain, 1, gpuNode);\n        // Register to nodes\n        HSAuint32 nodes[nGPU];\n        for (unsigned int i = 0; i < nGPU; i++)\n            nodes[i] = gpuNodes.at(i);\n        EXPECT_SUCCESS_GPU(hsaKmtRegisterMemoryToNodes((void *)(&mem[2]),\n                                sizeof(HSAuint32)*2, nGPU, nodes), gpuNode);\n        EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo((void *)(&mem[2]), &ptrInfo), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.NRegisteredNodes, nGPU, gpuNode);\n        EXPECT_SUCCESS_GPU(hsaKmtDeregisterMemory((void *)(&mem[2])), gpuNode);\n    }\n\n    /* Not a starting address, but an address inside the memory range\n     * should also get the memory information\n     */\n    HSAuint32 *address = hostBuffer.As<HSAuint32 *>() + 1;\n    EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo(reinterpret_cast<void *>(address), &ptrInfo), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_ALLOCATED, gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.CPUAddress, hostBuffer.As<void*>(), gpuNode);\n    if (hsakmt_is_dgpu() && &mem[1] != hsaBuffer.As<HSAuint32 *>() + 1) {\n        EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo((void *)(&mem[1]), &ptrInfo), gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.Type, HSA_POINTER_REGISTERED_USER, gpuNode);\n        EXPECT_EQ_GPU(ptrInfo.CPUAddress, &mem[0], gpuNode);\n    }\n\n    /*** Set user data ***/\n    char userData[16] = \"This is a test.\";\n    EXPECT_SUCCESS_GPU(hsaKmtSetMemoryUserData(hostBuffer.As<HSAuint32 *>(), reinterpret_cast<void *>(userData)), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtQueryPointerInfo(hostBuffer.As<void*>(), &ptrInfo), gpuNode);\n    EXPECT_EQ_GPU(ptrInfo.UserData, (void *)userData, gpuNode);\n}\n\nTEST_F(KFDMemoryTest, QueryPointerInfo) {\n\n\t TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(QueryPointerInfo));\n\n    TEST_END\n}\n\n/* Linux OS-specific test for a debugger accessing HSA memory in a\n * debugged process.\n *\n * Allocates a system memory and a visible local memory buffer (if\n * possible). Forks a child process that PTRACE_ATTACHes to the parent\n * to access its memory like a debugger would. Child copies data in\n * the parent process using PTRACE_PEEKDATA and PTRACE_POKEDATA. After\n * the child terminates, the parent checks that the copy was\n * successful.\n */\nstatic void PtraceAccess(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 1;\n\n    void *mem[2];\n    unsigned i;\n\n    /* Offset in the VRAM buffer to test crossing non-contiguous\n     * buffer boundaries. The second access starting from offset\n     * sizeof(HSAint64)+1 will cross a node boundary in a single access,\n     * for node sizes of 4MB or smaller.\n     */\n    const HSAuint64 VRAM_OFFSET = (4 << 20) - 2 * sizeof(HSAint64);\n\n    // Alloc system memory from node 0 and initialize it\n    memFlags.ui32.NonPaged = 0;\n    memFlags.ui32.NoNUMABind = 1;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(0, PAGE_SIZE*2, memFlags, &mem[0]), gpuNode);\n    for (i = 0; i < 4*sizeof(HSAint64) + 4; i++) {\n        (reinterpret_cast<HSAuint8 *>(mem[0]))[i] = i;            // source\n        (reinterpret_cast<HSAuint8 *>(mem[0]))[PAGE_SIZE+i] = 0;  // destination\n    }\n\n    // Try to alloc local memory from GPU node\n    memFlags.ui32.NonPaged = 1;\n    if (pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(gpuNode)) {\n        EXPECT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, PAGE_SIZE*2 + (4 << 20),\n                                            memFlags, &mem[1]), gpuNode);\n        mem[1] = reinterpret_cast<void *>(reinterpret_cast<HSAuint8 *>(mem[1]) + VRAM_OFFSET);\n        for (i = 0; i < 4*sizeof(HSAint64) + 4; i++) {\n            (reinterpret_cast<HSAuint8 *>(mem[1]))[i] = i;\n            (reinterpret_cast<HSAuint8 *>(mem[1]))[PAGE_SIZE+i] = 0;\n        }\n    } else {\n        LOG() << \"Not testing local memory, it's invisible\" << std::endl;\n        mem[1] = NULL;\n    }\n\n    /* Allow any process to trace this one. If kernel is built without\n     * Yama, this is not needed, and this call will fail.\n     */\n#ifdef PR_SET_PTRACER\n    prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);\n#endif\n\n    pthread_mutex_lock(&ptrace_mtx);\n\n    // Find current pid so the child can trace it\n    pid_t tracePid = getpid();\n\n    // Fork the child\n    pid_t childPid = fork();\n    ASSERT_GE_GPU(childPid, 0, gpuNode);\n    if (childPid == 0) {\n        int traceStatus;\n        int err = 0, r;\n\n        /* Child process: we catch any exceptions to make sure we detach\n         * from the traced process, because terminating without detaching\n         * leaves the traced process stopped.\n         */\n        r = ptrace(PTRACE_ATTACH, tracePid, NULL, NULL);\n        if (r) {\n            WARN() << \"PTRACE_ATTACH failed: \" << r << std::endl;\n            exit(1);\n        }\n        try {\n            do {\n                waitpid(tracePid, &traceStatus, 0);\n            } while (!WIFSTOPPED(traceStatus));\n\n            for (i = 0; i < 4; i++) {\n                // Test 4 different (mis-)alignments, leaving 1-byte gaps between longs\n                HSAuint8 *addr = reinterpret_cast<HSAuint8 *>(reinterpret_cast<long *>(mem[0]) + i) + i;\n                errno = 0;\n                long data = ptrace(PTRACE_PEEKDATA, tracePid, addr, NULL);\n                EXPECT_EQ_GPU(0, errno, gpuNode);\n                EXPECT_EQ_GPU(0, ptrace(PTRACE_POKEDATA, tracePid, addr + PAGE_SIZE,\n                                    reinterpret_cast<void *>(data)), gpuNode);\n\n                if (mem[1] == NULL)\n                    continue;\n\n                addr = reinterpret_cast<HSAuint8 *>(reinterpret_cast<long *>(mem[1]) + i) + i;\n                errno = 0;\n                data = ptrace(PTRACE_PEEKDATA, tracePid, addr, NULL);\n                EXPECT_EQ_GPU(0, errno, gpuNode);\n                EXPECT_EQ_GPU(0, ptrace(PTRACE_POKEDATA, tracePid, addr + PAGE_SIZE,\n                                reinterpret_cast<void *>(data)), gpuNode);\n            }\n        } catch (...) {\n            err = 1;\n        }\n        r = ptrace(PTRACE_DETACH, tracePid, NULL, NULL);\n        if (r) {\n            WARN() << \"PTRACE_DETACH failed: \" << r << std::endl;\n            exit(1);\n        }\n        exit(err);\n    } else {\n        int childStatus;\n\n        // Parent process, just wait for the child to finish\n        EXPECT_EQ_GPU(childPid, waitpid(childPid, &childStatus, 0), gpuNode);\n        EXPECT_NE_GPU(0, WIFEXITED(childStatus), gpuNode);\n        EXPECT_EQ_GPU(0, WEXITSTATUS(childStatus), gpuNode);\n    }\n\n    pthread_mutex_unlock(&ptrace_mtx);\n\n    // Clear gaps in the source that should not have been copied\n    (reinterpret_cast<uint8_t*>(mem[0]))[  sizeof(long)    ] = 0;\n    (reinterpret_cast<uint8_t*>(mem[0]))[2*sizeof(long) + 1] = 0;\n    (reinterpret_cast<uint8_t*>(mem[0]))[3*sizeof(long) + 2] = 0;\n    (reinterpret_cast<uint8_t*>(mem[0]))[4*sizeof(long) + 3] = 0;\n    // Check results\n    EXPECT_EQ_GPU(0, memcmp(mem[0], reinterpret_cast<HSAuint8 *>(mem[0]) + PAGE_SIZE,\n                        sizeof(long)*4 + 4), gpuNode);\n    // Free memory\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(mem[0], PAGE_SIZE*2), gpuNode);\n\n    if (mem[1]) {\n        (reinterpret_cast<uint8_t*>(mem[1]))[  sizeof(HSAint64)    ] = 0;\n        (reinterpret_cast<uint8_t*>(mem[1]))[2*sizeof(HSAint64) + 1] = 0;\n        (reinterpret_cast<uint8_t*>(mem[1]))[3*sizeof(HSAint64) + 2] = 0;\n        (reinterpret_cast<uint8_t*>(mem[1]))[4*sizeof(HSAint64) + 3] = 0;\n        EXPECT_EQ_GPU(0, memcmp(mem[1], reinterpret_cast<HSAuint8 *>(mem[1]) + PAGE_SIZE,\n                            sizeof(HSAint64)*4 + 4), gpuNode);\n        mem[1] = reinterpret_cast<void *>(reinterpret_cast<HSAuint8 *>(mem[1]) - VRAM_OFFSET);\n        EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(mem[1], PAGE_SIZE*2), gpuNode);\n    }\n}\n\nTEST_F(KFDMemoryTest, PtraceAccess) {\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(PtraceAccess));\n\n    TEST_END\n}\n\nstatic void PtraceAccessInvisibleVram(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n\tAssembler* m_pAsm;\n\tm_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n\tASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    char *hsaDebug = getenv(\"HSA_DEBUG\");\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: There is no VRAM on APU.\" << std::endl;\n        return;\n    }\n\n    if (!hsaDebug || !strcmp(hsaDebug, \"0\")) {\n        LOG() << \"Skipping test: HSA_DEBUG environment variable not set.\" << std::endl;\n        return;\n    }\n\n    HsaMemMapFlags mapFlags = {0};\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    /* Allocate host not accessible vram */\n    memFlags.ui32.HostAccess = 0;\n    memFlags.ui32.NonPaged = 1;\n\n    void *mem, *mem0, *mem1;\n    unsigned size = PAGE_SIZE*2 + (4 << 20);\n    HSAuint64 data[2] = {0xdeadbeefdeadbeef, 0xcafebabecafebabe};\n    unsigned int data0[2] = {0xdeadbeef, 0xdeadbeef};\n    unsigned int data1[2] = {0xcafebabe, 0xcafebabe};\n\n    const HSAuint64 VRAM_OFFSET = (4 << 20) - sizeof(HSAuint64);\n\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, size, memFlags, &mem), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(mem, size, NULL,\n                                mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)), gpuNode);\n    /* Set the word before 4M boundary to 0xdeadbeefdeadbeef\n     * and the word after 4M boundary to 0xcafebabecafebabe\n     */\n    mem0 = reinterpret_cast<void *>(reinterpret_cast<HSAuint8 *>(mem) + VRAM_OFFSET);\n    mem1 = reinterpret_cast<void *>(reinterpret_cast<HSAuint8 *>(mem) + VRAM_OFFSET + sizeof(HSAuint64));\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket((unsigned int *)mem0,\n                                                  data0[0], data0[1]));\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket((unsigned int *)mem1,\n                                                  data1[0], data1[1]));\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, true, 0, 0));\n    queue.Wait4PacketConsumption();\n\n    /* Allow any process to trace this one. If kernel is built without\n     * Yama, this is not needed, and this call will fail.\n     */\n#ifdef PR_SET_PTRACER\n    prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);\n#endif\n\n    pthread_mutex_lock(&ptrace_mtx);\n\n    // Find out my pid so the child can trace it\n    pid_t tracePid = getpid();\n\n    // Fork the child\n    pid_t childPid = fork();\n    ASSERT_GE_GPU(childPid, 0, gpuNode);\n    if (childPid == 0) {\n        int traceStatus;\n        int err = 0, r;\n\n        /* Child process: we catch any exceptions to make sure we detach\n         * from the traced process, because terminating without detaching\n         * leaves the traced process stopped.\n         */\n        r = ptrace(PTRACE_ATTACH, tracePid, NULL, NULL);\n        if (r) {\n            WARN() << \"PTRACE_ATTACH failed: \" << r << std::endl;\n            exit(1);\n        }\n        try {\n            do {\n                waitpid(tracePid, &traceStatus, 0);\n            } while (!WIFSTOPPED(traceStatus));\n\n            /* Peek the memory */\n            errno = 0;\n            HSAint64 data0 = ptrace(PTRACE_PEEKDATA, tracePid, mem0, NULL);\n            EXPECT_EQ_GPU(0, errno, gpuNode);\n            EXPECT_EQ_GPU(data[0], data0, gpuNode);\n            HSAint64 data1 = ptrace(PTRACE_PEEKDATA, tracePid, mem1, NULL);\n            EXPECT_EQ_GPU(0, errno, gpuNode);\n            EXPECT_EQ_GPU(data[1], data1, gpuNode);\n\n            /* Swap mem0 and mem1 by poking */\n            EXPECT_EQ_GPU(0, ptrace(PTRACE_POKEDATA, tracePid, mem0, reinterpret_cast<void *>(data[1])), gpuNode);\n            EXPECT_EQ_GPU(0, errno, gpuNode);\n            EXPECT_EQ_GPU(0, ptrace(PTRACE_POKEDATA, tracePid, mem1, reinterpret_cast<void *>(data[0])), gpuNode);\n            EXPECT_EQ_GPU(0, errno, gpuNode);\n        } catch (...) {\n            err = 1;\n        }\n        r = ptrace(PTRACE_DETACH, tracePid, NULL, NULL);\n        if (r) {\n            WARN() << \"PTRACE_DETACH failed: \" << r << std::endl;\n            exit(1);\n        }\n        exit(err);\n    } else {\n        int childStatus;\n\n        // Parent process, just wait for the child to finish\n        EXPECT_EQ_GPU(childPid, waitpid(childPid, &childStatus, 0), gpuNode);\n        EXPECT_NE_GPU(0, WIFEXITED(childStatus), gpuNode);\n        EXPECT_EQ_GPU(0, WEXITSTATUS(childStatus), gpuNode);\n    }\n\n    pthread_mutex_unlock(&ptrace_mtx);\n\n    /* Use shader to read back data to check poke results */\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    // dstBuffer is cpu accessible gtt memory\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, gpuNode);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(ScratchCopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(mem0, dstBuffer.As<void*>());\n    dispatch0.Submit(queue);\n    dispatch0.Sync();\n    EXPECT_EQ_GPU(data1[0], dstBuffer.As<unsigned int*>()[0], gpuNode);\n\n    Dispatch dispatch1(isaBuffer);\n    dispatch1.SetArgs(mem1, dstBuffer.As<int*>());\n    dispatch1.Submit(queue);\n    dispatch1.Sync();\n    WaitOnValue(dstBuffer.As<uint32_t *>(), data0[0]);\n    EXPECT_EQ_GPU(data0[0], dstBuffer.As<unsigned int*>()[0], gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(mem), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(mem, size), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, PtraceAccessInvisibleVram) {\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(PtraceAccessInvisibleVram));\n\n    TEST_END\n}\n\nvolatile int IntrSignalReceviced;\n\nvoid CatchSignal(int IntrSignal) {\n    IntrSignalReceviced = IntrSignal;\n}\n\nstatic void SignalHandling(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Test not supported on APU.\" << std::endl;\n        return;\n    }\n\n    unsigned int *nullPtr = NULL;\n    unsigned int* pDb = NULL;\n    struct sigaction sa;\n    SDMAQueue queue;\n    HSAuint64 size, sysMemSize;\n\n    sa.sa_handler = CatchSignal;\n    sigemptyset(&sa.sa_mask);\n    sa.sa_flags = 0;\n    pid_t ParentPid = getpid();\n    EXPECT_EQ(0, sigaction(SIGUSR1, &sa, NULL)) << \"An error occurred while setting a signal handler\";\n\n    sysMemSize = pKFDMemoryTest->GetSysMemSize();\n\n    /* System (kernel) memory are limited to 3/8th System RAM\n     * Try to allocate 1/4th System RAM\n     */\n    size = (sysMemSize >> 2) & ~(HSAuint64)(PAGE_SIZE - 1);\n\n    /* We don't need a too large buffer for this test. If it is too large,\n     * on some platform, the upcoming hsaKmtAllocMemory() might fail. In\n     * order to avoid this flaky behavior, limit the size to 3G.\n     */\n    size = size > (3ULL << 30) ? (3ULL << 30) : size;\n\n    pKFDMemoryTest->GetHsaMemFlags().ui32.NoNUMABind = 1;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(0 /* system */, size, pKFDMemoryTest->GetHsaMemFlags(), reinterpret_cast<void**>(&pDb)), gpuNode);\n    // Verify that pDb is not null before it's being used\n    EXPECT_NE_GPU(nullPtr, pDb, gpuNode) << \"hsaKmtAllocMemory returned a null pointer\";\n\n    pid_t childPid = fork();\n    ASSERT_GE_GPU(childPid, 0, gpuNode);\n    if (childPid == 0) {\n        EXPECT_EQ_GPU(0, kill(ParentPid, SIGUSR1), gpuNode);\n        exit(0);\n    } else {\n        LOG() << \"Start Memory Mapping...\" << std::endl;\n        ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(pDb, size, NULL), gpuNode);\n        LOG() << \"Mapping finished\" << std::endl;\n        int childStatus;\n        pid_t pid;\n\n        // Parent process, just wait for the child to finish\n        do {\n            pid = waitpid(childPid, &childStatus, 0);\n            if (IntrSignalReceviced) {\n                LOG() << \"Interrupt Signal \" << std::dec << IntrSignalReceviced\n                    << \" Received\" << std::endl;\n                IntrSignalReceviced = 0;\n            }\n        } while(pid == -1 && errno == EINTR);\n        EXPECT_EQ_GPU(childPid, pid, gpuNode);\n        EXPECT_NE_GPU(0, WIFEXITED(childStatus), gpuNode);\n        EXPECT_EQ_GPU(0, WEXITSTATUS(childStatus), gpuNode);\n    }\n\n    pDb[0] = 0x02020202;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), pDb, 0x01010101) );\n    queue.Wait4PacketConsumption();\n    EXPECT_TRUE_GPU(WaitOnValue(pDb, 0x01010101), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(pDb), gpuNode);\n    // Release the buffers\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, size), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, SignalHandling) {\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SignalHandling));\n\n    TEST_END\n}\n\nstatic void CheckZeroInitializationSysMem(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    int ret;\n\n    int gpuNum = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU().size();\n\n\t/* if no gpu node */\n\tif (gpuNum <= 0)\n\t\treturn;\n\n    HSAuint64 sysMemSizeMB = pKFDMemoryTest->GetSysMemSize() >> 20;\n\n    /* Testing system memory */\n    HSAuint64 * pDb = NULL;\n\n    HSAuint64 sysBufSizeMB = sysMemSizeMB >> 2;\n    HSAuint64 sysBufSize = sysBufSizeMB * 1024 * 1024;\n\n\t/* use divided sys ram to test on each gpu to avoid sys ram OOM */\n\tHSAuint64 sysBufSizePerGPU = sysBufSize/gpuNum;\n\n    int count = 5;\n\n    LOG() << \"Using \" << std::dec << sysBufSizeMB\n            << \"MB system buffer to test \" << std::dec << count\n            << \" times\" << std::endl;\n\n    unsigned int offset = 257;  // a constant offset, should be smaller than 512.\n    unsigned int size = sysBufSizePerGPU / sizeof(*pDb);\n\n    pKFDMemoryTest->GetHsaMemFlags().ui32.NoNUMABind = 1;\n\n    while (count--) {\n        ret = hsaKmtAllocMemory(0 /* system */, sysBufSizePerGPU, pKFDMemoryTest->GetHsaMemFlags(),\n                                reinterpret_cast<void**>(&pDb));\n        if (ret) {\n            LOG() << \"Failed to allocate system buffer of\" << std::dec << sysBufSizeMB\n                    << \"MB\" << std::endl;\n            return;\n        }\n\n        /* Check the first 64 bits */\n        EXPECT_EQ_GPU(0, pDb[0], gpuNode);\n        pDb[0] = 1;\n\n        for (HSAuint64 i = offset; i < size;) {\n            EXPECT_EQ_GPU(0, pDb[i], gpuNode);\n            pDb[i] = i + 1;  // set it to non zero\n\n            i += 4096 / sizeof(*pDb);\n        }\n\n        /* check the last 64 bit */\n        EXPECT_EQ_GPU(0, pDb[size-1], gpuNode);\n        pDb[size-1] = size;\n\n        EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(pDb, sysBufSizePerGPU), gpuNode);\n    }\n}\n\nTEST_F(KFDMemoryTest, CheckZeroInitializationSysMem) {\n\tTEST_START(TESTPROFILE_RUNALL);\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CheckZeroInitializationSysMem));\n\n    TEST_END\n}\n\nstatic inline void access(volatile void *sd, int size, int rw) {\n    /* Most likely sitting in cache*/\n    static struct DUMMY {\n        char dummy[1024];\n    } dummy;\n\n    while ((size -= sizeof(dummy)) >= 0) {\n        if (rw == 0)\n            dummy = *(struct DUMMY *)((char*)sd + size);\n        else\n            *(struct DUMMY *)((char*)sd + size) = dummy;\n    }\n}\n\n/*\n * On large-bar system, test the visible vram access speed.\n * KFD is not allowed to alloc visible vram on non-largebar system.\n */\nstatic void MMBandWidth(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    unsigned nBufs = 1000; /* measure us, report ns */\n    unsigned testIndex, sizeIndex, memType;\n    const unsigned nMemTypes = 2;\n    const char *memTypeStrings[nMemTypes] = {\"SysMem\", \"VRAM\"};\n    const unsigned nSizes = 4;\n    const unsigned bufSizes[nSizes] = {PAGE_SIZE, PAGE_SIZE*4, PAGE_SIZE*16, PAGE_SIZE*64};\n    const unsigned nTests = nSizes * nMemTypes;\n    const unsigned tmpBufferSize = PAGE_SIZE*64;\n#define _TEST_BUFSIZE(index) (bufSizes[index % nSizes])\n#define _TEST_MEMTYPE(index) ((index / nSizes) % nMemTypes)\n\n    void *bufs[nBufs];\n    HSAuint64 start;\n    unsigned i;\n    HSAKMT_STATUS ret;\n    HsaMemFlags memFlags = {0};\n    HsaMemMapFlags mapFlags = {0};\n\n    HSAuint64 vramSizeMB = pKFDMemoryTest->GetVramSize(gpuNode) >> 20;\n\n    LOG() << \"Found VRAM of \" << std::dec << vramSizeMB << \"MB.\" << std::endl;\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(gpuNode) || !vramSizeMB) {\n        LOG() << \"Skipping test: Test requires a large bar GPU.\" << std::endl;\n        return;\n    }\n\n    void *tmp = mmap(0,\n            tmpBufferSize,\n            PROT_READ | PROT_WRITE,\n            MAP_ANONYMOUS | MAP_PRIVATE,\n            -1,\n            0);\n    EXPECT_NE_GPU(tmp, MAP_FAILED, gpuNode);\n    memset(tmp, 0, tmpBufferSize);\n\n    LOG() << \"Test (avg. ns)\\t  memcpyRTime memcpyWTime accessRTime accessWTime\" << std::endl;\n    for (testIndex = 0; testIndex < nTests; testIndex++) {\n        unsigned bufSize = _TEST_BUFSIZE(testIndex);\n        unsigned memType = _TEST_MEMTYPE(testIndex);\n        HSAuint64 mcpRTime, mcpWTime, accessRTime, accessWTime;\n        HSAuint32 allocNode;\n        unsigned bufLimit;\n\n        if ((testIndex & (nSizes-1)) == 0)\n            LOG() << \"----------------------------------------------------------------------\" << std::endl;\n\n        if (memType == 0) {\n            allocNode = 0;\n            memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n            memFlags.ui32.HostAccess = 1;\n            memFlags.ui32.NonPaged = 0;\n            memFlags.ui32.NoNUMABind = 1;\n        } else {\n            /* Alloc visible vram*/\n            allocNode = gpuNode;\n            memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n            memFlags.ui32.HostAccess = 1;\n            memFlags.ui32.NonPaged = 1;\n\n\t    /* Buffer sizes are 2MB aligned to match new allocation policy.\n\t     * Upper limit of buffer number to fit 80% vram size.\n\t     */\n            bufLimit = ((vramSizeMB << 20) * 8 / 10) / ALIGN_UP(bufSize, VRAM_ALLOCATION_ALIGN);\n            if (bufLimit == 0)\n                continue; // skip when bufSize > vram\n\n            /* When vram is too small to fit all the buffers, fill 80% vram size*/\n            nBufs = std::min(nBufs , bufLimit);\n        }\n\n        for (i = 0; i < nBufs; i++)\n            ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(allocNode, bufSize, memFlags,\n                        &bufs[i]), gpuNode);\n\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            memcpy(bufs[i], tmp, bufSize);\n        }\n        mcpWTime = GetSystemTickCountInMicroSec() - start;\n\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            access(bufs[i], bufSize, 1);\n        }\n        accessWTime = GetSystemTickCountInMicroSec() - start;\n\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            memcpy(tmp, bufs[i], bufSize);\n        }\n        mcpRTime = GetSystemTickCountInMicroSec() - start;\n\n        start = GetSystemTickCountInMicroSec();\n        for (i = 0; i < nBufs; i++) {\n            access(bufs[i], bufSize, 0);\n        }\n        accessRTime = GetSystemTickCountInMicroSec() - start;\n\n        for (i = 0; i < nBufs; i++)\n            EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(bufs[i], bufSize), gpuNode);\n\n        LOG() << std::dec\n            << std::right << std::setw(3) << (bufSize >> 10) << \"K-\"\n            << std::left << std::setw(14) << memTypeStrings[memType]\n            << std::right\n            << std::setw(12) << mcpRTime\n            << std::setw(12) << mcpWTime\n            << std::setw(12) << accessRTime\n            << std::setw(12) << accessWTime\n            << std::endl;\n\n#define MMBANDWIDTH_KEY_PREFIX memTypeStrings[memType] << \"-\" \\\n                               << (bufSize >> 10) << \"K\" << \"-\"\n        RECORD(mcpRTime) << MMBANDWIDTH_KEY_PREFIX << \"mcpRTime\";\n        RECORD(mcpWTime) << MMBANDWIDTH_KEY_PREFIX << \"mcpWTime\";\n        RECORD(accessRTime) << MMBANDWIDTH_KEY_PREFIX << \"accessRTime\";\n        RECORD(accessWTime) << MMBANDWIDTH_KEY_PREFIX << \"accessWTime\";\n\n        // skip slow tests\n        if (mcpRTime + mcpWTime + accessRTime + accessWTime > 5000000)\n            break;\n    }\n\n    munmap(tmp, tmpBufferSize);\n}\n\nTEST_F(KFDMemoryTest, MMBandWidth) {\n\tTEST_START(TESTPROFILE_RUNALL);\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MMBandWidth));\n\n    TEST_END\n}\n\n/* For the purpose of testing HDP flush from CPU.\n * Use CPU to write to coherent vram and check\n * from shader.\n * Asic before gfx9 doesn't support user space\n * HDP flush so only run on vega10 and after.\n * This should only run on large bar system.\n */\nstatic void HostHdpFlush(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n\tAssembler* m_pAsm;\n\tm_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n\tASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n\tHSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemFlags memoryFlags = pKFDMemoryTest->GetHsaMemFlags();\n    /* buffer[0]: signal; buffer[1]: Input to shader; buffer[2]: Output to\n     * shader\n     */\n    unsigned int *buffer = NULL;\n    const HsaNodeProperties *pNodeProperties = pKFDMemoryTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n    HSAuint32 *mmioBase = NULL;\n    unsigned int *nullPtr = NULL;\n\n    if (!pNodeProperties) {\n        LOG() << \"Failed to get gpu node properties.\" << std::endl;\n        return;\n    }\n\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << \"Skipping test: Test requires gfx9 and later asics.\" << std::endl;\n        return;\n    }\n    HSAuint64 vramSizeMB = pKFDMemoryTest->GetVramSize(gpuNode) >> 20;\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(gpuNode) || !vramSizeMB) {\n        LOG() << \"Skipping test: Test requires a large bar GPU.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n    EXPECT_SUCCESS_GPU(hsaKmtGetNodeMemoryProperties(gpuNode, pNodeProperties->NumMemoryBanks,\n                   memoryProperties), gpuNode);\n    for (unsigned int bank = 0; bank < pNodeProperties->NumMemoryBanks; bank++) {\n        if (memoryProperties[bank].HeapType == HSA_HEAPTYPE_MMIO_REMAP) {\n            mmioBase = (unsigned int *)memoryProperties[bank].VirtualBaseAddress;\n            break;\n        }\n    }\n\n    if (mmioBase == nullPtr) {\n            LOG() << \"Skipping test: bsecause mmioBase is nullPtr, the mmio remap feature is not supported.\" << std::endl;\n            return;\n    }\n\n    memoryFlags.ui32.NonPaged = 1;\n    memoryFlags.ui32.CoarseGrain = 0;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, memoryFlags,\n                   reinterpret_cast<void**>(&buffer)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(buffer, PAGE_SIZE, NULL), gpuNode);\n\n    /* Signal is dead from the beginning*/\n    buffer[0] = 0xdead;\n    buffer[1] = 0xfeeb;\n    buffer[2] = 0xfeed;\n    /* Submit a shader to poll the signal*/\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyOnSignalIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(buffer, NULL);\n    dispatch0.Submit(queue);\n\n    buffer[1] = 0xbeef;\n    /* Flush HDP */\n    mmioBase[KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL/4] = 0x1;\n    buffer[0] = 0xcafe;\n\n    /* Check test result*/\n    dispatch0.Sync();\n    mmioBase[KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL/4] = 0x1;\n    EXPECT_EQ_GPU(0xbeef, buffer[2], gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    delete [] memoryProperties;\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buffer), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(buffer, PAGE_SIZE), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, HostHdpFlush) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(HostHdpFlush));\n\n    TEST_END\n}\n\n/* Test HDP flush from device.\n * Use shader on device 1 to write vram of device 0\n * and flush HDP of device 0. Read vram from device 0\n * and write back to vram to check the result from CPU.\n * Asic before gfx9 doesn't support device HDP flush\n * so only run on vega10 and after.\n * This should only run on system with at least one\n * large bar node (which is used as device 0).\n */\nstatic void DeviceHdpFlush(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n\tAssembler* m_pAsm;\n\tm_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n\tASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n\tHSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n    HsaMemFlags memoryFlags = pKFDMemoryTest->GetHsaMemFlags();\n    /* buffer is physically on device 0.\n     * buffer[0]: Use as signaling b/t devices;\n     * buffer[1]: Device 1 write to buffer[1] and device 0 read it\n     * buffer[2]: Device 0 copy buffer[1] to buffer[2] for CPU to check\n     */\n    unsigned int *buffer = NULL;\n    const HsaNodeProperties *pNodeProperties;\n    HSAuint32 *mmioBase = NULL;\n    unsigned int *nullPtr = NULL;\n    std::vector<int> nodes;\n    int numPeers;\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n\n     /* Users can use \"--node=gpu1 --dst_node=gpu2\" to specify devices */\n    if (g_TestDstNodeId != -1 && g_TestNodeId != -1) {\n        nodes.push_back(g_TestNodeId);\n        nodes.push_back(g_TestDstNodeId);\n\n        if (!pKFDMemoryTest->Get_NodeInfo()->IsPeerAccessibleByNode(g_TestDstNodeId, g_TestNodeId)) {\n            LOG() << \"Skipping test: first GPU specified is not peer-accessible.\" << std::endl;\n            return;\n        }\n\n        if (nodes[0] == nodes[1]) {\n            LOG() << \"Skipping test: Different GPUs must be specified (2 GPUs required).\" << std::endl;\n            return;\n        }\n    } else {\n        pKFDMemoryTest->Get_NodeInfo()->FindAccessiblePeers(&nodes, gpuNode);\n        if (nodes.size() < 2) {\n            LOG() << \"Skipping test: Test requires at least one large bar GPU.\" << std::endl;\n            LOG() << \"               or two GPUs are XGMI connected.\" << std::endl;\n            return;\n        }\n    }\n\n    const HsaNodeProperties *pNodePropertiesDev1 = NULL;\n    unsigned int m_FamilyIdDev1 = 0;\n\n    pNodeProperties = pKFDMemoryTest->Get_NodeInfo()->GetNodeProperties(nodes[0]);\n    pNodePropertiesDev1 = pKFDMemoryTest->Get_NodeInfo()->GetNodeProperties(nodes[1]);\n    if (!pNodeProperties || !pNodePropertiesDev1) {\n        LOG() << \"Failed to get gpu node properties.\" << std::endl;\n        return;\n    }\n\n    m_FamilyIdDev1 = FamilyIdFromNode(pNodePropertiesDev1);\n\n    if (m_FamilyId < FAMILY_AI || m_FamilyIdDev1 < FAMILY_AI) {\n        LOG() << \"Skipping test: Test requires gfx9 and later asics.\" << std::endl;\n        return;\n    }\n\n    if (pKFDMemoryTest->Get_NodeInfo()->IsNodeXGMItoCPU(nodes[0])) {\n        LOG() << \"Skipping test: PCIe link to CPU is required.\" << std::endl;\n        return;\n    }\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(nodes[0])) {\n        LOG() << \"Skipping test: Test requires device 0 large bar GPU.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n    EXPECT_SUCCESS_GPU(hsaKmtGetNodeMemoryProperties(nodes[0], pNodeProperties->NumMemoryBanks,\n                   memoryProperties), gpuNode);\n    for (unsigned int bank = 0; bank < pNodeProperties->NumMemoryBanks; bank++) {\n        if (memoryProperties[bank].HeapType == HSA_HEAPTYPE_MMIO_REMAP) {\n            mmioBase = (unsigned int *)memoryProperties[bank].VirtualBaseAddress;\n            break;\n        }\n    }\n\n    if (mmioBase == nullPtr) {\n            LOG() << \"Skipping test: bsecause mmioBase is nullPtr, the mmio remap feature is not supported.\" << std::endl;\n            return;\n    }\n\n    memoryFlags.ui32.NonPaged = 1;\n    memoryFlags.ui32.CoarseGrain = 0;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(nodes[0], PAGE_SIZE, memoryFlags,\n                   reinterpret_cast<void**>(&buffer)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(buffer, PAGE_SIZE, NULL), gpuNode);\n\n    /* Signal is dead from the beginning*/\n    buffer[0] = 0xdead;\n    buffer[1] = 0xfeeb;\n    buffer[2] = 0xfeeb;\n    /* Submit shaders*/\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(nodes[0]), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, nodes[0], true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyOnSignalIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer, NULL);\n    dispatch.Submit(queue);\n\n    PM4Queue queue0;\n    ASSERT_SUCCESS_GPU(queue0.Create(nodes[1]), gpuNode);\n    HsaMemoryBuffer isaBuffer0(PAGE_SIZE, nodes[1], true/*zero*/, false/*local*/, true/*exec*/);\n\n    /* Temporarily set target ASIC for Dev1 */\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(WriteAndSignalIsa, isaBuffer0.As<char*>(),\n                        PAGE_SIZE, GetGfxVersion(pNodePropertiesDev1)), gpuNode);\n\n    Dispatch dispatch0(isaBuffer0);\n    dispatch0.SetArgs(buffer, mmioBase);\n    dispatch0.Submit(queue0);\n\n    /* Check test result*/\n    dispatch0.Sync();\n    dispatch.Sync();\n    EXPECT_EQ(0xbeef, buffer[2]);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(queue0.Destroy(), gpuNode);\n    delete [] memoryProperties;\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buffer), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(buffer, PAGE_SIZE), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, DeviceHdpFlush) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(DeviceHdpFlush));\n\n    TEST_END\n}\n\n/* Test should only run on Arcturus series which has the new RW mtype\n * Map a local VRAM with RW mtype (coarse grain for upper layer),\n * read it locally to cache it and write with local SDMA, remote devices(\n * CPU or Remote GPU shader connected with PCIe or XGMI),\n * then read again. The second read should get back what SDMA wrote,\n * since the cache should be invalidated on write and second read\n * should go to physical VRAM instead of cache.\n */\nstatic void CacheInvalidateOnSdmaWrite(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemoryBuffer tmpBuffer(PAGE_SIZE, 0, true /* zero */);\n    volatile HSAuint32 *tmp = tmpBuffer.As<volatile HSAuint32 *>();\n    const int dwLocation = 100;\n\n    if (m_FamilyId != FAMILY_AR) {\n        LOG() << \"Skipping test: Test requires arcturus series asics.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer buffer(PAGE_SIZE, gpuNode, false/*zero*/, true/*local*/, false/*exec*/);\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n    buffer.Fill(0, sdmaQueue, 0, PAGE_SIZE);\n    sdmaQueue.PlacePacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(), buffer.As<int*>(), 0x5678));\n\n    /* Read buffer from shader to fill cache */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollMemoryIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer.As<int*>(), buffer.As<int*>()+dwLocation);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* SDMA writes to buffer. Shader should get what sdma writes and quits*/\n    sdmaQueue.SubmitPacket();\n    sdmaQueue.Wait4PacketConsumption();\n\n    /* Check test result*/\n    dispatch.Sync();\n    EXPECT_EQ_GPU(buffer.IsPattern(dwLocation*sizeof(int), 0x5678, sdmaQueue, tmp), true, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, CacheInvalidateOnSdmaWrite) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CacheInvalidateOnSdmaWrite));\n\n    TEST_END\n}\n\nstatic void CacheInvalidateOnCPUWrite(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId != FAMILY_AR) {\n        LOG() << \"Skipping test: Test requires arcturus series asics.\" << std::endl;\n        return;\n    }\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsGPUNodeLargeBar(gpuNode)) {\n        LOG() << \"Skipping test: Test requires a large bar GPU.\" << std::endl;\n        return;\n    }\n\n    int *buffer;\n    HsaMemFlags memFlags = {0};\n    /* Host accessible vram */\n    memFlags.ui32.HostAccess = 1;\n    memFlags.ui32.NonPaged = 1;\n    memFlags.ui32.CoarseGrain = 1;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, memFlags, reinterpret_cast<void**>(&buffer)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(buffer, PAGE_SIZE, NULL), gpuNode);\n    *buffer = 0;\n\n    /* Read buffer from shader to fill cache */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollMemoryIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer, buffer+100);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* CPU writes to buffer. Shader should get what CPU writes and quits*/\n    *buffer = 0x5678;\n\n    /* Check test result*/\n    dispatch.Sync();\n    EXPECT_EQ_GPU(buffer[100], 0x5678, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buffer), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(buffer, PAGE_SIZE), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, CacheInvalidateOnCPUWrite) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CacheInvalidateOnCPUWrite));\n\n    TEST_END\n}\n\nstatic void CacheInvalidateOnRemoteWrite(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemoryBuffer tmpBuffer(PAGE_SIZE, 0, true /* zero */);\n    volatile HSAuint32 *tmp = tmpBuffer.As<volatile HSAuint32 *>();\n    const int dwLocation = 100;\n    const int dwLocation1 = 50;\n\n    if (m_FamilyId != FAMILY_AR) {\n        LOG() << \"Skipping test: Test requires arcturus series asics.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 nondefaultNode;\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        if (gpuNodes.at(i) != gpuNode) {\n            nondefaultNode = gpuNodes.at(i);\n            break;\n        }\n    }\n\n    HsaMemoryBuffer buffer(PAGE_SIZE, gpuNode, false/*zero*/, true/*local*/, false/*exec*/);\n    buffer.MapMemToNodes(&nondefaultNode, 1);\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n    buffer.Fill(0, sdmaQueue, 0, PAGE_SIZE);\n\n    /* Read buffer from shader to fill cache */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollMemoryIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer.As<int*>(), buffer.As<int*>()+dwLocation);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* Using a remote shader to copy data from dwLocation1 to the beginning of the buffer.\n     * Local shader should get what remote writes and quits\n     */\n    PM4Queue queue1;\n    ASSERT_SUCCESS_GPU(queue1.Create(nondefaultNode), gpuNode);\n    buffer.Fill(0x5678, sdmaQueue, dwLocation1*sizeof(int), 4);\n    HsaMemoryBuffer isaBuffer1(PAGE_SIZE, nondefaultNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch1(isaBuffer1);\n    dispatch1.SetArgs(buffer.As<int*>()+dwLocation1, buffer.As<int*>());\n    dispatch1.Submit(queue1);\n    dispatch1.Sync(g_TestTimeOut);\n\n    /* Check test result*/\n    dispatch.Sync();\n    EXPECT_EQ_GPU(buffer.IsPattern(dwLocation*sizeof(int), 0x5678, sdmaQueue, tmp), true, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(queue1.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, CacheInvalidateOnRemoteWrite) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CacheInvalidateOnRemoteWrite));\n\n    TEST_END\n}\n\n/* Test is for new cache coherence on Aldebaran. It is to verify\n * two GPUs can coherently share a fine grain FB.\n */\nstatic void VramCacheCoherenceWithRemoteGPU(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemoryBuffer tmpBuffer(PAGE_SIZE, 0, true /* zero */);\n    volatile HSAuint32 *tmp = tmpBuffer.As<volatile HSAuint32 *>();\n    const int dwSource = 0x40 * sizeof(int); /* At 3rd cache line */\n    const int dwLocation = 0x80 * sizeof(int); /* At 5th cache line  */\n\n    if (m_FamilyId != FAMILY_AL && m_FamilyId != FAMILY_AV) {\n        LOG() << \"Skipping test: Test requires aldebaran or aqua vanjaram series asics.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = pKFDMemoryTest->Get_NodeInfo()->GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 nondefaultNode;\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        if (gpuNodes.at(i) != gpuNode) {\n            nondefaultNode = gpuNodes.at(i);\n            break;\n        }\n    }\n\n    unsigned int nodes[2] = {(HSAuint32)gpuNode, nondefaultNode};\n\n    /* Allocate a local FB */\n    HsaMemoryBuffer buffer(PAGE_SIZE, gpuNode, false/*zero*/, true/*local*/, false/*exec*/);\n    buffer.MapMemToNodes(&nodes[0], 2);\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n    buffer.Fill(0, sdmaQueue, 0, PAGE_SIZE);\n    buffer.Fill(0x5678, sdmaQueue, dwSource, 4);\n\n    /* Read buffer[0] as flag from local shader to fill cache line (64 dws)\n     * which should has 0 at buffer[1]\n     */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollAndCopyIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer.As<char *>(), buffer.As<char *>()+dwLocation);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* Using remote shader to write the flag and copy value from dwSource\n     * to dwLocation in buffer.\n     * Local shader should get the flag and execute CopyMemory\n     */\n    PM4Queue queue1;\n    ASSERT_SUCCESS_GPU(queue1.Create(nondefaultNode), gpuNode);\n    HsaMemoryBuffer isaBuffer1(PAGE_SIZE, nondefaultNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(WriteFlagAndValueIsa, isaBuffer1.As<char*>()), gpuNode);\n\n    Dispatch dispatch1(isaBuffer1);\n    dispatch1.SetArgs(buffer.As<char *>(), buffer.As<char *>()+dwSource);\n    dispatch1.Submit(queue1);\n    dispatch1.Sync(g_TestTimeOut);\n\n    /* Check test result*/\n    dispatch.Sync(g_TestTimeOut);\n    EXPECT_EQ_GPU(buffer.IsPattern(dwLocation, 0x5678, sdmaQueue, tmp), true, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(queue1.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, VramCacheCoherenceWithRemoteGPU) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(VramCacheCoherenceWithRemoteGPU));\n\n    TEST_END\n}\n\n/* Test is for new cache coherence on A+A(Aldebaran). It is to verify\n * new XGMI coherence HW link in caches between CPU and GPUs\n * in local FB with fine grain mode.\n */\nstatic void VramCacheCoherenceWithCPU(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId != FAMILY_AL && m_FamilyId != FAMILY_AV) {\n        LOG() << \"Skipping test: Test requires aldebaran or aqua vanjaram series asics.\" << std::endl;\n        return;\n    }\n\n    const int dwLocation = 0x80;\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsNodeXGMItoCPU(gpuNode)) {\n        LOG() << \"Skipping test: XGMI link to CPU is required.\" << std::endl;\n        return;\n    }\n\n    unsigned int *buffer;\n    HsaMemFlags memFlags = {0};\n    /* Allocate a fine grain local FB accessed by CPU */\n    memFlags.ui32.HostAccess = 1;\n    memFlags.ui32.NonPaged = 1;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, memFlags,\n            reinterpret_cast<void**>(&buffer)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(buffer, PAGE_SIZE, NULL), gpuNode);\n    buffer[0] = 0;\n    buffer[dwLocation] = 0;\n\n    /* Read buffer from shader to fill cache */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollAndCopyIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(buffer, buffer+dwLocation);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* CPU writes to buffer. Shader should get 0x5678 CPU writes\n     * after cache invalidating(buffer_invl2) and quits\n     */\n    buffer[1] = 0x5678;\n    buffer[0] = 1;\n\n    /* Check test result*/\n    dispatch.Sync(g_TestTimeOut);\n    EXPECT_EQ_GPU(buffer[dwLocation], 0x5678, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buffer), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(buffer, PAGE_SIZE), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, VramCacheCoherenceWithCPU) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(VramCacheCoherenceWithCPU));\n\n    TEST_END\n}\n\n/* Test is for new cache coherence on Aldebaran. It is to verify\n * new XGMI coherence HW link in caches between CPU and GPUs\n * in system RAM.\n */\nstatic void SramCacheCoherenceWithGPU(KFDTEST_PARAMETERS* pTestParamters) {\n\n\tint gpuNode = pTestParamters->gpuNode;\n\tKFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 m_FamilyId = pKFDMemoryTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId != FAMILY_AL && m_FamilyId != FAMILY_AV) {\n        LOG() << \"Skipping test: Test requires aldebaran or aqua vanjaram series asics.\" << std::endl;\n        return;\n    }\n\n    const int dwLocation = 0x80;\n\n    if (!pKFDMemoryTest->Get_NodeInfo()->IsNodeXGMItoCPU(gpuNode)) {\n        LOG() << \"Skipping test: XGMI link to CPU is required.\" << std::endl;\n        return;\n    }\n\n    unsigned int *fineBuffer = NULL;\n    unsigned int tmp;\n\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(gpuNode /* system */, PAGE_SIZE, pKFDMemoryTest->GetHsaMemFlags(),\n                       reinterpret_cast<void**>(&fineBuffer)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(fineBuffer, PAGE_SIZE, NULL), gpuNode);\n    fineBuffer[0] = 0;\n    fineBuffer[1] = 0;\n    /* Read buffer from CPU to fill cache */\n    tmp = fineBuffer[dwLocation];\n\n    /* Read fine grain buffer from shader to fill cache */\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(PollAndCopyIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(fineBuffer, fineBuffer+dwLocation);\n    dispatch.Submit(queue);\n\n    /* Delay 100ms to make sure shader executed*/\n    Delay(100);\n\n    /* CPU writes to buffer. Shader should get what CPU writes and quits*/\n    fineBuffer[1] = 0x5678;\n    fineBuffer[0] = 1;\n\n    /* Check test result, based on KFDEventTest.SignalEvent passed.\n     * if Sync times out,\n     * it means coherence issue that GPU doesn't read what CPU wrote.\n     * if buffer value is not expected,\n     * it means coherence issue that CPU doesn't read what GPU wrote.\n     */\n    dispatch.Sync(g_TestTimeOut);\n    EXPECT_EQ_GPU(fineBuffer[dwLocation], 0x5678, gpuNode);\n\n    // Clean up\n    EXPECT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(fineBuffer), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtFreeMemory(fineBuffer, PAGE_SIZE), gpuNode);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, SramCacheCoherenceWithGPU) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SramCacheCoherenceWithGPU));\n\n    TEST_END\n}\n\nvoid KFDMemoryTest::AcquireReleaseTestRunCPU(HSAuint32 acquireNode, bool scalar) {\n\n    LOG() << \"Testing coherency from CPU to node \" << std::dec << acquireNode << std::endl;\n\n    /* Allocate shared buffer - must be at least 64 * 6 bytes */\n    HsaMemoryBuffer buffer(PAGE_SIZE, acquireNode, false/*zero*/, false/*local*/, false/*exec*/);\n    buffer.MapMemToNodes(&acquireNode, 1);\n\n    /* Allocate output buffer and insert magic numbers */\n    HsaMemoryBuffer outputBuffer(PAGE_SIZE, acquireNode, true, false, false);\n    outputBuffer.As<char *>()[0x40] = 99;\n    outputBuffer.As<char *>()[0x80] = 99;\n    outputBuffer.As<char *>()[0xc0] = 99;\n    outputBuffer.As<char *>()[0x100] = 99;\n    outputBuffer.As<char *>()[0x140] = 99;\n\n    /* Flush results of previous tests from the buffer */\n    /* This would be done with SDMA, but SDMA doesn't work on some Aqua Vanjaram emulators */\n    PM4Queue flushQueue;\n    ASSERT_SUCCESS(flushQueue.Create(acquireNode));\n    HsaMemoryBuffer flushBuffer(PAGE_SIZE, acquireNode, true/*zero*/, false/*local*/, true/*exec*/);\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(FlushBufferForAcquireReleaseIsa, flushBuffer.As<char*>()));\n    Dispatch flushDispatch(flushBuffer);\n    flushDispatch.SetArgs(buffer.As<char *>(), NULL);\n    flushDispatch.SetDim(1, 1, 1);\n    flushDispatch.Submit(flushQueue);\n    flushDispatch.Sync(g_TestTimeOut);\n\n    /* Start acquiring thread */\n    PM4Queue acquireQueue;\n    ASSERT_SUCCESS(acquireQueue.Create(acquireNode));\n    HsaMemoryBuffer acquireBuffer(PAGE_SIZE, acquireNode, true/*zero*/, false/*local*/, true/*exec*/);\n    if (!scalar)\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadAcquireVectorIsa, acquireBuffer.As<char*>()));\n    else\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadAcquireScalarIsa, acquireBuffer.As<char*>()));\n    Dispatch acquireDispatch(acquireBuffer);\n    acquireDispatch.SetArgs(buffer.As<char *>(), outputBuffer.As<char *>());\n    acquireDispatch.SetDim(1, 1, 1);\n    acquireDispatch.Submit(acquireQueue);\n\n    /* Delay 100ms to ensure acquirer is waiting */\n    Delay(100);\n\n    if (!scalar) {\n        buffer.As<char *>()[0x40] = 0x1;\n        buffer.As<char *>()[0x80] = 0x2;\n        buffer.As<char *>()[0xc0] = 0x3;\n        buffer.As<char *>()[0x100] = 0x4;\n        buffer.As<char *>()[0x140] = 0x5;\n    } else {\n        buffer.As<char *>()[0x40] = 0x6;\n        buffer.As<char *>()[0x80] = 0x7;\n        buffer.As<char *>()[0xc0] = 0x8;\n        buffer.As<char *>()[0x100] = 0x9;\n        buffer.As<char *>()[0x140] = 0xa;\n    }\n    buffer.As<char *>()[0x0] = 0x1;\n\n    acquireDispatch.Sync(g_TestTimeOut);\n\n    /* Check test result*/\n    if (!scalar) {\n        EXPECT_EQ(0x1, outputBuffer.As<char *>()[0x40]);\n        EXPECT_EQ(0x2, outputBuffer.As<char *>()[0x80]);\n        EXPECT_EQ(0x3, outputBuffer.As<char *>()[0xc0]);\n        EXPECT_EQ(0x4, outputBuffer.As<char *>()[0x100]);\n        EXPECT_EQ(0x5, outputBuffer.As<char *>()[0x140]);\n    } else {\n        EXPECT_EQ(0x6, outputBuffer.As<char *>()[0x40]);\n        EXPECT_EQ(0x7, outputBuffer.As<char *>()[0x80]);\n        EXPECT_EQ(0x8, outputBuffer.As<char *>()[0xc0]);\n        EXPECT_EQ(0x9, outputBuffer.As<char *>()[0x100]);\n        EXPECT_EQ(0xa, outputBuffer.As<char *>()[0x140]);\n    }\n\n    /*\n     * Guide to results:\n     * 0x99: acquiring shader did not write to output buffer at all\n     * 0x77: coherency error. Either releasing shader did not write or acquiring shader read stale value\n     * All five EXPECT_EQ fail: error occurs even when releasing shader bypasses cache\n     * Only first four EXPECT_EQ fail: error occurs only when releasing shader uses cache\n     */\n\n    /* Clean up */\n    EXPECT_SUCCESS(acquireQueue.Destroy());\n    EXPECT_SUCCESS(flushQueue.Destroy());\n}\n\nvoid KFDMemoryTest::AcquireReleaseTestRun(HSAuint32 acquireNode, HSAuint32 releaseNode,\n                                          bool localToRemote, bool scalar) {\n\n    LOG() << \"Testing coherency from node \" << std::dec << releaseNode << \" to node \" << std::dec << acquireNode << std::endl;\n\n    /* Allocate shared buffer - must be at least 64 * 6 bytes */\n    HSAuint32 localNode;\n    if (!localToRemote)\n        localNode = acquireNode;\n    else\n        localNode = releaseNode;\n    HsaMemoryBuffer buffer(PAGE_SIZE, localNode, false/*zero*/, true/*local*/, false/*exec*/);\n    unsigned int nodes[2] = {acquireNode, releaseNode};\n    buffer.MapMemToNodes(&nodes[0], 2);\n\n    /* Allocate output buffer and insert magic numbers */\n    HsaMemoryBuffer outputBuffer(PAGE_SIZE, acquireNode, true, false, false);\n    outputBuffer.As<char *>()[0x40] = 99;\n    outputBuffer.As<char *>()[0x80] = 99;\n    outputBuffer.As<char *>()[0xc0] = 99;\n    outputBuffer.As<char *>()[0x100] = 99;\n    outputBuffer.As<char *>()[0x140] = 99;\n\n    /* Flush results of previous tests from the buffer */\n    /* This would be done with SDMA, but SDMA doesn't work on some Aqua Vanjaram emulators */\n    PM4Queue flushQueue;\n    ASSERT_SUCCESS(flushQueue.Create(acquireNode));\n    HsaMemoryBuffer flushBuffer(PAGE_SIZE, acquireNode, true/*zero*/, false/*local*/, true/*exec*/);\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(FlushBufferForAcquireReleaseIsa, flushBuffer.As<char*>()));\n    Dispatch flushDispatch(flushBuffer);\n    flushDispatch.SetArgs(buffer.As<char *>(), NULL);\n    flushDispatch.SetDim(1, 1, 1);\n    flushDispatch.Submit(flushQueue);\n    flushDispatch.Sync(g_TestTimeOut);\n\n    /* Start acquiring thread */\n    PM4Queue acquireQueue;\n    ASSERT_SUCCESS(acquireQueue.Create(acquireNode));\n    HsaMemoryBuffer acquireBuffer(PAGE_SIZE, acquireNode, true/*zero*/, false/*local*/, true/*exec*/);\n    if (!scalar)\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadAcquireVectorIsa, acquireBuffer.As<char*>()));\n    else\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadAcquireScalarIsa, acquireBuffer.As<char*>()));\n    Dispatch acquireDispatch(acquireBuffer);\n    acquireDispatch.SetArgs(buffer.As<char *>(), outputBuffer.As<char *>());\n    acquireDispatch.SetDim(1, 1, 1);\n    acquireDispatch.Submit(acquireQueue);\n\n    /* Delay 100ms to ensure acquirer is waiting */\n    Delay(100);\n\n    /* Start releasing thread */\n    PM4Queue releaseQueue;\n    ASSERT_SUCCESS(releaseQueue.Create(releaseNode));\n    HsaMemoryBuffer releaseBuffer(PAGE_SIZE, releaseNode, true/*zero*/, false/*local*/, true/*exec*/);\n    if (!scalar)\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(WriteReleaseVectorIsa, releaseBuffer.As<char*>()));\n    else\n        ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(WriteReleaseScalarIsa, releaseBuffer.As<char*>()));\n    Dispatch releaseDispatch(releaseBuffer);\n    releaseDispatch.SetArgs(buffer.As<char *>(), NULL);\n    releaseDispatch.SetDim(1, 1, 1);\n    releaseDispatch.Submit(releaseQueue);\n\n    /* Wait for threads to finish */\n    releaseDispatch.Sync(g_TestTimeOut);\n    acquireDispatch.Sync(g_TestTimeOut);\n\n    /* Check test result*/\n    if (!scalar) {\n        EXPECT_EQ(0x1, outputBuffer.As<char *>()[0x40]);\n        EXPECT_EQ(0x2, outputBuffer.As<char *>()[0x80]);\n        EXPECT_EQ(0x3, outputBuffer.As<char *>()[0xc0]);\n        EXPECT_EQ(0x4, outputBuffer.As<char *>()[0x100]);\n        EXPECT_EQ(0x5, outputBuffer.As<char *>()[0x140]);\n    } else {\n        EXPECT_EQ(0x6, outputBuffer.As<char *>()[0x40]);\n        EXPECT_EQ(0x7, outputBuffer.As<char *>()[0x80]);\n        EXPECT_EQ(0x8, outputBuffer.As<char *>()[0xc0]);\n        EXPECT_EQ(0x9, outputBuffer.As<char *>()[0x100]);\n        EXPECT_EQ(0xa, outputBuffer.As<char *>()[0x140]);\n    }\n\n    /*\n     * Guide to results:\n     * 0x99: acquiring shader did not write to output buffer at all\n     * 0x77: coherency error. Either releasing shader did not write or acquiring shader read stale value\n     * All five EXPECT_EQ fail: error occurs even when releasing shader bypasses cache\n     * Only first four EXPECT_EQ fail: error occurs only when releasing shader uses cache\n     */\n\n    /* Clean up */\n    EXPECT_SUCCESS(acquireQueue.Destroy());\n    EXPECT_SUCCESS(releaseQueue.Destroy());\n    EXPECT_SUCCESS(flushQueue.Destroy());\n}\n\n/* A test of the memory coherence features on Aqua_Vanjaram.\n * One shader stores values at 5 positions in memory, then performs\n * a write-release. The other shader performs a read-acquire, then loads\n * those 5 values, then stores them in a CPU-visible buffer\n *\n * withinGPU: When true, the two shaders will be loaded onto two nodes within\n *            the same GPU. When false, the two shaders will be loaded onto different\n *            GPUs.\n *\n * localToRemote: When true, the shared memory will be local to the releasing node.\n *                When false, the shared memory will be local to the acquiring node.\n *\n * scalar: When true, the shared data will be stored and loaded with scalar instructions.\n *         When false, the shared data will be stored and loaded with vector instructions.\n */\nvoid KFDMemoryTest::AcquireReleaseTest(bool withinGPU, bool localToRemote, bool scalar) {\n\n    if (m_FamilyId != FAMILY_AV) {\n        LOG() << \"Skipping test: Test requires aqua vanjaram series asics.\" << std::endl;\n        return;\n    }\n\n    /* Find second node - nodes with the same DrmRenderMinor are on the same GPU */\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    HSAuint32 acquireNode;\n    HSAint32 acquireDRM;\n    bool foundSecondNode = false;\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        acquireNode = gpuNodes.at(i);\n        acquireDRM = m_NodeInfo.GetNodeProperties(acquireNode)->DrmRenderMinor;\n        for (unsigned j = 0; j < gpuNodes.size(); j++) {\n            if (!withinGPU) {\n                if (m_NodeInfo.GetNodeProperties(gpuNodes.at(j))->DrmRenderMinor != acquireDRM) {\n                    foundSecondNode = true;\n                    AcquireReleaseTestRun(acquireNode, gpuNodes.at(j), localToRemote, scalar);\n                }\n            } else {\n                if (m_NodeInfo.GetNodeProperties(gpuNodes.at(j))->DrmRenderMinor == acquireDRM && gpuNodes.at(j) != acquireNode) {\n                    foundSecondNode = true;\n                    AcquireReleaseTestRun(acquireNode, gpuNodes.at(j), localToRemote, scalar);\n                }\n            }\n        }\n    }\n    if (!foundSecondNode) {\n        if (!withinGPU) {\n            LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        } else {\n            LOG() << \"Skipping test: At least two nodes on the same GPU are required.\" << std::endl;\n        }\n\n    }\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseCPU) {\n    if (m_FamilyId != FAMILY_AV) {\n        LOG() << \"Skipping test: Test requires aqua vanjaram series asics.\" << std::endl;\n        return;\n    }\n\n    /* Find second node - nodes with the same DrmRenderMinor are on the same GPU */\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    HSAuint32 acquireNode;\n    for (unsigned i = 0; i < gpuNodes.size(); i++) {\n        acquireNode = gpuNodes.at(i);\n        AcquireReleaseTestRunCPU(acquireNode, true);\n        AcquireReleaseTestRunCPU(acquireNode, false);\n    }\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseFarLocalVector) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(false /* multi-GPU */, false /* acquirer is local */, false /* vector */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseFarLocalScalar) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(false /* multi-GPU */, false /* acquirer is local */, true /* scalar */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseFarRemoteVector) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(false /* multi-GPU */, true /* releaser is local */, false /* vector */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseFarRemoteScalar) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(false /* multi-GPU */, true /* releaser is local */, true /* scalar */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseCloseLocalVector) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(true /* within-GPU */, false /* acquirer is local */, false /* vector */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseCloseLocalScalar) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(true /* within-GPU */, false /* acquirer is local */, true /* scalar */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseCloseRemoteVector) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(true /* within-GPU */, true /* releaser is local */, false /* vector */);\n\n    TEST_END\n}\n\nTEST_F(KFDMemoryTest, AcquireReleaseCloseRemoteScalar) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    AcquireReleaseTest(true /* within-GPU */, true /* releaser is local */, true /* scalar */);\n\n    TEST_END\n}\n\n\n/* Application register same userptr to multiple GPUs using multiple threads\n * Test multiple threads register/deregister same userptr, to verify Thunk race handling\n */\nstruct ThreadParams {\n    void* pBuf;\n    HSAuint64 BufferSize;\n    HSAuint64 VAGPU;\n    pthread_barrier_t *barrier;\n};\nstatic unsigned int RegisterThread(void* p) {\n    struct ThreadParams* pArgs = reinterpret_cast<struct ThreadParams*>(p);\n\n    pthread_barrier_wait(pArgs->barrier);\n    EXPECT_SUCCESS(hsaKmtRegisterMemory(pArgs->pBuf, pArgs->BufferSize));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPU(pArgs->pBuf, pArgs->BufferSize, &pArgs->VAGPU));\n\n    return 0;\n}\nstatic unsigned int UnregisterThread(void* p) {\n    struct ThreadParams* pArgs = reinterpret_cast<struct ThreadParams*>(p);\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(reinterpret_cast<void *>(pArgs->VAGPU)));\n    pthread_barrier_wait(pArgs->barrier);\n    EXPECT_SUCCESS(hsaKmtDeregisterMemory(reinterpret_cast<void *>(pArgs->VAGPU)));\n\n    return 0;\n}\n\n#define N_THREADS   32\n\nTEST_F(KFDMemoryTest, MultiThreadRegisterUserptrTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    HSAuint32 test_loops = 1;\n    HSAuint64 BufferSize = 1UL << 27;\n\n    void *pBuf = mmap(NULL, BufferSize, PROT_READ | PROT_WRITE,\n                      MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    ASSERT_NE(pBuf, MAP_FAILED);\n\n    struct ThreadParams params[N_THREADS];\n    HSAuint64 threadId[N_THREADS];\n\n    pthread_barrier_t barrier;\n    ASSERT_SUCCESS(pthread_barrier_init(&barrier, NULL, N_THREADS));\n\n    for (HSAuint32 loop = 0; loop < test_loops; loop++) {\n        for (HSAuint32 i = 0; i < N_THREADS; i++) {\n            params[i].pBuf = pBuf;\n            params[i].BufferSize = BufferSize;\n            params[i].VAGPU = 0;\n            params[i].barrier = &barrier;\n        }\n\n        for (HSAuint32 i = 0; i < N_THREADS; i++)\n            ASSERT_EQ(true, StartThread(&RegisterThread, &params[i], threadId[i]));\n        for (HSAuint32 i = 0; i < N_THREADS; i++)\n            WaitForThread(threadId[i]);\n\n        for (HSAuint32 i = 0; i < N_THREADS; i++)\n            ASSERT_EQ(params[0].VAGPU, params[i].VAGPU);\n\n        for (HSAuint32 i = 0; i < N_THREADS; i++)\n            ASSERT_EQ(true, StartThread(&UnregisterThread, &params[i], threadId[i]));\n        for (HSAuint32 i = 0; i < N_THREADS; i++)\n            WaitForThread(threadId[i]);\n    }\n\n    pthread_barrier_destroy(&barrier);\n    munmap(pBuf, BufferSize);\n\n    TEST_END\n}\n\nstatic void ExportDMABufTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    if (pKFDMemoryTest->Get_Version()->KernelInterfaceMinorVersion < 12) {\n        LOG() << \"Skipping test, requires KFD ioctl version 1.12 or newer\" << std::endl;\n        return;\n    }\n\n    // Use a GTT BO for export because it's conveniently CPU accessible.\n    // On multi-GPU systems this also checks for interactions with driver-\n    // internal DMA buf use for DMA attachment to multiple GPUs\n    HsaMemFlags memFlags = pKFDMemoryTest->GetHsaMemFlags();\n    memFlags.ui32.NonPaged = 1;\n\n    HSAuint32 *buf;\n    ASSERT_SUCCESS_GPU(hsaKmtAllocMemory(0, PAGE_SIZE, memFlags,\n                                          reinterpret_cast<void**>(&buf)), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPU(buf, PAGE_SIZE, NULL), gpuNode);\n\n    for (int i = 0; i < PAGE_SIZE/4; i++)\n        buf[i] = i;\n    const HSAuint64 INDEX = 25;\n    const HSAuint64 SIZE = 25;\n    HSAuint64 offset;\n    int fd;\n\n    // Expected error: address out of range (not a BO)\n    ASSERT_EQ_GPU(HSAKMT_STATUS_INVALID_PARAMETER,\n            hsaKmtExportDMABufHandle(buf + PAGE_SIZE/4, SIZE*4, &fd, &offset), gpuNode);\n    // Expected error: size out of range\n    ASSERT_EQ_GPU(HSAKMT_STATUS_INVALID_PARAMETER,\n            hsaKmtExportDMABufHandle(buf + INDEX, PAGE_SIZE, &fd, &offset), gpuNode);\n\n    // For real this time. Check that the offset matches\n    ASSERT_SUCCESS_GPU(hsaKmtExportDMABufHandle(buf + INDEX, SIZE*4, &fd, &offset), gpuNode);\n    ASSERT_EQ_GPU(INDEX*4, offset, gpuNode);\n\n    // Free the original BO. The memory should persist as long as the DMA buf\n    // handle exists.\n    ASSERT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buf), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtFreeMemory(buf, PAGE_SIZE), gpuNode);\n\n    // Import the BO using the Interop API and check the contents. It doesn't\n    // map the import for CPU access, which gives us an excuse to test GPU\n    // mapping of the imported BO as well.\n    HsaGraphicsResourceInfo info;\n    ASSERT_SUCCESS_GPU(hsaKmtRegisterGraphicsHandleToNodes(fd, &info, 1, (HSAuint32 *)&gpuNode), gpuNode);\n    buf = reinterpret_cast<HSAuint32 *>(info.MemoryAddress);\n    ASSERT_EQ_GPU(info.SizeInBytes, PAGE_SIZE, gpuNode);\n\n    HsaMemMapFlags mapFlags = {0};\n    ASSERT_SUCCESS_GPU(hsaKmtMapMemoryToGPUNodes(buf, PAGE_SIZE, NULL, mapFlags, 1,\n                                             (HSAuint32 *)&gpuNode), gpuNode);\n\n    PM4Queue pm4Queue;\n    ASSERT_SUCCESS_GPU(pm4Queue.Create(gpuNode), gpuNode);\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, gpuNode);\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n    for (int i = 0; i < PAGE_SIZE/4; i++) {\n        Dispatch dispatch(isaBuffer);\n        dispatch.SetArgs(&buf[i], dstBuffer.As<void*>());\n        dispatch.Submit(pm4Queue);\n        dispatch.Sync(g_TestTimeOut);\n        ASSERT_EQ(i, *dstBuffer.As<HSAuint32 *>());\n    }\n    ASSERT_SUCCESS_GPU(pm4Queue.Destroy(), gpuNode);\n\n    ASSERT_SUCCESS_GPU(hsaKmtUnmapMemoryToGPU(buf), gpuNode);\n    ASSERT_SUCCESS_GPU(hsaKmtDeregisterMemory(buf), gpuNode);\n\n    ASSERT_EQ_GPU(0, close(fd), gpuNode);\n}\n\nTEST_F(KFDMemoryTest, ExportDMABufTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(ExportDMABufTest));\n\n    TEST_END\n}\n\nstatic void VA_VRAM_Only_AllocTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDMemoryTest* pKFDMemoryTest = (KFDMemoryTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDMemoryTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n   if (pKFDMemoryTest->Get_Version()->KernelInterfaceMinorVersion < 12) {\n        LOG() << \"Skipping test, requires KFD ioctl version 1.12 or newer\" << std::endl;\n        return;\n    }\n\n    HsaMemFlags memFlags = pKFDMemoryTest->GetHsaMemFlags();\n    memFlags.ui32.NonPaged = 1;\n    memFlags.ui32.HostAccess = 0;\n\n    HsaMemMapFlags mapFlags = {0};\n\n    HSAuint32 *buf;\n\n    /*alloc va without vram alloc*/\n    memFlags.ui32.OnlyAddress = 1;\n    ASSERT_SUCCESS(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, memFlags,\n                                          reinterpret_cast<void**>(&buf)));\n\n    /*mapping VA allocated by kfd api would fail*/\n    ASSERT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtMapMemoryToGPU(buf, PAGE_SIZE, NULL));\n    ASSERT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtMapMemoryToGPUNodes(buf, PAGE_SIZE, NULL,\n                               mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)));\n\n    ASSERT_SUCCESS(hsaKmtFreeMemory(buf, PAGE_SIZE));\n\n    /*alloc vram without va assigned*/\n    memFlags.ui32.OnlyAddress = 0;\n    memFlags.ui32.NoAddress = 1;\n    ASSERT_SUCCESS(hsaKmtAllocMemory(gpuNode, PAGE_SIZE, memFlags,\n                                      reinterpret_cast<void**>(&buf)));\n\n    /*mapping handle allocated by kfd API would fail*/\n    ASSERT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtMapMemoryToGPU(buf, PAGE_SIZE, NULL));\n    ASSERT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtMapMemoryToGPUNodes(buf, PAGE_SIZE, NULL,\n                               mapFlags, 1, reinterpret_cast<HSAuint32 *>(&gpuNode)));\n\n    ASSERT_SUCCESS(hsaKmtFreeMemory(buf, PAGE_SIZE));\n}\n\nTEST_F(KFDMemoryTest, VA_VRAM_Only_AllocTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n\tTEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(VA_VRAM_Only_AllocTest));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDMemoryTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDBaseComponentTest.hpp\"\n\n#ifndef __KFD_MEMORY_TEST__H__\n#define __KFD_MEMORY_TEST__H__\n\n/* @class KFDTopologyTest\n * This class has no additional features to KFDBaseComponentTest\n * The separation was made so we are able to group all memory tests together\n */\nclass KFDMemoryTest :  public KFDBaseComponentTest {\n public:\n    KFDMemoryTest(void) {}\n    ~KFDMemoryTest(void) {}\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n protected:\n    friend void SearchLargestBuffer(int allocNode, const HsaMemFlags &memFlags,\n                                            HSAuint64 highMB, int nodeToMap,\n                                            HSAuint64 *lastSizeMB);\n    void AcquireReleaseTestRunCPU(HSAuint32 acquireNode, bool scalar);\n    void AcquireReleaseTestRun(HSAuint32 acquireNode, HSAuint32 releaseNode,\n                                          bool localToRemote, bool scalar);\n    void AcquireReleaseTest(bool withinGPU, bool localToRemote, bool scalar);\n};\n\n#endif  // __KFD_MEMORY_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDMultiProcessTest.cpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDMultiProcessTest.hpp\"\n\nvoid KFDMultiProcessTest::ForkChildProcesses(unsigned int nodeId, int nprocesses) {\n    int i;\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(nodeId);\n\n    for (i = 0; i < nprocesses - 1; ++i) {\n        pid_t pid = fork();\n        ASSERT_GE(pid, 0);\n\n        if (pid == 0) {\n            /* Child process */\n            /* Cleanup file descriptors copied from parent process\n             * then call SetUp->hsaKmtOpenKFD to create new process\n             */\n            m_psName[gpuIndex] = \"Child Test process \" + std::to_string(i) +\n                          \" on gpuNode: \" + std::to_string(gpuIndex) + \" \";\n            TearDown();\n            SetUp();\n            m_ChildPids[gpuIndex].clear();\n            m_IsParent[gpuIndex] = false;\n            m_ProcessIndex[gpuIndex] = i;\n            return;\n        }\n\n        /* Parent process */\n        m_ChildPids[gpuIndex].push_back(pid);\n    }\n\n    m_psName[gpuIndex] = \"Parent Test process \" + std::to_string(i) +\n                        \" on gpuNode: \" + std::to_string(gpuIndex) + \" \";\n    m_ProcessIndex[gpuIndex] = i;\n}\n\nvoid KFDMultiProcessTest::WaitChildProcesses(unsigned int nodeId) {\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(nodeId);\n\n    if (m_IsParent[gpuIndex]) {\n        /* Only run by parent process */\n        int childStatus;\n        int childExitOkNum = 0;\n        int size = m_ChildPids[gpuIndex].size();\n\n        for (HSAuint32 i = 0; i < size; i++) {\n            pid_t pid = m_ChildPids[gpuIndex].front();\n\n            waitpid(pid, &childStatus, 0);\n            if (WIFEXITED(childStatus) == 1 && WEXITSTATUS(childStatus) == 0)\n                childExitOkNum++;\n\n            m_ChildPids[gpuIndex].erase(m_ChildPids[gpuIndex].begin());\n        }\n\n        EXPECT_EQ(childExitOkNum, size);\n    }\n\n    /* Child process or parent process finished successfully */\n    m_ChildStatus[gpuIndex] = HSAKMT_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDMultiProcessTest.hpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_MULTI_PROCESS_TEST__H__\n#define __KFD_MULTI_PROCESS_TEST__H__\n\n#include <string>\n#include <vector>\n#include \"KFDBaseComponentTest.hpp\"\n\n// @class KFDMultiProcessTest\n// Base class for tests forking multiple child processes\nclass KFDMultiProcessTest :  public KFDBaseComponentTest {\n public:\n    KFDMultiProcessTest(void) {\n        for ( int i = 0; i < MAX_GPU; i++) {\n            m_ChildStatus[i] = HSAKMT_STATUS_ERROR;\n            m_IsParent[i] = true;\n        }\n    }\n\n    ~KFDMultiProcessTest(void) {\n        for (int i = 0; i < MAX_GPU; i++) {\n            if (!m_IsParent[i]) {\n                /* Child process has to exit\n                 * otherwise gtest will continue other tests\n                */\n                exit(m_ChildStatus[i]);\n            }\n        }\n\n        try {\n            const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n            int gpu_node;\n            /* parent porcess waits all its child processes on each gpu */\n            for (int i = 0; i < std::min((int)gpuNodes.size(), MAX_GPU); i++) {\n                gpu_node = gpuNodes.at(i);\n                WaitChildProcesses(gpu_node);\n            }\n       } catch (...) {}\n\n    }\n\n protected:\n    void ForkChildProcesses(unsigned int nodeId, int nprocesses);\n    void WaitChildProcesses(unsigned int nodeId);\n\n protected:  // Members\n    std::string     m_psName[MAX_GPU];\n    int             m_ProcessIndex[MAX_GPU];\n    std::vector<pid_t> m_ChildPids[MAX_GPU];\n    HSAKMT_STATUS   m_ChildStatus[MAX_GPU];\n    bool            m_IsParent[MAX_GPU];\n};\n\n#endif  // __KFD_MULTI_PROCESS_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDNegativeTest.cpp",
    "content": "/*\n * Copyright (C) 2024 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDNegativeTest.hpp\"\n#include \"Dispatch.hpp\"\n#include <sys/ptrace.h>\n\nvoid KFDNegativeTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDNegativeTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\n/**\n *  Basic Pipe Reset Test\n *\n *  KFD pipe reset sequence:\n *  - on HWS preemption hang KFD will scan the device and find the blocked\n *    hardware queue slot.\n *  - KFD will attempt to queue reset.\n *  - Bad packet lengths should cause queue reset to fail and the KFD will\n *    automatically fall back to pipe reset.\n *  - KFD will verify success by checking blocked hardware slot is now unnoccupied.\n *  - KFD should only signal a reset exception to processes that have had queues\n *    reset.\n */\nTEST_F(KFDNegativeTest, BasicPipeReset) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    const HsaNodeProperties *nodeProps = m_NodeInfo.GetNodeProperties(defaultGPUNode);\n    bool perQueueResetSupported = nodeProps->Capability.ui32.PerQueueResetSupported;\n\n    if (perQueueResetSupported) {\n        int pipefd[2];\n        pipe(pipefd);\n\n        pid_t childPid = fork();\n\n        if (childPid == 0) {\n            // Refresh setup for HSA device and mem buffer use in child\n            KFDBaseComponentTest::TearDown();\n            KFDBaseComponentTest::SetUp();\n\n            HsaEvent *resetEvent;\n            ASSERT_SUCCESS(CreateHWExceptionEvent(false, false, defaultGPUNode, &resetEvent));\n\n            LOG() << \"Child ==> Wait on parent to set reset event\" << std::endl;\n            char buf;\n            read(pipefd[0], &buf, 1);\n\n            PM4Queue queue;\n            ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n            PM4ReleaseMemoryPacket packet = PM4ReleaseMemoryPacket(m_FamilyId, true, 0, 0, false, false, 1);\n            queue.PlaceAndSubmitPacket(packet);\n            LOG() << \"Child ==> Launching packet with bad header then dequeue\" << std::endl;\n            queue.Wait4PacketConsumption();\n            queue.Destroy();\n\n            // child expects hw exception event\n            EXPECT_SUCCESS(hsaKmtWaitOnEvent(resetEvent, g_TestTimeOut));\n            EXPECT_EQ(resetEvent->EventData.EventType, HSA_EVENTTYPE_HW_EXCEPTION);\n\n            LOG() << \"Child ==> Complete\" << std::endl;\n\n            exit(0);\n\t} else {\n            int childStatus = 0;\n\n            HsaEvent *resetEvent;\n\n            ASSERT_SUCCESS(CreateHWExceptionEvent(false, false, defaultGPUNode, &resetEvent));\n\n            char buf = 'x';\n            write(pipefd[1], &buf, 1);\n            LOG() << \"Parent ==> Wait on child to launch bad packet\" << std::endl;\n            waitpid(childPid, &childStatus, 0);\n\n            // parent process should not intercept reset event on child queue reset\n            EXPECT_NE(HSAKMT_STATUS_SUCCESS, hsaKmtWaitOnEvent(resetEvent, 100));\n\n            HsaMemoryBuffer destBuf(PAGE_SIZE, defaultGPUNode, false);\n            destBuf.Fill(0xFF);\n            HsaEvent *event;\n            ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &event));\n\n            PM4Queue queue;\n            ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n            LOG() << \"Parent ==> Submit queue packet to verify process is healthy\" << std::endl;\n            queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0, 0));\n            queue.Wait4PacketConsumption(event);\n            EXPECT_TRUE(WaitOnValue(destBuf.As<unsigned int*>(), 0));\n\n            hsaKmtDestroyEvent(event);\n            hsaKmtDestroyEvent(resetEvent);\n            EXPECT_SUCCESS(queue.Destroy());\n\n            LOG() << \"Parent ==> Complete\" << std::endl;\n\t}\n    } else {\n        LOG() << \"Skipping test: Family ID 0x\" << m_FamilyId << \" with per-queue reset support = \"\n              << perQueueResetSupported << std::endl;\n    }\n\n    TEST_END\n}\n\n/**\n * Basic SDMA Reset\n *\n * To check SDMA queue reset, launch a healthy SDMA queue and a bad SDMA queue with\n * dispatches per SDMA engine.\n * Similar to compute queue reset, only processes that have bad SDMA queues should\n * be reset, leaving healthy SDMA queue unaffected.\n *\n * The test forks two processes, where for every given engine, the parent process\n * enqueues a healthy queue while the child process enqueues a bad queue that triggers\n * the reset in the following sequence:\n *\n * - Parent/child communicates test status via pipe 1 & 2\n * - Child waits on pipe 1 read for parent to enqueue a queue on SDMA engine <n> with\n *   healthy poll and write packet.\n * - Parent waits on pipe 2 read for child to enqueue a queue on SDMA engine <n> with\n *   unhealthy write packet then destroy its queue to trigger reset on HWS hang.\n * - Child waits on pipe 1 for parent to confirm healthy poll and write packet\n *   complete on SDMA engine <n>.\n * - Child should verify it recieves a reset event, while the parent should not\n *   recieve a reset event.\n * - The parent/child test re-iterates again on SDMA engine <n+1>.\n */\nTEST_F(KFDNegativeTest, BasicSDMAReset) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    int gpuNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(gpuNode, 0) << \"failed to get default GPU Node\";\n\n    const HsaNodeProperties *nodeProps = m_NodeInfo.GetNodeProperties(gpuNode);\n    int totalEngines = nodeProps->NumSdmaEngines + nodeProps->NumSdmaXgmiEngines;\n    bool perSDMAQueueResetSupported = nodeProps->Capability2.ui32.PerSDMAQueueResetSupported;\n\n    if (perSDMAQueueResetSupported) {\n        int pipe1[2];\n        int pipe2[2];\n        pipe(pipe1);\n        pipe(pipe2);\n\n        LOG() << std::dec << \"Running SDMA queue reset on \" << totalEngines\n              <<\" SDMA engines\" << std::endl;\n\n        pid_t childPid = fork();\n\n        if (childPid == 0) {\n            KFDBaseComponentTest::TearDown();\n            KFDBaseComponentTest::SetUp();\n            close(pipe1[1]); // Close write end of pipe1\n            close(pipe2[0]); // Close read end of pipe2\n            HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n            unsigned int *dest = destBuf.As<unsigned int*>();\n            for (int i = 0; i < totalEngines; i++) {\n                HsaEvent *resetEvent;\n                ASSERT_SUCCESS(CreateHWExceptionEvent(false, false, gpuNode, &resetEvent));\n\n                // wait for parent to schedule healthy queue on engine\n                char buf1, buf2 ='0' + i;\n                read(pipe1[0], &buf1, 1);\n                ASSERT_EQ(buf1, buf2);\n\n                // submit bad queue and destroy to trigger reset\n                SDMAQueueByEngId queue(i);\n                ASSERT_SUCCESS(queue.Create(gpuNode));\n                queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), &dest[0], 0, 6));\n                Delay(50);\n                LOG() << std::dec << \"Reset SDMA queue on engine \" << i << std::endl;\n                queue.Destroy();\n\n                // child expects hw exception event\n                EXPECT_SUCCESS(hsaKmtWaitOnEvent(resetEvent, g_TestTimeOut));\n                EXPECT_EQ(resetEvent->EventData.EventType, HSA_EVENTTYPE_HW_EXCEPTION);\n                hsaKmtDestroyEvent(resetEvent);\n\n                // ack reset to parent and wait for parent to check healthy queue\n                write(pipe2[1], &buf2, 1);\n                read(pipe1[0], &buf1, 1);\n                ASSERT_EQ(buf1, buf2);\n            }\n\n            close(pipe1[0]);\n            close(pipe2[1]);\n            LOG() << \"Child ==> Complete\" << std::endl;\n            exit(0);\n        } else {\n            int childStatus = 0;\n            close(pipe1[0]); // Close read end of pipe1\n            close(pipe2[1]); // Close write end of pipe2\n\n            // parent process should not intercept reset event on child queue reset\n            HsaMemoryBuffer pollBuf(PAGE_SIZE, gpuNode, false);\n            HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n            unsigned int *poll = pollBuf.As<unsigned int*>();\n            unsigned int *dest = destBuf.As<unsigned int*>();\n            uint32_t targetDestValue = 0x12345678;\n\n            for (int i = 0; i < totalEngines; i++) {\n               poll[0] = 0;\n               dest[0] = 0;\n               HsaEvent *event;\n               HsaEvent *resetEvent;\n               ASSERT_SUCCESS(CreateHWExceptionEvent(false, false, gpuNode, &resetEvent));\n               ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, gpuNode, &event));\n\n               SDMAQueueByEngId queue(i);\n               ASSERT_SUCCESS(queue.Create(gpuNode));\n\n               // submit write on poll to maintain non-zero read/write pointer\n               // in engine during reset\n               queue.PlaceAndSubmitPacket(SDMAPollRegMemPacket(&poll[0], 1));\n               queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), &dest[0], targetDestValue));\n\n               // wait for for child to trigger reset on engine\n               char buf1 = '0' + i, buf2;\n               write(pipe1[1], &buf1, 1);\n               read(pipe2[0], &buf2, 1);\n               ASSERT_EQ(buf1, buf2);\n\n               // expect no reset event, then update poll to trigger write completion check\n               EXPECT_NE(HSAKMT_STATUS_SUCCESS, hsaKmtWaitOnEvent(resetEvent, 100));\n               poll[0] = 1;\n               queue.Wait4PacketConsumption();\n               EXPECT_TRUE(WaitOnValue(&dest[0], targetDestValue));\n               hsaKmtDestroyEvent(event);\n               hsaKmtDestroyEvent(resetEvent);\n               EXPECT_SUCCESS(queue.Destroy());\n               write(pipe1[1], &buf1, 1);\n            }\n\n            waitpid(childPid, &childStatus, 0);\n            close(pipe1[1]);\n            close(pipe2[0]);\n            LOG() << \"Parent ==> Complete\" << std::endl;\n        }\n    } else {\n        LOG() << \"Skipping test: Family ID 0x\" << m_FamilyId\n              << \" with per-sdma queue reset support = \"\n              << perSDMAQueueResetSupported << std::endl;\n    }\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDNegativeTest.hpp",
    "content": "/*\n * Copyright (C) 2024 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_NEGATIVE_TEST__H__\n#define __KFD_NEGATIVE_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"PM4Queue.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n#include \"SDMAQueueByEngId.hpp\"\n#include \"SDMAPacket.hpp\"\n\nclass KFDNegativeTest : public KFDBaseComponentTest {\n public:\n    KFDNegativeTest() {}\n    ~KFDNegativeTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_NEGATIVE_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDOpenCloseKFDTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDOpenCloseKFDTest.hpp\"\n#include \"KFDTestUtil.hpp\"\n\n// Before every test from this class fixture, open KFD\nvoid KFDOpenCloseKFDTest::SetUp() {\n    ROUTINE_START\n\n    ASSERT_SUCCESS(hsaKmtOpenKFD() );\n\n    ROUTINE_END\n}\n\n// After every test from this class fixture, close KFD\nvoid KFDOpenCloseKFDTest::TearDown() {\n    ROUTINE_START\n\n    EXPECT_SUCCESS(hsaKmtCloseKFD() );\n\n    ROUTINE_END\n}\n\n/* This test does not use class KFDOpenCloseKFDTest but is placed here\n * since it's testing same topic as other test\n * Verify that calling hsaKmtCloseKFD on a closed KFD will return right status\n */\nTEST(KFDCloseKFDTest, CloseAClosedKfd ) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_EQ(HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED, hsaKmtCloseKFD());\n\n    TEST_END\n}\n\n// Verify that calling hsaKmtCloseKFD on an already opened KFD will return right status\nTEST_F(KFDOpenCloseKFDTest, OpenAlreadyOpenedKFD ) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    EXPECT_EQ(HSAKMT_STATUS_KERNEL_ALREADY_OPENED, hsaKmtOpenKFD());\n\n    EXPECT_SUCCESS(hsaKmtCloseKFD());\n\n    TEST_END\n}\n\n// Testing the normal scenario: open followed by close (done in the setup and teardown functions)\nTEST_F(KFDOpenCloseKFDTest, OpenCloseKFD ) {\n}\n\nTEST_F(KFDOpenCloseKFDTest, InvalidKFDHandleTest ) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    HsaVersionInfo  m_VersionInfo;\n    pid_t m_ChildPid = fork();\n    if (m_ChildPid == 0) {\n        EXPECT_EQ(HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED, hsaKmtGetVersion(&m_VersionInfo));\n        exit(0);\n    } else {\n        int childStatus;\n        EXPECT_EQ(m_ChildPid, waitpid(m_ChildPid, &childStatus, 0));\n        EXPECT_NE(0, WIFEXITED(childStatus));\n        EXPECT_EQ(0, WEXITSTATUS(childStatus));\n    }\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDOpenCloseKFDTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <gtest/gtest.h>\n#include \"hsakmt/hsakmt.h\"\n\n#ifndef __KFD_OPEN_CLOSE_KFD_TEST__H__\n#define __KFD_OPEN_CLOSE_KFD_TEST__H__\n\n//  @class KFDOpenCloseKFDTest\nclass KFDOpenCloseKFDTest : public testing::Test {\n public:\n    KFDOpenCloseKFDTest(void) {}\n    ~KFDOpenCloseKFDTest(void) {}\n\n protected:\n    // @brief Executed before every test that uses KFDOpenCloseKFDTest class, sets all common settings for the tests.\n    virtual void SetUp();\n    // @brief Executed after every test that uses KFDOpenCloseKFDTest class\n    virtual void TearDown();\n};\n\n#endif  //  __KFD_OPEN_CLOSE_KFD_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPCSamplingTest.cpp",
    "content": "/*\n * Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDPCSamplingTest.hpp\"\n#include <sys/prctl.h>\n#include <sys/ptrace.h>\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <signal.h>\n#include <numa.h>\n#include <vector>\n#include \"Dispatch.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"hsakmt/linux/kfd_ioctl.h\"\n\n#define N_PROCESSES             (2)     /* Number of processes running in parallel, must be at least 2 */\n\n/* Captures user specified time (seconds) to sleep */\nextern unsigned int g_SleepTime;\n\nvoid KFDPCSamplingTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDPCSamplingTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nTEST_F(KFDPCSamplingTest, BasicTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (hsaKmtPcSamplingSupport() != HSAKMT_STATUS_SUCCESS)\n        return;\n\n    HSAuint32 num_sample_info = 0;\n    HSAuint32 return_num_sample_info = 0;\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"Failed to get default GPU Node.\";\n\n    /* 1. get pc sampling format numbe of entry */\n    HSAKMT_STATUS ret = hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, NULL,\n                                         num_sample_info, &return_num_sample_info);\n    if (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n        LOG() << \"Skipping test: This GPU does not support PC Sampling.\" << std::endl;\n        return;\n    }\n    ASSERT_GE(return_num_sample_info, 1);\n\n    num_sample_info = return_num_sample_info;\n    void *info_buf = calloc(num_sample_info, sizeof(HsaPcSamplingInfo));\n\n    ASSERT_SUCCESS(hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, info_buf,\n                                         num_sample_info, &return_num_sample_info));\n\n    HsaPcSamplingInfo *samples = (HsaPcSamplingInfo*) info_buf;\n    HsaPcSamplingTraceId traceId1, traceId2;\n\n    samples[0].value = 0x100000; /* 1,048,576 usec */\n\n    /* 1. Failed to start uncreated pc sampling ID */\n    ASSERT_SUCCESS(!hsaKmtPcSamplingStart(defaultGPUNode, 12345));\n\n    /* 2. Failed to stop uncreated pc sampling ID */\n    ASSERT_SUCCESS(!hsaKmtPcSamplingStop(defaultGPUNode, 12345));\n\n    /* 3. Failed to destroy uncreated pc sampling ID */\n    ASSERT_SUCCESS(!hsaKmtPcSamplingDestroy(defaultGPUNode, 12345));\n\n    /* 4. create pc sampling */\n    ASSERT_SUCCESS(hsaKmtPcSamplingCreate(defaultGPUNode, &samples[0], &traceId1));\n    ASSERT_SUCCESS(hsaKmtPcSamplingDestroy(defaultGPUNode, traceId1));\n\n    /* 5. create twice in the same process with pc sampling activated */\n    ASSERT_SUCCESS(hsaKmtPcSamplingCreate(defaultGPUNode, &samples[0], &traceId2));\n    ASSERT_SUCCESS(hsaKmtPcSamplingStart(defaultGPUNode, traceId2));\n          /* Creat and start 2nd session pc sampling */\n    ASSERT_SUCCESS(hsaKmtPcSamplingCreate(defaultGPUNode, &samples[0], &traceId1));\n    ASSERT_SUCCESS(hsaKmtPcSamplingStart(defaultGPUNode, traceId1));\n    sleep(2);\n          /* Stop its own pc sampling session, but another session still alive */\n    ASSERT_SUCCESS(hsaKmtPcSamplingStop(defaultGPUNode, traceId2));\n          /* Destroy its own pc sampling session when it is de-activated */\n    ASSERT_SUCCESS(hsaKmtPcSamplingDestroy(defaultGPUNode, traceId2));\n    sleep(1);\n    ASSERT_SUCCESS(hsaKmtPcSamplingDestroy(defaultGPUNode, traceId1));\n\n    free(info_buf);\n    TEST_END\n}\n\nstruct ThreadParams {\n    int test_num;\n    HSAuint32 GPUNode;\n    HsaPcSamplingInfo *samples;\n};\n\nstatic unsigned int PCSamplingThread(void* p) {\n    struct ThreadParams* pArgs = reinterpret_cast<struct ThreadParams*>(p);\n\n    LOG() << \"PCSamplingThread #\" << pArgs->test_num << \" start.\" << std::endl;\n    HsaPcSamplingTraceId traceId;\n\n    EXPECT_SUCCESS(hsaKmtPcSamplingCreate(pArgs->GPUNode, pArgs->samples, &traceId));\n    EXPECT_SUCCESS(hsaKmtPcSamplingStart(pArgs->GPUNode, traceId));\n    sleep(3);\n\n    LOG() << \"PCSamplingThread #\" << pArgs->test_num << \" stop.\" << std::endl;\n    EXPECT_SUCCESS(hsaKmtPcSamplingStop(pArgs->GPUNode, traceId));\n    EXPECT_SUCCESS(hsaKmtPcSamplingDestroy(pArgs->GPUNode, traceId));\n\n    return 0;\n}\n\nTEST_F(KFDPCSamplingTest, MultiThreadPcSamplingTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (hsaKmtPcSamplingSupport() != HSAKMT_STATUS_SUCCESS)\n        return;\n\n    HSAuint64 threadId[2];\n    struct ThreadParams params[2];\n    HSAuint32 num_sample_info = 0;\n    HSAuint32 return_num_sample_info = 0;\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"Failed to get default GPU Node\";\n\n    HSAKMT_STATUS ret = hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, NULL,\n                                         num_sample_info, &return_num_sample_info);\n    if (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n        LOG() << \"Skipping test: This GPU does not support PC Sampling.\" << std::endl;\n        return;\n    }\n    ASSERT_GE(return_num_sample_info, 1);\n\n    num_sample_info = return_num_sample_info;\n    void *info_buf = calloc(num_sample_info, sizeof(HsaPcSamplingInfo));\n\n    ASSERT_SUCCESS(hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, info_buf,\n                                         num_sample_info, &return_num_sample_info));\n    HsaPcSamplingInfo *samples = (HsaPcSamplingInfo*) info_buf;\n\n    samples[0].value = 0x100000; /* 1,048,576 usec */\n\n    params[0].test_num = 1;\n    params[1].test_num = 2;\n    params[0].GPUNode = defaultGPUNode;\n    params[1].GPUNode = defaultGPUNode;\n    params[0].samples = samples;\n    params[1].samples = samples;\n\n    ASSERT_EQ(true, StartThread(&PCSamplingThread, &params[0], threadId[0]));\n    sleep(1);\n    /* start 2nd thread after 1 sec */\n    ASSERT_EQ(true, StartThread(&PCSamplingThread, &params[1], threadId[1]));\n\n    WaitForThread(threadId[0]);\n    WaitForThread(threadId[1]);\n\n    free(info_buf);\n\n    TEST_END;\n}\n\nstruct ProcParams {\n    std::string test_name;\n    HSAuint32 GPUNode;\n    HsaPcSamplingInfo *samples;\n};\n\nstatic unsigned int PCSamplingProcRun(void* p) {\n    struct ProcParams* pArgs = reinterpret_cast<struct ProcParams*>(p);\n    bool process1_flag = !pArgs->test_name.compare(\"Test process 1 \");\n    int start_delay;\n\n    if (process1_flag)\n        start_delay = 0;\n    else\n        start_delay = 1;\n\n    LOG() << \"PCSamplingProc <\" << pArgs->test_name <<\n                 \"> starting after 0x\" <<  start_delay  << \" secs\" << std::endl;\n    sleep(start_delay);\n\n    HsaPcSamplingTraceId traceId = start_delay;\n\n    EXPECT_SUCCESS(hsaKmtPcSamplingCreate(pArgs->GPUNode, pArgs->samples, &traceId));\n    EXPECT_SUCCESS(hsaKmtPcSamplingStart(pArgs->GPUNode, traceId));\n    sleep(3);\n\n    LOG() << \"PCSamplingProc <\" << pArgs->test_name << \"> stop\" << std::endl;\n    EXPECT_SUCCESS(hsaKmtPcSamplingStop(pArgs->GPUNode, traceId));\n    EXPECT_SUCCESS(hsaKmtPcSamplingDestroy(pArgs->GPUNode, traceId));\n    LOG() << \"PCSamplingProc <\" << pArgs->test_name << \"> done\" << std::endl;\n\n    return 0;\n}\n\nTEST_F(KFDPCSamplingTest, MultiProcPcSamplingTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (hsaKmtPcSamplingSupport() != HSAKMT_STATUS_SUCCESS)\n        return;\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"Failed to get default GPU Node\";\n\n    HSAuint32 num_sample_info = 0;\n    HSAuint32 return_num_sample_info = 0;\n    struct ProcParams params;\n\n    params.GPUNode = defaultGPUNode;\n\n    HSAKMT_STATUS ret = hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, NULL,\n                                         num_sample_info, &return_num_sample_info);\n    if (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n        LOG() << \"Skipping test: This GPU does not support PC Sampling.\" << std::endl;\n        return;\n    }\n    ASSERT_GE(return_num_sample_info, 1);\n\n    num_sample_info = return_num_sample_info;\n    void *info_buf = calloc(num_sample_info, sizeof(HsaPcSamplingInfo));\n    ASSERT_SUCCESS(hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, info_buf,\n                                         num_sample_info, &return_num_sample_info));\n\n    HsaPcSamplingInfo *samples = (HsaPcSamplingInfo*) info_buf;\n\n    samples[0].value = 0x100000; /* 1,048,576 usec */\n\n    /* Fork the child processes */\n    ForkChildProcesses(defaultGPUNode, N_PROCESSES);\n\n    int rn = FindDRMRenderNode(defaultGPUNode);\n    if (rn < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU.\" << std::endl;\n        WaitChildProcesses(defaultGPUNode);\n        return;\n    }\n\n    params.samples = samples;\n\n    int gpuIndex = m_NodeInfo.HsaGPUindexFromGpuNode(defaultGPUNode);\n    params.test_name = m_psName[gpuIndex];\n\n    PCSamplingProcRun(&params);\n\n    WaitChildProcesses(defaultGPUNode);\n\n    if (info_buf)\n        free(info_buf);\n    TEST_END\n}\n\n/* Manully run multiple KFDPCSamplingTest.MultiProcPcSamplingTestM */\nTEST_F(KFDPCSamplingTest, MultiProcPcSamplingTestM) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (hsaKmtPcSamplingSupport() != HSAKMT_STATUS_SUCCESS)\n        return;\n\n    HSAuint32 num_sample_info = 0;\n    HSAuint32 return_num_sample_info = 0;\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"Failed to get default GPU Node\";\n\n    HSAKMT_STATUS ret = hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, NULL,\n                                         num_sample_info, &return_num_sample_info);\n    if (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n        LOG() << \"Skipping test: This GPU does not support PC Sampling.\" << std::endl;\n        return;\n    }\n    ASSERT_GE(return_num_sample_info, 1);\n\n    num_sample_info = return_num_sample_info;\n    void *info_buf = calloc(num_sample_info, sizeof(HsaPcSamplingInfo));\n    ASSERT_SUCCESS(hsaKmtPcSamplingQueryCapabilities(defaultGPUNode, info_buf,\n                                         num_sample_info, &return_num_sample_info));\n\n    HsaPcSamplingInfo *samples = (HsaPcSamplingInfo*) info_buf;\n    HsaPcSamplingTraceId traceId;\n\n    samples[0].value = 0x100000; /* 1,048,576 usec */\n    ASSERT_SUCCESS(hsaKmtPcSamplingCreate(defaultGPUNode, &samples[0], &traceId));\n\n    ASSERT_SUCCESS(hsaKmtPcSamplingStart(defaultGPUNode, traceId));\n    sleep(3);\n    ASSERT_SUCCESS(hsaKmtPcSamplingStop(defaultGPUNode, traceId));\n    ASSERT_SUCCESS(hsaKmtPcSamplingDestroy(defaultGPUNode, traceId));\n\n    free(info_buf);\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPCSamplingTest.hpp",
    "content": "/*\n * Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_PCSAMPLING_TEST__H__\n#define __KFD_PCSAMPLING_TEST__H__\n\n#include \"KFDMultiProcessTest.hpp\"\n\nclass KFDPCSamplingTest : public KFDMultiProcessTest {\n public:\n    KFDPCSamplingTest(void) {}\n    ~KFDPCSamplingTest(void) {}\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n protected:\n};\n\n#endif  // __KFD_PCSAMPLING_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPMTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDPMTest.hpp\"\n#include \"KFDTestUtil.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"hsakmt/hsakmt.h\"\n\nvoid KFDPMTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDPMTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nTEST_F(KFDPMTest, SuspendWithActiveProcess) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    EXPECT_EQ(true, SuspendAndWakeUp());\n\n    TEST_END\n}\n\nTEST_F(KFDPMTest, SuspendWithIdleQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    PM4Queue queue;\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n    EXPECT_EQ(true, SuspendAndWakeUp());\n\n    EXPECT_SUCCESS(queue.Destroy());\n\n    TEST_END\n}\n\nTEST_F(KFDPMTest, SuspendWithIdleQueueAfterWork) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    PM4Queue queue;\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    HsaMemoryBuffer destBuffer(PAGE_SIZE, defaultGPUNode);\n\n    ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n\n    HsaEvent *event;\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, defaultGPUNode, &event));\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuffer.As<unsigned int*>(), 0x1, 0x2));\n    queue.Wait4PacketConsumption(event);\n    WaitOnValue(&(destBuffer.As<unsigned int*>()[0]), 0x1);\n    WaitOnValue(&(destBuffer.As<unsigned int*>()[1]), 0x2);\n\n    destBuffer.Fill(0);\n\n    EXPECT_EQ(true, SuspendAndWakeUp());\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(&(destBuffer.As<unsigned int*>()[2]), 0x3, 0x4));\n    queue.Wait4PacketConsumption(event);\n\n    EXPECT_EQ(destBuffer.As<unsigned int*>()[0], 0);\n    EXPECT_EQ(destBuffer.As<unsigned int*>()[1], 0);\n\n    WaitOnValue(&(destBuffer.As<unsigned int*>()[2]), 0x3);\n    WaitOnValue(&(destBuffer.As<unsigned int*>()[3]), 0x4);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS(queue.Destroy());\n\n    TEST_END\n}\n\n// TODO: Suspend while workload is being executed by a queue\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPMTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFDPMTEST_HPP__\n#define __KFDPMTEST_HPP__\n\n#include <gtest/gtest.h>\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDPMTest : public KFDBaseComponentTest {\n public:\n    KFDPMTest() {}\n    ~KFDPMTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFDPMTEST_HPP__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPerfCounters.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDPerfCounters.hpp\"\n\nvoid KFDPerfCountersTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDPerfCountersTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic struct block_name_table {\n    char name[32];\n    HSA_UUID uuid;\n} block_lookup_table[] = {\n    {\"CB     \", {0x9ba429c6, 0xaf2d, 0x4b38, 0xb3, 0x49, 0x15, 0x72, 0x71, 0xbe, 0xac, 0x6a}},\n    {\"CPF    \", {0x2b0ad2b5, 0x1c43, 0x4f46, 0xa7, 0xbc, 0xe1, 0x19, 0x41, 0x1e, 0xa6, 0xc9}},\n    {\"CPG    \", {0x590ec94d, 0x20f0, 0x448f, 0x8d, 0xff, 0x31, 0x6c, 0x67, 0x9d, 0xe7, 0xff}},\n    {\"DB     \", {0x3d1a47fc, 0x0013, 0x4ed4, 0x83, 0x06, 0x82, 0x2c, 0xa0, 0xb7, 0xa6, 0xc2}},\n    {\"GDS    \", {0xf59276ec, 0x2526, 0x4bf8, 0x8e, 0xc0, 0x11, 0x8f, 0x77, 0x70, 0x0d, 0xc9}},\n    {\"GRBM   \", {0x8f00933c, 0xc33d, 0x4801, 0x97, 0xb7, 0x70, 0x07, 0xf7, 0x85, 0x73, 0xad}},\n    {\"GRBMSE \", {0x34ebd8d7, 0x7c8b, 0x4d15, 0x88, 0xfa, 0x0e, 0x4e, 0x4a, 0xf5, 0x9a, 0xc1}},\n    {\"IA     \", {0x34276944, 0x4264, 0x4fcd, 0x9d, 0x6e, 0xae, 0x26, 0x45, 0x82, 0xec, 0x51}},\n    {\"MC     \", {0x13900b57, 0x4956, 0x4d98, 0x81, 0xd0, 0x68, 0x52, 0x19, 0x37, 0xf5, 0x9c}},\n    {\"PASC   \", {0xb0e7fb5d, 0x0efc, 0x4744, 0xb5, 0x16, 0x5d, 0x23, 0xdc, 0x1f, 0xd5, 0x6c}},\n    {\"PASU   \", {0x9a152b6a, 0x1fad, 0x45f2, 0xa5, 0xbf, 0xf1, 0x63, 0x82, 0x6b, 0xd0, 0xcd}},\n    {\"SPI    \", {0xeda81044, 0xd62c, 0x47eb, 0xaf, 0x89, 0x4f, 0x6f, 0xbf, 0x3b, 0x38, 0xe0}},\n    {\"SRBM   \", {0x9f8040e0, 0x6830, 0x4019, 0xac, 0xc8, 0x46, 0x3c, 0x9e, 0x44, 0x5b, 0x89}},\n    {\"SQ     \", {0xb5c396b6, 0xd310, 0x47e4, 0x86, 0xfc, 0x5c, 0xc3, 0x4, 0x3a, 0xf5, 0x8}},\n    {\"SX     \", {0xbdb8d737, 0x43cc, 0x4162, 0xbe, 0x52, 0x51, 0xcf, 0xb8, 0x47, 0xbe, 0xaf}},\n    {\"TA     \", {0xc01ee43d, 0xad92, 0x44b1, 0x8a, 0xb9, 0xbe, 0x5e, 0x69, 0x6c, 0xee, 0xa7}},\n    {\"TCA    \", {0x333e393f, 0xe147, 0x4f49, 0xa6, 0xd1, 0x60, 0x91, 0x4c, 0x70, 0x86, 0xb0}},\n    {\"TCC    \", {0x848ce855, 0xd805, 0x4566, 0xa8, 0xab, 0x73, 0xe8, 0x84, 0xcc, 0x6b, 0xff}},\n    {\"TCP    \", {0xe10a013b, 0x17d4, 0x4bf5, 0xb0, 0x89, 0x42, 0x95, 0x91, 0x05, 0x9b, 0x60}},\n    {\"TCS    \", {0x4126245c, 0x4d96, 0x4d1a, 0x8a, 0xed, 0xa9, 0x39, 0xd4, 0xcc, 0x8e, 0xc9}},\n    {\"TD     \", {0x7d7c0fe4, 0xfe41, 0x4fea, 0x92, 0xc9, 0x45, 0x44, 0xd7, 0x70, 0x6d, 0xc6}},\n    {\"VGT    \", {0x0b6a8cb7, 0x7a01, 0x409f, 0xa2, 0x2c, 0x30, 0x14, 0x85, 0x4f, 0x13, 0x59}},\n    {\"WD     \", {0x0e176789, 0x46ed, 0x4b02, 0x97, 0x2a, 0x91, 0x6d, 0x2f, 0xac, 0x24, 0x4a}},\n    {\"DRIVER \", {0xea9b5ae1, 0x6c3f, 0x44b3, 0x89, 0x54, 0xda, 0xf0, 0x75, 0x65, 0xa9, 0xa}}\n};\n\nstatic void GetBlockName(HSA_UUID uuid, char *name, uint32_t name_len,\n                                       char *uuid_str, uint32_t uuid_str_len) {\n    uint32_t i, table_size;\n\n    table_size = sizeof(block_lookup_table) / sizeof(struct block_name_table);\n\n    snprintf(name, name_len, \"unknown\");\n    for (i = 0; i < table_size; i++) {\n        if (!memcmp(&block_lookup_table[i].uuid, &uuid, sizeof(HSA_UUID))) {\n            if (name)\n                snprintf(name, name_len, \"%s\", block_lookup_table[i].name);\n            break;\n        }\n    }\n\n    if (uuid_str)\n        snprintf(uuid_str, uuid_str_len,\n                 \"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\",\n                 uuid.Data1, uuid.Data2, uuid.Data3,\n                 uuid.Data4[0], uuid.Data4[1], uuid.Data4[2],\n                 uuid.Data4[3], uuid.Data4[4], uuid.Data4[5],\n                 uuid.Data4[6], uuid.Data4[7]);\n}\n\nstatic void GetCounterProperties(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDPerfCountersTest* pKFDPerfCountersTest =\n                         (KFDPerfCountersTest*)pTestParamters->pTestObject;\n\n    HsaCounterProperties* pProps = NULL;\n    ASSERT_SUCCESS(hsaKmtPmcGetCounterProperties(gpuNode, &pProps));\n    /* Verifying that there is at least one block */\n    ASSERT_NE(0, pProps->NumBlocks) << \"No performance counters blocks\";\n\n    LOG() << std::dec << pProps->NumBlocks << \" blocks found.\" << std::endl;\n\n    HsaCounterBlockProperties *block;\n    block = &pProps->Blocks[0];\n    for (HSAuint32 i = 0; i < pProps->NumBlocks; i++) {\n        char uuid_string[37] = \"\";\n        char name[32] = \"\";\n        GetBlockName(block->BlockId, name, 32, uuid_string, 37);\n\n        char type[32];\n        switch (block->Counters[0].Type) {\n        case HSA_PROFILE_TYPE_PRIVILEGED_IMMEDIATE:\n            snprintf(type, sizeof(type), \"Priv Immediate\");\n            break;\n        case HSA_PROFILE_TYPE_PRIVILEGED_STREAMING:\n            snprintf(type, sizeof(type), \"Priv Streaming\");\n            break;\n        case HSA_PROFILE_TYPE_NONPRIV_IMMEDIATE:\n            snprintf(type, sizeof(type), \"Non-priv Immediate\");\n            break;\n        case HSA_PROFILE_TYPE_NONPRIV_STREAMING:\n            snprintf(type, sizeof(type), \"Non-priv Immediate\");\n            break;\n        default:\n            snprintf(type, sizeof(type), \"Unknown\");\n            break;\n        }\n\n        LOG() << name << \" (\" << uuid_string << \"): \" << type << \", \" <<\n            block->NumCounters << \" counter IDs\" << std::endl;\n        block = reinterpret_cast<HsaCounterBlockProperties *>(&block->Counters[block->NumCounters]);\n    }\n}\n\nTEST_F(KFDPerfCountersTest, GetCounterProperties) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(GetCounterProperties));\n\n    TEST_END\n}\n\nstatic void RegisterTrace(KFDTEST_PARAMETERS* pTestParamters) {\n\n    HsaCounterProperties* pProps;\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDPerfCountersTest* pKFDPerfCountersTest =\n                         (KFDPerfCountersTest*)pTestParamters->pTestObject;\n\n    HsaPmcTraceRoot root;\n\n    pProps = NULL;\n    ASSERT_SUCCESS(hsaKmtPmcGetCounterProperties(gpuNode, &pProps));\n\n    /* Verifying that there is at least one block */\n    ASSERT_NE(0, pProps->NumBlocks) << \"No performance counters blocks\";\n\n    HsaCounterBlockProperties *block = &pProps->Blocks[0];\n    bool priv_block_found = false;\n    for (HSAuint32 i = 0; i < pProps->NumBlocks; i++) {\n        if (block->Counters[0].Type <= HSA_PROFILE_TYPE_PRIVILEGED_STREAMING) {\n            priv_block_found = true;\n            break;\n        }\n        block = reinterpret_cast<HsaCounterBlockProperties *>(&block->Counters[block->NumCounters]);\n    }\n\n    if (!priv_block_found) {\n        LOG() << \"Skipping test: No privileged block is found.\"\n            << std::endl;\n        return;\n    }\n\n    /* Registering trace */\n    ASSERT_SUCCESS(hsaKmtPmcRegisterTrace(gpuNode,\n                                          block->NumConcurrent,\n                                          block->Counters,\n                                          &root));\n    EXPECT_SUCCESS(hsaKmtPmcUnregisterTrace(gpuNode, root.TraceId));\n}\n\nTEST_F(KFDPerfCountersTest, RegisterTrace) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(RegisterTrace));\n\n    TEST_END\n}\n\nstatic const unsigned int START_STOP_DELAY = 10000;     // 10 sec tracing\n\nstatic void StartStopQueryTrace(KFDTEST_PARAMETERS* pTestParamters){\n\n    HsaPmcTraceRoot root;\n    HsaCounterProperties* pProps;\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDPerfCountersTest* pKFDPerfCountersTest =\n                         (KFDPerfCountersTest*)pTestParamters->pTestObject;\n\n    pProps = NULL;\n    ASSERT_SUCCESS(hsaKmtPmcGetCounterProperties(gpuNode, &pProps));\n\n    /* Verifying that there is at least one block */\n    ASSERT_NE(0, pProps->NumBlocks) << \"No performance counters blocks\";\n\n    HsaCounterBlockProperties *block = &pProps->Blocks[0];\n    bool priv_block_found = false;\n    for (HSAuint32 i = 0; i < pProps->NumBlocks; i++) {\n        if (block->Counters[0].Type <= HSA_PROFILE_TYPE_PRIVILEGED_STREAMING) {\n            priv_block_found = true;\n            break;\n        }\n        block = reinterpret_cast<HsaCounterBlockProperties *>(&block->Counters[block->NumCounters]);\n    }\n\n    if (!priv_block_found) {\n        LOG() << \"Skipping test: No privileged block is found.\"\n             << std::endl;\n        return;\n    }\n\n    if (getuid()) { /* Non-root */\n        LOG() << \"Skipping test: Privileged counters requires the user as root.\" << std::endl;\n        return;\n    }\n\n    /* Registering trace */\n    ASSERT_SUCCESS(hsaKmtPmcRegisterTrace(gpuNode,\n                                          block->NumConcurrent,\n                                          block->Counters,\n                                          &root));\n\n    /* Acquiring access for the trace */\n    ASSERT_SUCCESS(hsaKmtPmcAcquireTraceAccess(gpuNode, root.TraceId));\n\n    /* Allocating memory buffer for the trace */\n    HsaMemoryBuffer membuf(PAGE_SIZE, gpuNode);\n\n    /* Starting the trace */\n    ASSERT_SUCCESS(hsaKmtPmcStartTrace(root.TraceId,\n                                       membuf.As<void*>(),\n                                       membuf.Size()));\n\n    /* Delay between START and STOP tracing */\n    Delay(START_STOP_DELAY);\n\n    /* Stopping the trace */\n    ASSERT_SUCCESS(hsaKmtPmcStopTrace(root.TraceId));\n\n    /* Querying the trace */\n    ASSERT_SUCCESS(hsaKmtPmcQueryTrace(root.TraceId));\n    uint64_t *buf = membuf.As<uint64_t*>();\n    for (uint32_t i = 0; i < block->NumConcurrent; i++, buf++)\n        LOG() << \"Counter \" << std::dec << i << \": \" << *buf << std::endl;\n\n    /* Releasing the trace */\n    EXPECT_SUCCESS(hsaKmtPmcReleaseTraceAccess(0, root.TraceId));\n\n    EXPECT_SUCCESS(hsaKmtPmcUnregisterTrace(gpuNode, root.TraceId));\n}\n\nTEST_F(KFDPerfCountersTest, StartStopQueryTrace) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(RegisterTrace));\n\n    TEST_END\n}\n\nstatic void ClockCountersBasicTest(KFDTEST_PARAMETERS* pTestParamters){\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDPerfCountersTest* pKFDPerfCountersTest =\n\t\t\t\t\t  (KFDPerfCountersTest*)pTestParamters->pTestObject;\n\n    HsaClockCounters counters1;\n    HsaClockCounters counters2;\n\n    EXPECT_SUCCESS(hsaKmtGetClockCounters(gpuNode, &counters1));\n\n    Delay(100);\n\n    EXPECT_SUCCESS(hsaKmtGetClockCounters(gpuNode, &counters2));\n\n    EXPECT_NE(0, counters1.GPUClockCounter);\n    EXPECT_NE(0, counters2.GPUClockCounter);\n    EXPECT_NE(0, counters1.SystemClockCounter);\n    EXPECT_NE(0, counters2.SystemClockCounter);\n\n    EXPECT_GT(counters2.GPUClockCounter, counters1.GPUClockCounter);\n    EXPECT_GT(counters2.SystemClockCounter, counters1.SystemClockCounter);\n\n}\n\nTEST_F(KFDPerfCountersTest, ClockCountersBasicTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(ClockCountersBasicTest));\n\n    TEST_END\n}\n\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPerfCounters.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFDPERFCOUNTERS_HPP__\n#define __KFDPERFCOUNTERS_HPP__\n\n#include <gtest/gtest.h>\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDPerfCountersTest : public KFDBaseComponentTest {\n public:\n    KFDPerfCountersTest() {}\n    ~KFDPerfCountersTest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFDPERFCOUNTERS_HPP__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDPerformanceTest.cpp",
    "content": "/*\n * Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n#include <sys/time.h>\n#include <vector>\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"AqlQueue.hpp\"\n#include \"KFDTestUtilQueue.hpp\"\n#include <algorithm>\n#include <gtest/gtest.h>\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDPerformanceTest: public KFDBaseComponentTest {\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\nvoid KFDPerformanceTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDPerformanceTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nenum P2PDirection {\n    IN = 1,\n    OUT = 2,\n    IN_OUT = 3,\n    NONE = 4,\n};\n\n/*\n * Do the copy of one GPU from & to multiple GPUs.\n */\nstatic void\ntestNodeToNodes(HSAuint32 n1, const HSAuint32 *const n2Array, int n, P2PDirection n1Direction,\n        P2PDirection n2Direction, HSAuint64 size, HSAuint64 *speed, HSAuint64 *speed2, std::stringstream *msg,\n        bool isTestOverhead = false, HSAuint64 *time = 0) {\n    HSAuint32 n2[n];\n    void *n1Mem, *n2Mem[n];\n    HsaMemFlags memFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 0;\n    memFlags.ui32.NonPaged = 1;\n    SDMACopyParams array[n * 4];\n    int array_count = 0;\n    HSAuint64 alloc_size = ALIGN_UP(size, PAGE_SIZE);\n    std::vector<SDMACopyParams> copyArray;\n    int i;\n\n    ASSERT_SUCCESS(hsaKmtAllocMemory(n1, alloc_size, memFlags, &n1Mem));\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(n1Mem, alloc_size, NULL));\n\n    for (i = 0; i < n; i++) {\n        n2[i] = n2Array[i];\n        ASSERT_SUCCESS(hsaKmtAllocMemory(n2[i], alloc_size, memFlags, &n2Mem[i]));\n        ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(n2Mem[i], alloc_size, NULL));\n    }\n\n    for (i = 0; i < n; i++) {\n        if (n1Direction != NONE)\n            ASSERT_NE(n1, 0);\n        if (n2Direction != NONE)\n            ASSERT_NE(n2[i], 0);\n\n        do {\n            if (n1Direction == IN || n1Direction == IN_OUT)\n                /* n2Mem -> n1Mem*/\n                array[array_count++] = {n1, n2Mem[i], n1Mem, size, n1/*group id, just a hint*/};\n            if (n1Direction == OUT || n1Direction == IN_OUT)\n                /* n1Mem -> n2Mem*/\n                array[array_count++] = {n1, n1Mem, n2Mem[i], size, n1};\n            /* Issue two copies to make full use of sdma.*/\n        } while (n1Direction < IN_OUT && n == 1 && array_count % 2);\n        /* Do nothing if no IN or OUT specified.*/\n\n        do {\n            if (n2Direction == IN || n2Direction == IN_OUT)\n                /* n1Mem -> n2Mem*/\n                array[array_count++] = {n2[i], n1Mem, n2Mem[i], size, n2[i]};\n            if (n2Direction == OUT || n2Direction == IN_OUT)\n                /* n2Mem -> n1Mem*/\n                array[array_count++] = {n2[i], n2Mem[i], n1Mem, size, n2[i]};\n        } while (n2Direction < IN_OUT && array_count % 2);\n    }\n\n    /* We measure a bunch of packets.*/\n    if (isTestOverhead) {\n            for (i = 0; i < 1000; i++)\n                for (int j = 0; j < array_count; j++)\n                    copyArray.push_back(array[j]);\n        sdma_multicopy(copyArray, 1, HEAD_TAIL);\n        *time = CounterToNanoSec(copyArray[0].timeConsumption / (1000 * array_count));\n    } else\n        /* It did not respect the group id we set above.*/\n        sdma_multicopy(array, array_count, speed, speed2, msg);\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(n1Mem));\n    EXPECT_SUCCESS(hsaKmtFreeMemory(n1Mem, alloc_size));\n\n    for (i = 0; i < n; i++) {\n        EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(n2Mem[i]));\n        EXPECT_SUCCESS(hsaKmtFreeMemory(n2Mem[i], alloc_size));\n    }\n}\n\nTEST_F(KFDPerformanceTest, P2PBandWidthTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Can't have 2 APUs on the same system.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    std::vector<int> nodes;\n    const bool isSpecified = g_TestDstNodeId != -1 && g_TestNodeId != -1;\n    int numPeers = 0;\n    const unsigned int maxSdmaQueues = m_numSdmaEngines * m_numSdmaQueuesPerEngine;\n\n    if (isSpecified) {\n        if (g_TestNodeId != g_TestDstNodeId) {\n            nodes.push_back(g_TestNodeId);\n            nodes.push_back(g_TestDstNodeId);\n            if ((m_NodeInfo.IsPeerAccessibleByNode(g_TestNodeId, g_TestDstNodeId) &&\n                 m_NodeInfo.IsPeerAccessibleByNode(g_TestDstNodeId, g_TestNodeId)))\n                numPeers = 2;\n        }\n    } else {\n        nodes = m_NodeInfo.GetNodesWithGPU();\n        numPeers = nodes.size();\n    }\n\n    if (numPeers < 2) {\n        LOG() << \"Skipping test: Need at least two large bar GPU or XGMI connected.\" << std::endl;\n        return;\n    }\n\n    g_TestTimeOut *= numPeers;\n\n    std::vector<int> sysNodes(nodes); // include sysMem node 0...\n    sysNodes.insert(sysNodes.begin(),0);\n\n    const int total_tests = 7;\n    const char *test_suits_string[total_tests] = {\n        \"Copy from node to node by [push, NONE]\",\n        \"Copy from node to node by [pull, NONE]\",\n        \"Full duplex copy from node to node by [push|pull, NONE]\",\n        \"Full duplex copy from node to node by [push, push]\",\n        \"Full duplex copy from node to node by [pull, pull]\",\n        \"Copy from node to multiple nodes by [push, NONE]\",\n        \"Copy from multiple nodes to node by [push, NONE]\",\n    };\n    const P2PDirection test_suits[total_tests][2] = {\n        /* One node used.*/\n        {OUT,   NONE},\n        {IN,    NONE},\n        {IN_OUT,NONE},\n        /* two nodes used.*/\n        {OUT,   OUT},\n        {IN,    IN},\n        /* Multi nodes used*/\n        {OUT,   NONE},\n        {NONE,  OUT},\n    };\n    const int twoNodesIdx = 3;\n    const int multiNodesIdx = 5;\n    const HSAuint32 size = 32ULL << 20;\n    int s = 0; //test index;\n    std::stringstream msg;\n    char str[64];\n\n    if (isSpecified) {\n        HSAuint32 n1 = g_TestNodeId;\n        HSAuint32 n2 = g_TestDstNodeId;\n        HSAuint64 speed, speed2;\n\n        LOG() << \"Copy from node to node by [push, pull]\" << std::endl;\n        snprintf(str, sizeof(str), \"[%d -> %d] \", n1, n2);\n        testNodeToNodes(n1, &n2, 1, OUT, IN, size, &speed, &speed2, &msg);\n\n        LOG() << std::dec << str << (float)speed / 1024 << \" - \" <<\n                                 (float)speed2 / 1024 << \" GB/s\" << std::endl;\n        goto exit;\n\n    }\n\n    for (; s < twoNodesIdx; s++) {\n        LOG() << test_suits_string[s] << std::endl;\n        msg << test_suits_string[s] << std::endl;\n\n        for (unsigned i = 0; i < nodes.size(); i++) {\n            /* Src node is a GPU.*/\n            HSAuint32 n1 = nodes[i];\n            HSAuint64 speed, speed2;\n\n            /* Pick up dst node which can be sysMem.*/\n            for (unsigned j = 0; j < sysNodes.size(); j++) {\n                HSAuint32 n2 = sysNodes[j];\n                if (n1 == n2)\n                    continue;\n\n                if (!m_NodeInfo.IsPeerAccessibleByNode(n2, n1))\n                    continue;\n\n                snprintf(str, sizeof(str), \"[%d -> %d] \", n1, n2);\n                msg << str << std::endl;\n                testNodeToNodes(n1, &n2, 1, test_suits[s][0], test_suits[s][1], size, &speed, &speed2, &msg);\n\n                LOG() << std::dec << str << (float)speed / 1024 << \" - \" <<\n                                            (float)speed2 / 1024 << \" GB/s\" << std::endl;\n            }\n        }\n    }\n\n    for (; s < multiNodesIdx; s++) {\n        LOG() << test_suits_string[s] << std::endl;\n        msg << test_suits_string[s] << std::endl;\n\n        for (unsigned i = 0; i < nodes.size(); i++) {\n            HSAuint32 n1 = nodes[i];\n            HSAuint64 speed, speed2;\n\n            for (unsigned j = i + 1; j < nodes.size(); j++) {\n                HSAuint32 n2 = nodes[j];\n\n                if (!m_NodeInfo.IsPeerAccessibleByNode(n2, n1) ||\n                    !m_NodeInfo.IsPeerAccessibleByNode(n1, n2))\n                    continue;\n\n                snprintf(str, sizeof(str), \"[%d <-> %d] \", n1, n2);\n                msg << str << std::endl;\n                testNodeToNodes(n1, &n2, 1, test_suits[s][0], test_suits[s][1], size, &speed, &speed2, &msg);\n\n                LOG() << std::dec << str << (float)speed / 1024 << \" - \" <<\n                                            (float)speed2 / 1024 << \" GB/s\" << std::endl;\n            }\n        }\n    }\n\n    for (; s < total_tests && !isSpecified; s++) {\n        LOG() << test_suits_string[s] << std::endl;\n        msg << test_suits_string[s] << std::endl;\n        /* Just use GPU nodes to do copy.*/\n        std::vector<int> &src = test_suits[s][0] != NONE ? nodes : sysNodes;\n        std::vector<int> &dst = test_suits[s][1] != NONE ? nodes : sysNodes;\n\n        for (unsigned i = 0; i < src.size(); i++) {\n            HSAuint32 n1 = src[i];\n            HSAuint64 speed, speed2;\n            HSAuint32 n2[dst.size()];\n            int n = 0;\n            char str[64];\n\n            for (unsigned j = 0; j < dst.size(); j++) {\n                if (dst[j] != n1) {\n                    if (test_suits[s][0] != NONE &&\n                        !m_NodeInfo.IsPeerAccessibleByNode(dst[j], n1))\n                            continue;\n                    if (test_suits[s][1] != NONE &&\n                        !m_NodeInfo.IsPeerAccessibleByNode(n1, dst[j]))\n                            continue;\n                    n2[n++] = dst[j];\n                }\n            }\n\n            /* At least 2 dst GPUs.*/\n            if (n < 2)\n                continue;\n\n            if (test_suits[s][1] == OUT) {\n                snprintf(str, sizeof(str), \"[[%d...%d] -> %d] \", dst.front(), dst.back(), n1);\n                msg << str << std::endl;\n                testNodeToNodes(n1, n2, n, test_suits[s][0], test_suits[s][1], size, &speed, &speed2, &msg);\n\n                LOG() << std::dec << str << (float)speed / 1024 << \" - \" <<\n                                        (float)speed2 / 1024 << \" GB/s\" << std::endl;\n            } else {\n                /* If the total number of peers is greater than the number of SDMA queues supported,\n                 * then we test in the following way:\n                 * 1. Test peers in batches where each batch consists of number of peers equal to the\n                 *    max number of SDMA queues.\n                 * 2. Keep repeating step 1 if number of peers left is greater than number of SDMA queues\n                 *    supported.\n                 * 3. Test the last batch with the remaining peers left which can be less than the number of\n                 *    SDMA queues supported.\n                 * For example, if there are 24 peers and max number of SDMA queues supported is 16, then\n                 * the test will test 16 peers/nodes first and then remaining 8 in the next round.\n                 */\n                unsigned int j=0;\n                unsigned int start_index;\n                unsigned int end_index;\n                do {\n                    start_index = maxSdmaQueues * j++;\n                    end_index = start_index + maxSdmaQueues - 1;\n\n                    if (end_index + 1 > n)\n                        end_index = n - 1;\n\n                    snprintf(str, sizeof(str), \"[%d -> [%d...%d]] \", n1, n2[start_index], n2[end_index]);\n                    msg << str << std::endl;\n                    testNodeToNodes(n1, &n2[start_index], end_index - start_index + 1,\n                                    test_suits[s][0], test_suits[s][1], size, &speed, &speed2, &msg);\n                    LOG() << std::dec << str << (float)speed / 1024 << \" - \" <<\n                                                (float)speed2 / 1024 << \" GB/s\" << std::endl;\n                } while(end_index < (n - 1));\n            }\n        }\n    }\n\n    g_TestTimeOut /= numPeers;\nexit:\n    /* New line.*/\n    LOG() << std::endl << msg.str() << std::endl;\n\n    TEST_END\n}\n\nTEST_F(KFDPerformanceTest, P2POverheadTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Can't have 2 APUs on the same system.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    std::vector<int> nodes;\n\n    nodes = m_NodeInfo.GetNodesWithGPU();\n    int numPeers = nodes.size();\n\n    if (numPeers < 2) {\n        LOG() << \"Skipping test: Need at least two large bar GPU or XGMI connected.\" << std::endl;\n        return;\n    }\n\n    std::vector<int> sysNodes(nodes); // include sysMem node 0...\n    sysNodes.insert(sysNodes.begin(),0);\n\n    /* size should be small.*/\n    const HSAuint32 sizeArray[] = {4, 8, 16, 64, 256, 1024};\n    const int total_tests = 3;\n    const char *test_suits_string[total_tests] = {\n        \"[push]     \",\n        \"[pull]     \",\n        \"[push|pull]\",\n    };\n    const P2PDirection test_suits[total_tests] = {OUT, IN, IN_OUT};\n    std::stringstream msg;\n    int s; //test index;\n\n    msg << \"Test (avg. ns) | Size\";\n    for (auto &size : sizeArray)\n        msg << \"\\t\" << size;\n    LOG() << msg.str() << std::endl;\n    LOG() << \"-----------------------------------------------------------------------\" << std::endl;\n\n    for (s = 0; s < total_tests; s++) {\n\n        for (unsigned i = 0; i < nodes.size(); i++) {\n            /* Src node is a GPU.*/\n            HSAuint32 n1 = nodes[i];\n            HSAuint64 time;\n\n            /* Pick up dst node which can be sysMem.*/\n            for (unsigned j = 0; j < sysNodes.size(); j++) {\n                HSAuint32 n2 = sysNodes[j];\n                std::stringstream msg;\n\n                if (n1 != n2 && !m_NodeInfo.IsPeerAccessibleByNode(n2, n1))\n                    continue;\n\n                msg << test_suits_string[s] << \"[\" << n1 << \" -> \" << n2 << \"]\";\n                for (auto &size : sizeArray) {\n                    testNodeToNodes(n1, &n2, 1, test_suits[s], NONE, size, 0, 0, 0, 1, &time);\n                    msg << \"\\t\" << time;\n                }\n                LOG() << msg.str() << std::endl;\n            }\n        }\n    }\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDQMTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <sys/time.h>\n#include <sys/mman.h>\n#include <vector>\n#include <utility>\n#include <mutex>\n\n#include \"KFDQMTest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"XgmiOptimizedSDMAQueue.hpp\"\n#include \"AqlQueue.hpp\"\n#include <algorithm>\n\n#include \"Dispatch.hpp\"\n\nextern unsigned int g_TestGPUsNum;\n\nvoid KFDQMTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid KFDQMTest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic void CreateDestroyCpQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, CreateDestroyCpQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n   ASSERT_SUCCESS(KFDTest_Launch(CreateDestroyCpQueue));\n\n    TEST_END\n}\n\nstatic void SubmitNopCpQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    PM4Queue queue;\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4NopPacket());\n\n    queue.Wait4PacketConsumption(event);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, SubmitNopCpQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SubmitNopCpQueue));\n\n    TEST_END\n}\n\nstatic void SubmitPacketCpQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFF);\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    PM4Queue queue;\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0, 0));\n\n    queue.Wait4PacketConsumption(event);\n\n    EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>(), 0), gpuNode);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, SubmitPacketCpQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SubmitPacketCpQueue));\n\n    TEST_END\n}\n\nstatic void AllCpQueues(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    int gpuIndex = pKFDQMTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFF);\n\n    unsigned int  m_numCpQueues = pKFDQMTest->Get_NumCpQueues(gpuIndex);\n    std::vector<PM4Queue> queues(m_numCpQueues);\n\n    for (unsigned int qidx = 0; qidx < m_numCpQueues; ++qidx)\n        ASSERT_SUCCESS_GPU(queues[qidx].Create(gpuNode), gpuNode) << \" QueueId=\" << qidx;\n\n    for (unsigned int qidx = 0; qidx < m_numCpQueues; ++qidx) {\n        queues[qidx].PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>()+qidx*2, qidx, qidx));\n        queues[qidx].PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, true, 0, 0));\n        queues[qidx].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>()+qidx*2, qidx), gpuNode);\n    }\n\n    for (unsigned int qidx = 0; qidx < m_numCpQueues; ++qidx)\n       EXPECT_SUCCESS_GPU(queues[qidx].Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, AllCpQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AllCpQueues));\n\n    TEST_END\n}\n\nstatic void CreateDestroySdmaQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    SDMAQueue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, CreateDestroySdmaQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(CreateDestroySdmaQueue));\n\n    TEST_END\n}\n\nstatic void SubmitNopSdmaQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    SDMAQueue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(SDMANopPacket());\n\n    queue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, SubmitNopSdmaQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SubmitNopSdmaQueue));\n\n    TEST_END\n}\n\nstatic void SubmitPacketSdmaQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFF);\n\n    SDMAQueue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), destBuf.As<void *>(), 0x02020202));\n\n    queue.Wait4PacketConsumption();\n\n    EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>(), 0x02020202), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, SubmitPacketSdmaQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SubmitPacketSdmaQueue));\n\n    TEST_END\n}\n\nstatic void AllSdmaQueues(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    int gpuIndex = pKFDQMTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n\n    unsigned int m_numSdmaEngines = pKFDQMTest->Get_NumSdmaEngines(gpuIndex);\n    unsigned int m_numSdmaQueuesPerEngine = pKFDQMTest->Get_NumSdmaSdmaQueuesPerEngine(gpuIndex);\n\n    int bufSize = PAGE_SIZE;\n    const unsigned int numSdmaQueues = m_numSdmaEngines * m_numSdmaQueuesPerEngine;\n\n    LOG() << \"Regular SDMA engines number: \" << m_numSdmaEngines\n          << \" SDMA queues per engine: \" << m_numSdmaQueuesPerEngine << std::endl;\n\n    HsaMemoryBuffer destBuf(bufSize << 1 , gpuNode, false);\n    HsaMemoryBuffer srcBuf(bufSize, gpuNode, false);\n    destBuf.Fill(0xFF);\n\n    std::vector<SDMAQueue> queues(numSdmaQueues);\n\n    for (unsigned int qidx = 0; qidx < numSdmaQueues; ++qidx)\n        ASSERT_SUCCESS_GPU(queues[qidx].Create(gpuNode), gpuNode);\n\n    for (unsigned int qidx = 0; qidx < numSdmaQueues; ++qidx) {\n        destBuf.Fill(0x0);\n        srcBuf.Fill(qidx + 0xa0);\n        queues[qidx].PlaceAndSubmitPacket(\n            SDMACopyDataPacket(queues[qidx].GetFamilyId(), destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize));\n        queues[qidx].PlaceAndSubmitPacket(\n            SDMAWriteDataPacket(queues[qidx].GetFamilyId(), destBuf.As<unsigned int*>() + bufSize/4, 0x02020202));\n\n        queues[qidx].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>() + bufSize/4, 0x02020202), gpuNode);\n\n        EXPECT_SUCCESS_GPU(memcmp(\n            destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize), gpuNode);\n    }\n\n    for (unsigned int qidx = 0; qidx < numSdmaQueues; ++qidx)\n        EXPECT_SUCCESS_GPU(queues[qidx].Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, AllSdmaQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AllSdmaQueues));\n\n    TEST_END\n}\n\nstatic void AllXgmiSdmaQueues(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    int gpuIndex = pKFDQMTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    unsigned int m_numSdmaXgmiEngines = pKFDQMTest->Get_NumSdmaSdmaXgmiEngines(gpuIndex);\n    unsigned int m_numSdmaQueuesPerEngine = pKFDQMTest->Get_NumSdmaSdmaQueuesPerEngine(gpuIndex);\n\n    int bufSize = PAGE_SIZE;\n    int j;\n\n    const unsigned int numXgmiSdmaQueues =\n            m_numSdmaXgmiEngines * m_numSdmaQueuesPerEngine;\n\n    LOG() << \"XGMI SDMA engines number: \" << m_numSdmaXgmiEngines\n            << \" SDMA queues per engine: \" << m_numSdmaQueuesPerEngine << std::endl;\n\n    HsaMemoryBuffer destBuf(bufSize << 1 , gpuNode, false);\n    HsaMemoryBuffer srcBuf(bufSize, gpuNode, false);\n    destBuf.Fill(0xFF);\n\n    std::vector<XgmiOptimizedSDMAQueue> xgmiSdmaQueues(numXgmiSdmaQueues);\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j)\n        ASSERT_SUCCESS_GPU(xgmiSdmaQueues[j].Create(gpuNode), gpuNode);\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j) {\n        destBuf.Fill(0x0);\n        srcBuf.Fill(j + 0xa0);\n        xgmiSdmaQueues[j].PlaceAndSubmitPacket(\n            SDMACopyDataPacket(xgmiSdmaQueues[j].GetFamilyId(),\n                    destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize));\n        xgmiSdmaQueues[j].PlaceAndSubmitPacket(\n            SDMAWriteDataPacket(xgmiSdmaQueues[j].GetFamilyId(),\n                    destBuf.As<unsigned int*>() + bufSize/4, 0x02020202));\n\n        xgmiSdmaQueues[j].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>() + bufSize/4, 0x02020202), gpuNode);\n\n        EXPECT_SUCCESS_GPU(memcmp(\n            destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize), gpuNode);\n    }\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j)\n        EXPECT_SUCCESS_GPU(xgmiSdmaQueues[j].Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, AllXgmiSdmaQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AllXgmiSdmaQueues));\n\n    TEST_END\n}\n\nstatic void AllQueues(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDQMTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    unsigned int m_numSdmaXgmiEngines = pKFDQMTest->Get_NumSdmaSdmaXgmiEngines(gpuIndex);\n    unsigned int m_numSdmaQueuesPerEngine = pKFDQMTest->Get_NumSdmaSdmaQueuesPerEngine(gpuIndex);\n    unsigned int m_numSdmaEngines = pKFDQMTest->Get_NumSdmaEngines(gpuIndex);\n    unsigned int m_numCpQueues = pKFDQMTest->Get_NumCpQueues(gpuIndex);\n\n    int bufSize = PAGE_SIZE;\n    unsigned int i, j;\n\n    const unsigned int numCpQueues = m_numCpQueues;\n    const unsigned int numSdmaQueues = m_numSdmaEngines * m_numSdmaQueuesPerEngine;\n    const unsigned int numXgmiSdmaQueues =\n            m_numSdmaXgmiEngines * m_numSdmaQueuesPerEngine;\n\n    HsaMemoryBuffer destBufCp(PAGE_SIZE, gpuNode, false);\n    destBufCp.Fill(0xFF);\n\n    HsaMemoryBuffer destBuf(bufSize << 1 , gpuNode, false);\n    HsaMemoryBuffer srcBuf(bufSize, gpuNode, false);\n    destBuf.Fill(0xFF);\n\n    std::vector<PM4Queue> cpQueues(numCpQueues);\n    std::vector<SDMAQueue> sdmaQueues(numSdmaQueues);\n    std::vector<XgmiOptimizedSDMAQueue> xgmiSdmaQueues(numXgmiSdmaQueues);\n\n    for (i = 0; i < numCpQueues; ++i)\n        ASSERT_SUCCESS_GPU(cpQueues[i].Create(gpuNode), gpuNode) << \" QueueId=\" << i;\n\n    for (j = 0; j < numSdmaQueues; ++j)\n        ASSERT_SUCCESS_GPU(sdmaQueues[j].Create(gpuNode), gpuNode);\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j)\n        ASSERT_SUCCESS_GPU(xgmiSdmaQueues[j].Create(gpuNode), gpuNode);\n\n\n    for (i = 0; i < numCpQueues; ++i) {\n        cpQueues[i].PlaceAndSubmitPacket(PM4WriteDataPacket(destBufCp.As<unsigned int*>()+i*2, i, i));\n        cpQueues[i].PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, true, 0, 0));\n\n        cpQueues[i].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBufCp.As<unsigned int*>()+i*2, i), gpuNode);\n    }\n\n    for (j = 0; j < numSdmaQueues; ++j) {\n        destBuf.Fill(0x0);\n        srcBuf.Fill(j + 0xa0);\n        sdmaQueues[j].PlaceAndSubmitPacket(\n            SDMACopyDataPacket(sdmaQueues[j].GetFamilyId(), destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize));\n        sdmaQueues[j].PlaceAndSubmitPacket(\n            SDMAWriteDataPacket(sdmaQueues[j].GetFamilyId(), destBuf.As<unsigned int*>() + bufSize/4, 0x02020202));\n\n        sdmaQueues[j].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>() + bufSize/4, 0x02020202), gpuNode);\n\n        EXPECT_SUCCESS_GPU(memcmp(\n            destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize), gpuNode);\n    }\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j) {\n        destBuf.Fill(0x0);\n        srcBuf.Fill(j + 0xa0);\n        xgmiSdmaQueues[j].PlaceAndSubmitPacket(\n            SDMACopyDataPacket(xgmiSdmaQueues[j].GetFamilyId(),\n                    destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize));\n        xgmiSdmaQueues[j].PlaceAndSubmitPacket(\n            SDMAWriteDataPacket(xgmiSdmaQueues[j].GetFamilyId(),\n                    destBuf.As<unsigned int*>() + bufSize/4, 0x02020202));\n\n        xgmiSdmaQueues[j].Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>() + bufSize/4, 0x02020202), gpuNode);\n\n        EXPECT_SUCCESS_GPU(memcmp(\n            destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize), gpuNode);\n    }\n\n\n    for (i = 0; i < numCpQueues; ++i)\n       EXPECT_SUCCESS_GPU(cpQueues[i].Destroy(), gpuNode);\n\n    for (j = 0; j < numSdmaQueues; ++j)\n        EXPECT_SUCCESS_GPU(sdmaQueues[j].Destroy(), gpuNode);\n\n    for (j = 0; j < numXgmiSdmaQueues; ++j)\n        EXPECT_SUCCESS_GPU(xgmiSdmaQueues[j].Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, AllQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(AllQueues));\n\n    TEST_END\n}\n\n/* The following test is designed to reproduce an intermittent hang on\n * Fiji and other VI/Polaris GPUs. This test typically hangs in a few\n * seconds. According to analysis done by HW engineers, the culprit\n * seems to be PCIe speed switching. The problem can be worked around\n * by disabling the lowest DPM level on Fiji.\n */\nstatic void SdmaConcurrentCopies(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    int gpuIndex = pKFDQMTest->Get_NodeInfo()->HsaGPUindexFromGpuNode(gpuNode);\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n#define BUFFER_SIZE (64*1024)\n#define NPACKETS 1\n#define COPY_SIZE (BUFFER_SIZE / NPACKETS)\n    HsaMemoryBuffer srcBuf(BUFFER_SIZE, 0, true);\n    HsaMemoryBuffer dstBuf(BUFFER_SIZE, gpuNode, false, hsakmt_is_dgpu() ? true : false);\n\n    SDMAQueue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    std::ostream &log = LOG();\n    char progress[] = \"-\\b\";\n    log << \"Running ... \";\n\n    for (unsigned i = 0; i < 100000; i++) {\n        if (i % 1000 == 0) {\n            const char progressSteps[4] = {'-', '\\\\', '|', '/'};\n            progress[0] = progressSteps[(i/1000) % 4];\n            log << progress;\n        }\n\n        for (unsigned j = 0; j < NPACKETS; j++)\n            queue.PlacePacket(\n                SDMACopyDataPacket(queue.GetFamilyId(), dstBuf.As<char *>()+COPY_SIZE*j,\n                                   srcBuf.As<char *>()+COPY_SIZE*j, COPY_SIZE));\n        queue.SubmitPacket();\n\n        /* Waste a variable amount of time. Submission timing\n         * while SDMA runs concurrently seems to be critical for\n         * reproducing the hang\n         */\n        for (int k = 0; k < (i & 0xfff); k++)\n            memcpy(srcBuf.As<char *>()+PAGE_SIZE, srcBuf.As<char *>(), 1024);\n\n        /* Wait for idle every 8 packets to allow the SDMA engine to\n         * run concurrently for a bit without getting too far ahead\n         */\n        if ((i & 0x7) == 0)\n            queue.Wait4PacketConsumption();\n    }\n    log << \"Done.\" << std::endl;\n\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), srcBuf.As<unsigned *>(), 0x02020202));\n    queue.Wait4PacketConsumption();\n    EXPECT_TRUE_GPU(WaitOnValue(srcBuf.As<unsigned int*>(), 0x02020202), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, SdmaConcurrentCopies) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SdmaConcurrentCopies));\n\n    TEST_END\n}\n\nstatic void DisableCpQueueByUpdateWithNullAddress(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0, 0));\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 0);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    EXPECT_SUCCESS_GPU(queue.Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, BaseQueue::DEFAULT_PRIORITY, true), gpuNode);\n\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 1, 1));\n\n    // Don't sync since we don't expect rptr to change when the queue is disabled.\n    Delay(2000);\n\n    EXPECT_EQ_GPU(destBuf.As<unsigned int*>()[0], 0xFFFFFFFF, gpuNode)\n        << \"Packet executed even though the queue is supposed to be disabled!\";\n\n    EXPECT_SUCCESS_GPU(queue.Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 1);\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, DisableCpQueueByUpdateWithNullAddress) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(DisableCpQueueByUpdateWithNullAddress));\n\n    TEST_END\n}\n\nstatic void DisableSdmaQueueByUpdateWithNullAddress(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    SDMAQueue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), destBuf.As<void*>(), 0));\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 0);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    EXPECT_SUCCESS_GPU(queue.Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, BaseQueue::DEFAULT_PRIORITY, true), gpuNode);\n\n    queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), destBuf.As<void*>(), 0));\n\n    // Don't sync since we don't expect rptr to change when the queue is disabled.\n    Delay(2000);\n\n    EXPECT_EQ_GPU(destBuf.As<unsigned int*>()[0], 0xFFFFFFFF, gpuNode)\n        << \"Packet executed even though the queue is supposed to be disabled!\";\n\n    EXPECT_SUCCESS_GPU(queue.Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n    queue.Wait4PacketConsumption();\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 0);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n\n}\nTEST_F(KFDQMTest, DisableSdmaQueueByUpdateWithNullAddress) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(DisableSdmaQueueByUpdateWithNullAddress));\n\n    TEST_END\n}\n\nstatic void DisableCpQueueByUpdateWithZeroPercentage(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    PM4WriteDataPacket packet1, packet2;\n    packet1.InitPacket(destBuf.As<unsigned int*>(), 0, 0);\n    packet2.InitPacket(destBuf.As<unsigned int*>(), 1, 1);\n\n    queue.PlaceAndSubmitPacket(packet1);\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 0);\n\n    destBuf.Fill(0xFFFFFFFF);\n\n    EXPECT_SUCCESS_GPU(queue.Update(0/*percentage*/, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n    queue.PlaceAndSubmitPacket(packet2);\n\n    // Don't sync since we don't expect rptr to change when the queue is disabled.\n    Delay(2000);\n\n    EXPECT_EQ_GPU(destBuf.As<unsigned int*>()[0], 0xFFFFFFFF, gpuNode)\n        << \"Packet executed even though the queue is supposed to be disabled!\";\n\n    EXPECT_SUCCESS_GPU(queue.Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, BaseQueue::DEFAULT_PRIORITY, false), gpuNode);\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 1);\n    hsaKmtDestroyEvent(event);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, DisableCpQueueByUpdateWithZeroPercentage) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(DisableCpQueueByUpdateWithZeroPercentage));\n\n    TEST_END\n}\n\nstatic void CreateQueueStressSingleThreaded(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n\n    static const HSAuint64 TEST_TIME_SEC = 15;\n\n    HSAuint64 initialTime = GetSystemTickCountInMicroSec();\n\n    unsigned int numIter = 0;\n\n    HSAuint64 timePassed = 0;\n\n    do {\n        // The following means we'll get the order 0,0 => 0,1 => 1,0 => 1,1 so we cover all options.\n        unsigned int firstToCreate = (numIter % 2 != 0) ? 1 : 0;\n        unsigned int firstToDestroy = (numIter % 4 > 1) ? 1 : 0;\n\n        unsigned int secondToCreate = (firstToCreate + 1)%2;\n        unsigned int secondToDestroy = (firstToDestroy + 1)%2;\n\n        BaseQueue *queues[2] = {new PM4Queue(), new SDMAQueue()};\n\n        ASSERT_SUCCESS_GPU(queues[firstToCreate]->Create(gpuNode), gpuNode);\n        ASSERT_SUCCESS_GPU(queues[secondToCreate]->Create(gpuNode),gpuNode);\n\n        EXPECT_SUCCESS_GPU(queues[firstToDestroy]->Destroy(), gpuNode);\n        EXPECT_SUCCESS_GPU(queues[secondToDestroy]->Destroy(), gpuNode);\n\n        delete queues[0];\n        delete queues[1];\n        ++numIter;\n\n        HSAuint64 curTime = GetSystemTickCountInMicroSec();\n        timePassed = (curTime - initialTime) / 1000000;\n    } while (timePassed < TEST_TIME_SEC);\n\n}\n\nTEST_F(KFDQMTest, CreateQueueStressSingleThreaded) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(CreateQueueStressSingleThreaded));\n\n    TEST_END\n}\n\nstatic void OverSubscribeCpQueues(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    const HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId == FAMILY_CI || m_FamilyId == FAMILY_KV) {\n        LOG() << \"Skipping test: CI doesn't have HW scheduling.\" << std::endl;\n        return;\n    }\n\n    /* The max queues per process is 1024 limited by\n     * KFD, so MAX_CP_QUEUES is needed to adapt it\n     * when total queues exceed it.\n     */\n    static const unsigned int MAX_CP_QUEUES = g_TestGPUsNum > 15 ?\n                                              1024 / g_TestGPUsNum :\n                                              65;\n    static const unsigned int MAX_PACKETS = 100;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode, false);\n\n    destBuf.Fill(0xFF);\n\n    PM4Queue queues[MAX_CP_QUEUES];\n\n    for (unsigned int qidx = 0; qidx < MAX_CP_QUEUES; ++qidx)\n        ASSERT_SUCCESS_GPU(queues[qidx].Create(gpuNode), gpuNode) << \" QueueId=\" << qidx;\n\n    for (unsigned int qidx = 0; qidx < MAX_CP_QUEUES; ++qidx) {\n        unsigned int pktSizeDw = 0;\n        for (unsigned int i = 0; i < MAX_PACKETS; i++) {\n            PM4WriteDataPacket packet;\n            packet.InitPacket(destBuf.As<unsigned int*>()+qidx*2, qidx+i, qidx+i);  // two dwords per packet\n            queues[qidx].PlacePacket(packet);\n        }\n    }\n\n    for (unsigned int qidx = 0; qidx < MAX_CP_QUEUES; ++qidx)\n        queues[qidx].SubmitPacket();\n\n    // Delaying for 5 seconds in order to get all the results\n    Delay(5000);\n\n    for (unsigned int qidx = 0; qidx < MAX_CP_QUEUES; ++qidx)\n        EXPECT_TRUE_GPU(queues[qidx].AllPacketsSubmitted(), gpuNode)<< \"QueueId=\" << qidx;;\n\n    for (unsigned int qidx = 0; qidx < MAX_CP_QUEUES; ++qidx)\n        EXPECT_SUCCESS_GPU(queues[qidx].Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, OverSubscribeCpQueues) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(OverSubscribeCpQueues));\n\n    TEST_END\n}\n\nHSAint64 KFDQMTest::TimeConsumedwithCUMask(int node, uint32_t* mask, uint32_t mask_count) {\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, node, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer dstBuffer(PAGE_SIZE, node, true, false, false);\n    HsaMemoryBuffer ctlBuffer(PAGE_SIZE, node, true, false, false);\n\n    EXPECT_SUCCESS(m_pAsm->RunAssembleBuf(LoopIsa, isaBuffer.As<char*>()));\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetDim(1024, 16, 16);\n\n    PM4Queue queue;\n    EXPECT_SUCCESS(queue.Create(node));\n    EXPECT_SUCCESS(queue.SetCUMask(mask, mask_count));\n    queue.SetSkipWaitConsump(true);\n\n    HSAuint64 startTime = GetSystemTickCountInMicroSec();\n    dispatch.Submit(queue);\n    dispatch.Sync();\n    HSAuint64 endTime = GetSystemTickCountInMicroSec();\n\n    EXPECT_SUCCESS(queue.Destroy());\n    return endTime - startTime;\n}\n\n/* To cover for outliers, allow us to get the Average time based on a specified number of iterations */\nHSAint64 KFDQMTest::GetAverageTimeConsumedwithCUMask(int node, uint32_t* mask, uint32_t mask_count, int iterations) {\n    HSAint64 timeArray[iterations];\n    HSAint64 timeTotal = 0;\n    if (iterations < 1) {\n        LOG() << \"ERROR: At least 1 iteration must be performed\" << std::endl;\n        return 0;\n    }\n\n    for (int x = 0; x < iterations; x++) {\n        timeArray[x] = TimeConsumedwithCUMask(node, mask, mask_count);\n        timeTotal += timeArray[x];\n    }\n\n    if (timeTotal == 0) {\n        LOG() << \"ERROR: Total time reported as 0. Exiting\" << std::endl;\n        return 0;\n    }\n\n    for (int x = 0; x < iterations; x++) {\n        HSAint64 variance = timeArray[x] / (timeTotal / iterations);\n        if (variance < CuNegVariance || variance > CuPosVariance)\n            LOG() << \"WARNING: Measurement #\" << x << \"/\" << iterations << \" (\" << timeArray[x]\n                  << \") is at least \" << CuVariance*100 << \"% away from the mean (\" << timeTotal/iterations << \")\"\n                  << std::endl;\n    }\n\n    return timeTotal / iterations;\n}\n\n/*\n * Apply CU masking in a linear fashion, adding 1 CU per iteration\n * until all Shader Engines are full\n */\nvoid BasicCuMaskingLinear(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    const HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId >= FAMILY_VI) {\n        const HsaNodeProperties *pNodeProperties = pKFDQMTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n        uint32_t ActiveCU = (pNodeProperties->NumFComputeCores / pNodeProperties->NumSIMDPerCU);\n        uint32_t numSEs = pNodeProperties->NumShaderBanks;\n        LOG() << std::dec << \"# Compute cores: \" << pNodeProperties->NumFComputeCores << std::endl;\n        LOG() << std::dec << \"# SIMDs per CU: \" << pNodeProperties->NumSIMDPerCU << std::endl;\n        LOG() << std::dec << \"# Shader engines: \" << numSEs << std::endl;\n        LOG() << std::dec << \"# Active CUs: \" << ActiveCU << std::endl;\n        HSAint64 TimewithCU1, TimewithCU;\n        uint32_t maskNumDwords = (ActiveCU + 31) / 32; /* Round up to the nearest multiple of 32 */\n        uint32_t maskNumBits = maskNumDwords * 32;\n        uint32_t mask[maskNumDwords];\n        double ratio;\n\n        mask[0] = 0x1;\n        for (int i = 1; i < maskNumDwords; i++)\n            mask[i] = 0x0;\n\n        /* Execute once to get any HW optimizations out of the way */\n        pKFDQMTest->TimeConsumedwithCUMask(gpuNode, mask, maskNumBits);\n\n        LOG() << \"Getting baseline performance numbers (CU Mask: 0x1)\" << std::endl;\n        TimewithCU1 = pKFDQMTest->GetAverageTimeConsumedwithCUMask(gpuNode, mask, maskNumBits, 3);\n\n        for (int nCUs = 2; nCUs <= ActiveCU; nCUs++) {\n            int maskIndex = (nCUs - 1) / 32;\n            mask[maskIndex] |= 1 << ((nCUs - 1) % 32);\n\n            TimewithCU = pKFDQMTest->TimeConsumedwithCUMask(gpuNode, mask, maskNumBits);\n            ratio = (double)(TimewithCU1) / ((double)(TimewithCU) * nCUs);\n\n            LOG() << \"Expected performance of \" << nCUs << \" CUs vs 1 CU:\" << std::endl;\n            LOG() << std::setprecision(2) << pKFDQMTest->CuNegVariance << \" <= \" << std::fixed << std::setprecision(8)\n                  << ratio << \" <= \" << std::setprecision(2) << pKFDQMTest->CuPosVariance << std::endl;\n\n            EXPECT_TRUE((ratio >= pKFDQMTest->CuNegVariance) && (ratio <= pKFDQMTest->CuPosVariance));\n\n            RECORD(ratio) << \"Ratio-\" << nCUs << \"-CUs\";\n        }\n    } else {\n        LOG() << \"Skipping test: Test not supported for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n    }\n}\n\nTEST_F(KFDQMTest, BasicCuMaskingLinear) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicCuMaskingLinear));\n\n    TEST_END\n}\n\n\n// ====== ExtendedCuMasking Helper Functions ====== //\n\n\n#define CUMASK_DEBUG 0   // Enable extra output for debugging issues\n\n#if CUMASK_DEBUG\n#define DBG_PRINT printf\n#else\n#define DBG_PRINT\n#endif\n\n\n/*\n * Helper function to print multi-dword mask.\n *\n *   pHeader: A non-NULL pointer to a string to use as the header.\n *     pMask: A pointer to the mask to print out.\n * numDwords: Number of elements in mask array.\n *\n */\nstatic void printMask(const char *pHeader, uint32_t *pMask, uint32_t numDwords) {\n    printf(\"%s0x\", pHeader);\n    for (int i = numDwords - 1; i >= 0; i--) {\n        printf(\"%08x\", pMask[i]);\n    }\n    printf(\"\\n\");\n}\n\n\n/*\n * Set the CU mask for each specified WGPs.\n *\n * Note: The effect is cumulative, function can be called multiple times to\n *       set up additional WGPs in the provided pMask.\n *\n * pMask:      A non-NULL pointer to the CU mask.\n * maskConfig: Information on GPU configuration.\n * seMask:     Specifies SEs that are targetted.\n * saMask:     Specifies SAs that are targetted within the SEs specified.\n * wgpMask:    Specifies WGPs that are targetted within the (SE,SA) specified.\n *\n * For seMask, saMask, and wgpMask:\n *   One bit per SE/SA/WGP, multiple bits can be specified.\n *   Masks cannot be 0 (at least 1 SE, 1 SA and 1 WGP must be specified).\n *   Special value: -1 (specifies ALL)\n *\n */\nstatic bool setCUMask(uint32_t *pMask, mask_config_t maskConfig, uint32_t seMask, uint32_t saMask, uint32_t wgpMask) {\n\n    bool result = true;\n\n    if (pMask) {\n        if (seMask && saMask && wgpMask) {   // proceed only with non-zero mask\n            for (int i = 0; i < maskConfig.numWGPperSA; i++) {\n                if (((wgpMask >> i) & 1)) {\n                    for (int j = 0; j < maskConfig.numSAperSE; j++) {\n                        if (((saMask >> j) & 1)) {\n                            for (int k = 0; k < maskConfig.numSEs; k++) {\n                                if (((seMask >> k) & 1)) {\n                                    uint32_t insLoc = k * 2 + j * (2 * maskConfig.numSEs) + i * (2 * maskConfig.numSEs * maskConfig.numSAperSE);\n                                    pMask[insLoc / 32] |= (0x3 << (insLoc % 32));\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            LOG() << \"ERROR: SE/SA/WGP mask values must be non-zero!\\n\";\n            result = false;\n        }\n    } else {\n        LOG() << \"ERROR: pMask is NULL!\\n\";\n        result = false;\n    }\n\n    return result;\n}\n\n\n/*\n * Compute an adjusted CU mask to use when some WGPs are inactive.\n *\n * The adjusted mask takes into account the inactive WGPs by removing their corresponding\n * bits from the mask as these are skipped by KFD.   As bits are removed from the mask,\n * the remaining bit values are shifted right.\n *\n *   pAdjMask: A non-NULL pointer where the adjusted mask will be written.\n *      pMask: A non-NULL pointer to the CU mask.\n * maskConfig: Information on GPU configuration.\n *\n * Returns:\n *      true: If adjusted mask has one or more non-zero bit set.\n *     false: If the adjusted mask is all zeroes (no WGPs left to do work).\n *\n * When false is returned, we should skipped the specific test scenario.\n *\n */\nbool adjustMask(uint32_t *pAdjMask, uint32_t *pMask, mask_config_t maskConfig) {\n    int wi = 0;\n    int totalBits = maskConfig.numBits;\n    bool nonZero = false;\n\n    memset(pAdjMask, 0, sizeof(uint32_t) * maskConfig.numDwords);\n\n    for (int ri = 0; ri < totalBits; ri += 2) {\n\n        uint32_t value = (pMask[ri / 32] >> (ri % 32)) & 0x3;\n\n        if ((maskConfig.pInactiveMask[ri / 32] & (0x3 << (ri % 32))) != 0)\n        {\n            // skip that entry\n        }\n        else\n        {\n            uint32_t newValue = value << (wi % 32);\n            pAdjMask[wi / 32] |= newValue;\n            wi += 2;\n\n            if (value != 0) {\n                nonZero = true;\n            }\n        }\n    }\n\n#if CUMASK_DEBUG\n    printf(\"\\nAdjusting mask:\\n\");\n    printMask(\"    mask: \", pMask, maskConfig.numDwords);\n    printMask(\"inactive: \", maskConfig.pInactiveMask, maskConfig.numDwords);\n    printMask(\"adjusted: \", pAdjMask, maskConfig.numDwords);\n    printf(\"\\n\");\n#endif //CUMASK_DEBUG\n\n    return nonZero;\n}\n\n\n\n/*\n * Validates the result of a test.\n *\n * pMask:        A non-NULL pointer to the CU mask that was used for the test.\n * maskConfig:   Information on GPU configuration.\n * numWorkItems: Number of work items used for shader execution.\n * pOutput:      Pointer to the output array.\n * pResultMask:  If non-NULL, result mask constructed from output is stored at that memory location.\n *\n */\nstatic bool validateTest(uint32_t *pMask, mask_config_t maskConfig, uint32_t numWorkItems, out_data_t *pOutput, uint32_t *pResultMask)\n{\n    uint32_t resultMask[maskConfig.numDwords];\n    bool result = false;\n\n    memset(resultMask, 0, sizeof(resultMask));\n\n    for (int i = 0; i < numWorkItems; i++) {\n        DBG_PRINT(\"=== % 4d: 0x%08x [ se: %2d, sa: %2d, wgp: %2d]\\n\", i, pOutput[i].data, pOutput[i].se, pOutput[i].sa, pOutput[i].wgp);\n\n        setCUMask(resultMask, maskConfig,\n                  1 << pOutput[i].se,\n                  1 << pOutput[i].sa,\n                  1 << pOutput[i].wgp);\n    }\n\n    if (pResultMask) {\n        memcpy(pResultMask, resultMask, sizeof(resultMask));\n    }\n\n    if (maskConfig.pInactiveMask) {\n        // If some WGPs were inactive, compute a verify mask taking into account the inactive WGPs.\n        uint32_t verifyMask[maskConfig.numDwords];\n        memset(verifyMask, 0, sizeof(verifyMask));\n\n        for (int i = 0; i < maskConfig.numDwords; i++) {\n            verifyMask[i] = pMask[i] & ~maskConfig.pInactiveMask[i];\n        }\n\n#if CUMASK_DEBUG\n        printf(\"\\nValidate test:\\n\");\n        printMask(\"        mask: \", pMask, maskConfig.numDwords);\n        printMask(\"  resultMask: \", resultMask, maskConfig.numDwords);\n        printMask(\"inactiveMask: \", maskConfig.pInactiveMask, maskConfig.numDwords);\n        printMask(\"  verifyMask: \", verifyMask, maskConfig.numDwords);\n#endif //CUMASK_DEBUG\n\n        result = (memcmp(verifyMask, resultMask, sizeof(resultMask)) == 0);\n    } else {\n\n#if CUMASK_DEBUG\n        printf(\"\\nValidate test:\\n\");\n        printMask(\"        mask: \", pMask, maskConfig.numDwords);\n        printMask(\"  resultMask: \", resultMask, maskConfig.numDwords);\n#endif //CUMASK_DEBUG\n\n        result = (memcmp(pMask, resultMask, sizeof(resultMask)) == 0);\n    }\n\n    DBG_PRINT(\"      Result: %s\\n\\n\", result ? \"PASS\" : \"FAIL\");\n\n    return result;\n}\n\n/*\n * Set CU Mask, submit the testing shader, and validate the results.\n *\n * gpuNode:       The node to use for the test.\n * pMask:         A non-NULL pointer to the CU mask to use for the test.\n * maskConfig:    Information on GPU configuration.\n * programBuffer: The buffer that contains the shader program.\n * numWorkItems:  The number of work items to use.\n * pOutput:       A non-NULL pointer to the output buffer used by the shader.\n * pResultMask:   If non-NULL, result mask constructed from output is stored at that memory location.\n *\n */\nstatic bool testCUMask(int gpuNode, uint32_t *pMask, mask_config_t maskConfig, HsaMemoryBuffer &programBuffer, uint32_t numWorkItems, out_data_t *pOutput, uint32_t *pResultMask = NULL) {\n\n    PM4Queue queue;\n    uint32_t *pAdjMask = NULL;\n    uint32_t adjMask[maskConfig.numDwords];\n\n    if (maskConfig.pInactiveMask) {\n        if (adjustMask(adjMask, pMask, maskConfig)) {\n            pAdjMask = adjMask;\n        } else {\n            // Adjusted mask is all zeroes, skip test and mark as passing.\n            return true;\n        }\n    } else {\n        pAdjMask = pMask;\n    }\n\n    Dispatch dispatch(programBuffer);\n    dispatch.SetArgs(NULL, pOutput);\n    dispatch.SetDim(numWorkItems, 1, 1);\n\n    EXPECT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.SetCUMask(pAdjMask, maskConfig.numBits), gpuNode);\n\n    dispatch.Submit(queue);\n    dispatch.Sync();\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    return validateTest(pMask, maskConfig, numWorkItems, pOutput, pResultMask);\n}\n\n\n/*\n * ExtendedCuMasking\n *\n * Newer implementation of CU mask testing that focuses on correctness of masking.\n *\n * Unlike previous implementations, this new implementation does not rely on performance\n * measurements to decide if the masking took place.   Instead, this implementation checks\n * if waves were executed on all the CUs enabled and only the CUs enabled.\n *\n * Implementation does a series of tests, new tests can be easily added as needed.\n *\n * For each test, these steps are performed:\n *\n * 1) Decide the units that are enabled for the test (SEs, SAs, WGPs).\n * 2) Generate a CU mask that specifies the WGPs enabled on each (SE,SA) pairs.\n * 3) Set the mask for the queue and run a special shader.\n * 4) Shader records in a buffer the unit that is used by the wave (SE,SA,WGP).\n * 5) Test program analyses the results and verifies if shader used all and only the\n *    WGP units specified by the mask.\n *\n * Multiple tests are done with different combinations.\n * There are (2^numWGPs - 1) possibilities, not everything can be tested.\n *\n * For each new ASIC supported, the following changes might be required:\n * 1) Minor shader changes to put fill information into buffer.\n * 2) Format of out_data_t struct.\n * 3) Changes to validation code.\n *\n */\nstatic void extendedCuMasking(KFDTEST_PARAMETERS* pTestParameters) {\n\n    int gpuNode = pTestParameters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParameters->pTestObject;\n    const HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId >= FAMILY_GFX12) {  // Supporting GFX12 and up for now\n\n        // Lock to prevent interleave of logging on multigpu (multithreaded) testing\n        static std::mutex logMutex;\n\n        const HsaNodeProperties *pProps = pKFDQMTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n        const uint32_t activeCU = (pProps->NumFComputeCores / pProps->NumSIMDPerCU);\n        const uint32_t numSEs = pProps->NumShaderBanks;\n        const uint32_t numSAperSE = pProps->NumArrays;\n        const uint32_t numWGPperSA = pProps->NumCUPerArray / 2;\n        const uint32_t maxCU = numSEs * numSAperSE * numWGPperSA * 2;\n\n        std::ostringstream nodeStream;\n        nodeStream << \"(Node \" << gpuNode << \")\";\n        const std::string nodeStr = nodeStream.str();\n\n        logMutex.lock();\n        LOG() << std::endl;\n        LOG() << std::dec << \"****** GFX Configuration \" << nodeStr << \" ******\" << std::endl;\n        LOG() << std::dec << \"  Compute Cores (SIMD): \" << std::setw(3) << pProps->NumFComputeCores << std::endl;\n        LOG() << std::dec << \"          SIMDs per CU: \" << std::setw(3) << pProps->NumSIMDPerCU << std::endl;\n        LOG() << std::dec << \"            Active CUs: \" << std::setw(3) << activeCU << std::endl;\n        LOG() << std::dec << \"               Max CUs: \" << std::setw(3) << maxCU << std::endl;\n        LOG() << std::dec << \"        Shader Engines: \" << std::setw(3) << numSEs << std::endl;\n        LOG() << std::dec << \"            SAs per SE: \" << std::setw(3) << numSAperSE << std::endl;\n        LOG() << std::dec << \"           WGPs per SA: \" << std::setw(3) << numWGPperSA << std::endl;\n        LOG() << std::dec << \"****************************************\" << std::endl;\n        logMutex.unlock();\n\n        const uint32_t maskNumDwords = (maxCU + 31) / 32; /* Round up to the nearest multiple of 32 */\n        const uint32_t maskNumBits = maskNumDwords * 32;\n\n\n        uint32_t mask[maskNumDwords];\n        uint32_t inactiveMask[maskNumDwords];\n\n        mask_config_t maskConfig = { maskNumDwords, maskNumBits, numSEs, numSAperSE, numWGPperSA, NULL };\n\n        /*\n         * Note: On system with WGPs, CU bits in the same WGP must be either both set or both unset\n         *       i.e. enabling/disabling is on a per-WGP basis.\n         *\n         * Format of CU Mask array (Assuming 4 SEs)\n         *\n         * Bit    Value    Masking\n         *\n         *  0,1    0x03     SE0 SA0 WGP0 (i.e. CU0 and CU1)\n         *  2,3    0x0c     SE1 SA0 WGP0\n         *  4,5    0x30     SE2 SA0 WGP0\n         *  6,7    0xc0     SE3 SA0 WGP0\n         *\n         *  8,9    0x0300   SE0 SA1 WGP0\n         * 10,11   0x0c00   SE1 SA1 WGP0\n         * 12,13   0x3000   SE2 SA1 WGP0\n         * 14,15   0xc000   SE3 SA1 WGP0\n         *\n         * 16,17   0x030000 SE0 SA0 WGP1\n         * 18,19   0x030000 SE1 SA0 WGP1\n         * ...\n         * 32,33            SE0 SA0 WGP2\n         * ...\n         * 48,49            SE0 SA0 WGP3\n         * ...\n         *\n         */\n\n        /*\n         * Number of work items needs to be sufficiently large to have enough work items for each WGP enabled.\n         *\n         * Using total number of WGPs multiplied by 16.\n         *\n         */\n        const uint32_t numWorkItems = 16 * numSEs * numSAperSE * numWGPperSA;\n\n        // Allocate buffers for program and output\n        HsaMemoryBuffer programBuffer(PAGE_SIZE, gpuNode, true, false, true);\n        HsaMemoryBuffer outputBuffer(((sizeof(out_data_t) * numWorkItems) + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1), gpuNode, true, false, false);\n        out_data_t *pOutput = outputBuffer.As<out_data_t *>();\n\n        // Assemble shader\n        Assembler *pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n        ASSERT_NOTNULL_GPU(pAsm, gpuNode);\n        ASSERT_SUCCESS_GPU(pAsm->RunAssembleBuf(CheckCuMaskIsa, programBuffer.As<char*>()), gpuNode);\n\n\n       /*\n        * Check and record any inactive WPGs.\n        *\n        */\n        memset(mask, 0, sizeof(mask));\n        memset(inactiveMask, 0, sizeof(inactiveMask));\n\n        // Use full mask and collect all active CUs in inactiveMask\n        setCUMask(mask, maskConfig, -1, -1, -1);\n        if (testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput, inactiveMask)) {\n            // Using full mask, if all CUs are used, we expect them to be all active.\n            EXPECT_TRUE_GPU(activeCU == maxCU, gpuNode);\n        } else {\n            // Some CUs were not used, generate inactive mask and count inactive CUs.\n            uint32_t inactiveCount = 0;\n\n            // Flip bits and count inactive\n            for (int i = 0; i < maskNumDwords; i++) {\n                inactiveMask[i] = ~inactiveMask[i];\n                inactiveCount += __builtin_popcount(inactiveMask[i]);\n            }\n\n            // Check if what we detected is consistent with info from KFD\n            EXPECT_TRUE_GPU((activeCU + inactiveCount) == maxCU, gpuNode);\n\n            maskConfig.pInactiveMask = inactiveMask;\n\n            std::ostringstream logStr;\n            logStr << nodeStr << \" Inactive WGP detected: \" << inactiveCount << \"  0x\" << std::hex << std::setw(8);\n            for (int i = maskNumDwords - 1; i >= 0; i--) {\n                logStr << inactiveMask[i];\n            }\n            LOG() << logStr.str() << std::endl;\n        }\n\n\n        /*\n         * Generate symmetric test configuration for all (SE, SA, WGP) combinations, one level at a time.\n         *\n         * Other levels fully enabled.\n         *\n         * Example: If testing SE disablement, all SA/WGP are enabled on the SE that are used.\n         *          If testing SA disablement, all SE are used, all WGP are enabled on the SA enabled.\n         *\n         */\n        uint32_t totalConfigTested = 0;\n\n        // All SE combination (0 not allowed, need at least one enabled)\n        LOG() << nodeStr << \" === Testing SE mask (\" << ((1 << numSEs) - 1) << \" configs)\\n\";\n        for (int i = 1; i < (1 << numSEs); i++) {\n            memset(mask, 0, sizeof(mask));\n            DBG_PRINT(\"SE mask: 0x%x\\n\", i);\n            setCUMask(mask, maskConfig, i, -1, -1);\n            EXPECT_TRUE_GPU(testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput), gpuNode);\n            totalConfigTested++;\n        }\n\n        // All SA combinations (0 not allowed, need at least one enabled)\n        LOG() << nodeStr << \" === Testing SA mask (\" << ((1 << numSAperSE) - 1) << \" configs)\\n\";\n        for (uint32_t i = 1; i < (1 << numSAperSE); i++) {\n            memset(mask, 0, sizeof(mask));\n\n            DBG_PRINT(\"SA mask: 0x%x\\n\", i);\n            setCUMask(mask, maskConfig, -1, i, -1);\n            EXPECT_TRUE_GPU(testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput), gpuNode);\n            totalConfigTested++;\n        }\n\n        // All WGP combinations (0 not allowed, need at least one enabled)\n        LOG() << nodeStr << \" === Testing WGP mask (\" << ((1 << numWGPperSA) - 1) << \" configs)\\n\";\n        for (uint32_t i = 1; i < (1 << numWGPperSA); i++) {\n            memset(mask, 0, sizeof(mask));\n\n            DBG_PRINT(\"WGP mask: 0x%x\\n\", i);\n            setCUMask(mask, maskConfig, -1, -1, i);\n            EXPECT_TRUE_GPU(testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput), gpuNode);\n            totalConfigTested++;\n        }\n\n        /*\n         * Linear Masking\n         *\n         * Enable one WGP at a time until they are all enabled.\n         *\n         */\n        {\n            uint32_t totalWGPs = numSEs * numSAperSE * numWGPperSA;\n\n            LOG() << nodeStr << \" === Testing linear mask (\" << totalWGPs << \" configs)\\n\";\n\n            memset(mask, 0, sizeof(mask));\n\n            for (int32_t i = 0; i < totalWGPs; i++) {\n                mask[i / 16] |= (0x3 << (i * 2));\n\n#if CUMASK_DEBUG\n                printMask(\"  linear mask: \", mask, maskNumDwords);\n#endif //CUMASK_DEBUG\n\n                EXPECT_TRUE_GPU(testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput), gpuNode);\n                totalConfigTested++;\n            }\n        }\n\n        /*\n         * Random asymmetric config.\n         *\n         * Asymmetric, different WGPs/SAs are enabled/disabled on different SEs.\n         *\n         */\n        {\n            uint32_t randomCount = 1000;  // Total number of random test to perform\n            uint32_t seed = 1;            // Specifying a seed to have deterministic random sequence\n\n            srand(seed);\n\n            LOG() << nodeStr << \" === Testing \" << randomCount << \" random mask config...\\n\";\n\n            for (uint32_t i = 0; i < randomCount; i++) {\n\n                memset(mask, 0, sizeof(mask));\n\n                uint32_t wgpLeft = maxCU / 2;   // init to total WGPs\n                uint32_t maskIndex = 0;\n\n                while (wgpLeft > 0) {\n                    uint32_t wgpBlock = (wgpLeft > 16) ? 16 : wgpLeft;   // max 16 WGPs at a time\n                    wgpLeft -= wgpBlock;\n\n                    /*\n                     * Pick random number between 0 to (2^wgpBlock - 1) - 1.\n                     * Then add 1 to get random number between 1 to (2^wgpBlock - 1).\n                     * This ensure that we don't end up with 0 for all the dwords in the mask.\n                     */\n                    uint32_t wgpMask = (rand() % ((1ULL << wgpBlock) - 1)) + 1;\n\n                    // expand WGP mask to CU mask by doubling each individual bits.\n                    uint32_t expandToCUMask = 0;\n                    for (uint32_t j = 0; j < wgpBlock; j++) {\n                        if (wgpMask & (1 << j)) {\n                            expandToCUMask |= (0x3ULL << (j * 2));\n                        }\n                    }\n\n                    DBG_PRINT(\"maskIndex: %u  fullWGPMask: 0x%08x  expand: 0x%08x\\n\", maskIndex, wgpMask, expandToCUMask);\n\n                    mask[maskIndex++] = expandToCUMask;\n                }\n\n                EXPECT_TRUE_GPU(testCUMask(gpuNode, mask, maskConfig, programBuffer, numWorkItems, pOutput), gpuNode);\n                totalConfigTested++;\n            }\n        }\n\n        LOG() << std::endl;\n        LOG() << nodeStr << \" Total config tested: \" << totalConfigTested << std::endl;\n        LOG() << std::endl;\n\n    } else {\n        LOG() << \"Skipping test: Test not supported for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n    }\n}\n\nTEST_F(KFDQMTest, ExtendedCuMasking) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(extendedCuMasking));\n\n    TEST_END\n}\n\n#undef CUMASK_DEBUG\n#undef DBG_PRINT\n\n// ====== End of ExtendedCUMasking Functions ====== //\n\n\n\n/**\n * Apply CU masking where the number of CUs is equal across all Shader Engines\n * This will work due to the HW splitting the workload unevenly across the Shader\n * Engines when ((#ofCUs)/(#ofShaderEngines)) is not a whole number. The tests above\n * will not yield viable results when an uneven distribution of CUs is used over multiple\n * shader engines (e.g. 0x1000100030003), until the HW changes how it schedules work.\n */\nvoid BasicCuMaskingEven(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    const HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    if (m_FamilyId >= FAMILY_VI) {\n        const HsaNodeProperties *pNodeProperties = pKFDQMTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n        uint32_t ActiveCU = (pNodeProperties->NumFComputeCores / pNodeProperties->NumSIMDPerCU);\n        uint32_t numShaderEngines = pNodeProperties->NumShaderBanks;\n        if (numShaderEngines == 1) {\n            LOG() << \"Skipping test: Only 1 Shader Engine present.\" << std::endl;\n            return;\n        }\n\n        LOG() << std::dec << \"# Compute cores: \" << pNodeProperties->NumFComputeCores << std::endl;\n        LOG() << std::dec << \"# SIMDs per CU: \" << pNodeProperties->NumSIMDPerCU << std::endl;\n        LOG() << std::dec << \"# Shader engines: \" << numShaderEngines << std::endl;\n        LOG() << std::dec << \"# Active CUs: \" << ActiveCU << std::endl;\n        HSAint64 TimewithCU1, TimewithCU;\n        uint32_t maskNumDwords = (ActiveCU + 31) / 32; /* Round up to the nearest multiple of 32 */\n        uint32_t maskNumBits = maskNumDwords * 32;\n        uint32_t mask[maskNumDwords];\n        int numCuPerShader = ActiveCU / numShaderEngines;\n        double ratio;\n\n        /* In KFD we symmetrically map mask to all SEs:\n         * mask[0] bit0 -> se0 cu0;\n         * mask[0] bit1 -> se1 cu0;\n         * ... (if # SE is 4)\n         * mask[0] bit4 -> se0 cu1;\n         * ...\n         */\n        /* Set Mask to 1 CU per SE */\n        memset(mask, 0, maskNumDwords * sizeof(uint32_t));\n        for (int i = 0; i < numShaderEngines; i++) {\n            int maskIndex = (i / 32) % maskNumDwords;\n            mask[maskIndex] |= 1 << (i % 32);\n        }\n\n        /* Execute once to get any HW optimizations out of the way */\n        pKFDQMTest->TimeConsumedwithCUMask(gpuNode, mask, maskNumBits);\n\n        LOG() << \"Getting baseline performance numbers (1 CU per SE)\" << std::endl;\n        TimewithCU1 = pKFDQMTest->GetAverageTimeConsumedwithCUMask(gpuNode, mask, maskNumBits, 3);\n\n        /* Each loop will add 1 more CU per SE. We use the mod and divide to handle\n         * when SEs aren't distributed in multiples of 32 (e.g. Tonga)\n         * OR the new bit in for simplicity instead of re-creating the mask each iteration\n         */\n        for (int x = 0; x < numCuPerShader; x++) {\n            for (int se = 0; se < numShaderEngines; se++) {\n                int offset = x * numShaderEngines + se;\n                int maskIndex = (offset / 32) % maskNumDwords;\n                mask[maskIndex] |= 1 << (offset % 32);\n            }\n            int nCUs = x + 1;\n\n            TimewithCU = pKFDQMTest->TimeConsumedwithCUMask(gpuNode, mask, maskNumBits);\n            ratio = (double)(TimewithCU1) / ((double)(TimewithCU) * nCUs);\n\n            LOG() << \"Expected performance of \" << nCUs << \" CU(s)/SE vs 1 CU/SE:\" << std::endl;\n            LOG() << std::setprecision(2) << pKFDQMTest->CuNegVariance << \" <= \" << std::fixed << std::setprecision(8)\n                  << ratio << \" <= \" << std::setprecision(2) << pKFDQMTest->CuPosVariance << std::endl;\n\n            EXPECT_TRUE_GPU((ratio >= pKFDQMTest->CuNegVariance) && (ratio <= pKFDQMTest->CuPosVariance), gpuNode);\n\n            RECORD(ratio) << \"Ratio-\" << nCUs << \"-CUs\";\n        }\n    } else {\n        LOG() << \"Skipping test: Test not supported for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n    }\n}\n\nTEST_F(KFDQMTest, BasicCuMaskingEven) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicCuMaskingEven));\n\n    TEST_END\n}\n\nvoid testQueuePriority(KFDTEST_PARAMETERS* pTestParamters, bool isSamePipe)\n{\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    const HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    if (m_FamilyId < FAMILY_VI) {\n        LOG() << \"Skipping test: Shader won't run on CI.\" << std::endl;\n        return;\n    }\n\n    // Reduce test case if running on emulator\n    // Reduction applies to all 3 dims (effect is cubic)\n    const int scaleDown = (g_IsEmuMode ? 4 : 1);\n\n    HsaMemoryBuffer syncBuf(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HSAint32 *syncBuffer = syncBuf.As<HSAint32*>();\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    //ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(LoopIsa, isaBuffer.As<char*>()));\n\tASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(LoopIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch[2] = {\n        Dispatch(isaBuffer, true),\n        Dispatch(isaBuffer, true)\n    };\n\n    const int queueCount = isSamePipe ? 13 : 2;\n    int activeTaskBitmap = 0x3;\n    HSAuint64 startTime, endTime[2];\n    HsaEvent *pHsaEvent[2];\n    int numEvent = 2;\n    PM4Queue queue[queueCount];\n    HSA_QUEUE_PRIORITY priority[2] = {\n        HSA_QUEUE_PRIORITY_LOW,\n        HSA_QUEUE_PRIORITY_HIGH\n    };\n    int i;\n\n    /*\n     * For different pipe variation:\n     *   Only two queues are created, they should be on two different pipes.\n     *\n     * For same pipe variation:\n     *   queue[2..12] are dummy queues. Create queue in this sequence to\n     *   render queue[0] and queue[1] on same pipe with no assumptions\n     *   about the number of pipes used by KFD. Queue #12 is a multiple\n     *   of 1, 2, 3 and 4, so it falls on pipe 0 for any number of pipes\n     */\n\tEXPECT_SUCCESS_GPU(queue[0].Create(gpuNode), gpuNode);  // Queue 0 is on Pipe 0\n    if (isSamePipe) {\n        for (i = 2; i < queueCount; i++)\n            EXPECT_SUCCESS_GPU(queue[i].Create(gpuNode), gpuNode);\n    }\n    EXPECT_SUCCESS_GPU(queue[1].Create(gpuNode), gpuNode);\n\n    for (i = 0; i < 2; i++) {\n        syncBuffer[i] = -1;\n        queue[i].Update(BaseQueue::DEFAULT_QUEUE_PERCENTAGE, priority[i], false);\n        pHsaEvent[i] = dispatch[i].GetHsaEvent();\n        pHsaEvent[i]->EventData.EventData.SyncVar.SyncVar.UserData = &syncBuffer[i];\n        dispatch[i].SetDim(1024 / scaleDown , 16 / scaleDown, 16 / scaleDown);\n    }\n\n    startTime = GetSystemTickCountInMicroSec();\n    for (i = 0; i < 2; i++)\n        dispatch[i].Submit(queue[i]);\n\n    while (activeTaskBitmap > 0) {\n        hsaKmtWaitOnMultipleEvents(pHsaEvent, numEvent, false, g_TestTimeOut);\n        for (i = 0; i < 2; i++) {\n            if ((activeTaskBitmap & (1 << i)) && (syncBuffer[i] == pHsaEvent[i]->EventId)) {\n                endTime[i] = GetSystemTickCountInMicroSec();\n                activeTaskBitmap &= ~(1 << i);\n            }\n        }\n    }\n\n    for (i = 0; i < 2; i++) {\n        int usecs = endTime[i] - startTime;\n        LOG() << \"Task priority: \" << std::dec << priority[i] << \"\\t\";\n        LOG() << \"Task duration: \" << std::dec << std::setw(10) << usecs << \" usecs\" << std::endl;\n    }\n\n    for (i = 0; i < queueCount; i++) {\n        EXPECT_SUCCESS_GPU(queue[i].Destroy(), gpuNode);\n    }\n}\n\nstatic void QueuePriorityOnDifferentPipe(KFDTEST_PARAMETERS* pTestParamters) {\n\n\ttestQueuePriority(pTestParamters, false);\n}\n\nTEST_F(KFDQMTest, QueuePriorityOnDifferentPipe) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(QueuePriorityOnDifferentPipe));\n\n    TEST_END\n}\n\nvoid QueuePriorityOnSamePipe(KFDTEST_PARAMETERS* pTestParamters) {\n\n    testQueuePriority(pTestParamters, true);\n}\n\nTEST_F(KFDQMTest, QueuePriorityOnSamePipe) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(QueuePriorityOnSamePipe));\n\n    TEST_END\n}\n\nvoid KFDQMTest::SyncDispatch(const HsaMemoryBuffer& isaBuffer, void* pSrcBuf, void* pDstBuf, int node) {\n    PM4Queue queue;\n\n    if (node == -1)\n        node = m_NodeInfo.HsaDefaultGPUNode();\n\n    ASSERT_GE_GPU(node, 0, node) << \"failed to get GPU Node\";\n\n    Dispatch dispatch(isaBuffer);\n    dispatch.SetArgs(pSrcBuf, pDstBuf);\n    dispatch.SetDim(1, 1, 1);\n\n    ASSERT_SUCCESS_GPU(queue.Create(node), node);\n\n    dispatch.Submit(queue);\n    dispatch.Sync();\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), node);\n}\n\nvoid EmptyDispatch(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(NoopIsa, isaBuffer.As<char*>()), gpuNode);\n\n    pKFDQMTest->SyncDispatch(isaBuffer, NULL, NULL, gpuNode);\n\n}\n\nTEST_F(KFDQMTest, EmptyDispatch) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(EmptyDispatch));\n\n    TEST_END\n}\n\nvoid SimpleWriteDispatch(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcBuffer(PAGE_SIZE, gpuNode, false);\n    HsaMemoryBuffer destBuffer(PAGE_SIZE, gpuNode);\n\n    srcBuffer.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()),gpuNode);\n\n    pKFDQMTest->SyncDispatch(isaBuffer, srcBuffer.As<void*>(), destBuffer.As<void*>(), gpuNode);\n\n    EXPECT_EQ(destBuffer.As<unsigned int*>()[0], 0x01010101);\n\n}\n\nTEST_F(KFDQMTest, SimpleWriteDispatch) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SimpleWriteDispatch));\n\n    TEST_END\n}\n\nstatic void MultipleCpQueuesStressDispatch(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    static const unsigned int MAX_CP_QUEUES = 16;\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcBuffer(PAGE_SIZE, gpuNode, false);\n    HsaMemoryBuffer destBuffer(PAGE_SIZE, gpuNode);\n\n    unsigned int* src = srcBuffer.As<unsigned int*>();\n    unsigned int* dst = destBuffer.As<unsigned int*>();\n\n    static const HSAuint64 TEST_TIME_SEC = 15;\n    HSAuint64 initialTime, curTime;\n    unsigned int numIter = 0;\n    HSAuint64 timePassed = 0;\n\n    unsigned int i;\n    PM4Queue queues[MAX_CP_QUEUES];\n    Dispatch* dispatch[MAX_CP_QUEUES];\n\n    destBuffer.Fill(0xFF);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    for (i = 0; i < MAX_CP_QUEUES; ++i)\n        ASSERT_SUCCESS_GPU(queues[i].Create(gpuNode), gpuNode) << \" QueueId=\" << i;\n\n    initialTime = GetSystemTickCountInMicroSec();\n\n    do {\n        for (i = 0; i < MAX_CP_QUEUES; ++i) {\n            dispatch[i] = new Dispatch(isaBuffer);\n            src[i] = numIter;\n            dst[i] = 0xff;\n            dispatch[i]->SetArgs(&src[i], &dst[i]);\n            dispatch[i]->SetDim(1, 1, 1);\n            dispatch[i]->Submit(queues[i]);\n        }\n        for (i = 0; i < MAX_CP_QUEUES; ++i) {\n            dispatch[i]->Sync();\n            EXPECT_EQ_GPU(dst[i], src[i], gpuNode);\n            delete dispatch[i];\n        }\n        ++numIter;\n        curTime = GetSystemTickCountInMicroSec();\n        timePassed = (curTime - initialTime) / 1000000;\n    } while (timePassed < TEST_TIME_SEC);\n\n    LOG() << \"Total iterated : \" << std::dec << numIter << std::endl;\n\n    for (i = 0; i < MAX_CP_QUEUES; ++i)\n       EXPECT_SUCCESS_GPU(queues[i].Destroy(), gpuNode);\n\n\n}\n\nTEST_F(KFDQMTest, MultipleCpQueuesStressDispatch) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(MultipleCpQueuesStressDispatch));\n\n    TEST_END\n}\n\nstatic void CpuWriteCoherence(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    PM4Queue queue;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    /* The queue might be full and we fail to submit. There is always one word space unused in queue.\n     * So let rptr one step ahead then we continually submit packet.\n     */\n    queue.PlaceAndSubmitPacket(PM4NopPacket());\n    queue.Wait4PacketConsumption();\n    EXPECT_EQ(1, queue.Rptr());\n\n    do {\n        queue.PlaceAndSubmitPacket(PM4NopPacket());\n    } while (queue.Wptr() != 0);\n\n    queue.Wait4PacketConsumption();\n\n    EXPECT_EQ_GPU(0, queue.Rptr(), gpuNode);\n\n    /* Now that the GPU has cached the PQ contents, we modify them in CPU cache and\n     * ensure that the GPU sees the updated value:\n     */\n    queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0x42, 0x42));\n\n    queue.Wait4PacketConsumption(event);\n\n    WaitOnValue(destBuf.As<unsigned int*>(), 0x42);\n\n    hsaKmtDestroyEvent(event);\n}\n\nTEST_F(KFDQMTest, CpuWriteCoherence) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CpuWriteCoherence));\n\n    TEST_END\n}\n\nstatic void CreateAqlCpQueue(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    AqlQueue queue;\n\n    HsaMemoryBuffer pointers(PAGE_SIZE, gpuNode, /*zero*/true, /*local*/false, /*exec*/false, /*isScratch */false, /* isReadOnly */false, /* isUncached */false, /* NonPaged */g_baseTest->NeedNonPagedWptr(gpuNode));\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode, PAGE_SIZE, pointers.As<HSAuint64 *>()), gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, CreateAqlCpQueue) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(CreateAqlCpQueue));\n\n    TEST_END\n}\n\nstatic void QueueLatency(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    PM4Queue queue;\n    const int queueSize = PAGE_SIZE * 2;\n    const int packetSize = PM4ReleaseMemoryPacket(m_FamilyId, 0, 0, 0, 0, 0).SizeInBytes();\n    /* We always leave one NOP(dword) empty after packet which is required by ring itself.\n     * We also place NOPs when queue wraparound to avoid crossing buffer end. See PlacePacket().\n     * So the worst case is that we need two packetSize space to place one packet.\n     * Like below, N=NOP,E=Empty,P=Packet.\n     * |E|E|E|E|E|E|E|rptr...wptr|E|E|E|E|E| ---> |P|P|P|P|P|P|E|rptr...wptr|N|N|N|N|N|\n     * So to respect that, we reserve packetSize space for these additional NOPs.\n     * Also we reserve the remainder of the division by packetSize explicitly.\n     * Reserve another packetSize for event-based wait which uses a releseMemory packet.\n     */\n    const int reservedSpace = packetSize + queueSize % packetSize + packetSize;\n    const int slots = (queueSize - reservedSpace) / packetSize;\n    HSAint64 queue_latency_avg = 0, queue_latency_min, queue_latency_max, queue_latency_med;\n    HSAint64 overhead, workload;\n    HSAint64 *queue_latency_arr = reinterpret_cast<HSAint64*>(calloc(slots, sizeof(HSAint64)));\n    const int skip = 2;\n    const char *fs[skip] = {\"1st\", \"2nd\"};\n    HsaClockCounters *ts;\n    HSAuint64 *qts;\n    int i = 0;\n\n    ASSERT_NE_GPU((HSAuint64)queue_latency_arr, 0, gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode, queueSize), gpuNode);\n\n    LOG() << std::dec << \"Queue Submit NanoSeconds (\" << slots << \" Packets)\" << std::endl;\n\n    HsaMemoryBuffer buf(ALIGN_UP(slots * sizeof(HsaClockCounters), PAGE_SIZE), 0);\n    ts = buf.As<HsaClockCounters*>();\n\n    HsaMemoryBuffer qbuf(ALIGN_UP(slots * sizeof(HSAuint64), PAGE_SIZE), 0);\n    qts = qbuf.As<HSAuint64*>();\n\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    /* GpuCounter overhead*/\n    do {\n        hsaKmtGetClockCounters(gpuNode, &ts[i]);\n    } while (++i < slots);\n    overhead = ts[slots-1].GPUClockCounter - ts[0].GPUClockCounter;\n    overhead /= 2 * (slots - 1);\n\n    /* Submit packets serially*/\n    i = 0;\n    do {\n        queue.PlacePacket(PM4ReleaseMemoryPacket(m_FamilyId, true,\n                    (HSAuint64)&qts[i],\n                    0,\n                    true,\n                    1));\n        hsaKmtGetClockCounters(gpuNode, &ts[i]);\n        queue.SubmitPacket();\n        queue.Wait4PacketConsumption(event);\n    } while (++i < slots);\n\n    /* Calculate timing which includes workload and overhead*/\n    i = 0;\n    do {\n        HSAint64 queue_latency = qts[i] - ts[i].GPUClockCounter;\n\n        EXPECT_GE_GPU(queue_latency, 0, gpuNode);\n\n        queue_latency_arr[i] = queue_latency;\n        if (i >= skip)\n            queue_latency_avg += queue_latency;\n    } while (++i < slots);\n    /* Calculate avg from packet[skip, slots-1] */\n    queue_latency_avg /= (slots - skip);\n\n    /* Workload of queue packet itself */\n    i = 0;\n    do {\n        queue.PlacePacket(PM4ReleaseMemoryPacket(m_FamilyId, true,\n                    (HSAuint64)&qts[i],\n                    0,\n                    true,\n                    1));\n    } while (++i < slots);\n    queue.SubmitPacket();\n    queue.Wait4PacketConsumption(event);\n\n    hsaKmtDestroyEvent(event);\n    /* qts[i] records the timestamp of the end of packet[i] which is\n     * approximate that of the beginging of packet[i+1].\n     * The workload total is [0, skip], [skip+1, slots-1].\n     * And We ignore [0, skip], that means we ignore (skip+1) packets.\n     */\n    workload = qts[slots - 1] - qts[skip];\n    workload /= (slots - 1 - skip);\n\n    EXPECT_GE_GPU(workload, 0, gpuNode);\n\n    i = 0;\n    do {\n        /* The queue_latency is not that correct as the workload and overhead are average*/\n        queue_latency_arr[i] -= workload + overhead;\n        /* The First submit takes an HSAint64 time*/\n        if (i < skip)\n            LOG() << \"Queue Latency \" << fs[i] << \": \\t\" << CounterToNanoSec(queue_latency_arr[i]) << std::endl;\n    } while (++i < slots);\n\n    std::sort(queue_latency_arr + skip, queue_latency_arr + slots);\n\n    queue_latency_min = queue_latency_arr[skip];\n    queue_latency_med = queue_latency_arr[(slots+skip)/2];\n    queue_latency_max = queue_latency_arr[slots-1];\n\n    LOG() << \"Queue Latency Avg:     \\t\" << CounterToNanoSec(queue_latency_avg) << std::endl;\n    LOG() << \"Queue Latency Min:     \\t\" << CounterToNanoSec(queue_latency_min) << std::endl;\n    LOG() << \"Queue Latency Median:  \\t\" << CounterToNanoSec(queue_latency_med) << std::endl;\n    LOG() << \"Queue Latency Max:     \\t\" << CounterToNanoSec(queue_latency_max) << std::endl;\n    LOG() << \"Queue Packet Workload: \\t\" << CounterToNanoSec(workload) << std::endl;\n    LOG() << \"Get GpuCounter Overhead: \\t\" << CounterToNanoSec(overhead) << std::endl;\n\n    RECORD(CounterToNanoSec(queue_latency_avg)) << \"Queue-Latency-Avg\";\n    RECORD(CounterToNanoSec(queue_latency_min)) << \"Queue-Latency-Min\";\n    RECORD(CounterToNanoSec(queue_latency_med)) << \"Queue-Latency-Med\";\n    RECORD(CounterToNanoSec(queue_latency_max)) << \"Queue-Latency-Max\";\n    RECORD(CounterToNanoSec(workload)) << \"Queue-Packet-Workload\";\n    RECORD(CounterToNanoSec(overhead)) << \"GpuCounter-Overhead\";\n\n}\n\nTEST_F(KFDQMTest, QueueLatency) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(QueueLatency));\n\n    TEST_END\n}\n\nstatic void CpQueueWraparound(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    PM4Queue queue;\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    HsaEvent *event;\n    ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event), gpuNode);\n\n    for (unsigned int pktIdx = 0; pktIdx <= PAGE_SIZE/sizeof(PM4WRITE_DATA_CI); ++pktIdx) {\n        queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), pktIdx, pktIdx));\n        queue.Wait4PacketConsumption(event);\n        WaitOnValue(destBuf.As<unsigned int*>(), pktIdx);\n    }\n\n    for (unsigned int pktIdx = 0; pktIdx <= PAGE_SIZE/sizeof(PM4WRITE_DATA_CI); ++pktIdx) {\n        queue.PlaceAndSubmitPacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), pktIdx, pktIdx));\n        queue.Wait4PacketConsumption(event);\n        WaitOnValue(destBuf.As<unsigned int*>(), pktIdx);\n    }\n\n    hsaKmtDestroyEvent(event);\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, CpQueueWraparound) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(CpQueueWraparound));\n\n    TEST_END\n}\n\nstatic void SdmaQueueWraparound(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    int bufSize = PAGE_SIZE;\n\n    SDMAQueue queue;\n\n    HsaMemoryBuffer destBuf(bufSize << 1, gpuNode, false);\n    HsaMemoryBuffer srcBuf(bufSize, gpuNode, false);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    for (unsigned int pktIdx = 0;  pktIdx <= queue.Size()/sizeof(SDMA_PKT_COPY_LINEAR); ++pktIdx) {\n        destBuf.Fill(0x0);\n        srcBuf.Fill(pktIdx);\n        queue.PlaceAndSubmitPacket(\n                SDMACopyDataPacket(queue.GetFamilyId(), destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize));\n        queue.PlaceAndSubmitPacket(\n                SDMAWriteDataPacket(queue.GetFamilyId(), destBuf.As<unsigned int*>() + bufSize/4, 0x02020202));\n        queue.Wait4PacketConsumption();\n\n        EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int*>() + bufSize/4, 0x02020202), gpuNode);\n\n        EXPECT_SUCCESS_GPU(memcmp(\n                destBuf.As<unsigned int*>(), srcBuf.As<unsigned int*>(), bufSize), gpuNode);\n    }\n\n    for (unsigned int pktIdx = 0; pktIdx <= queue.Size()/sizeof(SDMA_PKT_WRITE_UNTILED); ++pktIdx) {\n        queue.PlaceAndSubmitPacket(SDMAWriteDataPacket(queue.GetFamilyId(), destBuf.As<unsigned int*>(), pktIdx));\n        queue.Wait4PacketConsumption();\n        WaitOnValue(destBuf.As<unsigned int*>(), pktIdx);\n    }\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n}\n\nTEST_F(KFDQMTest, SdmaQueueWraparound) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(SdmaQueueWraparound));\n\n    TEST_END\n}\n\nstruct AtomicIncThreadParams {\n    HSAint64* pDest;\n    volatile unsigned int count;\n    volatile bool loop;\n};\n\nunsigned int AtomicIncThread(void* pCtx) {\n    AtomicIncThreadParams* pArgs = reinterpret_cast<AtomicIncThreadParams*>(pCtx);\n\n    while (pArgs->loop) {\n        AtomicInc(pArgs->pDest);\n        ++pArgs->count;\n    }\n\n    LOG() << \"CPU atomic increments finished\" << std::endl;\n\n    return 0;\n}\n\nstatic void Atomics(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDQMTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    if (!hasPciAtomicsSupport(gpuNode)) {\n        LOG() << \"Skipping test: Node doesn't support Atomics.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer isaBuf(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer destBuf(PAGE_SIZE, gpuNode);\n\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(AtomicIncIsa, isaBuf.As<char*>()), gpuNode);\n\n    Dispatch dispatch(isaBuf);\n    dispatch.SetArgs(destBuf.As<void*>(), NULL);\n    dispatch.SetDim(1024, 1, 1);\n\n    hsaKmtSetMemoryPolicy(gpuNode, HSA_CACHING_CACHED, HSA_CACHING_CACHED, NULL, 0);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    AtomicIncThreadParams params;\n    params.pDest = destBuf.As<HSAint64*>();\n    params.loop = true;\n    params.count = 0;\n\n    uint64_t threadId;\n\n    ASSERT_EQ_GPU(true, StartThread(&AtomicIncThread, &params, threadId), gpuNode);\n\n    LOG() << \"Waiting for CPU to atomic increment 1000 times\" << std::endl;\n\n    while (params.count < 1000)\n        {}\n\n    LOG() << \"Submitting the GPU atomic increment shader\" << std::endl;\n\n    dispatch.Submit(queue);\n    dispatch.Sync();\n\n    params.loop = false;\n\n    WaitForThread(threadId);\n\n    EXPECT_EQ_GPU(destBuf.As<unsigned int*>()[0], 1024 + params.count, gpuNode);\n\n    LOG() << \"GPU increments: 1024, CPU increments: \" << std::dec\n            << params.count << std::endl;\n\n    queue.Destroy();\n}\n\nTEST_F(KFDQMTest, Atomics) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(Atomics));\n\n    TEST_END\n}\n\nTEST_F(KFDQMTest, mGPUShareBO) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    unsigned int src_node = 2;\n    unsigned int dst_node = 1;\n\n    if (g_TestDstNodeId != -1 && g_TestNodeId != -1) {\n        src_node = g_TestNodeId;\n        dst_node = g_TestDstNodeId;\n    }\n\n    HsaMemoryBuffer shared_addr(PAGE_SIZE, dst_node, true, false, false, false);\n\n    HsaMemoryBuffer srcNodeMem(PAGE_SIZE, src_node);\n    HsaMemoryBuffer dstNodeMem(PAGE_SIZE, dst_node);\n\n    /* Handle ISA to write to local memory BO */\n    HsaMemoryBuffer isaBufferSrc(PAGE_SIZE, src_node, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer isaBufferDst(PAGE_SIZE, dst_node, true/*zero*/, false/*local*/, true/*exec*/);\n\n    srcNodeMem.Fill(0x05050505);\n\n    ASSERT_SUCCESS(m_pAsm->RunAssemble(CopyDwordIsa));\n\n    m_pAsm->CopyInstrStream(isaBufferSrc.As<char*>());\n    SyncDispatch(isaBufferSrc, srcNodeMem.As<void*>(), shared_addr.As<void *>(), src_node);\n\n    m_pAsm->CopyInstrStream(isaBufferDst.As<char*>());\n    SyncDispatch(isaBufferDst, shared_addr.As<void *>(), dstNodeMem.As<void*>(), dst_node);\n\n    EXPECT_EQ(dstNodeMem.As<unsigned int*>()[0], 0x05050505);\n\n    EXPECT_SUCCESS(shared_addr.UnmapMemToNodes(&dst_node, 1));\n\n    TEST_END\n}\n\nstatic void\nsdma_copy(HSAuint32 node, void *src, void *const dst[], int n, HSAuint64 size) {\n    SDMAQueue sdmaQueue;\n    HsaEvent *event;\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, node, &event));\n    ASSERT_SUCCESS(sdmaQueue.Create(node));\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(), dst, src, n, size));\n    sdmaQueue.Wait4PacketConsumption(event);\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\n    hsaKmtDestroyEvent(event);\n}\n\nstatic void\nsdma_fill(HSAint32 node, void *dst, unsigned int data, HSAuint64 size) {\n    SDMAQueue sdmaQueue;\n    HsaEvent *event;\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, node, &event));\n    ASSERT_SUCCESS(sdmaQueue.Create(node));\n    sdmaQueue.PlaceAndSubmitPacket(SDMAFillDataPacket(sdmaQueue.GetFamilyId(), dst, data, size));\n    sdmaQueue.Wait4PacketConsumption(event);\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\n    hsaKmtDestroyEvent(event);\n}\n\nTEST_F(KFDQMTest, P2PTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n    if (!hsakmt_is_dgpu()) {\n        LOG() << \"Skipping test: Two GPUs are required, but no dGPUs are present.\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: At least two GPUs are required.\" << std::endl;\n        return;\n    }\n    std::vector<int> nodes;\n\n    /* This test simulates RT team's P2P part in IPCtest:\n     *\n     * +------------------------------------------------+\n     * |         gpu1           gpu2           gpuX     |\n     * |gpu1 mem ----> gpu2 mem ----> gpuX mem          |\n     * |        \\               \\               \\  mGPUShareBO     |\n     * |         \\               \\               \\      |\n     * |    system buffer   system buffer  system buffer|\n     * +------------------------------------------------+\n     *\n     * Copy data from current GPU memory to next GPU memory and system memory\n     * Using current GPU, aka p2p push.\n     * Verify the system buffer has the expected content after each push.\n     */\n\n    /* Users can use \"--node=gpu1 --dst_node=gpu2\" to specify devices */\n    if (g_TestDstNodeId != -1 && g_TestNodeId != -1) {\n        nodes.push_back(g_TestNodeId);\n        nodes.push_back(g_TestDstNodeId);\n\n        if (!m_NodeInfo.IsPeerAccessibleByNode(g_TestNodeId, g_TestDstNodeId)) {\n            LOG() << \"Skipping test: Dst GPU specified is not peer-accessible.\" << std::endl;\n            return;\n        }\n        if (nodes[0] == nodes[1]) {\n            LOG() << \"Skipping test: Different GPUs must be specified (2 GPUs required).\" << std::endl;\n            return;\n        }\n    } else {\n        nodes = m_NodeInfo.GetNodesWithGPU();\n        if (nodes.size() < 2) {\n            LOG() << \"Skipping test: Test requires at least one large bar GPU.\" << std::endl;\n            LOG() << \"               or two GPUs are XGMI connected.\" << std::endl;\n            return;\n        }\n    }\n\n    HSAuint32 *sysBuf;\n    HSAuint32 size = 16ULL<<20;  // bigger than 16MB to test non-contiguous memory\n    HsaMemFlags memFlags = {0};\n    HsaMemMapFlags mapFlags = {0};\n    memFlags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    memFlags.ui32.HostAccess = 0;\n    memFlags.ui32.NonPaged = 1;\n    memFlags.ui32.NoNUMABind = 1;\n    unsigned int end = size / sizeof(HSAuint32) - 1;\n\n    /* 1. Allocate a system buffer and allow the access to GPUs */\n    EXPECT_SUCCESS(hsaKmtAllocMemory(0, size, m_MemoryFlags,\n                                     reinterpret_cast<void **>(&sysBuf)));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(sysBuf, size, NULL,\n                                             mapFlags, nodes.size(), (HSAuint32 *)&nodes[0]));\n#define MAGIC_NUM 0xdeadbeaf\n\n    /* First GPU fills mem with MAGIC_NUM */\n    void *src, *dst;\n    HSAuint32 cur = nodes[0], next;\n    ASSERT_SUCCESS(hsaKmtAllocMemory(cur, size, memFlags, reinterpret_cast<void**>(&src)));\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(src, size, NULL));\n    sdma_fill(cur, src, MAGIC_NUM, size);\n\n    for (unsigned i = 1; i <= nodes.size(); i++) {\n        int n;\n        memset(sysBuf, 0, size);\n\n        /* Last GPU just copy mem to sysBuf*/\n        if (i == nodes.size()) {\n               n = 1;\n               next = 0;/*system memory node*/\n               dst = 0;\n        } else {\n            n = 2;\n            next = nodes[i];\n\n            /* check if cur access next node */\n            if (!m_NodeInfo.IsPeerAccessibleByNode(next, cur))\n                continue;\n\n            ASSERT_SUCCESS(hsaKmtAllocMemory(next, size, memFlags, reinterpret_cast<void**>(&dst)));\n            ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(dst, size, NULL));\n        }\n\n        LOG() << \"Test \" << cur << \" -> \" << next << std::endl;\n        /* Copy to sysBuf and next GPU*/\n        void *dst_array[] = {sysBuf, dst};\n        sdma_copy(cur, src, dst_array, n, size);\n\n        /* Verify the data*/\n        EXPECT_EQ(sysBuf[0], MAGIC_NUM);\n        EXPECT_EQ(sysBuf[end], MAGIC_NUM);\n\n        LOG() << \"PASS \" << cur << \" -> \" << next << std::endl;\n\n        EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(src));\n        EXPECT_SUCCESS(hsaKmtFreeMemory(src, size));\n\n        cur = next;\n        src = dst;\n    }\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(sysBuf));\n    EXPECT_SUCCESS(hsaKmtFreeMemory(sysBuf, size));\n\n    TEST_END\n}\n\nstatic void PM4EventInterrupt(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    const HSAuint64 bufSize = PAGE_SIZE;\n    const int packetCount = bufSize / sizeof(unsigned int);\n    const int totalPacketSize = packetCount * PM4WriteDataPacket(0, 0).SizeInBytes() +\n                                                PM4ReleaseMemoryPacket(m_FamilyId, 0, 0, 0).SizeInBytes();\n    const int queueSize = RoundToPowerOf2(totalPacketSize);\n\n    /* Reduce number of iteration if running with emulator. */\n    const int numIter = (g_IsEmuMode ? 32 : 1024);\n\n    /* 4 PM4 queues will be running at same time.*/\n    const int numPM4Queue = 4;\n    HsaEvent *event[numPM4Queue];\n    PM4Queue queue[numPM4Queue];\n    HsaMemoryBuffer *destBuf[numPM4Queue];\n    unsigned int *buf[numPM4Queue];\n\n    for (int i = 0; i < numPM4Queue; i++) {\n        destBuf[i] = new HsaMemoryBuffer(bufSize, gpuNode, true, false); // System memory\n        buf[i] = destBuf[i]->As<unsigned int *>();\n    }\n\n    /* A simple loop here to give more pressure.*/\n    for (int test_count = 0; test_count < numIter; test_count++) {\n        for (int i = 0; i < numPM4Queue; i++) {\n            ASSERT_SUCCESS_GPU(queue[i].Create(gpuNode, queueSize), gpuNode);\n            ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event[i]), gpuNode);\n\n            /* Let CP have some workload first.*/\n            for(int index = 0; index < packetCount; index++)\n                queue[i].PlacePacket(PM4WriteDataPacket(buf[i] + index, 0xdeadbeaf));\n\n            /* releaseMemory packet makes sure all previous written data is visible.*/\n            queue[i].PlacePacket(PM4ReleaseMemoryPacket(m_FamilyId, 0,\n                        reinterpret_cast<HSAuint64>(event[i]->EventData.HWData2),\n                        event[i]->EventId,\n                        true));\n        }\n\n        for (int i = 0; i < numPM4Queue; i++)\n            queue[i].SubmitPacket();\n\n        for (int i = 0; i < numPM4Queue; i++) {\n            EXPECT_SUCCESS_GPU(hsaKmtWaitOnEvent(event[i], g_TestTimeOut), gpuNode);\n            EXPECT_EQ_GPU(buf[i][0], 0xdeadbeaf, gpuNode);\n            EXPECT_EQ_GPU(buf[i][packetCount - 1], 0xdeadbeaf, gpuNode);\n            memset(buf[i], 0, bufSize);\n        }\n\n        for (int i = 0; i < numPM4Queue; i++) {\n            EXPECT_SUCCESS_GPU(queue[i].Destroy(), gpuNode);\n            EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(event[i]), gpuNode);\n        }\n    }\n\n    for (int i = 0; i < numPM4Queue; i++)\n        delete destBuf[i];\n}\n\nTEST_F(KFDQMTest, PM4EventInterrupt) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(PM4EventInterrupt));\n\n    TEST_END\n}\n\n#include \"KFDTestUtilQueue.hpp\"\nstatic void SdmaEventInterrupt(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n\n    const HSAuint64 bufSize = 4 << 20;\n    HsaMemoryBuffer srcBuf(bufSize, 0); // System memory.\n\n    HSAuint64 *src = srcBuf.As<HSAuint64*>();\n    TimeStamp *tsbuf = srcBuf.As<TimeStamp*>();\n    tsbuf = reinterpret_cast<TimeStamp *>ALIGN_UP(tsbuf, sizeof(TimeStamp));\n\n    /* Have 3 queues created for test.*/\n    const int numSDMAQueue = 3;\n    HsaEvent *event[numSDMAQueue];\n    SDMAQueue queue[numSDMAQueue];\n    HsaMemoryBuffer *destBuf[numSDMAQueue];\n    HSAuint64 *dst[numSDMAQueue];\n\n    for (int i = 0; i < numSDMAQueue; i++) {\n        destBuf[i] = new HsaMemoryBuffer(bufSize, gpuNode, true, false); // System memory\n        dst[i] = destBuf[i]->As<HSAuint64*>();\n    }\n\n    /* Test 1 queue, 2 queues, 3 queues running at same time one by one.*/\n    for (int testSDMAQueue = 1; testSDMAQueue <= numSDMAQueue; testSDMAQueue++)\n        /* A simple loop here to give more pressure.*/\n        for (int test_count = 0; test_count < 2048; test_count++) {\n            for (int i = 0; i < testSDMAQueue; i++) {\n                TimeStamp *ts = tsbuf + i * 32;\n                ASSERT_SUCCESS_GPU(queue[i].Create(gpuNode), gpuNode);\n                /* FIXME\n                 * We create event every time along with queue.\n                 * However that will significantly enhance the failure of sdma event timeout.\n                 */\n                ASSERT_SUCCESS_GPU(CreateQueueTypeEvent(false, false, gpuNode, &event[i]), gpuNode);\n\n                /* Get the timestamp directly. The first member of HsaClockCounters and TimeStamp is GPU clock counter.*/\n                hsaKmtGetClockCounters(gpuNode, reinterpret_cast<HsaClockCounters*>(&ts[0]));\n                /* Let sDMA have some workload first.*/\n                queue[i].PlacePacket(SDMATimePacket(&ts[1]));\n                queue[i].PlacePacket(\n                        SDMACopyDataPacket(queue[i].GetFamilyId(), dst[i], src, bufSize));\n                queue[i].PlacePacket(SDMATimePacket(&ts[2]));\n                queue[i].PlacePacket(\n                        SDMAFencePacket(queue[i].GetFamilyId(),\n                                reinterpret_cast<void*>(event[i]->EventData.HWData2), event[i]->EventId));\n                queue[i].PlacePacket(SDMATimePacket(&ts[3]));\n                queue[i].PlacePacket(SDMATrapPacket(event[i]->EventId));\n                queue[i].PlacePacket(SDMATimePacket(&ts[4]));\n\n                /* Will verify the value of srcBuf and destBuf later. Give it a different value each time.*/\n                src[0] = ts[0].timestamp;\n            }\n\n            for (int i = 0; i < testSDMAQueue; i++)\n                queue[i].SubmitPacket();\n\n            for (int i = 0; i < testSDMAQueue; i++) {\n                TimeStamp *ts = tsbuf + i * 32;\n                HSAKMT_STATUS ret = hsaKmtWaitOnEvent(event[i], g_TestTimeOut);\n\n                if (dst[i][0] != src[0])\n                    WARN() << \"SDMACopyData FAIL! \" << std::dec\n                        << dst[i][0] << \" VS \" << src[0] << std::endl;\n\n                if (ret == HSAKMT_STATUS_SUCCESS) {\n                    for (int i = 1; i <= 4; i++)\n                        /* Is queue latency too big? The workload is really small.*/\n                        if (CounterToNanoSec(ts[i].timestamp - ts[i - 1].timestamp) > 1000000000)\n                            WARN() << \"SDMA queue latency is bigger than 1s!\" << std::endl;\n                } else {\n                    WARN() << \"Event On Queue \" << testSDMAQueue << \":\" << i\n                        << \" Timeout, try to resubmit packets!\" << std::endl;\n\n                    queue[i].SubmitPacket();\n\n                    if (hsaKmtWaitOnEvent(event[i], g_TestTimeOut) == HSAKMT_STATUS_SUCCESS)\n                        WARN() << \"The timeout event is signaled!\" << std::endl;\n                    else\n                        WARN() << \"The timeout event is lost after resubmit!\" << std::endl;\n\n                    LOG() << \"Time Consumption (ns)\" << std::endl;\n                    for (int i = 1; i <= 4; i++)\n                        LOG() << std::dec << i << \": \"\n                            << CounterToNanoSec(ts[i].timestamp - ts[i - 1].timestamp) << std::endl;\n                }\n\n                EXPECT_SUCCESS_GPU(ret, gpuNode);\n            }\n\n            for (int i = 0; i < testSDMAQueue; i++) {\n                EXPECT_SUCCESS_GPU(queue[i].Destroy(), gpuNode);\n                EXPECT_SUCCESS_GPU(hsaKmtDestroyEvent(event[i]), gpuNode);\n            }\n        }\n\n    for (int i = 0; i < numSDMAQueue; i++)\n        delete destBuf[i];\n\n}\n\nTEST_F(KFDQMTest, SdmaEventInterrupt) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n     ASSERT_SUCCESS(KFDTest_Launch(SdmaEventInterrupt));\n\n    TEST_END\n}\n\n#define DOORBELL_WRITE_USE_SDMA\nstatic void GPUDoorbellWrite(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDQMTest* pKFDQMTest = (KFDQMTest*)pTestParamters->pTestObject;\n    HSAuint32 m_FamilyId = pKFDQMTest->GetFamilyIdFromNodeId(gpuNode);\n\n    HsaMemoryBuffer destBuf(PAGE_SIZE, 0, true);\n    PM4Queue pm4Queue;\n#ifdef DOORBELL_WRITE_USE_SDMA\n    SDMAQueue otherQueue;\n#else\n    PM4Queue otherQueue;\n#endif\n\n    ASSERT_SUCCESS_GPU(pm4Queue.Create(gpuNode), gpuNode);\n    ASSERT_SUCCESS_GPU(otherQueue.Create(gpuNode), gpuNode);\n\n    /* Place PM4 packet in the queue, but don't submit it */\n    pm4Queue.PlacePacket(PM4WriteDataPacket(destBuf.As<unsigned int*>(), 0x12345678, 0x87654321));\n\n    HsaQueueResource *qRes = pm4Queue.GetResource();\n\n    if (m_FamilyId < FAMILY_AI) {\n        unsigned int pendingWptr = pm4Queue.GetPendingWptr();\n\n#ifdef DOORBELL_WRITE_USE_SDMA\n        /* Write the wptr and doorbell update using the GPU's SDMA\n         * engine. This should submit the PM4 packet on the first\n         * queue.\n         */\n        otherQueue.PlacePacket(SDMAWriteDataPacket(otherQueue.GetFamilyId(), qRes->Queue_write_ptr,\n                                                   pendingWptr));\n        otherQueue.PlacePacket(SDMAWriteDataPacket(otherQueue.GetFamilyId(), qRes->Queue_DoorBell,\n                                                   pendingWptr));\n#else\n        /* Write the wptr and doorbell update using WRITE_DATA packets\n         * on a second PM4 queue. This should submit the PM4 packet on\n         * the first queue.\n         */\n        otherQueue.PlacePacket(\n            PM4ReleaseMemoryPacket(m_FamilyId, true, (HSAuint64)qRes->Queue_write_ptr,\n                                   pendingWptr, false));\n        otherQueue.PlacePacket(\n            PM4ReleaseMemoryPacket(m_FamilyId, true, (HSAuint64)qRes->Queue_DoorBell,\n                                   pendingWptr, false));\n#endif\n\n        otherQueue.SubmitPacket();\n    } else {\n        HSAuint64 pendingWptr64 = pm4Queue.GetPendingWptr64();\n\n#ifdef DOORBELL_WRITE_USE_SDMA\n        /* Write the wptr and doorbell update using the GPU's SDMA\n         * engine. This should submit the PM4 packet on the first\n         * queue.\n         */\n        otherQueue.PlacePacket(SDMAWriteDataPacket(otherQueue.GetFamilyId(), qRes->Queue_write_ptr,\n                                                   2, &pendingWptr64));\n        otherQueue.PlacePacket(SDMAWriteDataPacket(otherQueue.GetFamilyId(), qRes->Queue_DoorBell,\n                                                   2, &pendingWptr64));\n#else\n        /* Write the 64-bit wptr and doorbell update using RELEASE_MEM\n         * packets without IRQs on a second PM4 queue. RELEASE_MEM\n         * should perform one atomic 64-bit access. This should submit\n         * the PM4 packet on the first queue.\n         */\n        otherQueue.PlacePacket(\n            PM4ReleaseMemoryPacket(m_FamilyId, true, (HSAuint64)qRes->Queue_write_ptr,\n                                   pendingWptr64, true));\n        otherQueue.PlacePacket(\n            PM4ReleaseMemoryPacket(m_FamilyId, true, (HSAuint64)qRes->Queue_DoorBell,\n                                   pendingWptr64, true));\n#endif\n\n        otherQueue.SubmitPacket();\n    }\n\n    /* Check that the PM4 packet has been executed */\n    EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int *>(), 0x12345678), gpuNode);\n    EXPECT_TRUE_GPU(WaitOnValue(destBuf.As<unsigned int *>()+1, 0x87654321), gpuNode);\n\n    EXPECT_SUCCESS_GPU(pm4Queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(otherQueue.Destroy(), gpuNode);\n\n}\n\nTEST_F(KFDQMTest, GPUDoorbellWrite) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(GPUDoorbellWrite));\n\n    TEST_END\n}\n\nTEST_F(KFDQMTest, UserQueueBufValidation) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    HsaQueueResource QueueResources;\n    HsaMemoryBuffer *QueueBuf;\n    HSAKMT_STATUS status;\n\n    memset(&QueueResources, 0, sizeof(QueueResources));\n\n    // System memory mapping on GPU\n    QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);\n\n    EXPECT_SUCCESS(hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_COMPUTE,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               QueueBuf->As<unsigned int*>(),\n                               PAGE_SIZE,\n                               NULL,\n                               &QueueResources));\n    EXPECT_SUCCESS(hsaKmtDestroyQueue(QueueResources.QueueId));\n\n    // CP Queue creation should fail using wrong ring buffer size\n    EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_COMPUTE,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               QueueBuf->As<unsigned int*>(),\n                               PAGE_SIZE * 2,\n                               NULL,\n                               &QueueResources));\n\n    // SDMA queue create should fail using wrong ring buffer size\n    EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_SDMA,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               QueueBuf->As<unsigned int*>(),\n                               PAGE_SIZE * 2,\n                               NULL,\n                               &QueueResources));\n\n    // CP queue create should fail using NULL ring buffer\n    EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_COMPUTE,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               NULL,\n                               PAGE_SIZE,\n                               NULL,\n                               &QueueResources));\n\n    // SDMA queue create should fail using NULL ring buffer\n    EXPECT_SUCCESS(!hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_SDMA,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               NULL,\n                               PAGE_SIZE,\n                               NULL,\n                               &QueueResources));\n\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>()));\n    EXPECT_SUCCESS(hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE));\n\n    //\n    // This following negative test will evict user queues, must execute in child process,\n    // because parent process is allowed to create queue to run the remaining tests.\n    //\n    pid_t childPid = fork();\n\n    if (childPid == 0) { /* Child process */\n        void *cwsr_addr;\n        int exit_code = 1;\n\n        TearDown();\n        SetUp();\n\n        // System memory mapping on GPU\n        QueueBuf = new HsaMemoryBuffer(PAGE_SIZE, defaultGPUNode);\n        memset(&QueueResources, 0, sizeof(QueueResources));\n\n        status = hsaKmtCreateQueue(defaultGPUNode,\n                               HSA_QUEUE_COMPUTE,\n                               100,\n                               HSA_QUEUE_PRIORITY_NORMAL,\n                               QueueBuf->As<unsigned int*>(),\n                               PAGE_SIZE,\n                               NULL,\n                               &QueueResources);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"create queue failed.\" << std::endl;\n            goto free_exit;\n        }\n\n        // Update queue percentage 0 to set queue inactive in order to get queue info CWSR area\n        status = hsaKmtUpdateQueue(QueueResources.QueueId, 0, HSA_QUEUE_PRIORITY_NORMAL,\n                                     QueueBuf->As<unsigned int*>(), PAGE_SIZE, NULL);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"update queue failed.\" << std::endl;\n            goto err_exit;\n        }\n\n        HsaQueueInfo QueueInfo;\n        status = hsaKmtGetQueueInfo(QueueResources.QueueId, &QueueInfo);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"get queue info failed.\" << std::endl;\n            goto err_exit;\n        }\n\n        // unmap CWSR buffer will evict queue before queue is destroyed\n        cwsr_addr = QueueInfo.UserContextSaveArea;\n        munmap(cwsr_addr, PAGE_SIZE);\n\n        // unmap and free queue ring buffer should fail before the queue is destroyed\n        status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);\n        if (status == HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"free queue buf should fail.\" << std::endl;\n            goto err_exit;\n        }\n\n        status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());\n        if (status == HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"unmap queue buf should fail.\" << std::endl;\n            goto err_exit;\n        }\n\n        exit_code = 0;\n\nerr_exit:\n        status = hsaKmtDestroyQueue(QueueResources.QueueId);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"destroy queue failed.\" << std::endl;\n            exit_code = 1;\n        }\nfree_exit:\n        status = hsaKmtUnmapMemoryToGPU(QueueBuf->As<unsigned int*>());\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"unmap queue buf failed.\" << std::endl;\n            exit_code = 1;\n        }\n\n        status = hsaKmtFreeMemory(QueueBuf->As<unsigned int*>(), PAGE_SIZE);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"free queue buf failed.\" << std::endl;\n            exit_code = 1;\n        }\n\n        exit(exit_code);\n    } else {\n        int childStatus;\n\n        waitpid(childPid, &childStatus, 0);\n        EXPECT_EQ(true, WIFEXITED(childStatus));\n        EXPECT_EQ(0, WEXITSTATUS(childStatus));\n    }\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDQMTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_QCM_TEST__H__\n#define __KFD_QCM_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"PM4Queue.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n#include \"Dispatch.hpp\"\n\n/*\n * Used by ExtendedCuMasking test case to pass GPU configuration information to helper functions.\n */\ntypedef struct {\n    uint32_t numDwords;\n    uint32_t numBits;\n    uint32_t numSEs;\n    uint32_t numSAperSE;\n    uint32_t numWGPperSA;\n    uint32_t *pInactiveMask;\n} mask_config_t;\n\n/*\n * Used by ExtendedCuMasking test case.\n *\n * Struct is hardware-dependent and fields are layed out same way as hardware register.\n *\n */\ntypedef union {\n    uint32_t data;\n    // Fields needed from HW_ID1 (format same for GFX11 and GFX12)\n    struct {\n        unsigned     :10;\n        unsigned wgp : 4;\n        unsigned     : 2;\n        unsigned  sa : 1;\n        unsigned     : 1;\n        unsigned  se : 3;\n        unsigned     :11;\n    };\n} out_data_t;\n\n\nclass KFDQMTest : public KFDBaseComponentTest {\n public:\n    KFDQMTest() {}\n\n    ~KFDQMTest() {}\n\n    friend void BasicCuMaskingLinear(KFDTEST_PARAMETERS* pTestParamters);\n    friend void BasicCuMaskingEven(KFDTEST_PARAMETERS* pTestParamters);\n    friend void EmptyDispatch(KFDTEST_PARAMETERS* pTestParamters) ;\n    friend void SimpleWriteDispatch(KFDTEST_PARAMETERS* pTestParamters);\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n    void SyncDispatch(const HsaMemoryBuffer& isaBuffer, void* pSrcBuf, void* pDstBuf, int node = -1);\n    HSAint64 TimeConsumedwithCUMask(int node, uint32_t *mask, uint32_t mask_count);\n    HSAint64 GetAverageTimeConsumedwithCUMask(int node, uint32_t *mask, uint32_t mask_count, int iterations);\n    friend void testQueuePriority(KFDTEST_PARAMETERS* pTestParamters, bool isSamePipe);\n\n protected:  // Members\n    /* Acceptable performance for CU Masking should be within 5% of linearly-predicted performance */\n    const double CuVariance = 0.15;\n    const double CuNegVariance = 1.0 - CuVariance;\n    const double CuPosVariance = 1.0 + CuVariance;\n};\n\n#endif  // __KFD_QCM_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDRASTest.cpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <math.h>\n#include <limits.h>\n\n#include \"hsakmt/linux/kfd_ioctl.h\"\n#include \"KFDRASTest.hpp\"\n#include \"PM4Queue.hpp\"\n\n#define AMDGPU_DEBUGFS_NODES \"/sys/kernel/debug/dri/\"\n#define RAS_CONTROL \"ras/ras_ctrl\"\n#define DRM_RENDER_NUMBER 64\n\nvoid KFDRASTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    char path[256], name[128], tmp[128];\n    int renderNode, minor, i;\n    FILE *pDriMinor, *pDriPrimary;\n    uint32_t rasFeatures = 0;\n    HsaEventDescriptor eventDesc;\n\n    m_pRasEvent = NULL;\n    m_setupStatus = false;\n\n    m_defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n\n    renderNode = KFDBaseComponentTest::FindDRMRenderNode(m_defaultGPUNode);\n    if (renderNode < 0) {\n        LOG() << \"Skipping test: Could not find render node for default GPU.\" << std::endl;\n        throw;\n    }\n\n    amdgpu_query_info(m_RenderNodes[renderNode].device_handle,\n                AMDGPU_INFO_RAS_ENABLED_FEATURES,\n                sizeof(uint32_t), &rasFeatures);\n    if (!(rasFeatures &\n            (AMDGPU_INFO_RAS_ENABLED_SDMA |\n             AMDGPU_INFO_RAS_ENABLED_UMC |\n             AMDGPU_INFO_RAS_ENABLED_GFX))) {\n        LOG() << \"Skipping test: GPU doesn't support RAS features!\" << std::endl;\n        throw;\n    }\n\n    minor = renderNode + 128;\n\n    snprintf(path, sizeof(path), \"%s%d/%s\", AMDGPU_DEBUGFS_NODES, minor, \"name\");\n    pDriMinor = fopen(path, \"r\");\n    if (!pDriMinor) {\n        LOG() << \"Skipping test: DRM render debugfs node requires root access!\" << std::endl;\n        throw;\n    }\n\n    memset(name, 0, sizeof(name));\n    fread(name, sizeof(name), 1, pDriMinor);\n\n    fclose(pDriMinor);\n\n    for (i = 0; i < DRM_RENDER_NUMBER; i++) {\n        snprintf(path, sizeof(path), \"%s%d/%s\", AMDGPU_DEBUGFS_NODES, i, \"name\");\n        pDriPrimary = fopen(path, \"r\");\n        if (!pDriPrimary)\n            continue;\n        memset(tmp, 0, sizeof(tmp));\n        fread(tmp, sizeof(tmp), 1, pDriPrimary);\n        if (!strcmp(name, tmp)) {\n            fclose(pDriPrimary);\n            break;\n        }\n        fclose(pDriPrimary);\n    }\n\n    if (i == DRM_RENDER_NUMBER) {\n        LOG() << \"Skipping test: Could not find the debugfs node!\" << std::endl;\n        throw;\n    }\n\n    snprintf(path, sizeof(path), \"%s%d/%s\", AMDGPU_DEBUGFS_NODES, i, RAS_CONTROL);\n    m_pFile = fopen(path, \"w\");\n    if (!m_pFile) {\n        LOG() << \"Skipping test: RAS error injection requires root access!\" << std::endl;\n        throw;\n    }\n\n    eventDesc.EventType = HSA_EVENTTYPE_MEMORY;\n    eventDesc.NodeId = m_defaultGPUNode;\n    eventDesc.SyncVar.SyncVar.UserData = NULL;\n    eventDesc.SyncVar.SyncVarSize = 0;\n\n    ASSERT_SUCCESS(hsaKmtCreateEvent(&eventDesc, true, false, &m_pRasEvent));\n\n    m_setupStatus = true;\n\n    ROUTINE_END\n}\n\nvoid KFDRASTest::TearDown() {\n    ROUTINE_START\n\n    if (m_pRasEvent != NULL) {\n        EXPECT_SUCCESS(hsaKmtDestroyEvent(m_pRasEvent));\n    }\n\n    fclose(m_pFile);\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nTEST_F(KFDRASTest, DISABLED_BasicTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!m_setupStatus) {\n        return;\n    }\n\n    // write an uncorrectable error injection at address 0 as value 0\n    fwrite(\"inject umc ue 0 0\", sizeof(char), 17, m_pFile);\n    fflush(m_pFile);\n\n    EXPECT_SUCCESS(hsaKmtWaitOnEvent(m_pRasEvent, g_TestTimeOut));\n\n    EXPECT_EQ(1, m_pRasEvent->EventData.EventData.MemoryAccessFault.Failure.ErrorType);\n\n    TEST_END;\n}\n\nTEST_F(KFDRASTest, DISABLED_MixEventsTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!m_setupStatus) {\n        return;\n    }\n\n    PM4Queue queue;\n    HsaEvent* pHsaEvent;\n\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, m_defaultGPUNode, &pHsaEvent));\n    ASSERT_NE(0, pHsaEvent->EventData.HWData2);\n\n    ASSERT_SUCCESS(queue.Create(m_defaultGPUNode));\n\n    queue.PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, false,\n            pHsaEvent->EventData.HWData2, pHsaEvent->EventId));\n\n    queue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS(hsaKmtWaitOnEvent(pHsaEvent, g_TestTimeOut));\n\n    fwrite(\"inject umc ue 0 0\", sizeof(char), 17, m_pFile);\n    fflush(m_pFile);\n\n    EXPECT_SUCCESS(hsaKmtWaitOnEvent(m_pRasEvent, g_TestTimeOut));\n\n    EXPECT_EQ(1, m_pRasEvent->EventData.EventData.MemoryAccessFault.Failure.ErrorType);\n\n    EXPECT_SUCCESS(queue.Destroy());\n    EXPECT_SUCCESS(hsaKmtDestroyEvent(pHsaEvent));\n\n    TEST_END;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDRASTest.hpp",
    "content": "/*\n * Copyright (C) 2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDBaseComponentTest.hpp\"\n\n#ifndef __KFD_RAS_TEST__H__\n#define __KFD_RAS_TEST__H__\n\n// To be removed when amdgpu_drm.h updated with those definitions\n#ifndef AMDGPU_INFO_RAS_ENABLED_FEATURES\n#define AMDGPU_INFO_RAS_ENABLED_FEATURES    0x20\n\n#define AMDGPU_INFO_RAS_ENABLED_UMC         (1 << 0)\n#define AMDGPU_INFO_RAS_ENABLED_SDMA        (1 << 1)\n#define AMDGPU_INFO_RAS_ENABLED_GFX         (1 << 2)\n#endif\n\nclass KFDRASTest :  public KFDBaseComponentTest {\n public:\n    KFDRASTest(void) {}\n    ~KFDRASTest(void) {}\n\n    // @brief Executed before every test in KFDRASTest.\n    virtual void SetUp();\n    // @brief Executed after every test in KFDRASTest.\n    virtual void TearDown();\n\n protected:\n    static const unsigned int EVENT_TIMEOUT = 5000;  // 5 seconds\n    HsaEvent* m_pRasEvent;\n    HSAint32 m_defaultGPUNode;\n    FILE* m_pFile;\n    bool m_setupStatus;\n};\n\n#endif  // __KFD_RAS_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDSVMEvictTest.cpp",
    "content": "/*\n * Copyright (C) 2020 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDSVMEvictTest.hpp\"\n#include <sys/mman.h>\n#include <vector>\n#include <string>\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n\n#define N_PROCESSES             (2)     /* number of processes running in parallel, at least 2 */\n#define ALLOCATE_BUF_SIZE_MB    (64)\n#define ALLOCATE_RETRY_TIMES    (3)\n#define MAX_WAVEFRONTS          (512)\n\nvoid KFDSVMEvictTest::SetUp() {\n    ROUTINE_START\n\n    KFDLocalMemoryTest::SetUp();\n\n    SVMSetXNACKMode(GetParam());\n\n    ROUTINE_END\n}\n\nvoid KFDSVMEvictTest::TearDown() {\n    ROUTINE_START\n\n    SVMRestoreXNACKMode();\n\n    KFDLocalMemoryTest::TearDown();\n\n    ROUTINE_END\n}\n\nHSAint32 KFDSVMEvictTest::GetBufferCounter(HSAuint64 vramSize, HSAuint64 vramBufSize) {\n    HSAuint64 vramBufSizeInPages = vramBufSize >> PAGE_SHIFT;\n    HSAuint64 sysMemSize = GetSysMemSize();\n    HSAuint64 size, sizeInPages;\n    HSAuint32 count;\n\n    LOG() << \"Found System RAM of \" << std::dec << (sysMemSize >> 20) << \"MB\" << std::endl;\n\n    /* use one third of total system memory for eviction buffer to test\n     * limit max allocate size to double of vramSize\n     * count is zero if not enough memory for XNACK off case\n     */\n    size = MIN(sysMemSize / 3, vramSize / 2);\n    size += vramSize;\n\n    /* Check if there is enough system memory to pass test for XNACK off\n     * KFD system memory limit is 15/16.\n     */\n    HSAint32 xnack_enable = 0;\n    EXPECT_SUCCESS(hsaKmtGetXNACKMode(&xnack_enable));\n    if (!xnack_enable && size > (sysMemSize - (sysMemSize >> 4)))\n        return 0;\n\n    sizeInPages = size >> PAGE_SHIFT;\n    count = sizeInPages / (vramBufSizeInPages * N_PROCESSES);\n\n    return count;\n}\n\nHSAint64 KFDSVMEvictTest::GetBufferSize(HSAuint64 vramSize, HSAuint32 count,\n                                        HSAint32 xnack_enable) {\n    HSAuint64 sysMemSize = GetSysMemSize();\n    HSAuint64 size, sizeInPages;\n    HSAuint64 vramBufSizeInPages;\n\n    LOG() << \"Found System RAM of \" << std::dec << (sysMemSize >> 20) << \"MB\" << std::endl;\n\n    /* use up to one third of total system memory for eviction buffer to test\n     * limit max eviction size to 1/2 of vramSize.\n     */\n    size = MIN(sysMemSize / 3, vramSize / 2);\n    size += vramSize;\n\n    /* Check if there is enough system memory to pass test for XNACK off\n     * KFD system memory limit is 15/16.\n     */\n    if (!xnack_enable && size > (sysMemSize - (sysMemSize >> 4)))\n        return 0;\n\n    sizeInPages = size >> PAGE_SHIFT;\n    vramBufSizeInPages = sizeInPages / (count * N_PROCESSES);\n\n    return vramBufSizeInPages << PAGE_SHIFT;\n}\n\nvoid KFDSVMEvictTest::AllocBuffers(HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize,\n        std::vector<void *> &pBuffers, HSAuint32 Granularity) {\n    HSAuint64   totalMB;\n\n    totalMB = N_PROCESSES * count * (vramBufSize >> 20);\n    if (m_IsParent) {\n        LOG() << \"Testing \" << N_PROCESSES << \"*\" << count << \"*\" << (vramBufSize>>20) << \"(=\"<< totalMB << \")MB\" << std::endl;\n    }\n    HSAKMT_STATUS ret;\n    HSAuint32 retry = 0;\n\n    for (HSAuint32 i = 0; i < count; i++) {\n        m_pBuf = mmap(0, vramBufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n        ASSERT_NE(MAP_FAILED, m_pBuf);\n\n        m_Flags = (HSA_SVM_FLAGS)0;\nretry:\n        ret = RegisterSVMRange(defaultGPUNode, m_pBuf, vramBufSize, defaultGPUNode, m_Flags);\n        if (ret == HSAKMT_STATUS_SUCCESS) {\n            pBuffers.push_back(m_pBuf);\n            if (Granularity)\n                EXPECT_SUCCESS(SVMRangSetGranularity(m_pBuf, vramBufSize, Granularity));\n            retry = 0;\n        } else {\n            if (retry++ > ALLOCATE_RETRY_TIMES) {\n                munmap(m_pBuf, vramBufSize);\n                break;\n            }\n            printf(\"retry %d allocate vram\\n\", retry);\n\n            /* wait for 1 second to try allocate again */\n            sleep(1);\n            goto retry;\n        }\n    }\n}\n\nvoid KFDSVMEvictTest::FreeBuffers(std::vector<void *> &pBuffers, HSAuint64 vramBufSize) {\n    for (HSAuint32 i = 0; i < pBuffers.size(); i++) {\n        m_pBuf = pBuffers[i];\n        if (m_pBuf != NULL)\n            munmap(m_pBuf, vramBufSize);\n    }\n}\n\nvoid KFDSVMEvictTest::ForkChildProcesses(int nprocesses) {\n    int i;\n\n    for (i = 0; i < nprocesses - 1; ++i) {\n        pid_t pid = fork();\n        ASSERT_GE(pid, 0);\n\n        if (pid == 0) {\n            /* Child process */\n            /* Cleanup file descriptors copied from parent process\n             * then call SetUp->hsaKmtOpenKFD to create new process\n             */\n            m_psName = \"Test process \" + std::to_string(i) + \" \";\n            TearDown();\n            SetUp();\n            m_ChildPids.clear();\n            m_IsParent = false;\n            return;\n        }\n\n        /* Parent process */\n        m_ChildPids.push_back(pid);\n    }\n\n    m_psName = \"Test process \" + std::to_string(i) + \" \";\n}\n\nvoid KFDSVMEvictTest::WaitChildProcesses() {\n    if (m_IsParent) {\n        /* only run by parent process */\n        int childStatus;\n        int childExitOkNum = 0;\n        int size = m_ChildPids.size();\n\n        for (HSAuint32 i = 0; i < size; i++) {\n            pid_t pid = m_ChildPids.front();\n\n            waitpid(pid, &childStatus, 0);\n            if (WIFEXITED(childStatus) == 1 && WEXITSTATUS(childStatus) == 0)\n                childExitOkNum++;\n\n            m_ChildPids.erase(m_ChildPids.begin());\n        }\n\n        ASSERT_EQ(childExitOkNum, size);\n    }\n\n    /* child process or parent process finished successfullly */\n    m_ChildStatus = HSAKMT_STATUS_SUCCESS;\n}\n\n/* Evict and restore procedure basic test\n *\n * Use N_PROCESSES processes to allocate vram buf size larger than total vram size\n *\n * ALLOCATE_BUF_SIZE_MB buf allocation size\n *\n * number of buf is equal to (vramSizeMB / (vramBufSizeMB * N_PROCESSES) ) + 8\n * Total vram all processes allocated: 8GB for 4GB Fiji, and 20GB for 16GB Vega10\n *\n * many times of eviction and restore will happen:\n * ttm will evict buffers of another process if not enough free vram\n * process restore will evict buffers of another process\n *\n * Sometimes the allocate may fail (maybe that is normal)\n * ALLOCATE_RETRY_TIMES max retry times to allocate\n *\n * This is basic test, no queue so vram are not used by GPU during test\n *\n * Todo:\n *    - Synchronization between the processes, so they know for sure when\n *        they are done allocating memory\n */\nTEST_P(KFDSVMEvictTest, BasicTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    HSAint32 xnack_enable = 0;\n    EXPECT_SUCCESS(hsaKmtGetXNACKMode(&xnack_enable));\n    if (!xnack_enable) {\n\t    LOG() << std::hex << \"Test is skipped with xnack off\" << std::endl;\n            return;\n    }\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n    HSAuint64 vramBufSize = ALLOCATE_BUF_SIZE_MB * 1024 * 1024;\n\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n\n    if (!vramSize) {\n        LOG() << \"No VRAM found, skipping the test\" << std::endl;\n        return;\n    } else {\n        LOG() << \"Found VRAM of \" << std::dec << (vramSize >> 20) << \"MB\" << std::endl;\n    }\n\n    HSAuint32 count = GetBufferCounter(vramSize, vramBufSize);\n    if (count == 0) {\n        LOG() << \"Not enough system memory, skipping the test\" << std::endl;\n        return;\n    }\n\n    /* Fork the child processes */\n    ForkChildProcesses(N_PROCESSES);\n\n    std::vector<void *> pBuffers;\n    AllocBuffers(defaultGPUNode, count, vramBufSize, pBuffers, 0);\n\n    /* wait for other processes to finish allocation, then free buffer */\n    sleep(ALLOCATE_RETRY_TIMES);\n\n    LOG() << m_psName << \"free buffer\" << std::endl;\n    FreeBuffers(pBuffers, vramBufSize);\n\n    WaitChildProcesses();\n\n    TEST_END\n}\n\n/* Evict and restore queue test\n *\n * N_PROCESSES processes read all local buffers in parallel while buffers are evicted and restored\n * If GPU vm page fault happens, then test shader will stop and failed to write specific value\n * at dest buffer. Test will report failed.\n *\n * Steps:\n *    - fork N_PROCESSES processes, each process does the same below\n *    - allocate local buffers, each buffer size is 64MB\n *    - allocate zero initialized host access address buffer and result buffer\n *        address buffer to pass address of local buffers to shader\n *        result buffer to store shader output result\n *    - submit queue to run ReadMemory shader\n *    - shader start m_DimX wavefronts, each wavefront keep reading one local buffer\n *    - notify shader to quit\n *    - check result buffer with specific value to confirm all wavefronts quit normally\n */\nTEST_P(KFDSVMEvictTest, QueueTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    if (!SVMAPISupported())\n        return;\n\n    HSAint32 xnack_enable = 0;\n    EXPECT_SUCCESS(hsaKmtGetXNACKMode(&xnack_enable));\n    if (!xnack_enable) {\n\tLOG() << std::hex << \"Test is skipped with xnack off\" << std::endl;\n        return;\n    }\n\n    HSAuint32 defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n    unsigned int count = MAX_WAVEFRONTS;\n\n    const HsaNodeProperties *pNodeProperties = m_NodeInfo.HsaDefaultGPUNodeProperties();\n\n    /* Skip test for chip it doesn't have CWSR, which the test depends on */\n    if (m_FamilyId < FAMILY_VI || isTonga(pNodeProperties) || m_FamilyId >= FAMILY_NV) {\n        LOG() << std::hex << \"Test is skipped for family ID 0x\" << m_FamilyId << std::endl;\n        return;\n    }\n\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    uint32_t cu_num = pNodeProperties->NumFComputeCores / pNodeProperties->NumSIMDPerCU;\n    uint32_t wave_num = MIN(cu_num * 40,\n                        (pNodeProperties->NumShaderBanks / pNodeProperties->NumArrays) * 512);\n    if (wave_num < count * N_PROCESSES) {\n        LOG() << std::hex << \"Test is skipped, wave_num \" << wave_num << \" not enough\" << std::endl;\n        return;\n    }\n\n    HSAuint32 i;\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n\n    if (!vramSize) {\n        LOG() << \"No VRAM found, skipping the test\" << std::endl;\n        return;\n    } else {\n        LOG() << \"Found VRAM of \" << std::dec << (vramSize >> 20) << \"MB.\" << std::endl;\n    }\n\n    HSAuint64 vramBufSize = GetBufferSize(vramSize, count, xnack_enable);\n    if (vramBufSize == 0) {\n        LOG() << \"Not enough system memory, skipping the test\" << std::endl;\n        return;\n    }\n    /* assert all buffer address can be stored within one page\n     * because only one page host memory srcBuf is allocated\n     */\n    ASSERT_LE(count, PAGE_SIZE/sizeof(unsigned int *));\n\n    /* Fork the child processes */\n    ForkChildProcesses(N_PROCESSES);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, defaultGPUNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer addrBuffer(PAGE_SIZE, defaultGPUNode);\n    HsaMemoryBuffer resultBuffer(PAGE_SIZE, defaultGPUNode);\n\n    std::vector<void *> pBuffers;\n    HSAuint32 granularity = 0;\n    /* xnack is on, shadder code will trigger gpu page fault that bring data\n     * to vram. use granularity to move all data from system buffer to vram\n     * to reduce system ram pressure in order to avoid system ram oom in system\n     * that has less system ram.\n     */\n    if (xnack_enable)\n       granularity = 0xff;\n    AllocBuffers(defaultGPUNode, count, vramBufSize, pBuffers, granularity);\n\n    unsigned int wavefront_num = pBuffers.size();\n    LOG() << m_psName << \"wavefront number \" << wavefront_num << std::endl;\n\n    void **localBufAddr = addrBuffer.As<void **>();\n    unsigned int *result = resultBuffer.As<uint32_t *>();\n\n    for (i = 0; i < wavefront_num; i++)\n        *(localBufAddr + i) = pBuffers[i];\n\n    for (i = 0; i < wavefront_num; i++)\n        *(result + i) = vramBufSize;\n\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(ReadMemoryIsa, isaBuffer.As<char*>()));\n\n    PM4Queue pm4Queue;\n    ASSERT_SUCCESS(pm4Queue.Create(defaultGPUNode));\n\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(localBufAddr, result);\n    dispatch0.SetDim(wavefront_num, 1, 1);\n    /* submit the packet and start shader */\n    dispatch0.Submit(pm4Queue);\n\n    /* doing evict/restore queue test for 5 seconds while queue is running */\n    sleep(5);\n\n    /* LOG() << m_psName << \"notify shader to quit\" << std::endl; */\n    /* fill address buffer so shader quits */\n    addrBuffer.Fill(0x5678);\n\n    /* wait for shader to finish or timeout if shade has vm page fault */\n    dispatch0.SyncWithStatus(g_TestTimeOut * 5);\n\n    ASSERT_SUCCESS(pm4Queue.Destroy());\n    /* LOG() << m_psName << \"free buffer\" << std::endl; */\n    /* cleanup */\n    FreeBuffers(pBuffers, vramBufSize);\n\n    /* check if all wavefronts finish successfully */\n    for (i = 0; i < wavefront_num; i++)\n        ASSERT_EQ(0x5678, *(result + i));\n\n    WaitChildProcesses();\n\n    TEST_END\n}\n\nINSTANTIATE_TEST_CASE_P(, KFDSVMEvictTest,::testing::Values(0, 1));\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDSVMEvictTest.hpp",
    "content": "/*\n * Copyright (C) 2020 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_SVM_EVICT_TEST__H__\n#define __KFD_SVM_EVICT_TEST__H__\n\n#include <string>\n#include <vector>\n#include \"KFDLocalMemoryTest.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n\n// @class KFDEvictTest\n// Test eviction and restore procedure using two processes\nclass KFDSVMEvictTest : public KFDLocalMemoryTest,\n                        public ::testing::WithParamInterface<int> {\n public:\n    KFDSVMEvictTest(void): m_ChildStatus(HSAKMT_STATUS_ERROR), m_IsParent(true) {}\n\n    ~KFDSVMEvictTest(void) {\n        if (!m_IsParent) {\n            /* child process has to exit\n             * otherwise gtest will continue other tests\n             */\n            exit(m_ChildStatus);\n        }\n\n        try {\n            WaitChildProcesses();\n        } catch (...) {}\n    }\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n\n protected:\n    std::string CreateShader();\n    void AllocBuffers(HSAuint32 defaultGPUNode, HSAuint32 count, HSAuint64 vramBufSize,\n                    std::vector<void *> &pBuffers, HSAuint32 Granularity);\n    void FreeBuffers(std::vector<void *> &pBuffers, HSAuint64 vramBufSize);\n    void ForkChildProcesses(int nprocesses);\n    void WaitChildProcesses();\n    HSAint32 GetBufferCounter(HSAuint64 vramSize, HSAuint64 vramBufSize);\n    HSAint64 GetBufferSize(HSAuint64 vramSize, HSAuint32 count,\n                           HSAint32 xnack_enable);\n\n protected:  // members\n    std::string     m_psName;\n    std::vector<pid_t> m_ChildPids;\n    HSA_SVM_FLAGS   m_Flags;\n    void*           m_pBuf;\n    HSAKMT_STATUS   m_ChildStatus;\n    bool            m_IsParent;\n};\n\n#endif  // __KFD_SVM_EVICT_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDSVMRangeTest.cpp",
    "content": "/*\n * Copyright (C) 2020 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n#include \"KFDSVMRangeTest.hpp\"\n#include <poll.h>\n#include <sys/mman.h>\n#include <vector>\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n\nextern unsigned int g_TestGPUsNum;\n\nvoid KFDSVMRangeTest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    SVMSetXNACKMode(GetParam());\n\n    ROUTINE_END\n}\n\nvoid KFDSVMRangeTest::TearDown() {\n    ROUTINE_START\n\n    SVMRestoreXNACKMode();\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nstatic void BasicSystemMemTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    PM4Queue queue;\n    HSAuint64 AlternateVAGPU;\n    unsigned int BufferSize = PAGE_SIZE;\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaSVMRange srcSysBuffer(BufferSize, gpuNode);\n    HsaSVMRange destSysBuffer(BufferSize,gpuNode);\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDSVMRangeTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    srcSysBuffer.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    queue.SetSkipWaitConsump(0);\n\n    Dispatch dispatch(isaBuffer);\n\n    dispatch.SetArgs(srcSysBuffer.As<void*>(), destSysBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    EXPECT_EQ_GPU(destSysBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n}\n\nTEST_P(KFDSVMRangeTest, BasicSystemMemTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicSystemMemTest));\n\n    TEST_END\n}\n\nstatic void SetGetAttributesTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    int i;\n    unsigned int BufSize = PAGE_SIZE;\n    HsaSVMRange *sysBuffer = new HsaSVMRange(BufSize);\n    HSAuint32 nAttributes = 5;\n    HSA_SVM_ATTRIBUTE outputAttributes[nAttributes];\n    HSA_SVM_ATTRIBUTE inputAttributes[] = {\n                                                {HSA_SVM_ATTR_PREFETCH_LOC, (HSAuint32)gpuNode},\n                                                {HSA_SVM_ATTR_PREFERRED_LOC, (HSAuint32)gpuNode},\n                                                {HSA_SVM_ATTR_SET_FLAGS,\n                                                 HSA_SVM_FLAG_HOST_ACCESS | HSA_SVM_FLAG_GPU_EXEC | HSA_SVM_FLAG_COHERENT},\n                                                {HSA_SVM_ATTR_GRANULARITY, 0x3F},\n                                                {HSA_SVM_ATTR_ACCESS, (HSAuint32)gpuNode},\n                                          };\n\n    HSAuint32 expectedDefaultResults[] = {\n                                             INVALID_NODEID,\n                                             INVALID_NODEID,\n                                             HSA_SVM_FLAG_HOST_ACCESS | HSA_SVM_FLAG_COHERENT,\n                                             9,\n                                             0,\n                                         };\n    HSAint32 enable = -1;\n    EXPECT_SUCCESS_GPU(hsaKmtGetXNACKMode(&enable), gpuNode);\n    expectedDefaultResults[4] = (enable) ?\n                                 HSA_SVM_ATTR_ACCESS : HSA_SVM_ATTR_NO_ACCESS;\n    char *pBuf = sysBuffer->As<char *>();\n\n    LOG() << \"Get default atrributes\" << std::endl;\n    memcpy(outputAttributes, inputAttributes, nAttributes * sizeof(HSA_SVM_ATTRIBUTE));\n    EXPECT_SUCCESS_GPU(hsaKmtSVMGetAttr(pBuf, BufSize,\n                                    nAttributes, outputAttributes), gpuNode);\n\n    for (i = 0; i < nAttributes; i++) {\n        /* Default granularity could be specified using module parameter,\n         * therefore it is incorrect to expect a particular value\n         */\n        if (outputAttributes[i].type == HSA_SVM_ATTR_GRANULARITY)\n            continue;\n\n        if (outputAttributes[i].type == HSA_SVM_ATTR_ACCESS ||\n            outputAttributes[i].type == HSA_SVM_ATTR_ACCESS_IN_PLACE ||\n            outputAttributes[i].type == HSA_SVM_ATTR_NO_ACCESS)\n            EXPECT_EQ_GPU(outputAttributes[i].type, expectedDefaultResults[i], gpuNode);\n        else\n            EXPECT_EQ_GPU(outputAttributes[i].value, expectedDefaultResults[i], gpuNode);\n    }\n    LOG() << \"Setting/Getting atrributes\" << std::endl;\n    memcpy(outputAttributes, inputAttributes, nAttributes * sizeof(HSA_SVM_ATTRIBUTE));\n    EXPECT_SUCCESS_GPU(hsaKmtSVMSetAttr(pBuf, BufSize,\n                                    nAttributes, inputAttributes), gpuNode);\n    EXPECT_SUCCESS_GPU(hsaKmtSVMGetAttr(pBuf, BufSize,\n                                    nAttributes, outputAttributes), gpuNode);\n    for (i = 0; i < nAttributes; i++) {\n        if (outputAttributes[i].type == HSA_SVM_ATTR_ACCESS ||\n            outputAttributes[i].type == HSA_SVM_ATTR_ACCESS_IN_PLACE ||\n            outputAttributes[i].type == HSA_SVM_ATTR_NO_ACCESS)\n            EXPECT_EQ_GPU(inputAttributes[i].type, outputAttributes[i].type, gpuNode);\n        else\n            EXPECT_EQ_GPU(inputAttributes[i].value, outputAttributes[i].value, gpuNode);\n    }\n    delete sysBuffer;\n\n}\n\nTEST_P(KFDSVMRangeTest, SetGetAttributesTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SetGetAttributesTest));\n\n    TEST_END\n}\n\nTEST_P(KFDSVMRangeTest, XNACKModeTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    HSAuint32 i, j;\n    HSAint32 r;\n    PM4Queue queue;\n    HSAint32 enable = 0;\n    const std::vector<int> gpuNodes = m_NodeInfo.GetNodesWithGPU();\n\n    EXPECT_SUCCESS(hsaKmtGetXNACKMode(&enable));\n    for (i = 0; i < 2; i++) {\n        enable = !enable;\n        r = hsaKmtSetXNACKMode(enable);\n        if (r == HSAKMT_STATUS_SUCCESS) {\n            LOG() << \"XNACK mode: \" << std::boolalpha << enable <<\n                     \" supported\" << std::endl;\n\n            for (j = 0; j < gpuNodes.size(); j++) {\n                LOG() << \"Creating queue and try to set xnack mode on node: \"\n                      << gpuNodes.at(j) << std::endl;\n                ASSERT_SUCCESS(queue.Create(gpuNodes.at(j)));\n                EXPECT_EQ(HSAKMT_STATUS_ERROR,\n                        hsaKmtSetXNACKMode(enable));\n                EXPECT_SUCCESS(queue.Destroy());\n            }\n        } else if (r == HSAKMT_STATUS_NOT_SUPPORTED) {\n            LOG() << \"XNACK mode: \" << std::boolalpha << enable <<\n                     \" NOT supported\" << std::endl;\n        }\n    }\n\n    TEST_END\n}\n\nstatic void InvalidRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    HSAuint32 Flags;;\n    HSAKMT_STATUS ret;\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    Flags = HSA_SVM_FLAG_HOST_ACCESS | HSA_SVM_FLAG_COHERENT;\n\n    ret = RegisterSVMRange(gpuNode, reinterpret_cast<void *>(0x10000), 0x1000, 0, Flags);\n    EXPECT_NE_GPU(ret, HSAKMT_STATUS_SUCCESS, gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, InvalidRangeTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(InvalidRangeTest));\n\n    TEST_END\n}\n\nvoid KFDSVMRangeTest::SplitRangeTest(int gpuNode, int prefetch_location) {\n    unsigned int BufSize = 16 * PAGE_SIZE;\n\n    HsaSVMRange *sysBuffer;\n    HsaSVMRange *sysBuffer2;\n    HsaSVMRange *sysBuffer3;\n    HsaSVMRange *sysBuffer4;\n\n    void *pBuf;\n\n    // case 1\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 8192, PAGE_SIZE, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize);\n\n    // case 2.1\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 4096, BufSize - 4096, gpuNode,\n                                 prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize);\n\n    // case 2.2\n    pBuf = mmap(0, BufSize + 8192, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 8192, BufSize, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize + 8192);\n\n    // case 3\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(reinterpret_cast<char *>(pBuf), BufSize - 8192, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize);\n\n    // case 4.1\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize);\n\n    // case 4.2\n    pBuf = mmap(0, BufSize + 8192, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(pBuf, BufSize + 8192, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer;\n    munmap(pBuf, BufSize + 8192);\n\n    // case 5\n    pBuf = mmap(0, BufSize + 65536, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 8192, 8192, gpuNode, prefetch_location);\n    sysBuffer2 = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 32768, 8192, gpuNode, prefetch_location);\n    sysBuffer3 = new HsaSVMRange(pBuf, BufSize + 65536, gpuNode, prefetch_location);\n    delete sysBuffer2;\n    delete sysBuffer3;\n    delete sysBuffer;\n    munmap(pBuf, BufSize + 65536);\n\n    // case 6, unregister after free\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(reinterpret_cast<char *>(pBuf) + 8192, 8192, gpuNode, prefetch_location);\n    munmap(pBuf, BufSize);\n    delete sysBuffer;\n}\n\nstatic void SplitSystemRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    pKFDSVMRangeTest->SplitRangeTest(gpuNode, 0);\n\n}\n\nTEST_P(KFDSVMRangeTest, SplitSystemRangeTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SplitSystemRangeTest));\n\n    TEST_END\n}\n\nstatic void EvictSystemRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDSVMRangeTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    HSAuint32 stackData[2 * PAGE_SIZE] = {0};\n    char *pBuf = reinterpret_cast<char *>(((uint64_t)stackData + PAGE_SIZE) & ~(PAGE_SIZE - 1));\n    HSAuint32 *globalData = reinterpret_cast<uint32_t *>(pBuf);\n    const unsigned dstOffset = ((uint64_t)pBuf + 2 * PAGE_SIZE - (uint64_t)stackData) / 4;\n    const unsigned sdmaOffset = dstOffset + PAGE_SIZE;\n\n    *globalData = 0xdeadbeef;\n\n    HsaSVMRange srcBuffer((globalData), PAGE_SIZE, gpuNode);\n    HsaSVMRange dstBuffer(&stackData[dstOffset], PAGE_SIZE, gpuNode);\n    HsaSVMRange sdmaBuffer(&stackData[sdmaOffset], PAGE_SIZE, gpuNode);\n\n    /* Create PM4 and SDMA queues before fork+COW to test queue\n     * eviction and restore\n     */\n    PM4Queue pm4Queue;\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(pm4Queue.Create(gpuNode), gpuNode);\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    Dispatch dispatch0(isaBuffer);\n    dispatch0.SetArgs(srcBuffer.As<void*>(), dstBuffer.As<void*>());\n    dispatch0.Submit(pm4Queue);\n    dispatch0.Sync(g_TestTimeOut);\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(),\n                                   sdmaBuffer.As<HSAuint32 *>(), 0x12345678));\n\n    sdmaQueue.Wait4PacketConsumption();\n    EXPECT_TRUE_GPU(WaitOnValue(&stackData[sdmaOffset], 0x12345678), gpuNode);\n\n    /* Fork a child process to mark pages as COW */\n    pid_t pid = fork();\n    ASSERT_GE_GPU(pid, 0, gpuNode);\n    if (pid == 0) {\n        /* Child process waits for a SIGTERM from the parent. It can't\n         * make any write access to the stack because we want the\n         * parent to make the first write access and get a new copy. A\n         * busy loop is the safest way to do that, since any function\n         * call (e.g. sleep) would write to the stack.\n         */\n        while (1)\n        {}\n        WARN() << \"Shouldn't get here!\" << std::endl;\n        exit(0);\n    }\n\n    /* Parent process writes to COW page(s) and gets a new copy. MMU\n     * notifier needs to update the GPU mapping(s) for the test to\n     * pass.\n     */\n    *globalData = 0xD00BED00;\n    stackData[dstOffset] = 0xdeadbeef;\n    stackData[sdmaOffset] = 0xdeadbeef;\n\n    /* Terminate the child process before a possible test failure that\n     * would leave it spinning in the background indefinitely.\n     */\n    int status;\n    EXPECT_EQ_GPU(0, kill(pid, SIGTERM),gpuNode);\n    EXPECT_EQ_GPU(pid, waitpid(pid, &status, 0), gpuNode);\n    EXPECT_NE_GPU(0, WIFSIGNALED(status), gpuNode);\n    EXPECT_EQ_GPU(SIGTERM, WTERMSIG(status), gpuNode);\n\n    /* Now check that the GPU is accessing the correct page */\n    Dispatch dispatch1(isaBuffer);\n    dispatch1.SetArgs(srcBuffer.As<void*>(), dstBuffer.As<void*>());\n    dispatch1.Submit(pm4Queue);\n    dispatch1.Sync(g_TestTimeOut);\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAWriteDataPacket(sdmaQueue.GetFamilyId(),\n                                   sdmaBuffer.As<HSAuint32 *>(), 0xD0BED0BE));\n    sdmaQueue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS_GPU(pm4Queue.Destroy(), gpuNode);\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n\n    EXPECT_EQ_GPU(0xD00BED00, *globalData, gpuNode);\n    EXPECT_EQ_GPU(0xD00BED00, stackData[dstOffset], gpuNode);\n    EXPECT_EQ_GPU(0xD0BED0BE, stackData[sdmaOffset],gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, EvictSystemRangeTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(EvictSystemRangeTest));\n\n    TEST_END\n}\n\nstatic void PartialUnmapSysMemTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDSVMRangeTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    unsigned int BufSize = 16 * PAGE_SIZE;\n    void *pBuf;\n\n    PM4Queue queue;\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaSVMRange *sysBuffer;\n    HsaSVMRange destSysBuffer(BufSize, gpuNode);\n\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    sysBuffer = new HsaSVMRange(pBuf, BufSize, gpuNode, 0);\n    sysBuffer->Fill(0x01010101);\n\n    char *pBuf2 = reinterpret_cast<char *>(pBuf) + 8192;\n    unsigned int Buf2Size = 4 * PAGE_SIZE;\n    char *pBuf3 = pBuf2 + Buf2Size;\n\n    munmap(pBuf2, Buf2Size);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n\n    Dispatch dispatch(isaBuffer);\n    Dispatch dispatch2(isaBuffer);\n\n    dispatch.SetArgs(pBuf3, destSysBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n    EXPECT_EQ_GPU(destSysBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n\n    dispatch2.SetArgs(pBuf, destSysBuffer.As<void*>());\n    dispatch2.Submit(queue);\n    dispatch2.Sync(g_TestTimeOut);\n\n    EXPECT_EQ_GPU(destSysBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    //munmap(pBuf, BufSize);\n    /* munmpa vm ranges that has not been done */\n    munmap(pBuf, 8192);\n    munmap(pBuf3, BufSize - 8192 - Buf2Size);\n\n}\n\nTEST_P(KFDSVMRangeTest, PartialUnmapSysMemTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n   ASSERT_SUCCESS(KFDTest_Launch(PartialUnmapSysMemTest));\n\n    TEST_END\n}\n\nstatic void BasicVramTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    Assembler* m_pAsm;\n    m_pAsm = pKFDSVMRangeTest->GetAssemblerFromNodeId(gpuNode);\n    ASSERT_NOTNULL_GPU(m_pAsm, gpuNode);\n\n    PM4Queue queue;\n    HSAuint64 AlternateVAGPU;\n    unsigned int BufferSize = PAGE_SIZE;\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaSVMRange srcSysBuffer(BufferSize, gpuNode);\n    HsaSVMRange locBuffer(BufferSize, gpuNode, gpuNode);\n    HsaSVMRange destSysBuffer(BufferSize, gpuNode);\n\n    srcSysBuffer.Fill(0x01010101);\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()), gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode), gpuNode);\n    queue.SetSkipWaitConsump(0);\n\n    Dispatch dispatch(isaBuffer);\n    Dispatch dispatch2(isaBuffer);\n\n    dispatch.SetArgs(srcSysBuffer.As<void*>(), locBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);\n\n    dispatch2.SetArgs(locBuffer.As<void*>(), destSysBuffer.As<void*>());\n    dispatch2.Submit(queue);\n    dispatch2.Sync(g_TestTimeOut);\n\n    EXPECT_SUCCESS_GPU(queue.Destroy(), gpuNode);\n\n    EXPECT_EQ_GPU(destSysBuffer.As<unsigned int*>()[0], 0x01010101, gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, BasicVramTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(BasicVramTest));\n\n    TEST_END\n}\n\nstatic void SplitVramRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    pKFDSVMRangeTest->SplitRangeTest(gpuNode, gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, SplitVramRangeTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    ASSERT_SUCCESS(KFDTest_Launch(SplitVramRangeTest));\n\n    TEST_END\n}\n\nstatic void PrefetchTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int BufSize = 16 << 10;\n    HsaSVMRange *sysBuffer;\n    uint32_t node_id;\n\n    sysBuffer = new HsaSVMRange(BufSize, gpuNode);\n    char *pBuf = sysBuffer->As<char *>();\n    delete sysBuffer;\n\n    /* after mumap sysBuffer it should be not accessible from gpuNode */\n    HSA_SVM_ATTRIBUTE attr;\n    attr.type = HSA_SVM_ATTR_ACCESS;\n    attr.value = 0;\n    /* hsaKmtSVMGetAttr for HSA_SVM_ATTR_ACCESS is either fail or\n     * returned attr.value not equal gpuNode\n     */\n    if (hsaKmtSVMGetAttr(pBuf, BufSize, 1, &attr) == HSAKMT_STATUS_SUCCESS)\n        EXPECT_NE_GPU(attr.value, gpuNode, gpuNode);\n\n    sysBuffer = new HsaSVMRange(BufSize, gpuNode);\n    pBuf = sysBuffer->As<char *>();\n    char *pLocBuf = pBuf + BufSize / 2;\n\n    EXPECT_SUCCESS_GPU(SVMRangeGetPrefetchNode(pBuf, BufSize, &node_id), gpuNode);\n    EXPECT_EQ_GPU(node_id, 0, gpuNode);\n\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pLocBuf, BufSize / 2, gpuNode), gpuNode);\n\n    EXPECT_SUCCESS_GPU(SVMRangeGetPrefetchNode(pLocBuf, BufSize / 2, &node_id), gpuNode);\n    EXPECT_EQ_GPU(node_id, gpuNode, gpuNode);\n\n    EXPECT_SUCCESS_GPU(SVMRangeGetPrefetchNode(pBuf, BufSize, &node_id), gpuNode);\n    EXPECT_EQ_GPU(node_id, 0xffffffff, gpuNode);\n    delete sysBuffer;\n\n}\n\nTEST_P(KFDSVMRangeTest, PrefetchTest) {\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(PrefetchTest));\n\n    TEST_END\n}\n\nstatic void MigrateTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    HSAuint32 migrateRepeat = 8;\n    unsigned int BufferSize = 16 << 20;\n\n    HsaSVMRange DataBuffer(BufferSize, gpuNode);\n    HSAuint32 *pData = DataBuffer.As<HSAuint32 *>();\n\n    HsaSVMRange SysBuffer(BufferSize, gpuNode);\n    HSAuint32 *pBuf = SysBuffer.As<HSAuint32 *>();\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufferSize, 0), gpuNode);\n\n    HsaSVMRange SysBuffer2(BufferSize, gpuNode);\n    HSAuint32 *pBuf2 = SysBuffer2.As<HSAuint32 *>();\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf2, BufferSize, 0), gpuNode);\n\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    for (HSAuint32 i = 0; i < BufferSize / 4; i++)\n        pData[i] = i;\n\n    while (migrateRepeat--) {\n        /* Migrate from ram to vram */\n        EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufferSize, gpuNode), gpuNode);\n        EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf2, BufferSize, gpuNode), gpuNode);\n        /* Update content in migrated buffer in vram */\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pBuf, pData, BufferSize));\n        sdmaQueue.Wait4PacketConsumption();\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pBuf2, pData, BufferSize));\n        sdmaQueue.Wait4PacketConsumption();\n\n        /* Migrate from vram to ram\n         * CPU access the buffer migrated to vram have page fault\n         * page fault trigger migration from vram back to ram\n         * so SysBuffer should have same value as in vram\n         */\n        for (HSAuint32 i = 0; i < BufferSize / 4; i++) {\n            ASSERT_EQ_GPU(i, pBuf[i], gpuNode);\n            ASSERT_EQ_GPU(i, pBuf2[i], gpuNode);\n        }\n   }\n\n    /* If xnack off, after migrating back to ram, GPU mapping should be updated to ram\n     * test if shade can read from ram\n     * If xnack on, GPU mapping should be cleared, test if GPU vm fault can update\n     * page table and shade can read from ram.\n     */\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                pBuf, pData, BufferSize));\n    sdmaQueue.Wait4PacketConsumption();\n    for (HSAuint32 i = 0; i < BufferSize / 4; i++)\n        ASSERT_EQ_GPU(i, pBuf[i], gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, MigrateTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigrateTest));\n\n    TEST_END\n}\n\nstatic void MigrateAccessInPlaceTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    unsigned int BufferSize = MIN(256ULL << 20, pKFDSVMRangeTest->GetVramSize(gpuNode) / 2);\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode),gpuNode);\n\n    HsaSVMRange DataBuffer(BufferSize, gpuNode);\n    HSAuint32 *pData = DataBuffer.As<HSAuint32 *>();\n\n    EXPECT_SUCCESS_GPU(SVMRangeMapInPlaceToNode(pData, BufferSize, gpuNode), gpuNode);\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pData, BufferSize, gpuNode), gpuNode);\n\n    for (HSAuint32 i = 0; i < BufferSize / 4; i += 1024)\n        pData[i] = i;\n\n    /* GPU/SDMA update content in buffer migrated back to system memory */\n    sdmaQueue.PlaceAndSubmitPacket(SDMAFillDataPacket(sdmaQueue.GetFamilyId(),\n           pData, 0x55AAAA55, BufferSize));\n    sdmaQueue.Wait4PacketConsumption();\n\n    for (HSAuint32 i = 0; i < BufferSize / 4; i += 1024)\n        ASSERT_EQ_GPU(0x55AAAA55, pData[i], gpuNode);\n\n    ASSERT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n\n}\n/*\n * Test if GPU mapping to system memory is correct after range on VRAM split and migrate back\n * to system memory.\n *\n * Steps, it is same for XNACK on or off\n *   1. alloc 256MB range on system memory, set ACCESS_IN_PLACE by GPU\n *   2. Prefetcg to migrate range to GPU VRAM\n *   3. Use CPU to fill the range, range is migrated back to system memory, and split by granularity,\n *      GPU mapping update to system memory\n *   4. Use GPU sdma to fill the range in system memory\n *   5. Check if data is correct in system memory\n */\nTEST_P(KFDSVMRangeTest, MigrateAccessInPlaceTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigrateAccessInPlaceTest));\n\n    TEST_END\n}\n\n/*\n * The test changes migration granularity, then trigger CPU page fault to migrate\n * the svm range from vram to ram.\n * Check the dmesg driver output to confirm the number of CPU page fault is correct\n * based on granularity.\n *\n * For example, this is BufferPages = 5, while granularity change from 2 to 0\n * [  292.623498] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597ee000\n * [  292.623727] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f0000\n * [  292.724414] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597ee000\n * [  292.724824] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f0000\n * [  292.725094] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f2000\n * [  292.728186] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597ee000\n * [  292.729171] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597ef000\n * [  292.729576] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f0000\n * [  292.730010] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f1000\n * [  292.730931] amdgpu:svm_migrate_to_ram:744: CPU page fault address 0x7f22597f2000\n */\n\nstatic void MigrateGranularityTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\" << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found on gpuNode.\" << gpuNode << std::endl;\n        return;\n    }\n\n    HSAuint64 BufferPages = 16384;\n    HSAuint64 BufferSize = BufferPages * PAGE_SIZE;\n    HsaSVMRange SysBuffer(BufferSize, gpuNode);\n    HSAint32 *pBuf = SysBuffer.As<HSAint32*>();\n\n    HsaSVMRange SysBuffer2(BufferSize, gpuNode);\n    HSAint32 *pBuf2 = SysBuffer2.As<HSAint32*>();\n\n    HSAint32 Granularity;\n\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    for (Granularity = 0; (1ULL << Granularity) <= BufferPages; Granularity++);\n    for (HSAuint32 i = 0; i < BufferPages; i++)\n        pBuf2[i * PAGE_SIZE / 4] = i;\n\n    while (Granularity--) {\n        /* Prefetch the entire range to vram */\n        EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufferSize, gpuNode), gpuNode);\n        EXPECT_SUCCESS_GPU(SVMRangSetGranularity(pBuf, BufferSize, Granularity), gpuNode);\n\n        /* Change Buffer content in vram, then migrate it back to ram */\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                        pBuf, pBuf2, BufferSize));\n        sdmaQueue.Wait4PacketConsumption();\n\n        /* Migrate from vram to ram */\n        for (HSAuint32 i = 0; i < BufferPages; i++)\n            ASSERT_EQ_GPU(i, pBuf[i * PAGE_SIZE / 4], gpuNode);\n    }\n\n}\n\nTEST_P(KFDSVMRangeTest, MigrateGranularityTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigrateGranularityTest));\n\n    TEST_END\n}\n\nstatic void MigrateLargeBufTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    PM4Queue queue;\n    HSAuint64 AlternateVAGPU;\n    unsigned long BufferSize = 1L << 30;\n\n    unsigned long maxSDMASize = 128L << 20;  /* IB size is 4K */\n    unsigned long Size, i;\n\n    HSAuint64 vramSize;\n    vramSize = pKFDSVMRangeTest->GetVramSize(gpuNode);\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    BufferSize = MIN(BufferSize, vramSize * 3 / 4);\n\n    /* Check if the system memory size is sufficient\n     * to register the system buffer and system buffer 2\n     */\n    if(BufferSize * 2 > pKFDSVMRangeTest->GetSysMemSize() / 2) {\n        LOG() << \"Skipping test: Not enough system memory.\" << std::endl;\n        return;\n    }\n    HsaSVMRange SysBuffer(BufferSize, gpuNode);\n    SysBuffer.Fill(0x1);\n\n    HsaSVMRange SysBuffer2(BufferSize, gpuNode);\n    SysBuffer2.Fill(0x2);\n\n    /* Migrate from ram to vram\n     * using same address to register to GPU to trigger migration\n     * so LocalBuffer will have same value as SysBuffer\n     */\n    HsaSVMRange LocalBuffer(SysBuffer.As<void*>(), BufferSize, gpuNode, gpuNode);\n\n    SDMAQueue sdmaQueue;\n\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n    for (i = 0; i < BufferSize; i += Size) {\n        Size = (BufferSize - i) > maxSDMASize ? maxSDMASize : (BufferSize - i);\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    SysBuffer2.As<char*>() + i, LocalBuffer.As<char*>() + i, Size));\n        sdmaQueue.Wait4PacketConsumption();\n    }\n\n    /* Check content in migrated buffer in vram */\n    for (i = 0; i < BufferSize / 4; i += 1024)\n        ASSERT_EQ_GPU(0x1, SysBuffer2.As<unsigned int*>()[i], gpuNode);\n\n    /* Change LocalBuffer content in vram, then migrate it back to ram */\n    SysBuffer2.Fill(0x3);\n\n    for (i = 0; i < BufferSize; i += Size) {\n        Size = (BufferSize - i) > maxSDMASize ? maxSDMASize : (BufferSize - i);\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    LocalBuffer.As<char*>() + i, SysBuffer2.As<char*>() + i, Size));\n        sdmaQueue.Wait4PacketConsumption();\n    }\n\n    /* Migrate from vram to ram\n     * CPU access the buffer migrated to vram have page fault\n     * page fault trigger migration from vram back to ram\n     * so SysBuffer should have same value as in LocalBuffer\n     */\n    EXPECT_SUCCESS_GPU(SVMRangSetGranularity(SysBuffer.As<unsigned int*>(), BufferSize, 30),gpuNode);\n    for (i = 0; i < BufferSize / 4; i += 1024)\n        ASSERT_EQ_GPU(0x3, SysBuffer.As<unsigned int*>()[i], gpuNode);\n\n    /* After migrating back to ram, GPU mapping should be updated to ram\n     * test if shade can read from ram\n     */\n    SysBuffer.Fill(0x4);\n\n    for (i = 0; i < BufferSize; i += Size) {\n        Size = (BufferSize - i) > maxSDMASize ? maxSDMASize : (BufferSize - i);\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    SysBuffer2.As<char*>() + i, LocalBuffer.As<char*>() + i, Size));\n        sdmaQueue.Wait4PacketConsumption();\n    }\n\n    for (i = 0; i < BufferSize / 4; i += 1024)\n        ASSERT_EQ_GPU(0x4, SysBuffer2.As<unsigned int*>()[i],gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, MigrateLargeBufTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigrateLargeBufTest));\n\n    TEST_END\n}\n\nstatic void MigratePolicyTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\" << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    unsigned long BufferSize = 1UL << 20;\n\n    HsaSVMRange DataBuffer(BufferSize, gpuNode);\n    HSAuint64 *pData = DataBuffer.As<HSAuint64 *>();\n\n    HsaSVMRange SysBuffer(BufferSize, gpuNode);\n    HSAuint64 *pBuf = SysBuffer.As<HSAuint64 *>();\n\n    SDMAQueue sdmaQueue;\n    ASSERT_SUCCESS_GPU(sdmaQueue.Create(gpuNode),gpuNode);\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i++)\n        pData[i] = i;\n\n    /* Prefetch to migrate from ram to vram */\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufferSize, gpuNode),gpuNode);\n\n    /* Update content in migrated buffer in vram */\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                pBuf, pData, BufferSize));\n    sdmaQueue.Wait4PacketConsumption(NULL, HSA_EVENTTIMEOUT_INFINITE);\n\n    /* Migrate from vram to ram\n     * CPU access the buffer migrated to vram have page fault\n     * page fault trigger migration from vram back to ram\n     * so SysBuffer should have same value as in vram\n     */\n    for (HSAuint64 i = 0; i < BufferSize / 8; i++) {\n        ASSERT_EQ_GPU(i, pBuf[i],gpuNode);\n        /* Update buf */\n        pBuf[i] = i + 1;\n    }\n\n    /* Migrate from ram to vram if xnack on\n     * If xnack off, after migrating back to ram, GPU mapping should be updated to ram\n     * test if shade can read from ram\n     * If xnack on, GPU mapping should be cleared, test if GPU vm fault can update\n     * page table and shade can read from ram.\n     */\n//#define USE_PM4_QUEUE_TRIGGER_VM_FAULT\n#ifdef USE_PM4_QUEUE_TRIGGER_VM_FAULT\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, gpuNode, true/*zero*/, false/*local*/, true/*exec*/);\n    PM4Queue queue;\n\n    ASSERT_SUCCESS_GPU(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()),gpuNode);\n\n    ASSERT_SUCCESS_GPU(queue.Create(gpuNode),gpuNode);\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i += 512) {\n        Dispatch dispatch(isaBuffer);\n        \n        dispatch.SetArgs(pBuf + i, pData + i);\n        dispatch.Submit(queue);\n        dispatch.Sync(HSA_EVENTTIMEOUT_INFINITE);\n    }\n#else\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                pData, pBuf, BufferSize));\n    sdmaQueue.Wait4PacketConsumption(NULL, HSA_EVENTTIMEOUT_INFINITE);\n#endif\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i += 512)\n        ASSERT_EQ_GPU(i + 1, pData[i],gpuNode);\n\n    ASSERT_SUCCESS_GPU(sdmaQueue.Destroy(),gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, MigratePolicyTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigratePolicyTest));\n\n    TEST_END\n}\n\n/* Multiple GPU migration test\n *\n * Steps:\n *     1. Prefetch pBuf, pData to all GPUs, to test migration from GPU to GPU\n *     2. Use sdma queue on all GPUs, to copy data from pBuf to pData\n *     3. Check pData data\n *\n * Notes:\n *     With xnack on, step 2 will have retry fault on pBuf, to migrate from GPU to GPU,\n *     retry fault on pData, to migrate from CPU to GPU\n *\n *     With xnack off, pBuf and pData should prefetch to CPU to ensure multiple GPU access\n *\n *     step3 migrate pData from GPU to CPU\n *\n * Test will skip if only one GPU found\n */\nTEST_P(KFDSVMRangeTest, MultiGPUMigrationTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodesAll = m_NodeInfo.GetNodesWithGPU();\n    std::vector<int> gpuNodes;\n\n    for (auto node : gpuNodesAll) {\n        const HsaNodeProperties *pNodeProperties;\n\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n        if (pNodeProperties->Capability.ui32.SVMAPISupported)\n            gpuNodes.push_back(node);\n    }\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: at least two SVM supported GPUs needed.\" << std::endl;\n        return;\n    }\n\n    unsigned long BufferSize = 1UL << 20;\n\n    HsaSVMRange SysBuffer(BufferSize, defaultGPUNode);\n    HSAuint64 *pBuf = SysBuffer.As<HSAuint64 *>();\n    HsaSVMRange DataBuffer(BufferSize, defaultGPUNode);\n    HSAuint64 *pData = DataBuffer.As<HSAuint64 *>();\n\n    SDMAQueue sdmaQueue;\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i++)\n        pBuf[i] = i;\n\n    for (auto node : gpuNodes) {\n        EXPECT_SUCCESS(SVMRangeMapToNode(pBuf, BufferSize, node));\n        EXPECT_SUCCESS(SVMRangePrefetchToNode(pBuf, BufferSize, node));\n\n        EXPECT_SUCCESS(SVMRangeMapToNode(pData, BufferSize, node));\n        EXPECT_SUCCESS(SVMRangePrefetchToNode(pData, BufferSize, node));\n    }\n\n    for (auto node : gpuNodes) {\n        ASSERT_SUCCESS(sdmaQueue.Create(node));\n\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pData, pBuf, BufferSize));\n        sdmaQueue.Wait4PacketConsumption();\n\n        for (HSAuint64 i = 0; i < BufferSize / 8; i += 512)\n            ASSERT_EQ(i, pData[i]);\n\n        EXPECT_SUCCESS(sdmaQueue.Destroy());\n    }\n\n    TEST_END\n}\n\n/* Multiple GPU access in place test\n *\n * Steps:\n *     1. Prefetch pBuf, pData to all GPUs, with ACCESS_IN_PLACE on GPUs\n *     2. Use sdma queue on all GPUs, to copy data from pBuf to pData\n *     3. Prefetch pData to CPU, check pData data\n *\n * Notes:\n *     With xnack on, step 2 will have retry fault on pBuf, to migrate from GPU to GPU.\n *     If multiple GPU on xGMI same hive, there should not have retry fault on pBuf\n *     because mapping should update to another GPU vram through xGMI\n *\n *     With xnack off, pBuf and pData should prefetch to CPU to ensure multiple GPU access\n *\n *     step3 migrate pData from GPU to CPU, should not have retry fault on GPUs.\n *\n * Test will skip if only one GPU found\n */\nTEST_P(KFDSVMRangeTest, MultiGPUAccessInPlaceTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    const std::vector<int> gpuNodesAll = m_NodeInfo.GetNodesWithGPU();\n    std::vector<int> gpuNodes;\n\n    for (auto node : gpuNodesAll) {\n        const HsaNodeProperties *pNodeProperties;\n\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n        if (pNodeProperties->Capability.ui32.SVMAPISupported)\n            gpuNodes.push_back(node);\n    }\n    if (gpuNodes.size() < 2) {\n        LOG() << \"Skipping test: at least two SVM supported GPUs needed.\" << std::endl;\n        return;\n    }\n\n    unsigned long BufferSize = 1UL << 20;\n\n    HsaSVMRange SysBuffer(BufferSize, defaultGPUNode);\n    HSAuint64 *pBuf = SysBuffer.As<HSAuint64 *>();\n    HsaSVMRange DataBuffer(BufferSize, defaultGPUNode);\n    HSAuint64 *pData = DataBuffer.As<HSAuint64 *>();\n\n    SDMAQueue sdmaQueue;\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i++)\n        pBuf[i] = i;\n\n    for (auto node : gpuNodes) {\n        EXPECT_SUCCESS(SVMRangeMapInPlaceToNode(pBuf, BufferSize, node));\n        EXPECT_SUCCESS(SVMRangePrefetchToNode(pBuf, BufferSize, node));\n\n        EXPECT_SUCCESS(SVMRangeMapInPlaceToNode(pData, BufferSize, node));\n        EXPECT_SUCCESS(SVMRangePrefetchToNode(pData, BufferSize, node));\n    }\n\n    for (auto node : gpuNodes) {\n        ASSERT_SUCCESS(sdmaQueue.Create(node));\n\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pData, pBuf, BufferSize));\n        sdmaQueue.Wait4PacketConsumption();\n\n        for (HSAuint64 i = 0; i < BufferSize / 8; i += 512)\n            ASSERT_EQ(i, pData[i]);\n\n        EXPECT_SUCCESS(sdmaQueue.Destroy());\n    }\n\n    TEST_END\n}\n\n/* Multiple thread migration test\n *\n * 2 threads do migration at same time to test range migration race conditon handle.\n *\n * Steps:\n * 1. register 128MB range on system memory, don't map to GPU, 128MB is max size to put in\n *    sdma queue 4KB IB buffer.\n * 2. one thread prefetch range to GPU, another thread use sdma queue to access range at same\n *    time to generate retry vm fault to migrate range to GPU\n * 3. one thread prefetch range to CPU, another thread read range to generate CPU page fault\n *    to migrate range to CPU at same time\n * 4. loop test step 2 and 3 twice, to random CPU/GPU fault and prefetch migration order\n */\nstruct ReadThreadParams {\n    HSAuint64* pBuf;\n    HSAint64 BufferSize;\n    int defaultGPUNode;\n};\n\nunsigned int CpuReadThread(void* p) {\n    struct ReadThreadParams* pArgs = reinterpret_cast<struct ReadThreadParams*>(p);\n\n    for (HSAuint64 i = 0; i < pArgs->BufferSize / 8; i += 512)\n         EXPECT_EQ(i, pArgs->pBuf[i]);\n    return 0;\n}\n\nunsigned int GpuReadThread(void* p) {\n    struct ReadThreadParams* pArgs = reinterpret_cast<struct ReadThreadParams*>(p);\n\n    EXPECT_SUCCESS(SVMRangePrefetchToNode(pArgs->pBuf, pArgs->BufferSize, pArgs->defaultGPUNode));\n    return 0;\n}\n\nstatic void MultiThreadMigrationTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\" << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    unsigned long test_loops = 2;\n    unsigned long BufferSize = 1UL << 27;\n    HsaSVMRange SysBuffer(BufferSize, gpuNode);\n    HSAuint64 *pBuf = SysBuffer.As<HSAuint64 *>();\n    HsaSVMRange DataBuffer(BufferSize, gpuNode);\n    HSAuint64 *pData = DataBuffer.As<HSAuint64 *>();\n    SDMAQueue sdmaQueue;\n    uint64_t threadId;\n    struct ReadThreadParams params;\n\n    params.pBuf = pBuf;\n    params.BufferSize = BufferSize;\n    params.defaultGPUNode = gpuNode;\n\n    EXPECT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    for (HSAuint64 i = 0; i < BufferSize / 8; i++)\n        pBuf[i] = i;\n\n    for (HSAuint64 i = 0; i < test_loops; i++) {\n        /* 2 threads migrate to GPU */\n        sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pData, pBuf, BufferSize));\n        ASSERT_EQ_GPU(true, StartThread(&GpuReadThread, &params, threadId), gpuNode);\n        sdmaQueue.Wait4PacketConsumption();\n        WaitForThread(threadId);\n\n        /* 2 threads migrate to cpu */\n        ASSERT_EQ_GPU(true, StartThread(&CpuReadThread, &params, threadId), gpuNode);\n        EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufferSize, 0), gpuNode);\n        WaitForThread(threadId);\n    }\n\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n\n}\n\nTEST_P(KFDSVMRangeTest, MultiThreadMigrationTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MultiThreadMigrationTest));\n\n    TEST_END\n}\n\n/*\n * Test SVM support file backed range\n *\n * Create temp file, mmap to alloc memory backed on file.\n * Create file backed svm range, to map to GPU for xnack on or off\n * Use sdma to write data to memory, should write to file\n * Close file, and then check if file data is updated correctly\n */\nstatic void MigrateFileBackedRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\"\n            << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    char tmpfname[] = \"/tmp/kfdtest-XXXXXX\";\n    int fd = mkostemp(tmpfname, 0600);\n    ASSERT_NE(-1, fd);\n\n    size_t size = PAGE_SIZE;\n    char *buf = reinterpret_cast<char *>(alloca(size));\n    memset(buf, 0x30, size);\n\n    ASSERT_EQ(size, write(fd, buf, size));\n\n    void *MmapedFile = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);\n    ASSERT_NE(MAP_FAILED, MmapedFile);\n\n    HsaSVMRange filebackedRange(MmapedFile, size, gpuNode, gpuNode);\n\n    SDMAQueue sdmaQueue;\n    EXPECT_SUCCESS(sdmaQueue.Create(gpuNode));\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAFillDataPacket(sdmaQueue.GetFamilyId(),\n                    MmapedFile, 0x33333333, size));\n    sdmaQueue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\n    munmap(MmapedFile, size);\n    EXPECT_SUCCESS(close(fd));\n\n    fd = open(tmpfname, O_RDONLY);\n    ASSERT_NE(-1, fd);\n\n    ASSERT_EQ(size, read(fd, buf, size));\n    EXPECT_EQ(0x33, buf[0]);\n\n    EXPECT_SUCCESS(close(fd));\n    EXPECT_SUCCESS(remove(tmpfname));\n}\n\nTEST_P(KFDSVMRangeTest, MigrateFileBackedRangeTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(MigrateFileBackedRangeTest));\n\n    TEST_END\n}\n\n/*\n * Test SVM support read only range\n *\n * Map read only range to GPU, test sdma can read the range\n * write to range should trigger GPU vm fault for both xnack on and off\n */\n\nTEST_P(KFDSVMRangeTest, ReadOnlyRangeTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (!GetVramSize(defaultGPUNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    /*\n     * Use child process to run test because the test trigger GPU vm fault, KFD evict all user queues\n     * of the process and no more test can run after vm fault on the process.\n     */\n    int pid = fork();\n    if (pid == 0) {\n        TearDown();\n        SetUp();\n    } else {\n        int childStatus;\n\n        waitpid(pid, &childStatus, 0);\n        if (hsakmt_is_dgpu()) {\n            EXPECT_EQ(true, WIFEXITED(childStatus));\n            EXPECT_EQ(0, WEXITSTATUS(childStatus));\n        } else {\n            EXPECT_EQ(true, WIFSIGNALED(childStatus));\n            EXPECT_EQ(SIGSEGV, WTERMSIG(childStatus));\n        }\n\n        return;\n    }\n\n    /* Use child process to run test */\n    int ret = 0;\n    HsaSVMRange inBuffer(PAGE_SIZE * 2, defaultGPUNode);\n    HSAuint8 *pinBuf = inBuffer.As<HSAuint8 *>();\n\n    memset(pinBuf, 0x55, PAGE_SIZE);\n\n    /* Map readonly pinBuf to GPU, sDMA should be able to read it */\n    mprotect(pinBuf, PAGE_SIZE, PROT_READ);\n\n    HsaSVMRange outputBuffer(PAGE_SIZE, defaultGPUNode);\n    HSAuint8 *pBuf = outputBuffer.As<HSAuint8 *>();\n\n    HsaEvent *vmFaultEvent;\n    HSAuint64 faultAddress;\n    HsaEventDescriptor eventDesc;\n    eventDesc.EventType = HSA_EVENTTYPE_MEMORY;\n    eventDesc.NodeId = defaultGPUNode;\n    eventDesc.SyncVar.SyncVar.UserData = NULL;\n    eventDesc.SyncVar.SyncVarSize = 0;\n\n    ret = hsaKmtCreateEvent(&eventDesc, true, false, &vmFaultEvent);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Event create failed\" << std::endl;\n        exit(ret);\n    }\n\n    SDMAQueue sdmaQueue;\n\n    ret = sdmaQueue.Create(defaultGPUNode);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Queue create failed\" << std::endl;\n        goto queue_fail;\n    }\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pBuf, reinterpret_cast<void *>(pinBuf), PAGE_SIZE));\n    sdmaQueue.Wait4PacketConsumption();\n    EXPECT_EQ(0x55, pBuf[0]);\n    if (pBuf[0] != 0x55)\n        goto event_fail;\n\n    /* sDMA write to readonly pinBuf should fail with GPU vm fault, check if pinBuf content is\n     * not changed, and KFD send HSA_EVENTTYPE_MEMORY event back with fault address pinBuf.\n     *\n     * This must be the last step of test because all queues are evicted after vm fault.\n     */\n\n    memset(pBuf, 0xAA, PAGE_SIZE);\n    sdmaQueue.PlaceAndSubmitPacket(SDMACopyDataPacket(sdmaQueue.GetFamilyId(),\n                    pinBuf, reinterpret_cast<void *>(pBuf), PAGE_SIZE));\n\n    ret = hsaKmtWaitOnEvent(vmFaultEvent, g_TestTimeOut);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n        WARN() << \"Wait failed. No Exception triggered\" << std::endl;\n        goto event_fail;\n    }\n    if (vmFaultEvent->EventData.EventType != HSA_EVENTTYPE_MEMORY) {\n        WARN() << \"Unexpected Event Received \" << vmFaultEvent->EventData.EventType << std::endl;\n        ret = HSAKMT_STATUS_ERROR;\n\n        goto event_fail;\n    }\n    faultAddress = vmFaultEvent->EventData.EventData.MemoryAccessFault.VirtualAddress;\n    if (faultAddress != (HSAuint64)pinBuf) {\n        WARN() << \"Unexpected Fault Address \" << faultAddress << std::endl;\n        ret = HSAKMT_STATUS_ERROR;\n    }\n\nevent_fail:\n    EXPECT_SUCCESS(sdmaQueue.Destroy());\nqueue_fail:\n    hsaKmtDestroyEvent(vmFaultEvent);\n    /* Child process exit, otherwise it will continue to run remaining tests */\n    exit(ret);\n\n    TEST_END\n}\n\n/*\n * Test SMI HMM SVM profiling event\n * Use separate thread to read event the same way as ROCr and ROCProfiler\n */\nstruct ReadEventThreadParams {\n    int nodeid;\n    HSAuint64 *pBuf;\n    int BufSize;\n    pthread_barrier_t *barrier;\n};\n\nunsigned int ReadSMIEventThread(void* p) {\n    struct ReadEventThreadParams *pArgs = (struct ReadEventThreadParams *)p;\n    char msg[HSA_SMI_EVENT_MSG_SIZE];\n    struct pollfd fds = {0};\n    HSAuint64 events;\n    int fd;\n\n    EXPECT_SUCCESS_GPU(hsaKmtOpenSMI(pArgs->nodeid, &fd), pArgs->nodeid);\n\n    events = HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_INDEX_MAX) - 1;\n    EXPECT_EQ_GPU(write(fd, &events, sizeof(events)), sizeof(events), pArgs->nodeid);\n\n    pthread_barrier_wait(pArgs->barrier);\n\n    fds.fd = fd;\n    fds.events = POLLIN;\n    EXPECT_GE(poll(&fds, 1, 1000), 0);\n\n    memset(msg, 0, sizeof(msg));\n    EXPECT_GE_GPU(read(fd, msg, HSA_SMI_EVENT_MSG_SIZE), 0, pArgs->nodeid);\n\n    int event_id, pid, size, trigger, unused;\n    unsigned int id;\n    HSAuint64 timestamp;\n    HSAuint64 addr;\n\n    sscanf(msg, \"%x\", &event_id);\n\n    /* check each possible response event message format */\n    if (event_id == HSA_SMI_EVENT_MIGRATE_START) {\n        /* the message is HSA_SMI_EVENT_MIGRATE_START */\n        EXPECT_EQ_GPU(sscanf(msg + sizeof(event_id), \"%ld -%d @%lx(%d) %d->%x %x:%d %d\\n\", &timestamp, &pid,\n                     &addr, &size, &unused, &unused, &unused, &unused, &trigger), 9, pArgs->nodeid);\n        EXPECT_EQ_GPU((HSAuint64 *)(addr << PAGE_SHIFT), pArgs->pBuf, pArgs->nodeid);\n        EXPECT_EQ_GPU(size << PAGE_SHIFT, pArgs->BufSize, pArgs->nodeid);\n        EXPECT_EQ_GPU(pid, getpid(), pArgs->nodeid);\n        EXPECT_EQ_GPU(trigger, HSA_MIGRATE_TRIGGER_PREFETCH, pArgs->nodeid);\n\n     }else if (event_id == HSA_SMI_EVENT_QUEUE_EVICTION) {\n        /* the message is HSA_SMI_EVENT_QUEUE_EVICTION */\n        EXPECT_EQ_GPU(sscanf(msg + sizeof(event_id), \"%ld -%d %x %d\\n\",  &timestamp, &pid, &id, &trigger),\n                      4, pArgs->nodeid);\n        EXPECT_EQ_GPU(pid, getpid(), pArgs->nodeid);\n        EXPECT_EQ_GPU(trigger, HSA_QUEUE_EVICTION_TRIGGER_SVM, pArgs->nodeid);\n\n    } else if (event_id == HSA_SMI_EVENT_QUEUE_RESTORE) {\n      /* the message is HSA_SMI_EVENT_QUEUE_RESTORE */\n        EXPECT_EQ_GPU(sscanf(msg + sizeof(event_id), \"%ld -%d %x\\n\", &timestamp, &pid, &id), 3, pArgs->nodeid);\n        EXPECT_EQ_GPU(pid, getpid(), pArgs->nodeid);\n\n    } else if (event_id == HSA_SMI_EVENT_UNMAP_FROM_GPU) {\n        /* the message is HSA_SMI_EVENT_UNMAP_FROM_GPU */\n        EXPECT_EQ_GPU(sscanf(msg + sizeof(event_id), \"%ld -%d @%lx(%d) %x %d\\n\", &timestamp, &pid,\n                      &addr, &size, &id, &trigger), 6, pArgs->nodeid);\n        /* unmap address can be from different gpus */\n        EXPECT_EQ_GPU(size << PAGE_SHIFT, pArgs->BufSize, pArgs->nodeid);\n        EXPECT_EQ_GPU(pid, getpid(), pArgs->nodeid);\n        EXPECT_EQ_GPU(trigger, HSA_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU, pArgs->nodeid);\n    } else {\n        WARN() << \"HMMProfilingEvent failed on gpuNode: \" <<  pArgs->nodeid << std::endl;\n    }\n\n    close(fd);\n    return 0;\n}\n\nstatic void HMMProfilingEvent(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    if (pKFDSVMRangeTest->Get_Version()->KernelInterfaceMinorVersion < 10)\n        return;\n\n    const HsaNodeProperties *pNodeProperties =\n        pKFDSVMRangeTest->Get_NodeInfo()->GetNodeProperties(gpuNode);\n    if (pNodeProperties->Integrated) {\n        LOG() << \"Skipping test on APU.\" << std::endl;\n        return;\n    }\n\n    if (!pKFDSVMRangeTest->GetVramSize(gpuNode)) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    if (pKFDSVMRangeTest->Get_NodeInfo()->IsAppAPU(gpuNode)) {\n        LOG() << \"Skipping test on AppAPU.\" << std::endl;\n        return;\n    }\n\n    pthread_barrier_t barrier;\n    ASSERT_SUCCESS(pthread_barrier_init(&barrier, NULL, 2));\n\n    int BufSize = 16 << 10;\n    HsaSVMRange SysBuffer(BufSize, gpuNode);\n    HSAuint64 *pBuf = SysBuffer.As<HSAuint64 *>();\n\n    struct ReadEventThreadParams pArgs = {gpuNode, pBuf, BufSize, &barrier};\n    uint64_t threadId;\n    ASSERT_EQ(true, StartThread(&ReadSMIEventThread, &pArgs, threadId));\n\n    pthread_barrier_wait(&barrier);\n\n    EXPECT_SUCCESS(SVMRangePrefetchToNode(pBuf, BufSize, gpuNode));\n\n    WaitForThread(threadId);\n\n}\n\nTEST_P(KFDSVMRangeTest, HMMProfilingEvent) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(HMMProfilingEvent));\n\n    TEST_END\n}\n\n/*\n * Test SVM support VRAM overcommitment\n *\n * Prefetch total VRAM size plus overCommitSize SVM range to VRAM. after VRAM is full,\n * KFD should support VRAM overcommitment by evicting SVM ranges to system memory to alloc\n * VRAM for new ranges.\n */\nstatic void VramOvercommitTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\" << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    HSAuint64 vramSize = pKFDSVMRangeTest->GetVramSize(gpuNode);\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    unsigned long overCommitSize = 1UL << 30;\n\n    /* With XNACK off, KFD checks that all SVM memory will fit into system memory */\n\tif (!g_TestGPUsNum && vramSize + overCommitSize > pKFDSVMRangeTest->GetSysMemSize() / 2) {\n        LOG() << \"Skipping test: Not enough system memory.\" << std::endl;\n        return;\n\t} else if (g_TestGPUsNum && g_TestGPUsNum *(vramSize + overCommitSize)\n\t\t\t    > pKFDSVMRangeTest->GetSysMemSize() / 2) {\n        LOG() << \"Skipping test: Not enough system memory.\" << std::endl;\n        return;\n\t}\n\n    unsigned long BufSize = 512UL << 20;\n    unsigned long numBufs = (vramSize + overCommitSize) / BufSize;\n    HSAKMT_STATUS ret;\n\n    void *pBuf[numBufs];\n    unsigned long i;\n\n    for (i = 0; i < numBufs; i++) {\n        pBuf[i] = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n        ASSERT_NE(MAP_FAILED, pBuf[i]);\n\n        ret = RegisterSVMRange(gpuNode, pBuf[i], BufSize, gpuNode, 0);\n        if (ret != HSAKMT_STATUS_SUCCESS)\n            break;\n    }\n\n    EXPECT_EQ_GPU(numBufs, i, gpuNode);\n\n    while (i--)\n        munmap(pBuf[i], BufSize);\n\n}\n\nTEST_P(KFDSVMRangeTest, VramOvercommitTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(VramOvercommitTest));\n\n    TEST_END\n}\n\n/*\n * Test SVM support VRAM overcommitment\n *\n * Prefetch giant overcommit SVM range to VRAM, KFD should support VRAM overcommitment\n * by spliting giant range into smaller ranges, evicting SVM ranges to system memory to\n * alloc VRAM for overcommitment ranges.\n */\nTEST_P(KFDSVMRangeTest, VramOvercommitGiantRangeTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    if (!SVMAPISupported())\n        return;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test: No svm range support for family \"\n                             \"ID 0x\" << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    HSAuint64 vramSize = GetVramSize(defaultGPUNode);\n    if (!vramSize) {\n        LOG() << \"Skipping test: No VRAM found.\" << std::endl;\n        return;\n    }\n\n    unsigned long overCommitSize = 1UL << 30;\n\n    /* With XNACK off, KFD checks that all SVM memory will fit into system memory */\n    if (vramSize + overCommitSize > GetSysMemSize() / 2) {\n        LOG() << \"Skipping test: no enough system memory.\" << std::endl;\n        return;\n    }\n\n    unsigned long BufSize = vramSize + overCommitSize;\n    HSAKMT_STATUS ret;\n    void *pBuf;\n\n    pBuf = mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    ASSERT_NE(MAP_FAILED, pBuf);\n\n    ret = RegisterSVMRange(defaultGPUNode, pBuf, BufSize, defaultGPUNode, 0);\n    EXPECT_EQ (HSAKMT_STATUS_SUCCESS, ret);\n\n    munmap(pBuf, BufSize);\n    TEST_END\n}\n\n/*\n * Test partial range prefault\n *\n * mmap alloc 4 pages range, memset middle 2 pages, prefetch entire range to VRAM,\n * use sdma to memset the rest 2 pages, each page has different value 0x1, 0x2, 0x3, 0x4\n * then check if all page have the specific value after migrating 4 pages to system memory.\n */\nstatic void PrefaultPartialRangeTest(KFDTEST_PARAMETERS* pTestParamters) {\n\n    int gpuNode = pTestParamters->gpuNode;\n    KFDSVMRangeTest* pKFDSVMRangeTest = (KFDSVMRangeTest*)pTestParamters->pTestObject;\n\n    if (!pKFDSVMRangeTest->SVMAPISupported_GPU(gpuNode))\n        return;\n\n    unsigned int m_FamilyId = pKFDSVMRangeTest->GetFamilyIdFromNodeId(gpuNode);\n    if (m_FamilyId < FAMILY_AI) {\n        LOG() << std::hex << \"Skipping test on gpuNode: No svm range support for family ID 0x\" << gpuNode << m_FamilyId << \".\" << std::endl;\n        return;\n    }\n\n    unsigned long BufSize = 4 * PAGE_SIZE;\n    HSAKMT_STATUS ret;\n    char *pBuf;\n\n    pBuf = (char *)mmap(0, BufSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n    ASSERT_NE_GPU(MAP_FAILED, pBuf, gpuNode);\n\n    memset(pBuf + PAGE_SIZE, 0x2, PAGE_SIZE);\n    memset(pBuf + 2 * PAGE_SIZE, 0x3, PAGE_SIZE);\n\n    EXPECT_SUCCESS_GPU(RegisterSVMRange(gpuNode, pBuf, BufSize, 0, 0), gpuNode);\n    EXPECT_SUCCESS_GPU(SVMRangePrefetchToNode(pBuf, BufSize, gpuNode), gpuNode);\n\n    SDMAQueue sdmaQueue;\n    EXPECT_SUCCESS_GPU(sdmaQueue.Create(gpuNode), gpuNode);\n\n    sdmaQueue.PlaceAndSubmitPacket(SDMAFillDataPacket(sdmaQueue.GetFamilyId(),\n                       pBuf, 0x01010101, PAGE_SIZE));\n    sdmaQueue.PlaceAndSubmitPacket(SDMAFillDataPacket(sdmaQueue.GetFamilyId(),\n                       pBuf + 3 * PAGE_SIZE, 0x04040404, PAGE_SIZE));\n    sdmaQueue.Wait4PacketConsumption();\n\n    EXPECT_SUCCESS_GPU(sdmaQueue.Destroy(), gpuNode);\n\n    for (int i = 0; i < 4; i++)\n        EXPECT_EQ_GPU(pBuf[i * PAGE_SIZE], i + 1, gpuNode);\n\n    munmap(pBuf, BufSize);\n\n}\n\nTEST_P(KFDSVMRangeTest, PrefaultPartialRangeTest) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    ASSERT_SUCCESS(KFDTest_Launch(PrefaultPartialRangeTest));\n\n    TEST_END\n}\n\nINSTANTIATE_TEST_CASE_P(, KFDSVMRangeTest,::testing::Values(0, 1));\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDSVMRangeTest.hpp",
    "content": "/*\n * Copyright (C) 2020 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_SVMRANGE_TEST__H__\n#define __KFD_SVMRANGE_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass KFDSVMRangeTest : public KFDBaseComponentTest,\n                        public ::testing::WithParamInterface<int> {\n public:\n    KFDSVMRangeTest() {}\n    ~KFDSVMRangeTest() {}\n    void SplitRangeTest(int defaultGPUNode, int prefetch_location);\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __KFD_LOCALMEMORY_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestFlags.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_TEST_FLAGS__H__\n#define __KFD_TEST_FLAGS__H__\n\nextern unsigned int g_TestRunProfile;\nextern unsigned int g_TestENVCaps;\nextern unsigned int g_TestTimeOut;\nextern int g_TestNodeId;\nextern int g_TestDstNodeId;\nextern bool g_IsChildProcess;\nextern bool g_IsEmuMode;\n\n// Each test should call TEST_START with the test custom profile and HW scheduling\nenum TESTPROFILE{\n    TESTPROFILE_DEV =          0x1,\n    TESTPROFILE_PROMO =    0x2,\n    // 0x4 - 0x8000 - unused flags\n    // Can add any flag that will mark only part of the tests to run\n    TESTPROFILE_RUNALL = 0xFFFF\n};\n\nenum ENVCAPS{\n    ENVCAPS_NOADDEDCAPS    =  0x0,\n    ENVCAPS_HWSCHEDULING   =  0x1,\n    ENVCAPS_16BITPASID             =  0x2,\n    ENVCAPS_32BITLINUX              =  0x4,\n    ENVCAPS_64BITLINUX              =  0x8\n    // 0x8 - 0x8000 - unused flags\n    // Can add any flag that will mark specific hw limitation or capability\n};\n\nenum KfdFamilyId {\n    FAMILY_UNKNOWN = 0,\n    FAMILY_CI,    // Sea Islands: Hawaii (P), Maui (P), Bonaire (M)\n    FAMILY_KV,    // Fusion Kaveri: Spectre, Spooky; Fusion Kabini: Kalindi\n    FAMILY_VI,    // Volcanic Islands: Iceland (V), Tonga (M)\n    FAMILY_CZ,    // Carrizo, Nolan, Amur\n    FAMILY_AI,    // Arctic Islands\n    FAMILY_RV,    // Raven\n    FAMILY_AR,    // Arcturus\n    FAMILY_AL,    // Aldebaran\n    FAMILY_AV,    // Aqua Vanjaram\n    FAMILY_NV,    // Navi10\n    FAMILY_GFX11, // GFX11\n    FAMILY_GFX12, // GFX12\n};\n\n#endif  //  __KFD_TEST_FLAGS__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestMain.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"gtest/gtest.h\"\n#include \"KFDTestFlags.hpp\"\n#include \"KFDTestUtil.hpp\"\n#include \"GoogleTestExtension.hpp\"\n#include \"OSWrapper.hpp\"\n#include \"Assemble.hpp\"\n\n#define KFD_TEST_DEFAULT_TIMEOUT 60000\n\nstd::ostream& operator << (std::ostream& out, TESTPROFILE profile) {\n    switch (profile) {\n    case TESTPROFILE_DEV:\n        out << \"Developer Test\";\n        break;\n    case TESTPROFILE_PROMO:\n        out << \"Promotion Test\";\n        break;\n    case TESTPROFILE_RUNALL:\n        out << \"Full Test\";\n        break;\n    default:\n        out << \"INVALID\";\n    }\n\n    return out;\n}\n\nunsigned int g_TestGPUsNum ;\nunsigned int g_TestRunProfile;\nunsigned int g_TestENVCaps;\nunsigned int g_TestTimeOut;\nint g_TestNodeId;\nint g_TestDstNodeId;\nbool g_IsChildProcess;\nbool g_IsEmuMode;\nunsigned int g_SleepTime;\nunsigned int g_TestGPUFamilyId;\nclass KFDBaseComponentTest *g_baseTest;\n\nGTEST_API_ int main(int argc, char **argv) {\n    // Default values for run parameters\n    g_TestRunProfile = TESTPROFILE_RUNALL;\n    g_TestENVCaps = ENVCAPS_NOADDEDCAPS | ENVCAPS_64BITLINUX;\n    g_TestTimeOut = KFD_TEST_DEFAULT_TIMEOUT;\n\n    testing::InitGoogleTest(&argc, argv);\n\n    CommandLineArguments args;\n    memset(&args, 0, sizeof(args));\n\n    bool success = GetCommandLineArguments(argc, argv, args);\n\n    if (success) {\n        int r;\n        if ((GetHwCapabilityHWS() || args.HwsEnabled == HWCAP__FORCE_ENABLED) &&\n                (args.HwsEnabled != HWCAP__FORCE_DISABLED))\n            g_TestENVCaps |= ENVCAPS_HWSCHEDULING;\n\n        g_TestRunProfile = args.TestProfile;\n        g_IsChildProcess = args.ChildProcess;\n\n        if ( args.TimeOut > 0 )\n            g_TestTimeOut = args.TimeOut;\n\n        g_SleepTime = 0x00;\n        if (args.SleepTime > 0) {\n            g_SleepTime = args.SleepTime;\n        }\n\n        // If --node is not specified, then args.NodeId == -1\n        g_TestNodeId = args.NodeId;\n        g_TestDstNodeId = args.DstNodeId;\n\n        g_IsEmuMode = CheckEmuModeEnabled();\n\n        LOG() << \"Profile: \" << (TESTPROFILE)g_TestRunProfile << std::endl;\n        LOG() << \"HW capabilities: 0x\" << std::hex << g_TestENVCaps << std::endl;\n        if (g_IsEmuMode)\n        {\n            LOG() << \"Emulation Mode Enabled\" << std::endl;\n        }\n\n        if (g_SleepTime > 0) {\n            LOG() << \"Sleep time in seconds as specified by user: \" << std::dec << g_SleepTime << std::endl;\n        }\n\n        char *testGPUsNum = NULL;\n        /* if HSA_TEST_GPUS_NUM is defined use it, otherwise test on 1 gpu */\n        testGPUsNum = getenv(\"HSA_TEST_GPUS_NUM\");\n        if (testGPUsNum)\n            g_TestGPUsNum = std::max(1, atoi(testGPUsNum));\n        else\n            g_TestGPUsNum = 1;\n\n        /* init LLVM one time*/\n        Init_LLVM();\n\n        r = RUN_ALL_TESTS();\n\n        /* shutdown LLVM after tests finish */\n        Shutdown_LLVM();\n\n        LOG() << \"kfdtest finished with return code: \" << r << std::endl;\n        return r;\n    }\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestUtil.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDTestUtil.hpp\"\n#include <stdlib.h>\n#include <sys/time.h>\n#include <sys/mman.h>\n#include <algorithm>\n#include <vector>\n#include \"BaseQueue.hpp\"\n#include \"Dispatch.hpp\"\n#include \"SDMAPacket.hpp\"\n\nvoid WaitUntilInput() {\n    char dummy;\n    printf(\"Press enter to continue: \");\n    do {\n        scanf(\"%c\", &dummy);\n    } while (dummy != 10); // enter key's ascii value is 10\n}\n\n/* fscanf_dec - read a file whose content is a decimal number\n *      @file [IN ] file to read\n *      @num [OUT] number in the file\n *\n * It is copied from the same function in libhsakmt\n */\nHSAKMT_STATUS fscanf_dec(const char *file, uint32_t *num)\n{\n    FILE *fd;\n    HSAKMT_STATUS ret = HSAKMT_STATUS_SUCCESS;\n\n    fd = fopen(file, \"r\");\n    if (!fd) {\n        LOG() << \"Failed to open \" << file << std::endl;\n        return HSAKMT_STATUS_INVALID_PARAMETER;\n    }\n    if (fscanf(fd, \"%u\", num) != 1) {\n        LOG() << \"Failed to parse as a decimal: \" << file << std::endl;;\n        ret = HSAKMT_STATUS_ERROR;\n    }\n\n    fclose(fd);\n    return ret;\n}\n\nuint64_t RoundToPowerOf2(uint64_t val) {\n    val--;\n\n    /* Shift with amount larger than the bit width can result in\n     * undefined behavior by compiler for release builds.\n     * Shift till 32 bit only which is less than bit width of val.\n     */\n    for (int i = 1; i <= 32; i *= 2)\n        val |= val >> i;\n\n    val++;\n\n    return val;\n}\n\nbool WaitOnValue(const volatile unsigned int *buf, unsigned int value, unsigned int timeOut) {\n    while (timeOut > 0 && *buf != value) {\n        Delay(1);\n\n        if (timeOut != HSA_EVENTTIMEOUT_INFINITE)\n            timeOut--;\n    }\n\n    return *buf == value;\n}\n\nvoid SplitU64(const HSAuint64 value, unsigned int& rLoPart, unsigned int& rHiPart) {\n    rLoPart = static_cast<unsigned int>(value);\n    rHiPart = static_cast<unsigned int>(value >> 32);\n}\n\nbool CheckEmuModeEnabled()\n{\n    uint32_t emu_mode = false;\n    fscanf_dec(\"/sys/module/amdgpu/parameters/emu_mode\", &emu_mode);\n    return (emu_mode != 0);\n}\n\nbool GetHwCapabilityHWS() {\n    unsigned int value = 0;\n    bool valExists = ReadDriverConfigValue(CONFIG_HWS, value);\n\n    /* HWS is enabled by default */\n    return ( (!valExists) || ( value > 0));\n}\n\nHSAKMT_STATUS CreateQueueTypeEvent(\n    bool                ManualReset,            // IN\n    bool                IsSignaled,             // IN\n    unsigned int        NodeId,                 // IN\n    HsaEvent**          Event                   // OUT\n    ) {\n    HsaEventDescriptor Descriptor;\n\n// TODO: Create per-OS header with this sort of definitions\n#ifdef _WIN32\n    Descriptor.EventType = HSA_EVENTTYPE_QUEUE_EVENT;\n#else\n    Descriptor.EventType = HSA_EVENTTYPE_SIGNAL;\n#endif\n    Descriptor.SyncVar.SyncVar.UserData = (void*)0xABCDABCD;\n    Descriptor.NodeId = NodeId;\n\n    return hsaKmtCreateEvent(&Descriptor, ManualReset, IsSignaled, Event);\n}\n\nHSAKMT_STATUS CreateHWExceptionEvent(\n    bool                ManualReset,            // IN\n    bool                IsSignaled,             // IN\n    unsigned int        NodeId,                 // IN\n    HsaEvent**          Event                   // OUT\n    ) {\n    HsaEventDescriptor Descriptor;\n\n    Descriptor.EventType = HSA_EVENTTYPE_HW_EXCEPTION;\n    Descriptor.SyncVar.SyncVar.UserData = (void*)0xABCDABCD;\n    Descriptor.NodeId = NodeId;\n\n    return hsaKmtCreateEvent(&Descriptor, ManualReset, IsSignaled, Event);\n}\n\nstatic bool hsakmt_is_dgpu_dev = false;\n\nbool hsakmt_is_dgpu() {\n    return hsakmt_is_dgpu_dev;\n}\n\nbool hasPciAtomicsSupport(int node) {\n    /* If we can't get Node Properties, assume a lack of Atomics support */\n    HsaNodeProperties *pNodeProperties = new HsaNodeProperties();\n    if (hsaKmtGetNodeProperties(node, pNodeProperties)) {\n        LOG() << \"Unable to get Node Properties for node \" << node << std::endl;\n        return false;\n    }\n\n    /* APUs don't have IO Links, but support Atomic Ops by default */\n    if (pNodeProperties->NumCPUCores && pNodeProperties->NumFComputeCores)\n        return true;\n\n    HsaIoLinkProperties *IolinkProperties = new HsaIoLinkProperties[pNodeProperties->NumIOLinks];\n    if (hsaKmtGetNodeIoLinkProperties(node, pNodeProperties->NumIOLinks, IolinkProperties)) {\n        LOG() << \"Unable to get Node IO Link Information for node \" << node << std::endl;\n        return false;\n    }\n\n    /* Make sure we're checking GPU-to-CPU connection here */\n    for (int linkId = 0; linkId < pNodeProperties->NumIOLinks; linkId++) {\n        /* Make sure it's a CPU */\n        HsaNodeProperties *linkProps = new HsaNodeProperties();\n        if (hsaKmtGetNodeProperties(IolinkProperties[linkId].NodeTo, linkProps)) {\n            LOG() << \"Unable to get connected device's IO Link information\" << std::endl;\n            return false;\n        }\n        if (linkProps->NumCPUCores) {\n            /* IOLink flags are only valid if Override flag is set */\n            return (IolinkProperties[linkId].Flags.ui32.Override &&\n                   !IolinkProperties[linkId].Flags.ui32.NoAtomics32bit &&\n                   !IolinkProperties[linkId].Flags.ui32.NoAtomics64bit);\n        }\n    }\n\n    return false;\n}\n\nunsigned int FamilyIdFromNode(const HsaNodeProperties *props) {\n    unsigned int familyId = FAMILY_UNKNOWN;\n\n    switch (props->EngineId.ui32.Major) {\n    case 7:\n        if (props->EngineId.ui32.Minor == 0) {\n            if (props->EngineId.ui32.Stepping == 0)\n                familyId = FAMILY_KV;\n            else\n                familyId = FAMILY_CI;\n        }\n        break;\n    case 8:\n        familyId = FAMILY_VI;\n        if (props->EngineId.ui32.Stepping == 1)\n            familyId = FAMILY_CZ;\n        break;\n    case 9:\n        familyId = FAMILY_AI;\n        if (props->EngineId.ui32.Minor >= 4)\n            familyId = FAMILY_AV;\n        else if (props->EngineId.ui32.Stepping == 2)\n            familyId = FAMILY_RV;\n        else if (props->EngineId.ui32.Stepping == 8)\n            familyId = FAMILY_AR;\n        else if (props->EngineId.ui32.Stepping == 10)\n            familyId = FAMILY_AL;\n        break;\n    case 10:\n        familyId = FAMILY_NV;\n        break;\n    case 11:\n        familyId = FAMILY_GFX11;\n        break;\n    case 12:\n        familyId = FAMILY_GFX12;\n\tbreak;\n    }\n\n    if (props->NumCPUCores && props->NumFComputeCores)\n        hsakmt_is_dgpu_dev = false;\n    else\n        hsakmt_is_dgpu_dev = true;\n\n    return familyId;\n}\n\nvoid GetHwQueueInfo(const HsaNodeProperties *props,\n                 unsigned int *p_num_cp_queues,\n                 unsigned int *p_num_sdma_engines,\n                 unsigned int *p_num_sdma_xgmi_engines,\n                 unsigned int *p_num_sdma_queues_per_engine) {\n    if (p_num_sdma_engines)\n        *p_num_sdma_engines = props->NumSdmaEngines;\n\n    if (p_num_sdma_xgmi_engines)\n        *p_num_sdma_xgmi_engines = props->NumSdmaXgmiEngines;\n\n    if (p_num_sdma_queues_per_engine)\n        *p_num_sdma_queues_per_engine = props->NumSdmaQueuesPerEngine;\n\n    if (p_num_cp_queues)\n        *p_num_cp_queues = props->NumCpQueues;\n}\n\nbool isTonga(const HsaNodeProperties *props) {\n    /* Tonga has some workarounds in the thunk that cause certain failures */\n    if (props->EngineId.ui32.Major == 8 && props->EngineId.ui32.Stepping == 2) {\n        return true;\n    }\n\n    return false;\n}\n\nconst uint32_t GetGfxVersion(const HsaNodeProperties *props) {\n    return ((props->EngineId.ui32.Major << 16) |\n            (props->EngineId.ui32.Minor <<  8) |\n            (props->EngineId.ui32.Stepping));\n}\n\nHSAuint64 GetSystemTickCountInMicroSec() {\n    struct timeval t;\n    gettimeofday(&t, 0);\n    return t.tv_sec * 1000000ULL + t.tv_usec;\n}\n\nconst HsaMemoryBuffer HsaMemoryBuffer::Null;\n\nHsaMemoryBuffer::HsaMemoryBuffer(HSAuint64 size, unsigned int node, bool zero, bool isLocal, bool isExec,\n                                 bool isScratch, bool isReadOnly, bool isUncached, bool NonPaged)\n    :m_Size(size),\n    m_pUser(NULL),\n    m_pBuf(NULL),\n    m_Local(isLocal),\n    m_Node(node) {\n    m_Flags.Value = 0;\n\n    HsaMemMapFlags mapFlags = {0};\n    bool map_specific_gpu = (node && !isScratch);\n\n    if (isScratch) {\n        m_Flags.ui32.Scratch = 1;\n        m_Flags.ui32.HostAccess = 1;\n    } else {\n        m_Flags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n\n        if (isLocal) {\n            m_Flags.ui32.HostAccess = 0;\n            m_Flags.ui32.NonPaged = 1;\n            m_Flags.ui32.CoarseGrain = 1;\n            EXPECT_EQ(isUncached, 0) << \"Uncached flag is relevant only for system or host memory\";\n        } else {\n            m_Flags.ui32.HostAccess = 1;\n            m_Flags.ui32.NonPaged = NonPaged ? 1 : 0;\n            m_Flags.ui32.CoarseGrain = 0;\n            m_Flags.ui32.NoNUMABind = 1;\n            m_Flags.ui32.Uncached = isUncached;\n        }\n\n        if (isExec)\n            m_Flags.ui32.ExecuteAccess = 1;\n    }\n    if (isReadOnly)\n        m_Flags.ui32.ReadOnly = 1;\n\n    if (zero)\n        EXPECT_EQ(m_Flags.ui32.HostAccess, 1);\n\n    EXPECT_SUCCESS(hsaKmtAllocMemory(m_Node, m_Size, m_Flags, &m_pBuf));\n    if (hsakmt_is_dgpu()) {\n        if (map_specific_gpu)\n            EXPECT_SUCCESS(hsaKmtMapMemoryToGPUNodes(m_pBuf, m_Size, NULL, mapFlags, 1, &m_Node));\n        else\n            EXPECT_SUCCESS(hsaKmtMapMemoryToGPU(m_pBuf, m_Size, NULL));\n        m_MappedNodes = 1 << m_Node;\n    }\n\n    if (zero && !isLocal)\n        Fill(0);\n}\n\nHsaMemoryBuffer::HsaMemoryBuffer(void *addr, HSAuint64 size):\n    m_Size(size),\n    m_pUser(addr),\n    m_pBuf(NULL),\n    m_Local(false),\n    m_Node(0) {\n    HSAuint64 gpuva = 0;\n    EXPECT_SUCCESS(hsaKmtRegisterMemory(m_pUser, m_Size));\n    EXPECT_SUCCESS(hsaKmtMapMemoryToGPU(m_pUser, m_Size, &gpuva));\n    m_pBuf = gpuva ? (void *)gpuva : m_pUser;\n}\n\nHsaMemoryBuffer::HsaMemoryBuffer()\n    :m_Size(0),\n    m_pBuf(NULL) {\n}\n\nvoid HsaMemoryBuffer::Fill(unsigned char value, HSAuint64 offset, HSAuint64 size) {\n    HSAuint32 uiValue;\n\n    EXPECT_EQ(m_Local, 0) << \"Local Memory. Call Fill(HSAuint32 value, BaseQueue& baseQueue)\";\n\n    size = size ? size : m_Size;\n    ASSERT_TRUE(size + offset <= m_Size) << \"Buffer Overflow\" << std::endl;\n\n    if (m_pUser != NULL)\n        memset(reinterpret_cast<char *>(m_pUser) + offset, value, size);\n    else if (m_pBuf != NULL)\n        memset(reinterpret_cast<char *>(m_pBuf) + offset, value, size);\n    else\n        ASSERT_TRUE(0) << \"Invalid HsaMemoryBuffer\";\n}\n\n/* Fill CPU accessible buffer with the value. */\nvoid HsaMemoryBuffer::Fill(HSAuint32 value, HSAuint64 offset, HSAuint64 size) {\n    HSAuint64 i;\n    HSAuint32 *ptr = NULL;\n\n    EXPECT_EQ(m_Local, 0) << \"Local Memory. Call Fill(HSAuint32 value, BaseQueue& baseQueue)\";\n    size = size ? size : m_Size;\n    EXPECT_EQ((size & (sizeof(HSAuint32) - 1)), 0) << \"Not word aligned. Call Fill(unsigned char)\";\n    ASSERT_TRUE(size + offset <= m_Size) << \"Buffer Overflow\" << std::endl;\n\n    if (m_pUser != NULL)\n        ptr = reinterpret_cast<HSAuint32 *>(reinterpret_cast<char *>(m_pUser) + offset);\n    else if (m_pBuf != NULL)\n        ptr = reinterpret_cast<HSAuint32 *>(reinterpret_cast<char *>(m_pBuf) + offset);\n\n    ASSERT_NOTNULL(ptr);\n\n    for (i = 0; i < size / sizeof(HSAuint32); i++)\n        ptr[i] = value;\n}\n\n/* Fill GPU only accessible Local memory with @value using SDMA Constant Fill Command */\nvoid HsaMemoryBuffer::Fill(HSAuint32 value, BaseQueue& baseQueue, HSAuint64 offset, HSAuint64 size) {\n    HsaEvent* event = NULL;\n\n    EXPECT_NE(m_Local, 0) << \"Not Local Memory. Call Fill(HSAuint32 value)\";\n\n    ASSERT_SUCCESS(CreateQueueTypeEvent(false, false, m_Node, &event));\n    ASSERT_EQ(baseQueue.GetQueueType(), HSA_QUEUE_SDMA) << \"Only SDMA queues supported\";\n\n    size = size ? size : m_Size;\n    ASSERT_TRUE(size + offset <= m_Size) << \"Buffer Overflow\" << std::endl;\n\n    baseQueue.PlacePacket(SDMAFillDataPacket(baseQueue.GetFamilyId(),\n                                (reinterpret_cast<void *>(this->As<char*>() + offset)), value, size));\n    baseQueue.PlacePacket(SDMAFencePacket(baseQueue.GetFamilyId(),\n                                reinterpret_cast<void*>(event->EventData.HWData2), event->EventId));\n    baseQueue.PlaceAndSubmitPacket(SDMATrapPacket(event->EventId));\n    EXPECT_SUCCESS(hsaKmtWaitOnEvent(event, g_TestTimeOut));\n\n    hsaKmtDestroyEvent(event);\n}\n\n/* Check if HsaMemoryBuffer[location] has the pattern specified.\n * Return TRUE if correct pattern else return FALSE\n * HsaMemoryBuffer has to be CPU accessible\n */\nbool HsaMemoryBuffer::IsPattern(HSAuint64 location, HSAuint32 pattern) {\n    HSAuint32 *ptr = NULL;\n\n    EXPECT_EQ(m_Local, 0) << \"Local Memory. Call IsPattern(..baseQueue& baseQueue)\";\n\n    if (location >= m_Size) /* Out of bounds */\n        return false;\n\n    if (m_pUser != NULL)\n        ptr = reinterpret_cast<HSAuint32 *>(m_pUser);\n    else if (m_pBuf != NULL)\n        ptr = reinterpret_cast<HSAuint32 *>(m_pBuf);\n    else\n        return false;\n\n    if (ptr)\n        return (ptr[location/sizeof(HSAuint32)] == pattern);\n\n    return false;\n}\n\n/* Check if HsaMemoryBuffer[location] has the pattern specified.\n * Return TRUE if correct pattern else return FALSE\n * HsaMemoryBuffer is supposed to be only GPU accessible\n * Use @baseQueue to copy the HsaMemoryBuffer[location] to stack and check the value\n */\n\nbool HsaMemoryBuffer::IsPattern(HSAuint64 location, HSAuint32 pattern, BaseQueue& baseQueue, volatile HSAuint32 *tmp) {\n    HsaEvent* event = NULL;\n    int ret;\n\n    EXPECT_NE(m_Local, 0) << \"Not Local Memory. Call IsPattern(HSAuint64 location, HSAuint32 pattern)\";\n    EXPECT_EQ(baseQueue.GetQueueType(), HSA_QUEUE_SDMA) << \"Only SDMA queues supported\";\n\n    if (location >= m_Size) /* Out of bounds */\n        return false;\n\n    ret = CreateQueueTypeEvent(false, false, m_Node, &event);\n    if (ret)\n        return false;\n\n    *tmp = ~pattern;\n    baseQueue.PlacePacket(SDMACopyDataPacket(baseQueue.GetFamilyId(), (void *)tmp,\n            reinterpret_cast<void *>(this->As<HSAuint64>() + location),\n            sizeof(HSAuint32)));\n    baseQueue.PlacePacket(SDMAFencePacket(baseQueue.GetFamilyId(), reinterpret_cast<void*>(event->EventData.HWData2),\n            event->EventId));\n    baseQueue.PlaceAndSubmitPacket(SDMATrapPacket(event->EventId));\n\n    ret = hsaKmtWaitOnEvent(event, g_TestTimeOut);\n    hsaKmtDestroyEvent(event);\n    if (ret)\n        return false;\n\n    return WaitOnValue(tmp, pattern);\n}\n\nunsigned int HsaMemoryBuffer::Size() {\n    return m_Size;\n}\n\nHsaMemFlags HsaMemoryBuffer::Flags() {\n    return m_Flags;\n}\n\nunsigned int HsaMemoryBuffer::Node() const {\n    return m_Node;\n}\n\nint HsaMemoryBuffer::MapMemToNodes(unsigned int *nodes, unsigned int nodes_num) {\n    HsaMemMapFlags mapFlags = {0};\n    int ret, bit;\n\n    ret = hsaKmtMapMemoryToGPUNodes(m_pBuf, m_Size, NULL, mapFlags, nodes_num, nodes);\n    if (ret != 0) {\n        return ret;\n    }\n\n    for (unsigned int i = 0; i < nodes_num; i++) {\n        bit = 1 << nodes[i];\n        m_MappedNodes |= bit;\n    }\n\n    return 0;\n}\n\nint HsaMemoryBuffer::UnmapMemToNodes(unsigned int *nodes, unsigned int nodes_num) {\n    int ret, bit;\n\n    ret = hsaKmtUnmapMemoryToGPU(m_pBuf);\n    if (ret)\n        return ret;\n\n    for (unsigned int i = 0; i < nodes_num; i++) {\n        bit = 1 << nodes[i];\n        m_MappedNodes &= ~bit;\n    }\n\n    return 0;\n}\n\nvoid HsaMemoryBuffer::UnmapAllNodes() {\n    unsigned int *Arr, size, i, j;\n    int bit;\n\n    size = 0;\n    for (i = 0; i < 8; i++) {\n        bit = 1 << i;\n        if (m_MappedNodes & bit)\n            size++;\n    }\n\n    Arr = (unsigned int *)malloc(sizeof(unsigned int) * size);\n    if (!Arr)\n        return;\n\n    for (i = 0, j =0; i < 8; i++) {\n        bit = 1 << i;\n        if (m_MappedNodes & bit)\n            Arr[j++] = i;\n    }\n\n    /*\n     * TODO: When thunk is updated, use hsaKmtRegisterToNodes. Then nodes will be used\n     */\n    hsaKmtUnmapMemoryToGPU(m_pBuf);\n\n    m_MappedNodes = 0;\n\n    free(Arr);\n}\n\nHsaMemoryBuffer::~HsaMemoryBuffer() {\n    if (m_pUser != NULL) {\n        hsaKmtUnmapMemoryToGPU(m_pUser);\n        hsaKmtDeregisterMemory(m_pUser);\n    } else if (m_pBuf != NULL) {\n        if (hsakmt_is_dgpu()) {\n            if (m_MappedNodes) {\n                hsaKmtUnmapMemoryToGPU(m_pBuf);\n            }\n        }\n        hsaKmtFreeMemory(m_pBuf, m_Size);\n    }\n    m_pBuf = NULL;\n}\n\nHsaInteropMemoryBuffer::HsaInteropMemoryBuffer(HSAuint64 device_handle, HSAuint64 buffer_handle,\n                                               HSAuint64 size, unsigned int node)\n    :m_Size(0),\n     m_pBuf(NULL),\n     m_graphic_handle(0),\n     m_Node(node) {\n    HSAuint64 flat_address;\n    EXPECT_SUCCESS(hsaKmtMapGraphicHandle(m_Node, device_handle, buffer_handle, 0, size, &flat_address));\n    m_pBuf = reinterpret_cast<void*>(flat_address);\n}\n\nHsaInteropMemoryBuffer::~HsaInteropMemoryBuffer() {\n    hsaKmtUnmapGraphicHandle(m_Node, (HSAuint64)m_pBuf, m_Size);\n}\n\n\nHsaNodeInfo::HsaNodeInfo() {\n}\n\n/* Init - Get and store information about all the HSA nodes from the Thunk Library.\n * @NumOfNodes - Number to system nodes returned by hsaKmtAcquireSystemProperties\n * @Return - false: if no node information is available\n */\nbool HsaNodeInfo::Init(int NumOfNodes) {\n    HsaNodeProperties *nodeProperties;\n    _HSAKMT_STATUS status;\n    bool ret = false;\n\n    for (int i = 0; i < NumOfNodes; i++) {\n        nodeProperties = new HsaNodeProperties();\n\n        status = hsaKmtGetNodeProperties(i, nodeProperties);\n        /* This is not a fatal test (not using assert), since even when it fails for one node\n         * we want to get information regarding others.\n         */\n        EXPECT_SUCCESS(status) << \"Node index: \" << i << \"hsaKmtGetNodeProperties returned status \" << status;\n\n        if (status == HSAKMT_STATUS_SUCCESS) {\n            m_HsaNodeProps.push_back(nodeProperties);\n            ret = true;  // Return true if atleast one information is available\n\n            if (nodeProperties->NumFComputeCores)\n                m_NodesWithGPU.push_back(i);\n            else\n                m_NodesWithoutGPU.push_back(i);\n        } else {\n            delete nodeProperties;\n        }\n    }\n\n    return ret;\n}\n\nvoid HsaNodeInfo::Delete() {\n    const HsaNodeProperties *nodeProperties;\n\n    for (unsigned int i = 0; i < m_HsaNodeProps.size(); i++)\n        delete m_HsaNodeProps.at(i);\n\n    m_HsaNodeProps.clear();\n    m_NodesWithGPU.clear();\n    m_NodesWithoutGPU.clear();\n}\n\nHsaNodeInfo::~HsaNodeInfo() {\n    Delete();\n}\n\nconst std::vector<int>& HsaNodeInfo::GetNodesWithGPU() const {\n    return m_NodesWithGPU;\n}\n\nconst HsaNodeProperties* HsaNodeInfo::GetNodeProperties(int NodeNum) const {\n    return m_HsaNodeProps.at(NodeNum);\n}\n\nconst int HsaNodeInfo::HsaGPUindexFromGpuNode(int gpuNodeId) const {\n    if (m_NodesWithGPU.size() == 0)\n        return -1;\n\n    for (unsigned int i = 0; i < m_NodesWithGPU.size(); i++) {\n        if (gpuNodeId == m_NodesWithGPU.at(i))\n            return i;\n    }\n\n    return -1;\n}\n\nconst HsaNodeProperties* HsaNodeInfo::HsaDefaultGPUNodeProperties() const {\n    int NodeNum = HsaDefaultGPUNode();\n    if (NodeNum < 0)\n        return NULL;\n    return GetNodeProperties(NodeNum);\n}\n\nconst int HsaNodeInfo::HsaDefaultGPUNode() const {\n    if (m_NodesWithGPU.size() == 0)\n        return -1;\n\n    if (g_TestNodeId >= 0) {\n        // Check if this is a valid Id, if so use this else use first available\n        for (unsigned int i = 0; i < m_NodesWithGPU.size(); i++) {\n            if (g_TestNodeId == m_NodesWithGPU.at(i))\n                return g_TestNodeId;\n        }\n    }\n\n    return m_NodesWithGPU.at(0);\n}\n\nvoid HsaNodeInfo::PrintNodeInfo() const {\n    const HsaNodeProperties *nodeProperties;\n\n    for (unsigned int i = 0; i < m_HsaNodeProps.size(); i++) {\n        nodeProperties = m_HsaNodeProps.at(i);\n\n        LOG() << \"***********************************\" << std::endl;\n        LOG() << \"Node \" << i << std::endl;\n        LOG() << \"NumCPUCores=\\t\" << nodeProperties->NumCPUCores << std::endl;\n        LOG() << \"NumFComputeCores=\\t\" << nodeProperties->NumFComputeCores << std::endl;\n        LOG() << \"NumMemoryBanks=\\t\" << nodeProperties->NumMemoryBanks << std::endl;\n        LOG() << \"VendorId=\\t\" << nodeProperties->VendorId << std::endl;\n        LOG() << \"DeviceId=\\t\" << nodeProperties->DeviceId << std::endl;\n        LOG() << \"***********************************\" << std::endl;\n    }\n\n    LOG() << \"Default GPU NODE \" << HsaDefaultGPUNode() << std::endl;\n}\n\nconst bool HsaNodeInfo::IsGPUNodeLargeBar(int node) const {\n    const HsaNodeProperties *pNodeProperties;\n\n    pNodeProperties = GetNodeProperties(node);\n    if (pNodeProperties) {\n        HsaMemoryProperties *memoryProperties =\n                new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n        EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(node,\n                       pNodeProperties->NumMemoryBanks, memoryProperties));\n        for (unsigned bank = 0; bank < pNodeProperties->NumMemoryBanks; bank++)\n            if (memoryProperties[bank].HeapType ==\n                                HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC) {\n                delete [] memoryProperties;\n                return true;\n            }\n        delete [] memoryProperties;\n    }\n\n    return false;\n}\n\nconst bool HsaNodeInfo::IsAppAPU(int node) const {\n    const HsaNodeProperties *pNodeProperties = GetNodeProperties(node);\n\n    /*  CPU with compute cores is small APU, not AppAPU */\n    if (pNodeProperties->NumCPUCores && pNodeProperties->NumFComputeCores)\n        return false;\n\n    HsaIoLinkProperties *IolinkProperties = new HsaIoLinkProperties[pNodeProperties->NumIOLinks];\n    if (hsaKmtGetNodeIoLinkProperties(node, pNodeProperties->NumIOLinks, IolinkProperties)) {\n        LOG() << \"Unable to get Node IO Link Information for node \" << node << std::endl;\n        delete [] IolinkProperties;\n        return false;\n    }\n\n    /* Checking GPU-to-CPU connection weight */\n    for (int linkId = 0; linkId < pNodeProperties->NumIOLinks; linkId++) {\n        HsaNodeProperties linkProps;\n\n        if (hsaKmtGetNodeProperties(IolinkProperties[linkId].NodeTo, &linkProps)) {\n            LOG() << \"Unable to get connected device's IO Link information\" << std::endl;\n            break;\n        }\n\n        /* If it's GPU-CPU link with connection weight KFD_CRAT_INTRA_SOCKET_WEIGHT 13 */\n        if (linkProps.NumCPUCores && IolinkProperties[linkId].Weight == 13) {\n            delete [] IolinkProperties;\n            return true;\n        }\n    }\n    delete [] IolinkProperties;\n    return false;\n}\n\nconst bool HsaNodeInfo::IsPeerAccessibleByNode(int peer, int node) const {\n    const HsaNodeProperties *pNodeProperties;\n\n    pNodeProperties = GetNodeProperties(node);\n    if (pNodeProperties) {\n        HsaIoLinkProperties p2pLinksProperties[pNodeProperties->NumIOLinks];\n        EXPECT_SUCCESS(hsaKmtGetNodeIoLinkProperties(node,\n\t\t\t\t\tpNodeProperties->NumIOLinks, p2pLinksProperties));\n\n        for (unsigned link = 0; link < pNodeProperties->NumIOLinks; link++)\n            if (p2pLinksProperties[link].NodeTo == peer)\n                return true;\n    }\n\n    return false;\n}\n\nconst int HsaNodeInfo::FindLargeBarGPUNode() const {\n    const std::vector<int> gpuNodes = GetNodesWithGPU();\n\n    for (unsigned i = 0; i < gpuNodes.size(); i++)\n        if (IsGPUNodeLargeBar(gpuNodes.at(i)))\n            return gpuNodes.at(i);\n\n    return -1;\n}\n\nconst bool HsaNodeInfo::AreGPUNodesXGMI(int node0, int node1) const {\n    const HsaNodeProperties *pNodeProperties0 = GetNodeProperties(node0);\n    const HsaNodeProperties *pNodeProperties1 = GetNodeProperties(node1);\n\n    if ((pNodeProperties0->HiveID != 0) && (pNodeProperties1->HiveID != 0) &&\n        (pNodeProperties0->HiveID == pNodeProperties1->HiveID))\n        return true;\n\n    return false;\n}\n\nint HsaNodeInfo::FindAccessiblePeers(std::vector<int> *peers,\n\t\t                             HSAuint32 node) const {\n    peers->push_back(node);\n\n    for (unsigned i = 0; i < m_NodesWithGPU.size(); i++) {\n        if (m_NodesWithGPU.at(i) == node)\n            continue;\n\n        if (IsPeerAccessibleByNode(m_NodesWithGPU.at(i), node))\n            peers->push_back(m_NodesWithGPU.at(i));\n    }\n    return peers->size();\n}\n\nconst bool HsaNodeInfo::IsNodeXGMItoCPU(int node) const {\n    const HsaNodeProperties *pNodeProperties;\n    bool ret = false;\n\n    pNodeProperties = GetNodeProperties(node);\n    if (pNodeProperties && pNodeProperties->NumIOLinks) {\n        HsaIoLinkProperties  *IolinkProperties =  new HsaIoLinkProperties[pNodeProperties->NumIOLinks];\n        EXPECT_SUCCESS(hsaKmtGetNodeIoLinkProperties(node, pNodeProperties->NumIOLinks, IolinkProperties));\n\n        for (int linkId = 0; linkId < pNodeProperties->NumIOLinks; linkId++) {\n            EXPECT_EQ(node, IolinkProperties[linkId].NodeFrom);\n            const HsaNodeProperties *pNodeProperties0 =\n                    GetNodeProperties(IolinkProperties[linkId].NodeTo);\n            if (pNodeProperties0->NumFComputeCores == 0 &&\n                    IolinkProperties[linkId].IoLinkType == HSA_IOLINK_TYPE_XGMI)\n                ret = true;\n        }\n        delete [] IolinkProperties;\n    }\n\n    return ret;\n}\n\nHSAKMT_STATUS RegisterSVMRange(HSAuint32 GPUNode, void *MemoryAddress,\n                               HSAuint64 SizeInBytes, HSAuint32 PrefetchNode,\n                               HSAuint32 SVMFlags) {\n    HSA_SVM_ATTRIBUTE *attrs;\n    HSAuint64 s_attr;\n    HSAuint32 nattr;\n    HSAKMT_STATUS r;\n\n    nattr = 4;\n    s_attr = sizeof(*attrs) * nattr;\n    attrs = (HSA_SVM_ATTRIBUTE *)alloca(s_attr);\n\n    attrs[0].type = HSA_SVM_ATTR_PREFETCH_LOC;\n    attrs[0].value = PrefetchNode;\n    attrs[1].type = HSA_SVM_ATTR_PREFERRED_LOC;\n    attrs[1].value = PrefetchNode;\n    attrs[2].type = HSA_SVM_ATTR_SET_FLAGS;\n    attrs[2].value = SVMFlags;\n    attrs[3].type = HSA_SVM_ATTR_ACCESS;\n    attrs[3].value = GPUNode;\n\n    r = hsaKmtSVMSetAttr(MemoryAddress, SizeInBytes, nattr, attrs);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS SVMRangeGetPrefetchNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                      HSAuint32 *PrefetchNode) {\n    HSA_SVM_ATTRIBUTE attr;\n    int r;\n\n    attr.type = HSA_SVM_ATTR_PREFETCH_LOC;\n    attr.value = 0;\n\n    r = hsaKmtSVMGetAttr(MemoryAddress, SizeInBytes, 1, &attr);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    *PrefetchNode = attr.value;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS SVMRangePrefetchToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                           HSAuint32 PrefetchNode) {\n    HSA_SVM_ATTRIBUTE attr;\n    int r;\n\n    attr.type = HSA_SVM_ATTR_PREFETCH_LOC;\n    attr.value = PrefetchNode;\n\n    r = hsaKmtSVMSetAttr(MemoryAddress, SizeInBytes, 1, &attr);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS SVMRangeMapToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                           HSAuint32 NodeID) {\n    HSA_SVM_ATTRIBUTE attr;\n    int r;\n\n    attr.type = HSA_SVM_ATTR_ACCESS;\n    attr.value = NodeID;\n\n    r = hsaKmtSVMSetAttr(MemoryAddress, SizeInBytes, 1, &attr);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS SVMRangeMapInPlaceToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                           HSAuint32 NodeID) {\n    HSA_SVM_ATTRIBUTE attr;\n    int r;\n\n    attr.type = HSA_SVM_ATTR_ACCESS_IN_PLACE;\n    attr.value = NodeID;\n\n    r = hsaKmtSVMSetAttr(MemoryAddress, SizeInBytes, 1, &attr);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHSAKMT_STATUS SVMRangSetGranularity(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                    HSAuint32 Granularity) {\n    HSA_SVM_ATTRIBUTE attr;\n    int r;\n\n    attr.type = HSA_SVM_ATTR_GRANULARITY;\n    attr.value = Granularity;\n\n    r = hsaKmtSVMSetAttr(MemoryAddress, SizeInBytes, 1, &attr);\n    if (r)\n        return HSAKMT_STATUS_ERROR;\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nHsaSVMRange::HsaSVMRange(HSAuint64 size, HSAuint32 GPUNode) :\n    HsaSVMRange(NULL, size, GPUNode, 0) {}\n\nHsaSVMRange::HsaSVMRange(HSAuint64 size) :\n    HsaSVMRange(NULL, size, 0, 0, true) {}\n\nHsaSVMRange::HsaSVMRange(HSAuint64 size, HSAuint32 GPUNode, HSAuint32 PrefetchNode) :\n    HsaSVMRange(NULL, size, GPUNode, PrefetchNode) {}\n\nHsaSVMRange::HsaSVMRange(void *addr, HSAuint64 size, HSAuint32 GPUNode, HSAuint32 PrefetchNode,\n                         bool noRegister, bool isLocal, bool isExec, bool isReadOnly):\n    m_Size(size),\n    m_pUser(addr),\n    m_Local(isLocal),\n    m_Node(PrefetchNode),\n    m_SelfAllocated(false) {\n    if (!m_pUser) {\n        m_pUser = mmap(0, m_Size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);\n        EXPECT_NE(MAP_FAILED, m_pUser);\n        m_SelfAllocated = true;\n    }\n\n    if (m_Local)\n        m_Flags = HSA_SVM_FLAG_HOST_ACCESS;\n    else\n        m_Flags = HSA_SVM_FLAG_HOST_ACCESS | HSA_SVM_FLAG_COHERENT;\n\n    if (isReadOnly)\n        m_Flags |= HSA_SVM_FLAG_GPU_RO;\n    if (isExec)\n        m_Flags |= HSA_SVM_FLAG_GPU_EXEC;\n\n    if (!noRegister)\n        EXPECT_SUCCESS(RegisterSVMRange(GPUNode, m_pUser, m_Size, PrefetchNode, m_Flags));\n}\n\nHsaSVMRange::~HsaSVMRange() {\n    if (m_pUser != NULL) {\n        if (m_SelfAllocated)\n            munmap(m_pUser, m_Size);\n        m_pUser = NULL;\n    }\n}\n\nvoid HsaSVMRange::Fill(HSAuint32 value, HSAuint64 offset, HSAuint64 size) {\n    HSAuint64 i;\n    HSAuint32 *ptr = NULL;\n\n    size = size ? size : m_Size;\n    EXPECT_EQ((size & (sizeof(HSAuint32) - 1)), 0) << \"Not word aligned. Call Fill(unsigned char)\";\n    ASSERT_TRUE(size + offset <= m_Size) << \"Buffer Overflow\" << std::endl;\n\n    if (m_pUser != NULL)\n        ptr = reinterpret_cast<HSAuint32 *>(reinterpret_cast<char *>(m_pUser) + offset);\n\n    ASSERT_NOTNULL(ptr);\n\n    for (i = 0; i < size / sizeof(HSAuint32); i++)\n        ptr[i] = value;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestUtil.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD__TEST__UTIL__H__\n#define __KFD__TEST__UTIL__H__\n\n#include <gtest/gtest.h>\n#include <vector>\n#include \"OSWrapper.hpp\"\n#include \"GoogleTestExtension.hpp\"\n#include \"hsakmt/hsakmt.h\"\n\nclass BaseQueue;\n#define ARRAY_SIZE(_x) (sizeof(_x)/sizeof(_x[0]))\n#define ALIGN_UP(x, align) (((uint64_t)(x) + (align) - 1) & ~(uint64_t)((align)-1))\n#define CounterToNanoSec(x) ((x) * 1000 / (hsakmt_is_dgpu() ? 27 : 100))\n\nvoid WaitUntilInput();\nHSAKMT_STATUS fscanf_dec(const char *file, uint32_t *num);\nuint64_t RoundToPowerOf2(uint64_t val);\n\n// @brief: waits until the value is written to the buffer or until time out if received through args\nbool WaitOnValue(const volatile unsigned int *buf, unsigned int value, unsigned int timeOut = g_TestTimeOut);\n\nvoid SplitU64(const HSAuint64 value, unsigned int& rLoPart, unsigned int& rHiPart);\n\nbool CheckEmuModeEnabled();\n\nbool GetHwCapabilityHWS();\n\nHSAKMT_STATUS CreateQueueTypeEvent(bool ManualReset, bool IsSignaled, unsigned int NodeId, HsaEvent** Event);\nHSAKMT_STATUS CreateHWExceptionEvent(bool ManualReset, bool IsSignaled, unsigned int NodeId, HsaEvent** Event);\n\nbool hsakmt_is_dgpu();\nbool isTonga(const HsaNodeProperties *props);\nbool hasPciAtomicsSupport(int node);\nunsigned int FamilyIdFromNode(const HsaNodeProperties *props);\nconst uint32_t GetGfxVersion(const HsaNodeProperties *props);\n\nvoid GetHwQueueInfo(const HsaNodeProperties *props,\n                 unsigned int *p_num_cp_queues,\n                 unsigned int *p_num_sdma_engines,\n                 unsigned int *p_num_sdma_xgmi_engines,\n                 unsigned int *p_num_sdma_queues_per_engine);\n\nHSAuint64 GetSystemTickCountInMicroSec();\n\nclass HsaMemoryBuffer {\n public:\n    static const HsaMemoryBuffer Null;\n\n public:\n    HsaMemoryBuffer(HSAuint64 size, unsigned int node, bool zero = true, bool isLocal = false,\n                    bool isExec = false, bool isScratch = false, bool isReadOnly = false, bool isUncached = false, bool NonPaged = false);\n    HsaMemoryBuffer(void *addr, HSAuint64 size);\n    template<typename RetType>\n    RetType As() {\n        return reinterpret_cast<RetType>(m_pBuf);\n    }\n\n    template<typename RetType>\n    const RetType As() const {\n        return reinterpret_cast<const RetType>(m_pBuf);\n    }\n\n    /* Fill @size bytes of buffer with @value starting from @offset\n     * If @size is 0, the whole buffer is filled with @value\n     */\n    void Fill(unsigned char value, HSAuint64 offset = 0, HSAuint64 size = 0);\n    void Fill(HSAuint32 value, HSAuint64 offset = 0, HSAuint64 size = 0);\n    void Fill(int value, HSAuint64 offset = 0, HSAuint64 size = 0) {\n              Fill((HSAuint32)value, offset, size);\n    }\n    void Fill(HSAuint32 value, BaseQueue& baseQueue,\n              HSAuint64 offset = 0, HSAuint64 size = 0);\n\n    bool IsPattern(HSAuint64 location, HSAuint32 pattern);\n    bool IsPattern(HSAuint64 location, HSAuint32 pattern,\n                   BaseQueue& baseQueue, volatile HSAuint32 *tmp);\n\n    unsigned int Size();\n    HsaMemFlags Flags();\n    unsigned int Node() const;\n\n    int MapMemToNodes(unsigned int *nodes, unsigned int nodes_num);\n    int UnmapMemToNodes(unsigned int *nodes, unsigned int nodes_num);\n\n    void *GetUserPtr() { return m_pUser; }\n    bool isLocal() { return m_Local; }\n    ~HsaMemoryBuffer();\n\n private:\n    // Disable copy\n    HsaMemoryBuffer(const HsaMemoryBuffer&);\n    const HsaMemoryBuffer& operator=(const HsaMemoryBuffer&);\n\n    void UnmapAllNodes();\n    HsaMemoryBuffer();\n\n private:\n    HsaMemFlags m_Flags;\n    HSAuint64 m_Size;\n    void* m_pUser;\n    void* m_pBuf;\n    bool m_Local;\n    unsigned int m_Node;\n    HSAuint64 m_MappedNodes;\n};\nHSAKMT_STATUS RegisterSVMRange(HSAuint32 GPUNode, void *MemoryAddress,\n                               HSAuint64 SizeInBytes, HSAuint32 PrefetchNode,\n                               HSAuint32 SVMFlags);\nHSAKMT_STATUS SVMRangeGetPrefetchNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                      HSAuint32 *PrefetchNode);\nHSAKMT_STATUS SVMRangePrefetchToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                     HSAuint32 PrefetchNode);\nHSAKMT_STATUS SVMRangeMapToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                     HSAuint32 NodeID);\nHSAKMT_STATUS SVMRangeMapInPlaceToNode(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                     HSAuint32 NodeID);\nHSAKMT_STATUS SVMRangSetGranularity(void *MemoryAddress, HSAuint64 SizeInBytes,\n                                    HSAuint32 Granularity);\n\nclass HsaSVMRange {\n public:\n    HsaSVMRange(HSAuint64 size, HSAuint32 GPUNode);\n    HsaSVMRange(HSAuint64 size, HSAuint32 GPUNode, HSAuint32 PreferredNode);\n    HsaSVMRange(HSAuint64 size);\n    HsaSVMRange(void *addr, HSAuint64 size, HSAuint32 GPUNode, HSAuint32 PreferredNode = 0,\n                bool noRegister = false, bool isLocal = false, bool isExec = false,\n                bool isReadOnly = false);\n    template<typename RetType>\n    RetType As() {\n        return reinterpret_cast<RetType>(m_pUser);\n    }\n\n    template<typename RetType>\n    const RetType As() const {\n        return reinterpret_cast<const RetType>(m_pUser);\n    }\n    ~HsaSVMRange();\n\n    void Fill(HSAuint32 value, HSAuint64 offset = 0, HSAuint64 size = 0);\n\n private:\n    HSAuint32 m_Flags;\n    HSAuint64 m_Size;\n    void* m_pUser;\n    bool m_SelfAllocated;\n    bool m_Local;\n    unsigned int m_Node;\n};\n\nclass HsaInteropMemoryBuffer {\n public:\n    HsaInteropMemoryBuffer(HSAuint64 device_handle, HSAuint64 buffer_handle, HSAuint64 size, unsigned int node);\n\n    template<typename RetType>\n    RetType As() {\n        return reinterpret_cast<RetType>(m_pBuf);\n    }\n\n    template<typename RetType>\n    const RetType As() const {\n        return reinterpret_cast<const RetType>(m_pBuf);\n    }\n\n    unsigned int Size();\n\n    ~HsaInteropMemoryBuffer();\n\n private:\n    // Disable copy\n    HsaInteropMemoryBuffer(const HsaInteropMemoryBuffer&);\n    const HsaInteropMemoryBuffer& operator=(const HsaInteropMemoryBuffer&);\n\n private:\n    HSAuint64 m_Size;\n    void* m_pBuf;\n    HSAuint64 m_graphic_handle;\n    unsigned int m_Node;\n};\n\n// @class HsaNodeInfo - Gather and store all HSA node information from Thunk.\nclass HsaNodeInfo {\n    // List containing HsaNodeProperties of all Nodes available\n    std::vector<HsaNodeProperties*> m_HsaNodeProps;\n\n    // List of HSA Nodes that contain a GPU. This includes both APU and dGPU\n    std::vector<int> m_NodesWithGPU;\n\n    // List of HSA Nodes with CPU only\n    std::vector<int> m_NodesWithoutGPU;\n\n public:\n    HsaNodeInfo();\n    ~HsaNodeInfo();\n\n    bool Init(int NumOfNodes);\n    void Delete();\n\n    /* This function should be deprecated soon. This for transistion purpose only\n     * Currently, KfdTest is designed to test only ONE node. This function acts\n     * as transition.\n     */\n    const HsaNodeProperties* HsaDefaultGPUNodeProperties() const;\n    const int HsaDefaultGPUNode() const;\n\n    /* TODO: Use the following two functions to support multi-GPU.\n     * const std::vector<int>& GpuNodes = GetNodesWithGPU()\n     * for (..GpuNodes.size()..) GetNodeProperties(GpuNodes.at(i))\n     */\n    const std::vector<int>& GetNodesWithGPU() const;\n\n    /* get gpu index from gpuNodeID */\n    const int HsaGPUindexFromGpuNode(int gpuNodeId) const;\n\n    // @param node index of the node we are looking at\n    // @param nodeProperties HsaNodeProperties returned\n    const HsaNodeProperties* GetNodeProperties(int NodeNum) const;\n\n    void PrintNodeInfo() const;\n    const bool IsGPUNodeLargeBar(int node) const;\n    const bool IsAppAPU(int node) const;\n    const bool IsPeerAccessibleByNode(int peer, int node) const;\n    // @brief Find the first available Large-BAR GPU node\n    // @return: Node ID if successful or -1\n    const int FindLargeBarGPUNode() const;\n    const bool AreGPUNodesXGMI(int node0, int node1) const;\n    int FindAccessiblePeers(std::vector<int> *peers,\n                                        HSAuint32 node) const;\n    /* @brief: to determine if the node is XGMI-linked to CPU\n     * @param: node index of the node we are looking at\n     * @return: bool true or false\n     */\n    const bool IsNodeXGMItoCPU(int node) const;\n};\n\n#endif  // __KFD__TEST__UTIL__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestUtilQueue.cpp",
    "content": "/*\n * Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <algorithm>\n#include <memory>\n#include <vector>\n#include <list>\n#include \"SDMAQueue.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"KFDTestUtil.hpp\"\n#include \"KFDTestUtilQueue.hpp\"\n#include \"KFDBaseComponentTest.hpp\"\n\n#define MB_PER_SEC(size, time) ((((size) * 1ULL) >> 20) * 1000ULL * 1000ULL * 1000ULL / (time))\n\nclass AsyncMPSQ;\nclass AsyncMPMQ;\n\ntypedef std::shared_ptr<AsyncMPSQ> sharedAsyncMPSQ;\ntypedef std::list<sharedAsyncMPSQ> AsyncMPSQList;\n\ntypedef std::shared_ptr<BasePacket> sharedPacket;\ntypedef std::list<sharedPacket> PacketList;\n\n/* AsyncMPSQ is short for Async multiple packet single queue.\n * It is allowed to place a list of packets to run on one queue of the specified GPU node.\n */\nclass AsyncMPSQ {\n    public:\n        AsyncMPSQ() : m_queue(NULL), m_buf(NULL), m_event(NULL) { /*do nothing*/}\n\n        virtual ~AsyncMPSQ(void) { Destroy(); }\n\n        /* It is the main function to deal with the packet and queue.*/\n        void PlacePacketOnNode(PacketList &packetList, int node, TSPattern tsp);\n\n        /* Run the packets placed on nodes and return immediately.*/\n        void Submit(void) { ASSERT_NE(m_queue, nullptr); m_queue->SubmitPacket(); }\n\n        /* Return only when all packets are consumed.\n         * If there is any packet issues some IO operations, wait these IO to complete too.\n         */\n        void Wait(void) {\n            ASSERT_NE(m_queue, nullptr);\n            m_queue->Wait4PacketConsumption(m_event, std::max((unsigned int)6000, g_TestTimeOut));\n        }\n\n        /* Report the time used between packet [begin, end) in Global Counter on success.\n         * Return 0 on failure.\n         */\n        HSAuint64 Report(int indexOfPacketBegin = 0, int indexOfPacketEnd = 0);\n        /* Report the timestamp around the packet.\n         * Return the time used on success.\n         * Return 0 on failure.\n         */\n        HSAuint64 Report(int indexOfPacket, HSAuint64 &tsBegin, HSAuint64 &tsEnd);\n\n    private:\n        BaseQueue *m_queue;\n        HSA_QUEUE_TYPE m_queueType;\n        HsaEvent *m_event;\n        /* m_ts points to m_buf's memory.*/\n        HsaMemoryBuffer *m_buf;\n        TimeStamp *m_ts;\n        unsigned m_ts_count;\n        TSPattern m_ts_pattern;\n\n        void AllocTimeStampBuf(int packetCount);\n        void Destroy();\n\n        /* It determines which queue will be created.*/\n        void InitQueueType(PACKETTYPE packetType) {\n            if (packetType == PACKETTYPE_SDMA)\n                m_queueType = HSA_QUEUE_SDMA;\n            else if (packetType == PACKETTYPE_PM4)\n                m_queueType = HSA_QUEUE_COMPUTE;\n            else\n                WARN() << \"Unsupported queue type!\" << std::endl;\n        }\n\n        unsigned int TimePacketSize(void) {\n            if (m_queueType == HSA_QUEUE_SDMA)\n                return SDMATimePacket(0).SizeInBytes();\n            else if (m_queueType == HSA_QUEUE_COMPUTE)\n                return PM4ReleaseMemoryPacket(m_queue->GetFamilyId(), 0, 0, 0, 0, 0).SizeInBytes();\n            return 0;\n        }\n\n        void CreateNewQueue(int node, unsigned int queueSize) {\n            if (m_queueType == HSA_QUEUE_SDMA)\n                m_queue = new SDMAQueue();\n            else if (m_queueType == HSA_QUEUE_COMPUTE)\n                m_queue = new PM4Queue();\n            else {\n                m_queue = NULL;\n                WARN() << \"Unsupported queue type!\" << std::endl;\n            }\n\n            if (m_queue)\n                ASSERT_SUCCESS(m_queue->Create(node, queueSize));\n        }\n\n        void PlaceTimestampPacket(void *addr) {\n            if (m_queueType == HSA_QUEUE_SDMA)\n                PlacePacket(SDMATimePacket(addr));\n            else if (m_queueType == HSA_QUEUE_COMPUTE)\n                PlacePacket(\n                        PM4ReleaseMemoryPacket(m_queue->GetFamilyId(), true, (HSAuint64)addr, 0, true, true));\n            else\n                WARN() << \"Unsupported queue type!\" << std::endl;\n        }\n\n        void PlacePacket(const BasePacket &packet) {\n            m_queue->PlacePacket(packet);\n        }\n};\n\nvoid AsyncMPSQ::Destroy(void) {\n    /* Delete queue first.*/\n    if (m_queue) {\n        delete m_queue;\n    }\n\n    if (m_buf)\n        delete m_buf;\n\n    if (m_event)\n        hsaKmtDestroyEvent(m_event);\n}\n\nvoid AsyncMPSQ::AllocTimeStampBuf(int packetCount) {\n    if (m_ts_pattern == NOTS) {\n        m_buf = NULL;\n        m_ts = NULL;\n        m_ts_count = 0;\n        return;\n    }\n\n    if (m_ts_pattern == ALLTS)\n        /* One extra timestamp packet.*/\n        m_ts_count = packetCount + 1;\n    else\n        m_ts_count = 2;\n\n    /* One more timestamp space to fit with alignment.*/\n    HSAuint64 size = ALIGN_UP(sizeof(TimeStamp) * (m_ts_count + 1), PAGE_SIZE);\n\n    m_buf = new HsaMemoryBuffer(size, 0, true, false);\n\n    TimeStamp *array = m_buf->As<TimeStamp*>();\n\n    /* SDMATimePacket need 32bytes aligned boundary dst address*/\n    m_ts = reinterpret_cast<TimeStamp *>ALIGN_UP(array, sizeof(TimeStamp));\n}\n\nvoid AsyncMPSQ::PlacePacketOnNode(PacketList &packets, int node, TSPattern tsp = ALLTS) {\n    int nPacket = packets.size();\n\n    if (nPacket == 0) {\n        WARN() << \"Empty packetList!\" << std::endl;\n        return;\n    }\n\n    /*1: All resources should be freed.*/\n    Destroy();\n\n    /*2: Must initialize queueType first.*/\n    InitQueueType(packets.front()->PacketType());\n    /*3: Initialize timestamp buf second with the pattern.*/\n    m_ts_pattern = tsp;\n    AllocTimeStampBuf(nPacket);\n    /*4: Create a event for Wait().*/\n    CreateQueueTypeEvent(false, false, node, &m_event);\n\n    int i = -1;\n    int packetSize = 0;\n    /* Calculate the space to put all timestamp packet.*/\n    int timePacketSize = TimePacketSize() * m_ts_count;\n    /* Another one page space to put fence, trap, etc*/\n    int extraPacketSize = PAGE_SIZE + timePacketSize;\n\n    /* To calculate the total packet size we will need to create the queue.\n     * As the packet in the vector might be different with each other,\n     * we have no other way to calculate the queuesize.\n     */\n    for (auto &packet : packets)\n        packetSize += packet->SizeInBytes();\n\n    /* queueSize need be power of 2.*/\n    const int queueSize = RoundToPowerOf2(packetSize + extraPacketSize);\n\n    /*5: Create a new queue on node for the packets.*/\n    CreateNewQueue(node, queueSize);\n\n    if (tsp != NOTS) {\n        i++;\n        PlaceTimestampPacket(m_ts + i);\n    }\n\n    for (auto &packet : packets) {\n        PlacePacket(*packet);\n        if (tsp == ALLTS) {\n            i++;\n            PlaceTimestampPacket(m_ts + i);\n        }\n    }\n\n    if (tsp == HEAD_TAIL) {\n        i++;\n        PlaceTimestampPacket(m_ts + i);\n    }\n\n    ASSERT_EQ(i + 1, m_ts_count);\n}\n\nHSAuint64 AsyncMPSQ::Report(int indexOfPacket, HSAuint64 &begin, HSAuint64 &end) {\n    /* Should not get any timestamp if NOTS is specified.*/\n    int error = 0;\n    EXPECT_NE(m_ts_pattern, NOTS)\n        << \" Error \" << ++error << \": No timestamp would be reported!\" << std::endl;\n\n    if (m_ts_pattern == HEAD_TAIL)\n        indexOfPacket = 0;\n\n    EXPECT_NE(m_ts, nullptr)\n        << \" Error \" << ++error << \": No timestamp buf!\" << std::endl;\n    /* m_ts_count is equal to packets count + 1, see PlacePacketOnNode().\n     * So the max index of a packet is m_ts_count - 2.\n     * make it unsigned to defend any minus values.\n     */\n    EXPECT_GE(m_ts_count - 2, (unsigned)indexOfPacket)\n        << \" Error \" << ++error << \": Index overflow!\" << std::endl;\n\n    if (error)\n        return 0;\n\n    begin = m_ts[indexOfPacket].timestamp;\n    end = m_ts[indexOfPacket + 1].timestamp;\n    return end - begin;\n}\n\nHSAuint64 AsyncMPSQ::Report(int indexOfPacketBegin, int indexOfPacketEnd) {\n    HSAuint64 ts[4];\n    int error = 0;\n\n    if (indexOfPacketEnd == 0)\n        indexOfPacketEnd = m_ts_count - 1;\n\n    EXPECT_GT((unsigned)indexOfPacketEnd, (unsigned)indexOfPacketBegin)\n        << \" Error \" << ++error << \": Index inverted!\" << std::endl;\n\n    if (error)\n        return 0;\n    /* Get the timestamps around the two packets.*/\n    if (!Report(indexOfPacketBegin, ts[0], ts[1]))\n        return 0;\n    /* [begin, end)*/\n    if (!Report(indexOfPacketEnd - 1, ts[2], ts[3]))\n        return 0;\n\n    EXPECT_GT(ts[3], ts[0])\n        << \" Waring: Might be wrong timestamp values!\" << std::endl;\n\n    return ts[3] - ts[0];\n}\n\n/* AsyncMPMQ is short for Async multiple packet multiple queue.\n * AsyncMPMQ manages a list of AsyncMPSQ.\n * So the packet can be running on multiple GPU nodes at same time.\n */\n\nclass AsyncMPMQ {\n    public:\n        AsyncMPMQ(void) { /* do nothing*/}\n\n        virtual ~AsyncMPMQ(void) { /*do nothing*/}\n\n        sharedAsyncMPSQ PlacePacketOnNode(PacketList &packetList, int node, TSPattern tsp = ALLTS) {\n            /* Create a sharedAsyncMPSQ object and push it into the AsyncMPSQList.\n             * As we might submit packet to same GPU nodes several times, AsyncMPSQ *\n             * is returned to stand for the AsyncMPSQ it is created with\n             */\n            sharedAsyncMPSQ mpsq_ptr(new AsyncMPSQ);\n            mpsq_ptr->PlacePacketOnNode(packetList, node, tsp);\n            m_mpsqList.push_back(mpsq_ptr);\n            return mpsq_ptr;\n        }\n\n        void Submit(void) {\n            for (auto &mpsq : m_mpsqList)\n                mpsq->Submit();\n        }\n\n        void Wait(void) {\n            for (auto &mpsq : m_mpsqList)\n                mpsq->Wait();\n        }\n\n    private:\n        AsyncMPSQList m_mpsqList;\n};\n\n\n/*\n * SDMA queue helper functions.\n */\n\nbool sort_SDMACopyParams(const SDMACopyParams &a1, const SDMACopyParams &a2) {\n    if (a1.node != a2.node)\n        return a1.node < a2.node;\n    return a1.group < a2.group;\n}\n\n/*\n * Copy from src to dst with corresponding sDMA.\n * It will try to merge copy on same node into one queue unless\n * caller forbid it by setting mashup to 0 and SDMACopyParams::group to different values.\n * On condition of mashup is 1, it will re-sort array into mergeable state.\n * All mergeable copy will be placed together.\n * On condition os mashup is 0, it keeps array in original order.\n * It will merge nearby copy if they have same group and node anyway.\n */\nvoid sdma_multicopy(std::vector<SDMACopyParams> &array, int mashup, TSPattern tsp) {\n    int i, packet_index = 0, queue_index = 0;\n    PacketList packetList;\n    AsyncMPMQ obj;\n    std::vector<sharedAsyncMPSQ> handle;\n\n    /* Sort it and then reduce the amount of queues if caller permits.\n     * We might change the order of array only here.\n     */\n    if (mashup)\n        std::sort(array.begin(), array.end(), sort_SDMACopyParams);\n\n    for (i = 0; i < array.size(); i++) {\n        sharedPacket packet(new\n                SDMACopyDataPacket(g_baseTest->GetFamilyIdFromNodeId(array[i].node), array[i].dst, array[i].src, array[i].size));\n        packetList.push_back(packet);\n\n        /* We put the real queue_id in local handle[] to reduce some assignment.*/\n        array[i].queue_id = queue_index;\n        /* Every queue has its packets with the index starts from 0.*/\n        array[i].packet_id = packet_index++;\n\n        /* If next copy is on same node and group, try to merge it into same queue.*/\n        if (i + 1 < array.size() && array[i].node == array[i + 1].node\n                                    && array[i].group == array[i + 1].group)\n                continue;\n\n        /* Now we have prepare one packetList, place packet into the queue on GPU node.*/\n        queue_index++;\n        handle.push_back(obj.PlacePacketOnNode(packetList, array[i].node, tsp));\n\n        /* Prepare a new(empty) packetList.*/\n        packetList.clear();\n\n        /* Prepare a new(zero) packet index for the packets in the new queue.*/\n        packet_index = 0;\n    }\n\n    obj.Submit();\n    obj.Wait();\n\n    if (tsp == NOTS)\n        return;\n\n    /* Get the time used by packet.*/\n    for (i = 0; i < array.size(); i++)\n        array[i].timeConsumption = (handle[array[i].queue_id])->Report(\n                array[i].packet_id, array[i].timeBegin, array[i].timeEnd);\n}\n\nstatic\nvoid sdma_multicopy_report(std::vector<SDMACopyParams> &array, HSAuint64 countPerGroup, std::stringstream *msg,\n                                HSAuint64 &timeConsumptionMin, HSAuint64 &timeConsumptionMax,\n                                HSAuint64 &totalSizeMin, HSAuint64 &totalSizeMax) {\n    HSAuint64 begin, end;\n    /* There can be different count of copies in different groups in the future.\n     * But assume they are same now.\n     */\n    HSAuint64 group = array.size() / countPerGroup;\n    HSAuint64 interval = -1;\n    timeConsumptionMin = -1;\n    timeConsumptionMax = 0;\n    totalSizeMin = totalSizeMax = 0;\n\n    /* Try to find out\n     * 1) The max/min timeConsumption of one copy in all copies.\n     * 2) The minimal average of timeConsumption of one packet in all copies.\n     * And one char # or - stands for one interval, aka minimal average.\n     * Say, one copy use 10ns with 10 copy packets. the other copy use 20ns\n     * with 10 copy packets. So the interval is 1ns, the timeConsumption is 20ns.\n     * So the ouput msg will be like\n     * ########## //copy1 10ns\n     * #---##----####### //copy2 20ns\n     */\n    for (int i = 0; i < group; i++) {\n        HSAuint64 begin, end, base = i * countPerGroup;\n\n        begin = array[base].timeBegin;\n        end = array[base + countPerGroup - 1].timeEnd;\n\n        if (begin == 0 && end == 0)\n            continue;\n\n        if (timeConsumptionMax < end - begin)\n            timeConsumptionMax = end - begin;\n\n        if (timeConsumptionMin > end - begin)\n            timeConsumptionMin = end - begin;\n    }\n\n    interval = timeConsumptionMin / countPerGroup;\n\n    /* Draw the timestamp event for each copy list.\n     * - means still doing copy.\n     * # means just finish one copy.\n     */\n    if (msg)\n        for (int i = 0; i < group; i++) {\n            HSAuint64 base = i * countPerGroup;\n            HSAuint64 last = array[base].timeBegin;\n            HSAuint64 timeConsumption;\n\n            *msg << \"[\" << array[base].node << \" : \" << array[base].group << \"] \";\n\n            for (int j = 0; j < countPerGroup; j++) {\n                timeConsumption = array[base + j].timeEnd - last;\n\n                while (timeConsumption >= interval) {\n                    timeConsumption -= interval;\n                    last += interval;\n\n                    if (timeConsumption >= interval)\n                        *msg << \"-\";\n                    else\n                        *msg << \"#\";\n                };\n            }\n\n            *msg << std::endl;\n        }\n\n    /* Try to find out\n     * 1) The size of all copies in all queues.\n     * 2) The size of the copies running within the same period in all queues.\n     * We assume all packets begin to run at same time.\n     */\n    for (int i = 0; i < group; i++) {\n        HSAuint64 base = i * countPerGroup;\n        HSAuint64 time = 0;\n\n        for (int j = 0; j < countPerGroup; j++) {\n            totalSizeMax += array[base + j].size;\n\n            if (time < timeConsumptionMin) {\n                time += array[base + j].timeConsumption;\n                totalSizeMin += array[base + j].size;\n            }\n        }\n    }\n}\n\n/*\n * Do copy with corresponding sDMA.\n */\nvoid\nsdma_multicopy(SDMACopyParams *copyArray, int arrayCount,\n                        HSAuint64 *minSpeed, HSAuint64 *maxSpeed, std::stringstream *msg) {\n    const HSAuint64 countPerGroup = minSpeed || maxSpeed ? 100 : 1;\n    std::vector<SDMACopyParams> array;\n    HSAuint64 totalSizeMin, totalSizeMax, timeConsumptionMin, timeConsumptionMax;\n\n    for (int i = 0; i < arrayCount; i++) {\n        /* Each copy has its own queue.*/\n        copyArray[i].group = i;\n        for (int j = 0; j < countPerGroup; j++)\n            array.push_back(copyArray[i]);\n    }\n\n    sdma_multicopy(array, 0, ALLTS);\n\n    sdma_multicopy_report(array, countPerGroup, msg,\n            timeConsumptionMin, timeConsumptionMax,\n            totalSizeMin, totalSizeMax);\n\n    if (minSpeed)\n        *minSpeed = MB_PER_SEC(totalSizeMin, CounterToNanoSec(timeConsumptionMin));\n\n    if (maxSpeed)\n        *maxSpeed = MB_PER_SEC(totalSizeMax, CounterToNanoSec(timeConsumptionMax));\n}\n\n/*\n * PM4 queue helper functions.\n */\n// TODO\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTestUtilQueue.hpp",
    "content": "/*\n * Copyright (C) 2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD__TEST__UTIL__QUEUE__H__\n#define __KFD__TEST__UTIL__QUEUE__H__\n\n#include \"hsakmt/hsakmt.h\"\n#include <vector>\n\ntypedef struct {\n        HSAuint64 timestamp;\n        HSAuint64 timeConsumption;\n        HSAuint64 timeBegin;\n        HSAuint64 timeEnd;\n} TimeStamp;\n\n/* We have three pattern to put timestamp packet,\n * NOTS: No timestamp packet insert.\n * ALLTS: Put timestamp packet around every packet. This is the default behavoir.\n *    It will look like |timestamp|packet|timestamp|...|packet|timestamp|\n * HEAD_TAIL: Put timestmap packet at head and tail to measure the overhead of a bunch of packet.\n *    It will look like |timestamp|packet|...|packet|timestamp|\n */\ntypedef enum {\n    NOTS = 0,\n    ALLTS = 1,\n    HEAD_TAIL = 2,\n} TSPattern;\n\ntypedef struct {\n    /* input values*/\n    HSAuint32 node;\n    void *src;\n    void *dst;\n    HSAuint64 size;\n    /* input value for internal use.*/\n    HSAuint64 group;\n    /* output value*/\n    HSAuint64 timeConsumption;\n    HSAuint64 timeBegin;\n    HSAuint64 timeEnd;\n    /* private: Output values for internal use.*/\n    HSAuint64 queue_id;\n    HSAuint64 packet_id;\n} SDMACopyParams;\n\nvoid sdma_multicopy(SDMACopyParams *array, int n,\n        HSAuint64 *speedSmall = 0, HSAuint64 *speedLarge = 0, std::stringstream *s = 0);\nvoid sdma_multicopy(std::vector<SDMACopyParams> &array, int mashup = 1, TSPattern tsp = ALLTS);\n#endif //__KFD__TEST__UTIL__QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTopologyTest.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDTopologyTest.hpp\"\n#include <vector>\n#include <string>\n\nconst HSAuint64 KFDTopologyTest::c_4Gigabyte = (1ull << 32) - 1;\nconst HSAuint64 KFDTopologyTest::c_40BitAddressSpace = (1ull << 40);\n\nTEST_F(KFDTopologyTest , BasicTest) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    const HsaNodeProperties *pNodeProperties;\n\n    // Goes over all nodes in the sytem properties and check the basic info received\n    for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n        if (pNodeProperties != NULL) {\n            HSAuint64 uniqueid;\n            if (!pNodeProperties->UniqueID)\n                uniqueid = 0;\n            else\n                uniqueid = pNodeProperties->UniqueID;\n            LOG() << \"UniqueID : \" << std::dec << uniqueid <<\n                     \" Node index: \" << node << std::endl;\n            // Checking for cpu core only if it's a cpu only node or if its KAVERI apu.\n            if (pNodeProperties->DeviceId == 0 || FamilyIdFromNode(pNodeProperties) == FAMILY_KV) {\n                EXPECT_GT(pNodeProperties->NumCPUCores, HSAuint32(0)) << \"Node index: \" << node\n                                                                      << \" No CPUs core are connected for node index\";\n            }\n\n            // If it's not a cpu only node, look for a gpu core\n            if (pNodeProperties->DeviceId != 0) {\n                EXPECT_GT(pNodeProperties->NumFComputeCores, HSAuint32(0)) << \"Node index: \" << node\n                                                                           << \"No GPUs core are connected.\";\n                // EngineId only applies to GPU, not CPU-only nodes\n                EXPECT_GT(pNodeProperties->EngineId.ui32.uCode, 0) << \"uCode version is 0\";\n                EXPECT_GE(pNodeProperties->EngineId.ui32.Major, 7) << \"Major Version is less than 7\";\n                EXPECT_LT(pNodeProperties->EngineId.ui32.Minor, 10) << \"Minor Version is greater than 9\";\n                EXPECT_GT(pNodeProperties->uCodeEngineVersions.uCodeSDMA, 0) << \"sDMA firmware version is 0\";\n\n                LOG() << \"VGPR Size is \" << pNodeProperties->VGPRSizePerCU <<\n                         \"  SGPR Size is \" << pNodeProperties->SGPRSizePerCU << std::endl;\n            }\n            EXPECT_GT(pNodeProperties->NumMemoryBanks, HSAuint32(0)) << \"Node index: \" << node << \"No MemoryBanks.\";\n            if (pNodeProperties->NumCaches ==0)\n                // SWDEV-420270\n                // For \"Intel Meteor lake Mobile\", the cache info is not in sysfs,\n                // That means /sys/devices/system/node/node%d/%s/cache is not exist.\n                LOG() <<  \"Node index: \" << node << \"  No Caches or not available to read .\" << std::endl;\n        }\n    }\n\n    TEST_END\n}\n\n// This test verifies failure status on hsaKmtGetNodeProperties with invalid params\nTEST_F(KFDTopologyTest, GetNodePropertiesInvalidParams) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    EXPECT_EQ(HSAKMT_STATUS_INVALID_PARAMETER, hsaKmtGetNodeProperties(0, NULL));\n\n    TEST_END\n}\n\n// This test verifies failure status on hsaKmtGetNodeProperties with invalid params\nTEST_F(KFDTopologyTest, GetNodePropertiesInvalidNodeNum) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    HsaNodeProperties nodeProperties;\n    memset(&nodeProperties, 0, sizeof(nodeProperties));\n    EXPECT_EQ(HSAKMT_STATUS_INVALID_NODE_UNIT, hsaKmtGetNodeProperties(m_SystemProperties.NumNodes, &nodeProperties));\n\n    TEST_END\n}\n\n// Test that we can get memory properties successfully per node\n// TODO: Check validity of values returned\nTEST_F(KFDTopologyTest, GetNodeMemoryProperties) {\n    TEST_START(TESTPROFILE_RUNALL)\n    const HsaNodeProperties *pNodeProperties;\n\n    for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n\n        if (pNodeProperties != NULL) {\n            HsaMemoryProperties *memoryProperties = new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n            EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(node, pNodeProperties->NumMemoryBanks, memoryProperties));\n            delete [] memoryProperties;\n        }\n    }\n\n    TEST_END\n}\n\n\n// Test that the GPU local memory aperture is valid.\nTEST_F(KFDTopologyTest, GpuvmApertureValidate) {\n    TEST_REQUIRE_NO_ENV_CAPABILITIES(ENVCAPS_32BITLINUX);\n\n    TEST_START(TESTPROFILE_RUNALL)\n    const HsaNodeProperties *pNodeProperties;\n    const std::vector<int> GpuNodes = m_NodeInfo.GetNodesWithGPU();\n\n    for (unsigned i = 0; i < GpuNodes.size(); i++) {\n        pNodeProperties = m_NodeInfo.GetNodeProperties(GpuNodes.at(i));\n        if (pNodeProperties != NULL) {\n            if (!hsakmt_is_dgpu() && !(FamilyIdFromNode(pNodeProperties) == FAMILY_KV)) {\n                LOG() << \"Skipping test: GPUVM framebuffer heap not exposed on APU except Kaveri.\" << std::endl;\n                return;\n            }\n            HsaMemoryProperties *memoryProperties =  new HsaMemoryProperties[pNodeProperties->NumMemoryBanks];\n            EXPECT_SUCCESS(hsaKmtGetNodeMemoryProperties(GpuNodes.at(i), pNodeProperties->NumMemoryBanks,\n                                                         memoryProperties));\n            bool GpuVMHeapFound = false;\n            for (unsigned int bank = 0 ; bank  < pNodeProperties->NumMemoryBanks ; bank++) {\n                // Check for either private (small-bar/APU) or public (large-bar)\n                if ((HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE == memoryProperties[bank].HeapType) ||\n                     (HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC == memoryProperties[bank].HeapType))\n                    GpuVMHeapFound = true;\n            }\n            EXPECT_TRUE(GpuVMHeapFound);\n            delete [] memoryProperties;\n        }\n    }\n\n    TEST_END\n}\n\n// Test that we can get cache property successfully per node\n// TODO: Check validity of values returned\nTEST_F(KFDTopologyTest, GetNodeCacheProperties) {\n    TEST_START(TESTPROFILE_RUNALL)\n\n    const HsaNodeProperties *pNodeProperties;\n\n    for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n        if (pNodeProperties != NULL) {\n            HsaCacheProperties *cacheProperties = new HsaCacheProperties[pNodeProperties->NumCaches];\n            EXPECT_SUCCESS(hsaKmtGetNodeCacheProperties(node, pNodeProperties->CComputeIdLo,\n                           pNodeProperties->NumCaches, cacheProperties));\n            if (pNodeProperties->NumCPUCores > 0) {  // this is a CPU node\n                LOG() << \"CPU Node \" << std::dec << node << \": \" << pNodeProperties->NumCaches << \" caches\"\n                      << std::endl;\n                for (unsigned n = 0; n < pNodeProperties->NumCaches; n++) {\n                    LOG()<< n << \" - Level \" << cacheProperties[n].CacheLevel <<\n                    \" Type \" << cacheProperties[n].CacheType.Value <<\n                    \" Size \" << (cacheProperties[n].CacheSize >> 10) << \"K \" <<\n                    \" Associativity \" << cacheProperties[n].CacheAssociativity <<\n                    \" LineSize \" << cacheProperties[n].CacheLineSize <<\n                    \" LinesPerTag \" << cacheProperties[n].CacheLinesPerTag << std::endl;\n                    char string[1024] = \"\";\n                    char sibling[5] = \"\";\n                    for (unsigned i = 0; i < 256; i++) {\n                        if (cacheProperties[n].SiblingMap[i]) {\n                            sprintf(sibling, \"%d,\", i);\n                            strcat(string, sibling);\n                        }\n                    }\n                    LOG() << \"     ProcIdLow \" << cacheProperties[n].ProcessorIdLow <<\n                    \" SiblingMap \" << string << std::endl;\n                }\n            } else {  // this is a GPU node\n                LOG() << \"GPU Node \" << std::dec << node << \": \" << pNodeProperties->NumCaches << \" caches\"\n                      << std::endl;\n                for (unsigned n = 0; n < pNodeProperties->NumCaches; n++) {\n                    LOG()<< n << \" - Level \" << cacheProperties[n].CacheLevel <<\n                    \" Type \" << cacheProperties[n].CacheType.Value <<\n                    \" Size \" << cacheProperties[n].CacheSize << \"K \" <<\n                    \" Associativity \" << cacheProperties[n].CacheAssociativity <<\n                    \" LineSize \" << cacheProperties[n].CacheLineSize <<\n                    \" LinesPerTag \" << cacheProperties[n].CacheLinesPerTag << std::endl;\n                    char string[1024] = \"\";\n                    char sibling[5] = \"\";\n                    for (unsigned i = 0; i < 256; i++) {\n                        if (cacheProperties[n].SiblingMap[i]) {\n                            snprintf(sibling, 5, \"%d,\", i);\n                            strcat(string, sibling);\n                        }\n                    }\n                    LOG() << \"     ProcIdLow \" << cacheProperties[n].ProcessorIdLow <<\n                    \" SiblingMap \" << string << std::endl;\n                }\n            }\n            delete [] cacheProperties;\n        }\n    }\n\n    TEST_END\n}\n\n// Test that we can get NodeIoLink property successfully per node\n// TODO: Check validity of values returned\n// GetNodeIoLinkProperties is disabled for now, test fails due to bug in BIOS\nTEST_F(KFDTopologyTest, GetNodeIoLinkProperties) {\n    TEST_START(TESTPROFILE_RUNALL)\n    const HsaNodeProperties *pNodeProperties;\n    int linkId;\n    char c;\n\n    LOG() << \"Topology. [FromNode]--(Weight)-->[ToNode]\" << std::endl;\n\n    for (unsigned node = 0; node < m_SystemProperties.NumNodes; node++) {\n        pNodeProperties = m_NodeInfo.GetNodeProperties(node);\n\n        if (pNodeProperties != NULL) {\n            HsaIoLinkProperties  *IolinkProperties =  new HsaIoLinkProperties[pNodeProperties->NumIOLinks];\n            EXPECT_SUCCESS(hsaKmtGetNodeIoLinkProperties(node, pNodeProperties->NumIOLinks, IolinkProperties));\n            if (pNodeProperties->NumIOLinks == 0) {\n                // No io_links. Just print the node\n                LOG() << \"[\" << node << \"]\" << std::endl;\n                continue;\n            }\n\n            for (linkId = 0; linkId < pNodeProperties->NumIOLinks; linkId++) {\n                if (linkId == 0) {\n                    // First io_link. Print Parent Node and io_link Node\n                    EXPECT_EQ(node, IolinkProperties[linkId].NodeFrom);\n                    LOG() << \"[\" << IolinkProperties[linkId].NodeFrom << \"]--(\" <<\n                        IolinkProperties[linkId].Weight << \")-->\" <<\n                        \"[\" << IolinkProperties[linkId].NodeTo << \"]\" << std::endl;\n                    continue;\n                }\n                if (linkId == (pNodeProperties->NumIOLinks - 1))\n                    c = '`';  // last node\n                else\n                    c = '|';\n                LOG() << \"  \" << c << \"--(\" << IolinkProperties[linkId].Weight << \")-->\" <<\n                    \"[\" << IolinkProperties[linkId].NodeTo << \"]\" << std::endl;\n            }\n            LOG() << std::endl;\n            delete [] IolinkProperties;\n        }\n    }\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/KFDTopologyTest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"KFDBaseComponentTest.hpp\"\n\n#ifndef __KFD_TOPOLOGY_TEST__H__\n#define __KFD_TOPOLOGY_TEST__H__\n\n/* @class KFDTopologyTest\n * This class has no additional features to KFDBaseComponentTest\n * The separation was made so we are able to group all topology tests together\n */\nclass KFDTopologyTest : public KFDBaseComponentTest {\n public:\n    KFDTopologyTest(void) {}\n    ~KFDTopologyTest(void) {}\n    static const HSAuint64 c_4Gigabyte;\n    static const HSAuint64 c_40BitAddressSpace;\n};\n\n#endif  // __KFD_TOPOLOGY_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/LinuxOSWrapper.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef WIN32\n\n#include \"OSWrapper.hpp\"\n\n#include <gtest/gtest.h>\n#include <unistd.h>\n#include <errno.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <getopt.h>\n#include <drm.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/ioctl.h>\n\nstatic int protection_flags[8] = {PROT_NONE, PROT_READ, PROT_WRITE, PROT_READ | PROT_WRITE,\n                                  PROT_EXEC, PROT_EXEC | PROT_READ, PROT_EXEC | PROT_WRITE,\n                                  PROT_EXEC | PROT_WRITE | PROT_READ};\n\nvoid SetConsoleTextColor(TEXTCOLOR color) {\n    // TODO: Complete\n}\n\nvoid Delay(int delayCount) {\n    // usleep accepts time in microseconds\n    usleep(delayCount * 1000);\n}\n\nvoid *VirtualAllocMemory(void *address, unsigned int size, int memProtection ) {\n    void *ptr;\n\n    ptr = mmap(address, size, protection_flags[memProtection], MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n\n    if (ptr == MAP_FAILED)\n        ptr = NULL;\n    return ptr;\n}\n\nbool VirtualFreeMemory(void *address, unsigned int size) {\n    if (munmap(address, size) == 0)\n        return true;\n    else\n        return false;\n}\n\nHSAuint64 GetLastErrorNo() {\n    return errno;\n}\n\nbool MultiProcessTest(const char *testToRun, int numOfProcesses, int runsPerProcess) {\n    // TODO: Implement\n    return false;\n}\n\nbool SuspendAndWakeUp() {\n    printf(\"Please press any key after the system suspends....\\n\");\n\n    // Use \"sudo apt install pm-utils\" to install the \"pm-suspend\"\n    int ret = system(\"sudo pm-suspend\");\n\n    if (ret == -1) {\n        printf(\"The system linux command could not be run!\\n\");\n        return false;\n    } else {\n        if (WEXITSTATUS(ret)) {\n            printf(\"Use 'sudo apt install pm-utils' to install 'pm-suspend' on Ubuntu\\n\");\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool ReadDriverConfigValue(CONFIG_VALUE config, unsigned int& rValue) {\n    return false;\n}\n\nvoid ComandLineArgumentsUsage() {\n    printf(\"Invalid option value\\n\");\n    printf(\"\\t--hws arg\\t - Force HW capability\\n\");\n    printf(\"\\t--profile arg\\t - Test profile\\n\");\n    printf(\"\\t--child arg\\t - Child Process\\n\");\n    printf(\"\\t--timeout arg\\t - Time Out\\n\");\n    printf(\"\\t--dst_node\\t - For testing multiple nodes\");\n    printf(\"\\t--sleep_time\\t - For testing CRIU, etc\");\n}\n\nbool GetCommandLineArguments(int argc, char **argv, CommandLineArguments& rArgs) {\n    int option_index = 0;\n\n    /* Make getop silent */\n    opterr = 0;\n    static struct option long_options[] = {\n        { \"hws\", required_argument, 0, 0 },\n        { \"profile\", required_argument, 0, 0},\n        { \"child\", required_argument, 0, 0},\n        { \"timeout\", required_argument, 0, 0},\n        { \"node\", required_argument, 0, 0 },\n        { \"dst_node\", required_argument, 0, 0 },\n        { \"sleep_time\", required_argument, 0, 0 },\n        { 0, 0, 0, 0 }\n    };\n\n    rArgs.HwsEnabled = HWCAP__DEFAULT;\n    rArgs.TestProfile = TESTPROFILE_RUNALL;\n    rArgs.ChildProcess = false;\n    rArgs.TimeOut = 0;\n    rArgs.NodeId = -1;\n    rArgs.DstNodeId = -1;\n    rArgs.SleepTime = 0;\n\n    while (true) {\n        int c = getopt_long(argc, argv, \"\", long_options, &option_index);\n\n        /* Detect the end of the options. */\n        if (c != 0)\n            break;\n\n        /* If this option sets a flag, do nothing else. */\n        if (long_options[option_index].flag != 0)\n            continue;\n\n        if (optarg == NULL) {\n            ComandLineArgumentsUsage();\n            return false;\n        }\n\n        switch (option_index) {\n        /* HWS case */\n        case 0:\n            if (!strcmp(optarg, \"disable\")) {\n                rArgs.HwsEnabled = HWCAP__FORCE_DISABLED;\n            } else if (!strcmp(optarg, \"enable\")) {\n                rArgs.HwsEnabled = HWCAP__FORCE_ENABLED;\n            } else {\n                ComandLineArgumentsUsage();\n                return false;\n            }\n            break;\n        /* TEST PROFILE */\n        case 1:\n            if (!strcmp(optarg, \"dev\")) {\n                rArgs.TestProfile = TESTPROFILE_DEV;\n            } else if (!strcmp(optarg, \"promo\")) {\n                rArgs.TestProfile = TESTPROFILE_PROMO;\n            } else if (!strcmp(optarg, \"all\")) {\n                rArgs.TestProfile = TESTPROFILE_RUNALL;\n            } else {\n                ComandLineArgumentsUsage();\n                return false;\n            }\n            break;\n\n        case 2:\n            rArgs.ChildProcess = true;\n            break;\n\n        case 3:\n            {\n                int timeOut = atoi(optarg);\n                if (timeOut > 0)\n                    rArgs.TimeOut = timeOut;\n            }\n            break;\n        case 4:\n            {\n                int nodeId = atoi(optarg);\n                if (nodeId >= 0)\n                    rArgs.NodeId = nodeId;\n            }\n            break;\n        case 5:\n            {\n                int dstNodeId = atoi(optarg);\n                if (dstNodeId >= 0)\n                    rArgs.DstNodeId = dstNodeId;\n            }\n            break;\n        /* Sleep time - used in testing CRIU */\n        case 6:\n            {\n                int sleepTime = atoi(optarg);\n                if (sleepTime >= 0)\n                    rArgs.SleepTime = sleepTime;\n            }\n            break;\n        }\n    }\n\n    return true;\n}\n\nvoid HWMemoryBarrier() {\n    __sync_synchronize();\n}\n\nbool StartThread(unsigned int (*thread_func)(void*), void* param, uint64_t& thread_id) {\n    pthread_t id;\n    bool ret = false;\n    typedef void* (*pthread_func_t)(void*);\n\n    if (!pthread_create(&id, NULL, (pthread_func_t)thread_func, param)) {\n        thread_id = (pthread_t)id;\n        ret = true;\n    }\n    return ret;\n}\n\nbool WaitForThread(uint64_t threadId) {\n    return 0 == pthread_join((pthread_t)threadId, NULL);\n}\n\nHSAint64 AtomicInc(volatile HSAint64* pValue) {\n    return __sync_add_and_fetch(pValue, 1);\n}\n\nvoid MemoryBarrier() {\n       __sync_synchronize();\n}\n\n#endif  // !WIN32\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/OSWrapper.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n#include <sys/user.h>\n#include <string>\n\n#include \"KFDTestFlags.hpp\"\n#include \"hsakmt/hsakmt.h\"\n\n#ifndef __OS__WRAPPER__H__\n#define __OS__WRAPPER__H__\n\n#ifndef PAGE_SIZE\n#define PAGE_SIZE   (1<<12)\n#endif\n#ifndef PAGE_SHIFT\n#define PAGE_SHIFT  (12)\n#endif\n\nenum TEXTCOLOR {\n    TEXTCOLOR_WHITE,\n    TEXTCOLOR_GREEN,\n    TEXTCOLOR_YELLOW\n};\n\nenum OS_PRIVILEGE {\n    OS_DRIVER_OPERATIONS,\n    OS_SUSPEND\n};\n\nenum CONFIG_VALUE {\n    CONFIG_HWS\n};\n\nenum HwCapabilityStatus {\n    HWCAP__FORCE_DISABLED,\n    HWCAP__DEFAULT,\n    HWCAP__FORCE_ENABLED\n};\n\nstruct CommandLineArguments {\n    HwCapabilityStatus HwsEnabled;\n    TESTPROFILE TestProfile;\n    bool ChildProcess;\n    unsigned int TimeOut;\n    int NodeId;\n    int DstNodeId;\n    /* Time in units of seconds */\n    unsigned int SleepTime;\n};\n\n// It is either MEM_NONE or the bitwise OR of one or more of the following flags\n#define MEM_NONE 0x00\n#define MEM_READ 0x01\n#define MEM_WRITE 0x02\n#define MEM_EXECUTE 0x4\n\n// @brief Change console text color\nvoid SetConsoleTextColor(TEXTCOLOR color);\n// @params delayCount : delay time in milliseconds\nvoid Delay(int delayCount);\n// @brief Replacement for windows VirtualAlloc func\nvoid *VirtualAllocMemory(void *address, unsigned int size, int memProtection = MEM_READ | MEM_WRITE);\n// @brief Replacement for windows FreeVirtual func\nbool VirtualFreeMemory(void *address, unsigned int size);\n// @brief Retrieve the last error number\nHSAuint64 GetLastErrorNo();\n\nHSAint64 AtomicInc(volatile HSAint64* pValue);\n\nvoid MemoryBarrier();\n\n/* @brief: Runs the selected test case number of times required, each in a separate process\n * @params testToRun : Can be a specific test testcase like TestCase.TestName or if you want\n *                     to run all tests in a test case: TestCase.* and so on\n * @params numOfProcesses : How many processes to run in parallel\n * @params runsPerProcess : How many iteration a test should do per process, must be a positive number\n */\nbool MultiProcessTest(const char *testToRun, int numOfProcesses, int runsPerProcess = 1);\n\n/* Put the system to S3/S4 power state and bring it back to S0.\n * @return 'true' on success, 'false' on failure.\n */\nbool SuspendAndWakeUp();\n\nbool ReadDriverConfigValue(CONFIG_VALUE config, unsigned int& rValue);\n\nbool GetCommandLineArguments(int argc, char **argv, CommandLineArguments& rArgs);\n\nvoid HWMemoryBarrier();\nbool StartThread(unsigned int (*)(void*), void* pParam, uint64_t& threadId);\nbool WaitForThread(uint64_t threadId);\n\n#endif  // __OS__WRAPPER__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/PM4Packet.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <stdint.h>\n#include <stddef.h>\n#include <string.h>\n#include \"PM4Packet.hpp\"\n#include \"hsakmt/hsakmttypes.h\"\n#include \"KFDBaseComponentTest.hpp\"\n\n#include \"asic_reg/gfx_7_2_enum.h\"\n\nunsigned int PM4Packet::CalcCountValue() const {\n    return (SizeInDWords() - (sizeof(PM4_TYPE_3_HEADER) / sizeof(uint32_t)) - 1);\n}\n\nvoid PM4Packet::InitPM4Header(PM4_TYPE_3_HEADER &header, it_opcode_type opCode) {\n    header.count                    = CalcCountValue() + m_HeaderCountOffset;\n    header.opcode                 = opCode;\n    header.type                      = PM4_TYPE_3;\n    header.shaderType          = 1;  // compute\n    header.predicate              = 0;\n    header.reserved1             = 0;\n}\n\nunsigned int PM4WriteDataPacket::SizeInBytes() const {\n    return (offsetof(PM4WRITE_DATA_CI, data) + m_ndw*sizeof(uint32_t));\n}\n\nvoid PM4WriteDataPacket::InitPacket(unsigned int *destBuf, void *data) {\n    m_pPacketData = reinterpret_cast<PM4WRITE_DATA_CI *>(AllocPacket());\n\n    InitPM4Header(m_pPacketData->header, IT_WRITE_DATA);\n\n    m_pPacketData->bitfields2.dst_sel      = dst_sel_mec_write_data_MEMORY_5;  // memory-async\n    m_pPacketData->bitfields2.addr_incr    = addr_incr_mec_write_data_INCREMENT_ADDR_0;  // increment addr\n    m_pPacketData->bitfields2.wr_confirm   = wr_confirm_mec_write_data_WAIT_FOR_CONFIRMATION_1;\n    m_pPacketData->bitfields2.atc          = hsakmt_is_dgpu() ?\n        atc_write_data_NOT_USE_ATC_0 : atc_write_data_USE_ATC_1;\n    m_pPacketData->bitfields2.cache_policy = cache_policy_mec_write_data_BYPASS_2;\n\n    m_pPacketData->dst_addr_lo    = static_cast<uint32_t>(\n        reinterpret_cast<uint64_t>(destBuf));  // byte addr\n    m_pPacketData->dst_address_hi = static_cast<uint32_t>(\n        reinterpret_cast<uint64_t>(destBuf) >> 32);\n\n    memcpy(m_pPacketData->data, data, m_ndw * sizeof(uint32_t));\n}\n\nPM4ReleaseMemoryPacket::PM4ReleaseMemoryPacket(unsigned int familyId, bool isPolling,\n                    uint64_t address, uint64_t data, bool is64bit, bool isTimeStamp,\n                    int headerCountOffset):m_pPacketData(NULL) {\n    m_FamilyId = familyId;\n    m_HeaderCountOffset = headerCountOffset;\n    if (familyId < FAMILY_AI)\n        InitPacketCI(isPolling, address, data, is64bit, isTimeStamp);\n    else if (familyId < FAMILY_NV)\n        InitPacketAI(isPolling, address, data, is64bit, isTimeStamp);\n    else\n        InitPacketNV(isPolling, address, data, is64bit, isTimeStamp);\n}\n\nvoid PM4ReleaseMemoryPacket::InitPacketCI(bool isPolling, uint64_t address,\n                                    uint64_t data, bool is64bit, bool isTimeStamp) {\n    PM4_RELEASE_MEM_CI *pkt;\n\n    m_packetSize = sizeof(PM4_RELEASE_MEM_CI);\n    pkt = reinterpret_cast<PM4_RELEASE_MEM_CI *>(AllocPacket());\n    m_pPacketData = pkt;\n\n    InitPM4Header(pkt->header, IT_RELEASE_MEM);\n\n    pkt->bitfields2.event_type       = 0x14;\n    pkt->bitfields2.event_index      = event_index_mec_release_mem_EVENT_WRITE_EOP_5;\n                        // Possible values:\n                        // 0101(5): EVENT_WRITE_EOP event types\n                        // 0110(6): Reserved for EVENT_WRITE_EOS packet.\n                        // 0111(7): Reserved (previously) for EVENT_WRITE packet.\n    pkt->bitfields2.l2_wb            = 1;\n    pkt->bitfields2.l2_inv           = 1;\n    pkt->bitfields2.cache_policy     = cache_policy_mec_release_mem_BYPASS_2;\n    pkt->bitfields2.atc = hsakmt_is_dgpu() ?\n                    atc_mec_release_mem_ci_NOT_USE_ATC_0 :\n                    atc_mec_release_mem_ci_USE_ATC_1;  // ATC setting for fences and timestamps to the MC or TCL2.\n    pkt->bitfields3.dst_sel          = dst_sel_mec_release_mem_MEMORY_CONTROLLER_0;\n                        // Possible values:\n                        // 0 - memory_controller.\n                        // 1 - tc_l2.\n    if (address) {\n        pkt->bitfields3.int_sel      = (isPolling ?\n                    int_sel_mec_release_mem_SEND_DATA_AFTER_WRITE_CONFIRM_3 :\n                    int_sel_mec_release_mem_SEND_INTERRUPT_AFTER_WRITE_CONFIRM_2);\n                // Possible values:\n                // 0 - None (Do not send an interrupt).\n                // 1 - Send Interrupt Only. Program DATA_SEL 0\".\n                // 2 - Send Interrupt when Write Confirm (WC) is received from the MC.\n                // 3 - Wait for WC, but dont send interrupt (applicable to 7.3+) [g73_1]\n                // 4 - Reserved for INTERRUPT packet\n        if (isTimeStamp && is64bit)\n            pkt->bitfields3.data_sel = data_sel_mec_release_mem_SEND_GPU_CLOCK_COUNTER_3;\n        else\n            pkt->bitfields3.data_sel     = is64bit ?\n                        data_sel_mec_release_mem_SEND_64_BIT_DATA_2 :\n                        data_sel_mec_release_mem_SEND_32_BIT_LOW_1;\n                    // Possible values:\n                    // 0 - None, i.e., Discard Data.\n                    // 1 - Send 32-bit Data Low (Discard Data High).\n                    // 2 - Send 64-bit Data.\n                    // 3 - Send current value of the 64 bit global GPU clock counter.\n                    // 4 - Send current value of the 64 bit system clock counter.\n                    // 5 - Store GDS Data to memory.\n                    // 6 - Reserved for use by the CP for Signal Semaphore.\n                    // 7 - Reserved for use by the CP for Wait Semaphore.\n    } else {\n        pkt->bitfields3.int_sel      = (isPolling ?\n                    int_sel_mec_release_mem_NONE_0 :\n                    int_sel_mec_release_mem_SEND_INTERRUPT_ONLY_1);\n        pkt->bitfields3.data_sel     = data_sel_mec_release_mem_NONE_0;\n    }\n\n    pkt->bitfields4a.address_lo_dword_aligned = static_cast<uint32_t>((address&0xffffffff) >> 2);\n    pkt->addr_hi = static_cast<uint32_t>(address>>32);\n\n    pkt->data_lo = static_cast<uint32_t>(data);\n    pkt->data_hi = static_cast<uint32_t>(data >> 32);\n}\nvoid PM4ReleaseMemoryPacket::InitPacketAI(bool isPolling, uint64_t address,\n                                        uint64_t data, bool is64bit, bool isTimeStamp) {\n    PM4MEC_RELEASE_MEM_AI *pkt;\n\n    m_packetSize = sizeof(PM4MEC_RELEASE_MEM_AI);\n    pkt = reinterpret_cast<PM4MEC_RELEASE_MEM_AI *>(AllocPacket());\n    m_pPacketData = pkt;\n\n    InitPM4Header(pkt->header, IT_RELEASE_MEM);\n\n    pkt->bitfields2.event_type       = 0x14;\n    pkt->bitfields2.event_index      = event_index__mec_release_mem__end_of_pipe;\n    pkt->bitfields2.tc_wb_action_ena = 1;\n    pkt->bitfields2.tc_action_ena    = 1;\n    pkt->bitfields2.cache_policy     = cache_policy__mec_release_mem__lru;\n\n    pkt->bitfields3.dst_sel          = dst_sel__mec_release_mem__memory_controller;\n\n    if (address) {\n        pkt->bitfields3.int_sel  = (isPolling ?\n                int_sel__mec_release_mem__send_data_after_write_confirm:\n                int_sel__mec_release_mem__send_interrupt_after_write_confirm);\n\n        if (isTimeStamp && is64bit)\n            pkt->bitfields3.data_sel = data_sel__mec_release_mem__send_gpu_clock_counter;\n        else\n            pkt->bitfields3.data_sel     = is64bit ?\n                    data_sel__mec_release_mem__send_64_bit_data :\n                    data_sel__mec_release_mem__send_32_bit_low;\n    } else {\n        pkt->bitfields3.int_sel  = (isPolling ?\n                int_sel__mec_release_mem__none:\n                int_sel__mec_release_mem__send_interrupt_only);\n        pkt->bitfields3.data_sel     = data_sel__mec_release_mem__none;\n    }\n\n    pkt->bitfields4a.address_lo_32b = static_cast<uint32_t>((address&0xffffffff) >> 2);\n    pkt->address_hi = static_cast<uint32_t>(address>>32);\n\n    pkt->data_lo = static_cast<uint32_t>(data);\n    pkt->data_hi = static_cast<uint32_t>(data >> 32);\n\n    pkt->int_ctxid = static_cast<uint32_t>(data);\n}\n\nvoid PM4ReleaseMemoryPacket::InitPacketNV(bool isPolling, uint64_t address,\n                                uint64_t data, bool is64bit, bool isTimeStamp) {\n    PM4MEC_RELEASE_MEM_NV *pkt;\n\n    m_packetSize = sizeof(PM4_MEC_RELEASE_MEM_NV);\n    pkt = reinterpret_cast<PM4_MEC_RELEASE_MEM_NV *>(AllocPacket());\n    m_pPacketData = pkt;\n\n    InitPM4Header(pkt->header, IT_RELEASE_MEM);\n\n    pkt->bitfields2.event_type       = 0x14;\n    pkt->bitfields2.event_index      = event_index__mec_release_mem__end_of_pipe;\n    pkt->bitfields2.gcr_cntl         = (1<<10) | (1<<9) | (1<<8) | (1<<3) | (1<<2);\n    pkt->bitfields2.cache_policy     = cache_policy__mec_release_mem__lru;\n\n    pkt->bitfields3.dst_sel          = dst_sel__mec_release_mem__memory_controller;\n\n    if (address) {\n        pkt->bitfields3.int_sel  = (isPolling ?\n                int_sel__mec_release_mem__send_data_after_write_confirm:\n                int_sel__mec_release_mem__send_interrupt_after_write_confirm);\n\n        if (isTimeStamp && is64bit)\n            pkt->bitfields3.data_sel = data_sel__mec_release_mem__send_gpu_clock_counter;\n        else\n            pkt->bitfields3.data_sel     = is64bit ?\n                    data_sel__mec_release_mem__send_64_bit_data :\n                    data_sel__mec_release_mem__send_32_bit_low;\n    } else {\n        pkt->bitfields3.int_sel  = (isPolling ?\n                int_sel__mec_release_mem__none:\n                int_sel__mec_release_mem__send_interrupt_only);\n        pkt->bitfields3.data_sel     = data_sel__mec_release_mem__none;\n    }\n\n    pkt->bitfields4a.address_lo_32b = static_cast<uint32_t>((address&0xffffffff) >> 2);\n    pkt->address_hi = static_cast<uint32_t>(address>>32);\n\n    pkt->data_lo = static_cast<uint32_t>(data);\n    pkt->data_hi = static_cast<uint32_t>(data >> 32);\n\n    pkt->int_ctxid = static_cast<uint32_t>(data);\n}\n\nPM4IndirectBufPacket::PM4IndirectBufPacket(IndirectBuffer *pIb) {\n    InitPacket(pIb);\n}\n\nunsigned int PM4IndirectBufPacket::SizeInBytes() const {\n    return sizeof(PM4MEC_INDIRECT_BUFFER);\n}\n\nvoid PM4IndirectBufPacket::InitPacket(IndirectBuffer *pIb) {\n    memset(&m_packetData, 0, SizeInBytes());\n    InitPM4Header(m_packetData.header,  IT_INDIRECT_BUFFER);\n\n    m_packetData.bitfields2.ib_base_lo = static_cast<HSAuint32>((reinterpret_cast<HSAuint64>(pIb->Addr()))) >> 2;\n    m_packetData.bitfields3.ib_base_hi = reinterpret_cast<HSAuint64>(pIb->Addr()) >> 32;\n    m_packetData.bitfields4.ib_size          = pIb->SizeInDWord();\n    m_packetData.bitfields4.chain            = 0;\n    m_packetData.bitfields4.offload_polling  = 0;\n    m_packetData.bitfields4.volatile_setting = 0;\n    m_packetData.bitfields4.valid            = 1;\n    m_packetData.bitfields4.vmid             = 0;  // in iommutest:  vmid = queueParams.VMID;\n    m_packetData.bitfields4.cache_policy     = cache_policy_indirect_buffer_BYPASS_2;\n}\nPM4AcquireMemoryPacket::PM4AcquireMemoryPacket(unsigned int familyId):m_pPacketData(NULL)\n{\n    m_FamilyId = familyId;\n\n    if (familyId < FAMILY_NV)\n        InitPacketAI();\n    else\n        InitPacketNV();\n}\n\nvoid PM4AcquireMemoryPacket::InitPacketAI(void) {\n\n    PM4ACQUIRE_MEM *pkt;\n    m_packetSize = sizeof(PM4ACQUIRE_MEM);\n    pkt = reinterpret_cast<PM4ACQUIRE_MEM*>(AllocPacket());\n    m_pPacketData = pkt;\n\n    InitPM4Header(pkt->header,  IT_ACQUIRE_MEM);\n    pkt->bitfields2.coher_cntl     = 0x28c00000;  // copied from the way the HSART does this.\n    pkt->bitfields2.engine         = engine_acquire_mem_PFP_0;\n    pkt->coher_size                = 0xFFFFFFFF;\n    pkt->bitfields3.coher_size_hi  = 0;\n    pkt->coher_base_lo             = 0;\n    pkt->bitfields4.coher_base_hi  = 0;\n    pkt->bitfields5.poll_interval  = 4;  // copied from the way the HSART does this.\n}\nvoid PM4AcquireMemoryPacket::InitPacketNV(void) {\n    PM4ACQUIRE_MEM_NV *pkt;\n    m_packetSize = sizeof(PM4ACQUIRE_MEM_NV);\n    pkt = reinterpret_cast<PM4ACQUIRE_MEM_NV*>(AllocPacket());\n    m_pPacketData = pkt;\n\n    InitPM4Header(pkt->header,  IT_ACQUIRE_MEM);\n    pkt->coher_size                = 0xFFFFFFFF;\n    pkt->bitfields3.coher_size_hi  = 0;\n    pkt->coher_base_lo             = 0;\n    pkt->bitfields4.coher_base_hi  = 0;\n    pkt->bitfields5.poll_interval  = 4; //copied from the way the HSART does this.\n    /* Invalidate gL2, gL1 with range base\n          * Invalidate GLV, GLK (L0$)\n          * Invalidate all Icache (GLI)\n          */\n    pkt->bitfields6.gcr_cntl = (1<<14|1<<9|1<<8|1<<7|1);\n}\n\nPM4SetShaderRegPacket::PM4SetShaderRegPacket(void) {\n}\n\nPM4SetShaderRegPacket::PM4SetShaderRegPacket(unsigned int baseOffset, const unsigned int regValues[],\n                                             unsigned int numRegs) {\n    InitPacket(baseOffset, regValues, numRegs);\n}\n\nvoid PM4SetShaderRegPacket::InitPacket(unsigned int baseOffset, const unsigned int regValues[],\n                                       unsigned int numRegs) {\n    // 1st register is a part of the packet struct.\n    m_packetSize = sizeof(PM4SET_SH_REG) + (numRegs-1)*sizeof(uint32_t);\n\n    /* Allocating the size of the packet, since the packet is assembled from a struct\n     * followed by an additional dword data\n     */\n    m_pPacketData = reinterpret_cast<PM4SET_SH_REG *>(AllocPacket());\n\n    memset(m_pPacketData, 0, m_packetSize);\n\n    InitPM4Header(m_pPacketData->header,  IT_SET_SH_REG);\n\n    m_pPacketData->bitfields2.reg_offset = baseOffset - PERSISTENT_SPACE_START;\n\n    memcpy(m_pPacketData->reg_data, regValues, numRegs*sizeof(uint32_t));\n}\n\nPM4DispatchDirectPacket::PM4DispatchDirectPacket(unsigned int dimX, unsigned int dimY,\n                                                 unsigned int dimZ, unsigned int dispatchInit) {\n    InitPacket(dimX, dimY, dimZ, dispatchInit);\n}\n\nvoid PM4DispatchDirectPacket::InitPacket(unsigned int dimX, unsigned int dimY, unsigned int dimZ,\n                                         unsigned int dispatchInit) {\n    memset(&m_packetData, 0, SizeInBytes());\n    InitPM4Header(m_packetData.header, IT_DISPATCH_DIRECT);\n\n    m_packetData.dim_x = dimX;\n    m_packetData.dim_y = dimY;\n    m_packetData.dim_z = dimZ;\n    m_packetData.dispatch_initiator = dispatchInit;\n}\n\nunsigned int PM4DispatchDirectPacket::SizeInBytes() const {\n    return sizeof(PM4DISPATCH_DIRECT);\n}\n\nPM4PartialFlushPacket::PM4PartialFlushPacket(void) {\n    memset(&m_packetData, 0, SizeInBytes());\n    InitPM4Header(m_packetData.header, IT_EVENT_WRITE);\n\n    m_packetData.bitfields2.event_index = event_index_event_write_CS_VS_PS_PARTIAL_FLUSH_4;\n    m_packetData.bitfields2.event_type = CS_PARTIAL_FLUSH;\n}\n\nunsigned int PM4PartialFlushPacket::SizeInBytes() const {\n    // For PARTIAL_FLUSH_CS packets, the last 2 dwordS don't exist.\n    return sizeof(PM4EVENT_WRITE) - sizeof(uint32_t)*2;\n}\n\nPM4NopPacket::PM4NopPacket(unsigned int count): m_packetSize(count * 4) {\n    m_packetData = reinterpret_cast<PM4_TYPE_3_HEADER *>(AllocPacket());\n    InitPM4Header(*m_packetData, IT_NOP);\n}\n\nPM4WaitRegMemPacket::PM4WaitRegMemPacket(bool memory, uint64_t addr,\n                                         uint32_t ref, uint16_t pollInterval) {\n    InitPacket(function__mec_wait_reg_mem__equal_to_the_reference_value,\n               memory ?\n               mem_space__mec_wait_reg_mem__memory_space :\n               mem_space__mec_wait_reg_mem__register_space,\n               operation__mec_wait_reg_mem__wait_reg_mem,\n               addr, ref, 0xffffffff, pollInterval);\n}\nPM4WaitRegMemPacket::PM4WaitRegMemPacket(unsigned int function,\n                                         unsigned int space,\n                                         unsigned int operation,\n                                         uint64_t addr, uint32_t ref,\n                                         uint32_t mask, uint16_t pollInterval) {\n    InitPacket(function, space, operation, addr, ref, mask, pollInterval);\n}\n\nvoid PM4WaitRegMemPacket::InitPacket(unsigned int function,\n                                     unsigned int space,\n                                     unsigned int operation,\n                                     uint64_t addr, uint32_t ref,\n                                     uint32_t mask, uint16_t pollInterval) {\n    memset(&m_packetData, 0, SizeInBytes());\n    InitPM4Header(m_packetData.header, IT_WAIT_REG_MEM);\n\n    m_packetData.bitfields2.function = (MEC_WAIT_REG_MEM_function_enum)function;\n    m_packetData.bitfields2.mem_space = (MEC_WAIT_REG_MEM_mem_space_enum)space;\n    m_packetData.bitfields2.operation = (MEC_WAIT_REG_MEM_operation_enum)operation;\n\n    m_packetData.ordinal3 = addr;\n    m_packetData.mem_poll_addr_hi = addr >> 32;\n\n    m_packetData.reference = ref;\n    m_packetData.mask = mask;\n\n    m_packetData.bitfields7.poll_interval = pollInterval;\n    m_packetData.bitfields7.optimize_ace_offload_mode = 1;\n}\n\nunsigned int PM4WaitRegMemPacket::SizeInBytes() const {\n    return sizeof(m_packetData);\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/PM4Packet.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_PM4_PACKET__H__\n#define __KFD_PM4_PACKET__H__\n\n#include \"BasePacket.hpp\"\n#include \"kfd_pm4_opcodes.h\"\n#include \"pm4_pkt_struct_common.h\"\n#include \"pm4_pkt_struct_ci.h\"\n#include \"pm4_pkt_struct_ai.h\"\n#include \"pm4_pkt_struct_nv.h\"\n#include \"IndirectBuffer.hpp\"\n\n// @class PM4Packet: Marks a group of all PM4 packets\nclass PM4Packet : public BasePacket {\n public:\n        PM4Packet(void): m_HeaderCountOffset(0) {}\n        virtual ~PM4Packet(void) {}\n\n        virtual PACKETTYPE PacketType() const { return PACKETTYPE_PM4; }\n        unsigned int CalcCountValue() const;\n\n protected:\n        int m_HeaderCountOffset;\n        void InitPM4Header(PM4_TYPE_3_HEADER &header, it_opcode_type opCode);\n};\n\n// @class PM4WriteDataPacket\nclass PM4WriteDataPacket : public PM4Packet {\n public:\n    // Empty constructor, before using the packet call the init func\n    PM4WriteDataPacket(void): m_ndw(0), m_pPacketData(NULL) {}\n    // This contructor will also init the packet, no need for additional calls\n    PM4WriteDataPacket(unsigned int *destBuf, unsigned int data1):\n        m_ndw(1), m_pPacketData(NULL) {InitPacket(destBuf, &data1);}\n    PM4WriteDataPacket(unsigned int *destBuf, unsigned int data1, unsigned int data2):\n        m_ndw(2), m_pPacketData(NULL) {\n        unsigned int data[2] = {data1, data2};\n        InitPacket(destBuf, data);\n    }\n\n    virtual ~PM4WriteDataPacket(void) {}\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return m_pPacketData; }\n    // @brief Initialise the packet\n    void InitPacket(unsigned int *destBuf, unsigned int data1) {\n        m_ndw = 1;\n        InitPacket(destBuf, &data1);\n    }\n    void InitPacket(unsigned int *destBuf, unsigned int data1, unsigned int data2) {\n        unsigned int data[2] = {data1, data2};\n        m_ndw = 2;\n        InitPacket(destBuf, data);\n    }\n    void InitPacket(unsigned int *destBuf, void *data);\n\n protected:\n    unsigned int m_ndw;\n    // PM4WRITE_DATA_CI struct contains all the packet's data\n    PM4WRITE_DATA_CI  *m_pPacketData;\n};\n\n// @class PM4ReleaseMemoryPacket\nclass PM4ReleaseMemoryPacket : public PM4Packet {\n public:\n    // Empty constructor, before using the packet call the init func\n    PM4ReleaseMemoryPacket(void): m_pPacketData(NULL) {}\n    // This contructor will also init the packet, no need for additional calls\n    PM4ReleaseMemoryPacket(unsigned int familyId, bool isPolling, uint64_t address, uint64_t data,\n                           bool is64bit = false, bool isTimeStamp = false, int headerCountOffset = 0);\n\n    virtual ~PM4ReleaseMemoryPacket(void) {}\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return m_packetSize; }\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return m_pPacketData; }\n    // @brief Initialise the packet\n\n private:\n    void InitPacketCI(bool isPolling, uint64_t address, uint64_t data,\n                 bool is64bit = false, bool isTimeStamp = false);\n    void InitPacketAI(bool isPolling, uint64_t address, uint64_t data,\n                 bool is64bit = false, bool isTimeStamp = false);\n    void InitPacketNV(bool isPolling, uint64_t address, uint64_t data,\n                 bool is64bit = false, bool isTimeStamp = false);\n\n    void *m_pPacketData;\n    unsigned int  m_packetSize;\n};\n\n// @class PM4IndirectBufPacket\nclass PM4IndirectBufPacket : public PM4Packet {\n public:\n    // Empty constructor, before using the packet call the init func\n    PM4IndirectBufPacket(void) {}\n    // This contructor will also init the packet, no need for additional calls\n    explicit PM4IndirectBufPacket(IndirectBuffer *pIb);\n\n    virtual ~PM4IndirectBufPacket(void) {}\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return &m_packetData; }\n    // @breif Initialise the packet\n    void InitPacket(IndirectBuffer *pIb);\n\n private:\n    // PM4MEC_INDIRECT_BUFFER struct contains all the packet's data\n    PM4MEC_INDIRECT_BUFFER  m_packetData;\n};\n\n// @class PM4AcquireMemoryPacket\nclass PM4AcquireMemoryPacket : public PM4Packet {\n public:\n    PM4AcquireMemoryPacket(unsigned int familyId);\n    virtual ~PM4AcquireMemoryPacket(void) {}\n\n    // @returns the packet size in bytes\n    virtual unsigned int SizeInBytes() const { return m_packetSize; }\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return m_pPacketData; }\n\n private:\n    void InitPacketAI(void);\n    void InitPacketNV(void);\n    void *m_pPacketData;\n    unsigned int  m_packetSize;\n};\n\n// @class PM4SetShaderRegPacket Packet that writes to consecutive registers starting at baseOffset.\nclass PM4SetShaderRegPacket : public PM4Packet {\n public:\n    PM4SetShaderRegPacket(void);\n\n    PM4SetShaderRegPacket(unsigned int baseOffset, const unsigned int regValues[], unsigned int numRegs);\n\n    virtual ~PM4SetShaderRegPacket(void) {}\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return m_packetSize; }\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return m_pPacketData; }\n\n    void InitPacket(unsigned int baseOffset, const unsigned int regValues[], unsigned int numRegs);\n\n private:\n    unsigned int m_packetSize;\n    // PM4SET_SH_REG struct contains all the packet's data\n    PM4SET_SH_REG  *m_pPacketData;\n};\n\n// @class PM4DispatchDirectPacket\nclass PM4DispatchDirectPacket : public PM4Packet {\n public:\n    PM4DispatchDirectPacket(void) {}\n\n    PM4DispatchDirectPacket(unsigned int dimX, unsigned int dimY, unsigned int dimZ, unsigned int dispatchInit);\n\n    virtual ~PM4DispatchDirectPacket(void) {}\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return &m_packetData; }\n\n    void InitPacket(unsigned int dimX, unsigned int dimY, unsigned int dimZ, unsigned int dispatchInit);\n\n private:\n    // PM4DISPATCH_DIRECT struct contains all the packet's data\n    PM4DISPATCH_DIRECT  m_packetData;\n};\n\n// @class PM4PartialFlushPacket\nclass PM4PartialFlushPacket : public PM4Packet {\n public:\n    PM4PartialFlushPacket(void);\n    virtual ~PM4PartialFlushPacket(void) {}\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return &m_packetData; }\n\n private:\n    // PM4EVENT_WRITE struct contains all the packet's data\n    PM4EVENT_WRITE  m_packetData;\n};\n\n// @class PM4NopPacket\nclass PM4NopPacket : public PM4Packet {\n public:\n    PM4NopPacket(unsigned int count = 1);\n    virtual ~PM4NopPacket(void) {}\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return m_packetSize; }\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return m_packetData; }\n\n private:\n    unsigned int m_packetSize;\n    PM4_TYPE_3_HEADER *m_packetData;\n};\n\n// @class PM4WaitRegMemPacket\nclass PM4WaitRegMemPacket : public PM4Packet {\n public:\n    PM4WaitRegMemPacket(void) {}\n    PM4WaitRegMemPacket(bool memory, uint64_t addr, uint32_t ref, uint16_t pollInterval);\n    PM4WaitRegMemPacket(unsigned int function, unsigned int space, unsigned int operation,\n                        uint64_t addr, uint32_t ref, uint32_t mask, uint16_t pollInterval);\n    virtual ~PM4WaitRegMemPacket(void) {}\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const;\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return &m_packetData; }\n\n    void InitPacket(unsigned int function, unsigned int space, unsigned int operation,\n                    uint64_t addr, uint32_t ref, uint32_t mask, uint16_t pollInterval);\n\n private:\n    PM4MEC_WAIT_REG_MEM m_packetData;\n};\n\n#endif  // __KFD_PM4_PACKET__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/PM4Queue.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"PM4Queue.hpp\"\n#include \"pm4_pkt_struct_common.h\"\n#include \"GoogleTestExtension.hpp\"\n#include \"kfd_pm4_opcodes.h\"\n\n\nPM4Queue::PM4Queue(void) {\n    CMD_NOP = CMD_NOP_TYPE_3;\n}\n\nPM4Queue::~PM4Queue(void) {\n}\n\nunsigned int PM4Queue::Wptr() {\n    /* Write pointer in dwords. Simulate 32-bit wptr that wraps at\n     * queue size even on Vega10 and later chips with 64-bit wptr.\n     */\n    return *m_Resources.Queue_write_ptr % (m_QueueBuf->Size() / 4);\n}\n\nunsigned int PM4Queue::Rptr() {\n    /* CP read pointer in dwords. It's still 32-bit even on Vega10. */\n    return *m_Resources.Queue_read_ptr;\n}\n\nunsigned int PM4Queue::RptrWhenConsumed() {\n    /* On PM4 queues Rptr is always 32-bit in dword units and wraps at\n     * queue size. The expected value when all packets are consumed is\n     * exactly the value returned by Wptr().\n     */\n    return Wptr();\n}\n\nvoid PM4Queue::SubmitPacket() {\n    // m_pending Wptr is in dwords\n    if (m_FamilyId < FAMILY_AI) {\n        // Pre-Vega10 uses 32-bit wptr and doorbell\n        MemoryBarrier();\n        *m_Resources.Queue_write_ptr = m_pendingWptr;\n        MemoryBarrier();\n        *(m_Resources.Queue_DoorBell) = m_pendingWptr;\n    } else {\n        // Vega10 and later uses 64-bit wptr and doorbell\n        MemoryBarrier();\n        *m_Resources.Queue_write_ptr_aql = m_pendingWptr64;\n        MemoryBarrier();\n        *(m_Resources.Queue_DoorBell_aql) = m_pendingWptr64;\n    }\n}\n\nvoid PM4Queue::Wait4PacketConsumption(HsaEvent *event, unsigned int timeOut) {\n    if (event) {\n        PlaceAndSubmitPacket(PM4ReleaseMemoryPacket(m_FamilyId, 0,\n                    event->EventData.HWData2,\n                    event->EventId,\n                    true));\n\n        EXPECT_SUCCESS(hsaKmtWaitOnEvent(event, timeOut));\n    } else {\n        BaseQueue::Wait4PacketConsumption(NULL, timeOut);\n    }\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/PM4Queue.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_PM4_QUEUE__H__\n#define __KFD_PM4_QUEUE__H__\n\n#include \"BaseQueue.hpp\"\n#include \"PM4Packet.hpp\"\n\nclass PM4Queue : public BaseQueue {\n public:\n    PM4Queue(void);\n    virtual ~PM4Queue(void);\n\n    // @brief update queue write pointer and sets the queue doorbell to the queue write pointer\n    virtual void SubmitPacket();\n\n    // @ return read pointer modulo queue size in dwords\n    virtual unsigned int Rptr();\n    // @ return write pointer modulo queue size in dwords\n    virtual unsigned int Wptr();\n    // @ return expected m_Resources.Queue_read_ptr when all packets consumed\n    virtual unsigned int RptrWhenConsumed();\n    /** Wait for all the packets submitted to the queue to be consumed. (i.e. wait until RPTR=WPTR).\n     *  Note that all packets being consumed is not the same as all packets being processed.\n     *  If event is set, wait all packets being processed.\n     *  And we can benefit from that as it has\n     *  1) Less CPU usage (process can sleep, waiting for interrupt).\n     *  2) Lower latency (GPU only updates RPTR in memory periodically).\n     */\n    virtual void Wait4PacketConsumption(HsaEvent *event = NULL, unsigned int timeOut = g_TestTimeOut);\n\n protected:\n    virtual PACKETTYPE PacketTypeSupported() { return PACKETTYPE_PM4; }\n\n    virtual _HSA_QUEUE_TYPE GetQueueType() { return HSA_QUEUE_COMPUTE; }\n};\n\n#endif  // __KFD_PM4_QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/RDMATest.cpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"RDMATest.hpp\"\n#include \"PM4Queue.hpp\"\n#include \"PM4Packet.hpp\"\n#include \"SDMAPacket.hpp\"\n#include \"SDMAQueue.hpp\"\n#include \"Dispatch.hpp\"\n#include \"RDMAUtil.hpp\"\n\nvoid RDMATest::SetUp() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::SetUp();\n\n    ROUTINE_END\n}\n\nvoid RDMATest::TearDown() {\n    ROUTINE_START\n\n    KFDBaseComponentTest::TearDown();\n\n    ROUTINE_END\n}\n\nTEST_F(RDMATest, GPUDirect) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n    HSAuint64 AlternateVAGPU;\n\n    PM4Queue queue;\n    unsigned int BufferSize = PAGE_SIZE;\n    int ret;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, defaultGPUNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcSysBuffer(BufferSize, defaultGPUNode, false);\n    HsaMemoryBuffer srcLocalBuffer(BufferSize, defaultGPUNode, false, true);\n\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(srcSysBuffer.As<void*>(),\n                                        srcSysBuffer.Size(),\n                                        &AlternateVAGPU));\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(srcLocalBuffer.As<void*>(),\n                                        srcLocalBuffer.Size(),\n                                        &AlternateVAGPU));\n\n    /* Fill up srcSysBuffer */\n    srcSysBuffer.Fill(0xfe);\n\n    /* Put 'copy dword' command to ISA buffer */\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()));\n\n\n    ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n    Dispatch dispatch(isaBuffer);\n\n    /* Submit the command to GPU so GPU will copy from system memory\n     * (srcSysBuffer) to local memory(srcLocalBuffer)\n     */\n    dispatch.SetArgs(srcSysBuffer.As<void*>(), srcLocalBuffer.As<void*>());\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);  // GPU executed the command\n\n    EXPECT_SUCCESS(queue.Destroy());\n\n    LocalMemoryAccess Rdma;\n\n    Rdma.Open();\n    ASSERT_GE(Rdma.fd, 0) << \"Failed to open RDMA\";\n\n    /* GetPages asks the test driver to convert GPU virtual memory to DMA/\n     * Physical memory and save it in the list. rdma_mmap maps the memory to\n     * user space memory.\n     */\n    ret = Rdma.GetPages((uint64_t)srcLocalBuffer.As<void*>(), PAGE_SIZE);\n    ASSERT_EQ(ret, 0) << \"Failed to get pages\";\n\n    void *gpuAddr = Rdma.MMap((uint64_t)srcLocalBuffer.As<void*>(), PAGE_SIZE);\n    ASSERT_GE((uint64_t)gpuAddr, 0) << \"Failed to map RDMA address.\";\n\n    /* Read the memory to confirm that application can read the local memory\n     * correctly from the mapped address.\n     */\n    EXPECT_EQ(memcmp(gpuAddr, srcSysBuffer.As<void*>(), 4), 0);\n\n    Rdma.UnMap(gpuAddr, PAGE_SIZE);\n    Rdma.Close();\n\n    TEST_END\n}\n\nTEST_F(RDMATest, ContiguousVRAMAllocation) {\n    TEST_REQUIRE_ENV_CAPABILITIES(ENVCAPS_64BITLINUX);\n    TEST_START(TESTPROFILE_RUNALL);\n\n    HSAuint64 AlternateVAGPU;\n\n    PM4Queue queue;\n    unsigned long BufferSize = 4UL << 30;\n\n    int defaultGPUNode = m_NodeInfo.HsaDefaultGPUNode();\n    ASSERT_GE(defaultGPUNode, 0) << \"failed to get default GPU Node\";\n\n    if (GetVramSize(defaultGPUNode) < BufferSize + (1UL << 30)) {\n        LOG() << \"no enough VRAM, skipping the test\" << std::endl;\n        return;\n    }\n\n    HsaMemoryBuffer isaBuffer(PAGE_SIZE, defaultGPUNode, true/*zero*/, false/*local*/, true/*exec*/);\n    HsaMemoryBuffer srcSysBuffer(PAGE_SIZE, defaultGPUNode, false);\n    void *LocalBuffer;\n    HsaMemFlags memFlags = {0};\n    int ret;\n\n    memFlags.ui32.NonPaged = 1;\n    memFlags.ui32.Contiguous = 1;\n    ret = hsaKmtAllocMemory(defaultGPUNode, BufferSize, memFlags, &LocalBuffer);\n    if (ret == HSAKMT_STATUS_NOT_SUPPORTED) {\n        LOG() << \"KFD does not support contiguous memory, skipping the test\" << std::endl;\n        return;\n    }\n\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(srcSysBuffer.As<void*>(),\n                                        srcSysBuffer.Size(),\n                                        &AlternateVAGPU));\n    ASSERT_SUCCESS(hsaKmtMapMemoryToGPU(LocalBuffer, BufferSize, &AlternateVAGPU));\n\n    /* Fill up srcSysBuffer */\n    srcSysBuffer.Fill(0xfe);\n\n    /* Put 'copy dword' command to ISA buffer */\n    ASSERT_SUCCESS(m_pAsm->RunAssembleBuf(CopyDwordIsa, isaBuffer.As<char*>()));\n\n    ASSERT_SUCCESS(queue.Create(defaultGPUNode));\n    Dispatch dispatch(isaBuffer);\n\n    /* Submit the command to GPU so GPU will copy from system memory\n     * (srcSysBuffer) to local memory(LocalBuffer)\n     */\n    dispatch.SetArgs(srcSysBuffer.As<void*>(), LocalBuffer);\n    dispatch.Submit(queue);\n    dispatch.Sync(g_TestTimeOut);  // GPU executed the command\n\n    EXPECT_SUCCESS(queue.Destroy());\n\n    LocalMemoryAccess Rdma;\n    void *gpuAddr;\n\n    Rdma.Open();\n    if (Rdma.fd < 0) {\n        LOG() << \"amdp2ptest.ko driver not loaded, skipping RDMA getpages\" << std::endl;\n        goto exit;\n    }\n\n    /* GetPages asks the test driver to convert GPU virtual memory to DMA/\n     * Physical memory and save it in the list. rdma_mmap maps the memory to\n     * user space memory.\n     */\n    ret = Rdma.GetPages((uint64_t)LocalBuffer, BufferSize);\n    ASSERT_EQ(ret, 0) << \"Failed to get pages\";\n\n    gpuAddr = Rdma.MMap((uint64_t)LocalBuffer, BufferSize);\n    ASSERT_GE((int64_t)gpuAddr, 0) << \"Failed to map RDMA address.\";\n\n    printf(\"contiguous VRAM address %p size 0x%lx bytes\\n\", LocalBuffer, BufferSize);\n    printf(\"Pause to dump page table to check if allocation is contiguous\\n\");\n    printf(\"Press Enter key to continue\\n\");\n    getchar();\n\n    /* Read the memory to confirm that application can read the local memory\n     * correctly from the mapped address.\n     */\n    EXPECT_EQ(memcmp(gpuAddr, srcSysBuffer.As<void*>(), 4), 0);\n\n    Rdma.UnMap(gpuAddr, PAGE_SIZE);\n    Rdma.Close();\n\nexit:\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(srcSysBuffer.As<void*>()));\n    EXPECT_SUCCESS(hsaKmtUnmapMemoryToGPU(LocalBuffer));\n    EXPECT_SUCCESS(hsaKmtFreeMemory(LocalBuffer, BufferSize));\n\n    TEST_END\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/RDMATest.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __RDMA_TEST__H__\n#define __RDMA_TEST__H__\n\n#include <gtest/gtest.h>\n\n#include \"KFDBaseComponentTest.hpp\"\n\nclass RDMATest : public KFDBaseComponentTest {\n public:\n    RDMATest() {}\n    ~RDMATest() {}\n\n protected:\n    virtual void SetUp();\n    virtual void TearDown();\n};\n\n#endif  // __RDMA_TEST__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/RDMAUtil.cpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <gtest/gtest.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <sys/ioctl.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <string>\n#include \"amdp2ptest.h\"\n#include \"RDMAUtil.hpp\"\n\nvoid LocalMemoryAccess::Open() {\n    fd = open(AMDP2PTEST_DEVICE_PATH, O_RDWR);\n}\n\nvoid LocalMemoryAccess::Close() {\n    close(fd);\n    fd = -1;\n}\n\nint LocalMemoryAccess::GetPages(uint64_t gpu_va_addr, uint64_t size) {\n    struct AMDRDMA_IOCTL_GET_PAGES_PARAM param = {0};\n\n    if (fd <= 0)\n        return -1;\n\n    param.addr = gpu_va_addr;\n    param.length = size;\n\n    return ioctl(fd, AMD2P2PTEST_IOCTL_GET_PAGES, &param);\n}\n\nvoid *LocalMemoryAccess::MMap(uint64_t offset, size_t size) {\n    void *gpuAddr;\n\n    if (fd <= 0)\n        return NULL;\n\n    gpuAddr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, offset);\n    return gpuAddr;\n}\n\nvoid LocalMemoryAccess::UnMap(void *offset, size_t size) {\n    munmap(offset, size);\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/RDMAUtil.hpp",
    "content": "/*\n * Copyright (C) 2016-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __RDMA__UTIL__H__\n#define __RDMA__UTIL__H__\n\nclass LocalMemoryAccess {\n public:\n    int fd;\n    void Open(void);\n    void Close(void);\n    int GetPages(uint64_t, uint64_t);\n    void *MMap(uint64_t, size_t);\n    void UnMap(void *, size_t);\n};\n\n#endif  // __RDMA__UTIL__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/SDMAPacket.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include <stdint.h>\n#include <stddef.h>\n#include <string.h>\n#include \"SDMAPacket.hpp\"\n#include \"KFDTestUtil.hpp\"\n\n/* Byte/dword count in many SDMA packets is 1-based in AI, meaning a\n * count of 1 is encoded as 0.\n */\n#define SDMA_COUNT(c) (m_FamilyId < FAMILY_AI ? (c) : (c)-1)\n\nSDMAWriteDataPacket::SDMAWriteDataPacket(unsigned int familyId, void* destAddr, unsigned int data,\n                                         unsigned int packetSizeOffset):\n    packetData(NULL) {\n    m_FamilyId = familyId;\n    InitPacket(destAddr, 1, &data, packetSizeOffset);\n}\n\nSDMAWriteDataPacket::SDMAWriteDataPacket(unsigned int familyId, void* destAddr, unsigned int ndw,\n                                         void *data):\n    packetData(NULL) {\n    m_FamilyId = familyId;\n    InitPacket(destAddr, ndw, data);\n}\n\nvoid SDMAWriteDataPacket::InitPacket(void* destAddr, unsigned int ndw,\n                                     void *data, unsigned int packetSizeOffset) {\n    packetSize = sizeof(SDMA_PKT_WRITE_UNTILED) +\n        (ndw - 1) * sizeof(unsigned int);\n    packetSize -= packetSizeOffset;\n    packetData = reinterpret_cast<SDMA_PKT_WRITE_UNTILED *>(AllocPacket());\n\n    packetData->HEADER_UNION.op = SDMA_OP_WRITE;\n    packetData->HEADER_UNION.sub_op = SDMA_SUBOP_WRITE_LINEAR;\n\n    SplitU64(reinterpret_cast<HSAuint64>(destAddr),\n             packetData->DST_ADDR_LO_UNION.DW_1_DATA,  // dst_addr_31_0\n             packetData->DST_ADDR_HI_UNION.DW_2_DATA);  // dst_addr_63_32\n\n    packetData->DW_3_UNION.count = SDMA_COUNT(ndw);\n    memcpy(&packetData->DATA0_UNION.DW_4_DATA, data, ndw*sizeof(unsigned int));\n}\n\n#define BITS (21)\n#define TWO_MEG (1 << BITS)\nSDMACopyDataPacket::SDMACopyDataPacket(unsigned int familyId,\n                        void *const dsts[], void *src, int n, unsigned int surfsize) {\n    int32_t size = 0, i;\n    void **dst = reinterpret_cast<void**>(malloc(sizeof(void*) * n));\n    const int singlePacketSize = sizeof(SDMA_PKT_COPY_LINEAR) +\n                        sizeof(SDMA_PKT_COPY_LINEAR::DST_ADDR[0]) * n;\n\n    if (n > 2)\n        WARN() << \"SDMACopyDataPacket does not support more than 2 dst addresses!\" << std::endl;\n\n    m_FamilyId = familyId;\n    memcpy(dst, dsts, sizeof(void*) * n);\n\n    packetSize = ((surfsize + TWO_MEG - 1) >> BITS) * singlePacketSize;\n\n    SDMA_PKT_COPY_LINEAR *pSDMA = reinterpret_cast<SDMA_PKT_COPY_LINEAR *>(AllocPacket());\n    packetData = pSDMA;\n\n    while (surfsize > 0) {\n        /* SDMA support maximum 0x3fffe0 byte in one copy, take 2M here */\n        if (surfsize > TWO_MEG)\n            size = TWO_MEG;\n        else\n            size = surfsize;\n\n        memset(pSDMA, 0, singlePacketSize);\n        pSDMA->HEADER_UNION.op           = SDMA_OP_COPY;\n        pSDMA->HEADER_UNION.sub_op       = SDMA_SUBOP_COPY_LINEAR;\n        pSDMA->HEADER_UNION.broadcast       = n > 1 ? 1 : 0;\n        pSDMA->COUNT_UNION.count             = SDMA_COUNT(size);\n        SplitU64(reinterpret_cast<HSAuint64>(src),\n                 pSDMA->SRC_ADDR_LO_UNION.DW_3_DATA,  // src_addr_31_0\n                 pSDMA->SRC_ADDR_HI_UNION.DW_4_DATA);  // src_addr_63_32\n\n        for (i = 0; i < n; i++)\n            SplitU64(reinterpret_cast<HSAuint64>(dst[i]),\n                    pSDMA->DST_ADDR[i].DST_ADDR_LO_UNION.DW_5_DATA,  // dst_addr_31_0\n                    pSDMA->DST_ADDR[i].DST_ADDR_HI_UNION.DW_6_DATA);  // dst_addr_63_32\n\n        pSDMA = reinterpret_cast<SDMA_PKT_COPY_LINEAR *>(reinterpret_cast<char *>(pSDMA) + singlePacketSize);\n        for (i = 0; i < n; i++)\n            dst[i] = reinterpret_cast<char *>(dst[i]) + size;\n        src = reinterpret_cast<char *>(src) + size;\n        surfsize -= size;\n    }\n    free(dst);\n}\n\nSDMACopyDataPacket::SDMACopyDataPacket(unsigned int familyId, void* dst, void *src, unsigned int surfsize) {\n    new (this)SDMACopyDataPacket(familyId, &dst, src, 1, surfsize);\n}\n\nSDMAFillDataPacket::SDMAFillDataPacket(unsigned int familyId, void *dst, unsigned int data, unsigned int size) {\n    unsigned int copy_size;\n    SDMA_PKT_CONSTANT_FILL *pSDMA;\n\n    m_FamilyId = familyId;\n    /* SDMA support maximum 0x3fffe0 byte in one copy. Use 2M copy_size */\n    m_PacketSize = ((size + TWO_MEG - 1) >> BITS) * sizeof(SDMA_PKT_CONSTANT_FILL);\n    pSDMA = reinterpret_cast<SDMA_PKT_CONSTANT_FILL *>(AllocPacket());\n    m_PacketData = pSDMA;\n\n    while (size > 0) {\n        if (size > TWO_MEG)\n            copy_size = TWO_MEG;\n        else\n            copy_size = size;\n\n        pSDMA->HEADER_UNION.op = SDMA_OP_CONST_FILL;\n        pSDMA->HEADER_UNION.sub_op = 0;\n\n        /* If both size and address are DW aligned, then use DW fill */\n        if (!(copy_size & 0x3) && !((HSAuint64)dst & 0x3))\n            pSDMA->HEADER_UNION.fillsize = 2; /* DW Fill */\n        else\n            pSDMA->HEADER_UNION.fillsize = 0; /* Byte Fill */\n\n        pSDMA->COUNT_UNION.count = SDMA_COUNT(copy_size);\n\n        SplitU64(reinterpret_cast<HSAuint64>(dst),\n            pSDMA->DST_ADDR_LO_UNION.DW_1_DATA, /*dst_addr_31_0*/\n            pSDMA->DST_ADDR_HI_UNION.DW_2_DATA); /*dst_addr_63_32*/\n\n        pSDMA->DATA_UNION.DW_3_DATA = data;\n        pSDMA++;\n\n        dst = reinterpret_cast<char *>(dst) + copy_size;\n        size -= copy_size;\n    }\n}\n\nSDMAFencePacket::SDMAFencePacket(void) {\n}\n\nSDMAFencePacket::SDMAFencePacket(unsigned int familyId, void* destAddr, unsigned int data) {\n    m_FamilyId = familyId;\n    if (m_FamilyId < FAMILY_NV)\n        InitPacketCI(destAddr, data);\n    else\n        InitPacketNV(destAddr, data);\n}\n\nSDMAFencePacket::~SDMAFencePacket(void) {\n}\n\nvoid SDMAFencePacket::InitPacketCI(void* destAddr, unsigned int data) {\n    memset(&packetData, 0, SizeInBytes());\n\n    packetData.HEADER_UNION.op = SDMA_OP_FENCE;\n\n    SplitU64(reinterpret_cast<HSAuint64>(destAddr),\n             packetData.ADDR_LO_UNION.DW_1_DATA, /*dst_addr_31_0*/\n             packetData.ADDR_HI_UNION.DW_2_DATA); /*dst_addr_63_32*/\n\n    packetData.DATA_UNION.data = data;\n}\n\nvoid SDMAFencePacket::InitPacketNV(void * destAddr,unsigned int data) {\n    memset(&packetData, 0, SizeInBytes());\n\n    /* GPA=0 becaue we use virtual address\n     * Snoop = 1 because we want the write be CPU coherent\n     * System = 1 because the memory is system memory\n     * mtype = uncached, for the purpose of CPU coherent, L2 policy doesn't matter in this case\n     */\n    packetData.HEADER_UNION.DW_0_DATA = (0 << 23) | (1 << 22) | (1 << 20) | (3 << 16) | SDMA_OP_FENCE;\n\n    SplitU64(reinterpret_cast<unsigned long long>(destAddr),\n             packetData.ADDR_LO_UNION.DW_1_DATA, /*dst_addr_31_0*/\n             packetData.ADDR_HI_UNION.DW_2_DATA); /*dst_addr_63_32*/\n\n    packetData.DATA_UNION.data = data;\n}\n\n\nSDMATrapPacket::SDMATrapPacket(unsigned int eventID) {\n    InitPacket(eventID);\n}\n\nSDMATrapPacket::~SDMATrapPacket(void) {\n}\n\nvoid SDMATrapPacket::InitPacket(unsigned int eventID) {\n    memset(&packetData, 0, SizeInBytes());\n\n    packetData.HEADER_UNION.op = SDMA_OP_TRAP;\n    packetData.INT_CONTEXT_UNION.int_context = eventID;\n}\n\nSDMAPollRegMemPacket::SDMAPollRegMemPacket(void *addr, int value) {\n    InitPacket(addr, value);\n}\n\nSDMAPollRegMemPacket::~SDMAPollRegMemPacket(void) {\n}\n\nvoid SDMAPollRegMemPacket::InitPacket(void *addr, int value) {\n    memset(&packetData, 0, SizeInBytes());\n\n    packetData.HEADER_UNION.op = SDMA_OP_POLL_REGMEM;\n    packetData.HEADER_UNION.mem_poll = 1;\n    packetData.HEADER_UNION.func = 0x3; // IsEqual.\n    SplitU64(reinterpret_cast<unsigned long long>(addr),\n             packetData.ADDR_LO_UNION.DW_1_DATA,\n             packetData.ADDR_HI_UNION.DW_2_DATA);\n    packetData.VALUE_UNION.value = value;\n    packetData.MASK_UNION.mask = 0xffffffff; // Compare the whole content.\n    packetData.DW5_UNION.interval = 0x04;\n    packetData.DW5_UNION.retry_count = 0xfff;\n}\n\nSDMATimePacket::SDMATimePacket(void *destaddr) {\n    InitPacket(destaddr);\n}\n\nSDMATimePacket::~SDMATimePacket(void) {\n}\n\nvoid SDMATimePacket::InitPacket(void *destaddr) {\n    memset(&packetData, 0, SizeInBytes());\n\n    packetData.HEADER_UNION.op = SDMA_OP_TIMESTAMP;\n    packetData.HEADER_UNION.sub_op = 1 << 1; /* Get Global GPU Timestamp*/\n\n    if (reinterpret_cast<unsigned long long>(destaddr) & 0x1f)\n        WARN() << \"SDMATimePacket dst address must aligned to 32bytes boundary\" << std::endl;\n\n    SplitU64(reinterpret_cast<unsigned long long>(destaddr),\n            packetData.ADDR_LO_UNION.DW_1_DATA, /*dst_addr_31_0*/\n            packetData.ADDR_HI_UNION.DW_2_DATA); /*dst_addr_63_32*/\n}\n\nSDMANopPacket::SDMANopPacket(unsigned int count) {\n    packetSize = count * sizeof(unsigned int);\n    packetData = reinterpret_cast<SDMA_PKT_NOP *>(AllocPacket());\n\n    packetData->HEADER_UNION.op = SDMA_OP_NOP;\n    packetData->HEADER_UNION.sub_op = 0;\n    packetData->HEADER_UNION.count = count - 1;\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/SDMAPacket.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_SDMA_PACKET__H__\n#define __KFD_SDMA_PACKET__H__\n\n#include \"BasePacket.hpp\"\n#include \"sdma_pkt_struct.h\"\n\n// @class SDMAPacket: Marks a group of all SDMA packets\nclass SDMAPacket : public BasePacket {\n public:\n        SDMAPacket(void) {}\n        virtual ~SDMAPacket(void) {}\n\n        virtual PACKETTYPE PacketType() const { return PACKETTYPE_SDMA; }\n};\n\nclass SDMAWriteDataPacket : public SDMAPacket {\n public:\n    // This contructor will also init the packet, no need for additional calls\n    SDMAWriteDataPacket(unsigned int familyId, void* destAddr, unsigned int data,\n\t\t        unsigned int packSizeOffset = 0);\n    SDMAWriteDataPacket(unsigned int familyId, void* destAddr, unsigned int ndw, void *data);\n\n    virtual ~SDMAWriteDataPacket(void) {}\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return packetData; }\n    // @breif Initialise the packet\n    void InitPacket(void* destAddr, unsigned int ndw, void *data, unsigned int packetSizeOffset = 0);\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return packetSize; }\n\n protected:\n    // SDMA_PKT_WRITE_UNTILED struct contains all the packet's data\n    SDMA_PKT_WRITE_UNTILED *packetData;\n    unsigned int packetSize;\n};\n\nclass SDMACopyDataPacket : public SDMAPacket {\n public:\n    // This contructor will also init the packet, no need for additional calls\n    SDMACopyDataPacket(unsigned int familyId, void *dest, void *src, unsigned int size);\n    SDMACopyDataPacket(unsigned int familyId, void *const dst[], void *src, int n, unsigned int surfsize);\n\n    virtual ~SDMACopyDataPacket(void) {}\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return packetData; }\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return packetSize; }\n\n protected:\n    // SDMA_PKT_COPY_LINEAR struct contains all the packet's data\n    SDMA_PKT_COPY_LINEAR  *packetData;\n\n    unsigned int packetSize;\n};\n\nclass SDMAFillDataPacket : public SDMAPacket {\n public:\n    // This contructor will also init the packet, no need for additional calls\n    SDMAFillDataPacket(unsigned int familyId, void *dest, unsigned int data, unsigned int size);\n\n    virtual ~SDMAFillDataPacket(void) {}\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return m_PacketData; }\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return m_PacketSize; }\n\n protected:\n    // SDMA_PKT_CONSTANT_FILL struct contains all the packet's data\n    SDMA_PKT_CONSTANT_FILL  *m_PacketData;\n\n    unsigned int m_PacketSize;\n};\n\nclass SDMAFencePacket : public SDMAPacket {\n public:\n    // Empty constructor, before using the packet call the init func\n    SDMAFencePacket(void);\n    // This contructor will also init the packet, no need for additional calls\n    SDMAFencePacket(unsigned int familyId, void* destAddr, unsigned int data);\n\n    virtual ~SDMAFencePacket(void);\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return &packetData; }\n    // @brief Initialise the packet\n    void InitPacketCI(void* destAddr, unsigned int data);\n    void InitPacketNV(void* destAddr, unsigned int data);\n\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return sizeof(SDMA_PKT_FENCE ); }\n\n protected:\n    // SDMA_PKT_FENCE struct contains all the packet's data\n    SDMA_PKT_FENCE  packetData;\n};\n\nclass SDMATrapPacket : public SDMAPacket {\n public:\n    // Empty constructor, before using the packet call the init func\n    explicit SDMATrapPacket(unsigned int eventID = 0);\n\n    virtual ~SDMATrapPacket(void);\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return &packetData; }\n    // @brief Initialise the packet\n    void InitPacket(unsigned int eventID);\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return sizeof(SDMA_PKT_TRAP); }\n\n protected:\n    // SDMA_PKT_TRAP struct contains all the packet's data\n    SDMA_PKT_TRAP  packetData;\n};\n\nclass SDMAPollRegMemPacket : public SDMAPacket {\n public:\n    // This contructor will also init the packet, no need for additional calls\n    SDMAPollRegMemPacket(void* addr, int value);\n\n    virtual ~SDMAPollRegMemPacket(void);\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return &packetData; }\n    // @breif Initialise the packet\n    void InitPacket(void* addr, int value);\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return sizeof(SDMA_PKT_POLL_REGMEM); }\n\n protected:\n    // SDMA_PKT_WRITE_UNTILED struct contains all the packet's data\n    SDMA_PKT_POLL_REGMEM packetData;\n    unsigned int packetSize;\n};\n\nclass SDMATimePacket : public SDMAPacket {\n public:\n    // Empty constructor, before using the packet call the init func\n    SDMATimePacket(void*);\n\n    virtual ~SDMATimePacket(void);\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const  { return &packetData; }\n    // @brief Initialise the packet\n    void InitPacket(void*);\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return sizeof(SDMA_PKT_TIMESTAMP); }\n\n protected:\n    SDMA_PKT_TIMESTAMP  packetData;\n};\n\nclass SDMANopPacket : public SDMAPacket {\n public:\n    SDMANopPacket(unsigned int count = 1);\n    virtual ~SDMANopPacket(void) {}\n\n    // @returns Pointer to the packet\n    virtual const void *GetPacket() const { return packetData; }\n    // @returns Packet size in bytes\n    virtual unsigned int SizeInBytes() const { return packetSize; }\n\n private:\n    SDMA_PKT_NOP *packetData;\n    unsigned int packetSize;\n};\n\n\n#endif  // __KFD_SDMA_PACKET__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/SDMAQueue.cpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"SDMAQueue.hpp\"\n#include \"SDMAPacket.hpp\"\n\nSDMAQueue::SDMAQueue(void) {\n     CMD_NOP = 0;\n}\n\nSDMAQueue::~SDMAQueue(void) {\n}\n\nunsigned int SDMAQueue::Wptr() {\n    /* In SDMA queues write pointers are saved in bytes, convert the\n     * wptr value to dword to fit the way BaseQueue works. On Vega10\n     * the write ptr is 64-bit. We only read the low 32 bit (assuming\n     * the queue buffer is smaller than 4GB) and modulo divide by the\n     * queue size to simulate a 32-bit read pointer.\n     */\n    return (*m_Resources.Queue_write_ptr % m_QueueBuf->Size()) /\n        sizeof(unsigned int);\n}\n\nunsigned int SDMAQueue::Rptr() {\n    /* In SDMA queues read pointers are saved in bytes, convert the\n     * read value to dword to fit the way BaseQueue works. On Vega10\n     * the read ptr is 64-bit. We only read the low 32 bit (assuming\n     * the queue buffer is smaller than 4GB) and modulo divide by the\n     * queue size to simulate a 32-bit read pointer.\n     */\n    return (*m_Resources.Queue_read_ptr % m_QueueBuf->Size()) /\n        sizeof(unsigned int);\n}\n\nunsigned int SDMAQueue::RptrWhenConsumed() {\n    /* Rptr is same size and byte units as Wptr. Here we only care\n     * about the low 32-bits. When all packets are consumed, read and\n     * write pointers should have the same value.\n     */\n    return *m_Resources.Queue_write_ptr;\n}\n\nvoid SDMAQueue::SubmitPacket() {\n    // m_pending Wptr is in dwords\n    if (m_FamilyId < FAMILY_AI) {\n        // Pre-Vega10 uses 32-bit wptr and doorbell\n        unsigned int wPtrInBytes = m_pendingWptr * sizeof(unsigned int);\n        MemoryBarrier();\n        *m_Resources.Queue_write_ptr = wPtrInBytes;\n        MemoryBarrier();\n        *(m_Resources.Queue_DoorBell) = wPtrInBytes;\n    } else {\n        // Vega10 and later uses 64-bit wptr and doorbell\n        HSAuint64 wPtrInBytes = m_pendingWptr64 * sizeof(unsigned int);\n        MemoryBarrier();\n        *m_Resources.Queue_write_ptr_aql = wPtrInBytes;\n        MemoryBarrier();\n        *(m_Resources.Queue_DoorBell_aql) = wPtrInBytes;\n    }\n}\n\nvoid SDMAQueue::Wait4PacketConsumption(HsaEvent *event, unsigned int timeOut) {\n    if (event) {\n        PlacePacket(SDMAFencePacket(m_FamilyId, (void*)event->EventData.HWData2, event->EventId));\n\n        PlaceAndSubmitPacket(SDMATrapPacket(event->EventId));\n\n        EXPECT_SUCCESS(hsaKmtWaitOnEvent(event, timeOut));\n    } else {\n        BaseQueue::Wait4PacketConsumption(NULL, timeOut);\n    }\n}\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/SDMAQueue.hpp",
    "content": "/*\n * Copyright (C) 2014-2018 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_SDMA_QUEUE__H__\n#define __KFD_SDMA_QUEUE__H__\n\n#include \"BaseQueue.hpp\"\n\nclass SDMAQueue : public BaseQueue {\n public:\n    SDMAQueue(void);\n    virtual ~SDMAQueue(void);\n\n    // @brief Update queue write pointer and set the queue doorbell to the queue write pointer\n    virtual void SubmitPacket();\n\n    /** Wait for all the packets submitted to the queue to be consumed. (i.e. wait until RPTR=WPTR).\n     *  Note that all packets being consumed is not the same as all packets being processed.\n     *  If event is set, wait all packets being processed.\n     *  And we can benefit from that as it has\n     *  1) Less CPU usage (process can sleep, waiting for interrupt).\n     *  2) Lower latency (GPU only updates RPTR in memory periodically).\n     */\n    virtual void Wait4PacketConsumption(HsaEvent *event = NULL, unsigned int timeOut = g_TestTimeOut);\n\n protected:\n    // @ return Write pointer modulo queue size in dwords\n    virtual unsigned int Wptr();\n    // @ return Read pointer modulo queue size in dwords\n    virtual unsigned int Rptr();\n    // @ return Expected m_Resources.Queue_read_ptr when all packets are consumed\n    virtual unsigned int RptrWhenConsumed();\n\n    virtual PACKETTYPE PacketTypeSupported() { return PACKETTYPE_SDMA; }\n\n    virtual _HSA_QUEUE_TYPE GetQueueType() { return HSA_QUEUE_SDMA; }\n};\n\n#endif  // __KFD_SDMA_QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/SDMAQueueByEngId.hpp",
    "content": "/*\n * Copyright (C) 2025 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_SDMA_QUEUE_BY_ENG_ID__H__\n#define __KFD_SDMA_QUEUE_BY_ENG_ID__H__\n\n#include \"SDMAQueue.hpp\"\n\nclass SDMAQueueByEngId : public SDMAQueue {\n public:\n    SDMAQueueByEngId(int engineId) {CMD_NOP = 0; m_SdmaEngineId = engineId;}\n    virtual ~SDMAQueueByEngId(void) {}\n protected:\n    virtual _HSA_QUEUE_TYPE GetQueueType() { return HSA_QUEUE_SDMA_BY_ENG_ID; }\n};\n\n#endif  // __KFD_SDMA_QUEUE_BY_ENG_ID__H__\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/ShaderStore.cpp",
    "content": "/*\n * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#include \"ShaderStore.hpp\"\n\n/**\n * KFDASMTest List\n */\n\nconst std::vector<const char*> ShaderList = {\n    NoopIsa,\n    CopyDwordIsa,\n    InfiniteLoopIsa,\n    AtomicIncIsa,\n    ScratchCopyDwordIsa,\n    PollMemoryIsa,\n    CopyOnSignalIsa,\n    PollAndCopyIsa,\n    WriteFlagAndValueIsa,\n    WriteAndSignalIsa,\n    LoopIsa,\n    PersistentIterateIsa,\n    ReadMemoryIsa,\n    GwsInitIsa,\n    GwsAtomicIncreaseIsa,\n    CheckCuMaskIsa\n};\n\n/**\n * Macros\n */\n\n#define SHADER_START \".text\\n\"\n\n/* Macros for portable v_add_co_u32, v_add_co_ci_u32,\n * and v_cmp_lt_u32.\n */\n#define SHADER_MACROS_U32 \\\n    \"   .text\\n\"\\\n    \"   .macro V_ADD_CO_U32 vdst, src0, vsrc1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number >= 10)\\n\"\\\n    \"           v_add_co_u32        \\\\vdst, vcc_lo, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .elseif (.amdgcn.gfx_generation_number >= 9)\\n\"\\\n    \"           v_add_co_u32        \\\\vdst, vcc, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .else\\n\"\\\n    \"           v_add_u32           \\\\vdst, vcc, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro V_ADD_CO_CI_U32 vdst, src0, vsrc1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number >= 10)\\n\"\\\n    \"           v_add_co_ci_u32     \\\\vdst, vcc_lo, \\\\src0, \\\\vsrc1, vcc_lo\\n\"\\\n    \"       .elseif (.amdgcn.gfx_generation_number >= 9)\\n\"\\\n    \"           v_addc_co_u32       \\\\vdst, vcc, \\\\src0, \\\\vsrc1, vcc\\n\"\\\n    \"       .else\\n\"\\\n    \"           v_addc_u32          \\\\vdst, vcc, \\\\src0, \\\\vsrc1, vcc\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro V_CMP_LT_U32 src0, vsrc1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number >= 10)\\n\"\\\n    \"           v_cmp_lt_u32        vcc_lo, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .else\\n\"\\\n    \"           v_cmp_lt_u32        vcc, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro V_CMP_EQ_U32 src0, vsrc1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number >= 10)\\n\"\\\n    \"           v_cmp_eq_u32        vcc_lo, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .else\\n\"\\\n    \"           v_cmp_eq_u32        vcc, \\\\src0, \\\\vsrc1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\n\n/* Macros for portable flat load/store/atomic instructions.\n *\n * gc943 (gfx94x) deprecates glc/slc in favour of nt/sc1/sc0.\n * The below macros when used will always use the nt sc1 sc0\n * modifiers for gfx94x, but also take in arg0 arg1 to specify\n * (for non-gfx94x): glc, slc, or glc slc.\n */\n#define SHADER_MACROS_FLAT \\\n    \"   .macro FLAT_LOAD_DWORD_NSS vdst, vaddr arg0 arg1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\\n\"\\\n    \"           flat_load_dword \\\\vdst, \\\\vaddr nt sc1 sc0\\n\"\\\n    \"       .else\\n\"\\\n    \"           flat_load_dword \\\\vdst, \\\\vaddr \\\\arg0 \\\\arg1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro FLAT_LOAD_DWORDX2_NSS vdst, vaddr arg0 arg1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\\n\"\\\n    \"           flat_load_dwordx2 \\\\vdst, \\\\vaddr nt sc1 sc0\\n\"\\\n    \"       .else\\n\"\\\n    \"           flat_load_dwordx2 \\\\vdst, \\\\vaddr \\\\arg0 \\\\arg1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro FLAT_STORE_DWORD_NSS vaddr, vsrc arg0 arg1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\\n\"\\\n    \"           flat_store_dword \\\\vaddr, \\\\vsrc nt sc1 sc0\\n\"\\\n    \"       .else\\n\"\\\n    \"           flat_store_dword \\\\vaddr, \\\\vsrc \\\\arg0 \\\\arg1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\\\n    \"   .macro FLAT_ATOMIC_ADD_NSS vdst, vaddr, vsrc arg0 arg1\\n\"\\\n    \"       .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\\n\"\\\n    \"           flat_atomic_add \\\\vdst, \\\\vaddr, \\\\vsrc nt sc1 sc0\\n\"\\\n    \"       .else\\n\"\\\n    \"           flat_atomic_add \\\\vdst, \\\\vaddr, \\\\vsrc \\\\arg0 \\\\arg1\\n\"\\\n    \"       .endif\\n\"\\\n    \"   .endm\\n\"\n\n/**\n * Common\n */\n\nconst char *NoopIsa =\n    SHADER_START\n    R\"(\n        s_endpgm\n)\";\n\nconst char *CopyDwordIsa =\n    SHADER_START\n    SHADER_MACROS_FLAT\n    R\"(\n        v_mov_b32 v0, s0\n        v_mov_b32 v1, s1\n        v_mov_b32 v2, s2\n        v_mov_b32 v3, s3\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORD_NSS v4, v[0:1] scope:SCOPE_SYS\n            s_wait_loadcnt 0\n            FLAT_STORE_DWORD_NSS v[2:3], v4 scope:SCOPE_SYS\n        .else\n            FLAT_LOAD_DWORD_NSS v4, v[0:1] glc slc\n            s_waitcnt 0\n            FLAT_STORE_DWORD_NSS v[2:3], v4 glc slc\n        .endif\n        s_endpgm\n)\";\n\nconst char *InfiniteLoopIsa =\n    SHADER_START\n    R\"(\n        .text\n        LOOP:\n        s_nop 0x10\n        s_branch LOOP\n        s_endpgm\n)\";\n\nconst char *AtomicIncIsa =\n    SHADER_START\n    SHADER_MACROS_FLAT\n    R\"(\n        v_mov_b32 v0, s0\n        v_mov_b32 v1, s1\n        .if (.amdgcn.gfx_generation_number >= 12)\n            v_mov_b32 v2, 1\n            FLAT_ATOMIC_ADD_NSS v3, v[0:1], v2 scope:SCOPE_SYS th:TH_ATOMIC_RETURN\n        .elseif (.amdgcn.gfx_generation_number >= 8)\n            v_mov_b32 v2, 1\n            FLAT_ATOMIC_ADD_NSS v3, v[0:1], v2 glc slc\n        .else\n            v_mov_b32 v2, -1\n            flat_atomic_inc v3, v[0:1], v2 glc slc\n        .endif\n        s_endpgm\n)\";\n\n/**\n * KFDMemoryTest\n */\n\nconst char *ScratchCopyDwordIsa =\n    SHADER_START\n    SHADER_MACROS_FLAT\n    R\"(\n        // Copy the parameters from scalar registers to vector registers\n        .if (.amdgcn.gfx_generation_number >= 9)\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            v_mov_b32 v2, s2\n            v_mov_b32 v3, s3\n        .else\n            v_mov_b32_e32 v0, s0\n            v_mov_b32_e32 v1, s1\n            v_mov_b32_e32 v2, s2\n            v_mov_b32_e32 v3, s3\n        .endif\n\n        // Setup the scratch parameters. This assumes a single 16-reg block\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_setreg_b32 hwreg(HW_REG_SCRATCH_BASE_LO), s4\n            s_setreg_b32 hwreg(HW_REG_SCRATCH_BASE_HI), s5\n        .elseif (.amdgcn.gfx_generation_number >= 10)\n            s_setreg_b32 hwreg(HW_REG_FLAT_SCR_LO), s4\n            s_setreg_b32 hwreg(HW_REG_FLAT_SCR_HI), s5\n        .elseif (.amdgcn.gfx_generation_number == 9)\n            s_mov_b32 flat_scratch_lo, s4\n            s_mov_b32 flat_scratch_hi, s5\n        .else\n            s_mov_b32 flat_scratch_lo, 8\n            s_mov_b32 flat_scratch_hi, 0\n        .endif\n\n        // Copy a dword between the passed addresses\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORD_NSS v4, v[0:1] scope:SCOPE_SYS\n            s_wait_loadcnt 0\n            FLAT_STORE_DWORD_NSS v[2:3], v4 scope:SCOPE_SYS\n        .else\n            FLAT_LOAD_DWORD_NSS v4, v[0:1] slc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            FLAT_STORE_DWORD_NSS v[2:3], v4 slc\n        .endif\n\n        s_endpgm\n)\";\n\n/* Continuously poll src buffer and check buffer value\n * After src buffer is filled with specific value (0x5678,\n * by host program), fill dst buffer with specific\n * value(0x5678) and quit\n */\nconst char *PollMemoryIsa =\n    SHADER_START\n    R\"(\n        // Assume src address in s0, s1, and dst address in s2, s3\n        s_movk_i32 s18, 0x5678\n        .if (.amdgcn.gfx_generation_number >= 10)\n            v_mov_b32 v0, s2\n            v_mov_b32 v1, s3\n            v_mov_b32 v2, 0x5678\n        .endif\n        LOOP:\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_load_dword s16, s[0:1], 0x0 scope:SCOPE_SYS\n        .else\n            s_load_dword s16, s[0:1], 0x0 glc\n        .endif\n        s_cmp_eq_i32 s16, s18\n        s_cbranch_scc0   LOOP\n        .if (.amdgcn.gfx_generation_number >= 12)\n            flat_store_dword v[0:1], v2 scope:SCOPE_SYS\n        .elseif (.amdgcn.gfx_generation_number >= 10)\n            flat_store_dword v[0:1], v2 slc\n        .else\n            s_store_dword s18, s[2:3], 0x0 glc\n        .endif\n        s_endpgm\n)\";\n\n/* Similar to PollMemoryIsa except that the buffer\n * polled can be Non-coherant memory. SCC system-level\n * cache coherence is not supported in scalar (smem) path.\n * Use vmem operations with scc\n */\nconst char *PollNCMemoryIsa =\n    SHADER_START\n    R\"(\n        // Assume src address in s0, s1, and dst address in s2, s3\n        v_mov_b32 v6, 0x5678\n        v_mov_b32 v0, s0\n        v_mov_b32 v1, s1\n        LOOP:\n        flat_load_dword v4, v[0:1] scc\n        v_cmp_eq_u32 vcc, v4, v6\n        s_cbranch_vccz   LOOP\n        v_mov_b32 v0, s2\n        v_mov_b32 v1, s3\n        flat_store_dword v[0:1], v6 scc\n        s_endpgm\n)\";\n\n/* Input: A buffer of at least 3 dwords.\n * DW0: used as a signal. 0xcafe means it is signaled\n * DW1: Input buffer for device to read.\n * DW2: Output buffer for device to write.\n * Once receive signal, device will copy DW1 to DW2\n * This shader continously poll the signal buffer,\n * Once signal buffer is signaled, it copies input buffer\n * to output buffer\n */\nconst char *CopyOnSignalIsa =\n    SHADER_START\n    R\"(\n        // Assume input buffer in s0, s1\n        .if (.amdgcn.gfx_generation_number >= 10)\n            s_add_u32 s2, s0, 0x8\n            s_addc_u32 s3, s1, 0x0\n            s_mov_b32 s18, 0xcafe\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            v_mov_b32 v4, s2\n            v_mov_b32 v5, s3\n        .else\n            s_mov_b32 s18, 0xcafe\n        .endif\n\n        .if (.amdgcn.gfx_generation_number >= 12)\n\n            POLLSIGNAL:\n            s_load_dword s16, s[0:1], 0x0 scope:SCOPE_SYS\n            s_cmp_eq_i32 s16, s18\n            s_cbranch_scc0   POLLSIGNAL\n\n            s_load_dword s17, s[0:1], 0x4 scope:SCOPE_SYS\n            s_wait_kmcnt 0\n\n            v_mov_b32 v2, s17\n            flat_store_dword v[4:5], v2 scope:SCOPE_SYS\n        .else\n\n            POLLSIGNAL:\n            s_load_dword s16, s[0:1], 0x0 glc\n            s_cmp_eq_i32 s16, s18\n            s_cbranch_scc0   POLLSIGNAL\n\n            s_load_dword s17, s[0:1], 0x4 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            .if (.amdgcn.gfx_generation_number >= 10)\n                v_mov_b32 v2, s17\n                flat_store_dword v[4:5], v2 glc\n            .else\n                s_store_dword s17, s[0:1], 0x8 glc\n            .endif\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n\n        .endif\n        s_endpgm\n)\";\n\n/* Continuously poll the flag at src buffer\n * After the flag of s[0:1] is 1 filled,\n * copy the value from s[0:1]+4 to dst buffer\n *\n * Note: Only works on GFX9 (only used in\n *       aldebaran tests)\n */\nconst char *PollAndCopyIsa =\n    SHADER_START\n    SHADER_MACROS_FLAT\n    R\"(\n        // Assume src buffer in s[0:1] and dst buffer in s[2:3]\n        // Path for Aldebaran, Aqua Vanjaram\n        .if (.amdgcn.gfx_generation_number == 9 && (.amdgcn.gfx_generation_minor >= 4 || .amdgcn.gfx_generation_stepping == 10))\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            v_mov_b32 v18, 0x1\n            LOOP0:\n            FLAT_LOAD_DWORD_NSS v16, v[0:1] glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            v_cmp_eq_i32 vcc, v16, v18\n            s_cbranch_vccz LOOP0\n            .if (.amdgcn.gfx_generation_minor >= 4)\n                buffer_inv sc1 sc0\n            .else\n                buffer_invl2\n            .endif\n            s_load_dword s17, s[0:1], 0x4 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            s_store_dword s17, s[2:3], 0x0 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            buffer_wbl2\n        .elseif (.amdgcn.gfx_generation_number == 9)\n            s_movk_i32 s18, 0x1\n            LOOP1:\n            s_load_dword s16, s[0:1], 0x0 glc\n            s_cmp_eq_i32 s16, s18\n            s_cbranch_scc0 LOOP1\n            s_load_dword s17, s[0:1], 0x4 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            s_store_dword s17, s[2:3], 0x0 glc\n        .endif\n        s_waitcnt vmcnt(0) & lgkmcnt(0)\n        s_endpgm\n)\";\n\n/* Input0: A buffer of at least 2 dwords.\n * DW0: used as a signal. Write 0x1 to signal\n * DW1: Write the value from 2nd input buffer\n *      for other device to read.\n * Input1: A buffer of at least 2 dwords.\n * DW0: used as the value to be written.\n *\n * Note: Only works on Aldebaran and Aqua Vanjaram\n */\nconst char *WriteFlagAndValueIsa =\n    SHADER_START\n    SHADER_MACROS_FLAT\n    R\"(\n        // Assume two inputs buffer in s[0:1] and s[2:3]\n        .if (.amdgcn.gfx_generation_number == 9 && (.amdgcn.gfx_generation_minor >= 4 || .amdgcn.gfx_generation_stepping == 10))\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            s_load_dword s18, s[2:3], 0x0 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            s_store_dword s18, s[0:1], 0x4 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            buffer_wbl2\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            v_mov_b32 v16, 0x1\n            FLAT_STORE_DWORD_NSS v[0:1], v16 glc\n        .endif\n        s_endpgm\n)\";\n\n/* Input0: A buffer of at least 2 dwords.\n * DW0: used as a signal. Write 0xcafe to signal\n * DW1: Write to this buffer for other device to read.\n * Input1: mmio base address\n */\nconst char *WriteAndSignalIsa =\n    SHADER_START\n    R\"(\n        // Assume input buffer in s0, s1\n        .if (.amdgcn.gfx_generation_number >= 10)\n            s_add_u32 s4, s0, 0x4\n            s_addc_u32 s5, s1, 0x0\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            v_mov_b32 v2, s2\n            v_mov_b32 v3, s3\n            v_mov_b32 v4, s4\n            v_mov_b32 v5, s5\n            .if (.amdgcn.gfx_generation_number >= 12)\n                v_mov_b32 v18, 0xbeef\n                flat_store_dword v[4:5], v18 scope:SCOPE_SYS\n                v_mov_b32 v18, 0x1\n                flat_store_dword v[2:3], v18 scope:SCOPE_SYS\n                v_mov_b32 v18, 0xcafe\n                flat_store_dword v[0:1], v18 scope:SCOPE_SYS\n            .else\n                v_mov_b32 v18, 0xbeef\n                flat_store_dword v[4:5], v18 glc\n                v_mov_b32 v18, 0x1\n                flat_store_dword v[2:3], v18 glc\n                v_mov_b32 v18, 0xcafe\n                flat_store_dword v[0:1], v18 glc\n            .endif\n        .else\n            s_mov_b32 s18, 0xbeef\n            s_store_dword s18, s[0:1], 0x4 glc\n            s_mov_b32 s18, 0x1\n            s_store_dword s18, s[2:3], 0 glc\n            s_mov_b32 s18, 0xcafe\n            s_store_dword s18, s[0:1], 0x0 glc\n        .endif\n        s_endpgm\n)\";\n\n/* Input:\n * s[0:1], A buffer of at least 64 * 6 bytes\n *\n * Store the value 0x77 at the 5 addresses 0x40,\n * 0x80, ..., 0x140 in the buffer\n *\n * Aqua Vanjaram only\n */\nconst char *FlushBufferForAcquireReleaseIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n            s_mov_b32 s11, 0x77\n            s_mov_b32 s12, 0x0\n            // Store some data on 5 different cache lines\n            s_store_dword s12, s[0:1], 0x0 glc\n            s_store_dword s11, s[0:1], 0x40 glc\n            s_store_dword s11, s[0:1], 0x80 glc\n            s_store_dword s11, s[0:1], 0xc0 glc\n            s_store_dword s11, s[0:1], 0x100 glc\n            s_store_dword s11, s[0:1], 0x140 glc\n            s_waitcnt lgkmcnt(0)\n        .endif\n        s_endpgm\n)\";\n\n/* Input:\n * s[0:1], A buffer of at least 64 * 6 bytes,\n * shared with the acquiring shader\n *\n * Store the values 1 - 5 at the 5 addresses 0x40,\n * 0x80, ..., 0x140 in the buffer, then signal\n * the flag at address 0x0 in the buffer.\n *\n * Uses vector stores\n *\n * Aqua Vanjaram only\n */\nconst char *WriteReleaseVectorIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n            v_mov_b32 v11, 0x1\n            v_mov_b32 v12, 0x2\n            v_mov_b32 v13, 0x3\n            v_mov_b32 v14, 0x4\n            v_mov_b32 v15, 0x5\n            v_mov_b32 v21, 0x40\n            v_mov_b32 v22, 0x80\n            v_mov_b32 v23, 0xc0\n            v_mov_b32 v24, 0x100\n            v_mov_b32 v25, 0x140\n            // Store some data on 5 different cache lines\n            global_store_dword v21, v11, s[0:1]\n            global_store_dword v22, v12, s[0:1]\n            global_store_dword v23, v13, s[0:1]\n            global_store_dword v24, v14, s[0:1]\n            global_store_dword v25, v15, s[0:1] nt sc1 sc0\n            s_waitcnt vmcnt(0)\n            // Write-Release\n            s_mov_b32 s16, 0x1\n            buffer_wbl2 sc1 sc0\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            s_store_dword s16, s[0:1], 0x0 glc\n        .endif\n        s_endpgm\n)\";\n\n/* Input:\n * s[0:1], A buffer of at least 64 * 6 bytes,\n * shared with the acquiring shader\n *\n * Store the values 6 - 10 at the 5 addresses 0x40,\n * 0x80, ..., 0x140 in the buffer, then signal\n * the flag at address 0x0 in the buffer.\n *\n * Uses scalar stores\n *\n * Aqua Vanjaram only\n */\nconst char *WriteReleaseScalarIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n            s_mov_b32 s11, 0x6\n            s_mov_b32 s12, 0x7\n            s_mov_b32 s13, 0x8\n            s_mov_b32 s14, 0x9\n            s_mov_b32 s15, 0xa\n            // Store some data on 5 different cache lines\n            s_store_dword s11, s[0:1], 0x40\n            s_store_dword s12, s[0:1], 0x80\n            s_store_dword s13, s[0:1], 0xc0\n            s_store_dword s14, s[0:1], 0x100\n            s_store_dword s15, s[0:1], 0x140 glc\n            s_waitcnt lgkmcnt(0)\n            // Write-Release\n            s_dcache_wb // WB Scalar L1 cache\n            s_mov_b32 s16, 0x1\n            buffer_wbl2 sc1 sc0\n            s_waitcnt vmcnt(0) & lgkmcnt(0)\n            s_store_dword s16, s[0:1], 0x0 glc\n            s_waitcnt lgkmcnt(0)\n        .endif\n        s_endpgm\n)\";\n\n/* Input:\n * s[0:1], A buffer of at least 64 * 6 bytes,\n * shared with the releasing shader\n * s[2:3], A buffer of at least 64 * 6 bytes,\n * accessible by the CPU, used for output\n *\n * Polls the flag at address 0x0 in the shared buffer.\n * When the signal is received, read the values\n * at the 5 addresses 0x40, 0x80, ... 0x140,\n * and store them at the same locations in\n * the output buffer\n *\n * Uses vector loads\n *\n * Aqua Vanjaram only\n */\nconst char *ReadAcquireVectorIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n            // Read-Acquire\n            s_mov_b32 s18, 0x1\n            LOOP:\n            s_load_dword s17, s[0:1], 0x0 glc\n            s_waitcnt lgkmcnt(0)\n            s_cmp_eq_i32 s17, s18\n            s_cbranch_scc0 LOOP\n            buffer_inv sc1 sc0\n            // Load data\n            v_mov_b32 v21, 0x40\n            v_mov_b32 v22, 0x80\n            v_mov_b32 v23, 0xc0\n            v_mov_b32 v24, 0x100\n            v_mov_b32 v25, 0x140\n            global_load_dword v11, v21, s[0:1]\n            global_load_dword v12, v22, s[0:1]\n            global_load_dword v13, v23, s[0:1]\n            global_load_dword v14, v24, s[0:1]\n            global_load_dword v15, v25, s[0:1]\n            s_waitcnt vmcnt(0)\n            // Store data for output\n            v_mov_b32 v21, 0x40\n            v_mov_b32 v22, 0x80\n            v_mov_b32 v23, 0xc0\n            v_mov_b32 v24, 0x100\n            v_mov_b32 v25, 0x140\n            global_store_dword v21, v11, s[2:3] nt sc1 sc0\n            global_store_dword v22, v12, s[2:3] nt sc1 sc0\n            global_store_dword v23, v13, s[2:3] nt sc1 sc0\n            global_store_dword v24, v14, s[2:3] nt sc1 sc0\n            global_store_dword v25, v15, s[2:3] nt sc1 sc0\n            s_waitcnt vmcnt(0)\n        .endif\n        s_endpgm\n)\";\n\n/* Input:\n * s[0:1], A buffer of at least 64 * 6 bytes,\n * shared with the releasing shader\n * s[2:3], A buffer of at least 64 * 6 bytes,\n * accessible by the CPU, used for output\n *\n * Polls the flag at address 0x0 in the shared buffer.\n * When the signal is received, read the values\n * at the 5 addresses 0x40, 0x80, ... 0x140,\n * and store them at the same locations in\n * the output buffer\n *\n * Uses scalar loads\n *\n * Aqua Vanjaram only\n */\nconst char *ReadAcquireScalarIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n            // Read-Acquire\n            s_mov_b32 s18, 0x1\n            LOOP:\n            s_load_dword s17, s[0:1], 0x0 glc\n            s_waitcnt lgkmcnt(0)\n            s_cmp_eq_i32 s17, s18\n            s_cbranch_scc0 LOOP\n            buffer_inv sc1 sc0\n            // Load data\n            s_load_dword s21, s[0:1], 0x40\n            s_load_dword s22, s[0:1], 0x80\n            s_load_dword s23, s[0:1], 0xc0\n            s_load_dword s24, s[0:1], 0x100\n            s_load_dword s25, s[0:1], 0x140\n            s_waitcnt lgkmcnt(0)\n            // Store data for output\n            s_store_dword s21, s[2:3], 0x40 glc\n            s_store_dword s22, s[2:3], 0x80 glc\n            s_store_dword s23, s[2:3], 0xc0 glc\n            s_store_dword s24, s[2:3], 0x100 glc\n            s_store_dword s25, s[2:3], 0x140 glc\n            s_waitcnt lgkmcnt(0)\n        .endif\n        s_endpgm\n)\";\n\n/**\n * KFDQMTest\n */\n\n/* A simple isa loop program with dense mathematic operations\n * s1 controls the number iterations of the loop\n * This shader can be used by GFX8, GFX9 and GFX10\n */\nconst char *LoopIsa =\n    SHADER_START\n    R\"(\n        s_movk_i32    s0, 0x0008\n        s_movk_i32    s1, 0x00ff\n        s_mov_b32     s4, 0\n        s_mov_b32     s5, 0\n        s_mov_b32     s6, 0\n        s_mov_b32     s7, 0\n        s_mov_b32     s12, 0\n        s_mov_b32     s13, 0\n        s_mov_b32     s14, 0\n        s_mov_b32     s15, 0\n        v_mov_b32     v0, 0\n        v_mov_b32     v1, 0\n        v_mov_b32     v2, 0\n        v_mov_b32     v3, 0\n        v_mov_b32     v4, 0\n        v_mov_b32     v5, 0\n        v_mov_b32     v6, 0\n        v_mov_b32     v7, 0\n        v_mov_b32     v8, 0\n        v_mov_b32     v9, 0\n        v_mov_b32     v10, 0\n        v_mov_b32     v11, 0\n        v_mov_b32     v12, 0\n        v_mov_b32     v13, 0\n        v_mov_b32     v14, 0\n        v_mov_b32     v15, 0\n        v_mov_b32     v16, 0\n        LOOP:\n        s_mov_b32     s8, s4\n        s_mov_b32     s9, s1\n        s_mov_b32     s10, s6\n        s_mov_b32     s11, s7\n        s_cmp_le_i32  s1, s0\n        s_cbranch_scc1  END_OF_PGM\n        v_add_f32     v0, 2.0, v0\n        v_cvt_f32_i32 v17, s1\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_wait_dscnt     0\n            s_wait_kmcnt     0\n        .else\n            s_waitcnt lgkmcnt(0)\n        .endif\n        v_add_f32     v18, s8, v17\n        v_add_f32     v19, s9, v17\n        v_add_f32     v20, s10, v17\n        v_add_f32     v21, s11, v17\n        v_add_f32     v22, s12, v17\n        v_add_f32     v23, s13, v17\n        v_add_f32     v24, s14, v17\n        v_add_f32     v17, s15, v17\n        v_log_f32     v25, v18\n        v_mul_f32     v25, v22, v25\n        v_exp_f32     v25, v25\n        v_log_f32     v26, v19\n        v_mul_f32     v26, v23, v26\n        v_exp_f32     v26, v26\n        v_log_f32     v27, v20\n        v_mul_f32     v27, v24, v27\n        v_exp_f32     v27, v27\n        v_log_f32     v28, v21\n        v_mul_f32     v28, v17, v28\n        v_exp_f32     v28, v28\n        v_add_f32     v5, v5, v25\n        v_add_f32     v6, v6, v26\n        v_add_f32     v7, v7, v27\n        v_add_f32     v8, v8, v28\n        v_mul_f32     v18, 0x3fb8aa3b, v18\n        v_exp_f32     v18, v18\n        v_mul_f32     v19, 0x3fb8aa3b, v19\n        v_exp_f32     v19, v19\n        v_mul_f32     v20, 0x3fb8aa3b, v20\n        v_exp_f32     v20, v20\n        v_mul_f32     v21, 0x3fb8aa3b, v21\n        v_exp_f32     v21, v21\n        v_add_f32     v9, v9, v18\n        v_add_f32     v10, v10, v19\n        v_add_f32     v11, v11, v20\n        v_add_f32     v12, v12, v21\n        v_sqrt_f32    v18, v22\n        v_sqrt_f32    v19, v23\n        v_sqrt_f32    v20, v24\n        v_sqrt_f32    v21, v17\n        v_add_f32     v13, v13, v18\n        v_add_f32     v14, v14, v19\n        v_add_f32     v15, v15, v20\n        v_add_f32     v16, v16, v21\n        v_rsq_f32     v18, v22\n        v_rsq_f32     v19, v23\n        v_rsq_f32     v20, v24\n        v_rsq_f32     v17, v17\n        v_add_f32     v1, v1, v18\n        v_add_f32     v2, v2, v19\n        v_add_f32     v3, v3, v20\n        v_add_f32     v4, v4, v17\n        s_add_u32     s0, s0, 1\n        s_branch      LOOP\n        END_OF_PGM:\n        s_endpgm\n)\";\n\n\n/**\n * KFDCWSRTest\n */\n\n/* Initial state:\n *   s[0:1] - input buffer base address\n *   s[2:3] - output buffer base address\n *   s4 - workgroup id\n *   v0 - workitem id\n * Registers:\n *   v0 - calculated workitem = v0 + s4 * NUM_THREADS_X, which is s4\n *   v[4:5] - corresponding output buf address: s[2:3] + v0 * 4\n *   v6 - register storing known-value output for mangle testing\n *   v7 - counter\n */\nconst char *PersistentIterateIsa =\n    SHADER_START\n    SHADER_MACROS_U32\n    SHADER_MACROS_FLAT\n    R\"(\n        // Compute address of output buffer\n        .if (.amdgcn.gfx_generation_number >= 12)\n            v_mov_b32               v0, ttmp9   // use workgroup id as index\n        .else\n            v_mov_b32               v0, s4      // use workgroup id as index\n        .endif\n        v_lshlrev_b32           v0, 2, v0       // v0 *= 4\n        V_ADD_CO_U32            v4, s2, v0      // v[4:5] = s[2:3] + v0 * 4\n        v_mov_b32               v5, s3          // v[4:5] = s[2:3] + v0 * 4\n        V_ADD_CO_CI_U32         v5, v5, 0       // v[4:5] = s[2:3] + v0 * 4\n\n        // Store known-value output in register\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORD_NSS     v6, v[4:5] scope:SCOPE_SYS\n            s_wait_loadcnt 0                        // wait for memory reads to finish\n        .else\n            FLAT_LOAD_DWORD_NSS     v6, v[4:5] glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)         // wait for memory reads to finish\n        .endif\n\n        // Initialize counter\n        v_mov_b32               v7, 0\n\n        LOOP:\n        flat_store_dword        v[4:5], v6      // store known-val in output\n        V_ADD_CO_U32            v7, 1, v7       // increment counter\n\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_load_dword            s6, s[0:1], 0 scope:SCOPE_SYS\n            s_wait_loadcnt 0                        // wait for memory reads to finish\n        .else\n            s_load_dword            s6, s[0:1], 0 glc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)         // wait for memory reads to finish\n        .endif\n        s_cmp_eq_i32            s6, 0x12345678  // compare input buf to stopval\n        s_cbranch_scc1          L_QUIT          // branch if notified to quit by host\n\n        s_branch LOOP\n\n        L_QUIT:\n        s_endpgm\n)\";\n\n/**\n * KFDEvictTest\n */\n\n/* Shader to read local buffers using multiple wavefronts in parallel\n * until address buffer is filled with specific value 0x5678 by host program,\n * then each wavefront fills value 0x5678 at corresponding result buffer and quit\n *\n * Initial state:\n *   s[0:1]   - address buffer base address\n *   s[2:3]   - result buffer base address\n *   s4/ttmp9 - workgroup id (in s4 pre-GFX12, in ttmp9 on GFX12)\n *   v0       - workitem id, always 0 because NUM_THREADS_X(number of threads) in workgroup set to 1\n * Registers:\n *   v0 - calculated workitem id, v0 = v0 + s4 * NUM_THREADS_X\n *   v[2:3] - address of corresponding local buf address offset: s[0:1] + v0 * 8\n *   v[4:5] - corresponding output buf address: s[2:3] + v0 * 4\n *   v[6:7] - local buf address used for read test\n *   v11 - size of local buffer in MB\n */\nconst char *ReadMemoryIsa =\n    SHADER_START\n    SHADER_MACROS_U32\n    SHADER_MACROS_FLAT\n    R\"(\n        // Compute address of corresponding output buffer\n        .if (.amdgcn.gfx_generation_number >= 12)\n            v_mov_b32           v0, ttmp9       // use workgroup id as index\n        .else\n            v_mov_b32           v0, s4          // use workgroup id as index\n        .endif\n        v_lshlrev_b32           v0, 2, v0       // v0 *= 4\n        V_ADD_CO_U32            v4, s2, v0      // v[4:5] = s[2:3] + v0 * 4\n        v_mov_b32               v5, s3          // v[4:5] = s[2:3] + v0 * 4\n        V_ADD_CO_CI_U32         v5, v5, 0       // v[4:5] = s[2:3] + v0 * 4\n\n        // Compute input buffer offset used to store corresponding local buffer address\n        v_lshlrev_b32           v0, 1, v0       // v0 *= 8\n        V_ADD_CO_U32            v2, s0, v0      // v[2:3] = s[0:1] + v0 * 8\n        v_mov_b32               v3, s1          // v[2:3] = s[0:1] + v0 * 8\n        V_ADD_CO_CI_U32         v3, v3, 0       // v[2:3] = s[0:1] + v0 * 8\n\n        // Load local buffer size from output buffer\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORD_NSS     v11, v[4:5] scope:SCOPE_DEV\n        .else\n            FLAT_LOAD_DWORD_NSS     v11, v[4:5] slc\n        .endif\n\n        // Load 64bit local buffer address stored at v[2:3] to v[6:7]\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORDX2_NSS   v[6:7], v[2:3] scope:SCOPE_DEV\n            s_wait_loadcnt 0\n        .else\n            FLAT_LOAD_DWORDX2_NSS   v[6:7], v[2:3] slc\n            s_waitcnt vmcnt(0) & lgkmcnt(0)         // wait for memory reads to finish\n        .endif\n        v_mov_b32               v8, 0x5678\n        s_movk_i32              s8, 0x5678\n        L_REPEAT:\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_load_dword        s16, s[0:1], 0x0 scope:SCOPE_SYS\n            s_wait_kmcnt        0                      // wait for memory reads to finish\n        .else\n            s_load_dword        s16, s[0:1], 0x0 glc\n            s_waitcnt           vmcnt(0) & lgkmcnt(0)  // wait for memory reads to finish\n        .endif\n        s_cmp_eq_i32            s16, s8\n        s_cbranch_scc1          L_QUIT          // if notified to quit by host\n\n        // Loop read local buffer starting at v[6:7]\n        // every 4k page only read once\n        v_mov_b32               v9, 0\n        v_mov_b32               v10, 0x1000     // 4k page\n        v_mov_b32               v12, v6\n        v_mov_b32               v13, v7\n        L_LOOP_READ:\n        .if (.amdgcn.gfx_generation_number >= 12)\n            FLAT_LOAD_DWORDX2_NSS   v[14:15], v[12:13] scope:SCOPE_DEV\n        .else\n            FLAT_LOAD_DWORDX2_NSS   v[14:15], v[12:13] slc\n        .endif\n        V_ADD_CO_U32            v9, v9, v10\n        V_ADD_CO_U32            v12, v12, v10\n        V_ADD_CO_CI_U32         v13, v13, 0\n        V_CMP_LT_U32            v9, v11\n        s_cbranch_vccnz         L_LOOP_READ\n        s_branch                L_REPEAT\n        L_QUIT:\n        flat_store_dword        v[4:5], v8\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_wait_storecnt     0\n        .else\n            s_waitcnt vmcnt(0) & lgkmcnt(0)         // wait for memory writes to finish\n        .endif\n        s_endpgm\n)\";\n\n/**\n * KFDGWSTest\n */\n\n/* Shader to initialize gws counter to 1 */\nconst char *GwsInitIsa =\n    SHADER_START\n    R\"(\n        .if (.amdgcn.gfx_generation_number >= 12)\n        .else\n            s_mov_b32 m0, 0\n            s_nop 0\n            s_load_dword s16, s[0:1], 0x0 glc\n            s_waitcnt 0\n            v_mov_b32 v0, s16\n            s_waitcnt 0\n            ds_gws_init v0 offset:0 gds\n            s_waitcnt 0\n            s_endpgm\n        .endif\n)\";\n\n/* Atomically increase a value in memory\n * This is expected to be executed from\n * multiple work groups simultaneously.\n * GWS semaphore is used to guarantee\n * the operation is atomic.\n */\nconst char *GwsAtomicIncreaseIsa =\n    SHADER_START\n    R\"(\n        // Assume src address in s0, s1\n        .if (.amdgcn.gfx_generation_number >= 12)\n        .elseif (.amdgcn.gfx_generation_number >= 10)\n            s_mov_b32 m0, 0\n            s_mov_b32 exec_lo, 0x1\n            v_mov_b32 v0, s0\n            v_mov_b32 v1, s1\n            ds_gws_sema_p offset:0 gds\n            s_waitcnt 0\n            flat_load_dword v2, v[0:1] glc dlc\n            s_waitcnt 0\n            v_add_nc_u32 v2, v2, 1\n            flat_store_dword v[0:1], v2\n            s_waitcnt_vscnt null, 0\n            ds_gws_sema_v offset:0 gds\n        .else\n            s_mov_b32 m0, 0\n            s_nop 0\n            ds_gws_sema_p offset:0 gds\n            s_waitcnt 0\n            s_load_dword s16, s[0:1], 0x0 glc\n            s_waitcnt 0\n            s_add_u32 s16, s16, 1\n            s_store_dword s16, s[0:1], 0x0 glc\n            s_waitcnt lgkmcnt(0)\n            ds_gws_sema_v offset:0 gds\n        .endif\n        s_waitcnt 0\n        s_endpgm\n)\";\n\n\n/*\n * Shader used by ExtendedCuMasking test case to check if CU mask is used correctly.\n *\n * Shader will write to output buffer the (SE, SA, WGP) used by the wave.\n * The test program will then analyse the data.\n *\n * Inputs\n * ------\n * s[2:3]  : output buffer base address\n * s4/ttmp9: workgroup id (s4 for pre-GFX12, ttmp9 for GFX12)\n *\n * Output\n * ------\n * Store HW_ID1 content in output buffer at index corresponding to workgroup id.\n *\n */\nconst char *CheckCuMaskIsa =\n    SHADER_START\n    SHADER_MACROS_U32\n    SHADER_MACROS_FLAT\n    R\"(\n        // Get workgroup id\n        .if (.amdgcn.gfx_generation_number >= 12)\n            v_mov_b32    v0, ttmp9\n        .else\n            v_mov_b32    v0, s4\n        .endif\n\n        // Address of output buffer element: v[4:5] = s[2:3] + v0 * 4\n        v_lshlrev_b32    v6, 2, v0\n        V_ADD_CO_U32     v4, s2, v6\n        v_mov_b32        v5, s3\n        V_ADD_CO_CI_U32  v5, v5, 0\n\n        // Store HW_ID1 content\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_getreg_b32     s6, hwreg(HW_REG_HW_ID1)\n        .else\n            s_getreg_b32     s6, hwreg(HW_REG_HW_ID)\n        .endif\n        v_mov_b32        v1, s6\n        flat_store_dword v[4:5], v1\n\n        s_endpgm\n)\";\n\n\nconst char *JumpToTrapIsa =\n    SHADER_START\n    SHADER_MACROS_U32\n    R\"(\n        /*copy the parameters from scalar registers to vector registers*/\n        v_mov_b32 v4, 0\n        v_mov_b32 v0, s0\n        v_mov_b32 v1, s1\n        s_trap 1\n        EXIT_LOOP:\n        V_CMP_EQ_U32 v4, 0\n        s_cbranch_vccnz EXIT_LOOP\n        flat_store_dword v[0:1], v4\n        s_waitcnt vmcnt(0)&lgkmcnt(0)\n        s_endpgm\n)\";\n\nconst char *TrapHandlerIsa =\n    SHADER_START\n    R\"(\n        CHECK_VMFAULT:\n        /*if trap jumped to by vmfault, restore skip m0 signalling*/\n        .if (.amdgcn.gfx_generation_number < 12)\n            s_getreg_b32 ttmp14, hwreg(HW_REG_TRAPSTS)\n            s_and_b32 ttmp2, ttmp14, 0x800\n        .else\n            s_getreg_b32 ttmp14, hwreg(HW_REG_EXCP_FLAG_PRIV)\n            s_and_b32 ttmp2, ttmp14, 0x10\n        .endif\n        s_cbranch_scc1 RESTORE_AND_EXIT\n        /*check for address watch event and record pc check point delta*/\n        .if (.amdgcn.gfx_generation_number < 12)\n            s_and_b32 ttmp2, ttmp14, 0x7080\n        .else\n            s_and_b32 ttmp2, ttmp14, 0xf\n        .endif\n        s_cbranch_scc0 GET_DOORBELL\n        v_mov_b32 v5, v4 // capture watch checkpoint\n        v_mov_b32 v6, ttmp14 // capture watch trapsts\n        s_branch RESTORE_AND_EXIT\n        GET_DOORBELL:\n        .if .amdgcn.gfx_generation_number < 11\n            s_mov_b32 ttmp2, exec_lo\n            s_mov_b32 ttmp3, exec_hi\n            s_mov_b32 exec_lo, 0x80000000\n            s_sendmsg 10\n            WAIT_SENDMSG:\n            /*wait until msb is cleared (i.e. doorbell fetched)*/\n            s_nop 7\n            s_bitcmp0_b32 exec_lo, 0x1F\n            s_cbranch_scc0 WAIT_SENDMSG\n            /* restore exec */\n            s_mov_b32 exec_hi, ttmp3\n            s_and_b32 exec_lo, exec_lo, 0xfff\n            s_mov_b32 ttmp3, exec_lo\n            s_mov_b32 exec_lo, ttmp2\n        .else\n            s_sendmsg_rtn_b32 ttmp3, sendmsg(MSG_RTN_GET_DOORBELL)\n            s_waitcnt lgkmcnt(0)\n            s_and_b32 ttmp3, ttmp3, 0x3ff\n        .endif\n        s_mov_b32 ttmp2, m0\n        s_or_b32 ttmp3, ttmp3, 0x800\n        /* set m0, send interrupt and restore m0 and exit trap*/\n        s_mov_b32 m0, ttmp3\n        s_nop 0x0\n        s_sendmsg sendmsg(MSG_INTERRUPT)\n        s_waitcnt lgkmcnt(0)\n        s_mov_b32 m0, ttmp2\n        v_mov_b32 v4, ttmp1\n        .if (.amdgcn.gfx_generation_number >= 12)\n            s_getreg_b32 ttmp14, hwreg(HW_REG_EXCP_FLAG_PRIV)\n            s_and_b32 ttmp2, ttmp14, 0x300\n            s_cbranch_scc1 RESTORE_AND_EXIT\n         .elseif (.amdgcn.gfx_generation_number == 11)\n            s_getreg_b32 ttmp14, hwreg(HW_REG_TRAPSTS)\n            s_and_b32 ttmp2, ttmp14, 0x30000\n            s_cbranch_scc1 RESTORE_AND_EXIT\n         .else\n            s_getreg_b32 ttmp14, hwreg(HW_REG_TRAPSTS)\n            s_and_b32 ttmp2, ttmp14, 0x1800000\n            s_cbranch_scc1 RESTORE_AND_EXIT\n         .endif\n        /* restore and increment program counter to skip shader trap jump*/\n        s_add_u32 ttmp0, ttmp0, 4\n        s_addc_u32 ttmp1, ttmp1, 0\n        s_and_b32 ttmp1, ttmp1, 0xffff\n        RESTORE_AND_EXIT:\n        /* restore SQ_WAVE_IB_STS */\n        s_lshr_b32 ttmp2, ttmp11, (26 - 15)\n        s_and_b32 ttmp2, ttmp2, (0x8000 | 0x1F0000)\n        s_setreg_b32 hwreg(HW_REG_IB_STS), ttmp2\n        /* restore SQ_WAVE_STATUS */\n        s_and_b64 exec, exec, exec\n        s_and_b64 vcc, vcc, vcc\n        s_setreg_b32 hwreg(HW_REG_STATUS), ttmp12\n        s_rfe_b64 [ttmp0, ttmp1]\n)\";\n\n#define WATCH_START SHADER_START SHADER_MACROS_U32\\\n    \"v_mov_b32 v0, s0\\n\"\\\n    \"v_mov_b32 v1, s1\\n\"\\\n    \"v_mov_b32 v2, s2\\n\"\\\n    \"v_mov_b32 v3, s3\\n\"\\\n    \"flat_load_dword v4, v[2:3]\\n\"\\\n    \"s_waitcnt vmcnt(0) & lgkmcnt(0)\\n\"\\\n    \"v_mov_b32 v5, 0\\n\"\\\n    \"v_mov_b32 v6, 0\\n\"\n\n#define WATCH_END \"\\n\"\\\n    \"v_mov_b32 v4, 2\\n\"\\\n    \"LOOP:\\n\"\\\n    \"V_CMP_EQ_U32 v6, 0\\n\"\\\n    \"s_cbranch_vccnz LOOP\\n\"\\\n    \"V_ADD_CO_U32 v6, v6, v5\\n\"\\\n    \"flat_store_dword v[2:3], v6\\n\"\\\n    \"s_waitcnt vmcnt(0) & lgkmcnt(0)\\n\"\\\n    \"s_endpgm\\n\"\n\nconst char *WatchReadIsa =\n    WATCH_START\n    \"flat_load_dword v7, v[0:1]\"\n    WATCH_END;\n\nconst char *WatchWriteIsa =\n    WATCH_START\n    \"flat_store_dword v[0:1], v4\"\n    WATCH_END;\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/ShaderStore.hpp",
    "content": "/*\n * Copyright (C) 2021 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef _SHADERSTORE_H_\n#define _SHADERSTORE_H_\n\n#include <vector>\n\n/* KFDASMTest List */\nextern const std::vector<const char*> ShaderList;\n\n/* Common */\nextern const char *NoopIsa;\nextern const char *CopyDwordIsa;\nextern const char *InfiniteLoopIsa;\nextern const char *AtomicIncIsa;\n\n/* KFDMemoryTest */\nextern const char *ScratchCopyDwordIsa;\nextern const char *PollMemoryIsa;\nextern const char *PollNCMemoryIsa;\nextern const char *CopyOnSignalIsa;\nextern const char *PollAndCopyIsa;\nextern const char *WriteFlagAndValueIsa;\nextern const char *WriteAndSignalIsa;\nextern const char *WriteReleaseVectorIsa;\nextern const char *WriteReleaseScalarIsa;\nextern const char *ReadAcquireVectorIsa;\nextern const char *ReadAcquireScalarIsa;\nextern const char *FlushBufferForAcquireReleaseIsa;\n\n/* KFDQMTest */\nextern const char *LoopIsa;\nextern const char *CheckCuMaskIsa;\n\n/* KFDCWSRTest */\nextern const char *PersistentIterateIsa;\n\n/* KFDEvictTest */\nextern const char *ReadMemoryIsa;\n\n/* KFDGWSTest */\nextern const char *GwsInitIsa;\nextern const char *GwsAtomicIncreaseIsa;\n\n/* HitTrapEvent */\nextern const char *JumpToTrapIsa;\nextern const char *TrapHandlerIsa;\n\n/* HitWatchPointEvent */\nextern const char *WatchReadIsa;\nextern const char *WatchWriteIsa;\nextern const char *WatchAtomicIsa;\n\n#endif  // _SHADERSTORE_H_\n"
  },
  {
    "path": "libhsakmt/tests/kfdtest/src/XgmiOptimizedSDMAQueue.hpp",
    "content": "/*\n * Copyright (C) 2014-2019 Advanced Micro Devices, Inc. All Rights Reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n#ifndef __KFD_XGMI_OPTIMIZED_SDMA_QUEUE__H__\n#define __KFD_XGMI_OPTIMIZED_SDMA_QUEUE__H__\n\n#include \"SDMAQueue.hpp\"\n\nclass XgmiOptimizedSDMAQueue : public SDMAQueue {\n public:\n    XgmiOptimizedSDMAQueue(void) {CMD_NOP = 0;}\n    virtual ~XgmiOptimizedSDMAQueue(void) {}\n protected:\n    virtual _HSA_QUEUE_TYPE GetQueueType() { return HSA_QUEUE_SDMA_XGMI; }\n};\n\n#endif  // __KFD_XGMI_OPTIMIZED_SDMA_QUEUE__H__\n"
  },
  {
    "path": "libhsakmt/tests/rdma/simple/app/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.6)\n\nproject (rdma_test)\n\nfind_package(PkgConfig)\npkg_check_modules(DRM REQUIRED libdrm)\npkg_check_modules(DRM_AMDGPU REQUIRED libdrm_amdgpu)\ninclude_directories(${DRM_AMDGPU_INCLUDE_DIRS})\n\nif( DEFINED ENV{LIBHSAKMT_PATH} )\n    set ( LIBHSAKMT_PATH $ENV{LIBHSAKMT_PATH} )\n    message ( \"LIBHSAKMT_PATH environment variable is set\" )\nelse()\n    if ( ${ROCM_INSTALL_PATH} )\n       set ( ENV{PKG_CONFIG_PATH} ${ROCM_INSTALL_PATH}/lib/pkgconfig )\n    else()\n       set ( ENV{PKG_CONFIG_PATH} /opt/rocm/lib/pkgconfig )\n    endif()\n\n    pkg_check_modules(HSAKMT libhsakmt)\n\n    if( NOT HSAKMT_FOUND )\n       set ( LIBHSAKMT_PATH $ENV{OUT_DIR} )\n    endif()\nendif()\n\nif( DEFINED LIBHSAKMT_PATH )\n    set ( HSAKMT_LIBRARY_DIRS ${LIBHSAKMT_PATH}/lib )\n    set ( HSAKMT_LIBRARIES hsakmt )\nendif()\n\n\nlink_directories(${HSAKMT_LIBRARY_DIRS})\n\ninclude_directories($ENV{LIBHSAKMT_ROOT}/include)\ninclude_directories(../drv)\n\nadd_executable(rdma_test rdma_test.cpp)\ntarget_link_libraries(rdma_test libhsakmt.a dl pthread numa drm drm_amdgpu)\n"
  },
  {
    "path": "libhsakmt/tests/rdma/simple/app/rdma_test.cpp",
    "content": "/*\n * Copyright 2015 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <sys/ioctl.h>\n#include <sys/mman.h>\n#include \"hsakmt/hsakmt.h\"\n#include \"amdp2ptest.h\"\n\nint rdma_fd = -1;\n\nvoid rdma_open()\n{\n    rdma_fd = open(AMDP2PTEST_DEVICE_PATH, O_RDWR);\n\n    if (-1 == rdma_fd ) {\n        int ret = errno;\n        fprintf(stderr, \"error opening driver (errno=%d/%s)\\n\", ret, strerror(ret));\n        exit(EXIT_FAILURE);\n    }\n}\n\nvoid rdma_close()\n{\n    int retcode = close(rdma_fd);\n\n    if (-1 == retcode) {\n        fprintf(stderr, \"error closing driver (errno=%d/%s)\\n\", retcode, strerror(retcode));\n        exit(EXIT_FAILURE);\n    }\n\n    rdma_fd = -1;\n}\n\nint rdma_map(uint64_t gpu_ptr, size_t size, void **cpu_ptr)\n{\n    int ret = 0;\n\n    *cpu_ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, rdma_fd, gpu_ptr);\n\n    if (*cpu_ptr == NULL) {\n        int __errno = errno;\n        *cpu_ptr = NULL;\n        fprintf(stderr, \"Can't BAR, error=%s(%d) size=%zu offset=%llx\\n\",\n                strerror(__errno), __errno, size, (long long unsigned)gpu_ptr);\n        ret = __errno;\n    }\n\n    return ret;\n}\n\nint rdma_unmap(void *cpu_ptr, size_t size)\n{\n    int ret = 0;\n\n    int retcode = munmap(cpu_ptr, size);\n\n    if (-1 == retcode) {\n        int __errno = errno;\n        fprintf(stderr, \"can't unmap BAR, error=%s(%d) size=%zu\\n\",\n                strerror(__errno), __errno, size);\n        ret = __errno;\n    }\n\n    return ret;\n}\n\nvoid run_rdma_tests(HSAuint32 Node, HsaMemoryProperties *MemoryProperty)\n{\n    printf(\"Size 0x%lx (%ld MB)\\n\", MemoryProperty->SizeInBytes,\n                                        MemoryProperty->SizeInBytes / (1024 * 1024));\n    printf(\"VirtualBaseAddress 0x%lx\\n\", MemoryProperty->VirtualBaseAddress);\n\n\n    void *cpu_ptr;\n    int ret = 0;\n    void *MemoryAddress = 0;\n    HSAuint64 SizeInBytes = 4096;\n    HsaMemFlags memFlags = {0};\n\n    memFlags.ui32.NonPaged    = 1;\n    memFlags.ui32.CachePolicy = HSA_CACHING_WRITECOMBINED;\n    memFlags.ui32.NoSubstitute = 1;\n    memFlags.ui32.PageSize     = HSA_PAGE_SIZE_4KB;\n//    memFlags.ui32.HostAccess   = 1;\n    memFlags.ui32.CoarseGrain  = 1;\n\n    HSAKMT_STATUS status = hsaKmtAllocMemory(Node,\n                                             SizeInBytes,\n                                             memFlags,\n                                             &MemoryAddress);\n\n    if (status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"Failure to allocate memory. Status %d\\n\", status);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"Memory allocated. Address 0x%p\\n\", MemoryAddress);\n\n    struct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM get_page_size = {0};\n    get_page_size.addr   = (uint64_t) MemoryAddress;\n    get_page_size.length = SizeInBytes;\n\n    ret = ioctl(rdma_fd, AMD2P2PTEST_IOCTL_GET_PAGE_SIZE, &get_page_size);\n\n    if (ret != 0)\n    {\n        fprintf(stderr,\n                \"AMD2P2PTEST_IOCTL_GET_PAGE_SIZE error (errno=%d/%s)\\n\",\n                ret, strerror(ret));\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"GPU Page size: 0x%ld\\n\", get_page_size.page_size);\n\n    struct AMDRDMA_IOCTL_GET_PAGES_PARAM get_cpu_ptr = {0};\n    get_cpu_ptr.addr    = (uint64_t) MemoryAddress;\n    get_cpu_ptr.length  = SizeInBytes;\n\n    ret = ioctl(rdma_fd, AMD2P2PTEST_IOCTL_GET_PAGES, &get_cpu_ptr);\n\n    if (ret != 0)\n    {\n        fprintf(stderr, \"AMD2P2PTEST_IOCTL_GET_PAGES error (errno=%d/%s)\\n\",\n                         ret, strerror(ret));\n        exit(EXIT_FAILURE);\n    }\n\n\n    ret = rdma_map((uint64_t)MemoryAddress, 4096, &cpu_ptr);\n\n    if (ret < 0)\n    {\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"CPU Virtual address 0x%p\\n\", cpu_ptr);\n\n    hsaKmtFreeMemory(MemoryAddress, SizeInBytes);\n}\n\nint getSysMemorySize(unsigned long *memSize)\n{\n    FILE *meminfo = fopen(\"/proc/meminfo\", \"r\");\n\n    if(meminfo == NULL)\n        return -1;\n\n    char buff[256];\n    while (fgets(buff, sizeof(buff), meminfo))\n    {\n        long ramKB;\n        if (sscanf(buff, \"MemTotal: %ld kB\", &ramKB) == 1)\n        {\n            *memSize = ramKB * 1024;\n            break;\n        }\n    }\n\n    fclose(meminfo);\n    printf(\"Total system memory size 0x%lx\\n\", *memSize);\n    return 0;\n}\n\n/*\n * RDMA contiguous memory allocation test\n *\n * Test steps:\n * 1. fragment the entire VRAM, alloc all VRAM using multiple buffers, then free 1 buffer from every\n      other buffers\n * 2. alloc memFlags.ui32.Contiguous=1 buffer for contiguous VRAM allocation\n * 3. Call AMD2P2PTEST_IOCTL_GET_PAGES to get contiguous VRAM buffer pages\n * 4. Test fails if any above step failed\n */\nvoid run_rdma_contiguous_mem_tests(HSAuint32 Node, HsaMemoryProperties *MemoryProperty)\n{\n    unsigned int *nullPtr = NULL;\n    unsigned long bufSize = 512ULL << 20;\n    unsigned long nBuf;\n\n    HSAuint64 vramSize;\n    unsigned long sysMemSize;\n    HsaMemFlags memFlags = {0};\n    HSAKMT_STATUS status;\n\n    if (getSysMemorySize(&sysMemSize) < 0) {\n        fprintf(stderr, \"Failed to get system memory size\\n\");\n        exit(EXIT_FAILURE);\n    }\n    status = hsaKmtAvailableMemory(Node, &vramSize);\n    if (status != HSAKMT_STATUS_SUCCESS) {\n        fprintf(stderr, \"Failed %d to get VRAM size\\n\", status);\n        exit(EXIT_FAILURE);\n    }\n    if (sysMemSize < (16UL << 30) || vramSize < (4UL << 30)) {\n        fprintf(stderr, \"No enough system memory or VRAM\\n\");\n        exit(0);\n    }\n    nBuf = vramSize / bufSize;\n\n    void **pBuf = (void **)malloc(sizeof(*pBuf) * nBuf);\n    memFlags.ui32.NonPaged = 1;\n\n    for (int i = 0; i < nBuf; i++) {\n        status = hsaKmtAllocMemory(Node, bufSize, memFlags, &pBuf[i]);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            fprintf(stderr, \"Failed %d to alloc buf %d\\n\", status, i);\n            exit(EXIT_FAILURE);\n        }\n\n        status = hsaKmtMapMemoryToGPU(pBuf[i], bufSize, NULL);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            fprintf(stderr, \"Failed %d to map buf %d\\n\", status, i);\n            exit(EXIT_FAILURE);\n        }\n    }\n\n    //printf(\"Freeing every other BO to fragment VRAM\\n\");\n    for (int i = 0; i < nBuf; i+=2) {\n        status = hsaKmtUnmapMemoryToGPU(pBuf[i]);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            fprintf(stderr, \"Failed %d to unmap buf %d from GPU\\n\", status, i);\n            exit(EXIT_FAILURE);\n        }\n        status = hsaKmtFreeMemory(pBuf[i], bufSize);\n        if (status != HSAKMT_STATUS_SUCCESS) {\n            fprintf(stderr, \"Failed %d to free buf %d\\n\", status, i);\n            exit(EXIT_FAILURE);\n        }\n    }\n\n    printf(\"Node %d Size 0x%lx (%ld MB)\\n\", Node, MemoryProperty->SizeInBytes,\n                                        MemoryProperty->SizeInBytes / (1024 * 1024));\n\n    void *cpu_ptr;\n    int ret = 0;\n    void *MemoryAddress = 0;\n    HSAuint64 SizeInBytes = 1UL <<  30;\n\n    memFlags.ui32.Contiguous = 1;\n\n    status = hsaKmtAllocMemory(Node, SizeInBytes, memFlags, &MemoryAddress);\n    if (status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"Failure to allocate memory 0x%lx. Status %d\\n\", SizeInBytes, status);\n        exit(EXIT_FAILURE);\n    }\n\n    status = hsaKmtMapMemoryToGPU(MemoryAddress, SizeInBytes, NULL);\n    if (status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"Failure to map memory. Status %d\\n\", status);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"VRAM allocated. Address %p size 0x%lx bytes\\n\", MemoryAddress, SizeInBytes);\n    //printf(\"Press Enter key to continue\\n\");\n    //getchar();\n\n    struct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM get_page_size = {0};\n    get_page_size.addr   = (uint64_t) MemoryAddress;\n    get_page_size.length = SizeInBytes;\n\n    ret = ioctl(rdma_fd, AMD2P2PTEST_IOCTL_GET_PAGE_SIZE, &get_page_size);\n    if (ret != 0)\n    {\n        fprintf(stderr, \"AMD2P2PTEST_IOCTL_GET_PAGE_SIZE error (errno=%d/%s)\\n\",\n                ret, strerror(ret));\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"GPU Page size: 0x%ld\\n\", get_page_size.page_size);\n\n    struct AMDRDMA_IOCTL_GET_PAGES_PARAM get_cpu_ptr = {0};\n    get_cpu_ptr.addr    = (uint64_t) MemoryAddress;\n    get_cpu_ptr.length  = SizeInBytes;\n\n    ret = ioctl(rdma_fd, AMD2P2PTEST_IOCTL_GET_PAGES, &get_cpu_ptr);\n    if (ret != 0)\n    {\n        fprintf(stderr, \"AMD2P2PTEST_IOCTL_GET_PAGES error (errno=%d/%s)\\n\",\n                         ret, strerror(ret));\n\t\t//printf(\"IOCTL_GET_PAGES failed, Press Enter key to continue\\n\");\n\t\t//getchar();\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"IOCTL_GET_PAGES return contiguous VRAM address %p size 0x%lx bytes\\n\", MemoryAddress, SizeInBytes);\n    printf(\"Pause to dump page table to check if allocation is contiguous\\n\");\n    printf(\"Press Enter key to continue\\n\");\n    getchar();\n\n    ret = rdma_map((uint64_t)MemoryAddress, 4096, &cpu_ptr);\n    if (ret < 0)\n    {\n        exit(EXIT_FAILURE);\n    }\n\n    hsaKmtFreeMemory(MemoryAddress, SizeInBytes);\n}\n\nint main(void)\n{\n    HsaVersionInfo      VersionInfo;\n\n    HSAKMT_STATUS          status = hsaKmtOpenKFD();\n\n    if( status == HSAKMT_STATUS_SUCCESS)\n    {\n        status = hsaKmtGetVersion(&VersionInfo);\n\n        if(status == HSAKMT_STATUS_SUCCESS)\n        {\n            printf(\"Kernel Interface Major Version: %d\\n\", VersionInfo.KernelInterfaceMajorVersion);\n            printf(\"Kernel Interface Minor Version: %d\\n\", VersionInfo.KernelInterfaceMinorVersion);\n        }\n    }\n\n    rdma_open();\n\n    HsaSystemProperties SystemProperties = {0};\n    status = hsaKmtAcquireSystemProperties(&SystemProperties);\n\n    if(status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"hsaKmtAcquireSystemProperties call failed. Error: %d\\n\", status);\n        exit(EXIT_FAILURE);\n    }\n\n    printf(\"System properties: Number of nodes: %d\\n\", SystemProperties.NumNodes);\n\n    for (HSAuint32 iNode = 0; iNode < SystemProperties.NumNodes; iNode++)\n    {\n        HsaNodeProperties  NodeProperties = {0};\n        status = hsaKmtGetNodeProperties(iNode, &NodeProperties);\n\n        if(status != HSAKMT_STATUS_SUCCESS)\n        {\n            fprintf(stderr, \"hsaKmtGetNodeProperties (Node = %d) call failed. Error: %d\\n\",\n                             iNode, status);\n            exit(EXIT_FAILURE);\n        }\n\n        printf(\"Node %d -> Number of Memory Banks = %d\\n\", iNode,\n                            NodeProperties.NumMemoryBanks);\n\n        HsaMemoryProperties*  MemoryProperties =\n                    new HsaMemoryProperties[NodeProperties.NumMemoryBanks];\n\n        status = hsaKmtGetNodeMemoryProperties(iNode,\n                                               NodeProperties.NumMemoryBanks,\n                                               MemoryProperties);\n\n        if(status != HSAKMT_STATUS_SUCCESS)\n        {\n            fprintf(stderr, \"hsaKmtGetNodeMemoryProperties (Node = %d) call failed. Error: %d\\n\",\n                             iNode, status);\n            exit(EXIT_FAILURE);\n        }\n\n        for (HSAuint32 iMemBank = 0; iMemBank < NodeProperties.NumMemoryBanks; iMemBank++)\n        {\n            printf(\"Heap type: %d\\n\", MemoryProperties[iMemBank].HeapType);\n\n            if (MemoryProperties[iMemBank].HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC)\n            {\n                // We found local memory available for RDMA operation.\n                // Run some tests on it.\n                run_rdma_tests(iNode, &MemoryProperties[iMemBank]);\n                run_rdma_contiguous_mem_tests(iNode, &MemoryProperties[iMemBank]);\n            }\n        }\n    }\n\n\n    status = hsaKmtReleaseSystemProperties();\n\n    if(status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"hsaKmtReleaseSystemProperties call failed. Error: %d\\n\",\n                status);\n        exit(EXIT_FAILURE);\n    }\n\n    rdma_close();\n\n    status = hsaKmtCloseKFD();\n\n    if(status != HSAKMT_STATUS_SUCCESS)\n    {\n        fprintf(stderr, \"hsaKmtCloseKFD call failed. Error: %d\\n\", status);\n        exit(EXIT_FAILURE);\n    }\n\n    return EXIT_SUCCESS;\n}\n\n\n"
  },
  {
    "path": "libhsakmt/tests/rdma/simple/drv/amdp2ptest.c",
    "content": "/*\n * Copyright 2015 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n\n\n#include <linux/version.h>\n#include <linux/module.h>\n#include <linux/kernel.h>\n#include <linux/scatterlist.h>\n#include <linux/slab.h>\n#include <linux/types.h>\n#include <linux/delay.h>\n#include <linux/compiler.h>\n#include <linux/string.h>\n#include <linux/uaccess.h>\n#include <linux/fs.h>\n#include <linux/init.h>\n#include <linux/miscdevice.h>\n#include <linux/list.h>\n#include <linux/mm.h>\n#include <linux/io.h>\n#include <linux/uaccess.h>\n\n#include \"drm/amd_rdma.h\"\n#include \"amdp2ptest.h\"\n\n\nMODULE_AUTHOR(\"serguei.sagalovitch@amd.com\");\nMODULE_LICENSE(\"MIT\");\nMODULE_DESCRIPTION(\"AMD RDMA basic API test kernel-mode driver\");\nMODULE_VERSION(\"1.0\");\n\n\nconst struct amd_rdma_interface *rdma_interface;\n\n\nstruct va_pages_node {\n\tstruct list_head node;\n\tstruct amd_p2p_info *pages;\n};\n\n\nstruct amdp2ptest_pages_list {\n\tstruct list_head\thead;\n\tstruct mutex\tlock;\n};\n\n\n#define MSG_INFO(fmt, args ...)\t\\\n\t\t\tpr_info(AMDP2PTEST_DEVICE_NAME \": \" fmt, ## args)\n#define MSG_ERR(fmt, args ...)\t\\\n\t\t\tpr_err(AMDP2PTEST_DEVICE_NAME \": \" fmt, ## args)\n#define MSG_warn(fmt, args ...)\t\\\n\t\t\tpr_warn(AMDP2PTEST_DEVICE_NAME \": \" fmt, ## args)\n\nstatic int amdp2ptest_open(struct inode *inode, struct file *filp)\n{\n\tstruct amdp2ptest_pages_list *list;\n\n\tMSG_INFO(\"Open driver\\n\");\n\n\tlist = kmalloc(sizeof(struct amdp2ptest_pages_list), GFP_KERNEL);\n\n\tif (!list) {\n\t\tMSG_ERR(\"Can't alloc kernel memory to store list stucture\\n\");\n\t\treturn -ENOMEM;\n\t}\n\n\tINIT_LIST_HEAD(&list->head);\n\tmutex_init(&list->lock);\n\n\tfilp->private_data = list;\n\n\treturn 0;\n}\n\n\nstatic int amdp2ptest_release(struct inode *inode, struct file *filp)\n{\n\tstruct va_pages_node\t      *va_pages = NULL;\n\tint retcode;\n\tstruct amdp2ptest_pages_list *list = filp->private_data;\n\tstruct list_head *p, *n;\n\n\tMSG_INFO(\"Close driver\\n\");\n\n\tlist_for_each_safe(p, n, &list->head) {\n\t\tva_pages = list_entry(p, struct va_pages_node, node);\n\t\tMSG_INFO(\"Free pages: VA 0x%llx\\n\", va_pages->pages->va);\n\t\tretcode = rdma_interface->put_pages(&va_pages->pages);\n\n\t\tif (retcode != 0)\n\t\t\tMSG_ERR(\"Could not put pages back: %d\\n\", retcode);\n\n\t\tmutex_lock(&list->lock);\n\t\tlist_del(&va_pages->node);\n\t\tmutex_unlock(&list->lock);\n\t\tkfree(va_pages);\n\t}\n\n\tfilp->private_data = NULL;\n\tkfree(list);\n\treturn 0;\n}\n\n\nstatic int ioctl_get_page_size(struct file *filp, unsigned long arg)\n{\n\tstruct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM params = {0};\n\tunsigned long page_size;\n\tint result;\n\n\tMSG_INFO(\"AMD2P2PTEST_IOCTL_GET_PAGE_SIZE\");\n\n\tif (copy_from_user(&params, (void *)arg, sizeof(params))) {\n\t\tMSG_ERR(\"copy_from_user failed on pointer %p\\n\",\n\t\t\t\t\t\t\t(void *)arg);\n\t\treturn -EFAULT;\n\t}\n\n\tMSG_INFO(\"addr %llx, length %llx\\n\", params.addr,\n\t\t\t\t\t     params.length);\n\tresult = rdma_interface->get_page_size(params.addr,\n\t\t\t\tparams.length,\n\t\t\t\tget_task_pid(current, PIDTYPE_PID),\n\t\t\t\t&page_size);\n\n\tif (result) {\n\t\tMSG_ERR(\"Could not get page size. %d\", result);\n\t\treturn -EFAULT;\n\t}\n\n\tparams.page_size = page_size;\n\tMSG_INFO(\"Page size %llx\\n\", params.page_size);\n\n\tif (copy_to_user((void *)arg, &params, sizeof(params))) {\n\t\tMSG_ERR(\"copy_to_user failed on user pointer %p\\n\",\n\t\t\t\t\t\t(void *)arg);\n\n\t\treturn -EFAULT;\n\t}\n\n\treturn 0;\n}\n\nstatic int ioctl_get_pages(struct file *filp, unsigned long arg)\n{\n\tstruct va_pages_node\t      *va_pages = NULL;\n\tstruct amdp2ptest_pages_list *list = filp->private_data;\n\tstruct AMDRDMA_IOCTL_GET_PAGES_PARAM params = {0};\n\tint result;\n\tstruct amd_p2p_info  *pages;\n\n\tMSG_INFO(\"AMD2P2PTEST_IOCTL_GET_PAGES\");\n\n\tif (copy_from_user(&params, (void *)arg, sizeof(params))) {\n\t\tMSG_ERR(\"copy_from_user failed on pointer %p\\n\",\n\t\t\t\t\t\t\t(void *)arg);\n\t\treturn -EFAULT;\n\t}\n\n\n\tMSG_INFO(\"addr %llx, length %llx\\n\", params.addr, params.length);\n\n\tresult = rdma_interface->get_pages(params.addr, params.length,\n\t\t\t\t\tget_task_pid(current, PIDTYPE_PID),\n\t\t\t\t\t0, /* There is no dma_device for which\n\t\t\t\t\t      to get pages -> no IOMMU support\n\t\t\t\t\t      is needed */\n\t\t\t\t\t&pages,\n\t\t\t\t\tNULL,\n\t\t\t\t\tlist /* Pointer to the list */\n\t\t\t\t\t);\n\n\tif (result) {\n\t\tMSG_ERR(\"Could not get pages table. %d\", result);\n\t\treturn -EFAULT;\n\t}\n\n\tif (copy_to_user((void *)arg, &params, sizeof(params))) {\n\t\tMSG_ERR(\"copy_to_user failed on user pointer %p\\n\",\n\t\t\t\t\t\t\t(void *)arg);\n\t\trdma_interface->put_pages(&pages);\n\t\treturn -EFAULT;\n\t}\n\n\n\tva_pages = kmalloc(sizeof(struct va_pages_node), GFP_KERNEL);\n\n\tif (va_pages == 0) {\n\t\tMSG_ERR(\"Can't alloc kernel memory\\n\");\n\t\trdma_interface->put_pages(&pages);\n\t\treturn -ENOMEM;\n\t}\n\n\tmemset(va_pages, 0, sizeof(struct va_pages_node));\n\tva_pages->pages = pages;\n\n\tmutex_lock(&list->lock);\n\tlist_add(&va_pages->node, &list->head);\n\tmutex_unlock(&list->lock);\n\n\treturn 0;\n}\n\n\nstatic int ioctl_put_pages(struct file *filp, unsigned long arg)\n{\n\tstruct va_pages_node\t      *va_pages = NULL;\n\tstruct amdp2ptest_pages_list *list = filp->private_data;\n\tstruct AMDRDMA_IOCTL_PUT_PAGES_PARAM params = {0};\n\tstruct list_head *p, *n;\n\tint retcode;\n\n\tMSG_INFO(\"AMD2P2PTEST_IOCTL_PUT_PAGES\");\n\n\tif (copy_from_user(&params, (void *)arg, sizeof(params))) {\n\t\tMSG_ERR(\"copy_from_user failed on pointer %p\\n\",\n\t\t\t\t\t\t\t(void *)arg);\n\t\treturn -EFAULT;\n\t}\n\n\tMSG_INFO(\"addr %llx, length %llx\\n\", params.addr, params.length);\n\n\n\tlist_for_each_safe(p, n, &list->head) {\n\t\tva_pages = list_entry(p, struct va_pages_node, node);\n\n\t\tif (va_pages->pages->va == params.addr &&\n\t\t\tva_pages->pages->size == params.length) {\n\n\t\t\tretcode = rdma_interface->put_pages(&va_pages->pages);\n\n\t\t\tif (retcode != 0) {\n\t\t\t\tMSG_ERR(\"Could not put pages back: %d\\n\",\n\t\t\t\t\t\tretcode);\n\t\t\t}\n\n\t\t\tmutex_lock(&list->lock);\n\t\t\tlist_del(&va_pages->node);\n\t\t\tmutex_unlock(&list->lock);\n\t\t\tkfree(va_pages);\n\t\t\t/* Note: Do not break from loop to allow test\n\t\t\t * situation when \"get_pages\" would be called\n\t\t\t * on the same memory several times\n\t\t\t **/\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n\nstatic const struct ioctl_handler_map {\n\tint (*handler)(struct file *filp, unsigned long arg);\n\tunsigned int cmd;\n} handlers[] = {\n\t{ ioctl_get_page_size,\tAMD2P2PTEST_IOCTL_GET_PAGE_SIZE },\n\t{ ioctl_get_pages,\tAMD2P2PTEST_IOCTL_GET_PAGES\t},\n\t{ ioctl_put_pages,\tAMD2P2PTEST_IOCTL_PUT_PAGES\t},\n\t{ NULL, 0 }\n};\n\n\n\nstatic long amdp2ptest_unlocked_ioctl(struct file *filp, unsigned int cmd,\n\t\t\t\t\t\t\t unsigned long arg)\n{\n\tint result = -EINVAL;\n\tint i;\n\n\tfor (i = 0; handlers[i].handler != NULL; i++)\n\t\tif (cmd == handlers[i].cmd) {\n\t\t\tresult = handlers[i].handler(filp, arg);\n\t\t\tbreak;\n\t\t}\n\n\treturn result;\n}\n\n\nstatic int amdp2ptest_mmap(struct file *filp, struct vm_area_struct *vma)\n{\n\tint i;\n\tstruct scatterlist *sg;\n\tstruct va_pages_node\t      *va_pages = NULL;\n\tstruct amdp2ptest_pages_list *list = filp->private_data;\n\tstruct list_head *p, *n;\n\tuint64_t gpu_va = vma->vm_pgoff << PAGE_SHIFT;\n\n\tMSG_INFO(\"Mapping to CPU user space\\n\");\n\tMSG_INFO(\"Begin vm_start 0x%lx, vm_end 0x%lx\\n\", vma->vm_start, vma->vm_end);\n\tMSG_INFO(\"vm_pgoff 0x%lx\\n\", vma->vm_pgoff);\n\tMSG_INFO(\"gpu_va address 0x%llx\\n\", gpu_va);\n\n\tlist_for_each_safe(p, n, &list->head) {\n\t\tunsigned long addr = vma->vm_start;\n\t\tlong mmap_size = vma->vm_end - vma->vm_start;\n\t\tlong size;\n\t\tint ret;\n\n\t\tva_pages = list_entry(p, struct va_pages_node, node);\n\n\t\tMSG_INFO(\"node va 0x%llx size 0x%llx\\n\", va_pages->pages->va,\n\t\t\tva_pages->pages->size);\n\n\t\tif (gpu_va >= va_pages->pages->va  &&\n\t\t    gpu_va + size <= va_pages->pages->va + va_pages->pages->size) {\n\t\t\tMSG_INFO(\"Found node: va=0x%llx,size=0x%llx,nents %d\\n\",\n\t\t\t\t\tva_pages->pages->va,\n\t\t\t\t\tva_pages->pages->size,\n\t\t\t\t\tva_pages->pages->pages->nents);\n\n\t\t\tfor_each_sg(va_pages->pages->pages->sgl, sg,\n\t\t\t\t\tva_pages->pages->pages->nents, i) {\n\n\t\t\t\tMSG_INFO(\"Found page[%d]: dma 0x%llx size 0x%x\\n\",\n\t\t\t\t\ti, sg->dma_address, sg->length);\n\n\t\t\t\tsize = min_t(unsigned long, sg->length, mmap_size);\n\t\t\t\tMSG_INFO(\"remap_pfn range addr 0x%lx to dma_addr 0x%llx size 0x%lx\\n\",\n\t\t\t\t\taddr, sg->dma_address, size);\n\t\t\t\tret = remap_pfn_range(vma,\n\t\t\t\t\t\taddr,\n\t\t\t\t\t\tsg->dma_address >> PAGE_SHIFT,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tvma->vm_page_prot);\n\t\t\t\tif (ret) {\n\t\t\t\t\tMSG_ERR(\"Failed remap_pfn() size 0x%lx ret %d\\n\",\n\t\t\t\t\t\tsize, ret);\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\t\t\t\taddr += size;\n\t\t\t\tmmap_size -= size;\n\t\t\t\tif (mmap_size <= 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn -EINVAL;\n}\n\n\n/*---------------------------------------------------------------------------*/\n\nstatic const struct file_operations amdp2ptest_fops = {\n\t.owner = THIS_MODULE,\n\t.unlocked_ioctl = amdp2ptest_unlocked_ioctl,\n\t.open = amdp2ptest_open,\n\t.release = amdp2ptest_release,\n\t.mmap = amdp2ptest_mmap,\n};\n\n\n\nstatic struct miscdevice amdp2ptest_dev = {\n\t/*\n\t * We don't care what minor number we end up with, so tell the\n\t * kernel to just pick one.\n\t */\n\t.minor = MISC_DYNAMIC_MINOR,\n\t/*\n\t * Name ourselves /dev/hello.\n\t */\n\t.name = AMDP2PTEST_DEVICE_NAME,\n\t/*\n\t * What functions to call when a program performs file\n\t * operations on the device.\n\t */\n\t.fops = &amdp2ptest_fops,\n\n\t/* Security attribute / access */\n\t.mode = S_IRWXU | S_IRWXG | S_IRWXO\n};\n\nstatic int (*p2p_query_rdma_interface)(const struct amd_rdma_interface **);\n\nstatic int __init amdp2ptest_init(void)\n{\n\tint result;\n\n\tp2p_query_rdma_interface = (int (*)(const struct amd_rdma_interface **))\n\t\t\t\t   symbol_request(amdkfd_query_rdma_interface);\n\tif (!p2p_query_rdma_interface) {\n\t\tMSG_ERR(\"Can not get symbol amdkfd_query_rdma_interface, please load amdgpu driver\\n\");\n\t\treturn -ENOENT;\n\t}\n\n\tresult = p2p_query_rdma_interface(&rdma_interface);\n\tif (result < 0) {\n\t\tMSG_ERR(\"Can not get RDMA Interface (result = %d)\\n\", result);\n\t\treturn result;\n\t}\n\n\tMSG_INFO(\"RDMA Interface %p\\n\",\t\trdma_interface);\n\tMSG_INFO(\"     get_pages %p\\n\",\t\trdma_interface->get_pages);\n\tMSG_INFO(\"     put_pages %p\\n\",\t\trdma_interface->put_pages);\n\tMSG_INFO(\"     is_gpu_address %p\\n\",\trdma_interface->is_gpu_address);\n\tMSG_INFO(\"     get_page_size %p\\n\",\trdma_interface->get_page_size);\n\n\n\t/*\n\t* Create the device in the /sys/class/misc directory.\n\t* Udev will automatically create the /dev/xxxxx device using\n\t* the default rules.\n\t*/\n\tresult  = misc_register(&amdp2ptest_dev);\n\n\tif (result < 0) {\n\t\tMSG_ERR(\"Can not register device (result = %d)\\n\", result);\n\t\treturn result;\n\t}\n\n\treturn 0;\n}\n\n\n/* Note: cleanup_module is never called if registering failed */\nstatic void __exit amdp2ptest_cleanup(void)\n{\n\tMSG_INFO(\"Unregistering\\n\");\n\n\tmisc_deregister(&amdp2ptest_dev);\n\tif (p2p_query_rdma_interface)\n\t\tsymbol_put(amdkfd_query_rdma_interface);\n}\n\n\nmodule_init(amdp2ptest_init);\nmodule_exit(amdp2ptest_cleanup);\n\n\n"
  },
  {
    "path": "libhsakmt/tests/rdma/simple/drv/amdp2ptest.h",
    "content": "/*\n * Copyright 2015 Advanced Micro Devices, Inc.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\n * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n#ifndef AMDP2PTEST_H_\n#define AMDP2PTEST_H_\n\n#include <linux/ioctl.h>\n\n#define AMDP2PTEST_IOCTL_MAGIC 'A'\n\n\n#define AMDP2PTEST_DEVICE_NAME \"amdp2ptest\"\n#define AMDP2PTEST_DEVICE_PATH \"/dev/amdp2ptest\"\n\nstruct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n\n\t/* Output parameters */\n\tuint64_t page_size;\n};\n\nstruct AMDRDMA_IOCTL_GET_PAGES_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n\tuint64_t is_local;\t/* 1 if this is the pointer to local\n\t\t\t\t   allocation */\n\n\t/* Output parameters */\n\tuint64_t cpu_ptr;\n};\n\n\nstruct AMDRDMA_IOCTL_PUT_PAGES_PARAM {\n\t/* Input parameters */\n\tuint64_t addr;\n\tuint64_t length;\n};\n\n\n#define AMD2P2PTEST_IOCTL_GET_PAGE_SIZE\t\\\n_IOWR(AMDP2PTEST_IOCTL_MAGIC, 1, struct AMDRDMA_IOCTL_GET_PAGE_SIZE_PARAM *)\n\n#define AMD2P2PTEST_IOCTL_GET_PAGES \\\n_IOWR(AMDP2PTEST_IOCTL_MAGIC, 2, struct AMDRDMA_IOCTL_GET_PAGES_PARAM *)\n\n#define AMD2P2PTEST_IOCTL_PUT_PAGES\t\\\n_IOW(AMDP2PTEST_IOCTL_MAGIC, 3, struct AMDRDMA_IOCTL_PUT_PAGES_PARAM *)\n\n\n#endif  /* AMDP2PTEST_H */\n"
  },
  {
    "path": "libhsakmt/tests/reopen/CMakeLists.txt",
    "content": "cmake_minimum_required (VERSION 2.6)\n\nproject (kmtreopen)\n\nlink_directories($ENV{ROOT_OF_ROOTS}/out/lib)\n\ninclude_directories($ENV{LIBHSAKMT_ROOT}/include)\n\nadd_executable(kmtreopen kmtreopen.c)\ntarget_link_libraries(kmtreopen libdl.so)\n\n"
  },
  {
    "path": "libhsakmt/tests/reopen/kmtreopen.c",
    "content": "#include <dlfcn.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <hsakmt.h>\n\nHSAKMT_STATUS HSAKMTAPI (*pfn_hsaKmtOpenKFD)(void);\nHSAKMT_STATUS HSAKMTAPI (*pfn_hsaKmtCloseKFD)(void);\nHSAKMT_STATUS HSAKMTAPI (*pfn_hsaKmtGetVersion)(HsaVersionInfo* VersionInfo);\nHSAKMT_STATUS HSAKMTAPI (*pfn_hsaKmtAcquireSystemProperties)(HsaSystemProperties* SystemProperties);\nHSAKMT_STATUS HSAKMTAPI (*pfn_hsaKmtReleaseSystemProperties)(void);\n\nHsaVersionInfo g_versionInfo;\nHsaSystemProperties g_systemProperties;\n\nstatic void hsa_perror(const char *s, HSAKMT_STATUS status)\n{\n    static const char *errorStrings[] = {\n        [HSAKMT_STATUS_SUCCESS] = \"Success\",\n        [HSAKMT_STATUS_ERROR] = \"General error\",\n        [HSAKMT_STATUS_DRIVER_MISMATCH] = \"Driver mismatch\",\n        [HSAKMT_STATUS_INVALID_PARAMETER] = \"Invalid parameter\",\n        [HSAKMT_STATUS_INVALID_HANDLE] = \"Invalid handle\",\n        [HSAKMT_STATUS_INVALID_NODE_UNIT] = \"Invalid node or unit\",\n        [HSAKMT_STATUS_NO_MEMORY] = \"No memory\",\n        [HSAKMT_STATUS_BUFFER_TOO_SMALL] = \"Buffer too small\",\n        [HSAKMT_STATUS_NOT_IMPLEMENTED] = \"Not implemented\",\n        [HSAKMT_STATUS_NOT_SUPPORTED] = \"Not supported\",\n        [HSAKMT_STATUS_UNAVAILABLE] = \"Unavailable\",\n        [HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED] = \"Kernel IO channel not opened\",\n        [HSAKMT_STATUS_KERNEL_COMMUNICATION_ERROR] = \"Kernel communication error\",\n        [HSAKMT_STATUS_KERNEL_ALREADY_OPENED] = \"Kernel already opened\",\n        [HSAKMT_STATUS_HSAMMU_UNAVAILABLE] = \"HSA MMU unavailable\",\n        [HSAKMT_STATUS_WAIT_FAILURE] = \"Wait failure\",\n        [HSAKMT_STATUS_WAIT_TIMEOUT] = \"Wait timeout\",\n        [HSAKMT_STATUS_MEMORY_ALREADY_REGISTERED] = \"Memory already registered\",\n        [HSAKMT_STATUS_MEMORY_NOT_REGISTERED] = \"Memory not registered\",\n        [HSAKMT_STATUS_MEMORY_ALIGNMENT] = \"Memory alignment error\"\n    };\n\n    if (status >= 0 && status <= HSAKMT_STATUS_MEMORY_ALIGNMENT)\n        fprintf(stderr, \"%s: %s\\n\", s, errorStrings[status]);\n    else\n        fprintf(stderr, \"%s: Unknown error %d\\n\", s, status);\n}\n\n#define HSA_CHECK_RETURN(call) do {             \\\n        HSAKMT_STATUS __ret;                    \\\n        printf(\"  Calling %s\\n\", #call);        \\\n        __ret = pfn_##call;                     \\\n        if (__ret != HSAKMT_STATUS_SUCCESS) {   \\\n            hsa_perror(#call, __ret);           \\\n            return __ret;                       \\\n        }                                       \\\n    } while(0)\n\n#define HSA_DLSYM(handle, func) do {                            \\\n        pfn_##func = dlsym(handle, #func);                      \\\n        if (pfn_##func == NULL) {                               \\\n            fprintf(stderr, \"dlsym failed: %s\\n\", dlerror());   \\\n            return HSAKMT_STATUS_ERROR;                         \\\n        }                                                       \\\n    } while(0)\n\nstatic int runTest(void *handle)\n{\n    HSA_DLSYM(handle, hsaKmtOpenKFD);\n    HSA_DLSYM(handle, hsaKmtCloseKFD);\n    HSA_DLSYM(handle, hsaKmtGetVersion);\n    HSA_DLSYM(handle, hsaKmtAcquireSystemProperties);\n    HSA_DLSYM(handle, hsaKmtReleaseSystemProperties);\n\n    HSA_CHECK_RETURN(hsaKmtOpenKFD());\n    HSA_CHECK_RETURN(hsaKmtGetVersion(&g_versionInfo));\n    HSA_CHECK_RETURN(hsaKmtAcquireSystemProperties(&g_systemProperties));\n\n    HSA_CHECK_RETURN(hsaKmtReleaseSystemProperties());\n    HSA_CHECK_RETURN(hsaKmtCloseKFD());\n\n    return HSAKMT_STATUS_SUCCESS;\n}\n\nint main(int argc, char *argv[])\n{\n    void *handle;\n    int i;\n\n    for (i = 0; i < 5; i++) {\n        printf(\"Iteration %d:\\n  Loading libhsakmt.so\\n\", i+1);\n\n        handle = dlopen(\"libhsakmt.so\", RTLD_LAZY);\n        if (handle == NULL) {\n            fprintf(stderr, \"dlopen failed: %s\\n\", dlerror());\n            exit(1);\n        }\n\n        if (runTest(handle) != HSAKMT_STATUS_SUCCESS)\n            exit(1);\n\n        printf(\"  Unloading libhsakmt.so\\n\");\n        if (dlclose(handle) != 0) {\n            fprintf(stderr, \"dlclose failed: %s\\n\", dlerror());\n            exit(1);\n        }\n    }\n}\n"
  },
  {
    "path": "rocrtst/.gitignore",
    "content": "\n*.o\n*.bin\n*.tar\n*.hsaco\n*.orig\n*.obsol\n*.bk\n*.old\n*.cmake\nbuild\n"
  },
  {
    "path": "rocrtst/Kernels/CMakeLists.txt",
    "content": "\ncmake_minimum_required(VERSION 2.8.0)\n\n#\n#  Setup build environment\n#\n#  1) Setup env var LLVM_DIR and OCL_BITCODE_DIR to point to\n#     folders containing relevant libraries seperately\n#\n#     export LLVM_DIR=\"Path to Lightning build artifacts\"\n#\n#     export OCL_BITCODE_DIR=\"Path containing AMDGCN Bitcode libraries\"\n#\n#  2) Make an new folder called build under root folder\n#\n#     mkdir build\n#\n#  3) Enter into folder of build, and run CMAKE to generate makefile\n#     and make it\n#\n#     cd build; cmake ..; make\n#\n\nif(WIN32)\n  message(\"Windows platform is not supported\")\n  return()\nendif()\n\n#\n# Flag to enable / disable verbose output.\n#\nSET( CMAKE_VERBOSE_MAKEFILE on )\n\nset(PROJECT_NAME \"CompileKernels\")\nproject (${PROJECT_NAME})\n\n#\n# Validate LLVM related resources are available\n#\nif (NOT DEFINED ENV{LLVM_DIR})\n  message(\"LLVM_DIR define is not set. Kernels cannot be built.\")\n  return()\nendif()\n\n#\n# Validate Opencl related resources are available\n#\nif (NOT DEFINED ENV{OCL_BITCODE_DIR})\n  message(FATAL_ERROR \"OCL_BITCODE_DIR define is not set. Kernels cannot be built.\")\nendif()\n\nset(CLANG $ENV{LLVM_DIR}/clang)\nif (NOT EXISTS ${CLANG})\n  message(\"Path to clang (${CLANG}) is not valid. Is LLVM_DIR defined correctly?\")\n  return()\nendif()\n\n#\n# Define Opencl version if it is not defined\n#\nif (DEFINED ENV{OPENCL_VER})\n  set(OPENCL_VER $ENV{OPENCL_VER})\nelse()\n  message(\"OPENCL_VER define is not set. Using default\")\n  set(OPENCL_VER \"2.0\")\nendif()\n\n#\n# Define list of Target Device types for which to get code objects\n#\nset(DEV_LIST \"gfx803\" \"gfx900\" CACHE STRING \"List of Gfx Devices\")\nset(TARGET_DEV_LIST ${DEV_LIST})\nseparate_arguments(TARGET_DEV_LIST)\n\n# Maintains a global list of targets to build\nset (ROCM_CODEOBJ_LIST \"\" CACHE INTERNAL ROCM_CODEOBJ_LIST)\n\n#\n# Options that are passed along to Clang to enable code object generation\n#\nset(KERN_SUFFIX \"kernels.hsaco\")\n# Check if device-libs bitcode is following old or new layout\nset(BITCODE_DIR \"$ENV{OCL_BITCODE_DIR}\")\nif(EXISTS \"${BITCODE_DIR}/opencl.amdgcn.bc\")\n  set(BITCODE_ARGS \"-nogpulib\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/opencl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ockl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ocml.amdgcn.bc\")\nelse()\n  set(BITCODE_ARGS \"--hip-device-lib-path=${BITCODE_DIR}\")\nendif()\n\n#\n# Compiles Opencl kernel into a AMDGcn code object\n#\nfunction(CompileKernel KRNL_NAME TARGET_DEV)\n\n  #\n  # Bind names for code object file and directory containing it\n  set(KERNEL_DIR ${PROJECT_BINARY_DIR}/${TARGET_DEV})\n  set(CODEASM_FILE \"${KRNL_NAME}_${TARGET_DEV}.asm\")\n  set(CODEOBJ_FILE \"${KRNL_NAME}_${TARGET_DEV}.hsaco\")\n\n  #\n  # Add target name to a global list of target names. This must\n  # be executed before the add_custom_target rule\n  set(TARGET_NAME \"${KRNL_NAME}_${TARGET_DEV}\")\n  set(ROCM_CODEOBJ_LIST ${ROCM_CODEOBJ_LIST} ${TARGET_NAME}\n                      CACHE INTERNAL ROCM_CODEOBJ_LIST)\n\n  #\n  # Build clang arguments into a string and tokenize it into a list\n  # The command \"separate_arguments\" will replace each instance of\n  # space char with a semi-colon char. Like any other program clang\n  # needs its arguments to be passed in as a list of tokens. The\n  # following strings are used to generate a code object and code\n  # asm files\n  #\n  string(CONCAT CODE_ARG_STR \"-Xclang -finclude-default-header \"\n                \"-target amdgcn-amdh-amdhsa -mcpu=${TARGET_DEV} \"\n                \"${BITCODE_ARGS} -cl-std=CL${OPENCL_VER} \"\n                \"${PROJECT_SOURCE_DIR}/${CL_FILE} -o ${KERNEL_DIR}/${CODEOBJ_FILE}\")\n  string(CONCAT ASM_ARG_STR \"-S -Xclang -finclude-default-header \"\n                \"-target amdgcn-amdh-amdhsa -mcpu=${TARGET_DEV} \"\n                \"${BITCODE_ARGS} -cl-std=CL${OPENCL_VER} \"\n                \"${PROJECT_SOURCE_DIR}/${CL_FILE} -o ${KERNEL_DIR}/${CODEASM_FILE}\")\n  set(ASM_ARG_LIST ${ASM_ARG_STR})\n  set(CODE_ARG_LIST ${CODE_ARG_STR})\n  separate_arguments(ASM_ARG_LIST)\n  separate_arguments(CODE_ARG_LIST)\n\n  #\n  # Create a custom command to execute associated commands\n  # and a target it is associated with\n  #\n  add_custom_command(OUTPUT ${KERNEL_DIR}/${KNAME_EXE}\n                     COMMAND ${CMAKE_COMMAND} -E make_directory ${KERNEL_DIR}\n                     COMMAND ${CLANG} ${ASM_ARG_LIST}\n                     COMMAND ${CLANG} ${CODE_ARG_LIST}\n                     COMMENT \"BUILDING KERNEL...\" VERBATIM)\n  add_custom_target(\"${TARGET_NAME}\" ALL DEPENDS \"${KERNEL_DIR}/${KNAME_EXE}\")\n\nendfunction(CompileKernel)\n\nfunction(buildCodeObjects kname)\n\n  # Bind the name of CL file and associate\n  # a name for the target\n  set(KNAME_EXE \"${kname}\")\n  set(CL_FILE \"${kname}_kernel.cl\")\n\n  # Iterate through list of target devices\n  foreach(tdev ${TARGET_DEV_LIST})\n    CompileKernel(${kname} ${tdev})\n  endforeach(tdev)\n\nendfunction(buildCodeObjects)\n\nbuildCodeObjects(\"read\")\nbuildCodeObjects(\"write\")\nbuildCodeObjects(\"binary_search\")\n\n#\n# Create a custom target which will build the full suite\n# of code objects for all kernels and target device pairs\n#\nadd_custom_target(rocm_code_objs ALL DEPENDS ${ROCM_CODEOBJ_LIST})\n\n"
  },
  {
    "path": "rocrtst/Kernels/binary_search_kernel.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/**\n * One instance of this kernel call is a thread.\n * Each thread finds out the segment in which it should look for the element.\n * After that, it checks if the element is between the lower bound and upper\n * bound of its segment. If yes, then this segment becomes the total\n * searchspace for the next pass.\n *\n * To achieve this, it writes the lower bound and upper bound to the output\n * array. In case the element at the left end (lower bound) matches the element\n * we are looking for, that is marked in the output and we no longer need to\n * look any further.\n */\n \n__kernel void\nbinarySearch(__global uint4 * outputArray,\n             __const __global uint2  * sortedArray,\n             const   unsigned int findMe) {\n  unsigned int tid = get_global_id(0);\n\n  // Then we find the elements  for this thread\n  uint2 element = sortedArray[tid];\n\n\n  // If the element to be found does not lie between\n  // them, then nothing left to do in this thread\n  if((element.x > findMe) || (element.y < findMe)) {\n    return;\n  } else {\n    // However, if the element does lie between the lower\n    // and upper bounds of this thread's searchspace\n    // we need to narrow down the search further in this\n    // search space \n    // The search space for this thread is marked in the\n    // output as being the total search space for the next pass\n    outputArray[0].x = tid;\n    outputArray[0].w = 1;\n  }\n}\n\n\n__kernel void\nbinarySearch_mulkeys(__global int *keys,\n                     __global uint *input,\n                     const unsigned int numKeys,\n                     __global int *output) {\n\n  int gid = get_global_id(0);\n  int lBound = gid * 256;\n  int uBound = lBound + 255;\n\n  for(int i = 0; i < numKeys; i++) {\n    if(keys[i] >= input[lBound] && keys[i] <= input[uBound])\n      output[i]=lBound;\n  }\n\n}\n\n\n__kernel void\nbinarySearch_mulkeysConcurrent(__global uint *keys,\n                               __global uint *input,\n                               const unsigned int inputSize, // num. of inputs\n                               const unsigned int numSubdivisions,\n                               __global int *output) {\n\n  int lBound = (get_global_id(0) % numSubdivisions) * (inputSize / numSubdivisions);\n  int uBound = lBound + inputSize / numSubdivisions;\n  int myKey = keys[get_global_id(0) / numSubdivisions];\n  int mid;\n\n  while(uBound >= lBound) {\n    mid = (lBound + uBound) / 2;\n    if(input[mid] == myKey) {\n      output[get_global_id(0) / numSubdivisions] = mid;\n      return;\n    } else if(input[mid] > myKey) {\n      uBound = mid - 1;\n    } else {\n      lBound = mid + 1;\n    }\n  }\n}\n"
  },
  {
    "path": "rocrtst/Kernels/read_kernel.cl",
    "content": "\n/**\n * @brief Opencl kernel to read from a buffer and sum its values\n * into a destination integer\n *\n * @param src Pointer to an array of 16 unsigned integers (32-bit) i.e. one instance\n * has 16 * 32-bit = 64 bytes\n * \n * @param size Specifies number of uint16 elements in the array\n *\n * @param threads Number of threads running this kernel\n *\n * @param dst Output parameter updated with sum of the input buffer\n *\n * @note: It is critical that the size of 'src' be a integral multiple\n * of (threads * sizeof(uint16)). If it is fractional and less than ONE\n * it will lead to accessing memory that is out-of-bounds. If it is fractional\n * more but more than ONE then it will lead to some threads not doing work\n * at all leading to incorrect benchmark computation\n *\n */\n\n__kernel void\n  read_kernel(__global uint16 *src,\n              ulong size, uint threads, __global uint* dst) {\n\n  uint16 pval;\n  int idx = get_global_id(0);\n  __global uint16 *srcEnd = src + size;\n  \n  uint tmp = 0;\n  src = &src[idx];\n  while (src < srcEnd) {\n    pval = *src;\n    src += threads;\n    tmp += pval.s0 + pval.s1 + pval.s2 + pval.s3 +  \\\n           pval.s4 + pval.s5 + pval.s6 +  pval.s7 + \\\n           pval.s8 + pval.s9 + pval.sa + pval.sb +  \\\n           pval.sc + pval.sd + pval.se + pval.sf;\n  }\n  atomic_add(dst, tmp);\n}\n\n"
  },
  {
    "path": "rocrtst/Kernels/write_kernel.cl",
    "content": "\n/**\n * @brief Opencl kernel to write into a buffer the values of const integer list\n *\n * @param dst Pointer to an array of 16 unsigned integers (32-bit) i.e. one instance\n * has 16 * 32-bit = 64 bytes\n * \n * @param size Specifies number of uint16 elements in the array\n *\n * @param threads Number of threads running this kernel\n *\n * @note: It is critical that the size of 'dst' be a integral multiple\n * of (threads * sizeof(uint16)). If it is fractional and less than ONE\n * it will lead to accessing memory that is out-of-bounds. If it is fractional\n * more but more than ONE then it will lead to some threads not doing work\n * at all leading to incorrect benchmark computation\n *\n */\n\n__kernel void\n  write_kernel(__global uint16 *dst,\n               ulong size, uint threads) {\n\n  uint16 pval = (uint16)(0xabababab, 0xabababab, 0xabababab, 0xabababab,\n                         0xabababab, 0xabababab, 0xabababab, 0xabababab,\n                         0xabababab, 0xabababab, 0xabababab, 0xabababab,\n                         0xabababab, 0xabababab, 0xabababab, 0xabababab);\n\n  int idx = get_global_id(0);\n  __global uint16 *dstEnd = dst + size;\n  \n  dst = &dst[idx];\n  do {\n    *dst = pval;\n    dst += threads;\n  } while (dst < dstEnd);\n\n}\n\n\n"
  },
  {
    "path": "rocrtst/README.md",
    "content": "# Building rocrtst\n\n## Library dependencies\nrocrtst needs hwloc and libnuma to build and run. On Debian systems, for example, you would need to get them like so:\n```sh\nsudo apt-get install libhwloc-dev libnuma-dev\n```\n## CMake option values\nWhen building rocrtst, several cmake command line options are available--some mandatory, some optional. These are described here:\n  * TARGET_DEVICES=<string>\n    * Optional\n    * semi-colon separated list of gpus to build kernels for; e.g. \"gfx908;gfx900;...\".\n    * Default: the list of devices that is used is specified in the CMakeLists.txt file, and includes the all the currently supported targets.\n  * ROCRTST_BLD_TYPE=<debug|release>\n    * Optional\n    * Build a debug or release build\n    * Default: Build the debug version\n  * CMAKE_PREFIX_PATH=<\"ROCR root path; LLVM root path\">\n    * Required\n    * Where to find ROCr and LLVM. The ROCr root path is typically something like /opt/rocm. The LLVM directory is typically something like /opt/rocm/llvm\n  * CMAKE_INSTALL_PREFIX=\"<Root path where rocrtst should be installed>\"\n    * Optional\n    * Where to install rocrtst\n  * CPACK_PACKAGING_INSTALL_PREFIX=\"<path where to install>\"\n    * Optional\n    * Where to install rocrtst within DEB/RPM packages\n  * CPACK_GENERATOR=<list of package generators>\n    * Optional\n    * List of CPack build generators to use; e.g. \"DEB;RPM\"\n  * ROCM_PATCH_VERSION=<string>\n    * Optional\n    * ROCm patch version used in package name\n  * ROCM_DIR=<ROCm path>\n    * Required\n    * ROCm root directory\n  * LLVM_DIR=\"<clang location>\"\n    * Required\n    * Location of clang executable\n  * OPENCL_DIR=<location of OpenCL root>\n    * Required\n    * Location where OpenCL root resides\n  * EMULATOR_BUILD=<true|false>\n    * Optional\n    * If EMULATOR_BUILD is defined, rocrtst will avoid tests that typically run too long on an HW emulator, or use a scaled-down version of the test.\n\n## Steps to build\n```sh\nmkdir build\ncd build\n# See description of these options above.\n# The values for these options are examples. They should be tailored\n# for your system.\ncmake -DTARGET_DEVICES=$GPU_LIST \\\n  -DROCRTST_BLD_TYPE=$ROCRTST_BUILD_TYPE \\\n  -DCMAKE_PREFIX_PATH=\"$PACKAGE_ROOT;$PACKAGE_ROOT/llvm\" \\\n  -DCMAKE_INSTALL_PREFIX=\"$ROCM_INSTALL_PATH\" \\\n  -DCPACK_PACKAGING_INSTALL_PREFIX=\"$ROCM_INSTALL_PATH\" \\\n  -DCPACK_GENERATOR=\"DEB;RPM\" \\\n  -DROCM_PATCH_VERSION=$ROCM_LIBPATCH_VERSION \\\n  -DROCM_DIR=$PACKAGE_ROOT \\\n  -DLLVM_DIR=\"$PACKAGE_ROOT/llvm/bin\" \\\n  -DOPENCL_DIR=$PACKAGE_ROOT \\\n  -DEMULATOR_BUILD=$EMULATOR_BUILD \\\n      ..\n# Build rocrtst executable\nmake\n# Build rocrtst kernels\nmake rocrtst_kernels\n```\n## Running rocrtst\nrocrtst needs to be able to find the ROCr library. This can be through ldconfig method or by setting LD_LIBRARY_PATH to have the ROCr library directory.\nWhen rocrtst is built, there is one rocrtst executable, and several symlinks pointing to that executable, one from each asic sub-directory. For example, for gfx900, we would see the following:\n```sh\ncd <rocrtst bin root>/gfx900\nls -l rocrtst\nlrwxrwxrwx 1 user user 12 Sep 28 17:23 rocrtst64 -> ../rocrtst64\n```\nTo run rocrtst, we should call the ASIC specific symlink. This allows the asic-specific kernels to be found.\n\nrocrtst is a Google Test (\"gtest\") based program and accepts gtest options. Additionally, there are some rocrtst specfic options. All of these options can be seen by using the \"-h\" option:\n```sh\n$ <rocrtst bin>/gfx900 $ ./rocrtst64 -h\n<GTest option descrption>\nOptional RocRTst Arguments:\n--iterations, -i <number of iterations to execute>; override default, which varies for each test\n--rocrtst_help, -r print this help message\n--verbosity, -v <verbosity level>\n  Verbosity levels:\n   0    -- minimal; just summary information\n   1    -- intermediate; show intermediate values such as intermediate perf. data\n   2    -- progress; show progress displays\n   >= 3 -- more debug output\n--monitor_verbosity, -m <monitor verbosity level>\n  Monitor Verbosity levels:\n   0    -- don't read or print out any GPU monitor information;\n   1    -- print out all available monitor information before the first test and after each test\n   >= 2 -- print out even more monitor information (test specific)\n\n```\n\n\n"
  },
  {
    "path": "rocrtst/common/base_rocr.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include \"common/base_rocr.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/os.h\"\n\nnamespace rocrtst {\n\nBaseRocR::BaseRocR(void) {\n  num_iteration_ = 1;\n  cpu_device_.handle = -1;\n  gpu_device1_.handle = -1;\n  device_pool_.handle = 0;\n  kern_arg_pool_.handle = 0;\n  main_queue_ = nullptr;\n  kernarg_buffer_ = nullptr;\n  kernel_object_ = 0;\n  memset(&aql_, 0, sizeof(aql_));\n  set_requires_profile(-1);\n  set_enable_interrupt(false);\n  orig_hsa_enable_interrupt_ = GetEnv(\"HSA_ENABLE_INTERRUPT\");\n  set_kernel_file_name(\"\");\n  set_verbosity(0);\n  set_monitor_verbosity(0);\n  set_title(\"unset_title\");\n}\n\nBaseRocR::~BaseRocR() {\n}\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/base_rocr.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/// \\file\n/// File containg base class declaration needed for all RocR tests and samples\n/// that allow derived classes to use utility functions.\n\n#ifndef ROCRTST_COMMON_BASE_ROCR_H_\n#define ROCRTST_COMMON_BASE_ROCR_H_\n#include <stdint.h>\n#include <stdio.h>\n#include <string>\n#include \"common/common.h\"\n#include \"common/hsatimer.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"common/rocr.h\"\n\nnamespace rocrtst {\n\n/// Common interface for RocR tests and samples, required for several\n/// common functions\nclass BaseRocR {\n public:\n  BaseRocR(void);\n\n  virtual ~BaseRocR(void);\n\n  ///< Setters and Getters\n\n  void set_gpu_device1(hsa_agent_t in_dev) {\n    gpu_device1_.handle = in_dev.handle;\n  }\n  hsa_agent_t* gpu_device1(void) {\n    return &gpu_device1_;\n  }\n\n  void set_cpu_device(hsa_agent_t in_dev) {\n    cpu_device_.handle = in_dev.handle;\n  }\n  hsa_agent_t* cpu_device(void) {\n    return &cpu_device_;\n  }\n\n  void set_kernel_file_name(const char* in_file_name) {\n    kernel_file_name_ = in_file_name;\n  }\n  std::string const kernel_file_name(void) const {\n    return kernel_file_name_;\n  }\n  const\n\n  void set_kernel_name(std::string in_kernel_name) {\n    kernel_name_ = in_kernel_name;\n  }\n  std::string const kernel_name(void) const {\n    return kernel_name_;\n  }\n\n  void set_agent_name(std::string in_agent_name) {\n    agent_name_ = in_agent_name;\n  }\n  std::string const get_agent_name(void) const {\n    return agent_name_;\n  }\n\n  void set_kernel_object(uint64_t in_kernel_object) {\n    kernel_object_ = in_kernel_object;\n  }\n  uint64_t kernel_object(void) const {\n    return kernel_object_;\n  }\n\n  void set_profile(hsa_profile_t in_prof) {\n    profile_ = in_prof;\n  }\n  hsa_profile_t profile(void) const {\n    return profile_;\n  }\n\n  uint32_t private_segment_size(void) const {\n    return private_segment_size_;\n  }\n  void set_private_segment_size(uint32_t sz) {\n    private_segment_size_ = sz;\n  }\n\n  void set_group_segment_size(uint32_t sz) {\n    group_segment_size_ = sz;\n  }\n  uint32_t group_segment_size(void) const {\n    return group_segment_size_;\n  }\n\n  void set_group_size(uint32_t sz) {\n    group_size_ = sz;\n  }\n  uint32_t group_size(void) const {\n    return group_size_;\n  }\n\n  void set_main_queue(hsa_queue_t* q) {\n    main_queue_ = q;\n  }\n  hsa_queue_t* main_queue(void) const {\n    return main_queue_;\n  }\n\n  void clear_code_object() {\n    for(std::vector<CodeObject *>::iterator  it = objs_.begin(); it != objs_.end(); ++it) {\n      delete *it;\n    }\n    objs_.clear();\n  }\n  void set_code_object(CodeObject* obj) {\n    objs_.push_back(obj);\n  }\n\n  hsa_kernel_dispatch_packet_t& aql(void) {\n    return aql_;\n  }\n\n  void set_num_iteration(int num) {\n    num_iteration_ = num;\n  }\n  uint32_t num_iteration(void) const {\n    return num_iteration_;\n  }\n\n  hsa_amd_memory_pool_t& device_pool(void) {\n    return device_pool_;\n  }\n\n  hsa_amd_memory_pool_t& cpu_pool(void) {\n    return cpu_pool_;\n  }\n\n  hsa_amd_memory_pool_t& kern_arg_pool(void) {\n    return kern_arg_pool_;\n  }\n\n  void set_kernarg_size(uint32_t sz) {\n    kernarg_size_ = sz;\n  }\n  uint32_t kernarg_size(void) const {\n    return kernarg_size_;\n  }\n\n  void set_kernarg_align(uint32_t align) {\n    kernarg_align_ = align;\n  }\n  uint32_t kernarg_align(void) const {\n    return kernarg_align_;\n  }\n\n  void* kernarg_buffer(void) const {\n    return kernarg_buffer_;\n  }\n  void set_kernarg_buffer(void* buffer) {\n    kernarg_buffer_ = buffer;\n  }\n\n  int32_t requires_profile(void) const {\n    return requires_profile_;\n  }\n\n  char* orig_hsa_enable_interrupt() const {\n    return orig_hsa_enable_interrupt_;\n  }\n\n  bool enable_interrupt() const {\n    return enable_interrupt_;\n  }\n\n  void set_title(std::string name) {\n    title_ = name;\n  }\n  std::string title(void) const {\n    return title_;\n  }\n\n  PerfTimer* hsa_timer(void) {\n    return &hsa_timer_;\n  }\n\n  void set_verbosity(uint32_t v) {\n    verbosity_ = v;\n  }\n  uint32_t verbosity(void) const {\n    return verbosity_;\n  }\n\n  void set_monitor_verbosity(uint32_t m) {\n    monitor_verbosity_ = m;\n  }\n  uint32_t monitor_verbosity(void) const {\n    return monitor_verbosity_;\n  }\n\n protected:\n  void set_requires_profile(int32_t reqd_prof) {\n    requires_profile_ = reqd_prof;\n  }\n\n  void set_enable_interrupt(bool doEnable) {\n    enable_interrupt_ = doEnable;\n  }\n\n private:\n  uint64_t num_iteration_;   ///< Number of times to execute test\n\n  hsa_queue_t* main_queue_;   ///< AQL queue used for packets\n\n  std::vector<CodeObject*> objs_; ///< CodeObject vector\n\n  hsa_agent_t gpu_device1_;   ///< Handle to first GPU found\n\n  hsa_agent_t cpu_device_;   ///< Handle to CPU\n\n  hsa_amd_memory_pool_t device_pool_;   ///< Memory pool on gpu pool list\n\n  hsa_amd_memory_pool_t cpu_pool_;   ///< Memory pool on cpu pool list\n\n  hsa_amd_memory_pool_t kern_arg_pool_;   ///< Memory pool suitable for args\n\n  uint64_t kernel_object_;   ///< Handle to kernel code\n\n  std::string kernel_file_name_;   ///< Code object file name\n\n  std::string kernel_name_;   ///< Kernel name\n\n  std::string agent_name_;   ///< Agent name\n\n  hsa_kernel_dispatch_packet_t aql_;   ///< Kernel dispatch packet\n\n  uint32_t group_segment_size_;   ///< Kernel group seg size\n\n  uint32_t kernarg_size_;   ///< Kernarg memory size\n\n  uint32_t kernarg_align_;   ///< Alignment for kern argument memory\n\n  void* kernarg_buffer_;    ///< Unaligned allocated kernel arg. buffer\n\n  hsa_profile_t profile_;   ///< Device profile.\n\n  uint32_t group_size_;   ///< Number of work items in one group\n\n  uint32_t private_segment_size_;   ///< Kernel private seg size\n\n  int32_t requires_profile_;   ///< Profile required by test (-1 if no req.)\n\n  char* orig_hsa_enable_interrupt_;   ///< Orig. value of HSA_ENABLE_INTERRUPT\n\n  bool enable_interrupt_;   ///< Whether to enable/disable interrupts for test\n\n  std::string title_;   ///< Displayed title of test\n\n  uint32_t verbosity_;   ///< How much additional output to produce\n\n  uint32_t monitor_verbosity_;   ///< How much additional output to produce\n\n  PerfTimer hsa_timer_;   ///< Timer to be used for timing parts of test\n};\n\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_BASE_ROCR_H_\n"
  },
  {
    "path": "rocrtst/common/base_rocr_utils.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/// \\file\n/// Utility functions that act on BaseRocR objects.\n\n#include \"common/base_rocr_utils.h\"\n#include <assert.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <string>\n#include \"common/base_rocr.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/os.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nnamespace rocrtst {\n\n\n#define RET_IF_HSA_UTILS_ERR(err)                                                                  \\\n  {                                                                                                \\\n    if ((err) != HSA_STATUS_SUCCESS) {                                                             \\\n      const char* msg = 0;                                                                         \\\n      hsa_status_string(err, &msg);                                                                \\\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err) << msg;                                                   \\\n      return (err);                                                                                \\\n    }                                                                                              \\\n  }\n\n#define RET_IF_HSA_UTILS_ERR_RET(err, ret)                                                             \\\n  {                                                                                                \\\n    if ((err) != HSA_STATUS_SUCCESS) {                                                             \\\n      const char* msg = 0;                                                                         \\\n      hsa_status_string(err, &msg);                                                                \\\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err) << msg;                                                   \\\n      return (ret);                                                                                \\\n    }                                                                                              \\\n  }\n// Clean up some of the common handles and memory used by BaseRocR code, then\n// shut down hsa. Restore HSA_ENABLE_INTERRUPT to original value, if necessary\nhsa_status_t CommonCleanUp(BaseRocR* test) {\n  hsa_status_t err;\n\n  assert(test != nullptr);\n\n  if (nullptr != test->kernarg_buffer()) {\n    err = hsa_amd_memory_pool_free(test->kernarg_buffer());\n    RET_IF_HSA_UTILS_ERR(err);\n    test->set_kernarg_buffer(nullptr);\n  }\n\n  if (nullptr != test->main_queue()) {\n    err = hsa_queue_destroy(test->main_queue());\n    RET_IF_HSA_UTILS_ERR(err);\n    test->set_main_queue(nullptr);\n  }\n\n  if (test->aql().completion_signal.handle != 0) {\n    err = hsa_signal_destroy(test->aql().completion_signal);\n    RET_IF_HSA_UTILS_ERR(err);\n  }\n\n  test->clear_code_object();\n  err = hsa_shut_down();\n  RET_IF_HSA_UTILS_ERR(err);\n\n  // Ensure that HSA is actually closed.\n  hsa_status_t check = hsa_shut_down();\n  if (check != HSA_STATUS_ERROR_NOT_INITIALIZED) {\n    EXPECT_EQ(HSA_STATUS_ERROR_NOT_INITIALIZED, check) << \"hsa_init reference count was too high.\";\n    return HSA_STATUS_ERROR;\n  }\n\n  std::string intr_val;\n\n  if (test->orig_hsa_enable_interrupt() == nullptr) {\n    intr_val = \"\";\n  } else {\n    intr_val = test->orig_hsa_enable_interrupt();\n  }\n\n  SetEnv(\"HSA_ENABLE_INTERRUPT\", intr_val.c_str());\n\n  return err;\n}\n\nstatic const char* PROFILE_STR[] = {\"HSA_PROFILE_BASE\", \"HSA_PROFILE_FULL\", };\n\n/// Verify that the machine running the test has the required profile.\n/// This function will verify that the execution machine meets any specific\n/// test requirement for a profile (HSA_PROFILE_BASE or HSA_PROFILE_FULL).\n/// \\param[in] test Test that provides profile requirements.\n/// \\returns bool\n///          - true Machine meets test requirements\n///          - false Machine does not meet test requirements\nbool CheckProfileAndInform(BaseRocR* test) {\n  if (test->verbosity() > 0) {\n    std::cout << \"Target HW Profile is \"\n              << PROFILE_STR[test->profile()] << std::endl;\n  }\n\n  if (test->requires_profile() == -1) {\n    if (test->verbosity() > 0) {\n      std::cout << \"Test can run on any profile. OK.\" << std::endl;\n    }\n    return true;\n  } else {\n    std::cout << \"Test requires \" << PROFILE_STR[test->requires_profile()]\n              << \". \";\n\n    if (test->requires_profile() != test->profile()) {\n      std::cout << \"Not Running.\" << std::endl;\n      return false;\n    } else {\n      std::cout << \"OK.\" << std::endl;\n      return true;\n    }\n  }\n}\n\n/// Helper function to process error returned from\n///  iterate function like hsa_amd_agent_iterate_memory_pools\n/// \\param[in] Error returned from iterate call\n/// \\returns HSA_STATUS_SUCCESS iff iterate call succeeds in finding\n///  what was being searched for\nstatic hsa_status_t ProcessIterateError(hsa_status_t err) {\n  if (err == HSA_STATUS_INFO_BREAK) {\n    err = HSA_STATUS_SUCCESS;\n  } else if (err == HSA_STATUS_SUCCESS) {\n    // This actually means no pool was found.\n    err = HSA_STATUS_ERROR;\n  }\n  return err;\n}\n\n// Find pools for cpu, gpu and for kernel arguments. These pools have\n// common basic requirements, but are not suitable for all cases. In\n// that case, set cpu_pool(), device_pool() and/or kern_arg_pool()\n// yourself instead of using this function.\nhsa_status_t SetPoolsTypical(BaseRocR* test) {\n  hsa_status_t err;\n  if (test->profile() == HSA_PROFILE_FULL) {\n    err = hsa_amd_agent_iterate_memory_pools(*test->cpu_device(),\n          rocrtst::FindAPUStandardPool, &test->cpu_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n\n    err = hsa_amd_agent_iterate_memory_pools(*test->cpu_device(),\n          rocrtst::FindAPUStandardPool, &test->device_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n\n    err = hsa_amd_agent_iterate_memory_pools(*test->cpu_device(),\n          rocrtst::FindAPUStandardPool, &test->kern_arg_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n\n  } else {\n    err = hsa_amd_agent_iterate_memory_pools(*test->cpu_device(),\n          rocrtst::FindStandardPool, &test->cpu_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n\n    err = hsa_amd_agent_iterate_memory_pools(*test->gpu_device1(),\n          rocrtst::FindStandardPool, &test->device_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n\n    err = hsa_amd_agent_iterate_memory_pools(*test->cpu_device(),\n          rocrtst::FindKernArgPool, &test->kern_arg_pool());\n    RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Enable interrupts if necessary, and call hsa_init()\nhsa_status_t InitAndSetupHSA(BaseRocR* test) {\n  hsa_status_t err;\n\n  if (test->enable_interrupt()) {\n    SetEnv(\"HSA_ENABLE_INTERRUPT\", \"1\");\n  }\n\n  err = hsa_init();\n  RET_IF_HSA_UTILS_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Attempt to find and set test->cpu_device and test->gpu_device1\nhsa_status_t SetDefaultAgents(BaseRocR* test) {\n  hsa_agent_t gpu_device1;\n  hsa_agent_t cpu_device;\n  hsa_status_t err;\n\n  gpu_device1.handle = 0;\n  err = hsa_iterate_agents(FindGPUDevice, &gpu_device1);\n  RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n  test->set_gpu_device1(gpu_device1);\n\n  cpu_device.handle = 0;\n  err = hsa_iterate_agents(FindCPUDevice, &cpu_device);\n  RET_IF_HSA_UTILS_ERR(rocrtst::ProcessIterateError(err));\n  test->set_cpu_device(cpu_device);\n\n  if (0 == gpu_device1.handle) {\n    std::cout << \"GPU Device is not Created properly!\" << std::endl;\n    RET_IF_HSA_UTILS_ERR(HSA_STATUS_ERROR);\n  }\n\n  if (0 == cpu_device.handle) {\n    std::cout << \"CPU Device is not Created properly!\" << std::endl;\n    RET_IF_HSA_UTILS_ERR(HSA_STATUS_ERROR);\n  }\n\n  if (test->verbosity() > 0) {\n    char name[64] = {0};\n    err = hsa_agent_get_info(gpu_device1, HSA_AGENT_INFO_NAME, name);\n    RET_IF_HSA_UTILS_ERR(err);\n    std::cout << \"The gpu device name is \" << name << std::endl;\n  }\n\n  hsa_profile_t profile;\n  err = hsa_agent_get_info(gpu_device1, HSA_AGENT_INFO_PROFILE, &profile);\n  RET_IF_HSA_UTILS_ERR(err);\n  test->set_profile(profile);\n\n  if (!CheckProfileAndInform(test)) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n// See if the profile of the target matches any required profile by the\n// test program.\nbool CheckProfile(BaseRocR const* test) {\n  if (test->requires_profile() == -1) {\n    return true;\n  } else {\n    return (test->requires_profile() == test->profile());\n  }\n}\n\n/// Locate file using local and device named file paths.\nstd::string LocateKernelFile(std::string filename, hsa_agent_t agent) {\n  char agent_name[64];\n  std::string obj_file;\n  hsa_status_t err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, agent_name);\n  RET_IF_HSA_UTILS_ERR_RET(err, obj_file);\n\n  obj_file = \"./\" + filename;\n  int file_handle = open(obj_file.c_str(), O_RDONLY);\n  if (file_handle < 0) {\n    obj_file = \"./\" + std::string(agent_name) + \"/\" + filename;\n    file_handle = open(obj_file.c_str(), O_RDONLY);\n    if(file_handle < 0)\n      std::runtime_error(\"Could not open file.\\n\");\n  }\n\n  close(file_handle);\n  return obj_file;\n}\n\n// Load the specified kernel code from the specified file, inspect and fill\n// in BaseRocR member variables related to the kernel and executable.\n// Required Input BaseRocR member variables:\n// - gpu_device1()\n// - kernel_file_name()\n// - kernel_name()\n//\n// Written BaseRocR member variables:\n//  -kernel_object()\n//  -private_segment_size()\n//  -group_segment_size()\n//  -kernarg_size()\n//  -kernarg_align()\nhsa_status_t LoadKernelFromObjFile(BaseRocR* test, hsa_agent_t* agent) {\n  hsa_status_t err;\n  Kernel kern;\n  std::string kern_name;\n  char agent_name[64];\n  std::string obj_file;\n  CodeObject* obj;\n\n  assert(test != nullptr);\n  if (agent == nullptr) {\n    agent = test->gpu_device1();  // Assume GPU agent for now\n  }\n\n  obj_file = LocateKernelFile(test->kernel_file_name(), *agent);\n  Device *gpu = (Device*)(agent - offsetof(Device, agent));\n  obj = new CodeObject(obj_file, *gpu);\n  test->set_code_object(obj);\n  kern_name = test->kernel_name() + \".kd\";\n\n  if(!obj->GetKernel(kern_name, kern)) {\n      ADD_FAILURE();\n      return HSA_STATUS_ERROR;\n  }\n\n  test->set_kernel_object(kern.handle);\n  test->set_private_segment_size(kern.scratch);\n  test->set_group_segment_size(kern.group);\n  test->set_kernarg_size(kern.kernarg_size);\n  assert(kern.kernarg_align >= 16 && \"Reported kernarg size is too small.\");\n  kern.kernarg_size = (kern.kernarg_size == 0) ? 16 : kern.kernarg_size;\n  test->set_kernarg_align(kern.kernarg_size);\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CreateQueue(hsa_agent_t device, hsa_queue_t** queue,\n                         uint32_t num_pkts) {\n  hsa_status_t err;\n\n  if (num_pkts == 0) {\n    err = hsa_agent_get_info(device, HSA_AGENT_INFO_QUEUE_MAX_SIZE,\n                             &num_pkts);\n    RET_IF_HSA_UTILS_ERR(err);\n  }\n\n  err = hsa_queue_create(device, num_pkts, HSA_QUEUE_TYPE_MULTI, NULL,\n                         NULL, UINT32_MAX, UINT32_MAX, queue);\n  RET_IF_HSA_UTILS_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n// Initialize the provided aql packet with standard default values, and\n// values from provided BaseRocR object.\nhsa_status_t InitializeAQLPacket(const BaseRocR* test,\n                         hsa_kernel_dispatch_packet_t* aql) {\n  hsa_status_t err;\n\n  assert(aql != nullptr);\n\n  if (aql == nullptr) {\n    return HSA_STATUS_ERROR;\n  }\n  \n  // Initialize Packet type as Invalid\n  // Update packet type to Kernel Dispatch\n  // right before ringing doorbell\n  aql->header = 1;\n\n  aql->setup = 1;\n  aql->workgroup_size_x = 256;\n  aql->workgroup_size_y = 1;\n  aql->workgroup_size_z = 1;\n\n  aql->grid_size_x = (uint64_t) 256;  // manual_input*group_input; workg max sz\n  aql->grid_size_y = 1;\n  aql->grid_size_z = 1;\n\n  aql->private_segment_size = test->private_segment_size();\n\n  aql->group_segment_size = test->group_segment_size();\n\n  // Pin kernel code and the kernel argument buffer to the aql packet->\n  aql->kernel_object = test->kernel_object();\n\n  // aql->kernarg_address may be filled in by AllocAndSetKernArgs() if it is\n  // called before this function, so we don't want overwrite it, therefore\n  // we ignore it in this function.\n\n  if (!aql->completion_signal.handle)\n    err = hsa_signal_create(1, 0, NULL, &aql->completion_signal);\n  else\n    err = HSA_STATUS_SUCCESS;\n\n  return err;\n}\n\n// Copy BaseRocR aql object values to the BaseRocR object queue in the\n// specified queue position (ind)\nhsa_kernel_dispatch_packet_t * WriteAQLToQueue(BaseRocR* test, uint64_t *ind) {\n  assert(test);\n  assert(test->main_queue());\n\n  void *queue_base = test->main_queue()->base_address;\n  const uint32_t queue_mask = test->main_queue()->size - 1;\n  uint64_t que_idx = hsa_queue_add_write_index_relaxed(test->main_queue(), 1);\n  *ind = que_idx;\n\n  hsa_kernel_dispatch_packet_t* staging_aql_packet = &test->aql();\n  hsa_kernel_dispatch_packet_t* queue_aql_packet;\n\n  queue_aql_packet =\n       &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue_base))\n                                                        [que_idx & queue_mask];\n\n  queue_aql_packet->workgroup_size_x = staging_aql_packet->workgroup_size_x;\n  queue_aql_packet->workgroup_size_y = staging_aql_packet->workgroup_size_y;\n  queue_aql_packet->workgroup_size_z = staging_aql_packet->workgroup_size_z;\n  queue_aql_packet->grid_size_x = staging_aql_packet->grid_size_x;\n  queue_aql_packet->grid_size_y = staging_aql_packet->grid_size_y;\n  queue_aql_packet->grid_size_z = staging_aql_packet->grid_size_z;\n  queue_aql_packet->private_segment_size =\n                                     staging_aql_packet->private_segment_size;\n  queue_aql_packet->group_segment_size =\n                                       staging_aql_packet->group_segment_size;\n  queue_aql_packet->kernel_object = staging_aql_packet->kernel_object;\n  queue_aql_packet->kernarg_address = staging_aql_packet->kernarg_address;\n  queue_aql_packet->completion_signal = staging_aql_packet->completion_signal;\n\n  return queue_aql_packet;\n}\n\nvoid\nWriteAQLToQueueLoc(hsa_queue_t *queue, uint64_t indx,\n                                      hsa_kernel_dispatch_packet_t *aql_pkt) {\n  assert(queue);\n  assert(aql_pkt);\n\n  void *queue_base = queue->base_address;\n  const uint32_t queue_mask = queue->size - 1;\n  hsa_kernel_dispatch_packet_t* queue_aql_packet;\n\n  queue_aql_packet =\n       &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue_base))\n                                                        [indx & queue_mask];\n\n  queue_aql_packet->workgroup_size_x = aql_pkt->workgroup_size_x;\n  queue_aql_packet->workgroup_size_y = aql_pkt->workgroup_size_y;\n  queue_aql_packet->workgroup_size_z = aql_pkt->workgroup_size_z;\n  queue_aql_packet->grid_size_x = aql_pkt->grid_size_x;\n  queue_aql_packet->grid_size_y = aql_pkt->grid_size_y;\n  queue_aql_packet->grid_size_z = aql_pkt->grid_size_z;\n  queue_aql_packet->private_segment_size =\n                                     aql_pkt->private_segment_size;\n  queue_aql_packet->group_segment_size =\n                                       aql_pkt->group_segment_size;\n  queue_aql_packet->kernel_object = aql_pkt->kernel_object;\n  queue_aql_packet->kernarg_address = aql_pkt->kernarg_address;\n  queue_aql_packet->completion_signal = aql_pkt->completion_signal;\n}\n\n// Allocate a buffer in the kern_arg_pool for the kernel arguments and write\n// the arguments to buffer\nhsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args, size_t arg_size) {\n  void* kern_arg_buf = nullptr;\n  hsa_status_t err;\n  size_t buf_size;\n  size_t req_align;\n  assert(args != nullptr);\n  assert(test != nullptr);\n\n  req_align = test->kernarg_align();\n  // Allocate enough extra space for alignment adjustments if ncessary\n  buf_size = arg_size + (req_align << 1);\n\n  err = hsa_amd_memory_pool_allocate(test->kern_arg_pool(), buf_size, 0,\n                                     reinterpret_cast<void**>(&kern_arg_buf));\n  RET_IF_HSA_UTILS_ERR(err);\n\n  test->set_kernarg_buffer(kern_arg_buf);\n\n  void *adj_kern_arg_buf = rocrtst::AlignUp(kern_arg_buf, req_align);\n\n  assert(arg_size >= test->kernarg_size());\n  assert(((uintptr_t)adj_kern_arg_buf + arg_size) <\n                                        ((uintptr_t)kern_arg_buf + buf_size));\n\n  hsa_agent_t ag_list[2] = {*test->gpu_device1(), *test->cpu_device()};\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, kern_arg_buf);\n  RET_IF_HSA_UTILS_ERR(err);\n\n  err = hsa_memory_copy(adj_kern_arg_buf, args, arg_size);\n  RET_IF_HSA_UTILS_ERR(err);\n\n  test->aql().kernarg_address = adj_kern_arg_buf;\n\n  return HSA_STATUS_SUCCESS;\n}\n\n#undef RET_IF_HSA_UTILS_ERR\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/base_rocr_utils.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_COMMON_BASE_ROCR_UTILS_H_\n#define ROCRTST_COMMON_BASE_ROCR_UTILS_H_ 1\n\n/// \\file\n/// Prototypes of utility functions that act on BaseRocR objects.\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n\nnamespace rocrtst {\n\n/// Locate kernel code object file and return path suitable for use with open().\nstd::string LocateKernelFile(std::string filename, hsa_agent_t agent);\n\n/// Open binary kernel object file and set all member data related to the\n/// kernel. Assumes that input test already has the kernel file name,\n/// agent name and kernel function specifed\n/// \\param[in] test Test for which the kernel will be loaded.\n/// \\param[in] agent for which the kernel will be loaded .\n/// \\returns HSA_STATUS_SUCCESS if no errors\nhsa_status_t LoadKernelFromObjFile(BaseRocR* test, hsa_agent_t* agent);\n\n/// Do initialization tasks for HSA test program.\n/// \\param[in] test Test to initialize\n/// \\returns HSA_STATUS_SUCCESS if no errors\nhsa_status_t InitAndSetupHSA(BaseRocR* test);\n\n/// Find and set the cpu and gpu agent member variables. Also checks that\n/// gpu agent meets test requirements (e.g., FULL profile vs. BASE profile).\nhsa_status_t SetDefaultAgents(BaseRocR* test);\n\n/// For the provided device agent, create an AQL queue\n/// \\param[in] device Device for which a queue is to be created\n/// \\param[out] queue Address to which created queue pointer will be written\n/// \\param[in] num_pkts Size of the queue to create\n/// \\param[in] do_profile [Optional] Specificy whether profiled queue should\n///  be created\n/// \\returns  HSA_STATUS_SUCCESS if no errors encountered\nhsa_status_t CreateQueue(hsa_agent_t device, hsa_queue_t** queue,\n                         uint32_t num_pkts = 0);\n\n/// This function sets some reasonable default values for an AQL packet.\n/// Override any field as necessary after calling this function.\n/// \\param[in] test Test from which information to populate aql packet can\n/// be drawn.\n/// \\param[inout] aql Caller provided pointer to aql packet that will be\n/// populated\n/// \\returns Appropriate hsa_status_t\nhsa_status_t InitializeAQLPacket(const BaseRocR* test,\n                         hsa_kernel_dispatch_packet_t* aql);\n\n/// This function writes all of the aql packet fields to the queue besides\n/// \"setup\" and \"header\". This assumes all the aql fields have be set\n/// appropriately.\n/// \\param[in] test Test containing the queue and aql packet to be written.\n/// \\returns Pointer to dispatch packet in queue that was written to\nhsa_kernel_dispatch_packet_t* WriteAQLToQueue(BaseRocR* test, uint64_t *ind);\n\nvoid WriteAQLToQueueLoc(hsa_queue_t *queue, uint64_t indx,\n                                      hsa_kernel_dispatch_packet_t *aql_pkt);\n/// This function writes the first 32 bits of an aql packet to the provided\n/// aql packet. This function is meant to be called immediately before\n/// ringing door_bell signal.\n/// \\param[in] header Value to be written to header field\n/// \\param[in] setup Value to be written to setup field\n/// \\param[in] queue_packet Start address of in queue memory of aql packet to\n/// be written\n/// \\returns void\ninline void AtomicSetPacketHeader(uint16_t header, uint16_t setup,\n                                hsa_kernel_dispatch_packet_t* queue_packet) {\n  __atomic_store_n(reinterpret_cast<uint32_t*>(queue_packet),\n                                    header | (setup <<16), __ATOMIC_RELEASE);\n}\n\n/// Perform common operations to clean up after executing a test. Specifically,\n/// hsa_shut_down() is called and environment variables that were changed are\n/// reset to their original values.\n/// \\param[in] test Test for which clean up with be performed\n/// \\returns HSA_STATUS_SUCCESS if everything cleaned up ok, or appropriate HSA\n///   error code otherwise.\nhsa_status_t CommonCleanUp(BaseRocR* test);\n\n///  Check to see if target machine has the necessary profile to run the\n///  provided test.\n///  \\param[1] test The test that specifies the required profile.\nbool CheckProfile(BaseRocR const* test);\n\n/// Allocate memory from the kernel args pool and write the provided argument\n/// data to the kernel arg memory. Assumes kern_arg memory pool has been\n/// assigned. The amount of memory allocated will actually be \\p arg_size\n/// plus the alignment required by the kernel arguments. The argument will\n/// be written with the proper alignment within the allocated buffer.\n/// \\p test kernarg_buffer() will point to the allocated buffer, and it should\n/// be freed when the kernel is no longer being used.\n/// \\param test Test from which to find kern_arg pool to write arguments\n/// \\param args pointer to block of data containing kernel arguments to be\n///  written. Arguments are assumed to be of the correct placement, length,\n///  and with any padding that is expected by the OpenCL kernel\n/// \\param arg_size Size of the kernel arg data (including padding) to be\n/// written\n/// \\returns HSA_STATUS_SUCCESS if no errors\nhsa_status_t AllocAndSetKernArgs(BaseRocR* test, void* args,\n                                 size_t arg_size);\n\n/// Verify that the machine running the test has the required profile.\n/// This function will verify that the execution machine meets any specific\n/// test requirement for a profile (HSA_PROFILE_BASE or HSA_PROFILE_FULL).\n/// \\param[in] test Test that provides profile requirements.\n/// \\returns bool\n///          - true Machine meets test requirements\n///          - false Machine does not meet test requirements\nbool CheckProfileAndInform(BaseRocR* test);\n\n/// This function will set the cpu and gpu memory pools to the type used in\n/// many applications.\n/// \\param[in] test Test that provides profile requirements.\n/// \\returns HSA_STATUS_SUCCESS if everything cleaned up ok, or appropriate HSA\n///   error code otherwise.\nhsa_status_t SetPoolsTypical(BaseRocR* test);\n\n/// Work-around for hsa_amd_memory_fill, which is currently broken.\n/// \\param[in] ptr Pointer to start of memory location to be filled\n/// \\param[in] value Value to write to each byte of input buffer\n/// \\param[in] count Size of buffer to fill\n/// \\param[in] dst_ag Agent owning the buffer to be filled\n/// \\param[in] src_ag Agent wanting to do the fill\n/// \\param[in] test Test that has handles to cpu and gpu agents that can own\n/// either source or destination of fill\n/// \\returns HSA_STATUS_OK if not errors\nhsa_status_t hsa_memory_fill_workaround_gen(void* ptr, uint32_t value,\n      size_t count, hsa_agent_t dst_ag, hsa_agent_t src_ag, BaseRocR* test);\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_BASE_ROCR_UTILS_H_\n"
  },
  {
    "path": "rocrtst/common/common.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/// \\file\n/// Implementation of utility functions used by RocR applications\n#include \"common/common.h\"\n#include <assert.h>\n#include <sstream>\n#include <string>\n#include <memory>\n\nnamespace rocrtst {\n\n\n#define RET_IF_HSA_COMMON_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n              __FILE__ << \". Call returned \" << err << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nstatic hsa_status_t FindAgent(hsa_agent_t agent, void* data,\n                                                hsa_device_type_t dev_type) {\n  assert(data != nullptr);\n\n  if (data == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE,\n                                &hsa_device_type);\n  RET_IF_HSA_COMMON_ERR(hsa_error_code);\n\n  if (hsa_device_type == dev_type) {\n    *(reinterpret_cast<hsa_agent_t*>(data)) = agent;\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Find CPU Agents\nhsa_status_t IterateCPUAgents(hsa_agent_t agent, void *data) {\n  hsa_status_t status;\n  assert(data != nullptr);\n  if (data == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  std::vector<hsa_agent_t>* cpus = static_cast<std::vector<hsa_agent_t>*>(data);\n  hsa_device_type_t device_type;\n  status = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n  RET_IF_HSA_COMMON_ERR(status);\n  if (HSA_STATUS_SUCCESS == status && HSA_DEVICE_TYPE_CPU == device_type) {\n    cpus->push_back(agent);\n  }\n  return status;\n}\n\n\n\n// Find GPU Agents\nhsa_status_t IterateGPUAgents(hsa_agent_t agent, void *data) {\n  hsa_status_t status;\n  assert(data != nullptr);\n  if (data == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  std::vector<hsa_agent_t>* gpus = static_cast<std::vector<hsa_agent_t>*>(data);\n  hsa_device_type_t device_type;\n  status = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n  RET_IF_HSA_COMMON_ERR(status);\n  if (HSA_STATUS_SUCCESS == status && HSA_DEVICE_TYPE_GPU == device_type) {\n    gpus->push_back(agent);\n  }\n  return status;\n}\n\n// Find coarse grained device memory if this exists.  Fine grain otherwise.\nhsa_status_t GetGlobalMemoryPool(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_amd_segment_t segment;\n  hsa_status_t err;\n  hsa_amd_memory_pool_t* ret = reinterpret_cast<hsa_amd_memory_pool_t*>(data);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                                         HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                         &segment);\n  RET_IF_HSA_COMMON_ERR(err);\n  if (HSA_AMD_SEGMENT_GLOBAL != segment)\n    return HSA_STATUS_SUCCESS;\n\n  hsa_amd_memory_pool_global_flag_t flags;\n  err = hsa_amd_memory_pool_get_info(pool,\n                                        HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS,\n                                        &flags);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  // this is valid for dGPUs. But on APUs, it has to be FINE_GRAINED\n  if (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED) {\n    *ret = pool;\n  } else {  // this is for APUs\n    if ((ret == nullptr) && (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED)) {\n      *ret = pool;\n    }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n// Find  a memory pool that can be used for kernarg locations.\nhsa_status_t GetKernArgMemoryPool(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_status_t err;\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  hsa_amd_segment_t segment;\n  err = hsa_amd_memory_pool_get_info(pool,\n                                         HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                         &segment);\n  RET_IF_HSA_COMMON_ERR(err);\n  if (HSA_AMD_SEGMENT_GLOBAL != segment) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  hsa_amd_memory_pool_global_flag_t flags;\n  err = hsa_amd_memory_pool_get_info(pool,\n                                         HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS,\n                                         &flags);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  if (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT) {\n    hsa_amd_memory_pool_t* ret =\n                                reinterpret_cast<hsa_amd_memory_pool_t*>(data);\n    *ret = pool;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindGPUDevice(hsa_agent_t agent, void* data) {\n  return FindAgent(agent, data, HSA_DEVICE_TYPE_GPU);\n}\n\nhsa_status_t FindCPUDevice(hsa_agent_t agent, void* data) {\n  return FindAgent(agent, data, HSA_DEVICE_TYPE_CPU);\n}\n\n/// Ennumeration that indicates whether a pool property must be present or not.\n/// This is meant to be used by FindPool\ntypedef enum {\n  POOL_PROP_OFF = 0,   ///< The property must be present.\n  POOL_PROP_ON,        ///< The property must not be present.\n  POOL_PROP_DONT_CARE  ///< We don't care if the property is present or not.\n} pool_prop_t;\n\nstatic hsa_status_t\nFindPool(hsa_amd_memory_pool_t pool, void* data, hsa_amd_segment_t in_segment,\n    pool_prop_t accessible_by_all, pool_prop_t kern_arg,\n                                                    pool_prop_t fine_grain) {\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_status_t err;\n  hsa_amd_segment_t segment;\n  uint32_t flag;\n\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                     &segment);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  if (in_segment != segment) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (HSA_AMD_SEGMENT_GLOBAL == in_segment) {\n    err = hsa_amd_memory_pool_get_info(pool,\n                               HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);\n    RET_IF_HSA_COMMON_ERR(err);\n\n    if (kern_arg != POOL_PROP_DONT_CARE) {\n      uint32_t karg_st = flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT;\n      if ((karg_st == 0 && kern_arg == POOL_PROP_ON) ||\n          (karg_st != 0 && kern_arg == POOL_PROP_OFF)) {\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n    if (fine_grain != POOL_PROP_DONT_CARE) {\n      uint32_t fg_st = flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED;\n      if ((fg_st == 0 && fine_grain == POOL_PROP_ON) ||\n          (fg_st != 0 && fine_grain == POOL_PROP_OFF)) {\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n  }\n\n  if (accessible_by_all != POOL_PROP_DONT_CARE) {\n    bool access_read;\n    err = hsa_amd_memory_pool_get_info(pool,\n          (hsa_amd_memory_pool_info_t)\n                    HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL, &access_read);\n    RET_IF_HSA_COMMON_ERR(err);\n\n    if (((!access_read) && accessible_by_all == POOL_PROP_ON) ||\n        (access_read  && (accessible_by_all == POOL_PROP_OFF))) {\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n\n  *(reinterpret_cast<hsa_amd_memory_pool_t*>(data)) = pool;\n  return HSA_STATUS_INFO_BREAK;\n}\n\nhsa_status_t FindStandardPool(hsa_amd_memory_pool_t pool, void* data) {\n  return FindPool(pool, data, HSA_AMD_SEGMENT_GLOBAL, POOL_PROP_DONT_CARE,\n                                          POOL_PROP_OFF, POOL_PROP_DONT_CARE);\n}\n\nhsa_status_t FindKernArgPool(hsa_amd_memory_pool_t pool, void* data) {\n    return FindPool(pool, data, HSA_AMD_SEGMENT_GLOBAL, POOL_PROP_DONT_CARE,\n                                            POOL_PROP_ON, POOL_PROP_DONT_CARE);\n}\nhsa_status_t FindGlobalPool(hsa_amd_memory_pool_t pool, void* data) {\n  return FindPool(pool, data, HSA_AMD_SEGMENT_GLOBAL, POOL_PROP_ON,\n                                          POOL_PROP_OFF, POOL_PROP_DONT_CARE);\n}\n\nhsa_status_t FindAPUStandardPool(hsa_amd_memory_pool_t pool, void* data) {\n  return FindPool(pool, data, HSA_AMD_SEGMENT_GLOBAL, POOL_PROP_DONT_CARE,\n                                          POOL_PROP_DONT_CARE, POOL_PROP_DONT_CARE);\n}\n\n// Populate the vector with handles to all agents and pools\nhsa_status_t\nGetAgentPools(std::vector<std::shared_ptr<agent_pools_t>> *agent_pools) {\n  hsa_status_t err;\n\n  assert(agent_pools != nullptr);\n\n  auto save_agent = [](hsa_agent_t a, void *data)->hsa_status_t {\n    std::vector<std::shared_ptr<agent_pools_t>> *ag_vec;\n    hsa_status_t err;\n    assert(data != nullptr);\n    ag_vec =\n        reinterpret_cast<std::vector<std::shared_ptr<agent_pools_t>> *>(data);\n    std::shared_ptr<agent_pools_t> ag(new agent_pools_t);\n    ag->agent = a;\n\n\n    auto save_pool = [](hsa_amd_memory_pool_t p, void *data)->hsa_status_t {\n      assert(data != nullptr);\n      std::vector<hsa_amd_memory_pool_t> *p_list =\n                 reinterpret_cast<std::vector<hsa_amd_memory_pool_t> *>(data);\n      p_list->push_back(p);\n\n      return HSA_STATUS_SUCCESS;\n    };\n\n    err = hsa_amd_agent_iterate_memory_pools(a, save_pool,\n                                        reinterpret_cast<void *>(&ag->pools));\n    ag_vec->push_back(ag);\n    return err;\n  };\n\n  err = hsa_iterate_agents(save_agent, reinterpret_cast<void *>(agent_pools));\n  return err;\n}\n\nstatic hsa_status_t MakeGlobalFlagsString(const pool_info_t *pool_i,\n                                        std::string* out_str) {\n  uint32_t global_flag = pool_i->global_flag;\n\n  assert(out_str != nullptr);\n\n  *out_str = \"\";\n\n  std::vector < std::string > flags;\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT & global_flag) {\n    flags.push_back(\"KERNARG\");\n  }\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED & global_flag) {\n    flags.push_back(\"FINE GRAINED\");\n  }\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED & global_flag) {\n    flags.push_back(\"EXT-SCOPE FINE GRAINED\");\n  }\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED & global_flag) {\n    flags.push_back(\"COARSE GRAINED\");\n  }\n\n  if (flags.size() > 0) {\n    *out_str += flags[0];\n  }\n\n  for (size_t i = 1; i < flags.size(); i++) {\n    *out_str += \", \" + flags[i];\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\nstatic hsa_status_t DumpSegment(const pool_info_t *pool_i,\n                                 std::string const *ind_lvl) {\n  hsa_status_t err;\n\n  fprintf(stdout, \"%s%-28s\", ind_lvl->c_str(), \"Pool Segment:\");\n  std::string seg_str = \"\";\n  std::string tmp_str;\n\n  switch (pool_i->segment) {\n    case HSA_AMD_SEGMENT_GLOBAL:\n      err = MakeGlobalFlagsString(pool_i, &tmp_str);\n      RET_IF_HSA_COMMON_ERR(err);\n\n      seg_str += \"GLOBAL; FLAGS: \" + tmp_str;\n      break;\n\n    case HSA_AMD_SEGMENT_READONLY:\n      seg_str += \"READONLY\";\n      break;\n\n    case HSA_AMD_SEGMENT_PRIVATE:\n      seg_str += \"PRIVATE\";\n      break;\n\n    case HSA_AMD_SEGMENT_GROUP:\n      seg_str += \"GROUP\";\n      break;\n\n    default:\n      std::cout << \"Not Supported\" << std::endl;\n      break;\n  }\n\n  fprintf(stdout, \"%-35s\\n\", seg_str.c_str());\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AcquirePoolInfo(hsa_amd_memory_pool_t pool,\n                                                        pool_info_t *pool_i) {\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                  HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &pool_i->global_flag);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                                             &pool_i->segment);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  // Get the size of the POOL\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE,\n                                                          &pool_i->size);\n  RET_IF_HSA_COMMON_ERR(err);\n\n#ifdef ROCRTST_EMULATOR_BUILD\n  // Limit pool sizes to 2 GB on emulator\n  const size_t max_pool_size = 2*1024*1024*1024UL;\n  pool_i->size = std::min(pool_i->size, max_pool_size);\n#endif\n\n  err = hsa_amd_memory_pool_get_info(pool,\n             HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,\n                                                      &pool_i->alloc_allowed);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n             HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE,\n                                                      &pool_i->alloc_granule);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE,\n                                     &pool_i->alloc_rec_granule);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                           HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT,\n                                               &pool_i->alloc_alignment);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                      HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL,\n                                                  &pool_i->accessible_by_all);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                       HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                       &pool_i->aggregate_alloc_max);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t DumpMemoryPoolInfo(const pool_info_t *pool_i,\n                                uint32_t indent) {\n  std::string ind_lvl(indent, ' ');\n\n  DumpSegment(pool_i, &ind_lvl);\n\n  std::string sz_str = std::to_string(pool_i->size / 1024) + \"KB\";\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Size:\",\n          sz_str.c_str());\n\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Allocatable:\",\n          (pool_i->alloc_allowed ? \"TRUE\" : \"FALSE\"));\n\n  std::string gr_str = std::to_string(pool_i->alloc_granule / 1024) + \"KB\";\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Alloc Granule:\",\n          gr_str.c_str());\n\n  std::string recgr_str = std::to_string(pool_i->alloc_rec_granule / 1024) + \"KB\";\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(),\n          \"Pool Alloc Recommended Granule:\", recgr_str.c_str());\n\n  std::string al_str =\n                   std::to_string(pool_i->alloc_alignment / 1024) + \"KB\";\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Alloc Alignment:\",\n          al_str.c_str());\n\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Acessible by all:\",\n          (pool_i->accessible_by_all ? \"TRUE\" : \"FALSE\"));\n\n  std::string agg_str =\n              std::to_string(pool_i->aggregate_alloc_max / 1024) + \"KB\";\n  fprintf(stdout, \"%s%-28s%-36s\\n\", ind_lvl.c_str(), \"Pool Aggregate Alloc Size:\",\n          agg_str.c_str());\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic const char* Types[] = {\"HSA_EXT_POINTER_TYPE_UNKNOWN\",\n                              \"HSA_EXT_POINTER_TYPE_HSA\",\n                              \"HSA_EXT_POINTER_TYPE_LOCKED\",\n                              \"HSA_EXT_POINTER_TYPE_GRAPHICS\",\n                              \"HSA_EXT_POINTER_TYPE_IPC\"\n                             };\n\nhsa_status_t DumpPointerInfo(void* ptr) {\n  hsa_amd_pointer_info_t info;\n  hsa_agent_t* agents;\n  uint32_t count;\n  hsa_status_t err;\n\n  err = hsa_amd_pointer_info(ptr, &info, malloc, &count, &agents);\n  RET_IF_HSA_COMMON_ERR(err);\n\n  std::cout << \"Info for ptr: \" << ptr << std::endl;\n  std::cout << \"CPU ptr: \" << reinterpret_cast<void*>(info.hostBaseAddress) <<\n                                                                     std::endl;\n  std::cout << \"GPU ptr: \" << reinterpret_cast<void*>(info.agentBaseAddress)\n                                                                  << std::endl;\n  std::cout << \"Size: \" << info.sizeInBytes << std::endl;\n  std::cout << \"Type: \" << Types[info.type] << std::endl;\n  std::cout << \"UsrPtr \" << reinterpret_cast<void*>(info.userData) <<\n                                                                     std::endl;\n  std::cout << \"Accessible by: \";\n\n  for (uint32_t i = 0; i < count; i++) {\n    std::cout << agents[i].handle << \" \";\n  }\n\n  std::cout << \" ;[EOM]\" << std::endl;\n  free(agents);\n  return HSA_STATUS_SUCCESS;\n}\n\n\n/*! \\brief Writes to the buffer and increments the write pointer to the\n *         buffer. Also, ensures that the argument is written to an\n *         aligned memory as specified. Return the new write pointer.\n *\n * @param dst The write pointer to the buffer\n * @param src The source pointer\n * @param size The size in bytes to copy\n * @param alignment The alignment to follow while writing to the buffer\n */\n#if 0\ninline void *\naddArg(void * dst, const void* src, size_t size, uint32_t alignment) {\n    dst = rocrtst::AlignUp(dst, alignment);\n    ::memcpy(dst, src, size);\n    return dst + size;\n}\n#endif\n#undef RET_IF_HSA_COMMON_ERR\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/common.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/// \\file\n/// RocR related helper functions for sequeneces that come up frequently\n\n#ifndef ROCRTST_COMMON_COMMON_H_\n#define ROCRTST_COMMON_COMMON_H_\n\n#include <stdio.h>\n#include <string.h>\n#include <cmath>\n#include <cstdlib>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\nnamespace rocrtst {\n\n#if defined(_MSC_VER)\n#define ALIGNED_(x) __declspec(align(x))\n#else\n#if defined(__GNUC__)\n#define ALIGNED_(x) __attribute__ ((aligned(x)))\n#endif  // __GNUC__\n#endif  // _MSC_VER\n\n#define MULTILINE(...) # __VA_ARGS__\n\n// define below should be deleted. Leaving in commented out until code that\n// refers to it has been corrected\n// #define HSA_ARGUMENT_ALIGN_BYTES 16\n\n// This structure holds memory pool information acquired through hsa info\n// related calls, and is later used for reference when displaying the\n// information.\ntypedef struct pool_info_t_ {\n    uint32_t segment;\n    size_t size;\n    bool alloc_allowed;\n    size_t alloc_granule;\n    size_t alloc_alignment;\n    size_t alloc_rec_granule;\n    bool accessible_by_all;\n    uint32_t global_flag;\n    uint64_t aggregate_alloc_max;\n    inline bool operator==(const pool_info_t_ &a) {\n      if (a.segment == segment && a.size == size\n          && a.alloc_allowed == alloc_allowed\n          && a.alloc_granule == alloc_granule\n          && a.alloc_rec_granule == alloc_rec_granule\n          && a.alloc_alignment == alloc_alignment\n          && a.accessible_by_all == accessible_by_all\n          && a.aggregate_alloc_max == aggregate_alloc_max\n          && a.global_flag == global_flag )\n          return true;\n      else\n          return false;\n    }\n} pool_info_t;\n\n\nstruct agent_pools_t{\n    hsa_agent_t agent;\n    std::vector<hsa_amd_memory_pool_t> pools;\n};\n\n/// Fill in the pool_info_t structure for the provided pool.\n/// \\param[in] pool Pool for which information will be retrieved\n/// \\param[out] pool_i Pointer to structure where pool info will be stored\n/// \\returns HSA_STATUS_SUCCESS if no errors are encountered.\nhsa_status_t AcquirePoolInfo(hsa_amd_memory_pool_t pool, pool_info_t *pool_i);\n\n/// If the provided agent is associated with a GPU, return that agent through\n/// output parameter. This function is meant to be the call-back function used\n/// with hsa_iterate_agents to find GPU agents.\n/// \\param[in] agent Agent to evaluate if GPU\n/// \\param[out] data If agent is associated with a GPU, this pointer will point\n///  to the agent upon return\n/// \\returns HSA_STATUS_SUCCESS if no errors are encountered.\nhsa_status_t FindGPUDevice(hsa_agent_t agent, void* data);\n\n/// If the provided agent is associated with a CPU, return that agent through\n/// output parameter. This function is meant to be the call-back function used\n/// with hsa_iterate_agents to find CPU agents.\n/// \\param[in] agent Agent to evaluate if CPU\n/// \\param[out] data If agent is associated with a CPU, this pointer will point\n///  to the agent upon return\n/// \\returns HSA_STATUS_SUCCESS if no errors are encountered.\nhsa_status_t FindCPUDevice(hsa_agent_t agent, void* data);\n\n// TODO(cfreehil): get rid of FindGlobalPool and replace with FindStandardPool\nhsa_status_t FindGlobalPool(hsa_amd_memory_pool_t pool, void* data);\n\n/// If the provided agent is associated with a CPU, return that agent through\n/// output parameter. This function is meant to be the call-back function used\n/// with hsa_iterate_agents to find all the CPU agents.\n/// \\param[in] agent Agent to evaluate if CPU\n/// \\param[out] data If agent is associated with a CPU, this pointer will point\n///  to the agent upon return\n/// \\returns HSA_STATUS_SUCCESS if no errors are encountered.\nhsa_status_t IterateCPUAgents(hsa_agent_t agent, void *data);\n\n/// If the provided agent is associated with a GPU, return that agent through\n/// output parameter. This function is meant to be the call-back function used\n/// with hsa_iterate_agents to find  all the GPU agents.\n/// \\param[in] agent Agent to evaluate if GPU\n/// \\param[out] data If agent is associated with a GPU, this pointer will point\n///  to the agent upon return\n/// \\returns HSA_STATUS_SUCCESS if no errors are encountered.\nhsa_status_t IterateGPUAgents(hsa_agent_t agent, void *data);\n\n/// Find a GLOBAL memory pool. By this, we mean not a kernel args pool.\n/// This function is meant to be the call-back function used\n/// with hsa_amd_agent_iterate_memory_pools.\n/// \\param[in] pool Pool to evaluate for required properties\n/// \\param[in] data If pool meets criteria, this pointer will point\n///  to the pool upon return\n/// \\returns hsa_status_t\n///      -HSA_STATUS_INFO_BREAK - we found a pool that meets criteria\n///      -HSA_STATUS_SUCCESS - we did not find a pool that meets the criteria\n///      -else return an appropriate error code for any error encountered\nhsa_status_t GetGlobalMemoryPool(hsa_amd_memory_pool_t pool, void* data);\n\n/// Find a \"kernel arg\" pool.\n/// This function is meant to be the call-back function used\n/// with hsa_amd_agent_iterate_memory_pools.\n/// \\param[in] pool Pool to evaluate for required properties\n/// \\param[in] data If pool meets criteria, this pointer will point\n///  to the pool upon return\n/// \\returns hsa_status_t\n///      -HSA_STATUS_INFO_BREAK - we found a pool that meets criteria\n///      -HSA_STATUS_SUCCESS - we did not find a pool that meets the criteria\n///      -else return an appropriate error code for any error encountered\nhsa_status_t GetKernArgMemoryPool(hsa_amd_memory_pool_t pool, void* data);\n\n\n/// Find a \"standard\" pool. By this, we mean not a kernel args pool.\n/// The pool found will have the following properties:\n///     HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL: Don't care\n///     HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT: Off\n///     HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED: Don't care\n/// This function is meant to be the call-back function used\n/// with hsa_amd_agent_iterate_memory_pools.\n/// \\param[in] pool Pool to evaluate for required properties\n/// \\param[in] data If pool meets criteria, this pointer will point\n///  to the pool upon return\n/// \\returns hsa_status_t\n///      -HSA_STATUS_INFO_BREAK - we found a pool that meets criteria\n///      -HSA_STATUS_SUCCESS - we did not find a pool that meets the criteria\n///      -else return an appropriate error code for any error encountered\nhsa_status_t FindStandardPool(hsa_amd_memory_pool_t pool, void* data);\nhsa_status_t FindAPUStandardPool(hsa_amd_memory_pool_t pool, void* data);\n\n/// Find a \"kernel arg\" pool.\n/// The pool found will have the following properties:\n///     HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL: Don't care\n///     HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT: On\n///     HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED: Don't care\n/// This function is meant to be the call-back function used\n/// with hsa_amd_agent_iterate_memory_pools.\n/// \\param[in] pool Pool to evaluate for required properties\n/// \\param[in] data If pool meets criteria, this pointer will point\n///  to the pool upon return\n/// \\returns hsa_status_t\n///      -HSA_STATUS_INFO_BREAK - we found a pool that meets criteria\n///      -HSA_STATUS_SUCCESS - we did not find a pool that meets the criteria\n///      -else return an appropriate error code for any error encountered\nhsa_status_t FindKernArgPool(hsa_amd_memory_pool_t pool, void* data);\n\n/// Dump information about provided memory pool to STDOUT\n/// \\param[in] pool Pool to gather and dump information for\n/// \\param[in] indent Number of spaces to indent output.\n/// \\returns hsa_status_t HSA_STATUS_SUCCESS if no errors\nhsa_status_t DumpMemoryPoolInfo(const pool_info_t *pool_i,\n                                                         uint32_t indent = 0);\n\n/// Dump information about a provided pointer to STDOUT.\n/// \\param[in] ptr Pointer about which information is dumped.\n/// \\returns HSA_STATUS_SUCCESS if there are no errors\nhsa_status_t DumpPointerInfo(void* ptr);\n\nhsa_status_t GetAgentPools(\n                    std::vector<std::shared_ptr<agent_pools_t>> *agent_pools);\n\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_COMMON_H_\n"
  },
  {
    "path": "rocrtst/common/concurrent_utils.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <errno.h>\n#include <stdio.h>\n#include <signal.h>\n#include <cstdlib>\n#include \"common/concurrent_utils.h\"\n\nnamespace rocrtst {\n\n/**\n * @brief worker function is invoked by each thread to execute tests\n * Initially, all threads are blocked to wait run_flag. After run_flag being\n * set up, the worker function begin to execute test function and change\n * the status of tests to TEST_RUNNING. After test function finish, the status\n * of tests will be changed to TEST_FINISHED, and worker function will be\n * blocked until run_flag being set up again.\n * @param input Pointer to thread_aux data structure, which contains test\n * function pointer and corresponding args for the test function, and other\n * auxiliary information, including status of test, number of running tests,\n * run_flag, exit_flag, etc.\n */\n\nstatic void *worker(void *input) {\n  func_ptr fun_prt;\n  thread_aux* thread = reinterpret_cast<thread_aux*>(input);\n  fun_prt = reinterpret_cast<func_ptr>(thread->test->fun_prt);\n  int run_flag_l = 0;\n\n  // While loop to repeatedly execute test function\n  while (1) {\n    pthread_mutex_lock(thread->test_mutex);\n    // Blocked to wait run_flag or exit_flag being changed\n    while (*thread->run_flag == run_flag_l && *thread->exit_flag == 0) {\n      pthread_cond_wait(thread->test_cond, thread->test_mutex);\n    }\n    pthread_mutex_unlock(thread->test_mutex);\n\n    // Reset run_flag\n    run_flag_l = run_flag_l ^ 1;\n\n    // If exit_flag is 0, run test function and set status of the test to\n    // TEST_RUNNING\n    if (*thread->exit_flag == 0) {\n      thread->test->status = TEST_RUNNING;\n      fun_prt(thread->test->data);\n\n      // After test function finish, subtract the number of running tests via atomic operations\n      // and check the number of running tests, if the number equal to 1,\n      // it means all tests are finished, broadcast a signal to the wakeup master\n      // thread.\n      pthread_mutex_lock(thread->test_mutex);\n      (*(thread->num_running_t))--;\n\n      if ((*thread->num_running_t) == 0) {\n        pthread_cond_broadcast(thread->test_cond);\n      }\n      pthread_mutex_unlock(thread->test_mutex);\n\n      // Set status of the test to TEST_STOP\n      thread->test->status = TEST_STOP;\n    } else {\n      // If exit_flag is no-zero, set status of the test to TEST_FINISHED\n      thread->test->status = TEST_FINISHED;\n      pthread_exit(NULL);\n    }\n  }\n  return NULL;\n}\n\n/**\n * @brief create a test_group data structure, initialize variables in\n * the test_group structure, allocate a test_list of group_size and\n * return a pointer to the test_group.\n * @param group_size The size of test group, i.e., the size of test lists\n * @return Pointer to the new test_group\n */\ntest_group *TestGroupCreate(size_t group_size) {\n  test_group *new_group = static_cast<test_group *>(malloc(sizeof(test_group)));\n  // initialize variables in the data structure\n  new_group->group_size = group_size;\n  new_group->n_threads = 0;\n  new_group->num_test = 0;\n  new_group->run_flag = 0;\n  new_group->exit_flag = 0;\n  new_group->num_running_t = 0;\n  // malloc test_list array with group_size\n  new_group->test_list = static_cast<test_aux *>(malloc(sizeof(test_aux) * group_size));\n\n  return new_group;\n}\n\nvoid TestGroupWait(test_group *t_group) {\n  pthread_mutex_lock(&t_group->test_mutex);\n  while (t_group->num_running_t != 0) {\n    pthread_cond_wait(&t_group->test_cond, &t_group->test_mutex);\n  }\n  pthread_mutex_unlock(&t_group->test_mutex);\n\n  return;\n}\n\nvoid TestGroupAdd(test_group *t_group, func_ptr fun_prt, void *data, size_t num_copy) {\n  if (t_group->group_size < (num_copy + t_group->num_test)) {\n    fprintf(stderr, \"Error beyound group size: %lu, please resize the test_group\\n\", t_group->group_size);\n    return;\n  }\n\n  int num_test = t_group->num_test;\n  test_aux *test_list = t_group->test_list;\n  unsigned int ii;\n  for (ii = 0; ii < num_copy; ii++) {\n    test_list[num_test + ii].fun_prt = reinterpret_cast<void*>(fun_prt);\n    test_list[num_test + ii].data = data;\n    test_list[num_test + ii].status = TEST_NOT_STARTED;\n  }\n  t_group->num_test = num_test + num_copy;\n\n  return;\n}\n\nvoid TestGroupResize(test_group *t_group, size_t new_group_size) {\n  if (new_group_size < t_group->group_size) {\n    fprintf(stderr, \"Error new group_size is smaller than current group_size\\n\");\n  }\n\n  test_aux *new_test_list;\n  new_test_list = static_cast<test_aux *>(realloc(t_group->test_list, new_group_size * sizeof(test_aux)));\n  t_group->group_size = new_group_size;\n  t_group->test_list = new_test_list;\n\n  return;\n}\n\n// Create threads for tests\nvoid TestGroupThreadCreate(test_group *t_group) {\n  pthread_mutex_init(&(t_group->test_mutex), NULL);\n  pthread_cond_init(&(t_group->test_cond), NULL);\n  pthread_attr_init(&(t_group->attr));\n  pthread_attr_setdetachstate(&(t_group->attr), PTHREAD_CREATE_JOINABLE);\n\n  int n_threads;\n  int ii = 0;\n\n  n_threads = t_group->n_threads = t_group->num_test;\n  thread_aux *thread_list = t_group->thread_list =\n              static_cast<thread_aux *>(malloc(sizeof(thread_aux) * n_threads));\n  t_group->tid = static_cast<pthread_t*>(malloc(sizeof(pthread_t) * n_threads));\n\n  for (ii = 0; ii < n_threads; ++ii) {\n    // CPU_ZERO(&thread_list[ii].cpuset);\n    thread_list[ii].tid = ii;\n    thread_list[ii].test = t_group->test_list + ii;\n    thread_list[ii].run_flag = &(t_group->run_flag);\n    thread_list[ii].exit_flag = &(t_group->exit_flag);\n    thread_list[ii].test_mutex = &(t_group->test_mutex);\n    thread_list[ii].test_cond = &(t_group->test_cond);\n    thread_list[ii].num_running_t = &(t_group->num_running_t);\n    int status = pthread_create(t_group->tid + ii, &(t_group->attr), worker, thread_list + ii);\n\n    // Print error statements and break\n    if (status != 0) {\n      printf(\"pthread_create return value %d\\n\", status);\n      printf(\"pthread_create error at idx: %d of %d\\n\", ii, n_threads);\n      perror(\"pthread_create failed\");\n      break;\n    }\n  }\n\n  // Update test group properties to \n  // accommodate thread creation error\n  t_group->num_test = ii;\n  t_group->n_threads = ii;\n  return;\n}\n\n// Return number of test\nint TestGroupNumTests(test_group *t_group) {\n  return t_group->num_test;\n}\n\n// Set affinity of the specific test\nvoid TestGroupThreadAffinity(test_group *t_group, int test_id, int cpu_id) {\n/*  Setting CPU affinity isn't currently supported.\n *  CPU_SET(cpu_id, &t_group->thread_list[test_id].cpuset);\n *  int status;\n *  status = pthread_setaffinity_np(t_group->tid[test_id],\n *          sizeof(cpu_set_t), &t_group->thread_list[test_id].cpuset);\n *  if (status != 0) {\n *      perror(\"pthread_setaffinity_np error\");\n *  }\n */\n  return;\n}\n\n// Set run_flag to 1\nvoid TestGroupStart(test_group *t_group) {\n  if (t_group->num_running_t != 0) {\n    fprintf(stderr, \"Error: %d tests are not finished\\n\", t_group->num_running_t);\n    return;\n  }\n\n  pthread_mutex_lock(&t_group->test_mutex);\n  t_group->run_flag = t_group->run_flag ^ 1;\n  t_group->num_running_t = t_group->num_test;\n  pthread_cond_broadcast(&t_group->test_cond);\n  pthread_mutex_unlock(&t_group->test_mutex);\n\n  return;\n}\n\n// Set exit_flag to 1, wait all threads finish and cleanup\nvoid TestGroupExit(test_group *t_group) {\n  int ii = 0;\n  int status;\n\n  pthread_mutex_lock(&t_group->test_mutex);\n  t_group->exit_flag = 1;\n  pthread_cond_broadcast(&t_group->test_cond);\n  pthread_mutex_unlock(&t_group->test_mutex);\n\n  for (ii = 0; ii < t_group->n_threads; ++ii) {\n    status = pthread_join(t_group->tid[ii], 0);\n    if (status < 0) {\n      perror(\"pthread_join failed\");\n      t_group->test_list[ii].status = TEST_ERROR;\n    }\n  }\n\n  pthread_attr_destroy(&(t_group->attr));\n  pthread_mutex_destroy(&(t_group->test_mutex));\n  pthread_cond_destroy(&(t_group->test_cond));\n\n  free(t_group->tid);\n  free(t_group->thread_list);\n\n  return;\n}\n\nvoid TestGroupKill(test_group *t_group) {\n  int ii = 0;\n  int status;\n  for (ii = 0; ii < t_group->n_threads; ++ii) {\n    status = pthread_cancel(t_group->tid[ii]);\n    if (status < 0) {\n      perror(\"pthread_cancel failed\");\n      t_group->test_list[ii].status = TEST_ERROR;\n    }\n  }\n\n  pthread_attr_destroy(&(t_group->attr));\n  pthread_mutex_destroy(&(t_group->test_mutex));\n  pthread_cond_destroy(&(t_group->test_cond));\n\n  free(t_group->tid);\n  free(t_group->thread_list);\n\n  return;\n}\n\nvoid TestGroupDestroy(test_group *t_group) {\n  free(t_group->test_list);\n  free(t_group);\n\n  return;\n}\n\nint TestGroupTestStatus(test_group *t_group, int test_id) {\n  if (test_id >= t_group->n_threads) {\n    fprintf(stderr, \"test_id: %d is larger than the number of test: %d\\n\", test_id, t_group->num_test);\n  }\n\n  if (t_group->test_list[test_id].status == TEST_RUNNING) {\n    if (pthread_kill(t_group->tid[test_id], 0) == ESRCH) {\n      t_group->test_list[test_id].status = TEST_ERROR;\n    }\n  }\n\n  return t_group->test_list[test_id].status;\n}\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/concurrent_utils.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_COMMON_CONCURRENT_UTILS_H_\n#define ROCRTST_COMMON_CONCURRENT_UTILS_H_\n\n#include <pthread.h>\n#include <stdint.h>\n#include <iostream>\n\n\nnamespace rocrtst {\n/**\n * @enum TEST_STATUS\n * @brief This enum lists status of test pthread\n */\nenum TEST_STATUS {TEST_NOT_STARTED, TEST_RUNNING,\n                  TEST_STOP, TEST_FINISHED, TEST_ERROR};\n\n\ntypedef void (*func_ptr)(void *input);\n/**\n * @struct test_aux\n * @brief This structure holds information for a test\n */\nstruct test_aux{\n    // Pointer to the test function\n    void *fun_prt;\n    // Pointer to the data for the test function\n    void *data;\n    // status of the test listed in enum TEST_STATUS\n    uint16_t status;\n};\n\n/**\n * @struct thread_aux\n * @brief This structure holds the data for a test thread.\n */\nstruct thread_aux {\n    // Thread Id\n    int tid;\n    // Pointer to a test item\n    test_aux *test;\n    // Pointer to the run_flag shared in the test group\n    volatile int *run_flag;\n    // Pointer to the exit_flag shared in the test group\n    volatile int *exit_flag;\n    // Pointer to the pthread mutex shared in the test group\n    pthread_mutex_t *test_mutex;\n    // Pointer to the pthread condition shared in the test group\n    pthread_cond_t *test_cond;\n    // Pointer to the number of running tests\n    volatile unsigned int *num_running_t;\n};\n\n/**\n * @struct test_group\n * @brief This structure holds data for a test group\n */\nstruct test_group {\n    // test group size, i.e., size of test_list array\n    size_t group_size;\n    // number of test\n    int num_test;\n    // number of threads - since one test per thread, equal to num_test\n    int n_threads;\n    // a flag for telling all threads to run - 0: stop, 1: run\n    volatile int run_flag;\n    // a flag for telling all threads to finish - 1: exit\n    volatile int exit_flag;\n    // pthread tid\n    pthread_t *tid;\n    // pthread attr\n    pthread_attr_t attr;\n    // pthread mutex shared in a group\n    pthread_mutex_t test_mutex;\n    // pthread condition signal shared in a group\n    pthread_cond_t test_cond;\n    // the list of test info\n    test_aux *test_list;\n    // the list of thread info\n    thread_aux *thread_list;\n    // number of running tests\n    volatile unsigned int num_running_t;\n};\n\n/**\n * @brief create a test group, and preallocate\n * test_list array with group_size\n * @return initialized struct test_group\n */\ntest_group* TestGroupCreate(size_t group_size);\n\n/**\n * @brief resize the array of test_list\n * @return\n */\nvoid TestGroupResize(test_group *t_group, size_t new_group_size);\n\n/**\n * @brief add a new test into the specific test group\n * @param t_group Pointer to a test group\n * @param fun Pointer to the test function\n * @param data Pointer to data for the test function\n * @param num_copy Number of copies of the test\n */\nvoid TestGroupAdd(test_group *t_group, func_ptr fun,\n                    void *data, size_t num_copy);\n\n/**\n * @brief create threads for tests in a test group\n * @param t_group Pointer to a test group\n */\nvoid TestGroupThreadCreate(test_group *t_group);\n\n/**\n * @brief return the number of tests in a test group\n * @param t_group Pointer to a test group\n */\nint TestGroupNumTests(test_group *t_group);\n\n/**\n * @brief run all threads/tests in a test group\n * @param t_group Pointer to a test group\n */\nvoid TestGroupStart(test_group *t_group);\n\n/**\n * @brief wait all threads/tests in a test group finish\n * The function is blocked until all threads are finished\n * @param t_group Pointer to a test group\n */\nvoid TestGroupWait(test_group *t_group);\n\n/**\n * @brief terminate all threads/tests in a test group by sending a signal\n * set exit_flag to 1, wait until all threads are finished\n * @param t_group Pointer to a test group\n */\nvoid TestGroupExit(test_group *t_group);\n\n/**\n * @brief destroy a test group, release all resources\n * @param t_group Pointer to a test group\n */\nvoid TestGroupDestroy(test_group *t_group);\n\n/**\n * @brief check the status of specific test in a test group\n * @param t_group Pointer to a test group\n * @param test_id Test No.\n * @return the status of the test listed in enum TEST_STATUS\n */\nint TestGroupTestStatus(test_group *t_group, int test_id);\n\n/**\n * @brief set affinity of the specific test\n * @param t_group Pointer to a test group\n * @param test_id Test No.\n * @param cpu_id CPU No. that the test is binded to\n */\nvoid TestGroupThreadAffinity(test_group *t_group,\n                                int test_id, int cpu_id);\n\n/**\n * @brief force kill a test group\n * @param t_group Pointer to a test group\n */\nvoid TestGroupKill(test_group *t_group);\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_CONCURRENT_UTILS_H_\n"
  },
  {
    "path": "rocrtst/common/helper_funcs.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include \"common/helper_funcs.h\"\n#ifndef _WIN32\n#include <unistd.h>\n#endif\n#include <assert.h>\n#include <cmath>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <numeric>\n\nnamespace rocrtst {\n\ntemplate<typename T>\nvoid PrintArray(const std::string header, const T* data, const int width,\n                const int height) {\n  std::cout << std::endl << header << std::endl;\n\n  for (int i = 0; i < height; i++) {\n    for (int j = 0; j < width; j++) {\n      std::cout << data[i * width + j] << \" \";\n    }\n\n    std::cout << std::endl;\n  }\n\n  std::cout << std::endl;\n}\n\ntemplate<typename T>\nint FillRandom(T* arrayPtr,\n               const int width,\n               const int height,\n               const T rangeMin,\n               const T rangeMax,\n               unsigned int seed) {\n  if (!arrayPtr) {\n    return 1;\n  }\n\n  if (!seed) {\n    seed = (unsigned int)time(NULL);\n  }\n\n  srand(seed);\n  double range = static_cast<double>(rangeMax - rangeMin) + 1.0;\n\n  /* random initialisation of input */\n  for (int i = 0; i < height; i++) {\n    for (int j = 0; j < width; j++) {\n      int index = i * width + j;\n      arrayPtr[index] = rangeMin + T(range * rand_r(&seed) / (RAND_MAX + 1.0));\n    }\n  }\n\n  return 0;\n}\n\nuint64_t RoundToPowerOf2(uint64_t val) {\n  val--;\n  /*\n   * Shift with amount larger than the bit width can result in\n   * undefined behavior by compiler for release builds.\n   * Shift till 32 bit only which is less than bit width of val.\n   */\n  for (int i = 1; i <= 32; i *= 2) val |= val >> i;\n\n  val++;\n  return val;\n}\n\nbool IsPowerOf2(uint64_t val) {\n  uint64_t tmp = val;\n\n  if ((tmp & (-tmp)) - tmp == 0 && tmp != 0) {\n    return true;\n  } else {\n    return false;\n  }\n}\n\nbool\nCompare(const float* refData, const float* data,\n        const int length, const float epsilon) {\n  float error = 0.0f;\n  float ref = 0.0f;\n\n  for (int i = 1; i < length; ++i) {\n    float diff = refData[i] - data[i];\n    error += diff * diff;\n    ref += refData[i] * refData[i];\n  }\n\n  float normRef =::sqrtf(static_cast<float>(ref));\n\n  if (::fabs(static_cast<float>(ref)) < 1e-7f) {\n    return false;\n  }\n\n  float normError = ::sqrtf(static_cast<float>(error));\n  error = normError / normRef;\n\n  return error < epsilon;\n}\n\nbool\nCompare(const double* refData, const double* data,\n        const int length, const double epsilon) {\n  double error = 0.0;\n  double ref = 0.0;\n\n  for (int i = 1; i < length; ++i) {\n    double diff = refData[i] - data[i];\n    error += diff * diff;\n    ref += refData[i] * refData[i];\n  }\n\n  double normRef =::sqrt(static_cast<double>(ref));\n\n  if (::fabs(static_cast<double>(ref)) < 1e-7) {\n    return false;\n  }\n\n  double normError = ::sqrt(static_cast<double>(error));\n  error = normError / normRef;\n\n  return error < epsilon;\n}\n\nintptr_t\nAlignDown(intptr_t value, size_t alignment) {\n    assert(alignment != 0 && \"Zero alignment\");\n    return (intptr_t) (value & ~(alignment - 1));\n}\n\nvoid *\nAlignDown(void* value, size_t alignment) {\n    return reinterpret_cast<void*>(AlignDown(\n                              reinterpret_cast<uintptr_t>(value), alignment));\n}\n\nvoid *\nAlignUp(void* value, size_t alignment) {\n    return reinterpret_cast<void*>(\n     AlignDown((uintptr_t)(reinterpret_cast<uintptr_t>(value) + alignment - 1),\n                                                                   alignment));\n}\n\ndouble CalcMedian(const std::vector<double> &scores) {\n  double median;\n  size_t size = scores.size();\n\n  if (size % 2 == 0) {\n    median = (scores[size / 2 - 1] + scores[size / 2]) / 2;\n  } else {\n    median = scores[size / 2];\n  }\n\n  return median;\n}\n\ndouble CalcMean(const std::vector<double> &scores) {\n  double mean;\n\n  mean = std::accumulate(scores.begin(), scores.end(), 0.0);\n  return mean/scores.size();\n}\n\ndouble CalcMean(const std::vector<double>& v1, const std::vector<double>& v2) {\n  double mean = 0;\n  size_t size = v1.size();\n\n  for (size_t i = 0; i < size; i++) {\n    mean += v2[i] - v1[i];\n  }\n\n  return mean / size;\n}\n\ndouble CalcStdDeviation(std::vector<double> scores, int score_mean) {\n  double ret = 0.0;\n\n  for (size_t i = 0; i < scores.size(); ++i) {\n    ret += (scores[i] - score_mean) * (scores[i] - score_mean);\n  }\n\n  ret /= scores.size();\n\n  return sqrt(ret);\n}\n\n/////////////////////////////////////////////////////////////////\n// Template Instantiations\n/////////////////////////////////////////////////////////////////\n\ntemplate\nvoid PrintArray<uint32_t>(const std::string, const unsigned int*, int, int);\n\ntemplate\nvoid PrintArray<float>(const std::string, const float*, int, int);\n\ntemplate\nint FillRandom<uint32_t>(uint32_t* arrayPtr,\n                         const int width, const int height,\n                         uint32_t rangeMin, uint32_t rangeMax,\n                                                           unsigned int seed);\n\ntemplate\nint FillRandom<float>(float* arrayPtr,\n                      const int width, const int height,\n                      float rangeMin, float rangeMax, unsigned int seed);\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/helper_funcs.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_COMMON_HELPER_FUNCS_H_\n#define ROCRTST_COMMON_HELPER_FUNCS_H_\n\n/// \\file\n/// General-purpose helper functions\n\n#include <string>\n#include <vector>\n#include <stdint.h>\n\n#if defined(__GNUC__)\n#define __forceinline __inline__ __attribute__((always_inline))\n#endif\n\n#define STRING2(x) #x\n#define STRING(x) STRING2(x)\n\n#define PASTE2(x, y) x##y\n#define PASTE(x, y) PASTE2(x, y)\n\nnamespace rocrtst {\n\nbool Compare(const float* refData, const float* data,\n             const int length, const float epsilon = 1e-6f);\nbool Compare(const double* refData, const double* data,\n             const int length, const double epsilon = 1e-6);\n\n/// Calculate the mean number of the vector\ndouble CalcMean(const std::vector<double> &scores);\n\n/// Calculate the mean time of difference of the two vectors\ndouble CalcMean(const std::vector<double>& v1, const std::vector<double>& v2);\n\n/// Return the median value of a vector of doubles\n/// \\param[in] scores Vector of doubles\n/// \\returns double Median value of provided vector\ndouble CalcMedian(const std::vector<double> &scores);\n\n/// Calculate the standard deviation of the vector\ndouble CalcStdDeviation(std::vector<double> scores, int score_mean);\n\n/// Display an array to std::out\ntemplate<typename T>\nvoid PrintArray(\n  const std::string header,\n  const T* data,\n  const int width,\n  const int height);\n\n/// Fill an array with random values\ntemplate<typename T>\nint FillRandom(\n  T* arrayPtr,\n  const int width,\n  const int height,\n  const T rangeMin,\n  const T rangeMax,\n  unsigned int seed = 123);\n\nintptr_t AlignDown(intptr_t value, size_t alignment);\nvoid* AlignDown(void* value, size_t alignment);\nvoid* AlignUp(void* value, size_t alignment);\n\n/// Rounds to a power of 2\nuint64_t RoundToPowerOf2(uint64_t val);\n\n///  Checks if a value is a power of 2\nbool IsPowerOf2(uint64_t val);\n\n// Count set bits.\nstatic __forceinline uint32_t popcount(uint32_t value) {\n  return __builtin_popcount(value);\n}\n\ntemplate <typename lambda>\nclass ScopeGuard {\n public:\n  explicit __forceinline ScopeGuard(const lambda& release)\n      : release_(release), dismiss_(false) {}\n\n  ScopeGuard(const ScopeGuard& rhs) {*this = rhs; }\n\n  __forceinline ~ScopeGuard() {\n    if (!dismiss_) release_();\n  }\n  __forceinline ScopeGuard& operator=(ScopeGuard& rhs) {\n    dismiss_ = rhs.dismiss_;\n    release_ = rhs.release_;\n    rhs.dismiss_ = true;\n  }\n  __forceinline void Dismiss() { dismiss_ = true; }\n\n private:\n  lambda release_;\n  bool dismiss_;\n};\n\ntemplate <typename lambda>\nstatic __forceinline ScopeGuard<lambda> MakeScopeGuard(lambda rel) {\n  return ScopeGuard<lambda>(rel);\n}\n\n#define MAKE_SCOPE_GUARD_HELPER(lname, sname, ...) \\\n  auto lname = __VA_ARGS__;                        \\\n  rocrtst::ScopeGuard<decltype(lname)> sname(lname);\n#define MAKE_SCOPE_GUARD(...)                                   \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), \\\n                          PASTE(scopeGuard, __COUNTER__), __VA_ARGS__)\n#define MAKE_NAMED_SCOPE_GUARD(name, ...)                             \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), name, \\\n                          __VA_ARGS__)\n\n#define ASSERT_SUCCESS(_val) ASSERT_EQ(HSA_STATUS_SUCCESS, (_val))\n\n#define ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))\n\n}  // namespace rocrtst\n#endif  //  ROCRTST_COMMON_HELPER_FUNCS_H_\n"
  },
  {
    "path": "rocrtst/common/hsatimer.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include \"common/hsatimer.h\"\n#include <x86intrin.h>\n\nnamespace rocrtst {\n\nstatic const uint64_t kNanosecondsPerSecond = 1000000000;\n\nPerfTimer::PerfTimer(void) {\n  freq_in_100mhz = MeasureTSCFreqHz();\n}\n\nPerfTimer::~PerfTimer() {\n  while (!_timers.empty()) {\n    Timer* temp = _timers.back();\n    _timers.pop_back();\n    delete temp;\n  }\n}\n\nint PerfTimer::CreateTimer(void) {\n  Timer* newTimer = new Timer;\n  newTimer->_start = 0;\n  newTimer->_clocks = 0;\n\n  newTimer->_freq = kNanosecondsPerSecond;\n\n  /* Push back the address of new Timer instance created */\n  _timers.push_back(newTimer);\n  return static_cast<int>(_timers.size() - 1);\n}\n\nint PerfTimer::StartTimer(int index) {\n  if (index >= static_cast<int>(_timers.size())) {\n    Error(\"Cannot reset timer. Invalid handle.\");\n    return 1;\n  }\n\n// General Linux timing method\n#ifndef _AMD\n  struct timespec s;\n  clock_gettime(CLOCK_MONOTONIC, &s);\n  _timers[index]->_start = (uint64_t) s.tv_sec * kNanosecondsPerSecond\n                           + (uint64_t) s.tv_nsec;\n#else\n\n  // AMD timing method\n\n  unsigned int unused;\n  _timers[index]->_start = __rdtscp(&unused);\n\n#endif\n\n  return 0;\n}\n\nint PerfTimer::StopTimer(int index) {\n  uint64_t n = 0;\n\n  if (index >= static_cast<int>(_timers.size())) {\n    Error(\"Cannot reset timer. Invalid handle.\");\n    return 1;\n  }\n\n  // General Linux timing method\n#ifndef _AMD\n  struct timespec s;\n  clock_gettime(CLOCK_MONOTONIC, &s);\n  n = (uint64_t) s.tv_sec * kNanosecondsPerSecond + (uint64_t) s.tv_nsec;\n#else\n  // AMD Linux timing\n\n  unsigned int unused;\n  n = __rdtscp(&unused);\n#endif\n\n  n -= _timers[index]->_start;\n  _timers[index]->_start = 0;\n\n#ifndef _AMD\n  _timers[index]->_clocks += n;\n#else\n  // convert to ms\n  _timers[index]->_clocks += 1.0E-6 * 10 * n / freq_in_100mhz;\n  cout << \"_AMD is enabled!!!\" << endl;\n#endif\n\n  return 0;\n}\n\nvoid PerfTimer::Error(std::string str) {\n  std::cout << str << std::endl;\n}\n\ndouble PerfTimer::ReadTimer(int index) {\n  if (index >= static_cast<int>(_timers.size())) {\n    Error(\"Cannot read timer. Invalid handle.\");\n    return 1;\n  }\n\n  double reading = static_cast<double>(_timers[index]->_clocks);\n\n  reading = static_cast<double>(reading / _timers[index]->_freq);\n\n  return reading;\n}\n\nvoid PerfTimer::ResetTimer(int index) {\n  // Check if index value is over the timer's size\n  if (index >= static_cast<int>(_timers.size())) {\n    Error(\"Invalid index value\\n\");\n    exit(1);\n  }\n\n  _timers[index]->_clocks = 0.0;\n  _timers[index]->_start = 0.0;\n}\n\nuint64_t PerfTimer::CoarseTimestampUs() {\n  struct timespec ts;\n  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);\n  return uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;\n}\n\nuint64_t PerfTimer::MeasureTSCFreqHz() {\n  // Make a coarse interval measurement of TSC ticks for 1 gigacycles.\n  unsigned int unused;\n  uint64_t tscTicksEnd;\n\n  uint64_t coarseBeginUs = CoarseTimestampUs();\n  uint64_t tscTicksBegin = __rdtscp(&unused);\n\n  do {\n    tscTicksEnd = __rdtscp(&unused);\n  } while (tscTicksEnd - tscTicksBegin < 1000000000);\n\n  uint64_t coarseEndUs = CoarseTimestampUs();\n\n  // Compute the TSC frequency and round to nearest 100MHz.\n  uint64_t coarseIntervalNs = (coarseEndUs - coarseBeginUs) * 1000;\n  uint64_t tscIntervalTicks = tscTicksEnd - tscTicksBegin;\n  return (tscIntervalTicks * 10 + (coarseIntervalNs / 2)) / coarseIntervalNs;\n}\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/hsatimer.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_COMMON_HSATIMER_H_\n#define ROCRTST_COMMON_HSATIMER_H_\n\n#include <stdint.h>\n#include <iostream>\n#include <vector>\n#include <string>\n/// \\file\n/// Timer related class.\n\nnamespace rocrtst {\n\nclass PerfTimer {\n private:\n  struct Timer {\n    std::string name; /* < name name of time object*/\n    uint64_t _freq; /* < _freq frequency*/\n    uint64_t _clocks; /* < _clocks number of ticks at end*/\n    uint64_t _start; /* < _start start point ticks*/\n  };\n\n  std::vector<Timer*> _timers; /*< _timers vector to Timer objects */\n  double freq_in_100mhz;\n\n public:\n  PerfTimer(void);\n  ~PerfTimer(void);\n\n  /// Create a new timer.\n  /// \\returns A new timer instantance index\n  int CreateTimer(void);\n\n  /// Start the timer associated with the given index\n  /// \\param[in] index Index of the timer to start\n  /// \\returns int 0 for success, non-zero otherwise\n  int StartTimer(int index);\n\n  /// Stop the timer associated with the given index\n  /// \\param[in] Index Index of the timer to stop\n  /// \\returns int 0 for success, non-zero otherwise\n  int StopTimer(int index);\n\n  /// Reset the timer to 0\n  /// param[in] Index of the timer to reset\n  /// \\returns void\n  void ResetTimer(int index);\n\n  /// Read the time value of the timer associated with the provided index.\n  /// Units are seconds\n  /// \\param[in] index Index of the timer to read\n  /// \\returns double Value of the timer\n  double ReadTimer(int index);\n\n private:\n  void Error(std::string str);\n  uint64_t CoarseTimestampUs();\n  uint64_t MeasureTSCFreqHz();\n};\n\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_HSATIMER_H_\n\n"
  },
  {
    "path": "rocrtst/common/os.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include \"common/os.h\"\n#include <stdlib.h>\n\nnamespace rocrtst {\n\nvoid SetEnv(const char* env_var_name, const char* env_var_value) {\n  int err = setenv(env_var_name, env_var_value, 1);\n\n  if (0 != err) {\n    printf(\"Set environment variable failed!\\n\");\n    exit(1);\n  }\n\n  return;\n}\n\nchar* GetEnv(const char* env_var_name) {\n  return getenv(env_var_name);\n}\n\n}  // namespace rocrtst\n"
  },
  {
    "path": "rocrtst/common/os.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/// \\file OS specific functionality\n\n#ifndef ROCRTST_COMMON_OS_H_\n#define ROCRTST_COMMON_OS_H_\n\n#include <stdio.h>\nnamespace rocrtst {\n\n/// Set envriroment variable.\n/// \\param[in] env_var_name Environment variable to set.\n/// \\param[in] env_var_value Value to set environment variable to.\n/// \\returns void\nvoid SetEnv(const char* env_var_name, const char* env_var_value);\n\n/// Get envriroment variable.\n/// \\param[in] env_var_name Environment variable to get.\n/// \\returns Pointer to string of characters that is the value of the\n///  environment variable.\nchar* GetEnv(const char* env_var_name);\n\n}  // namespace rocrtst\n#endif  // ROCRTST_COMMON_OS_H_\n"
  },
  {
    "path": "rocrtst/common/rocr.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2021-2021, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\r\n#include \"common/rocr.h\"\r\nSystem System::sys;\r\n\r\nbool DeviceDiscovery(System& devices) {\n  hsa_status_t err;\n\n  err = hsa_iterate_agents([](hsa_agent_t agent, void* data) {\n    hsa_status_t err;\n\n    System* devices = (System*)data;\n\n    Device dev;\n    dev.agent = agent;\n\n    dev.fine = -1u;\n    dev.coarse = -1u;\n\n    hsa_device_type_t type;\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type);\n    CHECK(err);\n\n    err = hsa_amd_agent_iterate_memory_pools(agent, [](hsa_amd_memory_pool_t pool, void* data) {\n      std::vector<Device::Memory>& pools = *reinterpret_cast<std::vector<Device::Memory>*>(data);\n      hsa_status_t err;\n\n      hsa_amd_segment_t segment;\n      err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n      CHECK(err);\n\n      if(segment != HSA_AMD_SEGMENT_GLOBAL)\n        return HSA_STATUS_SUCCESS;\n\n      uint32_t flags;\n      err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flags);\n      CHECK(err);\n\n      Device::Memory mem;\n      mem.pool=pool;\n      mem.fine = (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED);\n      mem.kernarg = (flags & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT);\n\n      err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE, &mem.size);\n      CHECK(err);\n\n      err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE, &mem.granule);\n      CHECK(err);\n\n      pools.push_back(mem);\n      return HSA_STATUS_SUCCESS;\n    }, (void*)&dev.pools);\n\n    if(!dev.pools.empty()) {\n      for(size_t i=0; i<dev.pools.size(); i++) {\n        if(dev.pools[i].fine && dev.pools[i].kernarg && dev.fine==-1u)\n          dev.fine = i;\n        if(dev.pools[i].fine && !dev.pools[i].kernarg)\n          dev.fine = i;\n        if(!dev.pools[i].fine)\n          dev.coarse = i;\n      }\n\n      if(type == HSA_DEVICE_TYPE_CPU)\n        devices->cpu_.push_back(dev);\n      else\n        devices->gpu_.push_back(dev);\n\n      devices->all_devices_.push_back(dev.agent);\n    }\n\n    return HSA_STATUS_SUCCESS;\n  }, &devices);\n\n  [&]() {\n    for(auto& dev : devices.cpu_) {\n      for(auto& mem : dev.pools) {\n        if(mem.fine && mem.kernarg) {\n          devices.kernarg_ = mem;\n          return;\n        }\n      }\n    }\n  }();\n\n  if(devices.cpu_.empty() || devices.gpu_.empty() || devices.kernarg_.pool.handle == 0)\n    return false;\n  return true;\n}\n\nvoid System::Init() {\n  hsa_status_t err = hsa_init();\n  CHECK(err);\n\n  DeviceDiscovery(sys);\n}\n\nvoid System::Shutdown() {\n  sys.~System();\n  new (&sys) System();\n  hsa_status_t err = hsa_shut_down();\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  err = hsa_shut_down();\n  EXPECT_EQ(HSA_STATUS_ERROR_NOT_INITIALIZED, err);\n}\n\nCodeObject::CodeObject(std::string filename, Device& agent) : agent(agent.agent) {\n  hsa_status_t err;\n\n  file = open(filename.c_str(), O_RDONLY);\n  if(file == -1) {\n    throw std::runtime_error(\"Could not open file.\\n\");\n  }\n  MAKE_NAMED_SCOPE_GUARD(fileGuard, [&](){ close(file); });\n\n  err = hsa_code_object_reader_create_from_file(file, &code_obj_rdr);\n  CHECK(err);\n  MAKE_NAMED_SCOPE_GUARD(readerGuard, [&](){ hsa_code_object_reader_destroy(code_obj_rdr); });\n  \n  err = hsa_executable_create_alt(HSA_PROFILE_FULL, HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT, nullptr, &executable);\n  CHECK(err);\n  MAKE_NAMED_SCOPE_GUARD(exeGuard, [&](){ hsa_executable_destroy(executable); });\n\n  err = hsa_executable_load_agent_code_object(executable, agent.agent, code_obj_rdr, nullptr, nullptr);\n  CHECK(err);\n\n  err = hsa_executable_freeze(executable, nullptr);\n  CHECK(err);\n\n  exeGuard.Dismiss();\n  readerGuard.Dismiss();\n  fileGuard.Dismiss();\n}\n\nCodeObject::~CodeObject() {\n  hsa_executable_destroy(executable);\n  hsa_code_object_reader_destroy(code_obj_rdr);\n  close(file);\n}\n\nbool CodeObject::GetKernel(std::string name, Kernel& kern) {\n  hsa_executable_symbol_t symbol;\n  hsa_status_t err = hsa_executable_get_symbol_by_name(executable, name.c_str(), &agent, &symbol);\n  if(err != HSA_STATUS_SUCCESS) {\n    err = hsa_executable_get_symbol_by_name(executable, (name+\".kd\").c_str(), &agent, &symbol);\n    if(err != HSA_STATUS_SUCCESS) {\n      return false;\n    }\n  }\n\n  err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &kern.handle);\n  CHECK(err);\n\n  err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE, &kern.scratch);\n  CHECK(err);\n  //printf(\"Scratch: %d\\n\", kern.scratch);\n\n  err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE, &kern.group);\n  CHECK(err);\n  //printf(\"LDS: %d\\n\", kern.group);\n  \n  // Remaining needs code object v2 or comgr.\n  err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE, &kern.kernarg_size);\n  CHECK(err);\n  //printf(\"Kernarg Size: %d\\n\", kern.kernarg_size);\n\n  err = hsa_executable_symbol_get_info(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT, &kern.kernarg_align);\n  CHECK(err);\n  //printf(\"Kernarg Align: %d\\n\", kern.kernarg_align);\n\n  return true;\n}\n\n// Not for parallel insertion.\nbool SubmitPacket(hsa_queue_t* queue, Aql& pkt) {\n  size_t mask = queue->size - 1;\n  Aql* ring = (Aql*)queue->base_address;\n\n  uint64_t write = hsa_queue_load_write_index_relaxed(queue);\n  uint64_t read = hsa_queue_load_read_index_relaxed(queue);\n  //if(write - read + 1 > queue->size)\n  //  return false;\n  \n  Aql& dst = ring[write & mask];\n\n  uint16_t header = pkt.header.raw;\n  pkt.header.raw = dst.header.raw;\n  dst = pkt;\n  __atomic_store_n(&dst.header.raw, header, __ATOMIC_RELEASE);\n  pkt.header.raw = header;\n\n  hsa_queue_store_write_index_release(queue, write+1);\n  hsa_signal_store_screlease(queue->doorbell_signal, write);\n\n  return true;\n}\n\nvoid* hsaMalloc(size_t size, const Device::Memory& mem) {\n  void* ret;\n  hsa_status_t err = hsa_amd_memory_pool_allocate(mem.pool, size, 0, &ret);\n  CHECK(err);\n  err = hsa_amd_agents_allow_access(System::all_devices().size(), &System::all_devices()[0], nullptr, ret);\n  CHECK(err);\n  return ret;\n}\n\nvoid* hsaMalloc(size_t size, const Device& dev, bool fine) {\n  uint32_t index = fine ? dev.fine : dev.coarse;\n  assert(index != -1u && \"Memory type unavailable.\");\n  return hsaMalloc(size, dev.pools[index]);\n}\n"
  },
  {
    "path": "rocrtst/common/rocr.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2021-2021, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"hsa/hsa_ext_image.h\"\n\n#include \"common/helper_funcs.h\"\n\n#include \"gtest/gtest.h\"\n\n#include <fcntl.h>\n#include <assert.h>\n#include \"string.h\"\n\n#include <vector>\n\n#define CHECK(err) [&](){                         \\\n    if(err != HSA_STATUS_SUCCESS) {               \\\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err);         \\\n      throw std::runtime_error(\"CHECK failure.\"); \\\n    }                                             \\\n  }();\n\nstruct Device {\n  struct Memory {\n    hsa_amd_memory_pool_t pool;\n    bool fine;\n    bool kernarg;\n    size_t size;\n    size_t granule;\n  };\n\n  hsa_agent_t agent;\n  std::vector<Memory> pools;\n  uint32_t fine;\n  uint32_t coarse;\n};\n\nstruct Kernel {\n  uint64_t handle;\n  uint32_t scratch;\n  uint32_t group;\n  uint32_t kernarg_size;\n  uint32_t kernarg_align;\n};\n\n// Assumes bitfield layout is little endian.\n// Assumes std::atomic<uint16_t> is binary compatible with uint16_t and uses HW atomics.\nunion AqlHeader {\n  struct {\n    uint16_t type     : 8;\n    uint16_t barrier  : 1;\n    uint16_t acquire  : 2;\n    uint16_t release  : 2;\n    uint16_t reserved : 3;\n  };\n  uint16_t raw;\n};\n\nstruct BarrierValue {\n  AqlHeader header;\n  uint8_t AmdFormat;\n  uint8_t reserved;\n  uint32_t reserved1;\n  hsa_signal_t signal;\n  hsa_signal_value_t value;\n  hsa_signal_value_t mask;\n  uint32_t cond;\n  uint32_t reserved2;\n  uint64_t reserved3;\n  uint64_t reserved4;\n  hsa_signal_t completion_signal;\n};\n\nunion Aql {\n  AqlHeader header;\n  hsa_kernel_dispatch_packet_t dispatch;\n  hsa_barrier_and_packet_t barrier_and;\n  hsa_barrier_or_packet_t barrier_or;\n  BarrierValue barrier_value;\n};\n\nstruct OCLHiddenArgs {\n  uint64_t offset_x;\n  uint64_t offset_y;\n  uint64_t offset_z;\n  void* printf_buffer;\n  void* enqueue;\n  void* enqueue2;\n  void* multi_grid;\n};\n\nstruct hip_hiddens {\n  uint64_t offset_x;\n  uint64_t offset_y;\n  uint64_t offset_z;\n  uint64_t _;\n  uint64_t _2;\n  uint64_t _3;\n  uint64_t multi_grid_sync;\n};\n\nclass System {\npublic:\n  std::vector<Device> cpu_, gpu_;\n  std::vector<hsa_agent_t> all_devices_;\n  Device::Memory kernarg_;\n\n  static void Init();\n  static void Shutdown();\n  static std::vector<Device>& cpu() { return sys.cpu_; }\n  static std::vector<Device>& gpu() { return sys.gpu_; }\n  static std::vector<hsa_agent_t>& all_devices() { return sys.all_devices_; }\n  static Device::Memory& kernarg() { return sys.kernarg_; }\n  static System sys;\n};\n\nclass CodeObject {\npublic:\n  CodeObject(std::string filename, Device& agent);\n  ~CodeObject();\n  bool GetKernel(std::string name, Kernel& kernel);\nprivate:\n  hsa_file_t file;\n  hsa_code_object_reader_t code_obj_rdr;\n  hsa_executable_t executable;\n  hsa_agent_t agent;\n};\n\n// Not for parallel insertion.\nbool SubmitPacket(hsa_queue_t* queue, Aql& pkt);\n\nvoid* hsaMalloc(size_t size, const Device::Memory& mem);\nvoid* hsaMalloc(size_t size, const Device& dev, bool fine);\n"
  },
  {
    "path": "rocrtst/common/utils_test/CMakeLists.txt",
    "content": "#\r\n# Source files for Tests verifying rocrtst Utils library\r\n#\r\nset (rocrtstUtilsTestSrcs utils_timer_gtest.cpp)\r\nset (rocrtstUtilsTestSrcs ${rocrtstUtilsTestSrcs} utils_timer_test.cpp)\r\nset (rocrtstUtilsTestSrcs ${rocrtstUtilsTestSrcs} utils_cpp11_gtest.cpp)\r\n\r\n#\r\n# Header files include path(s).\r\n#\r\ninclude_directories(${CMAKE_CURRENT_SOURCE_DIR})\r\ninclude_directories(${PROJECT_SOURCE_DIR}/utils)\r\ninclude_directories(${PROJECT_SOURCE_DIR}/gtest/include)\r\n\r\n#\r\n# Build rule to build an executable object\r\n#\r\nadd_executable(${ROCRTST_UTIL_TEST_NAME} ${rocrtstUtilsTestSrcs})\r\n\r\n#\r\n# Link unresolved symbols of rocrtst Utils Test executable\r\n#\r\ntarget_link_libraries(${ROCRTST_UTIL_TEST_NAME} ${ROCRTST_LIBS} elf c stdc++ dl pthread rt)\r\n\r\n#\r\n# Install build artifacts into one common location\r\n#\r\nINSTALL(TARGETS ${ROCRTST_UTIL_TEST_NAME}\r\n        ARCHIVE DESTINATION ${PROJECT_BINARY_DIR}/lib\r\n        LIBRARY DESTINATION ${PROJECT_BINARY_DIR}/lib\r\n        RUNTIME DESTINATION ${PROJECT_BINARY_DIR}/bin)\r\n"
  },
  {
    "path": "rocrtst/common/utils_test/utils_cpp11_gtest.cpp",
    "content": "#include<iostream>\r\n#include<thread>\r\n#include\"gtest/gtest.h\"\r\n\r\nusing std::cout;\r\nusing std::endl;\r\n\r\n// @Brief: this function is defined to be executed for thread #1\r\nstatic void ThreadEntry1() {\r\n  cout << \"The first thread is launched!\" << endl;\r\n  return;\r\n}\r\n// @Brief: this function is defined to be executed for thread #2\r\nstatic void ThreadEntry2() {\r\n  cout << \"The second thread is launched!\" << endl;\r\n  return;\r\n}\r\n\r\n// @Brief: google test case added for basic C++11 thread feature.\r\n// Here, in main function, it will create two threas objects, then,\r\n// check if each thread are joinable, if so, main thread wait until\r\n// the spawned threads finish.\r\nTEST(rocrtstCpp11Feature, BasicThread) {\r\n  // Define two threads object;\r\n  std::thread thread1;\r\n  std::thread thread2;\r\n\r\n  // At this point, it should be non-joinable\r\n  ASSERT_EQ(false, thread1.joinable());\r\n  ASSERT_EQ(false, thread2.joinable());\r\n\r\n  // Assign execution codes to threads;\r\n  thread1 = std::thread(ThreadEntry1);\r\n  thread2 = std::thread(ThreadEntry2);\r\n\r\n  // Now, the two threads should be joinable\r\n  ASSERT_EQ(true, thread1.joinable());\r\n  ASSERT_EQ(true, thread2.joinable());\r\n\r\n  // Join the two threads until they finish\r\n  thread1.join();\r\n  thread2.join();\r\n\r\n  // When execution flow reaches here, it succeed.\r\n  cout << \"Done!\" << endl;\r\n}\r\n"
  },
  {
    "path": "rocrtst/common/utils_test/utils_timer_gtest.cpp",
    "content": "\r\n\r\n#include <iostream>\r\n\r\n#include \"gtest/gtest.h\"\r\n\r\n#include \"utils_timer_test.hpp\"\r\n\r\nusing namespace std;\r\n\r\nclass rocrtstUtilsTimerGtest : public ::testing::Test {\r\n\r\n protected:\r\n\r\n  // No argument constructor called from Google Test Framework\r\n  rocrtstUtilsTimerGtest() { };\r\n\r\n};\r\n\r\nTEST_F(rocrtstUtilsTimerGtest, TestingTimer101) {\r\n\r\n  // Create a Hsa Perf Utils Timer Test object.\r\n  // The test will iterate 108 times with sleep\r\n  // time of 3 milliseconds per iteration\r\n  rocrtstUtilsTimerTest* timer = new rocrtstUtilsTimerTest(108, 3);\r\n\r\n  // Let the timer object collect data\r\n  timer->run();\r\n\r\n  // Print the statistics of timer object\r\n  timer->print();\r\n}\r\n"
  },
  {
    "path": "rocrtst/common/utils_test/utils_timer_test.cpp",
    "content": "\r\n#include <iostream>\r\n#include \"hsatimer.h\"\r\n#include <unistd.h>\r\n#include \"utils_timer_test.hpp\"\r\n\r\nusing namespace std;\r\n\r\n\r\n\r\n// Destructor method of test driver\r\nrocrtstUtilsTimerTest::~rocrtstUtilsTimerTest() { }\r\n\r\n// Constructor method of test driver\r\n//\r\n// @brief loopCnt number of times to call sleep Api\r\n//\r\n// @brief sleepTimer time to sleep in milliseconds\r\nrocrtstUtilsTimerTest::rocrtstUtilsTimerTest(uint32_t loopCnt, uint32_t sleepTime) :\r\n  loopCnt_(loopCnt), sleepTime_(sleepTime), total_time_(0) { }\r\n\r\n// Execute user defined number of sleep calls and collect the\r\n// total time taken by such calls\r\nvoid rocrtstUtilsTimerTest::run() {\r\n\r\n  double time;\r\n  PerfTimer timer;\r\n  uint32_t index = timer.CreateTimer();\r\n\r\n  for (uint32_t idx; idx < loopCnt_; idx++) {\r\n\r\n    timer.StartTimer(index);\r\n    usleep(sleepTime_);\r\n    timer.StopTimer(index);\r\n    time = timer.ReadTimer(index);\r\n    total_time_ += time;\r\n  }\r\n}\r\n\r\n// Print time reported by Hsa Perf Utils Timer service\r\nvoid rocrtstUtilsTimerTest::print() {\r\n\r\n  std::cout << \"Time taken by \" << loopCnt_;\r\n  std::cout << \" iterations of sleep is: \" << total_time_ << std::endl;\r\n}\r\n"
  },
  {
    "path": "rocrtst/common/utils_test/utils_timer_test.hpp",
    "content": "#ifndef ROCRTST_UTILS_TIMER_TEST_H_\r\n#define ROCRTST_UTILS_TIMER_TEST_H_\r\n\r\n// Encapsulates Api's to access Timer service of rocrtst Utils library\r\nclass rocrtstUtilsTimerTest {\r\n\r\n public:\r\n\r\n  // Destructor method of test driver\r\n  ~rocrtstUtilsTimerTest();\r\n\r\n  // Constructor method of test driver\r\n  //\r\n  // @brief loopCnt number of times to call sleep Api\r\n  //\r\n  // @brief sleepTimer time to sleep in milliseconds\r\n  rocrtstUtilsTimerTest(uint32_t loopCnt, uint32_t sleepTime);\r\n\r\n  // Execute user defined number of sleep calls and collect the\r\n  // total time taken by such calls\r\n  void run();\r\n\r\n  // Print time reported by rocrtst Utils Timer service\r\n  void print();\r\n\r\n private:\r\n\r\n  // Number of times to invoke sleep Api\r\n  uint32_t loopCnt_;\r\n\r\n  // Time to sleep per cycle, in milliseconds\r\n  uint32_t sleepTime_;\r\n\r\n  // Time taken by sleep Api\r\n  double total_time_;\r\n};\r\n\r\n#endif\r\n"
  },
  {
    "path": "rocrtst/gtest/CMakeLists.txt",
    "content": "#\r\n# Source files for Google Test Framework\r\n#\r\nset (gtFrwkSrcs src/gtest.cpp)\r\nset (gtFrwkSrcs ${gtFrwkSrcs} src/gtest-port.cpp)\r\nset (gtFrwkSrcs\t${gtFrwkSrcs} src/gtest-printers.cpp)\r\nset (gtFrwkSrcs\t${gtFrwkSrcs} src/gtest-filepath.cpp)\r\nset (gtFrwkSrcs\t${gtFrwkSrcs} src/gtest-test-part.cpp)\r\nset (gtFrwkSrcs\t${gtFrwkSrcs} src/gtest-typed-test.cpp)\r\nset (gtFrwkSrcs\t${gtFrwkSrcs} src/gtest-death-test.cpp)\r\nset (gtFrwkSrcs ${gtFrwkSrcs} src/gtest_main.cpp)\r\n\r\n#\r\n# Header files include path(s).\r\n#\r\ninclude_directories(include)\r\ninclude_directories(include/gtest)\r\ninclude_directories(${CMAKE_CURRENT_SOURCE_DIR})\r\n\r\n#\r\n# Build Google Test Framework as a Static Library object\r\n#\r\nadd_library(${GOOGLE_TEST_FRWK_NAME} STATIC ${gtFrwkSrcs})\r\n\r\n#\r\n# Install build artifacts into one common location\r\n#\r\nINSTALL(TARGETS ${GOOGLE_TEST_FRWK_NAME}\r\n        ARCHIVE DESTINATION ${PROJECT_BINARY_DIR}/lib\r\n        LIBRARY DESTINATION ${PROJECT_BINARY_DIR}/lib\r\n        RUNTIME DESTINATION ${PROJECT_BINARY_DIR}/bin)\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-death-test.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file defines the public API for death tests.  It is\r\n// #included by gtest.h so a user doesn't need to include this\r\n// directly.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\r\n\r\n#include \"gtest/internal/gtest-death-test-internal.h\"\r\n\r\nnamespace testing {\r\n\r\n// This flag controls the style of death tests.  Valid values are \"threadsafe\",\r\n// meaning that the death test child process will re-execute the test binary\r\n// from the start, running only a single death test, or \"fast\",\r\n// meaning that the child process will execute the test logic immediately\r\n// after forking.\r\nGTEST_DECLARE_string_(death_test_style);\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\nnamespace internal {\r\n\r\n// Returns a Boolean value indicating whether the caller is currently\r\n// executing in the context of the death test child process.  Tools such as\r\n// Valgrind heap checkers may need this to modify their behavior in death\r\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\r\n// implementation of death tests.  User code MUST NOT use it.\r\nGTEST_API_ bool InDeathTestChild();\r\n\r\n}  // namespace internal\r\n\r\n// The following macros are useful for writing death tests.\r\n\r\n// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is\r\n// executed:\r\n//\r\n//   1. It generates a warning if there is more than one active\r\n//   thread.  This is because it's safe to fork() or clone() only\r\n//   when there is a single thread.\r\n//\r\n//   2. The parent process clone()s a sub-process and runs the death\r\n//   test in it; the sub-process exits with code 0 at the end of the\r\n//   death test, if it hasn't exited already.\r\n//\r\n//   3. The parent process waits for the sub-process to terminate.\r\n//\r\n//   4. The parent process checks the exit code and error message of\r\n//   the sub-process.\r\n//\r\n// Examples:\r\n//\r\n//   ASSERT_DEATH(server.SendMessage(56, \"Hello\"), \"Invalid port number\");\r\n//   for (int i = 0; i < 5; i++) {\r\n//     EXPECT_DEATH(server.ProcessRequest(i),\r\n//                  \"Invalid request .* in ProcessRequest()\")\r\n//                  << \"Failed to die on request \" << i;\r\n//   }\r\n//\r\n//   ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), \"Exiting\");\r\n//\r\n//   bool KilledBySIGHUP(int exit_code) {\r\n//     return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;\r\n//   }\r\n//\r\n//   ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, \"Hanging up!\");\r\n//\r\n// On the regular expressions used in death tests:\r\n//\r\n//   On POSIX-compliant systems (*nix), we use the <regex.h> library,\r\n//   which uses the POSIX extended regex syntax.\r\n//\r\n//   On other platforms (e.g. Windows), we only support a simple regex\r\n//   syntax implemented as part of Google Test.  This limited\r\n//   implementation should be enough most of the time when writing\r\n//   death tests; though it lacks many features you can find in PCRE\r\n//   or POSIX extended regex syntax.  For example, we don't support\r\n//   union (\"x|y\"), grouping (\"(xy)\"), brackets (\"[xy]\"), and\r\n//   repetition count (\"x{5,7}\"), among others.\r\n//\r\n//   Below is the syntax that we do support.  We chose it to be a\r\n//   subset of both PCRE and POSIX extended regex, so it's easy to\r\n//   learn wherever you come from.  In the following: 'A' denotes a\r\n//   literal character, period (.), or a single \\\\ escape sequence;\r\n//   'x' and 'y' denote regular expressions; 'm' and 'n' are for\r\n//   natural numbers.\r\n//\r\n//     c     matches any literal character c\r\n//     \\\\d   matches any decimal digit\r\n//     \\\\D   matches any character that's not a decimal digit\r\n//     \\\\f   matches \\f\r\n//     \\\\n   matches \\n\r\n//     \\\\r   matches \\r\r\n//     \\\\s   matches any ASCII whitespace, including \\n\r\n//     \\\\S   matches any character that's not a whitespace\r\n//     \\\\t   matches \\t\r\n//     \\\\v   matches \\v\r\n//     \\\\w   matches any letter, _, or decimal digit\r\n//     \\\\W   matches any character that \\\\w doesn't match\r\n//     \\\\c   matches any literal character c, which must be a punctuation\r\n//     .     matches any single character except \\n\r\n//     A?    matches 0 or 1 occurrences of A\r\n//     A*    matches 0 or many occurrences of A\r\n//     A+    matches 1 or many occurrences of A\r\n//     ^     matches the beginning of a string (not that of each line)\r\n//     $     matches the end of a string (not that of each line)\r\n//     xy    matches x followed by y\r\n//\r\n//   If you accidentally use PCRE or POSIX extended regex features\r\n//   not implemented by us, you will get a run-time failure.  In that\r\n//   case, please try to rewrite your regular expression within the\r\n//   above syntax.\r\n//\r\n//   This implementation is *not* meant to be as highly tuned or robust\r\n//   as a compiled regex library, but should perform well enough for a\r\n//   death test, which already incurs significant overhead by launching\r\n//   a child process.\r\n//\r\n// Known caveats:\r\n//\r\n//   A \"threadsafe\" style death test obtains the path to the test\r\n//   program from argv[0] and re-executes it in the sub-process.  For\r\n//   simplicity, the current implementation doesn't search the PATH\r\n//   when launching the sub-process.  This means that the user must\r\n//   invoke the test program via a path that contains at least one\r\n//   path separator (e.g. path/to/foo_test and\r\n//   /absolute/path/to/bar_test are fine, but foo_test is not).  This\r\n//   is rarely a problem as people usually don't put the test binary\r\n//   directory in PATH.\r\n//\r\n// TODO(wan@google.com): make thread-safe death tests search the PATH.\r\n\r\n// Asserts that a given statement causes the program to exit, with an\r\n// integer exit status that satisfies predicate, and emitting error output\r\n// that matches regex.\r\n# define ASSERT_EXIT(statement, predicate, regex) \\\r\n    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)\r\n\r\n// Like ASSERT_EXIT, but continues on to successive tests in the\r\n// test case, if any:\r\n# define EXPECT_EXIT(statement, predicate, regex) \\\r\n    GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)\r\n\r\n// Asserts that a given statement causes the program to exit, either by\r\n// explicitly exiting with a nonzero exit code or being killed by a\r\n// signal, and emitting error output that matches regex.\r\n# define ASSERT_DEATH(statement, regex) \\\r\n    ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)\r\n\r\n// Like ASSERT_DEATH, but continues on to successive tests in the\r\n// test case, if any:\r\n# define EXPECT_DEATH(statement, regex) \\\r\n    EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)\r\n\r\n// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:\r\n\r\n// Tests that an exit code describes a normal exit with a given exit code.\r\nclass GTEST_API_ ExitedWithCode {\r\n public:\r\n  explicit ExitedWithCode(int exit_code);\r\n  bool operator()(int exit_status) const;\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ExitedWithCode& other);\r\n\r\n  const int exit_code_;\r\n};\r\n\r\n# if !GTEST_OS_WINDOWS\r\n// Tests that an exit code describes an exit due to termination by a\r\n// given signal.\r\nclass GTEST_API_ KilledBySignal {\r\n public:\r\n  explicit KilledBySignal(int signum);\r\n  bool operator()(int exit_status) const;\r\n private:\r\n  const int signum_;\r\n};\r\n# endif  // !GTEST_OS_WINDOWS\r\n\r\n// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.\r\n// The death testing framework causes this to have interesting semantics,\r\n// since the sideeffects of the call are only visible in opt mode, and not\r\n// in debug mode.\r\n//\r\n// In practice, this can be used to test functions that utilize the\r\n// LOG(DFATAL) macro using the following style:\r\n//\r\n// int DieInDebugOr12(int* sideeffect) {\r\n//   if (sideeffect) {\r\n//     *sideeffect = 12;\r\n//   }\r\n//   LOG(DFATAL) << \"death\";\r\n//   return 12;\r\n// }\r\n//\r\n// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {\r\n//   int sideeffect = 0;\r\n//   // Only asserts in dbg.\r\n//   EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), \"death\");\r\n//\r\n// #ifdef NDEBUG\r\n//   // opt-mode has sideeffect visible.\r\n//   EXPECT_EQ(12, sideeffect);\r\n// #else\r\n//   // dbg-mode no visible sideeffect.\r\n//   EXPECT_EQ(0, sideeffect);\r\n// #endif\r\n// }\r\n//\r\n// This will assert that DieInDebugReturn12InOpt() crashes in debug\r\n// mode, usually due to a DCHECK or LOG(DFATAL), but returns the\r\n// appropriate fallback value (12 in this case) in opt mode. If you\r\n// need to test that a function has appropriate side-effects in opt\r\n// mode, include assertions against the side-effects.  A general\r\n// pattern for this is:\r\n//\r\n// EXPECT_DEBUG_DEATH({\r\n//   // Side-effects here will have an effect after this statement in\r\n//   // opt mode, but none in debug mode.\r\n//   EXPECT_EQ(12, DieInDebugOr12(&sideeffect));\r\n// }, \"death\");\r\n//\r\n# ifdef NDEBUG\r\n\r\n#  define EXPECT_DEBUG_DEATH(statement, regex) \\\r\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\r\n\r\n#  define ASSERT_DEBUG_DEATH(statement, regex) \\\r\n  GTEST_EXECUTE_STATEMENT_(statement, regex)\r\n\r\n# else\r\n\r\n#  define EXPECT_DEBUG_DEATH(statement, regex) \\\r\n  EXPECT_DEATH(statement, regex)\r\n\r\n#  define ASSERT_DEBUG_DEATH(statement, regex) \\\r\n  ASSERT_DEATH(statement, regex)\r\n\r\n# endif  // NDEBUG for EXPECT_DEBUG_DEATH\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and\r\n// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if\r\n// death tests are supported; otherwise they just issue a warning.  This is\r\n// useful when you are combining death test assertions with normal test\r\n// assertions in one test.\r\n#if GTEST_HAS_DEATH_TEST\r\n# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\r\n    EXPECT_DEATH(statement, regex)\r\n# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\r\n    ASSERT_DEATH(statement, regex)\r\n#else\r\n# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \\\r\n    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )\r\n# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \\\r\n    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)\r\n#endif\r\n\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-message.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file defines the Message class.\r\n//\r\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\r\n// leave some internal implementation details in this header file.\r\n// They are clearly marked by comments like this:\r\n//\r\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n//\r\n// Such code is NOT meant to be used by a user directly, and is subject\r\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\r\n// program!\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\r\n\r\n#include <limits>\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n// Ensures that there is at least one operator<< in the global namespace.\r\n// See Message& operator<<(...) below for why.\r\nvoid operator<<(const testing::internal::Secret&, int);\r\n\r\nnamespace testing {\r\n\r\n// The Message class works like an ostream repeater.\r\n//\r\n// Typical usage:\r\n//\r\n//   1. You stream a bunch of values to a Message object.\r\n//      It will remember the text in a stringstream.\r\n//   2. Then you stream the Message object to an ostream.\r\n//      This causes the text in the Message to be streamed\r\n//      to the ostream.\r\n//\r\n// For example;\r\n//\r\n//   testing::Message foo;\r\n//   foo << 1 << \" != \" << 2;\r\n//   std::cout << foo;\r\n//\r\n// will print \"1 != 2\".\r\n//\r\n// Message is not intended to be inherited from.  In particular, its\r\n// destructor is not virtual.\r\n//\r\n// Note that stringstream behaves differently in gcc and in MSVC.  You\r\n// can stream a NULL char pointer to it in the former, but not in the\r\n// latter (it causes an access violation if you do).  The Message\r\n// class hides this difference by treating a NULL char pointer as\r\n// \"(null)\".\r\nclass GTEST_API_ Message {\r\n private:\r\n  // The type of basic IO manipulators (endl, ends, and flush) for\r\n  // narrow streams.\r\n  typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);\r\n\r\n public:\r\n  // Constructs an empty Message.\r\n  Message();\r\n\r\n  // Copy constructor.\r\n  Message(const Message& msg) : ss_(new ::std::stringstream) {  // NOLINT\r\n    *ss_ << msg.GetString();\r\n  }\r\n\r\n  // Constructs a Message from a C-string.\r\n  explicit Message(const char* str) : ss_(new ::std::stringstream) {\r\n    *ss_ << str;\r\n  }\r\n\r\n#if GTEST_OS_SYMBIAN\r\n  // Streams a value (either a pointer or not) to this object.\r\n  template <typename T>\r\n  inline Message& operator <<(const T& value) {\r\n    StreamHelper(typename internal::is_pointer<T>::type(), value);\r\n    return *this;\r\n  }\r\n#else\r\n  // Streams a non-pointer value to this object.\r\n  template <typename T>\r\n  inline Message& operator <<(const T& val) {\r\n    // Some libraries overload << for STL containers.  These\r\n    // overloads are defined in the global namespace instead of ::std.\r\n    //\r\n    // C++'s symbol lookup rule (i.e. Koenig lookup) says that these\r\n    // overloads are visible in either the std namespace or the global\r\n    // namespace, but not other namespaces, including the testing\r\n    // namespace which Google Test's Message class is in.\r\n    //\r\n    // To allow STL containers (and other types that has a << operator\r\n    // defined in the global namespace) to be used in Google Test\r\n    // assertions, testing::Message must access the custom << operator\r\n    // from the global namespace.  With this using declaration,\r\n    // overloads of << defined in the global namespace and those\r\n    // visible via Koenig lookup are both exposed in this function.\r\n    using ::operator <<;\r\n    *ss_ << val;\r\n    return *this;\r\n  }\r\n\r\n  // Streams a pointer value to this object.\r\n  //\r\n  // This function is an overload of the previous one.  When you\r\n  // stream a pointer to a Message, this definition will be used as it\r\n  // is more specialized.  (The C++ Standard, section\r\n  // [temp.func.order].)  If you stream a non-pointer, then the\r\n  // previous definition will be used.\r\n  //\r\n  // The reason for this overload is that streaming a NULL pointer to\r\n  // ostream is undefined behavior.  Depending on the compiler, you\r\n  // may get \"0\", \"(nil)\", \"(null)\", or an access violation.  To\r\n  // ensure consistent result across compilers, we always treat NULL\r\n  // as \"(null)\".\r\n  template <typename T>\r\n  inline Message& operator <<(T* const& pointer) {  // NOLINT\r\n    if (pointer == NULL) {\r\n      *ss_ << \"(null)\";\r\n    }\r\n    else {\r\n      *ss_ << pointer;\r\n    }\r\n\r\n    return *this;\r\n  }\r\n#endif  // GTEST_OS_SYMBIAN\r\n\r\n  // Since the basic IO manipulators are overloaded for both narrow\r\n  // and wide streams, we have to provide this specialized definition\r\n  // of operator <<, even though its body is the same as the\r\n  // templatized version above.  Without this definition, streaming\r\n  // endl or other basic IO manipulators to Message will confuse the\r\n  // compiler.\r\n  Message& operator <<(BasicNarrowIoManip val) {\r\n    *ss_ << val;\r\n    return *this;\r\n  }\r\n\r\n  // Instead of 1/0, we want to see true/false for bool values.\r\n  Message& operator <<(bool b) {\r\n    return *this << (b ? \"true\" : \"false\");\r\n  }\r\n\r\n  // These two overloads allow streaming a wide C string to a Message\r\n  // using the UTF-8 encoding.\r\n  Message& operator <<(const wchar_t* wide_c_str);\r\n  Message& operator <<(wchar_t* wide_c_str);\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\n  // Converts the given wide string to a narrow string using the UTF-8\r\n  // encoding, and streams the result to this Message object.\r\n  Message& operator <<(const ::std::wstring& wstr);\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\n  // Converts the given wide string to a narrow string using the UTF-8\r\n  // encoding, and streams the result to this Message object.\r\n  Message& operator <<(const ::wstring& wstr);\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n  // Gets the text streamed to this object so far as an std::string.\r\n  // Each '\\0' character in the buffer is replaced with \"\\\\0\".\r\n  //\r\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n  std::string GetString() const;\r\n\r\n private:\r\n\r\n#if GTEST_OS_SYMBIAN\r\n  // These are needed as the Nokia Symbian Compiler cannot decide between\r\n  // const T& and const T* in a function template. The Nokia compiler _can_\r\n  // decide between class template specializations for T and T*, so a\r\n  // tr1::type_traits-like is_pointer works, and we can overload on that.\r\n  template <typename T>\r\n  inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {\r\n    if (pointer == NULL) {\r\n      *ss_ << \"(null)\";\r\n    }\r\n    else {\r\n      *ss_ << pointer;\r\n    }\r\n  }\r\n  template <typename T>\r\n  inline void StreamHelper(internal::false_type /*is_pointer*/,\r\n                           const T& value) {\r\n    // See the comments in Message& operator <<(const T&) above for why\r\n    // we need this using statement.\r\n    using ::operator <<;\r\n    *ss_ << value;\r\n  }\r\n#endif  // GTEST_OS_SYMBIAN\r\n\r\n  // We'll hold the text streamed to this object here.\r\n  const internal::scoped_ptr< ::std::stringstream> ss_;\r\n\r\n  // We declare (but don't implement) this to prevent the compiler\r\n  // from implementing the assignment operator.\r\n  void operator=(const Message&);\r\n};\r\n\r\n// Streams a Message to an ostream.\r\ninline std::ostream& operator <<(std::ostream& os, const Message& sb) {\r\n  return os << sb.GetString();\r\n}\r\n\r\nnamespace internal {\r\n\r\n// Converts a streamable value to an std::string.  A NULL pointer is\r\n// converted to \"(null)\".  When the input value is a ::string,\r\n// ::std::string, ::wstring, or ::std::wstring object, each NUL\r\n// character in it is replaced with \"\\\\0\".\r\ntemplate <typename T>\r\nstd::string StreamableToString(const T& streamable) {\r\n  return (Message() << streamable).GetString();\r\n}\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-param-test.h",
    "content": "// This file was GENERATED by command:\r\n//     pump.py gtest-param-test.h.pump\r\n// DO NOT EDIT BY HAND!!!\r\n\r\n// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: vladl@google.com (Vlad Losev)\r\n//\r\n// Macros and functions for implementing parameterized tests\r\n// in Google C++ Testing Framework (Google Test)\r\n//\r\n// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\r\n//\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\r\n\r\n\r\n// Value-parameterized tests allow you to test your code with different\r\n// parameters without writing multiple copies of the same test.\r\n//\r\n// Here is how you use value-parameterized tests:\r\n\r\n#if 0\r\n\r\n// To write value-parameterized tests, first you should define a fixture\r\n// class. It is usually derived from testing::TestWithParam<T> (see below for\r\n// another inheritance scheme that's sometimes useful in more complicated\r\n// class hierarchies), where the type of your parameter values.\r\n// TestWithParam<T> is itself derived from testing::Test. T can be any\r\n// copyable type. If it's a raw pointer, you are responsible for managing the\r\n// lifespan of the pointed values.\r\n\r\nclass FooTest : public ::testing::TestWithParam<const char*> {\r\n  // You can implement all the usual class fixture members here.\r\n};\r\n\r\n// Then, use the TEST_P macro to define as many parameterized tests\r\n// for this fixture as you want. The _P suffix is for \"parameterized\"\r\n// or \"pattern\", whichever you prefer to think.\r\n\r\nTEST_P(FooTest, DoesBlah) {\r\n  // Inside a test, access the test parameter with the GetParam() method\r\n  // of the TestWithParam<T> class:\r\n  EXPECT_TRUE(foo.Blah(GetParam()));\r\n  ...\r\n}\r\n\r\nTEST_P(FooTest, HasBlahBlah) {\r\n  ...\r\n}\r\n\r\n// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test\r\n// case with any set of parameters you want. Google Test defines a number\r\n// of functions for generating test parameters. They return what we call\r\n// (surprise!) parameter generators. Here is a  summary of them, which\r\n// are all in the testing namespace:\r\n//\r\n//\r\n//  Range(begin, end [, step]) - Yields values {begin, begin+step,\r\n//                               begin+step+step, ...}. The values do not\r\n//                               include end. step defaults to 1.\r\n//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.\r\n//  ValuesIn(container)        - Yields values from a C-style array, an STL\r\n//  ValuesIn(begin,end)          container, or an iterator range [begin, end).\r\n//  Bool()                     - Yields sequence {false, true}.\r\n//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product\r\n//                               for the math savvy) of the values generated\r\n//                               by the N generators.\r\n//\r\n// For more details, see comments at the definitions of these functions below\r\n// in this file.\r\n//\r\n// The following statement will instantiate tests from the FooTest test case\r\n// each with parameter values \"meeny\", \"miny\", and \"moe\".\r\n\r\nINSTANTIATE_TEST_CASE_P(InstantiationName,\r\n                        FooTest,\r\n                        Values(\"meeny\", \"miny\", \"moe\"));\r\n\r\n// To distinguish different instances of the pattern, (yes, you\r\n// can instantiate it more then once) the first argument to the\r\n// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the\r\n// actual test case name. Remember to pick unique prefixes for different\r\n// instantiations. The tests from the instantiation above will have\r\n// these names:\r\n//\r\n//    * InstantiationName/FooTest.DoesBlah/0 for \"meeny\"\r\n//    * InstantiationName/FooTest.DoesBlah/1 for \"miny\"\r\n//    * InstantiationName/FooTest.DoesBlah/2 for \"moe\"\r\n//    * InstantiationName/FooTest.HasBlahBlah/0 for \"meeny\"\r\n//    * InstantiationName/FooTest.HasBlahBlah/1 for \"miny\"\r\n//    * InstantiationName/FooTest.HasBlahBlah/2 for \"moe\"\r\n//\r\n// You can use these names in --gtest_filter.\r\n//\r\n// This statement will instantiate all tests from FooTest again, each\r\n// with parameter values \"cat\" and \"dog\":\r\n\r\nconst char* pets[] = {\"cat\", \"dog\"};\r\nINSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));\r\n\r\n// The tests from the instantiation above will have these names:\r\n//\r\n//    * AnotherInstantiationName/FooTest.DoesBlah/0 for \"cat\"\r\n//    * AnotherInstantiationName/FooTest.DoesBlah/1 for \"dog\"\r\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for \"cat\"\r\n//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for \"dog\"\r\n//\r\n// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests\r\n// in the given test case, whether their definitions come before or\r\n// AFTER the INSTANTIATE_TEST_CASE_P statement.\r\n//\r\n// Please also note that generator expressions (including parameters to the\r\n// generators) are evaluated in InitGoogleTest(), after main() has started.\r\n// This allows the user on one hand, to adjust generator parameters in order\r\n// to dynamically determine a set of tests to run and on the other hand,\r\n// give the user a chance to inspect the generated tests with Google Test\r\n// reflection API before RUN_ALL_TESTS() is executed.\r\n//\r\n// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc\r\n// for more examples.\r\n//\r\n// In the future, we plan to publish the API for defining new parameter\r\n// generators. But for now this interface remains part of the internal\r\n// implementation and is subject to change.\r\n//\r\n//\r\n// A parameterized test fixture must be derived from testing::Test and from\r\n// testing::WithParamInterface<T>, where T is the type of the parameter\r\n// values. Inheriting from TestWithParam<T> satisfies that requirement because\r\n// TestWithParam<T> inherits from both Test and WithParamInterface. In more\r\n// complicated hierarchies, however, it is occasionally useful to inherit\r\n// separately from Test and WithParamInterface. For example:\r\n\r\nclass BaseTest : public ::testing::Test {\r\n  // You can inherit all the usual members for a non-parameterized test\r\n  // fixture here.\r\n};\r\n\r\nclass DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {\r\n  // The usual test fixture members go here too.\r\n};\r\n\r\nTEST_F(BaseTest, HasFoo) {\r\n  // This is an ordinary non-parameterized test.\r\n}\r\n\r\nTEST_P(DerivedTest, DoesBlah) {\r\n  // GetParam works just the same here as if you inherit from TestWithParam.\r\n  EXPECT_TRUE(foo.Blah(GetParam()));\r\n}\r\n\r\n#endif  // 0\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if !GTEST_OS_SYMBIAN\r\n# include <utility>\r\n#endif\r\n\r\n// scripts/fuse_gtest.py depends on gtest's own header being #included\r\n// *unconditionally*.  Therefore these #includes cannot be moved\r\n// inside #if GTEST_HAS_PARAM_TEST.\r\n#include \"gtest/internal/gtest-internal.h\"\r\n#include \"gtest/internal/gtest-param-util.h\"\r\n#include \"gtest/internal/gtest-param-util-generated.h\"\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n\r\nnamespace testing {\r\n\r\n// Functions producing parameter generators.\r\n//\r\n// Google Test uses these generators to produce parameters for value-\r\n// parameterized tests. When a parameterized test case is instantiated\r\n// with a particular generator, Google Test creates and runs tests\r\n// for each element in the sequence produced by the generator.\r\n//\r\n// In the following sample, tests from test case FooTest are instantiated\r\n// each three times with parameter values 3, 5, and 8:\r\n//\r\n// class FooTest : public TestWithParam<int> { ... };\r\n//\r\n// TEST_P(FooTest, TestThis) {\r\n// }\r\n// TEST_P(FooTest, TestThat) {\r\n// }\r\n// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));\r\n//\r\n\r\n// Range() returns generators providing sequences of values in a range.\r\n//\r\n// Synopsis:\r\n// Range(start, end)\r\n//   - returns a generator producing a sequence of values {start, start+1,\r\n//     start+2, ..., }.\r\n// Range(start, end, step)\r\n//   - returns a generator producing a sequence of values {start, start+step,\r\n//     start+step+step, ..., }.\r\n// Notes:\r\n//   * The generated sequences never include end. For example, Range(1, 5)\r\n//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)\r\n//     returns a generator producing {1, 3, 5, 7}.\r\n//   * start and end must have the same type. That type may be any integral or\r\n//     floating-point type or a user defined type satisfying these conditions:\r\n//     * It must be assignable (have operator=() defined).\r\n//     * It must have operator+() (operator+(int-compatible type) for\r\n//       two-operand version).\r\n//     * It must have operator<() defined.\r\n//     Elements in the resulting sequences will also have that type.\r\n//   * Condition start < end must be satisfied in order for resulting sequences\r\n//     to contain any elements.\r\n//\r\ntemplate <typename T, typename IncrementT>\r\ninternal::ParamGenerator<T> Range(T start, T end, IncrementT step) {\r\n  return internal::ParamGenerator<T>(\r\n           new internal::RangeGenerator<T, IncrementT>(start, end, step));\r\n}\r\n\r\ntemplate <typename T>\r\ninternal::ParamGenerator<T> Range(T start, T end) {\r\n  return Range(start, end, 1);\r\n}\r\n\r\n// ValuesIn() function allows generation of tests with parameters coming from\r\n// a container.\r\n//\r\n// Synopsis:\r\n// ValuesIn(const T (&array)[N])\r\n//   - returns a generator producing sequences with elements from\r\n//     a C-style array.\r\n// ValuesIn(const Container& container)\r\n//   - returns a generator producing sequences with elements from\r\n//     an STL-style container.\r\n// ValuesIn(Iterator begin, Iterator end)\r\n//   - returns a generator producing sequences with elements from\r\n//     a range [begin, end) defined by a pair of STL-style iterators. These\r\n//     iterators can also be plain C pointers.\r\n//\r\n// Please note that ValuesIn copies the values from the containers\r\n// passed in and keeps them to generate tests in RUN_ALL_TESTS().\r\n//\r\n// Examples:\r\n//\r\n// This instantiates tests from test case StringTest\r\n// each with C-string values of \"foo\", \"bar\", and \"baz\":\r\n//\r\n// const char* strings[] = {\"foo\", \"bar\", \"baz\"};\r\n// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));\r\n//\r\n// This instantiates tests from test case StlStringTest\r\n// each with STL strings with values \"a\" and \"b\":\r\n//\r\n// ::std::vector< ::std::string> GetParameterStrings() {\r\n//   ::std::vector< ::std::string> v;\r\n//   v.push_back(\"a\");\r\n//   v.push_back(\"b\");\r\n//   return v;\r\n// }\r\n//\r\n// INSTANTIATE_TEST_CASE_P(CharSequence,\r\n//                         StlStringTest,\r\n//                         ValuesIn(GetParameterStrings()));\r\n//\r\n//\r\n// This will also instantiate tests from CharTest\r\n// each with parameter values 'a' and 'b':\r\n//\r\n// ::std::list<char> GetParameterChars() {\r\n//   ::std::list<char> list;\r\n//   list.push_back('a');\r\n//   list.push_back('b');\r\n//   return list;\r\n// }\r\n// ::std::list<char> l = GetParameterChars();\r\n// INSTANTIATE_TEST_CASE_P(CharSequence2,\r\n//                         CharTest,\r\n//                         ValuesIn(l.begin(), l.end()));\r\n//\r\ntemplate <typename ForwardIterator>\r\ninternal::ParamGenerator <\r\ntypename ::testing::internal::IteratorTraits<ForwardIterator>::value_type >\r\nValuesIn(ForwardIterator begin, ForwardIterator end) {\r\n  typedef typename ::testing::internal::IteratorTraits<ForwardIterator>\r\n  ::value_type ParamType;\r\n  return internal::ParamGenerator<ParamType>(\r\n           new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));\r\n}\r\n\r\ntemplate <typename T, size_t N>\r\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {\r\n  return ValuesIn(array, array + N);\r\n}\r\n\r\ntemplate <class Container>\r\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\r\n  const Container& container) {\r\n  return ValuesIn(container.begin(), container.end());\r\n}\r\n\r\n// Values() allows generating tests from explicitly specified list of\r\n// parameters.\r\n//\r\n// Synopsis:\r\n// Values(T v1, T v2, ..., T vN)\r\n//   - returns a generator producing sequences with elements v1, v2, ..., vN.\r\n//\r\n// For example, this instantiates tests from test case BarTest each\r\n// with values \"one\", \"two\", and \"three\":\r\n//\r\n// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values(\"one\", \"two\", \"three\"));\r\n//\r\n// This instantiates tests from test case BazTest each with values 1, 2, 3.5.\r\n// The exact type of values will depend on the type of parameter in BazTest.\r\n//\r\n// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));\r\n//\r\n// Currently, Values() supports from 1 to 50 parameters.\r\n//\r\ntemplate <typename T1>\r\ninternal::ValueArray1<T1> Values(T1 v1) {\r\n  return internal::ValueArray1<T1>(v1);\r\n}\r\n\r\ntemplate <typename T1, typename T2>\r\ninternal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {\r\n  return internal::ValueArray2<T1, T2>(v1, v2);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3>\r\ninternal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {\r\n  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\ninternal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {\r\n  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\ninternal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n    T5 v5) {\r\n  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\ninternal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,\r\n    T4 v4, T5 v5, T6 v6) {\r\n  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\ninternal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,\r\n    T4 v4, T5 v5, T6 v6, T7 v7) {\r\n  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,\r\n         v6, v7);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\ninternal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,\r\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {\r\n  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,\r\n         v5, v6, v7, v8);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\ninternal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,\r\n    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {\r\n  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,\r\n         v4, v5, v6, v7, v8, v9);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\ninternal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,\r\n    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {\r\n  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,\r\n         v2, v3, v4, v5, v6, v7, v8, v9, v10);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11>\r\ninternal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,\r\n         T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\nT10 v10, T11 v11) {\r\n  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,\r\n         T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12>\r\ninternal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\nT10 v10, T11 v11, T12 v12) {\r\n  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13>\r\ninternal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n         T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\nT10 v10, T11 v11, T12 v12, T13 v13) {\r\n  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14>\r\ninternal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\nT10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {\r\n  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\r\n                        v14);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15>\r\ninternal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\r\nT9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {\r\n  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\r\n                             v13, v14, v15);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16>\r\ninternal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                               T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\nT16 v16) {\r\n  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\r\n                                  v12, v13, v14, v15, v16);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17>\r\ninternal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                                    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\nT16 v16, T17 v17) {\r\n  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\r\n                                       v11, v12, v13, v14, v15, v16, v17);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18>\r\ninternal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\r\n             T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\nT16 v16, T17 v17, T18 v18) {\r\n  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\r\n             v10, v11, v12, v13, v14, v15, v16, v17, v18);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19>\r\ninternal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\r\n             T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\r\nT15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {\r\n  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,\r\n             v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20>\r\ninternal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n             T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\r\nT14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {\r\n  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,\r\n             v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21>\r\ninternal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n             T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\r\nT14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {\r\n  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,\r\n             v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22>\r\ninternal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,\r\n             T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\nT21 v21, T22 v22) {\r\n  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,\r\n             v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\r\n             v20, v21, v22);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23>\r\ninternal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,\r\n             T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\nT21 v21, T22 v22, T23 v23) {\r\n  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,\r\n             v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\r\n             v20, v21, v22, v23);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24>\r\ninternal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,\r\n             T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\nT21 v21, T22 v22, T23 v23, T24 v24) {\r\n  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,\r\n             v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,\r\n             v19, v20, v21, v22, v23, v24);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25>\r\ninternal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,\r\n             T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,\r\n             T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,\r\nT20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {\r\n  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,\r\n             v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,\r\n             v18, v19, v20, v21, v22, v23, v24, v25);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26>\r\ninternal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\nT26 v26) {\r\n  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,\r\n              v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27>\r\ninternal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n         T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\nT26 v26, T27 v27) {\r\n  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,\r\n                   v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28>\r\ninternal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n         T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\nT26 v26, T27 v27, T28 v28) {\r\n  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\r\n                        v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,\r\n                        v28);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29>\r\ninternal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\nT26 v26, T27 v27, T28 v28, T29 v29) {\r\n  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\r\n                             v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,\r\n                             v27, v28, v29);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30>\r\ninternal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\r\n                          T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\r\n                          T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\r\nT25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {\r\n  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\r\n                                  v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,\r\n                                  v26, v27, v28, v29, v30);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31>\r\ninternal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                               T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n                               T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\nT24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {\r\n  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\r\n                                       v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,\r\n                                       v25, v26, v27, v28, v29, v30, v31);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32>\r\ninternal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                                    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n                                    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\n                                    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\r\nT32 v32) {\r\n  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\r\n             v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\r\n             v24, v25, v26, v27, v28, v29, v30, v31, v32);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33>\r\ninternal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\r\n             T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n             T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\n             T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\r\nT32 v32, T33 v33) {\r\n  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,\r\n             v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\r\n             v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34>\r\ninternal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\r\n             T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\r\n             T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,\r\n             T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,\r\nT31 v31, T32 v32, T33 v33, T34 v34) {\r\n  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,\r\n             v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,\r\n             v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35>\r\ninternal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n             T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\r\n             T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\r\n             T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\r\nT30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {\r\n  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,\r\n             v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,\r\n             v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36>\r\ninternal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n             T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\r\n             T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\r\n             T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\r\nT30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {\r\n  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,\r\n             v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\r\n             v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\r\n             v34, v35, v36);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37>\r\ninternal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,\r\n             T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\n             T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\r\n             T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\r\nT37 v37) {\r\n  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,\r\n             v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\r\n             v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\r\n             v34, v35, v36, v37);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38>\r\ninternal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,\r\n             T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\n             T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\r\n             T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\r\nT37 v37, T38 v38) {\r\n  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,\r\n             v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,\r\n             v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,\r\n             v33, v34, v35, v36, v37, v38);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39>\r\ninternal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,\r\n             T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,\r\n             T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,\r\n             T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,\r\n             T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,\r\nT37 v37, T38 v38, T39 v39) {\r\n  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,\r\n             v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,\r\n             v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,\r\n             v32, v33, v34, v35, v36, v37, v38, v39);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40>\r\ninternal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,\r\n             T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,\r\n             T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,\r\n             T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,\r\n             T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,\r\nT36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {\r\n  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,\r\n              v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,\r\n              v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41>\r\ninternal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n         T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n                     T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\nT34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {\r\n  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,\r\n                   v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,\r\n                   v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42>\r\ninternal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n         T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n                     T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n                     T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\nT42 v42) {\r\n  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,\r\n                        v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,\r\n                        v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,\r\n                        v42);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43>\r\ninternal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n         T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n                     T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n                     T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\nT42 v42, T43 v43) {\r\n  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,\r\n                             v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,\r\n                             v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,\r\n                             v41, v42, v43);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44>\r\ninternal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n                     T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n                     T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n                     T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n                     T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\nT42 v42, T43 v43, T44 v44) {\r\n  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,\r\n                                  v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,\r\n                                  v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,\r\n                                  v40, v41, v42, v43, v44);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45>\r\ninternal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\r\n                          T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\r\n                          T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\r\n                          T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,\r\n                          T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,\r\nT41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {\r\n  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,\r\n                                       v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,\r\n                                       v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,\r\n                                       v39, v40, v41, v42, v43, v44, v45);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46>\r\ninternal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                               T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n                               T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\n                               T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\r\n                               T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\r\nT40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {\r\n  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,\r\n             v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\r\n             v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,\r\n             v38, v39, v40, v41, v42, v43, v44, v45, v46);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47>\r\ninternal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n                                    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n                                    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\n                                    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\r\n                                    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\r\nT40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {\r\n  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,\r\n             v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,\r\n             v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,\r\n             v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48>\r\ninternal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,\r\n             T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,\r\n             T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,\r\n             T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,\r\n             T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,\r\n             T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,\r\nT48 v48) {\r\n  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,\r\n             v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,\r\n             v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,\r\n             v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49>\r\ninternal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,\r\n             T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,\r\n             T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,\r\n             T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,\r\n             T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,\r\n             T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,\r\nT47 v47, T48 v48, T49 v49) {\r\n  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,\r\n             v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,\r\n             v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,\r\n             v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49, typename T50>\r\ninternal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,\r\n             T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,\r\n             T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,\r\n             T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,\r\n             T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,\r\n             T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,\r\nT46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {\r\n  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n         T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n         T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n         T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,\r\n             v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,\r\n             v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,\r\n             v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,\r\n             v48, v49, v50);\r\n}\r\n\r\n// Bool() allows generating tests with parameters in a set of (false, true).\r\n//\r\n// Synopsis:\r\n// Bool()\r\n//   - returns a generator producing sequences with elements {false, true}.\r\n//\r\n// It is useful when testing code that depends on Boolean flags. Combinations\r\n// of multiple flags can be tested when several Bool()'s are combined using\r\n// Combine() function.\r\n//\r\n// In the following example all tests in the test case FlagDependentTest\r\n// will be instantiated twice with parameters false and true.\r\n//\r\n// class FlagDependentTest : public testing::TestWithParam<bool> {\r\n//   virtual void SetUp() {\r\n//     external_flag = GetParam();\r\n//   }\r\n// }\r\n// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());\r\n//\r\ninline internal::ParamGenerator<bool> Bool() {\r\n  return Values(false, true);\r\n}\r\n\r\n# if GTEST_HAS_COMBINE\r\n// Combine() allows the user to combine two or more sequences to produce\r\n// values of a Cartesian product of those sequences' elements.\r\n//\r\n// Synopsis:\r\n// Combine(gen1, gen2, ..., genN)\r\n//   - returns a generator producing sequences with elements coming from\r\n//     the Cartesian product of elements from the sequences generated by\r\n//     gen1, gen2, ..., genN. The sequence elements will have a type of\r\n//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types\r\n//     of elements from sequences produces by gen1, gen2, ..., genN.\r\n//\r\n// Combine can have up to 10 arguments. This number is currently limited\r\n// by the maximum number of elements in the tuple implementation used by Google\r\n// Test.\r\n//\r\n// Example:\r\n//\r\n// This will instantiate tests in test case AnimalTest each one with\r\n// the parameter values tuple(\"cat\", BLACK), tuple(\"cat\", WHITE),\r\n// tuple(\"dog\", BLACK), and tuple(\"dog\", WHITE):\r\n//\r\n// enum Color { BLACK, GRAY, WHITE };\r\n// class AnimalTest\r\n//     : public testing::TestWithParam<tuple<const char*, Color> > {...};\r\n//\r\n// TEST_P(AnimalTest, AnimalLooksNice) {...}\r\n//\r\n// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,\r\n//                         Combine(Values(\"cat\", \"dog\"),\r\n//                                 Values(BLACK, WHITE)));\r\n//\r\n// This will instantiate tests in FlagDependentTest with all variations of two\r\n// Boolean flags:\r\n//\r\n// class FlagDependentTest\r\n//     : public testing::TestWithParam<tuple<bool, bool> > {\r\n//   virtual void SetUp() {\r\n//     // Assigns external_flag_1 and external_flag_2 values from the tuple.\r\n//     tie(external_flag_1, external_flag_2) = GetParam();\r\n//   }\r\n// };\r\n//\r\n// TEST_P(FlagDependentTest, TestFeature1) {\r\n//   // Test your code using external_flag_1 and external_flag_2 here.\r\n// }\r\n// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,\r\n//                         Combine(Bool(), Bool()));\r\n//\r\ntemplate <typename Generator1, typename Generator2>\r\ninternal::CartesianProductHolder2<Generator1, Generator2> Combine(\r\n  const Generator1& g1, const Generator2& g2) {\r\n  return internal::CartesianProductHolder2<Generator1, Generator2>(\r\n           g1, g2);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3>\r\ninternal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(\r\n  const Generator1& g1, const Generator2& g2, const Generator3& g3) {\r\n  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(\r\n           g1, g2, g3);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4>\r\ninternal::CartesianProductHolder4<Generator1, Generator2, Generator3,\r\n         Generator4> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\nconst Generator4& g4) {\r\n  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,\r\n         Generator4>(\r\n           g1, g2, g3, g4);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5>\r\ninternal::CartesianProductHolder5<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\nconst Generator4& g4, const Generator5& g5) {\r\n  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5>(\r\n           g1, g2, g3, g4, g5);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5, typename Generator6>\r\ninternal::CartesianProductHolder6<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\nconst Generator4& g4, const Generator5& g5, const Generator6& g6) {\r\n  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6>(\r\n           g1, g2, g3, g4, g5, g6);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5, typename Generator6,\r\n          typename Generator7>\r\ninternal::CartesianProductHolder7<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\n           const Generator4& g4, const Generator5& g5, const Generator6& g6,\r\nconst Generator7& g7) {\r\n  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7>(\r\n           g1, g2, g3, g4, g5, g6, g7);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5, typename Generator6,\r\n          typename Generator7, typename Generator8>\r\ninternal::CartesianProductHolder8<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\n           const Generator4& g4, const Generator5& g5, const Generator6& g6,\r\nconst Generator7& g7, const Generator8& g8) {\r\n  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8>(\r\n           g1, g2, g3, g4, g5, g6, g7, g8);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5, typename Generator6,\r\n          typename Generator7, typename Generator8, typename Generator9>\r\ninternal::CartesianProductHolder9<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8,\r\n         Generator9> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\n           const Generator4& g4, const Generator5& g5, const Generator6& g6,\r\nconst Generator7& g7, const Generator8& g8, const Generator9& g9) {\r\n  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(\r\n           g1, g2, g3, g4, g5, g6, g7, g8, g9);\r\n}\r\n\r\ntemplate <typename Generator1, typename Generator2, typename Generator3,\r\n          typename Generator4, typename Generator5, typename Generator6,\r\n          typename Generator7, typename Generator8, typename Generator9,\r\n          typename Generator10>\r\ninternal::CartesianProductHolder10<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,\r\n         Generator10> Combine(\r\n           const Generator1& g1, const Generator2& g2, const Generator3& g3,\r\n           const Generator4& g4, const Generator5& g5, const Generator6& g6,\r\n           const Generator7& g7, const Generator8& g8, const Generator9& g9,\r\nconst Generator10& g10) {\r\n  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,\r\n         Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,\r\n         Generator10>(\r\n           g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);\r\n}\r\n# endif  // GTEST_HAS_COMBINE\r\n\r\n\r\n\r\n# define TEST_P(test_case_name, test_name) \\\r\n  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \\\r\n      : public test_case_name { \\\r\n   public: \\\r\n    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \\\r\n    virtual void TestBody(); \\\r\n   private: \\\r\n    static int AddToRegistry() { \\\r\n      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \\\r\n          GetTestCasePatternHolder<test_case_name>(\\\r\n              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\\\r\n                  #test_case_name, \\\r\n                  #test_name, \\\r\n                  new ::testing::internal::TestMetaFactory< \\\r\n                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \\\r\n      return 0; \\\r\n    } \\\r\n    static int gtest_registering_dummy_; \\\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(\\\r\n        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \\\r\n  }; \\\r\n  int GTEST_TEST_CLASS_NAME_(test_case_name, \\\r\n                             test_name)::gtest_registering_dummy_ = \\\r\n      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \\\r\n  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()\r\n\r\n# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \\\r\n  ::testing::internal::ParamGenerator<test_case_name::ParamType> \\\r\n      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \\\r\n  int gtest_##prefix##test_case_name##_dummy_ = \\\r\n      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \\\r\n          GetTestCasePatternHolder<test_case_name>(\\\r\n              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\\\r\n                  #prefix, \\\r\n                  &gtest_##prefix##test_case_name##_EvalGenerator_, \\\r\n                  __FILE__, __LINE__)\r\n\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-printers.h",
    "content": "// Copyright 2007, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Google Test - The Google C++ Testing Framework\r\n//\r\n// This file implements a universal value printer that can print a\r\n// value of any type T:\r\n//\r\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\r\n//\r\n// A user can teach this function how to print a class type T by\r\n// defining either operator<<() or PrintTo() in the namespace that\r\n// defines T.  More specifically, the FIRST defined function in the\r\n// following list will be used (assuming T is defined in namespace\r\n// foo):\r\n//\r\n//   1. foo::PrintTo(const T&, ostream*)\r\n//   2. operator<<(ostream&, const T&) defined in either foo or the\r\n//      global namespace.\r\n//\r\n// If none of the above is defined, it will print the debug string of\r\n// the value if it is a protocol buffer, or print the raw bytes in the\r\n// value otherwise.\r\n//\r\n// To aid debugging: when T is a reference type, the address of the\r\n// value is also printed; when T is a (const) char pointer, both the\r\n// pointer value and the NUL-terminated string it points to are\r\n// printed.\r\n//\r\n// We also provide some convenient wrappers:\r\n//\r\n//   // Prints a value to a string.  For a (const or not) char\r\n//   // pointer, the NUL-terminated string (but not the pointer) is\r\n//   // printed.\r\n//   std::string ::testing::PrintToString(const T& value);\r\n//\r\n//   // Prints a value tersely: for a reference type, the referenced\r\n//   // value (but not the address) is printed; for a (const or not) char\r\n//   // pointer, the NUL-terminated string (but not the pointer) is\r\n//   // printed.\r\n//   void ::testing::internal::UniversalTersePrint(const T& value, ostream*);\r\n//\r\n//   // Prints value using the type inferred by the compiler.  The difference\r\n//   // from UniversalTersePrint() is that this function prints both the\r\n//   // pointer and the NUL-terminated string for a (const or not) char pointer.\r\n//   void ::testing::internal::UniversalPrint(const T& value, ostream*);\r\n//\r\n//   // Prints the fields of a tuple tersely to a string vector, one\r\n//   // element for each field. Tuple support must be enabled in\r\n//   // gtest-port.h.\r\n//   std::vector<string> UniversalTersePrintTupleFieldsToStrings(\r\n//       const Tuple& value);\r\n//\r\n// Known limitation:\r\n//\r\n// The print primitives print the elements of an STL-style container\r\n// using the compiler-inferred type of *iter where iter is a\r\n// const_iterator of the container.  When const_iterator is an input\r\n// iterator but not a forward iterator, this inferred type may not\r\n// match value_type, and the print output may be incorrect.  In\r\n// practice, this is rarely a problem as for most containers\r\n// const_iterator is a forward iterator.  We'll fix this if there's an\r\n// actual need for it.  Note that this fix cannot rely on value_type\r\n// being defined as many user-defined container types don't have\r\n// value_type.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\r\n\r\n#include <ostream>  // NOLINT\r\n#include <sstream>\r\n#include <string>\r\n#include <utility>\r\n#include <vector>\r\n#include \"gtest/internal/gtest-port.h\"\r\n#include \"gtest/internal/gtest-internal.h\"\r\n\r\nnamespace testing {\r\n\r\n// Definitions in the 'internal' and 'internal2' name spaces are\r\n// subject to change without notice.  DO NOT USE THEM IN USER CODE!\r\nnamespace internal2 {\r\n\r\n// Prints the given number of bytes in the given object to the given\r\n// ostream.\r\nGTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,\r\n                                     size_t count,\r\n                                     ::std::ostream* os);\r\n\r\n// For selecting which printer to use when a given type has neither <<\r\n// nor PrintTo().\r\nenum TypeKind {\r\n  kProtobuf,              // a protobuf type\r\n  kConvertibleToInteger,  // a type implicitly convertible to BiggestInt\r\n  // (e.g. a named or unnamed enum type)\r\n  kOtherType              // anything else\r\n};\r\n\r\n// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called\r\n// by the universal printer to print a value of type T when neither\r\n// operator<< nor PrintTo() is defined for T, where kTypeKind is the\r\n// \"kind\" of T as defined by enum TypeKind.\r\ntemplate <typename T, TypeKind kTypeKind>\r\nclass TypeWithoutFormatter {\r\n public:\r\n  // This default version is called when kTypeKind is kOtherType.\r\n  static void PrintValue(const T& value, ::std::ostream* os) {\r\n    PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),\r\n                         sizeof(value), os);\r\n  }\r\n};\r\n\r\n// We print a protobuf using its ShortDebugString() when the string\r\n// doesn't exceed this many characters; otherwise we print it using\r\n// DebugString() for better readability.\r\nconst size_t kProtobufOneLinerMaxLength = 50;\r\n\r\ntemplate <typename T>\r\nclass TypeWithoutFormatter<T, kProtobuf> {\r\n public:\r\n  static void PrintValue(const T& value, ::std::ostream* os) {\r\n    const ::testing::internal::string short_str = value.ShortDebugString();\r\n    const ::testing::internal::string pretty_str =\r\n      short_str.length() <= kProtobufOneLinerMaxLength ?\r\n      short_str : (\"\\n\" + value.DebugString());\r\n    *os << (\"<\" + pretty_str + \">\");\r\n  }\r\n};\r\n\r\ntemplate <typename T>\r\nclass TypeWithoutFormatter<T, kConvertibleToInteger> {\r\n public:\r\n  // Since T has no << operator or PrintTo() but can be implicitly\r\n  // converted to BiggestInt, we print it as a BiggestInt.\r\n  //\r\n  // Most likely T is an enum type (either named or unnamed), in which\r\n  // case printing it as an integer is the desired behavior.  In case\r\n  // T is not an enum, printing it as an integer is the best we can do\r\n  // given that it has no user-defined printer.\r\n  static void PrintValue(const T& value, ::std::ostream* os) {\r\n    const internal::BiggestInt kBigInt = value;\r\n    *os << kBigInt;\r\n  }\r\n};\r\n\r\n// Prints the given value to the given ostream.  If the value is a\r\n// protocol message, its debug string is printed; if it's an enum or\r\n// of a type implicitly convertible to BiggestInt, it's printed as an\r\n// integer; otherwise the bytes in the value are printed.  This is\r\n// what UniversalPrinter<T>::Print() does when it knows nothing about\r\n// type T and T has neither << operator nor PrintTo().\r\n//\r\n// A user can override this behavior for a class type Foo by defining\r\n// a << operator in the namespace where Foo is defined.\r\n//\r\n// We put this operator in namespace 'internal2' instead of 'internal'\r\n// to simplify the implementation, as much code in 'internal' needs to\r\n// use << in STL, which would conflict with our own << were it defined\r\n// in 'internal'.\r\n//\r\n// Note that this operator<< takes a generic std::basic_ostream<Char,\r\n// CharTraits> type instead of the more restricted std::ostream.  If\r\n// we define it to take an std::ostream instead, we'll get an\r\n// \"ambiguous overloads\" compiler error when trying to print a type\r\n// Foo that supports streaming to std::basic_ostream<Char,\r\n// CharTraits>, as the compiler cannot tell whether\r\n// operator<<(std::ostream&, const T&) or\r\n// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more\r\n// specific.\r\ntemplate <typename Char, typename CharTraits, typename T>\r\n::std::basic_ostream<Char, CharTraits>& operator<<(\r\n  ::std::basic_ostream<Char, CharTraits>& os, const T& x) {\r\n  TypeWithoutFormatter < T,\r\n                       (internal::IsAProtocolMessage<T>::value ? kProtobuf :\r\n                        internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?\r\n                        kConvertibleToInteger : kOtherType) >::PrintValue(x, &os);\r\n  return os;\r\n}\r\n\r\n}  // namespace internal2\r\n}  // namespace testing\r\n\r\n// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up\r\n// magic needed for implementing UniversalPrinter won't work.\r\nnamespace testing_internal {\r\n\r\n// Used to print a value that is not an STL-style container when the\r\n// user doesn't define PrintTo() for it.\r\ntemplate <typename T>\r\nvoid DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {\r\n  // With the following statement, during unqualified name lookup,\r\n  // testing::internal2::operator<< appears as if it was declared in\r\n  // the nearest enclosing namespace that contains both\r\n  // ::testing_internal and ::testing::internal2, i.e. the global\r\n  // namespace.  For more details, refer to the C++ Standard section\r\n  // 7.3.4-1 [namespace.udir].  This allows us to fall back onto\r\n  // testing::internal2::operator<< in case T doesn't come with a <<\r\n  // operator.\r\n  //\r\n  // We cannot write 'using ::testing::internal2::operator<<;', which\r\n  // gcc 3.3 fails to compile due to a compiler bug.\r\n  using namespace ::testing::internal2;  // NOLINT\r\n\r\n  // Assuming T is defined in namespace foo, in the next statement,\r\n  // the compiler will consider all of:\r\n  //\r\n  //   1. foo::operator<< (thanks to Koenig look-up),\r\n  //   2. ::operator<< (as the current namespace is enclosed in ::),\r\n  //   3. testing::internal2::operator<< (thanks to the using statement above).\r\n  //\r\n  // The operator<< whose type matches T best will be picked.\r\n  //\r\n  // We deliberately allow #2 to be a candidate, as sometimes it's\r\n  // impossible to define #1 (e.g. when foo is ::std, defining\r\n  // anything in it is undefined behavior unless you are a compiler\r\n  // vendor.).\r\n  *os << value;\r\n}\r\n\r\n}  // namespace testing_internal\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given\r\n// value to the given ostream.  The caller must ensure that\r\n// 'ostream_ptr' is not NULL, or the behavior is undefined.\r\n//\r\n// We define UniversalPrinter as a class template (as opposed to a\r\n// function template), as we need to partially specialize it for\r\n// reference types, which cannot be done with function templates.\r\ntemplate <typename T>\r\nclass UniversalPrinter;\r\n\r\ntemplate <typename T>\r\nvoid UniversalPrint(const T& value, ::std::ostream* os);\r\n\r\n// Used to print an STL-style container when the user doesn't define\r\n// a PrintTo() for it.\r\ntemplate <typename C>\r\nvoid DefaultPrintTo(IsContainer /* dummy */,\r\n                    false_type /* is not a pointer */,\r\n                    const C& container, ::std::ostream* os) {\r\n  const size_t kMaxCount = 32;  // The maximum number of elements to print.\r\n  *os << '{';\r\n  size_t count = 0;\r\n\r\n  for (typename C::const_iterator it = container.begin();\r\n       it != container.end(); ++it, ++count) {\r\n    if (count > 0) {\r\n      *os << ',';\r\n\r\n      if (count == kMaxCount) {  // Enough has been printed.\r\n        *os << \" ...\";\r\n        break;\r\n      }\r\n    }\r\n\r\n    *os << ' ';\r\n    // We cannot call PrintTo(*it, os) here as PrintTo() doesn't\r\n    // handle *it being a native array.\r\n    internal::UniversalPrint(*it, os);\r\n  }\r\n\r\n  if (count > 0) {\r\n    *os << ' ';\r\n  }\r\n\r\n  *os << '}';\r\n}\r\n\r\n// Used to print a pointer that is neither a char pointer nor a member\r\n// pointer, when the user doesn't define PrintTo() for it.  (A member\r\n// variable pointer or member function pointer doesn't really point to\r\n// a location in the address space.  Their representation is\r\n// implementation-defined.  Therefore they will be printed as raw\r\n// bytes.)\r\ntemplate <typename T>\r\nvoid DefaultPrintTo(IsNotContainer /* dummy */,\r\n                    true_type /* is a pointer */,\r\n                    T* p, ::std::ostream* os) {\r\n  if (p == NULL) {\r\n    *os << \"NULL\";\r\n  }\r\n  else {\r\n    // C++ doesn't allow casting from a function pointer to any object\r\n    // pointer.\r\n    //\r\n    // IsTrue() silences warnings: \"Condition is always true\",\r\n    // \"unreachable code\".\r\n    if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {\r\n      // T is not a function type.  We just call << to print p,\r\n      // relying on ADL to pick up user-defined << for their pointer\r\n      // types, if any.\r\n      *os << p;\r\n    }\r\n    else {\r\n      // T is a function type, so '*os << p' doesn't do what we want\r\n      // (it just prints p as bool).  We want to print p as a const\r\n      // void*.  However, we cannot cast it to const void* directly,\r\n      // even using reinterpret_cast, as earlier versions of gcc\r\n      // (e.g. 3.4.5) cannot compile the cast when p is a function\r\n      // pointer.  Casting to UInt64 first solves the problem.\r\n      *os << reinterpret_cast<const void*>(\r\n            reinterpret_cast<internal::UInt64>(p));\r\n    }\r\n  }\r\n}\r\n\r\n// Used to print a non-container, non-pointer value when the user\r\n// doesn't define PrintTo() for it.\r\ntemplate <typename T>\r\nvoid DefaultPrintTo(IsNotContainer /* dummy */,\r\n                    false_type /* is not a pointer */,\r\n                    const T& value, ::std::ostream* os) {\r\n  ::testing_internal::DefaultPrintNonContainerTo(value, os);\r\n}\r\n\r\n// Prints the given value using the << operator if it has one;\r\n// otherwise prints the bytes in it.  This is what\r\n// UniversalPrinter<T>::Print() does when PrintTo() is not specialized\r\n// or overloaded for type T.\r\n//\r\n// A user can override this behavior for a class type Foo by defining\r\n// an overload of PrintTo() in the namespace where Foo is defined.  We\r\n// give the user this option as sometimes defining a << operator for\r\n// Foo is not desirable (e.g. the coding style may prevent doing it,\r\n// or there is already a << operator but it doesn't do what the user\r\n// wants).\r\ntemplate <typename T>\r\nvoid PrintTo(const T& value, ::std::ostream* os) {\r\n  // DefaultPrintTo() is overloaded.  The type of its first two\r\n  // arguments determine which version will be picked.  If T is an\r\n  // STL-style container, the version for container will be called; if\r\n  // T is a pointer, the pointer version will be called; otherwise the\r\n  // generic version will be called.\r\n  //\r\n  // Note that we check for container types here, prior to we check\r\n  // for protocol message types in our operator<<.  The rationale is:\r\n  //\r\n  // For protocol messages, we want to give people a chance to\r\n  // override Google Mock's format by defining a PrintTo() or\r\n  // operator<<.  For STL containers, other formats can be\r\n  // incompatible with Google Mock's format for the container\r\n  // elements; therefore we check for container types here to ensure\r\n  // that our format is used.\r\n  //\r\n  // The second argument of DefaultPrintTo() is needed to bypass a bug\r\n  // in Symbian's C++ compiler that prevents it from picking the right\r\n  // overload between:\r\n  //\r\n  //   PrintTo(const T& x, ...);\r\n  //   PrintTo(T* x, ...);\r\n  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);\r\n}\r\n\r\n// The following list of PrintTo() overloads tells\r\n// UniversalPrinter<T>::Print() how to print standard types (built-in\r\n// types, strings, plain arrays, and pointers).\r\n\r\n// Overloads for various char types.\r\nGTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);\r\nGTEST_API_ void PrintTo(signed char c, ::std::ostream* os);\r\ninline void PrintTo(char c, ::std::ostream* os) {\r\n  // When printing a plain char, we always treat it as unsigned.  This\r\n  // way, the output won't be affected by whether the compiler thinks\r\n  // char is signed or not.\r\n  PrintTo(static_cast<unsigned char>(c), os);\r\n}\r\n\r\n// Overloads for other simple built-in types.\r\ninline void PrintTo(bool x, ::std::ostream* os) {\r\n  *os << (x ? \"true\" : \"false\");\r\n}\r\n\r\n// Overload for wchar_t type.\r\n// Prints a wchar_t as a symbol if it is printable or as its internal\r\n// code otherwise and also as its decimal code (except for L'\\0').\r\n// The L'\\0' char is printed as \"L'\\\\0'\". The decimal code is printed\r\n// as signed integer when wchar_t is implemented by the compiler\r\n// as a signed type and is printed as an unsigned integer when wchar_t\r\n// is implemented as an unsigned type.\r\nGTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);\r\n\r\n// Overloads for C strings.\r\nGTEST_API_ void PrintTo(const char* s, ::std::ostream* os);\r\ninline void PrintTo(char* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const char*>(s), os);\r\n}\r\n\r\n// signed/unsigned char is often used for representing binary data, so\r\n// we print pointers to it as void* to be safe.\r\ninline void PrintTo(const signed char* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const void*>(s), os);\r\n}\r\ninline void PrintTo(signed char* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const void*>(s), os);\r\n}\r\ninline void PrintTo(const unsigned char* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const void*>(s), os);\r\n}\r\ninline void PrintTo(unsigned char* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const void*>(s), os);\r\n}\r\n\r\n// MSVC can be configured to define wchar_t as a typedef of unsigned\r\n// short.  It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native\r\n// type.  When wchar_t is a typedef, defining an overload for const\r\n// wchar_t* would cause unsigned short* be printed as a wide string,\r\n// possibly causing invalid memory accesses.\r\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\r\n// Overloads for wide C strings\r\nGTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);\r\ninline void PrintTo(wchar_t* s, ::std::ostream* os) {\r\n  PrintTo(ImplicitCast_<const wchar_t*>(s), os);\r\n}\r\n#endif\r\n\r\n// Overload for C arrays.  Multi-dimensional arrays are printed\r\n// properly.\r\n\r\n// Prints the given number of elements in an array, without printing\r\n// the curly braces.\r\ntemplate <typename T>\r\nvoid PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {\r\n  UniversalPrint(a[0], os);\r\n\r\n  for (size_t i = 1; i != count; i++) {\r\n    *os << \", \";\r\n    UniversalPrint(a[i], os);\r\n  }\r\n}\r\n\r\n// Overloads for ::string and ::std::string.\r\n#if GTEST_HAS_GLOBAL_STRING\r\nGTEST_API_ void PrintStringTo(const ::string& s, ::std::ostream* os);\r\ninline void PrintTo(const ::string& s, ::std::ostream* os) {\r\n  PrintStringTo(s, os);\r\n}\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\nGTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);\r\ninline void PrintTo(const ::std::string& s, ::std::ostream* os) {\r\n  PrintStringTo(s, os);\r\n}\r\n\r\n// Overloads for ::wstring and ::std::wstring.\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\nGTEST_API_ void PrintWideStringTo(const ::wstring& s, ::std::ostream* os);\r\ninline void PrintTo(const ::wstring& s, ::std::ostream* os) {\r\n  PrintWideStringTo(s, os);\r\n}\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\nGTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);\r\ninline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {\r\n  PrintWideStringTo(s, os);\r\n}\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\n#if GTEST_HAS_TR1_TUPLE\r\n// Overload for ::std::tr1::tuple.  Needed for printing function arguments,\r\n// which are packed as tuples.\r\n\r\n// Helper function for printing a tuple.  T must be instantiated with\r\n// a tuple type.\r\ntemplate <typename T>\r\nvoid PrintTupleTo(const T& t, ::std::ostream* os);\r\n\r\n// Overloaded PrintTo() for tuples of various arities.  We support\r\n// tuples of up-to 10 fields.  The following implementation works\r\n// regardless of whether tr1::tuple is implemented using the\r\n// non-standard variadic template feature or not.\r\n\r\ninline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1>\r\nvoid PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,\r\n             ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,\r\n             ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,\r\n             ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,\r\n             ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\nvoid PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,\r\n             ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\nvoid PrintTo(\r\n  const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,\r\n  ::std::ostream* os) {\r\n  PrintTupleTo(t, os);\r\n}\r\n#endif  // GTEST_HAS_TR1_TUPLE\r\n\r\n// Overload for std::pair.\r\ntemplate <typename T1, typename T2>\r\nvoid PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {\r\n  *os << '(';\r\n  // We cannot use UniversalPrint(value.first, os) here, as T1 may be\r\n  // a reference type.  The same for printing value.second.\r\n  UniversalPrinter<T1>::Print(value.first, os);\r\n  *os << \", \";\r\n  UniversalPrinter<T2>::Print(value.second, os);\r\n  *os << ')';\r\n}\r\n\r\n// Implements printing a non-reference type T by letting the compiler\r\n// pick the right overload of PrintTo() for T.\r\ntemplate <typename T>\r\nclass UniversalPrinter {\r\n public:\r\n  // MSVC warns about adding const to a function type, so we want to\r\n  // disable the warning.\r\n#ifdef _MSC_VER\r\n# pragma warning(push)          // Saves the current warning state.\r\n# pragma warning(disable:4180)  // Temporarily disables warning 4180.\r\n#endif  // _MSC_VER\r\n\r\n  // Note: we deliberately don't call this PrintTo(), as that name\r\n  // conflicts with ::testing::internal::PrintTo in the body of the\r\n  // function.\r\n  static void Print(const T& value, ::std::ostream* os) {\r\n    // By default, ::testing::internal::PrintTo() is used for printing\r\n    // the value.\r\n    //\r\n    // Thanks to Koenig look-up, if T is a class and has its own\r\n    // PrintTo() function defined in its namespace, that function will\r\n    // be visible here.  Since it is more specific than the generic ones\r\n    // in ::testing::internal, it will be picked by the compiler in the\r\n    // following statement - exactly what we want.\r\n    PrintTo(value, os);\r\n  }\r\n\r\n#ifdef _MSC_VER\r\n# pragma warning(pop)           // Restores the warning state.\r\n#endif  // _MSC_VER\r\n};\r\n\r\n// UniversalPrintArray(begin, len, os) prints an array of 'len'\r\n// elements, starting at address 'begin'.\r\ntemplate <typename T>\r\nvoid UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {\r\n  if (len == 0) {\r\n    *os << \"{}\";\r\n  }\r\n  else {\r\n    *os << \"{ \";\r\n    const size_t kThreshold = 18;\r\n    const size_t kChunkSize = 8;\r\n\r\n    // If the array has more than kThreshold elements, we'll have to\r\n    // omit some details by printing only the first and the last\r\n    // kChunkSize elements.\r\n    // TODO(wan@google.com): let the user control the threshold using a flag.\r\n    if (len <= kThreshold) {\r\n      PrintRawArrayTo(begin, len, os);\r\n    }\r\n    else {\r\n      PrintRawArrayTo(begin, kChunkSize, os);\r\n      *os << \", ..., \";\r\n      PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);\r\n    }\r\n\r\n    *os << \" }\";\r\n  }\r\n}\r\n// This overload prints a (const) char array compactly.\r\nGTEST_API_ void UniversalPrintArray(\r\n  const char* begin, size_t len, ::std::ostream* os);\r\n\r\n// This overload prints a (const) wchar_t array compactly.\r\nGTEST_API_ void UniversalPrintArray(\r\n  const wchar_t* begin, size_t len, ::std::ostream* os);\r\n\r\n// Implements printing an array type T[N].\r\ntemplate <typename T, size_t N>\r\nclass UniversalPrinter<T[N]> {\r\n public:\r\n  // Prints the given array, omitting some elements when there are too\r\n  // many.\r\n  static void Print(const T (&a)[N], ::std::ostream* os) {\r\n    UniversalPrintArray(a, N, os);\r\n  }\r\n};\r\n\r\n// Implements printing a reference type T&.\r\ntemplate <typename T>\r\nclass UniversalPrinter<T&> {\r\n public:\r\n  // MSVC warns about adding const to a function type, so we want to\r\n  // disable the warning.\r\n#ifdef _MSC_VER\r\n# pragma warning(push)          // Saves the current warning state.\r\n# pragma warning(disable:4180)  // Temporarily disables warning 4180.\r\n#endif  // _MSC_VER\r\n\r\n  static void Print(const T& value, ::std::ostream* os) {\r\n    // Prints the address of the value.  We use reinterpret_cast here\r\n    // as static_cast doesn't compile when T is a function type.\r\n    *os << \"@\" << reinterpret_cast<const void*>(&value) << \" \";\r\n\r\n    // Then prints the value itself.\r\n    UniversalPrint(value, os);\r\n  }\r\n\r\n#ifdef _MSC_VER\r\n# pragma warning(pop)           // Restores the warning state.\r\n#endif  // _MSC_VER\r\n};\r\n\r\n// Prints a value tersely: for a reference type, the referenced value\r\n// (but not the address) is printed; for a (const) char pointer, the\r\n// NUL-terminated string (but not the pointer) is printed.\r\n\r\ntemplate <typename T>\r\nclass UniversalTersePrinter {\r\n public:\r\n  static void Print(const T& value, ::std::ostream* os) {\r\n    UniversalPrint(value, os);\r\n  }\r\n};\r\ntemplate <typename T>\r\nclass UniversalTersePrinter<T&> {\r\n public:\r\n  static void Print(const T& value, ::std::ostream* os) {\r\n    UniversalPrint(value, os);\r\n  }\r\n};\r\ntemplate <typename T, size_t N>\r\nclass UniversalTersePrinter<T[N]> {\r\n public:\r\n  static void Print(const T (&value)[N], ::std::ostream* os) {\r\n    UniversalPrinter<T[N]>::Print(value, os);\r\n  }\r\n};\r\ntemplate <>\r\nclass UniversalTersePrinter<const char*> {\r\n public:\r\n  static void Print(const char* str, ::std::ostream* os) {\r\n    if (str == NULL) {\r\n      *os << \"NULL\";\r\n    }\r\n    else {\r\n      UniversalPrint(string(str), os);\r\n    }\r\n  }\r\n};\r\ntemplate <>\r\nclass UniversalTersePrinter<char*> {\r\n public:\r\n  static void Print(char* str, ::std::ostream* os) {\r\n    UniversalTersePrinter<const char*>::Print(str, os);\r\n  }\r\n};\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\ntemplate <>\r\nclass UniversalTersePrinter<const wchar_t*> {\r\n public:\r\n  static void Print(const wchar_t* str, ::std::ostream* os) {\r\n    if (str == NULL) {\r\n      *os << \"NULL\";\r\n    }\r\n    else {\r\n      UniversalPrint(::std::wstring(str), os);\r\n    }\r\n  }\r\n};\r\n#endif\r\n\r\ntemplate <>\r\nclass UniversalTersePrinter<wchar_t*> {\r\n public:\r\n  static void Print(wchar_t* str, ::std::ostream* os) {\r\n    UniversalTersePrinter<const wchar_t*>::Print(str, os);\r\n  }\r\n};\r\n\r\ntemplate <typename T>\r\nvoid UniversalTersePrint(const T& value, ::std::ostream* os) {\r\n  UniversalTersePrinter<T>::Print(value, os);\r\n}\r\n\r\n// Prints a value using the type inferred by the compiler.  The\r\n// difference between this and UniversalTersePrint() is that for a\r\n// (const) char pointer, this prints both the pointer and the\r\n// NUL-terminated string.\r\ntemplate <typename T>\r\nvoid UniversalPrint(const T& value, ::std::ostream* os) {\r\n  // A workarond for the bug in VC++ 7.1 that prevents us from instantiating\r\n  // UniversalPrinter with T directly.\r\n  typedef T T1;\r\n  UniversalPrinter<T1>::Print(value, os);\r\n}\r\n\r\n#if GTEST_HAS_TR1_TUPLE\r\ntypedef ::std::vector<string> Strings;\r\n\r\n// This helper template allows PrintTo() for tuples and\r\n// UniversalTersePrintTupleFieldsToStrings() to be defined by\r\n// induction on the number of tuple fields.  The idea is that\r\n// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N\r\n// fields in tuple t, and can be defined in terms of\r\n// TuplePrefixPrinter<N - 1>.\r\n\r\n// The inductive case.\r\ntemplate <size_t N>\r\nstruct TuplePrefixPrinter {\r\n  // Prints the first N fields of a tuple.\r\n  template <typename Tuple>\r\n  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {\r\n    TuplePrefixPrinter < N - 1 >::PrintPrefixTo(t, os);\r\n    *os << \", \";\r\n    UniversalPrinter < typename ::std::tr1::tuple_element < N - 1, Tuple >::type >\r\n    ::Print(::std::tr1::get < N - 1 > (t), os);\r\n  }\r\n\r\n  // Tersely prints the first N fields of a tuple to a string vector,\r\n  // one element for each field.\r\n  template <typename Tuple>\r\n  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {\r\n    TuplePrefixPrinter < N - 1 >::TersePrintPrefixToStrings(t, strings);\r\n    ::std::stringstream ss;\r\n    UniversalTersePrint(::std::tr1::get < N - 1 > (t), &ss);\r\n    strings->push_back(ss.str());\r\n  }\r\n};\r\n\r\n// Base cases.\r\ntemplate <>\r\nstruct TuplePrefixPrinter<0> {\r\n  template <typename Tuple>\r\n  static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}\r\n\r\n  template <typename Tuple>\r\n  static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}\r\n};\r\n// We have to specialize the entire TuplePrefixPrinter<> class\r\n// template here, even though the definition of\r\n// TersePrintPrefixToStrings() is the same as the generic version, as\r\n// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't\r\n// support specializing a method template of a class template.\r\ntemplate <>\r\nstruct TuplePrefixPrinter<1> {\r\n  template <typename Tuple>\r\n  static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {\r\n    UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::\r\n    Print(::std::tr1::get<0>(t), os);\r\n  }\r\n\r\n  template <typename Tuple>\r\n  static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {\r\n    ::std::stringstream ss;\r\n    UniversalTersePrint(::std::tr1::get<0>(t), &ss);\r\n    strings->push_back(ss.str());\r\n  }\r\n};\r\n\r\n// Helper function for printing a tuple.  T must be instantiated with\r\n// a tuple type.\r\ntemplate <typename T>\r\nvoid PrintTupleTo(const T& t, ::std::ostream* os) {\r\n  *os << \"(\";\r\n  TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::\r\n  PrintPrefixTo(t, os);\r\n  *os << \")\";\r\n}\r\n\r\n// Prints the fields of a tuple tersely to a string vector, one\r\n// element for each field.  See the comment before\r\n// UniversalTersePrint() for how we define \"tersely\".\r\ntemplate <typename Tuple>\r\nStrings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {\r\n  Strings result;\r\n  TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::\r\n  TersePrintPrefixToStrings(value, &result);\r\n  return result;\r\n}\r\n#endif  // GTEST_HAS_TR1_TUPLE\r\n\r\n}  // namespace internal\r\n\r\ntemplate <typename T>\r\n::std::string PrintToString(const T& value) {\r\n  ::std::stringstream ss;\r\n  internal::UniversalTersePrinter<T>::Print(value, &ss);\r\n  return ss.str();\r\n}\r\n\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-spi.h",
    "content": "// Copyright 2007, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// Utilities for testing Google Test itself and code that uses Google Test\r\n// (e.g. frameworks built on top of Google Test).\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_\r\n\r\n#include \"gtest/gtest.h\"\r\n\r\nnamespace testing {\r\n\r\n// This helper class can be used to mock out Google Test failure reporting\r\n// so that we can test Google Test or code that builds on Google Test.\r\n//\r\n// An object of this class appends a TestPartResult object to the\r\n// TestPartResultArray object given in the constructor whenever a Google Test\r\n// failure is reported. It can either intercept only failures that are\r\n// generated in the same thread that created this object or it can intercept\r\n// all generated failures. The scope of this mock object can be controlled with\r\n// the second argument to the two arguments constructor.\r\nclass GTEST_API_ ScopedFakeTestPartResultReporter\r\n  : public TestPartResultReporterInterface {\r\n public:\r\n  // The two possible mocking modes of this object.\r\n  enum InterceptMode {\r\n    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.\r\n    INTERCEPT_ALL_THREADS           // Intercepts all failures.\r\n  };\r\n\r\n  // The c'tor sets this object as the test part result reporter used\r\n  // by Google Test.  The 'result' parameter specifies where to report the\r\n  // results. This reporter will only catch failures generated in the current\r\n  // thread. DEPRECATED\r\n  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);\r\n\r\n  // Same as above, but you can choose the interception scope of this object.\r\n  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,\r\n                                   TestPartResultArray* result);\r\n\r\n  // The d'tor restores the previous test part result reporter.\r\n  virtual ~ScopedFakeTestPartResultReporter();\r\n\r\n  // Appends the TestPartResult object to the TestPartResultArray\r\n  // received in the constructor.\r\n  //\r\n  // This method is from the TestPartResultReporterInterface\r\n  // interface.\r\n  virtual void ReportTestPartResult(const TestPartResult& result);\r\n private:\r\n  void Init();\r\n\r\n  const InterceptMode intercept_mode_;\r\n  TestPartResultReporterInterface* old_reporter_;\r\n  TestPartResultArray* const result_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);\r\n};\r\n\r\nnamespace internal {\r\n\r\n// A helper class for implementing EXPECT_FATAL_FAILURE() and\r\n// EXPECT_NONFATAL_FAILURE().  Its destructor verifies that the given\r\n// TestPartResultArray contains exactly one failure that has the given\r\n// type and contains the given substring.  If that's not the case, a\r\n// non-fatal failure will be generated.\r\nclass GTEST_API_ SingleFailureChecker {\r\n public:\r\n  // The constructor remembers the arguments.\r\n  SingleFailureChecker(const TestPartResultArray* results,\r\n                       TestPartResult::Type type,\r\n                       const string& substr);\r\n  ~SingleFailureChecker();\r\n private:\r\n  const TestPartResultArray* const results_;\r\n  const TestPartResult::Type type_;\r\n  const string substr_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);\r\n};\r\n\r\n}  // namespace internal\r\n\r\n}  // namespace testing\r\n\r\n// A set of macros for testing Google Test assertions or code that's expected\r\n// to generate Google Test fatal failures.  It verifies that the given\r\n// statement will cause exactly one fatal Google Test failure with 'substr'\r\n// being part of the failure message.\r\n//\r\n// There are two different versions of this macro. EXPECT_FATAL_FAILURE only\r\n// affects and considers failures generated in the current thread and\r\n// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\r\n//\r\n// The verification of the assertion is done correctly even when the statement\r\n// throws an exception or aborts the current function.\r\n//\r\n// Known restrictions:\r\n//   - 'statement' cannot reference local non-static variables or\r\n//     non-static members of the current object.\r\n//   - 'statement' cannot return a value.\r\n//   - You cannot stream a failure message to this macro.\r\n//\r\n// Note that even though the implementations of the following two\r\n// macros are much alike, we cannot refactor them to use a common\r\n// helper macro, due to some peculiarity in how the preprocessor\r\n// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in\r\n// gtest_unittest.cc will fail to compile if we do that.\r\n#define EXPECT_FATAL_FAILURE(statement, substr) \\\r\n  do { \\\r\n    class GTestExpectFatalFailureHelper {\\\r\n     public:\\\r\n      static void Execute() { statement; }\\\r\n    };\\\r\n    ::testing::TestPartResultArray gtest_failures;\\\r\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\r\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\\\r\n    {\\\r\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\r\n          ::testing::ScopedFakeTestPartResultReporter:: \\\r\n          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\\\r\n      GTestExpectFatalFailureHelper::Execute();\\\r\n    }\\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \\\r\n  do { \\\r\n    class GTestExpectFatalFailureHelper {\\\r\n     public:\\\r\n      static void Execute() { statement; }\\\r\n    };\\\r\n    ::testing::TestPartResultArray gtest_failures;\\\r\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\r\n        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\\\r\n    {\\\r\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\r\n          ::testing::ScopedFakeTestPartResultReporter:: \\\r\n          INTERCEPT_ALL_THREADS, &gtest_failures);\\\r\n      GTestExpectFatalFailureHelper::Execute();\\\r\n    }\\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n// A macro for testing Google Test assertions or code that's expected to\r\n// generate Google Test non-fatal failures.  It asserts that the given\r\n// statement will cause exactly one non-fatal Google Test failure with 'substr'\r\n// being part of the failure message.\r\n//\r\n// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only\r\n// affects and considers failures generated in the current thread and\r\n// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.\r\n//\r\n// 'statement' is allowed to reference local variables and members of\r\n// the current object.\r\n//\r\n// The verification of the assertion is done correctly even when the statement\r\n// throws an exception or aborts the current function.\r\n//\r\n// Known restrictions:\r\n//   - You cannot stream a failure message to this macro.\r\n//\r\n// Note that even though the implementations of the following two\r\n// macros are much alike, we cannot refactor them to use a common\r\n// helper macro, due to some peculiarity in how the preprocessor\r\n// works.  If we do that, the code won't compile when the user gives\r\n// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that\r\n// expands to code containing an unprotected comma.  The\r\n// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc\r\n// catches that.\r\n//\r\n// For the same reason, we have to write\r\n//   if (::testing::internal::AlwaysTrue()) { statement; }\r\n// instead of\r\n//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\r\n// to avoid an MSVC warning on unreachable code.\r\n#define EXPECT_NONFATAL_FAILURE(statement, substr) \\\r\n  do {\\\r\n    ::testing::TestPartResultArray gtest_failures;\\\r\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\r\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\r\n        (substr));\\\r\n    {\\\r\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\r\n          ::testing::ScopedFakeTestPartResultReporter:: \\\r\n          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\\\r\n      if (::testing::internal::AlwaysTrue()) { statement; }\\\r\n    }\\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \\\r\n  do {\\\r\n    ::testing::TestPartResultArray gtest_failures;\\\r\n    ::testing::internal::SingleFailureChecker gtest_checker(\\\r\n        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \\\r\n        (substr));\\\r\n    {\\\r\n      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\\\r\n          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \\\r\n          &gtest_failures);\\\r\n      if (::testing::internal::AlwaysTrue()) { statement; }\\\r\n    }\\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-test-part.h",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: mheule@google.com (Markus Heule)\r\n//\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\r\n\r\n#include <iosfwd>\r\n#include <vector>\r\n#include \"gtest/internal/gtest-internal.h\"\r\n#include \"gtest/internal/gtest-string.h\"\r\n\r\nnamespace testing {\r\n\r\n// A copyable object representing the result of a test part (i.e. an\r\n// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).\r\n//\r\n// Don't inherit from TestPartResult as its destructor is not virtual.\r\nclass GTEST_API_ TestPartResult {\r\n public:\r\n  // The possible outcomes of a test part (i.e. an assertion or an\r\n  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).\r\n  enum Type {\r\n    kSuccess,          // Succeeded.\r\n    kNonFatalFailure,  // Failed but the test can continue.\r\n    kFatalFailure      // Failed and the test should be terminated.\r\n  };\r\n\r\n  // C'tor.  TestPartResult does NOT have a default constructor.\r\n  // Always use this constructor (with parameters) to create a\r\n  // TestPartResult object.\r\n  TestPartResult(Type a_type,\r\n                 const char* a_file_name,\r\n                 int a_line_number,\r\n                 const char* a_message)\r\n    : type_(a_type),\r\n      file_name_(a_file_name == NULL ? \"\" : a_file_name),\r\n      line_number_(a_line_number),\r\n      summary_(ExtractSummary(a_message)),\r\n      message_(a_message) {\r\n  }\r\n\r\n  // Gets the outcome of the test part.\r\n  Type type() const {\r\n    return type_;\r\n  }\r\n\r\n  // Gets the name of the source file where the test part took place, or\r\n  // NULL if it's unknown.\r\n  const char* file_name() const {\r\n    return file_name_.empty() ? NULL : file_name_.c_str();\r\n  }\r\n\r\n  // Gets the line in the source file where the test part took place,\r\n  // or -1 if it's unknown.\r\n  int line_number() const {\r\n    return line_number_;\r\n  }\r\n\r\n  // Gets the summary of the failure message.\r\n  const char* summary() const {\r\n    return summary_.c_str();\r\n  }\r\n\r\n  // Gets the message associated with the test part.\r\n  const char* message() const {\r\n    return message_.c_str();\r\n  }\r\n\r\n  // Returns true iff the test part passed.\r\n  bool passed() const {\r\n    return type_ == kSuccess;\r\n  }\r\n\r\n  // Returns true iff the test part failed.\r\n  bool failed() const {\r\n    return type_ != kSuccess;\r\n  }\r\n\r\n  // Returns true iff the test part non-fatally failed.\r\n  bool nonfatally_failed() const {\r\n    return type_ == kNonFatalFailure;\r\n  }\r\n\r\n  // Returns true iff the test part fatally failed.\r\n  bool fatally_failed() const {\r\n    return type_ == kFatalFailure;\r\n  }\r\n\r\n private:\r\n  Type type_;\r\n\r\n  // Gets the summary of the failure message by omitting the stack\r\n  // trace in it.\r\n  static std::string ExtractSummary(const char* message);\r\n\r\n  // The name of the source file where the test part took place, or\r\n  // \"\" if the source file is unknown.\r\n  std::string file_name_;\r\n  // The line in the source file where the test part took place, or -1\r\n  // if the line number is unknown.\r\n  int line_number_;\r\n  std::string summary_;  // The test failure summary.\r\n  std::string message_;  // The test failure message.\r\n};\r\n\r\n// Prints a TestPartResult object.\r\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result);\r\n\r\n// An array of TestPartResult objects.\r\n//\r\n// Don't inherit from TestPartResultArray as its destructor is not\r\n// virtual.\r\nclass GTEST_API_ TestPartResultArray {\r\n public:\r\n  TestPartResultArray() {}\r\n\r\n  // Appends the given TestPartResult to the array.\r\n  void Append(const TestPartResult& result);\r\n\r\n  // Returns the TestPartResult at the given index (0-based).\r\n  const TestPartResult& GetTestPartResult(int index) const;\r\n\r\n  // Returns the number of TestPartResult objects in the array.\r\n  int size() const;\r\n\r\n private:\r\n  std::vector<TestPartResult> array_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);\r\n};\r\n\r\n// This interface knows how to report a test part result.\r\nclass TestPartResultReporterInterface {\r\n public:\r\n  virtual ~TestPartResultReporterInterface() {}\r\n\r\n  virtual void ReportTestPartResult(const TestPartResult& result) = 0;\r\n};\r\n\r\nnamespace internal {\r\n\r\n// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a\r\n// statement generates new fatal failures. To do so it registers itself as the\r\n// current test part result reporter. Besides checking if fatal failures were\r\n// reported, it only delegates the reporting to the former result reporter.\r\n// The original result reporter is restored in the destructor.\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nclass GTEST_API_ HasNewFatalFailureHelper\r\n  : public TestPartResultReporterInterface {\r\n public:\r\n  HasNewFatalFailureHelper();\r\n  virtual ~HasNewFatalFailureHelper();\r\n  virtual void ReportTestPartResult(const TestPartResult& result);\r\n  bool has_new_fatal_failure() const {\r\n    return has_new_fatal_failure_;\r\n  }\r\n private:\r\n  bool has_new_fatal_failure_;\r\n  TestPartResultReporterInterface* original_reporter_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);\r\n};\r\n\r\n}  // namespace internal\r\n\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest-typed-test.h",
    "content": "// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\r\n\r\n// This header implements typed tests and type-parameterized tests.\r\n\r\n// Typed (aka type-driven) tests repeat the same test for types in a\r\n// list.  You must know which types you want to test with when writing\r\n// typed tests. Here's how you do it:\r\n\r\n#if 0\r\n\r\n// First, define a fixture class template.  It should be parameterized\r\n// by a type.  Remember to derive it from testing::Test.\r\ntemplate <typename T>\r\nclass FooTest : public testing::Test {\r\n public:\r\n  ...\r\n  typedef std::list<T> List;\r\n  static T shared_;\r\n  T value_;\r\n};\r\n\r\n// Next, associate a list of types with the test case, which will be\r\n// repeated for each type in the list.  The typedef is necessary for\r\n// the macro to parse correctly.\r\ntypedef testing::Types<char, int, unsigned int> MyTypes;\r\nTYPED_TEST_CASE(FooTest, MyTypes);\r\n\r\n// If the type list contains only one type, you can write that type\r\n// directly without Types<...>:\r\n//   TYPED_TEST_CASE(FooTest, int);\r\n\r\n// Then, use TYPED_TEST() instead of TEST_F() to define as many typed\r\n// tests for this test case as you want.\r\nTYPED_TEST(FooTest, DoesBlah) {\r\n  // Inside a test, refer to TypeParam to get the type parameter.\r\n  // Since we are inside a derived class template, C++ requires use to\r\n  // visit the members of FooTest via 'this'.\r\n  TypeParam n = this->value_;\r\n\r\n  // To visit static members of the fixture, add the TestFixture::\r\n  // prefix.\r\n  n += TestFixture::shared_;\r\n\r\n  // To refer to typedefs in the fixture, add the \"typename\r\n  // TestFixture::\" prefix.\r\n  typename TestFixture::List values;\r\n  values.push_back(n);\r\n  ...\r\n}\r\n\r\nTYPED_TEST(FooTest, HasPropertyA) {\r\n  ...\r\n}\r\n\r\n#endif  // 0\r\n\r\n// Type-parameterized tests are abstract test patterns parameterized\r\n// by a type.  Compared with typed tests, type-parameterized tests\r\n// allow you to define the test pattern without knowing what the type\r\n// parameters are.  The defined pattern can be instantiated with\r\n// different types any number of times, in any number of translation\r\n// units.\r\n//\r\n// If you are designing an interface or concept, you can define a\r\n// suite of type-parameterized tests to verify properties that any\r\n// valid implementation of the interface/concept should have.  Then,\r\n// each implementation can easily instantiate the test suite to verify\r\n// that it conforms to the requirements, without having to write\r\n// similar tests repeatedly.  Here's an example:\r\n\r\n#if 0\r\n\r\n// First, define a fixture class template.  It should be parameterized\r\n// by a type.  Remember to derive it from testing::Test.\r\ntemplate <typename T>\r\nclass FooTest : public testing::Test {\r\n  ...\r\n};\r\n\r\n// Next, declare that you will define a type-parameterized test case\r\n// (the _P suffix is for \"parameterized\" or \"pattern\", whichever you\r\n// prefer):\r\nTYPED_TEST_CASE_P(FooTest);\r\n\r\n// Then, use TYPED_TEST_P() to define as many type-parameterized tests\r\n// for this type-parameterized test case as you want.\r\nTYPED_TEST_P(FooTest, DoesBlah) {\r\n  // Inside a test, refer to TypeParam to get the type parameter.\r\n  TypeParam n = 0;\r\n  ...\r\n}\r\n\r\nTYPED_TEST_P(FooTest, HasPropertyA) {\r\n  ...\r\n}\r\n\r\n// Now the tricky part: you need to register all test patterns before\r\n// you can instantiate them.  The first argument of the macro is the\r\n// test case name; the rest are the names of the tests in this test\r\n// case.\r\nREGISTER_TYPED_TEST_CASE_P(FooTest,\r\n                           DoesBlah, HasPropertyA);\r\n\r\n// Finally, you are free to instantiate the pattern with the types you\r\n// want.  If you put the above code in a header file, you can #include\r\n// it in multiple C++ source files and instantiate it multiple times.\r\n//\r\n// To distinguish different instances of the pattern, the first\r\n// argument to the INSTANTIATE_* macro is a prefix that will be added\r\n// to the actual test case name.  Remember to pick unique prefixes for\r\n// different instances.\r\ntypedef testing::Types<char, int, unsigned int> MyTypes;\r\nINSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);\r\n\r\n// If the type list contains only one type, you can write that type\r\n// directly without Types<...>:\r\n//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);\r\n\r\n#endif  // 0\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n#include \"gtest/internal/gtest-type-util.h\"\r\n\r\n// Implements typed tests.\r\n\r\n#if GTEST_HAS_TYPED_TEST\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Expands to the name of the typedef for the type parameters of the\r\n// given test case.\r\n# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_\r\n\r\n// The 'Types' template argument below must have spaces around it\r\n// since some compilers may choke on '>>' when passing a template\r\n// instance (e.g. Types<int>)\r\n# define TYPED_TEST_CASE(CaseName, Types) \\\r\n  typedef ::testing::internal::TypeList< Types >::type \\\r\n      GTEST_TYPE_PARAMS_(CaseName)\r\n\r\n# define TYPED_TEST(CaseName, TestName) \\\r\n  template <typename gtest_TypeParam_> \\\r\n  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \\\r\n      : public CaseName<gtest_TypeParam_> { \\\r\n   private: \\\r\n    typedef CaseName<gtest_TypeParam_> TestFixture; \\\r\n    typedef gtest_TypeParam_ TypeParam; \\\r\n    virtual void TestBody(); \\\r\n  }; \\\r\n  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \\\r\n      ::testing::internal::TypeParameterizedTest< \\\r\n          CaseName, \\\r\n          ::testing::internal::TemplateSel< \\\r\n              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \\\r\n          GTEST_TYPE_PARAMS_(CaseName)>::Register(\\\r\n              \"\", #CaseName, #TestName, 0); \\\r\n  template <typename gtest_TypeParam_> \\\r\n  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST\r\n\r\n// Implements type-parameterized tests.\r\n\r\n#if GTEST_HAS_TYPED_TEST_P\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Expands to the namespace name that the type-parameterized tests for\r\n// the given type-parameterized test case are defined in.  The exact\r\n// name of the namespace is subject to change without notice.\r\n# define GTEST_CASE_NAMESPACE_(TestCaseName) \\\r\n  gtest_case_##TestCaseName##_\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Expands to the name of the variable used to remember the names of\r\n// the defined tests in the given test case.\r\n# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \\\r\n  gtest_typed_test_case_p_state_##TestCaseName##_\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.\r\n//\r\n// Expands to the name of the variable used to remember the names of\r\n// the registered tests in the given test case.\r\n# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \\\r\n  gtest_registered_test_names_##TestCaseName##_\r\n\r\n// The variables defined in the type-parameterized test macros are\r\n// static as typically these macros are used in a .h file that can be\r\n// #included in multiple translation units linked together.\r\n# define TYPED_TEST_CASE_P(CaseName) \\\r\n  static ::testing::internal::TypedTestCasePState \\\r\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)\r\n\r\n# define TYPED_TEST_P(CaseName, TestName) \\\r\n  namespace GTEST_CASE_NAMESPACE_(CaseName) { \\\r\n  template <typename gtest_TypeParam_> \\\r\n  class TestName : public CaseName<gtest_TypeParam_> { \\\r\n   private: \\\r\n    typedef CaseName<gtest_TypeParam_> TestFixture; \\\r\n    typedef gtest_TypeParam_ TypeParam; \\\r\n    virtual void TestBody(); \\\r\n  }; \\\r\n  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \\\r\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\\\r\n          __FILE__, __LINE__, #CaseName, #TestName); \\\r\n  } \\\r\n  template <typename gtest_TypeParam_> \\\r\n  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()\r\n\r\n# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \\\r\n  namespace GTEST_CASE_NAMESPACE_(CaseName) { \\\r\n  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \\\r\n  } \\\r\n  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \\\r\n      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\\\r\n          __FILE__, __LINE__, #__VA_ARGS__)\r\n\r\n// The 'Types' template argument below must have spaces around it\r\n// since some compilers may choke on '>>' when passing a template\r\n// instance (e.g. Types<int>)\r\n# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \\\r\n  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \\\r\n      ::testing::internal::TypeParameterizedTestCase<CaseName, \\\r\n          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \\\r\n          ::testing::internal::TypeList< Types >::type>::Register(\\\r\n              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST_P\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file defines the public API for Google Test.  It should be\r\n// included by any test program that uses Google Test.\r\n//\r\n// IMPORTANT NOTE: Due to limitation of the C++ language, we have to\r\n// leave some internal implementation details in this header file.\r\n// They are clearly marked by comments like this:\r\n//\r\n//   // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n//\r\n// Such code is NOT meant to be used by a user directly, and is subject\r\n// to CHANGE WITHOUT NOTICE.  Therefore DO NOT DEPEND ON IT in a user\r\n// program!\r\n//\r\n// Acknowledgment: Google Test borrowed the idea of automatic test\r\n// registration from Barthelemy Dagenais' (barthelemy@prologique.com)\r\n// easyUnit framework.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_H_\r\n\r\n#include <limits>\r\n#include <ostream>\r\n#include <vector>\r\n\r\n#include \"gtest/internal/gtest-internal.h\"\r\n#include \"gtest/internal/gtest-string.h\"\r\n#include \"gtest/gtest-death-test.h\"\r\n#include \"gtest/gtest-message.h\"\r\n#include \"gtest/gtest-param-test.h\"\r\n#include \"gtest/gtest-printers.h\"\r\n#include \"gtest/gtest_prod.h\"\r\n#include \"gtest/gtest-test-part.h\"\r\n#include \"gtest/gtest-typed-test.h\"\r\n\r\n// Depending on the platform, different string classes are available.\r\n// On Linux, in addition to ::std::string, Google also makes use of\r\n// class ::string, which has the same interface as ::std::string, but\r\n// has a different implementation.\r\n//\r\n// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that\r\n// ::string is available AND is a distinct type to ::std::string, or\r\n// define it to 0 to indicate otherwise.\r\n//\r\n// If the user's ::std::string and ::string are the same class due to\r\n// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0.\r\n//\r\n// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined\r\n// heuristically.\r\n\r\nnamespace testing {\r\n\r\n// Declares the flags.\r\n\r\n// This flag temporary enables the disabled tests.\r\nGTEST_DECLARE_bool_(also_run_disabled_tests);\r\n\r\n// This flag brings the debugger on an assertion failure.\r\nGTEST_DECLARE_bool_(break_on_failure);\r\n\r\n// This flag controls whether Google Test catches all test-thrown exceptions\r\n// and logs them as failures.\r\nGTEST_DECLARE_bool_(catch_exceptions);\r\n\r\n// This flag enables using colors in terminal output. Available values are\r\n// \"yes\" to enable colors, \"no\" (disable colors), or \"auto\" (the default)\r\n// to let Google Test decide.\r\nGTEST_DECLARE_string_(color);\r\n\r\n// This flag sets up the filter to select by name using a glob pattern\r\n// the tests to run. If the filter is not given all tests are executed.\r\nGTEST_DECLARE_string_(filter);\r\n\r\n// This flag causes the Google Test to list tests. None of the tests listed\r\n// are actually run if the flag is provided.\r\nGTEST_DECLARE_bool_(list_tests);\r\n\r\n// This flag controls whether Google Test emits a detailed XML report to a file\r\n// in addition to its normal textual output.\r\nGTEST_DECLARE_string_(output);\r\n\r\n// This flags control whether Google Test prints the elapsed time for each\r\n// test.\r\nGTEST_DECLARE_bool_(print_time);\r\n\r\n// This flag specifies the random number seed.\r\nGTEST_DECLARE_int32_(random_seed);\r\n\r\n// This flag sets how many times the tests are repeated. The default value\r\n// is 1. If the value is -1 the tests are repeating forever.\r\nGTEST_DECLARE_int32_(repeat);\r\n\r\n// This flag controls whether Google Test includes Google Test internal\r\n// stack frames in failure stack traces.\r\nGTEST_DECLARE_bool_(show_internal_stack_frames);\r\n\r\n// When this flag is specified, tests' order is randomized on every iteration.\r\nGTEST_DECLARE_bool_(shuffle);\r\n\r\n// This flag specifies the maximum number of stack frames to be\r\n// printed in a failure message.\r\nGTEST_DECLARE_int32_(stack_trace_depth);\r\n\r\n// When this flag is specified, a failed assertion will throw an\r\n// exception if exceptions are enabled, or exit the program with a\r\n// non-zero code otherwise.\r\nGTEST_DECLARE_bool_(throw_on_failure);\r\n\r\n// When this flag is set with a \"host:port\" string, on supported\r\n// platforms test results are streamed to the specified port on\r\n// the specified host machine.\r\nGTEST_DECLARE_string_(stream_result_to);\r\n\r\n// The upper limit for valid stack trace depths.\r\nconst int kMaxStackTraceDepth = 100;\r\n\r\nnamespace internal {\r\n\r\nclass AssertHelper;\r\nclass DefaultGlobalTestPartResultReporter;\r\nclass ExecDeathTest;\r\nclass NoExecDeathTest;\r\nclass FinalSuccessChecker;\r\nclass GTestFlagSaver;\r\nclass StreamingListenerTest;\r\nclass TestResultAccessor;\r\nclass TestEventListenersAccessor;\r\nclass TestEventRepeater;\r\nclass UnitTestRecordPropertyTestHelper;\r\nclass WindowsDeathTest;\r\nclass UnitTestImpl* GetUnitTestImpl();\r\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\r\n                                    const std::string& message);\r\n\r\n}  // namespace internal\r\n\r\n// The friend relationship of some of these classes is cyclic.\r\n// If we don't forward declare them the compiler might confuse the classes\r\n// in friendship clauses with same named classes on the scope.\r\nclass Test;\r\nclass TestCase;\r\nclass TestInfo;\r\nclass UnitTest;\r\n\r\n// A class for indicating whether an assertion was successful.  When\r\n// the assertion wasn't successful, the AssertionResult object\r\n// remembers a non-empty message that describes how it failed.\r\n//\r\n// To create an instance of this class, use one of the factory functions\r\n// (AssertionSuccess() and AssertionFailure()).\r\n//\r\n// This class is useful for two purposes:\r\n//   1. Defining predicate functions to be used with Boolean test assertions\r\n//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts\r\n//   2. Defining predicate-format functions to be\r\n//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).\r\n//\r\n// For example, if you define IsEven predicate:\r\n//\r\n//   testing::AssertionResult IsEven(int n) {\r\n//     if ((n % 2) == 0)\r\n//       return testing::AssertionSuccess();\r\n//     else\r\n//       return testing::AssertionFailure() << n << \" is odd\";\r\n//   }\r\n//\r\n// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))\r\n// will print the message\r\n//\r\n//   Value of: IsEven(Fib(5))\r\n//     Actual: false (5 is odd)\r\n//   Expected: true\r\n//\r\n// instead of a more opaque\r\n//\r\n//   Value of: IsEven(Fib(5))\r\n//     Actual: false\r\n//   Expected: true\r\n//\r\n// in case IsEven is a simple Boolean predicate.\r\n//\r\n// If you expect your predicate to be reused and want to support informative\r\n// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up\r\n// about half as often as positive ones in our tests), supply messages for\r\n// both success and failure cases:\r\n//\r\n//   testing::AssertionResult IsEven(int n) {\r\n//     if ((n % 2) == 0)\r\n//       return testing::AssertionSuccess() << n << \" is even\";\r\n//     else\r\n//       return testing::AssertionFailure() << n << \" is odd\";\r\n//   }\r\n//\r\n// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print\r\n//\r\n//   Value of: IsEven(Fib(6))\r\n//     Actual: true (8 is even)\r\n//   Expected: false\r\n//\r\n// NB: Predicates that support negative Boolean assertions have reduced\r\n// performance in positive ones so be careful not to use them in tests\r\n// that have lots (tens of thousands) of positive Boolean assertions.\r\n//\r\n// To use this class with EXPECT_PRED_FORMAT assertions such as:\r\n//\r\n//   // Verifies that Foo() returns an even number.\r\n//   EXPECT_PRED_FORMAT1(IsEven, Foo());\r\n//\r\n// you need to define:\r\n//\r\n//   testing::AssertionResult IsEven(const char* expr, int n) {\r\n//     if ((n % 2) == 0)\r\n//       return testing::AssertionSuccess();\r\n//     else\r\n//       return testing::AssertionFailure()\r\n//         << \"Expected: \" << expr << \" is even\\n  Actual: it's \" << n;\r\n//   }\r\n//\r\n// If Foo() returns 5, you will see the following message:\r\n//\r\n//   Expected: Foo() is even\r\n//     Actual: it's 5\r\n//\r\nclass GTEST_API_ AssertionResult {\r\n public:\r\n  // Copy constructor.\r\n  // Used in EXPECT_TRUE/FALSE(assertion_result).\r\n  AssertionResult(const AssertionResult& other);\r\n  // Used in the EXPECT_TRUE/FALSE(bool_expression).\r\n  explicit AssertionResult(bool success) : success_(success) {}\r\n\r\n  // Returns true iff the assertion succeeded.\r\n  operator bool() const {\r\n    return success_;  // NOLINT\r\n  }\r\n\r\n  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\r\n  AssertionResult operator!() const;\r\n\r\n  // Returns the text streamed into this AssertionResult. Test assertions\r\n  // use it when they fail (i.e., the predicate's outcome doesn't match the\r\n  // assertion's expectation). When nothing has been streamed into the\r\n  // object, returns an empty string.\r\n  const char* message() const {\r\n    return message_.get() != NULL ?  message_->c_str() : \"\";\r\n  }\r\n  // TODO(vladl@google.com): Remove this after making sure no clients use it.\r\n  // Deprecated; please use message() instead.\r\n  const char* failure_message() const {\r\n    return message();\r\n  }\r\n\r\n  // Streams a custom failure message into this object.\r\n  template <typename T> AssertionResult& operator<<(const T& value) {\r\n    AppendMessage(Message() << value);\r\n    return *this;\r\n  }\r\n\r\n  // Allows streaming basic output manipulators such as endl or flush into\r\n  // this object.\r\n  AssertionResult& operator<<(\r\n    ::std::ostream & (*basic_manipulator)(::std::ostream& stream)) {\r\n    AppendMessage(Message() << basic_manipulator);\r\n    return *this;\r\n  }\r\n\r\n private:\r\n  // Appends the contents of message to message_.\r\n  void AppendMessage(const Message& a_message) {\r\n    if (message_.get() == NULL) {\r\n      message_.reset(new ::std::string);\r\n    }\r\n\r\n    message_->append(a_message.GetString().c_str());\r\n  }\r\n\r\n  // Stores result of the assertion predicate.\r\n  bool success_;\r\n  // Stores the message describing the condition in case the expectation\r\n  // construct is not satisfied with the predicate's outcome.\r\n  // Referenced via a pointer to avoid taking too much stack frame space\r\n  // with test assertions.\r\n  internal::scoped_ptr< ::std::string> message_;\r\n\r\n  GTEST_DISALLOW_ASSIGN_(AssertionResult);\r\n};\r\n\r\n// Makes a successful assertion result.\r\nGTEST_API_ AssertionResult AssertionSuccess();\r\n\r\n// Makes a failed assertion result.\r\nGTEST_API_ AssertionResult AssertionFailure();\r\n\r\n// Makes a failed assertion result with the given failure message.\r\n// Deprecated; use AssertionFailure() << msg.\r\nGTEST_API_ AssertionResult AssertionFailure(const Message& msg);\r\n\r\n// The abstract class that all tests inherit from.\r\n//\r\n// In Google Test, a unit test program contains one or many TestCases, and\r\n// each TestCase contains one or many Tests.\r\n//\r\n// When you define a test using the TEST macro, you don't need to\r\n// explicitly derive from Test - the TEST macro automatically does\r\n// this for you.\r\n//\r\n// The only time you derive from Test is when defining a test fixture\r\n// to be used a TEST_F.  For example:\r\n//\r\n//   class FooTest : public testing::Test {\r\n//    protected:\r\n//     virtual void SetUp() { ... }\r\n//     virtual void TearDown() { ... }\r\n//     ...\r\n//   };\r\n//\r\n//   TEST_F(FooTest, Bar) { ... }\r\n//   TEST_F(FooTest, Baz) { ... }\r\n//\r\n// Test is not copyable.\r\nclass GTEST_API_ Test {\r\n public:\r\n  friend class TestInfo;\r\n\r\n  // Defines types for pointers to functions that set up and tear down\r\n  // a test case.\r\n  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;\r\n  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;\r\n\r\n  // The d'tor is virtual as we intend to inherit from Test.\r\n  virtual ~Test();\r\n\r\n  // Sets up the stuff shared by all tests in this test case.\r\n  //\r\n  // Google Test will call Foo::SetUpTestCase() before running the first\r\n  // test in test case Foo.  Hence a sub-class can define its own\r\n  // SetUpTestCase() method to shadow the one defined in the super\r\n  // class.\r\n  static void SetUpTestCase() {}\r\n\r\n  // Tears down the stuff shared by all tests in this test case.\r\n  //\r\n  // Google Test will call Foo::TearDownTestCase() after running the last\r\n  // test in test case Foo.  Hence a sub-class can define its own\r\n  // TearDownTestCase() method to shadow the one defined in the super\r\n  // class.\r\n  static void TearDownTestCase() {}\r\n\r\n  // Returns true iff the current test has a fatal failure.\r\n  static bool HasFatalFailure();\r\n\r\n  // Returns true iff the current test has a non-fatal failure.\r\n  static bool HasNonfatalFailure();\r\n\r\n  // Returns true iff the current test has a (either fatal or\r\n  // non-fatal) failure.\r\n  static bool HasFailure() {\r\n    return HasFatalFailure() || HasNonfatalFailure();\r\n  }\r\n\r\n  // Logs a property for the current test, test case, or for the entire\r\n  // invocation of the test program when used outside of the context of a\r\n  // test case.  Only the last value for a given key is remembered.  These\r\n  // are public static so they can be called from utility functions that are\r\n  // not members of the test fixture.  Calls to RecordProperty made during\r\n  // lifespan of the test (from the moment its constructor starts to the\r\n  // moment its destructor finishes) will be output in XML as attributes of\r\n  // the <testcase> element.  Properties recorded from fixture's\r\n  // SetUpTestCase or TearDownTestCase are logged as attributes of the\r\n  // corresponding <testsuite> element.  Calls to RecordProperty made in the\r\n  // global context (before or after invocation of RUN_ALL_TESTS and from\r\n  // SetUp/TearDown method of Environment objects registered with Google\r\n  // Test) will be output as attributes of the <testsuites> element.\r\n  static void RecordProperty(const std::string& key, const std::string& value);\r\n  static void RecordProperty(const std::string& key, int value);\r\n\r\n protected:\r\n  // Creates a Test object.\r\n  Test();\r\n\r\n  // Sets up the test fixture.\r\n  virtual void SetUp();\r\n\r\n  // Tears down the test fixture.\r\n  virtual void TearDown();\r\n\r\n private:\r\n  // Returns true iff the current test has the same fixture class as\r\n  // the first test in the current test case.\r\n  static bool HasSameFixtureClass();\r\n\r\n  // Runs the test after the test fixture has been set up.\r\n  //\r\n  // A sub-class must implement this to define the test logic.\r\n  //\r\n  // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM.\r\n  // Instead, use the TEST or TEST_F macro.\r\n  virtual void TestBody() = 0;\r\n\r\n  // Sets up, executes, and tears down the test.\r\n  void Run();\r\n\r\n  // Deletes self.  We deliberately pick an unusual name for this\r\n  // internal method to avoid clashing with names used in user TESTs.\r\n  void DeleteSelf_() {\r\n    delete this;\r\n  }\r\n\r\n  // Uses a GTestFlagSaver to save and restore all Google Test flags.\r\n  const internal::GTestFlagSaver* const gtest_flag_saver_;\r\n\r\n  // Often a user mis-spells SetUp() as Setup() and spends a long time\r\n  // wondering why it is never called by Google Test.  The declaration of\r\n  // the following method is solely for catching such an error at\r\n  // compile time:\r\n  //\r\n  //   - The return type is deliberately chosen to be not void, so it\r\n  //   will be a conflict if a user declares void Setup() in his test\r\n  //   fixture.\r\n  //\r\n  //   - This method is private, so it will be another compiler error\r\n  //   if a user calls it from his test fixture.\r\n  //\r\n  // DO NOT OVERRIDE THIS FUNCTION.\r\n  //\r\n  // If you see an error about overriding the following function or\r\n  // about it being private, you have mis-spelled SetUp() as Setup().\r\n  struct Setup_should_be_spelled_SetUp {};\r\n  virtual Setup_should_be_spelled_SetUp* Setup() {\r\n    return NULL;\r\n  }\r\n\r\n  // We disallow copying Tests.\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);\r\n};\r\n\r\ntypedef internal::TimeInMillis TimeInMillis;\r\n\r\n// A copyable object representing a user specified test property which can be\r\n// output as a key/value string pair.\r\n//\r\n// Don't inherit from TestProperty as its destructor is not virtual.\r\nclass TestProperty {\r\n public:\r\n  // C'tor.  TestProperty does NOT have a default constructor.\r\n  // Always use this constructor (with parameters) to create a\r\n  // TestProperty object.\r\n  TestProperty(const std::string& a_key, const std::string& a_value) :\r\n    key_(a_key), value_(a_value) {\r\n  }\r\n\r\n  // Gets the user supplied key.\r\n  const char* key() const {\r\n    return key_.c_str();\r\n  }\r\n\r\n  // Gets the user supplied value.\r\n  const char* value() const {\r\n    return value_.c_str();\r\n  }\r\n\r\n  // Sets a new value, overriding the one supplied in the constructor.\r\n  void SetValue(const std::string& new_value) {\r\n    value_ = new_value;\r\n  }\r\n\r\n private:\r\n  // The key supplied by the user.\r\n  std::string key_;\r\n  // The value supplied by the user.\r\n  std::string value_;\r\n};\r\n\r\n// The result of a single Test.  This includes a list of\r\n// TestPartResults, a list of TestProperties, a count of how many\r\n// death tests there are in the Test, and how much time it took to run\r\n// the Test.\r\n//\r\n// TestResult is not copyable.\r\nclass GTEST_API_ TestResult {\r\n public:\r\n  // Creates an empty TestResult.\r\n  TestResult();\r\n\r\n  // D'tor.  Do not inherit from TestResult.\r\n  ~TestResult();\r\n\r\n  // Gets the number of all test parts.  This is the sum of the number\r\n  // of successful test parts and the number of failed test parts.\r\n  int total_part_count() const;\r\n\r\n  // Returns the number of the test properties.\r\n  int test_property_count() const;\r\n\r\n  // Returns true iff the test passed (i.e. no test part failed).\r\n  bool Passed() const {\r\n    return !Failed();\r\n  }\r\n\r\n  // Returns true iff the test failed.\r\n  bool Failed() const;\r\n\r\n  // Returns true iff the test fatally failed.\r\n  bool HasFatalFailure() const;\r\n\r\n  // Returns true iff the test has a non-fatal failure.\r\n  bool HasNonfatalFailure() const;\r\n\r\n  // Returns the elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time() const {\r\n    return elapsed_time_;\r\n  }\r\n\r\n  // Returns the i-th test part result among all the results. i can range\r\n  // from 0 to test_property_count() - 1. If i is not in that range, aborts\r\n  // the program.\r\n  const TestPartResult& GetTestPartResult(int i) const;\r\n\r\n  // Returns the i-th test property. i can range from 0 to\r\n  // test_property_count() - 1. If i is not in that range, aborts the\r\n  // program.\r\n  const TestProperty& GetTestProperty(int i) const;\r\n\r\n private:\r\n  friend class TestInfo;\r\n  friend class TestCase;\r\n  friend class UnitTest;\r\n  friend class internal::DefaultGlobalTestPartResultReporter;\r\n  friend class internal::ExecDeathTest;\r\n  friend class internal::TestResultAccessor;\r\n  friend class internal::UnitTestImpl;\r\n  friend class internal::WindowsDeathTest;\r\n\r\n  // Gets the vector of TestPartResults.\r\n  const std::vector<TestPartResult>& test_part_results() const {\r\n    return test_part_results_;\r\n  }\r\n\r\n  // Gets the vector of TestProperties.\r\n  const std::vector<TestProperty>& test_properties() const {\r\n    return test_properties_;\r\n  }\r\n\r\n  // Sets the elapsed time.\r\n  void set_elapsed_time(TimeInMillis elapsed) {\r\n    elapsed_time_ = elapsed;\r\n  }\r\n\r\n  // Adds a test property to the list. The property is validated and may add\r\n  // a non-fatal failure if invalid (e.g., if it conflicts with reserved\r\n  // key names). If a property is already recorded for the same key, the\r\n  // value will be updated, rather than storing multiple values for the same\r\n  // key.  xml_element specifies the element for which the property is being\r\n  // recorded and is used for validation.\r\n  void RecordProperty(const std::string& xml_element,\r\n                      const TestProperty& test_property);\r\n\r\n  // Adds a failure if the key is a reserved attribute of Google Test\r\n  // testcase tags.  Returns true if the property is valid.\r\n  // TODO(russr): Validate attribute names are legal and human readable.\r\n  static bool ValidateTestProperty(const std::string& xml_element,\r\n                                   const TestProperty& test_property);\r\n\r\n  // Adds a test part result to the list.\r\n  void AddTestPartResult(const TestPartResult& test_part_result);\r\n\r\n  // Returns the death test count.\r\n  int death_test_count() const {\r\n    return death_test_count_;\r\n  }\r\n\r\n  // Increments the death test count, returning the new count.\r\n  int increment_death_test_count() {\r\n    return ++death_test_count_;\r\n  }\r\n\r\n  // Clears the test part results.\r\n  void ClearTestPartResults();\r\n\r\n  // Clears the object.\r\n  void Clear();\r\n\r\n  // Protects mutable state of the property vector and of owned\r\n  // properties, whose values may be updated.\r\n  internal::Mutex test_properites_mutex_;\r\n\r\n  // The vector of TestPartResults\r\n  std::vector<TestPartResult> test_part_results_;\r\n  // The vector of TestProperties\r\n  std::vector<TestProperty> test_properties_;\r\n  // Running count of death tests.\r\n  int death_test_count_;\r\n  // The elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time_;\r\n\r\n  // We disallow copying TestResult.\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult);\r\n};  // class TestResult\r\n\r\n// A TestInfo object stores the following information about a test:\r\n//\r\n//   Test case name\r\n//   Test name\r\n//   Whether the test should be run\r\n//   A function pointer that creates the test object when invoked\r\n//   Test result\r\n//\r\n// The constructor of TestInfo registers itself with the UnitTest\r\n// singleton such that the RUN_ALL_TESTS() macro knows which tests to\r\n// run.\r\nclass GTEST_API_ TestInfo {\r\n public:\r\n  // Destructs a TestInfo object.  This function is not virtual, so\r\n  // don't inherit from TestInfo.\r\n  ~TestInfo();\r\n\r\n  // Returns the test case name.\r\n  const char* test_case_name() const {\r\n    return test_case_name_.c_str();\r\n  }\r\n\r\n  // Returns the test name.\r\n  const char* name() const {\r\n    return name_.c_str();\r\n  }\r\n\r\n  // Returns the name of the parameter type, or NULL if this is not a typed\r\n  // or a type-parameterized test.\r\n  const char* type_param() const {\r\n    if (type_param_.get() != NULL) {\r\n      return type_param_->c_str();\r\n    }\r\n\r\n    return NULL;\r\n  }\r\n\r\n  // Returns the text representation of the value parameter, or NULL if this\r\n  // is not a value-parameterized test.\r\n  const char* value_param() const {\r\n    if (value_param_.get() != NULL) {\r\n      return value_param_->c_str();\r\n    }\r\n\r\n    return NULL;\r\n  }\r\n\r\n  // Returns true if this test should run, that is if the test is not\r\n  // disabled (or it is disabled but the also_run_disabled_tests flag has\r\n  // been specified) and its full name matches the user-specified filter.\r\n  //\r\n  // Google Test allows the user to filter the tests by their full names.\r\n  // The full name of a test Bar in test case Foo is defined as\r\n  // \"Foo.Bar\".  Only the tests that match the filter will run.\r\n  //\r\n  // A filter is a colon-separated list of glob (not regex) patterns,\r\n  // optionally followed by a '-' and a colon-separated list of\r\n  // negative patterns (tests to exclude).  A test is run if it\r\n  // matches one of the positive patterns and does not match any of\r\n  // the negative patterns.\r\n  //\r\n  // For example, *A*:Foo.* is a filter that matches any string that\r\n  // contains the character 'A' or starts with \"Foo.\".\r\n  bool should_run() const {\r\n    return should_run_;\r\n  }\r\n\r\n  // Returns true iff this test will appear in the XML report.\r\n  bool is_reportable() const {\r\n    // For now, the XML report includes all tests matching the filter.\r\n    // In the future, we may trim tests that are excluded because of\r\n    // sharding.\r\n    return matches_filter_;\r\n  }\r\n\r\n  // Returns the result of the test.\r\n  const TestResult* result() const {\r\n    return &result_;\r\n  }\r\n\r\n private:\r\n#if GTEST_HAS_DEATH_TEST\r\n  friend class internal::DefaultDeathTestFactory;\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n  friend class Test;\r\n  friend class TestCase;\r\n  friend class internal::UnitTestImpl;\r\n  friend class internal::StreamingListenerTest;\r\n  friend TestInfo* internal::MakeAndRegisterTestInfo(\r\n    const char* test_case_name,\r\n    const char* name,\r\n    const char* type_param,\r\n    const char* value_param,\r\n    internal::TypeId fixture_class_id,\r\n    Test::SetUpTestCaseFunc set_up_tc,\r\n    Test::TearDownTestCaseFunc tear_down_tc,\r\n    internal::TestFactoryBase* factory);\r\n\r\n  // Constructs a TestInfo object. The newly constructed instance assumes\r\n  // ownership of the factory object.\r\n  TestInfo(const std::string& test_case_name,\r\n           const std::string& name,\r\n           const char* a_type_param,   // NULL if not a type-parameterized test\r\n           const char* a_value_param,  // NULL if not a value-parameterized test\r\n           internal::TypeId fixture_class_id,\r\n           internal::TestFactoryBase* factory);\r\n\r\n  // Increments the number of death tests encountered in this test so\r\n  // far.\r\n  int increment_death_test_count() {\r\n    return result_.increment_death_test_count();\r\n  }\r\n\r\n  // Creates the test object, runs it, records its result, and then\r\n  // deletes it.\r\n  void Run();\r\n\r\n  static void ClearTestResult(TestInfo* test_info) {\r\n    test_info->result_.Clear();\r\n  }\r\n\r\n  // These fields are immutable properties of the test.\r\n  const std::string test_case_name_;     // Test case name\r\n  const std::string name_;               // Test name\r\n  // Name of the parameter type, or NULL if this is not a typed or a\r\n  // type-parameterized test.\r\n  const internal::scoped_ptr<const ::std::string> type_param_;\r\n  // Text representation of the value parameter, or NULL if this is not a\r\n  // value-parameterized test.\r\n  const internal::scoped_ptr<const ::std::string> value_param_;\r\n  const internal::TypeId fixture_class_id_;   // ID of the test fixture class\r\n  bool should_run_;                 // True iff this test should run\r\n  bool is_disabled_;                // True iff this test is disabled\r\n  bool matches_filter_;             // True if this test matches the\r\n  // user-specified filter.\r\n  internal::TestFactoryBase* const factory_;  // The factory that creates\r\n  // the test object\r\n\r\n  // This field is mutable and needs to be reset before running the\r\n  // test for the second time.\r\n  TestResult result_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);\r\n};\r\n\r\n// A test case, which consists of a vector of TestInfos.\r\n//\r\n// TestCase is not copyable.\r\nclass GTEST_API_ TestCase {\r\n public:\r\n  // Creates a TestCase with the given name.\r\n  //\r\n  // TestCase does NOT have a default constructor.  Always use this\r\n  // constructor to create a TestCase object.\r\n  //\r\n  // Arguments:\r\n  //\r\n  //   name:         name of the test case\r\n  //   a_type_param: the name of the test's type parameter, or NULL if\r\n  //                 this is not a type-parameterized test.\r\n  //   set_up_tc:    pointer to the function that sets up the test case\r\n  //   tear_down_tc: pointer to the function that tears down the test case\r\n  TestCase(const char* name, const char* a_type_param,\r\n           Test::SetUpTestCaseFunc set_up_tc,\r\n           Test::TearDownTestCaseFunc tear_down_tc);\r\n\r\n  // Destructor of TestCase.\r\n  virtual ~TestCase();\r\n\r\n  // Gets the name of the TestCase.\r\n  const char* name() const {\r\n    return name_.c_str();\r\n  }\r\n\r\n  // Returns the name of the parameter type, or NULL if this is not a\r\n  // type-parameterized test case.\r\n  const char* type_param() const {\r\n    if (type_param_.get() != NULL) {\r\n      return type_param_->c_str();\r\n    }\r\n\r\n    return NULL;\r\n  }\r\n\r\n  // Returns true if any test in this test case should run.\r\n  bool should_run() const {\r\n    return should_run_;\r\n  }\r\n\r\n  // Gets the number of successful tests in this test case.\r\n  int successful_test_count() const;\r\n\r\n  // Gets the number of failed tests in this test case.\r\n  int failed_test_count() const;\r\n\r\n  // Gets the number of disabled tests that will be reported in the XML report.\r\n  int reportable_disabled_test_count() const;\r\n\r\n  // Gets the number of disabled tests in this test case.\r\n  int disabled_test_count() const;\r\n\r\n  // Gets the number of tests to be printed in the XML report.\r\n  int reportable_test_count() const;\r\n\r\n  // Get the number of tests in this test case that should run.\r\n  int test_to_run_count() const;\r\n\r\n  // Gets the number of all tests in this test case.\r\n  int total_test_count() const;\r\n\r\n  // Returns true iff the test case passed.\r\n  bool Passed() const {\r\n    return !Failed();\r\n  }\r\n\r\n  // Returns true iff the test case failed.\r\n  bool Failed() const {\r\n    return failed_test_count() > 0;\r\n  }\r\n\r\n  // Returns the elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time() const {\r\n    return elapsed_time_;\r\n  }\r\n\r\n  // Returns the i-th test among all the tests. i can range from 0 to\r\n  // total_test_count() - 1. If i is not in that range, returns NULL.\r\n  const TestInfo* GetTestInfo(int i) const;\r\n\r\n  // Returns the TestResult that holds test properties recorded during\r\n  // execution of SetUpTestCase and TearDownTestCase.\r\n  const TestResult& ad_hoc_test_result() const {\r\n    return ad_hoc_test_result_;\r\n  }\r\n\r\n private:\r\n  friend class Test;\r\n  friend class internal::UnitTestImpl;\r\n\r\n  // Gets the (mutable) vector of TestInfos in this TestCase.\r\n  std::vector<TestInfo*>& test_info_list() {\r\n    return test_info_list_;\r\n  }\r\n\r\n  // Gets the (immutable) vector of TestInfos in this TestCase.\r\n  const std::vector<TestInfo*>& test_info_list() const {\r\n    return test_info_list_;\r\n  }\r\n\r\n  // Returns the i-th test among all the tests. i can range from 0 to\r\n  // total_test_count() - 1. If i is not in that range, returns NULL.\r\n  TestInfo* GetMutableTestInfo(int i);\r\n\r\n  // Sets the should_run member.\r\n  void set_should_run(bool should) {\r\n    should_run_ = should;\r\n  }\r\n\r\n  // Adds a TestInfo to this test case.  Will delete the TestInfo upon\r\n  // destruction of the TestCase object.\r\n  void AddTestInfo(TestInfo* test_info);\r\n\r\n  // Clears the results of all tests in this test case.\r\n  void ClearResult();\r\n\r\n  // Clears the results of all tests in the given test case.\r\n  static void ClearTestCaseResult(TestCase* test_case) {\r\n    test_case->ClearResult();\r\n  }\r\n\r\n  // Runs every test in this TestCase.\r\n  void Run();\r\n\r\n  // Runs SetUpTestCase() for this TestCase.  This wrapper is needed\r\n  // for catching exceptions thrown from SetUpTestCase().\r\n  void RunSetUpTestCase() {\r\n    (*set_up_tc_)();\r\n  }\r\n\r\n  // Runs TearDownTestCase() for this TestCase.  This wrapper is\r\n  // needed for catching exceptions thrown from TearDownTestCase().\r\n  void RunTearDownTestCase() {\r\n    (*tear_down_tc_)();\r\n  }\r\n\r\n  // Returns true iff test passed.\r\n  static bool TestPassed(const TestInfo* test_info) {\r\n    return test_info->should_run() && test_info->result()->Passed();\r\n  }\r\n\r\n  // Returns true iff test failed.\r\n  static bool TestFailed(const TestInfo* test_info) {\r\n    return test_info->should_run() && test_info->result()->Failed();\r\n  }\r\n\r\n  // Returns true iff the test is disabled and will be reported in the XML\r\n  // report.\r\n  static bool TestReportableDisabled(const TestInfo* test_info) {\r\n    return test_info->is_reportable() && test_info->is_disabled_;\r\n  }\r\n\r\n  // Returns true iff test is disabled.\r\n  static bool TestDisabled(const TestInfo* test_info) {\r\n    return test_info->is_disabled_;\r\n  }\r\n\r\n  // Returns true iff this test will appear in the XML report.\r\n  static bool TestReportable(const TestInfo* test_info) {\r\n    return test_info->is_reportable();\r\n  }\r\n\r\n  // Returns true if the given test should run.\r\n  static bool ShouldRunTest(const TestInfo* test_info) {\r\n    return test_info->should_run();\r\n  }\r\n\r\n  // Shuffles the tests in this test case.\r\n  void ShuffleTests(internal::Random* random);\r\n\r\n  // Restores the test order to before the first shuffle.\r\n  void UnshuffleTests();\r\n\r\n  // Name of the test case.\r\n  std::string name_;\r\n  // Name of the parameter type, or NULL if this is not a typed or a\r\n  // type-parameterized test.\r\n  const internal::scoped_ptr<const ::std::string> type_param_;\r\n  // The vector of TestInfos in their original order.  It owns the\r\n  // elements in the vector.\r\n  std::vector<TestInfo*> test_info_list_;\r\n  // Provides a level of indirection for the test list to allow easy\r\n  // shuffling and restoring the test order.  The i-th element in this\r\n  // vector is the index of the i-th test in the shuffled test list.\r\n  std::vector<int> test_indices_;\r\n  // Pointer to the function that sets up the test case.\r\n  Test::SetUpTestCaseFunc set_up_tc_;\r\n  // Pointer to the function that tears down the test case.\r\n  Test::TearDownTestCaseFunc tear_down_tc_;\r\n  // True iff any test in this test case should run.\r\n  bool should_run_;\r\n  // Elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time_;\r\n  // Holds test properties recorded during execution of SetUpTestCase and\r\n  // TearDownTestCase.\r\n  TestResult ad_hoc_test_result_;\r\n\r\n  // We disallow copying TestCases.\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);\r\n};\r\n\r\n// An Environment object is capable of setting up and tearing down an\r\n// environment.  The user should subclass this to define his own\r\n// environment(s).\r\n//\r\n// An Environment object does the set-up and tear-down in virtual\r\n// methods SetUp() and TearDown() instead of the constructor and the\r\n// destructor, as:\r\n//\r\n//   1. You cannot safely throw from a destructor.  This is a problem\r\n//      as in some cases Google Test is used where exceptions are enabled, and\r\n//      we may want to implement ASSERT_* using exceptions where they are\r\n//      available.\r\n//   2. You cannot use ASSERT_* directly in a constructor or\r\n//      destructor.\r\nclass Environment {\r\n public:\r\n  // The d'tor is virtual as we need to subclass Environment.\r\n  virtual ~Environment() {}\r\n\r\n  // Override this to define how to set up the environment.\r\n  virtual void SetUp() {}\r\n\r\n  // Override this to define how to tear down the environment.\r\n  virtual void TearDown() {}\r\n private:\r\n  // If you see an error about overriding the following function or\r\n  // about it being private, you have mis-spelled SetUp() as Setup().\r\n  struct Setup_should_be_spelled_SetUp {};\r\n  virtual Setup_should_be_spelled_SetUp* Setup() {\r\n    return NULL;\r\n  }\r\n};\r\n\r\n// The interface for tracing execution of tests. The methods are organized in\r\n// the order the corresponding events are fired.\r\nclass TestEventListener {\r\n public:\r\n  virtual ~TestEventListener() {}\r\n\r\n  // Fired before any test activity starts.\r\n  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;\r\n\r\n  // Fired before each iteration of tests starts.  There may be more than\r\n  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration\r\n  // index, starting from 0.\r\n  virtual void OnTestIterationStart(const UnitTest& unit_test,\r\n                                    int iteration) = 0;\r\n\r\n  // Fired before environment set-up for each iteration of tests starts.\r\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;\r\n\r\n  // Fired after environment set-up for each iteration of tests ends.\r\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;\r\n\r\n  // Fired before the test case starts.\r\n  virtual void OnTestCaseStart(const TestCase& test_case) = 0;\r\n\r\n  // Fired before the test starts.\r\n  virtual void OnTestStart(const TestInfo& test_info) = 0;\r\n\r\n  // Fired after a failed assertion or a SUCCEED() invocation.\r\n  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;\r\n\r\n  // Fired after the test ends.\r\n  virtual void OnTestEnd(const TestInfo& test_info) = 0;\r\n\r\n  // Fired after the test case ends.\r\n  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;\r\n\r\n  // Fired before environment tear-down for each iteration of tests starts.\r\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;\r\n\r\n  // Fired after environment tear-down for each iteration of tests ends.\r\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;\r\n\r\n  // Fired after each iteration of tests finishes.\r\n  virtual void OnTestIterationEnd(const UnitTest& unit_test,\r\n                                  int iteration) = 0;\r\n\r\n  // Fired after all test activities have ended.\r\n  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;\r\n};\r\n\r\n// The convenience class for users who need to override just one or two\r\n// methods and are not concerned that a possible change to a signature of\r\n// the methods they override will not be caught during the build.  For\r\n// comments about each method please see the definition of TestEventListener\r\n// above.\r\nclass EmptyTestEventListener : public TestEventListener {\r\n public:\r\n  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,\r\n                                    int /*iteration*/) {}\r\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}\r\n  virtual void OnTestStart(const TestInfo& /*test_info*/) {}\r\n  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}\r\n  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}\r\n  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}\r\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,\r\n                                  int /*iteration*/) {}\r\n  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}\r\n};\r\n\r\n// TestEventListeners lets users add listeners to track events in Google Test.\r\nclass GTEST_API_ TestEventListeners {\r\n public:\r\n  TestEventListeners();\r\n  ~TestEventListeners();\r\n\r\n  // Appends an event listener to the end of the list. Google Test assumes\r\n  // the ownership of the listener (i.e. it will delete the listener when\r\n  // the test program finishes).\r\n  void Append(TestEventListener* listener);\r\n\r\n  // Removes the given event listener from the list and returns it.  It then\r\n  // becomes the caller's responsibility to delete the listener. Returns\r\n  // NULL if the listener is not found in the list.\r\n  TestEventListener* Release(TestEventListener* listener);\r\n\r\n  // Returns the standard listener responsible for the default console\r\n  // output.  Can be removed from the listeners list to shut down default\r\n  // console output.  Note that removing this object from the listener list\r\n  // with Release transfers its ownership to the caller and makes this\r\n  // function return NULL the next time.\r\n  TestEventListener* default_result_printer() const {\r\n    return default_result_printer_;\r\n  }\r\n\r\n  // Returns the standard listener responsible for the default XML output\r\n  // controlled by the --gtest_output=xml flag.  Can be removed from the\r\n  // listeners list by users who want to shut down the default XML output\r\n  // controlled by this flag and substitute it with custom one.  Note that\r\n  // removing this object from the listener list with Release transfers its\r\n  // ownership to the caller and makes this function return NULL the next\r\n  // time.\r\n  TestEventListener* default_xml_generator() const {\r\n    return default_xml_generator_;\r\n  }\r\n\r\n private:\r\n  friend class TestCase;\r\n  friend class TestInfo;\r\n  friend class internal::DefaultGlobalTestPartResultReporter;\r\n  friend class internal::NoExecDeathTest;\r\n  friend class internal::TestEventListenersAccessor;\r\n  friend class internal::UnitTestImpl;\r\n\r\n  // Returns repeater that broadcasts the TestEventListener events to all\r\n  // subscribers.\r\n  TestEventListener* repeater();\r\n\r\n  // Sets the default_result_printer attribute to the provided listener.\r\n  // The listener is also added to the listener list and previous\r\n  // default_result_printer is removed from it and deleted. The listener can\r\n  // also be NULL in which case it will not be added to the list. Does\r\n  // nothing if the previous and the current listener objects are the same.\r\n  void SetDefaultResultPrinter(TestEventListener* listener);\r\n\r\n  // Sets the default_xml_generator attribute to the provided listener.  The\r\n  // listener is also added to the listener list and previous\r\n  // default_xml_generator is removed from it and deleted. The listener can\r\n  // also be NULL in which case it will not be added to the list. Does\r\n  // nothing if the previous and the current listener objects are the same.\r\n  void SetDefaultXmlGenerator(TestEventListener* listener);\r\n\r\n  // Controls whether events will be forwarded by the repeater to the\r\n  // listeners in the list.\r\n  bool EventForwardingEnabled() const;\r\n  void SuppressEventForwarding();\r\n\r\n  // The actual list of listeners.\r\n  internal::TestEventRepeater* repeater_;\r\n  // Listener responsible for the standard result output.\r\n  TestEventListener* default_result_printer_;\r\n  // Listener responsible for the creation of the XML output file.\r\n  TestEventListener* default_xml_generator_;\r\n\r\n  // We disallow copying TestEventListeners.\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);\r\n};\r\n\r\n// A UnitTest consists of a vector of TestCases.\r\n//\r\n// This is a singleton class.  The only instance of UnitTest is\r\n// created when UnitTest::GetInstance() is first called.  This\r\n// instance is never deleted.\r\n//\r\n// UnitTest is not copyable.\r\n//\r\n// This class is thread-safe as long as the methods are called\r\n// according to their specification.\r\nclass GTEST_API_ UnitTest {\r\n public:\r\n  // Gets the singleton UnitTest object.  The first time this method\r\n  // is called, a UnitTest object is constructed and returned.\r\n  // Consecutive calls will return the same object.\r\n  static UnitTest* GetInstance();\r\n\r\n  // Runs all tests in this UnitTest object and prints the result.\r\n  // Returns 0 if successful, or 1 otherwise.\r\n  //\r\n  // This method can only be called from the main thread.\r\n  //\r\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n  int Run() GTEST_MUST_USE_RESULT_;\r\n\r\n  // Returns the working directory when the first TEST() or TEST_F()\r\n  // was executed.  The UnitTest object owns the string.\r\n  const char* original_working_dir() const;\r\n\r\n  // Returns the TestCase object for the test that's currently running,\r\n  // or NULL if no test is running.\r\n  const TestCase* current_test_case() const\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // Returns the TestInfo object for the test that's currently running,\r\n  // or NULL if no test is running.\r\n  const TestInfo* current_test_info() const\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // Returns the random seed used at the start of the current test run.\r\n  int random_seed() const;\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n  // Returns the ParameterizedTestCaseRegistry object used to keep track of\r\n  // value-parameterized tests and instantiate and register them.\r\n  //\r\n  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n  internal::ParameterizedTestCaseRegistry& parameterized_test_registry()\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n  // Gets the number of successful test cases.\r\n  int successful_test_case_count() const;\r\n\r\n  // Gets the number of failed test cases.\r\n  int failed_test_case_count() const;\r\n\r\n  // Gets the number of all test cases.\r\n  int total_test_case_count() const;\r\n\r\n  // Gets the number of all test cases that contain at least one test\r\n  // that should run.\r\n  int test_case_to_run_count() const;\r\n\r\n  // Gets the number of successful tests.\r\n  int successful_test_count() const;\r\n\r\n  // Gets the number of failed tests.\r\n  int failed_test_count() const;\r\n\r\n  // Gets the number of disabled tests that will be reported in the XML report.\r\n  int reportable_disabled_test_count() const;\r\n\r\n  // Gets the number of disabled tests.\r\n  int disabled_test_count() const;\r\n\r\n  // Gets the number of tests to be printed in the XML report.\r\n  int reportable_test_count() const;\r\n\r\n  // Gets the number of all tests.\r\n  int total_test_count() const;\r\n\r\n  // Gets the number of tests that should run.\r\n  int test_to_run_count() const;\r\n\r\n  // Gets the time of the test program start, in ms from the start of the\r\n  // UNIX epoch.\r\n  TimeInMillis start_timestamp() const;\r\n\r\n  // Gets the elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time() const;\r\n\r\n  // Returns true iff the unit test passed (i.e. all test cases passed).\r\n  bool Passed() const;\r\n\r\n  // Returns true iff the unit test failed (i.e. some test case failed\r\n  // or something outside of all tests failed).\r\n  bool Failed() const;\r\n\r\n  // Gets the i-th test case among all the test cases. i can range from 0 to\r\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\r\n  const TestCase* GetTestCase(int i) const;\r\n\r\n  // Returns the TestResult containing information on test failures and\r\n  // properties logged outside of individual test cases.\r\n  const TestResult& ad_hoc_test_result() const;\r\n\r\n  // Returns the list of event listeners that can be used to track events\r\n  // inside Google Test.\r\n  TestEventListeners& listeners();\r\n\r\n private:\r\n  // Registers and returns a global test environment.  When a test\r\n  // program is run, all global test environments will be set-up in\r\n  // the order they were registered.  After all tests in the program\r\n  // have finished, all global test environments will be torn-down in\r\n  // the *reverse* order they were registered.\r\n  //\r\n  // The UnitTest object takes ownership of the given environment.\r\n  //\r\n  // This method can only be called from the main thread.\r\n  Environment* AddEnvironment(Environment* env);\r\n\r\n  // Adds a TestPartResult to the current TestResult object.  All\r\n  // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc)\r\n  // eventually call this to report their results.  The user code\r\n  // should use the assertion macros instead of calling this directly.\r\n  void AddTestPartResult(TestPartResult::Type result_type,\r\n                         const char* file_name,\r\n                         int line_number,\r\n                         const std::string& message,\r\n                         const std::string& os_stack_trace)\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // Adds a TestProperty to the current TestResult object when invoked from\r\n  // inside a test, to current TestCase's ad_hoc_test_result_ when invoked\r\n  // from SetUpTestCase or TearDownTestCase, or to the global property set\r\n  // when invoked elsewhere.  If the result already contains a property with\r\n  // the same key, the value will be updated.\r\n  void RecordProperty(const std::string& key, const std::string& value);\r\n\r\n  // Gets the i-th test case among all the test cases. i can range from 0 to\r\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\r\n  TestCase* GetMutableTestCase(int i);\r\n\r\n  // Accessors for the implementation object.\r\n  internal::UnitTestImpl* impl() {\r\n    return impl_;\r\n  }\r\n  const internal::UnitTestImpl* impl() const {\r\n    return impl_;\r\n  }\r\n\r\n  // These classes and funcions are friends as they need to access private\r\n  // members of UnitTest.\r\n  friend class Test;\r\n  friend class internal::AssertHelper;\r\n  friend class internal::ScopedTrace;\r\n  friend class internal::StreamingListenerTest;\r\n  friend class internal::UnitTestRecordPropertyTestHelper;\r\n  friend Environment* AddGlobalTestEnvironment(Environment* env);\r\n  friend internal::UnitTestImpl* internal::GetUnitTestImpl();\r\n  friend void internal::ReportFailureInUnknownLocation(\r\n    TestPartResult::Type result_type,\r\n    const std::string& message);\r\n\r\n  // Creates an empty UnitTest.\r\n  UnitTest();\r\n\r\n  // D'tor\r\n  virtual ~UnitTest();\r\n\r\n  // Pushes a trace defined by SCOPED_TRACE() on to the per-thread\r\n  // Google Test trace stack.\r\n  void PushGTestTrace(const internal::TraceInfo& trace)\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // Pops a trace from the per-thread Google Test trace stack.\r\n  void PopGTestTrace()\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // Protects mutable state in *impl_.  This is mutable as some const\r\n  // methods need to lock it too.\r\n  mutable internal::Mutex mutex_;\r\n\r\n  // Opaque implementation object.  This field is never changed once\r\n  // the object is constructed.  We don't mark it as const here, as\r\n  // doing so will cause a warning in the constructor of UnitTest.\r\n  // Mutable state in *impl_ is protected by mutex_.\r\n  internal::UnitTestImpl* impl_;\r\n\r\n  // We disallow copying UnitTest.\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest);\r\n};\r\n\r\n// A convenient wrapper for adding an environment for the test\r\n// program.\r\n//\r\n// You should call this before RUN_ALL_TESTS() is called, probably in\r\n// main().  If you use gtest_main, you need to call this before main()\r\n// starts for it to take effect.  For example, you can define a global\r\n// variable like this:\r\n//\r\n//   testing::Environment* const foo_env =\r\n//       testing::AddGlobalTestEnvironment(new FooEnvironment);\r\n//\r\n// However, we strongly recommend you to write your own main() and\r\n// call AddGlobalTestEnvironment() there, as relying on initialization\r\n// of global variables makes the code harder to read and may cause\r\n// problems when you register multiple environments from different\r\n// translation units and the environments have dependencies among them\r\n// (remember that the compiler doesn't guarantee the order in which\r\n// global variables from different translation units are initialized).\r\ninline Environment* AddGlobalTestEnvironment(Environment* env) {\r\n  return UnitTest::GetInstance()->AddEnvironment(env);\r\n}\r\n\r\n// Initializes Google Test.  This must be called before calling\r\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\r\n// flags that Google Test recognizes.  Whenever a Google Test flag is\r\n// seen, it is removed from argv, and *argc is decremented.\r\n//\r\n// No value is returned.  Instead, the Google Test flag variables are\r\n// updated.\r\n//\r\n// Calling the function for the second time has no user-visible effect.\r\nGTEST_API_ void InitGoogleTest(int* argc, char** argv);\r\n\r\n// This overloaded version can be used in Windows programs compiled in\r\n// UNICODE mode.\r\nGTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);\r\n\r\nnamespace internal {\r\n\r\n// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a\r\n// value of type ToPrint that is an operand of a comparison assertion\r\n// (e.g. ASSERT_EQ).  OtherOperand is the type of the other operand in\r\n// the comparison, and is used to help determine the best way to\r\n// format the value.  In particular, when the value is a C string\r\n// (char pointer) and the other operand is an STL string object, we\r\n// want to format the C string as a string, since we know it is\r\n// compared by value with the string object.  If the value is a char\r\n// pointer but the other operand is not an STL string object, we don't\r\n// know whether the pointer is supposed to point to a NUL-terminated\r\n// string, and thus want to print it as a pointer to be safe.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n\r\n// The default case.\r\ntemplate <typename ToPrint, typename OtherOperand>\r\nclass FormatForComparison {\r\n public:\r\n  static ::std::string Format(const ToPrint& value) {\r\n    return ::testing::PrintToString(value);\r\n  }\r\n};\r\n\r\n// Array.\r\ntemplate <typename ToPrint, size_t N, typename OtherOperand>\r\nclass FormatForComparison<ToPrint[N], OtherOperand> {\r\n public:\r\n  static ::std::string Format(const ToPrint* value) {\r\n    return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);\r\n  }\r\n};\r\n\r\n// By default, print C string as pointers to be safe, as we don't know\r\n// whether they actually point to a NUL-terminated string.\r\n\r\n#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType)                \\\r\n  template <typename OtherOperand>                                      \\\r\n  class FormatForComparison<CharType*, OtherOperand> {                  \\\r\n   public:                                                              \\\r\n    static ::std::string Format(CharType* value) {                      \\\r\n      return ::testing::PrintToString(static_cast<const void*>(value)); \\\r\n    }                                                                   \\\r\n  }\r\n\r\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);\r\n\r\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_\r\n\r\n// If a C string is compared with an STL string object, we know it's meant\r\n// to point to a NUL-terminated string, and thus can print it as a string.\r\n\r\n#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \\\r\n  template <>                                                           \\\r\n  class FormatForComparison<CharType*, OtherStringType> {               \\\r\n   public:                                                              \\\r\n    static ::std::string Format(CharType* value) {                      \\\r\n      return ::testing::PrintToString(value);                           \\\r\n    }                                                                   \\\r\n  }\r\n\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);\r\n\r\n#if GTEST_HAS_GLOBAL_STRING\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);\r\n#endif\r\n\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);\r\n#endif\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);\r\nGTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);\r\n#endif\r\n\r\n#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_\r\n\r\n// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)\r\n// operand to be used in a failure message.  The type (but not value)\r\n// of the other operand may affect the format.  This allows us to\r\n// print a char* as a raw pointer when it is compared against another\r\n// char* or void*, and print it as a C string when it is compared\r\n// against an std::string object, for example.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\ntemplate <typename T1, typename T2>\r\nstd::string FormatForComparisonFailureMessage(\r\n  const T1& value, const T2& /* other_operand */) {\r\n  return FormatForComparison<T1, T2>::Format(value);\r\n}\r\n\r\n// The helper function for {ASSERT|EXPECT}_EQ.\r\ntemplate <typename T1, typename T2>\r\nAssertionResult CmpHelperEQ(const char* expected_expression,\r\n                            const char* actual_expression,\r\n                            const T1& expected,\r\n                            const T2& actual) {\r\n#ifdef _MSC_VER\r\n# pragma warning(push)          // Saves the current warning state.\r\n# pragma warning(disable:4389)  // Temporarily disables warning on\r\n  // signed/unsigned mismatch.\r\n#endif\r\n\r\n  if (expected == actual) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n#ifdef _MSC_VER\r\n# pragma warning(pop)          // Restores the warning state.\r\n#endif\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   FormatForComparisonFailureMessage(expected, actual),\r\n                   FormatForComparisonFailureMessage(actual, expected),\r\n                   false);\r\n}\r\n\r\n// With this overloaded version, we allow anonymous enums to be used\r\n// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums\r\n// can be implicitly cast to BiggestInt.\r\nGTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression,\r\n                                       const char* actual_expression,\r\n                                       BiggestInt expected,\r\n                                       BiggestInt actual);\r\n\r\n// The helper class for {ASSERT|EXPECT}_EQ.  The template argument\r\n// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()\r\n// is a null pointer literal.  The following default implementation is\r\n// for lhs_is_null_literal being false.\r\ntemplate <bool lhs_is_null_literal>\r\nclass EqHelper {\r\n public:\r\n  // This templatized version is for the general case.\r\n  template <typename T1, typename T2>\r\n  static AssertionResult Compare(const char* expected_expression,\r\n                                 const char* actual_expression,\r\n                                 const T1& expected,\r\n                                 const T2& actual) {\r\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\r\n                       actual);\r\n  }\r\n\r\n  // With this overloaded version, we allow anonymous enums to be used\r\n  // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous\r\n  // enums can be implicitly cast to BiggestInt.\r\n  //\r\n  // Even though its body looks the same as the above version, we\r\n  // cannot merge the two, as it will make anonymous enums unhappy.\r\n  static AssertionResult Compare(const char* expected_expression,\r\n                                 const char* actual_expression,\r\n                                 BiggestInt expected,\r\n                                 BiggestInt actual) {\r\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\r\n                       actual);\r\n  }\r\n};\r\n\r\n// This specialization is used when the first argument to ASSERT_EQ()\r\n// is a null pointer literal, like NULL, false, or 0.\r\ntemplate <>\r\nclass EqHelper<true> {\r\n public:\r\n  // We define two overloaded versions of Compare().  The first\r\n  // version will be picked when the second argument to ASSERT_EQ() is\r\n  // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or\r\n  // EXPECT_EQ(false, a_bool).\r\n  template <typename T1, typename T2>\r\n  static AssertionResult Compare(\r\n    const char* expected_expression,\r\n    const char* actual_expression,\r\n    const T1& expected,\r\n    const T2& actual,\r\n    // The following line prevents this overload from being considered if T2\r\n    // is not a pointer type.  We need this because ASSERT_EQ(NULL, my_ptr)\r\n    // expands to Compare(\"\", \"\", NULL, my_ptr), which requires a conversion\r\n    // to match the Secret* in the other overload, which would otherwise make\r\n    // this template match better.\r\n    typename EnableIf < !is_pointer<T2>::value >::type* = 0) {\r\n    return CmpHelperEQ(expected_expression, actual_expression, expected,\r\n                       actual);\r\n  }\r\n\r\n  // This version will be picked when the second argument to ASSERT_EQ() is a\r\n  // pointer, e.g. ASSERT_EQ(NULL, a_pointer).\r\n  template <typename T>\r\n  static AssertionResult Compare(\r\n    const char* expected_expression,\r\n    const char* actual_expression,\r\n    // We used to have a second template parameter instead of Secret*.  That\r\n    // template parameter would deduce to 'long', making this a better match\r\n    // than the first overload even without the first overload's EnableIf.\r\n    // Unfortunately, gcc with -Wconversion-null warns when \"passing NULL to\r\n    // non-pointer argument\" (even a deduced integral argument), so the old\r\n    // implementation caused warnings in user code.\r\n    Secret* /* expected (NULL) */,\r\n    T* actual) {\r\n    // We already know that 'expected' is a null pointer.\r\n    return CmpHelperEQ(expected_expression, actual_expression,\r\n                       static_cast<T*>(NULL), actual);\r\n  }\r\n};\r\n\r\n// A macro for implementing the helper functions needed to implement\r\n// ASSERT_?? and EXPECT_??.  It is here just to avoid copy-and-paste\r\n// of similar code.\r\n//\r\n// For each templatized helper function, we also define an overloaded\r\n// version for BiggestInt in order to reduce code bloat and allow\r\n// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled\r\n// with gcc 4.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)\\\r\ntemplate <typename T1, typename T2>\\\r\nAssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\r\n                                   const T1& val1, const T2& val2) {\\\r\n  if (val1 op val2) {\\\r\n    return AssertionSuccess();\\\r\n  } else {\\\r\n    return AssertionFailure() \\\r\n        << \"Expected: (\" << expr1 << \") \" #op \" (\" << expr2\\\r\n        << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\\\r\n        << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\\\r\n  }\\\r\n}\\\r\nGTEST_API_ AssertionResult CmpHelper##op_name(\\\r\n    const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\n\r\n// Implements the helper function for {ASSERT|EXPECT}_NE\r\nGTEST_IMPL_CMP_HELPER_(NE, != );\r\n// Implements the helper function for {ASSERT|EXPECT}_LE\r\nGTEST_IMPL_CMP_HELPER_(LE, <= );\r\n// Implements the helper function for {ASSERT|EXPECT}_LT\r\nGTEST_IMPL_CMP_HELPER_(LT, < );\r\n// Implements the helper function for {ASSERT|EXPECT}_GE\r\nGTEST_IMPL_CMP_HELPER_(GE, >= );\r\n// Implements the helper function for {ASSERT|EXPECT}_GT\r\nGTEST_IMPL_CMP_HELPER_(GT, > );\r\n\r\n#undef GTEST_IMPL_CMP_HELPER_\r\n\r\n// The helper function for {ASSERT|EXPECT}_STREQ.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,\r\n    const char* actual_expression,\r\n    const char* expected,\r\n    const char* actual);\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,\r\n    const char* actual_expression,\r\n    const char* expected,\r\n    const char* actual);\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRNE.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\r\n    const char* s2_expression,\r\n    const char* s1,\r\n    const char* s2);\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,\r\n    const char* s2_expression,\r\n    const char* s1,\r\n    const char* s2);\r\n\r\n\r\n// Helper function for *_STREQ on wide strings.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression,\r\n    const char* actual_expression,\r\n    const wchar_t* expected,\r\n    const wchar_t* actual);\r\n\r\n// Helper function for *_STRNE on wide strings.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,\r\n    const char* s2_expression,\r\n    const wchar_t* s1,\r\n    const wchar_t* s2);\r\n\r\n}  // namespace internal\r\n\r\n// IsSubstring() and IsNotSubstring() are intended to be used as the\r\n// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by\r\n// themselves.  They check whether needle is a substring of haystack\r\n// (NULL is considered a substring of itself only), and return an\r\n// appropriate error message when they fail.\r\n//\r\n// The {needle,haystack}_expr arguments are the stringified\r\n// expressions that generated the two real arguments.\r\nGTEST_API_ AssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const char* needle, const char* haystack);\r\nGTEST_API_ AssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const wchar_t* needle, const wchar_t* haystack);\r\nGTEST_API_ AssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const char* needle, const char* haystack);\r\nGTEST_API_ AssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const wchar_t* needle, const wchar_t* haystack);\r\nGTEST_API_ AssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::string& needle, const ::std::string& haystack);\r\nGTEST_API_ AssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::string& needle, const ::std::string& haystack);\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\nGTEST_API_ AssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::wstring& needle, const ::std::wstring& haystack);\r\nGTEST_API_ AssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::wstring& needle, const ::std::wstring& haystack);\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\nnamespace internal {\r\n\r\n// Helper template function for comparing floating-points.\r\n//\r\n// Template parameter:\r\n//\r\n//   RawType: the raw floating-point type (either float or double)\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\ntemplate <typename RawType>\r\nAssertionResult CmpHelperFloatingPointEQ(const char* expected_expression,\r\n    const char* actual_expression,\r\n    RawType expected,\r\n    RawType actual) {\r\n  const FloatingPoint<RawType> lhs(expected), rhs(actual);\r\n\r\n  if (lhs.AlmostEquals(rhs)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  ::std::stringstream expected_ss;\r\n  expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\r\n              << expected;\r\n\r\n  ::std::stringstream actual_ss;\r\n  actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\r\n            << actual;\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   StringStreamToString(&expected_ss),\r\n                   StringStreamToString(&actual_ss),\r\n                   false);\r\n}\r\n\r\n// Helper function for implementing ASSERT_NEAR.\r\n//\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.\r\nGTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1,\r\n    const char* expr2,\r\n    const char* abs_error_expr,\r\n    double val1,\r\n    double val2,\r\n    double abs_error);\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n// A class that enables one to stream messages to assertion macros\r\nclass GTEST_API_ AssertHelper {\r\n public:\r\n  // Constructor.\r\n  AssertHelper(TestPartResult::Type type,\r\n               const char* file,\r\n               int line,\r\n               const char* message);\r\n  ~AssertHelper();\r\n\r\n  // Message assignment is a semantic trick to enable assertion\r\n  // streaming; see the GTEST_MESSAGE_ macro below.\r\n  void operator=(const Message& message) const;\r\n\r\n private:\r\n  // We put our data in a struct so that the size of the AssertHelper class can\r\n  // be as small as possible.  This is important because gcc is incapable of\r\n  // re-using stack space even for temporary variables, so every EXPECT_EQ\r\n  // reserves stack space for another AssertHelper.\r\n  struct AssertHelperData {\r\n    AssertHelperData(TestPartResult::Type t,\r\n                     const char* srcfile,\r\n                     int line_num,\r\n                     const char* msg)\r\n      : type(t), file(srcfile), line(line_num), message(msg) { }\r\n\r\n    TestPartResult::Type const type;\r\n    const char* const file;\r\n    int const line;\r\n    std::string const message;\r\n\r\n   private:\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);\r\n  };\r\n\r\n  AssertHelperData* const data_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);\r\n};\r\n\r\n}  // namespace internal\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n// The pure interface class that all value-parameterized tests inherit from.\r\n// A value-parameterized class must inherit from both ::testing::Test and\r\n// ::testing::WithParamInterface. In most cases that just means inheriting\r\n// from ::testing::TestWithParam, but more complicated test hierarchies\r\n// may need to inherit from Test and WithParamInterface at different levels.\r\n//\r\n// This interface has support for accessing the test parameter value via\r\n// the GetParam() method.\r\n//\r\n// Use it with one of the parameter generator defining functions, like Range(),\r\n// Values(), ValuesIn(), Bool(), and Combine().\r\n//\r\n// class FooTest : public ::testing::TestWithParam<int> {\r\n//  protected:\r\n//   FooTest() {\r\n//     // Can use GetParam() here.\r\n//   }\r\n//   virtual ~FooTest() {\r\n//     // Can use GetParam() here.\r\n//   }\r\n//   virtual void SetUp() {\r\n//     // Can use GetParam() here.\r\n//   }\r\n//   virtual void TearDown {\r\n//     // Can use GetParam() here.\r\n//   }\r\n// };\r\n// TEST_P(FooTest, DoesBar) {\r\n//   // Can use GetParam() method here.\r\n//   Foo foo;\r\n//   ASSERT_TRUE(foo.DoesBar(GetParam()));\r\n// }\r\n// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));\r\n\r\ntemplate <typename T>\r\nclass WithParamInterface {\r\n public:\r\n  typedef T ParamType;\r\n  virtual ~WithParamInterface() {}\r\n\r\n  // The current parameter value. Is also available in the test fixture's\r\n  // constructor. This member function is non-static, even though it only\r\n  // references static data, to reduce the opportunity for incorrect uses\r\n  // like writing 'WithParamInterface<bool>::GetParam()' for a test that\r\n  // uses a fixture whose parameter type is int.\r\n  const ParamType& GetParam() const {\r\n    GTEST_CHECK_(parameter_ != NULL)\r\n        << \"GetParam() can only be called inside a value-parameterized test \"\r\n        << \"-- did you intend to write TEST_P instead of TEST_F?\";\r\n    return *parameter_;\r\n  }\r\n\r\n private:\r\n  // Sets parameter value. The caller is responsible for making sure the value\r\n  // remains alive and unchanged throughout the current test.\r\n  static void SetParam(const ParamType* parameter) {\r\n    parameter_ = parameter;\r\n  }\r\n\r\n  // Static value used for accessing parameter during a test lifetime.\r\n  static const ParamType* parameter_;\r\n\r\n  // TestClass must be a subclass of WithParamInterface<T> and Test.\r\n  template <class TestClass> friend class internal::ParameterizedTestFactory;\r\n};\r\n\r\ntemplate <typename T>\r\nconst T* WithParamInterface<T>::parameter_ = NULL;\r\n\r\n// Most value-parameterized classes can ignore the existence of\r\n// WithParamInterface, and can just inherit from ::testing::TestWithParam.\r\n\r\ntemplate <typename T>\r\nclass TestWithParam : public Test, public WithParamInterface<T> {\r\n};\r\n\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n// Macros for indicating success/failure in test code.\r\n\r\n// ADD_FAILURE unconditionally adds a failure to the current test.\r\n// SUCCEED generates a success - it doesn't automatically make the\r\n// current test successful, as a test is only successful when it has\r\n// no failure.\r\n//\r\n// EXPECT_* verifies that a certain condition is satisfied.  If not,\r\n// it behaves like ADD_FAILURE.  In particular:\r\n//\r\n//   EXPECT_TRUE  verifies that a Boolean condition is true.\r\n//   EXPECT_FALSE verifies that a Boolean condition is false.\r\n//\r\n// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except\r\n// that they will also abort the current function on failure.  People\r\n// usually want the fail-fast behavior of FAIL and ASSERT_*, but those\r\n// writing data-driven tests often find themselves using ADD_FAILURE\r\n// and EXPECT_* more.\r\n\r\n// Generates a nonfatal failure with a generic message.\r\n#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_(\"Failed\")\r\n\r\n// Generates a nonfatal failure at the given source file location with\r\n// a generic message.\r\n#define ADD_FAILURE_AT(file, line) \\\r\n  GTEST_MESSAGE_AT_(file, line, \"Failed\", \\\r\n                    ::testing::TestPartResult::kNonFatalFailure)\r\n\r\n// Generates a fatal failure with a generic message.\r\n#define GTEST_FAIL() GTEST_FATAL_FAILURE_(\"Failed\")\r\n\r\n// Define this macro to 1 to omit the definition of FAIL(), which is a\r\n// generic name and clashes with some other libraries.\r\n#if !GTEST_DONT_DEFINE_FAIL\r\n# define FAIL() GTEST_FAIL()\r\n#endif\r\n\r\n// Generates a success with a generic message.\r\n#define GTEST_SUCCEED() GTEST_SUCCESS_(\"Succeeded\")\r\n\r\n// Define this macro to 1 to omit the definition of SUCCEED(), which\r\n// is a generic name and clashes with some other libraries.\r\n#if !GTEST_DONT_DEFINE_SUCCEED\r\n# define SUCCEED() GTEST_SUCCEED()\r\n#endif\r\n\r\n// Macros for testing exceptions.\r\n//\r\n//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):\r\n//         Tests that the statement throws the expected exception.\r\n//    * {ASSERT|EXPECT}_NO_THROW(statement):\r\n//         Tests that the statement doesn't throw any exception.\r\n//    * {ASSERT|EXPECT}_ANY_THROW(statement):\r\n//         Tests that the statement throws an exception.\r\n\r\n#define EXPECT_THROW(statement, expected_exception) \\\r\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_NO_THROW(statement) \\\r\n  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_ANY_THROW(statement) \\\r\n  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_THROW(statement, expected_exception) \\\r\n  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_NO_THROW(statement) \\\r\n  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_ANY_THROW(statement) \\\r\n  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)\r\n\r\n// Boolean assertions. Condition can be either a Boolean expression or an\r\n// AssertionResult. For more information on how to use AssertionResult with\r\n// these macros see comments on that class.\r\n#define EXPECT_TRUE(condition) \\\r\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\r\n                      GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_FALSE(condition) \\\r\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\r\n                      GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_TRUE(condition) \\\r\n  GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \\\r\n                      GTEST_FATAL_FAILURE_)\r\n#define ASSERT_FALSE(condition) \\\r\n  GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \\\r\n                      GTEST_FATAL_FAILURE_)\r\n\r\n// Includes the auto-generated header that implements a family of\r\n// generic predicate assertion macros.\r\n#include \"gtest/gtest_pred_impl.h\"\r\n\r\n// Macros for testing equalities and inequalities.\r\n//\r\n//    * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual\r\n//    * {ASSERT|EXPECT}_NE(v1, v2):           Tests that v1 != v2\r\n//    * {ASSERT|EXPECT}_LT(v1, v2):           Tests that v1 < v2\r\n//    * {ASSERT|EXPECT}_LE(v1, v2):           Tests that v1 <= v2\r\n//    * {ASSERT|EXPECT}_GT(v1, v2):           Tests that v1 > v2\r\n//    * {ASSERT|EXPECT}_GE(v1, v2):           Tests that v1 >= v2\r\n//\r\n// When they are not, Google Test prints both the tested expressions and\r\n// their actual values.  The values must be compatible built-in types,\r\n// or you will get a compiler error.  By \"compatible\" we mean that the\r\n// values can be compared by the respective operator.\r\n//\r\n// Note:\r\n//\r\n//   1. It is possible to make a user-defined type work with\r\n//   {ASSERT|EXPECT}_??(), but that requires overloading the\r\n//   comparison operators and is thus discouraged by the Google C++\r\n//   Usage Guide.  Therefore, you are advised to use the\r\n//   {ASSERT|EXPECT}_TRUE() macro to assert that two objects are\r\n//   equal.\r\n//\r\n//   2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on\r\n//   pointers (in particular, C strings).  Therefore, if you use it\r\n//   with two C strings, you are testing how their locations in memory\r\n//   are related, not how their content is related.  To compare two C\r\n//   strings by content, use {ASSERT|EXPECT}_STR*().\r\n//\r\n//   3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to\r\n//   {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you\r\n//   what the actual value is when it fails, and similarly for the\r\n//   other comparisons.\r\n//\r\n//   4. Do not depend on the order in which {ASSERT|EXPECT}_??()\r\n//   evaluate their arguments, which is undefined.\r\n//\r\n//   5. These macros evaluate their arguments exactly once.\r\n//\r\n// Examples:\r\n//\r\n//   EXPECT_NE(5, Foo());\r\n//   EXPECT_EQ(NULL, a_pointer);\r\n//   ASSERT_LT(i, array_size);\r\n//   ASSERT_GT(records.size(), 0) << \"There is no record left.\";\r\n\r\n#define EXPECT_EQ(expected, actual) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal:: \\\r\n                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \\\r\n                      expected, actual)\r\n#define EXPECT_NE(expected, actual) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)\r\n#define EXPECT_LE(val1, val2) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\r\n#define EXPECT_LT(val1, val2) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\r\n#define EXPECT_GE(val1, val2) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\r\n#define EXPECT_GT(val1, val2) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\r\n\r\n#define GTEST_ASSERT_EQ(expected, actual) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal:: \\\r\n                      EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \\\r\n                      expected, actual)\r\n#define GTEST_ASSERT_NE(val1, val2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)\r\n#define GTEST_ASSERT_LE(val1, val2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)\r\n#define GTEST_ASSERT_LT(val1, val2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)\r\n#define GTEST_ASSERT_GE(val1, val2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)\r\n#define GTEST_ASSERT_GT(val1, val2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)\r\n\r\n// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of\r\n// ASSERT_XY(), which clashes with some users' own code.\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_EQ\r\n# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2)\r\n#endif\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_NE\r\n# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2)\r\n#endif\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_LE\r\n# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2)\r\n#endif\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_LT\r\n# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2)\r\n#endif\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_GE\r\n# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2)\r\n#endif\r\n\r\n#if !GTEST_DONT_DEFINE_ASSERT_GT\r\n# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2)\r\n#endif\r\n\r\n// C-string Comparisons.  All tests treat NULL and any non-NULL string\r\n// as different.  Two NULLs are equal.\r\n//\r\n//    * {ASSERT|EXPECT}_STREQ(s1, s2):     Tests that s1 == s2\r\n//    * {ASSERT|EXPECT}_STRNE(s1, s2):     Tests that s1 != s2\r\n//    * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case\r\n//    * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case\r\n//\r\n// For wide or narrow string objects, you can use the\r\n// {ASSERT|EXPECT}_??() macros.\r\n//\r\n// Don't depend on the order in which the arguments are evaluated,\r\n// which is undefined.\r\n//\r\n// These macros evaluate their arguments exactly once.\r\n\r\n#define EXPECT_STREQ(expected, actual) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)\r\n#define EXPECT_STRNE(s1, s2) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\r\n#define EXPECT_STRCASEEQ(expected, actual) \\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)\r\n#define EXPECT_STRCASENE(s1, s2)\\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\r\n\r\n#define ASSERT_STREQ(expected, actual) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)\r\n#define ASSERT_STRNE(s1, s2) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)\r\n#define ASSERT_STRCASEEQ(expected, actual) \\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)\r\n#define ASSERT_STRCASENE(s1, s2)\\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)\r\n\r\n// Macros for comparing floating-point numbers.\r\n//\r\n//    * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual):\r\n//         Tests that two float values are almost equal.\r\n//    * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual):\r\n//         Tests that two double values are almost equal.\r\n//    * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error):\r\n//         Tests that v1 and v2 are within the given distance to each other.\r\n//\r\n// Google Test uses ULP-based comparison to automatically pick a default\r\n// error bound that is appropriate for the operands.  See the\r\n// FloatingPoint template class in gtest-internal.h if you are\r\n// interested in the implementation details.\r\n\r\n#define EXPECT_FLOAT_EQ(expected, actual)\\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\r\n                      expected, actual)\r\n\r\n#define EXPECT_DOUBLE_EQ(expected, actual)\\\r\n  EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\r\n                      expected, actual)\r\n\r\n#define ASSERT_FLOAT_EQ(expected, actual)\\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \\\r\n                      expected, actual)\r\n\r\n#define ASSERT_DOUBLE_EQ(expected, actual)\\\r\n  ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \\\r\n                      expected, actual)\r\n\r\n#define EXPECT_NEAR(val1, val2, abs_error)\\\r\n  EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \\\r\n                      val1, val2, abs_error)\r\n\r\n#define ASSERT_NEAR(val1, val2, abs_error)\\\r\n  ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \\\r\n                      val1, val2, abs_error)\r\n\r\n// These predicate format functions work on floating-point values, and\r\n// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g.\r\n//\r\n//   EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0);\r\n\r\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\r\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\r\nGTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,\r\n                                   float val1, float val2);\r\nGTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,\r\n                                    double val1, double val2);\r\n\r\n\r\n#if GTEST_OS_WINDOWS\r\n\r\n// Macros that test for HRESULT failure and success, these are only useful\r\n// on Windows, and rely on Windows SDK macros and APIs to compile.\r\n//\r\n//    * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr)\r\n//\r\n// When expr unexpectedly fails or succeeds, Google Test prints the\r\n// expected result and the actual result with both a human-readable\r\n// string representation of the error, if available, as well as the\r\n// hex result code.\r\n# define EXPECT_HRESULT_SUCCEEDED(expr) \\\r\n    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\r\n\r\n# define ASSERT_HRESULT_SUCCEEDED(expr) \\\r\n    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))\r\n\r\n# define EXPECT_HRESULT_FAILED(expr) \\\r\n    EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\r\n\r\n# define ASSERT_HRESULT_FAILED(expr) \\\r\n    ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))\r\n\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Macros that execute statement and check that it doesn't generate new fatal\r\n// failures in the current thread.\r\n//\r\n//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);\r\n//\r\n// Examples:\r\n//\r\n//   EXPECT_NO_FATAL_FAILURE(Process());\r\n//   ASSERT_NO_FATAL_FAILURE(Process()) << \"Process() failed\";\r\n//\r\n#define ASSERT_NO_FATAL_FAILURE(statement) \\\r\n    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)\r\n#define EXPECT_NO_FATAL_FAILURE(statement) \\\r\n    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)\r\n\r\n// Causes a trace (including the source file path, the current line\r\n// number, and the given message) to be included in every test failure\r\n// message generated by code in the current scope.  The effect is\r\n// undone when the control leaves the current scope.\r\n//\r\n// The message argument can be anything streamable to std::ostream.\r\n//\r\n// In the implementation, we include the current line number as part\r\n// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s\r\n// to appear in the same block - as long as they are on different\r\n// lines.\r\n#define SCOPED_TRACE(message) \\\r\n  ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\\\r\n    __FILE__, __LINE__, ::testing::Message() << (message))\r\n\r\n// Compile-time assertion for type equality.\r\n// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are\r\n// the same type.  The value it returns is not interesting.\r\n//\r\n// Instead of making StaticAssertTypeEq a class template, we make it a\r\n// function template that invokes a helper class template.  This\r\n// prevents a user from misusing StaticAssertTypeEq<T1, T2> by\r\n// defining objects of that type.\r\n//\r\n// CAVEAT:\r\n//\r\n// When used inside a method of a class template,\r\n// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is\r\n// instantiated.  For example, given:\r\n//\r\n//   template <typename T> class Foo {\r\n//    public:\r\n//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }\r\n//   };\r\n//\r\n// the code:\r\n//\r\n//   void Test1() { Foo<bool> foo; }\r\n//\r\n// will NOT generate a compiler error, as Foo<bool>::Bar() is never\r\n// actually instantiated.  Instead, you need:\r\n//\r\n//   void Test2() { Foo<bool> foo; foo.Bar(); }\r\n//\r\n// to cause a compiler error.\r\ntemplate <typename T1, typename T2>\r\nbool StaticAssertTypeEq() {\r\n  (void)internal::StaticAssertTypeEqHelper<T1, T2>();\r\n  return true;\r\n}\r\n\r\n// Defines a test.\r\n//\r\n// The first parameter is the name of the test case, and the second\r\n// parameter is the name of the test within the test case.\r\n//\r\n// The convention is to end the test case name with \"Test\".  For\r\n// example, a test case for the Foo class can be named FooTest.\r\n//\r\n// The user should put his test code between braces after using this\r\n// macro.  Example:\r\n//\r\n//   TEST(FooTest, InitializesCorrectly) {\r\n//     Foo foo;\r\n//     EXPECT_TRUE(foo.StatusIsOK());\r\n//   }\r\n\r\n// Note that we call GetTestTypeId() instead of GetTypeId<\r\n// ::testing::Test>() here to get the type ID of testing::Test.  This\r\n// is to work around a suspected linker bug when using Google Test as\r\n// a framework on Mac OS X.  The bug causes GetTypeId<\r\n// ::testing::Test>() to return different values depending on whether\r\n// the call is from the Google Test framework itself or from user test\r\n// code.  GetTestTypeId() is guaranteed to always return the same\r\n// value, as it always calls GetTypeId<>() from the Google Test\r\n// framework.\r\n#define GTEST_TEST(test_case_name, test_name)\\\r\n  GTEST_TEST_(test_case_name, test_name, \\\r\n              ::testing::Test, ::testing::internal::GetTestTypeId())\r\n\r\n// Define this macro to 1 to omit the definition of TEST(), which\r\n// is a generic name and clashes with some other libraries.\r\n#if !GTEST_DONT_DEFINE_TEST\r\n# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)\r\n#endif\r\n\r\n// Defines a test that uses a test fixture.\r\n//\r\n// The first parameter is the name of the test fixture class, which\r\n// also doubles as the test case name.  The second parameter is the\r\n// name of the test within the test case.\r\n//\r\n// A test fixture class must be declared earlier.  The user should put\r\n// his test code between braces after using this macro.  Example:\r\n//\r\n//   class FooTest : public testing::Test {\r\n//    protected:\r\n//     virtual void SetUp() { b_.AddElement(3); }\r\n//\r\n//     Foo a_;\r\n//     Foo b_;\r\n//   };\r\n//\r\n//   TEST_F(FooTest, InitializesCorrectly) {\r\n//     EXPECT_TRUE(a_.StatusIsOK());\r\n//   }\r\n//\r\n//   TEST_F(FooTest, ReturnsElementCountCorrectly) {\r\n//     EXPECT_EQ(0, a_.size());\r\n//     EXPECT_EQ(1, b_.size());\r\n//   }\r\n\r\n#define TEST_F(test_fixture, test_name)\\\r\n  GTEST_TEST_(test_fixture, test_name, test_fixture, \\\r\n              ::testing::internal::GetTypeId<test_fixture>())\r\n\r\n}  // namespace testing\r\n\r\n// Use this function in main() to run all tests.  It returns 0 if all\r\n// tests are successful, or 1 otherwise.\r\n//\r\n// RUN_ALL_TESTS() should be invoked after the command line has been\r\n// parsed by InitGoogleTest().\r\n//\r\n// This function was formerly a macro; thus, it is in the global\r\n// namespace and has an all-caps name.\r\nint RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_;\r\n\r\ninline int RUN_ALL_TESTS() {\r\n  return ::testing::UnitTest::GetInstance()->Run();\r\n}\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest_pred_impl.h",
    "content": "// Copyright 2006, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command\r\n// 'gen_gtest_pred_impl.py 5'.  DO NOT EDIT BY HAND!\r\n//\r\n// Implements a family of generic predicate assertion macros.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\r\n\r\n// Makes sure this header is not included before gtest.h.\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_H_\r\n# error Do not include gtest_pred_impl.h directly.  Include gtest.h instead.\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_H_\r\n\r\n// This header implements a family of generic predicate assertion\r\n// macros:\r\n//\r\n//   ASSERT_PRED_FORMAT1(pred_format, v1)\r\n//   ASSERT_PRED_FORMAT2(pred_format, v1, v2)\r\n//   ...\r\n//\r\n// where pred_format is a function or functor that takes n (in the\r\n// case of ASSERT_PRED_FORMATn) values and their source expression\r\n// text, and returns a testing::AssertionResult.  See the definition\r\n// of ASSERT_EQ in gtest.h for an example.\r\n//\r\n// If you don't care about formatting, you can use the more\r\n// restrictive version:\r\n//\r\n//   ASSERT_PRED1(pred, v1)\r\n//   ASSERT_PRED2(pred, v1, v2)\r\n//   ...\r\n//\r\n// where pred is an n-ary function or functor that returns bool,\r\n// and the values v1, v2, ..., must support the << operator for\r\n// streaming to std::ostream.\r\n//\r\n// We also define the EXPECT_* variations.\r\n//\r\n// For now we only support predicates whose arity is at most 5.\r\n// Please email googletestframework@googlegroups.com if you need\r\n// support for higher arities.\r\n\r\n// GTEST_ASSERT_ is the basic statement to which all of the assertions\r\n// in this file reduce.  Don't use this in your code.\r\n\r\n#define GTEST_ASSERT_(expression, on_failure) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (const ::testing::AssertionResult gtest_ar = (expression)) \\\r\n    ; \\\r\n  else \\\r\n    on_failure(gtest_ar.failure_message())\r\n\r\n\r\n// Helper function for implementing {EXPECT|ASSERT}_PRED1.  Don't use\r\n// this in your code.\r\ntemplate <typename Pred,\r\n          typename T1>\r\nAssertionResult AssertPred1Helper(const char* pred_text,\r\n                                  const char* e1,\r\n                                  Pred pred,\r\n                                  const T1& v1) {\r\n  if (pred(v1)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << pred_text << \"(\"\r\n         << e1 << \") evaluates to false, where\"\r\n         << \"\\n\" << e1 << \" evaluates to \" << v1;\r\n}\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.\r\n// Don't use this in your code.\r\n#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\\\r\n  GTEST_ASSERT_(pred_format(#v1, v1), \\\r\n                on_failure)\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED1.  Don't use\r\n// this in your code.\r\n#define GTEST_PRED1_(pred, v1, on_failure)\\\r\n  GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \\\r\n                                             #v1, \\\r\n                                             pred, \\\r\n                                             v1), on_failure)\r\n\r\n// Unary predicate assertion macros.\r\n#define EXPECT_PRED_FORMAT1(pred_format, v1) \\\r\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_PRED1(pred, v1) \\\r\n  GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_PRED_FORMAT1(pred_format, v1) \\\r\n  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_PRED1(pred, v1) \\\r\n  GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)\r\n\r\n\r\n\r\n// Helper function for implementing {EXPECT|ASSERT}_PRED2.  Don't use\r\n// this in your code.\r\ntemplate <typename Pred,\r\n          typename T1,\r\n          typename T2>\r\nAssertionResult AssertPred2Helper(const char* pred_text,\r\n                                  const char* e1,\r\n                                  const char* e2,\r\n                                  Pred pred,\r\n                                  const T1& v1,\r\n                                  const T2& v2) {\r\n  if (pred(v1, v2)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << pred_text << \"(\"\r\n         << e1 << \", \"\r\n         << e2 << \") evaluates to false, where\"\r\n         << \"\\n\" << e1 << \" evaluates to \" << v1\r\n         << \"\\n\" << e2 << \" evaluates to \" << v2;\r\n}\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.\r\n// Don't use this in your code.\r\n#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\\\r\n  GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \\\r\n                on_failure)\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED2.  Don't use\r\n// this in your code.\r\n#define GTEST_PRED2_(pred, v1, v2, on_failure)\\\r\n  GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \\\r\n                                             #v1, \\\r\n                                             #v2, \\\r\n                                             pred, \\\r\n                                             v1, \\\r\n                                             v2), on_failure)\r\n\r\n// Binary predicate assertion macros.\r\n#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \\\r\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_PRED2(pred, v1, v2) \\\r\n  GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \\\r\n  GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_PRED2(pred, v1, v2) \\\r\n  GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)\r\n\r\n\r\n\r\n// Helper function for implementing {EXPECT|ASSERT}_PRED3.  Don't use\r\n// this in your code.\r\ntemplate <typename Pred,\r\n          typename T1,\r\n          typename T2,\r\n          typename T3>\r\nAssertionResult AssertPred3Helper(const char* pred_text,\r\n                                  const char* e1,\r\n                                  const char* e2,\r\n                                  const char* e3,\r\n                                  Pred pred,\r\n                                  const T1& v1,\r\n                                  const T2& v2,\r\n                                  const T3& v3) {\r\n  if (pred(v1, v2, v3)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << pred_text << \"(\"\r\n         << e1 << \", \"\r\n         << e2 << \", \"\r\n         << e3 << \") evaluates to false, where\"\r\n         << \"\\n\" << e1 << \" evaluates to \" << v1\r\n         << \"\\n\" << e2 << \" evaluates to \" << v2\r\n         << \"\\n\" << e3 << \" evaluates to \" << v3;\r\n}\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.\r\n// Don't use this in your code.\r\n#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\\\r\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \\\r\n                on_failure)\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED3.  Don't use\r\n// this in your code.\r\n#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\\\r\n  GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \\\r\n                                             #v1, \\\r\n                                             #v2, \\\r\n                                             #v3, \\\r\n                                             pred, \\\r\n                                             v1, \\\r\n                                             v2, \\\r\n                                             v3), on_failure)\r\n\r\n// Ternary predicate assertion macros.\r\n#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\r\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_PRED3(pred, v1, v2, v3) \\\r\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \\\r\n  GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_PRED3(pred, v1, v2, v3) \\\r\n  GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)\r\n\r\n\r\n\r\n// Helper function for implementing {EXPECT|ASSERT}_PRED4.  Don't use\r\n// this in your code.\r\ntemplate <typename Pred,\r\n          typename T1,\r\n          typename T2,\r\n          typename T3,\r\n          typename T4>\r\nAssertionResult AssertPred4Helper(const char* pred_text,\r\n                                  const char* e1,\r\n                                  const char* e2,\r\n                                  const char* e3,\r\n                                  const char* e4,\r\n                                  Pred pred,\r\n                                  const T1& v1,\r\n                                  const T2& v2,\r\n                                  const T3& v3,\r\n                                  const T4& v4) {\r\n  if (pred(v1, v2, v3, v4)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << pred_text << \"(\"\r\n         << e1 << \", \"\r\n         << e2 << \", \"\r\n         << e3 << \", \"\r\n         << e4 << \") evaluates to false, where\"\r\n         << \"\\n\" << e1 << \" evaluates to \" << v1\r\n         << \"\\n\" << e2 << \" evaluates to \" << v2\r\n         << \"\\n\" << e3 << \" evaluates to \" << v3\r\n         << \"\\n\" << e4 << \" evaluates to \" << v4;\r\n}\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.\r\n// Don't use this in your code.\r\n#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\\\r\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \\\r\n                on_failure)\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED4.  Don't use\r\n// this in your code.\r\n#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\\\r\n  GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \\\r\n                                             #v1, \\\r\n                                             #v2, \\\r\n                                             #v3, \\\r\n                                             #v4, \\\r\n                                             pred, \\\r\n                                             v1, \\\r\n                                             v2, \\\r\n                                             v3, \\\r\n                                             v4), on_failure)\r\n\r\n// 4-ary predicate assertion macros.\r\n#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\r\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_PRED4(pred, v1, v2, v3, v4) \\\r\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \\\r\n  GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_PRED4(pred, v1, v2, v3, v4) \\\r\n  GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)\r\n\r\n\r\n\r\n// Helper function for implementing {EXPECT|ASSERT}_PRED5.  Don't use\r\n// this in your code.\r\ntemplate <typename Pred,\r\n          typename T1,\r\n          typename T2,\r\n          typename T3,\r\n          typename T4,\r\n          typename T5>\r\nAssertionResult AssertPred5Helper(const char* pred_text,\r\n                                  const char* e1,\r\n                                  const char* e2,\r\n                                  const char* e3,\r\n                                  const char* e4,\r\n                                  const char* e5,\r\n                                  Pred pred,\r\n                                  const T1& v1,\r\n                                  const T2& v2,\r\n                                  const T3& v3,\r\n                                  const T4& v4,\r\n                                  const T5& v5) {\r\n  if (pred(v1, v2, v3, v4, v5)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << pred_text << \"(\"\r\n         << e1 << \", \"\r\n         << e2 << \", \"\r\n         << e3 << \", \"\r\n         << e4 << \", \"\r\n         << e5 << \") evaluates to false, where\"\r\n         << \"\\n\" << e1 << \" evaluates to \" << v1\r\n         << \"\\n\" << e2 << \" evaluates to \" << v2\r\n         << \"\\n\" << e3 << \" evaluates to \" << v3\r\n         << \"\\n\" << e4 << \" evaluates to \" << v4\r\n         << \"\\n\" << e5 << \" evaluates to \" << v5;\r\n}\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.\r\n// Don't use this in your code.\r\n#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\\\r\n  GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \\\r\n                on_failure)\r\n\r\n// Internal macro for implementing {EXPECT|ASSERT}_PRED5.  Don't use\r\n// this in your code.\r\n#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\\\r\n  GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \\\r\n                                             #v1, \\\r\n                                             #v2, \\\r\n                                             #v3, \\\r\n                                             #v4, \\\r\n                                             #v5, \\\r\n                                             pred, \\\r\n                                             v1, \\\r\n                                             v2, \\\r\n                                             v3, \\\r\n                                             v4, \\\r\n                                             v5), on_failure)\r\n\r\n// 5-ary predicate assertion macros.\r\n#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\r\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\r\n#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \\\r\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)\r\n#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \\\r\n  GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\r\n#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \\\r\n  GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)\r\n\r\n\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/gtest_prod.h",
    "content": "// Copyright 2006, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// Google C++ Testing Framework definitions useful in production code.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_\r\n#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_\r\n\r\n// When you need to test the private or protected members of a class,\r\n// use the FRIEND_TEST macro to declare your tests as friends of the\r\n// class.  For example:\r\n//\r\n// class MyClass {\r\n//  private:\r\n//   void MyMethod();\r\n//   FRIEND_TEST(MyClassTest, MyMethod);\r\n// };\r\n//\r\n// class MyClassTest : public testing::Test {\r\n//   // ...\r\n// };\r\n//\r\n// TEST_F(MyClassTest, MyMethod) {\r\n//   // Can call MyClass::MyMethod() here.\r\n// }\r\n\r\n#define FRIEND_TEST(test_case_name, test_name)\\\r\nfriend class test_case_name##_##test_name##_Test\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_GTEST_PROD_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-death-test-internal.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file defines internal utilities needed for implementing\r\n// death tests.  They are subject to change without notice.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\r\n\r\n#include \"gtest/internal/gtest-internal.h\"\r\n\r\n#include <stdio.h>\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\nGTEST_DECLARE_string_(internal_run_death_test);\r\n\r\n// Names of the flags (needed for parsing Google Test flags).\r\nconst char kDeathTestStyleFlag[] = \"death_test_style\";\r\nconst char kDeathTestUseFork[] = \"death_test_use_fork\";\r\nconst char kInternalRunDeathTestFlag[] = \"internal_run_death_test\";\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\n// DeathTest is a class that hides much of the complexity of the\r\n// GTEST_DEATH_TEST_ macro.  It is abstract; its static Create method\r\n// returns a concrete class that depends on the prevailing death test\r\n// style, as defined by the --gtest_death_test_style and/or\r\n// --gtest_internal_run_death_test flags.\r\n\r\n// In describing the results of death tests, these terms are used with\r\n// the corresponding definitions:\r\n//\r\n// exit status:  The integer exit information in the format specified\r\n//               by wait(2)\r\n// exit code:    The integer code passed to exit(3), _exit(2), or\r\n//               returned from main()\r\nclass GTEST_API_ DeathTest {\r\n public:\r\n  // Create returns false if there was an error determining the\r\n  // appropriate action to take for the current death test; for example,\r\n  // if the gtest_death_test_style flag is set to an invalid value.\r\n  // The LastMessage method will return a more detailed message in that\r\n  // case.  Otherwise, the DeathTest pointer pointed to by the \"test\"\r\n  // argument is set.  If the death test should be skipped, the pointer\r\n  // is set to NULL; otherwise, it is set to the address of a new concrete\r\n  // DeathTest object that controls the execution of the current test.\r\n  static bool Create(const char* statement, const RE* regex,\r\n                     const char* file, int line, DeathTest** test);\r\n  DeathTest();\r\n  virtual ~DeathTest() { }\r\n\r\n  // A helper class that aborts a death test when it's deleted.\r\n  class ReturnSentinel {\r\n   public:\r\n    explicit ReturnSentinel(DeathTest* test) : test_(test) { }\r\n    ~ReturnSentinel() {\r\n      test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT);\r\n    }\r\n   private:\r\n    DeathTest* const test_;\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);\r\n  } GTEST_ATTRIBUTE_UNUSED_;\r\n\r\n  // An enumeration of possible roles that may be taken when a death\r\n  // test is encountered.  EXECUTE means that the death test logic should\r\n  // be executed immediately.  OVERSEE means that the program should prepare\r\n  // the appropriate environment for a child process to execute the death\r\n  // test, then wait for it to complete.\r\n  enum TestRole { OVERSEE_TEST, EXECUTE_TEST };\r\n\r\n  // An enumeration of the three reasons that a test might be aborted.\r\n  enum AbortReason {\r\n    TEST_ENCOUNTERED_RETURN_STATEMENT,\r\n    TEST_THREW_EXCEPTION,\r\n    TEST_DID_NOT_DIE\r\n  };\r\n\r\n  // Assumes one of the above roles.\r\n  virtual TestRole AssumeRole() = 0;\r\n\r\n  // Waits for the death test to finish and returns its status.\r\n  virtual int Wait() = 0;\r\n\r\n  // Returns true if the death test passed; that is, the test process\r\n  // exited during the test, its exit status matches a user-supplied\r\n  // predicate, and its stderr output matches a user-supplied regular\r\n  // expression.\r\n  // The user-supplied predicate may be a macro expression rather\r\n  // than a function pointer or functor, or else Wait and Passed could\r\n  // be combined.\r\n  virtual bool Passed(bool exit_status_ok) = 0;\r\n\r\n  // Signals that the death test did not die as expected.\r\n  virtual void Abort(AbortReason reason) = 0;\r\n\r\n  // Returns a human-readable outcome message regarding the outcome of\r\n  // the last death test.\r\n  static const char* LastMessage();\r\n\r\n  static void set_last_death_test_message(const std::string& message);\r\n\r\n private:\r\n  // A string containing a description of the outcome of the last death test.\r\n  static std::string last_death_test_message_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);\r\n};\r\n\r\n// Factory interface for death tests.  May be mocked out for testing.\r\nclass DeathTestFactory {\r\n public:\r\n  virtual ~DeathTestFactory() { }\r\n  virtual bool Create(const char* statement, const RE* regex,\r\n                      const char* file, int line, DeathTest** test) = 0;\r\n};\r\n\r\n// A concrete DeathTestFactory implementation for normal use.\r\nclass DefaultDeathTestFactory : public DeathTestFactory {\r\n public:\r\n  virtual bool Create(const char* statement, const RE* regex,\r\n                      const char* file, int line, DeathTest** test);\r\n};\r\n\r\n// Returns true if exit_status describes a process that was terminated\r\n// by a signal, or exited normally with a nonzero exit code.\r\nGTEST_API_ bool ExitedUnsuccessfully(int exit_status);\r\n\r\n// Traps C++ exceptions escaping statement and reports them as test\r\n// failures. Note that trapping SEH exceptions is not implemented here.\r\n# if GTEST_HAS_EXCEPTIONS\r\n#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\r\n  try { \\\r\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n  } catch (const ::std::exception& gtest_exception) { \\\r\n    fprintf(\\\r\n        stderr, \\\r\n        \"\\n%s: Caught std::exception-derived exception escaping the \" \\\r\n        \"death test statement. Exception message: %s\\n\", \\\r\n        ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \\\r\n        gtest_exception.what()); \\\r\n    fflush(stderr); \\\r\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\r\n  } catch (...) { \\\r\n    death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \\\r\n  }\r\n\r\n# else\r\n#  define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \\\r\n  GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)\r\n\r\n# endif\r\n\r\n// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,\r\n// ASSERT_EXIT*, and EXPECT_EXIT*.\r\n# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::AlwaysTrue()) { \\\r\n    const ::testing::internal::RE& gtest_regex = (regex); \\\r\n    ::testing::internal::DeathTest* gtest_dt; \\\r\n    if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \\\r\n        __FILE__, __LINE__, &gtest_dt)) { \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \\\r\n    } \\\r\n    if (gtest_dt != NULL) { \\\r\n      ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \\\r\n          gtest_dt_ptr(gtest_dt); \\\r\n      switch (gtest_dt->AssumeRole()) { \\\r\n        case ::testing::internal::DeathTest::OVERSEE_TEST: \\\r\n          if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \\\r\n            goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \\\r\n          } \\\r\n          break; \\\r\n        case ::testing::internal::DeathTest::EXECUTE_TEST: { \\\r\n          ::testing::internal::DeathTest::ReturnSentinel \\\r\n              gtest_sentinel(gtest_dt); \\\r\n          GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \\\r\n          gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \\\r\n          break; \\\r\n        } \\\r\n        default: \\\r\n          break; \\\r\n      } \\\r\n    } \\\r\n  } else \\\r\n    GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \\\r\n      fail(::testing::internal::DeathTest::LastMessage())\r\n// The symbol \"fail\" here expands to something into which a message\r\n// can be streamed.\r\n\r\n// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in\r\n// NDEBUG mode. In this case we need the statements to be executed, the regex is\r\n// ignored, and the macro must accept a streamed message even though the message\r\n// is never printed.\r\n# define GTEST_EXECUTE_STATEMENT_(statement, regex) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::AlwaysTrue()) { \\\r\n     GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n  } else \\\r\n    ::testing::Message()\r\n\r\n// A class representing the parsed contents of the\r\n// --gtest_internal_run_death_test flag, as it existed when\r\n// RUN_ALL_TESTS was called.\r\nclass InternalRunDeathTestFlag {\r\n public:\r\n  InternalRunDeathTestFlag(const std::string& a_file,\r\n                           int a_line,\r\n                           int an_index,\r\n                           int a_write_fd)\r\n    : file_(a_file), line_(a_line), index_(an_index),\r\n      write_fd_(a_write_fd) {}\r\n\r\n  ~InternalRunDeathTestFlag() {\r\n    if (write_fd_ >= 0) {\r\n      posix::Close(write_fd_);\r\n    }\r\n  }\r\n\r\n  const std::string& file() const {\r\n    return file_;\r\n  }\r\n  int line() const {\r\n    return line_;\r\n  }\r\n  int index() const {\r\n    return index_;\r\n  }\r\n  int write_fd() const {\r\n    return write_fd_;\r\n  }\r\n\r\n private:\r\n  std::string file_;\r\n  int line_;\r\n  int index_;\r\n  int write_fd_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);\r\n};\r\n\r\n// Returns a newly created InternalRunDeathTestFlag object with fields\r\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\r\n// the flag is specified; otherwise returns NULL.\r\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();\r\n\r\n#else  // GTEST_HAS_DEATH_TEST\r\n\r\n// This macro is used for implementing macros such as\r\n// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where\r\n// death tests are not supported. Those macros must compile on such systems\r\n// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on\r\n// systems that support death tests. This allows one to write such a macro\r\n// on a system that does not support death tests and be sure that it will\r\n// compile on a death-test supporting system.\r\n//\r\n// Parameters:\r\n//   statement -  A statement that a macro such as EXPECT_DEATH would test\r\n//                for program termination. This macro has to make sure this\r\n//                statement is compiled but not executed, to ensure that\r\n//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain\r\n//                parameter iff EXPECT_DEATH compiles with it.\r\n//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test\r\n//                the output of statement.  This parameter has to be\r\n//                compiled but not evaluated by this macro, to ensure that\r\n//                this macro only accepts expressions that a macro such as\r\n//                EXPECT_DEATH would accept.\r\n//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED\r\n//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.\r\n//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not\r\n//                compile inside functions where ASSERT_DEATH doesn't\r\n//                compile.\r\n//\r\n//  The branch that has an always false condition is used to ensure that\r\n//  statement and regex are compiled (and thus syntactically correct) but\r\n//  never executed. The unreachable code macro protects the terminator\r\n//  statement from generating an 'unreachable code' warning in case\r\n//  statement unconditionally returns or throws. The Message constructor at\r\n//  the end allows the syntax of streaming additional messages into the\r\n//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.\r\n# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \\\r\n    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n    if (::testing::internal::AlwaysTrue()) { \\\r\n      GTEST_LOG_(WARNING) \\\r\n          << \"Death tests are not supported on this platform.\\n\" \\\r\n          << \"Statement '\" #statement \"' cannot be verified.\"; \\\r\n    } else if (::testing::internal::AlwaysFalse()) { \\\r\n      ::testing::internal::RE::PartialMatch(\".*\", (regex)); \\\r\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n      terminator; \\\r\n    } else \\\r\n      ::testing::Message()\r\n\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-filepath.h",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: keith.ray@gmail.com (Keith Ray)\r\n//\r\n// Google Test filepath utilities\r\n//\r\n// This header file declares classes and functions used internally by\r\n// Google Test.  They are subject to change without notice.\r\n//\r\n// This file is #included in <gtest/internal/gtest-internal.h>.\r\n// Do not include this header file separately!\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\r\n\r\n#include \"gtest/internal/gtest-string.h\"\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// FilePath - a class for file and directory pathname manipulation which\r\n// handles platform-specific conventions (like the pathname separator).\r\n// Used for helper functions for naming files in a directory for xml output.\r\n// Except for Set methods, all methods are const or static, which provides an\r\n// \"immutable value object\" -- useful for peace of mind.\r\n// A FilePath with a value ending in a path separator (\"like/this/\") represents\r\n// a directory, otherwise it is assumed to represent a file. In either case,\r\n// it may or may not represent an actual file or directory in the file system.\r\n// Names are NOT checked for syntax correctness -- no checking for illegal\r\n// characters, malformed paths, etc.\r\n\r\nclass GTEST_API_ FilePath {\r\n public:\r\n  FilePath() : pathname_(\"\") { }\r\n  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }\r\n\r\n  explicit FilePath(const std::string& pathname) : pathname_(pathname) {\r\n    Normalize();\r\n  }\r\n\r\n  FilePath& operator=(const FilePath& rhs) {\r\n    Set(rhs);\r\n    return *this;\r\n  }\r\n\r\n  void Set(const FilePath& rhs) {\r\n    pathname_ = rhs.pathname_;\r\n  }\r\n\r\n  const std::string& string() const {\r\n    return pathname_;\r\n  }\r\n  const char* c_str() const {\r\n    return pathname_.c_str();\r\n  }\r\n\r\n  // Returns the current working directory, or \"\" if unsuccessful.\r\n  static FilePath GetCurrentDir();\r\n\r\n  // Given directory = \"dir\", base_name = \"test\", number = 0,\r\n  // extension = \"xml\", returns \"dir/test.xml\". If number is greater\r\n  // than zero (e.g., 12), returns \"dir/test_12.xml\".\r\n  // On Windows platform, uses \\ as the separator rather than /.\r\n  static FilePath MakeFileName(const FilePath& directory,\r\n                               const FilePath& base_name,\r\n                               int number,\r\n                               const char* extension);\r\n\r\n  // Given directory = \"dir\", relative_path = \"test.xml\",\r\n  // returns \"dir/test.xml\".\r\n  // On Windows, uses \\ as the separator rather than /.\r\n  static FilePath ConcatPaths(const FilePath& directory,\r\n                              const FilePath& relative_path);\r\n\r\n  // Returns a pathname for a file that does not currently exist. The pathname\r\n  // will be directory/base_name.extension or\r\n  // directory/base_name_<number>.extension if directory/base_name.extension\r\n  // already exists. The number will be incremented until a pathname is found\r\n  // that does not already exist.\r\n  // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\r\n  // There could be a race condition if two or more processes are calling this\r\n  // function at the same time -- they could both pick the same filename.\r\n  static FilePath GenerateUniqueFileName(const FilePath& directory,\r\n                                         const FilePath& base_name,\r\n                                         const char* extension);\r\n\r\n  // Returns true iff the path is \"\".\r\n  bool IsEmpty() const {\r\n    return pathname_.empty();\r\n  }\r\n\r\n  // If input name has a trailing separator character, removes it and returns\r\n  // the name, otherwise return the name string unmodified.\r\n  // On Windows platform, uses \\ as the separator, other platforms use /.\r\n  FilePath RemoveTrailingPathSeparator() const;\r\n\r\n  // Returns a copy of the FilePath with the directory part removed.\r\n  // Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\r\n  // FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\r\n  // the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\r\n  // returns an empty FilePath (\"\").\r\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\r\n  FilePath RemoveDirectoryName() const;\r\n\r\n  // RemoveFileName returns the directory path with the filename removed.\r\n  // Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\r\n  // If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\r\n  // FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\r\n  // not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\r\n  // On Windows platform, '\\' is the path separator, otherwise it is '/'.\r\n  FilePath RemoveFileName() const;\r\n\r\n  // Returns a copy of the FilePath with the case-insensitive extension removed.\r\n  // Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\r\n  // FilePath(\"dir/file\"). If a case-insensitive extension is not\r\n  // found, returns a copy of the original FilePath.\r\n  FilePath RemoveExtension(const char* extension) const;\r\n\r\n  // Creates directories so that path exists. Returns true if successful or if\r\n  // the directories already exist; returns false if unable to create\r\n  // directories for any reason. Will also return false if the FilePath does\r\n  // not represent a directory (that is, it doesn't end with a path separator).\r\n  bool CreateDirectoriesRecursively() const;\r\n\r\n  // Create the directory so that path exists. Returns true if successful or\r\n  // if the directory already exists; returns false if unable to create the\r\n  // directory for any reason, including if the parent directory does not\r\n  // exist. Not named \"CreateDirectory\" because that's a macro on Windows.\r\n  bool CreateFolder() const;\r\n\r\n  // Returns true if FilePath describes something in the file-system,\r\n  // either a file, directory, or whatever, and that something exists.\r\n  bool FileOrDirectoryExists() const;\r\n\r\n  // Returns true if pathname describes a directory in the file-system\r\n  // that exists.\r\n  bool DirectoryExists() const;\r\n\r\n  // Returns true if FilePath ends with a path separator, which indicates that\r\n  // it is intended to represent a directory. Returns false otherwise.\r\n  // This does NOT check that a directory (or file) actually exists.\r\n  bool IsDirectory() const;\r\n\r\n  // Returns true if pathname describes a root directory. (Windows has one\r\n  // root directory per disk drive.)\r\n  bool IsRootDirectory() const;\r\n\r\n  // Returns true if pathname describes an absolute path.\r\n  bool IsAbsolutePath() const;\r\n\r\n private:\r\n  // Replaces multiple consecutive separators with a single separator.\r\n  // For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\r\n  // redundancies that might be in a pathname involving \".\" or \"..\".\r\n  //\r\n  // A pathname with multiple consecutive separators may occur either through\r\n  // user error or as a result of some scripts or APIs that generate a pathname\r\n  // with a trailing separator. On other platforms the same API or script\r\n  // may NOT generate a pathname with a trailing \"/\". Then elsewhere that\r\n  // pathname may have another \"/\" and pathname components added to it,\r\n  // without checking for the separator already being there.\r\n  // The script language and operating system may allow paths like \"foo//bar\"\r\n  // but some of the functions in FilePath will not handle that correctly. In\r\n  // particular, RemoveTrailingPathSeparator() only removes one separator, and\r\n  // it is called in CreateDirectoriesRecursively() assuming that it will change\r\n  // a pathname from directory syntax (trailing separator) to filename syntax.\r\n  //\r\n  // On Windows this method also replaces the alternate path separator '/' with\r\n  // the primary path separator '\\\\', so that for example \"bar\\\\/\\\\foo\" becomes\r\n  // \"bar\\\\foo\".\r\n\r\n  void Normalize();\r\n\r\n  // Returns a pointer to the last occurence of a valid path separator in\r\n  // the FilePath. On Windows, for example, both '/' and '\\' are valid path\r\n  // separators. Returns NULL if no path separator was found.\r\n  const char* FindLastPathSeparator() const;\r\n\r\n  std::string pathname_;\r\n};  // class FilePath\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-internal.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file declares functions and macros used internally by\r\n// Google Test.  They are subject to change without notice.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if GTEST_OS_LINUX\r\n# include <stdlib.h>\r\n# include <sys/types.h>\r\n# include <sys/wait.h>\r\n# include <unistd.h>\r\n#endif  // GTEST_OS_LINUX\r\n\r\n#if GTEST_HAS_EXCEPTIONS\r\n# include <stdexcept>\r\n#endif\r\n\r\n#include <ctype.h>\r\n#include <float.h>\r\n#include <string.h>\r\n#include <iomanip>\r\n#include <limits>\r\n#include <set>\r\n\r\n#include \"gtest/gtest-message.h\"\r\n#include \"gtest/internal/gtest-string.h\"\r\n#include \"gtest/internal/gtest-filepath.h\"\r\n#include \"gtest/internal/gtest-type-util.h\"\r\n\r\n// Due to C++ preprocessor weirdness, we need double indirection to\r\n// concatenate two tokens when one of them is __LINE__.  Writing\r\n//\r\n//   foo ## __LINE__\r\n//\r\n// will result in the token foo__LINE__, instead of foo followed by\r\n// the current line number.  For more details, see\r\n// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6\r\n#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)\r\n#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar\r\n\r\nclass ProtocolMessage;\r\nnamespace proto2 {\r\nclass Message;\r\n}\r\n\r\nnamespace testing {\r\n\r\n// Forward declarations.\r\n\r\nclass AssertionResult;                 // Result of an assertion.\r\nclass Message;                         // Represents a failure message.\r\nclass Test;                            // Represents a test.\r\nclass TestInfo;                        // Information about a test.\r\nclass TestPartResult;                  // Result of a test part.\r\nclass UnitTest;                        // A collection of test cases.\r\n\r\ntemplate <typename T>\r\n::std::string PrintToString(const T& value);\r\n\r\nnamespace internal {\r\n\r\nstruct TraceInfo;                      // Information about a trace point.\r\nclass ScopedTrace;                     // Implements scoped trace.\r\nclass TestInfoImpl;                    // Opaque implementation of TestInfo\r\nclass UnitTestImpl;                    // Opaque implementation of UnitTest\r\n\r\n// How many times InitGoogleTest() has been called.\r\nGTEST_API_ extern int g_init_gtest_count;\r\n\r\n// The text used in failure messages to indicate the start of the\r\n// stack trace.\r\nGTEST_API_ extern const char kStackTraceMarker[];\r\n\r\n// Two overloaded helpers for checking at compile time whether an\r\n// expression is a null pointer literal (i.e. NULL or any 0-valued\r\n// compile-time integral constant).  Their return values have\r\n// different sizes, so we can use sizeof() to test which version is\r\n// picked by the compiler.  These helpers have no implementations, as\r\n// we only need their signatures.\r\n//\r\n// Given IsNullLiteralHelper(x), the compiler will pick the first\r\n// version if x can be implicitly converted to Secret*, and pick the\r\n// second version otherwise.  Since Secret is a secret and incomplete\r\n// type, the only expression a user can write that has type Secret* is\r\n// a null pointer literal.  Therefore, we know that x is a null\r\n// pointer literal if and only if the first version is picked by the\r\n// compiler.\r\nchar IsNullLiteralHelper(Secret* p);\r\nchar (&IsNullLiteralHelper(...))[2];  // NOLINT\r\n\r\n// A compile-time bool constant that is true if and only if x is a\r\n// null pointer literal (i.e. NULL or any 0-valued compile-time\r\n// integral constant).\r\n#ifdef GTEST_ELLIPSIS_NEEDS_POD_\r\n// We lose support for NULL detection where the compiler doesn't like\r\n// passing non-POD classes through ellipsis (...).\r\n# define GTEST_IS_NULL_LITERAL_(x) false\r\n#else\r\n# define GTEST_IS_NULL_LITERAL_(x) \\\r\n    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)\r\n#endif  // GTEST_ELLIPSIS_NEEDS_POD_\r\n\r\n// Appends the user-supplied message to the Google-Test-generated message.\r\nGTEST_API_ std::string AppendUserMessage(\r\n  const std::string& gtest_msg, const Message& user_msg);\r\n\r\n#if GTEST_HAS_EXCEPTIONS\r\n\r\n// This exception is thrown by (and only by) a failed Google Test\r\n// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions\r\n// are enabled).  We derive it from std::runtime_error, which is for\r\n// errors presumably detectable only at run time.  Since\r\n// std::runtime_error inherits from std::exception, many testing\r\n// frameworks know how to extract and print the message inside it.\r\nclass GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {\r\n public:\r\n  explicit GoogleTestFailureException(const TestPartResult& failure);\r\n};\r\n\r\n#endif  // GTEST_HAS_EXCEPTIONS\r\n\r\n// A helper class for creating scoped traces in user programs.\r\nclass GTEST_API_ ScopedTrace {\r\n public:\r\n  // The c'tor pushes the given source file location and message onto\r\n  // a trace stack maintained by Google Test.\r\n  ScopedTrace(const char* file, int line, const Message& message);\r\n\r\n  // The d'tor pops the info pushed by the c'tor.\r\n  //\r\n  // Note that the d'tor is not virtual in order to be efficient.\r\n  // Don't inherit from ScopedTrace!\r\n  ~ScopedTrace();\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);\r\n} GTEST_ATTRIBUTE_UNUSED_;  // A ScopedTrace object does its job in its\r\n// c'tor and d'tor.  Therefore it doesn't\r\n// need to be used otherwise.\r\n\r\n// Constructs and returns the message for an equality assertion\r\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\r\n//\r\n// The first four parameters are the expressions used in the assertion\r\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\r\n// where foo is 5 and bar is 6, we have:\r\n//\r\n//   expected_expression: \"foo\"\r\n//   actual_expression:   \"bar\"\r\n//   expected_value:      \"5\"\r\n//   actual_value:        \"6\"\r\n//\r\n// The ignoring_case parameter is true iff the assertion is a\r\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\r\n// be inserted into the message.\r\nGTEST_API_ AssertionResult EqFailure(const char* expected_expression,\r\n                                     const char* actual_expression,\r\n                                     const std::string& expected_value,\r\n                                     const std::string& actual_value,\r\n                                     bool ignoring_case);\r\n\r\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\r\nGTEST_API_ std::string GetBoolAssertionFailureMessage(\r\n  const AssertionResult& assertion_result,\r\n  const char* expression_text,\r\n  const char* actual_predicate_value,\r\n  const char* expected_predicate_value);\r\n\r\n// This template class represents an IEEE floating-point number\r\n// (either single-precision or double-precision, depending on the\r\n// template parameters).\r\n//\r\n// The purpose of this class is to do more sophisticated number\r\n// comparison.  (Due to round-off error, etc, it's very unlikely that\r\n// two floating-points will be equal exactly.  Hence a naive\r\n// comparison by the == operation often doesn't work.)\r\n//\r\n// Format of IEEE floating-point:\r\n//\r\n//   The most-significant bit being the leftmost, an IEEE\r\n//   floating-point looks like\r\n//\r\n//     sign_bit exponent_bits fraction_bits\r\n//\r\n//   Here, sign_bit is a single bit that designates the sign of the\r\n//   number.\r\n//\r\n//   For float, there are 8 exponent bits and 23 fraction bits.\r\n//\r\n//   For double, there are 11 exponent bits and 52 fraction bits.\r\n//\r\n//   More details can be found at\r\n//   http://en.wikipedia.org/wiki/IEEE_floating-point_standard.\r\n//\r\n// Template parameter:\r\n//\r\n//   RawType: the raw floating-point type (either float or double)\r\ntemplate <typename RawType>\r\nclass FloatingPoint {\r\n public:\r\n  // Defines the unsigned integer type that has the same size as the\r\n  // floating point number.\r\n  typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;\r\n\r\n  // Constants.\r\n\r\n  // # of bits in a number.\r\n  static const size_t kBitCount = 8 * sizeof(RawType);\r\n\r\n  // # of fraction bits in a number.\r\n  static const size_t kFractionBitCount =\r\n    std::numeric_limits<RawType>::digits - 1;\r\n\r\n  // # of exponent bits in a number.\r\n  static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;\r\n\r\n  // The mask for the sign bit.\r\n  static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);\r\n\r\n  // The mask for the fraction bits.\r\n  static const Bits kFractionBitMask =\r\n    ~static_cast<Bits>(0) >> (kExponentBitCount + 1);\r\n\r\n  // The mask for the exponent bits.\r\n  static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);\r\n\r\n  // How many ULP's (Units in the Last Place) we want to tolerate when\r\n  // comparing two numbers.  The larger the value, the more error we\r\n  // allow.  A 0 value means that two numbers must be exactly the same\r\n  // to be considered equal.\r\n  //\r\n  // The maximum error of a single floating-point operation is 0.5\r\n  // units in the last place.  On Intel CPU's, all floating-point\r\n  // calculations are done with 80-bit precision, while double has 64\r\n  // bits.  Therefore, 4 should be enough for ordinary use.\r\n  //\r\n  // See the following article for more details on ULP:\r\n  // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/\r\n  static const size_t kMaxUlps = 4;\r\n\r\n  // Constructs a FloatingPoint from a raw floating-point number.\r\n  //\r\n  // On an Intel CPU, passing a non-normalized NAN (Not a Number)\r\n  // around may change its bits, although the new value is guaranteed\r\n  // to be also a NAN.  Therefore, don't expect this constructor to\r\n  // preserve the bits in x when x is a NAN.\r\n  explicit FloatingPoint(const RawType& x) {\r\n    u_.value_ = x;\r\n  }\r\n\r\n  // Static methods\r\n\r\n  // Reinterprets a bit pattern as a floating-point number.\r\n  //\r\n  // This function is needed to test the AlmostEquals() method.\r\n  static RawType ReinterpretBits(const Bits bits) {\r\n    FloatingPoint fp(0);\r\n    fp.u_.bits_ = bits;\r\n    return fp.u_.value_;\r\n  }\r\n\r\n  // Returns the floating-point number that represent positive infinity.\r\n  static RawType Infinity() {\r\n    return ReinterpretBits(kExponentBitMask);\r\n  }\r\n\r\n  // Returns the maximum representable finite floating-point number.\r\n  static RawType Max();\r\n\r\n  // Non-static methods\r\n\r\n  // Returns the bits that represents this number.\r\n  const Bits& bits() const {\r\n    return u_.bits_;\r\n  }\r\n\r\n  // Returns the exponent bits of this number.\r\n  Bits exponent_bits() const {\r\n    return kExponentBitMask & u_.bits_;\r\n  }\r\n\r\n  // Returns the fraction bits of this number.\r\n  Bits fraction_bits() const {\r\n    return kFractionBitMask & u_.bits_;\r\n  }\r\n\r\n  // Returns the sign bit of this number.\r\n  Bits sign_bit() const {\r\n    return kSignBitMask & u_.bits_;\r\n  }\r\n\r\n  // Returns true iff this is NAN (not a number).\r\n  bool is_nan() const {\r\n    // It's a NAN if the exponent bits are all ones and the fraction\r\n    // bits are not entirely zeros.\r\n    return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);\r\n  }\r\n\r\n  // Returns true iff this number is at most kMaxUlps ULP's away from\r\n  // rhs.  In particular, this function:\r\n  //\r\n  //   - returns false if either number is (or both are) NAN.\r\n  //   - treats really large numbers as almost equal to infinity.\r\n  //   - thinks +0.0 and -0.0 are 0 DLP's apart.\r\n  bool AlmostEquals(const FloatingPoint& rhs) const {\r\n    // The IEEE standard says that any comparison operation involving\r\n    // a NAN must return false.\r\n    if (is_nan() || rhs.is_nan()) {\r\n      return false;\r\n    }\r\n\r\n    return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)\r\n           <= kMaxUlps;\r\n  }\r\n\r\n private:\r\n  // The data type used to store the actual floating-point number.\r\n  union FloatingPointUnion {\r\n    RawType value_;  // The raw floating-point number.\r\n    Bits bits_;      // The bits that represent the number.\r\n  };\r\n\r\n  // Converts an integer from the sign-and-magnitude representation to\r\n  // the biased representation.  More precisely, let N be 2 to the\r\n  // power of (kBitCount - 1), an integer x is represented by the\r\n  // unsigned number x + N.\r\n  //\r\n  // For instance,\r\n  //\r\n  //   -N + 1 (the most negative number representable using\r\n  //          sign-and-magnitude) is represented by 1;\r\n  //   0      is represented by N; and\r\n  //   N - 1  (the biggest number representable using\r\n  //          sign-and-magnitude) is represented by 2N - 1.\r\n  //\r\n  // Read http://en.wikipedia.org/wiki/Signed_number_representations\r\n  // for more details on signed number representations.\r\n  static Bits SignAndMagnitudeToBiased(const Bits& sam) {\r\n    if (kSignBitMask & sam) {\r\n      // sam represents a negative number.\r\n      return ~sam + 1;\r\n    }\r\n    else {\r\n      // sam represents a positive number.\r\n      return kSignBitMask | sam;\r\n    }\r\n  }\r\n\r\n  // Given two numbers in the sign-and-magnitude representation,\r\n  // returns the distance between them as an unsigned number.\r\n  static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,\r\n      const Bits& sam2) {\r\n    const Bits biased1 = SignAndMagnitudeToBiased(sam1);\r\n    const Bits biased2 = SignAndMagnitudeToBiased(sam2);\r\n    return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);\r\n  }\r\n\r\n  FloatingPointUnion u_;\r\n};\r\n\r\n// We cannot use std::numeric_limits<T>::max() as it clashes with the max()\r\n// macro defined by <windows.h>.\r\ntemplate <>\r\ninline float FloatingPoint<float>::Max() {\r\n  return FLT_MAX;\r\n}\r\ntemplate <>\r\ninline double FloatingPoint<double>::Max() {\r\n  return DBL_MAX;\r\n}\r\n\r\n// Typedefs the instances of the FloatingPoint template class that we\r\n// care to use.\r\ntypedef FloatingPoint<float> Float;\r\ntypedef FloatingPoint<double> Double;\r\n\r\n// In order to catch the mistake of putting tests that use different\r\n// test fixture classes in the same test case, we need to assign\r\n// unique IDs to fixture classes and compare them.  The TypeId type is\r\n// used to hold such IDs.  The user should treat TypeId as an opaque\r\n// type: the only operation allowed on TypeId values is to compare\r\n// them for equality using the == operator.\r\ntypedef const void* TypeId;\r\n\r\ntemplate <typename T>\r\nclass TypeIdHelper {\r\n public:\r\n  // dummy_ must not have a const type.  Otherwise an overly eager\r\n  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge\r\n  // TypeIdHelper<T>::dummy_ for different Ts as an \"optimization\".\r\n  static bool dummy_;\r\n};\r\n\r\ntemplate <typename T>\r\nbool TypeIdHelper<T>::dummy_ = false;\r\n\r\n// GetTypeId<T>() returns the ID of type T.  Different values will be\r\n// returned for different types.  Calling the function twice with the\r\n// same type argument is guaranteed to return the same ID.\r\ntemplate <typename T>\r\nTypeId GetTypeId() {\r\n  // The compiler is required to allocate a different\r\n  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate\r\n  // the template.  Therefore, the address of dummy_ is guaranteed to\r\n  // be unique.\r\n  return &(TypeIdHelper<T>::dummy_);\r\n}\r\n\r\n// Returns the type ID of ::testing::Test.  Always call this instead\r\n// of GetTypeId< ::testing::Test>() to get the type ID of\r\n// ::testing::Test, as the latter may give the wrong result due to a\r\n// suspected linker bug when compiling Google Test as a Mac OS X\r\n// framework.\r\nGTEST_API_ TypeId GetTestTypeId();\r\n\r\n// Defines the abstract factory interface that creates instances\r\n// of a Test object.\r\nclass TestFactoryBase {\r\n public:\r\n  virtual ~TestFactoryBase() {}\r\n\r\n  // Creates a test instance to run. The instance is both created and destroyed\r\n  // within TestInfoImpl::Run()\r\n  virtual Test* CreateTest() = 0;\r\n\r\n protected:\r\n  TestFactoryBase() {}\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);\r\n};\r\n\r\n// This class provides implementation of TeastFactoryBase interface.\r\n// It is used in TEST and TEST_F macros.\r\ntemplate <class TestClass>\r\nclass TestFactoryImpl : public TestFactoryBase {\r\n public:\r\n  virtual Test* CreateTest() {\r\n    return new TestClass;\r\n  }\r\n};\r\n\r\n#if GTEST_OS_WINDOWS\r\n\r\n// Predicate-formatters for implementing the HRESULT checking macros\r\n// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}\r\n// We pass a long instead of HRESULT to avoid causing an\r\n// include dependency for the HRESULT type.\r\nGTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,\r\n    long hr);  // NOLINT\r\nGTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,\r\n    long hr);  // NOLINT\r\n\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Types of SetUpTestCase() and TearDownTestCase() functions.\r\ntypedef void (*SetUpTestCaseFunc)();\r\ntypedef void (*TearDownTestCaseFunc)();\r\n\r\n// Creates a new TestInfo object and registers it with Google Test;\r\n// returns the created object.\r\n//\r\n// Arguments:\r\n//\r\n//   test_case_name:   name of the test case\r\n//   name:             name of the test\r\n//   type_param        the name of the test's type parameter, or NULL if\r\n//                     this is not a typed or a type-parameterized test.\r\n//   value_param       text representation of the test's value parameter,\r\n//                     or NULL if this is not a type-parameterized test.\r\n//   fixture_class_id: ID of the test fixture class\r\n//   set_up_tc:        pointer to the function that sets up the test case\r\n//   tear_down_tc:     pointer to the function that tears down the test case\r\n//   factory:          pointer to the factory that creates a test object.\r\n//                     The newly created TestInfo instance will assume\r\n//                     ownership of the factory object.\r\nGTEST_API_ TestInfo* MakeAndRegisterTestInfo(\r\n  const char* test_case_name,\r\n  const char* name,\r\n  const char* type_param,\r\n  const char* value_param,\r\n  TypeId fixture_class_id,\r\n  SetUpTestCaseFunc set_up_tc,\r\n  TearDownTestCaseFunc tear_down_tc,\r\n  TestFactoryBase* factory);\r\n\r\n// If *pstr starts with the given prefix, modifies *pstr to be right\r\n// past the prefix and returns true; otherwise leaves *pstr unchanged\r\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\r\nGTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);\r\n\r\n#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n// State of the definition of a type-parameterized test case.\r\nclass GTEST_API_ TypedTestCasePState {\r\n public:\r\n  TypedTestCasePState() : registered_(false) {}\r\n\r\n  // Adds the given test name to defined_test_names_ and return true\r\n  // if the test case hasn't been registered; otherwise aborts the\r\n  // program.\r\n  bool AddTestName(const char* file, int line, const char* case_name,\r\n                   const char* test_name) {\r\n    if (registered_) {\r\n      fprintf(stderr, \"%s Test %s must be defined before \"\r\n              \"REGISTER_TYPED_TEST_CASE_P(%s, ...).\\n\",\r\n              FormatFileLocation(file, line).c_str(), test_name, case_name);\r\n      fflush(stderr);\r\n      posix::Abort();\r\n    }\r\n\r\n    defined_test_names_.insert(test_name);\r\n    return true;\r\n  }\r\n\r\n  // Verifies that registered_tests match the test names in\r\n  // defined_test_names_; returns registered_tests if successful, or\r\n  // aborts the program otherwise.\r\n  const char* VerifyRegisteredTestNames(\r\n    const char* file, int line, const char* registered_tests);\r\n\r\n private:\r\n  bool registered_;\r\n  ::std::set<const char*> defined_test_names_;\r\n};\r\n\r\n// Skips to the first non-space char after the first comma in 'str';\r\n// returns NULL if no comma is found in 'str'.\r\ninline const char* SkipComma(const char* str) {\r\n  const char* comma = strchr(str, ',');\r\n\r\n  if (comma == NULL) {\r\n    return NULL;\r\n  }\r\n\r\n  while (IsSpace(*(++comma))) {}\r\n\r\n  return comma;\r\n}\r\n\r\n// Returns the prefix of 'str' before the first comma in it; returns\r\n// the entire string if it contains no comma.\r\ninline std::string GetPrefixUntilComma(const char* str) {\r\n  const char* comma = strchr(str, ',');\r\n  return comma == NULL ? str : std::string(str, comma);\r\n}\r\n\r\n// TypeParameterizedTest<Fixture, TestSel, Types>::Register()\r\n// registers a list of type-parameterized tests with Google Test.  The\r\n// return value is insignificant - we just need to return something\r\n// such that we can call this function in a namespace scope.\r\n//\r\n// Implementation note: The GTEST_TEMPLATE_ macro declares a template\r\n// template parameter.  It's defined in gtest-type-util.h.\r\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>\r\nclass TypeParameterizedTest {\r\n public:\r\n  // 'index' is the index of the test in the type list 'Types'\r\n  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,\r\n  // Types).  Valid values for 'index' are [0, N - 1] where N is the\r\n  // length of Types.\r\n  static bool Register(const char* prefix, const char* case_name,\r\n                       const char* test_names, int index) {\r\n    typedef typename Types::Head Type;\r\n    typedef Fixture<Type> FixtureClass;\r\n    typedef typename GTEST_BIND_(TestSel, Type) TestClass;\r\n\r\n    // First, registers the first type-parameterized test in the type\r\n    // list.\r\n    MakeAndRegisterTestInfo(\r\n      (std::string(prefix) + (prefix[0] == '\\0' ? \"\" : \"/\") + case_name + \"/\"\r\n       + StreamableToString(index)).c_str(),\r\n      GetPrefixUntilComma(test_names).c_str(),\r\n      GetTypeName<Type>().c_str(),\r\n      NULL,  // No value parameter.\r\n      GetTypeId<FixtureClass>(),\r\n      TestClass::SetUpTestCase,\r\n      TestClass::TearDownTestCase,\r\n      new TestFactoryImpl<TestClass>);\r\n\r\n    // Next, recurses (at compile time) with the tail of the type list.\r\n    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>\r\n           ::Register(prefix, case_name, test_names, index + 1);\r\n  }\r\n};\r\n\r\n// The base case for the compile time recursion.\r\ntemplate <GTEST_TEMPLATE_ Fixture, class TestSel>\r\nclass TypeParameterizedTest<Fixture, TestSel, Types0> {\r\n public:\r\n  static bool Register(const char* /*prefix*/, const char* /*case_name*/,\r\n                       const char* /*test_names*/, int /*index*/) {\r\n    return true;\r\n  }\r\n};\r\n\r\n// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()\r\n// registers *all combinations* of 'Tests' and 'Types' with Google\r\n// Test.  The return value is insignificant - we just need to return\r\n// something such that we can call this function in a namespace scope.\r\ntemplate <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>\r\nclass TypeParameterizedTestCase {\r\n public:\r\n  static bool Register(const char* prefix, const char* case_name,\r\n                       const char* test_names) {\r\n    typedef typename Tests::Head Head;\r\n\r\n    // First, register the first test in 'Test' for each type in 'Types'.\r\n    TypeParameterizedTest<Fixture, Head, Types>::Register(\r\n      prefix, case_name, test_names, 0);\r\n\r\n    // Next, recurses (at compile time) with the tail of the test list.\r\n    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>\r\n           ::Register(prefix, case_name, SkipComma(test_names));\r\n  }\r\n};\r\n\r\n// The base case for the compile time recursion.\r\ntemplate <GTEST_TEMPLATE_ Fixture, typename Types>\r\nclass TypeParameterizedTestCase<Fixture, Templates0, Types> {\r\n public:\r\n  static bool Register(const char* /*prefix*/, const char* /*case_name*/,\r\n                       const char* /*test_names*/) {\r\n    return true;\r\n  }\r\n};\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n// Returns the current OS stack trace as an std::string.\r\n//\r\n// The maximum number of stack frames to be included is specified by\r\n// the gtest_stack_trace_depth flag.  The skip_count parameter\r\n// specifies the number of top frames to be skipped, which doesn't\r\n// count against the number of frames to be included.\r\n//\r\n// For example, if Foo() calls Bar(), which in turn calls\r\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\r\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\r\nGTEST_API_ std::string GetCurrentOsStackTraceExceptTop(\r\n  UnitTest* unit_test, int skip_count);\r\n\r\n// Helpers for suppressing warnings on unreachable code or constant\r\n// condition.\r\n\r\n// Always returns true.\r\nGTEST_API_ bool AlwaysTrue();\r\n\r\n// Always returns false.\r\ninline bool AlwaysFalse() {\r\n  return !AlwaysTrue();\r\n}\r\n\r\n// Helper for suppressing false warning from Clang on a const char*\r\n// variable declared in a conditional expression always being NULL in\r\n// the else branch.\r\nstruct GTEST_API_ ConstCharPtr {\r\n  ConstCharPtr(const char* str) : value(str) {}\r\n  operator bool() const {\r\n    return true;\r\n  }\r\n  const char* value;\r\n};\r\n\r\n// A simple Linear Congruential Generator for generating random\r\n// numbers with a uniform distribution.  Unlike rand() and srand(), it\r\n// doesn't use global state (and therefore can't interfere with user\r\n// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,\r\n// but it's good enough for our purposes.\r\nclass GTEST_API_ Random {\r\n public:\r\n  static const UInt32 kMaxRange = 1u << 31;\r\n\r\n  explicit Random(UInt32 seed) : state_(seed) {}\r\n\r\n  void Reseed(UInt32 seed) {\r\n    state_ = seed;\r\n  }\r\n\r\n  // Generates a random number from [0, range).  Crashes if 'range' is\r\n  // 0 or greater than kMaxRange.\r\n  UInt32 Generate(UInt32 range);\r\n\r\n private:\r\n  UInt32 state_;\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);\r\n};\r\n\r\n// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a\r\n// compiler error iff T1 and T2 are different types.\r\ntemplate <typename T1, typename T2>\r\nstruct CompileAssertTypesEqual;\r\n\r\ntemplate <typename T>\r\nstruct CompileAssertTypesEqual<T, T> {\r\n};\r\n\r\n// Removes the reference from a type if it is a reference type,\r\n// otherwise leaves it unchanged.  This is the same as\r\n// tr1::remove_reference, which is not widely available yet.\r\ntemplate <typename T>\r\nstruct RemoveReference {\r\n  typedef T type;\r\n};  // NOLINT\r\ntemplate <typename T>\r\nstruct RemoveReference<T&> {\r\n  typedef T type;\r\n};  // NOLINT\r\n\r\n// A handy wrapper around RemoveReference that works when the argument\r\n// T depends on template parameters.\r\n#define GTEST_REMOVE_REFERENCE_(T) \\\r\n    typename ::testing::internal::RemoveReference<T>::type\r\n\r\n// Removes const from a type if it is a const type, otherwise leaves\r\n// it unchanged.  This is the same as tr1::remove_const, which is not\r\n// widely available yet.\r\ntemplate <typename T>\r\nstruct RemoveConst {\r\n  typedef T type;\r\n};  // NOLINT\r\ntemplate <typename T>\r\nstruct RemoveConst<const T> {\r\n  typedef T type;\r\n};  // NOLINT\r\n\r\n// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above\r\n// definition to fail to remove the const in 'const int[3]' and 'const\r\n// char[3][4]'.  The following specialization works around the bug.\r\ntemplate <typename T, size_t N>\r\nstruct RemoveConst<const T[N]> {\r\n  typedef typename RemoveConst<T>::type type[N];\r\n};\r\n\r\n#if defined(_MSC_VER) && _MSC_VER < 1400\r\n// This is the only specialization that allows VC++ 7.1 to remove const in\r\n// 'const int[3] and 'const int[3][4]'.  However, it causes trouble with GCC\r\n// and thus needs to be conditionally compiled.\r\ntemplate <typename T, size_t N>\r\nstruct RemoveConst<T[N]> {\r\n  typedef typename RemoveConst<T>::type type[N];\r\n};\r\n#endif\r\n\r\n// A handy wrapper around RemoveConst that works when the argument\r\n// T depends on template parameters.\r\n#define GTEST_REMOVE_CONST_(T) \\\r\n    typename ::testing::internal::RemoveConst<T>::type\r\n\r\n// Turns const U&, U&, const U, and U all into U.\r\n#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \\\r\n    GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))\r\n\r\n// Adds reference to a type if it is not a reference type,\r\n// otherwise leaves it unchanged.  This is the same as\r\n// tr1::add_reference, which is not widely available yet.\r\ntemplate <typename T>\r\nstruct AddReference {\r\n  typedef T& type;\r\n};  // NOLINT\r\ntemplate <typename T>\r\nstruct AddReference<T&> {\r\n  typedef T& type;\r\n};  // NOLINT\r\n\r\n// A handy wrapper around AddReference that works when the argument T\r\n// depends on template parameters.\r\n#define GTEST_ADD_REFERENCE_(T) \\\r\n    typename ::testing::internal::AddReference<T>::type\r\n\r\n// Adds a reference to const on top of T as necessary.  For example,\r\n// it transforms\r\n//\r\n//   char         ==> const char&\r\n//   const char   ==> const char&\r\n//   char&        ==> const char&\r\n//   const char&  ==> const char&\r\n//\r\n// The argument T must depend on some template parameters.\r\n#define GTEST_REFERENCE_TO_CONST_(T) \\\r\n    GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))\r\n\r\n// ImplicitlyConvertible<From, To>::value is a compile-time bool\r\n// constant that's true iff type From can be implicitly converted to\r\n// type To.\r\ntemplate <typename From, typename To>\r\nclass ImplicitlyConvertible {\r\n private:\r\n  // We need the following helper functions only for their types.\r\n  // They have no implementations.\r\n\r\n  // MakeFrom() is an expression whose type is From.  We cannot simply\r\n  // use From(), as the type From may not have a public default\r\n  // constructor.\r\n  static From MakeFrom();\r\n\r\n  // These two functions are overloaded.  Given an expression\r\n  // Helper(x), the compiler will pick the first version if x can be\r\n  // implicitly converted to type To; otherwise it will pick the\r\n  // second version.\r\n  //\r\n  // The first version returns a value of size 1, and the second\r\n  // version returns a value of size 2.  Therefore, by checking the\r\n  // size of Helper(x), which can be done at compile time, we can tell\r\n  // which version of Helper() is used, and hence whether x can be\r\n  // implicitly converted to type To.\r\n  static char Helper(To);\r\n  static char (&Helper(...))[2];  // NOLINT\r\n\r\n  // We have to put the 'public' section after the 'private' section,\r\n  // or MSVC refuses to compile the code.\r\n public:\r\n  // MSVC warns about implicitly converting from double to int for\r\n  // possible loss of data, so we need to temporarily disable the\r\n  // warning.\r\n#ifdef _MSC_VER\r\n# pragma warning(push)          // Saves the current warning state.\r\n# pragma warning(disable:4244)  // Temporarily disables warning 4244.\r\n\r\n  static const bool value =\r\n    sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;\r\n# pragma warning(pop)           // Restores the warning state.\r\n#elif defined(__BORLANDC__)\r\n  // C++Builder cannot use member overload resolution during template\r\n  // instantiation.  The simplest workaround is to use its C++0x type traits\r\n  // functions (C++Builder 2009 and above only).\r\n  static const bool value = __is_convertible(From, To);\r\n#else\r\n  static const bool value =\r\n    sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;\r\n#endif  // _MSV_VER\r\n};\r\ntemplate <typename From, typename To>\r\nconst bool ImplicitlyConvertible<From, To>::value;\r\n\r\n// IsAProtocolMessage<T>::value is a compile-time bool constant that's\r\n// true iff T is type ProtocolMessage, proto2::Message, or a subclass\r\n// of those.\r\ntemplate <typename T>\r\nstruct IsAProtocolMessage\r\n  : public bool_constant <\r\n    ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||\r\n    ImplicitlyConvertible<const T*, const ::proto2::Message*>::value > {\r\n};\r\n\r\n// When the compiler sees expression IsContainerTest<C>(0), if C is an\r\n// STL-style container class, the first overload of IsContainerTest\r\n// will be viable (since both C::iterator* and C::const_iterator* are\r\n// valid types and NULL can be implicitly converted to them).  It will\r\n// be picked over the second overload as 'int' is a perfect match for\r\n// the type of argument 0.  If C::iterator or C::const_iterator is not\r\n// a valid type, the first overload is not viable, and the second\r\n// overload will be picked.  Therefore, we can determine whether C is\r\n// a container class by checking the type of IsContainerTest<C>(0).\r\n// The value of the expression is insignificant.\r\n//\r\n// Note that we look for both C::iterator and C::const_iterator.  The\r\n// reason is that C++ injects the name of a class as a member of the\r\n// class itself (e.g. you can refer to class iterator as either\r\n// 'iterator' or 'iterator::iterator').  If we look for C::iterator\r\n// only, for example, we would mistakenly think that a class named\r\n// iterator is an STL container.\r\n//\r\n// Also note that the simpler approach of overloading\r\n// IsContainerTest(typename C::const_iterator*) and\r\n// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.\r\ntypedef int IsContainer;\r\ntemplate <class C>\r\nIsContainer IsContainerTest(int /* dummy */,\r\n                            typename C::iterator* /* it */ = NULL,\r\n                            typename C::const_iterator* /* const_it */ = NULL) {\r\n  return 0;\r\n}\r\n\r\ntypedef char IsNotContainer;\r\ntemplate <class C>\r\nIsNotContainer IsContainerTest(long /* dummy */) {\r\n  return '\\0';\r\n}\r\n\r\n// EnableIf<condition>::type is void when 'Cond' is true, and\r\n// undefined when 'Cond' is false.  To use SFINAE to make a function\r\n// overload only apply when a particular expression is true, add\r\n// \"typename EnableIf<expression>::type* = 0\" as the last parameter.\r\ntemplate<bool> struct EnableIf;\r\ntemplate<> struct EnableIf<true> {\r\n  typedef void type;\r\n};  // NOLINT\r\n\r\n// Utilities for native arrays.\r\n\r\n// ArrayEq() compares two k-dimensional native arrays using the\r\n// elements' operator==, where k can be any integer >= 0.  When k is\r\n// 0, ArrayEq() degenerates into comparing a single pair of values.\r\n\r\ntemplate <typename T, typename U>\r\nbool ArrayEq(const T* lhs, size_t size, const U* rhs);\r\n\r\n// This generic version is used when k is 0.\r\ntemplate <typename T, typename U>\r\ninline bool ArrayEq(const T& lhs, const U& rhs) {\r\n  return lhs == rhs;\r\n}\r\n\r\n// This overload is used when k >= 1.\r\ntemplate <typename T, typename U, size_t N>\r\ninline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) {\r\n  return internal::ArrayEq(lhs, N, rhs);\r\n}\r\n\r\n// This helper reduces code bloat.  If we instead put its logic inside\r\n// the previous ArrayEq() function, arrays with different sizes would\r\n// lead to different copies of the template code.\r\ntemplate <typename T, typename U>\r\nbool ArrayEq(const T* lhs, size_t size, const U* rhs) {\r\n  for (size_t i = 0; i != size; i++) {\r\n    if (!internal::ArrayEq(lhs[i], rhs[i])) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\n// Finds the first element in the iterator range [begin, end) that\r\n// equals elem.  Element may be a native array type itself.\r\ntemplate <typename Iter, typename Element>\r\nIter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {\r\n  for (Iter it = begin; it != end; ++it) {\r\n    if (internal::ArrayEq(*it, elem)) {\r\n      return it;\r\n    }\r\n  }\r\n\r\n  return end;\r\n}\r\n\r\n// CopyArray() copies a k-dimensional native array using the elements'\r\n// operator=, where k can be any integer >= 0.  When k is 0,\r\n// CopyArray() degenerates into copying a single value.\r\n\r\ntemplate <typename T, typename U>\r\nvoid CopyArray(const T* from, size_t size, U* to);\r\n\r\n// This generic version is used when k is 0.\r\ntemplate <typename T, typename U>\r\ninline void CopyArray(const T& from, U* to) {\r\n  *to = from;\r\n}\r\n\r\n// This overload is used when k >= 1.\r\ntemplate <typename T, typename U, size_t N>\r\ninline void CopyArray(const T(&from)[N], U(*to)[N]) {\r\n  internal::CopyArray(from, N, *to);\r\n}\r\n\r\n// This helper reduces code bloat.  If we instead put its logic inside\r\n// the previous CopyArray() function, arrays with different sizes\r\n// would lead to different copies of the template code.\r\ntemplate <typename T, typename U>\r\nvoid CopyArray(const T* from, size_t size, U* to) {\r\n  for (size_t i = 0; i != size; i++) {\r\n    internal::CopyArray(from[i], to + i);\r\n  }\r\n}\r\n\r\n// The relation between an NativeArray object (see below) and the\r\n// native array it represents.\r\nenum RelationToSource {\r\n  kReference,  // The NativeArray references the native array.\r\n  kCopy        // The NativeArray makes a copy of the native array and\r\n  // owns the copy.\r\n};\r\n\r\n// Adapts a native array to a read-only STL-style container.  Instead\r\n// of the complete STL container concept, this adaptor only implements\r\n// members useful for Google Mock's container matchers.  New members\r\n// should be added as needed.  To simplify the implementation, we only\r\n// support Element being a raw type (i.e. having no top-level const or\r\n// reference modifier).  It's the client's responsibility to satisfy\r\n// this requirement.  Element can be an array type itself (hence\r\n// multi-dimensional arrays are supported).\r\ntemplate <typename Element>\r\nclass NativeArray {\r\n public:\r\n  // STL-style container typedefs.\r\n  typedef Element value_type;\r\n  typedef Element* iterator;\r\n  typedef const Element* const_iterator;\r\n\r\n  // Constructs from a native array.\r\n  NativeArray(const Element* array, size_t count, RelationToSource relation) {\r\n    Init(array, count, relation);\r\n  }\r\n\r\n  // Copy constructor.\r\n  NativeArray(const NativeArray& rhs) {\r\n    Init(rhs.array_, rhs.size_, rhs.relation_to_source_);\r\n  }\r\n\r\n  ~NativeArray() {\r\n    // Ensures that the user doesn't instantiate NativeArray with a\r\n    // const or reference type.\r\n    static_cast<void>(StaticAssertTypeEqHelper<Element,\r\n                      GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>());\r\n\r\n    if (relation_to_source_ == kCopy) {\r\n      delete[] array_;\r\n    }\r\n  }\r\n\r\n  // STL-style container methods.\r\n  size_t size() const {\r\n    return size_;\r\n  }\r\n  const_iterator begin() const {\r\n    return array_;\r\n  }\r\n  const_iterator end() const {\r\n    return array_ + size_;\r\n  }\r\n  bool operator==(const NativeArray& rhs) const {\r\n    return size() == rhs.size() &&\r\n           ArrayEq(begin(), size(), rhs.begin());\r\n  }\r\n\r\n private:\r\n  // Initializes this object; makes a copy of the input array if\r\n  // 'relation' is kCopy.\r\n  void Init(const Element* array, size_t a_size, RelationToSource relation) {\r\n    if (relation == kReference) {\r\n      array_ = array;\r\n    }\r\n    else {\r\n      Element* const copy = new Element[a_size];\r\n      CopyArray(array, a_size, copy);\r\n      array_ = copy;\r\n    }\r\n\r\n    size_ = a_size;\r\n    relation_to_source_ = relation;\r\n  }\r\n\r\n  const Element* array_;\r\n  size_t size_;\r\n  RelationToSource relation_to_source_;\r\n\r\n  GTEST_DISALLOW_ASSIGN_(NativeArray);\r\n};\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#define GTEST_MESSAGE_AT_(file, line, message, result_type) \\\r\n  ::testing::internal::AssertHelper(result_type, file, line, message) \\\r\n    = ::testing::Message()\r\n\r\n#define GTEST_MESSAGE_(message, result_type) \\\r\n  GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)\r\n\r\n#define GTEST_FATAL_FAILURE_(message) \\\r\n  return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)\r\n\r\n#define GTEST_NONFATAL_FAILURE_(message) \\\r\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)\r\n\r\n#define GTEST_SUCCESS_(message) \\\r\n  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)\r\n\r\n// Suppresses MSVC warnings 4072 (unreachable code) for the code following\r\n// statement if it returns or throws (or doesn't return or throw in some\r\n// situations).\r\n#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \\\r\n  if (::testing::internal::AlwaysTrue()) { statement; }\r\n\r\n#define GTEST_TEST_THROW_(statement, expected_exception, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::ConstCharPtr gtest_msg = \"\") { \\\r\n    bool gtest_caught_expected = false; \\\r\n    try { \\\r\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n    } \\\r\n    catch (expected_exception const&) { \\\r\n      gtest_caught_expected = true; \\\r\n    } \\\r\n    catch (...) { \\\r\n      gtest_msg.value = \\\r\n          \"Expected: \" #statement \" throws an exception of type \" \\\r\n          #expected_exception \".\\n  Actual: it throws a different type.\"; \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \\\r\n    } \\\r\n    if (!gtest_caught_expected) { \\\r\n      gtest_msg.value = \\\r\n          \"Expected: \" #statement \" throws an exception of type \" \\\r\n          #expected_exception \".\\n  Actual: it throws nothing.\"; \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \\\r\n    } \\\r\n  } else \\\r\n    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \\\r\n      fail(gtest_msg.value)\r\n\r\n#define GTEST_TEST_NO_THROW_(statement, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::AlwaysTrue()) { \\\r\n    try { \\\r\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n    } \\\r\n    catch (...) { \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \\\r\n    } \\\r\n  } else \\\r\n    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \\\r\n      fail(\"Expected: \" #statement \" doesn't throw an exception.\\n\" \\\r\n           \"  Actual: it throws.\")\r\n\r\n#define GTEST_TEST_ANY_THROW_(statement, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::AlwaysTrue()) { \\\r\n    bool gtest_caught_any = false; \\\r\n    try { \\\r\n      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n    } \\\r\n    catch (...) { \\\r\n      gtest_caught_any = true; \\\r\n    } \\\r\n    if (!gtest_caught_any) { \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \\\r\n    } \\\r\n  } else \\\r\n    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \\\r\n      fail(\"Expected: \" #statement \" throws an exception.\\n\" \\\r\n           \"  Actual: it doesn't.\")\r\n\r\n\r\n// Implements Boolean test assertions such as EXPECT_TRUE. expression can be\r\n// either a boolean expression or an AssertionResult. text is a textual\r\n// represenation of expression as it was passed into the EXPECT_TRUE.\r\n#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (const ::testing::AssertionResult gtest_ar_ = \\\r\n      ::testing::AssertionResult(expression)) \\\r\n    ; \\\r\n  else \\\r\n    fail(::testing::internal::GetBoolAssertionFailureMessage(\\\r\n        gtest_ar_, text, #actual, #expected).c_str())\r\n\r\n#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \\\r\n  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n  if (::testing::internal::AlwaysTrue()) { \\\r\n    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \\\r\n    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \\\r\n    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \\\r\n      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \\\r\n    } \\\r\n  } else \\\r\n    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \\\r\n      fail(\"Expected: \" #statement \" doesn't generate new fatal \" \\\r\n           \"failures in the current thread.\\n\" \\\r\n           \"  Actual: it does.\")\r\n\r\n// Expands to the name of the class that implements the given test.\r\n#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \\\r\n  test_case_name##_##test_name##_Test\r\n\r\n// Helper macro for defining tests.\r\n#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\\\r\nclass GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\\\r\n public:\\\r\n  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\\\r\n private:\\\r\n  virtual void TestBody();\\\r\n  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\\\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(\\\r\n      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\\\r\n};\\\r\n\\\r\n::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\\\r\n  ::test_info_ =\\\r\n    ::testing::internal::MakeAndRegisterTestInfo(\\\r\n        #test_case_name, #test_name, NULL, NULL, \\\r\n        (parent_id), \\\r\n        parent_class::SetUpTestCase, \\\r\n        parent_class::TearDownTestCase, \\\r\n        new ::testing::internal::TestFactoryImpl<\\\r\n            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\\\r\nvoid GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-linked_ptr.h",
    "content": "// Copyright 2003 Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: Dan Egnor (egnor@google.com)\r\n//\r\n// A \"smart\" pointer type with reference tracking.  Every pointer to a\r\n// particular object is kept on a circular linked list.  When the last pointer\r\n// to an object is destroyed or reassigned, the object is deleted.\r\n//\r\n// Used properly, this deletes the object when the last reference goes away.\r\n// There are several caveats:\r\n// - Like all reference counting schemes, cycles lead to leaks.\r\n// - Each smart pointer is actually two pointers (8 bytes instead of 4).\r\n// - Every time a pointer is assigned, the entire list of pointers to that\r\n//   object is traversed.  This class is therefore NOT SUITABLE when there\r\n//   will often be more than two or three pointers to a particular object.\r\n// - References are only tracked as long as linked_ptr<> objects are copied.\r\n//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS\r\n//   will happen (double deletion).\r\n//\r\n// A good use of this class is storing object references in STL containers.\r\n// You can safely put linked_ptr<> in a vector<>.\r\n// Other uses may not be as good.\r\n//\r\n// Note: If you use an incomplete type with linked_ptr<>, the class\r\n// *containing* linked_ptr<> must have a constructor and destructor (even\r\n// if they do nothing!).\r\n//\r\n// Bill Gibbons suggested we use something like this.\r\n//\r\n// Thread Safety:\r\n//   Unlike other linked_ptr implementations, in this implementation\r\n//   a linked_ptr object is thread-safe in the sense that:\r\n//     - it's safe to copy linked_ptr objects concurrently,\r\n//     - it's safe to copy *from* a linked_ptr and read its underlying\r\n//       raw pointer (e.g. via get()) concurrently, and\r\n//     - it's safe to write to two linked_ptrs that point to the same\r\n//       shared object concurrently.\r\n// TODO(wan@google.com): rename this to safe_linked_ptr to avoid\r\n// confusion with normal linked_ptr.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\r\n\r\n#include <stdlib.h>\r\n#include <assert.h>\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// Protects copying of all linked_ptr objects.\r\nGTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);\r\n\r\n// This is used internally by all instances of linked_ptr<>.  It needs to be\r\n// a non-template class because different types of linked_ptr<> can refer to\r\n// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).\r\n// So, it needs to be possible for different types of linked_ptr to participate\r\n// in the same circular linked list, so we need a single class type here.\r\n//\r\n// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.\r\nclass linked_ptr_internal {\r\n public:\r\n  // Create a new circle that includes only this instance.\r\n  void join_new() {\r\n    next_ = this;\r\n  }\r\n\r\n  // Many linked_ptr operations may change p.link_ for some linked_ptr\r\n  // variable p in the same circle as this object.  Therefore we need\r\n  // to prevent two such operations from occurring concurrently.\r\n  //\r\n  // Note that different types of linked_ptr objects can coexist in a\r\n  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and\r\n  // linked_ptr<Derived2>).  Therefore we must use a single mutex to\r\n  // protect all linked_ptr objects.  This can create serious\r\n  // contention in production code, but is acceptable in a testing\r\n  // framework.\r\n\r\n  // Join an existing circle.\r\n  void join(linked_ptr_internal const* ptr)\r\n  GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {\r\n    MutexLock lock(&g_linked_ptr_mutex);\r\n\r\n    linked_ptr_internal const* p = ptr;\r\n\r\n    while (p->next_ != ptr) {\r\n      p = p->next_;\r\n    }\r\n\r\n    p->next_ = this;\r\n    next_ = ptr;\r\n  }\r\n\r\n  // Leave whatever circle we're part of.  Returns true if we were the\r\n  // last member of the circle.  Once this is done, you can join() another.\r\n  bool depart()\r\n  GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {\r\n    MutexLock lock(&g_linked_ptr_mutex);\r\n\r\n    if (next_ == this) {\r\n      return true;\r\n    }\r\n\r\n    linked_ptr_internal const* p = next_;\r\n\r\n    while (p->next_ != this) {\r\n      p = p->next_;\r\n    }\r\n\r\n    p->next_ = next_;\r\n    return false;\r\n  }\r\n\r\n private:\r\n  mutable linked_ptr_internal const* next_;\r\n};\r\n\r\ntemplate <typename T>\r\nclass linked_ptr {\r\n public:\r\n  typedef T element_type;\r\n\r\n  // Take over ownership of a raw pointer.  This should happen as soon as\r\n  // possible after the object is created.\r\n  explicit linked_ptr(T* ptr = NULL) {\r\n    capture(ptr);\r\n  }\r\n  ~linked_ptr() {\r\n    depart();\r\n  }\r\n\r\n  // Copy an existing linked_ptr<>, adding ourselves to the list of references.\r\n  template <typename U> linked_ptr(linked_ptr<U> const& ptr) {\r\n    copy(&ptr);\r\n  }\r\n  linked_ptr(linked_ptr const& ptr) {  // NOLINT\r\n    assert(&ptr != this);\r\n    copy(&ptr);\r\n  }\r\n\r\n  // Assignment releases the old value and acquires the new.\r\n  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {\r\n    depart();\r\n    copy(&ptr);\r\n    return *this;\r\n  }\r\n\r\n  linked_ptr& operator=(linked_ptr const& ptr) {\r\n    if (&ptr != this) {\r\n      depart();\r\n      copy(&ptr);\r\n    }\r\n\r\n    return *this;\r\n  }\r\n\r\n  // Smart pointer members.\r\n  void reset(T* ptr = NULL) {\r\n    depart();\r\n    capture(ptr);\r\n  }\r\n  T* get() const {\r\n    return value_;\r\n  }\r\n  T* operator->() const {\r\n    return value_;\r\n  }\r\n  T& operator*() const {\r\n    return *value_;\r\n  }\r\n\r\n  bool operator==(T* p) const {\r\n    return value_ == p;\r\n  }\r\n  bool operator!=(T* p) const {\r\n    return value_ != p;\r\n  }\r\n  template <typename U>\r\n  bool operator==(linked_ptr<U> const& ptr) const {\r\n    return value_ == ptr.get();\r\n  }\r\n  template <typename U>\r\n  bool operator!=(linked_ptr<U> const& ptr) const {\r\n    return value_ != ptr.get();\r\n  }\r\n\r\n private:\r\n  template <typename U>\r\n  friend class linked_ptr;\r\n\r\n  T* value_;\r\n  linked_ptr_internal link_;\r\n\r\n  void depart() {\r\n    if (link_.depart()) {\r\n      delete value_;\r\n    }\r\n  }\r\n\r\n  void capture(T* ptr) {\r\n    value_ = ptr;\r\n    link_.join_new();\r\n  }\r\n\r\n  template <typename U> void copy(linked_ptr<U> const* ptr) {\r\n    value_ = ptr->get();\r\n\r\n    if (value_) {\r\n      link_.join(&ptr->link_);\r\n    }\r\n    else {\r\n      link_.join_new();\r\n    }\r\n  }\r\n};\r\n\r\ntemplate<typename T> inline\r\nbool operator==(T* ptr, const linked_ptr<T>& x) {\r\n  return ptr == x.get();\r\n}\r\n\r\ntemplate<typename T> inline\r\nbool operator!=(T* ptr, const linked_ptr<T>& x) {\r\n  return ptr != x.get();\r\n}\r\n\r\n// A function to convert T* into linked_ptr<T>\r\n// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation\r\n// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))\r\ntemplate <typename T>\r\nlinked_ptr<T> make_linked_ptr(T* ptr) {\r\n  return linked_ptr<T>(ptr);\r\n}\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-param-util-generated.h",
    "content": "// This file was GENERATED by command:\r\n//     pump.py gtest-param-util-generated.h.pump\r\n// DO NOT EDIT BY HAND!!!\r\n\r\n// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: vladl@google.com (Vlad Losev)\r\n\r\n// Type and function utilities for implementing parameterized tests.\r\n// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\r\n//\r\n// Currently Google Test supports at most 50 arguments in Values,\r\n// and at most 10 arguments in Combine. Please contact\r\n// googletestframework@googlegroups.com if you need more.\r\n// Please note that the number of arguments to Combine is limited\r\n// by the maximum arity of the implementation of tr1::tuple which is\r\n// currently set at 10.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n\r\n// scripts/fuse_gtest.py depends on gtest's own header being #included\r\n// *unconditionally*.  Therefore these #includes cannot be moved\r\n// inside #if GTEST_HAS_PARAM_TEST.\r\n#include \"gtest/internal/gtest-param-util.h\"\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n\r\nnamespace testing {\r\n\r\n// Forward declarations of ValuesIn(), which is implemented in\r\n// include/gtest/gtest-param-test.h.\r\ntemplate <typename ForwardIterator>\r\ninternal::ParamGenerator <\r\ntypename ::testing::internal::IteratorTraits<ForwardIterator>::value_type >\r\nValuesIn(ForwardIterator begin, ForwardIterator end);\r\n\r\ntemplate <typename T, size_t N>\r\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]);\r\n\r\ntemplate <class Container>\r\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\r\n  const Container& container);\r\n\r\nnamespace internal {\r\n\r\n// Used in the Values() function to provide polymorphic capabilities.\r\ntemplate <typename T1>\r\nclass ValueArray1 {\r\n public:\r\n  explicit ValueArray1(T1 v1) : v1_(v1) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    return ValuesIn(&v1_, &v1_ + 1);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray1& other);\r\n\r\n  const T1 v1_;\r\n};\r\n\r\ntemplate <typename T1, typename T2>\r\nclass ValueArray2 {\r\n public:\r\n  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_)};\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray2& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3>\r\nclass ValueArray3 {\r\n public:\r\n  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray3& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\nclass ValueArray4 {\r\n public:\r\n  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray4& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\nclass ValueArray5 {\r\n public:\r\n  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray5& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\nclass ValueArray6 {\r\n public:\r\n  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray6& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\nclass ValueArray7 {\r\n public:\r\n  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray7& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\nclass ValueArray8 {\r\n public:\r\n  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,\r\n              T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray8& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\nclass ValueArray9 {\r\n public:\r\n  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,\r\n              T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray9& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\nclass ValueArray10 {\r\n public:\r\n  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray10& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11>\r\nclass ValueArray11 {\r\n public:\r\n  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\r\n    v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray11& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12>\r\nclass ValueArray12 {\r\n public:\r\n  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\r\n    v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray12& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13>\r\nclass ValueArray13 {\r\n public:\r\n  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\r\n    v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\r\n    v12_(v12), v13_(v13) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray13& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14>\r\nclass ValueArray14 {\r\n public:\r\n  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray14& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15>\r\nclass ValueArray15 {\r\n public:\r\n  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray15& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16>\r\nclass ValueArray16 {\r\n public:\r\n  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\r\n    v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\r\n    v16_(v16) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray16& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17>\r\nclass ValueArray17 {\r\n public:\r\n  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,\r\n               T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray17& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18>\r\nclass ValueArray18 {\r\n public:\r\n  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray18& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19>\r\nclass ValueArray19 {\r\n public:\r\n  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\r\n    v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\r\n    v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray19& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20>\r\nclass ValueArray20 {\r\n public:\r\n  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\r\n    v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\r\n    v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\r\n    v19_(v19), v20_(v20) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray20& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21>\r\nclass ValueArray21 {\r\n public:\r\n  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\r\n    v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\r\n    v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\r\n    v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray21& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22>\r\nclass ValueArray22 {\r\n public:\r\n  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray22& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23>\r\nclass ValueArray23 {\r\n public:\r\n  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray23& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24>\r\nclass ValueArray24 {\r\n public:\r\n  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\r\n    v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\r\n    v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\r\n    v22_(v22), v23_(v23), v24_(v24) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray24& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25>\r\nclass ValueArray25 {\r\n public:\r\n  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,\r\n               T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray25& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26>\r\nclass ValueArray26 {\r\n public:\r\n  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray26& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27>\r\nclass ValueArray27 {\r\n public:\r\n  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\r\n    v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\r\n    v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\r\n    v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\r\n    v26_(v26), v27_(v27) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray27& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28>\r\nclass ValueArray28 {\r\n public:\r\n  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\r\n    v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\r\n    v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\r\n    v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\r\n    v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray28& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29>\r\nclass ValueArray29 {\r\n public:\r\n  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\r\n    v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\r\n    v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\r\n    v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\r\n    v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray29& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30>\r\nclass ValueArray30 {\r\n public:\r\n  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray30& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31>\r\nclass ValueArray31 {\r\n public:\r\n  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30), v31_(v31) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray31& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32>\r\nclass ValueArray32 {\r\n public:\r\n  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\r\n    v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\r\n    v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\r\n    v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\r\n    v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray32& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33>\r\nclass ValueArray33 {\r\n public:\r\n  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,\r\n               T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray33& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34>\r\nclass ValueArray34 {\r\n public:\r\n  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33), v34_(v34) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray34& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35>\r\nclass ValueArray35 {\r\n public:\r\n  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\r\n    v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\r\n    v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\r\n    v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\r\n    v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),\r\n    v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray35& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36>\r\nclass ValueArray36 {\r\n public:\r\n  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\r\n    v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\r\n    v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\r\n    v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\r\n    v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),\r\n    v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray36& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37>\r\nclass ValueArray37 {\r\n public:\r\n  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\r\n    v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\r\n    v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\r\n    v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\r\n    v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),\r\n    v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),\r\n    v36_(v36), v37_(v37) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray37& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38>\r\nclass ValueArray38 {\r\n public:\r\n  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\r\n    v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray38& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39>\r\nclass ValueArray39 {\r\n public:\r\n  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\r\n    v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray39& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40>\r\nclass ValueArray40 {\r\n public:\r\n  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\r\n    v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\r\n    v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\r\n    v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\r\n    v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),\r\n    v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),\r\n    v40_(v40) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray40& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41>\r\nclass ValueArray41 {\r\n public:\r\n  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,\r\n               T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\r\n    v39_(v39), v40_(v40), v41_(v41) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray41& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42>\r\nclass ValueArray42 {\r\n public:\r\n  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\r\n    v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray42& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43>\r\nclass ValueArray43 {\r\n public:\r\n  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),\r\n    v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),\r\n    v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),\r\n    v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),\r\n    v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),\r\n    v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),\r\n    v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray43& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44>\r\nclass ValueArray44 {\r\n public:\r\n  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),\r\n    v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),\r\n    v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),\r\n    v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),\r\n    v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),\r\n    v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),\r\n    v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),\r\n    v43_(v43), v44_(v44) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray44& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45>\r\nclass ValueArray45 {\r\n public:\r\n  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),\r\n    v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),\r\n    v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),\r\n    v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),\r\n    v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),\r\n    v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),\r\n    v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),\r\n    v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray45& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46>\r\nclass ValueArray46 {\r\n public:\r\n  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),\r\n    v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\r\n    v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),\r\n    v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_), static_cast<T>(v46_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray46& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n  const T46 v46_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47>\r\nclass ValueArray47 {\r\n public:\r\n  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),\r\n    v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),\r\n    v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),\r\n    v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),\r\n    v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),\r\n    v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),\r\n    v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),\r\n    v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),\r\n    v47_(v47) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray47& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n  const T46 v46_;\r\n  const T47 v47_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48>\r\nclass ValueArray48 {\r\n public:\r\n  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),\r\n    v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),\r\n    v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),\r\n    v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),\r\n    v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),\r\n    v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),\r\n    v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),\r\n    v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),\r\n    v46_(v46), v47_(v47), v48_(v48) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),\r\n                       static_cast<T>(v48_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray48& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n  const T46 v46_;\r\n  const T47 v47_;\r\n  const T48 v48_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49>\r\nclass ValueArray49 {\r\n public:\r\n  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,\r\n               T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\r\n    v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),\r\n    v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),\r\n                       static_cast<T>(v48_), static_cast<T>(v49_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray49& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n  const T46 v46_;\r\n  const T47 v47_;\r\n  const T48 v48_;\r\n  const T49 v49_;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49, typename T50>\r\nclass ValueArray50 {\r\n public:\r\n  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,\r\n               T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,\r\n               T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,\r\n               T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,\r\n               T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,\r\n               T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,\r\n               T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),\r\n    v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),\r\n    v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),\r\n    v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),\r\n    v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),\r\n    v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),\r\n    v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),\r\n    v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),\r\n                       static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),\r\n                       static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),\r\n                       static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),\r\n                       static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),\r\n                       static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),\r\n                       static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),\r\n                       static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),\r\n                       static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),\r\n                       static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),\r\n                       static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),\r\n                       static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),\r\n                       static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),\r\n                       static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),\r\n                       static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),\r\n                       static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),\r\n                       static_cast<T>(v48_), static_cast<T>(v49_), static_cast<T>(v50_)\r\n                      };\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray50& other);\r\n\r\n  const T1 v1_;\r\n  const T2 v2_;\r\n  const T3 v3_;\r\n  const T4 v4_;\r\n  const T5 v5_;\r\n  const T6 v6_;\r\n  const T7 v7_;\r\n  const T8 v8_;\r\n  const T9 v9_;\r\n  const T10 v10_;\r\n  const T11 v11_;\r\n  const T12 v12_;\r\n  const T13 v13_;\r\n  const T14 v14_;\r\n  const T15 v15_;\r\n  const T16 v16_;\r\n  const T17 v17_;\r\n  const T18 v18_;\r\n  const T19 v19_;\r\n  const T20 v20_;\r\n  const T21 v21_;\r\n  const T22 v22_;\r\n  const T23 v23_;\r\n  const T24 v24_;\r\n  const T25 v25_;\r\n  const T26 v26_;\r\n  const T27 v27_;\r\n  const T28 v28_;\r\n  const T29 v29_;\r\n  const T30 v30_;\r\n  const T31 v31_;\r\n  const T32 v32_;\r\n  const T33 v33_;\r\n  const T34 v34_;\r\n  const T35 v35_;\r\n  const T36 v36_;\r\n  const T37 v37_;\r\n  const T38 v38_;\r\n  const T39 v39_;\r\n  const T40 v40_;\r\n  const T41 v41_;\r\n  const T42 v42_;\r\n  const T43 v43_;\r\n  const T44 v44_;\r\n  const T45 v45_;\r\n  const T46 v46_;\r\n  const T47 v47_;\r\n  const T48 v48_;\r\n  const T49 v49_;\r\n  const T50 v50_;\r\n};\r\n\r\n# if GTEST_HAS_COMBINE\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Generates values from the Cartesian product of values produced\r\n// by the argument generators.\r\n//\r\ntemplate <typename T1, typename T2>\r\nclass CartesianProductGenerator2\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2> ParamType;\r\n\r\n  CartesianProductGenerator2(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2)\r\n    : g1_(g1), g2_(g2) {}\r\n  virtual ~CartesianProductGenerator2() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current2_;\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd()) {\r\n        current_value_ = ParamType(*current1_, *current2_);\r\n      }\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator2::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator2& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n};  // class CartesianProductGenerator2\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3>\r\nclass CartesianProductGenerator3\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;\r\n\r\n  CartesianProductGenerator3(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)\r\n    : g1_(g1), g2_(g2), g3_(g3) {}\r\n  virtual ~CartesianProductGenerator3() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current3_;\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd()) {\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_);\r\n      }\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator3::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator3& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n};  // class CartesianProductGenerator3\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\nclass CartesianProductGenerator4\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;\r\n\r\n  CartesianProductGenerator4(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}\r\n  virtual ~CartesianProductGenerator4() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current4_;\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator4::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator4& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n};  // class CartesianProductGenerator4\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\nclass CartesianProductGenerator5\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;\r\n\r\n  CartesianProductGenerator5(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}\r\n  virtual ~CartesianProductGenerator5() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current5_;\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator5::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator5& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n};  // class CartesianProductGenerator5\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\nclass CartesianProductGenerator6\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,\r\n    T6> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;\r\n\r\n  CartesianProductGenerator6(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\r\n                             const ParamGenerator<T6>& g6)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}\r\n  virtual ~CartesianProductGenerator6() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5,\r\n             const ParamGenerator<T6>& g6,\r\n             const typename ParamGenerator<T6>::iterator& current6)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\r\n        begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current6_;\r\n\r\n      if (current6_ == end6_) {\r\n        current6_ = begin6_;\r\n        ++current5_;\r\n      }\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_ &&\r\n               current6_ == typed_other->current6_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_),\r\n        begin6_(other.begin6_),\r\n        end6_(other.end6_),\r\n        current6_(other.current6_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_, *current6_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_ ||\r\n        current6_ == end6_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    const typename ParamGenerator<T6>::iterator begin6_;\r\n    const typename ParamGenerator<T6>::iterator end6_;\r\n    typename ParamGenerator<T6>::iterator current6_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator6::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator6& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n  const ParamGenerator<T6> g6_;\r\n};  // class CartesianProductGenerator6\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\nclass CartesianProductGenerator7\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\r\n    T7> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;\r\n\r\n  CartesianProductGenerator7(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\r\n                             const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}\r\n  virtual ~CartesianProductGenerator7() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\r\n                        g7_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5,\r\n             const ParamGenerator<T6>& g6,\r\n             const typename ParamGenerator<T6>::iterator& current6,\r\n             const ParamGenerator<T7>& g7,\r\n             const typename ParamGenerator<T7>::iterator& current7)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\r\n        begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\r\n        begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current7_;\r\n\r\n      if (current7_ == end7_) {\r\n        current7_ = begin7_;\r\n        ++current6_;\r\n      }\r\n\r\n      if (current6_ == end6_) {\r\n        current6_ = begin6_;\r\n        ++current5_;\r\n      }\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_ &&\r\n               current6_ == typed_other->current6_ &&\r\n               current7_ == typed_other->current7_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_),\r\n        begin6_(other.begin6_),\r\n        end6_(other.end6_),\r\n        current6_(other.current6_),\r\n        begin7_(other.begin7_),\r\n        end7_(other.end7_),\r\n        current7_(other.current7_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_, *current6_, *current7_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_ ||\r\n        current6_ == end6_ ||\r\n        current7_ == end7_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    const typename ParamGenerator<T6>::iterator begin6_;\r\n    const typename ParamGenerator<T6>::iterator end6_;\r\n    typename ParamGenerator<T6>::iterator current6_;\r\n    const typename ParamGenerator<T7>::iterator begin7_;\r\n    const typename ParamGenerator<T7>::iterator end7_;\r\n    typename ParamGenerator<T7>::iterator current7_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator7::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator7& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n  const ParamGenerator<T6> g6_;\r\n  const ParamGenerator<T7> g7_;\r\n};  // class CartesianProductGenerator7\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\nclass CartesianProductGenerator8\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\r\n    T7, T8> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;\r\n\r\n  CartesianProductGenerator8(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\r\n                             const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\r\n                             const ParamGenerator<T8>& g8)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),\r\n      g8_(g8) {}\r\n  virtual ~CartesianProductGenerator8() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\r\n                        g7_.begin(), g8_, g8_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\r\n                        g8_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5,\r\n             const ParamGenerator<T6>& g6,\r\n             const typename ParamGenerator<T6>::iterator& current6,\r\n             const ParamGenerator<T7>& g7,\r\n             const typename ParamGenerator<T7>::iterator& current7,\r\n             const ParamGenerator<T8>& g8,\r\n             const typename ParamGenerator<T8>::iterator& current8)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\r\n        begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\r\n        begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\r\n        begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current8_;\r\n\r\n      if (current8_ == end8_) {\r\n        current8_ = begin8_;\r\n        ++current7_;\r\n      }\r\n\r\n      if (current7_ == end7_) {\r\n        current7_ = begin7_;\r\n        ++current6_;\r\n      }\r\n\r\n      if (current6_ == end6_) {\r\n        current6_ = begin6_;\r\n        ++current5_;\r\n      }\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_ &&\r\n               current6_ == typed_other->current6_ &&\r\n               current7_ == typed_other->current7_ &&\r\n               current8_ == typed_other->current8_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_),\r\n        begin6_(other.begin6_),\r\n        end6_(other.end6_),\r\n        current6_(other.current6_),\r\n        begin7_(other.begin7_),\r\n        end7_(other.end7_),\r\n        current7_(other.current7_),\r\n        begin8_(other.begin8_),\r\n        end8_(other.end8_),\r\n        current8_(other.current8_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_, *current6_, *current7_, *current8_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_ ||\r\n        current6_ == end6_ ||\r\n        current7_ == end7_ ||\r\n        current8_ == end8_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    const typename ParamGenerator<T6>::iterator begin6_;\r\n    const typename ParamGenerator<T6>::iterator end6_;\r\n    typename ParamGenerator<T6>::iterator current6_;\r\n    const typename ParamGenerator<T7>::iterator begin7_;\r\n    const typename ParamGenerator<T7>::iterator end7_;\r\n    typename ParamGenerator<T7>::iterator current7_;\r\n    const typename ParamGenerator<T8>::iterator begin8_;\r\n    const typename ParamGenerator<T8>::iterator end8_;\r\n    typename ParamGenerator<T8>::iterator current8_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator8::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator8& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n  const ParamGenerator<T6> g6_;\r\n  const ParamGenerator<T7> g7_;\r\n  const ParamGenerator<T8> g8_;\r\n};  // class CartesianProductGenerator8\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\nclass CartesianProductGenerator9\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\r\n    T7, T8, T9> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;\r\n\r\n  CartesianProductGenerator9(const ParamGenerator<T1>& g1,\r\n                             const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                             const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\r\n                             const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\r\n                             const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\r\n      g9_(g9) {}\r\n  virtual ~CartesianProductGenerator9() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\r\n                        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\r\n                        g8_.end(), g9_, g9_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5,\r\n             const ParamGenerator<T6>& g6,\r\n             const typename ParamGenerator<T6>::iterator& current6,\r\n             const ParamGenerator<T7>& g7,\r\n             const typename ParamGenerator<T7>::iterator& current7,\r\n             const ParamGenerator<T8>& g8,\r\n             const typename ParamGenerator<T8>::iterator& current8,\r\n             const ParamGenerator<T9>& g9,\r\n             const typename ParamGenerator<T9>::iterator& current9)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\r\n        begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\r\n        begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\r\n        begin8_(g8.begin()), end8_(g8.end()), current8_(current8),\r\n        begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current9_;\r\n\r\n      if (current9_ == end9_) {\r\n        current9_ = begin9_;\r\n        ++current8_;\r\n      }\r\n\r\n      if (current8_ == end8_) {\r\n        current8_ = begin8_;\r\n        ++current7_;\r\n      }\r\n\r\n      if (current7_ == end7_) {\r\n        current7_ = begin7_;\r\n        ++current6_;\r\n      }\r\n\r\n      if (current6_ == end6_) {\r\n        current6_ = begin6_;\r\n        ++current5_;\r\n      }\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_ &&\r\n               current6_ == typed_other->current6_ &&\r\n               current7_ == typed_other->current7_ &&\r\n               current8_ == typed_other->current8_ &&\r\n               current9_ == typed_other->current9_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_),\r\n        begin6_(other.begin6_),\r\n        end6_(other.end6_),\r\n        current6_(other.current6_),\r\n        begin7_(other.begin7_),\r\n        end7_(other.end7_),\r\n        current7_(other.current7_),\r\n        begin8_(other.begin8_),\r\n        end8_(other.end8_),\r\n        current8_(other.current8_),\r\n        begin9_(other.begin9_),\r\n        end9_(other.end9_),\r\n        current9_(other.current9_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_, *current6_, *current7_, *current8_,\r\n                                   *current9_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_ ||\r\n        current6_ == end6_ ||\r\n        current7_ == end7_ ||\r\n        current8_ == end8_ ||\r\n        current9_ == end9_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    const typename ParamGenerator<T6>::iterator begin6_;\r\n    const typename ParamGenerator<T6>::iterator end6_;\r\n    typename ParamGenerator<T6>::iterator current6_;\r\n    const typename ParamGenerator<T7>::iterator begin7_;\r\n    const typename ParamGenerator<T7>::iterator end7_;\r\n    typename ParamGenerator<T7>::iterator current7_;\r\n    const typename ParamGenerator<T8>::iterator begin8_;\r\n    const typename ParamGenerator<T8>::iterator end8_;\r\n    typename ParamGenerator<T8>::iterator current8_;\r\n    const typename ParamGenerator<T9>::iterator begin9_;\r\n    const typename ParamGenerator<T9>::iterator end9_;\r\n    typename ParamGenerator<T9>::iterator current9_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator9::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator9& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n  const ParamGenerator<T6> g6_;\r\n  const ParamGenerator<T7> g7_;\r\n  const ParamGenerator<T8> g8_;\r\n  const ParamGenerator<T9> g9_;\r\n};  // class CartesianProductGenerator9\r\n\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\nclass CartesianProductGenerator10\r\n  : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\r\n    T7, T8, T9, T10> > {\r\n public:\r\n  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;\r\n\r\n  CartesianProductGenerator10(const ParamGenerator<T1>& g1,\r\n                              const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,\r\n                              const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,\r\n                              const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,\r\n                              const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,\r\n                              const ParamGenerator<T10>& g10)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\r\n      g9_(g9), g10_(g10) {}\r\n  virtual ~CartesianProductGenerator10() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,\r\n                        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,\r\n                        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),\r\n                        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,\r\n                        g8_.end(), g9_, g9_.end(), g10_, g10_.end());\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base,\r\n             const ParamGenerator<T1>& g1,\r\n             const typename ParamGenerator<T1>::iterator& current1,\r\n             const ParamGenerator<T2>& g2,\r\n             const typename ParamGenerator<T2>::iterator& current2,\r\n             const ParamGenerator<T3>& g3,\r\n             const typename ParamGenerator<T3>::iterator& current3,\r\n             const ParamGenerator<T4>& g4,\r\n             const typename ParamGenerator<T4>::iterator& current4,\r\n             const ParamGenerator<T5>& g5,\r\n             const typename ParamGenerator<T5>::iterator& current5,\r\n             const ParamGenerator<T6>& g6,\r\n             const typename ParamGenerator<T6>::iterator& current6,\r\n             const ParamGenerator<T7>& g7,\r\n             const typename ParamGenerator<T7>::iterator& current7,\r\n             const ParamGenerator<T8>& g8,\r\n             const typename ParamGenerator<T8>::iterator& current8,\r\n             const ParamGenerator<T9>& g9,\r\n             const typename ParamGenerator<T9>::iterator& current9,\r\n             const ParamGenerator<T10>& g10,\r\n             const typename ParamGenerator<T10>::iterator& current10)\r\n      : base_(base),\r\n        begin1_(g1.begin()), end1_(g1.end()), current1_(current1),\r\n        begin2_(g2.begin()), end2_(g2.end()), current2_(current2),\r\n        begin3_(g3.begin()), end3_(g3.end()), current3_(current3),\r\n        begin4_(g4.begin()), end4_(g4.end()), current4_(current4),\r\n        begin5_(g5.begin()), end5_(g5.end()), current5_(current5),\r\n        begin6_(g6.begin()), end6_(g6.end()), current6_(current6),\r\n        begin7_(g7.begin()), end7_(g7.end()), current7_(current7),\r\n        begin8_(g8.begin()), end8_(g8.end()), current8_(current8),\r\n        begin9_(g9.begin()), end9_(g9.end()), current9_(current9),\r\n        begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current10_;\r\n\r\n      if (current10_ == end10_) {\r\n        current10_ = begin10_;\r\n        ++current9_;\r\n      }\r\n\r\n      if (current9_ == end9_) {\r\n        current9_ = begin9_;\r\n        ++current8_;\r\n      }\r\n\r\n      if (current8_ == end8_) {\r\n        current8_ = begin8_;\r\n        ++current7_;\r\n      }\r\n\r\n      if (current7_ == end7_) {\r\n        current7_ = begin7_;\r\n        ++current6_;\r\n      }\r\n\r\n      if (current6_ == end6_) {\r\n        current6_ = begin6_;\r\n        ++current5_;\r\n      }\r\n\r\n      if (current5_ == end5_) {\r\n        current5_ = begin5_;\r\n        ++current4_;\r\n      }\r\n\r\n      if (current4_ == end4_) {\r\n        current4_ = begin4_;\r\n        ++current3_;\r\n      }\r\n\r\n      if (current3_ == end3_) {\r\n        current3_ = begin3_;\r\n        ++current2_;\r\n      }\r\n\r\n      if (current2_ == end2_) {\r\n        current2_ = begin2_;\r\n        ++current1_;\r\n      }\r\n\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const {\r\n      return &current_value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n        CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n             (\r\n               current1_ == typed_other->current1_ &&\r\n               current2_ == typed_other->current2_ &&\r\n               current3_ == typed_other->current3_ &&\r\n               current4_ == typed_other->current4_ &&\r\n               current5_ == typed_other->current5_ &&\r\n               current6_ == typed_other->current6_ &&\r\n               current7_ == typed_other->current7_ &&\r\n               current8_ == typed_other->current8_ &&\r\n               current9_ == typed_other->current9_ &&\r\n               current10_ == typed_other->current10_);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : base_(other.base_),\r\n        begin1_(other.begin1_),\r\n        end1_(other.end1_),\r\n        current1_(other.current1_),\r\n        begin2_(other.begin2_),\r\n        end2_(other.end2_),\r\n        current2_(other.current2_),\r\n        begin3_(other.begin3_),\r\n        end3_(other.end3_),\r\n        current3_(other.current3_),\r\n        begin4_(other.begin4_),\r\n        end4_(other.end4_),\r\n        current4_(other.current4_),\r\n        begin5_(other.begin5_),\r\n        end5_(other.end5_),\r\n        current5_(other.current5_),\r\n        begin6_(other.begin6_),\r\n        end6_(other.end6_),\r\n        current6_(other.current6_),\r\n        begin7_(other.begin7_),\r\n        end7_(other.end7_),\r\n        current7_(other.current7_),\r\n        begin8_(other.begin8_),\r\n        end8_(other.end8_),\r\n        current8_(other.current8_),\r\n        begin9_(other.begin9_),\r\n        end9_(other.end9_),\r\n        current9_(other.current9_),\r\n        begin10_(other.begin10_),\r\n        end10_(other.end10_),\r\n        current10_(other.current10_) {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType(*current1_, *current2_, *current3_,\r\n                                   *current4_, *current5_, *current6_, *current7_, *current8_,\r\n                                   *current9_, *current10_);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n        current1_ == end1_ ||\r\n        current2_ == end2_ ||\r\n        current3_ == end3_ ||\r\n        current4_ == end4_ ||\r\n        current5_ == end5_ ||\r\n        current6_ == end6_ ||\r\n        current7_ == end7_ ||\r\n        current8_ == end8_ ||\r\n        current9_ == end9_ ||\r\n        current10_ == end10_;\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n    const typename ParamGenerator<T1>::iterator begin1_;\r\n    const typename ParamGenerator<T1>::iterator end1_;\r\n    typename ParamGenerator<T1>::iterator current1_;\r\n    const typename ParamGenerator<T2>::iterator begin2_;\r\n    const typename ParamGenerator<T2>::iterator end2_;\r\n    typename ParamGenerator<T2>::iterator current2_;\r\n    const typename ParamGenerator<T3>::iterator begin3_;\r\n    const typename ParamGenerator<T3>::iterator end3_;\r\n    typename ParamGenerator<T3>::iterator current3_;\r\n    const typename ParamGenerator<T4>::iterator begin4_;\r\n    const typename ParamGenerator<T4>::iterator end4_;\r\n    typename ParamGenerator<T4>::iterator current4_;\r\n    const typename ParamGenerator<T5>::iterator begin5_;\r\n    const typename ParamGenerator<T5>::iterator end5_;\r\n    typename ParamGenerator<T5>::iterator current5_;\r\n    const typename ParamGenerator<T6>::iterator begin6_;\r\n    const typename ParamGenerator<T6>::iterator end6_;\r\n    typename ParamGenerator<T6>::iterator current6_;\r\n    const typename ParamGenerator<T7>::iterator begin7_;\r\n    const typename ParamGenerator<T7>::iterator end7_;\r\n    typename ParamGenerator<T7>::iterator current7_;\r\n    const typename ParamGenerator<T8>::iterator begin8_;\r\n    const typename ParamGenerator<T8>::iterator end8_;\r\n    typename ParamGenerator<T8>::iterator current8_;\r\n    const typename ParamGenerator<T9>::iterator begin9_;\r\n    const typename ParamGenerator<T9>::iterator end9_;\r\n    typename ParamGenerator<T9>::iterator current9_;\r\n    const typename ParamGenerator<T10>::iterator begin10_;\r\n    const typename ParamGenerator<T10>::iterator end10_;\r\n    typename ParamGenerator<T10>::iterator current10_;\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator10::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator10& other);\r\n\r\n  const ParamGenerator<T1> g1_;\r\n  const ParamGenerator<T2> g2_;\r\n  const ParamGenerator<T3> g3_;\r\n  const ParamGenerator<T4> g4_;\r\n  const ParamGenerator<T5> g5_;\r\n  const ParamGenerator<T6> g6_;\r\n  const ParamGenerator<T7> g7_;\r\n  const ParamGenerator<T8> g8_;\r\n  const ParamGenerator<T9> g9_;\r\n  const ParamGenerator<T10> g10_;\r\n};  // class CartesianProductGenerator10\r\n\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Helper classes providing Combine() with polymorphic features. They allow\r\n// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is\r\n// convertible to U.\r\n//\r\ntemplate <class Generator1, class Generator2>\r\nclass CartesianProductHolder2 {\r\n public:\r\n  CartesianProductHolder2(const Generator1& g1, const Generator2& g2)\r\n    : g1_(g1), g2_(g2) {}\r\n  template <typename T1, typename T2>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(\r\n             new CartesianProductGenerator2<T1, T2>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder2& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n};  // class CartesianProductHolder2\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3>\r\nclass CartesianProductHolder3 {\r\n public:\r\n  CartesianProductHolder3(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3)\r\n    : g1_(g1), g2_(g2), g3_(g3) {}\r\n  template <typename T1, typename T2, typename T3>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(\r\n             new CartesianProductGenerator3<T1, T2, T3>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder3& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n};  // class CartesianProductHolder3\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4>\r\nclass CartesianProductHolder4 {\r\n public:\r\n  CartesianProductHolder4(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}\r\n  template <typename T1, typename T2, typename T3, typename T4>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(\r\n             new CartesianProductGenerator4<T1, T2, T3, T4>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder4& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n};  // class CartesianProductHolder4\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5>\r\nclass CartesianProductHolder5 {\r\n public:\r\n  CartesianProductHolder5(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4, const Generator5& g5)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(\r\n             new CartesianProductGenerator5<T1, T2, T3, T4, T5>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder5& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n};  // class CartesianProductHolder5\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5, class Generator6>\r\nclass CartesianProductHolder6 {\r\n public:\r\n  CartesianProductHolder6(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4, const Generator5& g5,\r\n                          const Generator6& g6)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n            typename T6>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(\r\n             new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_),\r\n               static_cast<ParamGenerator<T6> >(g6_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder6& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n  const Generator6 g6_;\r\n};  // class CartesianProductHolder6\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5, class Generator6, class Generator7>\r\nclass CartesianProductHolder7 {\r\n public:\r\n  CartesianProductHolder7(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4, const Generator5& g5,\r\n                          const Generator6& g6, const Generator7& g7)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n            typename T6, typename T7>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,\r\n  T7> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(\r\n             new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_),\r\n               static_cast<ParamGenerator<T6> >(g6_),\r\n               static_cast<ParamGenerator<T7> >(g7_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder7& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n  const Generator6 g6_;\r\n  const Generator7 g7_;\r\n};  // class CartesianProductHolder7\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5, class Generator6, class Generator7,\r\n          class Generator8>\r\nclass CartesianProductHolder8 {\r\n public:\r\n  CartesianProductHolder8(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4, const Generator5& g5,\r\n                          const Generator6& g6, const Generator7& g7, const Generator8& g8)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),\r\n      g8_(g8) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n            typename T6, typename T7, typename T8>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,\r\n  T8> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(\r\n             new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_),\r\n               static_cast<ParamGenerator<T6> >(g6_),\r\n               static_cast<ParamGenerator<T7> >(g7_),\r\n               static_cast<ParamGenerator<T8> >(g8_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder8& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n  const Generator6 g6_;\r\n  const Generator7 g7_;\r\n  const Generator8 g8_;\r\n};  // class CartesianProductHolder8\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5, class Generator6, class Generator7,\r\n          class Generator8, class Generator9>\r\nclass CartesianProductHolder9 {\r\n public:\r\n  CartesianProductHolder9(const Generator1& g1, const Generator2& g2,\r\n                          const Generator3& g3, const Generator4& g4, const Generator5& g5,\r\n                          const Generator6& g6, const Generator7& g7, const Generator8& g8,\r\n                          const Generator9& g9)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\r\n      g9_(g9) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n            typename T6, typename T7, typename T8, typename T9>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\r\n  T9> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\r\n           T9> >(\r\n             new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_),\r\n               static_cast<ParamGenerator<T6> >(g6_),\r\n               static_cast<ParamGenerator<T7> >(g7_),\r\n               static_cast<ParamGenerator<T8> >(g8_),\r\n               static_cast<ParamGenerator<T9> >(g9_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder9& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n  const Generator6 g6_;\r\n  const Generator7 g7_;\r\n  const Generator8 g8_;\r\n  const Generator9 g9_;\r\n};  // class CartesianProductHolder9\r\n\r\ntemplate <class Generator1, class Generator2, class Generator3,\r\n          class Generator4, class Generator5, class Generator6, class Generator7,\r\n          class Generator8, class Generator9, class Generator10>\r\nclass CartesianProductHolder10 {\r\n public:\r\n  CartesianProductHolder10(const Generator1& g1, const Generator2& g2,\r\n                           const Generator3& g3, const Generator4& g4, const Generator5& g5,\r\n                           const Generator6& g6, const Generator7& g7, const Generator8& g8,\r\n                           const Generator9& g9, const Generator10& g10)\r\n    : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),\r\n      g9_(g9), g10_(g10) {}\r\n  template <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n            typename T6, typename T7, typename T8, typename T9, typename T10>\r\n  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\r\n  T9, T10> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,\r\n           T9, T10> >(\r\n             new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,\r\n             T10>(\r\n               static_cast<ParamGenerator<T1> >(g1_),\r\n               static_cast<ParamGenerator<T2> >(g2_),\r\n               static_cast<ParamGenerator<T3> >(g3_),\r\n               static_cast<ParamGenerator<T4> >(g4_),\r\n               static_cast<ParamGenerator<T5> >(g5_),\r\n               static_cast<ParamGenerator<T6> >(g6_),\r\n               static_cast<ParamGenerator<T7> >(g7_),\r\n               static_cast<ParamGenerator<T8> >(g8_),\r\n               static_cast<ParamGenerator<T9> >(g9_),\r\n               static_cast<ParamGenerator<T10> >(g10_)));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder10& other);\r\n\r\n  const Generator1 g1_;\r\n  const Generator2 g2_;\r\n  const Generator3 g3_;\r\n  const Generator4 g4_;\r\n  const Generator5 g5_;\r\n  const Generator6 g6_;\r\n  const Generator7 g7_;\r\n  const Generator8 g8_;\r\n  const Generator9 g9_;\r\n  const Generator10 g10_;\r\n};  // class CartesianProductHolder10\r\n\r\n# endif  // GTEST_HAS_COMBINE\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  //  GTEST_HAS_PARAM_TEST\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-param-util-generated.h.pump",
    "content": "$$ -*- mode: c++; -*-\r\n$var n = 50  $$ Maximum length of Values arguments we want to support.\r\n$var maxtuple = 10  $$ Maximum number of Combine arguments we want to support.\r\n// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: vladl@google.com (Vlad Losev)\r\n\r\n// Type and function utilities for implementing parameterized tests.\r\n// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\r\n//\r\n// Currently Google Test supports at most $n arguments in Values,\r\n// and at most $maxtuple arguments in Combine. Please contact\r\n// googletestframework@googlegroups.com if you need more.\r\n// Please note that the number of arguments to Combine is limited\r\n// by the maximum arity of the implementation of tr1::tuple which is\r\n// currently set at $maxtuple.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n\r\n// scripts/fuse_gtest.py depends on gtest's own header being #included\r\n// *unconditionally*.  Therefore these #includes cannot be moved\r\n// inside #if GTEST_HAS_PARAM_TEST.\r\n#include \"gtest/internal/gtest-param-util.h\"\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n\r\nnamespace testing {\r\n\r\n// Forward declarations of ValuesIn(), which is implemented in\r\n// include/gtest/gtest-param-test.h.\r\ntemplate <typename ForwardIterator>\r\ninternal::ParamGenerator<\r\n  typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>\r\nValuesIn(ForwardIterator begin, ForwardIterator end);\r\n\r\ntemplate <typename T, size_t N>\r\ninternal::ParamGenerator<T> ValuesIn(const T (&array)[N]);\r\n\r\ntemplate <class Container>\r\ninternal::ParamGenerator<typename Container::value_type> ValuesIn(\r\n    const Container& container);\r\n\r\nnamespace internal {\r\n\r\n// Used in the Values() function to provide polymorphic capabilities.\r\ntemplate <typename T1>\r\nclass ValueArray1 {\r\n public:\r\n  explicit ValueArray1(T1 v1) : v1_(v1) {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray1& other);\r\n\r\n  const T1 v1_;\r\n};\r\n\r\n$range i 2..n\r\n$for i [[\r\n$range j 1..i\r\n\r\ntemplate <$for j, [[typename T$j]]>\r\nclass ValueArray$i {\r\n public:\r\n  ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}\r\n\r\n  template <typename T>\r\n  operator ParamGenerator<T>() const {\r\n    const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};\r\n    return ValuesIn(array);\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValueArray$i& other);\r\n\r\n$for j [[\r\n\r\n  const T$j v$(j)_;\r\n]]\r\n\r\n};\r\n\r\n]]\r\n\r\n# if GTEST_HAS_COMBINE\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Generates values from the Cartesian product of values produced\r\n// by the argument generators.\r\n//\r\n$range i 2..maxtuple\r\n$for i [[\r\n$range j 1..i\r\n$range k 2..i\r\n\r\ntemplate <$for j, [[typename T$j]]>\r\nclass CartesianProductGenerator$i\r\n    : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {\r\n public:\r\n  typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;\r\n\r\n  CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])\r\n      : $for j, [[g$(j)_(g$j)]] {}\r\n  virtual ~CartesianProductGenerator$i() {}\r\n\r\n  virtual ParamIteratorInterface<ParamType>* Begin() const {\r\n    return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);\r\n  }\r\n  virtual ParamIteratorInterface<ParamType>* End() const {\r\n    return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<ParamType> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[\r\n\r\n      const ParamGenerator<T$j>& g$j,\r\n      const typename ParamGenerator<T$j>::iterator& current$(j)]])\r\n        : base_(base),\r\n$for j, [[\r\n\r\n          begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)\r\n]]    {\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    // Advance should not be called on beyond-of-range iterators\r\n    // so no component iterators must be beyond end of range, either.\r\n    virtual void Advance() {\r\n      assert(!AtEnd());\r\n      ++current$(i)_;\r\n\r\n$for k [[\r\n      if (current$(i+2-k)_ == end$(i+2-k)_) {\r\n        current$(i+2-k)_ = begin$(i+2-k)_;\r\n        ++current$(i+2-k-1)_;\r\n      }\r\n\r\n]]\r\n      ComputeCurrentValue();\r\n    }\r\n    virtual ParamIteratorInterface<ParamType>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const ParamType* Current() const { return &current_value_; }\r\n    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const Iterator* typed_other =\r\n          CheckedDowncastToActualType<const Iterator>(&other);\r\n      // We must report iterators equal if they both point beyond their\r\n      // respective ranges. That can happen in a variety of fashions,\r\n      // so we have to consult AtEnd().\r\n      return (AtEnd() && typed_other->AtEnd()) ||\r\n         ($for j  && [[\r\n\r\n          current$(j)_ == typed_other->current$(j)_\r\n]]);\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n        : base_(other.base_), $for j, [[\r\n\r\n        begin$(j)_(other.begin$(j)_),\r\n        end$(j)_(other.end$(j)_),\r\n        current$(j)_(other.current$(j)_)\r\n]] {\r\n      ComputeCurrentValue();\r\n    }\r\n\r\n    void ComputeCurrentValue() {\r\n      if (!AtEnd())\r\n        current_value_ = ParamType($for j, [[*current$(j)_]]);\r\n    }\r\n    bool AtEnd() const {\r\n      // We must report iterator past the end of the range when either of the\r\n      // component iterators has reached the end of its range.\r\n      return\r\n$for j  || [[\r\n\r\n          current$(j)_ == end$(j)_\r\n]];\r\n    }\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<ParamType>* const base_;\r\n    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.\r\n    // current[i]_ is the actual traversing iterator.\r\n$for j [[\r\n\r\n    const typename ParamGenerator<T$j>::iterator begin$(j)_;\r\n    const typename ParamGenerator<T$j>::iterator end$(j)_;\r\n    typename ParamGenerator<T$j>::iterator current$(j)_;\r\n]]\r\n\r\n    ParamType current_value_;\r\n  };  // class CartesianProductGenerator$i::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductGenerator$i& other);\r\n\r\n\r\n$for j [[\r\n  const ParamGenerator<T$j> g$(j)_;\r\n\r\n]]\r\n};  // class CartesianProductGenerator$i\r\n\r\n\r\n]]\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Helper classes providing Combine() with polymorphic features. They allow\r\n// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is\r\n// convertible to U.\r\n//\r\n$range i 2..maxtuple\r\n$for i [[\r\n$range j 1..i\r\n\r\ntemplate <$for j, [[class Generator$j]]>\r\nclass CartesianProductHolder$i {\r\n public:\r\nCartesianProductHolder$i($for j, [[const Generator$j& g$j]])\r\n      : $for j, [[g$(j)_(g$j)]] {}\r\n  template <$for j, [[typename T$j]]>\r\n  operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {\r\n    return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(\r\n        new CartesianProductGenerator$i<$for j, [[T$j]]>(\r\n$for j,[[\r\n\r\n        static_cast<ParamGenerator<T$j> >(g$(j)_)\r\n]]));\r\n  }\r\n\r\n private:\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const CartesianProductHolder$i& other);\r\n\r\n\r\n$for j [[\r\n  const Generator$j g$(j)_;\r\n\r\n]]\r\n};  // class CartesianProductHolder$i\r\n\r\n]]\r\n\r\n# endif  // GTEST_HAS_COMBINE\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  //  GTEST_HAS_PARAM_TEST\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-param-util.h",
    "content": "// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: vladl@google.com (Vlad Losev)\r\n\r\n// Type and function utilities for implementing parameterized tests.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\r\n\r\n#include <iterator>\r\n#include <utility>\r\n#include <vector>\r\n\r\n// scripts/fuse_gtest.py depends on gtest's own header being #included\r\n// *unconditionally*.  Therefore these #includes cannot be moved\r\n// inside #if GTEST_HAS_PARAM_TEST.\r\n#include \"gtest/internal/gtest-internal.h\"\r\n#include \"gtest/internal/gtest-linked_ptr.h\"\r\n#include \"gtest/internal/gtest-port.h\"\r\n#include \"gtest/gtest-printers.h\"\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Outputs a message explaining invalid registration of different\r\n// fixture class for the same test case. This may happen when\r\n// TEST_P macro is used to define two tests with the same name\r\n// but in different namespaces.\r\nGTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,\r\n    const char* file, int line);\r\n\r\ntemplate <typename> class ParamGeneratorInterface;\r\ntemplate <typename> class ParamGenerator;\r\n\r\n// Interface for iterating over elements provided by an implementation\r\n// of ParamGeneratorInterface<T>.\r\ntemplate <typename T>\r\nclass ParamIteratorInterface {\r\n public:\r\n  virtual ~ParamIteratorInterface() {}\r\n  // A pointer to the base generator instance.\r\n  // Used only for the purposes of iterator comparison\r\n  // to make sure that two iterators belong to the same generator.\r\n  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;\r\n  // Advances iterator to point to the next element\r\n  // provided by the generator. The caller is responsible\r\n  // for not calling Advance() on an iterator equal to\r\n  // BaseGenerator()->End().\r\n  virtual void Advance() = 0;\r\n  // Clones the iterator object. Used for implementing copy semantics\r\n  // of ParamIterator<T>.\r\n  virtual ParamIteratorInterface* Clone() const = 0;\r\n  // Dereferences the current iterator and provides (read-only) access\r\n  // to the pointed value. It is the caller's responsibility not to call\r\n  // Current() on an iterator equal to BaseGenerator()->End().\r\n  // Used for implementing ParamGenerator<T>::operator*().\r\n  virtual const T* Current() const = 0;\r\n  // Determines whether the given iterator and other point to the same\r\n  // element in the sequence generated by the generator.\r\n  // Used for implementing ParamGenerator<T>::operator==().\r\n  virtual bool Equals(const ParamIteratorInterface& other) const = 0;\r\n};\r\n\r\n// Class iterating over elements provided by an implementation of\r\n// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>\r\n// and implements the const forward iterator concept.\r\ntemplate <typename T>\r\nclass ParamIterator {\r\n public:\r\n  typedef T value_type;\r\n  typedef const T& reference;\r\n  typedef ptrdiff_t difference_type;\r\n\r\n  // ParamIterator assumes ownership of the impl_ pointer.\r\n  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}\r\n  ParamIterator& operator=(const ParamIterator& other) {\r\n    if (this != &other) {\r\n      impl_.reset(other.impl_->Clone());\r\n    }\r\n\r\n    return *this;\r\n  }\r\n\r\n  const T& operator*() const {\r\n    return *impl_->Current();\r\n  }\r\n  const T* operator->() const {\r\n    return impl_->Current();\r\n  }\r\n  // Prefix version of operator++.\r\n  ParamIterator& operator++() {\r\n    impl_->Advance();\r\n    return *this;\r\n  }\r\n  // Postfix version of operator++.\r\n  ParamIterator operator++(int /*unused*/) {\r\n    ParamIteratorInterface<T>* clone = impl_->Clone();\r\n    impl_->Advance();\r\n    return ParamIterator(clone);\r\n  }\r\n  bool operator==(const ParamIterator& other) const {\r\n    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);\r\n  }\r\n  bool operator!=(const ParamIterator& other) const {\r\n    return !(*this == other);\r\n  }\r\n\r\n private:\r\n  friend class ParamGenerator<T>;\r\n  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}\r\n  scoped_ptr<ParamIteratorInterface<T> > impl_;\r\n};\r\n\r\n// ParamGeneratorInterface<T> is the binary interface to access generators\r\n// defined in other translation units.\r\ntemplate <typename T>\r\nclass ParamGeneratorInterface {\r\n public:\r\n  typedef T ParamType;\r\n\r\n  virtual ~ParamGeneratorInterface() {}\r\n\r\n  // Generator interface definition\r\n  virtual ParamIteratorInterface<T>* Begin() const = 0;\r\n  virtual ParamIteratorInterface<T>* End() const = 0;\r\n};\r\n\r\n// Wraps ParamGeneratorInterface<T> and provides general generator syntax\r\n// compatible with the STL Container concept.\r\n// This class implements copy initialization semantics and the contained\r\n// ParamGeneratorInterface<T> instance is shared among all copies\r\n// of the original object. This is possible because that instance is immutable.\r\ntemplate<typename T>\r\nclass ParamGenerator {\r\n public:\r\n  typedef ParamIterator<T> iterator;\r\n\r\n  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}\r\n  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}\r\n\r\n  ParamGenerator& operator=(const ParamGenerator& other) {\r\n    impl_ = other.impl_;\r\n    return *this;\r\n  }\r\n\r\n  iterator begin() const {\r\n    return iterator(impl_->Begin());\r\n  }\r\n  iterator end() const {\r\n    return iterator(impl_->End());\r\n  }\r\n\r\n private:\r\n  linked_ptr<const ParamGeneratorInterface<T> > impl_;\r\n};\r\n\r\n// Generates values from a range of two comparable values. Can be used to\r\n// generate sequences of user-defined types that implement operator+() and\r\n// operator<().\r\n// This class is used in the Range() function.\r\ntemplate <typename T, typename IncrementT>\r\nclass RangeGenerator : public ParamGeneratorInterface<T> {\r\n public:\r\n  RangeGenerator(T begin, T end, IncrementT step)\r\n    : begin_(begin), end_(end),\r\n      step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}\r\n  virtual ~RangeGenerator() {}\r\n\r\n  virtual ParamIteratorInterface<T>* Begin() const {\r\n    return new Iterator(this, begin_, 0, step_);\r\n  }\r\n  virtual ParamIteratorInterface<T>* End() const {\r\n    return new Iterator(this, end_, end_index_, step_);\r\n  }\r\n\r\n private:\r\n  class Iterator : public ParamIteratorInterface<T> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,\r\n             IncrementT step)\r\n      : base_(base), value_(value), index_(index), step_(step) {}\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    virtual void Advance() {\r\n      value_ = value_ + step_;\r\n      index_++;\r\n    }\r\n    virtual ParamIteratorInterface<T>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    virtual const T* Current() const {\r\n      return &value_;\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<T>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      const int other_index =\r\n        CheckedDowncastToActualType<const Iterator>(&other)->index_;\r\n      return index_ == other_index;\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n      : ParamIteratorInterface<T>(),\r\n        base_(other.base_), value_(other.value_), index_(other.index_),\r\n        step_(other.step_) {}\r\n\r\n    // No implementation - assignment is unsupported.\r\n    void operator=(const Iterator& other);\r\n\r\n    const ParamGeneratorInterface<T>* const base_;\r\n    T value_;\r\n    int index_;\r\n    const IncrementT step_;\r\n  };  // class RangeGenerator::Iterator\r\n\r\n  static int CalculateEndIndex(const T& begin,\r\n                               const T& end,\r\n                               const IncrementT& step) {\r\n    int end_index = 0;\r\n\r\n    for (T i = begin; i < end; i = i + step) {\r\n      end_index++;\r\n    }\r\n\r\n    return end_index;\r\n  }\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const RangeGenerator& other);\r\n\r\n  const T begin_;\r\n  const T end_;\r\n  const IncrementT step_;\r\n  // The index for the end() iterator. All the elements in the generated\r\n  // sequence are indexed (0-based) to aid iterator comparison.\r\n  const int end_index_;\r\n};  // class RangeGenerator\r\n\r\n\r\n// Generates values from a pair of STL-style iterators. Used in the\r\n// ValuesIn() function. The elements are copied from the source range\r\n// since the source can be located on the stack, and the generator\r\n// is likely to persist beyond that stack frame.\r\ntemplate <typename T>\r\nclass ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {\r\n public:\r\n  template <typename ForwardIterator>\r\n  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)\r\n    : container_(begin, end) {}\r\n  virtual ~ValuesInIteratorRangeGenerator() {}\r\n\r\n  virtual ParamIteratorInterface<T>* Begin() const {\r\n    return new Iterator(this, container_.begin());\r\n  }\r\n  virtual ParamIteratorInterface<T>* End() const {\r\n    return new Iterator(this, container_.end());\r\n  }\r\n\r\n private:\r\n  typedef typename ::std::vector<T> ContainerType;\r\n\r\n  class Iterator : public ParamIteratorInterface<T> {\r\n   public:\r\n    Iterator(const ParamGeneratorInterface<T>* base,\r\n             typename ContainerType::const_iterator iterator)\r\n      : base_(base), iterator_(iterator) {}\r\n    virtual ~Iterator() {}\r\n\r\n    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {\r\n      return base_;\r\n    }\r\n    virtual void Advance() {\r\n      ++iterator_;\r\n      value_.reset();\r\n    }\r\n    virtual ParamIteratorInterface<T>* Clone() const {\r\n      return new Iterator(*this);\r\n    }\r\n    // We need to use cached value referenced by iterator_ because *iterator_\r\n    // can return a temporary object (and of type other then T), so just\r\n    // having \"return &*iterator_;\" doesn't work.\r\n    // value_ is updated here and not in Advance() because Advance()\r\n    // can advance iterator_ beyond the end of the range, and we cannot\r\n    // detect that fact. The client code, on the other hand, is\r\n    // responsible for not calling Current() on an out-of-range iterator.\r\n    virtual const T* Current() const {\r\n      if (value_.get() == NULL) {\r\n        value_.reset(new T(*iterator_));\r\n      }\r\n\r\n      return value_.get();\r\n    }\r\n    virtual bool Equals(const ParamIteratorInterface<T>& other) const {\r\n      // Having the same base generator guarantees that the other\r\n      // iterator is of the same type and we can downcast.\r\n      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())\r\n          << \"The program attempted to compare iterators \"\r\n          << \"from different generators.\" << std::endl;\r\n      return iterator_ ==\r\n             CheckedDowncastToActualType<const Iterator>(&other)->iterator_;\r\n    }\r\n\r\n   private:\r\n    Iterator(const Iterator& other)\r\n    // The explicit constructor call suppresses a false warning\r\n    // emitted by gcc when supplied with the -Wextra option.\r\n      : ParamIteratorInterface<T>(),\r\n        base_(other.base_),\r\n        iterator_(other.iterator_) {}\r\n\r\n    const ParamGeneratorInterface<T>* const base_;\r\n    typename ContainerType::const_iterator iterator_;\r\n    // A cached value of *iterator_. We keep it here to allow access by\r\n    // pointer in the wrapping iterator's operator->().\r\n    // value_ needs to be mutable to be accessed in Current().\r\n    // Use of scoped_ptr helps manage cached value's lifetime,\r\n    // which is bound by the lifespan of the iterator itself.\r\n    mutable scoped_ptr<const T> value_;\r\n  };  // class ValuesInIteratorRangeGenerator::Iterator\r\n\r\n  // No implementation - assignment is unsupported.\r\n  void operator=(const ValuesInIteratorRangeGenerator& other);\r\n\r\n  const ContainerType container_;\r\n};  // class ValuesInIteratorRangeGenerator\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Stores a parameter value and later creates tests parameterized with that\r\n// value.\r\ntemplate <class TestClass>\r\nclass ParameterizedTestFactory : public TestFactoryBase {\r\n public:\r\n  typedef typename TestClass::ParamType ParamType;\r\n  explicit ParameterizedTestFactory(ParamType parameter) :\r\n    parameter_(parameter) {}\r\n  virtual Test* CreateTest() {\r\n    TestClass::SetParam(&parameter_);\r\n    return new TestClass();\r\n  }\r\n\r\n private:\r\n  const ParamType parameter_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);\r\n};\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// TestMetaFactoryBase is a base class for meta-factories that create\r\n// test factories for passing into MakeAndRegisterTestInfo function.\r\ntemplate <class ParamType>\r\nclass TestMetaFactoryBase {\r\n public:\r\n  virtual ~TestMetaFactoryBase() {}\r\n\r\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;\r\n};\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// TestMetaFactory creates test factories for passing into\r\n// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives\r\n// ownership of test factory pointer, same factory object cannot be passed\r\n// into that method twice. But ParameterizedTestCaseInfo is going to call\r\n// it for each Test/Parameter value combination. Thus it needs meta factory\r\n// creator class.\r\ntemplate <class TestCase>\r\nclass TestMetaFactory\r\n  : public TestMetaFactoryBase<typename TestCase::ParamType> {\r\n public:\r\n  typedef typename TestCase::ParamType ParamType;\r\n\r\n  TestMetaFactory() {}\r\n\r\n  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {\r\n    return new ParameterizedTestFactory<TestCase>(parameter);\r\n  }\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);\r\n};\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// ParameterizedTestCaseInfoBase is a generic interface\r\n// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase\r\n// accumulates test information provided by TEST_P macro invocations\r\n// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations\r\n// and uses that information to register all resulting test instances\r\n// in RegisterTests method. The ParameterizeTestCaseRegistry class holds\r\n// a collection of pointers to the ParameterizedTestCaseInfo objects\r\n// and calls RegisterTests() on each of them when asked.\r\nclass ParameterizedTestCaseInfoBase {\r\n public:\r\n  virtual ~ParameterizedTestCaseInfoBase() {}\r\n\r\n  // Base part of test case name for display purposes.\r\n  virtual const string& GetTestCaseName() const = 0;\r\n  // Test case id to verify identity.\r\n  virtual TypeId GetTestCaseTypeId() const = 0;\r\n  // UnitTest class invokes this method to register tests in this\r\n  // test case right before running them in RUN_ALL_TESTS macro.\r\n  // This method should not be called more then once on any single\r\n  // instance of a ParameterizedTestCaseInfoBase derived class.\r\n  virtual void RegisterTests() = 0;\r\n\r\n protected:\r\n  ParameterizedTestCaseInfoBase() {}\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);\r\n};\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P\r\n// macro invocations for a particular test case and generators\r\n// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that\r\n// test case. It registers tests with all values generated by all\r\n// generators when asked.\r\ntemplate <class TestCase>\r\nclass ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {\r\n public:\r\n  // ParamType and GeneratorCreationFunc are private types but are required\r\n  // for declarations of public methods AddTestPattern() and\r\n  // AddTestCaseInstantiation().\r\n  typedef typename TestCase::ParamType ParamType;\r\n  // A function that returns an instance of appropriate generator type.\r\n  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();\r\n\r\n  explicit ParameterizedTestCaseInfo(const char* name)\r\n    : test_case_name_(name) {}\r\n\r\n  // Test case base name for display purposes.\r\n  virtual const string& GetTestCaseName() const {\r\n    return test_case_name_;\r\n  }\r\n  // Test case id to verify identity.\r\n  virtual TypeId GetTestCaseTypeId() const {\r\n    return GetTypeId<TestCase>();\r\n  }\r\n  // TEST_P macro uses AddTestPattern() to record information\r\n  // about a single test in a LocalTestInfo structure.\r\n  // test_case_name is the base name of the test case (without invocation\r\n  // prefix). test_base_name is the name of an individual test without\r\n  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is\r\n  // test case base name and DoBar is test base name.\r\n  void AddTestPattern(const char* test_case_name,\r\n                      const char* test_base_name,\r\n                      TestMetaFactoryBase<ParamType>* meta_factory) {\r\n    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,\r\n                                          test_base_name,\r\n                                          meta_factory)));\r\n  }\r\n  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information\r\n  // about a generator.\r\n  int AddTestCaseInstantiation(const string& instantiation_name,\r\n                               GeneratorCreationFunc* func,\r\n                               const char* /* file */,\r\n                               int /* line */) {\r\n    instantiations_.push_back(::std::make_pair(instantiation_name, func));\r\n    return 0;  // Return value used only to run this method in namespace scope.\r\n  }\r\n  // UnitTest class invokes this method to register tests in this test case\r\n  // test cases right before running tests in RUN_ALL_TESTS macro.\r\n  // This method should not be called more then once on any single\r\n  // instance of a ParameterizedTestCaseInfoBase derived class.\r\n  // UnitTest has a guard to prevent from calling this method more then once.\r\n  virtual void RegisterTests() {\r\n    for (typename TestInfoContainer::iterator test_it = tests_.begin();\r\n         test_it != tests_.end(); ++test_it) {\r\n      linked_ptr<TestInfo> test_info = *test_it;\r\n\r\n      for (typename InstantiationContainer::iterator gen_it =\r\n             instantiations_.begin(); gen_it != instantiations_.end();\r\n           ++gen_it) {\r\n        const string& instantiation_name = gen_it->first;\r\n        ParamGenerator<ParamType> generator((*gen_it->second)());\r\n\r\n        string test_case_name;\r\n\r\n        if ( !instantiation_name.empty() ) {\r\n          test_case_name = instantiation_name + \"/\";\r\n        }\r\n\r\n        test_case_name += test_info->test_case_base_name;\r\n\r\n        int i = 0;\r\n\r\n        for (typename ParamGenerator<ParamType>::iterator param_it =\r\n               generator.begin();\r\n             param_it != generator.end(); ++param_it, ++i) {\r\n          Message test_name_stream;\r\n          test_name_stream << test_info->test_base_name << \"/\" << i;\r\n          MakeAndRegisterTestInfo(\r\n            test_case_name.c_str(),\r\n            test_name_stream.GetString().c_str(),\r\n            NULL,  // No type parameter.\r\n            PrintToString(*param_it).c_str(),\r\n            GetTestCaseTypeId(),\r\n            TestCase::SetUpTestCase,\r\n            TestCase::TearDownTestCase,\r\n            test_info->test_meta_factory->CreateTestFactory(*param_it));\r\n        }  // for param_it\r\n      }  // for gen_it\r\n    }  // for test_it\r\n  }  // RegisterTests\r\n\r\n private:\r\n  // LocalTestInfo structure keeps information about a single test registered\r\n  // with TEST_P macro.\r\n  struct TestInfo {\r\n    TestInfo(const char* a_test_case_base_name,\r\n             const char* a_test_base_name,\r\n             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :\r\n      test_case_base_name(a_test_case_base_name),\r\n      test_base_name(a_test_base_name),\r\n      test_meta_factory(a_test_meta_factory) {}\r\n\r\n    const string test_case_base_name;\r\n    const string test_base_name;\r\n    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;\r\n  };\r\n  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;\r\n  // Keeps pairs of <Instantiation name, Sequence generator creation function>\r\n  // received from INSTANTIATE_TEST_CASE_P macros.\r\n  typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >\r\n  InstantiationContainer;\r\n\r\n  const string test_case_name_;\r\n  TestInfoContainer tests_;\r\n  InstantiationContainer instantiations_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);\r\n};  // class ParameterizedTestCaseInfo\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase\r\n// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P\r\n// macros use it to locate their corresponding ParameterizedTestCaseInfo\r\n// descriptors.\r\nclass ParameterizedTestCaseRegistry {\r\n public:\r\n  ParameterizedTestCaseRegistry() {}\r\n  ~ParameterizedTestCaseRegistry() {\r\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\r\n         it != test_case_infos_.end(); ++it) {\r\n      delete *it;\r\n    }\r\n  }\r\n\r\n  // Looks up or creates and returns a structure containing information about\r\n  // tests and instantiations of a particular test case.\r\n  template <class TestCase>\r\n  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(\r\n    const char* test_case_name,\r\n    const char* file,\r\n    int line) {\r\n    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;\r\n\r\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\r\n         it != test_case_infos_.end(); ++it) {\r\n      if ((*it)->GetTestCaseName() == test_case_name) {\r\n        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {\r\n          // Complain about incorrect usage of Google Test facilities\r\n          // and terminate the program since we cannot guaranty correct\r\n          // test case setup and tear-down in this case.\r\n          ReportInvalidTestCaseType(test_case_name,  file, line);\r\n          posix::Abort();\r\n        }\r\n        else {\r\n          // At this point we are sure that the object we found is of the same\r\n          // type we are looking for, so we downcast it to that type\r\n          // without further checks.\r\n          typed_test_info = CheckedDowncastToActualType <\r\n                            ParameterizedTestCaseInfo<TestCase> > (*it);\r\n        }\r\n\r\n        break;\r\n      }\r\n    }\r\n\r\n    if (typed_test_info == NULL) {\r\n      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);\r\n      test_case_infos_.push_back(typed_test_info);\r\n    }\r\n\r\n    return typed_test_info;\r\n  }\r\n  void RegisterTests() {\r\n    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();\r\n         it != test_case_infos_.end(); ++it) {\r\n      (*it)->RegisterTests();\r\n    }\r\n  }\r\n\r\n private:\r\n  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;\r\n\r\n  TestCaseInfoContainer test_case_infos_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);\r\n};\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  //  GTEST_HAS_PARAM_TEST\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-port.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: wan@google.com (Zhanyong Wan)\r\n//\r\n// Low-level types and utilities for porting Google Test to various\r\n// platforms.  They are subject to change without notice.  DO NOT USE\r\n// THEM IN USER CODE.\r\n//\r\n// This file is fundamental to Google Test.  All other Google Test source\r\n// files are expected to #include this.  Therefore, it cannot #include\r\n// any other Google Test header.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\r\n\r\n// The user can define the following macros in the build script to\r\n// control Google Test's behavior.  If the user doesn't define a macro\r\n// in this list, Google Test will define it.\r\n//\r\n//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)\r\n//                              is/isn't available.\r\n//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions\r\n//                              are enabled.\r\n//   GTEST_HAS_GLOBAL_STRING  - Define it to 1/0 to indicate that ::string\r\n//                              is/isn't available (some systems define\r\n//                              ::string, which is different to std::string).\r\n//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string\r\n//                              is/isn't available (some systems define\r\n//                              ::wstring, which is different to std::wstring).\r\n//   GTEST_HAS_POSIX_RE       - Define it to 1/0 to indicate that POSIX regular\r\n//                              expressions are/aren't available.\r\n//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>\r\n//                              is/isn't available.\r\n//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't\r\n//                              enabled.\r\n//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that\r\n//                              std::wstring does/doesn't work (Google Test can\r\n//                              be used where std::wstring is unavailable).\r\n//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple\r\n//                              is/isn't available.\r\n//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the\r\n//                              compiler supports Microsoft's \"Structured\r\n//                              Exception Handling\".\r\n//   GTEST_HAS_STREAM_REDIRECTION\r\n//                            - Define it to 1/0 to indicate whether the\r\n//                              platform supports I/O stream redirection using\r\n//                              dup() and dup2().\r\n//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google\r\n//                              Test's own tr1 tuple implementation should be\r\n//                              used.  Unused when the user sets\r\n//                              GTEST_HAS_TR1_TUPLE to 0.\r\n//   GTEST_LANG_CXX11         - Define it to 1/0 to indicate that Google Test\r\n//                              is building in C++11/C++98 mode.\r\n//   GTEST_LINKED_AS_SHARED_LIBRARY\r\n//                            - Define to 1 when compiling tests that use\r\n//                              Google Test as a shared library (known as\r\n//                              DLL on Windows).\r\n//   GTEST_CREATE_SHARED_LIBRARY\r\n//                            - Define to 1 when compiling Google Test itself\r\n//                              as a shared library.\r\n\r\n// This header defines the following utilities:\r\n//\r\n// Macros indicating the current platform (defined to 1 if compiled on\r\n// the given platform; otherwise undefined):\r\n//   GTEST_OS_AIX      - IBM AIX\r\n//   GTEST_OS_CYGWIN   - Cygwin\r\n//   GTEST_OS_HPUX     - HP-UX\r\n//   GTEST_OS_LINUX    - Linux\r\n//     GTEST_OS_LINUX_ANDROID - Google Android\r\n//   GTEST_OS_MAC      - Mac OS X\r\n//     GTEST_OS_IOS    - iOS\r\n//       GTEST_OS_IOS_SIMULATOR - iOS simulator\r\n//   GTEST_OS_NACL     - Google Native Client (NaCl)\r\n//   GTEST_OS_OPENBSD  - OpenBSD\r\n//   GTEST_OS_QNX      - QNX\r\n//   GTEST_OS_SOLARIS  - Sun Solaris\r\n//   GTEST_OS_SYMBIAN  - Symbian\r\n//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)\r\n//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop\r\n//     GTEST_OS_WINDOWS_MINGW    - MinGW\r\n//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile\r\n//   GTEST_OS_ZOS      - z/OS\r\n//\r\n// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the\r\n// most stable support.  Since core members of the Google Test project\r\n// don't have access to other platforms, support for them may be less\r\n// stable.  If you notice any problems on your platform, please notify\r\n// googletestframework@googlegroups.com (patches for fixing them are\r\n// even more welcome!).\r\n//\r\n// Note that it is possible that none of the GTEST_OS_* macros are defined.\r\n//\r\n// Macros indicating available Google Test features (defined to 1 if\r\n// the corresponding feature is supported; otherwise undefined):\r\n//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized\r\n//                            tests)\r\n//   GTEST_HAS_DEATH_TEST   - death tests\r\n//   GTEST_HAS_PARAM_TEST   - value-parameterized tests\r\n//   GTEST_HAS_TYPED_TEST   - typed tests\r\n//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests\r\n//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used. Do not confuse with\r\n//                            GTEST_HAS_POSIX_RE (see above) which users can\r\n//                            define themselves.\r\n//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;\r\n//                            the above two are mutually exclusive.\r\n//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().\r\n//\r\n// Macros for basic C++ coding:\r\n//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.\r\n//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a\r\n//                              variable don't have to be used.\r\n//   GTEST_DISALLOW_ASSIGN_   - disables operator=.\r\n//   GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.\r\n//   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.\r\n//\r\n// Synchronization:\r\n//   Mutex, MutexLock, ThreadLocal, GetThreadCount()\r\n//                  - synchronization primitives.\r\n//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above\r\n//                         synchronization primitives have real implementations\r\n//                         and Google Test is thread-safe; or 0 otherwise.\r\n//\r\n// Template meta programming:\r\n//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ only.\r\n//   IteratorTraits - partial implementation of std::iterator_traits, which\r\n//                    is not available in libCstd when compiled with Sun C++.\r\n//\r\n// Smart pointers:\r\n//   scoped_ptr     - as in TR2.\r\n//\r\n// Regular expressions:\r\n//   RE             - a simple regular expression class using the POSIX\r\n//                    Extended Regular Expression syntax on UNIX-like\r\n//                    platforms, or a reduced regular exception syntax on\r\n//                    other platforms, including Windows.\r\n//\r\n// Logging:\r\n//   GTEST_LOG_()   - logs messages at the specified severity level.\r\n//   LogToStderr()  - directs all log messages to stderr.\r\n//   FlushInfoLog() - flushes informational log messages.\r\n//\r\n// Stdout and stderr capturing:\r\n//   CaptureStdout()     - starts capturing stdout.\r\n//   GetCapturedStdout() - stops capturing stdout and returns the captured\r\n//                         string.\r\n//   CaptureStderr()     - starts capturing stderr.\r\n//   GetCapturedStderr() - stops capturing stderr and returns the captured\r\n//                         string.\r\n//\r\n// Integer types:\r\n//   TypeWithSize   - maps an integer to a int type.\r\n//   Int32, UInt32, Int64, UInt64, TimeInMillis\r\n//                  - integers of known sizes.\r\n//   BiggestInt     - the biggest signed integer type.\r\n//\r\n// Command-line utilities:\r\n//   GTEST_FLAG()       - references a flag.\r\n//   GTEST_DECLARE_*()  - declares a flag.\r\n//   GTEST_DEFINE_*()   - defines a flag.\r\n//   GetInjectableArgvs() - returns the command line as a vector of strings.\r\n//\r\n// Environment variable utilities:\r\n//   GetEnv()             - gets the value of an environment variable.\r\n//   BoolFromGTestEnv()   - parses a bool environment variable.\r\n//   Int32FromGTestEnv()  - parses an Int32 environment variable.\r\n//   StringFromGTestEnv() - parses a string environment variable.\r\n\r\n#include <ctype.h>   // for isspace, etc\r\n#include <stddef.h>  // for ptrdiff_t\r\n#include <stdlib.h>\r\n#include <stdio.h>\r\n#include <string.h>\r\n#ifndef _WIN32_WCE\r\n# include <sys/types.h>\r\n# include <sys/stat.h>\r\n#endif  // !_WIN32_WCE\r\n\r\n#if defined __APPLE__\r\n# include <AvailabilityMacros.h>\r\n# include <TargetConditionals.h>\r\n#endif\r\n\r\n#include <iostream>  // NOLINT\r\n#include <sstream>  // NOLINT\r\n#include <string>  // NOLINT\r\n\r\n#define GTEST_DEV_EMAIL_ \"googletestframework@@googlegroups.com\"\r\n#define GTEST_FLAG_PREFIX_ \"gtest_\"\r\n#define GTEST_FLAG_PREFIX_DASH_ \"gtest-\"\r\n#define GTEST_FLAG_PREFIX_UPPER_ \"GTEST_\"\r\n#define GTEST_NAME_ \"Google Test\"\r\n#define GTEST_PROJECT_URL_ \"http://code.google.com/p/googletest/\"\r\n\r\n// Determines the version of gcc that is used to compile this.\r\n#ifdef __GNUC__\r\n// 40302 means version 4.3.2.\r\n# define GTEST_GCC_VER_ \\\r\n    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)\r\n#endif  // __GNUC__\r\n\r\n// Determines the platform on which Google Test is compiled.\r\n#ifdef __CYGWIN__\r\n# define GTEST_OS_CYGWIN 1\r\n#elif defined __SYMBIAN32__\r\n# define GTEST_OS_SYMBIAN 1\r\n#elif defined _WIN32\r\n# define GTEST_OS_WINDOWS 1\r\n# ifdef _WIN32_WCE\r\n#  define GTEST_OS_WINDOWS_MOBILE 1\r\n# elif defined(__MINGW__) || defined(__MINGW32__)\r\n#  define GTEST_OS_WINDOWS_MINGW 1\r\n# else\r\n#  define GTEST_OS_WINDOWS_DESKTOP 1\r\n# endif  // _WIN32_WCE\r\n#elif defined __APPLE__\r\n# define GTEST_OS_MAC 1\r\n# if TARGET_OS_IPHONE\r\n#  define GTEST_OS_IOS 1\r\n#  if TARGET_IPHONE_SIMULATOR\r\n#   define GTEST_OS_IOS_SIMULATOR 1\r\n#  endif\r\n# endif\r\n#elif defined __linux__\r\n# define GTEST_OS_LINUX 1\r\n# if defined __ANDROID__\r\n#  define GTEST_OS_LINUX_ANDROID 1\r\n# endif\r\n#elif defined __MVS__\r\n# define GTEST_OS_ZOS 1\r\n#elif defined(__sun) && defined(__SVR4)\r\n# define GTEST_OS_SOLARIS 1\r\n#elif defined(_AIX)\r\n# define GTEST_OS_AIX 1\r\n#elif defined(__hpux)\r\n# define GTEST_OS_HPUX 1\r\n#elif defined __native_client__\r\n# define GTEST_OS_NACL 1\r\n#elif defined __OpenBSD__\r\n# define GTEST_OS_OPENBSD 1\r\n#elif defined __QNX__\r\n# define GTEST_OS_QNX 1\r\n#endif  // __CYGWIN__\r\n\r\n#ifndef GTEST_LANG_CXX11\r\n// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when\r\n// -std={c,gnu}++{0x,11} is passed.  The C++11 standard specifies a\r\n// value for __cplusplus, and recent versions of clang, gcc, and\r\n// probably other compilers set that too in C++11 mode.\r\n# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L\r\n// Compiling in at least C++11 mode.\r\n#  define GTEST_LANG_CXX11 1\r\n# else\r\n#  define GTEST_LANG_CXX11 0\r\n# endif\r\n#endif\r\n\r\n// Brings in definitions for functions used in the testing::internal::posix\r\n// namespace (read, write, close, chdir, isatty, stat). We do not currently\r\n// use them on Windows Mobile.\r\n#if !GTEST_OS_WINDOWS\r\n// This assumes that non-Windows OSes provide unistd.h. For OSes where this\r\n// is not the case, we need to include headers that provide the functions\r\n// mentioned above.\r\n# include <unistd.h>\r\n# include <strings.h>\r\n#elif !GTEST_OS_WINDOWS_MOBILE\r\n# include <direct.h>\r\n# include <io.h>\r\n#endif\r\n\r\n#if GTEST_OS_LINUX_ANDROID\r\n// Used to define __ANDROID_API__ matching the target NDK API level.\r\n#  include <android/api-level.h>  // NOLINT\r\n#endif\r\n\r\n// Code Added by Ramesh based on changes by Mario\r\n#if defined(_MSC_VER)\r\n# include <windows.h>\r\n#endif\r\n\r\n// Defines this to true iff Google Test can use POSIX regular expressions.\r\n#ifndef GTEST_HAS_POSIX_RE\r\n# if GTEST_OS_LINUX_ANDROID\r\n// On Android, <regex.h> is only available starting with Gingerbread.\r\n#  define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)\r\n# else\r\n#  define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS)\r\n# endif\r\n#endif\r\n\r\n#if GTEST_HAS_POSIX_RE\r\n\r\n// On some platforms, <regex.h> needs someone to define size_t, and\r\n// won't compile otherwise.  We can #include it here as we already\r\n// included <stdlib.h>, which is guaranteed to define size_t through\r\n// <stddef.h>.\r\n# include <regex.h>  // NOLINT\r\n\r\n# define GTEST_USES_POSIX_RE 1\r\n\r\n#elif GTEST_OS_WINDOWS\r\n\r\n// <regex.h> is not available on Windows.  Use our own simple regex\r\n// implementation instead.\r\n# define GTEST_USES_SIMPLE_RE 1\r\n\r\n#else\r\n\r\n// <regex.h> may not be available on this platform.  Use our own\r\n// simple regex implementation instead.\r\n# define GTEST_USES_SIMPLE_RE 1\r\n\r\n#endif  // GTEST_HAS_POSIX_RE\r\n\r\n#ifndef GTEST_HAS_EXCEPTIONS\r\n// The user didn't tell us whether exceptions are enabled, so we need\r\n// to figure it out.\r\n# if defined(_MSC_VER) || defined(__BORLANDC__)\r\n// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS\r\n// macro to enable exceptions, so we'll do the same.\r\n// Assumes that exceptions are enabled by default.\r\n#  ifndef _HAS_EXCEPTIONS\r\n#   define _HAS_EXCEPTIONS 1\r\n#  endif  // _HAS_EXCEPTIONS\r\n#  define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS\r\n# elif defined(__GNUC__) && __EXCEPTIONS\r\n// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.\r\n#  define GTEST_HAS_EXCEPTIONS 1\r\n# elif defined(__SUNPRO_CC)\r\n// Sun Pro CC supports exceptions.  However, there is no compile-time way of\r\n// detecting whether they are enabled or not.  Therefore, we assume that\r\n// they are enabled unless the user tells us otherwise.\r\n#  define GTEST_HAS_EXCEPTIONS 1\r\n# elif defined(__IBMCPP__) && __EXCEPTIONS\r\n// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.\r\n#  define GTEST_HAS_EXCEPTIONS 1\r\n# elif defined(__HP_aCC)\r\n// Exception handling is in effect by default in HP aCC compiler. It has to\r\n// be turned of by +noeh compiler option if desired.\r\n#  define GTEST_HAS_EXCEPTIONS 1\r\n# else\r\n// For other compilers, we assume exceptions are disabled to be\r\n// conservative.\r\n#  define GTEST_HAS_EXCEPTIONS 0\r\n# endif  // defined(_MSC_VER) || defined(__BORLANDC__)\r\n#endif  // GTEST_HAS_EXCEPTIONS\r\n\r\n#if !defined(GTEST_HAS_STD_STRING)\r\n// Even though we don't use this macro any longer, we keep it in case\r\n// some clients still depend on it.\r\n# define GTEST_HAS_STD_STRING 1\r\n#elif !GTEST_HAS_STD_STRING\r\n// The user told us that ::std::string isn't available.\r\n# error \"Google Test cannot be used where ::std::string isn't available.\"\r\n#endif  // !defined(GTEST_HAS_STD_STRING)\r\n\r\n#ifndef GTEST_HAS_GLOBAL_STRING\r\n// The user didn't tell us whether ::string is available, so we need\r\n// to figure it out.\r\n\r\n# define GTEST_HAS_GLOBAL_STRING 0\r\n\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\n#ifndef GTEST_HAS_STD_WSTRING\r\n// The user didn't tell us whether ::std::wstring is available, so we need\r\n// to figure it out.\r\n// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring\r\n//   is available.\r\n\r\n// Cygwin 1.7 and below doesn't support ::std::wstring.\r\n// Solaris' libc++ doesn't support it either.  Android has\r\n// no support for it at least as recent as Froyo (2.2).\r\n# define GTEST_HAS_STD_WSTRING \\\r\n    (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))\r\n\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\n#ifndef GTEST_HAS_GLOBAL_WSTRING\r\n// The user didn't tell us whether ::wstring is available, so we need\r\n// to figure it out.\r\n# define GTEST_HAS_GLOBAL_WSTRING \\\r\n    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n// Determines whether RTTI is available.\r\n#ifndef GTEST_HAS_RTTI\r\n// The user didn't tell us whether RTTI is enabled, so we need to\r\n// figure it out.\r\n\r\n# ifdef _MSC_VER\r\n\r\n#  ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.\r\n#   define GTEST_HAS_RTTI 1\r\n#  else\r\n#   define GTEST_HAS_RTTI 0\r\n#  endif\r\n\r\n// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.\r\n# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)\r\n\r\n#  ifdef __GXX_RTTI\r\n// When building against STLport with the Android NDK and with\r\n// -frtti -fno-exceptions, the build fails at link time with undefined\r\n// references to __cxa_bad_typeid. Note sure if STL or toolchain bug,\r\n// so disable RTTI when detected.\r\n#   if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \\\r\n       !defined(__EXCEPTIONS)\r\n#    define GTEST_HAS_RTTI 0\r\n#   else\r\n#    define GTEST_HAS_RTTI 1\r\n#   endif  // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS\r\n#  else\r\n#   define GTEST_HAS_RTTI 0\r\n#  endif  // __GXX_RTTI\r\n\r\n// Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends\r\n// using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the\r\n// first version with C++ support.\r\n# elif defined(__clang__)\r\n\r\n#  define GTEST_HAS_RTTI __has_feature(cxx_rtti)\r\n\r\n// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if\r\n// both the typeid and dynamic_cast features are present.\r\n# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)\r\n\r\n#  ifdef __RTTI_ALL__\r\n#   define GTEST_HAS_RTTI 1\r\n#  else\r\n#   define GTEST_HAS_RTTI 0\r\n#  endif\r\n\r\n# else\r\n\r\n// For all other compilers, we assume RTTI is enabled.\r\n#  define GTEST_HAS_RTTI 1\r\n\r\n# endif  // _MSC_VER\r\n\r\n#endif  // GTEST_HAS_RTTI\r\n\r\n// It's this header's responsibility to #include <typeinfo> when RTTI\r\n// is enabled.\r\n#if GTEST_HAS_RTTI\r\n# include <typeinfo>\r\n#endif\r\n\r\n// Determines whether Google Test can use the pthreads library.\r\n#ifndef GTEST_HAS_PTHREAD\r\n// The user didn't tell us explicitly, so we assume pthreads support is\r\n// available on Linux and Mac.\r\n//\r\n// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0\r\n// to your compiler flags.\r\n# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \\\r\n    || GTEST_OS_QNX)\r\n#endif  // GTEST_HAS_PTHREAD\r\n\r\n#if GTEST_HAS_PTHREAD\r\n// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is\r\n// true.\r\n# include <pthread.h>  // NOLINT\r\n\r\n// For timespec and nanosleep, used below.\r\n# include <time.h>  // NOLINT\r\n#endif\r\n\r\n// Determines whether Google Test can use tr1/tuple.  You can define\r\n// this macro to 0 to prevent Google Test from using tuple (any\r\n// feature depending on tuple with be disabled in this mode).\r\n#ifndef GTEST_HAS_TR1_TUPLE\r\n# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR)\r\n// STLport, provided with the Android NDK, has neither <tr1/tuple> or <tuple>.\r\n#  define GTEST_HAS_TR1_TUPLE 0\r\n# else\r\n// The user didn't tell us not to do it, so we assume it's OK.\r\n#  define GTEST_HAS_TR1_TUPLE 0\r\n# endif\r\n#endif  // GTEST_HAS_TR1_TUPLE\r\n\r\n// Determines whether Google Test's own tr1 tuple implementation\r\n// should be used.\r\n#ifndef GTEST_USE_OWN_TR1_TUPLE\r\n// The user didn't tell us, so we need to figure it out.\r\n\r\n// We use our own TR1 tuple if we aren't sure the user has an\r\n// implementation of it already.  At this time, libstdc++ 4.0.0+ and\r\n// MSVC 2010 are the only mainstream standard libraries that come\r\n// with a TR1 tuple implementation.  NVIDIA's CUDA NVCC compiler\r\n// pretends to be GCC by defining __GNUC__ and friends, but cannot\r\n// compile GCC's tuple implementation.  MSVC 2008 (9.0) provides TR1\r\n// tuple in a 323 MB Feature Pack download, which we cannot assume the\r\n// user has.  QNX's QCC compiler is a modified GCC but it doesn't\r\n// support TR1 tuple.  libc++ only provides std::tuple, in C++11 mode,\r\n// and it can be used with some compilers that define __GNUC__.\r\n# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \\\r\n      && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600\r\n#  define GTEST_ENV_HAS_TR1_TUPLE_ 1\r\n# endif\r\n\r\n// C++11 specifies that <tuple> provides std::tuple. Use that if gtest is used\r\n// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6\r\n// can build with clang but need to use gcc4.2's libstdc++).\r\n# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325)\r\n#  define GTEST_ENV_HAS_STD_TUPLE_ 1\r\n# endif\r\n\r\n# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_\r\n#  define GTEST_USE_OWN_TR1_TUPLE 0\r\n# else\r\n#  define GTEST_USE_OWN_TR1_TUPLE 1\r\n# endif\r\n\r\n#endif  // GTEST_USE_OWN_TR1_TUPLE\r\n\r\n// To avoid conditional compilation everywhere, we make it\r\n// gtest-port.h's responsibility to #include the header implementing\r\n// tr1/tuple.\r\n#if GTEST_HAS_TR1_TUPLE\r\n\r\n# if GTEST_USE_OWN_TR1_TUPLE\r\n#  include \"gtest/internal/gtest-tuple.h\"\r\n# elif GTEST_ENV_HAS_STD_TUPLE_\r\n#  include <tuple>\r\n// C++11 puts its tuple into the ::std namespace rather than\r\n// ::std::tr1.  gtest expects tuple to live in ::std::tr1, so put it there.\r\n// This causes undefined behavior, but supported compilers react in\r\n// the way we intend.\r\nnamespace std {\r\nnamespace tr1 {\r\nusing ::std::get;\r\nusing ::std::make_tuple;\r\nusing ::std::tuple;\r\nusing ::std::tuple_element;\r\nusing ::std::tuple_size;\r\n}\r\n}\r\n\r\n# elif GTEST_OS_SYMBIAN\r\n\r\n// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to\r\n// use STLport's tuple implementation, which unfortunately doesn't\r\n// work as the copy of STLport distributed with Symbian is incomplete.\r\n// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to\r\n// use its own tuple implementation.\r\n#  ifdef BOOST_HAS_TR1_TUPLE\r\n#   undef BOOST_HAS_TR1_TUPLE\r\n#  endif  // BOOST_HAS_TR1_TUPLE\r\n\r\n// This prevents <boost/tr1/detail/config.hpp>, which defines\r\n// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.\r\n#  define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED\r\n#  include <tuple>\r\n\r\n# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)\r\n// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does\r\n// not conform to the TR1 spec, which requires the header to be <tuple>.\r\n\r\n#  if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302\r\n// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,\r\n// which is #included by <tr1/tuple>, to not compile when RTTI is\r\n// disabled.  _TR1_FUNCTIONAL is the header guard for\r\n// <tr1/functional>.  Hence the following #define is a hack to prevent\r\n// <tr1/functional> from being included.\r\n#   define _TR1_FUNCTIONAL 1\r\n#   include <tr1/tuple>\r\n#   undef _TR1_FUNCTIONAL  // Allows the user to #include\r\n// <tr1/functional> if he chooses to.\r\n#  else\r\n#   include <tr1/tuple>  // NOLINT\r\n#  endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302\r\n\r\n# else\r\n// If the compiler is not GCC 4.0+, we assume the user is using a\r\n// spec-conforming TR1 implementation.\r\n#  include <tuple>  // NOLINT\r\n# endif  // GTEST_USE_OWN_TR1_TUPLE\r\n\r\n#endif  // GTEST_HAS_TR1_TUPLE\r\n\r\n// Determines whether clone(2) is supported.\r\n// Usually it will only be available on Linux, excluding\r\n// Linux on the Itanium architecture.\r\n// Also see http://linux.die.net/man/2/clone.\r\n#ifndef GTEST_HAS_CLONE\r\n// The user didn't tell us, so we need to figure it out.\r\n\r\n# if GTEST_OS_LINUX && !defined(__ia64__)\r\n#  if GTEST_OS_LINUX_ANDROID\r\n// On Android, clone() is only available on ARM starting with Gingerbread.\r\n#    if defined(__arm__) && __ANDROID_API__ >= 9\r\n#     define GTEST_HAS_CLONE 1\r\n#    else\r\n#     define GTEST_HAS_CLONE 0\r\n#    endif\r\n#  else\r\n#   define GTEST_HAS_CLONE 1\r\n#  endif\r\n# else\r\n#  define GTEST_HAS_CLONE 0\r\n# endif  // GTEST_OS_LINUX && !defined(__ia64__)\r\n\r\n#endif  // GTEST_HAS_CLONE\r\n\r\n// Determines whether to support stream redirection. This is used to test\r\n// output correctness and to implement death tests.\r\n#ifndef GTEST_HAS_STREAM_REDIRECTION\r\n// By default, we assume that stream redirection is supported on all\r\n// platforms except known mobile ones.\r\n# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN\r\n#  define GTEST_HAS_STREAM_REDIRECTION 0\r\n# else\r\n#  define GTEST_HAS_STREAM_REDIRECTION 1\r\n# endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN\r\n#endif  // GTEST_HAS_STREAM_REDIRECTION\r\n\r\n// Determines whether to support death tests.\r\n// Google Test does not support death tests for VC 7.1 and earlier as\r\n// abort() in a VC 7.1 application compiled as GUI in debug config\r\n// pops up a dialog window that cannot be suppressed programmatically.\r\n#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \\\r\n     (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \\\r\n     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \\\r\n     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \\\r\n     GTEST_OS_OPENBSD || GTEST_OS_QNX)\r\n# define GTEST_HAS_DEATH_TEST 1\r\n# include <vector>  // NOLINT\r\n#endif\r\n\r\n// We don't support MSVC 7.1 with exceptions disabled now.  Therefore\r\n// all the compilers we care about are adequate for supporting\r\n// value-parameterized tests.\r\n#define GTEST_HAS_PARAM_TEST 1\r\n\r\n// Determines whether to support type-driven tests.\r\n\r\n// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,\r\n// Sun Pro CC, IBM Visual Age, and HP aCC support.\r\n#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \\\r\n    defined(__IBMCPP__) || defined(__HP_aCC)\r\n# define GTEST_HAS_TYPED_TEST 1\r\n# define GTEST_HAS_TYPED_TEST_P 1\r\n#endif\r\n\r\n// Determines whether to support Combine(). This only makes sense when\r\n// value-parameterized tests are enabled.  The implementation doesn't\r\n// work on Sun Studio since it doesn't understand templated conversion\r\n// operators.\r\n#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)\r\n# define GTEST_HAS_COMBINE 1\r\n#endif\r\n\r\n// Determines whether the system compiler uses UTF-16 for encoding wide strings.\r\n#define GTEST_WIDE_STRING_USES_UTF16_ \\\r\n    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)\r\n\r\n// Determines whether test results can be streamed to a socket.\r\n#if GTEST_OS_LINUX\r\n# define GTEST_CAN_STREAM_RESULTS_ 1\r\n#endif\r\n\r\n// Defines some utility macros.\r\n\r\n// The GNU compiler emits a warning if nested \"if\" statements are followed by\r\n// an \"else\" statement and braces are not used to explicitly disambiguate the\r\n// \"else\" binding.  This leads to problems with code like:\r\n//\r\n//   if (gate)\r\n//     ASSERT_*(condition) << \"Some message\";\r\n//\r\n// The \"switch (0) case 0:\" idiom is used to suppress this.\r\n#ifdef __INTEL_COMPILER\r\n# define GTEST_AMBIGUOUS_ELSE_BLOCKER_\r\n#else\r\n# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default:  // NOLINT\r\n#endif\r\n\r\n// Use this annotation at the end of a struct/class definition to\r\n// prevent the compiler from optimizing away instances that are never\r\n// used.  This is useful when all interesting logic happens inside the\r\n// c'tor and / or d'tor.  Example:\r\n//\r\n//   struct Foo {\r\n//     Foo() { ... }\r\n//   } GTEST_ATTRIBUTE_UNUSED_;\r\n//\r\n// Also use it after a variable or parameter declaration to tell the\r\n// compiler the variable/parameter does not have to be used.\r\n#if defined(__GNUC__) && !defined(COMPILER_ICC)\r\n# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))\r\n#else\r\n# define GTEST_ATTRIBUTE_UNUSED_\r\n#endif\r\n\r\n// A macro to disallow operator=\r\n// This should be used in the private: declarations for a class.\r\n#define GTEST_DISALLOW_ASSIGN_(type)\\\r\n  void operator=(type const &)\r\n\r\n// A macro to disallow copy constructor and operator=\r\n// This should be used in the private: declarations for a class.\r\n#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\\\r\n  type(type const &);\\\r\n  GTEST_DISALLOW_ASSIGN_(type)\r\n\r\n// Tell the compiler to warn about unused return values for functions declared\r\n// with this macro.  The macro should be used on function declarations\r\n// following the argument list:\r\n//\r\n//   Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;\r\n#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)\r\n# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))\r\n#else\r\n# define GTEST_MUST_USE_RESULT_\r\n#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC\r\n\r\n// Determine whether the compiler supports Microsoft's Structured Exception\r\n// Handling.  This is supported by several Windows compilers but generally\r\n// does not exist on any other system.\r\n#ifndef GTEST_HAS_SEH\r\n// The user didn't tell us, so we need to figure it out.\r\n\r\n# if defined(_MSC_VER) || defined(__BORLANDC__)\r\n// These two compilers are known to support SEH.\r\n#  define GTEST_HAS_SEH 1\r\n# else\r\n// Assume no SEH.\r\n#  define GTEST_HAS_SEH 0\r\n# endif\r\n\r\n#endif  // GTEST_HAS_SEH\r\n\r\n#ifdef _MSC_VER\r\n\r\n# if GTEST_LINKED_AS_SHARED_LIBRARY\r\n#  define GTEST_API_ __declspec(dllimport)\r\n# elif GTEST_CREATE_SHARED_LIBRARY\r\n#  define GTEST_API_ __declspec(dllexport)\r\n# endif\r\n\r\n#endif  // _MSC_VER\r\n\r\n#ifndef GTEST_API_\r\n# define GTEST_API_\r\n#endif\r\n\r\n#ifdef __GNUC__\r\n// Ask the compiler to never inline a given function.\r\n# define GTEST_NO_INLINE_ __attribute__((noinline))\r\n#else\r\n# define GTEST_NO_INLINE_\r\n#endif\r\n\r\n// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.\r\n#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)\r\n# define GTEST_HAS_CXXABI_H_ 1\r\n#else\r\n# define GTEST_HAS_CXXABI_H_ 0\r\n#endif\r\n\r\nnamespace testing {\r\n\r\nclass Message;\r\n\r\nnamespace internal {\r\n\r\n// A secret type that Google Test users don't know about.  It has no\r\n// definition on purpose.  Therefore it's impossible to create a\r\n// Secret object, which is what we want.\r\nclass Secret;\r\n\r\n// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time\r\n// expression is true. For example, you could use it to verify the\r\n// size of a static array:\r\n//\r\n//   GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,\r\n//                         content_type_names_incorrect_size);\r\n//\r\n// or to make sure a struct is smaller than a certain size:\r\n//\r\n//   GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);\r\n//\r\n// The second argument to the macro is the name of the variable. If\r\n// the expression is false, most compilers will issue a warning/error\r\n// containing the name of the variable.\r\n\r\ntemplate <bool>\r\nstruct CompileAssert {\r\n};\r\n\r\n#define GTEST_COMPILE_ASSERT_(expr, msg) \\\r\n  typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \\\r\n      msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_\r\n\r\n// Implementation details of GTEST_COMPILE_ASSERT_:\r\n//\r\n// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1\r\n//   elements (and thus is invalid) when the expression is false.\r\n//\r\n// - The simpler definition\r\n//\r\n//    #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]\r\n//\r\n//   does not work, as gcc supports variable-length arrays whose sizes\r\n//   are determined at run-time (this is gcc's extension and not part\r\n//   of the C++ standard).  As a result, gcc fails to reject the\r\n//   following code with the simple definition:\r\n//\r\n//     int foo;\r\n//     GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is\r\n//                                      // not a compile-time constant.\r\n//\r\n// - By using the type CompileAssert<(bool(expr))>, we ensures that\r\n//   expr is a compile-time constant.  (Template arguments must be\r\n//   determined at compile-time.)\r\n//\r\n// - The outter parentheses in CompileAssert<(bool(expr))> are necessary\r\n//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written\r\n//\r\n//     CompileAssert<bool(expr)>\r\n//\r\n//   instead, these compilers will refuse to compile\r\n//\r\n//     GTEST_COMPILE_ASSERT_(5 > 0, some_message);\r\n//\r\n//   (They seem to think the \">\" in \"5 > 0\" marks the end of the\r\n//   template argument list.)\r\n//\r\n// - The array size is (bool(expr) ? 1 : -1), instead of simply\r\n//\r\n//     ((expr) ? 1 : -1).\r\n//\r\n//   This is to avoid running into a bug in MS VC 7.1, which\r\n//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.\r\n\r\n// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.\r\n//\r\n// This template is declared, but intentionally undefined.\r\ntemplate <typename T1, typename T2>\r\nstruct StaticAssertTypeEqHelper;\r\n\r\ntemplate <typename T>\r\nstruct StaticAssertTypeEqHelper<T, T> {};\r\n\r\n#if GTEST_HAS_GLOBAL_STRING\r\ntypedef ::string string;\r\n#else\r\ntypedef ::std::string string;\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\ntypedef ::wstring wstring;\r\n#elif GTEST_HAS_STD_WSTRING\r\ntypedef ::std::wstring wstring;\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n// A helper for suppressing warnings on constant condition.  It just\r\n// returns 'condition'.\r\nGTEST_API_ bool IsTrue(bool condition);\r\n\r\n// Defines scoped_ptr.\r\n\r\n// This implementation of scoped_ptr is PARTIAL - it only contains\r\n// enough stuff to satisfy Google Test's need.\r\ntemplate <typename T>\r\nclass scoped_ptr {\r\n public:\r\n  typedef T element_type;\r\n\r\n  explicit scoped_ptr(T* p = NULL) : ptr_(p) {}\r\n  ~scoped_ptr() {\r\n    reset();\r\n  }\r\n\r\n  T& operator*() const {\r\n    return *ptr_;\r\n  }\r\n  T* operator->() const {\r\n    return ptr_;\r\n  }\r\n  T* get() const {\r\n    return ptr_;\r\n  }\r\n\r\n  T* release() {\r\n    T* const ptr = ptr_;\r\n    ptr_ = NULL;\r\n    return ptr;\r\n  }\r\n\r\n  void reset(T* p = NULL) {\r\n    if (p != ptr_) {\r\n      if (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.\r\n        delete ptr_;\r\n      }\r\n\r\n      ptr_ = p;\r\n    }\r\n  }\r\n\r\n private:\r\n  T* ptr_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);\r\n};\r\n\r\n// Defines RE.\r\n\r\n// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended\r\n// Regular Expression syntax.\r\nclass GTEST_API_ RE {\r\n public:\r\n  // A copy constructor is required by the Standard to initialize object\r\n  // references from r-values.\r\n  RE(const RE& other) {\r\n    Init(other.pattern());\r\n  }\r\n\r\n  // Constructs an RE from a string.\r\n  RE(const ::std::string& regex) {\r\n    Init(regex.c_str());  // NOLINT\r\n  }\r\n\r\n#if GTEST_HAS_GLOBAL_STRING\r\n\r\n  RE(const ::string& regex) {\r\n    Init(regex.c_str());  // NOLINT\r\n  }\r\n\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\n  RE(const char* regex) {\r\n    Init(regex);  // NOLINT\r\n  }\r\n  ~RE();\r\n\r\n  // Returns the string representation of the regex.\r\n  const char* pattern() const {\r\n    return pattern_;\r\n  }\r\n\r\n  // FullMatch(str, re) returns true iff regular expression re matches\r\n  // the entire str.\r\n  // PartialMatch(str, re) returns true iff regular expression re\r\n  // matches a substring of str (including str itself).\r\n  //\r\n  // TODO(wan@google.com): make FullMatch() and PartialMatch() work\r\n  // when str contains NUL characters.\r\n  static bool FullMatch(const ::std::string& str, const RE& re) {\r\n    return FullMatch(str.c_str(), re);\r\n  }\r\n  static bool PartialMatch(const ::std::string& str, const RE& re) {\r\n    return PartialMatch(str.c_str(), re);\r\n  }\r\n\r\n#if GTEST_HAS_GLOBAL_STRING\r\n\r\n  static bool FullMatch(const ::string& str, const RE& re) {\r\n    return FullMatch(str.c_str(), re);\r\n  }\r\n  static bool PartialMatch(const ::string& str, const RE& re) {\r\n    return PartialMatch(str.c_str(), re);\r\n  }\r\n\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\n  static bool FullMatch(const char* str, const RE& re);\r\n  static bool PartialMatch(const char* str, const RE& re);\r\n\r\n private:\r\n  void Init(const char* regex);\r\n\r\n  // We use a const char* instead of an std::string, as Google Test used to be\r\n  // used where std::string is not available.  TODO(wan@google.com): change to\r\n  // std::string.\r\n  const char* pattern_;\r\n  bool is_valid_;\r\n\r\n#if GTEST_USES_POSIX_RE\r\n\r\n  regex_t full_regex_;     // For FullMatch().\r\n  regex_t partial_regex_;  // For PartialMatch().\r\n\r\n#else  // GTEST_USES_SIMPLE_RE\r\n\r\n  const char* full_pattern_;  // For FullMatch();\r\n\r\n#endif\r\n\r\n  GTEST_DISALLOW_ASSIGN_(RE);\r\n};\r\n\r\n// Formats a source file path and a line number as they would appear\r\n// in an error message from the compiler used to compile this code.\r\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line);\r\n\r\n// Formats a file location for compiler-independent XML output.\r\n// Although this function is not platform dependent, we put it next to\r\n// FormatFileLocation in order to contrast the two functions.\r\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file,\r\n    int line);\r\n\r\n// Defines logging utilities:\r\n//   GTEST_LOG_(severity) - logs messages at the specified severity level. The\r\n//                          message itself is streamed into the macro.\r\n//   LogToStderr()  - directs all log messages to stderr.\r\n//   FlushInfoLog() - flushes informational log messages.\r\n\r\nenum GTestLogSeverity {\r\n  GTEST_INFO,\r\n  GTEST_WARNING,\r\n  GTEST_ERROR,\r\n  GTEST_FATAL\r\n};\r\n\r\n// Formats log entry severity, provides a stream object for streaming the\r\n// log message, and terminates the message with a newline when going out of\r\n// scope.\r\nclass GTEST_API_ GTestLog {\r\n public:\r\n  GTestLog(GTestLogSeverity severity, const char* file, int line);\r\n\r\n  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\r\n  ~GTestLog();\r\n\r\n  ::std::ostream& GetStream() {\r\n    return ::std::cerr;\r\n  }\r\n\r\n private:\r\n  const GTestLogSeverity severity_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);\r\n};\r\n\r\n#define GTEST_LOG_(severity) \\\r\n    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \\\r\n                                  __FILE__, __LINE__).GetStream()\r\n\r\ninline void LogToStderr() {}\r\ninline void FlushInfoLog() {\r\n  fflush(NULL);\r\n}\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE.\r\n//\r\n// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition\r\n// is not satisfied.\r\n//  Synopsys:\r\n//    GTEST_CHECK_(boolean_condition);\r\n//     or\r\n//    GTEST_CHECK_(boolean_condition) << \"Additional message\";\r\n//\r\n//    This checks the condition and if the condition is not satisfied\r\n//    it prints message about the condition violation, including the\r\n//    condition itself, plus additional message streamed into it, if any,\r\n//    and then it aborts the program. It aborts the program irrespective of\r\n//    whether it is built in the debug mode or not.\r\n#define GTEST_CHECK_(condition) \\\r\n    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\\r\n    if (::testing::internal::IsTrue(condition)) \\\r\n      ; \\\r\n    else \\\r\n      GTEST_LOG_(FATAL) << \"Condition \" #condition \" failed. \"\r\n\r\n// An all-mode assert to verify that the given POSIX-style function\r\n// call returns 0 (indicating success).  Known limitation: this\r\n// doesn't expand to a balanced 'if' statement, so enclose the macro\r\n// in {} if you need to use it as the only statement in an 'if'\r\n// branch.\r\n#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \\\r\n  if (const int gtest_error = (posix_call)) \\\r\n    GTEST_LOG_(FATAL) << #posix_call << \"failed with error \" \\\r\n                      << gtest_error\r\n\r\n// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.\r\n//\r\n// Use ImplicitCast_ as a safe version of static_cast for upcasting in\r\n// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a\r\n// const Foo*).  When you use ImplicitCast_, the compiler checks that\r\n// the cast is safe.  Such explicit ImplicitCast_s are necessary in\r\n// surprisingly many situations where C++ demands an exact type match\r\n// instead of an argument type convertable to a target type.\r\n//\r\n// The syntax for using ImplicitCast_ is the same as for static_cast:\r\n//\r\n//   ImplicitCast_<ToType>(expr)\r\n//\r\n// ImplicitCast_ would have been part of the C++ standard library,\r\n// but the proposal was submitted too late.  It will probably make\r\n// its way into the language in the future.\r\n//\r\n// This relatively ugly name is intentional. It prevents clashes with\r\n// similar functions users may have (e.g., implicit_cast). The internal\r\n// namespace alone is not enough because the function can be found by ADL.\r\ntemplate<typename To>\r\ninline To ImplicitCast_(To x) {\r\n  return x;\r\n}\r\n\r\n// When you upcast (that is, cast a pointer from type Foo to type\r\n// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts\r\n// always succeed.  When you downcast (that is, cast a pointer from\r\n// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because\r\n// how do you know the pointer is really of type SubclassOfFoo?  It\r\n// could be a bare Foo, or of type DifferentSubclassOfFoo.  Thus,\r\n// when you downcast, you should use this macro.  In debug mode, we\r\n// use dynamic_cast<> to double-check the downcast is legal (we die\r\n// if it's not).  In normal mode, we do the efficient static_cast<>\r\n// instead.  Thus, it's important to test in debug mode to make sure\r\n// the cast is legal!\r\n//    This is the only place in the code we should use dynamic_cast<>.\r\n// In particular, you SHOULDN'T be using dynamic_cast<> in order to\r\n// do RTTI (eg code like this:\r\n//    if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);\r\n//    if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);\r\n// You should design the code some other way not to need this.\r\n//\r\n// This relatively ugly name is intentional. It prevents clashes with\r\n// similar functions users may have (e.g., down_cast). The internal\r\n// namespace alone is not enough because the function can be found by ADL.\r\ntemplate<typename To, typename From>  // use like this: DownCast_<T*>(foo);\r\ninline To DownCast_(From* f) {  // so we only accept pointers\r\n  // Ensures that To is a sub-type of From *.  This test is here only\r\n  // for compile-time type checking, and has no overhead in an\r\n  // optimized build at run-time, as it will be optimized away\r\n  // completely.\r\n  if (false) {\r\n    const To to = NULL;\r\n    ::testing::internal::ImplicitCast_<From*>(to);\r\n  }\r\n\r\n#if GTEST_HAS_RTTI\r\n  // RTTI: debug mode only!\r\n  GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL);\r\n#endif\r\n  return static_cast<To>(f);\r\n}\r\n\r\n// Downcasts the pointer of type Base to Derived.\r\n// Derived must be a subclass of Base. The parameter MUST\r\n// point to a class of type Derived, not any subclass of it.\r\n// When RTTI is available, the function performs a runtime\r\n// check to enforce this.\r\ntemplate <class Derived, class Base>\r\nDerived* CheckedDowncastToActualType(Base* base) {\r\n#if GTEST_HAS_RTTI\r\n  GTEST_CHECK_(typeid(*base) == typeid(Derived));\r\n  return dynamic_cast<Derived*>(base);  // NOLINT\r\n#else\r\n  return static_cast<Derived*>(base);  // Poor man's downcast.\r\n#endif\r\n}\r\n\r\n#if GTEST_HAS_STREAM_REDIRECTION\r\n\r\n// Defines the stderr capturer:\r\n//   CaptureStdout     - starts capturing stdout.\r\n//   GetCapturedStdout - stops capturing stdout and returns the captured string.\r\n//   CaptureStderr     - starts capturing stderr.\r\n//   GetCapturedStderr - stops capturing stderr and returns the captured string.\r\n//\r\nGTEST_API_ void CaptureStdout();\r\nGTEST_API_ std::string GetCapturedStdout();\r\nGTEST_API_ void CaptureStderr();\r\nGTEST_API_ std::string GetCapturedStderr();\r\n\r\n#endif  // GTEST_HAS_STREAM_REDIRECTION\r\n\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\nconst ::std::vector<testing::internal::string>& GetInjectableArgvs();\r\nvoid SetInjectableArgvs(const ::std::vector<testing::internal::string>*\r\n                        new_argvs);\r\n\r\n// A copy of all command line arguments.  Set by InitGoogleTest().\r\nextern ::std::vector<testing::internal::string> g_argvs;\r\n\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n// Defines synchronization primitives.\r\n\r\n#if GTEST_HAS_PTHREAD\r\n\r\n// Sleeps for (roughly) n milli-seconds.  This function is only for\r\n// testing Google Test's own constructs.  Don't use it in user tests,\r\n// either directly or indirectly.\r\ninline void SleepMilliseconds(int n) {\r\n  const timespec time = {\r\n    0,                  // 0 seconds.\r\n    n * 1000L * 1000L,  // And n ms.\r\n  };\r\n  nanosleep(&time, NULL);\r\n}\r\n\r\n// Allows a controller thread to pause execution of newly created\r\n// threads until notified.  Instances of this class must be created\r\n// and destroyed in the controller thread.\r\n//\r\n// This class is only for testing Google Test's own constructs. Do not\r\n// use it in user tests, either directly or indirectly.\r\nclass Notification {\r\n public:\r\n  Notification() : notified_(false) {\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));\r\n  }\r\n  ~Notification() {\r\n    pthread_mutex_destroy(&mutex_);\r\n  }\r\n\r\n  // Notifies all threads created with this notification to start. Must\r\n  // be called from the controller thread.\r\n  void Notify() {\r\n    pthread_mutex_lock(&mutex_);\r\n    notified_ = true;\r\n    pthread_mutex_unlock(&mutex_);\r\n  }\r\n\r\n  // Blocks until the controller thread notifies. Must be called from a test\r\n  // thread.\r\n  void WaitForNotification() {\r\n    for (;;) {\r\n      pthread_mutex_lock(&mutex_);\r\n      const bool notified = notified_;\r\n      pthread_mutex_unlock(&mutex_);\r\n\r\n      if (notified) {\r\n        break;\r\n      }\r\n\r\n      SleepMilliseconds(10);\r\n    }\r\n  }\r\n\r\n private:\r\n  pthread_mutex_t mutex_;\r\n  bool notified_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);\r\n};\r\n\r\n// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.\r\n// Consequently, it cannot select a correct instantiation of ThreadWithParam\r\n// in order to call its Run(). Introducing ThreadWithParamBase as a\r\n// non-templated base class for ThreadWithParam allows us to bypass this\r\n// problem.\r\nclass ThreadWithParamBase {\r\n public:\r\n  virtual ~ThreadWithParamBase() {}\r\n  virtual void Run() = 0;\r\n};\r\n\r\n// pthread_create() accepts a pointer to a function type with the C linkage.\r\n// According to the Standard (7.5/1), function types with different linkages\r\n// are different even if they are otherwise identical.  Some compilers (for\r\n// example, SunStudio) treat them as different types.  Since class methods\r\n// cannot be defined with C-linkage we need to define a free C-function to\r\n// pass into pthread_create().\r\nextern \"C\" inline void* ThreadFuncWithCLinkage(void* thread) {\r\n  static_cast<ThreadWithParamBase*>(thread)->Run();\r\n  return NULL;\r\n}\r\n\r\n// Helper class for testing Google Test's multi-threading constructs.\r\n// To use it, write:\r\n//\r\n//   void ThreadFunc(int param) { /* Do things with param */ }\r\n//   Notification thread_can_start;\r\n//   ...\r\n//   // The thread_can_start parameter is optional; you can supply NULL.\r\n//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);\r\n//   thread_can_start.Notify();\r\n//\r\n// These classes are only for testing Google Test's own constructs. Do\r\n// not use them in user tests, either directly or indirectly.\r\ntemplate <typename T>\r\nclass ThreadWithParam : public ThreadWithParamBase {\r\n public:\r\n  typedef void (*UserThreadFunc)(T);\r\n\r\n  ThreadWithParam(\r\n    UserThreadFunc func, T param, Notification* thread_can_start)\r\n    : func_(func),\r\n      param_(param),\r\n      thread_can_start_(thread_can_start),\r\n      finished_(false) {\r\n    ThreadWithParamBase* const base = this;\r\n    // The thread can be created only after all fields except thread_\r\n    // have been initialized.\r\n    GTEST_CHECK_POSIX_SUCCESS_(\r\n      pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));\r\n  }\r\n  ~ThreadWithParam() {\r\n    Join();\r\n  }\r\n\r\n  void Join() {\r\n    if (!finished_) {\r\n      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));\r\n      finished_ = true;\r\n    }\r\n  }\r\n\r\n  virtual void Run() {\r\n    if (thread_can_start_ != NULL) {\r\n      thread_can_start_->WaitForNotification();\r\n    }\r\n\r\n    func_(param_);\r\n  }\r\n\r\n private:\r\n  const UserThreadFunc func_;  // User-supplied thread function.\r\n  const T param_;  // User-supplied parameter to the thread function.\r\n  // When non-NULL, used to block execution until the controller thread\r\n  // notifies.\r\n  Notification* const thread_can_start_;\r\n  bool finished_;  // true iff we know that the thread function has finished.\r\n  pthread_t thread_;  // The native thread object.\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);\r\n};\r\n\r\n// MutexBase and Mutex implement mutex on pthreads-based platforms. They\r\n// are used in conjunction with class MutexLock:\r\n//\r\n//   Mutex mutex;\r\n//   ...\r\n//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end\r\n//                            // of the current scope.\r\n//\r\n// MutexBase implements behavior for both statically and dynamically\r\n// allocated mutexes.  Do not use MutexBase directly.  Instead, write\r\n// the following to define a static mutex:\r\n//\r\n//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);\r\n//\r\n// You can forward declare a static mutex like this:\r\n//\r\n//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);\r\n//\r\n// To create a dynamic mutex, just define an object of type Mutex.\r\nclass MutexBase {\r\n public:\r\n  // Acquires this mutex.\r\n  void Lock() {\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));\r\n    owner_ = pthread_self();\r\n    has_owner_ = true;\r\n  }\r\n\r\n  // Releases this mutex.\r\n  void Unlock() {\r\n    // Since the lock is being released the owner_ field should no longer be\r\n    // considered valid. We don't protect writing to has_owner_ here, as it's\r\n    // the caller's responsibility to ensure that the current thread holds the\r\n    // mutex when this is called.\r\n    has_owner_ = false;\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));\r\n  }\r\n\r\n  // Does nothing if the current thread holds the mutex. Otherwise, crashes\r\n  // with high probability.\r\n  void AssertHeld() const {\r\n    GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))\r\n        << \"The current thread is not holding the mutex @\" << this;\r\n  }\r\n\r\n  // A static mutex may be used before main() is entered.  It may even\r\n  // be used before the dynamic initialization stage.  Therefore we\r\n  // must be able to initialize a static mutex object at link time.\r\n  // This means MutexBase has to be a POD and its member variables\r\n  // have to be public.\r\n public:\r\n  pthread_mutex_t mutex_;  // The underlying pthread mutex.\r\n  // has_owner_ indicates whether the owner_ field below contains a valid thread\r\n  // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All\r\n  // accesses to the owner_ field should be protected by a check of this field.\r\n  // An alternative might be to memset() owner_ to all zeros, but there's no\r\n  // guarantee that a zero'd pthread_t is necessarily invalid or even different\r\n  // from pthread_self().\r\n  bool has_owner_;\r\n  pthread_t owner_;  // The thread holding the mutex.\r\n};\r\n\r\n// Forward-declares a static mutex.\r\n# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\r\n    extern ::testing::internal::MutexBase mutex\r\n\r\n// Defines and statically (i.e. at link time) initializes a static mutex.\r\n// The initialization list here does not explicitly initialize each field,\r\n// instead relying on default initialization for the unspecified fields. In\r\n// particular, the owner_ field (a pthread_t) is not explicitly initialized.\r\n// This allows initialization to work whether pthread_t is a scalar or struct.\r\n// The flag -Wmissing-field-initializers must not be specified for this to work.\r\n# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \\\r\n    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }\r\n\r\n// The Mutex class can only be used for mutexes created at runtime. It\r\n// shares its API with MutexBase otherwise.\r\nclass Mutex : public MutexBase {\r\n public:\r\n  Mutex() {\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));\r\n    has_owner_ = false;\r\n  }\r\n  ~Mutex() {\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));\r\n  }\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);\r\n};\r\n\r\n// We cannot name this class MutexLock as the ctor declaration would\r\n// conflict with a macro named MutexLock, which is defined on some\r\n// platforms.  Hence the typedef trick below.\r\nclass GTestMutexLock {\r\n public:\r\n  explicit GTestMutexLock(MutexBase* mutex)\r\n    : mutex_(mutex) {\r\n    mutex_->Lock();\r\n  }\r\n\r\n  ~GTestMutexLock() {\r\n    mutex_->Unlock();\r\n  }\r\n\r\n private:\r\n  MutexBase* const mutex_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);\r\n};\r\n\r\ntypedef GTestMutexLock MutexLock;\r\n\r\n// Helpers for ThreadLocal.\r\n\r\n// pthread_key_create() requires DeleteThreadLocalValue() to have\r\n// C-linkage.  Therefore it cannot be templatized to access\r\n// ThreadLocal<T>.  Hence the need for class\r\n// ThreadLocalValueHolderBase.\r\nclass ThreadLocalValueHolderBase {\r\n public:\r\n  virtual ~ThreadLocalValueHolderBase() {}\r\n};\r\n\r\n// Called by pthread to delete thread-local data stored by\r\n// pthread_setspecific().\r\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\r\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\r\n}\r\n\r\n// Implements thread-local storage on pthreads-based systems.\r\n//\r\n//   // Thread 1\r\n//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.\r\n//\r\n//   // Thread 2\r\n//   tl.set(150);  // Changes the value for thread 2 only.\r\n//   EXPECT_EQ(150, tl.get());\r\n//\r\n//   // Thread 1\r\n//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.\r\n//   tl.set(200);\r\n//   EXPECT_EQ(200, tl.get());\r\n//\r\n// The template type argument T must have a public copy constructor.\r\n// In addition, the default ThreadLocal constructor requires T to have\r\n// a public default constructor.\r\n//\r\n// An object managed for a thread by a ThreadLocal instance is deleted\r\n// when the thread exits.  Or, if the ThreadLocal instance dies in\r\n// that thread, when the ThreadLocal dies.  It's the user's\r\n// responsibility to ensure that all other threads using a ThreadLocal\r\n// have exited when it dies, or the per-thread objects for those\r\n// threads will not be deleted.\r\n//\r\n// Google Test only uses global ThreadLocal objects.  That means they\r\n// will die after main() has returned.  Therefore, no per-thread\r\n// object managed by Google Test will be leaked as long as all threads\r\n// using Google Test have exited when main() returns.\r\ntemplate <typename T>\r\nclass ThreadLocal {\r\n public:\r\n  ThreadLocal() : key_(CreateKey()),\r\n    default_() {}\r\n  explicit ThreadLocal(const T& value) : key_(CreateKey()),\r\n    default_(value) {}\r\n\r\n  ~ThreadLocal() {\r\n    // Destroys the managed object for the current thread, if any.\r\n    DeleteThreadLocalValue(pthread_getspecific(key_));\r\n\r\n    // Releases resources associated with the key.  This will *not*\r\n    // delete managed objects for other threads.\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));\r\n  }\r\n\r\n  T* pointer() {\r\n    return GetOrCreateValue();\r\n  }\r\n  const T* pointer() const {\r\n    return GetOrCreateValue();\r\n  }\r\n  const T& get() const {\r\n    return *pointer();\r\n  }\r\n  void set(const T& value) {\r\n    *pointer() = value;\r\n  }\r\n\r\n private:\r\n  // Holds a value of type T.\r\n  class ValueHolder : public ThreadLocalValueHolderBase {\r\n   public:\r\n    explicit ValueHolder(const T& value) : value_(value) {}\r\n\r\n    T* pointer() {\r\n      return &value_;\r\n    }\r\n\r\n   private:\r\n    T value_;\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);\r\n  };\r\n\r\n  static pthread_key_t CreateKey() {\r\n    pthread_key_t key;\r\n    // When a thread exits, DeleteThreadLocalValue() will be called on\r\n    // the object managed for that thread.\r\n    GTEST_CHECK_POSIX_SUCCESS_(\r\n      pthread_key_create(&key, &DeleteThreadLocalValue));\r\n    return key;\r\n  }\r\n\r\n  T* GetOrCreateValue() const {\r\n    ThreadLocalValueHolderBase* const holder =\r\n      static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));\r\n\r\n    if (holder != NULL) {\r\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\r\n    }\r\n\r\n    ValueHolder* const new_holder = new ValueHolder(default_);\r\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\r\n    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));\r\n    return new_holder->pointer();\r\n  }\r\n\r\n  // A key pthreads uses for looking up per-thread values.\r\n  const pthread_key_t key_;\r\n  const T default_;  // The default value for each thread.\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);\r\n};\r\n\r\n# define GTEST_IS_THREADSAFE 1\r\n\r\n#else  // GTEST_HAS_PTHREAD\r\n\r\n// A dummy implementation of synchronization primitives (mutex, lock,\r\n// and thread-local variable).  Necessary for compiling Google Test where\r\n// mutex is not supported - using Google Test in multiple threads is not\r\n// supported on such platforms.\r\n\r\nclass Mutex {\r\n public:\r\n\r\n  /**\r\n   * Original Code being commented out and replaced\r\n   * with changes made by Mario.\r\n   *\r\n\r\n  Mutex() {}\r\n  void Lock() {}\r\n  void Unlock() {}\r\n  void AssertHeld() const {}\r\n\r\n  *\r\n  */\r\n  Mutex(): owner_(0), handle_() {\r\n    ::InitializeCriticalSection(&handle_);\r\n  }\r\n\r\n  ~Mutex() {\r\n    ::DeleteCriticalSection(&handle_);\r\n  }\r\n\r\n  void Lock() {\r\n    ::EnterCriticalSection(&handle_);\r\n    owner_ = ::GetCurrentThreadId();\r\n  }\r\n\r\n  void Unlock() {\r\n    ::LeaveCriticalSection(&handle_);\r\n    owner_ = 0;\r\n  }\r\n\r\n  // Does nothing if the current thread holds the mutex.\r\n  // Otherwise, crashes with high probability.\r\n  void AssertHeld() const {\r\n    GTEST_CHECK_(owner_ == ::GetCurrentThreadId())\r\n        << \"The current thread is not holding the mutex @\" << this;\r\n  }\r\n\r\n private:\r\n  DWORD              owner_;\r\n  CRITICAL_SECTION   handle_;\r\n};\r\n\r\n// Changing the extern to static in the following statement\r\n// per changes by Mario\r\n# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \\\r\n  static ::testing::internal::Mutex mutex\r\n\r\n// Changing the extern to static in the following statement\r\n// per changes by Mario\r\n# define GTEST_DEFINE_STATIC_MUTEX_(mutex)\r\n\r\nclass GTestMutexLock {\r\n public:\r\n  /**\r\n   * Replacing original code with changes made by Mario\r\n  explicit GTestMutexLock(Mutex*) {}  // NOLINT\r\n  */\r\n\r\n  explicit GTestMutexLock(Mutex* inMutex) : mutex_(inMutex) {\r\n    mutex_->Lock();\r\n  }\r\n\r\n  ~GTestMutexLock() {\r\n    mutex_->Unlock();\r\n  }\r\n\r\n private:\r\n  Mutex* mutex_;\r\n};\r\n\r\ntypedef GTestMutexLock MutexLock;\r\n\r\nclass ThreadLocalValueHolderBase {\r\n public:\r\n  virtual ~ThreadLocalValueHolderBase() {}\r\n};\r\n\r\nextern \"C\" inline void DeleteThreadLocalValue(void* value_holder) {\r\n  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);\r\n}\r\n\r\n// Implements thread-local storage on windows system.\r\ntemplate <typename T>\r\nclass ThreadLocal {\r\n public:\r\n\r\n  /**\r\n   * Replacing original code with changes from Mario\r\n   *\r\n  ThreadLocal() : value_() {}\r\n  explicit ThreadLocal(const T& value) : value_(value) {}\r\n  T* pointer() { return &value_; }\r\n  const T* pointer() const { return &value_; }\r\n  const T& get() const { return value_; }\r\n  void set(const T& value) { value_ = value; }\r\n  */\r\n\r\n  ThreadLocal() : key_(CreateKey()),\r\n    default_() {}\r\n  explicit ThreadLocal(const T& value) : key_(CreateKey()),\r\n    default_(value) {}\r\n\r\n  ~ThreadLocal() {\r\n    // Destroys the managed object for the current thread, if any.\r\n    DeleteThreadLocalValue(TlsGetValue(key_));\r\n\r\n    // Releases resources associated with the key.  This will *not*\r\n    // delete managed objects for other threads.\r\n    GTEST_CHECK_(TlsFree(key_) > 0);\r\n  }\r\n\r\n  T* pointer() {\r\n    return GetOrCreateValue();\r\n  }\r\n  const T* pointer() const {\r\n    return GetOrCreateValue();\r\n  }\r\n  const T& get() const {\r\n    return *pointer();\r\n  }\r\n  void set(const T& value) {\r\n    *pointer() = value;\r\n  }\r\n\r\n private:\r\n  // Holds a value of type T.\r\n  class ValueHolder : public ThreadLocalValueHolderBase {\r\n   public:\r\n    explicit ValueHolder(const T& value) : value_(value) {}\r\n\r\n    T* pointer() {\r\n      return &value_;\r\n    }\r\n\r\n   private:\r\n    T value_;\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);\r\n  };\r\n\r\n  static DWORD CreateKey() {\r\n    DWORD key;\r\n    // When a thread exits, DeleteThreadLocalValue() will be called on\r\n    // the object managed for that thread.\r\n    GTEST_CHECK_((key = TlsAlloc()) != TLS_OUT_OF_INDEXES);\r\n    return key;\r\n  }\r\n\r\n  T* GetOrCreateValue() const {\r\n    ThreadLocalValueHolderBase* const holder =\r\n      static_cast<ThreadLocalValueHolderBase*>(TlsGetValue(key_));\r\n\r\n    if (holder != NULL) {\r\n      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();\r\n    }\r\n\r\n    ValueHolder* const new_holder = new ValueHolder(default_);\r\n    ThreadLocalValueHolderBase* const holder_base = new_holder;\r\n    GTEST_CHECK_(TlsSetValue(key_, holder_base) != 0);\r\n    return new_holder->pointer();\r\n  }\r\n\r\n  // A key pthreads uses for looking up per-thread values.\r\n  const DWORD key_;\r\n  const T default_;  // The default value for each thread.\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);\r\n};\r\n\r\n// The above synchronization primitives have dummy implementations.\r\n// Therefore Google Test is not thread-safe.\r\n# define GTEST_IS_THREADSAFE 0\r\n\r\n#endif  // GTEST_HAS_PTHREAD\r\n\r\n// Returns the number of threads running in the process, or 0 to indicate that\r\n// we cannot detect it.\r\nGTEST_API_ size_t GetThreadCount();\r\n\r\n// Passing non-POD classes through ellipsis (...) crashes the ARM\r\n// compiler and generates a warning in Sun Studio.  The Nokia Symbian\r\n// and the IBM XL C/C++ compiler try to instantiate a copy constructor\r\n// for objects passed through ellipsis (...), failing for uncopyable\r\n// objects.  We define this to ensure that only POD is passed through\r\n// ellipsis on these systems.\r\n#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)\r\n// We lose support for NULL detection where the compiler doesn't like\r\n// passing non-POD classes through ellipsis (...).\r\n# define GTEST_ELLIPSIS_NEEDS_POD_ 1\r\n#else\r\n# define GTEST_CAN_COMPARE_NULL 1\r\n#endif\r\n\r\n// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between\r\n// const T& and const T* in a function template.  These compilers\r\n// _can_ decide between class template specializations for T and T*,\r\n// so a tr1::type_traits-like is_pointer works.\r\n#if defined(__SYMBIAN32__) || defined(__IBMCPP__)\r\n# define GTEST_NEEDS_IS_POINTER_ 1\r\n#endif\r\n\r\ntemplate <bool bool_value>\r\nstruct bool_constant {\r\n  typedef bool_constant<bool_value> type;\r\n  static const bool value = bool_value;\r\n};\r\ntemplate <bool bool_value> const bool bool_constant<bool_value>::value;\r\n\r\ntypedef bool_constant<false> false_type;\r\ntypedef bool_constant<true> true_type;\r\n\r\ntemplate <typename T>\r\nstruct is_pointer : public false_type {};\r\n\r\ntemplate <typename T>\r\nstruct is_pointer<T*> : public true_type {};\r\n\r\ntemplate <typename Iterator>\r\nstruct IteratorTraits {\r\n  typedef typename Iterator::value_type value_type;\r\n};\r\n\r\ntemplate <typename T>\r\nstruct IteratorTraits<T*> {\r\n  typedef T value_type;\r\n};\r\n\r\ntemplate <typename T>\r\nstruct IteratorTraits<const T*> {\r\n  typedef T value_type;\r\n};\r\n\r\n#if GTEST_OS_WINDOWS\r\n# define GTEST_PATH_SEP_ \"\\\\\"\r\n# define GTEST_HAS_ALT_PATH_SEP_ 1\r\n// The biggest signed integer type the compiler supports.\r\ntypedef __int64 BiggestInt;\r\n#else\r\n# define GTEST_PATH_SEP_ \"/\"\r\n# define GTEST_HAS_ALT_PATH_SEP_ 0\r\ntypedef long long BiggestInt;  // NOLINT\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Utilities for char.\r\n\r\n// isspace(int ch) and friends accept an unsigned char or EOF.  char\r\n// may be signed, depending on the compiler (or compiler flags).\r\n// Therefore we need to cast a char to unsigned char before calling\r\n// isspace(), etc.\r\n\r\ninline bool IsAlpha(char ch) {\r\n  return isalpha(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsAlNum(char ch) {\r\n  return isalnum(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsDigit(char ch) {\r\n  return isdigit(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsLower(char ch) {\r\n  return islower(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsSpace(char ch) {\r\n  return isspace(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsUpper(char ch) {\r\n  return isupper(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsXDigit(char ch) {\r\n  return isxdigit(static_cast<unsigned char>(ch)) != 0;\r\n}\r\ninline bool IsXDigit(wchar_t ch) {\r\n  const unsigned char low_byte = static_cast<unsigned char>(ch);\r\n  return ch == low_byte && isxdigit(low_byte) != 0;\r\n}\r\n\r\ninline char ToLower(char ch) {\r\n  return static_cast<char>(tolower(static_cast<unsigned char>(ch)));\r\n}\r\ninline char ToUpper(char ch) {\r\n  return static_cast<char>(toupper(static_cast<unsigned char>(ch)));\r\n}\r\n\r\n// The testing::internal::posix namespace holds wrappers for common\r\n// POSIX functions.  These wrappers hide the differences between\r\n// Windows/MSVC and POSIX systems.  Since some compilers define these\r\n// standard functions as macros, the wrapper cannot have the same name\r\n// as the wrapped function.\r\n\r\nnamespace posix {\r\n\r\n// Functions with a different name on Windows.\r\n\r\n#if GTEST_OS_WINDOWS\r\n\r\ntypedef struct _stat StatStruct;\r\n\r\n# ifdef __BORLANDC__\r\ninline int IsATTY(int fd) {\r\n  return isatty(fd);\r\n}\r\ninline int StrCaseCmp(const char* s1, const char* s2) {\r\n  return stricmp(s1, s2);\r\n}\r\ninline char* StrDup(const char* src) {\r\n  return strdup(src);\r\n}\r\n# else  // !__BORLANDC__\r\n#  if GTEST_OS_WINDOWS_MOBILE\r\ninline int IsATTY(int /* fd */) {\r\n  return 0;\r\n}\r\n#  else\r\ninline int IsATTY(int fd) {\r\n  return _isatty(fd);\r\n}\r\n#  endif  // GTEST_OS_WINDOWS_MOBILE\r\ninline int StrCaseCmp(const char* s1, const char* s2) {\r\n  return _stricmp(s1, s2);\r\n}\r\ninline char* StrDup(const char* src) {\r\n  return _strdup(src);\r\n}\r\n# endif  // __BORLANDC__\r\n\r\n# if GTEST_OS_WINDOWS_MOBILE\r\ninline int FileNo(FILE* file) {\r\n  return reinterpret_cast<int>(_fileno(file));\r\n}\r\n// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this\r\n// time and thus not defined there.\r\n# else\r\ninline int FileNo(FILE* file) {\r\n  return _fileno(file);\r\n}\r\ninline int Stat(const char* path, StatStruct* buf) {\r\n  return _stat(path, buf);\r\n}\r\ninline int RmDir(const char* dir) {\r\n  return _rmdir(dir);\r\n}\r\ninline bool IsDir(const StatStruct& st) {\r\n  return (_S_IFDIR & st.st_mode) != 0;\r\n}\r\n# endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n#else\r\n\r\ntypedef struct stat StatStruct;\r\n\r\ninline int FileNo(FILE* file) {\r\n  return fileno(file);\r\n}\r\ninline int IsATTY(int fd) {\r\n  return isatty(fd);\r\n}\r\ninline int Stat(const char* path, StatStruct* buf) {\r\n  return stat(path, buf);\r\n}\r\ninline int StrCaseCmp(const char* s1, const char* s2) {\r\n  return strcasecmp(s1, s2);\r\n}\r\ninline char* StrDup(const char* src) {\r\n  return strdup(src);\r\n}\r\ninline int RmDir(const char* dir) {\r\n  return rmdir(dir);\r\n}\r\ninline bool IsDir(const StatStruct& st) {\r\n  return S_ISDIR(st.st_mode);\r\n}\r\n\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Functions deprecated by MSVC 8.0.\r\n\r\n#ifdef _MSC_VER\r\n// Temporarily disable warning 4996 (deprecated function).\r\n# pragma warning(push)\r\n# pragma warning(disable:4996)\r\n#endif\r\n\r\ninline const char* StrNCpy(char* dest, const char* src, size_t n) {\r\n  return strncpy(dest, src, n);\r\n}\r\n\r\n// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and\r\n// StrError() aren't needed on Windows CE at this time and thus not\r\n// defined there.\r\n\r\n#if !GTEST_OS_WINDOWS_MOBILE\r\ninline int ChDir(const char* dir) {\r\n  return chdir(dir);\r\n}\r\n#endif\r\ninline FILE* FOpen(const char* path, const char* mode) {\r\n  return fopen(path, mode);\r\n}\r\n#if !GTEST_OS_WINDOWS_MOBILE\r\ninline FILE* FReopen(const char* path, const char* mode, FILE* stream) {\r\n  return freopen(path, mode, stream);\r\n}\r\ninline FILE* FDOpen(int fd, const char* mode) {\r\n  return fdopen(fd, mode);\r\n}\r\n#endif\r\ninline int FClose(FILE* fp) {\r\n  return fclose(fp);\r\n}\r\n#if !GTEST_OS_WINDOWS_MOBILE\r\ninline int Read(int fd, void* buf, unsigned int count) {\r\n  return static_cast<int>(read(fd, buf, count));\r\n}\r\ninline int Write(int fd, const void* buf, unsigned int count) {\r\n  return static_cast<int>(write(fd, buf, count));\r\n}\r\ninline int Close(int fd) {\r\n  return close(fd);\r\n}\r\ninline const char* StrError(int errnum) {\r\n  return strerror(errnum);\r\n}\r\n#endif\r\ninline const char* GetEnv(const char* name) {\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  // We are on Windows CE, which has no environment variables.\r\n  return NULL;\r\n#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)\r\n  // Environment variables which we programmatically clear will be set to the\r\n  // empty string rather than unset (NULL).  Handle that case.\r\n  const char* const env = getenv(name);\r\n  return (env != NULL && env[0] != '\\0') ? env : NULL;\r\n#else\r\n  return getenv(name);\r\n#endif\r\n}\r\n\r\n#ifdef _MSC_VER\r\n# pragma warning(pop)  // Restores the warning state.\r\n#endif\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n// Windows CE has no C library. The abort() function is used in\r\n// several places in Google Test. This implementation provides a reasonable\r\n// imitation of standard behaviour.\r\nvoid Abort();\r\n#else\r\ninline void Abort() {\r\n  abort();\r\n}\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n}  // namespace posix\r\n\r\n// MSVC \"deprecates\" snprintf and issues warnings wherever it is used.  In\r\n// order to avoid these warnings, we need to use _snprintf or _snprintf_s on\r\n// MSVC-based platforms.  We map the GTEST_SNPRINTF_ macro to the appropriate\r\n// function in order to achieve that.  We use macro definition here because\r\n// snprintf is a variadic function.\r\n#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE\r\n// MSVC 2005 and above support variadic macros.\r\n# define GTEST_SNPRINTF_(buffer, size, format, ...) \\\r\n     _snprintf_s(buffer, size, size, format, __VA_ARGS__)\r\n#elif defined(_MSC_VER)\r\n// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't\r\n// complain about _snprintf.\r\n# define GTEST_SNPRINTF_ _snprintf\r\n#else\r\n# define GTEST_SNPRINTF_ snprintf\r\n#endif\r\n\r\n// The maximum number a BiggestInt can represent.  This definition\r\n// works no matter BiggestInt is represented in one's complement or\r\n// two's complement.\r\n//\r\n// We cannot rely on numeric_limits in STL, as __int64 and long long\r\n// are not part of standard C++ and numeric_limits doesn't need to be\r\n// defined for them.\r\nconst BiggestInt kMaxBiggestInt =\r\n  ~(static_cast<BiggestInt>(1) << (8 * sizeof(BiggestInt) - 1));\r\n\r\n// This template class serves as a compile-time function from size to\r\n// type.  It maps a size in bytes to a primitive type with that\r\n// size. e.g.\r\n//\r\n//   TypeWithSize<4>::UInt\r\n//\r\n// is typedef-ed to be unsigned int (unsigned integer made up of 4\r\n// bytes).\r\n//\r\n// Such functionality should belong to STL, but I cannot find it\r\n// there.\r\n//\r\n// Google Test uses this class in the implementation of floating-point\r\n// comparison.\r\n//\r\n// For now it only handles UInt (unsigned int) as that's all Google Test\r\n// needs.  Other types can be easily added in the future if need\r\n// arises.\r\ntemplate <size_t size>\r\nclass TypeWithSize {\r\n public:\r\n  // This prevents the user from using TypeWithSize<N> with incorrect\r\n  // values of N.\r\n  typedef void UInt;\r\n};\r\n\r\n// The specialization for size 4.\r\ntemplate <>\r\nclass TypeWithSize<4> {\r\n public:\r\n  // unsigned int has size 4 in both gcc and MSVC.\r\n  //\r\n  // As base/basictypes.h doesn't compile on Windows, we cannot use\r\n  // uint32, uint64, and etc here.\r\n  typedef int Int;\r\n  typedef unsigned int UInt;\r\n};\r\n\r\n// The specialization for size 8.\r\ntemplate <>\r\nclass TypeWithSize<8> {\r\n public:\r\n#if GTEST_OS_WINDOWS\r\n  typedef __int64 Int;\r\n  typedef unsigned __int64 UInt;\r\n#else\r\n  typedef long long Int;  // NOLINT\r\n  typedef unsigned long long UInt;  // NOLINT\r\n#endif  // GTEST_OS_WINDOWS\r\n};\r\n\r\n// Integer types of known sizes.\r\ntypedef TypeWithSize<4>::Int Int32;\r\ntypedef TypeWithSize<4>::UInt UInt32;\r\ntypedef TypeWithSize<8>::Int Int64;\r\ntypedef TypeWithSize<8>::UInt UInt64;\r\ntypedef TypeWithSize<8>::Int TimeInMillis;  // Represents time in milliseconds.\r\n\r\n// Utilities for command line flags and environment variables.\r\n\r\n// Macro for referencing flags.\r\n#define GTEST_FLAG(name) FLAGS_gtest_##name\r\n\r\n// Macros for declaring flags.\r\n#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)\r\n#define GTEST_DECLARE_int32_(name) \\\r\n    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)\r\n#define GTEST_DECLARE_string_(name) \\\r\n    GTEST_API_ extern ::std::string GTEST_FLAG(name)\r\n\r\n// Macros for defining flags.\r\n#define GTEST_DEFINE_bool_(name, default_val, doc) \\\r\n    GTEST_API_ bool GTEST_FLAG(name) = (default_val)\r\n#define GTEST_DEFINE_int32_(name, default_val, doc) \\\r\n    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)\r\n#define GTEST_DEFINE_string_(name, default_val, doc) \\\r\n    GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)\r\n\r\n// Thread annotations\r\n#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)\r\n#define GTEST_LOCK_EXCLUDED_(locks)\r\n\r\n// Parses 'str' for a 32-bit signed integer.  If successful, writes the result\r\n// to *value and returns true; otherwise leaves *value unchanged and returns\r\n// false.\r\n// TODO(chandlerc): Find a better way to refactor flag and environment parsing\r\n// out of both gtest-port.cc and gtest.cc to avoid exporting this utility\r\n// function.\r\nbool ParseInt32(const Message& src_text, const char* str, Int32* value);\r\n\r\n// Parses a bool/Int32/string from the environment variable\r\n// corresponding to the given Google Test flag.\r\nbool BoolFromGTestEnv(const char* flag, bool default_val);\r\nGTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);\r\nconst char* StringFromGTestEnv(const char* flag, const char* default_val);\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-string.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n//\r\n// This header file declares the String class and functions used internally by\r\n// Google Test.  They are subject to change without notice. They should not used\r\n// by code external to Google Test.\r\n//\r\n// This header file is #included by <gtest/internal/gtest-internal.h>.\r\n// It should not be #included by other files.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\r\n\r\n#ifdef __BORLANDC__\r\n// string.h is not guaranteed to provide strcpy on C++ Builder.\r\n# include <mem.h>\r\n#endif\r\n\r\n#include <string.h>\r\n#include <string>\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// String - an abstract class holding static string utilities.\r\nclass GTEST_API_ String {\r\n public:\r\n  // Static utility methods\r\n\r\n  // Clones a 0-terminated C string, allocating memory using new.  The\r\n  // caller is responsible for deleting the return value using\r\n  // delete[].  Returns the cloned string, or NULL if the input is\r\n  // NULL.\r\n  //\r\n  // This is different from strdup() in string.h, which allocates\r\n  // memory using malloc().\r\n  static const char* CloneCString(const char* c_str);\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be\r\n  // able to pass strings to Win32 APIs on CE we need to convert them\r\n  // to 'Unicode', UTF-16.\r\n\r\n  // Creates a UTF-16 wide string from the given ANSI string, allocating\r\n  // memory using new. The caller is responsible for deleting the return\r\n  // value using delete[]. Returns the wide string, or NULL if the\r\n  // input is NULL.\r\n  //\r\n  // The wide string is created using the ANSI codepage (CP_ACP) to\r\n  // match the behaviour of the ANSI versions of Win32 calls and the\r\n  // C runtime.\r\n  static LPCWSTR AnsiToUtf16(const char* c_str);\r\n\r\n  // Creates an ANSI string from the given wide string, allocating\r\n  // memory using new. The caller is responsible for deleting the return\r\n  // value using delete[]. Returns the ANSI string, or NULL if the\r\n  // input is NULL.\r\n  //\r\n  // The returned string is created using the ANSI codepage (CP_ACP) to\r\n  // match the behaviour of the ANSI versions of Win32 calls and the\r\n  // C runtime.\r\n  static const char* Utf16ToAnsi(LPCWSTR utf16_str);\r\n#endif\r\n\r\n  // Compares two C strings.  Returns true iff they have the same content.\r\n  //\r\n  // Unlike strcmp(), this function can handle NULL argument(s).  A\r\n  // NULL C string is considered different to any non-NULL C string,\r\n  // including the empty string.\r\n  static bool CStringEquals(const char* lhs, const char* rhs);\r\n\r\n  // Converts a wide C string to a String using the UTF-8 encoding.\r\n  // NULL will be converted to \"(null)\".  If an error occurred during\r\n  // the conversion, \"(failed to convert from wide string)\" is\r\n  // returned.\r\n  static std::string ShowWideCString(const wchar_t* wide_c_str);\r\n\r\n  // Compares two wide C strings.  Returns true iff they have the same\r\n  // content.\r\n  //\r\n  // Unlike wcscmp(), this function can handle NULL argument(s).  A\r\n  // NULL C string is considered different to any non-NULL C string,\r\n  // including the empty string.\r\n  static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);\r\n\r\n  // Compares two C strings, ignoring case.  Returns true iff they\r\n  // have the same content.\r\n  //\r\n  // Unlike strcasecmp(), this function can handle NULL argument(s).\r\n  // A NULL C string is considered different to any non-NULL C string,\r\n  // including the empty string.\r\n  static bool CaseInsensitiveCStringEquals(const char* lhs,\r\n      const char* rhs);\r\n\r\n  // Compares two wide C strings, ignoring case.  Returns true iff they\r\n  // have the same content.\r\n  //\r\n  // Unlike wcscasecmp(), this function can handle NULL argument(s).\r\n  // A NULL C string is considered different to any non-NULL wide C string,\r\n  // including the empty string.\r\n  // NB: The implementations on different platforms slightly differ.\r\n  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE\r\n  // environment variable. On GNU platform this method uses wcscasecmp\r\n  // which compares according to LC_CTYPE category of the current locale.\r\n  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\r\n  // current locale.\r\n  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\r\n      const wchar_t* rhs);\r\n\r\n  // Returns true iff the given string ends with the given suffix, ignoring\r\n  // case. Any string is considered to end with an empty suffix.\r\n  static bool EndsWithCaseInsensitive(\r\n    const std::string& str, const std::string& suffix);\r\n\r\n  // Formats an int value as \"%02d\".\r\n  static std::string FormatIntWidth2(int value);  // \"%02d\" for width == 2\r\n\r\n  // Formats an int value as \"%X\".\r\n  static std::string FormatHexInt(int value);\r\n\r\n  // Formats a byte as \"%02X\".\r\n  static std::string FormatByte(unsigned char value);\r\n\r\n private:\r\n  String();  // Not meant to be instantiated.\r\n};  // class String\r\n\r\n// Gets the content of the stringstream's buffer as an std::string.  Each '\\0'\r\n// character in the buffer is replaced with \"\\\\0\".\r\nGTEST_API_ std::string StringStreamToString(::std::stringstream* stream);\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-tuple.h",
    "content": "// This file was GENERATED by command:\r\n//     pump.py gtest-tuple.h.pump\r\n// DO NOT EDIT BY HAND!!!\r\n\r\n// Copyright 2009 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Implements a subset of TR1 tuple needed by Google Test and Google Mock.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n\r\n#include <utility>  // For ::std::pair.\r\n\r\n// The compiler used in Symbian has a bug that prevents us from declaring the\r\n// tuple template as a friend (it complains that tuple is redefined).  This\r\n// hack bypasses the bug by declaring the members that should otherwise be\r\n// private as public.\r\n// Sun Studio versions < 12 also have the above bug.\r\n#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)\r\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:\r\n#else\r\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \\\r\n    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \\\r\n   private:\r\n#endif\r\n\r\n// GTEST_n_TUPLE_(T) is the type of an n-tuple.\r\n#define GTEST_0_TUPLE_(T) tuple<>\r\n#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \\\r\n    void, void, void>\r\n#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \\\r\n    void, void, void>\r\n#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \\\r\n    void, void, void>\r\n#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \\\r\n    void, void, void>\r\n#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \\\r\n    void, void, void>\r\n#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \\\r\n    void, void, void>\r\n#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\r\n    void, void, void>\r\n#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\r\n    T##7, void, void>\r\n#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\r\n    T##7, T##8, void>\r\n#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \\\r\n    T##7, T##8, T##9>\r\n\r\n// GTEST_n_TYPENAMES_(T) declares a list of n typenames.\r\n#define GTEST_0_TYPENAMES_(T)\r\n#define GTEST_1_TYPENAMES_(T) typename T##0\r\n#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1\r\n#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2\r\n#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3\r\n#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4\r\n#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4, typename T##5\r\n#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4, typename T##5, typename T##6\r\n#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7\r\n#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4, typename T##5, typename T##6, \\\r\n    typename T##7, typename T##8\r\n#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \\\r\n    typename T##3, typename T##4, typename T##5, typename T##6, \\\r\n    typename T##7, typename T##8, typename T##9\r\n\r\n// In theory, defining stuff in the ::std namespace is undefined\r\n// behavior.  We can do this as we are playing the role of a standard\r\n// library vendor.\r\nnamespace std {\r\nnamespace tr1 {\r\n\r\ntemplate <typename T0 = void, typename T1 = void, typename T2 = void,\r\n          typename T3 = void, typename T4 = void, typename T5 = void,\r\n          typename T6 = void, typename T7 = void, typename T8 = void,\r\n          typename T9 = void>\r\nclass tuple;\r\n\r\n// Anything in namespace gtest_internal is Google Test's INTERNAL\r\n// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.\r\nnamespace gtest_internal {\r\n\r\n// ByRef<T>::type is T if T is a reference; otherwise it's const T&.\r\ntemplate <typename T>\r\nstruct ByRef {\r\n  typedef const T& type;\r\n};  // NOLINT\r\ntemplate <typename T>\r\nstruct ByRef<T&> {\r\n  typedef T& type;\r\n};  // NOLINT\r\n\r\n// A handy wrapper for ByRef.\r\n#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type\r\n\r\n// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This\r\n// is the same as tr1::add_reference<T>::type.\r\ntemplate <typename T>\r\nstruct AddRef {\r\n  typedef T& type;\r\n};  // NOLINT\r\ntemplate <typename T>\r\nstruct AddRef<T&> {\r\n  typedef T& type;\r\n};  // NOLINT\r\n\r\n// A handy wrapper for AddRef.\r\n#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type\r\n\r\n// A helper for implementing get<k>().\r\ntemplate <int k> class Get;\r\n\r\n// A helper for implementing tuple_element<k, T>.  kIndexValid is true\r\n// iff k < the number of fields in tuple type T.\r\ntemplate <bool kIndexValid, int kIndex, class Tuple>\r\nstruct TupleElement;\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 0, GTEST_10_TUPLE_(T) > {\r\n  typedef T0 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 1, GTEST_10_TUPLE_(T) > {\r\n  typedef T1 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 2, GTEST_10_TUPLE_(T) > {\r\n  typedef T2 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 3, GTEST_10_TUPLE_(T) > {\r\n  typedef T3 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 4, GTEST_10_TUPLE_(T) > {\r\n  typedef T4 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 5, GTEST_10_TUPLE_(T) > {\r\n  typedef T5 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 6, GTEST_10_TUPLE_(T) > {\r\n  typedef T6 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 7, GTEST_10_TUPLE_(T) > {\r\n  typedef T7 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 8, GTEST_10_TUPLE_(T) > {\r\n  typedef T8 type;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct TupleElement<true, 9, GTEST_10_TUPLE_(T) > {\r\n  typedef T9 type;\r\n};\r\n\r\n}  // namespace gtest_internal\r\n\r\ntemplate <>\r\nclass tuple<> {\r\n public:\r\n  tuple() {}\r\n  tuple(const tuple& /* t */)  {}\r\n  tuple& operator=(const tuple& /* t */) {\r\n    return *this;\r\n  }\r\n};\r\n\r\ntemplate <GTEST_1_TYPENAMES_(T)>\r\nclass GTEST_1_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_) {}\r\n\r\n  template <GTEST_1_TYPENAMES_(U)>\r\n  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_1_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_1_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n};\r\n\r\ntemplate <GTEST_2_TYPENAMES_(T)>\r\nclass GTEST_2_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),\r\n    f1_(f1) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_) {}\r\n\r\n  template <GTEST_2_TYPENAMES_(U)>\r\n  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}\r\n  template <typename U0, typename U1>\r\n  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_2_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n  template <typename U0, typename U1>\r\n  tuple& operator=(const ::std::pair<U0, U1>& p) {\r\n    f0_ = p.first;\r\n    f1_ = p.second;\r\n    return *this;\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_2_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n};\r\n\r\ntemplate <GTEST_3_TYPENAMES_(T)>\r\nclass GTEST_3_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}\r\n\r\n  template <GTEST_3_TYPENAMES_(U)>\r\n  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_3_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_3_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n};\r\n\r\ntemplate <GTEST_4_TYPENAMES_(T)>\r\nclass GTEST_4_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),\r\n    f3_(f3) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}\r\n\r\n  template <GTEST_4_TYPENAMES_(U)>\r\n  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_4_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_4_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n};\r\n\r\ntemplate <GTEST_5_TYPENAMES_(T)>\r\nclass GTEST_5_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,\r\n                 GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_) {}\r\n\r\n  template <GTEST_5_TYPENAMES_(U)>\r\n  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_5_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_5_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n};\r\n\r\ntemplate <GTEST_6_TYPENAMES_(T)>\r\nclass GTEST_6_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\r\n                 GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\r\n    f5_(f5) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_), f5_(t.f5_) {}\r\n\r\n  template <GTEST_6_TYPENAMES_(U)>\r\n  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_6_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_6_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    f5_ = t.f5_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n  T5 f5_;\r\n};\r\n\r\ntemplate <GTEST_7_TYPENAMES_(T)>\r\nclass GTEST_7_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\r\n                 GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),\r\n    f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}\r\n\r\n  template <GTEST_7_TYPENAMES_(U)>\r\n  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_7_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_7_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    f5_ = t.f5_;\r\n    f6_ = t.f6_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n  T5 f5_;\r\n  T6 f6_;\r\n};\r\n\r\ntemplate <GTEST_8_TYPENAMES_(T)>\r\nclass GTEST_8_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\r\n                 GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,\r\n                 GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\r\n    f5_(f5), f6_(f6), f7_(f7) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}\r\n\r\n  template <GTEST_8_TYPENAMES_(U)>\r\n  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_8_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_8_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    f5_ = t.f5_;\r\n    f6_ = t.f6_;\r\n    f7_ = t.f7_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n  T5 f5_;\r\n  T6 f6_;\r\n  T7 f7_;\r\n};\r\n\r\ntemplate <GTEST_9_TYPENAMES_(T)>\r\nclass GTEST_9_TUPLE_(T) {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\r\n                 GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,\r\n                 GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),\r\n    f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}\r\n\r\n  tuple(const tuple & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}\r\n\r\n  template <GTEST_9_TYPENAMES_(U)>\r\n  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}\r\n\r\n  tuple& operator=(const tuple & t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_9_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_9_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    f5_ = t.f5_;\r\n    f6_ = t.f6_;\r\n    f7_ = t.f7_;\r\n    f8_ = t.f8_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n  T5 f5_;\r\n  T6 f6_;\r\n  T7 f7_;\r\n  T8 f8_;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nclass tuple {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),\r\n    f9_() {}\r\n\r\n  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,\r\n                 GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,\r\n                 GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,\r\n                 GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),\r\n    f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}\r\n\r\n  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),\r\n    f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}\r\n\r\n  template <GTEST_10_TYPENAMES_(U)>\r\n  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),\r\n    f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),\r\n    f9_(t.f9_) {}\r\n\r\n  tuple& operator=(const tuple& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  template <GTEST_10_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_10_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {\r\n    f0_ = t.f0_;\r\n    f1_ = t.f1_;\r\n    f2_ = t.f2_;\r\n    f3_ = t.f3_;\r\n    f4_ = t.f4_;\r\n    f5_ = t.f5_;\r\n    f6_ = t.f6_;\r\n    f7_ = t.f7_;\r\n    f8_ = t.f8_;\r\n    f9_ = t.f9_;\r\n    return *this;\r\n  }\r\n\r\n  T0 f0_;\r\n  T1 f1_;\r\n  T2 f2_;\r\n  T3 f3_;\r\n  T4 f4_;\r\n  T5 f5_;\r\n  T6 f6_;\r\n  T7 f7_;\r\n  T8 f8_;\r\n  T9 f9_;\r\n};\r\n\r\n// 6.1.3.2 Tuple creation functions.\r\n\r\n// Known limitations: we don't support passing an\r\n// std::tr1::reference_wrapper<T> to make_tuple().  And we don't\r\n// implement tie().\r\n\r\ninline tuple<> make_tuple() {\r\n  return tuple<>();\r\n}\r\n\r\ntemplate <GTEST_1_TYPENAMES_(T)>\r\ninline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {\r\n  return GTEST_1_TUPLE_(T)(f0);\r\n}\r\n\r\ntemplate <GTEST_2_TYPENAMES_(T)>\r\ninline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {\r\n  return GTEST_2_TUPLE_(T)(f0, f1);\r\n}\r\n\r\ntemplate <GTEST_3_TYPENAMES_(T)>\r\ninline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {\r\n  return GTEST_3_TUPLE_(T)(f0, f1, f2);\r\n}\r\n\r\ntemplate <GTEST_4_TYPENAMES_(T)>\r\ninline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3) {\r\n  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);\r\n}\r\n\r\ntemplate <GTEST_5_TYPENAMES_(T)>\r\ninline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3, const T4& f4) {\r\n  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);\r\n}\r\n\r\ntemplate <GTEST_6_TYPENAMES_(T)>\r\ninline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3, const T4& f4, const T5& f5) {\r\n  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);\r\n}\r\n\r\ntemplate <GTEST_7_TYPENAMES_(T)>\r\ninline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {\r\n  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);\r\n}\r\n\r\ntemplate <GTEST_8_TYPENAMES_(T)>\r\ninline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {\r\n  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);\r\n}\r\n\r\ntemplate <GTEST_9_TYPENAMES_(T)>\r\ninline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,\r\n                                    const T8& f8) {\r\n  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);\r\n}\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\ninline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,\r\n                                     const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,\r\n                                     const T8& f8, const T9& f9) {\r\n  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);\r\n}\r\n\r\n// 6.1.3.3 Tuple helper classes.\r\n\r\ntemplate <typename Tuple> struct tuple_size;\r\n\r\ntemplate <GTEST_0_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_0_TUPLE_(T) > {\r\n  static const int value = 0;\r\n};\r\n\r\ntemplate <GTEST_1_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_1_TUPLE_(T) > {\r\n  static const int value = 1;\r\n};\r\n\r\ntemplate <GTEST_2_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_2_TUPLE_(T) > {\r\n  static const int value = 2;\r\n};\r\n\r\ntemplate <GTEST_3_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_3_TUPLE_(T) > {\r\n  static const int value = 3;\r\n};\r\n\r\ntemplate <GTEST_4_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_4_TUPLE_(T) > {\r\n  static const int value = 4;\r\n};\r\n\r\ntemplate <GTEST_5_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_5_TUPLE_(T) > {\r\n  static const int value = 5;\r\n};\r\n\r\ntemplate <GTEST_6_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_6_TUPLE_(T) > {\r\n  static const int value = 6;\r\n};\r\n\r\ntemplate <GTEST_7_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_7_TUPLE_(T) > {\r\n  static const int value = 7;\r\n};\r\n\r\ntemplate <GTEST_8_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_8_TUPLE_(T) > {\r\n  static const int value = 8;\r\n};\r\n\r\ntemplate <GTEST_9_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_9_TUPLE_(T) > {\r\n  static const int value = 9;\r\n};\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_10_TUPLE_(T) > {\r\n  static const int value = 10;\r\n};\r\n\r\ntemplate <int k, class Tuple>\r\nstruct tuple_element {\r\n  typedef typename gtest_internal::TupleElement <\r\n  k < (tuple_size<Tuple>::value), k, Tuple>::type type;\r\n};\r\n\r\n#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type\r\n\r\n// 6.1.3.4 Element access.\r\n\r\nnamespace gtest_internal {\r\n\r\ntemplate <>\r\nclass Get<0> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f0_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f0_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<1> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f1_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f1_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<2> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f2_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f2_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<3> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f3_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f3_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<4> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f4_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f4_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<5> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f5_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f5_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<6> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f6_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f6_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<7> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f7_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f7_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<8> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f8_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f8_;\r\n  }\r\n};\r\n\r\ntemplate <>\r\nclass Get<9> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))\r\n  Field(Tuple& t) {\r\n    return t.f9_;  // NOLINT\r\n  }\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))\r\n  ConstField(const Tuple& t) {\r\n    return t.f9_;\r\n  }\r\n};\r\n\r\n}  // namespace gtest_internal\r\n\r\ntemplate <int k, GTEST_10_TYPENAMES_(T)>\r\nGTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))\r\nget(GTEST_10_TUPLE_(T)& t) {\r\n  return gtest_internal::Get<k>::Field(t);\r\n}\r\n\r\ntemplate <int k, GTEST_10_TYPENAMES_(T)>\r\nGTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))\r\nget(const GTEST_10_TUPLE_(T)& t) {\r\n  return gtest_internal::Get<k>::ConstField(t);\r\n}\r\n\r\n// 6.1.3.5 Relational operators\r\n\r\n// We only implement == and !=, as we don't have a need for the rest yet.\r\n\r\nnamespace gtest_internal {\r\n\r\n// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the\r\n// first k fields of t1 equals the first k fields of t2.\r\n// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if\r\n// k1 != k2.\r\ntemplate <int kSize1, int kSize2>\r\nstruct SameSizeTuplePrefixComparator;\r\n\r\ntemplate <>\r\nstruct SameSizeTuplePrefixComparator<0, 0> {\r\n  template <class Tuple1, class Tuple2>\r\n  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {\r\n    return true;\r\n  }\r\n};\r\n\r\ntemplate <int k>\r\nstruct SameSizeTuplePrefixComparator<k, k> {\r\n  template <class Tuple1, class Tuple2>\r\n  static bool Eq(const Tuple1& t1, const Tuple2& t2) {\r\n    return SameSizeTuplePrefixComparator < k - 1, k - 1 >::Eq(t1, t2) &&\r\n           ::std::tr1::get < k - 1 > (t1) == ::std::tr1::get < k - 1 > (t2);\r\n  }\r\n};\r\n\r\n}  // namespace gtest_internal\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>\r\ninline bool operator==(const GTEST_10_TUPLE_(T)& t,\r\n                       const GTEST_10_TUPLE_(U)& u) {\r\n  return gtest_internal::SameSizeTuplePrefixComparator <\r\n         tuple_size<GTEST_10_TUPLE_(T) >::value,\r\n         tuple_size<GTEST_10_TUPLE_(U) >::value >::Eq(t, u);\r\n}\r\n\r\ntemplate <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>\r\ninline bool operator!=(const GTEST_10_TUPLE_(T)& t,\r\n                       const GTEST_10_TUPLE_(U)& u) {\r\n  return !(t == u);\r\n}\r\n\r\n// 6.1.4 Pairs.\r\n// Unimplemented.\r\n\r\n}  // namespace tr1\r\n}  // namespace std\r\n\r\n#undef GTEST_0_TUPLE_\r\n#undef GTEST_1_TUPLE_\r\n#undef GTEST_2_TUPLE_\r\n#undef GTEST_3_TUPLE_\r\n#undef GTEST_4_TUPLE_\r\n#undef GTEST_5_TUPLE_\r\n#undef GTEST_6_TUPLE_\r\n#undef GTEST_7_TUPLE_\r\n#undef GTEST_8_TUPLE_\r\n#undef GTEST_9_TUPLE_\r\n#undef GTEST_10_TUPLE_\r\n\r\n#undef GTEST_0_TYPENAMES_\r\n#undef GTEST_1_TYPENAMES_\r\n#undef GTEST_2_TYPENAMES_\r\n#undef GTEST_3_TYPENAMES_\r\n#undef GTEST_4_TYPENAMES_\r\n#undef GTEST_5_TYPENAMES_\r\n#undef GTEST_6_TYPENAMES_\r\n#undef GTEST_7_TYPENAMES_\r\n#undef GTEST_8_TYPENAMES_\r\n#undef GTEST_9_TYPENAMES_\r\n#undef GTEST_10_TYPENAMES_\r\n\r\n#undef GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n#undef GTEST_BY_REF_\r\n#undef GTEST_ADD_REF_\r\n#undef GTEST_TUPLE_ELEMENT_\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-tuple.h.pump",
    "content": "$$ -*- mode: c++; -*-\r\n$var n = 10  $$ Maximum number of tuple fields we want to support.\r\n$$ This meta comment fixes auto-indentation in Emacs. }}\r\n// Copyright 2009 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Implements a subset of TR1 tuple needed by Google Test and Google Mock.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n\r\n#include <utility>  // For ::std::pair.\r\n\r\n// The compiler used in Symbian has a bug that prevents us from declaring the\r\n// tuple template as a friend (it complains that tuple is redefined).  This\r\n// hack bypasses the bug by declaring the members that should otherwise be\r\n// private as public.\r\n// Sun Studio versions < 12 also have the above bug.\r\n#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)\r\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:\r\n#else\r\n# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \\\r\n    template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \\\r\n   private:\r\n#endif\r\n\r\n\r\n$range i 0..n-1\r\n$range j 0..n\r\n$range k 1..n\r\n// GTEST_n_TUPLE_(T) is the type of an n-tuple.\r\n#define GTEST_0_TUPLE_(T) tuple<>\r\n\r\n$for k [[\r\n$range m 0..k-1\r\n$range m2 k..n-1\r\n#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>\r\n\r\n]]\r\n\r\n// GTEST_n_TYPENAMES_(T) declares a list of n typenames.\r\n\r\n$for j [[\r\n$range m 0..j-1\r\n#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]\r\n\r\n\r\n]]\r\n\r\n// In theory, defining stuff in the ::std namespace is undefined\r\n// behavior.  We can do this as we are playing the role of a standard\r\n// library vendor.\r\nnamespace std {\r\nnamespace tr1 {\r\n\r\ntemplate <$for i, [[typename T$i = void]]>\r\nclass tuple;\r\n\r\n// Anything in namespace gtest_internal is Google Test's INTERNAL\r\n// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.\r\nnamespace gtest_internal {\r\n\r\n// ByRef<T>::type is T if T is a reference; otherwise it's const T&.\r\ntemplate <typename T>\r\nstruct ByRef { typedef const T& type; };  // NOLINT\r\ntemplate <typename T>\r\nstruct ByRef<T&> { typedef T& type; };  // NOLINT\r\n\r\n// A handy wrapper for ByRef.\r\n#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type\r\n\r\n// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This\r\n// is the same as tr1::add_reference<T>::type.\r\ntemplate <typename T>\r\nstruct AddRef { typedef T& type; };  // NOLINT\r\ntemplate <typename T>\r\nstruct AddRef<T&> { typedef T& type; };  // NOLINT\r\n\r\n// A handy wrapper for AddRef.\r\n#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type\r\n\r\n// A helper for implementing get<k>().\r\ntemplate <int k> class Get;\r\n\r\n// A helper for implementing tuple_element<k, T>.  kIndexValid is true\r\n// iff k < the number of fields in tuple type T.\r\ntemplate <bool kIndexValid, int kIndex, class Tuple>\r\nstruct TupleElement;\r\n\r\n\r\n$for i [[\r\ntemplate <GTEST_$(n)_TYPENAMES_(T)>\r\nstruct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {\r\n  typedef T$i type;\r\n};\r\n\r\n\r\n]]\r\n}  // namespace gtest_internal\r\n\r\ntemplate <>\r\nclass tuple<> {\r\n public:\r\n  tuple() {}\r\n  tuple(const tuple& /* t */)  {}\r\n  tuple& operator=(const tuple& /* t */) { return *this; }\r\n};\r\n\r\n\r\n$for k [[\r\n$range m 0..k-1\r\ntemplate <GTEST_$(k)_TYPENAMES_(T)>\r\nclass $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {\r\n public:\r\n  template <int k> friend class gtest_internal::Get;\r\n\r\n  tuple() : $for m, [[f$(m)_()]] {}\r\n\r\n  explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]\r\n$for m, [[f$(m)_(f$m)]] {}\r\n\r\n  tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}\r\n\r\n  template <GTEST_$(k)_TYPENAMES_(U)>\r\n  tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}\r\n\r\n$if k == 2 [[\r\n  template <typename U0, typename U1>\r\n  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}\r\n\r\n]]\r\n\r\n  tuple& operator=(const tuple& t) { return CopyFrom(t); }\r\n\r\n  template <GTEST_$(k)_TYPENAMES_(U)>\r\n  tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {\r\n    return CopyFrom(t);\r\n  }\r\n\r\n$if k == 2 [[\r\n  template <typename U0, typename U1>\r\n  tuple& operator=(const ::std::pair<U0, U1>& p) {\r\n    f0_ = p.first;\r\n    f1_ = p.second;\r\n    return *this;\r\n  }\r\n\r\n]]\r\n\r\n  GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n\r\n  template <GTEST_$(k)_TYPENAMES_(U)>\r\n  tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {\r\n\r\n$for m [[\r\n    f$(m)_ = t.f$(m)_;\r\n\r\n]]\r\n    return *this;\r\n  }\r\n\r\n\r\n$for m [[\r\n  T$m f$(m)_;\r\n\r\n]]\r\n};\r\n\r\n\r\n]]\r\n// 6.1.3.2 Tuple creation functions.\r\n\r\n// Known limitations: we don't support passing an\r\n// std::tr1::reference_wrapper<T> to make_tuple().  And we don't\r\n// implement tie().\r\n\r\ninline tuple<> make_tuple() { return tuple<>(); }\r\n\r\n$for k [[\r\n$range m 0..k-1\r\n\r\ntemplate <GTEST_$(k)_TYPENAMES_(T)>\r\ninline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {\r\n  return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);\r\n}\r\n\r\n]]\r\n\r\n// 6.1.3.3 Tuple helper classes.\r\n\r\ntemplate <typename Tuple> struct tuple_size;\r\n\r\n\r\n$for j [[\r\ntemplate <GTEST_$(j)_TYPENAMES_(T)>\r\nstruct tuple_size<GTEST_$(j)_TUPLE_(T) > {\r\n  static const int value = $j;\r\n};\r\n\r\n\r\n]]\r\ntemplate <int k, class Tuple>\r\nstruct tuple_element {\r\n  typedef typename gtest_internal::TupleElement<\r\n      k < (tuple_size<Tuple>::value), k, Tuple>::type type;\r\n};\r\n\r\n#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type\r\n\r\n// 6.1.3.4 Element access.\r\n\r\nnamespace gtest_internal {\r\n\r\n\r\n$for i [[\r\ntemplate <>\r\nclass Get<$i> {\r\n public:\r\n  template <class Tuple>\r\n  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))\r\n  Field(Tuple& t) { return t.f$(i)_; }  // NOLINT\r\n\r\n  template <class Tuple>\r\n  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))\r\n  ConstField(const Tuple& t) { return t.f$(i)_; }\r\n};\r\n\r\n\r\n]]\r\n}  // namespace gtest_internal\r\n\r\ntemplate <int k, GTEST_$(n)_TYPENAMES_(T)>\r\nGTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))\r\nget(GTEST_$(n)_TUPLE_(T)& t) {\r\n  return gtest_internal::Get<k>::Field(t);\r\n}\r\n\r\ntemplate <int k, GTEST_$(n)_TYPENAMES_(T)>\r\nGTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_$(n)_TUPLE_(T)))\r\nget(const GTEST_$(n)_TUPLE_(T)& t) {\r\n  return gtest_internal::Get<k>::ConstField(t);\r\n}\r\n\r\n// 6.1.3.5 Relational operators\r\n\r\n// We only implement == and !=, as we don't have a need for the rest yet.\r\n\r\nnamespace gtest_internal {\r\n\r\n// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the\r\n// first k fields of t1 equals the first k fields of t2.\r\n// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if\r\n// k1 != k2.\r\ntemplate <int kSize1, int kSize2>\r\nstruct SameSizeTuplePrefixComparator;\r\n\r\ntemplate <>\r\nstruct SameSizeTuplePrefixComparator<0, 0> {\r\n  template <class Tuple1, class Tuple2>\r\n  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {\r\n    return true;\r\n  }\r\n};\r\n\r\ntemplate <int k>\r\nstruct SameSizeTuplePrefixComparator<k, k> {\r\n  template <class Tuple1, class Tuple2>\r\n  static bool Eq(const Tuple1& t1, const Tuple2& t2) {\r\n    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&\r\n        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);\r\n  }\r\n};\r\n\r\n}  // namespace gtest_internal\r\n\r\ntemplate <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>\r\ninline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,\r\n                       const GTEST_$(n)_TUPLE_(U)& u) {\r\n  return gtest_internal::SameSizeTuplePrefixComparator<\r\n      tuple_size<GTEST_$(n)_TUPLE_(T) >::value,\r\n      tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);\r\n}\r\n\r\ntemplate <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>\r\ninline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,\r\n                       const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }\r\n\r\n// 6.1.4 Pairs.\r\n// Unimplemented.\r\n\r\n}  // namespace tr1\r\n}  // namespace std\r\n\r\n\r\n$for j [[\r\n#undef GTEST_$(j)_TUPLE_\r\n\r\n]]\r\n\r\n\r\n$for j [[\r\n#undef GTEST_$(j)_TYPENAMES_\r\n\r\n]]\r\n\r\n#undef GTEST_DECLARE_TUPLE_AS_FRIEND_\r\n#undef GTEST_BY_REF_\r\n#undef GTEST_ADD_REF_\r\n#undef GTEST_TUPLE_ELEMENT_\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-type-util.h",
    "content": "// This file was GENERATED by command:\r\n//     pump.py gtest-type-util.h.pump\r\n// DO NOT EDIT BY HAND!!!\r\n\r\n// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Type utilities needed for implementing typed and type-parameterized\r\n// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\r\n//\r\n// Currently we support at most 50 types in a list, and at most 50\r\n// type-parameterized tests in one type-parameterized test case.\r\n// Please contact googletestframework@googlegroups.com if you need\r\n// more.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using\r\n// libstdc++ (which is where cxxabi.h comes from).\r\n# if GTEST_HAS_CXXABI_H_\r\n#  include <cxxabi.h>\r\n# elif defined(__HP_aCC)\r\n#  include <acxx_demangle.h>\r\n# endif  // GTEST_HASH_CXXABI_H_\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// GetTypeName<T>() returns a human-readable name of type T.\r\n// NB: This function is also used in Google Mock, so don't move it inside of\r\n// the typed-test-only section below.\r\ntemplate <typename T>\r\nstd::string GetTypeName() {\r\n# if GTEST_HAS_RTTI\r\n\r\n  const char* const name = typeid(T).name();\r\n#  if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)\r\n  int status = 0;\r\n  // gcc's implementation of typeid(T).name() mangles the type name,\r\n  // so we have to demangle it.\r\n#   if GTEST_HAS_CXXABI_H_\r\n  using abi::__cxa_demangle;\r\n#   endif  // GTEST_HAS_CXXABI_H_\r\n  char* const readable_name = __cxa_demangle(name, 0, 0, &status);\r\n  const std::string name_str(status == 0 ? readable_name : name);\r\n  free(readable_name);\r\n  return name_str;\r\n#  else\r\n  return name;\r\n#  endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC\r\n\r\n# else\r\n\r\n  return \"<type>\";\r\n\r\n# endif  // GTEST_HAS_RTTI\r\n}\r\n\r\n#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same\r\n// type.  This can be used as a compile-time assertion to ensure that\r\n// two types are equal.\r\n\r\ntemplate <typename T1, typename T2>\r\nstruct AssertTypeEq;\r\n\r\ntemplate <typename T>\r\nstruct AssertTypeEq<T, T> {\r\n  typedef bool type;\r\n};\r\n\r\n// A unique type used as the default value for the arguments of class\r\n// template Types.  This allows us to simulate variadic templates\r\n// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't\r\n// support directly.\r\nstruct None {};\r\n\r\n// The following family of struct and struct templates are used to\r\n// represent type lists.  In particular, TypesN<T1, T2, ..., TN>\r\n// represents a type list with N types (T1, T2, ..., and TN) in it.\r\n// Except for Types0, every struct in the family has two member types:\r\n// Head for the first type in the list, and Tail for the rest of the\r\n// list.\r\n\r\n// The empty type list.\r\nstruct Types0 {};\r\n\r\n// Type lists of length 1, 2, 3, and so on.\r\n\r\ntemplate <typename T1>\r\nstruct Types1 {\r\n  typedef T1 Head;\r\n  typedef Types0 Tail;\r\n};\r\ntemplate <typename T1, typename T2>\r\nstruct Types2 {\r\n  typedef T1 Head;\r\n  typedef Types1<T2> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3>\r\nstruct Types3 {\r\n  typedef T1 Head;\r\n  typedef Types2<T2, T3> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\nstruct Types4 {\r\n  typedef T1 Head;\r\n  typedef Types3<T2, T3, T4> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\nstruct Types5 {\r\n  typedef T1 Head;\r\n  typedef Types4<T2, T3, T4, T5> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\nstruct Types6 {\r\n  typedef T1 Head;\r\n  typedef Types5<T2, T3, T4, T5, T6> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\nstruct Types7 {\r\n  typedef T1 Head;\r\n  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\nstruct Types8 {\r\n  typedef T1 Head;\r\n  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\nstruct Types9 {\r\n  typedef T1 Head;\r\n  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\nstruct Types10 {\r\n  typedef T1 Head;\r\n  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11>\r\nstruct Types11 {\r\n  typedef T1 Head;\r\n  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12>\r\nstruct Types12 {\r\n  typedef T1 Head;\r\n  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13>\r\nstruct Types13 {\r\n  typedef T1 Head;\r\n  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14>\r\nstruct Types14 {\r\n  typedef T1 Head;\r\n  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15>\r\nstruct Types15 {\r\n  typedef T1 Head;\r\n  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16>\r\nstruct Types16 {\r\n  typedef T1 Head;\r\n  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17>\r\nstruct Types17 {\r\n  typedef T1 Head;\r\n  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18>\r\nstruct Types18 {\r\n  typedef T1 Head;\r\n  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19>\r\nstruct Types19 {\r\n  typedef T1 Head;\r\n  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20>\r\nstruct Types20 {\r\n  typedef T1 Head;\r\n  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21>\r\nstruct Types21 {\r\n  typedef T1 Head;\r\n  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22>\r\nstruct Types22 {\r\n  typedef T1 Head;\r\n  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23>\r\nstruct Types23 {\r\n  typedef T1 Head;\r\n  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24>\r\nstruct Types24 {\r\n  typedef T1 Head;\r\n  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25>\r\nstruct Types25 {\r\n  typedef T1 Head;\r\n  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26>\r\nstruct Types26 {\r\n  typedef T1 Head;\r\n  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27>\r\nstruct Types27 {\r\n  typedef T1 Head;\r\n  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28>\r\nstruct Types28 {\r\n  typedef T1 Head;\r\n  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29>\r\nstruct Types29 {\r\n  typedef T1 Head;\r\n  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30>\r\nstruct Types30 {\r\n  typedef T1 Head;\r\n  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31>\r\nstruct Types31 {\r\n  typedef T1 Head;\r\n  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32>\r\nstruct Types32 {\r\n  typedef T1 Head;\r\n  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33>\r\nstruct Types33 {\r\n  typedef T1 Head;\r\n  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34>\r\nstruct Types34 {\r\n  typedef T1 Head;\r\n  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35>\r\nstruct Types35 {\r\n  typedef T1 Head;\r\n  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36>\r\nstruct Types36 {\r\n  typedef T1 Head;\r\n  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37>\r\nstruct Types37 {\r\n  typedef T1 Head;\r\n  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38>\r\nstruct Types38 {\r\n  typedef T1 Head;\r\n  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39>\r\nstruct Types39 {\r\n  typedef T1 Head;\r\n  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40>\r\nstruct Types40 {\r\n  typedef T1 Head;\r\n  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41>\r\nstruct Types41 {\r\n  typedef T1 Head;\r\n  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42>\r\nstruct Types42 {\r\n  typedef T1 Head;\r\n  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43>\r\nstruct Types43 {\r\n  typedef T1 Head;\r\n  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44>\r\nstruct Types44 {\r\n  typedef T1 Head;\r\n  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45>\r\nstruct Types45 {\r\n  typedef T1 Head;\r\n  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46>\r\nstruct Types46 {\r\n  typedef T1 Head;\r\n  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45, T46> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47>\r\nstruct Types47 {\r\n  typedef T1 Head;\r\n  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45, T46, T47> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48>\r\nstruct Types48 {\r\n  typedef T1 Head;\r\n  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45, T46, T47, T48> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49>\r\nstruct Types49 {\r\n  typedef T1 Head;\r\n  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45, T46, T47, T48, T49> Tail;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49, typename T50>\r\nstruct Types50 {\r\n  typedef T1 Head;\r\n  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n          T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n          T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n          T44, T45, T46, T47, T48, T49, T50> Tail;\r\n};\r\n\r\n\r\n}  // namespace internal\r\n\r\n// We don't want to require the users to write TypesN<...> directly,\r\n// as that would require them to count the length.  Types<...> is much\r\n// easier to write, but generates horrible messages when there is a\r\n// compiler error, as gcc insists on printing out each template\r\n// argument, even if it has the default value (this means Types<int>\r\n// will appear as Types<int, None, None, ..., None> in the compiler\r\n// errors).\r\n//\r\n// Our solution is to combine the best part of the two approaches: a\r\n// user would write Types<T1, ..., TN>, and Google Test will translate\r\n// that to TypesN<T1, ..., TN> internally to make error messages\r\n// readable.  The translation is done by the 'type' member of the\r\n// Types template.\r\ntemplate <typename T1 = internal::None, typename T2 = internal::None,\r\n          typename T3 = internal::None, typename T4 = internal::None,\r\n          typename T5 = internal::None, typename T6 = internal::None,\r\n          typename T7 = internal::None, typename T8 = internal::None,\r\n          typename T9 = internal::None, typename T10 = internal::None,\r\n          typename T11 = internal::None, typename T12 = internal::None,\r\n          typename T13 = internal::None, typename T14 = internal::None,\r\n          typename T15 = internal::None, typename T16 = internal::None,\r\n          typename T17 = internal::None, typename T18 = internal::None,\r\n          typename T19 = internal::None, typename T20 = internal::None,\r\n          typename T21 = internal::None, typename T22 = internal::None,\r\n          typename T23 = internal::None, typename T24 = internal::None,\r\n          typename T25 = internal::None, typename T26 = internal::None,\r\n          typename T27 = internal::None, typename T28 = internal::None,\r\n          typename T29 = internal::None, typename T30 = internal::None,\r\n          typename T31 = internal::None, typename T32 = internal::None,\r\n          typename T33 = internal::None, typename T34 = internal::None,\r\n          typename T35 = internal::None, typename T36 = internal::None,\r\n          typename T37 = internal::None, typename T38 = internal::None,\r\n          typename T39 = internal::None, typename T40 = internal::None,\r\n          typename T41 = internal::None, typename T42 = internal::None,\r\n          typename T43 = internal::None, typename T44 = internal::None,\r\n          typename T45 = internal::None, typename T46 = internal::None,\r\n          typename T47 = internal::None, typename T48 = internal::None,\r\n          typename T49 = internal::None, typename T50 = internal::None>\r\nstruct Types {\r\n  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;\r\n};\r\n\r\ntemplate <>\r\nstruct Types<internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types0 type;\r\n};\r\ntemplate <typename T1>\r\nstruct Types<T1, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types1<T1> type;\r\n};\r\ntemplate <typename T1, typename T2>\r\nstruct Types<T1, T2, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types2<T1, T2> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3>\r\nstruct Types<T1, T2, T3, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types3<T1, T2, T3> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4>\r\nstruct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types4<T1, T2, T3, T4> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5>\r\nstruct Types<T1, T2, T3, T4, T5, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types5<T1, T2, T3, T4, T5> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6>\r\nstruct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,\r\n          T12> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,\r\n          T26> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,\r\n          T40> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None, internal::None> {\r\n  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None, internal::None> {\r\n  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\r\n         internal::None, internal::None, internal::None, internal::None,\r\n         internal::None> {\r\n  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\r\n         T46, internal::None, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\r\n         T46, T47, internal::None, internal::None, internal::None> {\r\n  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46, T47> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\r\n         T46, T47, T48, internal::None, internal::None> {\r\n  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46, T47, T48> type;\r\n};\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49>\r\nstruct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,\r\n         T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,\r\n         T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,\r\n         T46, T47, T48, T49, internal::None> {\r\n  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46, T47, T48, T49> type;\r\n};\r\n\r\nnamespace internal {\r\n\r\n# define GTEST_TEMPLATE_ template <typename T> class\r\n\r\n// The template \"selector\" struct TemplateSel<Tmpl> is used to\r\n// represent Tmpl, which must be a class template with one type\r\n// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined\r\n// as the type Tmpl<T>.  This allows us to actually instantiate the\r\n// template \"selected\" by TemplateSel<Tmpl>.\r\n//\r\n// This trick is necessary for simulating typedef for class templates,\r\n// which C++ doesn't support directly.\r\ntemplate <GTEST_TEMPLATE_ Tmpl>\r\nstruct TemplateSel {\r\n  template <typename T>\r\n  struct Bind {\r\n    typedef Tmpl<T> type;\r\n  };\r\n};\r\n\r\n# define GTEST_BIND_(TmplSel, T) \\\r\n  TmplSel::template Bind<T>::type\r\n\r\n// A unique struct template used as the default value for the\r\n// arguments of class template Templates.  This allows us to simulate\r\n// variadic templates (e.g. Templates<int>, Templates<int, double>,\r\n// and etc), which C++ doesn't support directly.\r\ntemplate <typename T>\r\nstruct NoneT {};\r\n\r\n// The following family of struct and struct templates are used to\r\n// represent template lists.  In particular, TemplatesN<T1, T2, ...,\r\n// TN> represents a list of N templates (T1, T2, ..., and TN).  Except\r\n// for Templates0, every struct in the family has two member types:\r\n// Head for the selector of the first template in the list, and Tail\r\n// for the rest of the list.\r\n\r\n// The empty template list.\r\nstruct Templates0 {};\r\n\r\n// Template lists of length 1, 2, 3, and so on.\r\n\r\ntemplate <GTEST_TEMPLATE_ T1>\r\nstruct Templates1 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates0 Tail;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>\r\nstruct Templates2 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates1<T2> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>\r\nstruct Templates3 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates2<T2, T3> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4>\r\nstruct Templates4 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates3<T2, T3, T4> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>\r\nstruct Templates5 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates4<T2, T3, T4, T5> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>\r\nstruct Templates6 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates5<T2, T3, T4, T5, T6> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7>\r\nstruct Templates7 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>\r\nstruct Templates8 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>\r\nstruct Templates9 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10>\r\nstruct Templates10 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>\r\nstruct Templates11 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>\r\nstruct Templates12 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13>\r\nstruct Templates13 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>\r\nstruct Templates14 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>\r\nstruct Templates15 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16>\r\nstruct Templates16 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>\r\nstruct Templates17 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>\r\nstruct Templates18 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19>\r\nstruct Templates19 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>\r\nstruct Templates20 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>\r\nstruct Templates21 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22>\r\nstruct Templates22 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>\r\nstruct Templates23 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>\r\nstruct Templates24 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25>\r\nstruct Templates25 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>\r\nstruct Templates26 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>\r\nstruct Templates27 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28>\r\nstruct Templates28 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>\r\nstruct Templates29 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>\r\nstruct Templates30 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31>\r\nstruct Templates31 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>\r\nstruct Templates32 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>\r\nstruct Templates33 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34>\r\nstruct Templates34 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>\r\nstruct Templates35 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>\r\nstruct Templates36 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37>\r\nstruct Templates37 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>\r\nstruct Templates38 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>\r\nstruct Templates39 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40>\r\nstruct Templates40 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>\r\nstruct Templates41 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>\r\nstruct Templates42 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43>\r\nstruct Templates43 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>\r\nstruct Templates44 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>\r\nstruct Templates45 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46>\r\nstruct Templates46 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45, T46> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>\r\nstruct Templates47 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45, T46, T47> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>\r\nstruct Templates48 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45, T46, T47, T48> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\r\n          GTEST_TEMPLATE_ T49>\r\nstruct Templates49 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45, T46, T47, T48, T49> Tail;\r\n};\r\n\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\r\n          GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>\r\nstruct Templates50 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n          T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n          T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,\r\n          T43, T44, T45, T46, T47, T48, T49, T50> Tail;\r\n};\r\n\r\n\r\n// We don't want to require the users to write TemplatesN<...> directly,\r\n// as that would require them to count the length.  Templates<...> is much\r\n// easier to write, but generates horrible messages when there is a\r\n// compiler error, as gcc insists on printing out each template\r\n// argument, even if it has the default value (this means Templates<list>\r\n// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler\r\n// errors).\r\n//\r\n// Our solution is to combine the best part of the two approaches: a\r\n// user would write Templates<T1, ..., TN>, and Google Test will translate\r\n// that to TemplatesN<T1, ..., TN> internally to make error messages\r\n// readable.  The translation is done by the 'type' member of the\r\n// Templates template.\r\ntemplate <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,\r\n          GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,\r\n          GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,\r\n          GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,\r\n          GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,\r\n          GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,\r\n          GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,\r\n          GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,\r\n          GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,\r\n          GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,\r\n          GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,\r\n          GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,\r\n          GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,\r\n          GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,\r\n          GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,\r\n          GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,\r\n          GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,\r\n          GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,\r\n          GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,\r\n          GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,\r\n          GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,\r\n          GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,\r\n          GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,\r\n          GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,\r\n          GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>\r\nstruct Templates {\r\n  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45, T46, T47, T48, T49, T50> type;\r\n};\r\n\r\ntemplate <>\r\nstruct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT> {\r\n  typedef Templates0 type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1>\r\nstruct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT> {\r\n  typedef Templates1<T1> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>\r\nstruct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT> {\r\n  typedef Templates2<T1, T2> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>\r\nstruct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates3<T1, T2, T3> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4>\r\nstruct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates4<T1, T2, T3, T4> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>\r\nstruct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates5<T1, T2, T3, T4, T5> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates6<T1, T2, T3, T4, T5, T6> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT> {\r\n  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT> {\r\n  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT> {\r\n  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT> {\r\n  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT> {\r\n  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT> {\r\n  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT> {\r\n  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT> {\r\n  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         T45, NoneT, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         T45, T46, NoneT, NoneT, NoneT, NoneT> {\r\n  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45, T46> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         T45, T46, T47, NoneT, NoneT, NoneT> {\r\n  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45, T46, T47> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         T45, T46, T47, T48, NoneT, NoneT> {\r\n  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45, T46, T47, T48> type;\r\n};\r\ntemplate <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,\r\n          GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,\r\n          GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,\r\n          GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,\r\n          GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,\r\n          GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,\r\n          GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,\r\n          GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,\r\n          GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,\r\n          GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,\r\n          GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,\r\n          GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,\r\n          GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,\r\n          GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,\r\n          GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,\r\n          GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,\r\n          GTEST_TEMPLATE_ T49>\r\nstruct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,\r\n         T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,\r\n         T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,\r\n         T45, T46, T47, T48, T49, NoneT> {\r\n  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n          T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,\r\n          T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,\r\n          T42, T43, T44, T45, T46, T47, T48, T49> type;\r\n};\r\n\r\n// The TypeList template makes it possible to use either a single type\r\n// or a Types<...> list in TYPED_TEST_CASE() and\r\n// INSTANTIATE_TYPED_TEST_CASE_P().\r\n\r\ntemplate <typename T>\r\nstruct TypeList {\r\n  typedef Types1<T> type;\r\n};\r\n\r\ntemplate <typename T1, typename T2, typename T3, typename T4, typename T5,\r\n          typename T6, typename T7, typename T8, typename T9, typename T10,\r\n          typename T11, typename T12, typename T13, typename T14, typename T15,\r\n          typename T16, typename T17, typename T18, typename T19, typename T20,\r\n          typename T21, typename T22, typename T23, typename T24, typename T25,\r\n          typename T26, typename T27, typename T28, typename T29, typename T30,\r\n          typename T31, typename T32, typename T33, typename T34, typename T35,\r\n          typename T36, typename T37, typename T38, typename T39, typename T40,\r\n          typename T41, typename T42, typename T43, typename T44, typename T45,\r\n          typename T46, typename T47, typename T48, typename T49, typename T50>\r\nstruct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,\r\n         T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,\r\n         T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,\r\n         T44, T45, T46, T47, T48, T49, T50> > {\r\n  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,\r\n          T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,\r\n          T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,\r\n          T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;\r\n};\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/include/gtest/internal/gtest-type-util.h.pump",
    "content": "$$ -*- mode: c++; -*-\r\n$var n = 50  $$ Maximum length of type lists we want to support.\r\n// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Type utilities needed for implementing typed and type-parameterized\r\n// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!\r\n//\r\n// Currently we support at most $n types in a list, and at most $n\r\n// type-parameterized tests in one type-parameterized test case.\r\n// Please contact googletestframework@googlegroups.com if you need\r\n// more.\r\n\r\n#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using\r\n// libstdc++ (which is where cxxabi.h comes from).\r\n# if GTEST_HAS_CXXABI_H_\r\n#  include <cxxabi.h>\r\n# elif defined(__HP_aCC)\r\n#  include <acxx_demangle.h>\r\n# endif  // GTEST_HASH_CXXABI_H_\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n// GetTypeName<T>() returns a human-readable name of type T.\r\n// NB: This function is also used in Google Mock, so don't move it inside of\r\n// the typed-test-only section below.\r\ntemplate <typename T>\r\nstd::string GetTypeName() {\r\n# if GTEST_HAS_RTTI\r\n\r\n  const char* const name = typeid(T).name();\r\n#  if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)\r\n  int status = 0;\r\n  // gcc's implementation of typeid(T).name() mangles the type name,\r\n  // so we have to demangle it.\r\n#   if GTEST_HAS_CXXABI_H_\r\n  using abi::__cxa_demangle;\r\n#   endif  // GTEST_HAS_CXXABI_H_\r\n  char* const readable_name = __cxa_demangle(name, 0, 0, &status);\r\n  const std::string name_str(status == 0 ? readable_name : name);\r\n  free(readable_name);\r\n  return name_str;\r\n#  else\r\n  return name;\r\n#  endif  // GTEST_HAS_CXXABI_H_ || __HP_aCC\r\n\r\n# else\r\n\r\n  return \"<type>\";\r\n\r\n# endif  // GTEST_HAS_RTTI\r\n}\r\n\r\n#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same\r\n// type.  This can be used as a compile-time assertion to ensure that\r\n// two types are equal.\r\n\r\ntemplate <typename T1, typename T2>\r\nstruct AssertTypeEq;\r\n\r\ntemplate <typename T>\r\nstruct AssertTypeEq<T, T> {\r\n  typedef bool type;\r\n};\r\n\r\n// A unique type used as the default value for the arguments of class\r\n// template Types.  This allows us to simulate variadic templates\r\n// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't\r\n// support directly.\r\nstruct None {};\r\n\r\n// The following family of struct and struct templates are used to\r\n// represent type lists.  In particular, TypesN<T1, T2, ..., TN>\r\n// represents a type list with N types (T1, T2, ..., and TN) in it.\r\n// Except for Types0, every struct in the family has two member types:\r\n// Head for the first type in the list, and Tail for the rest of the\r\n// list.\r\n\r\n// The empty type list.\r\nstruct Types0 {};\r\n\r\n// Type lists of length 1, 2, 3, and so on.\r\n\r\ntemplate <typename T1>\r\nstruct Types1 {\r\n  typedef T1 Head;\r\n  typedef Types0 Tail;\r\n};\r\n\r\n$range i 2..n\r\n\r\n$for i [[\r\n$range j 1..i\r\n$range k 2..i\r\ntemplate <$for j, [[typename T$j]]>\r\nstruct Types$i {\r\n  typedef T1 Head;\r\n  typedef Types$(i-1)<$for k, [[T$k]]> Tail;\r\n};\r\n\r\n\r\n]]\r\n\r\n}  // namespace internal\r\n\r\n// We don't want to require the users to write TypesN<...> directly,\r\n// as that would require them to count the length.  Types<...> is much\r\n// easier to write, but generates horrible messages when there is a\r\n// compiler error, as gcc insists on printing out each template\r\n// argument, even if it has the default value (this means Types<int>\r\n// will appear as Types<int, None, None, ..., None> in the compiler\r\n// errors).\r\n//\r\n// Our solution is to combine the best part of the two approaches: a\r\n// user would write Types<T1, ..., TN>, and Google Test will translate\r\n// that to TypesN<T1, ..., TN> internally to make error messages\r\n// readable.  The translation is done by the 'type' member of the\r\n// Types template.\r\n\r\n$range i 1..n\r\ntemplate <$for i, [[typename T$i = internal::None]]>\r\nstruct Types {\r\n  typedef internal::Types$n<$for i, [[T$i]]> type;\r\n};\r\n\r\ntemplate <>\r\nstruct Types<$for i, [[internal::None]]> {\r\n  typedef internal::Types0 type;\r\n};\r\n\r\n$range i 1..n-1\r\n$for i [[\r\n$range j 1..i\r\n$range k i+1..n\r\ntemplate <$for j, [[typename T$j]]>\r\nstruct Types<$for j, [[T$j]]$for k[[, internal::None]]> {\r\n  typedef internal::Types$i<$for j, [[T$j]]> type;\r\n};\r\n\r\n]]\r\n\r\nnamespace internal {\r\n\r\n# define GTEST_TEMPLATE_ template <typename T> class\r\n\r\n// The template \"selector\" struct TemplateSel<Tmpl> is used to\r\n// represent Tmpl, which must be a class template with one type\r\n// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined\r\n// as the type Tmpl<T>.  This allows us to actually instantiate the\r\n// template \"selected\" by TemplateSel<Tmpl>.\r\n//\r\n// This trick is necessary for simulating typedef for class templates,\r\n// which C++ doesn't support directly.\r\ntemplate <GTEST_TEMPLATE_ Tmpl>\r\nstruct TemplateSel {\r\n  template <typename T>\r\n  struct Bind {\r\n    typedef Tmpl<T> type;\r\n  };\r\n};\r\n\r\n# define GTEST_BIND_(TmplSel, T) \\\r\n  TmplSel::template Bind<T>::type\r\n\r\n// A unique struct template used as the default value for the\r\n// arguments of class template Templates.  This allows us to simulate\r\n// variadic templates (e.g. Templates<int>, Templates<int, double>,\r\n// and etc), which C++ doesn't support directly.\r\ntemplate <typename T>\r\nstruct NoneT {};\r\n\r\n// The following family of struct and struct templates are used to\r\n// represent template lists.  In particular, TemplatesN<T1, T2, ...,\r\n// TN> represents a list of N templates (T1, T2, ..., and TN).  Except\r\n// for Templates0, every struct in the family has two member types:\r\n// Head for the selector of the first template in the list, and Tail\r\n// for the rest of the list.\r\n\r\n// The empty template list.\r\nstruct Templates0 {};\r\n\r\n// Template lists of length 1, 2, 3, and so on.\r\n\r\ntemplate <GTEST_TEMPLATE_ T1>\r\nstruct Templates1 {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates0 Tail;\r\n};\r\n\r\n$range i 2..n\r\n\r\n$for i [[\r\n$range j 1..i\r\n$range k 2..i\r\ntemplate <$for j, [[GTEST_TEMPLATE_ T$j]]>\r\nstruct Templates$i {\r\n  typedef TemplateSel<T1> Head;\r\n  typedef Templates$(i-1)<$for k, [[T$k]]> Tail;\r\n};\r\n\r\n\r\n]]\r\n\r\n// We don't want to require the users to write TemplatesN<...> directly,\r\n// as that would require them to count the length.  Templates<...> is much\r\n// easier to write, but generates horrible messages when there is a\r\n// compiler error, as gcc insists on printing out each template\r\n// argument, even if it has the default value (this means Templates<list>\r\n// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler\r\n// errors).\r\n//\r\n// Our solution is to combine the best part of the two approaches: a\r\n// user would write Templates<T1, ..., TN>, and Google Test will translate\r\n// that to TemplatesN<T1, ..., TN> internally to make error messages\r\n// readable.  The translation is done by the 'type' member of the\r\n// Templates template.\r\n\r\n$range i 1..n\r\ntemplate <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>\r\nstruct Templates {\r\n  typedef Templates$n<$for i, [[T$i]]> type;\r\n};\r\n\r\ntemplate <>\r\nstruct Templates<$for i, [[NoneT]]> {\r\n  typedef Templates0 type;\r\n};\r\n\r\n$range i 1..n-1\r\n$for i [[\r\n$range j 1..i\r\n$range k i+1..n\r\ntemplate <$for j, [[GTEST_TEMPLATE_ T$j]]>\r\nstruct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {\r\n  typedef Templates$i<$for j, [[T$j]]> type;\r\n};\r\n\r\n]]\r\n\r\n// The TypeList template makes it possible to use either a single type\r\n// or a Types<...> list in TYPED_TEST_CASE() and\r\n// INSTANTIATE_TYPED_TEST_CASE_P().\r\n\r\ntemplate <typename T>\r\nstruct TypeList {\r\n  typedef Types1<T> type;\r\n};\r\n\r\n\r\n$range i 1..n\r\ntemplate <$for i, [[typename T$i]]>\r\nstruct TypeList<Types<$for i, [[T$i]]> > {\r\n  typedef typename Types<$for i, [[T$i]]>::type type;\r\n};\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-all.cpp",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: mheule@google.com (Markus Heule)\r\n//\r\n// Google C++ Testing Framework (Google Test)\r\n//\r\n// Sometimes it's desirable to build Google Test by compiling a single file.\r\n// This file serves this purpose.\r\n\r\n// This line ensures that gtest.h can be compiled on its own, even\r\n// when it's fused.\r\n#include \"gtest/gtest.h\"\r\n\r\n\r\n// The following lines pull in the real gtest *.cc files.\r\n/**\r\n#include \"src/gtest.cc\"\r\n#include \"src/gtest-death-test.cc\"\r\n#include \"src/gtest-filepath.cc\"\r\n#include \"src/gtest-port.cc\"\r\n#include \"src/gtest-printers.cc\"\r\n#include \"src/gtest-test-part.cc\"\r\n#include \"src/gtest-typed-test.cc\"\r\n**/\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-death-test.cpp",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)\r\n//\r\n// This file implements death tests.\r\n\r\n#include \"gtest/gtest-death-test.h\"\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\n# if GTEST_OS_MAC\r\n#  include <crt_externs.h>\r\n# endif  // GTEST_OS_MAC\r\n\r\n# include <errno.h>\r\n# include <fcntl.h>\r\n# include <limits.h>\r\n\r\n# if GTEST_OS_LINUX\r\n#  include <signal.h>\r\n# endif  // GTEST_OS_LINUX\r\n\r\n# include <stdarg.h>\r\n\r\n# if GTEST_OS_WINDOWS\r\n#  include <windows.h>\r\n# else\r\n#  include <sys/mman.h>\r\n#  include <sys/wait.h>\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n# if GTEST_OS_QNX\r\n#  include <spawn.h>\r\n# endif  // GTEST_OS_QNX\r\n\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n#include \"gtest/gtest-message.h\"\r\n#include \"gtest/internal/gtest-string.h\"\r\n\r\n// Indicates that this translation unit is part of Google Test's\r\n// implementation.  It must come before gtest-internal-inl.h is\r\n// included, or there will be a compiler error.  This trick is to\r\n// prevent a user from accidentally including gtest-internal-inl.h in\r\n// his code.\r\n#define GTEST_IMPLEMENTATION_ 1\r\n#include \"src/gtest-internal-inl.h\"\r\n#undef GTEST_IMPLEMENTATION_\r\n\r\nnamespace testing {\r\n\r\n// Constants.\r\n\r\n// The default death test style.\r\nstatic const char kDefaultDeathTestStyle[] = \"fast\";\r\n\r\nGTEST_DEFINE_string_(\r\n  death_test_style,\r\n  internal::StringFromGTestEnv(\"death_test_style\", kDefaultDeathTestStyle),\r\n  \"Indicates how to run a death test in a forked child process: \"\r\n  \"\\\"threadsafe\\\" (child process re-executes the test binary \"\r\n  \"from the beginning, running only the specific death test) or \"\r\n  \"\\\"fast\\\" (child process runs the death test immediately \"\r\n  \"after forking).\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  death_test_use_fork,\r\n  internal::BoolFromGTestEnv(\"death_test_use_fork\", false),\r\n  \"Instructs to use fork()/_exit() instead of clone() in death tests. \"\r\n  \"Ignored and always uses fork() on POSIX systems where clone() is not \"\r\n  \"implemented. Useful when running under valgrind or similar tools if \"\r\n  \"those do not support clone(). Valgrind 3.3.1 will just fail if \"\r\n  \"it sees an unsupported combination of clone() flags. \"\r\n  \"It is not recommended to use this flag w/o valgrind though it will \"\r\n  \"work in 99% of the cases. Once valgrind is fixed, this flag will \"\r\n  \"most likely be removed.\");\r\n\r\nnamespace internal {\r\nGTEST_DEFINE_string_(\r\n  internal_run_death_test, \"\",\r\n  \"Indicates the file, line number, temporal index of \"\r\n  \"the single death test to run, and a file descriptor to \"\r\n  \"which a success code may be sent, all separated by \"\r\n  \"the '|' characters.  This flag is specified if and only if the current \"\r\n  \"process is a sub-process launched for running a thread-safe \"\r\n  \"death test.  FOR INTERNAL USE ONLY.\");\r\n}  // namespace internal\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\nnamespace internal {\r\n\r\n// Valid only for fast death tests. Indicates the code is running in the\r\n// child process of a fast style death test.\r\nstatic bool g_in_fast_death_test_child = false;\r\n\r\n// Returns a Boolean value indicating whether the caller is currently\r\n// executing in the context of the death test child process.  Tools such as\r\n// Valgrind heap checkers may need this to modify their behavior in death\r\n// tests.  IMPORTANT: This is an internal utility.  Using it may break the\r\n// implementation of death tests.  User code MUST NOT use it.\r\nbool InDeathTestChild() {\r\n# if GTEST_OS_WINDOWS\r\n\r\n  // On Windows, death tests are thread-safe regardless of the value of the\r\n  // death_test_style flag.\r\n  return !GTEST_FLAG(internal_run_death_test).empty();\r\n\r\n# else\r\n\r\n  if (GTEST_FLAG(death_test_style) == \"threadsafe\") {\r\n    return !GTEST_FLAG(internal_run_death_test).empty();\r\n  }\r\n  else {\r\n    return g_in_fast_death_test_child;\r\n  }\r\n\r\n#endif\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// ExitedWithCode constructor.\r\nExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {\r\n}\r\n\r\n// ExitedWithCode function-call operator.\r\nbool ExitedWithCode::operator()(int exit_status) const {\r\n# if GTEST_OS_WINDOWS\r\n\r\n  return exit_status == exit_code_;\r\n\r\n# else\r\n\r\n  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;\r\n\r\n# endif  // GTEST_OS_WINDOWS\r\n}\r\n\r\n# if !GTEST_OS_WINDOWS\r\n// KilledBySignal constructor.\r\nKilledBySignal::KilledBySignal(int signum) : signum_(signum) {\r\n}\r\n\r\n// KilledBySignal function-call operator.\r\nbool KilledBySignal::operator()(int exit_status) const {\r\n  return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;\r\n}\r\n# endif  // !GTEST_OS_WINDOWS\r\n\r\nnamespace internal {\r\n\r\n// Utilities needed for death tests.\r\n\r\n// Generates a textual description of a given exit code, in the format\r\n// specified by wait(2).\r\nstatic std::string ExitSummary(int exit_code) {\r\n  Message m;\r\n\r\n# if GTEST_OS_WINDOWS\r\n\r\n  m << \"Exited with exit status \" << exit_code;\r\n\r\n# else\r\n\r\n  if (WIFEXITED(exit_code)) {\r\n    m << \"Exited with exit status \" << WEXITSTATUS(exit_code);\r\n  }\r\n  else if (WIFSIGNALED(exit_code)) {\r\n    m << \"Terminated by signal \" << WTERMSIG(exit_code);\r\n  }\r\n\r\n#  ifdef WCOREDUMP\r\n\r\n  if (WCOREDUMP(exit_code)) {\r\n    m << \" (core dumped)\";\r\n  }\r\n\r\n#  endif\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n  return m.GetString();\r\n}\r\n\r\n// Returns true if exit_status describes a process that was terminated\r\n// by a signal, or exited normally with a nonzero exit code.\r\nbool ExitedUnsuccessfully(int exit_status) {\r\n  return !ExitedWithCode(0)(exit_status);\r\n}\r\n\r\n# if !GTEST_OS_WINDOWS\r\n// Generates a textual failure message when a death test finds more than\r\n// one thread running, or cannot determine the number of threads, prior\r\n// to executing the given statement.  It is the responsibility of the\r\n// caller not to pass a thread_count of 1.\r\nstatic std::string DeathTestThreadWarning(size_t thread_count) {\r\n  Message msg;\r\n  msg << \"Death tests use fork(), which is unsafe particularly\"\r\n      << \" in a threaded context. For this test, \" << GTEST_NAME_ << \" \";\r\n\r\n  if (thread_count == 0) {\r\n    msg << \"couldn't detect the number of threads.\";\r\n  }\r\n  else {\r\n    msg << \"detected \" << thread_count << \" threads.\";\r\n  }\r\n\r\n  return msg.GetString();\r\n}\r\n# endif  // !GTEST_OS_WINDOWS\r\n\r\n// Flag characters for reporting a death test that did not die.\r\nstatic const char kDeathTestLived = 'L';\r\nstatic const char kDeathTestReturned = 'R';\r\nstatic const char kDeathTestThrew = 'T';\r\nstatic const char kDeathTestInternalError = 'I';\r\n\r\n// An enumeration describing all of the possible ways that a death test can\r\n// conclude.  DIED means that the process died while executing the test\r\n// code; LIVED means that process lived beyond the end of the test code;\r\n// RETURNED means that the test statement attempted to execute a return\r\n// statement, which is not allowed; THREW means that the test statement\r\n// returned control by throwing an exception.  IN_PROGRESS means the test\r\n// has not yet concluded.\r\n// TODO(vladl@google.com): Unify names and possibly values for\r\n// AbortReason, DeathTestOutcome, and flag characters above.\r\nenum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };\r\n\r\n// Routine for aborting the program which is safe to call from an\r\n// exec-style death test child process, in which case the error\r\n// message is propagated back to the parent process.  Otherwise, the\r\n// message is simply printed to stderr.  In either case, the program\r\n// then exits with status 1.\r\nvoid DeathTestAbort(const std::string& message) {\r\n  // On a POSIX system, this function may be called from a threadsafe-style\r\n  // death test child process, which operates on a very small stack.  Use\r\n  // the heap for any additional non-minuscule memory requirements.\r\n  const InternalRunDeathTestFlag* const flag =\r\n    GetUnitTestImpl()->internal_run_death_test_flag();\r\n\r\n  if (flag != NULL) {\r\n    FILE* parent = posix::FDOpen(flag->write_fd(), \"w\");\r\n    fputc(kDeathTestInternalError, parent);\r\n    fprintf(parent, \"%s\", message.c_str());\r\n    fflush(parent);\r\n    _exit(1);\r\n  }\r\n  else {\r\n    fprintf(stderr, \"%s\", message.c_str());\r\n    fflush(stderr);\r\n    posix::Abort();\r\n  }\r\n}\r\n\r\n// A replacement for CHECK that calls DeathTestAbort if the assertion\r\n// fails.\r\n# define GTEST_DEATH_TEST_CHECK_(expression) \\\r\n  do { \\\r\n    if (!::testing::internal::IsTrue(expression)) { \\\r\n      DeathTestAbort( \\\r\n          ::std::string(\"CHECK failed: File \") + __FILE__ +  \", line \" \\\r\n          + ::testing::internal::StreamableToString(__LINE__) + \": \" \\\r\n          + #expression); \\\r\n    } \\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for\r\n// evaluating any system call that fulfills two conditions: it must return\r\n// -1 on failure, and set errno to EINTR when it is interrupted and\r\n// should be tried again.  The macro expands to a loop that repeatedly\r\n// evaluates the expression as long as it evaluates to -1 and sets\r\n// errno to EINTR.  If the expression evaluates to -1 but errno is\r\n// something other than EINTR, DeathTestAbort is called.\r\n# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \\\r\n  do { \\\r\n    int gtest_retval; \\\r\n    do { \\\r\n      gtest_retval = (expression); \\\r\n    } while (gtest_retval == -1 && errno == EINTR); \\\r\n    if (gtest_retval == -1) { \\\r\n      DeathTestAbort( \\\r\n          ::std::string(\"CHECK failed: File \") + __FILE__ + \", line \" \\\r\n          + ::testing::internal::StreamableToString(__LINE__) + \": \" \\\r\n          + #expression + \" != -1\"); \\\r\n    } \\\r\n  } while (::testing::internal::AlwaysFalse())\r\n\r\n// Returns the message describing the last system error in errno.\r\nstd::string GetLastErrnoDescription() {\r\n  return errno == 0 ? \"\" : posix::StrError(errno);\r\n}\r\n\r\n// This is called from a death test parent process to read a failure\r\n// message from the death test child process and log it with the FATAL\r\n// severity. On Windows, the message is read from a pipe handle. On other\r\n// platforms, it is read from a file descriptor.\r\nstatic void FailFromInternalError(int fd) {\r\n  Message error;\r\n  char buffer[256];\r\n  int num_read;\r\n\r\n  do {\r\n    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {\r\n      buffer[num_read] = '\\0';\r\n      error << buffer;\r\n    }\r\n  }\r\n  while (num_read == -1 && errno == EINTR);\r\n\r\n  if (num_read == 0) {\r\n    GTEST_LOG_(FATAL) << error.GetString();\r\n  }\r\n  else {\r\n    const int last_error = errno;\r\n    GTEST_LOG_(FATAL) << \"Error while reading death test internal: \"\r\n                      << GetLastErrnoDescription() << \" [\" << last_error << \"]\";\r\n  }\r\n}\r\n\r\n// Death test constructor.  Increments the running death test count\r\n// for the current test.\r\nDeathTest::DeathTest() {\r\n  TestInfo* const info = GetUnitTestImpl()->current_test_info();\r\n\r\n  if (info == NULL) {\r\n    DeathTestAbort(\"Cannot run a death test outside of a TEST or \"\r\n                   \"TEST_F construct\");\r\n  }\r\n}\r\n\r\n// Creates and returns a death test by dispatching to the current\r\n// death test factory.\r\nbool DeathTest::Create(const char* statement, const RE* regex,\r\n                       const char* file, int line, DeathTest** test) {\r\n  return GetUnitTestImpl()->death_test_factory()->Create(\r\n           statement, regex, file, line, test);\r\n}\r\n\r\nconst char* DeathTest::LastMessage() {\r\n  return last_death_test_message_.c_str();\r\n}\r\n\r\nvoid DeathTest::set_last_death_test_message(const std::string& message) {\r\n  last_death_test_message_ = message;\r\n}\r\n\r\nstd::string DeathTest::last_death_test_message_;\r\n\r\n// Provides cross platform implementation for some death functionality.\r\nclass DeathTestImpl : public DeathTest {\r\n protected:\r\n  DeathTestImpl(const char* a_statement, const RE* a_regex)\r\n    : statement_(a_statement),\r\n      regex_(a_regex),\r\n      spawned_(false),\r\n      status_(-1),\r\n      outcome_(IN_PROGRESS),\r\n      read_fd_(-1),\r\n      write_fd_(-1) {}\r\n\r\n  // read_fd_ is expected to be closed and cleared by a derived class.\r\n  ~DeathTestImpl() {\r\n    GTEST_DEATH_TEST_CHECK_(read_fd_ == -1);\r\n  }\r\n\r\n  void Abort(AbortReason reason);\r\n  virtual bool Passed(bool status_ok);\r\n\r\n  const char* statement() const {\r\n    return statement_;\r\n  }\r\n  const RE* regex() const {\r\n    return regex_;\r\n  }\r\n  bool spawned() const {\r\n    return spawned_;\r\n  }\r\n  void set_spawned(bool is_spawned) {\r\n    spawned_ = is_spawned;\r\n  }\r\n  int status() const {\r\n    return status_;\r\n  }\r\n  void set_status(int a_status) {\r\n    status_ = a_status;\r\n  }\r\n  DeathTestOutcome outcome() const {\r\n    return outcome_;\r\n  }\r\n  void set_outcome(DeathTestOutcome an_outcome) {\r\n    outcome_ = an_outcome;\r\n  }\r\n  int read_fd() const {\r\n    return read_fd_;\r\n  }\r\n  void set_read_fd(int fd) {\r\n    read_fd_ = fd;\r\n  }\r\n  int write_fd() const {\r\n    return write_fd_;\r\n  }\r\n  void set_write_fd(int fd) {\r\n    write_fd_ = fd;\r\n  }\r\n\r\n  // Called in the parent process only. Reads the result code of the death\r\n  // test child process via a pipe, interprets it to set the outcome_\r\n  // member, and closes read_fd_.  Outputs diagnostics and terminates in\r\n  // case of unexpected codes.\r\n  void ReadAndInterpretStatusByte();\r\n\r\n private:\r\n  // The textual content of the code this object is testing.  This class\r\n  // doesn't own this string and should not attempt to delete it.\r\n  const char* const statement_;\r\n  // The regular expression which test output must match.  DeathTestImpl\r\n  // doesn't own this object and should not attempt to delete it.\r\n  const RE* const regex_;\r\n  // True if the death test child process has been successfully spawned.\r\n  bool spawned_;\r\n  // The exit status of the child process.\r\n  int status_;\r\n  // How the death test concluded.\r\n  DeathTestOutcome outcome_;\r\n  // Descriptor to the read end of the pipe to the child process.  It is\r\n  // always -1 in the child process.  The child keeps its write end of the\r\n  // pipe in write_fd_.\r\n  int read_fd_;\r\n  // Descriptor to the child's write end of the pipe to the parent process.\r\n  // It is always -1 in the parent process.  The parent keeps its end of the\r\n  // pipe in read_fd_.\r\n  int write_fd_;\r\n};\r\n\r\n// Called in the parent process only. Reads the result code of the death\r\n// test child process via a pipe, interprets it to set the outcome_\r\n// member, and closes read_fd_.  Outputs diagnostics and terminates in\r\n// case of unexpected codes.\r\nvoid DeathTestImpl::ReadAndInterpretStatusByte() {\r\n  char flag;\r\n  int bytes_read;\r\n\r\n  // The read() here blocks until data is available (signifying the\r\n  // failure of the death test) or until the pipe is closed (signifying\r\n  // its success), so it's okay to call this in the parent before\r\n  // the child process has exited.\r\n  do {\r\n    bytes_read = posix::Read(read_fd(), &flag, 1);\r\n  }\r\n  while (bytes_read == -1 && errno == EINTR);\r\n\r\n  if (bytes_read == 0) {\r\n    set_outcome(DIED);\r\n  }\r\n  else if (bytes_read == 1) {\r\n    switch (flag) {\r\n      case kDeathTestReturned:\r\n        set_outcome(RETURNED);\r\n        break;\r\n\r\n      case kDeathTestThrew:\r\n        set_outcome(THREW);\r\n        break;\r\n\r\n      case kDeathTestLived:\r\n        set_outcome(LIVED);\r\n        break;\r\n\r\n      case kDeathTestInternalError:\r\n        FailFromInternalError(read_fd());  // Does not return.\r\n        break;\r\n\r\n      default:\r\n        GTEST_LOG_(FATAL) << \"Death test child process reported \"\r\n                          << \"unexpected status byte (\"\r\n                          << static_cast<unsigned int>(flag) << \")\";\r\n    }\r\n  }\r\n  else {\r\n    GTEST_LOG_(FATAL) << \"Read from death test child process failed: \"\r\n                      << GetLastErrnoDescription();\r\n  }\r\n\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));\r\n  set_read_fd(-1);\r\n}\r\n\r\n// Signals that the death test code which should have exited, didn't.\r\n// Should be called only in a death test child process.\r\n// Writes a status byte to the child's status file descriptor, then\r\n// calls _exit(1).\r\nvoid DeathTestImpl::Abort(AbortReason reason) {\r\n  // The parent process considers the death test to be a failure if\r\n  // it finds any data in our pipe.  So, here we write a single flag byte\r\n  // to the pipe, then exit.\r\n  const char status_ch =\r\n    reason == TEST_DID_NOT_DIE ? kDeathTestLived :\r\n    reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned;\r\n\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));\r\n  // We are leaking the descriptor here because on some platforms (i.e.,\r\n  // when built as Windows DLL), destructors of global objects will still\r\n  // run after calling _exit(). On such systems, write_fd_ will be\r\n  // indirectly closed from the destructor of UnitTestImpl, causing double\r\n  // close if it is also closed here. On debug configurations, double close\r\n  // may assert. As there are no in-process buffers to flush here, we are\r\n  // relying on the OS to close the descriptor after the process terminates\r\n  // when the destructors are not run.\r\n  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)\r\n}\r\n\r\n// Returns an indented copy of stderr output for a death test.\r\n// This makes distinguishing death test output lines from regular log lines\r\n// much easier.\r\nstatic ::std::string FormatDeathTestOutput(const ::std::string& output) {\r\n  ::std::string ret;\r\n\r\n  for (size_t at = 0; ; ) {\r\n    const size_t line_end = output.find('\\n', at);\r\n    ret += \"[  DEATH   ] \";\r\n\r\n    if (line_end == ::std::string::npos) {\r\n      ret += output.substr(at);\r\n      break;\r\n    }\r\n\r\n    ret += output.substr(at, line_end + 1 - at);\r\n    at = line_end + 1;\r\n  }\r\n\r\n  return ret;\r\n}\r\n\r\n// Assesses the success or failure of a death test, using both private\r\n// members which have previously been set, and one argument:\r\n//\r\n// Private data members:\r\n//   outcome:  An enumeration describing how the death test\r\n//             concluded: DIED, LIVED, THREW, or RETURNED.  The death test\r\n//             fails in the latter three cases.\r\n//   status:   The exit status of the child process. On *nix, it is in the\r\n//             in the format specified by wait(2). On Windows, this is the\r\n//             value supplied to the ExitProcess() API or a numeric code\r\n//             of the exception that terminated the program.\r\n//   regex:    A regular expression object to be applied to\r\n//             the test's captured standard error output; the death test\r\n//             fails if it does not match.\r\n//\r\n// Argument:\r\n//   status_ok: true if exit_status is acceptable in the context of\r\n//              this particular death test, which fails if it is false\r\n//\r\n// Returns true iff all of the above conditions are met.  Otherwise, the\r\n// first failing condition, in the order given above, is the one that is\r\n// reported. Also sets the last death test message string.\r\nbool DeathTestImpl::Passed(bool status_ok) {\r\n  if (!spawned()) {\r\n    return false;\r\n  }\r\n\r\n  const std::string error_message = GetCapturedStderr();\r\n\r\n  bool success = false;\r\n  Message buffer;\r\n\r\n  buffer << \"Death test: \" << statement() << \"\\n\";\r\n\r\n  switch (outcome()) {\r\n    case LIVED:\r\n      buffer << \"    Result: failed to die.\\n\"\r\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\r\n      break;\r\n\r\n    case THREW:\r\n      buffer << \"    Result: threw an exception.\\n\"\r\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\r\n      break;\r\n\r\n    case RETURNED:\r\n      buffer << \"    Result: illegal return in test statement.\\n\"\r\n             << \" Error msg:\\n\" << FormatDeathTestOutput(error_message);\r\n      break;\r\n\r\n    case DIED:\r\n      if (status_ok) {\r\n        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());\r\n\r\n        if (matched) {\r\n          success = true;\r\n        }\r\n        else {\r\n          buffer << \"    Result: died but not with expected error.\\n\"\r\n                 << \"  Expected: \" << regex()->pattern() << \"\\n\"\r\n                 << \"Actual msg:\\n\" << FormatDeathTestOutput(error_message);\r\n        }\r\n      }\r\n      else {\r\n        buffer << \"    Result: died but not with expected exit code:\\n\"\r\n               << \"            \" << ExitSummary(status()) << \"\\n\"\r\n               << \"Actual msg:\\n\" << FormatDeathTestOutput(error_message);\r\n      }\r\n\r\n      break;\r\n\r\n    case IN_PROGRESS:\r\n    default:\r\n      GTEST_LOG_(FATAL)\r\n          << \"DeathTest::Passed somehow called before conclusion of test\";\r\n  }\r\n\r\n  DeathTest::set_last_death_test_message(buffer.GetString());\r\n  return success;\r\n}\r\n\r\n# if GTEST_OS_WINDOWS\r\n// WindowsDeathTest implements death tests on Windows. Due to the\r\n// specifics of starting new processes on Windows, death tests there are\r\n// always threadsafe, and Google Test considers the\r\n// --gtest_death_test_style=fast setting to be equivalent to\r\n// --gtest_death_test_style=threadsafe there.\r\n//\r\n// A few implementation notes:  Like the Linux version, the Windows\r\n// implementation uses pipes for child-to-parent communication. But due to\r\n// the specifics of pipes on Windows, some extra steps are required:\r\n//\r\n// 1. The parent creates a communication pipe and stores handles to both\r\n//    ends of it.\r\n// 2. The parent starts the child and provides it with the information\r\n//    necessary to acquire the handle to the write end of the pipe.\r\n// 3. The child acquires the write end of the pipe and signals the parent\r\n//    using a Windows event.\r\n// 4. Now the parent can release the write end of the pipe on its side. If\r\n//    this is done before step 3, the object's reference count goes down to\r\n//    0 and it is destroyed, preventing the child from acquiring it. The\r\n//    parent now has to release it, or read operations on the read end of\r\n//    the pipe will not return when the child terminates.\r\n// 5. The parent reads child's output through the pipe (outcome code and\r\n//    any possible error messages) from the pipe, and its stderr and then\r\n//    determines whether to fail the test.\r\n//\r\n// Note: to distinguish Win32 API calls from the local method and function\r\n// calls, the former are explicitly resolved in the global namespace.\r\n//\r\nclass WindowsDeathTest : public DeathTestImpl {\r\n public:\r\n  WindowsDeathTest(const char* a_statement,\r\n                   const RE* a_regex,\r\n                   const char* file,\r\n                   int line)\r\n    : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}\r\n\r\n  // All of these virtual functions are inherited from DeathTest.\r\n  virtual int Wait();\r\n  virtual TestRole AssumeRole();\r\n\r\n private:\r\n  // The name of the file in which the death test is located.\r\n  const char* const file_;\r\n  // The line number on which the death test is located.\r\n  const int line_;\r\n  // Handle to the write end of the pipe to the child process.\r\n  AutoHandle write_handle_;\r\n  // Child process handle.\r\n  AutoHandle child_handle_;\r\n  // Event the child process uses to signal the parent that it has\r\n  // acquired the handle to the write end of the pipe. After seeing this\r\n  // event the parent can release its own handles to make sure its\r\n  // ReadFile() calls return when the child terminates.\r\n  AutoHandle event_handle_;\r\n};\r\n\r\n// Waits for the child in a death test to exit, returning its exit\r\n// status, or 0 if no child process exists.  As a side effect, sets the\r\n// outcome data member.\r\nint WindowsDeathTest::Wait() {\r\n  if (!spawned()) {\r\n    return 0;\r\n  }\r\n\r\n  // Wait until the child either signals that it has acquired the write end\r\n  // of the pipe or it dies.\r\n  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };\r\n\r\n  switch (::WaitForMultipleObjects(2,\r\n                                   wait_handles,\r\n                                   FALSE,  // Waits for any of the handles.\r\n                                   INFINITE)) {\r\n    case WAIT_OBJECT_0:\r\n    case WAIT_OBJECT_0 + 1:\r\n      break;\r\n\r\n    default:\r\n      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.\r\n  }\r\n\r\n  // The child has acquired the write end of the pipe or exited.\r\n  // We release the handle on our side and continue.\r\n  write_handle_.Reset();\r\n  event_handle_.Reset();\r\n\r\n  ReadAndInterpretStatusByte();\r\n\r\n  // Waits for the child process to exit if it haven't already. This\r\n  // returns immediately if the child has already exited, regardless of\r\n  // whether previous calls to WaitForMultipleObjects synchronized on this\r\n  // handle or not.\r\n  GTEST_DEATH_TEST_CHECK_(\r\n    WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),\r\n        INFINITE));\r\n  DWORD status_code;\r\n  GTEST_DEATH_TEST_CHECK_(\r\n    ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE);\r\n  child_handle_.Reset();\r\n  set_status(static_cast<int>(status_code));\r\n  return status();\r\n}\r\n\r\n// The AssumeRole process for a Windows death test.  It creates a child\r\n// process with the same executable as the current process to run the\r\n// death test.  The child process is given the --gtest_filter and\r\n// --gtest_internal_run_death_test flags such that it knows to run the\r\n// current death test only.\r\nDeathTest::TestRole WindowsDeathTest::AssumeRole() {\r\n  const UnitTestImpl* const impl = GetUnitTestImpl();\r\n  const InternalRunDeathTestFlag* const flag =\r\n    impl->internal_run_death_test_flag();\r\n  const TestInfo* const info = impl->current_test_info();\r\n  const int death_test_index = info->result()->death_test_count();\r\n\r\n  if (flag != NULL) {\r\n    // ParseInternalRunDeathTestFlag() has performed all the necessary\r\n    // processing.\r\n    set_write_fd(flag->write_fd());\r\n    return EXECUTE_TEST;\r\n  }\r\n\r\n  // WindowsDeathTest uses an anonymous pipe to communicate results of\r\n  // a death test.\r\n  SECURITY_ATTRIBUTES handles_are_inheritable = {\r\n    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE\r\n  };\r\n  HANDLE read_handle, write_handle;\r\n  GTEST_DEATH_TEST_CHECK_(\r\n    ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,\r\n                 0)  // Default buffer size.\r\n    != FALSE);\r\n  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),\r\n                                O_RDONLY));\r\n  write_handle_.Reset(write_handle);\r\n  event_handle_.Reset(::CreateEvent(\r\n                        &handles_are_inheritable,\r\n                        TRUE,    // The event will automatically reset to non-signaled state.\r\n                        FALSE,   // The initial state is non-signalled.\r\n                        NULL));  // The even is unnamed.\r\n  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);\r\n  const std::string filter_flag =\r\n    std::string(\"--\") + GTEST_FLAG_PREFIX_ + kFilterFlag + \"=\" +\r\n    info->test_case_name() + \".\" + info->name();\r\n  const std::string internal_flag =\r\n    std::string(\"--\") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +\r\n    \"=\" + file_ + \"|\" + StreamableToString(line_) + \"|\" +\r\n    StreamableToString(death_test_index) + \"|\" +\r\n    StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) +\r\n    // size_t has the same width as pointers on both 32-bit and 64-bit\r\n    // Windows platforms.\r\n    // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.\r\n    \"|\" + StreamableToString(reinterpret_cast<size_t>(write_handle)) +\r\n    \"|\" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));\r\n\r\n  char executable_path[_MAX_PATH + 1];  // NOLINT\r\n  GTEST_DEATH_TEST_CHECK_(\r\n    _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,\r\n                                          executable_path,\r\n                                          _MAX_PATH));\r\n\r\n  std::string command_line =\r\n    std::string(::GetCommandLineA()) + \" \" + filter_flag + \" \\\"\" +\r\n    internal_flag + \"\\\"\";\r\n\r\n  DeathTest::set_last_death_test_message(\"\");\r\n\r\n  CaptureStderr();\r\n  // Flush the log buffers since the log streams are shared with the child.\r\n  FlushInfoLog();\r\n\r\n  // The child process will share the standard handles with the parent.\r\n  STARTUPINFOA startup_info;\r\n  memset(&startup_info, 0, sizeof(STARTUPINFO));\r\n  startup_info.dwFlags = STARTF_USESTDHANDLES;\r\n  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);\r\n  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);\r\n  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);\r\n\r\n  PROCESS_INFORMATION process_info;\r\n  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(\r\n                            executable_path,\r\n                            const_cast<char*>(command_line.c_str()),\r\n                            NULL,   // Retuned process handle is not inheritable.\r\n                            NULL,   // Retuned thread handle is not inheritable.\r\n                            TRUE,   // Child inherits all inheritable handles (for write_handle_).\r\n                            0x0,    // Default creation flags.\r\n                            NULL,   // Inherit the parent's environment.\r\n                            UnitTest::GetInstance()->original_working_dir(),\r\n                            &startup_info,\r\n                            &process_info) != FALSE);\r\n  child_handle_.Reset(process_info.hProcess);\r\n  ::CloseHandle(process_info.hThread);\r\n  set_spawned(true);\r\n  return OVERSEE_TEST;\r\n}\r\n# else  // We are not on Windows.\r\n\r\n// ForkingDeathTest provides implementations for most of the abstract\r\n// methods of the DeathTest interface.  Only the AssumeRole method is\r\n// left undefined.\r\nclass ForkingDeathTest : public DeathTestImpl {\r\n public:\r\n  ForkingDeathTest(const char* statement, const RE* regex);\r\n\r\n  // All of these virtual functions are inherited from DeathTest.\r\n  virtual int Wait();\r\n\r\n protected:\r\n  void set_child_pid(pid_t child_pid) {\r\n    child_pid_ = child_pid;\r\n  }\r\n\r\n private:\r\n  // PID of child process during death test; 0 in the child process itself.\r\n  pid_t child_pid_;\r\n};\r\n\r\n// Constructs a ForkingDeathTest.\r\nForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)\r\n  : DeathTestImpl(a_statement, a_regex),\r\n    child_pid_(-1) {}\r\n\r\n// Waits for the child in a death test to exit, returning its exit\r\n// status, or 0 if no child process exists.  As a side effect, sets the\r\n// outcome data member.\r\nint ForkingDeathTest::Wait() {\r\n  if (!spawned()) {\r\n    return 0;\r\n  }\r\n\r\n  ReadAndInterpretStatusByte();\r\n\r\n  int status_value;\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));\r\n  set_status(status_value);\r\n  return status_value;\r\n}\r\n\r\n// A concrete death test class that forks, then immediately runs the test\r\n// in the child process.\r\nclass NoExecDeathTest : public ForkingDeathTest {\r\n public:\r\n  NoExecDeathTest(const char* a_statement, const RE* a_regex) :\r\n    ForkingDeathTest(a_statement, a_regex) { }\r\n  virtual TestRole AssumeRole();\r\n};\r\n\r\n// The AssumeRole process for a fork-and-run death test.  It implements a\r\n// straightforward fork, with a simple pipe to transmit the status byte.\r\nDeathTest::TestRole NoExecDeathTest::AssumeRole() {\r\n  const size_t thread_count = GetThreadCount();\r\n\r\n  if (thread_count != 1) {\r\n    GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count);\r\n  }\r\n\r\n  int pipe_fd[2];\r\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\r\n\r\n  DeathTest::set_last_death_test_message(\"\");\r\n  CaptureStderr();\r\n  // When we fork the process below, the log file buffers are copied, but the\r\n  // file descriptors are shared.  We flush all log files here so that closing\r\n  // the file descriptors in the child process doesn't throw off the\r\n  // synchronization between descriptors and buffers in the parent process.\r\n  // This is as close to the fork as possible to avoid a race condition in case\r\n  // there are multiple threads running before the death test, and another\r\n  // thread writes to the log file.\r\n  FlushInfoLog();\r\n\r\n  const pid_t child_pid = fork();\r\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\r\n  set_child_pid(child_pid);\r\n\r\n  if (child_pid == 0) {\r\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0]));\r\n    set_write_fd(pipe_fd[1]);\r\n    // Redirects all logging to stderr in the child process to prevent\r\n    // concurrent writes to the log files.  We capture stderr in the parent\r\n    // process and append the child process' output to a log.\r\n    LogToStderr();\r\n    // Event forwarding to the listeners of event listener API mush be shut\r\n    // down in death test subprocesses.\r\n    GetUnitTestImpl()->listeners()->SuppressEventForwarding();\r\n    g_in_fast_death_test_child = true;\r\n    return EXECUTE_TEST;\r\n  }\r\n  else {\r\n    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\r\n    set_read_fd(pipe_fd[0]);\r\n    set_spawned(true);\r\n    return OVERSEE_TEST;\r\n  }\r\n}\r\n\r\n// A concrete death test class that forks and re-executes the main\r\n// program from the beginning, with command-line flags set that cause\r\n// only this specific death test to be run.\r\nclass ExecDeathTest : public ForkingDeathTest {\r\n public:\r\n  ExecDeathTest(const char* a_statement, const RE* a_regex,\r\n                const char* file, int line) :\r\n    ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }\r\n  virtual TestRole AssumeRole();\r\n private:\r\n  static ::std::vector<testing::internal::string>\r\n  GetArgvsForDeathTestChildProcess() {\r\n    ::std::vector<testing::internal::string> args = GetInjectableArgvs();\r\n    return args;\r\n  }\r\n  // The name of the file in which the death test is located.\r\n  const char* const file_;\r\n  // The line number on which the death test is located.\r\n  const int line_;\r\n};\r\n\r\n// Utility class for accumulating command-line arguments.\r\nclass Arguments {\r\n public:\r\n  Arguments() {\r\n    args_.push_back(NULL);\r\n  }\r\n\r\n  ~Arguments() {\r\n    for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();\r\n         ++i) {\r\n      free(*i);\r\n    }\r\n  }\r\n  void AddArgument(const char* argument) {\r\n    args_.insert(args_.end() - 1, posix::StrDup(argument));\r\n  }\r\n\r\n  template <typename Str>\r\n  void AddArguments(const ::std::vector<Str>& arguments) {\r\n    for (typename ::std::vector<Str>::const_iterator i = arguments.begin();\r\n         i != arguments.end();\r\n         ++i) {\r\n      args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));\r\n    }\r\n  }\r\n  char* const* Argv() {\r\n    return &args_[0];\r\n  }\r\n\r\n private:\r\n  std::vector<char*> args_;\r\n};\r\n\r\n// A struct that encompasses the arguments to the child process of a\r\n// threadsafe-style death test process.\r\nstruct ExecDeathTestArgs {\r\n  char* const* argv;  // Command-line arguments for the child's call to exec\r\n  int close_fd;       // File descriptor to close; the read end of a pipe\r\n};\r\n\r\n#  if GTEST_OS_MAC\r\ninline char** GetEnviron() {\r\n  // When Google Test is built as a framework on MacOS X, the environ variable\r\n  // is unavailable. Apple's documentation (man environ) recommends using\r\n  // _NSGetEnviron() instead.\r\n  return *_NSGetEnviron();\r\n}\r\n#  else\r\n// Some POSIX platforms expect you to declare environ. extern \"C\" makes\r\n// it reside in the global namespace.\r\nextern \"C\" char** environ;\r\ninline char** GetEnviron() {\r\n  return environ;\r\n}\r\n#  endif  // GTEST_OS_MAC\r\n\r\n#  if !GTEST_OS_QNX\r\n// The main function for a threadsafe-style death test child process.\r\n// This function is called in a clone()-ed process and thus must avoid\r\n// any potentially unsafe operations like malloc or libc functions.\r\nstatic int ExecDeathTestChildMain(void* child_arg) {\r\n  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));\r\n\r\n  // We need to execute the test program in the same environment where\r\n  // it was originally invoked.  Therefore we change to the original\r\n  // working directory first.\r\n  const char* const original_dir =\r\n    UnitTest::GetInstance()->original_working_dir();\r\n\r\n  // We can safely call chdir() as it's a direct system call.\r\n  if (chdir(original_dir) != 0) {\r\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir + \"\\\") failed: \" +\r\n                   GetLastErrnoDescription());\r\n    return EXIT_FAILURE;\r\n  }\r\n\r\n  // We can safely call execve() as it's a direct system call.  We\r\n  // cannot use execvp() as it's a libc function and thus potentially\r\n  // unsafe.  Since execve() doesn't search the PATH, the user must\r\n  // invoke the test program via a valid path that contains at least\r\n  // one path separator.\r\n  execve(args->argv[0], args->argv, GetEnviron());\r\n  DeathTestAbort(std::string(\"execve(\") + args->argv[0] + \", ...) in \" +\r\n                 original_dir + \" failed: \" +\r\n                 GetLastErrnoDescription());\r\n  return EXIT_FAILURE;\r\n}\r\n#  endif  // !GTEST_OS_QNX\r\n\r\n// Two utility routines that together determine the direction the stack\r\n// grows.\r\n// This could be accomplished more elegantly by a single recursive\r\n// function, but we want to guard against the unlikely possibility of\r\n// a smart compiler optimizing the recursion away.\r\n//\r\n// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining\r\n// StackLowerThanAddress into StackGrowsDown, which then doesn't give\r\n// correct answer.\r\nvoid StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;\r\nvoid StackLowerThanAddress(const void* ptr, bool* result) {\r\n  int dummy;\r\n  *result = (&dummy < ptr);\r\n}\r\n\r\nbool StackGrowsDown() {\r\n  int dummy;\r\n  bool result;\r\n  StackLowerThanAddress(&dummy, &result);\r\n  return result;\r\n}\r\n\r\n// Spawns a child process with the same executable as the current process in\r\n// a thread-safe manner and instructs it to run the death test.  The\r\n// implementation uses fork(2) + exec.  On systems where clone(2) is\r\n// available, it is used instead, being slightly more thread-safe.  On QNX,\r\n// fork supports only single-threaded environments, so this function uses\r\n// spawn(2) there instead.  The function dies with an error message if\r\n// anything goes wrong.\r\nstatic pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) {\r\n  ExecDeathTestArgs args = { argv, close_fd };\r\n  pid_t child_pid = -1;\r\n\r\n#  if GTEST_OS_QNX\r\n  // Obtains the current directory and sets it to be closed in the child\r\n  // process.\r\n  const int cwd_fd = open(\".\", O_RDONLY);\r\n  GTEST_DEATH_TEST_CHECK_(cwd_fd != -1);\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC));\r\n  // We need to execute the test program in the same environment where\r\n  // it was originally invoked.  Therefore we change to the original\r\n  // working directory first.\r\n  const char* const original_dir =\r\n    UnitTest::GetInstance()->original_working_dir();\r\n\r\n  // We can safely call chdir() as it's a direct system call.\r\n  if (chdir(original_dir) != 0) {\r\n    DeathTestAbort(std::string(\"chdir(\\\"\") + original_dir + \"\\\") failed: \" +\r\n                   GetLastErrnoDescription());\r\n    return EXIT_FAILURE;\r\n  }\r\n\r\n  int fd_flags;\r\n  // Set close_fd to be closed after spawn.\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD));\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD,\r\n                                        fd_flags | FD_CLOEXEC));\r\n  struct inheritance inherit = {0};\r\n  // spawn is a system call.\r\n  child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());\r\n  // Restores the current working directory.\r\n  GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));\r\n\r\n#  else   // GTEST_OS_QNX\r\n#   if GTEST_OS_LINUX\r\n  // When a SIGPROF signal is received while fork() or clone() are executing,\r\n  // the process may hang. To avoid this, we ignore SIGPROF here and re-enable\r\n  // it after the call to fork()/clone() is complete.\r\n  struct sigaction saved_sigprof_action;\r\n  struct sigaction ignore_sigprof_action;\r\n  memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action));\r\n  sigemptyset(&ignore_sigprof_action.sa_mask);\r\n  ignore_sigprof_action.sa_handler = SIG_IGN;\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction(\r\n                                    SIGPROF, &ignore_sigprof_action, &saved_sigprof_action));\r\n#   endif  // GTEST_OS_LINUX\r\n\r\n#   if GTEST_HAS_CLONE\r\n  const bool use_fork = GTEST_FLAG(death_test_use_fork);\r\n\r\n  if (!use_fork) {\r\n    static const bool stack_grows_down = StackGrowsDown();\r\n    const size_t stack_size = getpagesize();\r\n    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.\r\n    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,\r\n                             MAP_ANON | MAP_PRIVATE, -1, 0);\r\n    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);\r\n\r\n    // Maximum stack alignment in bytes:  For a downward-growing stack, this\r\n    // amount is subtracted from size of the stack space to get an address\r\n    // that is within the stack space and is aligned on all systems we care\r\n    // about.  As far as I know there is no ABI with stack alignment greater\r\n    // than 64.  We assume stack and stack_size already have alignment of\r\n    // kMaxStackAlignment.\r\n    const size_t kMaxStackAlignment = 64;\r\n    void* const stack_top =\r\n      static_cast<char*>(stack) +\r\n      (stack_grows_down ? stack_size - kMaxStackAlignment : 0);\r\n    GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment &&\r\n                            reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0);\r\n\r\n    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);\r\n\r\n    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);\r\n  }\r\n\r\n#   else\r\n  const bool use_fork = true;\r\n#   endif  // GTEST_HAS_CLONE\r\n\r\n  if (use_fork && (child_pid = fork()) == 0) {\r\n    ExecDeathTestChildMain(&args);\r\n    _exit(0);\r\n  }\r\n\r\n#  endif  // GTEST_OS_QNX\r\n#  if GTEST_OS_LINUX\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(\r\n    sigaction(SIGPROF, &saved_sigprof_action, NULL));\r\n#  endif  // GTEST_OS_LINUX\r\n\r\n  GTEST_DEATH_TEST_CHECK_(child_pid != -1);\r\n  return child_pid;\r\n}\r\n\r\n// The AssumeRole process for a fork-and-exec death test.  It re-executes the\r\n// main program from the beginning, setting the --gtest_filter\r\n// and --gtest_internal_run_death_test flags to cause only the current\r\n// death test to be re-run.\r\nDeathTest::TestRole ExecDeathTest::AssumeRole() {\r\n  const UnitTestImpl* const impl = GetUnitTestImpl();\r\n  const InternalRunDeathTestFlag* const flag =\r\n    impl->internal_run_death_test_flag();\r\n  const TestInfo* const info = impl->current_test_info();\r\n  const int death_test_index = info->result()->death_test_count();\r\n\r\n  if (flag != NULL) {\r\n    set_write_fd(flag->write_fd());\r\n    return EXECUTE_TEST;\r\n  }\r\n\r\n  int pipe_fd[2];\r\n  GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1);\r\n  // Clear the close-on-exec flag on the write end of the pipe, lest\r\n  // it be closed when the child process does an exec:\r\n  GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);\r\n\r\n  const std::string filter_flag =\r\n    std::string(\"--\") + GTEST_FLAG_PREFIX_ + kFilterFlag + \"=\"\r\n    + info->test_case_name() + \".\" + info->name();\r\n  const std::string internal_flag =\r\n    std::string(\"--\") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + \"=\"\r\n    + file_ + \"|\" + StreamableToString(line_) + \"|\"\r\n    + StreamableToString(death_test_index) + \"|\"\r\n    + StreamableToString(pipe_fd[1]);\r\n  Arguments args;\r\n  args.AddArguments(GetArgvsForDeathTestChildProcess());\r\n  args.AddArgument(filter_flag.c_str());\r\n  args.AddArgument(internal_flag.c_str());\r\n\r\n  DeathTest::set_last_death_test_message(\"\");\r\n\r\n  CaptureStderr();\r\n  // See the comment in NoExecDeathTest::AssumeRole for why the next line\r\n  // is necessary.\r\n  FlushInfoLog();\r\n\r\n  const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]);\r\n  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));\r\n  set_child_pid(child_pid);\r\n  set_read_fd(pipe_fd[0]);\r\n  set_spawned(true);\r\n  return OVERSEE_TEST;\r\n}\r\n\r\n# endif  // !GTEST_OS_WINDOWS\r\n\r\n// Creates a concrete DeathTest-derived class that depends on the\r\n// --gtest_death_test_style flag, and sets the pointer pointed to\r\n// by the \"test\" argument to its address.  If the test should be\r\n// skipped, sets that pointer to NULL.  Returns true, unless the\r\n// flag is set to an invalid value.\r\nbool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,\r\n                                     const char* file, int line,\r\n                                     DeathTest** test) {\r\n  UnitTestImpl* const impl = GetUnitTestImpl();\r\n  const InternalRunDeathTestFlag* const flag =\r\n    impl->internal_run_death_test_flag();\r\n  const int death_test_index = impl->current_test_info()\r\n                               ->increment_death_test_count();\r\n\r\n  if (flag != NULL) {\r\n    if (death_test_index > flag->index()) {\r\n      DeathTest::set_last_death_test_message(\r\n        \"Death test count (\" + StreamableToString(death_test_index)\r\n        + \") somehow exceeded expected maximum (\"\r\n        + StreamableToString(flag->index()) + \")\");\r\n      return false;\r\n    }\r\n\r\n    if (!(flag->file() == file && flag->line() == line &&\r\n          flag->index() == death_test_index)) {\r\n      *test = NULL;\r\n      return true;\r\n    }\r\n  }\r\n\r\n# if GTEST_OS_WINDOWS\r\n\r\n  if (GTEST_FLAG(death_test_style) == \"threadsafe\" ||\r\n      GTEST_FLAG(death_test_style) == \"fast\") {\r\n    *test = new WindowsDeathTest(statement, regex, file, line);\r\n  }\r\n\r\n# else\r\n\r\n  if (GTEST_FLAG(death_test_style) == \"threadsafe\") {\r\n    *test = new ExecDeathTest(statement, regex, file, line);\r\n  }\r\n  else if (GTEST_FLAG(death_test_style) == \"fast\") {\r\n    *test = new NoExecDeathTest(statement, regex);\r\n  }\r\n\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.\r\n    DeathTest::set_last_death_test_message(\r\n      \"Unknown death test style \\\"\" + GTEST_FLAG(death_test_style)\r\n      + \"\\\" encountered\");\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\n// Splits a given string on a given delimiter, populating a given\r\n// vector with the fields.  GTEST_HAS_DEATH_TEST implies that we have\r\n// ::std::string, so we can use it here.\r\nstatic void SplitString(const ::std::string& str, char delimiter,\r\n                        ::std::vector< ::std::string>* dest) {\r\n  ::std::vector< ::std::string> parsed;\r\n  ::std::string::size_type pos = 0;\r\n\r\n  while (::testing::internal::AlwaysTrue()) {\r\n    const ::std::string::size_type colon = str.find(delimiter, pos);\r\n\r\n    if (colon == ::std::string::npos) {\r\n      parsed.push_back(str.substr(pos));\r\n      break;\r\n    }\r\n    else {\r\n      parsed.push_back(str.substr(pos, colon - pos));\r\n      pos = colon + 1;\r\n    }\r\n  }\r\n\r\n  dest->swap(parsed);\r\n}\r\n\r\n# if GTEST_OS_WINDOWS\r\n// Recreates the pipe and event handles from the provided parameters,\r\n// signals the event, and returns a file descriptor wrapped around the pipe\r\n// handle. This function is called in the child process only.\r\nint GetStatusFileDescriptor(unsigned int parent_process_id,\r\n                            size_t write_handle_as_size_t,\r\n                            size_t event_handle_as_size_t) {\r\n  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,\r\n                                   FALSE,  // Non-inheritable.\r\n                                   parent_process_id));\r\n\r\n  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {\r\n    DeathTestAbort(\"Unable to open parent process \" +\r\n                   StreamableToString(parent_process_id));\r\n  }\r\n\r\n  // TODO(vladl@google.com): Replace the following check with a\r\n  // compile-time assertion when available.\r\n  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));\r\n\r\n  const HANDLE write_handle =\r\n    reinterpret_cast<HANDLE>(write_handle_as_size_t);\r\n  HANDLE dup_write_handle;\r\n\r\n  // The newly initialized handle is accessible only in in the parent\r\n  // process. To obtain one accessible within the child, we need to use\r\n  // DuplicateHandle.\r\n  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,\r\n                         ::GetCurrentProcess(), &dup_write_handle,\r\n                         0x0,    // Requested privileges ignored since\r\n                         // DUPLICATE_SAME_ACCESS is used.\r\n                         FALSE,  // Request non-inheritable handler.\r\n                         DUPLICATE_SAME_ACCESS)) {\r\n    DeathTestAbort(\"Unable to duplicate the pipe handle \" +\r\n                   StreamableToString(write_handle_as_size_t) +\r\n                   \" from the parent process \" +\r\n                   StreamableToString(parent_process_id));\r\n  }\r\n\r\n  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);\r\n  HANDLE dup_event_handle;\r\n\r\n  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,\r\n                         ::GetCurrentProcess(), &dup_event_handle,\r\n                         0x0,\r\n                         FALSE,\r\n                         DUPLICATE_SAME_ACCESS)) {\r\n    DeathTestAbort(\"Unable to duplicate the event handle \" +\r\n                   StreamableToString(event_handle_as_size_t) +\r\n                   \" from the parent process \" +\r\n                   StreamableToString(parent_process_id));\r\n  }\r\n\r\n  const int write_fd =\r\n    ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);\r\n\r\n  if (write_fd == -1) {\r\n    DeathTestAbort(\"Unable to convert pipe handle \" +\r\n                   StreamableToString(write_handle_as_size_t) +\r\n                   \" to a file descriptor\");\r\n  }\r\n\r\n  // Signals the parent that the write end of the pipe has been acquired\r\n  // so the parent can release its own write end.\r\n  ::SetEvent(dup_event_handle);\r\n\r\n  return write_fd;\r\n}\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n// Returns a newly created InternalRunDeathTestFlag object with fields\r\n// initialized from the GTEST_FLAG(internal_run_death_test) flag if\r\n// the flag is specified; otherwise returns NULL.\r\nInternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {\r\n  if (GTEST_FLAG(internal_run_death_test) == \"\") {\r\n    return NULL;\r\n  }\r\n\r\n  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we\r\n  // can use it here.\r\n  int line = -1;\r\n  int index = -1;\r\n  ::std::vector< ::std::string> fields;\r\n  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);\r\n  int write_fd = -1;\r\n\r\n# if GTEST_OS_WINDOWS\r\n\r\n  unsigned int parent_process_id = 0;\r\n  size_t write_handle_as_size_t = 0;\r\n  size_t event_handle_as_size_t = 0;\r\n\r\n  if (fields.size() != 6\r\n      || !ParseNaturalNumber(fields[1], &line)\r\n      || !ParseNaturalNumber(fields[2], &index)\r\n      || !ParseNaturalNumber(fields[3], &parent_process_id)\r\n      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)\r\n      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {\r\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \" +\r\n                   GTEST_FLAG(internal_run_death_test));\r\n  }\r\n\r\n  write_fd = GetStatusFileDescriptor(parent_process_id,\r\n                                     write_handle_as_size_t,\r\n                                     event_handle_as_size_t);\r\n# else\r\n\r\n  if (fields.size() != 4\r\n      || !ParseNaturalNumber(fields[1], &line)\r\n      || !ParseNaturalNumber(fields[2], &index)\r\n      || !ParseNaturalNumber(fields[3], &write_fd)) {\r\n    DeathTestAbort(\"Bad --gtest_internal_run_death_test flag: \"\r\n                   + GTEST_FLAG(internal_run_death_test));\r\n  }\r\n\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);\r\n}\r\n\r\n}  // namespace internal\r\n\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-filepath.cpp",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Authors: keith.ray@gmail.com (Keith Ray)\r\n\r\n#include \"gtest/gtest-message.h\"\r\n#include \"gtest/internal/gtest-filepath.h\"\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#include <stdlib.h>\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n# include <windows.h>\r\n#elif GTEST_OS_WINDOWS\r\n# include <direct.h>\r\n# include <io.h>\r\n#elif GTEST_OS_SYMBIAN\r\n// Symbian OpenC has PATH_MAX in sys/syslimits.h\r\n# include <sys/syslimits.h>\r\n#else\r\n# include <limits.h>\r\n# include <climits>  // Some Linux distributions define PATH_MAX here.\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n#if GTEST_OS_WINDOWS\r\n# define GTEST_PATH_MAX_ _MAX_PATH\r\n#elif defined(PATH_MAX)\r\n# define GTEST_PATH_MAX_ PATH_MAX\r\n#elif defined(_XOPEN_PATH_MAX)\r\n# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX\r\n#else\r\n# define GTEST_PATH_MAX_ _POSIX_PATH_MAX\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n#include \"gtest/internal/gtest-string.h\"\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n#if GTEST_OS_WINDOWS\r\n// On Windows, '\\\\' is the standard path separator, but many tools and the\r\n// Windows API also accept '/' as an alternate path separator. Unless otherwise\r\n// noted, a file path can contain either kind of path separators, or a mixture\r\n// of them.\r\nconst char kPathSeparator = '\\\\';\r\nconst char kAlternatePathSeparator = '/';\r\nconst char kPathSeparatorString[] = \"\\\\\";\r\nconst char kAlternatePathSeparatorString[] = \"/\";\r\n# if GTEST_OS_WINDOWS_MOBILE\r\n// Windows CE doesn't have a current directory. You should not use\r\n// the current directory in tests on Windows CE, but this at least\r\n// provides a reasonable fallback.\r\nconst char kCurrentDirectoryString[] = \"\\\\\";\r\n// Windows CE doesn't define INVALID_FILE_ATTRIBUTES\r\nconst DWORD kInvalidFileAttributes = 0xffffffff;\r\n# else\r\nconst char kCurrentDirectoryString[] = \".\\\\\";\r\n# endif  // GTEST_OS_WINDOWS_MOBILE\r\n#else\r\nconst char kPathSeparator = '/';\r\nconst char kPathSeparatorString[] = \"/\";\r\nconst char kCurrentDirectoryString[] = \"./\";\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Returns whether the given character is a valid path separator.\r\nstatic bool IsPathSeparator(char c) {\r\n#if GTEST_HAS_ALT_PATH_SEP_\r\n  return (c == kPathSeparator) || (c == kAlternatePathSeparator);\r\n#else\r\n  return c == kPathSeparator;\r\n#endif\r\n}\r\n\r\n// Returns the current working directory, or \"\" if unsuccessful.\r\nFilePath FilePath::GetCurrentDir() {\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  // Windows CE doesn't have a current directory, so we just return\r\n  // something reasonable.\r\n  return FilePath(kCurrentDirectoryString);\r\n#elif GTEST_OS_WINDOWS\r\n  char cwd[GTEST_PATH_MAX_ + 1] = { '\\0' };\r\n  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? \"\" : cwd);\r\n#else\r\n  char cwd[GTEST_PATH_MAX_ + 1] = { '\\0' };\r\n  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? \"\" : cwd);\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n}\r\n\r\n// Returns a copy of the FilePath with the case-insensitive extension removed.\r\n// Example: FilePath(\"dir/file.exe\").RemoveExtension(\"EXE\") returns\r\n// FilePath(\"dir/file\"). If a case-insensitive extension is not\r\n// found, returns a copy of the original FilePath.\r\nFilePath FilePath::RemoveExtension(const char* extension) const {\r\n  const std::string dot_extension = std::string(\".\") + extension;\r\n\r\n  if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {\r\n    return FilePath(pathname_.substr(\r\n                      0, pathname_.length() - dot_extension.length()));\r\n  }\r\n\r\n  return *this;\r\n}\r\n\r\n// Returns a pointer to the last occurence of a valid path separator in\r\n// the FilePath. On Windows, for example, both '/' and '\\' are valid path\r\n// separators. Returns NULL if no path separator was found.\r\nconst char* FilePath::FindLastPathSeparator() const {\r\n  const char* const last_sep = strrchr(c_str(), kPathSeparator);\r\n#if GTEST_HAS_ALT_PATH_SEP_\r\n  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);\r\n\r\n  // Comparing two pointers of which only one is NULL is undefined.\r\n  if (last_alt_sep != NULL &&\r\n      (last_sep == NULL || last_alt_sep > last_sep)) {\r\n    return last_alt_sep;\r\n  }\r\n\r\n#endif\r\n  return last_sep;\r\n}\r\n\r\n// Returns a copy of the FilePath with the directory part removed.\r\n// Example: FilePath(\"path/to/file\").RemoveDirectoryName() returns\r\n// FilePath(\"file\"). If there is no directory part (\"just_a_file\"), it returns\r\n// the FilePath unmodified. If there is no file part (\"just_a_dir/\") it\r\n// returns an empty FilePath (\"\").\r\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\r\nFilePath FilePath::RemoveDirectoryName() const {\r\n  const char* const last_sep = FindLastPathSeparator();\r\n  return last_sep ? FilePath(last_sep + 1) : *this;\r\n}\r\n\r\n// RemoveFileName returns the directory path with the filename removed.\r\n// Example: FilePath(\"path/to/file\").RemoveFileName() returns \"path/to/\".\r\n// If the FilePath is \"a_file\" or \"/a_file\", RemoveFileName returns\r\n// FilePath(\"./\") or, on Windows, FilePath(\".\\\\\"). If the filepath does\r\n// not have a file, like \"just/a/dir/\", it returns the FilePath unmodified.\r\n// On Windows platform, '\\' is the path separator, otherwise it is '/'.\r\nFilePath FilePath::RemoveFileName() const {\r\n  const char* const last_sep = FindLastPathSeparator();\r\n  std::string dir;\r\n\r\n  if (last_sep) {\r\n    dir = std::string(c_str(), last_sep + 1 - c_str());\r\n  }\r\n  else {\r\n    dir = kCurrentDirectoryString;\r\n  }\r\n\r\n  return FilePath(dir);\r\n}\r\n\r\n// Helper functions for naming files in a directory for xml output.\r\n\r\n// Given directory = \"dir\", base_name = \"test\", number = 0,\r\n// extension = \"xml\", returns \"dir/test.xml\". If number is greater\r\n// than zero (e.g., 12), returns \"dir/test_12.xml\".\r\n// On Windows platform, uses \\ as the separator rather than /.\r\nFilePath FilePath::MakeFileName(const FilePath& directory,\r\n                                const FilePath& base_name,\r\n                                int number,\r\n                                const char* extension) {\r\n  std::string file;\r\n\r\n  if (number == 0) {\r\n    file = base_name.string() + \".\" + extension;\r\n  }\r\n  else {\r\n    file = base_name.string() + \"_\" + StreamableToString(number)\r\n           + \".\" + extension;\r\n  }\r\n\r\n  return ConcatPaths(directory, FilePath(file));\r\n}\r\n\r\n// Given directory = \"dir\", relative_path = \"test.xml\", returns \"dir/test.xml\".\r\n// On Windows, uses \\ as the separator rather than /.\r\nFilePath FilePath::ConcatPaths(const FilePath& directory,\r\n                               const FilePath& relative_path) {\r\n  if (directory.IsEmpty()) {\r\n    return relative_path;\r\n  }\r\n\r\n  const FilePath dir(directory.RemoveTrailingPathSeparator());\r\n  return FilePath(dir.string() + kPathSeparator + relative_path.string());\r\n}\r\n\r\n// Returns true if pathname describes something findable in the file-system,\r\n// either a file, directory, or whatever.\r\nbool FilePath::FileOrDirectoryExists() const {\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());\r\n  const DWORD attributes = GetFileAttributes(unicode);\r\n  delete [] unicode;\r\n  return attributes != kInvalidFileAttributes;\r\n#else\r\n  posix::StatStruct file_stat;\r\n  return posix::Stat(pathname_.c_str(), &file_stat) == 0;\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n}\r\n\r\n// Returns true if pathname describes a directory in the file-system\r\n// that exists.\r\nbool FilePath::DirectoryExists() const {\r\n  bool result = false;\r\n#if GTEST_OS_WINDOWS\r\n  // Don't strip off trailing separator if path is a root directory on\r\n  // Windows (like \"C:\\\\\").\r\n  const FilePath& path(IsRootDirectory() ? *this :\r\n                       RemoveTrailingPathSeparator());\r\n#else\r\n  const FilePath& path(*this);\r\n#endif\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());\r\n  const DWORD attributes = GetFileAttributes(unicode);\r\n  delete [] unicode;\r\n\r\n  if ((attributes != kInvalidFileAttributes) &&\r\n      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {\r\n    result = true;\r\n  }\r\n\r\n#else\r\n  posix::StatStruct file_stat;\r\n  result = posix::Stat(path.c_str(), &file_stat) == 0 &&\r\n           posix::IsDir(file_stat);\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n  return result;\r\n}\r\n\r\n// Returns true if pathname describes a root directory. (Windows has one\r\n// root directory per disk drive.)\r\nbool FilePath::IsRootDirectory() const {\r\n#if GTEST_OS_WINDOWS\r\n  // TODO(wan@google.com): on Windows a network share like\r\n  // \\\\server\\share can be a root directory, although it cannot be the\r\n  // current directory.  Handle this properly.\r\n  return pathname_.length() == 3 && IsAbsolutePath();\r\n#else\r\n  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);\r\n#endif\r\n}\r\n\r\n// Returns true if pathname describes an absolute path.\r\nbool FilePath::IsAbsolutePath() const {\r\n  const char* const name = pathname_.c_str();\r\n#if GTEST_OS_WINDOWS\r\n  return pathname_.length() >= 3 &&\r\n         ((name[0] >= 'a' && name[0] <= 'z') ||\r\n          (name[0] >= 'A' && name[0] <= 'Z')) &&\r\n         name[1] == ':' &&\r\n         IsPathSeparator(name[2]);\r\n#else\r\n  return IsPathSeparator(name[0]);\r\n#endif\r\n}\r\n\r\n// Returns a pathname for a file that does not currently exist. The pathname\r\n// will be directory/base_name.extension or\r\n// directory/base_name_<number>.extension if directory/base_name.extension\r\n// already exists. The number will be incremented until a pathname is found\r\n// that does not already exist.\r\n// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.\r\n// There could be a race condition if two or more processes are calling this\r\n// function at the same time -- they could both pick the same filename.\r\nFilePath FilePath::GenerateUniqueFileName(const FilePath& directory,\r\n    const FilePath& base_name,\r\n    const char* extension) {\r\n  FilePath full_pathname;\r\n  int number = 0;\r\n\r\n  do {\r\n    full_pathname.Set(MakeFileName(directory, base_name, number++, extension));\r\n  }\r\n  while (full_pathname.FileOrDirectoryExists());\r\n\r\n  return full_pathname;\r\n}\r\n\r\n// Returns true if FilePath ends with a path separator, which indicates that\r\n// it is intended to represent a directory. Returns false otherwise.\r\n// This does NOT check that a directory (or file) actually exists.\r\nbool FilePath::IsDirectory() const {\r\n  return !pathname_.empty() &&\r\n         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);\r\n}\r\n\r\n// Create directories so that path exists. Returns true if successful or if\r\n// the directories already exist; returns false if unable to create directories\r\n// for any reason.\r\nbool FilePath::CreateDirectoriesRecursively() const {\r\n  if (!this->IsDirectory()) {\r\n    return false;\r\n  }\r\n\r\n  if (pathname_.length() == 0 || this->DirectoryExists()) {\r\n    return true;\r\n  }\r\n\r\n  const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName());\r\n  return parent.CreateDirectoriesRecursively() && this->CreateFolder();\r\n}\r\n\r\n// Create the directory so that path exists. Returns true if successful or\r\n// if the directory already exists; returns false if unable to create the\r\n// directory for any reason, including if the parent directory does not\r\n// exist. Not named \"CreateDirectory\" because that's a macro on Windows.\r\nbool FilePath::CreateFolder() const {\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n  FilePath removed_sep(this->RemoveTrailingPathSeparator());\r\n  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());\r\n  int result = CreateDirectory(unicode, NULL) ? 0 : -1;\r\n  delete [] unicode;\r\n#elif GTEST_OS_WINDOWS\r\n  int result = _mkdir(pathname_.c_str());\r\n#else\r\n  int result = mkdir(pathname_.c_str(), 0777);\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n  if (result == -1) {\r\n    return this->DirectoryExists();  // An error is OK if the directory exists.\r\n  }\r\n\r\n  return true;  // No error.\r\n}\r\n\r\n// If input name has a trailing separator character, remove it and return the\r\n// name, otherwise return the name string unmodified.\r\n// On Windows platform, uses \\ as the separator, other platforms use /.\r\nFilePath FilePath::RemoveTrailingPathSeparator() const {\r\n  return IsDirectory()\r\n         ? FilePath(pathname_.substr(0, pathname_.length() - 1))\r\n         : *this;\r\n}\r\n\r\n// Removes any redundant separators that might be in the pathname.\r\n// For example, \"bar///foo\" becomes \"bar/foo\". Does not eliminate other\r\n// redundancies that might be in a pathname involving \".\" or \"..\".\r\n// TODO(wan@google.com): handle Windows network shares (e.g. \\\\server\\share).\r\nvoid FilePath::Normalize() {\r\n  if (pathname_.c_str() == NULL) {\r\n    pathname_ = \"\";\r\n    return;\r\n  }\r\n\r\n  const char* src = pathname_.c_str();\r\n  char* const dest = new char[pathname_.length() + 1];\r\n  char* dest_ptr = dest;\r\n  memset(dest_ptr, 0, pathname_.length() + 1);\r\n\r\n  while (*src != '\\0') {\r\n    *dest_ptr = *src;\r\n\r\n    if (!IsPathSeparator(*src)) {\r\n      src++;\r\n    }\r\n    else {\r\n#if GTEST_HAS_ALT_PATH_SEP_\r\n\r\n      if (*dest_ptr == kAlternatePathSeparator) {\r\n        *dest_ptr = kPathSeparator;\r\n      }\r\n\r\n#endif\r\n\r\n      while (IsPathSeparator(*src)) {\r\n        src++;\r\n      }\r\n    }\r\n\r\n    dest_ptr++;\r\n  }\r\n\r\n  *dest_ptr = '\\0';\r\n  pathname_ = dest;\r\n  delete[] dest;\r\n}\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-internal-inl.h",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n// Utility functions and classes used by the Google C++ testing framework.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// This file contains purely Google Test's internal implementation.  Please\r\n// DO NOT #INCLUDE IT IN A USER PROGRAM.\r\n\r\n#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_\r\n#define GTEST_SRC_GTEST_INTERNAL_INL_H_\r\n\r\n// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is\r\n// part of Google Test's implementation; otherwise it's undefined.\r\n#if !GTEST_IMPLEMENTATION_\r\n// A user is trying to include this from his code - just say no.\r\n# error \"gtest-internal-inl.h is part of Google Test's internal implementation.\"\r\n# error \"It must not be included except by Google Test itself.\"\r\n#endif  // GTEST_IMPLEMENTATION_\r\n\r\n#ifndef _WIN32_WCE\r\n# include <errno.h>\r\n#endif  // !_WIN32_WCE\r\n#include <stddef.h>\r\n#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.\r\n#include <string.h>  // For memmove.\r\n\r\n#include <algorithm>\r\n#include <string>\r\n#include <vector>\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n# include <arpa/inet.h>  // NOLINT\r\n# include <netdb.h>  // NOLINT\r\n#endif\r\n\r\n#if GTEST_OS_WINDOWS\r\n# include <windows.h>  // NOLINT\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n#include \"gtest/gtest.h\"  // NOLINT\r\n#include \"gtest/gtest-spi.h\"\r\n\r\nnamespace testing {\r\n\r\n// Declares the flags.\r\n//\r\n// We don't want the users to modify this flag in the code, but want\r\n// Google Test's own unit tests to be able to access it. Therefore we\r\n// declare it here as opposed to in gtest.h.\r\nGTEST_DECLARE_bool_(death_test_use_fork);\r\n\r\nnamespace internal {\r\n\r\n// The value of GetTestTypeId() as seen from within the Google Test\r\n// library.  This is solely for testing GetTestTypeId().\r\nGTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;\r\n\r\n// Names of the flags (needed for parsing Google Test flags).\r\nconst char kAlsoRunDisabledTestsFlag[] = \"also_run_disabled_tests\";\r\nconst char kBreakOnFailureFlag[] = \"break_on_failure\";\r\nconst char kCatchExceptionsFlag[] = \"catch_exceptions\";\r\nconst char kColorFlag[] = \"color\";\r\nconst char kFilterFlag[] = \"filter\";\r\nconst char kListTestsFlag[] = \"list_tests\";\r\nconst char kOutputFlag[] = \"output\";\r\nconst char kPrintTimeFlag[] = \"print_time\";\r\nconst char kRandomSeedFlag[] = \"random_seed\";\r\nconst char kRepeatFlag[] = \"repeat\";\r\nconst char kShuffleFlag[] = \"shuffle\";\r\nconst char kStackTraceDepthFlag[] = \"stack_trace_depth\";\r\nconst char kStreamResultToFlag[] = \"stream_result_to\";\r\nconst char kThrowOnFailureFlag[] = \"throw_on_failure\";\r\n\r\n// A valid random seed must be in [1, kMaxRandomSeed].\r\nconst int kMaxRandomSeed = 99999;\r\n\r\n// g_help_flag is true iff the --help flag or an equivalent form is\r\n// specified on the command line.\r\nGTEST_API_ extern bool g_help_flag;\r\n\r\n// Returns the current time in milliseconds.\r\nGTEST_API_ TimeInMillis GetTimeInMillis();\r\n\r\n// Returns true iff Google Test should use colors in the output.\r\nGTEST_API_ bool ShouldUseColor(bool stdout_is_tty);\r\n\r\n// Formats the given time in milliseconds as seconds.\r\nGTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);\r\n\r\n// Converts the given time in milliseconds to a date string in the ISO 8601\r\n// format, without the timezone information.  N.B.: due to the use the\r\n// non-reentrant localtime() function, this function is not thread safe.  Do\r\n// not use it in any code that can be called from multiple threads.\r\nGTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);\r\n\r\n// Parses a string for an Int32 flag, in the form of \"--flag=value\".\r\n//\r\n// On success, stores the value of the flag in *value, and returns\r\n// true.  On failure, returns false without changing *value.\r\nGTEST_API_ bool ParseInt32Flag(\r\n  const char* str, const char* flag, Int32* value);\r\n\r\n// Returns a random seed in range [1, kMaxRandomSeed] based on the\r\n// given --gtest_random_seed flag value.\r\ninline int GetRandomSeedFromFlag(Int32 random_seed_flag) {\r\n  const unsigned int raw_seed = (random_seed_flag == 0) ?\r\n                                static_cast<unsigned int>(GetTimeInMillis()) :\r\n                                static_cast<unsigned int>(random_seed_flag);\r\n\r\n  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that\r\n  // it's easy to type.\r\n  const int normalized_seed =\r\n    static_cast<int>((raw_seed - 1U) %\r\n                     static_cast<unsigned int>(kMaxRandomSeed)) + 1;\r\n  return normalized_seed;\r\n}\r\n\r\n// Returns the first valid random seed after 'seed'.  The behavior is\r\n// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is\r\n// considered to be 1.\r\ninline int GetNextRandomSeed(int seed) {\r\n  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)\r\n      << \"Invalid random seed \" << seed << \" - must be in [1, \"\r\n      << kMaxRandomSeed << \"].\";\r\n  const int next_seed = seed + 1;\r\n  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;\r\n}\r\n\r\n// This class saves the values of all Google Test flags in its c'tor, and\r\n// restores them in its d'tor.\r\nclass GTestFlagSaver {\r\n public:\r\n  // The c'tor.\r\n  GTestFlagSaver() {\r\n    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);\r\n    break_on_failure_ = GTEST_FLAG(break_on_failure);\r\n    catch_exceptions_ = GTEST_FLAG(catch_exceptions);\r\n    color_ = GTEST_FLAG(color);\r\n    death_test_style_ = GTEST_FLAG(death_test_style);\r\n    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);\r\n    filter_ = GTEST_FLAG(filter);\r\n    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);\r\n    list_tests_ = GTEST_FLAG(list_tests);\r\n    output_ = GTEST_FLAG(output);\r\n    print_time_ = GTEST_FLAG(print_time);\r\n    random_seed_ = GTEST_FLAG(random_seed);\r\n    repeat_ = GTEST_FLAG(repeat);\r\n    shuffle_ = GTEST_FLAG(shuffle);\r\n    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);\r\n    stream_result_to_ = GTEST_FLAG(stream_result_to);\r\n    throw_on_failure_ = GTEST_FLAG(throw_on_failure);\r\n  }\r\n\r\n  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.\r\n  ~GTestFlagSaver() {\r\n    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;\r\n    GTEST_FLAG(break_on_failure) = break_on_failure_;\r\n    GTEST_FLAG(catch_exceptions) = catch_exceptions_;\r\n    GTEST_FLAG(color) = color_;\r\n    GTEST_FLAG(death_test_style) = death_test_style_;\r\n    GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;\r\n    GTEST_FLAG(filter) = filter_;\r\n    GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;\r\n    GTEST_FLAG(list_tests) = list_tests_;\r\n    GTEST_FLAG(output) = output_;\r\n    GTEST_FLAG(print_time) = print_time_;\r\n    GTEST_FLAG(random_seed) = random_seed_;\r\n    GTEST_FLAG(repeat) = repeat_;\r\n    GTEST_FLAG(shuffle) = shuffle_;\r\n    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;\r\n    GTEST_FLAG(stream_result_to) = stream_result_to_;\r\n    GTEST_FLAG(throw_on_failure) = throw_on_failure_;\r\n  }\r\n\r\n private:\r\n  // Fields for saving the original values of flags.\r\n  bool also_run_disabled_tests_;\r\n  bool break_on_failure_;\r\n  bool catch_exceptions_;\r\n  std::string color_;\r\n  std::string death_test_style_;\r\n  bool death_test_use_fork_;\r\n  std::string filter_;\r\n  std::string internal_run_death_test_;\r\n  bool list_tests_;\r\n  std::string output_;\r\n  bool print_time_;\r\n  internal::Int32 random_seed_;\r\n  internal::Int32 repeat_;\r\n  bool shuffle_;\r\n  internal::Int32 stack_trace_depth_;\r\n  std::string stream_result_to_;\r\n  bool throw_on_failure_;\r\n} GTEST_ATTRIBUTE_UNUSED_;\r\n\r\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\r\n// code_point parameter is of type UInt32 because wchar_t may not be\r\n// wide enough to contain a code point.\r\n// If the code_point is not a valid Unicode code point\r\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\r\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\r\nGTEST_API_ std::string CodePointToUtf8(UInt32 code_point);\r\n\r\n// Converts a wide string to a narrow string in UTF-8 encoding.\r\n// The wide string is assumed to have the following encoding:\r\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)\r\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\r\n// Parameter str points to a null-terminated wide string.\r\n// Parameter num_chars may additionally limit the number\r\n// of wchar_t characters processed. -1 is used when the entire string\r\n// should be processed.\r\n// If the string contains code points that are not valid Unicode code points\r\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\r\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\r\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\r\n// will be encoded as individual Unicode characters from Basic Normal Plane.\r\nGTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars);\r\n\r\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\r\n// if the variable is present. If a file already exists at this location, this\r\n// function will write over it. If the variable is present, but the file cannot\r\n// be created, prints an error and exits.\r\nvoid WriteToShardStatusFileIfNeeded();\r\n\r\n// Checks whether sharding is enabled by examining the relevant\r\n// environment variable values. If the variables are present,\r\n// but inconsistent (e.g., shard_index >= total_shards), prints\r\n// an error and exits. If in_subprocess_for_death_test, sharding is\r\n// disabled because it must only be applied to the original test\r\n// process. Otherwise, we could filter out death tests we intended to execute.\r\nGTEST_API_ bool ShouldShard(const char* total_shards_str,\r\n                            const char* shard_index_str,\r\n                            bool in_subprocess_for_death_test);\r\n\r\n// Parses the environment variable var as an Int32. If it is unset,\r\n// returns default_val. If it is not an Int32, prints an error and\r\n// and aborts.\r\nGTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);\r\n\r\n// Given the total number of shards, the shard index, and the test id,\r\n// returns true iff the test should be run on this shard. The test id is\r\n// some arbitrary but unique non-negative integer assigned to each test\r\n// method. Assumes that 0 <= shard_index < total_shards.\r\nGTEST_API_ bool ShouldRunTestOnShard(\r\n  int total_shards, int shard_index, int test_id);\r\n\r\n// STL container utilities.\r\n\r\n// Returns the number of elements in the given container that satisfy\r\n// the given predicate.\r\ntemplate <class Container, typename Predicate>\r\ninline int CountIf(const Container& c, Predicate predicate) {\r\n  // Implemented as an explicit loop since std::count_if() in libCstd on\r\n  // Solaris has a non-standard signature.\r\n  int count = 0;\r\n\r\n  for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {\r\n    if (predicate(*it)) {\r\n      ++count;\r\n    }\r\n  }\r\n\r\n  return count;\r\n}\r\n\r\n// Applies a function/functor to each element in the container.\r\ntemplate <class Container, typename Functor>\r\nvoid ForEach(const Container& c, Functor functor) {\r\n  std::for_each(c.begin(), c.end(), functor);\r\n}\r\n\r\n// Returns the i-th element of the vector, or default_value if i is not\r\n// in range [0, v.size()).\r\ntemplate <typename E>\r\ninline E GetElementOr(const std::vector<E>& v, int i, E default_value) {\r\n  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];\r\n}\r\n\r\n// Performs an in-place shuffle of a range of the vector's elements.\r\n// 'begin' and 'end' are element indices as an STL-style range;\r\n// i.e. [begin, end) are shuffled, where 'end' == size() means to\r\n// shuffle to the end of the vector.\r\ntemplate <typename E>\r\nvoid ShuffleRange(internal::Random* random, int begin, int end,\r\n                  std::vector<E>* v) {\r\n  const int size = static_cast<int>(v->size());\r\n  GTEST_CHECK_(0 <= begin && begin <= size)\r\n      << \"Invalid shuffle range start \" << begin << \": must be in range [0, \"\r\n      << size << \"].\";\r\n  GTEST_CHECK_(begin <= end && end <= size)\r\n      << \"Invalid shuffle range finish \" << end << \": must be in range [\"\r\n      << begin << \", \" << size << \"].\";\r\n\r\n  // Fisher-Yates shuffle, from\r\n  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle\r\n  for (int range_width = end - begin; range_width >= 2; range_width--) {\r\n    const int last_in_range = begin + range_width - 1;\r\n    const int selected = begin + random->Generate(range_width);\r\n    std::swap((*v)[selected], (*v)[last_in_range]);\r\n  }\r\n}\r\n\r\n// Performs an in-place shuffle of the vector's elements.\r\ntemplate <typename E>\r\ninline void Shuffle(internal::Random* random, std::vector<E>* v) {\r\n  ShuffleRange(random, 0, static_cast<int>(v->size()), v);\r\n}\r\n\r\n// A function for deleting an object.  Handy for being used as a\r\n// functor.\r\ntemplate <typename T>\r\nstatic void Delete(T* x) {\r\n  delete x;\r\n}\r\n\r\n// A predicate that checks the key of a TestProperty against a known key.\r\n//\r\n// TestPropertyKeyIs is copyable.\r\nclass TestPropertyKeyIs {\r\n public:\r\n  // Constructor.\r\n  //\r\n  // TestPropertyKeyIs has NO default constructor.\r\n  explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}\r\n\r\n  // Returns true iff the test name of test property matches on key_.\r\n  bool operator()(const TestProperty& test_property) const {\r\n    return test_property.key() == key_;\r\n  }\r\n\r\n private:\r\n  std::string key_;\r\n};\r\n\r\n// Class UnitTestOptions.\r\n//\r\n// This class contains functions for processing options the user\r\n// specifies when running the tests.  It has only static members.\r\n//\r\n// In most cases, the user can specify an option using either an\r\n// environment variable or a command line flag.  E.g. you can set the\r\n// test filter using either GTEST_FILTER or --gtest_filter.  If both\r\n// the variable and the flag are present, the latter overrides the\r\n// former.\r\nclass GTEST_API_ UnitTestOptions {\r\n public:\r\n  // Functions for processing the gtest_output flag.\r\n\r\n  // Returns the output format, or \"\" for normal printed output.\r\n  static std::string GetOutputFormat();\r\n\r\n  // Returns the absolute path of the requested output file, or the\r\n  // default (test_detail.xml in the original working directory) if\r\n  // none was explicitly specified.\r\n  static std::string GetAbsolutePathToOutputFile();\r\n\r\n  // Functions for processing the gtest_filter flag.\r\n\r\n  // Returns true iff the wildcard pattern matches the string.  The\r\n  // first ':' or '\\0' character in pattern marks the end of it.\r\n  //\r\n  // This recursive algorithm isn't very efficient, but is clear and\r\n  // works well enough for matching test names, which are short.\r\n  static bool PatternMatchesString(const char* pattern, const char* str);\r\n\r\n  // Returns true iff the user-specified filter matches the test case\r\n  // name and the test name.\r\n  static bool FilterMatchesTest(const std::string& test_case_name,\r\n                                const std::string& test_name);\r\n\r\n#if GTEST_OS_WINDOWS\r\n  // Function for supporting the gtest_catch_exception flag.\r\n\r\n  // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the\r\n  // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.\r\n  // This function is useful as an __except condition.\r\n  static int GTestShouldProcessSEH(DWORD exception_code);\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n  // Returns true if \"name\" matches the ':' separated list of glob-style\r\n  // filters in \"filter\".\r\n  static bool MatchesFilter(const std::string& name, const char* filter);\r\n};\r\n\r\n// Returns the current application's name, removing directory path if that\r\n// is present.  Used by UnitTestOptions::GetOutputFile.\r\nGTEST_API_ FilePath GetCurrentExecutableName();\r\n\r\n// The role interface for getting the OS stack trace as a string.\r\nclass OsStackTraceGetterInterface {\r\n public:\r\n  OsStackTraceGetterInterface() {}\r\n  virtual ~OsStackTraceGetterInterface() {}\r\n\r\n  // Returns the current OS stack trace as an std::string.  Parameters:\r\n  //\r\n  //   max_depth  - the maximum number of stack frames to be included\r\n  //                in the trace.\r\n  //   skip_count - the number of top frames to be skipped; doesn't count\r\n  //                against max_depth.\r\n  virtual string CurrentStackTrace(int max_depth, int skip_count) = 0;\r\n\r\n  // UponLeavingGTest() should be called immediately before Google Test calls\r\n  // user code. It saves some information about the current stack that\r\n  // CurrentStackTrace() will use to find and hide Google Test stack frames.\r\n  virtual void UponLeavingGTest() = 0;\r\n\r\n private:\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);\r\n};\r\n\r\n// A working implementation of the OsStackTraceGetterInterface interface.\r\nclass OsStackTraceGetter : public OsStackTraceGetterInterface {\r\n public:\r\n  OsStackTraceGetter() : caller_frame_(NULL) {}\r\n\r\n  virtual string CurrentStackTrace(int max_depth, int skip_count)\r\n  GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);\r\n\r\n  // This string is inserted in place of stack frames that are part of\r\n  // Google Test's implementation.\r\n  static const char* const kElidedFramesMarker;\r\n\r\n private:\r\n  Mutex mutex_;  // protects all internal state\r\n\r\n  // We save the stack frame below the frame that calls user code.\r\n  // We do this because the address of the frame immediately below\r\n  // the user code changes between the call to UponLeavingGTest()\r\n  // and any calls to CurrentStackTrace() from within the user code.\r\n  void* caller_frame_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);\r\n};\r\n\r\n// Information about a Google Test trace point.\r\nstruct TraceInfo {\r\n  const char* file;\r\n  int line;\r\n  std::string message;\r\n};\r\n\r\n// This is the default global test part result reporter used in UnitTestImpl.\r\n// This class should only be used by UnitTestImpl.\r\nclass DefaultGlobalTestPartResultReporter\r\n  : public TestPartResultReporterInterface {\r\n public:\r\n  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);\r\n  // Implements the TestPartResultReporterInterface. Reports the test part\r\n  // result in the current test.\r\n  virtual void ReportTestPartResult(const TestPartResult& result);\r\n\r\n private:\r\n  UnitTestImpl* const unit_test_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);\r\n};\r\n\r\n// This is the default per thread test part result reporter used in\r\n// UnitTestImpl. This class should only be used by UnitTestImpl.\r\nclass DefaultPerThreadTestPartResultReporter\r\n  : public TestPartResultReporterInterface {\r\n public:\r\n  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);\r\n  // Implements the TestPartResultReporterInterface. The implementation just\r\n  // delegates to the current global test part result reporter of *unit_test_.\r\n  virtual void ReportTestPartResult(const TestPartResult& result);\r\n\r\n private:\r\n  UnitTestImpl* const unit_test_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);\r\n};\r\n\r\n// The private implementation of the UnitTest class.  We don't protect\r\n// the methods under a mutex, as this class is not accessible by a\r\n// user and the UnitTest class that delegates work to this class does\r\n// proper locking.\r\nclass GTEST_API_ UnitTestImpl {\r\n public:\r\n  explicit UnitTestImpl(UnitTest* parent);\r\n  virtual ~UnitTestImpl();\r\n\r\n  // There are two different ways to register your own TestPartResultReporter.\r\n  // You can register your own repoter to listen either only for test results\r\n  // from the current thread or for results from all threads.\r\n  // By default, each per-thread test result repoter just passes a new\r\n  // TestPartResult to the global test result reporter, which registers the\r\n  // test part result for the currently running test.\r\n\r\n  // Returns the global test part result reporter.\r\n  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();\r\n\r\n  // Sets the global test part result reporter.\r\n  void SetGlobalTestPartResultReporter(\r\n    TestPartResultReporterInterface* reporter);\r\n\r\n  // Returns the test part result reporter for the current thread.\r\n  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();\r\n\r\n  // Sets the test part result reporter for the current thread.\r\n  void SetTestPartResultReporterForCurrentThread(\r\n    TestPartResultReporterInterface* reporter);\r\n\r\n  // Gets the number of successful test cases.\r\n  int successful_test_case_count() const;\r\n\r\n  // Gets the number of failed test cases.\r\n  int failed_test_case_count() const;\r\n\r\n  // Gets the number of all test cases.\r\n  int total_test_case_count() const;\r\n\r\n  // Gets the number of all test cases that contain at least one test\r\n  // that should run.\r\n  int test_case_to_run_count() const;\r\n\r\n  // Gets the number of successful tests.\r\n  int successful_test_count() const;\r\n\r\n  // Gets the number of failed tests.\r\n  int failed_test_count() const;\r\n\r\n  // Gets the number of disabled tests that will be reported in the XML report.\r\n  int reportable_disabled_test_count() const;\r\n\r\n  // Gets the number of disabled tests.\r\n  int disabled_test_count() const;\r\n\r\n  // Gets the number of tests to be printed in the XML report.\r\n  int reportable_test_count() const;\r\n\r\n  // Gets the number of all tests.\r\n  int total_test_count() const;\r\n\r\n  // Gets the number of tests that should run.\r\n  int test_to_run_count() const;\r\n\r\n  // Gets the time of the test program start, in ms from the start of the\r\n  // UNIX epoch.\r\n  TimeInMillis start_timestamp() const {\r\n    return start_timestamp_;\r\n  }\r\n\r\n  // Gets the elapsed time, in milliseconds.\r\n  TimeInMillis elapsed_time() const {\r\n    return elapsed_time_;\r\n  }\r\n\r\n  // Returns true iff the unit test passed (i.e. all test cases passed).\r\n  bool Passed() const {\r\n    return !Failed();\r\n  }\r\n\r\n  // Returns true iff the unit test failed (i.e. some test case failed\r\n  // or something outside of all tests failed).\r\n  bool Failed() const {\r\n    return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();\r\n  }\r\n\r\n  // Gets the i-th test case among all the test cases. i can range from 0 to\r\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\r\n  const TestCase* GetTestCase(int i) const {\r\n    const int index = GetElementOr(test_case_indices_, i, -1);\r\n    return index < 0 ? NULL : test_cases_[i];\r\n  }\r\n\r\n  // Gets the i-th test case among all the test cases. i can range from 0 to\r\n  // total_test_case_count() - 1. If i is not in that range, returns NULL.\r\n  TestCase* GetMutableTestCase(int i) {\r\n    const int index = GetElementOr(test_case_indices_, i, -1);\r\n    return index < 0 ? NULL : test_cases_[index];\r\n  }\r\n\r\n  // Provides access to the event listener list.\r\n  TestEventListeners* listeners() {\r\n    return &listeners_;\r\n  }\r\n\r\n  // Returns the TestResult for the test that's currently running, or\r\n  // the TestResult for the ad hoc test if no test is running.\r\n  TestResult* current_test_result();\r\n\r\n  // Returns the TestResult for the ad hoc test.\r\n  const TestResult* ad_hoc_test_result() const {\r\n    return &ad_hoc_test_result_;\r\n  }\r\n\r\n  // Sets the OS stack trace getter.\r\n  //\r\n  // Does nothing if the input and the current OS stack trace getter\r\n  // are the same; otherwise, deletes the old getter and makes the\r\n  // input the current getter.\r\n  void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter);\r\n\r\n  // Returns the current OS stack trace getter if it is not NULL;\r\n  // otherwise, creates an OsStackTraceGetter, makes it the current\r\n  // getter, and returns it.\r\n  OsStackTraceGetterInterface* os_stack_trace_getter();\r\n\r\n  // Returns the current OS stack trace as an std::string.\r\n  //\r\n  // The maximum number of stack frames to be included is specified by\r\n  // the gtest_stack_trace_depth flag.  The skip_count parameter\r\n  // specifies the number of top frames to be skipped, which doesn't\r\n  // count against the number of frames to be included.\r\n  //\r\n  // For example, if Foo() calls Bar(), which in turn calls\r\n  // CurrentOsStackTraceExceptTop(1), Foo() will be included in the\r\n  // trace but Bar() and CurrentOsStackTraceExceptTop() won't.\r\n  std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;\r\n\r\n  // Finds and returns a TestCase with the given name.  If one doesn't\r\n  // exist, creates one and returns it.\r\n  //\r\n  // Arguments:\r\n  //\r\n  //   test_case_name: name of the test case\r\n  //   type_param:     the name of the test's type parameter, or NULL if\r\n  //                   this is not a typed or a type-parameterized test.\r\n  //   set_up_tc:      pointer to the function that sets up the test case\r\n  //   tear_down_tc:   pointer to the function that tears down the test case\r\n  TestCase* GetTestCase(const char* test_case_name,\r\n                        const char* type_param,\r\n                        Test::SetUpTestCaseFunc set_up_tc,\r\n                        Test::TearDownTestCaseFunc tear_down_tc);\r\n\r\n  // Adds a TestInfo to the unit test.\r\n  //\r\n  // Arguments:\r\n  //\r\n  //   set_up_tc:    pointer to the function that sets up the test case\r\n  //   tear_down_tc: pointer to the function that tears down the test case\r\n  //   test_info:    the TestInfo object\r\n  void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,\r\n                   Test::TearDownTestCaseFunc tear_down_tc,\r\n                   TestInfo* test_info) {\r\n    // In order to support thread-safe death tests, we need to\r\n    // remember the original working directory when the test program\r\n    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as\r\n    // the user may have changed the current directory before calling\r\n    // RUN_ALL_TESTS().  Therefore we capture the current directory in\r\n    // AddTestInfo(), which is called to register a TEST or TEST_F\r\n    // before main() is reached.\r\n    if (original_working_dir_.IsEmpty()) {\r\n      original_working_dir_.Set(FilePath::GetCurrentDir());\r\n      GTEST_CHECK_(!original_working_dir_.IsEmpty())\r\n          << \"Failed to get the current working directory.\";\r\n    }\r\n\r\n    GetTestCase(test_info->test_case_name(),\r\n                test_info->type_param(),\r\n                set_up_tc,\r\n                tear_down_tc)->AddTestInfo(test_info);\r\n  }\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n  // Returns ParameterizedTestCaseRegistry object used to keep track of\r\n  // value-parameterized tests and instantiate and register them.\r\n  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {\r\n    return parameterized_test_registry_;\r\n  }\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n  // Sets the TestCase object for the test that's currently running.\r\n  void set_current_test_case(TestCase* a_current_test_case) {\r\n    current_test_case_ = a_current_test_case;\r\n  }\r\n\r\n  // Sets the TestInfo object for the test that's currently running.  If\r\n  // current_test_info is NULL, the assertion results will be stored in\r\n  // ad_hoc_test_result_.\r\n  void set_current_test_info(TestInfo* a_current_test_info) {\r\n    current_test_info_ = a_current_test_info;\r\n  }\r\n\r\n  // Registers all parameterized tests defined using TEST_P and\r\n  // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter\r\n  // combination. This method can be called more then once; it has guards\r\n  // protecting from registering the tests more then once.  If\r\n  // value-parameterized tests are disabled, RegisterParameterizedTests is\r\n  // present but does nothing.\r\n  void RegisterParameterizedTests();\r\n\r\n  // Runs all tests in this UnitTest object, prints the result, and\r\n  // returns true if all tests are successful.  If any exception is\r\n  // thrown during a test, this test is considered to be failed, but\r\n  // the rest of the tests will still be run.\r\n  bool RunAllTests();\r\n\r\n  // Clears the results of all tests, except the ad hoc tests.\r\n  void ClearNonAdHocTestResult() {\r\n    ForEach(test_cases_, TestCase::ClearTestCaseResult);\r\n  }\r\n\r\n  // Clears the results of ad-hoc test assertions.\r\n  void ClearAdHocTestResult() {\r\n    ad_hoc_test_result_.Clear();\r\n  }\r\n\r\n  // Adds a TestProperty to the current TestResult object when invoked in a\r\n  // context of a test or a test case, or to the global property set. If the\r\n  // result already contains a property with the same key, the value will be\r\n  // updated.\r\n  void RecordProperty(const TestProperty& test_property);\r\n\r\n  enum ReactionToSharding {\r\n    HONOR_SHARDING_PROTOCOL,\r\n    IGNORE_SHARDING_PROTOCOL\r\n  };\r\n\r\n  // Matches the full name of each test against the user-specified\r\n  // filter to decide whether the test should run, then records the\r\n  // result in each TestCase and TestInfo object.\r\n  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests\r\n  // based on sharding variables in the environment.\r\n  // Returns the number of tests that should run.\r\n  int FilterTests(ReactionToSharding shard_tests);\r\n\r\n  // Prints the names of the tests matching the user-specified filter flag.\r\n  void ListTestsMatchingFilter();\r\n\r\n  const TestCase* current_test_case() const {\r\n    return current_test_case_;\r\n  }\r\n  TestInfo* current_test_info() {\r\n    return current_test_info_;\r\n  }\r\n  const TestInfo* current_test_info() const {\r\n    return current_test_info_;\r\n  }\r\n\r\n  // Returns the vector of environments that need to be set-up/torn-down\r\n  // before/after the tests are run.\r\n  std::vector<Environment*>& environments() {\r\n    return environments_;\r\n  }\r\n\r\n  // Getters for the per-thread Google Test trace stack.\r\n  std::vector<TraceInfo>& gtest_trace_stack() {\r\n    return *(gtest_trace_stack_.pointer());\r\n  }\r\n  const std::vector<TraceInfo>& gtest_trace_stack() const {\r\n    return gtest_trace_stack_.get();\r\n  }\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n  void InitDeathTestSubprocessControlInfo() {\r\n    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());\r\n  }\r\n  // Returns a pointer to the parsed --gtest_internal_run_death_test\r\n  // flag, or NULL if that flag was not specified.\r\n  // This information is useful only in a death test child process.\r\n  // Must not be called before a call to InitGoogleTest.\r\n  const InternalRunDeathTestFlag* internal_run_death_test_flag() const {\r\n    return internal_run_death_test_flag_.get();\r\n  }\r\n\r\n  // Returns a pointer to the current death test factory.\r\n  internal::DeathTestFactory* death_test_factory() {\r\n    return death_test_factory_.get();\r\n  }\r\n\r\n  void SuppressTestEventsIfInSubprocess();\r\n\r\n  friend class ReplaceDeathTestFactory;\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n  // Initializes the event listener performing XML output as specified by\r\n  // UnitTestOptions. Must not be called before InitGoogleTest.\r\n  void ConfigureXmlOutput();\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n  // Initializes the event listener for streaming test results to a socket.\r\n  // Must not be called before InitGoogleTest.\r\n  void ConfigureStreamingOutput();\r\n#endif\r\n\r\n  // Performs initialization dependent upon flag values obtained in\r\n  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\r\n  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\r\n  // this function is also called from RunAllTests.  Since this function can be\r\n  // called more than once, it has to be idempotent.\r\n  void PostFlagParsingInit();\r\n\r\n  // Gets the random seed used at the start of the current test iteration.\r\n  int random_seed() const {\r\n    return random_seed_;\r\n  }\r\n\r\n  // Gets the random number generator.\r\n  internal::Random* random() {\r\n    return &random_;\r\n  }\r\n\r\n  // Shuffles all test cases, and the tests within each test case,\r\n  // making sure that death tests are still run first.\r\n  void ShuffleTests();\r\n\r\n  // Restores the test cases and tests to their order before the first shuffle.\r\n  void UnshuffleTests();\r\n\r\n  // Returns the value of GTEST_FLAG(catch_exceptions) at the moment\r\n  // UnitTest::Run() starts.\r\n  bool catch_exceptions() const {\r\n    return catch_exceptions_;\r\n  }\r\n\r\n private:\r\n  friend class ::testing::UnitTest;\r\n\r\n  // Used by UnitTest::Run() to capture the state of\r\n  // GTEST_FLAG(catch_exceptions) at the moment it starts.\r\n  void set_catch_exceptions(bool value) {\r\n    catch_exceptions_ = value;\r\n  }\r\n\r\n  // The UnitTest object that owns this implementation object.\r\n  UnitTest* const parent_;\r\n\r\n  // The working directory when the first TEST() or TEST_F() was\r\n  // executed.\r\n  internal::FilePath original_working_dir_;\r\n\r\n  // The default test part result reporters.\r\n  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;\r\n  DefaultPerThreadTestPartResultReporter\r\n  default_per_thread_test_part_result_reporter_;\r\n\r\n  // Points to (but doesn't own) the global test part result reporter.\r\n  TestPartResultReporterInterface* global_test_part_result_repoter_;\r\n\r\n  // Protects read and write access to global_test_part_result_reporter_.\r\n  internal::Mutex global_test_part_result_reporter_mutex_;\r\n\r\n  // Points to (but doesn't own) the per-thread test part result reporter.\r\n  internal::ThreadLocal<TestPartResultReporterInterface*>\r\n  per_thread_test_part_result_reporter_;\r\n\r\n  // The vector of environments that need to be set-up/torn-down\r\n  // before/after the tests are run.\r\n  std::vector<Environment*> environments_;\r\n\r\n  // The vector of TestCases in their original order.  It owns the\r\n  // elements in the vector.\r\n  std::vector<TestCase*> test_cases_;\r\n\r\n  // Provides a level of indirection for the test case list to allow\r\n  // easy shuffling and restoring the test case order.  The i-th\r\n  // element of this vector is the index of the i-th test case in the\r\n  // shuffled order.\r\n  std::vector<int> test_case_indices_;\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n  // ParameterizedTestRegistry object used to register value-parameterized\r\n  // tests.\r\n  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;\r\n\r\n  // Indicates whether RegisterParameterizedTests() has been called already.\r\n  bool parameterized_tests_registered_;\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n  // Index of the last death test case registered.  Initially -1.\r\n  int last_death_test_case_;\r\n\r\n  // This points to the TestCase for the currently running test.  It\r\n  // changes as Google Test goes through one test case after another.\r\n  // When no test is running, this is set to NULL and Google Test\r\n  // stores assertion results in ad_hoc_test_result_.  Initially NULL.\r\n  TestCase* current_test_case_;\r\n\r\n  // This points to the TestInfo for the currently running test.  It\r\n  // changes as Google Test goes through one test after another.  When\r\n  // no test is running, this is set to NULL and Google Test stores\r\n  // assertion results in ad_hoc_test_result_.  Initially NULL.\r\n  TestInfo* current_test_info_;\r\n\r\n  // Normally, a user only writes assertions inside a TEST or TEST_F,\r\n  // or inside a function called by a TEST or TEST_F.  Since Google\r\n  // Test keeps track of which test is current running, it can\r\n  // associate such an assertion with the test it belongs to.\r\n  //\r\n  // If an assertion is encountered when no TEST or TEST_F is running,\r\n  // Google Test attributes the assertion result to an imaginary \"ad hoc\"\r\n  // test, and records the result in ad_hoc_test_result_.\r\n  TestResult ad_hoc_test_result_;\r\n\r\n  // The list of event listeners that can be used to track events inside\r\n  // Google Test.\r\n  TestEventListeners listeners_;\r\n\r\n  // The OS stack trace getter.  Will be deleted when the UnitTest\r\n  // object is destructed.  By default, an OsStackTraceGetter is used,\r\n  // but the user can set this field to use a custom getter if that is\r\n  // desired.\r\n  OsStackTraceGetterInterface* os_stack_trace_getter_;\r\n\r\n  // True iff PostFlagParsingInit() has been called.\r\n  bool post_flag_parse_init_performed_;\r\n\r\n  // The random number seed used at the beginning of the test run.\r\n  int random_seed_;\r\n\r\n  // Our random number generator.\r\n  internal::Random random_;\r\n\r\n  // The time of the test program start, in ms from the start of the\r\n  // UNIX epoch.\r\n  TimeInMillis start_timestamp_;\r\n\r\n  // How long the test took to run, in milliseconds.\r\n  TimeInMillis elapsed_time_;\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n  // The decomposed components of the gtest_internal_run_death_test flag,\r\n  // parsed when RUN_ALL_TESTS is called.\r\n  internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;\r\n  internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n  // A per-thread stack of traces created by the SCOPED_TRACE() macro.\r\n  internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_;\r\n\r\n  // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests()\r\n  // starts.\r\n  bool catch_exceptions_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);\r\n};  // class UnitTestImpl\r\n\r\n// Convenience function for accessing the global UnitTest\r\n// implementation object.\r\ninline UnitTestImpl* GetUnitTestImpl() {\r\n  return UnitTest::GetInstance()->impl();\r\n}\r\n\r\n#if GTEST_USES_SIMPLE_RE\r\n\r\n// Internal helper functions for implementing the simple regular\r\n// expression matcher.\r\nGTEST_API_ bool IsInSet(char ch, const char* str);\r\nGTEST_API_ bool IsAsciiDigit(char ch);\r\nGTEST_API_ bool IsAsciiPunct(char ch);\r\nGTEST_API_ bool IsRepeat(char ch);\r\nGTEST_API_ bool IsAsciiWhiteSpace(char ch);\r\nGTEST_API_ bool IsAsciiWordChar(char ch);\r\nGTEST_API_ bool IsValidEscape(char ch);\r\nGTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);\r\nGTEST_API_ bool ValidateRegex(const char* regex);\r\nGTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);\r\nGTEST_API_ bool MatchRepetitionAndRegexAtHead(\r\n  bool escaped, char ch, char repeat, const char* regex, const char* str);\r\nGTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);\r\n\r\n#endif  // GTEST_USES_SIMPLE_RE\r\n\r\n// Parses the command line for Google Test flags, without initializing\r\n// other parts of Google Test.\r\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);\r\nGTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\n// Returns the message describing the last system error, regardless of the\r\n// platform.\r\nGTEST_API_ std::string GetLastErrnoDescription();\r\n\r\n# if GTEST_OS_WINDOWS\r\n// Provides leak-safe Windows kernel handle ownership.\r\nclass AutoHandle {\r\n public:\r\n  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}\r\n  explicit AutoHandle(HANDLE handle) : handle_(handle) {}\r\n\r\n  ~AutoHandle() {\r\n    Reset();\r\n  }\r\n\r\n  HANDLE Get() const {\r\n    return handle_;\r\n  }\r\n  void Reset() {\r\n    Reset(INVALID_HANDLE_VALUE);\r\n  }\r\n  void Reset(HANDLE handle) {\r\n    if (handle != handle_) {\r\n      if (handle_ != INVALID_HANDLE_VALUE) {\r\n        ::CloseHandle(handle_);\r\n      }\r\n\r\n      handle_ = handle;\r\n    }\r\n  }\r\n\r\n private:\r\n  HANDLE handle_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);\r\n};\r\n# endif  // GTEST_OS_WINDOWS\r\n\r\n// Attempts to parse a string into a positive integer pointed to by the\r\n// number parameter.  Returns true if that is possible.\r\n// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use\r\n// it here.\r\ntemplate <typename Integer>\r\nbool ParseNaturalNumber(const ::std::string& str, Integer* number) {\r\n  // Fail fast if the given string does not begin with a digit;\r\n  // this bypasses strtoXXX's \"optional leading whitespace and plus\r\n  // or minus sign\" semantics, which are undesirable here.\r\n  if (str.empty() || !IsDigit(str[0])) {\r\n    return false;\r\n  }\r\n\r\n  errno = 0;\r\n\r\n  char* end;\r\n  // BiggestConvertible is the largest integer type that system-provided\r\n  // string-to-number conversion routines can return.\r\n\r\n# if GTEST_OS_WINDOWS && !defined(__GNUC__)\r\n\r\n  // MSVC and C++ Builder define __int64 instead of the standard long long.\r\n  typedef unsigned __int64 BiggestConvertible;\r\n  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);\r\n\r\n# else\r\n\r\n  typedef unsigned long long BiggestConvertible;  // NOLINT\r\n  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);\r\n\r\n# endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)\r\n\r\n  const bool parse_success = *end == '\\0' && errno == 0;\r\n\r\n  // TODO(vladl@google.com): Convert this to compile time assertion when it is\r\n  // available.\r\n  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));\r\n\r\n  const Integer result = static_cast<Integer>(parsed);\r\n\r\n  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {\r\n    *number = result;\r\n    return true;\r\n  }\r\n\r\n  return false;\r\n}\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n// TestResult contains some private methods that should be hidden from\r\n// Google Test user but are required for testing. This class allow our tests\r\n// to access them.\r\n//\r\n// This class is supplied only for the purpose of testing Google Test's own\r\n// constructs. Do not use it in user tests, either directly or indirectly.\r\nclass TestResultAccessor {\r\n public:\r\n  static void RecordProperty(TestResult* test_result,\r\n                             const std::string& xml_element,\r\n                             const TestProperty& property) {\r\n    test_result->RecordProperty(xml_element, property);\r\n  }\r\n\r\n  static void ClearTestPartResults(TestResult* test_result) {\r\n    test_result->ClearTestPartResults();\r\n  }\r\n\r\n  static const std::vector<testing::TestPartResult>& test_part_results(\r\n    const TestResult& test_result) {\r\n    return test_result.test_part_results();\r\n  }\r\n};\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n\r\n// Streams test results to the given port on the given host machine.\r\nclass StreamingListener : public EmptyTestEventListener {\r\n public:\r\n  // Abstract base class for writing strings to a socket.\r\n  class AbstractSocketWriter {\r\n   public:\r\n    virtual ~AbstractSocketWriter() {}\r\n\r\n    // Sends a string to the socket.\r\n    virtual void Send(const string& message) = 0;\r\n\r\n    // Closes the socket.\r\n    virtual void CloseConnection() {}\r\n\r\n    // Sends a string and a newline to the socket.\r\n    void SendLn(const string& message) {\r\n      Send(message + \"\\n\");\r\n    }\r\n  };\r\n\r\n  // Concrete class for actually writing strings to a socket.\r\n  class SocketWriter : public AbstractSocketWriter {\r\n   public:\r\n    SocketWriter(const string& host, const string& port)\r\n      : sockfd_(-1), host_name_(host), port_num_(port) {\r\n      MakeConnection();\r\n    }\r\n\r\n    virtual ~SocketWriter() {\r\n      if (sockfd_ != -1) {\r\n        CloseConnection();\r\n      }\r\n    }\r\n\r\n    // Sends a string to the socket.\r\n    virtual void Send(const string& message) {\r\n      GTEST_CHECK_(sockfd_ != -1)\r\n          << \"Send() can be called only when there is a connection.\";\r\n\r\n      const int len = static_cast<int>(message.length());\r\n\r\n      if (write(sockfd_, message.c_str(), len) != len) {\r\n        GTEST_LOG_(WARNING)\r\n            << \"stream_result_to: failed to stream to \"\r\n            << host_name_ << \":\" << port_num_;\r\n      }\r\n    }\r\n\r\n   private:\r\n    // Creates a client socket and connects to the server.\r\n    void MakeConnection();\r\n\r\n    // Closes the socket.\r\n    void CloseConnection() {\r\n      GTEST_CHECK_(sockfd_ != -1)\r\n          << \"CloseConnection() can be called only when there is a connection.\";\r\n\r\n      close(sockfd_);\r\n      sockfd_ = -1;\r\n    }\r\n\r\n    int sockfd_;  // socket file descriptor\r\n    const string host_name_;\r\n    const string port_num_;\r\n\r\n    GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);\r\n  };  // class SocketWriter\r\n\r\n  // Escapes '=', '&', '%', and '\\n' characters in str as \"%xx\".\r\n  static string UrlEncode(const char* str);\r\n\r\n  StreamingListener(const string& host, const string& port)\r\n    : socket_writer_(new SocketWriter(host, port)) {\r\n    Start();\r\n  }\r\n\r\n  explicit StreamingListener(AbstractSocketWriter* socket_writer)\r\n    : socket_writer_(socket_writer) {\r\n    Start();\r\n  }\r\n\r\n  void OnTestProgramStart(const UnitTest& /* unit_test */) {\r\n    SendLn(\"event=TestProgramStart\");\r\n  }\r\n\r\n  void OnTestProgramEnd(const UnitTest& unit_test) {\r\n    // Note that Google Test current only report elapsed time for each\r\n    // test iteration, not for the entire test program.\r\n    SendLn(\"event=TestProgramEnd&passed=\" + FormatBool(unit_test.Passed()));\r\n\r\n    // Notify the streaming server to stop.\r\n    socket_writer_->CloseConnection();\r\n  }\r\n\r\n  void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {\r\n    SendLn(\"event=TestIterationStart&iteration=\" +\r\n           StreamableToString(iteration));\r\n  }\r\n\r\n  void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {\r\n    SendLn(\"event=TestIterationEnd&passed=\" +\r\n           FormatBool(unit_test.Passed()) + \"&elapsed_time=\" +\r\n           StreamableToString(unit_test.elapsed_time()) + \"ms\");\r\n  }\r\n\r\n  void OnTestCaseStart(const TestCase& test_case) {\r\n    SendLn(std::string(\"event=TestCaseStart&name=\") + test_case.name());\r\n  }\r\n\r\n  void OnTestCaseEnd(const TestCase& test_case) {\r\n    SendLn(\"event=TestCaseEnd&passed=\" + FormatBool(test_case.Passed())\r\n           + \"&elapsed_time=\" + StreamableToString(test_case.elapsed_time())\r\n           + \"ms\");\r\n  }\r\n\r\n  void OnTestStart(const TestInfo& test_info) {\r\n    SendLn(std::string(\"event=TestStart&name=\") + test_info.name());\r\n  }\r\n\r\n  void OnTestEnd(const TestInfo& test_info) {\r\n    SendLn(\"event=TestEnd&passed=\" +\r\n           FormatBool((test_info.result())->Passed()) +\r\n           \"&elapsed_time=\" +\r\n           StreamableToString((test_info.result())->elapsed_time()) + \"ms\");\r\n  }\r\n\r\n  void OnTestPartResult(const TestPartResult& test_part_result) {\r\n    const char* file_name = test_part_result.file_name();\r\n\r\n    if (file_name == NULL) {\r\n      file_name = \"\";\r\n    }\r\n\r\n    SendLn(\"event=TestPartResult&file=\" + UrlEncode(file_name) +\r\n           \"&line=\" + StreamableToString(test_part_result.line_number()) +\r\n           \"&message=\" + UrlEncode(test_part_result.message()));\r\n  }\r\n\r\n private:\r\n  // Sends the given message and a newline to the socket.\r\n  void SendLn(const string& message) {\r\n    socket_writer_->SendLn(message);\r\n  }\r\n\r\n  // Called at the start of streaming to notify the receiver what\r\n  // protocol we are using.\r\n  void Start() {\r\n    SendLn(\"gtest_streaming_protocol_version=1.0\");\r\n  }\r\n\r\n  string FormatBool(bool value) {\r\n    return value ? \"1\" : \"0\";\r\n  }\r\n\r\n  const scoped_ptr<AbstractSocketWriter> socket_writer_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);\r\n};  // class StreamingListener\r\n\r\n#endif  // GTEST_CAN_STREAM_RESULTS_\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n\r\n#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-port.cpp",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\n#include <limits.h>\r\n#include <stdlib.h>\r\n#include <stdio.h>\r\n#include <string.h>\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n# include <windows.h>  // For TerminateProcess()\r\n#elif GTEST_OS_WINDOWS\r\n# include <io.h>\r\n# include <sys/stat.h>\r\n#else\r\n# include <unistd.h>\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n#if GTEST_OS_MAC\r\n# include <mach/mach_init.h>\r\n# include <mach/task.h>\r\n# include <mach/vm_map.h>\r\n#endif  // GTEST_OS_MAC\r\n\r\n#if GTEST_OS_QNX\r\n# include <devctl.h>\r\n# include <sys/procfs.h>\r\n#endif  // GTEST_OS_QNX\r\n\r\n#include \"gtest/gtest-spi.h\"\r\n#include \"gtest/gtest-message.h\"\r\n#include \"gtest/internal/gtest-internal.h\"\r\n#include \"gtest/internal/gtest-string.h\"\r\n\r\n// Indicates that this translation unit is part of Google Test's\r\n// implementation.  It must come before gtest-internal-inl.h is\r\n// included, or there will be a compiler error.  This trick is to\r\n// prevent a user from accidentally including gtest-internal-inl.h in\r\n// his code.\r\n#define GTEST_IMPLEMENTATION_ 1\r\n#include \"src/gtest-internal-inl.h\"\r\n#undef GTEST_IMPLEMENTATION_\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n#if defined(_MSC_VER) || defined(__BORLANDC__)\r\n// MSVC and C++Builder do not provide a definition of STDERR_FILENO.\r\nconst int kStdOutFileno = 1;\r\nconst int kStdErrFileno = 2;\r\n#else\r\nconst int kStdOutFileno = STDOUT_FILENO;\r\nconst int kStdErrFileno = STDERR_FILENO;\r\n#endif  // _MSC_VER\r\n\r\n#if GTEST_OS_MAC\r\n\r\n// Returns the number of threads running in the process, or 0 to indicate that\r\n// we cannot detect it.\r\nsize_t GetThreadCount() {\r\n  const task_t task = mach_task_self();\r\n  mach_msg_type_number_t thread_count;\r\n  thread_act_array_t thread_list;\r\n  const kern_return_t status = task_threads(task, &thread_list, &thread_count);\r\n\r\n  if (status == KERN_SUCCESS) {\r\n    // task_threads allocates resources in thread_list and we need to free them\r\n    // to avoid leaks.\r\n    vm_deallocate(task,\r\n                  reinterpret_cast<vm_address_t>(thread_list),\r\n                  sizeof(thread_t) * thread_count);\r\n    return static_cast<size_t>(thread_count);\r\n  }\r\n  else {\r\n    return 0;\r\n  }\r\n}\r\n\r\n#elif GTEST_OS_QNX\r\n\r\n// Returns the number of threads running in the process, or 0 to indicate that\r\n// we cannot detect it.\r\nsize_t GetThreadCount() {\r\n  const int fd = open(\"/proc/self/as\", O_RDONLY);\r\n\r\n  if (fd < 0) {\r\n    return 0;\r\n  }\r\n\r\n  procfs_info process_info;\r\n  const int status =\r\n    devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);\r\n  close(fd);\r\n\r\n  if (status == EOK) {\r\n    return static_cast<size_t>(process_info.num_threads);\r\n  }\r\n  else {\r\n    return 0;\r\n  }\r\n}\r\n\r\n#else\r\n\r\nsize_t GetThreadCount() {\r\n  // There's no portable way to detect the number of threads, so we just\r\n  // return 0 to indicate that we cannot detect it.\r\n  return 0;\r\n}\r\n\r\n#endif  // GTEST_OS_MAC\r\n\r\n#if GTEST_USES_POSIX_RE\r\n\r\n// Implements RE.  Currently only needed for death tests.\r\n\r\nRE::~RE() {\r\n  if (is_valid_) {\r\n    // regfree'ing an invalid regex might crash because the content\r\n    // of the regex is undefined. Since the regex's are essentially\r\n    // the same, one cannot be valid (or invalid) without the other\r\n    // being so too.\r\n    regfree(&partial_regex_);\r\n    regfree(&full_regex_);\r\n  }\r\n\r\n  free(const_cast<char*>(pattern_));\r\n}\r\n\r\n// Returns true iff regular expression re matches the entire str.\r\nbool RE::FullMatch(const char* str, const RE& re) {\r\n  if (!re.is_valid_) {\r\n    return false;\r\n  }\r\n\r\n  regmatch_t match;\r\n  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;\r\n}\r\n\r\n// Returns true iff regular expression re matches a substring of str\r\n// (including str itself).\r\nbool RE::PartialMatch(const char* str, const RE& re) {\r\n  if (!re.is_valid_) {\r\n    return false;\r\n  }\r\n\r\n  regmatch_t match;\r\n  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;\r\n}\r\n\r\n// Initializes an RE from its string representation.\r\nvoid RE::Init(const char* regex) {\r\n  pattern_ = posix::StrDup(regex);\r\n\r\n  // Reserves enough bytes to hold the regular expression used for a\r\n  // full match.\r\n  const size_t full_regex_len = strlen(regex) + 10;\r\n  char* const full_pattern = new char[full_regex_len];\r\n\r\n  snprintf(full_pattern, full_regex_len, \"^(%s)$\", regex);\r\n  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;\r\n\r\n  // We want to call regcomp(&partial_regex_, ...) even if the\r\n  // previous expression returns false.  Otherwise partial_regex_ may\r\n  // not be properly initialized can may cause trouble when it's\r\n  // freed.\r\n  //\r\n  // Some implementation of POSIX regex (e.g. on at least some\r\n  // versions of Cygwin) doesn't accept the empty string as a valid\r\n  // regex.  We change it to an equivalent form \"()\" to be safe.\r\n  if (is_valid_) {\r\n    const char* const partial_regex = (*regex == '\\0') ? \"()\" : regex;\r\n    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;\r\n  }\r\n\r\n  EXPECT_TRUE(is_valid_)\r\n      << \"Regular expression \\\"\" << regex\r\n      << \"\\\" is not a valid POSIX Extended regular expression.\";\r\n\r\n  delete[] full_pattern;\r\n}\r\n\r\n#elif GTEST_USES_SIMPLE_RE\r\n\r\n// Returns true iff ch appears anywhere in str (excluding the\r\n// terminating '\\0' character).\r\nbool IsInSet(char ch, const char* str) {\r\n  return ch != '\\0' && strchr(str, ch) != NULL;\r\n}\r\n\r\n// Returns true iff ch belongs to the given classification.  Unlike\r\n// similar functions in <ctype.h>, these aren't affected by the\r\n// current locale.\r\nbool IsAsciiDigit(char ch) {\r\n  return '0' <= ch && ch <= '9';\r\n}\r\nbool IsAsciiPunct(char ch) {\r\n  return IsInSet(ch, \"^-!\\\"#$%&'()*+,./:;<=>?@[\\\\]_`{|}~\");\r\n}\r\nbool IsRepeat(char ch) {\r\n  return IsInSet(ch, \"?*+\");\r\n}\r\nbool IsAsciiWhiteSpace(char ch) {\r\n  return IsInSet(ch, \" \\f\\n\\r\\t\\v\");\r\n}\r\nbool IsAsciiWordChar(char ch) {\r\n  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||\r\n         ('0' <= ch && ch <= '9') || ch == '_';\r\n}\r\n\r\n// Returns true iff \"\\\\c\" is a supported escape sequence.\r\nbool IsValidEscape(char c) {\r\n  return (IsAsciiPunct(c) || IsInSet(c, \"dDfnrsStvwW\"));\r\n}\r\n\r\n// Returns true iff the given atom (specified by escaped and pattern)\r\n// matches ch.  The result is undefined if the atom is invalid.\r\nbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {\r\n  if (escaped) {  // \"\\\\p\" where p is pattern_char.\r\n    switch (pattern_char) {\r\n      case 'd':\r\n        return IsAsciiDigit(ch);\r\n\r\n      case 'D':\r\n        return !IsAsciiDigit(ch);\r\n\r\n      case 'f':\r\n        return ch == '\\f';\r\n\r\n      case 'n':\r\n        return ch == '\\n';\r\n\r\n      case 'r':\r\n        return ch == '\\r';\r\n\r\n      case 's':\r\n        return IsAsciiWhiteSpace(ch);\r\n\r\n      case 'S':\r\n        return !IsAsciiWhiteSpace(ch);\r\n\r\n      case 't':\r\n        return ch == '\\t';\r\n\r\n      case 'v':\r\n        return ch == '\\v';\r\n\r\n      case 'w':\r\n        return IsAsciiWordChar(ch);\r\n\r\n      case 'W':\r\n        return !IsAsciiWordChar(ch);\r\n    }\r\n\r\n    return IsAsciiPunct(pattern_char) && pattern_char == ch;\r\n  }\r\n\r\n  return (pattern_char == '.' && ch != '\\n') || pattern_char == ch;\r\n}\r\n\r\n// Helper function used by ValidateRegex() to format error messages.\r\nstd::string FormatRegexSyntaxError(const char* regex, int index) {\r\n  return (Message() << \"Syntax error at index \" << index\r\n          << \" in simple regular expression \\\"\" << regex << \"\\\": \").GetString();\r\n}\r\n\r\n// Generates non-fatal failures and returns false if regex is invalid;\r\n// otherwise returns true.\r\nbool ValidateRegex(const char* regex) {\r\n  if (regex == NULL) {\r\n    // TODO(wan@google.com): fix the source file location in the\r\n    // assertion failures to match where the regex is used in user\r\n    // code.\r\n    ADD_FAILURE() << \"NULL is not a valid simple regular expression.\";\r\n    return false;\r\n  }\r\n\r\n  bool is_valid = true;\r\n\r\n  // True iff ?, *, or + can follow the previous atom.\r\n  bool prev_repeatable = false;\r\n\r\n  for (int i = 0; regex[i]; i++) {\r\n    if (regex[i] == '\\\\') {  // An escape sequence\r\n      i++;\r\n\r\n      if (regex[i] == '\\0') {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\r\n                      << \"'\\\\' cannot appear at the end.\";\r\n        return false;\r\n      }\r\n\r\n      if (!IsValidEscape(regex[i])) {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)\r\n                      << \"invalid escape sequence \\\"\\\\\" << regex[i] << \"\\\".\";\r\n        is_valid = false;\r\n      }\r\n\r\n      prev_repeatable = true;\r\n    }\r\n    else {    // Not an escape sequence.\r\n      const char ch = regex[i];\r\n\r\n      if (ch == '^' && i > 0) {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\r\n                      << \"'^' can only appear at the beginning.\";\r\n        is_valid = false;\r\n      }\r\n      else if (ch == '$' && regex[i + 1] != '\\0') {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\r\n                      << \"'$' can only appear at the end.\";\r\n        is_valid = false;\r\n      }\r\n      else if (IsInSet(ch, \"()[]{}|\")) {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\r\n                      << \"'\" << ch << \"' is unsupported.\";\r\n        is_valid = false;\r\n      }\r\n      else if (IsRepeat(ch) && !prev_repeatable) {\r\n        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)\r\n                      << \"'\" << ch << \"' can only follow a repeatable token.\";\r\n        is_valid = false;\r\n      }\r\n\r\n      prev_repeatable = !IsInSet(ch, \"^$?*+\");\r\n    }\r\n  }\r\n\r\n  return is_valid;\r\n}\r\n\r\n// Matches a repeated regex atom followed by a valid simple regular\r\n// expression.  The regex atom is defined as c if escaped is false,\r\n// or \\c otherwise.  repeat is the repetition meta character (?, *,\r\n// or +).  The behavior is undefined if str contains too many\r\n// characters to be indexable by size_t, in which case the test will\r\n// probably time out anyway.  We are fine with this limitation as\r\n// std::string has it too.\r\nbool MatchRepetitionAndRegexAtHead(\r\n  bool escaped, char c, char repeat, const char* regex,\r\n  const char* str) {\r\n  const size_t min_count = (repeat == '+') ? 1 : 0;\r\n  const size_t max_count = (repeat == '?') ? 1 :\r\n                           static_cast<size_t>(-1) - 1;\r\n  // We cannot call numeric_limits::max() as it conflicts with the\r\n  // max() macro on Windows.\r\n\r\n  for (size_t i = 0; i <= max_count; ++i) {\r\n    // We know that the atom matches each of the first i characters in str.\r\n    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {\r\n      // We have enough matches at the head, and the tail matches too.\r\n      // Since we only care about *whether* the pattern matches str\r\n      // (as opposed to *how* it matches), there is no need to find a\r\n      // greedy match.\r\n      return true;\r\n    }\r\n\r\n    if (str[i] == '\\0' || !AtomMatchesChar(escaped, c, str[i])) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  return false;\r\n}\r\n\r\n// Returns true iff regex matches a prefix of str.  regex must be a\r\n// valid simple regular expression and not start with \"^\", or the\r\n// result is undefined.\r\nbool MatchRegexAtHead(const char* regex, const char* str) {\r\n  if (*regex == '\\0') { // An empty regex matches a prefix of anything.\r\n    return true;\r\n  }\r\n\r\n  // \"$\" only matches the end of a string.  Note that regex being\r\n  // valid guarantees that there's nothing after \"$\" in it.\r\n  if (*regex == '$') {\r\n    return *str == '\\0';\r\n  }\r\n\r\n  // Is the first thing in regex an escape sequence?\r\n  const bool escaped = *regex == '\\\\';\r\n\r\n  if (escaped) {\r\n    ++regex;\r\n  }\r\n\r\n  if (IsRepeat(regex[1])) {\r\n    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so\r\n    // here's an indirect recursion.  It terminates as the regex gets\r\n    // shorter in each recursion.\r\n    return MatchRepetitionAndRegexAtHead(\r\n             escaped, regex[0], regex[1], regex + 2, str);\r\n  }\r\n  else {\r\n    // regex isn't empty, isn't \"$\", and doesn't start with a\r\n    // repetition.  We match the first atom of regex with the first\r\n    // character of str and recurse.\r\n    return (*str != '\\0') && AtomMatchesChar(escaped, *regex, *str) &&\r\n           MatchRegexAtHead(regex + 1, str + 1);\r\n  }\r\n}\r\n\r\n// Returns true iff regex matches any substring of str.  regex must be\r\n// a valid simple regular expression, or the result is undefined.\r\n//\r\n// The algorithm is recursive, but the recursion depth doesn't exceed\r\n// the regex length, so we won't need to worry about running out of\r\n// stack space normally.  In rare cases the time complexity can be\r\n// exponential with respect to the regex length + the string length,\r\n// but usually it's must faster (often close to linear).\r\nbool MatchRegexAnywhere(const char* regex, const char* str) {\r\n  if (regex == NULL || str == NULL) {\r\n    return false;\r\n  }\r\n\r\n  if (*regex == '^') {\r\n    return MatchRegexAtHead(regex + 1, str);\r\n  }\r\n\r\n  // A successful match can be anywhere in str.\r\n  do {\r\n    if (MatchRegexAtHead(regex, str)) {\r\n      return true;\r\n    }\r\n  }\r\n  while (*str++ != '\\0');\r\n\r\n  return false;\r\n}\r\n\r\n// Implements the RE class.\r\n\r\nRE::~RE() {\r\n  free(const_cast<char*>(pattern_));\r\n  free(const_cast<char*>(full_pattern_));\r\n}\r\n\r\n// Returns true iff regular expression re matches the entire str.\r\nbool RE::FullMatch(const char* str, const RE& re) {\r\n  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);\r\n}\r\n\r\n// Returns true iff regular expression re matches a substring of str\r\n// (including str itself).\r\nbool RE::PartialMatch(const char* str, const RE& re) {\r\n  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);\r\n}\r\n\r\n// Initializes an RE from its string representation.\r\nvoid RE::Init(const char* regex) {\r\n  pattern_ = full_pattern_ = NULL;\r\n\r\n  if (regex != NULL) {\r\n    pattern_ = posix::StrDup(regex);\r\n  }\r\n\r\n  is_valid_ = ValidateRegex(regex);\r\n\r\n  if (!is_valid_) {\r\n    // No need to calculate the full pattern when the regex is invalid.\r\n    return;\r\n  }\r\n\r\n  const size_t len = strlen(regex);\r\n  // Reserves enough bytes to hold the regular expression used for a\r\n  // full match: we need space to prepend a '^', append a '$', and\r\n  // terminate the string with '\\0'.\r\n  char* buffer = static_cast<char*>(malloc(len + 3));\r\n  full_pattern_ = buffer;\r\n\r\n  if (*regex != '^') {\r\n    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.\r\n  }\r\n\r\n  // We don't use snprintf or strncpy, as they trigger a warning when\r\n  // compiled with VC++ 8.0.\r\n  memcpy(buffer, regex, len);\r\n  buffer += len;\r\n\r\n  if (len == 0 || regex[len - 1] != '$') {\r\n    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.\r\n  }\r\n\r\n  *buffer = '\\0';\r\n}\r\n\r\n#endif  // GTEST_USES_POSIX_RE\r\n\r\nconst char kUnknownFile[] = \"unknown file\";\r\n\r\n// Formats a source file path and a line number as they would appear\r\n// in an error message from the compiler used to compile this code.\r\nGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {\r\n  const std::string file_name(file == NULL ? kUnknownFile : file);\r\n\r\n  if (line < 0) {\r\n    return file_name + \":\";\r\n  }\r\n\r\n#ifdef _MSC_VER\r\n  return file_name + \"(\" + StreamableToString(line) + \"):\";\r\n#else\r\n  return file_name + \":\" + StreamableToString(line) + \":\";\r\n#endif  // _MSC_VER\r\n}\r\n\r\n// Formats a file location for compiler-independent XML output.\r\n// Although this function is not platform dependent, we put it next to\r\n// FormatFileLocation in order to contrast the two functions.\r\n// Note that FormatCompilerIndependentFileLocation() does NOT append colon\r\n// to the file location it produces, unlike FormatFileLocation().\r\nGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(\r\n  const char* file, int line) {\r\n  const std::string file_name(file == NULL ? kUnknownFile : file);\r\n\r\n  if (line < 0) {\r\n    return file_name;\r\n  }\r\n  else {\r\n    return file_name + \":\" + StreamableToString(line);\r\n  }\r\n}\r\n\r\n\r\nGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)\r\n  : severity_(severity) {\r\n  const char* const marker =\r\n    severity == GTEST_INFO ?    \"[  INFO ]\" :\r\n    severity == GTEST_WARNING ? \"[WARNING]\" :\r\n    severity == GTEST_ERROR ?   \"[ ERROR ]\" : \"[ FATAL ]\";\r\n  GetStream() << ::std::endl << marker << \" \"\r\n              << FormatFileLocation(file, line).c_str() << \": \";\r\n}\r\n\r\n// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.\r\nGTestLog::~GTestLog() {\r\n  GetStream() << ::std::endl;\r\n\r\n  if (severity_ == GTEST_FATAL) {\r\n    fflush(stderr);\r\n    posix::Abort();\r\n  }\r\n}\r\n// Disable Microsoft deprecation warnings for POSIX functions called from\r\n// this class (creat, dup, dup2, and close)\r\n#ifdef _MSC_VER\r\n# pragma warning(push)\r\n# pragma warning(disable: 4996)\r\n#endif  // _MSC_VER\r\n\r\n#if GTEST_HAS_STREAM_REDIRECTION\r\n\r\n// Object that captures an output stream (stdout/stderr).\r\nclass CapturedStream {\r\n public:\r\n  // The ctor redirects the stream to a temporary file.\r\n  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {\r\n# if GTEST_OS_WINDOWS\r\n    char temp_dir_path[MAX_PATH + 1] = { '\\0' };  // NOLINT\r\n    char temp_file_path[MAX_PATH + 1] = { '\\0' };  // NOLINT\r\n\r\n    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);\r\n    const UINT success = ::GetTempFileNameA(temp_dir_path,\r\n                                            \"gtest_redir\",\r\n                                            0,  // Generate unique file name.\r\n                                            temp_file_path);\r\n    GTEST_CHECK_(success != 0)\r\n        << \"Unable to create a temporary file in \" << temp_dir_path;\r\n    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);\r\n    GTEST_CHECK_(captured_fd != -1) << \"Unable to open temporary file \"\r\n                                    << temp_file_path;\r\n    filename_ = temp_file_path;\r\n# else\r\n    // There's no guarantee that a test has write access to the current\r\n    // directory, so we create the temporary file in the /tmp directory\r\n    // instead. We use /tmp on most systems, and /sdcard on Android.\r\n    // That's because Android doesn't have /tmp.\r\n#  if GTEST_OS_LINUX_ANDROID\r\n    // Note: Android applications are expected to call the framework's\r\n    // Context.getExternalStorageDirectory() method through JNI to get\r\n    // the location of the world-writable SD Card directory. However,\r\n    // this requires a Context handle, which cannot be retrieved\r\n    // globally from native code. Doing so also precludes running the\r\n    // code as part of a regular standalone executable, which doesn't\r\n    // run in a Dalvik process (e.g. when running it through 'adb shell').\r\n    //\r\n    // The location /sdcard is directly accessible from native code\r\n    // and is the only location (unofficially) supported by the Android\r\n    // team. It's generally a symlink to the real SD Card mount point\r\n    // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or\r\n    // other OEM-customized locations. Never rely on these, and always\r\n    // use /sdcard.\r\n    char name_template[] = \"/sdcard/gtest_captured_stream.XXXXXX\";\r\n#  else\r\n    char name_template[] = \"/tmp/captured_stream.XXXXXX\";\r\n#  endif  // GTEST_OS_LINUX_ANDROID\r\n    const int captured_fd = mkstemp(name_template);\r\n    filename_ = name_template;\r\n# endif  // GTEST_OS_WINDOWS\r\n    fflush(NULL);\r\n    dup2(captured_fd, fd_);\r\n    close(captured_fd);\r\n  }\r\n\r\n  ~CapturedStream() {\r\n    remove(filename_.c_str());\r\n  }\r\n\r\n  std::string GetCapturedString() {\r\n    if (uncaptured_fd_ != -1) {\r\n      // Restores the original stream.\r\n      fflush(NULL);\r\n      dup2(uncaptured_fd_, fd_);\r\n      close(uncaptured_fd_);\r\n      uncaptured_fd_ = -1;\r\n    }\r\n\r\n    FILE* const file = posix::FOpen(filename_.c_str(), \"r\");\r\n    const std::string content = ReadEntireFile(file);\r\n    posix::FClose(file);\r\n    return content;\r\n  }\r\n\r\n private:\r\n  // Reads the entire content of a file as an std::string.\r\n  static std::string ReadEntireFile(FILE* file);\r\n\r\n  // Returns the size (in bytes) of a file.\r\n  static size_t GetFileSize(FILE* file);\r\n\r\n  const int fd_;  // A stream to capture.\r\n  int uncaptured_fd_;\r\n  // Name of the temporary file holding the stderr output.\r\n  ::std::string filename_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);\r\n};\r\n\r\n// Returns the size (in bytes) of a file.\r\nsize_t CapturedStream::GetFileSize(FILE* file) {\r\n  fseek(file, 0, SEEK_END);\r\n  return static_cast<size_t>(ftell(file));\r\n}\r\n\r\n// Reads the entire content of a file as a string.\r\nstd::string CapturedStream::ReadEntireFile(FILE* file) {\r\n  const size_t file_size = GetFileSize(file);\r\n  char* const buffer = new char[file_size];\r\n\r\n  size_t bytes_last_read = 0;  // # of bytes read in the last fread()\r\n  size_t bytes_read = 0;       // # of bytes read so far\r\n\r\n  fseek(file, 0, SEEK_SET);\r\n\r\n  // Keeps reading the file until we cannot read further or the\r\n  // pre-determined file size is reached.\r\n  do {\r\n    bytes_last_read = fread(buffer + bytes_read, 1, file_size - bytes_read, file);\r\n    bytes_read += bytes_last_read;\r\n  }\r\n  while (bytes_last_read > 0 && bytes_read < file_size);\r\n\r\n  const std::string content(buffer, bytes_read);\r\n  delete[] buffer;\r\n\r\n  return content;\r\n}\r\n\r\n# ifdef _MSC_VER\r\n#  pragma warning(pop)\r\n# endif  // _MSC_VER\r\n\r\nstatic CapturedStream* g_captured_stderr = NULL;\r\nstatic CapturedStream* g_captured_stdout = NULL;\r\n\r\n// Starts capturing an output stream (stdout/stderr).\r\nvoid CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {\r\n  if (*stream != NULL) {\r\n    GTEST_LOG_(FATAL) << \"Only one \" << stream_name\r\n                      << \" capturer can exist at a time.\";\r\n  }\r\n\r\n  *stream = new CapturedStream(fd);\r\n}\r\n\r\n// Stops capturing the output stream and returns the captured string.\r\nstd::string GetCapturedStream(CapturedStream** captured_stream) {\r\n  const std::string content = (*captured_stream)->GetCapturedString();\r\n\r\n  delete *captured_stream;\r\n  *captured_stream = NULL;\r\n\r\n  return content;\r\n}\r\n\r\n// Starts capturing stdout.\r\nvoid CaptureStdout() {\r\n  CaptureStream(kStdOutFileno, \"stdout\", &g_captured_stdout);\r\n}\r\n\r\n// Starts capturing stderr.\r\nvoid CaptureStderr() {\r\n  CaptureStream(kStdErrFileno, \"stderr\", &g_captured_stderr);\r\n}\r\n\r\n// Stops capturing stdout and returns the captured string.\r\nstd::string GetCapturedStdout() {\r\n  return GetCapturedStream(&g_captured_stdout);\r\n}\r\n\r\n// Stops capturing stderr and returns the captured string.\r\nstd::string GetCapturedStderr() {\r\n  return GetCapturedStream(&g_captured_stderr);\r\n}\r\n\r\n#endif  // GTEST_HAS_STREAM_REDIRECTION\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\n// A copy of all command line arguments.  Set by InitGoogleTest().\r\n::std::vector<testing::internal::string> g_argvs;\r\n\r\nstatic const ::std::vector<testing::internal::string>* g_injected_test_argvs =\r\n  NULL;  // Owned.\r\n\r\nvoid SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {\r\n  if (g_injected_test_argvs != argvs) {\r\n    delete g_injected_test_argvs;\r\n  }\r\n\r\n  g_injected_test_argvs = argvs;\r\n}\r\n\r\nconst ::std::vector<testing::internal::string>& GetInjectableArgvs() {\r\n  if (g_injected_test_argvs != NULL) {\r\n    return *g_injected_test_argvs;\r\n  }\r\n\r\n  return g_argvs;\r\n}\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\nnamespace posix {\r\nvoid Abort() {\r\n  DebugBreak();\r\n  TerminateProcess(GetCurrentProcess(), 1);\r\n}\r\n}  // namespace posix\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n// Returns the name of the environment variable corresponding to the\r\n// given flag.  For example, FlagToEnvVar(\"foo\") will return\r\n// \"GTEST_FOO\" in the open-source version.\r\nstatic std::string FlagToEnvVar(const char* flag) {\r\n  const std::string full_flag =\r\n    (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();\r\n\r\n  Message env_var;\r\n\r\n  for (size_t i = 0; i != full_flag.length(); i++) {\r\n    env_var << ToUpper(full_flag.c_str()[i]);\r\n  }\r\n\r\n  return env_var.GetString();\r\n}\r\n\r\n// Parses 'str' for a 32-bit signed integer.  If successful, writes\r\n// the result to *value and returns true; otherwise leaves *value\r\n// unchanged and returns false.\r\nbool ParseInt32(const Message& src_text, const char* str, Int32* value) {\r\n  // Parses the environment variable as a decimal integer.\r\n  char* end = NULL;\r\n  const long long_value = strtol(str, &end, 10);  // NOLINT\r\n\r\n  // Has strtol() consumed all characters in the string?\r\n  if (*end != '\\0') {\r\n    // No - an invalid character was encountered.\r\n    Message msg;\r\n    msg << \"WARNING: \" << src_text\r\n        << \" is expected to be a 32-bit integer, but actually\"\r\n        << \" has value \\\"\" << str << \"\\\".\\n\";\r\n    printf(\"%s\", msg.GetString().c_str());\r\n    fflush(stdout);\r\n    return false;\r\n  }\r\n\r\n  // Is the parsed value in the range of an Int32?\r\n  const Int32 result = static_cast<Int32>(long_value);\r\n\r\n  if (long_value == LONG_MAX || long_value == LONG_MIN ||\r\n      // The parsed value overflows as a long.  (strtol() returns\r\n      // LONG_MAX or LONG_MIN when the input overflows.)\r\n      result != long_value\r\n      // The parsed value overflows as an Int32.\r\n     ) {\r\n    Message msg;\r\n    msg << \"WARNING: \" << src_text\r\n        << \" is expected to be a 32-bit integer, but actually\"\r\n        << \" has value \" << str << \", which overflows.\\n\";\r\n    printf(\"%s\", msg.GetString().c_str());\r\n    fflush(stdout);\r\n    return false;\r\n  }\r\n\r\n  *value = result;\r\n  return true;\r\n}\r\n\r\n// Reads and returns the Boolean environment variable corresponding to\r\n// the given flag; if it's not set, returns default_value.\r\n//\r\n// The value is considered true iff it's not \"0\".\r\nbool BoolFromGTestEnv(const char* flag, bool default_value) {\r\n  const std::string env_var = FlagToEnvVar(flag);\r\n  const char* const string_value = posix::GetEnv(env_var.c_str());\r\n  return string_value == NULL ?\r\n         default_value : strcmp(string_value, \"0\") != 0;\r\n}\r\n\r\n// Reads and returns a 32-bit integer stored in the environment\r\n// variable corresponding to the given flag; if it isn't set or\r\n// doesn't represent a valid 32-bit integer, returns default_value.\r\nInt32 Int32FromGTestEnv(const char* flag, Int32 default_value) {\r\n  const std::string env_var = FlagToEnvVar(flag);\r\n  const char* const string_value = posix::GetEnv(env_var.c_str());\r\n\r\n  if (string_value == NULL) {\r\n    // The environment variable is not set.\r\n    return default_value;\r\n  }\r\n\r\n  Int32 result = default_value;\r\n\r\n  if (!ParseInt32(Message() << \"Environment variable \" << env_var,\r\n                  string_value, &result)) {\r\n    printf(\"The default value %s is used.\\n\",\r\n           (Message() << default_value).GetString().c_str());\r\n    fflush(stdout);\r\n    return default_value;\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\n// Reads and returns the string environment variable corresponding to\r\n// the given flag; if it's not set, returns default_value.\r\nconst char* StringFromGTestEnv(const char* flag, const char* default_value) {\r\n  const std::string env_var = FlagToEnvVar(flag);\r\n  const char* const value = posix::GetEnv(env_var.c_str());\r\n  return value == NULL ? default_value : value;\r\n}\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-printers.cpp",
    "content": "// Copyright 2007, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n// Google Test - The Google C++ Testing Framework\r\n//\r\n// This file implements a universal value printer that can print a\r\n// value of any type T:\r\n//\r\n//   void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);\r\n//\r\n// It uses the << operator when possible, and prints the bytes in the\r\n// object otherwise.  A user can override its behavior for a class\r\n// type Foo by defining either operator<<(::std::ostream&, const Foo&)\r\n// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that\r\n// defines Foo.\r\n\r\n#include \"gtest/gtest-printers.h\"\r\n#include <ctype.h>\r\n#include <stdio.h>\r\n#include <ostream>  // NOLINT\r\n#include <string>\r\n#include \"gtest/internal/gtest-port.h\"\r\n\r\nnamespace testing {\r\n\r\nnamespace {\r\n\r\nusing ::std::ostream;\r\n\r\n// Prints a segment of bytes in the given object.\r\nvoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,\r\n                                size_t count, ostream* os) {\r\n  char text[5] = \"\";\r\n\r\n  for (size_t i = 0; i != count; i++) {\r\n    const size_t j = start + i;\r\n\r\n    if (i != 0) {\r\n      // Organizes the bytes into groups of 2 for easy parsing by\r\n      // human.\r\n      if ((j % 2) == 0) {\r\n        *os << ' ';\r\n      }\r\n      else {\r\n        *os << '-';\r\n      }\r\n    }\r\n\r\n    GTEST_SNPRINTF_(text, sizeof(text), \"%02X\", obj_bytes[j]);\r\n    *os << text;\r\n  }\r\n}\r\n\r\n// Prints the bytes in the given value to the given ostream.\r\nvoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,\r\n                              ostream* os) {\r\n  // Tells the user how big the object is.\r\n  *os << count << \"-byte object <\";\r\n\r\n  const size_t kThreshold = 132;\r\n  const size_t kChunkSize = 64;\r\n\r\n  // If the object size is bigger than kThreshold, we'll have to omit\r\n  // some details by printing only the first and the last kChunkSize\r\n  // bytes.\r\n  // TODO(wan): let the user control the threshold using a flag.\r\n  if (count < kThreshold) {\r\n    PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);\r\n  }\r\n  else {\r\n    PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);\r\n    *os << \" ... \";\r\n    // Rounds up to 2-byte boundary.\r\n    const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;\r\n    PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);\r\n  }\r\n\r\n  *os << \">\";\r\n}\r\n\r\n}  // namespace\r\n\r\nnamespace internal2 {\r\n\r\n// Delegates to PrintBytesInObjectToImpl() to print the bytes in the\r\n// given object.  The delegation simplifies the implementation, which\r\n// uses the << operator and thus is easier done outside of the\r\n// ::testing::internal namespace, which contains a << operator that\r\n// sometimes conflicts with the one in STL.\r\nvoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,\r\n                          ostream* os) {\r\n  PrintBytesInObjectToImpl(obj_bytes, count, os);\r\n}\r\n\r\n}  // namespace internal2\r\n\r\nnamespace internal {\r\n\r\n// Depending on the value of a char (or wchar_t), we print it in one\r\n// of three formats:\r\n//   - as is if it's a printable ASCII (e.g. 'a', '2', ' '),\r\n//   - as a hexidecimal escape sequence (e.g. '\\x7F'), or\r\n//   - as a special escape sequence (e.g. '\\r', '\\n').\r\nenum CharFormat {\r\n  kAsIs,\r\n  kHexEscape,\r\n  kSpecialEscape\r\n};\r\n\r\n// Returns true if c is a printable ASCII character.  We test the\r\n// value of c directly instead of calling isprint(), which is buggy on\r\n// Windows Mobile.\r\ninline bool IsPrintableAscii(wchar_t c) {\r\n  return 0x20 <= c && c <= 0x7E;\r\n}\r\n\r\n// Prints a wide or narrow char c as a character literal without the\r\n// quotes, escaping it when necessary; returns how c was formatted.\r\n// The template argument UnsignedChar is the unsigned version of Char,\r\n// which is the type of c.\r\ntemplate <typename UnsignedChar, typename Char>\r\nstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {\r\n  switch (static_cast<wchar_t>(c)) {\r\n    case L'\\0':\r\n      *os << \"\\\\0\";\r\n      break;\r\n\r\n    case L'\\'':\r\n      *os << \"\\\\'\";\r\n      break;\r\n\r\n    case L'\\\\':\r\n      *os << \"\\\\\\\\\";\r\n      break;\r\n\r\n    case L'\\a':\r\n      *os << \"\\\\a\";\r\n      break;\r\n\r\n    case L'\\b':\r\n      *os << \"\\\\b\";\r\n      break;\r\n\r\n    case L'\\f':\r\n      *os << \"\\\\f\";\r\n      break;\r\n\r\n    case L'\\n':\r\n      *os << \"\\\\n\";\r\n      break;\r\n\r\n    case L'\\r':\r\n      *os << \"\\\\r\";\r\n      break;\r\n\r\n    case L'\\t':\r\n      *os << \"\\\\t\";\r\n      break;\r\n\r\n    case L'\\v':\r\n      *os << \"\\\\v\";\r\n      break;\r\n\r\n    default:\r\n      if (IsPrintableAscii(c)) {\r\n        *os << static_cast<char>(c);\r\n        return kAsIs;\r\n      }\r\n      else {\r\n        *os << \"\\\\x\" + String::FormatHexInt(static_cast<UnsignedChar>(c));\r\n        return kHexEscape;\r\n      }\r\n  }\r\n\r\n  return kSpecialEscape;\r\n}\r\n\r\n// Prints a wchar_t c as if it's part of a string literal, escaping it when\r\n// necessary; returns how c was formatted.\r\nstatic CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {\r\n  switch (c) {\r\n    case L'\\'':\r\n      *os << \"'\";\r\n      return kAsIs;\r\n\r\n    case L'\"':\r\n      *os << \"\\\\\\\"\";\r\n      return kSpecialEscape;\r\n\r\n    default:\r\n      return PrintAsCharLiteralTo<wchar_t>(c, os);\r\n  }\r\n}\r\n\r\n// Prints a char c as if it's part of a string literal, escaping it when\r\n// necessary; returns how c was formatted.\r\nstatic CharFormat PrintAsStringLiteralTo(char c, ostream* os) {\r\n  return PrintAsStringLiteralTo(\r\n           static_cast<wchar_t>(static_cast<unsigned char>(c)), os);\r\n}\r\n\r\n// Prints a wide or narrow character c and its code.  '\\0' is printed\r\n// as \"'\\\\0'\", other unprintable characters are also properly escaped\r\n// using the standard C++ escape sequence.  The template argument\r\n// UnsignedChar is the unsigned version of Char, which is the type of c.\r\ntemplate <typename UnsignedChar, typename Char>\r\nvoid PrintCharAndCodeTo(Char c, ostream* os) {\r\n  // First, print c as a literal in the most readable form we can find.\r\n  *os << ((sizeof(c) > 1) ? \"L'\" : \"'\");\r\n  const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);\r\n  *os << \"'\";\r\n\r\n  // To aid user debugging, we also print c's code in decimal, unless\r\n  // it's 0 (in which case c was printed as '\\\\0', making the code\r\n  // obvious).\r\n  if (c == 0) {\r\n    return;\r\n  }\r\n\r\n  *os << \" (\" << static_cast<int>(c);\r\n\r\n  // For more convenience, we print c's code again in hexidecimal,\r\n  // unless c was already printed in the form '\\x##' or the code is in\r\n  // [1, 9].\r\n  if (format == kHexEscape || (1 <= c && c <= 9)) {\r\n    // Do nothing.\r\n  }\r\n  else {\r\n    *os << \", 0x\" << String::FormatHexInt(static_cast<UnsignedChar>(c));\r\n  }\r\n\r\n  *os << \")\";\r\n}\r\n\r\nvoid PrintTo(unsigned char c, ::std::ostream* os) {\r\n  PrintCharAndCodeTo<unsigned char>(c, os);\r\n}\r\nvoid PrintTo(signed char c, ::std::ostream* os) {\r\n  PrintCharAndCodeTo<unsigned char>(c, os);\r\n}\r\n\r\n// Prints a wchar_t as a symbol if it is printable or as its internal\r\n// code otherwise and also as its code.  L'\\0' is printed as \"L'\\\\0'\".\r\nvoid PrintTo(wchar_t wc, ostream* os) {\r\n  PrintCharAndCodeTo<wchar_t>(wc, os);\r\n}\r\n\r\n// Prints the given array of characters to the ostream.  CharType must be either\r\n// char or wchar_t.\r\n// The array starts at begin, the length is len, it may include '\\0' characters\r\n// and may not be NUL-terminated.\r\ntemplate <typename CharType>\r\nstatic void PrintCharsAsStringTo(\r\n  const CharType* begin, size_t len, ostream* os) {\r\n  const char* const kQuoteBegin = sizeof(CharType) == 1 ? \"\\\"\" : \"L\\\"\";\r\n  *os << kQuoteBegin;\r\n  bool is_previous_hex = false;\r\n\r\n  for (size_t index = 0; index < len; ++index) {\r\n    const CharType cur = begin[index];\r\n\r\n    if (is_previous_hex && IsXDigit(cur)) {\r\n      // Previous character is of '\\x..' form and this character can be\r\n      // interpreted as another hexadecimal digit in its number. Break string to\r\n      // disambiguate.\r\n      *os << \"\\\" \" << kQuoteBegin;\r\n    }\r\n\r\n    is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;\r\n  }\r\n\r\n  *os << \"\\\"\";\r\n}\r\n\r\n// Prints a (const) char/wchar_t array of 'len' elements, starting at address\r\n// 'begin'.  CharType must be either char or wchar_t.\r\ntemplate <typename CharType>\r\nstatic void UniversalPrintCharArray(\r\n  const CharType* begin, size_t len, ostream* os) {\r\n  // The code\r\n  //   const char kFoo[] = \"foo\";\r\n  // generates an array of 4, not 3, elements, with the last one being '\\0'.\r\n  //\r\n  // Therefore when printing a char array, we don't print the last element if\r\n  // it's '\\0', such that the output matches the string literal as it's\r\n  // written in the source code.\r\n  if (len > 0 && begin[len - 1] == '\\0') {\r\n    PrintCharsAsStringTo(begin, len - 1, os);\r\n    return;\r\n  }\r\n\r\n  // If, however, the last element in the array is not '\\0', e.g.\r\n  //    const char kFoo[] = { 'f', 'o', 'o' };\r\n  // we must print the entire array.  We also print a message to indicate\r\n  // that the array is not NUL-terminated.\r\n  PrintCharsAsStringTo(begin, len, os);\r\n  *os << \" (no terminating NUL)\";\r\n}\r\n\r\n// Prints a (const) char array of 'len' elements, starting at address 'begin'.\r\nvoid UniversalPrintArray(const char* begin, size_t len, ostream* os) {\r\n  UniversalPrintCharArray(begin, len, os);\r\n}\r\n\r\n// Prints a (const) wchar_t array of 'len' elements, starting at address\r\n// 'begin'.\r\nvoid UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {\r\n  UniversalPrintCharArray(begin, len, os);\r\n}\r\n\r\n// Prints the given C string to the ostream.\r\nvoid PrintTo(const char* s, ostream* os) {\r\n  if (s == NULL) {\r\n    *os << \"NULL\";\r\n  }\r\n  else {\r\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\r\n    PrintCharsAsStringTo(s, strlen(s), os);\r\n  }\r\n}\r\n\r\n// MSVC compiler can be configured to define whar_t as a typedef\r\n// of unsigned short. Defining an overload for const wchar_t* in that case\r\n// would cause pointers to unsigned shorts be printed as wide strings,\r\n// possibly accessing more memory than intended and causing invalid\r\n// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when\r\n// wchar_t is implemented as a native type.\r\n#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)\r\n// Prints the given wide C string to the ostream.\r\nvoid PrintTo(const wchar_t* s, ostream* os) {\r\n  if (s == NULL) {\r\n    *os << \"NULL\";\r\n  }\r\n  else {\r\n    *os << ImplicitCast_<const void*>(s) << \" pointing to \";\r\n    PrintCharsAsStringTo(s, wcslen(s), os);\r\n  }\r\n}\r\n#endif  // wchar_t is native\r\n\r\n// Prints a ::string object.\r\n#if GTEST_HAS_GLOBAL_STRING\r\nvoid PrintStringTo(const ::string& s, ostream* os) {\r\n  PrintCharsAsStringTo(s.data(), s.size(), os);\r\n}\r\n#endif  // GTEST_HAS_GLOBAL_STRING\r\n\r\nvoid PrintStringTo(const ::std::string& s, ostream* os) {\r\n  PrintCharsAsStringTo(s.data(), s.size(), os);\r\n}\r\n\r\n// Prints a ::wstring object.\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\nvoid PrintWideStringTo(const ::wstring& s, ostream* os) {\r\n  PrintCharsAsStringTo(s.data(), s.size(), os);\r\n}\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\nvoid PrintWideStringTo(const ::std::wstring& s, ostream* os) {\r\n  PrintCharsAsStringTo(s.data(), s.size(), os);\r\n}\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\n}  // namespace internal\r\n\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-test-part.cpp",
    "content": "// Copyright 2008, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: mheule@google.com (Markus Heule)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n\r\n#include \"gtest/gtest-test-part.h\"\r\n\r\n// Indicates that this translation unit is part of Google Test's\r\n// implementation.  It must come before gtest-internal-inl.h is\r\n// included, or there will be a compiler error.  This trick is to\r\n// prevent a user from accidentally including gtest-internal-inl.h in\r\n// his code.\r\n#define GTEST_IMPLEMENTATION_ 1\r\n#include \"src/gtest-internal-inl.h\"\r\n#undef GTEST_IMPLEMENTATION_\r\n\r\nnamespace testing {\r\n\r\nusing internal::GetUnitTestImpl;\r\n\r\n// Gets the summary of the failure message by omitting the stack trace\r\n// in it.\r\nstd::string TestPartResult::ExtractSummary(const char* message) {\r\n  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);\r\n  return stack_trace == NULL ? message :\r\n         std::string(message, stack_trace);\r\n}\r\n\r\n// Prints a TestPartResult object.\r\nstd::ostream& operator<<(std::ostream& os, const TestPartResult& result) {\r\n  return os\r\n         << result.file_name() << \":\" << result.line_number() << \": \"\r\n         << (result.type() == TestPartResult::kSuccess ? \"Success\" :\r\n             result.type() == TestPartResult::kFatalFailure ? \"Fatal failure\" :\r\n             \"Non-fatal failure\") << \":\\n\"\r\n         << result.message() << std::endl;\r\n}\r\n\r\n// Appends a TestPartResult to the array.\r\nvoid TestPartResultArray::Append(const TestPartResult& result) {\r\n  array_.push_back(result);\r\n}\r\n\r\n// Returns the TestPartResult at the given index (0-based).\r\nconst TestPartResult& TestPartResultArray::GetTestPartResult(int index) const {\r\n  if (index < 0 || index >= size()) {\r\n    printf(\"\\nInvalid index (%d) into TestPartResultArray.\\n\", index);\r\n    internal::posix::Abort();\r\n  }\r\n\r\n  return array_[index];\r\n}\r\n\r\n// Returns the number of TestPartResult objects in the array.\r\nint TestPartResultArray::size() const {\r\n  return static_cast<int>(array_.size());\r\n}\r\n\r\nnamespace internal {\r\n\r\nHasNewFatalFailureHelper::HasNewFatalFailureHelper()\r\n  : has_new_fatal_failure_(false),\r\n    original_reporter_(GetUnitTestImpl()->\r\n                       GetTestPartResultReporterForCurrentThread()) {\r\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);\r\n}\r\n\r\nHasNewFatalFailureHelper::~HasNewFatalFailureHelper() {\r\n  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(\r\n    original_reporter_);\r\n}\r\n\r\nvoid HasNewFatalFailureHelper::ReportTestPartResult(\r\n  const TestPartResult& result) {\r\n  if (result.fatally_failed()) {\r\n    has_new_fatal_failure_ = true;\r\n  }\r\n\r\n  original_reporter_->ReportTestPartResult(result);\r\n}\r\n\r\n}  // namespace internal\r\n\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest-typed-test.cpp",
    "content": "// Copyright 2008 Google Inc.\r\n// All Rights Reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n\r\n#include \"gtest/gtest-typed-test.h\"\r\n#include \"gtest/gtest.h\"\r\n\r\nnamespace testing {\r\nnamespace internal {\r\n\r\n#if GTEST_HAS_TYPED_TEST_P\r\n\r\n// Skips to the first non-space char in str. Returns an empty string if str\r\n// contains only whitespace characters.\r\nstatic const char* SkipSpaces(const char* str) {\r\n  while (IsSpace(*str)) {\r\n    str++;\r\n  }\r\n\r\n  return str;\r\n}\r\n\r\n// Verifies that registered_tests match the test names in\r\n// defined_test_names_; returns registered_tests if successful, or\r\n// aborts the program otherwise.\r\nconst char* TypedTestCasePState::VerifyRegisteredTestNames(\r\n  const char* file, int line, const char* registered_tests) {\r\n  typedef ::std::set<const char*>::const_iterator DefinedTestIter;\r\n  registered_ = true;\r\n\r\n  // Skip initial whitespace in registered_tests since some\r\n  // preprocessors prefix stringizied literals with whitespace.\r\n  registered_tests = SkipSpaces(registered_tests);\r\n\r\n  Message errors;\r\n  ::std::set<std::string> tests;\r\n\r\n  for (const char* names = registered_tests; names != NULL;\r\n       names = SkipComma(names)) {\r\n    const std::string name = GetPrefixUntilComma(names);\r\n\r\n    if (tests.count(name) != 0) {\r\n      errors << \"Test \" << name << \" is listed more than once.\\n\";\r\n      continue;\r\n    }\r\n\r\n    bool found = false;\r\n\r\n    for (DefinedTestIter it = defined_test_names_.begin();\r\n         it != defined_test_names_.end();\r\n         ++it) {\r\n      if (name == *it) {\r\n        found = true;\r\n        break;\r\n      }\r\n    }\r\n\r\n    if (found) {\r\n      tests.insert(name);\r\n    }\r\n    else {\r\n      errors << \"No test named \" << name\r\n             << \" can be found in this test case.\\n\";\r\n    }\r\n  }\r\n\r\n  for (DefinedTestIter it = defined_test_names_.begin();\r\n       it != defined_test_names_.end();\r\n       ++it) {\r\n    if (tests.count(*it) == 0) {\r\n      errors << \"You forgot to list test \" << *it << \".\\n\";\r\n    }\r\n  }\r\n\r\n  const std::string& errors_str = errors.GetString();\r\n\r\n  if (errors_str != \"\") {\r\n    fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\r\n            errors_str.c_str());\r\n    fflush(stderr);\r\n    posix::Abort();\r\n  }\r\n\r\n  return registered_tests;\r\n}\r\n\r\n#endif  // GTEST_HAS_TYPED_TEST_P\r\n\r\n}  // namespace internal\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest.cpp",
    "content": "// Copyright 2005, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n//\r\n// Author: wan@google.com (Zhanyong Wan)\r\n//\r\n// The Google C++ Testing Framework (Google Test)\r\n\r\n#include \"gtest/gtest.h\"\r\n#include \"gtest/gtest-spi.h\"\r\n\r\n#include <ctype.h>\r\n#include <math.h>\r\n#include <stdarg.h>\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\n#include <time.h>\r\n#include <wchar.h>\r\n#include <wctype.h>\r\n\r\n#include <algorithm>\r\n#include <iomanip>\r\n#include <limits>\r\n#include <ostream>  // NOLINT\r\n#include <sstream>\r\n#include <vector>\r\n\r\n#if GTEST_OS_LINUX\r\n\r\n// TODO(kenton@google.com): Use autoconf to detect availability of\r\n// gettimeofday().\r\n# define GTEST_HAS_GETTIMEOFDAY_ 1\r\n\r\n# include <fcntl.h>  // NOLINT\r\n# include <limits.h>  // NOLINT\r\n# include <sched.h>  // NOLINT\r\n// Declares vsnprintf().  This header is not available on Windows.\r\n# include <strings.h>  // NOLINT\r\n# include <sys/mman.h>  // NOLINT\r\n# include <sys/time.h>  // NOLINT\r\n# include <unistd.h>  // NOLINT\r\n# include <string>\r\n\r\n#elif GTEST_OS_SYMBIAN\r\n# define GTEST_HAS_GETTIMEOFDAY_ 1\r\n# include <sys/time.h>  // NOLINT\r\n\r\n#elif GTEST_OS_ZOS\r\n# define GTEST_HAS_GETTIMEOFDAY_ 1\r\n# include <sys/time.h>  // NOLINT\r\n\r\n// On z/OS we additionally need strings.h for strcasecmp.\r\n# include <strings.h>  // NOLINT\r\n\r\n#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.\r\n\r\n# include <windows.h>  // NOLINT\r\n\r\n#elif GTEST_OS_WINDOWS  // We are on Windows proper.\r\n\r\n# include <io.h>  // NOLINT\r\n# include <sys/timeb.h>  // NOLINT\r\n# include <sys/types.h>  // NOLINT\r\n# include <sys/stat.h>  // NOLINT\r\n\r\n# if GTEST_OS_WINDOWS_MINGW\r\n// MinGW has gettimeofday() but not _ftime64().\r\n// TODO(kenton@google.com): Use autoconf to detect availability of\r\n//   gettimeofday().\r\n// TODO(kenton@google.com): There are other ways to get the time on\r\n//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW\r\n//   supports these.  consider using them instead.\r\n#  define GTEST_HAS_GETTIMEOFDAY_ 1\r\n#  include <sys/time.h>  // NOLINT\r\n# endif  // GTEST_OS_WINDOWS_MINGW\r\n\r\n// cpplint thinks that the header is already included, so we want to\r\n// silence it.\r\n# include <windows.h>  // NOLINT\r\n\r\n#else\r\n\r\n// Assume other platforms have gettimeofday().\r\n// TODO(kenton@google.com): Use autoconf to detect availability of\r\n//   gettimeofday().\r\n# define GTEST_HAS_GETTIMEOFDAY_ 1\r\n\r\n// cpplint thinks that the header is already included, so we want to\r\n// silence it.\r\n# include <sys/time.h>  // NOLINT\r\n# include <unistd.h>  // NOLINT\r\n\r\n#endif  // GTEST_OS_LINUX\r\n\r\n#if GTEST_HAS_EXCEPTIONS\r\n# include <stdexcept>\r\n#endif\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n# include <arpa/inet.h>  // NOLINT\r\n# include <netdb.h>  // NOLINT\r\n#endif\r\n\r\n// Indicates that this translation unit is part of Google Test's\r\n// implementation.  It must come before gtest-internal-inl.h is\r\n// included, or there will be a compiler error.  This trick is to\r\n// prevent a user from accidentally including gtest-internal-inl.h in\r\n// his code.\r\n#define GTEST_IMPLEMENTATION_ 1\r\n#include \"src/gtest-internal-inl.h\"\r\n#undef GTEST_IMPLEMENTATION_\r\n\r\n#if GTEST_OS_WINDOWS\r\n# define vsnprintf _vsnprintf\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\nnamespace testing {\r\n\r\nusing internal::CountIf;\r\nusing internal::ForEach;\r\nusing internal::GetElementOr;\r\nusing internal::Shuffle;\r\n\r\n// Constants.\r\n\r\n// A test whose test case name or test name matches this filter is\r\n// disabled and not run.\r\nstatic const char kDisableTestFilter[] = \"DISABLED_*:*/DISABLED_*\";\r\n\r\n// A test case whose name matches this filter is considered a death\r\n// test case and will be run before test cases whose name doesn't\r\n// match this filter.\r\nstatic const char kDeathTestCaseFilter[] = \"*DeathTest:*DeathTest/*\";\r\n\r\n// A test filter that matches everything.\r\nstatic const char kUniversalFilter[] = \"*\";\r\n\r\n// The default output file for XML output.\r\nstatic const char kDefaultOutputFile[] = \"test_detail.xml\";\r\n\r\n// The environment variable name for the test shard index.\r\nstatic const char kTestShardIndex[] = \"GTEST_SHARD_INDEX\";\r\n// The environment variable name for the total number of test shards.\r\nstatic const char kTestTotalShards[] = \"GTEST_TOTAL_SHARDS\";\r\n// The environment variable name for the test shard status file.\r\nstatic const char kTestShardStatusFile[] = \"GTEST_SHARD_STATUS_FILE\";\r\n\r\nnamespace internal {\r\n\r\n// The text used in failure messages to indicate the start of the\r\n// stack trace.\r\nconst char kStackTraceMarker[] = \"\\nStack trace:\\n\";\r\n\r\n// g_help_flag is true iff the --help flag or an equivalent form is\r\n// specified on the command line.\r\nbool g_help_flag = false;\r\n\r\n}  // namespace internal\r\n\r\nstatic const char* GetDefaultFilter() {\r\n  return kUniversalFilter;\r\n}\r\n\r\nGTEST_DEFINE_bool_(\r\n  also_run_disabled_tests,\r\n  internal::BoolFromGTestEnv(\"also_run_disabled_tests\", false),\r\n  \"Run disabled tests too, in addition to the tests normally being run.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  break_on_failure,\r\n  internal::BoolFromGTestEnv(\"break_on_failure\", false),\r\n  \"True iff a failed assertion should be a debugger break-point.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  catch_exceptions,\r\n  internal::BoolFromGTestEnv(\"catch_exceptions\", true),\r\n  \"True iff \" GTEST_NAME_\r\n  \" should catch exceptions and treat them as test failures.\");\r\n\r\nGTEST_DEFINE_string_(\r\n  color,\r\n  internal::StringFromGTestEnv(\"color\", \"auto\"),\r\n  \"Whether to use colors in the output.  Valid values: yes, no, \"\r\n  \"and auto.  'auto' means to use colors if the output is \"\r\n  \"being sent to a terminal and the TERM environment variable \"\r\n  \"is set to a terminal type that supports colors.\");\r\n\r\nGTEST_DEFINE_string_(\r\n  filter,\r\n  internal::StringFromGTestEnv(\"filter\", GetDefaultFilter()),\r\n  \"A colon-separated list of glob (not regex) patterns \"\r\n  \"for filtering the tests to run, optionally followed by a \"\r\n  \"'-' and a : separated list of negative patterns (tests to \"\r\n  \"exclude).  A test is run if it matches one of the positive \"\r\n  \"patterns and does not match any of the negative patterns.\");\r\n\r\nGTEST_DEFINE_bool_(list_tests, false,\r\n                   \"List all tests without running them.\");\r\n\r\nGTEST_DEFINE_string_(\r\n  output,\r\n  internal::StringFromGTestEnv(\"output\", \"\"),\r\n  \"A format (currently must be \\\"xml\\\"), optionally followed \"\r\n  \"by a colon and an output file name or directory. A directory \"\r\n  \"is indicated by a trailing pathname separator. \"\r\n  \"Examples: \\\"xml:filename.xml\\\", \\\"xml::directoryname/\\\". \"\r\n  \"If a directory is specified, output files will be created \"\r\n  \"within that directory, with file-names based on the test \"\r\n  \"executable's name and, if necessary, made unique by adding \"\r\n  \"digits.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  print_time,\r\n  internal::BoolFromGTestEnv(\"print_time\", true),\r\n  \"True iff \" GTEST_NAME_\r\n  \" should display elapsed time in text output.\");\r\n\r\nGTEST_DEFINE_int32_(\r\n  random_seed,\r\n  internal::Int32FromGTestEnv(\"random_seed\", 0),\r\n  \"Random number seed to use when shuffling test orders.  Must be in range \"\r\n  \"[1, 99999], or 0 to use a seed based on the current time.\");\r\n\r\nGTEST_DEFINE_int32_(\r\n  repeat,\r\n  internal::Int32FromGTestEnv(\"repeat\", 1),\r\n  \"How many times to repeat each test.  Specify a negative number \"\r\n  \"for repeating forever.  Useful for shaking out flaky tests.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  show_internal_stack_frames, false,\r\n  \"True iff \" GTEST_NAME_ \" should include internal stack frames when \"\r\n  \"printing test failure stack traces.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  shuffle,\r\n  internal::BoolFromGTestEnv(\"shuffle\", false),\r\n  \"True iff \" GTEST_NAME_\r\n  \" should randomize tests' order on every run.\");\r\n\r\nGTEST_DEFINE_int32_(\r\n  stack_trace_depth,\r\n  internal::Int32FromGTestEnv(\"stack_trace_depth\", kMaxStackTraceDepth),\r\n  \"The maximum number of stack frames to print when an \"\r\n  \"assertion fails.  The valid range is 0 through 100, inclusive.\");\r\n\r\nGTEST_DEFINE_string_(\r\n  stream_result_to,\r\n  internal::StringFromGTestEnv(\"stream_result_to\", \"\"),\r\n  \"This flag specifies the host name and the port number on which to stream \"\r\n  \"test results. Example: \\\"localhost:555\\\". The flag is effective only on \"\r\n  \"Linux.\");\r\n\r\nGTEST_DEFINE_bool_(\r\n  throw_on_failure,\r\n  internal::BoolFromGTestEnv(\"throw_on_failure\", false),\r\n  \"When this flag is specified, a failed assertion will throw an exception \"\r\n  \"if exceptions are enabled or exit the program with a non-zero code \"\r\n  \"otherwise.\");\r\n\r\nnamespace internal {\r\n\r\n// Generates a random number from [0, range), using a Linear\r\n// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater\r\n// than kMaxRange.\r\nUInt32 Random::Generate(UInt32 range) {\r\n  // These constants are the same as are used in glibc's rand(3).\r\n  state_ = (1103515245U * state_ + 12345U) % kMaxRange;\r\n\r\n  GTEST_CHECK_(range > 0)\r\n      << \"Cannot generate a number in the range [0, 0).\";\r\n  GTEST_CHECK_(range <= kMaxRange)\r\n      << \"Generation of a number in [0, \" << range << \") was requested, \"\r\n      << \"but this can only generate numbers in [0, \" << kMaxRange << \").\";\r\n\r\n  // Converting via modulus introduces a bit of downward bias, but\r\n  // it's simple, and a linear congruential generator isn't too good\r\n  // to begin with.\r\n  return state_ % range;\r\n}\r\n\r\n// GTestIsInitialized() returns true iff the user has initialized\r\n// Google Test.  Useful for catching the user mistake of not initializing\r\n// Google Test before calling RUN_ALL_TESTS().\r\n//\r\n// A user must call testing::InitGoogleTest() to initialize Google\r\n// Test.  g_init_gtest_count is set to the number of times\r\n// InitGoogleTest() has been called.  We don't protect this variable\r\n// under a mutex as it is only accessed in the main thread.\r\nGTEST_API_ int g_init_gtest_count = 0;\r\nstatic bool GTestIsInitialized() {\r\n  return g_init_gtest_count != 0;\r\n}\r\n\r\n// Iterates over a vector of TestCases, keeping a running sum of the\r\n// results of calling a given int-returning method on each.\r\n// Returns the sum.\r\nstatic int SumOverTestCaseList(const std::vector<TestCase*>& case_list,\r\n                               int (TestCase::*method)() const) {\r\n  int sum = 0;\r\n\r\n  for (size_t i = 0; i < case_list.size(); i++) {\r\n    sum += (case_list[i]->*method)();\r\n  }\r\n\r\n  return sum;\r\n}\r\n\r\n// Returns true iff the test case passed.\r\nstatic bool TestCasePassed(const TestCase* test_case) {\r\n  return test_case->should_run() && test_case->Passed();\r\n}\r\n\r\n// Returns true iff the test case failed.\r\nstatic bool TestCaseFailed(const TestCase* test_case) {\r\n  return test_case->should_run() && test_case->Failed();\r\n}\r\n\r\n// Returns true iff test_case contains at least one test that should\r\n// run.\r\nstatic bool ShouldRunTestCase(const TestCase* test_case) {\r\n  return test_case->should_run();\r\n}\r\n\r\n// AssertHelper constructor.\r\nAssertHelper::AssertHelper(TestPartResult::Type type,\r\n                           const char* file,\r\n                           int line,\r\n                           const char* message)\r\n  : data_(new AssertHelperData(type, file, line, message)) {\r\n}\r\n\r\nAssertHelper::~AssertHelper() {\r\n  delete data_;\r\n}\r\n\r\n// Message assignment, for assertion streaming support.\r\nvoid AssertHelper::operator=(const Message& message) const {\r\n  UnitTest::GetInstance()->\r\n  AddTestPartResult(data_->type, data_->file, data_->line,\r\n                    AppendUserMessage(data_->message, message),\r\n                    UnitTest::GetInstance()->impl()\r\n                    ->CurrentOsStackTraceExceptTop(1)\r\n                    // Skips the stack frame for this function itself.\r\n                   );  // NOLINT\r\n}\r\n\r\n// Mutex for linked pointers.\r\nGTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);\r\n\r\n// Application pathname gotten in InitGoogleTest.\r\nstd::string g_executable_path;\r\n\r\n// Returns the current application's name, removing directory path if that\r\n// is present.\r\nFilePath GetCurrentExecutableName() {\r\n  FilePath result;\r\n\r\n#if GTEST_OS_WINDOWS\r\n  result.Set(FilePath(g_executable_path).RemoveExtension(\"exe\"));\r\n#else\r\n  result.Set(FilePath(g_executable_path));\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n  return result.RemoveDirectoryName();\r\n}\r\n\r\n// Functions for processing the gtest_output flag.\r\n\r\n// Returns the output format, or \"\" for normal printed output.\r\nstd::string UnitTestOptions::GetOutputFormat() {\r\n  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();\r\n\r\n  if (gtest_output_flag == NULL) {\r\n    return std::string(\"\");\r\n  }\r\n\r\n  const char* const colon = strchr(gtest_output_flag, ':');\r\n  return (colon == NULL) ?\r\n         std::string(gtest_output_flag) :\r\n         std::string(gtest_output_flag, colon - gtest_output_flag);\r\n}\r\n\r\n// Returns the name of the requested output file, or the default if none\r\n// was explicitly specified.\r\nstd::string UnitTestOptions::GetAbsolutePathToOutputFile() {\r\n  const char* const gtest_output_flag = GTEST_FLAG(output).c_str();\r\n\r\n  if (gtest_output_flag == NULL) {\r\n    return \"\";\r\n  }\r\n\r\n  const char* const colon = strchr(gtest_output_flag, ':');\r\n\r\n  if (colon == NULL)\r\n    return internal::FilePath::ConcatPaths(\r\n             internal::FilePath(\r\n               UnitTest::GetInstance()->original_working_dir()),\r\n             internal::FilePath(kDefaultOutputFile)).string();\r\n\r\n  internal::FilePath output_name(colon + 1);\r\n\r\n  if (!output_name.IsAbsolutePath())\r\n    // TODO(wan@google.com): on Windows \\some\\path is not an absolute\r\n    // path (as its meaning depends on the current drive), yet the\r\n    // following logic for turning it into an absolute path is wrong.\r\n    // Fix it.\r\n    output_name = internal::FilePath::ConcatPaths(\r\n                    internal::FilePath(UnitTest::GetInstance()->original_working_dir()),\r\n                    internal::FilePath(colon + 1));\r\n\r\n  if (!output_name.IsDirectory()) {\r\n    return output_name.string();\r\n  }\r\n\r\n  internal::FilePath result(internal::FilePath::GenerateUniqueFileName(\r\n                              output_name, internal::GetCurrentExecutableName(),\r\n                              GetOutputFormat().c_str()));\r\n  return result.string();\r\n}\r\n\r\n// Returns true iff the wildcard pattern matches the string.  The\r\n// first ':' or '\\0' character in pattern marks the end of it.\r\n//\r\n// This recursive algorithm isn't very efficient, but is clear and\r\n// works well enough for matching test names, which are short.\r\nbool UnitTestOptions::PatternMatchesString(const char* pattern,\r\n    const char* str) {\r\n  switch (*pattern) {\r\n    case '\\0':\r\n    case ':':  // Either ':' or '\\0' marks the end of the pattern.\r\n      return *str == '\\0';\r\n\r\n    case '?':  // Matches any single character.\r\n      return *str != '\\0' && PatternMatchesString(pattern + 1, str + 1);\r\n\r\n    case '*':  // Matches any string (possibly empty) of characters.\r\n      return (*str != '\\0' && PatternMatchesString(pattern, str + 1)) ||\r\n             PatternMatchesString(pattern + 1, str);\r\n\r\n    default:  // Non-special character.  Matches itself.\r\n      return *pattern == *str &&\r\n             PatternMatchesString(pattern + 1, str + 1);\r\n  }\r\n}\r\n\r\nbool UnitTestOptions::MatchesFilter(\r\n  const std::string& name, const char* filter) {\r\n  const char* cur_pattern = filter;\r\n\r\n  for (;;) {\r\n    if (PatternMatchesString(cur_pattern, name.c_str())) {\r\n      return true;\r\n    }\r\n\r\n    // Finds the next pattern in the filter.\r\n    cur_pattern = strchr(cur_pattern, ':');\r\n\r\n    // Returns if no more pattern can be found.\r\n    if (cur_pattern == NULL) {\r\n      return false;\r\n    }\r\n\r\n    // Skips the pattern separater (the ':' character).\r\n    cur_pattern++;\r\n  }\r\n}\r\n\r\n// Returns true iff the user-specified filter matches the test case\r\n// name and the test name.\r\nbool UnitTestOptions::FilterMatchesTest(const std::string& test_case_name,\r\n                                        const std::string& test_name) {\r\n  const std::string& full_name = test_case_name + \".\" + test_name.c_str();\r\n\r\n  // Split --gtest_filter at '-', if there is one, to separate into\r\n  // positive filter and negative filter portions\r\n  const char* const p = GTEST_FLAG(filter).c_str();\r\n  const char* const dash = strchr(p, '-');\r\n  std::string positive;\r\n  std::string negative;\r\n\r\n  if (dash == NULL) {\r\n    positive = GTEST_FLAG(filter).c_str();  // Whole string is a positive filter\r\n    negative = \"\";\r\n  }\r\n  else {\r\n    positive = std::string(p, dash);   // Everything up to the dash\r\n    negative = std::string(dash + 1);  // Everything after the dash\r\n\r\n    if (positive.empty()) {\r\n      // Treat '-test1' as the same as '*-test1'\r\n      positive = kUniversalFilter;\r\n    }\r\n  }\r\n\r\n  // A filter is a colon-separated list of patterns.  It matches a\r\n  // test if any pattern in it matches the test.\r\n  return (MatchesFilter(full_name, positive.c_str()) &&\r\n          !MatchesFilter(full_name, negative.c_str()));\r\n}\r\n\r\n#if GTEST_HAS_SEH\r\n// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the\r\n// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.\r\n// This function is useful as an __except condition.\r\nint UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {\r\n  // Google Test should handle a SEH exception if:\r\n  //   1. the user wants it to, AND\r\n  //   2. this is not a breakpoint exception, AND\r\n  //   3. this is not a C++ exception (VC++ implements them via SEH,\r\n  //      apparently).\r\n  //\r\n  // SEH exception code for C++ exceptions.\r\n  // (see http://support.microsoft.com/kb/185294 for more information).\r\n  const DWORD kCxxExceptionCode = 0xe06d7363;\r\n\r\n  bool should_handle = true;\r\n\r\n  if (!GTEST_FLAG(catch_exceptions)) {\r\n    should_handle = false;\r\n  }\r\n  else if (exception_code == EXCEPTION_BREAKPOINT) {\r\n    should_handle = false;\r\n  }\r\n  else if (exception_code == kCxxExceptionCode) {\r\n    should_handle = false;\r\n  }\r\n\r\n  return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;\r\n}\r\n#endif  // GTEST_HAS_SEH\r\n\r\n}  // namespace internal\r\n\r\n// The c'tor sets this object as the test part result reporter used by\r\n// Google Test.  The 'result' parameter specifies where to report the\r\n// results. Intercepts only failures from the current thread.\r\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\r\n  TestPartResultArray* result)\r\n  : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),\r\n    result_(result) {\r\n  Init();\r\n}\r\n\r\n// The c'tor sets this object as the test part result reporter used by\r\n// Google Test.  The 'result' parameter specifies where to report the\r\n// results.\r\nScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(\r\n  InterceptMode intercept_mode, TestPartResultArray* result)\r\n  : intercept_mode_(intercept_mode),\r\n    result_(result) {\r\n  Init();\r\n}\r\n\r\nvoid ScopedFakeTestPartResultReporter::Init() {\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n\r\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\r\n    old_reporter_ = impl->GetGlobalTestPartResultReporter();\r\n    impl->SetGlobalTestPartResultReporter(this);\r\n  }\r\n  else {\r\n    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();\r\n    impl->SetTestPartResultReporterForCurrentThread(this);\r\n  }\r\n}\r\n\r\n// The d'tor restores the test part result reporter used by Google Test\r\n// before.\r\nScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n\r\n  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {\r\n    impl->SetGlobalTestPartResultReporter(old_reporter_);\r\n  }\r\n  else {\r\n    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);\r\n  }\r\n}\r\n\r\n// Increments the test part result count and remembers the result.\r\n// This method is from the TestPartResultReporterInterface interface.\r\nvoid ScopedFakeTestPartResultReporter::ReportTestPartResult(\r\n  const TestPartResult& result) {\r\n  result_->Append(result);\r\n}\r\n\r\nnamespace internal {\r\n\r\n// Returns the type ID of ::testing::Test.  We should always call this\r\n// instead of GetTypeId< ::testing::Test>() to get the type ID of\r\n// testing::Test.  This is to work around a suspected linker bug when\r\n// using Google Test as a framework on Mac OS X.  The bug causes\r\n// GetTypeId< ::testing::Test>() to return different values depending\r\n// on whether the call is from the Google Test framework itself or\r\n// from user test code.  GetTestTypeId() is guaranteed to always\r\n// return the same value, as it always calls GetTypeId<>() from the\r\n// gtest.cc, which is within the Google Test framework.\r\nTypeId GetTestTypeId() {\r\n  return GetTypeId<Test>();\r\n}\r\n\r\n// The value of GetTestTypeId() as seen from within the Google Test\r\n// library.  This is solely for testing GetTestTypeId().\r\nextern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();\r\n\r\n// This predicate-formatter checks that 'results' contains a test part\r\n// failure of the given type and that the failure message contains the\r\n// given substring.\r\nAssertionResult HasOneFailure(const char* /* results_expr */,\r\n                              const char* /* type_expr */,\r\n                              const char* /* substr_expr */,\r\n                              const TestPartResultArray& results,\r\n                              TestPartResult::Type type,\r\n                              const string& substr) {\r\n  const std::string expected(type == TestPartResult::kFatalFailure ?\r\n                             \"1 fatal failure\" :\r\n                             \"1 non-fatal failure\");\r\n  Message msg;\r\n\r\n  if (results.size() != 1) {\r\n    msg << \"Expected: \" << expected << \"\\n\"\r\n        << \"  Actual: \" << results.size() << \" failures\";\r\n\r\n    for (int i = 0; i < results.size(); i++) {\r\n      msg << \"\\n\" << results.GetTestPartResult(i);\r\n    }\r\n\r\n    return AssertionFailure() << msg;\r\n  }\r\n\r\n  const TestPartResult& r = results.GetTestPartResult(0);\r\n\r\n  if (r.type() != type) {\r\n    return AssertionFailure() << \"Expected: \" << expected << \"\\n\"\r\n           << \"  Actual:\\n\"\r\n           << r;\r\n  }\r\n\r\n  if (strstr(r.message(), substr.c_str()) == NULL) {\r\n    return AssertionFailure() << \"Expected: \" << expected << \" containing \\\"\"\r\n           << substr << \"\\\"\\n\"\r\n           << \"  Actual:\\n\"\r\n           << r;\r\n  }\r\n\r\n  return AssertionSuccess();\r\n}\r\n\r\n// The constructor of SingleFailureChecker remembers where to look up\r\n// test part results, what type of failure we expect, and what\r\n// substring the failure message should contain.\r\nSingleFailureChecker:: SingleFailureChecker(\r\n  const TestPartResultArray* results,\r\n  TestPartResult::Type type,\r\n  const string& substr)\r\n  : results_(results),\r\n    type_(type),\r\n    substr_(substr) {}\r\n\r\n// The destructor of SingleFailureChecker verifies that the given\r\n// TestPartResultArray contains exactly one failure that has the given\r\n// type and contains the given substring.  If that's not the case, a\r\n// non-fatal failure will be generated.\r\nSingleFailureChecker::~SingleFailureChecker() {\r\n  EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_);\r\n}\r\n\r\nDefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(\r\n  UnitTestImpl* unit_test) : unit_test_(unit_test) {}\r\n\r\nvoid DefaultGlobalTestPartResultReporter::ReportTestPartResult(\r\n  const TestPartResult& result) {\r\n  unit_test_->current_test_result()->AddTestPartResult(result);\r\n  unit_test_->listeners()->repeater()->OnTestPartResult(result);\r\n}\r\n\r\nDefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(\r\n  UnitTestImpl* unit_test) : unit_test_(unit_test) {}\r\n\r\nvoid DefaultPerThreadTestPartResultReporter::ReportTestPartResult(\r\n  const TestPartResult& result) {\r\n  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);\r\n}\r\n\r\n// Returns the global test part result reporter.\r\nTestPartResultReporterInterface*\r\nUnitTestImpl::GetGlobalTestPartResultReporter() {\r\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\r\n  return global_test_part_result_repoter_;\r\n}\r\n\r\n// Sets the global test part result reporter.\r\nvoid UnitTestImpl::SetGlobalTestPartResultReporter(\r\n  TestPartResultReporterInterface* reporter) {\r\n  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);\r\n  global_test_part_result_repoter_ = reporter;\r\n}\r\n\r\n// Returns the test part result reporter for the current thread.\r\nTestPartResultReporterInterface*\r\nUnitTestImpl::GetTestPartResultReporterForCurrentThread() {\r\n  return per_thread_test_part_result_reporter_.get();\r\n}\r\n\r\n// Sets the test part result reporter for the current thread.\r\nvoid UnitTestImpl::SetTestPartResultReporterForCurrentThread(\r\n  TestPartResultReporterInterface* reporter) {\r\n  per_thread_test_part_result_reporter_.set(reporter);\r\n}\r\n\r\n// Gets the number of successful test cases.\r\nint UnitTestImpl::successful_test_case_count() const {\r\n  return CountIf(test_cases_, TestCasePassed);\r\n}\r\n\r\n// Gets the number of failed test cases.\r\nint UnitTestImpl::failed_test_case_count() const {\r\n  return CountIf(test_cases_, TestCaseFailed);\r\n}\r\n\r\n// Gets the number of all test cases.\r\nint UnitTestImpl::total_test_case_count() const {\r\n  return static_cast<int>(test_cases_.size());\r\n}\r\n\r\n// Gets the number of all test cases that contain at least one test\r\n// that should run.\r\nint UnitTestImpl::test_case_to_run_count() const {\r\n  return CountIf(test_cases_, ShouldRunTestCase);\r\n}\r\n\r\n// Gets the number of successful tests.\r\nint UnitTestImpl::successful_test_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);\r\n}\r\n\r\n// Gets the number of failed tests.\r\nint UnitTestImpl::failed_test_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);\r\n}\r\n\r\n// Gets the number of disabled tests that will be reported in the XML report.\r\nint UnitTestImpl::reportable_disabled_test_count() const {\r\n  return SumOverTestCaseList(test_cases_,\r\n                             &TestCase::reportable_disabled_test_count);\r\n}\r\n\r\n// Gets the number of disabled tests.\r\nint UnitTestImpl::disabled_test_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);\r\n}\r\n\r\n// Gets the number of tests to be printed in the XML report.\r\nint UnitTestImpl::reportable_test_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count);\r\n}\r\n\r\n// Gets the number of all tests.\r\nint UnitTestImpl::total_test_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);\r\n}\r\n\r\n// Gets the number of tests that should run.\r\nint UnitTestImpl::test_to_run_count() const {\r\n  return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);\r\n}\r\n\r\n// Returns the current OS stack trace as an std::string.\r\n//\r\n// The maximum number of stack frames to be included is specified by\r\n// the gtest_stack_trace_depth flag.  The skip_count parameter\r\n// specifies the number of top frames to be skipped, which doesn't\r\n// count against the number of frames to be included.\r\n//\r\n// For example, if Foo() calls Bar(), which in turn calls\r\n// CurrentOsStackTraceExceptTop(1), Foo() will be included in the\r\n// trace but Bar() and CurrentOsStackTraceExceptTop() won't.\r\nstd::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) {\r\n  (void)skip_count;\r\n  return \"\";\r\n}\r\n\r\n// Returns the current time in milliseconds.\r\nTimeInMillis GetTimeInMillis() {\r\n#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)\r\n  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.\r\n  // http://analogous.blogspot.com/2005/04/epoch.html\r\n  const TimeInMillis kJavaEpochToWinFileTimeDelta =\r\n    static_cast<TimeInMillis>(116444736UL) * 100000UL;\r\n  const DWORD kTenthMicrosInMilliSecond = 10000;\r\n\r\n  SYSTEMTIME now_systime;\r\n  FILETIME now_filetime;\r\n  ULARGE_INTEGER now_int64;\r\n  // TODO(kenton@google.com): Shouldn't this just use\r\n  //   GetSystemTimeAsFileTime()?\r\n  GetSystemTime(&now_systime);\r\n\r\n  if (SystemTimeToFileTime(&now_systime, &now_filetime)) {\r\n    now_int64.LowPart = now_filetime.dwLowDateTime;\r\n    now_int64.HighPart = now_filetime.dwHighDateTime;\r\n    now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) -\r\n                         kJavaEpochToWinFileTimeDelta;\r\n    return now_int64.QuadPart;\r\n  }\r\n\r\n  return 0;\r\n#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_\r\n  __timeb64 now;\r\n\r\n# ifdef _MSC_VER\r\n\r\n  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996\r\n  // (deprecated function) there.\r\n  // TODO(kenton@google.com): Use GetTickCount()?  Or use\r\n  //   SystemTimeToFileTime()\r\n#  pragma warning(push)          // Saves the current warning state.\r\n#  pragma warning(disable:4996)  // Temporarily disables warning 4996.\r\n  _ftime64(&now);\r\n#  pragma warning(pop)           // Restores the warning state.\r\n# else\r\n\r\n  _ftime64(&now);\r\n\r\n# endif  // _MSC_VER\r\n\r\n  return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;\r\n#elif GTEST_HAS_GETTIMEOFDAY_\r\n  struct timeval now;\r\n  gettimeofday(&now, NULL);\r\n  return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;\r\n#else\r\n# error \"Don't know how to get the current time on your system.\"\r\n#endif\r\n}\r\n\r\n// Utilities\r\n\r\n// class String.\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE\r\n// Creates a UTF-16 wide string from the given ANSI string, allocating\r\n// memory using new. The caller is responsible for deleting the return\r\n// value using delete[]. Returns the wide string, or NULL if the\r\n// input is NULL.\r\nLPCWSTR String::AnsiToUtf16(const char* ansi) {\r\n  if (!ansi) {\r\n    return NULL;\r\n  }\r\n\r\n  const int length = strlen(ansi);\r\n  const int unicode_length =\r\n    MultiByteToWideChar(CP_ACP, 0, ansi, length,\r\n                        NULL, 0);\r\n  WCHAR* unicode = new WCHAR[unicode_length + 1];\r\n  MultiByteToWideChar(CP_ACP, 0, ansi, length,\r\n                      unicode, unicode_length);\r\n  unicode[unicode_length] = 0;\r\n  return unicode;\r\n}\r\n\r\n// Creates an ANSI string from the given wide string, allocating\r\n// memory using new. The caller is responsible for deleting the return\r\n// value using delete[]. Returns the ANSI string, or NULL if the\r\n// input is NULL.\r\nconst char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {\r\n  if (!utf16_str) {\r\n    return NULL;\r\n  }\r\n\r\n  const int ansi_length =\r\n    WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,\r\n                        NULL, 0, NULL, NULL);\r\n  char* ansi = new char[ansi_length + 1];\r\n  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,\r\n                      ansi, ansi_length, NULL, NULL);\r\n  ansi[ansi_length] = 0;\r\n  return ansi;\r\n}\r\n\r\n#endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n// Compares two C strings.  Returns true iff they have the same content.\r\n//\r\n// Unlike strcmp(), this function can handle NULL argument(s).  A NULL\r\n// C string is considered different to any non-NULL C string,\r\n// including the empty string.\r\nbool String::CStringEquals(const char* lhs, const char* rhs) {\r\n  if ( lhs == NULL ) {\r\n    return rhs == NULL;\r\n  }\r\n\r\n  if ( rhs == NULL ) {\r\n    return false;\r\n  }\r\n\r\n  return strcmp(lhs, rhs) == 0;\r\n}\r\n\r\n#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING\r\n\r\n// Converts an array of wide chars to a narrow string using the UTF-8\r\n// encoding, and streams the result to the given Message object.\r\nstatic void StreamWideCharsToMessage(const wchar_t* wstr, size_t length,\r\n                                     Message* msg) {\r\n  for (size_t i = 0; i != length; ) {  // NOLINT\r\n    if (wstr[i] != L'\\0') {\r\n      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));\r\n\r\n      while (i != length && wstr[i] != L'\\0') {\r\n        i++;\r\n      }\r\n    }\r\n    else {\r\n      *msg << '\\0';\r\n      i++;\r\n    }\r\n  }\r\n}\r\n\r\n#endif  // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING\r\n\r\n}  // namespace internal\r\n\r\n// Constructs an empty Message.\r\n// We allocate the stringstream separately because otherwise each use of\r\n// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's\r\n// stack frame leading to huge stack frames in some cases; gcc does not reuse\r\n// the stack space.\r\nMessage::Message() : ss_(new ::std::stringstream) {\r\n  // By default, we want there to be enough precision when printing\r\n  // a double to a Message.\r\n  *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);\r\n}\r\n\r\n// These two overloads allow streaming a wide C string to a Message\r\n// using the UTF-8 encoding.\r\nMessage& Message::operator <<(const wchar_t* wide_c_str) {\r\n  return *this << internal::String::ShowWideCString(wide_c_str);\r\n}\r\nMessage& Message::operator <<(wchar_t* wide_c_str) {\r\n  return *this << internal::String::ShowWideCString(wide_c_str);\r\n}\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\n// Converts the given wide string to a narrow string using the UTF-8\r\n// encoding, and streams the result to this Message object.\r\nMessage& Message::operator <<(const ::std::wstring& wstr) {\r\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\r\n  return *this;\r\n}\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\n#if GTEST_HAS_GLOBAL_WSTRING\r\n// Converts the given wide string to a narrow string using the UTF-8\r\n// encoding, and streams the result to this Message object.\r\nMessage& Message::operator <<(const ::wstring& wstr) {\r\n  internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);\r\n  return *this;\r\n}\r\n#endif  // GTEST_HAS_GLOBAL_WSTRING\r\n\r\n// Gets the text streamed to this object so far as an std::string.\r\n// Each '\\0' character in the buffer is replaced with \"\\\\0\".\r\nstd::string Message::GetString() const {\r\n  return internal::StringStreamToString(ss_.get());\r\n}\r\n\r\n// AssertionResult constructors.\r\n// Used in EXPECT_TRUE/FALSE(assertion_result).\r\nAssertionResult::AssertionResult(const AssertionResult& other)\r\n  : success_(other.success_),\r\n    message_(other.message_.get() != NULL ?\r\n             new ::std::string(*other.message_) :\r\n             static_cast< ::std::string*>(NULL)) {\r\n}\r\n\r\n// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.\r\nAssertionResult AssertionResult::operator!() const {\r\n  AssertionResult negation(!success_);\r\n\r\n  if (message_.get() != NULL) {\r\n    negation << *message_;\r\n  }\r\n\r\n  return negation;\r\n}\r\n\r\n// Makes a successful assertion result.\r\nAssertionResult AssertionSuccess() {\r\n  return AssertionResult(true);\r\n}\r\n\r\n// Makes a failed assertion result.\r\nAssertionResult AssertionFailure() {\r\n  return AssertionResult(false);\r\n}\r\n\r\n// Makes a failed assertion result with the given failure message.\r\n// Deprecated; use AssertionFailure() << message.\r\nAssertionResult AssertionFailure(const Message& message) {\r\n  return AssertionFailure() << message;\r\n}\r\n\r\nnamespace internal {\r\n\r\n// Constructs and returns the message for an equality assertion\r\n// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure.\r\n//\r\n// The first four parameters are the expressions used in the assertion\r\n// and their values, as strings.  For example, for ASSERT_EQ(foo, bar)\r\n// where foo is 5 and bar is 6, we have:\r\n//\r\n//   expected_expression: \"foo\"\r\n//   actual_expression:   \"bar\"\r\n//   expected_value:      \"5\"\r\n//   actual_value:        \"6\"\r\n//\r\n// The ignoring_case parameter is true iff the assertion is a\r\n// *_STRCASEEQ*.  When it's true, the string \" (ignoring case)\" will\r\n// be inserted into the message.\r\nAssertionResult EqFailure(const char* expected_expression,\r\n                          const char* actual_expression,\r\n                          const std::string& expected_value,\r\n                          const std::string& actual_value,\r\n                          bool ignoring_case) {\r\n  Message msg;\r\n  msg << \"Value of: \" << actual_expression;\r\n\r\n  if (actual_value != actual_expression) {\r\n    msg << \"\\n  Actual: \" << actual_value;\r\n  }\r\n\r\n  msg << \"\\nExpected: \" << expected_expression;\r\n\r\n  if (ignoring_case) {\r\n    msg << \" (ignoring case)\";\r\n  }\r\n\r\n  if (expected_value != expected_expression) {\r\n    msg << \"\\nWhich is: \" << expected_value;\r\n  }\r\n\r\n  return AssertionFailure() << msg;\r\n}\r\n\r\n// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.\r\nstd::string GetBoolAssertionFailureMessage(\r\n  const AssertionResult& assertion_result,\r\n  const char* expression_text,\r\n  const char* actual_predicate_value,\r\n  const char* expected_predicate_value) {\r\n  const char* actual_message = assertion_result.message();\r\n  Message msg;\r\n  msg << \"Value of: \" << expression_text\r\n      << \"\\n  Actual: \" << actual_predicate_value;\r\n\r\n  if (actual_message[0] != '\\0') {\r\n    msg << \" (\" << actual_message << \")\";\r\n  }\r\n\r\n  msg << \"\\nExpected: \" << expected_predicate_value;\r\n  return msg.GetString();\r\n}\r\n\r\n// Helper function for implementing ASSERT_NEAR.\r\nAssertionResult DoubleNearPredFormat(const char* expr1,\r\n                                     const char* expr2,\r\n                                     const char* abs_error_expr,\r\n                                     double val1,\r\n                                     double val2,\r\n                                     double abs_error) {\r\n  const double diff = fabs(val1 - val2);\r\n\r\n  if (diff <= abs_error) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  // TODO(wan): do not print the value of an expression if it's\r\n  // already a literal.\r\n  return AssertionFailure()\r\n         << \"The difference between \" << expr1 << \" and \" << expr2\r\n         << \" is \" << diff << \", which exceeds \" << abs_error_expr << \", where\\n\"\r\n         << expr1 << \" evaluates to \" << val1 << \",\\n\"\r\n         << expr2 << \" evaluates to \" << val2 << \", and\\n\"\r\n         << abs_error_expr << \" evaluates to \" << abs_error << \".\";\r\n}\r\n\r\n\r\n// Helper template for implementing FloatLE() and DoubleLE().\r\ntemplate <typename RawType>\r\nAssertionResult FloatingPointLE(const char* expr1,\r\n                                const char* expr2,\r\n                                RawType val1,\r\n                                RawType val2) {\r\n  // Returns success if val1 is less than val2,\r\n  if (val1 < val2) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  // or if val1 is almost equal to val2.\r\n  const FloatingPoint<RawType> lhs(val1), rhs(val2);\r\n\r\n  if (lhs.AlmostEquals(rhs)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  // Note that the above two checks will both fail if either val1 or\r\n  // val2 is NaN, as the IEEE floating-point standard requires that\r\n  // any predicate involving a NaN must return false.\r\n\r\n  ::std::stringstream val1_ss;\r\n  val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\r\n          << val1;\r\n\r\n  ::std::stringstream val2_ss;\r\n  val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2)\r\n          << val2;\r\n\r\n  return AssertionFailure()\r\n         << \"Expected: (\" << expr1 << \") <= (\" << expr2 << \")\\n\"\r\n         << \"  Actual: \" << StringStreamToString(&val1_ss) << \" vs \"\r\n         << StringStreamToString(&val2_ss);\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\r\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\r\nAssertionResult FloatLE(const char* expr1, const char* expr2,\r\n                        float val1, float val2) {\r\n  return internal::FloatingPointLE<float>(expr1, expr2, val1, val2);\r\n}\r\n\r\n// Asserts that val1 is less than, or almost equal to, val2.  Fails\r\n// otherwise.  In particular, it fails if either val1 or val2 is NaN.\r\nAssertionResult DoubleLE(const char* expr1, const char* expr2,\r\n                         double val1, double val2) {\r\n  return internal::FloatingPointLE<double>(expr1, expr2, val1, val2);\r\n}\r\n\r\nnamespace internal {\r\n\r\n// The helper function for {ASSERT|EXPECT}_EQ with int or enum\r\n// arguments.\r\nAssertionResult CmpHelperEQ(const char* expected_expression,\r\n                            const char* actual_expression,\r\n                            BiggestInt expected,\r\n                            BiggestInt actual) {\r\n  if (expected == actual) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   FormatForComparisonFailureMessage(expected, actual),\r\n                   FormatForComparisonFailureMessage(actual, expected),\r\n                   false);\r\n}\r\n\r\n// A macro for implementing the helper functions needed to implement\r\n// ASSERT_?? and EXPECT_?? with integer or enum arguments.  It is here\r\n// just to avoid copy-and-paste of similar code.\r\n#define GTEST_IMPL_CMP_HELPER_(op_name, op)\\\r\nAssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \\\r\n                                   BiggestInt val1, BiggestInt val2) {\\\r\n  if (val1 op val2) {\\\r\n    return AssertionSuccess();\\\r\n  } else {\\\r\n    return AssertionFailure() \\\r\n        << \"Expected: (\" << expr1 << \") \" #op \" (\" << expr2\\\r\n        << \"), actual: \" << FormatForComparisonFailureMessage(val1, val2)\\\r\n        << \" vs \" << FormatForComparisonFailureMessage(val2, val1);\\\r\n  }\\\r\n}\r\n\r\n// Implements the helper function for {ASSERT|EXPECT}_NE with int or\r\n// enum arguments.\r\nGTEST_IMPL_CMP_HELPER_(NE, != )\r\n// Implements the helper function for {ASSERT|EXPECT}_LE with int or\r\n// enum arguments.\r\nGTEST_IMPL_CMP_HELPER_(LE, <= )\r\n// Implements the helper function for {ASSERT|EXPECT}_LT with int or\r\n// enum arguments.\r\nGTEST_IMPL_CMP_HELPER_(LT, < )\r\n// Implements the helper function for {ASSERT|EXPECT}_GE with int or\r\n// enum arguments.\r\nGTEST_IMPL_CMP_HELPER_(GE, >= )\r\n// Implements the helper function for {ASSERT|EXPECT}_GT with int or\r\n// enum arguments.\r\nGTEST_IMPL_CMP_HELPER_(GT, > )\r\n\r\n#undef GTEST_IMPL_CMP_HELPER_\r\n\r\n// The helper function for {ASSERT|EXPECT}_STREQ.\r\nAssertionResult CmpHelperSTREQ(const char* expected_expression,\r\n                               const char* actual_expression,\r\n                               const char* expected,\r\n                               const char* actual) {\r\n  if (String::CStringEquals(expected, actual)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   PrintToString(expected),\r\n                   PrintToString(actual),\r\n                   false);\r\n}\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRCASEEQ.\r\nAssertionResult CmpHelperSTRCASEEQ(const char* expected_expression,\r\n                                   const char* actual_expression,\r\n                                   const char* expected,\r\n                                   const char* actual) {\r\n  if (String::CaseInsensitiveCStringEquals(expected, actual)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   PrintToString(expected),\r\n                   PrintToString(actual),\r\n                   true);\r\n}\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRNE.\r\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\r\n                               const char* s2_expression,\r\n                               const char* s1,\r\n                               const char* s2) {\r\n  if (!String::CStringEquals(s1, s2)) {\r\n    return AssertionSuccess();\r\n  }\r\n  else {\r\n    return AssertionFailure() << \"Expected: (\" << s1_expression << \") != (\"\r\n           << s2_expression << \"), actual: \\\"\"\r\n           << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\r\n  }\r\n}\r\n\r\n// The helper function for {ASSERT|EXPECT}_STRCASENE.\r\nAssertionResult CmpHelperSTRCASENE(const char* s1_expression,\r\n                                   const char* s2_expression,\r\n                                   const char* s1,\r\n                                   const char* s2) {\r\n  if (!String::CaseInsensitiveCStringEquals(s1, s2)) {\r\n    return AssertionSuccess();\r\n  }\r\n  else {\r\n    return AssertionFailure()\r\n           << \"Expected: (\" << s1_expression << \") != (\"\r\n           << s2_expression << \") (ignoring case), actual: \\\"\"\r\n           << s1 << \"\\\" vs \\\"\" << s2 << \"\\\"\";\r\n  }\r\n}\r\n\r\n}  // namespace internal\r\n\r\nnamespace {\r\n\r\n// Helper functions for implementing IsSubString() and IsNotSubstring().\r\n\r\n// This group of overloaded functions return true iff needle is a\r\n// substring of haystack.  NULL is considered a substring of itself\r\n// only.\r\n\r\nbool IsSubstringPred(const char* needle, const char* haystack) {\r\n  if (needle == NULL || haystack == NULL) {\r\n    return needle == haystack;\r\n  }\r\n\r\n  return strstr(haystack, needle) != NULL;\r\n}\r\n\r\nbool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {\r\n  if (needle == NULL || haystack == NULL) {\r\n    return needle == haystack;\r\n  }\r\n\r\n  return wcsstr(haystack, needle) != NULL;\r\n}\r\n\r\n// StringType here can be either ::std::string or ::std::wstring.\r\ntemplate <typename StringType>\r\nbool IsSubstringPred(const StringType& needle,\r\n                     const StringType& haystack) {\r\n  return haystack.find(needle) != StringType::npos;\r\n}\r\n\r\n// This function implements either IsSubstring() or IsNotSubstring(),\r\n// depending on the value of the expected_to_be_substring parameter.\r\n// StringType here can be const char*, const wchar_t*, ::std::string,\r\n// or ::std::wstring.\r\ntemplate <typename StringType>\r\nAssertionResult IsSubstringImpl(\r\n  bool expected_to_be_substring,\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const StringType& needle, const StringType& haystack) {\r\n  if (IsSubstringPred(needle, haystack) == expected_to_be_substring) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  const bool is_wide_string = sizeof(needle[0]) > 1;\r\n  const char* const begin_string_quote = is_wide_string ? \"L\\\"\" : \"\\\"\";\r\n  return AssertionFailure()\r\n         << \"Value of: \" << needle_expr << \"\\n\"\r\n         << \"  Actual: \" << begin_string_quote << needle << \"\\\"\\n\"\r\n         << \"Expected: \" << (expected_to_be_substring ? \"\" : \"not \")\r\n         << \"a substring of \" << haystack_expr << \"\\n\"\r\n         << \"Which is: \" << begin_string_quote << haystack << \"\\\"\";\r\n}\r\n\r\n}  // namespace\r\n\r\n// IsSubstring() and IsNotSubstring() check whether needle is a\r\n// substring of haystack (NULL is considered a substring of itself\r\n// only), and return an appropriate error message when they fail.\r\n\r\nAssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const char* needle, const char* haystack) {\r\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const wchar_t* needle, const wchar_t* haystack) {\r\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const char* needle, const char* haystack) {\r\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const wchar_t* needle, const wchar_t* haystack) {\r\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::string& needle, const ::std::string& haystack) {\r\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::string& needle, const ::std::string& haystack) {\r\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\n#if GTEST_HAS_STD_WSTRING\r\nAssertionResult IsSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::wstring& needle, const ::std::wstring& haystack) {\r\n  return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n\r\nAssertionResult IsNotSubstring(\r\n  const char* needle_expr, const char* haystack_expr,\r\n  const ::std::wstring& needle, const ::std::wstring& haystack) {\r\n  return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);\r\n}\r\n#endif  // GTEST_HAS_STD_WSTRING\r\n\r\nnamespace internal {\r\n\r\n#if GTEST_OS_WINDOWS\r\n\r\nnamespace {\r\n\r\n// Helper function for IsHRESULT{SuccessFailure} predicates\r\nAssertionResult HRESULTFailureHelper(const char* expr,\r\n                                     const char* expected,\r\n                                     long hr) {  // NOLINT\r\n# if GTEST_OS_WINDOWS_MOBILE\r\n\r\n  // Windows CE doesn't support FormatMessage.\r\n  const char error_text[] = \"\";\r\n\r\n# else\r\n\r\n  // Looks up the human-readable system message for the HRESULT code\r\n  // and since we're not passing any params to FormatMessage, we don't\r\n  // want inserts expanded.\r\n  const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM |\r\n                       FORMAT_MESSAGE_IGNORE_INSERTS;\r\n  const DWORD kBufSize = 4096;\r\n  // Gets the system's human readable message string for this HRESULT.\r\n  char error_text[kBufSize] = { '\\0' };\r\n  DWORD message_length = ::FormatMessageA(kFlags,\r\n                                          0,  // no source, we're asking system\r\n                                          hr,  // the error\r\n                                          0,  // no line width restrictions\r\n                                          error_text,  // output buffer\r\n                                          kBufSize,  // buf size\r\n                                          NULL);  // no arguments for inserts\r\n\r\n  // Trims tailing white space (FormatMessage leaves a trailing CR-LF)\r\n  for (; message_length && IsSpace(error_text[message_length - 1]);\r\n       --message_length) {\r\n    error_text[message_length - 1] = '\\0';\r\n  }\r\n\r\n# endif  // GTEST_OS_WINDOWS_MOBILE\r\n\r\n  const std::string error_hex(\"0x\" + String::FormatHexInt(hr));\r\n  return ::testing::AssertionFailure()\r\n         << \"Expected: \" << expr << \" \" << expected << \".\\n\"\r\n         << \"  Actual: \" << error_hex << \" \" << error_text << \"\\n\";\r\n}\r\n\r\n}  // namespace\r\n\r\nAssertionResult IsHRESULTSuccess(const char* expr, long hr) {  // NOLINT\r\n  if (SUCCEEDED(hr)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return HRESULTFailureHelper(expr, \"succeeds\", hr);\r\n}\r\n\r\nAssertionResult IsHRESULTFailure(const char* expr, long hr) {  // NOLINT\r\n  if (FAILED(hr)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return HRESULTFailureHelper(expr, \"fails\", hr);\r\n}\r\n\r\n#endif  // GTEST_OS_WINDOWS\r\n\r\n// Utility functions for encoding Unicode text (wide strings) in\r\n// UTF-8.\r\n\r\n// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8\r\n// like this:\r\n//\r\n// Code-point length   Encoding\r\n//   0 -  7 bits       0xxxxxxx\r\n//   8 - 11 bits       110xxxxx 10xxxxxx\r\n//  12 - 16 bits       1110xxxx 10xxxxxx 10xxxxxx\r\n//  17 - 21 bits       11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\r\n\r\n// The maximum code-point a one-byte UTF-8 sequence can represent.\r\nconst UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) <<  7) - 1;\r\n\r\n// The maximum code-point a two-byte UTF-8 sequence can represent.\r\nconst UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1;\r\n\r\n// The maximum code-point a three-byte UTF-8 sequence can represent.\r\nconst UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2 * 6)) - 1;\r\n\r\n// The maximum code-point a four-byte UTF-8 sequence can represent.\r\nconst UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3 * 6)) - 1;\r\n\r\n// Chops off the n lowest bits from a bit pattern.  Returns the n\r\n// lowest bits.  As a side effect, the original bit pattern will be\r\n// shifted to the right by n bits.\r\ninline UInt32 ChopLowBits(UInt32* bits, int n) {\r\n  const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1);\r\n  *bits >>= n;\r\n  return low_bits;\r\n}\r\n\r\n// Converts a Unicode code point to a narrow string in UTF-8 encoding.\r\n// code_point parameter is of type UInt32 because wchar_t may not be\r\n// wide enough to contain a code point.\r\n// If the code_point is not a valid Unicode code point\r\n// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted\r\n// to \"(Invalid Unicode 0xXXXXXXXX)\".\r\nstd::string CodePointToUtf8(UInt32 code_point) {\r\n  if (code_point > kMaxCodePoint4) {\r\n    return \"(Invalid Unicode 0x\" + String::FormatHexInt(code_point) + \")\";\r\n  }\r\n\r\n  char str[5];  // Big enough for the largest valid code point.\r\n\r\n  if (code_point <= kMaxCodePoint1) {\r\n    str[1] = '\\0';\r\n    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx\r\n  }\r\n  else if (code_point <= kMaxCodePoint2) {\r\n    str[2] = '\\0';\r\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx\r\n  }\r\n  else if (code_point <= kMaxCodePoint3) {\r\n    str[3] = '\\0';\r\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx\r\n  }\r\n  else {    // code_point <= kMaxCodePoint4\r\n    str[4] = '\\0';\r\n    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx\r\n    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx\r\n  }\r\n\r\n  return str;\r\n}\r\n\r\n// The following two functions only make sense if the the system\r\n// uses UTF-16 for wide string encoding. All supported systems\r\n// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.\r\n\r\n// Determines if the arguments constitute UTF-16 surrogate pair\r\n// and thus should be combined into a single Unicode code point\r\n// using CreateCodePointFromUtf16SurrogatePair.\r\ninline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {\r\n  return sizeof(wchar_t) == 2 &&\r\n         (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;\r\n}\r\n\r\n// Creates a Unicode code point from UTF16 surrogate pair.\r\ninline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,\r\n    wchar_t second) {\r\n  const UInt32 mask = (1 << 10) - 1;\r\n  return (sizeof(wchar_t) == 2) ?\r\n         (((first & mask) << 10) | (second & mask)) + 0x10000 :\r\n         // This function should not be called when the condition is\r\n         // false, but we provide a sensible default in case it is.\r\n         static_cast<UInt32>(first);\r\n}\r\n\r\n// Converts a wide string to a narrow string in UTF-8 encoding.\r\n// The wide string is assumed to have the following encoding:\r\n//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)\r\n//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)\r\n// Parameter str points to a null-terminated wide string.\r\n// Parameter num_chars may additionally limit the number\r\n// of wchar_t characters processed. -1 is used when the entire string\r\n// should be processed.\r\n// If the string contains code points that are not valid Unicode code points\r\n// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output\r\n// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding\r\n// and contains invalid UTF-16 surrogate pairs, values in those pairs\r\n// will be encoded as individual Unicode characters from Basic Normal Plane.\r\nstd::string WideStringToUtf8(const wchar_t* str, int num_chars) {\r\n  if (num_chars == -1) {\r\n    num_chars = static_cast<int>(wcslen(str));\r\n  }\r\n\r\n  ::std::stringstream stream;\r\n\r\n  for (int i = 0; i < num_chars; ++i) {\r\n    UInt32 unicode_code_point;\r\n\r\n    if (str[i] == L'\\0') {\r\n      break;\r\n    }\r\n    else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {\r\n      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],\r\n                           str[i + 1]);\r\n      i++;\r\n    }\r\n    else {\r\n      unicode_code_point = static_cast<UInt32>(str[i]);\r\n    }\r\n\r\n    stream << CodePointToUtf8(unicode_code_point);\r\n  }\r\n\r\n  return StringStreamToString(&stream);\r\n}\r\n\r\n// Converts a wide C string to an std::string using the UTF-8 encoding.\r\n// NULL will be converted to \"(null)\".\r\nstd::string String::ShowWideCString(const wchar_t* wide_c_str) {\r\n  if (wide_c_str == NULL) {\r\n    return \"(null)\";\r\n  }\r\n\r\n  return internal::WideStringToUtf8(wide_c_str, -1);\r\n}\r\n\r\n// Compares two wide C strings.  Returns true iff they have the same\r\n// content.\r\n//\r\n// Unlike wcscmp(), this function can handle NULL argument(s).  A NULL\r\n// C string is considered different to any non-NULL C string,\r\n// including the empty string.\r\nbool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {\r\n  if (lhs == NULL) {\r\n    return rhs == NULL;\r\n  }\r\n\r\n  if (rhs == NULL) {\r\n    return false;\r\n  }\r\n\r\n  return wcscmp(lhs, rhs) == 0;\r\n}\r\n\r\n// Helper function for *_STREQ on wide strings.\r\nAssertionResult CmpHelperSTREQ(const char* expected_expression,\r\n                               const char* actual_expression,\r\n                               const wchar_t* expected,\r\n                               const wchar_t* actual) {\r\n  if (String::WideCStringEquals(expected, actual)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return EqFailure(expected_expression,\r\n                   actual_expression,\r\n                   PrintToString(expected),\r\n                   PrintToString(actual),\r\n                   false);\r\n}\r\n\r\n// Helper function for *_STRNE on wide strings.\r\nAssertionResult CmpHelperSTRNE(const char* s1_expression,\r\n                               const char* s2_expression,\r\n                               const wchar_t* s1,\r\n                               const wchar_t* s2) {\r\n  if (!String::WideCStringEquals(s1, s2)) {\r\n    return AssertionSuccess();\r\n  }\r\n\r\n  return AssertionFailure() << \"Expected: (\" << s1_expression << \") != (\"\r\n         << s2_expression << \"), actual: \"\r\n         << PrintToString(s1)\r\n         << \" vs \" << PrintToString(s2);\r\n}\r\n\r\n// Compares two C strings, ignoring case.  Returns true iff they have\r\n// the same content.\r\n//\r\n// Unlike strcasecmp(), this function can handle NULL argument(s).  A\r\n// NULL C string is considered different to any non-NULL C string,\r\n// including the empty string.\r\nbool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {\r\n  if (lhs == NULL) {\r\n    return rhs == NULL;\r\n  }\r\n\r\n  if (rhs == NULL) {\r\n    return false;\r\n  }\r\n\r\n  return posix::StrCaseCmp(lhs, rhs) == 0;\r\n}\r\n\r\n// Compares two wide C strings, ignoring case.  Returns true iff they\r\n// have the same content.\r\n//\r\n// Unlike wcscasecmp(), this function can handle NULL argument(s).\r\n// A NULL C string is considered different to any non-NULL wide C string,\r\n// including the empty string.\r\n// NB: The implementations on different platforms slightly differ.\r\n// On windows, this method uses _wcsicmp which compares according to LC_CTYPE\r\n// environment variable. On GNU platform this method uses wcscasecmp\r\n// which compares according to LC_CTYPE category of the current locale.\r\n// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the\r\n// current locale.\r\nbool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,\r\n    const wchar_t* rhs) {\r\n  if (lhs == NULL) {\r\n    return rhs == NULL;\r\n  }\r\n\r\n  if (rhs == NULL) {\r\n    return false;\r\n  }\r\n\r\n#if GTEST_OS_WINDOWS\r\n  return _wcsicmp(lhs, rhs) == 0;\r\n#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID\r\n  return wcscasecmp(lhs, rhs) == 0;\r\n#else\r\n  // Android, Mac OS X and Cygwin don't define wcscasecmp.\r\n  // Other unknown OSes may not define it either.\r\n  wint_t left, right;\r\n\r\n  do {\r\n    left = towlower(*lhs++);\r\n    right = towlower(*rhs++);\r\n  }\r\n  while (left && left == right);\r\n\r\n  return left == right;\r\n#endif  // OS selector\r\n}\r\n\r\n// Returns true iff str ends with the given suffix, ignoring case.\r\n// Any string is considered to end with an empty suffix.\r\nbool String::EndsWithCaseInsensitive(\r\n  const std::string& str, const std::string& suffix) {\r\n  const size_t str_len = str.length();\r\n  const size_t suffix_len = suffix.length();\r\n  return (str_len >= suffix_len) &&\r\n         CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len,\r\n                                      suffix.c_str());\r\n}\r\n\r\n// Formats an int value as \"%02d\".\r\nstd::string String::FormatIntWidth2(int value) {\r\n  std::stringstream ss;\r\n  ss << std::setfill('0') << std::setw(2) << value;\r\n  return ss.str();\r\n}\r\n\r\n// Formats an int value as \"%X\".\r\nstd::string String::FormatHexInt(int value) {\r\n  std::stringstream ss;\r\n  ss << std::hex << std::uppercase << value;\r\n  return ss.str();\r\n}\r\n\r\n// Formats a byte as \"%02X\".\r\nstd::string String::FormatByte(unsigned char value) {\r\n  std::stringstream ss;\r\n  ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase\r\n     << static_cast<unsigned int>(value);\r\n  return ss.str();\r\n}\r\n\r\n// Converts the buffer in a stringstream to an std::string, converting NUL\r\n// bytes to \"\\\\0\" along the way.\r\nstd::string StringStreamToString(::std::stringstream* ss) {\r\n  const ::std::string& str = ss->str();\r\n  const char* const start = str.c_str();\r\n  const char* const end = start + str.length();\r\n\r\n  std::string result;\r\n  result.reserve(2 * (end - start));\r\n\r\n  for (const char* ch = start; ch != end; ++ch) {\r\n    if (*ch == '\\0') {\r\n      result += \"\\\\0\";  // Replaces NUL with \"\\\\0\";\r\n    }\r\n    else {\r\n      result += *ch;\r\n    }\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\n// Appends the user-supplied message to the Google-Test-generated message.\r\nstd::string AppendUserMessage(const std::string& gtest_msg,\r\n                              const Message& user_msg) {\r\n  // Appends the user message if it's non-empty.\r\n  const std::string user_msg_string = user_msg.GetString();\r\n\r\n  if (user_msg_string.empty()) {\r\n    return gtest_msg;\r\n  }\r\n\r\n  return gtest_msg + \"\\n\" + user_msg_string;\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// class TestResult\r\n\r\n// Creates an empty TestResult.\r\nTestResult::TestResult()\r\n  : death_test_count_(0),\r\n    elapsed_time_(0) {\r\n}\r\n\r\n// D'tor.\r\nTestResult::~TestResult() {\r\n}\r\n\r\n// Returns the i-th test part result among all the results. i can\r\n// range from 0 to total_part_count() - 1. If i is not in that range,\r\n// aborts the program.\r\nconst TestPartResult& TestResult::GetTestPartResult(int i) const {\r\n  if (i < 0 || i >= total_part_count()) {\r\n    internal::posix::Abort();\r\n  }\r\n\r\n  return test_part_results_.at(i);\r\n}\r\n\r\n// Returns the i-th test property. i can range from 0 to\r\n// test_property_count() - 1. If i is not in that range, aborts the\r\n// program.\r\nconst TestProperty& TestResult::GetTestProperty(int i) const {\r\n  if (i < 0 || i >= test_property_count()) {\r\n    internal::posix::Abort();\r\n  }\r\n\r\n  return test_properties_.at(i);\r\n}\r\n\r\n// Clears the test part results.\r\nvoid TestResult::ClearTestPartResults() {\r\n  test_part_results_.clear();\r\n}\r\n\r\n// Adds a test part result to the list.\r\nvoid TestResult::AddTestPartResult(const TestPartResult& test_part_result) {\r\n  test_part_results_.push_back(test_part_result);\r\n}\r\n\r\n// Adds a test property to the list. If a property with the same key as the\r\n// supplied property is already represented, the value of this test_property\r\n// replaces the old value for that key.\r\nvoid TestResult::RecordProperty(const std::string& xml_element,\r\n                                const TestProperty& test_property) {\r\n  if (!ValidateTestProperty(xml_element, test_property)) {\r\n    return;\r\n  }\r\n\r\n  internal::MutexLock lock(&test_properites_mutex_);\r\n  const std::vector<TestProperty>::iterator property_with_matching_key =\r\n    std::find_if(test_properties_.begin(), test_properties_.end(),\r\n                 internal::TestPropertyKeyIs(test_property.key()));\r\n\r\n  if (property_with_matching_key == test_properties_.end()) {\r\n    test_properties_.push_back(test_property);\r\n    return;\r\n  }\r\n\r\n  property_with_matching_key->SetValue(test_property.value());\r\n}\r\n\r\n// The list of reserved attributes used in the <testsuites> element of XML\r\n// output.\r\nstatic const char* const kReservedTestSuitesAttributes[] = {\r\n  \"disabled\",\r\n  \"errors\",\r\n  \"failures\",\r\n  \"name\",\r\n  \"random_seed\",\r\n  \"tests\",\r\n  \"time\",\r\n  \"timestamp\"\r\n};\r\n\r\n// The list of reserved attributes used in the <testsuite> element of XML\r\n// output.\r\nstatic const char* const kReservedTestSuiteAttributes[] = {\r\n  \"disabled\",\r\n  \"errors\",\r\n  \"failures\",\r\n  \"name\",\r\n  \"tests\",\r\n  \"time\"\r\n};\r\n\r\n// The list of reserved attributes used in the <testcase> element of XML output.\r\nstatic const char* const kReservedTestCaseAttributes[] = {\r\n  \"classname\",\r\n  \"name\",\r\n  \"status\",\r\n  \"time\",\r\n  \"type_param\",\r\n  \"value_param\"\r\n};\r\n\r\ntemplate <int kSize>\r\nstd::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {\r\n  return std::vector<std::string>(array, array + kSize);\r\n}\r\n\r\nstatic std::vector<std::string> GetReservedAttributesForElement(\r\n  const std::string& xml_element) {\r\n  if (xml_element == \"testsuites\") {\r\n    return ArrayAsVector(kReservedTestSuitesAttributes);\r\n  }\r\n  else if (xml_element == \"testsuite\") {\r\n    return ArrayAsVector(kReservedTestSuiteAttributes);\r\n  }\r\n  else if (xml_element == \"testcase\") {\r\n    return ArrayAsVector(kReservedTestCaseAttributes);\r\n  }\r\n  else {\r\n    GTEST_CHECK_(false) << \"Unrecognized xml_element provided: \" << xml_element;\r\n  }\r\n\r\n  // This code is unreachable but some compilers may not realizes that.\r\n  return std::vector<std::string>();\r\n}\r\n\r\nstatic std::string FormatWordList(const std::vector<std::string>& words) {\r\n  Message word_list;\r\n\r\n  for (size_t i = 0; i < words.size(); ++i) {\r\n    if (i > 0 && words.size() > 2) {\r\n      word_list << \", \";\r\n    }\r\n\r\n    if (i == words.size() - 1) {\r\n      word_list << \"and \";\r\n    }\r\n\r\n    word_list << \"'\" << words[i] << \"'\";\r\n  }\r\n\r\n  return word_list.GetString();\r\n}\r\n\r\nbool ValidateTestPropertyName(const std::string& property_name,\r\n                              const std::vector<std::string>& reserved_names) {\r\n  if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=\r\n      reserved_names.end()) {\r\n    ADD_FAILURE() << \"Reserved key used in RecordProperty(): \" << property_name\r\n                  << \" (\" << FormatWordList(reserved_names)\r\n                  << \" are reserved by \" << GTEST_NAME_ << \")\";\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\n// Adds a failure if the key is a reserved attribute of the element named\r\n// xml_element.  Returns true if the property is valid.\r\nbool TestResult::ValidateTestProperty(const std::string& xml_element,\r\n                                      const TestProperty& test_property) {\r\n  return ValidateTestPropertyName(test_property.key(),\r\n                                  GetReservedAttributesForElement(xml_element));\r\n}\r\n\r\n// Clears the object.\r\nvoid TestResult::Clear() {\r\n  test_part_results_.clear();\r\n  test_properties_.clear();\r\n  death_test_count_ = 0;\r\n  elapsed_time_ = 0;\r\n}\r\n\r\n// Returns true iff the test failed.\r\nbool TestResult::Failed() const {\r\n  for (int i = 0; i < total_part_count(); ++i) {\r\n    if (GetTestPartResult(i).failed()) {\r\n      return true;\r\n    }\r\n  }\r\n\r\n  return false;\r\n}\r\n\r\n// Returns true iff the test part fatally failed.\r\nstatic bool TestPartFatallyFailed(const TestPartResult& result) {\r\n  return result.fatally_failed();\r\n}\r\n\r\n// Returns true iff the test fatally failed.\r\nbool TestResult::HasFatalFailure() const {\r\n  return CountIf(test_part_results_, TestPartFatallyFailed) > 0;\r\n}\r\n\r\n// Returns true iff the test part non-fatally failed.\r\nstatic bool TestPartNonfatallyFailed(const TestPartResult& result) {\r\n  return result.nonfatally_failed();\r\n}\r\n\r\n// Returns true iff the test has a non-fatal failure.\r\nbool TestResult::HasNonfatalFailure() const {\r\n  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;\r\n}\r\n\r\n// Gets the number of all test parts.  This is the sum of the number\r\n// of successful test parts and the number of failed test parts.\r\nint TestResult::total_part_count() const {\r\n  return static_cast<int>(test_part_results_.size());\r\n}\r\n\r\n// Returns the number of the test properties.\r\nint TestResult::test_property_count() const {\r\n  return static_cast<int>(test_properties_.size());\r\n}\r\n\r\n// class Test\r\n\r\n// Creates a Test object.\r\n\r\n// The c'tor saves the values of all Google Test flags.\r\nTest::Test()\r\n  : gtest_flag_saver_(new internal::GTestFlagSaver) {\r\n}\r\n\r\n// The d'tor restores the values of all Google Test flags.\r\nTest::~Test() {\r\n  delete gtest_flag_saver_;\r\n}\r\n\r\n// Sets up the test fixture.\r\n//\r\n// A sub-class may override this.\r\nvoid Test::SetUp() {\r\n}\r\n\r\n// Tears down the test fixture.\r\n//\r\n// A sub-class may override this.\r\nvoid Test::TearDown() {\r\n}\r\n\r\n// Allows user supplied key value pairs to be recorded for later output.\r\nvoid Test::RecordProperty(const std::string& key, const std::string& value) {\r\n  UnitTest::GetInstance()->RecordProperty(key, value);\r\n}\r\n\r\n// Allows user supplied key value pairs to be recorded for later output.\r\nvoid Test::RecordProperty(const std::string& key, int value) {\r\n  Message value_message;\r\n  value_message << value;\r\n  RecordProperty(key, value_message.GetString().c_str());\r\n}\r\n\r\nnamespace internal {\r\n\r\nvoid ReportFailureInUnknownLocation(TestPartResult::Type result_type,\r\n                                    const std::string& message) {\r\n  // This function is a friend of UnitTest and as such has access to\r\n  // AddTestPartResult.\r\n  UnitTest::GetInstance()->AddTestPartResult(\r\n    result_type,\r\n    NULL,  // No info about the source file where the exception occurred.\r\n    -1,    // We have no info on which line caused the exception.\r\n    message,\r\n    \"\");   // No stack trace, either.\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// Google Test requires all tests in the same test case to use the same test\r\n// fixture class.  This function checks if the current test has the\r\n// same fixture class as the first test in the current test case.  If\r\n// yes, it returns true; otherwise it generates a Google Test failure and\r\n// returns false.\r\nbool Test::HasSameFixtureClass() {\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n  const TestCase* const test_case = impl->current_test_case();\r\n\r\n  // Info about the first test in the current test case.\r\n  const TestInfo* const first_test_info = test_case->test_info_list()[0];\r\n  const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;\r\n  const char* const first_test_name = first_test_info->name();\r\n\r\n  // Info about the current test.\r\n  const TestInfo* const this_test_info = impl->current_test_info();\r\n  const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_;\r\n  const char* const this_test_name = this_test_info->name();\r\n\r\n  if (this_fixture_id != first_fixture_id) {\r\n    // Is the first test defined using TEST?\r\n    const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId();\r\n    // Is this test defined using TEST?\r\n    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();\r\n\r\n    if (first_is_TEST || this_is_TEST) {\r\n      // The user mixed TEST and TEST_F in this test case - we'll tell\r\n      // him/her how to fix it.\r\n\r\n      // Gets the name of the TEST and the name of the TEST_F.  Note\r\n      // that first_is_TEST and this_is_TEST cannot both be true, as\r\n      // the fixture IDs are different for the two tests.\r\n      const char* const TEST_name =\r\n        first_is_TEST ? first_test_name : this_test_name;\r\n      const char* const TEST_F_name =\r\n        first_is_TEST ? this_test_name : first_test_name;\r\n\r\n      ADD_FAILURE()\r\n          << \"All tests in the same test case must use the same test fixture\\n\"\r\n          << \"class, so mixing TEST_F and TEST in the same test case is\\n\"\r\n          << \"illegal.  In test case \" << this_test_info->test_case_name()\r\n          << \",\\n\"\r\n          << \"test \" << TEST_F_name << \" is defined using TEST_F but\\n\"\r\n          << \"test \" << TEST_name << \" is defined using TEST.  You probably\\n\"\r\n          << \"want to change the TEST to TEST_F or move it to another test\\n\"\r\n          << \"case.\";\r\n    }\r\n    else {\r\n      // The user defined two fixture classes with the same name in\r\n      // two namespaces - we'll tell him/her how to fix it.\r\n      ADD_FAILURE()\r\n          << \"All tests in the same test case must use the same test fixture\\n\"\r\n          << \"class.  However, in test case \"\r\n          << this_test_info->test_case_name() << \",\\n\"\r\n          << \"you defined test \" << first_test_name\r\n          << \" and test \" << this_test_name << \"\\n\"\r\n          << \"using two different test fixture classes.  This can happen if\\n\"\r\n          << \"the two classes are from different namespaces or translation\\n\"\r\n          << \"units and have the same name.  You should probably rename one\\n\"\r\n          << \"of the classes to put the tests into different test cases.\";\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\n#if GTEST_HAS_SEH\r\n\r\n// Adds an \"exception thrown\" fatal failure to the current test.  This\r\n// function returns its result via an output parameter pointer because VC++\r\n// prohibits creation of objects with destructors on stack in functions\r\n// using __try (see error C2712).\r\nstatic std::string* FormatSehExceptionMessage(DWORD exception_code,\r\n    const char* location) {\r\n  Message message;\r\n  message << \"SEH exception with code 0x\" << std::setbase(16) <<\r\n          exception_code << std::setbase(10) << \" thrown in \" << location << \".\";\r\n\r\n  return new std::string(message.GetString());\r\n}\r\n\r\n#endif  // GTEST_HAS_SEH\r\n\r\nnamespace internal {\r\n\r\n#if GTEST_HAS_EXCEPTIONS\r\n\r\n// Adds an \"exception thrown\" fatal failure to the current test.\r\nstatic std::string FormatCxxExceptionMessage(const char* description,\r\n    const char* location) {\r\n  Message message;\r\n\r\n  if (description != NULL) {\r\n    message << \"C++ exception with description \\\"\" << description << \"\\\"\";\r\n  }\r\n  else {\r\n    message << \"Unknown C++ exception\";\r\n  }\r\n\r\n  message << \" thrown in \" << location << \".\";\r\n\r\n  return message.GetString();\r\n}\r\n\r\nstatic std::string PrintTestPartResultToString(\r\n  const TestPartResult& test_part_result);\r\n\r\nGoogleTestFailureException::GoogleTestFailureException(\r\n  const TestPartResult& failure)\r\n  : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}\r\n\r\n#endif  // GTEST_HAS_EXCEPTIONS\r\n\r\n// We put these helper functions in the internal namespace as IBM's xlC\r\n// compiler rejects the code if they were declared static.\r\n\r\n// Runs the given method and handles SEH exceptions it throws, when\r\n// SEH is supported; returns the 0-value for type Result in case of an\r\n// SEH exception.  (Microsoft compilers cannot handle SEH and C++\r\n// exceptions in the same function.  Therefore, we provide a separate\r\n// wrapper function for handling SEH exceptions.)\r\ntemplate <class T, typename Result>\r\nResult HandleSehExceptionsInMethodIfSupported(\r\n  T* object, Result (T::*method)(), const char* location) {\r\n#if GTEST_HAS_SEH\r\n\r\n  __try {\r\n    return (object->*method)();\r\n  }\r\n  __except (internal::UnitTestOptions::GTestShouldProcessSEH(    // NOLINT\r\n              GetExceptionCode())) {\r\n    // We create the exception message on the heap because VC++ prohibits\r\n    // creation of objects with destructors on stack in functions using __try\r\n    // (see error C2712).\r\n    std::string* exception_message = FormatSehExceptionMessage(\r\n                                       GetExceptionCode(), location);\r\n    internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,\r\n        *exception_message);\r\n    delete exception_message;\r\n    return static_cast<Result>(0);\r\n  }\r\n\r\n#else\r\n  (void)location;\r\n  return (object->*method)();\r\n#endif  // GTEST_HAS_SEH\r\n}\r\n\r\n// Runs the given method and catches and reports C++ and/or SEH-style\r\n// exceptions, if they are supported; returns the 0-value for type\r\n// Result in case of an SEH exception.\r\ntemplate <class T, typename Result>\r\nResult HandleExceptionsInMethodIfSupported(\r\n  T* object, Result (T::*method)(), const char* location) {\r\n  // NOTE: The user code can affect the way in which Google Test handles\r\n  // exceptions by setting GTEST_FLAG(catch_exceptions), but only before\r\n  // RUN_ALL_TESTS() starts. It is technically possible to check the flag\r\n  // after the exception is caught and either report or re-throw the\r\n  // exception based on the flag's value:\r\n  //\r\n  // try {\r\n  //   // Perform the test method.\r\n  // } catch (...) {\r\n  //   if (GTEST_FLAG(catch_exceptions))\r\n  //     // Report the exception as failure.\r\n  //   else\r\n  //     throw;  // Re-throws the original exception.\r\n  // }\r\n  //\r\n  // However, the purpose of this flag is to allow the program to drop into\r\n  // the debugger when the exception is thrown. On most platforms, once the\r\n  // control enters the catch block, the exception origin information is\r\n  // lost and the debugger will stop the program at the point of the\r\n  // re-throw in this function -- instead of at the point of the original\r\n  // throw statement in the code under test.  For this reason, we perform\r\n  // the check early, sacrificing the ability to affect Google Test's\r\n  // exception handling in the method where the exception is thrown.\r\n  if (internal::GetUnitTestImpl()->catch_exceptions()) {\r\n#if GTEST_HAS_EXCEPTIONS\r\n\r\n    try {\r\n      return HandleSehExceptionsInMethodIfSupported(object, method, location);\r\n    }\r\n    catch (const internal::GoogleTestFailureException&) {    // NOLINT\r\n      // This exception type can only be thrown by a failed Google\r\n      // Test assertion with the intention of letting another testing\r\n      // framework catch it.  Therefore we just re-throw it.\r\n      throw;\r\n    }\r\n    catch (const std::exception& e) {    // NOLINT\r\n      internal::ReportFailureInUnknownLocation(\r\n        TestPartResult::kFatalFailure,\r\n        FormatCxxExceptionMessage(e.what(), location));\r\n    }\r\n    catch (...) {    // NOLINT\r\n      internal::ReportFailureInUnknownLocation(\r\n        TestPartResult::kFatalFailure,\r\n        FormatCxxExceptionMessage(NULL, location));\r\n    }\r\n\r\n    return static_cast<Result>(0);\r\n#else\r\n    return HandleSehExceptionsInMethodIfSupported(object, method, location);\r\n#endif  // GTEST_HAS_EXCEPTIONS\r\n  }\r\n  else {\r\n    return (object->*method)();\r\n  }\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// Runs the test and updates the test result.\r\nvoid Test::Run() {\r\n  if (!HasSameFixtureClass()) {\r\n    return;\r\n  }\r\n\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n  internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, \"SetUp()\");\r\n\r\n  // We will run the test only if SetUp() was successful.\r\n  if (!HasFatalFailure()) {\r\n    impl->os_stack_trace_getter()->UponLeavingGTest();\r\n    internal::HandleExceptionsInMethodIfSupported(\r\n      this, &Test::TestBody, \"the test body\");\r\n  }\r\n\r\n  // However, we want to clean up as much as possible.  Hence we will\r\n  // always call TearDown(), even if SetUp() or the test body has\r\n  // failed.\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n  internal::HandleExceptionsInMethodIfSupported(\r\n    this, &Test::TearDown, \"TearDown()\");\r\n}\r\n\r\n// Returns true iff the current test has a fatal failure.\r\nbool Test::HasFatalFailure() {\r\n  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();\r\n}\r\n\r\n// Returns true iff the current test has a non-fatal failure.\r\nbool Test::HasNonfatalFailure() {\r\n  return internal::GetUnitTestImpl()->current_test_result()->\r\n         HasNonfatalFailure();\r\n}\r\n\r\n// class TestInfo\r\n\r\n// Constructs a TestInfo object. It assumes ownership of the test factory\r\n// object.\r\nTestInfo::TestInfo(const std::string& a_test_case_name,\r\n                   const std::string& a_name,\r\n                   const char* a_type_param,\r\n                   const char* a_value_param,\r\n                   internal::TypeId fixture_class_id,\r\n                   internal::TestFactoryBase* factory)\r\n  : test_case_name_(a_test_case_name),\r\n    name_(a_name),\r\n    type_param_(a_type_param ? new std::string(a_type_param) : NULL),\r\n    value_param_(a_value_param ? new std::string(a_value_param) : NULL),\r\n    fixture_class_id_(fixture_class_id),\r\n    should_run_(false),\r\n    is_disabled_(false),\r\n    matches_filter_(false),\r\n    factory_(factory),\r\n    result_() {}\r\n\r\n// Destructs a TestInfo object.\r\nTestInfo::~TestInfo() {\r\n  delete factory_;\r\n}\r\n\r\nnamespace internal {\r\n\r\n// Creates a new TestInfo object and registers it with Google Test;\r\n// returns the created object.\r\n//\r\n// Arguments:\r\n//\r\n//   test_case_name:   name of the test case\r\n//   name:             name of the test\r\n//   type_param:       the name of the test's type parameter, or NULL if\r\n//                     this is not a typed or a type-parameterized test.\r\n//   value_param:      text representation of the test's value parameter,\r\n//                     or NULL if this is not a value-parameterized test.\r\n//   fixture_class_id: ID of the test fixture class\r\n//   set_up_tc:        pointer to the function that sets up the test case\r\n//   tear_down_tc:     pointer to the function that tears down the test case\r\n//   factory:          pointer to the factory that creates a test object.\r\n//                     The newly created TestInfo instance will assume\r\n//                     ownership of the factory object.\r\nTestInfo* MakeAndRegisterTestInfo(\r\n  const char* test_case_name,\r\n  const char* name,\r\n  const char* type_param,\r\n  const char* value_param,\r\n  TypeId fixture_class_id,\r\n  SetUpTestCaseFunc set_up_tc,\r\n  TearDownTestCaseFunc tear_down_tc,\r\n  TestFactoryBase* factory) {\r\n  TestInfo* const test_info =\r\n    new TestInfo(test_case_name, name, type_param, value_param,\r\n                 fixture_class_id, factory);\r\n  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);\r\n  return test_info;\r\n}\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\nvoid ReportInvalidTestCaseType(const char* test_case_name,\r\n                               const char* file, int line) {\r\n  Message errors;\r\n  errors\r\n      << \"Attempted redefinition of test case \" << test_case_name << \".\\n\"\r\n      << \"All tests in the same test case must use the same test fixture\\n\"\r\n      << \"class.  However, in test case \" << test_case_name << \", you tried\\n\"\r\n      << \"to define a test using a fixture class different from the one\\n\"\r\n      << \"used earlier. This can happen if the two fixture classes are\\n\"\r\n      << \"from different namespaces and have the same name. You should\\n\"\r\n      << \"probably rename one of the classes to put the tests into different\\n\"\r\n      << \"test cases.\";\r\n\r\n  fprintf(stderr, \"%s %s\", FormatFileLocation(file, line).c_str(),\r\n          errors.GetString().c_str());\r\n}\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n}  // namespace internal\r\n\r\nnamespace {\r\n\r\n// A predicate that checks the test name of a TestInfo against a known\r\n// value.\r\n//\r\n// This is used for implementation of the TestCase class only.  We put\r\n// it in the anonymous namespace to prevent polluting the outer\r\n// namespace.\r\n//\r\n// TestNameIs is copyable.\r\nclass TestNameIs {\r\n public:\r\n  // Constructor.\r\n  //\r\n  // TestNameIs has NO default constructor.\r\n  explicit TestNameIs(const char* name)\r\n    : name_(name) {}\r\n\r\n  // Returns true iff the test name of test_info matches name_.\r\n  bool operator()(const TestInfo* test_info) const {\r\n    return test_info && test_info->name() == name_;\r\n  }\r\n\r\n private:\r\n  std::string name_;\r\n};\r\n\r\n}  // namespace\r\n\r\nnamespace internal {\r\n\r\n// This method expands all parameterized tests registered with macros TEST_P\r\n// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.\r\n// This will be done just once during the program runtime.\r\nvoid UnitTestImpl::RegisterParameterizedTests() {\r\n#if GTEST_HAS_PARAM_TEST\r\n\r\n  if (!parameterized_tests_registered_) {\r\n    parameterized_test_registry_.RegisterTests();\r\n    parameterized_tests_registered_ = true;\r\n  }\r\n\r\n#endif\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// Creates the test object, runs it, records its result, and then\r\n// deletes it.\r\nvoid TestInfo::Run() {\r\n  if (!should_run_) {\r\n    return;\r\n  }\r\n\r\n  // Tells UnitTest where to store test result.\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n  impl->set_current_test_info(this);\r\n\r\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\r\n\r\n  // Notifies the unit test event listeners that a test is about to start.\r\n  repeater->OnTestStart(*this);\r\n\r\n  const TimeInMillis start = internal::GetTimeInMillis();\r\n\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n\r\n  // Creates the test object.\r\n  Test* const test = internal::HandleExceptionsInMethodIfSupported(\r\n                       factory_, &internal::TestFactoryBase::CreateTest,\r\n                       \"the test fixture's constructor\");\r\n\r\n  // Runs the test only if the test object was created and its\r\n  // constructor didn't generate a fatal failure.\r\n  if ((test != NULL) && !Test::HasFatalFailure()) {\r\n    // This doesn't throw as all user code that can throw are wrapped into\r\n    // exception handling code.\r\n    test->Run();\r\n  }\r\n\r\n  // Deletes the test object.\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n  internal::HandleExceptionsInMethodIfSupported(\r\n    test, &Test::DeleteSelf_, \"the test fixture's destructor\");\r\n\r\n  result_.set_elapsed_time(internal::GetTimeInMillis() - start);\r\n\r\n  // Notifies the unit test event listener that a test has just finished.\r\n  repeater->OnTestEnd(*this);\r\n\r\n  // Tells UnitTest to stop associating assertion results to this\r\n  // test.\r\n  impl->set_current_test_info(NULL);\r\n}\r\n\r\n// class TestCase\r\n\r\n// Gets the number of successful tests in this test case.\r\nint TestCase::successful_test_count() const {\r\n  return CountIf(test_info_list_, TestPassed);\r\n}\r\n\r\n// Gets the number of failed tests in this test case.\r\nint TestCase::failed_test_count() const {\r\n  return CountIf(test_info_list_, TestFailed);\r\n}\r\n\r\n// Gets the number of disabled tests that will be reported in the XML report.\r\nint TestCase::reportable_disabled_test_count() const {\r\n  return CountIf(test_info_list_, TestReportableDisabled);\r\n}\r\n\r\n// Gets the number of disabled tests in this test case.\r\nint TestCase::disabled_test_count() const {\r\n  return CountIf(test_info_list_, TestDisabled);\r\n}\r\n\r\n// Gets the number of tests to be printed in the XML report.\r\nint TestCase::reportable_test_count() const {\r\n  return CountIf(test_info_list_, TestReportable);\r\n}\r\n\r\n// Get the number of tests in this test case that should run.\r\nint TestCase::test_to_run_count() const {\r\n  return CountIf(test_info_list_, ShouldRunTest);\r\n}\r\n\r\n// Gets the number of all tests.\r\nint TestCase::total_test_count() const {\r\n  return static_cast<int>(test_info_list_.size());\r\n}\r\n\r\n// Creates a TestCase with the given name.\r\n//\r\n// Arguments:\r\n//\r\n//   name:         name of the test case\r\n//   a_type_param: the name of the test case's type parameter, or NULL if\r\n//                 this is not a typed or a type-parameterized test case.\r\n//   set_up_tc:    pointer to the function that sets up the test case\r\n//   tear_down_tc: pointer to the function that tears down the test case\r\nTestCase::TestCase(const char* a_name, const char* a_type_param,\r\n                   Test::SetUpTestCaseFunc set_up_tc,\r\n                   Test::TearDownTestCaseFunc tear_down_tc)\r\n  : name_(a_name),\r\n    type_param_(a_type_param ? new std::string(a_type_param) : NULL),\r\n    set_up_tc_(set_up_tc),\r\n    tear_down_tc_(tear_down_tc),\r\n    should_run_(false),\r\n    elapsed_time_(0) {\r\n}\r\n\r\n// Destructor of TestCase.\r\nTestCase::~TestCase() {\r\n  // Deletes every Test in the collection.\r\n  ForEach(test_info_list_, internal::Delete<TestInfo>);\r\n}\r\n\r\n// Returns the i-th test among all the tests. i can range from 0 to\r\n// total_test_count() - 1. If i is not in that range, returns NULL.\r\nconst TestInfo* TestCase::GetTestInfo(int i) const {\r\n  const int index = GetElementOr(test_indices_, i, -1);\r\n  return index < 0 ? NULL : test_info_list_[index];\r\n}\r\n\r\n// Returns the i-th test among all the tests. i can range from 0 to\r\n// total_test_count() - 1. If i is not in that range, returns NULL.\r\nTestInfo* TestCase::GetMutableTestInfo(int i) {\r\n  const int index = GetElementOr(test_indices_, i, -1);\r\n  return index < 0 ? NULL : test_info_list_[index];\r\n}\r\n\r\n// Adds a test to this test case.  Will delete the test upon\r\n// destruction of the TestCase object.\r\nvoid TestCase::AddTestInfo(TestInfo* test_info) {\r\n  test_info_list_.push_back(test_info);\r\n  test_indices_.push_back(static_cast<int>(test_indices_.size()));\r\n}\r\n\r\n// Runs every test in this TestCase.\r\nvoid TestCase::Run() {\r\n  if (!should_run_) {\r\n    return;\r\n  }\r\n\r\n  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();\r\n  impl->set_current_test_case(this);\r\n\r\n  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();\r\n\r\n  repeater->OnTestCaseStart(*this);\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n  internal::HandleExceptionsInMethodIfSupported(\r\n    this, &TestCase::RunSetUpTestCase, \"SetUpTestCase()\");\r\n\r\n  const internal::TimeInMillis start = internal::GetTimeInMillis();\r\n\r\n  for (int i = 0; i < total_test_count(); i++) {\r\n    GetMutableTestInfo(i)->Run();\r\n  }\r\n\r\n  elapsed_time_ = internal::GetTimeInMillis() - start;\r\n\r\n  impl->os_stack_trace_getter()->UponLeavingGTest();\r\n  internal::HandleExceptionsInMethodIfSupported(\r\n    this, &TestCase::RunTearDownTestCase, \"TearDownTestCase()\");\r\n\r\n  repeater->OnTestCaseEnd(*this);\r\n  impl->set_current_test_case(NULL);\r\n}\r\n\r\n// Clears the results of all tests in this test case.\r\nvoid TestCase::ClearResult() {\r\n  ad_hoc_test_result_.Clear();\r\n  ForEach(test_info_list_, TestInfo::ClearTestResult);\r\n}\r\n\r\n// Shuffles the tests in this test case.\r\nvoid TestCase::ShuffleTests(internal::Random* random) {\r\n  Shuffle(random, &test_indices_);\r\n}\r\n\r\n// Restores the test order to before the first shuffle.\r\nvoid TestCase::UnshuffleTests() {\r\n  for (size_t i = 0; i < test_indices_.size(); i++) {\r\n    test_indices_[i] = static_cast<int>(i);\r\n  }\r\n}\r\n\r\n// Formats a countable noun.  Depending on its quantity, either the\r\n// singular form or the plural form is used. e.g.\r\n//\r\n// FormatCountableNoun(1, \"formula\", \"formuli\") returns \"1 formula\".\r\n// FormatCountableNoun(5, \"book\", \"books\") returns \"5 books\".\r\nstatic std::string FormatCountableNoun(int count,\r\n                                       const char* singular_form,\r\n                                       const char* plural_form) {\r\n  return internal::StreamableToString(count) + \" \" +\r\n         (count == 1 ? singular_form : plural_form);\r\n}\r\n\r\n// Formats the count of tests.\r\nstatic std::string FormatTestCount(int test_count) {\r\n  return FormatCountableNoun(test_count, \"test\", \"tests\");\r\n}\r\n\r\n// Formats the count of test cases.\r\nstatic std::string FormatTestCaseCount(int test_case_count) {\r\n  return FormatCountableNoun(test_case_count, \"test case\", \"test cases\");\r\n}\r\n\r\n// Converts a TestPartResult::Type enum to human-friendly string\r\n// representation.  Both kNonFatalFailure and kFatalFailure are translated\r\n// to \"Failure\", as the user usually doesn't care about the difference\r\n// between the two when viewing the test result.\r\nstatic const char* TestPartResultTypeToString(TestPartResult::Type type) {\r\n  switch (type) {\r\n    case TestPartResult::kSuccess:\r\n      return \"Success\";\r\n\r\n    case TestPartResult::kNonFatalFailure:\r\n    case TestPartResult::kFatalFailure:\r\n#ifdef _MSC_VER\r\n      return \"error: \";\r\n#else\r\n      return \"Failure\\n\";\r\n#endif\r\n\r\n    default:\r\n      return \"Unknown result type\";\r\n  }\r\n}\r\n\r\nnamespace internal {\r\n\r\n// Prints a TestPartResult to an std::string.\r\nstatic std::string PrintTestPartResultToString(\r\n  const TestPartResult& test_part_result) {\r\n  return (Message()\r\n          << internal::FormatFileLocation(test_part_result.file_name(),\r\n                                          test_part_result.line_number())\r\n          << \" \" << TestPartResultTypeToString(test_part_result.type())\r\n          << test_part_result.message()).GetString();\r\n}\r\n\r\n// Prints a TestPartResult.\r\nstatic void PrintTestPartResult(const TestPartResult& test_part_result) {\r\n  const std::string& result =\r\n    PrintTestPartResultToString(test_part_result);\r\n  printf(\"%s\\n\", result.c_str());\r\n  fflush(stdout);\r\n  // If the test program runs in Visual Studio or a debugger, the\r\n  // following statements add the test part result message to the Output\r\n  // window such that the user can double-click on it to jump to the\r\n  // corresponding source code location; otherwise they do nothing.\r\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\r\n  // We don't call OutputDebugString*() on Windows Mobile, as printing\r\n  // to stdout is done by OutputDebugString() there already - we don't\r\n  // want the same message printed twice.\r\n  ::OutputDebugStringA(result.c_str());\r\n  ::OutputDebugStringA(\"\\n\");\r\n#endif\r\n}\r\n\r\n// class PrettyUnitTestResultPrinter\r\n\r\nenum GTestColor {\r\n  COLOR_DEFAULT,\r\n  COLOR_RED,\r\n  COLOR_GREEN,\r\n  COLOR_YELLOW\r\n};\r\n\r\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\r\n\r\n// Returns the character attribute for the given color.\r\nWORD GetColorAttribute(GTestColor color) {\r\n  switch (color) {\r\n    case COLOR_RED:\r\n      return FOREGROUND_RED;\r\n\r\n    case COLOR_GREEN:\r\n      return FOREGROUND_GREEN;\r\n\r\n    case COLOR_YELLOW:\r\n      return FOREGROUND_RED | FOREGROUND_GREEN;\r\n\r\n    default:\r\n      return 0;\r\n  }\r\n}\r\n\r\n#else\r\n\r\n// Returns the ANSI color code for the given color.  COLOR_DEFAULT is\r\n// an invalid input.\r\nconst char* GetAnsiColorCode(GTestColor color) {\r\n  switch (color) {\r\n    case COLOR_RED:\r\n      return \"1\";\r\n\r\n    case COLOR_GREEN:\r\n      return \"2\";\r\n\r\n    case COLOR_YELLOW:\r\n      return \"3\";\r\n\r\n    default:\r\n      return NULL;\r\n  };\r\n}\r\n\r\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\r\n\r\n// Returns true iff Google Test should use colors in the output.\r\nbool ShouldUseColor(bool stdout_is_tty) {\r\n  const char* const gtest_color = GTEST_FLAG(color).c_str();\r\n\r\n  if (String::CaseInsensitiveCStringEquals(gtest_color, \"auto\")) {\r\n#if GTEST_OS_WINDOWS\r\n    // On Windows the TERM variable is usually not set, but the\r\n    // console there does support colors.\r\n    return stdout_is_tty;\r\n#else\r\n    // On non-Windows platforms, we rely on the TERM variable.\r\n    const char* const term = posix::GetEnv(\"TERM\");\r\n    const bool term_supports_color =\r\n      String::CStringEquals(term, \"xterm\") ||\r\n      String::CStringEquals(term, \"xterm-color\") ||\r\n      String::CStringEquals(term, \"xterm-256color\") ||\r\n      String::CStringEquals(term, \"screen\") ||\r\n      String::CStringEquals(term, \"screen-256color\") ||\r\n      String::CStringEquals(term, \"linux\") ||\r\n      String::CStringEquals(term, \"cygwin\");\r\n    return stdout_is_tty && term_supports_color;\r\n#endif  // GTEST_OS_WINDOWS\r\n  }\r\n\r\n  return String::CaseInsensitiveCStringEquals(gtest_color, \"yes\") ||\r\n         String::CaseInsensitiveCStringEquals(gtest_color, \"true\") ||\r\n         String::CaseInsensitiveCStringEquals(gtest_color, \"t\") ||\r\n         String::CStringEquals(gtest_color, \"1\");\r\n  // We take \"yes\", \"true\", \"t\", and \"1\" as meaning \"yes\".  If the\r\n  // value is neither one of these nor \"auto\", we treat it as \"no\" to\r\n  // be conservative.\r\n}\r\n\r\n// Helpers for printing colored strings to stdout. Note that on Windows, we\r\n// cannot simply emit special characters and have the terminal change colors.\r\n// This routine must actually emit the characters rather than return a string\r\n// that would be colored when printed, as can be done on Linux.\r\nvoid ColoredPrintf(GTestColor color, const char* fmt, ...) {\r\n  va_list args;\r\n  va_start(args, fmt);\r\n\r\n#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS\r\n  const bool use_color = false;\r\n#else\r\n  static const bool in_color_mode =\r\n    ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);\r\n  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);\r\n#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS\r\n  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.\r\n\r\n  if (!use_color) {\r\n    vprintf(fmt, args);\r\n    va_end(args);\r\n    return;\r\n  }\r\n\r\n#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\r\n  const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);\r\n\r\n  // Gets the current text color.\r\n  CONSOLE_SCREEN_BUFFER_INFO buffer_info;\r\n  GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);\r\n  const WORD old_color_attrs = buffer_info.wAttributes;\r\n\r\n  // We need to flush the stream buffers into the console before each\r\n  // SetConsoleTextAttribute call lest it affect the text that is already\r\n  // printed but has not yet reached the console.\r\n  fflush(stdout);\r\n  SetConsoleTextAttribute(stdout_handle,\r\n                          GetColorAttribute(color) | FOREGROUND_INTENSITY);\r\n  vprintf(fmt, args);\r\n\r\n  fflush(stdout);\r\n  // Restores the text color.\r\n  SetConsoleTextAttribute(stdout_handle, old_color_attrs);\r\n#else\r\n  printf(\"\\033[0;3%sm\", GetAnsiColorCode(color));\r\n  vprintf(fmt, args);\r\n  printf(\"\\033[m\");  // Resets the terminal to default.\r\n#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE\r\n  va_end(args);\r\n}\r\n\r\n// Text printed in Google Test's text output and --gunit_list_tests\r\n// output to label the type parameter and value parameter for a test.\r\nstatic const char kTypeParamLabel[] = \"TypeParam\";\r\nstatic const char kValueParamLabel[] = \"GetParam()\";\r\n\r\nvoid PrintFullTestCommentIfPresent(const TestInfo& test_info) {\r\n  const char* const type_param = test_info.type_param();\r\n  const char* const value_param = test_info.value_param();\r\n\r\n  if (type_param != NULL || value_param != NULL) {\r\n    printf(\", where \");\r\n\r\n    if (type_param != NULL) {\r\n      printf(\"%s = %s\", kTypeParamLabel, type_param);\r\n\r\n      if (value_param != NULL) {\r\n        printf(\" and \");\r\n      }\r\n    }\r\n\r\n    if (value_param != NULL) {\r\n      printf(\"%s = %s\", kValueParamLabel, value_param);\r\n    }\r\n  }\r\n}\r\n\r\n// This class implements the TestEventListener interface.\r\n//\r\n// Class PrettyUnitTestResultPrinter is copyable.\r\nclass PrettyUnitTestResultPrinter : public TestEventListener {\r\n public:\r\n  PrettyUnitTestResultPrinter() {}\r\n  static void PrintTestName(const char* test_case, const char* test) {\r\n    printf(\"%s.%s\", test_case, test);\r\n  }\r\n\r\n  // The following methods override what's in the TestEventListener class.\r\n  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);\r\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);\r\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestCaseStart(const TestCase& test_case);\r\n  virtual void OnTestStart(const TestInfo& test_info);\r\n  virtual void OnTestPartResult(const TestPartResult& result);\r\n  virtual void OnTestEnd(const TestInfo& test_info);\r\n  virtual void OnTestCaseEnd(const TestCase& test_case);\r\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);\r\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}\r\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\r\n  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}\r\n\r\n private:\r\n  static void PrintFailedTests(const UnitTest& unit_test);\r\n};\r\n\r\n// Fired before each iteration of tests starts.\r\nvoid PrettyUnitTestResultPrinter::OnTestIterationStart(\r\n  const UnitTest& unit_test, int iteration) {\r\n  if (GTEST_FLAG(repeat) != 1) {\r\n    printf(\"\\nRepeating all tests (iteration %d) . . .\\n\\n\", iteration + 1);\r\n  }\r\n\r\n  const char* const filter = GTEST_FLAG(filter).c_str();\r\n\r\n  // Prints the filter if it's not *.  This reminds the user that some\r\n  // tests may be skipped.\r\n  if (!String::CStringEquals(filter, kUniversalFilter)) {\r\n    ColoredPrintf(COLOR_YELLOW,\r\n                  \"Note: %s filter = %s\\n\", GTEST_NAME_, filter);\r\n  }\r\n\r\n  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {\r\n    const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);\r\n    ColoredPrintf(COLOR_YELLOW,\r\n                  \"Note: This is test shard %d of %s.\\n\",\r\n                  static_cast<int>(shard_index) + 1,\r\n                  internal::posix::GetEnv(kTestTotalShards));\r\n  }\r\n\r\n  if (GTEST_FLAG(shuffle)) {\r\n    ColoredPrintf(COLOR_YELLOW,\r\n                  \"Note: Randomizing tests' orders with a seed of %d .\\n\",\r\n                  unit_test.random_seed());\r\n  }\r\n\r\n  ColoredPrintf(COLOR_GREEN,  \"[==========] \");\r\n  printf(\"Running %s from %s.\\n\",\r\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\r\n         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(\r\n  const UnitTest& /*unit_test*/) {\r\n  ColoredPrintf(COLOR_GREEN,  \"[----------] \");\r\n  printf(\"Global test environment set-up.\\n\");\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {\r\n  const std::string counts =\r\n    FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\r\n  ColoredPrintf(COLOR_GREEN, \"[----------] \");\r\n  printf(\"%s from %s\", counts.c_str(), test_case.name());\r\n\r\n  if (test_case.type_param() == NULL) {\r\n    printf(\"\\n\");\r\n  }\r\n  else {\r\n    printf(\", where %s = %s\\n\", kTypeParamLabel, test_case.type_param());\r\n  }\r\n\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {\r\n  ColoredPrintf(COLOR_GREEN,  \"[ RUN      ] \");\r\n  PrintTestName(test_info.test_case_name(), test_info.name());\r\n  printf(\"\\n\");\r\n  fflush(stdout);\r\n}\r\n\r\n// Called after an assertion failure.\r\nvoid PrettyUnitTestResultPrinter::OnTestPartResult(\r\n  const TestPartResult& result) {\r\n  // If the test part succeeded, we don't need to do anything.\r\n  if (result.type() == TestPartResult::kSuccess) {\r\n    return;\r\n  }\r\n\r\n  // Print failure message from the assertion (e.g. expected this and got that).\r\n  PrintTestPartResult(result);\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {\r\n  if (test_info.result()->Passed()) {\r\n    ColoredPrintf(COLOR_GREEN, \"[       OK ] \");\r\n  }\r\n  else {\r\n    ColoredPrintf(COLOR_RED, \"[  FAILED  ] \");\r\n  }\r\n\r\n  PrintTestName(test_info.test_case_name(), test_info.name());\r\n\r\n  if (test_info.result()->Failed()) {\r\n    PrintFullTestCommentIfPresent(test_info);\r\n  }\r\n\r\n  if (GTEST_FLAG(print_time)) {\r\n    printf(\" (%s ms)\\n\", internal::StreamableToString(\r\n             test_info.result()->elapsed_time()).c_str());\r\n  }\r\n  else {\r\n    printf(\"\\n\");\r\n  }\r\n\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {\r\n  if (!GTEST_FLAG(print_time)) {\r\n    return;\r\n  }\r\n\r\n  const std::string counts =\r\n    FormatCountableNoun(test_case.test_to_run_count(), \"test\", \"tests\");\r\n  ColoredPrintf(COLOR_GREEN, \"[----------] \");\r\n  printf(\"%s from %s (%s ms total)\\n\\n\",\r\n         counts.c_str(), test_case.name(),\r\n         internal::StreamableToString(test_case.elapsed_time()).c_str());\r\n  fflush(stdout);\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(\r\n  const UnitTest& /*unit_test*/) {\r\n  ColoredPrintf(COLOR_GREEN,  \"[----------] \");\r\n  printf(\"Global test environment tear-down\\n\");\r\n  fflush(stdout);\r\n}\r\n\r\n// Internal helper for printing the list of failed tests.\r\nvoid PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {\r\n  const int failed_test_count = unit_test.failed_test_count();\r\n\r\n  if (failed_test_count == 0) {\r\n    return;\r\n  }\r\n\r\n  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {\r\n    const TestCase& test_case = *unit_test.GetTestCase(i);\r\n\r\n    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {\r\n      continue;\r\n    }\r\n\r\n    for (int j = 0; j < test_case.total_test_count(); ++j) {\r\n      const TestInfo& test_info = *test_case.GetTestInfo(j);\r\n\r\n      if (!test_info.should_run() || test_info.result()->Passed()) {\r\n        continue;\r\n      }\r\n\r\n      ColoredPrintf(COLOR_RED, \"[  FAILED  ] \");\r\n      printf(\"%s.%s\", test_case.name(), test_info.name());\r\n      PrintFullTestCommentIfPresent(test_info);\r\n      printf(\"\\n\");\r\n    }\r\n  }\r\n}\r\n\r\nvoid PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\r\n    int /*iteration*/) {\r\n  ColoredPrintf(COLOR_GREEN,  \"[==========] \");\r\n  printf(\"%s from %s ran.\",\r\n         FormatTestCount(unit_test.test_to_run_count()).c_str(),\r\n         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());\r\n\r\n  if (GTEST_FLAG(print_time)) {\r\n    printf(\" (%s ms total)\",\r\n           internal::StreamableToString(unit_test.elapsed_time()).c_str());\r\n  }\r\n\r\n  printf(\"\\n\");\r\n  ColoredPrintf(COLOR_GREEN,  \"[  PASSED  ] \");\r\n  printf(\"%s.\\n\", FormatTestCount(unit_test.successful_test_count()).c_str());\r\n\r\n  int num_failures = unit_test.failed_test_count();\r\n\r\n  if (!unit_test.Passed()) {\r\n    const int failed_test_count = unit_test.failed_test_count();\r\n    ColoredPrintf(COLOR_RED,  \"[  FAILED  ] \");\r\n    printf(\"%s, listed below:\\n\", FormatTestCount(failed_test_count).c_str());\r\n    PrintFailedTests(unit_test);\r\n    printf(\"\\n%2d FAILED %s\\n\", num_failures,\r\n           num_failures == 1 ? \"TEST\" : \"TESTS\");\r\n  }\r\n\r\n  int num_disabled = unit_test.reportable_disabled_test_count();\r\n\r\n  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {\r\n    if (!num_failures) {\r\n      printf(\"\\n\");  // Add a spacer if no FAILURE banner is displayed.\r\n    }\r\n\r\n    ColoredPrintf(COLOR_YELLOW,\r\n                  \"  YOU HAVE %d DISABLED %s\\n\\n\",\r\n                  num_disabled,\r\n                  num_disabled == 1 ? \"TEST\" : \"TESTS\");\r\n  }\r\n\r\n  // Ensure that Google Test output is printed before, e.g., heapchecker output.\r\n  fflush(stdout);\r\n}\r\n\r\n// End PrettyUnitTestResultPrinter\r\n\r\n// class TestEventRepeater\r\n//\r\n// This class forwards events to other event listeners.\r\nclass TestEventRepeater : public TestEventListener {\r\n public:\r\n  TestEventRepeater() : forwarding_enabled_(true) {}\r\n  virtual ~TestEventRepeater();\r\n  void Append(TestEventListener* listener);\r\n  TestEventListener* Release(TestEventListener* listener);\r\n\r\n  // Controls whether events will be forwarded to listeners_. Set to false\r\n  // in death test child processes.\r\n  bool forwarding_enabled() const {\r\n    return forwarding_enabled_;\r\n  }\r\n  void set_forwarding_enabled(bool enable) {\r\n    forwarding_enabled_ = enable;\r\n  }\r\n\r\n  virtual void OnTestProgramStart(const UnitTest& unit_test);\r\n  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);\r\n  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);\r\n  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);\r\n  virtual void OnTestCaseStart(const TestCase& test_case);\r\n  virtual void OnTestStart(const TestInfo& test_info);\r\n  virtual void OnTestPartResult(const TestPartResult& result);\r\n  virtual void OnTestEnd(const TestInfo& test_info);\r\n  virtual void OnTestCaseEnd(const TestCase& test_case);\r\n  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);\r\n  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);\r\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\r\n  virtual void OnTestProgramEnd(const UnitTest& unit_test);\r\n\r\n private:\r\n  // Controls whether events will be forwarded to listeners_. Set to false\r\n  // in death test child processes.\r\n  bool forwarding_enabled_;\r\n  // The list of listeners that receive events.\r\n  std::vector<TestEventListener*> listeners_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);\r\n};\r\n\r\nTestEventRepeater::~TestEventRepeater() {\r\n  ForEach(listeners_, Delete<TestEventListener>);\r\n}\r\n\r\nvoid TestEventRepeater::Append(TestEventListener* listener) {\r\n  listeners_.push_back(listener);\r\n}\r\n\r\n// TODO(vladl@google.com): Factor the search functionality into Vector::Find.\r\nTestEventListener* TestEventRepeater::Release(TestEventListener* listener) {\r\n  for (size_t i = 0; i < listeners_.size(); ++i) {\r\n    if (listeners_[i] == listener) {\r\n      listeners_.erase(listeners_.begin() + i);\r\n      return listener;\r\n    }\r\n  }\r\n\r\n  return NULL;\r\n}\r\n\r\n// Since most methods are very similar, use macros to reduce boilerplate.\r\n// This defines a member that forwards the call to all listeners.\r\n#define GTEST_REPEATER_METHOD_(Name, Type) \\\r\nvoid TestEventRepeater::Name(const Type& parameter) { \\\r\n  if (forwarding_enabled_) { \\\r\n    for (size_t i = 0; i < listeners_.size(); i++) { \\\r\n      listeners_[i]->Name(parameter); \\\r\n    } \\\r\n  } \\\r\n}\r\n// This defines a member that forwards the call to all listeners in reverse\r\n// order.\r\n#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \\\r\nvoid TestEventRepeater::Name(const Type& parameter) { \\\r\n  if (forwarding_enabled_) { \\\r\n    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \\\r\n      listeners_[i]->Name(parameter); \\\r\n    } \\\r\n  } \\\r\n}\r\n\r\nGTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)\r\nGTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)\r\nGTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)\r\nGTEST_REPEATER_METHOD_(OnTestStart, TestInfo)\r\nGTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)\r\nGTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)\r\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)\r\nGTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)\r\nGTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)\r\nGTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)\r\nGTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)\r\n\r\n#undef GTEST_REPEATER_METHOD_\r\n#undef GTEST_REVERSE_REPEATER_METHOD_\r\n\r\nvoid TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,\r\n    int iteration) {\r\n  if (forwarding_enabled_) {\r\n    for (size_t i = 0; i < listeners_.size(); i++) {\r\n      listeners_[i]->OnTestIterationStart(unit_test, iteration);\r\n    }\r\n  }\r\n}\r\n\r\nvoid TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,\r\n    int iteration) {\r\n  if (forwarding_enabled_) {\r\n    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {\r\n      listeners_[i]->OnTestIterationEnd(unit_test, iteration);\r\n    }\r\n  }\r\n}\r\n\r\n// End TestEventRepeater\r\n\r\n// This class generates an XML output file.\r\nclass XmlUnitTestResultPrinter : public EmptyTestEventListener {\r\n public:\r\n  explicit XmlUnitTestResultPrinter(const char* output_file);\r\n\r\n  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);\r\n\r\n private:\r\n  // Is c a whitespace character that is normalized to a space character\r\n  // when it appears in an XML attribute value?\r\n  static bool IsNormalizableWhitespace(char c) {\r\n    return c == 0x9 || c == 0xA || c == 0xD;\r\n  }\r\n\r\n  // May c appear in a well-formed XML document?\r\n  static bool IsValidXmlCharacter(char c) {\r\n    return IsNormalizableWhitespace(c) || c >= 0x20;\r\n  }\r\n\r\n  // Returns an XML-escaped copy of the input string str.  If\r\n  // is_attribute is true, the text is meant to appear as an attribute\r\n  // value, and normalizable whitespace is preserved by replacing it\r\n  // with character references.\r\n  static std::string EscapeXml(const std::string& str, bool is_attribute);\r\n\r\n  // Returns the given string with all characters invalid in XML removed.\r\n  static std::string RemoveInvalidXmlCharacters(const std::string& str);\r\n\r\n  // Convenience wrapper around EscapeXml when str is an attribute value.\r\n  static std::string EscapeXmlAttribute(const std::string& str) {\r\n    return EscapeXml(str, true);\r\n  }\r\n\r\n  // Convenience wrapper around EscapeXml when str is not an attribute value.\r\n  static std::string EscapeXmlText(const char* str) {\r\n    return EscapeXml(str, false);\r\n  }\r\n\r\n  // Verifies that the given attribute belongs to the given element and\r\n  // streams the attribute as XML.\r\n  static void OutputXmlAttribute(std::ostream* stream,\r\n                                 const std::string& element_name,\r\n                                 const std::string& name,\r\n                                 const std::string& value);\r\n\r\n  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\r\n  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);\r\n\r\n  // Streams an XML representation of a TestInfo object.\r\n  static void OutputXmlTestInfo(::std::ostream* stream,\r\n                                const char* test_case_name,\r\n                                const TestInfo& test_info);\r\n\r\n  // Prints an XML representation of a TestCase object\r\n  static void PrintXmlTestCase(::std::ostream* stream,\r\n                               const TestCase& test_case);\r\n\r\n  // Prints an XML summary of unit_test to output stream out.\r\n  static void PrintXmlUnitTest(::std::ostream* stream,\r\n                               const UnitTest& unit_test);\r\n\r\n  // Produces a string representing the test properties in a result as space\r\n  // delimited XML attributes based on the property key=\"value\" pairs.\r\n  // When the std::string is not empty, it includes a space at the beginning,\r\n  // to delimit this attribute from prior attributes.\r\n  static std::string TestPropertiesAsXmlAttributes(const TestResult& result);\r\n\r\n  // The output file.\r\n  const std::string output_file_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter);\r\n};\r\n\r\n// Creates a new XmlUnitTestResultPrinter.\r\nXmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)\r\n  : output_file_(output_file) {\r\n  if (output_file_.c_str() == NULL || output_file_.empty()) {\r\n    fprintf(stderr, \"XML output file may not be null\\n\");\r\n    fflush(stderr);\r\n    exit(EXIT_FAILURE);\r\n  }\r\n}\r\n\r\n// Called after the unit test ends.\r\nvoid XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,\r\n    int /*iteration*/) {\r\n  FILE* xmlout = NULL;\r\n  FilePath output_file(output_file_);\r\n  FilePath output_dir(output_file.RemoveFileName());\r\n\r\n  if (output_dir.CreateDirectoriesRecursively()) {\r\n    xmlout = posix::FOpen(output_file_.c_str(), \"w\");\r\n  }\r\n\r\n  if (xmlout == NULL) {\r\n    // TODO(wan): report the reason of the failure.\r\n    //\r\n    // We don't do it for now as:\r\n    //\r\n    //   1. There is no urgent need for it.\r\n    //   2. It's a bit involved to make the errno variable thread-safe on\r\n    //      all three operating systems (Linux, Windows, and Mac OS).\r\n    //   3. To interpret the meaning of errno in a thread-safe way,\r\n    //      we need the strerror_r() function, which is not available on\r\n    //      Windows.\r\n    fprintf(stderr,\r\n            \"Unable to open file \\\"%s\\\"\\n\",\r\n            output_file_.c_str());\r\n    fflush(stderr);\r\n    exit(EXIT_FAILURE);\r\n  }\r\n\r\n  std::stringstream stream;\r\n  PrintXmlUnitTest(&stream, unit_test);\r\n  fprintf(xmlout, \"%s\", StringStreamToString(&stream).c_str());\r\n  fclose(xmlout);\r\n}\r\n\r\n// Returns an XML-escaped copy of the input string str.  If is_attribute\r\n// is true, the text is meant to appear as an attribute value, and\r\n// normalizable whitespace is preserved by replacing it with character\r\n// references.\r\n//\r\n// Invalid XML characters in str, if any, are stripped from the output.\r\n// It is expected that most, if not all, of the text processed by this\r\n// module will consist of ordinary English text.\r\n// If this module is ever modified to produce version 1.1 XML output,\r\n// most invalid characters can be retained using character references.\r\n// TODO(wan): It might be nice to have a minimally invasive, human-readable\r\n// escaping scheme for invalid characters, rather than dropping them.\r\nstd::string XmlUnitTestResultPrinter::EscapeXml(\r\n  const std::string& str, bool is_attribute) {\r\n  Message m;\r\n\r\n  for (size_t i = 0; i < str.size(); ++i) {\r\n    const char ch = str[i];\r\n\r\n    switch (ch) {\r\n      case '<':\r\n        m << \"&lt;\";\r\n        break;\r\n\r\n      case '>':\r\n        m << \"&gt;\";\r\n        break;\r\n\r\n      case '&':\r\n        m << \"&amp;\";\r\n        break;\r\n\r\n      case '\\'':\r\n        if (is_attribute) {\r\n          m << \"&apos;\";\r\n        }\r\n        else {\r\n          m << '\\'';\r\n        }\r\n\r\n        break;\r\n\r\n      case '\"':\r\n        if (is_attribute) {\r\n          m << \"&quot;\";\r\n        }\r\n        else {\r\n          m << '\"';\r\n        }\r\n\r\n        break;\r\n\r\n      default:\r\n        if (IsValidXmlCharacter(ch)) {\r\n          if (is_attribute && IsNormalizableWhitespace(ch))\r\n            m << \"&#x\" << String::FormatByte(static_cast<unsigned char>(ch))\r\n              << \";\";\r\n          else {\r\n            m << ch;\r\n          }\r\n        }\r\n\r\n        break;\r\n    }\r\n  }\r\n\r\n  return m.GetString();\r\n}\r\n\r\n// Returns the given string with all characters invalid in XML removed.\r\n// Currently invalid characters are dropped from the string. An\r\n// alternative is to replace them with certain characters such as . or ?.\r\nstd::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(\r\n  const std::string& str) {\r\n  std::string output;\r\n  output.reserve(str.size());\r\n\r\n  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)\r\n    if (IsValidXmlCharacter(*it)) {\r\n      output.push_back(*it);\r\n    }\r\n\r\n  return output;\r\n}\r\n\r\n// The following routines generate an XML representation of a UnitTest\r\n// object.\r\n//\r\n// This is how Google Test concepts map to the DTD:\r\n//\r\n// <testsuites name=\"AllTests\">        <-- corresponds to a UnitTest object\r\n//   <testsuite name=\"testcase-name\">  <-- corresponds to a TestCase object\r\n//     <testcase name=\"test-name\">     <-- corresponds to a TestInfo object\r\n//       <failure message=\"...\">...</failure>\r\n//       <failure message=\"...\">...</failure>\r\n//       <failure message=\"...\">...</failure>\r\n//                                     <-- individual assertion failures\r\n//     </testcase>\r\n//   </testsuite>\r\n// </testsuites>\r\n\r\n// Formats the given time in milliseconds as seconds.\r\nstd::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {\r\n  ::std::stringstream ss;\r\n  ss << ms / 1000.0;\r\n  return ss.str();\r\n}\r\n\r\n// Converts the given epoch time in milliseconds to a date string in the ISO\r\n// 8601 format, without the timezone information.\r\nstd::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) {\r\n  // Using non-reentrant version as localtime_r is not portable.\r\n  time_t seconds = static_cast<time_t>(ms / 1000);\r\n#ifdef _MSC_VER\r\n# pragma warning(push)          // Saves the current warning state.\r\n# pragma warning(disable:4996)  // Temporarily disables warning 4996\r\n  // (function or variable may be unsafe).\r\n  const struct tm* const time_struct = localtime(&seconds);  // NOLINT\r\n# pragma warning(pop)           // Restores the warning state again.\r\n#else\r\n  const struct tm* const time_struct = localtime(&seconds);  // NOLINT\r\n#endif\r\n\r\n  if (time_struct == NULL) {\r\n    return \"\";  // Invalid ms value\r\n  }\r\n\r\n  // YYYY-MM-DDThh:mm:ss\r\n  return StreamableToString(time_struct->tm_year + 1900) + \"-\" +\r\n         String::FormatIntWidth2(time_struct->tm_mon + 1) + \"-\" +\r\n         String::FormatIntWidth2(time_struct->tm_mday) + \"T\" +\r\n         String::FormatIntWidth2(time_struct->tm_hour) + \":\" +\r\n         String::FormatIntWidth2(time_struct->tm_min) + \":\" +\r\n         String::FormatIntWidth2(time_struct->tm_sec);\r\n}\r\n\r\n// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.\r\nvoid XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,\r\n    const char* data) {\r\n  const char* segment = data;\r\n  *stream << \"<![CDATA[\";\r\n\r\n  for (;;) {\r\n    const char* const next_segment = strstr(segment, \"]]>\");\r\n\r\n    if (next_segment != NULL) {\r\n      stream->write(\r\n        segment, static_cast<std::streamsize>(next_segment - segment));\r\n      *stream << \"]]>]]&gt;<![CDATA[\";\r\n      segment = next_segment + strlen(\"]]>\");\r\n    }\r\n    else {\r\n      *stream << segment;\r\n      break;\r\n    }\r\n  }\r\n\r\n  *stream << \"]]>\";\r\n}\r\n\r\nvoid XmlUnitTestResultPrinter::OutputXmlAttribute(\r\n  std::ostream* stream,\r\n  const std::string& element_name,\r\n  const std::string& name,\r\n  const std::string& value) {\r\n  const std::vector<std::string>& allowed_names =\r\n    GetReservedAttributesForElement(element_name);\r\n\r\n  GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=\r\n               allowed_names.end())\r\n      << \"Attribute \" << name << \" is not allowed for element <\" << element_name\r\n      << \">.\";\r\n\r\n  *stream << \" \" << name << \"=\\\"\" << EscapeXmlAttribute(value) << \"\\\"\";\r\n}\r\n\r\n// Prints an XML representation of a TestInfo object.\r\n// TODO(wan): There is also value in printing properties with the plain printer.\r\nvoid XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,\r\n    const char* test_case_name,\r\n    const TestInfo& test_info) {\r\n  const TestResult& result = *test_info.result();\r\n  const std::string kTestcase = \"testcase\";\r\n\r\n  *stream << \"    <testcase\";\r\n  OutputXmlAttribute(stream, kTestcase, \"name\", test_info.name());\r\n\r\n  if (test_info.value_param() != NULL) {\r\n    OutputXmlAttribute(stream, kTestcase, \"value_param\",\r\n                       test_info.value_param());\r\n  }\r\n\r\n  if (test_info.type_param() != NULL) {\r\n    OutputXmlAttribute(stream, kTestcase, \"type_param\", test_info.type_param());\r\n  }\r\n\r\n  OutputXmlAttribute(stream, kTestcase, \"status\",\r\n                     test_info.should_run() ? \"run\" : \"notrun\");\r\n  OutputXmlAttribute(stream, kTestcase, \"time\",\r\n                     FormatTimeInMillisAsSeconds(result.elapsed_time()));\r\n  OutputXmlAttribute(stream, kTestcase, \"classname\", test_case_name);\r\n  *stream << TestPropertiesAsXmlAttributes(result);\r\n\r\n  int failures = 0;\r\n\r\n  for (int i = 0; i < result.total_part_count(); ++i) {\r\n    const TestPartResult& part = result.GetTestPartResult(i);\r\n\r\n    if (part.failed()) {\r\n      if (++failures == 1) {\r\n        *stream << \">\\n\";\r\n      }\r\n\r\n      const string location = internal::FormatCompilerIndependentFileLocation(\r\n                                part.file_name(), part.line_number());\r\n      const string summary = location + \"\\n\" + part.summary();\r\n      *stream << \"      <failure message=\\\"\"\r\n              << EscapeXmlAttribute(summary.c_str())\r\n              << \"\\\" type=\\\"\\\">\";\r\n      const string detail = location + \"\\n\" + part.message();\r\n      OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());\r\n      *stream << \"</failure>\\n\";\r\n    }\r\n  }\r\n\r\n  if (failures == 0) {\r\n    *stream << \" />\\n\";\r\n  }\r\n  else {\r\n    *stream << \"    </testcase>\\n\";\r\n  }\r\n}\r\n\r\n// Prints an XML representation of a TestCase object\r\nvoid XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,\r\n    const TestCase& test_case) {\r\n  const std::string kTestsuite = \"testsuite\";\r\n  *stream << \"  <\" << kTestsuite;\r\n  OutputXmlAttribute(stream, kTestsuite, \"name\", test_case.name());\r\n  OutputXmlAttribute(stream, kTestsuite, \"tests\",\r\n                     StreamableToString(test_case.reportable_test_count()));\r\n  OutputXmlAttribute(stream, kTestsuite, \"failures\",\r\n                     StreamableToString(test_case.failed_test_count()));\r\n  OutputXmlAttribute(\r\n    stream, kTestsuite, \"disabled\",\r\n    StreamableToString(test_case.reportable_disabled_test_count()));\r\n  OutputXmlAttribute(stream, kTestsuite, \"errors\", \"0\");\r\n  OutputXmlAttribute(stream, kTestsuite, \"time\",\r\n                     FormatTimeInMillisAsSeconds(test_case.elapsed_time()));\r\n  *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result())\r\n          << \">\\n\";\r\n\r\n  for (int i = 0; i < test_case.total_test_count(); ++i) {\r\n    if (test_case.GetTestInfo(i)->is_reportable()) {\r\n      OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));\r\n    }\r\n  }\r\n\r\n  *stream << \"  </\" << kTestsuite << \">\\n\";\r\n}\r\n\r\n// Prints an XML summary of unit_test to output stream out.\r\nvoid XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,\r\n    const UnitTest& unit_test) {\r\n  const std::string kTestsuites = \"testsuites\";\r\n\r\n  *stream << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\r\n  *stream << \"<\" << kTestsuites;\r\n\r\n  OutputXmlAttribute(stream, kTestsuites, \"tests\",\r\n                     StreamableToString(unit_test.reportable_test_count()));\r\n  OutputXmlAttribute(stream, kTestsuites, \"failures\",\r\n                     StreamableToString(unit_test.failed_test_count()));\r\n  OutputXmlAttribute(\r\n    stream, kTestsuites, \"disabled\",\r\n    StreamableToString(unit_test.reportable_disabled_test_count()));\r\n  OutputXmlAttribute(stream, kTestsuites, \"errors\", \"0\");\r\n  OutputXmlAttribute(\r\n    stream, kTestsuites, \"timestamp\",\r\n    FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));\r\n  OutputXmlAttribute(stream, kTestsuites, \"time\",\r\n                     FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));\r\n\r\n  if (GTEST_FLAG(shuffle)) {\r\n    OutputXmlAttribute(stream, kTestsuites, \"random_seed\",\r\n                       StreamableToString(unit_test.random_seed()));\r\n  }\r\n\r\n  *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());\r\n\r\n  OutputXmlAttribute(stream, kTestsuites, \"name\", \"AllTests\");\r\n  *stream << \">\\n\";\r\n\r\n  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {\r\n    if (unit_test.GetTestCase(i)->reportable_test_count() > 0) {\r\n      PrintXmlTestCase(stream, *unit_test.GetTestCase(i));\r\n    }\r\n  }\r\n\r\n  *stream << \"</\" << kTestsuites << \">\\n\";\r\n}\r\n\r\n// Produces a string representing the test properties in a result as space\r\n// delimited XML attributes based on the property key=\"value\" pairs.\r\nstd::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(\r\n  const TestResult& result) {\r\n  Message attributes;\r\n\r\n  for (int i = 0; i < result.test_property_count(); ++i) {\r\n    const TestProperty& property = result.GetTestProperty(i);\r\n    attributes << \" \" << property.key() << \"=\"\r\n               << \"\\\"\" << EscapeXmlAttribute(property.value()) << \"\\\"\";\r\n  }\r\n\r\n  return attributes.GetString();\r\n}\r\n\r\n// End XmlUnitTestResultPrinter\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n\r\n// Checks if str contains '=', '&', '%' or '\\n' characters. If yes,\r\n// replaces them by \"%xx\" where xx is their hexadecimal value. For\r\n// example, replaces \"=\" with \"%3D\".  This algorithm is O(strlen(str))\r\n// in both time and space -- important as the input str may contain an\r\n// arbitrarily long test failure message and stack trace.\r\nstring StreamingListener::UrlEncode(const char* str) {\r\n  string result;\r\n  result.reserve(strlen(str) + 1);\r\n\r\n  for (char ch = *str; ch != '\\0'; ch = *++str) {\r\n    switch (ch) {\r\n      case '%':\r\n      case '=':\r\n      case '&':\r\n      case '\\n':\r\n        result.append(\"%\" + String::FormatByte(static_cast<unsigned char>(ch)));\r\n        break;\r\n\r\n      default:\r\n        result.push_back(ch);\r\n        break;\r\n    }\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nvoid StreamingListener::SocketWriter::MakeConnection() {\r\n  GTEST_CHECK_(sockfd_ == -1)\r\n      << \"MakeConnection() can't be called when there is already a connection.\";\r\n\r\n  addrinfo hints;\r\n  memset(&hints, 0, sizeof(hints));\r\n  hints.ai_family = AF_UNSPEC;    // To allow both IPv4 and IPv6 addresses.\r\n  hints.ai_socktype = SOCK_STREAM;\r\n  addrinfo* servinfo = NULL;\r\n\r\n  // Use the getaddrinfo() to get a linked list of IP addresses for\r\n  // the given host name.\r\n  const int error_num = getaddrinfo(\r\n                          host_name_.c_str(), port_num_.c_str(), &hints, &servinfo);\r\n\r\n  if (error_num != 0) {\r\n    GTEST_LOG_(WARNING) << \"stream_result_to: getaddrinfo() failed: \"\r\n                        << gai_strerror(error_num);\r\n  }\r\n\r\n  // Loop through all the results and connect to the first we can.\r\n  for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;\r\n       cur_addr = cur_addr->ai_next) {\r\n    sockfd_ = socket(\r\n                cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);\r\n\r\n    if (sockfd_ != -1) {\r\n      // Connect the client socket to the server socket.\r\n      if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) {\r\n        close(sockfd_);\r\n        sockfd_ = -1;\r\n      }\r\n    }\r\n  }\r\n\r\n  freeaddrinfo(servinfo);  // all done with this structure\r\n\r\n  if (sockfd_ == -1) {\r\n    GTEST_LOG_(WARNING) << \"stream_result_to: failed to connect to \"\r\n                        << host_name_ << \":\" << port_num_;\r\n  }\r\n}\r\n\r\n// End of class Streaming Listener\r\n#endif  // GTEST_CAN_STREAM_RESULTS__\r\n\r\n// Class ScopedTrace\r\n\r\n// Pushes the given source file location and message onto a per-thread\r\n// trace stack maintained by Google Test.\r\nScopedTrace::ScopedTrace(const char* file, int line, const Message& message)\r\nGTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {\r\n  TraceInfo trace;\r\n  trace.file = file;\r\n  trace.line = line;\r\n  trace.message = message.GetString();\r\n\r\n  UnitTest::GetInstance()->PushGTestTrace(trace);\r\n}\r\n\r\n// Pops the info pushed by the c'tor.\r\nScopedTrace::~ScopedTrace()\r\nGTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {\r\n  UnitTest::GetInstance()->PopGTestTrace();\r\n}\r\n\r\n\r\n// class OsStackTraceGetter\r\n\r\n// Returns the current OS stack trace as an std::string.  Parameters:\r\n//\r\n//   max_depth  - the maximum number of stack frames to be included\r\n//                in the trace.\r\n//   skip_count - the number of top frames to be skipped; doesn't count\r\n//                against max_depth.\r\n//\r\nstring OsStackTraceGetter::CurrentStackTrace(int /* max_depth */,\r\n    int /* skip_count */)\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  return \"\";\r\n}\r\n\r\nvoid OsStackTraceGetter::UponLeavingGTest()\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n}\r\n\r\nconst char* const\r\nOsStackTraceGetter::kElidedFramesMarker =\r\n  \"... \" GTEST_NAME_ \" internal frames ...\";\r\n\r\n// A helper class that creates the premature-exit file in its\r\n// constructor and deletes the file in its destructor.\r\nclass ScopedPrematureExitFile {\r\n public:\r\n  explicit ScopedPrematureExitFile(const char* premature_exit_filepath)\r\n    : premature_exit_filepath_(premature_exit_filepath) {\r\n    // If a path to the premature-exit file is specified...\r\n    if (premature_exit_filepath != NULL && *premature_exit_filepath != '\\0') {\r\n      // create the file with a single \"0\" character in it.  I/O\r\n      // errors are ignored as there's nothing better we can do and we\r\n      // don't want to fail the test because of this.\r\n      FILE* pfile = posix::FOpen(premature_exit_filepath, \"w\");\r\n      fwrite(\"0\", 1, 1, pfile);\r\n      fclose(pfile);\r\n    }\r\n  }\r\n\r\n  ~ScopedPrematureExitFile() {\r\n    if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\\0') {\r\n      remove(premature_exit_filepath_);\r\n    }\r\n  }\r\n\r\n private:\r\n  const char* const premature_exit_filepath_;\r\n\r\n  GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);\r\n};\r\n\r\n}  // namespace internal\r\n\r\n// class TestEventListeners\r\n\r\nTestEventListeners::TestEventListeners()\r\n  : repeater_(new internal::TestEventRepeater()),\r\n    default_result_printer_(NULL),\r\n    default_xml_generator_(NULL) {\r\n}\r\n\r\nTestEventListeners::~TestEventListeners() {\r\n  delete repeater_;\r\n}\r\n\r\n// Returns the standard listener responsible for the default console\r\n// output.  Can be removed from the listeners list to shut down default\r\n// console output.  Note that removing this object from the listener list\r\n// with Release transfers its ownership to the user.\r\nvoid TestEventListeners::Append(TestEventListener* listener) {\r\n  repeater_->Append(listener);\r\n}\r\n\r\n// Removes the given event listener from the list and returns it.  It then\r\n// becomes the caller's responsibility to delete the listener. Returns\r\n// NULL if the listener is not found in the list.\r\nTestEventListener* TestEventListeners::Release(TestEventListener* listener) {\r\n  if (listener == default_result_printer_) {\r\n    default_result_printer_ = NULL;\r\n  }\r\n  else if (listener == default_xml_generator_) {\r\n    default_xml_generator_ = NULL;\r\n  }\r\n\r\n  return repeater_->Release(listener);\r\n}\r\n\r\n// Returns repeater that broadcasts the TestEventListener events to all\r\n// subscribers.\r\nTestEventListener* TestEventListeners::repeater() {\r\n  return repeater_;\r\n}\r\n\r\n// Sets the default_result_printer attribute to the provided listener.\r\n// The listener is also added to the listener list and previous\r\n// default_result_printer is removed from it and deleted. The listener can\r\n// also be NULL in which case it will not be added to the list. Does\r\n// nothing if the previous and the current listener objects are the same.\r\nvoid TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {\r\n  if (default_result_printer_ != listener) {\r\n    // It is an error to pass this method a listener that is already in the\r\n    // list.\r\n    delete Release(default_result_printer_);\r\n    default_result_printer_ = listener;\r\n\r\n    if (listener != NULL) {\r\n      Append(listener);\r\n    }\r\n  }\r\n}\r\n\r\n// Sets the default_xml_generator attribute to the provided listener.  The\r\n// listener is also added to the listener list and previous\r\n// default_xml_generator is removed from it and deleted. The listener can\r\n// also be NULL in which case it will not be added to the list. Does\r\n// nothing if the previous and the current listener objects are the same.\r\nvoid TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {\r\n  if (default_xml_generator_ != listener) {\r\n    // It is an error to pass this method a listener that is already in the\r\n    // list.\r\n    delete Release(default_xml_generator_);\r\n    default_xml_generator_ = listener;\r\n\r\n    if (listener != NULL) {\r\n      Append(listener);\r\n    }\r\n  }\r\n}\r\n\r\n// Controls whether events will be forwarded by the repeater to the\r\n// listeners in the list.\r\nbool TestEventListeners::EventForwardingEnabled() const {\r\n  return repeater_->forwarding_enabled();\r\n}\r\n\r\nvoid TestEventListeners::SuppressEventForwarding() {\r\n  repeater_->set_forwarding_enabled(false);\r\n}\r\n\r\n// class UnitTest\r\n\r\n// Gets the singleton UnitTest object.  The first time this method is\r\n// called, a UnitTest object is constructed and returned.  Consecutive\r\n// calls will return the same object.\r\n//\r\n// We don't protect this under mutex_ as a user is not supposed to\r\n// call this before main() starts, from which point on the return\r\n// value will never change.\r\nUnitTest* UnitTest::GetInstance() {\r\n  // When compiled with MSVC 7.1 in optimized mode, destroying the\r\n  // UnitTest object upon exiting the program messes up the exit code,\r\n  // causing successful tests to appear failed.  We have to use a\r\n  // different implementation in this case to bypass the compiler bug.\r\n  // This implementation makes the compiler happy, at the cost of\r\n  // leaking the UnitTest object.\r\n\r\n  // CodeGear C++Builder insists on a public destructor for the\r\n  // default implementation.  Use this implementation to keep good OO\r\n  // design with private destructor.\r\n\r\n#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)\r\n  static UnitTest* const instance = new UnitTest;\r\n  return instance;\r\n#else\r\n  static UnitTest instance;\r\n  return &instance;\r\n#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)\r\n}\r\n\r\n// Gets the number of successful test cases.\r\nint UnitTest::successful_test_case_count() const {\r\n  return impl()->successful_test_case_count();\r\n}\r\n\r\n// Gets the number of failed test cases.\r\nint UnitTest::failed_test_case_count() const {\r\n  return impl()->failed_test_case_count();\r\n}\r\n\r\n// Gets the number of all test cases.\r\nint UnitTest::total_test_case_count() const {\r\n  return impl()->total_test_case_count();\r\n}\r\n\r\n// Gets the number of all test cases that contain at least one test\r\n// that should run.\r\nint UnitTest::test_case_to_run_count() const {\r\n  return impl()->test_case_to_run_count();\r\n}\r\n\r\n// Gets the number of successful tests.\r\nint UnitTest::successful_test_count() const {\r\n  return impl()->successful_test_count();\r\n}\r\n\r\n// Gets the number of failed tests.\r\nint UnitTest::failed_test_count() const {\r\n  return impl()->failed_test_count();\r\n}\r\n\r\n// Gets the number of disabled tests that will be reported in the XML report.\r\nint UnitTest::reportable_disabled_test_count() const {\r\n  return impl()->reportable_disabled_test_count();\r\n}\r\n\r\n// Gets the number of disabled tests.\r\nint UnitTest::disabled_test_count() const {\r\n  return impl()->disabled_test_count();\r\n}\r\n\r\n// Gets the number of tests to be printed in the XML report.\r\nint UnitTest::reportable_test_count() const {\r\n  return impl()->reportable_test_count();\r\n}\r\n\r\n// Gets the number of all tests.\r\nint UnitTest::total_test_count() const {\r\n  return impl()->total_test_count();\r\n}\r\n\r\n// Gets the number of tests that should run.\r\nint UnitTest::test_to_run_count() const {\r\n  return impl()->test_to_run_count();\r\n}\r\n\r\n// Gets the time of the test program start, in ms from the start of the\r\n// UNIX epoch.\r\ninternal::TimeInMillis UnitTest::start_timestamp() const {\r\n  return impl()->start_timestamp();\r\n}\r\n\r\n// Gets the elapsed time, in milliseconds.\r\ninternal::TimeInMillis UnitTest::elapsed_time() const {\r\n  return impl()->elapsed_time();\r\n}\r\n\r\n// Returns true iff the unit test passed (i.e. all test cases passed).\r\nbool UnitTest::Passed() const {\r\n  return impl()->Passed();\r\n}\r\n\r\n// Returns true iff the unit test failed (i.e. some test case failed\r\n// or something outside of all tests failed).\r\nbool UnitTest::Failed() const {\r\n  return impl()->Failed();\r\n}\r\n\r\n// Gets the i-th test case among all the test cases. i can range from 0 to\r\n// total_test_case_count() - 1. If i is not in that range, returns NULL.\r\nconst TestCase* UnitTest::GetTestCase(int i) const {\r\n  return impl()->GetTestCase(i);\r\n}\r\n\r\n// Returns the TestResult containing information on test failures and\r\n// properties logged outside of individual test cases.\r\nconst TestResult& UnitTest::ad_hoc_test_result() const {\r\n  return *impl()->ad_hoc_test_result();\r\n}\r\n\r\n// Gets the i-th test case among all the test cases. i can range from 0 to\r\n// total_test_case_count() - 1. If i is not in that range, returns NULL.\r\nTestCase* UnitTest::GetMutableTestCase(int i) {\r\n  return impl()->GetMutableTestCase(i);\r\n}\r\n\r\n// Returns the list of event listeners that can be used to track events\r\n// inside Google Test.\r\nTestEventListeners& UnitTest::listeners() {\r\n  return *impl()->listeners();\r\n}\r\n\r\n// Registers and returns a global test environment.  When a test\r\n// program is run, all global test environments will be set-up in the\r\n// order they were registered.  After all tests in the program have\r\n// finished, all global test environments will be torn-down in the\r\n// *reverse* order they were registered.\r\n//\r\n// The UnitTest object takes ownership of the given environment.\r\n//\r\n// We don't protect this under mutex_, as we only support calling it\r\n// from the main thread.\r\nEnvironment* UnitTest::AddEnvironment(Environment* env) {\r\n  if (env == NULL) {\r\n    return NULL;\r\n  }\r\n\r\n  impl_->environments().push_back(env);\r\n  return env;\r\n}\r\n\r\n// Adds a TestPartResult to the current TestResult object.  All Google Test\r\n// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call\r\n// this to report their results.  The user code should use the\r\n// assertion macros instead of calling this directly.\r\nvoid UnitTest::AddTestPartResult(\r\n  TestPartResult::Type result_type,\r\n  const char* file_name,\r\n  int line_number,\r\n  const std::string& message,\r\n  const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) {\r\n  Message msg;\r\n  msg << message;\r\n\r\n  internal::MutexLock lock(&mutex_);\r\n\r\n  if (impl_->gtest_trace_stack().size() > 0) {\r\n    msg << \"\\n\" << GTEST_NAME_ << \" trace:\";\r\n\r\n    for (int i = static_cast<int>(impl_->gtest_trace_stack().size());\r\n         i > 0; --i) {\r\n      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];\r\n      msg << \"\\n\" << internal::FormatFileLocation(trace.file, trace.line)\r\n          << \" \" << trace.message;\r\n    }\r\n  }\r\n\r\n  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {\r\n    msg << internal::kStackTraceMarker << os_stack_trace;\r\n  }\r\n\r\n  const TestPartResult result =\r\n    TestPartResult(result_type, file_name, line_number,\r\n                   msg.GetString().c_str());\r\n  impl_->GetTestPartResultReporterForCurrentThread()->\r\n  ReportTestPartResult(result);\r\n\r\n  if (result_type != TestPartResult::kSuccess) {\r\n    // gtest_break_on_failure takes precedence over\r\n    // gtest_throw_on_failure.  This allows a user to set the latter\r\n    // in the code (perhaps in order to use Google Test assertions\r\n    // with another testing framework) and specify the former on the\r\n    // command line for debugging.\r\n    if (GTEST_FLAG(break_on_failure)) {\r\n#if GTEST_OS_WINDOWS\r\n      // Using DebugBreak on Windows allows gtest to still break into a debugger\r\n      // when a failure happens and both the --gtest_break_on_failure and\r\n      // the --gtest_catch_exceptions flags are specified.\r\n      DebugBreak();\r\n#else\r\n      // Dereference NULL through a volatile pointer to prevent the compiler\r\n      // from removing. We use this rather than abort() or __builtin_trap() for\r\n      // portability: Symbian doesn't implement abort() well, and some debuggers\r\n      // don't correctly trap abort().\r\n      *static_cast<volatile int*>(NULL) = 1;\r\n#endif  // GTEST_OS_WINDOWS\r\n    }\r\n    else if (GTEST_FLAG(throw_on_failure)) {\r\n#if GTEST_HAS_EXCEPTIONS\r\n      throw internal::GoogleTestFailureException(result);\r\n#else\r\n      // We cannot call abort() as it generates a pop-up in debug mode\r\n      // that cannot be suppressed in VC 7.1 or below.\r\n      exit(1);\r\n#endif\r\n    }\r\n  }\r\n}\r\n\r\n// Adds a TestProperty to the current TestResult object when invoked from\r\n// inside a test, to current TestCase's ad_hoc_test_result_ when invoked\r\n// from SetUpTestCase or TearDownTestCase, or to the global property set\r\n// when invoked elsewhere.  If the result already contains a property with\r\n// the same key, the value will be updated.\r\nvoid UnitTest::RecordProperty(const std::string& key,\r\n                              const std::string& value) {\r\n  impl_->RecordProperty(TestProperty(key, value));\r\n}\r\n\r\n// Runs all tests in this UnitTest object and prints the result.\r\n// Returns 0 if successful, or 1 otherwise.\r\n//\r\n// We don't protect this under mutex_, as we only support calling it\r\n// from the main thread.\r\nint UnitTest::Run() {\r\n  const bool in_death_test_child_process =\r\n    internal::GTEST_FLAG(internal_run_death_test).length() > 0;\r\n\r\n  // Google Test implements this protocol for catching that a test\r\n  // program exits before returning control to Google Test:\r\n  //\r\n  //   1. Upon start, Google Test creates a file whose absolute path\r\n  //      is specified by the environment variable\r\n  //      TEST_PREMATURE_EXIT_FILE.\r\n  //   2. When Google Test has finished its work, it deletes the file.\r\n  //\r\n  // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before\r\n  // running a Google-Test-based test program and check the existence\r\n  // of the file at the end of the test execution to see if it has\r\n  // exited prematurely.\r\n\r\n  // If we are in the child process of a death test, don't\r\n  // create/delete the premature exit file, as doing so is unnecessary\r\n  // and will confuse the parent process.  Otherwise, create/delete\r\n  // the file upon entering/leaving this function.  If the program\r\n  // somehow exits before this function has a chance to return, the\r\n  // premature-exit file will be left undeleted, causing a test runner\r\n  // that understands the premature-exit-file protocol to report the\r\n  // test as having failed.\r\n  const internal::ScopedPrematureExitFile premature_exit_file(\r\n    in_death_test_child_process ?\r\n    NULL : internal::posix::GetEnv(\"TEST_PREMATURE_EXIT_FILE\"));\r\n\r\n  // Captures the value of GTEST_FLAG(catch_exceptions).  This value will be\r\n  // used for the duration of the program.\r\n  impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));\r\n\r\n#if GTEST_HAS_SEH\r\n\r\n  // Either the user wants Google Test to catch exceptions thrown by the\r\n  // tests or this is executing in the context of death test child\r\n  // process. In either case the user does not want to see pop-up dialogs\r\n  // about crashes - they are expected.\r\n  if (impl()->catch_exceptions() || in_death_test_child_process) {\r\n# if !GTEST_OS_WINDOWS_MOBILE\r\n    // SetErrorMode doesn't exist on CE.\r\n    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |\r\n                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);\r\n# endif  // !GTEST_OS_WINDOWS_MOBILE\r\n\r\n# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE\r\n    // Death test children can be terminated with _abort().  On Windows,\r\n    // _abort() can show a dialog with a warning message.  This forces the\r\n    // abort message to go to stderr instead.\r\n    _set_error_mode(_OUT_TO_STDERR);\r\n# endif\r\n\r\n# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE\r\n\r\n    // In the debug version, Visual Studio pops up a separate dialog\r\n    // offering a choice to debug the aborted program. We need to suppress\r\n    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement\r\n    // executed. Google Test will notify the user of any unexpected\r\n    // failure via stderr.\r\n    //\r\n    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.\r\n    // Users of prior VC versions shall suffer the agony and pain of\r\n    // clicking through the countless debug dialogs.\r\n    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the\r\n    // debug mode when compiled with VC 7.1 or lower.\r\n    if (!GTEST_FLAG(break_on_failure))\r\n      _set_abort_behavior(\r\n        0x0,                                    // Clear the following flags:\r\n        _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.\r\n\r\n# endif\r\n  }\r\n\r\n#endif  // GTEST_HAS_SEH\r\n\r\n  return internal::HandleExceptionsInMethodIfSupported(\r\n           impl(),\r\n           &internal::UnitTestImpl::RunAllTests,\r\n           \"auxiliary test code (environments or event listeners)\") ? 0 : 1;\r\n}\r\n\r\n// Returns the working directory when the first TEST() or TEST_F() was\r\n// executed.\r\nconst char* UnitTest::original_working_dir() const {\r\n  return impl_->original_working_dir_.c_str();\r\n}\r\n\r\n// Returns the TestCase object for the test that's currently running,\r\n// or NULL if no test is running.\r\nconst TestCase* UnitTest::current_test_case() const\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  internal::MutexLock lock(&mutex_);\r\n  return impl_->current_test_case();\r\n}\r\n\r\n// Returns the TestInfo object for the test that's currently running,\r\n// or NULL if no test is running.\r\nconst TestInfo* UnitTest::current_test_info() const\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  internal::MutexLock lock(&mutex_);\r\n  return impl_->current_test_info();\r\n}\r\n\r\n// Returns the random seed used at the start of the current test run.\r\nint UnitTest::random_seed() const {\r\n  return impl_->random_seed();\r\n}\r\n\r\n#if GTEST_HAS_PARAM_TEST\r\n// Returns ParameterizedTestCaseRegistry object used to keep track of\r\n// value-parameterized tests and instantiate and register them.\r\ninternal::ParameterizedTestCaseRegistry&\r\nUnitTest::parameterized_test_registry()\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  return impl_->parameterized_test_registry();\r\n}\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n\r\n// Creates an empty UnitTest.\r\nUnitTest::UnitTest() {\r\n  impl_ = new internal::UnitTestImpl(this);\r\n}\r\n\r\n// Destructor of UnitTest.\r\nUnitTest::~UnitTest() {\r\n  delete impl_;\r\n}\r\n\r\n// Pushes a trace defined by SCOPED_TRACE() on to the per-thread\r\n// Google Test trace stack.\r\nvoid UnitTest::PushGTestTrace(const internal::TraceInfo& trace)\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  internal::MutexLock lock(&mutex_);\r\n  impl_->gtest_trace_stack().push_back(trace);\r\n}\r\n\r\n// Pops a trace from the per-thread Google Test trace stack.\r\nvoid UnitTest::PopGTestTrace()\r\nGTEST_LOCK_EXCLUDED_(mutex_) {\r\n  internal::MutexLock lock(&mutex_);\r\n  impl_->gtest_trace_stack().pop_back();\r\n}\r\n\r\nnamespace internal {\r\n\r\nUnitTestImpl::UnitTestImpl(UnitTest* parent)\r\n  : parent_(parent),\r\n#ifdef _MSC_VER\r\n# pragma warning(push)                    // Saves the current warning state.\r\n# pragma warning(disable:4355)            // Temporarily disables warning 4355\r\n    // (using this in initializer).\r\n    default_global_test_part_result_reporter_(this),\r\n    default_per_thread_test_part_result_reporter_(this),\r\n# pragma warning(pop)                     // Restores the warning state again.\r\n#else\r\n    default_global_test_part_result_reporter_(this),\r\n    default_per_thread_test_part_result_reporter_(this),\r\n#endif  // _MSC_VER\r\n    global_test_part_result_repoter_(\r\n      &default_global_test_part_result_reporter_),\r\n    per_thread_test_part_result_reporter_(\r\n      &default_per_thread_test_part_result_reporter_),\r\n#if GTEST_HAS_PARAM_TEST\r\n    parameterized_test_registry_(),\r\n    parameterized_tests_registered_(false),\r\n#endif  // GTEST_HAS_PARAM_TEST\r\n    last_death_test_case_(-1),\r\n    current_test_case_(NULL),\r\n    current_test_info_(NULL),\r\n    ad_hoc_test_result_(),\r\n    os_stack_trace_getter_(NULL),\r\n    post_flag_parse_init_performed_(false),\r\n    random_seed_(0),  // Will be overridden by the flag before first use.\r\n    random_(0),  // Will be reseeded before first use.\r\n    start_timestamp_(0),\r\n    elapsed_time_(0),\r\n#if GTEST_HAS_DEATH_TEST\r\n    death_test_factory_(new DefaultDeathTestFactory),\r\n#endif\r\n    // Will be overridden by the flag before first use.\r\n    catch_exceptions_(false) {\r\n  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);\r\n}\r\n\r\nUnitTestImpl::~UnitTestImpl() {\r\n  // Deletes every TestCase.\r\n  ForEach(test_cases_, internal::Delete<TestCase>);\r\n\r\n  // Deletes every Environment.\r\n  ForEach(environments_, internal::Delete<Environment>);\r\n\r\n  delete os_stack_trace_getter_;\r\n}\r\n\r\n// Adds a TestProperty to the current TestResult object when invoked in a\r\n// context of a test, to current test case's ad_hoc_test_result when invoke\r\n// from SetUpTestCase/TearDownTestCase, or to the global property set\r\n// otherwise.  If the result already contains a property with the same key,\r\n// the value will be updated.\r\nvoid UnitTestImpl::RecordProperty(const TestProperty& test_property) {\r\n  std::string xml_element;\r\n  TestResult* test_result;  // TestResult appropriate for property recording.\r\n\r\n  if (current_test_info_ != NULL) {\r\n    xml_element = \"testcase\";\r\n    test_result = &(current_test_info_->result_);\r\n  }\r\n  else if (current_test_case_ != NULL) {\r\n    xml_element = \"testsuite\";\r\n    test_result = &(current_test_case_->ad_hoc_test_result_);\r\n  }\r\n  else {\r\n    xml_element = \"testsuites\";\r\n    test_result = &ad_hoc_test_result_;\r\n  }\r\n\r\n  test_result->RecordProperty(xml_element, test_property);\r\n}\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n// Disables event forwarding if the control is currently in a death test\r\n// subprocess. Must not be called before InitGoogleTest.\r\nvoid UnitTestImpl::SuppressTestEventsIfInSubprocess() {\r\n  if (internal_run_death_test_flag_.get() != NULL) {\r\n    listeners()->SuppressEventForwarding();\r\n  }\r\n}\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n// Initializes event listeners performing XML output as specified by\r\n// UnitTestOptions. Must not be called before InitGoogleTest.\r\nvoid UnitTestImpl::ConfigureXmlOutput() {\r\n  const std::string& output_format = UnitTestOptions::GetOutputFormat();\r\n\r\n  if (output_format == \"xml\") {\r\n    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(\r\n                                          UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));\r\n  }\r\n  else if (output_format != \"\") {\r\n    printf(\"WARNING: unrecognized output format \\\"%s\\\" ignored.\\n\",\r\n           output_format.c_str());\r\n    fflush(stdout);\r\n  }\r\n}\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n// Initializes event listeners for streaming test results in string form.\r\n// Must not be called before InitGoogleTest.\r\nvoid UnitTestImpl::ConfigureStreamingOutput() {\r\n  const std::string& target = GTEST_FLAG(stream_result_to);\r\n\r\n  if (!target.empty()) {\r\n    const size_t pos = target.find(':');\r\n\r\n    if (pos != std::string::npos) {\r\n      listeners()->Append(new StreamingListener(target.substr(0, pos),\r\n                          target.substr(pos + 1)));\r\n    }\r\n    else {\r\n      printf(\"WARNING: unrecognized streaming target \\\"%s\\\" ignored.\\n\",\r\n             target.c_str());\r\n      fflush(stdout);\r\n    }\r\n  }\r\n}\r\n#endif  // GTEST_CAN_STREAM_RESULTS_\r\n\r\n// Performs initialization dependent upon flag values obtained in\r\n// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to\r\n// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest\r\n// this function is also called from RunAllTests.  Since this function can be\r\n// called more than once, it has to be idempotent.\r\nvoid UnitTestImpl::PostFlagParsingInit() {\r\n  // Ensures that this function does not execute more than once.\r\n  if (!post_flag_parse_init_performed_) {\r\n    post_flag_parse_init_performed_ = true;\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n    InitDeathTestSubprocessControlInfo();\r\n    SuppressTestEventsIfInSubprocess();\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n    // Registers parameterized tests. This makes parameterized tests\r\n    // available to the UnitTest reflection API without running\r\n    // RUN_ALL_TESTS.\r\n    RegisterParameterizedTests();\r\n\r\n    // Configures listeners for XML output. This makes it possible for users\r\n    // to shut down the default XML output before invoking RUN_ALL_TESTS.\r\n    ConfigureXmlOutput();\r\n\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n    // Configures listeners for streaming test results to the specified server.\r\n    ConfigureStreamingOutput();\r\n#endif  // GTEST_CAN_STREAM_RESULTS_\r\n  }\r\n}\r\n\r\n// A predicate that checks the name of a TestCase against a known\r\n// value.\r\n//\r\n// This is used for implementation of the UnitTest class only.  We put\r\n// it in the anonymous namespace to prevent polluting the outer\r\n// namespace.\r\n//\r\n// TestCaseNameIs is copyable.\r\nclass TestCaseNameIs {\r\n public:\r\n  // Constructor.\r\n  explicit TestCaseNameIs(const std::string& name)\r\n    : name_(name) {}\r\n\r\n  // Returns true iff the name of test_case matches name_.\r\n  bool operator()(const TestCase* test_case) const {\r\n    return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;\r\n  }\r\n\r\n private:\r\n  std::string name_;\r\n};\r\n\r\n// Finds and returns a TestCase with the given name.  If one doesn't\r\n// exist, creates one and returns it.  It's the CALLER'S\r\n// RESPONSIBILITY to ensure that this function is only called WHEN THE\r\n// TESTS ARE NOT SHUFFLED.\r\n//\r\n// Arguments:\r\n//\r\n//   test_case_name: name of the test case\r\n//   type_param:     the name of the test case's type parameter, or NULL if\r\n//                   this is not a typed or a type-parameterized test case.\r\n//   set_up_tc:      pointer to the function that sets up the test case\r\n//   tear_down_tc:   pointer to the function that tears down the test case\r\nTestCase* UnitTestImpl::GetTestCase(const char* test_case_name,\r\n                                    const char* type_param,\r\n                                    Test::SetUpTestCaseFunc set_up_tc,\r\n                                    Test::TearDownTestCaseFunc tear_down_tc) {\r\n  // Can we find a TestCase with the given name?\r\n  const std::vector<TestCase*>::const_iterator test_case =\r\n    std::find_if(test_cases_.begin(), test_cases_.end(),\r\n                 TestCaseNameIs(test_case_name));\r\n\r\n  if (test_case != test_cases_.end()) {\r\n    return *test_case;\r\n  }\r\n\r\n  // No.  Let's create one.\r\n  TestCase* const new_test_case =\r\n    new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);\r\n\r\n  // Is this a death test case?\r\n  if (internal::UnitTestOptions::MatchesFilter(test_case_name,\r\n      kDeathTestCaseFilter)) {\r\n    // Yes.  Inserts the test case after the last death test case\r\n    // defined so far.  This only works when the test cases haven't\r\n    // been shuffled.  Otherwise we may end up running a death test\r\n    // after a non-death test.\r\n    ++last_death_test_case_;\r\n    test_cases_.insert(test_cases_.begin() + last_death_test_case_,\r\n                       new_test_case);\r\n  }\r\n  else {\r\n    // No.  Appends to the end of the list.\r\n    test_cases_.push_back(new_test_case);\r\n  }\r\n\r\n  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));\r\n  return new_test_case;\r\n}\r\n\r\n// Helpers for setting up / tearing down the given environment.  They\r\n// are for use in the ForEach() function.\r\nstatic void SetUpEnvironment(Environment* env) {\r\n  env->SetUp();\r\n}\r\nstatic void TearDownEnvironment(Environment* env) {\r\n  env->TearDown();\r\n}\r\n\r\n// Runs all tests in this UnitTest object, prints the result, and\r\n// returns true if all tests are successful.  If any exception is\r\n// thrown during a test, the test is considered to be failed, but the\r\n// rest of the tests will still be run.\r\n//\r\n// When parameterized tests are enabled, it expands and registers\r\n// parameterized tests first in RegisterParameterizedTests().\r\n// All other functions called from RunAllTests() may safely assume that\r\n// parameterized tests are ready to be counted and run.\r\nbool UnitTestImpl::RunAllTests() {\r\n  // Makes sure InitGoogleTest() was called.\r\n  if (!GTestIsInitialized()) {\r\n    printf(\"%s\",\r\n           \"\\nThis test program did NOT call ::testing::InitGoogleTest \"\r\n           \"before calling RUN_ALL_TESTS().  Please fix it.\\n\");\r\n    return false;\r\n  }\r\n\r\n  // Do not run any test if the --help flag was specified.\r\n  if (g_help_flag) {\r\n    return true;\r\n  }\r\n\r\n  // Repeats the call to the post-flag parsing initialization in case the\r\n  // user didn't call InitGoogleTest.\r\n  PostFlagParsingInit();\r\n\r\n  // Even if sharding is not on, test runners may want to use the\r\n  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding\r\n  // protocol.\r\n  internal::WriteToShardStatusFileIfNeeded();\r\n\r\n  // True iff we are in a subprocess for running a thread-safe-style\r\n  // death test.\r\n  bool in_subprocess_for_death_test = false;\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,\r\n                                        in_subprocess_for_death_test);\r\n\r\n  // Compares the full test names with the filter to decide which\r\n  // tests to run.\r\n  const bool has_tests_to_run = FilterTests(should_shard\r\n                                ? HONOR_SHARDING_PROTOCOL\r\n                                : IGNORE_SHARDING_PROTOCOL) > 0;\r\n\r\n  // Lists the tests and exits if the --gtest_list_tests flag was specified.\r\n  if (GTEST_FLAG(list_tests)) {\r\n    // This must be called *after* FilterTests() has been called.\r\n    ListTestsMatchingFilter();\r\n    return true;\r\n  }\r\n\r\n  random_seed_ = GTEST_FLAG(shuffle) ?\r\n                 GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;\r\n\r\n  // True iff at least one test has failed.\r\n  bool failed = false;\r\n\r\n  TestEventListener* repeater = listeners()->repeater();\r\n\r\n  start_timestamp_ = GetTimeInMillis();\r\n  repeater->OnTestProgramStart(*parent_);\r\n\r\n  // How many times to repeat the tests?  We don't want to repeat them\r\n  // when we are inside the subprocess of a death test.\r\n  const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);\r\n  // Repeats forever if the repeat count is negative.\r\n  const bool forever = repeat < 0;\r\n\r\n  for (int i = 0; forever || i != repeat; i++) {\r\n    // We want to preserve failures generated by ad-hoc test\r\n    // assertions executed before RUN_ALL_TESTS().\r\n    ClearNonAdHocTestResult();\r\n\r\n    const TimeInMillis start = GetTimeInMillis();\r\n\r\n    // Shuffles test cases and tests if requested.\r\n    if (has_tests_to_run && GTEST_FLAG(shuffle)) {\r\n      random()->Reseed(random_seed_);\r\n      // This should be done before calling OnTestIterationStart(),\r\n      // such that a test event listener can see the actual test order\r\n      // in the event.\r\n      ShuffleTests();\r\n    }\r\n\r\n    // Tells the unit test event listeners that the tests are about to start.\r\n    repeater->OnTestIterationStart(*parent_, i);\r\n\r\n    // Runs each test case if there is at least one test to run.\r\n    if (has_tests_to_run) {\r\n      // Sets up all environments beforehand.\r\n      repeater->OnEnvironmentsSetUpStart(*parent_);\r\n      ForEach(environments_, SetUpEnvironment);\r\n      repeater->OnEnvironmentsSetUpEnd(*parent_);\r\n\r\n      // Runs the tests only if there was no fatal failure during global\r\n      // set-up.\r\n      if (!Test::HasFatalFailure()) {\r\n        for (int test_index = 0; test_index < total_test_case_count();\r\n             test_index++) {\r\n          GetMutableTestCase(test_index)->Run();\r\n        }\r\n      }\r\n\r\n      // Tears down all environments in reverse order afterwards.\r\n      repeater->OnEnvironmentsTearDownStart(*parent_);\r\n      std::for_each(environments_.rbegin(), environments_.rend(),\r\n                    TearDownEnvironment);\r\n      repeater->OnEnvironmentsTearDownEnd(*parent_);\r\n    }\r\n\r\n    elapsed_time_ = GetTimeInMillis() - start;\r\n\r\n    // Tells the unit test event listener that the tests have just finished.\r\n    repeater->OnTestIterationEnd(*parent_, i);\r\n\r\n    // Gets the result and clears it.\r\n    if (!Passed()) {\r\n      failed = true;\r\n    }\r\n\r\n    // Restores the original test order after the iteration.  This\r\n    // allows the user to quickly repro a failure that happens in the\r\n    // N-th iteration without repeating the first (N - 1) iterations.\r\n    // This is not enclosed in \"if (GTEST_FLAG(shuffle)) { ... }\", in\r\n    // case the user somehow changes the value of the flag somewhere\r\n    // (it's always safe to unshuffle the tests).\r\n    UnshuffleTests();\r\n\r\n    if (GTEST_FLAG(shuffle)) {\r\n      // Picks a new random seed for each iteration.\r\n      random_seed_ = GetNextRandomSeed(random_seed_);\r\n    }\r\n  }\r\n\r\n  repeater->OnTestProgramEnd(*parent_);\r\n\r\n  return !failed;\r\n}\r\n\r\n// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file\r\n// if the variable is present. If a file already exists at this location, this\r\n// function will write over it. If the variable is present, but the file cannot\r\n// be created, prints an error and exits.\r\nvoid WriteToShardStatusFileIfNeeded() {\r\n  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);\r\n\r\n  if (test_shard_file != NULL) {\r\n    FILE* const file = posix::FOpen(test_shard_file, \"w\");\r\n\r\n    if (file == NULL) {\r\n      ColoredPrintf(COLOR_RED,\r\n                    \"Could not write to the test shard status file \\\"%s\\\" \"\r\n                    \"specified by the %s environment variable.\\n\",\r\n                    test_shard_file, kTestShardStatusFile);\r\n      fflush(stdout);\r\n      exit(EXIT_FAILURE);\r\n    }\r\n\r\n    fclose(file);\r\n  }\r\n}\r\n\r\n// Checks whether sharding is enabled by examining the relevant\r\n// environment variable values. If the variables are present,\r\n// but inconsistent (i.e., shard_index >= total_shards), prints\r\n// an error and exits. If in_subprocess_for_death_test, sharding is\r\n// disabled because it must only be applied to the original test\r\n// process. Otherwise, we could filter out death tests we intended to execute.\r\nbool ShouldShard(const char* total_shards_env,\r\n                 const char* shard_index_env,\r\n                 bool in_subprocess_for_death_test) {\r\n  if (in_subprocess_for_death_test) {\r\n    return false;\r\n  }\r\n\r\n  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);\r\n  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);\r\n\r\n  if (total_shards == -1 && shard_index == -1) {\r\n    return false;\r\n  }\r\n  else if (total_shards == -1 && shard_index != -1) {\r\n    const Message msg = Message()\r\n                        << \"Invalid environment variables: you have \"\r\n                        << kTestShardIndex << \" = \" << shard_index\r\n                        << \", but have left \" << kTestTotalShards << \" unset.\\n\";\r\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\r\n    fflush(stdout);\r\n    exit(EXIT_FAILURE);\r\n  }\r\n  else if (total_shards != -1 && shard_index == -1) {\r\n    const Message msg = Message()\r\n                        << \"Invalid environment variables: you have \"\r\n                        << kTestTotalShards << \" = \" << total_shards\r\n                        << \", but have left \" << kTestShardIndex << \" unset.\\n\";\r\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\r\n    fflush(stdout);\r\n    exit(EXIT_FAILURE);\r\n  }\r\n  else if (shard_index < 0 || shard_index >= total_shards) {\r\n    const Message msg = Message()\r\n                        << \"Invalid environment variables: we require 0 <= \"\r\n                        << kTestShardIndex << \" < \" << kTestTotalShards\r\n                        << \", but you have \" << kTestShardIndex << \"=\" << shard_index\r\n                        << \", \" << kTestTotalShards << \"=\" << total_shards << \".\\n\";\r\n    ColoredPrintf(COLOR_RED, msg.GetString().c_str());\r\n    fflush(stdout);\r\n    exit(EXIT_FAILURE);\r\n  }\r\n\r\n  return total_shards > 1;\r\n}\r\n\r\n// Parses the environment variable var as an Int32. If it is unset,\r\n// returns default_val. If it is not an Int32, prints an error\r\n// and aborts.\r\nInt32 Int32FromEnvOrDie(const char* var, Int32 default_val) {\r\n  const char* str_val = posix::GetEnv(var);\r\n\r\n  if (str_val == NULL) {\r\n    return default_val;\r\n  }\r\n\r\n  Int32 result;\r\n\r\n  if (!ParseInt32(Message() << \"The value of environment variable \" << var,\r\n                  str_val, &result)) {\r\n    exit(EXIT_FAILURE);\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\n// Given the total number of shards, the shard index, and the test id,\r\n// returns true iff the test should be run on this shard. The test id is\r\n// some arbitrary but unique non-negative integer assigned to each test\r\n// method. Assumes that 0 <= shard_index < total_shards.\r\nbool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {\r\n  return (test_id % total_shards) == shard_index;\r\n}\r\n\r\n// Compares the name of each test with the user-specified filter to\r\n// decide whether the test should be run, then records the result in\r\n// each TestCase and TestInfo object.\r\n// If shard_tests == true, further filters tests based on sharding\r\n// variables in the environment - see\r\n// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.\r\n// Returns the number of tests that should run.\r\nint UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {\r\n  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?\r\n                             Int32FromEnvOrDie(kTestTotalShards, -1) : -1;\r\n  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?\r\n                            Int32FromEnvOrDie(kTestShardIndex, -1) : -1;\r\n\r\n  // num_runnable_tests are the number of tests that will\r\n  // run across all shards (i.e., match filter and are not disabled).\r\n  // num_selected_tests are the number of tests to be run on\r\n  // this shard.\r\n  int num_runnable_tests = 0;\r\n  int num_selected_tests = 0;\r\n\r\n  for (size_t i = 0; i < test_cases_.size(); i++) {\r\n    TestCase* const test_case = test_cases_[i];\r\n    const std::string& test_case_name = test_case->name();\r\n    test_case->set_should_run(false);\r\n\r\n    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {\r\n      TestInfo* const test_info = test_case->test_info_list()[j];\r\n      const std::string test_name(test_info->name());\r\n      // A test is disabled if test case name or test name matches\r\n      // kDisableTestFilter.\r\n      const bool is_disabled =\r\n        internal::UnitTestOptions::MatchesFilter(test_case_name,\r\n            kDisableTestFilter) ||\r\n        internal::UnitTestOptions::MatchesFilter(test_name,\r\n            kDisableTestFilter);\r\n      test_info->is_disabled_ = is_disabled;\r\n\r\n      const bool matches_filter =\r\n        internal::UnitTestOptions::FilterMatchesTest(test_case_name,\r\n            test_name);\r\n      test_info->matches_filter_ = matches_filter;\r\n\r\n      const bool is_runnable =\r\n        (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&\r\n        matches_filter;\r\n\r\n      const bool is_selected = is_runnable &&\r\n                               (shard_tests == IGNORE_SHARDING_PROTOCOL ||\r\n                                ShouldRunTestOnShard(total_shards, shard_index,\r\n                                    num_runnable_tests));\r\n\r\n      num_runnable_tests += is_runnable;\r\n      num_selected_tests += is_selected;\r\n\r\n      test_info->should_run_ = is_selected;\r\n      test_case->set_should_run(test_case->should_run() || is_selected);\r\n    }\r\n  }\r\n\r\n  return num_selected_tests;\r\n}\r\n\r\n// Prints the given C-string on a single line by replacing all '\\n'\r\n// characters with string \"\\\\n\".  If the output takes more than\r\n// max_length characters, only prints the first max_length characters\r\n// and \"...\".\r\nstatic void PrintOnOneLine(const char* str, int max_length) {\r\n  if (str != NULL) {\r\n    for (int i = 0; *str != '\\0'; ++str) {\r\n      if (i >= max_length) {\r\n        printf(\"...\");\r\n        break;\r\n      }\r\n\r\n      if (*str == '\\n') {\r\n        printf(\"\\\\n\");\r\n        i += 2;\r\n      }\r\n      else {\r\n        printf(\"%c\", *str);\r\n        ++i;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n// Prints the names of the tests matching the user-specified filter flag.\r\nvoid UnitTestImpl::ListTestsMatchingFilter() {\r\n  // Print at most this many characters for each type/value parameter.\r\n  const int kMaxParamLength = 250;\r\n\r\n  for (size_t i = 0; i < test_cases_.size(); i++) {\r\n    const TestCase* const test_case = test_cases_[i];\r\n    bool printed_test_case_name = false;\r\n\r\n    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {\r\n      const TestInfo* const test_info =\r\n        test_case->test_info_list()[j];\r\n\r\n      if (test_info->matches_filter_) {\r\n        if (!printed_test_case_name) {\r\n          printed_test_case_name = true;\r\n          printf(\"%s.\", test_case->name());\r\n\r\n          if (test_case->type_param() != NULL) {\r\n            printf(\"  # %s = \", kTypeParamLabel);\r\n            // We print the type parameter on a single line to make\r\n            // the output easy to parse by a program.\r\n            PrintOnOneLine(test_case->type_param(), kMaxParamLength);\r\n          }\r\n\r\n          printf(\"\\n\");\r\n        }\r\n\r\n        printf(\"  %s\", test_info->name());\r\n\r\n        if (test_info->value_param() != NULL) {\r\n          printf(\"  # %s = \", kValueParamLabel);\r\n          // We print the value parameter on a single line to make the\r\n          // output easy to parse by a program.\r\n          PrintOnOneLine(test_info->value_param(), kMaxParamLength);\r\n        }\r\n\r\n        printf(\"\\n\");\r\n      }\r\n    }\r\n  }\r\n\r\n  fflush(stdout);\r\n}\r\n\r\n// Sets the OS stack trace getter.\r\n//\r\n// Does nothing if the input and the current OS stack trace getter are\r\n// the same; otherwise, deletes the old getter and makes the input the\r\n// current getter.\r\nvoid UnitTestImpl::set_os_stack_trace_getter(\r\n  OsStackTraceGetterInterface* getter) {\r\n  if (os_stack_trace_getter_ != getter) {\r\n    delete os_stack_trace_getter_;\r\n    os_stack_trace_getter_ = getter;\r\n  }\r\n}\r\n\r\n// Returns the current OS stack trace getter if it is not NULL;\r\n// otherwise, creates an OsStackTraceGetter, makes it the current\r\n// getter, and returns it.\r\nOsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {\r\n  if (os_stack_trace_getter_ == NULL) {\r\n    os_stack_trace_getter_ = new OsStackTraceGetter;\r\n  }\r\n\r\n  return os_stack_trace_getter_;\r\n}\r\n\r\n// Returns the TestResult for the test that's currently running, or\r\n// the TestResult for the ad hoc test if no test is running.\r\nTestResult* UnitTestImpl::current_test_result() {\r\n  return current_test_info_ ?\r\n         &(current_test_info_->result_) : &ad_hoc_test_result_;\r\n}\r\n\r\n// Shuffles all test cases, and the tests within each test case,\r\n// making sure that death tests are still run first.\r\nvoid UnitTestImpl::ShuffleTests() {\r\n  // Shuffles the death test cases.\r\n  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);\r\n\r\n  // Shuffles the non-death test cases.\r\n  ShuffleRange(random(), last_death_test_case_ + 1,\r\n               static_cast<int>(test_cases_.size()), &test_case_indices_);\r\n\r\n  // Shuffles the tests inside each test case.\r\n  for (size_t i = 0; i < test_cases_.size(); i++) {\r\n    test_cases_[i]->ShuffleTests(random());\r\n  }\r\n}\r\n\r\n// Restores the test cases and tests to their order before the first shuffle.\r\nvoid UnitTestImpl::UnshuffleTests() {\r\n  for (size_t i = 0; i < test_cases_.size(); i++) {\r\n    // Unshuffles the tests in each test case.\r\n    test_cases_[i]->UnshuffleTests();\r\n    // Resets the index of each test case.\r\n    test_case_indices_[i] = static_cast<int>(i);\r\n  }\r\n}\r\n\r\n// Returns the current OS stack trace as an std::string.\r\n//\r\n// The maximum number of stack frames to be included is specified by\r\n// the gtest_stack_trace_depth flag.  The skip_count parameter\r\n// specifies the number of top frames to be skipped, which doesn't\r\n// count against the number of frames to be included.\r\n//\r\n// For example, if Foo() calls Bar(), which in turn calls\r\n// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in\r\n// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.\r\nstd::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,\r\n    int skip_count) {\r\n  // We pass skip_count + 1 to skip this wrapper function in addition\r\n  // to what the user really wants to skip.\r\n  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);\r\n}\r\n\r\n// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to\r\n// suppress unreachable code warnings.\r\nnamespace {\r\nclass ClassUniqueToAlwaysTrue {};\r\n}\r\n\r\nbool IsTrue(bool condition) {\r\n  return condition;\r\n}\r\n\r\nbool AlwaysTrue() {\r\n#if GTEST_HAS_EXCEPTIONS\r\n\r\n  // This condition is always false so AlwaysTrue() never actually throws,\r\n  // but it makes the compiler think that it may throw.\r\n  if (IsTrue(false)) {\r\n    throw ClassUniqueToAlwaysTrue();\r\n  }\r\n\r\n#endif  // GTEST_HAS_EXCEPTIONS\r\n  return true;\r\n}\r\n\r\n// If *pstr starts with the given prefix, modifies *pstr to be right\r\n// past the prefix and returns true; otherwise leaves *pstr unchanged\r\n// and returns false.  None of pstr, *pstr, and prefix can be NULL.\r\nbool SkipPrefix(const char* prefix, const char** pstr) {\r\n  const size_t prefix_len = strlen(prefix);\r\n\r\n  if (strncmp(*pstr, prefix, prefix_len) == 0) {\r\n    *pstr += prefix_len;\r\n    return true;\r\n  }\r\n\r\n  return false;\r\n}\r\n\r\n// Parses a string as a command line flag.  The string should have\r\n// the format \"--flag=value\".  When def_optional is true, the \"=value\"\r\n// part can be omitted.\r\n//\r\n// Returns the value of the flag, or NULL if the parsing failed.\r\nconst char* ParseFlagValue(const char* str,\r\n                           const char* flag,\r\n                           bool def_optional) {\r\n  // str and flag must not be NULL.\r\n  if (str == NULL || flag == NULL) {\r\n    return NULL;\r\n  }\r\n\r\n  // The flag must start with \"--\" followed by GTEST_FLAG_PREFIX_.\r\n  const std::string flag_str = std::string(\"--\") + GTEST_FLAG_PREFIX_ + flag;\r\n  const size_t flag_len = flag_str.length();\r\n\r\n  if (strncmp(str, flag_str.c_str(), flag_len) != 0) {\r\n    return NULL;\r\n  }\r\n\r\n  // Skips the flag name.\r\n  const char* flag_end = str + flag_len;\r\n\r\n  // When def_optional is true, it's OK to not have a \"=value\" part.\r\n  if (def_optional && (flag_end[0] == '\\0')) {\r\n    return flag_end;\r\n  }\r\n\r\n  // If def_optional is true and there are more characters after the\r\n  // flag name, or if def_optional is false, there must be a '=' after\r\n  // the flag name.\r\n  if (flag_end[0] != '=') {\r\n    return NULL;\r\n  }\r\n\r\n  // Returns the string after \"=\".\r\n  return flag_end + 1;\r\n}\r\n\r\n// Parses a string for a bool flag, in the form of either\r\n// \"--flag=value\" or \"--flag\".\r\n//\r\n// In the former case, the value is taken as true as long as it does\r\n// not start with '0', 'f', or 'F'.\r\n//\r\n// In the latter case, the value is taken as true.\r\n//\r\n// On success, stores the value of the flag in *value, and returns\r\n// true.  On failure, returns false without changing *value.\r\nbool ParseBoolFlag(const char* str, const char* flag, bool* value) {\r\n  // Gets the value of the flag as a string.\r\n  const char* const value_str = ParseFlagValue(str, flag, true);\r\n\r\n  // Aborts if the parsing failed.\r\n  if (value_str == NULL) {\r\n    return false;\r\n  }\r\n\r\n  // Converts the string value to a bool.\r\n  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');\r\n  return true;\r\n}\r\n\r\n// Parses a string for an Int32 flag, in the form of\r\n// \"--flag=value\".\r\n//\r\n// On success, stores the value of the flag in *value, and returns\r\n// true.  On failure, returns false without changing *value.\r\nbool ParseInt32Flag(const char* str, const char* flag, Int32* value) {\r\n  // Gets the value of the flag as a string.\r\n  const char* const value_str = ParseFlagValue(str, flag, false);\r\n\r\n  // Aborts if the parsing failed.\r\n  if (value_str == NULL) {\r\n    return false;\r\n  }\r\n\r\n  // Sets *value to the value of the flag.\r\n  return ParseInt32(Message() << \"The value of flag --\" << flag,\r\n                    value_str, value);\r\n}\r\n\r\n// Parses a string for a string flag, in the form of\r\n// \"--flag=value\".\r\n//\r\n// On success, stores the value of the flag in *value, and returns\r\n// true.  On failure, returns false without changing *value.\r\nbool ParseStringFlag(const char* str, const char* flag, std::string* value) {\r\n  // Gets the value of the flag as a string.\r\n  const char* const value_str = ParseFlagValue(str, flag, false);\r\n\r\n  // Aborts if the parsing failed.\r\n  if (value_str == NULL) {\r\n    return false;\r\n  }\r\n\r\n  // Sets *value to the value of the flag.\r\n  *value = value_str;\r\n  return true;\r\n}\r\n\r\n// Determines whether a string has a prefix that Google Test uses for its\r\n// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.\r\n// If Google Test detects that a command line flag has its prefix but is not\r\n// recognized, it will print its help message. Flags starting with\r\n// GTEST_INTERNAL_PREFIX_ followed by \"internal_\" are considered Google Test\r\n// internal flags and do not trigger the help message.\r\nstatic bool HasGoogleTestFlagPrefix(const char* str) {\r\n  return (SkipPrefix(\"--\", &str) ||\r\n          SkipPrefix(\"-\", &str) ||\r\n          SkipPrefix(\"/\", &str)) &&\r\n         !SkipPrefix(GTEST_FLAG_PREFIX_ \"internal_\", &str) &&\r\n         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||\r\n          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));\r\n}\r\n\r\n// Prints a string containing code-encoded text.  The following escape\r\n// sequences can be used in the string to control the text color:\r\n//\r\n//   @@    prints a single '@' character.\r\n//   @R    changes the color to red.\r\n//   @G    changes the color to green.\r\n//   @Y    changes the color to yellow.\r\n//   @D    changes to the default terminal text color.\r\n//\r\n// TODO(wan@google.com): Write tests for this once we add stdout\r\n// capturing to Google Test.\r\nstatic void PrintColorEncoded(const char* str) {\r\n  GTestColor color = COLOR_DEFAULT;  // The current color.\r\n\r\n  // Conceptually, we split the string into segments divided by escape\r\n  // sequences.  Then we print one segment at a time.  At the end of\r\n  // each iteration, the str pointer advances to the beginning of the\r\n  // next segment.\r\n  for (;;) {\r\n    const char* p = strchr(str, '@');\r\n\r\n    if (p == NULL) {\r\n      ColoredPrintf(color, \"%s\", str);\r\n      return;\r\n    }\r\n\r\n    ColoredPrintf(color, \"%s\", std::string(str, p).c_str());\r\n\r\n    const char ch = p[1];\r\n    str = p + 2;\r\n\r\n    if (ch == '@') {\r\n      ColoredPrintf(color, \"@\");\r\n    }\r\n    else if (ch == 'D') {\r\n      color = COLOR_DEFAULT;\r\n    }\r\n    else if (ch == 'R') {\r\n      color = COLOR_RED;\r\n    }\r\n    else if (ch == 'G') {\r\n      color = COLOR_GREEN;\r\n    }\r\n    else if (ch == 'Y') {\r\n      color = COLOR_YELLOW;\r\n    }\r\n    else {\r\n      --str;\r\n    }\r\n  }\r\n}\r\n\r\nstatic const char kColorEncodedHelpMessage[] =\r\n  \"This program contains tests written using \" GTEST_NAME_ \". You can use the\\n\"\r\n  \"following command line flags to control its behavior:\\n\"\r\n  \"\\n\"\r\n  \"Test Selection:\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"list_tests@D\\n\"\r\n  \"      List the names of all tests instead of running them. The name of\\n\"\r\n  \"      TEST(Foo, Bar) is \\\"Foo.Bar\\\".\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"filter=@YPOSTIVE_PATTERNS\"\r\n  \"[@G-@YNEGATIVE_PATTERNS]@D\\n\"\r\n  \"      Run only the tests whose name matches one of the positive patterns but\\n\"\r\n  \"      none of the negative patterns. '?' matches any single character; '*'\\n\"\r\n  \"      matches any substring; ':' separates two patterns.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"also_run_disabled_tests@D\\n\"\r\n  \"      Run all disabled tests too.\\n\"\r\n  \"\\n\"\r\n  \"Test Execution:\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"repeat=@Y[COUNT]@D\\n\"\r\n  \"      Run the tests repeatedly; use a negative count to repeat forever.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"shuffle@D\\n\"\r\n  \"      Randomize tests' orders on every iteration.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"random_seed=@Y[NUMBER]@D\\n\"\r\n  \"      Random number seed to use for shuffling test orders (between 1 and\\n\"\r\n  \"      99999, or 0 to use a seed based on the current time).\\n\"\r\n  \"\\n\"\r\n  \"Test Output:\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\\n\"\r\n  \"      Enable/disable colored output. The default is @Gauto@D.\\n\"\r\n  \"  -@G-\" GTEST_FLAG_PREFIX_ \"print_time=0@D\\n\"\r\n  \"      Don't print the elapsed time of each test.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"output=xml@Y[@G:@YDIRECTORY_PATH@G\"\r\n  GTEST_PATH_SEP_ \"@Y|@G:@YFILE_PATH]@D\\n\"\r\n  \"      Generate an XML report in the given directory or with the given file\\n\"\r\n  \"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\\n\"\r\n#if GTEST_CAN_STREAM_RESULTS_\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"stream_result_to=@YHOST@G:@YPORT@D\\n\"\r\n  \"      Stream test results to the given server.\\n\"\r\n#endif  // GTEST_CAN_STREAM_RESULTS_\r\n  \"\\n\"\r\n  \"Assertion Behavior:\\n\"\r\n#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\\n\"\r\n  \"      Set the default death test style.\\n\"\r\n#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"break_on_failure@D\\n\"\r\n  \"      Turn assertion failures into debugger break-points.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"throw_on_failure@D\\n\"\r\n  \"      Turn assertion failures into C++ exceptions.\\n\"\r\n  \"  @G--\" GTEST_FLAG_PREFIX_ \"catch_exceptions=0@D\\n\"\r\n  \"      Do not report exceptions as test failures. Instead, allow them\\n\"\r\n  \"      to crash the program or throw a pop-up (on Windows).\\n\"\r\n  \"\\n\"\r\n  \"Except for @G--\" GTEST_FLAG_PREFIX_ \"list_tests@D, you can alternatively set \"\r\n  \"the corresponding\\n\"\r\n  \"environment variable of a flag (all letters in upper-case). For example, to\\n\"\r\n  \"disable colored text output, you can either specify @G--\" GTEST_FLAG_PREFIX_\r\n  \"color=no@D or set\\n\"\r\n  \"the @G\" GTEST_FLAG_PREFIX_UPPER_ \"COLOR@D environment variable to @Gno@D.\\n\"\r\n  \"\\n\"\r\n  \"For more information, please read the \" GTEST_NAME_ \" documentation at\\n\"\r\n  \"@G\" GTEST_PROJECT_URL_ \"@D. If you find a bug in \" GTEST_NAME_ \"\\n\"\r\n  \"(not one in your own code or tests), please report it to\\n\"\r\n  \"@G<\" GTEST_DEV_EMAIL_ \">@D.\\n\";\r\n\r\n// Parses the command line for Google Test flags, without initializing\r\n// other parts of Google Test.  The type parameter CharType can be\r\n// instantiated to either char or wchar_t.\r\ntemplate <typename CharType>\r\nvoid ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {\r\n  for (int i = 1; i < *argc; i++) {\r\n    const std::string arg_string = StreamableToString(argv[i]);\r\n    const char* const arg = arg_string.c_str();\r\n\r\n    using internal::ParseBoolFlag;\r\n    using internal::ParseInt32Flag;\r\n    using internal::ParseStringFlag;\r\n\r\n    // Do we see a Google Test flag?\r\n    if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,\r\n                      &GTEST_FLAG(also_run_disabled_tests)) ||\r\n        ParseBoolFlag(arg, kBreakOnFailureFlag,\r\n                      &GTEST_FLAG(break_on_failure)) ||\r\n        ParseBoolFlag(arg, kCatchExceptionsFlag,\r\n                      &GTEST_FLAG(catch_exceptions)) ||\r\n        ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||\r\n        ParseStringFlag(arg, kDeathTestStyleFlag,\r\n                        &GTEST_FLAG(death_test_style)) ||\r\n        ParseBoolFlag(arg, kDeathTestUseFork,\r\n                      &GTEST_FLAG(death_test_use_fork)) ||\r\n        ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||\r\n        ParseStringFlag(arg, kInternalRunDeathTestFlag,\r\n                        &GTEST_FLAG(internal_run_death_test)) ||\r\n        ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||\r\n        ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||\r\n        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||\r\n        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||\r\n        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||\r\n        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||\r\n        ParseInt32Flag(arg, kStackTraceDepthFlag,\r\n                       &GTEST_FLAG(stack_trace_depth)) ||\r\n        ParseStringFlag(arg, kStreamResultToFlag,\r\n                        &GTEST_FLAG(stream_result_to)) ||\r\n        ParseBoolFlag(arg, kThrowOnFailureFlag,\r\n                      &GTEST_FLAG(throw_on_failure))\r\n       ) {\r\n      // Yes.  Shift the remainder of the argv list left by one.  Note\r\n      // that argv has (*argc + 1) elements, the last one always being\r\n      // NULL.  The following loop moves the trailing NULL element as\r\n      // well.\r\n      for (int j = i; j != *argc; j++) {\r\n        argv[j] = argv[j + 1];\r\n      }\r\n\r\n      // Decrements the argument count.\r\n      (*argc)--;\r\n\r\n      // We also need to decrement the iterator as we just removed\r\n      // an element.\r\n      i--;\r\n    }\r\n    else if (arg_string == \"--help\" || arg_string == \"-h\" ||\r\n             arg_string == \"-?\" || arg_string == \"/?\" ||\r\n             HasGoogleTestFlagPrefix(arg)) {\r\n      // Both help flag and unrecognized Google Test flags (excluding\r\n      // internal ones) trigger help display.\r\n      g_help_flag = true;\r\n    }\r\n  }\r\n\r\n  if (g_help_flag) {\r\n    // We print the help here instead of in RUN_ALL_TESTS(), as the\r\n    // latter may not be called at all if the user is using Google\r\n    // Test with another testing framework.\r\n    PrintColorEncoded(kColorEncodedHelpMessage);\r\n  }\r\n}\r\n\r\n// Parses the command line for Google Test flags, without initializing\r\n// other parts of Google Test.\r\nvoid ParseGoogleTestFlagsOnly(int* argc, char** argv) {\r\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\r\n}\r\nvoid ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {\r\n  ParseGoogleTestFlagsOnlyImpl(argc, argv);\r\n}\r\n\r\n// The internal implementation of InitGoogleTest().\r\n//\r\n// The type parameter CharType can be instantiated to either char or\r\n// wchar_t.\r\ntemplate <typename CharType>\r\nvoid InitGoogleTestImpl(int* argc, CharType** argv) {\r\n  g_init_gtest_count++;\r\n\r\n  // We don't want to run the initialization code twice.\r\n  if (g_init_gtest_count != 1) {\r\n    return;\r\n  }\r\n\r\n  if (*argc <= 0) {\r\n    return;\r\n  }\r\n\r\n  internal::g_executable_path = internal::StreamableToString(argv[0]);\r\n\r\n#if GTEST_HAS_DEATH_TEST\r\n\r\n  g_argvs.clear();\r\n\r\n  for (int i = 0; i != *argc; i++) {\r\n    g_argvs.push_back(StreamableToString(argv[i]));\r\n  }\r\n\r\n#endif  // GTEST_HAS_DEATH_TEST\r\n\r\n  ParseGoogleTestFlagsOnly(argc, argv);\r\n  GetUnitTestImpl()->PostFlagParsingInit();\r\n}\r\n\r\n}  // namespace internal\r\n\r\n// Initializes Google Test.  This must be called before calling\r\n// RUN_ALL_TESTS().  In particular, it parses a command line for the\r\n// flags that Google Test recognizes.  Whenever a Google Test flag is\r\n// seen, it is removed from argv, and *argc is decremented.\r\n//\r\n// No value is returned.  Instead, the Google Test flag variables are\r\n// updated.\r\n//\r\n// Calling the function for the second time has no user-visible effect.\r\nvoid InitGoogleTest(int* argc, char** argv) {\r\n  internal::InitGoogleTestImpl(argc, argv);\r\n}\r\n\r\n// This overloaded version can be used in Windows programs compiled in\r\n// UNICODE mode.\r\nvoid InitGoogleTest(int* argc, wchar_t** argv) {\r\n  internal::InitGoogleTestImpl(argc, argv);\r\n}\r\n\r\n}  // namespace testing\r\n"
  },
  {
    "path": "rocrtst/gtest/src/gtest_main.cpp",
    "content": "// Copyright 2006, Google Inc.\r\n// All rights reserved.\r\n//\r\n// Redistribution and use in source and binary forms, with or without\r\n// modification, are permitted provided that the following conditions are\r\n// met:\r\n//\r\n//     * Redistributions of source code must retain the above copyright\r\n// notice, this list of conditions and the following disclaimer.\r\n//     * Redistributions in binary form must reproduce the above\r\n// copyright notice, this list of conditions and the following disclaimer\r\n// in the documentation and/or other materials provided with the\r\n// distribution.\r\n//     * Neither the name of Google Inc. nor the names of its\r\n// contributors may be used to endorse or promote products derived from\r\n// this software without specific prior written permission.\r\n//\r\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n\r\n#include <stdio.h>\r\n\r\nint hsa_arg_cnt;\r\nchar* hsa_arg_list[32];\r\n\r\n#include \"gtest/gtest.h\"\r\n\r\nGTEST_API_ int main(int argc, char** argv) {\r\n\r\n  printf(\"Running main() from gtest_main.cc\\n\");\r\n  testing::InitGoogleTest(&argc, argv);\r\n\r\n  // Copy cmdline args for Hsa into a globally visible symbol\r\n  hsa_arg_cnt = argc;\r\n\r\n  for (int jdx = 0; jdx < argc; jdx++) {\r\n    hsa_arg_list[jdx] = argv[jdx];\r\n  }\r\n\r\n  return RUN_ALL_TESTS();\r\n}\r\n"
  },
  {
    "path": "rocrtst/samples/CMakeLists.txt",
    "content": "#\n# Minimum version of cmake required\n#\ncmake_minimum_required(VERSION 2.8.0)\n\n#\n# GCC 4.8 or higher compiler required.\n#\n\n#\n#   Required Defines on cmake command line\n#\n#   1) Set location of ROCR header files\n#\n#      ROCM_DIR=\"Root for RocM install\"\n#\n#   2) Set ROCRTST_BLD_TYPE to either \"Debug\" or \"Release\".\n#      If not set, the default value is \"Debug\" is bound.\n#\n#      ROCRTST_BLD_TYPE=Debug or ROCRTST_BLD_TYPE=Release\n#\n#   3) Set ROCRTST_BLD_BITS to either \"32\" or \"64\"\n#      If not set, the default value of \"64\" is bound.\n#\n#       ROCRTST_BLD_BITS=32 or ROCRTST_BLD_BITS=64\n#\n#   4) Set TARGET_DEVICES to indicate gpu types for kernel\n#      builds (e.g., \"gfx803;gfx900; ...\")\n#\n#   Building rocrtst Suite\n#\n#   1) Create build folder e.g. \"rocrtst/build\" - any name will do\n#   2) Cd into build folder\n#   3) Run \"cmake ..\"\n#   4) Run \"make\"\n#\n\ncmake_minimum_required(VERSION 3.5.0)\n\n# Set Name for Samples Project\n#\n\nset(PROJECT_NAME \"sample64\")\nproject (${PROJECT_NAME})\n\nset(DEFAULT_TARGET \"gfx803\")\n\n#############################\n# COMMON AREA\n#############################\n#\n# Currently support for Windows platform is not present\n#\nif(WIN32)\n  message(\"This sample is not supported on Windows platform\")\n  return()\nendif()\n\n#\n# Process input variables\n#\n\n# Required Defines first:\nfind_package(hsa-runtime64 REQUIRED )\nmessage(STATUS \"HSA Runtime found at ${hsa-runtime64_DIR} \")\n\nif (DEFINED LLVM_DIR)\n  set(CLANG ${LLVM_DIR}/clang)\n  if (NOT EXISTS ${CLANG})\n    # SPK temp until Jenkins script input is corrected.\n    set (CLANG ${OPENCL_DIR}/bin/clang)\n    if (NOT EXISTS ${CLANG})\n    message(\"ERROR: path to clang (${CLANG}) is not valid. Is define LLVM_DIR correct?\")\n    return()\n    endif()\n  endif()\nelse()\n    message(\"WARNING: LLVM_DIR define is not set. Kernels will not be built.\")\nendif()\n\nif (DEFINED OPENCL_DIR)\n  set(OPENCL_INC_DIR ${OPENCL_DIR}/include)\n  set(OPENCL_LIB_DIR ${OPENCL_DIR}/lib)\nelse()\n    message(\"WARNING: OPENCL_DIR define is not set. Kernels will not be built.\")\nendif()\n\nif (DEFINED OPENCL_VER)\n  set(OPENCL_VER ${OPENCL_VER})\nelse()\n  message(\"OPENCL_VER define is not set. Using default\")\n  set(OPENCL_VER \"2.0\")\nendif()\n\nif(NOT EXISTS \"${OPENCL_INC_DIR}/opencl-c.h\")\n  set(OPENCL_INC_DIR \"${OPENCL_DIR}/../../../external/llvm-project/clang/lib/Headers/\")\n  if(NOT EXISTS \"${OPENCL_INC_DIR}/opencl-c.h\")\n    message(WARNING \"opencl-c.h not found.\")\n  endif()\nendif()\n\nif (NOT DEFINED TARGET_DEVICES)\n  message(\"WARNING: No targets devices provided on command line\")\n  message(\"  e.g., cmake -DTARGET_DEVICES=\\\"gfx803;gfx900;gfx...\\\" ..\")\n  message(\"  Using default target of $DEFAULT_TARGET\")\n  list(APPEND TARGET_DEVICES \"gfx803\")\nendif()\n\nstring(TOLOWER \"${ROCRTST_BLD_TYPE}\" tmp)\nif(\"${tmp}\" STREQUAL release)\n  set(BUILD_TYPE \"Release\")\n  set(ISDEBUG 0)\nelse()\n  set(BUILD_TYPE \"Debug\")\n  set(ISDEBUG 1)\nendif()\n\nif(${EMULATOR_BUILD})\nadd_definitions(-DROCRTST_EMULATOR_BUILD=1)\nendif()\n\nfind_path(BITCODE_DIR NAMES \"opencl.bc\" \"opencl.amdgcn.bc\"\n  PATHS\n    \"${ROCM_DIR}/amdgcn/bitcode\"\n    \"${ROCM_DIR}/lib/bitcode\"\n    \"${ROCM_DIR}/lib\"\n    \"${ROCM_DIR}/lib/x86_64/bitcode\"\n    \"${OPENCL_DIR}/amdgcn/bitcode\"\n    \"${OPENCL_DIR}/lib/x86_64/bitcode\"\n    \"${LLVM_DIR}/../lib/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/amdgcn/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/lib/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/lib/x86_64/bitcode\")\n\n\n#\n# Print out the build configuration being used:\n#\n#   Build Src directory\n#   Build Binary directory\n#   Build Type: Debug Vs Release, 32 Vs 64\n#   Compiler Version, etc\n#\nmessage(\"\")\nmessage(\"Build Configuration:\")\nmessage(\"-------------IS64BIT: \" ${IS64BIT})\nmessage(\"-----------BuildType: \" ${BUILD_TYPE})\nmessage(\"------------Compiler: \" ${CMAKE_CXX_COMPILER})\nmessage(\"-------------Version: \" ${CMAKE_CXX_COMPILER_VERSION})\nmessage(\"--------Proj Src Dir: \" ${PROJECT_SOURCE_DIR})\nmessage(\"--------Proj Bld Dir: \" ${PROJECT_BINARY_DIR})\nmessage(\"--------Proj Lib Dir: \" ${PROJECT_BINARY_DIR}/lib)\nmessage(\"--------Proj Exe Dir: \" ${PROJECT_BINARY_DIR}/bin)\nmessage(\"------Target Devices: ${TARGET_DEVICES}\")\nmessage(\"----------Clang path: \" ${CLANG})\nmessage(\"----------OpenCL Dir: \" ${OPENCL_DIR})\nmessage(\"-------OpenCL version \" ${OPENCL_VER})\nmessage(\"\")\n\n#\n# Set the build type based on user input\n#\nset(CMAKE_BUILD_TYPE ${BUILD_TYPE})\n#\n# Flag to enable / disable verbose output.\n#\nSET( CMAKE_VERBOSE_MAKEFILE on )\n#\n# Compiler pre-processor definitions.\n#\n# Define MACRO \"DEBUG\" if build type is \"Debug\"\nif(${BUILD_TYPE} STREQUAL \"Debug\")\nadd_definitions(-DDEBUG)\nendif()\n\n#add_definitions(-D__linux__)\nadd_definitions(-DLITTLEENDIAN_CPU=1)\n\n#\n# Linux Compiler options\n#\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++11\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fexceptions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-rtti\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-math-errno\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-threadsafe-statics\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fmerge-all-constants\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fms-extensions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-missing-braces\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-unused\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Werror\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m64\")\n\n#\n# Add compiler flags to include symbol information for debug builds\n#\nif(ISDEBUG)\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb -O0\")\nendif()\nmessage(\"ISDEBUG STEP:Done\")\n\ninclude_directories(\"${OPENCL_DIR}/include\")\n\n# Use this function to build any samples that have kernels to be built\nfunction(process_sample S_NAME TARG_DEV HAS_KERNEL)\n  set(KERNEL_DIR ${PROJECT_BINARY_DIR}/${TARG_DEV})\n  set(SNAME_KERNEL \"${S_NAME}_kernels.hsaco\")\n\n  set(TARG_NAME \"${S_NAME}_hsaco.${TARG_DEV}\")\n  set (HSACO_TARG_LIST ${HSACO_TARG_LIST} ${TARG_NAME}\n                                               CACHE INTERNAL HSACO_TARG_LIST)\n\n  if (${HAS_KERNEL})\n    # Build the kernel\n    separate_arguments(CLANG_ARG_LIST UNIX_COMMAND\n     \"-x cl -target amdgcn-amd-amdhsa -Xclang -finclude-default-header -mcpu=${TARG_DEV} ${BITCODE_ARGS} -cl-std=CL${OPENCL_VER} ${CL_FILE_LIST} -o ${KERNEL_DIR}/${SNAME_KERNEL}\")\n    add_custom_target(\"${TARG_NAME}\" ${CLANG} ${CLANG_ARG_LIST} COMMAND\n      ${CMAKE_COMMAND} -E create_symlink\n        \"../${SNAME_EXE}\" \"${KERNEL_DIR}/${SNAME_EXE}\"\n       COMMENT \"BUILDING KERNEL...\"\n      VERBATIM)\n   else()\n    # No kernel to build, but we need to set up symlinks; we'll use the hsaco\n    # targ name, even though we aren't building an hsaco\n    add_custom_target(\"${TARG_NAME}\"\n       ${CMAKE_COMMAND} -E create_symlink\n             \"../${SNAME_EXE}\" \"${KERNEL_DIR}/${SNAME_EXE}\"\n       COMMENT \"NO KERNEL TO BUILD; SYMLINK ONLY...\"\n      VERBATIM)\n   endif()\nendfunction(process_sample)\n\nfunction(build_sample_for_devices S_NAME HAS_KERNEL)\n  set(SNAME_EXE \"${S_NAME}\")\n\n  aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/${S_NAME} S_NAME_SOURCES)\n  add_executable(${SNAME_EXE} ${S_NAME_SOURCES})\n  target_link_libraries(${SNAME_EXE} hsa-runtime64::hsa-runtime64 c stdc++ dl pthread rt)\n  set(HSACO_TARG_LIST PARENT_SCOPE)\n\n  foreach(t ${TARGET_DEVICES})\n    process_sample(${S_NAME} ${t} ${HAS_KERNEL})\n  endforeach(t)\nendfunction(build_sample_for_devices)\n\nfunction(add_symlink_to_exe DST)\n  foreach(td ${TARGET_DEVICES})\n  endforeach(td)\nendfunction(add_symlink_to_exe)\n\n\n# Make directories for each possible target device\nforeach(td ${TARGET_DEVICES})\n  file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${td})\nendforeach(td)\n\n###########################\n# SAMPLE SPECIFIC SECTION\n###########################\n\nset (HSACO_TARG_LIST \"\" CACHE INTERNAL HSACO_TARG_LIST)\n\nset(KERN_SUFFIX \"kernels.hsaco\")\n\n# Check if device-libs bitcode is following old or new layout\nif(EXISTS \"${BITCODE_DIR}/opencl.amdgcn.bc\")\n  set(BITCODE_ARGS \"-nogpulib\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/opencl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ockl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ocml.amdgcn.bc\")\nelse()\n  set(BITCODE_ARGS \"--hip-device-lib-path=${BITCODE_DIR}\")\nendif()\n\nset(CL_FILE_LIST\n               \"${PROJECT_SOURCE_DIR}/binary_search/binary_search_kernels.cl\")\nbuild_sample_for_devices(\"binary_search\" TRUE)\n\n# RocR Info\nbuild_sample_for_devices(\"rocrinfo\" FALSE)\n\n# IPC\nbuild_sample_for_devices(\"ipc\" FALSE)\n\n# Async Mem. Copy\nbuild_sample_for_devices(\"async_mem_copy\" FALSE)\n\nadd_custom_target(sample_kernels DEPENDS ${HSACO_TARG_LIST})\ninstall(TARGETS ${SAMPLE_EXE}\n        ARCHIVE DESTINATION ${PROJECT_BINARY_DIR}/lib\n        LIBRARY DESTINATION ${PROJECT_BINARY_DIR}/lib\n        RUNTIME DESTINATION ${PROJECT_BINARY_DIR}/bin)\n"
  },
  {
    "path": "rocrtst/samples/README.txt",
    "content": "\n\nTo build the sample, first export the following environment variables:\n\nexport ROCR_DIR=<root of RocR install; for RocR includes and libraries>\nexport OPENCL_DIR=<root of OpenCL install; for required clang and bitcode libs>\nexport OPENCL_VER=<OpenCL version; e.g., \"2.0\">\nexport TARGET_DEVICE=<GPU type; e.g., \"gfx803\" or \"gfx900\">\n\nNext, do the following:\nmkdir build\ncd build\ncmake ..\n\nFinally, do the following to build the application and respective kernels:\n\nmake\nmake sample_kernels\n\n"
  },
  {
    "path": "rocrtst/samples/async_mem_copy/async_mem_copy.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#include <cassert>\n#include <iostream>\n\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nstatic const uint32_t kTestFillValue1 = 0xabcdef12;\nstatic const uint32_t kTestFillValue2 = 0xba5eba11;\nstatic const uint32_t kTestFillValue3 = 0xfeed5a1e;\nstatic const uint32_t kTestInitValue = 0xbaadf00d;\n\n// This structure holds an agent pointer and associated memory pool to be used\n// for this test program.\nstruct async_mem_cpy_agent {\n    hsa_agent_t dev;\n    hsa_amd_memory_pool_t pool;\n    size_t granule;\n    void *ptr;\n};\n\nstruct async_mem_cpy_pool_query {\n  async_mem_cpy_agent* pool_info;\n  hsa_agent_t peer_device;\n};\n\nstruct callback_args {\n    struct async_mem_cpy_agent cpu;\n    struct async_mem_cpy_agent gpu1;\n    struct async_mem_cpy_agent gpu2;\n};\n\n// Find the least common multiple of 2 numbers\nstatic uint32_t lcm(uint32_t a, uint32_t  b) {\n    int tmp_a;\n    int tmp_b;\n\n    tmp_a = a;\n    tmp_b = b;\n\n    while (tmp_a != tmp_b) {\n      if (tmp_a < tmp_b) {\n        tmp_a = tmp_a + a;\n      } else {\n        tmp_b = tmp_b + b;\n      }\n    }\n\n    return tmp_a;\n}\n\n// This function is a callback for hsa_amd_agent_iterate_memory_pools()\n// and will test whether the provided memory pool is 1) in the GLOBAL\n// segment, 2) allows allocation and 3) is accessible by the provided\n// agent. The \"data\" input parameter is assumed to be pointing to a\n// struct async_mem_cpy_agent. If the provided pool meets these criteria,\n// HSA_STATUS_INFO_BREAK is returned.\nstatic hsa_status_t\nFindPool(hsa_amd_memory_pool_t in_pool, void* data) {\n  hsa_amd_segment_t segment;\n  hsa_status_t err;\n\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  struct async_mem_cpy_pool_query *args = (struct async_mem_cpy_pool_query *)data;\n\n  err = hsa_amd_memory_pool_get_info(in_pool,\n                                  HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n  RET_IF_HSA_ERR(err);\n  if (segment != HSA_AMD_SEGMENT_GLOBAL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  bool canAlloc;\n  err = hsa_amd_memory_pool_get_info(in_pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &canAlloc);\n  RET_IF_HSA_ERR(err);\n  if (!canAlloc) {\n     return HSA_STATUS_SUCCESS;\n  }\n\n  if(args->peer_device.handle != 0) {\n    hsa_amd_memory_pool_access_t access =\n      HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n    err = hsa_amd_agent_memory_pool_get_info(args->peer_device, in_pool,\n      HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\n    RET_IF_HSA_ERR(err);\n\n    if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n\n  err = hsa_amd_memory_pool_get_info(in_pool,\n    HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE, &args->pool_info->granule);\n  RET_IF_HSA_ERR(err);\n\n  args->pool_info->pool = in_pool;\n\n  return HSA_STATUS_INFO_BREAK;\n}\n\n// This function is meant to be a callback to hsa_iterate_agents. For each\n// input agent the iterator provides as input, this function will check to\n// see if the input agent is a CPU agent. If so, it will update the\n// async_mem_cpy_agent structure pointed to by the input parameter \"data\".\n\n// Return values:\n//  HSA_STATUS_INFO_BREAK -- CPU agent has been found and stored. Iterator\n//    should stop iterating\n//  HSA_STATUS_SUCCESS -- CPU agent has not yet been found; iterator\n//    should keep iterating\n//  Other -- Some error occurred\nstatic hsa_status_t FindCPUDevice(hsa_agent_t agent, void *data) {\n  if (data == NULL) {\n     return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE,\n                                                            &hsa_device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_CPU) {\n    struct async_mem_cpy_agent *args = (struct async_mem_cpy_agent *)data;\n\n    args->dev = agent;\n\n    async_mem_cpy_pool_query pool_query;\n    pool_query.peer_device.handle = 0;\n    pool_query.pool_info = args;\n\n    err = hsa_amd_agent_iterate_memory_pools(agent, FindPool, &pool_query);\n\n    if (err == HSA_STATUS_INFO_BREAK) {  // we found what we were looking for\n      return HSA_STATUS_INFO_BREAK;\n    } else {\n      args->dev = {0};\n      return err;\n    }\n  }\n\n  // Returning HSA_STATUS_SUCCESS tells the calling iterator to keep iterating\n  return HSA_STATUS_SUCCESS;\n}\n\n// This function is meant to be a callback to hsa_iterate_agents. It will\n// attempt to find 2, or at least 1 GPU agent suitable for our test. The data\n// input parameter should point to a callback_args struct. The 2 GPU fields\n// will be updated as GPUs are discovered.\n// Return values:\n//  HSA_STATUS_INFO_BREAK -- 2 GPU agents have been found and stored. Iterator\n//    should stop iterating\n//  HSA_STATUS_SUCCESS -- 2 GPU agents have not yet been found; 0 or 1 may\n//    have been found; iterator function should keep iterating\n//  Other -- Some error occurred\nstatic hsa_status_t FindGPUs(hsa_agent_t agent, void *data) {\n  if (data == NULL) {\n     return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t err = hsa_agent_get_info(agent,\n                                     HSA_AGENT_INFO_DEVICE, &hsa_device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_device_type != HSA_DEVICE_TYPE_GPU) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  struct callback_args *args = (struct callback_args *)data;\n  struct async_mem_cpy_agent *gpu;\n\n  async_mem_cpy_pool_query pool_query = {0,0};\n\n  if (args->gpu1.dev.handle == 0) {\n    gpu = &args->gpu1;\n  } else {\n    gpu = &args->gpu2;\n    // Check that gpu1 has peer access into the selected pool.\n    pool_query.peer_device = args->gpu1.dev;\n  }\n\n  // Make sure GPU device has pool host can access\n  gpu->dev = agent;\n  pool_query.pool_info = gpu;\n\n  err = hsa_amd_agent_iterate_memory_pools(agent, FindPool, &pool_query);\n\n  if (err == HSA_STATUS_INFO_BREAK) {\n    if (gpu == &args->gpu2) {\n      // We found 2 gpu's\n      return HSA_STATUS_INFO_BREAK;\n    } else {\n      // Keep looking for another gpu\n      return HSA_STATUS_SUCCESS;\n    }\n  } else {\n    gpu->dev = {0};\n  }\n\n  RET_IF_HSA_ERR(err);\n\n  // Returning HSA_STATUS_SUCCESS tells the calling iterator to keep iterating\n  return HSA_STATUS_SUCCESS;\n}\n\n// This is the main test, showing various paths of async. copy. Source and\n// destination agents and their respective pools should already be discovered.\n// Additionally, buffer from the pools should already be allocated and availble\n// from the input parameters.\nstatic hsa_status_t\nAsyncCpyTest(async_mem_cpy_agent *dst, async_mem_cpy_agent *src,\n                               callback_args *args, size_t sz, uint32_t val) {\n  hsa_status_t err;\n  hsa_signal_t copy_signal;\n\n  // Initialize the system and destination buffers with a value so we can later validate it has\n  // been overwritten\n  void *sysPtr = args->cpu.ptr;\n\n  err = hsa_amd_memory_fill(sysPtr, kTestInitValue, sz/sizeof(uint32_t));\n  RET_IF_HSA_ERR(err);\n\n  if(dst->ptr != sysPtr) {\n    err = hsa_amd_memory_fill(dst->ptr, kTestInitValue, sz/sizeof(uint32_t));\n    RET_IF_HSA_ERR(err);\n  }\n\n  // Fill the source buffer with the provided uint32_t value\n  err = hsa_amd_memory_fill(src->ptr, val, sz/sizeof(uint32_t));\n  RET_IF_HSA_ERR(err);\n\n  // Make sure the target and destination agents have access to the buffer.\n  hsa_agent_t ag_list[2] = {dst->dev, src->dev};\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, dst->ptr);\n  RET_IF_HSA_ERR(err);\n\n  // Create a signal that will be used to inform us when the copy is done\n  err = hsa_signal_create(1, 0, NULL, &copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  // Do the copy...\n  err = hsa_amd_memory_async_copy(dst->ptr, dst->dev, src->ptr, src->dev,\n                                                    sz, 0, NULL, copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  // Here we do a blocking wait. Alternatively, we could also use a\n  // non-blocking wait in a loop, and do other work while waiting.\n  if (hsa_signal_wait_relaxed(copy_signal, HSA_SIGNAL_CONDITION_LT,\n                                       1, -1, HSA_WAIT_STATE_BLOCKED) != 0) {\n    printf(\"Async copy returned error value.\\n\");\n    return HSA_STATUS_ERROR;\n  }\n\n  // Verify the copy was successful; copy from the dst buffer to the sysBuf,\n  // (if the result is not already in sys. mem.) and check the sysBuf values\n  if (dst->ptr != sysPtr) {\n    if (src->ptr != sysPtr) {\n      // In this case, we need to give the gpu dev that owns dst->ptr access\n      // to the system memory we are going to copy to.\n      hsa_agent_t ag_list_ck[2] = {dst->dev, args->cpu.dev};\n      err = hsa_amd_agents_allow_access(2, ag_list_ck, NULL, sysPtr);\n      RET_IF_HSA_ERR(err);\n    }\n\n    // Reset signal to 1\n    hsa_signal_store_screlease(copy_signal, 1);\n    err = hsa_amd_memory_async_copy(sysPtr, args->cpu.dev, dst->ptr, dst->dev,\n                                                    sz, 0, NULL, copy_signal);\n    RET_IF_HSA_ERR(err);\n\n    if (hsa_signal_wait_relaxed(copy_signal, HSA_SIGNAL_CONDITION_LT,\n                                       1, -1, HSA_WAIT_STATE_BLOCKED) != 0) {\n      printf(\"Async copy returned error value.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n  }\n\n  // Check that the contents of the buffer are what is expected.\n  for (uint32_t i = 0; i < sz/sizeof(uint32_t); ++i) {\n    if (reinterpret_cast<uint32_t *>(sysPtr)[i] != val) {\n      fprintf(stdout, \"Expected 0x%x but got 0x%x in buffer at index %d.\\n\",\n                             val, reinterpret_cast<uint32_t *>(sysPtr)[i], i);\n      return HSA_STATUS_ERROR;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// This program illustrates the usage of the asynchronous copy capability of\n// the RocR runtime library. The program will create a system memory buffer and\n// a local buffer for each GPU, up to 2 GPUs, if the system has at least 2\n// GPUs. The program will copy data to/from the host from/to the GPU. If 2\n// GPUs are available, the program will also copy data from one to the other.\nint main() {\n  hsa_status_t err;\n  struct callback_args args;\n  bool twoGPUs = false;\n\n  err = hsa_init();\n  RET_IF_HSA_ERR(err);\n\n  // First, find the cpu agent and associated pool\n  args.cpu = {0, 0, 0};\n  err = hsa_iterate_agents(FindCPUDevice, reinterpret_cast<void *>(&args.cpu));\n  assert(err == HSA_STATUS_INFO_BREAK);\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return -1;\n  }\n\n  // Now, find 1 or 2 (if possible) GPUs and associated pool(s) for our test\n  args.gpu1 = {0, 0, 0};\n  args.gpu2 = {0, 0, 0};\n  err = hsa_iterate_agents(FindGPUs, &args);\n\n  if (err == HSA_STATUS_INFO_BREAK) {\n    twoGPUs = true;\n  } else {\n    // See if we at least have 1 GPU\n    if (args.gpu1.dev.handle == 0) {\n      fprintf(stdout,\n       \"GPU with accessible VRAM not found; at least 1 required. Exiting\\n\");\n      return -1;\n    }\n    fprintf(stdout, \"Only 1 GPU found with required VRAM. \"\n                                      \"Peer-to-Peer copy will be skipped.\\n\");\n  }\n\n  // We will use the smallest amount of allocatable memory that works for all\n  // potential sources and destinations of the copy\n  size_t sz = lcm(args.cpu.granule, args.gpu1.granule);\n\n  // Allocate memory on each source/destination\n  if (twoGPUs) {\n    sz = lcm(sz, args.gpu2.granule);\n\n    err = hsa_amd_memory_pool_allocate(args.gpu2.pool, sz, 0,\n                                    reinterpret_cast<void**>(&args.gpu2.ptr));\n    RET_IF_HSA_ERR(err);\n  }\n\n  err = hsa_amd_memory_pool_allocate(args.cpu.pool, sz, 0,\n                                     reinterpret_cast<void**>(&args.cpu.ptr));\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_allocate(args.gpu1.pool, sz, 0,\n                                    reinterpret_cast<void**>(&args.gpu1.ptr));\n  RET_IF_HSA_ERR(err);\n\n  char name[64];\n  err = hsa_agent_get_info(args.cpu.dev, HSA_AGENT_INFO_NAME, &name);\n  fprintf(stdout, \"CPU is \\\"%s\\\"\\n\", name);\n\n  err = hsa_agent_get_info(args.gpu1.dev, HSA_AGENT_INFO_NAME, &name);\n  fprintf(stdout, \"GPU1 is \\\"%s\\\"\\n\", name);\n\n  if (twoGPUs) {\n    err = hsa_agent_get_info(args.gpu2.dev, HSA_AGENT_INFO_NAME, &name);\n    fprintf(stdout, \"GPU2 is \\\"%s\\\"\\n\", name);\n  }\n\n  fprintf(stdout,\n              \"Copying %lu bytes from gpu1 memory to system memory...\\n\", sz);\n  err = AsyncCpyTest(&args.cpu, &args.gpu1, &args, sz, kTestFillValue1);\n  RET_IF_HSA_ERR(err);\n  fprintf(stdout, \"Success!\\n\");\n\n  fprintf(stdout,\n              \"Copying %lu bytes from system memory to gpu1 memory...\\n\", sz);\n  err = AsyncCpyTest(&args.gpu1, &args.cpu, &args, sz, kTestFillValue2);\n  RET_IF_HSA_ERR(err);\n  fprintf(stdout, \"Success!\\n\");\n\n  if (twoGPUs) {\n    fprintf(stdout,\n                \"Copying %lu bytes from gpu1 memory to gpu2 memory...\\n\", sz);\n    err = AsyncCpyTest(&args.gpu2, &args.gpu1, &args, sz, kTestFillValue3);\n    RET_IF_HSA_ERR(err);\n    fprintf(stdout, \"Success!\\n\");\n  }\n\n  // Clean up\n  err = hsa_amd_memory_pool_free(args.cpu.ptr);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_free(args.gpu1.ptr);\n  RET_IF_HSA_ERR(err);\n\n  if (twoGPUs) {\n    err = hsa_amd_memory_pool_free(args.gpu2.ptr);\n    RET_IF_HSA_ERR(err);\n  }\n}\n"
  },
  {
    "path": "rocrtst/samples/binary_search/binary_search.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <assert.h>\n#include <stdint.h>\n#include <string.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <string>\n#include <iostream>\n#include <climits>\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n              __FILE__ << \". Call returned \" << err << std::endl; \\\n    return (err); \\\n  } \\\n}\n\n#ifndef ROCRTST_EMULATOR_BUILD\nstatic const uint32_t kBinarySearchLength = 512;\nstatic const uint32_t kBinarySearchFindMe = 108;\nstatic const uint32_t kWorkGroupSize = 256;\n#else\nstatic const uint32_t kBinarySearchLength = 16;\nstatic const uint32_t kBinarySearchFindMe = 6;\nstatic const uint32_t kWorkGroupSize = 8;\n#endif\n\n// Hold all the info specific to binary search\ntypedef struct BinarySearch {\n  // Binary Search parameters\n  uint32_t length;\n  uint32_t work_group_size;\n  uint32_t work_grid_size;\n  uint32_t num_sub_divisions;\n  uint32_t find_me;\n\n  // Buffers needed for this application\n  uint32_t* input;\n  uint32_t* input_arr;\n  uint32_t* input_arr_local;\n  uint32_t* output;\n  // Keneral argument buffers and addresses\n  void* kern_arg_buffer;  // Begin of allocated memory\n  //  this pointer to be deallocated\n  void* kern_arg_address;  // Properly aligned address to be used in aql\n  // packet (don't use for deallocation)\n\n  // Kernel code\n  std::string kernel_file_name;\n  std::string kernel_name;\n  uint32_t kernarg_size;\n  uint32_t kernarg_align;\n\n  // HSA/RocR objects needed for this application\n  hsa_agent_t gpu_dev;\n  hsa_agent_t cpu_dev;\n  hsa_signal_t signal;\n  hsa_queue_t* queue;\n  hsa_amd_memory_pool_t cpu_pool;\n  hsa_amd_memory_pool_t gpu_pool;\n  hsa_amd_memory_pool_t kern_arg_pool;\n\n  // Other items we need to populate AQL packet\n  uint64_t kernel_object;\n  uint32_t group_segment_size;   ///< Kernel group seg size\n  uint32_t private_segment_size;   ///< Kernel private seg size\n} BinarySearch;\n\nvoid InitializeBinarySearch(BinarySearch* bs) {\n  bs->kernel_file_name = \"./binary_search_kernels.hsaco\";\n  bs->kernel_name = \"binarySearch.kd\";\n  bs->length = kBinarySearchLength;\n  bs->find_me = kBinarySearchFindMe;\n  bs->work_group_size = kWorkGroupSize;\n  bs->num_sub_divisions = bs->length / bs->work_group_size;\n}\n\n// This function is called by the call-back functions used to find an agent of\n// the specified hsa_device_type_t. Note that it cannot be called directly from\n// hsa_iterate_agents() as it does not match the prototype of the call-back\n// function. It must be wrapped by a function with the correct prototype.\n//\n// Return values:\n//  HSA_STATUS_INFO_BREAK -- \"agent\" is of the specified type (dev_type)\n//  HSA_STATUS_SUCCESS -- \"agent\" is not of the specified type\n//  Other -- Some error occurred\nstatic hsa_status_t FindAgent(hsa_agent_t agent, void* data,\n                              hsa_device_type_t dev_type) {\n  if (data == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // See if the provided agent matches the input type (dev_type)\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE,\n                                &hsa_device_type);\n  RET_IF_HSA_ERR(hsa_error_code);\n\n  if (hsa_device_type == dev_type) {\n    *(reinterpret_cast<hsa_agent_t*>(data)) = agent;\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// This is the call-back function used to find a GPU type agent. Note that the\n// prototype of this function is dictated by the HSA specification\nhsa_status_t FindGPUDevice(hsa_agent_t agent, void* data) {\n  return FindAgent(agent, data, HSA_DEVICE_TYPE_GPU);\n}\n\n// This is the call-back function used to find a CPU type agent. Note that the\n// prototype of this function is dictated by the HSA specification\nhsa_status_t FindCPUDevice(hsa_agent_t agent, void* data) {\n  return FindAgent(agent, data, HSA_DEVICE_TYPE_CPU);\n}\n\n// Find the CPU and GPU agents we need to run this sample, and save them in the\n// BinarySearch structure for later use.\nhsa_status_t FindDevices(BinarySearch* bs) {\n  hsa_status_t err;\n\n  // Note that hsa_iterate_agents iterate through all known agents until\n  // HSA_STATUS_SUCCESS is not returned. The call-backs are implemented such\n  // that HSA_STATUS_INFO_BREAK means we found an agent of the specified type.\n  // This value is returned by hsa_iterate_agents.\n  bs->gpu_dev.handle = 0;\n  err = hsa_iterate_agents(FindGPUDevice, &bs->gpu_dev);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return HSA_STATUS_ERROR;\n  }\n\n  bs->cpu_dev.handle = 0;\n  err = hsa_iterate_agents(FindCPUDevice, &bs->cpu_dev);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return HSA_STATUS_ERROR;\n  }\n\n  if (0 == bs->gpu_dev.handle) {\n    std::cout << \"GPU Device is not Created properly!\" << std::endl;\n    RET_IF_HSA_ERR(HSA_STATUS_ERROR);\n  }\n\n  if (0 == bs->cpu_dev.handle) {\n    std::cout << \"CPU Device is not Created properly!\" << std::endl;\n    RET_IF_HSA_ERR(HSA_STATUS_ERROR);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// This function checks to see if the provided\n// pool has the HSA_AMD_SEGMENT_GLOBAL property. If the kern_arg flag is true,\n// the function adds an additional requirement that the pool have the\n// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT property. If kern_arg is false,\n// pools must NOT have this property.\n// Upon finding a pool that meets these conditions, HSA_STATUS_INFO_BREAK is\n// returned. HSA_STATUS_SUCCESS is returned if no errors were encountered, but\n// no pool was found meeting the requirements. If an error is encountered, we\n// return that error.\n\n// Note that this function does not match the required prototype for the\n// hsa_amd_agent_iterate_memory_pools call back function, and therefore must be\n// wrapped by a function with the correct prototype.\nstatic hsa_status_t\nFindGlobalPool(hsa_amd_memory_pool_t pool, void* data, bool kern_arg) {\n  hsa_status_t err;\n  hsa_amd_segment_t segment;\n  uint32_t flag;\n\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                     &segment);\n  RET_IF_HSA_ERR(err);\n\n  if (HSA_AMD_SEGMENT_GLOBAL != segment) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                                HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);\n  RET_IF_HSA_ERR(err);\n\n  uint32_t karg_st = flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT;\n\n  if ((karg_st == 0 && kern_arg) ||\n      (karg_st != 0 && !kern_arg)) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  *(reinterpret_cast<hsa_amd_memory_pool_t*>(data)) = pool;\n  return HSA_STATUS_INFO_BREAK;\n}\n\n// This is the call-back function for hsa_amd_agent_iterate_memory_pools() that\n// finds a pool with the properties of HSA_AMD_SEGMENT_GLOBAL and that is NOT\n// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT\nhsa_status_t FindStandardPool(hsa_amd_memory_pool_t pool, void* data) {\n  return FindGlobalPool(pool, data, false);\n}\n\n// This is the call-back function for hsa_amd_agent_iterate_memory_pools() that\n// finds a pool with the properties of HSA_AMD_SEGMENT_GLOBAL and that IS\n// HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT\nhsa_status_t FindKernArgPool(hsa_amd_memory_pool_t pool, void* data) {\n  return FindGlobalPool(pool, data, true);\n}\n\n// Find memory pools that we will need to allocate from for this sample\n// application. We will need memory associated with the host CPU, the GPU\n// executing the kernels, and for kernel arguments. This function will\n// save the found pools to the BinarySearch structure for use elsewhere\n// in this program.\nhsa_status_t FindPools(BinarySearch* bs) {\n  hsa_status_t err;\n\n  err = hsa_amd_agent_iterate_memory_pools(bs->cpu_dev, FindStandardPool,\n        &bs->cpu_pool);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return HSA_STATUS_ERROR;\n  }\n\n  err = hsa_amd_agent_iterate_memory_pools(bs->gpu_dev, FindStandardPool,\n        &bs->gpu_pool);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return HSA_STATUS_ERROR;\n  }\n\n  err = hsa_amd_agent_iterate_memory_pools(bs->cpu_dev,\n        FindKernArgPool, &bs->kern_arg_pool);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Once the needed memory pools have been found and the BinarySearch structure\n// has been updated with these handles, this function is then used to allocate\n// memory from those pools.\n// Devices with which a pool is associated already have access to the pool.\n// However, other devices may also need to read or write to that memory. Below,\n// we see how we can grant access to other devices to address this issue.\nhsa_status_t AllocateAndInitBuffers(BinarySearch* bs) {\n  hsa_status_t err;\n  uint32_t out_length = 4 * sizeof(uint32_t);\n  uint32_t in_length = bs->num_sub_divisions * 2 * sizeof(uint32_t);\n\n  // In all of these examples, we want both the cpu and gpu to have access to\n  // the buffer in question. We use the array of agents below in the susequent\n  // calls to hsa_amd_agents_allow_access() for this purpose.\n  hsa_agent_t ag_list[2] = {bs->gpu_dev, bs->cpu_dev};\n\n  err = hsa_amd_memory_pool_allocate(bs->cpu_pool, in_length, 0,\n                                     reinterpret_cast<void**>(&bs->input));\n  RET_IF_HSA_ERR(err);\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, bs->input);\n  RET_IF_HSA_ERR(err);\n  (void)memset(bs->input, 0, in_length);\n\n  err = hsa_amd_memory_pool_allocate(bs->cpu_pool, out_length, 0,\n                                     reinterpret_cast<void**>(&bs->output));\n  RET_IF_HSA_ERR(err);\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, bs->output);\n  RET_IF_HSA_ERR(err);\n  (void)memset(bs->input, 0, in_length);\n\n  err = hsa_amd_memory_pool_allocate(bs->cpu_pool, in_length, 0,\n                                     reinterpret_cast<void**>(&bs->input_arr));\n  RET_IF_HSA_ERR(err);\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, bs->input_arr);\n  RET_IF_HSA_ERR(err);\n  (void)memset(bs->input, 0, in_length);\n\n  err = hsa_amd_memory_pool_allocate(bs->cpu_pool, in_length, 0,\n                               reinterpret_cast<void**>(&bs->input_arr_local));\n  RET_IF_HSA_ERR(err);\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, bs->input_arr_local);\n  RET_IF_HSA_ERR(err);\n\n  // Binary-search application specific code...\n  // Initialize input buffer with random values in an increasing order\n  uint32_t max = bs->length * 20;\n  bs->input[0] = 0;\n\n  uint32_t seed = (unsigned int)time(NULL);\n  srand(seed);\n\n  for (uint32_t i = 1; i < bs->length; ++i) {\n    bs->input[i] = bs->input[i - 1] +\n     static_cast<uint32_t>(max * rand_r(&seed) / static_cast<float>(RAND_MAX));\n  }\n\n// #define VERBOSE 1\n#ifdef VERBOSE\n  std::cout << \"Input array values:\" << std::endl;\n\n  for (uint32_t i = 0; i < bs->length; ++i) {\n    std::cout << \"input[\" << i << \"] = \" << bs->input[i] << \" \";\n\n    if (i % 4 == 0) {\n      std::cout << std::endl;\n    }\n  }\n\n  std::cout << std::endl;\n#endif\n\n  return err;\n}\n\n// The code in this function illustrates how to load a kernel from\n// pre-compiled code. The goal is to get a handle that can be later\n// used in an AQL packet and also to extract information about kernel\n// that we will need. All of the information hand kernel handle will\n// be saved to the BinarySearch structure. It will be used when we\n// populate the AQL packet.\nhsa_status_t LoadKernelFromObjFile(BinarySearch* bs) {\n  hsa_status_t err;\n  hsa_code_object_reader_t code_obj_rdr = {0};\n  hsa_executable_t executable = {0};\n\n  hsa_file_t file_handle = open(bs->kernel_file_name.c_str(), O_RDONLY);\n\n  if (file_handle == -1) {\n    char agent_name[64];\n    err = hsa_agent_get_info(bs->gpu_dev, HSA_AGENT_INFO_NAME, agent_name);\n    RET_IF_HSA_ERR(err);\n    std::string fileName = std::string(\"./\") + agent_name + \"/\" + bs->kernel_file_name;\n    hsa_file_t file_handle = open(fileName.c_str(), O_RDONLY);\n  }\n\n  if (file_handle == -1) {\n    std::cout << \"failed to open \" << bs->kernel_file_name.c_str() <<\n              \" at line \" << __LINE__ << \", errno: \" << errno << std::endl;\n    return HSA_STATUS_ERROR;\n  }\n\n  err = hsa_code_object_reader_create_from_file(file_handle, &code_obj_rdr);\n  close(file_handle);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_create_alt(HSA_PROFILE_FULL,\n                HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT, NULL, &executable);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_load_agent_code_object(executable, bs->gpu_dev,\n        code_obj_rdr, NULL, NULL);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_freeze(executable, NULL);\n  RET_IF_HSA_ERR(err);\n\n  hsa_executable_symbol_t kern_sym;\n  err = hsa_executable_get_symbol(executable, NULL, bs->kernel_name.c_str(),\n                                  bs->gpu_dev, 0, &kern_sym);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_symbol_get_info(kern_sym,\n                                    HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT,\n                                                          &bs->kernel_object);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_symbol_get_info(kern_sym,\n                      HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE,\n                                                   &bs->private_segment_size);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_symbol_get_info(kern_sym,\n                        HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE,\n                                                     &bs->group_segment_size);\n  RET_IF_HSA_ERR(err);\n\n  // Remaining queries not supported on code object v3.\n  err = hsa_executable_symbol_get_info(kern_sym,\n                      HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE,\n                                                           &bs->kernarg_size);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_executable_symbol_get_info(kern_sym,\n                 HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT,\n                                                          &bs->kernarg_align);\n  RET_IF_HSA_ERR(err);\n  assert(bs->kernarg_align >= 16 && \"Reported kernarg size is too small.\");\n  bs->kernarg_align = (bs->kernarg_align == 0) ? 16 : bs->kernarg_align;\n\n  return err;\n}\n\n// This function shows how to do an asynchronous copy. We have to create a\n// signal and use the signal to notify us when the copy has completed.\nhsa_status_t AgentMemcpy(void* dst, const void* src,\n                         size_t size, hsa_agent_t dst_ag, hsa_agent_t src_ag) {\n  hsa_signal_t s;\n  hsa_status_t err;\n\n  err = hsa_signal_create(1, 0, NULL, &s);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_async_copy(dst, dst_ag, src, src_ag, size, 0, NULL, s);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,\n                                UINT64_MAX, HSA_WAIT_STATE_BLOCKED) != 0) {\n    err = HSA_STATUS_ERROR;\n    std::cout << \"Async copy signal error\" << std::endl;\n\n    RET_IF_HSA_ERR(err);\n  }\n\n  err = hsa_signal_destroy(s);\n\n  RET_IF_HSA_ERR(err);\n\n  return err;\n}\n\n// AlignDown and AlignUp are 2 utility functions we use to find an aligned\n// boundary either below or above a given value (address). The function will\n// return a value that has the specified alignment.\nstatic intptr_t\nAlignDown(intptr_t value, size_t alignment) {\n  assert(alignment != 0 && \"Zero alignment\");\n  return (intptr_t) (value & ~(alignment - 1));\n}\nstatic void*\nAlignUp(void* value, size_t alignment) {\n  return reinterpret_cast<void*>(AlignDown((uintptr_t)\n           (reinterpret_cast<uintptr_t>(value) + alignment - 1), alignment));\n}\n\n// This function populates the AQL patch with the information\n// we have collected and stored in the BinarySearch structure thus far.\nvoid PopulateAQLPacket(BinarySearch const* bs,\n                       hsa_kernel_dispatch_packet_t* aql) {\n  aql->header = 0;  // Dummy val. for now. Set this right before doorbell ring\n  aql->setup = 1;\n  aql->workgroup_size_x = bs->work_group_size;\n  aql->workgroup_size_y = 1;\n  aql->workgroup_size_z = 1;\n  aql->grid_size_x = bs->work_grid_size;\n  aql->grid_size_y = 1;\n  aql->grid_size_z = 1;\n  aql->private_segment_size = bs->private_segment_size;\n  aql->group_segment_size = bs->group_segment_size;\n  aql->kernel_object = bs->kernel_object;\n  aql->kernarg_address = bs->kern_arg_address;\n  aql->completion_signal = bs->signal;\n\n  return;\n}\n/*\n * Write everything in the provided AQL packet to the queue except the first 32\n * bits which include the header and setup fields. That should be done\n * last.\n */\nvoid WriteAQLToQueue(hsa_kernel_dispatch_packet_t const* in_aql,\n                     hsa_queue_t* q) {\n  void* queue_base = q->base_address;\n  const uint32_t queue_mask = q->size - 1;\n  uint64_t que_idx = hsa_queue_add_write_index_relaxed(q, 1);\n\n  hsa_kernel_dispatch_packet_t* queue_aql_packet;\n\n  queue_aql_packet =\n    &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue_base))\n    [que_idx & queue_mask];\n\n  queue_aql_packet->workgroup_size_x = in_aql->workgroup_size_x;\n  queue_aql_packet->workgroup_size_y = in_aql->workgroup_size_y;\n  queue_aql_packet->workgroup_size_z = in_aql->workgroup_size_z;\n  queue_aql_packet->grid_size_x = in_aql->grid_size_x;\n  queue_aql_packet->grid_size_y = in_aql->grid_size_y;\n  queue_aql_packet->grid_size_z = in_aql->grid_size_z;\n  queue_aql_packet->private_segment_size = in_aql->private_segment_size;\n  queue_aql_packet->group_segment_size = in_aql->group_segment_size;\n  queue_aql_packet->kernel_object = in_aql->kernel_object;\n  queue_aql_packet->kernarg_address = in_aql->kernarg_address;\n  queue_aql_packet->completion_signal = in_aql->completion_signal;\n}\n\n// This function allocates memory from the kern_arg pool we already found, and\n// then sets the argument values needed by the kernel code.\nhsa_status_t AllocAndSetKernArgs(BinarySearch* bs, void* args,\n                                 size_t arg_size, void** aql_buf_ptr) {\n  void* kern_arg_buf = nullptr;\n  hsa_status_t err;\n  size_t buf_size;\n  size_t req_align;\n\n  // The kernel code must be written to memory at the correct alignment. We\n  // already queried the executable to get the correct alignment, which is\n  // stored in bs->kernarg_align. In case the memory returned from\n  // hsa_amd_memory_pool is not of the correct alignment, we request a little\n  // more than what we need in case we need to adjust.\n  req_align = bs->kernarg_align;\n  // Allocate enough extra space for alignment adjustments if ncessary\n  buf_size = arg_size + (req_align << 1);\n\n  err = hsa_amd_memory_pool_allocate(bs->kern_arg_pool, buf_size, 0,\n                                     reinterpret_cast<void**>(&kern_arg_buf));\n  RET_IF_HSA_ERR(err);\n\n  // Address of the allocated buffer\n  bs->kern_arg_buffer = kern_arg_buf;\n\n  // Addr. of kern arg start.\n  bs->kern_arg_address = AlignUp(kern_arg_buf, req_align);\n\n  assert(arg_size >= bs->kernarg_size);\n  assert(((uintptr_t)bs->kern_arg_address + arg_size) <\n         ((uintptr_t)bs->kern_arg_buffer + buf_size));\n\n  (void)memcpy(bs->kern_arg_address, args, arg_size);\n  RET_IF_HSA_ERR(err);\n\n  // Make sure both the CPU and GPU can access the kernel arguments\n  hsa_agent_t ag_list[2] = {bs->gpu_dev, bs->cpu_dev};\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, bs->kern_arg_buffer);\n  RET_IF_HSA_ERR(err);\n\n  // Save this info in our BinarySearch structure for later.\n  *aql_buf_ptr = bs->kern_arg_address;\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// This wrapper atomically writes the provided header and setup to the\n// provided AQL packet. The provided AQL packet address should be in the\n// queue memory space.\ninline void AtomicSetPacketHeader(uint16_t header, uint16_t setup,\n                                  hsa_kernel_dispatch_packet_t* queue_packet) {\n  __atomic_store_n(reinterpret_cast<uint32_t*>(queue_packet),\n                   header | (setup << 16), __ATOMIC_RELEASE);\n}\n\n// Once all the required data for kernel execution is collected (in this\n// application it is stored in the BinarySearch structure) we can put it in\n// an AQL packet and ring the queue door bell to tell the command processor to\n// execute it.\nhsa_status_t Run(BinarySearch* bs) {\n  hsa_status_t err;\n\n  std::cout << \"Executing kernel \" << bs->kernel_name << std::endl;\n\n  // Adjust the size of workgroup\n  // This is mostly application specific.\n  if (bs->work_group_size > 64) {\n    bs->work_group_size = 64;\n    bs->num_sub_divisions = bs->length / bs->work_group_size;\n  }\n  if (bs->num_sub_divisions < bs->work_group_size) {\n    bs->num_sub_divisions = bs->work_group_size;\n  }\n\n  bs->work_grid_size = bs->num_sub_divisions;\n\n  // Explanation of BinarySearch algorithm.\n  /*\n   * Since a plain binary search on the GPU would not achieve much benefit\n   * over the GPU we are doing an N'ary search. We split the array into N\n   * segments every pass and therefore get log (base N) passes instead of log\n   * (base 2) passes.\n   *\n   * In every pass, only the thread that can potentially have the element we\n   * are looking for writes to the output array. For ex: if we are looking to\n   * find 4567 in the array and every thread is searching over a segment of\n   * 1000 values and the input array is 1, 2, 3, 4,... then the first thread\n   * is searching in 1 to 1000, the second one from 1001 to 2000, etc. The\n   * first one does not write to the output. The second one doesn't either.\n   * The fifth one however is from 4001 to 5000. So it can potentially have\n   * the element 4567 which lies between them.\n   *\n   * This particular thread writes to the output the lower bound, upper bound\n   * and whether the element equals the lower bound element. So, it would be\n   * 4001, 5000, 0\n   *\n   * The next pass would subdivide 4001 to 5000 into smaller segments and\n   * continue the same process from there.\n   *\n   * When a pass returns 1 in the third element, it means the element has been\n   * found and we can stop executing the kernel. If the element is not found,\n   * then the execution stops after looking at segment of size 1.\n   */\n\n  uint32_t global_lower_bound = 0;\n  uint32_t global_upper_bound = bs->length - 1;\n  uint32_t sub_div_size = (global_upper_bound - global_lower_bound + 1) /\n                          bs->num_sub_divisions;\n\n  if ((bs->input[0] > bs->find_me) ||\n      (bs->input[bs->length - 1] < bs->find_me)) {\n    bs->output[0] = 0;\n    bs->output[1] = bs->length - 1;\n    bs->output[2] = 0;\n    std::cout << \"Returning too early\" << std::endl;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  bs->output[3] = 1;\n\n  // Setup the kernel args\n  // See the meta-data for the compiled OpenCL kernel code to ascertain\n  // the sizes, padding and alignment required for kernel arguments.\n  // This can be seen by executing\n  // $ amdgcn-amd-amdhsa-readelf -aw ./binary_search_kernels.hsaco\n  // The kernel code will expect the following arguments aligned as shown.\n  typedef uint32_t uint2[2];\n  typedef uint32_t uint4[4];\n  struct __attribute__((aligned(16))) local_args_t {\n    uint4* outputArray;\n    uint2*  sortedArray;\n    uint32_t findMe;\n    uint32_t pad;\n    uint64_t global_offset_x;\n    uint64_t global_offset_y;\n    uint64_t global_offset_z;\n    uint64_t printf_buffer;\n    uint64_t default_queue;\n    uint64_t completion_action;\n  } local_args;\n\n  local_args.outputArray = reinterpret_cast<uint4*>(bs->output);\n  local_args.sortedArray = reinterpret_cast<uint2*>(bs->input_arr_local);\n  local_args.findMe = bs->find_me;\n  local_args.global_offset_x = 0;\n  local_args.global_offset_y = 0;\n  local_args.global_offset_z = 0;\n  local_args.printf_buffer = 0;\n  local_args.default_queue = 0;\n  local_args.completion_action = 0;\n\n  // Copy the kernel args structure into kernel arg memory\n  err = AllocAndSetKernArgs(bs, &local_args, sizeof(local_args),\n                            &bs->kern_arg_address);\n  RET_IF_HSA_ERR(err);\n\n  // Populate an AQL packet with the info we've gathered\n  hsa_kernel_dispatch_packet_t aql;\n  PopulateAQLPacket(bs, &aql);\n\n  uint32_t in_length = bs->num_sub_divisions * 2 * sizeof(uint32_t);\n\n  while ((sub_div_size > 1) && (bs->output[3] != 0)) {\n    for (uint32_t i = 0 ; i < bs->num_sub_divisions; i++) {\n      int idx1 = i * sub_div_size;\n      int idx2 = ((i + 1) * sub_div_size) - 1;\n      bs->input_arr[2 * i] = bs->input[idx1];\n      bs->input_arr[2 * i + 1] = bs->input[idx2];\n    }\n\n    // Copy kernel parameter from system memory to local memory\n    err = AgentMemcpy(reinterpret_cast<uint8_t*>(bs->input_arr_local),\n                      reinterpret_cast<uint8_t*>(bs->input_arr),\n                                        in_length, bs->gpu_dev, bs->cpu_dev);\n\n    RET_IF_HSA_ERR(err);\n\n    // Reset output buffer to zero\n    bs->output[3] = 0;\n\n    // Dispatch kernel with global work size, work group size with ONE dimesion\n    // and wait for kernel to complete\n\n    // Compute the write index of queue and copy Aql packet into it\n    uint64_t que_idx = hsa_queue_load_write_index_relaxed(bs->queue);\n\n    const uint32_t mask = bs->queue->size - 1;\n\n    // This function simply copies the data we've collected so far into our\n    // local AQL packet, except the the setup and header fields.\n    WriteAQLToQueue(&aql, bs->queue);\n\n    uint32_t aql_header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                  HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                  HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    // Set the packet's type, acquire and release fences. This should be done\n    // atomically after all the other fields have been set, using release\n    // memory ordering to ensure all the fields are set when the door bell\n    // signal is activated.\n    void* q_base = bs->queue->base_address;\n\n    AtomicSetPacketHeader(aql_header, aql.setup,\n                      &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                                                   (q_base))[que_idx & mask]);\n\n    // Increment the write index and ring the doorbell to dispatch kernel.\n    hsa_queue_store_write_index_relaxed(bs->queue, (que_idx + 1));\n    hsa_signal_store_relaxed(bs->queue->doorbell_signal, que_idx);\n\n    // Wait on the dispatch signal until the kernel is finished.\n    // Modify the wait condition to HSA_WAIT_STATE_ACTIVE (instead of\n    // HSA_WAIT_STATE_BLOCKED) if polling is needed instead of blocking, as we\n    // have below.\n    // The call below will block until the condition is met. Below we have said\n    // the condition is that the signal value (initiailzed to 1) associated with\n    // the queue is less than 1. When the kernel associated with the queued AQL\n    // packet has completed execution, the signal value is automatically\n    // decremented by the packet processor.\n    hsa_signal_value_t value = hsa_signal_wait_scacquire(bs->signal,\n                               HSA_SIGNAL_CONDITION_LT, 1,\n                               UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\n\n    // value should be 0, or we timed-out\n    if (value) {\n      std::cout << \"Timed out waiting for kernel to complete?\" << std::endl;\n      RET_IF_HSA_ERR(HSA_STATUS_ERROR);\n    }\n\n    // Reset the signal to its initial value for the next iteration\n    hsa_signal_store_screlease(bs->signal, 1);\n\n    // Binary search algorithm stuff...\n    global_lower_bound = bs->output[0] * sub_div_size;\n    global_upper_bound = global_lower_bound + sub_div_size - 1;\n    sub_div_size = (global_upper_bound - global_lower_bound + 1) /\n                   bs->num_sub_divisions;\n  }\n\n  uint32_t element_index = UINT_MAX;\n\n  for (uint32_t i = global_lower_bound; i <= global_upper_bound; i++) {\n    if (bs->input[i] == bs->find_me) {\n      element_index = i;\n      bs->output[0] = i;\n      bs->output[1] = i + 1;\n      bs->output[2] = 1;\n      break;\n    }\n\n    // Element is not found in region specified\n    // by global lower bound to global upper bound\n    bs->output[2] = 0;\n  }\n\n  uint32_t is_elem_found = bs->output[2];\n\n  std::cout << \"Lower bound = \" << global_lower_bound << std::endl;\n  std::cout << \"Upper bound = \" << global_upper_bound << std::endl;\n  std::cout << \"Element search for = \" << bs->find_me << std::endl;\n\n\n  if (is_elem_found == 1) {\n    std::cout << \"Element found at index \" << element_index << std::endl;\n  } else {\n    std::cout << \"Element value \" << bs->find_me << \" not found\" << std::endl;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Release all the RocR resources we have acquired in this application.\nhsa_status_t CleanUp(BinarySearch* bs) {\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_free(bs->input);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_free(bs->output);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_free(bs->input_arr);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_free(bs->kern_arg_buffer);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_queue_destroy(bs->queue);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_signal_destroy(bs->signal);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_shut_down();\n  RET_IF_HSA_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nint main(int argc, char* argv[]) {\n  // This BinarySearch structure (bs) below holds all of the appl. specific\n  // info we need to run the sample. This includes algorithm specific\n  // information as well as handles to RocR/HSA objects.\n\n  // The basic structure of this sample is to fill in this structure with the\n  // required RocR/HSA handles to RocR resources (e.g., agents, memory pools,\n  // queues, etc.) and then dispatch the packets to the queue, and examine the\n  // output.\n\n  BinarySearch bs;\n  hsa_status_t err;\n\n  // Set some working values specific to this application\n  InitializeBinarySearch(&bs);\n\n  // hsa_init() initializes internal data structures and causes devices\n  // (agents), memory pools and other resources to be discovered.\n  err = hsa_init();\n  RET_IF_HSA_ERR(err);\n\n  // Find the agents needed for the sample\n  err = FindDevices(&bs);\n  RET_IF_HSA_ERR(err);\n\n  // Create the completion signal used when dispatching a packet\n  err = hsa_signal_create(1, 0, NULL, &bs.signal);\n  RET_IF_HSA_ERR(err);\n\n  // Create a queue to submit our binary search AQL packets\n  err = hsa_queue_create(bs.gpu_dev, 128, HSA_QUEUE_TYPE_MULTI, NULL, NULL,\n                         UINT32_MAX, UINT32_MAX, &bs.queue);\n  RET_IF_HSA_ERR(err);\n\n  // Find the HSA memory pools we need to run this sample\n  err = FindPools(&bs);\n  RET_IF_HSA_ERR(err);\n\n  // Allocate memory from the correct memory pool, and initialize them as\n  // neeeded for the algorihm.\n  err = AllocateAndInitBuffers(&bs);\n  RET_IF_HSA_ERR(err);\n\n  // Create a kernel object from the pre-compiled kernel, and read some\n  // attributes associated with the kernel that we will need.\n  err = LoadKernelFromObjFile(&bs);\n  RET_IF_HSA_ERR(err);\n\n  // Fill in the AQL packet, assign the kernel arguments, enqueue the packet,\n  // \"ring\" the doorbell, and wait for completion.\n  err = Run(&bs);\n  RET_IF_HSA_ERR(err);\n\n  // Release all the RocR resources we've acquired and shutdown HSA.\n  err = CleanUp(&bs);\n\n  return 0;\n}\n\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/samples/binary_search/binary_search_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/**\n * One instance of this kernel call is a thread.\n * Each thread finds out the segment in which it should look for the element.\n * After that, it checks if the element is between the lower bound and upper\n * bound of its segment. If yes, then this segment becomes the total\n * searchspace for the next pass.\n *\n * To achieve this, it writes the lower bound and upper bound to the output\n * array. In case the element at the left end (lower bound) matches the element\n * we are looking for, that is marked in the output and we no longer need to\n * look any further.\n */\n \n__kernel void\nbinarySearch(__global uint4 * outputArray,\n             __const __global uint2  * sortedArray,\n             const   unsigned int findMe) {\n  unsigned int tid = get_global_id(0);\n\n  // Then we find the elements  for this thread\n  uint2 element = sortedArray[tid];\n\n\n  // If the element to be found does not lie between\n  // them, then nothing left to do in this thread\n  if((element.x > findMe) || (element.y < findMe)) {\n    return;\n  } else {\n    // However, if the element does lie between the lower\n    // and upper bounds of this thread's searchspace\n    // we need to narrow down the search further in this\n    // search space \n    // The search space for this thread is marked in the\n    // output as being the total search space for the next pass\n    outputArray[0].x = tid;\n    outputArray[0].w = 1;\n  }\n}\n\n\n__kernel void\nbinarySearch_mulkeys(__global int *keys,\n                     __global uint *input,\n                     const unsigned int numKeys,\n                     __global int *output) {\n\n  int gid = get_global_id(0);\n  int lBound = gid * 256;\n  int uBound = lBound + 255;\n\n  for(int i = 0; i < numKeys; i++) {\n    if(keys[i] >= input[lBound] && keys[i] <= input[uBound])\n      output[i]=lBound;\n  }\n\n}\n\n\n__kernel void\nbinarySearch_mulkeysConcurrent(__global uint *keys,\n                               __global uint *input,\n                               const unsigned int inputSize, // num. of inputs\n                               const unsigned int numSubdivisions,\n                               __global int *output) {\n\n  int lBound = (get_global_id(0) % numSubdivisions) * (inputSize / numSubdivisions);\n  int uBound = lBound + inputSize / numSubdivisions;\n  int myKey = keys[get_global_id(0) / numSubdivisions];\n  int mid;\n\n  while(uBound >= lBound) {\n    mid = (lBound + uBound) / 2;\n    if(input[mid] == myKey) {\n      output[get_global_id(0) / numSubdivisions] = mid;\n      return;\n    } else if(input[mid] > myKey) {\n      uBound = mid - 1;\n    } else {\n      lBound = mid + 1;\n    }\n  }\n}\n"
  },
  {
    "path": "rocrtst/samples/ipc/ipc.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/mman.h>\n#include <unistd.h>\n#include <sys/wait.h>\n\n#include <cassert>\n#include <iostream>\n\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\nstatic const uint32_t kShmemID = 1594685;\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nstruct callback_args {\n  hsa_agent_t host;\n  hsa_agent_t device;\n  hsa_amd_memory_pool_t cpu_pool;\n  hsa_amd_memory_pool_t gpu_pool;\n  size_t gpu_mem_granule;\n};\n\n// This function will test whether the provided memory pool is 1) in the\n// GLOBAL segment, 2) allows allocation and 3) is accessible by the provided\n// agent. If the provided pool meets these criteria, HSA_STATUS_INFO_BREAK is\n// returned\nstatic hsa_status_t\nFindPool(hsa_amd_memory_pool_t in_pool, hsa_agent_t agent) {\n  hsa_amd_segment_t segment;\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_get_info(in_pool,\n                                  HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n  RET_IF_HSA_ERR(err);\n  if (segment != HSA_AMD_SEGMENT_GLOBAL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  bool canAlloc;\n  err = hsa_amd_memory_pool_get_info(in_pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &canAlloc);\n  RET_IF_HSA_ERR(err);\n  if (!canAlloc) {\n     return HSA_STATUS_SUCCESS;\n  }\n\n  hsa_amd_memory_pool_access_t access =\n                                     HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n  err = hsa_amd_agent_memory_pool_get_info(agent, in_pool,\n                              HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\n  RET_IF_HSA_ERR(err);\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_INFO_BREAK;\n}\n\n// Callback function for hsa_amd_agent_iterate_memory_pools(). If the provided\n// pool is suitable (see comments for FindPool()), HSA_STATUS_INFO_BREAK is\n// returned. The input parameter \"data\" should point to memory for a \"struct\n// callback_args\", which includes a gpu pool and a granule field.  These fields\n// will be filled in by this function if the provided pool meets all the\n// requirements.\nstatic hsa_status_t FindDevicePool(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_status_t err;\n\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  struct callback_args *args = (struct callback_args *)data;\n\n  err = FindPool(pool, args->device);\n\n  if (err == HSA_STATUS_INFO_BREAK) {\n    args->gpu_pool = pool;\n\n\n#ifdef ROCRTST_EMULATOR_BUILD\n  args->gpu_mem_granule = 4;\n#else\n    err = hsa_amd_memory_pool_get_info(args->gpu_pool,\n      HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE, &args->gpu_mem_granule);\n    RET_IF_HSA_ERR(err);\n#endif\n\n    // We found what we were looking for, so return HSA_STATUS_INFO_BREAK\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Callback function for hsa_amd_agent_iterate_memory_pools(). If the provided\n// pool is suitable (see comments for FindPool()), HSA_STATUS_INFO_BREAK is\n// returned. The input parameter \"data\" should point to memory for a \"struct\n// callback_args\", which includes a cpu pool. This field will be filled in by\n// this function if the provided pool meets all the requirements.\nstatic hsa_status_t FindCPUPool(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_status_t err;\n\n  if (nullptr == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  struct callback_args *args = (struct callback_args *)data;\n\n  err = FindPool(pool, args->host);\n\n  if (err == HSA_STATUS_INFO_BREAK) {\n    args->cpu_pool = pool;\n  }\n  return err;\n}\n\n\n// This function is meant to be a call-back to hsa_iterate_agents. Find the\n// first GPU agent that has memory accessible by CPU\n// Return values:\n//  HSA_STATUS_INFO_BREAK -- 2 GPU agents have been found and stored. Iterator\n//    should stop iterating\n//  HSA_STATUS_SUCCESS -- 2 GPU agents have not yet been found; iterator\n//    should keep iterating\n//  Other -- Some error occurred\nstatic hsa_status_t FindGpu(hsa_agent_t agent, void *data) {\n  if (data == NULL) {\n     return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t err = hsa_agent_get_info(agent,\n                                     HSA_AGENT_INFO_DEVICE, &hsa_device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_device_type != HSA_DEVICE_TYPE_GPU) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  struct callback_args *args = (struct callback_args *)data;\n\n  // Make sure GPU device has pool host can access\n  args->device = agent;\n  err = hsa_amd_agent_iterate_memory_pools(agent, FindDevicePool, args);\n\n  if (err == HSA_STATUS_INFO_BREAK) {\n    // We were looking for, so return HSA_STATUS_INFO_BREAK\n    return HSA_STATUS_INFO_BREAK;\n  } else {\n    args->device = {0};\n  }\n\n  RET_IF_HSA_ERR(err);\n\n  // Returning HSA_STATUS_SUCCESS tells the calling iterator to keep iterating\n  return HSA_STATUS_SUCCESS;\n}\n\n// This function is meant to be a call-back to hsa_iterate_agents. For each\n// input agent the iterator provides as input, this function will check to\n// see if the input agent is a CPU. If so, it will update the callback_args\n// structure pointed to by the input parameter \"data\".\n\n// Return values:\n//  HSA_STATUS_INFO_BREAK -- CPU agent has been found and stored. Iterator\n//    should stop iterating\n//  HSA_STATUS_SUCCESS -- CPU agent has not yet been found; iterator\n//    should keep iterating\n//  Other -- Some error occurred\nstatic hsa_status_t FindCPUDevice(hsa_agent_t agent, void *data) {\n  if (data == NULL) {\n     return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE,\n                                                            &hsa_device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_CPU) {\n    struct callback_args *args = (struct callback_args *)data;\n\n    args->host = agent;\n\n    err = hsa_amd_agent_iterate_memory_pools(agent, FindCPUPool, args);\n\n    if (err == HSA_STATUS_INFO_BREAK) {  // we found what we were looking for\n      return HSA_STATUS_INFO_BREAK;\n    } else {\n      args->host = {0};\n      return err;\n    }\n  }\n\n  // Returning HSA_STATUS_SUCCESS tells the calling iterator to keep iterating\n  return HSA_STATUS_SUCCESS;\n}\n\n// This function will test whether the gpu-local buffer has been filled\n// with an expected value and return an error if not. The expected value is\n// also replaced with a new value.\n// Implementation notes: We create a buffer in system memory and copy\n// the gpu-local data buffer to be tested to this system memory buffer.\n// We also write the system memory buffer with the new value, and then copy\n// it back the gpu-local buffer.\nstatic hsa_status_t\nCheckAndFillBuffer(struct callback_args *args, void *gpu_src_ptr,\n                                     uint32_t exp_cur_val, uint32_t new_val) {\n  hsa_signal_t copy_signal;\n  size_t sz = args->gpu_mem_granule;\n  hsa_agent_t cpu_ag = args->host;\n  hsa_agent_t gpu_ag = args->device;\n  hsa_status_t err;\n\n  err = hsa_signal_create(1, 0, NULL, &copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  uint32_t *sysBuf;\n\n  err = hsa_amd_memory_pool_allocate(args->cpu_pool, sz, 0,\n                                          reinterpret_cast<void **>(&sysBuf));\n  RET_IF_HSA_ERR(err);\n\n  hsa_agent_t ag_list[2] = {args->device, args->host};\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, sysBuf);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_async_copy(sysBuf, cpu_ag, gpu_src_ptr, gpu_ag,\n                                                    sz, 0, NULL, copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_signal_wait_relaxed(copy_signal, HSA_SIGNAL_CONDITION_LT,\n                                       1, -1, HSA_WAIT_STATE_BLOCKED) != 0) {\n    printf(\"Async copy returned error value.\\n\");\n    return HSA_STATUS_ERROR;\n  }\n\n  uint32_t count = sz/sizeof(uint32_t);\n\n  for (uint32_t i = 0; i < count; ++i) {\n    if (sysBuf[i] != exp_cur_val) {\n      fprintf(stdout, \"Expected %d but got %d in buffer.\\n\",\n                                                      exp_cur_val, sysBuf[i]);\n      err = HSA_STATUS_ERROR;\n      break;\n    }\n    sysBuf[i] = new_val;\n  }\n\n  hsa_signal_store_relaxed(copy_signal, 1);\n\n  err = hsa_amd_memory_async_copy(gpu_src_ptr, gpu_ag, sysBuf, cpu_ag,\n                                                    sz, 0, NULL, copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  if (hsa_signal_wait_relaxed(copy_signal, HSA_SIGNAL_CONDITION_LT,\n                                       1, -1, HSA_WAIT_STATE_BLOCKED) != 0) {\n    printf(\"Async copy returned error value.\\n\");\n    return HSA_STATUS_ERROR;\n  }\n\n  err = hsa_signal_destroy(copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_free(sysBuf);\n  RET_IF_HSA_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// See if the other process wrote an error value to the token; if not, write\n// the newVal to the token.\nstatic void CheckAndSetToken(volatile int *token, int newVal) {\n  if (*token == -1) {\n    printf(\"Error in other process. Exiting.\\n\");\n    exit(-1);\n  } else {\n    *token = newVal;\n  }\n}\n\n// Summary of this IPC Sample:\n// This program demonstrates the IPC apis. Run it by executing 2 instances\n// of the program.\n// The first process will allocate some gpu-local memory and fill it with\n// 1's. This HSA buffer will be made shareable with hsa_amd_ipc_memory_create()\n// The 2nd process will access this shared buffer with\n// hsa_amd_ipc_memory_attach(), verify that 1's were written, and then fill\n// the buffer with 2's. Finally, the first process will then read the\n// gpu-local buffer and verify that the 2's were indeed written. The main\n// point is to show how hsa memory buffer handles can be shared among\n// processes.\n//\n// Implementation Notes:\n// -Standard linux shared memory is used in this sample program as a way\n// of sharing info and  synchronizing the 2 processes. This is independent\n// of RocR IPC and should not be confused with it.\nint main(int argc, char** argv) {\n  // IPC test\n  struct Shared {\n    volatile int token;\n    volatile int count;\n    volatile size_t size;\n    volatile hsa_amd_ipc_memory_t handle;\n    volatile hsa_amd_ipc_signal_t signal_handle;\n  };\n\n  // Allocate linux shared memory.\n  Shared* shared = (Shared*)mmap(nullptr, sizeof(Shared), PROT_READ | PROT_WRITE,\n                                 MAP_SHARED | MAP_ANONYMOUS, -1, 0);\n  if (shared == MAP_FAILED) {\n    fprintf(stdout, \"Unable to allocate shared memory. Exiting.\\n\");\n    return -1;\n  }\n\n  // \"token\" is used to signal state changes between the 2 processes.\n  volatile int* token = &shared->token;\n  *token = 0;\n  bool processOne;\n\n  // Spawn second process and verify communication\n  int child = fork();\n  if (child == -1) {\n    printf(\"fork failed.  Exiting.\\n\");\n    return -1;\n  }\n  if (child != 0) {\n    processOne = true;\n\n    // Signal to other process we are waiting, and then wait...\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n\n    fprintf(stdout, \"Second process observed, handshake...\\n\");\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n  } else {\n    processOne = false;\n    fprintf(stdout, \"Second process running.\\n\");\n\n    while (*token == 0) {\n      sched_yield();\n    }\n\n    CheckAndSetToken(token, 0);\n    // Wait for handshake\n    while (*token == 0) {\n      sched_yield();\n    }\n    CheckAndSetToken(token, 0);\n    fprintf(stdout, \"Handshake complete.\\n\");\n  }\n\n  hsa_status_t err;\n\n  err = hsa_init();\n  RET_IF_HSA_ERR(err);\n\n  struct callback_args args = {0, 0, 0};\n\n  err = hsa_iterate_agents(FindCPUDevice, &args);\n  assert(err == HSA_STATUS_INFO_BREAK);\n  if (err != HSA_STATUS_INFO_BREAK) {\n    return -1;\n  }\n\n  err = hsa_iterate_agents(FindGpu, &args);\n\n  if (err != HSA_STATUS_INFO_BREAK) {\n    printf(\n     \"No GPU with accessible VRAM required for this program found. Exiting\\n\");\n    return -1;\n  }\n\n  // Print out name of the device.\n  char name1[64] = {0};\n  char name2[64] = {0};\n  err = hsa_agent_get_info(args.host, HSA_AGENT_INFO_NAME, name1);\n  RET_IF_HSA_ERR(err);\n  err = hsa_agent_get_info(args.device, HSA_AGENT_INFO_NAME, name2);\n  RET_IF_HSA_ERR(err);\n  uint16_t loc1, loc2;\n  err = hsa_agent_get_info(args.host,\n                           (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &loc1);\n  RET_IF_HSA_ERR(err);\n  err = hsa_agent_get_info(args.device,\n                           (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &loc2);\n  RET_IF_HSA_ERR(err);\n  fprintf(stdout, \"Using: %s (%d) and %s (%d)\\n\", name1, loc1, name2, loc2);\n\n  // Get signal for async copy\n  hsa_signal_t copy_signal;\n  err = hsa_signal_create(1, 0, NULL, &copy_signal);\n  RET_IF_HSA_ERR(err);\n\n// Wrap printf to add first or second process indicator\n#define PROCESS_LOG(format, ...) \\\n    fprintf(stdout, \"line:%d P%u: \" format, \\\n                      __LINE__, static_cast<int>(!processOne), ##__VA_ARGS__);\n\n  hsa_agent_t ag_list[2] = {args.device, args.host};\n\n  if (processOne) {\n    // Allocate some VRAM and fill it with 1's\n    uint32_t* gpuBuf = NULL;\n    err = hsa_amd_memory_pool_allocate(args.gpu_pool, args.gpu_mem_granule, 0,\n                                            reinterpret_cast<void**>(&gpuBuf));\n    RET_IF_HSA_ERR(err);\n\n    PROCESS_LOG(\"Allocated local memory buffer at %p\\n\", gpuBuf);\n\n    err = hsa_amd_agents_allow_access(2, ag_list, NULL, gpuBuf);\n    RET_IF_HSA_ERR(err);\n\n    err = hsa_amd_ipc_memory_create(gpuBuf, args.gpu_mem_granule,\n                          const_cast<hsa_amd_ipc_memory_t*>(&shared->handle));\n    PROCESS_LOG(\n    \"Created IPC handle associated with gpu-local buffer at P0 address %p\\n\",\n                                                                      gpuBuf);\n\n    RET_IF_HSA_ERR(err);\n\n    uint32_t count = args.gpu_mem_granule/sizeof(uint32_t);\n    shared->size = args.gpu_mem_granule;\n    shared->count = count;\n\n    err = hsa_amd_memory_fill(gpuBuf, 1, count);\n    RET_IF_HSA_ERR(err);\n\n    // Get IPC capable signal\n    hsa_signal_t ipc_signal;\n    err = hsa_amd_signal_create(1, 0, NULL, HSA_AMD_SIGNAL_IPC, &ipc_signal);\n    RET_IF_HSA_ERR(err);\n\n    err = hsa_amd_ipc_signal_create(ipc_signal,\n                                    const_cast<hsa_amd_ipc_signal_t*>(&shared->signal_handle));\n    PROCESS_LOG(\"Created IPC handle associated with ipc_signal\\n\");\n    RET_IF_HSA_ERR(err);\n\n    // Signal Process 2 that the gpu buffer is ready to read.\n    CheckAndSetToken(token, 1);\n\n    PROCESS_LOG(\"Allocated buffer and filled it with 1's. Wait for P1...\\n\");\n    hsa_signal_value_t ret =\n        hsa_signal_wait_acquire(ipc_signal, HSA_SIGNAL_CONDITION_NE, 1, -1, HSA_WAIT_STATE_BLOCKED);\n\n    if (ret != 2) {\n      hsa_signal_store_release(ipc_signal, -1);\n      return -1;\n    }\n\n    err = CheckAndFillBuffer(&args, gpuBuf, 2, 0);\n    RET_IF_HSA_ERR(err);\n    PROCESS_LOG(\"Confirmed P1 filled buffer with 2\\n\")\n    PROCESS_LOG(\"PASSED on P0\\n\");\n\n    hsa_signal_store_relaxed(ipc_signal, 0);\n    \n    err = hsa_signal_destroy(ipc_signal);\n    RET_IF_HSA_ERR(err);\n\n    err = hsa_amd_memory_pool_free(gpuBuf);\n    RET_IF_HSA_ERR(err);\n\n    waitpid(child, nullptr, 0);\n\n  } else {  // \"ProcessTwo\"\n    PROCESS_LOG(\"Waiting for process 0 to write 1 to token...\\n\");\n    while (*token == 0) {\n      sched_yield();\n    }\n    if (*token != 1) {\n      *token = -1;\n      return -1;\n    }\n\n    // Attach shared VRAM\n    void* ptr;\n    err = hsa_amd_ipc_memory_attach(\n      const_cast<hsa_amd_ipc_memory_t*>(&shared->handle), shared->size, 1,\n                                                               ag_list, &ptr);\n    RET_IF_HSA_ERR(err);\n\n    PROCESS_LOG(\n     \"Attached to IPC handle; P1 buffer address gpu-local memory is %p\\n\",\n                                                                         ptr);\n\n    // Attach shared signal\n    hsa_signal_t ipc_signal;\n    err = hsa_amd_ipc_signal_attach(const_cast<hsa_amd_ipc_signal_t*>(&shared->signal_handle),\n                                    &ipc_signal);\n    RET_IF_HSA_ERR(err);\n\n    PROCESS_LOG(\"Attached to signal IPC handle\\n\");\n\n    err = CheckAndFillBuffer(&args, reinterpret_cast<uint32_t *>(ptr), 1, 2);\n    RET_IF_HSA_ERR(err);\n\n    PROCESS_LOG(\n      \"Confirmed P0 filled buffer with 1; P1 re-filled buffer with 2\\n\");\n    PROCESS_LOG(\"PASSED on P1\\n\");\n\n    hsa_signal_store_release(ipc_signal, 2);\n\n    err = hsa_amd_ipc_memory_detach(ptr);\n    RET_IF_HSA_ERR(err);\n\n    hsa_signal_wait_relaxed(ipc_signal, HSA_SIGNAL_CONDITION_NE, 2, -1, HSA_WAIT_STATE_BLOCKED);\n\n    err = hsa_signal_destroy(ipc_signal);\n    RET_IF_HSA_ERR(err);\n  }\n\n  err = hsa_signal_destroy(copy_signal);\n  RET_IF_HSA_ERR(err);\n\n  munmap(shared, sizeof(Shared));\n\n  err = hsa_shut_down();\n  RET_IF_HSA_ERR(err);\n\n#undef PROCESS_LOG\n  return 0;\n}\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 2.8.0)\n\n#\n#  Setup build environment\n#\n#  1) Setup env var ROCR_INC_DIR and ROCR_LIB_DIR to point to \n#     ROC Runtime header and libraries seperately\n#     \n#     export ROCR_INC_DIR=\"Path to ROC Runtime header\"\n#\n#     export ROCR_LIB_DIR=\"Path to ROC Runtime libraries\"\n#\n#     export ROCT_LIB_DIR=\"Path to ROC Thunk libraries\"\n#\n#  2) Make an new folder called build under root folder\n#\n#     mkdir build\n#\n#  3) Enter into folder of build, and run CMAKE to generate makefile\n#     and make it\n#\n#     cd build; cmake ..; make\n#\n\nif(WIN32)\n  MESSAGE(\"Windows platfomr is not supported\")\n  RRETURN()\nendif()\n\nif(NOT EXISTS $ENV{ROCR_INC_DIR}/hsa/hsa.h)\n  MESSAGE(\"ERROR: ROC Runtime headers can't be found under specified path\")\n  RETURN()\nendif()\n\n#\n# Flag to enable / disable verbose output.\n#\nSET( CMAKE_VERBOSE_MAKEFILE on )\n\n#\n# Set core runtime module name\n#\nset ( ROC_THUNK_NAME \"hsakmt\" )\nset ( ROC_THUNK_LIBRARY \"lib${ROC_THUNK_NAME}\" )\nset ( CORE_RUNTIME_NAME \"hsa-runtime\" )\nset ( CORE_RUNTIME_TARGET \"${CORE_RUNTIME_NAME}64\" )\nset ( CORE_RUNTIME_LIBRARY \"lib${CORE_RUNTIME_TARGET}\" )\n\nif(NOT EXISTS $ENV{ROCR_LIB_DIR}/${CORE_RUNTIME_LIBRARY}.so)\n  MESSAGE(\"ERROR: ROC Runtime libraries can't be found under sprcified path\")\n  RETURN()\nendif()\n\nif(NOT EXISTS $ENV{ROCT_LIB_DIR}/${ROC_THUNK_LIBRARY}.so)\n  MESSAGE(\"ERROR: ROC Thunk libraries can't be found under sprcified path\")\n  RETURN()\nendif()\n\nset(PROJECT_NAME \"rocm_async\")\nset(TEST_NAME \"${PROJECT_NAME}\")\nproject (${PROJECT_NAME})\n\nstring(TOLOWER \"${CMAKE_BUILD_TYPE}\" tmp)\nif(\"${tmp}\" STREQUAL \"debug\")\n  set(ISDEBUG \"1\")\n  add_definitions(-DDEBUG)\nendif()\n\nif(ISDEBUG)\n  set(CMAKE_CXX_FLAGS \"-std=c++11 -O0\")\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb\")\nelse()\n  set(CMAKE_CXX_FLAGS \"-std=c++11 -O2\")\nendif()\n\n#\n# Set the remaining compiler flags\n#\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Werror\")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-rtti\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fexceptions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-math-errno\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fms-extensions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fmerge-all-constants\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-threadsafe-statics\")\n\nINCLUDE_DIRECTORIES($ENV{ROCR_INC_DIR})\n\nLINK_DIRECTORIES($ENV{ROCR_LIB_DIR})\n\n# Add sources that belong to the project\naux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} Src)\n\nadd_executable(rocm_async  ${Src})\ntarget_link_libraries(rocm_async hsa-runtime64)\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/Readme.txt",
    "content": "\nIntroduction:\n#############\n\nRocmAsync is designed to capture the performance characteristics of buffer\ncopying and kernel read/write operations. The help screen of the benchmark\nshows various options one can use in initiating cop/read/writer operations.\nIn addition one can also query the topology of the system in terms of memory\npools and their agents\n\nBuild Environment:\n##################\n\nTo be able to build RocmAsync, users must ensure that the build platform has\nfollowing conditions satisfied:\nBuild Procedure:\n################\n\nThe following simply lists the steps to build RocmAsync\n  \n--- Define following environment variable to specify location of header\n    and library files\n\n    // Containins header files exported by ROC Runtime\n    ROCR_INC_DIR=\"Path of ROC Runtime Header Files\"\n\n    // Containins library files exported by ROC Runtime\n    ROCR_LIB_DIR=\"Path of ROC Runtime Library Files\"\n\n--- Create a build directory. The location of build directory can be anywhere\n    in the file system as long as it has read / write / execute permissions for\n    the user invoking the commands. User can choose any valid filename for the\n    build directory as the examples below illustrate\n\n        e.g. mkdir rocm_async/perfBuild\n        e.g. mkdir <parent_Of_rocm_async>rocm_async-build\n        e.g. mkdir <user_home>/rocmAsyncBuild\n\n--- Set working directory to be the new build directory\n\n        e.g. cd rocm_async/perfBuild\n        e.g. cd <parent_Of_rocm_async>rocm-async-build\n        e.g. cd <user_home>/rocmAsyncBuild\n\n--- Invoke Cmake to interpret build rules and generate native build files\n    The argument for cmake should be the root folder of RocmAsync test suite\n\n        // Builds Release version (default)\n        e.g. cmake .../rocm_async\n\n        // Builds Debug version\n        e.g. cmake -DCMAKE_BUILD_TYPE:STRING=Debug .../rocm_async\n\n--- Invoke the native build rules generated by cmake to build the various\n    object, library and executable files\n\n        e.g. make\n\n--- Invoke the install command to copy build artifacts to pre-defined folders\n    of RocmAsync suite. Upon completion artifacts will be copied to the bin and\n    lib directories of build directory\n    \n        e.g. make install\n    \n    @note: All executables will be found in <build_directory>/bin folder\n\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/base_test.cpp",
    "content": "#include \"base_test.hpp\"\n\n// Default Constructor\nBaseTest::BaseTest(size_t num) {\n  \n  // Set the numIteration_ to be 10 by default\n  num_iteration_ = num;\n}\n\nBaseTest::~BaseTest() {}\n\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/base_test.hpp",
    "content": "\n#ifndef ROCM_ASYNC_BW_BASE_TEST_H_\n#define ROCM_ASYNC_BW_BASE_TEST_H_\n\n#include \"hsa/hsa.h\"\n#include <iostream>\n#include <string>\n#include <vector>\n\nusing namespace std;\n\n// @Brief: An interface for tests to do some basic things,\n\nclass BaseTest {\n\n public:\n\n  BaseTest(size_t num = 10);\n\n  virtual ~BaseTest();\n\n  // @Brief: Allows setup proceedures to be completed\n  // before running the benchmark test case\n  virtual void SetUp() = 0;\n\n  // @Brief: Launches the proceedures of test scenario\n  virtual void Run() = 0;\n\n  // @Brief: Allows clean up proceedures to be invoked\n  virtual void Close() = 0;\n\n  // @Brief: Display the results\n  virtual void Display() const = 0;\n\n  // @Brief: Set number of iterations to run\n  void set_num_iteration(size_t num) {\n    num_iteration_ = num;\n    return;\n  }\n\n  // @Brief: Pre-declare some variables for deriviation, the\n  // derived class may declare more if needed\n protected:\n\n  // @Brief: Real iteration number\n  uint64_t num_iteration_;\n\n  // @Brief: Status code\n  hsa_status_t err_;\n};\n\n#endif  //  ROCM_ASYNC_BW_BASE_TEST_H_\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/common.cpp",
    "content": "#include \"common.hpp\"\n\nvoid error_check(hsa_status_t hsa_error_code, int line_num, const char* str) {\n  if (hsa_error_code != HSA_STATUS_SUCCESS &&\n      hsa_error_code != HSA_STATUS_INFO_BREAK) {\n    printf(\"HSA Error Found!  In file: %s;   At line: %d\\n\", str, line_num);\n    const char* string = nullptr;\n    hsa_status_string(hsa_error_code, &string);\n    printf(\"Error: %s\\n\", string);\n    exit(EXIT_FAILURE);\n  }\n}\n\n// So far, always find the first device\nhsa_status_t FindGpuDevice(hsa_agent_t agent, void* data) {\n  if (data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code =\n      hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &hsa_device_type);\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_GPU) {\n    *((hsa_agent_t*)data) = agent;\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindCpuDevice(hsa_agent_t agent, void* data) {\n  if (data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code =\n      hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &hsa_device_type);\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_CPU) {\n    *((hsa_agent_t*)data) = agent;\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindGlobalPool(hsa_amd_memory_pool_t region, void* data) {\n  if (NULL == data) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_status_t err;\n  hsa_amd_segment_t segment;\n  uint32_t flag;\n\n  err = hsa_amd_memory_pool_get_info(region, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n  ErrorCheck(err);\n\n  err = hsa_amd_memory_pool_get_info(region, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);\n  ErrorCheck(err);\n\n  if ((HSA_AMD_SEGMENT_GLOBAL == segment) &&\n      (flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED)) {\n    *((hsa_amd_memory_pool_t*)data) = region;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\ndouble CalcMedian(vector<double> scores) {\n  double median;\n  size_t size = scores.size();\n\n  if (size % 2 == 0)\n    median = (scores[size / 2 - 1] + scores[size / 2]) / 2;\n  else\n    median = scores[size / 2];\n\n  return median;\n}\n\ndouble CalcMean(vector<double> scores) {\n  double mean = 0;\n  size_t size = scores.size();\n\n  for (size_t i = 0; i < size; ++i) mean += scores[i];\n\n  return mean / size;\n}\n\ndouble CalcStdDeviation(vector<double> scores, int score_mean) {\n  double ret = 0.0;\n  for (size_t i = 0; i < scores.size(); ++i) {\n    ret += (scores[i] - score_mean) * (scores[i] - score_mean);\n  }\n\n  ret /= scores.size();\n\n  return sqrt(ret);\n}\n\nint CalcConcurrentQueues(vector<double> scores) {\n  int num_of_concurrent_queues = 0;\n  vector<double> execpted_exec_time_array;\n\n  for (size_t i = 0; i < scores.size(); ++i) {\n    execpted_exec_time_array.push_back(scores[0] / (1 << i));\n  }\n\n  for (size_t i = 0; i < scores.size(); ++i) {\n    cout << \"expected exe time = \" << execpted_exec_time_array[i] << endl;\n  }\n\n  for (size_t i = 1; i < scores.size(); ++i) {\n    if ((execpted_exec_time_array[i] - scores[i]) <\n        0.1 * execpted_exec_time_array[i])\n      ++num_of_concurrent_queues;\n  }\n\n  return num_of_concurrent_queues;\n}\n\n/**  hsa_status_t FindHostRegion(hsa_region_t region, void *data) {\n  if (data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  bool is_host_region = false;\n  hsa_status_t hsa_error_code = hsa_region_get_info(\n    region, (hsa_region_info_t)HSA_EXT_REGION_INFO_HOST_ACCESS, &is_host_region\n  );\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (is_host_region) {\n    *((hsa_region_t*)data) = region;\n  }\n\n  return HSA_STATUS_SUCCESS;\n} */\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/common.hpp",
    "content": "#ifndef ROCM_ASYNC_BW_COMMON_HPP\n#define ROCM_ASYNC_BW_COMMON_HPP\n\n#include <cstdlib>\n#include <iostream>\n#include <vector>\n#include <cmath>\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\nusing namespace std;\n\n#if defined(_MSC_VER)\n#define ALIGNED_(x) __declspec(align(x))\n#else\n#if defined(__GNUC__)\n#define ALIGNED_(x) __attribute__((aligned(x)))\n#endif  // __GNUC__\n#endif  // _MSC_VER\n\n#define MULTILINE(...) #__VA_ARGS__\n\n#define HSA_ARGUMENT_ALIGN_BYTES 16\n\n#define ErrorCheck(x) error_check(x, __LINE__, __FILE__)\n\n// @Brief: Check HSA API return value\nvoid error_check(hsa_status_t hsa_error_code, int line_num, const char* str);\n\n// @Brief: Find the first avaliable GPU device\nhsa_status_t FindGpuDevice(hsa_agent_t agent, void* data);\n\n// @Brief: Find the first avaliable CPU device\nhsa_status_t FindCpuDevice(hsa_agent_t agent, void* data);\n\n// @Brief: Find the agent's global region / pool\nhsa_status_t FindGlobalPool(hsa_amd_memory_pool_t region, void* data);\n\n// @Brief: Calculate the mean number of the vector\ndouble CalcMean(vector<double> scores);\n\n// @Brief: Calculate the Median valud of the vector\ndouble CalcMedian(vector<double> scores);\n\n// @Brief: Calculate the standard deviation of the vector\ndouble CalcStdDeviation(vector<double> scores, int score_mean);\n\n#endif  // ROCM_ASYNC_BW_COMMON_HPP\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/hsatimer.cpp",
    "content": "#include \"hsatimer.hpp\"\n\n#define NANOSECONDS_PER_SECOND 1000000000\n\nPerfTimer::PerfTimer() {\n  freq_in_100mhz = MeasureTSCFreqHz();\n}\n\nPerfTimer::~PerfTimer() {\n  while (!_timers.empty()) {\n    Timer *temp = _timers.back();\n    _timers.pop_back();\n    delete temp;\n  }\n}\n\n// Create a new timer instance and return its index\nint PerfTimer::CreateTimer() {\n\n  Timer *newTimer = new Timer;\n  newTimer->_start = 0.0;\n  newTimer->_clocks = 0.0;\n\n  #ifdef _WIN32\n  QueryPerformanceFrequency((LARGE_INTEGER *)&newTimer->_freq);\n  #endif\n\n  #ifdef  __linux__\n  newTimer->_freq = NANOSECONDS_PER_SECOND;\n  #endif\n\n  // Save the timer object in timer list\n  _timers.push_back(newTimer);\n  return (int)(_timers.size() - 1);\n}\n\nint PerfTimer::StartTimer(int index) {\n\n  if (index >= (int)_timers.size()) {\n    Error(\"Cannot reset timer. Invalid handle.\");\n    return HSA_FAILURE;\n  }\n\n  #ifdef _WIN32\n    // General Windows timing method\n    #ifndef _AMD\n      long long tmpStart;\n      QueryPerformanceCounter((LARGE_INTEGER *)&(tmpStart));\n  _   timers[index]->_start = (double)tmpStart;\n    // AMD Windows timing method\n    #else\n    #endif\n  #endif\n\n  #ifdef  __linux__\n    // General Linux timing method\n    #ifndef _AMD\n      struct timespec s;\n      clock_gettime(CLOCK_MONOTONIC, &s);\n      _timers[index]->_start =\n      (long long)s.tv_sec * NANOSECONDS_PER_SECOND + (long long)s.tv_nsec;\n    // AMD Linux timing method\n    #else\n      unsigned int unused;\n    _timers[index]->_start = __rdtscp(&unused);\n    #endif\n  #endif\n\n  return HSA_SUCCESS;\n}\n\nint PerfTimer::StopTimer(int index) {\n\n  long long n = 0;\n  if (index >= (int)_timers.size()) {\n    Error(\"Cannot reset timer. Invalid handle.\");\n    return HSA_FAILURE;\n  }\n  \n  #ifdef _WIN32\n    #ifndef _AMD\n      long long n1;\n      QueryPerformanceCounter((LARGE_INTEGER *)&(n1));\n      n = n1;\n    // AMD Window Timing\n    #else\n    #endif\n  #endif\n\n  #ifdef  __linux__\n    // General Linux timing method\n    #ifndef _AMD\n      struct timespec s;\n      clock_gettime(CLOCK_MONOTONIC, &s);\n      n = (long long)s.tv_sec * NANOSECONDS_PER_SECOND + (long long)s.tv_nsec;\n    // AMD Linux timing\n    #else\n      unsigned int unused;\n      n = __rdtscp(&unused);\n    #endif\n  #endif\n\n  n -= _timers[index]->_start;\n  _timers[index]->_start = 0;\n\n  #ifndef _AMD\n    _timers[index]->_clocks += n;\n  #endif\n\n  #ifdef  __linux__\n    //_timers[index]->_clocks += 10 * n /freq_in_100mhz;      // unit is ns\n    _timers[index]->_clocks += 1.0E-6 * 10 * n / freq_in_100mhz;  // convert to ms\n    // cout << \"_AMD is enabled!!!\" << endl;\n  #endif\n\n  return HSA_SUCCESS;\n}\n\nvoid PerfTimer::Error(string str) { cout << str << endl; }\n\ndouble PerfTimer::ReadTimer(int index) {\n\n  if (index >= (int)_timers.size()) {\n    Error(\"Cannot read timer. Invalid handle.\");\n    return HSA_FAILURE;\n  }\n\n  double reading = double(_timers[index]->_clocks);\n\n  reading = double(reading / _timers[index]->_freq);\n\n  return reading;\n}\n\nvoid PerfTimer::ResetTimer(int index) {\n  \n  // Check if index value is over the timer's size\n  if (index >= (int)_timers.size()) {\n    Error(\"Invalid index value\\n\");\n    exit(1);\n  }\n\n  _timers[index]->_clocks = 0.0;\n  _timers[index]->_start = 0.0;\n}\n\nuint64_t PerfTimer::CoarseTimestampUs() {\n  \n  #ifdef _WIN32\n    uint64_t freqHz, ticks;\n    QueryPerformanceFrequency((LARGE_INTEGER *)&freqHz);\n    QueryPerformanceCounter((LARGE_INTEGER *)&ticks);\n\n    // Scale numerator and divisor until (ticks * 1000000) fits in uint64_t.\n    while (ticks > (1ULL << 44)) {\n      ticks /= 16;\n      freqHz /= 16;\n    }\n\n    return (ticks * 1000000) / freqHz;\n  #endif\n\n  #ifdef  __linux__\n    struct timespec ts;\n    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);\n    return uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;\n  #endif\n}\n\nuint64_t PerfTimer::MeasureTSCFreqHz() {\n  \n  // Make a coarse interval measurement of TSC ticks for 1 gigacycles.\n  unsigned int unused;\n  uint64_t tscTicksEnd;\n\n  uint64_t coarseBeginUs = CoarseTimestampUs();\n  uint64_t tscTicksBegin = __rdtscp(&unused);\n  do {\n    tscTicksEnd = __rdtscp(&unused);\n  } while (tscTicksEnd - tscTicksBegin < 1000000000);\n\n  uint64_t coarseEndUs = CoarseTimestampUs();\n\n  // Compute the TSC frequency and round to nearest 100MHz.\n  uint64_t coarseIntervalNs = (coarseEndUs - coarseBeginUs) * 1000;\n  uint64_t tscIntervalTicks = tscTicksEnd - tscTicksBegin;\n  return (tscIntervalTicks * 10 + (coarseIntervalNs / 2)) / coarseIntervalNs;\n}\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/hsatimer.hpp",
    "content": "\n#ifndef ROCM_ASYNC_BW_MYTIME_H_\n#define ROCM_ASYNC_BW_MYTIME_H_\n\n// Will use AMD timer and general Linux timer based on users'\n// need --> compilation flag. Support for windows platform is\n// not currently available\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <x86intrin.h>\n#include <string.h>\n\n#include <iostream>\n#include <vector>\n#include <string>\n\nusing namespace std;\n\n#include <sys/time.h>\n\n#define HSA_FAILURE 1\n#define HSA_SUCCESS 0\n\nclass PerfTimer {\n\n private:\n\n  struct Timer {\n    string name;       /* < name name of time object*/\n    long long _freq;   /* < _freq frequency*/\n    long long _clocks; /* < _clocks number of ticks at end*/\n    long long _start;  /* < _start start point ticks*/\n  };\n\n  std::vector<Timer*> _timers; /*< _timers vector to Timer objects */\n  double freq_in_100mhz;\n\n public:\n\n  PerfTimer();\n  ~PerfTimer();\n\n private:\n\n  // AMD timing method\n  uint64_t CoarseTimestampUs();\n  uint64_t MeasureTSCFreqHz();\n\n  // General Linux timing method\n\n public:\n  \n  int CreateTimer();\n  int StartTimer(int index);\n  int StopTimer(int index);\n  void ResetTimer(int index);\n\n public:\n \n  // retrieve time\n  double ReadTimer(int index);\n  \n  // write into a file\n  double WriteTimer(int index);\n\n public:\n  void Error(string str);\n};\n\n#endif    //  ROCM_ASYNC_BW_MYTIME_H_\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/main.cpp",
    "content": "#include <unistd.h>\n#include <iostream>\n#include \"hsatimer.hpp\"\n#include \"rocm_async.hpp\"\n\nusing namespace std;\n\nint main(int argc, char** argv) {\n\n  // Create the Bandwidth test object\n  RocmAsync bw_test(argc, argv);\n\n  // Initialize the Bandwidth test object\n  bw_test.SetUp();\n\n  // Run the Bandwidth tests requested by user\n  bw_test.Run();\n\n  // Display the time taken by various tests\n  bw_test.Display();\n\n  // Release the Bandwidth test object resources\n  bw_test.Close();\n  return 0;\n}\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/os.cpp",
    "content": "\n// Compiling for Windows Platform\n#ifdef _WIN32\n\n#include \"os.hpp\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <Windows.h>\n\nvoid SetEnv(const char* env_var_name, const char* env_var_value) {\n  bool err = SetEnvironmentVariable(env_var_name, env_var_value);\n  if (false == err) {\n    printf(\"Set environment variable failed!\\n\");\n    exit(1);\n  }\n  return;\n}\n\nchar* GetEnv(const char* env_var_name) {\n  char* buff;\n  DWORD char_count = GetEnvironmentVariable(env_var_name, NULL, 0);\n  if (char_count == 0) return NULL;\n  buff = (char*)malloc(sizeof(char) * char_count);\n  GetEnvironmentVariable(env_var_name, buff, char_count);\n  buff[char_count - 1] = '\\0';\n  return buff;\n}\n\n#endif    // End of Windows Code\n\n// Compiling for Linux Platform\n#ifdef  __linux__\n\n#include \"os.hpp\"\n#include <stdlib.h>\n\nvoid SetEnv(const char* env_var_name, const char* env_var_value) {\n  int err = setenv(env_var_name, env_var_value, 1);\n  if (0 != err) {\n    printf(\"Set environment variable failed!\\n\");\n    exit(1);\n  }\n  return;\n}\n\nchar* GetEnv(const char* env_var_name) { return getenv(env_var_name); }\n\n#endif    // End of Linux Code\n\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/os.hpp",
    "content": "\n#ifndef ROCM_ASYNC_BW_UTILS_OS_H_\n#define ROCM_ASYNC_BW_UTILS_OS_H_\n\n#include <stdio.h>\n\n// Set envriroment variable\nvoid SetEnv(const char* env_var_name, const char* env_var_value);\n\n// Get the value of enviroment\nchar* GetEnv(const char* env_var_name);\n\n\n#endif    //  ROCM_ASYNC_BW_UTILS_OS_H_\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async.cpp",
    "content": "\r\n#include \"common.hpp\"\r\n#include \"rocm_async.hpp\"\r\n\r\n#include <stdlib.h>\r\n#include <assert.h>\r\n#include <algorithm>\r\n#include <unistd.h>\r\n#include <cctype>\r\n#include <sstream>\r\n\r\n// The values are in megabytes at allocation time\r\nconst uint32_t RocmAsync::SIZE_LIST[] = { 64, 128, 256, 512 };\r\n//const uint32_t RocmAsync::SIZE_LIST[] = { 2, 4, 8, 16, 32, 64, 128, 256, 512 };\r\n\r\nuint32_t RocmAsync::GetIterationNum() {\r\n  return num_iteration_ * 1.2 + 1;\r\n}\r\n\r\nvoid RocmAsync::AcquireAccess(hsa_agent_t agent, void* ptr) {\r\n  err_ = hsa_amd_agents_allow_access(1, &agent, NULL, ptr);\r\n  ErrorCheck(err_);\r\n}\r\n\r\nvoid RocmAsync::AllocateHostBuffers(bool bidir, uint32_t size,\r\n                                    void*& src_fwd, void*& dst_fwd,\r\n                                    void* buf_src_fwd, void* buf_dst_fwd,\r\n                                    hsa_agent_t src_agent_fwd, hsa_agent_t dst_agent_fwd,\r\n                                    void*& src_rev, void*& dst_rev,\r\n                                    void* buf_src_rev, void* buf_dst_rev,\r\n                                    hsa_agent_t src_agent_rev, hsa_agent_t dst_agent_rev,\r\n                                    hsa_signal_t& signal_fwd, hsa_signal_t& signal_rev) {\r\n\r\n  // Allocate host buffers and setup accessibility for copy operation\r\n  err_ = hsa_amd_memory_pool_allocate(sys_pool_, size, 0, (void**)&src_fwd);\r\n  ErrorCheck(err_);\r\n  AcquireAccess(src_agent_fwd, src_fwd);\r\n  AcquireAccess(cpu_agent_, buf_src_fwd);\r\n\r\n  err_ = hsa_amd_memory_pool_allocate(sys_pool_, size, 0, (void**)&dst_fwd);\r\n  ErrorCheck(err_);\r\n  AcquireAccess(dst_agent_fwd, dst_fwd);\r\n  AcquireAccess(cpu_agent_, buf_dst_fwd);\r\n\r\n  // Initialize host buffers to a determinate value\r\n  memset(src_fwd, 0x23, size);\r\n  memset(dst_fwd, 0x00, size);\r\n  \r\n  // Create a signal to wait on copy operation\r\n  // @TODO: replace it with a signal pool call\r\n  err_ = hsa_signal_create(1, 0, NULL, &signal_fwd);\r\n  ErrorCheck(err_);\r\n\r\n  if (bidir == false) {\r\n    return;\r\n  }\r\n\r\n  err_ = hsa_amd_memory_pool_allocate(sys_pool_, size, 0, (void**)&src_rev);\r\n  ErrorCheck(err_);\r\n  AcquireAccess(src_agent_rev, src_rev);\r\n  AcquireAccess(cpu_agent_, buf_src_rev);\r\n\r\n  err_ = hsa_amd_memory_pool_allocate(sys_pool_, size, 0, (void**)&dst_rev);\r\n  ErrorCheck(err_);\r\n  AcquireAccess(dst_agent_rev, dst_rev);\r\n  AcquireAccess(cpu_agent_, buf_dst_rev);\r\n\r\n  // Initialize host buffers to a determinate value\r\n  memset(src_rev, 0x23, size);\r\n  memset(dst_rev, 0x00, size);\r\n  \r\n  err_ = hsa_signal_create(1, 0, NULL, &signal_rev);\r\n  ErrorCheck(err_);\r\n}\r\n\r\nvoid RocmAsync::AllocateCopyBuffers(bool bidir, uint32_t size,\r\n                        void*& src_fwd, hsa_amd_memory_pool_t src_pool_fwd,\r\n                        void*& dst_fwd, hsa_amd_memory_pool_t dst_pool_fwd,\r\n                        hsa_agent_t src_agent_fwd, hsa_agent_t dst_agent_fwd,\r\n                        void*& src_rev, hsa_amd_memory_pool_t src_pool_rev,\r\n                        void*& dst_rev, hsa_amd_memory_pool_t dst_pool_rev,\r\n                        hsa_agent_t src_agent_rev, hsa_agent_t dst_agent_rev,\r\n                        hsa_signal_t& signal_fwd, hsa_signal_t& signal_rev) {\r\n\r\n  // Allocate buffers in src and dst pools for forward copy\r\n  err_ = hsa_amd_memory_pool_allocate(src_pool_fwd, size, 0, &src_fwd);\r\n  ErrorCheck(err_);\r\n  err_ = hsa_amd_memory_pool_allocate(dst_pool_fwd, size, 0, &dst_fwd);\r\n  ErrorCheck(err_);\r\n\r\n  // Allocate buffers in src and dst pools for reverse copy\r\n  if (bidir) {\r\n    err_ = hsa_amd_memory_pool_allocate(src_pool_rev, size, 0, &src_rev);\r\n    ErrorCheck(err_);\r\n    err_ = hsa_amd_memory_pool_allocate(dst_pool_rev, size, 0, &dst_rev);\r\n    ErrorCheck(err_);\r\n  }\r\n\r\n  // Acquire access to src and dst buffers for forward copy\r\n  AcquireAccess(src_agent_fwd, dst_fwd);\r\n  AcquireAccess(dst_agent_fwd, src_fwd);\r\n\r\n  // Acquire access to src and dst buffers for reverse copy\r\n  if (bidir) {\r\n    AcquireAccess(src_agent_rev, dst_rev);\r\n    AcquireAccess(dst_agent_rev, src_rev);\r\n  }\r\n  \r\n  // Create a signal to wait on copy operation\r\n  // @TODO: replace it with a signal pool call\r\n  err_ = hsa_signal_create(1, 0, NULL, &signal_fwd);\r\n  ErrorCheck(err_);\r\n  if (bidir) {\r\n    err_ = hsa_signal_create(1, 0, NULL, &signal_rev);\r\n    ErrorCheck(err_);\r\n  }\r\n}\r\n\r\nvoid RocmAsync::ReleaseBuffers(bool bidir,\r\n                               void* src_fwd, void* src_rev,\r\n                               void* dst_fwd, void* dst_rev,\r\n                               hsa_signal_t signal_fwd,\r\n                               hsa_signal_t signal_rev) {\r\n\r\n  // Free the src and dst buffers used in forward copy\r\n  // including the signal used to wait\r\n  err_ = hsa_amd_memory_pool_free(src_fwd);\r\n  ErrorCheck(err_);\r\n  err_ = hsa_amd_memory_pool_free(dst_fwd);\r\n  ErrorCheck(err_);\r\n  err_ = hsa_signal_destroy(signal_fwd);\r\n  ErrorCheck(err_);\r\n\r\n  // Free the src and dst buffers used in reverse copy\r\n  // including the signal used to wait\r\n  if (bidir) {\r\n    err_ = hsa_amd_memory_pool_free(src_rev);\r\n    ErrorCheck(err_);\r\n    err_ = hsa_amd_memory_pool_free(dst_rev);\r\n    ErrorCheck(err_);\r\n    err_ = hsa_signal_destroy(signal_rev);\r\n    ErrorCheck(err_);\r\n  }\r\n}\r\n\r\ndouble RocmAsync::GetGpuCopyTime(bool bidir,\r\n                                 hsa_signal_t signal_fwd,\r\n                                 hsa_signal_t signal_rev) {\r\n\r\n  // Obtain time taken for forward copy\r\n  hsa_amd_profiling_async_copy_time_t async_time_fwd = {0};\r\n  err_= hsa_amd_profiling_get_async_copy_time(signal_fwd, &async_time_fwd);\r\n  ErrorCheck(err_);\r\n  if (bidir == false) {\r\n    return(async_time_fwd.end - async_time_fwd.start);\r\n  }\r\n\r\n  hsa_amd_profiling_async_copy_time_t async_time_rev = {0};\r\n  err_= hsa_amd_profiling_get_async_copy_time(signal_rev, &async_time_rev);\r\n  ErrorCheck(err_);\r\n  double start = min(async_time_fwd.start, async_time_rev.start);\r\n  double end = max(async_time_fwd.end, async_time_rev.end);\r\n  return(end - start);\r\n}\r\n\r\nvoid RocmAsync::copy_buffer(void* dst, hsa_agent_t dst_agent,\r\n                            void* src, hsa_agent_t src_agent,\r\n                            size_t size, hsa_signal_t signal) {\r\n\r\n  // Copy from src into dst buffer\r\n  err_ = hsa_amd_memory_async_copy(dst, dst_agent,\r\n                                   src, src_agent,\r\n                                   size, 0, NULL, signal);\r\n  ErrorCheck(err_);\r\n  \r\n  // Wait for the forward copy operation to complete\r\n  while (hsa_signal_wait_acquire(signal, HSA_SIGNAL_CONDITION_LT, 1,\r\n                                     uint64_t(-1), HSA_WAIT_STATE_ACTIVE));\r\n}\r\n\r\nvoid RocmAsync::RunCopyBenchmark(async_trans_t& trans) {\r\n\r\n  // Bind if this transaction is bidirectional\r\n  bool bidir = trans.copy.bidir_;\r\n\r\n  // Initialize size of buffer to equal the largest element of allocation\r\n  uint32_t size_len = size_list_.size();\r\n  uint32_t max_size = size_list_.back() * 1024 * 1024;\r\n  \r\n  // Bind to resources such as pool and agents that are involved\r\n  // in both forward and reverse copy operations\r\n  void* buf_src_fwd;\r\n  void* buf_dst_fwd;\r\n  void* buf_src_rev;\r\n  void* buf_dst_rev;\r\n  void* host_src_fwd;\r\n  void* host_dst_fwd;\r\n  void* host_src_rev;\r\n  void* host_dst_rev;\r\n  hsa_signal_t signal_fwd;\r\n  hsa_signal_t signal_rev;\r\n  hsa_signal_t host_signal_fwd;\r\n  hsa_signal_t host_signal_rev;\r\n  hsa_amd_memory_pool_t src_pool_fwd = trans.copy.src_pool_;\r\n  hsa_amd_memory_pool_t dst_pool_fwd = trans.copy.dst_pool_;\r\n  hsa_amd_memory_pool_t src_pool_rev = dst_pool_fwd;\r\n  hsa_amd_memory_pool_t dst_pool_rev = src_pool_fwd;\r\n  hsa_agent_t src_agent_fwd = pool_list_[trans.copy.src_idx_].owner_agent_;\r\n  hsa_agent_t dst_agent_fwd = pool_list_[trans.copy.dst_idx_].owner_agent_;\r\n  hsa_agent_t src_agent_rev = dst_agent_fwd;\r\n  hsa_agent_t dst_agent_rev = src_agent_fwd;\r\n\r\n  // Allocate buffers and signal objects\r\n  AllocateCopyBuffers(bidir, max_size,\r\n                      buf_src_fwd, src_pool_fwd, \r\n                      buf_dst_fwd, dst_pool_fwd,\r\n                      src_agent_fwd, dst_agent_fwd,\r\n                      buf_src_rev, src_pool_rev, \r\n                      buf_dst_rev, dst_pool_rev,\r\n                      src_agent_rev, dst_agent_rev,\r\n                      signal_fwd, signal_rev);\r\n  \r\n  if (verify_) {\r\n    AllocateHostBuffers(bidir, max_size,\r\n                        host_src_fwd, host_dst_fwd,\r\n                        buf_src_fwd, buf_dst_fwd,\r\n                        src_agent_fwd, dst_agent_fwd,\r\n                        host_src_rev, host_dst_rev,\r\n                        buf_src_rev, buf_dst_rev,\r\n                        src_agent_rev, dst_agent_rev,\r\n                        host_signal_fwd, host_signal_rev);\r\n\r\n    // Initialize source buffer with values from verification buffer\r\n    copy_buffer(buf_src_fwd, src_agent_fwd,\r\n                host_src_fwd, cpu_agent_,\r\n                max_size, host_signal_fwd);\r\n    ErrorCheck(err_);\r\n    if (bidir) {\r\n      copy_buffer(buf_src_rev, src_agent_rev,\r\n                  host_src_rev, cpu_agent_,\r\n                  max_size, host_signal_rev);\r\n      ErrorCheck(err_);\r\n    }\r\n  }\r\n\r\n  // Bind the number of iterations\r\n  uint32_t iterations = GetIterationNum();\r\n\r\n  // Iterate through the differnt buffer sizes to\r\n  // compute the bandwidth as determined by copy\r\n  for (uint32_t idx = 0; idx < size_len; idx++) {\r\n    \r\n    // This should not be happening\r\n    uint32_t curr_size = size_list_[idx] * 1024 * 1024;\r\n    if (curr_size > max_size) {\r\n      break;\r\n    }\r\n\r\n    std::vector<double> cpu_time;\r\n    std::vector<double> gpu_time;\r\n    for (uint32_t it = 0; it < iterations; it++) {\r\n      #if DEBUG\r\n      printf(\".\");\r\n      fflush(stdout);\r\n      #endif\r\n\r\n      hsa_signal_store_relaxed(signal_fwd, 1);\r\n      if (bidir) {\r\n        hsa_signal_store_relaxed(signal_rev, 1);\r\n      }\r\n\r\n      if (verify_) {\r\n        AcquireAccess(src_agent_fwd, buf_dst_fwd);\r\n        AcquireAccess(dst_agent_fwd, buf_src_fwd);\r\n        if (bidir) {\r\n          AcquireAccess(src_agent_rev, buf_dst_rev);\r\n          AcquireAccess(dst_agent_rev, buf_src_rev);\r\n        }\r\n      }\r\n\r\n      // Create a timer object and reset signals\r\n      PerfTimer timer;\r\n      uint32_t index = timer.CreateTimer();\r\n\r\n      // Start the timer and launch forward copy operation\r\n      timer.StartTimer(index);\r\n      err_ = hsa_amd_memory_async_copy(buf_dst_fwd, dst_agent_fwd,\r\n                                       buf_src_fwd, src_agent_fwd,\r\n                                       curr_size, 0, NULL, signal_fwd);\r\n      ErrorCheck(err_);\r\n\r\n      // Launch reverse copy operation if it is bidirectional\r\n      if (bidir) {\r\n        err_ = hsa_amd_memory_async_copy(buf_dst_rev, dst_agent_rev,\r\n                                         buf_src_rev, src_agent_rev,\r\n                                         curr_size, 0, NULL, signal_rev);\r\n        ErrorCheck(err_);\r\n      }\r\n\r\n      // Wait for the forward copy operation to complete\r\n      while (hsa_signal_wait_acquire(signal_fwd, HSA_SIGNAL_CONDITION_LT, 1,\r\n                                     uint64_t(-1), HSA_WAIT_STATE_ACTIVE));\r\n\r\n      // Wait for the reverse copy operation to complete\r\n      if (bidir) {\r\n        while (hsa_signal_wait_acquire(signal_rev, HSA_SIGNAL_CONDITION_LT, 1,\r\n                                       uint64_t(-1), HSA_WAIT_STATE_ACTIVE));\r\n      }\r\n\r\n      // Stop the timer object\r\n      timer.StopTimer(index);\r\n\r\n      // Push the time taken for copy into a vector of copy times\r\n      cpu_time.push_back(timer.ReadTimer(index));\r\n\r\n      // Collect time from the signal(s)\r\n      if (trans.copy.uses_gpu_) {\r\n        double temp = GetGpuCopyTime(bidir, signal_fwd, signal_rev);\r\n        gpu_time.push_back(temp);\r\n      }\r\n\r\n      if (verify_) {\r\n\r\n        // Re-Establish access to destination buffer and host buffer\r\n        AcquireAccess(cpu_agent_, buf_dst_fwd);\r\n        AcquireAccess(dst_agent_fwd, host_dst_fwd);\r\n        \r\n        // Init dst buffer with values from outbuffer of copy operation\r\n        hsa_signal_store_relaxed(host_signal_fwd, 1);\r\n        copy_buffer(host_dst_fwd, cpu_agent_,\r\n                    buf_dst_fwd, dst_agent_fwd,\r\n                    curr_size, host_signal_fwd);\r\n        ErrorCheck(err_);\r\n        \r\n        // Compare output equals input\r\n        err_ = (hsa_status_t)memcmp(host_src_fwd, host_dst_fwd, curr_size);\r\n        ErrorCheck(err_);\r\n\r\n        if (bidir) {\r\n\r\n          // Re-Establish access to destination buffer and host buffer\r\n          AcquireAccess(cpu_agent_, buf_dst_rev);\r\n          AcquireAccess(dst_agent_rev, host_dst_rev);\r\n\r\n          hsa_signal_store_relaxed(host_signal_rev, 1);\r\n          copy_buffer(host_dst_rev, cpu_agent_,\r\n                      buf_dst_rev, dst_agent_rev,\r\n                      curr_size, host_signal_rev);\r\n          ErrorCheck(err_);\r\n        \r\n          // Compare output equals input\r\n          err_ = (hsa_status_t)memcmp(host_src_rev, host_dst_rev, curr_size);\r\n          ErrorCheck(err_);\r\n        }\r\n      }\r\n    }\r\n    #if DEBUG\r\n    std::cout << std::endl;\r\n    #endif\r\n\r\n    // Get Cpu min copy time\r\n    trans.cpu_min_time_.push_back(GetMinTime(cpu_time));\r\n    // Get Cpu mean copy time and store to the array\r\n    trans.cpu_avg_time_.push_back(GetMeanTime(cpu_time));\r\n\r\n    if (trans.copy.uses_gpu_) {\r\n      // Get Gpu min copy time\r\n      trans.gpu_min_time_.push_back(GetMinTime(gpu_time));\r\n      // Get Gpu mean copy time and store to the array\r\n      trans.gpu_avg_time_.push_back(GetMeanTime(gpu_time));\r\n    }\r\n\r\n    // Clear the stack of cpu times\r\n    cpu_time.clear();\r\n    gpu_time.clear();\r\n  }\r\n  \r\n  // Free up buffers and signal objects used in copy operation\r\n  ReleaseBuffers(bidir, buf_src_fwd, buf_src_rev,\r\n                 buf_dst_fwd, buf_dst_rev, signal_fwd, signal_rev);\r\n  \r\n  if (verify_) {\r\n    ReleaseBuffers(bidir, host_src_fwd, host_src_rev,\r\n                   host_dst_fwd, host_dst_rev, host_signal_fwd, host_signal_rev);\r\n  }\r\n}\r\n\r\nvoid RocmAsync::Run() {\r\n\r\n  // Enable profiling of Async Copy Activity\r\n  err_ = hsa_amd_profiling_async_copy_enable(true);\r\n  ErrorCheck(err_);\r\n\r\n  // Iterate through the list of transactions and execute them\r\n  uint32_t trans_size = trans_list_.size();\r\n  for (uint32_t idx = 0; idx < trans_size; idx++) {\r\n    async_trans_t& trans = trans_list_[idx];\r\n    if ((trans.req_type_ == REQ_COPY_BIDIR) ||\r\n        (trans.req_type_ == REQ_COPY_UNIDIR) ||\r\n        (trans.req_type_ == REQ_COPY_ALL_BIDIR) ||\r\n        (trans.req_type_ == REQ_COPY_ALL_UNIDIR)) {\r\n      RunCopyBenchmark(trans);\r\n      ComputeCopyTime(trans);\r\n    }\r\n    if ((trans.req_type_ == REQ_READ) ||\r\n        (trans.req_type_ == REQ_WRITE)) {\r\n      RunIOBenchmark(trans);\r\n    }\r\n  }\r\n\r\n  // Disable profiling of Async Copy Activity\r\n  err_ = hsa_amd_profiling_async_copy_enable(false);\r\n  ErrorCheck(err_);\r\n\r\n}\r\n\r\nvoid RocmAsync::Close() {\r\n  hsa_status_t status = hsa_shut_down();\r\n  ErrorCheck(status);\r\n  return;\r\n}\r\n\r\n// Sets up the bandwidth test object to enable running\r\n// the various test scenarios requested by user. The\r\n// things this proceedure takes care of are:\r\n//    \r\n//    Parse user arguments\r\n//    Discover RocR Device Topology\r\n//    Determine validity of requested test scenarios\r\n//    Build the list of transactions to execute\r\n//    Miscellaneous\r\n//\r\nvoid RocmAsync::SetUp() {\r\n\r\n  // Parse user arguments\r\n  ParseArguments();\r\n\r\n  // Validate input parameters\r\n  bool status = ValidateArguments();\r\n  if (status == false) {\r\n    PrintHelpScreen();\r\n    exit(1);\r\n  }\r\n\r\n  // Build list of transactions (copy, read, write) to execute\r\n  status = BuildTransList();\r\n  if (status == false) {\r\n    PrintHelpScreen();\r\n    exit(1);\r\n  }\r\n}\r\n\r\nRocmAsync::RocmAsync(int argc, char** argv) : BaseTest() {\r\n  usr_argc_ = argc;\r\n  usr_argv_ = argv;\r\n  verify_ = false;\r\n  pool_index_ = 0;\r\n  agent_index_ = 0;\r\n  req_read_ = REQ_INVALID;\r\n  req_write_ = REQ_INVALID;\r\n  req_copy_bidir_ = REQ_INVALID;\r\n  req_copy_unidir_ = REQ_INVALID;\r\n  req_copy_all_bidir_ = REQ_INVALID;\r\n  req_copy_all_unidir_ = REQ_INVALID;\r\n}\r\n\r\nRocmAsync::~RocmAsync() { }\r\n\r\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async.hpp",
    "content": "#ifndef __ROCM_ASYNC_BW_H__\n#define __ROCM_ASYNC_BW_H__\n\n#include \"hsa/hsa.h\"\n#include \"base_test.hpp\"\n#include \"hsatimer.hpp\"\n#include \"common.hpp\"\n#include <vector>\n\nusing namespace std;\n\n// Structure to encapsulate a RocR agent and its index in a list\ntypedef struct agent_info {\n\n  agent_info(hsa_agent_t agent,\n             uint32_t index, hsa_device_type_t device_type) {\n    agent_ = agent;\n    index_ = index;\n    device_type_ = device_type;\n  }\n\n  agent_info() {}\n  \n  uint32_t index_;\n  hsa_agent_t agent_;\n  hsa_device_type_t device_type_;\n\n} agent_info_t;\n\ntypedef struct pool_info {\n\n  pool_info(hsa_agent_t agent, uint32_t agent_index,\n            hsa_amd_memory_pool_t pool, hsa_amd_segment_t segment,\n            size_t size, size_t alloc_max_size, uint32_t index,\n            bool is_fine_grained, bool is_kernarg, bool access_to_all,\n            hsa_amd_memory_pool_access_t owner_access) {\n\n    pool_ = pool;\n    index_ = index;\n    segment_ = segment;\n    owner_agent_ = agent;\n    agent_index_ = agent_index;\n    size_ = size;\n    allocable_size_ = alloc_max_size;\n    is_kernarg_ = is_kernarg;\n    owner_access_ = owner_access;\n    access_to_all_ = access_to_all;\n    is_fine_grained_ = is_fine_grained;\n  }\n\n  pool_info() {}\n\n  uint32_t index_;\n  bool is_kernarg_;\n  bool access_to_all_;\n  bool is_fine_grained_;\n  size_t size_;\n  size_t allocable_size_;\n  uint32_t agent_index_;\n  hsa_agent_t owner_agent_;\n  hsa_amd_segment_t segment_;\n  hsa_amd_memory_pool_t pool_;\n  hsa_amd_memory_pool_access_t owner_access_;\n\n} pool_info_t;\n\n// Used to print out topology info\ntypedef struct agent_pool_info {\n\n  agent_pool_info() {}\n  \n  agent_info agent;\n  \n  vector<pool_info_t> pool_list;\n\n} agent_pool_info_t;\n\ntypedef struct async_trans {\n\n  uint32_t req_type_;\n  union {\n    struct {\n      bool bidir_;\n      bool uses_gpu_;\n      uint32_t src_idx_;\n      uint32_t dst_idx_;\n      hsa_amd_memory_pool_t src_pool_;\n      hsa_amd_memory_pool_t dst_pool_;\n    } copy;\n    struct {\n      void* code_;\n      uint32_t agent_idx_;\n      hsa_agent_t agent_;\n      uint32_t pool_idx_;\n      hsa_amd_memory_pool_t pool_;\n    } kernel;\n  };\n\n  // Cpu BenchMark average copy time\n  vector<double> cpu_avg_time_;\n\n  // Cpu Min time\n  vector<double> cpu_min_time_;\n\n  // Gpu BenchMark average copy time\n  vector<double> gpu_avg_time_;\n\n  // Gpu Min time\n  vector<double> gpu_min_time_;\n\n  // BenchMark's Average copy time and average bandwidth\n  vector<double> avg_time_;\n  vector<double> avg_bandwidth_;\n\n  // BenchMark's Min copy time and peak bandwidth\n  vector<double> min_time_;\n  vector<double> peak_bandwidth_;\n\n  async_trans(uint32_t req_type) { req_type_ = req_type; }\n} async_trans_t;\n\ntypedef enum Request_Type {\n\n  REQ_READ = 1,\n  REQ_WRITE = 2,\n  REQ_COPY_BIDIR = 3,\n  REQ_COPY_UNIDIR = 4,\n  REQ_COPY_ALL_BIDIR = 5,\n  REQ_COPY_ALL_UNIDIR = 6,\n  REQ_INVALID = 7,\n\n} Request_Type;\n\nclass RocmAsync : public BaseTest {\n\n public:\n\n  // @brief: Constructor for test case of RocmAsync\n  RocmAsync(int argc, char** argv);\n\n  // @brief: Destructor for test case of RocmAsync\n  virtual ~RocmAsync();\n\n  // @brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @brief: Core measurement execution\n  virtual void Run();\n\n  // @brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @brief: Display the results\n  virtual void Display() const;\n\n private:\n\n  // @brief: Print Help Menu Screen\n  void PrintHelpScreen();\n\n  // @brief: Discover the topology of pools on Rocm Platform\n  void DiscoverTopology();\n\n  // @brief: Print topology info\n  void PrintTopology();\n\n  // @brief: Print info on agents in system\n  void PrintAgentsList();\n\n  // @brief: Print info on memory pools in system\n  void PrintPoolsList();\n\n  // @brief: Parse the arguments provided by user to\n  // build list of transactions\n  void ParseArguments();\n  \n  // @brief: Print the list of transactions\n  void PrintTransList();\n\n  // @brief: Run read/write requests of users\n  void RunIOBenchmark(async_trans_t& trans);\n\n  // @brief: Run copy requests of users\n  void RunCopyBenchmark(async_trans_t& trans);\n\n  // @brief: Get iteration number\n  uint32_t GetIterationNum();\n\n  // @brief: Get the mean copy time\n  double GetMeanTime(std::vector<double>& vec);\n\n  // @brief: Get the min copy time\n  double GetMinTime(std::vector<double>& vec);\n\n  // @brief: Dispaly Benchmark result\n  void DisplayIOTime(async_trans_t& trans) const;\n  void DisplayCopyTime(async_trans_t& trans) const;\n  void DisplayCopyTimeMatrix() const;\n\n  private:\n\n  // @brief: Validate the arguments passed in by user\n  bool ValidateArguments();\n  bool ValidateReadReq();\n  bool ValidateWriteReq();\n  bool ValidateReadOrWriteReq(vector<uint32_t>& in_list);\n  \n  bool ValidateBidirCopyReq();\n  bool ValidateUnidirCopyReq();\n  bool ValidateCopyReq(vector<uint32_t>& in_list);\n  void PrintIOAccessError(uint32_t agent_idx, uint32_t pool_idx);\n  void PrintCopyAccessError(uint32_t src_pool_idx, uint32_t dst_pool_idx);\n  \n  bool PoolIsPresent(vector<uint32_t>& in_list);\n  bool PoolIsDuplicated(vector<uint32_t>& in_list);\n\n  // @brief: Builds a list of transaction per user request\n  void ComputeCopyTime(async_trans_t& trans);\n  bool BuildTransList();\n  bool BuildReadTrans();\n  bool BuildWriteTrans();\n  bool BuildBidirCopyTrans();\n  bool BuildUnidirCopyTrans();\n  bool BuildAllPoolsBidirCopyTrans();\n  bool BuildAllPoolsUnidirCopyTrans();\n  bool BuildReadOrWriteTrans(uint32_t req_type,\n                             vector<uint32_t>& in_list);\n  bool BuildCopyTrans(uint32_t req_type,\n                      vector<uint32_t>& src_list,\n                      vector<uint32_t>& dst_list);\n\n  void AllocateCopyBuffers(bool bidir, uint32_t size,\n                           void*& src_fwd, hsa_amd_memory_pool_t src_pool_fwd,\n                           void*& dst_fwd, hsa_amd_memory_pool_t dst_pool_fwd,\n                           hsa_agent_t src_agent_fwd, hsa_agent_t dst_agent_fwd,\n                           void*& src_rev, hsa_amd_memory_pool_t src_pool_rev,\n                           void*& dst_rev, hsa_amd_memory_pool_t dst_pool_rev,\n                           hsa_agent_t src_agent_rev, hsa_agent_t dst_agent_rev,\n                           hsa_signal_t& signal_fwd, hsa_signal_t& signal_rev);\n  void ReleaseBuffers(bool bidir,\n                      void* src_fwd, void* src_rev,\n                      void* dst_fwd, void* dst_rev,\n                      hsa_signal_t signal_fwd, hsa_signal_t signal_rev);\n  double GetGpuCopyTime(bool bidir, hsa_signal_t signal_fwd, hsa_signal_t signal_rev);\n  void AllocateHostBuffers(bool bidir, uint32_t size,\n                                    void*& src_fwd, void*& dst_fwd,\n                                    void* buf_src_fwd, void* buf_dst_fwd,\n                                    hsa_agent_t src_agent_fwd, hsa_agent_t dst_agent_fwd,\n                                    void*& src_rev, void*& dst_rev,\n                                    void* buf_src_rev, void* buf_dst_rev,\n                                    hsa_agent_t src_agent_rev, hsa_agent_t dst_agent_rev,\n                                    hsa_signal_t& signal_fwd, hsa_signal_t& signal_rev);\n  void copy_buffer(void* dst, hsa_agent_t dst_agent,\n                   void* src, hsa_agent_t src_agent,\n                   size_t size, hsa_signal_t signal);\n\n  // @brief: Check if agent and access memory pool, if so, set \n  // access to the agent, if not, exit\n  void AcquireAccess(hsa_agent_t agent, void* ptr);\n\n  // Functions to find agents and memory pools and udpate\n  // relevant data structures used to maintain system topology\n  friend hsa_status_t AgentInfo(hsa_agent_t agent, void* data);\n  friend hsa_status_t MemPoolInfo(hsa_amd_memory_pool_t pool, void* data);\n\n protected:\n  \n  // More variables declared for testing\n  // vector<transaction> tran_;\n\n  // Used to help count agent_info\n  uint32_t agent_index_;\n\n  // List used to store agent info, indexed by agent_index_\n  vector<agent_info_t> agent_list_;\n\n  // Used to help count pool_info_t\n  uint32_t pool_index_;\n\n  // List used to store pool_info_t, indexed by pool_index_\n  vector<pool_info_t> pool_list_;\n\n  // List used to store agent_pool_info_t\n  vector<agent_pool_info_t> agent_pool_list_;\n\n  // List of agents involved in a bidrectional copy operation\n  // Size of the list cannot exceed the number of agents\n  // reported by the system\n  vector<uint32_t> bidir_list_;\n\n  // List of source agents in a unidrectional copy operation\n  // Size of the list cannot exceed the number of agents\n  // reported by the system\n  vector<uint32_t> src_list_;\n\n  // List of destination agents in a unidrectional copy operation\n  // Size of the list cannot exceed the number of agents\n  // reported by the system\n  vector<uint32_t> dst_list_;\n\n  // List of agents involved in read operation. Has\n  // two agents, the first agent hosts the memory pool\n  // while the second agent executes the read operation\n  vector<uint32_t> read_list_;\n  \n  // List of agents involved in write operation. Has\n  // two agents, the first agent hosts the memory pool\n  // while the second agent executes the write operation\n  vector<uint32_t> write_list_;\n  \n  // List of sizes to use in copy and read/write transactions\n  // Size is specified in terms of Megabytes\n  vector<uint32_t> size_list_;\n\n  // Type of service requested by user\n  uint32_t req_read_;\n  uint32_t req_write_;\n  uint32_t req_copy_bidir_;\n  uint32_t req_copy_unidir_;\n  uint32_t req_copy_all_bidir_;\n  uint32_t req_copy_all_unidir_;\n\n  // List used to store transactions per user request\n  vector<async_trans_t> trans_list_;\n\n  // List used to store transactions involving Cpu-Gpu pools\n  vector<async_trans_t> matrix_trans_list_;\n\n  // Variable to store argument number\n\n  // Variable to store argument number\n\n  // Variable to store argument number\n  uint32_t usr_argc_;\n\n  // Pointer to store address of argument text\n  char** usr_argv_;\n\n  // BenchMark copy time\n  vector<double> op_time_;\n\n  // Min time\n  vector<double> min_time_;\n\n  // Determines if user has requested verification\n  bool verify_;\n\n  // CPU agent used for verification\n  hsa_agent_t cpu_agent_;\n\n  // System region\n  hsa_amd_memory_pool_t sys_pool_;\n \n  static const uint32_t SIZE_LIST[4];\n  //static const uint32_t SIZE_LIST[9];\n\n};\n\n#endif\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_io.cpp",
    "content": "\n#include \"common.hpp\"\n#include \"rocm_async.hpp\"\n\n#include <stdlib.h>\n#include <assert.h>\n#include <algorithm>\n#include <unistd.h>\n#include <cctype>\n#include <sstream>\n\nvoid RocmAsync::RunIOBenchmark(async_trans_t& trans) {\n\n  std::cout << \"Unsupported Request - Read / Write\" << std::endl;\n  exit(1);\n}\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_parse.cpp",
    "content": "#include \"common.hpp\"\r\n#include \"rocm_async.hpp\"\r\n\r\n#include <algorithm>\r\n#include <sstream>\r\n#include <unistd.h>\r\n\r\n// Parse option value string. The string has one more decimal\r\n// values separated by comma - \"3,6,9,12,15\".\r\nstatic bool ParseOptionValue(char* value, vector<uint32_t>&value_list) {\r\n \r\n  // Capture the option value string\r\n  std::stringstream stream;\r\n  stream << value;\r\n  \r\n  uint32_t token = 0x11231926;\r\n  do {\r\n    \r\n    // Read the option value\r\n    stream >> token;\r\n\r\n    // Update output list with values\r\n    value_list.push_back(token);\r\n\r\n    // Ignore the delimiter\r\n    if((stream.eof()) ||\r\n       (stream.peek() == ',')) {\r\n      stream.ignore();\r\n    } else {\r\n      return false;\r\n    }\r\n\r\n  } while (!stream.eof());\r\n\r\n  return true;\r\n}\r\n\r\nvoid RocmAsync::ParseArguments() {\r\n\r\n  bool print_help = false;\r\n  bool copy_all_bi = false;\r\n  bool copy_all_uni = false;\r\n  bool print_topology = false;\r\n\r\n  // This will suppress prints from getopt implementation\r\n  // In case of error, it will return the character '?' as\r\n  // return value.\r\n  opterr = 0;\r\n  \r\n  int opt;\r\n  bool status;\r\n  while ((opt = getopt(usr_argc_, usr_argv_, \"hvtaAb:s:d:r:w:m:\")) != -1) {\r\n    switch (opt) {\r\n\r\n      // Print help screen\r\n      case 'h':\r\n        print_help = true;\r\n        break;\r\n\r\n      // Print system topology\r\n      case 't':\r\n        print_topology = true;\r\n        break;\r\n\r\n      // Set verification flag to true\r\n      case 'v':\r\n        verify_ = true;\r\n        break;\r\n\r\n      // Collect list of agents involved in bidirectional copy operation\r\n      case 'b':\r\n        status = ParseOptionValue(optarg, bidir_list_);\r\n        if (status) {\r\n          req_copy_bidir_ = REQ_COPY_BIDIR;\r\n          break;\r\n        }\r\n        print_help = true;\r\n        break;\r\n\r\n      // Collect list of source pools involved in unidirectional copy operation\r\n      case 's':\r\n        status = ParseOptionValue(optarg, src_list_);\r\n        if (status) {\r\n          req_copy_unidir_ = REQ_COPY_UNIDIR;\r\n          break;\r\n        }\r\n        print_help = true;\r\n        break;\r\n\r\n      // Collect list of destination pools involved in unidirectional copy operation\r\n      case 'd':\r\n        status = ParseOptionValue(optarg, dst_list_);\r\n        if (status) {\r\n          req_copy_unidir_ = REQ_COPY_UNIDIR;\r\n          break;\r\n        }\r\n        print_help = true;\r\n        break;\r\n\r\n      // Collect request to read a buffer\r\n      case 'r':\r\n        req_read_ = REQ_READ;\r\n        status = ParseOptionValue(optarg, read_list_);\r\n        if (status == false) {\r\n          print_help = true;\r\n        }\r\n        break;\r\n\r\n      // Collect request to write a buffer\r\n      case 'w':\r\n        req_write_ = REQ_WRITE;\r\n        status = ParseOptionValue(optarg, write_list_);\r\n        if (status == false) {\r\n          print_help = true;\r\n        }\r\n        break;\r\n\r\n      // Size of buffers to use in copy and read/write operations\r\n      case 'm':\r\n        status = ParseOptionValue(optarg, size_list_);\r\n        if (status == false) {\r\n          print_help = true;\r\n        }\r\n        break;\r\n\r\n      // Enable Unidirectional copy among all valid pools\r\n      case 'a':\r\n        copy_all_uni = true;\r\n        req_copy_all_unidir_ = REQ_COPY_ALL_UNIDIR;\r\n        break;\r\n\r\n      // Enable Bidirectional copy among all valid pools\r\n      case 'A':\r\n        copy_all_bi = true;\r\n        req_copy_all_bidir_ = REQ_COPY_ALL_BIDIR;\r\n        break;\r\n\r\n      // getopt implementation returns the value of the unknown\r\n      // option or an option with missing operand in the variable\r\n      // optopt\r\n      case '?':\r\n        std::cout << \"Value of optopt is: \" << '?' << std::endl;\r\n        if ((optopt == 'b' || optopt == 's' || optopt == 'd' || optopt == 'e')) {\r\n          std::cout << \"Error: Option -b -s -d and -e require argument\" << std::endl;\r\n        }\r\n        print_help = true;\r\n        break;\r\n      default:\r\n        print_help = true;\r\n        break;\r\n    }\r\n  }\r\n  \r\n  // Print help screen if user option has \"-h\"\r\n  if (print_help) {\r\n    PrintHelpScreen();\r\n    exit(0);\r\n  }\r\n  \r\n  // Initialize Roc Runtime\r\n  err_ = hsa_init();\r\n  ErrorCheck(err_);\r\n\r\n  // Discover the topology of RocR agent in system\r\n  DiscoverTopology();\r\n  \r\n  // Print system topology if user option has \"-t\"\r\n  if (print_topology) {\r\n    PrintTopology();\r\n    exit(0);\r\n  }\r\n\r\n  // Invalidate request if user has requested full\r\n  // copying for both unidirectional and bidirectional\r\n  if ((copy_all_bi) && (copy_all_uni)) {\r\n    PrintHelpScreen();\r\n    exit(0);\r\n  }\r\n\r\n  // Initialize pool list if full copying in unidirectional mode is enabled\r\n  if (copy_all_uni) {\r\n    uint32_t size = pool_list_.size();\r\n    for (uint32_t idx = 0; idx < size; idx++) {\r\n      src_list_.push_back(idx);\r\n      dst_list_.push_back(idx);\r\n    }\r\n  }\r\n\r\n  // Initialize pool list if full copying in bidirectional mode is enabled\r\n  if (copy_all_bi) {\r\n    uint32_t size = pool_list_.size();\r\n    for (uint32_t idx = 0; idx < size; idx++) {\r\n      bidir_list_.push_back(idx);\r\n    }\r\n  }\r\n\r\n  // Initialize the list of buffer sizes to use in copy/read/write operations\r\n  // For All Copy operations use only one buffer size\r\n  if (size_list_.size() == 0) {\r\n    uint32_t size_len = sizeof(SIZE_LIST)/sizeof(uint32_t);\r\n    for (uint32_t idx = 0; idx < size_len; idx++) {\r\n      if ((copy_all_bi) || (copy_all_uni)) {\r\n        if (idx == 0) {\r\n          size_list_.push_back(SIZE_LIST[idx]);\r\n        }\r\n      } else {\r\n        size_list_.push_back(SIZE_LIST[idx]);\r\n      }\r\n    }\r\n  }\r\n  std::sort(size_list_.begin(), size_list_.end());\r\n}\r\n\r\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_print.cpp",
    "content": "#include \"common.hpp\"\r\n#include \"rocm_async.hpp\"\r\n\r\n// @Brief: Print Help Menu Screen\r\nvoid RocmAsync::PrintHelpScreen() {\r\n\r\n  std::cout << std::endl;\r\n  std::cout << \"Runs with following options:\" << std::endl;\r\n  std::cout << std::endl;\r\n  std::cout << \"\\t -h Prints the help screen\" << std::endl;\r\n  std::cout << \"\\t -g Prints Gpu times for transfers\" << std::endl;\r\n  std::cout << \"\\t -t Prints system topology and its memory pools\" << std::endl;\r\n  std::cout << \"\\t -m List of buffer sizes to use, specified in Megabytes\" << std::endl;\r\n  std::cout << \"\\t -r List of pool,agent pairs engaged in Read operation\" << std::endl;\r\n  std::cout << \"\\t -w List of pool,agent pairs engaged in Write operation\" << std::endl;\r\n  std::cout << \"\\t -b List pools to use in bidirectional copy operations\" << std::endl;\r\n  std::cout << \"\\t -s List of source pools to use in copy unidirectional operations\" << std::endl;\r\n  std::cout << \"\\t -d List of destination pools to use in unidirectional copy operations\" << std::endl;\r\n  std::cout << \"\\t -a Perform Unidirectional Copy involving all pool combinations\" << std::endl;\r\n  std::cout << \"\\t -A Perform Bidirectional Copy involving all pool combinations\" << std::endl;\r\n  std::cout << std::endl;\r\n  \r\n  std::cout << std::endl;\r\n  std::cout << \"\\t @note 1: Removes copyReq(srcI, dstJ) - where either Src or Dst Pool is fine-grained\" << std::endl;\r\n  std::cout << std::endl;\r\n  std::cout << \"\\t @note 2: Treats copyReq(dstI, srcJ) as NOT EQUAL to copyReq(dstJ, srcI) \" << std::endl;\r\n  std::cout << \"\\t            Underlying copy engine could be different \" << std::endl;\r\n  std::cout << std::endl;\r\n\r\n  /*\r\n  std::cout << \"\\t @note 1: Removes copyReq(srcI, dstI) - where Src & Dst Pools are same\" << std::endl;\r\n  std::cout << std::endl;\r\n  std::cout << \"\\t @note 2: Removes copyReq(srcI, dstJ) - where Src & Dst Pools are Cpu bound\" << std::endl;\r\n  std::cout << std::endl;\r\n  std::cout << \"\\t @note 3: Removes copyReq(srcI, dstJ) - where either Src or Dst Pool is fine-grained\" << std::endl;\r\n  std::cout << std::endl;\r\n  std::cout << \"\\t @note 4: Treats copyReq(dstI, srcJ) as NOT EQUAL to copyReq(dstJ, srcI) \" << std::endl;\r\n  std::cout << \"\\t            Underlying copy engine could be different \" << std::endl;\r\n  std::cout << std::endl;\r\n  */\r\n}\r\n\r\n// @brief: Print the topology of Memory Pools and Agents present in system\r\nvoid RocmAsync::PrintTopology() {\r\n\r\n  size_t count = agent_pool_list_.size();\r\n  std::cout << std::endl;\r\n  for (uint32_t idx = 0; idx < count; idx++) {\r\n    agent_pool_info_t node = agent_pool_list_.at(idx);\r\n\r\n    // Print agent info\r\n    std::cout << \"Agent: \" << node.agent.index_ << std::endl;\r\n    if (HSA_DEVICE_TYPE_CPU == node.agent.device_type_)\r\n      std::cout << \"  Agent Device Type:                            CPU\" << std::endl;\r\n    else if (HSA_DEVICE_TYPE_GPU == node.agent.device_type_)\r\n      std::cout << \"  Agent Device Type:                            GPU\" << std::endl;\r\n\r\n    // Print pool info\r\n    size_t pool_count = node.pool_list.size();\r\n    for (uint32_t jdx = 0; jdx < pool_count; jdx++) {\r\n      std::cout << \"    Memory Pool:                                \"\r\n           << node.pool_list.at(jdx).index_ << std::endl;\r\n      std::cout << \"        max allocable size in KB:               \"\r\n           << node.pool_list.at(jdx).allocable_size_ / 1024 << std::endl;\r\n      std::cout << \"        segment id:                             \"\r\n           << node.pool_list.at(jdx).segment_ << std::endl;\r\n      std::cout << \"        is kernarg:                             \"\r\n           << node.pool_list.at(jdx).is_kernarg_ << std::endl;\r\n      std::cout << \"        is fine-grained:                        \"\r\n           << node.pool_list.at(jdx).is_fine_grained_ << std::endl;\r\n      std::cout << \"        accessible to owner:                    \"\r\n           << node.pool_list.at(jdx).owner_access_ << std::endl;\r\n      std::cout << \"        accessible to all by default:           \"\r\n           << node.pool_list.at(jdx).access_to_all_ << std::endl;\r\n    }\r\n    std::cout << std::endl;\r\n  }\r\n  std::cout << std::endl;\r\n}\r\n\r\n// @brief: Print info on agents in system\r\nvoid RocmAsync::PrintAgentsList() {\r\n\r\n  size_t count = agent_pool_list_.size();\r\n  for (uint32_t idx = 0; idx < count; idx++) {\r\n    std::cout << std::endl;\r\n    agent_pool_info_t node = agent_pool_list_.at(idx);\r\n    std::cout << \"Agent: \" << node.agent.index_ << std::endl;\r\n    if (HSA_DEVICE_TYPE_CPU == node.agent.device_type_)\r\n      std::cout << \"  Agent Device Type:            CPU\" << std::endl;\r\n    else if (HSA_DEVICE_TYPE_GPU == node.agent.device_type_)\r\n      std::cout << \"  Agent Device Type:           GPU\" << std::endl;\r\n  }\r\n  std::cout << std::endl;\r\n}\r\n\r\n// @brief: Print info on memory pools in system\r\nvoid RocmAsync::PrintPoolsList() {\r\n\r\n  size_t pool_count = pool_list_.size();\r\n  for (uint32_t jdx = 0; jdx < pool_count; jdx++) {\r\n    std::cout << std::endl;\r\n    std::cout << \"Memory Pool Idx:                          \"\r\n         << pool_list_.at(jdx).index_ << std::endl;\r\n    std::cout << \"  max allocable size in KB:               \"\r\n         << pool_list_.at(jdx).allocable_size_ / 1024 << std::endl;\r\n    std::cout << \"  segment id:                             \"\r\n         << pool_list_.at(jdx).segment_ << std::endl;\r\n    std::cout << \"  is kernarg:                             \"\r\n         << pool_list_.at(jdx).is_kernarg_ << std::endl;\r\n    std::cout << \"  is fine-grained:                        \"\r\n         << pool_list_.at(jdx).is_fine_grained_ << std::endl;\r\n    std::cout << \"  accessible to owner:                    \"\r\n         << pool_list_.at(jdx).owner_access_ << std::endl;\r\n    std::cout << \"  accessible to all by default:           \"\r\n         << pool_list_.at(jdx).access_to_all_ << std::endl;\r\n  }\r\n  std::cout << std::endl;\r\n\r\n}\r\n\r\n// @brief: Print the list of transactions that will be executed\r\nvoid RocmAsync::PrintTransList() {\r\n\r\n  size_t count = trans_list_.size();\r\n  for (uint32_t idx = 0; idx < count; idx++) {\r\n    async_trans_t trans = trans_list_.at(idx);\r\n    std::cout << std::endl;\r\n    std::cout << \"                 Transaction Id: \" << idx << std::endl;\r\n    std::cout << \"               Transaction Type: \" << trans.req_type_ << std::endl;\r\n    if ((trans.req_type_ == REQ_READ) || (trans.req_type_ == REQ_WRITE)) {\r\n      std::cout << \"Rocm Kernel used by Transaction: \" << trans.kernel.code_ << std::endl;\r\n      std::cout << \"Rocm Memory Pool Used by Kernel: \" << trans.kernel.pool_idx_ << std::endl;\r\n      std::cout << \"  Rocm Agent used for Execution: \" << trans.kernel.agent_idx_ << std::endl;\r\n    }\r\n    if ((trans.req_type_ == REQ_COPY_BIDIR) || (trans.req_type_ == REQ_COPY_UNIDIR)) {\r\n      std::cout << \"   Src Memory Pool used in Copy: \" << trans.copy.src_idx_ << std::endl;\r\n      std::cout << \"   Dst Memory Pool used in Copy: \" << trans.copy.dst_idx_ << std::endl;\r\n    }\r\n\r\n  }\r\n  std::cout << std::endl;\r\n}\r\n\r\n// @brief: Prints error message when a request to copy between\r\n// source pool and destination pool is not possible\r\nvoid RocmAsync::PrintCopyAccessError(uint32_t src_idx, uint32_t dst_idx) {\r\n\r\n  // Retrieve Roc runtime handles for Src memory pool and agents\r\n  uint32_t src_dev_idx = pool_list_[src_idx].agent_index_;\r\n  hsa_device_type_t src_dev_type = agent_list_[src_dev_idx].device_type_;\r\n    \r\n  // Retrieve Roc runtime handles for Dst memory pool and agents\r\n  uint32_t dst_dev_idx = pool_list_[dst_idx].agent_index_;\r\n  hsa_device_type_t dst_dev_type = agent_list_[dst_dev_idx].device_type_;\r\n\r\n  std::cout << std::endl;\r\n  std::cout << \"Index of Src Pool: \" << src_idx << std::endl;\r\n  std::cout << \"Index of Dst Pool: \" << dst_idx << std::endl;\r\n  std::cout << \"Index of Src Pool's Agent: \" << src_dev_idx << std::endl;\r\n  std::cout << \"Index of Dst Pool's Agent: \" << dst_dev_idx << std::endl;\r\n  std::cout << \"Device Type of Src Pool's Agent: \" << src_dev_type << std::endl;\r\n  std::cout << \"Device Type of Dst Pool's Agent: \" << dst_dev_type << std::endl;\r\n  std::cout << \"Rocm Agent hosting Src Pool cannot ACCESS Dst Pool\" << std::endl;\r\n  std::cout << std::endl;\r\n}\r\n\r\n// @brief: Prints error message when a request to read / write from\r\n// a pool by an agent is not possible\r\nvoid RocmAsync::PrintIOAccessError(uint32_t exec_idx, uint32_t pool_idx) {\r\n\r\n  // Retrieve device type of executing agent\r\n  hsa_device_type_t exec_dev_type = agent_list_[exec_idx].device_type_;\r\n    \r\n  // Retrieve device type of memory pool's agent\r\n  uint32_t pool_dev_idx = pool_list_[pool_idx].agent_index_;\r\n  hsa_device_type_t pool_dev_type = agent_list_[pool_dev_idx].device_type_;\r\n\r\n  std::cout << std::endl;\r\n  std::cout << \"Index of Executing Agent: \" << exec_idx << std::endl;\r\n  std::cout << \"Device Type of Executing Agent: \" << exec_dev_type << std::endl;\r\n  \r\n  std::cout << \"Index of Buffer's Memory Pool: \" << pool_idx << std::endl;\r\n  std::cout << \"Index of Buffer Memory Pool's Agent: \" << pool_dev_idx << std::endl;\r\n  std::cout << \"Device Type of Buffer Memory Pool's Agent: \" << pool_dev_type << std::endl;\r\n  std::cout << \"Rocm Agent executing Read / Write request cannot ACCESS Buffer's Memory Pool\" << std::endl;\r\n  std::cout << std::endl;\r\n}\r\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_report.cpp",
    "content": "#include \"common.hpp\"\r\n#include \"rocm_async.hpp\"\r\n\r\n#include <iomanip>\r\n#include <sstream>\r\n#include <algorithm>\r\n\r\nstatic void printRecord(uint32_t size, double avg_time,\r\n                        double bandwidth, double min_time,\r\n                        double peak_bandwidth) {\r\n\r\n  std::stringstream size_str;\r\n  size_str << size << \" MB\";\r\n\r\n  uint32_t format = 15;\r\n  std::cout.precision(3);\r\n  std::cout.width(format);\r\n  std::cout << size_str.str();\r\n  std::cout.width(format);\r\n  std::cout << (avg_time * 1e6);\r\n  std::cout.width(format);\r\n  std::cout << bandwidth;\r\n  std::cout.width(format);\r\n  std::cout << (min_time * 1e6);\r\n  std::cout.width(format);\r\n  std::cout << peak_bandwidth;\r\n  std::cout << std::endl;\r\n}\r\n\r\nstatic void printCopyBanner(uint32_t src_pool_id, uint32_t src_agent_type,\r\n                            uint32_t dst_pool_id, uint32_t dst_agent_type) {\r\n\r\n  std::stringstream src_type;\r\n  std::stringstream dst_type;\r\n  (src_agent_type == 0) ? src_type <<  \"Cpu\" : src_type << \"Gpu\";\r\n  (dst_agent_type == 0) ? dst_type <<  \"Cpu\" : dst_type << \"Gpu\";\r\n\r\n  std::cout << std::endl;\r\n  std::cout << \"================\";\r\n  std::cout << \"           Benchmark Result\";\r\n  std::cout << \"         ================\";\r\n  std::cout << std::endl;\r\n  std::cout << \"================\";\r\n  std::cout << \" Src Pool Id: \" << src_pool_id;\r\n  std::cout << \" Src Agent Type: \" << src_type.str();\r\n  std::cout << \" ================\";\r\n  std::cout << std::endl;\r\n  std::cout << \"================\";\r\n  std::cout << \" Dst Pool Id: \" << dst_pool_id;\r\n  std::cout << \" Dst Agent Type: \" << dst_type.str();\r\n  std::cout << \" ================\";\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n\r\n  uint32_t format = 15;\r\n  std::cout.setf(ios::left);\r\n  std::cout.width(format);\r\n  std::cout << \"Data Size\";\r\n  std::cout.width(format);\r\n  std::cout << \"Avg Time(us)\";\r\n  std::cout.width(format);\r\n  std::cout << \"Avg BW(GB/s)\";\r\n  std::cout.width(format);\r\n  std::cout << \"Min Time(us)\";\r\n  std::cout.width(format);\r\n  std::cout << \"Peak BW(GB/s)\";\r\n  std::cout << std::endl;\r\n}\r\n\r\ndouble RocmAsync::GetMinTime(std::vector<double>& vec) {\r\n\r\n  std::sort(vec.begin(), vec.end());\r\n  return vec.at(0);\r\n}\r\n\r\ndouble RocmAsync::GetMeanTime(std::vector<double>& vec) {\r\n\r\n  std::sort(vec.begin(), vec.end());\r\n  vec.erase(vec.begin());\r\n  vec.erase(vec.begin(), vec.begin() + num_iteration_ * 0.1);\r\n  vec.erase(vec.begin() + num_iteration_, vec.end());\r\n\r\n  double mean = 0.0;\r\n  int num = vec.size();\r\n  for (int it = 0; it < num; it++) {\r\n    mean += vec[it];\r\n  }\r\n  mean /= num;\r\n  return mean;\r\n}\r\n\r\nvoid RocmAsync::Display() const {\r\n\r\n  // Iterate through list of transactions and display its timing data\r\n  uint32_t trans_size = trans_list_.size();\r\n  if (trans_size == 0) {\r\n    std::cout << std::endl;\r\n    std::cout << \"  One or more of the requests wered filtered out \" << std::endl;\r\n    std::cout << \"      i.e. No Valid Requests were Made or Remain\" << std::endl;\r\n    std::cout << std::endl;\r\n    return;\r\n  }\r\n\r\n  if ((req_copy_all_bidir_ == REQ_COPY_ALL_BIDIR) ||\r\n      (req_copy_all_unidir_ == REQ_COPY_ALL_UNIDIR)) {\r\n    DisplayCopyTimeMatrix();\r\n    std::cout << std::endl;\r\n    return;\r\n  }\r\n\r\n  for (uint32_t idx = 0; idx < trans_size; idx++) {\r\n    async_trans_t trans = trans_list_[idx];\r\n    if ((trans.req_type_ == REQ_COPY_BIDIR) ||\r\n        (trans.req_type_ == REQ_COPY_UNIDIR)) {\r\n      DisplayCopyTime(trans);\r\n    }\r\n    if ((trans.req_type_ == REQ_READ) ||\r\n        (trans.req_type_ == REQ_WRITE)) {\r\n      DisplayIOTime(trans);\r\n    }\r\n  }\r\n  std::cout << std::endl;\r\n}\r\n\r\nvoid RocmAsync::DisplayIOTime(async_trans_t& trans) const {\r\n\r\n}\r\n\r\nvoid RocmAsync::DisplayCopyTime(async_trans_t& trans) const {\r\n  \r\n  // Print Benchmark Header\r\n  uint32_t src_idx = trans.copy.src_idx_;\r\n  uint32_t dst_idx = trans.copy.dst_idx_;\r\n  uint32_t src_dev_idx = pool_list_[src_idx].agent_index_;\r\n  hsa_device_type_t src_dev_type = agent_list_[src_dev_idx].device_type_;\r\n  uint32_t dst_dev_idx = pool_list_[dst_idx].agent_index_;\r\n  hsa_device_type_t dst_dev_type = agent_list_[dst_dev_idx].device_type_;\r\n  printCopyBanner(src_idx, src_dev_type, dst_idx, dst_dev_type);\r\n  \r\n  uint32_t size_len = size_list_.size();\r\n  for (uint32_t idx = 0; idx < size_len; idx++) {\r\n    printRecord(size_list_[idx], trans.avg_time_[idx],\r\n                trans.avg_bandwidth_[idx], trans.min_time_[idx],\r\n                trans.peak_bandwidth_[idx]);\r\n  }\r\n}\r\n\r\nvoid RocmAsync::DisplayCopyTimeMatrix() const {\r\n  \r\n  double* avg_matrix = new double[agent_index_ * agent_index_]();\r\n  double* peak_matrix = new double[agent_index_ * agent_index_]();\r\n  uint32_t trans_size = trans_list_.size();\r\n  for (uint32_t idx = 0; idx < trans_size; idx++) {\r\n    async_trans_t trans = trans_list_[idx];\r\n    uint32_t src_idx = trans.copy.src_idx_;\r\n    uint32_t dst_idx = trans.copy.dst_idx_;\r\n    uint32_t src_dev_idx = pool_list_[src_idx].agent_index_;\r\n    uint32_t dst_dev_idx = pool_list_[dst_idx].agent_index_;\r\n    avg_matrix[(src_dev_idx * agent_index_) + dst_dev_idx] = trans.avg_bandwidth_[0];\r\n    peak_matrix[(src_dev_idx * agent_index_) + dst_dev_idx] = trans.peak_bandwidth_[0];\r\n  }\r\n\r\n  uint32_t format = 12;\r\n  std::cout.setf(ios::left);\r\n\r\n  std::cout << std::endl;\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout.width(format);\r\n  if (req_copy_all_unidir_ == REQ_COPY_ALL_UNIDIR) {\r\n    std::cout << \"Peak Bandwidth For Unidirectional Copies GB/sec\";\r\n  } else {\r\n    std::cout << \"Peak Bandwidth For Bidirectional Copies GB/sec\";\r\n  }\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  for (uint32_t idx0 = 0; idx0 < agent_index_; idx0++) {\r\n    std::cout.width(format);\r\n    std::stringstream agent_id;\r\n    agent_id << \"Dev-\" << idx0;\r\n    std::cout << agent_id.str();\r\n  }\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n  for (uint32_t idx0 = 0; idx0 < agent_index_; idx0++) {\r\n    std::cout.width(format);\r\n    std::cout << \"\";\r\n    std::stringstream agent_id;\r\n    agent_id << \"Dev-\" << idx0;\r\n    std::cout.width(format);\r\n    std::cout << agent_id.str();\r\n    for (uint32_t idx1 = 0; idx1 < agent_index_; idx1++) {\r\n      std::cout.width(format);\r\n      std::cout << peak_matrix[(idx0 * agent_index_) + idx1];\r\n    }\r\n    std::cout << std::endl;\r\n    std::cout << std::endl;\r\n  }\r\n  std::cout << std::endl;\r\n\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout.width(format);\r\n  if (req_copy_all_unidir_ == REQ_COPY_ALL_UNIDIR) {\r\n    std::cout << \"Average Bandwidth For Unidirectional Copies GB/sec\";\r\n  } else {\r\n    std::cout << \"Average Bandwidth For Bidirectional Copies GB/sec\";\r\n  }\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  for (uint32_t idx0 = 0; idx0 < agent_index_; idx0++) {\r\n    std::cout.width(format);\r\n    std::stringstream agent_id;\r\n    agent_id << \"Dev-\" << idx0;\r\n    std::cout << agent_id.str();\r\n  }\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n  for (uint32_t idx0 = 0; idx0 < agent_index_; idx0++) {\r\n    std::cout.width(format);\r\n    std::cout << \"\";\r\n    std::stringstream agent_id;\r\n    agent_id << \"Dev-\" << idx0;\r\n    std::cout.width(format);\r\n    std::cout << agent_id.str();\r\n    for (uint32_t idx1 = 0; idx1 < agent_index_; idx1++) {\r\n      std::cout.width(format);\r\n      std::cout << avg_matrix[(idx0 * agent_index_) + idx1];\r\n    }\r\n    std::cout << std::endl;\r\n    std::cout << std::endl;\r\n  }\r\n  std::cout << std::endl;\r\n\r\n  /*\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout << \"@note-1: ZERO in Dev-i != Dev-j means DIRECT PATH doesn't exist\";\r\n  std::cout << std::endl;\r\n  std::cout.width(format);\r\n  std::cout << \"\";\r\n  std::cout << \"@note-2: ZERO in Dev-i == Dev-j means COPY operation is filtered out\";\r\n  std::cout << std::endl;\r\n  std::cout << std::endl;\r\n  */\r\n}\r\n\r\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_topology.cpp",
    "content": "#include \"common.hpp\"\n#include \"rocm_async.hpp\"\n\n// @brief: Helper method to iterate throught the memory pools of\n// an agent and discover its properties\nhsa_status_t MemPoolInfo(hsa_amd_memory_pool_t pool, void* data) {\n\n  hsa_status_t status;\n  RocmAsync* asyncDrvr = reinterpret_cast<RocmAsync*>(data);\n\n  // Query pools' segment, report only pools from global segment\n  hsa_amd_segment_t segment;\n  status = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n  ErrorCheck(status);\n  if (HSA_AMD_SEGMENT_GLOBAL != segment) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Determine if allocation is allowed in this pool\n  // Report only pools that allow an alloction by user\n  bool alloc = false;\n  status = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &alloc);\n  ErrorCheck(status);\n  if (alloc != true) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Query the pool size\n  size_t size = 0;\n  status = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_SIZE, &size);\n  ErrorCheck(status);\n\n  // Query the max allocatable size\n  size_t max_size = 0;\n  status = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE, &max_size);\n  ErrorCheck(status);\n\n  // Determine if the pools is accessible to all agents\n  bool access_to_all = false;\n  status = hsa_amd_memory_pool_get_info(pool,\n                HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL, &access_to_all);\n  ErrorCheck(status);\n\n  // Determine type of access to owner agent\n  hsa_amd_memory_pool_access_t owner_access;\n  hsa_agent_t agent = asyncDrvr->agent_list_.back().agent_;\n  status = hsa_amd_agent_memory_pool_get_info(agent, pool,\n                         HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &owner_access);\n  ErrorCheck(status);\n\n  // Determine if the pool is fine-grained or coarse-grained\n  uint32_t flag = 0;\n  status = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);\n  ErrorCheck(status);\n  bool is_kernarg = (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT & flag);\n  bool is_fine_grained = (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED & flag);\n\n  // Update the pool handle for system memory if kernarg is true\n  if (is_kernarg) {\n    asyncDrvr->sys_pool_ = pool;\n  }\n\n  // Create an instance of agent_pool_info and add it to the list\n  pool_info_t pool_info(agent, asyncDrvr->agent_index_, pool,\n                        segment, size, max_size, asyncDrvr->pool_index_,\n                        is_fine_grained, is_kernarg,\n                        access_to_all, owner_access);\n  asyncDrvr->pool_list_.push_back(pool_info);\n\n  // Create an agent_pool_infot and add it to its list\n  asyncDrvr->agent_pool_list_[asyncDrvr->agent_index_].pool_list.push_back(pool_info);\n  asyncDrvr->pool_index_++;\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// @brief: Helper method to iterate throught the agents of\n// a system and discover its properties\nhsa_status_t AgentInfo(hsa_agent_t agent, void* data) {\n\n  RocmAsync* asyncDrvr = reinterpret_cast<RocmAsync*>(data);\n\n  // Get the name of the agent\n  char agent_name[64];\n  hsa_status_t status;\n  status = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, agent_name);\n  ErrorCheck(status);\n\n  // Get device type\n  hsa_device_type_t device_type;\n  status = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n  ErrorCheck(status);\n\n  // Capture the handle of Cpu agent\n  if (device_type == HSA_DEVICE_TYPE_CPU) {\n    asyncDrvr->cpu_agent_ = agent;\n  }\n\n  asyncDrvr->agent_list_.push_back(agent_info(agent, asyncDrvr->agent_index_, device_type));\n\n  // Contruct an new agent_pool_info structure and add it to the list\n  agent_pool_info node;\n  node.agent = asyncDrvr->agent_list_.back();\n  asyncDrvr->agent_pool_list_.push_back(node);\n\n  status = hsa_amd_agent_iterate_memory_pools(agent, MemPoolInfo, asyncDrvr);\n  asyncDrvr->agent_index_++;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid RocmAsync::DiscoverTopology() {\n  err_ = hsa_iterate_agents(AgentInfo, this);\n}\n\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_trans.cpp",
    "content": "#include \"common.hpp\"\r\n#include \"rocm_async.hpp\"\r\n\r\nbool RocmAsync::BuildReadOrWriteTrans(uint32_t req_type,\r\n                                      vector<uint32_t>& in_list) {\r\n  \r\n  // Validate the list of pool-agent tuples\r\n  hsa_status_t status;\r\n  hsa_amd_memory_pool_access_t access;\r\n  uint32_t list_size = in_list.size();\r\n  for (uint32_t idx = 0; idx < list_size; idx+=2) {\r\n    \r\n    uint32_t pool_idx = in_list[idx];\r\n    uint32_t exec_idx = in_list[idx + 1];\r\n    \r\n    // Retrieve Roc runtime handles for memory pool and agent\r\n    hsa_agent_t exec_agent = agent_list_[exec_idx].agent_;\r\n    hsa_amd_memory_pool_t pool = pool_list_[pool_idx].pool_;\r\n  \r\n    // Determine agent can access the memory pool\r\n    status = hsa_amd_agent_memory_pool_get_info(exec_agent, pool,\r\n                           HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\r\n    ErrorCheck(status);\r\n    \r\n    // Determine if accessibility to agent is not denied\r\n    if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n      PrintIOAccessError(exec_idx, pool_idx);\r\n      return false;\r\n    }\r\n\r\n    // Agent has access, build an instance of transaction\r\n    // and add it to the list of transactions\r\n    async_trans_t trans(req_type);\r\n    trans.kernel.code_ = nullptr;\r\n    trans.kernel.pool_ = pool;\r\n    trans.kernel.pool_idx_ = pool_idx;\r\n    trans.kernel.agent_ = exec_agent;\r\n    trans.kernel.agent_idx_ = exec_idx;\r\n    trans_list_.push_back(trans);\r\n  }\r\n  return true;\r\n}\r\n\r\nbool RocmAsync::BuildReadTrans() {\r\n  return BuildReadOrWriteTrans(REQ_READ, read_list_);\r\n}\r\n\r\nbool RocmAsync::BuildWriteTrans() {\r\n  return BuildReadOrWriteTrans(REQ_WRITE, write_list_);\r\n}\r\n\r\nbool RocmAsync::BuildCopyTrans(uint32_t req_type,\r\n                               vector<uint32_t>& src_list,\r\n                               vector<uint32_t>& dst_list) {\r\n\r\n  uint32_t src_size = src_list.size();\r\n  uint32_t dst_size = dst_list.size();\r\n  \r\n  hsa_status_t status;\r\n  hsa_amd_memory_pool_access_t access;\r\n  for (uint32_t idx = 0; idx < src_size; idx++) {\r\n    \r\n    // Retrieve Roc runtime handles for Src memory pool and agents\r\n    uint32_t src_idx = src_list[idx];\r\n    hsa_agent_t src_agent = pool_list_[src_idx].owner_agent_;\r\n    hsa_amd_memory_pool_t src_pool = pool_list_[src_idx].pool_;\r\n    uint32_t src_dev_idx = pool_list_[src_idx].agent_index_;\r\n    hsa_device_type_t src_dev_type = agent_list_[src_dev_idx].device_type_;\r\n\r\n    // Determine if dst pool is fine grained, if so filter out\r\n    // the transaction\r\n    if ((req_type == REQ_COPY_ALL_BIDIR) ||\r\n        (req_type == REQ_COPY_ALL_UNIDIR)) {\r\n      bool src_fine_grained =  pool_list_[src_idx].is_fine_grained_;\r\n      if (src_fine_grained) {\r\n        continue;\r\n      }\r\n    }\r\n\r\n    for (uint32_t jdx = 0; jdx < dst_size; jdx++) {\r\n    \r\n      // Retrieve Roc runtime handles for Dst memory pool and agents\r\n      uint32_t dst_idx = dst_list[jdx];\r\n      hsa_agent_t dst_agent = pool_list_[dst_idx].owner_agent_;\r\n      hsa_amd_memory_pool_t dst_pool = pool_list_[dst_idx].pool_;\r\n      uint32_t dst_dev_idx = pool_list_[dst_idx].agent_index_;\r\n      hsa_device_type_t dst_dev_type = agent_list_[dst_dev_idx].device_type_;\r\n\r\n      // Determine if dst pool is fine grained, if so filter out\r\n      // the transaction\r\n      if ((req_type == REQ_COPY_ALL_BIDIR) ||\r\n          (req_type == REQ_COPY_ALL_UNIDIR)) {\r\n        bool dst_fine_grained =  pool_list_[dst_idx].is_fine_grained_;\r\n        if (dst_fine_grained) {\r\n          continue;\r\n        }\r\n      }\r\n\r\n      // Filter out transaction when Src & Dst pools belong to Cpu\r\n      /*\r\n      if ((src_dev_type == HSA_DEVICE_TYPE_CPU) &&\r\n          (dst_dev_type == HSA_DEVICE_TYPE_CPU)) {\r\n        continue;\r\n      }\r\n      */\r\n\r\n      // Filter out transaction with same Src & Dst pools\r\n      /*\r\n      if (src_idx == dst_idx) {\r\n        continue;\r\n      }\r\n      */\r\n      \r\n      // Determine if accessibility to src pool for dst agent is not denied\r\n      status = hsa_amd_agent_memory_pool_get_info(dst_agent, src_pool,\r\n                             HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\r\n      ErrorCheck(status);\r\n      if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n        PrintCopyAccessError(src_idx, dst_idx);\r\n        return false;\r\n      }\r\n\r\n      // Determine if accessibility to dst pool for src agent is not denied\r\n      status = hsa_amd_agent_memory_pool_get_info(src_agent, dst_pool,\r\n                             HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\r\n      ErrorCheck(status);\r\n      if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n        return false;\r\n      }\r\n\r\n      // Agents have access, build an instance of transaction\r\n      // and add it to the list of transactions\r\n      async_trans_t trans(req_type);\r\n      trans.copy.src_idx_ = src_idx;\r\n      trans.copy.dst_idx_ = dst_idx;\r\n      trans.copy.src_pool_ = src_pool;\r\n      trans.copy.dst_pool_ = dst_pool;\r\n      trans.copy.bidir_ = ((req_type == REQ_COPY_BIDIR) ||\r\n                           (req_type == REQ_COPY_ALL_BIDIR));\r\n      trans.copy.uses_gpu_ = ((src_dev_type == HSA_DEVICE_TYPE_GPU) ||\r\n                              (dst_dev_type == HSA_DEVICE_TYPE_GPU));\r\n      trans_list_.push_back(trans);\r\n    }\r\n  }\r\n  return true;\r\n}\r\n\r\nbool RocmAsync::BuildBidirCopyTrans() {\r\n  return BuildCopyTrans(REQ_COPY_BIDIR, bidir_list_, bidir_list_);\r\n}\r\n\r\nbool RocmAsync::BuildUnidirCopyTrans() {\r\n  return BuildCopyTrans(REQ_COPY_UNIDIR, src_list_, dst_list_);\r\n}\r\n\r\nbool RocmAsync::BuildAllPoolsBidirCopyTrans() {\r\n  return BuildCopyTrans(REQ_COPY_ALL_BIDIR, bidir_list_, bidir_list_);\r\n}\r\n\r\nbool RocmAsync::BuildAllPoolsUnidirCopyTrans() {\r\n  return BuildCopyTrans(REQ_COPY_ALL_UNIDIR, src_list_, dst_list_);\r\n}\r\n\r\n// @brief: Builds a list of transaction per user request\r\nbool RocmAsync::BuildTransList() {\r\n  \r\n  // Build list of Read transactions per user request\r\n  bool status = false;\r\n  if (req_read_ == REQ_READ) {\r\n    status = BuildReadTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // Build list of Write transactions per user request\r\n  status = false;\r\n  if (req_write_ == REQ_WRITE) {\r\n    status = BuildWriteTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // Build list of Bidirectional Copy transactions per user request\r\n  status = false;\r\n  if (req_copy_bidir_ == REQ_COPY_BIDIR) {\r\n    status = BuildBidirCopyTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // Build list of Unidirectional Copy transactions per user request\r\n  status = false;\r\n  if (req_copy_unidir_ == REQ_COPY_UNIDIR) {\r\n    status = BuildUnidirCopyTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // Build list of All Bidir Copy transactions per user request\r\n  status = false;\r\n  if (req_copy_all_bidir_ == REQ_COPY_ALL_BIDIR) {\r\n    status = BuildAllPoolsBidirCopyTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // Build list of All Unidir Copy transactions per user request\r\n  status = false;\r\n  if (req_copy_all_unidir_ == REQ_COPY_ALL_UNIDIR) {\r\n    status = BuildAllPoolsUnidirCopyTrans();\r\n    if (status == false) {\r\n      return status;\r\n    }\r\n  }\r\n\r\n  // All of the transaction are built up\r\n  return true;\r\n}\r\n\r\nvoid RocmAsync::ComputeCopyTime(async_trans_t& trans) {\r\n\r\n  // Get the frequency of Gpu Timestamping\r\n  uint64_t sys_freq = 0;\r\n  hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sys_freq);\r\n  \r\n  double avg_time = 0;\r\n  double min_time = 0;\r\n  double bandwidth = 0;\r\n  uint32_t data_size = 0;\r\n  double peak_bandwidth = 0;\r\n  uint32_t size_len = size_list_.size();\r\n  for (uint32_t idx = 0; idx < size_len; idx++) {\r\n    \r\n    // Adjust size of data involved in copy\r\n    data_size = size_list_[idx];\r\n    if (trans.copy.bidir_ == true) {\r\n      data_size += size_list_[idx];\r\n    }\r\n    data_size = data_size * 1024 * 1024;\r\n\r\n    // Copy operation does not involve a Gpu device\r\n    if (trans.copy.uses_gpu_ != true) {\r\n      avg_time = trans.cpu_avg_time_[idx];\r\n      min_time = trans.cpu_min_time_[idx];\r\n      bandwidth = (double)data_size / avg_time / 1000 / 1000 / 1000;\r\n      peak_bandwidth = (double)data_size / min_time / 1000 / 1000 / 1000;\r\n    } else {\r\n      avg_time = trans.gpu_avg_time_[idx] / sys_freq;\r\n      min_time = trans.gpu_min_time_[idx] / sys_freq;\r\n      bandwidth = (double)data_size / avg_time / 1000 / 1000 / 1000;\r\n      peak_bandwidth = (double)data_size / min_time / 1000 / 1000 / 1000;\r\n    }\r\n\r\n    trans.min_time_.push_back(min_time);\r\n    trans.avg_time_.push_back(avg_time);\r\n    trans.avg_bandwidth_.push_back(bandwidth);\r\n    trans.peak_bandwidth_.push_back(peak_bandwidth);\r\n  }\r\n}\r\n\r\n"
  },
  {
    "path": "rocrtst/samples/rocm_async/rocm_async_validate.cpp",
    "content": "\n#include \"common.hpp\"\n#include \"rocm_async.hpp\"\n\n#include <assert.h>\n#include <algorithm>\n#include <unistd.h>\n#include <cctype>\n#include <sstream>\n\nbool RocmAsync::PoolIsPresent(vector<uint32_t>& in_list) {\n  \n  bool is_present;\n  uint32_t idx1 = 0;\n  uint32_t idx2 = 0;\n  uint32_t count = in_list.size();\n  uint32_t pool_count = pool_list_.size();\n  for (idx1 = 0; idx1 < count; idx1++) {\n    is_present = false;\n    for (idx2 = 0; idx2 < pool_count; idx2++) {\n      if (in_list[idx1] == pool_list_[idx2].index_) {\n        is_present = true;\n        break;\n      }\n    }\n    if (is_present == false) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nbool RocmAsync::PoolIsDuplicated(vector<uint32_t>& in_list) {\n  \n  uint32_t idx1 = 0;\n  uint32_t idx2 = 0;\n  uint32_t count = in_list.size();\n  for (idx1 = 0; idx1 < count; idx1++) {\n    for (idx2 = 0; idx2 < count; idx2++) {\n      if ((in_list[idx1] == in_list[idx2]) && (idx1 != idx2)){\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nbool RocmAsync::ValidateReadOrWriteReq(vector<uint32_t>& in_list) {\n\n  // Determine read / write request is even\n  // Request is specified as a list of memory\n  // pool, agent tuples - first element identifies\n  // memory pool while the second element denotes\n  // an agent\n  uint32_t list_size = in_list.size();\n  if ((list_size % 2) != 0) {\n    return false;\n  }\n  \n  // Validate the list of pool-agent tuples\n  for (uint32_t idx = 0; idx < list_size; idx+=2) {\n    uint32_t pool_idx = in_list[idx];\n    uint32_t exec_idx = in_list[idx + 1];\n    // Determine the pool and agent exist in system\n    if ((pool_idx >= pool_index_) ||\n        (exec_idx >= agent_index_)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nbool RocmAsync::ValidateReadReq() {\n  return ValidateReadOrWriteReq(read_list_);\n}\n\nbool RocmAsync::ValidateWriteReq() {\n  return ValidateReadOrWriteReq(write_list_);\n}\n\nbool RocmAsync::ValidateCopyReq(vector<uint32_t>& in_list) {\n  \n  // Determine pool list length is valid\n  uint32_t count = in_list.size();\n  uint32_t pool_count = pool_list_.size();\n  if (count > pool_count) {\n    return false;\n  }\n  \n  // Determine no pool is duplicated\n  bool status = PoolIsDuplicated(in_list);\n  if (status == false) {\n    return false;\n  }\n  \n  // Determine every pool is present in system\n  return PoolIsPresent(in_list);\n}\n\nbool RocmAsync::ValidateBidirCopyReq() {\n  return ValidateCopyReq(bidir_list_);\n}\n\nbool RocmAsync::ValidateUnidirCopyReq() {\n  return ((ValidateCopyReq(src_list_)) && (ValidateCopyReq(dst_list_)));\n}\n\nbool RocmAsync::ValidateArguments() {\n  \n  // Determine if user has requested a READ\n  // operation and gave valid inputs\n  bool status = false;\n  if (req_read_ == REQ_READ) {\n    status = ValidateReadReq();\n    if (status == false) {\n      return status;\n    }\n  }\n\n  // Determine if user has requested a WRITE\n  // operation and gave valid inputs\n  status = false;\n  if (req_write_ == REQ_WRITE) {\n    status = ValidateWriteReq();\n    if (status == false) {\n      return status;\n    }\n  }\n\n  // Determine if user has requested a Copy\n  // operation that is bidirectional and gave\n  // valid inputs. Same validation is applied\n  // for all-to-all unidirectional copy operation\n  status = false;\n  if ((req_copy_bidir_ == REQ_COPY_BIDIR) ||\n      (req_copy_all_bidir_ == REQ_COPY_ALL_BIDIR)) {\n    status = ValidateBidirCopyReq();\n    if (status == false) {\n      return status;\n    }\n  }\n\n  // Determine if user has requested a Copy\n  // operation that is unidirectional and gave\n  // valid inputs. Same validation is applied\n  // for all-to-all bidirectional copy operation\n  status = false;\n  if ((req_copy_unidir_ == REQ_COPY_UNIDIR) ||\n      (req_copy_all_unidir_ == REQ_COPY_ALL_UNIDIR)) {\n    status = ValidateUnidirCopyReq();\n    if (status == false) {\n      return status;\n    }\n  }\n\n  // All of the request are well formed\n  return true;\n}\n"
  },
  {
    "path": "rocrtst/samples/rocrinfo/rocrinfo.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#include <stdio.h>\n#include <vector>\n#include <string>\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    printf(\"hsa api call failure at line %d, file: %s. Call returned %d\\n\", \\\n                                                   __LINE__, __FILE__, err); \\\n    return (err); \\\n  } \\\n}\n\n// This structure holds system information acquired through hsa info related\n// calls, and is later used for reference when displaying the information.\nstruct system_info_t {\n    uint16_t major, minor;\n    uint64_t timestamp_frequency = 0;\n    uint64_t max_wait = 0;\n    hsa_endianness_t endianness;\n    hsa_machine_model_t machine_model;\n};\n\n// This structure holds agent information acquired through hsa info related\n// calls, and is later used for reference when displaying the information.\nstruct agent_info_t {\n  char name[64];\n  char vendor_name[64];\n  hsa_agent_feature_t agent_feature;\n  hsa_profile_t agent_profile;\n  hsa_default_float_rounding_mode_t float_rounding_mode;\n  uint32_t max_queue;\n  uint32_t queue_min_size;\n  uint32_t queue_max_size;\n  hsa_queue_type_t queue_type;\n  uint32_t node;\n  hsa_device_type_t device_type;\n  uint32_t cache_size[4];\n  uint32_t chip_id;\n  uint32_t cacheline_size;\n  uint32_t max_clock_freq;\n  uint32_t compute_unit;\n  uint32_t wavefront_size;\n  uint32_t workgroup_max_size;\n  uint32_t grid_max_size;\n  uint32_t fbarrier_max_size;\n  uint32_t waves_per_cu;\n  hsa_isa_t agent_isa;\n  hsa_dim3_t grid_max_dim;\n  uint16_t workgroup_max_dim[3];\n  uint16_t bdf_id;\n  bool fast_f16;\n};\n\n// This structure holds memory pool information acquired through hsa info\n// related calls, and is later used for reference when displaying the\n// information.\nstruct pool_info_t {\n    uint32_t segment;\n    size_t pool_size;\n    bool alloc_allowed;\n    size_t alloc_granule;\n    size_t alloc_recommended_granule;\n    size_t pool_alloc_alignment;\n    bool pl_access;\n    uint32_t global_flag;\n};\n\n// This structure holds ISA information acquired through hsa info\n// related calls, and is later used for reference when displaying the\n// information.\nstruct isa_info_t {\n    char *name_str;\n    uint32_t workgroup_max_size;\n    hsa_dim3_t grid_max_dim;\n    uint64_t grid_max_size;\n    uint32_t fbarrier_max_size;\n    uint16_t workgroup_max_dim[3];\n    bool def_rounding_modes[3];\n    bool base_rounding_modes[3];\n    bool mach_models[2];\n    bool profiles[2];\n    bool fast_f16;\n};\n\n// This structure holds cache information acquired through hsa info\n// related calls, and is later used for reference when displaying the\n// information.\nstruct cache_info_t {\n    char *name_str;\n    uint8_t level;\n    uint32_t size;\n};\n\nstatic const uint32_t kLabelFieldSize = 25;\nstatic const uint32_t kValueFieldSize = 35;\nstatic const uint32_t kIndentSize = 2;\n\nstatic void printLabelInt(char const *l, int d, uint32_t indent_lvl = 0) {\n  std::string ind(kIndentSize * indent_lvl, ' ');\n\n  printf(\"%s%-*s%-*u\\n\", ind.c_str(), kLabelFieldSize, l, kValueFieldSize, d);\n}\nstatic void printLabelStr(char const *l, char const *s,\n                                                    uint32_t indent_lvl = 0) {\n  std::string ind(kIndentSize * indent_lvl, ' ');\n  printf(\"%s%-*s%-*s\\n\", ind.c_str(), kLabelFieldSize, l, kValueFieldSize, s);\n}\nstatic void printLabel(char const *l, bool newline = false,\n                                                    uint32_t indent_lvl = 0) {\n  std::string ind(kIndentSize * indent_lvl, ' ');\n\n  printf(\"%s%-*s\", ind.c_str(), kLabelFieldSize, l);\n\n  if (newline) {\n    printf(\"\\n\");\n  }\n}\nstatic void printValueStr(char const *s, bool newline = true) {\n  printf(\"%-*s\\n\", kValueFieldSize, s);\n}\n\n// Acquire system information\nstatic hsa_status_t AcquireSystemInfo(system_info_t *sys_info) {\n  hsa_status_t err;\n\n  // Get Major and Minor version of runtime\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_VERSION_MAJOR, &sys_info->major);\n  RET_IF_HSA_ERR(err);\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_VERSION_MINOR, &sys_info->minor);\n  RET_IF_HSA_ERR(err);\n\n  // Get timestamp frequency\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY,\n                                              &sys_info->timestamp_frequency);\n  RET_IF_HSA_ERR(err);\n\n  // Get maximum duration of a signal wait operation\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_SIGNAL_MAX_WAIT,\n                                                         &sys_info->max_wait);\n  RET_IF_HSA_ERR(err);\n\n  // Get Endianness of the system\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_ENDIANNESS, &sys_info->endianness);\n  RET_IF_HSA_ERR(err);\n\n  // Get machine model info\n  err = hsa_system_get_info(HSA_SYSTEM_INFO_MACHINE_MODEL,\n                                                     &sys_info->machine_model);\n  RET_IF_HSA_ERR(err);\n  return err;\n}\n\nstatic void DisplaySystemInfo(system_info_t const *sys_info) {\n  printLabel(\"Runtime Version:\");\n  printf(\"%d.%d\\n\", sys_info->major, sys_info->minor);\n  printLabel(\"System Timestamp Freq.:\");\n  printf(\"%fMHz\\n\", sys_info->timestamp_frequency / 1e6);\n  printLabel(\"Sig. Max Wait Duration:\");\n  printf(\"%lu (number of timestamp)\\n\", sys_info->max_wait);\n\n  printLabel(\"Machine Model:\");\n  if (HSA_MACHINE_MODEL_SMALL == sys_info->machine_model) {\n    printValueStr(\"SMALL\");\n  } else if (HSA_MACHINE_MODEL_LARGE == sys_info->machine_model) {\n    printValueStr(\"LARGE\");\n  }\n\n  printLabel(\"System Endianness:\");\n  if (HSA_ENDIANNESS_LITTLE == sys_info->endianness) {\n    printValueStr(\"LITTLE\");\n  } else if (HSA_ENDIANNESS_BIG == sys_info->endianness) {\n    printValueStr(\"BIG\");\n  }\n  printf(\"\\n\");\n}\n\nstatic hsa_status_t\nAcquireAgentInfo(hsa_agent_t agent, agent_info_t *agent_i) {\n  hsa_status_t err;\n  // Get agent name and vendor\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, agent_i->name);\n  RET_IF_HSA_ERR(err);\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_VENDOR_NAME,\n                                                       &agent_i->vendor_name);\n  RET_IF_HSA_ERR(err);\n\n  // Get agent feature\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_FEATURE,\n                                                     &agent_i->agent_feature);\n  RET_IF_HSA_ERR(err);\n\n  // Get profile supported by the agent\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_PROFILE,\n                                                     &agent_i->agent_profile);\n  RET_IF_HSA_ERR(err);\n\n  // Get floating-point rounding mode\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE,\n                                               &agent_i->float_rounding_mode);\n  RET_IF_HSA_ERR(err);\n\n  // Get max number of queue\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUES_MAX,\n                                                         &agent_i->max_queue);\n  RET_IF_HSA_ERR(err);\n\n  // Get queue min size\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MIN_SIZE,\n                                                    &agent_i->queue_min_size);\n  RET_IF_HSA_ERR(err);\n\n  // Get queue max size\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MAX_SIZE,\n                                                    &agent_i->queue_max_size);\n  RET_IF_HSA_ERR(err);\n\n  // Get queue type\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_TYPE,\n                                                        &agent_i->queue_type);\n  RET_IF_HSA_ERR(err);\n\n  // Get agent node\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NODE, &agent_i->node);\n  RET_IF_HSA_ERR(err);\n\n  // Get device type\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE,\n                                                       &agent_i->device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (HSA_DEVICE_TYPE_GPU == agent_i->device_type) {\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_ISA, &agent_i->agent_isa);\n    RET_IF_HSA_ERR(err);\n  }\n\n  // Get cache size\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_CACHE_SIZE,\n                                                        agent_i->cache_size);\n  RET_IF_HSA_ERR(err);\n\n  // Get chip id\n  err = hsa_agent_get_info(agent,\n                           (hsa_agent_info_t) HSA_AMD_AGENT_INFO_CHIP_ID,\n                                                           &agent_i->chip_id);\n  RET_IF_HSA_ERR(err);\n\n  // Get cacheline size\n  err = hsa_agent_get_info(agent,\n                       (hsa_agent_info_t) HSA_AMD_AGENT_INFO_CACHELINE_SIZE,\n                                                    &agent_i->cacheline_size);\n  RET_IF_HSA_ERR(err);\n\n  // Get Max clock frequency\n  err = hsa_agent_get_info(agent,\n                  (hsa_agent_info_t) HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY,\n                                                    &agent_i->max_clock_freq);\n  RET_IF_HSA_ERR(err);\n\n  // Get Agent BDFID\n  err = hsa_agent_get_info(agent,\n                (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &agent_i->bdf_id);\n  RET_IF_HSA_ERR(err);\n\n  // Get number of Compute Unit\n  err = hsa_agent_get_info(agent,\n                   (hsa_agent_info_t) HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT,\n                                                      &agent_i->compute_unit);\n  RET_IF_HSA_ERR(err);\n\n  // Check if the agent is kernel agent\n  if (agent_i->agent_feature & HSA_AGENT_FEATURE_KERNEL_DISPATCH) {\n    // Get flaf of fast_f16 operation\n    err = hsa_agent_get_info(agent,\n                       HSA_AGENT_INFO_FAST_F16_OPERATION, &agent_i->fast_f16);\n    RET_IF_HSA_ERR(err);\n\n    // Get wavefront size\n    err = hsa_agent_get_info(agent,\n                     HSA_AGENT_INFO_WAVEFRONT_SIZE, &agent_i->wavefront_size);\n    RET_IF_HSA_ERR(err);\n\n    // Get max total number of work-items in a workgroup\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_WORKGROUP_MAX_SIZE,\n                                                &agent_i->workgroup_max_size);\n    RET_IF_HSA_ERR(err);\n\n    // Get max number of work-items of each dimension of a work-group\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_WORKGROUP_MAX_DIM,\n                                                 &agent_i->workgroup_max_dim);\n    RET_IF_HSA_ERR(err);\n\n    // Get max number of a grid per dimension\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_GRID_MAX_DIM,\n                                                      &agent_i->grid_max_dim);\n    RET_IF_HSA_ERR(err);\n\n    // Get max total number of work-items in a grid\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_GRID_MAX_SIZE,\n                                                     &agent_i->grid_max_size);\n    RET_IF_HSA_ERR(err);\n\n    // Get max number of fbarriers per work group\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_FBARRIER_MAX_SIZE,\n                                                 &agent_i->fbarrier_max_size);\n    RET_IF_HSA_ERR(err);\n\n    err = hsa_agent_get_info(agent,\n                    (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU,\n                                                      &agent_i->waves_per_cu);\n    RET_IF_HSA_ERR(err);\n  }\n  return err;\n}\n\nstatic void DisplayAgentInfo(agent_info_t *agent_i) {\n  printLabelStr(\"Name:\", agent_i->name, 1);\n  printLabelStr(\"Vendor Name:\", agent_i->vendor_name, 1);\n\n  printLabel(\"Feature:\", false, 1);\n  if (agent_i->agent_feature & HSA_AGENT_FEATURE_KERNEL_DISPATCH\n      && agent_i->agent_feature & HSA_AGENT_FEATURE_AGENT_DISPATCH) {\n    printValueStr(\"KERNEL_DISPATCH & AGENT_DISPATCH\");\n  } else if (agent_i->agent_feature & HSA_AGENT_FEATURE_KERNEL_DISPATCH) {\n    printValueStr(\"KERNEL_DISPATCH\");\n  } else if (agent_i->agent_feature & HSA_AGENT_FEATURE_AGENT_DISPATCH) {\n    printValueStr(\"AGENT_DISPATCH\");\n  } else {\n    printValueStr(\"None specified\");\n  }\n\n  printLabel(\"Profile:\", false, 1);\n  if (HSA_PROFILE_BASE == agent_i->agent_profile) {\n    printValueStr(\"BASE_PROFILE\");\n  } else if (HSA_PROFILE_FULL == agent_i->agent_profile) {\n    printValueStr(\"FULL_PROFILE\");\n  } else {\n    printValueStr(\"Unknown\");\n  }\n\n  printLabel(\"Float Round Mode:\", false, 1);\n  if (HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO == agent_i->float_rounding_mode) {\n    printValueStr(\"ZERO\");\n  } else if (HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR ==\n                                               agent_i->float_rounding_mode) {\n    printValueStr(\"NEAR\");\n  } else {\n    printValueStr(\"Not Supported\");\n  }\n\n  printLabelInt(\"Max Queue Number:\", agent_i->max_queue, 1);\n  printLabelInt(\"Queue Min Size:\", agent_i->queue_min_size, 1);\n  printLabelInt(\"Queue Max Size:\", agent_i->queue_max_size, 1);\n\n  if (HSA_QUEUE_TYPE_MULTI == agent_i->queue_type) {\n    printLabelStr(\"Queue Type:\", \"MULTI\", 1);\n  } else if (HSA_QUEUE_TYPE_SINGLE == agent_i->queue_type) {\n    printLabelStr(\"Queue Type:\", \"SINGLE\", 1);\n  } else {\n    printLabelStr(\"Queue Type:\", \"Unknown\", 1);\n  }\n\n  printLabelInt(\"Node:\", agent_i->node, 1);\n\n  printLabel(\"Device Type:\", false, 1);\n  if (HSA_DEVICE_TYPE_CPU == agent_i->device_type) {\n    printValueStr(\"CPU\");\n  } else if (HSA_DEVICE_TYPE_GPU == agent_i->device_type) {\n    printValueStr(\"GPU\");\n  } else {\n    printValueStr(\"DSP\");\n  }\n\n  printLabel(\"Cache Info:\", true, 1);\n\n  for (int i = 0; i < 4; i++) {\n    if (agent_i->cache_size[i]) {\n      std::string tmp_str(\"L\");\n      tmp_str += std::to_string(i+1);\n      tmp_str += \":\";\n      printLabel(tmp_str.c_str(), false, 2);\n\n      tmp_str = std::to_string(agent_i->cache_size[i]/1024);\n      tmp_str += \"KB\";\n      printValueStr(tmp_str.c_str());\n    }\n  }\n\n  printLabelInt(\"Chip ID:\", agent_i->chip_id, 1);\n  printLabelInt(\"Cacheline Size:\", agent_i->cacheline_size, 1);\n  printLabelInt(\"Max Clock Frequency (MHz):\", agent_i->max_clock_freq, 1);\n  printLabelInt(\"BDFID:\", agent_i->bdf_id, 1);\n  printLabelInt(\"Compute Unit:\", agent_i->compute_unit, 1);\n\n  printLabel(\"Features:\", false, 1);\n  if (agent_i->agent_feature & HSA_AGENT_FEATURE_KERNEL_DISPATCH) {\n    printf(\"%s\", \"KERNEL_DISPATCH \");\n  }\n  if (agent_i->agent_feature & HSA_AGENT_FEATURE_AGENT_DISPATCH) {\n    printf(\"%s\", \"AGENT_DISPATCH\");\n  }\n  if (agent_i->agent_feature == 0) {\n    printf(\"None\");\n  }\n  printf(\"\\n\");\n\n  if (agent_i->agent_feature & HSA_AGENT_FEATURE_KERNEL_DISPATCH) {\n    printLabelStr(\"Fast F16 Operation:\", agent_i->fast_f16 ? \"TRUE\":\"FALSE\", 1);\n\n    printLabelInt(\"Wavefront Size:\", agent_i->wavefront_size, 1);\n    printLabelInt(\"Workgroup Max Size:\", agent_i->workgroup_max_size, 1);\n\n    printLabel(\"Workgroup Max Size Per Dimension:\", true, 1);\n    std::string dim;\n    for (int i = 0; i < 3; i++) {\n      dim = \"Dim[\" + std::to_string(i) + \"]:\";\n      printLabelInt(dim.c_str(),\n              reinterpret_cast<uint32_t*>(&agent_i->workgroup_max_dim)[i], 2);\n    }\n    printLabelInt(\"Grid Max Size:\", agent_i->grid_max_size, 1);\n    printLabelInt(\"Waves Per CU:\", agent_i->waves_per_cu, 1);\n    printLabelInt(\"Max Work-item Per CU:\",\n                            agent_i->wavefront_size*agent_i->waves_per_cu, 1);\n    printLabel(\"Grid Max Size per Dimension:\", true, 1);\n    for (int i = 0; i < 3; i++) {\n      dim = \"Dim[\" + std::to_string(i) + \"]:\";\n      printLabelInt(dim.c_str(),\n                 reinterpret_cast<uint32_t*>(&agent_i->grid_max_dim)[i], 2);\n    }\n\n    printLabelInt(\"Max number Of fbarriers Per Workgroup:\",\n                                             agent_i->fbarrier_max_size, 1);\n  }\n}\n\nstatic hsa_status_t AcquirePoolInfo(hsa_amd_memory_pool_t pool,\n                                                        pool_info_t *pool_i) {\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                  HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &pool_i->global_flag);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                                             &pool_i->segment);\n  RET_IF_HSA_ERR(err);\n\n  // Get the size of the POOL\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE,\n                                                          &pool_i->pool_size);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n             HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,\n                                                      &pool_i->alloc_allowed);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n             HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE,\n                                                      &pool_i->alloc_granule);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                           HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT,\n                                               &pool_i->pool_alloc_alignment);\n  RET_IF_HSA_ERR(err);\n\n  err =\n      hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE,\n                                   &pool_i->alloc_recommended_granule);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_amd_memory_pool_get_info(pool,\n                      HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL,\n                                                          &pool_i->pl_access);\n  RET_IF_HSA_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic void MakeGlobalFlagsString(uint32_t global_flag, std::string* out_str) {\n  *out_str = \"\";\n\n  std::vector<std::string> flags;\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT & global_flag) {\n    flags.push_back(\"KERNARG\");\n  }\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED & global_flag) {\n    flags.push_back(\"FINE GRAINED\");\n  }\n\n  if (HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED & global_flag) {\n    flags.push_back(\"COARSE GRAINED\");\n  }\n\n  if (flags.size() > 0) {\n    *out_str += flags[0];\n  }\n\n  for (size_t i = 1; i < flags.size(); i++) {\n    *out_str += \", \" + flags[i];\n  }\n}\n\nstatic void DumpSegment(pool_info_t *pool_i, uint32_t ind_lvl) {\n  std::string seg_str;\n  std::string tmp_str;\n\n  printLabel(\"Segment:\", false, ind_lvl);\n\n  switch (pool_i->segment) {\n    case HSA_AMD_SEGMENT_GLOBAL:\n      MakeGlobalFlagsString(pool_i->global_flag, &tmp_str);\n      seg_str += \"GLOBAL; FLAGS: \" + tmp_str;\n      break;\n\n    case HSA_AMD_SEGMENT_READONLY:\n      seg_str += \"READONLY\";\n      break;\n\n    case HSA_AMD_SEGMENT_PRIVATE:\n      seg_str += \"PRIVATE\";\n      break;\n\n    case HSA_AMD_SEGMENT_GROUP:\n      seg_str += \"GROUP\";\n      break;\n\n    default:\n      printf(\"Not Supported\\n\");\n      break;\n  }\n  printValueStr(seg_str.c_str());\n}\n\nstatic void DisplayPoolInfo(pool_info_t *pool_i, uint32_t indent) {\n  DumpSegment(pool_i, indent);\n\n  std::string sz_str = std::to_string(pool_i->pool_size/1024) + \"KB\";\n  printLabelStr(\"Size:\", sz_str.c_str(), indent);\n  printLabelStr(\"Allocatable:\", (pool_i->alloc_allowed ? \"TRUE\" : \"FALSE\"),\n                                                                      indent);\n  std::string gr_str = std::to_string(pool_i->alloc_granule/1024)+\"KB\";\n  printLabelStr(\"Alloc Granule:\", gr_str.c_str(), indent);\n\n  std::string al_str = std::to_string(pool_i->pool_alloc_alignment/1024)+\"KB\";\n  printLabelStr(\"Alloc Alignment:\", al_str.c_str(), indent);\n\n  printLabelStr(\"Acessible by all:\", (pool_i->pl_access ? \"TRUE\" : \"FALSE\"),\n                                                                      indent);\n}\n\nstatic hsa_status_t\nAcquireAndDisplayMemPoolInfo(const hsa_amd_memory_pool_t pool,\n                                                            uint32_t indent) {\n  hsa_status_t err;\n  pool_info_t pool_i;\n\n  err = AcquirePoolInfo(pool, &pool_i);\n  RET_IF_HSA_ERR(err);\n\n  DisplayPoolInfo(&pool_i, 3);\n\n  return err;\n}\n\nstatic hsa_status_t get_pool_info(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_status_t err;\n  int* p_int = reinterpret_cast<int*>(data);\n  (*p_int)++;\n\n  std::string pool_str(\"Pool \");\n  pool_str += std::to_string(*p_int);\n  printLabel(pool_str.c_str(), true, 2);\n\n  err = AcquireAndDisplayMemPoolInfo(pool, 3);\n  RET_IF_HSA_ERR(err);\n\n  return err;\n}\n\nstatic hsa_status_t AcquireISAInfo(hsa_isa_t isa, isa_info_t *isa_i) {\n  hsa_status_t err;\n  uint32_t name_len;\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_NAME_LENGTH, &name_len);\n  RET_IF_HSA_ERR(err);\n\n  isa_i->name_str = new char[name_len];\n  if (isa_i->name_str == nullptr) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_NAME, isa_i->name_str);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_MACHINE_MODELS,\n                                                          isa_i->mach_models);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_PROFILES, isa_i->profiles);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_DEFAULT_FLOAT_ROUNDING_MODES,\n                                                   isa_i->def_rounding_modes);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa,\n                    HSA_ISA_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES,\n                                                  isa_i->base_rounding_modes);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_FAST_F16_OPERATION,\n                                                            &isa_i->fast_f16);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_WORKGROUP_MAX_DIM,\n                                                   &isa_i->workgroup_max_dim);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_WORKGROUP_MAX_SIZE,\n                                                  &isa_i->workgroup_max_size);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_GRID_MAX_DIM,\n                                                        &isa_i->grid_max_dim);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_GRID_MAX_SIZE,\n                                                        &isa_i->grid_max_size);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_isa_get_info_alt(isa, HSA_ISA_INFO_FBARRIER_MAX_SIZE,\n                                                    &isa_i->fbarrier_max_size);\n  RET_IF_HSA_ERR(err);\n\n  return err;\n}\n\nstatic void DisplayISAInfo(isa_info_t *isa_i, uint32_t indent) {\n  printLabelStr(\"Name:\", isa_i->name_str, indent);\n\n  std::string models(\"\");\n  if (isa_i->mach_models[HSA_MACHINE_MODEL_SMALL]) {\n    models = \"HSA_MACHINE_MODEL_SMALL \";\n  }\n  if (isa_i->mach_models[HSA_MACHINE_MODEL_LARGE]) {\n    models += \"HSA_MACHINE_MODEL_LARGE\";\n  }\n  printLabelStr(\"Machine Models:\", models.c_str(), indent);\n\n  std::string profiles(\"\");\n  if (isa_i->profiles[HSA_PROFILE_BASE]) {\n    profiles = \"HSA_PROFILE_BASE \";\n  }\n  if (isa_i->profiles[HSA_PROFILE_FULL]) {\n    profiles += \"HSA_PROFILE_FULL\";\n  }\n  printLabelStr(\"Profiles:\", profiles.c_str(), indent);\n\n  std::string rounding_modes(\"\");\n  if (isa_i->def_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT]) {\n    rounding_modes = \"DEFAULT \";\n  }\n  if (isa_i->def_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO]) {\n    rounding_modes += \"ZERO \";\n  }\n  if (isa_i->def_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR]) {\n    rounding_modes += \"NEAR\";\n  }\n  printLabelStr(\"Default Rounding Mode:\", rounding_modes.c_str(), indent);\n\n  rounding_modes = \"\";\n  if (isa_i->base_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT]) {\n    rounding_modes = \"DEFAULT \";\n  }\n  if (isa_i->base_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO]) {\n    rounding_modes += \"ZERO \";\n  }\n  if (isa_i->base_rounding_modes[HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR]) {\n    rounding_modes += \"NEAR\";\n  }\n  printLabelStr(\"Default Rounding Mode:\", rounding_modes.c_str(), indent);\n\n  printLabelStr(\"Fast f16:\", (isa_i->fast_f16 ? \"TRUE\" : \"FALSE\"), indent);\n\n  printLabel(\"Workgroup Max Dimension:\", true, indent);\n  std::string dim;\n  for (int i = 0; i < 3; i++) {\n    dim = \"Dim[\" + std::to_string(i) + \"]:\";\n    printLabelInt(dim.c_str(),\n         reinterpret_cast<uint32_t*>(&isa_i->workgroup_max_dim)[i], indent+1);\n  }\n\n  printLabelInt(\"Workgroup Max Size:\", isa_i->workgroup_max_size, indent);\n\n  printLabel(\"Grid Max Dimension:\", true, indent);\n  printLabelInt(\"x\", isa_i->grid_max_dim.x, indent+1);\n  printLabelInt(\"y\", isa_i->grid_max_dim.y, indent+1);\n  printLabelInt(\"z\", isa_i->grid_max_dim.z, indent+1);\n\n  printLabelInt(\"Grid Max Size:\", isa_i->grid_max_size, indent);\n  printLabelInt(\"FBarrier Max Size:\", isa_i->fbarrier_max_size, indent);\n}\n\nstatic hsa_status_t\nAcquireAndDisplayISAInfo(const hsa_isa_t isa, uint32_t indent) {\n  hsa_status_t err;\n  isa_info_t isa_i;\n\n  isa_i.name_str = nullptr;\n  err = AcquireISAInfo(isa, &isa_i);\n  RET_IF_HSA_ERR(err);\n\n  DisplayISAInfo(&isa_i, 3);\n\n  if (isa_i.name_str != nullptr) {\n    delete []isa_i.name_str;\n  }\n  return err;\n}\nstatic hsa_status_t get_isa_info(hsa_isa_t isa, void* data) {\n  hsa_status_t err;\n  int* isa_int = reinterpret_cast<int*>(data);\n  (*isa_int)++;\n\n  std::string isa_str(\"ISA \");\n  isa_str += std::to_string(*isa_int);\n  printLabel(isa_str.c_str(), true, 2);\n\n  err = AcquireAndDisplayISAInfo(isa, 3);\n  RET_IF_HSA_ERR(err);\n\n  return err;\n}\n// Cache info dump is ifdef'd out as it generates a lot of output that is\n// not that interesting. Define ENABLE_CACHE_DUMP if this is of interest.\n#ifdef ENABLE_CACHE_DUMP\nstatic void DisplayCacheInfo(cache_info_t *cache_i, uint32_t indent) {\n  printLabelStr(\"Name:\", cache_i->name_str, indent);\n\n  printLabelInt(\"Level:\", cache_i->level, indent);\n  printLabelInt(\"Size:\", cache_i->size, indent);\n}\n\nstatic hsa_status_t AcquireCacheInfo(hsa_cache_t cache, cache_info_t *cache_i) {\n  hsa_status_t err;\n  uint32_t name_len;\n  err = hsa_cache_get_info(cache, HSA_CACHE_INFO_NAME_LENGTH, &name_len);\n  RET_IF_HSA_ERR(err);\n\n  cache_i->name_str = new char[name_len];\n  if (cache_i->name_str == nullptr) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  err = hsa_cache_get_info(cache, HSA_CACHE_INFO_NAME, cache_i->name_str);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_cache_get_info(cache, HSA_CACHE_INFO_LEVEL, &cache_i->level);\n  RET_IF_HSA_ERR(err);\n\n  err = hsa_cache_get_info(cache, HSA_CACHE_INFO_SIZE, &cache_i->size);\n  RET_IF_HSA_ERR(err);\n  return err;\n}\n\nstatic hsa_status_t\nAcquireAndDisplayCacheInfo(const hsa_cache_t cache, uint32_t indent) {\n  hsa_status_t err;\n  cache_info_t cache_i;\n\n  err = AcquireCacheInfo(cache, &cache_i);\n  RET_IF_HSA_ERR(err);\n\n  DisplayCacheInfo(&cache_i, 3);\n\n  if (cache_i.name_str != nullptr) {\n    delete []cache_i.name_str;\n  }\n\n  return err;\n}\n\nstatic hsa_status_t get_cache_info(hsa_cache_t cache, void* data) {\n  hsa_status_t err;\n  int* cache_int = reinterpret_cast<int*>(data);\n  (*cache_int)++;\n\n  std::string cache_str(\"Cache L\");\n  cache_str += std::to_string(*cache_int);\n  printLabel(cache_str.c_str(), true, 2);\n\n  err = AcquireAndDisplayCacheInfo(cache, 3);\n  RET_IF_HSA_ERR(err);\n\n  return err;\n}\n#endif  // ENABLE_CACHE_DUMP\nstatic hsa_status_t\nAcquireAndDisplayAgentInfo(hsa_agent_t agent, void* data) {\n  int pool_number = 0;\n  int isa_number = 0;\n\n  hsa_status_t err;\n  agent_info_t agent_i;\n\n  int *agent_number = reinterpret_cast<int*>(data);\n  (*agent_number)++;\n\n  err = AcquireAgentInfo(agent, &agent_i);\n  RET_IF_HSA_ERR(err);\n\n  std::string ind(kIndentSize, ' ');\n\n  printLabel(\"*******\", true);\n  std::string agent_ind(\"Agent \");\n  agent_ind += std::to_string(*agent_number).c_str();\n  printLabel(agent_ind.c_str(), true);\n  printLabel(\"*******\", true);\n\n  DisplayAgentInfo(&agent_i);\n\n  printLabel(\"Pool Info:\", true, 1);\n  err = hsa_amd_agent_iterate_memory_pools(agent, get_pool_info, &pool_number);\n  RET_IF_HSA_ERR(err);\n\n  printLabel(\"ISA Info:\", true, 1);\n  err = hsa_agent_iterate_isas(agent, get_isa_info, &isa_number);\n  if (err == HSA_STATUS_ERROR_INVALID_AGENT) {\n    printLabel(\"N/A\", true, 2);\n    return HSA_STATUS_SUCCESS;\n  }\n  RET_IF_HSA_ERR(err);\n\n#if ENABLE_CACHE_DUMP\n  int cache_number = 0;\n  printLabel(\"Cache Info:\", true, 1);\n  err = hsa_agent_iterate_caches(agent, get_cache_info, &cache_number);\n  if (err == HSA_STATUS_ERROR_INVALID_AGENT) {\n    printLabel(\"N/A\", true, 2);\n    return HSA_STATUS_SUCCESS;\n  }\n#endif\n  RET_IF_HSA_ERR(err);\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Print out all static information known to HSA about the target system.\n// Throughout this program, the Acquire-type functions make HSA calls to\n// interate through HSA objects and then perform HSA get_info calls to\n// acccumulate information about those objects. Corresponding to each\n// Acquire-type function is a Display* function which display the\n// accumulated data in a formatted way.\nint main(int argc, char* argv[]) {\n  hsa_status_t err;\n\n  err = hsa_init();\n  RET_IF_HSA_ERR(err);\n\n  // Acquire and display system information\n  system_info_t sys_info;\n\n  // This function will call HSA get_info functions to gather information\n  // about the system.\n  err = AcquireSystemInfo(&sys_info);\n  RET_IF_HSA_ERR(err);\n\n  printLabel(\"=====================\", true);\n  printLabel(\"HSA System Attributes\", true);\n  printLabel(\"=====================\", true);\n  DisplaySystemInfo(&sys_info);\n\n  // Iterate through every agent and get and display their info\n  printLabel(\"==========\", true);\n  printLabel(\"HSA Agents\", true);\n  printLabel(\"==========\", true);\n  uint32_t agent_ind = 0;\n  err = hsa_iterate_agents(AcquireAndDisplayAgentInfo, &agent_ind);\n  RET_IF_HSA_ERR(err);\n\n  printLabel(\"*** Done ***\", true);\n\n  err = hsa_shut_down();\n  RET_IF_HSA_ERR(err);\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/agent_props.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n\n#include \"suites/functional/agent_props.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintAgentPropsSubtestHeader(const char *header) {\n  std::cout << \"  *** \" << header << \" ***\" << std::endl;\n}\n\nAgentPropTest::AgentPropTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"  *** Query RocR Agent Properties ***\");\n  set_description(\"  *** Checks properties of Agent's on a system ***\");\n}\n\nAgentPropTest::~AgentPropTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid AgentPropTest::SetUp(void) {\n  TestBase::SetUp();\n  std::cout << \"  *** Initialize ROCr Runtime and \" \n            << \"acquire handles of agents\" << \" ***\" << std::endl;\n}\n\nvoid AgentPropTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid AgentPropTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid AgentPropTest::DisplayResults(void) const {\n  TestBase::DisplayResults();\n  std::cout << std::endl;\n  for (uint32_t idx = 0 ; idx < this->propList_.size(); ++idx) {\n    std::cout << this->propList_[idx] << std::endl;\n  }\n  return;\n}\n\nvoid AgentPropTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n// Extend this method to query for agent properties that are\n// currently not tested\nvoid AgentPropTest::QueryAgentProp(hsa_agent_t agent,\n                                   hsa_agent_info_t prop) {\n  hsa_status_t err;\n  hsa_device_type_t agType;\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &agType);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  std::stringstream ss;\n  ss << \"  Agent \" << \"(\";\n  switch (agType) {\n    case HSA_DEVICE_TYPE_CPU:\n      ss << \"CPU) : \";\n      break;\n    case HSA_DEVICE_TYPE_GPU:\n      ss << \"GPU) : \";\n      break;\n    case HSA_DEVICE_TYPE_DSP:\n      ss << \"DSP) : \";\n      break;\n    case HSA_DEVICE_TYPE_AIE:\n      ss << \"AIE) : \";\n      break;\n  }\n\n  // Print the agent property\n  uint32_t key = uint32_t(prop);\n  switch (key) {\n  // Retrieves UUID property value of the agent\n  case HSA_AMD_AGENT_INFO_UUID: {\n    char uuid[32];\n    err = hsa_agent_get_info(agent, prop, (void*)&uuid[0]);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    ss << uuid;\n    propList_.push_back(ss.str());\n    break;\n  }\n  case HSA_AMD_AGENT_INFO_CLOCK_COUNTERS: {\n    std::stringstream str_s;\n\n    hsa_amd_clock_counters_t counters = {0};\n\n    err = hsa_agent_get_info(agent, prop, &counters);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    str_s << \"\\n\\n  Clock Counters\";\n    str_s << \"\\n  Clock Frequency: \"  << counters.system_clock_frequency << \"\\n\";\n    str_s << \"  GPU Clock counter: \"  << counters.gpu_clock_counter << \"\\n\";\n    str_s << \"  System system_clock_counter: \"  << counters.system_clock_counter << \"\\n\";\n    str_s << \"  CPU Clock counter: \"  << counters.cpu_clock_counter << \"\\n\";\n    propList_.push_back(str_s.str());\n\n    ASSERT_NE(0, counters.system_clock_frequency);\n    ASSERT_NE(0, counters.gpu_clock_counter);\n    ASSERT_NE(0, counters.system_clock_counter);\n    ASSERT_NE(0, counters.cpu_clock_counter);\n\n    break;\n  }\n  default:\n    FAIL();\n  }\n\n}\n\nvoid AgentPropTest::QueryAgentUUID() {\n  hsa_status_t err;\n  if (verbosity() > 0) {\n    PrintAgentPropsSubtestHeader(\"Query GPU and CPU Agent's UUID\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (uint32_t idx = 0 ; idx < cpus.size(); ++idx) {\n    QueryAgentProp(cpus[idx], (hsa_agent_info_t)HSA_AMD_AGENT_INFO_UUID);\n  }\n\n  for (uint32_t idx = 0 ; idx < gpus.size(); ++idx) {\n    QueryAgentProp(gpus[idx], (hsa_agent_info_t)HSA_AMD_AGENT_INFO_UUID);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"  *** Execution completed - subtest Passed \" << \" ***\" << std::endl;\n  }\n}\n\nvoid AgentPropTest::QueryAgentClockCounters() {\n  hsa_status_t err;\n  if (verbosity() > 0) {\n    PrintAgentPropsSubtestHeader(\"Query Agent's Clock Counters\");\n  }\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (uint32_t idx = 0 ; idx < gpus.size(); ++idx) {\n    QueryAgentProp(gpus[idx], (hsa_agent_info_t)HSA_AMD_AGENT_INFO_CLOCK_COUNTERS);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"  *** Execution completed - subtest Passed \" << \" ***\" << std::endl;\n  }\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/agent_props.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_AGENT_PROPS_H_\n#define ROCRTST_SUITES_FUNCTIONAL_AGENT_PROPS_H_\n\n#include <string>\n#include <vector>\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass AgentPropTest : public TestBase {\n public:\n    AgentPropTest();\n\n  // @Brief: Destructor for test case of AgentPropTest\n  virtual ~AgentPropTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Query UUID property of agents of a ROCm platform\n  void QueryAgentUUID();\n\n  // @Brief: Query Clock Counter property of agents of a ROCm platform\n  void QueryAgentClockCounters();\n\n private:\n  // Capture value for all agents on system\n  std::vector<std::string> propList_;\n\n  void QueryAgentProp(hsa_agent_t agent, hsa_agent_info_t prop);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_AGENT_PROPS_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/aql_barrier_bit.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#include <algorithm>\r\n#include <iostream>\r\n#include <vector>\r\n#include \"suites/functional/aql_barrier_bit.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/concurrent_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic const int NUM_WAIT_KERNELS = 8;\r\n\r\nstatic inline void AtomicSetPacketHeader(uint16_t header, uint16_t setup,\r\n                                  hsa_kernel_dispatch_packet_t* queue_packet) {\r\n  __atomic_store_n(reinterpret_cast<uint32_t*>(queue_packet),\r\n                   header | (setup << 16), __ATOMIC_RELEASE);\r\n}\r\n\r\nAqlBarrierBitTest::AqlBarrierBitTest(bool set, bool notSet) : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n                          // This is a default value which can be overridden\r\n                          // on the command line.\r\n  if (set) {\r\n  set_title(\"RocR Aql Barrier Bit Set Test\");\r\n  set_description(\"This test checks the barrier bit functionality, set\");\r\n  } else if (notSet) {\r\n  set_title(\"RocR Concurrent Shutdown Test\");\r\n  set_description(\"This test checks the barrier bit functionality, un set\");\r\n  }\r\n}\r\n\r\nAqlBarrierBitTest::~AqlBarrierBitTest(void) {\r\n}\r\n\r\nvoid AqlBarrierBitTest::SetUp(void) {\r\n  hsa_status_t err;\r\n\r\n  TestBase::SetUp();\r\n\r\n  err = rocrtst::SetDefaultAgents(this);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\r\n\r\n  err = rocrtst::SetPoolsTypical(this);\r\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\r\n  return;\r\n}\r\n\r\nvoid AqlBarrierBitTest::Run(void) {\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n  TestBase::Run();\r\n}\r\n\r\nvoid AqlBarrierBitTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid AqlBarrierBitTest::DisplayResults(void) const {\r\n  // Compare required profile for this test case with what we're actually\r\n  // running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  return;\r\n}\r\n\r\nvoid AqlBarrierBitTest::Close() {\r\n  // This will close handles opened within rocrtst utility calls and call\r\n  // hsa_shut_down(), so it should be done after other hsa cleanup\r\n}\r\n\r\nvoid AqlBarrierBitTest::BarrierBitSet(void) {\r\n  hsa_status_t status;\r\n\r\n  // The kernarg data structure\r\n  typedef struct __attribute__ ((aligned(16))) signal_args_s {\r\n    void *signal_values;\r\n  } signal_args_t;\r\n  signal_args_t signal_args;\r\n\r\n  // Get the GPU agents into a vector\r\n  std::vector<hsa_agent_t> agent_list;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &agent_list);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Get CPU agent to get the kern_arg pool\r\n  std::vector<hsa_agent_t> cpu_agent;\r\n  status = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpu_agent);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Repeat the test for each agent\r\n  unsigned int ii;\r\n  for (ii = 0; ii < agent_list.size(); ++ii) {\r\n  // Check if the queue supports dispatch\r\n  uint32_t features = 0;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_FEATURE, &features);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\r\n    continue;\r\n  }\r\n\r\n  // Find a memory pool that supports fine grained memory\r\n  hsa_amd_memory_pool_t global_pool;\r\n  global_pool.handle = (uint64_t)-1;\r\n  status = hsa_amd_agent_iterate_memory_pools(agent_list[ii], rocrtst::GetGlobalMemoryPool, &global_pool);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Obtain the agent's machine model\r\n  hsa_machine_model_t machine_model;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_MACHINE_MODEL, &machine_model);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Obtain the agent's profile\r\n  hsa_profile_t profile;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_PROFILE, &profile);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n\r\n  // Find a memory pool that supports kernel arguments\r\n  hsa_amd_memory_pool_t kernarg_pool;\r\n  kernarg_pool.handle = (uint64_t)-1;\r\n  status = hsa_amd_agent_iterate_memory_pools(cpu_agent[0], rocrtst::GetKernArgMemoryPool, &kernarg_pool);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create a queue\r\n  hsa_queue_t* queue;\r\n  status = hsa_queue_create(agent_list[ii], 1024, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n  set_kernel_name(\"signal_wait_kernel\");\r\n  status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Allocate the kernel argument buffer from the correct pool\r\n  signal_args_t* kernarg_buffer = NULL;\r\n  status = hsa_amd_memory_pool_allocate(kernarg_pool,\r\n           sizeof(signal_args_t), 0,\r\n           reinterpret_cast<void**>(&kernarg_buffer));\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  status = hsa_amd_agents_allow_access(1, &agent_list[ii], NULL, kernarg_buffer);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create the completion signal\r\n  hsa_signal_t completion_signal;\r\n  status = hsa_signal_create(1, 0, NULL, &completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  hsa_amd_memory_pool_access_t access;\r\n  status = hsa_amd_agent_memory_pool_get_info(cpu_agent[0],\r\n                                              global_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  hsa_signal_t* kernel_signal;\r\n  hsa_signal_value_t* set_value;\r\n\r\n\r\n  hsa_signal_t s;\r\n  status = hsa_signal_create(1, 0, NULL, &s);\r\n\r\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n    // Create the kernel signal\r\n    status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          sizeof(hsa_signal_t), 0, reinterpret_cast<void**>(&kernel_signal));\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_signal_create(1, 0, NULL, kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n    status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          sizeof(hsa_signal_value_t), 0, reinterpret_cast<void**>(&set_value));\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    memset(set_value, 0, sizeof(hsa_signal_value_t));\r\n\r\n    // Set the signal_args with kernel_signal, will be accessed from Kernel side\r\n    signal_args.signal_values = reinterpret_cast<void*>(kernel_signal);\r\n  }\r\n\r\n  memcpy(kernarg_buffer, &signal_args, sizeof(signal_args_t));\r\n\r\n  // Create the set kernel completion signal\r\n  hsa_signal_t set_kernel_completion_signal;\r\n  status = hsa_signal_create((hsa_signal_value_t)1, 0, NULL, &set_kernel_completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create the wait kernel completion signals\r\n  hsa_signal_t wait_kernel_completion_signal[NUM_WAIT_KERNELS];\r\n  int jj;\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    status = hsa_signal_create((hsa_signal_value_t)1, 0, NULL, &wait_kernel_completion_signal[jj]);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n\r\n  // Setup the dispatch packet\r\n  hsa_kernel_dispatch_packet_t dispatch_packet;\r\n  memset(&dispatch_packet, 0, sizeof(hsa_kernel_dispatch_packet_t));\r\n\r\n  dispatch_packet.workgroup_size_x = 1;\r\n  dispatch_packet.workgroup_size_y = 1;\r\n  dispatch_packet.workgroup_size_z = 1;\r\n  dispatch_packet.grid_size_x = 1;\r\n  dispatch_packet.grid_size_y = 1;\r\n  dispatch_packet.grid_size_z = 1;\r\n  dispatch_packet.kernel_object = kernel_object();\r\n  dispatch_packet.group_segment_size = group_segment_size();\r\n  dispatch_packet.private_segment_size = private_segment_size();\r\n  dispatch_packet.kernarg_address = kernarg_buffer;\r\n\r\n\r\n\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    // Set the appropriate completion signal\r\n    dispatch_packet.completion_signal = wait_kernel_completion_signal[jj];\r\n    // Dispatch the kernel\r\n    // const uint32_t queue_size = queue->size;\r\n    const uint32_t queue_mask = queue->size - 1;\r\n    // write to command queue\r\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n    reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                 (queue->base_address)[index & queue_mask] = dispatch_packet;\r\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n\r\n    dispatch_packet.header |= HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\r\n    dispatch_packet.header |= 0 << HSA_PACKET_HEADER_BARRIER;\r\n    dispatch_packet.setup |= 1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\r\n    void* q_base = queue->base_address;\r\n    // Set the Aql packet header\r\n    AtomicSetPacketHeader(dispatch_packet.header, dispatch_packet.setup,\r\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                            (q_base))[index & queue_mask]);\r\n\r\n    // ringdoor bell\r\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n  }\r\n\r\n  // Dispatch the set kernel, setting the barrier bit to 1\r\n  dispatch_packet.header |= 1 == HSA_PACKET_HEADER_BARRIER;\r\n\r\n  set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n  set_kernel_name(\"signal_st_rlx_kernel\");\r\n  status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n  // Set the appropriate completion signal and code descriptor values\r\n  dispatch_packet.kernel_object = kernel_object();\r\n  dispatch_packet.group_segment_size = group_segment_size();\r\n  dispatch_packet.private_segment_size = private_segment_size();\r\n  dispatch_packet.kernarg_address = kernarg_buffer;\r\n\r\n  // Dispatch the kernel\r\n  // const uint32_t queue_size = queue->size;\r\n  const uint32_t queue_mask = queue->size - 1;\r\n  // write to command queue\r\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n  reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                 (queue->base_address)[index & queue_mask] = dispatch_packet;\r\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n  // ringdoor bell\r\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n\r\n  // Query the systems timestamp frequency for wait timeout\r\n  uint16_t freq;\r\n  status = hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, reinterpret_cast<void*>(&freq));\r\n\r\n  // Wait on the completion signal of the set kernel, but\r\n  // timeout after 1 second\r\n  uint64_t wait_time = (uint64_t) freq;\r\n  hsa_signal_value_t signal_value;\r\n  signal_value = hsa_signal_wait_relaxed(set_kernel_completion_signal,\r\n                                         HSA_SIGNAL_CONDITION_EQ, 0, wait_time, HSA_WAIT_STATE_ACTIVE);\r\n  ASSERT_EQ(1, signal_value);\r\n\r\n  // Wait on the completion signals of each of the wait kernels, again timing out after 1 second\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    signal_value = hsa_signal_wait_relaxed(wait_kernel_completion_signal[jj],\r\n                                           HSA_SIGNAL_CONDITION_EQ, 0, wait_time, HSA_WAIT_STATE_ACTIVE);\r\n    ASSERT_EQ(1, signal_value);\r\n  }\r\n\r\n\r\n  // destroy the signal created for async copy\r\n  status = hsa_signal_destroy(completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n    status = hsa_amd_memory_pool_free(kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_memory_pool_free(set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  } else {\r\n    status = hsa_amd_memory_unlock(kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n    status = hsa_amd_memory_unlock(set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n  // Destroy the queue\r\n  status = hsa_queue_destroy(queue);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n}\r\n\r\nvoid AqlBarrierBitTest::BarrierBitNotSet(void) {\r\n  hsa_status_t status;\r\n\r\n  // The kernarg data structure\r\n  typedef struct __attribute__ ((aligned(16))) signal_args_s {\r\n    void *signal_values;\r\n  } signal_args_t;\r\n  signal_args_t signal_args;\r\n\r\n  // Get the GPU agents into a vector\r\n  std::vector<hsa_agent_t> agent_list;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &agent_list);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n\r\n  // Get CPU agent to get the kern_arg pool\r\n  std::vector<hsa_agent_t> cpu_agent;\r\n  status = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpu_agent);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Repeat the test for each agent\r\n  unsigned int ii;\r\n  for (ii = 0; ii < agent_list.size(); ++ii) {\r\n  // Check if the queue supports dispatch\r\n  uint32_t features = 0;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_FEATURE, &features);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\r\n    continue;\r\n  }\r\n\r\n  // Find a memory pool that supports fine grained memory\r\n  hsa_amd_memory_pool_t global_pool;\r\n  global_pool.handle = (uint64_t)-1;\r\n  status = hsa_amd_agent_iterate_memory_pools(agent_list[ii], rocrtst::GetGlobalMemoryPool, &global_pool);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Obtain the agent's machine model\r\n  hsa_machine_model_t machine_model;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_MACHINE_MODEL, &machine_model);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Obtain the agent's profile\r\n  hsa_profile_t profile;\r\n  status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_PROFILE, &profile);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n\r\n  // Find a memory pool that supports kernel arguments\r\n  hsa_amd_memory_pool_t kernarg_pool;\r\n  kernarg_pool.handle = (uint64_t)-1;\r\n  status = hsa_amd_agent_iterate_memory_pools(cpu_agent[0], rocrtst::GetKernArgMemoryPool, &kernarg_pool);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create a queue\r\n  hsa_queue_t* queue;\r\n  status = hsa_queue_create(agent_list[ii], 1024, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n  set_kernel_name(\"signal_wait_kernel\");\r\n  status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Allocate the kernel argument buffer from the correct pool\r\n  signal_args_t* kernarg_buffer = NULL;\r\n  status = hsa_amd_memory_pool_allocate(kernarg_pool,\r\n           sizeof(signal_args_t), 0,\r\n           reinterpret_cast<void**>(&kernarg_buffer));\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  status = hsa_amd_agents_allow_access(1, &agent_list[ii], NULL, kernarg_buffer);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create the completion signal\r\n  hsa_signal_t completion_signal;\r\n  status = hsa_signal_create(1, 0, NULL, &completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  hsa_amd_memory_pool_access_t access;\r\n  status = hsa_amd_agent_memory_pool_get_info(cpu_agent[0],\r\n                                              global_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  hsa_signal_t* kernel_signal;\r\n  hsa_signal_value_t* set_value;\r\n\r\n\r\n  hsa_signal_t s;\r\n  status = hsa_signal_create(1, 0, NULL, &s);\r\n\r\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n    // Create the kernel signal\r\n    status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          sizeof(hsa_signal_t), 0, reinterpret_cast<void**>(&kernel_signal));\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_signal_create(1, 0, NULL, kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n    status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          sizeof(hsa_signal_value_t), 0, reinterpret_cast<void**>(&set_value));\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    memset(set_value, 0, sizeof(hsa_signal_value_t));\r\n\r\n    // Set the signal_args with kernel_signal, will be accessed from Kernel side\r\n    signal_args.signal_values = reinterpret_cast<void*>(kernel_signal);\r\n  }\r\n\r\n  memcpy(kernarg_buffer, &signal_args, sizeof(signal_args_t));\r\n\r\n  // Create the set kernel completion signal\r\n  hsa_signal_t set_kernel_completion_signal;\r\n  status = hsa_signal_create((hsa_signal_value_t)1, 0, NULL, &set_kernel_completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  // Create the wait kernel completion signals\r\n  hsa_signal_t wait_kernel_completion_signal[NUM_WAIT_KERNELS];\r\n  int jj;\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    status = hsa_signal_create((hsa_signal_value_t)1, 0, NULL, &wait_kernel_completion_signal[jj]);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n\r\n  // Setup the dispatch packet\r\n  hsa_kernel_dispatch_packet_t dispatch_packet;\r\n  memset(&dispatch_packet, 0, sizeof(hsa_kernel_dispatch_packet_t));\r\n\r\n  dispatch_packet.workgroup_size_x = 1;\r\n  dispatch_packet.workgroup_size_y = 1;\r\n  dispatch_packet.workgroup_size_z = 1;\r\n  dispatch_packet.grid_size_x = 1;\r\n  dispatch_packet.grid_size_y = 1;\r\n  dispatch_packet.grid_size_z = 1;\r\n  dispatch_packet.kernel_object = kernel_object();\r\n  dispatch_packet.group_segment_size = group_segment_size();\r\n  dispatch_packet.private_segment_size = private_segment_size();\r\n  dispatch_packet.kernarg_address = kernarg_buffer;\r\n\r\n\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    // Set the appropriate completion signal\r\n    dispatch_packet.completion_signal = wait_kernel_completion_signal[jj];\r\n    // Dispatch the kernel\r\n    // const uint32_t queue_size = queue->size;\r\n    const uint32_t queue_mask = queue->size - 1;\r\n    // write to command queue\r\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n    reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                 (queue->base_address)[index & queue_mask] = dispatch_packet;\r\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n    dispatch_packet.header |= HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\r\n    dispatch_packet.header |= 0 << HSA_PACKET_HEADER_BARRIER;\r\n    dispatch_packet.setup |= 1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\r\n\r\n    void* q_base = queue->base_address;\r\n    // Set the Aql packet header\r\n    AtomicSetPacketHeader(dispatch_packet.header, dispatch_packet.setup,\r\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                            (q_base))[index & queue_mask]);\r\n\r\n    // ringdoor bell\r\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n  }\r\n\r\n  // Dispatch the set kernel, NOT setting the barrier bit\r\n  set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n  set_kernel_name(\"signal_st_rlx_kernel\");\r\n  status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n  // Set the appropriate completion signal and code descriptor values\r\n  dispatch_packet.kernel_object = kernel_object();\r\n  dispatch_packet.group_segment_size = group_segment_size();\r\n  dispatch_packet.private_segment_size = private_segment_size();\r\n  dispatch_packet.kernarg_address = kernarg_buffer;\r\n\r\n  // Set the appropriate completion signal\r\n  dispatch_packet.completion_signal = set_kernel_completion_signal;\r\n  // Dispatch the kernel\r\n  // const uint32_t queue_size = queue->size;\r\n  const uint32_t queue_mask = queue->size - 1;\r\n  // write to command queue\r\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n  reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                 (queue->base_address)[index & queue_mask] = dispatch_packet;\r\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n  // ringdoor bell\r\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n\r\n  // Query the systems timestamp frequency for wait timeout\r\n  uint16_t freq;\r\n  status = hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, reinterpret_cast<void*>(&freq));\r\n\r\n  // Wait on the completion signal of the set kernel, but\r\n  // timeout after 1 second\r\n  uint64_t wait_time = (uint64_t) freq;\r\n  hsa_signal_value_t signal_value;\r\n  signal_value = hsa_signal_wait_relaxed(set_kernel_completion_signal,\r\n                                         HSA_SIGNAL_CONDITION_EQ, 0, wait_time, HSA_WAIT_STATE_ACTIVE);\r\n  ASSERT_EQ(1, signal_value);\r\n\r\n  // Wait on the completion signals of each of the wait kernels, again timing out after 1 second\r\n  for (jj = 0; jj < NUM_WAIT_KERNELS; ++jj) {\r\n    signal_value = hsa_signal_wait_relaxed(wait_kernel_completion_signal[jj],\r\n                                           HSA_SIGNAL_CONDITION_EQ, 0, wait_time, HSA_WAIT_STATE_ACTIVE);\r\n    ASSERT_EQ(1, signal_value);\r\n  }\r\n\r\n  // Check kernel signal\r\n  std::cout << \"Kernel_signal Value after package execustion(should be 0) = \" << (kernel_signal->handle) << std::endl;\r\n\r\n  // destroy the signal created for async copy\r\n  status = hsa_signal_destroy(s);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  status = hsa_signal_destroy(completion_signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n    status = hsa_amd_memory_pool_free(kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    status = hsa_amd_memory_pool_free(set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  } else {\r\n    status = hsa_amd_memory_unlock(kernel_signal);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n    status = hsa_amd_memory_unlock(set_value);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n  // Destroy the queue\r\n  status = hsa_queue_destroy(queue);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n}\r\n\r\n"
  },
  {
    "path": "rocrtst/suites/functional/aql_barrier_bit.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_AQL_BARRIER_BIT_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_AQL_BARRIER_BIT_H_\r\n\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass AqlBarrierBitTest : public TestBase {\r\n public:\r\n    AqlBarrierBitTest(bool, bool);\r\n\r\n    // @Brief: Destructor for the AqlBarrierBitTest class\r\n    virtual ~AqlBarrierBitTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    // @Brief: Runtime will be initialized Num_Times\r\n    void BarrierBitSet(void);\r\n\r\n    void BarrierBitNotSet(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_AQL_BARRIER_BIT_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_init.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#include <algorithm>\r\n#include <iostream>\r\n\r\n\r\n#include \"suites/functional/concurrent_init.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic void* TestHSAInitFunction(void* args) {\r\n  // This function called for each thread\r\n  // This will initialize the HSA runtime.\r\n  hsa_status_t status;\r\n  // const char* err_str; // Local variable\r\n\r\n  // Initialize hsa runtime\r\n  status = hsa_init();\r\n  EXPECT_EQ(HSA_STATUS_SUCCESS, status) << \"hsa_init failed in worker thread.\";\r\n  pthread_exit(nullptr);\r\n  return nullptr;\r\n}\r\n\r\nstatic const int NumOfThreads = 100;  // Number of thread to be created\r\n\r\n#define RET_IF_HSA_ERR(err)                                                                        \\\r\n  {                                                                                                \\\r\n    if ((err) != HSA_STATUS_SUCCESS) {                                                             \\\r\n      const char* msg = 0;                                                                         \\\r\n      hsa_status_string(err, &msg);                                                                \\\r\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err) << msg;                                                   \\\r\n      return (err);                                                                                \\\r\n    }                                                                                              \\\r\n  \\\r\n}\r\n\r\nConcurrentInitTest::ConcurrentInitTest(void) : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n                          // This is a default value which can be overridden\r\n                          // on the command line.\r\n  set_title(\"RocR Concurrent Init Test\");\r\n  set_description(\"This test initializes HSA runtime concurrently\");\r\n}\r\n\r\n// Any 1-time setup involving member variables used in the rest of the test\r\n// should be done here.\r\nConcurrentInitTest::~ConcurrentInitTest(void) {\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitTest::SetUp(void) {\r\n  return;  // hsa runtime initalized pthread callback function\r\n}\r\n\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitTest::Run(void) {\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  TestBase::Run();\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid ConcurrentInitTest::DisplayResults(void) const {\r\n  // Compare required profile for this test case with what we're actually\r\n  // running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  return;\r\n}\r\n\r\nvoid ConcurrentInitTest::Close() {\r\n  // TestBase::SetUp() not used.\r\n}\r\n\r\nvoid ConcurrentInitTest::TestConcurrentInit(void) {\r\n  pthread_t ThreadId[NumOfThreads];\r\n  pthread_attr_t attr;\r\n  pthread_attr_init(&attr);\r\n  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);  // Setting the attribute to PTHREAD_CREATE_JOINABLE\r\n\r\n  // This is to create threads concurrently\r\n  // HSA runtime will be initialized for each thread\r\n  for (int Id = 0; Id < NumOfThreads; ++Id) {\r\n    int ThreadStatus = pthread_create(&ThreadId[Id], &attr, TestHSAInitFunction, nullptr);\r\n    // Check if the thread is created successfully\r\n    // Might want to switch to non-fatal EXPECT_EQ and\r\n    // handle not being able to create so many threads.\r\n    ASSERT_EQ(0, ThreadStatus) << \"pthead_create failed.\";\r\n  }\r\n\r\n  // Wait for workers.\r\n  for (int Id = 0; Id < NumOfThreads; ++Id) {\r\n    int err = pthread_join(ThreadId[Id], nullptr);\r\n    ASSERT_EQ(0, err) << \"pthread_join failed.\";\r\n  }\r\n\r\n  // Invoke hsa_shut_down and verify that all the hsa_init's were counted.\r\n  // HSA should be exactly closed after NumOfThreads calls.\r\n  for (int Id = 0; Id < NumOfThreads; ++Id) {\r\n    hsa_status_t err = hsa_shut_down();\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err) << \"An hsa_init was missed.\";\r\n  }\r\n\r\n  hsa_status_t err = hsa_shut_down();\r\n  ASSERT_EQ(HSA_STATUS_ERROR_NOT_INITIALIZED, err) << \"hsa_init reference count was too high.\";\r\n}\r\n#undef RET_IF_HSA_ERR\r\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_init.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_H_\r\n\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass ConcurrentInitTest : public TestBase {\r\n public:\r\n    ConcurrentInitTest();\r\n\r\n    // @Brief: Destructor for the ConcurrentInitTest class\r\n    virtual ~ConcurrentInitTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    void TestConcurrentInit(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_init_shutdown.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#include <algorithm>\r\n#include <iostream>\r\n#include \"suites/functional/concurrent_init_shutdown.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic void* TestHSAInitShutdownFunction(void* args) {\r\n  // This is callback function for each thread\r\n  // This will initialize the HSA runtime and shutdown\r\n  hsa_status_t status;\r\n\r\n  // Initialize hsa runtime\r\n  status = hsa_init();\r\n  EXPECT_EQ(HSA_STATUS_SUCCESS, status) << \"hsa_init failed in worker thread.\";\r\n\r\n  // Shutdown hsa runtime\r\n  status = hsa_shut_down();\r\n  EXPECT_EQ(HSA_STATUS_SUCCESS, status) << \"hsa_shut_down failed in worker thread.\";\r\n\r\n  pthread_exit(nullptr);\r\n  return nullptr;\r\n}\r\n\r\nstatic const int NumOfThreads = 100;  // Number of thread to be created\r\n\r\n#define RET_IF_HSA_ERR(err)                                                                        \\\r\n  {                                                                                                \\\r\n    if ((err) != HSA_STATUS_SUCCESS) {                                                             \\\r\n      const char* msg = 0;                                                                         \\\r\n      hsa_status_string(err, &msg);                                                                \\\r\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err) << msg;                                                   \\\r\n      return (err);                                                                                \\\r\n    }                                                                                              \\\r\n  \\\r\n}\r\n\r\nConcurrentInitShutdownTest::ConcurrentInitShutdownTest(void) : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n                        // This is a default value which can be overridden\r\n                        // on the command line.\r\n  set_title(\"RocR Concurrent Init Test\");\r\n  set_description(\"This test initializes HSA runtime concurrently\");\r\n}\r\n\r\n// Any 1-time setup involving member variables used in the rest of the test\r\n// should be done here.\r\nConcurrentInitShutdownTest::~ConcurrentInitShutdownTest(void) {\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitShutdownTest::SetUp(void) {\r\n  return;  // hsa runtime initalized pthread callback function\r\n}\r\n\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitShutdownTest::Run(void) {\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  TestBase::Run();\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ConcurrentInitShutdownTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid ConcurrentInitShutdownTest::DisplayResults(void) const {\r\n  // Compare required profile for this test case with what we're actually\r\n  // running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  return;\r\n}\r\n\r\nvoid ConcurrentInitShutdownTest::Close() {\r\n  // TestBase::SetUp() not used.\r\n  return;\r\n}\r\n\r\nvoid ConcurrentInitShutdownTest::TestConcurrentInitShutdown(void) {\r\n  pthread_t ThreadId[NumOfThreads];\r\n\r\n  pthread_attr_t attr;\r\n  pthread_attr_init(&attr);\r\n  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r\n\r\n  // This is to create threads concurrently\r\n  // HSA runtime will be initialized and shutdown in each thread\r\n  for (int Id = 0; Id < NumOfThreads; ++Id) {\r\n    int ThreadStatus = pthread_create(&ThreadId[Id], &attr, TestHSAInitShutdownFunction, nullptr);\r\n    // Check if the thread is created successfully\r\n    // Might want to switch to non-fatal EXPECT_EQ and handle not being able to create so many\r\n    // threads.\r\n    ASSERT_EQ(0, ThreadStatus) << \"pthead_create failed.\";\r\n  }\r\n\r\n  // Wait for workers.\r\n  for (int Id = 0; Id < NumOfThreads; ++Id) {\r\n    int err = pthread_join(ThreadId[Id], nullptr);\r\n    ASSERT_EQ(0, err) << \"pthread_join failed.\";\r\n  }\r\n\r\n  // Check that HSA refcount is exact.\r\n  hsa_status_t err = hsa_shut_down();\r\n  ASSERT_EQ(HSA_STATUS_ERROR_NOT_INITIALIZED, err) << \"hsa_init reference count was too high.\";\r\n}\r\n#undef RET_IF_HSA_ERR\r\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_init_shutdown.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_SHUTDOWN_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_SHUTDOWN_H_\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass ConcurrentInitShutdownTest : public TestBase {\r\n public:\r\n    ConcurrentInitShutdownTest();\r\n\r\n    // @Brief: Destructor for the ConcurrentInitShutdownTest class\r\n    virtual ~ConcurrentInitShutdownTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    void TestConcurrentInitShutdown(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_INIT_SHUTDOWN_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_shutdown.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <algorithm>\n#include <iostream>\n\n\n#include \"suites/functional/concurrent_shutdown.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nvoid* TestHSAShutdownFunction(void* args) {\n  // This function called for each thread\n  // This will shutdown the HSA runtime concurrently.\n  hsa_status_t status;\n\n  // Shutdown the hsa runtime concurrently\n  status = hsa_shut_down();\n  if (status != HSA_STATUS_SUCCESS) {\n    std::cout << \"Failed\" << std::endl;\n  }\n  pthread_exit(NULL);\n}\n\nstatic const int NumOfThreads = 1000;  // Number of thread to be created\nstatic const int NumTimesInitalize = 1000;  // Number of time the hsa runtime will be initialized\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nConcurrentShutdownTest::ConcurrentShutdownTest(void) : TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"RocR Concurrent Shutdown Test\");\n  set_description(\"This test initializes HSA runtime sequentially, shutdown concurrently\");\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nConcurrentShutdownTest::~ConcurrentShutdownTest(void) {\n}\n\nvoid ConcurrentShutdownTest::SetUp(void) {\n  hsa_status_t status;\n  // Initialize the hsa runtime sequentially, NumTimesInitalize\n  for (int Counter = 0; Counter < NumTimesInitalize; ++Counter) {\n  // Initialize hsa runtime NumTimesInitalize times.\n    status = hsa_init();\n    if (status != HSA_STATUS_SUCCESS) {\n      std::cout << \"Failed\" << std::endl;\n    }\n  }\n  return;  // hsa runtime initalized pthread callback function\n}\n\nvoid ConcurrentShutdownTest::Run(void) {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n  TestBase::Run();\n}\n\nvoid ConcurrentShutdownTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid ConcurrentShutdownTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid ConcurrentShutdownTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  // all the reference count decremented in main function, ConcurrentShutdownTest::SequentiallyInitializeRuntime()\n}\n\nvoid ConcurrentShutdownTest::TestConcurrentShutdown(void) {\n  pthread_t ThreadId[NumOfThreads];\n  pthread_attr_t attr;\n  pthread_attr_init(&attr);\n\n  // Setting the attribute to PTHREAD_CREATE_JOINABLE\n  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\n\n  for (int Id = 0; Id < NumOfThreads; ++Id) {  // This is to create threads concurrently\n                                               // HSA runtime will be shutdown concurrently from each thread\n    int ThreadStatus = pthread_create(ThreadId + Id,\n                                      &attr, TestHSAShutdownFunction, &Id);\n    // Check if the thread is created successfully\n    if (ThreadStatus < 0) {\n      std::cout << Id << \"Thread creation failed \" << std::endl;\n    }\n  }\n}\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/concurrent_shutdown.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_SHUTDOWN_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_SHUTDOWN_H_\r\n\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass ConcurrentShutdownTest : public TestBase {\r\n public:\r\n    ConcurrentShutdownTest();\r\n\r\n    // @Brief: Destructor for the ConcurrentShutdownTest class\r\n    virtual ~ConcurrentShutdownTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    // @Brief: Runtime will be initialized Num_Times\r\n    void SequentiallyInitializeRuntime(void);\r\n\r\n    void TestConcurrentShutdown(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_CONCURRENT_SHUTDOWN_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/cu_masking.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2021-2021, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include \"suites/functional/cu_masking.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/os.h\"\n#include \"common/helper_funcs.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\n#include <string>\n#include <stdlib.h>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nCU_Masking::CU_Masking() : TestBase() {\n  std::string name;\n  std::string desc;\n\n  name = \"CU Masking\";\n  desc = \"This test checks CU masking functionality via hsa_amd_queue_cu_get(set)_mask and HSA_CU_MASK.\";\n\n  set_title(name);\n  set_description(desc);\n\n  set_kernel_file_name(\"cu_mask_kernels.hsaco\");\n}\n\nvoid CU_Masking::Run() {\n  hsa_status_t err;\n  TestBase::Run();\n\n  printf(\"Running %lu iterations\\n\", RealIterationNum());\n\n  // Random source\n  std::mt19937 rand(std::chrono::system_clock::now().time_since_epoch().count());\n\n  // Store cu masking variable\n  std::string mask_var;\n  char* temp = getenv(\"HSA_CU_MASK\");\n  if(temp!=nullptr)\n    mask_var = temp;\n  unsetenv(\"HSA_CU_MASK\");\n\n  std::string mask_init_var;\n  temp = getenv(\"HSA_CU_MASK_SKIP_INIT\");\n  if(temp!=nullptr)\n    mask_init_var = temp;\n  unsetenv(\"HSA_CU_MASK_SKIP_INIT\");\n\n  // Loop over and test all GPUs\n  uint32_t idx = 0;\n  while(true) {\n    Device* gpu;\n    CodeObject* obj;\n    Kernel kern;\n\n    struct args_t {\n      uint32_t* hw_ids;\n      OCLHiddenArgs _;\n    };\n    args_t* args;\n\n    hsa_signal_t signal;\n    hsa_queue_t* q;\n\n    uint32_t cu_count;\n    uint32_t group_size;\n    uint32_t max_grid_size;\n    uint32_t threads;\n\n    auto init = [&]() {\n      System::Init();\n      if(idx == System::gpu().size())\n        return false;\n\n      gpu = &System::gpu()[idx];\n      std::string filename = rocrtst::LocateKernelFile(kernel_file_name(), gpu->agent);\n\n      obj = new CodeObject(filename, *gpu);\n\n      err = hsa_agent_get_info(gpu->agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &cu_count);\n      CHECK(err);\n\n      err = hsa_agent_get_info(gpu->agent, (hsa_agent_info_t)HSA_AGENT_INFO_WORKGROUP_MAX_SIZE, &group_size);\n      CHECK(err);\n\n      err = hsa_agent_get_info(gpu->agent, (hsa_agent_info_t)HSA_AGENT_INFO_GRID_MAX_SIZE, &max_grid_size);\n      CHECK(err);\n\n      uint64_t max_threads = uint64_t(cu_count)*group_size*10;\n      threads = max_threads < max_grid_size ? max_threads : max_grid_size;\n      threads = (threads / group_size) * group_size;\n\n      // All CU enabled check\n      if(!obj->GetKernel(\"get_hw_id\", kern)) {\n        ADD_FAILURE();\n        return false;\n      }\n\n      args = (args_t*)hsaMalloc(sizeof(args_t), System::kernarg());\n      memset(args, 0, sizeof(args_t));\n\n      args->hw_ids = (uint32_t*)hsaMalloc(sizeof(uint32_t)*threads, System::kernarg());\n\n      err = hsa_signal_create(1, 0, nullptr, &signal);\n      CHECK(err);\n\n      err = hsa_queue_create(gpu->agent, 4096, HSA_QUEUE_TYPE_SINGLE, nullptr, nullptr, 0, 0, &q);\n      CHECK(err);\n\n      return true;\n    };\n\n    auto fini = [&]() {\n      err = hsa_queue_destroy(q);\n      CHECK(err);\n      err = hsa_signal_destroy(signal);\n      CHECK(err);\n      err = hsa_memory_free(args->hw_ids);\n      CHECK(err);\n      err = hsa_memory_free(args);\n      CHECK(err);\n      delete obj;\n      gpu = nullptr;\n      System::Shutdown();\n    };\n\n    auto dispatch = [&]() {\n      memset(args->hw_ids, 0, sizeof(uint32_t)*threads);\n\n      Aql pkt = { };\n      pkt.header.type = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n      pkt.header.acquire = HSA_FENCE_SCOPE_SYSTEM;\n      pkt.header.release = HSA_FENCE_SCOPE_SYSTEM;\n      pkt.dispatch.kernel_object = kern.handle;\n      pkt.dispatch.private_segment_size = kern.scratch;\n      pkt.dispatch.group_segment_size = kern.group;\n      pkt.dispatch.setup = 1;\n      pkt.dispatch.workgroup_size_x = group_size;\n      pkt.dispatch.workgroup_size_y = 1;\n      pkt.dispatch.workgroup_size_z = 1;\n      pkt.dispatch.grid_size_x = threads;\n      pkt.dispatch.grid_size_y = 1;\n      pkt.dispatch.grid_size_z = 1;\n      pkt.dispatch.kernarg_address = args;\n      pkt.dispatch.completion_signal = signal;\n\n      SubmitPacket(q, pkt);\n\n      hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_EQ, 0, -1ull, HSA_WAIT_STATE_BLOCKED);\n      hsa_signal_store_relaxed(signal, 1);\n    };\n\n    auto getHwIds = [&](std::vector<uint32_t>& ids){\n      dispatch();\n      std::sort(&args->hw_ids[0], &args->hw_ids[threads]);\n      uint32_t* end = std::unique(&args->hw_ids[0], &args->hw_ids[threads]);\n      ids.clear();\n      ids.insert(ids.begin(), &args->hw_ids[0], end);\n    };\n\n    // Check fully unconstrained.\n    unsetenv(\"HSA_CU_MASK_SKIP_INIT\");\n    setenv(\"HSA_CU_MASK_SKIP_INIT\", \"1\", 1);\n\n    if(!init())\n      break;\n    \n    {\n      char name[64];\n      hsa_agent_get_info(gpu->agent, HSA_AGENT_INFO_NAME, name);\n      name[63]='\\0';\n      printf(\"Testing gpu index %u, %s\\n\", idx, name);\n    }\n\n    std::vector<uint32_t> left, right, isect;\n\n    // Check unconstrained cu set.\n    getHwIds(left);\n    printf(\"Expecting %u CUs, found %lu with HSA_CU_MASK_SKIP_INIT.\\n\", cu_count, left.size());\n    ASSERT_EQ(cu_count, left.size());\n    fini();\n    unsetenv(\"HSA_CU_MASK_SKIP_INIT\");\n\n    // Check fully enabled, but mask used, set.\n    setenv(\"HSA_CU_MASK\", (std::to_string(idx)+\":0-\"+std::to_string(cu_count-1)).c_str(), 1);\n    init();\n    getHwIds(right);\n    printf(\"Expecting %u CUs, found %lu with HSA_CU_MASK.\\n\", cu_count, right.size());\n    if(cu_count != right.size()) {\n      isect.resize(left.size());\n      auto isect_end = std::set_difference(left.begin(), left.end(), right.begin(), right.end(), isect.begin());\n      isect.resize(isect_end - isect.begin());\n      printf(\"Missing CUs: \");\n      for(auto cu : isect)\n        printf(\"%u \", cu);\n      printf(\"\\n\");\n    }\n    ASSERT_EQ(cu_count, right.size());\n    fini();\n    unsetenv(\"HSA_CU_MASK\");\n\n    // Check rocr default mask.\n    init();\n    getHwIds(right);\n    printf(\"Expecting %u CUs, found %lu.\\n\", cu_count, right.size());\n    if(cu_count != right.size()) {\n      isect.resize(left.size());\n      auto isect_end = std::set_difference(left.begin(), left.end(), right.begin(), right.end(), isect.begin());\n      isect.resize(isect_end - isect.begin());\n      printf(\"Missing CUs: \");\n      for(auto cu : isect)\n        printf(\"%u \", cu);\n      printf(\"\\n\");\n    }\n    ASSERT_EQ(cu_count, right.size());\n    fini();\n\n    std::vector<uint32_t> bits;\n    for(uint32_t i=0; i<cu_count; i++)\n      bits.push_back(i);\n    \n    std::vector<uint32_t> bitmask, resultmask;\n    uint32_t dwords = (cu_count + 31) / 32;\n\n    bitmask.resize(dwords);\n    resultmask.resize(dwords);\n\n    for(size_t iteration=0; iteration<RealIterationNum(); iteration++) {\n\n      auto setBits = [&](uint32_t start, uint32_t stop, std::vector<uint32_t>& array) {\n        assert(array.size() == dwords && \"Bitmask array has incorrect size.\");\n        for(uint32_t i=0; i<dwords; i++)\n          array[i] = 0;\n        for(uint32_t i=start; i<stop; i++) {\n          int dword = bits[i] / 32;\n          int offset = bits[i] % 32;\n          array[dword] |= (1 << offset);\n        }\n      };\n\n      auto getMasks = [&](uint32_t start, uint32_t stop, std::vector<uint32_t>& hw_ids) {\n        setBits(start, stop, bitmask);\n        err = hsa_amd_queue_cu_set_mask(q, dwords*32, &bitmask[0]);\n        if((err!=HSA_STATUS_SUCCESS) && (err!=(hsa_status_t)HSA_STATUS_CU_MASK_REDUCED))\n          CHECK(err);\n        err = hsa_amd_queue_cu_get_mask(q, dwords*32, &resultmask[0]);\n        CHECK(err);\n        getHwIds(hw_ids);\n      };\n\n      auto getIsect = [&]() {\n        isect.resize(left.size());\n        auto isect_end = std::set_intersection(left.begin(), left.end(), right.begin(), right.end(), isect.begin());\n        isect.resize(isect_end - isect.begin());\n      };\n\n      auto printMask = [](std::vector<uint32_t>& mask) {\n        printf(\"0x\");\n        for(size_t i=1; i<mask.size()+1; i++)\n          printf(\"%08X\", mask[mask.size()-i]);\n      };\n\n      auto printMasks = [&]() {\n        printf(\"Set mask: \");\n        printMask(bitmask);\n        printf(\"\\n\");\n        printf(\"Get mask: \");\n        printMask(resultmask);\n        printf(\"\\n\");\n      };\n\n      // CU set API check, no overlap\n      std::shuffle(bits.begin(), bits.end(), rand);\n      uint32_t split_index = (rand() % (cu_count - 2)) + 1;\n\n      init();\n\n      getMasks(0, split_index, left);\n      printMasks();\n      printf(\"Observed %lu CUs.\\n\", left.size());\n      for(uint32_t i=0; i<dwords; i++)\n        ASSERT_EQ(bitmask[i], resultmask[i]);\n      ASSERT_EQ(split_index, left.size());\n\n      getMasks(split_index, cu_count, right);\n      printMasks();\n      printf(\"Observed %lu CUs.\\n\", right.size());\n      for(uint32_t i=0; i<dwords; i++)\n        ASSERT_EQ(bitmask[i], resultmask[i]);\n      ASSERT_EQ(cu_count-split_index, right.size());\n\n      getIsect();\n      printf(\"Overlap of %lu CUs.\\n\", isect.size());\n      ASSERT_EQ(0u, isect.size());\n      \n      // CU set API check, overlap possible\n      uint32_t high_split_index = (rand() % (cu_count - 2)) + 1;\n\n      if(high_split_index < split_index)\n        std::swap(high_split_index, split_index);\n\n      getMasks(0, high_split_index, left);\n      printMasks();\n      printf(\"Observed %lu CUs.\\n\", left.size());\n      for(uint32_t i=0; i<dwords; i++)\n        ASSERT_EQ(bitmask[i], resultmask[i]);\n      ASSERT_EQ(high_split_index, left.size());\n\n      getMasks(split_index, cu_count, right);\n      printMasks();\n      printf(\"Observed %lu CUs.\\n\", right.size());\n      for(uint32_t i=0; i<dwords; i++)\n        ASSERT_EQ(bitmask[i], resultmask[i]);\n      ASSERT_EQ(cu_count-split_index, right.size());\n\n      getIsect();\n      printf(\"Overlap of %lu CUs.\\n\", isect.size());\n      ASSERT_EQ(high_split_index - split_index, isect.size());\n      \n      // HSA_CU_MASK check, default\n      fini();\n      \n      // Pick masking bits for env var\n      std::shuffle(bits.begin(), bits.end(), rand);\n      uint32_t mask_index = (rand() % (cu_count - 2)) + 1;\n      std::vector<uint32_t> env_mask(&bits[0], &bits[mask_index]);\n\n      // Convert to string range syntax\n      std::sort(env_mask.begin(), env_mask.end());\n      uint32_t start, stop;\n      start=stop=env_mask[0];\n      std::vector<std::string> ranges;\n      // Append invalid bit so that final loop will emit the last range.\n      env_mask.push_back(-1);\n      for(size_t j=1; j<env_mask.size(); j++) {\n        uint32_t index = env_mask[j];\n        if(index != stop+1) {\n          if(start==stop)\n            ranges.push_back(std::to_string(start));\n          else\n            ranges.push_back(std::to_string(start)+\"-\"+std::to_string(stop));\n          start=stop=index;\n        } else {\n          stop = index;\n        }\n      }\n      env_mask.pop_back();\n      // Shuffle ranges\n      std::shuffle(ranges.begin(), ranges.end(), rand);\n      // Assemble final env var string.\n      std::string env_var = std::to_string(idx) + \":\";\n      env_var += ranges[0];\n      for(uint32_t i=1; i<ranges.size(); i++)\n        env_var += \", \" + ranges[i];\n\n      // Set env var and check that default queues are masked.\n      //env_var = \"0:41-44, 104-107, 47-50, 67-68, 77-100, 61, 102, 19-24, 109, 70-75, 52-59, 63-65, 0-17, 27-39\";\n      setenv(\"HSA_CU_MASK\", env_var.c_str(), 1);\n      printf(\"HSA_CU_MASK = %s\\n\", env_var.c_str());\n      env_mask.clear();\n      env_mask.resize(dwords);\n      setBits(0, mask_index, env_mask);\n      printf(\"  HSA_CU_MASK => \");\n      printMask(env_mask);\n      printf(\"\\n\");\n\n      init();\n      \n      getHwIds(left);\n      printf(\"Expecting %u CUs, found %lu\\n\", mask_index, left.size());\n      ASSERT_EQ(left.size(), mask_index);\n\n      // Check that HSA_CU_MASK constrains the API\n      // Find at least partially enabled CU mask.\n      [&]() {\n        while(true) {\n          std::shuffle(bits.begin(), bits.end(), rand);\n          split_index = (rand() % (cu_count - 2)) + 1;\n          setBits(0, split_index, bitmask);\n          for(uint32_t i=0; i<dwords; i++) {\n            if((bitmask[i] & env_mask[i]) != 0)\n              return;\n          }\n        }\n      }();\n\n      getMasks(0, split_index, left);\n      printMasks();\n      printf(\"Observed %lu CUs.\\n\", left.size());\n      uint32_t enabledCus = 0;\n      for(uint32_t i=0; i<dwords; i++) {\n        bitmask[i] &= env_mask[i];\n        enabledCus += rocrtst::popcount(bitmask[i]);\n        ASSERT_EQ(bitmask[i], resultmask[i]);\n      }\n      ASSERT_EQ(enabledCus, left.size());\n      ASSERT_LE(enabledCus, mask_index);\n\n      fini();\n      unsetenv(\"HSA_CU_MASK\");\n\n      // Todo: Hex syntax.  Syntax errors.  Above hw limit bits.\n\n    }\n    idx++;\n  }\n\n  if(!mask_var.empty())\n    setenv(\"HSA_CU_MASK\", mask_var.c_str(), 1);\n  if(!mask_init_var.empty())\n    setenv(\"HSA_CU_MASK_SKIP_INIT\", mask_var.c_str(), 1);\n}\n"
  },
  {
    "path": "rocrtst/suites/functional/cu_masking.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2021-2021, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_FUNCTIONAL_CU_MASKING_H_\n#define ROCRTST_SUITES_FUNCTIONAL_CU_MASKING_H_\n#include <vector>\n\n#include \"suites/test_common/test_base.h\"\n#include \"common/base_rocr.h\"\n#include \"common/common.h\"\n\n// @Brief: This class is defined to measure the mean latency of enqueuing\n//  the packets to an empty kernel\n\nclass CU_Masking : public TestBase {\n public:\n  // @Brief: Constructor\n  explicit CU_Masking();\n\n  // @Brief: Destructor\n  virtual ~CU_Masking() {}\n\n  // @Brief: Set up the environment for the test\n  virtual void SetUp() { TestBase::SetupPrint(); }\n\n  // @Brief: Run the test case\n  virtual void Run();\n\n  // @Brief: Clean up and close the runtime\n  virtual void Close() { TestBase::ClosePrint(); }\n\n private:\n  // @Brief: Get actual iteration number\n  virtual size_t RealIterationNum() { return num_iteration(); }\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_CU_MASKING_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/deallocation_notifier.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n/* Test Name: deallocation_notifier\n *\n * Purpose: Verifies that deallocation callbacks are invoked prior to destruction,\n * are not retained between successive allocations, may be registered on non-base\n * addresses, are invoked exactly once, run concurrently with other APIs, and other\n * callbacks.\n *\n * Test Description:\n * Various interleavings of allocate, register callback, deregister callback, and deallocate.\n *\n * Expected Results: Callbacks should run before free returns.  Callbacks should trigger when\n * their allocation is released.  Free shoud deregister invoked callbacks.  Callbacks should not\n * be able to double free the allocation they monitor.  Callbacks should be able to execute\n * ROCr APIs including hsa_amd_memory_pool_allocate and hsa_amd_memory_pool_free, possibly\n * triggering other callbacks.\n *\n */\n#include \"suites/functional/deallocation_notifier.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\nstruct callback_status {\n  int callback_status = 0;\n  void* released_ptr = nullptr;\n};\n\nstatic callback_status notifiers[2];\nstatic hsa_amd_memory_pool_t pool;\n\n#define REGISTER(ptr, callback, i)                                                                 \\\n  do {                                                                                             \\\n    notifiers[i].callback_status = 0;                                                              \\\n    notifiers[i].released_ptr = ptr;                                                               \\\n    status = hsa_amd_register_deallocation_callback(ptr, callback, (void*)i);                      \\\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Register deallocation callback error.\";              \\\n  } while (false)\n\nstatic void call(void* ptr, void* user) {\n  size_t index = reinterpret_cast<size_t>(user);\n  ASSERT_EQ(ptr, notifiers[index].released_ptr) << \"Bad deallocation callback address\";\n  notifiers[index].callback_status = 1;\n}\n\nstatic void doublefree(void* ptr, void* user) {\n  call(ptr, user);\n\n  hsa_status_t status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_ERROR_INVALID_ALLOCATION, status) << \"Double free did not return an error.\";\n}\n\nstatic void recursive(void* ptr, void* user) {\n  ASSERT_EQ(0, user) << \"Wrong index.\";\n  call(ptr, user);\n\n  hsa_status_t status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, call, 1);\n  hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(1, notifiers[1].callback_status) << \"Callback not executed.\";\n}\n\nDeallocationNotifierTest::DeallocationNotifierTest() : TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"RocR Deallocation Notifier Test\");\n  set_description(\"Tests deallocation notification callbacks\");\n}\n\nDeallocationNotifierTest::~DeallocationNotifierTest(void) {}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid DeallocationNotifierTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  pool = device_pool();\n\n  return;\n}\n\nvoid DeallocationNotifierTest::Run(void) {\n// Compare required profile for this test case with what we're actually\n// running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n  TestDeallocationNotifier();\n}\n\nvoid DeallocationNotifierTest::DisplayTestInfo(void) { TestBase::DisplayTestInfo(); }\n\nvoid DeallocationNotifierTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid DeallocationNotifierTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\nvoid DeallocationNotifierTest::TestDeallocationNotifier(void) {\n  hsa_status_t status;\n\n  // Attempt register on null address.  Should fail.\n  void* ptr = nullptr;\n  status = hsa_amd_register_deallocation_callback(ptr, call, (void*)0xDEADBEEF);\n  ASSERT_EQ(HSA_STATUS_ERROR_INVALID_ARGUMENT, status) << \"Register deallocation callback error.\";\n\n  // Attempt register on bad address (ie one not known to ROCr).  Should fail.\n  ptr = malloc(4096);\n  status = hsa_amd_register_deallocation_callback(ptr, call, (void*)0xDEADBEEF);\n  free(ptr);\n  ASSERT_EQ(HSA_STATUS_ERROR_INVALID_ALLOCATION, status) << \"Register deallocation callback error.\";\n\n  // Allocate, register and free.  Callback should complete before free returns.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, call, 0);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n\n  // Re-allocate, free.  No callback should be invoked.\n  notifiers[0].callback_status = 0;\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(0, notifiers[0].callback_status) << \"Callback reused.\";\n\n  // Allocate, register with non-base address, free.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER((char*)ptr + 1024, call, 0);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n\n  // Allocate, Register, Deregister, Free.  No callback should be invoked.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER((char*)ptr + 1024, call, 0);\n  status = hsa_amd_deregister_deallocation_callback((char*)ptr + 1024, call);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Deregister deallocation callback error.\";\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(0, notifiers[0].callback_status) << \"Callback reused.\";\n\n  // Allocate, register, register another and free.  Callbacks should complete before free returns.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, call, 0);\n  REGISTER((char*)ptr + 1024, call, 1);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n  ASSERT_EQ(1, notifiers[1].callback_status) << \"Callback not executed.\";\n\n  // Repeat deregister.  Should error.\n  status = hsa_amd_deregister_deallocation_callback((char*)ptr + 1024, call);\n  ASSERT_EQ(HSA_STATUS_ERROR_INVALID_ARGUMENT, status) << \"Deregister deallocation callback error.\";\n\n  // Deregister from null.  Should error.\n  status = hsa_amd_deregister_deallocation_callback(nullptr, call);\n  ASSERT_EQ(HSA_STATUS_ERROR_INVALID_ARGUMENT, status) << \"Deregister deallocation callback error.\";\n\n  // Allocate fragment (second <2MB vram allocation), register, free.\n  void* ptr0;\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr0);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, call, 0);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n\n  // Allocate multiple fragments, register, free.  Free order should be respected by callbacks.\n  // Reuse fragment ptr0 from above.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, call, 0);\n  REGISTER(ptr0, call, 1);\n  status = hsa_amd_memory_pool_free(ptr0);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[1].callback_status) << \"Callback not executed.\";\n  ASSERT_EQ(0, notifiers[0].callback_status) << \"Callback executed improperly.\";\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n\n  // Allocate, register, free, with double free in callback.  Callbacks should not be able to free\n  // the triggering address again.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, doublefree, 0);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n\n  // Allocate, register, free, with allocate, register, free in callback.  Callbacks should nest and\n  // have access to HSA APIs.\n  status = hsa_amd_memory_pool_allocate(pool, 4096, 0, &ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory allocation failure.\";\n  REGISTER(ptr, recursive, 0);\n  status = hsa_amd_memory_pool_free(ptr);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status) << \"Memory free failure.\";\n  ASSERT_EQ(1, notifiers[0].callback_status) << \"Callback not executed.\";\n}\n"
  },
  {
    "path": "rocrtst/suites/functional/deallocation_notifier.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_FUNCTIONAL_DEALLOCATION_NOTIFIER_H_\n#define ROCRTST_SUITES_FUNCTIONAL_DEALLOCATION_NOTIFIER_H_\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass DeallocationNotifierTest : public TestBase {\n public:\n  DeallocationNotifierTest();\n\n  // @Brief: Destructor for the DeallocationNotifierTest class\n  virtual ~DeallocationNotifierTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Tests deallocation notifier callbacks.\n  void TestDeallocationNotifier(void);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_DEALLOCATION_NOTIFIER_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/debug_basic.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n#include \"suites/functional/debug_basic.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n#define M_ORDER 64\n#define M_GET(M, I, J) M[I * M_ORDER + J]\n#define M_SET(M, I, J, V) M[I * M_ORDER + J] = V\n\nstatic const uint32_t kNumBufferElements = 256;\ntypedef struct test_debug_data_t {\n  bool trap_triggered;\n  hsa_queue_t** queue_pointer;\n} test_debug_data;\n\nstatic void TestDebugTrap(hsa_status_t status, hsa_queue_t *source, void *data);\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nDebugBasicTest::DebugBasicTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  set_title(\"RocR Debug Function Tests\");\n  set_description(\"This series of tests check debug related functions.\");\n  set_kernel_file_name(\"vector_add_debug_trap_kernels.hsaco\");\n  set_kernel_name(\"vector_add_debug_trap\");\n}\n\nDebugBasicTest::~DebugBasicTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid DebugBasicTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid DebugBasicTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid DebugBasicTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid DebugBasicTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid DebugBasicTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\ntypedef struct __attribute__((aligned(16))) arguments_t {\n  const int *a;\n  const int *b;\n  const int *c;\n  int *d;\n  int *e;\n} arguments;\n\narguments *vectorAddKernArgs = NULL;\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintDebugSubtestHeader(const char *header) {\n  std::cout << \"  *** Debug Basic Subtest: \" << header << \" ***\" << std::endl;\n}\n\nvoid DebugBasicTest::VectorAddDebugTrapTest(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n  hsa_queue_t *queue = NULL;  // command queue\n  hsa_signal_t signal = {0};  // completion signal\n\n  int *M_IN0 = NULL;\n  int *M_IN1 = NULL;\n  int *M_RESULT_DEVICE = NULL;\n  int M_RESULT_HOST[M_ORDER * M_ORDER];\n\n  // get queue size\n  uint32_t queue_size = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  test_debug_data user_data{.trap_triggered = false,\n                            .queue_pointer = &queue};\n\n  // create queue\n  err = hsa_queue_create(gpuAgent,\n                         queue_size, HSA_QUEUE_TYPE_MULTI,\n                         TestDebugTrap, &user_data, 0, 0, &queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Find a memory pool that supports kernel arguments.\n  hsa_amd_memory_pool_t kernarg_pool;\n  err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                           rocrtst::GetKernArgMemoryPool,\n                                           &kernarg_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Get System Memory Pool on the cpuAgent to allocate host side buffers\n  hsa_amd_memory_pool_t global_pool;\n  err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                           rocrtst::GetGlobalMemoryPool,\n                                           &global_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // allocate input and output kernel arguments\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                     M_ORDER * M_ORDER * sizeof(int), 0,\n                                     reinterpret_cast<void**>(&M_IN0));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                     M_ORDER * M_ORDER * sizeof(int), 0,\n                                     reinterpret_cast<void**>(&M_IN1));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                     M_ORDER * M_ORDER * sizeof(int), 0,\n                                     reinterpret_cast<void**>(&M_RESULT_DEVICE));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // create kernel arguments\n  err = hsa_amd_memory_pool_allocate(kernarg_pool,\n                                     sizeof(arguments), 0,\n                                     reinterpret_cast<void**>(&vectorAddKernArgs));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Allow gpuAgent access to all allocated system memory.\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, M_IN0);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, M_IN1);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, M_RESULT_DEVICE);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, vectorAddKernArgs);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  memset(M_RESULT_HOST, 0, M_ORDER * M_ORDER * sizeof(int));\n  memset(M_RESULT_DEVICE, 0, M_ORDER * M_ORDER * sizeof(int));\n\n  vectorAddKernArgs->a = M_IN0;\n  vectorAddKernArgs->b = M_IN1;\n  vectorAddKernArgs->c = M_RESULT_DEVICE;\n\n  // initialize input and run on host\n  srand(time(NULL));\n  for (int i = 0; i < M_ORDER; ++i) {\n    for (int j = 0; j < M_ORDER; ++j) {\n      M_SET(M_IN0, i, j, (1 + rand() % 10));\n      M_SET(M_IN1, i, j, (1 + rand() % 10));\n    }\n  }\n\n  for (int i = 0; i < M_ORDER; ++i) {\n    for (int j = 0; j < M_ORDER; ++j) {\n      int s = M_GET(M_IN0, i, j) + M_GET(M_IN1, i, j);\n      M_SET(M_RESULT_HOST, i, j, s);\n    }\n  }\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill the dispatch packet with\n  // workgroup_size, grid_size, kernelArgs and completion signal\n  // Put it on the queue and launch the kernel by ringing the doorbell\n\n  // create completion signal\n  err = hsa_signal_create(1, 0, NULL, &signal);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // create aql packet\n  hsa_kernel_dispatch_packet_t aql;\n  memset(&aql, 0, sizeof(aql));\n\n  // initialize aql packet\n  aql.header = 0;\n  aql.setup = 1;\n  aql.workgroup_size_x = 64;\n  aql.workgroup_size_y = 1;\n  aql.workgroup_size_z = 1;\n  aql.grid_size_x = M_ORDER * M_ORDER;\n  aql.grid_size_y = 1;\n  aql.grid_size_z = 1;\n  aql.private_segment_size = 0;\n  aql.group_segment_size = 0;\n  aql.kernel_object = kernel_object();  // kernel_code;\n  aql.kernarg_address = vectorAddKernArgs;\n  aql.completion_signal = signal;\n\n  // const uint32_t queue_size = queue->size;\n  const uint32_t queue_mask = queue->size - 1;\n\n  // write to command queue\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n  rocrtst::WriteAQLToQueueLoc(queue, index, &aql);\n\n  uint32_t aql_header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n  aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n  aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n  void* q_base = queue->base_address;\n  rocrtst::AtomicSetPacketHeader(aql_header, aql.setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n  // ringdoor bell\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\n\n  // wait for the signal long enough for the debug trap event to happen\n  hsa_signal_value_t completion;\n  completion = hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                         0xffffff, HSA_WAIT_STATE_ACTIVE);\n\n  // completion signal should not be changed.\n  ASSERT_EQ(completion, 1);\n\n  // trap should be triggered\n  ASSERT_EQ(user_data.trap_triggered, true);\n\n  hsa_signal_store_relaxed(signal, 1);\n\n  if (M_IN0) { hsa_memory_free(M_IN0); }\n  if (M_IN1) { hsa_memory_free(M_IN1); }\n  if (M_RESULT_DEVICE) {hsa_memory_free(M_RESULT_DEVICE); }\n  if (vectorAddKernArgs) { hsa_memory_free(vectorAddKernArgs); }\n  if (signal.handle) { hsa_signal_destroy(signal); }\n  if (queue) { hsa_queue_destroy(queue); }\n  std::cout << kSubTestSeparator << std::endl;\n}\n\nvoid DebugBasicTest::VectorAddDebugTrapTest(void) {\n  hsa_status_t err;\n\n  PrintDebugSubtestHeader(\"VectorAddDebugTrapTest\");\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    VectorAddDebugTrapTest(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid TestDebugTrap(hsa_status_t status, hsa_queue_t *source, void *data) {\n  std::cout<< \"runtime catched trap instruction successfully\"<< std::endl;\n  ASSERT_NE(source, nullptr);\n  ASSERT_NE(data, nullptr);\n\n  test_debug_data *debug_data = reinterpret_cast<test_debug_data*>(data);\n  hsa_queue_t * queue  = *(debug_data->queue_pointer);\n  debug_data->trap_triggered = true;\n  // check the status\n  ASSERT_EQ(status, HSA_STATUS_ERROR_EXCEPTION);\n\n  // check the queue id and user data\n  ASSERT_EQ(source->id, queue->id);\n  std::cout<< \"custom queue error handler completed successfully\"<< std::endl;\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/debug_basic.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_DEBUG_BASIC_H_\n#define ROCRTST_SUITES_FUNCTIONAL_DEBUG_BASIC_H_\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass DebugBasicTest : public TestBase {\n public:\n    DebugBasicTest();\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~DebugBasicTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: This test verify that GPU is able to Read & write CPU memory\n  void VectorAddDebugTrapTest(void);\n\n private:\n  void VectorAddDebugTrapTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_DEBUG_BASIC_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/ipc.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n//\n//        Parent Process\n//  Allocate a block of gpu-local memory\n//  Print log message about allocation\n//  Acquire access to gpu-local memory\n//    This step may not be needed\n//  Obtain a IPC handle for gpu-local memory\n//  Print log message about getting IPC handle\n//  Initialize DWords of gpu-local memory with 0x01\n//  Print log message about updating gpu-local memory\n//  Create a Signal that is capable of IPC\n//  Obtain a IPC handle to signal\n//  Print log message about signalling Child process\n//  Signal Child process that it can proceed\n//  Print log message about waiting for signal from Child process\n//  Wait for Child processes signal\n//  Verify Child has updated DWords of gpu-local memory to 0x02\n//  Print log message about validation of gpu-local memory\n//  Set the DWords of gpu-local memory with 0x03\n//  Signal Child process that it can proceed  by setting signal to 3\n//  Wait for Child processes signal\n//  Verify Child has updated DWords of gpu-local memory to 0x04\n//  Print log message that IPC test passed\n//\n//        Child Process\n//  Print log message about waiting for signal from Parent process\n//  Wait/Yield for Parent process signal\n//  Validate Parent process signal is per expectation\n//  Attach to IPC memory handle shared by Parent process\n//  Print log message about successful acquisition of IPC memory handle\n//  Print log message about successful acquisition of IPC signal handle\n//  Verify Parent process has updated every DWord of Gpu buffer to 0x01\n//  Update every DWord of Gpu buffer with 0x02 value\n//  Print log message about validation of Gpu buffer state i.e every DWord has 0x01\n//  Register a callback using hsa_amd_signal_async_handler on the ipc signal\n//    - the callback function will update gpu-local memory DWords to 0x04\n//    - and update a local token to indicate that the callback happened.\n//  Signal the parent process that it can proceed by setting signal to 2\n//  Wait for callback function to update the local token.\n//  Signal the parent process that it can proceed by setting signal to 4\n//  Wait for parent to set signal to 0 to indicate that it can clean-up and exit.\n//\n// The comments provided below are focused more on the use of common rocrtst\n// utilities and boilerplate code, rather than the example app. itself.\n//\n\n#include <sys/mman.h>\n\n#include <algorithm>\n#include <vector>\n#include <atomic>\n\n#include \"suites/functional/ipc.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\n\nstruct callback_args {\n  hsa_agent_t host;\n  hsa_agent_t device;\n  hsa_amd_memory_pool_t cpu_pool;\n  hsa_amd_memory_pool_t gpu_pool;\n  size_t gpu_mem_granule;\n};\n\n// Wrap printf to add first or second process indicator\n#define PROCESS_LOG(format, ...)  { \\\n    if (verbosity() >= VERBOSE_STANDARD || !parentProcess_) { \\\n      fprintf(stdout, \"line:%d P%u: \" format, \\\n                   __LINE__, static_cast<int>(!parentProcess_), ##__VA_ARGS__); \\\n    } \\\n}\n\n// Fork safe ASSERT_EQ.\n#define MSG(y, msg, ...) msg\n#define Y(y, ...) y\n\n#define FORK_ASSERT_EQ(x, ...)                                                    \\\n  if ((x) != (Y(__VA_ARGS__))) {                                                  \\\n    if ((x) != (Y(__VA_ARGS__))) {                                                \\\n      std::cout << MSG(__VA_ARGS__, \"\");                                          \\\n      if (parentProcess_) {                                                       \\\n        shared_->parent_status = -1;                                              \\\n      } else {                                                                    \\\n        shared_->child_status = -1;                                               \\\n      }                                                                           \\\n      ASSERT_EQ(x, Y(__VA_ARGS__));                                               \\\n    }                                                                             \\\n  }\n\n#define USR_TRIGGERED_FAILURE(x, y, z)                                            \\\n  if (usr_fail_val_ == (z)) {                                                     \\\n    std::cout << \"Env value is: \" << z << std::endl;                              \\\n    std::cout << \"Return value before: \" << x << std::endl;                       \\\n    std::cout << \"Return value  after: \" << y << std::endl << std::flush;         \\\n    (x) = (y);                                                                    \\\n  }\n\nIPCTest::IPCTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"IPC Test\");\n  set_description(\"IPCTest verifies that the IPC feature of RocR is \"\n      \"functioning as expected. The test first forks off second process. The \"\n      \"2 processes share pointers to RocR allocated memory and also share \"\n      \"signal handles\");\n}\n\nIPCTest::~IPCTest(void) {\n}\n\n// See if the other process wrote an error value to the token; if not, write\n// the newVal to the token.\nstatic int CheckAndSetToken(std::atomic<int> *token, int newVal) {\n  if (*token == -1) {\n    return -1;\n  } else {\n    *token = newVal;\n  }\n\n  return 0;\n}\n\nstatic void ClearShared(Shared *s) {\n  s->token = 0;\n  s->count = 0;\n  s->size = 0;\n  s->child_status = 0;\n  s->parent_status = 0;\n  memset(&s->handle.handle, 0, sizeof(hsa_amd_ipc_memory_t));\n  memset(&s->signal_handle, 0, sizeof(hsa_amd_ipc_signal_t));\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid IPCTest::SetUp(void) {\n  hsa_status_t err;\n\n  // Allow user to trigger a failure\n  const char* env_val = getenv(\"ROCR_IPC_FAIL_KEY\");\n  if (env_val != NULL) {\n    usr_fail_val_ = atoi(env_val);\n  }\n\n  // We must fork process before doing HSA stuff, specifically, hsa_init, as\n  // each process needs to do this.\n  // Allocate linux shared_ memory.\n  shared_ = reinterpret_cast<Shared*>(\n      mmap(nullptr, sizeof(Shared), PROT_READ | PROT_WRITE,\n                                          MAP_SHARED | MAP_ANONYMOUS, -1, 0));\n  ASSERT_NE(shared_, MAP_FAILED) << \"mmap failed to allocated shared_ memory\";\n\n  // Initialize shared control block to zeros. The field \"token\"\n  // is used to signal state changes between the 2 processes.\n  ClearShared(shared_);\n\n  // Spawn second process and verify communication\n  child_ = 0;\n  child_ = fork();\n  ASSERT_NE(-1, child_) << \"fork failed\";\n  std::atomic<int> * token = &shared_->token;\n  if (child_ != 0) {\n    parentProcess_ = true;\n\n    // Signal to other process we are waiting, and then wait...\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n\n    PROCESS_LOG(\"Second process observed, handshake...\\n\");\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n\n  } else {\n    parentProcess_ = false;\n    set_verbosity(0);\n    PROCESS_LOG(\"Second process running.\\n\");\n\n    while (*token == 0) {\n      sched_yield();\n    }\n\n    int ret;\n    ret = CheckAndSetToken(token, 0);\n    ASSERT_EQ(0, ret) << \"Error detected in child process\\n\";\n    // Wait for handshake\n    while (*token == 0) {\n      sched_yield();\n    }\n    ret = CheckAndSetToken(token, 0);\n    ASSERT_EQ(0, ret) << \"Error detected in child process\\n\";\n  }\n  // TestBase::SetUp() will set HSA_ENABLE_INTERRUPT if enable_interrupt() is\n  // true, and call hsa_init(). It also prints the SetUp header.\n  TestBase::SetUp();\n\n  // SetDefaultAgents(this) will assign the first CPU and GPU found on\n  // iterating through the agents and assign them to cpu_device_ and\n  // gpu_device1_, respectively (cpu_device() and gpu_device1()). These\n  // BaseRocR member variables are used in some utilities. Additionally,\n  // SetDefaultAgents() checks the profile of the gpu and compares this\n  // to any required profile.\n  err = rocrtst::SetDefaultAgents(this);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Find and assign HSA_AMD_SEGMENT_GLOBAL pools for cpu, gpu and a kern_arg\n  // pool\n  err = rocrtst::SetPoolsTypical(this);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n// Update the size granularity for allocations\n#ifdef ROCRTST_EMULATOR_BUILD\n  gpu_mem_granule = 4;\n#else\n  err = hsa_amd_memory_pool_get_info(device_pool(), HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE,\n                                     &gpu_mem_granule);\n#endif\n\n  return;\n}\n\n// Do a few extra iterations as we toss out some of the inital and final\n// iterations when calculating statistics\nuint32_t IPCTest::RealIterationNum(void) {\n  return num_iteration() * 1.2 + 1;\n}\n\n/*\n * if the hsa_signal_value_t value matches sig_value, and\n * then set destination to\n * new value.\n */\nstruct signal_cb_handler_data {\n  IPCTest *obj;\n  hsa_signal_value_t exp_sig_value;\n  uint32_t exp_value;\n  uint32_t *destination;\n  uint32_t new_value;\n  std::atomic<int> token;\n};\n\nbool SignalCallbackHandler(hsa_signal_value_t value, void* arg) {\n  signal_cb_handler_data* cb_data = reinterpret_cast<signal_cb_handler_data*>(arg);\n  if (cb_data->exp_sig_value != value)\n    return false;\n\n  cb_data->obj->CheckAndFillBuffer(cb_data->destination, cb_data->exp_value, cb_data->new_value);\n  cb_data->token++;\n\n  /* return false to stop monitoring this callback */\n  return false;\n}\n\nvoid IPCTest::ChildProcessImpl() {\n\n  // Yield until shared token value changes i.e. is updated by parent.\n  // Validate parent's update is per expectation\n  PROCESS_LOG(\"Child: Waiting for parent process to signal\\n\");\n  while (shared_->token == 0) {\n    sched_yield();\n  }\n  if (shared_->token != 1) {\n    shared_->token = -1;\n  }\n  FORK_ASSERT_EQ(1, shared_->token, \"Child: Error detected in signaling token\\n\");\n  PROCESS_LOG(\"Child: Waking upon signal from parent process\\n\");\n\n  // List of devices involved in test. Gpu device is used\n  // to allocate buffer and signal that are part of an IPC\n  // transaction. Cpu is used in support of initialization\n  // of Gpu buffer\n  hsa_agent_t ag_list[2] = {*gpu_device1(), *cpu_device()};\n\n  // Attach to IPC memory handle shared by parent process\n  void* ipc_ptr;\n  hsa_status_t err;\n  err = hsa_amd_ipc_memory_attach(const_cast<hsa_amd_ipc_memory_t*>(&shared_->handle),\n                                  shared_->size, 1, ag_list, &ipc_ptr);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 200);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Child: Failure in attaching to IPC memory handle\\n\");\n  PROCESS_LOG(\"Child: Attached to IPC buffer shared by parent process\\n\");\n  PROCESS_LOG(\"Child: Address of buffer enabled for IPC: %p\\n\", ipc_ptr);\n\n  // Attach to IPC signal handle shared by parent process\n  hsa_signal_t ipc_signal;\n  err = hsa_amd_ipc_signal_attach(const_cast<hsa_amd_ipc_signal_t*>(&shared_->signal_handle),\n                                  &ipc_signal);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 201);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Child: Failure in attaching to IPC signal handle\\n\");\n  PROCESS_LOG(\"Child: Attached to IPC signal shared by parent process\\n\");\n\n  // Validate Gpu buffer is filled per expectation i.e. if so update\n  // per previously agreed upon value (first_val_ and second_val_)\n  CheckAndFillBuffer(reinterpret_cast<uint32_t*>(ipc_ptr), first_val_, second_val_);\n  PROCESS_LOG(\"Child: Confirmed DWord's of IPC buffer has: %d\\n\", first_val_);\n  PROCESS_LOG(\"Child: Updated DWord's of IPC buffer to: %d\\n\", second_val_);\n\n  // Register an async handler, we wait for parent process to set buffer value to\n  // third_val_. During the callback, SignalCallbackHandler  will set cb_result\n  // to fourth_val_ and increment cb_data->token\n  struct signal_cb_handler_data child_cb_data;\n  child_cb_data.obj = this;\n  child_cb_data.exp_sig_value = 3;\n  child_cb_data.exp_value = third_val_;\n  child_cb_data.destination = reinterpret_cast<uint32_t*>(ipc_ptr);\n  child_cb_data.new_value = fourth_val_;\n  child_cb_data.token = 0;\n\n  err = hsa_amd_signal_async_handler(ipc_signal, HSA_SIGNAL_CONDITION_GTE, 3, &SignalCallbackHandler, &child_cb_data);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 202);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Child: Failure registering async_handler to ipc_signal\\n\");\n  PROCESS_LOG(\"Child: [pid:%d] Attached async handler to IPC signal shared by parent process\\n\", getpid());\n\n  // Signal parent process to wake up and continue.\n  // The next time parent process updates ipc_signal, SignalCallbackHandler will\n  // be called\n  hsa_signal_store_release(ipc_signal, 2);\n\n  // Wait for SignalCallbackHandler to be called\n  while (child_cb_data.token <= 0)\n    sched_yield();\n\n  PROCESS_LOG(\"Child: Confirmed DWord's of IPC buffer has: %d\\n\", third_val_);\n  PROCESS_LOG(\"Child: Updated DWord's of IPC buffer to: %d\\n\", fourth_val_);\n\n  // Signal parent process to wake up and continue\n  hsa_signal_store_release(ipc_signal, 4);\n\n  hsa_signal_value_t ret = 1;\n  while(true) {\n    ret = hsa_signal_wait_acquire(ipc_signal, HSA_SIGNAL_CONDITION_LT, 0, timeout_, HSA_WAIT_STATE_BLOCKED);\n    if (shared_->child_status == -1) {\n      exit(0);\n    }\n    if (ret < 0) {\n      break;\n    }\n  }\n  USR_TRIGGERED_FAILURE(ret, HSA_STATUS_ERROR, 203);\n  FORK_ASSERT_EQ(-1, ret, \"Child: Expected signal value of 0, but got \" << ret << \"\\n\");\n\n  // Detach IPC memory that was used to test\n  err = hsa_amd_ipc_memory_detach(ipc_ptr);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 204);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Child: Failure in detaching IPC memory handle\\n\");\n  PROCESS_LOG(\"Child: Detached IPC memory handle\\n\");\n\n  // Reset the signal object and release acquired resources\n  err = hsa_signal_destroy(ipc_signal);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 205);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Child: Failure in destroying IPC signal handle\\n\");\n  PROCESS_LOG(\"Child: IPC test PASSED\\n\");\n}\n\nvoid IPCTest::ParentProcessImpl() {\n\n  // Ignoring the first allocation to exercise fragment allocation.\n  hsa_status_t err;\n  uint32_t* discard = NULL;\n  err = hsa_amd_memory_pool_allocate(device_pool(), gpu_mem_granule, 0,\n                                     reinterpret_cast<void**>(&discard));\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 100);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to allocate gpu memory\\n\");\n\n  // Allocate some VRAM that is used to test IPC\n  uint32_t* gpuBuf = NULL;\n  err = hsa_amd_memory_pool_allocate(device_pool(), gpu_mem_granule, 0,\n                                     reinterpret_cast<void**>(&gpuBuf));\n  PROCESS_LOG(\"Parent: Allocated framebuffer of size: %zu\\n\", gpu_mem_granule);\n  PROCESS_LOG(\"Parent: Address of allocated framebuffer: %p\\n\", gpuBuf);\n\n  // Free the test allocation of memory block\n  err = hsa_amd_memory_pool_free(discard);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 101);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to free gpu memory\\n\");\n\n  // List of devices involved in test. Gpu device is used\n  // to allocate buffer and signal that are part of an IPC\n  // transaction. Cpu is used in support of initialization\n  // of Gpu buffer\n  hsa_agent_t ag_list[2] = {*gpu_device1(), *cpu_device()};\n\n  // Grant access to buffer to participating devices\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, gpuBuf);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 102);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to get access to gpu memory\\n\");\n\n  // Update shared data structure's buffer related parameters\n  shared_->size = gpu_mem_granule;\n  shared_->count = gpu_mem_granule / sizeof(uint32_t);\n\n  // Initialize every DWord of IPC buffer with a value per previous\n  // agreement i.e. first_val_\n  err = hsa_amd_memory_fill(gpuBuf, first_val_, shared_->count);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 103);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to initialize gpu memory\\n\");\n  PROCESS_LOG(\"Parent: Initialized Dword's of framebuffer with: %d\\n\", first_val_);\n\n  // Create an IPC memory handle. IPC handle value is shared with\n  // child process via a shared data structure\n  err = hsa_amd_ipc_memory_create(gpuBuf, gpu_mem_granule,\n                                  const_cast<hsa_amd_ipc_memory_t*>(&shared_->handle));\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 104);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to create IPC memory handle\\n\");\n  PROCESS_LOG(\"Parent: Created IPC handle for framebuffer: %p\\n\", gpuBuf);\n\n  // Create a signal that is capable of IPC. Also obtain a IPC handle\n  // which is shared with child process via a shared data structure\n  hsa_signal_t ipc_signal;\n  err = hsa_amd_signal_create(1, 0, NULL, HSA_AMD_SIGNAL_IPC, &ipc_signal);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 105);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to create IPC signal\\n\");\n  err = hsa_amd_ipc_signal_create(ipc_signal,\n                                  const_cast<hsa_amd_ipc_signal_t*>(&shared_->signal_handle));\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 106);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to create IPC signal handle\\n\");\n  PROCESS_LOG(\"Parent: Created IPC handle associated with ipc_signal\\n\");\n\n  // Signal child process that the gpu buffer is ready to read.\n  PROCESS_LOG(\"Parent: Signalling child proces process\\n\");\n  CheckAndSetToken(&shared_->token, 1);\n  PROCESS_LOG(\"Parent: Waiting for signal from child process\\n\");\n\n  // Wait for child processs to signal. Child will update signal object\n  // value to TWO (2). Check signal value is per expectation\n  hsa_signal_value_t ret = 1;\n  while(true) {\n    ret = hsa_signal_wait_acquire(ipc_signal, HSA_SIGNAL_CONDITION_GTE, 2, timeout_, HSA_WAIT_STATE_BLOCKED);\n    if (shared_->child_status == -1) {\n      exit(0);\n    }\n    if (ret >= 2) {\n      break;\n    }\n  }\n  USR_TRIGGERED_FAILURE(ret, HSA_STATUS_ERROR, 107);\n  FORK_ASSERT_EQ(2, ret, \"Parent: Expected signal value of 2, but got \" << ret << \"\\n\");\n\n  // Verify child process has updated all DWords of buffer per\n  // previously agreed upon values (second_val_ and third_val_)\n  CheckAndFillBuffer(gpuBuf, second_val_, third_val_);\n  PROCESS_LOG(\"Parent: Confirmed DWord's of frambuffer has: %d\\n\", second_val_);\n  PROCESS_LOG(\"Parent: Updated DWord's of framebuffer to: %d\\n\", third_val_);\n\n  hsa_signal_store_relaxed(ipc_signal, 3);\n\n  while(true) {\n    ret = hsa_signal_wait_acquire(ipc_signal, HSA_SIGNAL_CONDITION_GTE, 4, timeout_, HSA_WAIT_STATE_BLOCKED);\n    if (shared_->child_status == -1) {\n      exit(0);\n    }\n    if (ret >= 4) {\n      break;\n    }\n  }\n\n  CheckAndFillBuffer(gpuBuf, fourth_val_, 0);\n  PROCESS_LOG(\"Parent: Confirmed DWord's of frambuffer has: %d\\n\", fourth_val_);\n\n  USR_TRIGGERED_FAILURE(ret, HSA_STATUS_ERROR, 108);\n  FORK_ASSERT_EQ(4, ret, \"Parent: Expected signal value of 4, but got \" << ret << \"\\n\");\n\n  // Reset the signal object and release acquired resources\n  hsa_signal_store_relaxed(ipc_signal, -1);\n  err = hsa_signal_destroy(ipc_signal);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 109);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failure in destroying IPC signal\\n\");\n  err = hsa_amd_memory_pool_free(gpuBuf);\n  USR_TRIGGERED_FAILURE(err, HSA_STATUS_ERROR, 110);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"Parent: Failed to free gpu memory\\n\");\n  PROCESS_LOG(\"Parent: IPC test PASSED\\n\");\n\n  // Wait for child process to terminate before exiting\n  int exit_status = 0;\n  waitpid(child_, &exit_status, 0);\n  munmap(shared_, sizeof(Shared));\n}\n\nvoid IPCTest::PrintVerboseMesg(void) {\n  // Collect names of GPU's\n  hsa_status_t err;\n  char name1[64] = {0};\n  char name2[64] = {0};\n  err = hsa_agent_get_info(*cpu_device(), HSA_AGENT_INFO_NAME, name1);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"hsa_agent_get_info() failed\\n\");\n  err = hsa_agent_get_info(*gpu_device1(), HSA_AGENT_INFO_NAME, name2);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err, \"hsa_agent_get_info() failed\\n\");\n\n  // Collect BDF information of GPU's\n  uint32_t loc1, loc2;\n  err = hsa_agent_get_info(*cpu_device(), (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &loc1);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  err = hsa_agent_get_info(*gpu_device1(), (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &loc2);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Print the name and BDF info about the devices\n  fprintf(stdout, \"Using: %s (%d) and %s (%d)\\n\", name1, loc1, name2, loc2);\n}\n\nvoid IPCTest::CheckAndFillBuffer(void* gpu_src_ptr, uint32_t exp_cur_val, uint32_t new_val) {\n  uint32_t* sysBuf;\n  hsa_status_t err;\n  hsa_signal_value_t sig;\n  hsa_signal_t copy_signal;\n\n  // Bind the size granularity of allocation\n  size_t sz = gpu_mem_granule;\n\n  // Allocate a signal to track copy progress\n  err = hsa_signal_create(1, 0, NULL, &copy_signal);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Allocate buffer in system memory to validate\n  err = hsa_amd_memory_pool_allocate(cpu_pool(), sz, 0, reinterpret_cast<void**>(&sysBuf));\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Enable access to buffer in system memory\n  hsa_agent_t ag_list[2] = {*gpu_device1(), *cpu_device()};\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, sysBuf);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Copy data to buffer in system memory\n  err = hsa_amd_memory_async_copy(sysBuf, *cpu_device(), gpu_src_ptr, *gpu_device1(), sz, 0, NULL,\n                                  copy_signal);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Wait for copy to complete\n  sig = hsa_signal_wait_relaxed(copy_signal,\n                   HSA_SIGNAL_CONDITION_LT, 1, -1, HSA_WAIT_STATE_BLOCKED);\n  FORK_ASSERT_EQ(0, sig, \"Expected signal 0, but got \" << sig << \"\\n\");\n\n  // Validate buffer has expected data\n  uint32_t count = sz / sizeof(uint32_t);\n  for (uint32_t idx = 0; idx < count; idx++) {\n    if (exp_cur_val != sysBuf[idx]) {\n      PROCESS_LOG(\"Validation failed: expected: %d observed: %d at index: %d\\n\",\n                  exp_cur_val, sysBuf[idx], idx);\n      FORK_ASSERT_EQ(exp_cur_val, sysBuf[idx]);\n    }\n    sysBuf[idx] = new_val;\n  }\n\n  // Reset copy signal and update buffer in Gpu with new value\n  hsa_signal_store_relaxed(copy_signal, 1);\n  err = hsa_amd_memory_async_copy(gpu_src_ptr, *gpu_device1(), sysBuf, *cpu_device(), sz, 0, NULL,\n                                  copy_signal);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Wait for copy to complete\n  sig = hsa_signal_wait_relaxed(copy_signal, HSA_SIGNAL_CONDITION_LT, 1, -1, HSA_WAIT_STATE_BLOCKED);\n  FORK_ASSERT_EQ(sig, 0, \"Expected signal 0, but got \" << sig << \"\\n\");\n\n  // Release resources allocated by this method\n  err = hsa_signal_destroy(copy_signal);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  err = hsa_amd_memory_pool_free(sysBuf);\n  FORK_ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n}\n\nvoid IPCTest::Run(void) {\n  TestBase::Run();\n\n  // Collect and print debug information\n  if (verbosity() >= VERBOSE_STANDARD) {\n    PrintVerboseMesg();\n  }\n\n  // Note: Close() (and hsa_shut_down()) will be called from main()\n  // processOne is true for parent process, false for child process\n  if (parentProcess_) {\n    ParentProcessImpl();\n  } else {\n    ChildProcessImpl();\n    exit(0);\n  }\n\n  return;\n}\n\nvoid IPCTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid IPCTest::DisplayResults(void) const {\n  TestBase::DisplayResults();\n  return;\n}\n\nvoid IPCTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n#undef PROCESS_LOG\n#undef FORK_ASSERT_EQ\n#undef MSG\n#undef Y\n"
  },
  {
    "path": "rocrtst/suites/functional/ipc.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_FUNCTIONAL_IPC_H_\n#define ROCRTST_SUITES_FUNCTIONAL_IPC_H_\n\n#include <sys/types.h>\n#include <unistd.h>\n#include <atomic>\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nstruct Shared {\n  std::atomic<int> token;\n  std::atomic<int> count;\n  std::atomic<size_t> size;\n  std::atomic<int> child_status;\n  std::atomic<int> parent_status;\n  hsa_amd_ipc_memory_t handle;\n  hsa_amd_ipc_signal_t signal_handle;\n};\n\nclass IPCTest : public TestBase {\n public:\n    IPCTest();\n\n  // @Brief: Destructor for test case of TestExample\n  virtual ~IPCTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Implements child process exclusive logic\n  void ChildProcessImpl();\n\n  // @Brief: Implements parent process exclusive logic\n  void ParentProcessImpl();\n\n  // @Brief: Implements the check to see if buffer has expected\n  // value if so updates it with new values\n  void CheckAndFillBuffer(void* gpu_src_ptr, uint32_t exp_cur_val, uint32_t new_val);\n\n private:\n  // @Brief: Bind number of iterations to run per user specification\n  uint32_t RealIterationNum(void);\n\n  // @Brief: Collect and print verbose messages to enable debugging\n  void PrintVerboseMesg(void);\n\n  // @Brief: Values used to initialize framebuffer that is shared\n  uint32_t first_val_ = 0x01;\n  uint32_t second_val_ = 0x02;\n  uint32_t third_val_ = 0x03;\n  uint32_t fourth_val_ = 0x04;\n  uint32_t fifth_val_ = 0x05;\n\n  int child_;\n  Shared* shared_;\n  bool parentProcess_;\n  size_t gpu_mem_granule;\n\n  // Supports user triggered failure\n  int32_t usr_fail_val_ = 0xFFFFFFFF;\n\n  // Specifies timeout period for parent/child processes\n  int32_t timeout_ = 0x20000;\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_IPC_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_access.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n#include \"suites/functional/memory_access.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\n\n\nMemoryAccessTest::MemoryAccessTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  set_title(\"RocR Memory Access Tests\");\n  set_description(\"This series of tests check memory allocation\"\n    \"on GPU and CPU, i.e. GPU access to system memory \"\n    \"and CPU access to GPU memory.\");\n}\n\nMemoryAccessTest::~MemoryAccessTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryAccessTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid MemoryAccessTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryAccessTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAccessTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryAccessTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n\n\n\ntypedef struct  __attribute__ ((aligned(16)))  args_t {\n     int *a;\n     int *b;\n     int *c;\n  } args;\n\n  args *kernArgs = NULL;\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Subtest: \" << header << \" ***\" << std::endl;\n}\n\n#if ROCRTST_EMULATOR_BUILD\nstatic const int kMemoryAllocSize = 8;\n#else\nstatic const int kMemoryAllocSize = 1024;\n#endif\n\n\n// Test to check GPU can read & write to system memory\nvoid MemoryAccessTest::GPUAccessToCPUMemoryTest(hsa_agent_t cpuAgent,\n                                                   hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Get Global Memory Pool on the gpuAgent to allocate gpu buffers\n  hsa_amd_memory_pool_t gpu_pool;\n  err = hsa_amd_agent_iterate_memory_pools(gpuAgent,\n                                            rocrtst::GetGlobalMemoryPool,\n                                            &gpu_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  hsa_amd_memory_pool_access_t access;\n  hsa_amd_agent_memory_pool_get_info(cpuAgent, gpu_pool,\n                                       HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                       &access);\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    // hsa objects\n    hsa_queue_t *queue = NULL;  // command queue\n    hsa_signal_t signal = {0};  // completion signal\n\n\n    // get queue size\n    uint32_t queue_size = 0;\n    err = hsa_agent_get_info(gpuAgent,\n                                HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                              queue_size, HSA_QUEUE_TYPE_MULTI,\n                              NULL, NULL, 0, 0, &queue);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Get System Memory Pool on the cpuAgent to allocate host side buffers\n    hsa_amd_memory_pool_t global_pool;\n    err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                              rocrtst::GetGlobalMemoryPool,\n                                              &global_pool);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n\n    // Find a memory pool that supports kernel arguments.\n    hsa_amd_memory_pool_t kernarg_pool;\n    err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                              rocrtst::GetKernArgMemoryPool,\n                                              &kernarg_pool);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Allocate the host side buffers\n    // (sys_data,dup_sys_data,cpuResult,kernArg) on system memory\n    int *sys_data = NULL;\n    int *dup_sys_data = NULL;\n    int *cpuResult = NULL;\n    int *gpuResult = NULL;\n\n    err = hsa_amd_memory_pool_allocate(global_pool,\n                                      kMemoryAllocSize*sizeof(int), 0,\n                                      reinterpret_cast<void **>(&cpuResult));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    err = hsa_amd_memory_pool_allocate(global_pool,\n                                      kMemoryAllocSize*sizeof(int), 0,\n                                      reinterpret_cast<void **>(&sys_data));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    err = hsa_amd_memory_pool_allocate(global_pool,\n                                      kMemoryAllocSize*sizeof(int), 0,\n                                      reinterpret_cast<void **>(&dup_sys_data));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n    // Allocate the kernel argument buffer from the kernarg_pool.\n    err = hsa_amd_memory_pool_allocate(kernarg_pool, sizeof(args_t), 0,\n                                        reinterpret_cast<void **>(&kernArgs));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // initialize the host buffers\n    for (int i = 0; i < kMemoryAllocSize; ++i) {\n      unsigned int seed = time(NULL);\n      sys_data[i] = 1 + rand_r(&seed) % 1;\n      dup_sys_data[i] = sys_data[i];\n    }\n\n    memset(cpuResult, 0, kMemoryAllocSize * sizeof(int));\n\n    // for the dGPU, we have coarse grained local memory,\n    // so allocate memory for it on the GPU's GLOBAL segment .\n\n    // Get local memory of GPU to allocate device side buffers\n\n    err = hsa_amd_memory_pool_allocate(gpu_pool,\n      kMemoryAllocSize*sizeof(int), 0, reinterpret_cast<void **>(&gpuResult));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n    // Allow cpuAgent access to all allocated GPU memory.\n    err = hsa_amd_agents_allow_access(1, &cpuAgent, NULL, gpuResult);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    memset(gpuResult, 0, kMemoryAllocSize * sizeof(int));\n\n    // Allow gpuAgent access to all allocated system memory.\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, cpuResult);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, sys_data);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, dup_sys_data);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, kernArgs);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    kernArgs->a = sys_data;\n    kernArgs->b = cpuResult;  // system memory passed to gpu for write\n    kernArgs->c = gpuResult;  // gpu memory to verify that gpu read system data\n\n\n    // Create the executable, get symbol by name and load the code object\n    set_kernel_file_name(\"gpuReadWrite_kernels.hsaco\");\n    set_kernel_name(\"gpuReadWrite\");\n    err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Fill the dispatch packet with\n    // workgroup_size, grid_size, kernelArgs and completion signal\n    // Put it on the queue and launch the kernel by ringing the doorbell\n\n    // create completion signal\n    err = hsa_signal_create(1, 0, NULL, &signal);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // create aql packet\n    hsa_kernel_dispatch_packet_t aql;\n    memset(&aql, 0, sizeof(aql));\n\n    // initialize aql packet\n    aql.workgroup_size_x = 256;\n    aql.workgroup_size_y = 1;\n    aql.workgroup_size_z = 1;\n    aql.grid_size_x = kMemoryAllocSize;\n    aql.grid_size_y = 1;\n    aql.grid_size_z = 1;\n    aql.private_segment_size = 0;\n    aql.group_segment_size = 0;\n    aql.kernel_object = kernel_object();  // kernel_code;\n    aql.kernarg_address = kernArgs;\n    aql.completion_signal = signal;\n\n    // const uint32_t queue_size = queue->size;\n    const uint32_t queue_mask = queue->size - 1;\n\n    // write to command queue\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue, index, &aql);\n\n    hsa_kernel_dispatch_packet_t *q_base_addr =\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>(queue->base_address);\n    rocrtst::AtomicSetPacketHeader(\n        (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n           (1 << HSA_PACKET_HEADER_BARRIER) |\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE) |\n           (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE),\n                  (1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS),\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                          (&q_base_addr[index & queue_mask]));\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\n    // wait for the signal and reset it for future use\n    while (hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                      (uint64_t)-1, HSA_WAIT_STATE_ACTIVE)) { }\n    hsa_signal_store_relaxed(signal, 1);\n\n    // compare device and host side results\n    if (verbosity() > 0) {\n      std::cout<< \"check gpu has read the system memory\"<< std::endl;\n    }\n    for (int i = 0; i < kMemoryAllocSize; ++i) {\n      ASSERT_EQ(gpuResult[i], dup_sys_data[i]);\n    }\n\n    if (verbosity() > 0) {\n      std::cout<< \"gpu has read the system memory successfully\"<< std::endl;\n      std::cout<< \"check gpu has written to system memory\"<< std::endl;\n    }\n    for (int i = 0; i < kMemoryAllocSize; ++i) {\n      ASSERT_EQ(cpuResult[i], i);\n    }\n\n    if (verbosity() > 0) {\n      std::cout<< \"gpu has written to system memory successfully\"<< std::endl;\n    }\n\n    if (sys_data) { hsa_amd_memory_pool_free(sys_data); }\n    if (dup_sys_data) { hsa_amd_memory_pool_free(dup_sys_data); }\n    if (cpuResult) {hsa_amd_memory_pool_free(cpuResult); }\n    if (gpuResult) {hsa_amd_memory_pool_free(gpuResult); }\n    if (kernArgs) { hsa_amd_memory_pool_free(kernArgs); }\n    if (signal.handle) { hsa_signal_destroy(signal); }\n    if (queue) { hsa_queue_destroy(queue); }\n  } else {\n    if (verbosity() > 0) {\n      std::cout<< \"Test not applicable as system is not large bar.\"\n                   \"Skipping.\"<< std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n}\n\n// Test to check cpu can read & write to GPU memory\nvoid MemoryAccessTest::CPUAccessToGPUMemoryTest(hsa_agent_t cpuAgent,\n                                                 hsa_agent_t gpuAgent,\n                                                 hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (pool_i.segment == HSA_AMD_SEGMENT_GLOBAL &&\n        pool_i.global_flag == HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED) {\n    hsa_amd_memory_pool_access_t access;\n    hsa_amd_agent_memory_pool_get_info(cpuAgent, pool,\n                                         HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                         &access);\n    if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n      if (!pool_i.alloc_allowed || pool_i.alloc_granule == 0 ||\n                                           pool_i.alloc_alignment == 0) {\n        if (verbosity() > 0) {\n          std::cout << \"  Test not applicable. Skipping.\" << std::endl;\n          std::cout << kSubTestSeparator << std::endl;\n        }\n        return;\n      }\n\n\n      auto gran_sz = pool_i.alloc_granule;\n      auto pool_sz = pool_i.size / gran_sz;\n      auto max_alloc_size = pool_sz/2;\n      unsigned int max_element = max_alloc_size/sizeof(unsigned int);\n      unsigned int *gpu_data;\n      unsigned int *sys_data;\n      sys_data = (unsigned int*)malloc(max_alloc_size);\n\n      ASSERT_NE(sys_data, nullptr);\n\n      for (unsigned int i = 0; i < max_element; ++i) {\n        sys_data[i] = i;\n      }\n      // err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, sys_data);\n      // EXPECT_EQ(err, HSA_STATUS_SUCCESS);\n      err = hsa_amd_memory_pool_allocate(pool, max_alloc_size, 0,\n                                          reinterpret_cast<void**>(&gpu_data));\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n      /*\n      if (err == HSA_STATUS_ERROR) {\n        err = hsa_amd_memory_pool_free(gpu_data);\n      }*/\n\n      err = hsa_amd_agents_allow_access(1, &cpuAgent, NULL, gpu_data);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n      // EXPECT_EQ(HSA_STATUS_SUCCESS, err);\n\n      // Verify CPU can read & write to GPU memory\n      std::cout<< \"Verify CPU can read & write to GPU memory\"<< std::endl;\n      for (unsigned int i = 0; i < max_element; ++i) {\n        gpu_data[i] = i;  // Write to gpu memory directly\n      }\n\n     for (unsigned int  i = 0; i < max_element; ++i) {\n       if (sys_data[i] != gpu_data[i]) {  // Reading GPU memory\n            fprintf(stdout, \"Values not mathing !! sys_data[%d]:%d ,\"\n                \"gpu_data[%d]\\n\", sys_data[i], i, gpu_data[i]);\n       }\n     }\n     std::cout<< \"CPU have read & write to GPU memory successfully\"<< std::endl;\n     err = hsa_amd_memory_pool_free(gpu_data);\n     free(sys_data);\n     } else {\n        if (verbosity() > 0) {\n          std::cout<< \"Test not applicable as system is not large bar.\"\n                         \"Skipping.\"<< std::endl;\n          std::cout << kSubTestSeparator << std::endl;\n        }\n        return;\n    }\n  }\n}\n\n\nvoid MemoryAccessTest::CPUAccessToGPUMemoryTest(void) {\n  hsa_status_t err;\n\n  PrintMemorySubtestHeader(\"CPUAccessToGPUMemoryTest in Memory Pools\");\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    hsa_amd_memory_pool_t gpu_pool;\n    memset(&gpu_pool, 0, sizeof(gpu_pool));\n    err = hsa_amd_agent_iterate_memory_pools(gpus[i],\n                                              rocrtst::GetGlobalMemoryPool,\n                                              &gpu_pool);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    if (gpu_pool.handle == 0) {\n      std::cout << \"no global mempool in gpu agent\" << std::endl;\n      return;\n    }\n    CPUAccessToGPUMemoryTest(cpus[0], gpus[i], gpu_pool);\n  }\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryAccessTest::GPUAccessToCPUMemoryTest(void) {\n  hsa_status_t err;\n\n  PrintMemorySubtestHeader(\"GPUAccessToCPUMemoryTest in Memory Pools\");\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    GPUAccessToCPUMemoryTest(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_access.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_MEMORY_ACCESS_H_\n#define ROCRTST_SUITES_FUNCTIONAL_MEMORY_ACCESS_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass MemoryAccessTest : public TestBase {\n public:\n    MemoryAccessTest();\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryAccessTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n\n  // @Brief: This test verify that CPU is able to Read & write GPU memory\n  void CPUAccessToGPUMemoryTest(void);\n\n  // @Brief: This test verify that GPU is able to Read & write CPU memory\n  void GPUAccessToCPUMemoryTest(void);\n\n\n private:\n  void CPUAccessToGPUMemoryTest(hsa_agent_t cpuAgent,\n                                                   hsa_agent_t gpuAgent,\n                                                   hsa_amd_memory_pool_t pool);\n  void GPUAccessToCPUMemoryTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_MEMORY_ACCESS_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_alignment.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n#include \"suites/functional/memory_alignment.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"common/concurrent_utils.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n\nstatic const uint32_t kNumThreads = 4096;\n\ntypedef struct control_block {\n    hsa_amd_memory_pool_t* pool;\n} cb_t;\n\n// Callback function which will call upon when need\n// to allocate memory from the pool in the thread.\nstatic void CallbackVerifyPoolAlignmendFunc(void *data) {\n  hsa_status_t err;\n  cb_t *cb = reinterpret_cast<cb_t*>(data);\n\n  rocrtst::pool_info_t info;\n  memset(&info, 0, sizeof(rocrtst::pool_info_t));\n  err = rocrtst::AcquirePoolInfo(*(cb->pool), &info);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  if (info.alloc_allowed) {\n    // Get the allocated alignment size\n    size_t alignment_size = info.alloc_alignment;\n    EXPECT_TRUE(alignment_size);\n    // Verifies the alignment attribute is a power of 2\n    if (info.size != 0) {\n      EXPECT_TRUE((alignment_size&&(!(alignment_size&(alignment_size-1)))));\n    }\n  }\n  return;\n}\n\n\nMemoryAlignmentTest::MemoryAlignmentTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  set_title(\"RocR Memory Alignment Test\");\n  set_description(\" This test verifies that each memory pool of the agent that\"\n  \" has HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED alloc memory, It is \"\n  \" aligned as specified by the HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT\"\n  \" and has the alignment attribute is a power of 2.\");\n}\n\nMemoryAlignmentTest::~MemoryAlignmentTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryAlignmentTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid MemoryAlignmentTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryAlignmentTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAlignmentTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryAlignmentTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Functional Subtest: \" << header << \" ***\" << std::endl;\n}\n\nstatic void PrintAgentNameAndType(hsa_agent_t agent) {\n  hsa_status_t err;\n\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  std::cout << \"  Agent: \" << ag_name << \" (\";\n  switch (ag_type) {\n    case HSA_DEVICE_TYPE_CPU:\n      std::cout << \"CPU)\";\n      break;\n    case HSA_DEVICE_TYPE_GPU:\n      std::cout << \"GPU)\";\n      break;\n    case HSA_DEVICE_TYPE_DSP:\n      std::cout << \"DSP)\";\n      break;\n    case HSA_DEVICE_TYPE_AIE:\n      std::cout << \"AIE)\";\n      break;\n    }\n  std::cout << std::endl;\n  return;\n}\n\n\n\nvoid MemoryAlignmentTest::MemoryPoolAlignment(hsa_agent_t agent,\n                                                hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  if (pool_i.alloc_allowed) {\n    // Get the allocated alignment size\n    size_t alignment_size = pool_i.alloc_alignment;\n    EXPECT_TRUE(alignment_size);\n    // Verifies the alignment attribute is a power of 2\n    if (pool_i.size != 0) {\n      EXPECT_TRUE((alignment_size&&(!(alignment_size&(alignment_size-1)))));\n    }\n\n    // verifies that alignment attribute is a power of 2 in different threads\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreads);\n    // The control blocks are used to pass data to the threads\n    uint32_t kk;\n    cb_t cb[kNumThreads];\n    for (kk = 0; kk < kNumThreads; kk++) {\n      cb[kk].pool = &pool;\n      rocrtst::TestGroupAdd(tg_concurrent, &CallbackVerifyPoolAlignmendFunc, &cb[kk], 1);\n    }\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n  }\n  return;\n}\n\n\nvoid MemoryAlignmentTest::MemoryPoolAlignment(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryPoolAlignment in Basic func & Stress Test\");\n  }\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryPoolAlignment(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_alignment.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALIGNMENT_H_\n#define ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALIGNMENT_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\n\nclass MemoryAlignmentTest : public TestBase {\n public:\n    MemoryAlignmentTest();\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryAlignmentTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void MemoryPoolAlignment(void);\n\n\n private:\n  void MemoryPoolAlignment(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALIGNMENT_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_allocation.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <string>\n#include <memory>\n\n#include \"suites/functional/memory_allocation.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\nstatic const int kValue = 5;\n\n\nMemoryAllocationTest::MemoryAllocationTest(bool launch_GroupMemory,\n                                           bool launch_BasicAllocateFree) : TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  std::string name;\n  std::string desc;\n\n  name = \"RocR Memory Test \";\n  if (launch_GroupMemory) {\n    name += \" For Kernel Dynamic Memory Alocation\";\n    desc += \" This test Allocate group memory in kernel dynamically.\";\n  } else if (launch_BasicAllocateFree) {\n    name += \" For BasicAllocateFree\";\n    desc += \" This test Allocate And free Memory on all the availble pool \"\n            \" on which allocation is allowed on RocR Agents.\";\n  }\n  set_title(name);\n  set_description(desc);\n\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n}\n\nMemoryAllocationTest::~MemoryAllocationTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryAllocationTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  return;\n}\n\nvoid MemoryAllocationTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryAllocationTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAllocationTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryAllocationTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\nvoid MemoryAllocationTest::WriteAQLPktToQueue(hsa_queue_t* q) {\n  void* queue_base = q->base_address;\n  const uint32_t queue_mask = q->size - 1;\n  uint64_t index = hsa_queue_add_write_index_relaxed(q, 1);\n\n      reinterpret_cast<hsa_kernel_dispatch_packet_t *>(\n                                     queue_base)[index & queue_mask] = aql();\n}\n\n\n\n\n\ntypedef struct  __attribute__ ((aligned(16)))  args_t {\n     uint32_t *a;\n     uint32_t *b;\n     uint32_t grp_offset;\n     uint32_t count;\n  } args;\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Allocation  Test: \" << header << \" ***\" << std::endl;\n}\n\nstatic const int kMemoryAllocSize = 1024;\n\nvoid MemoryAllocationTest::GroupMemoryDynamicAllocation(hsa_agent_t cpuAgent,\n                                                   hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Get Global Memory Pool on the gpuAgent to allocate gpu buffers\n  hsa_amd_memory_pool_t gpu_pool;\n  err = hsa_amd_agent_iterate_memory_pools(gpuAgent,\n                                            rocrtst::GetGlobalMemoryPool,\n                                            &gpu_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  hsa_amd_memory_pool_access_t access;\n  hsa_amd_agent_memory_pool_get_info(cpuAgent, gpu_pool,\n                                       HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                       &access);\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    // hsa objects\n    hsa_queue_t *queue = NULL;  // command queue\n\n    // get queue size\n    uint32_t queue_size = 0;\n    err = hsa_agent_get_info(gpuAgent,\n                                HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                              queue_size, HSA_QUEUE_TYPE_MULTI,\n                              NULL, NULL, 0, 0, &queue);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Get System Memory Pool on the cpuAgent to allocate host side buffers\n    hsa_amd_memory_pool_t global_pool;\n    err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                              rocrtst::GetGlobalMemoryPool,\n                                              &global_pool);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Find a memory pool that supports kernel arguments.\n    hsa_amd_memory_pool_t kernarg_pool;\n    err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                              rocrtst::GetKernArgMemoryPool,\n                                              &kernarg_pool);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Allocate the host side buffers\n    // (Indata,kernArg) on system memory\n    uint32_t *Indata = NULL;\n    args *kernArgs = NULL;\n\n    err = hsa_amd_memory_pool_allocate(global_pool,\n                                      kMemoryAllocSize*sizeof(uint32_t), 0,\n                                      reinterpret_cast<void **>(&Indata));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n    // Allocate the kernel argument buffer from the kernarg_pool.\n    err = hsa_amd_memory_pool_allocate(kernarg_pool, sizeof(args_t), 0,\n                                        reinterpret_cast<void **>(&kernArgs));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // initialize the host buffers\n    for (int i = 0; i < kMemoryAllocSize; ++i) {\n      // unsigned int seed = time(NULL);\n      Indata[i] = i;\n    }\n\n    // for the dGPU, we have coarse grained local memory,\n    // so allocate memory for it on the GPU's GLOBAL segment .\n\n    // Get local memory of GPU to allocate device side buffers\n    uint32_t *OutData = NULL;\n    err = hsa_amd_memory_pool_allocate(gpu_pool, kMemoryAllocSize*sizeof(uint32_t), 0,\n                                        reinterpret_cast<void **>(&OutData));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n    // Allow cpuAgent access to all allocated GPU memory.\n    err = hsa_amd_agents_allow_access(1, &cpuAgent, NULL, OutData);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    memset(OutData, 0, kMemoryAllocSize * sizeof(int));\n\n    // Allow gpuAgent access to all allocated system memory.\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, Indata);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, kernArgs);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    uint32_t grp_offset = group_segment_size();\n    kernArgs->a = Indata;\n    // gpu memory where data will be copied from dynamically group memory\n    kernArgs->b = OutData;\n    kernArgs->grp_offset = grp_offset;\n    kernArgs->count = kMemoryAllocSize;\n\n    // Fill up the kernel packet except header\n    err = rocrtst::InitializeAQLPacket(this, &aql());\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    // Create the executable, get symbol by name and load the code object\n    set_kernel_file_name(\"groupMemoryDynamic_kernels.hsaco\");\n    set_kernel_name(\"group_memory_dynamic\");\n    err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // The total byte size of group memory, static + dynamic\n    uint32_t total_grp_byte_size = group_segment_size() + kMemoryAllocSize * sizeof(uint32_t);\n    if (verbosity() > 0) {\n      std::cout << \"aql.total_grp_byte_size\" << total_grp_byte_size << std::endl;\n    }\n\n    // Fill up the kernel packet except header\n    err = rocrtst::InitializeAQLPacket(this, &aql());\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    aql().workgroup_size_x = 256;\n    aql().workgroup_size_y = 1;\n    aql().workgroup_size_z = 1;\n    aql().grid_size_y = 1;\n    aql().grid_size_z = 1;\n    aql().private_segment_size = 0;\n    aql().grid_size_x = kMemoryAllocSize;\n    aql().group_segment_size = total_grp_byte_size;\n    aql().kernel_object = kernel_object();\n    aql().kernarg_address = kernArgs;\n\n    const uint32_t queue_mask = queue->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n    // This function simply copies the data we've collected so far into our\n    // local AQL packet, except the the setup and header fields.\n    rocrtst::WriteAQLToQueueLoc(queue, index, &aql());\n\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    void* q_base = queue->base_address;\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\n\n    // wait for the signal and reset it for future use\n    while (hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                      (uint64_t)-1, HSA_WAIT_STATE_ACTIVE)) { }\n\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n\n    // compare Results\n    for (int i = 0; i < kMemoryAllocSize; ++i) {\n      if (verbosity() > 0) {\n        // std::cout<< i << \"OutData[i]\" << OutData[i] << \"Indata[i]\" << Indata[i] <<std::endl;\n      }\n      ASSERT_EQ(OutData[i], Indata[i]);\n    }\n    if (Indata) { hsa_amd_memory_pool_free(Indata); }\n    if (OutData) { hsa_amd_memory_pool_free(OutData); }\n    if (kernArgs) { hsa_amd_memory_pool_free(kernArgs); }\n    if (queue) { hsa_queue_destroy(queue); }\n  } else {\n    if (verbosity() > 0) {\n      std::cout<< \"Test not applicable as system is not large bar.\"\n                   \"Skipping.\"<< std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n}\n\n\n\nvoid MemoryAllocationTest::GroupMemoryDynamicAllocation(void) {\n  hsa_status_t err;\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"Memory Group dynamic allocation\");\n  }\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    GroupMemoryDynamicAllocation(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n\nstatic void PrintAgentNameAndType(hsa_agent_t agent) {\n  hsa_status_t err;\n\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  std::cout << \"  Agent: \" << ag_name << \" (\";\n  switch (ag_type) {\n    case HSA_DEVICE_TYPE_CPU:\n      std::cout << \"CPU)\";\n      break;\n    case HSA_DEVICE_TYPE_GPU:\n      std::cout << \"GPU)\";\n      break;\n    case HSA_DEVICE_TYPE_DSP:\n      std::cout << \"DSP)\";\n      break;\n    case HSA_DEVICE_TYPE_AIE:\n      std::cout << \"AIE)\";\n      break;\n    }\n  std::cout << std::endl;\n  return;\n}\n\nstatic void PrintSegmentNameAndType(uint32_t segment) {\n  switch (segment) {\n    case HSA_AMD_SEGMENT_GLOBAL:\n      std::cout << \"  GLOBAL SEGMENT\";\n      break;\n    case HSA_AMD_SEGMENT_GROUP:\n      std::cout << \"  GROUP SEGMENT\";\n      break;\n    case HSA_AMD_SEGMENT_PRIVATE:\n      std::cout << \"  PRIVATE SEGMENT\";\n      break;\n    case HSA_AMD_SEGMENT_READONLY:\n      std::cout << \"  READONLY SEGMENT\";\n      break;\n    default:\n      std::cout << \"  no segment\";\n      break;\n    }\n  std::cout << std::endl;\n  return;\n}\n\nvoid MemoryAllocationTest::MemoryBasicAllocationAndFree(hsa_agent_t agent,\n                                               hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  // if allocation is allowed in this pool allocate the memory\n  // and then free it\n  if (pool_i.alloc_allowed) {\n    if (verbosity() > 0) {\n      PrintSegmentNameAndType(pool_i.segment);\n    }\n    size_t max_size;\n    err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                      &max_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    max_size = (max_size > kMemoryAllocSize) ? kMemoryAllocSize : max_size;\n\n    char *memoryPtr;\n    err = hsa_amd_memory_pool_allocate(pool, max_size , 0,\n                                       reinterpret_cast<void**>(&memoryPtr));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    if (memoryPtr) {\n      err = hsa_amd_memory_pool_free(memoryPtr);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    }\n  }\n  return;\n}\n\n\nvoid MemoryAllocationTest::MemoryBasicAllocationAndFree(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryBasicAllocationAndFree\");\n  }\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryBasicAllocationAndFree(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryAllocationTest::MemoryAllocateContiguousTest(hsa_agent_t agent,\n                                                        hsa_amd_memory_pool_t pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(pool, &pool_i));\n\n  if (verbosity() > 0) PrintAgentNameAndType(agent);\n\n  ASSERT_SUCCESS(hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type));\n\n  // if allocation is allowed in this pool allocate the memory\n  // and then free it\n  if (ag_type != HSA_DEVICE_TYPE_GPU || !pool_i.alloc_allowed || !pool_i.alloc_granule ||\n      !pool_i.alloc_alignment) {\n    return;\n  }\n\n  if (verbosity() > 0) PrintSegmentNameAndType(pool_i.segment);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n\n  const size_t alloc_size = pool_i.alloc_granule * 1024;\n\n  char* memoryPtr;\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_allocate(pool, alloc_size, HSA_AMD_MEMORY_POOL_CONTIGUOUS_FLAG,\n                                              reinterpret_cast<void**>(&memoryPtr)));\n  if (!memoryPtr) return;\n\n  int dmabuf = -1;\n  uint64_t offset;\n  ASSERT_SUCCESS(hsa_amd_portable_export_dmabuf(memoryPtr, alloc_size, &dmabuf, &offset));\n\n  std::vector<hsa_agent_t> accessible_gpus;\n  for (auto gpuIter: gpus) {\n    hsa_amd_memory_pool_access_t access = HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n    ASSERT_SUCCESS(hsa_amd_agent_memory_pool_get_info(gpuIter, pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access));\n    if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED)\n      accessible_gpus.push_back(gpuIter);\n  }\n\n  void* importedPtr = nullptr;\n  size_t importedSz;\n\n  ASSERT_SUCCESS(hsa_amd_interop_map_buffer(accessible_gpus.size(), accessible_gpus.data(), dmabuf, 0, &importedSz,\n                                                   &importedPtr, 0, NULL));\n\n  ASSERT_NE(importedPtr, nullptr);\n  ASSERT_EQ(importedSz, alloc_size);\n\n  close(dmabuf);\n\n  ASSERT_SUCCESS(hsa_amd_interop_unmap_buffer(importedPtr));\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_free(memoryPtr));\n  return;\n}\n\nvoid MemoryAllocationTest::MemoryAllocateContiguousTest(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryAllocateContiguousTest\");\n  }\n\n  ASSERT_SUCCESS(rocrtst::GetAgentPools(&agent_pools));\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryAllocateContiguousTest(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_allocation.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALLOCATION_H_\n#define ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALLOCATION_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass MemoryAllocationTest : public TestBase {\n public:\n    MemoryAllocationTest(bool launch_GroupMemory,\n                         bool launch_BasicAllocateFree);\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryAllocationTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void GroupMemoryDynamicAllocation(void);\n\n  void MemoryBasicAllocationAndFree(void);\n  void MemoryAllocateContiguousTest(void);\n\n\n private:\n  void GroupMemoryDynamicAllocation(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void MemoryBasicAllocationAndFree(hsa_agent_t agent,\n                                               hsa_amd_memory_pool_t pool);\n  void MemoryAllocateContiguousTest(hsa_agent_t agent, hsa_amd_memory_pool_t pool);\n\n  void WriteAQLPktToQueue(hsa_queue_t* q);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_MEMORY_ALLOCATION_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_atomics.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <string>\n\n#include \"suites/functional/memory_atomics.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\nstatic const int kValue = 5;\n\nMemoryAtomic::MemoryAtomic(AtomicTest testtype) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  testtype_ = testtype;\n  std::string name;\n  std::string desc;\n\n  name = \"RocR Memory Atomic Test\";\n  desc = \"\";\n\n  if (testtype_ == ADD) {\n    name += \" For ADD\";\n    desc += \" This test will do Add kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == SUB) {\n    name += \" For Sub\";\n    desc += \" This test will do Sub kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == AND) {\n    name += \" For And\";\n    desc += \" This test will do AND kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == OR) {\n    name += \" For Or\";\n    desc += \" This test will do OR kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == XOR) {\n    name += \" For Xor\";\n    desc += \" This test will do XOR kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == MIN) {\n    name += \" For Minimum\";\n    desc += \" This test will do Minimum kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == MAX) {\n    name += \" For Maximum\";\n    desc += \" This test will do Maximum kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == XCHG) {\n    name += \" For Exchange\";\n    desc += \" This test will do Xchg kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == INC) {\n    name += \" For Increment\";\n    desc += \" This test will do Increment kernel atomic\"\n            \" operation on GPU and system memory.\";\n  } else if (testtype_ == DEC) {\n    name += \" For Decremnet\";\n    desc += \" This test will do decrement kernel atomic\"\n            \" operation on GPU and system memory.\";\n  }\n\n  set_title(name);\n  set_description(desc);\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n}\n\nMemoryAtomic::~MemoryAtomic(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryAtomic::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  return;\n}\n\nvoid MemoryAtomic::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryAtomic::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAtomic::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryAtomic::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\ntypedef struct  __attribute__ ((aligned(16)))  args_t {\n  int *a;\n  int *b;\n  int *c;\n  int d;\n  int n;\n  } args;\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\n\nstatic const int kMemoryAllocSize = 4096;\n\nvoid MemoryAtomic::MemoryAtomicTest(hsa_agent_t cpuAgent,\n                                                   hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Get Global Memory Pool on the gpuAgent to allocate gpu buffers\n  hsa_amd_memory_pool_t gpu_pool;\n  err = hsa_amd_agent_iterate_memory_pools(gpuAgent,\n                                            rocrtst::GetGlobalMemoryPool,\n                                            &gpu_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  hsa_amd_memory_pool_access_t access;\n  hsa_amd_agent_memory_pool_get_info(cpuAgent, gpu_pool,\n                                       HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                       &access);\n  // hsa objects\n  hsa_queue_t *queue = NULL;  // command queue\n  // get queue size\n  uint32_t queue_size = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // create queue\n  err = hsa_queue_create(gpuAgent,\n                         queue_size, HSA_QUEUE_TYPE_MULTI,\n                         NULL, NULL, 0, 0, &queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Find a memory pool that supports kernel arguments.\n  hsa_amd_memory_pool_t kernarg_pool;\n  err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                            rocrtst::GetKernArgMemoryPool,\n                                            &kernarg_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Allocate the host side buffers\n  // (refSysdata,oldValues,oldrefdata,kernArg) on system memory\n\n  // this is ref sys data on which atomics operation need to done\n  int *refSysdata = NULL;\n  // This is oldrefdata which will be required  to compare the returned old values after atomics operation\n  int *oldrefdata = NULL;\n  // This is returned old values\n  int *oldValues = NULL;\n  // This is expected data set\n  int *expecteddata = NULL;\n  // Array size for the data\n  int arraySize = kMemoryAllocSize/sizeof(int);\n\n  // Get System Memory Pool on the cpuAgent to allocate host side buffers\n  hsa_amd_memory_pool_t global_pool;\n  err = hsa_amd_agent_iterate_memory_pools(cpuAgent,\n                                            rocrtst::GetGlobalMemoryPool,\n                                            &global_pool);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                    kMemoryAllocSize, 0,\n                                    reinterpret_cast<void **>(&oldValues));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                    kMemoryAllocSize, 0,\n                                    reinterpret_cast<void **>(&refSysdata));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                    kMemoryAllocSize, 0,\n                                    reinterpret_cast<void **>(&oldrefdata));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_allocate(global_pool,\n                                    kMemoryAllocSize, 0,\n                                    reinterpret_cast<void **>(&expecteddata));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n  // Allocate the kernel argument buffer from the kernarg_pool.\n  args *kernArguments = NULL;\n  err = hsa_amd_memory_pool_allocate(kernarg_pool, sizeof(args_t), 0,\n                                     reinterpret_cast<void **>(&kernArguments));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n  memset(oldValues, 0, kMemoryAllocSize);\n  memset(expecteddata, 0, kMemoryAllocSize);\n  // this signal will be used for copying the data memory from To and fro from GPU\n  // on Non-largebar system\n  hsa_signal_t copy_signal;\n\n  // for the dGPU, we have coarse grained local memory,\n  // so allocate memory for it on the GPU's GLOBAL segment .\n\n  // Get local memory of GPU to allocate device side buffers on which atomics operation need to done\n  int *gpuRefData = NULL;\n\n  // On non-Large bar system acess to GPU pool not allowed to directly so pinned memory\n  // g_gpuRefData is pointer to GPU Memory allocated on non-large bar where\n  // gpuRefData would be pointer to  host allocated memory on non-large bar\n  int *g_gpuRefData = NULL;\n  //  Pointer to the location where to store the new address\n  int *device_ptr = NULL;\n\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    err = hsa_amd_memory_pool_allocate(gpu_pool, kMemoryAllocSize, 0,\n                                       reinterpret_cast<void **>(&gpuRefData));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Allow cpuAgent access to all allocated GPU memory.\n    err = hsa_amd_agents_allow_access(1, &cpuAgent, NULL, gpuRefData);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    memset(gpuRefData, 0, kMemoryAllocSize);\n  } else {\n    err = hsa_signal_create(1, 0, NULL, &copy_signal);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    // Alocate the System Memory and get pointer gpuRefData\n    err = hsa_amd_memory_pool_allocate(global_pool, kMemoryAllocSize, 0,\n                                        reinterpret_cast<void **>(&gpuRefData));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    memset(gpuRefData, 0, kMemoryAllocSize);\n    // Alocate the GPU Memory and get pointer g_gpuRefData\n    err = hsa_amd_memory_pool_allocate(gpu_pool, kMemoryAllocSize, 0,\n                                        reinterpret_cast<void **>(&g_gpuRefData));\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    // Map the Host memory and get the pointer to new adress which is accesible to GPU agent\n    err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, gpuRefData);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    device_ptr = gpuRefData;\n  }\n\n\n\n  // initialize the host buffers & gpuRefData buffer\n  for (int i = 0; i < arraySize; ++i) {\n    unsigned int seed = time(NULL);\n    refSysdata[i] = 6 + rand_r(&seed) % 1;\n    gpuRefData[i] = 6 + rand_r(&seed) % 1;\n    oldrefdata[i] = refSysdata[i];\n  }\n\n  // Sync the data from system memory to GPU memory on non-largebar\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    hsa_signal_store_relaxed(copy_signal, 1);\n    err = hsa_amd_memory_async_copy(g_gpuRefData, gpuAgent, device_ptr,\n                                    gpuAgent, kMemoryAllocSize, 0, NULL, copy_signal);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    while (hsa_signal_wait_acquire(copy_signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)(-1), HSA_WAIT_STATE_ACTIVE)) {}\n  }\n\n\n  // Allow gpuAgent access to all allocated system memory.\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, oldValues);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, refSysdata);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, oldrefdata);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  err = hsa_amd_agents_allow_access(1, &gpuAgent, NULL, kernArguments);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  kernArguments->a = refSysdata;\n  if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    kernArguments->b = gpuRefData;\n  } else {\n    kernArguments->b = g_gpuRefData;\n  }\n  kernArguments->c = oldValues;\n\n  if (testtype_ != INC && testtype_ != DEC) {\n    kernArguments->d = kValue;\n  }\n\n  // Create the executable, get symbol by name and load the code object\n  set_kernel_file_name(\"atomicOperations_kernels.hsaco\");\n\n  if (testtype_ == ADD) {\n    set_kernel_name(\"test_atomic_add\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] + kValue;\n    }\n  } else if (testtype_ == SUB) {\n    set_kernel_name(\"test_atomic_sub\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] - kValue;\n    }\n  } else if (testtype_ == AND) {\n    set_kernel_name(\"test_atomic_and\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] & kValue;\n    }\n  } else if (testtype_ == OR) {\n    set_kernel_name(\"test_atomic_or\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] | kValue;\n    }\n  } else if (testtype_ == XOR) {\n    set_kernel_name(\"test_atomic_xor\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] ^ kValue;\n    }\n  } else if (testtype_ == MIN) {\n    set_kernel_name(\"test_atomic_min\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = std::min(oldrefdata[i], kValue);\n    }\n  } else if (testtype_ == MAX) {\n    set_kernel_name(\"test_atomic_max\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = std::max(oldrefdata[i], kValue);\n    }\n  } else if (testtype_ == INC) {\n    set_kernel_name(\"test_atomic_inc\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] + 4;\n    }\n  } else if (testtype_ == DEC) {\n    set_kernel_name(\"test_atomic_dec\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = oldrefdata[i] - 4;\n    }\n  } else if (testtype_ == XCHG) {\n    set_kernel_name(\"test_atomic_xchg\");\n    // set the expected data result set from kernel\n    for (int i = 0; i < arraySize; ++i) {\n      expecteddata[i] = kValue;\n    }\n  } else {\n    if (verbosity() > 0) {\n      std::cout<< \"No test specified\" <<std::endl;\n    }\n  }\n\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  aql().workgroup_size_x = 256;\n  aql().workgroup_size_y = 1;\n  aql().workgroup_size_z = 1;\n  aql().grid_size_x = arraySize;\n  aql().kernarg_address = kernArguments;\n  aql().kernel_object = kernel_object();\n\n  const uint32_t queue_mask = queue->size - 1;\n\n  // Load index for writing header later to command queue at same index\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n  rocrtst::WriteAQLToQueueLoc(queue, index, &aql());\n\n  aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n  aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n               HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n  aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n               HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n  void* q_base = queue->base_address;\n  // Set the Aql packet header\n  rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                      &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                          (q_base))[index & queue_mask]);\n\n\n  // ringdoor bell\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\n\n  // wait for the signal and reset it for future use\n  while (hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                      (uint64_t)-1, HSA_WAIT_STATE_ACTIVE)) { }\n\n  hsa_signal_store_relaxed(aql().completion_signal, 1);\n\n  // Sync the data from GPU memory to system memory on non-largebar\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    hsa_signal_store_relaxed(copy_signal, 1);\n    err = hsa_amd_memory_async_copy(device_ptr, gpuAgent, g_gpuRefData,\n                                    gpuAgent, kMemoryAllocSize, 0, NULL, copy_signal);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    while (hsa_signal_wait_acquire(copy_signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)(-1), HSA_WAIT_STATE_ACTIVE)) { }\n  }\n\n  // compare results with expected results\n  for (int i = 0; i < arraySize; ++i) {\n    ASSERT_EQ(refSysdata[i], expecteddata[i]);\n    ASSERT_EQ(gpuRefData[i], expecteddata[i]);\n    ASSERT_EQ(oldValues[i], oldrefdata[i]);\n  }\n\n  if (refSysdata) {\n    err = hsa_memory_free(refSysdata);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n  if (oldrefdata) {\n    err = hsa_memory_free(oldrefdata);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n  if (oldValues) {\n    err = hsa_memory_free(oldValues);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    err = hsa_amd_memory_unlock(gpuRefData);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    // Destroy the copy signal\n    err = hsa_signal_destroy(copy_signal);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    if (g_gpuRefData) {\n      err = hsa_memory_free(g_gpuRefData);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    }\n  }\n  if (gpuRefData) {\n    err = hsa_memory_free(gpuRefData);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n  if (kernArguments) {\n    err = hsa_memory_free(kernArguments);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n  if (queue) {\n    err = hsa_queue_destroy(queue);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n}\n\nvoid MemoryAtomic::MemoryAtomicTest(void) {\n  hsa_status_t err;\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    MemoryAtomicTest(cpus[0], gpus[i]);\n  }\n}\n\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_atomics.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_MEMORY_ATOMICS_H_\n#define ROCRTST_SUITES_FUNCTIONAL_MEMORY_ATOMICS_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\n// Atomic Test type\nenum AtomicTest {\n  ADD,  // For add atomic operation\n  SUB,  // For sub atomic operation\n  AND,  // For and atomic operation\n  OR,   // For or atomic operation\n  XOR,  // For xor atomic operation\n  INC,  // For inc atomic operation\n  DEC,  // For dec atomic operation\n  MAX,  // For max atomic operation\n  MIN,  // For min atomic operation\n  XCHG,  // For xchg atomic operation\n  NO_TEST};\n\nclass MemoryAtomic : public TestBase {\n public:\n  explicit MemoryAtomic(AtomicTest testtype);\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryAtomic();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void MemoryAtomicTest(void);\n\n\n private:\n  void MemoryAtomicTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n\n  void WriteAQLPktToQueue(hsa_queue_t* q);\n\n  AtomicTest testtype_;\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_MEMORY_ATOMICS_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_basic.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <sys/sysinfo.h>\n\n#include \"suites/functional/memory_basic.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\n\nMemoryTest::MemoryTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"RocR Memory Tests\");\n  set_description(\"This series of tests check memory allocation limits, extent\"\n    \" of GPU access to system memory and other memory related functionality.\");\n}\n\nMemoryTest::~MemoryTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  return;\n}\n\nvoid MemoryTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\nhsa_status_t MemoryTest::TestAllocate(hsa_amd_memory_pool_t pool, size_t sz) {\n  void *ptr;\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_allocate(pool, sz, 0, &ptr);\n\n  if (err == HSA_STATUS_SUCCESS) {\n    err = hsa_memory_free(ptr);\n  }\n\n  return err;\n}\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Subtest: \" << header << \" ***\" << std::endl;\n}\n\n// Test Fixtures\nvoid MemoryTest::MaxSingleAllocationTest(hsa_agent_t ag,\n                                                 hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n  struct sysinfo info;\n\n  rocrtst::pool_info_t pool_i;\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n\n  err = hsa_agent_get_info(ag, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(ag, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  uint32_t node_id;\n  err = hsa_agent_get_info(ag, HSA_AGENT_INFO_NODE, &node_id);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  sysinfo(&info);\n  if (verbosity() > 0) {\n    time_t t = time(&t);\n\n    std::cout << \"  Current date and time: \" << ctime(&t);\n    std::cout << \"  Agent: \" << ag_name << \" (\";\n    switch (ag_type) {\n      case HSA_DEVICE_TYPE_CPU:\n        std::cout << \"CPU)\" << std::endl;\n        std::cout << \"  System Total Memory:        \"\n                  << info.totalram / 1024 << \" KB\" << std::endl;\n        std::cout << \"  System Free Memory:         \"\n                  << info.freeram / 1024 << \" KB\";\n        break;\n      case HSA_DEVICE_TYPE_GPU:\n        std::cout << \"GPU)\";\n        break;\n      case HSA_DEVICE_TYPE_DSP:\n        std::cout << \"DSP)\";\n        break;\n      case HSA_DEVICE_TYPE_AIE:\n        std::cout << \"AIE)\";\n        break;\n\n    }\n    std::cout << std::endl;\n  }\n\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n      rocrtst::DumpMemoryPoolInfo(&pool_i, 2);\n  }\n\n  if (!pool_i.alloc_allowed || pool_i.alloc_granule == 0 || pool_i.alloc_alignment == 0 ||\n      (pool_i.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED)\n      ) {\n    if (verbosity() > 0) {\n      std::cout << \"  Test not applicable. Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  // To speed-up test, test all pools on CPU-0, only test coare-grained on remaining CPU agents\n  if (ag_type == HSA_DEVICE_TYPE_CPU && node_id > 0 &&\n      !(pool_i.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED)) {\n\n    if (verbosity() > 0) {\n      std::cout << \"  Test not applicable. Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  // Do everything in \"granule\" units\n  auto gran_sz = pool_i.alloc_granule;\n  auto pool_sz = pool_i.aggregate_alloc_max / gran_sz;\n\n  // Neg. test: Try to allocate more than the pool size\n  err = TestAllocate(pool, pool_sz*gran_sz + gran_sz);\n  EXPECT_EQ(HSA_STATUS_ERROR_INVALID_ALLOCATION, err);\n\n  pool_sz = (ag_type == HSA_DEVICE_TYPE_CPU)?\n              std::min(pool_sz, info.totalram / gran_sz) :\n              pool_sz;\n\n  // Reduce upper_bound by 10% for system-RAM. Otherwise Linux OOM-Killer app can be triggered,\n  // if system has allocated all available physical memory and swap space, and so killing this\n  // process.\n  uint64_t upper_bound = (ag_type == HSA_DEVICE_TYPE_CPU) ? (pool_sz * 0.90) : pool_sz;\n  uint64_t lower_bound = 0;\n  auto max_alloc_size = upper_bound;\n\n  while (true) {\n    err = TestAllocate(pool, max_alloc_size * gran_sz);\n    ASSERT_TRUE(err == HSA_STATUS_SUCCESS ||\n                err == HSA_STATUS_ERROR_OUT_OF_RESOURCES ||\n                err == HSA_STATUS_ERROR_INVALID_ALLOCATION);\n    if (err == HSA_STATUS_SUCCESS) {\n      break;\n    } else if (err == HSA_STATUS_ERROR_OUT_OF_RESOURCES ||\n               err == HSA_STATUS_ERROR_INVALID_ALLOCATION) {\n      upper_bound = max_alloc_size;\n      max_alloc_size =\n          static_cast<uint64_t>(max_alloc_size * 0.99);  // Reduce by 1% in each iteration\n    }\n\n    ASSERT_GT(upper_bound, lower_bound);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"  Biggest single allocation size for this pool is \" <<\n                        (max_alloc_size * gran_sz)/1024 << \"KB.\" << std::endl;\n    std::cout << \"  This is \" <<\n                  static_cast<float>(max_alloc_size)/pool_sz*100 <<\n                                               \"% of the total.\" << std::endl;\n  }\n\n  if (ag_type == HSA_DEVICE_TYPE_GPU) {\n    if (pool_sz <= 536870912) {\n      EXPECT_GE((float)max_alloc_size/pool_sz, (float)6/10);\n    } else {\n      EXPECT_GE((float)max_alloc_size/pool_sz, (float)3/4);\n    }\n  }\n  if (verbosity() > 0) {\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryTest::MaxSingleAllocationTest(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  PrintMemorySubtestHeader(\"Maximum Single Allocation in Memory Pools\");\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      MaxSingleAllocationTest(a->agent, p);\n    }\n  }\n}\n\nvoid MemoryTest::MemAvailableTest(hsa_agent_t ag, hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n  void *memPtr1, *memPtr2;\n  rocrtst::pool_info_t pool_i;\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n  uint64_t allocate_sz2, ag_avail_memory_before, ag_avail_memory_after;\n\n  err = hsa_agent_get_info(ag, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(ag, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  if (verbosity() > 0) {\n    std::cout << \"  Agent: \" << ag_name << \" (\";\n    switch (ag_type) {\n      case HSA_DEVICE_TYPE_CPU:\n        std::cout << \"CPU)\";\n        break;\n      case HSA_DEVICE_TYPE_GPU:\n        std::cout << \"GPU)\";\n        break;\n      case HSA_DEVICE_TYPE_DSP:\n        std::cout << \"DSP)\";\n        break;\n      case HSA_DEVICE_TYPE_AIE:\n        std::cout << \"AIE)\";\n        break;\n    }\n    std::cout << std::endl;\n  }\n\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (ag_type != HSA_DEVICE_TYPE_GPU ||\n      !pool_i.alloc_allowed || !pool_i.alloc_granule || !pool_i.alloc_alignment) {\n    if (verbosity() > 0) {\n      std::cout << \"  Test not applicable. Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  // Do everything in \"granule\" units\n  auto gran_sz = pool_i.alloc_granule;\n  auto pool_sz = pool_i.aggregate_alloc_max / gran_sz;\n\n  err = hsa_agent_get_info(ag, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                            &ag_avail_memory_before);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Try to allocate half\n  uint64_t allocate_sz1 = (pool_sz / 2) * gran_sz;\n\n  err = hsa_amd_memory_pool_allocate(pool, allocate_sz1, 0, &memPtr1);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  hsa_amd_pointer_info_t info = {};\n  info.size = sizeof(info);\n\n  // Check pointer info for valid pointer\n  ASSERT_SUCCESS(hsa_amd_pointer_info(memPtr1, &info, NULL, 0, NULL));\n\n  ASSERT_EQ(info.type, HSA_EXT_POINTER_TYPE_HSA);\n  ASSERT_EQ(info.sizeInBytes, allocate_sz1);\n  ASSERT_EQ(info.agentOwner.handle, ag.handle);\n  // ROCR may return a smaller size of info if it is an older version of ROCr and ROCr's\n  // internal definition hsa_amd_pointer_info_t is smaller than the users. But ROCr cannot\n  // return a bigger size\n  ASSERT_LE(info.size, sizeof(info));\n\n  // Check pointer info for invalid pointer\n  hsa_amd_pointer_info_t info2 = {};\n  info2.size = sizeof(info2);\n  ASSERT_SUCCESS(hsa_amd_pointer_info((reinterpret_cast<uint8_t *>(memPtr1) + allocate_sz1 + 1), &info2, NULL, 0, NULL));\n  ASSERT_EQ(info2.type, HSA_EXT_POINTER_TYPE_UNKNOWN);\n\n  // Simulate case where ROCr has added extra parameters to hsa_amd_pointer_info.\n  // i.e ROCr's hsa_amd_pointer_info is bigger than user's hsa_amd_pointer_info\n  // ROCr should still return info.size same as user's size\n  hsa_amd_pointer_info_t info3 = {};\n  info3.size = sizeof(info3) - 2;\n  ASSERT_SUCCESS(hsa_amd_pointer_info(memPtr1, &info3, NULL, 0, NULL));\n  ASSERT_EQ(info.type, HSA_EXT_POINTER_TYPE_HSA);\n  ASSERT_EQ(info3.size, sizeof(info3) - 2);\n\n  err = hsa_agent_get_info(ag, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                            &ag_avail_memory_after);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Memory available after could be smaller because of fragmentation\n  ASSERT_GE(ag_avail_memory_before - allocate_sz1, ag_avail_memory_after);\n\n  // Try to allocate 30%/80% of remaining\n  if (pool_i.aggregate_alloc_max <= 536870912)\n    allocate_sz2 = (0.3 * ag_avail_memory_after * gran_sz) / gran_sz;\n  else\n    allocate_sz2 = (0.8 * ag_avail_memory_after * gran_sz) / gran_sz;\n\n\n  err = hsa_amd_memory_pool_allocate(pool, allocate_sz2, 0, &memPtr2);\n  if (err != HSA_STATUS_SUCCESS) hsa_memory_free(memPtr1);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(ag, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                            &ag_avail_memory_after);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  ASSERT_GE(ag_avail_memory_before - (allocate_sz1 + allocate_sz2),\n                            ag_avail_memory_after);\n\n  if (verbosity() > 0) {\n    std::cout << \"  Available memory before: \" << ag_avail_memory_before << std::endl;\n    std::cout << \"         Memory allocated: \" << allocate_sz1 \n                  << \" + \" << allocate_sz2 << std::endl;\n    std::cout << \"   Available memory after: \" << ag_avail_memory_after << std::endl;\n  }\n\n  err = hsa_memory_free(memPtr1);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_memory_free(memPtr2);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(ag, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                            &ag_avail_memory_after);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  ASSERT_EQ(ag_avail_memory_before, ag_avail_memory_after);\n\n  if (verbosity() > 0) {\n    std::cout << \"     Available memory end: \" << ag_avail_memory_after << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryTest::MemAvailableTest(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  PrintMemorySubtestHeader(\"Memory Available Allocation in Memory Pools\");\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      MemAvailableTest(a->agent, p);\n    }\n  }\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/functional/memory_basic.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_MEMORY_BASIC_H_\n#define ROCRTST_SUITES_FUNCTIONAL_MEMORY_BASIC_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass MemoryTest : public TestBase {\n public:\n    MemoryTest();\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void MaxSingleAllocationTest(void);\n\n  void MemAvailableTest(void);\n\n  hsa_status_t TestAllocate(hsa_amd_memory_pool_t pool, size_t sz);\n\n private:\n  void MaxSingleAllocationTest(hsa_agent_t ag, hsa_amd_memory_pool_t pool);\n\n  void MemAvailableTest(hsa_agent_t ag, hsa_amd_memory_pool_t pool);\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_MEMORY_BASIC_H_\n"
  },
  {
    "path": "rocrtst/suites/functional/reference_count.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n/* Test Name: reference_count\r\n *\r\n * Purpose: Verifies that the hsa_init and hsa_shutdown APIs properly increment\r\n * and decrement reference counting.\r\n *\r\n * Test Description:\r\n * 1) Initialize the ROC runtime with hsa_init by calling that API N times, (N\r\n * should be large).\r\n * 2) Verify that the runtime is operational by querying the agent list.\r\n * 3) Call hsa_shutdown N-1 times.\r\n * 4) Again, verify the runtime is operational by querying the agent list.\r\n *\r\n * Expected Results: The runtime should remain operational when the reference\r\n * count is positive. Repeated calls to hsa_init should not cause undefined behavior.\r\n *\r\n */\r\n#include <algorithm>\r\n#include <iostream>\r\n\r\n\r\n#include \"suites/functional/reference_count.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic const int NumOfTimes = 1000;  // No of times the hsa runtime will be initialized\r\nstatic const double MaxRefCount = 2147483649;  // Setting to max value to test to INIT_MAX+2 as defined in hsa runtime\r\n\r\n#define RET_IF_HSA_ERR(err) { \\\r\n  if ((err) != HSA_STATUS_SUCCESS) { \\\r\n    const char* msg = 0; \\\r\n    hsa_status_string(err, &msg); \\\r\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\r\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\r\n    std::cout << msg << std::endl; \\\r\n  } \\\r\n}\r\n\r\nReferenceCountTest::ReferenceCountTest(bool referenceCount_, bool maxReferenceCount_) : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n                          // This is a default value which can be overridden\r\n                          // on the command line.\r\n  if (referenceCount_) {\r\n    set_title(\"RocR Reference Count Test\");\r\n    set_description(\"Initializes HSA runtime N times and shutdown N-1 times, again call shutdown\");\r\n  } else if (maxReferenceCount_) {\r\n    set_title(\"RocR Max Reference Count Test\");\r\n    set_description(\"This test initializes HSA runtime to maximum allowed reference count\");\r\n  }\r\n}\r\n\r\n// Any 1-time setup involving member variables used in the rest of the test\r\n// should be done here.\r\nReferenceCountTest::~ReferenceCountTest(void) {\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ReferenceCountTest::SetUp(void) {\r\n  return;  // hsa runtime initalized in ReferenceCountTest::TestReferenceCount()\r\n}\r\n\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ReferenceCountTest::Run(void) {\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  TestBase::Run();\r\n}\r\n\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\nvoid ReferenceCountTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid ReferenceCountTest::DisplayResults(void) const {\r\n  // Compare required profile for this test case with what we're actually\r\n  // running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  return;\r\n}\r\n\r\nvoid ReferenceCountTest::Close() {\r\n  // This will close handles opened within rocrtst utility calls and call\r\n  // hsa_shut_down(), so it should be done after other hsa cleanup\r\n  // all the reference count decremented in main function, ReferenceCountTest::TestReferenceCount(void)\r\n}\r\n\r\nvoid ReferenceCountTest::TestReferenceCount(void) {\r\n  hsa_status_t status;\r\n  // Initialize hsa runtime N times\r\n  for (int i = 0; i < NumOfTimes; ++i) {\r\n    status = hsa_init();\r\n    RET_IF_HSA_ERR(status);\r\n  }\r\n\r\n  // Shutdown hsa runtime N - 1 times\r\n  for (int i = 0; i < NumOfTimes-1; ++i) {\r\n    status = hsa_shut_down();\r\n    RET_IF_HSA_ERR(status);\r\n  }\r\n\r\n  status = hsa_shut_down();\r\n  RET_IF_HSA_ERR(status);\r\n}\r\n\r\nvoid ReferenceCountTest::TestMaxReferenceCount(void) {\r\n  hsa_status_t status;\r\n  // Initialize hsa runtime to maximum allowed  times\r\n  for (int i = 0; i < MaxRefCount; ++i) {\r\n    status = hsa_init();\r\n    if (status != HSA_STATUS_SUCCESS && status == HSA_STATUS_ERROR_REFCOUNT_OVERFLOW) {\r\n      std::cout << \"Max allowed reference count is = \" << i << std::endl;\r\n      // Gracefull exit after reaching the INIT_MAX as defined in hsa rutnime.\r\n      break;\r\n    }\r\n  }\r\n  for (int i = 0; i < MaxRefCount-2; ++i) {\r\n    status = hsa_shut_down();\r\n    RET_IF_HSA_ERR(status);\r\n  }\r\n}\r\n#undef RET_IF_HSA_ERR\r\n"
  },
  {
    "path": "rocrtst/suites/functional/reference_count.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_REFERENCE_COUNT_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_REFERENCE_COUNT_H_\r\n\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass ReferenceCountTest:public TestBase {\r\n public:\r\n    ReferenceCountTest(bool _referenceCount, bool _maxReferenceCount);\r\n\r\n    // @Brief: Destructor for the ReferenceCountTest class\r\n    virtual ~ReferenceCountTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    // @Brief: The function initializes runtime to N times, shutdown N-1\r\n    void TestReferenceCount(void);\r\n\r\n    // @Brief: The function checks maximum no.of allowed hsa runtime initialization before reaching outof resource\r\n    void TestMaxReferenceCount(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_REFERENCE_COUNT_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/signal_concurrent.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#include <algorithm>\r\n#include <iostream>\r\n#include <vector>\r\n#include \"suites/functional/signal_concurrent.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"common/concurrent_utils.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic const int N = 8;\r\nstatic const int M = 32;\r\nstatic const int INI_VAL = 0;\r\nstatic const int CMP_VAL = 1;\r\nhsa_signal_t *signals;\r\n\r\n#define ASSERT_MSG(C, err) { \\\r\n  if (C == 1) { \\\r\n    std::cout << err << std::endl; \\\r\n  } \\\r\n}\r\n\r\nstatic void TestSignalCreateFunction(void *data) {\r\n  hsa_status_t status;\r\n  int* offset = reinterpret_cast<int *>(data);\r\n  int i;\r\n  for (i = 0; i < M; ++i) {\r\n    status = hsa_signal_create(INI_VAL, 0, NULL, &signals[*offset + i]);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n  return;\r\n}\r\n\r\nstatic void signals_wait_host_func(void *data) {\r\n  int i;\r\n  for (i = 0; i < M * N; ++i) {\r\n    hsa_signal_wait_scacquire(signals[i], HSA_SIGNAL_CONDITION_EQ, CMP_VAL, UINT64_MAX,\r\n                              HSA_WAIT_STATE_BLOCKED);\r\n  }\r\n  return;\r\n}\r\n\r\nstatic void signals_wait_component_func(void *data) {\r\n  int i;\r\n  for (i = 0; i < M * N; ++i) {\r\n    // Launch a kernel with signal_wait_func\r\n    hsa_signal_wait_scacquire(signals[i], HSA_SIGNAL_CONDITION_EQ, CMP_VAL, UINT64_MAX,\r\n                              HSA_WAIT_STATE_BLOCKED);\r\n  }\r\n  return;\r\n}\r\n\r\nstatic void TestSignalDestroyFunction(void* data) {\r\n  hsa_status_t status;\r\n  int *offset = reinterpret_cast<int*>(data);\r\n  int i;\r\n  for (i = 0; i < M; i++) {\r\n    status = hsa_signal_destroy(signals[*offset + i]);\r\n    ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n  }\r\n}\r\n\r\nstatic void signal_wait_host_func(void *data) {\r\n  hsa_signal_t *signal_ptr = reinterpret_cast<hsa_signal_t*>(data);\r\n  hsa_signal_wait_scacquire(*signal_ptr, HSA_SIGNAL_CONDITION_EQ, CMP_VAL, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\r\n  return;\r\n}\r\n\r\nstatic void signal_wait_component_func(void *data) {\r\n  hsa_signal_t *signal_ptr = reinterpret_cast<hsa_signal_t*>(data);\r\n  hsa_signal_wait_scacquire(*signal_ptr, HSA_SIGNAL_CONDITION_EQ, CMP_VAL, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\r\n  return;\r\n}\r\nSignalConcurrentTest::SignalConcurrentTest(bool destroy, bool max_consumer, bool cpu, bool create)\r\n    : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n                        // This is a default value which can be overridden\r\n                        // on the command line.\r\n  if (destroy) {\r\n    set_title(\"RocR Signal Destroy Concurrent Test\");\r\n    set_description(\"This test destroy signals concurrently\");\r\n  } else if (max_consumer) {\r\n    set_title(\"RocR Signal Max Consumers Test\");\r\n    set_description(\"This verify signal is created with num_consumers and signal can wait on all\");\r\n  } else if (create) {\r\n    set_title(\"RocR Signal Create Concurrent Test\");\r\n    set_description(\"This test create signals concurrently\");\r\n  } else if (cpu) {\r\n    set_title(\"RocR CPU Signal Completion Test\");\r\n    set_description(\"This test checks whether CPU signals completed\");\r\n  }\r\n}\r\n\r\nSignalConcurrentTest::~SignalConcurrentTest(void) {\r\n}\r\n\r\n// Any 1-time setup involving member variables used in the rest of the test\r\n// should be done here.\r\nvoid SignalConcurrentTest::SetUp(void) {\r\n  hsa_status_t err;\r\n\r\n  TestBase::SetUp();\r\n\r\n  err = rocrtst::SetDefaultAgents(this);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\r\n\r\n  err = rocrtst::SetPoolsTypical(this);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\r\n  return;\r\n}\r\n\r\n\r\nvoid SignalConcurrentTest::Run(void) {\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  TestBase::Run();\r\n}\r\n\r\nvoid SignalConcurrentTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid SignalConcurrentTest::DisplayResults(void) const {\r\n  // Compare required profile for this test case with what we're actually\r\n  // running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n    return;\r\n  }\r\n\r\n  return;\r\n}\r\n\r\n\r\nvoid SignalConcurrentTest::Close() {\r\n  // This will close handles opened within rocrtst utility calls and call\r\n  // hsa_shut_down(), so it should be done after other hsa cleanup\r\n  TestBase::Close();\r\n}\r\n\r\nvoid SignalConcurrentTest::TestSignalCreateConcurrent(void) {\r\n  unsigned int i;\r\n  hsa_status_t status;\r\n  signals = reinterpret_cast<hsa_signal_t*>(malloc(sizeof(hsa_signal_t) * N * M));\r\n\r\n  ASSERT_NE(signals, nullptr);\r\n\r\n  struct rocrtst::test_group* tg_sg_create = rocrtst::TestGroupCreate(N);\r\n  int* offset = reinterpret_cast<int*>(malloc(sizeof(int) * N));\r\n\r\n  EXPECT_NE(offset, nullptr);\r\n  if (!offset) {\r\n\t  free(signals);\r\n\t  return;\r\n  }\r\n\r\n  for (i = 0; i < N; ++i) {\r\n    offset[i] = i * M;\r\n    rocrtst::TestGroupAdd(tg_sg_create, &TestSignalCreateFunction, offset + i, 1);\r\n    }\r\n  rocrtst::TestGroupThreadCreate(tg_sg_create);\r\n  rocrtst::TestGroupStart(tg_sg_create);\r\n  rocrtst::TestGroupWait(tg_sg_create);\r\n  rocrtst::TestGroupExit(tg_sg_create);\r\n  rocrtst::TestGroupDestroy(tg_sg_create);\r\n\r\n  std::vector<hsa_agent_t> gpus;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    struct rocrtst::test_group *tg_sg_wait = rocrtst::TestGroupCreate(gpus.size());\r\n    for (i = 0; i < gpus.size(); ++i) {\r\n      hsa_device_type_t device_type;\r\n      status = hsa_agent_get_info(gpus[i], HSA_AGENT_INFO_DEVICE, &device_type);\r\n      ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n      if (device_type == HSA_DEVICE_TYPE_CPU) {\r\n        rocrtst::TestGroupAdd(tg_sg_wait, &signals_wait_host_func, &(gpus[i]), 1);\r\n      } else if (device_type == HSA_DEVICE_TYPE_GPU) {\r\n        rocrtst::TestGroupAdd(tg_sg_wait, &signals_wait_component_func, &(gpus[i]), 1);\r\n      } else if (device_type == HSA_DEVICE_TYPE_DSP) {\r\n        ASSERT_MSG(1, \"ERROR: DSP_AGENT NOT SUPPORTED\\n\");\r\n      } else {\r\n        ASSERT_MSG(1, \"ERROR: UNKNOWN DEVICE\\n\");\r\n      }\r\n    }\r\n\r\n    rocrtst::TestGroupThreadCreate(tg_sg_wait);\r\n    rocrtst::TestGroupStart(tg_sg_wait);\r\n\r\n    for (i = 0; i < N * M; ++i) {\r\n      hsa_signal_store_relaxed(signals[i], CMP_VAL);\r\n    }\r\n    rocrtst::TestGroupWait(tg_sg_wait);\r\n    rocrtst::TestGroupExit(tg_sg_wait);\r\n    rocrtst::TestGroupDestroy(tg_sg_wait);\r\n\r\n    for (i = 0; i < N * M; ++i) {\r\n      status = hsa_signal_destroy(signals[i]);\r\n      ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    }\r\n\r\n    free(signals);\r\n    free(offset);\r\n}\r\n\r\n /*\r\n * Test Name: TestSignalDestroyConcurrent\r\n * Scope: Conformance\r\n *\r\n * Purpose: Verifies that signals can be created concurrently in different\r\n * threads.\r\n *\r\n * Test Description:\r\n * 1) Start N threads that each\r\n *   a) Create M signals, that are maintained in a global list.\r\n *   b) When creating the symbols specify all agents as consumers.\r\n * 2) After the signals have been created, have each agent wait on\r\n *    each of the signals. All agents should wait on a signal concurrently\r\n *    and all signals in the signal list should be waited on one at a time.\r\n * 3) Set the signal values in another thread so the waiting agents wake\r\n *    up, as expected.\r\n * 4) Destroy all of the signals in the main thread.\r\n *\r\n *   Expected Results: All of the signals should be created successfully.\r\n *   All\r\n *   agents should be able to wait on all of the N*M threads successfully.\r\n */\r\nvoid SignalConcurrentTest::TestSignalDestroyConcurrent(void) {\r\n  int i;\r\n\r\n  signals = reinterpret_cast<hsa_signal_t *>(malloc(sizeof(hsa_signal_t) * N * M));\r\n\r\n  ASSERT_NE(signals, nullptr);\r\n\r\n  struct rocrtst::test_group *tg_sg_destroy = rocrtst::TestGroupCreate(N);\r\n  int *offset = reinterpret_cast<int *>(malloc(sizeof(int) * N));\r\n\r\n  EXPECT_NE(offset, nullptr);\r\n  if (!offset)\r\n    return;\r\n\r\n  for (i = 0; i < N; ++i) {\r\n    int j;\r\n    offset[i] = i * M;\r\n    for (j = 0; j < M; ++j) {\r\n      hsa_status_t status = hsa_signal_create(INI_VAL, 0, NULL, &signals[i * M + j]);\r\n      ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n    }\r\n  }\r\n\r\n  for (i = 0; i < N; ++i) {\r\n    rocrtst::TestGroupAdd(tg_sg_destroy, &TestSignalDestroyFunction, &offset[i], 1);\r\n  }\r\n\r\n  rocrtst::TestGroupThreadCreate(tg_sg_destroy);\r\n  rocrtst::TestGroupStart(tg_sg_destroy);\r\n  rocrtst::TestGroupWait(tg_sg_destroy);\r\n  rocrtst::TestGroupExit(tg_sg_destroy);\r\n  rocrtst::TestGroupDestroy(tg_sg_destroy);\r\n\r\n  free(signals);\r\n  free(offset);\r\n}\r\n\r\n/*\r\n * Test Name: TestSignalCreateMaxConsumers\r\n * Scope: Conformance\r\n *\r\n * Purpose: Verifies that when a signal is created with the num_consumers\r\n * parameter set to the total number of agents and a consumers list\r\n * that contains all agents, the signal can be waited on by all agent_list.\r\n *\r\n * Test Description:\r\n * 1) Create a signal using the following parameters,\r\n *    a) A num_consumers value equal to the total number\r\n *       of agents on the system.\r\n *    b) A consumers list containing all of the agents\r\n *       in the system.\r\n * 2) After the signal is created, have all of the agents in\r\n * the system wait on the signal one at a time,\r\n * either using the appropriate hsa_signal_wait API or a\r\n * HSAIL instruction executed in a kernel.\r\n * 3) Set the signal on another thread such that the waiting\r\n * threads wait condition is satisfied.\r\n *\r\n * Expected Results: All of the agents should be able to properly wait\r\n * on the signal.\r\n */\r\nvoid SignalConcurrentTest::TestSignalCreateMaxConsumers(void) {\r\n  unsigned int i;\r\n  hsa_status_t status;\r\n\r\n  std::vector<hsa_agent_t> gpus;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n\r\n  hsa_signal_t signal;\r\n  status = hsa_signal_create(INI_VAL, 0, NULL, &signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n\r\n  struct rocrtst::test_group *tg_sg_wait = rocrtst::TestGroupCreate(gpus.size());\r\n  for (i = 0; i < gpus.size(); ++i) {\r\n    hsa_device_type_t device_type;\r\n    hsa_agent_get_info(gpus[i], HSA_AGENT_INFO_DEVICE, &device_type);\r\n    if (device_type == HSA_DEVICE_TYPE_CPU) {\r\n      rocrtst::TestGroupAdd(tg_sg_wait, &signal_wait_host_func, &signal, 1);\r\n    } else if (device_type == HSA_DEVICE_TYPE_GPU) {\r\n      rocrtst::TestGroupAdd(tg_sg_wait, &signal_wait_component_func, &signal, 1);\r\n    } else if (device_type == HSA_DEVICE_TYPE_DSP) {\r\n      ASSERT_MSG(1, \"ERROR: DSP_AGENT NOT SUPPORTED\\n\");\r\n    } else {\r\n      ASSERT_MSG(1, \"ERROR: UNKOWN DEIVCE TYPE\");\r\n    }\r\n  }\r\n\r\n  rocrtst::TestGroupThreadCreate(tg_sg_wait);\r\n  rocrtst::TestGroupStart(tg_sg_wait);\r\n\r\n  hsa_signal_store_relaxed(signal, CMP_VAL);\r\n\r\n  rocrtst::TestGroupWait(tg_sg_wait);\r\n  rocrtst::TestGroupExit(tg_sg_wait);\r\n  rocrtst::TestGroupDestroy(tg_sg_wait);\r\n\r\n  status = hsa_signal_destroy(signal);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, status);\r\n}\r\n\r\nvoid SignalConcurrentTest::TestSignalCPUCompletion(void) {\r\n  // Not clear with the requirements, have to check with Runtime team/Ramesh\r\n  // As we are not implemented the test fully hence the test will be skipped for now\r\n  std::cout << \"The test skipped siliently and reports as pass\" << std::endl;\r\n}\r\n\r\n#undef RET_IF_HSA_ERR\r\n"
  },
  {
    "path": "rocrtst/suites/functional/signal_concurrent.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_SIGNAL_CONCURRENT_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_SIGNAL_CONCURRENT_H_\r\n#include <pthread.h>\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nclass SignalConcurrentTest : public TestBase {\r\n public:\r\n    SignalConcurrentTest(bool, bool, bool, bool);\r\n\r\n    // @Brief: Destructor for the SignalConcurrentTest class\r\n    virtual ~SignalConcurrentTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    void TestSignalCreateConcurrent(void);\r\n\r\n    void TestSignalDestroyConcurrent(void);\r\n\r\n    void TestSignalCreateMaxConsumers(void);\r\n\r\n    // @Brief: This is not implemented, created a member function for future reference\r\n    void TestSignalCPUCompletion(void);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_SIGNAL_CONCURRENT_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/signal_kernel.cc",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *         AMD Research and AMD ROC Software Development\r\n *\r\n *         Advanced Micro Devices, Inc.\r\n *\r\n *         www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *  this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *  notice, this list of conditions and the following disclaimers in\r\n *  the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *  nor the names of its contributors may be used to endorse or promote\r\n *  products derived from this Software without specific prior written\r\n *  permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#include <inttypes.h>\r\n#include <stdlib.h>\r\n#include <algorithm>\r\n#include <iostream>\r\n#include <vector>\r\n#include \"suites/functional/signal_kernel.h\"\r\n#include \"common/base_rocr_utils.h\"\r\n#include \"common/common.h\"\r\n#include \"common/helper_funcs.h\"\r\n#include \"common/hsatimer.h\"\r\n#include \"common/concurrent_utils.h\"\r\n#include \"gtest/gtest.h\"\r\n#include \"hsa/hsa.h\"\r\n\r\nstatic unsigned int NumOfKernels = 1;\r\n\r\n#define ASSERT_MSG(C, err) { \\\r\n  if (C == 1) { \\\r\n  std::cout << err << std::endl; \\\r\n  } \\\r\n}\r\n\r\nSignalKernelTest::SignalKernelTest(SignalKernelType type_) : TestBase() {\r\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\r\n            // This is a default value which can be overridden\r\n            // on the command line.\r\n  if (type_ == SET) {\r\n  set_title(\"RocR Signal Kernel Set Test\");\r\n  set_description(\"This test verifies that the signal is set from kernel\");\r\n  } else if (type_ == WAIT) {\r\n  set_title(\"RocR Signal Wait Test\");\r\n  set_description(\"This test verifies that the signal is re-set from system side\");\r\n  } else if (type_ == MULTISET) {\r\n  set_title(\"RocR Signal Kernel Multi Set Test\");\r\n  set_description(\"This test verifies that the signal is set on multiple work-items\");\r\n  } else if (type_ ==  MULTIWAIT) {\r\n  set_title(\"RocR Signal Kernel Multi Set Test\");\r\n  set_description(\"This tset verifies that re-set signal from system side, multiple work-items\");\r\n  }\r\n}\r\n\r\nSignalKernelTest::~SignalKernelTest(void) {\r\n}\r\n\r\nvoid SignalKernelTest::SetUp(void) {\r\n  hsa_status_t err;\r\n\r\n  TestBase::SetUp();\r\n\r\n  err = rocrtst::SetDefaultAgents(this);\r\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\r\n\r\n  err = rocrtst::SetPoolsTypical(this);\r\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\r\n  return;\r\n}\r\n\r\n\r\nvoid SignalKernelTest::Run(void) {\r\n// Compare required profile for this test case with what we're actually\r\n// running on\r\n  if (!rocrtst::CheckProfile(this)) {\r\n  return;\r\n  }\r\n\r\n  TestBase::Run();\r\n}\r\n\r\nvoid SignalKernelTest::DisplayTestInfo(void) {\r\n  TestBase::DisplayTestInfo();\r\n}\r\n\r\nvoid SignalKernelTest::DisplayResults(void) const {\r\n  return;\r\n}\r\n\r\nvoid SignalKernelTest::Close() {\r\n  // This will close handles opened within rocrtst utility calls and call\r\n  // hsa_shut_down(), so it should be done after other hsa cleanup\r\n  TestBase::Close();\r\n}\r\n\r\n\r\n\r\n// The kernarg data structure\r\ntypedef struct __attribute__ ((aligned(16))) signal_args_s {\r\n  void *signal_values;\r\n} signal_args_t;\r\nsignal_args_t signal_args;\r\n\r\nvoid SignalKernelTest::KernelSetFunction(SignalKernelType type_) {\r\n  hsa_status_t status;\r\n\r\n  // Get the GPU agents into a vector\r\n  std::vector<hsa_agent_t> agent_list;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &agent_list);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n  // Get CPU agent to get the kern_arg pool\r\n  std::vector<hsa_agent_t> cpu_agent;\r\n  status = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpu_agent);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n  // Repeat the test for each agent\r\n  unsigned int ii;\r\n  for (ii = 0; ii < agent_list.size(); ++ii) {\r\n    // Check if the queue supports dispatch\r\n    uint32_t features = 0;\r\n    status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_FEATURE, &features);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\r\n      continue;\r\n    }\r\n\r\n    // Find a memory pool that supports fine grained memory\r\n    hsa_amd_memory_pool_t global_pool;\r\n    global_pool.handle = (uint64_t)-1;\r\n    status = hsa_amd_agent_iterate_memory_pools(agent_list[ii], rocrtst::GetGlobalMemoryPool, &global_pool);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Obtain the agent's machine model\r\n    hsa_machine_model_t machine_model;\r\n    status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_MACHINE_MODEL, &machine_model);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Find a memory pool that supports kernel arguments\r\n    hsa_amd_memory_pool_t kernarg_pool;\r\n    kernarg_pool.handle = (uint64_t)-1;\r\n    status = hsa_amd_agent_iterate_memory_pools(cpu_agent[0], rocrtst::GetKernArgMemoryPool, &kernarg_pool);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    // Create a queue\r\n    hsa_queue_t* queue;\r\n    status = hsa_queue_create(agent_list[ii], 1024, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n    if (type_ == SET) {\r\n      set_kernel_name(\"signal_st_rlx_kernel\");\r\n    } else if (type_ == MULTISET) {\r\n      set_kernel_name(\"signal_st_rlx_kernel_multi\");\r\n      NumOfKernels = 16;\r\n    } else if (type_ == WAIT) {\r\n      set_kernel_name(\"signal_wait_kernel\");\r\n    } else if (type_ == MULTIWAIT) {\r\n      set_kernel_name(\"signal_wait_kernel_multi\");\r\n      NumOfKernels = 16;\r\n    }\r\n\r\n    status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n\r\n    // Allocate the kernel argument buffer from the correct pool\r\n    signal_args_t* kernarg_buffer = NULL;\r\n    status = hsa_amd_memory_pool_allocate(kernarg_pool,\r\n                 sizeof(signal_args_t), 0,\r\n                   reinterpret_cast<void**>(&kernarg_buffer));\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    status = hsa_amd_agents_allow_access(1, &agent_list[ii], NULL, kernarg_buffer);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    // Create the completion signal\r\n    hsa_signal_t completion_signal;\r\n    status = hsa_signal_create(1, 0, NULL, &completion_signal);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    hsa_amd_memory_pool_access_t access;\r\n    status = hsa_amd_agent_memory_pool_get_info(cpu_agent[0],\r\n                                              global_pool,\r\n                                              HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\r\n                                              &access);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    hsa_signal_t* kernel_signal;\r\n\r\n    if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n     // Create the kernel signal\r\n      status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          NumOfKernels*sizeof(hsa_signal_t), 0,\r\n                                          reinterpret_cast<void**>(&kernel_signal));\r\n      ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n      status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, kernel_signal);\r\n      ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n      for (unsigned int k = 0; k < NumOfKernels; ++k) {\r\n        status = hsa_signal_create(1, 0, NULL, kernel_signal);\r\n        ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n      }\r\n      // Set the signal_args with kernel_signal, will be accessed from Kernel side\r\n      signal_args.signal_values = reinterpret_cast<void*>(kernel_signal);\r\n    }\r\n\r\n    memcpy(kernarg_buffer, &signal_args, sizeof(signal_args_t));\r\n\r\n    // Setup the dispatch packet\r\n    hsa_kernel_dispatch_packet_t dispatch_packet;\r\n    memset(&dispatch_packet, 0, sizeof(hsa_kernel_dispatch_packet_t));\r\n    dispatch_packet.workgroup_size_x = NumOfKernels;\r\n    dispatch_packet.workgroup_size_y = 1;\r\n    dispatch_packet.workgroup_size_z = 1;\r\n    dispatch_packet.grid_size_x = NumOfKernels;\r\n    dispatch_packet.grid_size_y = 1;\r\n    dispatch_packet.grid_size_z = 1;\r\n    dispatch_packet.kernel_object = kernel_object();\r\n    dispatch_packet.group_segment_size = group_segment_size();\r\n    dispatch_packet.private_segment_size = private_segment_size();\r\n    dispatch_packet.kernarg_address = kernarg_buffer;\r\n    dispatch_packet.completion_signal = completion_signal;\r\n\r\n    // const uint32_t queue_size = queue->size;\r\n    const uint32_t queue_mask = queue->size - 1;\r\n\r\n    // write to command queue\r\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n\r\n    rocrtst::WriteAQLToQueueLoc(queue, index, &dispatch_packet);\r\n\r\n\r\n    dispatch_packet.header |= HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\r\n    dispatch_packet.header |= 1 << HSA_PACKET_HEADER_BARRIER;\r\n    dispatch_packet.setup |= 1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\r\n\r\n    void* q_base = queue->base_address;\r\n    // Set the Aql packet header\r\n    rocrtst::AtomicSetPacketHeader(dispatch_packet.header, dispatch_packet.setup,\r\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                            (q_base))[index & queue_mask]);\r\n\r\n    // ringdoor bell\r\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n\r\n    if (type_ == WAIT) {\r\n      for (unsigned int k = 0; k < NumOfKernels; ++k) {\r\n        // setting the kernel_signal to 0 from system side.\r\n        kernel_signal[k].handle = 0;\r\n      }\r\n    }\r\n\r\n    // Wait on the completion signal\r\n    hsa_signal_wait_relaxed(completion_signal, HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\r\n\r\n    // Check kernel signal\r\n    for (unsigned int k = 0; k < NumOfKernels; ++k) {\r\n      ASSERT_EQ(0, (int)(kernel_signal[k].handle));\r\n    }\r\n\r\n    status = hsa_signal_destroy(completion_signal);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n\r\n    if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n      status = hsa_amd_memory_pool_free(kernel_signal);\r\n      ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    }\r\n\r\n    status = hsa_amd_memory_pool_free(kernarg_buffer);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Destroy the queue\r\n    status = hsa_queue_destroy(queue);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n  }\r\n}\r\nvoid SignalKernelTest::TestSignalKernelSet(void) {\r\n  KernelSetFunction(SET);\r\n}\r\n\r\n\r\nvoid SignalKernelTest::TestSignalKernelMultiSet(void) {\r\n  KernelSetFunction(MULTISET);\r\n}\r\n\r\n\r\nvoid SignalKernelTest::TestSignalKernelWait(void) {\r\n  KernelSetFunction(WAIT);\r\n}\r\n\r\n\r\nvoid SignalKernelTest::TestSignalKernelMultiWait(void) {\r\n  hsa_status_t status;\r\n\r\n  // Get the GPU agents into a vector\r\n  std::vector<hsa_agent_t> agent_list;\r\n  status = hsa_iterate_agents(rocrtst::IterateGPUAgents, &agent_list);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n\r\n  // Get CPU agent to get the kern_arg pool\r\n  std::vector<hsa_agent_t> cpu_agent;\r\n  status = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpu_agent);\r\n  ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n  // Repeat the test for each agent\r\n  unsigned int ii;\r\n  for (ii = 0; ii < agent_list.size(); ++ii) {\r\n    // Check if the queue supports dispatch\r\n    uint32_t features = 0;\r\n    status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_FEATURE, &features);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\r\n      continue;\r\n    }\r\n\r\n    // Find a memory pool that supports fine grained memory\r\n    hsa_amd_memory_pool_t global_pool;\r\n    global_pool.handle = (uint64_t)-1;\r\n    status = hsa_amd_agent_iterate_memory_pools(agent_list[ii], rocrtst::GetGlobalMemoryPool, &global_pool);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Obtain the agent's machine model\r\n    hsa_machine_model_t machine_model;\r\n    status = hsa_agent_get_info(agent_list[ii], HSA_AGENT_INFO_MACHINE_MODEL, &machine_model);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n\r\n    // Find a memory pool that supports kernel arguments\r\n    hsa_amd_memory_pool_t kernarg_pool;\r\n    kernarg_pool.handle = (uint64_t)-1;\r\n    status = hsa_amd_agent_iterate_memory_pools(cpu_agent[0], rocrtst::GetKernArgMemoryPool, &kernarg_pool);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Create a queue\r\n    hsa_queue_t* queue;\r\n    status = hsa_queue_create(agent_list[ii], 1024, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n\r\n    set_kernel_file_name(\"signal_operations_kernels.hsaco\");\r\n    set_kernel_name(\"signal_wait_kernel_multi\");\r\n    status = rocrtst::LoadKernelFromObjFile(this, &agent_list[ii]);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Allocate the kernel argument buffer from the correct pool\r\n    signal_args_t* kernarg_buffer = NULL;\r\n    status = hsa_amd_memory_pool_allocate(kernarg_pool,\r\n           sizeof(signal_args_t), 0,\r\n           reinterpret_cast<void**>(&kernarg_buffer));\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    status = hsa_amd_agents_allow_access(1, &agent_list[ii], NULL, kernarg_buffer);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n    // Create the completion signal\r\n    hsa_signal_t completion_signal;\r\n    status = hsa_signal_create(1, 0, NULL, &completion_signal);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    hsa_amd_memory_pool_access_t access;\r\n    status = hsa_amd_agent_memory_pool_get_info(cpu_agent[0],\r\n                                              global_pool,\r\n                                              HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\r\n                                              &access);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    hsa_signal_t* kernel_signal;\r\n\r\n    if (access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\r\n      // Create the kernel signal\r\n      status = hsa_amd_memory_pool_allocate(global_pool,\r\n                                          NumOfKernels*sizeof(hsa_signal_t), 0,\r\n                                          reinterpret_cast<void**>(&kernel_signal));\r\n      ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n      status = hsa_amd_agents_allow_access(1, &cpu_agent[0], NULL, kernel_signal);\r\n      ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n      for (unsigned int k = 0; k < NumOfKernels; ++k) {\r\n       status = hsa_signal_create(1, 0, NULL, kernel_signal + k);\r\n       ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n      }\r\n\r\n      // Set the signal_args with kernel_signal, will be accessed from Kernel side\r\n      signal_args.signal_values = reinterpret_cast<void*>(kernel_signal);\r\n    }\r\n\r\n    memcpy(kernarg_buffer, &signal_args, sizeof(signal_args_t));\r\n\r\n    // Setup the dispatch packet\r\n    hsa_kernel_dispatch_packet_t dispatch_packet;\r\n    memset(&dispatch_packet, 0, sizeof(hsa_kernel_dispatch_packet_t));\r\n\r\n    dispatch_packet.workgroup_size_x = NumOfKernels;\r\n    dispatch_packet.workgroup_size_y = 1;\r\n    dispatch_packet.workgroup_size_z = 1;\r\n    dispatch_packet.grid_size_x = NumOfKernels;\r\n    dispatch_packet.grid_size_y = 1;\r\n    dispatch_packet.grid_size_z = 1;\r\n    dispatch_packet.kernel_object = kernel_object();\r\n    dispatch_packet.group_segment_size = group_segment_size();\r\n    dispatch_packet.private_segment_size = private_segment_size();\r\n    dispatch_packet.kernarg_address = kernarg_buffer;\r\n    dispatch_packet.completion_signal = completion_signal;\r\n\r\n    // const uint32_t queue_size = queue->size;\r\n    const uint32_t queue_mask = queue->size - 1;\r\n    // write to command queue\r\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\r\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\r\n\r\n    rocrtst::WriteAQLToQueueLoc(queue, index, &dispatch_packet);\r\n\r\n\r\n    dispatch_packet.header |= HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\r\n    dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\r\n    dispatch_packet.header |= 1 << HSA_PACKET_HEADER_BARRIER;\r\n    dispatch_packet.setup |= 1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\r\n\r\n    void* q_base = queue->base_address;\r\n    // Set the Aql packet header\r\n    rocrtst::AtomicSetPacketHeader(dispatch_packet.header, dispatch_packet.setup,\r\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\r\n                            (q_base))[index & queue_mask]);\r\n\r\n\r\n    // ringdoor bell\r\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\r\n\r\n    // setting the kernel_signal to 0 from system side.\r\n    for (unsigned int k = 0; k < NumOfKernels; ++k) {\r\n      kernel_signal[k].handle = 0;\r\n    }\r\n    // Wait on the completion signal\r\n    hsa_signal_wait_relaxed(completion_signal, HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\r\n\r\n    // Check kernel signal\r\n    ASSERT_EQ(0, (int)kernel_signal->handle);\r\n\r\n    // destroy the signal created\r\n    status = hsa_signal_destroy(completion_signal);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    status = hsa_amd_memory_pool_free(kernarg_buffer);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n\r\n    // Destroy the queue\r\n    status = hsa_queue_destroy(queue);\r\n    ASSERT_EQ(status, HSA_STATUS_SUCCESS);\r\n  }\r\n}\r\n\r\n"
  },
  {
    "path": "rocrtst/suites/functional/signal_kernel.h",
    "content": "/*\r\n * =============================================================================\r\n *   ROC Runtime Conformance Release License\r\n * =============================================================================\r\n * The University of Illinois/NCSA\r\n * Open Source License (NCSA)\r\n *\r\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\r\n * All rights reserved.\r\n *\r\n * Developed by:\r\n *\r\n *                 AMD Research and AMD ROC Software Development\r\n *\r\n *                 Advanced Micro Devices, Inc.\r\n *\r\n *                 www.amd.com\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to\r\n * deal with the Software without restriction, including without limitation\r\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r\n * and/or sell copies of the Software, and to permit persons to whom the\r\n * Software is furnished to do so, subject to the following conditions:\r\n *\r\n *  - Redistributions of source code must retain the above copyright notice,\r\n *    this list of conditions and the following disclaimers.\r\n *  - Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimers in\r\n *    the documentation and/or other materials provided with the distribution.\r\n *  - Neither the names of <Name of Development Group, Name of Institution>,\r\n *    nor the names of its contributors may be used to endorse or promote\r\n *    products derived from this Software without specific prior written\r\n *    permission.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\r\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\r\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\r\n * DEALINGS WITH THE SOFTWARE.\r\n *\r\n */\r\n\r\n#ifndef ROCRTST_SUITES_FUNCTIONAL_SIGNAL_KERNEL_H_\r\n#define ROCRTST_SUITES_FUNCTIONAL_SIGNAL_KERNEL_H_\r\n#include \"common/base_rocr.h\"\r\n#include \"hsa/hsa.h\"\r\n#include \"suites/test_common/test_base.h\"\r\n\r\nenum SignalKernelType {\r\n\tSET,  // For signal kernel set operation\r\n\tMULTISET, // For multiple kernel set operation\r\n\tWAIT, // For single wait operation\r\n    MULTIWAIT, // For multiple wait operation\r\n\tNOTEST  // No operation\r\n}; \r\nclass SignalKernelTest : public TestBase {\r\n public:\r\n    SignalKernelTest(SignalKernelType);\r\n\r\n    // @Brief: Destructor for the SignalKernelTest class\r\n    virtual ~SignalKernelTest();\r\n\r\n    // @Brief: Setup the environment for measurement\r\n    virtual void SetUp();\r\n\r\n    // @Brief: Core measurement execution\r\n    virtual void Run();\r\n\r\n    // @Brief: Clean up and retrive the resource\r\n    virtual void Close();\r\n\r\n    // @Brief: Display  results\r\n    virtual void DisplayResults() const;\r\n\r\n    // @Brief: Display information about what this test does\r\n    virtual void DisplayTestInfo(void);\r\n\r\n    void TestSignalKernelSet(void);\r\n\r\n    void TestSignalKernelWait(void);\r\n\r\n    void TestSignalKernelMultiSet(void);\r\n\r\n    void TestSignalKernelMultiWait(void);\r\n\r\n    void KernelSetFunction(SignalKernelType);\r\n};\r\n\r\n#endif  // ROCRTST_SUITES_FUNCTIONAL_SIGNAL_KERNEL_H_\r\n"
  },
  {
    "path": "rocrtst/suites/functional/virtual_memory.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <sys/mman.h>\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <sys/socket.h>\n\n#include \"suites/functional/virtual_memory.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"common/concurrent_utils.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n// Wrap printf to add first or second process indicator\n#define PROCESS_LOG(format, ...)                                                                   \\\n  {                                                                                                \\\n    if (verbosity() >= VERBOSE_STANDARD || !parentProcess_) {                                      \\\n      fprintf(stdout, \"line:%d P%u: \" format, __LINE__, static_cast<int>(!parentProcess_),         \\\n              ##__VA_ARGS__);                                                                      \\\n    }                                                                                              \\\n  }\n\n// Fork safe ASSERT_EQ.\n#define MSG(y, msg, ...) msg\n#define Y(y, ...) y\n\n#define FORK_ASSERT_EQ(x, ...)                                                                     \\\n  if ((x) != (Y(__VA_ARGS__))) {                                                                   \\\n    if ((x) != (Y(__VA_ARGS__))) {                                                                 \\\n      std::cout << MSG(__VA_ARGS__, \"\");                                                           \\\n      if (parentProcess_) {                                                                        \\\n        shared_->parent_status = -1;                                                               \\\n      } else {                                                                                     \\\n        shared_->child_status = -1;                                                                \\\n      }                                                                                            \\\n      ASSERT_EQ(x, Y(__VA_ARGS__));                                                                \\\n    }                                                                                              \\\n  }\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char* header) {\n  std::cout << \"  *** Virtual Memory Functional Subtest: \" << header << \" ***\" << std::endl;\n}\n\nVirtMemoryTestBasic::VirtMemoryTestBasic(void) : TestBase() {\n  set_title(\"ROCr Virtual Memory Basic Tests\");\n  set_description(\" Tests virtual memory API functions\");\n}\n\nVirtMemoryTestBasic::~VirtMemoryTestBasic(void) {}\n\nvoid VirtMemoryTestBasic::TestCreateDestroy(hsa_agent_t agent, hsa_amd_memory_pool_t pool) {\n  std::vector<hsa_agent_t> gpus;\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  void* addrRangeUnmapped;\n  hsa_status_t err;\n  void* addrRange;\n\n  ASSERT_SUCCESS(hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type));\n\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(pool, &pool_i));\n\n  if (ag_type != HSA_DEVICE_TYPE_GPU || !pool_i.alloc_allowed) return;\n\n  size_t granule_size = pool_i.alloc_granule;\n\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRange, 20 * granule_size, 0, 0));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRangeUnmapped, 10 * granule_size, 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t mem_handle;\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_handle_create(pool, 10 * granule_size, MEMORY_TYPE_NONE, 0, &mem_handle));\n\n  /* Test alloc properties returns correct memory type and pool handle */\n  hsa_amd_memory_pool_t poolRet;\n  hsa_amd_memory_type_t memTypeRet;\n  ASSERT_SUCCESS(hsa_amd_vmem_get_alloc_properties_from_handle(mem_handle, &poolRet, &memTypeRet));\n\n  ASSERT_EQ(poolRet.handle, pool.handle);\n  ASSERT_EQ(memTypeRet, MEMORY_TYPE_NONE);\n\n  hsa_amd_vmem_alloc_handle_t mem_handleTypePinned;\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_create(pool, 10 * granule_size, MEMORY_TYPE_PINNED, 0,\n                                            &mem_handleTypePinned));\n\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_get_alloc_properties_from_handle(mem_handleTypePinned, &poolRet, &memTypeRet));\n  ASSERT_EQ(poolRet.handle, pool.handle);\n  ASSERT_EQ(memTypeRet, MEMORY_TYPE_PINNED);\n\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map(addrRange, 10 * granule_size, 0, mem_handle, 0));\n\n  // Access to each GPU should be None\n  for (auto gpuIt = gpus.begin(); gpuIt != gpus.end(); ++gpuIt) {\n    hsa_access_permission_t perm = HSA_ACCESS_PERMISSION_RW;\n\n    ASSERT_SUCCESS(hsa_amd_vmem_get_access(addrRange, &perm, *gpuIt));\n    ASSERT_EQ(perm, HSA_ACCESS_PERMISSION_NONE);\n  }\n\n  /* Set RO Access to all GPUs */\n  {\n    int descIndex = 0;\n    hsa_amd_memory_access_desc_t desc[gpus.size()];\n    for (auto gpuIt = gpus.begin(); gpuIt != gpus.end(); ++gpuIt) {\n      desc[descIndex++] = {HSA_ACCESS_PERMISSION_RO, *gpuIt};\n    }\n\n    ASSERT_SUCCESS(hsa_amd_vmem_set_access(addrRange, 10 * granule_size, desc, gpus.size()));\n  }\n\n  for (auto gpuIt = gpus.begin(); gpuIt != gpus.end(); ++gpuIt) {\n    hsa_access_permission_t perm = HSA_ACCESS_PERMISSION_NONE;\n\n    ASSERT_SUCCESS(hsa_amd_vmem_get_access(addrRange, &perm, *gpuIt));\n    ASSERT_EQ(perm, HSA_ACCESS_PERMISSION_RO);\n\n    /* addrRangeUnmapped was never mapped, so this is an invalid mapping */\n    err = hsa_amd_vmem_get_access(addrRangeUnmapped, &perm, *gpuIt);\n    ASSERT_EQ(err, HSA_STATUS_ERROR_INVALID_ALLOCATION);\n  }\n\n  if (gpus.size() > 1) {\n    /* Call set_access with a smaller list of agents, this should leave access to\n     * the other GPUs unchanged */\n    hsa_amd_memory_access_desc_t desc = {HSA_ACCESS_PERMISSION_RW, gpus[1]};\n    ASSERT_SUCCESS(hsa_amd_vmem_set_access(addrRange, 10 * granule_size, &desc, 1));\n\n    size_t i = 0;\n    for (i = 0; i < gpus.size(); i++) {\n      hsa_access_permission_t perm = HSA_ACCESS_PERMISSION_NONE;\n\n      /* Only 2nd GPU should have RW access */\n      ASSERT_SUCCESS(hsa_amd_vmem_get_access(addrRange, &perm, gpus[i]));\n      if (i == 1) {\n        ASSERT_EQ(perm, HSA_ACCESS_PERMISSION_RW);\n      } else {\n        ASSERT_EQ(perm, HSA_ACCESS_PERMISSION_RO);\n      }\n    }\n  }\n\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(addrRange, 10 * granule_size));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handle));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addrRange, 20 * granule_size));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addrRangeUnmapped, 10 * granule_size));\n}\n\nvoid VirtMemoryTestBasic::TestCreateDestroy(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"CreateDestroy Test\");\n  }\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  ASSERT_SUCCESS(rocrtst::GetAgentPools(&agent_pools));\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      TestCreateDestroy(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid VirtMemoryTestBasic::TestRefCount(hsa_agent_t agent, hsa_amd_memory_pool_t pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  void* addrRangeUnmapped;\n  hsa_status_t err;\n  void* addrRange;\n\n  ASSERT_SUCCESS(hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, ag_name));\n  ASSERT_SUCCESS(hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type));\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(pool, &pool_i));\n\n  if (ag_type != HSA_DEVICE_TYPE_GPU || !pool_i.alloc_allowed) return;\n\n  size_t granule_size = pool_i.alloc_granule;\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRange, 10 * granule_size, 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t mem_handleA1;\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_handle_create(pool, 10 * granule_size, MEMORY_TYPE_NONE, 0, &mem_handleA1));\n  ASSERT_SUCCESS(hsa_amd_vmem_map(addrRange, 10 * granule_size, 0, mem_handleA1, 0));\n\n  /* Allocate duplicate handle */\n  hsa_amd_vmem_alloc_handle_t mem_handleA1Dup;\n  ASSERT_SUCCESS(hsa_amd_vmem_retain_alloc_handle(&mem_handleA1Dup, addrRange));\n\n  /* Try to unmap with incorrect size */\n  err = hsa_amd_vmem_unmap(addrRange, 5 * granule_size);\n  ASSERT_NE(err, HSA_STATUS_SUCCESS);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handleA1));\n\n  /* Try to release duplicate handle twice - second time should fail */\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handleA1Dup));\n\n  /* Already released so should fail*/\n  err = hsa_amd_vmem_handle_release(mem_handleA1Dup);\n  ASSERT_NE(err, HSA_STATUS_SUCCESS);\n\n  /* Unmap with correct size - un-mapping after releasing the handle is valid */\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(addrRange, 10 * granule_size));\n\n  /* Try to free with incorrect size */\n  err = hsa_amd_vmem_address_free(addrRange, 5 * granule_size);\n  ASSERT_NE(err, HSA_STATUS_SUCCESS);\n\n  /* Free with correct size */\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addrRange, 10 * granule_size));\n}\n\nvoid VirtMemoryTestBasic::TestRefCount(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"Reference Count Test\");\n  }\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n  ASSERT_SUCCESS(rocrtst::GetAgentPools(&agent_pools));\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) TestRefCount(a->agent, p);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid VirtMemoryTestBasic::TestPartialMapping(hsa_agent_t agent, hsa_amd_memory_pool_t pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  void* addrRangeUnmapped;\n  hsa_status_t err;\n  void* addrRange;\n\n  ASSERT_SUCCESS(hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type));\n\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(pool, &pool_i));\n\n  if (ag_type != HSA_DEVICE_TYPE_GPU || !pool_i.alloc_allowed) return;\n\n  size_t granule_size = pool_i.alloc_granule;\n\n  /************************************************************************************************\n    Map partial chunks within the address range and confirm what overlaps fail.\n    Units below are in multiples of granule_size.\n\n              ------------------------------------------------------------------\n              | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |\n              ------------------------------------------------------------------\n    Step 1:             A   A   A   A   A   A\n    Step 2:                                                  B    B    B\n    Step 3:                                                                 B\n    Step 4:                                     B   B    B\n\n   ***********************************************************************************************/\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRange, 15 * granule_size, 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t mem_handleA;\n\n  // Step 1\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_handle_create(pool, 8 * granule_size, MEMORY_TYPE_NONE, 0, &mem_handleA));\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map((void*)((uint64_t)addrRange + (2 * granule_size)),\n                                  6 * granule_size, 0, mem_handleA, 0));\n\n  // Step 2\n  hsa_amd_vmem_alloc_handle_t mem_handleB;\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_handle_create(pool, 8 * granule_size, MEMORY_TYPE_NONE, 0, &mem_handleB));\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map((void*)((uint64_t)addrRange + (11 * granule_size)),\n                                  3 * granule_size, 0, mem_handleB, 0));\n\n  // Step 3\n  // Should fail as this is exceeding size of address range\n  err = hsa_amd_vmem_map((void*)((uint64_t)addrRange + (14 * granule_size)),\n                                  2 * granule_size, 0, mem_handleB, 0);\n  ASSERT_NE(err, HSA_STATUS_SUCCESS);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map((void*)((uint64_t)addrRange + (14 * granule_size)),\n                                  1 * granule_size, 0, mem_handleB, 0));\n\n  // Step 4\n  // Should fail as this is overlapping with AddressRange[11] already mapped\n  err = hsa_amd_vmem_map((void*)((uint64_t)addrRange + (8 * granule_size)),\n                                  4 * granule_size, 0, mem_handleB, 0);\n  ASSERT_NE(err, HSA_STATUS_SUCCESS);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map((void*)((uint64_t)addrRange + (8 * granule_size)),\n                                  3 * granule_size, 0, mem_handleB, 0));\n\n  // Done, unmap all\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_unmap((void*)((uint64_t)addrRange + (2 * granule_size)), 6 * granule_size));\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_unmap((void*)((uint64_t)addrRange + (8 * granule_size)), 3 * granule_size));\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_unmap((void*)((uint64_t)addrRange + (11 * granule_size)), 3 * granule_size));\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_unmap((void*)((uint64_t)addrRange + (14 * granule_size)), 1 * granule_size));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addrRange, 15 * granule_size));\n}\n\nvoid VirtMemoryTestBasic::TestPartialMapping(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"Partial Mapping Test\");\n  }\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  ASSERT_SUCCESS(rocrtst::GetAgentPools(&agent_pools));\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) TestPartialMapping(a->agent, p);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\ntypedef struct __attribute__((aligned(16))) args_t {\n  int* a;\n  int* b;\n  int* c;\n} args;\n\nargs* kernArgsVirt = NULL;\n\n// Test to check CPU can read & write to GPU memory\nvoid VirtMemoryTestBasic::CPUAccessToGPUMemoryTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent,\n                                                   hsa_amd_memory_pool_t device_pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(device_pool, &pool_i));\n\n  if (!(pool_i.segment == HSA_AMD_SEGMENT_GLOBAL &&\n        pool_i.global_flag == HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED))\n    return;\n\n  hsa_amd_memory_pool_access_t access;\n  hsa_amd_agent_memory_pool_get_info(cpuAgent, device_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                     &access);\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    if (verbosity() > 0) {\n      std::cout << \"    Test not applicable as system is not large bar - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n  if (!pool_i.alloc_allowed || pool_i.alloc_granule == 0 || pool_i.alloc_alignment == 0) {\n    if (verbosity() > 0) {\n      std::cout << \"    Test not applicable. Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  auto max_alloc_size = pool_i.alloc_granule * 100;\n  unsigned int max_element = max_alloc_size / sizeof(unsigned int);\n  unsigned int* dev_data = NULL;\n  unsigned int* host_data = NULL;\n  host_data = (unsigned int*)malloc(max_alloc_size);\n\n  ASSERT_NE(host_data, nullptr);\n\n  for (unsigned int i = 0; i < max_element; ++i) {\n    host_data[i] = i;\n  }\n\n  hsa_amd_memory_access_desc_t permsAccess[] = {{HSA_ACCESS_PERMISSION_RW, cpuAgent},\n                                                {HSA_ACCESS_PERMISSION_RW, gpuAgent}};\n\n  hsa_amd_vmem_alloc_handle_t mem_handle_host, mem_handle_dev;\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_address_reserve(reinterpret_cast<void**>(&dev_data), max_alloc_size, 0, 0));\n\n  ASSERT_NE(dev_data, nullptr);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_create(device_pool, max_alloc_size, MEMORY_TYPE_NONE, 0,\n                                            &mem_handle_dev));\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_map(reinterpret_cast<void*>(dev_data), max_alloc_size, 0, mem_handle_dev, 0));\n\n  // Give device access to host data\n  ASSERT_SUCCESS(hsa_amd_vmem_set_access(dev_data, max_alloc_size, permsAccess, 2));\n\n  // Verify CPU can read & write to GPU memory\n  std::cout << \"    Verify CPU can read & write to GPU memory\" << std::endl;\n  for (unsigned int i = 0; i < max_element; ++i) {\n    dev_data[i] = i;  // Write to gpu memory directly\n  }\n\n  for (unsigned int i = 0; i < max_element; ++i) {\n    if (host_data[i] != dev_data[i]) {  // Reading GPU memory\n      fprintf(stdout,\n              \"    Values not mathing !! host_data[%d]:%d ,\"\n              \"dev_data[%d]\\n\",\n              host_data[i], i, dev_data[i]);\n    }\n  }\n  std::cout << \"    CPU have read & write to GPU memory successfully\" << std::endl;\n\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(dev_data, max_alloc_size));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handle_dev));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(reinterpret_cast<void*>(dev_data), max_alloc_size));\n  free(host_data);\n}\n\nvoid VirtMemoryTestBasic::CPUAccessToGPUMemoryTest(void) {\n  hsa_status_t err;\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus));\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n\n  if (verbosity() > 0) PrintMemorySubtestHeader(\"CPU To GPU Access test\");\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  for (unsigned int i = 0; i < gpus.size(); ++i) {\n    hsa_amd_memory_pool_t gpu_pool;\n    memset(&gpu_pool, 0, sizeof(gpu_pool));\n    ASSERT_SUCCESS(\n        hsa_amd_agent_iterate_memory_pools(gpus[i], rocrtst::GetGlobalMemoryPool, &gpu_pool));\n    if (gpu_pool.handle == 0) {\n      std::cout << \"    No global mempool in gpu agent\" << std::endl;\n      return;\n    }\n    CPUAccessToGPUMemoryTest(cpus[0], gpus[i], gpu_pool);\n  }\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n// Test to check GPU can read & write to CPU memory\nvoid VirtMemoryTestBasic::GPUAccessToCPUMemoryTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent,\n                                                   hsa_amd_memory_pool_t device_pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  hsa_status_t err;\n\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(device_pool, &pool_i));\n\n  if (!pool_i.alloc_allowed || pool_i.segment != HSA_AMD_SEGMENT_GLOBAL ||\n      pool_i.global_flag != HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED)\n    return;\n\n  hsa_amd_memory_pool_access_t access;\n  ASSERT_SUCCESS(hsa_amd_agent_memory_pool_get_info(\n      cpuAgent, device_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access));\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    if (verbosity() > 0) {\n      std::cout << \"    Test not applicable as system is not large bar - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n      return;\n    }\n  }\n\n  hsa_queue_t* queue = NULL;  // command queue\n  hsa_signal_t signal = {0};  // completion signal\n\n  size_t& granule_size = pool_i.alloc_granule;\n  size_t alloc_size = granule_size * 100;\n  static const int kMemoryAllocSize = 1024;\n  unsigned int max_element = alloc_size / sizeof(unsigned int);\n\n  // get queue size\n  uint32_t queue_size = 0;\n  ASSERT_SUCCESS(hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size));\n\n  // create queue\n  ASSERT_SUCCESS(\n      hsa_queue_create(gpuAgent, queue_size, HSA_QUEUE_TYPE_MULTI, NULL, NULL, 0, 0, &queue));\n\n  // Find a memory pool that supports kernel arguments.\n  hsa_amd_memory_pool_t kernarg_pool;\n  ASSERT_SUCCESS(\n      hsa_amd_agent_iterate_memory_pools(cpuAgent, rocrtst::GetKernArgMemoryPool, &kernarg_pool));\n\n  // Get System Memory Pool on the cpuAgent to allocate host side buffers\n  hsa_amd_memory_pool_t global_pool;\n  ASSERT_SUCCESS(\n      hsa_amd_agent_iterate_memory_pools(cpuAgent, rocrtst::GetGlobalMemoryPool, &global_pool));\n\n  struct host_data_t {\n    int data[kMemoryAllocSize * 4];\n    int dup_data[kMemoryAllocSize * 4];\n    int result[kMemoryAllocSize * 4];\n  };\n\n  struct dev_data_t {\n    int result[kMemoryAllocSize * 4];\n  };\n\n\n  struct host_data_t* host_data;\n  struct dev_data_t* dev_data;\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_allocate(global_pool, sizeof(*host_data), 0,\n                                              reinterpret_cast<void**>(&host_data)));\n\n  // Allow gpuAgent access to all allocated system memory.\n  ASSERT_SUCCESS(hsa_amd_agents_allow_access(1, &gpuAgent, NULL, host_data));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve((void**)&dev_data, sizeof(*dev_data), 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t mem_handle;\n\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_handle_create(device_pool, sizeof(*dev_data), MEMORY_TYPE_NONE, 0, &mem_handle));\n  ASSERT_SUCCESS(hsa_amd_vmem_map(dev_data, sizeof(*dev_data), 0, mem_handle, 0));\n\n  // Give host and device access to device data\n  hsa_amd_memory_access_desc_t permsAccess[] = {{HSA_ACCESS_PERMISSION_RW, gpuAgent},\n                                                {HSA_ACCESS_PERMISSION_RW, cpuAgent}};\n\n  ASSERT_SUCCESS(hsa_amd_vmem_set_access(dev_data, sizeof(*dev_data), permsAccess, 2));\n\n  // Allocate the kernel argument buffer from the kernarg_pool.\n  ASSERT_SUCCESS(hsa_amd_memory_pool_allocate(kernarg_pool, sizeof(args_t), 0,\n                                              reinterpret_cast<void**>(&kernArgsVirt)));\n\n  // initialize the host buffers\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    unsigned int seed = time(NULL);\n    host_data->data[i] = 1 + rand_r(&seed) % 1;\n    host_data->dup_data[i] = host_data->data[i];\n  }\n\n  memset(host_data->result, 0, sizeof(host_data->result));\n  memset(dev_data->result, 0, sizeof(dev_data->result));\n\n  ASSERT_SUCCESS(hsa_amd_agents_allow_access(1, &gpuAgent, NULL, kernArgsVirt));\n\n  kernArgsVirt->a = host_data->data;\n  kernArgsVirt->b = host_data->result;  // system memory passed to gpu for write\n  kernArgsVirt->c = dev_data->result;   // gpu memory to verify that gpu read system data\n\n  // Create the executable, get symbol by name and load the code object\n  set_kernel_file_name(\"gpuReadWrite_kernels.hsaco\");\n  set_kernel_name(\"gpuReadWrite\");\n  ASSERT_SUCCESS(rocrtst::LoadKernelFromObjFile(this, &gpuAgent));\n\n  // Fill the dispatch packet with\n  // workgroup_size, grid_size, kernelArgs and completion signal\n  // Put it on the queue and launch the kernel by ringing the doorbell\n\n  // create completion signal\n  ASSERT_SUCCESS(hsa_signal_create(1, 0, NULL, &signal));\n\n  // create aql packet\n  hsa_kernel_dispatch_packet_t aql;\n  memset(&aql, 0, sizeof(aql));\n\n  // initialize aql packet\n  aql.workgroup_size_x = 256;\n  aql.workgroup_size_y = 1;\n  aql.workgroup_size_z = 1;\n  aql.grid_size_x = kMemoryAllocSize;\n  aql.grid_size_y = 1;\n  aql.grid_size_z = 1;\n  aql.private_segment_size = 0;\n  aql.group_segment_size = 0;\n  aql.kernel_object = kernel_object();  // kernel_code;\n  aql.kernarg_address = kernArgsVirt;\n  aql.completion_signal = signal;\n\n  // const uint32_t queue_size = queue->size;\n  const uint32_t queue_mask = queue->size - 1;\n\n  // write to command queue\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n  rocrtst::WriteAQLToQueueLoc(queue, index, &aql);\n\n  hsa_kernel_dispatch_packet_t* q_base_addr =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue->base_address);\n  rocrtst::AtomicSetPacketHeader(\n      (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n          (1 << HSA_PACKET_HEADER_BARRIER) |\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE) |\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE),\n      (1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS),\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(&q_base_addr[index & queue_mask]));\n\n  // ringdoor bell\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\n  // wait for the signal and reset it for future use\n  while (hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,\n                                   HSA_WAIT_STATE_ACTIVE)) {\n  }\n  hsa_signal_store_relaxed(signal, 1);\n\n  // compare device and host side results\n  if (verbosity() > 0) {\n    std::cout << \"    Check GPU has read the system memory\" << std::endl;\n  }\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    // printf(\"Verifying data at index[%d]\\n\", i);\n    ASSERT_EQ(dev_data->result[i], host_data->dup_data[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    GPU has read the system memory successfully\" << std::endl;\n    std::cout << \"    Check GPU has written to system memory\" << std::endl;\n  }\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    ASSERT_EQ(host_data->result[i], i);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    GPU has written to system memory successfully\" << std::endl;\n  }\n\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(dev_data, sizeof(*dev_data)));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handle));\n\n  if (dev_data) {\n    ASSERT_SUCCESS(hsa_amd_vmem_address_free(dev_data, sizeof(*dev_data)));\n  }\n\n  if (host_data) hsa_memory_free(host_data);\n  if (kernArgsVirt) {\n    hsa_memory_free(kernArgsVirt);\n  }\n  if (signal.handle) {\n    hsa_signal_destroy(signal);\n  }\n  if (queue) {\n    hsa_queue_destroy(queue);\n  }\n}\n\nvoid VirtMemoryTestBasic::GPUAccessToCPUMemoryTest(void) {\n  hsa_status_t err;\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus));\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n\n  if (verbosity() > 0) PrintMemorySubtestHeader(\"CPU To GPU Access test\");\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  for (unsigned int i = 0; i < gpus.size(); ++i) {\n    hsa_amd_memory_pool_t gpu_pool;\n    memset(&gpu_pool, 0, sizeof(gpu_pool));\n    ASSERT_SUCCESS(\n        hsa_amd_agent_iterate_memory_pools(gpus[i], rocrtst::GetGlobalMemoryPool, &gpu_pool));\n    if (gpu_pool.handle == 0) {\n      std::cout << \"no global mempool in GPU agent\" << std::endl;\n      return;\n    }\n    GPUAccessToCPUMemoryTest(cpus[0], gpus[i], gpu_pool);\n  }\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n// Test to check GPU can read & write to GPU memory\nvoid VirtMemoryTestBasic::GPUAccessToGPUMemoryTest(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent,\n                                                   hsa_amd_memory_pool_t device_pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  hsa_status_t err;\n\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(device_pool, &pool_i));\n\n  if (!pool_i.alloc_allowed || pool_i.segment != HSA_AMD_SEGMENT_GLOBAL ||\n      pool_i.global_flag != HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED)\n    return;\n\n  hsa_amd_memory_pool_access_t access;\n  ASSERT_SUCCESS(hsa_amd_agent_memory_pool_get_info(\n      cpuAgent, device_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access));\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    if (verbosity() > 0) {\n      std::cout << \"    Test not applicable as system is not large bar - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n      return;\n    }\n  }\n\n  hsa_queue_t* queue = NULL;  // command queue\n  hsa_signal_t signal = {0};  // completion signal\n\n  size_t& granule_size = pool_i.alloc_granule;\n  size_t alloc_size = granule_size * 100;\n  static const int kMemoryAllocSize = 4096;\n  unsigned int max_element = alloc_size / sizeof(unsigned int);\n\n  // get queue size\n  uint32_t queue_size = 0;\n  ASSERT_SUCCESS(hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size));\n\n  // create queue\n  ASSERT_SUCCESS(\n      hsa_queue_create(gpuAgent, queue_size, HSA_QUEUE_TYPE_MULTI, NULL, NULL, 0, 0, &queue));\n\n  // Find a memory pool that supports kernel arguments.\n  hsa_amd_memory_pool_t kernarg_pool;\n  ASSERT_SUCCESS(\n      hsa_amd_agent_iterate_memory_pools(cpuAgent, rocrtst::GetKernArgMemoryPool, &kernarg_pool));\n\n  // Get System Memory Pool on the cpuAgent to allocate host side buffers\n  hsa_amd_memory_pool_t global_pool;\n  ASSERT_SUCCESS(\n      hsa_amd_agent_iterate_memory_pools(cpuAgent, rocrtst::GetGlobalMemoryPool, &global_pool));\n\n  struct host_data_t {\n    int data[kMemoryAllocSize * 4];\n    int gpuWrite[kMemoryAllocSize * 4];\n    int result[kMemoryAllocSize * 4];\n  };\n\n  struct dev_data_t {\n    int data[kMemoryAllocSize * 4];\n    int result[kMemoryAllocSize * 4];\n  };\n\n\n  struct host_data_t* host_data;\n  struct dev_data_t* dev_data;\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_allocate(global_pool, sizeof(*host_data), 0,\n                                              reinterpret_cast<void**>(&host_data)));\n\n  // Allow gpuAgent access to all allocated system memory.\n  ASSERT_SUCCESS(hsa_amd_agents_allow_access(1, &gpuAgent, NULL, host_data));\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve((void**)&dev_data, sizeof(*dev_data), 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t mem_handle;\n\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_create(device_pool, sizeof(*dev_data), MEMORY_TYPE_PINNED, 0,\n                                            &mem_handle));\n\n  ASSERT_SUCCESS(hsa_amd_vmem_map(dev_data, sizeof(*dev_data), 0, mem_handle, 0));\n\n  // Give host and device access to device data\n  hsa_amd_memory_access_desc_t permsAccess[] = {{HSA_ACCESS_PERMISSION_RW, gpuAgent}};\n\n  ASSERT_SUCCESS(\n      hsa_amd_vmem_set_access(dev_data, sizeof(*dev_data), permsAccess, ARRAY_SIZE(permsAccess)));\n\n  // Allocate the kernel argument buffer from the kernarg_pool.\n  ASSERT_SUCCESS(hsa_amd_memory_pool_allocate(kernarg_pool, sizeof(args_t), 0,\n                                              reinterpret_cast<void**>(&kernArgsVirt)));\n\n  // create completion signal\n  ASSERT_SUCCESS(hsa_signal_create(1, 0, NULL, &signal));\n\n  // initialize the host buffers\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    unsigned int seed = time(NULL);\n    host_data->data[i] = 1 + rand_r(&seed) % 1;\n  }\n\n  ASSERT_SUCCESS(hsa_amd_memory_async_copy(dev_data->data, gpuAgent, host_data->data, cpuAgent,\n                                           kMemoryAllocSize * 4, 0, NULL, signal));\n\n  while (hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,\n                                   HSA_WAIT_STATE_ACTIVE)) {\n  }\n  hsa_signal_store_relaxed(signal, 1);\n\n  memset(host_data->result, 0, sizeof(host_data->result));\n\n  ASSERT_SUCCESS(hsa_amd_agents_allow_access(1, &gpuAgent, NULL, kernArgsVirt));\n\n\n  kernArgsVirt->a = dev_data->data;\n  kernArgsVirt->b = host_data->gpuWrite;  // system memory passed to gpu for write\n  kernArgsVirt->c = dev_data->result;     // gpu memory to verify that gpu read system data\n\n  // Create the executable, get symbol by name and load the code object\n  set_kernel_file_name(\"gpuReadWrite_kernels.hsaco\");\n  set_kernel_name(\"gpuReadWrite\");\n  ASSERT_SUCCESS(rocrtst::LoadKernelFromObjFile(this, &gpuAgent));\n\n  // Fill the dispatch packet with\n  // workgroup_size, grid_size, kernelArgs and completion signal\n  // Put it on the queue and launch the kernel by ringing the doorbell\n\n  // create aql packet\n  hsa_kernel_dispatch_packet_t aql;\n  memset(&aql, 0, sizeof(aql));\n\n  // initialize aql packet\n  aql.workgroup_size_x = 256;\n  aql.workgroup_size_y = 1;\n  aql.workgroup_size_z = 1;\n  aql.grid_size_x = kMemoryAllocSize;\n  aql.grid_size_y = 1;\n  aql.grid_size_z = 1;\n  aql.private_segment_size = 0;\n  aql.group_segment_size = 0;\n  aql.kernel_object = kernel_object();  // kernel_code;\n  aql.kernarg_address = kernArgsVirt;\n  aql.completion_signal = signal;\n\n  const uint32_t queue_mask = queue->size - 1;\n\n  // write to command queue\n  uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n  hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n  rocrtst::WriteAQLToQueueLoc(queue, index, &aql);\n\n  hsa_kernel_dispatch_packet_t* q_base_addr =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue->base_address);\n  rocrtst::AtomicSetPacketHeader(\n      (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n          (1 << HSA_PACKET_HEADER_BARRIER) |\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE) |\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE),\n      (1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS),\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(&q_base_addr[index & queue_mask]));\n\n  // ringdoor bell\n  hsa_signal_store_relaxed(queue->doorbell_signal, index);\n  // wait for the signal and reset it for future use\n  while (hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,\n                                   HSA_WAIT_STATE_ACTIVE)) {\n  }\n  hsa_signal_store_relaxed(signal, 1);\n\n  ASSERT_SUCCESS(hsa_amd_memory_async_copy(host_data->result, cpuAgent, dev_data->result, gpuAgent,\n                                           kMemoryAllocSize * 4, 0, NULL, signal));\n\n  while (hsa_signal_wait_scacquire(signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,\n                                   HSA_WAIT_STATE_ACTIVE)) {\n  }\n  // compare device and host side results\n  if (verbosity() > 0) {\n    std::cout << \"    Check GPU has read the system memory\" << std::endl;\n  }\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    // printf(\"Verifying data at index[%d]\\n\", i);\n    ASSERT_EQ(host_data->result[i], host_data->data[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    GPU has read the system memory successfully\" << std::endl;\n    std::cout << \"    Check GPU has written to system memory\" << std::endl;\n  }\n  for (int i = 0; i < kMemoryAllocSize; ++i) {\n    ASSERT_EQ(host_data->gpuWrite[i], i);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"    GPU has written to system memory successfully\" << std::endl;\n  }\n\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(dev_data, sizeof(*dev_data)));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(mem_handle));\n\n  if (dev_data) {\n    ASSERT_SUCCESS(hsa_amd_vmem_address_free(dev_data, sizeof(*dev_data)));\n  }\n\n  if (host_data) hsa_memory_free(host_data);\n  if (kernArgsVirt) {\n    hsa_memory_free(kernArgsVirt);\n  }\n  if (signal.handle) {\n    hsa_signal_destroy(signal);\n  }\n  if (queue) {\n    hsa_queue_destroy(queue);\n  }\n}\n\nvoid VirtMemoryTestBasic::GPUAccessToGPUMemoryTest(void) {\n  hsa_status_t err;\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus));\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n\n  if (verbosity() > 0) PrintMemorySubtestHeader(\"GPU To GPU Access test\");\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  for (unsigned int i = 0; i < gpus.size(); ++i) {\n    hsa_amd_memory_pool_t gpu_pool;\n    memset(&gpu_pool, 0, sizeof(gpu_pool));\n    ASSERT_SUCCESS(\n        hsa_amd_agent_iterate_memory_pools(gpus[i], rocrtst::GetGlobalMemoryPool, &gpu_pool));\n    if (gpu_pool.handle == 0) {\n      std::cout << \"no global mempool in GPU agent\" << std::endl;\n      return;\n    }\n    GPUAccessToGPUMemoryTest(cpus[0], gpus[i], gpu_pool);\n  }\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid VirtMemoryTestBasic::NonContiguousChunks(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent,\n                                              hsa_amd_memory_pool_t device_pool) {\n  rocrtst::pool_info_t pool_i;\n  hsa_device_type_t ag_type;\n  char ag_name[64];\n  hsa_status_t err;\n\n  ASSERT_SUCCESS(rocrtst::AcquirePoolInfo(device_pool, &pool_i));\n\n  if (!pool_i.alloc_allowed || pool_i.segment != HSA_AMD_SEGMENT_GLOBAL ||\n      pool_i.global_flag != HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED)\n    return;\n\n  hsa_amd_memory_pool_access_t access;\n  ASSERT_SUCCESS(hsa_amd_agent_memory_pool_get_info(\n      cpuAgent, device_pool, HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access));\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    if (verbosity() > 0) {\n      std::cout << \"    Test not applicable as system is not large bar - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n      return;\n    }\n  }\n\n  size_t& granule_size = pool_i.alloc_granule;\n  size_t alloc_size = granule_size * 512;\n  const unsigned NUM_BUFFERS = 6;\n\n  void* addr;\n  void* addr_chunks[NUM_BUFFERS];\n  hsa_amd_vmem_alloc_handle_t mem_handles[NUM_BUFFERS];\n\n  static const int kMemoryAllocSize = 4096;\n  unsigned int max_element = alloc_size / sizeof(unsigned int);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve((void**)&addr, NUM_BUFFERS * alloc_size, 0, 0));\n\n  for (unsigned i = 0; i < NUM_BUFFERS; i++) {\n    // Allocate 6 separate memory memory handles\n    ASSERT_SUCCESS(hsa_amd_vmem_handle_create(device_pool, alloc_size, MEMORY_TYPE_PINNED, 0,\n                                              &(mem_handles[i])));\n    addr_chunks[i] = ((uint8_t*)addr) + (i * alloc_size);\n  }\n\n  for (unsigned i = 0; i < NUM_BUFFERS; i++) {\n    // Map each chunk in reverse order\n    ASSERT_SUCCESS(hsa_amd_vmem_map(addr_chunks[i], alloc_size, 0, mem_handles[NUM_BUFFERS - i - 1],\n                                    alloc_size));\n  }\n\n  hsa_amd_memory_access_desc_t permsAccess[] = {{HSA_ACCESS_PERMISSION_RW, gpuAgent}};\n\n  ASSERT_SUCCESS(hsa_amd_vmem_set_access(addr, NUM_BUFFERS * alloc_size, permsAccess,\n                                         ARRAY_SIZE(permsAccess)));\n\n  for (unsigned i = 0; i < NUM_BUFFERS; i++) {\n    // TODO Map them in opposite order\n    ASSERT_SUCCESS(hsa_amd_vmem_unmap(addr_chunks[i], alloc_size));\n  }\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addr, NUM_BUFFERS * alloc_size));\n}\n\nvoid VirtMemoryTestBasic::NonContiguousChunks(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) PrintMemorySubtestHeader(\"GPU To GPU Access test\");\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus));\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  ASSERT_SUCCESS(hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus));\n\n  for (unsigned int i = 0; i < gpus.size(); ++i) {\n    hsa_amd_memory_pool_t gpu_pool;\n    memset(&gpu_pool, 0, sizeof(gpu_pool));\n    ASSERT_SUCCESS(\n        hsa_amd_agent_iterate_memory_pools(gpus[i], rocrtst::GetGlobalMemoryPool, &gpu_pool));\n    if (gpu_pool.handle == 0) {\n      std::cout << \"no global mempool in GPU agent\" << std::endl;\n      return;\n    }\n    NonContiguousChunks(cpus[0], gpus[i], gpu_pool);\n  }\n  if (verbosity() > 0) {\n    std::cout << \"    Subtest finished\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid VirtMemoryTestBasic::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  ASSERT_SUCCESS(rocrtst::SetDefaultAgents(this));\n  ASSERT_SUCCESS(rocrtst::SetPoolsTypical(this));\n\n  return;\n}\n\nvoid VirtMemoryTestBasic::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid VirtMemoryTestBasic::DisplayTestInfo(void) { TestBase::DisplayTestInfo(); }\n\nvoid VirtMemoryTestBasic::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid VirtMemoryTestBasic::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\nVirtMemoryTestInterProcess::VirtMemoryTestInterProcess(void) : TestBase() {\n  set_title(\"ROCr Virtual Memory Test - InterProcess \");\n  set_description(\" Tests Virtual Memory API with memory shared between two processes\");\n}\n\nVirtMemoryTestInterProcess::~VirtMemoryTestInterProcess(void) {}\n\n// See if the other process wrote an error value to the token; if not, write\n// the newVal to the token.\nstatic int CheckAndSetToken(std::atomic<int>* token, int newVal) {\n  if (*token == -1) {\n    return -1;\n  } else {\n    *token = newVal;\n  }\n\n  return 0;\n}\n\nstatic void ClearShared(SharedVirtMem* s) {\n  s->token = 0;\n  s->count = 0;\n  s->size = 0;\n  s->child_status = 0;\n  s->parent_status = 0;\n  memset(&s->sv, 0, sizeof(s->sv));\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid VirtMemoryTestInterProcess::SetUp(void) {\n  hsa_status_t err;\n\n  // We must fork process before doing HSA stuff, specifically, hsa_init, as\n  // each process needs to do this.\n  // Allocate linux shared_ memory.\n  shared_ = reinterpret_cast<SharedVirtMem*>(mmap(\n      nullptr, sizeof(SharedVirtMem), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0));\n  ASSERT_NE(shared_, MAP_FAILED) << \"mmap failed to allocated shared_ memory\";\n\n  // Initialize shared control block to zeros. The field \"token\"\n  // is used to signal state changes between the 2 processes.\n  ClearShared(shared_);\n\n  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, shared_->sv) != 0) {\n    std::cout << \"Failed to create Unix-domain socket pair\" << std::endl;\n    ASSERT_EQ(0, 1);\n  }\n\n  // Spawn second process and verify communication\n  child_ = 0;\n  child_ = fork();\n  ASSERT_NE(-1, child_) << \"fork failed\";\n  std::atomic<int>* token = &shared_->token;\n  if (child_ != 0) {\n    parentProcess_ = true;\n\n    // Signal to other process we are waiting, and then wait...\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n\n    PROCESS_LOG(\"Second process observed, handshake...\\n\");\n    *token = 1;\n    while (*token == 1) {\n      sched_yield();\n    }\n\n  } else {\n    parentProcess_ = false;\n    set_verbosity(0);\n    PROCESS_LOG(\"Second process running.\\n\");\n\n    while (*token == 0) {\n      sched_yield();\n    }\n\n    int ret;\n    ret = CheckAndSetToken(token, 0);\n    ASSERT_EQ(0, ret) << \"Error detected in child process\\n\";\n    // Wait for handshake\n    while (*token == 0) {\n      sched_yield();\n    }\n    ret = CheckAndSetToken(token, 0);\n    ASSERT_EQ(0, ret) << \"Error detected in child process\\n\";\n  }\n\n  TestBase::SetUp();\n\n  ASSERT_SUCCESS(rocrtst::SetDefaultAgents(this));\n  ASSERT_SUCCESS(rocrtst::SetPoolsTypical(this));\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_get_info(\n      device_pool(), HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE, &min_gpu_mem_granule));\n\n  ASSERT_SUCCESS(hsa_amd_memory_pool_get_info(\n      device_pool(), HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE, &rec_gpu_mem_granule));\n\n  return;\n}\n\nvoid VirtMemoryTestInterProcess::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n\n  // Note: Close() (and hsa_shut_down()) will be called from main()\n  // processOne is true for parent process, false for child process\n  if (parentProcess_) {\n    ParentProcessImpl();\n  } else {\n    ChildProcessImpl();\n    exit(0);\n  }\n}\n\nvoid VirtMemoryTestInterProcess::DisplayTestInfo(void) { TestBase::DisplayTestInfo(); }\n\nvoid VirtMemoryTestInterProcess::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid VirtMemoryTestInterProcess::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n/* Send the dmabuf_fd to another process via Unix socket */\nint VirtMemoryTestInterProcess::SendDmaBufFd(int socket, int dmabuf_fd) {\n  char* iov_str = (char*)\"rocrtst\";\n  struct msghdr msg = {0};\n  char buf[CMSG_SPACE(sizeof(dmabuf_fd))];\n\n  memset(buf, '\\0', sizeof(buf));\n\n  struct iovec io = {.iov_base = iov_str, .iov_len = strlen(iov_str)};\n\n  msg.msg_iov = &io;\n  msg.msg_iovlen = 1;\n  msg.msg_control = buf;\n  msg.msg_controllen = sizeof(buf);\n\n  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);\n  cmsg->cmsg_level = SOL_SOCKET;\n  cmsg->cmsg_type = SCM_RIGHTS;\n  cmsg->cmsg_len = CMSG_LEN(sizeof(dmabuf_fd));\n\n  // memmove(CMSG_DATA(cmsg), &dmabuf_fd, sizeof(dmabuf_fd));\n  memcpy(CMSG_DATA(cmsg), &dmabuf_fd, sizeof(dmabuf_fd));\n\n  msg.msg_controllen = CMSG_SPACE(sizeof(dmabuf_fd));\n\n  size_t sent = sendmsg(socket, &msg, 0);\n\n  return (sent < 0) ? -1 : 0;\n}\n\n/* Receive the dmabuf_fd to from process via Unix socket */\nint VirtMemoryTestInterProcess::ReceiveDmaBufFd(int socket) {\n  struct msghdr msg = {0};\n\n  /* On Mac OS X, the struct iovec is needed, even if it points to minimal data */\n  char m_buffer[1];\n  struct iovec io = {.iov_base = m_buffer, .iov_len = sizeof(m_buffer)};\n  msg.msg_iov = &io;\n  msg.msg_iovlen = 1;\n\n  char c_buffer[256];\n  msg.msg_control = c_buffer;\n  msg.msg_controllen = sizeof(c_buffer);\n\n  size_t rcv = recvmsg(socket, &msg, 0);\n  if (rcv < 0) return -1;\n\n  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);\n\n  int fd;\n  memmove(&fd, CMSG_DATA(cmsg), sizeof(fd));\n\n  return fd;\n}\n\nvoid VirtMemoryTestInterProcess::ParentProcessImpl() {\n  hsa_status_t err;\n\n  void* addrRange = NULL;\n\n  bool supp = false;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRange, 20 * rec_gpu_mem_granule, 0, 0));\n\n  hsa_amd_vmem_alloc_handle_t exported_handle;\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_create(device_pool(), 20 * rec_gpu_mem_granule,\n                                            MEMORY_TYPE_NONE, 0, &exported_handle));\n\n  int dmabuf_fd;\n  ASSERT_SUCCESS(hsa_amd_vmem_export_shareable_handle(&dmabuf_fd, exported_handle, 0));\n  ASSERT_GE(dmabuf_fd, 0);\n\n  // Signal child process that the gpu buffer is ready to read.\n  PROCESS_LOG(\"Parent: Signalling child proces process\\n\");\n  CheckAndSetToken(&shared_->token, 1);\n\n  close(shared_->sv[1]);\n  ASSERT_EQ(SendDmaBufFd(shared_->sv[0], dmabuf_fd), 0);\n\n  hsa_amd_vmem_alloc_handle_t imported_handle;\n  ASSERT_SUCCESS(hsa_amd_vmem_import_shareable_handle(dmabuf_fd, &imported_handle));\n\n  /* Test importing same handle twice */\n  hsa_amd_vmem_alloc_handle_t imported_handle2;\n  ASSERT_SUCCESS(hsa_amd_vmem_import_shareable_handle(dmabuf_fd, &imported_handle2));\n  ASSERT_SUCCESS(hsa_amd_vmem_map(addrRange, 10 * rec_gpu_mem_granule, 0, imported_handle, 0));\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(addrRange, 10 * rec_gpu_mem_granule));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(imported_handle));\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(imported_handle2));\n\n  PROCESS_LOG(\"Parent: Waiting for child process to signal\\n\");\n  while (shared_->token == 1) {\n    sched_yield();\n  }\n  if (shared_->token != 2) {\n    shared_->token = -1;\n  }\n  FORK_ASSERT_EQ(2, shared_->token, \"Parent: Error detected in signaling token\\n\");\n  PROCESS_LOG(\"Parent: Waking upon signal from child process\\n\");\n\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(exported_handle));\n\n  ASSERT_SUCCESS(hsa_amd_vmem_address_free(addrRange, 20 * rec_gpu_mem_granule));\n\n  PROCESS_LOG(\"Parent: Virtual Memory test PASSED\\n\");\n}\n\nvoid VirtMemoryTestInterProcess::ChildProcessImpl() {\n  int dmabuf_fd = -1;\n  bool supp = false;\n  hsa_status_t err;\n  ASSERT_SUCCESS(hsa_system_get_info(HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED, (void*)&supp));\n  if (!supp) {\n    if (verbosity() > 0) {\n      std::cout << \"    Virtual Memory API not supported on this system - Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n  void* addrRange = NULL;\n  ASSERT_SUCCESS(hsa_amd_vmem_address_reserve(&addrRange, 20 * rec_gpu_mem_granule, 0, 0));\n\n  // Yield until shared token value changes i.e. is updated by parent.\n  // Validate parent's update is per expectation\n  PROCESS_LOG(\"Child: Waiting for parent process to signal\\n\");\n  while (shared_->token == 0) {\n    sched_yield();\n  }\n  if (shared_->token != 1) {\n    shared_->token = -1;\n  }\n  FORK_ASSERT_EQ(1, shared_->token, \"Child: Error detected in signaling token\\n\");\n  PROCESS_LOG(\"Child: Waking upon signal from parent process\\n\");\n\n  close(shared_->sv[0]);\n  dmabuf_fd = ReceiveDmaBufFd(shared_->sv[1]);\n\n  hsa_amd_vmem_alloc_handle_t imported_handle;\n  ASSERT_SUCCESS(hsa_amd_vmem_import_shareable_handle(dmabuf_fd, &imported_handle));\n  ASSERT_SUCCESS(hsa_amd_vmem_map(addrRange, 10 * rec_gpu_mem_granule, 0, imported_handle, 0));\n  ASSERT_SUCCESS(hsa_amd_vmem_unmap(addrRange, 10 * rec_gpu_mem_granule));\n\n  PROCESS_LOG(\"Child: Signalling parent process\\n\");\n  CheckAndSetToken(&shared_->token, 2);\n\n  ASSERT_SUCCESS(hsa_amd_vmem_handle_release(imported_handle));\n\n  PROCESS_LOG(\"Child: Virtual Memory test PASSED\\n\");\n}\n"
  },
  {
    "path": "rocrtst/suites/functional/virtual_memory.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2022, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_FUNCTIONAL_VIRTUAL_MEMORY_H_\n#define ROCRTST_SUITES_FUNCTIONAL_VIRTUAL_MEMORY_H_\n\n#include <atomic>\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass VirtMemoryTestBasic : public TestBase {\n public:\n  VirtMemoryTestBasic();\n\n  // @Brief: Destructor for test case of VirtMemoryTestBasic\n  virtual ~VirtMemoryTestBasic();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void TestCreateDestroy(void);\n  void TestRefCount(void);\n  void TestPartialMapping(void);\n  void NonContiguousChunks(void);\n  void GPUAccessToCPUMemoryTest(void);\n  void CPUAccessToGPUMemoryTest(void);\n  void GPUAccessToGPUMemoryTest(void);\n\n private:\n  void TestCreateDestroy(hsa_agent_t agent, hsa_amd_memory_pool_t pool);\n  void TestRefCount(hsa_agent_t agent, hsa_amd_memory_pool_t pool);\n  void TestPartialMapping(hsa_agent_t agent, hsa_amd_memory_pool_t pool);\n  void NonContiguousChunks(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,\n                           hsa_amd_memory_pool_t pool);\n\n  void GPUAccessToCPUMemoryTest(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,\n                                hsa_amd_memory_pool_t pool);\n  void CPUAccessToGPUMemoryTest(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,\n                                hsa_amd_memory_pool_t pool);\n  void GPUAccessToGPUMemoryTest(hsa_agent_t cpu_agent, hsa_agent_t gpu_agent,\n                                hsa_amd_memory_pool_t pool);\n};\n\nstruct SharedVirtMem {\n  std::atomic<int> token;\n  std::atomic<int> count;\n  std::atomic<size_t> size;\n  std::atomic<int> child_status;\n  std::atomic<int> parent_status;\n\n  int sv[2];\n};\n\nclass VirtMemoryTestInterProcess : public TestBase {\n public:\n  VirtMemoryTestInterProcess();\n\n  // @Brief: Destructor for test case of VirtMemoryTest\n  virtual ~VirtMemoryTestInterProcess();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  void ParentProcessImpl();\n  void ChildProcessImpl();\n\n\n private:\n  int SendDmaBufFd(int socket, int dmabuf_fd);\n  int ReceiveDmaBufFd(int socket);\n\n  int child_;\n  SharedVirtMem* shared_;\n  bool parentProcess_;\n  size_t min_gpu_mem_granule; /* Minimum granularity */\n  size_t rec_gpu_mem_granule; /* Recommented granularity */\n};\n\n#endif  // ROCRTST_SUITES_FUNCTIONAL_VIRTUAL_MEMORY_H_\n"
  },
  {
    "path": "rocrtst/suites/negative/memory_allocate_negative_tests.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n\n#include \"suites/negative/memory_allocate_negative_tests.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kNumBufferElements = 256;\n\n\n\n\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\n\n\nMemoryAllocateNegativeTest::MemoryAllocateNegativeTest(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  set_title(\"RocR Memory Allocate Negative Test\");\n  set_description(\"This series of tests are Negative tests \"\n    \"that do check memory allocation on GPU and CPU, \"\n    \"i.e. requesting an allocation of more than max \"\n    \"pool size or 0 size.\");\n}\n\nMemoryAllocateNegativeTest::~MemoryAllocateNegativeTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryAllocateNegativeTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid MemoryAllocateNegativeTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryAllocateNegativeTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAllocateNegativeTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryAllocateNegativeTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Subtest: \" << header << \" ***\" << std::endl;\n}\n\nstatic void PrintAgentNameAndType(hsa_agent_t agent) {\n  hsa_status_t err;\n\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  std::cout << \"  Agent: \" << ag_name << \" (\";\n  switch (ag_type) {\n    case HSA_DEVICE_TYPE_CPU:\n      std::cout << \"CPU)\";\n      break;\n    case HSA_DEVICE_TYPE_GPU:\n      std::cout << \"GPU)\";\n      break;\n    case HSA_DEVICE_TYPE_DSP:\n      std::cout << \"DSP)\";\n      break;\n    case HSA_DEVICE_TYPE_AIE:\n      std::cout << \"AIE)\";\n      break;\n    }\n  std::cout << std::endl;\n  return;\n}\n\nstatic const int kMemoryAllocSize = 1024;\n\n// This test verify that hsa_memory_allocate can't allocate\n// memory more than HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE\nvoid MemoryAllocateNegativeTest::MaxMemoryAllocateTest(hsa_agent_t agent,\n                                               hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  // Determine if allocation is allowed in this pool\n  if (!pool_i.alloc_allowed || pool_i.alloc_granule == 0) {\n    if (verbosity() > 0) {\n      std::cout << \"  Test not applicable. Skipping.\" << std::endl;\n      std::cout << kSubTestSeparator << std::endl;\n    }\n    return;\n  }\n\n    char *memoryPtr;\n  auto gran_sz = pool_i.alloc_granule;\n  size_t max_size = pool_i.aggregate_alloc_max;\n  err = hsa_amd_memory_pool_allocate(pool, (max_size + gran_sz), 0,\n                                       reinterpret_cast<void**>(&memoryPtr));\n    ASSERT_EQ(err, HSA_STATUS_ERROR_INVALID_ALLOCATION);\n  return;\n}\n\n\n\n\n// This test verify that requesting an allocation\n// of 0 size is valid on memory pool or not\nvoid MemoryAllocateNegativeTest::ZeroMemoryAllocateTest(hsa_agent_t agent,\n                                                hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  // Determine if allocation is allowed in this pool\n  bool alloc = false;\n  err = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &alloc);\n\n  if (alloc) {\n    char *memoryPtr;\n    err = hsa_amd_memory_pool_allocate(pool, 0, 0,\n                                       reinterpret_cast<void**>(&memoryPtr));\n    ASSERT_EQ(err, HSA_STATUS_ERROR_INVALID_ARGUMENT);\n  }\n  return;\n}\n\n\nvoid MemoryAllocateNegativeTest::MaxMemoryAllocateTest(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  PrintMemorySubtestHeader(\"MaxMemoryAllocateTest in Memory Pools\");\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      MaxMemoryAllocateTest(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryAllocateNegativeTest::ZeroMemoryAllocateTest(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  PrintMemorySubtestHeader(\"ZeroMemoryAllocateTest in Memory Pools\");\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      ZeroMemoryAllocateTest(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nstatic const uint32_t kMaxQueueSizeForAgent = 1024;\nstatic const uint32_t kMaxQueue = 64;\n\ntypedef struct test_validation_data_t {\n  bool cb_triggered;\n  uint64_t expected_address;\n} test_validation_data;\n\nhsa_status_t CallbackSystemErrorHandling(const hsa_amd_event_t* event, void* data) {\n  test_validation_data* user_data = reinterpret_cast<test_validation_data*>(data);\n\n  if (event->event_type != HSA_AMD_GPU_MEMORY_ERROR_EVENT) {\n    std::cout << \"ERROR: Invalid error type\" << std::endl;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  const hsa_amd_gpu_memory_error_info_t& error_info =\n      reinterpret_cast<const hsa_amd_gpu_memory_error_info_t&>(event->memory_error);\n\n  if (error_info.virtual_address != user_data->expected_address) {\n    std::cout << \"ERROR: Invalid virtual address\" << std::endl;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (!(error_info.error_reason_mask & HSA_AMD_MEMORY_ERROR_MEMORY_IN_USE)) {\n    std::cout << \"ERROR: HSA_AMD_MEMORY_ERROR_MEMORY_IN_USE flag not set\" << std::endl;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  user_data->cb_triggered = true;\n\n  return HSA_STATUS_SUCCESS;\n}\n\n\nvoid MemoryAllocateNegativeTest::FreeQueueRingBufferTest(void) {\n  hsa_status_t err;\n\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n  set_kernel_file_name(\"dispatch_time_kernels.hsaco\");\n  set_kernel_name(\"empty_kernel\");\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"RingBufferFree\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0; i < gpus.size(); ++i) {\n    FreeQueueRingBufferTest(gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryAllocateNegativeTest::FreeQueueRingBufferTest(hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  auto enqueue_dispatch = [&](hsa_queue_t* queue) {\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n\n    aql().setup |= 1 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\n    aql().workgroup_size_x = 1;\n    aql().workgroup_size_y = 1;\n    aql().workgroup_size_z = 1;\n\n    aql().kernel_object = kernel_object();\n\n    const uint32_t queue_mask = queue->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue);\n    hsa_queue_store_write_index_relaxed(queue, index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue, index, &aql());\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                                   &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>(\n                                       queue->base_address))[index & queue_mask]);\n\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue->doorbell_signal, index);\n\n    // wait for the signal long enough for the queue error handling callback to happen\n    hsa_signal_value_t completion;\n    completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                           0xffffff, HSA_WAIT_STATE_ACTIVE);\n    // completion signal should be 0.\n    return completion;\n  };\n\n  // Create the executable, get symbol by name and load the code object\n  ASSERT_SUCCESS(rocrtst::LoadKernelFromObjFile(this, &gpuAgent));\n\n  // Fill up the kernel packet except header\n  ASSERT_SUCCESS(rocrtst::InitializeAQLPacket(this, &aql()));\n\n  // get queue size\n  uint32_t queue_max = 0;\n  ASSERT_SUCCESS(hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max));\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max : kMaxQueueSizeForAgent;\n\n  hsa_queue_t* queue[kMaxQueue];  // command queue\n  uint32_t i;\n  test_validation_data user_data = {};\n  ASSERT_SUCCESS( hsa_amd_register_system_event_handler(CallbackSystemErrorHandling, &user_data));\n  for (i = 0; i < kMaxQueue; ++i) {\n    // create queue\n    ASSERT_SUCCESS(hsa_queue_create(gpuAgent, kMaxQueueSizeForAgent, HSA_QUEUE_TYPE_SINGLE, NULL,\n                                    NULL, 0, 0, &queue[i]));\n\n    user_data.cb_triggered = false;\n    user_data.expected_address = reinterpret_cast<uint64_t>(queue[i]->base_address);\n\n    // Enqueue a dispatch and make sure completion signal is 0.\n    ASSERT_EQ(enqueue_dispatch(queue[i]), 0);\n\n    // Try to delete the Queue ring buffer, this should return error.\n    // Note: This will leave the hsa-runtime internal allocation table in an inconsistent state\n    // because hsa-runtime clean's up its internal allocation table before calling libhsakmt to try\n    // to do the actual free. So when compiled in debug mode, this will trigger a \"Can't find\n    // address in allocation map\" warning when hsa_queue_destroy is called afterwards. This is the\n    // expected behavior because trying to re-organise hsa-runtime hsa_memory_free function to\n    // handle this negative use-case is not worth it and the caller is expected to call abort in\n    // their system error handler.\n\n    ASSERT_NE(hsa_memory_free(queue[i]->base_address), HSA_STATUS_SUCCESS);\n\n    // Make sure queue is still in a working state. Enqueue a second dispatch and make sure\n    // completion signal is 0.\n    ASSERT_EQ(enqueue_dispatch(queue[i]), 0);\n\n    // Make sure CallbackSystemErrorHandling was called and memory event has valid info\n    ASSERT_TRUE(user_data.cb_triggered);\n\n    if (queue[i]) hsa_queue_destroy(queue[i]);\n  }\n\n  clear_code_object();\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/negative/memory_allocate_negative_tests.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_NEGATIVE_MEMORY_ALLOCATE_NEGATIVE_TESTS_H_\n#define ROCRTST_SUITES_NEGATIVE_MEMORY_ALLOCATE_NEGATIVE_TESTS_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass MemoryAllocateNegativeTest : public TestBase {\n public:\n    MemoryAllocateNegativeTest();\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryAllocateNegativeTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n\n  // @Brief: This test verify that hsa_memory_allocate can't allocate\n  // memory more than POOL_INFO_SIZE\n  void MaxMemoryAllocateTest(void);\n\n  // @Brief: This test verify that requesting an allocation\n  // of 0 size is valid on memory pool or not\n  void ZeroMemoryAllocateTest(void);\n\n  // @Brief: This test verify that freeing a ring buffer used by a queue\n  // will trigger an error\n  void FreeQueueRingBufferTest(void);\n\n private:\n  void MaxMemoryAllocateTest(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n  void ZeroMemoryAllocateTest(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n\n  void FreeQueueRingBufferTest(hsa_agent_t agent);\n};\n\n#endif  // ROCRTST_SUITES_NEGATIVE_MEMORY_ALLOCATE_NEGATIVE_TESTS_H_\n"
  },
  {
    "path": "rocrtst/suites/negative/queue_validation.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <string>\n\n#include \"suites/negative/queue_validation.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nstatic const uint32_t kMaxQueueSizeForAgent = 1024;\nstatic const uint32_t kMaxQueue = 64;\n\ntypedef struct test_validation_data_t {\n  bool cb_triggered;\n  hsa_queue_t** queue_pointer;\n  hsa_status_t  expected_status;\n} test_validation_data;\n\nstatic void CallbackQueueErrorHandling(hsa_status_t status, hsa_queue_t *source, void *data);\n\nQueueValidation::QueueValidation(bool launch_InvalidDimension,\n                                 bool launch_InvalidGroupMemory,\n                                 bool launch_InvalidKernelObject,\n                                 bool launch_InvalidPacket,\n                                 bool launch_InvalidWorkGroupSize) :TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  std::string name;\n  std::string desc;\n\n  name = \"RocR Queue Validation\";\n  desc = \"This series of tests submit different negative aql packet into the queue\"\n         \" and verifies that queue error handling callback called with proper exception.\";\n\n  if (launch_InvalidDimension) {\n    name += \" For InvalidDimension\";\n    desc += \" This test verifies that if an aql packet specifies a dimension \"\n            \" value above 3, the queue's error handling callback will trigger\";\n  } else if (launch_InvalidGroupMemory) {\n    name += \" For InvalidGroupMemory\";\n    desc += \" This test verifies that if an aql packet specifies an invalid group\"\n            \" memory size, the queue's error handling.\";\n  } else if (launch_InvalidKernelObject) {\n    name += \" ForInvalidKernelObject\";\n    desc += \" This test verifies that if an aql packet specifies an invalid\"\n            \" kernel object, the queue's error handling callback will trigger.\";\n  } else if (launch_InvalidPacket) {\n    name += \" For InvalidPacket\";\n    desc += \" This test verifies that if an aql packet is invalid (bad packet type),\"\n            \" the queue's error handling callback will trigger.\";\n  } else if (launch_InvalidWorkGroupSize) {\n    name += \" For InvalidWorkGroupSize\";\n    desc += \" This test verifies that if an aql packet specifies an invalid\"\n            \" workgroup size, the queue's error handling callback will trigger.\";\n  }\n  set_title(name);\n  set_description(desc);\n\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n  set_kernel_file_name(\"dispatch_time_kernels.hsaco\");\n  set_kernel_name(\"empty_kernel\");\n}\n\nQueueValidation::~QueueValidation(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid QueueValidation::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  /* The queue exceptions will trigger a coredump. Set the limit to 0 to disable  */\n  if (getrlimit(RLIMIT_CORE, &rlimit_)) {\n    perror(\"Could not get system rlimit\\n\");\n  } else {\n    struct rlimit rlimit_set;\n\n    rlimit_set.rlim_cur = 0;\n    rlimit_set.rlim_max = 0;\n\n    /* Do not error if system does not allow disabling limit */\n    if (setrlimit(RLIMIT_CORE, &rlimit_set))\n      perror(\"Could not set core file size\\n\");\n  }\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  return;\n}\n\nvoid QueueValidation::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid QueueValidation::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid QueueValidation::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid QueueValidation::Close() {\n  /* Restore rlimit to initial value before test - do not error if fails */\n  if (setrlimit(RLIMIT_CORE, &rlimit_))\n      perror(\"Could not set core file size\\n\");\n\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintDebugSubtestHeader(const char *header) {\n  std::cout << \"  *** QueueValidation Subtest: \" << header << \" ***\" << std::endl;\n}\n\nvoid QueueValidation::QueueValidationForInvalidDimension(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // get queue size\n  uint32_t queue_max = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max: kMaxQueueSizeForAgent;\n\n  hsa_queue_t *queue[kMaxQueue];  // command queue\n  uint32_t ii;\n  test_validation_data user_data[kMaxQueue];\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // set callback flag to false if callback called then it will change to true\n    user_data[ii].cb_triggered = false;\n    // set the queue pointer\n    user_data[ii].queue_pointer = &queue[ii];\n    // set the expected status in queue error calback handling\n    user_data[ii].expected_status = HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                       queue_max, HSA_QUEUE_TYPE_SINGLE,\n                       CallbackQueueErrorHandling, &user_data[ii], 0, 0, &queue[ii]);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // setting the dimesion more than 3\n    aql().setup = 4;\n    aql().kernel_object = kernel_object();\n    const uint32_t queue_mask = queue[ii]->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue[ii]);\n    hsa_queue_store_write_index_relaxed(queue[ii], index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue[ii], index, &aql());\n\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    void* q_base = queue[ii]->base_address;\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue[ii]->doorbell_signal, index);\n\n    // wait for the signal long enough for the queue error handling callback to happen\n    hsa_signal_value_t completion;\n    completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                           0xffffff, HSA_WAIT_STATE_ACTIVE);\n    // completion signal should not be changed.\n    ASSERT_EQ(completion, 1);\n\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n  }\n  sleep(1);\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // queue error handling callback  should be triggered\n    ASSERT_EQ(user_data[ii].cb_triggered, true);\n    if (queue[ii]) { hsa_queue_destroy(queue[ii]); }\n  }\n\n  clear_code_object();\n}\n\n\nvoid QueueValidation::QueueValidationInvalidGroupMemory(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // get queue size\n  uint32_t queue_max = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max: kMaxQueueSizeForAgent;\n\n  hsa_queue_t *queue[kMaxQueue];  // command queue\n  test_validation_data user_data[kMaxQueue];\n\n  uint32_t ii;\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // set callback flag to false if callback called then it will change to true\n    user_data[ii].cb_triggered = false;\n    // set the queue pointer\n    user_data[ii].queue_pointer = &queue[ii];\n    // set the expected status in queue error calback handling\n    user_data[ii].expected_status = HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                       queue_max, HSA_QUEUE_TYPE_SINGLE,\n                       CallbackQueueErrorHandling, &user_data[ii], 0, 0, &queue[ii]);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    aql().kernel_object = kernel_object();\n    // Request a large group memory segment size\n    aql().group_segment_size = (uint32_t)-1;\n\n    const uint32_t queue_mask = queue[ii]->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue[ii]);\n    hsa_queue_store_write_index_relaxed(queue[ii], index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue[ii], index, &aql());\n\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    void* q_base = queue[ii]->base_address;\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue[ii]->doorbell_signal, index);\n\n    // wait for the signal long enough for the queue error handling callback to happen\n    hsa_signal_value_t completion;\n    completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                           0xffffff, HSA_WAIT_STATE_ACTIVE);\n    // completion signal should not be changed.\n    ASSERT_EQ(completion, 1);\n\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n  }\n  sleep(1);\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // queue error handling callback  should be triggered\n    ASSERT_EQ(user_data[ii].cb_triggered, true);\n    if (queue[ii]) { hsa_queue_destroy(queue[ii]); }\n  }\n\n  clear_code_object();\n}\n\nvoid QueueValidation::QueueValidationForInvalidKernelObject(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // get queue size\n  uint32_t queue_max = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max: kMaxQueueSizeForAgent;\n\n  hsa_queue_t *queue[kMaxQueue];  // command queue\n  test_validation_data user_data[kMaxQueue];\n  uint32_t ii;\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // set callback flag to false if callback called then it will change to true\n    user_data[ii].cb_triggered = false;\n    // set the queue pointer\n    user_data[ii].queue_pointer = &queue[ii];\n    // set the expected status in queue error calback handling\n    user_data[ii].expected_status = HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                           kMaxQueueSizeForAgent, HSA_QUEUE_TYPE_SINGLE,\n                           CallbackQueueErrorHandling, &user_data[ii], 0, 0, &queue[ii]);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // setting the null code object\n    aql().kernel_object = 0;\n\n    const uint32_t queue_mask = queue[ii]->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue[ii]);\n    hsa_queue_store_write_index_relaxed(queue[ii], index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue[ii], index, &aql());\n\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                 HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    void* q_base = queue[ii]->base_address;\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue[ii]->doorbell_signal, index);\n\n    // wait for the signal long enough for the queue error handling callback to happen\n    hsa_signal_value_t completion;\n    completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                           0xffffff, HSA_WAIT_STATE_ACTIVE);\n    // completion signal should not be changed.\n    ASSERT_EQ(completion, 1);\n\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n  }\n  sleep(1);\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // queue error handling callback  should be triggered\n    ASSERT_EQ(user_data[ii].cb_triggered, true);\n    if (queue[ii]) { hsa_queue_destroy(queue[ii]); }\n  }\n\n  clear_code_object();\n}\n\nvoid QueueValidation::QueueValidationForInvalidPacket(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // get queue size\n  uint32_t queue_max = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max: kMaxQueueSizeForAgent;\n\n  hsa_queue_t *queue[kMaxQueue];  // command queue\n  uint32_t ii;\n  test_validation_data user_data[kMaxQueue];\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // set callback flag to false if callback called then it will change to true\n    user_data[ii].cb_triggered = false;\n    // set the queue pointer\n    user_data[ii].queue_pointer = &queue[ii];\n    // set the expected status in queue error calback handling\n    user_data[ii].expected_status = HSA_STATUS_ERROR_INVALID_PACKET_FORMAT;\n\n    // create queue\n    err = hsa_queue_create(gpuAgent,\n                       queue_max, HSA_QUEUE_TYPE_SINGLE,\n                       CallbackQueueErrorHandling, &user_data[ii], 0, 0, &queue[ii]);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    const uint32_t queue_mask = queue[ii]->size - 1;\n\n    // Load index for writing header later to command queue at same index\n    uint64_t index = hsa_queue_load_write_index_relaxed(queue[ii]);\n    hsa_queue_store_write_index_relaxed(queue[ii], index + 1);\n\n    rocrtst::WriteAQLToQueueLoc(queue[ii], index, &aql());\n    // setting the invalid packet type\n    aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n    aql().header |=  0xFFFF << HSA_PACKET_HEADER_TYPE;\n    aql().kernel_object = kernel_object();\n\n    void* q_base = queue[ii]->base_address;\n    // Set the Aql packet header\n    rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                        &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                            (q_base))[index & queue_mask]);\n\n\n    // ringdoor bell\n    hsa_signal_store_relaxed(queue[ii]->doorbell_signal, index);\n\n    // wait for the signal long enough for the queue error handling callback to happen\n    hsa_signal_value_t completion;\n    completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                           0xffffff, HSA_WAIT_STATE_ACTIVE);\n    // completion signal should not be changed.\n    ASSERT_EQ(completion, 1);\n\n    hsa_signal_store_relaxed(aql().completion_signal, 1);\n  }\n  sleep(1);\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    // queue error handling callback  should be triggered\n    ASSERT_EQ(user_data[ii].cb_triggered, true);\n    if (queue[ii]) { hsa_queue_destroy(queue[ii]); }\n  }\n\n  clear_code_object();\n}\n\nvoid QueueValidation::QueueValidationForInvalidWorkGroupSize(hsa_agent_t cpuAgent,\n                                            hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // Create the executable, get symbol by name and load the code object\n  err = rocrtst::LoadKernelFromObjFile(this, &gpuAgent);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // get queue size\n  uint32_t queue_max = 0;\n  err = hsa_agent_get_info(gpuAgent,\n                           HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_max);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Adjust the size to the max of 1024\n  queue_max = (queue_max < kMaxQueueSizeForAgent) ? queue_max: kMaxQueueSizeForAgent;\n\n  hsa_queue_t *queue[kMaxQueue];  // command queue\n  test_validation_data user_data[kMaxQueue][3];\n  uint32_t ii;\n  for (ii = 0; ii < kMaxQueue; ++ii) {\n    uint32_t jj;\n    for (jj = 1; jj <= 3; ++jj) {\n      // set callback flag to false if callback called then it will change to true\n      user_data[ii][jj - 1].cb_triggered = false;\n      // set the queue pointer\n      user_data[ii][jj - 1].queue_pointer = &queue[ii];\n      // set the expected status in queue error calback handling\n      user_data[ii][jj - 1].expected_status = HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n      // create queue\n      err = hsa_queue_create(gpuAgent,\n              kMaxQueueSizeForAgent, HSA_QUEUE_TYPE_SINGLE,\n              CallbackQueueErrorHandling, &user_data[ii][jj - 1], 0, 0, &queue[ii]);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n      aql().setup |= jj << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\n      aql().workgroup_size_x = (jj == 1) ? (uint16_t)-1 : 1;\n      aql().workgroup_size_y = (jj == 2) ? (uint16_t)-1 : 1;\n      aql().workgroup_size_z = (jj == 3) ? (uint16_t)-1 : 1;\n\n      aql().kernel_object = kernel_object();\n\n      const uint32_t queue_mask = queue[ii]->size - 1;\n\n      // Load index for writing header later to command queue at same index\n      uint64_t index = hsa_queue_load_write_index_relaxed(queue[ii]);\n      hsa_queue_store_write_index_relaxed(queue[ii], index + 1);\n\n      rocrtst::WriteAQLToQueueLoc(queue[ii], index, &aql());\n      aql().header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n      aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                    HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n      aql().header |= HSA_FENCE_SCOPE_SYSTEM <<\n                    HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n      void* q_base = queue[ii]->base_address;\n      // Set the Aql packet header\n      rocrtst::AtomicSetPacketHeader(aql().header, aql().setup,\n                          &(reinterpret_cast<hsa_kernel_dispatch_packet_t*>\n                          (q_base))[index & queue_mask]);\n\n\n      // ringdoor bell\n      hsa_signal_store_relaxed(queue[ii]->doorbell_signal, index);\n\n      // wait for the signal long enough for the queue error handling callback to happen\n      hsa_signal_value_t completion;\n      completion = hsa_signal_wait_scacquire(aql().completion_signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                             0xffffff, HSA_WAIT_STATE_ACTIVE);\n      // completion signal should not be changed.\n      ASSERT_EQ(completion, 1);\n\n      hsa_signal_store_relaxed(aql().completion_signal, 1);\n      if (queue[ii]) { hsa_queue_destroy(queue[ii]); }\n    }\n  }\n  sleep(1);\n  for (uint32_t ii = 0; ii < kMaxQueue; ++ii) {\n    for (uint32_t jj = 0; jj < 3; ++jj) {\n      // queue error handling callback  should be triggered\n      ASSERT_EQ(user_data[ii][jj].cb_triggered, true);\n    }\n  }\n\n  clear_code_object();\n}\n\n\nvoid QueueValidation::QueueValidationForInvalidDimension(void) {\n  hsa_status_t err;\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"InvalidDimensionTest\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueValidationForInvalidDimension(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueValidation::QueueValidationInvalidGroupMemory(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"InvalidGroupMemory\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueValidationInvalidGroupMemory(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueValidation::QueueValidationForInvalidKernelObject(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"InvalidKernelObject\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueValidationForInvalidKernelObject(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueValidation::QueueValidationForInvalidPacket(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"InvalidPacket\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueValidationForInvalidPacket(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueValidation::QueueValidationForInvalidWorkGroupSize(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"InvalidWorkGroupSize\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueValidationForInvalidWorkGroupSize(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n\nvoid CallbackQueueErrorHandling(hsa_status_t status, hsa_queue_t* source, void* data) {\n  ASSERT_NE(source, nullptr);\n  ASSERT_NE(data, nullptr);\n\n  test_validation_data *debug_data = reinterpret_cast<test_validation_data*>(data);\n  hsa_queue_t * queue  = *(debug_data->queue_pointer);\n  debug_data->cb_triggered = true;\n  // check the status\n  ASSERT_EQ(status, debug_data->expected_status);\n  // check the queue id and user data\n  ASSERT_EQ(source->id, queue->id);\n  return;\n}\n\n"
  },
  {
    "path": "rocrtst/suites/negative/queue_validation.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_NEGATIVE_QUEUE_VALIDATION_H_\n#define ROCRTST_SUITES_NEGATIVE_QUEUE_VALIDATION_H_\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n#include <sys/resource.h>\n\n\nclass QueueValidation : public TestBase {\n public:\n    QueueValidation(bool launch_InvalidDimension,\n                    bool launch_InvalidGroupMemory,\n                    bool launch_InvalidKernelObject,\n                    bool launch_InvalidPacket,\n                    bool launch_InvalidWorkGroupSize);\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~QueueValidation();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Verifies that if an aql packet specifies a dimension\n  // value above 3, the queue's error handling callback will trigger\n  void QueueValidationForInvalidDimension(void);\n  // @Brief: Verifies that if an aql packet specifies an invalid group\n  // memory size, the queue's error handling\n  void QueueValidationInvalidGroupMemory(void);\n  // @Brief: Verifies that if an aql packet specifies an invalid\n  // kernel object, the queue's error handling callback will trigger.\n  void QueueValidationForInvalidKernelObject(void);\n  // @Brief: Verifies that if an aql packet is invalid (bad packet type),\n  // the queue's error handling callback will trigger\n  void QueueValidationForInvalidPacket(void);\n  // @Brief: Verifies that if an aql packet specifies an invalid\n  // workgroup size, the queue's error handling callback will trigger.\n  void QueueValidationForInvalidWorkGroupSize(void);\n\n\n private:\n  struct rlimit rlimit_; //value of rlimit before test starts\n\n  void QueueValidationForInvalidDimension(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueValidationInvalidGroupMemory(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueValidationForInvalidKernelObject(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueValidationForInvalidPacket(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueValidationForInvalidWorkGroupSize(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n};\n\n#endif  // ROCRTST_SUITES_NEGATIVE_QUEUE_VALIDATION_H_\n"
  },
  {
    "path": "rocrtst/suites/performance/dispatch_time.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <algorithm>\n#include <string>\n\n#include \"suites/performance/dispatch_time.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/os.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nDispatchTime::\nDispatchTime(bool defaultInterrupt, bool launchSingleKernel) : TestBase(),\n              use_default_interupt_(defaultInterrupt),\n                                          launch_single_(launchSingleKernel) {\n  queue_size_ = 0;\n#ifdef ROCRTST_EMULATOR_BUILD\n  num_batch_ = 2;\n  set_num_iteration(1);\n#else\n  num_batch_ = 100000;\n  set_num_iteration(100);\n#endif\n\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n  dispatch_time_mean_ = 0.0;\n\n  set_kernel_file_name(\"dispatch_time_kernels.hsaco\");\n  set_kernel_name(\"empty_kernel\");\n\n  std::string name;\n  std::string desc;\n\n  name = \"Average Dispatch Time\";\n  desc = \"This test measures the time to handle AQL packets that \"\n      \"do no work. Time is measured from when the packet is made available to\"\n      \" the Command Processor to when the target agent notifies the host that \"\n      \"the packet has been executed.  \";\n\n  if (defaultInterrupt) {\n    name += \", Default Interrupts\";\n    desc += \"Interrupts are controlled by HSA_ENABLE_INTERRUPT environment \"\n                                                                \"variable. \";\n  } else {\n    name += \", Interrupts Enabled\";\n    desc += \"Interrupts are enabled. \";\n  }\n\n  if (launchSingleKernel) {\n    name += \", Single Kernel\";\n    desc += \" One kernel at a time is and executed.\";\n  } else {\n    name += \", Multiple Kernels\";\n    desc += \" Enough kernels to fill the queue are dispatched at one time\";\n  }\n\n  set_title(name);\n  set_description(desc);\n}\n\nDispatchTime::~DispatchTime() {\n}\n\nvoid DispatchTime::SetUp() {\n  hsa_status_t err;\n\n  // This need to happen before TestBase::SetUp()\n  if (use_default_interupt_) {\n    set_enable_interrupt(false);\n  } else {\n    set_enable_interrupt(true);\n  }\n\n  TestBase::SetUp();\n  // If it indicates to use default signal, set env var properly\n\n  err = SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  hsa_agent_t* gpu_dev = gpu_device1();\n\n  // Create a queue\n  hsa_queue_t* q = nullptr;\n  rocrtst::CreateQueue(*gpu_dev, &q);\n  ASSERT_NE(q, nullptr);\n  set_main_queue(q);\n\n  // Here, modify the batch size if it is larger than the queue size\n  if (!launch_single_) {\n    hsa_status_t err;\n    uint32_t size = 0;\n    err = hsa_agent_get_info(*gpu_dev, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    num_batch_ = num_batch_ > size ? size : num_batch_;\n  }\n\n  err = rocrtst::LoadKernelFromObjFile(this, gpu_dev);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet except header\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  aql().workgroup_size_x = 1;\n  aql().grid_size_x = 1;\n}\n\nvoid DispatchTime::Run() {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n  if (launch_single_) {\n    RunSingle();\n  } else {\n    RunMulti();\n  }\n}\n\nsize_t DispatchTime::RealIterationNum() {\n  return num_iteration() * 1.2 + 1;\n}\n\nvoid DispatchTime::RunSingle() {\n  std::vector<double> timer;\n\n  uint32_t it = RealIterationNum();\n  const uint32_t queue_mask = main_queue()->size - 1;\n\n  // queue should be empty\n  ASSERT_EQ(hsa_queue_load_read_index_scacquire(main_queue()),\n            hsa_queue_load_write_index_scacquire(main_queue()));\n\n  hsa_kernel_dispatch_packet_t *q_base_addr =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                                 (main_queue()->base_address);\n\n  if (it > main_queue()->size) {\n    it = main_queue()->size;\n  }\n  for (uint32_t i = 0; i < it; i++) {\n    // Obtain the current queue write index.\n    uint64_t index = hsa_queue_add_write_index_relaxed(main_queue(), 1);\n\n    // Write the aql packet at the calculated queue index address.\n    rocrtst::WriteAQLToQueueLoc(main_queue(), index, &aql());\n\n    // Get timing stamp and ring the doorbell to dispatch the kernel.\n    rocrtst::PerfTimer p_timer;\n    int id = p_timer.CreateTimer();\n    p_timer.StartTimer(id);\n\n    rocrtst::AtomicSetPacketHeader(\n        HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE,\n        aql().setup,\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                        (&(q_base_addr)[index & queue_mask]));\n\n    hsa_signal_store_screlease(main_queue()->doorbell_signal, index);\n\n    // Wait on the dispatch signal until the kernel is finished.\n    while (hsa_signal_wait_scacquire(aql().completion_signal,\n         HSA_SIGNAL_CONDITION_LT, 1, (uint64_t) - 1, HSA_WAIT_STATE_ACTIVE)) {\n    }\n\n    p_timer.StopTimer(id);\n\n    timer.push_back(p_timer.ReadTimer(id));\n    hsa_signal_store_screlease(aql().completion_signal, 1);\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << \".\";\n      fflush(stdout);\n    }\n  }\n\n  if (verbosity() >= VERBOSE_PROGRESS) {\n    std::cout << std::endl;\n  }\n\n  // Abandon the first result and after sort, delete the last 2% value\n  timer.erase(timer.begin());\n  std::sort(timer.begin(), timer.end());\n\n  timer.erase(timer.begin() + num_iteration(), timer.end());\n\n  dispatch_time_mean_ = rocrtst::CalcMean(timer);\n\n  return;\n}\n\nvoid DispatchTime::RunMulti() {\n  std::vector<double> timer;\n  int it = RealIterationNum();\n  const uint32_t queue_mask = main_queue()->size - 1;\n  hsa_kernel_dispatch_packet_t *q_base_addr =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                                 (main_queue()->base_address);\n\n  // queue should be empty\n  ASSERT_EQ(hsa_queue_load_read_index_scacquire(main_queue()),\n            hsa_queue_load_write_index_scacquire(main_queue()));\n\n  rocrtst::PerfTimer p_timer;\n\n  for (int i = 0; i < it; i++) {\n    uint64_t* index =\n           reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t) * num_batch_));\n\n    ASSERT_NE(index, nullptr);\n\n    hsa_signal_store_screlease(aql().completion_signal, num_batch_);\n\n    for (uint32_t j = 0; j < num_batch_; j++) {\n      // index[j] = hsa_queue_add_write_index_scacq_screl(main_queue(), 1);\n      index[j] = hsa_queue_add_write_index_relaxed(main_queue(), 1);\n\n      // Write the aql packet at the calculated queue index address.\n      rocrtst::WriteAQLToQueueLoc(main_queue(), index[j], &aql());\n    }\n\n    rocrtst::AtomicSetPacketHeader(\n        (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n        (1 << HSA_PACKET_HEADER_BARRIER),\n        aql().setup,\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                          (&q_base_addr[index[num_batch_ - 1] & queue_mask]));\n\n    // Set packet header reversly; set all headers except the very first\n    // one, for now.\n    for (uint32_t j = num_batch_ - 1; j > 0; j--) {\n      rocrtst::AtomicSetPacketHeader(\n          HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE,\n          aql().setup,\n          reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                      (&q_base_addr[index[j] & queue_mask]));\n    }\n\n    // Get timing stamp and ring the doorbell to dispatch the kernel.\n    int id = p_timer.CreateTimer();\n    p_timer.StartTimer(id);\n    // Set the very first header...\n    rocrtst::AtomicSetPacketHeader(\n        HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE,\n        aql().setup,\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                     (&(q_base_addr)[index[0] & queue_mask]));\n\n    hsa_signal_store_screlease(main_queue()->doorbell_signal, index[num_batch_ - 1]);\n\n    // Wait on the dispatch signal until the kernel is finished.\n    while (hsa_signal_wait_scacquire(aql().completion_signal,\n        HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_ACTIVE) != 0) {\n    }\n\n    p_timer.StopTimer(id);\n\n    timer.push_back(p_timer.ReadTimer(id));\n    hsa_signal_store_screlease(aql().completion_signal, 1);\n\n    free(index);\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << \".\";\n      fflush(stdout);\n    }\n  }\n\n  std::cout << std::endl;\n\n  // Abandon the first result and after sort, delete the last 2% value\n  timer.erase(timer.begin());\n  std::sort(timer.begin(), timer.end());\n\n  timer.erase(timer.begin() + num_iteration(), timer.end());\n\n  dispatch_time_mean_ = rocrtst::CalcMean(timer);\n\n  return;\n}\n\nvoid DispatchTime::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid DispatchTime::DisplayResults(void) const {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::DisplayResults();\n\n  std::cout << \"Average Time to Completion: \";\n  if (launch_single_) {\n    std::cout << dispatch_time_mean_ * 1e6;\n  } else {\n    std::cout << dispatch_time_mean_ * 1e6 / num_batch_;\n  }\n\n  std::cout << \" uS\" << std::endl;\n  return;\n}\n\nvoid DispatchTime::Close() {\n  TestBase::Close();\n  return;\n}\n"
  },
  {
    "path": "rocrtst/suites/performance/dispatch_time.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_PERFORMANCE_DISPATCH_TIME_H_\n#define ROCRTST_SUITES_PERFORMANCE_DISPATCH_TIME_H_\n#include <vector>\n\n#include \"suites/test_common/test_base.h\"\n#include \"common/base_rocr.h\"\n#include \"common/common.h\"\n#include \"hsa/hsa.h\"\n\n// @Brief: This class is defined to measure the mean latency of launching\n// an empty kernel\n\nclass DispatchTime : public TestBase {\n public:\n  // @Brief: Constructor\n  DispatchTime(bool defaultInterrupt, bool launchSingleKernel);\n\n  // @Brief: Destructor\n  virtual ~DispatchTime(void);\n\n  // @Brief: Set up the environment for the test\n  virtual void SetUp(void);\n\n  // @Brief: Run the test case\n  virtual void Run(void);\n\n  // @Brief: Display  results we got\n  virtual void DisplayResults(void) const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Clean up and close the runtime\n  virtual void Close(void);\n\n private:\n  // @Brief: Get actual iteration number\n  virtual size_t RealIterationNum(void);\n\n  // @Brief: Launch single packet each time\n  virtual void RunSingle(void);\n\n  // @Brief: Launch multiple packets each time\n  virtual void RunMulti(void);\n\n  // @Brief: Indicate if use default signal or not\n  bool use_default_interupt_;\n\n  // @Brief: Indicate if launch single kernel or not\n  bool launch_single_;\n\n  // @Brief: Store the size of queue\n  uint32_t queue_size_;\n\n  // @Brief: Number of packets in a batch\n  uint32_t num_batch_;\n\n  // @Brief: Ave. dispatch time\n  double dispatch_time_mean_;\n\n  char* orig_iterrupt_env_;\n};\n\n#endif  // ROCRTST_SUITES_PERFORMANCE_DISPATCH_TIME_H_\n\n"
  },
  {
    "path": "rocrtst/suites/performance/enqueueLatency.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#include <fcntl.h>\n#include <algorithm>\n#include <string>\n\n#include \"suites/performance/enqueueLatency.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/os.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nEnqueueLatency::\nEnqueueLatency(bool enqueueSinglePacket) : TestBase(),\n                                    enqueue_single_(enqueueSinglePacket) {\n  queue_size_ = 0;\n#if ROCRTST_EMULATOR_BUILD\n  num_of_pkts_ = 2;\n  set_num_iteration(1);\n#else\n  num_of_pkts_ = 100000;\n  set_num_iteration(100);\n#endif\n\n  memset(&aql(), 0, sizeof(hsa_kernel_dispatch_packet_t));\n  enqueue_time_mean_ = 0.0;\n\n  std::string name;\n  std::string desc;\n\n  name = \"Average Enqueue Time\";\n  desc = \"This test measures the time when the packet enqueue to the\"\n      \" queue and before the door bell is ring to notify the command processor \"\n      \"to execute the packet\";\n\n\n\n  if (enqueueSinglePacket) {\n    name += \", Single Packet\";\n    desc += \" One Packet at a time in queue.\";\n  } else {\n    name += \", Multiple Packets\";\n    desc += \" Multiple i.e. maximum Packets equeued to queue at one time\";\n  }\n\n  set_title(name);\n  set_description(desc);\n}\n\nEnqueueLatency::~EnqueueLatency() {\n}\n\nvoid EnqueueLatency::SetUp() {\n  hsa_status_t err;\n  TestBase::SetUp();\n  // If it indicates to use default signal, set env var properly\n\n  err = SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n}\n\nvoid EnqueueLatency::Run() {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n  hsa_status_t err;\n  TestBase::Run();\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    hsa_agent_t* gpu_dev = &gpus[i];\n    char agent_name[64];\n    err = hsa_agent_get_info(*gpu_dev, HSA_AGENT_INFO_NAME, agent_name);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    set_agent_name(agent_name);\n\n    // Create a queue\n    hsa_queue_t* q = nullptr;\n    rocrtst::CreateQueue(*gpu_dev, &q);\n    ASSERT_NE(q, nullptr);\n    set_main_queue(q);\n\n    set_kernel_file_name(\"dispatch_time_kernels.hsaco\");\n    set_kernel_name(\"empty_kernel\");\n    err = rocrtst::LoadKernelFromObjFile(this, gpu_dev);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // Fill up the kernel packet except header\n    err = rocrtst::InitializeAQLPacket(this, &aql());\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    aql().workgroup_size_x = 1;\n    aql().grid_size_x = 1;\n\n    // Here, modify the batch size if it is larger than the queue size\n    if (enqueue_single_) {\n      EnqueueSinglePacket();\n    } else {\n      hsa_status_t err;\n      uint32_t size = 0;\n      err = hsa_agent_get_info(*gpu_dev, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &size);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n      num_of_pkts_ = num_of_pkts_ > size ? size : num_of_pkts_;\n      EnqueueMultiPackets();\n    }\n    hsa_queue_destroy(q);\n    set_main_queue(nullptr);\n  }\n}\n\n\n\nsize_t EnqueueLatency::RealIterationNum() {\n  return num_iteration() * 1.2 + 1;\n}\n\nvoid EnqueueLatency::EnqueueSinglePacket() {\n  std::vector<double> timer;\n\n  int it = RealIterationNum();\n  const uint32_t queue_mask = main_queue()->size - 1;\n\n  // queue should be empty\n  ASSERT_EQ(hsa_queue_load_read_index_scacquire(main_queue()),\n            hsa_queue_load_write_index_scacquire(main_queue()));\n\n  hsa_kernel_dispatch_packet_t *q_base_addr =\n                      reinterpret_cast<hsa_kernel_dispatch_packet_t *>(\n                                                  main_queue()->base_address);\n  rocrtst::PerfTimer p_timer;\n  for (int i = 0; i < it; i++) {\n    // Get timing stamp and ring the doorbell to dispatch the kernel.\n    int id = p_timer.CreateTimer();\n    p_timer.StartTimer(id);\n    // Obtain the current queue write index.\n    uint64_t index = hsa_queue_add_write_index_relaxed(main_queue(), 1);\n\n    ASSERT_LT(index, main_queue()->size + index);\n\n    // Write the aql packet at the calculated queue index address.\n    rocrtst::WriteAQLToQueueLoc(main_queue(), index, &aql());\n\n    rocrtst::AtomicSetPacketHeader(\n        HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE,\n        aql().setup,\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                     (&(q_base_addr)[index & queue_mask]));\n\n    p_timer.StopTimer(id);\n\n    timer.push_back(p_timer.ReadTimer(id));\n    hsa_signal_store_screlease(main_queue()->doorbell_signal, index);\n\n    // Wait on the dispatch signal until the kernel is finished.\n    while (hsa_signal_wait_scacquire(aql().completion_signal,\n         HSA_SIGNAL_CONDITION_LT, 1, (uint64_t) - 1, HSA_WAIT_STATE_ACTIVE)) {\n    }\n\n    hsa_signal_store_screlease(aql().completion_signal, 1);\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << \".\";\n      fflush(stdout);\n    }\n  }\n\n  if (verbosity() >= VERBOSE_PROGRESS) {\n    std::cout << std::endl;\n  }\n\n  // Abandon the first result and after sort, delete the last 2% value\n  timer.erase(timer.begin());\n  std::sort(timer.begin(), timer.end());\n\n  timer.erase(timer.begin() + num_iteration(), timer.end());\n\n  enqueue_time_mean_ = rocrtst::CalcMean(timer);\n\n  return;\n}\n\nvoid EnqueueLatency::EnqueueMultiPackets() {\n  std::vector<double> timer;\n  int it = RealIterationNum();\n  const uint32_t queue_mask = main_queue()->size - 1;\n\n  // queue should be empty\n  ASSERT_EQ(hsa_queue_load_read_index_scacquire(main_queue()),\n            hsa_queue_load_write_index_scacquire(main_queue()));\n\n  rocrtst::PerfTimer p_timer;\n\n  hsa_kernel_dispatch_packet_t *q_base_addr =\n                      reinterpret_cast<hsa_kernel_dispatch_packet_t *>(\n                                                  main_queue()->base_address);\n\n  for (int i = 0; i < it; i++) {\n    // Get timing stamp and ring the doorbell to dispatch the kernel.\n    int id = p_timer.CreateTimer();\n    p_timer.StartTimer(id);\n    uint64_t* index =\n           reinterpret_cast<uint64_t*>(malloc(sizeof(uint64_t) * num_of_pkts_));\n\n    ASSERT_NE(index, nullptr);\n\n    hsa_signal_store_screlease(aql().completion_signal, num_of_pkts_);\n\n    for (uint32_t j = 0; j < num_of_pkts_; j++) {\n      // index[j] = hsa_queue_add_write_index_scacq_screl(main_queue(), 1);\n      index[j] = hsa_queue_add_write_index_relaxed(main_queue(), 1);\n\n      // Write the aql packet at the calculated queue index address.\n      rocrtst::WriteAQLToQueueLoc(main_queue(), index[j], &aql());\n    }\n    // Write the aql packet at the calculated queue index address.\n\n    rocrtst::AtomicSetPacketHeader(\n        (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n        (1 << HSA_PACKET_HEADER_BARRIER),\n        aql().setup,\n        reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                      (&(q_base_addr)[index[num_of_pkts_ - 1] & queue_mask]));\n\n\n    // Set packet header reversly; set all headers except the very first\n    // one, for now.\n    for (int32_t j = num_of_pkts_ - 1; j >= 0; j--) {\n      rocrtst::AtomicSetPacketHeader(\n          HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE,\n          aql().setup,\n          reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                     (&(q_base_addr)[index[j] & queue_mask]));\n    }\n\n    p_timer.StopTimer(id);\n\n    timer.push_back(p_timer.ReadTimer(id));\n\n    for (uint32_t j = 0; j < num_of_pkts_; j++) {\n      hsa_signal_store_screlease(main_queue()->doorbell_signal, index[j]);\n    }\n\n    // Wait on the dispatch signal until the kernel is finished.\n    while (hsa_signal_wait_scacquire(aql().completion_signal,\n        HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_ACTIVE) != 0) {\n    }\n\n\n    hsa_signal_store_screlease(aql().completion_signal, 1);\n\n    free(index);\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << \".\";\n      fflush(stdout);\n    }\n  }\n\n  std::cout << std::endl;\n\n  // Abandon the first result and after sort, delete the last 2% value\n  timer.erase(timer.begin());\n  std::sort(timer.begin(), timer.end());\n\n  timer.erase(timer.begin() + num_iteration(), timer.end());\n\n  enqueue_time_mean_ = rocrtst::CalcMean(timer);\n\n  return;\n}\n\n\n\nvoid EnqueueLatency::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid EnqueueLatency::DisplayResults(void) const {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::DisplayResults();\n\n  std::cout << \"Average Time to Completion: \";\n  if (enqueue_single_) {\n    std::cout << enqueue_time_mean_ * 1e6;\n  } else {\n    std::cout << enqueue_time_mean_ * 1e6 / num_of_pkts_;\n  }\n\n  std::cout << \" uS\" << std::endl;\n  return;\n}\n\nvoid EnqueueLatency::Close() {\n  TestBase::Close();\n  return;\n}\n"
  },
  {
    "path": "rocrtst/suites/performance/enqueueLatency.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_PERFORMANCE_ENQUEUELATENCY_H_\n#define ROCRTST_SUITES_PERFORMANCE_ENQUEUELATENCY_H_\n#include <vector>\n\n#include \"suites/test_common/test_base.h\"\n#include \"common/base_rocr.h\"\n#include \"common/common.h\"\n#include \"hsa/hsa.h\"\n\n// @Brief: This class is defined to measure the mean latency of enqueuing\n//  the packets to an empty kernel\n\nclass EnqueueLatency : public TestBase {\n public:\n  // @Brief: Constructor\n  explicit EnqueueLatency(bool launchSingleKernel);\n\n  // @Brief: Destructor\n  virtual ~EnqueueLatency(void);\n\n  // @Brief: Set up the environment for the test\n  virtual void SetUp(void);\n\n  // @Brief: Run the test case\n  virtual void Run(void);\n\n  // @Brief: Display  results we got\n  virtual void DisplayResults(void) const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // @Brief: Clean up and close the runtime\n  virtual void Close(void);\n\n  // @Brief: Create the executable, get symbol by name and load the code object\n  // virtual void LoadCodeObject(hsa_agent_t gpuAgent,uint64_t &kernel_code);\n\n private:\n  // @Brief: Get actual iteration number\n  virtual size_t RealIterationNum(void);\n\n  // @Brief: Launch single packet each time\n  virtual void EnqueueSinglePacket(void);\n\n  // @Brief: Launch multiple packets each time\n  virtual void EnqueueMultiPackets(void);\n\n\n  // @Brief: Indicate if we enqueued single pkt or not\n  bool enqueue_single_;\n\n  // @Brief: Store the size of queue\n  uint32_t queue_size_;\n\n  // @Brief: Number of packets in a batch\n  uint32_t num_of_pkts_;\n\n  // @Brief: Ave. dispatch time\n  double enqueue_time_mean_;\n};\n\n#endif  // ROCRTST_SUITES_PERFORMANCE_ENQUEUELATENCY_H_\n\n"
  },
  {
    "path": "rocrtst/suites/performance/memory_async_copy.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <hwloc.h>\n#include <hwloc/linux-libnuma.h>\n#include <numa.h>\n\n#include <vector>\n#include <algorithm>\n\n#include \"common/base_rocr.h\"\n#include \"suites/test_common/test_base.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"suites/performance/memory_async_copy.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/helper_funcs.h\"\n#include \"gtest/gtest.h\"\n\n#define RET_IF_HSA_ERR(err)                                                                        \\\n  {                                                                                                \\\n    if ((err) != HSA_STATUS_SUCCESS) {                                                             \\\n      const char* msg = 0;                                                                         \\\n      hsa_status_string(err, &msg);                                                                \\\n      EXPECT_EQ(HSA_STATUS_SUCCESS, err) << msg;                                                   \\\n      return (err);                                                                                \\\n    }                                                                                              \\\n  }\n\n/* PCIE BDF ID: 0xC81407 is specific to DTIF platform */\nstatic const uint32_t kDtifBdfId = 0xC81407;\n\nconstexpr const size_t MemoryAsyncCopy::Size[kNumGranularity];\nconstexpr const char* MemoryAsyncCopy::Str[kNumGranularity];\nconstexpr const int MemoryAsyncCopy::kMaxCopySize;\n\nMemoryAsyncCopy::MemoryAsyncCopy(void) :\n    TestBase() {\n  static_assert(sizeof(Size)/sizeof(size_t) == kNumGranularity,\n      \"kNumGranularity does not match size of arrays\");\n\n  cpu_agent_.handle = 0;  // Ignore any previous initialization\n  gpu_local_agent1_.handle = 0;\n  gpu_local_agent2_.handle = 0;\n  gpu_remote_agent_.handle = 0;\n  topology_ = nullptr;\n  cpu_hwl_numa_nodeset_ = nullptr;\n  agent_index_ = 0;\n  pool_index_ = 0;\n  tran_.clear();\n  agent_info()->clear();\n  pool_info()->clear();\n  node_info()->clear();\n  verified_ = true;\n  do_p2p_ = true;\n  src_pool_id_ = -1;\n  dst_pool_id_ = -1;\n  set_num_iteration(10);  // Default value\n  set_title(\"Asynchronous Memory Copy Bandwidth\");\n  set_description(\"This test measures bandwidth to/from Host from/to GPU \"\n      \"and Peer to Peer using hsa_amd_memory_async_copy() to copy buffers \"\n      \"of various length from memory pool to another.\");\n}\n\nMemoryAsyncCopy::~MemoryAsyncCopy(void) {\n  for (PoolInfo *p : pool_info_) {\n    delete p;\n  }\n\n  for (AgentInfo *a : agent_info_) {\n    delete a;\n  }\n}\n\nvoid MemoryAsyncCopy::SetUp(void) {\n  TestBase::SetUp();\n\n  hwloc_topology_init(&topology_);\n\n  FindTopology();\n\n  if (verbosity() >= VERBOSE_STANDARD) {\n    PrintTopology();\n  }\n  ConstructTransactionList();\n  return;\n}\n\nvoid MemoryAsyncCopy::Run(void) {\n  TestBase::Run();\n\n  for (Transaction t : tran_) {\n    this->RunBenchmarkWithVerification(&t);\n  }\n}\n\nvoid MemoryAsyncCopy::FindSystemPool(void) {\n  hsa_status_t err;\n\n//  err = hsa_iterate_agents(rocrtst::FindCPUDevice, &cpu_agent_);\n//  ASSERT_EQ(HSA_STATUS_INFO_BREAK, err);\n\n  err = hsa_amd_agent_iterate_memory_pools(cpu_agent_, rocrtst::FindGlobalPool,\n        &sys_pool_);\n  ASSERT_EQ(HSA_STATUS_INFO_BREAK, err);\n}\n\nhsa_status_t AcquireAccess(hsa_agent_t agent,\n                                    hsa_amd_memory_pool_t pool, void* ptr) {\n  hsa_status_t err;\n\n  hsa_amd_memory_pool_access_t access;\n  err = hsa_amd_agent_memory_pool_get_info(agent, pool,\n                              HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS, &access);\n\n  RET_IF_HSA_ERR(err);\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n    return HSA_STATUS_ERROR;\n  }\n\n  if (access == HSA_AMD_MEMORY_POOL_ACCESS_DISALLOWED_BY_DEFAULT) {\n    err = hsa_amd_agents_allow_access(1, &agent, NULL, ptr);\n    RET_IF_HSA_ERR(err);\n  }\n\n  return err;\n}\n\n// Provided a destination pointer, pool and agent, and a source ptr, pool,\n// and agent, get access for one of the 2 agents to the other agent's pool.\n// Return the selected agent. This function will first attempt to gain access\n// for the first agent to the second pool. If that succeeds, it will return a\n// pointer to the first agent. Otherwise, the function will attempt to again\n// access to the first pool by the second agent. If that succeeds a pointer to\n// the second agent will be returned. If it fails, nullptr will be returned.\n// We prefer to use GPU agents over CPU agents to avoid poor copy performance\n// due to reading of uncached device memory by CPU.\nhsa_agent_t *\nMemoryAsyncCopy::AcquireAsyncCopyAccess(\n         void *dst_ptr, hsa_amd_memory_pool_t dst_pool, hsa_agent_t *dst_ag,\n         void *src_ptr, hsa_amd_memory_pool_t src_pool, hsa_agent_t *src_ag) {\n  hsa_status_t err;\n  bool can_use_src_agent = false;\n  hsa_device_type_t type = HSA_DEVICE_TYPE_CPU;\n\n  err = AcquireAccess(*src_ag, dst_pool, dst_ptr);\n  if (err == HSA_STATUS_SUCCESS) {\n    can_use_src_agent = true;\n\n    if (hsa_agent_get_info(*src_ag, HSA_AGENT_INFO_DEVICE, &type) != HSA_STATUS_SUCCESS)\n      return NULL;\n\n    // We prefer GPU agents over CPU agents, so if this is not a GPU agent,\n    // try using the destination agent\n    if (type == HSA_DEVICE_TYPE_GPU) return src_ag;\n  }\n\n  err = AcquireAccess(*dst_ag, src_pool, src_ptr);\n  if (err == HSA_STATUS_SUCCESS) return dst_ag;\n\n  if (can_use_src_agent) return src_ag;\n  return NULL;\n}\n\nvoid MemoryAsyncCopy::PrintTransactionType(Transaction *t) {\n  if (verbosity() >= VERBOSE_STANDARD) {\n    printf(\"Executing Copy Path: From Pool %d To Pool %d \", t->src, t->dst);\n    switch (t->type) {\n      case H2D:\n        printf(\"(Host-To-Device)\\n\");\n        break;\n\n      case D2H:\n        printf(\"(Device-To-Host)\\n\");\n        break;\n\n      case P2P:\n        printf(\"(Peer-To-Peer)\\n\");\n        break;\n\n      case H2DRemote:\n        printf(\"(Host To Remote Device)\\n\");\n        break;\n\n      case D2HRemote:\n        printf(\"(Remote Device To Host)\\n\");\n        break;\n\n      case P2PRemote:\n        printf(\"(Peer To Remote Peer)\\n\");\n        break;\n\n      default:\n        printf(\"**Unexpected path**\\n\");\n        return;\n    }\n  }\n}\nvoid MemoryAsyncCopy::RunBenchmarkWithVerification(Transaction *t) {\n  hsa_status_t err;\n  void* ptr_src;\n  void* ptr_dst;\n  size_t src_alloc_size;\n  size_t dst_alloc_size;\n  size_t max_alloc_size;\n  size_t size;\n  hsa_device_type_t ag_type;\n\n\n  size_t max_trans_size = t->max_size * 1024;\n\n  hsa_amd_memory_pool_t src_pool =  pool_info_[t->src]->pool_;\n  hsa_agent_t dst_agent = pool_info_[t->dst]->owner_agent_info()->agent();\n  hsa_amd_memory_pool_t dst_pool = pool_info_[t->dst]->pool_;\n  hsa_agent_t src_agent = pool_info_[t->src]->owner_agent_info()->agent();\n\n  PrintTransactionType(t);\n\n  err = hsa_amd_memory_pool_get_info(src_pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                      &src_alloc_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(src_agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  if (src_alloc_size <= 536870912 && ag_type == HSA_DEVICE_TYPE_GPU) {\n    err = hsa_agent_get_info(src_agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                              &src_alloc_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n\n  err = hsa_amd_memory_pool_get_info(dst_pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                      &dst_alloc_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(dst_agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  if (dst_alloc_size <= 536870912 && ag_type == HSA_DEVICE_TYPE_GPU) {\n    err = hsa_agent_get_info(dst_agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                              &dst_alloc_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  }\n\n  max_alloc_size = (src_alloc_size < dst_alloc_size) ? src_alloc_size: dst_alloc_size;\n\n  if (dst_alloc_size <= 536870912 && ag_type == HSA_DEVICE_TYPE_GPU)\n    size = (max_alloc_size/3 <= max_trans_size) ? max_alloc_size/3: max_trans_size;\n  else\n    size = (max_alloc_size/2 <= max_trans_size) ? max_alloc_size/2: max_trans_size;\n\n  err = hsa_amd_memory_pool_allocate(src_pool, size, 0,\n\t\t\t\t      &ptr_src);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = hsa_amd_memory_pool_allocate(dst_pool, size, 0,\n\t\t\t\t      &ptr_dst);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n\n  // rocrtst::CommonCleanUp data\n  void* host_ptr_src = NULL;\n  void* host_ptr_dst = NULL;\n  err = hsa_amd_memory_pool_allocate(sys_pool_, size, 0,\n                                     reinterpret_cast<void**>(&host_ptr_src));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  err = hsa_amd_memory_pool_allocate(sys_pool_, size, 0,\n                                     reinterpret_cast<void**>(&host_ptr_dst));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = hsa_amd_memory_fill(host_ptr_src, 1, size/sizeof(uint32_t));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = hsa_amd_memory_fill(host_ptr_dst, 0, size/sizeof(uint32_t));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  hsa_signal_t s;\n  err = hsa_signal_create(1, 0, NULL, &s);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n\n  // Deallocate resources...\n  MAKE_SCOPE_GUARD([&]() {\n    err = hsa_amd_memory_pool_free(ptr_src);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n    err = hsa_amd_memory_pool_free(ptr_dst);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    err = hsa_amd_memory_pool_free(host_ptr_src);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n    err = hsa_amd_memory_pool_free(host_ptr_dst);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    err = hsa_signal_destroy(s);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  });\n\n  // **** First copy from the system buffer source to the test source pool\n  // Acquire the appropriate access; prefer GPU agent over CPU where there\n  // is a choice.\n  hsa_agent_t *cpy_ag = nullptr;\n  cpy_ag = AcquireAsyncCopyAccess(ptr_src, src_pool, &src_agent, host_ptr_src,\n                                                     sys_pool_, &cpu_agent_);\n  if (cpy_ag == nullptr) {\n    std::cout << \"Agents \" << t->src << \" and \" << t->dst <<\n                              \"cannot access each other's pool.\" << std::endl;\n    std::cout << \"Skipping...\" << std::endl;\n    return;\n  }\n\n  err = hsa_amd_memory_async_copy(ptr_src, *cpy_ag, host_ptr_src, *cpy_ag,\n                                                            size, 0, NULL, s);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  while (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1, uint64_t(-1),\n                                   HSA_WAIT_STATE_ACTIVE))\n  {}\n\n  int iterations = RealIterationNum();\n\n  // **** Next, copy from the test source pool to the test destination pool\n  // Prefer a gpu agent to a cpu agent\n\n  cpy_ag = AcquireAsyncCopyAccess(ptr_dst, dst_pool, &dst_agent, ptr_src,\n                                                        src_pool, &src_agent);\n  if (cpy_ag == nullptr) {\n    std::cout << \"Owner agents for pools\" << t->src << \" and \" <<\n                   t->dst << \" cannot access each other's pool.\" << std::endl;\n    std::cout << \"Skipping...\" << std::endl;\n    return;\n  }\n\n  for (int i = 0; i < kNumGranularity; i++) {\n    if (Size[i] > size) {\n      printf(\"Skip test with block size %s\\n\", Str[i]);\n      break;\n    }\n    printf(\"Start test with block size %s\\n\",Str[i]);\n\n    std::vector<double> time;\n\n    for (int it = 0; it < iterations; it++) {\n      if (verbosity() >= VERBOSE_PROGRESS) {\n        std::cout << \".\";\n        std::cout.flush();\n      }\n\n      hsa_signal_store_relaxed(t->signal, 1);\n\n      rocrtst::PerfTimer copy_timer;\n      int index = copy_timer.CreateTimer();\n\n      copy_timer.StartTimer(index);\n      err = hsa_amd_memory_async_copy(ptr_dst, *cpy_ag, ptr_src, *cpy_ag,\n                                                 Size[i], 0, NULL, t->signal);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n      while (hsa_signal_wait_scacquire(t->signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                         uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n      {}\n\n      copy_timer.StopTimer(index);\n\n      hsa_signal_store_relaxed(s, 1);\n\n      err = AcquireAccess(dst_agent, sys_pool_,\n                    host_ptr_dst);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n\n      err = hsa_amd_memory_async_copy(host_ptr_dst, cpu_agent_, ptr_dst,\n                                                 dst_agent, Size[i], 0, NULL, s);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n      while (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,\n                                       uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n      {}\n\n      err = AcquireAccess(cpu_agent_, sys_pool_, host_ptr_dst);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n      if (memcmp(host_ptr_src, host_ptr_dst, Size[i])) {\n        verified_ = false;\n      }\n      // Push the result back to vector time\n\n      time.push_back(copy_timer.ReadTimer(index));\n    }\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << std::endl;\n    }\n\n    // Get Min copy time\n    t->min_time->push_back(*std::min_element(time.begin(), time.end()));\n    // Get mean copy time and store to the array\n    t->benchmark_copy_time->push_back(GetMeanTime(&time));\n  }\n}\n\nsize_t MemoryAsyncCopy::RealIterationNum(void) {\n  return num_iteration() * 1.2 + 1;\n}\n\ndouble MemoryAsyncCopy::GetMeanTime(std::vector<double> *vec) {\n  std::sort(vec->begin(), vec->end());\n\n  vec->erase(vec->begin());\n  vec->erase(vec->begin(), vec->begin() + num_iteration() * 0.1);\n  vec->erase(vec->begin() + num_iteration(), vec->end());\n\n  double mean = 0.0;\n  int num = vec->size();\n\n  for (int it = 0; it < num; it++) {\n    mean += (*vec)[it];\n  }\n\n  mean /= num;\n  return mean;\n}\n\nvoid MemoryAsyncCopy::DisplayResults(void) const {\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::DisplayResults();\n  hsa_status_t err;\n  for (Transaction t : tran_) {\n    DisplayBenchmark(&t);\n    err = hsa_signal_destroy(t.signal);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    delete t.benchmark_copy_time;\n    delete t.min_time;\n  }\n\n  return;\n}\n\nvoid MemoryAsyncCopy::DisplayBenchmark(Transaction *t) const {\n  hsa_status_t err;\n  size_t src_alloc_size;\n  size_t dst_alloc_size;\n  size_t max_alloc_size;\n  size_t size;\n\n  size_t max_trans_size = t->max_size * 1024;\n  hsa_amd_memory_pool_t src_pool =  pool_info_[t->src]->pool_;\n  hsa_amd_memory_pool_t dst_pool = pool_info_[t->dst]->pool_;\n\n  err = hsa_amd_memory_pool_get_info(src_pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                    &src_alloc_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_memory_pool_get_info(dst_pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                    &dst_alloc_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  max_alloc_size = (src_alloc_size < dst_alloc_size) ? src_alloc_size: dst_alloc_size;\n\n  size = (max_alloc_size/2 <= max_trans_size) ? max_alloc_size/2: max_trans_size;\n\n  printf(\"=========================== PATH: From Pool %d To Pool %d (\",\n                                                              t->src, t->dst);\n\n  switch (t->type) {\n    case H2D:\n      printf(\"Host-To-Device) ===========================\\n\");\n      break;\n\n    case D2H:\n      printf(\"Device-To-Host) ===========================\\n\");\n      break;\n\n    case P2P:\n      printf(\"Peer-To-Peer) =============================\\n\");\n      break;\n\n    case P2PRemote:\n      printf(\"(Peer-To-Remote-Peer) =====================\\n\");\n      break;\n\n    case H2DRemote:\n      printf(\"(Host-To-Remote-Device) ===================\\n\");\n      break;\n\n    case D2HRemote:\n      printf(\"(Device-To-Remote-Host) ===================\\n\");\n      break;\n\n    default:\n      ASSERT_TRUE(false) << \"Unexpected Transaction value:\" << t->type <<\n                                                                    std::endl;\n  }\n\n  if ((*t->benchmark_copy_time).size() == 0) {\n    printf(\"Skipped...\\n\");\n    return;\n  }\n  if (verified_) {\n    std::cout << \"Verification: Pass\" << std::endl;\n  } else {\n    std::cout << \"Verification: Fail\" << std::endl;\n  }\n\n  if (verbosity() < VERBOSE_STANDARD) {\n    return;\n  }\n\n  printf(\"Data Size             Avg Time(us)         Avg BW(GB/s)\"\n                           \"          Min Time(us)          Peak BW(GB/s)\\n\");\n\n  for (int i = 0; i < kNumGranularity; i++) {\n\n    if (Size[i] > size) {\n      printf(\n         \"Notice: Data Size >= %s is skipped due to hard limit of 1/2 vram size \\n\\n\",\n         Str[i]\n      );\n      break;\n    }\n\n    double band_width =\n    static_cast<double>(Size[i]/(*(t->benchmark_copy_time))[i]/1024/1024/1024);\n    double peak_band_width =\n       static_cast<double>(Size[i] / (*(t->min_time))[i]/ 1024 / 1024 / 1024);\n    printf(\n        \"  %4s            %14lf        %14lf         %14lf         %14lf\\n\",\n       Str[i], (*(t->benchmark_copy_time))[i] * 1e6, band_width,\n                                  (*(t->min_time))[i] * 1e6, peak_band_width);\n  }\n\n  return;\n}\n\nvoid MemoryAsyncCopy::Close() {\n  if (cpu_hwl_numa_nodeset_ != nullptr) {\n    hwloc_bitmap_free(cpu_hwl_numa_nodeset_);\n    cpu_hwl_numa_nodeset_ = nullptr;\n  }\n  hwloc_topology_destroy(topology_);\n\n  // hwloc hack - hwloc uses OpenCL which loads ROCr.  As OpenCL does not have a shutdown routine it\n  // can not free HSA state.  This will leak resources but is the only option short of isolating\n  // hwloc in it's own process.\n  while (hsa_shut_down() == HSA_STATUS_SUCCESS)\n    ;\n  hsa_init();\n\n  TestBase::Close();\n}\n\nstatic hsa_status_t GetPoolInfo(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_status_t err;\n  MemoryAsyncCopy* ptr = reinterpret_cast<MemoryAsyncCopy*>(data);\n  // Query pool segment, only report global one\n  hsa_amd_segment_t region_segment;\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                                     &region_segment);\n  RET_IF_HSA_ERR(err);\n\n  if (region_segment != HSA_AMD_SEGMENT_GLOBAL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Check if the pool is alloc allowed, if not, discard this pool\n  bool alloc_allowed = false;\n  err = hsa_amd_memory_pool_get_info(pool,\n              HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &alloc_allowed);\n  RET_IF_HSA_ERR(err);\n\n  if (alloc_allowed != true) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Query the pool size\n  size_t size = 0;\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE,\n                                     &size);\n  RET_IF_HSA_ERR(err);\n\n  // Query the max allocable size\n  size_t alloc_max_size = 0;\n  err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                     &alloc_max_size);\n  RET_IF_HSA_ERR(err);\n\n  // Check if the pool is fine-grained or coarse-grained\n  uint32_t global_flag = 0;\n  err = hsa_amd_memory_pool_get_info(pool,\n                        HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &global_flag);\n  RET_IF_HSA_ERR(err);\n\n  bool is_fine_grained = HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED\n                         & global_flag;\n\n  int pool_i = ptr->pool_index();\n  int ag_ind = ptr->agent_index();\n  ptr->pool_info()->push_back(\n    new PoolInfo(pool, pool_i, region_segment, is_fine_grained, size,\n                                  alloc_max_size, ptr->agent_info()->back()));\n\n  // Construct node_info and push back to agent_info_\n  (*ptr->node_info())[ag_ind].pool.push_back(*ptr->pool_info()->back());\n  ptr->set_pool_index(pool_i + 1);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic hsa_status_t GetGPUAgents(hsa_agent_t agent, void* data) {\n  hsa_status_t err;\n  MemoryAsyncCopy* ptr = reinterpret_cast<MemoryAsyncCopy*>(data);\n\n  hsa_device_type_t device_type;\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n  RET_IF_HSA_ERR(err);\n\n  if (device_type != HSA_DEVICE_TYPE_GPU) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  uint32_t agent_bdf_id;\n  err = hsa_agent_get_info(agent,\n                (hsa_agent_info_t)HSA_AMD_AGENT_INFO_BDFID, &agent_bdf_id);\n  RET_IF_HSA_ERR(err);\n\n  uint8_t bus = (agent_bdf_id & (0xFF << 8)) >> 8;\n  uint8_t device = (agent_bdf_id & (0x1F << 3)) >> 3;\n\n  // The function part of the location_id hasn't been used yet\n  // and may not contain a valid function number.\n  uint8_t function = 0; //(agent_bdf_id & 0x07);\n\n  if (ptr->verbosity() >  MemoryAsyncCopy::VERBOSE_STANDARD) {\n    char name[64];\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, name);\n    RET_IF_HSA_ERR(err);\n\n    const char* name2 = (HSA_DEVICE_TYPE_GPU == device_type) ? \"GPU\" : \"CPU\";\n\n    printf(\"The %s agent name located at PCIe Bus %x, Device %x, \"\n                                                     \"Function %x, is %s.\\n\",\n                                          name2, bus, device, function, name);\n  }\n\n  uint32_t pci_domain_id = 0;\n  err = hsa_agent_get_info(agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_DOMAIN, &pci_domain_id);\n  RET_IF_HSA_ERR(err);\n\n  bool is_dxg = false;\n  int fd = open(\"/dev/dxg\", O_RDWR);\n  if (fd >= 0) {\n    close(fd);\n    is_dxg = true;\n  }\n  hwloc_obj_t gpu_numa_node = nullptr;\n  if ((agent_bdf_id != kDtifBdfId) && !is_dxg) {\n    hwloc_obj_t gpu_hwl_dev;\n    gpu_hwl_dev = hwloc_get_pcidev_by_busid(ptr->topology(), pci_domain_id, bus, device,\n                                                                      function);\n\n    if (gpu_hwl_dev == nullptr) {\n      return HSA_STATUS_ERROR;\n    }\n\n    gpu_numa_node = hwloc_get_ancestor_obj_by_type(ptr->topology(),\n                                              HWLOC_OBJ_NUMANODE, gpu_hwl_dev);\n  }\n\n  if (gpu_numa_node != nullptr) {\n    char s1[256], s2[256];\n    hwloc_bitmap_snprintf(s1, sizeof(s1), gpu_numa_node->nodeset);\n    hwloc_bitmap_snprintf(s2, sizeof(s2), ptr->cpu_hwl_numa_nodeset());\n    printf(\"gpu nodeset: %s\\n\", s1);\n    printf(\"cpu nodeset: %s\\n\", s2);\n    if (!hwloc_bitmap_isequal(gpu_numa_node->nodeset,\n                                              ptr->cpu_hwl_numa_nodeset())) {\n      if (ptr->gpu_remote_agent().handle == 0) {\n        ptr->set_gpu_remote_agent(agent);\n      }\n\n      if (ptr->gpu_local_agent1().handle != 0 &&\n                                          ptr->gpu_local_agent2().handle != 0) {\n        return HSA_STATUS_INFO_BREAK;\n      } else {\n        return HSA_STATUS_SUCCESS;\n      }\n    } else {\n      if (ptr->gpu_local_agent1().handle == 0) {\n        ptr->set_gpu_local_agent1(agent);\n      } else if (ptr->gpu_local_agent2().handle == 0) {\n        ptr->set_gpu_local_agent2(agent);\n      }\n      if (ptr->gpu_local_agent1().handle != 0 &&\n                                     ptr->gpu_local_agent2().handle != 0 &&\n                                        ptr->gpu_remote_agent().handle != 0) {\n        return HSA_STATUS_INFO_BREAK;\n      } else {\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n\n    if (!hwloc_bitmap_isequal(gpu_numa_node->nodeset,\n                                               ptr->cpu_hwl_numa_nodeset())) {\n      std::cout << \"ASSERT: Unexpected unequal nodesets\" << std::endl;\n      return HSA_STATUS_ERROR;\n    }\n  } else if (ptr->verbosity() >= MemoryAsyncCopy::VERBOSE_STANDARD) {\n    std::cout << \"Only 1 NUMA node found.\\n\" << std::endl;\n  }\n\n  if (ptr->gpu_local_agent1().handle != 0) {\n    if (ptr->gpu_local_agent2().handle != 0) {\n      if (gpu_numa_node == nullptr) {\n        return HSA_STATUS_INFO_BREAK;\n      } else if (ptr->gpu_remote_agent().handle == 0) {\n        return HSA_STATUS_SUCCESS;\n      } else {\n        return HSA_STATUS_INFO_BREAK;\n      }\n    } else {\n      ptr->set_gpu_local_agent2(agent);\n      if (ptr->gpu_remote_agent().handle == 0) {\n        return (gpu_numa_node == nullptr ?\n                  HSA_STATUS_INFO_BREAK : HSA_STATUS_SUCCESS);\n      } else {\n        return HSA_STATUS_INFO_BREAK;\n      }\n    }\n  } else {\n    ptr->set_gpu_local_agent1(agent);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic hsa_status_t GetAgentInfo(hsa_agent_t agent, void* data) {\n  MemoryAsyncCopy* ptr = reinterpret_cast<MemoryAsyncCopy*>(data);\n\n  hsa_status_t err;\n  int ret;\n\n  if (ptr->cpu_agent().handle != 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n\n  // Get device type\n  hsa_device_type_t device_type;\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n  RET_IF_HSA_ERR(err);\n\n  // First thing is to find CPU agent\n  if (device_type != HSA_DEVICE_TYPE_CPU) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  ptr->set_cpu_agent(agent);\n  uint32_t cpu_numa_node_id;\n//  hwloc_obj_t cpu_numa;\n  hwloc_nodeset_t cpu_nodeset;\n\n  err = hsa_agent_get_info(ptr->cpu_agent(), HSA_AGENT_INFO_NODE,\n                                                           &cpu_numa_node_id);\n  RET_IF_HSA_ERR(err);\n\n  struct bitmask *numa_node_mask = numa_allocate_nodemask();\n  cpu_nodeset = hwloc_bitmap_alloc();\n\n  numa_bitmask_setbit(numa_node_mask, cpu_numa_node_id);\n\n  ret = hwloc_nodeset_from_linux_libnuma_bitmask(ptr->topology(),\n      cpu_nodeset, numa_node_mask);\n  numa_free_nodemask(numa_node_mask);\n\n  if (ret == -1) {\n    hwloc_bitmap_free(cpu_nodeset);\n    return HSA_STATUS_ERROR;\n  }\n\n  ptr->set_cpu_hwl_numa_nodeset(cpu_nodeset);\n\n  err = hsa_iterate_agents(GetGPUAgents, data);\n\n  if (err != HSA_STATUS_INFO_BREAK && err != HSA_STATUS_SUCCESS) {\n    return err;\n  }\n\n  if (ptr->gpu_local_agent1().handle == 0) {\n    hwloc_bitmap_free(ptr->cpu_hwl_numa_nodeset());\n    ptr->set_cpu_hwl_numa_nodeset(nullptr);\n\n    if (ptr->gpu_local_agent2().handle != 0) {\n      std::cout << \"Unexpected value set for gpu_local_agent2\" << std::endl;\n      return HSA_STATUS_ERROR;\n    }\n    // In this case, the CPU and at least 1 GPU are not on the same NUMA node;\n    // try another CPU\n    hsa_agent_t t;\n    t.handle = 0;\n    ptr->set_gpu_local_agent1(t);\n    ptr->set_cpu_agent(t);\n    ptr->set_gpu_remote_agent(t);\n    return HSA_STATUS_SUCCESS;\n  }\n  auto add_agent = [&](hsa_agent_t ag, hsa_device_type_t dev_type,\n                                                                bool remote) {\n    if (ag.handle == 0) {\n      return;\n    }\n    ptr->agent_info()->push_back(\n            new AgentInfo(ag, ptr->agent_index(), dev_type, remote));\n\n    // Contruct a new NodeInfo structure and push back to agent_info_\n    NodeInfo node;\n    node.agent = *ptr->agent_info()->back();\n    ptr->node_info()->push_back(node);\n\n    err = hsa_amd_agent_iterate_memory_pools(ag, GetPoolInfo, data);\n    ptr->set_agent_index(ptr->agent_index() + 1);\n  };\n\n  add_agent(ptr->cpu_agent(), HSA_DEVICE_TYPE_CPU, false);\n  add_agent(ptr->gpu_local_agent1(), HSA_DEVICE_TYPE_GPU, false);\n  add_agent(ptr->gpu_local_agent2(), HSA_DEVICE_TYPE_GPU, false);\n  add_agent(ptr->gpu_remote_agent(), HSA_DEVICE_TYPE_GPU, true);\n\n  return HSA_STATUS_INFO_BREAK;\n}\n\nvoid MemoryAsyncCopy::FindTopology() {\n  hsa_status_t err;\n\n  hwloc_topology_set_flags(topology_, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM |\n                                         HWLOC_TOPOLOGY_FLAG_IO_DEVICES);\n\n  hwloc_topology_load(topology_);\n\n  err = hsa_iterate_agents(GetAgentInfo, this);\n\n  if (gpu_local_agent1_.handle == 0) {\n    std::cout << \"**** No GPU found in same NUMA node as a CPU ****\"\n                                                                 << std::endl;\n  }\n  ASSERT_EQ(HSA_STATUS_INFO_BREAK, err);\n\n  FindSystemPool();\n}\n\nvoid MemoryAsyncCopy::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryAsyncCopy::ConstructTransactionList(void) {\n  hsa_status_t err;\n\n  tran_.clear();\n\n  int cpu_pool_indx = -1;\n  int gpu_local1_pool_indx = -1;\n  int gpu_local2_pool_indx = -1;\n  int gpu_remote_pool_indx = -1;\n\n  auto push_trans = [&](int from_indx, int to_indx, TransType type) {\n    Transaction t;\n    t.src = from_indx;\n    t.dst = to_indx;\n    t.max_size = kMaxCopySize/1024;\n    t.type = type;\n    t.benchmark_copy_time = new  std::vector<double>;\n    t.min_time = new std::vector<double>;\n    err = hsa_signal_create(1, 0, NULL, &t.signal);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    tran_.push_back(t);\n  };\n\n  // Find the CPU Node and pool\n  for (NodeInfo n : *node_info()) {\n    if (cpu_pool_indx == -1 && n.agent.device_type() == HSA_DEVICE_TYPE_CPU) {\n      cpu_pool_indx = n.pool[0].index_;\n      continue;\n    }\n\n    if (n.agent.device_type() == HSA_DEVICE_TYPE_GPU) {\n      if (!n.agent.is_remote()) {\n        if (gpu_local1_pool_indx == -1) {\n          gpu_local1_pool_indx = n.pool[0].index_;\n          continue;\n        }\n        if (gpu_local2_pool_indx == -1) {\n          gpu_local2_pool_indx = n.pool[0].index_;\n        }\n      } else if (gpu_remote_pool_indx == -1) {\n        gpu_remote_pool_indx = n.pool[0].index_;\n      }\n    }\n  }\n\n  ASSERT_NE(cpu_pool_indx, -1);\n  ASSERT_NE(gpu_local1_pool_indx, -1);\n\n  push_trans(cpu_pool_indx, gpu_local1_pool_indx, H2D);\n  push_trans(gpu_local1_pool_indx, cpu_pool_indx, D2H);\n\n  if (do_p2p_ && gpu_local2_pool_indx != -1) {\n    push_trans(gpu_local1_pool_indx, gpu_local2_pool_indx, P2P);\n    push_trans(gpu_local2_pool_indx, gpu_local1_pool_indx, P2P);\n  }\n\n  if (gpu_remote_pool_indx != -1) {\n    push_trans(cpu_pool_indx, gpu_remote_pool_indx, H2DRemote);\n    push_trans(gpu_remote_pool_indx, cpu_pool_indx, D2HRemote);\n    if (do_p2p_) {\n      push_trans(gpu_local1_pool_indx, gpu_remote_pool_indx, P2PRemote);\n      push_trans(gpu_remote_pool_indx, gpu_local1_pool_indx, P2PRemote);\n    }\n  }\n}\n\nvoid MemoryAsyncCopy::PrintTopology(void) {\n  size_t node_num = node_info()->size();\n\n  for (uint32_t i = 0; i < node_num; i++) {\n    NodeInfo node = node_info()->at(i);\n    // Print agent info\n    std::cout << std::endl;\n    std::cout << \"Agent #\" << node.agent.index_ << \":\" << std::endl;\n\n    if (HSA_DEVICE_TYPE_CPU == node.agent.device_type())\n      std::cout << \"Agent Device Type:                             CPU\"\n                << std::endl;\n    else if (HSA_DEVICE_TYPE_GPU == node.agent.device_type())\n      std::cout << \"Agent Device Type:                             GPU\"\n                << std::endl;\n\n    // Print pool info\n    size_t pool_num = node.pool.size();\n\n    for (uint32_t j = 0; j < pool_num; j++) {\n      std::cout << \"    Memory Pool#\" << node.pool.at(j).index_ << \":\"\n                << std::endl;\n      std::cout << \"        max allocable size in KB: \\t\\t\"\n                << node.pool.at(j).allocable_size_ / 1024 << std::endl;\n      std::cout << \"        is fine-grained: \\t\\t\\t\"\n                << node.pool.at(j).is_fine_grained_ << std::endl;\n    }\n  }\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/performance/memory_async_copy.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_H_\n#define ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_H_\n\n#include <hwloc.h>\n\n#include <vector>\n#include <algorithm>\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"suites/test_common/test_base.h\"\n\nhsa_status_t AcquireAccess(hsa_agent_t agent,\n                                    hsa_amd_memory_pool_t pool, void* ptr);\ntypedef enum TransType\n              {H2D = 0, D2H, P2P, H2DRemote, D2HRemote, P2PRemote} TransType;\n\ntypedef struct Transaction {\n  int src;\n  int dst;\n  hsa_signal_t signal;\n  size_t max_size;  // Max. amount of kBytes to copy\n  TransType type;\n  // BenchMark copy time\n  std::vector<double> *benchmark_copy_time;\n  // Min time\n  std::vector<double> *min_time;\n} Transaction;\n\nclass AgentInfo {\n public:\n    AgentInfo(hsa_agent_t agent, int index, hsa_device_type_t device_type,\n                                                        bool remote = false) {\n      agent_ = agent;\n      index_ = index;\n      device_type_ = device_type;\n      remote_ = remote;\n    }\n    AgentInfo() {}\n\n    ~AgentInfo() {}\n    hsa_agent_t agent(void) const {return agent_;}\n    hsa_device_type_t device_type(void) const {return device_type_;}\n    bool is_remote(void) const {return remote_;}\n    void set_remote(bool r) {remote_ = r;}\n    hsa_agent_t agent_;\n    int index_;\n\n private:\n    hsa_device_type_t device_type_;\n    bool remote_;\n};\n\nclass PoolInfo {\n public:\n    PoolInfo(hsa_amd_memory_pool_t pool, int index,\n               hsa_amd_segment_t segment, bool is_fine_grained, size_t size,\n               size_t max_alloc_size, AgentInfo *agent_info) {\n      pool_ = pool;\n      index_ = index;\n      segment_ = segment;\n      is_fine_grained_ = is_fine_grained;\n      size_ = size;\n      allocable_size_ = max_alloc_size;\n      owner_agent_info_ = agent_info;\n    }\n    PoolInfo() {}\n    ~PoolInfo() {}\n    AgentInfo* owner_agent_info(void) const {return owner_agent_info_;}\n    hsa_amd_memory_pool_t pool_;\n    int index_;\n    hsa_amd_segment_t segment_;\n    bool is_fine_grained_;\n    size_t size_;\n    size_t allocable_size_;\n private:\n    AgentInfo *owner_agent_info_;\n};\n\n\n// Used to print out topology info\ntypedef struct NodeInfo {\n  AgentInfo agent;\n  std::vector<PoolInfo> pool;\n} NodeInfo;\n\n\nclass MemoryAsyncCopy : public TestBase {\n public:\n  MemoryAsyncCopy();\n\n  // @Brief: Destructor for test case of MemoryAsyncCopy\n  virtual ~MemoryAsyncCopy();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n  // There are 3 levels of testing, from quickest/very specific to\n  // longest/most complete:\n  // 1. to and from a specified source to a specified target\n  // 2. to and from the cpu to 1 gpu, and to/from a gpu to another gpu\n  //    (if available)\n  // 3. to and from the cpu to 1 gpu and, to/from every gpu to every\n  //    other gpu\n  // The default is #2 above. If *both* a source and dest. are set for #1\n  // above, then that overides both #2 and #3\n  void set_src_pool(int pool_id) {src_pool_id_ = pool_id;}\n  void set_dst_pool(int pool_id) {dst_pool_id_ = pool_id;}\n  int pool_index(void) const {return pool_index_;}\n  void set_pool_index(int i) {pool_index_ = i;}\n  int agent_index(void) const {return agent_index_;}\n  void set_agent_index(int i) {agent_index_ = i;}\n  std::vector<PoolInfo *> *pool_info(void) {return &pool_info_;}\n  std::vector<AgentInfo *> *agent_info(void) {return &agent_info_;}\n  std::vector<NodeInfo> *node_info(void) {return &node_info_;}\n\n  hwloc_topology_t topology(void) const {return topology_;}\n  void set_topology(hwloc_topology_t t) {topology_ = t;}\n\n  hwloc_nodeset_t cpu_hwl_numa_nodeset(void) const {\n                                                return cpu_hwl_numa_nodeset_;}\n  void set_cpu_hwl_numa_nodeset(hwloc_nodeset_t ns) {\n                                                  cpu_hwl_numa_nodeset_ = ns;}\n  hsa_agent_t gpu_local_agent1() const {return gpu_local_agent1_;}\n  void set_gpu_local_agent1(hsa_agent_t a) {gpu_local_agent1_ = a;}\n  hsa_agent_t gpu_local_agent2() const {return gpu_local_agent2_;}\n  void set_gpu_local_agent2(hsa_agent_t a) {gpu_local_agent2_ = a;}\n\n  hsa_agent_t gpu_remote_agent() const {return gpu_remote_agent_;}\n  void set_gpu_remote_agent(hsa_agent_t a) {gpu_remote_agent_ = a;}\n\n  hsa_agent_t cpu_agent() const {return cpu_agent_;}\n  void set_cpu_agent(hsa_agent_t a) {cpu_agent_ = a;}\n\n  hsa_agent_t *\n  AcquireAsyncCopyAccess(\n         void *dst_ptr, hsa_amd_memory_pool_t dst_pool, hsa_agent_t *dst_ag,\n         void *src_ptr, hsa_amd_memory_pool_t src_pool, hsa_agent_t *src_ag);\n\n protected:\n  void PrintTransactionType(Transaction *t);\n#if ROCRTST_EMULATOR_BUILD\n  static const int kNumGranularity = 1;\n  static constexpr const char* Str[kNumGranularity] = {\"1k\"};\n\n  static constexpr const size_t Size[kNumGranularity] = {1024};\n#else\n\n  static const int kNumGranularity = 20;\n  static constexpr const char* Str[kNumGranularity] = {\n      \"1k\", \"2K\", \"4K\", \"8K\", \"16K\", \"32K\", \"64K\", \"128K\", \"256K\", \"512K\",\n      \"1M\", \"2M\", \"4M\", \"8M\", \"16M\", \"32M\", \"64M\", \"128M\", \"256M\", \"512M\"};\n\n  static constexpr const size_t Size[kNumGranularity] = {\n      1024, 2*1024, 4*1024, 8*1024, 16*1024, 32*1024, 64*1024, 128*1024,\n      256*1024, 512*1024, 1024*1024, 2048*1024, 4096*1024, 8*1024*1024,\n      16*1024*1024, 32*1024*1024, 64*1024*1024, 128*1024*1024, 256*1024*1024,\n      512*1024*1024};\n#endif\n  static constexpr const int kMaxCopySize = Size[kNumGranularity - 1];\n\n  // @Brief: Get real iteration number\n  virtual size_t RealIterationNum(void);\n\n  // @Brief: Get the mean copy time\n  double GetMeanTime(std::vector<double>* vec);\n\n  // @Brief: Find and print out the needed topology info\n  virtual void FindTopology(void);\n\n  // @Brief: Run for Benchmark mode with verification\n  virtual void RunBenchmarkWithVerification(Transaction *t);\n\n  // @Brief: Dispaly Benchmark result\n  void DisplayBenchmark(Transaction *t) const;\n\n  // @Brief: Print topology info\n  void PrintTopology(void);\n\n  virtual void ConstructTransactionList(void);\n\n  // @Brief: Find system region\n  void FindSystemPool(void);\n\n  // More variables declared for testing\n  std::vector<Transaction> tran_;\n\n  // Variable used to store agent info, indexed by agent_index_\n  std::vector<AgentInfo *> agent_info_;\n\n  // Variable used to store region info, indexed by pool_index_\n  std::vector<PoolInfo *> pool_info_;\n\n  // To store node info\n  std::vector<NodeInfo> node_info_;\n\n  // Variable to help count agent index\n  int agent_index_;\n\n  // Variable to help count region index\n  int pool_index_;\n\n  // Verification result\n  bool verified_;\n\n  // Should we test p2p copying?\n  bool do_p2p_;\n\n  // Store the testing level\n  int src_pool_id_;\n  int dst_pool_id_;\n  // System region\n  hsa_amd_memory_pool_t sys_pool_;\n\n  // CPU agent used for verification\n  hsa_agent_t cpu_agent_;\n\n  rocrtst::PerfTimer copy_timer_;\n\n  hwloc_topology_t topology_;\n  hwloc_nodeset_t cpu_hwl_numa_nodeset_;\n\n  // hsa_agent_t cpu_agent_; use one in base class\n  hsa_agent_t gpu_local_agent1_;\n  hsa_agent_t gpu_local_agent2_;\n  hsa_agent_t gpu_remote_agent_;  // Not associated with cpu_agent_\n};\n\n\n#endif  // ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_H_\n"
  },
  {
    "path": "rocrtst/suites/performance/memory_async_copy_numa.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <hwloc.h>\n#include <hwloc/linux-libnuma.h>\n#include <numa.h>\n\n#include <vector>\n#include <algorithm>\n\n#include \"common/base_rocr.h\"\n#include \"suites/test_common/test_base.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"suites/performance/memory_async_copy_numa.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/helper_funcs.h\"\n#include \"gtest/gtest.h\"\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\nMemoryAsyncCopyNUMA::MemoryAsyncCopyNUMA(void) : MemoryAsyncCopy() {\n  set_title(\"Asynchronous Memory Copy Bandwidth Using NUMA aware allocation\");\n  set_description(\"This test measures bandwidth to/from Host from/to GPU \"\n      \"using hsa_amd_memory_async_copy() to copy buffers of various length \"\n      \"from memory pool to another. Host memory is allocated using NUMA \"\n      \"aware allocators. Bandwidth performance using NUMA should, at worst, \"\n      \"be as good as using the standard hsa allocator.\");\n\n  do_p2p_ = false;\n}\n\nMemoryAsyncCopyNUMA::~MemoryAsyncCopyNUMA(void) {\n}\n\nvoid MemoryAsyncCopyNUMA::Run(void) {\n  int ret;\n  TestBase::Run();\n\n  hwloc_bitmap_t cpu_bind_set = nullptr;\n  char *a;\n\n  // Bind CPU\n  cpu_bind_set = hwloc_bitmap_alloc();\n\n  hwloc_cpuset_from_nodeset(topology_, cpu_bind_set, cpu_hwl_numa_nodeset_);\n\n  ASSERT_FALSE((bool)hwloc_bitmap_iszero(cpu_bind_set));\n\n  if (hwloc_bitmap_isfull(cpu_bind_set)) {\n    std::cout <<\n     \"All cpus associated with NUMA node. No hwloc cpu binding will be done.\"\n                                                                 << std::endl;\n  } else {\n    hwloc_bitmap_t cpu_bind_set_chk = nullptr;\n    cpu_bind_set_chk = hwloc_bitmap_alloc();\n\n    hwloc_bitmap_singlify(cpu_bind_set);\n    ret = hwloc_set_cpubind(topology_, cpu_bind_set, HWLOC_CPUBIND_PROCESS);\n    ASSERT_TRUE(ret == 0 &&\n          \"hwloc: cpubind not supported or cannot be enforced. Check errno.\");\n\n    hwloc_get_cpubind(topology_, cpu_bind_set_chk, 0);\n\n    if (verbosity() >= VERBOSE_STANDARD) {\n      hwloc_bitmap_asprintf(&a, cpu_bind_set);\n      printf(\"write hwloc cpubind mask: %s\\n\", a);\n      hwloc_bitmap_asprintf(&a, cpu_bind_set_chk);\n      printf(\"read hwloc cpubind mask: %s\\n\", a);\n    }\n    ASSERT_TRUE(hwloc_bitmap_isequal(cpu_bind_set, cpu_bind_set_chk) &&\n                                              \"Unexpected hwloc cpubind set\");\n    hwloc_bitmap_free(cpu_bind_set_chk);\n\n    // Bind Memory\n    ret = hwloc_set_membind_nodeset(topology_, cpu_hwl_numa_nodeset_,\n                                     HWLOC_MEMBIND_BIND, 0);\n    ASSERT_TRUE(ret == 0 &&\n          \"hwloc: membind not supported or cannot be enforced. Check errno.\");\n  }\n  for (Transaction t : tran_) {\n    RunBenchmarkWithVerification(&t);\n  }\n\n  hwloc_bitmap_free(cpu_bind_set);\n}\n\nvoid MemoryAsyncCopyNUMA::RunBenchmarkWithVerification(Transaction *t) {\n  hsa_status_t err;\n  void* ptr_src;\n  void* ptr_dst;\n\n  size_t size = t->max_size * 1024;\n\n  hsa_amd_memory_pool_t src_pool =  pool_info_[t->src]->pool_;\n  hsa_agent_t dst_agent = pool_info_[t->dst]->owner_agent_info()->agent();\n  hsa_amd_memory_pool_t dst_pool = pool_info_[t->dst]->pool_;\n\n  hsa_agent_t src_agent = pool_info_[t->src]->owner_agent_info()->agent();\n\n  PrintTransactionType(t);\n\n  // Allocate resources...\n  void *locked_mem;\n\n  // We are relying a previous call to hwloc_set_membind_nodeset() to set\n  // policy\n  void *local_alloc = hwloc_alloc(topology_, size);\n  ASSERT_TRUE(local_alloc != nullptr && \"hwloc_alloc_membind() failed\");\n  hsa_agent_t gpu_agent = ((t->type == H2D || t->type == H2DRemote) ?\n                                                       dst_agent : src_agent);\n\n  // 1. We should specify the gpu agent here as the cpu already has\n  // access to the system memory.\n  // 2. The host can only use the pointer assigned from the system mem.\n  // alloc. call (e.g., \"local_alloc\" below). The gpu agent can only use the\n  // pointer returned by the lock call (e.g., \"locked_mem\" below). This is\n  // a current (as of August 2017) limitation of KFD.\n  err = hsa_amd_memory_lock(local_alloc, size, &gpu_agent, 1, &locked_mem);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (t->type == D2H || t->type == D2HRemote) {\n    err = hsa_amd_memory_pool_allocate(src_pool, size, 0, &ptr_src);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    ptr_dst = locked_mem;\n  } else if (t->type == H2D || t->type == H2DRemote) {\n    err = hsa_amd_memory_pool_allocate(dst_pool, size, 0, &ptr_dst);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    ptr_src = locked_mem;\n  } else {\n    ASSERT_EQ(t->type, P2P);\n    std::cout << \"Skipping P2P for NUMA test\" << std::endl;\n    return;\n  }\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  void* host_ptr_src = NULL;\n  void* host_ptr_dst = NULL;\n  err = hsa_amd_memory_pool_allocate(sys_pool_, size, 0,\n                                     reinterpret_cast<void**>(&host_ptr_src));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  err = hsa_amd_memory_pool_allocate(sys_pool_, size, 0,\n                                     reinterpret_cast<void**>(&host_ptr_dst));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  hsa_signal_t s;\n  err = hsa_signal_create(1, 0, NULL, &s);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // Deallocate resources...\n  MAKE_SCOPE_GUARD([&]() {\n    // NOTE that the host memory pointer (local_alloc) must be used below\n    err = hsa_amd_memory_unlock(local_alloc);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    if (t->type == D2H) {\n      err = hsa_amd_memory_pool_free(ptr_src);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n    } else {\n      err = hsa_amd_memory_pool_free(ptr_dst);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n    }\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    // numa_free(local_alloc, size);\n    hwloc_free(topology_, local_alloc, size);\n    err = hsa_amd_memory_pool_free(host_ptr_src);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n    err = hsa_amd_memory_pool_free(host_ptr_dst);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    err = hsa_signal_destroy(s);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n  });\n\n  hsa_agent_t *cpy_ag = nullptr;\n  // **** First copy from the system buffer source to the test source pool\n  // Acquire the appropriate access; prefer GPU agent over CPU where there\n  // is a choice. We don't need to do this is the test source happens to\n  // be the host pool\n\n  err = hsa_amd_memory_fill(host_ptr_src, 1, size/sizeof(uint32_t));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = hsa_amd_memory_fill(host_ptr_dst, 0, size/sizeof(uint32_t));\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (t->type == D2H) {\n    cpy_ag = AcquireAsyncCopyAccess(ptr_src, src_pool, &src_agent,\n                                        host_ptr_src, sys_pool_, &cpu_agent_);\n    if (cpy_ag == nullptr) {\n      std::cout << \"Agents \" << t->src << \" and \" << t->dst <<\n                              \"cannot access each other's pool.\" << std::endl;\n      std::cout << \"Skipping...\" << std::endl;\n      return;\n    }\n    ASSERT_NE(cpy_ag, nullptr);\n\n    err = hsa_amd_memory_async_copy(ptr_src, *cpy_ag, host_ptr_src, *cpy_ag,\n                                                            size, 0, NULL, s);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    while (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,\n                                         uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n    {}\n\n    memset(local_alloc, 0, size);\n  } else {  // H2D\n    cpy_ag = AcquireAsyncCopyAccess(ptr_dst, dst_pool, &dst_agent,\n                                        host_ptr_dst, sys_pool_, &cpu_agent_);\n    if (cpy_ag == nullptr) {\n      std::cout << \"Agents \" << t->src << \" and \" << t->dst <<\n                              \"cannot access each other's pool.\" << std::endl;\n      std::cout << \"Skipping...\" << std::endl;\n      return;\n    }\n    ASSERT_NE(cpy_ag, nullptr);\n\n    err = hsa_amd_memory_async_copy(ptr_src, *cpy_ag, host_ptr_src, *cpy_ag,\n                                                            size, 0, NULL, s);\n    ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n    while (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,\n                                         uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n    {}\n\n    memset(local_alloc, 1, size);\n  }\n\n  int iterations = RealIterationNum();\n\n  // **** Next, copy from the test source pool to the test destination pool\n  // Prefer a gpu agent to a cpu agent\n\n  ASSERT_NE(cpy_ag, nullptr);\n\n  cpy_ag = AcquireAsyncCopyAccess(ptr_dst, dst_pool, &dst_agent,\n              ptr_src, src_pool, &src_agent);\n  if (cpy_ag == nullptr) {\n    std::cout << \"Agents \" << t->src << \" and \" << t->dst <<\n                            \"cannot access each other's pool.\" << std::endl;\n    std::cout << \"Skipping...\" << std::endl;\n    return;\n  }\n  ASSERT_NE(cpy_ag, nullptr);\n\n  for (int i = 0; i < kNumGranularity; i++) {\n    if (Size[i] > size) {\n      break;\n    }\n\n    std::vector<double> time;\n\n    for (int it = 0; it < iterations; it++) {\n      if (verbosity() >= VERBOSE_PROGRESS) {\n        std::cout << \".\";\n        std::cout.flush();\n      }\n\n      hsa_signal_store_relaxed(t->signal, 1);\n\n      rocrtst::PerfTimer copy_timer;\n      int index = copy_timer.CreateTimer();\n\n      copy_timer.StartTimer(index);\n      err = hsa_amd_memory_async_copy(ptr_dst, *cpy_ag, ptr_src, *cpy_ag,\n                                                 Size[i], 0, NULL, t->signal);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n      while (hsa_signal_wait_scacquire(t->signal, HSA_SIGNAL_CONDITION_LT, 1,\n                                         uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n      {}\n\n      copy_timer.StopTimer(index);\n\n      hsa_signal_store_relaxed(s, 1);\n\n      err = AcquireAccess(dst_agent, sys_pool_, host_ptr_dst);\n      ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n      if (t->type == D2H) {\n        memcpy(host_ptr_dst, local_alloc, size);\n      } else {\n        err = hsa_amd_memory_async_copy(host_ptr_dst, dst_agent, ptr_dst,\n                                                 dst_agent, size, 0, NULL, s);\n        ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n        while (hsa_signal_wait_scacquire(s, HSA_SIGNAL_CONDITION_LT, 1,\n                                       uint64_t(-1), HSA_WAIT_STATE_ACTIVE))\n          {}\n      }\n\n      if (memcmp(host_ptr_src, host_ptr_dst, Size[i])) {\n        verified_ = false;\n      }\n      // Push the result back to vector time\n      time.push_back(copy_timer.ReadTimer(index));\n    }\n\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << std::endl;\n    }\n\n    // Get Min copy time\n    t->min_time->push_back(*std::min_element(time.begin(), time.end()));\n    // Get mean copy time and store to the array\n    t->benchmark_copy_time->push_back(GetMeanTime(&time));\n  }\n}\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/performance/memory_async_copy_numa.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_NUMA_H_\n#define ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_NUMA_H_\n\n#include <hwloc.h>\n\n#include <vector>\n#include <algorithm>\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"hsa/hsa_ext_amd.h\"\n#include \"suites/test_common/test_base.h\"\n#include \"suites/performance/memory_async_copy.h\"\n\nclass MemoryAsyncCopyNUMA : public MemoryAsyncCopy {\n public:\n  MemoryAsyncCopyNUMA();\n\n  // @Brief: Destructor for test case of MemoryAsyncCopyNUMA\n  virtual ~MemoryAsyncCopyNUMA();\n\n  virtual void Run();\n\n protected:\n  // @Brief: Run for Benchmark mode with verification\n  virtual void RunBenchmarkWithVerification(Transaction *t);\n};\n\n#endif  // ROCRTST_SUITES_PERFORMANCE_MEMORY_ASYNC_COPY_NUMA_H_\n"
  },
  {
    "path": "rocrtst/suites/stress/memory_concurrent_tests.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <string>\n\n#include \"suites/stress/memory_concurrent_tests.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"common/concurrent_utils.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n\nstatic const uint32_t kNumThreads = 1024;\nstatic const uint32_t kMaxAllocSize = 1024 * 1024;\n\n\n\n\ntypedef struct control_block {\n    hsa_amd_memory_pool_t* pool;\n    size_t alloc_size;\n    void* alloc_pointer;\n} cb_t;\n\n\n// Callback function which will call upon when need\n// to allocate memory from the pool in the thread.\nstatic void CallbackHSAMemoryAllocateFunc(void *data) {\n  hsa_status_t err;\n  cb_t *cb = static_cast<cb_t*>(data);\n\n  err = hsa_amd_memory_pool_allocate(*(cb->pool),\n                               cb->alloc_size, 0,\n                               reinterpret_cast<void**>(&(cb->alloc_pointer)));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  return;\n}\n\n// Callback function which will call upon when need\n// to Free memory from the pool in the thread.\nstatic void CallbackHSAMemoryFreeFunc(void *data) {\n  hsa_status_t err;\n  cb_t *cb = static_cast<cb_t*>(data);\n\n  err = hsa_memory_free(cb->alloc_pointer);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  return;\n}\n\ntypedef struct thread_data_get_pool_info_s {\n    // The current pool\n    hsa_amd_memory_pool_t pool;\n    // The pool info retrieved from main thread\n    rocrtst::pool_info_t* info;\n    // Consistency check result\n    int consistency;\n} thread_data_get_pool_info_t;\n\n// Callback function which will call upon when need\n// to Fetch different info for the pool in the thread.\nstatic void CallbackGetPoolInfo(void* data) {\n  hsa_status_t err;\n\n  thread_data_get_pool_info_t* thread_data =\n              static_cast<thread_data_get_pool_info_t*>(data);\n\n  rocrtst::pool_info_t info;\n  memset(&info, 0, sizeof(rocrtst::pool_info_t));\n  err = rocrtst::AcquirePoolInfo(thread_data->pool, &info);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (*(thread_data->info) == info) {\n    // The pool info is consistent with the one got from the main thread\n    thread_data->consistency = 1;\n  } else {\n    thread_data->consistency = 0;\n  }\n}\n\nMemoryConcurrentTest::MemoryConcurrentTest(bool launch_Concurrent_Allocate_,\n                      bool launch_Concurrent_Free_ ,\n                      bool launch_Concurrent_PoolGetInfo_) :TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  std::string name;\n  std::string desc;\n\n  name = \"RocR Memory Concurrent\";\n  desc = \"These series of tests are Stress tests which contains different subtests \";\n\n  if (launch_Concurrent_Allocate_) {\n    name += \" Allocate\";\n    desc += \" This test Verify that memory can be concurrently allocated from pool\"\n            \" and thread safety while allocating memory from different threads\"\n            \" on ROCR agents\";\n  } else if (launch_Concurrent_Free_) {\n    name += \" Free\";\n    desc += \" This test thet memory Verify can be concurrently freed from pool\"\n            \" and thread safety while memory free from different threads\"\n            \" on ROCR agents\";\n  } else if (launch_Concurrent_PoolGetInfo_) {\n    name += \" PoolGetInfo\";\n    desc += \" This test Verify that memory pool info can be concurrently \"\n            \" get from different threads on ROCR agents\";\n  }\n  set_title(name);\n  set_description(desc);\n}\n\nMemoryConcurrentTest::~MemoryConcurrentTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid MemoryConcurrentTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid MemoryConcurrentTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid MemoryConcurrentTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid MemoryConcurrentTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid MemoryConcurrentTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintMemorySubtestHeader(const char *header) {\n  std::cout << \"  *** Memory Stress Subtest: \" << header << \" ***\" << std::endl;\n}\n\nstatic void PrintAgentNameAndType(hsa_agent_t agent) {\n  hsa_status_t err;\n\n  char ag_name[64];\n  hsa_device_type_t ag_type;\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, ag_name);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  std::cout << \"  Agent: \" << ag_name << \" (\";\n  switch (ag_type) {\n    case HSA_DEVICE_TYPE_CPU:\n      std::cout << \"CPU)\";\n      break;\n    case HSA_DEVICE_TYPE_GPU:\n      std::cout << \"GPU)\";\n      break;\n    case HSA_DEVICE_TYPE_DSP:\n      std::cout << \"DSP)\";\n      break;\n    case HSA_DEVICE_TYPE_AIE:\n      std::cout << \"AIE)\";\n      break;\n    }\n  std::cout << std::endl;\n  return;\n}\n\n// This test verify check  memory can be\n// concurrently allocated from pool on ROCR agents\nvoid MemoryConcurrentTest::MemoryConcurrentAllocate(hsa_agent_t agent,\n                                               hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  // Determine if allocation is allowed in this memory pool\n  bool alloc = false;\n  err = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &alloc);\n\n  if (alloc) {\n    size_t alloc_size;\n    size_t total_vram_size;\n    hsa_device_type_t ag_type;\n\n    err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                      &total_vram_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // If VRAM size <= 512MB, it should be APU whose VRAM is carved from system memory\n    // and much smaller than dGPU. Change the threshold accordingly.\n    if (total_vram_size <= 536870912 && ag_type == HSA_DEVICE_TYPE_GPU) {\n      // Make sure do not allocate more than 1/4 of the available vram size\n      err = hsa_agent_get_info(agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                                &total_vram_size);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n      alloc_size = (total_vram_size*1/4 <= kMaxAllocSize*kNumThreads) ? total_vram_size*1/(4*kNumThreads): kMaxAllocSize;\n    } else {\n      // Make sure do not allocate more than 3/4 of the vram size\n      alloc_size = (total_vram_size*3/4 <= kMaxAllocSize*kNumThreads) ? total_vram_size*3/(4*kNumThreads): kMaxAllocSize;\n    }\n\n    // Page align the alloc_size\n    alloc_size = alloc_size - (alloc_size & ((1 << 12) - 1));\n\n    // Create a test group\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreads);\n\n    // The control blocks are used to pass data to the threads\n    uint32_t kk;\n    cb_t cb[kNumThreads];\n    for (kk = 0; kk < kNumThreads; kk++) {\n      cb[kk].pool = &pool;\n      cb[kk].alloc_size = alloc_size;\n      rocrtst::TestGroupAdd(tg_concurrent, &CallbackHSAMemoryAllocateFunc, &cb[kk], 1);\n    }\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n\n    // Check for overlapping addresses\n    char *addr1, *addr2;\n    for (kk = 0; kk < kNumThreads; ++kk) {\n      addr1 = reinterpret_cast<char *>(cb[kk].alloc_pointer);\n      addr2 = addr1+alloc_size;\n      ASSERT_NE(reinterpret_cast<void *>(addr1), nullptr);\n      uint32_t ll;\n      for (ll = kk+1; ll < kNumThreads; ++ll) {\n        if (addr1 < reinterpret_cast<char *>(cb[ll].alloc_pointer)) {\n          ASSERT_LE(addr2, reinterpret_cast<char *>(cb[ll].alloc_pointer));\n        }\n        if (addr2 > reinterpret_cast<char *>(cb[ll].alloc_pointer)+alloc_size) {\n          ASSERT_GE(addr1, reinterpret_cast<char *>(cb[ll].alloc_pointer)+alloc_size);\n        }\n      }\n    }\n\n    for (uint32_t ii = 0; ii < kNumThreads; ii++) {\n      err = hsa_memory_free(cb[ii].alloc_pointer);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n    }\n  }\n  return;\n}\n\n\n\n\n// This test verify check  memory can be\n// concurrently allocated from pool on ROCR agents\nvoid MemoryConcurrentTest::MemoryConcurrentFree(hsa_agent_t agent,\n                                                hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n  // Determine if allocation is allowed in this pool\n  bool alloc = false;\n  err = hsa_amd_memory_pool_get_info(pool,\n                   HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED, &alloc);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  if (alloc) {\n    // Get the maximum allocation size\n    size_t alloc_size;\n    size_t total_vram_size;\n    hsa_device_type_t ag_type;\n\n    err = hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE,\n                                      &total_vram_size);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    err = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &ag_type);\n    ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n    // If VRAM size <= 512MB, it should be APU whose VRAM is carved from system memory\n    // and much smaller than dGPU. Change the threshold accordingly.\n    if (total_vram_size <= 536870912 && ag_type == HSA_DEVICE_TYPE_GPU) {\n      // Make sure do not allocate more than 1/4 of the available vram size\n      err = hsa_agent_get_info(agent, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_MEMORY_AVAIL,\n                                &total_vram_size);\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n      alloc_size = (total_vram_size*1/4 <= kMaxAllocSize*kNumThreads) ? total_vram_size*1/(4*kNumThreads): kMaxAllocSize;\n    } else {\n      // Make sure do not allocate more than 3/4 of the vram size\n      alloc_size = (total_vram_size*3/4 <= kMaxAllocSize*kNumThreads) ? total_vram_size*3/(4*kNumThreads): kMaxAllocSize;\n    }\n\n    // Page align the alloc_size\n    alloc_size = alloc_size - (alloc_size & ((1 << 12) - 1));\n\n    // Create a test group\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreads);\n\n    // The control blocks are used to pass data to the threads\n    uint32_t kk;\n    cb_t cb[kNumThreads];\n    for (kk = 0; kk < kNumThreads; kk++) {\n      cb[kk].pool = &pool;\n      cb[kk].alloc_size = alloc_size;\n      err = hsa_amd_memory_pool_allocate(*(cb[kk].pool), cb[kk].alloc_size, 0, &(cb[kk].alloc_pointer));\n      ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n      rocrtst::TestGroupAdd(tg_concurrent, &CallbackHSAMemoryFreeFunc, &cb[kk], 1);\n    }\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n  }\n  return;\n}\n\n\n// This test verify if each Agent pool's attribute information\n// is consistent across multiple thread.\nvoid MemoryConcurrentTest::MemoryConcurrentPoolGetInfo(hsa_agent_t agent,\n                                                hsa_amd_memory_pool_t pool) {\n  hsa_status_t err;\n\n  rocrtst::pool_info_t pool_i;\n  err = rocrtst::AcquirePoolInfo(pool, &pool_i);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  if (verbosity() > 0) {\n    PrintAgentNameAndType(agent);\n  }\n\n\n  uint32_t kk;\n  thread_data_get_pool_info_t thread_data[kNumThreads];\n\n  // Create a test group\n  rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreads);\n\n  for (kk = 0; kk < kNumThreads; kk++) {\n    thread_data[kk].pool = pool;\n    thread_data[kk].info = &pool_i;\n    thread_data[kk].consistency = 0;\n    rocrtst::TestGroupAdd(tg_concurrent, &CallbackGetPoolInfo, thread_data + kk, 1);\n  }\n\n  // Create threads for each test\n  rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n  // Start to run tests\n  rocrtst::TestGroupStart(tg_concurrent);\n\n  // Wait all tests finish\n  rocrtst::TestGroupWait(tg_concurrent);\n\n  // Exit all tests\n  rocrtst::TestGroupExit(tg_concurrent);\n\n  // Destroy thread group and cleanup resources\n  rocrtst::TestGroupDestroy(tg_concurrent);\n\n  // Verify pool info is consistent among all threads\n  for (kk = 0; kk < kNumThreads; kk++) {\n    ASSERT_EQ(thread_data[kk].consistency, 1);\n  }\n  return;\n}\n\n\n\nvoid MemoryConcurrentTest::MemoryConcurrentAllocate(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryConcurrentAllocate in Stress Test\");\n  }\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryConcurrentAllocate(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryConcurrentTest::MemoryConcurrentFree(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryConcurrentFree in Stress Test\");\n  }\n\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryConcurrentFree(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid MemoryConcurrentTest::MemoryConcurrentPoolGetInfo(void) {\n  hsa_status_t err;\n  std::vector<std::shared_ptr<rocrtst::agent_pools_t>> agent_pools;\n\n  if (verbosity() > 0) {\n    PrintMemorySubtestHeader(\"MemoryConcurrentPoolGetInfo in Stress Test\");\n  }\n  err = rocrtst::GetAgentPools(&agent_pools);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  auto pool_idx = 0;\n  for (auto a : agent_pools) {\n    for (auto p : a->pools) {\n      if (verbosity() > 0) {\n        std::cout << \"  Pool \" << pool_idx++ << \":\" << std::endl;\n      }\n      MemoryConcurrentPoolGetInfo(a->agent, p);\n    }\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n"
  },
  {
    "path": "rocrtst/suites/stress/memory_concurrent_tests.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_STRESS_MEMORY_CONCURRENT_TESTS_H_\n#define ROCRTST_SUITES_STRESS_MEMORY_CONCURRENT_TESTS_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\n\nclass MemoryConcurrentTest : public TestBase {\n public:\n    MemoryConcurrentTest(bool launch_Concurrent_Allocate_,\n                         bool launch_Concurrent_Free_ ,\n                         bool launch_Concurrent_PoolGetInfo_);\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~MemoryConcurrentTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n\n  // @Brief: This test verify check  memory can be\n  // concurrently allocated from pool on ROCR agents\n  void MemoryConcurrentAllocate(void);\n\n  // @Brief: This test verify check  memory can be\n  // concurrently freed from pool on ROCR agents\n  void MemoryConcurrentFree(void);\n\n  // @Brief: This test verify if each Agent pool's attribute information\n  // is consistent across multiple thread.\n  void MemoryConcurrentPoolGetInfo(void);\n\n private:\n  void MemoryConcurrentAllocate(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n  void MemoryConcurrentFree(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n  void MemoryConcurrentPoolGetInfo(hsa_agent_t agent,\n                             hsa_amd_memory_pool_t pool);\n\n  // @Brief: Indicate if launch concurrent allocate test\n  bool launch_Concurrent_Allocate_;\n\n  // @Brief: Indicate if launch concurrent Free test\n  bool launch_Concurrent_Free_;\n\n  // @Brief: Indicate if launch concurrent pool get info test\n  bool launch_Concurrent_PoolGetInfo_;\n};\n\n#endif  // ROCRTST_SUITES_STRESS_MEMORY_CONCURRENT_TESTS_H_\n"
  },
  {
    "path": "rocrtst/suites/stress/queue_write_index_concurrent_tests.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#include <fcntl.h>\n#include <algorithm>\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <string>\n\n#include \"suites/stress/queue_write_index_concurrent_tests.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"common/concurrent_utils.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\nenum memoryOrdering {\n  SCACQ_SCREL,\n  SCACQUIRE,\n  RELAXED,\n  SCRELEASE,\n  MEM_ORDERING_END};\n\nstatic const uint32_t kNumThreadsForAdd = 10;\n\nstatic const uint32_t kNumOfAddAtomic = 1*1024*1024;\n\ntypedef struct write_index_add_atomic_data_s {\n    hsa_queue_t* queue;\n    int memory_ordering_type;\n} write_index_add_atomic_data_t;\n\n\nstatic void thread_proc_write_index_add_atomic(void* data) {\n  write_index_add_atomic_data_t* thread_data = reinterpret_cast<write_index_add_atomic_data_t*> (data);\n  uint64_t ii;\n  for (ii = 0; ii < kNumOfAddAtomic; ++ii) {\n    switch (thread_data->memory_ordering_type) {\n      case SCACQ_SCREL:\n        hsa_queue_add_write_index_scacq_screl(thread_data->queue, 1);\n        break;\n      case SCACQUIRE:\n        hsa_queue_add_write_index_scacquire(thread_data->queue, 1);\n        break;\n      case RELAXED:\n        hsa_queue_add_write_index_relaxed(thread_data->queue, 1);\n        break;\n      case SCRELEASE:\n        hsa_queue_add_write_index_screlease(thread_data->queue, 1);\n        break;\n      default:\n        break;\n    }\n  }\n}\n\nstatic const uint32_t kNumThreadsForCas = 4;\nstatic const uint32_t kNumOfCasAtomic = 1*1024*1024;\ntypedef struct write_index_cas_thread_data_s {\n    hsa_queue_t* queue;\n    int thread_index;\n    int num_threads;\n    uint64_t termination_value;\n    int memory_ordering_type;\n} write_index_cas_thread_data_t;\n\nstatic void thread_proc_write_index_cas_atomic(void* data) {\n  write_index_cas_thread_data_t* thread_data = reinterpret_cast<write_index_cas_thread_data_t*>(data);\n\n  uint64_t ii;\n  for (ii = thread_data->thread_index; ii < thread_data->termination_value; ii += thread_data->num_threads) {\n    switch (thread_data->memory_ordering_type) {\n      case SCACQ_SCREL:\n        while ((uint64_t)ii !=\n          hsa_queue_cas_write_index_scacq_screl(thread_data->queue, ii, ii + 1)) {}\n          break;\n     case SCACQUIRE:\n        while ((uint64_t)ii !=\n          hsa_queue_cas_write_index_scacquire(thread_data->queue, ii, ii + 1)) {}\n          break;\n     case RELAXED:\n        while ((uint64_t)ii !=\n          hsa_queue_cas_write_index_relaxed(thread_data->queue, ii, ii + 1)) {}\n          break;\n     case SCRELEASE:\n        while ((uint64_t)ii !=\n          hsa_queue_cas_write_index_screlease(thread_data->queue, ii, ii + 1)) {}\n          break;\n        }\n    }\n}\n\nstatic const uint32_t kNumOfLoadStoreAtomic = 1*1024*1024;\n// Use a 64-bit value to test the atomicity\nstatic uint64_t kStoreValue = UINT64_MAX;\n\ntypedef struct write_index_load_atomic_thread_data_s {\n  hsa_queue_t* queue;\n  uint64_t num_iterations;\n  int memory_ordering_type;\n} write_index_load_atomic_thread_data_t;\n\ntypedef struct write_index_store_atomic_thread_data_s {\n  hsa_queue_t* queue;\n  uint64_t kStoreValue;\n  uint64_t num_iterations;\n  int memory_ordering_type;\n} write_index_store_atomic_thread_data_t;\n\nstatic uint64_t const WRITE_INDEX_FAILURE = 2;\nvoid thread_proc_write_index_load_atomic(void* data) {\n  write_index_load_atomic_thread_data_t* thread_data =\n              reinterpret_cast<write_index_load_atomic_thread_data_t*>(data);\n  uint32_t ii;\n  for (ii = 0; ii < thread_data->num_iterations; ++ii) {\n    uint64_t write_index = WRITE_INDEX_FAILURE;  // initalized with value other than kStoreValue\n    if (SCRELEASE == thread_data->memory_ordering_type) {\n      write_index = hsa_queue_load_write_index_scacquire(thread_data->queue);\n    } else if (RELAXED == thread_data->memory_ordering_type) {\n      write_index = hsa_queue_load_write_index_relaxed(thread_data->queue);\n    }\n    // The only two possible values\n    EXPECT_TRUE(0 == write_index || kStoreValue == write_index);\n  }\n}\n\nvoid thread_proc_write_index_store_atomic(void* data) {\n  write_index_store_atomic_thread_data_t* thread_data =\n              reinterpret_cast<write_index_store_atomic_thread_data_t*>(data);\n  uint32_t ii;\n  for (ii = 0; ii < thread_data->num_iterations; ++ii) {\n    if (SCRELEASE == thread_data->memory_ordering_type) {\n      hsa_queue_store_write_index_screlease(thread_data->queue, thread_data->kStoreValue);\n    } else if (RELAXED == thread_data->memory_ordering_type) {\n      hsa_queue_store_write_index_relaxed(thread_data->queue, thread_data->kStoreValue);\n    }\n  }\n}\n\n\n\nQueueWriteIndexConcurrentTest::QueueWriteIndexConcurrentTest(bool launch_Concurrent_AddWriteIndex,\n                      bool launch_Concurrent_CasWriteIndex ,\n                      bool launch_Concurrent_LoadStoreWriteIndex) :TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n\n  std::string name;\n  std::string desc;\n\n  name = \"RocR Queue write Index Tests\";\n  desc = \"These series of tests are Stress tests which contains different subtests \";\n\n  if (launch_Concurrent_AddWriteIndex) {\n    name += \" AddWriteIndex\";\n    desc += \" This test Verifies that the hsa_queue_write_index_add operations is atomic\"\n            \" and 'torn' adds do not occur when this API is executed concurrently.\";\n  } else if (launch_Concurrent_CasWriteIndex) {\n    name += \" CasWriteIndex\";\n    desc += \" This test Verifies that the hsa_queue_cas_write_index operations is atomic,\"\n            \" and 'torn' compare and swaps do not occur when this API is executed\"\n            \" concurrently.\";\n  } else if (launch_Concurrent_LoadStoreWriteIndex) {\n    name += \" LoadStoreWriteIndex\";\n    desc += \" This test Verifies that the hsa_queue_write_index_load and store operations\"\n            \" are atomic, and 'torn' loads or stores do not occur when these APIs are executed\"\n            \" concurrently.\";\n  }\n  set_title(name);\n  set_description(desc);\n}\n\nQueueWriteIndexConcurrentTest::~QueueWriteIndexConcurrentTest(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid QueueWriteIndexConcurrentTest::SetUp(void) {\n  hsa_status_t err;\n\n  TestBase::SetUp();\n\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  return;\n}\n\nvoid QueueWriteIndexConcurrentTest::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n}\n\nvoid QueueWriteIndexConcurrentTest::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid QueueWriteIndexConcurrentTest::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  return;\n}\n\nvoid QueueWriteIndexConcurrentTest::Close() {\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n\n\nstatic const char kSubTestSeparator[] = \"  **************************\";\n\nstatic void PrintDebugSubtestHeader(const char *header) {\n  std::cout << \"  *** QueueWriteIndexConcurrent Subtest: \" << header << \" ***\" << std::endl;\n}\n\n\n\n// This test verify check  memory can be\n// concurrently allocated from pool on ROCR agents\nvoid QueueWriteIndexConcurrentTest::QueueAddWriteIndexAtomic(hsa_agent_t cpuAgent,\n                                    hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // check if the gpuAgent supports kernel dispatch\n  uint32_t features = 0;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_FEATURE, &features);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\n    return;\n  }\n\n\n  // Get max number of queues\n  uint32_t queue_size;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Create a queue\n  hsa_queue_t* queue;\n  err = hsa_queue_create(gpuAgent, queue_size, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  int memory_ordering_type;\n  for (memory_ordering_type = SCACQ_SCREL; memory_ordering_type < MEM_ORDERING_END; ++memory_ordering_type) {\n    // Thread data\n    write_index_add_atomic_data_t thread_data;\n    thread_data.queue = queue;\n    thread_data.memory_ordering_type = memory_ordering_type;\n\n    // Create a test group\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreadsForAdd);\n\n    uint32_t kk;\n    for (kk = 0; kk < kNumThreadsForAdd; kk++) {\n      rocrtst::TestGroupAdd(tg_concurrent, &thread_proc_write_index_add_atomic, &thread_data, 1);\n    }\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n\n    // Verify the write_index\n    uint64_t write_index = hsa_queue_load_write_index_relaxed(queue);\n    uint64_t expected = (uint64_t)(kNumOfAddAtomic * kNumThreadsForAdd);\n    ASSERT_EQ(write_index, expected);\n\n    // Restore the write_index of the queue\n    hsa_queue_store_write_index_screlease(queue, 0);\n  }\n\n  // Destroy queue\n  err = hsa_queue_destroy(queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n}\n\n\n\n\n// This test verify check  memory can be\n// concurrently allocated from pool on ROCR agents\nvoid QueueWriteIndexConcurrentTest::QueueCasWriteIndexAtomic(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // check if the gpuAgent supports kernel dispatch\n  uint32_t features = 0;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_FEATURE, &features);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\n    return;\n  }\n\n\n  // Get max number of queues\n  uint32_t queue_size;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Create a queue\n  hsa_queue_t* queue;\n  err = hsa_queue_create(gpuAgent, queue_size, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  int memory_ordering_type;\n  for (memory_ordering_type = SCACQ_SCREL; memory_ordering_type < MEM_ORDERING_END; ++memory_ordering_type) {\n    // Thread data\n    write_index_cas_thread_data_t thread_data[kNumThreadsForCas];\n\n    // Create a test group\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(kNumThreadsForCas);\n\n    uint32_t kk;\n    for (kk = 0; kk < kNumThreadsForCas; ++kk) {\n      thread_data[kk].queue = queue;\n      thread_data[kk].thread_index = kk;\n      thread_data[kk].num_threads = kNumThreadsForCas;\n      thread_data[kk].memory_ordering_type = memory_ordering_type;\n      thread_data[kk].termination_value = kNumOfCasAtomic;\n      rocrtst::TestGroupAdd(tg_concurrent, &thread_proc_write_index_cas_atomic, thread_data + kk, 1);\n    }\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n\n    // Verify the write_index\n    uint64_t write_index = hsa_queue_load_write_index_relaxed(queue);\n    uint64_t expected = (uint64_t)(kNumOfCasAtomic);\n    ASSERT_EQ(write_index, expected);\n\n    // Restore the write_index of the queue\n    hsa_queue_store_write_index_screlease(queue, 0);\n  }\n\n  // Destroy queue\n  err = hsa_queue_destroy(queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n}\n\n\n// This test verify if each Agent pool's attribute information\n// is consistent across multiple thread.\nvoid QueueWriteIndexConcurrentTest::QueueLoadStoreWriteIndexAtomic(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent) {\n  hsa_status_t err;\n\n  // check if the gpuAgent supports kernel dispatch\n  uint32_t features = 0;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_FEATURE, &features);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n  if (0 == (features & HSA_AGENT_FEATURE_KERNEL_DISPATCH)) {\n    return;\n  }\n\n\n  // Get max number of queues\n  uint32_t queue_size;\n  err = hsa_agent_get_info(gpuAgent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Create a queue\n  hsa_queue_t* queue;\n  err = hsa_queue_create(gpuAgent, queue_size, HSA_QUEUE_TYPE_SINGLE, NULL, NULL, UINT32_MAX, UINT32_MAX, &queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Use a 64-bit value to test the atomicity\n  kStoreValue = UINT64_MAX;\n\n  int memory_ordering_type;\n  for (memory_ordering_type = RELAXED; memory_ordering_type < MEM_ORDERING_END; ++memory_ordering_type) {\n    // Thread data\n    write_index_load_atomic_thread_data_t  load_thread_data[2];\n    write_index_store_atomic_thread_data_t store_thread_data[2];\n    load_thread_data[0].queue = queue;\n    load_thread_data[0].num_iterations = kNumOfLoadStoreAtomic;\n    load_thread_data[0].memory_ordering_type = memory_ordering_type;\n    load_thread_data[1].queue = queue;\n    load_thread_data[1].num_iterations = kNumOfLoadStoreAtomic;\n    load_thread_data[1].memory_ordering_type = memory_ordering_type;\n\n    store_thread_data[0].queue = queue;\n    store_thread_data[0].kStoreValue = 0;\n    store_thread_data[0].num_iterations = kNumOfLoadStoreAtomic;\n    store_thread_data[0].memory_ordering_type = memory_ordering_type;\n    store_thread_data[1].queue = queue;\n    store_thread_data[1].kStoreValue = kStoreValue;\n    store_thread_data[1].num_iterations = kNumOfLoadStoreAtomic;\n    store_thread_data[1].memory_ordering_type = memory_ordering_type;\n    // Create a test group\n    rocrtst::test_group* tg_concurrent = rocrtst::TestGroupCreate(4);\n    rocrtst::TestGroupAdd(tg_concurrent, &thread_proc_write_index_load_atomic, load_thread_data, 1);\n    rocrtst::TestGroupAdd(tg_concurrent, &thread_proc_write_index_load_atomic, load_thread_data  + 1, 1);\n    rocrtst::TestGroupAdd(tg_concurrent,  &thread_proc_write_index_store_atomic, store_thread_data, 1);\n    rocrtst::TestGroupAdd(tg_concurrent, &thread_proc_write_index_store_atomic, store_thread_data + 1, 1);\n\n\n    // Create threads for each test\n    rocrtst::TestGroupThreadCreate(tg_concurrent);\n\n    // Start to run tests\n    rocrtst::TestGroupStart(tg_concurrent);\n\n    // Wait all tests finish\n    rocrtst::TestGroupWait(tg_concurrent);\n\n    // Exit all tests\n    rocrtst::TestGroupExit(tg_concurrent);\n\n    // Destroy thread group and cleanup resources\n    rocrtst::TestGroupDestroy(tg_concurrent);\n  }\n\n  // Destroy queue\n  err = hsa_queue_destroy(queue);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n}\n\n\nvoid QueueWriteIndexConcurrentTest::QueueAddWriteIndexAtomic(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"QueueAddWriteIndexAtomic\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueAddWriteIndexAtomic(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueWriteIndexConcurrentTest::QueueCasWriteIndexAtomic(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"QueueCasWriteIndexAtomic\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueCasWriteIndexAtomic(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\nvoid QueueWriteIndexConcurrentTest::QueueLoadStoreWriteIndexAtomic(void) {\n  hsa_status_t err;\n\n  if (verbosity() > 0) {\n    PrintDebugSubtestHeader(\"QueueLoadStoreWriteIndexAtomic\");\n  }\n\n  // find all cpu agents\n  std::vector<hsa_agent_t> cpus;\n  err = hsa_iterate_agents(rocrtst::IterateCPUAgents, &cpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // find all gpu agents\n  std::vector<hsa_agent_t> gpus;\n  err = hsa_iterate_agents(rocrtst::IterateGPUAgents, &gpus);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  for (unsigned int i = 0 ; i< gpus.size(); ++i) {\n    QueueLoadStoreWriteIndexAtomic(cpus[0], gpus[i]);\n  }\n\n  if (verbosity() > 0) {\n    std::cout << \"subtest Passed\" << std::endl;\n    std::cout << kSubTestSeparator << std::endl;\n  }\n}\n\n"
  },
  {
    "path": "rocrtst/suites/stress/queue_write_index_concurrent_tests.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_STRESS_QUEUE_WRITE_INDEX_CONCURRENT_TESTS_H_\n#define ROCRTST_SUITES_STRESS_QUEUE_WRITE_INDEX_CONCURRENT_TESTS_H_\n\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\n\nclass QueueWriteIndexConcurrentTest : public TestBase {\n public:\n    QueueWriteIndexConcurrentTest(bool launch_Concurrent_AddWriteIndex,\n                         bool launch_Concurrent_CasWriteIndex ,\n                         bool launch_Concurrent_LoadStoreWriteIndex);\n\n  // @Brief: Destructor for test case of MemoryTest\n  virtual ~QueueWriteIndexConcurrentTest();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n\n  // @Brief: Verifies that the hsa_queue_write_index_add operations is atomic,\n  // and 'torn' adds do not occur when this API is executed concurrently.\n  void QueueAddWriteIndexAtomic(void);\n\n  // @Brief:  Verifies that the hsa_queue_cas_write_index operations is atomic,\n  // and 'torn' compare and swaps do not occur when this API is executed\n  // concurrently.\n  void QueueCasWriteIndexAtomic(void);\n\n  // @Brief: Verifies that the hsa_queue_write_index_load and store operations\n  // are atomic, and 'torn' loads or stores do not occur when these APIs are executed\n  // concurrently.\n  void QueueLoadStoreWriteIndexAtomic(void);\n\n private:\n  void QueueAddWriteIndexAtomic(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueCasWriteIndexAtomic(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n  void QueueLoadStoreWriteIndexAtomic(hsa_agent_t cpuAgent, hsa_agent_t gpuAgent);\n};\n\n#endif  // ROCRTST_SUITES_STRESS_QUEUE_WRITE_INDEX_CONCURRENT_TESTS_H_\n"
  },
  {
    "path": "rocrtst/suites/test_common/CMakeLists.txt",
    "content": "#\n#   Required Defines on cmake command line\n#\n#   1) Set location of ROCR header files\n#\n#      ROCM_DIR=\"Root for RocM install\"\n#\n#   2) Set ROCRTST_BLD_TYPE to either \"Debug\" or \"Release\".\n#      If not set, the default value is \"Debug\" is bound.\n#\n#      ROCRTST_BLD_TYPE=Debug or ROCRTST_BLD_TYPE=Release\n#\n#   3) Set ROCRTST_BLD_BITS to either \"32\" or \"64\"\n#      If not set, the default value of \"64\" is bound.\n#\n#       ROCRTST_BLD_BITS=32 or ROCRTST_BLD_BITS=64\n#\n#   4) Set TARGET_DEVICES to indicate gpu types for kernel\n#      builds (e.g., \"gfx803;gfx900; ...\")\n#\n#   Building rocrtst Suite\n#\n#\n#   1) Create build folder e.g. \"rocrtst/build\" - any name will do\n#   2) Cd into build folder\n#   3) Run \"cmake ..\"\n#   4) Run \"make\"\n#\n\ncmake_minimum_required(VERSION 3.5.0)\n\n# Set Name for Samples Project\n#\n\nset(PROJECT_NAME \"rocrtst64\")\nproject (${PROJECT_NAME})\n\nif ( NOT DEFINED BUILD_SHARED_LIBS )\n  set ( BUILD_SHARED_LIBS ON )\nendif()\n\n# For DEB/RPM generation\nif(BUILD_SHARED_LIBS)\n  set ( CPACK_PACKAGE_NAME \"rocrtst\" )\nelse()\n  set ( CPACK_RPM_PACKAGE_NAME \"rocrtst-static\" )\n  set ( CPACK_DEBIAN_PACKAGE_NAME \"rocrtst-static\" )\nendif()\n\nset ( CPACK_PACKAGE_CONTACT \"Advanced Micro Devices Inc.\" )\nset ( CPACK_PACKAGE_DESCRIPTION \"This package includes rocrtst and a convenience script to run the test suite\" )\nset ( CPACK_PACKAGE_DESCRIPTION_SUMMARY \"Test suite for ROCr\" )\nset ( CPACK_PACKAGE_VERSION_MAJOR \"1\" )\nset ( CPACK_PACKAGE_VERSION_MINOR \"0\" )\nset ( CPACK_PACKAGE_VERSION_PATCH \"0\" )\n\n# Make proper version for appending\n# Default Value is 99999, setting it first\nset(ROCM_VERSION_FOR_PACKAGE \"99999\")\nif(DEFINED ENV{ROCM_LIBPATCH_VERSION})\n  set(ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_LIBPATCH_VERSION})\nendif()\nset (PACKAGE_VERSION_STR \"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${ROCM_VERSION_FOR_PACKAGE}\")\nset ( CPACK_PACKAGE_VERSION \"${PACKAGE_VERSION_STR}\")\n\nset ( CPACK_PACKAGING_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"  CACHE STRING \"Default packaging prefix.\" )\nset ( CPACK_GENERATOR \"DEB;RPM\"  CACHE STRING \"Default packaging generators.\" )\nset ( CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/RadeonOpenCompute/ROCR-Runtime\" )\nset ( CPACK_PACKAGE_HOMEPAGE_URL \"https://github.com/RadeonOpenCompute/ROCR-Runtime\" )\nset ( CPACK_RPM_PACKAGE_AUTOREQ 0 )\nset ( CPACK_RPM_FILE_NAME \"RPM-DEFAULT\" )\nset ( CPACK_DEBIAN_FILE_NAME \"DEB-DEFAULT\" )\n## Debian package values\nset ( CPACK_DEBIAN_PACKAGE_RELEASE \"local\" )\nif( DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE} )\n  set ( CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE} )\nendif()\n\nif(BUILD_SHARED_LIBS)\n  set (CPACK_DEBIAN_PACKAGE_DEPENDS \"rocm-core,hsa-rocr\")\nelse()\n  set (CPACK_DEBIAN_PACKAGE_DEPENDS \"rocm-core,hsa-rocr-static-dev\")\nendif()\n\n## RPM package variables\nset ( CPACK_RPM_PACKAGE_RELEASE \"local\" )\nif( DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE} )\n  set ( CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE} )\nendif()\n## Add os details to rpm package name. For deb packages, its set from build environment\n# Modify line 87 to be \"if the env. variable DISTRO_NAME IS centos or rhel\"\nif (DEFINED ENV{DISTRO_NAME} AND\n  (ENV{DISTRO_NAME} MATCHES \"centos\" OR\n   ENV{DISTRO_NAME} MATCHES \"rhel\" OR\n   ENV{DISTRO_NAME} MATCHES \"sles\"))\n  execute_process(COMMAND rpm --eval %{?dist}\n          RESULT_VARIABLE PROC_RESULT\n          OUTPUT_VARIABLE EVAL_RESULT\n          OUTPUT_STRIP_TRAILING_WHITESPACE)\n  if (PROC_RESULT EQUAL \"0\" AND NOT EVAL_RESULT STREQUAL \"\")\n    string (APPEND CPACK_RPM_PACKAGE_RELEASE \"%{?dist}\")\n  endif()\nendif()\n\n\nif(BUILD_SHARED_LIBS)\n  set (CPACK_RPM_PACKAGE_REQUIRES \"rocm-core,hsa-rocr\")\nelse()\n  set (CPACK_RPM_PACKAGE_REQUIRES \"rocm-core,hsa-rocr-static-devel\")\nendif()\n\nset(DEFAULT_TARGETS \"gfx700;gfx701;gfx702;gfx801;gfx802;gfx803;gfx805;gfx810\"\n                    \"gfx900;gfx902;gfx904;gfx906;gfx908;gfx909;gfx90a;gfx90c;gfx942;gfx950\"\n                    \"gfx1010;gfx1011;gfx1012;gfx1013;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036\"\n                    \"gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151;gfx1152;gfx1153;gfx1200;gfx1201\")\n\n#\n# Currently support for Windows platform is not present\n#\n\n#############################\n# COMMON AREA\n#############################\nif(WIN32)\n  message(\"rocrtst Suite is not supported on Windows platform\")\n  return()\nendif()\n\n#\n# Process input variables\n#\n\n# Required Defines first:\nfind_package(hsa-runtime64 REQUIRED)\nfind_package(amd_smi REQUIRED)\n\nset (ONLY64STR \"64\")\n\nif (DEFINED LLVM_DIR)\n  set(CLANG ${LLVM_DIR}/clang)\n  if (NOT EXISTS ${CLANG})\n    message(\"ERROR: path to clang (${CLANG}) is not valid. Is define LLVM_DIR correct?\")\n    return()\n  endif()\nelse()\n    message(\"WARNING: LLVM_DIR define is not set. Kernels will not be built.\")\nendif()\n\nif (DEFINED OPENCL_DIR)\n  set(OPENCL_INC_DIR ${OPENCL_DIR}/include)\n  set(OPENCL_LIB_DIR ${OPENCL_DIR}/lib)\nelse()\n    message(\"WARNING: OPENCL_DIR define is not set. Kernels will not be built.\")\nendif()\n\nif (DEFINED OPENCL_VER)\n  set(OPENCL_VER ${OPENCL_VER})\nelse()\n  message(\"OPENCL_VER define is not set. Using default\")\n  set(OPENCL_VER \"2.0\")\nendif()\n\nif(NOT EXISTS \"${OPENCL_INC_DIR}/opencl-c.h\")\n  if(DEFINED ENV{LLVM_PROJECT_ROOT})\n    set(OPENCL_INC_DIR \"$ENV{LLVM_PROJECT_ROOT}/clang/lib/Headers/\")\n  else()\n    set(OPENCL_INC_DIR \"${OPENCL_DIR}/../../../external/llvm-project/clang/lib/Headers/\")\n  endif()\n  if(NOT EXISTS \"${OPENCL_INC_DIR}/opencl-c.h\")\n    message(WARNING \"opencl-c.h not found.\")\n  endif()\nendif()\n\nif (NOT DEFINED TARGET_DEVICES)\n  message(\"No targets devices provided on command line\")\n  message(\"  e.g., cmake -DTARGET_DEVICES=\\\"gfx803;gfx900;gfx...\\\" ..\")\n  message(\"  Using default target of ${DEFAULT_TARGETS}\")\n  list(APPEND TARGET_DEVICES ${DEFAULT_TARGETS})\nendif()\n\nstring(TOLOWER \"${ROCRTST_BLD_TYPE}\" tmp)\nif(\"${tmp}\" STREQUAL release)\n  set(BUILD_TYPE \"Release\")\n  set(ISDEBUG 0)\nelse()\n  set(BUILD_TYPE \"Debug\")\n  set(ISDEBUG 1)\nendif()\n\nfind_path(BITCODE_DIR NAMES \"opencl.bc\" \"opencl.amdgcn.bc\"\n  PATHS\n    \"${ROCM_DIR}/amdgcn/bitcode\"\n    \"${ROCM_DIR}/lib/bitcode\"\n    \"${ROCM_DIR}/lib\"\n    \"${ROCM_DIR}/lib/x86_64/bitcode\"\n    \"${OPENCL_DIR}/amdgcn/bitcode\"\n    \"${OPENCL_DIR}/lib/x86_64/bitcode\"\n    \"${LLVM_DIR}/../lib/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/amdgcn/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/lib/bitcode\"\n    \"${CMAKE_PREFIX_PATH}/lib/x86_64/bitcode\")\n\n#\n# Print out the build configuration being used:\n#\n#   Build Src directory\n#   Build Binary directory\n#   Build Type: Debug Vs Release, 32 Vs 64\n#   Compiler Version, etc\n#\nmessage(\"\")\nmessage(\"Build Configuration:\")\nmessage(\"-------------IS64BIT: \" ${IS64BIT})\nmessage(\"-----------BuildType: \" ${BUILD_TYPE})\nmessage(\"------------Compiler: \" ${CMAKE_CXX_COMPILER})\nmessage(\"-------------Version: \" ${CMAKE_CXX_COMPILER_VERSION})\nmessage(\"--------Proj Src Dir: \" ${PROJECT_SOURCE_DIR})\nmessage(\"--------Proj Bld Dir: \" ${PROJECT_BINARY_DIR})\nmessage(\"--------Proj Lib Dir: \" ${PROJECT_BINARY_DIR}/lib)\nmessage(\"--------Proj Exe Dir: \" ${PROJECT_BINARY_DIR}/bin)\nmessage(\"------Target Devices: ${TARGET_DEVICES}\")\nmessage(\"----------Clang path: \" ${CLANG})\nmessage(\"----------OpenCL Dir: \" ${OPENCL_DIR})\nmessage(\"-------OpenCL version \" ${OPENCL_VER})\nmessage(\"\")\n\nset(KERNELS_DIR ${PROJECT_SOURCE_DIR}/kernels)\n#\n# Set the build type based on user input\n#\nset(CMAKE_BUILD_TYPE ${BUILD_TYPE})\n#\n# Compiler pre-processor definitions.\n#\n# Define MACRO \"DEBUG\" if build type is \"Debug\"\nif(${BUILD_TYPE} STREQUAL \"Debug\")\nadd_definitions(-DDEBUG)\nendif()\n\nif(${EMULATOR_BUILD})\nadd_definitions(-DROCRTST_EMULATOR_BUILD=1)\nendif()\n\n\n#add_definitions(-D__linux__)\nadd_definitions(-DLITTLEENDIAN_CPU=1)\n\n#\n# Linux Compiler options\n#\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fexceptions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-rtti\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-math-errno\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-threadsafe-statics\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fmerge-all-constants\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fms-extensions\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall\")\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-unused\")\n# set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -pedantic\")\n\n#\n# Add compiler flags to include symbol information for debug builds\n#\nif(ISDEBUG)\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb -O0\")\nendif()\nMESSAGE(\"ISDEBUG STEP:Done\")\n\nset(ROCRTST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)\n\n# Set Name for Google Test Framework and build it as a\n# static library to be linked with user test programs\n#\nset(GOOGLE_TEST_FRWK_NAME \"google-test-frwk${ONLY64STR}\")\nadd_subdirectory(${ROCRTST_ROOT}/gtest \"${PROJECT_BINARY_DIR}/gtest\" EXCLUDE_FROM_ALL)\nset (ROCRTST_LIBS ${ROCRTST_LIBS} ${GOOGLE_TEST_FRWK_NAME})\n\nMESSAGE(\"ROCRTST_LIBS SET STEP:Done\")\n#\n#\n# Other source directories\naux_source_directory(${ROCRTST_ROOT}/common common_srcs)\n\n#\n# Extend the list of libraries to be used for linking ROC Perf Apps\n#\nset(ROCRTST_LIBS ${ROCRTST_LIBS} hsa-runtime64::hsa-runtime64)\nset(ROCRTST_LIBS ${ROCRTST_LIBS} amd_smi)\n\n\n# Set Name for rocrtst\nMESSAGE(${ROCRTST_LIBS})\nset(ROCRTST \"rocrtst${ONLY64STR}\")\n\n#\n# Source files for building rocrtst\n#\naux_source_directory(${ROCRTST_ROOT}/suites/performance performanceSources)\naux_source_directory(${ROCRTST_ROOT}/suites/functional functionalSources)\naux_source_directory(${ROCRTST_ROOT}/suites/negative negativeSources)\naux_source_directory(${ROCRTST_ROOT}/suites/stress stressSources)\naux_source_directory(${ROCRTST_ROOT}/suites/test_common testCommonSources)\n\n# Header file include path\n\ninclude_directories(${ROCRTST_ROOT})\ninclude_directories(${ROCRTST_ROOT}/gtest/include)\ninclude_directories(${ROCRTST_ROOT}/thirdparty/include/)\n\n# Custom command set for code objects.\nset (HSACO_TARG_LIST \"\")\n\n# Use this function to build any samples that have kernels to be built\nfunction(build_kernel S_NAME TARG_DEV)\n  set(KERNEL_DIR ${PROJECT_BINARY_DIR}/${TARG_DEV})\n  set(SNAME_KERNEL \"${S_NAME}_kernels.hsaco\")\n\n  set(TARG_NAME \"${S_NAME}_hsaco.${TARG_DEV}\")\n  set(HSACO_TARG_LIST ${HSACO_TARG_LIST} \"${KERNEL_DIR}/${SNAME_KERNEL}\" PARENT_SCOPE)\n  string(SUBSTRING ${TARG_DEV} 3 -1 gfxNum)\n  separate_arguments(CLANG_ARG_LIST UNIX_COMMAND\n   \"-D ROCRTST_GPU=0x${gfxNum} -x cl -target amdgcn-amd-amdhsa -include ${OPENCL_INC_DIR}/opencl-c.h -mcpu=${TARG_DEV} ${BITCODE_ARGS} -cl-std=CL${OPENCL_VER} -mcode-object-version=4 ${CL_FILE_LIST} -o ${KERNEL_DIR}/${SNAME_KERNEL}\")\n  add_custom_command(OUTPUT \"${KERNEL_DIR}/${SNAME_KERNEL}\" COMMAND ${CLANG} ${CLANG_ARG_LIST} DEPENDS ${CL_FILE_LIST} ${CLANG} COMMENT \"BUILDING ${KERNEL_DIR}/${SNAME_KERNEL}\" VERBATIM)\nendfunction(build_kernel)\n\nfunction(build_sample_for_devices S_NAME)\n  foreach(t ${TARGET_DEVICES})\n    build_kernel(${S_NAME} ${t})\n  endforeach(t)\n  set(HSACO_TARG_LIST ${HSACO_TARG_LIST} PARENT_SCOPE)\nendfunction(build_sample_for_devices)\n\n# Make directories for each possible target device\n# List of symlinks per directory\nset(ROCRTST_LINKS_LIST \"\")\nforeach(td ${TARGET_DEVICES})\n  file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/${td})\n  add_custom_command(OUTPUT \"${PROJECT_BINARY_DIR}/${td}/${ROCRTST}\" COMMAND ${CMAKE_COMMAND} -E create_symlink \"../${ROCRTST}\" \"${td}/${ROCRTST}\" COMMENT \"BUILDING ${td}/${ROCRTST}\" VERBATIM)\n  set(ROCRTST_LINKS_LIST ${ROCRTST_LINKS_LIST} \"${PROJECT_BINARY_DIR}/${td}/${ROCRTST}\")\n  install ( DIRECTORY ${PROJECT_BINARY_DIR}/${td} DESTINATION bin )\nendforeach(td)\n\n######################\n# Kernel Build Section\n######################\nset(KERN_SUFFIX \"kernels.hsaco\")\n\n# Check if device-libs bitcode is following old or new layout\nif(EXISTS \"${BITCODE_DIR}/opencl.amdgcn.bc\")\n  set(BITCODE_ARGS \"-nogpulib\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/opencl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ockl.amdgcn.bc\n    -Xclang -mlink-bitcode-file -Xclang ${BITCODE_DIR}/ocml.amdgcn.bc\")\nelse()\n  set(BITCODE_ARGS \"--hip-device-lib-path=${BITCODE_DIR}\")\nendif()\n\n# Test Case Template example\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/test_case_template_kernels.cl\")\nbuild_sample_for_devices(\"test_case_template\")\n\n# P2P Memory Access\n#set(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\n#set(CL_FILE_LIST \"${KERNELS_DIR}/p2p_mem_access_kernels.cl\")\n#build_sample_for_devices(\"p2p_mem_access\")\n\n# Dispatch Time\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/dispatch_time_kernels.cl\")\nbuild_sample_for_devices(\"dispatch_time\")\n\n# gpuReadWrite\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/gpuReadWrite_kernels.cl\")\nbuild_sample_for_devices(\"gpuReadWrite\")\n\n\n# Vector Add Debug Trap\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/vector_add_debug_trap_kernel.cl\")\nbuild_sample_for_devices(\"vector_add_debug_trap\")\n\n# Vector Add Memory Fault\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/vector_add_memory_fault_kernel.cl\")\nbuild_sample_for_devices(\"vector_add_memory_fault\")\n\n# atomic_add_kernels\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/atomicOperations_kernels.cl\")\nbuild_sample_for_devices(\"atomicOperations\")\n\n# Signal Operations\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/signal_operations.cl\")\nbuild_sample_for_devices(\"signal_operations\")\n\n# groupMemoryDynamic\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/groupMemoryDynamic_kernels.cl\")\nbuild_sample_for_devices(\"groupMemoryDynamic\")\n\n# groupMemoryDynamic\nset(BITCODE_LIBS \"${COMMON_BITCODE_LIBS}\")\nset(CL_FILE_LIST \"${KERNELS_DIR}/cu_mask_kernels.cl\")\nbuild_sample_for_devices(\"cu_mask\")\n\nset(CMAKE_BUILD_WITH_INSTALL_RPATH ON)\n\n# Build rules\nadd_executable(${ROCRTST} ${performanceSources} ${functionalSources} ${negativeSources} ${stressSources}\n                                           ${common_srcs} ${testCommonSources})\n\ntarget_link_libraries(${ROCRTST} ${ROCRTST_LIBS} c stdc++ dl pthread rt numa ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/lib/libhwloc.so.5)\n\n#Build kernels\nadd_custom_target(rocrtst_kernels ALL DEPENDS ${HSACO_TARG_LIST})\n\n#Build symlinks\nadd_custom_target(rocrtst_links ALL DEPENDS ${ROCRTST_LINKS_LIST} )\n\n## Set RUNPATH to pickup local copy of hwloc\nset_property(TARGET ${ROCRTST} PROPERTY INSTALL_RPATH \"$ORIGIN;$ORIGIN/thirdparty/lib;$ORIGIN/../lib/rocrtst/thirdparty/lib\" )\nset_property(TARGET ${ROCRTST} PROPERTY LINK_FLAGS \"-Wl,--enable-new-dtags\")\n\ninstall(TARGETS ${ROCRTST}\n        ARCHIVE DESTINATION lib\n        LIBRARY DESTINATION lib\n        RUNTIME DESTINATION bin)\n\ninstall ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/lib DESTINATION lib/rocrtst )\n\ninclude ( CPack )\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/atomicOperations_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n__kernel void test_atomic_add(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_add(&sysMemory[tid], value);\n    atomic_add(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_sub(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_sub(&sysMemory[tid], value);\n    atomic_sub(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_and(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_and(&sysMemory[tid], value);\n    atomic_and(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_or(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_or(&sysMemory[tid], value);\n    atomic_or(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_xor(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_xor(&sysMemory[tid], value);\n    atomic_xor(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_xchg(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_xchg(&sysMemory[tid], value);\n    atomic_xchg(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_inc(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_inc(&sysMemory[tid]);\n    atomic_inc(&sysMemory[tid]);\n    atomic_inc(&sysMemory[tid]);\n    atomic_inc(&sysMemory[tid]);\n\n    atomic_inc(&gpuMemory[tid]);\n    atomic_inc(&gpuMemory[tid]);\n    atomic_inc(&gpuMemory[tid]);\n    atomic_inc(&gpuMemory[tid]);\n}\n\n__kernel void test_atomic_dec(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_dec(&sysMemory[tid]);\n    atomic_dec(&sysMemory[tid]);\n    atomic_dec(&sysMemory[tid]);\n    atomic_dec(&sysMemory[tid]);\n\n    atomic_dec(&gpuMemory[tid]);\n    atomic_dec(&gpuMemory[tid]);\n    atomic_dec(&gpuMemory[tid]);\n    atomic_dec(&gpuMemory[tid]);\n}\n\n__kernel void test_atomic_max(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_max(&sysMemory[tid], value);\n    atomic_max(&gpuMemory[tid], value);\n}\n\n__kernel void test_atomic_min(volatile __global int *sysMemory,\n                              volatile __global int *gpuMemory,\n                             __global int *oldValues, int value) {\n    int  tid = get_global_id(0);\n    oldValues[tid] = atomic_min(&sysMemory[tid], value);\n    atomic_min(&gpuMemory[tid], value);\n}\n\n\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/cu_mask_kernels.cl",
    "content": "#define GETREG_IMMED(SIZE, OFFSET, REG) ((SIZE-1)<<11)|(OFFSET<<6)|REG\n\n#if ROCRTST_GPU < 0x1000\n  #define HW_ID_CU_ID_OFFSET 8\n  #define HW_ID 4\n  #if (ROCRTST_GPU == 0x908) || (ROCRTST_GPU == 0x90a) || (ROCRTST_GPU == 0x940)\n    #define HW_ID_CU_ID_SIZE 8\n  #else\n    #define HW_ID_CU_ID_SIZE 7\n  #endif\n#else\n  #define HW_ID_CU_ID_OFFSET 9 //Skips first bit of SIMD ID, could be wrong.\n  #define HW_ID 23\n  #define HW_ID_CU_ID_SIZE 10\n#endif\n\n__kernel void get_hw_id(__global uint* hw_ids) {\n  uint idx = get_global_id(0);\n  hw_ids[idx] = __builtin_amdgcn_s_getreg(GETREG_IMMED(HW_ID_CU_ID_SIZE, HW_ID_CU_ID_OFFSET, HW_ID));\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/dispatch_time_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n__kernel void\nempty_kernel(void) {\n  return;\n}\n \n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/gpuReadWrite_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n__kernel void gpuReadWrite(__global const int * a,\n                           __global int * b, __global int * c) {\n  int i = get_global_id(0);\n  // Reading the system memory and writing to gpu memory\n  c[i] = a[i];  // a[i] point to system memory while c[i] to gpu memory.\n  //writing to system memory\n  b[i] = i;\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/groupMemoryDynamic_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2018, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n\n__kernel void group_memory_dynamic(__global uint * in,\n                            __global uint * out,__local uint *grp_offset,__private uint count) {\n  __local uint grp[256];\n  __private int gid = get_global_id(0);\n  if( gid > count)\n    return;\n  grp_offset[gid] = in[gid];\n  out[gid] = grp_offset[gid];\n  return;\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/signal_operations.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n\n#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable\n\n__kernel void signal_st_rlx_kernel(__global void* dumy_signal)\n{\n \n int  tid = get_global_id(0);\n volatile __global long* p = (volatile __global long* )(dumy_signal);\n atom_xchg(p,0);\n}\n\n__kernel void signal_st_rlx_kernel_multi(__global void* dumy_signal)\n{\n \n int  tid = get_global_id(0);\n int offset = 8*tid; // handle is of long unsigned int, having size of 8bytes\n volatile __global long* p = (volatile __global long* )(dumy_signal+ offset);\n atom_xchg(p,0);\n}\n\n__kernel void signal_wait_kernel(__global void* dumy_signal)\n{\n \n int  tid = get_global_id(0);\n volatile __global long* p = (volatile __global long* )(dumy_signal);\n while(!(*p == 0)) {  } // Will be using the volatile type as we dont have atom_cmp() function from Khronos spec\n\n}\n\n__kernel void signal_wait_kernel_multi(__global void* dumy_signal)\n{\n \n int  tid = get_global_id(0);\n int offset = 8*tid; // handle is of long unsigned int, having size of 8bytes\n volatile __global long* p = (volatile __global long* )(dumy_signal + offset);\n while(!(*p == 0)) {  } // Will be using the volatile type as we dont have atom_cmp() function from Khronos spec\n\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/test_case_template_kernels.cl",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n __kernel void\nsquare(__global int *dstArray,  __global const int *srcArray, const int sz) {\n  unsigned int id = get_global_id(0);\n  if (id < sz) {\n     dstArray[id] = srcArray[id] * srcArray[id];\n  } \n  return;\n}\n \n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/vector_add_debug_trap_kernel.cl",
    "content": "__kernel void\nvector_add_debug_trap(__global int *a,\n                      __global int *b,\n                      __global int *c)\n{\n  int gid = get_global_id(0);\n  c[gid] = a[gid] + b[gid];\n  __builtin_trap();\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/kernels/vector_add_memory_fault_kernel.cl",
    "content": "static __global int ga[] = { 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35 };\n\n__kernel void\nvector_add_memory_fault(\n  __global const int *a,\n  __global const int *b,\n  __global const int *c,\n  __global int *d,\n  __global int *e)\n{\n    int gid = get_global_id(0);\n    d[gid*10] = ga[gid & 31];\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/main.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <string>\n#include <vector>\n#include <memory>\n\n#include \"gtest/gtest.h\"\n#include \"suites/functional/agent_props.h\"\n#include \"suites/functional/debug_basic.h\"\n#include \"suites/functional/memory_basic.h\"\n#include \"suites/functional/memory_access.h\"\n#include \"suites/functional/ipc.h\"\n#include \"suites/functional/memory_alignment.h\"\n#include \"suites/functional/memory_atomics.h\"\n#include \"suites/functional/memory_allocation.h\"\n#include \"suites/functional/deallocation_notifier.h\"\n#include \"suites/functional/virtual_memory.h\"\n#include \"suites/performance/dispatch_time.h\"\n#include \"suites/performance/memory_async_copy.h\"\n#include \"suites/performance/memory_async_copy_numa.h\"\n#include \"suites/performance/enqueueLatency.h\"\n#include \"suites/negative/memory_allocate_negative_tests.h\"\n#include \"suites/negative/queue_validation.h\"\n#include \"suites/stress/memory_concurrent_tests.h\"\n#include \"suites/stress/queue_write_index_concurrent_tests.h\"\n#include \"suites/test_common/test_case_template.h\"\n#include \"suites/test_common/main.h\"\n#include \"suites/test_common/test_common.h\"\n#include \"suites/functional/concurrent_init.h\"\n#include \"suites/functional/concurrent_init_shutdown.h\"\n#include \"suites/functional/concurrent_shutdown.h\"\n#include \"suites/functional/reference_count.h\"\n#include \"suites/functional/signal_concurrent.h\"\n#include \"suites/functional/aql_barrier_bit.h\"\n#include \"suites/functional/signal_kernel.h\"\n#include \"suites/functional/cu_masking.h\"\n#include \"amd_smi/amdsmi.h\"\n\nstatic RocrTstGlobals *sRocrtstGlvalues = nullptr;\n\nstatic void SetFlags(TestBase *test) {\n  assert(sRocrtstGlvalues != nullptr);\n\n  test->set_num_iteration(sRocrtstGlvalues->num_iterations);\n  test->set_verbosity(sRocrtstGlvalues->verbosity);\n  test->set_monitor_verbosity(sRocrtstGlvalues->monitor_verbosity);\n}\n\nstatic void RunCustomTestProlog(TestBase *test) {\n  SetFlags(test);\n\n  test->DisplayTestInfo();\n  test->SetUp();\n  test->Run();\n  return;\n}\nstatic void RunCustomTestEpilog(TestBase *test) {\n  test->DisplayResults();\n  test->Close();\n  return;\n}\n\n// If the test case one big test, you should use RunGenericTest()\n// to run the test case. OTOH, if the test case consists of multiple\n// functions to be run as separate tests, follow this pattern:\n//   * RunCustomTestProlog(test)  // Run() should contain minimal code\n//   * <insert call to actual test function within test case>\n//   * RunCustomTestEpilog(test)\nstatic void RunGenericTest(TestBase *test) {\n  RunCustomTestProlog(test);\n  RunCustomTestEpilog(test);\n  return;\n}\n\n// TEST ENTRY TEMPLATE:\n// TEST(rocrtst, Perf_<test name>) {\n//  <Test Implementation class> <test_obj>;\n//\n//  // Copy and modify implementation of RunGenericTest() if you need to deviate\n//  // from the standard pattern implemented there.\n//  RunGenericTest(&<test_obj>);\n// }\n\nTEST(rocrtst, Test_Example) {\n  TestExample tst;\n\n  RunGenericTest(&tst);\n}\n\nTEST(rocrtstFunc, MemoryAccessTests) {\n  MemoryAccessTest mt;\n  RunCustomTestProlog(&mt);\n  mt.CPUAccessToGPUMemoryTest();\n  mt.GPUAccessToCPUMemoryTest();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstFunc, GroupMemoryAllocationTest) {\n  MemoryAllocationTest ma(true, false);\n  RunCustomTestProlog(&ma);\n  ma.GroupMemoryDynamicAllocation();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, MemoryAllocateAndFreeTest) {\n  MemoryAllocationTest ma(false, true);\n  RunCustomTestProlog(&ma);\n  ma.MemoryBasicAllocationAndFree();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, MemoryAllocateContiguousTest) {\n  MemoryAllocationTest ma(false, true);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAllocateContiguousTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Concurrent_Init_Test) {\n  ConcurrentInitTest ci;\n  RunCustomTestProlog(&ci);\n  ci.TestConcurrentInit();\n  RunCustomTestEpilog(&ci);\n}\n\nTEST(rocrtstFunc, Concurrent_Init_Shutdown_Test) {\n  ConcurrentInitShutdownTest ci;\n  RunCustomTestProlog(&ci);\n  ci.TestConcurrentInitShutdown();\n  RunCustomTestEpilog(&ci);\n}\nTEST(rocrtstFunc, Concurrent_Shutdown) {\n  ConcurrentShutdownTest cs;\n  RunCustomTestProlog(&cs);\n  cs.TestConcurrentShutdown();\n  RunCustomTestEpilog(&cs);\n}\n\nTEST(rocrtstFunc, Reference_Count) {\n  ReferenceCountTest rc(true, false);\n  RunCustomTestProlog(&rc);\n  rc.TestReferenceCount();\n  RunCustomTestEpilog(&rc);\n}\n\nTEST(rocrtstFunc, Max_Reference_Count) {\n  ReferenceCountTest rc(false, true);\n  RunCustomTestProlog(&rc);\n  rc.TestMaxReferenceCount();\n  RunCustomTestEpilog(&rc);\n}\n\nTEST(rocrtstFunc, Signal_Destroy_Concurrently) {\n  SignalConcurrentTest sd(true, false, false, false);\n  RunCustomTestProlog(&sd);\n  sd.TestSignalDestroyConcurrent();\n  RunCustomTestEpilog(&sd);\n}\n\nTEST(rocrtstFunc, Signal_Max_Consumer) {\n  SignalConcurrentTest sd(false, true, false, false);\n  RunCustomTestProlog(&sd);\n  sd.TestSignalCreateMaxConsumers();\n  RunCustomTestEpilog(&sd);\n}\n\nTEST(rocrtstFunc, Signal_Create_Concurrently) {\n  SignalConcurrentTest sd(false, false, false, true);\n  RunCustomTestProlog(&sd);\n  sd.TestSignalCreateConcurrent();\n  RunCustomTestEpilog(&sd);\n}\n\n/* Temporary: Disable CU Masking until it is fixed */\nTEST(rocrtstFunc, DISABLED_CU_Masking) {\n  CU_Masking sd;\n  RunGenericTest(&sd);\n}\n\n#ifndef ROCRTST_EMULATOR_BUILD\nTEST(rocrtstFunc, IPC) {\n  IPCTest ipc;\n  RunGenericTest(&ipc);\n}\n\nTEST(rocrtstFunc, DISABLED_Signal_Kernel_Set) {\n  SignalKernelTest sk(SET);\n  RunCustomTestProlog(&sk);\n  sk.TestSignalKernelSet();\n  RunCustomTestEpilog(&sk);\n}\n\nTEST(rocrtstFunc, DISABLED_Signal_Kernel_Multi_Set) {\n  SignalKernelTest sk(MULTISET);\n  RunCustomTestProlog(&sk);\n  sk.TestSignalKernelMultiSet();\n  RunCustomTestEpilog(&sk);\n}\n\nTEST(rocrtstFunc, DISABLED_Signal_Kernel_Wait) {\n  SignalKernelTest sw(WAIT);\n  RunCustomTestProlog(&sw);\n  sw.TestSignalKernelWait();\n  RunCustomTestEpilog(&sw);\n}\n\nTEST(rocrtstFunc, DISABLED_Signal_Kernel_Multi_Wait) {\n  SignalKernelTest sw(MULTIWAIT);\n  RunCustomTestProlog(&sw);\n  sw.TestSignalKernelMultiWait();\n  RunCustomTestEpilog(&sw);\n}\n\nTEST(rocrtstFunc, DISABLED_Aql_Barrier_Bit_Set) {\n  AqlBarrierBitTest ab(true, false);\n  RunCustomTestProlog(&ab);\n  ab.BarrierBitSet();\n  RunCustomTestEpilog(&ab);\n}\n\nTEST(rocrtstFunc, DISABLED_Aql_Barrier_Bit_Not_Set) {\n  AqlBarrierBitTest ab(false, true);\n  RunCustomTestProlog(&ab);\n  ab.BarrierBitNotSet();\n  RunCustomTestEpilog(&ab);\n}\n\nTEST(rocrtstFunc, Memory_Max_Mem) {\n  MemoryTest mt;\n\n  RunCustomTestProlog(&mt);\n  mt.MaxSingleAllocationTest();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstFunc, Memory_Available) {\n  MemoryTest mt;\n\n  RunCustomTestProlog(&mt);\n  mt.MemAvailableTest();\n  RunCustomTestEpilog(&mt);\n}\n\n\nTEST(rocrtstFunc, Memory_Atomic_Add_Test) {\n  MemoryAtomic ma(ADD);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Sub_Test) {\n  MemoryAtomic ma(SUB);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_And_Test) {\n  MemoryAtomic ma(AND);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Or_Test) {\n  MemoryAtomic ma(OR);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Xor_Test) {\n  MemoryAtomic ma(XOR);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Min_Test) {\n  MemoryAtomic ma(MIN);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Max_Test) {\n  MemoryAtomic ma(MAX);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Inc_Test) {\n  MemoryAtomic ma(INC);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Dec_Test) {\n  MemoryAtomic ma(DEC);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Memory_Atomic_Xchg_Test) {\n  MemoryAtomic ma(XCHG);\n  RunCustomTestProlog(&ma);\n  ma.MemoryAtomicTest();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, DISABLED_DebugBasicTests) {\n  DebugBasicTest mt;\n  RunCustomTestProlog(&mt);\n  mt.VectorAddDebugTrapTest();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstFunc, Memory_Alignment_Test) {\n  MemoryAlignmentTest ma;\n  RunCustomTestProlog(&ma);\n  ma.MemoryPoolAlignment();\n  RunCustomTestEpilog(&ma);\n}\n\nTEST(rocrtstFunc, Deallocation_Notifier_Test) {\n  DeallocationNotifierTest notifier;\n  RunGenericTest(&notifier);\n}\n\nTEST(rocrtstFunc, AgentPropertiesTests) {\n  AgentPropTest propTest;\n  RunCustomTestProlog(&propTest);\n  propTest.QueryAgentUUID();\n  propTest.QueryAgentClockCounters();\n  RunCustomTestEpilog(&propTest);\n}\n\nTEST(rocrtstFunc, VirtMemory_Basic_Test) {\n  VirtMemoryTestBasic vmt;\n\n  RunCustomTestProlog(&vmt);\n  vmt.TestCreateDestroy();\n  vmt.TestRefCount();\n  vmt.TestPartialMapping();\n  RunCustomTestEpilog(&vmt);\n}\n\nTEST(rocrtstFunc, VirtMemory_Access_Test) {\n  VirtMemoryTestBasic vmt;\n\n  RunCustomTestProlog(&vmt);\n  vmt.CPUAccessToGPUMemoryTest();\n  vmt.GPUAccessToCPUMemoryTest();\n  vmt.GPUAccessToGPUMemoryTest();\n  RunCustomTestEpilog(&vmt);\n}\n\nTEST(rocrtstFunc, VirtMemory_Interprocess_Test) {\n  VirtMemoryTestInterProcess vmt;\n  RunCustomTestProlog(&vmt);\n  RunCustomTestEpilog(&vmt);\n}\n\nTEST(rocrtstNeg, Memory_Negative_Tests) {\n  MemoryAllocateNegativeTest mt;\n  RunCustomTestProlog(&mt);\n  mt.ZeroMemoryAllocateTest();\n  mt.MaxMemoryAllocateTest();\n\n  // Disabled temporarily - Renable this test only\n  // on recent GPUs - gfx94x+\n  // mt.FreeQueueRingBufferTest();\n\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstNeg, Queue_Validation_InvalidDimension) {\n  QueueValidation qv(true, false, false, false, false);\n  RunCustomTestProlog(&qv);\n  qv.QueueValidationForInvalidDimension();\n  RunCustomTestEpilog(&qv);\n}\n\nTEST(rocrtstNeg, Queue_Validation_InvalidGroupMemory) {\n  QueueValidation qv(false, true, false, false, false);\n  RunCustomTestProlog(&qv);\n  qv.QueueValidationInvalidGroupMemory();\n  RunCustomTestEpilog(&qv);\n}\n\nTEST(rocrtstNeg, Queue_Validation_InvalidKernelObject) {\n  QueueValidation qv(false, false, true, false, false);\n  RunCustomTestProlog(&qv);\n  qv.QueueValidationForInvalidKernelObject();\n  RunCustomTestEpilog(&qv);\n}\n\nTEST(rocrtstNeg, Queue_Validation_InvalidPacket) {\n  QueueValidation qv(false, false, false, true, false);\n  RunCustomTestProlog(&qv);\n  qv.QueueValidationForInvalidPacket();\n  RunCustomTestEpilog(&qv);\n}\n\nTEST(rocrtstNeg, DISABLED_Queue_Validation_InvalidWorkGroupSize) {\n  QueueValidation qv(false, false, false, false, true);\n  RunCustomTestProlog(&qv);\n  qv.QueueValidationForInvalidWorkGroupSize();\n  RunCustomTestEpilog(&qv);\n}\n\nTEST(rocrtstStress, Memory_Concurrent_Allocate_Test) {\n  MemoryConcurrentTest mt(true, false, false);\n  RunCustomTestProlog(&mt);\n  mt.MemoryConcurrentAllocate();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstStress, Memory_Concurrent_Free_Test) {\n  MemoryConcurrentTest mt(false, true, false);\n  RunCustomTestProlog(&mt);\n  mt.MemoryConcurrentFree();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstStress, Memory_Concurrent_Pool_Info_Test) {\n  MemoryConcurrentTest mt(false, false, true);\n  RunCustomTestProlog(&mt);\n  mt.MemoryConcurrentPoolGetInfo();\n  RunCustomTestEpilog(&mt);\n}\n\nTEST(rocrtstStress, Queue_Add_Write_Index_ConcurrentTest) {\n  QueueWriteIndexConcurrentTest Qw(true, false, false);\n  RunCustomTestProlog(&Qw);\n  Qw.QueueAddWriteIndexAtomic();\n  RunCustomTestEpilog(&Qw);\n}\n\nTEST(rocrtstStress, Queue_CAS_Write_Index_ConcurrentTest) {\n  QueueWriteIndexConcurrentTest Qw(false, true, false);\n  RunCustomTestProlog(&Qw);\n  Qw.QueueCasWriteIndexAtomic();\n  RunCustomTestEpilog(&Qw);\n}\n\nTEST(rocrtstStress, Queue_LoadStore_Write_Index_ConcurrentTest) {\n  QueueWriteIndexConcurrentTest Qw(false, false, true);\n  RunCustomTestProlog(&Qw);\n  Qw.QueueLoadStoreWriteIndexAtomic();\n  RunCustomTestEpilog(&Qw);\n}\n\nTEST(rocrtstPerf, Memory_Async_Copy) {\n  MemoryAsyncCopy mac;\n  // To do full test, uncomment this:\n  //  mac.set_full_test(true);\n  // To test only 1 path, add lines like this:\n  //  mac.set_src_pool(<src pool id>);\n  //  mac.set_dst_pool(<dst pool id>);\n  // The default is to and from the cpu to 1 gpu, and to/from a gpu to\n  // another gpu\n  RunGenericTest(&mac);\n}\n#endif  // ROCRTST_EMULATOR_BUILD\n\nTEST(rocrtstPerf, ENQUEUE_LATENCY) {\n  EnqueueLatency singlePacketequeue(true);\n  EnqueueLatency multiPacketequeue(false);\n  RunGenericTest(&singlePacketequeue);\n  RunGenericTest(&multiPacketequeue);\n}\n\nTEST(rocrtstPerf, DISABLED_Memory_Async_Copy_NUMA) {\n  MemoryAsyncCopyNUMA numa;\n  RunGenericTest(&numa);\n}\n\nTEST(rocrtstPerf, AQL_Dispatch_Time_Single_SpinWait) {\n  DispatchTime dt(true, true);\n  RunGenericTest(&dt);\n}\n\nTEST(rocrtstPerf, AQL_Dispatch_Time_Single_Interrupt) {\n  DispatchTime dt(false, true);\n  RunGenericTest(&dt);\n}\n\nTEST(rocrtstPerf, AQL_Dispatch_Time_Multi_SpinWait) {\n  DispatchTime dt(true, false);\n  RunGenericTest(&dt);\n}\n\nTEST(rocrtstPerf, AQL_Dispatch_Time_Multi_Interrupt) {\n  DispatchTime dt(false, false);\n  RunGenericTest(&dt);\n}\n\nint main(int argc, char** argv) {\n  ::testing::InitGoogleTest(&argc, argv);\n\n  #ifdef ROCRTST_EMULATOR_BUILD\n  std::cout << \"--- Emulation build ---\" << std::endl;\n  #endif\n\n  RocrTstGlobals settings;\n\n  // Set some default values\n  settings.verbosity = 1;\n  settings.monitor_verbosity = 0;\n  settings.num_iterations = 5;\n\n  if (ProcessCmdline(&settings, argc, argv)) {\n    return 1;\n  }\n  sRocrtstGlvalues = &settings;\n\n  if (settings.monitor_verbosity > 0) {\n    amdsmi_status_t amdsmi_ret = amdsmi_init(AMDSMI_INIT_AMD_GPUS);\n    if (amdsmi_ret != AMDSMI_STATUS_SUCCESS) {\n      std::cout << \"Failed to initialize AMD smi\" << std::endl;\n      return 1;\n    }\n    DumpMonitorInfo();\n  }\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/main.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_TEST_COMMON_MAIN_H_\n#define ROCRTST_SUITES_TEST_COMMON_MAIN_H_\n\n#endif  // ROCRTST_SUITES_TEST_COMMON_MAIN_H_\n\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_base.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <assert.h>\n\n#include \"suites/test_common/test_base.h\"\n#include \"suites/test_common/test_common.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"gtest/gtest.h\"\n\nstatic const int kOutputLineLength = 80;\nstatic const char kLabelDelimiter[] = \"####\";\nstatic const char kDescriptionLabel[] = \"TEST DESCRIPTION\";\nstatic const char kTitleLabel[] = \"TEST NAME\";\nstatic const char kSetupLabel[] = \"TEST SETUP\";\nstatic const char kRunLabel[] = \"TEST EXECUTION\";\nstatic const char kCloseLabel[] = \"TEST CLEAN UP\";\nstatic const char kResultsLabel[] = \"TEST RESULTS\";\n\n\nTestBase::TestBase() : description_(\"\") {\n}\nTestBase::~TestBase() {\n}\n\nstatic void MakeHeaderStr(const char *inStr, std::string *outStr) {\n  assert(outStr != nullptr);\n  assert(inStr != nullptr);\n\n  outStr->clear();\n  *outStr = kLabelDelimiter;\n  *outStr += \" \";\n  *outStr += inStr;\n  *outStr += \" \";\n  *outStr += kLabelDelimiter;\n}\n\nvoid TestBase::SetupPrint() {\n  std::string label;\n  MakeHeaderStr(kSetupLabel, &label);\n  printf(\"\\n\\t%s\\n\", label.c_str());\n}\n\nvoid TestBase::SetUp(void) {\n  hsa_status_t err;\n  SetupPrint();\n  err = rocrtst::InitAndSetupHSA(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  return;\n}\n\nvoid TestBase::Run(void) {\n  std::string label;\n  MakeHeaderStr(kRunLabel, &label);\n  printf(\"\\n\\t%s\\n\", label.c_str());\n}\n\nvoid TestBase::ClosePrint() {\n  std::string label;\n  MakeHeaderStr(kCloseLabel, &label);\n  printf(\"\\n\\t%s\\n\", label.c_str());\n}\n\nvoid TestBase::Close(void) {\n  hsa_status_t err;\n  ClosePrint();\n  if (monitor_verbosity() > 0) {\n    DumpMonitorInfo();\n  }\n\n  err = rocrtst::CommonCleanUp(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n}\n\n\nvoid TestBase::DisplayResults(void) const {\n  std::string label;\n  MakeHeaderStr(kResultsLabel, &label);\n  printf(\"\\n\\t%s\\n\", label.c_str());\n}\n\nvoid TestBase::DisplayTestInfo(void) {\n  printf(\"#########################################\"\n                                  \"######################################\\n\");\n\n  std::string label;\n  MakeHeaderStr(kTitleLabel, &label);\n  printf(\"\\n\\t%s\\n%s\\n\", label.c_str(), title().c_str());\n\n  if (verbosity() >= VERBOSE_STANDARD) {\n    MakeHeaderStr(kDescriptionLabel, &label);\n    printf(\"\\n\\t%s\\n%s\\n\", label.c_str(), description().c_str());\n  }\n}\n\nvoid TestBase::set_description(std::string d) {\n  int le = kOutputLineLength - 4;\n\n  description_ = d;\n  size_t endlptr;\n\n  for (size_t i = le; i < description_.size(); i += le) {\n    endlptr = description_.find_last_of(\" \", i);\n    description_.replace(endlptr, 1, \"\\n\");\n    i = endlptr;\n  }\n}\n\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_base.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n#ifndef ROCRTST_SUITES_TEST_COMMON_TEST_BASE_H_\n#define ROCRTST_SUITES_TEST_COMMON_TEST_BASE_H_\n\n#include <string>\n#include <memory>\n#include <vector>\n\n#include \"common/base_rocr.h\"\n\nclass TestBase : public rocrtst::BaseRocR {\n public:\n  TestBase(void);\n\n  virtual ~TestBase(void);\n\n  enum VerboseLevel {VERBOSE_MIN = 0, VERBOSE_STANDARD, VERBOSE_PROGRESS};\n\n  // @Brief: Before run the core measure codes, do something to set up\n  // i.e. init runtime, prepare packet...\n  virtual void SetUp(void);\n\n  // @Brief: Core measurement codes executing here\n  virtual void Run(void);\n\n  // @Brief: Do something clean up\n  virtual void Close(void);\n\n  // @Brief: Display the results\n  virtual void DisplayResults(void) const;\n\n  // @Brief: Display information about the test\n  virtual void DisplayTestInfo(void);\n\n  const std::string & description(void) const {return description_;}\n\n  void set_description(std::string d);\n\n  // @Brief: Emit setup output string only.  For tests with custom setup.\n  void SetupPrint(void);\n\n  // @Brief: Emit close output string only.  For tests with custom close.\n  void ClosePrint(void);\n\n private:\n  std::string description_;\n};\n\n#endif  // ROCRTST_SUITES_TEST_COMMON_TEST_BASE_H_\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_case_template.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n// The purpose of this test is to provide an example of the use of the\n// common RocrTest classes and utilities that are used in many examples.\n// It can be used as a template to start off with when writing new tests.\n// In many cases, the existing boilerplate code will be sufficient as is.\n// Otherwise, the boilerplate code can be either supplemented or replaced\n// by your own code in your example, as necessary.\n//\n// The comments provided are focused more on the use of the common rocrtst\n// utilities and boilerplate code, rather than the example app. itself.\n//\n// The boilerplate code includes code for:\n// * hsa initialization and clean up\n// * code to load pre-built kernels\n// * creating queues\n// * populating AQL packets\n// * checking for required profiles\n// * finding cpu and gpu agents (callbacks for common use cases)\n// * finding pools (having common requirements)\n// * allocating and setting kernel arguments\n// * somewhat standardized output\n// * handling additional command line arguments, beyond google-test arguments\n// * support for various level of verbosity, controlled from command line arg\n// * support for building OpenCL kernels\n// * timer support\n//\n// Overview of RocrTst code organization:\n// Classes:\n// * class BaseRocR (base_rocr.h) -- base class for all rocrtst examples and\n//   tests. Most of the rocrtst common utilities act on BaseRocR objects\n//\n// * TestBase (test_base.h)  -- derives from BaseRocR and is the base class\n//   for all tests under <rocrtst root>/suites. The implementation in TestBase\n//   methods are typically actions that are required for most/all tests and\n//   should therefore be called from the derived implementions of the methods.\n//\n// Utilities:\n// * <rocrtst root>/common/base_rocr_utils.<cc/h> contains a set of utilities\n//   that act on BaseRocR objects.\n//\n// * <rocrtst root>/common/common.<cc/h> contain other non-BaseRocR utilities\n//\n// Special Files:\n// * main.cc -- The main google test file from which the tests are invoked.\n//     There should be an entry for each test to be run there.\n//\n// * kernels -- OpenCL kernel source files should go in the kernels directory\n//\n// * CMakeLists.txt -- Host code (*.cc and *.h files) should build without\n//     modifying the CMakeList.txt file, if the files are place in the\n//     \"performance\" directory. However, an entry for OpenCL kernels. For\n//     each kernel to be built, the bitcode libraries must be indicated before\n//     the call to \"build_kernel()\" is made. See existing code for examples.\n\n#include <algorithm>\n#include <iostream>\n#include <vector>\n\n#include \"suites/test_common/test_case_template.h\"\n#include \"common/base_rocr_utils.h\"\n#include \"common/common.h\"\n#include \"common/helper_funcs.h\"\n#include \"common/hsatimer.h\"\n#include \"gtest/gtest.h\"\n#include \"hsa/hsa.h\"\n\n#ifdef ROCRTST_EMULATOR_BUILD\nstatic const uint32_t kNumBufferElements = 4;\n#else\nstatic const uint32_t kNumBufferElements = 256;\n#endif\n\n#define RET_IF_HSA_ERR(err) { \\\n  if ((err) != HSA_STATUS_SUCCESS) { \\\n    const char* msg = 0; \\\n    hsa_status_string(err, &msg); \\\n    std::cout << \"hsa api call failure at line \" << __LINE__ << \", file: \" << \\\n                          __FILE__ << \". Call returned \" << err << std::endl; \\\n    std::cout << msg << std::endl; \\\n    return (err); \\\n  } \\\n}\n\n// Many test cases want to perform an operation on memory sizes of various\n// granularities.\n#if 0\nstatic const int kNumGranularity = 20;\nconst char* Str[kNumGranularity] = {\"1k\", \"2K\", \"4K\", \"8K\", \"16K\", \"32K\",\n    \"64K\", \"128K\", \"256K\", \"512K\", \"1M\", \"2M\", \"4M\", \"8M\", \"16M\", \"32M\",\n                                               \"64M\", \"128M\", \"256M\", \"512M\"};\n\nconst size_t Size[kNumGranularity] = {\n    1024, 2*1024, 4*1024, 8*1024, 16*1024, 32*1024, 64*1024, 128*1024,\n    256*1024, 512*1024, 1024*1024, 2048*1024, 4096*1024, 8*1024*1024,\n    16*1024*1024, 32*1024*1024, 64*1024*1024, 128*1024*1024, 256*1024*1024,\n    512*1024*1024};\n\nstatic const int kMaxCopySize = Size[kNumGranularity - 1];\n#endif\nTestExample::TestExample(void) :\n    TestBase() {\n  set_num_iteration(10);  // Number of iterations to execute of the main test;\n                          // This is a default value which can be overridden\n                          // on the command line.\n  set_title(\"Test Case Example\");\n  set_description(\"Put a description of the test case here. Line breaks \"\n      \"will be taken care of on output, not here.\");\n\n  set_kernel_file_name(\"test_case_template_kernels.hsaco\");\n  set_kernel_name(\"square\");  // kernel function name\n\n#if 0\n  // Set required profile to HSA_PROFILE_FULL or HSA_PROFILE_BASE if it\n  // matters for this test. If either profile is fine, then leave with\n  // default\n  set_requires_profile(<value>);\n#endif\n}\n\nTestExample::~TestExample(void) {\n}\n\n// Any 1-time setup involving member variables used in the rest of the test\n// should be done here.\nvoid TestExample::SetUp(void) {\n  hsa_status_t err;\n\n  // TestBase::SetUp() will set HSA_ENABLE_INTERRUPT if enable_interrupt() is\n  // true, and call hsa_init(). It also prints the SetUp header.\n  TestBase::SetUp();\n\n  // SetDefaultAgents(this) will assign the first CPU and GPU found on\n  // iterating through the agents and assign them to cpu_device_ and\n  // gpu_device1_, respectively (cpu_device() and gpu_device1()). These\n  // BaseRocR member variables are used in some utilities. Additionally,\n  // SetDefaultAgents() checks the profile of the gpu and compares this\n  // to any required profile.\n  //\n  // If SetDefaultAgents() is not used, if the profile of the target GPU\n  // matters for this test, it should be set with set_profile() and\n  // CheckProfileAndInform() should be called to check if it is the\n  // required profile\n  err = rocrtst::SetDefaultAgents(this);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  hsa_agent_t* gpu_dev = gpu_device1();\n\n  // Find and assign HSA_AMD_SEGMENT_GLOBAL pools for cpu, gpu and a kern_arg\n  // pool\n  err = rocrtst::SetPoolsTypical(this);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Create a queue\n  hsa_queue_t* q = nullptr;\n  rocrtst::CreateQueue(*gpu_dev, &q);\n  ASSERT_NE(q, nullptr);\n  set_main_queue(q);\n\n  err = rocrtst::LoadKernelFromObjFile(this, gpu_dev);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Fill up the kernel packet (except header) with some values we've\n  // collected so far, and some reasonable default values; this should be after\n  // LoadKernelFromObjFile(). AllocAndSetKernArgs() will fill in the kern_args\n  err = rocrtst::InitializeAQLPacket(this, &aql());\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  hsa_agent_t ag_list[2] = {*gpu_device1(), *cpu_device()};\n\n  // Allocate a few buffers for our example\n  err = hsa_amd_memory_pool_allocate(cpu_pool(),\n                                   kNumBufferElements*sizeof(uint32_t),\n                                   0, reinterpret_cast<void**>(&src_buffer_));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, src_buffer_);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Initialize the source buffer\n  for (uint32_t i = 0; i < kNumBufferElements; ++i) {\n    reinterpret_cast<uint32_t *>(src_buffer_)[i] = i;\n  }\n\n  err = hsa_amd_memory_pool_allocate(cpu_pool(),\n                                   kNumBufferElements*sizeof(uint32_t),\n                                   0, reinterpret_cast<void**>(&dst_buffer_));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  err = hsa_amd_agents_allow_access(2, ag_list, NULL, dst_buffer_);\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  // Set up Kernel arguments\n  // See the meta-data for the compiled OpenCL kernel code to ascertain\n  // the sizes, padding and alignment required for kernel arguments.\n  // This can be seen by executing\n  // $ amdgcn-amd-amdhsa-readelf -aw ./binary_search_kernels.hsaco\n  // The kernel code will expect the following arguments aligned as shown.\n//  typedef uint32_t uint4[4];\n  struct __attribute__((aligned(16))) local_args_t {\n    uint32_t* dstArray;\n    uint32_t* srcArray;\n    uint32_t size;\n    uint32_t pad;\n    uint64_t global_offset_x;\n    uint64_t global_offset_y;\n    uint64_t global_offset_z;\n    uint64_t printf_buffer;\n    uint64_t default_queue;\n    uint64_t completion_action;\n  } local_args;\n\n  local_args.dstArray = reinterpret_cast<uint32_t *>(dst_buffer_);\n  local_args.srcArray = reinterpret_cast<uint32_t *>(src_buffer_);\n  local_args.size = kNumBufferElements;\n  local_args.global_offset_x = 0;\n  local_args.global_offset_y = 0;\n  local_args.global_offset_z = 0;\n  local_args.printf_buffer = 0;\n  local_args.default_queue = 0;\n  local_args.completion_action = 0;\n\n  err = rocrtst::AllocAndSetKernArgs(this, &local_args, sizeof(local_args));\n  ASSERT_EQ(err, HSA_STATUS_SUCCESS);\n\n  return;\n}\n\n// This wrapper atomically writes the provided header and setup to the\n// provided AQL packet. The provided AQL packet address should be in the\n// queue memory space.\nstatic inline void AtomicSetPacketHeader(uint16_t header, uint16_t setup,\n                                  hsa_kernel_dispatch_packet_t* queue_packet) {\n  __atomic_store_n(reinterpret_cast<uint32_t*>(queue_packet),\n                   header | (setup << 16), __ATOMIC_RELEASE);\n}\n\n// Do a few extra iterations as we toss out some of the inital and final\n// iterations when calculating statistics\nuint32_t TestExample::RealIterationNum(void) {\n  return num_iteration() * 1.2 + 1;\n}\n\nstatic bool VerifyResult(uint32_t *ar, size_t sz) {\n  for (size_t i = 0; i < sz; ++i) {\n    if (i*i != ar[i]) {\n      return false;\n    }\n  }\n  return true;\n}\nvoid TestExample::Run(void) {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::Run();\n\n  // Override whatever we need to...\n  aql().workgroup_size_x = kNumBufferElements;\n  aql().grid_size_x = kNumBufferElements;\n\n  std::vector<double> timer;\n\n  int it = RealIterationNum();\n  hsa_kernel_dispatch_packet_t *queue_aql_packet;\n\n  rocrtst::PerfTimer p_timer;\n  uint64_t index;\n\n  for (int i = 0; i < it; i++) {\n    // This function simply copies the data we've collected so far into our\n    // local AQL packet, except the the setup and header fields.\n    queue_aql_packet = WriteAQLToQueue(this, &index);\n    ASSERT_EQ(queue_aql_packet,\n              reinterpret_cast<hsa_kernel_dispatch_packet_t *>\n                                      (main_queue()->base_address) + index);\n    uint32_t aql_header = HSA_PACKET_TYPE_KERNEL_DISPATCH;\n\n    aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                  HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n    aql_header |= HSA_FENCE_SCOPE_SYSTEM <<\n                  HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\n    // Create and start a timer for this iteration\n    int id = p_timer.CreateTimer();\n    p_timer.StartTimer(id);\n\n    ::AtomicSetPacketHeader(aql_header, aql().setup, queue_aql_packet);\n\n    hsa_signal_store_screlease(main_queue()->doorbell_signal, index);\n\n    // Wait on the dispatch signal until the kernel is finished.\n    while (hsa_signal_wait_scacquire(aql().completion_signal,\n         HSA_SIGNAL_CONDITION_LT, 1, (uint64_t) - 1, HSA_WAIT_STATE_ACTIVE)) {\n    }\n\n    // Stop the timer\n    p_timer.StopTimer(id);\n\n    // Store time for later analysis\n    timer.push_back(p_timer.ReadTimer(id));\n    hsa_signal_store_screlease(aql().completion_signal, 1);\n\n    ASSERT_TRUE(VerifyResult(reinterpret_cast<uint32_t *>(dst_buffer_),\n                                                         kNumBufferElements));\n\n    // Pay attention to verbosity level for things like progress output\n    if (verbosity() >= VERBOSE_PROGRESS) {\n      std::cout << \".\";\n      fflush(stdout);\n    }\n  }\n\n  if (verbosity() >= VERBOSE_PROGRESS) {\n    std::cout << std::endl;\n  }\n\n  // Abandon the first result and after sort, delete the last 2% value\n  timer.erase(timer.begin());\n  std::sort(timer.begin(), timer.end());\n  timer.erase(timer.begin() + num_iteration(), timer.end());\n\n  time_mean_ = rocrtst::CalcMean(timer);\n}\n\nvoid TestExample::DisplayTestInfo(void) {\n  TestBase::DisplayTestInfo();\n}\n\nvoid TestExample::DisplayResults(void) const {\n  // Compare required profile for this test case with what we're actually\n  // running on\n  if (!rocrtst::CheckProfile(this)) {\n    return;\n  }\n\n  TestBase::DisplayResults();\n  std::cout << \"The average time was: \" << time_mean_ * 1e6 <<\n                                                           \" uS\" << std::endl;\n  return;\n}\n\nvoid TestExample::Close() {\n  hsa_status_t err;\n\n  err = hsa_amd_memory_pool_free(src_buffer_);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  err = hsa_amd_memory_pool_free(dst_buffer_);\n  ASSERT_EQ(HSA_STATUS_SUCCESS, err);\n\n  // This will close handles opened within rocrtst utility calls and call\n  // hsa_shut_down(), so it should be done after other hsa cleanup\n  TestBase::Close();\n}\n\n\n#undef RET_IF_HSA_ERR\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_case_template.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_TEST_COMMON_TEST_CASE_TEMPLATE_H_\n#define ROCRTST_SUITES_TEST_COMMON_TEST_CASE_TEMPLATE_H_\n\n#include \"common/base_rocr.h\"\n#include \"hsa/hsa.h\"\n#include \"suites/test_common/test_base.h\"\n\nclass TestExample : public TestBase {\n public:\n  TestExample();\n\n  // @Brief: Destructor for test case of TestExample\n  virtual ~TestExample();\n\n  // @Brief: Setup the environment for measurement\n  virtual void SetUp();\n\n  // @Brief: Core measurement execution\n  virtual void Run();\n\n  // @Brief: Clean up and retrive the resource\n  virtual void Close();\n\n  // @Brief: Display  results\n  virtual void DisplayResults() const;\n\n  // @Brief: Display information about what this test does\n  virtual void DisplayTestInfo(void);\n\n private:\n  uint32_t RealIterationNum(void);\n\n  double time_mean_;\n  void *src_buffer_;\n  void *dst_buffer_;\n};\n\n#endif  // ROCRTST_SUITES_TEST_COMMON_TEST_CASE_TEMPLATE_H_\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_common.cc",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#include <assert.h>\n#include <stdint.h>\n#include <getopt.h>\n\n#include <iostream>\n#include <string>\n#include <sstream>\n\n#include \"suites/test_common/test_base.h\"\n#include \"suites/test_common/test_common.h\"\n#include \"amd_smi/amdsmi.h\"\n\nstatic const struct option long_options[] = {\n  {\"iterations\", required_argument, nullptr, 'i'},\n  {\"verbose\", required_argument, nullptr, 'v'},\n  {\"monitor_verbose\", required_argument, nullptr, 'm'},\n\n  {nullptr, 0, nullptr, 0}\n};\nstatic const char* short_options = \"i:v:m:r\";\n\nstatic void PrintHelp(void) {\n  std::cout <<\n     \"Optional RocRTst Arguments:\\n\"\n     \"--iterations, -i <number of iterations to execute>; override default, \"\n         \"which varies for each test\\n\"\n     \"--rocrtst_help, -r print this help message\\n\"\n     \"--verbosity, -v <verbosity level>\\n\"\n     \"  Verbosity levels:\\n\"\n     \"   0    -- minimal; just summary information\\n\"\n     \"   1    -- intermediate; show intermediate values such as intermediate \"\n                  \"perf. data\\n\"\n     \"   2    -- progress; show progress displays\\n\"\n     \"   >= 3 -- more debug output\\n\"\n     \"--monitor_verbosity, -m <monitor verbosity level>\\n\"\n     \"  Monitor Verbosity levels:\\n\"\n     \"   0    -- don't read or print out any GPU monitor information;\\n\"\n     \"   1    -- print out all available monitor information before the first \"\n                 \"test and after each test\\n\"\n     \"   >= 2 -- print out even more monitor information (test specific)\\n\";\n}\n\nuint32_t ProcessCmdline(RocrTstGlobals* test, int arg_cnt, char** arg_list) {\n  int a;\n  int ind = -1;\n\n  assert(test != nullptr);\n\n  while (true) {\n    a = getopt_long(arg_cnt, arg_list, short_options, long_options, &ind);\n\n    if (a == -1) {\n      break;\n    }\n\n    switch (a) {\n      case 'i':\n        test->num_iterations = std::stoi(optarg);\n        break;\n\n      case 'v':\n        test->verbosity = std::stoi(optarg);\n        break;\n\n      case 'm':\n        test->monitor_verbosity = std::stoi(optarg);\n        break;\n\n      case 'r':\n        PrintHelp();\n        return 1;\n\n      default:\n        PrintHelp();\n        return 1;\n    }\n  }\n  return 0;\n}\n\ntemplate<typename T>\nstatic std::string IntegerToString(T intVal, bool hex = true) {\n  std::stringstream stream;\n\n  if (hex) {\n    stream << \"0x\" << std::hex << intVal;\n  } else {\n    stream << std::dec << intVal;\n  }\n  return stream.str();\n}\n\nint DumpMonitorInfo() {\n  int ret = 0;\n  uint64_t value_u64;\n  uint16_t value_u16;\n  uint32_t value_u32;\n  int64_t value_i64;\n  std::string val_str;\n  std::vector<std::string> val_vec;\n  amdsmi_status_t amdsmi_ret;\n  int dump_ret = 0;\n\n  auto print_attr_label =\n      [&](std::string attrib) -> bool {\n          std::cout << \"\\t** \" << attrib;\n          if (ret == -1) {\n            std::cout << \"not available\" << std::endl;\n            return false;\n          }\n          return true;\n  };\n\n  auto delim = \"\\t***********************************\";\n\n  std::cout << \"\\t***** Hardware monitor values *****\" << std::endl;\n  std::cout << delim << std::endl;\n  std::cout.setf(std::ios::dec, std::ios::basefield);\n\n  // Get socket handles\n  uint32_t socket_count = AMDSMI_MAX_DEVICES;\n  amdsmi_socket_handle socket_handles[AMDSMI_MAX_DEVICES];\n  amdsmi_ret = amdsmi_get_socket_handles(&socket_count, socket_handles);\n  if (amdsmi_ret != AMDSMI_STATUS_SUCCESS) {\n      std::cout << \"Failed to get socket count. Error: \" << \n                                                      amdsmi_ret << std::endl;\n      amdsmi_shut_down();\n      return 1;\n  }\n\n  uint32_t socket_processors = AMDSMI_MAX_DEVICES;\n  uint32_t total_num_processors = 0;\n\n  amdsmi_processor_handle processor_handles[AMDSMI_MAX_DEVICES];\n  amdsmi_processor_handle socket_processor_handles[AMDSMI_MAX_DEVICES];\n\n  // Collect devices from sockets\n  for (uint32_t socket_idx = 0; socket_idx < socket_count; ++socket_idx) {\n    amdsmi_ret = amdsmi_get_processor_handles(socket_handles[socket_idx], \n      &socket_processors, socket_processor_handles);\n    if (amdsmi_ret != AMDSMI_STATUS_SUCCESS) {\n        std::cout << \"amdsmi_get_processor_handles() for socket \" << \n                        socket_idx << \" returned \" << amdsmi_ret << std::endl;\n        amdsmi_shut_down();\n        return 1;\n    }\n\n    for (uint32_t i = 0; i < socket_processors && \n                        total_num_processors + i < AMDSMI_MAX_DEVICES; ++i) {\n      processor_handles[total_num_processors + i] = socket_processor_handles[i];\n    }\n    total_num_processors += socket_processors;\n  }\n\n  // Filter for GPU processors\n  uint32_t gpu_count = 0;\n  for (uint32_t i = 0; i < total_num_processors; ++i) {\n      processor_type_t processor_type;\n      amdsmi_ret = amdsmi_get_processor_type(processor_handles[i], \n                                                              &processor_type);\n      if (amdsmi_ret == AMDSMI_STATUS_SUCCESS && \n                              processor_type == AMDSMI_PROCESSOR_TYPE_AMD_GPU) {\n          gpu_count++;\n      }\n  }\n\n  for (uint32_t dindx = 0; dindx < gpu_count; ++dindx) {\n    auto print_frequencies = [&](amdsmi_frequencies_t *freqs, \n                                                            std::string label) {\n      if (amdsmi_ret != AMDSMI_STATUS_SUCCESS) {\n        std::cout << \"get frequency call  returned \" << amdsmi_ret << std::endl;\n        dump_ret = 1;\n        return;\n      }\n\n      if (print_attr_label(label)) {\n        for (uint32_t i = 0; i < freqs->num_supported; ++i) {\n          std::cout << \"\\t**  \" << i << \": \" <<\n                                         freqs->frequency[i]/1000000 << \"Mhz\";\n          if (i == freqs->current) {\n            std::cout << \" *\";\n          }\n\n          std::cout << std::endl;\n        }\n      }\n    };\n    auto print_val_str = [&](std::string val, std::string label) {\n      std::cout << \"\\t** \" << label;\n      if (ret != AMDSMI_STATUS_SUCCESS) {\n        std::cout << \"not available; amdsmi call returned\" << amdsmi_ret;\n        dump_ret = 1;\n      } else {\n        std::cout << val;\n      }\n      std::cout << std:: endl;\n    };\n\n    amdsmi_ret = amdsmi_get_gpu_id(processor_handles[dindx], &value_u16);\n    print_val_str(IntegerToString(value_u16), \"Device ID: \");\n\n    amdsmi_dev_perf_level_t perf;\n    std::string perf_str;\n    amdsmi_ret = amdsmi_get_gpu_perf_level(processor_handles[dindx], &perf);\n    switch (perf) {\n      case AMDSMI_DEV_PERF_LEVEL_AUTO:\n        perf_str = \"auto\";\n        break;\n      default:\n        perf_str = \"unknown\";\n    }\n    print_val_str(perf_str, \"Performance Level: \");\n\n    uint32_t overdrive_level;\n    amdsmi_ret = amdsmi_get_gpu_overdrive_level(processor_handles[dindx], \n                                                            &overdrive_level);\n\n    print_val_str(IntegerToString(value_u32, false) + \"%\", \"OverDrive Level: \");\n\n    amdsmi_frequencies_t freqs;\n    amdsmi_ret = amdsmi_get_clk_freq(processor_handles[dindx], \n                                                AMDSMI_CLK_TYPE_SYS, &freqs);\n\n    print_frequencies(&freqs, \"Supported GPU clock frequencies:\\n\");\n\n    amdsmi_ret = amdsmi_get_clk_freq(processor_handles[dindx], \n                                                AMDSMI_CLK_TYPE_MEM, &freqs);\n    print_frequencies(&freqs, \"Supported GPU Memory clock frequencies:\\n\");\n\n    amdsmi_board_info_t board_info;\n    amdsmi_get_gpu_board_info(processor_handles[dindx], &board_info);\n    print_val_str(board_info.product_name, \"Monitor name: \");\n    \n    amdsmi_ret = amdsmi_get_temp_metric(processor_handles[dindx], \n                AMDSMI_TEMPERATURE_TYPE_EDGE, AMDSMI_TEMP_CURRENT, &value_i64);\n    print_val_str(IntegerToString(value_i64/1000, false) + \"C\",\n                                                            \"Temperature: \");\n\n    amdsmi_ret = amdsmi_get_gpu_fan_speed(processor_handles[dindx], \n                                                                0, &value_i64);\n    if (ret != AMDSMI_STATUS_SUCCESS) {\n        std::cout << \"not available; amdsmi call returned\" << amdsmi_ret;\n        dump_ret = 1;\n    }\n    amdsmi_ret = amdsmi_get_gpu_fan_speed_max(processor_handles[dindx], \n                                                                0, &value_u64);\n    if (ret != AMDSMI_STATUS_SUCCESS) {\n        std::cout << \"not available; amdsmi call returned\" << amdsmi_ret;\n        dump_ret = 1;\n    }\n    if (print_attr_label(\"Current Fan Speed: \")) {\n      std::cout << static_cast<float>(value_i64)/value_u64 * 100 << \"% (\" <<\n          value_i64 << \"/\" << value_u64 << \")\" << std::endl;\n    }\n\n    std::cout << \"\\t=======\" << std::endl;\n  }\n  std::cout << delim << std::endl;\n  return dump_ret;\n}\n"
  },
  {
    "path": "rocrtst/suites/test_common/test_common.h",
    "content": "/*\n * =============================================================================\n *   ROC Runtime Conformance Release License\n * =============================================================================\n * The University of Illinois/NCSA\n * Open Source License (NCSA)\n *\n * Copyright (c) 2017, Advanced Micro Devices, Inc.\n * All rights reserved.\n *\n * Developed by:\n *\n *                 AMD Research and AMD ROC Software Development\n *\n *                 Advanced Micro Devices, Inc.\n *\n *                 www.amd.com\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal with the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n *  - Redistributions of source code must retain the above copyright notice,\n *    this list of conditions and the following disclaimers.\n *  - Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimers in\n *    the documentation and/or other materials provided with the distribution.\n *  - Neither the names of <Name of Development Group, Name of Institution>,\n *    nor the names of its contributors may be used to endorse or promote\n *    products derived from this Software without specific prior written\n *    permission.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS WITH THE SOFTWARE.\n *\n */\n\n#ifndef ROCRTST_SUITES_TEST_COMMON_TEST_COMMON_H_\n#define ROCRTST_SUITES_TEST_COMMON_TEST_COMMON_H_\n\n#include <memory>\n#include <vector>\n\nstruct RocrTstGlobals {\n  uint32_t verbosity;\n  uint32_t monitor_verbosity;\n  uint32_t num_iterations;\n};\n\nuint32_t ProcessCmdline(RocrTstGlobals* test, int arg_cnt, char** arg_list);\n\nint DumpMonitorInfo(void);\n\n#endif  // ROCRTST_SUITES_TEST_COMMON_TEST_COMMON_H_\n"
  },
  {
    "path": "rocrtst/thirdparty/include/LICENSE",
    "content": "Copyright © 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation.  All rights reserved.\nCopyright © 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation.  All rights reserved.\nCopyright © 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart.  All rights reserved.\nCopyright © 2004-2005 The Regents of the University of California. All rights reserved.\nCopyright © 2009      CNRS\nCopyright © 2009-2016 Inria.  All rights reserved.\nCopyright © 2009-2015 Université Bordeaux\nCopyright © 2009-2015 Cisco Systems, Inc.  All rights reserved.\nCopyright © 2009-2012 Oracle and/or its affiliates.  All rights reserved.\nCopyright © 2010      IBM\nCopyright © 2010      Jirka Hladky\nCopyright © 2012      Aleksej Saushev, The NetBSD Foundation\nCopyright © 2012      Blue Brain Project, EPFL. All rights reserved.\nCopyright © 2013-2014 University of Wisconsin-La Crosse. All rights reserved.\nCopyright © 2015      Research Organization for Information Science and Technology (RIST). All rights reserved.\nCopyright © 2015-2016 Intel, Inc.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n1. Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/autogen/config.h",
    "content": "/* include/hwloc/autogen/config.h.  Generated from config.h.in by configure.  */\n/* -*- c -*-\n * Copyright © 2009 CNRS\n * Copyright © 2009-2014 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/* The configuration file */\n\n#ifndef HWLOC_CONFIG_H\n#define HWLOC_CONFIG_H\n\n#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))\n# define __hwloc_restrict __restrict\n#else\n# if __STDC_VERSION__ >= 199901L\n#  define __hwloc_restrict restrict\n# else\n#  define __hwloc_restrict\n# endif\n#endif\n\n/* Note that if we're compiling C++, then just use the \"inline\"\n   keyword, since it's part of C++ */\n#if defined(c_plusplus) || defined(__cplusplus)\n#  define __hwloc_inline inline\n#elif defined(_MSC_VER) || defined(__HP_cc)\n#  define __hwloc_inline __inline\n#else\n#  define __hwloc_inline __inline__\n#endif\n\n/*\n * Note: this is public.  We can not assume anything from the compiler used\n * by the application and thus the HWLOC_HAVE_* macros below are not\n * fetched from the autoconf result here. We only automatically use a few\n * well-known easy cases.\n */\n\n/* Some handy constants to make the logic below a little more readable */\n#if defined(__cplusplus) && \\\n    (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR >= 4))\n#define GXX_ABOVE_3_4 1\n#else\n#define GXX_ABOVE_3_4 0\n#endif\n\n#if !defined(__cplusplus) && \\\n    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))\n#define GCC_ABOVE_2_95 1\n#else\n#define GCC_ABOVE_2_95 0\n#endif\n\n#if !defined(__cplusplus) && \\\n    (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))\n#define GCC_ABOVE_2_96 1\n#else\n#define GCC_ABOVE_2_96 0\n#endif\n\n#if !defined(__cplusplus) && \\\n    (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))\n#define GCC_ABOVE_3_3 1\n#else\n#define GCC_ABOVE_3_3 0\n#endif\n\n/* Maybe before gcc 2.95 too */\n#ifdef HWLOC_HAVE_ATTRIBUTE_UNUSED\n#define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED \n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_UNUSED (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_UNUSED 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_UNUSED\n# define __hwloc_attribute_unused __attribute__((__unused__))\n#else\n# define __hwloc_attribute_unused\n#endif\n\n#ifdef HWLOC_HAVE_ATTRIBUTE_MALLOC\n#define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC \n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_MALLOC (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_MALLOC 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_MALLOC\n# define __hwloc_attribute_malloc __attribute__((__malloc__))\n#else\n# define __hwloc_attribute_malloc\n#endif\n\n#ifdef HWLOC_HAVE_ATTRIBUTE_CONST\n#define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST \n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_CONST (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_CONST 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_CONST\n# define __hwloc_attribute_const __attribute__((__const__))\n#else\n# define __hwloc_attribute_const\n#endif\n\n#ifdef HWLOC_HAVE_ATTRIBUTE_PURE\n#define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE \n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_PURE (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_PURE 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_PURE\n# define __hwloc_attribute_pure __attribute__((__pure__))\n#else\n# define __hwloc_attribute_pure\n#endif\n\n#ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED\n#define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED \n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_DEPRECATED\n# define __hwloc_attribute_deprecated __attribute__((__deprecated__))\n#else\n# define __hwloc_attribute_deprecated\n#endif\n\n#ifdef HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS\n#define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS\n#elif defined(__GNUC__)\n# define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)\n#else\n# define __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS 0\n#endif\n#if __HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS\n# define __hwloc_attribute_may_alias __attribute__((__may_alias__))\n#else\n# define __hwloc_attribute_may_alias\n#endif\n\n#ifdef HWLOC_C_HAVE_VISIBILITY\n# if HWLOC_C_HAVE_VISIBILITY\n#  define HWLOC_DECLSPEC __attribute__((__visibility__(\"default\")))\n# else\n#  define HWLOC_DECLSPEC\n# endif\n#else\n# define HWLOC_DECLSPEC\n#endif\n\n/* Defined to 1 on Linux */\n#define HWLOC_LINUX_SYS 1\n\n/* Defined to 1 if the CPU_SET macro works */\n#define HWLOC_HAVE_CPU_SET 1\n\n/* Defined to 1 if you have the `windows.h' header. */\n/* #undef HWLOC_HAVE_WINDOWS_H */\n#define hwloc_pid_t pid_t\n#define hwloc_thread_t pthread_t\n\n#ifdef HWLOC_HAVE_WINDOWS_H\n\n#  include <windows.h>\ntypedef DWORDLONG hwloc_uint64_t;\n\n#else /* HWLOC_HAVE_WINDOWS_H */\n\n#  ifdef hwloc_thread_t\n#    include <pthread.h>\n#  endif /* hwloc_thread_t */\n\n/* Defined to 1 if you have the <stdint.h> header file. */\n#  define HWLOC_HAVE_STDINT_H 1\n\n#  include <unistd.h>\n#  ifdef HWLOC_HAVE_STDINT_H\n#    include <stdint.h>\n#  endif\ntypedef uint64_t hwloc_uint64_t;\n\n#endif /* HWLOC_HAVE_WINDOWS_H */\n\n/* Whether we need to re-define all the hwloc public symbols or not */\n#define HWLOC_SYM_TRANSFORM 0\n\n/* The hwloc symbol prefix */\n#define HWLOC_SYM_PREFIX hwloc_\n\n/* The hwloc symbol prefix in all caps */\n#define HWLOC_SYM_PREFIX_CAPS HWLOC_\n\n#endif /* HWLOC_CONFIG_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/bitmap.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2017 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief The bitmap API, for use in hwloc itself.\n */\n\n#ifndef HWLOC_BITMAP_H\n#define HWLOC_BITMAP_H\n\n#include <hwloc/autogen/config.h>\n#include <assert.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_bitmap The bitmap API\n *\n * The ::hwloc_bitmap_t type represents a set of objects, typically OS\n * processors -- which may actually be hardware threads (represented\n * by ::hwloc_cpuset_t, which is a typedef for ::hwloc_bitmap_t) -- or\n * memory nodes (represented by ::hwloc_nodeset_t, which is also a\n * typedef for ::hwloc_bitmap_t).\n *\n * <em>Both CPU and node sets are always indexed by OS physical number.</em>\n *\n * \\note CPU sets and nodesets are described in \\ref hwlocality_object_sets.\n *\n * A bitmap may be of infinite size (all bits are set after some point).\n * A bitmap may even be full if all bits are set.\n *\n * \\note Several examples of using the bitmap API are available under the\n * doc/examples/ directory in the source tree.\n * Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use\n * of this API.\n * @{\n */\n\n\n/** \\brief\n * Set of bits represented as an opaque pointer to an internal bitmap.\n */\ntypedef struct hwloc_bitmap_s * hwloc_bitmap_t;\n/** \\brief a non-modifiable ::hwloc_bitmap_t */\ntypedef const struct hwloc_bitmap_s * hwloc_const_bitmap_t;\n\n\n/*\n * Bitmap allocation, freeing and copying.\n */\n\n/** \\brief Allocate a new empty bitmap.\n *\n * \\returns A valid bitmap or \\c NULL.\n *\n * The bitmap should be freed by a corresponding call to\n * hwloc_bitmap_free().\n */\nHWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc(void) __hwloc_attribute_malloc;\n\n/** \\brief Allocate a new full bitmap. */\nHWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc_full(void) __hwloc_attribute_malloc;\n\n/** \\brief Free bitmap \\p bitmap.\n *\n * If \\p bitmap is \\c NULL, no operation is performed.\n */\nHWLOC_DECLSPEC void hwloc_bitmap_free(hwloc_bitmap_t bitmap);\n\n/** \\brief Duplicate bitmap \\p bitmap by allocating a new bitmap and copying \\p bitmap contents.\n *\n * If \\p bitmap is \\c NULL, \\c NULL is returned.\n */\nHWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc;\n\n/** \\brief Copy the contents of bitmap \\p src into the already allocated bitmap \\p dst */\nHWLOC_DECLSPEC void hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src);\n\n\n/*\n * Bitmap/String Conversion\n */\n\n/** \\brief Stringify a bitmap.\n *\n * Up to \\p buflen characters may be written in buffer \\p buf.\n *\n * If \\p buflen is 0, \\p buf may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Stringify a bitmap into a newly allocated string.\n *\n * \\return -1 on error.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Parse a bitmap string and stores it in bitmap \\p bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);\n\n/** \\brief Stringify a bitmap in the list format.\n *\n * Lists are comma-separated indexes or ranges.\n * Ranges are dash separated indexes.\n * The last range may not have an ending indexes if the bitmap is infinitely set.\n *\n * Up to \\p buflen characters may be written in buffer \\p buf.\n *\n * If \\p buflen is 0, \\p buf may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Stringify a bitmap into a newly allocated list string.\n *\n * \\return -1 on error.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Parse a list string and stores it in bitmap \\p bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);\n\n/** \\brief Stringify a bitmap in the taskset-specific format.\n *\n * The taskset command manipulates bitmap strings that contain a single\n * (possible very long) hexadecimal number starting with 0x.\n *\n * Up to \\p buflen characters may be written in buffer \\p buf.\n *\n * If \\p buflen is 0, \\p buf may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Stringify a bitmap into a newly allocated taskset-specific string.\n *\n * \\return -1 on error.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);\n\n/** \\brief Parse a taskset-specific bitmap string and stores it in bitmap \\p bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_taskset_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);\n\n\n/*\n * Building bitmaps.\n */\n\n/** \\brief Empty the bitmap \\p bitmap */\nHWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap);\n\n/** \\brief Fill bitmap \\p bitmap with all possible indexes (even if those objects don't exist or are otherwise unavailable) */\nHWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap);\n\n/** \\brief Empty the bitmap \\p bitmap and add bit \\p id */\nHWLOC_DECLSPEC void hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id);\n\n/** \\brief Fill the bitmap \\p and clear the index \\p id */\nHWLOC_DECLSPEC void hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id);\n\n/** \\brief Setup bitmap \\p bitmap from unsigned long \\p mask */\nHWLOC_DECLSPEC void hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask);\n\n/** \\brief Setup bitmap \\p bitmap from unsigned long \\p mask used as \\p i -th subset */\nHWLOC_DECLSPEC void hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);\n\n\n/*\n * Modifying bitmaps.\n */\n\n/** \\brief Add index \\p id in bitmap \\p bitmap */\nHWLOC_DECLSPEC void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id);\n\n/** \\brief Add indexes from \\p begin to \\p end in bitmap \\p bitmap.\n *\n * If \\p end is \\c -1, the range is infinite.\n */\nHWLOC_DECLSPEC void hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end);\n\n/** \\brief Replace \\p i -th subset of bitmap \\p bitmap with unsigned long \\p mask */\nHWLOC_DECLSPEC void hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);\n\n/** \\brief Remove index \\p id from bitmap \\p bitmap */\nHWLOC_DECLSPEC void hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id);\n\n/** \\brief Remove indexes from \\p begin to \\p end in bitmap \\p bitmap.\n *\n * If \\p end is \\c -1, the range is infinite.\n */\nHWLOC_DECLSPEC void hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end);\n\n/** \\brief Keep a single index among those set in bitmap \\p bitmap\n *\n * May be useful before binding so that the process does not\n * have a chance of migrating between multiple logical CPUs\n * in the original mask.\n */\nHWLOC_DECLSPEC void hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);\n\n\n/*\n * Consulting bitmaps.\n */\n\n/** \\brief Convert the beginning part of bitmap \\p bitmap into unsigned long \\p mask */\nHWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ulong(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Convert the \\p i -th subset of bitmap \\p bitmap into unsigned long mask */\nHWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) __hwloc_attribute_pure;\n\n/** \\brief Test whether index \\p id is part of bitmap \\p bitmap */\nHWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure;\n\n/** \\brief Test whether bitmap \\p bitmap is empty */\nHWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Test whether bitmap \\p bitmap is completely full\n *\n * \\note A full bitmap is always infinitely set.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_isfull(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Compute the first index (least significant bit) in bitmap \\p bitmap\n *\n * \\return -1 if no index is set in \\p bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_first(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Compute the next index in bitmap \\p bitmap which is after index \\p prev\n *\n * If \\p prev is -1, the first index is returned.\n *\n * \\return -1 if no index with higher index is set in \\p bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_next(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;\n\n/** \\brief Compute the last index (most significant bit) in bitmap \\p bitmap\n *\n * \\return -1 if no index is set in \\p bitmap, or if \\p bitmap is infinitely set.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Compute the \"weight\" of bitmap \\p bitmap (i.e., number of\n * indexes that are in the bitmap).\n *\n * \\return the number of indexes that are in the bitmap.\n *\n * \\return -1 if \\p bitmap is infinitely set.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;\n\n/** \\brief Loop macro iterating on bitmap \\p bitmap\n *\n * The loop must start with hwloc_bitmap_foreach_begin() and end\n * with hwloc_bitmap_foreach_end() followed by a terminating ';'.\n *\n * \\p index is the loop variable; it should be an unsigned int.  The\n * first iteration will set \\p index to the lowest index in the bitmap.\n * Successive iterations will iterate through, in order, all remaining\n * indexes set in the bitmap.  To be specific: each iteration will return a\n * value for \\p index such that hwloc_bitmap_isset(bitmap, index) is true.\n *\n * The assert prevents the loop from being infinite if the bitmap is infinitely set.\n *\n * \\hideinitializer\n */\n#define hwloc_bitmap_foreach_begin(id, bitmap) \\\ndo { \\\n        assert(hwloc_bitmap_weight(bitmap) != -1); \\\n        for (id = hwloc_bitmap_first(bitmap); \\\n             (unsigned) id != (unsigned) -1; \\\n             id = hwloc_bitmap_next(bitmap, id)) {\n\n/** \\brief End of loop macro iterating on a bitmap.\n *\n * Needs a terminating ';'.\n *\n * \\sa hwloc_bitmap_foreach_begin()\n * \\hideinitializer\n */\n#define hwloc_bitmap_foreach_end()\t\t\\\n        } \\\n} while (0)\n\n\n/*\n * Combining bitmaps.\n */\n\n/** \\brief Or bitmaps \\p bitmap1 and \\p bitmap2 and store the result in bitmap \\p res\n *\n * \\p res can be the same as \\p bitmap1 or \\p bitmap2\n */\nHWLOC_DECLSPEC void hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);\n\n/** \\brief And bitmaps \\p bitmap1 and \\p bitmap2 and store the result in bitmap \\p res\n *\n * \\p res can be the same as \\p bitmap1 or \\p bitmap2\n */\nHWLOC_DECLSPEC void hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);\n\n/** \\brief And bitmap \\p bitmap1 and the negation of \\p bitmap2 and store the result in bitmap \\p res\n *\n * \\p res can be the same as \\p bitmap1 or \\p bitmap2\n */\nHWLOC_DECLSPEC void hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);\n\n/** \\brief Xor bitmaps \\p bitmap1 and \\p bitmap2 and store the result in bitmap \\p res\n *\n * \\p res can be the same as \\p bitmap1 or \\p bitmap2\n */\nHWLOC_DECLSPEC void hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);\n\n/** \\brief Negate bitmap \\p bitmap and store the result in bitmap \\p res\n *\n * \\p res can be the same as \\p bitmap\n */\nHWLOC_DECLSPEC void hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap);\n\n\n/*\n * Comparing bitmaps.\n */\n\n/** \\brief Test whether bitmaps \\p bitmap1 and \\p bitmap2 intersects */\nHWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;\n\n/** \\brief Test whether bitmap \\p sub_bitmap is part of bitmap \\p super_bitmap.\n *\n * \\note The empty bitmap is considered included in any other bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_isincluded (hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure;\n\n/** \\brief Test whether bitmap \\p bitmap1 is equal to bitmap \\p bitmap2 */\nHWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;\n\n/** \\brief Compare bitmaps \\p bitmap1 and \\p bitmap2 using their lowest index.\n *\n * Smaller least significant bit is smaller.\n * The empty bitmap is considered higher than anything.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;\n\n/** \\brief Compare bitmaps \\p bitmap1 and \\p bitmap2 in lexicographic order.\n *\n * Lexicographic comparison of bitmaps, starting for their highest indexes.\n * Compare last indexes first, then second, etc.\n * The empty bitmap is considered lower than anything.\n *\n * \\note This is different from the non-existing hwloc_bitmap_compare_last()\n * which would only compare the highest index of each bitmap.\n */\nHWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_BITMAP_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/cpuset.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2010 inria.  All rights reserved.\n * Copyright © 2009-2010, 2013 Université Bordeaux 1\n * Copyright © 2009-2010 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief The old deprecated Cpuset API.\n * This interface should not be used anymore, it will be dropped in a later release.\n *\n * hwloc/bitmap.h should be used instead. Most hwloc_cpuset_foo functions are\n * replaced with hwloc_bitmap_foo. The only exceptions are:\n * - hwloc_cpuset_from_string -> hwloc_bitmap_sscanf\n * - hwloc_cpuset_cpu -> hwloc_bitmap_only\n * - hwloc_cpuset_all_but_cpu -> hwloc_bitmap_allbut\n */\n\n#ifndef HWLOC_CPUSET_H\n#define HWLOC_CPUSET_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"hwloc/bitmap.h\"\n\nstatic __hwloc_inline hwloc_bitmap_t __hwloc_attribute_deprecated hwloc_cpuset_alloc(void) { return hwloc_bitmap_alloc(); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_free(hwloc_bitmap_t bitmap) { hwloc_bitmap_free(bitmap); }\nstatic __hwloc_inline hwloc_bitmap_t __hwloc_attribute_deprecated hwloc_cpuset_dup(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_dup(bitmap); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src) { hwloc_bitmap_copy(dst, src); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_snprintf(buf, buflen, bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_asprintf(strp, bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_from_string(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string) { return hwloc_bitmap_sscanf(bitmap, string); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_zero(hwloc_bitmap_t bitmap) { hwloc_bitmap_zero(bitmap); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_fill(hwloc_bitmap_t bitmap) { hwloc_bitmap_fill(bitmap); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask) { hwloc_bitmap_from_ulong(bitmap, mask); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask) { hwloc_bitmap_from_ith_ulong(bitmap, i, mask); }\nstatic __hwloc_inline unsigned __hwloc_attribute_deprecated long hwloc_cpuset_to_ulong(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_to_ulong(bitmap); }\nstatic __hwloc_inline unsigned __hwloc_attribute_deprecated long hwloc_cpuset_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) { return hwloc_bitmap_to_ith_ulong(bitmap, i); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_cpu(hwloc_bitmap_t bitmap, unsigned index_) { hwloc_bitmap_only(bitmap, index_); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_all_but_cpu(hwloc_bitmap_t bitmap, unsigned index_) { hwloc_bitmap_allbut(bitmap, index_); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_set(hwloc_bitmap_t bitmap, unsigned index_) { hwloc_bitmap_set(bitmap, index_); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_set_range(hwloc_bitmap_t bitmap, unsigned begin, unsigned end) { hwloc_bitmap_set_range(bitmap, begin, end); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask) { hwloc_bitmap_set_ith_ulong(bitmap, i, mask); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_clr(hwloc_bitmap_t bitmap, unsigned index_) { hwloc_bitmap_clr(bitmap, index_); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_clr_range(hwloc_bitmap_t bitmap, unsigned begin, unsigned end) { hwloc_bitmap_clr_range(bitmap, begin, end); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_isset(hwloc_const_bitmap_t bitmap, unsigned index_) { return hwloc_bitmap_isset(bitmap, index_); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_iszero(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_iszero(bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_isfull(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_isfull(bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_isequal(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { return hwloc_bitmap_isequal(bitmap1, bitmap2); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_intersects(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { return hwloc_bitmap_intersects(bitmap1, bitmap2); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_isincluded(hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) { return hwloc_bitmap_isincluded(sub_bitmap, super_bitmap); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_or(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { hwloc_bitmap_or(res, bitmap1, bitmap2); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_and(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { hwloc_bitmap_and(res, bitmap1, bitmap2); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_andnot(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { hwloc_bitmap_andnot(res, bitmap1, bitmap2); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_xor(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { hwloc_bitmap_xor(res, bitmap1, bitmap2); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_not(hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap) { hwloc_bitmap_not(res, bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_first(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_first(bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_last(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_last(bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_next(hwloc_const_bitmap_t bitmap, unsigned prev) { return hwloc_bitmap_next(bitmap, prev); }\nstatic __hwloc_inline void __hwloc_attribute_deprecated hwloc_cpuset_singlify(hwloc_bitmap_t bitmap) { hwloc_bitmap_singlify(bitmap); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { return hwloc_bitmap_compare_first(bitmap1, bitmap2); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) { return hwloc_bitmap_compare(bitmap1, bitmap2); }\nstatic __hwloc_inline int __hwloc_attribute_deprecated hwloc_cpuset_weight(hwloc_const_bitmap_t bitmap) { return hwloc_bitmap_weight(bitmap); }\n\n#define hwloc_cpuset_foreach_begin hwloc_bitmap_foreach_begin\n#define hwloc_cpuset_foreach_end hwloc_bitmap_foreach_end\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n#endif /* HWLOC_CPUSET_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/cuda.h",
    "content": "/*\n * Copyright © 2010-2017 Inria.  All rights reserved.\n * Copyright © 2010-2011 Université Bordeaux\n * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and the CUDA Driver API.\n *\n * Applications that use both hwloc and the CUDA Driver API may want to\n * include this file so as to get topology information for CUDA devices.\n *\n */\n\n#ifndef HWLOC_CUDA_H\n#define HWLOC_CUDA_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#include <hwloc/helper.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#endif\n\n#include <cuda.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_cuda Interoperability with the CUDA Driver API\n *\n * This interface offers ways to retrieve topology information about\n * CUDA devices when using the CUDA Driver API.\n *\n * @{\n */\n\n/** \\brief Return the domain, bus and device IDs of the CUDA device \\p cudevice.\n *\n * Device \\p cudevice must match the local machine.\n */\nstatic __hwloc_inline int\nhwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t      CUdevice cudevice, int *domain, int *bus, int *dev)\n{\n  CUresult cres;\n\n#if CUDA_VERSION >= 4000\n  cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);\n  if (cres != CUDA_SUCCESS) {\n    errno = ENOSYS;\n    return -1;\n  }\n#else\n  *domain = 0;\n#endif\n  cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);\n  if (cres != CUDA_SUCCESS) {\n    errno = ENOSYS;\n    return -1;\n  }\n  cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);\n  if (cres != CUDA_SUCCESS) {\n    errno = ENOSYS;\n    return -1;\n  }\n\n  return 0;\n}\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to device \\p cudevice.\n *\n * Return the CPU set describing the locality of the CUDA device \\p cudevice.\n *\n * Topology \\p topology and device \\p cudevice must match the local machine.\n * I/O devices detection and the CUDA component are not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_cuda_get_device_osdev()\n * and hwloc_cuda_get_device_osdev_by_index().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux; other systems will simply get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t     CUdevice cudevice, hwloc_cpuset_t set)\n{\n#ifdef HWLOC_LINUX_SYS\n  /* If we're on Linux, use the sysfs mechanism to get the local cpus */\n#define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128\n  char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];\n  FILE *sysfile = NULL;\n  int domainid, busid, deviceid;\n\n  if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))\n    return -1;\n\n  if (!hwloc_topology_is_thissystem(topology)) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  sprintf(path, \"/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus\", domainid, busid, deviceid);\n  sysfile = fopen(path, \"r\");\n  if (!sysfile)\n    return -1;\n\n  if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n      || hwloc_bitmap_iszero(set))\n    hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n  fclose(sysfile);\n#else\n  /* Non-Linux systems simply get a full cpuset */\n  hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n  return 0;\n}\n\n/** \\brief Get the hwloc PCI device object corresponding to the\n * CUDA device \\p cudevice.\n *\n * Return the PCI device object describing the CUDA device \\p cudevice.\n * Return NULL if there is none.\n *\n * Topology \\p topology and device \\p cudevice must match the local machine.\n * I/O devices detection must be enabled in topology \\p topology.\n * The CUDA component is not needed in the topology.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)\n{\n  int domain, bus, dev;\n\n  if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))\n    return NULL;\n\n  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);\n}\n\n/** \\brief Get the hwloc OS device object corresponding to CUDA device \\p cudevice.\n *\n * Return the hwloc OS device object that describes the given\n * CUDA device \\p cudevice. Return NULL if there is none.\n *\n * Topology \\p topology and device \\p cudevice must match the local machine.\n * I/O devices detection and the CUDA component must be enabled in the topology.\n * If not, the locality of the object may still be found using\n * hwloc_cuda_get_device_cpuset().\n *\n * \\note The corresponding hwloc PCI device may be found by looking\n * at the result parent pointer.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)\n{\n\thwloc_obj_t osdev = NULL;\n\tint domain, bus, dev;\n\n\tif (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))\n\t\treturn NULL;\n\n\tosdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\thwloc_obj_t pcidev = osdev->parent;\n\t\tif (strncmp(osdev->name, \"cuda\", 4))\n\t\t\tcontinue;\n\t\tif (pcidev\n\t\t    && pcidev->type == HWLOC_OBJ_PCI_DEVICE\n\t\t    && (int) pcidev->attr->pcidev.domain == domain\n\t\t    && (int) pcidev->attr->pcidev.bus == bus\n\t\t    && (int) pcidev->attr->pcidev.dev == dev\n\t\t    && pcidev->attr->pcidev.func == 0)\n\t\t\treturn osdev;\n\t}\n\n\treturn NULL;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * CUDA device whose index is \\p idx.\n *\n * Return the OS device object describing the CUDA device whose\n * index is \\p idx. Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the CUDA component must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n *\n * \\note This function is identical to hwloc_cudart_get_device_osdev_by_index().\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)\n{\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\tif (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type\n\t\t    && osdev->name\n\t\t    && !strncmp(\"cuda\", osdev->name, 4)\n\t\t    && atoi(osdev->name + 4) == (int) idx)\n\t\t\treturn osdev;\n\t}\n\treturn NULL;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_CUDA_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/cudart.h",
    "content": "/*\n * Copyright © 2010-2017 Inria.  All rights reserved.\n * Copyright © 2010-2011 Université Bordeaux\n * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and the CUDA Runtime API.\n *\n * Applications that use both hwloc and the CUDA Runtime API may want to\n * include this file so as to get topology information for CUDA devices.\n *\n */\n\n#ifndef HWLOC_CUDART_H\n#define HWLOC_CUDART_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#include <hwloc/helper.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#endif\n\n#include <cuda.h> /* for CUDA_VERSION */\n#include <cuda_runtime_api.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_cudart Interoperability with the CUDA Runtime API\n *\n * This interface offers ways to retrieve topology information about\n * CUDA devices when using the CUDA Runtime API.\n *\n * @{\n */\n\n/** \\brief Return the domain, bus and device IDs of the CUDA device whose index is \\p idx.\n *\n * Device index \\p idx must match the local machine.\n */\nstatic __hwloc_inline int\nhwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t\tint idx, int *domain, int *bus, int *dev)\n{\n  cudaError_t cerr;\n  struct cudaDeviceProp prop;\n\n  cerr = cudaGetDeviceProperties(&prop, idx);\n  if (cerr) {\n    errno = ENOSYS;\n    return -1;\n  }\n\n#if CUDA_VERSION >= 4000\n  *domain = prop.pciDomainID;\n#else\n  *domain = 0;\n#endif\n\n  *bus = prop.pciBusID;\n  *dev = prop.pciDeviceID;\n\n  return 0;\n}\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to device \\p idx.\n *\n * Return the CPU set describing the locality of the CUDA device\n * whose index is \\p idx.\n *\n * Topology \\p topology and device \\p idx must match the local machine.\n * I/O devices detection and the CUDA component are not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_cudart_get_device_osdev_by_index().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux; other systems will simply get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t       int idx, hwloc_cpuset_t set)\n{\n#ifdef HWLOC_LINUX_SYS\n  /* If we're on Linux, use the sysfs mechanism to get the local cpus */\n#define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128\n  char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];\n  FILE *sysfile = NULL;\n  int domain, bus, dev;\n\n  if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))\n    return -1;\n\n  if (!hwloc_topology_is_thissystem(topology)) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  sprintf(path, \"/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus\", (unsigned) domain, (unsigned) bus, (unsigned) dev);\n  sysfile = fopen(path, \"r\");\n  if (!sysfile)\n    return -1;\n\n  if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n      || hwloc_bitmap_iszero(set))\n    hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n  fclose(sysfile);\n#else\n  /* Non-Linux systems simply get a full cpuset */\n  hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n  return 0;\n}\n\n/** \\brief Get the hwloc PCI device object corresponding to the\n * CUDA device whose index is \\p idx.\n *\n * Return the PCI device object describing the CUDA device whose\n * index is \\p idx. Return NULL if there is none.\n *\n * Topology \\p topology and device \\p idx must match the local machine.\n * I/O devices detection must be enabled in topology \\p topology.\n * The CUDA component is not needed in the topology.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)\n{\n  int domain, bus, dev;\n\n  if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))\n    return NULL;\n\n  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * CUDA device whose index is \\p idx.\n *\n * Return the OS device object describing the CUDA device whose\n * index is \\p idx. Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the CUDA component must be enabled in the topology.\n * If not, the locality of the object may still be found using\n * hwloc_cudart_get_device_cpuset().\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n *\n * \\note This function is identical to hwloc_cuda_get_device_osdev_by_index().\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)\n{\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\tif (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type\n\t\t    && osdev->name\n\t\t    && !strncmp(\"cuda\", osdev->name, 4)\n\t\t    && atoi(osdev->name + 4) == (int) idx)\n\t\t\treturn osdev;\n\t}\n\treturn NULL;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_CUDART_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/deprecated.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2014 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2010 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/**\n * This file contains the inline code of functions declared in hwloc.h\n */\n\n#ifndef HWLOC_DEPRECATED_H\n#define HWLOC_DEPRECATED_H\n\n#ifndef HWLOC_H\n#error Please include the main hwloc.h instead\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* backward compat with v1.10 before Socket->Package renaming */\n#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE\n/* backward compat with v1.10 before Node->NUMANode clarification */\n#define HWLOC_OBJ_NODE HWLOC_OBJ_NUMANODE\n\n/** \\brief Return an object type from the string\n *\n * \\return -1 if unrecognized.\n */\nHWLOC_DECLSPEC hwloc_obj_type_t hwloc_obj_type_of_string (const char * string) __hwloc_attribute_pure __hwloc_attribute_deprecated;\n\n/** \\brief Stringify a given topology object into a human-readable form.\n *\n * \\note This function is deprecated in favor of hwloc_obj_type_snprintf()\n * and hwloc_obj_attr_snprintf() since it is not very flexible and\n * only prints physical/OS indexes.\n *\n * Fill string \\p string up to \\p size characters with the description\n * of topology object \\p obj in topology \\p topology.\n *\n * If \\p verbose is set, a longer description is used. Otherwise a\n * short description is used.\n *\n * \\p indexprefix is used to prefix the \\p os_index attribute number of\n * the object in the description. If \\c NULL, the \\c # character is used.\n *\n * If \\p size is 0, \\p string may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_obj_snprintf(char * __hwloc_restrict string, size_t size,\n\t\t\t\t      hwloc_topology_t topology, hwloc_obj_t obj,\n\t\t\t\t      const char * __hwloc_restrict indexprefix, int verbose) __hwloc_attribute_deprecated;\n\n/** \\brief Distribute \\p n items over the topology under \\p root\n *\n * Array \\p cpuset will be filled with \\p n cpusets recursively distributed\n * linearly over the topology under \\p root, down to depth \\p until (which can\n * be INT_MAX to distribute down to the finest level).\n *\n * This is typically useful when an application wants to distribute \\p n\n * threads over a machine, giving each of them as much private cache as\n * possible and keeping them locally in number order.\n *\n * The caller may typically want to also call hwloc_bitmap_singlify()\n * before binding a thread so that it does not move at all.\n *\n * \\note This function requires the \\p root object to have a CPU set.\n */\nstatic __hwloc_inline void\nhwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until) __hwloc_attribute_deprecated;\nstatic __hwloc_inline void\nhwloc_distribute(hwloc_topology_t topology, hwloc_obj_t root, hwloc_cpuset_t *set, unsigned n, unsigned until)\n{\n  hwloc_distrib(topology, &root, 1, set, n, until, 0);\n}\n\n/** \\brief Distribute \\p n items over the topology under \\p roots\n *\n * This is the same as hwloc_distribute(), but takes an array of roots instead of\n * just one root.\n *\n * \\note This function requires the \\p roots objects to have a CPU set.\n */\nstatic __hwloc_inline void\nhwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until) __hwloc_attribute_deprecated;\nstatic __hwloc_inline void\nhwloc_distributev(hwloc_topology_t topology, hwloc_obj_t *roots, unsigned n_roots, hwloc_cpuset_t *set, unsigned n, unsigned until)\n{\n  hwloc_distrib(topology, roots, n_roots, set, n, until, 0);\n}\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_DEPRECATED_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/diff.h",
    "content": "/*\n * Copyright © 2013-2016 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Topology differences.\n */\n\n#ifndef HWLOC_DIFF_H\n#define HWLOC_DIFF_H\n\n#ifndef HWLOC_H\n#error Please include the main hwloc.h instead\n#endif\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#elif 0\n}\n#endif\n\n\n/** \\defgroup hwlocality_diff Topology differences\n *\n * Applications that manipulate many similar topologies, for instance\n * one for each node of a homogeneous cluster, may want to compress\n * topologies to reduce the memory footprint.\n *\n * This file offers a way to manipulate the difference between topologies\n * and export/import it to/from XML.\n * Compression may therefore be achieved by storing one topology\n * entirely while the others are only described by their differences\n * with the former.\n * The actual topology can be reconstructed when actually needed by\n * applying the precomputed difference to the reference topology.\n *\n * This interface targets very similar nodes.\n * Only very simple differences between topologies are actually\n * supported, for instance a change in the memory size, the name\n * of the object, or some info attribute.\n * More complex differences such as adding or removing objects cannot\n * be represented in the difference structures and therefore return\n * errors.\n *\n * It means that there is no need to apply the difference when\n * looking at the tree organization (how many levels, how many\n * objects per level, what kind of objects, CPU and node sets, etc)\n * and when binding to objects.\n * However the difference must be applied when looking at object\n * attributes such as the name, the memory size or info attributes.\n *\n * @{\n */\n\n\n/** \\brief Type of one object attribute difference.\n */\ntypedef enum hwloc_topology_diff_obj_attr_type_e {\n  /** \\brief The object local memory is modified.\n   * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s\n   * (and the index field is ignored).\n   */\n  HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,\n\n  /** \\brief The object name is modified.\n   * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s\n   * (and the name field is ignored).\n   */\n\n  HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,\n  /** \\brief the value of an info attribute is modified.\n   * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s.\n   */\n  HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO\n} hwloc_topology_diff_obj_attr_type_t;\n\n/** \\brief One object attribute difference.\n */\nunion hwloc_topology_diff_obj_attr_u {\n  struct hwloc_topology_diff_obj_attr_generic_s {\n    /* each part of the union must start with these */\n    hwloc_topology_diff_obj_attr_type_t type;\n  } generic;\n\n  /** \\brief Integer attribute modification with an optional index. */\n  struct hwloc_topology_diff_obj_attr_uint64_s {\n    /* used for storing integer attributes */\n    hwloc_topology_diff_obj_attr_type_t type;\n    hwloc_uint64_t index; /* not used for SIZE */\n    hwloc_uint64_t oldvalue;\n    hwloc_uint64_t newvalue;\n  } uint64;\n\n  /** \\brief String attribute modification with an optional name */\n  struct hwloc_topology_diff_obj_attr_string_s {\n    /* used for storing name and info pairs */\n    hwloc_topology_diff_obj_attr_type_t type;\n    char *name; /* not used for NAME */\n    char *oldvalue;\n    char *newvalue;\n  } string;\n};\n\n\n/** \\brief Type of one element of a difference list.\n */\ntypedef enum hwloc_topology_diff_type_e {\n  /** \\brief An object attribute was changed.\n   * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_s.\n   */\n  HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,\n\n  /** \\brief The difference is too complex,\n   * it cannot be represented. The difference below\n   * this object has not been checked.\n   * hwloc_topology_diff_build() will return 1.\n   *\n   * The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_too_complex_s.\n   */\n  HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX\n} hwloc_topology_diff_type_t;\n\n/** \\brief One element of a difference list between two topologies.\n */\ntypedef union hwloc_topology_diff_u {\n  struct hwloc_topology_diff_generic_s {\n    /* each part of the union must start with these */\n    hwloc_topology_diff_type_t type;\n    union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */\n  } generic;\n\n  /* A difference in an object attribute. */\n  struct hwloc_topology_diff_obj_attr_s {\n    hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */\n    union hwloc_topology_diff_u * next;\n    /* List of attribute differences for a single object */\n    unsigned obj_depth;\n    unsigned obj_index;\n    union hwloc_topology_diff_obj_attr_u diff;\n  } obj_attr;\n\n  /* A difference that is too complex. */\n  struct hwloc_topology_diff_too_complex_s {\n    hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */\n    union hwloc_topology_diff_u * next;\n    /* Where we had to stop computing the diff in the first topology */\n    unsigned obj_depth;\n    unsigned obj_index;\n  } too_complex;\n} * hwloc_topology_diff_t;\n\n\n/** \\brief Compute the difference between 2 topologies.\n *\n * The difference is stored as a list of ::hwloc_topology_diff_t entries\n * starting at \\p diff.\n * It is computed by doing a depth-first traversal of both topology trees\n * simultaneously.\n *\n * If the difference between 2 objects is too complex to be represented\n * (for instance if some objects have different types, or different numbers\n * of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX\n * is queued.\n * The computation of the diff does not continue below these objects.\n * So each such diff entry means that the difference between two subtrees\n * could not be computed.\n *\n * \\return 0 if the difference can be represented properly.\n *\n * \\return 0 with \\p diff pointing to NULL if there is no difference\n * between the topologies.\n *\n * \\return 1 if the difference is too complex (see above). Some entries in\n * the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.\n *\n * \\return -1 on any other error.\n *\n * \\note \\p flags is currently not used. It should be 0.\n *\n * \\note The output diff has to be freed with hwloc_topology_diff_destroy().\n *\n * \\note The output diff can only be exported to XML or passed to\n * hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type\n * ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.\n *\n * \\note The output diff may be modified by removing some entries from\n * the list. The removed entries should be freed by passing them to\n * to hwloc_topology_diff_destroy() (possible as another list).\n*/\nHWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);\n\n/** \\brief Flags to be given to hwloc_topology_diff_apply().\n */\nenum hwloc_topology_diff_apply_flags_e {\n  /** \\brief Apply topology diff in reverse direction.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)\n};\n\n/** \\brief Apply a topology diff to an existing topology.\n *\n * \\p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e.\n *\n * The new topology is modified in place. hwloc_topology_dup()\n * may be used to duplicate it before patching.\n *\n * If the difference cannot be applied entirely, all previous applied\n * elements are unapplied before returning.\n *\n * \\return 0 on success.\n *\n * \\return -N if applying the difference failed while trying\n * to apply the N-th part of the difference. For instance -1\n * is returned if the very first difference element could not\n * be applied.\n */\nHWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);\n\n/** \\brief Destroy a list of topology differences.\n *\n * \\note The \\p topology parameter must be a valid topology\n * but it is not required that it is related to \\p diff.\n */\nHWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_t topology, hwloc_topology_diff_t diff);\n\n/** \\brief Load a list of topology differences from a XML file.\n *\n * If not \\c NULL, \\p refname will be filled with the identifier\n * string of the reference topology for the difference file,\n * if any was specified in the XML file.\n * This identifier is usually the name of the other XML file\n * that contains the reference topology.\n *\n * \\note The \\p topology parameter must be a valid topology\n * but it is not required that it is related to \\p diff.\n *\n * \\note the pointer returned in refname should later be freed\n * by the caller.\n */\nHWLOC_DECLSPEC int hwloc_topology_diff_load_xml(hwloc_topology_t topology, const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);\n\n/** \\brief Export a list of topology differences to a XML file.\n *\n * If not \\c NULL, \\p refname defines an identifier string\n * for the reference topology which was used as a base when\n * computing this difference.\n * This identifier is usually the name of the other XML file\n * that contains the reference topology.\n * This attribute is given back when reading the diff from XML.\n *\n * \\note The \\p topology parameter must be a valid topology\n * but it is not required that it is related to \\p diff.\n */\nHWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_t topology, hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);\n\n/** \\brief Load a list of topology differences from a XML buffer.\n *\n * If not \\c NULL, \\p refname will be filled with the identifier\n * string of the reference topology for the difference file,\n * if any was specified in the XML file.\n * This identifier is usually the name of the other XML file\n * that contains the reference topology.\n *\n * \\note The \\p topology parameter must be a valid topology\n * but it is not required that it is related to \\p diff.\n *\n * \\note the pointer returned in refname should later be freed\n * by the caller.\n  */\nHWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(hwloc_topology_t topology, const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);\n\n/** \\brief Export a list of topology differences to a XML buffer.\n *\n * If not \\c NULL, \\p refname defines an identifier string\n * for the reference topology which was used as a base when\n * computing this difference.\n * This identifier is usually the name of the other XML file\n * that contains the reference topology.\n * This attribute is given back when reading the diff from XML.\n *\n * \\note The XML buffer should later be freed with hwloc_free_xmlbuffer().\n *\n * \\note The \\p topology parameter must be a valid topology\n * but it is not required that it is related to \\p diff.\n */\nHWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_t topology, hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_DIFF_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/gl.h",
    "content": "/*\n * Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.\n * Copyright © 2012-2013 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and OpenGL displays.\n *\n * Applications that use both hwloc and OpenGL may want to include\n * this file so as to get topology information for OpenGL displays.\n */\n\n#ifndef HWLOC_GL_H\n#define HWLOC_GL_H\n\n#include <hwloc.h>\n\n#include <stdio.h>\n#include <string.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_gl Interoperability with OpenGL displays\n *\n * This interface offers ways to retrieve topology information about\n * OpenGL displays.\n *\n * Only the NVIDIA display locality information is currently available,\n * using the NV-CONTROL X11 extension and the NVCtrl library.\n *\n * @{\n */\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * OpenGL display given by port and device index.\n *\n * Return the OS device object describing the OpenGL display\n * whose port (server) is \\p port and device (screen) is \\p device.\n * Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the GL component must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,\n\t\t\t\t\t  unsigned port, unsigned device)\n{\n        unsigned x = (unsigned) -1, y = (unsigned) -1;\n        hwloc_obj_t osdev = NULL;\n        while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n                if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type\n                    && osdev->name\n                    && sscanf(osdev->name, \":%u.%u\", &x, &y) == 2\n                    && port == x && device == y)\n                        return osdev;\n        }\n\terrno = EINVAL;\n        return NULL;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * OpenGL display given by name.\n *\n * Return the OS device object describing the OpenGL display\n * whose name is \\p name, built as \":port.device\" such as \":0.0\" .\n * Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the GL component must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,\n\t\t\t\t   const char *name)\n{\n        hwloc_obj_t osdev = NULL;\n        while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n                if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type\n                    && osdev->name\n                    && !strcmp(name, osdev->name))\n                        return osdev;\n        }\n\terrno = EINVAL;\n        return NULL;\n}\n\n/** \\brief Get the OpenGL display port and device corresponding\n * to the given hwloc OS object.\n *\n * Return the OpenGL display port (server) in \\p port and device (screen)\n * in \\p screen that correspond to the given hwloc OS device object.\n * Return \\c -1 if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the GL component must be enabled in the topology.\n */\nstatic __hwloc_inline int\nhwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t      hwloc_obj_t osdev,\n\t\t\t      unsigned *port, unsigned *device)\n{\n\tunsigned x = -1, y = -1;\n\tif (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type\n\t    && sscanf(osdev->name, \":%u.%u\", &x, &y) == 2) {\n\t\t*port = x;\n\t\t*device = y;\n\t\treturn 0;\n\t}\n\terrno = EINVAL;\n\treturn -1;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_GL_H */\n\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/glibc-sched.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2013 inria.  All rights reserved.\n * Copyright © 2009-2011 Université Bordeaux\n * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and glibc scheduling routines.\n *\n * Applications that use both hwloc and glibc scheduling routines such as\n * sched_getaffinity() or pthread_attr_setaffinity_np() may want to include\n * this file so as to ease conversion between their respective types.\n */\n\n#ifndef HWLOC_GLIBC_SCHED_H\n#define HWLOC_GLIBC_SCHED_H\n\n#include <hwloc.h>\n#include <hwloc/helper.h>\n#include <assert.h>\n\n#if !defined _GNU_SOURCE || !defined _SCHED_H || (!defined CPU_SETSIZE && !defined sched_priority)\n#error Please make sure to include sched.h before including glibc-sched.h, and define _GNU_SOURCE before any inclusion of sched.h\n#endif\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n#ifdef HWLOC_HAVE_CPU_SET\n\n\n/** \\defgroup hwlocality_glibc_sched Interoperability with glibc sched affinity\n *\n * This interface offers ways to convert between hwloc cpusets and glibc cpusets\n * such as those manipulated by sched_getaffinity() or pthread_attr_setaffinity_np().\n *\n * \\note Topology \\p topology must match the current machine.\n *\n * @{\n */\n\n\n/** \\brief Convert hwloc CPU set \\p toposet into glibc sched affinity CPU set \\p schedset\n *\n * This function may be used before calling sched_setaffinity or any other function\n * that takes a cpu_set_t as input parameter.\n *\n * \\p schedsetsize should be sizeof(cpu_set_t) unless \\p schedset was dynamically allocated with CPU_ALLOC\n */\nstatic __hwloc_inline int\nhwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset,\n\t\t\t\t    cpu_set_t *schedset, size_t schedsetsize)\n{\n#ifdef CPU_ZERO_S\n  unsigned cpu;\n  CPU_ZERO_S(schedsetsize, schedset);\n  hwloc_bitmap_foreach_begin(cpu, hwlocset)\n    CPU_SET_S(cpu, schedsetsize, schedset);\n  hwloc_bitmap_foreach_end();\n#else /* !CPU_ZERO_S */\n  unsigned cpu;\n  CPU_ZERO(schedset);\n  assert(schedsetsize == sizeof(cpu_set_t));\n  hwloc_bitmap_foreach_begin(cpu, hwlocset)\n    CPU_SET(cpu, schedset);\n  hwloc_bitmap_foreach_end();\n#endif /* !CPU_ZERO_S */\n  return 0;\n}\n\n/** \\brief Convert glibc sched affinity CPU set \\p schedset into hwloc CPU set\n *\n * This function may be used before calling sched_setaffinity  or any other function\n * that takes a cpu_set_t  as input parameter.\n *\n * \\p schedsetsize should be sizeof(cpu_set_t) unless \\p schedset was dynamically allocated with CPU_ALLOC\n */\nstatic __hwloc_inline int\nhwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cpuset_t hwlocset,\n                                       const cpu_set_t *schedset, size_t schedsetsize)\n{\n  int cpu;\n#ifdef CPU_ZERO_S\n  int count;\n#endif\n  hwloc_bitmap_zero(hwlocset);\n#ifdef CPU_ZERO_S\n  count = CPU_COUNT_S(schedsetsize, schedset);\n  cpu = 0;\n  while (count) {\n    if (CPU_ISSET_S(cpu, schedsetsize, schedset)) {\n      hwloc_bitmap_set(hwlocset, cpu);\n      count--;\n    }\n    cpu++;\n  }\n#else /* !CPU_ZERO_S */\n  /* sched.h does not support dynamic cpu_set_t (introduced in glibc 2.7),\n   * assume we have a very old interface without CPU_COUNT (added in 2.6)\n   */\n  assert(schedsetsize == sizeof(cpu_set_t));\n  for(cpu=0; cpu<CPU_SETSIZE; cpu++)\n    if (CPU_ISSET(cpu, schedset))\n      hwloc_bitmap_set(hwlocset, cpu);\n#endif /* !CPU_ZERO_S */\n  return 0;\n}\n\n/** @} */\n\n\n#endif /* CPU_SET */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_GLIBC_SCHED_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/helper.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2016 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2010 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief High-level hwloc traversal helpers.\n */\n\n#ifndef HWLOC_HELPER_H\n#define HWLOC_HELPER_H\n\n#ifndef HWLOC_H\n#error Please include the main hwloc.h instead\n#endif\n\n#include <stdlib.h>\n#include <errno.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_helper_find_inside Finding Objects inside a CPU set\n * @{\n */\n\n/** \\brief Get the first largest object included in the given cpuset \\p set.\n *\n * \\return the first object that is included in \\p set and whose parent is not.\n *\n * This is convenient for iterating over all largest objects within a CPU set\n * by doing a loop getting the first largest object and clearing its CPU set\n * from the remaining CPU set.\n *\n * \\note This function cannot work if the root object does not have a CPU set,\n * e.g. if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t set)\n{\n  hwloc_obj_t obj = hwloc_get_root_obj(topology);\n  if (!obj->cpuset || !hwloc_bitmap_intersects(obj->cpuset, set))\n    return NULL;\n  while (!hwloc_bitmap_isincluded(obj->cpuset, set)) {\n    /* while the object intersects without being included, look at its children */\n    hwloc_obj_t child = obj->first_child;\n    while (child) {\n      if (child->cpuset && hwloc_bitmap_intersects(child->cpuset, set))\n\tbreak;\n      child = child->next_sibling;\n    }\n    if (!child)\n      /* no child intersects, return their father */\n      return obj;\n    /* found one intersecting child, look at its children */\n    obj = child;\n  }\n  /* obj is included, return it */\n  return obj;\n}\n\n/** \\brief Get the set of largest objects covering exactly a given cpuset \\p set\n *\n * \\return the number of objects returned in \\p objs.\n *\n * \\note This function cannot work if the root object does not have a CPU set,\n * e.g. if the topology is made of different machines.\n */\nHWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t\t hwloc_obj_t * __hwloc_restrict objs, int max);\n\n/** \\brief Return the next object at depth \\p depth included in CPU set \\p set.\n *\n * If \\p prev is \\c NULL, return the first object at depth \\p depth\n * included in \\p set.  The next invokation should pass the previous\n * return value in \\p prev so as to obtain the next object in \\p set.\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects at the given depth do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t   unsigned depth, hwloc_obj_t prev)\n{\n  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);\n  if (!next || !next->cpuset)\n    return NULL;\n  while (next && (hwloc_bitmap_iszero(next->cpuset) || !hwloc_bitmap_isincluded(next->cpuset, set)))\n    next = next->next_cousin;\n  return next;\n}\n\n/** \\brief Return the next object of type \\p type included in CPU set \\p set.\n *\n * If there are multiple or no depth for given type, return \\c NULL\n * and let the caller fallback to\n * hwloc_get_next_obj_inside_cpuset_by_depth().\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects of the given type do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t  hwloc_obj_type_t type, hwloc_obj_t prev)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return NULL;\n  return hwloc_get_next_obj_inside_cpuset_by_depth(topology, set, depth, prev);\n}\n\n/** \\brief Return the (logically) \\p idx -th object at depth \\p depth included in CPU set \\p set.\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects at the given depth do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t      unsigned depth, unsigned idx) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t      unsigned depth, unsigned idx)\n{\n  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);\n  unsigned count = 0;\n  if (!obj || !obj->cpuset)\n    return NULL;\n  while (obj) {\n    if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {\n      if (count == idx)\n\treturn obj;\n      count++;\n    }\n    obj = obj->next_cousin;\n  }\n  return NULL;\n}\n\n/** \\brief Return the \\p idx -th object of type \\p type included in CPU set \\p set.\n *\n * If there are multiple or no depth for given type, return \\c NULL\n * and let the caller fallback to\n * hwloc_get_obj_inside_cpuset_by_depth().\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects of the given type do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t     hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t     hwloc_obj_type_t type, unsigned idx)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return NULL;\n  return hwloc_get_obj_inside_cpuset_by_depth(topology, set, depth, idx);\n}\n\n/** \\brief Return the number of objects at depth \\p depth included in CPU set \\p set.\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects at the given depth do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline unsigned\nhwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t unsigned depth) __hwloc_attribute_pure;\nstatic __hwloc_inline unsigned\nhwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t unsigned depth)\n{\n  hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);\n  unsigned count = 0;\n  if (!obj || !obj->cpuset)\n    return 0;\n  while (obj) {\n    if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))\n      count++;\n    obj = obj->next_cousin;\n  }\n  return count;\n}\n\n/** \\brief Return the number of objects of type \\p type included in CPU set \\p set.\n *\n * If no object for that type exists inside CPU set \\p set, 0 is\n * returned.  If there are several levels with objects of that type\n * inside CPU set \\p set, -1 is returned.\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n *\n * \\note This function cannot work if objects of the given type do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline int\nhwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\thwloc_obj_type_t type) __hwloc_attribute_pure;\nstatic __hwloc_inline int\nhwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\thwloc_obj_type_t type)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)\n    return 0;\n  if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return -1; /* FIXME: agregate nbobjs from different levels? */\n  return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);\n}\n\n/** \\brief Return the logical index among the objects included in CPU set \\p set.\n *\n * Consult all objects in the same level as \\p obj and inside CPU set \\p set\n * in the logical order, and return the index of \\p obj within them.\n * If \\p set covers the entire topology, this is the logical index of \\p obj.\n * Otherwise, this is similar to a logical index within the part of the topology\n * defined by CPU set \\p set.\n *\n * \\note Objects with empty CPU sets are ignored\n * (otherwise they would be considered included in any given set).\n */\nstatic __hwloc_inline int\nhwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,\n\t\t\t\t   hwloc_obj_t obj) __hwloc_attribute_pure;\nstatic __hwloc_inline int\nhwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,\n\t\t\t\t   hwloc_obj_t obj)\n{\n  int idx = 0;\n  if (!hwloc_bitmap_isincluded(obj->cpuset, set))\n    return -1;\n  /* count how many objects are inside the cpuset on the way from us to the beginning of the level */\n  while ((obj = obj->prev_cousin) != NULL)\n    if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set))\n      idx++;\n  return idx;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_find_covering Finding Objects covering at least CPU set\n * @{\n */\n\n/** \\brief Get the child covering at least CPU set \\p set.\n *\n * \\return \\c NULL if no child matches or if \\p set is empty.\n *\n * \\note This function cannot work if parent does not have a CPU set.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,\n\t\t\t\thwloc_obj_t parent) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,\n\t\t\t\thwloc_obj_t parent)\n{\n  hwloc_obj_t child;\n  if (!parent->cpuset || hwloc_bitmap_iszero(set))\n    return NULL;\n  child = parent->first_child;\n  while (child) {\n    if (child->cpuset && hwloc_bitmap_isincluded(set, child->cpuset))\n      return child;\n    child = child->next_sibling;\n  }\n  return NULL;\n}\n\n/** \\brief Get the lowest object covering at least CPU set \\p set\n *\n * \\return \\c NULL if no object matches or if \\p set is empty.\n *\n * \\note This function cannot work if the root object does not have a CPU set,\n * e.g. if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)\n{\n  struct hwloc_obj *current = hwloc_get_root_obj(topology);\n  if (hwloc_bitmap_iszero(set) || !current->cpuset || !hwloc_bitmap_isincluded(set, current->cpuset))\n    return NULL;\n  while (1) {\n    hwloc_obj_t child = hwloc_get_child_covering_cpuset(topology, set, current);\n    if (!child)\n      return current;\n    current = child;\n  }\n}\n\n/** \\brief Iterate through same-depth objects covering at least CPU set \\p set\n *\n * If object \\p prev is \\c NULL, return the first object at depth \\p\n * depth covering at least part of CPU set \\p set.  The next\n * invokation should pass the previous return value in \\p prev so as\n * to obtain the next object covering at least another part of \\p set.\n *\n * \\note This function cannot work if objects at the given depth do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t    unsigned depth, hwloc_obj_t prev)\n{\n  hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);\n  if (!next || !next->cpuset)\n    return NULL;\n  while (next && !hwloc_bitmap_intersects(set, next->cpuset))\n    next = next->next_cousin;\n  return next;\n}\n\n/** \\brief Iterate through same-type objects covering at least CPU set \\p set\n *\n * If object \\p prev is \\c NULL, return the first object of type \\p\n * type covering at least part of CPU set \\p set.  The next invokation\n * should pass the previous return value in \\p prev so as to obtain\n * the next object of type \\p type covering at least another part of\n * \\p set.\n *\n * If there are no or multiple depths for type \\p type, \\c NULL is returned.\n * The caller may fallback to hwloc_get_next_obj_covering_cpuset_by_depth()\n * for each depth.\n *\n * \\note This function cannot work if objects of the given type do\n * not have CPU sets or if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,\n\t\t\t\t\t   hwloc_obj_type_t type, hwloc_obj_t prev)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return NULL;\n  return hwloc_get_next_obj_covering_cpuset_by_depth(topology, set, depth, prev);\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_ancestors Looking at Ancestor and Child Objects\n * @{\n *\n * Be sure to see the figure in \\ref termsanddefs that shows a\n * complete topology tree, including depths, child/sibling/cousin\n * relationships, and an example of an asymmetric topology where one\n * package has fewer caches than its peers.\n */\n\n/** \\brief Returns the ancestor object of \\p obj at depth \\p depth. */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj)\n{\n  hwloc_obj_t ancestor = obj;\n  if (obj->depth < depth)\n    return NULL;\n  while (ancestor && ancestor->depth > depth)\n    ancestor = ancestor->parent;\n  return ancestor;\n}\n\n/** \\brief Returns the ancestor object of \\p obj with type \\p type. */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_ancestor_obj_by_type (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_type_t type, hwloc_obj_t obj)\n{\n  hwloc_obj_t ancestor = obj->parent;\n  while (ancestor && ancestor->type != type)\n    ancestor = ancestor->parent;\n  return ancestor;\n}\n\n/** \\brief Returns the common parent object to objects \\p obj1 and \\p obj2 */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_common_ancestor_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj1, hwloc_obj_t obj2)\n{\n  /* the loop isn't so easy since intermediate ancestors may have\n   * different depth, causing us to alternate between using obj1->parent\n   * and obj2->parent. Also, even if at some point we find ancestors of\n   * of the same depth, their ancestors may have different depth again.\n   */\n  while (obj1 != obj2) {\n    while (obj1->depth > obj2->depth)\n      obj1 = obj1->parent;\n    while (obj2->depth > obj1->depth)\n      obj2 = obj2->parent;\n    if (obj1 != obj2 && obj1->depth == obj2->depth) {\n      obj1 = obj1->parent;\n      obj2 = obj2->parent;\n    }\n  }\n  return obj1;\n}\n\n/** \\brief Returns true if \\p obj is inside the subtree beginning with ancestor object \\p subtree_root.\n *\n * \\note This function assumes that both \\p obj and \\p subtree_root have a \\p cpuset.\n */\nstatic __hwloc_inline int\nhwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root) __hwloc_attribute_pure;\nstatic __hwloc_inline int\nhwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj, hwloc_obj_t subtree_root)\n{\n  return hwloc_bitmap_isincluded(obj->cpuset, subtree_root->cpuset);\n}\n\n/** \\brief Return the next child.\n *\n * If \\p prev is \\c NULL, return the first child.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t parent, hwloc_obj_t prev)\n{\n  if (!prev)\n    return parent->first_child;\n  if (prev->parent != parent)\n    return NULL;\n  return prev->next_sibling;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_find_cache Looking at Cache Objects\n * @{\n */\n\n/** \\brief Find the depth of cache objects matching cache depth and type.\n *\n * Return the depth of the topology level that contains cache objects\n * whose attributes match \\p cachedepth and \\p cachetype. This function\n * intends to disambiguate the case where hwloc_get_type_depth() returns\n * ::HWLOC_TYPE_DEPTH_MULTIPLE.\n *\n * If no cache level matches, ::HWLOC_TYPE_DEPTH_UNKNOWN is returned.\n *\n * If \\p cachetype is ::HWLOC_OBJ_CACHE_UNIFIED, the depth of the\n * unique matching unified cache level is returned.\n *\n * If \\p cachetype is ::HWLOC_OBJ_CACHE_DATA or ::HWLOC_OBJ_CACHE_INSTRUCTION,\n * either a matching cache, or a unified cache is returned.\n *\n * If \\p cachetype is \\c -1, it is ignored and multiple levels may\n * match. The function returns either the depth of a uniquely matching\n * level or ::HWLOC_TYPE_DEPTH_MULTIPLE.\n */\nstatic __hwloc_inline int\nhwloc_get_cache_type_depth (hwloc_topology_t topology,\n\t\t\t    unsigned cachelevel, hwloc_obj_cache_type_t cachetype)\n{\n  int depth;\n  int found = HWLOC_TYPE_DEPTH_UNKNOWN;\n  for (depth=0; ; depth++) {\n    hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);\n    if (!obj)\n      break;\n    if (obj->type != HWLOC_OBJ_CACHE || obj->attr->cache.depth != cachelevel)\n      /* doesn't match, try next depth */\n      continue;\n    if (cachetype == (hwloc_obj_cache_type_t) -1) {\n      if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {\n\t/* second match, return MULTIPLE */\n        return HWLOC_TYPE_DEPTH_MULTIPLE;\n      }\n      /* first match, mark it as found */\n      found = depth;\n      continue;\n    }\n    if (obj->attr->cache.type == cachetype || obj->attr->cache.type == HWLOC_OBJ_CACHE_UNIFIED)\n      /* exact match (either unified is alone, or we match instruction or data), return immediately */\n      return depth;\n  }\n  /* went to the bottom, return what we found */\n  return found;\n}\n\n/** \\brief Get the first cache covering a cpuset \\p set\n *\n * \\return \\c NULL if no cache matches.\n *\n * \\note This function cannot work if the root object does not have a CPU set,\n * e.g. if the topology is made of different machines.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_cache_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set)\n{\n  hwloc_obj_t current = hwloc_get_obj_covering_cpuset(topology, set);\n  while (current) {\n    if (current->type == HWLOC_OBJ_CACHE)\n      return current;\n    current = current->parent;\n  }\n  return NULL;\n}\n\n/** \\brief Get the first cache shared between an object and somebody else.\n *\n * \\return \\c NULL if no cache matches or if an invalid object is given.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_obj_t obj)\n{\n  hwloc_obj_t current = obj->parent;\n  if (!obj->cpuset)\n    return NULL;\n  while (current && current->cpuset) {\n    if (!hwloc_bitmap_isequal(current->cpuset, obj->cpuset)\n        && current->type == HWLOC_OBJ_CACHE)\n      return current;\n    current = current->parent;\n  }\n  return NULL;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_find_misc Finding objects, miscellaneous helpers\n * @{\n *\n * Be sure to see the figure in \\ref termsanddefs that shows a\n * complete topology tree, including depths, child/sibling/cousin\n * relationships, and an example of an asymmetric topology where one\n * package has fewer caches than its peers.\n */\n\n/** \\brief Returns the object of type ::HWLOC_OBJ_PU with \\p os_index.\n *\n * This function is useful for converting a CPU set into the PU\n * objects it contains.\n * When retrieving the current binding (e.g. with hwloc_get_cpubind()),\n * one may iterate over the bits of the resulting CPU set with\n * hwloc_bitmap_foreach_begin(), and find the corresponding PUs\n * with this function.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_pu_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)\n{\n  hwloc_obj_t obj = NULL;\n  while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PU, obj)) != NULL)\n    if (obj->os_index == os_index)\n      return obj;\n  return NULL;\n}\n\n/** \\brief Returns the object of type ::HWLOC_OBJ_NUMANODE with \\p os_index.\n *\n * This function is useful for converting a nodeset into the NUMA node\n * objects it contains.\n * When retrieving the current binding (e.g. with hwloc_get_membind_nodeset()),\n * one may iterate over the bits of the resulting nodeset with\n * hwloc_bitmap_foreach_begin(), and find the corresponding NUMA nodes\n * with this function.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_numanode_obj_by_os_index(hwloc_topology_t topology, unsigned os_index)\n{\n  hwloc_obj_t obj = NULL;\n  while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)\n    if (obj->os_index == os_index)\n      return obj;\n  return NULL;\n}\n\n/** \\brief Do a depth-first traversal of the topology to find and sort\n *\n * all objects that are at the same depth than \\p src.\n * Report in \\p objs up to \\p max physically closest ones to \\p src.\n *\n * \\return the number of objects returned in \\p objs.\n *\n * \\return 0 if \\p src is an I/O object.\n *\n * \\note This function requires the \\p src object to have a CPU set.\n */\n/* TODO: rather provide an iterator? Provide a way to know how much should be allocated? By returning the total number of objects instead? */\nHWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc_obj_t src, hwloc_obj_t * __hwloc_restrict objs, unsigned max);\n\n/** \\brief Find an object below another object, both specified by types and indexes.\n *\n * Start from the top system object and find object of type \\p type1\n * and logical index \\p idx1.  Then look below this object and find another\n * object of type \\p type2 and logical index \\p idx2.  Indexes are specified\n * within the parent, not withing the entire system.\n *\n * For instance, if type1 is PACKAGE, idx1 is 2, type2 is CORE and idx2\n * is 3, return the fourth core object below the third package.\n *\n * \\note This function requires these objects to have a CPU set.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_below_by_type (hwloc_topology_t topology,\n\t\t\t     hwloc_obj_type_t type1, unsigned idx1,\n\t\t\t     hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_below_by_type (hwloc_topology_t topology,\n\t\t\t     hwloc_obj_type_t type1, unsigned idx1,\n\t\t\t     hwloc_obj_type_t type2, unsigned idx2)\n{\n  hwloc_obj_t obj;\n  obj = hwloc_get_obj_by_type (topology, type1, idx1);\n  if (!obj || !obj->cpuset)\n    return NULL;\n  return hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, type2, idx2);\n}\n\n/** \\brief Find an object below a chain of objects specified by types and indexes.\n *\n * This is a generalized version of hwloc_get_obj_below_by_type().\n *\n * Arrays \\p typev and \\p idxv must contain \\p nr types and indexes.\n *\n * Start from the top system object and walk the arrays \\p typev and \\p idxv.\n * For each type and logical index couple in the arrays, look under the previously found\n * object to find the index-th object of the given type.\n * Indexes are specified within the parent, not withing the entire system.\n *\n * For instance, if nr is 3, typev contains NODE, PACKAGE and CORE,\n * and idxv contains 0, 1 and 2, return the third core object below\n * the second package below the first NUMA node.\n *\n * \\note This function requires all these objects and the root object\n * to have a CPU set.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_below_array_by_type (hwloc_topology_t topology, int nr, hwloc_obj_type_t *typev, unsigned *idxv)\n{\n  hwloc_obj_t obj = hwloc_get_root_obj(topology);\n  int i;\n  for(i=0; i<nr; i++) {\n    if (!obj || !obj->cpuset)\n      return NULL;\n    obj = hwloc_get_obj_inside_cpuset_by_type(topology, obj->cpuset, typev[i], idxv[i]);\n  }\n  return obj;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_distribute Distributing items over a topology\n * @{\n */\n\n/** \\brief Flags to be given to hwloc_distrib().\n */\nenum hwloc_distrib_flags_e {\n  /** \\brief Distrib in reverse order, starting from the last objects.\n   * \\hideinitializer\n   */\n  HWLOC_DISTRIB_FLAG_REVERSE = (1UL<<0)\n};\n\n/** \\brief Distribute \\p n items over the topology under \\p roots\n *\n * Array \\p set will be filled with \\p n cpusets recursively distributed\n * linearly over the topology under objects \\p roots, down to depth \\p until\n * (which can be INT_MAX to distribute down to the finest level).\n *\n * \\p n_roots is usually 1 and \\p roots only contains the topology root object\n * so as to distribute over the entire topology.\n *\n * This is typically useful when an application wants to distribute \\p n\n * threads over a machine, giving each of them as much private cache as\n * possible and keeping them locally in number order.\n *\n * The caller may typically want to also call hwloc_bitmap_singlify()\n * before binding a thread so that it does not move at all.\n *\n * \\p flags should be 0 or a OR'ed set of ::hwloc_distrib_flags_e.\n *\n * \\note This function requires the \\p roots objects to have a CPU set.\n *\n * \\note This function replaces the now deprecated hwloc_distribute()\n * and hwloc_distributev() functions.\n */\nstatic __hwloc_inline int\nhwloc_distrib(hwloc_topology_t topology,\n\t      hwloc_obj_t *roots, unsigned n_roots,\n\t      hwloc_cpuset_t *set,\n\t      unsigned n,\n\t      unsigned until, unsigned long flags)\n{\n  unsigned i;\n  unsigned tot_weight;\n  unsigned given, givenweight;\n  hwloc_cpuset_t *cpusetp = set;\n\n  if (flags & ~HWLOC_DISTRIB_FLAG_REVERSE) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  tot_weight = 0;\n  for (i = 0; i < n_roots; i++)\n    if (roots[i]->cpuset)\n      tot_weight += hwloc_bitmap_weight(roots[i]->cpuset);\n\n  for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {\n    unsigned chunk, weight;\n    hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];\n    hwloc_cpuset_t cpuset = root->cpuset;\n    if (!cpuset)\n      continue;\n    weight = hwloc_bitmap_weight(cpuset);\n    if (!weight)\n      continue;\n    /* Give to root a chunk proportional to its weight.\n     * If previous chunks got rounded-up, we may get a bit less. */\n    chunk = (( (givenweight+weight) * n  + tot_weight-1) / tot_weight)\n          - ((  givenweight         * n  + tot_weight-1) / tot_weight);\n    if (!root->arity || chunk <= 1 || root->depth >= until) {\n      /* We can't split any more, put everything there.  */\n      if (chunk) {\n\t/* Fill cpusets with ours */\n\tunsigned j;\n\tfor (j=0; j < chunk; j++)\n\t  cpusetp[j] = hwloc_bitmap_dup(cpuset);\n      } else {\n\t/* We got no chunk, just merge our cpuset to a previous one\n\t * (the first chunk cannot be empty)\n\t * so that this root doesn't get ignored.\n\t */\n\tassert(given);\n\thwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);\n      }\n    } else {\n      /* Still more to distribute, recurse into children */\n      hwloc_distrib(topology, root->children, root->arity, cpusetp, chunk, until, flags);\n    }\n    cpusetp += chunk;\n    given += chunk;\n    givenweight += weight;\n  }\n\n  return 0;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies\n * @{\n */\n/** \\brief Get complete CPU set\n *\n * \\return the complete CPU set of logical processors of the system. If the\n * topology is the result of a combination of several systems, NULL is\n * returned.\n *\n * \\note The returned cpuset is not newly allocated and should thus not be\n * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_complete_cpuset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->complete_cpuset;\n}\n\n/** \\brief Get topology CPU set\n *\n * \\return the CPU set of logical processors of the system for which hwloc\n * provides topology information. This is equivalent to the cpuset of the\n * system object. If the topology is the result of a combination of several\n * systems, NULL is returned.\n *\n * \\note The returned cpuset is not newly allocated and should thus not be\n * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_topology_cpuset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->cpuset;\n}\n\n/** \\brief Get online CPU set\n *\n * \\return the CPU set of online logical processors of the system. If the\n * topology is the result of a combination of several systems, NULL is\n * returned.\n *\n * \\note The returned cpuset is not newly allocated and should thus not be\n * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_online_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_online_cpuset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->online_cpuset;\n}\n\n/** \\brief Get allowed CPU set\n *\n * \\return the CPU set of allowed logical processors of the system. If the\n * topology is the result of a combination of several systems, NULL is\n * returned.\n *\n * \\note The returned cpuset is not newly allocated and should thus not be\n * changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_cpuset_t\nhwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->allowed_cpuset;\n}\n\n/** \\brief Get complete node set\n *\n * \\return the complete node set of memory of the system. If the\n * topology is the result of a combination of several systems, NULL is\n * returned.\n *\n * \\note The returned nodeset is not newly allocated and should thus not be\n * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_complete_nodeset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->complete_nodeset;\n}\n\n/** \\brief Get topology node set\n *\n * \\return the node set of memory of the system for which hwloc\n * provides topology information. This is equivalent to the nodeset of the\n * system object. If the topology is the result of a combination of several\n * systems, NULL is returned.\n *\n * \\note The returned nodeset is not newly allocated and should thus not be\n * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_topology_nodeset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->nodeset;\n}\n\n/** \\brief Get allowed node set\n *\n * \\return the node set of allowed memory of the system. If the\n * topology is the result of a combination of several systems, NULL is\n * returned.\n *\n * \\note The returned nodeset is not newly allocated and should thus not be\n * changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.\n */\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;\nstatic __hwloc_inline hwloc_const_nodeset_t\nhwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)\n{\n  return hwloc_get_root_obj(topology)->allowed_nodeset;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_helper_nodeset_convert Converting between CPU sets and node sets\n *\n * There are two semantics for converting cpusets to nodesets depending on how\n * non-NUMA machines are handled.\n *\n * When manipulating nodesets for memory binding, non-NUMA machines should be\n * considered as having a single NUMA node. The standard conversion routines\n * below should be used so that marking the first bit of the nodeset means\n * that memory should be bound to a non-NUMA whole machine.\n *\n * When manipulating nodesets as an actual list of NUMA nodes without any\n * need to handle memory binding on non-NUMA machines, the strict conversion\n * routines may be used instead.\n * @{\n */\n\n/** \\brief Convert a CPU set into a NUMA node set and handle non-NUMA cases\n *\n * If some NUMA nodes have no CPUs at all, this function never sets their\n * indexes in the output node set, even if a full CPU set is given in input.\n *\n * If the topology contains no NUMA nodes, the machine is considered\n * as a single memory node, and the following behavior is used:\n * If \\p cpuset is empty, \\p nodeset will be emptied as well.\n * Otherwise \\p nodeset will be entirely filled.\n */\nstatic __hwloc_inline void\nhwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)\n{\n\tint depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\thwloc_obj_t obj;\n\n\tif (depth == HWLOC_TYPE_DEPTH_UNKNOWN) {\n\t\t if (hwloc_bitmap_iszero(_cpuset))\n\t\t\thwloc_bitmap_zero(nodeset);\n\t\telse\n\t\t\t/* Assume the whole system */\n\t\t\thwloc_bitmap_fill(nodeset);\n\t\treturn;\n\t}\n\n\thwloc_bitmap_zero(nodeset);\n\tobj = NULL;\n\twhile ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)\n\t\thwloc_bitmap_set(nodeset, obj->os_index);\n}\n\n/** \\brief Convert a CPU set into a NUMA node set without handling non-NUMA cases\n *\n * This is the strict variant of hwloc_cpuset_to_nodeset(). It does not fix\n * non-NUMA cases. If the topology contains some NUMA nodes, behave exactly\n * the same. However, if the topology contains no NUMA nodes, return an empty\n * nodeset.\n */\nstatic __hwloc_inline void\nhwloc_cpuset_to_nodeset_strict(struct hwloc_topology *topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)\n{\n\tint depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\thwloc_obj_t obj;\n\tif (depth == HWLOC_TYPE_DEPTH_UNKNOWN )\n\t\treturn;\n\thwloc_bitmap_zero(nodeset);\n\tobj = NULL;\n\twhile ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)\n\t\thwloc_bitmap_set(nodeset, obj->os_index);\n}\n\n/** \\brief Convert a NUMA node set into a CPU set and handle non-NUMA cases\n *\n * If the topology contains no NUMA nodes, the machine is considered\n * as a single memory node, and the following behavior is used:\n * If \\p nodeset is empty, \\p cpuset will be emptied as well.\n * Otherwise \\p cpuset will be entirely filled.\n * This is useful for manipulating memory binding sets.\n */\nstatic __hwloc_inline void\nhwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)\n{\n\tint depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\thwloc_obj_t obj;\n\n\tif (depth == HWLOC_TYPE_DEPTH_UNKNOWN ) {\n\t\tif (hwloc_bitmap_iszero(nodeset))\n\t\t\thwloc_bitmap_zero(_cpuset);\n\t\telse\n\t\t\t/* Assume the whole system */\n\t\t\thwloc_bitmap_fill(_cpuset);\n\t\treturn;\n\t}\n\n\thwloc_bitmap_zero(_cpuset);\n\tobj = NULL;\n\twhile ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {\n\t\tif (hwloc_bitmap_isset(nodeset, obj->os_index))\n\t\t\t/* no need to check obj->cpuset because objects in levels always have a cpuset */\n\t\t\thwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);\n\t}\n}\n\n/** \\brief Convert a NUMA node set into a CPU set without handling non-NUMA cases\n *\n * This is the strict variant of hwloc_cpuset_from_nodeset(). It does not fix\n * non-NUMA cases. If the topology contains some NUMA nodes, behave exactly\n * the same. However, if the topology contains no NUMA nodes, return an empty\n * cpuset.\n */\nstatic __hwloc_inline void\nhwloc_cpuset_from_nodeset_strict(struct hwloc_topology *topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)\n{\n\tint depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\thwloc_obj_t obj;\n\tif (depth == HWLOC_TYPE_DEPTH_UNKNOWN )\n\t\treturn;\n\thwloc_bitmap_zero(_cpuset);\n\tobj = NULL;\n\twhile ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL)\n\t\tif (hwloc_bitmap_isset(nodeset, obj->os_index))\n\t\t\t/* no need to check obj->cpuset because objects in levels always have a cpuset */\n\t\t\thwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset);\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_distances Manipulating Distances\n * @{\n */\n\n/** \\brief Get the distances between all objects at the given depth.\n *\n * \\return a distances structure containing a matrix with all distances\n * between all objects at the given depth.\n *\n * Slot i+nbobjs*j contains the distance from the object of logical index i\n * the object of logical index j.\n *\n * \\note This function only returns matrices covering the whole topology,\n * without any unknown distance value. Those matrices are available in\n * top-level object of the hierarchy. Matrices of lower objects are not\n * reported here since they cover only part of the machine.\n *\n * The returned structure belongs to the hwloc library. The caller should\n * not modify or free it.\n *\n * \\return \\c NULL if no such distance matrix exists.\n */\n\nstatic __hwloc_inline const struct hwloc_distances_s *\nhwloc_get_whole_distance_matrix_by_depth(hwloc_topology_t topology, unsigned depth)\n{\n  hwloc_obj_t root = hwloc_get_root_obj(topology);\n  unsigned i;\n  for(i=0; i<root->distances_count; i++)\n    if (root->distances[i]->relative_depth == depth)\n      return root->distances[i];\n  return NULL;\n}\n\n/** \\brief Get the distances between all objects of a given type.\n *\n * \\return a distances structure containing a matrix with all distances\n * between all objects of the given type.\n *\n * Slot i+nbobjs*j contains the distance from the object of logical index i\n * the object of logical index j.\n *\n * \\note This function only returns matrices covering the whole topology,\n * without any unknown distance value. Those matrices are available in\n * top-level object of the hierarchy. Matrices of lower objects are not\n * reported here since they cover only part of the machine.\n *\n * The returned structure belongs to the hwloc library. The caller should\n * not modify or free it.\n *\n * \\return \\c NULL if no such distance matrix exists.\n */\n\nstatic __hwloc_inline const struct hwloc_distances_s *\nhwloc_get_whole_distance_matrix_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth < 0)\n    return NULL;\n  return hwloc_get_whole_distance_matrix_by_depth(topology, depth);\n}\n\n/** \\brief Get distances for the given depth and covering some objects\n *\n * Return a distance matrix that describes depth \\p depth and covers at\n * least object \\p obj and all its children.\n *\n * When looking for the distance between some objects, a common ancestor should\n * be passed in \\p obj.\n *\n * \\p firstp is set to logical index of the first object described by the matrix.\n *\n * The returned structure belongs to the hwloc library. The caller should\n * not modify or free it.\n */\nstatic __hwloc_inline const struct hwloc_distances_s *\nhwloc_get_distance_matrix_covering_obj_by_depth(hwloc_topology_t topology,\n\t\t\t\t\t\thwloc_obj_t obj, unsigned depth,\n\t\t\t\t\t\tunsigned *firstp)\n{\n  while (obj && obj->cpuset) {\n    unsigned i;\n    for(i=0; i<obj->distances_count; i++)\n      if (obj->distances[i]->relative_depth == depth - obj->depth) {\n\tif (!obj->distances[i]->nbobjs)\n\t  continue;\n\t*firstp = hwloc_get_next_obj_inside_cpuset_by_depth(topology, obj->cpuset, depth, NULL)->logical_index;\n\treturn obj->distances[i];\n      }\n    obj = obj->parent;\n  }\n  return NULL;\n}\n\n/** \\brief Get the latency in both directions between two objects.\n *\n * Look at ancestor objects from the bottom to the top until one of them\n * contains a distance matrix that matches the objects exactly.\n *\n * \\p latency gets the value from object \\p obj1 to \\p obj2, while\n * \\p reverse_latency gets the reverse-direction value, which\n * may be different on some architectures.\n *\n * \\return -1 if no ancestor contains a matching latency matrix.\n */\nstatic __hwloc_inline int\nhwloc_get_latency(hwloc_topology_t topology,\n\t\t   hwloc_obj_t obj1, hwloc_obj_t obj2,\n\t\t   float *latency, float *reverse_latency)\n{\n  hwloc_obj_t ancestor;\n  const struct hwloc_distances_s * distances;\n  unsigned first_logical ;\n\n  if (obj1->depth != obj2->depth) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  ancestor = hwloc_get_common_ancestor_obj(topology, obj1, obj2);\n  distances = hwloc_get_distance_matrix_covering_obj_by_depth(topology, ancestor, obj1->depth, &first_logical);\n  if (distances && distances->latency) {\n    const float * latency_matrix = distances->latency;\n    unsigned nbobjs = distances->nbobjs;\n    unsigned l1 = obj1->logical_index - first_logical;\n    unsigned l2 = obj2->logical_index - first_logical;\n    *latency = latency_matrix[l1*nbobjs+l2];\n    *reverse_latency = latency_matrix[l2*nbobjs+l1];\n    return 0;\n  }\n\n  errno = ENOSYS;\n  return -1;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_advanced_io Finding I/O objects\n * @{\n */\n\n/** \\brief Get the first non-I/O ancestor object.\n *\n * Given the I/O object \\p ioobj, find the smallest non-I/O ancestor\n * object. This regular object may then be used for binding because\n * its locality is the same as \\p ioobj.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t      hwloc_obj_t ioobj)\n{\n  hwloc_obj_t obj = ioobj;\n  while (obj && !obj->cpuset) {\n    obj = obj->parent;\n  }\n  return obj;\n}\n\n/** \\brief Get the next PCI device in the system.\n *\n * \\return the first PCI device if \\p prev is \\c NULL.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)\n{\n  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_PCI_DEVICE, prev);\n}\n\n/** \\brief Find the PCI device object matching the PCI bus id\n * given domain, bus device and function PCI bus id.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_pcidev_by_busid(hwloc_topology_t topology,\n\t\t\t  unsigned domain, unsigned bus, unsigned dev, unsigned func)\n{\n  hwloc_obj_t obj = NULL;\n  while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {\n    if (obj->attr->pcidev.domain == domain\n\t&& obj->attr->pcidev.bus == bus\n\t&& obj->attr->pcidev.dev == dev\n\t&& obj->attr->pcidev.func == func)\n      return obj;\n  }\n  return NULL;\n}\n\n/** \\brief Find the PCI device object matching the PCI bus id\n * given as a string xxxx:yy:zz.t or yy:zz.t.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_pcidev_by_busidstring(hwloc_topology_t topology, const char *busid)\n{\n  unsigned domain = 0; /* default */\n  unsigned bus, dev, func;\n\n  if (sscanf(busid, \"%x:%x.%x\", &bus, &dev, &func) != 3\n      && sscanf(busid, \"%x:%x:%x.%x\", &domain, &bus, &dev, &func) != 4) {\n    errno = EINVAL;\n    return NULL;\n  }\n\n  return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, func);\n}\n\n/** \\brief Get the next OS device in the system.\n *\n * \\return the first OS device if \\p prev is \\c NULL.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_osdev(hwloc_topology_t topology, hwloc_obj_t prev)\n{\n  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_OS_DEVICE, prev);\n}\n\n/** \\brief Get the next bridge in the system.\n *\n * \\return the first bridge if \\p prev is \\c NULL.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)\n{\n  return hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_BRIDGE, prev);\n}\n\n/* \\brief Checks whether a given bridge covers a given PCI bus.\n */\nstatic __hwloc_inline int\nhwloc_bridge_covers_pcibus(hwloc_obj_t bridge,\n\t\t\t   unsigned domain, unsigned bus)\n{\n  return bridge->type == HWLOC_OBJ_BRIDGE\n    && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI\n    && bridge->attr->bridge.downstream.pci.domain == domain\n    && bridge->attr->bridge.downstream.pci.secondary_bus <= bus\n    && bridge->attr->bridge.downstream.pci.subordinate_bus >= bus;\n}\n\n/** \\brief Find the hostbridge that covers the given PCI bus.\n *\n * This is useful for finding the locality of a bus because\n * it is the hostbridge parent cpuset.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_hostbridge_by_pcibus(hwloc_topology_t topology,\n\t\t\t       unsigned domain, unsigned bus)\n{\n  hwloc_obj_t obj = NULL;\n  while ((obj = hwloc_get_next_bridge(topology, obj)) != NULL) {\n    if (hwloc_bridge_covers_pcibus(obj, domain, bus)) {\n      /* found bridge covering this pcibus, make sure it's a hostbridge */\n      assert(obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_HOST);\n      assert(obj->parent->type != HWLOC_OBJ_BRIDGE);\n      assert(obj->parent->cpuset);\n      return obj;\n    }\n  }\n  return NULL;\n}\n\n/** @} */\n\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_HELPER_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/inlines.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2013 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2010 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/**\n * This file contains the inline code of functions declared in hwloc.h\n */\n\n#ifndef HWLOC_INLINES_H\n#define HWLOC_INLINES_H\n\n#ifndef HWLOC_H\n#error Please include the main hwloc.h instead\n#endif\n\n#include <stdlib.h>\n#include <errno.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstatic __hwloc_inline int\nhwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)\n    return depth;\n\n  /* find the highest existing level with type order >= */\n  for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)\n    if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)\n      return depth+1;\n\n  /* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth.  */\n  /* abort(); */\n}\n\nstatic __hwloc_inline int\nhwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)\n    return depth;\n\n  /* find the lowest existing level with type order <= */\n  for(depth = 0; ; depth++)\n    if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)\n      return depth-1;\n\n  /* Shouldn't ever happen, as there is always a PU level with higher order and known depth.  */\n  /* abort(); */\n}\n\nstatic __hwloc_inline int\nhwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)\n    return 0;\n  if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return -1; /* FIXME: agregate nbobjs from different levels? */\n  return hwloc_get_nbobjs_by_depth(topology, depth);\n}\n\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)\n    return NULL;\n  if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return NULL;\n  return hwloc_get_obj_by_depth(topology, depth, idx);\n}\n\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev)\n{\n  if (!prev)\n    return hwloc_get_obj_by_depth (topology, depth, 0);\n  if (prev->depth != depth)\n    return NULL;\n  return prev->next_cousin;\n}\n\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,\n\t\t\t    hwloc_obj_t prev)\n{\n  int depth = hwloc_get_type_depth(topology, type);\n  if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)\n    return NULL;\n  return hwloc_get_next_obj_by_depth (topology, depth, prev);\n}\n\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_root_obj (hwloc_topology_t topology)\n{\n  return hwloc_get_obj_by_depth (topology, 0, 0);\n}\n\nstatic __hwloc_inline const char *\nhwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)\n{\n  unsigned i;\n  for(i=0; i<obj->infos_count; i++)\n    if (!strcmp(obj->infos[i].name, name))\n      return obj->infos[i].value;\n  return NULL;\n}\n\nstatic __hwloc_inline void *\nhwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)\n{\n  void *p = hwloc_alloc_membind_nodeset(topology, len, nodeset, policy, flags);\n  if (p)\n    return p;\n  hwloc_set_membind_nodeset(topology, nodeset, policy, flags);\n  p = hwloc_alloc(topology, len);\n  if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)\n    /* Enforce the binding by touching the data */\n    memset(p, 0, len);\n  return p;\n}\n\nstatic __hwloc_inline void *\nhwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)\n{\n  void *p = hwloc_alloc_membind(topology, len, set, policy, flags);\n  if (p)\n    return p;\n  hwloc_set_membind(topology, set, policy, flags);\n  p = hwloc_alloc(topology, len);\n  if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)\n    /* Enforce the binding by touching the data */\n    memset(p, 0, len);\n  return p;\n}\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_INLINES_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/intel-mic.h",
    "content": "/*\n * Copyright © 2013-2016 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and Intel Xeon Phi (MIC).\n *\n * Applications that use both hwloc and Intel Xeon Phi (MIC) may want to\n * include this file so as to get topology information for MIC devices.\n */\n\n#ifndef HWLOC_INTEL_MIC_H\n#define HWLOC_INTEL_MIC_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#include <hwloc/helper.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#include <dirent.h>\n#include <string.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_intel_mic Interoperability with Intel Xeon Phi (MIC)\n *\n * This interface offers ways to retrieve topology information about\n * Intel Xeon Phi (MIC) devices.\n *\n * @{\n */\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to MIC device whose index is \\p idx.\n *\n * Return the CPU set describing the locality of the MIC device whose index is \\p idx.\n *\n * Topology \\p topology and device index \\p idx must match the local machine.\n * I/O devices detection is not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_intel_mic_get_device_osdev_by_index().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux; other systems will simply get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t\t  int idx __hwloc_attribute_unused,\n\t\t\t\t  hwloc_cpuset_t set)\n{\n#ifdef HWLOC_LINUX_SYS\n\t/* If we're on Linux, use the sysfs mechanism to get the local cpus */\n#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128\n\tchar path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];\n\tDIR *sysdir = NULL;\n\tFILE *sysfile = NULL;\n\tstruct dirent *dirent;\n\tunsigned pcibus, pcidev, pcifunc;\n\n\tif (!hwloc_topology_is_thissystem(topology)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\n\tsprintf(path, \"/sys/class/mic/mic%d\", idx);\n\tsysdir = opendir(path);\n\tif (!sysdir)\n\t\treturn -1;\n\n\twhile ((dirent = readdir(sysdir)) != NULL) {\n\t\tif (sscanf(dirent->d_name, \"pci_%02x:%02x.%02x\", &pcibus, &pcidev, &pcifunc) == 3) {\n\t\t\tsprintf(path, \"/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus\", idx, pcibus, pcidev, pcifunc);\n\t\t\tsysfile = fopen(path, \"r\");\n\t\t\tif (!sysfile) {\n\t\t\t\tclosedir(sysdir);\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n\t\t\t    || hwloc_bitmap_iszero(set))\n\t\t\t\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n\t\t\tfclose(sysfile);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tclosedir(sysdir);\n#else\n\t/* Non-Linux systems simply get a full cpuset */\n\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n\treturn 0;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * MIC device for the given index.\n *\n * Return the OS device object describing the MIC device whose index is \\p idx.\n * Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology,\n\t\t\t\t\t  unsigned idx)\n{\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\tif (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type\n                    && osdev->name\n\t\t    && !strncmp(\"mic\", osdev->name, 3)\n\t\t    && atoi(osdev->name + 3) == (int) idx)\n                        return osdev;\n        }\n        return NULL;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_INTEL_MIC_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/linux-libnuma.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2014 Inria.  All rights reserved.\n * Copyright © 2009-2010, 2012 Université Bordeaux\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and Linux libnuma.\n *\n * Applications that use both Linux libnuma and hwloc may want to\n * include this file so as to ease conversion between their respective types.\n*/\n\n#ifndef HWLOC_LINUX_LIBNUMA_H\n#define HWLOC_LINUX_LIBNUMA_H\n\n#include <hwloc.h>\n#include <numa.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks\n *\n * This interface helps converting between Linux libnuma unsigned long masks\n * and hwloc cpusets and nodesets.\n *\n * It also offers a consistent behavior on non-NUMA machines\n * or non-NUMA-aware kernels by assuming that the machines have a single\n * NUMA node.\n *\n * \\note Topology \\p topology must match the current machine.\n *\n * \\note The behavior of libnuma is undefined if the kernel is not NUMA-aware.\n * (when CONFIG_NUMA is not set in the kernel configuration).\n * This helper and libnuma may thus not be strictly compatible in this case,\n * which may be detected by checking whether numa_available() returns -1.\n *\n * @{\n */\n\n\n/** \\brief Convert hwloc CPU set \\p cpuset into the array of unsigned long \\p mask\n *\n * \\p mask is the array of unsigned long that will be filled.\n * \\p maxnode contains the maximal node number that may be stored in \\p mask.\n * \\p maxnode will be set to the maximal node number that was found, plus one.\n *\n * This function may be used before calling set_mempolicy, mbind, migrate_pages\n * or any other function that takes an array of unsigned long and a maximal\n * node number as input parameter.\n */\nstatic __hwloc_inline int\nhwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,\n\t\t\t\t    unsigned long *mask, unsigned long *maxnode)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n  unsigned long outmaxnode = -1;\n\n  /* round-up to the next ulong and clear all bytes */\n  *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);\n  memset(mask, 0, *maxnode/8);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) {\n      if (node->os_index >= *maxnode)\n\tcontinue;\n      mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));\n      if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)\n\toutmaxnode = node->os_index;\n    }\n\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (!hwloc_bitmap_iszero(cpuset)) {\n      mask[0] = 1;\n      outmaxnode = 0;\n    }\n  }\n\n  *maxnode = outmaxnode+1;\n  return 0;\n}\n\n/** \\brief Convert hwloc NUMA node set \\p nodeset into the array of unsigned long \\p mask\n *\n * \\p mask is the array of unsigned long that will be filled.\n * \\p maxnode contains the maximal node number that may be stored in \\p mask.\n * \\p maxnode will be set to the maximal node number that was found, plus one.\n *\n * This function may be used before calling set_mempolicy, mbind, migrate_pages\n * or any other function that takes an array of unsigned long and a maximal\n * node number as input parameter.\n */\nstatic __hwloc_inline int\nhwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,\n\t\t\t\t      unsigned long *mask, unsigned long *maxnode)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n  unsigned long outmaxnode = -1;\n\n  /* round-up to the next ulong and clear all bytes */\n  *maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);\n  memset(mask, 0, *maxnode/8);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) {\n      if (node->os_index >= *maxnode)\n\tcontinue;\n      if (!hwloc_bitmap_isset(nodeset, node->os_index))\n\tcontinue;\n      mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));\n      if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)\n\toutmaxnode = node->os_index;\n    }\n\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (!hwloc_bitmap_iszero(nodeset)) {\n      mask[0] = 1;\n      outmaxnode = 0;\n    }\n  }\n\n  *maxnode = outmaxnode+1;\n  return 0;\n}\n\n/** \\brief Convert the array of unsigned long \\p mask into hwloc CPU set\n *\n * \\p mask is a array of unsigned long that will be read.\n * \\p maxnode contains the maximal node number that may be read in \\p mask.\n *\n * This function may be used after calling get_mempolicy or any other function\n * that takes an array of unsigned long as output parameter (and possibly\n * a maximal node number as input parameter).\n */\nstatic __hwloc_inline int\nhwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,\n\t\t\t\t      const unsigned long *mask, unsigned long maxnode)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    hwloc_bitmap_zero(cpuset);\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)\n      if (node->os_index < maxnode\n\t  && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))\n\thwloc_bitmap_or(cpuset, cpuset, node->cpuset);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (mask[0] & 1)\n      hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));\n    else\n      hwloc_bitmap_zero(cpuset);\n  }\n\n  return 0;\n}\n\n/** \\brief Convert the array of unsigned long \\p mask into hwloc NUMA node set\n *\n * \\p mask is a array of unsigned long that will be read.\n * \\p maxnode contains the maximal node number that may be read in \\p mask.\n *\n * This function may be used after calling get_mempolicy or any other function\n * that takes an array of unsigned long as output parameter (and possibly\n * a maximal node number as input parameter).\n */\nstatic __hwloc_inline int\nhwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,\n\t\t\t\t\tconst unsigned long *mask, unsigned long maxnode)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    hwloc_bitmap_zero(nodeset);\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)\n      if (node->os_index < maxnode\n\t  && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))\n\thwloc_bitmap_set(nodeset, node->os_index);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (mask[0] & 1)\n      hwloc_bitmap_fill(nodeset);\n    else\n      hwloc_bitmap_zero(nodeset);\n  }\n\n  return 0;\n}\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask\n *\n * This interface helps converting between Linux libnuma bitmasks\n * and hwloc cpusets and nodesets.\n *\n * It also offers a consistent behavior on non-NUMA machines\n * or non-NUMA-aware kernels by assuming that the machines have a single\n * NUMA node.\n *\n * \\note Topology \\p topology must match the current machine.\n *\n * \\note The behavior of libnuma is undefined if the kernel is not NUMA-aware.\n * (when CONFIG_NUMA is not set in the kernel configuration).\n * This helper and libnuma may thus not be strictly compatible in this case,\n * which may be detected by checking whether numa_available() returns -1.\n *\n * @{\n */\n\n\n/** \\brief Convert hwloc CPU set \\p cpuset into the returned libnuma bitmask\n *\n * The returned bitmask should later be freed with numa_bitmask_free.\n *\n * This function may be used before calling many numa_ functions\n * that use a struct bitmask as an input parameter.\n *\n * \\return newly allocated struct bitmask.\n */\nstatic __hwloc_inline struct bitmask *\nhwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc;\nstatic __hwloc_inline struct bitmask *\nhwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n  struct bitmask *bitmask = numa_allocate_cpumask();\n  if (!bitmask)\n    return NULL;\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)\n      if (node->memory.local_memory)\n\tnuma_bitmask_setbit(bitmask, node->os_index);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (!hwloc_bitmap_iszero(cpuset))\n      numa_bitmask_setbit(bitmask, 0);\n  }\n\n  return bitmask;\n}\n\n/** \\brief Convert hwloc NUMA node set \\p nodeset into the returned libnuma bitmask\n *\n * The returned bitmask should later be freed with numa_bitmask_free.\n *\n * This function may be used before calling many numa_ functions\n * that use a struct bitmask as an input parameter.\n *\n * \\return newly allocated struct bitmask.\n */\nstatic __hwloc_inline struct bitmask *\nhwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc;\nstatic __hwloc_inline struct bitmask *\nhwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n  struct bitmask *bitmask = numa_allocate_cpumask();\n  if (!bitmask)\n    return NULL;\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)\n      if (hwloc_bitmap_isset(nodeset, node->os_index) && node->memory.local_memory)\n\tnuma_bitmask_setbit(bitmask, node->os_index);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (!hwloc_bitmap_iszero(nodeset))\n      numa_bitmask_setbit(bitmask, 0);\n  }\n\n  return bitmask;\n}\n\n/** \\brief Convert libnuma bitmask \\p bitmask into hwloc CPU set \\p cpuset\n *\n * This function may be used after calling many numa_ functions\n * that use a struct bitmask as an output parameter.\n */\nstatic __hwloc_inline int\nhwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,\n\t\t\t\t\tconst struct bitmask *bitmask)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    hwloc_bitmap_zero(cpuset);\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)\n      if (numa_bitmask_isbitset(bitmask, node->os_index))\n\thwloc_bitmap_or(cpuset, cpuset, node->cpuset);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (numa_bitmask_isbitset(bitmask, 0))\n      hwloc_bitmap_copy(cpuset, hwloc_topology_get_complete_cpuset(topology));\n    else\n      hwloc_bitmap_zero(cpuset);\n  }\n\n  return 0;\n}\n\n/** \\brief Convert libnuma bitmask \\p bitmask into hwloc NUMA node set \\p nodeset\n *\n * This function may be used after calling many numa_ functions\n * that use a struct bitmask as an output parameter.\n */\nstatic __hwloc_inline int\nhwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,\n\t\t\t\t\t const struct bitmask *bitmask)\n{\n  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);\n\n  if (depth != HWLOC_TYPE_DEPTH_UNKNOWN) {\n    hwloc_obj_t node = NULL;\n    hwloc_bitmap_zero(nodeset);\n    while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)\n      if (numa_bitmask_isbitset(bitmask, node->os_index))\n\thwloc_bitmap_set(nodeset, node->os_index);\n  } else {\n    /* if no numa, libnuma assumes we have a single node */\n    if (numa_bitmask_isbitset(bitmask, 0))\n      hwloc_bitmap_fill(nodeset);\n    else\n      hwloc_bitmap_zero(nodeset);\n  }\n\n  return 0;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_LINUX_NUMA_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/linux.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2016 Inria.  All rights reserved.\n * Copyright © 2009-2011 Université Bordeaux\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and Linux.\n *\n * Applications that use hwloc on Linux may want to include this file\n * if using some low-level Linux features.\n */\n\n#ifndef HWLOC_LINUX_H\n#define HWLOC_LINUX_H\n\n#include <hwloc.h>\n#include <stdio.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_linux Linux-specific helpers\n *\n * This includes helpers for manipulating Linux kernel cpumap files, and hwloc\n * equivalents of the Linux sched_setaffinity and sched_getaffinity system calls.\n *\n * @{\n */\n\n/** \\brief Convert a linux kernel cpumap file \\p file into hwloc CPU set.\n *\n * Might be used when reading CPU set from sysfs attributes such as topology\n * and caches for processors, or local_cpus for devices.\n */\nHWLOC_DECLSPEC int hwloc_linux_parse_cpumap_file(FILE *file, hwloc_cpuset_t set);\n\n/** \\brief Bind a thread \\p tid on cpus given in cpuset \\p set\n *\n * The behavior is exactly the same as the Linux sched_setaffinity system call,\n * but uses a hwloc cpuset.\n *\n * \\note This is equivalent to calling hwloc_set_proc_cpubind() with\n * HWLOC_CPUBIND_THREAD as flags.\n */\nHWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);\n\n/** \\brief Get the current binding of thread \\p tid\n *\n * The behavior is exactly the same as the Linux sched_getaffinity system call,\n * but uses a hwloc cpuset.\n *\n * \\note This is equivalent to calling hwloc_get_proc_cpubind() with\n * ::HWLOC_CPUBIND_THREAD as flags.\n */\nHWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);\n\n/** \\brief Get the last physical CPU where thread \\p tid ran.\n *\n * \\note This is equivalent to calling hwloc_get_proc_last_cpu_location() with\n * ::HWLOC_CPUBIND_THREAD as flags.\n */\nHWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set);\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_LINUX_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/myriexpress.h",
    "content": "/*\n * Copyright © 2010-2014 Inria.  All rights reserved.\n * Copyright © 2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and Myrinet Express.\n *\n * Applications that use both hwloc and Myrinet Express verbs may want to\n * include this file so as to get topology information for Myrinet hardware.\n *\n */\n\n#ifndef HWLOC_MYRIEXPRESS_H\n#define HWLOC_MYRIEXPRESS_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n\n#include <myriexpress.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_myriexpress Interoperability with Myrinet Express\n *\n * This interface offers ways to retrieve topology information about\n * Myrinet Express hardware.\n *\n * @{\n */\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close the MX board \\p id.\n *\n * Return the CPU set describing the locality of the Myrinet Express\n * board whose index is \\p id.\n *\n * Topology \\p topology and device \\p id must match the local machine.\n * I/O devices detection is not needed in the topology.\n *\n * The function only returns the locality of the device.\n * No additional information about the device is available.\n */\nstatic __hwloc_inline int\nhwloc_mx_board_get_device_cpuset(hwloc_topology_t topology,\n\t\t\t\t unsigned id, hwloc_cpuset_t set)\n{\n  uint32_t in, out;\n\n  if (!hwloc_topology_is_thissystem(topology)) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  in = id;\n  if (mx_get_info(NULL, MX_NUMA_NODE, &in, sizeof(in), &out, sizeof(out)) != MX_SUCCESS) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  if (out != (uint32_t) -1) {\n    hwloc_obj_t obj = NULL;\n    while ((obj = hwloc_get_next_obj_by_type(topology, HWLOC_OBJ_NUMANODE, obj)) != NULL)\n      if (obj->os_index == out) {\n\thwloc_bitmap_copy(set, obj->cpuset);\n\tgoto out;\n      }\n  }\n  /* fallback to the full topology cpuset */\n  hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n out:\n  return 0;\n}\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close the MX endpoint \\p endpoint.\n *\n * Return the CPU set describing the locality of the Myrinet Express\n * board that runs the MX endpoint \\p endpoint.\n *\n * Topology \\p topology and device \\p id must match the local machine.\n * I/O devices detection is not needed in the topology.\n *\n * The function only returns the locality of the endpoint.\n * No additional information about the endpoint or device is available.\n */\nstatic __hwloc_inline int\nhwloc_mx_endpoint_get_device_cpuset(hwloc_topology_t topology,\n\t\t\t\t    mx_endpoint_t endpoint, hwloc_cpuset_t set)\n{\n  uint64_t nid;\n  uint32_t nindex, eid;\n  mx_endpoint_addr_t eaddr;\n\n  if (mx_get_endpoint_addr(endpoint, &eaddr) != MX_SUCCESS) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  if (mx_decompose_endpoint_addr(eaddr, &nid, &eid) != MX_SUCCESS) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  if (mx_nic_id_to_board_number(nid, &nindex) != MX_SUCCESS) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  return hwloc_mx_board_get_device_cpuset(topology, nindex, set);\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_MYRIEXPRESS_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/nvml.h",
    "content": "/*\n * Copyright © 2012-2016 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and the NVIDIA Management Library.\n *\n * Applications that use both hwloc and the NVIDIA Management Library may want to\n * include this file so as to get topology information for NVML devices.\n */\n\n#ifndef HWLOC_NVML_H\n#define HWLOC_NVML_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#include <hwloc/helper.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#endif\n\n#include <nvml.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_nvml Interoperability with the NVIDIA Management Library\n *\n * This interface offers ways to retrieve topology information about\n * devices managed by the NVIDIA Management Library (NVML).\n *\n * @{\n */\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to NVML device \\p device.\n *\n * Return the CPU set describing the locality of the NVML device \\p device.\n *\n * Topology \\p topology and device \\p device must match the local machine.\n * I/O devices detection and the NVML component are not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_nvml_get_device_osdev()\n * and hwloc_nvml_get_device_osdev_by_index().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux; other systems will simply get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t     nvmlDevice_t device, hwloc_cpuset_t set)\n{\n#ifdef HWLOC_LINUX_SYS\n  /* If we're on Linux, use the sysfs mechanism to get the local cpus */\n#define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128\n  char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];\n  FILE *sysfile = NULL;\n  nvmlReturn_t nvres;\n  nvmlPciInfo_t pci;\n\n  if (!hwloc_topology_is_thissystem(topology)) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  nvres = nvmlDeviceGetPciInfo(device, &pci);\n  if (NVML_SUCCESS != nvres) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  sprintf(path, \"/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus\", pci.domain, pci.bus, pci.device);\n  sysfile = fopen(path, \"r\");\n  if (!sysfile)\n    return -1;\n\n  if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n      || hwloc_bitmap_iszero(set))\n    hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n  fclose(sysfile);\n#else\n  /* Non-Linux systems simply get a full cpuset */\n  hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n  return 0;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * NVML device whose index is \\p idx.\n *\n * Return the OS device object describing the NVML device whose\n * index is \\p idx. Returns NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the NVML component must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)\n{\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n                if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type\n                    && osdev->name\n\t\t    && !strncmp(\"nvml\", osdev->name, 4)\n\t\t    && atoi(osdev->name + 4) == (int) idx)\n                        return osdev;\n        }\n        return NULL;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to NVML device \\p device.\n *\n * Return the hwloc OS device object that describes the given\n * NVML device \\p device. Return NULL if there is none.\n *\n * Topology \\p topology and device \\p device must match the local machine.\n * I/O devices detection and the NVML component must be enabled in the topology.\n * If not, the locality of the object may still be found using\n * hwloc_nvml_get_device_cpuset().\n *\n * \\note The corresponding hwloc PCI device may be found by looking\n * at the result parent pointer.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)\n{\n\thwloc_obj_t osdev;\n\tnvmlReturn_t nvres;\n\tnvmlPciInfo_t pci;\n\n\tif (!hwloc_topology_is_thissystem(topology)) {\n\t\terrno = EINVAL;\n\t\treturn NULL;\n\t}\n\n\tnvres = nvmlDeviceGetPciInfo(device, &pci);\n\tif (NVML_SUCCESS != nvres)\n\t\treturn NULL;\n\n\tosdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\thwloc_obj_t pcidev = osdev->parent;\n\t\tif (strncmp(osdev->name, \"nvml\", 4))\n\t\t\tcontinue;\n\t\tif (pcidev\n\t\t    && pcidev->type == HWLOC_OBJ_PCI_DEVICE\n\t\t    && pcidev->attr->pcidev.domain == pci.domain\n\t\t    && pcidev->attr->pcidev.bus == pci.bus\n\t\t    && pcidev->attr->pcidev.dev == pci.device\n\t\t    && pcidev->attr->pcidev.func == 0)\n\t\t\treturn osdev;\n\t}\n\n\treturn NULL;\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_NVML_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/opencl.h",
    "content": "/*\n * Copyright © 2012-2017 Inria.  All rights reserved.\n * Copyright © 2013 Université Bordeaux.  All right reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and the OpenCL interface.\n *\n * Applications that use both hwloc and OpenCL may want to\n * include this file so as to get topology information for OpenCL devices.\n */\n\n#ifndef HWLOC_OPENCL_H\n#define HWLOC_OPENCL_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#include <hwloc/helper.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#endif\n\n#include <CL/cl.h>\n#include <CL/cl_ext.h>\n\n#include <stdio.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_opencl Interoperability with OpenCL\n *\n * This interface offers ways to retrieve topology information about\n * OpenCL devices.\n *\n * Only the AMD OpenCL interface currently offers useful locality information\n * about its devices.\n *\n * @{\n */\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to OpenCL device \\p device.\n *\n * Return the CPU set describing the locality of the OpenCL device \\p device.\n *\n * Topology \\p topology and device \\p device must match the local machine.\n * I/O devices detection and the OpenCL component are not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_opencl_get_device_osdev()\n * and hwloc_opencl_get_device_osdev_by_index().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux with the AMD OpenCL implementation; other systems will simply\n * get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t       cl_device_id device __hwloc_attribute_unused,\n\t\t\t       hwloc_cpuset_t set)\n{\n#if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD)\n\t/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */\n#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128\n\tchar path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];\n\tFILE *sysfile = NULL;\n\tcl_device_topology_amd amdtopo;\n\tcl_int clret;\n\n\tif (!hwloc_topology_is_thissystem(topology)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\n\tclret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);\n\tif (CL_SUCCESS != clret) {\n\t\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\t\treturn 0;\n\t}\n\tif (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {\n\t\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\t\treturn 0;\n\t}\n\n\tsprintf(path, \"/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus\",\n\t\t(unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function);\n\tsysfile = fopen(path, \"r\");\n\tif (!sysfile)\n\t\treturn -1;\n\n\tif (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n\t    || hwloc_bitmap_iszero(set))\n\t\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n\tfclose(sysfile);\n#else\n\t/* Non-Linux + AMD OpenCL systems simply get a full cpuset */\n\thwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n  return 0;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the\n * OpenCL device for the given indexes.\n *\n * Return the OS device object describing the OpenCL device\n * whose platform index is \\p platform_index,\n * and whose device index within this platform if \\p device_index.\n * Return NULL if there is none.\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection and the OpenCL component must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,\n\t\t\t\t       unsigned platform_index, unsigned device_index)\n{\n\tunsigned x = (unsigned) -1, y = (unsigned) -1;\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\tif (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type\n                    && osdev->name\n\t\t    && sscanf(osdev->name, \"opencl%ud%u\", &x, &y) == 2\n\t\t    && platform_index == x && device_index == y)\n                        return osdev;\n        }\n        return NULL;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to OpenCL device \\p device.\n *\n * Return the hwloc OS device object that describes the given\n * OpenCL device \\p device. Return NULL if there is none.\n *\n * Topology \\p topology and device \\p device must match the local machine.\n * I/O devices detection and the OpenCL component must be enabled in the topology.\n * If not, the locality of the object may still be found using\n * hwloc_opencl_get_device_cpuset().\n *\n * \\note The corresponding hwloc PCI device may be found by looking\n * at the result parent pointer.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t      cl_device_id device __hwloc_attribute_unused)\n{\n#ifdef CL_DEVICE_TOPOLOGY_AMD\n\thwloc_obj_t osdev;\n\tcl_device_topology_amd amdtopo;\n\tcl_int clret;\n\n\tclret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);\n\tif (CL_SUCCESS != clret) {\n\t\terrno = EINVAL;\n\t\treturn NULL;\n\t}\n\tif (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {\n\t\terrno = EINVAL;\n\t\treturn NULL;\n\t}\n\n\tosdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\thwloc_obj_t pcidev = osdev->parent;\n\t\tif (strncmp(osdev->name, \"opencl\", 6))\n\t\t\tcontinue;\n\t\tif (pcidev\n\t\t    && pcidev->type == HWLOC_OBJ_PCI_DEVICE\n\t\t    && pcidev->attr->pcidev.domain == 0\n\t\t    && pcidev->attr->pcidev.bus == amdtopo.pcie.bus\n\t\t    && pcidev->attr->pcidev.dev == amdtopo.pcie.device\n\t\t    && pcidev->attr->pcidev.func == amdtopo.pcie.function)\n\t\t\treturn osdev;\n\t}\n\n\treturn NULL;\n#else\n\treturn NULL;\n#endif\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_OPENCL_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/openfabrics-verbs.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2016 Inria.  All rights reserved.\n * Copyright © 2009-2010 Université Bordeaux\n * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/** \\file\n * \\brief Macros to help interaction between hwloc and OpenFabrics\n * verbs.\n *\n * Applications that use both hwloc and OpenFabrics verbs may want to\n * include this file so as to get topology information for OpenFabrics\n * hardware (InfiniBand, etc).\n *\n */\n\n#ifndef HWLOC_OPENFABRICS_VERBS_H\n#define HWLOC_OPENFABRICS_VERBS_H\n\n#include <hwloc.h>\n#include <hwloc/autogen/config.h>\n#ifdef HWLOC_LINUX_SYS\n#include <hwloc/linux.h>\n#endif\n\n#include <infiniband/verbs.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_openfabrics Interoperability with OpenFabrics\n *\n * This interface offers ways to retrieve topology information about\n * OpenFabrics devices (InfiniBand, Omni-Path, usNIC, etc).\n *\n * @{\n */\n\n/** \\brief Get the CPU set of logical processors that are physically\n * close to device \\p ibdev.\n *\n * Return the CPU set describing the locality of the OpenFabrics\n * device \\p ibdev (InfiniBand, etc).\n *\n * Topology \\p topology and device \\p ibdev must match the local machine.\n * I/O devices detection is not needed in the topology.\n *\n * The function only returns the locality of the device.\n * If more information about the device is needed, OS objects should\n * be used instead, see hwloc_ibv_get_device_osdev()\n * and hwloc_ibv_get_device_osdev_by_name().\n *\n * This function is currently only implemented in a meaningful way for\n * Linux; other systems will simply get a full cpuset.\n */\nstatic __hwloc_inline int\nhwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,\n\t\t\t    struct ibv_device *ibdev, hwloc_cpuset_t set)\n{\n#ifdef HWLOC_LINUX_SYS\n  /* If we're on Linux, use the verbs-provided sysfs mechanism to\n     get the local cpus */\n#define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128\n  char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];\n  FILE *sysfile = NULL;\n\n  if (!hwloc_topology_is_thissystem(topology)) {\n    errno = EINVAL;\n    return -1;\n  }\n\n  sprintf(path, \"/sys/class/infiniband/%s/device/local_cpus\",\n\t  ibv_get_device_name(ibdev));\n  sysfile = fopen(path, \"r\");\n  if (!sysfile)\n    return -1;\n\n  if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0\n      || hwloc_bitmap_iszero(set))\n    hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n\n  fclose(sysfile);\n#else\n  /* Non-Linux systems simply get a full cpuset */\n  hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));\n#endif\n  return 0;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the OpenFabrics\n * device named \\p ibname.\n *\n * Return the OS device object describing the OpenFabrics device\n * (InfiniBand, Omni-Path, usNIC, etc) whose name is \\p ibname\n * (mlx5_0, hfi1_0, usnic_0, qib0, etc).\n * Returns NULL if there is none.\n * The name \\p ibname is usually obtained from ibv_get_device_name().\n *\n * The topology \\p topology does not necessarily have to match the current\n * machine. For instance the topology may be an XML import of a remote host.\n * I/O devices detection must be enabled in the topology.\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,\n\t\t\t\t   const char *ibname)\n{\n\thwloc_obj_t osdev = NULL;\n\twhile ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {\n\t\tif (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type\n\t\t    && osdev->name && !strcmp(ibname, osdev->name))\n\t\t\treturn osdev;\n\t}\n\treturn NULL;\n}\n\n/** \\brief Get the hwloc OS device object corresponding to the OpenFabrics\n * device \\p ibdev.\n *\n * Return the OS device object describing the OpenFabrics device \\p ibdev\n * (InfiniBand, etc). Returns NULL if there is none.\n *\n * Topology \\p topology and device \\p ibdev must match the local machine.\n * I/O devices detection must be enabled in the topology.\n * If not, the locality of the object may still be found using\n * hwloc_ibv_get_device_cpuset().\n *\n * \\note The corresponding PCI device object can be obtained by looking\n * at the OS device parent object.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_ibv_get_device_osdev(hwloc_topology_t topology,\n\t\t\t   struct ibv_device *ibdev)\n{\n\tif (!hwloc_topology_is_thissystem(topology)) {\n\t\terrno = EINVAL;\n\t\treturn NULL;\n\t}\n\treturn hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));\n}\n\n/** @} */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_OPENFABRICS_VERBS_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/plugins.h",
    "content": "/*\n * Copyright © 2013-2015 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n#ifndef HWLOC_PLUGINS_H\n#define HWLOC_PLUGINS_H\n\n/** \\file\n * \\brief Public interface for building hwloc plugins.\n */\n\nstruct hwloc_backend;\n\n#include <hwloc.h>\n#ifdef HWLOC_INSIDE_PLUGIN\n/* needed for hwloc_plugin_check_namespace() */\n#include <ltdl.h>\n#endif\n\n\n\n/** \\defgroup hwlocality_disc_components Components and Plugins: Discovery components\n * @{\n */\n\n/** \\brief Discovery component type */\ntypedef enum hwloc_disc_component_type_e {\n  /** \\brief CPU-only discovery through the OS, or generic no-OS support.\n   * \\hideinitializer */\n  HWLOC_DISC_COMPONENT_TYPE_CPU = (1<<0),\n\n  /** \\brief xml, synthetic or custom,\n   * platform-specific components such as bgq.\n   * Anything the discovers CPU and everything else.\n   * No misc backend is expected to complement a global component.\n   * \\hideinitializer */\n  HWLOC_DISC_COMPONENT_TYPE_GLOBAL = (1<<1),\n\n  /** \\brief OpenCL, Cuda, etc.\n   * \\hideinitializer */\n  HWLOC_DISC_COMPONENT_TYPE_MISC = (1<<2)\n} hwloc_disc_component_type_t;\n\n/** \\brief Discovery component structure\n *\n * This is the major kind of components, taking care of the discovery.\n * They are registered by generic components, either statically-built or as plugins.\n */\nstruct hwloc_disc_component {\n  /** \\brief Discovery component type */\n  hwloc_disc_component_type_t type;\n\n  /** \\brief Name.\n   * If this component is built as a plugin, this name does not have to match the plugin filename.\n   */\n  const char *name;\n\n  /** \\brief Component types to exclude, as an OR'ed set of ::hwloc_disc_component_type_e.\n   *\n   * For a GLOBAL component, this usually includes all other types (~0).\n   *\n   * Other components only exclude types that may bring conflicting\n   * topology information. MISC components should likely not be excluded\n   * since they usually bring non-primary additional information.\n   */\n  unsigned excludes;\n\n  /** \\brief Instantiate callback to create a backend from the component.\n   * Parameters data1, data2, data3 are NULL except for components\n   * that have special enabling routines such as hwloc_topology_set_xml(). */\n  struct hwloc_backend * (*instantiate)(struct hwloc_disc_component *component, const void *data1, const void *data2, const void *data3);\n\n  /** \\brief Component priority.\n   * Used to sort topology->components, higher priority first.\n   * Also used to decide between two components with the same name.\n   *\n   * Usual values are\n   * 50 for native OS (or platform) components,\n   * 45 for x86,\n   * 40 for no-OS fallback,\n   * 30 for global components (xml/synthetic/custom),\n   * 20 for pci,\n   * 10 for other misc components (opencl etc.).\n   */\n  unsigned priority;\n\n  /** \\private Used internally to list components by priority on topology->components\n   * (the component structure is usually read-only,\n   *  the core copies it before using this field for queueing)\n   */\n  struct hwloc_disc_component * next;\n};\n\n/** @} */\n\n\n\n\n/** \\defgroup hwlocality_disc_backends Components and Plugins: Discovery backends\n * @{\n */\n\n/** \\brief Discovery backend structure\n *\n * A backend is the instantiation of a discovery component.\n * When a component gets enabled for a topology,\n * its instantiate() callback creates a backend.\n *\n * hwloc_backend_alloc() initializes all fields to default values\n * that the component may change (except \"component\" and \"next\")\n * before enabling the backend with hwloc_backend_enable().\n */\nstruct hwloc_backend {\n  /** \\private Reserved for the core, set by hwloc_backend_alloc() */\n  struct hwloc_disc_component * component;\n  /** \\private Reserved for the core, set by hwloc_backend_enable() */\n  struct hwloc_topology * topology;\n  /** \\private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */\n  int envvar_forced;\n  /** \\private Reserved for the core. Used internally to list backends topology->backends. */\n  struct hwloc_backend * next;\n\n  /** \\brief Backend flags, as an OR'ed set of ::hwloc_backend_flag_e */\n  unsigned long flags;\n\n  /** \\brief Backend-specific 'is_custom' property.\n   * Shortcut on !strcmp(..->component->name, \"custom\").\n   * Only the custom component should touch this. */\n  int is_custom;\n\n  /** \\brief Backend-specific 'is_thissystem' property.\n   * Set to 0 or 1 if the backend should enforce the thissystem flag when it gets enabled.\n   * Set to -1 if the backend doesn't care (default). */\n  int is_thissystem;\n\n  /** \\brief Backend private data, or NULL if none. */\n  void * private_data;\n  /** \\brief Callback for freeing the private_data.\n   * May be NULL.\n   */\n  void (*disable)(struct hwloc_backend *backend);\n\n  /** \\brief Main discovery callback.\n   * returns > 0 if it modified the topology tree, -1 on error, 0 otherwise.\n   * May be NULL if type is ::HWLOC_DISC_COMPONENT_TYPE_MISC. */\n  int (*discover)(struct hwloc_backend *backend);\n\n  /** \\brief Callback used by the PCI backend to retrieve the locality of a PCI object from the OS/cpu backend.\n   * May be NULL. */\n  int (*get_obj_cpuset)(struct hwloc_backend *backend, struct hwloc_backend *caller, struct hwloc_obj *obj, hwloc_bitmap_t cpuset);\n\n  /** \\brief Callback called by backends to notify this backend that a new object was added.\n   * returns > 0 if it modified the topology tree, 0 otherwise.\n   * May be NULL. */\n  int (*notify_new_object)(struct hwloc_backend *backend, struct hwloc_backend *caller, struct hwloc_obj *obj);\n};\n\n/** \\brief Backend flags */\nenum hwloc_backend_flag_e {\n  /** \\brief Levels should be reconnected before this backend discover() is used.\n   * \\hideinitializer */\n  HWLOC_BACKEND_FLAG_NEED_LEVELS = (1UL<<0)\n};\n\n/** \\brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.\n * The caller will then modify whatever needed, and call hwloc_backend_enable().\n */\nHWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_disc_component *component);\n\n/** \\brief Enable a previously allocated and setup backend. */\nHWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *backend);\n\n/** \\brief Used by backends discovery callbacks to request locality information from others.\n *\n * Traverse the list of enabled backends until one has a\n * get_obj_cpuset() method, and call it.\n */\nHWLOC_DECLSPEC int hwloc_backends_get_obj_cpuset(struct hwloc_backend *caller, struct hwloc_obj *obj, hwloc_bitmap_t cpuset);\n\n/** \\brief Used by backends discovery callbacks to notify other\n * backends of new objects.\n *\n * Traverse the list of enabled backends (all but caller) and invoke\n * their notify_new_object() method to notify them that a new object\n * just got added to the topology.\n *\n * Currently only used for notifying of new PCI device objects.\n */\nHWLOC_DECLSPEC int hwloc_backends_notify_new_object(struct hwloc_backend *caller, struct hwloc_obj *obj);\n\n/** @} */\n\n\n\n\n/** \\defgroup hwlocality_generic_components Components and Plugins: Generic components\n * @{\n */\n\n/** \\brief Generic component type */\ntypedef enum hwloc_component_type_e {\n  /** \\brief The data field must point to a struct hwloc_disc_component. */\n  HWLOC_COMPONENT_TYPE_DISC,\n\n  /** \\brief The data field must point to a struct hwloc_xml_component. */\n  HWLOC_COMPONENT_TYPE_XML\n} hwloc_component_type_t;\n\n/** \\brief Generic component structure\n *\n * Generic components structure, either statically listed by configure in static-components.h\n * or dynamically loaded as a plugin.\n */\nstruct hwloc_component {\n  /** \\brief Component ABI version, set to ::HWLOC_COMPONENT_ABI */\n  unsigned abi;\n\n  /** \\brief Process-wide component initialization callback.\n   *\n   * This optional callback is called when the component is registered\n   * to the hwloc core (after loading the plugin).\n   *\n   * When the component is built as a plugin, this callback\n   * should call hwloc_check_plugin_namespace()\n   * and return an negative error code on error.\n   *\n   * \\p flags is always 0 for now.\n   *\n   * \\return 0 on success, or a negative code on error.\n   *\n   * \\note If the component uses ltdl for loading its own plugins,\n   * it should load/unload them only in init() and finalize(),\n   * to avoid race conditions with hwloc's use of ltdl.\n   */\n  int (*init)(unsigned long flags);\n\n  /** \\brief Process-wide component termination callback.\n   *\n   * This optional callback is called after unregistering the component\n   * from the hwloc core (before unloading the plugin).\n   *\n   * \\p flags is always 0 for now.\n   *\n   * \\note If the component uses ltdl for loading its own plugins,\n   * it should load/unload them only in init() and finalize(),\n   * to avoid race conditions with hwloc's use of ltdl.\n   */\n  void (*finalize)(unsigned long flags);\n\n  /** \\brief Component type */\n  hwloc_component_type_t type;\n\n  /** \\brief Component flags, unused for now */\n  unsigned long flags;\n\n  /** \\brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */\n  void * data;\n};\n\n/** @} */\n\n\n\n\n/** \\defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components\n * @{\n */\n\n/** \\brief Add an object to the topology.\n *\n * It is sorted along the tree of other objects according to the inclusion of\n * cpusets, to eventually be added as a child of the smallest object including\n * this object.\n *\n * If the cpuset is empty, the type of the object (and maybe some attributes)\n * must be enough to find where to insert the object. This is especially true\n * for NUMA nodes with memory and no CPUs.\n *\n * The given object should not have children.\n *\n * This shall only be called before levels are built.\n *\n * In case of error, hwloc_report_os_error() is called.\n *\n * Returns the object on success.\n * Returns NULL and frees obj on error.\n * Returns another object and frees obj if it was merged with an identical pre-existing object.\n */\nHWLOC_DECLSPEC struct hwloc_obj *hwloc_insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj);\n\n/** \\brief Type of error callbacks during object insertion */\ntypedef void (*hwloc_report_error_t)(const char * msg, int line);\n/** \\brief Report an insertion error from a backend */\nHWLOC_DECLSPEC void hwloc_report_os_error(const char * msg, int line);\n/** \\brief Check whether insertion errors are hidden */\nHWLOC_DECLSPEC int hwloc_hide_errors(void);\n\n/** \\brief Add an object to the topology and specify which error callback to use.\n *\n * Aside from the error callback selection, this function is identical to hwloc_insert_object_by_cpuset()\n */\nHWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj, hwloc_report_error_t report_error);\n\n/** \\brief Insert an object somewhere in the topology.\n *\n * It is added as the last child of the given parent.\n * The cpuset is completely ignored, so strange objects such as I/O devices should\n * preferably be inserted with this.\n *\n * When used for \"normal\" children with cpusets (when importing from XML\n * when duplicating a topology), the caller should make sure children are inserted\n * in order.\n *\n * The given object may have children.\n *\n * Remember to call topology_connect() afterwards to fix handy pointers.\n */\nHWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);\n\n/** \\brief Allocate and initialize an object of the given type and physical index */\nstatic __hwloc_inline struct hwloc_obj *\nhwloc_alloc_setup_object(hwloc_obj_type_t type, signed os_index)\n{\n  struct hwloc_obj *obj = malloc(sizeof(*obj));\n  memset(obj, 0, sizeof(*obj));\n  obj->type = type;\n  obj->os_index = os_index;\n  obj->os_level = -1;\n  obj->attr = malloc(sizeof(*obj->attr));\n  memset(obj->attr, 0, sizeof(*obj->attr));\n  /* do not allocate the cpuset here, let the caller do it */\n  return obj;\n}\n\n/** \\brief Setup object cpusets/nodesets by OR'ing its children.\n *\n * Used when adding an object late in the topology, after propagating sets up and down.\n * The caller should use this after inserting by cpuset (which means the cpusets is already OK).\n * Typical case: PCI backend adding a hostbridge parent.\n */\nHWLOC_DECLSPEC int hwloc_fill_object_sets(hwloc_obj_t obj);\n\n/** \\brief Make sure that plugins can lookup core symbols.\n *\n * This is a sanity check to avoid lazy-lookup failures when libhwloc\n * is loaded within a plugin, and later tries to load its own plugins.\n * This may fail (and abort the program) if libhwloc symbols are in a\n * private namespace.\n *\n * \\return 0 on success.\n * \\return -1 if the plugin cannot be successfully loaded. The caller\n * plugin init() callback should return a negative error code as well.\n *\n * Plugins should call this function in their init() callback to avoid\n * later crashes if lazy symbol resolution is used by the upper layer that\n * loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).\n *\n * \\note The build system must define HWLOC_INSIDE_PLUGIN if and only if\n * building the caller as a plugin.\n *\n * \\note This function should remain inline so plugins can call it even\n * when they cannot find libhwloc symbols.\n */\nstatic __hwloc_inline int\nhwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)\n{\n#ifdef HWLOC_INSIDE_PLUGIN\n  lt_dlhandle handle;\n  void *sym;\n  handle = lt_dlopen(NULL);\n  if (!handle)\n    /* cannot check, assume things will work */\n    return 0;\n  sym = lt_dlsym(handle, symbol);\n  lt_dlclose(handle);\n  if (!sym) {\n    static int verboseenv_checked = 0;\n    static int verboseenv_value = 0;\n    if (!verboseenv_checked) {\n      const char *verboseenv = getenv(\"HWLOC_PLUGINS_VERBOSE\");\n      verboseenv_value = verboseenv ? atoi(verboseenv) : 0;\n      verboseenv_checked = 1;\n    }\n    if (verboseenv_value)\n      fprintf(stderr, \"Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\\n\",\n\t      pluginname, symbol);\n    return -1;\n  }\n#endif /* HWLOC_INSIDE_PLUGIN */\n  return 0;\n}\n\n/** @} */\n\n\n\n\n/** \\defgroup hwlocality_components_pci_funcs Components and Plugins: PCI functions to be used by components\n * @{\n */\n\n/** \\brief Insert a list of PCI devices and bridges in the backend topology.\n *\n * Insert a list of objects (either PCI device or bridges) starting at first_obj\n * (linked by next_sibling in the topology, and ending with NULL).\n * Objects are placed under the right bridges, and the remaining upstream bridges\n * are then inserted in the topology by calling the get_obj_cpuset() callback to\n * find their locality.\n */\nHWLOC_DECLSPEC int hwloc_insert_pci_device_list(struct hwloc_backend *backend, struct hwloc_obj *first_obj);\n\n/** \\brief Return the offset of the given capability in the PCI config space buffer\n *\n * This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.\n */\nHWLOC_DECLSPEC unsigned hwloc_pci_find_cap(const unsigned char *config, unsigned cap);\n\n/** \\brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.\n *\n * Needs 20 bytes of EXP capability block starting at offset in the config space\n * for registers up to link status.\n */\nHWLOC_DECLSPEC int hwloc_pci_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);\n\n/** \\brief Modify the PCI device object into a bridge and fill its attribute if a bridge is found in the PCI config space.\n *\n * This function requires 64 bytes of common configuration header at the beginning of config.\n *\n * Returns -1 and destroys /p obj if bridge fields are invalid.\n */\nHWLOC_DECLSPEC int hwloc_pci_prepare_bridge(hwloc_obj_t obj, const unsigned char *config);\n\n/** @} */\n\n\n\n\n#endif /* HWLOC_PLUGINS_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc/rename.h",
    "content": "/*\n * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.\n * Copyright © 2010-2017 Inria.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n#ifndef HWLOC_RENAME_H\n#define HWLOC_RENAME_H\n\n#include <hwloc/autogen/config.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/* Only enact these defines if we're actually renaming the symbols\n   (i.e., avoid trying to have no-op defines if we're *not*\n   renaming). */\n\n#if HWLOC_SYM_TRANSFORM\n\n/* Use a preprocessor two-step in order to get the prefixing right.\n   Make 2 macros: HWLOC_NAME and HWLOC_NAME_CAPS for renaming\n   things. */\n\n#define HWLOC_MUNGE_NAME(a, b) HWLOC_MUNGE_NAME2(a, b)\n#define HWLOC_MUNGE_NAME2(a, b) a ## b\n#define HWLOC_NAME(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX, hwloc_ ## name)\n#define HWLOC_NAME_CAPS(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX_CAPS, hwloc_ ## name)\n\n/* Now define all the \"real\" names to be the prefixed names.  This\n   allows us to use the real names throughout the code base (i.e.,\n   \"hwloc_<foo>\"); the preprocessor will adjust to have the prefixed\n   name under the covers. */\n\n/* Names from hwloc.h */\n\n#define hwloc_get_api_version HWLOC_NAME(get_api_version)\n\n#define hwloc_topology HWLOC_NAME(topology)\n#define hwloc_topology_t HWLOC_NAME(topology_t)\n\n#define hwloc_cpuset_t HWLOC_NAME(cpuset_t)\n#define hwloc_const_cpuset_t HWLOC_NAME(const_cpuset_t)\n#define hwloc_nodeset_t HWLOC_NAME(nodeset_t)\n#define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t)\n\n#define HWLOC_OBJ_SYSTEM HWLOC_NAME_CAPS(OBJ_SYSTEM)\n#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)\n#define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)\n#define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE)\n#define HWLOC_OBJ_CACHE HWLOC_NAME_CAPS(OBJ_CACHE)\n#define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE)\n#define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU)\n#define HWLOC_OBJ_MISC HWLOC_NAME_CAPS(OBJ_MISC)\n#define HWLOC_OBJ_GROUP HWLOC_NAME_CAPS(OBJ_GROUP)\n#define HWLOC_OBJ_BRIDGE HWLOC_NAME_CAPS(OBJ_BRIDGE)\n#define HWLOC_OBJ_PCI_DEVICE HWLOC_NAME_CAPS(OBJ_PCI_DEVICE)\n#define HWLOC_OBJ_OS_DEVICE HWLOC_NAME_CAPS(OBJ_OS_DEVICE)\n#define HWLOC_OBJ_TYPE_MAX HWLOC_NAME_CAPS(OBJ_TYPE_MAX)\n#define hwloc_obj_type_t HWLOC_NAME(obj_type_t)\n\n#define hwloc_obj_cache_type_e HWLOC_NAME(obj_cache_type_e)\n#define hwloc_obj_cache_type_t HWLOC_NAME(obj_cache_type_t)\n#define HWLOC_OBJ_CACHE_UNIFIED HWLOC_NAME_CAPS(OBJ_CACHE_UNIFIED)\n#define HWLOC_OBJ_CACHE_DATA HWLOC_NAME_CAPS(OBJ_CACHE_DATA)\n#define HWLOC_OBJ_CACHE_INSTRUCTION HWLOC_NAME_CAPS(OBJ_CACHE_INSTRUCTION)\n\n#define hwloc_obj_bridge_type_e HWLOC_NAME(obj_bridge_type_e)\n#define hwloc_obj_bridge_type_t HWLOC_NAME(obj_bridge_type_t)\n#define HWLOC_OBJ_BRIDGE_HOST HWLOC_NAME_CAPS(OBJ_BRIDGE_HOST)\n#define HWLOC_OBJ_BRIDGE_PCI HWLOC_NAME_CAPS(OBJ_BRIDGE_PCI)\n\n#define hwloc_obj_osdev_type_e HWLOC_NAME(obj_osdev_type_e)\n#define hwloc_obj_osdev_type_t HWLOC_NAME(obj_osdev_type_t)\n#define HWLOC_OBJ_OSDEV_BLOCK HWLOC_NAME_CAPS(OBJ_OSDEV_BLOCK)\n#define HWLOC_OBJ_OSDEV_GPU HWLOC_NAME_CAPS(OBJ_OSDEV_GPU)\n#define HWLOC_OBJ_OSDEV_NETWORK HWLOC_NAME_CAPS(OBJ_OSDEV_NETWORK)\n#define HWLOC_OBJ_OSDEV_OPENFABRICS HWLOC_NAME_CAPS(OBJ_OSDEV_OPENFABRICS)\n#define HWLOC_OBJ_OSDEV_DMA HWLOC_NAME_CAPS(OBJ_OSDEV_DMA)\n#define HWLOC_OBJ_OSDEV_COPROC HWLOC_NAME_CAPS(OBJ_OSDEV_COPROC)\n\n#define hwloc_compare_types HWLOC_NAME(compare_types)\n\n#define hwloc_compare_types_e HWLOC_NAME(compare_types_e)\n#define HWLOC_TYPE_UNORDERED HWLOC_NAME_CAPS(TYPE_UNORDERED)\n\n#define hwloc_obj_memory_s HWLOC_NAME(obj_memory_s)\n#define hwloc_obj_memory_page_type_s HWLOC_NAME(obj_memory_page_type_s)\n\n#define hwloc_obj HWLOC_NAME(obj)\n#define hwloc_obj_t HWLOC_NAME(obj_t)\n\n#define hwloc_distances_s HWLOC_NAME(distances_s)\n#define hwloc_obj_info_s HWLOC_NAME(obj_info_s)\n\n#define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u)\n#define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s)\n#define hwloc_group_attr_s HWLOC_NAME(group_attr_s)\n#define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s)\n#define hwloc_bridge_attr_s HWLOC_NAME(bridge_attr_s)\n#define hwloc_osdev_attr_s HWLOC_NAME(osdev_attr_s)\n\n#define hwloc_topology_init HWLOC_NAME(topology_init)\n#define hwloc_topology_load HWLOC_NAME(topology_load)\n#define hwloc_topology_destroy HWLOC_NAME(topology_destroy)\n#define hwloc_topology_dup HWLOC_NAME(topology_dup)\n#define hwloc_topology_check HWLOC_NAME(topology_check)\n#define hwloc_topology_ignore_type HWLOC_NAME(topology_ignore_type)\n#define hwloc_topology_ignore_type_keep_structure HWLOC_NAME(topology_ignore_type_keep_structure)\n#define hwloc_topology_ignore_all_keep_structure HWLOC_NAME(topology_ignore_all_keep_structure)\n\n#define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e)\n\n#define HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WHOLE_SYSTEM)\n#define HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IS_THISSYSTEM)\n#define HWLOC_TOPOLOGY_FLAG_IO_DEVICES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IO_DEVICES)\n#define HWLOC_TOPOLOGY_FLAG_IO_BRIDGES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IO_BRIDGES)\n#define HWLOC_TOPOLOGY_FLAG_WHOLE_IO HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WHOLE_IO)\n#define HWLOC_TOPOLOGY_FLAG_ICACHES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_ICACHES)\n#define HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES)\n\n#define hwloc_topology_set_flags HWLOC_NAME(topology_set_flags)\n#define hwloc_topology_set_fsroot HWLOC_NAME(topology_set_fsroot)\n#define hwloc_topology_set_pid HWLOC_NAME(topology_set_pid)\n#define hwloc_topology_set_synthetic HWLOC_NAME(topology_set_synthetic)\n#define hwloc_topology_set_xml HWLOC_NAME(topology_set_xml)\n#define hwloc_topology_set_xmlbuffer HWLOC_NAME(topology_set_xmlbuffer)\n#define hwloc_topology_set_custom HWLOC_NAME(topology_set_custom)\n#define hwloc_topology_set_distance_matrix HWLOC_NAME(topology_set_distance_matrix)\n\n#define hwloc_topology_discovery_support HWLOC_NAME(topology_discovery_support)\n#define hwloc_topology_cpubind_support HWLOC_NAME(topology_cpubind_support)\n#define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support)\n#define hwloc_topology_support HWLOC_NAME(topology_support)\n#define hwloc_topology_get_support HWLOC_NAME(topology_get_support)\n#define hwloc_topology_set_userdata HWLOC_NAME(topology_set_userdata)\n#define hwloc_topology_get_userdata HWLOC_NAME(topology_get_userdata)\n\n#define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml)\n#define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer)\n#define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer)\n#define hwloc_topology_set_userdata_export_callback HWLOC_NAME(topology_set_userdata_export_callback)\n#define hwloc_export_obj_userdata HWLOC_NAME(export_obj_userdata)\n#define hwloc_export_obj_userdata_base64 HWLOC_NAME(export_obj_userdata_base64)\n#define hwloc_topology_set_userdata_import_callback HWLOC_NAME(topology_set_userdata_import_callback)\n\n#define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e)\n#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES)\n#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)\n#define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic)\n\n#define hwloc_topology_insert_misc_object_by_cpuset HWLOC_NAME(topology_insert_misc_object_by_cpuset)\n#define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent)\n\n#define hwloc_custom_insert_topology HWLOC_NAME(custom_insert_topology)\n#define hwloc_custom_insert_group_object_by_parent HWLOC_NAME(custom_insert_group_object_by_parent)\n\n#define hwloc_restrict_flags_e HWLOC_NAME(restrict_flags_e)\n#define HWLOC_RESTRICT_FLAG_ADAPT_DISTANCES HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_DISTANCES)\n#define HWLOC_RESTRICT_FLAG_ADAPT_MISC HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_MISC)\n#define HWLOC_RESTRICT_FLAG_ADAPT_IO HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_IO)\n#define hwloc_topology_restrict HWLOC_NAME(topology_restrict)\n\n#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)\n#define hwloc_get_type_depth HWLOC_NAME(get_type_depth)\n\n#define hwloc_get_type_depth_e HWLOC_NAME(get_type_depth_e)\n#define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN)\n#define HWLOC_TYPE_DEPTH_MULTIPLE HWLOC_NAME_CAPS(TYPE_DEPTH_MULTIPLE)\n#define HWLOC_TYPE_DEPTH_BRIDGE HWLOC_NAME_CAPS(TYPE_DEPTH_BRIDGE)\n#define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE)\n#define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)\n\n#define hwloc_get_depth_type HWLOC_NAME(get_depth_type)\n#define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth)\n#define hwloc_get_nbobjs_by_type HWLOC_NAME(get_nbobjs_by_type)\n\n#define hwloc_topology_is_thissystem HWLOC_NAME(topology_is_thissystem)\n#define hwloc_topology_get_flags HWLOC_NAME(topology_get_flags)\n\n#define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth )\n#define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type )\n\n#define hwloc_obj_type_string HWLOC_NAME(obj_type_string )\n#define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf )\n#define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf )\n#define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf)\n#define hwloc_obj_type_sscanf HWLOC_NAME(obj_type_sscanf)\n\n#define hwloc_obj_get_info_by_name HWLOC_NAME(obj_get_info_by_name)\n#define hwloc_obj_add_info HWLOC_NAME(obj_add_info)\n\n#define HWLOC_CPUBIND_PROCESS HWLOC_NAME_CAPS(CPUBIND_PROCESS)\n#define HWLOC_CPUBIND_THREAD HWLOC_NAME_CAPS(CPUBIND_THREAD)\n#define HWLOC_CPUBIND_STRICT HWLOC_NAME_CAPS(CPUBIND_STRICT)\n#define HWLOC_CPUBIND_NOMEMBIND HWLOC_NAME_CAPS(CPUBIND_NOMEMBIND)\n\n#define hwloc_cpubind_flags_t HWLOC_NAME(cpubind_flags_t)\n\n#define hwloc_set_cpubind HWLOC_NAME(set_cpubind)\n#define hwloc_get_cpubind HWLOC_NAME(get_cpubind)\n#define hwloc_set_proc_cpubind HWLOC_NAME(set_proc_cpubind)\n#define hwloc_get_proc_cpubind HWLOC_NAME(get_proc_cpubind)\n#define hwloc_set_thread_cpubind HWLOC_NAME(set_thread_cpubind)\n#define hwloc_get_thread_cpubind HWLOC_NAME(get_thread_cpubind)\n\n#define hwloc_get_last_cpu_location HWLOC_NAME(get_last_cpu_location)\n#define hwloc_get_proc_last_cpu_location HWLOC_NAME(get_proc_last_cpu_location)\n\n#define HWLOC_MEMBIND_DEFAULT HWLOC_NAME_CAPS(MEMBIND_DEFAULT)\n#define HWLOC_MEMBIND_FIRSTTOUCH HWLOC_NAME_CAPS(MEMBIND_FIRSTTOUCH)\n#define HWLOC_MEMBIND_BIND HWLOC_NAME_CAPS(MEMBIND_BIND)\n#define HWLOC_MEMBIND_INTERLEAVE HWLOC_NAME_CAPS(MEMBIND_INTERLEAVE)\n#define HWLOC_MEMBIND_REPLICATE HWLOC_NAME_CAPS(MEMBIND_REPLICATE)\n#define HWLOC_MEMBIND_NEXTTOUCH HWLOC_NAME_CAPS(MEMBIND_NEXTTOUCH)\n#define HWLOC_MEMBIND_MIXED HWLOC_NAME_CAPS(MEMBIND_MIXED)\n\n#define hwloc_membind_policy_t HWLOC_NAME(membind_policy_t)\n\n#define HWLOC_MEMBIND_PROCESS HWLOC_NAME_CAPS(MEMBIND_PROCESS)\n#define HWLOC_MEMBIND_THREAD HWLOC_NAME_CAPS(MEMBIND_THREAD)\n#define HWLOC_MEMBIND_STRICT HWLOC_NAME_CAPS(MEMBIND_STRICT)\n#define HWLOC_MEMBIND_MIGRATE HWLOC_NAME_CAPS(MEMBIND_MIGRATE)\n#define HWLOC_MEMBIND_NOCPUBIND HWLOC_NAME_CAPS(MEMBIND_NOCPUBIND)\n#define HWLOC_MEMBIND_BYNODESET HWLOC_NAME_CAPS(MEMBIND_BYNODESET)\n\n#define hwloc_membind_flags_t HWLOC_NAME(membind_flags_t)\n\n#define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset)\n#define hwloc_set_membind HWLOC_NAME(set_membind)\n#define hwloc_get_membind_nodeset HWLOC_NAME(get_membind_nodeset)\n#define hwloc_get_membind HWLOC_NAME(get_membind)\n#define hwloc_set_proc_membind_nodeset HWLOC_NAME(set_proc_membind_nodeset)\n#define hwloc_set_proc_membind HWLOC_NAME(set_proc_membind)\n#define hwloc_get_proc_membind_nodeset HWLOC_NAME(get_proc_membind_nodeset)\n#define hwloc_get_proc_membind HWLOC_NAME(get_proc_membind)\n#define hwloc_set_area_membind_nodeset HWLOC_NAME(set_area_membind_nodeset)\n#define hwloc_set_area_membind HWLOC_NAME(set_area_membind)\n#define hwloc_get_area_membind_nodeset HWLOC_NAME(get_area_membind_nodeset)\n#define hwloc_get_area_membind HWLOC_NAME(get_area_membind)\n#define hwloc_get_area_memlocation HWLOC_NAME(get_area_memlocation)\n#define hwloc_alloc_membind_nodeset HWLOC_NAME(alloc_membind_nodeset)\n#define hwloc_alloc_membind HWLOC_NAME(alloc_membind)\n#define hwloc_alloc HWLOC_NAME(alloc)\n#define hwloc_free HWLOC_NAME(free)\n\n#define hwloc_get_non_io_ancestor_obj HWLOC_NAME(get_non_io_ancestor_obj)\n#define hwloc_get_next_pcidev HWLOC_NAME(get_next_pcidev)\n#define hwloc_get_pcidev_by_busid HWLOC_NAME(get_pcidev_by_busid)\n#define hwloc_get_pcidev_by_busidstring HWLOC_NAME(get_pcidev_by_busidstring)\n#define hwloc_get_next_osdev HWLOC_NAME(get_next_osdev)\n#define hwloc_get_next_bridge HWLOC_NAME(get_next_bridge)\n#define hwloc_bridge_covers_pcibus HWLOC_NAME(bridge_covers_pcibus)\n#define hwloc_get_hostbridge_by_pcibus HWLOC_NAME(get_hostbridge_by_pcibus)\n\n/* hwloc/bitmap.h */\n\n#define hwloc_bitmap_s HWLOC_NAME(bitmap_s)\n#define hwloc_bitmap_t HWLOC_NAME(bitmap_t)\n#define hwloc_const_bitmap_t HWLOC_NAME(const_bitmap_t)\n\n#define hwloc_bitmap_alloc HWLOC_NAME(bitmap_alloc)\n#define hwloc_bitmap_alloc_full HWLOC_NAME(bitmap_alloc_full)\n#define hwloc_bitmap_free HWLOC_NAME(bitmap_free)\n#define hwloc_bitmap_dup HWLOC_NAME(bitmap_dup)\n#define hwloc_bitmap_copy HWLOC_NAME(bitmap_copy)\n#define hwloc_bitmap_snprintf HWLOC_NAME(bitmap_snprintf)\n#define hwloc_bitmap_asprintf HWLOC_NAME(bitmap_asprintf)\n#define hwloc_bitmap_sscanf HWLOC_NAME(bitmap_sscanf)\n#define hwloc_bitmap_list_snprintf HWLOC_NAME(bitmap_list_snprintf)\n#define hwloc_bitmap_list_asprintf HWLOC_NAME(bitmap_list_asprintf)\n#define hwloc_bitmap_list_sscanf HWLOC_NAME(bitmap_list_sscanf)\n#define hwloc_bitmap_taskset_snprintf HWLOC_NAME(bitmap_taskset_snprintf)\n#define hwloc_bitmap_taskset_asprintf HWLOC_NAME(bitmap_taskset_asprintf)\n#define hwloc_bitmap_taskset_sscanf HWLOC_NAME(bitmap_taskset_sscanf)\n#define hwloc_bitmap_zero HWLOC_NAME(bitmap_zero)\n#define hwloc_bitmap_fill HWLOC_NAME(bitmap_fill)\n#define hwloc_bitmap_from_ulong HWLOC_NAME(bitmap_from_ulong)\n\n#define hwloc_bitmap_from_ith_ulong HWLOC_NAME(bitmap_from_ith_ulong)\n#define hwloc_bitmap_to_ulong HWLOC_NAME(bitmap_to_ulong)\n#define hwloc_bitmap_to_ith_ulong HWLOC_NAME(bitmap_to_ith_ulong)\n#define hwloc_bitmap_only HWLOC_NAME(bitmap_only)\n#define hwloc_bitmap_allbut HWLOC_NAME(bitmap_allbut)\n#define hwloc_bitmap_set HWLOC_NAME(bitmap_set)\n#define hwloc_bitmap_set_range HWLOC_NAME(bitmap_set_range)\n#define hwloc_bitmap_set_ith_ulong HWLOC_NAME(bitmap_set_ith_ulong)\n#define hwloc_bitmap_clr HWLOC_NAME(bitmap_clr)\n#define hwloc_bitmap_clr_range HWLOC_NAME(bitmap_clr_range)\n#define hwloc_bitmap_isset HWLOC_NAME(bitmap_isset)\n#define hwloc_bitmap_iszero HWLOC_NAME(bitmap_iszero)\n#define hwloc_bitmap_isfull HWLOC_NAME(bitmap_isfull)\n#define hwloc_bitmap_isequal HWLOC_NAME(bitmap_isequal)\n#define hwloc_bitmap_intersects HWLOC_NAME(bitmap_intersects)\n#define hwloc_bitmap_isincluded HWLOC_NAME(bitmap_isincluded)\n#define hwloc_bitmap_or HWLOC_NAME(bitmap_or)\n#define hwloc_bitmap_and HWLOC_NAME(bitmap_and)\n#define hwloc_bitmap_andnot HWLOC_NAME(bitmap_andnot)\n#define hwloc_bitmap_xor HWLOC_NAME(bitmap_xor)\n#define hwloc_bitmap_not HWLOC_NAME(bitmap_not)\n#define hwloc_bitmap_first HWLOC_NAME(bitmap_first)\n#define hwloc_bitmap_last HWLOC_NAME(bitmap_last)\n#define hwloc_bitmap_next HWLOC_NAME(bitmap_next)\n#define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify)\n#define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first)\n#define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare)\n#define hwloc_bitmap_weight HWLOC_NAME(bitmap_weight)\n\n/* hwloc/cpuset.h -- deprecated but still available */\n\n#define hwloc_cpuset_alloc HWLOC_NAME(cpuset_alloc)\n#define hwloc_cpuset_free HWLOC_NAME(cpuset_free)\n#define hwloc_cpuset_dup HWLOC_NAME(cpuset_dup)\n#define hwloc_cpuset_copy HWLOC_NAME(cpuset_copy)\n#define hwloc_cpuset_snprintf HWLOC_NAME(cpuset_snprintf)\n#define hwloc_cpuset_asprintf HWLOC_NAME(cpuset_asprintf)\n#define hwloc_cpuset_from_string HWLOC_NAME(cpuset_from_string)\n#define hwloc_cpuset_zero HWLOC_NAME(cpuset_zero)\n#define hwloc_cpuset_fill HWLOC_NAME(cpuset_fill)\n#define hwloc_cpuset_from_ulong HWLOC_NAME(cpuset_from_ulong)\n#define hwloc_cpuset_taskset_snprintf HWLOC_NAME(cpuset_taskset_snprintf)\n#define hwloc_cpuset_taskset_asprintf HWLOC_NAME(cpuset_taskset_asprintf)\n#define hwloc_cpuset_taskset_sscanf HWLOC_NAME(cpuset_taskset_sscanf)\n\n#define hwloc_cpuset_from_ith_ulong HWLOC_NAME(cpuset_from_ith_ulong)\n#define hwloc_cpuset_to_ulong HWLOC_NAME(cpuset_to_ulong)\n#define hwloc_cpuset_to_ith_ulong HWLOC_NAME(cpuset_to_ith_ulong)\n#define hwloc_cpuset_cpu HWLOC_NAME(cpuset_cpu)\n#define hwloc_cpuset_all_but_cpu HWLOC_NAME(cpuset_all_but_cpu)\n#define hwloc_cpuset_set HWLOC_NAME(cpuset_set)\n#define hwloc_cpuset_set_range HWLOC_NAME(cpuset_set_range)\n#define hwloc_cpuset_set_ith_ulong HWLOC_NAME(cpuset_set_ith_ulong)\n#define hwloc_cpuset_clr HWLOC_NAME(cpuset_clr)\n#define hwloc_cpuset_clr_range HWLOC_NAME(cpuset_clr_range)\n#define hwloc_cpuset_isset HWLOC_NAME(cpuset_isset)\n#define hwloc_cpuset_iszero HWLOC_NAME(cpuset_iszero)\n#define hwloc_cpuset_isfull HWLOC_NAME(cpuset_isfull)\n#define hwloc_cpuset_isequal HWLOC_NAME(cpuset_isequal)\n#define hwloc_cpuset_intersects HWLOC_NAME(cpuset_intersects)\n#define hwloc_cpuset_isincluded HWLOC_NAME(cpuset_isincluded)\n#define hwloc_cpuset_or HWLOC_NAME(cpuset_or)\n#define hwloc_cpuset_and HWLOC_NAME(cpuset_and)\n#define hwloc_cpuset_andnot HWLOC_NAME(cpuset_andnot)\n#define hwloc_cpuset_xor HWLOC_NAME(cpuset_xor)\n#define hwloc_cpuset_not HWLOC_NAME(cpuset_not)\n#define hwloc_cpuset_first HWLOC_NAME(cpuset_first)\n#define hwloc_cpuset_last HWLOC_NAME(cpuset_last)\n#define hwloc_cpuset_next HWLOC_NAME(cpuset_next)\n#define hwloc_cpuset_singlify HWLOC_NAME(cpuset_singlify)\n#define hwloc_cpuset_compare_first HWLOC_NAME(cpuset_compare_first)\n#define hwloc_cpuset_compare HWLOC_NAME(cpuset_compare)\n#define hwloc_cpuset_weight HWLOC_NAME(cpuset_weight)\n\n/* hwloc/helper.h */\n\n#define hwloc_get_type_or_below_depth HWLOC_NAME(get_type_or_below_depth)\n#define hwloc_get_type_or_above_depth HWLOC_NAME(get_type_or_above_depth)\n#define hwloc_get_root_obj HWLOC_NAME(get_root_obj)\n#define hwloc_get_ancestor_obj_by_depth HWLOC_NAME(get_ancestor_obj_by_depth)\n#define hwloc_get_ancestor_obj_by_type HWLOC_NAME(get_ancestor_obj_by_type)\n#define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth)\n#define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type)\n#define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index)\n#define hwloc_get_numanode_obj_by_os_index HWLOC_NAME(get_numanode_obj_by_os_index)\n#define hwloc_get_next_child HWLOC_NAME(get_next_child)\n#define hwloc_get_common_ancestor_obj HWLOC_NAME(get_common_ancestor_obj)\n#define hwloc_obj_is_in_subtree HWLOC_NAME(obj_is_in_subtree)\n#define hwloc_get_first_largest_obj_inside_cpuset HWLOC_NAME(get_first_largest_obj_inside_cpuset)\n#define hwloc_get_largest_objs_inside_cpuset HWLOC_NAME(get_largest_objs_inside_cpuset)\n#define hwloc_get_next_obj_inside_cpuset_by_depth HWLOC_NAME(get_next_obj_inside_cpuset_by_depth)\n#define hwloc_get_next_obj_inside_cpuset_by_type HWLOC_NAME(get_next_obj_inside_cpuset_by_type)\n#define hwloc_get_obj_inside_cpuset_by_depth HWLOC_NAME(get_obj_inside_cpuset_by_depth)\n#define hwloc_get_obj_inside_cpuset_by_type HWLOC_NAME(get_obj_inside_cpuset_by_type)\n#define hwloc_get_nbobjs_inside_cpuset_by_depth HWLOC_NAME(get_nbobjs_inside_cpuset_by_depth)\n#define hwloc_get_nbobjs_inside_cpuset_by_type HWLOC_NAME(get_nbobjs_inside_cpuset_by_type)\n#define hwloc_get_obj_index_inside_cpuset HWLOC_NAME(get_obj_index_inside_cpuset)\n#define hwloc_get_child_covering_cpuset HWLOC_NAME(get_child_covering_cpuset)\n#define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset)\n#define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth)\n#define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type)\n#define hwloc_get_cache_type_depth HWLOC_NAME(get_cache_type_depth)\n#define hwloc_get_cache_covering_cpuset HWLOC_NAME(get_cache_covering_cpuset)\n#define hwloc_get_shared_cache_covering_obj HWLOC_NAME(get_shared_cache_covering_obj)\n#define hwloc_get_closest_objs HWLOC_NAME(get_closest_objs)\n#define hwloc_get_obj_below_by_type HWLOC_NAME(get_obj_below_by_type)\n#define hwloc_get_obj_below_array_by_type HWLOC_NAME(get_obj_below_array_by_type)\n#define hwloc_distrib_flags_e HWLOC_NAME(distrib_flags_e)\n#define HWLOC_DISTRIB_FLAG_REVERSE HWLOC_NAME_CAPS(DISTRIB_FLAG_REVERSE)\n#define hwloc_distrib HWLOC_NAME(distrib)\n#define hwloc_alloc_membind_policy HWLOC_NAME(alloc_membind_policy)\n#define hwloc_alloc_membind_policy_nodeset HWLOC_NAME(alloc_membind_policy_nodeset)\n#define hwloc_topology_get_complete_cpuset HWLOC_NAME(topology_get_complete_cpuset)\n#define hwloc_topology_get_topology_cpuset HWLOC_NAME(topology_get_topology_cpuset)\n#define hwloc_topology_get_online_cpuset HWLOC_NAME(topology_get_online_cpuset)\n#define hwloc_topology_get_allowed_cpuset HWLOC_NAME(topology_get_allowed_cpuset)\n#define hwloc_topology_get_complete_nodeset HWLOC_NAME(topology_get_complete_nodeset)\n#define hwloc_topology_get_topology_nodeset HWLOC_NAME(topology_get_topology_nodeset)\n#define hwloc_topology_get_allowed_nodeset HWLOC_NAME(topology_get_allowed_nodeset)\n#define hwloc_cpuset_to_nodeset HWLOC_NAME(cpuset_to_nodeset)\n#define hwloc_cpuset_to_nodeset_strict HWLOC_NAME(cpuset_to_nodeset_strict)\n#define hwloc_cpuset_from_nodeset HWLOC_NAME(cpuset_from_nodeset)\n#define hwloc_cpuset_from_nodeset_strict HWLOC_NAME(cpuset_from_nodeset_strict)\n#define hwloc_get_whole_distance_matrix_by_depth HWLOC_NAME(get_whole_distance_matrix_by_depth)\n#define hwloc_get_whole_distance_matrix_by_type HWLOC_NAME(get_whole_distance_matrix_by_type)\n#define hwloc_get_distance_matrix_covering_obj_by_depth HWLOC_NAME(get_distance_matrix_covering_obj_by_depth)\n#define hwloc_get_latency HWLOC_NAME(get_latency)\n\n/* diff.h */\n\n#define hwloc_topology_diff_obj_attr_type_e HWLOC_NAME(topology_diff_obj_attr_type_e)\n#define hwloc_topology_diff_obj_attr_type_t HWLOC_NAME(topology_diff_obj_attr_type_t)\n#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_SIZE)\n#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_NAME)\n#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_INFO)\n#define hwloc_topology_diff_obj_attr_u HWLOC_NAME(topology_diff_obj_attr_u)\n#define hwloc_topology_diff_obj_attr_generic_s HWLOC_NAME(topology_diff_obj_attr_generic_s)\n#define hwloc_topology_diff_obj_attr_uint64_s HWLOC_NAME(topology_diff_obj_attr_uint64_s)\n#define hwloc_topology_diff_obj_attr_string_s HWLOC_NAME(topology_diff_obj_attr_string_s)\n#define hwloc_topology_diff_type_e HWLOC_NAME(topology_diff_type_e)\n#define hwloc_topology_diff_type_t HWLOC_NAME(topology_diff_type_t)\n#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR)\n#define HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX HWLOC_NAME_CAPS(TOPOLOGY_DIFF_TOO_COMPLEX)\n#define hwloc_topology_diff_u HWLOC_NAME(topology_diff_u)\n#define hwloc_topology_diff_t HWLOC_NAME(topology_diff_t)\n#define hwloc_topology_diff_generic_s HWLOC_NAME(topology_diff_generic_s)\n#define hwloc_topology_diff_obj_attr_s HWLOC_NAME(topology_diff_obj_attr_s)\n#define hwloc_topology_diff_too_complex_s HWLOC_NAME(topology_diff_too_complex_s)\n#define hwloc_topology_diff_build HWLOC_NAME(topology_diff_build)\n#define hwloc_topology_diff_apply_flags_e HWLOC_NAME(topology_diff_apply_flags_e)\n#define HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_APPLY_REVERSE)\n#define hwloc_topology_diff_apply HWLOC_NAME(topology_diff_apply)\n#define hwloc_topology_diff_destroy HWLOC_NAME(topology_diff_destroy)\n#define hwloc_topology_diff_load_xml HWLOC_NAME(topology_diff_load_xml)\n#define hwloc_topology_diff_export_xml HWLOC_NAME(topology_diff_export_xml)\n#define hwloc_topology_diff_load_xmlbuffer HWLOC_NAME(topology_diff_load_xmlbuffer)\n#define hwloc_topology_diff_export_xmlbuffer HWLOC_NAME(topology_diff_export_xmlbuffer)\n\n/* glibc-sched.h */\n\n#define hwloc_cpuset_to_glibc_sched_affinity HWLOC_NAME(cpuset_to_glibc_sched_affinity)\n#define hwloc_cpuset_from_glibc_sched_affinity HWLOC_NAME(cpuset_from_glibc_sched_affinity)\n\n/* linux-libnuma.h */\n\n#define hwloc_cpuset_to_linux_libnuma_ulongs HWLOC_NAME(cpuset_to_linux_libnuma_ulongs)\n#define hwloc_nodeset_to_linux_libnuma_ulongs HWLOC_NAME(nodeset_to_linux_libnuma_ulongs)\n#define hwloc_cpuset_from_linux_libnuma_ulongs HWLOC_NAME(cpuset_from_linux_libnuma_ulongs)\n#define hwloc_nodeset_from_linux_libnuma_ulongs HWLOC_NAME(nodeset_from_linux_libnuma_ulongs)\n#define hwloc_cpuset_to_linux_libnuma_bitmask HWLOC_NAME(cpuset_to_linux_libnuma_bitmask)\n#define hwloc_nodeset_to_linux_libnuma_bitmask HWLOC_NAME(nodeset_to_linux_libnuma_bitmask)\n#define hwloc_cpuset_from_linux_libnuma_bitmask HWLOC_NAME(cpuset_from_linux_libnuma_bitmask)\n#define hwloc_nodeset_from_linux_libnuma_bitmask HWLOC_NAME(nodeset_from_linux_libnuma_bitmask)\n\n/* linux.h */\n\n#define hwloc_linux_parse_cpumap_file HWLOC_NAME(linux_parse_cpumap_file)\n#define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind)\n#define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind)\n#define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location)\n\n/* openfabrics-verbs.h */\n\n#define hwloc_ibv_get_device_cpuset HWLOC_NAME(ibv_get_device_cpuset)\n#define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev)\n#define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name)\n\n/* myriexpress.h */\n\n#define hwloc_mx_board_get_device_cpuset HWLOC_NAME(mx_board_get_device_cpuset)\n#define hwloc_mx_endpoint_get_device_cpuset HWLOC_NAME(mx_endpoint_get_device_cpuset)\n\n/* intel-mic.h */\n\n#define hwloc_intel_mic_get_device_cpuset HWLOC_NAME(intel_mic_get_device_cpuset)\n#define hwloc_intel_mic_get_device_osdev_by_index HWLOC_NAME(intel_mic_get_device_osdev_by_index)\n\n/* opencl.h */\n\n#define hwloc_opencl_get_device_cpuset HWLOC_NAME(opencl_get_device_cpuset)\n#define hwloc_opencl_get_device_osdev HWLOC_NAME(opencl_get_device_osdev)\n#define hwloc_opencl_get_device_osdev_by_index HWLOC_NAME(opencl_get_device_osdev_by_index)\n\n/* cuda.h */\n\n#define hwloc_cuda_get_device_pci_ids HWLOC_NAME(cuda_get_device_pci_ids)\n#define hwloc_cuda_get_device_cpuset HWLOC_NAME(cuda_get_device_cpuset)\n#define hwloc_cuda_get_device_pcidev HWLOC_NAME(cuda_get_device_pcidev)\n#define hwloc_cuda_get_device_osdev HWLOC_NAME(cuda_get_device_osdev)\n#define hwloc_cuda_get_device_osdev_by_index HWLOC_NAME(cuda_get_device_osdev_by_index)\n\n/* cudart.h */\n\n#define hwloc_cudart_get_device_pci_ids HWLOC_NAME(cudart_get_device_pci_ids)\n#define hwloc_cudart_get_device_cpuset HWLOC_NAME(cudart_get_device_cpuset)\n#define hwloc_cudart_get_device_pcidev HWLOC_NAME(cudart_get_device_pcidev)\n#define hwloc_cudart_get_device_osdev_by_index HWLOC_NAME(cudart_get_device_osdev_by_index)\n\n/* nvml.h */\n\n#define hwloc_nvml_get_device_cpuset HWLOC_NAME(nvml_get_device_cpuset)\n#define hwloc_nvml_get_device_osdev HWLOC_NAME(nvml_get_device_osdev)\n#define hwloc_nvml_get_device_osdev_by_index HWLOC_NAME(nvml_get_device_osdev_by_index)\n\n/* gl.h */\n\n#define hwloc_gl_get_display_osdev_by_port_device HWLOC_NAME(gl_get_display_osdev_by_port_device)\n#define hwloc_gl_get_display_osdev_by_name HWLOC_NAME(gl_get_display_osdev_by_name)\n#define hwloc_gl_get_display_by_osdev HWLOC_NAME(gl_get_display_by_osdev)\n\n/* hwloc/plugins.h */\n\n#define hwloc_disc_component_type_e HWLOC_NAME(disc_component_type_e)\n#define HWLOC_DISC_COMPONENT_TYPE_CPU HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_CPU)\n#define HWLOC_DISC_COMPONENT_TYPE_GLOBAL HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_GLOBAL)\n#define HWLOC_DISC_COMPONENT_TYPE_MISC HWLOC_NAME_CAPS(DISC_COMPONENT_TYPE_MISC)\n#define hwloc_disc_component_type_t HWLOC_NAME(disc_component_type_t)\n#define hwloc_disc_component HWLOC_NAME(disc_component)\n\n#define hwloc_backend HWLOC_NAME(backend)\n#define hwloc_backend_flag_e HWLOC_NAME(backend_flag_e)\n#define HWLOC_BACKEND_FLAG_NEED_LEVELS HWLOC_NAME_CAPS(BACKEND_FLAG_NEED_LEVELS)\n\n#define hwloc_backend_alloc HWLOC_NAME(backend_alloc)\n#define hwloc_backend_enable HWLOC_NAME(backend_enable)\n#define hwloc_backends_get_obj_cpuset HWLOC_NAME(backends_get_obj_cpuset)\n#define hwloc_backends_notify_new_object HWLOC_NAME(backends_notify_new_object)\n\n#define hwloc_component_type_e HWLOC_NAME(component_type_e)\n#define HWLOC_COMPONENT_TYPE_DISC HWLOC_NAME_CAPS(COMPONENT_TYPE_DISC)\n#define HWLOC_COMPONENT_TYPE_XML HWLOC_NAME_CAPS(COMPONENT_TYPE_XML)\n#define hwloc_component_type_t HWLOC_NAME(component_type_t)\n#define hwloc_component HWLOC_NAME(component)\n\n#define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)\n\n#define hwloc_insert_object_by_cpuset HWLOC_NAME(insert_object_by_cpuset)\n#define hwloc_report_error_t HWLOC_NAME(report_error_t)\n#define hwloc_report_os_error HWLOC_NAME(report_os_error)\n#define hwloc_hide_errors HWLOC_NAME(hide_errors)\n#define hwloc__insert_object_by_cpuset HWLOC_NAME(_insert_object_by_cpuset)\n#define hwloc_insert_object_by_parent HWLOC_NAME(insert_object_by_parent)\n#define hwloc_alloc_setup_object HWLOC_NAME(alloc_setup_object)\n#define hwloc_fill_object_sets HWLOC_NAME(fill_object_sets)\n\n#define hwloc_insert_pci_device_list HWLOC_NAME(insert_pci_device_list)\n#define hwloc_pci_find_cap HWLOC_NAME(pci_find_cap)\n#define hwloc_pci_find_linkspeed HWLOC_NAME(pci_find_linkspeed)\n#define hwloc_pci_prepare_bridge HWLOC_NAME(pci_prepare_bridge)\n\n/* hwloc/deprecated.h */\n\n#define hwloc_obj_type_of_string HWLOC_NAME(obj_type_of_string )\n#define hwloc_obj_snprintf HWLOC_NAME(obj_snprintf)\n#define hwloc_distributev HWLOC_NAME(distributev)\n#define hwloc_distribute HWLOC_NAME(distribute)\n\n/* private/debug.h */\n\n#define hwloc_debug_enabled HWLOC_NAME(debug_enabled)\n#define hwloc_debug HWLOC_NAME(debug)\n\n/* private/misc.h */\n\n#define hwloc_snprintf HWLOC_NAME(snprintf)\n#define hwloc_namecoloncmp HWLOC_NAME(namecoloncmp)\n#define hwloc_ffsl_manual HWLOC_NAME(ffsl_manual)\n#define hwloc_ffs32 HWLOC_NAME(ffs32)\n#define hwloc_ffsl_from_ffs32 HWLOC_NAME(ffsl_from_ffs32)\n#define hwloc_flsl_manual HWLOC_NAME(flsl_manual)\n#define hwloc_fls32 HWLOC_NAME(fls32)\n#define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32)\n#define hwloc_weight_long HWLOC_NAME(weight_long)\n#define hwloc_strncasecmp HWLOC_NAME(strncasecmp)\n\n/* private/cpuid-x86.h */\n\n#define hwloc_have_x86_cpuid HWLOC_NAME(have_x86_cpuid)\n#define hwloc_x86_cpuid HWLOC_NAME(x86_cpuid)\n\n/* private/xml.h */\n\n#define hwloc__xml_verbose HWLOC_NAME(_xml_verbose)\n\n#define hwloc__xml_import_state_s HWLOC_NAME(_xml_import_state_s)\n#define hwloc__xml_import_state_t HWLOC_NAME(_xml_import_state_t)\n#define hwloc__xml_import_diff HWLOC_NAME(_xml_import_diff)\n#define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s)\n#define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s)\n#define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t)\n#define hwloc__xml_export_object HWLOC_NAME(_xml_export_object)\n#define hwloc__xml_export_diff HWLOC_NAME(_xml_export_diff)\n\n#define hwloc_xml_callbacks HWLOC_NAME(xml_callbacks)\n#define hwloc_xml_component HWLOC_NAME(xml_component)\n#define hwloc_xml_callbacks_register HWLOC_NAME(xml_callbacks_register)\n#define hwloc_xml_callbacks_reset HWLOC_NAME(xml_callbacks_reset)\n\n/* private/components.h */\n\n#define hwloc_disc_component_force_enable HWLOC_NAME(disc_component_force_enable)\n#define hwloc_disc_components_enable_others HWLOC_NAME(disc_components_instantiate_others)\n\n#define hwloc_backends_disable_all HWLOC_NAME(backends_disable_all)\n#define hwloc_backends_is_thissystem HWLOC_NAME(backends_is_thissystem)\n\n#define hwloc_components_init HWLOC_NAME(components_init)\n#define hwloc_components_destroy_all HWLOC_NAME(components_destroy_all)\n\n/* private/private.h */\n\n#define hwloc_ignore_type_e HWLOC_NAME(ignore_type_e)\n\n#define HWLOC_IGNORE_TYPE_NEVER HWLOC_NAME_CAPS(IGNORE_TYPE_NEVER)\n#define HWLOC_IGNORE_TYPE_KEEP_STRUCTURE HWLOC_NAME_CAPS(IGNORE_TYPE_KEEP_STRUCTURE)\n#define HWLOC_IGNORE_TYPE_ALWAYS HWLOC_NAME_CAPS(IGNORE_TYPE_ALWAYS)\n\n#define hwloc_os_distances_s HWLOC_NAME(os_distances_s)\n\n#define hwloc_xml_imported_distances_s HWLOC_NAME(xml_imported_distances_s)\n\n#define hwloc_alloc_obj_cpusets HWLOC_NAME(alloc_obj_cpusets)\n#define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level)\n#define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)\n#define hwloc_get_sysctl HWLOC_NAME(get_sysctl)\n#define hwloc_fallback_nbprocessors HWLOC_NAME(fallback_nbprocessors)\n#define hwloc_connect_children HWLOC_NAME(connect_children)\n#define hwloc_connect_levels HWLOC_NAME(connect_levels)\n\n#define hwloc__object_cpusets_compare_first HWLOC_NAME(_object_cpusets_compare_first)\n\n#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)\n#define hwloc_topology_clear HWLOC_NAME(topology_clear)\n\n#define hwloc__add_info HWLOC_NAME(_add_info)\n#define hwloc__find_info_slot HWLOC_NAME(_find_info_slot)\n#define hwloc__move_infos HWLOC_NAME(_move_infos)\n#define hwloc__free_infos HWLOC_NAME(_free_infos)\n\n#define hwloc_binding_hooks HWLOC_NAME(binding_hooks)\n#define hwloc_set_native_binding_hooks HWLOC_NAME(set_native_binding_hooks)\n#define hwloc_set_binding_hooks HWLOC_NAME(set_binding_hooks)\n\n#define hwloc_set_linuxfs_hooks HWLOC_NAME(set_linuxfs_hooks)\n#define hwloc_set_bgq_hooks HWLOC_NAME(set_bgq_hooks)\n#define hwloc_set_solaris_hooks HWLOC_NAME(set_solaris_hooks)\n#define hwloc_set_aix_hooks HWLOC_NAME(set_aix_hooks)\n#define hwloc_set_osf_hooks HWLOC_NAME(set_osf_hooks)\n#define hwloc_set_windows_hooks HWLOC_NAME(set_windows_hooks)\n#define hwloc_set_darwin_hooks HWLOC_NAME(set_darwin_hooks)\n#define hwloc_set_freebsd_hooks HWLOC_NAME(set_freebsd_hooks)\n#define hwloc_set_netbsd_hooks HWLOC_NAME(set_netbsd_hooks)\n#define hwloc_set_hpux_hooks HWLOC_NAME(set_hpux_hooks)\n\n#define hwloc_look_hardwired_fujitsu_k HWLOC_NAME(look_hardwired_fujitsu_k)\n#define hwloc_look_hardwired_fujitsu_fx10 HWLOC_NAME(look_hardwired_fujitsu_fx10)\n#define hwloc_look_hardwired_fujitsu_fx100 HWLOC_NAME(look_hardwired_fujitsu_fx100)\n\n#define hwloc_add_uname_info HWLOC_NAME(add_uname_info)\n#define hwloc_free_unlinked_object HWLOC_NAME(free_unlinked_object)\n#define hwloc__duplicate_objects HWLOC_NAME(_duplicate_objects)\n\n#define hwloc_alloc_heap HWLOC_NAME(alloc_heap)\n#define hwloc_alloc_mmap HWLOC_NAME(alloc_mmap)\n#define hwloc_free_heap HWLOC_NAME(free_heap)\n#define hwloc_free_mmap HWLOC_NAME(free_mmap)\n#define hwloc_alloc_or_fail HWLOC_NAME(alloc_or_fail)\n\n#define hwloc_distances_init HWLOC_NAME(distances_init)\n#define hwloc_distances_destroy HWLOC_NAME(distances_destroy)\n#define hwloc_distances_set HWLOC_NAME(distances_set)\n#define hwloc_distances_set_from_env HWLOC_NAME(distances_set_from_env)\n#define hwloc_distances_restrict_os HWLOC_NAME(distances_restrict_os)\n#define hwloc_distances_restrict HWLOC_NAME(distances_restrict)\n#define hwloc_distances_finalize_os HWLOC_NAME(distances_finalize_os)\n#define hwloc_distances_finalize_logical HWLOC_NAME(distances_finalize_logical)\n#define hwloc_clear_object_distances HWLOC_NAME(clear_object_distances)\n#define hwloc_clear_object_distances_one HWLOC_NAME(clear_object_distances_one)\n#define hwloc_group_by_distances HWLOC_NAME(group_by_distances)\n\n#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)\n#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)\n\n#define hwloc_obj_add_info_nodup HWLOC_NAME(obj_add_info_nodup)\n\n#define hwloc_progname HWLOC_NAME(progname)\n\n#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)\n\n/* private/solaris-chiptype.h */\n\n#define hwloc_solaris_chip_info_s HWLOC_NAME(solaris_chip_info_s)\n#define hwloc_solaris_get_chip_info HWLOC_NAME(solaris_get_chip_info)\n\n#endif /* HWLOC_SYM_TRANSFORM */\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n#endif /* HWLOC_RENAME_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/include/hwloc.h",
    "content": "/*\n * Copyright © 2009 CNRS\n * Copyright © 2009-2017 Inria.  All rights reserved.\n * Copyright © 2009-2012 Université Bordeaux\n * Copyright © 2009-2011 Cisco Systems, Inc.  All rights reserved.\n * See COPYING in top-level directory.\n */\n\n/*=====================================================================\n *                 PLEASE GO READ THE DOCUMENTATION!\n *         ------------------------------------------------\n *               $tarball_directory/doc/doxygen-doc/\n *                                or\n *           http://www.open-mpi.org/projects/hwloc/doc/\n *=====================================================================\n *\n * FAIR WARNING: Do NOT expect to be able to figure out all the\n * subtleties of hwloc by simply reading function prototypes and\n * constant descrptions here in this file.\n *\n * Hwloc has wonderful documentation in both PDF and HTML formats for\n * your reading pleasure.  The formal documentation explains a LOT of\n * hwloc-specific concepts, provides definitions, and discusses the\n * \"big picture\" for many of the things that you'll find here in this\n * header file.\n *\n * The PDF/HTML documentation was generated via Doxygen; much of what\n * you'll see in there is also here in this file.  BUT THERE IS A LOT\n * THAT IS IN THE PDF/HTML THAT IS ***NOT*** IN hwloc.h!\n *\n * There are entire paragraph-length descriptions, discussions, and\n * pretty prictures to explain subtle corner cases, provide concrete\n * examples, etc.\n *\n * Please, go read the documentation.  :-)\n *\n * Moreover there are several examples of hwloc use under doc/examples\n * in the source tree.\n *\n *=====================================================================*/\n\n/** \\file\n * \\brief The hwloc API.\n *\n * See hwloc/bitmap.h for bitmap specific macros.\n * See hwloc/helper.h for high-level topology traversal helpers.\n * See hwloc/inlines.h for the actual inline code of some functions below.\n */\n\n#ifndef HWLOC_H\n#define HWLOC_H\n\n#include <hwloc/autogen/config.h>\n#include <sys/types.h>\n#include <stdio.h>\n#include <string.h>\n#include <limits.h>\n\n/*\n * Symbol transforms\n */\n#include <hwloc/rename.h>\n\n/*\n * Bitmap definitions\n */\n\n#include <hwloc/bitmap.h>\n#include <hwloc/cpuset.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/** \\defgroup hwlocality_api_version API version\n * @{\n */\n\n/** \\brief Indicate at build time which hwloc API version is being used.\n *\n * This number is updated to (X>>16)+(Y>>8)+Z when a new release X.Y.Z\n * actually modifies the API.\n *\n * Users may check for available features at build time using this number\n * (see \\ref faq_upgrade).\n */\n#define HWLOC_API_VERSION 0x00010b06\n\n/** \\brief Indicate at runtime which hwloc API version was used at build time.\n *\n * Should be ::HWLOC_API_VERSION if running on the same version.\n */\nHWLOC_DECLSPEC unsigned hwloc_get_api_version(void);\n\n/** \\brief Current component and plugin ABI version (see hwloc/plugins.h) */\n#define HWLOC_COMPONENT_ABI 4\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_object_sets Object Sets (hwloc_cpuset_t and hwloc_nodeset_t)\n *\n * Hwloc uses bitmaps to represent two distinct kinds of object sets:\n * CPU sets (::hwloc_cpuset_t) and NUMA node sets (::hwloc_nodeset_t).\n * These types are both typedefs to a common back end type\n * (::hwloc_bitmap_t), and therefore all the hwloc bitmap functions\n * are applicable to both ::hwloc_cpuset_t and ::hwloc_nodeset_t (see\n * \\ref hwlocality_bitmap).\n *\n * The rationale for having two different types is that even though\n * the actions one wants to perform on these types are the same (e.g.,\n * enable and disable individual items in the set/mask), they're used\n * in very different contexts: one for specifying which processors to\n * use and one for specifying which NUMA nodes to use.  Hence, the\n * name difference is really just to reflect the intent of where the\n * type is used.\n *\n * @{\n */\n\n/** \\brief A CPU set is a bitmap whose bits are set according to CPU\n * physical OS indexes.\n *\n * It may be consulted and modified with the bitmap API as any\n * ::hwloc_bitmap_t (see hwloc/bitmap.h).\n *\n * Each bit may be converted into a PU object using\n * hwloc_get_pu_obj_by_os_index().\n */\ntypedef hwloc_bitmap_t hwloc_cpuset_t;\n/** \\brief A non-modifiable ::hwloc_cpuset_t. */\ntypedef hwloc_const_bitmap_t hwloc_const_cpuset_t;\n\n/** \\brief A node set is a bitmap whose bits are set according to NUMA\n * memory node physical OS indexes.\n *\n * It may be consulted and modified with the bitmap API as any\n * ::hwloc_bitmap_t (see hwloc/bitmap.h).\n * Each bit may be converted into a NUMA node object using\n * hwloc_get_numanode_obj_by_os_index().\n *\n * When binding memory on a system without any NUMA node\n * (when the whole memory is considered as a single memory bank),\n * the nodeset may be either empty (no memory selected)\n * or full (whole system memory selected).\n *\n * See also \\ref hwlocality_helper_nodeset_convert.\n */\ntypedef hwloc_bitmap_t hwloc_nodeset_t;\n/** \\brief A non-modifiable ::hwloc_nodeset_t.\n */\ntypedef hwloc_const_bitmap_t hwloc_const_nodeset_t;\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_object_types Object Types\n * @{\n */\n\n/** \\brief Type of topology object.\n *\n * \\note Do not rely on the ordering or completeness of the values as new ones\n * may be defined in the future!  If you need to compare types, use\n * hwloc_compare_types() instead.\n */\ntypedef enum {\n    /* ***************************************************************\n       WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n\n       If new enum values are added here, you MUST also go update the\n       obj_type_order[] and obj_order_type[] arrays in src/topology.c.\n\n       WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n       *************************************************************** */\n\n  HWLOC_OBJ_SYSTEM,\t/**< \\brief Whole system (may be a cluster of machines).\n  \t\t\t  * The whole system that is accessible to hwloc.\n\t\t\t  * That may comprise several machines in SSI systems\n\t\t\t  * like Kerrighed.\n\t\t\t  */\n  HWLOC_OBJ_MACHINE,\t/**< \\brief Machine.\n\t\t\t  * The typical root object type.\n\t\t\t  * A set of processors and memory with cache\n\t\t\t  * coherency.\n\t\t\t  */\n  HWLOC_OBJ_NUMANODE,\t/**< \\brief NUMA node.\n\t\t\t  * An object that contains memory that is directly\n\t\t\t  * and byte-accessible to the host processors.\n\t\t\t  * It is usually close to some cores (the corresponding objects\n\t\t\t  * are descendants of the NUMA node object in the hwloc tree).\n\t\t\t  *\n\t\t\t  * There is always at one such object in the topology\n\t\t\t  * even if the machine is not NUMA.\n\t\t\t  */\n  HWLOC_OBJ_PACKAGE,\t/**< \\brief Physical package.\n\t\t\t  * The physical package that usually gets inserted\n\t\t\t  * into a socket on the motherboard.\n\t\t\t  * A processor package usually contains multiple cores.\n\t\t\t  */\n  HWLOC_OBJ_CACHE,\t/**< \\brief Cache.\n\t\t\t  * Can be L1i, L1d, L2, L3, ...\n\t\t\t  */\n  HWLOC_OBJ_CORE,\t/**< \\brief Core.\n\t\t\t  * A computation unit (may be shared by several\n\t\t\t  * logical processors).\n\t\t\t  */\n  HWLOC_OBJ_PU,\t\t/**< \\brief Processing Unit, or (Logical) Processor.\n\t\t\t  * An execution unit (may share a core with some\n\t\t\t  * other logical processors, e.g. in the case of\n\t\t\t  * an SMT core).\n\t\t\t  *\n\t\t\t  * Objects of this kind are always reported and can\n\t\t\t  * thus be used as fallback when others are not.\n\t\t\t  */\n\n  HWLOC_OBJ_GROUP,\t/**< \\brief Group objects.\n\t\t\t  * Objects which do not fit in the above but are\n\t\t\t  * detected by hwloc and are useful to take into\n\t\t\t  * account for affinity. For instance, some operating systems\n\t\t\t  * expose their arbitrary processors aggregation this\n\t\t\t  * way.  And hwloc may insert such objects to group\n\t\t\t  * NUMA nodes according to their distances.\n\t\t\t  * See also \\ref faq_groups.\n\t\t\t  *\n\t\t\t  * These objects are ignored when they do not bring\n\t\t\t  * any structure.\n\t\t\t  */\n\n  HWLOC_OBJ_MISC,\t/**< \\brief Miscellaneous objects.\n\t\t\t  * Objects without particular meaning, that can e.g. be\n\t\t\t  * added by the application for its own use, or by hwloc\n\t\t\t  * for miscellaneous objects such as MemoryModule (DIMMs).\n\t\t\t  */\n\n  HWLOC_OBJ_BRIDGE,\t/**< \\brief Bridge.\n\t\t\t  * Any bridge that connects the host or an I/O bus,\n\t\t\t  * to another I/O bus.\n\t\t\t  * Bridge objects have neither CPU sets nor node sets.\n\t\t\t  * They are not added to the topology unless I/O discovery\n\t\t\t  * is enabled with hwloc_topology_set_flags().\n\t\t\t  */\n  HWLOC_OBJ_PCI_DEVICE,\t/**< \\brief PCI device.\n\t\t\t  * These objects have neither CPU sets nor node sets.\n\t\t\t  * They are not added to the topology unless I/O discovery\n\t\t\t  * is enabled with hwloc_topology_set_flags().\n\t\t\t  */\n  HWLOC_OBJ_OS_DEVICE,\t/**< \\brief Operating system device.\n\t\t\t  * These objects have neither CPU sets nor node sets.\n\t\t\t  * They are not added to the topology unless I/O discovery\n\t\t\t  * is enabled with hwloc_topology_set_flags().\n\t\t\t  */\n\n  HWLOC_OBJ_TYPE_MAX    /**< \\private Sentinel value */\n\n    /* ***************************************************************\n       WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n\n       If new enum values are added here, you MUST also go update the\n       obj_type_order[] and obj_order_type[] arrays in src/topology.c.\n\n       WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n       *************************************************************** */\n} hwloc_obj_type_t;\n\n/** \\brief Cache type. */\ntypedef enum hwloc_obj_cache_type_e {\n  HWLOC_OBJ_CACHE_UNIFIED,      /**< \\brief Unified cache. */\n  HWLOC_OBJ_CACHE_DATA,         /**< \\brief Data cache. */\n  HWLOC_OBJ_CACHE_INSTRUCTION   /**< \\brief Instruction cache.\n\t\t\t\t  * Only used when the ::HWLOC_TOPOLOGY_FLAG_ICACHES topology flag is set. */\n} hwloc_obj_cache_type_t;\n\n/** \\brief Type of one side (upstream or downstream) of an I/O bridge. */\ntypedef enum hwloc_obj_bridge_type_e {\n  HWLOC_OBJ_BRIDGE_HOST,\t/**< \\brief Host-side of a bridge, only possible upstream. */\n  HWLOC_OBJ_BRIDGE_PCI\t\t/**< \\brief PCI-side of a bridge. */\n} hwloc_obj_bridge_type_t;\n\n/** \\brief Type of a OS device. */\ntypedef enum hwloc_obj_osdev_type_e {\n  HWLOC_OBJ_OSDEV_BLOCK,\t/**< \\brief Operating system block device.\n\t\t\t\t  * For instance \"sda\" on Linux. */\n  HWLOC_OBJ_OSDEV_GPU,\t\t/**< \\brief Operating system GPU device.\n\t\t\t\t  * For instance \":0.0\" for a GL display,\n\t\t\t\t  * \"card0\" for a Linux DRM device. */\n  HWLOC_OBJ_OSDEV_NETWORK,\t/**< \\brief Operating system network device.\n\t\t\t\t  * For instance the \"eth0\" interface on Linux. */\n  HWLOC_OBJ_OSDEV_OPENFABRICS,\t/**< \\brief Operating system openfabrics device.\n\t\t\t\t  * For instance the \"mlx4_0\" InfiniBand HCA,\n\t\t\t\t  * or \"hfi1_0\" Omni-Path interface on Linux. */\n  HWLOC_OBJ_OSDEV_DMA,\t\t/**< \\brief Operating system dma engine device.\n\t\t\t\t  * For instance the \"dma0chan0\" DMA channel on Linux. */\n  HWLOC_OBJ_OSDEV_COPROC\t/**< \\brief Operating system co-processor device.\n\t\t\t\t  * For instance \"mic0\" for a Xeon Phi (MIC) on Linux,\n\t\t\t\t  * \"opencl0d0\" for a OpenCL device,\n\t\t\t\t  * \"cuda0\" for a CUDA device. */\n} hwloc_obj_osdev_type_t;\n\n/** \\brief Compare the depth of two object types\n *\n * Types shouldn't be compared as they are, since newer ones may be added in\n * the future.  This function returns less than, equal to, or greater than zero\n * respectively if \\p type1 objects usually include \\p type2 objects, are the\n * same as \\p type2 objects, or are included in \\p type2 objects. If the types\n * can not be compared (because neither is usually contained in the other),\n * ::HWLOC_TYPE_UNORDERED is returned.  Object types containing CPUs can always\n * be compared (usually, a system contains machines which contain nodes which\n * contain packages which contain caches, which contain cores, which contain\n * processors).\n *\n * \\note ::HWLOC_OBJ_PU will always be the deepest.\n * \\note This does not mean that the actual topology will respect that order:\n * e.g. as of today cores may also contain caches, and packages may also contain\n * nodes. This is thus just to be seen as a fallback comparison method.\n */\nHWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const;\n\nenum hwloc_compare_types_e {\n    HWLOC_TYPE_UNORDERED = INT_MAX\t/**< \\brief Value returned by hwloc_compare_types() when types can not be compared. \\hideinitializer */\n};\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_objects Object Structure and Attributes\n * @{\n */\n\nunion hwloc_obj_attr_u;\n\n/** \\brief Object memory */\nstruct hwloc_obj_memory_s {\n  hwloc_uint64_t total_memory; /**< \\brief Total memory (in bytes) in this object and its children */\n  hwloc_uint64_t local_memory; /**< \\brief Local memory (in bytes) */\n\n  /** \\brief Size of array \\p page_types */\n  unsigned page_types_len;\n  /** \\brief Array of local memory page types, \\c NULL if no local memory and \\p page_types is 0.\n   *\n   * The array is sorted by increasing \\p size fields.\n   * It contains \\p page_types_len slots.\n   */\n  struct hwloc_obj_memory_page_type_s {\n    hwloc_uint64_t size;\t/**< \\brief Size of pages */\n    hwloc_uint64_t count;\t/**< \\brief Number of pages of this size */\n  } * page_types;\n};\n\n/** \\brief Structure of a topology object\n *\n * Applications must not modify any field except hwloc_obj.userdata.\n */\nstruct hwloc_obj {\n  /* physical information */\n  hwloc_obj_type_t type;\t\t/**< \\brief Type of object */\n\n  unsigned os_index;\t\t\t/**< \\brief OS-provided physical index number.\n\t\t\t\t\t * It is not guaranteed unique across the entire machine,\n\t\t\t\t\t * except for PUs and NUMA nodes.\n\t\t\t\t\t */\n  char *name;\t\t\t\t/**< \\brief Object-specific name if any.\n\t\t\t\t\t * Mostly used for identifying OS devices and Misc objects where\n\t\t\t\t\t * a name string is more useful than numerical indexes.\n\t\t\t\t\t */\n\n  struct hwloc_obj_memory_s memory;\t/**< \\brief Memory attributes */\n\n  union hwloc_obj_attr_u *attr;\t\t/**< \\brief Object type-specific Attributes,\n\t\t\t\t\t * may be \\c NULL if no attribute value was found */\n\n  /* global position */\n  unsigned depth;\t\t\t/**< \\brief Vertical index in the hierarchy.\n\t\t\t\t\t *\n\t\t\t\t\t * For normal objects, this is the depth of the horizontal level\n\t\t\t\t\t * that contains this object and its cousins of the same type.\n\t\t\t\t\t * If the topology is symmetric, this is equal to the parent depth\n\t\t\t\t\t * plus one, and also equal to the number of parent/child links\n\t\t\t\t\t * from the root object to here.\n\t\t\t\t\t *\n\t\t\t\t\t * For special objects (I/O and Misc) that are not\n\t\t\t\t\t * in the main tree, this is a special negative value that\n\t\t\t\t\t * corresponds to their dedicated level,\n\t\t\t\t\t * see hwloc_get_type_depth() and ::hwloc_get_type_depth_e.\n\t\t\t\t\t * Those special values can be passed to hwloc functions such\n\t\t\t\t\t * hwloc_get_nbobjs_by_depth() as usual.\n\t\t\t\t\t */\n  unsigned logical_index;\t\t/**< \\brief Horizontal index in the whole list of similar objects,\n\t\t\t\t\t * hence guaranteed unique across the entire machine.\n\t\t\t\t\t * Could be a \"cousin_rank\" since it's the rank within the \"cousin\" list below\n\t\t\t\t\t */\n  signed os_level;\t\t\t/**< \\brief OS-provided physical level, -1 if unknown or meaningless */\n\n  /* cousins are all objects of the same type (and depth) across the entire topology */\n  struct hwloc_obj *next_cousin;\t/**< \\brief Next object of same type and depth */\n  struct hwloc_obj *prev_cousin;\t/**< \\brief Previous object of same type and depth */\n\n  /* children of the same parent are siblings, even if they may have different type and depth */\n  struct hwloc_obj *parent;\t\t/**< \\brief Parent, \\c NULL if root (system object) */\n  unsigned sibling_rank;\t\t/**< \\brief Index in parent's \\c children[] array */\n  struct hwloc_obj *next_sibling;\t/**< \\brief Next object below the same parent */\n  struct hwloc_obj *prev_sibling;\t/**< \\brief Previous object below the same parent */\n\n  /* children array below this object */\n  unsigned arity;\t\t\t/**< \\brief Number of children */\n  struct hwloc_obj **children;\t\t/**< \\brief Children, \\c children[0 .. arity -1] */\n  struct hwloc_obj *first_child;\t/**< \\brief First child */\n  struct hwloc_obj *last_child;\t\t/**< \\brief Last child */\n\n  /* misc */\n  void *userdata;\t\t\t/**< \\brief Application-given private data pointer,\n\t\t\t\t\t * initialized to \\c NULL, use it as you wish.\n\t\t\t\t\t * See hwloc_topology_set_userdata_export_callback()\n\t\t\t\t\t * if you wish to export this field to XML. */\n\n  /* cpusets and nodesets */\n  hwloc_cpuset_t cpuset;\t\t/**< \\brief CPUs covered by this object\n                                          *\n                                          * This is the set of CPUs for which there are PU objects in the topology\n                                          * under this object, i.e. which are known to be physically contained in this\n                                          * object and known how (the children path between this object and the PU\n                                          * objects).\n                                          *\n                                          * If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set, some of\n                                          * these CPUs may be offline, or not allowed for binding, see online_cpuset\n                                          * and allowed_cpuset.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n  hwloc_cpuset_t complete_cpuset;       /**< \\brief The complete CPU set of logical processors of this object,\n                                          *\n                                          * This includes not only the same as the cpuset field, but also some CPUs for\n                                          * which topology information is unknown or incomplete, and the CPUs that are\n                                          * ignored when the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM flag is not set.\n                                          * Thus no corresponding PU object may be found in the topology, because the\n                                          * precise position is undefined. It is however known that it would be somewhere\n                                          * under this object.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n  hwloc_cpuset_t online_cpuset;         /**< \\brief The CPU set of online logical processors\n                                          *\n                                          * This includes the CPUs contained in this object that are online, i.e. draw\n                                          * power and can execute threads.  It may however not be allowed to bind to\n                                          * them due to administration rules, see allowed_cpuset.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n  hwloc_cpuset_t allowed_cpuset;        /**< \\brief The CPU set of allowed logical processors\n                                          *\n                                          * This includes the CPUs contained in this object which are allowed for\n                                          * binding, i.e. passing them to the hwloc binding functions should not return\n                                          * permission errors.  This is usually restricted by administration rules.\n                                          * Some of them may however be offline so binding to them may still not be\n                                          * possible, see online_cpuset.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n\n  hwloc_nodeset_t nodeset;              /**< \\brief NUMA nodes covered by this object or containing this object\n                                          *\n                                          * This is the set of NUMA nodes for which there are NUMA node objects in the\n                                          * topology under or above this object, i.e. which are known to be physically\n                                          * contained in this object or containing it and known how (the children path\n                                          * between this object and the NUMA node objects).\n                                          *\n                                          * In the end, these nodes are those that are close to the current object.\n                                          *\n                                          * If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set, some of\n                                          * these nodes may not be allowed for allocation, see allowed_nodeset.\n                                          *\n                                          * If there are no NUMA nodes in the machine, all the memory is close to this\n                                          * object, so \\p nodeset is full.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n  hwloc_nodeset_t complete_nodeset;     /**< \\brief The complete NUMA node set of this object,\n                                          *\n                                          * This includes not only the same as the nodeset field, but also some NUMA\n                                          * nodes for which topology information is unknown or incomplete, and the nodes\n                                          * that are ignored when the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM flag is not set.\n                                          * Thus no corresponding NUMA node object may be found in the topology, because the\n                                          * precise position is undefined. It is however known that it would be\n                                          * somewhere under this object.\n                                          *\n                                          * If there are no NUMA nodes in the machine, all the memory is close to this\n                                          * object, so \\p complete_nodeset is full.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n  hwloc_nodeset_t allowed_nodeset;      /**< \\brief The set of allowed NUMA memory nodes\n                                          *\n                                          * This includes the NUMA memory nodes contained in this object which are\n                                          * allowed for memory allocation, i.e. passing them to NUMA node-directed\n                                          * memory allocation should not return permission errors. This is usually\n                                          * restricted by administration rules.\n                                          *\n                                          * If there are no NUMA nodes in the machine, all the memory is close to this\n                                          * object, so \\p allowed_nodeset is full.\n                                          *\n                                          * \\note Its value must not be changed, hwloc_bitmap_dup() must be used instead.\n                                          */\n\n  struct hwloc_distances_s **distances;\t/**< \\brief Distances between all objects at same depth below this object */\n  unsigned distances_count;\n\n  struct hwloc_obj_info_s *infos;\t/**< \\brief Array of stringified info type=name. */\n  unsigned infos_count;\t\t\t/**< \\brief Size of infos array. */\n\n  int symmetric_subtree;\t\t/**< \\brief Set if the subtree of objects below this object is symmetric,\n\t\t\t\t\t  * which means all children and their children have identical subtrees.\n\t\t\t\t\t  * If set in the topology root object, lstopo may export the topology\n\t\t\t\t\t  * as a synthetic string.\n\t\t\t\t\t  */\n};\n/**\n * \\brief Convenience typedef; a pointer to a struct hwloc_obj.\n */\ntypedef struct hwloc_obj * hwloc_obj_t;\n\n/** \\brief Object type-specific Attributes */\nunion hwloc_obj_attr_u {\n  /** \\brief Cache-specific Object Attributes */\n  struct hwloc_cache_attr_s {\n    hwloc_uint64_t size;\t\t  /**< \\brief Size of cache in bytes */\n    unsigned depth;\t\t\t  /**< \\brief Depth of cache (e.g., L1, L2, ...etc.) */\n    unsigned linesize;\t\t\t  /**< \\brief Cache-line size in bytes. 0 if unknown */\n    int associativity;\t\t\t  /**< \\brief Ways of associativity,\n    \t\t\t\t\t    *  -1 if fully associative, 0 if unknown */\n    hwloc_obj_cache_type_t type;          /**< \\brief Cache type */\n  } cache;\n  /** \\brief Group-specific Object Attributes */\n  struct hwloc_group_attr_s {\n    unsigned depth;\t\t\t  /**< \\brief Depth of group object */\n  } group;\n  /** \\brief PCI Device specific Object Attributes */\n  struct hwloc_pcidev_attr_s {\n    unsigned short domain;\n    unsigned char bus, dev, func;\n    unsigned short class_id;\n    unsigned short vendor_id, device_id, subvendor_id, subdevice_id;\n    unsigned char revision;\n    float linkspeed; /* in GB/s */\n  } pcidev;\n  /** \\brief Bridge specific Object Attribues */\n  struct hwloc_bridge_attr_s {\n    union {\n      struct hwloc_pcidev_attr_s pci;\n    } upstream;\n    hwloc_obj_bridge_type_t upstream_type;\n    union {\n      struct {\n\tunsigned short domain;\n\tunsigned char secondary_bus, subordinate_bus;\n      } pci;\n    } downstream;\n    hwloc_obj_bridge_type_t downstream_type;\n    unsigned depth;\n  } bridge;\n  /** \\brief OS Device specific Object Attributes */\n  struct hwloc_osdev_attr_s {\n    hwloc_obj_osdev_type_t type;\n  } osdev;\n};\n\n/** \\brief Distances between objects\n *\n * One object may contain a distance structure describing distances\n * between all its descendants at a given relative depth. If the\n * containing object is the root object of the topology, then the\n * distances are available for all objects in the machine.\n *\n * If the \\p latency pointer is not \\c NULL, the pointed array contains\n * memory latencies (non-zero values), see below.\n *\n * In the future, some other types of distances may be considered.\n * In these cases, \\p latency may be \\c NULL.\n */\nstruct hwloc_distances_s {\n  unsigned relative_depth;\t/**< \\brief Relative depth of the considered objects\n\t\t\t\t * below the object containing this distance information. */\n  unsigned nbobjs;\t\t/**< \\brief Number of objects considered in the matrix.\n\t\t\t\t * It is the number of descendant objects at \\p relative_depth\n\t\t\t\t * below the containing object.\n\t\t\t\t * It corresponds to the result of hwloc_get_nbobjs_inside_cpuset_by_depth(). */\n\n  float *latency;\t\t/**< \\brief Matrix of latencies between objects, stored as a one-dimension array.\n\t\t\t\t * May be \\c NULL if the distances considered here are not latencies.\n\t\t\t\t *\n\t\t\t\t * Unless defined by the user, this currently contains latencies\n\t\t\t\t * between NUMA nodes (as reported in the System Locality Distance Information Table\n\t\t\t\t * (SLIT) in the ACPI specification), which may or may not be accurate.\n\t\t\t\t * It corresponds to the latency for accessing the memory of one node\n\t\t\t\t * from a core in another node.\n\t\t\t\t *\n\t\t\t\t * Values are normalized to get 1.0 as the minimal value in the matrix.\n\t\t\t\t * Latency from i-th to j-th object is stored in slot i*nbobjs+j.\n\t\t\t\t */\n  float latency_max;\t\t/**< \\brief The maximal value in the latency matrix. */\n  float latency_base;\t\t/**< \\brief The multiplier that should be applied to latency matrix\n\t\t\t\t * to retrieve the original OS-provided latencies.\n\t\t\t\t * Usually 10 on Linux since ACPI SLIT uses 10 for local latency.\n\t\t\t\t */\n};\n\n/** \\brief Object info\n *\n * \\sa hwlocality_info_attr\n */\nstruct hwloc_obj_info_s {\n  char *name;\t/**< \\brief Info name */\n  char *value;\t/**< \\brief Info value */\n};\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_creation Topology Creation and Destruction\n * @{\n */\n\nstruct hwloc_topology;\n/** \\brief Topology context\n *\n * To be initialized with hwloc_topology_init() and built with hwloc_topology_load().\n */\ntypedef struct hwloc_topology * hwloc_topology_t;\n\n/** \\brief Allocate a topology context.\n *\n * \\param[out] topologyp is assigned a pointer to the new allocated context.\n *\n * \\return 0 on success, -1 on error.\n */\nHWLOC_DECLSPEC int hwloc_topology_init (hwloc_topology_t *topologyp);\n\n/** \\brief Build the actual topology\n *\n * Build the actual topology once initialized with hwloc_topology_init() and\n * tuned with \\ref hwlocality_configuration routines.\n * No other routine may be called earlier using this topology context.\n *\n * \\param topology is the topology to be loaded with objects.\n *\n * \\return 0 on success, -1 on error.\n *\n * \\note On failure, the topology is reinitialized. It should be either\n * destroyed with hwloc_topology_destroy() or configured and loaded again.\n *\n * \\note This function may be called only once per topology.\n *\n * \\note The binding of the current thread or process may temporarily change\n * during this call but it will be restored before it returns.\n *\n * \\sa hwlocality_configuration\n */\nHWLOC_DECLSPEC int hwloc_topology_load(hwloc_topology_t topology);\n\n/** \\brief Terminate and free a topology context\n *\n * \\param topology is the topology to be freed\n */\nHWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology);\n\n/** \\brief Duplicate a topology.\n *\n * The entire topology structure as well as its objects\n * are duplicated into a new one.\n *\n * This is useful for keeping a backup while modifying a topology.\n *\n * \\note Object userdata is not duplicated since hwloc does not know what it point to.\n * The objects of both old and new topologies will point to the same userdata.\n */\nHWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);\n\n/** \\brief Run internal checks on a topology structure\n *\n * The program aborts if an inconsistency is detected in the given topology.\n *\n * \\param topology is the topology to be checked\n *\n * \\note This routine is only useful to developers.\n *\n * \\note The input topology should have been previously loaded with\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_configuration Topology Detection Configuration and Query\n *\n * Several functions can optionally be called between hwloc_topology_init() and\n * hwloc_topology_load() to configure how the detection should be performed,\n * e.g. to ignore some objects types, define a synthetic topology, etc.\n *\n * If none of them is called, the default is to detect all the objects of the\n * machine that the caller is allowed to access.\n *\n * This default behavior may also be modified through environment variables\n * if the application did not modify it already.\n * Setting HWLOC_XMLFILE in the environment enforces the discovery from a XML\n * file as if hwloc_topology_set_xml() had been called.\n * HWLOC_FSROOT switches to reading the topology from the specified Linux\n * filesystem root as if hwloc_topology_set_fsroot() had been called.\n * Finally, HWLOC_THISSYSTEM enforces the return value of\n * hwloc_topology_is_thissystem().\n *\n * @{\n */\n\n/** \\brief Ignore an object type.\n *\n * Ignore all objects from the given type.\n * The bottom-level type ::HWLOC_OBJ_PU may not be ignored.\n * The top-level object of the hierarchy will never be ignored, even if this function\n * succeeds.\n * Group objects are always ignored if they do not bring any structure\n * since they are designed to add structure to the topology.\n * I/O objects may not be ignored, topology flags should be used to configure\n * their discovery instead.\n */\nHWLOC_DECLSPEC int hwloc_topology_ignore_type(hwloc_topology_t topology, hwloc_obj_type_t type);\n\n/** \\brief Ignore an object type if it does not bring any structure.\n *\n * Ignore all objects from the given type as long as they do not bring any structure:\n * Each ignored object should have a single children or be the only child of its parent.\n * The bottom-level type ::HWLOC_OBJ_PU may not be ignored.\n * I/O objects may not be ignored, topology flags should be used to configure\n * their discovery instead.\n */\nHWLOC_DECLSPEC int hwloc_topology_ignore_type_keep_structure(hwloc_topology_t topology, hwloc_obj_type_t type);\n\n/** \\brief Ignore all objects that do not bring any structure.\n *\n * Ignore all objects that do not bring any structure:\n * This is equivalent to calling hwloc_topology_ignore_type_keep_structure()\n * for all object types.\n */\nHWLOC_DECLSPEC int hwloc_topology_ignore_all_keep_structure(hwloc_topology_t topology);\n\n/** \\brief Flags to be set onto a topology context before load.\n *\n * Flags should be given to hwloc_topology_set_flags().\n * They may also be returned by hwloc_topology_get_flags().\n */\nenum hwloc_topology_flags_e {\n /** \\brief Detect the whole system, ignore reservations and offline settings.\n   *\n   * Gather all resources, even if some were disabled by the administrator.\n   * For instance, ignore Linux Cgroup/Cpusets and gather all processors and memory nodes,\n   * and ignore the fact that some resources may be offline.\n   *\n   * When this flag is not set, PUs that are disallowed are not added to the topology.\n   * Parent objects (package, core, cache, etc.) are added only if some of their children are allowed.\n   * NUMA nodes are always added but their available memory is set to 0 when disallowed.\n   *\n   * If the current topology is exported to XML and reimported later, this flag\n   * should be set again in the reimported topology so that disallowed resources\n   * are reimported as well.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM = (1UL<<0),\n\n /** \\brief Assume that the selected backend provides the topology for the\n   * system on which we are running.\n   *\n   * This forces hwloc_topology_is_thissystem() to return 1, i.e. makes hwloc assume that\n   * the selected backend provides the topology for the system on which we are running,\n   * even if it is not the OS-specific backend but the XML backend for instance.\n   * This means making the binding functions actually call the OS-specific\n   * system calls and really do binding, while the XML backend would otherwise\n   * provide empty hooks just returning success.\n   *\n   * Setting the environment variable HWLOC_THISSYSTEM may also result in the\n   * same behavior.\n   *\n   * This can be used for efficiency reasons to first detect the topology once,\n   * save it to an XML file, and quickly reload it later through the XML\n   * backend, but still having binding functions actually do bind.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM = (1UL<<1),\n\n  /** \\brief Detect PCI devices.\n   *\n   * By default, I/O devices are ignored. This flag enables I/O device\n   * detection using the pci backend. Only the common PCI devices (GPUs,\n   * NICs, block devices, ...) and host bridges (objects that connect the host\n   * objects to an I/O subsystem) will be added to the topology.\n   * Additionally it also enables MemoryModule misc objects.\n   * Uncommon devices and other bridges (such as PCI-to-PCI bridges) will be\n   * ignored.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_IO_DEVICES = (1UL<<2),\n\n  /** \\brief Detect PCI bridges.\n   *\n   * This flag should be combined with ::HWLOC_TOPOLOGY_FLAG_IO_DEVICES to enable\n   * the detection of both common devices and of all useful bridges (bridges that\n   * have at least one device behind them).\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_IO_BRIDGES = (1UL<<3),\n\n  /** \\brief Detect the whole PCI hierarchy.\n   *\n   * This flag enables detection of all I/O devices (even the uncommon ones\n   * such as DMA channels) and bridges (even those that have no device behind\n   * them) using the pci backend.\n   * This implies ::HWLOC_TOPOLOGY_FLAG_IO_DEVICES.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_WHOLE_IO = (1UL<<4),\n\n  /** \\brief Detect instruction caches.\n   *\n   * This flag enables detection of Instruction caches,\n   * instead of only Data and Unified caches.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_ICACHES = (1UL<<5),\n\n  /** \\brief Get the set of allowed resources from the local operating system even if the topology was loaded from XML or synthetic description.\n   *\n   * If the topology was loaded from XML or from a synthetic string,\n   * restrict it by applying the current process restrictions such as\n   * Linux Cgroup/Cpuset.\n   *\n   * This is useful when the topology is not loaded directly from\n   * the local machine (e.g. for performance reason) and it comes\n   * with all resources, while the running process is restricted\n   * to only parts of the machine.\n   *\n   * This flag is ignored unless ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM is\n   * also set since the loaded topology must match the underlying machine\n   * where restrictions will be gathered from.\n   *\n   * Setting the environment variable HWLOC_THISSYSTEM_ALLOWED_RESOURCES\n   * would result in the same behavior.\n   * \\hideinitializer\n   */\n  HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES = (1UL<<6)\n};\n\n/** \\brief Set OR'ed flags to non-yet-loaded topology.\n *\n * Set a OR'ed set of ::hwloc_topology_flags_e onto a topology that was not yet loaded.\n *\n * If this function is called multiple times, the last invokation will erase\n * and replace the set of flags that was previously set.\n *\n * The flags set in a topology may be retrieved with hwloc_topology_get_flags()\n */\nHWLOC_DECLSPEC int hwloc_topology_set_flags (hwloc_topology_t topology, unsigned long flags);\n\n/** \\brief Get OR'ed flags of a topology.\n *\n * Get the OR'ed set of ::hwloc_topology_flags_e of a topology.\n *\n * \\return the flags previously set with hwloc_topology_set_flags().\n */\nHWLOC_DECLSPEC unsigned long hwloc_topology_get_flags (hwloc_topology_t topology);\n\n/** \\brief Change which process the topology is viewed from\n *\n * On some systems, processes may have different views of the machine, for\n * instance the set of allowed CPUs. By default, hwloc exposes the view from\n * the current process. Calling hwloc_topology_set_pid() permits to make it\n * expose the topology of the machine from the point of view of another\n * process.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note -1 is returned and errno is set to ENOSYS on platforms that do not\n * support this feature.\n */\nHWLOC_DECLSPEC int hwloc_topology_set_pid(hwloc_topology_t __hwloc_restrict topology, hwloc_pid_t pid);\n\n/** \\brief Change the file-system root path when building the topology from sysfs/procfs.\n *\n * On Linux system, use sysfs and procfs files as if they were mounted on the given\n * \\p fsroot_path instead of the main file-system root. Setting the environment\n * variable HWLOC_FSROOT may also result in this behavior.\n * Not using the main file-system root causes hwloc_topology_is_thissystem()\n * to return 0.\n *\n * Note that this function does not actually load topology\n * information; it just tells hwloc where to load it from.  You'll\n * still need to invoke hwloc_topology_load() to actually load the\n * topology information.\n *\n * \\return -1 with errno set to ENOSYS on non-Linux and on Linux systems that\n * do not support it.\n * \\return -1 with the appropriate errno if \\p fsroot_path cannot be used.\n *\n * \\note For convenience, this backend provides empty binding hooks which just\n * return success.  To have hwloc still actually call OS-specific hooks, the\n * ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM has to be set to assert that the loaded\n * file is really the underlying system.\n *\n * \\note On success, the Linux component replaces the previously enabled\n * component (if any), but the topology is not actually modified until\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC int hwloc_topology_set_fsroot(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict fsroot_path);\n\n/** \\brief Enable synthetic topology.\n *\n * Gather topology information from the given \\p description,\n * a space-separated string of numbers describing\n * the arity of each level.\n * Each number may be prefixed with a type and a colon to enforce the type\n * of a level.  If only some level types are enforced, hwloc will try to\n * choose the other types according to usual topologies, but it may fail\n * and you may have to specify more level types manually.\n * See also the \\ref synthetic.\n *\n * If \\p description was properly parsed and describes a valid topology\n * configuration, this function returns 0.\n * Otherwise -1 is returned and errno is set to EINVAL.\n *\n * Note that this function does not actually load topology\n * information; it just tells hwloc where to load it from.  You'll\n * still need to invoke hwloc_topology_load() to actually load the\n * topology information.\n *\n * \\note For convenience, this backend provides empty binding hooks which just\n * return success.\n *\n * \\note On success, the synthetic component replaces the previously enabled\n * component (if any), but the topology is not actually modified until\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC int hwloc_topology_set_synthetic(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict description);\n\n/** \\brief Enable XML-file based topology.\n *\n * Gather topology information from the XML file given at \\p xmlpath.\n * Setting the environment variable HWLOC_XMLFILE may also result in this behavior.\n * This file may have been generated earlier with hwloc_topology_export_xml()\n * or lstopo file.xml.\n *\n * Note that this function does not actually load topology\n * information; it just tells hwloc where to load it from.  You'll\n * still need to invoke hwloc_topology_load() to actually load the\n * topology information.\n *\n * \\return -1 with errno set to EINVAL on failure to read the XML file.\n *\n * \\note See also hwloc_topology_set_userdata_import_callback()\n * for importing application-specific object userdata.\n *\n * \\note For convenience, this backend provides empty binding hooks which just\n * return success.  To have hwloc still actually call OS-specific hooks, the\n * ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM has to be set to assert that the loaded\n * file is really the underlying system.\n *\n * \\note On success, the XML component replaces the previously enabled\n * component (if any), but the topology is not actually modified until\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC int hwloc_topology_set_xml(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict xmlpath);\n\n/** \\brief Enable XML based topology using a memory buffer (instead of\n * a file, as with hwloc_topology_set_xml()).\n *\n * Gather topology information from the XML memory buffer given at \\p\n * buffer and of length \\p size.  This buffer may have been filled\n * earlier with hwloc_topology_export_xmlbuffer().\n *\n * Note that this function does not actually load topology\n * information; it just tells hwloc where to load it from.  You'll\n * still need to invoke hwloc_topology_load() to actually load the\n * topology information.\n *\n * \\return -1 with errno set to EINVAL on failure to read the XML buffer.\n *\n * \\note See also hwloc_topology_set_userdata_import_callback()\n * for importing application-specific object userdata.\n *\n * \\note For convenience, this backend provides empty binding hooks which just\n * return success.  To have hwloc still actually call OS-specific hooks, the\n * ::HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM has to be set to assert that the loaded\n * file is really the underlying system.\n *\n * \\note On success, the XML component replaces the previously enabled\n * component (if any), but the topology is not actually modified until\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC int hwloc_topology_set_xmlbuffer(hwloc_topology_t __hwloc_restrict topology, const char * __hwloc_restrict buffer, int size);\n\n/** \\brief Prepare the topology for custom assembly.\n *\n * The topology then contains a single root object.\n * It must then be built by inserting other topologies with\n * hwloc_custom_insert_topology() or single objects with\n * hwloc_custom_insert_group_object_by_parent().\n * hwloc_topology_load() must be called to finalize the new\n * topology as usual.\n *\n * \\note If nothing is inserted in the topology,\n * hwloc_topology_load() will fail with errno set to EINVAL.\n *\n * \\note The cpuset and nodeset of the root object are NULL because\n * these sets are meaningless when assembling multiple topologies.\n *\n * \\note On success, the custom component replaces the previously enabled\n * component (if any), but the topology is not actually modified until\n * hwloc_topology_load().\n */\nHWLOC_DECLSPEC int hwloc_topology_set_custom(hwloc_topology_t topology);\n\n/** \\brief Provide a distance matrix.\n *\n * Provide the matrix of distances between a set of objects of the given type.\n * \\p nbobjs must be at least 2.\n * The set may or may not contain all the existing objects of this type.\n * The objects are specified by their OS/physical index in the \\p os_index\n * array. The \\p distances matrix follows the same order.\n * The distance from object i to object j in the i*nbobjs+j.\n *\n * A single latency matrix may be defined for each type.\n * If another distance matrix already exists for the given type,\n * either because the user specified it or because the OS offers it,\n * it will be replaced by the given one.\n * If \\p nbobjs is \\c 0, \\p os_index is \\c NULL and \\p distances is \\c NULL,\n * the existing distance matrix for the given type is removed.\n *\n * \\note Distance matrices are ignored in multi-node topologies.\n */\nHWLOC_DECLSPEC int hwloc_topology_set_distance_matrix(hwloc_topology_t __hwloc_restrict topology,\n\t\t\t\t\t\t      hwloc_obj_type_t type, unsigned nbobjs,\n\t\t\t\t\t\t      unsigned *os_index, float *distances);\n\n/** \\brief Does the topology context come from this system?\n *\n * \\return 1 if this topology context was built using the system\n * running this program.\n * \\return 0 instead (for instance if using another file-system root,\n * a XML topology file, or a synthetic topology).\n */\nHWLOC_DECLSPEC int hwloc_topology_is_thissystem(hwloc_topology_t  __hwloc_restrict topology) __hwloc_attribute_pure;\n\n/** \\brief Flags describing actual discovery support for this topology. */\nstruct hwloc_topology_discovery_support {\n  /** \\brief Detecting the number of PU objects is supported. */\n  unsigned char pu;\n};\n\n/** \\brief Flags describing actual PU binding support for this topology.\n *\n * A flag may be set even if the feature isn't supported in all cases\n * (e.g. binding to random sets of non-contiguous objects).\n */\nstruct hwloc_topology_cpubind_support {\n  /** Binding the whole current process is supported.  */\n  unsigned char set_thisproc_cpubind;\n  /** Getting the binding of the whole current process is supported.  */\n  unsigned char get_thisproc_cpubind;\n  /** Binding a whole given process is supported.  */\n  unsigned char set_proc_cpubind;\n  /** Getting the binding of a whole given process is supported.  */\n  unsigned char get_proc_cpubind;\n  /** Binding the current thread only is supported.  */\n  unsigned char set_thisthread_cpubind;\n  /** Getting the binding of the current thread only is supported.  */\n  unsigned char get_thisthread_cpubind;\n  /** Binding a given thread only is supported.  */\n  unsigned char set_thread_cpubind;\n  /** Getting the binding of a given thread only is supported.  */\n  unsigned char get_thread_cpubind;\n  /** Getting the last processors where the whole current process ran is supported */\n  unsigned char get_thisproc_last_cpu_location;\n  /** Getting the last processors where a whole process ran is supported */\n  unsigned char get_proc_last_cpu_location;\n  /** Getting the last processors where the current thread ran is supported */\n  unsigned char get_thisthread_last_cpu_location;\n};\n\n/** \\brief Flags describing actual memory binding support for this topology.\n *\n * A flag may be set even if the feature isn't supported in all cases\n * (e.g. binding to random sets of non-contiguous objects).\n */\nstruct hwloc_topology_membind_support {\n  /** Binding the whole current process is supported.  */\n  unsigned char set_thisproc_membind;\n  /** Getting the binding of the whole current process is supported.  */\n  unsigned char get_thisproc_membind;\n  /** Binding a whole given process is supported.  */\n  unsigned char set_proc_membind;\n  /** Getting the binding of a whole given process is supported.  */\n  unsigned char get_proc_membind;\n  /** Binding the current thread only is supported.  */\n  unsigned char set_thisthread_membind;\n  /** Getting the binding of the current thread only is supported.  */\n  unsigned char get_thisthread_membind;\n  /** Binding a given memory area is supported. */\n  unsigned char set_area_membind;\n  /** Getting the binding of a given memory area is supported.  */\n  unsigned char get_area_membind;\n  /** Allocating a bound memory area is supported. */\n  unsigned char alloc_membind;\n  /** First-touch policy is supported. */\n  unsigned char firsttouch_membind;\n  /** Bind policy is supported. */\n  unsigned char bind_membind;\n  /** Interleave policy is supported. */\n  unsigned char interleave_membind;\n  /** Replication policy is supported. */\n  unsigned char replicate_membind;\n  /** Next-touch migration policy is supported. */\n  unsigned char nexttouch_membind;\n  /** Migration flags is supported. */\n  unsigned char migrate_membind;\n  /** Getting the last NUMA nodes where a memory area was allocated is supported */\n  unsigned char get_area_memlocation;\n};\n\n/** \\brief Set of flags describing actual support for this topology.\n *\n * This is retrieved with hwloc_topology_get_support() and will be valid until\n * the topology object is destroyed.  Note: the values are correct only after\n * discovery.\n */\nstruct hwloc_topology_support {\n  struct hwloc_topology_discovery_support *discovery;\n  struct hwloc_topology_cpubind_support *cpubind;\n  struct hwloc_topology_membind_support *membind;\n};\n\n/** \\brief Retrieve the topology support.\n *\n * Each flag indicates whether a feature is supported.\n * If set to 0, the feature is not supported.\n * If set to 1, the feature is supported, but the corresponding\n * call may still fail in some corner cases.\n *\n * These features are also listed by hwloc-info \\--support\n */\nHWLOC_DECLSPEC const struct hwloc_topology_support *hwloc_topology_get_support(hwloc_topology_t __hwloc_restrict topology);\n\n/** \\brief Set the topology-specific userdata pointer.\n *\n * Each topology may store one application-given private data pointer.\n * It is initialized to \\c NULL.\n * hwloc will never modify it.\n *\n * Use it as you wish, after hwloc_topology_init() and until hwloc_topolog_destroy().\n *\n * This pointer is not exported to XML.\n */\nHWLOC_DECLSPEC void hwloc_topology_set_userdata(hwloc_topology_t topology, const void *userdata);\n\n/** \\brief Retrieve the topology-specific userdata pointer.\n *\n * Retrieve the application-given private data pointer that was\n * previously set with hwloc_topology_set_userdata().\n */\nHWLOC_DECLSPEC void * hwloc_topology_get_userdata(hwloc_topology_t topology);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_levels Object levels, depths and types\n * @{\n *\n * Be sure to see the figure in \\ref termsanddefs that shows a\n * complete topology tree, including depths, child/sibling/cousin\n * relationships, and an example of an asymmetric topology where one\n * package has fewer caches than its peers.\n */\n\n/** \\brief Get the depth of the hierarchical tree of objects.\n *\n * This is the depth of ::HWLOC_OBJ_PU objects plus one.\n *\n * \\note I/O and Misc objects are ignored when computing the depth\n * of the tree (they are placed on special levels, or none).\n */\nHWLOC_DECLSPEC unsigned hwloc_topology_get_depth(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;\n\n/** \\brief Returns the depth of objects of type \\p type.\n *\n * If no object of this type is present on the underlying architecture, or if\n * the OS doesn't provide this kind of information, the function returns\n * ::HWLOC_TYPE_DEPTH_UNKNOWN.\n *\n * If type is absent but a similar type is acceptable, see also\n * hwloc_get_type_or_below_depth() and hwloc_get_type_or_above_depth().\n *\n * If some objects of the given type exist in different levels,\n * for instance L1 and L2 caches, or L1i and L1d caches,\n * the function returns ::HWLOC_TYPE_DEPTH_MULTIPLE.\n * See hwloc_get_cache_type_depth() in hwloc/helper.h to better handle this\n * case.\n *\n * If an I/O object type is given, the function returns a virtual value\n * because I/O objects are stored in special levels that are not CPU-related.\n * This virtual depth may be passed to other hwloc functions such as\n * hwloc_get_obj_by_depth() but it should not be considered as an actual\n * depth by the application. In particular, it should not be compared with\n * any other object depth or with the entire topology depth.\n *\n * If ::HWLOC_OBJ_MISC is given, the function returns ::HWLOC_TYPE_DEPTH_UNKNOWN.\n */\nHWLOC_DECLSPEC int hwloc_get_type_depth (hwloc_topology_t topology, hwloc_obj_type_t type);\n\nenum hwloc_get_type_depth_e {\n    HWLOC_TYPE_DEPTH_UNKNOWN = -1,    /**< \\brief No object of given type exists in the topology. \\hideinitializer */\n    HWLOC_TYPE_DEPTH_MULTIPLE = -2,   /**< \\brief Objects of given type exist at different depth in the topology. \\hideinitializer */\n    HWLOC_TYPE_DEPTH_BRIDGE = -3,     /**< \\brief Virtual depth for bridge object level. \\hideinitializer */\n    HWLOC_TYPE_DEPTH_PCI_DEVICE = -4, /**< \\brief Virtual depth for PCI device object level. \\hideinitializer */\n    HWLOC_TYPE_DEPTH_OS_DEVICE = -5   /**< \\brief Virtual depth for software device object level. \\hideinitializer */\n};\n\n/** \\brief Returns the depth of objects of type \\p type or below\n *\n * If no object of this type is present on the underlying architecture, the\n * function returns the depth of the first \"present\" object typically found\n * inside \\p type.\n *\n * If some objects of the given type exist in different levels, for instance\n * L1 and L2 caches, the function returns ::HWLOC_TYPE_DEPTH_MULTIPLE.\n */\nstatic __hwloc_inline int\nhwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;\n\n/** \\brief Returns the depth of objects of type \\p type or above\n *\n * If no object of this type is present on the underlying architecture, the\n * function returns the depth of the first \"present\" object typically\n * containing \\p type.\n *\n * If some objects of the given type exist in different levels, for instance\n * L1 and L2 caches, the function returns ::HWLOC_TYPE_DEPTH_MULTIPLE.\n */\nstatic __hwloc_inline int\nhwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;\n\n/** \\brief Returns the type of objects at depth \\p depth.\n *\n * \\p depth should between 0 and hwloc_topology_get_depth()-1.\n *\n * \\return -1 if depth \\p depth does not exist.\n */\nHWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type (hwloc_topology_t topology, unsigned depth) __hwloc_attribute_pure;\n\n/** \\brief Returns the width of level at depth \\p depth.\n */\nHWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, unsigned depth) __hwloc_attribute_pure;\n\n/** \\brief Returns the width of level type \\p type\n *\n * If no object for that type exists, 0 is returned.\n * If there are several levels with objects of that type, -1 is returned.\n */\nstatic __hwloc_inline int\nhwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type) __hwloc_attribute_pure;\n\n/** \\brief Returns the top-object of the topology-tree.\n *\n * Its type is typically ::HWLOC_OBJ_MACHINE but it could be different\n * for complex topologies.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;\n\n/** \\brief Returns the topology object at logical index \\p idx from depth \\p depth */\nHWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, unsigned depth, unsigned idx) __hwloc_attribute_pure;\n\n/** \\brief Returns the topology object at logical index \\p idx with type \\p type\n *\n * If no object for that type exists, \\c NULL is returned.\n * If there are several levels with objects of that type, \\c NULL is returned\n * and ther caller may fallback to hwloc_get_obj_by_depth().\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;\n\n/** \\brief Returns the next object at depth \\p depth.\n *\n * If \\p prev is \\c NULL, return the first object at depth \\p depth.\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev);\n\n/** \\brief Returns the next object of type \\p type.\n *\n * If \\p prev is \\c NULL, return the first object at type \\p type.  If\n * there are multiple or no depth for given type, return \\c NULL and\n * let the caller fallback to hwloc_get_next_obj_by_depth().\n */\nstatic __hwloc_inline hwloc_obj_t\nhwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,\n\t\t\t    hwloc_obj_t prev);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_object_strings Converting between Object Types, Sets and Attributes, and Strings\n * @{\n */\n\n/** \\brief Return a constant stringified object type.\n *\n * This function is the basic way to convert a generic type into a string.\n *\n * hwloc_obj_type_snprintf() may return a more precise output for a specific\n * object, but it requires the caller to provide the output buffer.\n */\nHWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const;\n\n/** \\brief Stringify the type of a given topology object into a human-readable form.\n *\n * Contrary to hwloc_obj_type_string(), this function includes object-specific\n * attributes (such as the Group depth, the Bridge type, or OS device type)\n * in the output, and it requires the caller to provide the output buffer.\n *\n * The output is guaranteed to be the same for all objects of a same topology level.\n *\n * If \\p size is 0, \\p string may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj,\n\t\t\t\t   int verbose);\n\n/** \\brief Stringify the attributes of a given topology object into a human-readable form.\n *\n * Attribute values are separated by \\p separator.\n *\n * Only the major attributes are printed in non-verbose mode.\n *\n * If \\p size is 0, \\p string may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, const char * __hwloc_restrict separator,\n\t\t\t\t   int verbose);\n\n/** \\brief Stringify the cpuset containing a set of objects.\n *\n * If \\p size is 0, \\p string may safely be \\c NULL.\n *\n * \\return the number of character that were actually written if not truncating,\n * or that would have been written (not including the ending \\\\0).\n */\nHWLOC_DECLSPEC int hwloc_obj_cpuset_snprintf(char * __hwloc_restrict str, size_t size, size_t nobj, const hwloc_obj_t * __hwloc_restrict objs);\n\n/** \\brief Return an object type and attributes from a type string.\n *\n * Convert strings such as \"Package\" or \"Cache\" into the corresponding types.\n * Matching is case-insensitive, and only the first letters are actually\n * required to match.\n *\n * This function is guaranteed to match any string returned by hwloc_obj_type_string()\n * or hwloc_obj_type_snprintf().\n *\n * Types that have specific attributes, for instance caches and groups,\n * may be returned in \\p depthattrp and \\p typeattrp. They are ignored\n * when these pointers are \\c NULL.\n *\n * For instance \"L2i\" or \"L2iCache\" would return\n * type HWLOC_OBJ_CACHE in \\p typep, 2 in \\p depthattrp,\n * and HWLOC_OBJ_CACHE_TYPE_INSTRUCTION in \\p typeattrp\n * (this last pointer should point to a hwloc_obj_cache_type_t).\n * \"Group3\" would return type HWLOC_OBJ_GROUP type and 3 in \\p depthattrp.\n * Attributes that are not specified in the string (for instance \"Group\"\n * without a depth, or \"L2Cache\" without a cache type) are set to -1.\n *\n * \\p typeattrp is only filled if the size specified in \\p typeattrsize\n * is large enough. It is currently only used for caches, and the required\n * size is at least the size of hwloc_obj_cache_type_t.\n *\n * \\return 0 if a type was correctly identified, otherwise -1.\n *\n * \\note This is an extended version of the now deprecated hwloc_obj_type_of_string()\n */\nHWLOC_DECLSPEC int hwloc_obj_type_sscanf(const char *string,\n\t\t\t\t\t hwloc_obj_type_t *typep,\n\t\t\t\t\t int *depthattrp,\n\t\t\t\t\t void *typeattrp, size_t typeattrsize);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_info_attr Consulting and Adding Key-Value Info Attributes\n *\n * @{\n */\n\n/** \\brief Search the given key name in object infos and return the corresponding value.\n *\n * If multiple keys match the given name, only the first one is returned.\n *\n * \\return \\c NULL if no such key exists.\n */\nstatic __hwloc_inline const char *\nhwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) __hwloc_attribute_pure;\n\n/** \\brief Add the given info name and value pair to the given object.\n *\n * The info is appended to the existing info array even if another key\n * with the same name already exists.\n *\n * The input strings are copied before being added in the object infos.\n *\n * \\note This function may be used to enforce object colors in the lstopo\n * graphical output by using \"lstopoStyle\" as a name and \"Background=#rrggbb\"\n * as a value. See CUSTOM COLORS in the lstopo(1) manpage for details.\n *\n * \\note If \\p value contains some non-printable characters, they will\n * be dropped when exporting to XML, see hwloc_topology_export_xml().\n */\nHWLOC_DECLSPEC void hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const char *value);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_cpubinding CPU binding\n *\n * It is often useful to call hwloc_bitmap_singlify() first so that a single CPU\n * remains in the set. This way, the process will not even migrate between\n * different CPUs inside the given set.\n * Some operating systems also only support that kind of binding.\n *\n * Some operating systems do not provide all hwloc-supported\n * mechanisms to bind processes, threads, etc.\n * hwloc_topology_get_support() may be used to query about the actual CPU\n * binding support in the currently used operating system.\n *\n * When the requested binding operation is not available and the\n * ::HWLOC_CPUBIND_STRICT flag was passed, the function returns -1.\n * \\p errno is set to \\c ENOSYS when it is not possible to bind the requested kind of object\n * processes/threads. errno is set to \\c EXDEV when the requested cpuset\n * can not be enforced (e.g. some systems only allow one CPU, and some\n * other systems only allow one NUMA node).\n *\n * If ::HWLOC_CPUBIND_STRICT was not passed, the function may fail as well,\n * or the operating system may use a slightly different operation\n * (with side-effects, smaller binding set, etc.)\n * when the requested operation is not exactly supported.\n *\n * The most portable version that should be preferred over the others,\n * whenever possible, is the following one which just binds the current program,\n * assuming it is single-threaded:\n *\n * \\code\n * hwloc_set_cpubind(topology, set, 0),\n * \\endcode\n *\n * If the program may be multithreaded, the following one should be preferred\n * to only bind the current thread:\n *\n * \\code\n * hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD),\n * \\endcode\n *\n * \\sa Some example codes are available under doc/examples/ in the source tree.\n *\n * \\note To unbind, just call the binding function with either a full cpuset or\n * a cpuset equal to the system cpuset.\n *\n * \\note On some operating systems, CPU binding may have effects on memory binding, see\n * ::HWLOC_CPUBIND_NOMEMBIND\n *\n * \\note Running lstopo \\--top or hwloc-ps can be a very convenient tool to check\n * how binding actually happened.\n * @{\n */\n\n/** \\brief Process/Thread binding flags.\n *\n * These bit flags can be used to refine the binding policy.\n *\n * The default (0) is to bind the current process, assumed to be\n * single-threaded, in a non-strict way.  This is the most portable\n * way to bind as all operating systems usually provide it.\n *\n * \\note Not all systems support all kinds of binding.  See the\n * \"Detailed Description\" section of \\ref hwlocality_cpubinding for a\n * description of errors that can occur.\n */\ntypedef enum {\n  /** \\brief Bind all threads of the current (possibly) multithreaded process.\n   * \\hideinitializer */\n  HWLOC_CPUBIND_PROCESS = (1<<0),\n\n  /** \\brief Bind current thread of current process.\n   * \\hideinitializer */\n  HWLOC_CPUBIND_THREAD = (1<<1),\n\n  /** \\brief Request for strict binding from the OS.\n   *\n   * By default, when the designated CPUs are all busy while other\n   * CPUs are idle, operating systems may execute the thread/process\n   * on those other CPUs instead of the designated CPUs, to let them\n   * progress anyway.  Strict binding means that the thread/process\n   * will _never_ execute on other cpus than the designated CPUs, even\n   * when those are busy with other tasks and other CPUs are idle.\n   *\n   * \\note Depending on the operating system, strict binding may not\n   * be possible (e.g., the OS does not implement it) or not allowed\n   * (e.g., for an administrative reasons), and the function will fail\n   * in that case.\n   *\n   * When retrieving the binding of a process, this flag checks\n   * whether all its threads  actually have the same binding. If the\n   * flag is not given, the binding of each thread will be\n   * accumulated.\n   *\n   * \\note This flag is meaningless when retrieving the binding of a\n   * thread.\n   * \\hideinitializer\n   */\n  HWLOC_CPUBIND_STRICT = (1<<2),\n\n  /** \\brief Avoid any effect on memory binding\n   *\n   * On some operating systems, some CPU binding function would also\n   * bind the memory on the corresponding NUMA node.  It is often not\n   * a problem for the application, but if it is, setting this flag\n   * will make hwloc avoid using OS functions that would also bind\n   * memory.  This will however reduce the support of CPU bindings,\n   * i.e. potentially return -1 with errno set to ENOSYS in some\n   * cases.\n   *\n   * This flag is only meaningful when used with functions that set\n   * the CPU binding.  It is ignored when used with functions that get\n   * CPU binding information.\n   * \\hideinitializer\n   */\n  HWLOC_CPUBIND_NOMEMBIND = (1<<3)\n} hwloc_cpubind_flags_t;\n\n/** \\brief Bind current process or thread on cpus given in physical bitmap \\p set.\n *\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n */\nHWLOC_DECLSPEC int hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);\n\n/** \\brief Get current process or thread binding.\n *\n * Writes into \\p set the physical cpuset which the process or thread (according to \\e\n * flags) was last bound to.\n */\nHWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);\n\n/** \\brief Bind a process \\p pid on cpus given in physical bitmap \\p set.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note As a special case on Linux, if a tid (thread ID) is supplied\n * instead of a pid (process ID) and ::HWLOC_CPUBIND_THREAD is passed in flags,\n * the binding is applied to that specific thread.\n *\n * \\note On non-Linux systems, ::HWLOC_CPUBIND_THREAD can not be used in \\p flags.\n */\nHWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);\n\n/** \\brief Get the current physical binding of process \\p pid.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note As a special case on Linux, if a tid (thread ID) is supplied\n * instead of a pid (process ID) and ::HWLOC_CPUBIND_THREAD is passed in flags,\n * the binding for that specific thread is returned.\n *\n * \\note On non-Linux systems, ::HWLOC_CPUBIND_THREAD can not be used in \\p flags.\n */\nHWLOC_DECLSPEC int hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);\n\n#ifdef hwloc_thread_t\n/** \\brief Bind a thread \\p thread on cpus given in physical bitmap \\p set.\n *\n * \\note \\p hwloc_thread_t is \\p pthread_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note ::HWLOC_CPUBIND_PROCESS can not be used in \\p flags.\n */\nHWLOC_DECLSPEC int hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t thread, hwloc_const_cpuset_t set, int flags);\n#endif\n\n#ifdef hwloc_thread_t\n/** \\brief Get the current physical binding of thread \\p tid.\n *\n * \\note \\p hwloc_thread_t is \\p pthread_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note ::HWLOC_CPUBIND_PROCESS can not be used in \\p flags.\n */\nHWLOC_DECLSPEC int hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t thread, hwloc_cpuset_t set, int flags);\n#endif\n\n/** \\brief Get the last physical CPU where the current process or thread ran.\n *\n * The operating system may move some tasks from one processor\n * to another at any time according to their binding,\n * so this function may return something that is already\n * outdated.\n *\n * \\p flags can include either ::HWLOC_CPUBIND_PROCESS or ::HWLOC_CPUBIND_THREAD to\n * specify whether the query should be for the whole process (union of all CPUs\n * on which all threads are running), or only the current thread. If the\n * process is single-threaded, flags can be set to zero to let hwloc use\n * whichever method is available on the underlying OS.\n */\nHWLOC_DECLSPEC int hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);\n\n/** \\brief Get the last physical CPU where a process ran.\n *\n * The operating system may move some tasks from one processor\n * to another at any time according to their binding,\n * so this function may return something that is already\n * outdated.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n *\n * \\note As a special case on Linux, if a tid (thread ID) is supplied\n * instead of a pid (process ID) and ::HWLOC_CPUBIND_THREAD is passed in flags,\n * the last CPU location of that specific thread is returned.\n *\n * \\note On non-Linux systems, ::HWLOC_CPUBIND_THREAD can not be used in \\p flags.\n */\nHWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_membinding Memory binding\n *\n * Memory binding can be done three ways:\n *\n * - explicit memory allocation thanks to hwloc_alloc_membind() and friends:\n *   the binding will have effect on the memory allocated by these functions.\n * - implicit memory binding through binding policy: hwloc_set_membind() and\n *   friends only define the current policy of the process, which will be\n *   applied to the subsequent calls to malloc() and friends.\n * - migration of existing memory ranges, thanks to hwloc_set_area_membind()\n *   and friends, which move already-allocated data.\n *\n * Not all operating systems support all three ways.\n * hwloc_topology_get_support() may be used to query about the actual memory\n * binding support in the currently used operating system.\n *\n * When the requested binding operation is not available and the\n * ::HWLOC_MEMBIND_STRICT flag was passed, the function returns -1.\n * \\p errno will be set to \\c ENOSYS when the system does support\n * the specified action or policy\n * (e.g., some systems only allow binding memory on a per-thread\n * basis, whereas other systems only allow binding memory for all\n * threads in a process).\n * \\p errno will be set to EXDEV when the requested set can not be enforced\n * (e.g., some systems only allow binding memory to a single NUMA node).\n *\n * If ::HWLOC_MEMBIND_STRICT was not passed, the function may fail as well,\n * or the operating system may use a slightly different operation\n * (with side-effects, smaller binding set, etc.)\n * when the requested operation is not exactly supported.\n *\n * The most portable form that should be preferred over the others\n * whenever possible is as follows.\n * It allocates some memory hopefully bound to the specified set.\n * To do so, hwloc will possibly have to change the current memory\n * binding policy in order to actually get the memory bound, if the OS\n * does not provide any other way to simply allocate bound memory\n * without changing the policy for all allocations. That is the\n * difference with hwloc_alloc_membind(), which will never change the\n * current memory binding policy.\n *\n * \\code\n * hwloc_alloc_membind_policy(topology, size, set,\n *                            HWLOC_MEMBIND_BIND, 0);\n * \\endcode\n *\n * Each hwloc memory binding function is available in two forms: one\n * that takes a bitmap argument (a CPU set by default, or a NUMA memory\n * node set if the flag ::HWLOC_MEMBIND_BYNODESET is specified),\n * and another one (whose name ends with _nodeset) that always takes\n * a NUMA memory node set.\n * See \\ref hwlocality_object_sets and \\ref hwlocality_bitmap for a\n * discussion of CPU sets and NUMA memory node sets.\n * It is also possible to convert between CPU set and node set using\n * hwloc_cpuset_to_nodeset() or hwloc_cpuset_from_nodeset().\n *\n * Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.\n * Binding by nodeset should therefore be preferred whenever possible.\n *\n * \\sa Some example codes are available under doc/examples/ in the source tree.\n *\n * \\note On some operating systems, memory binding affects the CPU\n * binding; see ::HWLOC_MEMBIND_NOCPUBIND\n * @{\n */\n\n/** \\brief Memory binding policy.\n *\n * These constants can be used to choose the binding policy.  Only one policy can\n * be used at a time (i.e., the values cannot be OR'ed together).\n *\n * Not all systems support all kinds of binding.\n * hwloc_topology_get_support() may be used to query about the actual memory\n * binding policy support in the currently used operating system.\n * See the \"Detailed Description\" section of \\ref hwlocality_membinding\n * for a description of errors that can occur.\n */\ntypedef enum {\n  /** \\brief Reset the memory allocation policy to the system default.\n   * Depending on the operating system, this may correspond to\n   * ::HWLOC_MEMBIND_FIRSTTOUCH (Linux),\n   * or ::HWLOC_MEMBIND_BIND (AIX, HP-UX, OSF, Solaris, Windows).\n   * This policy is never returned by get membind functions when running\n   * on normal machines.\n   * It is only returned when binding hooks are empty because the topology\n   * was loaded from XML, or HWLOC_THISSYSTEM=0, etc.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_DEFAULT =\t0,\n\n  /** \\brief Allocate memory\n   * but do not immediately bind it to a specific locality. Instead,\n   * each page in the allocation is bound only when it is first\n   * touched. Pages are individually bound to the local NUMA node of\n   * the first thread that touches it. If there is not enough memory\n   * on the node, allocation may be done in the specified nodes\n   * before allocating on other nodes.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_FIRSTTOUCH =\t1,\n\n  /** \\brief Allocate memory on the specified nodes.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_BIND =\t\t2,\n\n  /** \\brief Allocate memory on the given nodes in an interleaved\n   * / round-robin manner.  The precise layout of the memory across\n   * multiple NUMA nodes is OS/system specific. Interleaving can be\n   * useful when threads distributed across the specified NUMA nodes\n   * will all be accessing the whole memory range concurrently, since\n   * the interleave will then balance the memory references.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_INTERLEAVE =\t3,\n\n  /** \\brief Replicate memory on the given nodes; reads from this\n   * memory will attempt to be serviced from the NUMA node local to\n   * the reading thread. Replicating can be useful when multiple\n   * threads from the specified NUMA nodes will be sharing the same\n   * read-only data.\n   *\n   * This policy can only be used with existing memory allocations\n   * (i.e., the hwloc_set_*membind*() functions); it cannot be used\n   * with functions that allocate new memory (i.e., the hwloc_alloc*()\n   * functions).\n   * \\hideinitializer */\n  HWLOC_MEMBIND_REPLICATE =\t4,\n\n  /** \\brief For each page bound with this policy, by next time\n   * it is touched (and next time only), it is moved from its current\n   * location to the local NUMA node of the thread where the memory\n   * reference occurred (if it needs to be moved at all).\n   * \\hideinitializer */\n  HWLOC_MEMBIND_NEXTTOUCH =\t5,\n\n  /** \\brief Returned by get_membind() functions when multiple\n   * threads or parts of a memory area have differing memory binding\n   * policies.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_MIXED = -1\n} hwloc_membind_policy_t;\n\n/** \\brief Memory binding flags.\n *\n * These flags can be used to refine the binding policy.\n * All flags can be logically OR'ed together with the exception of\n * ::HWLOC_MEMBIND_PROCESS and ::HWLOC_MEMBIND_THREAD;\n * these two flags are mutually exclusive.\n *\n * Not all systems support all kinds of binding.\n * hwloc_topology_get_support() may be used to query about the actual memory\n * binding support in the currently used operating system.\n * See the \"Detailed Description\" section of \\ref hwlocality_membinding\n * for a description of errors that can occur.\n */\ntypedef enum {\n  /** \\brief Set policy for all threads of the specified (possibly\n   * multithreaded) process.  This flag is mutually exclusive with\n   * ::HWLOC_MEMBIND_THREAD.\n   * \\hideinitializer */\n  HWLOC_MEMBIND_PROCESS =       (1<<0),\n\n /** \\brief Set policy for a specific thread of the current process.\n  * This flag is mutually exclusive with ::HWLOC_MEMBIND_PROCESS.\n  * \\hideinitializer */\n  HWLOC_MEMBIND_THREAD =        (1<<1),\n\n /** Request strict binding from the OS.  The function will fail if\n  * the binding can not be guaranteed / completely enforced.\n  *\n  * This flag has slightly different meanings depending on which\n  * function it is used with.\n  * \\hideinitializer  */\n  HWLOC_MEMBIND_STRICT =        (1<<2),\n\n /** \\brief Migrate existing allocated memory.  If the memory cannot\n  * be migrated and the ::HWLOC_MEMBIND_STRICT flag is passed, an error\n  * will be returned.\n  * \\hideinitializer  */\n  HWLOC_MEMBIND_MIGRATE =       (1<<3),\n\n  /** \\brief Avoid any effect on CPU binding.\n   *\n   * On some operating systems, some underlying memory binding\n   * functions also bind the application to the corresponding CPU(s).\n   * Using this flag will cause hwloc to avoid using OS functions that\n   * could potentially affect CPU bindings.  Note, however, that using\n   * NOCPUBIND may reduce hwloc's overall memory binding\n   * support. Specifically: some of hwloc's memory binding functions\n   * may fail with errno set to ENOSYS when used with NOCPUBIND.\n   * \\hideinitializer\n   */\n  HWLOC_MEMBIND_NOCPUBIND =     (1<<4),\n\n  /** \\brief Consider the bitmap argument as a nodeset.\n   *\n   * Functions whose name ends with _nodeset() take a nodeset argument.\n   * Other functions take a bitmap argument that is considered a nodeset\n   * if this flag is given, or a cpuset otherwise.\n   *\n   * Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.\n   * Binding by nodeset should therefore be preferred whenever possible.\n   * \\hideinitializer\n   */\n  HWLOC_MEMBIND_BYNODESET =     (1<<5)\n} hwloc_membind_flags_t;\n\n/** \\brief Set the default memory binding policy of the current\n * process or thread to prefer the NUMA node(s) specified by \\p nodeset\n *\n * If neither ::HWLOC_MEMBIND_PROCESS nor ::HWLOC_MEMBIND_THREAD is\n * specified, the current process is assumed to be single-threaded.\n * This is the most portable form as it permits hwloc to use either\n * process-based OS functions or thread-based OS functions, depending\n * on which are available.\n *\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n */\nHWLOC_DECLSPEC int hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Set the default memory binding policy of the current\n * process or thread to prefer the NUMA node(s) specified by \\p set\n *\n * If neither ::HWLOC_MEMBIND_PROCESS nor ::HWLOC_MEMBIND_THREAD is\n * specified, the current process is assumed to be single-threaded.\n * This is the most portable form as it permits hwloc to use either\n * process-based OS functions or thread-based OS functions, depending\n * on which are available.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n */\nHWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Query the default memory binding policy and physical locality of the\n * current process or thread.\n *\n * This function has two output parameters: \\p nodeset and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the current memory binding policies and nodesets in\n * the queried target.\n *\n * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query\n * target is the current policies and nodesets for all the threads in\n * the current process.  Passing ::HWLOC_MEMBIND_THREAD specifies that\n * the query target is the current policy and nodeset for only the\n * thread invoking this function.\n *\n * If neither of these flags are passed (which is the most portable\n * method), the process is assumed to be single threaded.  This allows\n * hwloc to use either process-based OS functions or thread-based OS\n * functions, depending on which are available.\n *\n * ::HWLOC_MEMBIND_STRICT is only meaningful when ::HWLOC_MEMBIND_PROCESS\n * is also specified.  In this case, hwloc will check the default\n * memory policies and nodesets for all threads in the process.  If\n * they are not identical, -1 is returned and errno is set to EXDEV.\n * If they are identical, the values are returned in \\p nodeset and \\p\n * policy.\n *\n * Otherwise, if ::HWLOC_MEMBIND_PROCESS is specified (and\n * ::HWLOC_MEMBIND_STRICT is \\em not specified), \\p nodeset is set to\n * the logical OR of all threads' default nodeset.\n * If all threads' default policies are the same, \\p policy is set to\n * that policy.  If they are different, \\p policy is set to\n * ::HWLOC_MEMBIND_MIXED.\n *\n * In the ::HWLOC_MEMBIND_THREAD case (or when neither\n * ::HWLOC_MEMBIND_PROCESS or ::HWLOC_MEMBIND_THREAD is specified), there\n * is only one nodeset and policy; they are returned in \\p nodeset and\n * \\p policy, respectively.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n */\nHWLOC_DECLSPEC int hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Query the default memory binding policy and physical locality of the\n * current process or thread.\n *\n * This function has two output parameters: \\p set and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the current memory binding policies and nodesets in\n * the queried target.\n *\n * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query\n * target is the current policies and nodesets for all the threads in\n * the current process.  Passing ::HWLOC_MEMBIND_THREAD specifies that\n * the query target is the current policy and nodeset for only the\n * thread invoking this function.\n *\n * If neither of these flags are passed (which is the most portable\n * method), the process is assumed to be single threaded.  This allows\n * hwloc to use either process-based OS functions or thread-based OS\n * functions, depending on which are available.\n *\n * ::HWLOC_MEMBIND_STRICT is only meaningful when ::HWLOC_MEMBIND_PROCESS\n * is also specified.  In this case, hwloc will check the default\n * memory policies and nodesets for all threads in the process.  If\n * they are not identical, -1 is returned and errno is set to EXDEV.\n * If they are identical, the values are returned in \\p set and \\p\n * policy.\n *\n * Otherwise, if ::HWLOC_MEMBIND_PROCESS is specified (and\n * ::HWLOC_MEMBIND_STRICT is \\em not specified), the default set\n * from each thread is logically OR'ed together.\n * If all threads' default policies are the same, \\p policy is set to\n * that policy.  If they are different, \\p policy is set to\n * ::HWLOC_MEMBIND_MIXED.\n *\n * In the ::HWLOC_MEMBIND_THREAD case (or when neither\n * ::HWLOC_MEMBIND_PROCESS or ::HWLOC_MEMBIND_THREAD is specified), there\n * is only one set and policy; they are returned in \\p set and\n * \\p policy, respectively.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n */\nHWLOC_DECLSPEC int hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Set the default memory binding policy of the specified\n * process to prefer the NUMA node(s) specified by \\p nodeset\n *\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n */\nHWLOC_DECLSPEC int hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Set the default memory binding policy of the specified\n * process to prefer the NUMA node(s) specified by \\p set\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n */\nHWLOC_DECLSPEC int hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Query the default memory binding policy and physical locality of the\n * specified process.\n *\n * This function has two output parameters: \\p nodeset and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the current memory binding policies and nodesets in\n * the queried target.\n *\n * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query\n * target is the current policies and nodesets for all the threads in\n * the specified process.  If ::HWLOC_MEMBIND_PROCESS is not specified\n * (which is the most portable method), the process is assumed to be\n * single threaded.  This allows hwloc to use either process-based OS\n * functions or thread-based OS functions, depending on which are\n * available.\n *\n * Note that it does not make sense to pass ::HWLOC_MEMBIND_THREAD to\n * this function.\n *\n * If ::HWLOC_MEMBIND_STRICT is specified, hwloc will check the default\n * memory policies and nodesets for all threads in the specified\n * process.  If they are not identical, -1 is returned and errno is\n * set to EXDEV.  If they are identical, the values are returned in \\p\n * nodeset and \\p policy.\n *\n * Otherwise, \\p nodeset is set to the logical OR of all threads'\n * default nodeset.  If all threads' default policies are the same, \\p\n * policy is set to that policy.  If they are different, \\p policy is\n * set to ::HWLOC_MEMBIND_MIXED.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n */\nHWLOC_DECLSPEC int hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Query the default memory binding policy and physical locality of the\n * specified process.\n *\n * This function has two output parameters: \\p set and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the current memory binding policies and nodesets in\n * the queried target.\n *\n * Passing the ::HWLOC_MEMBIND_PROCESS flag specifies that the query\n * target is the current policies and nodesets for all the threads in\n * the specified process.  If ::HWLOC_MEMBIND_PROCESS is not specified\n * (which is the most portable method), the process is assumed to be\n * single threaded.  This allows hwloc to use either process-based OS\n * functions or thread-based OS functions, depending on which are\n * available.\n *\n * Note that it does not make sense to pass ::HWLOC_MEMBIND_THREAD to\n * this function.\n *\n * If ::HWLOC_MEMBIND_STRICT is specified, hwloc will check the default\n * memory policies and nodesets for all threads in the specified\n * process.  If they are not identical, -1 is returned and errno is\n * set to EXDEV.  If they are identical, the values are returned in \\p\n * set and \\p policy.\n *\n * Otherwise, \\p set is set to the logical OR of all threads'\n * default set.  If all threads' default policies\n * are the same, \\p policy is set to that policy.  If they are\n * different, \\p policy is set to ::HWLOC_MEMBIND_MIXED.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n *\n * \\note \\p hwloc_pid_t is \\p pid_t on Unix platforms,\n * and \\p HANDLE on native Windows platforms.\n */\nHWLOC_DECLSPEC int hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Bind the already-allocated memory identified by (addr, len)\n * to the NUMA node(s) specified by \\p nodeset.\n *\n * \\return 0 if \\p len is 0.\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n */\nHWLOC_DECLSPEC int hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Bind the already-allocated memory identified by (addr, len)\n * to the NUMA node(s) specified by \\p set.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * \\return 0 if \\p len is 0.\n * \\return -1 with errno set to ENOSYS if the action is not supported\n * \\return -1 with errno set to EXDEV if the binding cannot be enforced\n */\nHWLOC_DECLSPEC int hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags);\n\n/** \\brief Query the physical NUMA node(s) and binding policy of the memory\n * identified by (\\p addr, \\p len ).\n *\n * This function has two output parameters: \\p nodeset and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the memory binding policies and nodesets of the pages\n * in the address range.\n *\n * If ::HWLOC_MEMBIND_STRICT is specified, the target pages are first\n * checked to see if they all have the same memory binding policy and\n * nodeset.  If they do not, -1 is returned and errno is set to EXDEV.\n * If they are identical across all pages, the nodeset and policy are\n * returned in \\p nodeset and \\p policy, respectively.\n *\n * If ::HWLOC_MEMBIND_STRICT is not specified, \\p nodeset is set to the\n * union of all NUMA node(s) containing pages in the address range.\n * If all pages in the target have the same policy, it is returned in\n * \\p policy.  Otherwise, \\p policy is set to ::HWLOC_MEMBIND_MIXED.\n *\n * If \\p len is 0, -1 is returned and errno is set to EINVAL.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n */\nHWLOC_DECLSPEC int hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Query the CPUs near the physical NUMA node(s) and binding policy of\n * the memory identified by (\\p addr, \\p len ).\n *\n * This function has two output parameters: \\p set and \\p policy.\n * The values returned in these parameters depend on both the \\p flags\n * passed in and the memory binding policies and nodesets of the pages\n * in the address range.\n *\n * If ::HWLOC_MEMBIND_STRICT is specified, the target pages are first\n * checked to see if they all have the same memory binding policy and\n * nodeset.  If they do not, -1 is returned and errno is set to EXDEV.\n * If they are identical across all pages, the set and policy are\n * returned in \\p set and \\p policy, respectively.\n *\n * If ::HWLOC_MEMBIND_STRICT is not specified, the union of all NUMA\n * node(s) containing pages in the address range is calculated.\n * If all pages in the target have the same policy, it is returned in\n * \\p policy.  Otherwise, \\p policy is set to ::HWLOC_MEMBIND_MIXED.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * If \\p len is 0, -1 is returned and errno is set to EINVAL.\n *\n * If any other flags are specified, -1 is returned and errno is set\n * to EINVAL.\n */\nHWLOC_DECLSPEC int hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags);\n\n/** \\brief Get the NUMA nodes where memory identified by (\\p addr, \\p len ) is physically allocated.\n *\n * Fills \\p set according to the NUMA nodes where the memory area pages\n * are physically allocated. If no page is actually allocated yet,\n * \\p set may be empty.\n *\n * If pages spread to multiple nodes, it is not specified whether they spread\n * equitably, or whether most of them are on a single node, etc.\n *\n * The operating system may move memory pages from one processor\n * to another at any time according to their binding,\n * so this function may return something that is already\n * outdated.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified in \\p flags, set is\n * considered a nodeset. Otherwise it's a cpuset.\n *\n * If \\p len is 0, \\p set is emptied.\n */\nHWLOC_DECLSPEC int hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, int flags);\n\n/** \\brief Allocate some memory\n *\n * This is equivalent to malloc(), except that it tries to allocate\n * page-aligned memory from the OS.\n *\n * \\note The allocated memory should be freed with hwloc_free().\n */\nHWLOC_DECLSPEC void *hwloc_alloc(hwloc_topology_t topology, size_t len);\n\n/** \\brief Allocate some memory on NUMA memory nodes specified by \\p nodeset\n *\n * \\return NULL with errno set to ENOSYS if the action is not supported\n * and ::HWLOC_MEMBIND_STRICT is given\n * \\return NULL with errno set to EXDEV if the binding cannot be enforced\n * and ::HWLOC_MEMBIND_STRICT is given\n * \\return NULL with errno set to ENOMEM if the memory allocation failed\n * even before trying to bind.\n *\n * \\note The allocated memory should be freed with hwloc_free().\n */\nHWLOC_DECLSPEC void *hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;\n\n/** \\brief Allocate some memory on NUMA memory nodes specified by \\p set\n *\n * \\return NULL with errno set to ENOSYS if the action is not supported\n * and ::HWLOC_MEMBIND_STRICT is given\n * \\return NULL with errno set to EXDEV if the binding cannot be enforced\n * and ::HWLOC_MEMBIND_STRICT is given\n * \\return NULL with errno set to ENOMEM if the memory allocation failed\n * even before trying to bind.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n *\n * \\note The allocated memory should be freed with hwloc_free().\n */\nHWLOC_DECLSPEC void *hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;\n\n/** \\brief Allocate some memory on NUMA memory nodes specified by \\p nodeset\n *\n * This is similar to hwloc_alloc_membind() except that it is allowed to change\n * the current memory binding policy, thus providing more binding support, at\n * the expense of changing the current state.\n */\nstatic __hwloc_inline void *\nhwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;\n\n/** \\brief Allocate some memory on NUMA memory nodes specified by \\p set\n *\n * This is similar to hwloc_alloc_membind_nodeset() except that it is allowed to change\n * the current memory binding policy, thus providing more binding support, at\n * the expense of changing the current state.\n *\n * If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.\n * Otherwise it's a cpuset.\n */\nstatic __hwloc_inline void *\nhwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc;\n\n/** \\brief Free memory that was previously allocated by hwloc_alloc()\n * or hwloc_alloc_membind().\n */\nHWLOC_DECLSPEC int hwloc_free(hwloc_topology_t topology, void *addr, size_t len);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_tinker Modifying a loaded Topology\n * @{\n */\n\n/** \\brief Add a MISC object to the topology\n *\n * A new MISC object will be created and inserted into the topology at the\n * position given by bitmap \\p cpuset. This offers a way to add new\n * intermediate levels to the topology hierarchy.\n *\n * \\p cpuset and \\p name will be copied to setup the new object attributes.\n *\n * \\return the newly-created object.\n * \\return \\c NULL if the insertion conflicts with the existing topology tree.\n *\n * \\note If \\p name contains some non-printable characters, they will\n * be dropped when exporting to XML, see hwloc_topology_export_xml().\n */\nHWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_cpuset(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, const char *name);\n\n/** \\brief Add a MISC object as a leaf of the topology\n *\n * A new MISC object will be created and inserted into the topology at the\n * position given by parent. It is appended to the list of existing children,\n * without ever adding any intermediate hierarchy level. This is useful for\n * annotating the topology without actually changing the hierarchy.\n *\n * \\p name will be copied to the setup the new object attributes.\n * However, the new leaf object will not have any \\p cpuset.\n *\n * \\return the newly-created object\n *\n * \\note If \\p name contains some non-printable characters, they will\n * be dropped when exporting to XML, see hwloc_topology_export_xml().\n */\nHWLOC_DECLSPEC hwloc_obj_t hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name);\n\n/** \\brief Flags to be given to hwloc_topology_restrict(). */\nenum hwloc_restrict_flags_e {\n  /** \\brief Adapt distance matrices according to objects being removed during restriction.\n   * If this flag is not set, distance matrices are removed.\n   * \\hideinitializer\n   */\n  HWLOC_RESTRICT_FLAG_ADAPT_DISTANCES = (1<<0),\n\n  /** \\brief Move Misc objects to ancestors if their parents are removed during restriction.\n   * If this flag is not set, Misc objects are removed when their parents are removed.\n   * \\hideinitializer\n   */\n  HWLOC_RESTRICT_FLAG_ADAPT_MISC = (1<<1),\n\n  /** \\brief Move I/O objects to ancestors if their parents are removed during restriction.\n   * If this flag is not set, I/O devices and bridges are removed when their parents are removed.\n   * \\hideinitializer\n   */\n  HWLOC_RESTRICT_FLAG_ADAPT_IO = (1<<2)\n};\n\n/** \\brief Restrict the topology to the given CPU set.\n *\n * Topology \\p topology is modified so as to remove all objects that\n * are not included (or partially included) in the CPU set \\p cpuset.\n * All objects CPU and node sets are restricted accordingly.\n *\n * \\p flags is a OR'ed set of ::hwloc_restrict_flags_e.\n *\n * \\note This call may not be reverted by restricting back to a larger\n * cpuset. Once dropped during restriction, objects may not be brought\n * back, except by loading another topology with hwloc_topology_load().\n *\n * \\return 0 on success.\n *\n * \\return -1 with errno set to EINVAL if the input cpuset is invalid.\n * The topology is not modified in this case.\n *\n * \\return -1 with errno set to ENOMEM on failure to allocate internal data.\n * The topology is reinitialized in this case. It should be either\n * destroyed with hwloc_topology_destroy() or configured and loaded again.\n */\nHWLOC_DECLSPEC int hwloc_topology_restrict(hwloc_topology_t __hwloc_restrict topology, hwloc_const_cpuset_t cpuset, unsigned long flags);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_custom Building Custom Topologies\n *\n * A custom topology may be initialized by calling hwloc_topology_set_custom()\n * after hwloc_topology_init(). It may then be modified by inserting objects\n * or entire topologies. Once done assembling, hwloc_topology_load() should\n * be invoked as usual to finalize the topology.\n * @{\n */\n\n/** \\brief Insert an existing topology inside a custom topology\n *\n * Duplicate the existing topology \\p oldtopology inside a new\n * custom topology \\p newtopology as a leaf of object \\p newparent.\n *\n * If \\p oldroot is not \\c NULL, duplicate \\p oldroot and all its\n * children instead of the entire \\p oldtopology. Passing the root\n * object of \\p oldtopology in \\p oldroot is equivalent to passing\n * \\c NULL.\n *\n * The custom topology \\p newtopology must have been prepared with\n * hwloc_topology_set_custom() and not loaded with hwloc_topology_load()\n * yet.\n *\n * \\p newparent may be either the root of \\p newtopology or an object\n * that was added through hwloc_custom_insert_group_object_by_parent().\n *\n * \\note The cpuset and nodeset of the \\p newparent object are not\n * modified based on the contents of \\p oldtopology.\n */\nHWLOC_DECLSPEC int hwloc_custom_insert_topology(hwloc_topology_t newtopology, hwloc_obj_t newparent, hwloc_topology_t oldtopology, hwloc_obj_t oldroot);\n\n/** \\brief Insert a new group object inside a custom topology\n *\n * An object with type ::HWLOC_OBJ_GROUP is inserted as a new child\n * of object \\p parent.\n *\n * \\p groupdepth is the depth attribute to be given to the new object.\n * It may for instance be 0 for top-level groups, 1 for their children,\n * and so on.\n *\n * The custom topology \\p newtopology must have been prepared with\n * hwloc_topology_set_custom() and not loaded with hwloc_topology_load()\n * yet.\n *\n * \\p parent may be either the root of \\p topology or an object that\n * was added earlier through hwloc_custom_insert_group_object_by_parent().\n *\n * \\note The cpuset and nodeset of the new group object are NULL because\n * these sets are meaningless when assembling multiple topologies.\n *\n * \\note The cpuset and nodeset of the \\p parent object are not modified.\n */\nHWLOC_DECLSPEC hwloc_obj_t hwloc_custom_insert_group_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, int groupdepth);\n\n/** @} */\n\n\n\n/** \\defgroup hwlocality_xmlexport Exporting Topologies to XML\n * @{\n */\n\n/** \\brief Export the topology into an XML file.\n *\n * This file may be loaded later through hwloc_topology_set_xml().\n *\n * \\return -1 if a failure occured.\n *\n * \\note See also hwloc_topology_set_userdata_export_callback()\n * for exporting application-specific object userdata.\n *\n * \\note The topology-specific userdata pointer is ignored when exporting to XML.\n *\n * \\note Only printable characters may be exported to XML string attributes.\n * Any other character, especially any non-ASCII character, will be silently\n * dropped.\n *\n * \\note If \\p name is \"-\", the XML output is sent to the standard output.\n */\nHWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const char *xmlpath);\n\n/** \\brief Export the topology into a newly-allocated XML memory buffer.\n *\n * \\p xmlbuffer is allocated by the callee and should be freed with\n * hwloc_free_xmlbuffer() later in the caller.\n *\n * This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().\n *\n * \\return -1 if a failure occured.\n *\n * \\note See also hwloc_topology_set_userdata_export_callback()\n * for exporting application-specific object userdata.\n *\n * \\note The topology-specific userdata pointer is ignored when exporting to XML.\n *\n * \\note Only printable characters may be exported to XML string attributes.\n * Any other character, especially any non-ASCII character, will be silently\n * dropped.\n */\nHWLOC_DECLSPEC int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen);\n\n/** \\brief Free a buffer allocated by hwloc_topology_export_xmlbuffer() */\nHWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuffer);\n\n/** \\brief Set the application-specific callback for exporting object userdata\n *\n * The object userdata pointer is not exported to XML by default because hwloc\n * does not know what it contains.\n *\n * This function lets applications set \\p export_cb to a callback function\n * that converts this opaque userdata into an exportable string.\n *\n * \\p export_cb is invoked during XML export for each object whose\n * \\p userdata pointer is not \\c NULL.\n * The callback should use hwloc_export_obj_userdata() or\n * hwloc_export_obj_userdata_base64() to actually export\n * something to XML (possibly multiple times per object).\n *\n * \\p export_cb may be set to \\c NULL if userdata should not be exported to XML.\n *\n * \\note The topology-specific userdata pointer is ignored when exporting to XML.\n */\nHWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,\n\t\t\t\t\t\t\t\tvoid (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));\n\n/** \\brief Export some object userdata to XML\n *\n * This function may only be called from within the export() callback passed\n * to hwloc_topology_set_userdata_export_callback().\n * It may be invoked one of multiple times to export some userdata to XML.\n * The \\p buffer content of length \\p length is stored with optional name\n * \\p name.\n *\n * When importing this XML file, the import() callback (if set) will be\n * called exactly as many times as hwloc_export_obj_userdata() was called\n * during export(). It will receive the corresponding \\p name, \\p buffer\n * and \\p length arguments.\n *\n * \\p reserved, \\p topology and \\p obj must be the first three parameters\n * that were given to the export callback.\n *\n * Only printable characters may be exported to XML string attributes.\n * If a non-printable character is passed in \\p name or \\p buffer,\n * the function returns -1 with errno set to EINVAL.\n *\n * If exporting binary data, the application should first encode into\n * printable characters only (or use hwloc_export_obj_userdata_base64()).\n * It should also take care of portability issues if the export may\n * be reimported on a different architecture.\n */\nHWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);\n\n/** \\brief Encode and export some object userdata to XML\n *\n * This function is similar to hwloc_export_obj_userdata() but it encodes\n * the input buffer into printable characters before exporting.\n * On import, decoding is automatically performed before the data is given\n * to the import() callback if any.\n *\n * This function may only be called from within the export() callback passed\n * to hwloc_topology_set_userdata_export_callback().\n *\n * The function does not take care of portability issues if the export\n * may be reimported on a different architecture.\n */\nHWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);\n\n/** \\brief Set the application-specific callback for importing userdata\n *\n * On XML import, userdata is ignored by default because hwloc does not know\n * how to store it in memory.\n *\n * This function lets applications set \\p import_cb to a callback function\n * that will get the XML-stored userdata and store it in the object as expected\n * by the application.\n *\n * \\p import_cb is called during hwloc_topology_load() as many times as\n * hwloc_export_obj_userdata() was called during export. The topology\n * is not entirely setup yet. Object attributes are ready to consult,\n * but links between objects are not.\n *\n * \\p import_cb may be \\c NULL if userdata should be ignored during import.\n *\n * \\note \\p buffer contains \\p length characters followed by a null byte ('\\0').\n *\n * \\note This function should be called before hwloc_topology_load().\n *\n * \\note The topology-specific userdata pointer is ignored when importing from XML.\n */\nHWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,\n\t\t\t\t\t\t\t\tvoid (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));\n\n/** @} */\n\n\n/** \\defgroup hwlocality_syntheticexport Exporting Topologies to Synthetic\n * @{\n */\n\n/** \\brief Flags for exporting synthetic topologies.\n *\n * Flags to be given as a OR'ed set to hwloc_topology_export_synthetic().\n */\nenum hwloc_topology_export_synthetic_flags_e {\n /** \\brief Export extended types such as L2dcache as basic types such as Cache.\n  *\n  * This is required if loading the synthetic description with hwloc < 1.9.\n  * \\hideinitializer\n  */\n HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES = (1UL<<0),\n\n /** \\brief Do not export level attributes.\n  *\n  * Ignore level attributes such as memory/cache sizes or PU indexes.\n  * This is required if loading the synthetic description with hwloc < 1.10.\n  * \\hideinitializer\n  */\n HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1)\n};\n\n/** \\brief Export the topology as a synthetic string.\n *\n * At most \\p buflen characters will be written in \\p buffer,\n * including the terminating \\0.\n *\n * This exported string may be given back to hwloc_topology_set_synthetic().\n *\n * \\p flags is a OR'ed set of hwloc_topology_export_synthetic_flags_e.\n *\n * \\return The number of characters that were written,\n * not including the terminating \\0.\n *\n * \\return -1 if the topology could not be exported,\n * for instance if it is not symmetric.\n *\n * \\note A 1024-byte buffer should be large enough for exporting\n * topologies in the vast majority of cases.\n */\n  HWLOC_DECLSPEC int hwloc_topology_export_synthetic(hwloc_topology_t topology, char *buffer, size_t buflen, unsigned long flags);\n\n/** @} */\n\n\n\n#ifdef __cplusplus\n} /* extern \"C\" */\n#endif\n\n\n/* high-level helpers */\n#include <hwloc/helper.h>\n\n/* inline code of some functions above */\n#include <hwloc/inlines.h>\n\n/* topology diffs */\n#include <hwloc/diff.h>\n\n/* deprecated headers */\n#include <hwloc/deprecated.h>\n\n#endif /* HWLOC_H */\n"
  },
  {
    "path": "rocrtst/thirdparty/lib/LICENSE",
    "content": "Copyright © 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation.  All rights reserved.\nCopyright © 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation.  All rights reserved.\nCopyright © 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart.  All rights reserved.\nCopyright © 2004-2005 The Regents of the University of California. All rights reserved.\nCopyright © 2009      CNRS\nCopyright © 2009-2016 Inria.  All rights reserved.\nCopyright © 2009-2015 Université Bordeaux\nCopyright © 2009-2015 Cisco Systems, Inc.  All rights reserved.\nCopyright © 2009-2012 Oracle and/or its affiliates.  All rights reserved.\nCopyright © 2010      IBM\nCopyright © 2010      Jirka Hladky\nCopyright © 2012      Aleksej Saushev, The NetBSD Foundation\nCopyright © 2012      Blue Brain Project, EPFL. All rights reserved.\nCopyright © 2013-2014 University of Wisconsin-La Crosse. All rights reserved.\nCopyright © 2015      Research Organization for Information Science and Technology (RIST). All rights reserved.\nCopyright © 2015-2016 Intel, Inc.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n1. Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n3. The name of the author may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n"
  },
  {
    "path": "runtime/cmake_modules/COPYING-CMAKE-SCRIPTS",
    "content": "Redistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n3. The name of the author may not be used to endorse or promote products \n   derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "runtime/cmake_modules/FindLibElf.cmake",
    "content": "# - Try to find libelf\n# Once done this will define\n#\n#  LIBELF_FOUND - system has libelf\n#  LIBELF_INCLUDE_DIRS - the libelf include directory\n#  LIBELF_LIBRARIES - Link these to use libelf\n#  LIBELF_DEFINITIONS - Compiler switches required for using libelf\n#\n#  Copyright (c) 2008 Bernhard Walle <bernhard.walle@gmx.de>\n#\n#  Redistribution and use is allowed according to the terms of the New\n#  BSD license.\n#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n#\n\nif (LIBELF_FOUND)\n  return()\nendif (LIBELF_FOUND)\n\nfind_path (LIBELF_INCLUDE_DIRS\n  NAMES\n    libelf.h\n  PATHS\n    /usr/include\n    /usr/include/libelf\n    /usr/local/include\n    /usr/local/include/libelf\n    /opt/local/include\n    /opt/local/include/libelf\n    /sw/include\n    /sw/include/libelf\n    ENV CPATH)\n\nfind_library (LIBELF_LIBRARIES\n  NAMES\n    elf\n  PATHS\n    /usr/lib\n    /usr/local/lib\n    /opt/local/lib\n    /sw/lib\n    ENV LIBRARY_PATH\n    ENV LD_LIBRARY_PATH)\n\ninclude (FindPackageHandleStandardArgs)\n\n\n# handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE\nFIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG\n  LIBELF_LIBRARIES\n  LIBELF_INCLUDE_DIRS)\n\nSET(CMAKE_REQUIRED_LIBRARIES elf)\nINCLUDE(CheckCXXSourceCompiles)\nCHECK_CXX_SOURCE_COMPILES(\"#include <libelf.h>\nint main() {\n  Elf *e = (Elf*)0;\n  size_t sz;\n  elf_getshdrstrndx(e, &sz);\n  return 0;\n}\" ELF_GETSHDRSTRNDX)\n\nmark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX)\n\nif(LIBELF_FOUND)\n  add_library(elf UNKNOWN IMPORTED)\n  set_property(TARGET elf PROPERTY IMPORTED_LOCATION ${LIBELF_LIBRARIES})\n  set_property(TARGET elf PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIBELF_INCLUDE_DIRS})\nendif()\n"
  },
  {
    "path": "runtime/docs/api-reference/api.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _rocr-api:\n\nAPI\n===\n\n:ref:`genindex`\n\n:ref:`search`\n\nArchitected Queuing Language\n############################\n.. doxygengroup:: aql\n   :content-only:\n   :inner:\n\nCode objects [**DEPRECATED**]\n#############################\n.. doxygengroup:: code-object\n   :content-only:\n   :inner:\n\nExecutable\n##########\n.. doxygengroup:: executable\n   :content-only:\n   :inner:\n\nFinalization extensions\n#######################\n.. doxygengroup:: ext-alt-finalizer-extensions\n   :content-only:\n   :inner:\n\nFinalization program\n####################\n.. doxygengroup:: ext-alt-finalizer-program\n   :content-only:\n   :inner:\n\nImages and samplers\n###################\n.. doxygengroup:: ext-images\n   :content-only:\n   :inner:\n\nInstruction set architecture\n############################\n.. doxygengroup:: instruction-set-architecture\n   :content-only:\n   :inner:\n\nMemory\n######\n.. doxygengroup:: memory\n   :content-only:\n   :inner:\n\nQueues\n######\n.. doxygengroup:: queue\n   :content-only:\n   :inner:\n\nRuntime notifications\n#####################\n.. doxygengroup:: status\n   :content-only:\n   :inner:\n\nSignals\n#######\n.. doxygengroup:: signals\n   :content-only:\n   :inner:\n\nSystem and agent information\n############################\n.. doxygengroup:: agentinfo\n   :content-only:\n   :inner:\n\nProfiling\n###############\n.. doxygengroup:: profile\n   :content-only:\n   :inner:\n\nError codes\n#############\n.. doxygengroup:: error-codes\n   :content-only:\n   :inner:\n\n\n"
  },
  {
    "path": "runtime/docs/api-reference/c-interface-adaptors.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _c-interface-adaptors:\n\nC interface adaptors\n=====================\n\nThe C interface layer is the :ref:`top layer in ROCR <runtime-design>` that provides C++ APIs as defined in the `HSA Runtime Specification 1.2 <https://hsafoundation.com/wp-content/uploads/2021/02/HSA-Runtime-1.2.pdf>`_. The C interface layer also consists of the interfaces and default definitions for the standard extensions. The interface functions simply forward to a function pointer table defined here. The table is initialized to point to default definitions, which simply returns an appropriate error code. If available, the extension library is loaded as part of runtime initialization and the table is updated to point to the extension library.\n\nFiles present in this layer:\n\n- ``hsa.h`` (cpp)\n\n- ``hsa_ext_interface.h`` (cpp)"
  },
  {
    "path": "runtime/docs/api-reference/environment_variables.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _environment-variables:\n\nEnvironment variables\n========================\n\nThe following table lists the most often used environment variables.\n\n.. include:: ../data/env_variables.rst\n"
  },
  {
    "path": "runtime/docs/conf.py",
    "content": "# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\nimport os\nimport re\n\nfrom rocm_docs import ROCmDocs\n\nwith open('../../CMakeLists.txt', encoding='utf-8') as f:\n    match = re.search(r'get_version\\(\\\"?([0-9.]+)[^0-9.]+', f.read())\n    if not match:\n        raise ValueError(\"VERSION not found!\")\n    version_number = match[1]\nleft_nav_title = f\"ROCR {version_number} Documentation\"\n\n# for PDF output on Read the Docs\nproject = \"ROCR Documentation\"\nauthor = \"Advanced Micro Devices, Inc.\"\ncopyright = \"Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.\"\nversion = version_number\nrelease = version_number\n\nexternal_toc_path = \"./sphinx/_toc.yml\"\n\nexternal_projects_current_project = \"rocr-runtime\"\n\ndocs_core = ROCmDocs(left_nav_title)\ndocs_core.run_doxygen(doxygen_root=\"doxygen\", doxygen_path=\"doxygen/xml\")\ndocs_core.setup()\n\nfor sphinx_var in ROCmDocs.SPHINX_VARS:\n    globals()[sphinx_var] = getattr(docs_core, sphinx_var)\n"
  },
  {
    "path": "runtime/docs/contribution/contributing-to-rocr.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _contributing-to-rocr:\n\nContributing to ROCR\n========================\n\nThis document contains useful information required to contribute to ROCR.\n\n.. _runtime-design:\n\nRuntime design\n-----------------\n\nROCR consists of the following primary layers:\n\n1. :ref:`C interface adaptors <c-interface-adaptors>`\n\n2. C++ interface classes and common functions\n\n3. Device-specific implementations\n\nThe first layer provides interfaces to make ROCR APIs available to the user applications.\nThe second and third layers comprise of the internal ROCR implementation, which is available for contribution.\n\nAdditionally, the runtime is dependent on a small utility library that provides simple common functions, limited operating system, compiler abstraction, and atomic operation interfaces.\n\nThe following sections list the important files present in the second and third layer.\n\nC++ interface classes and common functions\n----------------------------------------------\n\nThe C++ interface layer provides abstract interface classes encapsulating commands to HSA signals, agents, and queues. This layer also contains the implementation of device-independent commands, such as ``hsa_init``, ``hsa_system_get_info``, and a default signal and queue implementation.\n\nFiles present in this layer:\n\n- ``runtime.h`` (cpp)\n\n- ``agent.h``\n\n- ``queue.h``\n\n- ``signal.h``\n\n- ``memory_region.h`` (cpp)\n\n- ``checked.h``\n\n- ``memory_database.h`` (cpp)\n\n- ``default_signal.h`` (cpp)\n\nDevice-specific implementations\n----------------------------------\n\nThe device-specific layer contains implementations of the C++ interface classes that implement HSA functionality for ROCm supported devices.\n\nFiles present in this layer:\n\n- ``amd_cpu_agent.h`` (cpp)\n\n- ``amd_gpu_agent.h`` (cpp)\n\n- ``amd_hw_aql_command_processor.h`` (cpp)\n\n- ``amd_memory_region.h`` (cpp)\n\n- ``amd_memory_registration.h`` (cpp)\n\n- ``amd_topology.h`` (cpp)\n\n- ``host_queue.h`` (cpp)\n\n- ``interrupt_signal.h`` (cpp)\n\n- ``hsa_ext_private_amd.h`` (cpp)\n\nSource and include directories\n--------------------------------\n\n- ``core``: Source code for AMD’s implementation of the core HSA Runtime API’s\n\n- ``cmake_modules``: CMake support modules and files\n\n- ``inc``: Public and AMD-specific header files exposing the HSA Runtime`s interfaces\n\n- ``libamdhsacode``: Code object definitions and interfaces\n\n- ``loader``: Loads code objects\n\n- ``utils``: Utilities required to build the core runtime"
  },
  {
    "path": "runtime/docs/data/env_variables.rst",
    "content": ".. meta::\n    :description: ROCR-Runtime environment variables\n    :keywords: AMD, ROCR, environment variables, environment\n\n.. _rocr-env:\n.. list-table::\n    :header-rows: 1\n    :widths: 35,14,51\n\n    * - Environment variable\n      - Default value\n      - Value\n\n    * - | ``ROCR_VISIBLE_DEVICES``\n        | Specifies a list of device indices or UUIDs to be exposed to the applications.\n      - None\n      - ``0,GPU-DEADBEEFDEADBEEF``\n\n    * - | ``HSA_NO_SCRATCH_RECLAIM``\n        | Controls whether scratch memory allocations are permanently assigned to queues or can be reclaimed based on usage thresholds.\n      - ``0``\n      - | 0: Disable.\n        | When dispatches need scratch memory that are lower than the threshold, the memory will be permanently assigned to the queue. For dispatches that exceed the threshold, a scratch-use-once mechanism will be used, resulting in the memory to be unassigned after the dispatch.\n        | 1: Enable.\n        | If a kernel dispatch needs scratch memory, runtime will allocate and permanently assign device memory to the queue handling the dispatch, even if the amount of scratch memory exceeds the default threshold. This memory will not be available to other queues or processes until this process exits.\n\n    * - | ``HSA_SCRATCH_SINGLE_LIMIT``\n        | Specifies the threshold for the amount of scratch memory allocated and reclaimed in kernel dispatches.\n        | Enabling ``HSA_NO_SCRATCH_RECLAIM`` circumvents ``HSA_SCRATCH_SINGLE_LIMIT``, and treats ``HSA_SCRATCH_SINGLE_LIMIT`` as the maximum value.\n      - ``146800640``\n      - 0 to 4GB per XCC\n\n    * - | ``HSA_SCRATCH_SINGLE_LIMIT_ASYNC``\n        | On GPUs that support asynchronous scratch reclaim, this variable is used instead of ``HSA_SCRATCH_SINGLE_LIMIT`` to specify the threshold for scratch memory allocation.\n      - ``3221225472`` (3GB)\n      - 0 to 4GB per XCC\n\n    * - | ``HSA_ENABLE_SCRATCH_ASYNC_RECLAIM``\n        | Controls asynchronous scratch memory reclamation on supported GPUs.\n        | When enabled, if a device memory allocation fails, ROCr will attempt to reclaim scratch memory assigned to all queues and retry the allocation.\n      - ``1``\n      - | 0: Disable asynchronous scratch reclaim.\n        | 1: Enable asynchronous scratch reclaim on supported GPUs.\n\n    * - | ``HSA_XNACK``\n        | Enables XNACK.\n      - None\n      - 1: Enable\n\n    * - | ``HSA_CU_MASK``\n        | Sets the mask on a lower level of queue creation in the driver.\n        | This mask is also applied to the queues being profiled.\n      - None\n      - ``1:0-8``\n\n    * - | ``HSA_ENABLE_SDMA``\n        | Enables the use of direct memory access (DMA) engines in all copy directions (Host-to-Device, Device-to-Host, Device-to-Device), when using any of the following APIs:\n        | ``hsa_memory_copy``,\n        | ``hsa_amd_memory_fill``,\n        | ``hsa_amd_memory_async_copy``,\n        | ``hsa_amd_memory_async_copy_on_engine``.\n      - ``1``\n      - | 0: Disable\n        | 1: Enable\n\n    * - | ``HSA_ENABLE_PEER_SDMA``\n        | **Note**: This environment variable is ignored if ``HSA_ENABLE_SDMA`` is set to 0.\n        | Enables the use of DMA engines for Device-to-Device copies, when using any of the following APIs:\n        | ``hsa_memory_copy``,\n        | ``hsa_amd_memory_async_copy``,\n        | ``hsa_amd_memory_async_copy_on_engine``.\n      - ``1``\n      - | 0: Disable\n        | 1: Enable\n\n    * - | ``HSA_ENABLE_MWAITX``\n        | When mwaitx is enabled, on AMD CPUs, runtime will hint to the CPU to go into lower power-states when doing busy loops by using the mwaitx instruction.\n      - ``0``\n      - | 0: Disable\n        | 1: Enable\n\n    * - | ``HSA_OVERRIDE_CPU_AFFINITY_DEBUG``\n        | Controls whether ROCm helper threads inherit the parent process's CPU affinity mask.\n      - ``1``\n      - | 0: Enable inheritance. Helper threads use the parent process's core affinity mask, which should be set with enough cores for all threads.\n        | 1: Disable inheritance. Helper threads spawn on all available cores, ignoring the parent's affinity settings, which may affect performance in certain environments.\n\n    * - | ``HSA_ENABLE_DEBUG``\n        | Enables additional debug information and validation in the runtime.\n      - ``0``\n      - | 0: Disable debug mode.\n        | 1: Enable debug mode with additional validation and logging.\n\n\nHardware Debugging Environment Variables\n----------------------------------------\n\nThe following environment variables are intended for experienced users who are debugging hardware-specific issues.\nThese settings may impact performance and stability and should only be used when troubleshooting specific hardware problems.\n\n.. _rocr-debug-env:\n.. list-table::\n    :header-rows: 1\n    :widths: 35,14,51\n\n    * - Environment variable\n      - Default value\n      - Value\n\n    * - | ``HSA_DISABLE_FRAGMENT_ALLOCATOR``\n        | Disables internal memory fragment caching to help debug memory faults.\n      - ``0``\n      - | 0: Fragment allocator enabled (normal operation).\n        | 1: Fragment allocator disabled. Helps debug tools identify memory faults at their origin by preventing cached memory blocks from masking out-of-bounds writes.\n\n    * - | ``HSAKMT_DEBUG_LEVEL``\n        | Controls the verbosity level of debug messages from the ``libhsakmt.so`` driver layer.\n      - ``3``\n      - | 3: Only error messages (``pr_err``) are printed.\n        | 4: Error and warning messages (``pr_err``, ``pr_warn``) are printed.\n        | 5: Same as level 4 (notice level not implemented).\n        | 6: Error, warning, and info messages (``pr_err``, ``pr_warn``, ``pr_info``) are printed.\n        | 7: All debug messages including ``pr_debug`` are printed.\n\n    * - | ``HSA_ENABLE_INTERRUPT``\n        | Controls how completion signals are detected, useful for diagnosing interrupt storm issues.\n      - ``1``\n      - | 0: Disable hardware interrupts. Uses memory-based polling for completion signals instead of interrupts.\n        | 1: Enable hardware interrupts (normal operation).\n\n    * - | ``HSA_SVM_GUARD_PAGES``\n        | Controls the use of guard pages in Shared Virtual Memory (SVM) allocations.\n      - ``1``\n      - | 0: Disable SVM guard pages (for debugging memory access patterns).\n        | 1: Enable SVM guard pages (normal operation).\n\n    * - | ``HSA_DISABLE_CACHE``\n        | Controls GPU L2 cache utilization for all memory regions.\n      - ``0``\n      - | 0: Normal caching behavior (L2 cache enabled).\n        | 1: Disables L2 cache entirely. Sets all memory regions as uncacheable (MTYPE=UC) in the GPU, bypassing the L2 cache. Useful for diagnosing cache-related performance or correctness issues.\n"
  },
  {
    "path": "runtime/docs/index.rst",
    "content": ".. meta::\n    :description: HSA runtime implementation\n    :keywords: ROCm runtime, HSA runtime\n\n.. _index:\n\n=====================\nROCR documentation\n=====================\n\nThe ROCm runtime (ROCR) is AMD's implementation of HSA runtime, which is a thin, user-mode API that exposes the necessary interfaces to access and interact with graphics hardware driven by the AMDGPU driver set and the ROCK kernel driver. To learn more, see :ref:`what-is-rocr-runtime`\n\nYou can access ROCR code on our `GitHub repository <https://github.com/ROCm/ROCR-Runtime>`_.\n\nThe documentation is structured as follows:\n\n.. grid:: 2\n  :gutter: 3\n\n  .. grid-item-card:: Install\n\n    * :ref:`installation`\n    \n  .. grid-item-card:: API reference\n\n    * :ref:`c-interface-adaptors`\n    * :ref:`environment-variables`\n    * :ref:`rocr-api`\n\n  .. grid-item-card:: Contribution\n\n    * :ref:`contributing-to-rocr`\n\nTo contribute to the documentation, refer to\n`Contributing to ROCm  <https://rocm.docs.amd.com/en/latest/contribute/contributing.html>`_.\n\nYou can find licensing information on the `Licensing <https://rocm.docs.amd.com/en/latest/about/license.html>`_ page.\n"
  },
  {
    "path": "runtime/docs/install/installation.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _installation:\n\n====================\nInstallation\n====================\n\nThis document provides information required to build and install ROCR using prebuilt binaries or from source.\n\nBuild and install using prebuilt binaries\n-------------------------------------------\n\nHere is how you can install ROCR using prebuilt binaries.\n\nPrerequisites\n*******************\n\n- A system supporting ROCm. See the `supported operating systems <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-operating-systems>`_.\n\n- Install ROCm. See `how to install ROCm <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/>`_.\n\n- Install ``libdrm`` package.\n\n.. code-block:: shell\n    \n    sudo apt install libdrm-dev\n\nThe ROCR prebuilt binaries include:\n\n**Core runtime package:**\n\n- HSA include files to support application development on the HSA runtime for the ROCR runtime\n\n- A 64-bit version of AMD’s HSA core runtime for the ROCR runtime\n\n**Runtime extension package:**\n\n- A 64-bit version of AMD’s runtime tools library\n\n- A 64-bit version of AMD’s runtime image library\n\nThe contents of these packages are installed in ``/opt/rocm/hsa`` and ``/opt/rocm`` by default. The core runtime package depends on the ``hsakmt-roct-dev`` package.\n\nBuild and install from source\n--------------------------------\n\nHere is how you can build ROCR from source.\n\nPrerequisites\n***************\n\n- CMake 3.7 or later. Export CMake bin into your PATH.\n\n- Support packages ``libelf-dev`` and ``g++``.\n\n.. code-block:: shell\n\n    sudo apt install libelf-dev g++\n\n- A compatible version of the ``libhsakmt`` library and the ``hsakmt.h`` header file. Obtain the latest version of these files from the `ROCT-Thunk-Interface repository <https://github.com/ROCm/ROCT-Thunk-Interface>`_.\n\n- Install ``xxd``.\n\n.. code-block:: shell\n\n    sudo apt install xxd\n    \nBuilding the runtime\n----------------------\n\nThe ``libhsakmt`` development packages include a CMake package config file. The runtime locates ``libhsakmt`` via ``find_package`` if ``libhsakmt`` is installed in a standard location. For installations that don't use standard ROCm paths, set CMake variables ``CMAKE_PREFIX_PATH`` or ``hsakmt_DIR`` to override ``find_package`` search paths.\nThe runtime includes an optional image support module (previously ``hsa-ext-rocr-dev``). By default this module is included in the runtime builds. To exclude the image module from the runtime, set the CMake variable ``IMAGE_SUPPORT`` to OFF.\nTo build the optional image module, install AMDGCN-compatible clang and device library. You can find the latest version of these additional build dependencies in the `ROCm package repository <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/native-install/package-manager-integration.html#packages-in-rocm-programming-models>`_.\nThe latest source for these projects are available in the `llvm project <https://github.com/ROCm/llvm-project>`_ and `ROCm device libs <https://github.com/ROCm/ROCm-Device-Libs>`_ repositories.\n\nThe runtime optionally supports use of the CMake user package registry. By default the registry is not modified. Set CMake variable ``EXPORT_TO_USER_PACKAGE_REGISTRY`` to ON to enable updating the package registry.\n\nTo build, install, and produce packages on a system with standard ROCm packages installed, clone your copy of ROCR and run the following from ``src/``:\n\n.. code-block:: shell\n\n    mkdir build\n    cd build\n    cmake -DCMAKE_INSTALL_PREFIX=/opt/rocm ..\n    make\n    make install\n    make package\n\nExample with a custom installation path, build dependency path, and options:\n\n.. code-block:: shell\n\n    cmake -DIMAGE_SUPPORT=OFF \\\n          -DEXPORT_TO_USER_PACKAGE_REGISTRY=ON \\\n          -DCMAKE_VERBOSE_MAKEFILE=1 \\\n          -DCMAKE_PREFIX_PATH=<alternate path(s) to build dependencies> \\\n          -DCMAKE_INSTALL_PATH=<custom install path for this build> \\\n          ..\n\nAlternatively, use ``ccmake`` and ``cmake-gui``:\n\n.. code-block:: shell\n\n    mkdir build\n    cd build\n    ccmake ..\n    press c to configure\n    populate variables as desired\n    press c again\n    press g to generate and exit\n    make\n\nBuilding against the runtime\n---------------------------------\n\nThe runtime provides a CMake package config file, installed by default to ``/opt/rocm/lib/cmake/hsa-runtime64``. The runtime exports CMake target ``hsa-runtime64`` in namespace ``hsa-runtime64``. A CMake project (``Foo``) using the runtime may locate, include, and link the runtime using the following template:\n\n.. code-block:: shell\n\n    # Add /opt/rocm to CMAKE_PREFIX_PATH.\n\n    find_package(hsa-runtime64 1.0 REQUIRED)\n    ...\n    add_library(Foo ...)\n    ...\n    target_link_libraries(Foo PRIVATE hsa-runtime64::hsa-runtime64)\n"
  },
  {
    "path": "runtime/docs/license.rst",
    "content": "License\n=======\n\n.. include:: ../../LICENSE.txt\n"
  },
  {
    "path": "runtime/docs/sphinx/_toc.yml.in",
    "content": "# Anywhere {branch} is used, the branch name will be substituted.\n# These comments will also be removed.\nroot: index\nsubtrees:\n  - caption: Install\n    entries:\n    - file: install/installation\n\n  - caption: API reference\n    entries:\n    - file: api-reference/c-interface-adaptors\n    - file: api-reference/environment_variables\n    - file: api-reference/api\n    \n  - caption: Contribution\n    entries:\n    - file: contribution/contributing-to-rocr\n\n  - caption: About\n    entries:\n    - file: license\n"
  },
  {
    "path": "runtime/docs/sphinx/requirements.in",
    "content": "rocm-docs-core==1.8.0\n"
  },
  {
    "path": "runtime/docs/sphinx/requirements.txt",
    "content": "#\n# This file is autogenerated by pip-compile with Python 3.10\n# by the following command:\n#\n#    pip-compile sphinx/requirements.in\n#\naccessible-pygments==0.0.5\n    # via pydata-sphinx-theme\nalabaster==1.0.0\n    # via sphinx\nbabel==2.16.0\n    # via\n    #   pydata-sphinx-theme\n    #   sphinx\nbeautifulsoup4==4.12.3\n    # via pydata-sphinx-theme\nbreathe==4.35.0\n    # via rocm-docs-core\ncertifi==2024.8.30\n    # via requests\ncffi==1.17.1\n    # via\n    #   cryptography\n    #   pynacl\ncharset-normalizer==3.3.2\n    # via requests\nclick==8.1.7\n    # via sphinx-external-toc\ncryptography==43.0.1\n    # via pyjwt\ndeprecated==1.2.14\n    # via pygithub\ndocutils==0.21.2\n    # via\n    #   breathe\n    #   myst-parser\n    #   pydata-sphinx-theme\n    #   sphinx\nfastjsonschema==2.20.0\n    # via rocm-docs-core\ngitdb==4.0.11\n    # via gitpython\ngitpython==3.1.43\n    # via rocm-docs-core\nidna==3.10\n    # via requests\nimagesize==1.4.1\n    # via sphinx\njinja2==3.1.4\n    # via\n    #   myst-parser\n    #   sphinx\nmarkdown-it-py==3.0.0\n    # via\n    #   mdit-py-plugins\n    #   myst-parser\nmarkupsafe==2.1.5\n    # via jinja2\nmdit-py-plugins==0.4.2\n    # via myst-parser\nmdurl==0.1.2\n    # via markdown-it-py\nmyst-parser==4.0.0\n    # via rocm-docs-core\npackaging==24.1\n    # via\n    #   pydata-sphinx-theme\n    #   sphinx\npycparser==2.22\n    # via cffi\npydata-sphinx-theme==0.15.4\n    # via\n    #   rocm-docs-core\n    #   sphinx-book-theme\npygithub==2.4.0\n    # via rocm-docs-core\npygments==2.18.0\n    # via\n    #   accessible-pygments\n    #   pydata-sphinx-theme\n    #   sphinx\npyjwt[crypto]==2.9.0\n    # via pygithub\npynacl==1.5.0\n    # via pygithub\npyyaml==6.0.2\n    # via\n    #   myst-parser\n    #   rocm-docs-core\n    #   sphinx-external-toc\nrequests==2.32.3\n    # via\n    #   pygithub\n    #   sphinx\nrocm-docs-core==1.8.0\n    # via -r requirements.in\nsmmap==5.0.1\n    # via gitdb\nsnowballstemmer==2.2.0\n    # via sphinx\nsoupsieve==2.6\n    # via beautifulsoup4\nsphinx==8.0.2\n    # via\n    #   breathe\n    #   myst-parser\n    #   pydata-sphinx-theme\n    #   rocm-docs-core\n    #   sphinx-book-theme\n    #   sphinx-copybutton\n    #   sphinx-design\n    #   sphinx-external-toc\n    #   sphinx-notfound-page\nsphinx-book-theme==1.1.3\n    # via rocm-docs-core\nsphinx-copybutton==0.5.2\n    # via rocm-docs-core\nsphinx-design==0.6.1\n    # via rocm-docs-core\nsphinx-external-toc==1.0.1\n    # via rocm-docs-core\nsphinx-notfound-page==1.0.4\n    # via rocm-docs-core\nsphinxcontrib-applehelp==2.0.0\n    # via sphinx\nsphinxcontrib-devhelp==2.0.0\n    # via sphinx\nsphinxcontrib-htmlhelp==2.1.0\n    # via sphinx\nsphinxcontrib-jsmath==1.0.1\n    # via sphinx\nsphinxcontrib-qthelp==2.0.0\n    # via sphinx\nsphinxcontrib-serializinghtml==2.0.0\n    # via sphinx\ntomli==2.0.1\n    # via sphinx\ntyping-extensions==4.12.2\n    # via\n    #   pydata-sphinx-theme\n    #   pygithub\nurllib3==2.2.3\n    # via\n    #   pygithub\n    #   requests\nwrapt==1.16.0\n    # via deprecated\n"
  },
  {
    "path": "runtime/docs/what-is-rocr-runtime.rst",
    "content": ".. meta::\n   :description: HSA runtime implementation\n   :keywords: ROCR, ROCm, library, tool, runtime\n\n.. _what-is-rocr-runtime:\n\nWhat is ROCR?\n========================\n\nThe ROCm runtime (ROCR) is AMD's implementation of HSA runtime, which is a thin, user-mode API that exposes the necessary interfaces to access and interact with graphics hardware driven by the AMDGPU driver set and the ROCK kernel driver. Together they enable you to directly harness the power of discrete AMD graphics devices by allowing host applications to launch compute kernels directly to the graphics hardware.\n\nThe ROCR APIs are capable of the following:\n\n- Error handling\n\n- Runtime initialization and shutdown\n\n- System and agent information\n\n- Signals and synchronization\n\n- Architected dispatch\n\n- Memory management\n\n- Fitting into a typical software architecture stack\n\nROCR provides direct access to the graphics hardware, allowing you more control over execution. An example of low-level hardware access is the support for one or more user-mode queues, which provides a low-latency kernel dispatch interface, allowing you to develop customized dispatch algorithms specific to your application.\nThe HSA Architected Queuing Language (AQL) is an open standard defined by the HSA Foundation, which specifies the packet syntax used to control supported AMD or ATI Radeon © graphics devices. The AQL language supports several packet types, including packets that can command the hardware to automatically resolve inter-packet dependencies (barrier AND and barrier OR packet), kernel dispatch packets, and agent dispatch packets.\nIn addition to user-mode queues and AQL, the HSA runtime exposes various virtual address ranges that can be accessed by one or more of the system’s graphics devices and also possibly by the host. The exposed virtual address ranges support either a fine-grained or a coarse-grained access. Updates to memory in a fine-grained region are immediately visible to all devices that can access it, but only one device can have access to a coarse-grained allocation at a time. You can change the ownership of a coarse-grained region using the HSA runtime memory APIs, but this transfer of ownership must be explicitly done by the host application.\n\nFor a complete description of the HSA Runtime APIs, AQL, and the HSA memory policy, refer to the `HSA Runtime Programmer’s Reference Manual <https://hsafoundation.com/wp-content/uploads/2021/02/HSA-Runtime-1.2.pdf>`_.\n"
  },
  {
    "path": "runtime/hsa-ext-finalize/CMakeLists.txt",
    "content": "cmake_minimum_required ( VERSION 3.5.0 )\n\n## Verbose output.\nset ( CMAKE_VERBOSE_MAKEFILE on )\n\n## Determine external build folder.\nif( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    set( BUILD_FOLDER \"lnx64a/B_rel\" )\nelse()\n    set( BUILD_FOLDER \"lnx64a/B_dbg\" )\nendif()\n\n## Check that the libhsail include and library directories are defined.\nif ( NOT DEFINED LIBHSAIL_BUILD_FOLDER )\n    set ( LIBHSAIL_BUILD_FOLDER ${BUILD_FOLDER} )\nendif()\n\n## Set ext runtime module name and project name.\nset ( FINALIZE_NAME \"hsa-ext-finalize\" )\nset ( FINALIZE_TARGET \"${FINALIZE_NAME}64\" )\nproject ( ${FINALIZE_TARGET} )\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules\" )\ninclude ( utils )\n\n## Compiler preproc definitions.\n#add_definitions ( -D__linux__ )\nadd_definitions ( -DUNIX_OS )\nadd_definitions ( -DLINUX )\nadd_definitions ( -D__AMD64__ )\nadd_definitions ( -D__x86_64__ )\nadd_definitions ( -DAMD_INTERNAL_BUILD )\nadd_definitions ( -DLITTLEENDIAN_CPU=1 )\nadd_definitions ( -D HSA_DEPRECATED= )\n\n## Get the package version. The defaults to 1.0.0.\nget_version ( \"1.0.0\" )\n\nset ( BUILD_VERSION_MAJOR ${VERSION_MAJOR} )\nset ( BUILD_VERSION_MINOR ${VERSION_MINOR} )\nset ( BUILD_VERSION_PATCH ${VERSION_PATCH} )\nset ( LIB_VERSION_STRING \"${BUILD_VERSION_MAJOR}.${BUILD_VERSION_MINOR}.${BUILD_VERSION_PATCH}\" )\nif ( DEFINED VERSION_BUILD )\n    set ( BUILD_VERSION_PATCH \"${BUILD_VERSION_PATCH}-${VERSION_BUILD}\" )\nendif ()\nset ( BUILD_VERSION_STRING \"${BUILD_VERSION_MAJOR}.${BUILD_VERSION_MINOR}.${BUILD_VERSION_PATCH}\" )\n\n## Find the hsakmt library and include files\nfind_file ( HSAKMT_INC NAMES \"hsakmt.h\" \"libhsakmt/hsakmt.h\" )\nfind_library ( HSAKMT_LIB libhsakmt.so )\nget_filename_component ( HSAKMT_LIB_PATH ${HSAKMT_LIB} DIRECTORY )\nget_filename_component ( HSAKMT_INC_PATH ${HSAKMT_INC} DIRECTORY )\ninclude_directories ( ${HSAKMT_INC_PATH} )\nlink_directories (${HSAKMT_LIB_PATH})\n\n## Find the hsa-runtime and include files\nfind_file ( HSA_INC \"hsa/hsa.h\" )\nfind_library ( HSA_LIB libhsa-runtime64.so )\nget_filename_component ( HSA_LIB_PATH ${HSA_LIB} DIRECTORY )\nget_filename_component ( HSA_INC_PATH ${HSA_INC} DIRECTORY )\ninclude_directories ( ${HSA_INC_PATH} )\nlink_directories (${HSA_LIB_PATH})\n\n## Find the external library files and set the link command\nfind_library ( HSAIL_LIB libhsail.a )\nset ( LIBHSAIL -Wl,--no-whole-archive PRIVATE ${HSAIL_LIB} )\n\nfind_library ( HSAIL_AMD_LIB libhsail-amd.a )\nset ( LIBHSAILAMD -Wl,--no-whole-archive PRIVATE ${HSAIL_AMD_LIB} )\n\nfind_library ( AMDHSAFIN_LIB amdhsafin64.a )\nset ( LIBAMDHSAFIN -Wl,--no-whole-archive ${AMDHSAFIN_LIB} )\n\nfind_library ( LIBAMDHSACODE libamdhsacode.a )\n\nfind_library ( LIBCACHING libcaching.a )\n\nfind_library ( LIBSCP3 scSP3_R1000.a )\n\nfind_library ( LIBDWARF libdwarf.a )\n\nfind_library ( LIBELF libelf.a )\n\n## External dependencies and directories\nif ( NOT DEFINED REG_INCLUDE )\n  set(REG_INCLUDE ${HSA_CLOSED_SOURCE_DIR}/drivers/inc/asic_reg)\nendif()\n\nif ( NOT EXISTS ${REG_INCLUDE}/si_id.h )\n    MESSAGE ( FATAL_ERROR \"Environment variable REG_INCLUDE is not set appropriately. REG_INCLUDE=${REG_INCLUDE}\" )\nelse ()\n    set ( REG_INCLUDE ${REG_INCLUDE} )\nendif ()\n\nif( NOT DEFINED EXT_SOURCE_DIR )\n  set ( EXT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )\nendif()\n\nif( NOT DEFINED OPEN_SOURCE_DIR )\n  set ( OPEN_SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/..\" )\nendif()\n\n## Check for _GNU_SOURCE pthread extensions\nset(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)\nCHECK_SYMBOL_EXISTS ( \"pthread_attr_setaffinity_np\" \"pthread.h\" HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\nCHECK_SYMBOL_EXISTS ( \"pthread_rwlockattr_setkind_np\" \"pthread.h\" HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\nunset(CMAKE_REQUIRED_DEFINITIONS)\nif ( HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\nendif()\nif ( HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\nendif()\n\n## ------------------------- Linux Compiler and Linker options -------------------------\nset ( CMAKE_CXX_FLAGS \"-std=c++11 \" )\n\nset ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Werror -fexceptions -fno-rtti -fvisibility=hidden -Wno-error=sign-compare -Wno-sign-compare -Wno-write-strings -Wno-deprecated-declarations -Wno-conversion-null -fno-math-errno -fno-threadsafe-statics -fmerge-all-constants -fms-extensions -Wno-error=comment -Wno-comment -Wno-error=pointer-arith -Wno-pointer-arith -fPIC\" )\n\nif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86_64\" )\n    set  ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m64  -msse -msse2\" )\nelseif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86\" )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m32\" )\nendif ()\n\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Debug )\n    set( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb\" )\nendif ()\n\nset ( DRVDEF \"${EXT_SOURCE_DIR}/make/finalize.so.def\" )\n\nset ( CMAKE_SHARED_LINKER_FLAGS \"-Wl,-Bdynamic -Wl,-z,noexecstack -Wl,--version-script=${DRVDEF}\" )\n\nset ( CMAKE_SKIP_BUILD_RPATH TRUE )\n\n## Library path(s).\ninclude_directories ( ${REG_INCLUDE} )\ninclude_directories ( ${EXT_SOURCE_DIR}/.. )\ninclude_directories ( ${EXT_SOURCE_DIR}/inc )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime/inc )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime/core/inc )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime/core/common )\ninclude_directories ( ${HSA_CLOSED_SOURCE_DIR}/drivers/hsa/compiler/ext_finalize/amdhsafin/Interface )\ninclude_directories ( ${HSA_CLOSED_SOURCE_DIR}/drivers/hsa/compiler/finalizer/HSAIL/include )\ninclude_directories ( ${HSA_CLOSED_SOURCE_DIR}/drivers/hsa/compiler/finalizer/HSAIL/hsail-tools/libHSAIL-AMD )\ninclude_directories ( ${HSA_CLOSED_SOURCE_DIR}/drivers/hsa/compiler/finalizer/HSAIL/hsail-tools/libHSAIL )\ninclude_directories ( ${HSA_CLOSED_SOURCE_DIR}/drivers/hsa/compiler/finalizer/HSAIL/hsail-tools/libHSAIL/build/${LIBHSAIL_BUILD_FOLDER} )\n\nset ( FINALIZE_SRCS ${EXT_SOURCE_DIR}/finalize/hsa_ext_finalize.cpp\n                    ${EXT_SOURCE_DIR}/finalize/program_context.cpp\n                    ${EXT_SOURCE_DIR}/finalize/finalizer_manager.cpp\n                    ${EXT_SOURCE_DIR}/runtime/amd_ext.cpp\n                    ${EXT_SOURCE_DIR}/runtime/device_info.cpp\n                    ${OPEN_SOURCE_DIR}/hsa-runtime/core/common/hsa_table_interface.cpp\n                    ${OPEN_SOURCE_DIR}/hsa-runtime/core/common/shared.cpp\n                    ${OPEN_SOURCE_DIR}/hsa-runtime/core/util/lnx/os_linux.cpp\n)\n\nadd_library ( ${FINALIZE_TARGET} SHARED ${FINALIZE_SRCS} )\n\n## Set the VERSION and SOVERSION values\nset_property ( TARGET ${FINALIZE_TARGET} PROPERTY VERSION \"${LIB_VERSION_STRING}\" )\nset_property ( TARGET ${FINALIZE_TARGET} PROPERTY SOVERSION \"${BUILD_VERSION_MAJOR}\" )\n\n## Add the core runtime in the link\ntarget_link_libraries (\n    ${FINALIZE_TARGET}\n    PRIVATE ${LIBAMDHSAFIN}\n    PRIVATE ${LIBAMDHSACODE}\n    PRIVATE ${LIBCACHING}\n    PRIVATE ${LIBSCP3}\n    PRIVATE ${LIBHSAILAMD}\n    PRIVATE ${LIBHSAIL}\n    PRIVATE ${LIBDWARF}\n    PRIVATE ${LIBELF}\n    PRIVATE hsa-runtime64\n    PRIVATE hsakmt\n    c stdc++ dl pthread rt\n)\n\n## If the build is Release, strip the target library\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    add_custom_command ( TARGET ${FINALIZE_TARGET} POST_BUILD COMMAND ${CMAKE_STRIP} *.so )\nendif ()\n\n## Set install information\ninstall ( TARGETS ${FINALIZE_TARGET} LIBRARY DESTINATION hsa/lib )\n"
  },
  {
    "path": "runtime/hsa-ext-image/CMakeLists.txt",
    "content": "cmake_minimum_required ( VERSION 3.5.0 )\n\n## Set ext runtime module name and project name.\nset ( IMAGE_NAME \"hsa-ext-image\" )\nset ( IMAGE_TARGET \"${IMAGE_NAME}64\" )\nset ( IMAGE_LIBRARY \"lib${IMAGE_TARGET}\" )\nproject ( ${IMAGE_TARGET} )\n\n# Optionally, build with ccache.\nset(ROCM_CCACHE_BUILD OFF CACHE BOOL \"Set to ON for a ccache enabled build\")\nif (ROCM_CCACHE_BUILD)\n  find_program(CCACHE_PROGRAM ccache)\n  if (CCACHE_PROGRAM)\n    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})\n  else()\n    message(WARNING \"Unable to find ccache. Falling back to real compiler\")\n  endif() # if (CCACHE_PROGRAM)\nendif() # if (ROCM_CCACHE_BUILD)\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules\" )\ninclude ( utils )\n\n## Compiler preproc definitions.\n#add_definitions ( -D__linux__ )\nadd_definitions ( -DUNIX_OS )\nadd_definitions ( -DLINUX )\nadd_definitions ( -D__AMD64__ )\nadd_definitions ( -D__x86_64__ )\nadd_definitions ( -DAMD_INTERNAL_BUILD )\nadd_definitions ( -DLITTLEENDIAN_CPU=1 )\nadd_definitions ( -D HSA_DEPRECATED= )\nadd_definitions ( -D BRAHMA_BUILD=1 )\n\n## Get the package version.\nget_version( \"1.1.9\")\nset(SO_MAJOR 1)\nset(SO_MINOR 1)\nif ( ${ROCM_PATCH_VERSION} )\n    set ( SO_PATCH ${ROCM_PATCH_VERSION})\n    set ( VERSION_PATCH ${ROCM_PATCH_VERSION})\nelse ()\n    set(SO_PATCH 9)\nendif ()\n\nset( SO_VERSION_STRING \"${SO_MAJOR}.${SO_MINOR}.${SO_PATCH}\" )\nset( PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_COMMIT_COUNT}-${VERSION_JOB}-${VERSION_HASH}\" )\n\n## Find self\nif( \"${EXT_SOURCE_DIR}\" STREQUAL \"\" )\n    get_include_path( EXT_SOURCE_FILE null NAMES \"image/hsa_ext_image.cpp\" HINTS \"${CMAKE_CURRENT_SOURCE_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}/../../ext/\" )\n    get_filename_component( EXT_SOURCE_DIR \"${EXT_SOURCE_FILE}/..\" ABSOLUTE )\n    unset( EXT_SOURCE_FILE CACHE )\nendif()\nset( EXT_SOURCE_DIR ${EXT_SOURCE_DIR} CACHE PATH \"Image lib source dir\" FORCE )\n\nget_filename_component( OPEN_SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/..\" ABSOLUTE CACHE )\nset( OPEN_SOURCE_DIR ${OPEN_SOURCE_DIR} CACHE PATH \"Open source root dir\" FORCE )\n\n## Set RUNPATH - ../../lib covers use of the legacy symlink in /hsa/lib/\nset(CMAKE_INSTALL_RPATH \"$ORIGIN;$ORIGIN/../../lib;$ORIGIN/../../lib64;$ORIGIN/../lib64\")\n\n## ------------------------- Linux Compiler and Linker options -------------------------\nset ( CMAKE_CXX_FLAGS \"-std=c++11 \" )\n\nset ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Werror -fexceptions -fno-rtti -fvisibility=hidden -Wno-error=sign-compare -Wno-sign-compare -Wno-write-strings -Wno-deprecated-declarations -Wno-conversion-null -fno-math-errno -fno-threadsafe-statics -fmerge-all-constants -fms-extensions -Wno-error=comment -Wno-comment -Wno-error=pointer-arith -Wno-pointer-arith -fPIC\" )\n\nif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86_64\" )\n    set  ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m64  -msse -msse2\" )\nelseif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86\" )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m32\" )\nendif ()\n\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Debug )\n    set( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb\" )\nendif ()\n\nset ( DRVDEF \"${EXT_SOURCE_DIR}/image/image.so.def\" )\n\nset ( CMAKE_SHARED_LINKER_FLAGS \"-Wl,-Bdynamic -Wl,-z,noexecstack -Wl,--version-script=${DRVDEF} -Wl,--enable-new-dtags\" )\n\n## Library path(s).\ninclude_directories(${REG_INCLUDE})\ninclude_directories(${EXT_SOURCE_DIR}/..)\ninclude_directories(${EXT_SOURCE_DIR}/inc)\ninclude_directories(${OPEN_SOURCE_DIR}/hsa-runtime)\ninclude_directories(${OPEN_SOURCE_DIR}/hsa-runtime/inc)\ninclude_directories(${OPEN_SOURCE_DIR}/hsa-runtime/core/inc)\nset ( IMAGE_SRCS ${EXT_SOURCE_DIR}/image/hsa_ext_image.cpp)\n\nadd_library ( ${IMAGE_TARGET} SHARED ${IMAGE_SRCS} )\n\n## Set the VERSION and SOVERSION values\nset_property ( TARGET ${IMAGE_TARGET} PROPERTY VERSION \"${SO_VERSION_STRING}\" )\nset_property ( TARGET ${IMAGE_TARGET} PROPERTY SOVERSION \"${SO_MAJOR}\" )\n\n## Add the core runtime in the link\ntarget_link_libraries (\n    ${IMAGE_TARGET}\n    c dl pthread rt\n)\n\n## If the build is Release, strip the target library\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    add_custom_command ( TARGET ${IMAGE_TARGET} POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE_NAME:${IMAGE_TARGET}> )\nendif ()\n\n## Create symlinks for legacy packaging and install\nadd_custom_target ( hsa_images_lib_link ALL WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E create_symlink ../hsa/lib/${IMAGE_LIBRARY}.so ${IMAGE_LIBRARY}-link.so )\n\n## Set install information\ninstall ( TARGETS ${IMAGE_TARGET} LIBRARY DESTINATION hsa/lib )\ninstall ( FILES ${CMAKE_CURRENT_BINARY_DIR}/${IMAGE_LIBRARY}-link.so DESTINATION lib PERMISSIONS OWNER_WRITE OWNER_READ RENAME ${IMAGE_LIBRARY}.so )\n"
  },
  {
    "path": "runtime/hsa-runtime/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.7 )\n\n## Clear target dependency data.\n## Needed to allow UI transitions between static and dynamic builds.\n## Need an update to CMake 3.12 to remove this hack. See CMake policy change CMP0073.\nunset ( hsa-runtime64_LIB_DEPENDS CACHE )\n\nset(CMAKE_VERBOSE_MAKEFILE ON)\nset(CMAKE_CXX_STANDARD 17)\n\n## Set core runtime module name and project name.\nset ( CORE_RUNTIME_NAME \"hsa-runtime64\" )\nset ( CORE_RUNTIME_TARGET \"${CORE_RUNTIME_NAME}\" )\nset ( CORE_RUNTIME_LIBRARY \"lib${CORE_RUNTIME_TARGET}\" )\n\n## Set project name\nproject( ${CORE_RUNTIME_TARGET} )\n\n## Utilty functions\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules\" )\ninclude ( utils )\ninclude ( hsa_common )\ninclude ( GNUInstallDirs )\n\n## Adjust target name for static builds\n## Original name will be an interface target that adds --whole-archive linker options around the target.\nif( NOT ${BUILD_SHARED_LIBS} )\n  set ( CORE_RUNTIME_TARGET \"${CORE_RUNTIME_TARGET}_static\" )\nendif()\n\n# Optionally, build HSA Runtime with ccache.\nset(ROCM_CCACHE_BUILD OFF CACHE BOOL \"Set to ON for a ccache enabled build\")\nif (ROCM_CCACHE_BUILD)\n  find_program(CCACHE_PROGRAM ccache)\n  if (CCACHE_PROGRAM)\n    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})\n  else()\n    message(WARNING \"Unable to find ccache. Falling back to real compiler\")\n  endif() # if (CCACHE_PROGRAM)\nendif() # if (ROCM_CCACHE_BUILD)\n\n## Find external dependencies.\nfind_package(PkgConfig)\nfind_package(LibElf REQUIRED)\n\npkg_check_modules(drm REQUIRED IMPORTED_TARGET libdrm)\n\n## Create the rocr target.\nadd_library( ${CORE_RUNTIME_TARGET} \"\" )\n\n## Enforce uniform output file naming.\nset_property(TARGET  ${CORE_RUNTIME_TARGET} PROPERTY OUTPUT_NAME ${CORE_RUNTIME_NAME} )\n\n## Compiler preproc definitions.\ntarget_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE \"${HSA_COMMON_DEFS}\" __linux__ HSA_EXPORT=1 HSA_EXPORT_FINALIZER=1 HSA_EXPORT_IMAGES=1 HSA_DEPRECATED=\nROCR_BUILD_ID=\"${PACKAGE_VERSION_STRING}-${VERSION_JOB}-${VERSION_HASH}\" )\n\n## Check for memfd_create syscall\ninclude(CheckSymbolExists)\nCHECK_SYMBOL_EXISTS ( \"__NR_memfd_create\" \"sys/syscall.h\" HAVE_MEMFD_CREATE )\nif ( HAVE_MEMFD_CREATE )\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HAVE_MEMFD_CREATE )\nendif()\n\n## Check for _GNU_SOURCE pthread extensions\nset(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)\nCHECK_SYMBOL_EXISTS ( \"pthread_attr_setaffinity_np\" \"pthread.h\" HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\nCHECK_SYMBOL_EXISTS ( \"pthread_rwlockattr_setkind_np\" \"pthread.h\" HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\nunset(CMAKE_REQUIRED_DEFINITIONS)\nif ( HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HAVE_PTHREAD_ATTR_SETAFFINITY_NP )\nendif()\nif ( HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP )\nendif()\n\n## Set include directories for ROCr runtime\ntarget_include_directories( ${CORE_RUNTIME_TARGET}\n  PUBLIC\n  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>\n  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n  PRIVATE\n  ${CMAKE_CURRENT_SOURCE_DIR}\n  ${CMAKE_CURRENT_SOURCE_DIR}/libamdhsacode\n  ${CMAKE_CURRENT_BINARY_DIR}/core/runtime/trap_handler\n  ${CMAKE_CURRENT_BINARY_DIR}/core/runtime/blit_shaders)\n\n\n## ------------------------- Linux Compiler and Linker options -------------------------\nset ( HSA_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} -fexceptions -fno-rtti -fvisibility=hidden -Wno-error=missing-braces -Wno-error=sign-compare -Wno-sign-compare -Wno-write-strings -Wno-conversion-null -fno-math-errno -fno-threadsafe-statics -fmerge-all-constants -fms-extensions -Wno-error=comment -Wno-comment -Wno-error=pointer-arith -Wno-pointer-arith -Wno-error=unused-variable -Wno-error=unused-function )\n\n## Extra x86 specific settings\nif ( CMAKE_SYSTEM_PROCESSOR MATCHES \"i?86|x86_64|amd64|AMD64\" )\n  set ( HSA_CXX_FLAGS ${HSA_CXX_FLAGS} -mmwaitx )\nendif()\n\n## Extra image settings - audit!\nset ( HSA_CXX_FLAGS ${HSA_CXX_FLAGS} -Wno-deprecated-declarations )\n\nif ( CMAKE_COMPILER_IS_GNUCXX )\n    set ( HSA_CXX_FLAGS ${HSA_CXX_FLAGS} -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable)\nendif ()\nif ( CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n  set ( HSA_CXX_FLAGS ${HSA_CXX_FLAGS} -Wno-error=self-assign)\n  if( ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL 13)\n    set ( HSA_CXX_FLAGS ${HSA_CXX_FLAGS} -Wno-error=unused-but-set-variable)\n  endif()\nendif()\n\nset ( DRVDEF \"${CMAKE_CURRENT_SOURCE_DIR}/hsacore.so.def\" )\nset ( LNKSCR \"hsacore.so.link\" )\nset ( HSA_SHARED_LINK_FLAGS \"-Wl,-Bdynamic -Wl,-z,noexecstack -Wl,${CMAKE_CURRENT_SOURCE_DIR}/${LNKSCR} -Wl,--version-script=${DRVDEF} -Wl,--enable-new-dtags\" )\n\ntarget_compile_options(${CORE_RUNTIME_TARGET} PRIVATE ${HSA_CXX_FLAGS})\n#target_link_options not available prior to CMake 3.13\nset_property(TARGET ${CORE_RUNTIME_TARGET} PROPERTY LINK_FLAGS ${HSA_SHARED_LINK_FLAGS})\n##  -------------------------  End Compiler and Linker options ----------------------------\n\n## Source files.\nset ( SRCS core/driver/driver.cpp\n           core/driver/kfd/amd_kfd_driver.cpp\n           core/driver/xdna/amd_xdna_driver.cpp\n           core/util/lnx/os_linux.cpp\n           core/util/small_heap.cpp\n           core/util/timer.cpp\n           core/util/flag.cpp\n           core/runtime/amd_aie_agent.cpp\n           core/runtime/amd_aie_aql_queue.cpp\n           core/runtime/amd_blit_kernel.cpp\n           core/runtime/amd_blit_sdma.cpp\n           core/runtime/amd_cpu_agent.cpp\n           core/runtime/amd_gpu_agent.cpp\n           core/runtime/amd_hsa_loader.cpp\n           core/runtime/amd_aql_queue.cpp\n           core/runtime/amd_loader_context.cpp\n           core/runtime/hsa_ven_amd_loader.cpp\n           core/runtime/amd_memory_region.cpp\n           core/runtime/amd_filter_device.cpp\n           core/runtime/amd_topology.cpp\n           core/runtime/default_signal.cpp\n           core/runtime/host_queue.cpp\n           core/runtime/hsa.cpp\n           core/runtime/hsa_api_trace.cpp\n           core/runtime/hsa_ext_amd.cpp\n           core/runtime/hsa_ext_interface.cpp\n           core/runtime/interrupt_signal.cpp\n           core/runtime/intercept_queue.cpp\n           core/runtime/ipc_signal.cpp\n           core/runtime/isa.cpp\n           core/runtime/runtime.cpp\n           core/runtime/signal.cpp\n           core/runtime/queue.cpp\n           core/runtime/cache.cpp\n           core/runtime/svm_profiler.cpp\n           core/runtime/thunk_loader.cpp\n           core/common/hsa_table_interface.cpp\n           loader/executable.cpp\n           libamdhsacode/amd_elf_image.cpp\n           libamdhsacode/amd_hsa_code_util.cpp\n           libamdhsacode/amd_hsa_locks.cpp\n           libamdhsacode/amd_options.cpp\n           libamdhsacode/amd_hsa_code.cpp\n           libamdhsacode/amd_core_dump.cpp )\n\nif ( BUILD_THUNK_VIRTIO )\n  list(APPEND SRCS core/driver/virtio/amd_kfd_virtio_driver.cpp)\n  target_compile_definitions(hsa-runtime64 PRIVATE HSAKMT_VIRTIO_ENABLED=1)\nendif()\n\ntarget_sources( ${CORE_RUNTIME_TARGET} PRIVATE ${SRCS} )\n\n## Depend on trap handler target.\nadd_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/core/runtime/trap_handler )\nadd_dependencies( ${CORE_RUNTIME_TARGET} amd_trap_handler_v2 )\n\n## Depend on blit shader target.\nadd_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/core/runtime/blit_shaders )\nadd_dependencies( ${CORE_RUNTIME_TARGET} amd_blit_shaders_v2)\n\noption(PC_SAMPLING_SUPPORT \"Enable PC Sampling Support\" ON)\n\nif (${PC_SAMPLING_SUPPORT})\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HSA_PC_SAMPLING_SUPPORT)\n\n  set( PCS_SRCS pcs/hsa_ven_amd_pc_sampling.cpp pcs/pcs_runtime.cpp )\n\n  target_sources( ${CORE_RUNTIME_TARGET} PRIVATE ${PCS_SRCS} )\nendif()\n\nif ( NOT DEFINED IMAGE_SUPPORT AND CMAKE_SYSTEM_PROCESSOR MATCHES \"i?86|x86_64|amd64|AMD64|loongarch64\" )\n  set ( IMAGE_SUPPORT ON )\nendif()\nset ( IMAGE_SUPPORT ${IMAGE_SUPPORT} CACHE BOOL \"Build with image support (default: ON for x86, OFF elsewise).\" )\n\n## Optional image module defintions.\nif(${IMAGE_SUPPORT})\n  ## Image definitons - audit!\n  target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE\n    HSA_IMAGE_SUPPORT\n    UNIX_OS\n    LINUX\n    AMD_INTERNAL_BUILD\n    BRAHMA_BUILD=1 )\n\n  set ( IMAGE_SRCS image/addrlib/src/addrinterface.cpp\n                   image/addrlib/src/core/coord.cpp\n                   image/addrlib/src/core/addrlib.cpp\n                   image/addrlib/src/core/addrlib1.cpp\n                   image/addrlib/src/core/addrlib2.cpp\n                   image/addrlib/src/core/addrlib3.cpp\n                   image/addrlib/src/core/addrobject.cpp\n                   image/addrlib/src/core/addrelemlib.cpp\n                   image/addrlib/src/gfx9/gfx9addrlib.cpp\n                   image/addrlib/src/gfx10/gfx10addrlib.cpp\n                   image/addrlib/src/gfx11/gfx11addrlib.cpp\n                   image/addrlib/src/gfx12/gfx12addrlib.cpp\n                   image/device_info.cpp\n                   image/hsa_ext_image.cpp\n                   image/image_runtime.cpp\n                   image/image_manager.cpp\n                   image/image_manager_kv.cpp\n                   image/image_manager_ai.cpp\n                   image/image_manager_nv.cpp\n                   image/image_manager_gfx11.cpp\n                   image/image_manager_gfx12.cpp\n                   image/image_lut_kv.cpp\n                   image/image_lut_gfx11.cpp\n                   image/blit_object_gfx7xx.cpp\n                   image/blit_object_gfx8xx.cpp\n                   image/blit_object_gfx9xx.cpp\n                   image/blit_kernel.cpp\n                   ${CMAKE_CURRENT_BINARY_DIR}/image/blit_src/opencl_blit_objects.cpp )\n\n  set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/image/blit_src/opencl_blit_objects.cpp PROPERTIES GENERATED TRUE)\n\n  target_include_directories( ${CORE_RUNTIME_TARGET}\n    PRIVATE\n    ${CMAKE_CURRENT_SOURCE_DIR}/image\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/inc\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/core\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/r800\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/gfx9\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/gfx10\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/gfx11\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/gfx12\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/chip/r800\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/chip/gfx9\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/chip/gfx10\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/chip/gfx11\n    ${CMAKE_CURRENT_SOURCE_DIR}/image/addrlib/src/chip/gfx12 )\n\n  target_sources( ${CORE_RUNTIME_TARGET} PRIVATE ${IMAGE_SRCS} )\n\n  ## Depend on blit kernel target.\n  add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/image/blit_src )\n  add_dependencies( ${CORE_RUNTIME_TARGET} opencl_blit_objects )\n\nendif()\n\ntarget_link_libraries ( ${CORE_RUNTIME_TARGET} PRIVATE elf::elf dl pthread rt )\n# For static package rocprofiler-register dependency is not required\n# Link to hsakmt target for shared library builds\n# Link to hsakmt-staticdrm target for static library builds\nif( BUILD_SHARED_LIBS )\n  target_link_libraries ( ${CORE_RUNTIME_TARGET} PRIVATE hsakmt::hsakmt PkgConfig::drm)\n  if( BUILD_THUNK_VIRTIO )\n    message(STATUS \"Building with virtio support\")\n    target_link_libraries ( ${CORE_RUNTIME_TARGET} PRIVATE hsakmt_virtio)\n  endif()\n  find_package(rocprofiler-register)\n  if(rocprofiler-register_FOUND)\n    target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HSA_ROCPROFILER_REGISTER=1\n                                                              HSA_VERSION_MAJOR=${VERSION_MAJOR}\n                                                              HSA_VERSION_MINOR=${VERSION_MINOR}\n                                                              HSA_VERSION_PATCH=${VERSION_PATCH})\n    target_link_libraries(${CORE_RUNTIME_TARGET} PRIVATE rocprofiler-register::rocprofiler-register)\n    set(HSA_DEP_ROCPROFILER_REGISTER ON CACHE INTERNAL \"\")\n  else()\n    set(HSA_DEP_ROCPROFILER_REGISTER OFF CACHE INTERNAL \"\")\n  endif() # end rocprofiler-register_FOUND\nelse()\n  include_directories(${drm_INCLUDE_DIRS})\n  target_link_libraries ( ${CORE_RUNTIME_TARGET} PRIVATE hsakmt-staticdrm::hsakmt-staticdrm)\nendif()#end BUILD_SHARED_LIBS\n\n## Set the VERSION and SOVERSION values\nset_property ( TARGET ${CORE_RUNTIME_TARGET} PROPERTY VERSION \"${SO_VERSION_STRING}\" )\nset_property ( TARGET ${CORE_RUNTIME_TARGET} PROPERTY SOVERSION \"${VERSION_MAJOR}\" )\n\n## Add the public interface export target if doing a static build.\n## Bind ROCr dependencies to the interface target rather than to the source build\n## target so that -Wl,--whole-archive is tightly applied.  Requires binding\n## indirectly to the source build taret.\nif( NOT ${BUILD_SHARED_LIBS} )\n  add_library(${CORE_RUNTIME_NAME} INTERFACE)\n\n  ## Bind to source build target interface but not its link requirements.\n  target_include_directories( ${CORE_RUNTIME_NAME} INTERFACE $<TARGET_PROPERTY:${CORE_RUNTIME_NAME}::${CORE_RUNTIME_TARGET},INTERFACE_INCLUDE_DIRECTORIES> )\n  target_link_libraries ( ${CORE_RUNTIME_NAME} INTERFACE -Wl,$<INSTALL_PREFIX>/${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME}/${LNKSCR}\n    -Wl,--whole-archive $<TARGET_FILE:${CORE_RUNTIME_NAME}::${CORE_RUNTIME_TARGET}> -Wl,--no-whole-archive)\n  add_dependencies( ${CORE_RUNTIME_NAME} ${CORE_RUNTIME_TARGET} )\n\n  ## Add external link requirements.\n  target_link_libraries ( ${CORE_RUNTIME_NAME} INTERFACE hsakmt-staticdrm::hsakmt-staticdrm )\n  target_link_libraries ( ${CORE_RUNTIME_NAME} INTERFACE elf::elf dl pthread rt )\n\n  install ( TARGETS ${CORE_RUNTIME_NAME} EXPORT ${CORE_RUNTIME_NAME}Targets )\nendif()\n\n## Set install information\n# Installs binaries and exports the library usage data to ${HSAKMT_TARGET}Targets\ninstall ( TARGETS ${CORE_RUNTIME_TARGET} EXPORT ${CORE_RUNTIME_NAME}Targets\n  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary\n  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT binary )\ninstall ( TARGETS ${CORE_RUNTIME_TARGET}\n  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT asan )\n\n# Install license\nif(ENABLE_ASAN_PACKAGING)\n   install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR}-asan COMPONENT asan )\nendif()\ninstall ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT binary )\n\n# Install public headers\ninstall ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/inc/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hsa COMPONENT dev )\n\n## Configure and install package config file\n# Record our usage data for clients find_package calls.\ninstall ( EXPORT ${CORE_RUNTIME_NAME}Targets\n  FILE ${CORE_RUNTIME_NAME}Targets.cmake\n  NAMESPACE ${CORE_RUNTIME_NAME}::\n  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME}\n  COMPONENT dev)\n\n# Adds the target alias hsa-runtime64::hsa-runtime64 to the local cmake cache.\n# This isn't necessary today.  It's harmless preparation for some\n# hypothetical future in which the we might be included by add_subdirectory()\n# in some other project's cmake file.  It allows uniform use of find_package\n# and target_link_library() without regard to whether a target is external or\n# a subdirectory of the current build.\nadd_library( ${CORE_RUNTIME_NAME}::${CORE_RUNTIME_NAME} ALIAS ${CORE_RUNTIME_NAME} )\n\n# Create cmake configuration files\ninclude(CMakePackageConfigHelpers)\n\nconfigure_package_config_file(${CORE_RUNTIME_NAME}-config.cmake.in\n  ${CORE_RUNTIME_NAME}-config.cmake\n  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME} )\n\nwrite_basic_package_version_file(${CORE_RUNTIME_NAME}-config-version.cmake\n  VERSION ${SO_VERSION_STRING} COMPATIBILITY AnyNewerVersion )\n\ninstall(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CORE_RUNTIME_NAME}-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${CORE_RUNTIME_NAME}-config-version.cmake\n  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME}\n  COMPONENT dev)\n\n# Install build files needed only when using a static build.\nif( NOT ${BUILD_SHARED_LIBS} )\n  # libelf find package module\n  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/FindLibElf.cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/COPYING-CMAKE-SCRIPTS\n    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME}\n    COMPONENT dev)\n  # Linker script (defines function aliases)\n  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LNKSCR}\n    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CORE_RUNTIME_NAME}\n    COMPONENT dev)\nendif()\n"
  },
  {
    "path": "runtime/hsa-runtime/LICENSE.md",
    "content": "ROCR-Runtime LICENSE\n\nThe University of Illinois/NCSA\nOpen Source License (NCSA)\n\nCopyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n\nDeveloped by:\n\n                AMD Research and AMD HSA Software Development\n\n                Advanced Micro Devices, Inc.\n\n                www.amd.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal with the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\n - Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimers.\n - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimers in\n   the documentation and/or other materials provided with the distribution.\n - Neither the names of Advanced Micro Devices, Inc,\n   nor the names of its contributors may be used to endorse or promote\n   products derived from this Software without specific prior written\n   permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS WITH THE SOFTWARE.\n"
  },
  {
    "path": "runtime/hsa-runtime/cmake_modules/COPYING-CMAKE-SCRIPTS",
    "content": "Redistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n3. The name of the author may not be used to endorse or promote products \n   derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\nNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "runtime/hsa-runtime/cmake_modules/FindLibElf.cmake",
    "content": "# - Try to find libelf\n# Once done this will define\n#\n#  LIBELF_FOUND - system has libelf\n#  LIBELF_INCLUDE_DIRS - the libelf include directory\n#  LIBELF_LIBRARIES - Link these to use libelf\n#  LIBELF_DEFINITIONS - Compiler switches required for using libelf\n#\n#  Copyright (c) 2008 Bernhard Walle <bernhard.walle@gmx.de>\n#\n#  Redistribution and use is allowed according to the terms of the New\n#  BSD license.\n#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n#\n\nif (LIBELF_FOUND)\n  return()\nendif (LIBELF_FOUND)\n\nfind_path (LIBELF_INCLUDE_DIRS\n  NAMES\n    libelf.h\n  PATHS\n    /usr/include\n    /usr/include/libelf\n    /usr/local/include\n    /usr/local/include/libelf\n    /opt/local/include\n    /opt/local/include/libelf\n    ENV CPATH)\n\nfind_library (LIBELF_LIBRARIES\n  NAMES\n    elf\n  PATHS\n    /usr/lib\n    /usr/lib64\n    /usr/local/lib\n    /usr/local/lib64\n    /opt/local/lib\n    /opt/local/lib64\n    ENV LIBRARY_PATH\n    ENV LD_LIBRARY_PATH)\n\ninclude (FindPackageHandleStandardArgs)\n\n\n# handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE\nFIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG\n  LIBELF_LIBRARIES\n  LIBELF_INCLUDE_DIRS)\n\nSET(CMAKE_REQUIRED_LIBRARIES elf)\nif (CMAKE_CXX_COMPILER_LOADED)\n  INCLUDE(CheckCXXSourceCompiles)\n  CHECK_CXX_SOURCE_COMPILES(\"#include <libelf.h>\n  int main() {\n    Elf *e = (Elf*)0;\n    size_t sz;\n    elf_getshdrstrndx(e, &sz);\n    return 0;\n  }\" ELF_GETSHDRSTRNDX)\nelse()\nset ( ELF_GETSHDRSTRNDX \"TRUE\" )\nendif(CMAKE_CXX_COMPILER_LOADED)\n\nmark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX)\n\nif(LIBELF_FOUND)\n  add_library(elf::elf UNKNOWN IMPORTED)\n  set_property(TARGET elf::elf PROPERTY IMPORTED_LOCATION ${LIBELF_LIBRARIES})\n  set_property(TARGET elf::elf PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIBELF_INCLUDE_DIRS})\nendif()\n"
  },
  {
    "path": "runtime/hsa-runtime/cmake_modules/hsa_common.cmake",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n#\n# HSA Build compiler definitions common between components.\n#\n\nset(IS64BIT 0)\nset(ONLY64STR \"32\")\nif(CMAKE_SIZEOF_VOID_P EQUAL 8)\n  set(IS64BIT 1)\n  set(ONLY64STR \"64\")\nendif()\n\nset(HSA_COMMON_CXX_FLAGS \"-Wall\")\nset(HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-fPIC\")\nif (CMAKE_COMPILER_IS_GNUCXX)\n  set(HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-Wl,--unresolved-symbols=ignore-in-shared-libs\")\nendif ()\nset(HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-fno-strict-aliasing\")\nif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86_64\")\n  set( HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-m64\"  \"-msse\" \"-msse2\")\nelseif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86\" )\n  set ( HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-m32\")\nendif ()\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Debug )\n  set ( HSA_COMMON_CXX_FLAGS ${HSA_COMMON_CXX_FLAGS} \"-O0\" \"-ggdb\")\nendif ()\nset( HSA_COMMON_DEFS \"__STDC_LIMIT_MACROS\")\nset( HSA_COMMON_DEFS ${HSA_COMMON_DEFS} \"__STDC_CONSTANT_MACROS\")\nset( HSA_COMMON_DEFS ${HSA_COMMON_DEFS} \"__STDC_FORMAT_MACROS\")\nset( HSA_COMMON_DEFS ${HSA_COMMON_DEFS} \"LITTLEENDIAN_CPU=1\")\n"
  },
  {
    "path": "runtime/hsa-runtime/cmake_modules/utils.cmake",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nfunction( get_path LIB CACHED_PATH HELP )\n\n    set( options \"\")\n    set( oneValueArgs RESULT )\n    set( multiValueArgs HINTS NAMES )\n    cmake_parse_arguments(ARGS \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN} )\n\n    # Search for canary file.\n    if( ${LIB} )\n        find_library( FULLPATH NAMES ${ARGS_NAMES} HINTS ${${CACHED_PATH}} ${ARGS_HINTS} )\n    else()\n        find_file( FULLPATH NAMES ${ARGS_NAMES} HINTS ${${CACHED_PATH}} ${ARGS_HINTS} )\n    endif()\n    set( RESULT (NOT ${FULLPATH} MATCHES NOTFOUND) )\n    \n    # Extract path\n    get_filename_component ( DIRPATH ${FULLPATH} DIRECTORY )\n    \n    # Check path against cache\n    if( NOT \"${${CACHED_PATH}}\" STREQUAL \"\" )\n        if ( NOT \"${${CACHED_PATH}}\" STREQUAL \"${DIRPATH}\" )\n            message(WARNING \"${CACHED_PATH} may be incorrect.\" )\n            set( DIRPATH ${${CACHED_PATH}} )\n        endif()\n    elseif(NOT ${RESULT})\n        message(WARNING \"${CACHED_PATH} not located during path search.\")\n    endif()\n\n    # Set cache variable and help text\n    set( ${CACHED_PATH} ${DIRPATH} CACHE PATH ${HELP} FORCE )\n    unset( FULLPATH CACHE )\n\n    # Return success flag\n    if( NOT ${ARGS_RESULT} STREQUAL \"\" )\n        set( ${ARGS_RESULT} ${RESULT} PARENT_SCOPE)\n    endif()\n\nendfunction()\n\n## Searches for a file using include paths and stores the path to that file in the cache\n## using the cached value if set.  Search paths are optional.  Returns success in RESULT.\n## get_include_path(<VAR> NAMES name1 [name2...] [HINTS path1 [path2 ... ENV var]] [RESULT <var>]\nmacro( get_include_path CACHED_PATH HELP )\n    get_path( 0 ${ARGV} )\nendmacro()\n\n## Searches for a file using library paths and stores the path to that file in the cache\n## using the cached value if set.  Search paths are optional.  Returns success in RESULT.\n## get_library_path(<VAR> NAMES name1 [name2...] [HINTS path1 [path2 ... ENV var]] [RESULT <var>]\nmacro( get_library_path CACHED_PATH HELP )\n    get_path( 1 ${ARGV} )\nendmacro()\n\n## Parses the VERSION_STRING variable and places\n## the first, second and third number values in\n## the major, minor and patch variables.\nfunction( parse_version VERSION_STRING )\n\n    string ( FIND ${VERSION_STRING} \"-\" STRING_INDEX )\n\n    if ( ${STRING_INDEX} GREATER -1 )\n        math ( EXPR STRING_INDEX \"${STRING_INDEX} + 1\" )\n        string ( SUBSTRING ${VERSION_STRING} ${STRING_INDEX} -1 VERSION_BUILD )\n    endif ()\n\n    string ( REGEX MATCHALL \"[0123456789]+\" VERSIONS ${VERSION_STRING} )\n    list ( LENGTH VERSIONS VERSION_COUNT )\n\n    if ( ${VERSION_COUNT} GREATER 0)\n        list ( GET VERSIONS 0 MAJOR )\n        set ( VERSION_MAJOR ${MAJOR} PARENT_SCOPE )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 1 )\n        list ( GET VERSIONS 1 MINOR )\n        set ( VERSION_MINOR ${MINOR} PARENT_SCOPE )\n    endif ()\n\n    if ( ${VERSION_COUNT} GREATER 2 )\n        list ( GET VERSIONS 2 PATCH )\n        set ( VERSION_PATCH ${PATCH} PARENT_SCOPE )\n    endif ()\n\nendfunction ()\n\n## Gets the current version of the repository\n## using versioning tags and git describe.\n## Passes back a packaging version string\n## and a library version string.\nfunction ( get_version DEFAULT_VERSION_STRING )\n\n    set( VERSION_JOB \"local-build\" )\n    set( VERSION_COMMIT_COUNT 0 )\n    set( VERSION_HASH \"unknown\" )\n\n    find_program( GIT NAMES git )\n\n    if( GIT )\n\n        #execute_process ( COMMAND git describe --tags --dirty --long\n        #                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n        #                  OUTPUT_VARIABLE GIT_TAG_STRING\n        #                  OUTPUT_STRIP_TRAILING_WHITESPACE\n        #                  RESULT_VARIABLE RESULT )\n\n        # Get branch commit (common ancestor) of current branch and master branch.\n        execute_process(COMMAND git merge-base HEAD origin/HEAD\n                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                        OUTPUT_VARIABLE GIT_MERGE_BASE\n                        OUTPUT_STRIP_TRAILING_WHITESPACE\n                        RESULT_VARIABLE RESULT )\n\n        if( ${RESULT} EQUAL 0 )\n            # Count commits from branch point.\n            execute_process(COMMAND git rev-list --count ${GIT_MERGE_BASE}..HEAD\n                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                            OUTPUT_VARIABLE VERSION_COMMIT_COUNT\n                            OUTPUT_STRIP_TRAILING_WHITESPACE\n                            RESULT_VARIABLE RESULT )\n            if(NOT ${RESULT} EQUAL 0 )\n                set( VERSION_COMMIT_COUNT 0 )\n            endif()\n        endif()\n\n        # Get current short hash.\n        execute_process(COMMAND git rev-parse --short HEAD\n                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                        OUTPUT_VARIABLE VERSION_HASH\n                        OUTPUT_STRIP_TRAILING_WHITESPACE\n                        RESULT_VARIABLE RESULT )\n        if( ${RESULT} EQUAL 0 )\n            # Check for dirty workspace.\n            execute_process(COMMAND git diff --quiet\n                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n                            RESULT_VARIABLE RESULT )\n            if(${RESULT} EQUAL 1)\n                set(VERSION_HASH \"${VERSION_HASH}-dirty\")\n            endif()\n        else()\n            set( VERSION_HASH \"unknown\" )\n        endif()\n    endif()\n\n    # Build automation IDs\n    if(DEFINED ENV{ROCM_BUILD_ID})\n        set( VERSION_JOB $ENV{ROCM_BUILD_ID} )\n    endif()\n\n    parse_version(${DEFAULT_VERSION_STRING})\n\n    set( VERSION_MAJOR  \"${VERSION_MAJOR}\" PARENT_SCOPE )\n    set( VERSION_MINOR  \"${VERSION_MINOR}\" PARENT_SCOPE )\n    set( VERSION_PATCH  \"${VERSION_PATCH}\" PARENT_SCOPE )\n    set( VERSION_COMMIT_COUNT \"${VERSION_COMMIT_COUNT}\" PARENT_SCOPE )\n    set( VERSION_HASH \"${VERSION_HASH}\" PARENT_SCOPE )\n    set( VERSION_JOB \"${VERSION_JOB}\" PARENT_SCOPE )\n\n    #message(\"${VERSION_MAJOR}\" )\n    #message(\"${VERSION_MINOR}\" )\n    #message(\"${VERSION_PATCH}\" )\n    #message(\"${VERSION_COMMIT_COUNT}\")\n    #message(\"${VERSION_HASH}\")\n    #message(\"${VERSION_JOB}\")\n\nendfunction()\n\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/common/hsa_table_interface.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"inc/hsa_api_trace.h\"\n#include \"core/inc/hsa_api_trace_int.h\"\n\nstatic const HsaApiTable* hsaApiTable;\nstatic const CoreApiTable* coreApiTable;\nstatic const AmdExtTable* amdExtTable;\nstatic const ToolsApiTable* toolsApiTable;\n\nvoid hsa_table_interface_init(const HsaApiTable* apiTable) {\n    hsaApiTable = apiTable;\n    coreApiTable = apiTable->core_;\n    amdExtTable = apiTable->amd_ext_;\n    toolsApiTable = apiTable->tools_;\n}\n\nconst HsaApiTable* hsa_table_interface_get_table() {\n  return hsaApiTable;\n}\n\n// Pass through stub functions\nhsa_status_t HSA_API hsa_init() {\n  // We initialize the api tables here once more since the code above is prone to a\n  // link-time ordering condition: This compilation unit here may get its global\n  // variables initialized earlier than the global objects in other compilation units.\n  // In particular Init::Init may get called earlier than that the underlying hsa_api_table_\n  // object in hsa_api_trace.cpp has been initialized.\n  rocr::core::LoadInitialHsaApiTable();\n  return coreApiTable->hsa_init_fn();\n}\n\nhsa_status_t HSA_API hsa_shut_down() { return coreApiTable->hsa_shut_down_fn(); }\n\nhsa_status_t HSA_API\n    hsa_system_get_info(hsa_system_info_t attribute, void* value) {\n  return coreApiTable->hsa_system_get_info_fn(attribute, value);\n}\n\nhsa_status_t HSA_API hsa_extension_get_name(uint16_t extension, const char** name) {\n  return coreApiTable->hsa_extension_get_name_fn(extension, name);\n}\n\nhsa_status_t HSA_API\n    hsa_system_extension_supported(uint16_t extension, uint16_t version_major,\n                                   uint16_t version_minor, bool* result) {\n  return coreApiTable->hsa_system_extension_supported_fn(\n      extension, version_major, version_minor, result);\n}\n\nhsa_status_t HSA_API hsa_system_major_extension_supported(uint16_t extension,\n                                                          uint16_t version_major,\n                                                          uint16_t* version_minor, bool* result) {\n  return coreApiTable->hsa_system_major_extension_supported_fn(extension, version_major,\n                                                               version_minor, result);\n}\n\nhsa_status_t HSA_API hsa_system_get_extension_table(uint16_t extension, uint16_t version_major,\n                                                    uint16_t version_minor, void* table) {\n  return coreApiTable->hsa_system_get_extension_table_fn(\n      extension, version_major, version_minor, table);\n}\n\nhsa_status_t HSA_API hsa_system_get_major_extension_table(uint16_t extension,\n                                                          uint16_t version_major,\n                                                          size_t table_length, void* table) {\n  return coreApiTable->hsa_system_get_major_extension_table_fn(extension, version_major,\n                                                               table_length, table);\n}\n\nhsa_status_t HSA_API\n    hsa_iterate_agents(hsa_status_t (*callback)(hsa_agent_t agent, void* data),\n                       void* data) {\n  return coreApiTable->hsa_iterate_agents_fn(callback, data);\n}\n\nhsa_status_t HSA_API hsa_agent_get_info(hsa_agent_t agent,\n                                        hsa_agent_info_t attribute,\n                                        void* value) {\n  return coreApiTable->hsa_agent_get_info_fn(agent, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_agent_get_exception_policies(hsa_agent_t agent,\n                                                      hsa_profile_t profile,\n                                                      uint16_t* mask) {\n  return coreApiTable->hsa_agent_get_exception_policies_fn(agent, profile, mask);\n}\n\nhsa_status_t HSA_API hsa_cache_get_info(hsa_cache_t cache, hsa_cache_info_t attribute,\n                                        void* value) {\n  return coreApiTable->hsa_cache_get_info_fn(cache, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_agent_iterate_caches(\n    hsa_agent_t agent, hsa_status_t (*callback)(hsa_cache_t cache, void* data), void* value) {\n  return coreApiTable->hsa_agent_iterate_caches_fn(agent, callback, value);\n}\n\nhsa_status_t HSA_API\n    hsa_agent_extension_supported(uint16_t extension, hsa_agent_t agent,\n                                  uint16_t version_major,\n                                  uint16_t version_minor, bool* result) {\n  return coreApiTable->hsa_agent_extension_supported_fn(\n      extension, agent, version_major, version_minor, result);\n}\n\nhsa_status_t HSA_API hsa_agent_major_extension_supported(uint16_t extension, hsa_agent_t agent,\n                                                         uint16_t version_major,\n                                                         uint16_t* version_minor, bool* result) {\n  return coreApiTable->hsa_agent_major_extension_supported_fn(extension, agent, version_major,\n                                                              version_minor, result);\n}\n\nhsa_status_t HSA_API\n    hsa_queue_create(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,\n                     void (*callback)(hsa_status_t status, hsa_queue_t* source,\n                                      void* data),\n                     void* data, uint32_t private_segment_size,\n                     uint32_t group_segment_size, hsa_queue_t** queue) {\n  return coreApiTable->hsa_queue_create_fn(agent, size, type, callback, data,\n                                          private_segment_size,\n                                          group_segment_size, queue);\n}\n\nhsa_status_t HSA_API\n    hsa_soft_queue_create(hsa_region_t region, uint32_t size,\n                          hsa_queue_type32_t type, uint32_t features,\n                          hsa_signal_t completion_signal, hsa_queue_t** queue) {\n  return coreApiTable->hsa_soft_queue_create_fn(region, size, type, features,\n                                               completion_signal, queue);\n}\n\nhsa_status_t HSA_API hsa_queue_destroy(hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_destroy_fn(queue);\n}\n\nhsa_status_t HSA_API hsa_queue_inactivate(hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_inactivate_fn(queue);\n}\n\nuint64_t HSA_API hsa_queue_load_read_index_scacquire(const hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_load_read_index_scacquire_fn(queue);\n}\n\nuint64_t HSA_API hsa_queue_load_read_index_relaxed(const hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_load_read_index_relaxed_fn(queue);\n}\n\nuint64_t HSA_API hsa_queue_load_write_index_scacquire(const hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_load_write_index_scacquire_fn(queue);\n}\n\nuint64_t HSA_API hsa_queue_load_write_index_relaxed(const hsa_queue_t* queue) {\n  return coreApiTable->hsa_queue_load_write_index_relaxed_fn(queue);\n}\n\nvoid HSA_API hsa_queue_store_write_index_relaxed(const hsa_queue_t* queue,\n                                                 uint64_t value) {\n  return coreApiTable->hsa_queue_store_write_index_relaxed_fn(queue, value);\n}\n\nvoid HSA_API hsa_queue_store_write_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  return coreApiTable->hsa_queue_store_write_index_screlease_fn(queue, value);\n}\n\nuint64_t HSA_API hsa_queue_cas_write_index_scacq_screl(const hsa_queue_t* queue, uint64_t expected,\n                                                       uint64_t value) {\n  return coreApiTable->hsa_queue_cas_write_index_scacq_screl_fn(queue, expected, value);\n}\n\nuint64_t HSA_API hsa_queue_cas_write_index_scacquire(const hsa_queue_t* queue, uint64_t expected,\n                                                     uint64_t value) {\n  return coreApiTable->hsa_queue_cas_write_index_scacquire_fn(queue, expected, value);\n}\n\nuint64_t HSA_API hsa_queue_cas_write_index_relaxed(const hsa_queue_t* queue,\n                                                   uint64_t expected,\n                                                   uint64_t value) {\n  return coreApiTable->hsa_queue_cas_write_index_relaxed_fn(queue, expected,\n                                                           value);\n}\n\nuint64_t HSA_API hsa_queue_cas_write_index_screlease(const hsa_queue_t* queue, uint64_t expected,\n                                                     uint64_t value) {\n  return coreApiTable->hsa_queue_cas_write_index_screlease_fn(queue, expected, value);\n}\n\nuint64_t HSA_API hsa_queue_add_write_index_scacq_screl(const hsa_queue_t* queue, uint64_t value) {\n  return coreApiTable->hsa_queue_add_write_index_scacq_screl_fn(queue, value);\n}\n\nuint64_t HSA_API hsa_queue_add_write_index_scacquire(const hsa_queue_t* queue, uint64_t value) {\n  return coreApiTable->hsa_queue_add_write_index_scacquire_fn(queue, value);\n}\n\nuint64_t HSA_API hsa_queue_add_write_index_relaxed(const hsa_queue_t* queue,\n                                                   uint64_t value) {\n  return coreApiTable->hsa_queue_add_write_index_relaxed_fn(queue, value);\n}\n\nuint64_t HSA_API hsa_queue_add_write_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  return coreApiTable->hsa_queue_add_write_index_screlease_fn(queue, value);\n}\n\nvoid HSA_API hsa_queue_store_read_index_relaxed(const hsa_queue_t* queue,\n                                                uint64_t value) {\n  return coreApiTable->hsa_queue_store_read_index_relaxed_fn(queue, value);\n}\n\nvoid HSA_API hsa_queue_store_read_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  return coreApiTable->hsa_queue_store_read_index_screlease_fn(queue, value);\n}\n\nhsa_status_t HSA_API hsa_agent_iterate_regions(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_region_t region, void* data), void* data) {\n  return coreApiTable->hsa_agent_iterate_regions_fn(agent, callback, data);\n}\n\nhsa_status_t HSA_API hsa_region_get_info(hsa_region_t region,\n                                         hsa_region_info_t attribute,\n                                         void* value) {\n  return coreApiTable->hsa_region_get_info_fn(region, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_memory_register(void* address, size_t size) {\n  return coreApiTable->hsa_memory_register_fn(address, size);\n}\n\nhsa_status_t HSA_API hsa_memory_deregister(void* address, size_t size) {\n  return coreApiTable->hsa_memory_deregister_fn(address, size);\n}\n\nhsa_status_t HSA_API\n    hsa_memory_allocate(hsa_region_t region, size_t size, void** ptr) {\n  return coreApiTable->hsa_memory_allocate_fn(region, size, ptr);\n}\n\nhsa_status_t HSA_API hsa_memory_free(void* ptr) {\n  return coreApiTable->hsa_memory_free_fn(ptr);\n}\n\nhsa_status_t HSA_API hsa_memory_copy(void* dst, const void* src, size_t size) {\n  return coreApiTable->hsa_memory_copy_fn(dst, src, size);\n}\n\nhsa_status_t HSA_API hsa_memory_assign_agent(void* ptr, hsa_agent_t agent,\n                                             hsa_access_permission_t access) {\n  return coreApiTable->hsa_memory_assign_agent_fn(ptr, agent, access);\n}\n\nhsa_status_t HSA_API\n    hsa_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                      const hsa_agent_t* consumers, hsa_signal_t* signal) {\n  return coreApiTable->hsa_signal_create_fn(initial_value, num_consumers,\n                                           consumers, signal);\n}\n\nhsa_status_t HSA_API hsa_signal_destroy(hsa_signal_t signal) {\n  return coreApiTable->hsa_signal_destroy_fn(signal);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_load_relaxed(hsa_signal_t signal) {\n  return coreApiTable->hsa_signal_load_relaxed_fn(signal);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_load_scacquire(hsa_signal_t signal) {\n  return coreApiTable->hsa_signal_load_scacquire_fn(signal);\n}\n\nvoid HSA_API\n    hsa_signal_store_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_store_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_store_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_store_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_silent_store_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_silent_store_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_silent_store_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_silent_store_screlease_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API\n    hsa_signal_wait_relaxed(hsa_signal_t signal,\n                            hsa_signal_condition_t condition,\n                            hsa_signal_value_t compare_value,\n                            uint64_t timeout_hint,\n                            hsa_wait_state_t wait_expectancy_hint) {\n  return coreApiTable->hsa_signal_wait_relaxed_fn(\n      signal, condition, compare_value, timeout_hint, wait_expectancy_hint);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_wait_scacquire(hsa_signal_t signal,\n                                                     hsa_signal_condition_t condition,\n                                                     hsa_signal_value_t compare_value,\n                                                     uint64_t timeout_hint,\n                                                     hsa_wait_state_t wait_expectancy_hint) {\n  return coreApiTable->hsa_signal_wait_scacquire_fn(signal, condition, compare_value, timeout_hint,\n                                                    wait_expectancy_hint);\n}\n\nhsa_status_t HSA_API hsa_signal_group_create(uint32_t num_signals, const hsa_signal_t* signals,\n                                             uint32_t num_consumers, const hsa_agent_t* consumers,\n                                             hsa_signal_group_t* signal_group) {\n  return coreApiTable->hsa_signal_group_create_fn(num_signals, signals, num_consumers, consumers,\n                                                  signal_group);\n}\n\nhsa_status_t HSA_API hsa_signal_group_destroy(hsa_signal_group_t signal_group) {\n  return coreApiTable->hsa_signal_group_destroy_fn(signal_group);\n}\n\nhsa_status_t HSA_API hsa_signal_group_wait_any_relaxed(hsa_signal_group_t signal_group,\n                                                       const hsa_signal_condition_t* conditions,\n                                                       const hsa_signal_value_t* compare_values,\n                                                       hsa_wait_state_t wait_state_hint,\n                                                       hsa_signal_t* signal,\n                                                       hsa_signal_value_t* value) {\n  return coreApiTable->hsa_signal_group_wait_any_relaxed_fn(\n      signal_group, conditions, compare_values, wait_state_hint, signal, value);\n}\n\nhsa_status_t HSA_API hsa_signal_group_wait_any_scacquire(hsa_signal_group_t signal_group,\n                                                         const hsa_signal_condition_t* conditions,\n                                                         const hsa_signal_value_t* compare_values,\n                                                         hsa_wait_state_t wait_state_hint,\n                                                         hsa_signal_t* signal,\n                                                         hsa_signal_value_t* value) {\n  return coreApiTable->hsa_signal_group_wait_any_scacquire_fn(\n      signal_group, conditions, compare_values, wait_state_hint, signal, value);\n}\n\nvoid HSA_API\n    hsa_signal_and_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_and_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_and_scacquire(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_and_scacquire_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_and_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_and_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_and_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_and_scacq_screl_fn(signal, value);\n}\n\nvoid HSA_API\n    hsa_signal_or_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_or_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_or_scacquire(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_or_scacquire_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_or_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_or_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_or_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_or_scacq_screl_fn(signal, value);\n}\n\nvoid HSA_API\n    hsa_signal_xor_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_xor_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_xor_scacquire(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_xor_scacquire_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_xor_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_xor_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_xor_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_xor_scacq_screl_fn(signal, value);\n}\n\nvoid HSA_API\n    hsa_signal_add_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_add_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_add_scacquire(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_add_scacquire_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_add_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_add_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_add_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_add_scacq_screl_fn(signal, value);\n}\n\nvoid HSA_API\n    hsa_signal_subtract_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_subtract_relaxed_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_subtract_scacquire(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_subtract_scacquire_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_subtract_screlease(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_subtract_screlease_fn(signal, value);\n}\n\nvoid HSA_API hsa_signal_subtract_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_subtract_scacq_screl_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API\n    hsa_signal_exchange_relaxed(hsa_signal_t signal, hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_exchange_relaxed_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_exchange_scacquire(hsa_signal_t signal,\n                                                         hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_exchange_scacquire_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_exchange_screlease(hsa_signal_t signal,\n                                                         hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_exchange_screlease_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_exchange_scacq_screl(hsa_signal_t signal,\n                                                           hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_exchange_scacq_screl_fn(signal, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_cas_relaxed(hsa_signal_t signal,\n                                                  hsa_signal_value_t expected,\n                                                  hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_cas_relaxed_fn(signal, expected, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_cas_scacquire(hsa_signal_t signal,\n                                                    hsa_signal_value_t expected,\n                                                    hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_cas_scacquire_fn(signal, expected, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_cas_screlease(hsa_signal_t signal,\n                                                    hsa_signal_value_t expected,\n                                                    hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_cas_screlease_fn(signal, expected, value);\n}\n\nhsa_signal_value_t HSA_API hsa_signal_cas_scacq_screl(hsa_signal_t signal,\n                                                      hsa_signal_value_t expected,\n                                                      hsa_signal_value_t value) {\n  return coreApiTable->hsa_signal_cas_scacq_screl_fn(signal, expected, value);\n}\n\n//===--- Instruction Set Architecture -------------------------------------===//\n\nhsa_status_t HSA_API hsa_isa_from_name(\n    const char *name,\n    hsa_isa_t *isa) {\n  return coreApiTable->hsa_isa_from_name_fn(name, isa);\n}\n\nhsa_status_t HSA_API hsa_agent_iterate_isas(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_isa_t isa,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_agent_iterate_isas_fn(agent, callback, data);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_isa_get_info(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    uint32_t index,\n    void *value) {\n  return coreApiTable->hsa_isa_get_info_fn(isa, attribute, index, value);\n}\n\nhsa_status_t HSA_API hsa_isa_get_info_alt(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_isa_get_info_alt_fn(isa, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_isa_get_exception_policies(\n    hsa_isa_t isa,\n    hsa_profile_t profile,\n    uint16_t *mask) {\n  return coreApiTable->hsa_isa_get_exception_policies_fn(isa, profile, mask);\n}\n\nhsa_status_t HSA_API hsa_isa_get_round_method(\n    hsa_isa_t isa,\n    hsa_fp_type_t fp_type,\n    hsa_flush_mode_t flush_mode,\n    hsa_round_method_t *round_method) {\n  return coreApiTable->hsa_isa_get_round_method_fn(\n      isa, fp_type, flush_mode, round_method);\n}\n\nhsa_status_t HSA_API hsa_wavefront_get_info(\n    hsa_wavefront_t wavefront,\n    hsa_wavefront_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_wavefront_get_info_fn(wavefront, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_isa_iterate_wavefronts(\n    hsa_isa_t isa,\n    hsa_status_t (*callback)(hsa_wavefront_t wavefront,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_isa_iterate_wavefronts_fn(isa, callback, data);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_isa_compatible(\n    hsa_isa_t code_object_isa,\n    hsa_isa_t agent_isa,\n    bool *result) {\n  return coreApiTable->hsa_isa_compatible_fn(\n      code_object_isa, agent_isa, result);\n}\n\n//===--- Code Objects (deprecated) ----------------------------------------===//\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_serialize(\n    hsa_code_object_t code_object,\n    hsa_status_t (*alloc_callback)(size_t size,\n                                   hsa_callback_data_t data,\n                                   void **address),\n    hsa_callback_data_t callback_data,\n    const char *options,\n    void **serialized_code_object,\n    size_t *serialized_code_object_size) {\n  return coreApiTable->hsa_code_object_serialize_fn(\n      code_object, alloc_callback, callback_data, options,\n      serialized_code_object, serialized_code_object_size);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_deserialize(\n    void *serialized_code_object,\n    size_t serialized_code_object_size,\n    const char *options,\n    hsa_code_object_t *code_object) {\n  return coreApiTable->hsa_code_object_deserialize_fn(\n      serialized_code_object, serialized_code_object_size, options,\n      code_object);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_destroy(\n    hsa_code_object_t code_object) {\n  return coreApiTable->hsa_code_object_destroy_fn(code_object);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_get_info(\n    hsa_code_object_t code_object,\n    hsa_code_object_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_code_object_get_info_fn(\n      code_object, attribute, value);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_get_symbol(\n    hsa_code_object_t code_object,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol) {\n  return coreApiTable->hsa_code_object_get_symbol_fn(\n      code_object, symbol_name, symbol);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_get_symbol_from_name(\n    hsa_code_object_t code_object,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol) {\n  return coreApiTable->hsa_code_object_get_symbol_from_name_fn(\n      code_object, module_name, symbol_name, symbol);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_symbol_get_info(\n    hsa_code_symbol_t code_symbol,\n    hsa_code_symbol_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_code_symbol_get_info_fn(\n      code_symbol, attribute, value);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_code_object_iterate_symbols(\n    hsa_code_object_t code_object,\n    hsa_status_t (*callback)(hsa_code_object_t code_object,\n                             hsa_code_symbol_t symbol,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_code_object_iterate_symbols_fn(\n      code_object, callback, data);\n}\n\n//===--- Executable -------------------------------------------------------===//\n\nhsa_status_t HSA_API hsa_code_object_reader_create_from_file(\n    hsa_file_t file,\n    hsa_code_object_reader_t *code_object_reader) {\n  return coreApiTable->hsa_code_object_reader_create_from_file_fn(\n      file, code_object_reader);\n}\n\nhsa_status_t HSA_API hsa_code_object_reader_create_from_memory(\n    const void *code_object,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader) {\n  return coreApiTable->hsa_code_object_reader_create_from_memory_fn(\n      code_object, size, code_object_reader);\n}\n\nhsa_status_t HSA_API hsa_code_object_reader_destroy(\n    hsa_code_object_reader_t code_object_reader) {\n  return coreApiTable->hsa_code_object_reader_destroy_fn(code_object_reader);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_executable_create(\n    hsa_profile_t profile,\n    hsa_executable_state_t executable_state,\n    const char *options,\n    hsa_executable_t *executable) {\n  return coreApiTable->hsa_executable_create_fn(\n      profile, executable_state, options, executable);\n}\n\nhsa_status_t HSA_API hsa_executable_create_alt(\n    hsa_profile_t profile,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode,\n    const char *options,\n    hsa_executable_t *executable) {\n  return coreApiTable->hsa_executable_create_alt_fn(\n      profile, default_float_rounding_mode, options, executable);\n}\n\nhsa_status_t HSA_API hsa_executable_destroy(\n    hsa_executable_t executable) {\n  return coreApiTable->hsa_executable_destroy_fn(executable);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_executable_load_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    const char *options) {\n  return coreApiTable->hsa_executable_load_code_object_fn(\n      executable, agent, code_object, options);\n}\n\nhsa_status_t HSA_API hsa_executable_load_program_code_object(\n    hsa_executable_t executable,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object) {\n  return coreApiTable->hsa_executable_load_program_code_object_fn(\n      executable, code_object_reader, options, loaded_code_object);\n}\n\nhsa_status_t HSA_API hsa_executable_load_agent_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object) {\n  return coreApiTable->hsa_executable_load_agent_code_object_fn(\n      executable, agent, code_object_reader, options, loaded_code_object);\n}\n\nhsa_status_t HSA_API hsa_executable_freeze(\n    hsa_executable_t executable,\n    const char *options) {\n  return coreApiTable->hsa_executable_freeze_fn(executable, options);\n}\n\nhsa_status_t HSA_API hsa_executable_get_info(\n    hsa_executable_t executable,\n    hsa_executable_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_executable_get_info_fn(executable, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_executable_global_variable_define(\n    hsa_executable_t executable,\n    const char *variable_name,\n    void *address) {\n  return coreApiTable->hsa_executable_global_variable_define_fn(\n      executable, variable_name, address);\n}\n\nhsa_status_t HSA_API hsa_executable_agent_global_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address) {\n  return coreApiTable->hsa_executable_agent_global_variable_define_fn(\n      executable, agent, variable_name, address);\n}\n\nhsa_status_t HSA_API hsa_executable_readonly_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address) {\n  return coreApiTable->hsa_executable_readonly_variable_define_fn(\n      executable, agent, variable_name, address);\n}\n\nhsa_status_t HSA_API hsa_executable_validate(\n    hsa_executable_t executable,\n    uint32_t *result) {\n  return coreApiTable->hsa_executable_validate_fn(executable, result);\n}\n\nhsa_status_t HSA_API hsa_executable_validate_alt(\n    hsa_executable_t executable,\n    const char *options,\n    uint32_t *result) {\n  return coreApiTable->hsa_executable_validate_alt_fn(\n      executable, options, result);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_executable_get_symbol(\n    hsa_executable_t executable,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_agent_t agent,\n    int32_t call_convention,\n    hsa_executable_symbol_t *symbol) {\n  return coreApiTable->hsa_executable_get_symbol_fn(\n      executable, module_name, symbol_name, agent, call_convention, symbol);\n}\n\nhsa_status_t HSA_API hsa_executable_get_symbol_by_name(\n    hsa_executable_t executable,\n    const char *symbol_name,\n    const hsa_agent_t *agent,\n    hsa_executable_symbol_t *symbol) {\n  return coreApiTable->hsa_executable_get_symbol_by_name_fn(\n      executable, symbol_name, agent, symbol);\n}\n\nhsa_status_t HSA_API hsa_executable_symbol_get_info(\n    hsa_executable_symbol_t executable_symbol,\n    hsa_executable_symbol_info_t attribute,\n    void *value) {\n  return coreApiTable->hsa_executable_symbol_get_info_fn(\n      executable_symbol, attribute, value);\n}\n\n/* deprecated */ hsa_status_t HSA_API hsa_executable_iterate_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t executable,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_executable_iterate_symbols_fn(\n      executable, callback, data);\n}\n\nhsa_status_t HSA_API hsa_executable_iterate_agent_symbols(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_agent_t agent,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_executable_iterate_agent_symbols_fn(\n      executable, agent, callback, data);\n}\n\nhsa_status_t HSA_API hsa_executable_iterate_program_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  return coreApiTable->hsa_executable_iterate_program_symbols_fn(\n      executable, callback, data);\n}\n\n//===--- Runtime Notifications --------------------------------------------===//\n\nhsa_status_t HSA_API hsa_status_string(\n    hsa_status_t status,\n    const char **status_string) {\n  return coreApiTable->hsa_status_string_fn(status, status_string);\n}\n\n/*\n * Following set of functions are bundled as AMD Extension Apis\n */\n\n// Pass through stub functions\nhsa_status_t HSA_API hsa_amd_coherency_get_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t* type) {\n  return amdExtTable->hsa_amd_coherency_get_type_fn(agent, type);\n}\n\n// Pass through stub functions\nhsa_status_t HSA_API hsa_amd_coherency_set_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t type) {\n  return amdExtTable->hsa_amd_coherency_set_type_fn(agent, type);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {\n  return amdExtTable->hsa_amd_profiling_set_profiler_enabled_fn(\n                                     queue, enable);\n}\n\nhsa_status_t HSA_API\n  hsa_amd_profiling_async_copy_enable(bool enable) {\n    return amdExtTable->hsa_amd_profiling_async_copy_enable_fn(enable);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_profiling_get_dispatch_time(\n    hsa_agent_t agent, hsa_signal_t signal,\n    hsa_amd_profiling_dispatch_time_t* time) {\n  return amdExtTable->hsa_amd_profiling_get_dispatch_time_fn(\n                                     agent, signal, time);\n}\n\nhsa_status_t HSA_API\n  hsa_amd_profiling_get_async_copy_time(\n    hsa_signal_t hsa_signal, hsa_amd_profiling_async_copy_time_t* time) {\n      return amdExtTable->hsa_amd_profiling_get_async_copy_time_fn(hsa_signal, time);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent,\n                                                    uint64_t agent_tick,\n                                                    uint64_t* system_tick) {\n  return amdExtTable->hsa_amd_profiling_convert_tick_to_system_domain_fn(\n                                     agent, agent_tick, system_tick);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_signal_async_handler(hsa_signal_t signal,\n                                 hsa_signal_condition_t cond,\n                                 hsa_signal_value_t value,\n                                 hsa_amd_signal_handler handler, void* arg) {\n  return amdExtTable->hsa_amd_signal_async_handler_fn(\n                                     signal, cond, value, handler, arg);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_async_function(void (*callback)(void* arg), void* arg) {\n  return amdExtTable->hsa_amd_async_function_fn(callback, arg);\n}\n\n// Mirrors Amd Extension Apis\nuint32_t HSA_API hsa_amd_signal_wait_all(uint32_t signal_count, hsa_signal_t* signals,\n                                         hsa_signal_condition_t* conds, hsa_signal_value_t* values,\n                                         uint64_t timeout_hint, hsa_wait_state_t wait_hint,\n                                         hsa_signal_value_t* satisfying_values) {\n  return amdExtTable->hsa_amd_signal_wait_all_fn(signal_count, signals, conds, values, timeout_hint,\n                                                 wait_hint, satisfying_values);\n}\n\n// Mirrors Amd Extension Apis\nuint32_t HSA_API\n    hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* signals,\n                            hsa_signal_condition_t* conds,\n                            hsa_signal_value_t* values, uint64_t timeout_hint,\n                            hsa_wait_state_t wait_hint,\n                            hsa_signal_value_t* satisfying_value) {\n  return amdExtTable->hsa_amd_signal_wait_any_fn(\n                                     signal_count, signals,\n                                     conds, values, timeout_hint,\n                                     wait_hint, satisfying_value);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue,\n                                               uint32_t num_cu_mask_count,\n                                               const uint32_t* cu_mask) {\n  return amdExtTable->hsa_amd_queue_cu_set_mask_fn(\n                                     queue, num_cu_mask_count, cu_mask);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_queue_cu_get_mask(const hsa_queue_t* queue, uint32_t num_cu_mask_count,\n                                               uint32_t* cu_mask) {\n  return amdExtTable->hsa_amd_queue_cu_get_mask_fn(queue, num_cu_mask_count, cu_mask);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,\n                                 hsa_amd_memory_pool_info_t attribute,\n                                 void* value) {\n  return amdExtTable->hsa_amd_memory_pool_get_info_fn(\n                                     memory_pool, attribute, value);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_agent_iterate_memory_pools(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),\n    void* data) {\n  return amdExtTable->hsa_amd_agent_iterate_memory_pools_fn(\n                                     agent, callback, data);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,\n                                 uint32_t flags, void** ptr) {\n  return amdExtTable->hsa_amd_memory_pool_allocate_fn(\n                                     memory_pool, size, flags, ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_pool_free(void* ptr) {\n  return amdExtTable->hsa_amd_memory_pool_free_fn(ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal) {\n  return amdExtTable->hsa_amd_memory_async_copy_fn(\n                                     dst, dst_agent, src, src_agent, size,\n                                     num_dep_signals, dep_signals, completion_signal);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_async_copy_on_engine(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal,\n                              hsa_amd_sdma_engine_id_t engine_id,\n                              bool force_copy_on_sdma) {\n  return amdExtTable->hsa_amd_memory_async_copy_on_engine_fn(\n                                     dst, dst_agent, src, src_agent, size,\n                                     num_dep_signals, dep_signals, completion_signal,\n                                     engine_id, force_copy_on_sdma);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_copy_engine_status(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                      uint32_t *engine_ids_mask) {\n  return amdExtTable->hsa_amd_memory_copy_engine_status_fn(dst_agent, src_agent,\n                                                           engine_ids_mask);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_get_preferred_copy_engine(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                             uint32_t* recommended_ids_mask) {\n  return amdExtTable->hsa_amd_memory_get_preferred_copy_engine_fn(dst_agent, src_agent,\n                                                                  recommended_ids_mask);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_async_copy_rect(\n    const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,\n    const hsa_dim3_t* src_offset, const hsa_dim3_t* range, hsa_agent_t copy_agent,\n    hsa_amd_copy_direction_t dir, uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n    hsa_signal_t completion_signal) {\n  return amdExtTable->hsa_amd_memory_async_copy_rect_fn(dst, dst_offset, src, src_offset, range,\n                                                        copy_agent, dir, num_dep_signals,\n                                                        dep_signals, completion_signal);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_agent_memory_pool_get_info(\n    hsa_agent_t agent, hsa_amd_memory_pool_t memory_pool,\n    hsa_amd_agent_memory_pool_info_t attribute, void* value) {\n  return amdExtTable->hsa_amd_agent_memory_pool_get_info_fn(\n                                     agent, memory_pool, attribute, value);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,\n                                const uint32_t* flags, const void* ptr) {\n  return amdExtTable->hsa_amd_agents_allow_access_fn(\n                                     num_agents, agents, flags, ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,\n                                    hsa_amd_memory_pool_t dst_memory_pool,\n                                    bool* result) {\n  return amdExtTable->hsa_amd_memory_pool_can_migrate_fn(\n                                     src_memory_pool, dst_memory_pool, result);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_migrate(const void* ptr,\n                                            hsa_amd_memory_pool_t memory_pool,\n                                            uint32_t flags) {\n  return amdExtTable->hsa_amd_memory_migrate_fn(\n                                     ptr, memory_pool, flags);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_lock(void* host_ptr, size_t size,\n                                         hsa_agent_t* agents, int num_agent,\n                                         void** agent_ptr) {\n  return amdExtTable->hsa_amd_memory_lock_fn(\n                                     host_ptr, size, agents, num_agent, agent_ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_lock_to_pool(void* host_ptr, size_t size, hsa_agent_t* agents,\n                                                 int num_agent, hsa_amd_memory_pool_t pool,\n                                                 uint32_t flags, void** agent_ptr) {\n  return amdExtTable->hsa_amd_memory_lock_to_pool_fn(host_ptr, size, agents, num_agent, pool, flags,\n                                                     agent_ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_memory_unlock(void* host_ptr) {\n  return amdExtTable->hsa_amd_memory_unlock_fn(host_ptr);\n\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API\n    hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {\n  return amdExtTable->hsa_amd_memory_fill_fn(ptr, value, count);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents,\n                                        hsa_agent_t* agents,\n                                        int interop_handle,\n                                        uint32_t flags,\n                                        size_t* size,\n                                        void** ptr,\n                                        size_t* metadata_size,\n                                        const void** metadata) {\n  return amdExtTable->hsa_amd_interop_map_buffer_fn(\n                                     num_agents, agents, interop_handle,\n                                     flags, size, ptr, metadata_size, metadata);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_interop_unmap_buffer(void* ptr) {\n  return amdExtTable->hsa_amd_interop_unmap_buffer_fn(ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_image_create(\n  hsa_agent_t agent,\n  const hsa_ext_image_descriptor_t *image_descriptor,\n  const hsa_amd_image_descriptor_t *image_layout,\n  const void *image_data,\n  hsa_access_permission_t access_permission,\n  hsa_ext_image_t *image) {\n  return amdExtTable->hsa_amd_image_create_fn(agent, image_descriptor,\n                          image_layout, image_data, access_permission, image);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_pointer_info(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),\n                              uint32_t* num_agents_accessible, hsa_agent_t** accessible) {\n  return amdExtTable->hsa_amd_pointer_info_fn(ptr, info, alloc, num_agents_accessible, accessible);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_pointer_info_set_userdata(const void* ptr, void* userptr) {\n  return amdExtTable->hsa_amd_pointer_info_set_userdata_fn(ptr, userptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_create(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle) {\n  return amdExtTable->hsa_amd_ipc_memory_create_fn(ptr, len, handle);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t len,\n                                       uint32_t num_agents, const hsa_agent_t* mapping_agents,\n                                       void** mapped_ptr) {\n  return amdExtTable->hsa_amd_ipc_memory_attach_fn(ipc, len, num_agents, mapping_agents,\n                                                   mapped_ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_detach(void* mapped_ptr) {\n  return amdExtTable->hsa_amd_ipc_memory_detach_fn(mapped_ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                                   const hsa_agent_t* consumers, uint64_t attributes,\n                                   hsa_signal_t* signal) {\n  return amdExtTable->hsa_amd_signal_create_fn(initial_value, num_consumers, consumers, attributes,\n                                               signal);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_ipc_signal_create(hsa_signal_t signal, hsa_amd_ipc_signal_t* handle) {\n  return amdExtTable->hsa_amd_ipc_signal_create_fn(signal, handle);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handle,\n                                               hsa_signal_t* signal) {\n  return amdExtTable->hsa_amd_ipc_signal_attach_fn(handle, signal);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_register_system_event_handler(\n    hsa_amd_system_event_callback_t callback, void* data) {\n  return amdExtTable->hsa_amd_register_system_event_handler_fn(callback, data);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_queue_set_priority(hsa_queue_t* queue,\n                                                hsa_amd_queue_priority_t priority) {\n  return amdExtTable->hsa_amd_queue_set_priority_fn(queue, priority);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_register_deallocation_callback(void* ptr,\n                                                    hsa_amd_deallocation_callback_t callback,\n                                                    void* user_data) {\n  return amdExtTable->hsa_amd_register_deallocation_callback_fn(ptr, callback, user_data);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_deregister_deallocation_callback(void* ptr,\n                                                      hsa_amd_deallocation_callback_t callback) {\n  return amdExtTable->hsa_amd_deregister_deallocation_callback_fn(ptr, callback);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_signal_value_pointer(hsa_signal_t signal,\n                                                  volatile hsa_signal_value_t** value_ptr) {\n  return amdExtTable->hsa_amd_signal_value_pointer_fn(signal, value_ptr);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_attributes_set(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count) {\n  return amdExtTable->hsa_amd_svm_attributes_set_fn(ptr, size, attribute_list, attribute_count);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_attributes_get(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count) {\n  return amdExtTable->hsa_amd_svm_attributes_get_fn(ptr, size, attribute_list, attribute_count);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_prefetch_async(void* ptr, size_t size, hsa_agent_t agent,\n                                        uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                        hsa_signal_t completion_signal) {\n  return amdExtTable->hsa_amd_svm_prefetch_async_fn(ptr, size, agent, num_dep_signals, dep_signals, completion_signal);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_acquire(hsa_agent_t agent) {\n  return amdExtTable->hsa_amd_spm_acquire_fn(agent);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_release(hsa_agent_t agent) {\n  return amdExtTable->hsa_amd_spm_release_fn(agent);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_set_dest_buffer(hsa_agent_t agent, size_t size, uint32_t* timeout,\n                                                 uint32_t* size_copied, void* dest,\n                                                 bool* is_data_loss) {\n  return amdExtTable->hsa_amd_spm_set_dest_buffer_fn(agent, size, timeout, size_copied, dest,\n                                                     is_data_loss);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_portable_export_dmabuf(const void* ptr, size_t size, int* dmabuf,\n                                                    uint64_t* offset) {\n  return amdExtTable->hsa_amd_portable_export_dmabuf_fn(ptr, size, dmabuf, offset);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_portable_export_dmabuf_v2(const void* ptr, size_t size, int* dmabuf,\n                                                    uint64_t* offset, uint64_t flags) {\n  return amdExtTable->hsa_amd_portable_export_dmabuf_v2_fn(ptr, size, dmabuf, offset, flags);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_portable_close_dmabuf(int dmabuf) {\n  return amdExtTable->hsa_amd_portable_close_dmabuf_fn(dmabuf);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_address_reserve(void** ptr, size_t size, uint64_t address,\n                                                  uint64_t flags) {\n  return amdExtTable->hsa_amd_vmem_address_reserve_fn(ptr, size, address, flags);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_address_reserve_align(void** ptr, size_t size, uint64_t address,\n                                                  uint64_t alignment, uint64_t flags) {\n  return amdExtTable->hsa_amd_vmem_address_reserve_align_fn(ptr, size, address, alignment, flags);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_address_free(void* ptr, size_t size) {\n  return amdExtTable->hsa_amd_vmem_address_free_fn(ptr, size);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_handle_create(hsa_amd_memory_pool_t pool, size_t size,\n                                                hsa_amd_memory_type_t type, uint64_t flags,\n                                                hsa_amd_vmem_alloc_handle_t* memory_handle) {\n  return amdExtTable->hsa_amd_vmem_handle_create_fn(pool, size, type, flags, memory_handle);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_handle_release(hsa_amd_vmem_alloc_handle_t memory_handle) {\n  return amdExtTable->hsa_amd_vmem_handle_release_fn(memory_handle);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_map(void* va, size_t size, size_t in_offset,\n                                      hsa_amd_vmem_alloc_handle_t memory_handle, uint64_t flags) {\n  return amdExtTable->hsa_amd_vmem_map_fn(va, size, in_offset, memory_handle, flags);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_unmap(void* va, size_t size) {\n  return amdExtTable->hsa_amd_vmem_unmap_fn(va, size);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_set_access(void* va, size_t size,\n                                             const hsa_amd_memory_access_desc_t* desc,\n                                             const size_t desc_cnt) {\n  return amdExtTable->hsa_amd_vmem_set_access_fn(va, size, desc, desc_cnt);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_get_access(void* va, hsa_access_permission_t* perms,\n                                             const hsa_agent_t agent_handle) {\n  return amdExtTable->hsa_amd_vmem_get_access_fn(va, perms, agent_handle);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_export_shareable_handle(int* dmabuf_fd,\n                                                          hsa_amd_vmem_alloc_handle_t handle,\n                                                          uint64_t flags) {\n  return amdExtTable->hsa_amd_vmem_export_shareable_handle_fn(dmabuf_fd, handle, flags);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_import_shareable_handle(int dmabuf_fd,\n                                                          hsa_amd_vmem_alloc_handle_t* handle) {\n  return amdExtTable->hsa_amd_vmem_import_shareable_handle_fn(dmabuf_fd, handle);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_retain_alloc_handle(hsa_amd_vmem_alloc_handle_t* handle,\n                                                      void* addr) {\n  return amdExtTable->hsa_amd_vmem_retain_alloc_handle_fn(handle, addr);\n}\n\nhsa_status_t HSA_API hsa_amd_vmem_get_alloc_properties_from_handle(\n    hsa_amd_vmem_alloc_handle_t alloc_handle, hsa_amd_memory_pool_t* pool,\n    hsa_amd_memory_type_t* type) {\n  return amdExtTable->hsa_amd_vmem_get_alloc_properties_from_handle_fn(alloc_handle, pool, type);\n}\n\nhsa_status_t HSA_API hsa_amd_agent_set_async_scratch_limit(hsa_agent_t agent, size_t threshold) {\n  return amdExtTable->hsa_amd_agent_set_async_scratch_limit_fn(agent, threshold);\n}\n\nhsa_status_t HSA_API hsa_amd_queue_get_info(hsa_queue_t* queue,\n                                            hsa_queue_info_attribute_t attribute, void* value) {\n  return amdExtTable->hsa_amd_queue_get_info_fn(queue, attribute, value);\n}\n\nhsa_status_t HSA_API hsa_amd_enable_logging(uint8_t* flags, void* file) {\n  return amdExtTable->hsa_amd_enable_logging_fn(flags, file);\n}\n\n// Tools only table interfaces.\nnamespace rocr {\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_queue_intercept_create(\n    hsa_agent_t agent_handle, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,\n    uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue) {\n  return amdExtTable->hsa_amd_queue_intercept_create_fn(\n      agent_handle, size, type, callback, data, private_segment_size, group_segment_size, queue);\n}\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_queue_intercept_register(hsa_queue_t* queue,\n                                              hsa_amd_queue_intercept_handler callback,\n                                              void* user_data) {\n  return amdExtTable->hsa_amd_queue_intercept_register_fn(queue, callback, user_data);\n}\n\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/common/shared.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_SHARED_H_\n#define HSA_RUNTME_CORE_INC_SHARED_H_\n\n#include <assert.h>\n#include <cstring>\n#include <functional>\n#include <memory>\n\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\n/// @brief Base class encapsulating the allocator and deallocator for\n/// shared shared object.  As used this will allocate GPU visible host\n/// memory mapped to all GPUs.\nclass BaseShared {\n public:\n  static void SetAllocateAndFree(\n      const std::function<void*(size_t, size_t, uint32_t, int)>& alloc,\n      const std::function<void(void*)>& fr) {\n    allocate_() = alloc;\n    free_() = fr;\n  }\n\n protected:\n  static __forceinline std::function<void*(size_t, size_t, uint32_t, int)>&\n   allocate_() {\n    static std::function<void*(size_t, size_t, uint32_t, int)> alloc =\n                                                                      nullptr;\n    return alloc;\n  }\n  static __forceinline std::function<void(void*)>&\n   free_() {\n    static std::function<void(void*)> fr = nullptr;\n    return fr;\n  }\n\n};\n\n/// @brief Default Allocator for Shared.  Ensures allocations are whole pages.\ntemplate <typename T> class PageAllocator : private BaseShared {\n public:\n  __forceinline static T* alloc(int flags = 0) {\n    T* ret = reinterpret_cast<T*>(\n                        allocate_()(AlignUp(sizeof(T), 4096), 4096, flags, 0));\n    if (ret == nullptr) throw std::bad_alloc();\n\n    MAKE_NAMED_SCOPE_GUARD(throwGuard, [&]() { free_()(ret); });\n\n    new (ret) T;\n\n    throwGuard.Dismiss();\n    return ret;\n  }\n\n  __forceinline static T* alloc(int agent_node_id, int flags) {\n    T* ret = reinterpret_cast<T*>(\n            allocate_()(AlignUp(sizeof(T), 4096), 4096, flags, agent_node_id));\n    if (ret == nullptr) throw std::bad_alloc();\n\n    MAKE_NAMED_SCOPE_GUARD(throwGuard, [&]() { free_()(ret); });\n\n    new (ret) T;\n\n    throwGuard.Dismiss();\n    return ret;\n  }\n\n  __forceinline static void free(T* ptr) {\n    if (ptr != nullptr) {\n      ptr->~T();\n      free_()(ptr);\n    }\n  }\n};\n\n/// @brief Container for object located in GPU visible host memory.\n/// If a custom allocator is not given then data will be placed in dedicated pages.\ntemplate <typename T, typename Allocator = PageAllocator<T>>\nclass Shared final : private BaseShared {\n public:\n  explicit Shared(Allocator* pool = nullptr, int flags = 0) : pool_(pool) {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n           \"Shared object allocator is not set\");\n\n    if (pool_)\n      shared_object_ = pool_->alloc();\n    else\n      shared_object_ = PageAllocator<T>::alloc(flags);\n  }\n\n  explicit Shared(int agent_node_id, Allocator* pool = nullptr, int flags = 0) : pool_(pool) {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n           \"Shared object allocator is not set\");\n\n    if (pool_)\n      shared_object_ = pool_->alloc();\n    else\n      shared_object_ = PageAllocator<T>::alloc(agent_node_id, flags);\n  }\n\n  ~Shared() {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n                                        \"Shared object allocator is not set\");\n\n    if (pool_)\n      pool_->free(shared_object_);\n    else\n      PageAllocator<T>::free(shared_object_);\n  }\n\n  Shared(Shared&& rhs) {\n    this->~Shared();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n    pool_ = rhs.pool_;\n    rhs.pool_ = nullptr;\n  }\n  Shared& operator=(Shared&& rhs) {\n    this->~Shared();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n    pool_ = rhs.pool_;\n    rhs.pool_ = nullptr;\n    return *this;\n  }\n\n  T* shared_object() const { return shared_object_; }\n\n private:\n  T* shared_object_;\n  Allocator* pool_;\n};\n\ntemplate <typename T> class Shared<T, PageAllocator<T>> final : private BaseShared {\n public:\n  Shared(int flags = 0) {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n                                        \"Shared object allocator is not set\");\n\n    shared_object_ = PageAllocator<T>::alloc(flags);\n  }\n\n  Shared(int agent_node_id, int flags) {\n    assert(allocate_() != nullptr && free_() != nullptr && \"Shared object allocator is not set\");\n\n    shared_object_ = PageAllocator<T>::alloc(agent_node_id, flags);\n  }\n\n  ~Shared() {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n           \"Shared object allocator is not set\");\n\n    PageAllocator<T>::free(shared_object_);\n  }\n\n  Shared(Shared&& rhs) {\n    this->~Shared();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n  }\n  Shared& operator=(Shared&& rhs) {\n    this->~Shared();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n    return *this;\n  }\n\n  T* shared_object() const { return shared_object_; }\n\n private:\n  T* shared_object_;\n};\n\n/// @brief Container for array located in GPU visible host memory.\n/// Alignment defaults to __alignof(T) but may be increased.\ntemplate <typename T, size_t Align> class SharedArray final : private BaseShared {\n public:\n  SharedArray() : shared_object_(nullptr) {}\n\n  explicit SharedArray(size_t length) : shared_object_(nullptr), len(length) {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n                                        \"Shared object allocator is not set\");\n    static_assert((__alignof(T) <= Align) || (Align == 0), \"Align is less than alignof(T)\");\n\n    shared_object_ =\n        reinterpret_cast<T*>(allocate_()(sizeof(T) * length, Max(__alignof(T), Align), 0, 0));\n    if (shared_object_ == nullptr) throw std::bad_alloc();\n\n    size_t i = 0;\n\n    MAKE_NAMED_SCOPE_GUARD(loopGuard, [&]() {\n      for (size_t t = 0; t < i - 1; t++) shared_object_[t].~T();\n      free_()(shared_object_);\n    });\n\n    for (; i < length; i++) new (&shared_object_[i]) T;\n\n    loopGuard.Dismiss();\n  }\n\n  ~SharedArray() {\n    assert(allocate_() != nullptr && free_() != nullptr &&\n                                        \"Shared object allocator is not set\");\n\n    if (shared_object_ != nullptr) {\n      for (size_t i = 0; i < len; i++) shared_object_[i].~T();\n      free_()(shared_object_);\n    }\n  }\n\n  SharedArray(SharedArray&& rhs) {\n    this->~SharedArray();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n    len = rhs.len;\n  }\n  SharedArray& operator=(SharedArray&& rhs) {\n    this->~SharedArray();\n    shared_object_ = rhs.shared_object_;\n    rhs.shared_object_ = nullptr;\n    len = rhs.len;\n    return *this;\n  }\n\n  T& operator[](size_t index) {\n    assert(index < len && \"Index out of bounds.\");\n    return shared_object_[index];\n  }\n  const T& operator[](size_t index) const {\n    assert(index < len && \"Index out of bounds.\");\n    return shared_object_[index];\n  }\n\n private:\n  T* shared_object_;\n  size_t len;\n};\n\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/driver/driver.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/driver.h\"\n\n#include \"inc/hsa.h\"\n\nnamespace rocr {\nnamespace core {\n\nDriver::Driver(DriverType kernel_driver_type, std::string devnode_name)\n    : kernel_driver_type_(std::move(kernel_driver_type)),\n      devnode_name_(std::move(devnode_name)) {}\n\n} // namespace core\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/driver/kfd/amd_kfd_driver.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_kfd_driver.h\"\n\n#include <memory>\n#include <string>\n\n#include <amdgpu_drm.h>\n#include <link.h>\n#include <sys/ioctl.h>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/runtime.h\"\n\nextern r_debug _amdgpu_r_debug;\n\nnamespace rocr {\nnamespace AMD {\n\nstatic_assert(\n    (sizeof(core::ShareableHandle::handle) >= sizeof(amdgpu_bo_handle)) &&\n        (alignof(core::ShareableHandle::handle) >= alignof(amdgpu_bo_handle)),\n    \"ShareableHandle cannot store a amdgpu_bo_handle\");\n\nnamespace {\n\n__forceinline uint64_t drm_perm(hsa_access_permission_t perm) {\n  switch (perm) {\n  case HSA_ACCESS_PERMISSION_RO:\n    return AMDGPU_VM_PAGE_READABLE;\n  case HSA_ACCESS_PERMISSION_WO:\n    return AMDGPU_VM_PAGE_WRITEABLE;\n  case HSA_ACCESS_PERMISSION_RW:\n    return AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE;\n  case HSA_ACCESS_PERMISSION_NONE:\n  default:\n    return 0;\n  }\n}\n\n} // namespace\n\nKfdDriver::KfdDriver(std::string devnode_name)\n    : core::Driver(core::DriverType::KFD, std::move(devnode_name)) {}\n\nhsa_status_t KfdDriver::Init() {\n  HSAKMT_STATUS ret =\n      HSAKMT_CALL(hsaKmtRuntimeEnable(&_amdgpu_r_debug, core::Runtime::runtime_singleton_->flag().debug()));\n\n  if (ret != HSAKMT_STATUS_SUCCESS && ret != HSAKMT_STATUS_NOT_SUPPORTED) return HSA_STATUS_ERROR;\n\n  uint32_t caps_mask = 0;\n  if (HSAKMT_CALL(hsaKmtGetRuntimeCapabilities(&caps_mask)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  core::Runtime::runtime_singleton_->KfdVersion(\n      ret != HSAKMT_STATUS_NOT_SUPPORTED,\n      !!(caps_mask & HSA_RUNTIME_ENABLE_CAPS_SUPPORTS_CORE_DUMP_MASK));\n\n  if (HSAKMT_CALL(hsaKmtGetVersion(&version_)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  if (version_.KernelInterfaceMajorVersion == kfd_version_major_min &&\n      version_.KernelInterfaceMinorVersion < kfd_version_major_min)\n    return HSA_STATUS_ERROR;\n\n  core::Runtime::runtime_singleton_->KfdVersion(version_);\n\n  if (version_.KernelInterfaceMajorVersion == 1 && version_.KernelInterfaceMinorVersion == 0)\n    core::g_use_interrupt_wait = false;\n\n  bool xnack_mode = BindXnackMode();\n  core::Runtime::runtime_singleton_->XnackEnabled(xnack_mode);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ShutDown() {\n  HSAKMT_STATUS ret = HSAKMT_CALL(hsaKmtRuntimeDisable());\n  if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  ret = HSAKMT_CALL(hsaKmtReleaseSystemProperties());\n\n  if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return Close();\n}\n\nhsa_status_t KfdDriver::DiscoverDriver(std::unique_ptr<core::Driver>& driver) {\n  auto tmp_driver = std::unique_ptr<core::Driver>(new KfdDriver(\"/dev/kfd\"));\n\n  if (tmp_driver->Open() == HSA_STATUS_SUCCESS) {\n    driver = std::move(tmp_driver);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdDriver::QueryKernelModeDriver(core::DriverQuery query) {\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::Open() {\n  return HSAKMT_CALL(hsaKmtOpenKFD()) == HSAKMT_STATUS_SUCCESS ? HSA_STATUS_SUCCESS\n                                                  : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdDriver::Close() {\n  return HSAKMT_CALL(hsaKmtCloseKFD()) == HSAKMT_STATUS_SUCCESS ? HSA_STATUS_SUCCESS\n                                                   : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdDriver::GetSystemProperties(HsaSystemProperties& sys_props) const {\n  if (HSAKMT_CALL(hsaKmtReleaseSystemProperties()) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  if (HSAKMT_CALL(hsaKmtAcquireSystemProperties(&sys_props)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const {\n  if (HSAKMT_CALL(hsaKmtGetNodeProperties(node_id, &node_props)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                          uint32_t node_id) const {\n  if (HSAKMT_CALL(hsaKmtGetNodeIoLinkProperties(node_id, io_link_props.size(), io_link_props.data())) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetMemoryProperties(uint32_t node_id,\n                                            std::vector<HsaMemoryProperties>& mem_props) const {\n  if (!mem_props.data()) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  if (HSAKMT_CALL(hsaKmtGetNodeMemoryProperties(node_id, mem_props.size(), mem_props.data())) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                           std::vector<HsaCacheProperties>& cache_props) const {\n  if (!cache_props.data()) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  if (HSAKMT_CALL(hsaKmtGetNodeCacheProperties(node_id, processor_id, cache_props.size(), cache_props.data())) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t\nKfdDriver::AllocateMemory(const core::MemoryRegion &mem_region,\n                          core::MemoryRegion::AllocateFlags alloc_flags,\n                          void **mem, size_t size, uint32_t agent_node_id) {\n  const MemoryRegion &m_region(static_cast<const MemoryRegion &>(mem_region));\n  HsaMemFlags kmt_alloc_flags(m_region.mem_flags());\n\n  kmt_alloc_flags.ui32.ExecuteAccess =\n      (alloc_flags & core::MemoryRegion::AllocateExecutable ? 1 : 0);\n\n  if (m_region.IsSystem() &&\n      (alloc_flags & core::MemoryRegion::AllocateNonPaged)) {\n    kmt_alloc_flags.ui32.NonPaged = 1;\n  }\n\n  if (!m_region.IsLocalMemory() &&\n      (alloc_flags & core::MemoryRegion::AllocateMemoryOnly)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Allocating a memory handle for virtual memory\n  kmt_alloc_flags.ui32.NoAddress =\n      !!(alloc_flags & core::MemoryRegion::AllocateMemoryOnly);\n\n  // Allocate pseudo fine grain memory\n  kmt_alloc_flags.ui32.CoarseGrain =\n      (alloc_flags & core::MemoryRegion::AllocatePCIeRW\n           ? 0\n           : kmt_alloc_flags.ui32.CoarseGrain);\n\n  kmt_alloc_flags.ui32.NoSubstitute =\n      (alloc_flags & core::MemoryRegion::AllocatePinned\n           ? 1\n           : kmt_alloc_flags.ui32.NoSubstitute);\n\n  kmt_alloc_flags.ui32.GTTAccess =\n      (alloc_flags & core::MemoryRegion::AllocateGTTAccess\n           ? 1\n           : kmt_alloc_flags.ui32.GTTAccess);\n\n  kmt_alloc_flags.ui32.Uncached =\n      (alloc_flags & core::MemoryRegion::AllocateUncached\n            ? 1\n            : kmt_alloc_flags.ui32.Uncached);\n\n  kmt_alloc_flags.ui32.ExecuteBlit =\n    !!(alloc_flags & core::MemoryRegion::AllocateExecutableBlitKernelObject);\n\n  if (m_region.IsLocalMemory()) {\n    // Allocate physically contiguous memory. AllocateKfdMemory function call\n    // will fail if this flag is not supported in KFD.\n    kmt_alloc_flags.ui32.Contiguous =\n        (alloc_flags & core::MemoryRegion::AllocateContiguous\n             ? 1\n             : kmt_alloc_flags.ui32.Contiguous);\n  }\n\n  //// Only allow using the suballocator for ordinary VRAM.\n  if (m_region.IsLocalMemory() && !kmt_alloc_flags.ui32.NoAddress) {\n    bool subAllocEnabled =\n        !core::Runtime::runtime_singleton_->flag().disable_fragment_alloc();\n    // Avoid modifying executable or queue allocations.\n    bool useSubAlloc = subAllocEnabled;\n    useSubAlloc &=\n        ((alloc_flags & (~core::MemoryRegion::AllocateRestrict)) == 0);\n\n    if (useSubAlloc) {\n      *mem = m_region.fragment_alloc(size);\n\n      if ((alloc_flags & core::MemoryRegion::AllocateAsan) &&\n          HSAKMT_CALL(hsaKmtReplaceAsanHeaderPage(*mem)) != HSAKMT_STATUS_SUCCESS) {\n        m_region.fragment_free(*mem);\n        *mem = nullptr;\n        return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n      }\n\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n\n  const uint32_t node_id =\n      (alloc_flags & core::MemoryRegion::AllocateGTTAccess)\n          ? agent_node_id\n          : m_region.owner()->node_id();\n\n  //// Allocate memory.\n  //// If it fails attempt to release memory from the block allocator and retry.\n  *mem = AllocateKfdMemory(kmt_alloc_flags, node_id, size);\n  if (*mem == nullptr) {\n    m_region.owner()->Trim();\n    *mem = AllocateKfdMemory(kmt_alloc_flags, node_id, size);\n  }\n\n  if (*mem != nullptr) {\n    if (kmt_alloc_flags.ui32.NoAddress)\n      return HSA_STATUS_SUCCESS;\n\n    // Commit the memory.\n    // For system memory, on non-restricted allocation, map it to all GPUs. On\n    // restricted allocation, only CPU is allowed to access by default, so\n    // no need to map\n    // For local memory, only map it to the owning GPU. Mapping to other GPU,\n    // if the access is allowed, is performed on AllowAccess.\n    HsaMemMapFlags map_flag = m_region.map_flags();\n    size_t map_node_count = 1;\n    const uint32_t owner_node_id = m_region.owner()->node_id();\n    const uint32_t *map_node_id = &owner_node_id;\n\n    if (m_region.IsSystem()) {\n      if ((alloc_flags & core::MemoryRegion::AllocateRestrict) == 0) {\n        // Map to all GPU agents.\n        map_node_count = core::Runtime::runtime_singleton_->gpu_ids().size();\n\n        if (map_node_count == 0) {\n          // No need to pin since no GPU in the platform.\n          return HSA_STATUS_SUCCESS;\n        }\n\n        map_node_id = &core::Runtime::runtime_singleton_->gpu_ids()[0];\n      } else {\n        // No need to pin it for CPU exclusive access.\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n\n    uint64_t alternate_va = 0;\n    const bool is_resident = MakeKfdMemoryResident(\n        map_node_count, map_node_id, *mem, size, &alternate_va, map_flag);\n\n    const bool require_pinning =\n        (!m_region.full_profile() || m_region.IsLocalMemory() ||\n         m_region.IsScratch());\n\n    if (require_pinning && !is_resident) {\n      FreeKfdMemory(*mem, size);\n      *mem = nullptr;\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n\n    if ((alloc_flags & core::MemoryRegion::AllocateAsan) &&\n        HSAKMT_CALL(hsaKmtReplaceAsanHeaderPage(*mem)) != HSAKMT_STATUS_SUCCESS) {\n      FreeKfdMemory(*mem, size);\n      *mem = nullptr;\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n}\n\nhsa_status_t KfdDriver::FreeMemory(void *mem, size_t size) {\n  MakeKfdMemoryUnresident(mem);\n  return FreeKfdMemory(mem, size) ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdDriver::CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                                    HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id,\n                                    void* queue_addr, uint64_t queue_size_bytes, HsaEvent* event,\n                                    HsaQueueResource& queue_resource) const {\n  if (HSAKMT_CALL(hsaKmtCreateQueueExt(node_id, type, queue_pct, priority, sdma_engine_id,\n                                       queue_addr, queue_size_bytes, event, &queue_resource)) !=\n      HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::DestroyQueue(HSA_QUEUEID queue_id) const {\n  if (HSAKMT_CALL(hsaKmtDestroyQueue(queue_id)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_pct,\n                                    HSA_QUEUE_PRIORITY priority, void* queue_addr,\n                                    uint64_t queue_size, HsaEvent* event) const {\n  if (HSAKMT_CALL(hsaKmtUpdateQueue(queue_id, queue_pct, priority, queue_addr, queue_size,\n                                    event)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t cu_mask_count,\n                                       uint32_t* queue_cu_mask) const {\n  if (HSAKMT_CALL(hsaKmtSetQueueCUMask(queue_id, cu_mask_count, queue_cu_mask)) !=\n      HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_gws,\n                                      uint32_t* first_gws) const {\n  if (HSAKMT_CALL(hsaKmtAllocQueueGWS(queue_id, num_gws, first_gws)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ExportDMABuf(void *mem, size_t size, int *dmabuf_fd,\n                                     size_t *offset) {\n  int dmabuf_fd_res = -1;\n  size_t offset_res = 0;\n  HSAKMT_STATUS status =\n      HSAKMT_CALL(hsaKmtExportDMABufHandle(mem, size, &dmabuf_fd_res, &offset_res));\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    if (status == HSAKMT_STATUS_INVALID_PARAMETER) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  *dmabuf_fd = dmabuf_fd_res;\n  *offset = offset_res;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ImportDMABuf(int dmabuf_fd, core::Agent &agent,\n                                     core::ShareableHandle &handle) {\n  auto &gpu_agent = static_cast<GpuAgent &>(agent);\n  amdgpu_bo_import_result res;\n  auto ret = DRM_CALL(amdgpu_bo_import(\n      gpu_agent.libDrmDev(), amdgpu_bo_handle_type_dma_buf_fd, dmabuf_fd, &res));\n  if (ret)\n    return HSA_STATUS_ERROR;\n\n  handle.handle = reinterpret_cast<uint64_t>(res.buf_handle);\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::Map(core::ShareableHandle handle, void *mem,\n                            size_t offset, size_t size,\n                            hsa_access_permission_t perms) {\n  const auto ldrm_bo = reinterpret_cast<amdgpu_bo_handle>(handle.handle);\n  if (!ldrm_bo)\n    return HSA_STATUS_ERROR;\n\n  if (DRM_CALL(amdgpu_bo_va_op(ldrm_bo, offset, size, reinterpret_cast<uint64_t>(mem),\n                      drm_perm(perms), AMDGPU_VA_OP_MAP)) != 0)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::Unmap(core::ShareableHandle handle, void *mem,\n                              size_t offset, size_t size) {\n  const auto ldrm_bo = reinterpret_cast<amdgpu_bo_handle>(handle.handle);\n  if (!ldrm_bo)\n    return HSA_STATUS_ERROR;\n\n  if (DRM_CALL(amdgpu_bo_va_op(ldrm_bo, offset, size, reinterpret_cast<uint64_t>(mem), 0,\n                      AMDGPU_VA_OP_UNMAP)) != 0)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ReleaseShareableHandle(core::ShareableHandle &handle) {\n  const auto ldrm_bo = reinterpret_cast<amdgpu_bo_handle>(handle.handle);\n  if (!ldrm_bo)\n    return HSA_STATUS_ERROR;\n\n  const auto ret = DRM_CALL(amdgpu_bo_free(ldrm_bo));\n  if (ret)\n    return HSA_STATUS_ERROR;\n\n  handle = {};\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::SPMAcquire(uint32_t preferred_node_id) const {\n  if (HSAKMT_CALL(hsaKmtSPMAcquire(preferred_node_id)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::SPMRelease(uint32_t preferred_node_id) const {\n  if (HSAKMT_CALL(hsaKmtSPMRelease(preferred_node_id)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::SPMSetDestBuffer(uint32_t preferred_node_id, uint32_t size_bytes,\n                                         uint32_t* timeout, uint32_t* size_copied,\n                                         void* dest_mem_addr, bool* is_spm_data_loss) const {\n  if (HSAKMT_CALL(hsaKmtSPMSetDestBuffer(preferred_node_id, size_bytes, timeout, size_copied, dest_mem_addr,\n                             is_spm_data_loss)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::OpenSMI(uint32_t node_id, int* fd) const {\n  if (HSAKMT_CALL(hsaKmtOpenSMI(node_id, fd)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid *KfdDriver::AllocateKfdMemory(const HsaMemFlags &flags, uint32_t node_id,\n                                   size_t size) {\n  void *mem = nullptr;\n  const HSAKMT_STATUS status = HSAKMT_CALL(hsaKmtAllocMemory(node_id, size, flags, &mem));\n  return (status == HSAKMT_STATUS_SUCCESS) ? mem : nullptr;\n}\n\nbool KfdDriver::FreeKfdMemory(void *mem, size_t size) {\n  if (mem == nullptr || size == 0) {\n    debug_print(\"Invalid free ptr:%p size:%lu\\n\", mem, size);\n    return false;\n  }\n\n  if (HSAKMT_CALL(hsaKmtFreeMemory(mem, size)) != HSAKMT_STATUS_SUCCESS) {\n    debug_print(\"Failed to free ptr:%p size:%lu\\n\", mem, size);\n    return false;\n  }\n  return true;\n}\n\nbool KfdDriver::MakeKfdMemoryResident(size_t num_node, const uint32_t *nodes,\n                                      const void *mem, size_t size,\n                                      uint64_t *alternate_va,\n                                      HsaMemMapFlags map_flag) {\n  assert(num_node > 0);\n  assert(nodes);\n\n  *alternate_va = 0;\n\n  HSAKMT_STATUS kmt_status(HSAKMT_CALL(hsaKmtMapMemoryToGPUNodes(\n      const_cast<void *>(mem), size, alternate_va, map_flag, num_node,\n      const_cast<uint32_t *>(nodes))));\n\n  return (kmt_status == HSAKMT_STATUS_SUCCESS);\n}\n\nvoid KfdDriver::MakeKfdMemoryUnresident(const void *mem) {\n  HSAKMT_CALL(hsaKmtUnmapMemoryToGPU(const_cast<void *>(mem)));\n}\n\nbool KfdDriver::BindXnackMode() {\n  // Get users' preference for Xnack mode of ROCm platform.\n  HSAint32 mode = core::Runtime::runtime_singleton_->flag().xnack();\n  bool config_xnack = (mode != Flag::XNACK_REQUEST::XNACK_UNCHANGED);\n\n  // Indicate to driver users' preference for Xnack mode\n  // Call to driver can fail and is a supported feature\n  HSAKMT_STATUS status = HSAKMT_STATUS_ERROR;\n  if (config_xnack) {\n    status = HSAKMT_CALL(hsaKmtSetXNACKMode(mode));\n    if (status == HSAKMT_STATUS_SUCCESS) {\n      return (mode != Flag::XNACK_DISABLE);\n    }\n  }\n\n  // Get Xnack mode of devices bound by driver. This could happen\n  // when a call to SET Xnack mode fails or user has no particular\n  // preference\n  status = HSAKMT_CALL(hsaKmtGetXNACKMode(&mode));\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    debug_print(\n        \"KFD does not support xnack mode query.\\nROCr must assume \"\n        \"xnack is disabled.\\n\");\n    return false;\n  }\n  return (mode != Flag::XNACK_DISABLE);\n}\n\nhsa_status_t KfdDriver::SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                                       const void* buffer_base, uint64_t buffer_base_size) const {\n  if (HSAKMT_CALL(hsaKmtSetTrapHandler(node_id, const_cast<void*>(base), base_size,\n                                       const_cast<void*>(buffer_base), buffer_base_size)) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const {\n  assert(mem);\n  assert(size > 0);\n\n  HsaMemFlags flags = {};\n  flags.ui32.Scratch = 1;\n  flags.ui32.HostAccess = 1;\n\n  void* ptr = AllocateKfdMemory(flags, node_id, size);\n  if (ptr == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  *mem = ptr;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetDeviceHandle(uint32_t node_id, void** device_handle) const {\n  assert(device_handle);\n\n  if (HSAKMT_CALL(hsaKmtGetAMDGPUDeviceHandle(node_id, reinterpret_cast<HsaAMDGPUDeviceHandle*>(device_handle))) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetClockCounters(uint32_t node_id, HsaClockCounters* clock_counter) const {\n  assert(clock_counter);\n\n  if (HSAKMT_CALL(hsaKmtGetClockCounters(node_id, clock_counter)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const {\n  assert(config);\n\n  if (HSAKMT_CALL(hsaKmtGetTileConfig(node_id, config)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::AvailableMemory(uint32_t node_id, uint64_t* available_size) const {\n  assert(available_size);\n\n  if (HSAKMT_CALL(hsaKmtAvailableMemory(node_id, available_size)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const {\n  assert(ptr);\n  assert(size > 0);\n\n  if (HSAKMT_CALL(hsaKmtRegisterMemoryWithFlags(ptr, size, mem_flags)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::DeregisterMemory(void* ptr) const {\n  if (HSAKMT_CALL(hsaKmtDeregisterMemory(ptr)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                           const HsaMemMapFlags* mem_flags, uint32_t num_nodes,\n                                           const uint32_t* nodes) const {\n  if (mem_flags == nullptr && nodes == nullptr) {\n    if (HSAKMT_CALL(hsaKmtMapMemoryToGPU(const_cast<void*>(mem), size, alternate_va)) !=\n        HSAKMT_STATUS_SUCCESS) {\n      return HSA_STATUS_ERROR;\n    }\n  } else if (mem_flags != nullptr && nodes != nullptr) {\n    if (!MakeKfdMemoryResident(num_nodes, nodes, mem, size, alternate_va, *mem_flags)) {\n      return HSA_STATUS_ERROR;\n    }\n  } else {\n    debug_print(\"Invalid memory flags ptr:%p nodes ptr:%p\\n\", mem_flags, nodes);\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::MakeMemoryUnresident(const void* mem) const {\n  HSAKMT_CALL(hsaKmtUnmapMemoryToGPU(const_cast<void*>(mem)));\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::IsModelEnabled(bool* enable) const {\n  // AIE does not support streaming performance monitor.\n  HSAKMT_STATUS status = HSAKMT_STATUS_ERROR;\n  status = HSAKMT_CALL(hsaKmtModelEnabled(enable));\n  if (status != HSAKMT_STATUS_SUCCESS)\n     return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const {\n  assert(frequency);\n\n  amdgpu_gpu_info info;\n  amdgpu_device_handle handle;\n  if (GetDeviceHandle(node_id, reinterpret_cast<void**>(&handle)) != HSA_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  if (DRM_CALL(amdgpu_query_gpu_info(handle, &info)) < 0) return HSA_STATUS_ERROR;\n\n  // Reported by libdrm in KHz.\n  *frequency = uint64_t(info.gpu_counter_freq) * 1000ull;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ShareMemory(void* mem, size_t size,\n                                    HsaSharedMemoryHandle* share_mem) const {\n  assert(share_mem);\n\n  if (HSAKMT_CALL(hsaKmtShareMemory(mem, size, share_mem)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::RegisterSharedHandle(const HsaSharedMemoryHandle* share_mem, void** mem,\n                                             uint64_t* size) const {\n  assert(share_mem);\n  assert(mem);\n  assert(size);\n\n  if (HSAKMT_CALL(hsaKmtRegisterSharedHandle(share_mem, mem, size)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ReplaceAsanHeaderPage(void* mem) const {\n  if (HSAKMT_CALL(hsaKmtReplaceAsanHeaderPage(mem)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::ReturnAsanHeaderPage(void* mem) const {\n  if (HSAKMT_CALL(hsaKmtReturnAsanHeaderPage(mem)) != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::PcSamplingQueryCapabilities(uint32_t node_id, void* sample_info,\n                                                    uint32_t sample_info_sz,\n                                                    uint32_t* sz_needed) const {\n  HSAKMT_STATUS status = HSAKMT_CALL(\n      hsaKmtPcSamplingQueryCapabilities(node_id, sample_info, sample_info_sz, sz_needed));\n  if (status == HSAKMT_STATUS_KERNEL_ALREADY_OPENED) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_RESOURCE_BUSY);\n  }\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::PcSamplingCreate(uint32_t node_id, HsaPcSamplingInfo* sample_info,\n                                         uint32_t* trace_id) const {\n  HSAKMT_STATUS status = HSAKMT_CALL(hsaKmtPcSamplingCreate(node_id, sample_info, trace_id));\n  if (status == HSAKMT_STATUS_KERNEL_ALREADY_OPENED) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_RESOURCE_BUSY);\n  }\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::PcSamplingDestroy(uint32_t node_id, uint32_t trace_id) const {\n  HSAKMT_STATUS status = HSAKMT_CALL(hsaKmtPcSamplingDestroy(node_id, trace_id));\n  if (status == HSAKMT_STATUS_KERNEL_ALREADY_OPENED) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_RESOURCE_BUSY);\n  }\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::PcSamplingStart(uint32_t node_id, uint32_t trace_id) const {\n  HSAKMT_STATUS status = HSAKMT_CALL(hsaKmtPcSamplingStart(node_id, trace_id));\n  if (status == HSAKMT_STATUS_KERNEL_ALREADY_OPENED) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_RESOURCE_BUSY);\n  }\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdDriver::PcSamplingStop(uint32_t node_id, uint32_t trace_id) const {\n  HSAKMT_STATUS status = HSAKMT_CALL(hsaKmtPcSamplingStop(node_id, trace_id));\n  if (status == HSAKMT_STATUS_KERNEL_ALREADY_OPENED) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_RESOURCE_BUSY);\n  }\n  if (status != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n} // namespace AMD\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/driver/virtio/amd_kfd_virtio_driver.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_virtio_driver.h\"\n#include \"hsakmt/hsakmt_virtio.h\"\n\n#include <link.h>\n#include <vector>\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/runtime.h\"\n\nextern r_debug _amdgpu_r_debug;\n\nnamespace rocr {\nnamespace AMD {\n\nKfdVirtioDriver::KfdVirtioDriver(std::string devnode_name)\n    : core::Driver(core::DriverType::KFD_VIRTIO, std::move(devnode_name)) {}\n\nhsa_status_t KfdVirtioDriver::DiscoverDriver(std::unique_ptr<core::Driver>& driver) {\n  auto tmp_driver = std::unique_ptr<core::Driver>(new KfdVirtioDriver(\"\"));\n\n  if (tmp_driver->Open() == HSA_STATUS_SUCCESS) {\n    driver = std::move(tmp_driver);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::Open() {\n  return vhsaKmtOpenKFD() == HSAKMT_STATUS_SUCCESS ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::Close() {\n  return vhsaKmtCloseKFD() == HSAKMT_STATUS_SUCCESS ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::Init() {\n  HSAKMT_STATUS ret =\n      vhsaKmtRuntimeEnable(&_amdgpu_r_debug, core::Runtime::runtime_singleton_->flag().debug());\n  uint32_t caps_mask = 0;\n\n  if (ret != HSAKMT_STATUS_SUCCESS && ret != HSAKMT_STATUS_NOT_SUPPORTED) return HSA_STATUS_ERROR;\n\n  if (vhsaKmtGetRuntimeCapabilities(&caps_mask) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  core::Runtime::runtime_singleton_->KfdVersion(\n      ret != HSAKMT_STATUS_NOT_SUPPORTED,\n      !!(caps_mask & HSA_RUNTIME_ENABLE_CAPS_SUPPORTS_CORE_DUMP_MASK));\n\n  if (vhsaKmtGetVersion(&version_) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  core::Runtime::runtime_singleton_->KfdVersion(version_);\n\n  if (version_.KernelInterfaceMajorVersion == 1 && version_.KernelInterfaceMinorVersion == 0)\n    core::g_use_interrupt_wait = false;\n\n  /* Force disable interrupt wait in VIRTIO driver temporarily */\n  core::g_use_interrupt_wait = false;\n\n  /* Force disable XNACK in VIRTIO driver temporarily */\n  core::Runtime::runtime_singleton_->XnackEnabled(false);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::ShutDown() {\n  HSAKMT_STATUS ret = vhsaKmtRuntimeDisable();\n  if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  ret = vhsaKmtReleaseSystemProperties();\n\n  if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return Close();\n}\n\nhsa_status_t KfdVirtioDriver::QueryKernelModeDriver(core::DriverQuery query) {\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetSystemProperties(HsaSystemProperties& sys_props) const {\n  if (vhsaKmtAcquireSystemProperties(&sys_props) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetNodeProperties(HsaNodeProperties& node_props,\n                                                uint32_t node_id) const {\n  if (vhsaKmtGetNodeProperties(node_id, &node_props) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                                uint32_t node_id) const {\n  if (vhsaKmtGetNodeIoLinkProperties(node_id, io_link_props.size(), io_link_props.data()) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetMemoryProperties(\n    uint32_t node_id, std::vector<HsaMemoryProperties>& mem_props) const {\n  if (mem_props.empty()) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (vhsaKmtGetNodeMemoryProperties(node_id, mem_props.size(), mem_props.data()) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetCacheProperties(\n    uint32_t node_id, uint32_t processor_id, std::vector<HsaCacheProperties>& cache_props) const {\n  if (cache_props.empty()) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (vhsaKmtGetNodeCacheProperties(node_id, 0, cache_props.size(), cache_props.data()) !=\n      HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetDeviceHandle(uint32_t node_id, void** device_handle) const {\n  assert(device_handle != nullptr);\n\n  if (vhsaKmtGetAMDGPUDeviceHandle(node_id, device_handle) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::GetClockCounters(uint32_t node_id,\n                                               HsaClockCounters* clock_counter) const {\n  assert(clock_counter != nullptr);\n\n  if (vhsaKmtGetClockCounters(node_id, clock_counter) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                                             const void* buffer_base,\n                                             uint64_t buffer_base_size) const {\n  if (vhsaKmtSetTrapHandler(node_id, const_cast<void*>(base), base_size,\n                            const_cast<void*>(buffer_base),\n                            buffer_base_size) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::AllocateMemory(const core::MemoryRegion& mem_region,\n                                             core::MemoryRegion::AllocateFlags alloc_flags,\n                                             void** mem, size_t size, uint32_t agent_node_id) {\n  const MemoryRegion& m_region(static_cast<const MemoryRegion&>(mem_region));\n  HsaMemFlags kmt_alloc_flags(m_region.mem_flags());\n  HSAKMT_STATUS ret;\n\n  kmt_alloc_flags.ui32.ExecuteAccess =\n      (alloc_flags & core::MemoryRegion::AllocateExecutable ? 1 : 0);\n  kmt_alloc_flags.ui32.AQLQueueMemory =\n      (alloc_flags & core::MemoryRegion::AllocateDoubleMap ? 1 : 0);\n\n  if (m_region.IsSystem() && (alloc_flags & core::MemoryRegion::AllocateNonPaged)) {\n    kmt_alloc_flags.ui32.NonPaged = 1;\n  }\n\n  if (!m_region.IsLocalMemory() && (alloc_flags & core::MemoryRegion::AllocateMemoryOnly)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Allocating a memory handle for virtual memory\n  kmt_alloc_flags.ui32.NoAddress = !!(alloc_flags & core::MemoryRegion::AllocateMemoryOnly);\n\n  // Allocate pseudo fine grain memory\n  kmt_alloc_flags.ui32.CoarseGrain =\n      (alloc_flags & core::MemoryRegion::AllocatePCIeRW ? 0 : kmt_alloc_flags.ui32.CoarseGrain);\n\n  kmt_alloc_flags.ui32.NoSubstitute =\n      (alloc_flags & core::MemoryRegion::AllocatePinned ? 1 : kmt_alloc_flags.ui32.NoSubstitute);\n\n  kmt_alloc_flags.ui32.GTTAccess =\n      (alloc_flags & core::MemoryRegion::AllocateGTTAccess ? 1 : kmt_alloc_flags.ui32.GTTAccess);\n\n  kmt_alloc_flags.ui32.Uncached =\n      (alloc_flags & core::MemoryRegion::AllocateUncached ? 1 : kmt_alloc_flags.ui32.Uncached);\n\n  if (m_region.IsLocalMemory()) {\n    // Allocate physically contiguous memory. AllocateKfdMemory function call\n    // will fail if this flag is not supported in KFD.\n    kmt_alloc_flags.ui32.Contiguous =\n        (alloc_flags & core::MemoryRegion::AllocateContiguous ? 1\n                                                              : kmt_alloc_flags.ui32.Contiguous);\n  }\n\n  //// Only allow using the suballocator for ordinary VRAM.\n  if (m_region.IsLocalMemory() && !kmt_alloc_flags.ui32.NoAddress) {\n    bool subAllocEnabled = !core::Runtime::runtime_singleton_->flag().disable_fragment_alloc();\n    // Avoid modifying executable or queue allocations.\n    bool useSubAlloc = subAllocEnabled;\n    useSubAlloc &= ((alloc_flags & (~core::MemoryRegion::AllocateRestrict)) == 0);\n\n    if (useSubAlloc) {\n      *mem = m_region.fragment_alloc(size);\n\n      if ((alloc_flags & core::MemoryRegion::AllocateAsan)) {\n        // TODO: Implement ASAN support for VIRTIO driver\n        return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n      }\n\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n\n  const uint32_t node_id = (alloc_flags & core::MemoryRegion::AllocateGTTAccess)\n      ? agent_node_id\n      : m_region.owner()->node_id();\n\n  //// Allocate memory.\n  //// If it fails attempt to release memory from the block allocator and retry.\n  ret = vhsaKmtAllocMemory(node_id, size, kmt_alloc_flags, mem);\n  if (ret != HSAKMT_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  if (*mem == nullptr) {\n    m_region.owner()->Trim();\n    ret = vhsaKmtAllocMemory(node_id, size, kmt_alloc_flags, mem);\n    if (ret != HSAKMT_STATUS_SUCCESS) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  if (*mem != nullptr) {\n    if (kmt_alloc_flags.ui32.NoAddress) return HSA_STATUS_SUCCESS;\n\n    // Commit the memory.\n    // For system memory, on non-restricted allocation, map it to all GPUs. On\n    // restricted allocation, only CPU is allowed to access by default, so\n    // no need to map\n    // For local memory, only map it to the owning GPU. Mapping to other GPU,\n    // if the access is allowed, is performed on AllowAccess.\n    HsaMemMapFlags map_flag = m_region.map_flags();\n    size_t map_node_count = 1;\n    const uint32_t owner_node_id = m_region.owner()->node_id();\n    const uint32_t* map_node_id = &owner_node_id;\n\n    if (m_region.IsSystem()) {\n      if ((alloc_flags & core::MemoryRegion::AllocateRestrict) == 0) {\n        // Map to all GPU agents.\n        map_node_count = core::Runtime::runtime_singleton_->gpu_ids().size();\n\n        if (map_node_count == 0) {\n          // No need to pin since no GPU in the platform.\n          return HSA_STATUS_SUCCESS;\n        }\n\n        map_node_id = &core::Runtime::runtime_singleton_->gpu_ids()[0];\n      } else {\n        // No need to pin it for CPU exclusive access.\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n\n    uint64_t alternate_va = 0;\n    const bool is_resident =\n        (MakeMemoryResident(*mem, size, &alternate_va, &map_flag, map_node_count, map_node_id) ==\n         HSA_STATUS_SUCCESS);\n\n    const bool require_pinning =\n        (!m_region.full_profile() || m_region.IsLocalMemory() || m_region.IsScratch());\n\n    if (require_pinning && !is_resident) {\n      vhsaKmtFreeMemory(*mem, size);\n      *mem = nullptr;\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n\n    if ((alloc_flags & core::MemoryRegion::AllocateAsan)) {\n      // TODO: Implement ASAN support for VIRTIO driver\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n}\n\nhsa_status_t KfdVirtioDriver::FreeMemory(void* mem, size_t size) {\n  MakeMemoryUnresident(mem);\n  return vhsaKmtFreeMemory(mem, size) == HSAKMT_STATUS_SUCCESS ? HSA_STATUS_SUCCESS\n                                                               : HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::AllocateScratchMemory(uint32_t node_id, uint64_t size,\n                                                    void** mem) const {\n  assert(mem != nullptr);\n  assert(size != 0);\n\n  HsaMemFlags flags = {};\n  flags.ui32.Scratch = 1;\n  flags.ui32.HostAccess = 1;\n  void* ptr = nullptr;\n\n  HSAKMT_STATUS ret = vhsaKmtAllocMemory(node_id, size, flags, &ptr);\n  if (ret != HSAKMT_STATUS_SUCCESS || ptr == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  *mem = ptr;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::RegisterMemory(void* ptr, uint64_t size,\n                                             HsaMemFlags mem_flags) const {\n  assert(ptr != nullptr);\n  assert(size != 0);\n\n  if (vhsaKmtRegisterMemoryWithFlags(ptr, size, mem_flags) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::DeregisterMemory(void* ptr) const {\n  if (vhsaKmtDeregisterMemory(ptr) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::AvailableMemory(uint32_t node_id, uint64_t* available_size) const {\n  assert(available_size != nullptr);\n\n  if (vhsaKmtAvailableMemory(node_id, available_size) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::MakeMemoryResident(const void* mem, size_t size,\n                                                 uint64_t* alternate_va,\n                                                 const HsaMemMapFlags* mem_flags,\n                                                 uint32_t num_nodes, const uint32_t* nodes) const {\n  assert(mem != nullptr);\n  assert(size != 0);\n\n  if (mem_flags == nullptr && nodes == nullptr) {\n    if (vhsaKmtMapMemoryToGPU(const_cast<void*>(mem), size, alternate_va) != HSAKMT_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n  } else if (mem_flags != nullptr && nodes != nullptr) {\n    if (vhsaKmtMapMemoryToGPUNodes(const_cast<void*>(mem), size, alternate_va, *mem_flags,\n                                   num_nodes,\n                                   const_cast<uint32_t*>(nodes)) != HSAKMT_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n  } else {\n    debug_print(\"Invalid memory flags ptr:%p nodes ptr:%p\\n\", mem_flags, nodes);\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::MakeMemoryUnresident(const void* mem) const {\n  vhsaKmtUnmapMemoryToGPU(const_cast<void*>(mem));\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                                          HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id,\n                                          void* queue_addr, uint64_t queue_size_bytes,\n                                          HsaEvent* event, HsaQueueResource& queue_resource) const {\n  if (vhsaKmtCreateQueueExt(node_id, type, queue_pct, priority, sdma_engine_id, queue_addr,\n                            queue_size_bytes, event, &queue_resource) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::DestroyQueue(HSA_QUEUEID queue_id) const {\n  if (vhsaKmtDestroyQueue(queue_id) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_percentage,\n                                          HSA_QUEUE_PRIORITY priority, void* queue_mem,\n                                          uint64_t queue_size, HsaEvent* event) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t num_cu_mask,\n                                             uint32_t* cu_mask) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_GWS,\n                                            uint32_t* GWS) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::ExportDMABuf(void* mem, size_t size, int* dmabuf_fd, size_t* offset) {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::ImportDMABuf(int dmabuf_fd, core::Agent& agent,\n                                           core::ShareableHandle& handle) {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::Map(core::ShareableHandle handle, void* mem, size_t offset,\n                                  size_t size, hsa_access_permission_t perms) {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::Unmap(core::ShareableHandle handle, void* mem, size_t offset,\n                                    size_t size) {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::ReleaseShareableHandle(core::ShareableHandle& handle) {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t KfdVirtioDriver::GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const {\n  if (vhsaKmtGetTileConfig(node_id, config) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::SPMAcquire(uint32_t node_id) const { return HSA_STATUS_ERROR; }\n\nhsa_status_t KfdVirtioDriver::SPMRelease(uint32_t node_id) const { return HSA_STATUS_ERROR; }\n\nhsa_status_t KfdVirtioDriver::SPMSetDestBuffer(uint32_t node_id, uint32_t size, uint32_t* timeout,\n                                               uint32_t* size_copied, void* dest,\n                                               bool* is_data_loss) const {\n  return HSA_STATUS_ERROR;\n}\n\n\nhsa_status_t KfdVirtioDriver::OpenSMI(uint32_t node_id, int* fd) const { return HSA_STATUS_ERROR; }\n\nhsa_status_t KfdVirtioDriver::GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const {\n  assert(frequency != nullptr);\n\n  amdgpu_gpu_info info;\n  amdgpu_device_handle handle;\n  if (GetDeviceHandle(node_id, reinterpret_cast<void**>(&handle)) != HSA_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  if (vamdgpu_query_gpu_info(handle, &info) < 0) return HSA_STATUS_ERROR;\n\n  // Reported by libdrm in KHz.\n  *frequency = uint64_t(info.gpu_counter_freq) * 1000ull;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t KfdVirtioDriver::IsModelEnabled(bool* enable) const {\n  *enable = false;\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace AMD\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/driver/xdna/amd_xdna_driver.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_xdna_driver.h\"\n\n#include <fcntl.h>\n#include <sys/ioctl.h>\n#include <sys/mman.h>\n#include <unistd.h>\n\n#include <memory>\n#include <string>\n\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/util/memory.h\"\n#include \"core/util/utils.h\"\n#include \"uapi/amdxdna_accel.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nstatic_assert((sizeof(core::ShareableHandle::handle) >= sizeof(uint32_t)) &&\n                  (alignof(core::ShareableHandle::handle) >= alignof(uint32_t)),\n              \"ShareableHandle cannot store a XDNA handle\");\n\n/// @brief Index of the first operand in a command.\n///\n/// Before the operands there are:\n/// - 2 dwords for transaction op code\n/// - 2 dwords for the instructions BO address\n/// - 1 dword for the size of the instructions BO size\nconstexpr uint32_t operand_starting_index = 5;\n\n/// @brief Default amdxdna_cu_config::cu_func when configuring a CU.\nconstexpr uint32_t default_cu_func = 0;\n\n/// @brief Calculates the number of operands in a packet given the number of arguments in the\n///        packet.\n///\n/// Each operand is 3 dwords (hi, lo address, and size). The op code is not counted in @p arg_count\n/// but the instructions are.\n///\n/// @param arg_count number of arguments in the packet\n/// @return number of operands in the packet\nconstexpr uint32_t GetOperandCount(uint32_t arg_count) { return (arg_count / 3) - 1; }\n\n/// @brief Flushes operands.\nstatic void FlushOperands(uint32_t count, hsa_amd_aie_ert_start_kernel_data_t* cmd_pkt_payload) {\n  // Going through all of the operands in the command and flushing them.\n  const uint32_t num_operands = GetOperandCount(count);\n  for (uint32_t operand_iter = 0; operand_iter < num_operands; operand_iter++) {\n    const uint32_t operand_index = operand_starting_index + 2 * operand_iter;\n    const uint64_t operand_addr = Concat<uint64_t>(cmd_pkt_payload->data[operand_index + 1],\n                                                   cmd_pkt_payload->data[operand_index]);\n    const uint32_t operand_size_starting_index = operand_starting_index + 2 * num_operands;\n    const uint32_t operand_bo_size =\n        cmd_pkt_payload->data[operand_size_starting_index + operand_iter];\n    FlushCpuCache(reinterpret_cast<void*>(operand_addr), 0, operand_bo_size);\n  }\n}\n\nXdnaDriver::XdnaDriver(std::string devnode_name)\n    : core::Driver(core::DriverType::XDNA, std::move(devnode_name)) {}\n\nhsa_status_t XdnaDriver::DiscoverDriver(std::unique_ptr<core::Driver>& driver) {\n  const int max_minor_num(64);\n  static const std::string devnode_prefix(\"/dev/accel/accel\");\n\n  for (int i = 0; i < max_minor_num; ++i) {\n    auto tmp_driver = std::unique_ptr<Driver>(new XdnaDriver(devnode_prefix + std::to_string(i)));\n    if (tmp_driver->Open() == HSA_STATUS_SUCCESS) {\n      if (tmp_driver->QueryKernelModeDriver(core::DriverQuery::GET_DRIVER_VERSION) ==\n          HSA_STATUS_SUCCESS) {\n        driver = std::move(tmp_driver);\n        return HSA_STATUS_SUCCESS;\n      } else {\n        tmp_driver->Close();\n      }\n    }\n  }\n\n  return HSA_STATUS_ERROR;\n}\n\nuint64_t XdnaDriver::GetSystemMemoryByteSize() {\n  const long pagesize = sysconf(_SC_PAGESIZE);\n  const long page_count = sysconf(_SC_PHYS_PAGES);\n  return pagesize * page_count;\n}\n\nuint64_t XdnaDriver::GetDevHeapByteSize() {\n  return dev_heap_size;\n}\n\nhsa_status_t XdnaDriver::Init() { return InitDeviceHeap(); }\n\nhsa_status_t XdnaDriver::ShutDown() { return FreeDeviceHeap(); }\n\nhsa_status_t XdnaDriver::QueryKernelModeDriver(core::DriverQuery query) {\n  switch (query) {\n  case core::DriverQuery::GET_DRIVER_VERSION:\n    return QueryDriverVersion();\n  default:\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n}\n\nhsa_status_t XdnaDriver::Open() {\n  fd_ = open(devnode_name_.c_str(), O_RDWR | O_CLOEXEC);\n  if (fd_ < 0) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::Close() {\n  int ret(0);\n  if (fd_ > 0) {\n    ret = close(fd_);\n    fd_ = -1;\n  }\n  if (ret) {\n    return HSA_STATUS_ERROR;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::GetSystemProperties(HsaSystemProperties& sys_props) const {\n  sys_props.NumNodes = 1;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const {\n  amdxdna_drm_query_aie_metadata aie_metadata = {};\n  amdxdna_drm_get_info get_info_args = {};\n  get_info_args.param = DRM_AMDXDNA_QUERY_AIE_METADATA;\n  get_info_args.buffer_size = sizeof(aie_metadata);\n  get_info_args.buffer = reinterpret_cast<uintptr_t>(&aie_metadata);\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_GET_INFO, &get_info_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // Right now can only target N-1 columns as that is the number of shim DMAs\n  // in NPU1 devices.\n  node_props.NumNeuralCores = (aie_metadata.cols - 1) * aie_metadata.core.row_count;\n  /// @todo XDNA driver currently only supports single-node AIE\n  /// devices over PCIe. Update this once we can get topology\n  /// information dynamically from the sysfs.\n  node_props.NumIOLinks = 0;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                           uint32_t node_id) const {\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::GetMemoryProperties(uint32_t node_id,\n                                             std::vector<HsaMemoryProperties>& mem_props) const {\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                            std::vector<HsaCacheProperties>& cache_props) const {\n  // AIE currently has no caches.\n  return HSA_STATUS_ERROR_INVALID_CACHE;\n}\n\nhsa_status_t\nXdnaDriver::AllocateMemory(const core::MemoryRegion &mem_region,\n                           core::MemoryRegion::AllocateFlags alloc_flags,\n                           void **mem, size_t size, uint32_t node_id) {\n  const MemoryRegion& m_region = static_cast<const MemoryRegion&>(mem_region);\n\n  if (!m_region.IsSystem()) {\n    return HSA_STATUS_ERROR_INVALID_REGION;\n  }\n\n  amdxdna_drm_create_bo create_bo_args = {};\n  create_bo_args.size = size;\n  const bool use_bo_shmem = !m_region.IsDeviceSVM();\n  if (use_bo_shmem) {\n    create_bo_args.type = AMDXDNA_BO_SHMEM;\n  } else {\n    create_bo_args.type = AMDXDNA_BO_DEV;\n  }\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_CREATE_BO, &create_bo_args) < 0) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  BOHandle bo_handle;\n  bo_handle.handle = create_bo_args.handle;\n  bo_handle.size = size;\n\n  // Close the BO in case of error.\n  MAKE_NAMED_SCOPE_GUARD(bo_guard, [&] { DestroyBOHandle(bo_handle); });\n\n  amdxdna_drm_get_bo_info get_bo_info_args = {};\n  get_bo_info_args.handle = create_bo_args.handle;\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_GET_BO_INFO, &get_bo_info_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  /// TODO: For now we always map the memory and keep a mapping from handles\n  /// to VA memory addresses. Once we can support the separate VMEM call to\n  /// map handles we can fix this.\n  if (use_bo_shmem) {\n    bo_handle.vaddr =\n        mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, get_bo_info_args.map_offset);\n    if (bo_handle.vaddr == MAP_FAILED) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  } else {\n    bo_handle.vaddr = reinterpret_cast<void*>(get_bo_info_args.vaddr);\n  }\n\n  if (alloc_flags & core::MemoryRegion::AllocateMemoryOnly) {\n    *mem = reinterpret_cast<void *>(create_bo_args.handle);\n  } else {\n    *mem = bo_handle.vaddr;\n  }\n\n  vmem_handle_mappings.emplace(bo_handle.handle, bo_handle.vaddr);\n  vmem_addr_mappings.emplace(bo_handle.vaddr, bo_handle);\n\n  bo_guard.Dismiss();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::FreeMemory(void *mem, size_t size) {\n  auto it = vmem_addr_mappings.find(mem);\n  if (it == vmem_addr_mappings.end()) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  auto handle = it->second.handle;\n\n  drm_gem_close close_args = {};\n  close_args.handle = handle;\n  if (ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  vmem_handle_mappings.erase(handle);\n  vmem_addr_mappings.erase(it);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                                     HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id,\n                                     void* queue_addr, uint64_t queue_size_bytes, HsaEvent* event,\n                                     HsaQueueResource& queue_resource) const {\n  queue_resource.QueueId = AMDXDNA_INVALID_CTX_HANDLE;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::DestroyQueue(HSA_QUEUEID queue_id) const {\n  if (queue_id == AMDXDNA_INVALID_CTX_HANDLE) {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  auto hw_ctx_handle = static_cast<uint32_t>(queue_id);\n  amdxdna_drm_destroy_hwctx destroy_hwctx_args = {};\n  destroy_hwctx_args.handle = hw_ctx_handle;\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_DESTROY_HWCTX, &destroy_hwctx_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_pct,\n                                     HSA_QUEUE_PRIORITY priority, void* queue_addr,\n                                     uint64_t queue_size, HsaEvent* event) const {\n  // AIE doesn't support queue updates.\n  return HSA_STATUS_ERROR_INVALID_QUEUE;\n}\n\nhsa_status_t XdnaDriver::SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t cu_mask_count,\n                                        uint32_t* queue_cu_mask) const {\n  // AIE doesn't support queue CU masks.\n  return HSA_STATUS_ERROR_INVALID_QUEUE;\n}\n\nhsa_status_t XdnaDriver::AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_gws,\n                                       uint32_t* first_gws) const {\n  // AIE doesn't support GWS.\n  return HSA_STATUS_ERROR_INVALID_QUEUE;\n}\n\nhsa_status_t XdnaDriver::ExportDMABuf(void* mem, size_t size, int* dmabuf_fd, size_t* offset) {\n  auto bo_handle = FindBOHandle(mem);\n  if (!bo_handle.IsValid()) {\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  drm_prime_handle export_params = {};\n  export_params.handle = bo_handle.handle;\n  export_params.flags = DRM_RDWR;\n  export_params.fd = -1;\n  if (ioctl(fd_, DRM_IOCTL_PRIME_HANDLE_TO_FD, &export_params) < 0) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  *dmabuf_fd = export_params.fd;\n  *offset = reinterpret_cast<uintptr_t>(mem) - reinterpret_cast<uintptr_t>(bo_handle.vaddr);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::ImportDMABuf(int dmabuf_fd, core::Agent &agent,\n                                      core::ShareableHandle &handle) {\n  drm_prime_handle import_params = {};\n  import_params.handle = AMDXDNA_INVALID_BO_HANDLE;\n  import_params.fd = dmabuf_fd;\n  if (ioctl(fd_, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_params) < 0)\n    return HSA_STATUS_ERROR;\n\n  handle.handle = import_params.handle;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::Map(core::ShareableHandle handle, void *mem,\n                             size_t offset, size_t size,\n                             hsa_access_permission_t perms) {\n  // Get fd associated with the handle.\n  drm_prime_handle params = {};\n  params.handle = handle.handle;\n  params.fd = -1;\n  if (ioctl(fd_, DRM_IOCTL_PRIME_HANDLE_TO_FD, &params) < 0)\n    return HSA_STATUS_ERROR;\n\n  // Change permissions.\n  void *mapped_ptr = mmap(mem, size, PermissionsToMmapFlags(perms),\n                          MAP_FIXED | MAP_SHARED, params.fd, offset);\n  if (mapped_ptr == MAP_FAILED)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::Unmap(core::ShareableHandle handle, void *mem,\n                               size_t offset, size_t size) {\n  if (munmap(mem, size) != 0)\n    return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::ReleaseShareableHandle(core::ShareableHandle &handle) {\n  drm_gem_close close_params = {};\n  close_params.handle = handle.handle;\n  if (ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_params) < 0)\n    return HSA_STATUS_ERROR;\n\n  handle = {};\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::QueryDriverVersion() {\n  amdxdna_drm_query_aie_version aie_version{0, 0};\n  amdxdna_drm_get_info args{DRM_AMDXDNA_QUERY_AIE_VERSION, sizeof(aie_version),\n                            reinterpret_cast<uintptr_t>(&aie_version)};\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_GET_INFO, &args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  version_.KernelInterfaceMajorVersion = aie_version.major;\n  version_.KernelInterfaceMinorVersion = aie_version.minor;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::InitDeviceHeap() {\n  amdxdna_drm_create_bo create_bo_args = {};\n  create_bo_args.size = dev_heap_size;\n  create_bo_args.type = AMDXDNA_BO_DEV_HEAP;\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_CREATE_BO, &create_bo_args) < 0) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  dev_heap_handle.handle = create_bo_args.handle;\n\n  // Unmap memory and close the BO in case of error.\n  MAKE_NAMED_SCOPE_GUARD(dev_heap_handle_guard, [&] { DestroyBOHandle(dev_heap_handle); });\n\n  amdxdna_drm_get_bo_info get_bo_info_args = {};\n  get_bo_info_args.handle = dev_heap_handle.handle;\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_GET_BO_INFO, &get_bo_info_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  const size_t size = dev_heap_align * 2 - 1;\n  dev_heap_handle.vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);\n  if (dev_heap_handle.vaddr == MAP_FAILED) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  dev_heap_handle.size = size;\n\n  void* addr_aligned = reinterpret_cast<void*>(\n      AlignUp(reinterpret_cast<uintptr_t>(dev_heap_handle.vaddr), dev_heap_align));\n\n  dev_heap_aligned =\n      mmap(addr_aligned, dev_heap_size, PROT_READ | PROT_WRITE,\n           MAP_SHARED | MAP_FIXED, fd_, get_bo_info_args.map_offset);\n  if (dev_heap_aligned == MAP_FAILED) {\n    dev_heap_aligned = nullptr;\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  dev_heap_handle_guard.Dismiss();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::FreeDeviceHeap() {\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n\n  if (dev_heap_aligned) {\n    if (munmap(dev_heap_aligned, dev_heap_size) != 0) {\n      status = HSA_STATUS_ERROR;\n    }\n    dev_heap_aligned = nullptr;\n  }\n\n  if (dev_heap_handle.IsValid()) {\n    if (munmap(dev_heap_handle.vaddr, dev_heap_handle.size) != 0) {\n      status = HSA_STATUS_ERROR;\n    }\n    drm_gem_close close_bo_args = {};\n    close_bo_args.handle = dev_heap_handle.handle;\n    ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_bo_args);\n    dev_heap_handle = BOHandle{};\n  }\n\n  return status;\n}\n\nhsa_status_t XdnaDriver::ExecCmdAndWait(const BOHandle& cmd_chain_bo_handle,\n                                        const std::vector<uint32_t>& bo_handles,\n                                        HSA_QUEUEID queue_id) {\n  if (queue_id == AMDXDNA_INVALID_CTX_HANDLE) {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  auto hw_ctx_handle = static_cast<uint32_t>(queue_id);\n  // Submit command chain.\n  amdxdna_drm_exec_cmd exec_cmd = {};\n  exec_cmd.hwctx = hw_ctx_handle;\n  exec_cmd.type = AMDXDNA_CMD_SUBMIT_EXEC_BUF;\n  exec_cmd.cmd_handles = cmd_chain_bo_handle.handle;\n  exec_cmd.args = reinterpret_cast<uint64_t>(bo_handles.data());\n  exec_cmd.cmd_count = 1;\n  exec_cmd.arg_count = bo_handles.size();\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_EXEC_CMD, &exec_cmd) < 0) return HSA_STATUS_ERROR;\n\n  // Waiting for command chain to finish.\n  amdxdna_drm_wait_cmd wait_cmd = {};\n  wait_cmd.hwctx = hw_ctx_handle;\n  wait_cmd.timeout = DEFAULT_TIMEOUT_VAL;\n  wait_cmd.seq = exec_cmd.seq;\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_WAIT_CMD, &wait_cmd) < 0) return HSA_STATUS_ERROR;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::PrepareBOs(uint32_t count,\n                                    hsa_amd_aie_ert_start_kernel_data_t* cmd_pkt_payload,\n                                    std::vector<uint32_t>& bo_handles) {\n  const uint64_t instr_addr =\n      Concat<uint64_t>(cmd_pkt_payload->data[CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_IDX + 1],\n                       cmd_pkt_payload->data[CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_IDX]);\n  auto instr_bo_handle = FindBOHandle(reinterpret_cast<void*>(instr_addr));\n  if (!instr_bo_handle.IsValid()) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // Keep track of the instruction sequence BO.\n  bo_handles.push_back(instr_bo_handle.handle);\n\n  // Flush the instruction sequence. The packet contains the number of instructions.\n  const uint32_t instr_bo_size =\n      cmd_pkt_payload->data[CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_SIZE_IDX] * INSTR_SIZE_BYTES;\n  FlushCpuCache(reinterpret_cast<void*>(instr_addr), 0, instr_bo_size);\n\n  // Going through all of the operands in the command, keeping track of the\n  // addresses and turning the addresses into handles. The starting index of\n  // the operands in a command is `operand_starting_index` and the fields\n  // are 32-bits we need to iterate over every two\n  const uint32_t num_operands = GetOperandCount(count);\n  bo_handles.reserve(num_operands);\n  for (uint32_t operand_iter = 0; operand_iter < num_operands; operand_iter++) {\n    const uint32_t operand_index = operand_starting_index + 2 * operand_iter;\n    const uint64_t operand_addr = Concat<uint64_t>(cmd_pkt_payload->data[operand_index + 1],\n                                                   cmd_pkt_payload->data[operand_index]);\n    auto operand_bo_handle = FindBOHandle(reinterpret_cast<void*>(operand_addr));\n    if (!operand_bo_handle.IsValid()) {\n      return HSA_STATUS_ERROR;\n    }\n\n    // Keep track of the operand BO.\n    bo_handles.push_back(operand_bo_handle.handle);\n\n    // Flush the operand.\n    const uint32_t operand_size_starting_index = operand_starting_index + 2 * num_operands;\n    const uint32_t operand_bo_size =\n        cmd_pkt_payload->data[operand_size_starting_index + operand_iter];\n    FlushCpuCache(reinterpret_cast<void*>(operand_addr), 0, operand_bo_size);\n  }\n\n  // Transform the instruction sequence address into device address\n  cmd_pkt_payload->data[CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_IDX] =\n      DEV_ADDR_BASE | (instr_addr & DEV_ADDR_OFFSET_MASK);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::CreateCmdBO(uint32_t size, BOHandle& cmd_bo_handle) {\n  amdxdna_drm_create_bo create_cmd_bo = {};\n  create_cmd_bo.type = AMDXDNA_BO_CMD;\n  create_cmd_bo.size = size;\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_CREATE_BO, &create_cmd_bo) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // Close the BO in case of error.\n  MAKE_NAMED_SCOPE_GUARD(cmd_bo_handle_guard, [&] {\n    drm_gem_close close_bo_args = {};\n    close_bo_args.handle = create_cmd_bo.handle;\n    ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_bo_args);\n  });\n\n  amdxdna_drm_get_bo_info cmd_bo_get_bo_info = {};\n  cmd_bo_get_bo_info.handle = create_cmd_bo.handle;\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_GET_BO_INFO, &cmd_bo_get_bo_info) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  void* mem = static_cast<amdxdna_cmd*>(mmap(nullptr, create_cmd_bo.size, PROT_READ | PROT_WRITE,\n                                             MAP_SHARED, fd_, cmd_bo_get_bo_info.map_offset));\n  if (mem == MAP_FAILED) {\n    return HSA_STATUS_ERROR;\n  }\n\n  cmd_bo_handle = BOHandle{mem, create_cmd_bo.handle, size};\n\n  cmd_bo_handle_guard.Dismiss();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::SubmitCmdChain(hsa_amd_aie_ert_packet_t* first_pkt, uint32_t num_pkts,\n                                        HSA_QUEUEID& queue_id, uint32_t num_core_tiles) {\n  // Stores instruction and operand BOs.\n  std::vector<uint32_t> bo_handles;\n\n  // Stores commands that we are going to submit and the corresponding metadata.\n  std::vector<BOHandle> cmd_bo_handles;\n  cmd_bo_handles.reserve(num_pkts);\n  // Unmap and close the command BOs in case of an error.\n  MAKE_NAMED_SCOPE_GUARD(cmd_bo_handles_guard, [&] {\n    for (auto& bo_handle : cmd_bo_handles) {\n      DestroyBOHandle(bo_handle);\n    }\n  });\n\n  auto hw_ctx_handle = static_cast<uint32_t>(queue_id);\n  // PDI cache. If the cache is updated, a new hardware context will be created for the queue.\n  auto pdi_cache_it = hw_ctx_pdi_cache_map.find(hw_ctx_handle);\n  auto pdi_cache = (pdi_cache_it != hw_ctx_pdi_cache_map.end()) ? pdi_cache_it->second : PDICache{};\n  bool reconfigure_queue = false;\n\n  // Iterating over all the contiguous HSA_AMD_AIE_ERT_CMD_CHAIN packets\n  for (uint32_t pkt_iter = 0; pkt_iter < num_pkts; pkt_iter++) {\n    // Getting the current command packet\n    hsa_amd_aie_ert_packet_t* pkt = first_pkt + pkt_iter;\n    hsa_amd_aie_ert_start_kernel_data_t* cmd_pkt_payload =\n        reinterpret_cast<hsa_amd_aie_ert_start_kernel_data_t*>(pkt->payload_data);\n\n    // Add the handles for all of the BOs to bo_handles as well as rewrite\n    // the instruction handle to contain the device address\n    hsa_status_t status = PrepareBOs(pkt->count, cmd_pkt_payload, bo_handles);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n\n    // Creating a packet that contains the command to execute the kernel\n    const uint32_t cmd_size = sizeof(amdxdna_cmd) + pkt->count * sizeof(uint32_t);\n    BOHandle cmd_bo_handle;\n    status = CreateCmdBO(cmd_size, cmd_bo_handle);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n    // Unmap and close the command BO in case of an error.\n    MAKE_NAMED_SCOPE_GUARD(cmd_bo_handle_guard, [&] { DestroyBOHandle(cmd_bo_handle); });\n\n    auto* cmd = static_cast<amdxdna_cmd*>(cmd_bo_handle.vaddr);\n\n    // Filling in the fields of the command\n    cmd->state = pkt->state;\n    cmd->extra_cu_masks = 0;\n\n    // The driver places a structure before each command in a command chain.\n    // Need to increase the size of the command by the size of this structure.\n    cmd->count = pkt->count + CMD_COUNT_SIZE_INCREASE;\n    cmd->opcode = pkt->opcode;\n\n    // Find if the PDI is cached in the queues PDI cache. If even one PDI is not found, the hardware\n    // context will need to be reconfigured and the cache updated.\n    auto pdi_bo_handle = FindBOHandle(cmd_pkt_payload->pdi_addr);\n    if (!pdi_bo_handle.IsValid()) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n    // Determine if the PDI is cached, if not it will be added to the PDI cache.\n    auto cached_pdi_index = pdi_cache.GetIndex(pdi_bo_handle.handle);\n    if (cached_pdi_index == PDICache::NotFound) {\n      FlushCpuCache(pdi_bo_handle.vaddr, 0, pdi_bo_handle.size);\n      status = pdi_cache.SetNext(pdi_bo_handle, cached_pdi_index);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n      reconfigure_queue = true;\n    }\n\n    cmd->data[0] = 0x1 << static_cast<uint32_t>(cached_pdi_index);\n    memcpy((cmd->data + 1), cmd_pkt_payload->data, 4 * pkt->count);\n\n    // Keeping track of the command\n    cmd_bo_handles.push_back(cmd_bo_handle);\n    cmd_bo_handle_guard.Dismiss();\n  }\n\n  // If there were PDIs that were not cached, the hardware context needs to be reconfigured.\n  // The cache map will be update with the new hardware context.\n  if (reconfigure_queue) {\n    if (pdi_cache_it != hw_ctx_pdi_cache_map.end()) {\n      hw_ctx_pdi_cache_map.erase(pdi_cache_it);\n    }\n\n    hsa_status_t status = ConfigHwCtx(pdi_cache, queue_id, num_core_tiles);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n\n    // Update cache mapping.\n    hw_ctx_pdi_cache_map.emplace(hw_ctx_handle, pdi_cache);\n  }\n\n  // Creating a packet that contains the command chain\n  const uint32_t cmd_chain_size = (cmd_bo_handles.size() + 1) * sizeof(uint32_t);\n  BOHandle cmd_chain_bo_handle;\n  hsa_status_t status = CreateCmdBO(cmd_chain_size, cmd_chain_bo_handle);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n  // Unmap and close the command chain BO in case of an error.\n  MAKE_NAMED_SCOPE_GUARD(cmd_chain_bo_handle_guard, [&] { DestroyBOHandle(cmd_chain_bo_handle); });\n\n  auto* cmd_chain = static_cast<amdxdna_cmd*>(cmd_chain_bo_handle.vaddr);\n\n  // Writing information to the command buffer\n  amdxdna_cmd_chain* cmd_chain_payload = reinterpret_cast<amdxdna_cmd_chain*>(cmd_chain->data);\n\n  // Creating a command chain\n  cmd_chain->state = HSA_AMD_AIE_ERT_STATE_NEW;\n  cmd_chain->extra_cu_masks = 0;\n  cmd_chain->count = sizeof(amdxdna_cmd_chain) + cmd_bo_handles.size() * sizeof(uint64_t);\n  cmd_chain->opcode = HSA_AMD_AIE_ERT_CMD_CHAIN;\n  cmd_chain_payload->command_count = cmd_bo_handles.size();\n  cmd_chain_payload->submit_index = 0;\n  cmd_chain_payload->error_index = 0;\n  for (size_t i = 0; i < cmd_bo_handles.size(); i++) {\n    cmd_chain_payload->data[i] = cmd_bo_handles[i].handle;\n  }\n\n  // Removing duplicates in the bo container. The driver will report\n  // an error if we provide the same BO handle multiple times.\n  // This can happen if any of the BOs are the same across jobs\n  std::sort(bo_handles.begin(), bo_handles.end());\n  bo_handles.erase(std::unique(bo_handles.begin(), bo_handles.end()), bo_handles.end());\n\n  // Executing all commands in the command chain\n  status = ExecCmdAndWait(cmd_chain_bo_handle, bo_handles, queue_id);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  for (uint32_t pkt_iter = 0; pkt_iter < num_pkts; pkt_iter++) {\n    hsa_amd_aie_ert_packet_t* pkt = first_pkt + pkt_iter;\n    auto* cmd_pkt_payload =\n        reinterpret_cast<hsa_amd_aie_ert_start_kernel_data_t*>(pkt->payload_data);\n    FlushOperands(pkt->count, cmd_pkt_payload);\n  }\n\n  // Unmapping and closing the cmd BOs\n  cmd_bo_handles_guard.Dismiss();\n  for (auto& command_bo_handle : cmd_bo_handles) {\n    if (munmap(command_bo_handle.vaddr, command_bo_handle.size) != 0) {\n      status = HSA_STATUS_ERROR;\n    }\n    drm_gem_close close_bo_args = {};\n    close_bo_args.handle = command_bo_handle.handle;\n    ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_bo_args);\n  }\n\n  // Unmapping and closing the cmd_chain BO\n  cmd_chain_bo_handle_guard.Dismiss();\n  if (munmap(cmd_chain, cmd_chain_size) != 0) {\n    status = HSA_STATUS_ERROR;\n  }\n  drm_gem_close close_bo_args = {};\n  close_bo_args.handle = cmd_chain_bo_handle.handle;\n  ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_bo_args);\n\n  return status;\n}\n\nhsa_status_t XdnaDriver::SPMAcquire(uint32_t preferred_node_id) const {\n  // AIE does not support streaming performance monitor.\n  return HSA_STATUS_ERROR_INVALID_AGENT;\n}\n\nhsa_status_t XdnaDriver::SPMRelease(uint32_t preferred_node_id) const {\n  // AIE does not support streaming performance monitor.\n  return HSA_STATUS_ERROR_INVALID_AGENT;\n};\n\nhsa_status_t XdnaDriver::SPMSetDestBuffer(uint32_t preferred_node_id, uint32_t size_bytes,\n                                          uint32_t* timeout, uint32_t* size_copied,\n                                          void* dest_mem_addr, bool* is_spm_data_loss) const {\n  // AIE does not support streaming performance monitor.\n  return HSA_STATUS_ERROR_INVALID_AGENT;\n}\n\nhsa_status_t XdnaDriver::IsModelEnabled(bool* enable) const {\n  // AIE does not support a driver model.\n  *enable = false;\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid XdnaDriver::DestroyBOHandle(BOHandle& handle) {\n  munmap(handle.vaddr, handle.size);\n  drm_gem_close close_bo_args = {};\n  close_bo_args.handle = handle.handle;\n  ioctl(fd_, DRM_IOCTL_GEM_CLOSE, &close_bo_args);\n  handle = {};\n}\n\nXdnaDriver::BOHandle XdnaDriver::FindBOHandle(void* mem) const {\n  auto it = vmem_addr_mappings.lower_bound(mem);\n  if (it == vmem_addr_mappings.cend()) {\n    // Exact address not found or is larger than the largest address.\n    return BOHandle{};\n  }\n\n  if (it->first == mem) {\n    // Exact address found.\n    return it->second;\n  }\n\n  if (it == vmem_addr_mappings.cbegin()) {\n    // Address is smaller than the smallest registered address.\n    return BOHandle{};\n  }\n\n  // Go back one element, since lower_bound returns an iterator to the element that is equal or\n  // greater.\n  --it;\n\n  assert(it->first < mem);\n  if (mem >= (static_cast<char*>(it->first) + it->second.size)) {\n    // Address is not from this allocation.\n    return BOHandle{};\n  }\n\n  return it->second;\n}\n\nhsa_status_t XdnaDriver::ConfigHwCtx(const PDICache& pdi_bo_handles, HSA_QUEUEID& queue_id,\n                                     uint32_t num_core_tiles) {\n  const size_t config_cu_param_size =\n      sizeof(amdxdna_hwctx_param_config_cu) + pdi_bo_handles.size() * sizeof(amdxdna_cu_config);\n\n  auto* xdna_config_cu_param =\n      static_cast<amdxdna_hwctx_param_config_cu*>(malloc(config_cu_param_size));\n  if (xdna_config_cu_param == nullptr) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  MAKE_SCOPE_GUARD([xdna_config_cu_param] { free(xdna_config_cu_param); });\n\n  xdna_config_cu_param->num_cus = pdi_bo_handles.size();\n\n  for (size_t i = 0; i < pdi_bo_handles.size(); i++) {\n    xdna_config_cu_param->cu_configs[i].cu_bo = pdi_bo_handles[i].handle;\n    xdna_config_cu_param->cu_configs[i].cu_func = default_cu_func;\n  }\n\n  auto hw_ctx_handle = static_cast<uint32_t>(queue_id);\n\n  if (hw_ctx_handle != AMDXDNA_INVALID_CTX_HANDLE) {\n    // Destroy the hardware context\n    // Note: we can do this because we have forced synchronization between\n    // command chains. If we move to a more asynchronous model, we will need to\n    // figure out how hardware context destruction works while applications\n    // are running\n    amdxdna_drm_destroy_hwctx destroy_hwctx_args = {};\n    destroy_hwctx_args.handle = hw_ctx_handle;\n    if (ioctl(fd_, DRM_IOCTL_AMDXDNA_DESTROY_HWCTX, &destroy_hwctx_args) < 0) {\n      return HSA_STATUS_ERROR;\n    }\n    queue_id = AMDXDNA_INVALID_CTX_HANDLE;\n  }\n\n  // Create the new hardware context\n  // Currently we do not leverage QoS information.\n  amdxdna_qos_info qos_info = {};\n  amdxdna_drm_create_hwctx create_hwctx_args = {};\n  create_hwctx_args.qos_p = reinterpret_cast<uintptr_t>(&qos_info);\n  create_hwctx_args.max_opc = 0x800;\n  create_hwctx_args.num_tiles = num_core_tiles;\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_CREATE_HWCTX, &create_hwctx_args) < 0) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  // Configure the new hardware context\n  amdxdna_drm_config_hwctx config_hw_ctx_args = {};\n  config_hw_ctx_args.handle = create_hwctx_args.handle;\n  config_hw_ctx_args.param_type = DRM_AMDXDNA_HWCTX_CONFIG_CU;\n  config_hw_ctx_args.param_val = reinterpret_cast<uint64_t>(xdna_config_cu_param);\n  config_hw_ctx_args.param_val_size = static_cast<uint32_t>(config_cu_param_size);\n\n  if (ioctl(fd_, DRM_IOCTL_AMDXDNA_CONFIG_HWCTX, &config_hw_ctx_args) < 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  queue_id = create_hwctx_args.handle;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t XdnaDriver::SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                                        const void* buffer_base, uint64_t buffer_base_size) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::GetDeviceHandle(uint32_t node_id, void** device_handle) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::GetClockCounters(uint32_t node_id, HsaClockCounters* clock_counter) const {\n  return HSA_STATUS_ERROR;\n}\n\n\nhsa_status_t XdnaDriver::GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::AvailableMemory(uint32_t node_id, uint64_t* available_size) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::DeregisterMemory(void* ptr) const { return HSA_STATUS_ERROR; }\n\nhsa_status_t XdnaDriver::MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                            const HsaMemMapFlags* mem_flags, uint32_t num_nodes,\n                                            const uint32_t* nodes) const {\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t XdnaDriver::MakeMemoryUnresident(const void* mem) const { return HSA_STATUS_ERROR; }\n\n} // namespace AMD\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/driver/xdna/uapi/amdxdna_accel.h",
    "content": "/* SPDX-License-Identifier: NCSA */\n/*\n * Copyright (C) 2022-2024, Advanced Micro Devices, Inc.\n */\n\n#ifndef AMDXDNA_ACCEL_H_\n#define AMDXDNA_ACCEL_H_\n\n#include <libdrm/drm.h>\n#include <linux/const.h>\n#include <linux/stddef.h>\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef __counted_by\n#define __counted_by(cnt)\n#endif\n\n#define AMDXDNA_DRIVER_MAJOR 1\n#define AMDXDNA_DRIVER_MINOR 0\n\n#define AMDXDNA_INVALID_ADDR (~0UL)\n#define AMDXDNA_INVALID_CTX_HANDLE 0\n#define AMDXDNA_INVALID_BO_HANDLE 0\n#define AMDXDNA_INVALID_FENCE_HANDLE 0\n\n/*\n * The interface can grow/extend over time.\n * On each struct amdxdna_drm_*, to support potential extension, we defined it\n * like this.\n *\n * Example code:\n *\n * struct amdxdna_drm_example_data {\n *\t.ext = (uintptr_t)&example_data_ext;\n *\t...\n * };\n *\n * We don't have extension now. The extension struct will define in the future.\n */\n\nenum amdxdna_drm_ioctl_id {\n  DRM_AMDXDNA_CREATE_HWCTX,\n  DRM_AMDXDNA_DESTROY_HWCTX,\n  DRM_AMDXDNA_CONFIG_HWCTX,\n  DRM_AMDXDNA_CREATE_BO,\n  DRM_AMDXDNA_GET_BO_INFO,\n  DRM_AMDXDNA_SYNC_BO,\n  DRM_AMDXDNA_EXEC_CMD,\n  DRM_AMDXDNA_GET_INFO,\n  DRM_AMDXDNA_SET_STATE,\n  DRM_AMDXDNA_WAIT_CMD,\n  DRM_AMDXDNA_NUM_IOCTLS\n};\n\nenum amdxdna_device_type {\n  AMDXDNA_DEV_TYPE_UNKNOWN = -1,\n  AMDXDNA_DEV_TYPE_KMQ,\n  AMDXDNA_DEV_TYPE_UMQ,\n};\n\n/**\n * struct qos_info - QoS information for driver.\n * @gops: Giga operations per second.\n * @fps: Frames per second.\n * @dma_bandwidth: DMA bandwidtha.\n * @latency: Frame response latency.\n * @frame_exec_time: Frame execution time.\n * @priority: Request priority.\n *\n * User program can provide QoS hints to driver.\n */\nstruct amdxdna_qos_info {\n  __u32 gops;\n  __u32 fps;\n  __u32 dma_bandwidth;\n  __u32 latency;\n  __u32 frame_exec_time;\n  __u32 priority;\n};\n\n/**\n * struct amdxdna_drm_create_hwctx - Create hardware context.\n * @ext: MBZ.\n * @ext_flags: MBZ.\n * @qos_p: Address of QoS info.\n * @umq_bo: BO handle for user mode queue(UMQ).\n * @log_buf_bo: BO handle for log buffer.\n * @max_opc: Maximum operations per cycle.\n * @num_tiles: Number of AIE tiles.\n * @mem_size: Size of AIE tile memory.\n * @umq_doorbell: Returned offset of doorbell associated with UMQ.\n * @handle: Returned hardware context handle.\n * @pad: Structure padding.\n */\nstruct amdxdna_drm_create_hwctx {\n  __u64 ext;\n  __u64 ext_flags;\n  __u64 qos_p;\n  __u32 umq_bo;\n  __u32 log_buf_bo;\n  __u32 max_opc;\n  __u32 num_tiles;\n  __u32 mem_size;\n  __u32 umq_doorbell;\n  __u32 handle;\n  __u32 pad;\n};\n\n/**\n * struct amdxdna_drm_destroy_hwctx - Destroy hardware context.\n * @handle: Hardware context handle.\n * @pad: Structure padding.\n */\nstruct amdxdna_drm_destroy_hwctx {\n  __u32 handle;\n  __u32 pad;\n};\n\n/**\n * struct amdxdna_cu_config - configuration for one CU\n * @cu_bo: CU configuration buffer bo handle.\n * @cu_func: Function of a CU.\n * @pad: Structure padding.\n */\nstruct amdxdna_cu_config {\n  __u32 cu_bo;\n  __u8 cu_func;\n  __u8 pad[3];\n};\n\n/**\n * struct amdxdna_hwctx_param_config_cu - configuration for CUs in hardware\n * context\n * @num_cus: Number of CUs to configure.\n * @pad: Structure padding.\n * @cu_configs: Array of CU configurations of struct amdxdna_cu_config.\n */\nstruct amdxdna_hwctx_param_config_cu {\n  __u16 num_cus;\n  __u16 pad[3];\n  struct amdxdna_cu_config cu_configs[] __counted_by(num_cus);\n};\n\nenum amdxdna_drm_config_hwctx_param {\n  DRM_AMDXDNA_HWCTX_CONFIG_CU,\n  DRM_AMDXDNA_HWCTX_ASSIGN_DBG_BUF,\n  DRM_AMDXDNA_HWCTX_REMOVE_DBG_BUF,\n  DRM_AMDXDNA_HWCTX_CONFIG_NUM\n};\n\n/**\n * struct amdxdna_drm_config_hwctx - Configure hardware context.\n * @handle: hardware context handle.\n * @param_type: Value in enum amdxdna_drm_config_hwctx_param. Specifies the\n *              structure passed in via param_val.\n * @param_val: A structure specified by the param_type struct member.\n * @param_val_size: Size of the parameter buffer pointed to by the param_val.\n *\t\t    If param_val is not a pointer, driver can ignore this.\n * @pad: Structure padding.\n *\n * Note: if the param_val is a pointer pointing to a buffer, the maximum size\n * of the buffer is 4KiB(PAGE_SIZE).\n */\nstruct amdxdna_drm_config_hwctx {\n  __u32 handle;\n  __u32 param_type;\n  __u64 param_val;\n  __u32 param_val_size;\n  __u32 pad;\n};\n\n/*\n * AMDXDNA_BO_SHMEM:\tDRM GEM SHMEM bo\n * AMDXDNA_BO_DEV_HEAP: Shared host memory to device as heap memory\n * AMDXDNA_BO_DEV_BO:\tAllocated from BO_DEV_HEAP\n * AMDXDNA_BO_CMD:\tUser and driver accessible bo\n * AMDXDNA_BO_DMA:\tDRM GEM DMA bo\n */\nenum amdxdna_bo_type {\n  AMDXDNA_BO_INVALID = 0,\n  AMDXDNA_BO_SHMEM,\n  AMDXDNA_BO_DEV_HEAP,\n  AMDXDNA_BO_DEV,\n  AMDXDNA_BO_CMD,\n  AMDXDNA_BO_DMA,\n};\n\n/**\n * struct amdxdna_drm_create_bo - Create a buffer object.\n * @flags: Buffer flags. MBZ.\n * @vaddr: User VA of buffer if applied. MBZ.\n * @size: Size in bytes.\n * @type: Buffer type.\n * @handle: Returned DRM buffer object handle.\n */\nstruct amdxdna_drm_create_bo {\n  __u64 flags;\n  __u64 vaddr;\n  __u64 size;\n  __u32 type;\n  __u32 handle;\n};\n\n/**\n * struct amdxdna_drm_get_bo_info - Get buffer object information.\n * @ext: MBZ.\n * @ext_flags: MBZ.\n * @handle: DRM buffer object handle.\n * @pad: Structure padding.\n * @map_offset: Returned DRM fake offset for mmap().\n * @vaddr: Returned user VA of buffer. 0 in case user needs mmap().\n * @xdna_addr: Returned XDNA device virtual address.\n */\nstruct amdxdna_drm_get_bo_info {\n  __u64 ext;\n  __u64 ext_flags;\n  __u32 handle;\n  __u32 pad;\n  __u64 map_offset;\n  __u64 vaddr;\n  __u64 xdna_addr;\n};\n\n/**\n * struct amdxdna_drm_sync_bo - Sync buffer object.\n * @handle: Buffer object handle.\n * @direction: Direction of sync, can be from device or to device.\n * @offset: Offset in the buffer to sync.\n * @size: Size in bytes.\n */\nstruct amdxdna_drm_sync_bo {\n  __u32 handle;\n#define SYNC_DIRECT_TO_DEVICE 0U\n#define SYNC_DIRECT_FROM_DEVICE 1U\n  __u32 direction;\n  __u64 offset;\n  __u64 size;\n};\n\nenum amdxdna_cmd_type {\n  AMDXDNA_CMD_SUBMIT_EXEC_BUF = 0,\n  AMDXDNA_CMD_SUBMIT_DEPENDENCY,\n  AMDXDNA_CMD_SUBMIT_SIGNAL,\n};\n\n/**\n * struct amdxdna_drm_exec_cmd - Execute command.\n * @ext: MBZ.\n * @ext_flags: MBZ.\n * @hwctx: Hardware context handle.\n * @type: One of command type in enum amdxdna_cmd_type.\n * @cmd_handles: Array of command handles or the command handle itself\n * in case of just one.\n * @args: Array of arguments for all command handles.\n * @cmd_count: Number of command handles in the cmd_handles array.\n * @arg_count: Number of arguments in the args array.\n * @seq: Returned sequence number for this command.\n */\nstruct amdxdna_drm_exec_cmd {\n  __u64 ext;\n  __u64 ext_flags;\n  __u32 hwctx;\n  __u32 type;\n  __u64 cmd_handles;\n  __u64 args;\n  __u32 cmd_count;\n  __u32 arg_count;\n  __u64 seq;\n};\n\n/**\n * struct amdxdna_drm_wait_cmd - Wait exectuion command.\n *\n * @hwctx: hardware context handle.\n * @timeout: timeout in ms, 0 implies infinite wait.\n * @seq: sequence number of the command returned by execute command.\n *\n * Wait a command specified by seq to be completed.\n */\nstruct amdxdna_drm_wait_cmd {\n  __u32 hwctx;\n  __u32 timeout;\n  __u64 seq;\n};\n\n/**\n * struct amdxdna_drm_query_aie_status - Query the status of the AIE hardware\n * @buffer: The user space buffer that will return the AIE status.\n * @buffer_size: The size of the user space buffer.\n * @cols_filled: A bitmap of AIE columns whose data has been returned in the buffer.\n */\nstruct amdxdna_drm_query_aie_status {\n  __u64 buffer;      /* out */\n  __u32 buffer_size; /* in */\n  __u32 cols_filled; /* out */\n};\n\n/**\n * struct amdxdna_drm_query_aie_version - Query the version of the AIE hardware\n * @major: The major version number.\n * @minor: The minor version number.\n */\nstruct amdxdna_drm_query_aie_version {\n  __u32 major; /* out */\n  __u32 minor; /* out */\n};\n\n/**\n * struct amdxdna_drm_query_aie_tile_metadata - Query the metadata of AIE tile\n * (core, mem, shim)\n * @row_count: The number of rows.\n * @row_start: The starting row number.\n * @dma_channel_count: The number of dma channels.\n * @lock_count: The number of locks.\n * @event_reg_count: The number of events.\n * @pad: Structure padding.\n */\nstruct amdxdna_drm_query_aie_tile_metadata {\n  __u16 row_count;\n  __u16 row_start;\n  __u16 dma_channel_count;\n  __u16 lock_count;\n  __u16 event_reg_count;\n  __u16 pad[3];\n};\n\n/**\n * struct amdxdna_drm_query_aie_metadata - Query the metadata of the AIE hardware\n * @col_size: The size of a column in bytes.\n * @cols: The total number of columns.\n * @rows: The total number of rows.\n * @version: The version of the AIE hardware.\n * @core: The metadata for all core tiles.\n * @mem: The metadata for all mem tiles.\n * @shim: The metadata for all shim tiles.\n */\nstruct amdxdna_drm_query_aie_metadata {\n  __u32 col_size;\n  __u16 cols;\n  __u16 rows;\n  struct amdxdna_drm_query_aie_version version;\n  struct amdxdna_drm_query_aie_tile_metadata core;\n  struct amdxdna_drm_query_aie_tile_metadata mem;\n  struct amdxdna_drm_query_aie_tile_metadata shim;\n};\n\n/**\n * struct amdxdna_drm_query_clock - Metadata for a clock\n * @name: The clock name.\n * @freq_mhz: The clock frequency.\n * @pad: Structure padding.\n */\nstruct amdxdna_drm_query_clock {\n  __u8 name[16];\n  __u32 freq_mhz;\n  __u32 pad;\n};\n\n/**\n * struct amdxdna_drm_query_clock_metadata - Query metadata for clocks\n * @mp_npu_clock: The metadata for MP-NPU clock.\n * @h_clock: The metadata for H clock.\n */\nstruct amdxdna_drm_query_clock_metadata {\n  struct amdxdna_drm_query_clock mp_npu_clock;\n  struct amdxdna_drm_query_clock h_clock;\n};\n\nenum amdxdna_sensor_type { AMDXDNA_SENSOR_TYPE_POWER };\n\n/**\n * struct amdxdna_drm_query_sensor - The data for single sensor.\n * @label: The name for a sensor.\n * @input: The current value of the sensor.\n * @max: The maximum value possible for the sensor.\n * @average: The average value of the sensor.\n * @highest: The highest recorded sensor value for this driver load for the sensor.\n * @status: The sensor status.\n * @units: The sensor units.\n * @unitm: Translates value member variables into the correct unit via (pow(10, unitm) * value).\n * @type: The sensor type from enum amdxdna_sensor_type.\n * @pad: Structure padding.\n */\nstruct amdxdna_drm_query_sensor {\n  __u8 label[64];\n  __u32 input;\n  __u32 max;\n  __u32 average;\n  __u32 highest;\n  __u8 status[64];\n  __u8 units[16];\n  __s8 unitm;\n  __u8 type;\n  __u8 pad[6];\n};\n\n/**\n * struct amdxdna_drm_query_hwctx - The data for single context.\n * @context_id: The ID for this context.\n * @start_col: The starting column for the partition assigned to this context.\n * @num_col: The number of columns in the partition assigned to this context.\n * @pad: Structure padding.\n * @pid: The Process ID of the process that created this context.\n * @command_submissions: The number of commands submitted to this context.\n * @command_completions: The number of commands completed by this context.\n * @migrations: The number of times this context has been moved to a different partition.\n * @preemptions: The number of times this context has been preempted by another context in the\n *               same partition.\n * @errors: The errors for this context.\n */\nstruct amdxdna_drm_query_hwctx {\n  __u32 context_id;\n  __u32 start_col;\n  __u32 num_col;\n  __u32 pad;\n  __s64 pid;\n  __u64 command_submissions;\n  __u64 command_completions;\n  __u64 migrations;\n  __u64 preemptions;\n  __u64 errors;\n};\n\n/**\n * struct amdxdna_drm_aie_mem - The data for AIE memory read/write\n * @col:   The AIE column index\n * @row:   The AIE row index\n * @addr:  The AIE memory address to read/write\n * @size:  The size of bytes to read/write\n * @buf_p: The buffer to store read/write data\n *\n * This is used for DRM_AMDXDNA_READ_AIE_MEM and DRM_AMDXDNA_WRITE_AIE_MEM\n * parameters.\n */\nstruct amdxdna_drm_aie_mem {\n  __u32 col;\n  __u32 row;\n  __u32 addr;\n  __u32 size;\n  __u64 buf_p;\n};\n\n/**\n * struct amdxdna_drm_aie_reg - The data for AIE register read/write\n * @col: The AIE column index\n * @row: The AIE row index\n * @addr: The AIE register address to read/write\n * @val: The value to write or returned value from AIE\n *\n * This is used for DRM_AMDXDNA_READ_AIE_REG and DRM_AMDXDNA_WRITE_AIE_REG\n * parameters.\n */\nstruct amdxdna_drm_aie_reg {\n  __u32 col;\n  __u32 row;\n  __u32 addr;\n  __u32 val;\n};\n\nenum amdxdna_power_mode_type {\n  POWER_MODE_DEFAULT, /**< Fallback to calculated DPM */\n  POWER_MODE_LOW,     /**< Set frequency to lowest DPM */\n  POWER_MODE_MEDIUM,  /**< Set frequency to medium DPM */\n  POWER_MODE_HIGH,    /**< Set frequency to highest DPM */\n  POWER_MODE_TURBO,   /**< More power, more performance */\n};\n\n/**\n * struct amdxdna_drm_get_power_mode - Get the power mode of the AIE hardware\n * @power_mode: The sensor type from enum amdxdna_power_mode_type\n * @pad: MBZ.\n */\nstruct amdxdna_drm_get_power_mode {\n  __u8 power_mode;\n  __u8 pad[7];\n};\n\n/**\n * struct amdxdna_drm_query_firmware_version - Query the version of the firmware\n * @major: The major version number\n * @minor: The minor version number\n * @patch: The patch level version number\n * @build: The build ID\n */\nstruct amdxdna_drm_query_firmware_version {\n  __u32 major; /* out */\n  __u32 minor; /* out */\n  __u32 patch; /* out */\n  __u32 build; /* out */\n};\n\nenum amdxdna_drm_get_param {\n  DRM_AMDXDNA_QUERY_AIE_STATUS,\n  DRM_AMDXDNA_QUERY_AIE_METADATA,\n  DRM_AMDXDNA_QUERY_AIE_VERSION,\n  DRM_AMDXDNA_QUERY_CLOCK_METADATA,\n  DRM_AMDXDNA_QUERY_SENSORS,\n  DRM_AMDXDNA_QUERY_HW_CONTEXTS,\n  DRM_AMDXDNA_READ_AIE_MEM,\n  DRM_AMDXDNA_READ_AIE_REG,\n  DRM_AMDXDNA_QUERY_FIRMWARE_VERSION,\n  DRM_AMDXDNA_GET_POWER_MODE,\n  DRM_AMDXDNA_QUERY_TELEMETRY,\n  DRM_AMDXDNA_NUM_GET_PARAM,\n};\n\n/**\n * struct amdxdna_drm_get_info - Get some information from the AIE hardware.\n * @param: Value in enum amdxdna_drm_get_param. Specifies the structure passed in the buffer.\n * @buffer_size: Size of the input buffer. Size needed/written by the kernel.\n * @buffer: A structure specified by the param struct member.\n */\nstruct amdxdna_drm_get_info {\n  __u32 param;       /* in */\n  __u32 buffer_size; /* in/out */\n  __u64 buffer;      /* in/out */\n};\n\n/**\n * struct amdxdna_drm_set_power_mode - Set the power mode of the AIE hardware\n * @power_mode: The sensor type from enum amdxdna_power_mode_type\n * @pad: MBZ.\n */\nstruct amdxdna_drm_set_power_mode {\n  __u8 power_mode;\n  __u8 pad[7];\n};\n\nenum amdxdna_drm_set_param {\n  DRM_AMDXDNA_SET_POWER_MODE,\n  DRM_AMDXDNA_WRITE_AIE_MEM,\n  DRM_AMDXDNA_WRITE_AIE_REG,\n  DRM_AMDXDNA_NUM_SET_PARAM,\n};\n\n/**\n * struct amdxdna_drm_set_state - Set the state of some component within the AIE hardware.\n * @param: Value in enum amdxdna_drm_set_param. Specifies the structure passed in the buffer.\n * @buffer_size: Size of the input buffer.\n * @buffer: A structure specified by the param struct member.\n */\nstruct amdxdna_drm_set_state {\n  __u32 param;       /* in */\n  __u32 buffer_size; /* in */\n  __u64 buffer;      /* in */\n};\n\n#define DRM_IOCTL_AMDXDNA_CREATE_HWCTX                                                             \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_CREATE_HWCTX, struct amdxdna_drm_create_hwctx)\n\n#define DRM_IOCTL_AMDXDNA_DESTROY_HWCTX                                                            \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_DESTROY_HWCTX, struct amdxdna_drm_destroy_hwctx)\n\n#define DRM_IOCTL_AMDXDNA_CONFIG_HWCTX                                                             \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_CONFIG_HWCTX, struct amdxdna_drm_config_hwctx)\n\n#define DRM_IOCTL_AMDXDNA_CREATE_BO                                                                \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_CREATE_BO, struct amdxdna_drm_create_bo)\n\n#define DRM_IOCTL_AMDXDNA_GET_BO_INFO                                                              \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_GET_BO_INFO, struct amdxdna_drm_get_bo_info)\n\n#define DRM_IOCTL_AMDXDNA_SYNC_BO                                                                  \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_SYNC_BO, struct amdxdna_drm_sync_bo)\n\n#define DRM_IOCTL_AMDXDNA_EXEC_CMD                                                                 \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_EXEC_CMD, struct amdxdna_drm_exec_cmd)\n\n#define DRM_IOCTL_AMDXDNA_WAIT_CMD                                                                 \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_WAIT_CMD, struct amdxdna_drm_wait_cmd)\n\n#define DRM_IOCTL_AMDXDNA_GET_INFO                                                                 \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_GET_INFO, struct amdxdna_drm_get_info)\n\n#define DRM_IOCTL_AMDXDNA_SET_STATE                                                                \\\n  DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDXDNA_SET_STATE, struct amdxdna_drm_set_state)\n\n#if defined(__cplusplus)\n} /* extern c end */\n#endif\n\n#endif /* AMDXDNA_ACCEL_H_ */\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/agent.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_AGENT_H_\n#define HSA_RUNTME_CORE_INC_AGENT_H_\n\n#include <assert.h>\n#include <vector>\n\n#include \"core/inc/checked.h\"\n#include \"core/inc/isa.h\"\n#include \"core/inc/memory_region.h\"\n#include \"core/inc/queue.h\"\n#include \"core/util/locks.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\n\n// Forward declare AMD::MemoryRegion\nnamespace AMD {\nclass MemoryRegion;\n}\n\nnamespace core {\nclass Driver;\nclass Signal;\n\ntypedef void (*HsaEventCallback)(hsa_status_t status, hsa_queue_t* source,\n                                 void* data);\n\n// Agent is intended to be an pure interface class and may be wrapped or\n// replaced by tools libraries. All funtions other than Convert, node_id,\n// device_type, and public_handle must be virtual.\nclass Agent : public Checked<0xF6BC25EB17E6F917> {\n  friend class rocr::AMD::MemoryRegion;\n\n public:\n  // @brief Convert agent object into hsa_agent_t.\n  //\n  // @param [in] agent Pointer to an agent.\n  //\n  // @retval hsa_agent_t\n  static __forceinline hsa_agent_t Convert(Agent* agent) {\n    const hsa_agent_t agent_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(agent))};\n    return agent_handle;\n  }\n\n  // @brief Convert agent object into const hsa_agent_t.\n  //\n  // @param [in] agent Pointer to an agent.\n  //\n  // @retval const hsa_agent_t\n  static __forceinline const hsa_agent_t Convert(const Agent* agent) {\n    const hsa_agent_t agent_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(agent))};\n    return agent_handle;\n  }\n\n  // @brief Convert hsa_agent_t handle into Agent*.\n  //\n  // @param [in] agent An hsa_agent_t handle.\n  //\n  // @retval Agent*\n  static __forceinline Agent* Convert(hsa_agent_t agent) {\n    return reinterpret_cast<Agent*>(agent.handle);\n  }\n\n  // Lightweight RTTI for vendor specific implementations.\n  enum DeviceType {\n    kAmdGpuDevice = 0,\n    kAmdCpuDevice = 1,\n    kAmdAieDevice = 2,\n    kUnknownDevice = 3\n  };\n\n  // @brief Agent class contructor.\n  //\n  // @param [in] type CPU or GPU or other.\n  explicit Agent(Driver &driver, uint32_t node_id, DeviceType type)\n      : node_id_(node_id), device_type_(uint32_t(type)), driver_(&driver),\n        profiling_enabled_(false), enabled_(false) {\n    public_handle_ = Convert(this);\n  }\n\n  // @brief Agent class destructor.\n  virtual ~Agent() {}\n\n  // @brief Submit DMA copy command to move data from src to dst and wait\n  // until it is finished.\n  //\n  // @details The agent must be able to access @p dst and @p src.\n  //\n  // @param [in] dst Memory address of the destination.\n  // @param [in] src Memory address of the source.\n  // @param [in] size Copy size in bytes.\n  //\n  // @retval HSA_STATUS_SUCCESS The memory copy is finished and successful.\n  virtual hsa_status_t DmaCopy(void* dst, const void* src, size_t size) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Submit DMA copy command to move data from src to dst. This call\n  // does not wait until the copy is finished\n  //\n  // @details The agent must be able to access @p dst and @p src. Memory copy\n  // will be performed after all signals in @p dep_signals have value of 0.\n  // On memory copy completion, the value of out_signal is decremented.\n  //\n  // @param [in] dst Memory address of the destination.\n  // @param [in] dst_agent Agent that owns the memory pool associated with @p\n  // dst.\n  // @param [in] src Memory address of the source.\n  // @param [in] src_agent Agent that owns the memory pool associated with @p\n  // src.\n  // @param [in] size Copy size in bytes.\n  // @param [in] dep_signals Array of signal dependency.\n  // @param [in] out_signal Completion signal.\n  //\n  // @retval HSA_STATUS_SUCCESS The memory copy is finished and successful.\n  virtual hsa_status_t DmaCopy(void* dst, core::Agent& dst_agent,\n                               const void* src, core::Agent& src_agent,\n                               size_t size,\n                               std::vector<core::Signal*>& dep_signals,\n                               core::Signal& out_signal) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Submit DMA copy command to move data from src to dst on engine_id.\n  // This call does not wait until the copy is finished\n  //\n  // @details All semantics and params are identical to DmaCopy except for engine_id.\n  //\n  // @param [in] engine_offset Target engine\n  // @param [in] force_copy_on_sdma By default, blit kernel copies are used if\n  // dst_agent == src_agent.  Setting this true forces the copy over SDMA1.\n  //\n  //\n  // @retval HSA_STATUS_SUCCESS The memory copy is finished and successful.\n  virtual hsa_status_t DmaCopyOnEngine(void* dst, core::Agent& dst_agent,\n                               const void* src, core::Agent& src_agent,\n                               size_t size,\n                               std::vector<core::Signal*>& dep_signals,\n                               core::Signal& out_signal,\n                               int engine_offset,\n                               bool force_copy_on_sdma) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Return DMA availability status for copy direction.\n  //\n  // @param [in] dst_agent Destination agent.\n  // @param [in] src_agent Source agent.\n  // @param [out] engine_ids_mask Mask of engine ids.\n  //\n  // @retval HSA_STATUS_SUCCESS DMA engines are available\n  // @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES DMA engines are not available\n  virtual hsa_status_t DmaCopyStatus(core::Agent& dst_agent, core::Agent& src_agent,\n                                     uint32_t *engine_ids_mask) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Return DMA availability status for copy direction.\n  //\n  // @param [in] dst_agent Destination agent.\n  // @param [in] src_agent Source agent.\n  // @param [out] recommended_ids_mask Mask of recommended engine ids.\n  //\n  // @retval HSA_STATUS_SUCCESS For mask returned\n  virtual hsa_status_t DmaPreferredEngine(core::Agent& dst_agent, core::Agent& src_agent,\n                                          uint32_t* recommended_ids_mask) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Submit DMA command to set the content of a pointer and wait\n  // until it is finished.\n  //\n  // @details The agent must be able to access @p ptr\n  //\n  // @param [in] ptr Address of the memory to be set.\n  // @param [in] value The value/pattern that will be used to set @p ptr.\n  // @param [in] count Number of uint32_t element to be set.\n  //\n  // @retval HSA_STATUS_SUCCESS The memory fill is finished and successful.\n  virtual hsa_status_t DmaFill(void* ptr, uint32_t value, size_t count) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // @brief Invoke the user provided callback for each region accessible by\n  // this agent.\n  //\n  // @param [in] callback User provided callback function.\n  // @param [in] data User provided pointer as input for @p callback.\n  //\n  // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  // region returns ::HSA_STATUS_SUCCESS.\n  virtual hsa_status_t IterateRegion(\n      hsa_status_t (*callback)(hsa_region_t region, void* data),\n      void* data) const = 0;\n\n  // @brief Invoke the user provided callback for each isa supported by\n  // this agent.\n  //\n  // @param [in] callback User provided callback function.\n  // @param [in] data User provided pointer as input for @p callback.\n  //\n  // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  // isa returns ::HSA_STATUS_SUCCESS.\n  virtual hsa_status_t IterateSupportedIsas(\n      hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n      void* data) const = 0;\n\n  // @brief Invoke the callback for each cache useable by this agent.\n  virtual hsa_status_t IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                                    void* data) const = 0;\n\n  /// @brief Create queue.\n  ///\n  /// @param [in] size Number of packets the queue is expected to hold. Must be a\n  /// power of 2 greater than 0.\n  /// @param [in] queue_type Queue type.\n  /// @param [in] flags Flags to specify queue attributes on creation.\n  /// @param [in] event_callback Callback invoked for every\n  /// asynchronous event related to the newly created queue. May be NULL.The HSA\n  /// runtime passes three arguments to the callback : a code identifying the\n  /// event that triggered the invocation, a pointer to the queue where the event\n  /// originated, and the application data.\n  /// @param [in] data Application data that is passed to @p callback.\n  /// @param [in] private_segment_size A hint to indicate the maximum expected\n  /// private segment usage per work-item, in bytes.\n  /// @param [in] group_segment_size A hint to indicate the maximum expected\n  /// group segment usage per work-group, in bytes.\n  /// @param[out] queue Memory location where the HSA runtime stores a pointer\n  /// to the newly created queue.\n  ///\n  /// @retval HSA_STATUS_SUCCESS The queue has been created successfully.\n  virtual hsa_status_t QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                                   HsaEventCallback event_callback, void* data,\n                                   uint32_t private_segment_size, uint32_t group_segment_size,\n                                   Queue** queue) = 0;\n\n  // @brief Query the value of an attribute.\n  //\n  // @param [in] attribute Attribute to query.\n  // @param [out] value Pointer to store the value of the attribute.\n  //\n  // @param HSA_STATUS_SUCCESS @p value has been filled with the value of the\n  // attribute.\n  virtual hsa_status_t GetInfo(hsa_agent_info_t attribute,\n                               void* value) const = 0;\n\n  // @brief Returns an array of regions owned by the agent.\n  virtual const std::vector<const core::MemoryRegion*>& regions() const = 0;\n\n  // @brief Returns the ISA's supported by the agent.\n  // @details The returned vector is a list of pointers to the supported ISA,\n  // ordered from most specific (and performant) to most generic. For CPU\n  // and AIE agents, this list will be empty.\n  virtual const std::vector<const core::Isa *>& supported_isas() const = 0;\n\n  virtual uint64_t HiveId() const { return 0; }\n\n  // @brief Returns the device type (CPU/GPU/Others).\n  __forceinline uint32_t device_type() const { return device_type_; }\n\n  // @brief Returns hsa_agent_t handle exposed to end user.\n  //\n  // @details Only matters when tools library need to intercept HSA calls.\n  __forceinline hsa_agent_t public_handle() const { return public_handle_; }\n\n  // @brief Returns node id associated with this agent.\n  __forceinline uint32_t node_id() const { return node_id_; }\n\n  // @brief Returns the driver associated with this agent.\n  __forceinline Driver& driver() { return *driver_; }\n  __forceinline const Driver& driver() const { return *driver_; }\n\n  // @brief Getter for profiling_enabled_.\n  __forceinline bool profiling_enabled() const { return profiling_enabled_; }\n\n  // @brief Setter for profiling_enabled_.\n  virtual hsa_status_t profiling_enabled(bool enable) {\n    const hsa_status_t stat = EnableDmaProfiling(enable);\n    if (HSA_STATUS_SUCCESS == stat) {\n      profiling_enabled_ = enable;\n    }\n\n    return stat;\n  }\n\n  __forceinline bool Enabled() const { return enabled_; }\n\n  __forceinline void Enable() { enabled_ = true; }\n\n  __forceinline void Disable() { enabled_ = false; }\n\n  virtual void Trim() {\n    for (auto region : regions()) region->Trim();\n  }\n\n  virtual void ReleaseResources() { }\n\nprotected:\n  // Intention here is to have a polymorphic update procedure for public_handle_\n  // which is callable on any Agent* but only from some class dervied from\n  // Agent*.  do_set_public_handle should remain protected or private in all\n  // derived types.\n  static __forceinline void set_public_handle(Agent* agent,\n                                              hsa_agent_t handle) {\n    agent->do_set_public_handle(handle);\n  }\n\n  virtual void do_set_public_handle(hsa_agent_t handle) {\n    public_handle_ = handle;\n  }\n\n  // @brief Enable profiling of the asynchronous DMA copy. The timestamp\n  // of each copy request will be stored in the completion signal structure.\n  //\n  // @param enable True to enable profiling. False to disable profiling.\n  //\n  // @retval HSA_STATUS_SUCCESS The profiling is enabled and the\n  // timing of subsequent async copy will be measured.\n  virtual hsa_status_t EnableDmaProfiling(bool enable) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  hsa_agent_t public_handle_;\n  std::vector<const core::Isa *> supported_isas_;\n\n private:\n  // @brief Node id.\n  const uint32_t node_id_;\n\n  const uint32_t device_type_;\n\n  Driver *driver_;\n\n  bool profiling_enabled_;\n\n  bool enabled_;\n\n  // Used by an Agent's MemoryRegions to ensure serial memory operation on the device.\n  // Serial memory operations are needed to ensure, among other things, that allocation failures are\n  // due to true OOM conditions and per region caching (Trim and Allocate must be serial and\n  // exclusive to ensure this).\n  KernelMutex agent_memory_lock_;\n\n  // Forbid copying and moving of this object\n  DISALLOW_COPY_AND_ASSIGN(Agent);\n};\n}  // namespace core\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_aie_agent.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// AMD specific HSA backend.\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_AIE_AGENT_H_\n#define HSA_RUNTIME_CORE_INC_AMD_AIE_AGENT_H_\n\n#include \"core/inc/agent.h\"\n#include \"core/inc/runtime.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nclass AieAgent : public core::Agent {\npublic:\n /// @brief AIE agent constructor.\n /// @param [in] node Node id.\n /// @param [in] node_props Node properties.\n AieAgent(uint32_t node, const HsaNodeProperties& node_props);\n\n ~AieAgent();\n\n hsa_status_t VisitRegion(bool include_peer,\n                          hsa_status_t (*callback)(hsa_region_t region, void* data),\n                          void* data) const;\n hsa_status_t IterateRegion(hsa_status_t (*callback)(hsa_region_t region, void* data),\n                            void* data) const override;\n\n hsa_status_t IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                           void* value) const override;\n\n hsa_status_t IterateSupportedIsas(hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                   void* data) const override;\n\n hsa_status_t GetInfo(hsa_agent_info_t attribute, void* value) const override;\n\n hsa_status_t QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                          core::HsaEventCallback event_callback, void* data,\n                          uint32_t private_segment_size, uint32_t group_segment_size,\n                          core::Queue** queue) override;\n\n /// @brief Override from core::Agent.\n const std::vector<const core::Isa*>& supported_isas() const override { return supported_isas_; }\n\n const std::vector<const core::MemoryRegion*>& regions() const override { return regions_; }\n\n /// @brief Getter for the AIE system allocator.\n const std::function<void*(size_t size, size_t align, core::MemoryRegion::AllocateFlags flags)>&\n system_allocator() const {\n   return system_allocator_;\n }\n\n  /// @brief Getter for the AIE system deallocator.\n  const std::function<void(void*)>& system_deallocator() const { return system_deallocator_; }\n\n  const HsaNodeProperties& properties() const { return node_props_; }\n\nprivate:\n  /// @brief Query the driver to get the region list owned by this agent.\n  void InitRegionList();\n  /// @brief Setup the memory allocators used by this agent.\n  void InitAllocators();\n\n  std::vector<const core::MemoryRegion *> regions_;\n  std::function<void *(size_t size, size_t align,\n                       core::MemoryRegion::AllocateFlags flags)>\n      system_allocator_;\n\n\n  std::function<void(void*)> system_deallocator_;\n\n  const hsa_profile_t profile_ = HSA_PROFILE_BASE;\n  const uint32_t min_aql_size_ = 0x40;\n  const uint32_t max_aql_size_ = 0x40;\n  const uint32_t max_queues_ = 1;\n\n  const HsaNodeProperties node_props_;\n};\n\n} // namespace AMD\n} // namespace rocr\n\n#endif // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_aie_aql_queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_HW_AQL_AIE_COMMAND_PROCESSOR_H_\n#define HSA_RUNTIME_CORE_INC_AMD_HW_AQL_AIE_COMMAND_PROCESSOR_H_\n\n#include <limits>\n\n#include \"core/inc/amd_aie_agent.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n\nnamespace rocr {\nnamespace AMD {\n\n/// @brief Encapsulates HW AIE AQL Command Processor functionality. It\n/// provides the interface for things such as doorbells, queue read and\n/// write pointers, and a buffer.\nclass AieAqlQueue : public core::Queue,\n                    private core::LocalSignal,\n                    core::DoorbellSignal {\n public:\n  static __forceinline bool IsType(core::Signal *signal) {\n    return signal->IsType(&rtti_id());\n  }\n\n  static __forceinline bool IsType(core::Queue *queue) {\n    return queue->IsType(&rtti_id());\n  }\n\n  AieAqlQueue(core::SharedQueue* shared_queue, AieAgent* agent, size_t req_size_pkts,\n              uint32_t node_id, uint64_t flags);\n  ~AieAqlQueue();\n\n  hsa_status_t Inactivate() override;\n  hsa_status_t SetPriority(HSA_QUEUE_PRIORITY priority) override;\n  void Destroy() override;\n  uint64_t LoadReadIndexRelaxed() override;\n  uint64_t LoadReadIndexAcquire() override;\n  uint64_t LoadWriteIndexRelaxed() override;\n  uint64_t LoadWriteIndexAcquire() override;\n  void StoreReadIndexRelaxed(uint64_t value) override { assert(false); }\n  void StoreReadIndexRelease(uint64_t value) override { assert(false); }\n  void StoreWriteIndexRelaxed(uint64_t value) override;\n  void StoreWriteIndexRelease(uint64_t value) override;\n  uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) override;\n  uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) override;\n  uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) override;\n  uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) override;\n  uint64_t AddWriteIndexRelaxed(uint64_t value) override;\n  uint64_t AddWriteIndexAcquire(uint64_t value) override;\n  uint64_t AddWriteIndexRelease(uint64_t value) override;\n  uint64_t AddWriteIndexAcqRel(uint64_t value) override;\n  void StoreRelaxed(hsa_signal_value_t value) override;\n  void StoreRelease(hsa_signal_value_t value) override;\n\n  /// @brief Provide information about the queue.\n  hsa_status_t GetInfo(hsa_queue_info_attribute_t attribute,\n                       void *value) override;\n\n  // AIE-specific API\n\n  /// @brief Returns the agent associated with this queue.\n  AieAgent& GetAgent() { return agent_; }\n\n  // GPU-specific queue functions are unsupported.\n\n  hsa_status_t GetCUMasking(uint32_t num_cu_mask_count,\n                            uint32_t *cu_mask) override;\n  hsa_status_t SetCUMasking(uint32_t num_cu_mask_count,\n                            const uint32_t *cu_mask) override;\n  void ExecutePM4(uint32_t *cmd_data, size_t cmd_size_b,\n                  hsa_fence_scope_t acquireFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_fence_scope_t releaseFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_signal_t *signal = NULL) override;\n\n private:\n  HSA_QUEUEID queue_id_ = INVALID_QUEUEID;\n  /// @brief ID of AIE device on which this queue has been mapped.\n  uint32_t node_id_ = std::numeric_limits<uint32_t>::max();\n  /// @brief Queue size in bytes.\n  uint32_t queue_size_bytes_ = std::numeric_limits<uint32_t>::max();\n\n protected:\n  bool _IsA(Queue::rtti_t id) const override { return id == &rtti_id(); }\n\n private:\n  AieAgent &agent_;\n\n  /// @brief Base of the queue's ring buffer storage.\n  void *ring_buf_ = nullptr;\n\n  /// @brief Called when the doorbell is rung to submit all queued packets.\n  void SubmitPackets();\n\n  /// @brief Indicates if queue is active.\n  std::atomic<bool> active_;\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n\n};\n\n} // namespace AMD\n} // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_AMD_HW_AQL_AIE_COMMAND_PROCESSOR_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_aql_queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_HW_AQL_COMMAND_PROCESSOR_H_\n#define HSA_RUNTIME_CORE_INC_AMD_HW_AQL_COMMAND_PROCESSOR_H_\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/util/locks.h\"\n\nnamespace rocr {\nnamespace AMD {\n/// @brief Encapsulates HW Aql Command Processor functionality. It\n/// provide the interface for things such as Doorbell register, read,\n/// write pointers and a buffer.\nclass AqlQueue : public core::Queue, private core::LocalSignal, public core::DoorbellSignal {\n public:\n  static __forceinline bool IsType(core::Signal* signal) {\n    return signal->IsType(&rtti_id());\n  }\n\n  static __forceinline bool IsType(core::Queue* queue) { return queue->IsType(&rtti_id()); }\n\n  // Acquires/releases queue resources and requests HW schedule/deschedule.\n  AqlQueue(core::SharedQueue* shared_queue, GpuAgent* agent, size_t req_size_pkts,\n           HSAuint32 node_id, ScratchInfo& scratch, core::HsaEventCallback callback, void* err_data,\n           uint64_t flags);\n\n  ~AqlQueue();\n\n  /// @brief Queue interfaces\n  hsa_status_t Inactivate() override;\n\n  /// @brief Change the scheduling priority of the queue\n  hsa_status_t SetPriority(HSA_QUEUE_PRIORITY priority) override;\n\n  /// @brief Destroy ref counted queue\n  void Destroy() override;\n\n  /// @brief Atomically reads the Read index of with Acquire semantics\n  ///\n  /// @return uint64_t Value of read index\n  uint64_t LoadReadIndexAcquire() override;\n\n  /// @brief Atomically reads the Read index of with Relaxed semantics\n  ///\n  /// @return uint64_t Value of read index\n  uint64_t LoadReadIndexRelaxed() override;\n\n  /// @brief Atomically reads the Write index of with Acquire semantics\n  ///\n  /// @return uint64_t Value of write index\n  uint64_t LoadWriteIndexAcquire() override;\n\n  /// @brief Atomically reads the Write index of with Relaxed semantics\n  ///\n  /// @return uint64_t Value of write index\n  uint64_t LoadWriteIndexRelaxed() override;\n\n  /// @brief This operation is illegal\n  void StoreReadIndexRelaxed(uint64_t value) override { assert(false); }\n\n  /// @brief This operation is illegal\n  void StoreReadIndexRelease(uint64_t value) override { assert(false); }\n\n  /// @brief Atomically writes the Write index of with Relaxed semantics\n  ///\n  /// @param value New value of write index to update with\n  void StoreWriteIndexRelaxed(uint64_t value) override;\n\n  /// @brief Atomically writes the Write index of with Release semantics\n  ///\n  /// @param value New value of write index to update with\n  void StoreWriteIndexRelease(uint64_t value) override;\n\n  /// @brief Compares and swaps Write index using Acquire and Release semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) override;\n\n  /// @brief Compares and swaps Write index using Acquire semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) override;\n\n  /// @brief Compares and swaps Write index using Relaxed semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) override;\n\n  /// @brief Compares and swaps Write index using Release semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) override;\n\n  /// @brief Updates the Write index using Acquire and Release semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t AddWriteIndexAcqRel(uint64_t value) override;\n\n  /// @brief Updates the Write index using Acquire semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t AddWriteIndexAcquire(uint64_t value) override;\n\n  /// @brief Updates the Write index using Relaxed semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t AddWriteIndexRelaxed(uint64_t value) override;\n\n  /// @brief Updates the Write index using Release semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  uint64_t AddWriteIndexRelease(uint64_t value) override;\n\n  /// @brief Set CU Masking\n  ///\n  /// @param num_cu_mask_count size of mask bit array\n  ///\n  /// @param cu_mask pointer to cu mask\n  ///\n  /// @return hsa_status_t\n  hsa_status_t SetCUMasking(uint32_t num_cu_mask_count, const uint32_t* cu_mask) override;\n\n  /// @brief Get CU Masking\n  ///\n  /// @param num_cu_mask_count size of mask bit array\n  ///\n  /// @param cu_mask pointer to cu mask\n  ///\n  /// @return hsa_status_t\n  hsa_status_t GetCUMasking(uint32_t num_cu_mask_count, uint32_t* cu_mask) override;\n\n  // @brief Submits a block of PM4 and waits until it has been executed.\n  void ExecutePM4(uint32_t* cmd_data, size_t cmd_size_b,\n                  hsa_fence_scope_t acquireFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_fence_scope_t releaseFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_signal_t* signal = NULL) override;\n\n  /// @brief Enables/Disables profiling overrides SetProfiling from core::Queue\n  void SetProfiling(bool enabled) override;\n\n  /// @brief Update signal value using Relaxed semantics\n  void StoreRelaxed(hsa_signal_value_t value) override;\n\n  /// @brief Update signal value using Release semantics\n  void StoreRelease(hsa_signal_value_t value) override;\n\n  /// @brief Provide information about the queue\n  hsa_status_t GetInfo(hsa_queue_info_attribute_t attribute, void* value) override;\n\n  /// @brief Enable use of GWS from this queue.\n  hsa_status_t EnableGWS(int gws_slot_count);\n\n  /// @brief Update internal scratch limits based on agent limits. If current allocated scratch are\n  /// larger than new limits, perform async-reclaim.\n  void CheckScratchLimits();\n\n  /// @brief Async reclaim main scratch memory\n  void AsyncReclaimMainScratch();\n\n  /// @brief Async reclaim alternate scratch memory\n  void AsyncReclaimAltScratch();\n\n protected:\n  bool _IsA(Queue::rtti_t id) const override { return id == &rtti_id(); }\n\n private:\n  uint32_t ComputeRingBufferMinPkts();\n  uint32_t ComputeRingBufferMaxPkts();\n\n  // (De)allocates and (de)registers ring_buf_.\n  void AllocRegisteredRingBuffer(uint32_t queue_size_pkts);\n\n  /// @brief Frees the queue's packet ring buffer and its queue struct.\n  void FreeQueueMemory();\n\n  /// @brief Abstracts the file handle use for double mapping queues.\n  void CloseRingBufferFD(const char* ring_buf_shm_path, int fd) const;\n  int CreateRingBufferFD(const char* ring_buf_shm_path, uint32_t ring_buf_phys_size_bytes) const;\n\n  /// @brief Define the Scratch Buffer Descriptor and related parameters\n  /// that enable kernel access scratch memory\n  void InitScratchSRD();\n  void FillBufRsrcWord0();\n  void FillBufRsrcWord1();\n  void FillBufRsrcWord1_Gfx11();\n  void FillBufRsrcWord2();\n  void FillBufRsrcWord3();\n  void FillBufRsrcWord3_Gfx10();\n  void FillBufRsrcWord3_Gfx11();\n  void FillBufRsrcWord3_Gfx12();\n  void FillComputeTmpRingSize();\n  void FillAltComputeTmpRingSize();\n  void FillComputeTmpRingSize_Gfx11();\n  void FillComputeTmpRingSize_Gfx12();\n\n  void FreeMainScratchSpace();\n  void FreeAltScratchSpace();\n\n  /// @brief Halt the queue without destroying it or fencing memory.\n  void Suspend();\n\n  /// @brief Resume the queue.\n  void Resume();\n\n  /// @brief Handle insufficient scratch\n  void HandleInsufficientScratch(hsa_signal_value_t& error_code, hsa_signal_value_t& waitVal,\n                                 bool& changeWait);\n\n  /// @brief Handler for hardware queue events.\n  template <bool HandleExceptions>\n  static bool DynamicQueueEventsHandler(hsa_signal_value_t error_code, void* arg);\n\n  /// @brief Handler for KFD exceptions.\n  static bool ExceptionHandler(hsa_signal_value_t error_code, void* arg);\n\n  // AQL packet ring buffer\n  void* ring_buf_;\n\n  // Size of ring_buf_ allocation.\n  // This may be larger than (amd_queue_.hsa_queue.size * sizeof(AqlPacket)).\n  uint32_t ring_buf_alloc_bytes_;\n\n  // Id of the Queue used in communication with thunk\n  HSA_QUEUEID queue_id_;\n\n  // Indicates if queue is active\n  std::atomic<bool> active_;\n\n  // Handle of agent, which queue is attached to\n  GpuAgent* agent_;\n\n  // Handle of scratch memory descriptor\n  ScratchInfo queue_scratch_;\n\n  AMD::callback_t<core::HsaEventCallback> errors_callback_;\n\n  void* errors_data_;\n\n  // GPU-visible indirect buffer holding PM4 commands.\n  void* pm4_ib_buf_;\n  uint32_t pm4_ib_size_b_;\n  KernelMutex pm4_ib_mutex_;\n\n  // Error handler control variable.\n  std::atomic<uint32_t> dynamicScratchState, exceptionState;\n  enum { ERROR_HANDLER_DONE = 1, ERROR_HANDLER_TERMINATE = 2, ERROR_HANDLER_SCRATCH_RETRY = 4 };\n\n  // Queue currently suspended or scheduled\n  bool suspended_;\n\n  // Thunk dispatch and wavefront scheduling priority\n  HSA_QUEUE_PRIORITY priority_;\n\n  // Exception notification signal\n  Signal* exception_signal_;\n\n  // CU mask lock\n  KernelMutex mask_lock_;\n\n  // Mutex to prevent AsyncReclaimScratch and HandleInsufficientScratch from\n  // happening at the same time.\n  KernelMutex scratch_lock_;\n\n  // Current CU mask\n  std::vector<uint32_t> cu_mask_;\n\n  // Shared event used for queue errors\n  static __forceinline HsaEvent*& queue_event() {\n    static HsaEvent* queue_event_ = nullptr;\n    return queue_event_;\n  }\n  // Queue count - used to ref count queue_event_\n  static __forceinline std::atomic<uint32_t>& queue_count() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static std::atomic<uint32_t>* queue_count_ = new std::atomic<uint32_t>(0);\n    return *queue_count_;\n  }\n\n  // Mutex for queue_event_ manipulation\nKernelMutex& queue_lock() {\n  // This allocation is meant to last until the last thread has exited.\n  // It is intentionally not freed.\n  static KernelMutex* queue_lock_ = new KernelMutex();\n  return *queue_lock_;\n}\n\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n\n  // Forbid copying and moving of this object\n  DISALLOW_COPY_AND_ASSIGN(AqlQueue);\n};\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_available_drivers.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_AMD_AVAILABLE_DRIVERS_H_\n#define HSA_RUNTME_CORE_INC_AMD_AVAILABLE_DRIVERS_H_\n\n#ifdef __linux__\n\n#include \"core/inc/amd_kfd_driver.h\"\n#include \"core/inc/amd_xdna_driver.h\"\n\n#endif\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_blit_kernel.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_BLIT_KERNEL_H_\n#define HSA_RUNTIME_CORE_INC_AMD_BLIT_KERNEL_H_\n\n#include <map>\n#include <mutex>\n#include <vector>\n#include <atomic>\n#include <stdint.h>\n\n#include \"core/inc/blit.h\"\n\nnamespace rocr {\nnamespace AMD {\nclass BlitKernel : public core::Blit {\n public:\n  explicit BlitKernel(core::Queue* queue);\n  virtual ~BlitKernel() override;\n\n  /// @brief Initialize a blit kernel object.\n  ///\n  /// @param agent Pointer to the agent that will execute the AQL packets.\n  ///\n  /// @return hsa_status_t\n  hsa_status_t Initialize(const core::Agent& agent);\n\n  /// @brief Marks the blit kernel object as invalid and uncouples its link with\n  /// the underlying AQL kernel queue. Use of the blit object\n  /// once it has been release is illegal and any behavior is indeterminate\n  ///\n  /// @note: The call will block until all AQL packets have been executed.\n  ///\n  /// @param agent Agent passed to Initialize.\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t Destroy(const core::Agent& agent) override;\n\n  /// @brief Submit an AQL packet to perform vector copy. The call is blocking\n  /// until the command execution is finished.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  virtual hsa_status_t SubmitLinearCopyCommand(void* dst, const void* src,\n                                               size_t size) override;\n\n  /// @brief Submit a linear copy command to the the underlying compute device's\n  /// control block. The call is non blocking. The memory transfer will start\n  /// after all dependent signals are satisfied. After the transfer is\n  /// completed, the out signal will be decremented.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  /// @param dep_signals Arrays of dependent signal.\n  /// @param out_signal Output signal.\n  /// @param gang_signals Array of gang signals.\n  virtual hsa_status_t SubmitLinearCopyCommand(\n      void* dst, const void* src, size_t size,\n      std::vector<core::Signal*>& dep_signals,\n      core::Signal& out_signal, std::vector<core::Signal*>& gang_signals) override;\n\n  /// @brief Submit an AQL packet to perform memory fill. The call is blocking\n  /// until the command execution is finished.\n  ///\n  /// @param ptr Memory address of the fill destination.\n  /// @param value Value to be set.\n  /// @param count Number of uint32_t element to be set to the value.\n  virtual hsa_status_t SubmitLinearFillCommand(void* ptr, uint32_t value,\n                                               size_t count) override;\n\n  virtual hsa_status_t EnableProfiling(bool enable) override;\n\n  virtual uint64_t PendingBytes() override;\n\n  virtual void GangLeader(bool gang_leader) override {}\n  virtual bool GangLeader() const override { return false; }\n\n  const uint16_t kInvalidPacketHeader = HSA_PACKET_TYPE_INVALID;\n private:\n  union KernelArgs {\n    struct __ALIGNED__(16) {\n      uint64_t phase1_src_start;\n      uint64_t phase1_dst_start;\n      uint64_t phase2_src_start;\n      uint64_t phase2_dst_start;\n      uint64_t phase3_src_start;\n      uint64_t phase3_dst_start;\n      uint64_t phase4_src_start;\n      uint64_t phase4_dst_start;\n      uint64_t phase4_src_end;\n      uint64_t phase4_dst_end;\n      uint32_t num_workitems;\n    } copy_aligned;\n\n    struct __ALIGNED__(16) {\n      uint64_t phase1_src_start;\n      uint64_t phase1_dst_start;\n      uint64_t phase2_src_start;\n      uint64_t phase2_dst_start;\n      uint64_t phase2_src_end;\n      uint64_t phase2_dst_end;\n      uint32_t num_workitems;\n    } copy_misaligned;\n\n    struct __ALIGNED__(16) {\n      uint64_t phase1_dst_start;\n      uint64_t phase2_dst_start;\n      uint64_t phase2_dst_end;\n      uint32_t fill_value;\n      uint32_t num_workitems;\n    } fill;\n  };\n\n  // Index after which bytes will have been written.\n  struct BytesWritten {\n    uint64_t index;\n    uint64_t bytes;\n  };\n\n  /// Reserve a slot in the queue buffer. The call will wait until the queue\n  /// buffer has a room.\n  uint64_t AcquireWriteIndex(uint32_t num_packet);\n\n  /// Update the queue doorbell register with ::write_index. This\n  /// function also serializes concurrent doorbell update to ensure that the\n  /// packet processor doesn't get invalid packet.\n  void ReleaseWriteIndex(uint64_t write_index, uint32_t num_packet);\n\n  void PopulateQueue(uint64_t index, uint64_t code_handle, void* args,\n                     uint32_t grid_size_x, hsa_signal_t completion_signal);\n\n  KernelArgs* ObtainAsyncKernelCopyArg();\n\n  void RecordBlitHistory(uint64_t size, uint64_t index);\n\n  /// AQL code object and size for each kernel.\n  enum class KernelType {\n    CopyAligned,\n    CopyMisaligned,\n    Fill,\n  };\n\n  struct KernelCode {\n    void* code_buf_;\n    size_t code_buf_size_;\n  };\n\n  std::map<KernelType, KernelCode> kernels_;\n\n  /// AQL queue for submitting the vector copy kernel.\n  core::Queue* queue_;\n  uint32_t queue_bitmask_;\n\n  /// Pointer to the kernel argument buffer.\n  KernelArgs* kernarg_async_;\n  uint32_t kernarg_async_mask_;\n  volatile uint32_t kernarg_async_counter_;\n\n  /// Completion signal for every kernel dispatched.\n  hsa_signal_t completion_signal_;\n\n  /// Bytes moved by commands < index.\n  /// Any record's byte value may be inexact by the size of concurrently issued operations.\n  std::vector<BytesWritten> bytes_written_;\n\n  /// Total bytes written by all commands issued.\n  uint64_t bytes_queued_;\n\n  /// Index where most recent blit operation queued.\n  uint64_t last_queued_;\n\n  /// Orders command indices and bytes_queued_ updates\n  std::mutex reservation_lock_;\n\n  /// Search resume index\n  std::atomic<uint64_t> pending_search_index_;\n\n  /// Lock to synchronize access to kernarg_ and completion_signal_\n  std::mutex lock_;\n\n  /// Number of CUs on the underlying agent.\n  int num_cus_;\n};\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_blit_sdma.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_BLIT_SDMA_H_\n#define HSA_RUNTIME_CORE_INC_AMD_BLIT_SDMA_H_\n\n#include <mutex>\n#include <stdint.h>\n#include <vector>\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/blit.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nclass BlitSdmaBase : public core::Blit {\n public:\n  static const size_t kQueueSize;\n  static const size_t kCopyPacketSize;\n  static const size_t kMaxSingleCopySize;\n  static const size_t kMaxSingleFillSize;\n  virtual bool isSDMA() const override { return true; }\n  virtual hsa_status_t Initialize(const core::Agent& agent, bool use_xgmi,\n                                  size_t linear_copy_size_override, int rec_engine) = 0;\n  virtual hsa_status_t SubmitCopyRectCommand(const hsa_pitched_ptr_t* dst,\n                                             const hsa_dim3_t* dst_offset,\n                                             const hsa_pitched_ptr_t* src,\n                                             const hsa_dim3_t* src_offset, const hsa_dim3_t* range,\n                                             std::vector<core::Signal*>& dep_signals,\n                                             core::Signal& out_signal) = 0;\n};\n\ntemplate <bool useGCR> class BlitSdma : public BlitSdmaBase {\n public:\n  BlitSdma();\n\n  virtual ~BlitSdma() override;\n\n  /// @brief Initialize a User Mode SDMA Queue object. Input parameters specify\n  /// properties of queue being created.\n  ///\n  /// @param agent Pointer to the agent that will execute the PM4 commands.\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t Initialize(const core::Agent& agent, bool use_xgmi,\n                                  size_t linear_copy_size_override, int rec_eng) override;\n\n  /// @brief Marks the queue object as invalid and uncouples its link with\n  /// the underlying compute device's control block. Use of queue object\n  /// once it has been release is illegal and any behavior is indeterminate\n  ///\n  /// @note: The call will block until all packets have executed.\n  ///\n  /// @param agent Agent passed to Initialize.\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t Destroy(const core::Agent& agent) override;\n\n  /// @brief Submit a linear copy command to the queue buffer.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  virtual hsa_status_t SubmitLinearCopyCommand(void* dst, const void* src,\n                                               size_t size) override;\n\n  /// @brief Submit a linear copy command to the the underlying compute device's\n  /// control block. The call is non blocking. The memory transfer will start\n  /// after all dependent signals are satisfied. After the transfer is\n  /// completed, the out signal will be decremented.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  /// @param dep_signals Arrays of dependent signal.\n  /// @param out_signal Output signal.\n  /// @param gang_signals Array of gang signals.\n  virtual hsa_status_t SubmitLinearCopyCommand(\n      void* dst, const void* src, size_t size,\n      std::vector<core::Signal*>& dep_signals,\n      core::Signal& out_signal, std::vector<core::Signal*>& gang_signals) override;\n\n  virtual hsa_status_t SubmitCopyRectCommand(const hsa_pitched_ptr_t* dst,\n                                             const hsa_dim3_t* dst_offset,\n                                             const hsa_pitched_ptr_t* src,\n                                             const hsa_dim3_t* src_offset, const hsa_dim3_t* range,\n                                             std::vector<core::Signal*>& dep_signals,\n                                             core::Signal& out_signal) override;\n\n  /// @brief Submit a linear fill command to the queue buffer\n  ///\n  /// @param ptr Memory address of the fill destination.\n  /// @param value Value to be set.\n  /// @param count Number of uint32_t element to be set to the value.\n  virtual hsa_status_t SubmitLinearFillCommand(void* ptr, uint32_t value,\n                                               size_t count) override;\n\n  virtual hsa_status_t EnableProfiling(bool enable) override;\n\n  virtual uint64_t PendingBytes() override;\n  virtual void GangLeader(bool gang_leader) override { gang_leader_ = gang_leader; }\n  virtual bool GangLeader() const override { return gang_leader_; }\n\n private:\n  /// @brief Acquires the address into queue buffer where a new command\n  /// packet of specified size could be written. The address that is\n  /// returned is guaranteed to be unique even in a multi-threaded access\n  /// scenario. This function is guaranteed to return a pointer for writing\n  /// data into the queue buffer.\n  ///\n  /// @param cmd_size Command packet size in bytes.\n  ///\n  /// @param curr_index (output) Index to pass to ReleaseWriteAddress.\n  ///\n  /// @return pointer into the queue buffer where a PM4 packet of specified size\n  /// could be written. NULL if input size is greater than the size of queue\n  /// buffer.\n\n  char* AcquireWriteAddress(uint32_t cmd_size, uint64_t& curr_index);\n\n  void UpdateWriteAndDoorbellRegister(uint64_t curr_index, uint64_t new_index);\n\n  /// @brief Updates the Write Register of compute device to the end of\n  /// SDMA packet written into queue buffer. The update to Write Register\n  /// will be safe under multi-threaded usage scenario. Furthermore, updates\n  /// to Write Register are blocking until all prior updates are completed\n  /// i.e. if two threads T1 & T2 were to call release, then updates by T2\n  /// will block until T1 has completed its update (assumes T1 acquired the\n  /// write address first).\n  ///\n  /// @param curr_index Index passed back from AcquireWriteAddress.\n  ///\n  /// @param cmd_size Command packet size in bytes.\n  void ReleaseWriteAddress(uint64_t curr_index, uint32_t cmd_size);\n\n  /// @brief Writes NO-OP words into queue buffer in case writing a command\n  /// causes the queue buffer to wrap.\n  ///\n  /// @param curr_index Index to begin padding from.\n  void PadRingToEnd(uint64_t curr_index);\n\n  uint32_t WrapIntoRing(uint64_t index);\n  bool CanWriteUpto(uint64_t upto_index);\n\n  /// @brief Build fence command\n  void BuildFenceCommand(char* fence_command_addr, uint32_t* fence,\n                         uint32_t fence_value);\n\n  /// @brief Build Hdp Flush command\n  void BuildHdpFlushCommand(char* cmd_addr);\n\n  void BuildCopyCommand(char* cmd_addr, uint32_t num_copy_command, void* dst,\n                        const void* src, size_t size);\n\n  void BuildCopyRectCommand(const std::function<void*(size_t)>& append,\n                            const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset,\n                            const hsa_pitched_ptr_t* src, const hsa_dim3_t* src_offset,\n                            const hsa_dim3_t* range);\n\n  void BuildFillCommand(char* cmd_addr, uint32_t num_fill_command, void* ptr, uint32_t value,\n                        size_t count);\n\n  void BuildPollCommand(char* cmd_addr, void* addr, uint32_t reference);\n\n  void BuildAtomicDecrementCommand(char* cmd_addr, void* addr);\n\n  void BuildGetGlobalTimestampCommand(char* cmd_addr, void* write_address);\n\n  void BuildTrapCommand(char* cmd_addr, uint32_t event_id);\n\n  void BuildGCRCommand(char* cmd_addr, bool invalidate);\n\n  hsa_status_t SubmitCommand(const void* cmds, size_t cmd_size, uint64_t size,\n                             const std::vector<core::Signal*>& dep_signals,\n                             core::Signal& out_signal, std::vector<core::Signal*>& gang_signals);\n\n  hsa_status_t SubmitBlockingCommand(const void* cmds, size_t cmd_size, uint64_t size);\n\n  // Agent object owning the SDMA engine.\n  GpuAgent* agent_;\n\n  /// Base address of the Queue buffer at construction time.\n  char* queue_start_addr_;\n\n  // Pending bytes tracking\n  // bytes_written_ is indexed with wrapped command queue indices (which are in bytes).\n  // The data_ index corresponding to a command queue index is the first uint64_t index which begins\n  // in the packet area.  All packets have a header & at least one address so must be larger than 12\n  // bytes, thus this index always exists.\n  std::mutex reservation_lock_;\n  uint64_t bytes_queued_;\n  class {\n   public:\n    // Indexed by wrapped command queue indices (offsets).\n    uint64_t& operator[](uint32_t index) { return data_[convert(index)]; }\n\n    void resize(size_t size) { data_.resize(convert(size)); }\n\n    void fill(uint32_t start, uint32_t stop, uint64_t value) {\n      for (uint32_t i = convert(start); i < convert(stop); i++) {\n        data_[i] = value;\n      }\n    }\n\n   private:\n    uint32_t convert(uint32_t index) { return (index + sizeof(uint64_t) - 1) / sizeof(uint64_t); }\n\n    std::vector<uint64_t> data_;\n  } bytes_written_;\n\n  // Internal signals for blocking APIs\n  core::unique_signal_ptr signals_[2];\n  KernelMutex lock_;\n  bool parity_;\n\n  /// Queue resource descriptor for doorbell, read\n  /// and write indices\n  HsaQueueResource queue_resource_;\n\n  // Monotonic ring indices, in bytes, tracking written and submitted commands.\n  uint64_t cached_reserve_index_;\n  uint64_t cached_commit_index_;\n\n  static const uint32_t linear_copy_command_size_;\n\n  static const uint32_t fill_command_size_;\n\n  static const uint32_t fence_command_size_;\n\n  static const uint32_t poll_command_size_;\n\n  static const uint32_t flush_command_size_;\n\n  static const uint32_t atomic_command_size_;\n\n  static const uint32_t timestamp_command_size_;\n\n  static const uint32_t trap_command_size_;\n\n  static const uint32_t gcr_command_size_;\n\n  // Max copy size of a single linear copy command packet.\n  size_t max_single_linear_copy_size_;\n\n  /// Max total copy size supported by the queue.\n  size_t max_total_linear_copy_size_;\n\n  /// Max count of uint32_t of a single fill command packet.\n  size_t max_single_fill_size_;\n\n  /// Max total fill count supported by the queue.\n  size_t max_total_fill_size_;\n\n  /// True if platform atomic is supported.\n  bool platform_atomic_support_;\n\n  /// True if sDMA supports HDP flush\n  bool hdp_flush_support_;\n\n  /// True if SDMA blit is gang leader\n  bool gang_leader_;\n\n  /// True if SDMA blit is ganged\n  bool is_ganged_;\n\n  /// Minimum submission size in bytes.\n  size_t min_submission_size_;\n};\n\n\ntypedef BlitSdma<false> BlitSdmaV4;\n\n// SDMA is connected to gL2.\ntypedef BlitSdma<true> BlitSdmaV5;\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_blit_shaders.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef OPENSRC_HSA_RUNTIME_CORE_INC_AMD_BLIT_SHADERS_H_ \n#define OPENSRC_HSA_RUNTIME_CORE_INC_AMD_BLIT_SHADERS_H_\n\nnamespace rocr {\nnamespace AMD {\n\nstatic const unsigned int kCodeCopyAligned7[] = {\n    0xC0820100, 0xC0840104, 0xC0860108, 0xC088010C, 0xC08A0110, 0xC00C0114,\n    0xBF8C007F, 0x8F028602, 0x4A000002, 0x7E060205, 0xD24A6A02, 0x00000900,\n    0xD2506A03, 0x01A90103, 0x7E0A0207, 0xD24A6A04, 0x00000D00, 0xD2506A05,\n    0x01A90105, 0xD1C2006A, 0x00001102, 0xBF86000F, 0x87FE6A7E, 0xDC200000,\n    0x01000002, 0xBF8C0F70, 0xD24A6A02, 0x00003102, 0xD2506A03, 0x01A90103,\n    0xDC600000, 0x00000104, 0xD24A6A04, 0x00003104, 0xD2506A05, 0x01A90105,\n    0xBF82FFEE, 0xBEFE04C1, 0x8F198418, 0x34020084, 0x7E060209, 0xD24A6A02,\n    0x00001101, 0xD2506A03, 0x01A90103, 0x7E0A020B, 0xD24A6A04, 0x00001501,\n    0xD2506A05, 0x01A90105, 0xD1C2006A, 0x00001902, 0xBF86000E, 0xDC380000,\n    0x08000002, 0xD24A6A02, 0x00003302, 0xD2506A03, 0x01A90103, 0xBF8C0F70,\n    0xDC780000, 0x00000804, 0xD24A6A04, 0x00003304, 0xD2506A05, 0x01A90105,\n    0xBF82FFEF, 0x8F198218, 0x34020082, 0x7E06020D, 0xD24A6A02, 0x00001901,\n    0xD2506A03, 0x01A90103, 0x7E0A020F, 0xD24A6A04, 0x00001D01, 0xD2506A05,\n    0x01A90105, 0xD1C2006A, 0x00002102, 0xBF86000F, 0x87FE6A7E, 0xDC300000,\n    0x01000002, 0xD24A6A02, 0x00003302, 0xD2506A03, 0x01A90103, 0xBF8C0F70,\n    0xDC700000, 0x00000104, 0xD24A6A04, 0x00003304, 0xD2506A05, 0x01A90105,\n    0xBF82FFEE, 0xBEFE04C1, 0x7E060211, 0xD24A6A02, 0x00002100, 0xD2506A03,\n    0x01A90103, 0x7E0A0213, 0xD24A6A04, 0x00002500, 0xD2506A05, 0x01A90105,\n    0xD1C2006A, 0x00002902, 0xBF860006, 0x87FE6A7E, 0xDC200000, 0x01000002,\n    0xBF8C0F70, 0xDC600000, 0x00000104, 0xBF810000,\n};\n\nstatic const unsigned int kCodeCopyMisaligned7[] = {\n    0xC0820100, 0xC0840104, 0xC0860108, 0xC008010C, 0xBF8C007F, 0x8F028602,\n    0x4A000002, 0x7E060205, 0xD24A6A02, 0x00000900, 0xD2506A03, 0x01A90103,\n    0x7E0A0207, 0xD24A6A04, 0x00000D00, 0xD2506A05, 0x01A90105, 0xD1C2006A,\n    0x00001102, 0xBF860032, 0xDC200000, 0x06000002, 0xD24A6A02, 0x00002102,\n    0xD2506A03, 0x01A90103, 0xDC200000, 0x07000002, 0xD24A6A02, 0x00002102,\n    0xD2506A03, 0x01A90103, 0xDC200000, 0x08000002, 0xD24A6A02, 0x00002102,\n    0xD2506A03, 0x01A90103, 0xDC200000, 0x09000002, 0xD24A6A02, 0x00002102,\n    0xD2506A03, 0x01A90103, 0xBF8C0F70, 0xDC600000, 0x00000604, 0xD24A6A04,\n    0x00002104, 0xD2506A05, 0x01A90105, 0xDC600000, 0x00000704, 0xD24A6A04,\n    0x00002104, 0xD2506A05, 0x01A90105, 0xDC600000, 0x00000804, 0xD24A6A04,\n    0x00002104, 0xD2506A05, 0x01A90105, 0xDC600000, 0x00000904, 0xD24A6A04,\n    0x00002104, 0xD2506A05, 0x01A90105, 0xBF82FFCB, 0x7E060209, 0xD24A6A02,\n    0x00001100, 0xD2506A03, 0x01A90103, 0x7E0A020B, 0xD24A6A04, 0x00001500,\n    0xD2506A05, 0x01A90105, 0xD1C2006A, 0x00001902, 0xBF86000F, 0x87FE6A7E,\n    0xDC200000, 0x01000002, 0xD24A6A02, 0x00002102, 0xD2506A03, 0x01A90103,\n    0xBF8C0F70, 0xDC600000, 0x00000104, 0xD24A6A04, 0x00002104, 0xD2506A05,\n    0x01A90105, 0xBF82FFEE, 0xBF810000,\n};\n\nstatic const unsigned int kCodeFill7[] = {\n    0xC0820100, 0xC0840104, 0xBF8C007F, 0x8F028602, 0x4A000002, 0x7E08020A,\n    0x7E0A020A, 0x7E0C020A, 0x7E0E020A, 0x8F0C840B, 0x34020084, 0x7E060205,\n    0xD24A6A02, 0x00000901, 0xD2506A03, 0x01A90103, 0xD1C2006A, 0x00000D02,\n    0xBF860007, 0xDC780000, 0x00000402, 0xD24A6A02, 0x00001902, 0xD2506A03,\n    0x01A90103, 0xBF82FFF6, 0x8F0C820B, 0x34020082, 0x7E060207, 0xD24A6A02,\n    0x00000D01, 0xD2506A03, 0x01A90103, 0xD1C2006A, 0x00001102, 0xBF860008,\n    0x87FE6A7E, 0xDC700000, 0x00000402, 0xD24A6A02, 0x00001902, 0xD2506A03,\n    0x01A90103, 0xBF82FFF5, 0xBF810000,\n};\n\nstatic const unsigned int kCodeCopyAligned8[] = {\n    0xC00A0100, 0x00000000, 0xC00A0200, 0x00000010, 0xC00A0300, 0x00000020,\n    0xC00A0400, 0x00000030, 0xC00A0500, 0x00000040, 0xC0020600, 0x00000050,\n    0xBF8C007F, 0x8E028602, 0x32000002, 0x7E060205, 0xD1196A02, 0x00000900,\n    0xD11C6A03, 0x01A90103, 0x7E0A0207, 0xD1196A04, 0x00000D00, 0xD11C6A05,\n    0x01A90105, 0xD0E9006A, 0x00001102, 0xBF86000F, 0x86FE6A7E, 0xDC400000,\n    0x01000002, 0xBF8C0F70, 0xD1196A02, 0x00003102, 0xD11C6A03, 0x01A90103,\n    0xDC600000, 0x00000104, 0xD1196A04, 0x00003104, 0xD11C6A05, 0x01A90105,\n    0xBF82FFEE, 0xBEFE01C1, 0x8E198418, 0x24020084, 0x7E060209, 0xD1196A02,\n    0x00001101, 0xD11C6A03, 0x01A90103, 0x7E0A020B, 0xD1196A04, 0x00001501,\n    0xD11C6A05, 0x01A90105, 0xD0E9006A, 0x00001902, 0xBF86000E, 0xDC5C0000,\n    0x08000002, 0xD1196A02, 0x00003302, 0xD11C6A03, 0x01A90103, 0xBF8C0F70,\n    0xDC7C0000, 0x00000804, 0xD1196A04, 0x00003304, 0xD11C6A05, 0x01A90105,\n    0xBF82FFEF, 0x8E198218, 0x24020082, 0x7E06020D, 0xD1196A02, 0x00001901,\n    0xD11C6A03, 0x01A90103, 0x7E0A020F, 0xD1196A04, 0x00001D01, 0xD11C6A05,\n    0x01A90105, 0xD0E9006A, 0x00002102, 0xBF86000F, 0x86FE6A7E, 0xDC500000,\n    0x01000002, 0xD1196A02, 0x00003302, 0xD11C6A03, 0x01A90103, 0xBF8C0F70,\n    0xDC700000, 0x00000104, 0xD1196A04, 0x00003304, 0xD11C6A05, 0x01A90105,\n    0xBF82FFEE, 0xBEFE01C1, 0x7E060211, 0xD1196A02, 0x00002100, 0xD11C6A03,\n    0x01A90103, 0x7E0A0213, 0xD1196A04, 0x00002500, 0xD11C6A05, 0x01A90105,\n    0xD0E9006A, 0x00002902, 0xBF860006, 0x86FE6A7E, 0xDC400000, 0x01000002,\n    0xBF8C0F70, 0xDC600000, 0x00000104, 0xBF810000,\n};\n\nstatic const unsigned int kCodeCopyMisaligned8[] = {\n    0xC00A0100, 0x00000000, 0xC00A0200, 0x00000010, 0xC00A0300, 0x00000020,\n    0xC0020400, 0x00000030, 0xBF8C007F, 0x8E028602, 0x32000002, 0x7E060205,\n    0xD1196A02, 0x00000900, 0xD11C6A03, 0x01A90103, 0x7E0A0207, 0xD1196A04,\n    0x00000D00, 0xD11C6A05, 0x01A90105, 0xD0E9006A, 0x00001102, 0xBF860032,\n    0xDC400000, 0x06000002, 0xD1196A02, 0x00002102, 0xD11C6A03, 0x01A90103,\n    0xDC400000, 0x07000002, 0xD1196A02, 0x00002102, 0xD11C6A03, 0x01A90103,\n    0xDC400000, 0x08000002, 0xD1196A02, 0x00002102, 0xD11C6A03, 0x01A90103,\n    0xDC400000, 0x09000002, 0xD1196A02, 0x00002102, 0xD11C6A03, 0x01A90103,\n    0xBF8C0F70, 0xDC600000, 0x00000604, 0xD1196A04, 0x00002104, 0xD11C6A05,\n    0x01A90105, 0xDC600000, 0x00000704, 0xD1196A04, 0x00002104, 0xD11C6A05,\n    0x01A90105, 0xDC600000, 0x00000804, 0xD1196A04, 0x00002104, 0xD11C6A05,\n    0x01A90105, 0xDC600000, 0x00000904, 0xD1196A04, 0x00002104, 0xD11C6A05,\n    0x01A90105, 0xBF82FFCB, 0x7E060209, 0xD1196A02, 0x00001100, 0xD11C6A03,\n    0x01A90103, 0x7E0A020B, 0xD1196A04, 0x00001500, 0xD11C6A05, 0x01A90105,\n    0xD0E9006A, 0x00001902, 0xBF86000F, 0x86FE6A7E, 0xDC400000, 0x01000002,\n    0xD1196A02, 0x00002102, 0xD11C6A03, 0x01A90103, 0xBF8C0F70, 0xDC600000,\n    0x00000104, 0xD1196A04, 0x00002104, 0xD11C6A05, 0x01A90105, 0xBF82FFEE,\n    0xBF810000,\n};\n\nstatic const unsigned int kCodeFill8[] = {\n    0xC00A0100, 0x00000000, 0xC00A0200, 0x00000010, 0xBF8C007F, 0x8E028602,\n    0x32000002, 0x7E08020A, 0x7E0A020A, 0x7E0C020A, 0x7E0E020A, 0x8E0C840B,\n    0x24020084, 0x7E060205, 0xD1196A02, 0x00000901, 0xD11C6A03, 0x01A90103,\n    0xD0E9006A, 0x00000D02, 0xBF860007, 0xDC7C0000, 0x00000402, 0xD1196A02,\n    0x00001902, 0xD11C6A03, 0x01A90103, 0xBF82FFF6, 0x8E0C820B, 0x24020082,\n    0x7E060207, 0xD1196A02, 0x00000D01, 0xD11C6A03, 0x01A90103, 0xD0E9006A,\n    0x00001102, 0xBF860008, 0x86FE6A7E, 0xDC700000, 0x00000402, 0xD1196A02,\n    0x00001902, 0xD11C6A03, 0x01A90103, 0xBF82FFF5, 0xBF810000,\n};\n\n}  // namespace AMD\n}  // namespace rocr\n\n#endif // OPENSRC_HSA_RUNTIME_CORE_INC_AMD_BLIT_SHADERS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_core_dump.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef OPENSRC_HSA_RUNTIME_CORE_INC_AMD_CORE_DUMP_HPP_\n#define OPENSRC_HSA_RUNTIME_CORE_INC_AMD_CORE_DUMP_HPP_\n\nnamespace rocr {\nnamespace amd {\nnamespace coredump {\nhsa_status_t dump_gpu_core();\n}   //  namespace coredump\n}   //  namespace amd\n}   //  namespace rocr\n\n#endif // OPENSRC_HSA_RUNTIME_CORE_INC_AMD_CORE_DUMP_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_cpu_agent.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// AMD specific HSA backend.\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_CPU_AGENT_H_\n#define HSA_RUNTIME_CORE_INC_AMD_CPU_AGENT_H_\n\n#include <vector>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/agent.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/cache.h\"\n#include \"core/inc/driver.h\"\n\nnamespace rocr {\nnamespace AMD {\n// @brief Class to represent a CPU device.\nclass CpuAgent : public core::Agent {\n public:\n  // @brief CpuAgent constructor.\n  //\n  // @param [in] node Node id. Each CPU in different socket will get distinct\n  // id.\n  // @param [in] node_props Node property.\n  // @param [in] driver_type Driver type. Default is KFD.\n  CpuAgent(HSAuint32 node, const HsaNodeProperties& node_props,\n           core::DriverType driver_type = core::DriverType::KFD);\n\n  // @brief CpuAgent destructor.\n  ~CpuAgent();\n\n  // @brief Invoke the user provided callback for each region accessible by\n  // this agent.\n  //\n  // @param [in] include_peer If true, the callback will be also invoked on each\n  // peer memory region accessible by this agent. If false, only invoke the\n  // callback on memory region owned by this agent.\n  // @param [in] callback User provided callback function.\n  // @param [in] data User provided pointer as input for @p callback.\n  //\n  // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  // region returns ::HSA_STATUS_SUCCESS.\n  hsa_status_t VisitRegion(bool include_peer,\n                           hsa_status_t (*callback)(hsa_region_t region,\n                                                    void* data),\n                           void* data) const;\n\n  // @brief Override from core::Agent.\n  hsa_status_t IterateRegion(hsa_status_t (*callback)(hsa_region_t region,\n                                                      void* data),\n                             void* data) const override;\n\n  hsa_status_t IterateSupportedIsas(\n                    hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                                  void* data) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                            void* value) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t GetInfo(hsa_agent_info_t attribute, void* value) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                           core::HsaEventCallback event_callback, void* data,\n                           uint32_t private_segment_size, uint32_t group_segment_size,\n                           core::Queue** queue) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopy(void* dst, core::Agent& dst_agent, const void* src, core::Agent& src_agent,\n                       size_t size, std::vector<core::Signal*>& dep_signals,\n                       core::Signal& out_signal) override;\n\n  // @brief Returns number of data caches.\n  __forceinline size_t num_cache() const { return cache_props_.size(); }\n\n  // @brief Returns Hive ID\n  __forceinline uint64_t HiveId() const override { return  properties_.HiveID; }\n\n  // @brief Returns data cache property.\n  //\n  // @param [in] idx Cache level.\n  __forceinline const HsaCacheProperties& cache_prop(int idx) const {\n    return cache_props_[idx];\n  }\n\n  // @brief Override from core::Agent.\n  const std::vector<const core::MemoryRegion*>& regions() const override {\n    return regions_;\n  }\n\n  // @brief Override from core::Agent.\n  const std::vector<const core::Isa*>& supported_isas() const override {\n    return supported_isas_;\n  }\n private:\n  // @brief Query the driver to get the region list owned by this agent.\n  void InitRegionList();\n\n  // @brief Query the driver to get the cache properties.\n  void InitCacheList();\n\n  // @brief Invoke the user provided callback for every region in @p regions.\n  //\n  // @param [in] regions Array of region object.\n  // @param [in] callback User provided callback function.\n  // @param [in] data User provided pointer as input for @p callback.\n  //\n  // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  // region returns ::HSA_STATUS_SUCCESS.\n  hsa_status_t VisitRegion(\n      const std::vector<const core::MemoryRegion*>& regions,\n      hsa_status_t (*callback)(hsa_region_t region, void* data),\n      void* data) const;\n\n  // @brief Node property.\n  const HsaNodeProperties properties_;\n\n  // @brief Array of data cache property. The array index represents the cache\n  // level.\n  std::vector<HsaCacheProperties> cache_props_;\n\n  // @brief Array of HSA cache objects.\n  std::vector<std::unique_ptr<core::Cache>> caches_;\n\n  // @brief Array of regions owned by this agent.\n  std::vector<const core::MemoryRegion*> regions_;\n\n  DISALLOW_COPY_AND_ASSIGN(CpuAgent);\n};\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_elf_image.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_ELF_IMAGE_HPP_\n#define AMD_ELF_IMAGE_HPP_\n\n#include <string>\n#include <sstream>\n#include <vector>\n#include <memory>\n#include <cstdint>\n\nnamespace rocr {\nnamespace amd {\nnamespace elf {\n    class Symbol;\n    class SymbolTable;\n    class Section;\n    class RelocationSection;\n\n    class Segment {\n    public:\n      virtual ~Segment() { }\n      virtual uint64_t type() const = 0;\n      virtual uint64_t memSize() const = 0;\n      virtual uint64_t align() const = 0;\n      virtual uint64_t imageSize() const = 0;\n      virtual uint64_t vaddr() const = 0;\n      virtual uint64_t flags() const = 0;\n      virtual uint64_t offset() const = 0;\n      virtual const char* data() const = 0;\n      virtual uint16_t getSegmentIndex() = 0;\n      virtual bool updateAddSection(Section *section) = 0;\n    };\n\n    class Section {\n    public:\n      virtual ~Section() { }\n      virtual uint16_t getSectionIndex() const = 0;\n      virtual uint32_t type() const = 0;\n      virtual std::string Name() const = 0;\n      virtual uint64_t offset() const = 0;\n      virtual uint64_t addr() const = 0;\n      virtual bool updateAddr(uint64_t addr) = 0;\n      virtual uint64_t addralign() const = 0;\n      virtual uint64_t flags() const = 0;\n      virtual uint64_t size() const = 0;\n      virtual uint64_t nextDataOffset(uint64_t align) const = 0;\n      virtual uint64_t addData(const void *src, uint64_t size, uint64_t align) = 0;\n      virtual bool getData(uint64_t offset, void* dest, uint64_t size) = 0;\n      virtual Segment* segment() = 0;\n      virtual RelocationSection* asRelocationSection() = 0;\n      virtual bool hasRelocationSection() const = 0;\n      virtual RelocationSection* relocationSection(SymbolTable* symtab = 0) = 0;\n      virtual bool setMemSize(uint64_t s) = 0;\n      virtual uint64_t memSize() const = 0;\n      virtual bool setAlign(uint64_t a) = 0;\n      virtual uint64_t memAlign() const = 0;\n    };\n\n    class Relocation {\n    public:\n      virtual ~Relocation() { }\n      virtual RelocationSection* section() = 0;\n      virtual uint32_t type() = 0;\n      virtual uint32_t symbolIndex() = 0;\n      virtual Symbol* symbol() = 0;\n      virtual uint64_t offset() = 0;\n      virtual int64_t addend() = 0;\n    };\n\n    class RelocationSection : public virtual Section {\n    public:\n      virtual Relocation* addRelocation(uint32_t type, Symbol* symbol, uint64_t offset, int64_t addend) = 0;\n      virtual size_t relocationCount() const = 0;\n      virtual Relocation* relocation(size_t i) = 0;\n      virtual Section* targetSection() = 0;\n    };\n\n    class StringTable : public virtual Section {\n    public:\n      virtual const char* addString(const std::string& s) = 0;\n      virtual size_t addString1(const std::string& s) = 0;\n      virtual const char* getString(size_t ndx) = 0;\n      virtual size_t getStringIndex(const char* name) = 0;\n    };\n\n    class Symbol {\n    public:\n      virtual ~Symbol() { }\n      virtual uint32_t index() = 0;\n      virtual uint32_t type() = 0;\n      virtual uint32_t binding() = 0;\n      virtual uint64_t size() = 0;\n      virtual uint64_t value() = 0;\n      virtual unsigned char other() = 0;\n      virtual std::string name() = 0;\n      virtual Section* section() = 0;\n      virtual void setValue(uint64_t value) = 0;\n      virtual void setSize(uint64_t size) = 0;\n    };\n\n    class SymbolTable : public virtual Section {\n    public:\n      virtual Symbol* addSymbol(Section* section, const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, unsigned char other = 0) = 0;\n      virtual size_t symbolCount() = 0;\n      virtual Symbol* symbol(size_t i) = 0;\n    };\n\n    class NoteSection : public virtual Section {\n    public:\n      virtual bool addNote(const std::string& name, uint32_t type, const void* desc = 0, uint32_t desc_size = 0) = 0;\n      virtual bool getNote(const std::string& name, uint32_t type, void** desc, uint32_t* desc_size) = 0;\n    };\n\n    class Image {\n    public:\n      virtual ~Image() { }\n\n      virtual bool initNew(uint16_t machine, uint16_t type, uint8_t os_abi = 0, uint8_t abi_version = 0, uint32_t e_flags = 0) = 0;\n      virtual bool loadFromFile(const std::string& filename) = 0;\n      virtual bool saveToFile(const std::string& filename) = 0;\n      virtual bool initFromBuffer(const void* buffer, size_t size) = 0;\n      virtual bool initAsBuffer(const void* buffer, size_t size) = 0;\n      virtual bool writeTo(const std::string& filename) = 0;\n      virtual bool copyToBuffer(void** buf, size_t* size = 0) = 0; // Copy to new buffer allocated with malloc\n      virtual bool copyToBuffer(void* buf, size_t size) = 0; // Copy to existing buffer of given size.\n\n      virtual const char* data() = 0;\n      virtual uint64_t size() = 0;\n\n      virtual uint16_t Machine() = 0;\n      virtual uint16_t Type() = 0;\n      virtual uint32_t EFlags() = 0;\n      virtual uint32_t ABIVersion() = 0;\n      virtual uint32_t EClass() = 0;\n      virtual uint32_t OsAbi() = 0;\n\n      std::string output() { return out.str(); }\n\n      virtual bool Freeze() = 0;\n      virtual bool Validate() = 0;\n\n      virtual StringTable* shstrtab() = 0;\n      virtual StringTable* strtab() = 0;\n      virtual SymbolTable* symtab() = 0;\n      virtual SymbolTable* getSymtab(uint16_t index) = 0;\n      virtual SymbolTable* dynsym() = 0;\n      virtual SymbolTable* getDynsym(uint16_t index) = 0;\n      virtual SymbolTable* getSymbolTable() = 0;\n      virtual SymbolTable* getSymbolTable(uint16_t index) = 0;\n\n      virtual StringTable* addStringTable(const std::string& name) = 0;\n      virtual StringTable* getStringTable(uint16_t index) = 0;\n\n      virtual SymbolTable* addSymbolTable(const std::string& name, StringTable* stab = 0) = 0;\n\n      virtual size_t segmentCount() = 0;\n      virtual Segment* segment(size_t i) = 0;\n      virtual Segment* segmentByVAddr(uint64_t vaddr) = 0;\n\n      virtual size_t sectionCount() = 0;\n      virtual Section* section(size_t i) = 0;\n      virtual Section* sectionByVAddr(uint64_t vaddr) = 0;\n\n      virtual NoteSection* note() = 0;\n      virtual NoteSection* addNoteSection(const std::string& name) = 0;\n\n      virtual Segment* initSegment(uint32_t type, uint32_t flags, uint64_t paddr = 0) = 0;\n      virtual bool addSegments() = 0;\n\n      virtual Section* addSection(const std::string &name,\n                                  uint32_t type,\n                                  uint64_t flags = 0,\n                                  uint64_t entsize = 0,\n                                  Segment* segment = 0) = 0;\n\n      virtual RelocationSection* relocationSection(Section* sec, SymbolTable* symtab = 0) = 0;\n\n    protected:\n      std::ostringstream out;\n    };\n\n    Image* NewElf32Image();\n    Image* NewElf64Image();\n\n    uint64_t ElfSize(const void* buffer);\n\n    std::string GetNoteString(uint32_t s_size, const char* s);\n\n}   //  namespace elf\n}   //  namespace amd\n}   //  namespace rocr\n\n#endif // AMD_ELF_IMAGE_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_filter_device.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_FILTER_DEVICE_H_\n#define HSA_RUNTIME_CORE_INC_AMD_FILTER_DEVICE_H_\n\n#include <algorithm>\n#include <cstdint>\n#include <cstring>\n#include <vector>\n#include <map>\n#include <string>\n#include <sstream>\n\n// Forward declaration of the HsaNodeProperties.\nstruct _HsaNodeProperties;\nusing HsaNodeProperties = _HsaNodeProperties;\n\nnamespace rocr {\nnamespace AMD {\n\n// ROCr allows users to filter and reorder various Gpu devices that are\n// present on ROCm system. This ability is made available via environment\n// variable ROCR_VISIBLE_DEVICES (RVD). Users are allowed to specify a list\n// of Gpu Identifiers separated by comma delimiter as the value of this env\n// variable.\n//\n// On a ROCm platform instance, a Gpu device could be identified by its:\n//\n//    Index - Position at which ROCr reports it upon device enumeration\n//    UUID  - A string that is unique and is immutable i.e. tags Gpu\n//            instance across systems and power cycles. UUID values\n//            are defined to begin with \"GPU-\" prefix\n//\n//    @note: Not all Gpu devices will report valid UUID's. For example,\n//    Only devices from Gfx9 and later will encode valid UUID's. To account\n//    for this and other reasons, the UUID string \"GPU-XX\" is defined as\n//    indicating those devices. Users can still select those Gpu devices\n//    by using their enumeration index\n//\n//  Users are allowed to select a device by specifying its UUID string in\n//  full or part. A UUID string that does not uniquely match an agent's\n//  valid UUID prefix is interpreted as terminating. The UUID string\n//  \"GPU-XX\" will not match and therefore will terminate\n//\n//  RVD interpreter treats an empty token list as filtering all devices.\n//    Users can use this mode to report ZERO Gpu devices\n//\n//  RVD interpreter treats a token as Illegal if can't be evaluated into an\n//    instance of Device UUID or Enumeration Index\n//\n//  RVD interpreter treats a Legal instance of Enumeration Index as Terminating\n//    if any ONE of the following conditions apply:\n//      Value of index lies outside the interval [0 - (numGpuDevices - 1)]\n//      Value of index maps to a device that has been previously selected\n//\n//  RVD interpreter treats a Legal instance of Device UUID as Terminating\n//    if any ONE of the following conditions apply:\n//      Value of UUID is the literal \"GPU-XX\"\n//      Value of UUID matches ZERO devices on system\n//      Value of UUID matches TWO or more devices on system\n//      Value of UUID maps to a device that has been previously selected\n//\n//  RVD interpreter builds the list of Gpu devices to surface using tokens\n//    that are Legal and NOT Terminating\n//\n//  Following are some examples of RVD value strings and their intepretation\n//  on a ROCm system with four Gpu devices. Assume for now the UUID's of the\n//  four Gpu devices are:\n//    Gpu-0: \"GPU-BABABABABABABABA\"\n//    Gpu-1: \"GPU-ABBAABBAABBAABBA\"\n//    Gpu-2: \"GPU-BABAABBAABBABABA\"\n//    Gpu-3: \"GPU-ABBABABABABAABBA\"\n//\n//    Surface ZERO devices\n//    A1) ROCR_VISIBLE_DEVICES=\"\"\n//    A2) ROCR_VISIBLE_DEVICES=\"-1\"\n//    A3) ROCR_VISIBLE_DEVICES=\"GPU-XX\"\n//\n//    Surface Gpu-3 and Gpu-0 devices in that order\n//    B) ROCR_VISIBLE_DEVICES=\"3,GPU-BABABABABABABABA,4\"\n//\n//    Surface Gpu-1 and Gpu-2 devices in that order\n//    C) ROCR_VISIBLE_DEVICES=\"1,GPU-ABBAABBAABBAABBA,GPU-XX\"\n//\n//    Surface Gpu-3 and Gpu-2 devices in that order\n//    D) ROCR_VISIBLE_DEVICES=\"3,GPU-BABAABBA,GPU-XX\"\n//\nclass RvdFilter {\n public:\n  /// @brief Constructor\n  RvdFilter() {}\n\n  // @brief Destructor.\n  ~RvdFilter() {}\n\n  /// @brief Determine if user has specified environment variable\n  /// ROCR_VISIBLE_DEVICES (RVD) to filter and reorder Gpu devices\n  ///\n  /// @return TRUE if user has defined the env RVD\n  static bool FilterDevices();\n\n  /// @brief Determine if user has specified environment variable\n  /// ROCR_VISIBLE_DEVICES (RVD) to filter out all Gpu devices i.e.\n  /// surface ZERO devices\n  ///\n  /// @return TRUE if user has specified ZERO to be surfaced\n  bool SelectZeroDevices();\n\n  /// @brief Builds the list of tokens specified by user to filter\n  /// and reorder Gpu devices. A token represents either a Gpu's\n  /// enumeration index or its UUID value. It is possible for the\n  /// list to have no tokens i.e. user has selected zero devices\n  void BuildRvdTokenList();\n\n  /// @brief Build the list of Gpu device UUIDs as enumerated by ROCt\n  ///\n  /// @param numNodes Number of ROCm devices present on system, includes\n  /// both Cpu and Gpu's devices\n  void BuildDeviceUuidList(const std::vector<HsaNodeProperties>& node_props);\n\n  /// @brief Build the list of Gpu devices that will be enumerated to user\n  ///\n  /// @return Number of Gpu devices to surface upon devices enumeration\n  uint32_t BuildUsrDeviceList();\n\n  /// @brief Processes UUID token and returns its enumeration index\n  ///\n  /// @param token RVD token encoding a device's UUID value\n  /// @return int32_t if it is valid, -1 otherwise\n  int32_t ProcessUuidToken(const std::string& token);\n\n  /// @brief Get the number of Gpu devices that will be surface\n  /// upon device enumeration\n  ///\n  /// @uint32_t Number of devices to enumerate including possibly\n  /// ZERO devices\n  uint32_t GetUsrDeviceListSize();\n\n  /// @brief Return the rank of queried Gpu device. If queried device\n  /// is surfaced the number of Gpu devices that will be surface\n  /// upon device enumeration\n  ///\n  /// @int32_t -1 if queried device is not surfaced, else a value in\n  /// the range [0 - (numGpus - 1)]\n  int32_t GetUsrDeviceRank(uint32_t roctIdx);\n\n#ifndef NDEBUG\n  /// @brief Set debug UUID values to Gpu devices. This is intended to\n  /// help debug and test RVD module functionality\n  void SetDeviceUuidList();\n\n  /// @brief Print the list of Uuids of Gpu devices present on system\n  void PrintDeviceUuidList();\n\n  /// @brief Print the list of Gpu devices per their enumeration order\n  void PrintUsrDeviceList();\n\n  /// @brief Print the list of tokens specified by user to filter\n  /// and reorder Gpu devices\n  void PrintRvdTokenList();\n#endif\n\n private:\n  /// @brief List of tokens specified by user to select and reorder\n  std::vector<std::string> rvdTokenList_;\n\n  /// @brief Ordered list of ROCt enumerated Gpu device's UUID values\n  std::vector<std::string> devUuidList_;\n\n  /// @brief Ordered list of ROCr enumerated Gpu devices\n  std::map<uint32_t, int32_t> usrDeviceList_;\n\n};  // End of class RvdFilter\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard - HSA_RUNTIME_CORE_INC_AMD_FILTER_DEVICE_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_gpu_agent.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// AMD specific HSA backend.\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_GPU_AGENT_H_\n#define HSA_RUNTIME_CORE_INC_AMD_GPU_AGENT_H_\n\n#include <vector>\n#include <list>\n#include <map>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/agent.h\"\n#include \"core/inc/blit.h\"\n#include \"core/inc/cache.h\"\n#include \"core/inc/driver.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/scratch_cache.h\"\n#include \"core/inc/signal.h\"\n#include \"core/util/lazy_ptr.h\"\n#include \"core/util/locks.h\"\n#include \"core/util/small_heap.h\"\n#include \"pcs/pcs_runtime.h\"\n\nnamespace rocr {\nnamespace AMD {\nclass MemoryRegion;\n\ntypedef ScratchCache::ScratchInfo ScratchInfo;\n\n// @brief Interface to represent a GPU agent.\nclass GpuAgentInt : public core::Agent {\n public:\n  // @brief Constructor\n  // @param [in] node_id Node id.\n  // @param [in] driver_type Driver type. Default is KFD.\n  GpuAgentInt(uint32_t node_id, core::DriverType driver_type)\n      : core::Agent(core::Runtime::runtime_singleton_->AgentDriver(driver_type), node_id,\n      core::Agent::DeviceType::kAmdGpuDevice) {}\n\n   // @brief Ensure blits are ready (performance hint).\n   virtual void PreloadBlits() {}\n\n   // @brief Initialization hook invoked after tools library has loaded,\n   // to allow tools interception of interface functions.\n   //\n   // @retval HSA_STATUS_SUCCESS if initialization is successful.\n   virtual hsa_status_t PostToolsInit() = 0;\n\n   virtual void ReleaseResources() = 0;\n\n   // @brief Invoke the user provided callback for each region accessible by\n   // this agent.\n   //\n   // @param [in] include_peer If true, the callback will be also invoked on\n   // each peer memory region accessible by this agent. If false, only invoke\n   // the callback on memory region owned by this agent.\n   // @param [in] callback User provided callback function.\n   // @param [in] data User provided pointer as input for @p callback.\n   //\n   // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n   // region returns ::HSA_STATUS_SUCCESS.\n   virtual hsa_status_t\n   VisitRegion(bool include_peer,\n               hsa_status_t (*callback)(hsa_region_t region, void *data),\n               void *data) const = 0;\n\n   // @brief Carve scratch memory for main from scratch pool.\n   //\n   // @param [in,out] scratch Structure to be populated with the carved memory\n   // information.\n   virtual void AcquireQueueMainScratch(ScratchInfo &scratch) = 0;\n\n   // @brief Carve scratch memory for alt from scratch pool.\n   //\n   // @param [in,out] scratch Structure to be populated with the carved memory\n   // information.\n   virtual void AcquireQueueAltScratch(ScratchInfo &scratch) = 0;\n\n   // @brief Release scratch memory from main back to scratch pool.\n   //\n   // @param [in,out] scratch Scratch memory previously acquired with call to\n   // ::AcquireQueueMainScratch.\n   virtual void ReleaseQueueMainScratch(ScratchInfo &base) = 0;\n\n   // @brief Release scratch memory back from alternate to scratch pool.\n   //\n   // @param [in,out] scratch Scratch memory  previously acquired with call to\n   // ::AcquireQueueAltScratch.\n   virtual void ReleaseQueueAltScratch(ScratchInfo &base) = 0;\n\n   // @brief Translate the kernel start and end dispatch timestamp from agent\n   // domain to host domain.\n   //\n   // @param [in] signal Pointer to signal that provides the dispatch timing.\n   // @param [out] time Structure to be populated with the host domain value.\n   virtual void TranslateTime(core::Signal *signal,\n                              hsa_amd_profiling_dispatch_time_t &time) = 0;\n\n   // @brief Translate the async copy start and end timestamp from agent\n   // domain to host domain.\n   //\n   // @param [in] signal Pointer to signal that provides the async copy timing.\n   // @param [out] time Structure to be populated with the host domain value.\n   virtual void TranslateTime(core::Signal *signal,\n                              hsa_amd_profiling_async_copy_time_t &time) = 0;\n\n   // @brief Translate timestamp agent domain to host domain.\n   //\n   // @param [out] time Timestamp in agent domain.\n   virtual uint64_t TranslateTime(uint64_t tick) = 0;\n\n   // @brief Invalidate caches on the agent which may hold code object data.\n   virtual void InvalidateCodeCaches(void *ptr, size_t size) = 0;\n\n   // @brief Sets the coherency type of this agent.\n   //\n   // @param [in] type New coherency type.\n   //\n   // @retval true The new coherency type is set successfuly.\n   virtual bool current_coherency_type(hsa_amd_coherency_type_t type) = 0;\n\n   // @brief Returns the current coherency type of this agent.\n   //\n   // @retval Coherency type.\n   virtual hsa_amd_coherency_type_t current_coherency_type() const = 0;\n\n   virtual void RegisterGangPeer(core::Agent &gang_peer,\n                                 unsigned int bandwidth_factor) = 0;\n\n   virtual void RegisterRecSdmaEngIdMaskPeer(core::Agent &gang_peer,\n                                             uint32_t rec_sdma_eng_id_mask) = 0;\n\n   virtual void SetRecSdmaEngOverride(bool flag) = 0;\n\n   // @brief Query the agent HSA profile.\n   //\n   // @retval HSA profile.\n   virtual hsa_profile_t profile() const = 0;\n\n   // @brief Query the agent memory bus width in bit.\n   //\n   // @retval Bus width in bit.\n   virtual uint32_t memory_bus_width() const = 0;\n\n   // @brief Query the agent memory maximum frequency in MHz.\n   //\n   // @retval Bus width in MHz.\n   virtual uint32_t memory_max_frequency() const = 0;\n\n   // @brief Whether agent supports asynchronous scratch reclaim. Depends on CP\n   // FW\n   virtual bool AsyncScratchReclaimEnabled() const = 0;\n\n   // @brief Update the agent's scratch use-once threshold.\n   // Only valid when async scratch reclaim is supported\n   // @retval HSA_STATUS_SUCCESS if successful\n   virtual hsa_status_t SetAsyncScratchThresholds(size_t use_once_limit) = 0;\n\n   // @brief Iterate through supported PC Sampling configurations\n   // @retval HSA_STATUS_SUCCESS if successful\n   virtual hsa_status_t\n   PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb,\n                           void *cb_data) = 0;\n\n   virtual hsa_status_t\n   PcSamplingCreate(pcs::PcsRuntime::PcSamplingSession &session) = 0;\n\n   virtual hsa_status_t\n   PcSamplingCreateFromId(HsaPcSamplingTraceId pcsId,\n                          pcs::PcsRuntime::PcSamplingSession &session) = 0;\n\n   virtual hsa_status_t\n   PcSamplingDestroy(pcs::PcsRuntime::PcSamplingSession &session) = 0;\n\n   virtual hsa_status_t\n   PcSamplingStart(pcs::PcsRuntime::PcSamplingSession &session) = 0;\n\n   virtual hsa_status_t\n   PcSamplingStop(pcs::PcsRuntime::PcSamplingSession &session) = 0;\n\n   virtual hsa_status_t\n   PcSamplingFlush(pcs::PcsRuntime::PcSamplingSession &session) = 0;\n};\n\nclass GpuAgent : public GpuAgentInt {\n public:\n  // @brief GPU agent constructor.\n  //\n  // @param [in] node Node id. Each CPU in different socket will get distinct\n  // id.\n  // @param [in] node_props Node property.\n  // @param [in] xnack_mode XNACK mode of device.\n  // @param [in] index Index of the GPU device.\n  // @param [in] driver_type Driver type. Default is KFD.\n  GpuAgent(HSAuint32 node, const HsaNodeProperties& node_props, bool xnack_mode, uint32_t index,\n           core::DriverType driver_type = core::DriverType::KFD);\n\n  // @brief GPU agent destructor.\n  ~GpuAgent();\n\n  // @brief Release allocated resources and disables agent\n  void ReleaseResources() override;\n\n  // @brief Ensure blits are ready (performance hint).\n  void PreloadBlits() override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t PostToolsInit() override;\n\n  uint16_t GetMicrocodeVersion() const;\n\n  uint16_t GetSdmaMicrocodeVersion() const;\n\n  // @brief Assembles SP3 shader source into ISA or AQL code object.\n  //\n  // @param [in] src_sp3 SP3 shader source text representation.\n  // @param [in] func_name Name of the SP3 function to assemble.\n  // @param [in] assemble_target ISA or AQL assembly target.\n  // @param [out] code_buf Code object buffer.\n  // @param [out] code_buf_size Size of code object buffer in bytes.\n  enum class AssembleTarget { ISA, AQL };\n\n  void AssembleShader(const char* func_name, AssembleTarget assemble_target, void*& code_buf,\n                      size_t& code_buf_size) const;\n\n  // @brief Frees code object created by AssembleShader.\n  //\n  // @param [in] code_buf Code object buffer.\n  // @param [in] code_buf_size Size of code object buffer in bytes.\n  void ReleaseShader(void* code_buf, size_t code_buf_size) const;\n\n  // @brief Override from core::Agent.\n  hsa_status_t VisitRegion(bool include_peer,\n                           hsa_status_t (*callback)(hsa_region_t region,\n                                                    void* data),\n                           void* data) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t IterateRegion(hsa_status_t (*callback)(hsa_region_t region,\n                                                      void* data),\n                             void* data) const override;\n\n  hsa_status_t IterateSupportedIsas(\n                    hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                                  void* data) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                            void* value) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopy(void* dst, const void* src, size_t size) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopy(void* dst, core::Agent& dst_agent, const void* src,\n                       core::Agent& src_agent, size_t size,\n                       std::vector<core::Signal*>& dep_signals,\n                       core::Signal& out_signal) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopyOnEngine(void* dst, core::Agent& dst_agent, const void* src,\n                       core::Agent& src_agent, size_t size,\n                       std::vector<core::Signal*>& dep_signals,\n                       core::Signal& out_signal, int engine_offset,\n                       bool force_copy_on_sdma) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopyStatus(core::Agent& dst_agent, core::Agent& src_agent,\n                             uint32_t *engine_ids_mask) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaPreferredEngine(core::Agent& dst_agent, core::Agent& src_agent,\n                                  uint32_t* recommended_ids_mask) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaCopyRect(const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset,\n                           const hsa_pitched_ptr_t* src, const hsa_dim3_t* src_offset,\n                           const hsa_dim3_t* range, hsa_amd_copy_direction_t dir,\n                           std::vector<core::Signal*>& dep_signals, core::Signal& out_signal);\n\n  // @brief Override from core::Agent.\n  hsa_status_t DmaFill(void* ptr, uint32_t value, size_t count) override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t GetInfo(hsa_agent_info_t attribute, void* value) const override;\n\n  // @brief Override from core::Agent.\n  hsa_status_t QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                           core::HsaEventCallback event_callback, void* data,\n                           uint32_t private_segment_size, uint32_t group_segment_size,\n                           core::Queue** queue) override;\n\n  // @brief Decrement GWS ref count.\n  void GWSRelease();\n\n  // @brief Override from AMD::GpuAgentInt.\n  void AcquireQueueMainScratch(ScratchInfo& scratch) override;\n  void ReleaseQueueMainScratch(ScratchInfo& scratch) override;\n\n  void AcquireQueueAltScratch(ScratchInfo& scratch) override;\n  void ReleaseQueueAltScratch(ScratchInfo& scratch) override;\n\n  // @brief Override from AMD::GpuAgentInt.\n  void TranslateTime(core::Signal* signal, hsa_amd_profiling_dispatch_time_t& time) override;\n\n  // @brief Override from AMD::GpuAgentInt.\n  void TranslateTime(core::Signal* signal, hsa_amd_profiling_async_copy_time_t& time) override;\n\n  // @brief Override from AMD::GpuAgentInt.\n  uint64_t TranslateTime(uint64_t tick) override;\n\n  // @brief Override from AMD::GpuAgentInt.\n  void InvalidateCodeCaches(void* ptr, size_t size) override;\n\n  // @brief Override from AMD::GpuAgentInt.\n  bool current_coherency_type(hsa_amd_coherency_type_t type) override;\n\n  hsa_amd_coherency_type_t current_coherency_type() const override {\n    return current_coherency_type_;\n  }\n\n  core::Agent* GetNearestCpuAgent(void) const;\n\n  void RegisterGangPeer(core::Agent& gang_peer, unsigned int bandwidth_factor) override;\n\n  void RegisterRecSdmaEngIdMaskPeer(core::Agent& gang_peer, uint32_t rec_sdma_eng_id_mask) override;\n\n  // Getter & setters.\n\n  // @brief Returns Hive ID\n  __forceinline uint64_t HiveId() const override { return  properties_.HiveID; }\n\n  // @brief Returns KFD's GPU id which is a hash used internally.\n  __forceinline uint64_t KfdGpuID() const { return properties_.KFDGpuID; }\n\n  // @brief Returns node property.\n  __forceinline const HsaNodeProperties& properties() const {\n    return properties_;\n  }\n\n  // @brief set rec_sdma_eng_override_\n  __forceinline void SetRecSdmaEngOverride(bool flag) override { rec_sdma_eng_override_ = flag; }\n\n  // @brief Returns number of data caches.\n  __forceinline size_t num_cache() const { return cache_props_.size(); }\n\n  // @brief Returns data cache property.\n  //\n  // @param [in] idx Cache level.\n  __forceinline const HsaCacheProperties& cache_prop(int idx) const {\n    return cache_props_[idx];\n  }\n\n  // @brief Override from core::Agent.\n  const std::vector<const core::MemoryRegion*>& regions() const override {\n    return regions_;\n  }\n\n  const std::vector<const core::Isa *>& supported_isas() const override {\n                                                      return supported_isas_;}\n\n  // @brief Override from AMD::GpuAgentInt.\n  __forceinline hsa_profile_t profile() const override { return profile_; }\n\n  // @brief Override from AMD::GpuAgentInt.\n  __forceinline uint32_t memory_bus_width() const override {\n    return memory_bus_width_;\n  }\n\n  // @brief Override from AMD::GpuAgentInt.\n  __forceinline uint32_t memory_max_frequency() const override {\n    return memory_max_frequency_;\n  }\n\n  // @brief Order the device is surfaced in hsa_iterate_agents counting only\n  // GPU devices.\n  __forceinline uint32_t enumeration_index() const { return enum_index_; }\n\n  // @brief returns true if agent uses MES scheduler\n  __forceinline const bool isMES() const { return (isa_->GetMajorVersion() >= 11) ? true : false; };\n\n  // @brief returns the libdrm device handle\n  __forceinline amdgpu_device_handle libDrmDev() const { return ldrm_dev_; }\n\n  __forceinline void CheckClockTicks() {\n    // If we did not update t1 since agent initialization, force a SyncClock. Otherwise computing\n    // the SystemClockCounter to GPUClockCounter ratio in TranslateTime(tick) results to a division\n    // by 0.\n    if (t0_.GPUClockCounter == t1_.GPUClockCounter) SyncClocks();\n  }\n\n  /// @brief Override from AMD::GpuAgentInt.\n  __forceinline bool is_xgmi_cpu_gpu() const { return xgmi_cpu_gpu_; }\n  /// @brief Is large BAR support enabled for this GPU.\n  __forceinline bool LargeBarEnabled() const { return large_bar_enabled_; }\n\n  /// @brief Force a WC flush on PCIe devices by doing a write and then read-back\n  __forceinline void PcieWcFlush(void *ptr, size_t size) const {\n    if (!xgmi_cpu_gpu_) {\n      _mm_sfence();\n      *((uint8_t*)ptr + size - 1) = *((uint8_t*)ptr + size - 1);\n      _mm_mfence();\n      auto readback = *(reinterpret_cast<volatile uint8_t*>(ptr) + size - 1);\n      UNUSED(readback);\n    }\n  }\n\n  const size_t MAX_SCRATCH_APERTURE_PER_XCC = (1ULL << 32);\n  size_t MaxScratchDevice() const { return properties_.NumXcc * MAX_SCRATCH_APERTURE_PER_XCC; }\n\n  void ReserveScratch();\n\n  // @brief If agent supports it, release scratch memory for all AQL queues on this agent.\n  void AsyncReclaimScratchQueues();\n\n  // @brief Returns true if scratch reclaim is enabled\n  __forceinline bool AsyncScratchReclaimEnabled() const override {\n    const uint32_t GFX94X_MIN_CP_FW_VERSION_REQUIRED = 177;\n    const uint32_t GFX95X_MIN_CP_FW_VERSION_REQUIRED = 24;\n\n    return (core::Runtime::runtime_singleton_->flag().enable_scratch_async_reclaim() &&\n\t    supported_isas()[0]->GetMajorVersion() == 9 &&\n\t    ((supported_isas()[0]->GetMinorVersion() == 4 &&\n\t      properties_.EngineId.ui32.uCode >= GFX94X_MIN_CP_FW_VERSION_REQUIRED) ||\n\t     (supported_isas()[0]->GetMinorVersion() == 5 &&\n\t      properties_.EngineId.ui32.uCode >= GFX95X_MIN_CP_FW_VERSION_REQUIRED)));\n  };\n\n  hsa_status_t SetAsyncScratchThresholds(size_t use_once_limit) override;\n\n  __forceinline size_t ScratchSingleLimitAsyncThreshold() const {\n    return scratch_limit_async_threshold_;\n  }\n\n  void Trim() override;\n\n  const std::function<void*(size_t size, size_t align, core::MemoryRegion::AllocateFlags flags)>&\n  system_allocator() const {\n    return system_allocator_;\n  }\n\n  const std::function<void(void*)>& system_deallocator() const { return system_deallocator_; }\n\n  const std::function<void*(size_t size, core::MemoryRegion::AllocateFlags flags)>&\n  finegrain_allocator() const {\n    return finegrain_allocator_;\n  }\n\n  const std::function<void(void*)>& finegrain_deallocator() const { return finegrain_deallocator_; }\n\n  /// @brief Allocate coarse grain device memory on this GPU agent.\n  const std::function<void*(size_t size, core::MemoryRegion::AllocateFlags flags)>&\n  coarsegrain_allocator() const {\n    return coarsegrain_allocator_;\n  }\n\n  /// @brief Deallocate memory allocated from the coarsegrain_allocator\n  /// on this GPU agent.\n  const std::function<void(void*)>& coarsegrain_deallocator() const {\n    return coarsegrain_deallocator_;\n  }\n\n protected:\n  // Sizes are in packets.\n  const uint32_t minAqlSize_ = 0x40;     // 4KB min\n  const uint32_t maxAqlSize_ = 0x20000;  // 8MB max\n\n  // @brief Create an internal queue allowing tools to be notified.\n  core::Queue* CreateInterceptibleQueue(const uint32_t size = 0) {\n    return CreateInterceptibleQueue(core::Queue::DefaultErrorHandler, nullptr, size);\n  }\n\n  // @brief Create an internal queue, with a custom error handler, allowing tools to be\n  // notified.\n  core::Queue* CreateInterceptibleQueue(void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),\n                                        void* data, const uint32_t size);\n\n  // @brief Create SDMA blit object.\n  //\n  // @retval NULL if SDMA blit creation and initialization failed.\n  core::Blit* CreateBlitSdma(bool use_xgmi, int rec_eng);\n\n  // @brief Create Kernel blit object using provided compute queue.\n  //\n  // @retval NULL if Kernel blit creation and initialization failed.\n  core::Blit* CreateBlitKernel(core::Queue* queue);\n\n  // @brief Invoke the user provided callback for every region in @p regions.\n  //\n  // @param [in] regions Array of region object.\n  // @param [in] callback User provided callback function.\n  // @param [in] data User provided pointer as input for @p callback.\n  //\n  // @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  // region returns ::HSA_STATUS_SUCCESS.\n  hsa_status_t VisitRegion(\n      const std::vector<const core::MemoryRegion*>& regions,\n      hsa_status_t (*callback)(hsa_region_t region, void* data),\n      void* data) const;\n\n  // @brief Update ::t1_ tick count.\n  void SyncClocks();\n\n  // @brief Binds the second-level trap handler to this node.\n  void BindTrapHandler();\n\n  // @brief Override from core::Agent.\n  hsa_status_t EnableDmaProfiling(bool enable) override;\n\n  hsa_status_t PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb,\n                                       void* cb_data) override;\n  hsa_status_t PcSamplingCreate(pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingCreateFromId(HsaPcSamplingTraceId pcsId,\n                            pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingDestroy(pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingStart(pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingStop(pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingFlush(pcs::PcsRuntime::PcSamplingSession& session) override;\n  hsa_status_t PcSamplingFlushDeviceBuffers(pcs::PcsRuntime::PcSamplingSession& session);\n\n  // @brief Node properties.\n  const HsaNodeProperties properties_;\n\n  // @brief Current coherency type.\n  hsa_amd_coherency_type_t current_coherency_type_;\n\n  // @brief Maximum number of queues that can be created.\n  uint32_t max_queues_;\n\n  // @brief Object to manage scratch memory.\n  SmallHeap scratch_pool_;\n\n  // @brief Current short duration scratch memory size.\n  size_t scratch_used_large_;\n\n  // @brief Notifications for scratch release.\n  std::map<hsa_signal_t, hsa_signal_value_t> scratch_notifiers_;\n\n  // @brief Default scratch size per queue.\n  size_t queue_scratch_len_;\n\n  // @brief Default scratch size per work item.\n  size_t scratch_per_thread_;\n\n  // @brief Blit interfaces for each data path.\n  enum BlitEnum { BlitDevToDev, BlitHostToDev, BlitDevToHost, DefaultBlitCount };\n\n  // Blit objects managed by an instance of GpuAgent\n  std::vector<lazy_ptr<core::Blit>> blits_;\n\n  // List of agents connected via xGMI\n  std::vector<const core::Agent*> xgmi_peer_list_;\n\n  // Protects xgmi_peer_list_\n  KernelMutex xgmi_peer_list_lock_;\n\n  // @brief AQL queues for cache management and blit compute usage.\n  enum QueueEnum {\n    QueueUtility,     // Cache management and device to {host,device} blit compute\n    QueueBlitOnly,    // Host to device blit\n    QueuePCSampling,  // Dedicated high priority queue for PC Sampling\n    QueueCount\n  };\n\n  lazy_ptr<core::Queue> queues_[QueueCount];\n\n  // @brief Mutex to protect the update to coherency type.\n  KernelMutex coherency_lock_;\n\n  // @brief Mutex to protect access to scratch pool.\n  KernelMutex scratch_lock_;\n\n  // @brief Mutex to protect access to ::t1_.\n  KernelMutex t1_lock_;\n\n  // @brief Mutex to protect access to blit objects.\n  KernelMutex blit_lock_;\n\n  // @brief Mutex to protect sdma gang submissions.\n  KernelMutex sdma_gang_lock_;\n\n  // @brief GPU tick on initialization.\n  HsaClockCounters t0_;\n\n  HsaClockCounters t1_;\n\n  double historical_clock_ratio_;\n\n  // @brief s_memrealtime nominal clock frequency\n  uint64_t wallclock_frequency_;\n\n  // @brief Array of GPU cache property.\n  std::vector<HsaCacheProperties> cache_props_;\n\n  // @brief Array of HSA cache objects.\n  std::vector<std::unique_ptr<core::Cache>> caches_;\n\n  // @brief Array of regions owned by this agent.\n  std::vector<const core::MemoryRegion*> regions_;\n\n  core::Isa* isa_;\n\n  // @brief HSA profile.\n  hsa_profile_t profile_;\n\n  void* trap_code_buf_;\n\n  size_t trap_code_buf_size_;\n\n  // @brief Mappings from doorbell index to queue, for trap handler.\n  // Correlates with output of s_sendmsg(MSG_GET_DOORBELL) for queue identification.\n  amd_queue_v2_t** doorbell_queue_map_;\n\n  // @brief The GPU memory bus width in bit.\n  uint32_t memory_bus_width_;\n\n  // @brief The GPU memory maximum frequency in MHz.\n  uint32_t memory_max_frequency_;\n\n  // @brief Enumeration index\n  uint32_t enum_index_;\n\n  // @brief HDP flush registers\n  hsa_amd_hdp_flush_t HDP_flush_ = {nullptr, nullptr};\n\n private:\n  // @brief Query the driver to get the region list owned by this agent.\n  void InitRegionList();\n\n  // @brief Reserve memory for scratch pool to be used by AQL queue of this\n  // agent.\n  void InitScratchPool();\n\n  // @brief Query the driver to get the cache properties.\n  void InitCacheList();\n\n  // @brief Create internal queues and blits.\n  void InitDma();\n\n  // @brief Setup GWS accessing queue.\n  void InitGWS();\n\n  // @brief Set-up memory allocators\n  void InitAllocators();\n\n  // @brief Initialize scratch handler thresholds\n  void InitAsyncScratchThresholds();\n\n  // @brief Register signal for notification when scratch may become available.\n  // @p signal is notified by OR'ing with @p value.\n  bool AddScratchNotifier(hsa_signal_t signal, hsa_signal_value_t value) {\n    if (signal.handle != 0) return false;\n    scratch_notifiers_[signal] = value;\n    return true;\n  }\n\n  // @brief Deregister scratch notification signals.\n  void ClearScratchNotifiers() { scratch_notifiers_.clear(); }\n\n  // @brief Releases scratch back to the driver.\n  // caller must hold scratch_lock_.\n  void ReleaseScratch(void* base, size_t size, bool large);\n\n  // Bind index of peer device that is connected via xGMI links\n  lazy_ptr<core::Blit>& GetXgmiBlit(const core::Agent& peer_agent);\n\n  // Bind the Blit object that will drive the copy operation\n  // across PCIe links (H2D or D2H) or is within same device D2D\n  lazy_ptr<core::Blit>& GetPcieBlit(const core::Agent& dst_agent, const core::Agent& src_agent);\n\n  // Bind the Blit object that will drive the copy operation\n  lazy_ptr<core::Blit>& GetBlitObject(const core::Agent& dst_agent, const core::Agent& src_agent,\n                                      const size_t size);\n\n  // Bind the Blit object that will drive the copy operation by engine ID\n  lazy_ptr<core::Blit>& GetBlitObject(uint32_t engine_id);\n\n  // @brief initialize libdrm handle\n  void InitLibDrm();\n\n  void GetInfoMemoryProperties(uint8_t value[8]) const;\n\n  // @brief Alternative aperture base address. Only on KV.\n  uintptr_t ape1_base_;\n\n  // @brief Queue with GWS access.\n  struct {\n    lazy_ptr<core::Queue> queue_;\n    int ref_ct_;\n    KernelMutex lock_;\n  } gws_queue_;\n\n  // @brief list of AQL queues owned by this agent. Indexed by queue pointer\n  std::vector<core::Queue*> aql_queues_;\n\n  // Sets and Tracks pending SDMA status check or request counts\n  void SetCopyRequestRefCount(bool set);\n  void SetCopyStatusCheckRefCount(bool set);\n  int pending_copy_req_ref_;\n  int pending_copy_stat_check_ref_;\n\n  // Tracks what SDMA blits have been used since initialization.\n  uint32_t sdma_blit_used_mask_;\n\n  // Scratch limit thresholds when async scratch is enabled.\n  uint64_t scratch_limit_async_threshold_;\n\n  ScratchCache scratch_cache_;\n\n  /// @brief System memory allocator in the nearest NUMA node.\n  std::function<void*(size_t size, size_t align, core::MemoryRegion::AllocateFlags flags)>\n      system_allocator_;\n  /// @brief System memory deallocator in the nearest NUMA node.\n  std::function<void(void*)> system_deallocator_;\n  /// @brief Fine-grain allocator on this GPU.\n  std::function<void*(size_t size, core::MemoryRegion::AllocateFlags flags)> finegrain_allocator_;\n  /// @brief Fine-grain deallocator on this GPU.\n  std::function<void(void*)> finegrain_deallocator_;\n  /// @brief Coarse-grain allocator on this GPU.\n  std::function<void*(size_t size, core::MemoryRegion::AllocateFlags flags)> coarsegrain_allocator_;\n  /// @brief Coarse-grain deallocator on this GPU.\n  std::function<void(void*)> coarsegrain_deallocator_;\n\n  void* trap_handler_tma_region_;\n\n  /* PC Sampling fields - begin */\n  /* 2nd level Trap handler code is based on the offsets within this structure */\n  typedef struct {\n    uint64_t buf_write_val;\n    uint32_t buf_size;\n    uint32_t reserved0;\n    uint32_t buf_written_val0;\n    uint32_t buf_watermark0;\n    hsa_signal_t done_sig0;\n    uint32_t buf_written_val1;\n    uint32_t buf_watermark1;\n    hsa_signal_t done_sig1;\n    uint8_t reserved1[16];\n    /* pc_sample_t buffer0[buf_size]; */\n    /* pc_sample_t buffer1[buf_size]; */\n  } pcs_sampling_data_t;\n\n  typedef struct {\n    /* Sampling data - stored on device for trap handler access */\n    pcs_sampling_data_t* device_data;\n\n    /* Sampling host buffer - stored on host */\n    uint8_t* host_buffer;\n    size_t host_buffer_size;\n    uint8_t* host_buffer_wrap_pos;\n    uint8_t* host_write_ptr;\n    uint8_t* host_read_ptr;\n    size_t lost_sample_count;\n    std::mutex host_buffer_mutex;\n\n    uint32_t which_buffer;\n    uint64_t* old_val;\n    uint32_t* cmd_data;\n    size_t cmd_data_sz;\n    // signal to pass into ExecutePM4() so that we do not need to re-allocate a\n    // new signal on each call\n    hsa_signal_t exec_pm4_signal;\n\n    os::Thread thread;\n    pcs::PcsRuntime::PcSamplingSession* session;\n  } pcs_data_t;\n  /* PC Sampling fields - end */\n\n  hsa_status_t UpdateTrapHandlerWithPCS(pcs_sampling_data_t* pcs_hosttrap_buffers,\n                                        pcs_sampling_data_t* pcs_stochastic_buffers);\n\n  // @brief Thread function to process PC sampling data collected via host-trap\n  // or Stochastic sampling.\n  void PcSamplingThread(pcs_data_t& pcs_data, const char* thread_name);\n\n  // @brief device handle\n  amdgpu_device_handle ldrm_dev_;\n\n  DISALLOW_COPY_AND_ASSIGN(GpuAgent);\n\n  // Check if SDMA engine by ID is free\n  bool DmaEngineIsFree(uint32_t engine_id);\n\n  std::map<uint64_t,unsigned int> gang_peers_info_;\n\n  std::map<uint64_t, uint32_t> rec_sdma_eng_id_peers_info_;\n\n  bool uses_rec_sdma_eng_id_mask_;\n  bool rec_sdma_eng_override_;\n\n  // structure for host trap sampling\n  pcs_data_t pcs_hosttrap_data_;\n\n  // structure for stochastic sampling\n  pcs_data_t pcs_stochastic_data_;\n\n  /// @brief XGMI CPU<->GPU\n  bool xgmi_cpu_gpu_;\n  /// @brief Is PCIe large BAR enabled.\n  bool large_bar_enabled_;\n};\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_gpu_pm4.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_GPU_PM4_H_\n#define HSA_RUNTIME_CORE_INC_AMD_GPU_PM4_H_\n\n // clang-format off\n\n#define PM4_HDR_IT_OPCODE_NOP                             0x10\n#define PM4_HDR_IT_OPCODE_INDIRECT_BUFFER                 0x3F\n#define PM4_HDR_IT_OPCODE_RELEASE_MEM                     0x49\n#define PM4_HDR_IT_OPCODE_ACQUIRE_MEM                     0x58\n\n#define PM4_HDR_IT_OPCODE_ATOMIC_MEM                      0x1E\n#define PM4_HDR_IT_OPCODE_PRED_EXEC                       0x23\n#define PM4_HDR_IT_OPCODE_WRITE_DATA                      0x37\n#define PM4_HDR_IT_OPCODE_WAIT_REG_MEM                    0x3C\n#define PM4_HDR_IT_OPCODE_COPY_DATA                       0x40\n#define PM4_HDR_IT_OPCODE_DMA_DATA                        0x50\n\n#define PM4_HDR_SHADER_TYPE(x)                            (((x) & 0x1) << 1)\n#define PM4_HDR_IT_OPCODE(x)                              (((x) & 0xFF) << 8)\n#define PM4_HDR_COUNT(x)                                  (((x) & 0x3FFF) << 16)\n#define PM4_HDR_TYPE(x)                                   (((x) & 0x3) << 30)\n\n#define PM4_HDR(it_opcode, pkt_size_dw, gfxip_ver) (  \\\n  PM4_HDR_SHADER_TYPE((gfxip_ver) == 7 ? 1 : 0)    |  \\\n  PM4_HDR_IT_OPCODE(it_opcode)                     |  \\\n  PM4_HDR_COUNT(pkt_size_dw - 2)                   |  \\\n  PM4_HDR_TYPE(3)                                     \\\n)\n\n#define PM4_INDIRECT_BUFFER_DW1_IB_BASE_LO(x)              (((x) & 0x3FFFFFFF) << 2)\n#define PM4_INDIRECT_BUFFER_DW2_IB_BASE_HI(x)              (((x) & 0xFFFF) << 0)\n#define PM4_INDIRECT_BUFFER_DW3_IB_SIZE(x)                 (((x) & 0xFFFFF) << 0)\n#define PM4_INDIRECT_BUFFER_DW3_IB_VALID(x)                (((x) & 0x1) << 23)\n\n#define PM4_ACQUIRE_MEM_DW1_COHER_CNTL(x)                  (((x) & 0x7FFFFFFF) << 0)\n#  define PM4_ACQUIRE_MEM_COHER_CNTL_TC_WB_ACTION_ENA      (1 << 18)\n#  define PM4_ACQUIRE_MEM_COHER_CNTL_TC_ACTION_ENA         (1 << 23)\n#  define PM4_ACQUIRE_MEM_COHER_CNTL_SH_KCACHE_ACTION_ENA  (1 << 27)\n#  define PM4_ACQUIRE_MEM_COHER_CNTL_SH_ICACHE_ACTION_ENA  (1 << 29)\n#define PM4_ACQUIRE_MEM_DW2_COHER_SIZE(x)                  (((x) & 0xFFFFFFFF) << 0)\n#define PM4_ACQUIRE_MEM_DW3_COHER_SIZE_HI(x)               (((x) & 0xFF) << 0)\n#define PM4_ACQUIRE_MEM_DW4_COHER_BASE(x)                  ((x >> 8) & 0xFFFFFFFF)\n#define PM4_ACQUIRE_MEM_DW4_COHER_BASE_HI(x)               ((x >> 40) & 0xFFFFFF)\n#define PM4_ACQUIRE_MEM_DW7_GCR_CNTL(x)                    (((x) & 0x7FFFF) << 0)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GLI_INV(x)              (((x) & 0x3) << 0)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GLK_INV                 (1 << 7)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GLV_INV                 (1 << 8)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GL1_INV                 (1 << 9)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GL2_INV                 (1 << 14)\n#  define PM4_ACQUIRE_MEM_GCR_CNTL_GL2_WB                  (1 << 15)\n#define PM4_RELEASE_MEM_DW1_EVENT_INDEX(x)                 (((x) & 0xF) << 8)\n#  define PM4_RELEASE_MEM_EVENT_INDEX_AQL                  0x7\n\n#define PM4_ATOMIC_MEM_DW1_ATOMIC(x)                       (((x) & 0x7F) << 0)\n#  define PM4_ATOMIC_MEM_GL2_OP_ATOMIC_SWAP_RTN_64         (39 << 0)\n#define PM4_ATOMIC_MEM_DW2_ADDR_LO(x)                      (((x) & 0xFFFFFFF8) << 0)\n#define PM4_ATOMIC_MEM_DW3_ADDR_HI(x)                      (((x) & 0xFFFFFFFF) << 0)\n#define PM4_ATOMIC_MEM_DW4_SRC_DATA_LO(x)                  (((x) & 0xFFFFFFFF) << 0)\n#define PM4_ATOMIC_MEM_DW5_SRC_DATA_HI(x)                  (((x) & 0xFFFFFFFF) << 0)\n\n#define PM4_PRED_EXEC_DW1_HEADER(x)                        (((x) & 0xFFFFFFFF) << 0)\n#define PM4_PRED_EXEC_DW2_EXEC_COUNT(x)                    (((x) & 0x3FFF) << 0)\n#define PM4_PRED_EXEC_DW2_VIRTUALXCCID_SELECT(x)           (((x) & 0xFF) << 24)\n\n#define PM4_COPY_DATA_DW1(x)                               (((x) & 0xFFFFFFFF) << 0)\n#  define PM4_COPY_DATA_SRC_SEL_ATOMIC_RETURN_DATA         (6 << 0)\n#  define PM4_COPY_DATA_DST_SEL_TC_12                      (2 << 8)\n#  define PM4_COPY_DATA_COUNT_SEL                          (1 << 16)\n#  define PM4_COPY_DATA_WR_CONFIRM                         (1 << 20)\n#define PM4_COPY_DATA_DW4_DST_ADDR_LO(x)                   (((x) & 0xFFFFFFF8) << 0)\n#define PM4_COPY_DATA_DW5_DST_ADDR_HI(x)                   (((x) & 0xFFFFFFFF) << 0)\n\n#define PM4_WAIT_REG_MEM_DW1(x)                            (((x) & 0xFFFFFFFF) << 0)\n#  define PM4_WAIT_REG_MEM_FUNCTION_EQUAL_TO_REFERENCE     (3 << 0)\n#  define PM4_WAIT_REG_MEM_MEM_SPACE_MEMORY_SPACE          (1 << 4)\n#  define PM4_WAIT_REG_MEM_OPERATION_WAIT_REG_MEM          (0 << 6)\n#define PM4_WAIT_REG_MEM_DW2_MEM_POLL_ADDR_LO(x)           (((x) & 0xFFFFFFFC) << 0)\n#define PM4_WAIT_REG_MEM_DW3_MEM_POLL_ADDR_HI(x)           (((x) & 0xFFFFFFFF) << 0)\n#define PM4_WAIT_REG_MEM_DW4_REFERENCE(x)                  (((x) & 0xFFFFFFFF) << 0)\n#define PM4_WAIT_REG_MEM_DW6(x)                            (((x) & 0x8000FFFF) << 0)\n#  define PM4_WAIT_REG_MEM_POLL_INTERVAL(x)                (((x) & 0xFFFF) << 0)\n#  define PM4_WAIT_REG_MEM_OPTIMIZE_ACE_OFFLOAD_MODE       (1 << 31)\n\n#define PM4_DMA_DATA_DW1(x)                            (((x) & 0xFFFFFFFF) << 0)\n#  define PM4_DMA_DATA_DST_SEL_DST_ADDR_USING_L2       (3 << 20)\n#  define PM4_DMA_DATA_SRC_SEL_SRC_ADDR_USING_L2       (3 << 29)\n#define PM4_DMA_DATA_DW2_SRC_ADDR_LO(x)                (((x) & 0xFFFFFFFF) << 0)\n#define PM4_DMA_DATA_DW3_SRC_ADDR_HI(x)                (((x) & 0xFFFFFFFF) << 0)\n#define PM4_DMA_DATA_DW4_DST_ADDR_LO(x)                (((x) & 0xFFFFFFFF) << 0)\n#define PM4_DMA_DATA_DW5_DST_ADDR_HI(x)                (((x) & 0xFFFFFFFF) << 0)\n#define PM4_DMA_DATA_DW6(x)                            (((x) & 0xFFFFFFFF) << 0)\n#  define PM4_DMA_DATA_BYTE_COUNT(x)                   (((x) & 0x3FFFFFF) << 0)\n#  define PM4_DMA_DATA_DIS_WC                          (1 << 31)\n#  define PM4_DMA_DATA_DIS_WC_LAST                     (0 << 31)\n\n#define PM4_WRITE_DATA_DW1(x)                          (((x) & 0xFFFFFF00) << 0)\n#  define PM4_WRITE_DATA_DST_SEL_TC_L2                 (2 << 8)\n#  define PM4_WRITE_DATA_WR_CONFIRM_WAIT_CONFIRMATION  (1 << 20)\n#define PM4_WRITE_DATA_DW2_DST_MEM_ADDR_LO(x)          (((x) & 0xFFFFFFFC) << 0)\n#define PM4_WRITE_DATA_DW3_DST_MEM_ADDR_HI(x)          (((x) & 0xFFFFFFFF) << 0)\n#define PM4_WRITE_DATA_DW4_DATA(x)                     (((x) & 0xFFFFFFFF) << 0)\n\n// clang-format on\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_hsa_code.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_CODE_HPP_\n#define AMD_HSA_CODE_HPP_\n\n#include \"core/inc/amd_elf_image.hpp\"\n#include \"inc/amd_hsa_elf.h\"\n#include \"inc/amd_hsa_kernel_code.h\"\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_finalize.h\"\n#include <memory>\n#include <sstream>\n#include <cassert>\n#include <unordered_map>\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace common {\n\ntemplate<uint64_t signature>\nclass Signed {\npublic:\n  static const uint64_t CT_SIGNATURE;\n  const uint64_t RT_SIGNATURE;\n\nprotected:\n  Signed(): RT_SIGNATURE(signature) {}\n  virtual ~Signed() {}\n};\n\ntemplate<uint64_t signature>\nconst uint64_t Signed<signature>::CT_SIGNATURE = signature;\n\nbool IsAccessibleMemoryAddress(uint64_t address);\n\ntemplate<typename class_type, typename member_type>\nsize_t OffsetOf(member_type class_type::*member)\n{\n  return (char*)&((class_type*)nullptr->*member) - (char*)nullptr;\n}\n\ntemplate<typename class_type>\nclass_type* ObjectAt(uint64_t address)\n{\n  if (!IsAccessibleMemoryAddress(address)) {\n    return nullptr;\n  }\n\n  const uint64_t *rt_signature =\n    (const uint64_t*)(address + OffsetOf(&class_type::RT_SIGNATURE));\n  if (nullptr == rt_signature) {\n    return nullptr;\n  }\n  if (class_type::CT_SIGNATURE != *rt_signature) {\n    return nullptr;\n  }\n\n  return (class_type*)address;\n}\n\n}   //  namespace common\n\nnamespace code {\n\n    typedef amd::elf::Segment Segment;\n    typedef amd::elf::Section Section;\n    typedef amd::elf::RelocationSection RelocationSection;\n    typedef amd::elf::Relocation Relocation;\n\n    class KernelSymbol;\n    class VariableSymbol;\n\n    class Symbol {\n    protected:\n      amd::elf::Symbol* elfsym;\n\n    public:\n      explicit Symbol(amd::elf::Symbol* elfsym_)\n        : elfsym(elfsym_) { }\n      virtual ~Symbol() { }\n      virtual bool IsKernelSymbol() const { return false; }\n      virtual KernelSymbol* AsKernelSymbol() { assert(false); return 0; }\n      virtual bool IsVariableSymbol() const { return false; }\n      virtual VariableSymbol* AsVariableSymbol() { assert(false); return 0; }\n      amd::elf::Symbol* elfSym() { return elfsym; }\n      std::string Name() const { return elfsym ? elfsym->name() : \"\"; }\n      Section* GetSection() { return elfsym->section(); }\n      virtual uint64_t SectionOffset() const { return elfsym->value(); }\n      virtual uint64_t VAddr() const { return elfsym->section()->addr() + elfsym->value(); }\n      uint32_t Index() const { return elfsym ? elfsym->index() : 0; }\n      bool IsDeclaration() const;\n      bool IsDefinition() const;\n      virtual bool IsAgent() const;\n      virtual hsa_symbol_kind_t Kind() const = 0;\n      hsa_symbol_linkage_t Linkage() const;\n      hsa_variable_allocation_t Allocation() const;\n      hsa_variable_segment_t Segment() const;\n      uint64_t Size() const;\n      uint32_t Size32() const;\n      uint32_t Alignment() const;\n      bool IsConst() const;\n      virtual hsa_status_t GetInfo(hsa_code_symbol_info_t attribute, void *value);\n      static hsa_code_symbol_t ToHandle(Symbol* sym);\n      static Symbol* FromHandle(hsa_code_symbol_t handle);\n      void setValue(uint64_t value) { elfsym->setValue(value); }\n      void setSize(uint32_t size) { elfsym->setSize(size); }\n\n      std::string GetModuleName() const;\n      std::string GetSymbolName() const;\n    };\n\n    class KernelSymbol : public Symbol {\n    private:\n      uint32_t kernarg_segment_size, kernarg_segment_alignment;\n      uint32_t group_segment_size, private_segment_size;\n      bool is_dynamic_callstack;\n\n    public:\n      explicit KernelSymbol(amd::elf::Symbol* elfsym_, const amd_kernel_code_t* akc);\n      bool IsKernelSymbol() const override { return true; }\n      KernelSymbol* AsKernelSymbol() override { return this; }\n      hsa_symbol_kind_t Kind() const override { return HSA_SYMBOL_KIND_KERNEL; }\n      hsa_status_t GetInfo(hsa_code_symbol_info_t attribute, void *value) override;\n    };\n\n    class VariableSymbol : public Symbol {\n    public:\n      explicit VariableSymbol(amd::elf::Symbol* elfsym_)\n        : Symbol(elfsym_) { }\n      bool IsVariableSymbol() const override { return true; }\n      VariableSymbol* AsVariableSymbol() override { return this; }\n      hsa_symbol_kind_t Kind() const override { return HSA_SYMBOL_KIND_VARIABLE; }\n      hsa_status_t GetInfo(hsa_code_symbol_info_t attribute, void *value) override;\n    };\n\n    class AmdHsaCode {\n    private:\n      std::ostringstream out;\n      std::unique_ptr<amd::elf::Image> img;\n      std::vector<Segment*> dataSegments;\n      std::vector<Section*> dataSections;\n      std::vector<RelocationSection*> relocationSections;\n      std::vector<Symbol*> symbols;\n      bool combineDataSegments;\n      Segment* hsaSegments[AMDGPU_HSA_SEGMENT_LAST][2];\n      Section* hsaSections[AMDGPU_HSA_SECTION_LAST];\n\n      amd::elf::Section* hsatext;\n      amd::elf::Section* imageInit;\n      amd::elf::Section* samplerInit;\n      amd::elf::Section* debugInfo;\n      amd::elf::Section* debugLine;\n      amd::elf::Section* debugAbbrev;\n\n      bool PullElf();\n      bool PullElfV1();\n      bool PullElfV2();\n\n      void AddAmdNote(uint32_t type, const void* desc, uint32_t desc_size);\n      template <typename S>\n      bool GetAmdNote(uint32_t type, S** desc)\n      {\n        uint32_t desc_size;\n        if (!img->note()->getNote(\"AMD\", type, (void**) desc, &desc_size)) {\n          out << \"Failed to find note, type: \" << type << std::endl;\n          return false;\n        }\n        if (desc_size < sizeof(S)) {\n          out << \"Note size mismatch, type: \" << type << \" size: \" << desc_size << \" expected at least \" << sizeof(S) << std::endl;\n          return false;\n        }\n        return true;\n      }\n\n      void PrintSegment(std::ostream& out, Segment* segment);\n      void PrintSection(std::ostream& out, Section* section);\n      void PrintRawData(std::ostream& out, Section* section);\n      void PrintRawData(std::ostream& out, const unsigned char *data, size_t size);\n      void PrintRelocationData(std::ostream& out, RelocationSection* section);\n      void PrintSymbol(std::ostream& out, Symbol* sym);\n      void PrintDisassembly(std::ostream& out, const unsigned char *isa, size_t size, uint32_t isa_offset = 0);\n      std::string MangleSymbolName(const std::string& module_name, const std::string& symbol_name);\n      bool ElfImageError();\n\n    public:\n      bool HasHsaText() const { return hsatext != 0; }\n      amd::elf::Section* HsaText() { assert(hsatext); return hsatext; }\n      const amd::elf::Section* HsaText() const { assert(hsatext); return hsatext; }\n      amd::elf::SymbolTable* Symtab() { assert(img); return img->symtab(); }\n      uint16_t Machine() const { return img->Machine(); }\n      uint32_t EFlags() const { return img->EFlags(); }\n      uint32_t EClass() const { return img->EClass(); }\n      uint32_t OsAbi() const { return img->OsAbi(); }\n\n      AmdHsaCode(bool combineDataSegments = true);\n      virtual ~AmdHsaCode();\n\n      std::string output() { return out.str(); }\n      bool LoadFromFile(const std::string& filename);\n      bool SaveToFile(const std::string& filename);\n      bool WriteToBuffer(void* buffer);\n      bool InitFromBuffer(const void* buffer, size_t size);\n      bool InitAsBuffer(const void* buffer, size_t size);\n      bool InitAsHandle(hsa_code_object_t code_handle);\n      bool InitNew(bool xnack = false);\n      bool Freeze();\n      hsa_code_object_t GetHandle();\n      const char* ElfData();\n      uint64_t ElfSize();\n      bool Validate();\n      void Print(std::ostream& out);\n      void PrintNotes(std::ostream& out);\n      void PrintSegments(std::ostream& out);\n      void PrintSections(std::ostream& out);\n      void PrintSymbols(std::ostream& out);\n      void PrintMachineCode(std::ostream& out);\n      void PrintMachineCode(std::ostream& out, KernelSymbol* sym);\n      bool PrintToFile(const std::string& filename);\n\n      void AddNoteCodeObjectVersion(uint32_t major, uint32_t minor);\n      bool GetNoteCodeObjectVersion(std::string& version);\n      void AddNoteHsail(uint32_t hsail_major, uint32_t hsail_minor, hsa_profile_t profile, hsa_machine_model_t machine_model, hsa_default_float_rounding_mode_t rounding_mode);\n      bool GetNoteHsail(uint32_t* hsail_major, uint32_t* hsail_minor, hsa_profile_t* profile, hsa_machine_model_t* machine_model, hsa_default_float_rounding_mode_t* default_float_round);\n      void AddNoteIsa(const std::string& vendor_name, const std::string& architecture_name, uint32_t major, uint32_t minor, uint32_t stepping);\n      bool GetNoteIsa(std::string& vendor_name, std::string& architecture_name, uint32_t* major_version, uint32_t* minor_version, uint32_t* stepping);\n      void AddNoteProducer(uint32_t major, uint32_t minor, const std::string& producer);\n      bool GetNoteProducer(uint32_t* major, uint32_t* minor, std::string& producer_name);\n      void AddNoteProducerOptions(const std::string& options);\n      void AddNoteProducerOptions(int32_t call_convention, const hsa_ext_control_directives_t& user_directives, const std::string& user_options);\n      bool GetNoteProducerOptions(std::string& options);\n\n      bool GetIsa(std::string& isaName, unsigned *genericVersion = nullptr);\n      bool GetCodeObjectVersion(uint32_t* major, uint32_t* minor);\n      hsa_status_t GetInfo(hsa_code_object_info_t attribute, void *value);\n      hsa_status_t GetSymbol(const char *module_name, const char *symbol_name, hsa_code_symbol_t *sym);\n      hsa_status_t IterateSymbols(hsa_code_object_t code_object,\n                                  hsa_status_t (*callback)(\n                                    hsa_code_object_t code_object,\n                                    hsa_code_symbol_t symbol,\n                                    void* data),\n                                  void* data);\n\n      void AddHsaTextData(const void* buffer, size_t size);\n      uint64_t NextKernelCodeOffset() const;\n      bool AddKernelCode(KernelSymbol* sym, const void* code, size_t size);\n\n      Symbol* AddKernelDefinition(const std::string& name, const void* isa, size_t isa_size);\n\n      size_t DataSegmentCount() const { return dataSegments.size(); }\n      Segment* DataSegment(size_t i) const { return dataSegments[i]; }\n\n      size_t DataSectionCount() { return dataSections.size(); }\n      Section* DataSection(size_t i) { return dataSections[i]; }\n\n      Section* AddEmptySection();\n      Section* AddCodeSection(Segment* segment);\n      Section* AddDataSection(const std::string &name,\n                              uint32_t type,\n                              uint64_t flags,\n                              Segment* segment);\n\n      bool HasImageInitSection() const { return imageInit != 0; }\n      Section* ImageInitSection();\n      void AddImageInitializer(Symbol* image, uint64_t destOffset, const amdgpu_hsa_image_descriptor_t& init);\n      void AddImageInitializer(Symbol* image, uint64_t destOffset,\n        amdgpu_hsa_metadata_kind16_t kind,\n        amdgpu_hsa_image_geometry8_t geometry,\n        amdgpu_hsa_image_channel_order8_t channel_order, amdgpu_hsa_image_channel_type8_t channel_type,\n        uint64_t width, uint64_t height, uint64_t depth, uint64_t array);\n\n\n      bool HasSamplerInitSection() const { return samplerInit != 0; }\n      amd::elf::Section* SamplerInitSection();\n      amd::elf::Section* AddSamplerInit();\n      void AddSamplerInitializer(Symbol* sampler, uint64_t destOffset, const amdgpu_hsa_sampler_descriptor_t& init);\n      void AddSamplerInitializer(Symbol* sampler, uint64_t destOffset,\n        amdgpu_hsa_sampler_coord8_t coord,\n        amdgpu_hsa_sampler_filter8_t filter,\n        amdgpu_hsa_sampler_addressing8_t addressing);\n\n      void AddInitVarWithAddress(bool large, Symbol* dest, uint64_t destOffset, Symbol* addrOf, uint64_t addrAddend);\n\n      void InitHsaSegment(amdgpu_hsa_elf_segment_t segment, bool writable);\n      bool AddHsaSegments();\n      Segment* HsaSegment(amdgpu_hsa_elf_segment_t segment, bool writable);\n\n      void InitHsaSectionSegment(amdgpu_hsa_elf_section_t section, bool combineSegments = true);\n      Section* HsaDataSection(amdgpu_hsa_elf_section_t section, bool combineSegments = true);\n\n      Symbol* AddExecutableSymbol(const std::string &name,\n                                  unsigned char type,\n                                  unsigned char binding,\n                                  unsigned char other,\n                                  Section *section = 0);\n\n      Symbol* AddVariableSymbol(const std::string &name,\n                                unsigned char type,\n                                unsigned char binding,\n                                unsigned char other,\n                                Section *section,\n                                uint64_t value,\n                                uint64_t size);\n      void AddSectionSymbols();\n\n      size_t RelocationSectionCount() { return relocationSections.size(); }\n      RelocationSection* GetRelocationSection(size_t i) { return relocationSections[i]; }\n\n      size_t SymbolCount() { return symbols.size(); }\n      Symbol* GetSymbol(size_t i) { return symbols[i]; }\n      Symbol* GetSymbolByElfIndex(size_t index);\n      Symbol* FindSymbol(const std::string &n);\n\n      void AddData(amdgpu_hsa_elf_section_t section, const void* data = 0, size_t size = 0);\n\n      Section* DebugInfo();\n      Section* DebugLine();\n      Section* DebugAbbrev();\n\n      Section* AddHsaHlDebug(const std::string& name, const void* data, size_t size);\n    };\n\n    class AmdHsaCodeManager {\n    private:\n      typedef std::unordered_map<uint64_t, AmdHsaCode*> CodeMap;\n      CodeMap codeMap;\n\n    public:\n      AmdHsaCode* FromHandle(hsa_code_object_t handle);\n      bool Destroy(hsa_code_object_t handle);\n    };\n\n    class KernelSymbolV2 : public KernelSymbol {\n    private:\n    public:\n      explicit KernelSymbolV2(amd::elf::Symbol* elfsym_, const amd_kernel_code_t* akc);\n      bool IsAgent() const override { return true; }\n      uint64_t SectionOffset() const override { return elfsym->value() - elfsym->section()->addr(); }\n      uint64_t VAddr() const override { return elfsym->value(); }\n    };\n\n    class VariableSymbolV2 : public VariableSymbol {\n    private:\n    public:\n      explicit VariableSymbolV2(amd::elf::Symbol* elfsym_) : VariableSymbol(elfsym_) { }\n      bool IsAgent() const override { return false; }\n      uint64_t SectionOffset() const override { return elfsym->value() - elfsym->section()->addr(); }\n      uint64_t VAddr() const override { return elfsym->value(); }\n    };\n}   //  namespace code\n}   //  namespace hsa\n}   //  namespace amd\n}   //  namespace rocr\n\n#endif // AMD_HSA_CODE_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_hsa_loader.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_LOADER_HPP\n#define AMD_HSA_LOADER_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"inc/hsa_ven_amd_loader.h\"\n#include \"inc/amd_hsa_elf.h\"\n#include <string>\n#include <memory>\n#include <mutex>\n#include <vector>\n\n#if defined(_WIN32) || defined(_WIN64)\n#include <io.h>\n#define __read__  _read\n#define __lseek__ _lseek\n#else\n#include <unistd.h>\n#define __read__  read\n#define __lseek__ lseek\n#endif  // _WIN32 || _WIN64\n\n/// @brief Major version of the AMD HSA Loader. Major versions are not backwards\n/// compatible.\n#define AMD_HSA_LOADER_VERSION_MAJOR 0\n\n/// @brief Minor version of the AMD HSA Loader. Minor versions are backwards\n/// compatible.\n#define AMD_HSA_LOADER_VERSION_MINOR 5\n\n/// @brief Descriptive version of the AMD HSA Loader.\n#define AMD_HSA_LOADER_VERSION \"AMD HSA Loader v0.05 (June 16, 2015)\"\n\nenum hsa_ext_symbol_info_t {\n  HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_SIZE = 100,\n  HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_ALIGN = 101,\n};\n\ntypedef uint32_t hsa_symbol_info32_t;\ntypedef hsa_executable_symbol_t hsa_symbol_t;\ntypedef hsa_executable_symbol_info_t hsa_symbol_info_t;\n\n/// @brief Loaded code object attributes.\nenum amd_loaded_code_object_info_t {\n  AMD_LOADED_CODE_OBJECT_INFO_ELF_IMAGE = 0,\n  AMD_LOADED_CODE_OBJECT_INFO_ELF_IMAGE_SIZE = 1\n};\n\n/// @brief Loaded segment handle.\ntypedef struct amd_loaded_segment_s {\n  uint64_t handle;\n} amd_loaded_segment_t;\n\n/// @brief Loaded segment attributes.\nenum amd_loaded_segment_info_t {\n  AMD_LOADED_SEGMENT_INFO_TYPE = 0,\n  AMD_LOADED_SEGMENT_INFO_ELF_BASE_ADDRESS = 1,\n  AMD_LOADED_SEGMENT_INFO_LOAD_BASE_ADDRESS = 2,\n  AMD_LOADED_SEGMENT_INFO_SIZE = 3\n};\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace loader {\n\n/// @class CodeObjectReaderImpl.\n/// @brief Code Object Reader Wrapper.\nstruct CodeObjectReaderImpl final {\n public:\n  /// @returns Handle equivalent of @p object.\n  static hsa_code_object_reader_t Handle(\n      const CodeObjectReaderImpl *object) {\n    hsa_code_object_reader_t handle = {reinterpret_cast<uint64_t>(object)};\n    return handle;\n  }\n\n  /// @returns Object equivalent of @p handle.\n  static CodeObjectReaderImpl *Object(\n      const hsa_code_object_reader_t &handle) {\n    CodeObjectReaderImpl *object =\n      reinterpret_cast<CodeObjectReaderImpl*>(handle.handle);\n    return object;\n  }\n\n  /// @brief Default constructor.\n  CodeObjectReaderImpl() {}\n\n  /// @brief Default destructor.\n  ~CodeObjectReaderImpl();\n\n  hsa_status_t SetFile(\n      hsa_file_t _code_object_file_descriptor,\n      size_t _code_object_offset = 0,\n      size_t _code_object_size = 0);\n\n  hsa_status_t SetMemory(\n      const void *_code_object_memory,\n      size_t _code_object_size);\n\n  const void *GetCodeObjectMemory() const { return code_object_memory; };\n\n  std::string GetUri() const { return uri; };\n\n private:\n  const void *code_object_memory{nullptr};\n  size_t code_object_size{0};\n  std::string uri{};\n  bool is_mmap{false};\n};\n\n//===----------------------------------------------------------------------===//\n// Context.                                                                   //\n//===----------------------------------------------------------------------===//\n\nclass Context {\npublic:\n  virtual ~Context() {}\n\n  virtual hsa_isa_t IsaFromName(const char *name) = 0;\n\n  virtual bool IsaSupportedByAgent(hsa_agent_t agent, hsa_isa_t isa, unsigned genericVersion) = 0;\n\n  virtual void* SegmentAlloc(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, size_t size, size_t align, bool zero) = 0;\n\n  virtual bool SegmentCopy(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* dst, size_t offset, const void* src, size_t size) = 0;\n\n  virtual void SegmentFree(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t size) = 0;\n\n  virtual void* SegmentAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t offset) = 0;\n\n  virtual void* SegmentHostAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t offset) = 0;\n\n  virtual bool SegmentFreeze(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t size) = 0;\n\n  virtual bool ImageExtensionSupported() = 0;\n\n  virtual hsa_status_t ImageCreate(\n    hsa_agent_t agent,\n    hsa_access_permission_t image_permission,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_ext_image_t *image_handle) = 0;\n\n  virtual hsa_status_t ImageDestroy(\n    hsa_agent_t agent, hsa_ext_image_t image_handle) = 0;\n\n  virtual hsa_status_t SamplerCreate(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler_handle) = 0;\n\n  virtual hsa_status_t SamplerDestroy(\n    hsa_agent_t agent, hsa_ext_sampler_t sampler_handle) = 0;\n\nprotected:\n  Context() {}\n\nprivate:\n  Context(const Context &c);\n  Context& operator=(const Context &c);\n};\n\n//===----------------------------------------------------------------------===//\n// Symbol.                                                                    //\n//===----------------------------------------------------------------------===//\n\nclass Symbol {\npublic:\n  static hsa_symbol_t Handle(Symbol *symbol) {\n    hsa_symbol_t symbol_handle =\n      {reinterpret_cast<uint64_t>(symbol)};\n    return symbol_handle;\n  }\n\n  static Symbol* Object(hsa_symbol_t symbol_handle) {\n    Symbol *symbol =\n      reinterpret_cast<Symbol*>(symbol_handle.handle);\n    return symbol;\n  }\n\n  virtual ~Symbol() {}\n\n  virtual bool GetInfo(hsa_symbol_info32_t symbol_info, void *value) = 0;\n\n  virtual hsa_agent_t GetAgent() = 0;\n\nprotected:\n  Symbol() {}\n\nprivate:\n  Symbol(const Symbol &s);\n  Symbol& operator=(const Symbol &s);\n};\n\n//===----------------------------------------------------------------------===//\n// LoadedCodeObject.                                                          //\n//===----------------------------------------------------------------------===//\n\nclass LoadedCodeObject {\npublic:\n  static hsa_loaded_code_object_t Handle(LoadedCodeObject *object) {\n    hsa_loaded_code_object_t handle =\n      {reinterpret_cast<uint64_t>(object)};\n    return handle;\n  }\n\n  static LoadedCodeObject* Object(hsa_loaded_code_object_t handle) {\n    LoadedCodeObject *object =\n      reinterpret_cast<LoadedCodeObject*>(handle.handle);\n    return object;\n  }\n\n  virtual ~LoadedCodeObject() {}\n\n  virtual bool GetInfo(amd_loaded_code_object_info_t attribute, void *value) = 0;\n\n  virtual hsa_status_t IterateLoadedSegments(\n    hsa_status_t (*callback)(\n      amd_loaded_segment_t loaded_segment,\n      void *data),\n    void *data) = 0;\n\n  virtual hsa_agent_t getAgent() const = 0;\n  virtual hsa_executable_t getExecutable() const = 0;\n  virtual uint64_t getElfData() const = 0;\n  virtual uint64_t getElfSize() const = 0;\n  virtual uint64_t getStorageOffset() const = 0;\n  virtual uint64_t getLoadBase() const = 0;\n  virtual uint64_t getLoadSize() const = 0;\n  virtual int64_t getDelta() const = 0;\n  virtual std::string getUri() const = 0;\n\nprotected:\n  LoadedCodeObject() {}\n\nprivate:\n  LoadedCodeObject(const LoadedCodeObject&);\n  LoadedCodeObject& operator=(const LoadedCodeObject&);\n};\n\n//===----------------------------------------------------------------------===//\n// LoadedSegment.                                                             //\n//===----------------------------------------------------------------------===//\n\nclass LoadedSegment {\npublic:\n  static amd_loaded_segment_t Handle(LoadedSegment *object) {\n    amd_loaded_segment_t handle =\n      {reinterpret_cast<uint64_t>(object)};\n    return handle;\n  }\n\n  static LoadedSegment* Object(amd_loaded_segment_t handle) {\n    LoadedSegment *object =\n      reinterpret_cast<LoadedSegment*>(handle.handle);\n    return object;\n  }\n\n  virtual ~LoadedSegment() {}\n\n  virtual bool GetInfo(amd_loaded_segment_info_t attribute, void *value) = 0;\n\nprotected:\n  LoadedSegment() {}\n\nprivate:\n  LoadedSegment(const LoadedSegment&);\n  LoadedSegment& operator=(const LoadedSegment&);\n};\n\n//===----------------------------------------------------------------------===//\n// Executable.                                                                //\n//===----------------------------------------------------------------------===//\n\nclass Executable {\npublic:\n  static hsa_executable_t Handle(Executable *executable) {\n    hsa_executable_t executable_handle =\n      {reinterpret_cast<uint64_t>(executable)};\n    return executable_handle;\n  }\n\n  static Executable* Object(hsa_executable_t executable_handle) {\n    Executable *executable =\n      reinterpret_cast<Executable*>(executable_handle.handle);\n    return executable;\n  }\n\n  virtual ~Executable() {}\n\n  virtual hsa_status_t GetInfo(\n    hsa_executable_info_t executable_info, void *value) = 0;\n\n  virtual hsa_status_t DefineProgramExternalVariable(\n    const char *name, void *address) = 0;\n\n  virtual hsa_status_t DefineAgentExternalVariable(\n    const char *name,\n    hsa_agent_t agent,\n    hsa_variable_segment_t segment,\n    void *address) = 0;\n\n  virtual hsa_status_t LoadCodeObject(\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    const char *options,\n    const std::string &uri,\n    hsa_loaded_code_object_t *loaded_code_object = nullptr) = 0;\n\n  virtual hsa_status_t LoadCodeObject(\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    size_t code_object_size,\n    const char *options,\n    const std::string &uri,\n    hsa_loaded_code_object_t *loaded_code_object = nullptr) = 0;\n\n  virtual hsa_status_t Freeze(const char *options) = 0;\n\n  virtual hsa_status_t Validate(uint32_t *result) = 0;\n\n  /// @note needed for hsa v1.0.\n  /// @todo remove during loader refactoring.\n  virtual bool IsProgramSymbol(const char *symbol_name) = 0;\n\n  virtual Symbol* GetSymbol(\n    const char *symbol_name,\n    const hsa_agent_t *agent) = 0;\n\n  typedef hsa_status_t (*iterate_symbols_f)(\n    hsa_executable_t executable,\n    hsa_symbol_t symbol_handle,\n    void *data);\n\n  virtual hsa_status_t IterateSymbols(\n    iterate_symbols_f callback, void *data) = 0;\n\n  /// @since hsa v1.1.\n  virtual hsa_status_t IterateAgentSymbols(\n      hsa_agent_t agent,\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_agent_t agent,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data) = 0;\n\n  /// @since hsa v1.1.\n  virtual hsa_status_t IterateProgramSymbols(\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data) = 0;\n\n  virtual hsa_status_t IterateLoadedCodeObjects(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      hsa_loaded_code_object_t loaded_code_object,\n      void *data),\n    void *data) = 0;\n\n  virtual size_t GetNumSegmentDescriptors() = 0;\n\n  virtual size_t QuerySegmentDescriptors(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t total_num_segment_descriptors,\n    size_t first_empty_segment_descriptor) = 0;\n\n  virtual uint64_t FindHostAddress(uint64_t device_address) = 0;\n\n  virtual void Print(std::ostream& out) = 0;\n  virtual bool PrintToFile(const std::string& filename) = 0;\n\nprotected:\n  Executable() {}\n\nprivate:\n  Executable(const Executable &e);\n  Executable& operator=(const Executable &e);\n\n  static std::vector<Executable*> executables;\n  static std::mutex executables_mutex;\n};\n\n/// @class Loader\nclass Loader {\npublic:\n  /// @brief Destructor.\n  virtual ~Loader() {}\n\n  /// @brief Creates AMD HSA Loader with specified @p context.\n  ///\n  /// @param[in] context Context. Must not be null.\n  ///\n  /// @returns AMD HSA Loader on success, null on failure.\n  static Loader* Create(Context* context);\n\n  /// @brief Destroys AMD HSA Loader @p Loader_object.\n  ///\n  /// @param[in] loader AMD HSA Loader to destroy. Must not be null.\n  static void Destroy(Loader *loader);\n\n  /// @returns Context associated with Loader.\n  virtual Context* GetContext() const = 0;\n\n  /// @brief Creates empty AMD HSA Executable with specified @p profile,\n  /// @p options\n  virtual Executable* CreateExecutable(\n      hsa_profile_t profile,\n      const char *options,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode = HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT) = 0;\n\n  /// @brief Creates empty AMD HSA Executable with specified @p profile,\n  /// @p options and @p isolated_context that is isolated from the runtime.\n  virtual Executable* CreateExecutable(\n      std::unique_ptr<Context> isolated_context,\n      hsa_profile_t profile,\n      const char *options,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode = HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT) = 0;\n\n  /// @brief Freezes @p executable\n  virtual hsa_status_t FreezeExecutable(Executable *executable, const char *options) = 0;\n\n  /// @brief Destroys @p executable\n  virtual void DestroyExecutable(Executable *executable) = 0;\n\n  /// @brief Invokes @p callback for each created executable\n  virtual hsa_status_t IterateExecutables(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      void *data),\n    void *data) = 0;\n\n  /// @brief same as hsa_ven_amd_loader_query_segment_descriptors.\n  virtual hsa_status_t QuerySegmentDescriptors(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors) = 0;\n\n  /// @brief Finds the handle of executable to which @p device_address\n  /// belongs. Return NULL handle if device address is invalid.\n  virtual hsa_executable_t FindExecutable(uint64_t device_address) = 0;\n\n  /// @brief Returns host address given @p device_address. If @p device_address\n  /// is already host address, returns null pointer. If @p device_address is\n  /// invalid address, returns null pointer.\n  virtual uint64_t FindHostAddress(uint64_t device_address) = 0;\n\n  /// @brief Print loader help.\n  virtual void PrintHelp(std::ostream& out) = 0;\n\nprotected:\n  /// @brief Default constructor.\n  Loader() {}\n\nprivate:\n  /// @brief Copy constructor - not available.\n  Loader(const Loader&);\n\n  /// @brief Assignment operator - not available.\n  Loader& operator=(const Loader&);\n};\n\n\n} // namespace loader\n} // namespace hsa\n} // namespace amd\n} // namespace rocr\n\n#endif // AMD_HSA_LOADER_HPP\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_kfd_driver.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_KFD_DRIVER_H_\n#define HSA_RUNTIME_CORE_INC_AMD_KFD_DRIVER_H_\n\n#include <memory>\n#include <string>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/driver.h\"\n#include \"core/inc/memory_region.h\"\n\nnamespace rocr {\n\nnamespace core {\n\nclass Queue;\n\n}\n\nnamespace AMD {\n\n/// @brief AMD Kernel Fusion Driver (KFD) for AMD GPU and CPU agents.\n///\n/// @details The user-mode driver into the Linux KFD for AMD GPU and CPU HSA\n/// agents. Provides APIs for the ROCr core to discover the topology produced\n/// by the KFD, allocate memory out of the KFD, manage DMA bufs, allocate queues,\n/// and more.\nclass KfdDriver final : public core::Driver {\npublic:\n  KfdDriver(std::string devnode_name);\n\n  /// @brief Determine of the KFD is present on the system and attemp to open it if found.\n  ///\n  /// @param[out] Driver object for the KFD.\n  /// @return HSA_STATUS_SUCCESS if driver found and opened.\n  /// @return HSA_STATUS_ERROR if unable to find or open the KFD.\n  static hsa_status_t DiscoverDriver(std::unique_ptr<core::Driver>& driver);\n\n  hsa_status_t Init() override;\n  hsa_status_t ShutDown() override;\n  hsa_status_t QueryKernelModeDriver(core::DriverQuery query) override;\n  hsa_status_t Open() override;\n  hsa_status_t Close() override;\n  hsa_status_t GetSystemProperties(HsaSystemProperties& sys_props) const override;\n  hsa_status_t GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const override;\n  hsa_status_t GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                 uint32_t node_id) const override;\n  hsa_status_t GetMemoryProperties(uint32_t node_id,\n                                   std::vector<HsaMemoryProperties>& mem_props) const override;\n  hsa_status_t GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                  std::vector<HsaCacheProperties>& cache_props) const override;\n  hsa_status_t AllocateMemory(const core::MemoryRegion &mem_region,\n                              core::MemoryRegion::AllocateFlags alloc_flags,\n                              void **mem, size_t size,\n                              uint32_t node_id) override;\n  hsa_status_t FreeMemory(void *mem, size_t size) override;\n  hsa_status_t CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                           HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id, void* queue_addr,\n                           uint64_t queue_size_bytes, HsaEvent* event,\n                           HsaQueueResource& queue_resource) const override;\n  hsa_status_t UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_pct, HSA_QUEUE_PRIORITY priority,\n                           void* queue_addr, uint64_t queue_size, HsaEvent* event) const override;\n  hsa_status_t DestroyQueue(HSA_QUEUEID queue_id) const override;\n  hsa_status_t SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t cu_mask_count,\n                              uint32_t* queue_cu_mask) const override;\n  hsa_status_t AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_gws,\n                             uint32_t* first_gws) const override;\n  hsa_status_t ExportDMABuf(void *mem, size_t size, int *dmabuf_fd,\n                            size_t *offset) override;\n  hsa_status_t ImportDMABuf(int dmabuf_fd, core::Agent &agent,\n                            core::ShareableHandle &handle) override;\n  hsa_status_t Map(core::ShareableHandle handle, void *mem, size_t offset,\n                   size_t size, hsa_access_permission_t perms) override;\n  hsa_status_t Unmap(core::ShareableHandle handle, void *mem, size_t offset,\n                     size_t size) override;\n  hsa_status_t ReleaseShareableHandle(core::ShareableHandle &handle) override;\n\n  hsa_status_t SPMAcquire(uint32_t preferred_node_id) const override;\n  hsa_status_t SPMRelease(uint32_t preferred_node_id) const override;\n  hsa_status_t SPMSetDestBuffer(uint32_t preferred_node_id, uint32_t size_bytes, uint32_t* timeout,\n                                uint32_t* size_copied, void* dest_mem_addr,\n                                bool* is_spm_data_loss) const override;\n  hsa_status_t SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                              const void* buffer_base, uint64_t buffer_base_size) const override;\n  hsa_status_t GetDeviceHandle(uint32_t node_id, void** device_handle) const override;\n  hsa_status_t GetClockCounters(uint32_t node_id, HsaClockCounters* clock_counter) const override;\n  hsa_status_t GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const override;\n  hsa_status_t GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const override;\n  hsa_status_t AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const override;\n  hsa_status_t AvailableMemory(uint32_t node_id, uint64_t* available_size) const override;\n  hsa_status_t RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const override;\n  hsa_status_t DeregisterMemory(void* ptr) const override;\n  hsa_status_t MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                  const HsaMemMapFlags* mem_flags, uint32_t num_nodes,\n                                  const uint32_t* nodes) const override;\n  hsa_status_t MakeMemoryUnresident(const void* mem) const override;\n  hsa_status_t ShareMemory(void* mem, size_t size, HsaSharedMemoryHandle* share_mem) const override;\n  hsa_status_t RegisterSharedHandle(const HsaSharedMemoryHandle* share_mem, void** mem,\n                                    uint64_t* size) const override;\n  hsa_status_t ReplaceAsanHeaderPage(void* mem) const override;\n  hsa_status_t ReturnAsanHeaderPage(void* mem) const override;\n  hsa_status_t PcSamplingQueryCapabilities(uint32_t node_id, void* sample_info,\n                                           uint32_t sample_info_sz,\n                                           uint32_t* sz_needed) const override;\n  hsa_status_t PcSamplingCreate(uint32_t node_id, HsaPcSamplingInfo* sample_info,\n                                uint32_t* trace_id) const override;\n  hsa_status_t PcSamplingDestroy(uint32_t node_id, uint32_t trace_id) const override;\n  hsa_status_t PcSamplingStart(uint32_t node_id, uint32_t trace_id) const override;\n  hsa_status_t PcSamplingStop(uint32_t node_id, uint32_t trace_id) const override;\n\n  hsa_status_t OpenSMI(uint32_t node_id, int* fd) const override;\n\n  hsa_status_t IsModelEnabled(bool* enable) const override;\n\n private:\n  /// @brief Allocate agent accessible memory (system / local memory).\n  static void *AllocateKfdMemory(const HsaMemFlags &flags, uint32_t node_id,\n                                 size_t size);\n\n  /// @brief Free agent accessible memory (system / local memory).\n  static bool FreeKfdMemory(void *mem, size_t size);\n\n  /// @brief Pin memory.\n  static bool MakeKfdMemoryResident(size_t num_node, const uint32_t *nodes,\n                                    const void *mem, size_t size,\n                                    uint64_t *alternate_va,\n                                    HsaMemMapFlags map_flag);\n\n  /// @brief Unpin memory.\n  static void MakeKfdMemoryUnresident(const void *mem);\n\n  /// @brief Query for user preference and use that to determine Xnack mode\n  /// of ROCm system. Return true if Xnack mode is ON or false if OFF. Xnack\n  /// mode of a system is orthogonal to devices that do not support Xnack mode.\n  /// It is legal for a system with Xnack ON to have devices that do not support\n  /// Xnack functionality.\n  static bool BindXnackMode();\n\n  // Minimum acceptable KFD version numbers.\n  static const uint32_t kfd_version_major_min = 0;\n  static const uint32_t kfd_version_minor_min = 99;\n};\n\n} // namespace AMD\n} // namespace rocr\n\n#endif // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_loader_context.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_LOADER_CONTEXT_HPP\n#define HSA_RUNTIME_CORE_INC_AMD_LOADER_CONTEXT_HPP\n\n#include \"core/inc/amd_hsa_loader.hpp\"\n\nnamespace rocr {\nnamespace amd {\n\nclass LoaderContext final : public rocr::amd::hsa::loader::Context {\n public:\n  LoaderContext() : rocr::amd::hsa::loader::Context() {}\n\n  ~LoaderContext() {}\n\n  hsa_isa_t IsaFromName(const char *name) override;\n\n  bool IsaSupportedByAgent(hsa_agent_t agent, hsa_isa_t code_object_isa, unsigned codeGenericVersion) override;\n\n  void* SegmentAlloc(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, size_t size, size_t align, bool zero) override;\n\n  bool SegmentCopy(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* dst, size_t offset, const void* src, size_t size) override;\n\n  void SegmentFree(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t size = 0) override;\n\n  void* SegmentAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t offset) override;\n\n  void* SegmentHostAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t offset) override;\n\n  bool SegmentFreeze(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg, size_t size) override;\n\n  bool ImageExtensionSupported() override;\n\n  hsa_status_t ImageCreate(hsa_agent_t agent, hsa_access_permission_t image_permission,\n                           const hsa_ext_image_descriptor_t* image_descriptor,\n                           const void* image_data, hsa_ext_image_t* image_handle) override;\n\n  hsa_status_t ImageDestroy(hsa_agent_t agent, hsa_ext_image_t image_handle) override;\n\n  hsa_status_t SamplerCreate(hsa_agent_t agent,\n                             const hsa_ext_sampler_descriptor_t* sampler_descriptor,\n                             hsa_ext_sampler_t* sampler_handle) override;\n\n  hsa_status_t SamplerDestroy(hsa_agent_t agent, hsa_ext_sampler_t sampler_handle) override;\n\nprivate:\n  LoaderContext(const LoaderContext&);\n  LoaderContext& operator=(const LoaderContext&);\n};\n\n} // namespace amd\n} // namespace rocr\n\n#endif // HSA_RUNTIME_CORE_INC_AMD_LOADER_CONTEXT_HPP\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_memory_region.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// AMD specific HSA backend.\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_MEMORY_REGION_H_\n#define HSA_RUNTIME_CORE_INC_AMD_MEMORY_REGION_H_\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/agent.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/memory_region.h\"\n#include \"core/util/simple_heap.h\"\n#include \"core/util/locks.h\"\n\n#include \"inc/hsa_ext_amd.h\"\n\nnamespace rocr {\nnamespace AMD {\nclass MemoryRegion : public core::MemoryRegion {\n public:\n  /// @brief Convert this object into hsa_region_t.\n  static __forceinline hsa_region_t Convert(MemoryRegion* region) {\n    const hsa_region_t region_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(region))};\n    return region_handle;\n  }\n\n  static __forceinline const hsa_region_t Convert(const MemoryRegion* region) {\n    const hsa_region_t region_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(region))};\n    return region_handle;\n  }\n\n  /// @brief  Convert hsa_region_t into AMD::MemoryRegion *.\n  static __forceinline MemoryRegion* Convert(hsa_region_t region) {\n    return reinterpret_cast<MemoryRegion*>(region.handle);\n  }\n\n  MemoryRegion(bool fine_grain, bool kernarg, bool full_profile, bool extended_scope_fine_grain,\n               bool user_visible, core::Agent* owner, const HsaMemoryProperties& mem_props);\n\n  ~MemoryRegion();\n\n  hsa_status_t Allocate(size_t& size, AllocateFlags alloc_flags, void** address, int agent_node_id = 0) const;\n\n  hsa_status_t Free(void* address, size_t size) const;\n\n  hsa_status_t IPCFragmentExport(void* address) const;\n\n  hsa_status_t GetInfo(hsa_region_info_t attribute, void* value) const;\n\n  hsa_status_t GetPoolInfo(hsa_amd_memory_pool_info_t attribute,\n                           void* value) const;\n\n  hsa_status_t GetAgentPoolInfo(const core::Agent& agent,\n                                hsa_amd_agent_memory_pool_info_t attribute,\n                                void* value) const;\n\n  hsa_status_t AllowAccess(uint32_t num_agents, const hsa_agent_t* agents,\n                           const void* ptr, size_t size) const;\n\n  hsa_status_t CanMigrate(const MemoryRegion& dst, bool& result) const;\n\n  hsa_status_t Migrate(uint32_t flag, const void* ptr) const;\n\n  hsa_status_t Lock(uint32_t num_agents, const hsa_agent_t* agents,\n                    void* host_ptr, size_t size, void** agent_ptr) const;\n\n  hsa_status_t Unlock(void* host_ptr) const;\n\n  HSAuint64 GetBaseAddress() const { return mem_props_.VirtualBaseAddress; }\n\n  HSAuint64 GetPhysicalSize() const { return mem_props_.SizeInBytes; }\n\n  HSAuint64 GetVirtualSize() const { return virtual_size_; }\n\n  hsa_status_t AssignAgent(void* ptr, size_t size, const core::Agent& agent,\n                           hsa_access_permission_t access) const;\n\n  void Trim() const;\n\n  HSAuint64 GetCacheSize() const { return fragment_allocator_.cache_size(); }\n\n  __forceinline bool IsLocalMemory() const {\n    return ((mem_props_.HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE) ||\n            (mem_props_.HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC));\n  }\n\n  __forceinline bool IsPublic() const {\n    return (mem_props_.HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC);\n  }\n\n  __forceinline bool IsSystem() const {\n    return ((mem_props_.HeapType == HSA_HEAPTYPE_SYSTEM) ||\n            (mem_props_.HeapType == HSA_HEAPTYPE_DEVICE_SVM));\n  }\n\n  __forceinline bool IsDeviceSVM() const {\n    return (mem_props_.HeapType == HSA_HEAPTYPE_DEVICE_SVM);\n  }\n\n  __forceinline bool IsLDS() const {\n    return mem_props_.HeapType == HSA_HEAPTYPE_GPU_LDS;\n  }\n\n  __forceinline bool IsGDS() const {\n    return mem_props_.HeapType == HSA_HEAPTYPE_GPU_GDS;\n  }\n\n  __forceinline bool IsScratch() const {\n    return mem_props_.HeapType == HSA_HEAPTYPE_GPU_SCRATCH;\n  }\n\n  __forceinline uint32_t BusWidth() const {\n    return static_cast<uint32_t>(mem_props_.Width);\n  }\n\n  __forceinline uint32_t MaxMemCloc() const {\n    return static_cast<uint32_t>(mem_props_.MemoryClockMax);\n  }\n\n  __forceinline static size_t GetPageSize() { return kPageSize_; }\n\n  __forceinline const HsaMemFlags &mem_flags() const { return mem_flag_; }\n  __forceinline const HsaMemMapFlags &map_flags() const { return map_flag_; }\n\n  void *fragment_alloc(size_t size) const {\n    return fragment_allocator_.alloc(size);\n  }\n  bool fragment_free(void *mem) const { return fragment_allocator_.free(mem); }\n\nprivate:\n  const HsaMemoryProperties mem_props_;\n\n  HsaMemFlags mem_flag_;\n\n  HsaMemMapFlags map_flag_;\n\n  size_t max_single_alloc_size_;\n\n  // Used to collect total system memory\n  static size_t max_sysmem_alloc_size_;\n\n  HSAuint64 virtual_size_;\n\n  // Protects against concurrent allow_access calls to fragments of the same block by virtue of all\n  // fragments of the block routing to the same MemoryRegion.\n  mutable KernelMutex access_lock_;\n\n  static const size_t kPageSize_;\n\n  // Determine access type allowed to requesting device\n  hsa_amd_memory_pool_access_t GetAccessInfo(const core::Agent& agent,\n                                             const core::Runtime::LinkInfo& link_info) const;\n\n  // Operational body for Allocate.  Recursive.\n  hsa_status_t AllocateImpl(size_t& size, AllocateFlags alloc_flags, void** address, int agent_node_id) const;\n\n  // Operational body for Free.  Recursive.\n  hsa_status_t FreeImpl(void* address, size_t size) const;\n\n  class BlockAllocator {\n   private:\n    MemoryRegion& region_;\n    static const size_t block_size_ = 2 * 1024 * 1024;  // 2MB blocks.\n   public:\n    explicit BlockAllocator(MemoryRegion& region) : region_(region) {}\n    void* alloc(size_t request_size, size_t& allocated_size) const;\n    void free(void* ptr, size_t length) const { region_.FreeImpl(ptr, length); }\n    size_t block_size() const { return block_size_; }\n  };\n\n  mutable SimpleHeap<BlockAllocator> fragment_allocator_;\n};\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_topology.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_TOPOLOGY_H_\n#define HSA_RUNTIME_CORE_INC_AMD_TOPOLOGY_H_\n\nnamespace rocr {\nnamespace AMD {\n/// @brief Initializes the runtime.\n/// Should not be called directly, must be called only from Runtime::Acquire()\nbool Load();\n\n/// @brief Shutdown/cleanup of runtime.\n/// Should not be called directly, must be called only from Runtime::Release()\nbool Unload();\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_trap_handler_v1.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef OPENSRC_HSA_RUNTIME_CORE_INC_AMD_TRAP_HANDLER_V1_H_ \n#define OPENSRC_HSA_RUNTIME_CORE_INC_AMD_TRAP_HANDLER_V1_H_ \n\nnamespace rocr {\nnamespace AMD {\n\nstatic const unsigned int kCodeTrapHandler8[] = {\n    0xC0061C80, 0x000000C0, 0xBF8C007F, 0xBEFE0181, 0x80728872, 0x82738073,\n    0x7E000272, 0x7E020273, 0x7E0402FF, 0x80000000, 0x7E060280, 0xDD800000,\n    0x00000200, 0xBF8C0F70, 0x7DD40500, 0xBF870011, 0xC0061D39, 0x00000008,\n    0xBF8C007F, 0x86F47474, 0xBF84000C, 0x80729072, 0x82738073, 0xC0021CB9,\n    0x00000000, 0xBF8C007F, 0x7E000274, 0x7E020275, 0x7E040272, 0xDC700000,\n    0x00000200, 0xBF8C0F70, 0xBF900001, 0xBF8D0001, 0xBE801F70,\n};\n\nstatic const unsigned int kCodeTrapHandler9[] = {\n/*\n  .set SQ_WAVE_PC_HI_ADDRESS_MASK              , 0xFFFF\n  .set SQ_WAVE_PC_HI_TRAP_ID_SHIFT             , 16\n  .set SQ_WAVE_PC_HI_TRAP_ID_SIZE              , 8\n  .set SQ_WAVE_PC_HI_TRAP_ID_BFE               , (SQ_WAVE_PC_HI_TRAP_ID_SHIFT | (SQ_WAVE_PC_HI_TRAP_ID_SIZE << 16))\n  .set SQ_WAVE_PC_HI_HT_MASK                   , 0x1000000\n  .set SQ_WAVE_STATUS_HALT_BIT                 , 13\n  .set SQ_WAVE_STATUS_HALT_BFE                 , (SQ_WAVE_STATUS_HALT_BIT | (1 << 16))\n  .set SQ_WAVE_TRAPSTS_ADDRESS_WATCH_MASK      , 0x7080\n  .set SQ_WAVE_TRAPSTS_MEM_VIOL_MASK           , 0x100\n  .set SQ_WAVE_TRAPSTS_ILLEGAL_INST_MASK       , 0x800\n  .set SQ_WAVE_TRAPSTS_XNACK_ERROR_MASK        , 0x10000000\n  .set SQ_WAVE_MODE_DEBUG_EN_SHIFT             , 11\n  .set SIGNAL_CODE_MEM_VIOL                    , (1 << 29)\n  .set SIGNAL_CODE_ILLEGAL_INST                , (1 << 30)\n  .set SIGNAL_CODE_LLVM_TRAP                   , (1 << 31)\n  .set MAX_NUM_DOORBELLS_MASK                  , ((1 << 10) - 1)\n  .set SENDMSG_M0_DOORBELL_ID_BITS             , 12\n  .set SENDMSG_M0_DOORBELL_ID_MASK             , ((1 << SENDMSG_M0_DOORBELL_ID_BITS) - 1)\n\n  .set TTMP7_DISPATCH_ID_CONVERTED_BIT         , 31\n  .set TTMP7_WAVE_STOPPED_BIT                  , 30\n  .set TTMP7_SAVED_STATUS_HALT_BIT             , 29\n  .set TTMP7_SAVED_TRAP_ID_SHIFT               , 25\n  .set TTMP7_SAVED_TRAP_ID_BITS                , 4\n  .set TTMP7_SAVED_TRAP_ID_MASK                , ((1 << TTMP7_SAVED_TRAP_ID_BITS) - 1)\n  .set TTMP7_PACKET_INDEX_BITS                 , 25\n  .set TTMP7_PACKET_INDEX_MASK                 , ((1 << TTMP7_PACKET_INDEX_BITS) - 1)\n  .set TTMP11_PC_HI_SHIFT                      , 7\n\n  .if .amdgcn.gfx_generation_number == 9\n    .set DEBUG_INTERRUPT_CONTEXT_ID_BIT        , 23\n    .set TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT   , 26\n    .set SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT     , 15\n    .set SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK , 0x1F8000\n  .elseif .amdgcn.gfx_generation_number == 10\n    .set DEBUG_INTERRUPT_CONTEXT_ID_BIT        , 22\n    .set TTMP11_SAVE_REPLAY_W64H_SHIFT         , 31\n    .set TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT   , 24\n    .set SQ_WAVE_IB_STS_REPLAY_W64H_SHIFT      , 25\n    .set SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT     , 15\n    .set SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK , 0x3F8000\n    .set SQ_WAVE_IB_STS_REPLAY_W64H_MASK       , 0x2000000\n  .else\n    .error \"unsupported target\"\n  .endif\n\n  // ABI between first and second level trap handler:\n  //   ttmp0 = PC[31:0]\n  //   ttmp1 = 0[2:0], PCRewind[3:0], HostTrap[0], TrapId[7:0], PC[47:32]\n  //   ttmp12 = SQ_WAVE_STATUS\n  //   ttmp14 = TMA[31:0]\n  //   ttmp15 = TMA[63:32]\n  // gfx9:\n  //   ttmp11 = SQ_WAVE_IB_STS[20:15], 0[18:0], NoScratch[0], WaveIdInWG[5:0]\n  // gfx10:\n  //   ttmp11 = SQ_WAVE_IB_STS[25], SQ_WAVE_IB_STS[21:15], 0[16:0], NoScratch[0], WaveIdInWG[5:0]\n  // gfx1030/gfx1100:\n  //   ttmp11 = 0[7:0], DebugEnabled[0], 0[15:0], NoScratch[0], WaveIdInWG[5:0]\n\n  .macro mGetDoorbellId\n    s_mov_b32            exec_lo, 0x80000000\n    s_sendmsg            sendmsg(MSG_GET_DOORBELL)\n  .wait_sendmsg_\\@:\n    s_nop                7\n    s_bitcmp0_b32        exec_lo, 0x1F\n    s_cbranch_scc0       .wait_sendmsg_\\@\n  .endm\n\n  .macro mExitTrap\n    // Restore SQ_WAVE_IB_STS.\n  .if .amdgcn.gfx_generation_number == 9\n    s_lshr_b32           ttmp2, ttmp11, (TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)\n    s_and_b32            ttmp2, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK\n    s_setreg_b32         hwreg(HW_REG_IB_STS), ttmp2\n  .endif\n  .if .amdgcn.gfx_generation_number == 10\n    s_lshr_b32           ttmp2, ttmp11, (TTMP11_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)\n    s_and_b32            ttmp3, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK\n    s_lshr_b32           ttmp2, ttmp11, (TTMP11_SAVE_REPLAY_W64H_SHIFT - SQ_WAVE_IB_STS_REPLAY_W64H_SHIFT)\n    s_and_b32            ttmp2, ttmp2, SQ_WAVE_IB_STS_REPLAY_W64H_MASK\n    s_or_b32             ttmp2, ttmp2, ttmp3\n    s_setreg_b32         hwreg(HW_REG_IB_STS), ttmp2\n  .endif\n\n    // Restore SQ_WAVE_STATUS.\n    s_and_b64            exec, exec, exec // Restore STATUS.EXECZ, not writable by s_setreg_b32\n    s_and_b64            vcc, vcc, vcc    // Restore STATUS.VCCZ, not writable by s_setreg_b32\n    s_setreg_b32         hwreg(HW_REG_STATUS), ttmp12\n\n    // Return to shader at unmodified PC.\n    s_rfe_b64            [ttmp0, ttmp1]\n  .endm\n\n  trap_entry:\n    s_andn2_b32          ttmp7, ttmp7, (TTMP7_SAVED_TRAP_ID_MASK << TTMP7_SAVED_TRAP_ID_SHIFT) | (1 << TTMP7_SAVED_STATUS_HALT_BIT)\n\n    // Save the entry status.halt in ttmp7.saved_status_halt\n    s_bfe_u32            ttmp2, ttmp12, SQ_WAVE_STATUS_HALT_BFE\n    s_lshl_b32           ttmp2, ttmp2, TTMP7_SAVED_STATUS_HALT_BIT\n    s_or_b32             ttmp7, ttmp7, ttmp2\n\n    // If trap raised (non-zero trap id) then branch.\n    s_bfe_u32            ttmp2, ttmp1, SQ_WAVE_PC_HI_TRAP_ID_BFE\n    s_cbranch_scc1       .trap_raised\n\n    // If non-masked exception raised then branch.\n    s_getreg_b32         ttmp2, hwreg(HW_REG_TRAPSTS)\n    s_and_b32            ttmp3, ttmp2, (SQ_WAVE_TRAPSTS_MEM_VIOL_MASK | SQ_WAVE_TRAPSTS_ILLEGAL_INST_MASK)\n    s_cbranch_scc1       .excp_raised\n\n  .signal_debugger:\n    // Fetch doorbell index for our queue.\n    s_mov_b32            ttmp2, exec_lo\n    s_mov_b32            ttmp3, exec_hi\n    mGetDoorbellId\n    s_mov_b32            exec_hi, ttmp3\n\n    // Restore exec_lo, move the doorbell_id into ttmp3\n    s_and_b32            ttmp3, exec_lo, SENDMSG_M0_DOORBELL_ID_MASK\n    s_mov_b32            exec_lo, ttmp2\n\n    // Set the debug interrupt context id.\n    // FIXME: Make conditional when exceptions are handled.\n    s_bitset1_b32        ttmp3, DEBUG_INTERRUPT_CONTEXT_ID_BIT\n\n    // Send an interrupt to trigger event notification.\n    s_mov_b32            ttmp2, m0\n    s_mov_b32            m0, ttmp3\n    s_nop                0x0 // Manually inserted wait states\n    s_sendmsg            sendmsg(MSG_INTERRUPT)\n\n    // Restore m0\n    s_mov_b32            m0, ttmp2\n\n    // Parking the wave requires saving the original pc in the preserved ttmps.\n    // Since all ttmps are used, we must first free ttmp6 by compressing the\n    // 40bit dispatch ptr in ttmp6:7 into a 25bit queue packet id.\n    //\n    // Register layout before parking the wave:\n    //\n    // ttmp6: dispatch_ptr[31:6] 0[5:0]\n    // ttmp7: 0[0] wave_stopped[0] status_halt[0] trap_id[3:0] 0[16:0] dispatch_ptr[39:32]\n    // ttmp11: 1st_level_ttmp11[31:23] 0[15:0] 1st_level_ttmp11[6:0]\n    //\n    // After parking the wave:\n    //\n    // ttmp6:  pc_lo[31:0]\n    // ttmp7:  1[0] wave_stopped[0] status_halt[0] trap_id[3:0] packet_id[24:0]\n    // ttmp11: 1st_level_ttmp11[31:23] pc_hi[15:0] 1st_level_ttmp11[6:0]\n    //\n    // The conversion from dispatch ptr to queue packet index only needs to be\n    // done once, the first time the wave executes the trap handler.\n\n  .if ((.amdgcn.gfx_generation_number == 10 && .amdgcn.gfx_generation_minor >= 3) || .amdgcn.gfx_generation_number > 10)\n    s_branch             .halt_wave\n  .else\n    s_bitcmp1_b32        ttmp7, TTMP7_DISPATCH_ID_CONVERTED_BIT\n    s_cbranch_scc1       .ttmp7_has_dispatch_index\n\n    s_and_b32            ttmp3, ttmp3, MAX_NUM_DOORBELLS_MASK\n    s_lshl_b32           ttmp3, ttmp3, 0x3\n\n    // Map doorbell index to amd_queue_t* through TMA (doorbell_queue_map).\n    s_load_dwordx2       [ttmp2, ttmp3], [ttmp14, ttmp15], ttmp3 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Retrieve queue base_address from hsa_queue_t*.\n    s_load_dword         ttmp2, [ttmp2, ttmp3], 0x8 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // The dispatch index is (dispatch_ptr.lo - base_address.lo) >> 6\n    s_sub_u32            ttmp2, ttmp6, ttmp2\n    s_lshr_b32           ttmp2, ttmp2, 0x6\n    s_andn2_b32          ttmp7, ttmp7, TTMP7_PACKET_INDEX_MASK\n    s_or_b32             ttmp7, ttmp7, ttmp2\n    s_bitset1_b32        ttmp7, TTMP7_DISPATCH_ID_CONVERTED_BIT\n\n  .ttmp7_has_dispatch_index:\n    // Save the PC\n    s_mov_b32            ttmp6, ttmp0\n    s_and_b32            ttmp1, ttmp1, SQ_WAVE_PC_HI_ADDRESS_MASK\n    s_lshl_b32           ttmp1, ttmp1, TTMP11_PC_HI_SHIFT\n    s_andn2_b32          ttmp11, ttmp11, (SQ_WAVE_PC_HI_ADDRESS_MASK << TTMP11_PC_HI_SHIFT)\n    s_or_b32             ttmp11, ttmp11, ttmp1\n\n    // Park the wave\n    s_getpc_b64          [ttmp0, ttmp1]\n    s_add_u32            ttmp0, ttmp0, .parked - .\n    s_addc_u32           ttmp1, ttmp1, 0x0\n    s_branch             .halt_wave\n\n  .parked:\n    s_trap               0x2\n    s_branch             .parked\n  .endif\n\n  .excp_raised:\n    // If memory violation without XNACK error then signal queue error.\n    // XNACK error will be handled by VM interrupt, since it has more information.\n    s_and_b32            ttmp3, ttmp2, (SQ_WAVE_TRAPSTS_MEM_VIOL_MASK | SQ_WAVE_TRAPSTS_XNACK_ERROR_MASK)\n    s_cmp_eq_u32         ttmp3, SQ_WAVE_TRAPSTS_MEM_VIOL_MASK\n    s_mov_b32            ttmp3, SIGNAL_CODE_MEM_VIOL\n    s_cbranch_scc1       .signal_error\n\n    // If illegal instruction then signal queue error.\n    s_and_b32            ttmp3, ttmp2, SQ_WAVE_TRAPSTS_ILLEGAL_INST_MASK\n    s_mov_b32            ttmp3, SIGNAL_CODE_ILLEGAL_INST\n    s_cbranch_scc1       .signal_error\n\n    // Otherwise (memory violation with XNACK error) return to shader. Do not\n    // send a signal as that will cause an interrupt storm. Instead let the\n    // interrupt generated by the TLB miss cause the kernel to notify ROCr and\n    // put the queue into an error state. This also ensures the TLB interrupt\n    // is received which provides information about the page causing the fault.\n    s_branch             .halt_wave\n\n  .trap_raised:\n    // Save the entry trap id in ttmp7.saved_trap_id\n    s_min_u32            ttmp3, ttmp2, 0xF\n    s_lshl_b32           ttmp3, ttmp3, TTMP7_SAVED_TRAP_ID_SHIFT\n    s_or_b32             ttmp7, ttmp7, ttmp3\n\n    // If debugger trap (s_trap >= 3) then signal debugger.\n    s_cmp_ge_u32         ttmp2, 0x3;\n    s_cbranch_scc1       .signal_debugger\n\n    // If llvm.trap (s_trap 2) then signal queue error.\n    s_cmp_eq_u32         ttmp2, 0x2\n    s_mov_b32            ttmp3, SIGNAL_CODE_LLVM_TRAP\n    s_cbranch_scc1       .signal_error\n\n    // For other traps advance PC and return to shader.\n    s_add_u32            ttmp0, ttmp0, 0x4\n    s_addc_u32           ttmp1, ttmp1, 0x0\n    s_branch             .exit_trap\n\n  .signal_error:\n  .if (.amdgcn.gfx_generation_number == 10 && .amdgcn.gfx_generation_minor >= 3)\n    // This needs to be rewritten for gfx10.3 as scalar stores are not available.\n  .else\n    // FIXME: don't trash ttmp4/ttmp5 when exception handling is unified.\n    s_mov_b32            ttmp4, ttmp3\n\n    // Fetch doorbell index for our queue.\n    s_mov_b32            ttmp2, exec_lo\n    s_mov_b32            ttmp3, exec_hi\n    mGetDoorbellId\n    s_mov_b32            exec_hi, ttmp3\n\n    // Restore exec_lo, move the doorbell index into ttmp3\n    s_and_b32            exec_lo, exec_lo, MAX_NUM_DOORBELLS_MASK\n    s_lshl_b32           ttmp3, exec_lo, 0x3\n    s_mov_b32            exec_lo, ttmp2\n\n    // Map doorbell index to amd_queue_t* through TMA (doorbell_queue_map).\n    s_load_dwordx2       [ttmp2, ttmp3], [ttmp14, ttmp15], ttmp3 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Retrieve queue_inactive_signal from amd_queue_t*.\n    s_load_dwordx2       [ttmp2, ttmp3], [ttmp2, ttmp3], 0xC0 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Set queue signal value to error code.\n    s_mov_b32            ttmp5, 0x0\n    s_atomic_swap_x2     [ttmp4, ttmp5], [ttmp2, ttmp3], 0x8 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Skip event trigger if the signal value was already non-zero.\n    s_or_b32             ttmp4, ttmp4, ttmp5\n    s_cbranch_scc1       .skip_event_trigger\n\n    // Check for a non-NULL signal event mailbox.\n    s_load_dwordx2       [ttmp4, ttmp5], [ttmp2, ttmp3], 0x10 glc\n    s_waitcnt            lgkmcnt(0)\n    s_and_b64            [ttmp4, ttmp5], [ttmp4, ttmp5], [ttmp4, ttmp5]\n    s_cbranch_scc0       .skip_event_trigger\n\n    // Load the signal event value.\n    s_load_dword         ttmp2, [ttmp2, ttmp3], 0x18 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Write the signal event value to the mailbox.\n    s_store_dword        ttmp2, [ttmp4, ttmp5], 0x0 glc\n    s_waitcnt            lgkmcnt(0)\n\n    // Send an interrupt to trigger event notification.\n    s_mov_b32            m0, 0x0\n    s_nop                0\n    s_sendmsg            sendmsg(MSG_INTERRUPT)\n  .endif\n\n  .skip_event_trigger:\n    // Since we trashed ttmp4/ttmp5, reset the wave_id to 0\n    s_mov_b32            ttmp4, 0x0\n    s_mov_b32            ttmp5, 0x0\n\n  .halt_wave:\n    s_bitset1_b32        ttmp7, TTMP7_WAVE_STOPPED_BIT\n\n    // Halt the wavefront.\n    s_bitset1_b32        ttmp12, SQ_WAVE_STATUS_HALT_BIT\n\n  .exit_trap:\n    mExitTrap\n*/\n    0x8973ff73, 0x3e000000, 0x92eeff78, 0x0001000d, 0x8e6e9d6e, 0x87736e73,\n    0x92eeff6d, 0x00080010, 0xbf850041, 0xb8eef803, 0x866fff6e, 0x00000900,\n    0xbf850031, 0xbeee007e, 0xbeef007f, 0xbefe00ff, 0x80000000, 0xbf90000a,\n    0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff006f, 0x866fff7e, 0x00000fff,\n    0xbefe006e, 0xbeef1a97, 0xbeee007c, 0xbefc006f, 0xbf800000, 0xbf900001,\n    0xbefc006e, 0xbf0d9f73, 0xbf85000f, 0x866fff6f, 0x000003ff, 0x8e6f836f,\n    0xc0051bbd, 0x0000006f, 0xbf8cc07f, 0xc0031bb7, 0x00000008, 0xbf8cc07f,\n    0x80ee6e72, 0x8f6e866e, 0x8973ff73, 0x01ffffff, 0x87736e73, 0xbef31a9f,\n    0xbef2006c, 0x866dff6d, 0x0000ffff, 0x8e6d876d, 0x8977ff77, 0x007fff80,\n    0x87776d77, 0xbeec1c00, 0x806cff6c, 0x00000010, 0x826d806d, 0xbf820044,\n    0xbf920002, 0xbf82fffe, 0x866fff6e, 0x10000100, 0xbf06ff6f, 0x00000100,\n    0xbeef00ff, 0x20000000, 0xbf850011, 0x866fff6e, 0x00000800, 0xbeef00f4,\n    0xbf85000d, 0xbf820036, 0x83ef8f6e, 0x8e6f996f, 0x87736f73, 0xbf09836e,\n    0xbf85ffbe, 0xbf06826e, 0xbeef00ff, 0x80000000, 0xbf850003, 0x806c846c,\n    0x826d806d, 0xbf82002c, 0xbef0006f, 0xbeee007e, 0xbeef007f, 0xbefe00ff,\n    0x80000000, 0xbf90000a, 0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff006f,\n    0x867eff7e, 0x000003ff, 0x8e6f837e, 0xbefe006e, 0xc0051bbd, 0x0000006f,\n    0xbf8cc07f, 0xc0071bb7, 0x000000c0, 0xbf8cc07f, 0xbef10080, 0xc2831c37,\n    0x00000008, 0xbf8cc07f, 0x87707170, 0xbf85000e, 0xc0071c37, 0x00000010,\n    0xbf8cc07f, 0x86f07070, 0xbf840009, 0xc0031bb7, 0x00000018, 0xbf8cc07f,\n    0xc0431bb8, 0x00000000, 0xbf8cc07f, 0xbefc0080, 0xbf800000, 0xbf900001,\n    0xbef00080, 0xbef10080, 0xbef31a9e, 0xbef81a8d, 0x8f6e8b77, 0x866eff6e,\n    0x001f8000, 0xb96ef807, 0x86fe7e7e, 0x86ea6a6a, 0xb978f802, 0xbe801f6c,\n};\n\nstatic const unsigned int kCodeTrapHandler90a[] = {\n    0x8973ff73, 0x3e000000, 0x92eeff78, 0x0001000d, 0x8e6e9d6e, 0x87736e73,\n    0x92eeff6d, 0x00080010, 0xbf850041, 0xb8eef803, 0x866fff6e, 0x00000900,\n    0xbf850031, 0xbeee007e, 0xbeef007f, 0xbefe00ff, 0x80000000, 0xbf90000a,\n    0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff006f, 0x866fff7e, 0x00000fff,\n    0xbefe006e, 0xbeef1a97, 0xbeee007c, 0xbefc006f, 0xbf800000, 0xbf900001,\n    0xbefc006e, 0xbf0d9f73, 0xbf85000f, 0x866fff6f, 0x000003ff, 0x8e6f836f,\n    0xc0051bbd, 0x0000006f, 0xbf8cc07f, 0xc0031bb7, 0x00000008, 0xbf8cc07f,\n    0x80ee6e72, 0x8f6e866e, 0x8973ff73, 0x01ffffff, 0x87736e73, 0xbef31a9f,\n    0xbef2006c, 0x866dff6d, 0x0000ffff, 0x8e6d876d, 0x8977ff77, 0x007fff80,\n    0x87776d77, 0xbeec1c00, 0x806cff6c, 0x00000010, 0x826d806d, 0xbf820044,\n    0xbf920002, 0xbf82fffe, 0x866fff6e, 0x10000100, 0xbf06ff6f, 0x00000100,\n    0xbeef00ff, 0x20000000, 0xbf850011, 0x866fff6e, 0x00000800, 0xbeef00f4,\n    0xbf85000d, 0xbf820036, 0x83ef8f6e, 0x8e6f996f, 0x87736f73, 0xbf09836e,\n    0xbf85ffbe, 0xbf06826e, 0xbeef00ff, 0x80000000, 0xbf850003, 0x806c846c,\n    0x826d806d, 0xbf82002c, 0xbef0006f, 0xbeee007e, 0xbeef007f, 0xbefe00ff,\n    0x80000000, 0xbf90000a, 0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff006f,\n    0x867eff7e, 0x000003ff, 0x8e6f837e, 0xbefe006e, 0xc0051bbd, 0x0000006f,\n    0xbf8cc07f, 0xc0071bb7, 0x000000c0, 0xbf8cc07f, 0xbef10080, 0xc2831c37,\n    0x00000008, 0xbf8cc07f, 0x87707170, 0xbf85000e, 0xc0071c37, 0x00000010,\n    0xbf8cc07f, 0x86f07070, 0xbf840009, 0xc0031bb7, 0x00000018, 0xbf8cc07f,\n    0xc0431bb8, 0x00000000, 0xbf8cc07f, 0xbefc0080, 0xbf800000, 0xbf900001,\n    0xbef00080, 0xbef10080, 0xbef31a9e, 0xbef81a8d, 0x8f6e8b77, 0x866eff6e,\n    0x001f8000, 0xb96ef807, 0x86fe7e7e, 0x86ea6a6a, 0xb978f802, 0xbe801f6c,\n};\n\n\nstatic const unsigned int kCodeTrapHandler1010[] = {\n    0x8a73ff73, 0x3e000000, 0x93eeff78, 0x0001000d, 0x8f6e9d6e, 0x88736e73,\n    0x93eeff6d, 0x00080010, 0xbf850041, 0xb96ef803, 0x876fff6e, 0x00000900,\n    0xbf850031, 0xbeee037e, 0xbeef037f, 0xbefe03ff, 0x80000000, 0xbf90000a,\n    0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff036f, 0x876fff7e, 0x00000fff,\n    0xbefe036e, 0xbeef1d96, 0xbeee037c, 0xbefc036f, 0xbf800000, 0xbf900001,\n    0xbefc036e, 0xbf0d9f73, 0xbf85000f, 0x876fff6f, 0x000003ff, 0x8f6f836f,\n    0xf4051bbd, 0xde000000, 0xbf8cc07f, 0xf4011bb7, 0xfa000008, 0xbf8cc07f,\n    0x80ee6e72, 0x906e866e, 0x8a73ff73, 0x01ffffff, 0x88736e73, 0xbef31d9f,\n    0xbef2036c, 0x876dff6d, 0x0000ffff, 0x8f6d876d, 0x8a77ff77, 0x007fff80,\n    0x88776d77, 0xbeec1f00, 0x806cff6c, 0x00000010, 0x826d806d, 0xbf820044,\n    0xbf920002, 0xbf82fffe, 0x876fff6e, 0x10000100, 0xbf06ff6f, 0x00000100,\n    0xbeef03ff, 0x20000000, 0xbf850011, 0x876fff6e, 0x00000800, 0xbeef03f4,\n    0xbf85000d, 0xbf820036, 0x83ef8f6e, 0x8f6f996f, 0x88736f73, 0xbf09836e,\n    0xbf85ffbe, 0xbf06826e, 0xbeef03ff, 0x80000000, 0xbf850003, 0x806c846c,\n    0x826d806d, 0xbf82002c, 0xbef0036f, 0xbeee037e, 0xbeef037f, 0xbefe03ff,\n    0x80000000, 0xbf90000a, 0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff036f,\n    0x877eff7e, 0x000003ff, 0x8f6f837e, 0xbefe036e, 0xf4051bbd, 0xde000000,\n    0xbf8cc07f, 0xf4051bb7, 0xfa0000c0, 0xbf8cc07f, 0xbef10380, 0xf6811c37,\n    0xfa000008, 0xbf8cc07f, 0x88707170, 0xbf85000e, 0xf4051c37, 0xfa000010,\n    0xbf8cc07f, 0x87f07070, 0xbf840009, 0xf4011bb7, 0xfa000018, 0xbf8cc07f,\n    0xf4411bb8, 0xfa000000, 0xbf8cc07f, 0xbefc0380, 0xbf800000, 0xbf900001,\n    0xbef00380, 0xbef10380, 0xbef31d9e, 0xbef81d8d, 0x906e8977, 0x876fff6e,\n    0x003f8000, 0x906e8677, 0x876eff6e, 0x02000000, 0x886e6f6e, 0xb9eef807,\n    0x87fe7e7e, 0x87ea6a6a, 0xb9f8f802, 0xbe80226c,\n};\n\nstatic const unsigned int kCodeTrapHandler10[] = {\n    0x8a73ff73, 0x3e000000, 0x93eeff78, 0x0001000d, 0x8f6e9d6e, 0x88736e73,\n    0x93eeff6d, 0x00080010, 0xbf850023, 0xb96ef803, 0x876fff6e, 0x00000900,\n    0xbf850013, 0xbeee037e, 0xbeef037f, 0xbefe03ff, 0x80000000, 0xbf90000a,\n    0xbf800007, 0xbf0c9f7e, 0xbf84fffd, 0xbeff036f, 0x876fff7e, 0x00000fff,\n    0xbefe036e, 0xbeef1d96, 0xbeee037c, 0xbefc036f, 0xbf800000, 0xbf900001,\n    0xbefc036e, 0xbf82001a, 0x876fff6e, 0x10000100, 0xbf06ff6f, 0x00000100,\n    0xbeef03ff, 0x20000000, 0xbf850011, 0x876fff6e, 0x00000800, 0xbeef03f4,\n    0xbf85000d, 0xbf82000e, 0x83ef8f6e, 0x8f6f996f, 0x88736f73, 0xbf09836e,\n    0xbf85ffdc, 0xbf06826e, 0xbeef03ff, 0x80000000, 0xbf850003, 0x806c846c,\n    0x826d806d, 0xbf820004, 0xbef00380, 0xbef10380, 0xbef31d9e, 0xbef81d8d,\n    0x906e8977, 0x876fff6e, 0x003f8000, 0x906e8677, 0x876eff6e, 0x02000000,\n    0x886e6f6e, 0xb9eef807, 0x87fe7e7e, 0x87ea6a6a, 0xb9f8f802, 0xbe80226c,\n};\n\n}  // namespace AMD\n}  // namespace rocr\n\n#endif  //OPENSRC_HSA_RUNTIME_CORE_INC_AMD_TRAP_HANDLER_V1_H_ \n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_virtio_driver.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_AMD_VIRTIO_DRIVER_H_\n#define HSA_RUNTIME_CORE_INC_AMD_VIRTIO_DRIVER_H_\n\n#include <memory>\n#include <string>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/driver.h\"\n#include \"core/inc/memory_region.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nclass KfdVirtioDriver final : public core::Driver {\n public:\n  KfdVirtioDriver(std::string devnode_name);\n\n  static hsa_status_t DiscoverDriver(std::unique_ptr<core::Driver>& driver);\n\n  hsa_status_t Init() override;\n  hsa_status_t ShutDown() override;\n  hsa_status_t QueryKernelModeDriver(core::DriverQuery query) override;\n  hsa_status_t Open() override;\n  hsa_status_t Close() override;\n  hsa_status_t GetSystemProperties(HsaSystemProperties& sys_props) const override;\n  hsa_status_t GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const override;\n  hsa_status_t GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                 uint32_t node_id) const override;\n  hsa_status_t GetMemoryProperties(uint32_t node_id,\n                                   std::vector<HsaMemoryProperties>& mem_props) const override;\n  hsa_status_t GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                  std::vector<HsaCacheProperties>& cache_props) const override;\n  hsa_status_t GetDeviceHandle(uint32_t node_id, void** device_handle) const;\n  hsa_status_t GetClockCounters(uint32_t node_id, HsaClockCounters* clock_counter) const;\n  hsa_status_t SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                              const void* buffer_base, uint64_t buffer_base_size) const;\n  hsa_status_t AllocateMemory(const core::MemoryRegion& mem_region,\n                              core::MemoryRegion::AllocateFlags alloc_flags, void** mem,\n                              size_t size, uint32_t agent_node_id) override;\n  hsa_status_t FreeMemory(void* mem, size_t size) override;\n  hsa_status_t AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const;\n  hsa_status_t RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const override;\n  hsa_status_t DeregisterMemory(void* ptr) const override;\n  hsa_status_t AvailableMemory(uint32_t node_id, uint64_t* available_size) const;\n  hsa_status_t MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                  const HsaMemMapFlags* mem_flags, uint32_t num_nodes,\n                                  const uint32_t* nodes) const override;\n  hsa_status_t MakeMemoryUnresident(const void* mem) const override;\n  hsa_status_t CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                           HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id, void* queue_addr,\n                           uint64_t queue_size_bytes, HsaEvent* event,\n                           HsaQueueResource& queue_resource) const override;\n  hsa_status_t DestroyQueue(HSA_QUEUEID queue_id) const override;\n  hsa_status_t UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_percentage,\n                           HSA_QUEUE_PRIORITY priority, void* queue_mem, uint64_t queue_size,\n                           HsaEvent* event) const override;\n  hsa_status_t SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t num_cu_mask,\n                              uint32_t* cu_mask) const override;\n  hsa_status_t AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_GWS, uint32_t* GWS) const override;\n  hsa_status_t ExportDMABuf(void* mem, size_t size, int* dmabuf_fd, size_t* offset) override;\n  hsa_status_t ImportDMABuf(int dmabuf_fd, core::Agent& agent,\n                            core::ShareableHandle& handle) override;\n  hsa_status_t Map(core::ShareableHandle handle, void* mem, size_t offset, size_t size,\n                   hsa_access_permission_t perms) override;\n  hsa_status_t Unmap(core::ShareableHandle handle, void* mem, size_t offset, size_t size) override;\n  hsa_status_t ReleaseShareableHandle(core::ShareableHandle& handle) override;\n  hsa_status_t GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const;\n  hsa_status_t SPMAcquire(uint32_t node_id) const override;\n  hsa_status_t SPMRelease(uint32_t node_id) const override;\n  hsa_status_t SPMSetDestBuffer(uint32_t node_id, uint32_t size, uint32_t* timeout,\n                                uint32_t* size_copied, void* dest,\n                                bool* is_data_loss) const override;\n  hsa_status_t OpenSMI(uint32_t node_id, int* fd) const override;\n  hsa_status_t GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const;\n  hsa_status_t IsModelEnabled(bool* enable) const override;\n};\n\n}  // namespace AMD\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_AMD_VIRTIO_DRIVER_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/amd_xdna_driver.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n#ifndef HSA_RUNTIME_CORE_INC_AMD_XDNA_DRIVER_H_\n#define HSA_RUNTIME_CORE_INC_AMD_XDNA_DRIVER_H_\n\n#include <array>\n#include <climits>\n#include <map>\n#include <memory>\n#include <unordered_map>\n\n#include \"core/driver/xdna/uapi/amdxdna_accel.h\"\n#include \"core/inc/amd_aie_agent.h\"\n#include \"core/inc/driver.h\"\n#include \"core/inc/memory_region.h\"\n\n/// @brief struct amdxdna_cmd_chain - Interpretation of data payload for\n/// ERT_CMD_CHAIN\nstruct amdxdna_cmd_chain {\n  /// Number of commands in chain\n  __u32 command_count;\n  /// Index of last successfully submitted command in chain\n  __u32 submit_index;\n  /// Index of failing command if cmd status is not completed\n  __u32 error_index;\n  __u32 reserved[3];\n  /// Address of each command in chain\n  __u64 data[] __counted_by(command_count);\n};\n\n/// @brief struct amdxdna_cmd - Exec buffer command header format\nstruct amdxdna_cmd {\n  union {\n    struct {\n      /// Current state of a command\n      __u32 state : 4;\n      __u32 unused : 6;\n      /// Extra CU masks in addition to mandatory mask\n      __u32 extra_cu_masks : 2;\n      /// Number of words in payload (data)\n      __u32 count : 11;\n      /// Opcode identifying specific command\n      __u32 opcode : 5;\n      __u32 reserved : 4;\n    };\n    __u32 header;\n  };\n  /// Count number of words representing packet payload\n  __u32 data[] __counted_by(count);\n};\n\nnamespace rocr {\nnamespace core {\nclass Queue;\n}\n\nnamespace AMD {\n\n// @brief: Used to transform an address into a device address\nconstexpr uint32_t DEV_ADDR_BASE = 0x04000000;\nconstexpr uint32_t DEV_ADDR_OFFSET_MASK = 0x02FFFFFF;\n\n/// @brief: The driver places a structure before each command in a command chain.\n/// Need to increase the size of the command by the size of this structure.\n/// In the following xdna driver source can see where this is implemented:\n/// Commit hash: eddd92c0f61592c576a500f16efa24eb23667c23\n/// https://github.com/amd/xdna-driver/blob/main/src/driver/amdxdna/aie2_msg_priv.h#L387-L391\n/// https://github.com/amd/xdna-driver/blob/main/src/driver/amdxdna/aie2_message.c#L637\nconstexpr uint32_t CMD_COUNT_SIZE_INCREASE = 3;\n\n/// @brief: The size of an instruction in bytes\nconstexpr uint32_t INSTR_SIZE_BYTES = 4;\n\n/// @brief: Index of command payload where the instruction sequence\n/// address is located\nconstexpr uint32_t CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_IDX = 2;\nconstexpr uint32_t CMD_PKT_PAYLOAD_INSTRUCTION_SEQUENCE_SIZE_IDX = 4;\n\n/// @brief Environment variable to define job submission timeout\nconstexpr uint32_t DEFAULT_TIMEOUT_VAL = 50;\n\nclass XdnaDriver final : public core::Driver {\n  /// @brief BO handle information.\n  struct BOHandle {\n    /// Mapped address.\n    void* vaddr = nullptr;\n    /// Handle returned by xdna.\n    uint32_t handle = AMDXDNA_INVALID_BO_HANDLE;\n    /// Size in bytes.\n    size_t size = 0;\n\n    constexpr BOHandle() = default;\n    constexpr BOHandle(void* vaddr, uint32_t handle, size_t size)\n        : vaddr{vaddr}, handle{handle}, size{size} {}\n    constexpr bool IsValid() const { return handle != AMDXDNA_INVALID_BO_HANDLE; }\n  };\n\n  /// @brief CU mask size.\n  static constexpr size_t cu_mask_size = sizeof(uint32_t) * CHAR_BIT;\n\n  /// @brief Per hardware context PDI cache.\n  class PDICache {\n    std::array<BOHandle, cu_mask_size> entries = {};\n    size_t entry_count = 0;\n\n   public:\n    /// @brief Sentinel value for entries not found.\n    constexpr static size_t NotFound = cu_mask_size;\n\n    /// @brief Returns the size of the cache.\n    constexpr size_t size() const { return entry_count; }\n\n    /// @brief Returns the index of the BO handle if it is the cache, otherwise @ref NotFound.\n    ///\n    /// This function does a linear search because the mask is small (32 elements).\n    size_t GetIndex(uint32_t pdi_handle) const {\n      for (size_t i = 0; i < entry_count; ++i) {\n        if (entries[i].handle == pdi_handle) {\n          return i;\n        }\n      }\n      return NotFound;\n    }\n\n    /// @brief Sets the next cache entry.\n    hsa_status_t SetNext(const BOHandle& pdi_bo_handle, size_t& index) {\n      if (entry_count == entries.size()) {\n        // cache is full\n        return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n      }\n\n      index = entry_count++;\n      entries[index] = pdi_bo_handle;\n      return HSA_STATUS_SUCCESS;\n    }\n\n    constexpr const BOHandle& operator[](size_t index) const { return entries[index]; }\n  };\n\npublic:\n  XdnaDriver(std::string devnode_name);\n\n  static hsa_status_t DiscoverDriver(std::unique_ptr<core::Driver>& driver);\n\n  /// @brief Returns the size of the system memory heap in bytes.\n  static uint64_t GetSystemMemoryByteSize();\n\n  /// @brief Returns the size of the dev heap in bytes.\n  static uint64_t GetDevHeapByteSize();\n\n  hsa_status_t Init() override;\n  hsa_status_t ShutDown() override;\n  hsa_status_t QueryKernelModeDriver(core::DriverQuery query) override;\n\n  hsa_status_t Open() override;\n  hsa_status_t Close() override;\n  hsa_status_t GetSystemProperties(HsaSystemProperties& sys_props) const override;\n  hsa_status_t GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const override;\n  hsa_status_t GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                 uint32_t node_id) const override;\n  hsa_status_t GetMemoryProperties(uint32_t node_id,\n                                   std::vector<HsaMemoryProperties>& mem_props) const override;\n  hsa_status_t GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                  std::vector<HsaCacheProperties>& cache_props) const override;\n  hsa_status_t AllocateMemory(const core::MemoryRegion &mem_region,\n                              core::MemoryRegion::AllocateFlags alloc_flags,\n                              void **mem, size_t size,\n                              uint32_t node_id) override;\n  hsa_status_t FreeMemory(void *mem, size_t size) override;\n  hsa_status_t CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                           HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id, void* queue_addr,\n                           uint64_t queue_size_bytes, HsaEvent* event,\n                           HsaQueueResource& queue_resource) const override;\n  hsa_status_t UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_pct, HSA_QUEUE_PRIORITY priority,\n                           void* queue_addr, uint64_t queue_size, HsaEvent* event) const override;\n  hsa_status_t DestroyQueue(HSA_QUEUEID queue_id) const override;\n  hsa_status_t SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t cu_mask_count,\n                              uint32_t* queue_cu_mask) const override;\n  hsa_status_t AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_gws,\n                             uint32_t* first_gws) const override;\n  hsa_status_t ExportDMABuf(void *mem, size_t size, int *dmabuf_fd,\n                            size_t *offset) override;\n  hsa_status_t ImportDMABuf(int dmabuf_fd, core::Agent &agent,\n                            core::ShareableHandle &handle) override;\n  hsa_status_t Map(core::ShareableHandle handle, void *mem, size_t offset,\n                   size_t size, hsa_access_permission_t perms) override;\n  hsa_status_t Unmap(core::ShareableHandle handle, void *mem, size_t offset,\n                     size_t size) override;\n  hsa_status_t ReleaseShareableHandle(core::ShareableHandle &handle) override;\n\n  /// @brief Submits @p num_pkts packets in a command chain.\n  hsa_status_t SubmitCmdChain(hsa_amd_aie_ert_packet_t* first_pkt, uint32_t num_pkts,\n                              HSA_QUEUEID& queue_id, uint32_t num_core_tiles);\n\n  hsa_status_t SPMAcquire(uint32_t preferred_node_id) const override;\n  hsa_status_t SPMRelease(uint32_t preferred_node_id) const override;\n  hsa_status_t SPMSetDestBuffer(uint32_t preferred_node_id, uint32_t size_bytes, uint32_t* timeout,\n                                uint32_t* size_copied, void* dest_mem_addr,\n                                bool* is_spm_data_loss) const override;\n  hsa_status_t SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                              const void* buffer_base, uint64_t buffer_base_size) const override;\n  hsa_status_t GetDeviceHandle(uint32_t node_id, void** device_handle) const override;\n  hsa_status_t GetClockCounters(uint32_t node_id, HsaClockCounters* clock_counter) const override;\n  hsa_status_t GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const override;\n  hsa_status_t GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const override;\n  hsa_status_t AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const override;\n  hsa_status_t AvailableMemory(uint32_t node_id, uint64_t* available_size) const override;\n  hsa_status_t RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const override;\n  hsa_status_t DeregisterMemory(void* ptr) const override;\n  hsa_status_t MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                  const HsaMemMapFlags* mem_flags, uint32_t num_nodes,\n                                  const uint32_t* nodes) const override;\n  hsa_status_t MakeMemoryUnresident(const void* mem) const override;\n\n  hsa_status_t IsModelEnabled(bool* enable) const override;\n\n private:\n  /// @brief Destroys @p bo_handle.\n  ///\n  /// This function will unmap the virtual address and close the BO, but will not return any status.\n  void DestroyBOHandle(BOHandle& bo_handle);\n\n  /// @brief Finds the BO associated with the address.\n  BOHandle FindBOHandle(void* mem) const;\n\n  /// @brief Creates a new hardware context with the given PDI BO handles.\n  hsa_status_t ConfigHwCtx(const PDICache& pdi_bo_handles, HSA_QUEUEID& queue_id,\n                           uint32_t num_core_tiles);\n\n  hsa_status_t QueryDriverVersion();\n\n  /// @brief Allocate device accesible heap space.\n  ///\n  /// Allocate and map a buffer object (BO) that the AIE device can access.\n  hsa_status_t InitDeviceHeap();\n  hsa_status_t FreeDeviceHeap();\n\n  /// @brief Creates a command BO and returns it to @p bo_info.\n  ///\n  /// @param size size of memory to allocate\n  /// @param bo_info allocated BO\n  hsa_status_t CreateCmdBO(uint32_t size, BOHandle& bo_info);\n\n  /// @brief Gets all BOs from a command packet payload, flushes the caches associated with them and\n  /// replaces the instruction virtual address with the device address.\n  ///\n  /// @param count Number of entries in the command\n  /// @param cmd_pkt_payload A pointer to the payload of the command\n  /// @param bo_handles vector that contains all BO handles\n  hsa_status_t PrepareBOs(uint32_t count, hsa_amd_aie_ert_start_kernel_data_t* cmd_pkt_payload,\n                          std::vector<uint32_t>& bo_handles);\n\n  /// @brief Executes a command and waits for its completion\n  ///\n  /// @param cmd_chain_bo_handle command to execute\n  /// @param bo_handles handles associated with the command\n  /// @param aie_queue queue to submit to\n  hsa_status_t ExecCmdAndWait(const BOHandle& cmd_chain_bo_handle,\n                              const std::vector<uint32_t>& bo_handles, HSA_QUEUEID queue_id);\n\n  /// TODO: Remove this in the future and rely on the core Runtime\n  /// object to track handle allocations. Using the VMEM API for mapping XDNA\n  /// driver handles requires a bit more refactoring. So rely on the XDNA driver\n  /// to manage some of this for now.\n  std::unordered_map<uint32_t, void *> vmem_handle_mappings;\n  std::map<void*, BOHandle> vmem_addr_mappings;\n\n  /// @brief Hardware context to PDI cache mapping.\n  std::unordered_map<uint32_t, PDICache> hw_ctx_pdi_cache_map;\n\n  /// @brief Virtual address range allocated for the device heap.\n  ///\n  /// Allocate a large enough space so we can carve out the device heap in\n  /// this range and ensure it is aligned to 64MB. Currently, npu1 supports\n  /// 64MB device heap and it must be aligned to 64MB.\n  BOHandle dev_heap_handle;\n\n  /// @brief The aligned device heap.\n  void *dev_heap_aligned = nullptr;\n\n  static constexpr size_t dev_heap_size = 64 * 1024 * 1024;\n  static constexpr size_t dev_heap_align = 64 * 1024 * 1024;\n};\n\n} // namespace AMD\n} // namespace rocr\n\n#endif // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/blit.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_BLIT_H_\n#define HSA_RUNTIME_CORE_INC_BLIT_H_\n\n#include <stdint.h>\n\n#include \"core/inc/agent.h\"\n\nnamespace rocr {\nnamespace core {\nclass Blit {\n public:\n  explicit Blit() {}\n  virtual ~Blit() {}\n\n  /// @brief Marks the blit object as invalid and uncouples its link with\n  /// the underlying compute device's control block. Use of blit object\n  /// once it has been release is illegal and any behavior is indeterminate\n  ///\n  /// @note: The call will block until all commands have executed.\n  ///\n  /// @param agent Agent passed to Initialize.\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t Destroy(const core::Agent& agent) = 0;\n\n  /// @brief Submit a linear copy command to the the underlying compute device's\n  /// control block. The call is blocking until the command execution is\n  /// finished.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  virtual hsa_status_t SubmitLinearCopyCommand(void* dst, const void* src,\n                                               size_t size) = 0;\n\n  /// @brief Submit a linear copy command to the the underlying compute device's\n  /// control block. The call is non blocking. The memory transfer will start\n  /// after all dependent signals are satisfied. After the transfer is\n  /// completed, the out signal will be decremented.\n  ///\n  /// @param dst Memory address of the copy destination.\n  /// @param src Memory address of the copy source.\n  /// @param size Size of the data to be copied.\n  /// @param dep_signals Arrays of dependent signal.\n  /// @param out_signal Output signal.\n  /// @param gang_signals Array of gang signals.\n  virtual hsa_status_t SubmitLinearCopyCommand(\n      void* dst, const void* src, size_t size,\n      std::vector<core::Signal*>& dep_signals, core::Signal& out_signal,\n      std::vector<core::Signal*>& gang_signals) = 0;\n\n  /// @brief Submit a linear fill command to the the underlying compute device's\n  /// control block. The call is blocking until the command execution is\n  /// finished.\n  ///\n  /// @param ptr Memory address of the fill destination.\n  /// @param value Value to be set.\n  /// @param num Number of uint32_t element to be set to the value.\n  virtual hsa_status_t SubmitLinearFillCommand(void* ptr, uint32_t value,\n                                               size_t num) = 0;\n\n  /// @brief Enable profiling of the asynchronous copy command. The timestamp\n  /// of each copy request will be stored in the completion signal structure.\n  ///\n  /// @param enable True to enable profiling. False to disable profiling.\n  ///\n  /// @return HSA_STATUS_SUCCESS if the request to enable/disable profiling is\n  /// successful.\n  virtual hsa_status_t EnableProfiling(bool enable) = 0;\n\n  /// @brief Blit operations use SDMA.\n  virtual bool isSDMA() const { return false; }\n\n  /// @Brief Reports the approximate number of remaining bytes to copy or fill.  Any return of zero\n  /// must be exact.\n  virtual uint64_t PendingBytes() = 0;\n\n  virtual void GangLeader(bool gang_leader) = 0;\n  virtual bool GangLeader() const { return false; };\n};\n}  // namespace core\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/cache.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_CACHE_H\n#define HSA_RUNTIME_CORE_INC_CACHE_H\n\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/checked.h\"\n#include \"core/util/utils.h\"\n#include <utility>\n#include <string>\n\nnamespace rocr {\nnamespace core {\n\nclass Cache : public Checked<0x39A6C7AD3F135B06> {\n public:\n  static __forceinline hsa_cache_t Convert(const Cache* cache) {\n    const hsa_cache_t handle = {static_cast<uint64_t>(reinterpret_cast<uintptr_t>(cache))};\n    return handle;\n  }\n  static __forceinline Cache* Convert(const hsa_cache_t cache) {\n    return reinterpret_cast<Cache*>(static_cast<uintptr_t>(cache.handle));\n  }\n\n  Cache(const std::string& name, uint8_t level, uint32_t size)\n      : name_(name), level_(level), size_(size) {}\n\n  Cache(std::string&& name, uint8_t level, uint32_t size)\n      : name_(std::move(name)), level_(level), size_(size) {}\n\n  hsa_status_t GetInfo(hsa_cache_info_t attribute, void* value);\n\n private:\n  std::string name_;\n  uint32_t level_;\n  uint32_t size_;\n\n  // Forbid copying and moving of this object\n  DISALLOW_COPY_AND_ASSIGN(Cache);\n};\n\n}   // namespace core\n}   // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_CACHE_H\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/checked.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_CHECKED_H_\n#define HSA_RUNTME_CORE_INC_CHECKED_H_\n\n#include <stdint.h>\n#include <stdlib.h>\n\nnamespace rocr {\nnamespace core {\n\n/// @brief Compares type codes and pointers to check object validity.  Used for cast validation.\ntemplate <uint64_t code, bool multiProcess = false> class Check final {\n public:\n  typedef Check<code> CheckType;\n\n  Check() { object_ = uintptr_t(this) ^ uintptr_t(code); }\n  Check(const Check&) { object_ = uintptr_t(this) ^ uintptr_t(code); }\n  Check(Check&&) { object_ = uintptr_t(this) ^ uintptr_t(code); }\n\n  ~Check() { object_ = uintptr_t(NULL); }\n\n  const Check& operator=(Check&& rhs) { return *this; }\n  const Check& operator=(const Check& rhs) { return *this; }\n\n  bool IsValid() const {\n    return object_ == (uintptr_t(this) ^ uintptr_t(code));\n  }\n\n  uint64_t check_code() const { return code; }\n\n private:\n  uintptr_t object_;\n};\n\ntemplate <uint64_t code> class Check<code, true> final {\n public:\n  typedef Check<code> CheckType;\n\n  Check() { object_ = uintptr_t(code); }\n  Check(const Check&) { object_ = uintptr_t(code); }\n  Check(Check&&) { object_ = uintptr_t(code); }\n\n  const Check& operator=(Check&& rhs) { return *this; }\n  const Check& operator=(const Check& rhs) { return *this; }\n\n  bool IsValid() const { return object_ == uintptr_t(code); }\n\n  uint64_t check_code() const { return code; }\n\n private:\n  uintptr_t object_;\n};\n\n/// @brief Base class for validating objects.\ntemplate <uint64_t code> class Checked {\n public:\n  typedef Checked<code> CheckedType;\n\n  bool IsValid() const { return id.IsValid(); }\n\n  virtual ~Checked() {}\n\n private:\n  Check<code, false> id;\n};\n\n}  // namespace core\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/default_signal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_DEFAULT_SIGNAL_H_\n#define HSA_RUNTME_CORE_INC_DEFAULT_SIGNAL_H_\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\n\n/// @brief Operations for a simple pure memory based signal.\n/// @brief See base class Signal.\nclass BusyWaitSignal : public Signal {\n public:\n  /// @brief Determines if a Signal* can be safely converted to BusyWaitSignal*\n  /// via static_cast.\n  static __forceinline bool IsType(Signal* ptr) {\n    return ptr->IsType(&rtti_id());\n  }\n\n  /// @brief See base class Signal.\n  explicit BusyWaitSignal(SharedSignal* abi_block, bool enableIPC);\n\n  // Below are various methods corresponding to the APIs, which load/store the\n  // signal value or modify the existing signal value automically and with\n  // specified memory ordering semantics.\n\n  hsa_signal_value_t LoadRelaxed();\n\n  hsa_signal_value_t LoadAcquire();\n\n  void StoreRelaxed(hsa_signal_value_t value);\n\n  void StoreRelease(hsa_signal_value_t value);\n\n  hsa_signal_value_t WaitRelaxed(hsa_signal_condition_t condition,\n                                 hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint);\n\n  hsa_signal_value_t WaitAcquire(hsa_signal_condition_t condition,\n                                 hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint);\n\n  void AndRelaxed(hsa_signal_value_t value);\n\n  void AndAcquire(hsa_signal_value_t value);\n\n  void AndRelease(hsa_signal_value_t value);\n\n  void AndAcqRel(hsa_signal_value_t value);\n\n  void OrRelaxed(hsa_signal_value_t value);\n\n  void OrAcquire(hsa_signal_value_t value);\n\n  void OrRelease(hsa_signal_value_t value);\n\n  void OrAcqRel(hsa_signal_value_t value);\n\n  void XorRelaxed(hsa_signal_value_t value);\n\n  void XorAcquire(hsa_signal_value_t value);\n\n  void XorRelease(hsa_signal_value_t value);\n\n  void XorAcqRel(hsa_signal_value_t value);\n\n  void AddRelaxed(hsa_signal_value_t value);\n\n  void AddAcquire(hsa_signal_value_t value);\n\n  void AddRelease(hsa_signal_value_t value);\n\n  void AddAcqRel(hsa_signal_value_t value);\n\n  void SubRelaxed(hsa_signal_value_t value);\n\n  void SubAcquire(hsa_signal_value_t value);\n\n  void SubRelease(hsa_signal_value_t value);\n\n  void SubAcqRel(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchRelaxed(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchAcquire(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchRelease(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchAcqRel(hsa_signal_value_t value);\n\n  hsa_signal_value_t CasRelaxed(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasAcquire(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasRelease(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasAcqRel(hsa_signal_value_t expected,\n                               hsa_signal_value_t value);\n\n  /// @brief see the base class Signal\n  __forceinline hsa_signal_value_t* ValueLocation() const {\n    return (hsa_signal_value_t*)&signal_.value;\n  }\n\n  /// @brief see the base class Signal\n  __forceinline HsaEvent* EopEvent() { return NULL; }\n\n protected:\n  bool _IsA(rtti_t id) const { return id == &rtti_id(); }\n\n private:\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n\n  DISALLOW_COPY_AND_ASSIGN(BusyWaitSignal);\n};\n\n/// @brief Simple memory only signal using a new ABI block.\nclass DefaultSignal : private LocalSignal, public BusyWaitSignal {\n public:\n  /// @brief Determines if a Signal* can be safely converted to BusyWaitSignal*\n  /// via static_cast.\n  static __forceinline bool IsType(Signal* ptr) { return ptr->IsType(&rtti_id()); }\n\n  /// @brief See base class Signal.\n  explicit DefaultSignal(hsa_signal_value_t initial_value, bool enableIPC = false)\n      : LocalSignal(initial_value, enableIPC), BusyWaitSignal(signal(), enableIPC) {}\n\n protected:\n  bool _IsA(rtti_t id) const {\n    if (id == &rtti_id()) return true;\n    return BusyWaitSignal::_IsA(id);\n  }\n\n private:\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n\n  DISALLOW_COPY_AND_ASSIGN(DefaultSignal);\n};\n\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/driver.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_DRIVER_H_\n#define HSA_RUNTME_CORE_INC_DRIVER_H_\n\n#include <cstdint>\n#include <limits>\n#include <string>\n\n#include \"core/inc/memory_region.h\"\n#include \"hsakmt/hsakmttypes.h\"\n#include \"inc/hsa.h\"\n\nnamespace rocr {\nnamespace core {\n\nclass Queue;\n\nenum class DriverQuery { GET_DRIVER_VERSION };\n\nenum class DriverType {\n  XDNA = 0,\n  KFD,\n#ifdef HSAKMT_VIRTIO_ENABLED\n  KFD_VIRTIO,\n#endif\n  NUM_DRIVER_TYPES\n};\n\n/// @brief Handle for exported / imported memory.\nstruct ShareableHandle {\n  uint64_t handle{};\n\n  bool IsValid() const { return handle != 0; }\n};\n\n/// @brief Kernel driver interface.\n///\n/// @details A class used to provide an interface between the core runtime\n/// and agent kernel drivers. It also maintains state associated with active\n/// kernel drivers.\nclass Driver {\npublic:\n  Driver(DriverType kernel_driver_type, std::string devnode_name);\n  virtual ~Driver() = default;\n\n  /// @brief Initialize the driver's state after opening.\n  virtual hsa_status_t Init() = 0;\n\n  /// @brief Release the driver's resources and close the kernel-mode\n  /// driver.\n  virtual hsa_status_t ShutDown() = 0;\n\n  /// @brief Get driver version information.\n  /// @retval DriverVersionInfo containing the driver's version information.\n  const HsaVersionInfo& Version() const { return version_; }\n\n  /// @brief Query the kernel-model driver.\n  /// @retval HSA_STATUS_SUCCESS if the kernel-model driver query was\n  /// successful.\n  virtual hsa_status_t QueryKernelModeDriver(DriverQuery query) = 0;\n\n  /// @brief Open a connection to the driver using name_.\n  /// @retval HSA_STATUS_SUCCESS if the driver was opened successfully.\n  virtual hsa_status_t Open() = 0;\n\n  /// @brief Close a connection to the open driver using fd_.\n  /// @retval HSA_STATUS_SUCCESS if the driver was opened successfully.\n  virtual hsa_status_t Close() = 0;\n\n  /// @brief Get the system properties for nodes managed by this driver.\n  virtual hsa_status_t GetSystemProperties(HsaSystemProperties& sys_props) const = 0;\n\n  /// @brief Get the properties for a specific node managed by this driver.\n  virtual hsa_status_t GetNodeProperties(HsaNodeProperties& node_props, uint32_t node_id) const = 0;\n\n  /// @brief Get the edge (IO link) properties of a specific node (that is\n  /// managed by this driver) in the topology graph.\n  /// @param[out] io_link_props IO link properties of the node specified by @p node_id.\n  /// @param[in] node_id ID of the node whose link properties are being queried.\n  virtual hsa_status_t GetEdgeProperties(std::vector<HsaIoLinkProperties>& io_link_props,\n                                         uint32_t node_id) const = 0;\n\n  /// @brief Get the memory properties of a specific node.\n  /// @param[in] node_id Node ID of the agent.\n  /// @param[out] mem_props Memory properties of the node specified by @p node_id.\n  /// @retval HSA_STATUS_SUCCESS if the driver sucessfully returns the node's\n  /// memory properties.\n  virtual hsa_status_t GetMemoryProperties(uint32_t node_id,\n                                           std::vector<HsaMemoryProperties>& mem_props) const = 0;\n\n  /// @brief Get the cache properties of a specific node.\n  /// @param[in] node_ide Node ID of the agent.\n  /// @param[out] cache_props Cache properties of the node specified by @p node_id.\n  /// @retval HSA_STATUS_SUCCESS if the driver successfully returns the node's cache properties.\n  virtual hsa_status_t GetCacheProperties(uint32_t node_id, uint32_t processor_id,\n                                          std::vector<HsaCacheProperties>& cache_props) const = 0;\n\n  /// @brief Allocate agent-accessible memory (system or agent-local memory).\n  /// @param[out] mem pointer to newly allocated memory.\n  /// @retval HSA_STATUS_SUCCESS if memory was successfully allocated or\n  /// hsa_status_t error code if the memory allocation failed.\n  virtual hsa_status_t AllocateMemory(const MemoryRegion &mem_region,\n                                      MemoryRegion::AllocateFlags alloc_flags,\n                                      void **mem, size_t size,\n                                      uint32_t node_id) = 0;\n\n  virtual hsa_status_t FreeMemory(void *mem, size_t size) = 0;\n\n  /// @brief Create an agent dispatch queue with user-mode access rights.\n  /// @param[in] node_id Node ID of the agent on which the queue is being created.\n  /// @param[in] type Queue's type.\n  /// @param[in] queue_pct Maximum percentage of a queue's occupancy allowed.\n  /// @param[in] priority Queue's priority for scheduling.\n  /// @param[in] sdma_engine_id ID of the SDMA engine on which the queue is being created. Only used\n  /// if @p type is one of the SDMA queue types.\n  /// @param[in] queue_addr Address of the queue's ring buffer.\n  /// @param[in] queue_size_bytes Size of the queue's ring buffer in bytes.\n  /// @param[in] event HsaEvent for event-driven callbacks.\n  /// @param[out] queue_resource Queue resource information populated by the driver.\n  virtual hsa_status_t CreateQueue(uint32_t node_id, HSA_QUEUE_TYPE type, uint32_t queue_pct,\n                                   HSA_QUEUE_PRIORITY priority, uint32_t sdma_engine_id,\n                                   void* queue_addr, uint64_t queue_size_bytes, HsaEvent* event,\n                                   HsaQueueResource& queue_resource) const = 0;\n\n  /// @brief Destroy a queue.\n  /// @param queue_id Kernel-mode driver's assigned queue ID.\n  virtual hsa_status_t DestroyQueue(HSA_QUEUEID queue_id) const = 0;\n\n  /// @brief Update a queue's properties.\n  /// @param[in] queue_id Kernel-mode driver's assigned queue ID.\n  /// @param[in] queue_pct Maximum percentage of a queue's occupancy allowed.\n  /// @param[in] priority Queue's priority for scheduling.\n  /// @param[in] queue_addr Queue's ring buffer base address.\n  /// @param[in] queue_size_bytes Size of the queue's ring buffer in bytes.\n  /// @param[in] event HsaEvent for event-driven callbacks.\n  virtual hsa_status_t UpdateQueue(HSA_QUEUEID queue_id, uint32_t queue_pct,\n                                   HSA_QUEUE_PRIORITY priority, void* queue_addr,\n                                   uint64_t queue_size_bytes, HsaEvent* event) const = 0;\n\n  /// @brief Set the CU mask for a queue.\n  /// @details This sets the CU bitmask for a queue. The CU mask determines which CUs\n  /// a queue's dispatches can target. Currently this is only supported for GPU devices.\n  /// @param[in] queue_id Kernel-mode driver's assigned queue ID.\n  /// @param[in] cu_mask_count Number of CU bits in the mask.\n  /// @param[in] queue_cu_mask New CU mask for the queue.\n  virtual hsa_status_t SetQueueCUMask(HSA_QUEUEID queue_id, uint32_t cu_mask_count,\n                                      uint32_t* queue_cu_mask) const = 0;\n\n  /// @brief Allocate global wave sync (GWS) resource for a queue. This is only supported for GPUs.\n  /// GWS can be used to synchronize wavefronts across the entire GPU device.\n  /// @param[in] queue_id Kernel-mode driver's assigned queue ID.\n  /// @param[in] num_gws Number of GWS slots.\n  /// @param[in] first_gws First GWS slot.\n  virtual hsa_status_t AllocQueueGWS(HSA_QUEUEID queue_id, uint32_t num_gws,\n                                     uint32_t* first_gws) const = 0;\n\n  /// @brief Imports memory using dma-buf.\n  ///\n  /// @param[in] mem virtual address\n  /// @param[in] size memory size in bytes\n  /// @param[out] dmabuf_fd dma-buf file descriptor\n  /// @param[out] offset memory offset in bytes\n  virtual hsa_status_t ExportDMABuf(void *mem, size_t size, int *dmabuf_fd,\n                                    size_t *offset) = 0;\n\n  /// @brief Imports a memory chunk via dma-buf.\n  ///\n  /// @param[in] dmabuf_fd dma-buf file descriptor\n  /// @param[in] agent agent to import the memory for\n  /// @param[out] handle handle to the imported memory\n  virtual hsa_status_t ImportDMABuf(int dmabuf_fd, core::Agent &agent,\n                                    core::ShareableHandle &handle) = 0;\n\n  /// @brief Maps the memory associated with the handle.\n  ///\n  /// @param[in] handle handle to the memory object\n  /// @param[in] mem virtual address associated with the handle\n  /// @param[in] offset memory offset in bytes\n  /// @param[in] size memory size in bytes\n  /// @param[out] perms new permissions\n  virtual hsa_status_t Map(core::ShareableHandle handle, void *mem,\n                           size_t offset, size_t size,\n                           hsa_access_permission_t perms) = 0;\n\n  /// @brief Unmaps the memory associated with the handle.\n  ///\n  /// @param[in] handle handle to the memory object\n  /// @param[in] mem virtual address associated with the handle\n  /// @param[in] offset memory offset in bytes\n  /// @param[in] size memory size in bytes\n  virtual hsa_status_t Unmap(core::ShareableHandle handle, void *mem,\n                             size_t offset, size_t size) = 0;\n\n  /// @brief Releases the object associated with the handle.\n  ///\n  /// @param[in] handle handle of the object to release\n  virtual hsa_status_t\n  ReleaseShareableHandle(core::ShareableHandle &handle) = 0;\n\n  /// @brief Acquire a streaming performance monitor on an agent.\n  /// @param[in] preferred_node_id Node ID of the preferred agent.\n  virtual hsa_status_t SPMAcquire(uint32_t preferred_node_id) const = 0;\n  /// @brief Release a streaming performance monitor on an agent.\n  /// @param[in] preferred_node_id Node ID of the preferred agent.\n  virtual hsa_status_t SPMRelease(uint32_t preferred_node_id) const = 0;\n  /// @brief Setup the destination user-mode buffer for streaming performance monitor data.\n  /// @param[in] preferred_node_id Node ID of the preferred agent.\n  /// @param[in] size_bytes Size of the destination buffer in bytes.\n  /// @param[in, out] timeout Timeout in milliseconds.\n  /// @param[out] size_copied Size of data copied in bytes.\n  /// @param[in] dest_mem_addr Destination address for streaming performance data. Set to NULL to\n  /// stop copy on previous buffer.\n  /// @param[out] is_spm_data_loss Data was lost if true.\n  virtual hsa_status_t SPMSetDestBuffer(uint32_t preferred_node_id, uint32_t size_bytes,\n                                        uint32_t* timeout, uint32_t* size_copied,\n                                        void* dest_mem_addr, bool* is_spm_data_loss) const = 0;\n\n  /// @brief Open anonymous file descriptor to enable events and read SMI events.\n  /// @param[in] node_id Node ID to receive the SMI event from.\n  /// @param[out] fd Anonymous file descriptor.\n  /// @retval HSA_STATUS_ERROR_INVALID_AGENT if the agent's driver doesn't support\n  /// SMI events.\n  virtual hsa_status_t OpenSMI(uint32_t node_id, int* fd) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Sets trap handler and trap buffer to be used for all queues associated\n  /// with the specified NodeId within this process context\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] base Trap handler base address\n  /// @param[in] base_size Trap handler base size\n  /// @param[in] buffer_base Trap buffer base address\n  /// @param[in] buffer_base_size Trap buffer size\n  /// @return HSA_STATUS_SUCCESS if the driver successfully sets the trap handler.\n  virtual hsa_status_t SetTrapHandler(uint32_t node_id, const void* base, uint64_t base_size,\n                                      const void* buffer_base, uint64_t buffer_base_size) const = 0;\n\n  /// @brief Gets the device handle for a specific node.\n  /// @param node_id Node ID of the agent\n  /// @param device_handle Device handle\n  /// @return HSA_STATUS_SUCCESS if the driver successfully returns the device\n  virtual hsa_status_t GetDeviceHandle(uint32_t node_id, void** device_handle) const = 0;\n\n\n  /// @brief Gets clock counters for particular Node\n  /// @param[in] node_id Node ID of the agent\n  /// @param[out] clock_counter Clock counter\n  /// @return HSA_STATUS_SUCCESS if the driver successfully returns the clock\n  virtual hsa_status_t GetClockCounters(uint32_t node_id,\n                                        HsaClockCounters* clock_counter) const = 0;\n\n  /// @brief Get the tile configuration for a specific node.\n  ///\n  /// @param[in] node_id Node ID of the agent\n  /// @param[out] config Pointer to tile configuration\n  /// @return HSA_STATUS_SUCCESS if the driver successfully returns the tile configuration.\n  virtual hsa_status_t GetTileConfig(uint32_t node_id, HsaGpuTileConfig* config) const = 0;\n\n  /// @brief Check if the HSA KMT Model is enabled\n  /// @param[out] enable True if the model is enabled, false otherwise\n  virtual hsa_status_t IsModelEnabled(bool* enable) const = 0;\n\n  /// @brief Gets the wallclock frequency for a specific node.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[out] frequency Pointer to the wallclock frequency\n  /// @return HSA_STATUS_SUCCESS if the wallclock frequency was successfully retrieved, or an error\n  /// code.\n  virtual hsa_status_t GetWallclockFrequency(uint32_t node_id, uint64_t* frequency) const = 0;\n\n  /// @brief Allocates scratch memory for the agent.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] size Size of the scratch memory\n  /// @param[out] mem Pointer to the scratch memory\n  /// @return HSA_STATUS_SUCCESS if scratch memory allocated successfully.\n  virtual hsa_status_t AllocateScratchMemory(uint32_t node_id, uint64_t size, void** mem) const = 0;\n\n  /// @brief Inquires memory available for allocation as a memory buffer\n  /// @param[in] node_id Node ID of the agent\n  /// @param[out] available_size Available memory size in bytes\n  /// @return HSA_STATUS_SUCCESS if the driver successfully returns the available memory size.\n  virtual hsa_status_t AvailableMemory(uint32_t node_id, uint64_t* available_size) const = 0;\n\n  /// @brief Register memory to GPU\n  /// @param[in] ptr Address of memory to be registered\n  /// @param[in] size Size of memory\n  /// @param[in] mem_flags Flags of memory registering\n  /// @return HSA_STATUS_SUCCESS if memory registered successfully.\n  virtual hsa_status_t RegisterMemory(void* ptr, uint64_t size, HsaMemFlags mem_flags) const = 0;\n\n  /// @brief Unregisters with a memory\n  /// @param[in] ptr Pointer of memory\n  /// @return HSA_STATUS_SUCCESS if deregister memory successfully.\n  virtual hsa_status_t DeregisterMemory(void* ptr) const = 0;\n\n  /// @brief Make the memory is resident and can be accessed by GPU\n  /// @param[in] mem address of memory to be made resident\n  /// @param[in] size size of memory\n  /// @param[out] alternate_va alternate virtual address\n  /// @param[in] mem_flags memory flags can be null\n  /// @param[in] num_nodes number of nodes to be used can be 0 if not used\n  /// @param[in] nodes nodes to be used can be null\n  /// @return HSA_STATUS_SUCCESS if the driver successfully makes the memory\n  virtual hsa_status_t MakeMemoryResident(const void* mem, size_t size, uint64_t* alternate_va,\n                                          const HsaMemMapFlags* mem_flags = nullptr,\n                                          uint32_t num_nodes = 0,\n                                          const uint32_t* nodes = nullptr) const = 0;\n\n  /// @brief Releases the residency of the memory\n  /// @param[in] mem address of memory to be made unresident\n  /// @return HSA_STATUS_SUCCESS if the driver successfully makes the memory\n  virtual hsa_status_t MakeMemoryUnresident(const void* mem) const = 0;\n\n  /// @brief Shares memory with another process.\n  /// @param[in] mem Pointer to the memory to be shared.\n  /// @param[in] size Size of the memory to be shared.\n  /// @param[out] share_mem Pointer to the shared memory handle.\n  /// @return HSA_STATUS_SUCCESS if the memory was successfully shared, or an error code.\n  virtual hsa_status_t ShareMemory(void* mem, size_t size, HsaSharedMemoryHandle* share_mem) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Registers a shared memory handle.\n  /// @param[in] share_mem Pointer to the shared memory handle.\n  /// @param[out] mem Pointer to the memory.\n  /// @param[out] size Size of the memory.\n  /// @return HSA_STATUS_SUCCESS if the memory was successfully registered, or an error code.\n  virtual hsa_status_t RegisterSharedHandle(const HsaSharedMemoryHandle* share_mem, void** mem,\n                                            uint64_t* size) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Replaces the ASAN header page with a valid one.\n  /// @param[in] mem Pointer to the memory to be replaced.\n  /// @return HSA_STATUS_SUCCESS if the ASAN header page was successfully replaced, or an error\n  /// code.\n  virtual hsa_status_t ReplaceAsanHeaderPage(void* mem) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Returns the ASAN header page to its original state.\n  /// @param[in] mem Pointer to the memory to be returned.\n  /// @return HSA_STATUS_SUCCESS if the ASAN header page was successfully returned, or an error\n  /// code.\n  virtual hsa_status_t ReturnAsanHeaderPage(void* mem) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Queries the PC sampling capabilities.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] sample_info Pointer to the sample information\n  /// @param[in] sample_info_sz Size of the sample information\n  /// @param[out] sz_needed Size of the sample information needed\n  /// @return HSA_STATUS_SUCCESS if the PC sampling capabilities were successfully queried, or an\n  /// error code.\n  virtual hsa_status_t PcSamplingQueryCapabilities(uint32_t node_id, void* sample_info,\n                                                   uint32_t sample_info_sz,\n                                                   uint32_t* sz_needed) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Creates a PC sampling session.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] sample_info Pointer to the sample information\n  /// @param[out] trace_id Pointer to the trace ID\n  /// @return HSA_STATUS_SUCCESS if the PC sampling session was successfully created, or an error\n  /// code.\n  virtual hsa_status_t PcSamplingCreate(uint32_t node_id, HsaPcSamplingInfo* sample_info,\n                                        uint32_t* trace_id) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Destroys a PC sampling session.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] trace_id Trace ID of the PC sampling session\n  /// @return HSA_STATUS_SUCCESS if the PC sampling session was successfully destroyed, or an error\n  /// code.\n  virtual hsa_status_t PcSamplingDestroy(uint32_t node_id, uint32_t trace_id) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Starts a PC sampling session.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] trace_id Trace ID of the PC sampling session\n  /// @return HSA_STATUS_SUCCESS if the PC sampling session was successfully started, or an error\n  /// code.\n  virtual hsa_status_t PcSamplingStart(uint32_t node_id, uint32_t trace_id) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// @brief Stops a PC sampling session.\n  /// @param[in] node_id Node ID of the agent\n  /// @param[in] trace_id Trace ID of the PC sampling session\n  /// @return HSA_STATUS_SUCCESS if the PC sampling session was successfully stopped, or an error\n  /// code.\n  virtual hsa_status_t PcSamplingStop(uint32_t node_id, uint32_t trace_id) const {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  /// Unique identifier for supported kernel-mode drivers.\n  const DriverType kernel_driver_type_;\n\nprotected:\n HsaVersionInfo version_{std::numeric_limits<uint32_t>::max(),\n                         std::numeric_limits<uint32_t>::max()};\n\n const std::string devnode_name_;\n int fd_ = -1;\n};\n\n} // namespace core\n} // namespace rocr\n\n#endif // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/exceptions.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_EXCEPTIONS_H\n#define HSA_RUNTIME_CORE_INC_EXCEPTIONS_H\n\n#include <exception>\n#include <string>\n\n#include \"core/inc/hsa_internal.h\"\n\nnamespace rocr {\nnamespace AMD {\n\n/// @brief Exception type which carries an error code to return to the user.\nclass hsa_exception : public std::exception {\n public:\n  hsa_exception(hsa_status_t error, const char* description) : err_(error), desc_(description) {}\n  hsa_status_t error_code() const noexcept { return err_; }\n  const char* what() const noexcept override { return desc_.c_str(); }\n\n private:\n  hsa_status_t err_;\n  std::string desc_;\n};\n\n/// @brief Holds and invokes callbacks, capturing any execptions and forwarding those to the user\n/// after unwinding the runtime stack.\ntemplate <class F> class callback_t;\ntemplate <class R, class... Args> class callback_t<R (*)(Args...)> {\n public:\n  typedef R (*func_t)(Args...);\n\n  callback_t() : function(nullptr) {}\n\n  // Should not be marked explicit.\n  callback_t(func_t function_ptr) : function(function_ptr) {}\n  callback_t& operator=(func_t function_ptr) { function = function_ptr; return *this; }\n\n  bool operator==(func_t function_ptr) { return function == function_ptr; }\n  bool operator!=(func_t function_ptr) { return function != function_ptr; }\n\n  // Allows common function pointer idioms, such as if( func != nullptr )...\n  // without allowing silent reversion to the original function pointer type.\n  operator void*() { return reinterpret_cast<void*>(function); }\n\n  R operator()(Args... args) {\n    try {\n      return function(args...);\n    } catch (...) {\n      throw std::nested_exception();\n    }\n  }\n\n private:\n  func_t function;\n};\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_EXCEPTIONS_H\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/host_queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_HOST_QUEUE_H_\n#define HSA_RUNTIME_CORE_INC_HOST_QUEUE_H_\n\n#include \"core/inc/memory_region.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n\nnamespace rocr {\nnamespace core {\nclass HostQueue : public Queue {\n public:\n  static __forceinline bool IsType(core::Queue* queue) { return queue->IsType(&rtti_id()); }\n\n  HostQueue(core::SharedQueue* shared_queue, hsa_region_t region, uint32_t ring_size,\n            hsa_queue_type32_t type, uint32_t features, hsa_signal_t doorbell_signal);\n\n  ~HostQueue();\n\n  hsa_status_t Inactivate() override { return HSA_STATUS_SUCCESS; }\n  hsa_status_t SetPriority(HSA_QUEUE_PRIORITY priority) override {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  uint64_t LoadReadIndexAcquire() override {\n    return atomic::Load(&amd_queue_.read_dispatch_id,\n                        std::memory_order_acquire);\n  }\n\n  uint64_t LoadReadIndexRelaxed() override {\n    return atomic::Load(&amd_queue_.read_dispatch_id,\n                        std::memory_order_relaxed);\n  }\n\n  uint64_t LoadWriteIndexAcquire() override {\n    return atomic::Load(&amd_queue_.write_dispatch_id,\n                        std::memory_order_acquire);\n  }\n\n  uint64_t LoadWriteIndexRelaxed() override {\n    return atomic::Load(&amd_queue_.write_dispatch_id,\n                        std::memory_order_relaxed);\n  }\n\n  void StoreReadIndexRelaxed(uint64_t value) override {\n    atomic::Store(&amd_queue_.read_dispatch_id, value,\n                  std::memory_order_relaxed);\n  }\n\n  void StoreReadIndexRelease(uint64_t value) override {\n    atomic::Store(&amd_queue_.read_dispatch_id, value,\n                  std::memory_order_release);\n  }\n\n  void StoreWriteIndexRelaxed(uint64_t value) override {\n    atomic::Store(&amd_queue_.write_dispatch_id, value,\n                  std::memory_order_relaxed);\n  }\n\n  void StoreWriteIndexRelease(uint64_t value) override {\n    atomic::Store(&amd_queue_.write_dispatch_id, value,\n                  std::memory_order_release);\n  }\n\n  uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                       std::memory_order_acq_rel);\n  }\n\n  uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                       std::memory_order_acquire);\n  }\n\n  uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                       std::memory_order_relaxed);\n  }\n\n  uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                       std::memory_order_release);\n  }\n\n  uint64_t AddWriteIndexAcqRel(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                       std::memory_order_acq_rel);\n  }\n\n  uint64_t AddWriteIndexAcquire(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                       std::memory_order_acquire);\n  }\n\n  uint64_t AddWriteIndexRelaxed(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                       std::memory_order_relaxed);\n  }\n\n  uint64_t AddWriteIndexRelease(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                       std::memory_order_release);\n  }\n\n  hsa_status_t SetCUMasking(uint32_t num_cu_mask_count, const uint32_t* cu_mask) override {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  hsa_status_t GetCUMasking(uint32_t num_cu_mask_count, uint32_t* cu_mask) override {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  void ExecutePM4(uint32_t* cmd_data, size_t cmd_size_b,\n                  hsa_fence_scope_t acquireFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_fence_scope_t releaseFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_signal_t* signal = NULL) override {\n    assert(false && \"HostQueue::ExecutePM4 is unimplemented\");\n  }\n\n  hsa_status_t GetInfo(hsa_queue_info_attribute_t attribute, void* value) override {\n    assert(false && \"HostQueue::GetInfo is unimplemented\");\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  void* operator new(size_t size) {\n    return _aligned_malloc(AlignUp(size, HSA_QUEUE_ALIGN_BYTES), HSA_QUEUE_ALIGN_BYTES);\n  }\n\n  void* operator new(size_t size, void* ptr) { return ptr; }\n\n  void operator delete(void* ptr) { _aligned_free(ptr); }\n\n  void operator delete(void*, void*) {}\n\n protected:\n  bool _IsA(Queue::rtti_t id) const override { return id == &rtti_id(); }\n\n private:\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n  static const size_t kRingAlignment = 256;\n  const uint32_t size_;\n  void* ring_;\n\n  // Host queue id counter, starting from 0x80000000 to avoid overlaping\n  // with aql queue id.\n  static __forceinline std::atomic<uint32_t>& queue_count() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static std::atomic<uint32_t>* queue_count_ = new std::atomic<uint32_t>();\n    return *queue_count_;\n  }\n\n  DISALLOW_COPY_AND_ASSIGN(HostQueue);\n};\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_amd_tool_int.hpp",
    "content": "#ifndef HSA_RUNTIME_INC_HSA_TOOL_HOOK_IMPL_H\n#define HSA_RUNTIME_INC_HSA_TOOL_HOOK_IMPL_H\n\n#include \"inc/hsa_amd_tool.h\"\n#include \"runtime.h\"\n\n// namespace rocr::AMD::tool {  // C++17\nnamespace rocr { namespace AMD { namespace tool {\n\nusing scratch_alloc_flag = hsa_amd_event_scratch_alloc_flag_t;\n\n__forceinline void notify_event_scratch_alloc_start(const hsa_queue_t* queue,\n                                                    scratch_alloc_flag flag, uint64_t dispatch_id);\n\n__forceinline void notify_event_scratch_alloc_end(const hsa_queue_t* queue, scratch_alloc_flag flag,\n                                                  uint64_t dispatch_id, size_t size,\n                                                  size_t num_slots);\n\n__forceinline void notify_event_scratch_free_start(const hsa_queue_t* queue,\n                                                   scratch_alloc_flag flag);\n\n__forceinline void notify_event_scratch_free_end(const hsa_queue_t* queue, scratch_alloc_flag flag);\n\n__forceinline void notify_event_scratch_async_reclaim_start(const hsa_queue_t* queue,\n                                                            scratch_alloc_flag flag);\n\n__forceinline void notify_event_scratch_async_reclaim_end(const hsa_queue_t* queue,\n                                                          scratch_alloc_flag flag);\n\n\n// Impl\n\n__forceinline void notify_event_scratch_alloc_start(const hsa_queue_t* queue,\n                                                    scratch_alloc_flag flags,\n                                                    uint64_t dispatch_id) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_alloc_start_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_alloc_start_t{.kind = HSA_AMD_TOOL_EVENT_SCRATCH_ALLOC_START,\n                                                   .queue = queue,\n                                                   .flags = flags,\n                                                   .dispatch_id = dispatch_id};\n\n  tool_table.hsa_amd_tool_scratch_event_alloc_start_fn(\n      hsa_amd_tool_event_t{.scratch_alloc_start = &event});\n}\n\n__forceinline void notify_event_scratch_alloc_end(const hsa_queue_t* queue,\n                                                  scratch_alloc_flag flags, uint64_t dispatch_id,\n                                                  size_t size, size_t num_slots) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_alloc_end_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_alloc_end_t{\n      .kind = HSA_AMD_TOOL_EVENT_SCRATCH_ALLOC_END,\n      .queue = queue,\n      .flags = flags,\n      .dispatch_id = dispatch_id,\n      .size = size,\n      .num_slots = num_slots,\n  };\n\n  tool_table.hsa_amd_tool_scratch_event_alloc_end_fn(\n      hsa_amd_tool_event_t{.scratch_alloc_end = &event});\n}\n\n__forceinline void notify_event_scratch_free_start(const hsa_queue_t* queue,\n                                                   scratch_alloc_flag flags) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_free_start_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_free_start_t{\n      .kind = HSA_AMD_TOOL_EVENT_SCRATCH_FREE_START,\n      .queue = queue,\n      .flags = flags,\n  };\n\n  tool_table.hsa_amd_tool_scratch_event_free_start_fn(\n      hsa_amd_tool_event_t{.scratch_free_start = &event});\n}\n\n__forceinline void notify_event_scratch_free_end(const hsa_queue_t* queue,\n                                                 scratch_alloc_flag flags) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_free_end_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_free_end_t{\n      .kind = HSA_AMD_TOOL_EVENT_SCRATCH_FREE_END,\n      .queue = queue,\n      .flags = flags,\n  };\n\n  tool_table.hsa_amd_tool_scratch_event_free_end_fn(\n      hsa_amd_tool_event_t{.scratch_free_end = &event});\n}\n\n__forceinline void notify_event_scratch_async_reclaim_start(const hsa_queue_t* queue,\n                                                            scratch_alloc_flag flags) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_async_reclaim_start_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_async_reclaim_start_t{\n      .kind = HSA_AMD_TOOL_EVENT_SCRATCH_ASYNC_RECLAIM_START,\n      .queue = queue,\n      .flags = flags,\n  };\n\n  tool_table.hsa_amd_tool_scratch_event_async_reclaim_start_fn(\n      hsa_amd_tool_event_t{.scratch_async_reclaim_start = &event});\n}\n\n__forceinline void notify_event_scratch_async_reclaim_end(const hsa_queue_t* queue,\n                                                          scratch_alloc_flag flags) {\n  const auto& tool_table = core::hsa_api_table().tools_api;\n  if (!tool_table.hsa_amd_tool_scratch_event_async_reclaim_end_fn) {\n    return;\n  }\n\n  auto event = hsa_amd_event_scratch_async_reclaim_end_t{\n      .kind = HSA_AMD_TOOL_EVENT_SCRATCH_ASYNC_RECLAIM_END,\n      .queue = queue,\n      .flags = flags,\n  };\n\n  tool_table.hsa_amd_tool_scratch_event_async_reclaim_end_fn(\n      hsa_amd_tool_event_t{.scratch_async_reclaim_end = &event});\n}\n\n// }  // namespace rocr::AMD::tool\n}  // namespace rocr\n}  // namespace AMD\n}  // namespace tool\n\n#endif"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_api_trace_int.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_HSA_API_TRACE_INT_H\n#define HSA_RUNTIME_CORE_INC_HSA_API_TRACE_INT_H\n\n#include \"inc/hsa_api_trace.h\"\n#include \"core/inc/hsa_internal.h\"\n\nnamespace rocr {\nnamespace core {\n  struct HsaApiTable {\n\n    static const uint32_t HSA_EXT_FINALIZER_API_TABLE_ID = 0;\n    static const uint32_t HSA_EXT_IMAGE_API_TABLE_ID = 1;\n    static const uint32_t HSA_EXT_AQLPROFILE_API_TABLE_ID = 2;\n    static const uint32_t HSA_EXT_PC_SAMPLING_API_TABLE_ID = 3;\n\n    ::HsaApiTable hsa_api;\n    ::CoreApiTable core_api;\n    ::AmdExtTable amd_ext_api;\n    ::FinalizerExtTable finalizer_api;\n    ::ImageExtTable image_api;\n    ::ToolsApiTable tools_api;\n    ::PcSamplingExtTable pcs_api;\n\n    HsaApiTable();\n    void Init();\n    void UpdateCore();\n    void UpdateAmdExts();\n    void UpdateTools();\n    void CloneExts(void* ptr, uint32_t table_id);\n    void LinkExts(void* ptr, uint32_t table_id);\n    void Reset();\n  };\n\n  extern HsaApiTable& hsa_api_table();\n  extern HsaApiTable& hsa_internal_api_table();\n\n  void LoadInitialHsaApiTable();\n}   //  namespace core\n}   //  namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_ext_amd_impl.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA AMD extension.\n\n#ifndef HSA_RUNTIME_CORE_INC_EXT_AMD_H_\n#define HSA_RUNTIME_CORE_INC_EXT_AMD_H_\n\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"inc/hsa_ext_amd.h\"\n\n// Wrap internal implementation inside AMD namespace\nnamespace rocr {\nnamespace AMD {\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_coherency_get_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t* type);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t type);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_profiling_async_copy_enable(bool enable);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_profiling_get_dispatch_time(\n    hsa_agent_t agent, hsa_signal_t signal,\n    hsa_amd_profiling_dispatch_time_t* time);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_profiling_get_async_copy_time(\n    hsa_signal_t signal, hsa_amd_profiling_async_copy_time_t* time);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent,\n                                                    uint64_t agent_tick,\n                                                    uint64_t* system_tick);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_signal_async_handler(hsa_signal_t signal,\n                                 hsa_signal_condition_t cond,\n                                 hsa_signal_value_t value,\n                                 hsa_amd_signal_handler handler, void* arg);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_async_function(void (*callback)(void* arg), void* arg);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                                           const hsa_agent_t* consumers, uint64_t attributes,\n                                           hsa_signal_t* signal);\n\n// Mirrors Amd Extension Apis\nuint32_t hsa_amd_signal_wait_all(uint32_t signal_count, hsa_signal_t* signals,\n                                 hsa_signal_condition_t* conds, hsa_signal_value_t* values,\n                                 uint64_t timeout_hint, hsa_wait_state_t wait_hint,\n                                 hsa_signal_value_t* satisfying_values);\n\n// Mirrors Amd Extension Apis\nuint32_t\n    hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* signals,\n                            hsa_signal_condition_t* conds,\n                            hsa_signal_value_t* values, uint64_t timeout_hint,\n                            hsa_wait_state_t wait_hint,\n                            hsa_signal_value_t* satisfying_value);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue,\n                                               uint32_t num_cu_mask_count,\n                                               const uint32_t* cu_mask);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_queue_cu_get_mask(const hsa_queue_t* queue, uint32_t num_cu_mask_count,\n                                               uint32_t* cu_mask);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,\n                                 hsa_amd_memory_pool_info_t attribute,\n                                 void* value);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_agent_iterate_memory_pools(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),\n    void* data);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,\n                                 uint32_t flags, void** ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_pool_free(void* ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_async_copy_on_engine(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal,\n                              hsa_amd_sdma_engine_id_t engine_id,\n                              bool force_copy_on_sdma);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_copy_engine_status(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                      uint32_t *engine_ids_mask);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_get_preferred_copy_engine(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                             uint32_t* recommended_ids_mask);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_async_copy_rect(\n    const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,\n    const hsa_dim3_t* src_offset, const hsa_dim3_t* range, hsa_agent_t copy_agent,\n    hsa_amd_copy_direction_t dir, uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n    hsa_signal_t completion_signal);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_agent_memory_pool_get_info(\n    hsa_agent_t agent, hsa_amd_memory_pool_t memory_pool,\n    hsa_amd_agent_memory_pool_info_t attribute, void* value);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,\n                                const uint32_t* flags, const void* ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,\n                                    hsa_amd_memory_pool_t dst_memory_pool,\n                                    bool* result);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_migrate(const void* ptr,\n                                            hsa_amd_memory_pool_t memory_pool,\n                                            uint32_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,\n                                         hsa_agent_t* agents, int num_agent,\n                                         void** agent_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_lock_to_pool(void* host_ptr, size_t size, hsa_agent_t* agents,\n                                                 int num_agent, hsa_amd_memory_pool_t pool,\n                                                 uint32_t flags, void** agent_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_memory_unlock(void* host_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t\n    hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,\n                                        hsa_agent_t* agents,\n                                        int interop_handle,\n                                        uint32_t flags,\n                                        size_t* size,\n                                        void** ptr,\n                                        size_t* metadata_size,\n                                        const void** metadata);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_interop_unmap_buffer(void* ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_pointer_info(const void* ptr, hsa_amd_pointer_info_t* info,\n                                          void* (*alloc)(size_t), uint32_t* num_agents_accessible,\n                                          hsa_agent_t** accessible);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_pointer_info_set_userdata(const void* ptr, void* userdata);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_create(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* handle, size_t len,\n                                               uint32_t num_agents,\n                                               const hsa_agent_t* mapping_agents,\n                                               void** mapped_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_memory_detach(void* mapped_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_signal_create(hsa_signal_t signal, hsa_amd_ipc_signal_t* handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handle,\n                                               hsa_signal_t* signal);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_register_system_event_handler(hsa_amd_system_event_callback_t callback,\n                                                           void* data);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_queue_set_priority(hsa_queue_t* queue,\n                                                hsa_amd_queue_priority_t priority);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_register_deallocation_callback(\n    void* ptr, hsa_amd_deallocation_callback_t callback, void* user_data);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_deregister_deallocation_callback(\n    void* ptr, hsa_amd_deallocation_callback_t callback);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_signal_value_pointer(hsa_signal_t signal,\n                                          volatile hsa_signal_value_t** value_ptr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_attributes_set(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_attributes_get(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_svm_prefetch_async(void* ptr, size_t size, hsa_agent_t agent,\n                                        uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                        hsa_signal_t completion_signal);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_acquire(hsa_agent_t agent);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_release(hsa_agent_t agent);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_spm_set_dest_buffer(hsa_agent_t agent, size_t size, uint32_t* timeout,\n                                                 uint32_t* size_copied, void* dest,\n                                                 bool* is_data_loss);\n\nhsa_status_t HSA_API hsa_amd_portable_export_dmabuf_v2(const void* ptr,\n                  size_t size, int* dmabuf, uint64_t* offset, uint64_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_portable_export_dmabuf(const void* ptr, size_t size, int* dmabuf,\n                                                    uint64_t* offset);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_portable_close_dmabuf(int dmabuf);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_address_reserve(void** ptr, size_t size, uint64_t address,\n                                          uint64_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_address_reserve_align(void** ptr, size_t size, uint64_t address,\n                                          uint64_t alignment, uint64_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_address_free(void* ptr, size_t size);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_handle_create(hsa_amd_memory_pool_t pool, size_t size,\n                                        hsa_amd_memory_type_t type, uint64_t flags,\n                                        hsa_amd_vmem_alloc_handle_t* memory_handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_handle_release(hsa_amd_vmem_alloc_handle_t memory_handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_map(void* va, size_t size, size_t in_offset,\n                              hsa_amd_vmem_alloc_handle_t memory_handle, uint64_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_unmap(void* va, size_t size);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_set_access(void* va, size_t size,\n                                     const hsa_amd_memory_access_desc_t* desc,\n                                     const size_t desc_cnt);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_get_access(void* va, hsa_access_permission_t* flags,\n                                     const hsa_agent_t agent_handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_export_shareable_handle(int* dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t handle,\n                                                  uint64_t flags);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_import_shareable_handle(int dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t* handle);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_retain_alloc_handle(hsa_amd_vmem_alloc_handle_t* allocHandle, void* addr);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_vmem_get_alloc_properties_from_handle(hsa_amd_vmem_alloc_handle_t allocHandle,\n                                                           hsa_amd_memory_pool_t* pool,\n                                                           hsa_amd_memory_type_t* type);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_agent_set_async_scratch_limit(hsa_agent_t agent, size_t threshold);\n\n// Mirrors Amd Extension Apis\nhsa_status_t hsa_amd_queue_get_info(hsa_queue_t* queue, hsa_queue_info_attribute_t attribute,\n                                    void* value);\n\n// Mirrors Amd Extension Apis\nhsa_status_t HSA_API hsa_amd_enable_logging(uint8_t* flags, void* file);\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_ext_interface.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_AMD_EXT_INTERFACE_H_\n#define HSA_RUNTME_CORE_INC_AMD_EXT_INTERFACE_H_\n\n#include <string>\n#include <vector>\n\n#include \"core/inc/hsa_api_trace_int.h\"\n\n#include \"core/util/os.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\nstruct ImageExtTableInternal : public ImageExtTable {\n  decltype(::hsa_amd_image_get_info_max_dim)* hsa_amd_image_get_info_max_dim_fn;\n};\n\nstruct PcSamplingExtTableInternal : public PcSamplingExtTable {};\n\nclass ExtensionEntryPoints {\n public:\n\n  // Table of function pointers for Hsa Extension Image\n  ImageExtTableInternal image_api;\n\n  // Table of function pointers for Hsa vendor PC Sampling\n  PcSamplingExtTableInternal pcs_api;\n\n  // Table of function pointers for Hsa Extension Finalizer\n  FinalizerExtTable finalizer_api;\n\n  ExtensionEntryPoints();\n\n  bool LoadFinalizer(std::string library_name);\n  void Unload();\n\n  // Update Image Api table with handles to implementation\n  bool LoadImage();\n\n  // Reset Api tables to point to null implementations\n  void UnloadImage();\n\n  // Update PC Sampling Api table with handles to implementation\n  void LoadPcSampling();\n\n  // Reset PC Sampling tables to point to null implementations\n  void UnloadPcSampling();\n\n private:\n  typedef void (*Load_t)(const ::HsaApiTable* table);\n  typedef void (*Unload_t)();\n\n  std::vector<os::LibHandle> libs_;\n\n  // Initialize table for HSA Finalizer Extension Api's\n  void InitFinalizerExtTable();\n\n  // Initialize table for HSA Image Extension Api's\n  void InitImageExtTable();\n\n  // Initialize table for HSA PC Sampling Extension Api's\n  void InitPcSamplingExtTable();\n\n  // Initialize Amd Ext table for Api related to Images\n  void InitAmdExtTable();\n\n  // Update Amd Ext table for Api related to Images\n  void UpdateAmdExtTable(decltype(::hsa_amd_image_create)* func_ptr);\n\n  DISALLOW_COPY_AND_ASSIGN(ExtensionEntryPoints);\n};\n}   //  namespace core\n}   //  namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_internal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_HSA_INTERNAL_H\n#define HSA_RUNTIME_CORE_INC_HSA_INTERNAL_H\n\n#include \"inc/hsa.h\"\n\nnamespace rocr {\nnamespace HSA {\n\n  // Define core namespace interfaces - copy of function declarations in hsa.h\n  hsa_status_t hsa_init();\n  hsa_status_t hsa_shut_down();\n  hsa_status_t\n    hsa_system_get_info(hsa_system_info_t attribute, void *value);\n  hsa_status_t hsa_extension_get_name(uint16_t extension, const char** name);\n  hsa_status_t hsa_system_extension_supported(uint16_t extension, uint16_t version_major,\n                                                      uint16_t version_minor, bool* result);\n  hsa_status_t hsa_system_major_extension_supported(uint16_t extension,\n                                                            uint16_t version_major,\n                                                            uint16_t* version_minor, bool* result);\n  hsa_status_t\n    hsa_system_get_extension_table(uint16_t extension, uint16_t version_major,\n    uint16_t version_minor, void *table);\n  hsa_status_t hsa_system_get_major_extension_table(uint16_t extension,\n                                                            uint16_t version_major,\n                                                            size_t table_length, void* table);\n  hsa_status_t\n    hsa_iterate_agents(hsa_status_t (*callback)(hsa_agent_t agent, void *data),\n    void *data);\n  hsa_status_t hsa_agent_get_info(hsa_agent_t agent,\n    hsa_agent_info_t attribute,\n    void *value);\n  hsa_status_t hsa_agent_get_exception_policies(hsa_agent_t agent,\n    hsa_profile_t profile,\n    uint16_t *mask);\n  hsa_status_t hsa_cache_get_info(hsa_cache_t cache, hsa_cache_info_t attribute,\n                                          void* value);\n  hsa_status_t hsa_agent_iterate_caches(\n      hsa_agent_t agent, hsa_status_t (*callback)(hsa_cache_t cache, void* data), void* value);\n  hsa_status_t\n    hsa_agent_extension_supported(uint16_t extension, hsa_agent_t agent,\n    uint16_t version_major,\n    uint16_t version_minor, bool *result);\n  hsa_status_t hsa_agent_major_extension_supported(uint16_t extension, hsa_agent_t agent,\n                                                           uint16_t version_major,\n                                                           uint16_t* version_minor, bool* result);\n  hsa_status_t\n    hsa_queue_create(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t *source,\n    void *data),\n    void *data, uint32_t private_segment_size,\n    uint32_t group_segment_size, hsa_queue_t **queue);\n  hsa_status_t\n    hsa_soft_queue_create(hsa_region_t region, uint32_t size,\n    hsa_queue_type32_t type, uint32_t features,\n    hsa_signal_t completion_signal, hsa_queue_t **queue);\n  hsa_status_t hsa_queue_destroy(hsa_queue_t *queue);\n  hsa_status_t hsa_queue_inactivate(hsa_queue_t *queue);\n  uint64_t hsa_queue_load_read_index_scacquire(const hsa_queue_t* queue);\n  uint64_t hsa_queue_load_read_index_relaxed(const hsa_queue_t *queue);\n  uint64_t hsa_queue_load_write_index_scacquire(const hsa_queue_t* queue);\n  uint64_t hsa_queue_load_write_index_relaxed(const hsa_queue_t *queue);\n  void hsa_queue_store_write_index_relaxed(const hsa_queue_t *queue,\n    uint64_t value);\n  void hsa_queue_store_write_index_screlease(const hsa_queue_t* queue, uint64_t value);\n  uint64_t hsa_queue_cas_write_index_scacq_screl(const hsa_queue_t* queue,\n                                                         uint64_t expected, uint64_t value);\n  uint64_t hsa_queue_cas_write_index_scacquire(const hsa_queue_t* queue, uint64_t expected,\n                                                       uint64_t value);\n  uint64_t hsa_queue_cas_write_index_relaxed(const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n  uint64_t hsa_queue_cas_write_index_screlease(const hsa_queue_t* queue, uint64_t expected,\n                                                       uint64_t value);\n  uint64_t hsa_queue_add_write_index_scacq_screl(const hsa_queue_t* queue, uint64_t value);\n  uint64_t hsa_queue_add_write_index_scacquire(const hsa_queue_t* queue, uint64_t value);\n  uint64_t\n    hsa_queue_add_write_index_relaxed(const hsa_queue_t *queue, uint64_t value);\n  uint64_t hsa_queue_add_write_index_screlease(const hsa_queue_t* queue, uint64_t value);\n  void hsa_queue_store_read_index_relaxed(const hsa_queue_t *queue,\n    uint64_t value);\n  void hsa_queue_store_read_index_screlease(const hsa_queue_t* queue, uint64_t value);\n  hsa_status_t hsa_agent_iterate_regions(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_region_t region, void *data), void *data);\n  hsa_status_t hsa_region_get_info(hsa_region_t region,\n    hsa_region_info_t attribute,\n    void *value);\n  hsa_status_t hsa_memory_register(void *address, size_t size);\n  hsa_status_t hsa_memory_deregister(void *address, size_t size);\n  hsa_status_t\n    hsa_memory_allocate(hsa_region_t region, size_t size, void **ptr);\n  hsa_status_t hsa_memory_free(void *ptr);\n  hsa_status_t hsa_memory_copy(void *dst, const void *src, size_t size);\n  hsa_status_t hsa_memory_assign_agent(void *ptr, hsa_agent_t agent,\n    hsa_access_permission_t access);\n  hsa_status_t\n    hsa_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n    const hsa_agent_t *consumers, hsa_signal_t *signal);\n  hsa_status_t hsa_signal_destroy(hsa_signal_t signal);\n  hsa_signal_value_t hsa_signal_load_relaxed(hsa_signal_t signal);\n  hsa_signal_value_t hsa_signal_load_scacquire(hsa_signal_t signal);\n  void\n    hsa_signal_store_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_store_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_silent_store_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_silent_store_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  hsa_signal_value_t\n    hsa_signal_wait_relaxed(hsa_signal_t signal,\n    hsa_signal_condition_t condition,\n    hsa_signal_value_t compare_value,\n    uint64_t timeout_hint,\n    hsa_wait_state_t wait_expectancy_hint);\n  hsa_signal_value_t hsa_signal_wait_scacquire(hsa_signal_t signal,\n                                                       hsa_signal_condition_t condition,\n                                                       hsa_signal_value_t compare_value,\n                                                       uint64_t timeout_hint,\n                                                       hsa_wait_state_t wait_expectancy_hint);\n  hsa_status_t hsa_signal_group_create(uint32_t num_signals, const hsa_signal_t* signals,\n                                               uint32_t num_consumers, const hsa_agent_t* consumers,\n                                               hsa_signal_group_t* signal_group);\n  hsa_status_t hsa_signal_group_destroy(hsa_signal_group_t signal_group);\n  hsa_status_t hsa_signal_group_wait_any_scacquire(hsa_signal_group_t signal_group,\n                                                           const hsa_signal_condition_t* conditions,\n                                                           const hsa_signal_value_t* compare_values,\n                                                           hsa_wait_state_t wait_state_hint,\n                                                           hsa_signal_t* signal,\n                                                           hsa_signal_value_t* value);\n  hsa_status_t hsa_signal_group_wait_any_relaxed(hsa_signal_group_t signal_group,\n                                                         const hsa_signal_condition_t* conditions,\n                                                         const hsa_signal_value_t* compare_values,\n                                                         hsa_wait_state_t wait_state_hint,\n                                                         hsa_signal_t* signal,\n                                                         hsa_signal_value_t* value);\n  void\n    hsa_signal_and_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_and_scacquire(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_and_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_and_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value);\n  void\n    hsa_signal_or_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_or_scacquire(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_or_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_or_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value);\n  void\n    hsa_signal_xor_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_xor_scacquire(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_xor_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_xor_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value);\n  void\n    hsa_signal_add_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_add_scacquire(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_add_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_add_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value);\n  void\n    hsa_signal_subtract_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_subtract_scacquire(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_subtract_screlease(hsa_signal_t signal, hsa_signal_value_t value);\n  void hsa_signal_subtract_scacq_screl(hsa_signal_t signal, hsa_signal_value_t value);\n  hsa_signal_value_t\n    hsa_signal_exchange_relaxed(hsa_signal_t signal, hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_exchange_scacquire(hsa_signal_t signal,\n                                                           hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_exchange_screlease(hsa_signal_t signal,\n                                                           hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_exchange_scacq_screl(hsa_signal_t signal,\n                                                             hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_cas_relaxed(hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_cas_scacquire(hsa_signal_t signal,\n                                                      hsa_signal_value_t expected,\n                                                      hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_cas_screlease(hsa_signal_t signal,\n                                                      hsa_signal_value_t expected,\n                                                      hsa_signal_value_t value);\n  hsa_signal_value_t hsa_signal_cas_scacq_screl(hsa_signal_t signal,\n                                                        hsa_signal_value_t expected,\n                                                        hsa_signal_value_t value);\n\n  //===--- Instruction Set Architecture -----------------------------------===//\n\n  hsa_status_t hsa_isa_from_name(\n      const char *name,\n      hsa_isa_t *isa);\n  hsa_status_t hsa_agent_iterate_isas(\n      hsa_agent_t agent,\n      hsa_status_t (*callback)(hsa_isa_t isa,\n                               void *data),\n      void *data);\n  /* deprecated */ hsa_status_t hsa_isa_get_info(\n      hsa_isa_t isa,\n      hsa_isa_info_t attribute,\n      uint32_t index,\n      void *value);\n  hsa_status_t hsa_isa_get_info_alt(\n      hsa_isa_t isa,\n      hsa_isa_info_t attribute,\n      void *value);\n  hsa_status_t hsa_isa_get_exception_policies(\n      hsa_isa_t isa,\n      hsa_profile_t profile,\n      uint16_t *mask);\n  hsa_status_t hsa_isa_get_round_method(\n      hsa_isa_t isa,\n      hsa_fp_type_t fp_type,\n      hsa_flush_mode_t flush_mode,\n      hsa_round_method_t *round_method);\n  hsa_status_t hsa_wavefront_get_info(\n      hsa_wavefront_t wavefront,\n      hsa_wavefront_info_t attribute,\n      void *value);\n  hsa_status_t hsa_isa_iterate_wavefronts(\n      hsa_isa_t isa,\n      hsa_status_t (*callback)(hsa_wavefront_t wavefront,\n                               void *data),\n      void *data);\n  /* deprecated */ hsa_status_t hsa_isa_compatible(\n      hsa_isa_t code_object_isa,\n      hsa_isa_t agent_isa,\n      bool *result);\n\n  //===--- Code Objects (deprecated) --------------------------------------===//\n\n  /* deprecated */ hsa_status_t hsa_code_object_serialize(\n      hsa_code_object_t code_object,\n      hsa_status_t (*alloc_callback)(size_t size,\n                                     hsa_callback_data_t data,\n                                     void **address),\n      hsa_callback_data_t callback_data,\n      const char *options,\n      void **serialized_code_object,\n      size_t *serialized_code_object_size);\n  /* deprecated */ hsa_status_t hsa_code_object_deserialize(\n      void *serialized_code_object,\n      size_t serialized_code_object_size,\n      const char *options,\n      hsa_code_object_t *code_object);\n  /* deprecated */ hsa_status_t hsa_code_object_destroy(\n      hsa_code_object_t code_object);\n  /* deprecated */ hsa_status_t hsa_code_object_get_info(\n      hsa_code_object_t code_object,\n      hsa_code_object_info_t attribute,\n      void *value);\n  /* deprecated */ hsa_status_t hsa_code_object_get_symbol(\n      hsa_code_object_t code_object,\n      const char *symbol_name,\n      hsa_code_symbol_t *symbol);\n  /* deprecated */ hsa_status_t hsa_code_object_get_symbol_from_name(\n      hsa_code_object_t code_object,\n      const char *module_name,\n      const char *symbol_name,\n      hsa_code_symbol_t *symbol);\n  /* deprecated */ hsa_status_t hsa_code_symbol_get_info(\n      hsa_code_symbol_t code_symbol,\n      hsa_code_symbol_info_t attribute,\n      void *value);\n  /* deprecated */ hsa_status_t hsa_code_object_iterate_symbols(\n      hsa_code_object_t code_object,\n      hsa_status_t (*callback)(hsa_code_object_t code_object,\n                               hsa_code_symbol_t symbol,\n                               void *data),\n      void *data);\n\n  //===--- Executable -----------------------------------------------------===//\n\n  hsa_status_t hsa_code_object_reader_create_from_file(\n      hsa_file_t file,\n      hsa_code_object_reader_t *code_object_reader);\n  hsa_status_t hsa_code_object_reader_create_from_memory(\n      const void *code_object,\n      size_t size,\n      hsa_code_object_reader_t *code_object_reader);\n  hsa_status_t hsa_code_object_reader_destroy(\n      hsa_code_object_reader_t code_object_reader);\n  /* deprecated */ hsa_status_t hsa_executable_create(\n      hsa_profile_t profile,\n      hsa_executable_state_t executable_state,\n      const char *options,\n      hsa_executable_t *executable);\n  hsa_status_t hsa_executable_create_alt(\n      hsa_profile_t profile,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode,\n      const char *options,\n      hsa_executable_t *executable);\n  hsa_status_t hsa_executable_destroy(\n      hsa_executable_t executable);\n  /* deprecated */ hsa_status_t hsa_executable_load_code_object(\n      hsa_executable_t executable,\n      hsa_agent_t agent,\n      hsa_code_object_t code_object,\n      const char *options);\n  hsa_status_t hsa_executable_load_program_code_object(\n      hsa_executable_t executable,\n      hsa_code_object_reader_t code_object_reader,\n      const char *options,\n      hsa_loaded_code_object_t *loaded_code_object);\n  hsa_status_t hsa_executable_load_agent_code_object(\n      hsa_executable_t executable,\n      hsa_agent_t agent,\n      hsa_code_object_reader_t code_object_reader,\n      const char *options,\n      hsa_loaded_code_object_t *loaded_code_object);\n  hsa_status_t hsa_executable_freeze(\n      hsa_executable_t executable,\n      const char *options);\n  hsa_status_t hsa_executable_get_info(\n      hsa_executable_t executable,\n      hsa_executable_info_t attribute,\n      void *value);\n  hsa_status_t hsa_executable_global_variable_define(\n      hsa_executable_t executable,\n      const char *variable_name,\n      void *address);\n  hsa_status_t hsa_executable_agent_global_variable_define(\n      hsa_executable_t executable,\n      hsa_agent_t agent,\n      const char *variable_name,\n      void *address);\n  hsa_status_t hsa_executable_readonly_variable_define(\n      hsa_executable_t executable,\n      hsa_agent_t agent,\n      const char *variable_name,\n      void *address);\n  hsa_status_t hsa_executable_validate(\n      hsa_executable_t executable,\n      uint32_t *result);\n  hsa_status_t hsa_executable_validate_alt(\n      hsa_executable_t executable,\n      const char *options,\n      uint32_t *result);\n  /* deprecated */ hsa_status_t hsa_executable_get_symbol(\n      hsa_executable_t executable,\n      const char *module_name,\n      const char *symbol_name,\n      hsa_agent_t agent,\n      int32_t call_convention,\n      hsa_executable_symbol_t *symbol);\n  hsa_status_t hsa_executable_get_symbol_by_name(\n      hsa_executable_t executable,\n      const char *symbol_name,\n      const hsa_agent_t *agent,\n      hsa_executable_symbol_t *symbol);\n  hsa_status_t hsa_executable_symbol_get_info(\n      hsa_executable_symbol_t executable_symbol,\n      hsa_executable_symbol_info_t attribute,\n      void *value);\n  /* deprecated */ hsa_status_t hsa_executable_iterate_symbols(\n      hsa_executable_t executable,\n      hsa_status_t (*callback)(hsa_executable_t executable,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data);\n  hsa_status_t hsa_executable_iterate_agent_symbols(\n      hsa_executable_t executable,\n      hsa_agent_t agent,\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_agent_t agent,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data);\n  hsa_status_t hsa_executable_iterate_program_symbols(\n      hsa_executable_t executable,\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data);\n  hsa_status_t hsa_get_tile_config(hsa_agent_t agent_handle, void* config);\n\n  //===--- Runtime Notifications ------------------------------------------===//\n\n  hsa_status_t hsa_status_string(\n      hsa_status_t status,\n      const char **status_string);\n\n}   //  namespace HSA\n}   //  namespace rocr\n\n#ifdef BUILDING_HSA_CORE_RUNTIME\n//This using declaration is deliberate!\n//We want unqualified name resolution to fail when building the runtime.  This is a guard against accidental use of the intercept layer in the runtime.\n//using namespace rocr::HSA;\n#endif\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_table_interface.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef RUNTIME_HSA_RUNTIME_CORE_INC_HSA_TABLE_INTERFACE_H_\n#define RUNTIME_HSA_RUNTIME_CORE_INC_HSA_TABLE_INTERFACE_H_\n\n#include \"inc/hsa_api_trace.h\"\n\nvoid hsa_table_interface_init(const HsaApiTable* apiTable);\n\nconst HsaApiTable* hsa_table_interface_get_table();\n\n#endif // RUNTIME_HSA_RUNTIME_CORE_INC_HSA_TABLE_INTERFACE_H_"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/hsa_ven_amd_loader_impl.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2020-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n#ifndef HSA_RUNTME_CORE_INC_HSA_VEN_AMD_LOADER_IMPL_H_\n#define HSA_RUNTME_CORE_INC_HSA_VEN_AMD_LOADER_IMPL_H_\n\n#include \"inc/hsa_ven_amd_loader.h\"\n\nnamespace rocr {\n\n  hsa_status_t hsa_ven_amd_loader_query_host_address(\n    const void *device_address,\n    const void **host_address);\n\n  hsa_status_t hsa_ven_amd_loader_query_segment_descriptors(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors);\n\n  hsa_status_t hsa_ven_amd_loader_query_executable(\n    const void *device_address,\n    hsa_executable_t *executable);\n\n  hsa_status_t hsa_ven_amd_loader_executable_iterate_loaded_code_objects(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(\n    hsa_executable_t executable,\n    hsa_loaded_code_object_t loaded_code_object,\n    void *data),\n    void *data);\n\n  hsa_status_t hsa_ven_amd_loader_loaded_code_object_get_info(\n    hsa_loaded_code_object_t loaded_code_object,\n    hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n    void *value);\n\n  hsa_status_t\n    hsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size(\n    hsa_file_t file,\n    size_t offset,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader);\n\n  hsa_status_t\n    hsa_ven_amd_loader_iterate_executables(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      void *data),\n    void *data);\n}  // namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/intercept_queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_INTERCEPT_QUEUE_H_\n#define HSA_RUNTIME_CORE_INC_INTERCEPT_QUEUE_H_\n\n#include <vector>\n#include <memory>\n#include <utility>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/exceptions.h\"\n#include \"core/util/locks.h\"\n\nnamespace rocr {\nnamespace core {\n\n// @brief Generic container to forward Queue interfaces into Queue* member.\n// Class only has utility as a base type customized Queue wrappers.\nclass QueueWrapper : public Queue {\n public:\n  std::unique_ptr<Queue> wrapped;\n\n  explicit QueueWrapper(std::unique_ptr<Queue> queue)\n      : Queue(static_cast<core::SharedQueue*>(core::Runtime::runtime_singleton_->system_allocator()(\n                  sizeof(core::SharedQueue), 4096, 0, 0)),\n              0),\n        wrapped(std::move(queue)) {\n    memcpy(&amd_queue_, &wrapped->amd_queue_, sizeof(amd_queue_));\n    wrapped->set_public_handle(wrapped.get(), public_handle_);\n  }\n\n  ~QueueWrapper() {\n    if (shared_queue_) core::Runtime::runtime_singleton_->system_deallocator()(shared_queue_);\n  }\n\n  hsa_status_t Inactivate() override { return wrapped->Inactivate(); }\n  hsa_status_t SetPriority(HSA_QUEUE_PRIORITY priority) override {\n    return wrapped->SetPriority(priority);\n  }\n  uint64_t LoadReadIndexAcquire() override { return wrapped->LoadReadIndexAcquire(); }\n  uint64_t LoadReadIndexRelaxed() override { return wrapped->LoadReadIndexRelaxed(); }\n  uint64_t LoadWriteIndexRelaxed() override { return wrapped->LoadWriteIndexRelaxed(); }\n  uint64_t LoadWriteIndexAcquire() override { return wrapped->LoadWriteIndexAcquire(); }\n  void StoreReadIndexRelaxed(uint64_t value) override {\n    return wrapped->StoreReadIndexRelaxed(value);\n  }\n  void StoreReadIndexRelease(uint64_t value) override {\n    return wrapped->StoreReadIndexRelease(value);\n  }\n  void StoreWriteIndexRelaxed(uint64_t value) override {\n    return wrapped->StoreWriteIndexRelaxed(value);\n  }\n  void StoreWriteIndexRelease(uint64_t value) override {\n    return wrapped->StoreWriteIndexRelease(value);\n  }\n  uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) override {\n    return wrapped->CasWriteIndexAcqRel(expected, value);\n  }\n  uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) override {\n    return wrapped->CasWriteIndexAcquire(expected, value);\n  }\n  uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) override {\n    return wrapped->CasWriteIndexRelaxed(expected, value);\n  }\n  uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) override {\n    return wrapped->CasWriteIndexRelease(expected, value);\n  }\n  uint64_t AddWriteIndexAcqRel(uint64_t value) override {\n    return wrapped->AddWriteIndexAcqRel(value);\n  }\n  uint64_t AddWriteIndexAcquire(uint64_t value) override {\n    return wrapped->AddWriteIndexAcquire(value);\n  }\n  uint64_t AddWriteIndexRelaxed(uint64_t value) override {\n    return wrapped->AddWriteIndexRelaxed(value);\n  }\n  uint64_t AddWriteIndexRelease(uint64_t value) override {\n    return wrapped->AddWriteIndexRelease(value);\n  }\n  hsa_status_t SetCUMasking(uint32_t num_cu_mask_count, const uint32_t* cu_mask) override {\n    return wrapped->SetCUMasking(num_cu_mask_count, cu_mask);\n  }\n  hsa_status_t GetCUMasking(uint32_t num_cu_mask_count, uint32_t* cu_mask) override {\n    return wrapped->GetCUMasking(num_cu_mask_count, cu_mask);\n  }\n  void ExecutePM4(uint32_t* cmd_data, size_t cmd_size_b,\n                  hsa_fence_scope_t acquireFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_fence_scope_t releaseFence = HSA_FENCE_SCOPE_NONE,\n                  hsa_signal_t* signal = NULL) override {\n    wrapped->ExecutePM4(cmd_data, cmd_size_b, acquireFence, releaseFence, signal);\n  }\n  void SetProfiling(bool enabled) override { wrapped->SetProfiling(enabled); }\n\n protected:\n  void do_set_public_handle(hsa_queue_t* handle) override {\n    public_handle_ = handle;\n    wrapped->set_public_handle(wrapped.get(), handle);\n  }\n};\n\n// @brief Generic container for a proxy queue.\n// Presents an proxy packet buffer and doorbell signal for an underlying Queue.  Write index\n// operations act on the proxy buffer while all other operations pass through to the underlying\n// queue.\nclass QueueProxy : public QueueWrapper {\n public:\n  explicit QueueProxy(std::unique_ptr<Queue> queue) : QueueWrapper(std::move(queue)) {}\n\n  uint64_t LoadReadIndexAcquire() override {\n    return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_acquire);\n  }\n  uint64_t LoadReadIndexRelaxed() override {\n    return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_relaxed);\n  }\n  void StoreReadIndexRelaxed(uint64_t value) override { assert(false); }\n  void StoreReadIndexRelease(uint64_t value) override { assert(false); }\n\n  uint64_t LoadWriteIndexRelaxed() override {\n    return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_relaxed);\n  }\n  uint64_t LoadWriteIndexAcquire() override {\n    return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_acquire);\n  }\n  void StoreWriteIndexRelaxed(uint64_t value) override {\n    atomic::Store(&amd_queue_.write_dispatch_id, value, std::memory_order_relaxed);\n  }\n  void StoreWriteIndexRelease(uint64_t value) override {\n    atomic::Store(&amd_queue_.write_dispatch_id, value, std::memory_order_release);\n  }\n  uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected, std::memory_order_acq_rel);\n  }\n  uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected, std::memory_order_acquire);\n  }\n  uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected, std::memory_order_relaxed);\n  }\n  uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) override {\n    return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected, std::memory_order_release);\n  }\n  uint64_t AddWriteIndexAcqRel(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value, std::memory_order_acq_rel);\n  }\n  uint64_t AddWriteIndexAcquire(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value, std::memory_order_acquire);\n  }\n  uint64_t AddWriteIndexRelaxed(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value, std::memory_order_relaxed);\n  }\n  uint64_t AddWriteIndexRelease(uint64_t value) override {\n    return atomic::Add(&amd_queue_.write_dispatch_id, value, std::memory_order_release);\n  }\n};\n\n// @brief Provides packet intercept and rewrite capability for a queue.\n// Host-side dispatches are processed during doorbell ring.\n// Device-side dispatches are processed as an asynchronous signal event.\nclass InterceptQueue : public QueueProxy, private LocalSignal, public DoorbellSignal {\n public:\n  explicit InterceptQueue(std::unique_ptr<Queue> queue);\n  ~InterceptQueue();\n\n  void AddInterceptor(hsa_amd_queue_intercept_handler interceptor, void* data) {\n    assert(interceptor != nullptr && \"Packet intercept callback was nullptr.\");\n    interceptors.push_back(std::make_pair(interceptor, data));\n  }\n\n  hsa_status_t Inactivate() override {\n    active_ = false;\n    return wrapped->Inactivate();\n  }\n\n private:\n  // Serialize packet interception processing.\n  KernelMutex lock_;\n\n  // Largest processed packet index.\n  uint64_t next_packet_;\n\n  // Post interception packet overflow buffer\n  std::vector<AqlPacket> overflow_;\n\n  // Index at which async intercept processing was scheduled.\n  uint64_t retry_index_;\n\n  // Given the current value of the wrapped queue read index, determine if\n  // there is a retry barrier packet already in the wrapped queue.\n  bool IsPendingRetryPoint(uint64_t wrapped_current_read_index) const;\n\n  // Event signal to use for async packet processing and control flag.\n  Signal* async_doorbell_;\n  std::atomic<bool> quit_;\n\n  // Indicates queue active/inactive state.\n  std::atomic<bool> active_;\n\n  // Proxy packet buffer\n  SharedArray<AqlPacket, 4096> buffer_;\n\n  // Packet transform callbacks\n  std::vector<std::pair<AMD::callback_t<hsa_amd_queue_intercept_handler>, void*>> interceptors;\n\n  static const hsa_signal_value_t DOORBELL_MAX = 0xFFFFFFFFFFFFFFFFull;\n\n  static bool HandleAsyncDoorbell(hsa_signal_value_t value, void* arg);\n  static void PacketWriter(const void* pkts, uint64_t pkt_count);\n\n  // Submit packets to the wrapped queue and return number of packets that were\n  // submitted.\n  uint64_t Submit(const AqlPacket* packets, uint64_t count);\n\n  // Used as the final packet rewriter that submits the packets to the wrapped\n  // queue.\n  static void Submit(const void* pkts, uint64_t pkt_count, uint64_t user_pkt_index, void* data,\n                     hsa_amd_queue_intercept_packet_writer writer);\n\n  /*\n   * Remaining Queue and Signal interface definitions.\n   */\n public:\n  /// @brief Update signal value using Relaxed semantics\n  ///\n  /// @param value Value of signal to update with\n  void StoreRelaxed(hsa_signal_value_t value) override;\n\n  /// @brief Update signal value using Release semantics\n  ///\n  /// @param value Value of signal to update with\n  void StoreRelease(hsa_signal_value_t value) override {\n    std::atomic_thread_fence(std::memory_order_release);\n    StoreRelaxed(value);\n  }\n\n  /// @brief Provide information about the queue\n  hsa_status_t GetInfo(hsa_queue_info_attribute_t attribute, void* value) override;\n\n  static __forceinline bool IsType(core::Signal* signal) { return signal->IsType(&rtti_id()); }\n  static __forceinline bool IsType(core::Queue* queue) { return queue->IsType(&rtti_id()); }\n\n protected:\n  bool _IsA(Queue::rtti_t id) const override { return id == &rtti_id(); }\n\n private:\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n};\n\n}  // namespace core\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_INTERCEPT_QUEUE_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/interrupt_signal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_INTERRUPT_SIGNAL_H_\n#define HSA_RUNTME_CORE_INC_INTERRUPT_SIGNAL_H_\n\n#include <memory>\n#include <vector>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/inc/signal.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\n\n/// @brief A Signal implementation using interrupts versus plain memory based.\n/// Also see base class Signal.\n///\n/// Breaks common/vendor separation - signals in general needs to be re-worked\n/// at the foundation level to make sense in a multi-device system.\n/// Supports only one waiter for now.\n/// KFD changes are needed to support multiple waiters and have device\n/// signaling.\nclass InterruptSignal : private LocalSignal, public Signal {\n public:\n  class EventPool {\n   public:\n    struct Deleter {\n      void operator()(HsaEvent* evt) { InterruptSignal::DestroyEvent(evt); }\n    };\n    using unique_event_ptr = ::std::unique_ptr<HsaEvent, Deleter>;\n\n    EventPool() : allEventsAllocated(false) {}\n\n    HsaEvent* alloc();\n    void free(HsaEvent* evt);\n    void clear() {\n      events_.clear();\n      allEventsAllocated = false;\n    }\n\n   private:\n    HybridMutex lock_;\n    std::vector<unique_event_ptr> events_;\n    bool allEventsAllocated;\n  };\n\n  static HsaEvent* CreateEvent(HSA_EVENTTYPE type, bool manual_reset);\n  static void DestroyEvent(HsaEvent* evt);\n\n  /// @brief Determines if a Signal* can be safely converted to an\n  /// InterruptSignal* via static_cast.\n  static __forceinline bool IsType(Signal* ptr) {\n    return ptr->IsType(&rtti_id());\n  }\n\n  explicit InterruptSignal(hsa_signal_value_t initial_value,\n                           HsaEvent* use_event = NULL);\n\n  ~InterruptSignal();\n\n  // Below are various methods corresponding to the APIs, which load/store the\n  // signal value or modify the existing signal value automically and with\n  // specified memory ordering semantics.\n\n  hsa_signal_value_t LoadRelaxed();\n\n  hsa_signal_value_t LoadAcquire();\n\n  void StoreRelaxed(hsa_signal_value_t value);\n\n  void StoreRelease(hsa_signal_value_t value);\n\n  hsa_signal_value_t WaitRelaxed(hsa_signal_condition_t condition,\n                                 hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint);\n\n  hsa_signal_value_t WaitAcquire(hsa_signal_condition_t condition,\n                                 hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint);\n\n  void AndRelaxed(hsa_signal_value_t value);\n\n  void AndAcquire(hsa_signal_value_t value);\n\n  void AndRelease(hsa_signal_value_t value);\n\n  void AndAcqRel(hsa_signal_value_t value);\n\n  void OrRelaxed(hsa_signal_value_t value);\n\n  void OrAcquire(hsa_signal_value_t value);\n\n  void OrRelease(hsa_signal_value_t value);\n\n  void OrAcqRel(hsa_signal_value_t value);\n\n  void XorRelaxed(hsa_signal_value_t value);\n\n  void XorAcquire(hsa_signal_value_t value);\n\n  void XorRelease(hsa_signal_value_t value);\n\n  void XorAcqRel(hsa_signal_value_t value);\n\n  void AddRelaxed(hsa_signal_value_t value);\n\n  void AddAcquire(hsa_signal_value_t value);\n\n  void AddRelease(hsa_signal_value_t value);\n\n  void AddAcqRel(hsa_signal_value_t value);\n\n  void SubRelaxed(hsa_signal_value_t value);\n\n  void SubAcquire(hsa_signal_value_t value);\n\n  void SubRelease(hsa_signal_value_t value);\n\n  void SubAcqRel(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchRelaxed(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchAcquire(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchRelease(hsa_signal_value_t value);\n\n  hsa_signal_value_t ExchAcqRel(hsa_signal_value_t value);\n\n  hsa_signal_value_t CasRelaxed(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasAcquire(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasRelease(hsa_signal_value_t expected,\n                                hsa_signal_value_t value);\n\n  hsa_signal_value_t CasAcqRel(hsa_signal_value_t expected,\n                               hsa_signal_value_t value);\n\n  /// @brief See base class Signal.\n  __forceinline hsa_signal_value_t* ValueLocation() const {\n    return (hsa_signal_value_t*)&signal_.value;\n  }\n\n  /// @brief See base class Signal.\n  __forceinline HsaEvent* EopEvent() { return event_; }\n\n protected:\n  bool _IsA(rtti_t id) const { return id == &rtti_id(); }\n\n private:\n  /// @variable KFD event on which the interrupt signal is based on.\n  HsaEvent* event_;\n\n  /// @variable Indicates whether the signal should release the event when it\n  /// closes or not.\n  bool free_event_;\n\n  /// Used to obtain a globally unique value (address) for rtti.\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n    return rtti_id_;\n  }\n\n  void SetEvent();\n\n  DISALLOW_COPY_AND_ASSIGN(InterruptSignal);\n};\n\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/ipc_signal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_IPC_SIGNAL_H_\n#define HSA_RUNTME_CORE_INC_IPC_SIGNAL_H_\n\n#include <atomic>\n#include <utility>\n\n#include \"core/inc/signal.h\"\n#include \"core/inc/default_signal.h\"\n#include \"core/util/locks.h\"\n\nnamespace rocr {\nnamespace core {\n\n/// @brief Container for ipc shared memory.\nclass SharedMemory {\n public:\n  SharedMemory(const hsa_amd_ipc_memory_t* handle, size_t len);\n  ~SharedMemory();\n  SharedMemory(SharedMemory&&);\n\n  void* ptr() const { return ptr_; }\n\n private:\n  void* ptr_;\n};\n\n/// @brief Container for ipc signal abi block.\nclass SharedMemorySignal {\n public:\n  explicit SharedMemorySignal(const hsa_amd_ipc_memory_t* handle) : signal_(handle, 4096) {\n    if (!signal()->IsValid())\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"IPC Signal handle is invalid.\");\n  }\n  SharedSignal* signal() const { return reinterpret_cast<SharedSignal*>(signal_.ptr()); }\n\n private:\n  SharedMemory signal_;\n};\n\n/// @brief Memory only signal using a shared memory ABI block.\nclass IPCSignal : private SharedMemorySignal, public BusyWaitSignal {\n public:\n  /// @brief Creates a sharable handle for an IPC enabled signal.\n  static void CreateHandle(Signal* signal, hsa_amd_ipc_signal_t* ipc_handle);\n\n  /// @brief Opens an IPC signal from its IPC handle.\n  static Signal* Attach(const hsa_amd_ipc_signal_t* ipc_handle);\n\n  /// @brief Determines if a Signal* can be safely converted to BusyWaitSignal*\n  /// via static_cast.\n  static __forceinline bool IsType(Signal* ptr) { return ptr->IsType(&rtti_id()); }\n\n protected:\n  bool _IsA(rtti_t id) const {\n    if (id == &rtti_id()) return true;\n    return BusyWaitSignal::_IsA(id);\n  }\n\n private:\n  static __forceinline int& rtti_id() {\n    static int rtti_id_ = 0;\n      return rtti_id_;\n  }\n  static KernelMutex lock_;\n\n  explicit IPCSignal(SharedMemorySignal&& abi_block)\n      : SharedMemorySignal(std::move(abi_block)), BusyWaitSignal(signal(), true) {}\n\n  DISALLOW_COPY_AND_ASSIGN(IPCSignal);\n};\n\n}  // namespace core\n}  // namespace rocr\n\n#endif  // HSA_RUNTME_CORE_INC_IPC_SIGNAL_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/isa.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_ISA_H_\n#define HSA_RUNTIME_CORE_ISA_H_\n\n#include <cassert>\n#include <cstdint>\n#include <string>\n#include <tuple>\n#include <unordered_map>\n#include \"core/inc/amd_hsa_code.hpp\"\n\nnamespace rocr {\nnamespace core {\n\n/// @class Wavefront.\n/// @brief Wavefront.\nclass Wavefront final: public amd::hsa::common::Signed<0xA02483F1AD7F101C> {\npublic:\n  /// @brief Default destructor.\n  ~Wavefront() {}\n\n  /// @returns Handle equivalent of @p object.\n  static hsa_wavefront_t Handle(const Wavefront *object) {\n    hsa_wavefront_t handle = { reinterpret_cast<uint64_t>(object) };\n    return handle;\n  }\n\n  /// @returns Object equivalent of @p handle.\n  static Wavefront *Object(const hsa_wavefront_t &handle) {\n    Wavefront *object = amd::hsa::common::ObjectAt<Wavefront>(handle.handle);\n    return object;\n  }\n\n  /// @brief Query value of requested @p attribute and record it in @p value.\n  bool GetInfo(const hsa_wavefront_info_t &attribute, void *value) const;\n\nprivate:\n  uint32_t num_threads_;\n  /// @brief Default constructor.\n  Wavefront() : num_threads_(0) {}\n  Wavefront(uint32_t num_threads) : num_threads_(num_threads) {}\n\n  /// @brief Wavefront's friends.\n  friend class Isa;\n  friend class IsaRegistry;\n};\n\nenum class IsaFeature : uint8_t {\n  Unsupported,\n  Any,\n  Disabled,\n  Enabled,\n};\n\n/// @class Isa.\n/// @brief Instruction Set Architecture.\nclass Isa final: public amd::hsa::common::Signed<0xB13594F2BD8F212D> {\n public:\n  /// @brief Isa's version type.\n  typedef std::tuple<int32_t, int32_t, int32_t> Version;\n\n  /// @brief Default destructor.\n  ~Isa() = default;\n\n  /// @returns Handle equivalent of @p isa_object.\n  static hsa_isa_t Handle(const Isa *isa_object) {\n    hsa_isa_t isa_handle = { reinterpret_cast<uint64_t>(isa_object) };\n    return isa_handle;\n  }\n\n  /// @returns Object equivalent of @p isa_handle.\n  static Isa *Object(const hsa_isa_t &isa_handle) {\n    Isa *isa_object = amd::hsa::common::ObjectAt<Isa>(isa_handle.handle);\n    return isa_object;\n  }\n\n  /// @returns True if @p code_object_isa and @p agent_isa are compatible,\n  /// false otherwise.\n  static bool IsCompatible(const Isa &code_object_isa,\n                      const Isa &agent_isa, unsigned int codeGenericVersion);\n\n  /// @returns This Isa's version.\n  const Version &GetVersion() const {\n    return version_;\n  }\n  /// @returns This Isa's generic target.\n  const std::string & GetIsaGeneric() const {return generic_;}\n\n\n  /// @returns SRAM ECC feature status.\n  IsaFeature GetSramecc() const {\n    return sramecc_;\n  }\n\n  /// @returns XNACK feature status.\n  IsaFeature GetXnack() const {\n    return xnack_;\n  }\n\n  /// @returns This Isa's supported wavefront.\n  const Wavefront &GetWavefront() const {\n    return wavefront_;\n  }\n\n  /// @returns True if SRAMECC feature is supported, false otherwise.\n  bool IsSrameccSupported() const {\n    return sramecc_ != IsaFeature::Unsupported;\n  }\n\n  /// @returns True if XNACK feature is supported, false otherwise.\n  bool IsXnackSupported() const {\n    return xnack_ != IsaFeature::Unsupported;\n  }\n\n  /// @returns This Isa's major version.\n  int32_t GetMajorVersion() const {\n    return std::get<0>(version_);\n  }\n\n  /// @returns This Isa's minor version.\n  int32_t GetMinorVersion() const {\n    return std::get<1>(version_);\n  }\n\n  /// @returns This Isa's stepping.\n  int32_t GetStepping() const {\n    return std::get<2>(version_);\n  }\n\n  /// @brief Isa is always in valid state.\n  bool IsValid() const {\n    return true;\n  }\n\n  /// @returns This Isa's processor name.\n  std::string GetProcessorName() const;\n\n  /// @returns This Isa's name consisting of the target triple and target ID.\n  std::string GetIsaName() const;\n\n  /// @brief Query value of requested @p attribute and record it in @p value.\n  bool GetInfo(const hsa_isa_info_t &attribute, void *value) const;\n\n  /// @returns Round method (single or double) used to implement the floating-\n  /// point multiply add instruction (mad) for a given combination of @p fp_type\n  /// and @p flush_mode.\n  hsa_round_method_t GetRoundMethod(\n      hsa_fp_type_t fp_type,\n      hsa_flush_mode_t flush_mode) const;\n\n  /// @brief Default constructor.\n  Isa()\n      : version_(Version(-1, -1, -1)),\n        sramecc_(IsaFeature::Unsupported),\n        xnack_(IsaFeature::Unsupported) {}\n  private:\n\n  // @brief Isa's target ID name.\n  std::string targetid_;\n\n  // @brief Isa's generic version, if it exists. \"\" otherwise.\n  std::string generic_;\n\n  /// @brief Isa's version.\n  Version version_;\n\n  /// @brief SRAMECC feature.\n  IsaFeature sramecc_;\n\n  /// @brief XNACK feature.\n  IsaFeature xnack_;\n\n  /// @brief Isa's supported wavefront.\n  Wavefront wavefront_;\n\n  /// @brief Isa's friends.\n  friend class IsaRegistry;\n}; // class Isa\n\n/// @class IsaRegistry.\n/// @brief Instruction Set Architecture Registry.\nclass IsaRegistry final {\n public:\n  /// @returns Isa for requested @p full_name, null pointer if not supported.\n  static const Isa *GetIsa(const std::string &full_name);\n\n  /// @returns Isa for requested @p version, null pointer if not supported.\n  static const Isa *GetIsa(const Isa::Version &version,\n                           IsaFeature sramecc = IsaFeature::Any,\n                           IsaFeature xnack = IsaFeature::Any);\n  static const std::unordered_map<std::string, unsigned int> &\n                                                GetSupportedGenericVersions();\n private:\n  /// @brief IsaRegistry's map type.\n  typedef std::unordered_map<std::string, Isa> IsaMap;\n\n  /// @brief  Default constructor\n  IsaRegistry() = delete;\n\n  /// @brief Default destructor\n  ~IsaRegistry() = default;\n\n  /// @returns Supported instruction set architectures.\n  static const IsaMap& GetSupportedIsas();\n}; // class IsaRegistry\n\n} // namespace core\n} // namespace rocr\n\n#endif // HSA_RUNTIME_CORE_ISA_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/memory_region.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_MEMORY_REGION_H_\n#define HSA_RUNTME_CORE_INC_MEMORY_REGION_H_\n\n#include <vector>\n\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/checked.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\nclass Agent;\n\nclass MemoryRegion : public Checked<0x9C961F19EE175BB3> {\n public:\n  MemoryRegion(bool fine_grain, bool kernarg, bool full_profile, bool extended_scope_fine_grain,\n               bool user_visible, core::Agent* owner)\n      : fine_grain_(fine_grain),\n        kernarg_(kernarg),\n        full_profile_(full_profile),\n        extended_scope_fine_grain_(extended_scope_fine_grain),\n        user_visible_(user_visible),\n        owner_(owner) {\n    assert(owner_ != NULL);\n  }\n\n  virtual ~MemoryRegion() {}\n\n  // Convert this object into hsa_region_t.\n  static __forceinline hsa_region_t Convert(MemoryRegion* region) {\n    const hsa_region_t region_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(region))};\n    return region_handle;\n  }\n\n  static __forceinline const hsa_region_t Convert(const MemoryRegion* region) {\n    const hsa_region_t region_handle = {\n        static_cast<uint64_t>(reinterpret_cast<uintptr_t>(region))};\n    return region_handle;\n  }\n\n  // Convert hsa_region_t into MemoryRegion *.\n  static __forceinline MemoryRegion* Convert(hsa_region_t region) {\n    return reinterpret_cast<MemoryRegion*>(region.handle);\n  }\n\n  enum AllocateEnum {\n    AllocateNoFlags = 0,\n    AllocateRestrict = (1 << 0),    // Don't map system memory to GPU agents\n    AllocateExecutable = (1 << 1),  // Set executable permission\n    AllocateDoubleMap = (1 << 2),   // Deprecated:Map twice VA allocation to backing store\n    AllocateDirect = (1 << 3),      // Bypass fragment cache.\n    AllocateIPC = (1 << 4),         // System memory that can be IPC-shared\n    AllocateNonPaged = (1 << 4),    // Non-paged system memory (AllocateIPC alias)\n    AllocatePCIeRW = (1 << 5),      // Enforce pseudo fine grain/RW memory\n    AllocateAsan = (1 << 6),        // ASAN - First page of allocation remapped to system memory\n    AllocatePinned = (1 << 7),      // Currently treating Pinned memory as NoSubstitute\n    AllocateMemoryOnly = (1 << 8),  // Memory only handle from thunk, no virtual address\n    // Flag to allocate system memory with GTT Access\n    // Note: The node_id needs to be the node_id of the device even though this is allocating\n    // system memory\n    AllocateGTTAccess = (1 << 9),\n    AllocateContiguous = (1 << 10), // Physically contiguous memory\n    AllocateUncached = (1 << 11),   // Uncached memory\n    // this flag is ignored by Thunk and only used for emulator/dxg to track code-object\n    // allocations in AQL to PM4 conversion.\n    AllocateExecutableBlitKernelObject = (1 << 12),\n  };\n\n  typedef uint32_t AllocateFlags;\n\n  virtual hsa_status_t Allocate(size_t& size, AllocateFlags alloc_flags, void** address, int agent_node_id) const = 0;\n\n  virtual hsa_status_t Free(void* address, size_t size) const = 0;\n\n  // Prepares suballocated memory for IPC export.\n  virtual hsa_status_t IPCFragmentExport(void* address) const = 0;\n\n  // Translate memory properties into HSA region attribute.\n  virtual hsa_status_t GetInfo(hsa_region_info_t attribute,\n                               void* value) const = 0;\n\n  virtual hsa_status_t AssignAgent(void* ptr, size_t size, const Agent& agent,\n                                   hsa_access_permission_t access) const = 0;\n\n  // Releases any cached memory that may be held within the allocator.\n  virtual void Trim() const {}\n\n  __forceinline bool fine_grain() const { return fine_grain_; }\n\n  __forceinline bool extended_scope_fine_grain() const { return extended_scope_fine_grain_; }\n\n  __forceinline bool kernarg() const { return kernarg_; }\n\n  __forceinline bool full_profile() const { return full_profile_; }\n\n  __forceinline bool user_visible() const { return user_visible_; }\n\n  __forceinline core::Agent* owner() const { return owner_; }\n\n private:\n  const bool fine_grain_;\n  const bool kernarg_;\n  const bool full_profile_;\n  const bool extended_scope_fine_grain_;\n  const bool user_visible_;\n\n  core::Agent* owner_;\n};\n}  // namespace core\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_COMMAND_QUEUE_H_\n#define HSA_RUNTME_CORE_INC_COMMAND_QUEUE_H_\n\n#include <sstream>\n\n#include \"core/common/shared.h\"\n#include \"core/inc/checked.h\"\n#include \"core/inc/memory_region.h\"\n#include \"core/util/utils.h\"\n#include \"inc/amd_hsa_queue.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"hsakmt/hsakmt.h\"\n\nnamespace rocr {\nnamespace core {\nstruct AqlPacket {\n\n  union {\n    struct {\n      uint16_t header;\n      struct {\n        uint8_t user_data[62];\n      } body;\n     } packet;\n    struct {\n      uint16_t header;\n      uint8_t format;\n      uint8_t rest[61];\n    } amd_vendor;\n    hsa_kernel_dispatch_packet_t dispatch;\n    hsa_barrier_and_packet_t barrier_and;\n    hsa_barrier_or_packet_t barrier_or;\n    hsa_agent_dispatch_packet_t agent;\n  };\n\n  // Access the type field from a packet header. The caller is responsible for\n  // loading the header using an atomic or ordinary load as appropriate.\n  static uint8_t type(uint16_t header) {\n    return ((header >> HSA_PACKET_HEADER_TYPE) & ((1 << HSA_PACKET_HEADER_WIDTH_TYPE) - 1));\n  }\n\n  // Determine if a packet is valid. The caller is responsible for loading the\n  // header using an atomic or ordinary load as appropriate.\n  static bool IsValid(uint16_t header) {\n    return ((type(header) <= HSA_PACKET_TYPE_BARRIER_OR) &&\n            (type(header) != HSA_PACKET_TYPE_INVALID));\n  }\n\n  bool __forceinline IsDispatchAndNeedsScratch() const {\n    assert(IsValid(packet.header) && \"Invalid packet in dynamic scratch handler.\");\n\n    if (type(packet.header) != HSA_PACKET_TYPE_KERNEL_DISPATCH ||\n        dispatch.private_segment_size == 0)\n      return false;\n\n    assert((dispatch.workgroup_size_x != 0) && (dispatch.workgroup_size_y != 0) &&\n           (dispatch.workgroup_size_z != 0) && \"Invalid dispatch dimension.\");\n\n    return true;\n  }\n\n  std::string string() const {\n    std::stringstream string;\n    uint8_t t = type(packet.header);\n\n    static const char* type_names[] = {\n        \"HSA_PACKET_TYPE_VENDOR_SPECIFIC\", \"HSA_PACKET_TYPE_INVALID\",\n        \"HSA_PACKET_TYPE_KERNEL_DISPATCH\", \"HSA_PACKET_TYPE_BARRIER_AND\",\n        \"HSA_PACKET_TYPE_AGENT_DISPATCH\",  \"HSA_PACKET_TYPE_BARRIER_OR\"};\n\n    if (t >= sizeof(type_names) / sizeof(const char*)) {\n      string << \"type: UNKNOWN#\" << t;\n      return string.str();\n    }\n\n    string << \"type: \" << type_names[t]\n           << \"\\nbarrier: \" << ((dispatch.header >> HSA_PACKET_HEADER_BARRIER) &\n                                ((1 << HSA_PACKET_HEADER_WIDTH_BARRIER) - 1))\n           << \"\\nacquire: \" << ((dispatch.header >> HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) &\n                                ((1 << HSA_PACKET_HEADER_WIDTH_SCACQUIRE_FENCE_SCOPE) - 1))\n           << \"\\nrelease: \" << ((dispatch.header >> HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE) &\n                                ((1 << HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE) - 1));\n\n    if (t == HSA_PACKET_TYPE_KERNEL_DISPATCH) {\n      string << \"\\nDim: \" << dispatch.setup\n             << \"\\nworkgroup_size: \" << dispatch.workgroup_size_x << \", \"\n             << dispatch.workgroup_size_y << \", \" << dispatch.workgroup_size_z\n             << \"\\ngrid_size: \" << dispatch.grid_size_x << \", \"\n             << dispatch.grid_size_y << \", \" << dispatch.grid_size_z\n             << \"\\nprivate_size: \" << dispatch.private_segment_size\n             << \"\\ngroup_size: \" << dispatch.group_segment_size\n             << \"\\nkernel_object: \" << dispatch.kernel_object\n             << \"\\nkern_arg: \" << dispatch.kernarg_address\n             << \"\\nsignal: \" << dispatch.completion_signal.handle;\n    }\n\n    if ((t == HSA_PACKET_TYPE_BARRIER_AND) ||\n        (t == HSA_PACKET_TYPE_BARRIER_OR)) {\n      for (int i = 0; i < 5; i++)\n        string << \"\\ndep[\" << i << \"]: \" << barrier_and.dep_signal[i].handle;\n      string << \"\\nsignal: \" << barrier_and.completion_signal.handle;\n    }\n\n    return string.str();\n  }\n};\n\nclass Queue;\n\n/// @brief Helper structure to simplify conversion of amd_queue_v2_t and\n/// core::Queue object.\nstruct SharedQueue {\n  amd_queue_v2_t amd_queue;\n  Queue* core_queue;\n};\n\n/// @brief Class Queue which encapsulate user mode queues and\n/// provides Api to access its Read, Write indices using Acquire,\n/// Release and Relaxed semantics.\n/*\nQueue is intended to be an pure interface class and may be wrapped or replaced\nby tools.\nAll funtions other than Convert and public_handle must be virtual.\n*/\nclass Queue : public Checked<0xFA3906A679F9DB49> {\n public:\n  Queue(SharedQueue* shared_queue, uint64_t queue_flags)\n      : Queue(shared_queue, queue_flags, false) {}\n\n  Queue(SharedQueue* shared_queue, uint64_t queue_flags, bool pcie_write_ordering)\n      : amd_queue_(shared_queue->amd_queue),\n        shared_queue_(shared_queue),\n        flags_(queue_flags),\n        pcie_write_ordering_(pcie_write_ordering) {\n    public_handle_ = Convert(this);\n    shared_queue->core_queue = this;\n  }\n\n  virtual ~Queue() {}\n\n  virtual void Destroy() { delete this; }\n\n  /// @brief Returns the handle of Queue's public data type\n  ///\n  /// @param queue Pointer to an instance of Queue implementation object\n  ///\n  /// @return hsa_queue_t * Pointer to the public data type of a queue\n  static __forceinline hsa_queue_t* Convert(Queue* queue) {\n    return (queue != nullptr) ? &queue->amd_queue_.hsa_queue : nullptr;\n  }\n\n  /// @brief Transform the public data type of a Queue's data type into an\n  //  instance of it Queue class object\n  ///\n  /// @param queue Handle of public data type of a queue\n  ///\n  /// @return Queue * Pointer to the Queue's implementation object\n  static __forceinline Queue* Convert(const hsa_queue_t* queue) {\n    return (queue != nullptr)\n        ? reinterpret_cast<SharedQueue*>(reinterpret_cast<uintptr_t>(queue) -\n                                         offsetof(SharedQueue, amd_queue.hsa_queue))->core_queue\n        : nullptr;\n  }\n\n  /// @brief Inactivate the queue object. Once inactivate a\n  /// queue cannot be used anymore and must be destroyed\n  ///\n  /// @return hsa_status_t Status of request\n  virtual hsa_status_t Inactivate() = 0;\n\n  /// @brief Change the scheduling priority of the queue\n  virtual hsa_status_t SetPriority(HSA_QUEUE_PRIORITY priority) = 0;\n\n  /// @brief Reads the Read Index of Queue using Acquire semantics\n  ///\n  /// @return uint64_t Value of Read index\n  virtual uint64_t LoadReadIndexAcquire() = 0;\n\n  /// @brief Reads the Read Index of Queue using Relaxed semantics\n  ///\n  /// @return uint64_t Value of Read index\n  virtual uint64_t LoadReadIndexRelaxed() = 0;\n\n  /// @brief Reads the Write Index of Queue using Acquire semantics\n  ///\n  /// @return uint64_t Value of Write index\n  virtual uint64_t LoadWriteIndexAcquire() = 0;\n\n  /// Reads the Write Index of Queue using Relaxed semantics\n  ///\n  /// @return uint64_t Value of Write index\n  virtual uint64_t LoadWriteIndexRelaxed() = 0;\n\n  /// @brief Updates the Read Index of Queue using Relaxed semantics\n  ///\n  /// @param value New value of Read index to update\n  virtual void StoreReadIndexRelaxed(uint64_t value) = 0;\n\n  /// @brief Updates the Read Index of Queue using Release semantics\n  ///\n  /// @param value New value of Read index to update\n  virtual void StoreReadIndexRelease(uint64_t value) = 0;\n\n  /// @brief Updates the Write Index of Queue using Relaxed semantics\n  ///\n  /// @param value New value of Write index to update\n  virtual void StoreWriteIndexRelaxed(uint64_t value) = 0;\n\n  /// @brief Updates the Write Index of Queue using Release semantics\n  ///\n  /// @param value New value of Write index to update\n  virtual void StoreWriteIndexRelease(uint64_t value) = 0;\n\n  /// @brief Compares and swaps Write index using Acquire and Release semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t CasWriteIndexAcqRel(uint64_t expected, uint64_t value) = 0;\n\n  /// @brief Compares and swaps Write index using Acquire semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t CasWriteIndexAcquire(uint64_t expected, uint64_t value) = 0;\n\n  /// @brief Compares and swaps Write index using Relaxed semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t CasWriteIndexRelaxed(uint64_t expected, uint64_t value) = 0;\n\n  /// @brief Compares and swaps Write index using Release semantics\n  ///\n  /// @param expected Current value of write index\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t CasWriteIndexRelease(uint64_t expected, uint64_t value) = 0;\n\n  /// @brief Updates the Write index using Acquire and Release semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t AddWriteIndexAcqRel(uint64_t value) = 0;\n\n  /// @brief Updates the Write index using Acquire semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t AddWriteIndexAcquire(uint64_t value) = 0;\n\n  /// @brief Updates the Write index using Relaxed semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t AddWriteIndexRelaxed(uint64_t value) = 0;\n\n  /// @brief Updates the Write index using Release semantics\n  ///\n  /// @param value Value of new write index\n  ///\n  /// @return uint64_t Value of write index before the update\n  virtual uint64_t AddWriteIndexRelease(uint64_t value) = 0;\n\n  /// @brief Set CU Masking\n  ///\n  /// @param num_cu_mask_count size of mask bit array\n  ///\n  /// @param cu_mask pointer to cu mask\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t SetCUMasking(uint32_t num_cu_mask_count, const uint32_t* cu_mask) = 0;\n\n  /// @brief Get CU Masking\n  ///\n  /// @param num_cu_mask_count size of mask bit array\n  ///\n  /// @param cu_mask pointer to cu mask\n  ///\n  /// @return hsa_status_t\n  virtual hsa_status_t GetCUMasking(uint32_t num_cu_mask_count, uint32_t* cu_mask) = 0;\n\n  /// @brief Submits a block of PM4.\n  ///\n  /// @param cmd_data pointer to command buffer\n  ///\n  /// @param cmd_size_b command buffer size in bytes\n  ///\n  /// @param acquireFence acquire-fence type\n  ///\n  /// @param releaseFence acquire-fence type\n  ///\n  /// @param signal optional wait signal\n  ///\n  /// if @p signal is provided, function will return without waiting for commands to be executed\n  /// if @p signal is NULL, waits until commands have been executed.\n  virtual void ExecutePM4(uint32_t* cmd_data, size_t cmd_size_b,\n                          hsa_fence_scope_t acquireFence = HSA_FENCE_SCOPE_NONE,\n                          hsa_fence_scope_t releaseFence = HSA_FENCE_SCOPE_NONE,\n                          hsa_signal_t* signal = NULL) = 0;\n\n  virtual void SetProfiling(bool enabled) {\n    AMD_HSA_BITS_SET(amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_ENABLE_PROFILING,\n                     (enabled != 0));\n  }\n\n  /// @ brief Returns queue queries about the queue\n  virtual hsa_status_t GetInfo(hsa_queue_info_attribute_t attribute, void* value) = 0;\n\n  /// @ brief Reports async queue errors to stderr if no other error handler was registered.\n  static void DefaultErrorHandler(hsa_status_t status, hsa_queue_t* source, void* data);\n\n  // Handle of AMD Queue struct\n  amd_queue_v2_t& amd_queue_;\n\n  hsa_queue_t* public_handle() const { return public_handle_; }\n\n  typedef void* rtti_t;\n\n  bool IsType(rtti_t id) { return _IsA(id); }\n\n  /// @brief Used to determine if the queue's packet buffer was allocated\n  /// in the agent's local device memory.\n  bool IsDeviceMemRingBuf() const {\n    return (flags_ & HSA_AMD_QUEUE_CREATE_DEVICE_MEM_RING_BUF) != 0;\n  }\n  /// @brief Used to determine if the queue descriptor was allocated in\n  /// the agent's local device memory.\n  bool IsDeviceMemQueueDescriptor() const {\n    return (flags_ & HSA_AMD_QUEUE_CREATE_DEVICE_MEM_QUEUE_DESCRIPTOR) != 0;\n  }\n\n  bool needsPcieOrdering() const { return pcie_write_ordering_; }\n\n protected:\n  static void set_public_handle(Queue* ptr, hsa_queue_t* handle) {\n    ptr->do_set_public_handle(handle);\n  }\n  virtual void do_set_public_handle(hsa_queue_t* handle) {\n    public_handle_ = handle;\n  }\n\n  virtual bool _IsA(rtti_t id) const = 0;\n\n  SharedQueue* shared_queue_;\n\n  hsa_queue_t* public_handle_;\n\n  /// Next available queue id.\n  uint64_t GetQueueId() { return hsa_queue_counter_++; }\n\n private:\n\n  // HSA Queue ID - used to bind a unique ID\n  static std::atomic<uint64_t> hsa_queue_counter_;\n\n  const uint64_t flags_;\n  bool pcie_write_ordering_ = false;\n\n  DISALLOW_COPY_AND_ASSIGN(Queue);\n};\n}   //  namespace core\n}   //  namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/registers.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// This file is used only for open source cmake builds, if we hardcode the\n// register values in amd_aql_queue.cpp then this file won't be required. For\n// now we are using this file where register details are  spelled out in the\n// structs/unions below.\n#ifndef HSA_RUNTME_CORE_INC_REGISTERS_H_\n#define HSA_RUNTME_CORE_INC_REGISTERS_H_\n\ntypedef enum SQ_RSRC_BUF_TYPE {\nSQ_RSRC_BUF                              = 0x00000000,\nSQ_RSRC_BUF_RSVD_1                       = 0x00000001,\nSQ_RSRC_BUF_RSVD_2                       = 0x00000002,\nSQ_RSRC_BUF_RSVD_3                       = 0x00000003,\n} SQ_RSRC_BUF_TYPE;\n\ntypedef enum BUF_DATA_FORMAT {\nBUF_DATA_FORMAT_INVALID                  = 0x00000000,\nBUF_DATA_FORMAT_8                        = 0x00000001,\nBUF_DATA_FORMAT_16                       = 0x00000002,\nBUF_DATA_FORMAT_8_8                      = 0x00000003,\nBUF_DATA_FORMAT_32                       = 0x00000004,\nBUF_DATA_FORMAT_16_16                    = 0x00000005,\nBUF_DATA_FORMAT_10_11_11                 = 0x00000006,\nBUF_DATA_FORMAT_11_11_10                 = 0x00000007,\nBUF_DATA_FORMAT_10_10_10_2               = 0x00000008,\nBUF_DATA_FORMAT_2_10_10_10               = 0x00000009,\nBUF_DATA_FORMAT_8_8_8_8                  = 0x0000000a,\nBUF_DATA_FORMAT_32_32                    = 0x0000000b,\nBUF_DATA_FORMAT_16_16_16_16              = 0x0000000c,\nBUF_DATA_FORMAT_32_32_32                 = 0x0000000d,\nBUF_DATA_FORMAT_32_32_32_32              = 0x0000000e,\nBUF_DATA_FORMAT_RESERVED_15              = 0x0000000f,\n} BUF_DATA_FORMAT;\n\ntypedef enum BUF_NUM_FORMAT {\nBUF_NUM_FORMAT_UNORM                     = 0x00000000,\nBUF_NUM_FORMAT_SNORM                     = 0x00000001,\nBUF_NUM_FORMAT_USCALED                   = 0x00000002,\nBUF_NUM_FORMAT_SSCALED                   = 0x00000003,\nBUF_NUM_FORMAT_UINT                      = 0x00000004,\nBUF_NUM_FORMAT_SINT                      = 0x00000005,\nBUF_NUM_FORMAT_SNORM_OGL__SI__CI         = 0x00000006,\nBUF_NUM_FORMAT_RESERVED_6__VI            = 0x00000006,\nBUF_NUM_FORMAT_FLOAT                     = 0x00000007,\n} BUF_NUM_FORMAT;\n\ntypedef enum BUF_FORMAT {\nBUF_FORMAT_32_UINT                       = 0x00000014,\n} BUF_FORMAT;\n\ntypedef enum SQ_SEL_XYZW01 {\nSQ_SEL_0                                 = 0x00000000,\nSQ_SEL_1                                 = 0x00000001,\nSQ_SEL_RESERVED_0                        = 0x00000002,\nSQ_SEL_RESERVED_1                        = 0x00000003,\nSQ_SEL_X                                 = 0x00000004,\nSQ_SEL_Y                                 = 0x00000005,\nSQ_SEL_Z                                 = 0x00000006,\nSQ_SEL_W                                 = 0x00000007,\n} SQ_SEL_XYZW01;\n\n\tunion COMPUTE_TMPRING_SIZE {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n\t\tunsigned int                           WAVES : 12;\n\t\tunsigned int                        WAVESIZE : 13;\n\t\tunsigned int                                 : 7;\n#elif\t\tdefined(BIGENDIAN_CPU)\n\t\tunsigned int                                 : 7;\n\t\tunsigned int                        WAVESIZE : 13;\n\t\tunsigned int                           WAVES : 12;\n#endif\n\t} bitfields, bits;\n\tunsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n\t};\n\n        union COMPUTE_TMPRING_SIZE_GFX11 {\n          struct {\n#if defined(LITTLEENDIAN_CPU)\n            unsigned int WAVES : 12;\n            unsigned int WAVESIZE : 15;\n            unsigned int : 5;\n#elif defined(BIGENDIAN_CPU)\n            unsigned int : 5;\n            unsigned int WAVESIZE : 15;\n            unsigned int WAVES : 12;\n#endif\n          } bitfields, bits;\n          unsigned int u32All;\n          signed int i32All;\n          float f32All;\n        };\n\n        union COMPUTE_TMPRING_SIZE_GFX12 {\n          struct {\n#if defined(LITTLEENDIAN_CPU)\n            unsigned int WAVES : 12;\n            unsigned int WAVESIZE : 18;\n            unsigned int : 2;\n#elif defined(BIGENDIAN_CPU)\n            unsigned int : 2;\n            unsigned int WAVESIZE : 18;\n            unsigned int WAVES : 12;\n#endif\n          } bitfields, bits;\n          unsigned int u32All;\n          signed int i32All;\n          float f32All;\n        };\n\n\n        union SQ_BUF_RSRC_WORD0 {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n\t\tunsigned int                    BASE_ADDRESS : 32;\n#elif\t\tdefined(BIGENDIAN_CPU)\n\t\tunsigned int                    BASE_ADDRESS : 32;\n#endif\n\t} bitfields, bits;\n\tunsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n\t};\n\n\n\tunion SQ_BUF_RSRC_WORD1 {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n\t\tunsigned int                 BASE_ADDRESS_HI : 16;\n\t\tunsigned int                          STRIDE : 14;\n\t\tunsigned int                   CACHE_SWIZZLE : 1;\n\t\tunsigned int                  SWIZZLE_ENABLE : 1;\n#elif\t\tdefined(BIGENDIAN_CPU)\n\t\tunsigned int                  SWIZZLE_ENABLE : 1;\n\t\tunsigned int                   CACHE_SWIZZLE : 1;\n\t\tunsigned int                          STRIDE : 14;\n\t\tunsigned int                 BASE_ADDRESS_HI : 16;\n#endif\n\t} bitfields, bits;\n\tunsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n\t};\n\n        union SQ_BUF_RSRC_WORD1_GFX11 {\n          struct {\n#if defined(LITTLEENDIAN_CPU)\n            unsigned int BASE_ADDRESS_HI : 16;\n            unsigned int STRIDE : 14;\n            unsigned int SWIZZLE_ENABLE : 2;\n#elif defined(BIGENDIAN_CPU)\n            unsigned int SWIZZLE_ENABLE : 2;\n            unsigned int STRIDE : 14;\n            unsigned int BASE_ADDRESS_HI : 16;\n#endif\n          } bitfields, bits;\n          unsigned int u32All;\n          signed int i32All;\n          float f32All;\n        };\n\n\n        union SQ_BUF_RSRC_WORD2 {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n\t\tunsigned int                     NUM_RECORDS : 32;\n#elif\t\tdefined(BIGENDIAN_CPU)\n\t\tunsigned int                     NUM_RECORDS : 32;\n#endif\n\t} bitfields, bits;\n\tunsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n\t};\n\n\n\tunion SQ_BUF_RSRC_WORD3 {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n                unsigned int                       DST_SEL_X : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                      NUM_FORMAT : 3;\n                unsigned int                     DATA_FORMAT : 4;\n                unsigned int                    ELEMENT_SIZE : 2;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                     ATC__CI__VI : 1;\n                unsigned int                     HASH_ENABLE : 1;\n                unsigned int                            HEAP : 1;\n                unsigned int                   MTYPE__CI__VI : 3;\n                unsigned int                            TYPE : 2;\n#elif\t\tdefined(BIGENDIAN_CPU)\n                unsigned int                            TYPE : 2;\n                unsigned int                   MTYPE__CI__VI : 3;\n                unsigned int                            HEAP : 1;\n                unsigned int                     HASH_ENABLE : 1;\n                unsigned int                     ATC__CI__VI : 1;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                    ELEMENT_SIZE : 2;\n                unsigned int                     DATA_FORMAT : 4;\n                unsigned int                      NUM_FORMAT : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_X : 3;\n#endif\n\t} bitfields, bits;\n\tunsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n\t};\n\n\tunion SQ_BUF_RSRC_WORD3_GFX10 {\n\tstruct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n                unsigned int                       DST_SEL_X : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                          FORMAT : 7;\n                unsigned int                       RESERVED1 : 2;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                  RESOURCE_LEVEL : 1;\n                unsigned int                       RESERVED2 : 3;\n                unsigned int                      OOB_SELECT : 2;\n                unsigned int                            TYPE : 2;\n#elif\t\tdefined(BIGENDIAN_CPU)\n                unsigned int                            TYPE : 2;\n                unsigned int                      OOB_SELECT : 2;\n                unsigned int                       RESERVED2 : 3;\n                unsigned int                  RESOURCE_LEVEL : 1;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                       RESERVED1 : 2;\n                unsigned int                          FORMAT : 7;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_X : 3;\n#endif\n        } bitfields, bits;\n        unsigned int u32All;\n        signed int i32All;\n        float f32All;\n        };\n\n        // From V# Table\n        union SQ_BUF_RSRC_WORD3_GFX11 {\n          struct {\n#if defined(LITTLEENDIAN_CPU)\n            unsigned int DST_SEL_X : 3;\n            unsigned int DST_SEL_Y : 3;\n            unsigned int DST_SEL_Z : 3;\n            unsigned int DST_SEL_W : 3;\n            unsigned int FORMAT : 6;\n            unsigned int RESERVED1 : 3;\n            unsigned int INDEX_STRIDE : 2;\n            unsigned int ADD_TID_ENABLE : 1;\n            unsigned int RESERVED2 : 4;\n            unsigned int OOB_SELECT : 2;\n            unsigned int TYPE : 2;\n#elif defined(BIGENDIAN_CPU)\n            unsigned int TYPE : 2;\n            unsigned int OOB_SELECT : 2;\n            unsigned int RESERVED2 : 4;\n            unsigned int ADD_TID_ENABLE : 1;\n            unsigned int INDEX_STRIDE : 2;\n            unsigned int RESERVED1 : 3;\n            unsigned int FORMAT : 6;\n            unsigned int DST_SEL_W : 3;\n            unsigned int DST_SEL_Z : 3;\n            unsigned int DST_SEL_Y : 3;\n            unsigned int DST_SEL_X : 3;\n#endif\n          } bitfields, bits;\n        unsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n        };\n\n        // From V# Table\n        union SQ_BUF_RSRC_WORD3_GFX12 {\n          struct {\n#if defined(LITTLEENDIAN_CPU)\n            unsigned int DST_SEL_X : 3;\n            unsigned int DST_SEL_Y : 3;\n            unsigned int DST_SEL_Z : 3;\n            unsigned int DST_SEL_W : 3;\n            unsigned int FORMAT : 6;\n            unsigned int RESERVED1 : 3;\n            unsigned int INDEX_STRIDE : 2;\n            unsigned int ADD_TID_ENABLE : 1;\n            unsigned int WRITE_COMPRESS_ENABLE : 1;\n            unsigned int COMPRESSION_EN : 1;\n            unsigned int COMPRESSION_ACCESS_MODE : 2;\n            unsigned int OOB_SELECT : 2;\n            unsigned int TYPE : 2;\n#elif defined(BIGENDIAN_CPU)\n            unsigned int TYPE : 2;\n            unsigned int OOB_SELECT : 2;\n            unsigned int COMPRESSION_ACCESS_MODE : 2;\n            unsigned int COMPRESSION_EN : 1;\n            unsigned int WRITE_COMPRESS_ENABLE : 1;\n            unsigned int ADD_TID_ENABLE : 1;\n            unsigned int INDEX_STRIDE : 2;\n            unsigned int RESERVED1 : 3;\n            unsigned int FORMAT : 6;\n            unsigned int DST_SEL_W : 3;\n            unsigned int DST_SEL_Z : 3;\n            unsigned int DST_SEL_Y : 3;\n            unsigned int DST_SEL_X : 3;\n#endif\n          } bitfields, bits;\n        unsigned int\tu32All;\n\tsigned int\ti32All;\n\tfloat\tf32All;\n        };\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/runtime.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_RUNTIME_H_\n#define HSA_RUNTME_CORE_INC_RUNTIME_H_\n\n#include <vector>\n#include <map>\n#include <memory>\n#include <tuple>\n#include <utility>\n#include <thread>\n#include <sys/un.h>\n\n#if defined(__linux__)\n#include <xf86drm.h>\n#include <amdgpu.h>\n#endif\n\n#include \"core/inc/hsa_ext_interface.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n\n#include \"core/inc/agent.h\"\n#include \"core/inc/driver.h\"\n#include \"core/inc/exceptions.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/memory_region.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/svm_profiler.h\"\n#include \"core/inc/thunk_loader.h\"\n#include \"core/util/flag.h\"\n#include \"core/util/locks.h\"\n#include \"core/util/os.h\"\n#include \"core/util/utils.h\"\n\n#include \"core/inc/amd_loader_context.hpp\"\n#include \"core/inc/amd_hsa_code.hpp\"\n\n#if defined(__clang__)\n#if __has_feature(address_sanitizer)\n#define SANITIZER_AMDGPU 1\n#endif\n#endif\n\n//---------------------------------------------------------------------------//\n//    Constants                                                              //\n//---------------------------------------------------------------------------//\n\n#define HSA_ARGUMENT_ALIGN_BYTES 16\n#define HSA_QUEUE_ALIGN_BYTES 64\n#define HSA_PACKET_ALIGN_BYTES 64\n#define HSA_MAX_DEP_SIGNALS 5\n\n//Avoids include\nnamespace rocr {\nnamespace AMD {\n  class MemoryRegion;\n} // namespace amd\n\nnamespace core {\nextern bool g_use_interrupt_wait;\nextern bool g_use_mwaitx;\n\n/// @brief  Runtime class provides the following functions:\n/// - open and close connection to kernel driver.\n/// - load supported extension library (image and finalizer).\n/// - load tools library.\n/// - expose supported agents.\n/// - allocate and free memory.\n/// - memory copy and fill.\n/// - grant access to memory (dgpu memory pool extension).\n/// - maintain loader state.\n/// - monitor asynchronous event from agent.\nclass Runtime {\n friend class AMD::MemoryRegion;\n public:\n  /// @brief Structure to describe connectivity between agents.\n  struct LinkInfo {\n    LinkInfo() : num_hop(0), rec_sdma_eng_id_mask(0), info{0} {}\n\n    uint32_t num_hop;\n    uint32_t rec_sdma_eng_id_mask;\n    hsa_amd_memory_pool_link_info_t info;\n  };\n\n  struct KfdVersion_t {\n    HsaVersionInfo version;\n    bool supports_exception_debugging;\n    bool supports_event_age;\n    bool supports_core_dump;\n  };\n\n  /// @brief Open connection to kernel driver and increment reference count.\n  static hsa_status_t Acquire();\n\n  /// @brief Decrement reference count and close connection to kernel driver.\n  static hsa_status_t Release();\n\n  /// @brief Checks if connection to kernel driver is opened.\n  /// @retval True if the connection to kernel driver is opened.\n  static bool IsOpen();\n\n  // @brief Callback handler for HW Exceptions.\n  static bool HwExceptionHandler(hsa_signal_value_t val, void* arg);\n\n  // @brief Callback handler for VM fault access.\n  static bool VMFaultHandler(hsa_signal_value_t val, void* arg);\n\n  // @brief Print known allocations near ptr.\n  static void PrintMemoryMapNear(void* ptr);\n\n  /// @brief Singleton object of the runtime.\n  static Runtime* runtime_singleton_;\n\n  /// @brief Insert agent into agent list ::agents_.\n  /// @param [in] agent Pointer to the agent object.\n  void RegisterAgent(Agent* agent, bool Enabled);\n\n  /// @brief Insert agent into the driver list.\n  /// @param [in] driver Unique pointer to the driver object.\n  void RegisterDriver(std::unique_ptr<Driver> driver);\n\n  /// @brief Delete all agent objects from ::agents_.\n  void DestroyAgents();\n\n  /// @brief Close and delete all agent driver objects from ::agent_drivers_.\n  void DestroyDrivers();\n\n  /// @brief Set the number of links connecting the agents in the platform.\n  void SetLinkCount(size_t num_link);\n\n  /// @brief Register link information connecting @p node_id_from and @p\n  /// node_id_to.\n  /// @param [in] node_id_from Node id of the source node.\n  /// @param [in] node_id_to Node id of the destination node.\n  /// @param [in] link_info The link information between source and destination\n  /// nodes.\n  void RegisterLinkInfo(uint32_t node_id_from, uint32_t node_id_to,\n                        uint32_t num_hop, uint32_t rec_sdma_eng_id_mask,\n                        hsa_amd_memory_pool_link_info_t& link_info);\n\n  /// @brief Query link information between two nodes.\n  /// @param [in] node_id_from Node id of the source node.\n  /// @param [in] node_id_to Node id of the destination node.\n  /// @retval The link information between source and destination nodes.\n  const LinkInfo GetLinkInfo(uint32_t node_id_from, uint32_t node_id_to);\n\n  /// @brief Invoke the user provided call back for each agent in the agent\n  /// list.\n  ///\n  /// @param [in] callback User provided callback function.\n  /// @param [in] data User provided pointer as input for @p callback.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS if the callback function for each traversed\n  /// agent returns ::HSA_STATUS_SUCCESS.\n  hsa_status_t IterateAgent(hsa_status_t (*callback)(hsa_agent_t agent,\n                                                     void* data),\n                            void* data);\n\n  /// @brief Allocate memory on a particular region.\n  ///\n  /// @param [in] region Pointer to region object.\n  /// @param [in] size Allocation size in bytes.\n  /// @param [in] alloc_flags Modifiers to pass to MemoryRegion allocator.\n  /// @param [out] address Pointer to store the allocation result.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS If allocation is successful.\n  hsa_status_t AllocateMemory(const MemoryRegion* region, size_t size,\n                              MemoryRegion::AllocateFlags alloc_flags,\n                              void** address, int agent_node_id = 0);\n\n  /// @brief Free memory previously allocated with AllocateMemory.\n  ///\n  /// @param [in] ptr Address of the memory to be freed.\n  ///\n  /// @retval ::HSA_STATUS_ERROR If @p ptr is not the address of previous\n  /// allocation via ::core::Runtime::AllocateMemory\n  /// @retval ::HSA_STATUS_SUCCESS if @p ptr is successfully released.\n  hsa_status_t FreeMemory(void* ptr);\n\n  hsa_status_t RegisterReleaseNotifier(void* ptr, hsa_amd_deallocation_callback_t callback,\n                                       void* user_data);\n\n  hsa_status_t DeregisterReleaseNotifier(void* ptr, hsa_amd_deallocation_callback_t callback);\n\n  /// @brief Blocking memory copy from src to dst.\n  ///\n  /// @param [in] dst Memory address of the destination.\n  /// @param [in] src Memory address of the source.\n  /// @param [in] size Copy size in bytes.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS if memory copy is successful and completed.\n  hsa_status_t CopyMemory(void* dst, const void* src, size_t size);\n\n  /// @brief Non-blocking memory copy from src to dst.\n  ///\n  /// @details The memory copy will be performed after all signals in\n  /// @p dep_signals have value of 0. On completion @p completion_signal\n  /// will be decremented.\n  ///\n  /// @param [in] dst Memory address of the destination.\n  /// @param [in] dst_agent Agent object associated with the destination. This\n  /// agent should be able to access the destination and source.\n  /// @param [in] src Memory address of the source.\n  /// @param [in] src_agent Agent object associated with the source. This\n  /// agent should be able to access the destination and source.\n  /// @param [in] size Copy size in bytes.\n  /// @param [in] dep_signals Array of signal dependency.\n  /// @param [in] completion_signal Completion signal object.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS if copy command has been submitted\n  /// successfully to the agent DMA queue.\n  hsa_status_t CopyMemory(void* dst, core::Agent* dst_agent, const void* src,\n                          core::Agent* src_agent, size_t size,\n                          std::vector<core::Signal*>& dep_signals, core::Signal& completion_signal);\n\n  /// @brief Non-blocking memory copy from src to dst on engine_id.\n  ///\n  /// @details All semantics and params are dentical to CopyMemory\n  ///  with the exception of engine_id.\n  ///\n  /// @param [in] engine_id Target engine to copy on.\n  ///\n  /// @param [in] force_copy_on_sdma By default, a blit kernel copy is used\n  /// when dst_agent == src_agent.  Setting this to true will force the copy\n  /// over SDMA1.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS if copy command has been submitted\n  /// successfully to the agent DMA queue.\n  hsa_status_t CopyMemoryOnEngine(void* dst, core::Agent* dst_agent, const void* src,\n                          core::Agent* src_agent, size_t size,\n                          std::vector<core::Signal*>& dep_signals, core::Signal& completion_signal,\n                          hsa_amd_sdma_engine_id_t  engine_id, bool force_copy_on_sdma);\n\n  /// @brief Return SDMA availability status for copy direction\n  ///\n  /// @param [in] dst_agent Destination agent.\n  /// @param [in] src_agent Source agent.\n  /// @param [out] engine_ids_mask Mask of engine_ids.\n  ///\n  /// @retval HSA_STATUS_SUCCESS DMA engines are available\n  /// @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES DMA engines are not available\n  hsa_status_t CopyMemoryStatus(core::Agent* dst_agent, core::Agent* src_agent,\n                                uint32_t *engine_ids_mask);\n\n  /// @brief Get preferred SDMA engine for the copy direction\n  ///\n  /// @param [in] dst_agent Destination agent.\n  /// @param [in] src_agent Source agent.\n  /// @param [out] recommended_ids_mask Mask of recommended_ids.\n  ///\n  /// @retval HSA_STATUS_SUCCESS For mask returned\n  hsa_status_t GetPreferredEngine(core::Agent* dst_agent, core::Agent* src_agent,\n                                  uint32_t* recommended_ids_mask);\n\n  /// @brief Fill the first @p count of uint32_t in ptr with value.\n  ///\n  /// @param [in] ptr Memory address to be filled.\n  /// @param [in] value The value/pattern that will be used to set @p ptr.\n  /// @param [in] count Number of uint32_t element to be set.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS if memory fill is successful and completed.\n  hsa_status_t FillMemory(void* ptr, uint32_t value, size_t count);\n\n  /// @brief Set agents as the whitelist to access ptr.\n  ///\n  /// @param [in] num_agents The number of agent handles in @p agents array.\n  /// @param [in] agents Agent handle array.\n  /// @param [in] ptr Pointer of memory previously allocated via\n  /// core::Runtime::AllocateMemory.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS The whitelist has been configured\n  /// successfully and all agents in the @p agents could start accessing @p ptr.\n  hsa_status_t AllowAccess(uint32_t num_agents, const hsa_agent_t* agents,\n                           const void* ptr);\n\n  /// @brief Query system information.\n  ///\n  /// @param [in] attribute System info attribute to query.\n  /// @param [out] value Pointer to store the attribute value.\n  ///\n  /// @retval HSA_STATUS_SUCCESS The attribute is valid and the @p value is\n  /// set.\n  hsa_status_t GetSystemInfo(hsa_system_info_t attribute, void* value);\n\n  /// @brief Register a callback function @p handler that is associated with\n  /// @p signal to asynchronous event monitor thread.\n  ///\n  /// @param [in] signal Signal handle associated with @p handler.\n  /// @param [in] cond The condition to execute the @p handler.\n  /// @param [in] value The value to compare with @p signal value. If the\n  /// comparison satisfy @p cond, the @p handler will be called.\n  /// @param [in] arg Pointer to the argument that will be provided to @p\n  /// handler.\n  ///\n  /// @retval ::HSA_STATUS_SUCCESS Registration is successful.\n  hsa_status_t SetAsyncSignalHandler(hsa_signal_t signal,\n                                     hsa_signal_condition_t cond,\n                                     hsa_signal_value_t value,\n                                     hsa_amd_signal_handler handler, void* arg);\n\n  hsa_status_t InteropMap(uint32_t num_agents, Agent** agents,\n                          int interop_handle, uint32_t flags, size_t* size,\n                          void** ptr, size_t* metadata_size,\n                          const void** metadata);\n\n  hsa_status_t InteropUnmap(void* ptr);\n\n  struct PtrInfoBlockData {\n    void* base;\n    size_t length;\n    core::Agent* agentOwner;\n  };\n\n  hsa_status_t PtrInfo(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),\n                       uint32_t* num_agents_accessible, hsa_agent_t** accessible,\n                       PtrInfoBlockData* block_info = nullptr);\n\n  hsa_status_t SetPtrInfoData(const void* ptr, void* userptr);\n\n  hsa_status_t IPCCreate(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle);\n\n  hsa_status_t IPCAttach(const hsa_amd_ipc_memory_t* handle, size_t len, uint32_t num_agents,\n                         Agent** mapping_agents, void** mapped_ptr);\n\n  hsa_status_t IPCDetach(void* ptr);\n\n  hsa_status_t SetSvmAttrib(void* ptr, size_t size, hsa_amd_svm_attribute_pair_t* attribute_list,\n                            size_t attribute_count);\n\n  hsa_status_t GetSvmAttrib(void* ptr, size_t size, hsa_amd_svm_attribute_pair_t* attribute_list,\n                            size_t attribute_count);\n\n  hsa_status_t SvmPrefetch(void* ptr, size_t size, hsa_agent_t agent, uint32_t num_dep_signals,\n                           const hsa_signal_t* dep_signals, hsa_signal_t completion_signal);\n\n  hsa_status_t DmaBufExport(const void* ptr, size_t size, int* dmabuf,\n                                            uint64_t* offset, uint64_t flags);\n\n  hsa_status_t DmaBufClose(int dmabuf);\n\n  hsa_status_t VMemoryAddressReserve(void** ptr, size_t size, uint64_t address, uint64_t alignment, uint64_t flags);\n\n  hsa_status_t VMemoryAddressFree(void* ptr, size_t size);\n\n  hsa_status_t VMemoryHandleCreate(const MemoryRegion* region, size_t size,\n                                   MemoryRegion::AllocateFlags alloc_flags,\n                                   uint64_t flags, hsa_amd_vmem_alloc_handle_t* memoryHandle);\n\n  hsa_status_t VMemoryHandleRelease(hsa_amd_vmem_alloc_handle_t memoryHandle);\n\n  hsa_status_t VMemoryHandleMap(void* va, size_t size, size_t in_offset,\n                                hsa_amd_vmem_alloc_handle_t memoryHandle, uint64_t flags);\n\n  hsa_status_t VMemoryHandleUnmap(void* va, size_t size);\n\n  hsa_status_t VMemorySetAccess(void* va, size_t size, const hsa_amd_memory_access_desc_t* desc,\n                                size_t desc_cnt);\n\n  hsa_status_t VMemoryGetAccess(const void* va, hsa_access_permission_t* perms,\n                                hsa_agent_t agent_handle);\n\n  hsa_status_t VMemoryExportShareableHandle(int* dmabuf_fd,\n                                            const hsa_amd_vmem_alloc_handle_t handle,\n                                            const uint64_t flags);\n\n  hsa_status_t VMemoryImportShareableHandle(const int dmabuf_fd,\n                                            hsa_amd_vmem_alloc_handle_t* handle);\n\n  hsa_status_t VMemoryRetainAllocHandle(hsa_amd_vmem_alloc_handle_t* memoryHandle, void* addr);\n\n  hsa_status_t VMemoryGetAllocPropertiesFromHandle(const hsa_amd_vmem_alloc_handle_t memoryHandle,\n                                                   const core::MemoryRegion** mem_region,\n                                                   hsa_amd_memory_type_t* type);\n\n  hsa_status_t EnableLogging(uint8_t* flags, void* file);\n\n  const std::vector<Agent*>& cpu_agents() { return cpu_agents_; }\n\n  const std::vector<Agent*>& gpu_agents() { return gpu_agents_; }\n\n  const std::vector<Agent *> &aie_agents() { return aie_agents_; }\n\n  const std::vector<Agent*>& disabled_gpu_agents() { return disabled_gpu_agents_; }\n\n  const std::vector<uint32_t>& gpu_ids() { return gpu_ids_; }\n\n  Agent* agent_by_gpuid(uint32_t gpuid) { return agents_by_gpuid_[gpuid]; }\n\n  Agent* region_gpu() { return region_gpu_; }\n\n  const std::vector<const MemoryRegion*>& system_regions_fine() const {\n    return system_regions_fine_;\n  }\n\n  const std::vector<const MemoryRegion*>& system_regions_coarse() const {\n    return system_regions_coarse_;\n  }\n\n  amd::hsa::loader::Loader* loader() { return loader_; }\n\n  amd::LoaderContext* loader_context() { return &loader_context_; }\n\n  amd::hsa::code::AmdHsaCodeManager* code_manager() { return &code_manager_; }\n\n  std::function<void*(size_t size, size_t align, MemoryRegion::AllocateFlags flags, int agent_node_id)>&\n  system_allocator() {\n    return system_allocator_;\n  }\n\n  std::function<void(void*)>& system_deallocator() {\n    return system_deallocator_;\n  }\n\n  const Flag& flag() const { return flag_; }\n\n  const ThunkLoader* thunkLoader() const { return thunkLoader_; }\n\n  ExtensionEntryPoints extensions_;\n\n  hsa_status_t SetCustomSystemEventHandler(hsa_amd_system_event_callback_t callback,\n                                           void* data);\n\n  hsa_status_t SetInternalQueueCreateNotifier(hsa_amd_runtime_queue_notifier callback,\n                                              void* user_data);\n\n  void InternalQueueCreateNotify(const hsa_queue_t* queue, hsa_agent_t agent);\n\n  SharedSignalPool_t* GetSharedSignalPool() { return &SharedSignalPool; }\n\n  InterruptSignal::EventPool* GetEventPool() { return &EventPool; }\n\n  uint64_t sys_clock_freq() const { return sys_clock_freq_; }\n\n  void KfdVersion(const HsaVersionInfo& version) {\n    kfd_version.version = version;\n    if (version.KernelInterfaceMajorVersion == 1 &&\n      version.KernelInterfaceMinorVersion >= 14)\n      kfd_version.supports_event_age = true;\n  }\n\n  void KfdVersion(bool exception_debugging, bool core_dump) {\n    kfd_version.supports_exception_debugging = exception_debugging;\n    kfd_version.supports_core_dump = core_dump;\n  }\n\n  KfdVersion_t KfdVersion() const { return kfd_version; }\n\n  bool VirtualMemApiSupported() const { return virtual_mem_api_supported_; }\n  bool XnackEnabled() const { return xnack_enabled_; }\n  void XnackEnabled(bool enable) { xnack_enabled_ = enable; }\n\n  Driver &AgentDriver(DriverType drv_type) {\n    auto is_drv_type = [&](const std::unique_ptr<Driver> &d) {\n      return d->kernel_driver_type_ == drv_type;\n    };\n\n    auto driver(std::find_if(agent_drivers_.begin(), agent_drivers_.end(),\n                             is_drv_type));\n\n    if (driver == agent_drivers_.end()) {\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                               \"Invalid agent device type, no driver found.\");\n    }\n\n    return **driver;\n  }\n\n  /// @brief Check if the drivers of the agents are different.\n  /// @param [in] agents Array of agents to check.\n  /// @param [in] num_agents Number of agents in the array.\n  /// @return True if the drivers of the agents are different, false otherwise.\n  static bool IsDifferentDriver(Agent* agents, uint32_t num_agents) {\n    if (num_agents == 0 || agents == nullptr) return true;\n\n    auto first_driver_type = agents[0].driver().kernel_driver_type_;\n    for (uint32_t i = 1; i < num_agents; ++i) {\n      if (agents[i].driver().kernel_driver_type_ != first_driver_type) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  std::vector<std::unique_ptr<Driver>>& AgentDrivers() { return agent_drivers_; }\n\n  static bool IsGPUDriver(DriverType driver_type) {\n    return driver_type == core::DriverType::KFD\n#ifdef HSAKMT_VIRTIO_ENABLED\n        || driver_type == core::DriverType::KFD_VIRTIO\n#endif\n        ;\n  }\n\n protected:\n  static void AsyncEventsLoop(void*);\n  static void AsyncIPCSockServerConnLoop(void*);\n\n  struct AllocationRegion {\n    AllocationRegion()\n        : region(NULL),\n          size(0),\n          size_requested(0),\n          alloc_flags(core::MemoryRegion::AllocateNoFlags),\n          user_ptr(nullptr),\n          ldrm_bo(NULL) {}\n    AllocationRegion(const MemoryRegion* region_arg, size_t size_arg, size_t size_requested,\n                     MemoryRegion::AllocateFlags alloc_flags)\n        : region(region_arg),\n          size(size_arg),\n          size_requested(size_requested),\n          alloc_flags(alloc_flags),\n          user_ptr(nullptr),\n          ldrm_bo(NULL) {}\n\n    struct notifier_t {\n      void* ptr;\n      AMD::callback_t<hsa_amd_deallocation_callback_t> callback;\n      void* user_data;\n    };\n\n    const MemoryRegion* region;\n    size_t size;           /* actual size = align_up(size_requested, granularity) */\n    size_t size_requested; /* size requested by user */\n    MemoryRegion::AllocateFlags alloc_flags;\n    void* user_ptr;\n    std::unique_ptr<std::vector<notifier_t>> notifiers;\n    amdgpu_bo_handle ldrm_bo;\n  };\n\n  struct AsyncEventsControl {\n    AsyncEventsControl() : async_events_thread_(NULL) {}\n    void Shutdown();\n\n    hsa_signal_t wake;\n    os::Thread async_events_thread_;\n    HybridMutex lock;\n    bool exit;\n  };\n\n  struct AsyncEvents {\n    void PushBack(hsa_signal_t signal, hsa_signal_condition_t cond,\n                  hsa_signal_value_t value, hsa_amd_signal_handler handler,\n                  void* arg);\n\n    void CopyIndex(size_t dst, size_t src);\n\n    size_t Size();\n\n    void PopBack();\n\n    void Clear();\n\n    std::vector<hsa_signal_t> signal_;\n    std::vector<hsa_signal_condition_t> cond_;\n    std::vector<hsa_signal_value_t> value_;\n    std::vector<hsa_amd_signal_handler> handler_;\n    std::vector<HsaEvent*> hsa_events_; //!< A list of HSA events for KFD wait\n    std::vector<uint64_t> age_;         //!< The age list for KFD wait\n    std::vector<void*> arg_;\n  };\n\n  struct PrefetchRange;\n  typedef std::map<uintptr_t, PrefetchRange> prefetch_map_t;\n\n  struct PrefetchOp {\n    void* base;\n    size_t size;\n    uint32_t node_id;\n    int remaining_deps;\n    hsa_signal_t completion;\n    std::vector<hsa_signal_t> dep_signals;\n    prefetch_map_t::iterator prefetch_map_entry;\n  };\n\n  struct PrefetchRange {\n    PrefetchRange() {}\n    PrefetchRange(size_t Bytes, PrefetchOp* Op) : bytes(Bytes), op(Op) {}\n    size_t bytes;\n    PrefetchOp* op;\n    prefetch_map_t::iterator prev;\n    prefetch_map_t::iterator next;\n  };\n\n  // Will be created before any user could call hsa_init but also could be\n  // destroyed before incorrectly written programs call hsa_shutdown.\n  static __forceinline KernelMutex& bootstrap_lock() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static KernelMutex* bootstrap_lock_ = new KernelMutex;\n    return *bootstrap_lock_;\n  }\n  Runtime();\n\n  Runtime(const Runtime&);\n\n  Runtime& operator=(const Runtime&);\n\n  ~Runtime() {}\n\n  /// @brief Open connection to kernel driver.\n  hsa_status_t Load();\n\n  /// @brief Close connection to kernel driver and cleanup resources.\n  void Unload();\n\n  /// @brief Dynamically load extension libraries (images, finalizer) and\n  /// call OnLoad method on each loaded library.\n  void LoadExtensions();\n\n  /// @brief Call OnUnload method on each extension library then close it.\n  void UnloadExtensions();\n\n  /// @brief Dynamically load tool libraries and call OnUnload method on each\n  /// loaded library.\n  void LoadTools();\n\n  /// @brief Call OnUnload method of each tool library.\n  void UnloadTools();\n\n  /// @brief Close tool libraries.\n  void CloseTools();\n\n  // @brief Binds Error handlers to this node.\n  void BindErrorHandlers();\n\n  // @brief Acquire snapshot of system event handlers.\n  // Returns a copy to avoid holding a lock during callbacks.\n  std::vector<std::pair<AMD::callback_t<hsa_amd_system_event_callback_t>, void*>>\n  GetSystemEventHandlers();\n\n  /// @brief Get the index of ::link_matrix_.\n  /// @param [in] node_id_from Node id of the source node.\n  /// @param [in] node_id_to Node id of the destination node.\n  /// @retval Index in ::link_matrix_.\n  uint32_t GetIndexLinkInfo(uint32_t node_id_from, uint32_t node_id_to);\n\n  /// @brief Get most recently issued SVM prefetch agent for the range in question.\n  Agent* GetSVMPrefetchAgent(void* ptr, size_t size);\n\n  /// @brief Get the highest used node id.\n  uint32_t max_node_id() const { return agents_by_node_.rbegin()->first; }\n\n  // Mutex object to protect multithreaded access to ::allocation_map_.\n  // Also ensures atomicity of pointer info queries by interlocking\n  // KFD map/unmap, register/unregister, and access to hsaKmtQueryPointerInfo\n  // registered & mapped arrays.\n  KernelSharedMutex memory_lock_;\n\n  // Array containing driver interfaces for compatible agent kernel-mode\n  // drivers. Currently supports AIE agents.\n  std::vector<std::unique_ptr<Driver>> agent_drivers_;\n\n  // Array containing tools library handles.\n  std::vector<os::LibHandle> tool_libs_;\n\n  // Agent list containing all CPU agents in the platform.\n  std::vector<Agent*> cpu_agents_;\n\n  // Agent list containing all compatible GPU agents in the platform.\n  std::vector<Agent*> gpu_agents_;\n\n  // Agent list containing all compatible AIE agents in the platform.\n  std::vector<Agent *> aie_agents_;\n\n  // Agent list containing incompletely initialized GPU agents not to be used by the process.\n  std::vector<Agent*> disabled_gpu_agents_;\n\n  // Agent map containing all agents indexed by their KFD node IDs.\n  std::map<uint32_t, std::vector<Agent*> > agents_by_node_;\n\n  // Agent map containing all agents indexed by their KFD gpuid.\n  std::map<uint32_t, Agent*> agents_by_gpuid_;\n\n  // Agent list containing all compatible gpu agent ids in the platform.\n  std::vector<uint32_t> gpu_ids_;\n\n  // List of all fine grain system memory region in the platform.\n  std::vector<const MemoryRegion*> system_regions_fine_;\n\n  // List of all coarse grain system memory region in the platform.\n  std::vector<const MemoryRegion*> system_regions_coarse_;\n\n  // Matrix of IO link.\n  std::vector<LinkInfo> link_matrix_;\n\n  // Loader instance.\n  amd::hsa::loader::Loader* loader_;\n\n  // Loader context.\n  amd::LoaderContext loader_context_;\n\n  // Code object manager.\n  amd::hsa::code::AmdHsaCodeManager code_manager_;\n\n  // Contains the region, address, and size of previously allocated memory.\n  std::map<const void*, AllocationRegion> allocation_map_;\n\n  // Pending prefetch containers.\n  KernelMutex prefetch_lock_;\n  prefetch_map_t prefetch_map_;\n\n  // Allocator using ::system_region_\n  std::function<void*(size_t size, size_t align, MemoryRegion::AllocateFlags flags, int agent_node_id)> system_allocator_;\n\n  // Deallocator using ::system_region_\n  std::function<void(void*)> system_deallocator_;\n\n  // Deprecated HSA Region API GPU (for legacy APU support only)\n  Agent* region_gpu_;\n\n  struct AsyncEventsInfo {\n    AsyncEventsControl control;\n    AsyncEvents events;\n    AsyncEvents new_events;\n    bool monitor_exceptions;\n  };\n\n  struct AsyncEventsInfo asyncSignals_;\n  struct AsyncEventsInfo asyncExceptions_;\n\n  // System clock frequency.\n  uint64_t sys_clock_freq_;\n\n  // Number of Numa Nodes\n  size_t num_nodes_;\n\n  // @brief AMD HSA event to monitor for virtual memory access fault.\n  HsaEvent* vm_fault_event_;\n\n  // @brief HSA signal to contain the VM fault event.\n  Signal* vm_fault_signal_;\n\n  // @brief AMD HSA event to monitor for HW exceptions.\n  HsaEvent* hw_exception_event_;\n\n  // @brief HSA signal to contain the HW exceptionevent.\n  Signal* hw_exception_signal_;\n\n  // Custom system event handlers.\n  std::vector<std::pair<AMD::callback_t<hsa_amd_system_event_callback_t>, void*>>\n      system_event_handlers_;\n\n  // System event handler lock\n  KernelMutex system_event_lock_;\n\n  // Internal queue creation notifier\n  AMD::callback_t<hsa_amd_runtime_queue_notifier> internal_queue_create_notifier_;\n\n  void* internal_queue_create_notifier_user_data_;\n\n  // Holds reference count to runtime object.\n  std::atomic<uint32_t> ref_count_;\n\n  // Track environment variables.\n  Flag flag_;\n\n  ThunkLoader* thunkLoader_;\n\n  // Pools memory for SharedSignal (Signal ABI blocks)\n  SharedSignalPool_t SharedSignalPool;\n\n  // Pools KFD Events for InterruptSignal\n  InterruptSignal::EventPool EventPool;\n\n  // Kfd version\n  KfdVersion_t kfd_version;\n\n  std::unique_ptr<AMD::SvmProfileControl> svm_profile_;\n\n  // IPC DMA buf unix domain socket server dmabuf FD passing\n  int ipc_sock_server_fd_;\n  std::map<uint64_t, int> ipc_sock_server_conns_;\n  KernelMutex ipc_sock_server_lock_;\n\n private:\n  void CheckVirtualMemApiSupport();\n  int GetAmdgpuDeviceArgs(Agent *agent, ShareableHandle handle, int *drm_fd,\n                          uint64_t *cpu_addr);\n\n  bool virtual_mem_api_supported_;\n  bool xnack_enabled_;\n\n  typedef void* ThunkHandle;\n\n  struct AddressHandle {\n    AddressHandle() : os_addr(nullptr), size(0), use_count(0), registered(false) {}\n    AddressHandle(void* addr, size_t _size, bool _registered) : os_addr(addr), size(_size), use_count(0), registered(_registered) {}\n\n    // Address returned by OS. May be different from user address when adjusted for alignment\n    void *os_addr;\n    size_t size;\n    int use_count;\n    bool registered;\n  };\n  std::map<const void*, AddressHandle> reserved_address_map_;  // Indexed by VA\n\n  struct MemoryHandle {\n    MemoryHandle(const MemoryRegion* region, size_t size, uint64_t flags_unused,\n                 ThunkHandle thunk_handle, MemoryRegion::AllocateFlags alloc_flag)\n        : region(region),\n          size(size),\n          ref_count(1),\n          use_count(0),\n          thunk_handle(thunk_handle),\n          alloc_flag(alloc_flag) {}\n\n    static __forceinline hsa_amd_vmem_alloc_handle_t Convert(ThunkHandle handle) {\n      hsa_amd_vmem_alloc_handle_t ret_handle = {\n          static_cast<uint64_t>(reinterpret_cast<uintptr_t>(handle))};\n      return ret_handle;\n    }\n\n    static __forceinline ThunkHandle Convert(hsa_amd_vmem_alloc_handle_t handle) {\n      return reinterpret_cast<void*>(handle.handle);\n    }\n\n    __forceinline core::Agent* agentOwner() const { return region->owner(); }\n\n    const MemoryRegion* region;\n    size_t size;\n    int ref_count;\n    int use_count;\n    ThunkHandle thunk_handle;  // handle returned by Driver::Allocate(NoAddress = 1)\n    MemoryRegion::AllocateFlags alloc_flag;\n  };\n  std::map<ThunkHandle, MemoryHandle> memory_handle_map_;\n\n  struct MappedHandle;\n  struct MappedHandleAllowedAgent {\n    MappedHandleAllowedAgent(MappedHandle* _mappedHandle, Agent* targetAgent, void* va, size_t size,\n                             hsa_access_permission_t perms);\n    ~MappedHandleAllowedAgent();\n\n    hsa_status_t RemoveAccess();\n    hsa_status_t EnableAccess(hsa_access_permission_t perms);\n\n    void* va;\n    size_t size;\n    Agent* targetAgent;\n    hsa_access_permission_t permissions;\n    MappedHandle* mappedHandle;\n    ShareableHandle shareable_handle;\n  };\n\n  struct MappedHandle {\n    MappedHandle(MemoryHandle *mem_handle, AddressHandle *address_handle,\n                 uint64_t offset, size_t size, int drm_fd, void *drm_cpu_addr,\n                 hsa_access_permission_t perm, ShareableHandle shareable_handle)\n        : mem_handle(mem_handle), address_handle(address_handle),\n          offset(offset), size(size), drm_fd(drm_fd),\n          drm_cpu_addr(drm_cpu_addr), shareable_handle(shareable_handle) {}\n\n    __forceinline core::Agent* agentOwner() const { return mem_handle->region->owner(); }\n\n    MemoryHandle* mem_handle;\n    AddressHandle* address_handle;\n    uint64_t offset;\n    size_t size;\n    int drm_fd;\n    void* drm_cpu_addr;  // CPU Buffer address\n    ShareableHandle shareable_handle;\n    std::map<Agent*, MappedHandleAllowedAgent> allowed_agents;\n  };\n  std::map<const void*, MappedHandle> mapped_handle_map_;  // Indexed by VA\n\n  hsa_status_t VMemoryMapAllowAccess(const void *va,\n                                     hsa_access_permission_t perm,\n                                     const hsa_agent_t *agents,\n                                     size_t num_agents);\n  hsa_status_t\n  VMemorySetAccessPerHandle(void *va, MappedHandle &MappedHandle,\n                            const hsa_amd_memory_access_desc_t *desc,\n                            const size_t desc_cnt);\n\n  void InitIPCDmaBufSupport();\n  bool ipc_dmabuf_supported_;\n  int  IPCClientImport(uint32_t conn_handle, uint64_t dmabuf_fd_handle,\n                       amdgpu_bo_import_result *res,\n                       unsigned int numNodes, HSAuint32 *nodes,\n                       void **importAddress, HSAuint64 *importSize);\n};\n\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/scratch_cache.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2020-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_SCRATCH_CACHE_H_\n#define HSA_RUNTIME_CORE_INC_SCRATCH_CACHE_H_\n\n#include \"core/util/locks.h\"\n#include \"core/util/utils.h\"\n\n#include <map>\n#include <functional>\n\nnamespace rocr {\nnamespace AMD {\n\nclass ScratchCache {\n public:\n  struct node {\n    enum STATE { FREE = 0, ALLOC = 1, TRIM = 2, STEAL = 4 };\n    void* base;\n    bool large;\n    uint32_t state;\n\n    node() : base(nullptr), large(false), state(FREE) {}\n\n    bool isFree() const { return state == FREE; }\n    bool trimPending() const { return state == (ALLOC | TRIM); }\n\n    void trim() {\n      assert(!isFree() && \"Trim of free scratch node.\");\n      state |= TRIM;\n    }\n    void free() {\n      assert(!isFree() && \"Free of free scratch node.\");\n      state = FREE;\n    }\n    void alloc() {\n      assert(isFree() && \"Alloc of non-free scratch node.\");\n      state = ALLOC;\n    }\n  };\n\n  typedef ::std::multimap<size_t, node> map_t;\n  typedef map_t::iterator ref_t;\n  typedef ::std::function<void(void*, size_t, bool)> deallocator_t;\n\n  // @brief Contains scratch memory information.\n  struct ScratchInfo {\n    // Size to satisfy the present dispatch without throttling.\n    size_t dispatch_size;\n    uint64_t dispatch_slots;\n\n    bool large;\n    size_t use_once_limit;\n    size_t use_alt_limit;\n    bool async_reclaim;  // This version of CP FW supports async_reclaim\n    bool retry;\n    uint32_t mem_alignment_size;  // Populated into SRD\n    bool cooperative;\n    hsa_signal_t queue_retry;\n\n    // Size to fill the main_scratch with size_per_thread\n    size_t main_size;\n    size_t main_size_per_thread;    // Populated into SRD\n    uint32_t main_lanes_per_wave;   // Populated into SRD\n    uint32_t main_waves_per_group;  // Used during waves reduction\n    void* main_queue_base;\n    ptrdiff_t main_queue_process_offset;\n    ScratchCache::ref_t main_scratch_node;\n\n    size_t alt_size;\n    size_t alt_size_per_thread;    // Populated into SRD\n    uint32_t alt_lanes_per_wave;   // Populated into SRD\n    uint32_t alt_waves_per_group;  // Used during waves reduction\n\n    uint64_t alt_dispatch_limit_x;\n    uint64_t alt_dispatch_limit_y;\n    uint64_t alt_dispatch_limit_z;\n    void* alt_queue_base;\n    ptrdiff_t alt_queue_process_offset;\n    ScratchCache::ref_t alt_scratch_node;\n  };\n\n  ScratchCache(const ScratchCache& rhs) = delete;\n  ScratchCache(ScratchCache&& rhs) = delete;\n  ScratchCache& operator=(const ScratchCache& rhs) = delete;\n  ScratchCache& operator=(ScratchCache&& rhs) = delete;\n\n  ScratchCache(deallocator_t deallocator) : dealloc(std::move(deallocator)), available_bytes_(0) {}\n\n  ~ScratchCache() { assert(map.empty() && \"ScratchCache not empty at shutdown.\"); }\n\n  bool allocMain(ScratchInfo& info) {\n    ref_t it = map.upper_bound(info.main_size - 1);\n    if (it == map.end()) return false;\n\n    // Small requests must have an exact size match and be small.\n    if (!info.large) {\n      while ((it != map.end()) && (it->first == info.main_size)) {\n        if (it->second.isFree() && (!it->second.large)) {\n          it->second.alloc();\n          info.main_queue_base = it->second.base;\n          info.main_scratch_node = it;\n          available_bytes_ -= it->first;\n          return true;\n        }\n        it++;\n      }\n      return false;\n    }\n\n    // Large requests may use a small allocation and do not require an exact size match.\n    while (it != map.end()) {\n      if (it->second.isFree()) {\n        it->second.alloc();\n        info.main_queue_base = it->second.base;\n        info.main_scratch_node = it;\n        available_bytes_ -= it->first;\n        return true;\n      }\n      it++;\n    }\n    return false;\n  }\n\n  void freeMain(ScratchInfo& info) {\n    if (info.main_scratch_node == map.end()) {\n      // This is reserved scratch memory. Do not de-allocate, just mark it as free.\n      assert(!reserved_.second.isFree() && \"free called when reserved node already free.\");\n      reserved_.second.free();\n      available_bytes_ += reserved_.first;\n      return;\n    }\n\n    assert(!info.main_scratch_node->second.isFree() && \"free called on free scratch node.\");\n    auto it = info.main_scratch_node;\n    if (it->second.trimPending()) {\n      dealloc(it->second.base, it->first, it->second.large);\n      map.erase(it);\n      return;\n    }\n    it->second.free();\n    available_bytes_ += it->first;\n  }\n\n  void insertMain(ScratchInfo& info) {\n    node n;\n    n.base = info.main_queue_base;\n    n.large = info.large;\n    n.alloc();\n\n    auto it = map.insert(std::make_pair(info.main_size, n));\n    info.main_scratch_node = it;\n  }\n\n  bool trim(bool trim_nodes_in_use) {\n    bool ret = !map.empty();\n    auto it = map.begin();\n    while (it != map.end()) {\n      if (it->second.isFree()) {\n        available_bytes_ -= it->first;\n        dealloc(it->second.base, it->first, it->second.large);\n        auto temp = it;\n        it++;\n        map.erase(temp);\n      } else {\n        if (trim_nodes_in_use) it->second.trim();\n        it++;\n      }\n    }\n    return ret;\n  }\n\n  bool allocAlt(ScratchInfo& info) {\n    ref_t it = map.upper_bound(info.alt_size - 1);\n    if (it == map.end()) return false;\n\n    // Alt requests should have exact size\n    while ((it != map.end()) && (it->first == info.alt_size)) {\n      if (it->second.isFree() && (!it->second.large)) {\n        it->second.alloc();\n        info.alt_queue_base = it->second.base;\n        info.alt_scratch_node = it;\n        available_bytes_ -= it->first;\n        return true;\n      }\n      it++;\n    }\n    return false;\n  }\n\n  void freeAlt(ScratchInfo& info) {\n    assert(!info.alt_scratch_node->second.isFree() && \"free called on free scratch node.\");\n    auto it = info.alt_scratch_node;\n    if (it->second.trimPending()) {\n      dealloc(it->second.base, it->first, it->second.large);\n      map.erase(it);\n      return;\n    }\n    it->second.free();\n    available_bytes_ += it->first;\n  }\n\n  void insertAlt(ScratchInfo& info) {\n    node n;\n    n.base = info.alt_queue_base;\n    n.large = false;\n    n.alloc();\n\n    auto it = map.insert(std::make_pair(info.alt_size, n));\n    info.alt_scratch_node = it;\n  }\n\n  size_t free_bytes() const { return available_bytes_; }\n  size_t reserved_bytes() const { return reserved_.first; }\n\n  void reserve(size_t bytes, void* base) {\n    assert(!reserved_.first && \"Already reserved memory.\");\n\n    node n;\n    n.base = base;\n    n.large = 0;\n\n    available_bytes_ += bytes;\n\n    reserved_ = std::make_pair(bytes, n);\n  }\n\n  bool use_reserved(ScratchInfo& info) {\n    if (!reserved_.second.isFree() || info.main_size > reserved_.first) {\n      debug_print(\"reserved node is already in use or too small (requested:%ld reserved:%ld)\\n\",\n                  info.main_size, reserved_.first);\n      return false;\n    }\n    reserved_.second.large = info.large;\n    reserved_.second.alloc();\n    info.main_queue_base = reserved_.second.base;\n    // Special case to indicate that this node is reserved memory\n    info.main_scratch_node = map.end();\n    available_bytes_ -= reserved_.first;\n    return true;\n  }\n\n  void free_reserve() {\n    available_bytes_ -= reserved_.first;\n    if (reserved_.first) dealloc(reserved_.second.base, reserved_.first, reserved_.second.large);\n\n    reserved_.first = 0;\n    reserved_.second.base = NULL;\n    reserved_.second.large = 0;\n  }\n\n private:\n  map_t map;\n  deallocator_t dealloc;\n  size_t available_bytes_;\n\n  std::pair<size_t, node> reserved_;\n};\n\n}  // namespace AMD\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/sdma_registers.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_SDMA_REGISTERS_H_\n#define HSA_RUNTIME_CORE_INC_SDMA_REGISTERS_H_\n\n#include <stddef.h>\n#include <stdint.h>\n\nnamespace rocr {\nnamespace AMD {\n\n// SDMA packet for VI device.\n// Reference: http://people.freedesktop.org/~agd5f/dma_packets.txt\n\nconst unsigned int SDMA_OP_COPY = 1;\nconst unsigned int SDMA_OP_FENCE = 5;\nconst unsigned int SDMA_OP_TRAP = 6;\nconst unsigned int SDMA_OP_POLL_REGMEM = 8;\nconst unsigned int SDMA_OP_ATOMIC = 10;\nconst unsigned int SDMA_OP_CONST_FILL = 11;\nconst unsigned int SDMA_OP_TIMESTAMP = 13;\nconst unsigned int SDMA_OP_GCR = 17;\nconst unsigned int SDMA_SUBOP_COPY_LINEAR = 0;\nconst unsigned int SDMA_SUBOP_COPY_LINEAR_RECT = 4;\nconst unsigned int SDMA_SUBOP_TIMESTAMP_GET_GLOBAL = 2;\nconst unsigned int SDMA_SUBOP_USER_GCR = 1;\nconst unsigned int SDMA_ATOMIC_ADD64 = 47;\n\ntypedef struct SDMA_PKT_COPY_LINEAR_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int extra_info : 16;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int count : 22;\n      unsigned int reserved_0 : 10;\n    } count;\n    struct {\n      unsigned int count : 30;\n      unsigned int reserved_0 : 2;\n    } count_ext;\n    unsigned int DW_1_DATA;\n  } COUNT_UNION;\n\n  union {\n    struct {\n      unsigned int reserved_0 : 16;\n      unsigned int dst_swap : 2;\n      unsigned int reserved_1 : 6;\n      unsigned int src_swap : 2;\n      unsigned int reserved_2 : 6;\n    };\n    unsigned int DW_2_DATA;\n  } PARAMETER_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_31_0 : 32;\n    };\n    unsigned int DW_3_DATA;\n  } SRC_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_63_32 : 32;\n    };\n    unsigned int DW_4_DATA;\n  } SRC_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_31_0 : 32;\n    };\n    unsigned int DW_5_DATA;\n  } DST_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_63_32 : 32;\n    };\n    unsigned int DW_6_DATA;\n  } DST_ADDR_HI_UNION;\n\n  static const size_t kMaxSize_ = 0x3fffe0;\n} SDMA_PKT_COPY_LINEAR;\n\n// linear sub-window (pre-GFX12)\ntypedef struct SDMA_PKT_COPY_LINEAR_RECT_TAG {\n  static const unsigned int pitch_bits = 19;\n  static const unsigned int slice_bits = 28;\n  static const unsigned int rect_xy_bits = 14;\n  static const unsigned int rect_z_bits = 11;\n\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int reserved : 13;\n      unsigned int element : 3;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } SRC_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } SRC_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int src_offset_x : 14;\n      unsigned int reserved_1 : 2;\n      unsigned int src_offset_y : 14;\n      unsigned int reserved_2 : 2;\n    };\n    unsigned int DW_3_DATA;\n  } SRC_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int src_offset_z : 11;\n      unsigned int reserved_1 : 2;\n      unsigned int src_pitch : pitch_bits;\n    };\n    unsigned int DW_4_DATA;\n  } SRC_PARAMETER_2_UNION;\n\n  union {\n    struct {\n      unsigned int src_slice_pitch : slice_bits;\n      unsigned int reserved_1 : 4;\n    };\n    unsigned int DW_5_DATA;\n  } SRC_PARAMETER_3_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_31_0 : 32;\n    };\n    unsigned int DW_6_DATA;\n  } DST_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_63_32 : 32;\n    };\n    unsigned int DW_7_DATA;\n  } DST_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int dst_offset_x : 14;\n      unsigned int reserved_1 : 2;\n      unsigned int dst_offset_y : 14;\n      unsigned int reserved_2 : 2;\n    };\n    unsigned int DW_8_DATA;\n  } DST_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int dst_offset_z : 11;\n      unsigned int reserved_1 : 2;\n      unsigned int dst_pitch : pitch_bits;\n    };\n    unsigned int DW_9_DATA;\n  } DST_PARAMETER_2_UNION;\n\n  union {\n    struct {\n      unsigned int dst_slice_pitch : slice_bits;\n      unsigned int reserved_1 : 4;\n    };\n    unsigned int DW_10_DATA;\n  } DST_PARAMETER_3_UNION;\n\n  union {\n    struct {\n      unsigned int rect_x : rect_xy_bits;\n      unsigned int reserved_1 : 2;\n      unsigned int rect_y : rect_xy_bits;\n      unsigned int reserved_2 : 2;\n    };\n    unsigned int DW_11_DATA;\n  } RECT_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int rect_z : rect_z_bits;\n      unsigned int reserved_1 : 5;\n      unsigned int dst_swap : 2;\n      unsigned int reserved_2 : 6;\n      unsigned int src_swap : 2;\n      unsigned int reserved_3 : 6;\n    };\n    unsigned int DW_12_DATA;\n  } RECT_PARAMETER_2_UNION;\n\n} SDMA_PKT_COPY_LINEAR_RECT;\n\n// linear sub-window (GFX12)\ntypedef struct SDMA_PKT_COPY_LINEAR_RECT_TAG_GFX12 {\n  static const unsigned int pitch_bits   = 16;\n  static const unsigned int slice_bits   = 32;\n  static const unsigned int rect_xy_bits = 16;\n  static const unsigned int rect_z_bits  = 14;\n\n  union {\n    struct {\n      unsigned int op       :  8;\n      unsigned int sub_op   :  8;\n      unsigned int reserved : 13;\n      unsigned int element  :  3;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } SRC_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int src_addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } SRC_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int src_offset_x : 16;\n      unsigned int src_offset_y : 16;\n    };\n    unsigned int DW_3_DATA;\n  } SRC_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int src_offset_z : 14;\n      unsigned int reserved_1   : 2;\n      unsigned int src_pitch    : pitch_bits;\n    };\n    unsigned int DW_4_DATA;\n  } SRC_PARAMETER_2_UNION;\n\n  union {\n    struct {\n      unsigned int src_slice_pitch : slice_bits;\n    };\n    unsigned int DW_5_DATA;\n  } SRC_PARAMETER_3_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_31_0 : 32;\n    };\n    unsigned int DW_6_DATA;\n  } DST_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_63_32 : 32;\n    };\n    unsigned int DW_7_DATA;\n  } DST_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int dst_offset_x : 16;\n      unsigned int dst_offset_y : 16;\n    };\n    unsigned int DW_8_DATA;\n  } DST_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int dst_offset_z : 14;\n      unsigned int reserved_1   : 2;\n      unsigned int dst_pitch    : pitch_bits;\n    };\n    unsigned int DW_9_DATA;\n  } DST_PARAMETER_2_UNION;\n\n  union {\n    struct {\n      unsigned int dst_slice_pitch : slice_bits;\n    };\n    unsigned int DW_10_DATA;\n  } DST_PARAMETER_3_UNION;\n\n  union {\n    struct {\n      unsigned int rect_x : rect_xy_bits;\n      unsigned int rect_y : rect_xy_bits;\n      };\n    unsigned int DW_11_DATA;\n  } RECT_PARAMETER_1_UNION;\n\n  union {\n    struct {\n      unsigned int rect_z           : rect_z_bits;\n      unsigned int reserved_1       : 6;\n      unsigned int dst_cache_policy : 3;\n      unsigned int reserved_2       : 5;\n      unsigned int src_cache_policy : 3;\n      unsigned int reserved_3       : 1;\n    };\n    unsigned int DW_12_DATA;\n  } RECT_PARAMETER_2_UNION;\n\n} SDMA_PKT_COPY_LINEAR_RECT_GFX12;\n\ntypedef struct SDMA_PKT_CONSTANT_FILL_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int sw : 2;\n      unsigned int reserved_0 : 12;\n      unsigned int fillsize : 2;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } DST_ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int dst_addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } DST_ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int src_data_31_0 : 32;\n    };\n    unsigned int DW_3_DATA;\n  } DATA_UNION;\n\n  union {\n    struct {\n      unsigned int count : 22;\n      unsigned int reserved_0 : 10;\n    };\n    unsigned int DW_4_DATA;\n  } COUNT_UNION;\n\n  static const size_t kMaxSize_ = 0x3fffe0;\n} SDMA_PKT_CONSTANT_FILL;\n\ntypedef struct SDMA_PKT_FENCE_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int mtype : 3;\n      unsigned int gcc : 1;\n      unsigned int sys : 1;\n      unsigned int pad1 : 1;\n      unsigned int snp : 1;\n      unsigned int gpa : 1;\n      unsigned int l2_policy : 2;\n      unsigned int reserved_0 : 6;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int data : 32;\n    };\n    unsigned int DW_3_DATA;\n  } DATA_UNION;\n} SDMA_PKT_FENCE;\n\ntypedef struct SDMA_PKT_POLL_REGMEM_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int reserved_0 : 10;\n      unsigned int hdp_flush : 1;\n      unsigned int reserved_1 : 1;\n      unsigned int func : 3;\n      unsigned int mem_poll : 1;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int value : 32;\n    };\n    unsigned int DW_3_DATA;\n  } VALUE_UNION;\n\n  union {\n    struct {\n      unsigned int mask : 32;\n    };\n    unsigned int DW_4_DATA;\n  } MASK_UNION;\n\n  union {\n    struct {\n      unsigned int interval : 16;\n      unsigned int retry_count : 12;\n      unsigned int reserved_0 : 4;\n    };\n    unsigned int DW_5_DATA;\n  } DW5_UNION;\n} SDMA_PKT_POLL_REGMEM;\n\ntypedef struct SDMA_PKT_ATOMIC_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int l : 1;\n      unsigned int reserved_0 : 8;\n      unsigned int operation : 7;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } ADDR_HI_UNION;\n\n  union {\n    struct {\n      unsigned int src_data_31_0 : 32;\n    };\n    unsigned int DW_3_DATA;\n  } SRC_DATA_LO_UNION;\n\n  union {\n    struct {\n      unsigned int src_data_63_32 : 32;\n    };\n    unsigned int DW_4_DATA;\n  } SRC_DATA_HI_UNION;\n\n  union {\n    struct {\n      unsigned int cmp_data_31_0 : 32;\n    };\n    unsigned int DW_5_DATA;\n  } CMP_DATA_LO_UNION;\n\n  union {\n    struct {\n      unsigned int cmp_data_63_32 : 32;\n    };\n    unsigned int DW_6_DATA;\n  } CMP_DATA_HI_UNION;\n\n  union {\n    struct {\n      unsigned int loop_interval : 13;\n      unsigned int reserved_0 : 19;\n    };\n    unsigned int DW_7_DATA;\n  } LOOP_UNION;\n} SDMA_PKT_ATOMIC;\n\ntypedef struct SDMA_PKT_TIMESTAMP_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int reserved_0 : 16;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int addr_31_0 : 32;\n    };\n    unsigned int DW_1_DATA;\n  } ADDR_LO_UNION;\n\n  union {\n    struct {\n      unsigned int addr_63_32 : 32;\n    };\n    unsigned int DW_2_DATA;\n  } ADDR_HI_UNION;\n\n} SDMA_PKT_TIMESTAMP;\n\ntypedef struct SDMA_PKT_TRAP_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int reserved_0 : 16;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int int_ctx : 28;\n      unsigned int reserved_1 : 4;\n    };\n    unsigned int DW_1_DATA;\n  } INT_CONTEXT_UNION;\n} SDMA_PKT_TRAP;\n\n// HDP flush packet, no parameters.\ntypedef struct SDMA_PKT_HDP_FLUSH_TAG {\n  unsigned int DW_0_DATA;\n  unsigned int DW_1_DATA;\n  unsigned int DW_2_DATA;\n  unsigned int DW_3_DATA;\n  unsigned int DW_4_DATA;\n  unsigned int DW_5_DATA;\n\n  // Version of gfx9 sDMA microcode introducing SDMA_PKT_HDP_FLUSH\n  static const uint16_t kMinVersion_ = 0x1A5;\n} SDMA_PKT_HDP_FLUSH;\nstatic const SDMA_PKT_HDP_FLUSH hdp_flush_cmd = {0x8, 0x0, 0x80000000, 0x0, 0x0, 0x0};\n\ntypedef struct SDMA_PKT_GCR_TAG {\n  union {\n    struct {\n      unsigned int op : 8;\n      unsigned int sub_op : 8;\n      unsigned int : 16;\n    };\n    unsigned int DW_0_DATA;\n  } HEADER_UNION;\n\n  union {\n    struct {\n      unsigned int : 7;\n      unsigned int BaseVA_LO : 25;\n    };\n    unsigned int DW_1_DATA;\n  } WORD1_UNION;\n\n  union {\n    struct {\n      unsigned int BaseVA_HI : 16;\n      unsigned int GCR_CONTROL_GLI_INV : 2;\n      unsigned int GCR_CONTROL_GL1_RANGE : 2;\n      unsigned int GCR_CONTROL_GLM_WB : 1;\n      unsigned int GCR_CONTROL_GLM_INV : 1;\n      unsigned int GCR_CONTROL_GLK_WB : 1;\n      unsigned int GCR_CONTROL_GLK_INV : 1;\n      unsigned int GCR_CONTROL_GLV_INV : 1;\n      unsigned int GCR_CONTROL_GL1_INV : 1;\n      unsigned int GCR_CONTROL_GL2_US : 1;\n      unsigned int GCR_CONTROL_GL2_RANGE : 2;\n      unsigned int GCR_CONTROL_GL2_DISCARD : 1;\n      unsigned int GCR_CONTROL_GL2_INV : 1;\n      unsigned int GCR_CONTROL_GL2_WB : 1;\n    };\n    unsigned int DW_2_DATA;\n  } WORD2_UNION;\n\n  union {\n    struct {\n      unsigned int GCR_CONTROL_RANGE_IS_PA : 1;\n      unsigned int GCR_CONTROL_SEQ : 2;\n      unsigned int : 4;\n      unsigned int LimitVA_LO : 25;\n    };\n    unsigned int DW_3_DATA;\n  } WORD3_UNION;\n\n  union {\n    struct {\n      unsigned int LimitVA_HI : 16;\n      unsigned int : 8;\n      unsigned int VMID : 4;\n      unsigned int : 4;\n    };\n    unsigned int DW_4_DATA;\n  } WORD4_UNION;\n} SDMA_PKT_GCR;\n\n}  // namespace amd\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_SDMA_REGISTERS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/signal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA runtime C++ interface file.\n\n#ifndef HSA_RUNTME_CORE_INC_SIGNAL_H_\n#define HSA_RUNTME_CORE_INC_SIGNAL_H_\n\n#include <map>\n#include <functional>\n#include <memory>\n#include <vector>\n#include <utility>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"core/common/shared.h\"\n\n#include \"core/inc/checked.h\"\n#include \"core/inc/exceptions.h\"\n\n#include \"core/util/utils.h\"\n#include \"core/util/locks.h\"\n#include \"core/util/timer.h\"\n\n#include \"inc/amd_hsa_signal.h\"\n\n#if defined(__i386__) || defined(__x86_64__)\n#include <mwaitxintrin.h>\n#ifndef MWAITX_ECX_TIMER_ENABLE\n#define MWAITX_ECX_TIMER_ENABLE 0x2  // BIT(1)\n#endif\n#endif\n\n// Allow hsa_signal_t to be keys in STL structures.\nnamespace std {\ntemplate <> struct less<hsa_signal_t> {\n  __forceinline bool operator()(const hsa_signal_t& x, const hsa_signal_t& y) const {\n    return x.handle < y.handle;\n  }\n  typedef hsa_signal_t first_argument_type;\n  typedef hsa_signal_t second_argument_type;\n  typedef bool result_type;\n};\n}\n\nnamespace rocr {\nnamespace timer {\ninline timer::fast_clock::duration GetFastTimeout(uint64_t timeout) {\n  uint64_t hsa_freq = 0;\n  HSA::hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &hsa_freq);\n  return timer::duration_from_seconds<timer::fast_clock::duration>(\n      double(timeout) / double(hsa_freq));\n}\n\ninline void CheckAbortTimeout(const timer::fast_clock::time_point& start_time,\n                            uint32_t signal_abort_timeout) {\n  if (signal_abort_timeout) {\n    const timer::fast_clock::duration abort_timeout =\n        std::chrono::seconds(signal_abort_timeout);\n    if (timer::fast_clock::now() - start_time > abort_timeout) {\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_FATAL,\n                             \"Signal wait abort timeout.\\n\");\n    }\n  }\n}\n\ninline void DoMwaitx(int64_t* addr, uint32_t timeout, bool timer_enable = false) {\n#if defined(__i386__) || defined(__x86_64__)\n  _mm_monitorx(addr, 0, 0);\n  _mm_mwaitx(0, timeout, timer_enable ? MWAITX_ECX_TIMER_ENABLE : 0);\n#endif\n}\n} // namespace timer\n\ninline bool CheckSignalCondition(int64_t value, hsa_signal_condition_t condition,\n                               hsa_signal_value_t compare_value) {\n  switch (condition) {\n    case HSA_SIGNAL_CONDITION_EQ:\n      return value == compare_value;\n    case HSA_SIGNAL_CONDITION_NE:\n      return value != compare_value;\n    case HSA_SIGNAL_CONDITION_GTE:\n      return value >= compare_value;\n    case HSA_SIGNAL_CONDITION_LT:\n      return value < compare_value;\n    default:\n      return false;\n  }\n}\n\nnamespace core {\nclass Agent;\nclass Signal;\n\n/// @brief ABI and object conversion struct for signals.  May be shared between processes.\nstruct SharedSignal {\n  amd_signal_t amd_signal;\n  uint64_t sdma_start_ts;\n  Signal* core_signal;\n  Check<0x71FCCA6A3D5D5276, true> id;\n  uint8_t reserved[8];\n  uint64_t sdma_end_ts;\n  uint8_t reserved2[24];\n\n  SharedSignal() :\n    sdma_start_ts(0),\n    reserved{},\n    sdma_end_ts(0),\n    reserved2{} {\n    memset(&amd_signal, 0, sizeof(amd_signal));\n    amd_signal.kind = AMD_SIGNAL_KIND_INVALID;\n    core_signal = nullptr;\n  }\n\n  bool IsValid() const { return (Convert(this).handle != 0) && id.IsValid(); }\n\n  bool IsIPC() const { return core_signal == nullptr; }\n\n  void GetSdmaTsAddresses(uint64_t*& start, uint64_t*& end) {\n    /*\n    SDMA timestamps on gfx7xx/8xxx require 32 byte alignment (gfx9xx relaxes\n    alignment to 8 bytes).  This conflicts with the frozen format for amd_signal_t\n    so we place the time stamps in sdma_start/end_ts instead (amd_signal.start_ts\n    is also properly aligned).  Reading of the timestamps occurs in GetRawTs().\n    */\n    start = &sdma_start_ts;\n    end = &sdma_end_ts;\n  }\n\n  void CopyPrep() {\n    // Clear sdma_end_ts before a copy so we can detect if the copy was done via\n    // SDMA or blit kernel.\n    sdma_start_ts = 0;\n    sdma_end_ts = 0;\n  }\n\n  void GetRawTs(bool FetchCopyTs, uint64_t& start, uint64_t& end) {\n    /*\n    If the read is for a copy we need to check if it was done by blit kernel or SDMA.\n    Since we clear sdma_start/end_ts during CopyPrep we know it was a SDMA copy if one\n    of those is non-zero.  Otherwise return compute kernel stamps from amd_signal.\n    */\n    if (FetchCopyTs && sdma_end_ts != 0) {\n      start = sdma_start_ts;\n      end = sdma_end_ts;\n      return;\n    }\n    start = amd_signal.start_ts;\n    end = amd_signal.end_ts;\n  }\n\n  static __forceinline SharedSignal* Convert(hsa_signal_t signal) {\n    SharedSignal* ret = reinterpret_cast<SharedSignal*>(static_cast<uintptr_t>(signal.handle) -\n                                                        offsetof(SharedSignal, amd_signal));\n    return ret;\n  }\n\n  static __forceinline hsa_signal_t Convert(const SharedSignal* signal) {\n    assert(signal != nullptr && \"Conversion on null Signal object.\");\n    const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->amd_signal));\n    const hsa_signal_t signal_handle = {handle};\n    return signal_handle;\n  }\n};\nstatic_assert(std::is_standard_layout<SharedSignal>::value,\n              \"SharedSignal must remain standard layout for IPC use.\");\nstatic_assert(std::is_trivially_destructible<SharedSignal>::value,\n              \"SharedSignal must not be modified on delete for IPC use.\");\nstatic_assert((offsetof(SharedSignal, sdma_start_ts) % 32) == 0,\n              \"Bad SDMA time stamp alignment.\");\nstatic_assert((offsetof(SharedSignal, sdma_end_ts) % 32) == 0,\n              \"Bad SDMA time stamp alignment.\");\nstatic_assert(sizeof(SharedSignal) == 128,\n              \"Bad SharedSignal size.\");\n\n\n#define SIGNAL_PREALLOC_BLOCKS 512 //16K Signals\n\n/// @brief Pool class for SharedSignal suitable for use with Shared.\nclass SharedSignalPool_t : private BaseShared {\n public:\n  SharedSignalPool_t() : block_size_(SIGNAL_PREALLOC_BLOCKS * minblock_) {}\n  ~SharedSignalPool_t() { clear(); }\n\n  SharedSignal* alloc();\n  void free(SharedSignal* ptr);\n  void clear();\n\n private:\n  static const size_t minblock_ = 4096 / sizeof(SharedSignal);\n  HybridMutex lock_;\n  std::vector<SharedSignal*> free_list_;\n  std::vector<std::pair<void*, size_t>> block_list_;\n  size_t block_size_;\n};\n\nclass LocalSignal {\n public:\n  // Temporary, for legacy tools lib support.\n  explicit LocalSignal(hsa_signal_value_t initial_value) {\n    local_signal_.shared_object()->amd_signal.value = initial_value;\n  }\n  LocalSignal(hsa_signal_value_t initial_value, bool exportable);\n\n  SharedSignal* signal() const { return local_signal_.shared_object(); }\n\n private:\n  Shared<SharedSignal, SharedSignalPool_t> local_signal_;\n};\n\n/// @brief An abstract base class which helps implement the public hsa_signal_t\n/// type (an opaque handle) and its associated APIs. At its core, signal uses\n/// a 32 or 64 bit value. This value can be waitied on or signaled atomically\n/// using specified memory ordering semantics.\nclass Signal {\n public:\n  /// @brief Constructor Links and publishes the signal interface object.\n  explicit Signal(SharedSignal* abi_block, bool enableIPC = false)\n      : signal_(abi_block->amd_signal), async_copy_agent_(NULL), refcount_(1) {\n    assert(abi_block != nullptr && \"Signal abi_block must not be NULL\");\n\n    waiting_ = 0;\n    retained_ = 1;\n\n    if (enableIPC) {\n      abi_block->core_signal = nullptr;\n      registerIpc();\n    } else {\n      abi_block->core_signal = this;\n    }\n  }\n\n  /// @brief Interface to discard a signal handle (hsa_signal_t)\n  /// Decrements signal ref count and invokes doDestroySignal() when\n  /// Signal is no longer in use.\n  void DestroySignal() {\n    // If handle is now invalid wake any retained sleepers.\n    if (--refcount_ == 0) CasRelaxed(0, 0);\n    // Release signal, last release will destroy the object.\n    Release();\n  }\n\n  /// @brief Converts from this interface class to the public\n  /// hsa_signal_t type - an opaque handle.\n  static __forceinline hsa_signal_t Convert(Signal* signal) {\n    assert(signal != nullptr && \"Conversion on null Signal object.\");\n    const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));\n    const hsa_signal_t signal_handle = {handle};\n    return signal_handle;\n  }\n\n  /// @brief Converts from this interface class to the public\n  /// hsa_signal_t type - an opaque handle.\n  static __forceinline const hsa_signal_t Convert(const Signal* signal) {\n    assert(signal != nullptr && \"Conversion on null Signal object.\");\n    const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));\n    const hsa_signal_t signal_handle = {handle};\n    return signal_handle;\n  }\n\n  /// @brief Converts from public hsa_signal_t type (an opaque handle) to\n  /// this interface class object.\n  static __forceinline Signal* Convert(hsa_signal_t signal) {\n    if (signal.handle == 0) throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"\");\n    SharedSignal* shared = SharedSignal::Convert(signal);\n    if (!shared->IsValid())\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_SIGNAL, \"Signal handle is invalid.\");\n    if (shared->IsIPC()) {\n      Signal* ret = lookupIpc(signal);\n      if (ret == nullptr)\n        throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_SIGNAL, \"Signal handle is invalid.\");\n      return ret;\n    } else {\n      return shared->core_signal;\n    }\n  }\n\n  static Signal* DuplicateHandle(hsa_signal_t signal) {\n    if (signal.handle == 0) return nullptr;\n    SharedSignal* shared = SharedSignal::Convert(signal);\n\n    if (!shared->IsIPC()) {\n      if (!shared->IsValid()) return nullptr;\n      shared->core_signal->refcount_++;\n      shared->core_signal->Retain();\n      return shared->core_signal;\n    }\n\n    // IPC signals may only be duplicated while holding the ipcMap lock.\n    return duplicateIpc(signal);\n  }\n\n  bool IsValid() const { return refcount_ != 0; }\n\n  bool __forceinline isIPC() const { return SharedSignal::Convert(Convert(this))->IsIPC(); }\n\n  // Below are various methods corresponding to the APIs, which load/store the\n  // signal value or modify the existing signal value automically and with\n  // specified memory ordering semantics.\n  virtual hsa_signal_value_t LoadRelaxed() = 0;\n  virtual hsa_signal_value_t LoadAcquire() = 0;\n\n  virtual void StoreRelaxed(hsa_signal_value_t value) = 0;\n  virtual void StoreRelease(hsa_signal_value_t value) = 0;\n\n  virtual hsa_signal_value_t WaitRelaxed(hsa_signal_condition_t condition,\n                                         hsa_signal_value_t compare_value,\n                                         uint64_t timeout,\n                                         hsa_wait_state_t wait_hint) = 0;\n  virtual hsa_signal_value_t WaitAcquire(hsa_signal_condition_t condition,\n                                         hsa_signal_value_t compare_value,\n                                         uint64_t timeout,\n                                         hsa_wait_state_t wait_hint) = 0;\n\n  virtual void AndRelaxed(hsa_signal_value_t value) = 0;\n  virtual void AndAcquire(hsa_signal_value_t value) = 0;\n  virtual void AndRelease(hsa_signal_value_t value) = 0;\n  virtual void AndAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual void OrRelaxed(hsa_signal_value_t value) = 0;\n  virtual void OrAcquire(hsa_signal_value_t value) = 0;\n  virtual void OrRelease(hsa_signal_value_t value) = 0;\n  virtual void OrAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual void XorRelaxed(hsa_signal_value_t value) = 0;\n  virtual void XorAcquire(hsa_signal_value_t value) = 0;\n  virtual void XorRelease(hsa_signal_value_t value) = 0;\n  virtual void XorAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual void AddRelaxed(hsa_signal_value_t value) = 0;\n  virtual void AddAcquire(hsa_signal_value_t value) = 0;\n  virtual void AddRelease(hsa_signal_value_t value) = 0;\n  virtual void AddAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual void SubRelaxed(hsa_signal_value_t value) = 0;\n  virtual void SubAcquire(hsa_signal_value_t value) = 0;\n  virtual void SubRelease(hsa_signal_value_t value) = 0;\n  virtual void SubAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual hsa_signal_value_t ExchRelaxed(hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t ExchAcquire(hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t ExchRelease(hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t ExchAcqRel(hsa_signal_value_t value) = 0;\n\n  virtual hsa_signal_value_t CasRelaxed(hsa_signal_value_t expected,\n                                        hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t CasAcquire(hsa_signal_value_t expected,\n                                        hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t CasRelease(hsa_signal_value_t expected,\n                                        hsa_signal_value_t value) = 0;\n  virtual hsa_signal_value_t CasAcqRel(hsa_signal_value_t expected,\n                                       hsa_signal_value_t value) = 0;\n\n  //-------------------------\n  // implementation specific\n  //-------------------------\n  typedef void* rtti_t;\n\n  /// @brief Returns the address of the value.\n  virtual hsa_signal_value_t* ValueLocation() const = 0;\n\n  /// @brief Applies only to InterrupEvent type, returns the event used to.\n  /// Returns NULL for DefaultEvent Type.\n  virtual HsaEvent* EopEvent() = 0;\n\n  /// @brief Waits until multiple signals in the list satisfy their conditions\n  /// or a timeout is reached.\n  /// @param signal_count Number of hsa_signals in the list.\n  /// @param hsa_signals Pointer to array of HSA signals.\n  /// @param conds Pointer to array of signal conditions.\n  /// @param values Pointer to array of signal values.\n  /// @param timeout Timeout hint value.\n  /// @param wait_hint Hint about wait state.\n  /// @param satisfying_values Vector of satisfying values. If \\p wait_on_all\n  /// is false (then we are waiting on any signal in the list) this will contain\n  /// only the first satisfying value.\n  /// @param wait_on_all Wait on all signals in the list to satisfy their\n  /// conditions if true, else wait on any signal in the list to satisfy its\n  /// condition.\n  /// @return Return the index of the first signal in the list that satisfies\n  /// its condition or -1 on a timeout. Note that if \\p wait_on_all is true,\n  /// then all signals in the list satisfy their conditions, thus the index will\n  /// always be 0.\n  static uint32_t WaitMultiple(uint32_t signal_count, const hsa_signal_t* hsa_signals,\n                               const hsa_signal_condition_t* conds,\n                               const hsa_signal_value_t* values, uint64_t timeout,\n                               hsa_wait_state_t wait_hint,\n                               std::vector<hsa_signal_value_t>& satisfying_values,\n                               bool wait_on_all);\n\n  /// @brief Dedicated funtion to wait on signals that are not of type HSA_EVENTTYPE_SIGNAL\n  /// these events can only be received by calling the underlying driver (i.e via the hsaKmtWaitOnMultipleEvents_Ext\n  /// function call). We still need to have 1 signal of type HSA_EVENT_TYPE_SIGNAL attached to the list of signals\n  /// to be able to force hsaKmtWaitOnMultipleEvents_Ext to return.\n  /// @param signal_count Number of hsa_signals\n  /// @param hsa_signals Pointer to array of signals. All signals should have a valid EopEvent()\n  /// @param conds list of conditions\n  /// @param values list of values\n  /// @param satisfying_value value to be satisfied\n  /// @return index of signal that satisfies condition\n  static uint32_t WaitAnyExceptions(uint32_t signal_count, const hsa_signal_t* hsa_signals,\n                         const hsa_signal_condition_t* conds, const hsa_signal_value_t* values,\n                         hsa_signal_value_t* satisfying_value);\n\n  __forceinline bool IsType(rtti_t id) { return _IsA(id); }\n\n  /// @brief Prevents the signal from being destroyed until the matching Release().\n  void Retain() { retained_++; }\n  void Release();\n\n  /// @brief Checks if signal is currently in use by a wait API.\n  bool InWaiting() const { return waiting_ != 0; }\n\n  /// @brief Increments the waiting indicator.\n  void WaitingInc() { waiting_++; }\n\n  /// @brief Decrements the waiting indicator.\n  void WaitingDec() { waiting_--; }\n\n  // Prep for copy profiling.  Store copy agent and ready API block.\n  __forceinline void async_copy_agent(core::Agent* agent) {\n    async_copy_agent_ = agent;\n    core::SharedSignal::Convert(Convert(this))->CopyPrep();\n  }\n\n  __forceinline core::Agent* async_copy_agent() { return async_copy_agent_; }\n\n  void GetSdmaTsAddresses(uint64_t*& start, uint64_t*& end) {\n    core::SharedSignal::Convert(Convert(this))->GetSdmaTsAddresses(start, end);\n  }\n\n  // Set FetchCopyTs = true when reading time stamps from a copy operation.\n  void GetRawTs(bool FetchCopyTs, uint64_t& start, uint64_t& end) {\n    core::SharedSignal::Convert(Convert(this))->GetRawTs(FetchCopyTs, start, end);\n  }\n\n  /// @brief Structure which defines key signal elements like type and value.\n  /// Address of this struct is used as a value for the opaque handle of type\n  /// hsa_signal_t provided to the public API.\n  amd_signal_t& signal_;\n\n protected:\n  virtual ~Signal();\n\n  /// @brief Overrideable deletion function\n  virtual void doDestroySignal() { delete this; }\n\n  /// @brief Simple RTTI type checking helper\n  /// Returns true if the object can be converted to the query type via\n  /// static_cast.\n  /// Do not use directly.  Use IsType in the desired derived type instead.\n  virtual bool _IsA(rtti_t id) const = 0;\n\n  /// @variable Indicates number of runtime threads waiting on this signal.\n  /// Value of zero means no waits.\n  std::atomic<uint32_t> waiting_;\n\n  /// @variable Pointer to agent used to perform an async copy.\n  core::Agent* async_copy_agent_;\n\n private:\n  static KernelMutex ipcLock_;\n  static std::map<decltype(hsa_signal_t::handle), Signal*> ipcMap_;\n\n  static Signal* lookupIpc(hsa_signal_t signal);\n  static Signal* duplicateIpc(hsa_signal_t signal);\n\n  /// @variable Ref count of this signal's handle (see IPC APIs)\n  std::atomic<uint32_t> refcount_;\n\n  /// @variable Count of handle references and Retain() calls for this handle (see IPC APIs)\n  std::atomic<uint32_t> retained_;\n\n  void registerIpc();\n  bool deregisterIpc();\n\n  DISALLOW_COPY_AND_ASSIGN(Signal);\n};\n\n/// @brief Handle signal operations which are not for use on doorbells.\nclass DoorbellSignal : public Signal {\n public:\n  using Signal::Signal;\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t LoadRelaxed() final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t LoadAcquire() final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t WaitRelaxed(hsa_signal_condition_t condition, hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t WaitAcquire(hsa_signal_condition_t condition, hsa_signal_value_t compare_value,\n                                 uint64_t timeout, hsa_wait_state_t wait_hint) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  void AndRelaxed(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AndAcquire(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AndRelease(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AndAcqRel(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void OrRelaxed(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void OrAcquire(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void OrRelease(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void OrAcqRel(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void XorRelaxed(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void XorAcquire(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void XorRelease(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void XorAcqRel(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AddRelaxed(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AddAcquire(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AddRelease(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void AddAcqRel(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void SubRelaxed(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void SubAcquire(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void SubRelease(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  void SubAcqRel(hsa_signal_value_t value) final override { assert(false); }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t ExchRelaxed(hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t ExchAcquire(hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t ExchRelease(hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t ExchAcqRel(hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t CasRelaxed(hsa_signal_value_t expected,\n                                hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t CasAcquire(hsa_signal_value_t expected,\n                                hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t CasRelease(hsa_signal_value_t expected,\n                                hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t CasAcqRel(hsa_signal_value_t expected,\n                               hsa_signal_value_t value) final override {\n    assert(false);\n    return 0;\n  }\n\n  /// @brief This operation is illegal\n  hsa_signal_value_t* ValueLocation() const final override {\n    assert(false);\n    return NULL;\n  }\n\n  /// @brief This operation is illegal\n  HsaEvent* EopEvent() final override {\n    assert(false);\n    return NULL;\n  }\n\n protected:\n  /// @brief Disallow destroying doorbell apart from its queue.\n  void doDestroySignal() final override { assert(false); }\n};\n\nstruct hsa_signal_handle {\n  hsa_signal_t signal;\n\n  hsa_signal_handle() {}\n  hsa_signal_handle(hsa_signal_t Signal) { signal = Signal; }\n  operator hsa_signal_t() { return signal; }\n  Signal* operator->() { return core::Signal::Convert(signal); }\n};\nstatic_assert(\n    sizeof(hsa_signal_handle) == sizeof(hsa_signal_t),\n    \"hsa_signal_handle and hsa_signal_t must have identical binary layout.\");\nstatic_assert(\n    sizeof(hsa_signal_handle[2]) == sizeof(hsa_signal_t[2]),\n    \"hsa_signal_handle and hsa_signal_t must have identical binary layout.\");\n\nclass SignalGroup : public Checked<0xBD35DDDD578F091> {\n public:\n  static __forceinline hsa_signal_group_t Convert(SignalGroup* group) {\n    const hsa_signal_group_t handle = {static_cast<uint64_t>(reinterpret_cast<uintptr_t>(group))};\n    return handle;\n  }\n  static __forceinline SignalGroup* Convert(hsa_signal_group_t group) {\n    return reinterpret_cast<SignalGroup*>(static_cast<uintptr_t>(group.handle));\n  }\n\n  SignalGroup(uint32_t num_signals, const hsa_signal_t* signals);\n  ~SignalGroup() { delete[] signals; }\n\n  bool IsValid() const {\n    if (CheckedType::IsValid() && signals != NULL) return true;\n    return false;\n  }\n\n  const hsa_signal_t* List() const { return signals; }\n  uint32_t Count() const { return count; }\n\n private:\n  hsa_signal_t* signals;\n  const uint32_t count;\n  DISALLOW_COPY_AND_ASSIGN(SignalGroup);\n};\n\nclass SignalDeleter {\n public:\n  void operator()(Signal* ptr) { ptr->DestroySignal(); }\n};\nusing unique_signal_ptr = ::std::unique_ptr<core::Signal, SignalDeleter>;\n\n}  // namespace core\n}  // namespace rocr\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/svm_profiler.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022-2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_INC_SVM_PROFILER_H_\n#define HSA_RUNTME_CORE_INC_SVM_PROFILER_H_\n\n#include <vector>\n#include <string>\n#include <thread>\n#include \"core/util/os.h\"\n\nnamespace rocr {\nnamespace AMD {\n\n    class SvmProfileControl {\n    public:\n      SvmProfileControl();\n      ~SvmProfileControl();\n\n    private:\n      template <typename... Args> std::string format(const char* format, Args... arg);\n      void PollSmi();\n      static void PollSmiRun(void* profileControl);\n      int event;\n      bool exit;\n      os::Thread poll_smi_thread_;\n      std::vector<char> format_buffer;\n    };\n\n} // namespace AMD\n} // namespace rocr\n#endif // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/inc/thunk_loader.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_THUNK_LOADER_H\n#define HSA_RUNTIME_CORE_INC_THUNK_LOADER_H\n\n#include <amdgpu.h>\n#include \"hsakmt/hsakmttypes.h\"\n\nclass DtifPlatform;\ntypedef DtifPlatform* (DtifCreateFunc)(const char*);\ntypedef void (DtifDestroyFunc)();\n\nnamespace rocr {\nnamespace core {\n\n#define HSAKMT_DEF(function_name)   PFN##function_name\n#define HSAKMT_PFN(function_name)   pfn_##function_name\n#define HSAKMT_CALL(function_name)   core::Runtime::runtime_singleton_->thunkLoader()->pfn_##function_name\n\n#define DRM_DEF(function_name)   PFN##function_name\n#define DRM_PFN(function_name)   pfn_##function_name\n#define DRM_CALL(function_name)   core::Runtime::runtime_singleton_->thunkLoader()->pfn_##function_name\n\nclass ThunkLoader {\n  public:\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtOpenKFD))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtCloseKFD))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetVersion))(HsaVersionInfo* VersionInfo);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtAcquireSystemProperties))(HsaSystemProperties* SystemProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtReleaseSystemProperties))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetNodeProperties))(HSAuint32 NodeId, \\\n                                      HsaNodeProperties* NodeProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetNodeMemoryProperties))(HSAuint32 NodeId, \\\n                                      HSAuint32 NumBanks, \\\n                                      HsaMemoryProperties* MemoryProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetNodeCacheProperties))(HSAuint32 NodeId, \\\n                                      HSAuint32 ProcessorId, \\\n                                      HSAuint32 NumCaches, \\\n                                      HsaCacheProperties* CacheProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetNodeIoLinkProperties))(HSAuint32 NodeId, \\\n                                      HSAuint32 NumIoLinks, \\\n                                      HsaIoLinkProperties* IoLinkProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtCreateEvent))(HsaEventDescriptor* EventDesc, \\\n                                      bool ManualReset, \\\n                                      bool IsSignaled, \\\n                                      HsaEvent** Event);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDestroyEvent))(HsaEvent* Event);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetEvent))(HsaEvent* Event);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtResetEvent))(HsaEvent* Event);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtQueryEventState))(HsaEvent* Event, \\\n                                      HSAuint32 Milliseconds);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtWaitOnEvent))(HsaEvent* Event, \\\n                                      HSAuint32 Milliseconds);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents))(HsaEvent* Events[], \\\n                                      HSAuint32 NumEvents, \\\n                                      bool WaitOnAll, \\\n                                      HSAuint32 Milliseconds);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtCreateQueue))(HSAuint32 NodeId, \\\n                                      HSA_QUEUE_TYPE Type, \\\n                                      HSAuint32 QueuePercentage, \\\n                                      HSA_QUEUE_PRIORITY Priority, \\\n                                      void* QueueAddress, \\\n                                      HSAuint64 QueueSizeInBytes, \\\n                                      HsaEvent* Event, \\\n                                      HsaQueueResource* QueueResource);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtCreateQueueExt))(HSAuint32 NodeId, \\\n                                      HSA_QUEUE_TYPE Type, \\\n                                      HSAuint32 QueuePercentage, \\\n                                      HSA_QUEUE_PRIORITY Priority, \\\n                                      HSAuint32 SdmaEngineId, \\\n                                      void* QueueAddress, \\\n                                      HSAuint64 QueueSizeInBytes, \\\n                                      HsaEvent* Event, \\\n                                      HsaQueueResource* QueueResource);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtUpdateQueue))( HSA_QUEUEID QueueId, \\\n                                      HSAuint32 QueuePercentage, \\\n                                      HSA_QUEUE_PRIORITY Priority, \\\n                                      void* QueueAddress, \\\n                                      HSAuint64 QueueSize, \\\n                                      HsaEvent* Event);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDestroyQueue))(HSA_QUEUEID QueueId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetQueueCUMask))(HSA_QUEUEID QueueId, \\\n                                      HSAuint32 CUMaskCount, \\\n                                      HSAuint32* QueueCUMask);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetMemoryPolicy))(HSAuint32 Node, \\\n                                      HSAuint32 DefaultPolicy, \\\n                                      HSAuint32 AlternatePolicy, \\\n                                      void* MemoryAddressAlternate, \\\n                                      HSAuint64 MemorySizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtAllocMemory))(HSAuint32 PreferredNode, \\\n                                      HSAuint64 SizeInBytes, \\\n                                      HsaMemFlags MemFlags, \\\n                                      void** MemoryAddress);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtAllocMemoryAlign))(HSAuint32 PreferredNode, \\\n                                      HSAuint64 SizeInBytes, \\\n                                      HSAuint64 Alignment, \\\n                                      HsaMemFlags emFlags, \\\n                                      void** MemoryAddress);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtFreeMemory))(void* MemoryAddress, \\\n                                      HSAuint64 SizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtAvailableMemory))(HSAuint32 Node, \\\n                                      HSAuint64 *AvailableBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterMemory))(void* MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterMemoryToNodes))(void *MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes, \\\n                                      HSAuint64 NumberOfNodes, \\\n                                      HSAuint32* NodeArray);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterMemoryWithFlags))(void *MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes, \\\n                                      HsaMemFlags MemFlags);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodes))(HSAuint64 GraphicsResourceHandle, \\\n                                      HsaGraphicsResourceInfo *GraphicsResourceInfo, \\\n                                      HSAuint64 NumberOfNodes, \\\n                                      HSAuint32* NodeArray);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodesExt))(HSAuint64 GraphicsResourceHandle, \\\n                                      HsaGraphicsResourceInfo *GraphicsResourceInfo, \\\n                                      HSAuint64 NumberOfNodes, \\\n                                      HSAuint32* NodeArray, \\\n                                      HSA_REGISTER_MEM_FLAGS RegisterFlags);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtShareMemory))(void *MemoryAddress, \\\n                                      HSAuint64 SizeInBytes, \\\n                                      HsaSharedMemoryHandle *SharedMemoryHandle);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterSharedHandle))(const HsaSharedMemoryHandle *SharedMemoryHandle, \\\n                                      void **MemoryAddress, \\\n                                      HSAuint64 *SizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRegisterSharedHandleToNodes))(const HsaSharedMemoryHandle *SharedMemoryHandle, \\\n                                      void **MemoryAddress, \\\n                                      HSAuint64 *SizeInBytes, \\\n                                      HSAuint64 NumberOfNodes, \\\n                                      HSAuint32* NodeArray);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtProcessVMRead))(HSAuint32 Pid, \\\n                                      HsaMemoryRange *LocalMemoryArray, \\\n                                      HSAuint64 LocalMemoryArrayCount, \\\n                                      HsaMemoryRange *RemoteMemoryArray, \\\n                                      HSAuint64 RemoteMemoryArrayCount, \\\n                                      HSAuint64 *SizeCopied);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtProcessVMWrite))(HSAuint32 Pid, \\\n                                      HsaMemoryRange *LocalMemoryArray, \\\n                                      HSAuint64 LocalMemoryArrayCount, \\\n                                      HsaMemoryRange *RemoteMemoryArray, \\\n                                      HSAuint64 RemoteMemoryArrayCount, \\\n                                      HSAuint64 *SizeCopied);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDeregisterMemory))(void* MemoryAddress);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtMapMemoryToGPU))(void*  MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes, \\\n                                      HSAuint64* AlternateVAGPU);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtMapMemoryToGPUNodes))(void* MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes, \\\n                                      HSAuint64* AlternateVAGPU, \\\n                                      HsaMemMapFlags MemMapFlags, \\\n                                      HSAuint64 NumberOfNodes, \\\n                                      HSAuint32* NodeArray);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtUnmapMemoryToGPU))(void* MemoryAddress);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgRegister))(HSAuint32 NodeId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgUnregister))(HSAuint32 NodeId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgWavefrontControl))(HSAuint32 NodeId, \\\n                                      HSA_DBG_WAVEOP Operand, \\\n                                      HSA_DBG_WAVEMODE Mode, \\\n                                      HSAuint32 TrapId, \\\n                                      HsaDbgWaveMessage* DbgWaveMsgRing);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgAddressWatch))(HSAuint32 NodeId, \\\n                                      HSAuint32 NumWatchPoints, \\\n                                      HSA_DBG_WATCH_MODE WatchMode[], \\\n                                      void* WatchAddress[], \\\n                                      HSAuint64 WatchMask[], \\\n                                      HsaEvent* WatchEvent[]);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgEnable))(void **runtime_info, \\\n                                      HSAuint32 *data_size);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgDisable))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgGetDeviceData))(void **data, \\\n                                      HSAuint32 *n_entries, \\\n                                      HSAuint32 *entry_size);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDbgGetQueueData))(void **data, \\\n                                      HSAuint32 *n_entries, \\\n                                      HSAuint32 *entry_size, \\\n                                      bool suspend_queues);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetClockCounters))(HSAuint32 NodeId, \\\n                                      HsaClockCounters* Counters);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcGetCounterProperties))(HSAuint32 NodeId, \\\n                                      HsaCounterProperties** CounterProperties);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcRegisterTrace))(HSAuint32 NodeId, \\\n                                      HSAuint32 NumberOfCounters, \\\n                                      HsaCounter* Counters, \\\n                                      HsaPmcTraceRoot* TraceRoot);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcUnregisterTrace))(HSAuint32 NodeId, \\\n                                      HSATraceId TraceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcAcquireTraceAccess))(HSAuint32 NodeId, \\\n                                      HSATraceId TraceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcReleaseTraceAccess))(HSAuint32 NodeId, \\\n                                      HSATraceId TraceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcStartTrace))(HSATraceId TraceId, \\\n                                      void* TraceBuffer, \\\n                                      HSAuint64 TraceBufferSizeBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcQueryTrace))(HSATraceId TraceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPmcStopTrace))(HSATraceId TraceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtMapGraphicHandle))(HSAuint32 NodeId, \\\n                                      HSAuint64 GraphicDeviceHandle, \\\n                                      HSAuint64 GraphicResourceHandle, \\\n                                      HSAuint64 GraphicResourceOffset, \\\n                                      HSAuint64 GraphicResourceSize, \\\n                                      HSAuint64* FlatMemoryAddress);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtUnmapGraphicHandle))(HSAuint32 NodeId, \\\n                                      HSAuint64 FlatMemoryAddress, \\\n                                      HSAuint64 SizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetTrapHandler))(HSAuint32 NodeId, \\\n                                      void* TrapHandlerBaseAddress, \\\n                                      HSAuint64 TrapHandlerSizeInBytes, \\\n                                      void* TrapBufferBaseAddress, \\\n                                      HSAuint64 TrapBufferSizeInBytes);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetTileConfig))(HSAuint32 NodeId, \\\n                                      HsaGpuTileConfig* config);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtQueryPointerInfo))(const void* Pointer, \\\n                                      HsaPointerInfo* PointerInfo);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetMemoryUserData))(const void* Pointer,  \\\n                                      void* UserData);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetQueueInfo))(HSA_QUEUEID QueueId, \\\n                                      HsaQueueInfo *QueueInfo);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtAllocQueueGWS))(HSA_QUEUEID QueueId, \\\n                                      HSAuint32 nGWS, \\\n                                      HSAuint32 *firstGWS);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRuntimeEnable))(void* rDebug, \\\n                                      bool setupTtmp);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtRuntimeDisable))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtCheckRuntimeDebugSupport))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetRuntimeCapabilities))(HSAuint32 *caps_mask);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtDebugTrapIoctl))(struct kfd_ioctl_dbg_trap_args *arg, \\\n                                      HSA_QUEUEID *Queues, \\\n                                      HSAuint64 *DebugReturn);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSPMAcquire))(HSAuint32 PreferredNode);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSPMRelease))(HSAuint32 PreferredNode);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSPMSetDestBuffer))(HSAuint32 PreferredNode, \\\n                                      HSAuint32 SizeInBytes, \\\n                                      HSAuint32* timeout, \\\n                                      HSAuint32* SizeCopied, \\\n                                      void *DestMemoryAddress, \\\n                                      bool *isSPMDataLoss);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSVMSetAttr))(void *start_addr, \\\n                                      HSAuint64 size, \\\n                                      unsigned int nattr, \\\n                                      HSA_SVM_ATTRIBUTE *attrs);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSVMGetAttr))(void *start_addr, \\\n                                      HSAuint64 size, \\\n                                      unsigned int nattr, \\\n                                      HSA_SVM_ATTRIBUTE *attrs);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtSetXNACKMode))(HSAint32 enable);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetXNACKMode))(HSAint32 * enable);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtOpenSMI))(HSAuint32 NodeId, \\\n                                      int *fd);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtExportDMABufHandle))(void *MemoryAddress, \\\n                                      HSAuint64 MemorySizeInBytes, \\\n                                      int *DMABufFd, \\\n                                      HSAuint64 *Offset);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtWaitOnEvent_Ext))(HsaEvent* Event, \\\n                                      HSAuint32 Milliseconds, \\\n                                      uint64_t *event_age);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents_Ext))(HsaEvent* Events[], \\\n                                      HSAuint32 NumEvents, \\\n                                      bool WaitOnAll, \\\n                                      HSAuint32 Milliseconds, \\\n                                      uint64_t *event_age);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtReplaceAsanHeaderPage))(void *addr);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtReturnAsanHeaderPage))(void *addr);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtGetAMDGPUDeviceHandle))(HSAuint32 NodeId, \\\n                                      HsaAMDGPUDeviceHandle *DeviceHandle);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingQueryCapabilities))(HSAuint32 NodeId, \\\n                                      void *sample_info, \\\n                                      HSAuint32 sample_info_sz, \\\n                                      HSAuint32 *sz_needed);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingCreate))(HSAuint32 node_id, \\\n                                      HsaPcSamplingInfo *sample_info, \\\n                                      HsaPcSamplingTraceId *traceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingDestroy))(HSAuint32 NodeId, \\\n                                      HsaPcSamplingTraceId traceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingStart))(HSAuint32 NodeId, \\\n                                      HsaPcSamplingTraceId traceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingStop))(HSAuint32 NodeId, \\\n                                      HsaPcSamplingTraceId traceId);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtPcSamplingSupport))(void);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtModelEnabled))(bool* enable);\n    typedef HSAKMT_STATUS (HSAKMT_DEF(hsaKmtQueueRingDoorbell))(HSA_QUEUEID QueueId);\n\n    /* drm API */\n    typedef int (DRM_DEF(amdgpu_device_initialize))(int fd, \\\n                                      uint32_t *major_version, \\\n                                      uint32_t *minor_version, \\\n                                      amdgpu_device_handle *device_handle);\n\n    typedef int (DRM_DEF(amdgpu_device_deinitialize))(amdgpu_device_handle device_handle);\n\n    typedef int (DRM_DEF(amdgpu_query_gpu_info))(amdgpu_device_handle dev, \\\n                                      struct amdgpu_gpu_info *info);\n\n    typedef int (DRM_DEF(amdgpu_bo_cpu_map))(amdgpu_bo_handle bo, \\\n                                      void **cpu);\n\n    typedef int (DRM_DEF(amdgpu_bo_free))(amdgpu_bo_handle buf_handle);\n\n    typedef int (DRM_DEF(amdgpu_bo_export))(amdgpu_bo_handle bo, \\\n                                      enum amdgpu_bo_handle_type type, \\\n                                      uint32_t *shared_handle);\n\n    typedef int (DRM_DEF(amdgpu_bo_import))(amdgpu_device_handle dev, \\\n                                      enum amdgpu_bo_handle_type type, \\\n                                      uint32_t shared_handle, \\\n                                      struct amdgpu_bo_import_result *output);\n\n    typedef int (DRM_DEF(amdgpu_bo_va_op))(amdgpu_bo_handle bo, \\\n                                      uint64_t offset, \\\n                                      uint64_t size, \\\n                                      uint64_t addr, \\\n                                      uint64_t flags, \\\n                                      uint32_t op);\n\n    typedef int (DRM_DEF(drmCommandWriteRead))(int fd, \\\n                                      unsigned long drmCommandIndex, \\\n                                      void *data, \\\n                                      unsigned long size);\n\n    ThunkLoader();\n    ~ThunkLoader();\n\n    void LoadThunkApiTable();\n    bool CreateThunkInstance();\n    bool DestroyThunkInstance();\n\n    HSAKMT_DEF(hsaKmtOpenKFD)* HSAKMT_PFN(hsaKmtOpenKFD);\n    HSAKMT_DEF(hsaKmtCloseKFD)* HSAKMT_PFN(hsaKmtCloseKFD);\n    HSAKMT_DEF(hsaKmtGetVersion)* HSAKMT_PFN(hsaKmtGetVersion);\n    HSAKMT_DEF(hsaKmtAcquireSystemProperties)* HSAKMT_PFN(hsaKmtAcquireSystemProperties);\n    HSAKMT_DEF(hsaKmtReleaseSystemProperties)* HSAKMT_PFN(hsaKmtReleaseSystemProperties);\n    HSAKMT_DEF(hsaKmtGetNodeProperties)* HSAKMT_PFN(hsaKmtGetNodeProperties);\n    HSAKMT_DEF(hsaKmtGetNodeMemoryProperties)* HSAKMT_PFN(hsaKmtGetNodeMemoryProperties);\n    HSAKMT_DEF(hsaKmtGetNodeCacheProperties)* HSAKMT_PFN(hsaKmtGetNodeCacheProperties);\n    HSAKMT_DEF(hsaKmtGetNodeIoLinkProperties)* HSAKMT_PFN(hsaKmtGetNodeIoLinkProperties);\n    HSAKMT_DEF(hsaKmtCreateEvent)* HSAKMT_PFN(hsaKmtCreateEvent);\n    HSAKMT_DEF(hsaKmtDestroyEvent)* HSAKMT_PFN(hsaKmtDestroyEvent);\n    HSAKMT_DEF(hsaKmtSetEvent)* HSAKMT_PFN(hsaKmtSetEvent);\n    HSAKMT_DEF(hsaKmtResetEvent)* HSAKMT_PFN(hsaKmtResetEvent);\n    HSAKMT_DEF(hsaKmtQueryEventState)* HSAKMT_PFN(hsaKmtQueryEventState);\n    HSAKMT_DEF(hsaKmtWaitOnEvent)* HSAKMT_PFN(hsaKmtWaitOnEvent);\n    HSAKMT_DEF(hsaKmtWaitOnMultipleEvents)* HSAKMT_PFN(hsaKmtWaitOnMultipleEvents);\n    HSAKMT_DEF(hsaKmtCreateQueue)* HSAKMT_PFN(hsaKmtCreateQueue);\n    HSAKMT_DEF(hsaKmtCreateQueueExt)* HSAKMT_PFN(hsaKmtCreateQueueExt);\n    HSAKMT_DEF(hsaKmtUpdateQueue)* HSAKMT_PFN(hsaKmtUpdateQueue);\n    HSAKMT_DEF(hsaKmtDestroyQueue)* HSAKMT_PFN(hsaKmtDestroyQueue);\n    HSAKMT_DEF(hsaKmtSetQueueCUMask)* HSAKMT_PFN(hsaKmtSetQueueCUMask);\n    HSAKMT_DEF(hsaKmtSetMemoryPolicy)* HSAKMT_PFN(hsaKmtSetMemoryPolicy);\n    HSAKMT_DEF(hsaKmtAllocMemory)* HSAKMT_PFN(hsaKmtAllocMemory);\n    HSAKMT_DEF(hsaKmtAllocMemoryAlign)* HSAKMT_PFN(hsaKmtAllocMemoryAlign);\n    HSAKMT_DEF(hsaKmtFreeMemory)* HSAKMT_PFN(hsaKmtFreeMemory);\n    HSAKMT_DEF(hsaKmtAvailableMemory)* HSAKMT_PFN(hsaKmtAvailableMemory);\n    HSAKMT_DEF(hsaKmtRegisterMemory)* HSAKMT_PFN(hsaKmtRegisterMemory);\n    HSAKMT_DEF(hsaKmtRegisterMemoryToNodes)* HSAKMT_PFN(hsaKmtRegisterMemoryToNodes);\n    HSAKMT_DEF(hsaKmtRegisterMemoryWithFlags)* HSAKMT_PFN(hsaKmtRegisterMemoryWithFlags);\n    HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodes)* HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodes);\n    HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodesExt)* HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodesExt);\n    HSAKMT_DEF(hsaKmtShareMemory)* HSAKMT_PFN(hsaKmtShareMemory);\n    HSAKMT_DEF(hsaKmtRegisterSharedHandle)* HSAKMT_PFN(hsaKmtRegisterSharedHandle);\n    HSAKMT_DEF(hsaKmtRegisterSharedHandleToNodes)* HSAKMT_PFN(hsaKmtRegisterSharedHandleToNodes);\n    HSAKMT_DEF(hsaKmtProcessVMRead)* HSAKMT_PFN(hsaKmtProcessVMRead);\n    HSAKMT_DEF(hsaKmtProcessVMWrite)* HSAKMT_PFN(hsaKmtProcessVMWrite);\n    HSAKMT_DEF(hsaKmtDeregisterMemory)* HSAKMT_PFN(hsaKmtDeregisterMemory);\n    HSAKMT_DEF(hsaKmtMapMemoryToGPU)* HSAKMT_PFN(hsaKmtMapMemoryToGPU);\n    HSAKMT_DEF(hsaKmtMapMemoryToGPUNodes)* HSAKMT_PFN(hsaKmtMapMemoryToGPUNodes);\n    HSAKMT_DEF(hsaKmtUnmapMemoryToGPU)* HSAKMT_PFN(hsaKmtUnmapMemoryToGPU);\n    HSAKMT_DEF(hsaKmtDbgRegister)* HSAKMT_PFN(hsaKmtDbgRegister);\n    HSAKMT_DEF(hsaKmtDbgUnregister)* HSAKMT_PFN(hsaKmtDbgUnregister);\n    HSAKMT_DEF(hsaKmtDbgWavefrontControl)* HSAKMT_PFN(hsaKmtDbgWavefrontControl);\n    HSAKMT_DEF(hsaKmtDbgAddressWatch)* HSAKMT_PFN(hsaKmtDbgAddressWatch);\n    HSAKMT_DEF(hsaKmtDbgEnable)* HSAKMT_PFN(hsaKmtDbgEnable);\n    HSAKMT_DEF(hsaKmtDbgDisable)* HSAKMT_PFN(hsaKmtDbgDisable);\n    HSAKMT_DEF(hsaKmtDbgGetDeviceData)* HSAKMT_PFN(hsaKmtDbgGetDeviceData);\n    HSAKMT_DEF(hsaKmtDbgGetQueueData)* HSAKMT_PFN(hsaKmtDbgGetQueueData);\n    HSAKMT_DEF(hsaKmtGetClockCounters)* HSAKMT_PFN(hsaKmtGetClockCounters);\n    HSAKMT_DEF(hsaKmtPmcGetCounterProperties)* HSAKMT_PFN(hsaKmtPmcGetCounterProperties);\n    HSAKMT_DEF(hsaKmtPmcRegisterTrace)* HSAKMT_PFN(hsaKmtPmcRegisterTrace);\n    HSAKMT_DEF(hsaKmtPmcUnregisterTrace)* HSAKMT_PFN(hsaKmtPmcUnregisterTrace);\n    HSAKMT_DEF(hsaKmtPmcAcquireTraceAccess)* HSAKMT_PFN(hsaKmtPmcAcquireTraceAccess);\n    HSAKMT_DEF(hsaKmtPmcReleaseTraceAccess)* HSAKMT_PFN(hsaKmtPmcReleaseTraceAccess);\n    HSAKMT_DEF(hsaKmtPmcStartTrace)* HSAKMT_PFN(hsaKmtPmcStartTrace);\n    HSAKMT_DEF(hsaKmtPmcQueryTrace)* HSAKMT_PFN(hsaKmtPmcQueryTrace);\n    HSAKMT_DEF(hsaKmtPmcStopTrace)* HSAKMT_PFN(hsaKmtPmcStopTrace);\n    HSAKMT_DEF(hsaKmtMapGraphicHandle)* HSAKMT_PFN(hsaKmtMapGraphicHandle);\n    HSAKMT_DEF(hsaKmtUnmapGraphicHandle)* HSAKMT_PFN(hsaKmtUnmapGraphicHandle);\n    HSAKMT_DEF(hsaKmtSetTrapHandler)* HSAKMT_PFN(hsaKmtSetTrapHandler);\n    HSAKMT_DEF(hsaKmtGetTileConfig)* HSAKMT_PFN(hsaKmtGetTileConfig);\n    HSAKMT_DEF(hsaKmtQueryPointerInfo)* HSAKMT_PFN(hsaKmtQueryPointerInfo);\n    HSAKMT_DEF(hsaKmtSetMemoryUserData)* HSAKMT_PFN(hsaKmtSetMemoryUserData);\n    HSAKMT_DEF(hsaKmtGetQueueInfo)* HSAKMT_PFN(hsaKmtGetQueueInfo);\n    HSAKMT_DEF(hsaKmtAllocQueueGWS)* HSAKMT_PFN(hsaKmtAllocQueueGWS);\n    HSAKMT_DEF(hsaKmtRuntimeEnable)* HSAKMT_PFN(hsaKmtRuntimeEnable);\n    HSAKMT_DEF(hsaKmtRuntimeDisable)* HSAKMT_PFN(hsaKmtRuntimeDisable);\n    HSAKMT_DEF(hsaKmtCheckRuntimeDebugSupport)* HSAKMT_PFN(hsaKmtCheckRuntimeDebugSupport);\n    HSAKMT_DEF(hsaKmtGetRuntimeCapabilities)* HSAKMT_PFN(hsaKmtGetRuntimeCapabilities);\n    HSAKMT_DEF(hsaKmtDebugTrapIoctl)* HSAKMT_PFN(hsaKmtDebugTrapIoctl);\n    HSAKMT_DEF(hsaKmtSPMAcquire)* HSAKMT_PFN(hsaKmtSPMAcquire);\n    HSAKMT_DEF(hsaKmtSPMRelease)* HSAKMT_PFN(hsaKmtSPMRelease);\n    HSAKMT_DEF(hsaKmtSPMSetDestBuffer)* HSAKMT_PFN(hsaKmtSPMSetDestBuffer);\n    HSAKMT_DEF(hsaKmtSVMSetAttr)* HSAKMT_PFN(hsaKmtSVMSetAttr);\n    HSAKMT_DEF(hsaKmtSVMGetAttr)* HSAKMT_PFN(hsaKmtSVMGetAttr);\n    HSAKMT_DEF(hsaKmtSetXNACKMode)* HSAKMT_PFN(hsaKmtSetXNACKMode);\n    HSAKMT_DEF(hsaKmtGetXNACKMode)* HSAKMT_PFN(hsaKmtGetXNACKMode);\n    HSAKMT_DEF(hsaKmtOpenSMI)* HSAKMT_PFN(hsaKmtOpenSMI);\n    HSAKMT_DEF(hsaKmtExportDMABufHandle)* HSAKMT_PFN(hsaKmtExportDMABufHandle);\n    HSAKMT_DEF(hsaKmtWaitOnEvent_Ext)* HSAKMT_PFN(hsaKmtWaitOnEvent_Ext);\n    HSAKMT_DEF(hsaKmtWaitOnMultipleEvents_Ext)* HSAKMT_PFN(hsaKmtWaitOnMultipleEvents_Ext);\n    HSAKMT_DEF(hsaKmtReplaceAsanHeaderPage)* HSAKMT_PFN(hsaKmtReplaceAsanHeaderPage);\n    HSAKMT_DEF(hsaKmtReturnAsanHeaderPage)* HSAKMT_PFN(hsaKmtReturnAsanHeaderPage);\n    HSAKMT_DEF(hsaKmtGetAMDGPUDeviceHandle)* HSAKMT_PFN(hsaKmtGetAMDGPUDeviceHandle);\n    HSAKMT_DEF(hsaKmtPcSamplingQueryCapabilities)* HSAKMT_PFN(hsaKmtPcSamplingQueryCapabilities);\n    HSAKMT_DEF(hsaKmtPcSamplingCreate)* HSAKMT_PFN(hsaKmtPcSamplingCreate);\n    HSAKMT_DEF(hsaKmtPcSamplingDestroy)* HSAKMT_PFN(hsaKmtPcSamplingDestroy);\n    HSAKMT_DEF(hsaKmtPcSamplingStart)* HSAKMT_PFN(hsaKmtPcSamplingStart);\n    HSAKMT_DEF(hsaKmtPcSamplingStop)* HSAKMT_PFN(hsaKmtPcSamplingStop);\n    HSAKMT_DEF(hsaKmtPcSamplingSupport)* HSAKMT_PFN(hsaKmtPcSamplingSupport);\n    HSAKMT_DEF(hsaKmtModelEnabled)* HSAKMT_PFN(hsaKmtModelEnabled);\n    HSAKMT_DEF(hsaKmtQueueRingDoorbell)* HSAKMT_PFN(hsaKmtQueueRingDoorbell);\n\n    DRM_DEF(amdgpu_device_initialize)* DRM_PFN(amdgpu_device_initialize);\n    DRM_DEF(amdgpu_device_deinitialize)* DRM_PFN(amdgpu_device_deinitialize);\n    DRM_DEF(amdgpu_query_gpu_info)* DRM_PFN(amdgpu_query_gpu_info);\n    DRM_DEF(amdgpu_bo_cpu_map)* DRM_PFN(amdgpu_bo_cpu_map);\n    DRM_DEF(amdgpu_bo_free)* DRM_PFN(amdgpu_bo_free);\n    DRM_DEF(amdgpu_bo_export)* DRM_PFN(amdgpu_bo_export);\n    DRM_DEF(amdgpu_bo_import)* DRM_PFN(amdgpu_bo_import);\n    DRM_DEF(amdgpu_bo_va_op)* DRM_PFN(amdgpu_bo_va_op);\n    DRM_DEF(drmCommandWriteRead)* DRM_PFN(drmCommandWriteRead);\n\n  private:\n    void *dtif_handle;\n};\n\n}   //  namespace core\n}   //  namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_aie_agent.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_aie_agent.h\"\n\n#include <cstring>\n#include <functional>\n#include <string>\n\n#include \"core/inc/amd_aie_aql_queue.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/amd_xdna_driver.h\"\n#include \"core/inc/driver.h\"\n#include \"core/inc/runtime.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nAieAgent::AieAgent(uint32_t node, const HsaNodeProperties& node_props)\n    : core::Agent(core::Runtime::runtime_singleton_->AgentDriver(core::DriverType::XDNA), node,\n                  core::Agent::DeviceType::kAmdAieDevice),\n      node_props_(node_props) {\n  InitRegionList();\n  InitAllocators();\n}\n\nAieAgent::~AieAgent() {\n  std::for_each(regions_.begin(), regions_.end(), DeleteObject());\n  regions_.clear();\n}\n\nhsa_status_t AieAgent::VisitRegion(bool include_peer,\n                                   hsa_status_t (*callback)(hsa_region_t region,\n                                                            void *data),\n                                   void *data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (const auto r : regions_) {\n    hsa_region_t region_handle(core::MemoryRegion::Convert(r));\n    hsa_status_t err = call(region_handle, data);\n    if (err != HSA_STATUS_SUCCESS) {\n      return err;\n    }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AieAgent::IterateRegion(\n    hsa_status_t (*callback)(hsa_region_t region, void *data),\n    void *data) const {\n  return VisitRegion(false, callback, data);\n}\n\nhsa_status_t AieAgent::IterateCache(hsa_status_t (*callback)(hsa_cache_t cache,\n                                                             void *data),\n                                    void *data) const {\n  // AIE has no caches.\n  return HSA_STATUS_ERROR_INVALID_CACHE;\n}\n\nhsa_status_t AieAgent::IterateSupportedIsas(\n                    hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                                          void* data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (const auto& isa : supported_isas()) {\n    hsa_status_t err = call(core::Isa::Handle(isa), data);\n    if (err != HSA_STATUS_SUCCESS) return err;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AieAgent::GetInfo(hsa_agent_info_t attribute, void *value) const {\n  const size_t attribute_ = static_cast<size_t>(attribute);\n\n  switch (attribute_) {\n  case HSA_AGENT_INFO_NAME: {\n    const std::string name_info_(\"aie2\");\n    assert(name_info_.size() < HSA_PUBLIC_NAME_SIZE);\n    std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n    std::strncat(reinterpret_cast<char *>(value), name_info_.c_str(),\n                 name_info_.size());\n    break;\n  }\n  case HSA_AGENT_INFO_VENDOR_NAME: {\n    const std::string vendor_name_info_(\"AMD\");\n    assert(vendor_name_info_.size() < HSA_PUBLIC_NAME_SIZE);\n    std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n    std::strncat(reinterpret_cast<char *>(value), vendor_name_info_.c_str(),\n                 vendor_name_info_.size());\n    break;\n  }\n  case HSA_AGENT_INFO_FEATURE:\n    *((hsa_agent_feature_t *)value) = HSA_AGENT_FEATURE_AGENT_DISPATCH;\n    break;\n  case HSA_AGENT_INFO_MACHINE_MODEL:\n    *reinterpret_cast<hsa_machine_model_t *>(value) = HSA_MACHINE_MODEL_LARGE;\n    break;\n  case HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES:\n  case HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE:\n    // TODO: validate if this is true.\n    *reinterpret_cast<hsa_default_float_rounding_mode_t *>(value) =\n        HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR;\n    break;\n  case HSA_AGENT_INFO_PROFILE:\n    *reinterpret_cast<hsa_profile_t *>(value) = profile_;\n    break;\n  case HSA_AGENT_INFO_WAVEFRONT_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AGENT_INFO_WORKGROUP_MAX_DIM:\n    std::memset(value, 0, sizeof(uint16_t) * 3);\n    break;\n  case HSA_AGENT_INFO_WORKGROUP_MAX_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AGENT_INFO_GRID_MAX_DIM:\n    std::memset(value, 0, sizeof(uint16_t) * 3);\n    break;\n  case HSA_AGENT_INFO_GRID_MAX_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AGENT_INFO_FBARRIER_MAX_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AGENT_INFO_QUEUES_MAX:\n    *reinterpret_cast<uint32_t *>(value) = max_queues_;\n    break;\n  case HSA_AGENT_INFO_QUEUE_MIN_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = min_aql_size_;\n    break;\n  case HSA_AGENT_INFO_QUEUE_MAX_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = max_aql_size_;\n    break;\n  case HSA_AGENT_INFO_QUEUE_TYPE:\n    *reinterpret_cast<hsa_queue_type32_t *>(value) = HSA_QUEUE_TYPE_SINGLE;\n    break;\n  case HSA_AGENT_INFO_NODE:\n    *reinterpret_cast<uint32_t *>(value) = node_id();\n    break;\n  case HSA_AGENT_INFO_DEVICE:\n    *reinterpret_cast<hsa_device_type_t *>(value) = HSA_DEVICE_TYPE_AIE;\n    break;\n  case HSA_AGENT_INFO_CACHE_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AGENT_INFO_VERSION_MAJOR:\n    *reinterpret_cast<uint32_t *>(value) = 1;\n    break;\n  case HSA_AGENT_INFO_VERSION_MINOR:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_CHIP_ID:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_CACHELINE_SIZE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_DRIVER_NODE_ID:\n    *reinterpret_cast<uint32_t *>(value) = node_id();\n    break;\n  case HSA_AMD_AGENT_INFO_MAX_ADDRESS_WATCH_POINTS:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_BDFID:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_NUM_SHADER_ENGINES:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_NUM_SHADER_ARRAYS_PER_SE:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_1DA_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_1DB_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_2D_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_2DA_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_2DDEPTH_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_2DADEPTH_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_3D_MAX_ELEMENTS:\n  case HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_PRODUCT_NAME: {\n    const std::string product_name_info_(\"AIE-ML\");\n    assert(product_name_info_.size() < HSA_PUBLIC_NAME_SIZE);\n    std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n    std::strncat(reinterpret_cast<char *>(value), product_name_info_.c_str(),\n                 product_name_info_.size());\n    break;\n  }\n  case HSA_AMD_AGENT_INFO_UUID: {\n    // At this point AIE devices do not support UUID's.\n    char uuid_tmp[] = \"AIE-XX\";\n    snprintf((char *)value, sizeof(uuid_tmp), \"%s\", uuid_tmp);\n    break;\n  }\n  case HSA_AMD_AGENT_INFO_ASIC_REVISION:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    break;\n  case HSA_AMD_AGENT_INFO_SVM_DIRECT_HOST_ACCESS:\n    assert(regions_.size() != 0 && \"No device local memory found!\");\n    *reinterpret_cast<bool *>(value) = true;\n    break;\n  case HSA_AMD_AGENT_INFO_MEMORY_PROPERTIES:\n    std::memset(value, 0, sizeof(uint8_t) * 8);\n    break;\n  case HSA_AMD_AGENT_INFO_CLOCK_COUNTERS:\n    std::memset(value, 0, sizeof(hsa_amd_clock_counters_t));\n    break;\n  default:\n    *reinterpret_cast<uint32_t *>(value) = 0;\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AieAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                                   core::HsaEventCallback event_callback, void* data,\n                                   uint32_t private_segment_size, uint32_t group_segment_size,\n                                   core::Queue** queue) {\n  if ((flags & HSA_AMD_QUEUE_CREATE_DEVICE_MEM_RING_BUF) != 0 ||\n      (flags & HSA_AMD_QUEUE_CREATE_DEVICE_MEM_QUEUE_DESCRIPTOR) != 0) {\n    // AIE agents do not currently support queue creation in device memory.\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (!IsPowerOfTwo(size)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (size < min_aql_size_ || size > max_aql_size_) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  core::SharedQueue* shared_queue =\n      static_cast<core::SharedQueue*>(core::Runtime::runtime_singleton_->system_allocator()(\n          sizeof(core::SharedQueue), MemoryRegion::GetPageSize(), 0, node_id()));\n\n  if (!shared_queue) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  auto aql_queue(new AieAqlQueue(shared_queue, this, size, node_id(), flags));\n  if (aql_queue == nullptr) {\n    core::Runtime::runtime_singleton_->system_deallocator()(shared_queue);\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  *queue = aql_queue;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid AieAgent::InitRegionList() {\n  /// TODO: Find a way to set the other memory properties in a reasonable way.\n  ///       This should be easier once the ROCt source is incorporated into the\n  ///       ROCr source. Since the AIE itself currently has no memory regions of\n  ///       its own all memory is just the system DRAM.\n  const uint64_t total_system_memory = XdnaDriver::GetSystemMemoryByteSize();\n\n  /// For allocating kernel arguments or other objects that only need\n  /// system memory.\n  HsaMemoryProperties sys_mem_props = {};\n  sys_mem_props.HeapType = HSA_HEAPTYPE_SYSTEM;\n  sys_mem_props.SizeInBytes = total_system_memory;\n\n  /// For any other allocation, e.g., buffers.\n  HsaMemoryProperties other_mem_props = {};\n  other_mem_props.HeapType = HSA_HEAPTYPE_SYSTEM;\n  other_mem_props.SizeInBytes = total_system_memory;\n\n  /// For allocating memory for programmable device image (PDI) files. These\n  /// need to be mapped to the device so the hardware can access the PDIs.\n  HsaMemoryProperties dev_mem_props = {};\n  dev_mem_props.HeapType = HSA_HEAPTYPE_DEVICE_SVM;\n  dev_mem_props.SizeInBytes = XdnaDriver::GetDevHeapByteSize();\n\n  /// As of now the AIE devices support coarse-grain memory regions that require\n  /// explicit sync operations.\n  regions_.reserve(3);\n  regions_.push_back(\n      new MemoryRegion(false, true, false, false, true, this, sys_mem_props));\n  regions_.push_back(\n      new MemoryRegion(false, false, false, false, true, this, dev_mem_props));\n  regions_.push_back(new MemoryRegion(false, false, false, false, true, this,\n                                      other_mem_props));\n}\n\nvoid AieAgent::InitAllocators() {\n  for (const auto *region : regions()) {\n    const MemoryRegion *amd_mem_region(\n        static_cast<const MemoryRegion *>(region));\n    if (amd_mem_region->kernarg()) {\n      system_allocator_ =\n          [region](size_t size, size_t align,\n                   core::MemoryRegion::AllocateFlags alloc_flags) -> void * {\n        void *mem(nullptr);\n        return (core::Runtime::runtime_singleton_->AllocateMemory(\n                    region, size, alloc_flags, &mem) == HSA_STATUS_SUCCESS)\n                   ? mem\n                   : nullptr;\n      };\n\n      system_deallocator_ = [](void* ptr) { core::Runtime::runtime_singleton_->FreeMemory(ptr); };\n      break;\n    }\n  }\n}\n\n} // namespace AMD\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_aie_aql_queue.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_aie_aql_queue.h\"\n#include \"core/inc/amd_xdna_driver.h\"\n\n#ifdef __linux__\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <sys/stat.h>\n#endif\n\n#ifdef _WIN32\n#include <Windows.h>\n#endif\n\n#include <atomic>\n#include <cstring>\n\n#include \"core/inc/amd_xdna_driver.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nAieAqlQueue::AieAqlQueue(core::SharedQueue* shared_queue, AieAgent* agent, size_t req_size_pkts,\n                         uint32_t node_id, uint64_t flags)\n    : Queue(shared_queue, flags),\n      LocalSignal(0, false),\n      DoorbellSignal(signal()),\n      agent_(*agent),\n      active_(false) {\n  if (agent_.device_type() != core::Agent::DeviceType::kAmdAieDevice) {\n    throw AMD::hsa_exception(\n        HSA_STATUS_ERROR_INVALID_AGENT,\n        \"Attempting to create an AIE queue on a non-AIE agent.\");\n  }\n  queue_size_bytes_ = req_size_pkts * sizeof(core::AqlPacket);\n  ring_buf_ = agent_.system_allocator()(queue_size_bytes_, 4096,\n                                        core::MemoryRegion::AllocateNoFlags);\n\n  if (!ring_buf_) {\n    throw AMD::hsa_exception(\n        HSA_STATUS_ERROR_INVALID_QUEUE_CREATION,\n        \"Could not allocate a ring buffer for an AIE queue.\");\n  }\n\n  // Populate hsa_queue_t fields.\n  amd_queue_.hsa_queue.type = HSA_QUEUE_TYPE_SINGLE;\n  amd_queue_.hsa_queue.id = INVALID_QUEUEID;\n  amd_queue_.hsa_queue.doorbell_signal = Signal::Convert(this);\n  amd_queue_.hsa_queue.size = req_size_pkts;\n  amd_queue_.hsa_queue.base_address = ring_buf_;\n  // Populate AMD queue fields.\n  amd_queue_.write_dispatch_id = 0;\n  amd_queue_.read_dispatch_id = 0;\n\n  signal_.hardware_doorbell_ptr = nullptr;\n  signal_.kind = AMD_SIGNAL_KIND_DOORBELL;\n  signal_.queue_ptr = &amd_queue_;\n  active_ = true;\n\n  HsaQueueResource queue_resource = {};\n  hsa_status_t status =\n      agent_.driver().CreateQueue(node_id, HSA_QUEUE_COMPUTE_AQL, 0, HSA_QUEUE_PRIORITY_NORMAL, 0,\n                                  nullptr, queue_size_bytes_, nullptr, queue_resource);\n  if (status != HSA_STATUS_SUCCESS) {\n    throw AMD::hsa_exception(status, \"Failed to create a hardware context for an AIE queue.\");\n  }\n\n  queue_id_ = queue_resource.QueueId;\n  amd_queue_.hsa_queue.id = GetQueueId();\n}\n\nAieAqlQueue::~AieAqlQueue() {\n  AieAqlQueue::Inactivate();\n  if (ring_buf_) {\n    agent_.system_deallocator()(ring_buf_);\n  }\n  if (shared_queue_) {\n    core::Runtime::runtime_singleton_->system_deallocator()(shared_queue_);\n  }\n}\n\nhsa_status_t AieAqlQueue::Inactivate() {\n  bool active(active_.exchange(false, std::memory_order_relaxed));\n  hsa_status_t status(HSA_STATUS_SUCCESS);\n\n  if (active) {\n    agent_.driver().DestroyQueue(queue_id_);\n  }\n\n  return status;\n}\n\nhsa_status_t AieAqlQueue::SetPriority(HSA_QUEUE_PRIORITY priority) {\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid AieAqlQueue::Destroy() { delete this; }\n\n// Atomic Reads/Writes\nuint64_t AieAqlQueue::LoadReadIndexRelaxed() {\n  return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_relaxed);\n}\n\nuint64_t AieAqlQueue::LoadReadIndexAcquire() {\n  return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_acquire);\n}\n\nuint64_t AieAqlQueue::LoadWriteIndexRelaxed() {\n  return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_relaxed);\n}\n\nuint64_t AieAqlQueue::LoadWriteIndexAcquire() {\n  return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_acquire);\n}\n\nvoid AieAqlQueue::StoreWriteIndexRelaxed(uint64_t value) {\n  atomic::Store(&amd_queue_.write_dispatch_id, value,\n                std::memory_order_relaxed);\n}\n\nvoid AieAqlQueue::StoreWriteIndexRelease(uint64_t value) {\n  atomic::Store(&amd_queue_.write_dispatch_id, value,\n                std::memory_order_release);\n}\n\nuint64_t AieAqlQueue::CasWriteIndexRelaxed(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_relaxed);\n}\n\nuint64_t AieAqlQueue::CasWriteIndexAcquire(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_acquire);\n}\n\nuint64_t AieAqlQueue::CasWriteIndexRelease(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_release);\n}\n\nuint64_t AieAqlQueue::CasWriteIndexAcqRel(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_acq_rel);\n}\n\nuint64_t AieAqlQueue::AddWriteIndexRelaxed(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_relaxed);\n}\n\nuint64_t AieAqlQueue::AddWriteIndexAcquire(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_acquire);\n}\n\nuint64_t AieAqlQueue::AddWriteIndexRelease(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_release);\n}\n\nuint64_t AieAqlQueue::AddWriteIndexAcqRel(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_acq_rel);\n}\n\nvoid AieAqlQueue::StoreRelaxed(hsa_signal_value_t value) { SubmitPackets(); }\n\nvoid AieAqlQueue::SubmitPackets() {\n  if (!active_.load(std::memory_order_relaxed)) {\n    return;\n  }\n\n  auto& driver = static_cast<XdnaDriver&>(agent_.driver());\n  void* queue_base = amd_queue_.hsa_queue.base_address;\n\n  uint64_t cur_id = LoadReadIndexRelaxed();\n  const uint64_t end = LoadWriteIndexAcquire();\n  while (cur_id < end) {\n    auto* pkt = static_cast<hsa_amd_aie_ert_packet_t*>(queue_base) + cur_id;\n\n    // Get the packet header information\n    if (pkt->header.header != HSA_PACKET_TYPE_VENDOR_SPECIFIC ||\n        pkt->header.AmdFormat != HSA_AMD_PACKET_TYPE_AIE_ERT) {\n      assert(false && \"Invalid packet header\");\n    }\n\n    // Get the payload information\n    switch (pkt->opcode) {\n      case HSA_AMD_AIE_ERT_START_CU: {\n        // Iterating over future packets and seeing how many contiguous HSA_AMD_AIE_ERT_START_CU\n        // packets there are. All can be combined into a single chain.\n        uint64_t num_cont_start_cu_pkts = 1;\n        for (uint64_t peak_pkt_id = cur_id + 1; peak_pkt_id < end; peak_pkt_id++) {\n          auto* peak_pkt = static_cast<hsa_amd_aie_ert_packet_t*>(queue_base) + peak_pkt_id;\n          if (peak_pkt->opcode != HSA_AMD_AIE_ERT_START_CU) {\n            break;\n          }\n          num_cont_start_cu_pkts++;\n        }\n\n        // Call into the driver to submit from cur_id to write_dispatch_id.\n        // Submitting the command chain might create a new hardware context.\n        hsa_status_t status = driver.SubmitCmdChain(pkt, num_cont_start_cu_pkts, queue_id_,\n                                                    agent_.properties().NumNeuralCores);\n        if (status != HSA_STATUS_SUCCESS) {\n          assert(false && \"Could not submit packets\");\n        }\n\n        cur_id += num_cont_start_cu_pkts;\n        break;\n      }\n      default:\n        break;\n    }\n  }\n\n  atomic::Store(&amd_queue_.read_dispatch_id, cur_id, std::memory_order_release);\n}\n\nvoid AieAqlQueue::StoreRelease(hsa_signal_value_t value) {\n  std::atomic_thread_fence(std::memory_order_release);\n  StoreRelaxed(value);\n}\n\nhsa_status_t AieAqlQueue::GetInfo(hsa_queue_info_attribute_t attribute,\n                                  void *value) {\n  switch (attribute) {\n    case HSA_AMD_QUEUE_INFO_AGENT:\n      *static_cast<hsa_agent_t*>(value) = agent_.public_handle();\n      break;\n    case HSA_AMD_QUEUE_INFO_DOORBELL_ID:\n      // Hardware doorbell supports AQL semantics.\n      *static_cast<uint64_t*>(value) = reinterpret_cast<uint64_t>(signal_.hardware_doorbell_ptr);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AieAqlQueue::GetCUMasking(uint32_t num_cu_mask_count,\n                                       uint32_t *cu_mask) {\n  assert(false && \"AIE AQL queue does not support CU masking.\");\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t AieAqlQueue::SetCUMasking(uint32_t num_cu_mask_count,\n                                       const uint32_t *cu_mask) {\n  assert(false && \"AIE AQL queue does not support CU masking.\");\n  return HSA_STATUS_ERROR;\n}\n\nvoid AieAqlQueue::ExecutePM4(uint32_t *cmd_data, size_t cmd_size_b,\n                             hsa_fence_scope_t acquireFence,\n                             hsa_fence_scope_t releaseFence,\n                             hsa_signal_t *signal) {\n  assert(false && \"AIE AQL queue does not support PM4 packets.\");\n}\n\n} // namespace AMD\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_aql_queue.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_aql_queue.h\"\n\n#ifdef __linux__\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <sys/stat.h>\n#include <sys/syscall.h>\n#include <unistd.h>\n#endif\n\n#ifdef _WIN32\n#include <Windows.h>\n#endif\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/queue.h\"\n#include \"core/util/utils.h\"\n#include \"core/inc/registers.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/default_signal.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"core/inc/amd_gpu_pm4.h\"\n#include \"core/inc/hsa_amd_tool_int.hpp\"\n#include \"core/inc/amd_core_dump.hpp\"\n\nnamespace rocr {\nnamespace AMD {\n\n#define SCRATCH_ALT_RATIO 4\n\nAqlQueue::AqlQueue(core::SharedQueue* shared_queue, GpuAgent* agent, size_t req_size_pkts,\n                   HSAuint32 node_id, ScratchInfo& scratch, core::HsaEventCallback callback,\n                   void* err_data, uint64_t flags)\n    : Queue(shared_queue, flags, !agent->is_xgmi_cpu_gpu()),\n      LocalSignal(0, false),\n      DoorbellSignal(signal()),\n      ring_buf_(nullptr),\n      ring_buf_alloc_bytes_(0),\n      queue_id_(HSA_QUEUEID(-1)),\n      active_(false),\n      agent_(agent),\n      queue_scratch_(scratch),\n      errors_callback_(callback),\n      errors_data_(err_data),\n      pm4_ib_buf_(nullptr),\n      pm4_ib_size_b_(0x1000),\n      dynamicScratchState(0),\n      exceptionState(0),\n      suspended_(false),\n      priority_(HSA_QUEUE_PRIORITY_NORMAL),\n      exception_signal_(nullptr) {\n\n  // Queue size is a function of several restrictions.\n  const uint32_t min_pkts = ComputeRingBufferMinPkts();\n  const uint32_t max_pkts = ComputeRingBufferMaxPkts();\n\n  // Apply sizing constraints to the ring buffer.\n  uint32_t queue_size_pkts = uint32_t(req_size_pkts);\n  queue_size_pkts = Min(queue_size_pkts, max_pkts);\n  queue_size_pkts = Max(queue_size_pkts, min_pkts);\n\n  uint32_t queue_size_bytes = queue_size_pkts * sizeof(core::AqlPacket);\n  if ((queue_size_bytes & (queue_size_bytes - 1)) != 0)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_QUEUE_CREATION,\n                             \"Requested queue with non-power of two packet capacity.\\n\");\n\n  // Allocate the AQL packet ring buffer.\n  AllocRegisteredRingBuffer(queue_size_pkts);\n  if (ring_buf_ == nullptr) throw std::bad_alloc();\n  MAKE_NAMED_SCOPE_GUARD(RingGuard, [&]() { FreeQueueMemory(); });\n\n  // Fill the ring buffer with invalid packet headers.\n  // Leave packet content uninitialized to help track errors.\n  for (uint32_t pkt_id = 0; pkt_id < queue_size_pkts; ++pkt_id) {\n    (((core::AqlPacket*)ring_buf_)[pkt_id]).dispatch.header = HSA_PACKET_TYPE_INVALID;\n  }\n\n  // Zero the amd_queue_ structure to clear RPTR/WPTR before queue attach.\n  memset(&amd_queue_, 0, sizeof(amd_queue_));\n\n  // Initialize and map a HW AQL queue.\n  HsaQueueResource queue_rsrc = {0};\n  queue_rsrc.Queue_read_ptr_aql = (uint64_t*)&amd_queue_.read_dispatch_id;\n\n  // Hardware write pointer supports AQL semantics.\n  queue_rsrc.Queue_write_ptr_aql = (uint64_t*)&amd_queue_.write_dispatch_id;\n\n  // Populate amd_queue_ structure.\n  amd_queue_.hsa_queue.type = HSA_QUEUE_TYPE_MULTI;\n  amd_queue_.hsa_queue.features = HSA_QUEUE_FEATURE_KERNEL_DISPATCH;\n  amd_queue_.hsa_queue.base_address = ring_buf_;\n  amd_queue_.hsa_queue.doorbell_signal = Signal::Convert(this);\n  amd_queue_.hsa_queue.size = queue_size_pkts;\n  amd_queue_.hsa_queue.id = INVALID_QUEUEID;\n  amd_queue_.read_dispatch_id_field_base_byte_offset = uint32_t(\n      uintptr_t(&amd_queue_.read_dispatch_id) - uintptr_t(&amd_queue_));\n  // Initialize the doorbell signal structure.\n  memset(&signal_, 0, sizeof(signal_));\n  signal_.kind = AMD_SIGNAL_KIND_DOORBELL;\n  signal_.hardware_doorbell_ptr = nullptr;\n  signal_.queue_ptr = &amd_queue_;\n\n  const auto& props = agent->properties();\n  amd_queue_.max_cu_id = (props.NumFComputeCores / props.NumSIMDPerCU) - 1;\n  amd_queue_.max_wave_id = (props.MaxWavesPerSIMD * props.NumSIMDPerCU) - 1;\n\n#ifdef HSA_LARGE_MODEL\n  AMD_HSA_BITS_SET(amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_IS_PTR64,\n                   1);\n#else\n  AMD_HSA_BITS_SET(amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_IS_PTR64,\n                   0);\n#endif\n\n  // Set group and private memory apertures in amd_queue_.\n  auto& regions = agent->regions();\n\n  for (auto region : regions) {\n    const MemoryRegion* amdregion = static_cast<const AMD::MemoryRegion*>(region);\n    uint64_t base = amdregion->GetBaseAddress();\n\n    if (amdregion->IsLDS()) {\n#ifdef HSA_LARGE_MODEL\n      amd_queue_.group_segment_aperture_base_hi =\n          uint32_t(uintptr_t(base) >> 32);\n#else\n      amd_queue_.group_segment_aperture_base_hi = uint32_t(base);\n#endif\n    }\n\n    if (amdregion->IsScratch()) {\n#ifdef HSA_LARGE_MODEL\n      amd_queue_.private_segment_aperture_base_hi =\n          uint32_t(uintptr_t(base) >> 32);\n#else\n      amd_queue_.private_segment_aperture_base_hi = uint32_t(base);\n#endif\n    }\n  }\n\n  assert(amd_queue_.group_segment_aperture_base_hi != 0 && \"No group region found.\");\n\n  if (core::Runtime::runtime_singleton_->flag().check_flat_scratch()) {\n    assert(amd_queue_.private_segment_aperture_base_hi != 0 && \"No private region found.\");\n  }\n\n  if (agent_->supported_isas()[0]->GetMajorVersion() >= 11)\n    queue_scratch_.mem_alignment_size = 256;\n  else\n    queue_scratch_.mem_alignment_size = 1024;\n\n  queue_scratch_.use_once_limit = core::Runtime::runtime_singleton_->flag().scratch_single_limit();\n  if (queue_scratch_.use_once_limit > agent_->MaxScratchDevice()) {\n    fprintf(stdout, \"User specified scratch limit exceeds device limits (requested:%lu max:%lu)!\\n\",\n                    queue_scratch_.use_once_limit, agent_->MaxScratchDevice());\n    queue_scratch_.use_once_limit = agent_->MaxScratchDevice();\n  }\n\n  queue_scratch_.use_alt_limit = 0;\n\n  queue_scratch_.async_reclaim = agent_->AsyncScratchReclaimEnabled();\n  if (queue_scratch_.async_reclaim) {\n    queue_scratch_.use_once_limit = agent_->ScratchSingleLimitAsyncThreshold();\n    queue_scratch_.use_alt_limit = core::Runtime::runtime_singleton_->flag().enable_scratch_alt()\n        ? (queue_scratch_.use_once_limit / SCRATCH_ALT_RATIO)\n        : 0;\n  }\n\n  MAKE_NAMED_SCOPE_GUARD(EventGuard, [&]() {\n    ScopedAcquire<KernelMutex> _lock(&queue_lock());\n    queue_count()--;\n    if (queue_count() == 0) {\n      core::InterruptSignal::DestroyEvent(queue_event());\n      queue_event() = nullptr;\n    }\n  });\n\n  MAKE_NAMED_SCOPE_GUARD(SignalGuard, [&]() {\n    if (amd_queue_.queue_inactive_signal.handle != 0)\n      HSA::hsa_signal_destroy(amd_queue_.queue_inactive_signal);\n    if (exception_signal_ != nullptr) exception_signal_->DestroySignal();\n  });\n\n  if (core::g_use_interrupt_wait) {\n    ScopedAcquire<KernelMutex> _lock(&queue_lock());\n    queue_count()++;\n    if (queue_event() == nullptr) {\n      assert(queue_count() == 1 && \"Inconsistency in queue event reference counting found.\\n\");\n\n      queue_event() = core::InterruptSignal::CreateEvent(HSA_EVENTTYPE_SIGNAL, false);\n      if (queue_event() == nullptr)\n        throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                                 \"Queue event creation failed.\\n\");\n    }\n    auto Signal = new core::InterruptSignal(0, queue_event());\n    assert(Signal != nullptr && \"Should have thrown!\\n\");\n    amd_queue_.queue_inactive_signal = core::InterruptSignal::Convert(Signal);\n    exception_signal_ = new core::InterruptSignal(0, queue_event());\n    assert(exception_signal_ != nullptr && \"Should have thrown!\\n\");\n  } else {\n    EventGuard.Dismiss();\n    auto Signal = new core::DefaultSignal(0);\n    assert(Signal != nullptr && \"Should have thrown!\\n\");\n    amd_queue_.queue_inactive_signal = core::DefaultSignal::Convert(Signal);\n    exception_signal_ = new core::DefaultSignal(0);\n    assert(exception_signal_ != nullptr && \"Should have thrown!\\n\");\n  }\n\n  // Make sure the queue signal always has a waiting_ > 0 so that\n  // so that we call hsakmtSetEvent to force hsaKmtWaitOnEvent to return.\n  exception_signal_->WaitingInc();\n\n  // Ensure the amd_queue_ is fully initialized before creating the KFD queue.\n  // This ensures that the debugger can access the fields once it detects there\n  // is a KFD queue. The debugger may access the aperture addresses, queue\n  // scratch base, and queue type.\n\n  hsa_status_t status;\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging) {\n    queue_rsrc.ErrorReason = &exception_signal_->signal_.value;\n    status =\n        agent->driver().CreateQueue(node_id, HSA_QUEUE_COMPUTE_AQL, 100, priority_, 0, ring_buf_,\n                                    ring_buf_alloc_bytes_, queue_event(), queue_rsrc);\n  } else {\n    status = agent->driver().CreateQueue(node_id, HSA_QUEUE_COMPUTE_AQL, 100, priority_, 0,\n                                         ring_buf_, ring_buf_alloc_bytes_, NULL, queue_rsrc);\n  }\n  if (status != HSA_STATUS_SUCCESS)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                             \"Queue create failed\\n\");\n  // Complete populating the doorbell signal structure.\n  signal_.hardware_doorbell_ptr = queue_rsrc.Queue_DoorBell_aql;\n\n  // Bind Id of Queue such that is unique i.e. it is not re-used by another\n  // queue (AQL, HOST) in the same process during its lifetime.\n  amd_queue_.hsa_queue.id = this->GetQueueId();\n\n  queue_id_ = queue_rsrc.QueueId;\n  MAKE_NAMED_SCOPE_GUARD(QueueGuard, [&]() { agent_->driver().DestroyQueue(queue_id_); });\n\n  amd_queue_.scratch_max_use_index = UINT64_MAX;\n  amd_queue_.alt_scratch_max_use_index = UINT64_MAX;\n\n  // Set flag to notify CP FW that SW supports the new amd_queue_v2\n  if (agent_->AsyncScratchReclaimEnabled())\n    amd_queue_.caps |= AMD_QUEUE_CAPS_SW_ASYNC_RECLAIM;\n\n  // On the first queue creation, reserve some scratch memory on this agent.\n  agent_->ReserveScratch();\n\n  // Initialize scratch memory related entities\n  queue_scratch_.queue_retry = amd_queue_.queue_inactive_signal;\n  InitScratchSRD();\n\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging) {\n    if (AMD::hsa_amd_signal_async_handler(amd_queue_.queue_inactive_signal, HSA_SIGNAL_CONDITION_NE,\n                                          0, DynamicQueueEventsHandler<false>,\n                                          this) != HSA_STATUS_SUCCESS)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                               \"Queue event handler failed registration.\\n\");\n    if (AMD::hsa_amd_signal_async_handler(core::Signal::Convert(exception_signal_),\n                                          HSA_SIGNAL_CONDITION_NE, 0, ExceptionHandler,\n                                          this) != HSA_STATUS_SUCCESS)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                               \"Queue event handler failed registration.\\n\");\n  } else {\n    if (AMD::hsa_amd_signal_async_handler(amd_queue_.queue_inactive_signal, HSA_SIGNAL_CONDITION_NE,\n                                          0, DynamicQueueEventsHandler<true>,\n                                          this) != HSA_STATUS_SUCCESS)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                               \"Queue event handler failed registration.\\n\");\n    exceptionState = ERROR_HANDLER_DONE;\n  }\n\n  // Allocate IB for icache flushes.\n  pm4_ib_buf_ =\n      agent_->system_allocator()(pm4_ib_size_b_, 0x1000, core::MemoryRegion::AllocateExecutable);\n  if (pm4_ib_buf_ == nullptr)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES, \"PM4 IB allocation failed.\\n\");\n\n  MAKE_NAMED_SCOPE_GUARD(PM4IBGuard, [&]() { agent_->system_deallocator()(pm4_ib_buf_); });\n\n  // Set initial CU mask\n  if (!core::Runtime::runtime_singleton_->flag().cu_mask_skip_init()) SetCUMasking(0, nullptr);\n\n  active_ = true;\n\n  PM4IBGuard.Dismiss();\n  RingGuard.Dismiss();\n  QueueGuard.Dismiss();\n  EventGuard.Dismiss();\n  SignalGuard.Dismiss();\n}\n\nAqlQueue::~AqlQueue() {\n  // Remove error handler synchronously.\n  // Sequences error handler callbacks with queue destroy.\n  dynamicScratchState |= ERROR_HANDLER_TERMINATE;\n  while ((dynamicScratchState & ERROR_HANDLER_DONE) != ERROR_HANDLER_DONE) {\n    HSA::hsa_signal_store_screlease(amd_queue_.queue_inactive_signal, 0x8000000000000000ull);\n    HSA::hsa_signal_wait_relaxed(amd_queue_.queue_inactive_signal, HSA_SIGNAL_CONDITION_NE,\n                                 0x8000000000000000ull, -1ull, HSA_WAIT_STATE_BLOCKED);\n  }\n\n  // Remove kfd exception handler\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging) {\n    exceptionState |= ERROR_HANDLER_TERMINATE;\n    while ((exceptionState & ERROR_HANDLER_DONE) != ERROR_HANDLER_DONE) {\n      const uint64_t timeout_ms = 5000;\n\n      exception_signal_->StoreRelease(-1ull);\n      exception_signal_->WaitRelaxed(HSA_SIGNAL_CONDITION_NE, -1ull, timeout_ms,\n                                     HSA_WAIT_STATE_BLOCKED);\n    }\n  }\n\n  Inactivate();\n\n  if (queue_scratch_.main_queue_base) {\n    tool::notify_event_scratch_free_start(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n    agent_->ReleaseQueueMainScratch(queue_scratch_);\n    tool::notify_event_scratch_free_end(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n  }\n  if (queue_scratch_.alt_queue_base) {\n    tool::notify_event_scratch_free_start(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n    agent_->ReleaseQueueAltScratch(queue_scratch_);\n    tool::notify_event_scratch_free_end(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n  }\n\n  exception_signal_->WaitingDec();\n  exception_signal_->DestroySignal();\n  HSA::hsa_signal_destroy(amd_queue_.queue_inactive_signal);\n  FreeQueueMemory();\n\n  if (core::g_use_interrupt_wait) {\n    ScopedAcquire<KernelMutex> lock(&queue_lock());\n    queue_count()--;\n    if (queue_count() == 0) {\n      core::InterruptSignal::DestroyEvent(queue_event());\n      queue_event() = nullptr;\n    }\n  }\n  agent_->system_deallocator()(pm4_ib_buf_);\n}\n\nvoid AqlQueue::Destroy() {\n  if (amd_queue_.hsa_queue.type == HSA_QUEUE_TYPE_COOPERATIVE) {\n    agent_->GWSRelease();\n    return;\n  }\n  delete this;\n}\n\nuint64_t AqlQueue::LoadReadIndexAcquire() {\n  return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_acquire);\n}\n\nuint64_t AqlQueue::LoadReadIndexRelaxed() {\n  return atomic::Load(&amd_queue_.read_dispatch_id, std::memory_order_relaxed);\n}\n\nuint64_t AqlQueue::LoadWriteIndexAcquire() {\n  return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_acquire);\n}\n\nuint64_t AqlQueue::LoadWriteIndexRelaxed() {\n  return atomic::Load(&amd_queue_.write_dispatch_id, std::memory_order_relaxed);\n}\n\nvoid AqlQueue::StoreWriteIndexRelaxed(uint64_t value) {\n  atomic::Store(&amd_queue_.write_dispatch_id, value,\n                std::memory_order_relaxed);\n}\n\nvoid AqlQueue::StoreWriteIndexRelease(uint64_t value) {\n  atomic::Store(&amd_queue_.write_dispatch_id, value,\n                std::memory_order_release);\n}\n\nuint64_t AqlQueue::CasWriteIndexAcqRel(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_acq_rel);\n}\nuint64_t AqlQueue::CasWriteIndexAcquire(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_acquire);\n}\nuint64_t AqlQueue::CasWriteIndexRelaxed(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_relaxed);\n}\nuint64_t AqlQueue::CasWriteIndexRelease(uint64_t expected, uint64_t value) {\n  return atomic::Cas(&amd_queue_.write_dispatch_id, value, expected,\n                     std::memory_order_release);\n}\n\nuint64_t AqlQueue::AddWriteIndexAcqRel(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_acq_rel);\n}\n\nuint64_t AqlQueue::AddWriteIndexAcquire(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_acquire);\n}\n\nuint64_t AqlQueue::AddWriteIndexRelaxed(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_relaxed);\n}\n\nuint64_t AqlQueue::AddWriteIndexRelease(uint64_t value) {\n  return atomic::Add(&amd_queue_.write_dispatch_id, value,\n                     std::memory_order_release);\n}\n\nvoid AqlQueue::StoreRelaxed(hsa_signal_value_t value) {\n  if (core::Runtime::runtime_singleton_->flag().enable_dtif()) {\n    HSAKMT_CALL(hsaKmtQueueRingDoorbell(queue_id_));\n  } else {\n    // Hardware doorbell supports AQL semantics.\n    _mm_sfence();\n    *(signal_.hardware_doorbell_ptr) = uint64_t(value);\n    /* signal_ is allocated as uncached so we do not need read-back to flush WC */\n  }\n  return;\n}\n\nvoid AqlQueue::StoreRelease(hsa_signal_value_t value) {\n  std::atomic_thread_fence(std::memory_order_release);\n  StoreRelaxed(value);\n}\n\nhsa_status_t AqlQueue::GetInfo(hsa_queue_info_attribute_t attribute, void* value) {\n  switch (attribute) {\n    case HSA_AMD_QUEUE_INFO_AGENT:\n      *(reinterpret_cast<hsa_agent_t*>(value)) = agent_->public_handle();\n      break;\n    case HSA_AMD_QUEUE_INFO_DOORBELL_ID:\n      *(reinterpret_cast<uint64_t*>(value)) =\n          reinterpret_cast<uint64_t>(signal_.hardware_doorbell_ptr);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nuint32_t AqlQueue::ComputeRingBufferMinPkts() {\n  // From CP_HQD_PQ_CONTROL.QUEUE_SIZE specification:\n  //   Size of the primary queue (PQ) will be: 2^(HQD_QUEUE_SIZE+1) DWs.\n  //   Min Size is 7 (2^8 = 256 DWs) and max size is 29 (2^30 = 1 G-DW)\n  uint32_t min_bytes = 0x400;\n\n  return uint32_t(min_bytes / sizeof(core::AqlPacket));\n}\n\nuint32_t AqlQueue::ComputeRingBufferMaxPkts() {\n  // From CP_HQD_PQ_CONTROL.QUEUE_SIZE specification:\n  //   Size of the primary queue (PQ) will be: 2^(HQD_QUEUE_SIZE+1) DWs.\n  //   Min Size is 7 (2^8 = 256 DWs) and max size is 29 (2^30 = 1 G-DW)\n  uint64_t max_bytes = 0x100000000;\n\n  return uint32_t(max_bytes / sizeof(core::AqlPacket));\n}\n\nvoid AqlQueue::AllocRegisteredRingBuffer(uint32_t queue_size_pkts) {\n  // Allocate storage for the ring buffer.\n  ring_buf_alloc_bytes_ = queue_size_pkts * sizeof(core::AqlPacket);\n  assert(IsMultipleOf(ring_buf_alloc_bytes_, 4096) && \"Ring buffer sizes must be 4KiB aligned.\");\n\n  if (IsDeviceMemRingBuf()) {\n    if (!agent_->LargeBarEnabled()) {\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_QUEUE_CREATION,\n                                \"Trying to allocate an AQL ring buffer in device memory without \"\n                                \"large BAR PCIe enabled.\");\n    }\n    ring_buf_ = agent_->coarsegrain_allocator()(\n        ring_buf_alloc_bytes_,\n        core::MemoryRegion::AllocateExecutable | core::MemoryRegion::AllocateUncached);\n  } else {\n    ring_buf_ = agent_->system_allocator()(\n        ring_buf_alloc_bytes_, 0x1000,\n        core::MemoryRegion::AllocateExecutable);\n  }\n\n  assert(ring_buf_ != NULL && \"AQL queue memory allocation failure\");\n}\n\nvoid AqlQueue::FreeQueueMemory() {\n  if (shared_queue_) {\n    if (IsDeviceMemQueueDescriptor())\n      agent_->coarsegrain_deallocator()(shared_queue_);\n    else\n      core::Runtime::runtime_singleton_->system_deallocator()(shared_queue_);\n\n    shared_queue_ = nullptr;\n  }\n\n  if (ring_buf_) {\n    if (IsDeviceMemRingBuf()) {\n      agent_->coarsegrain_deallocator()(ring_buf_);\n    } else {\n      agent_->system_deallocator()(ring_buf_);\n    }\n  }\n\n  ring_buf_ = NULL;\n  ring_buf_alloc_bytes_ = 0;\n}\n\nvoid AqlQueue::CloseRingBufferFD(const char* ring_buf_shm_path, int fd) const {\n#ifdef __linux__\n#if !defined(HAVE_MEMFD_CREATE)\n  shm_unlink(ring_buf_shm_path);\n#endif\n  close(fd);\n#else\n  assert(false && \"Function only needed on Linux.\");\n#endif\n}\n\nint AqlQueue::CreateRingBufferFD(const char* ring_buf_shm_path,\n                                 uint32_t ring_buf_phys_size_bytes) const {\n#ifdef __linux__\n  int fd;\n#ifdef HAVE_MEMFD_CREATE\n  fd = syscall(__NR_memfd_create, ring_buf_shm_path, 0);\n\n  if (fd == -1) return -1;\n\n  if (ftruncate(fd, ring_buf_phys_size_bytes) == -1) {\n    CloseRingBufferFD(ring_buf_shm_path, fd);\n    return -1;\n  }\n#else\n  fd = shm_open(ring_buf_shm_path, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);\n\n  if (fd == -1) return -1;\n\n  if (posix_fallocate(fd, 0, ring_buf_phys_size_bytes) != 0) {\n    CloseRingBufferFD(ring_buf_shm_path, fd);\n    return -1;\n  }\n#endif\n  return fd;\n#else\n  assert(false && \"Function only needed on Linux.\");\n  return -1;\n#endif\n}\n\nvoid AqlQueue::Suspend() {\n  suspended_ = true;\n  auto err =\n      agent_->driver().UpdateQueue(queue_id_, 0, priority_, ring_buf_, ring_buf_alloc_bytes_, NULL);\n  assert(err == HSA_STATUS_SUCCESS && \"Update queue failed.\");\n}\n\nvoid AqlQueue::Resume() {\n  if (suspended_) {\n    suspended_ = false;\n    auto err = agent_->driver().UpdateQueue(queue_id_, 100, priority_, ring_buf_,\n                                            ring_buf_alloc_bytes_, NULL);\n    assert(err == HSA_STATUS_SUCCESS && \"Update queue failed.\");\n  }\n}\n\nhsa_status_t AqlQueue::Inactivate() {\n  bool active = active_.exchange(false, std::memory_order_relaxed);\n  if (active) {\n    auto err = agent_->driver().DestroyQueue(queue_id_);\n    assert(err == HSA_STATUS_SUCCESS && \"Destroy queue failed.\");\n    atomic::Fence(std::memory_order_acquire);\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AqlQueue::SetPriority(HSA_QUEUE_PRIORITY priority) {\n  if (suspended_) {\n    return HSA_STATUS_ERROR_INVALID_QUEUE;\n  }\n\n  priority_ = priority;\n  auto err = agent_->driver().UpdateQueue(queue_id_, 100, priority_, ring_buf_,\n                                          ring_buf_alloc_bytes_, NULL);\n  return (err == HSA_STATUS_SUCCESS ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_OUT_OF_RESOURCES);\n}\n\nvoid AqlQueue::CheckScratchLimits() {\n  auto& scratch = queue_scratch_;\n  if (!scratch.async_reclaim) return;\n\n  scratch.use_once_limit = agent_->ScratchSingleLimitAsyncThreshold();\n  scratch.use_alt_limit = core::Runtime::runtime_singleton_->flag().enable_scratch_alt()\n      ? (scratch.use_once_limit / SCRATCH_ALT_RATIO)\n      : 0;\n\n  if (scratch.main_size > scratch.use_once_limit)\n    AsyncReclaimMainScratch();\n\n  if (scratch.alt_size > scratch.use_alt_limit)\n    AsyncReclaimAltScratch();\n\n  return;\n}\n\nvoid AqlQueue::FreeMainScratchSpace() {\n  auto& scratch = queue_scratch_;\n  if (queue_scratch_.main_queue_base) {\n    tool::notify_event_scratch_free_start(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n    agent_->ReleaseQueueMainScratch(scratch);\n    tool::notify_event_scratch_free_end(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n  }\n  scratch.main_size = 0;\n  scratch.main_size_per_thread = 0;\n  scratch.main_queue_process_offset = 0;\n  InitScratchSRD();\n}\n\nvoid AqlQueue::AsyncReclaimMainScratch() {\n  /*\n   * Pseudocode for scratch memory management when asynchronous scratch is\n   * supported\n   *\n   * Notes:\n   * - CP FW only updates its copy of amd_queue_ (scratch_copy) on queue_connect\n   * so changes to amd_queue_ by ROCr are only visible to CP FW after a queue\n   * re-map.\n   *\n   * - CP sets AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM bit to indicate that this version\n   * of CP FW supports asynchronous scratch reclaim. But CP will only update\n   * amd_queue_.caps on queue-connect so ROCr assumes that async scratch reclaim\n   * is supported based on the CP FW version.\n   *\n   * - ROCR sets AMD_QUEUE_CAPS_SW_ASYNC_RECLAIM bit to indicate to CP that this\n   * version of FW supports asynchronous scratch and therefore CP is allowed to\n   * access the extra fields that exist in amd_queue_v2.\n   *\n   * CP FW Pseudocode:\n   * On doorbell-ring:\n   * <start>\n   *    Start processing AQL dispatch packet at read_index\n   *    if (packet->private_segment_size > 0) {\n   *      // This dispatch needs scratch\n   *      if (packet->private_segment_size <= scratch_copy.scratch_wave64_lane_byte_size) {\n   *         if (read_index <= scratch_max_use_index) {\n   *           scratch_copy->scratch_last_used_index = current_index\n   *           dispatch-uses-primary-scratch\n   *           goto proceed-with-dispatch\n   *         }\n   *      } else if (packet->private_segment_size <= scratch_copy.alt_scratch_wave64_lane_byte_size\n   *              && packet->grid_size_x <= scratch_copy.alt_scratch_dispatch_limit_x\n   *              && packet->grid_size_y <= scratch_copy.alt_scratch_dispatch_limit_y\n   *              && packet->grid_size_z <= scratch_copy.alt_scratch_dispatch_limit_z) {\n   *         if (read_index <= alt_scratch_max_use_index) {\n   *           scratch_copy->alt_scratch_last_used_index = current_index\n   *           dispatch-uses-alternate-scratch\n   *           goto proceed-with-dispatch\n   *         }\n   *      }\n   *      request-more-scratch\n   *    }\n   *    goto proceed-with-dispatch\n   * <end>\n   *\n   * On queue-connect:\n   * <start>\n   *    set AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM to indicate that this version of CP\n   *    FW supports asynchronous scratch reclaim\n   * <end>\n   *\n   * On queue-disconnect:\n   * <start>\n   *     // This guarantees that ROCr sees updated values of scratch_last_used_index\n   *     // and alt_scratch_last_used_index after queue is unmapped.\n   *     queue->scratch_last_used_index= scratch_copy->scratch_last_used_index\n   *     queue->alt_scratch_last_used_index= scratch_copy->alt_scratch_last_used_index\n   * <end>\n   *\n   * ROCr Pseudocode:\n   * On init:\n   *     queue->scratch_max_use_index = UINT64_MAX\n   *     queue->alt_scratch_max_use_index = UINT64_MAX\n   *\n   * To reclaim scratch:\n   * <start>\n   *      // mutex blocks async-thread in case CP raises signal to request more scratch\n   *     acquire(scratch-mutex)\n   *     queue-unmap\n   *     // Tell CP that it cannot use scratch after current packet\n   *     queue->scratch_last_used_index = max(amd_queue_->scratch_last_used_index_per_xcc[])\n   *\n   *     queue-map\n   *     // wait for CP to finish current packet\n   *     while (queue->max_scratch_use_index >= queue->read_dispatch_id)\n   *         sched_yield();\n   *\n   *     free-scratch\n   *     release(scratch-mutex)\n   * <end>\n   */\n  auto getMaxMainScratchUseIndex = [&]() {\n    uint64_t max = 0;\n    for (int i = 0; i < agent_->properties().NumXcc; i++) {\n      if (amd_queue_.scratch_last_used_index[i].main > max)\n        max = amd_queue_.scratch_last_used_index[i].main;\n    }\n    return max;\n  };\n\n  auto& scratch = queue_scratch_;\n  if (!scratch.async_reclaim || !scratch.main_size) {\n    return;\n  }\n\n  assert((amd_queue_.caps & AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM) &&\n          \"This version of CP FW should support async scratch, but flag is not set\");\n\n  tool::notify_event_scratch_async_reclaim_start(public_handle(),\n                                                 HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n\n  // Unmap the queue. CP will check amd_queue_ fields on re-map\n  Suspend();\n\n  /*\n   * amd_queue_.scratch_last_used_index[*].main is updated by CP FW every time a\n   * dispatch packet is launched and it needs scratch memory.\n   * If amd_queue_.scratch_last_used_index[*].main >= amd_queue_.read_dispatch_id\n   * then this XCC is currently running a dispatch that uses scratch.\n   * Setting max_scratch_use_index to max(amd_queue_.scratch_last_used_index[*].main)\n   * prevents CP from trying to use main-scratch after\n   * amd_queue_.scratch_max_use_index. If CP sees a dispatch that needs scratch,\n   * it will raise a new signal. CP may use alt-scratch in the meantime.\n   */\n  amd_queue_.scratch_max_use_index = getMaxMainScratchUseIndex();\n\n  Resume();\n\n  // If current dispatch is using scratch, wait for it to finish\n  while (amd_queue_.scratch_max_use_index >= LoadReadIndexRelaxed()) {\n    //TODO: if mwaitx supported, //mwaitx(amd_queue_.read_dispatch_id);\n    os::YieldThread();\n  }\n\n  FreeMainScratchSpace();\n  tool::notify_event_scratch_async_reclaim_end(public_handle(),\n                                                HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n\n  return;\n}\n\nvoid AqlQueue::FreeAltScratchSpace() {\n  auto& scratch = queue_scratch_;\n  if (queue_scratch_.alt_queue_base) {\n    tool::notify_event_scratch_free_start(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n    agent_->ReleaseQueueAltScratch(scratch);\n    tool::notify_event_scratch_free_end(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n  }\n  scratch.alt_size = 0;\n  scratch.alt_size_per_thread = 0;\n  scratch.alt_queue_process_offset = 0;\n  InitScratchSRD();\n}\n\nvoid AqlQueue::AsyncReclaimAltScratch() {\n  /*\n   * See AsyncReclaimMainScratch() for scratch reclaim handshake protocol with\n   * CP FW.\n   */\n  auto getMaxAltScratchUseIndex = [&]() {\n    uint64_t max = 0;\n    for (int i = 0; i < agent_->properties().NumXcc; i++) {\n      if (amd_queue_.scratch_last_used_index[i].alt > max)\n        max = amd_queue_.scratch_last_used_index[i].alt;\n    }\n    return max;\n  };\n\n  auto& scratch = queue_scratch_;\n  if (!scratch.async_reclaim || !scratch.alt_size) {\n    return;\n  }\n\n  assert((amd_queue_.caps & AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM) &&\n          \"This version of CP FW should support async scratch, but flag is not set\");\n\n  tool::notify_event_scratch_async_reclaim_start(public_handle(),\n                                                 HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n\n  // Unmap the queue. CP will check amd_queue_ fields on re-map\n  Suspend();\n\n  amd_queue_.alt_scratch_max_use_index = getMaxAltScratchUseIndex();\n\n  Resume();\n\n  // If current dispatch is using alt scratch, wait for it to finish\n  while (amd_queue_.alt_scratch_max_use_index >= LoadReadIndexRelaxed()) {\n    //TODO: if mwaitx supported, //mwaitx(amd_queue_.read_dispatch_id);\n    os::YieldThread();\n  }\n\n  FreeAltScratchSpace();\n  tool::notify_event_scratch_async_reclaim_end(public_handle(),\n                                                HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n  return;\n}\n\nvoid AqlQueue::HandleInsufficientScratch(hsa_signal_value_t& error_code,\n                                         hsa_signal_value_t& waitVal, bool& changeWait) {\n  // Insufficient scratch - recoverable, don't process dynamic scratch if errors are present.\n  auto& scratch = queue_scratch_;\n\n  /*******************************************************************************************\n   * uint32_t max_scratch_slots;   // Maximum number of slots for this device based on num CUs\n   * uint64_t dispatch_slots;      // Number of slots wanted for this dispatch\n   *\n   * uint64_t all_slots_size;      // Size needed to fill all slots on this device\n   * uint64_t dispatch_size;       // Size needed to fill wanted slots for this dispatch\n   *\n   * //Default values:\n   * size_t use_once_limit = 128 MB      // When async reclaim not supported\n   *                                     // DEFAULT_SCRATCH_SINGLE_LIMIT\n   *                       = 3GB per-XCC // When async reclaim is supported\n   *                                     // DEFAULT_SCRATCH_SINGLE_LIMIT_ASYNC_PER_XCC\n   *\n   * size_t use_alt_limit  = 768 MB per-XCC // use_once_limit/SCRATCH_ALT_RATIO\n   *\n   * if (async-scratch-reclaim-supported\n   *     && dispatch_slots < max_scratch_slots\n   *     && dispatch_size < use_alt_limit) {\n   *   // This dispatch wants less waves than number of slots, use alternate scratch\n   *   // alt_tmpring_size will have limited waves\n   *  use_alt()\n   * } else if (all_slots_size <= use_once_limit) {\n   *  use_main()\n   *\n   *  //If we failed to allocate memory to fill all slots, scratch.use_once will be set\n   *  if (scratch.use_once) {\n   *    use_once\n   *  } else if (all_slots_size > scratch.alt_size) {\n   *    //Primary scratch is large enough to handle needs of alt-scratch\n   *    free_alt()\n   *  }\n   * }\n   *\n   *******************************************************************************************/\n\n  core::AqlPacket *pkt = NULL;\n  uint64_t dispatch_id = UINT64_MAX;\n\n  auto get_dispatch_pkt = [&]() {\n    dispatch_id = amd_queue_.read_dispatch_id;\n    do {\n      // On GPUs where EOP is handled in asic, the read_dispatch_id is not\n      // updated after each packet so look for the first dispatch that needs\n      // scratch\n      const uint64_t pkt_slot_idx =\n          dispatch_id & (amd_queue_.hsa_queue.size - 1);\n\n      core::AqlPacket *dispatch_pkt =\n          &((core::AqlPacket *)amd_queue_.hsa_queue.base_address)[pkt_slot_idx];\n      if (dispatch_pkt->IsDispatchAndNeedsScratch()) return dispatch_pkt;\n\n      dispatch_id++;\n    } while (dispatch_id <= LoadWriteIndexRelaxed());\n\n    return (core::AqlPacket *)NULL;\n  };\n\n  auto calc_dispatch_waves_per_group = [&](core::AqlPacket& pkt) {\n    const uint64_t lanes_per_group =\n        (uint64_t(pkt.dispatch.workgroup_size_x) * pkt.dispatch.workgroup_size_y) *\n        pkt.dispatch.workgroup_size_z;\n\n    const uint32_t lanes_per_wave = (error_code & 0x400) ? 32 : 64;\n    return (lanes_per_group + lanes_per_wave - 1) / lanes_per_wave;\n  };\n\n  auto calc_dispatch_groups = [&](core::AqlPacket& pkt) {\n    const uint64_t lanes_per_group =\n        (uint64_t(pkt.dispatch.workgroup_size_x) * pkt.dispatch.workgroup_size_y) *\n        pkt.dispatch.workgroup_size_z;\n\n    uint64_t groups = ((uint64_t(pkt.dispatch.grid_size_x) + pkt.dispatch.workgroup_size_x - 1) /\n                       pkt.dispatch.workgroup_size_x) *\n                      ((uint64_t(pkt.dispatch.grid_size_y) + pkt.dispatch.workgroup_size_y - 1) /\n                       pkt.dispatch.workgroup_size_y) *\n                      ((uint64_t(pkt.dispatch.grid_size_z) + pkt.dispatch.workgroup_size_z - 1) /\n                       pkt.dispatch.workgroup_size_z);\n    const uint32_t cu_count = amd_queue_.max_cu_id + 1;\n\n    const uint32_t engines = agent_->properties().NumShaderBanks;\n\n    const uint32_t symmetric_cus = AlignDown(cu_count, engines);\n    const uint32_t asymmetryPerRound = cu_count - symmetric_cus;\n    const uint64_t rounds = groups / cu_count;\n    const uint64_t asymmetricGroups = rounds * asymmetryPerRound;\n    const uint64_t symmetricGroups = groups - asymmetricGroups;\n    uint64_t maxGroupsPerEngine =\n        ((symmetricGroups + engines - 1) / engines) + (asymmetryPerRound ? rounds : 0);\n\n    // For gfx10+ devices we must attempt to assign the smaller of 256 lanes or 16 groups to each\n    // engine.\n    if (agent_->supported_isas()[0]->GetMajorVersion() >= 10 &&\n        maxGroupsPerEngine < 16 &&\n                              lanes_per_group * maxGroupsPerEngine < 256) {\n      uint64_t groups_per_interleave = (256 + lanes_per_group - 1) / lanes_per_group;\n      maxGroupsPerEngine = Min(groups_per_interleave, 16ul);\n    }\n\n    // Populate all engines at max group occupancy, then clip down to device limits.\n    return maxGroupsPerEngine * engines;\n  };\n\n  // TODO: Move this to queue constructor since it does not depend on pkt, must be re-computed if\n  // CU Masking is enabled\n  auto calc_device_slots = [&]() {\n    // Get the hw maximum scratch slot count taking into consideration asymmetric harvest.\n    const uint32_t engines = agent_->properties().NumShaderBanks;\n    const uint32_t cu_count = amd_queue_.max_cu_id + 1;\n    return AlignUp(cu_count, engines) * agent_->properties().MaxSlotsScratchCU;\n  };\n\n  assert(core::Runtime::runtime_singleton_->flag().enable_scratch_async_reclaim() &&\n         (!scratch.async_reclaim || (amd_queue_.caps & AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM)) &&\n          \"Asynchronous scratch reclaim capability not set, but this FW version should support it\");\n\n  scratch.cooperative = (amd_queue_.hsa_queue.type == HSA_QUEUE_TYPE_COOPERATIVE);\n\n  pkt = get_dispatch_pkt(); // Sets dispatch_id\n  assert((pkt && dispatch_id != UINT64_MAX) &&\n         \"Could not find dispatch packet with private_segment_size > 0\");\n\n  tool::notify_event_scratch_alloc_start(\n      public_handle(), HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE, dispatch_id);\n\n  uint32_t device_slots = calc_device_slots();\n  uint32_t groups = calc_dispatch_groups(*pkt);\n  uint32_t waves_per_group = calc_dispatch_waves_per_group(*pkt);\n\n  uint32_t dispatch_slots = groups * waves_per_group;\n  dispatch_slots = std::min(dispatch_slots, device_slots);\n\n  const uint64_t lanes_per_wave = (error_code & 0x400) ? 32 : 64;\n\n  const uint64_t size_per_thread =\n      AlignUp(pkt->dispatch.private_segment_size,\n              scratch.mem_alignment_size / lanes_per_wave);\n  const uint64_t device_size = size_per_thread * lanes_per_wave * device_slots;\n  const uint64_t dispatch_size = size_per_thread * lanes_per_wave * dispatch_slots;\n\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n\n  // scratch.use_alt_limit will be 0 if alt scratch is not supported or disabled\n  if (dispatch_size < scratch.use_alt_limit && dispatch_slots < device_slots) {\n    // Try to use ALT scratch\n    if (scratch.alt_queue_base) {\n      tool::notify_event_scratch_free_start(public_handle(),\n                                HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n      agent_->ReleaseQueueAltScratch(scratch);\n      tool::notify_event_scratch_free_end(public_handle(),\n                                HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n    }\n\n    scratch.alt_size = dispatch_size;\n    scratch.alt_size_per_thread = size_per_thread;\n    scratch.alt_lanes_per_wave = lanes_per_wave;\n    scratch.alt_waves_per_group = waves_per_group;\n\n    agent_->AcquireQueueAltScratch(scratch);\n    if (scratch.alt_queue_base) {\n      scratch.alt_dispatch_limit_x = pkt->dispatch.grid_size_x;\n      scratch.alt_dispatch_limit_y = pkt->dispatch.grid_size_y;\n      scratch.alt_dispatch_limit_z = pkt->dispatch.grid_size_z;\n\n      InitScratchSRD();\n      /*\n       * Indicate to CP FW that any dispatch may use alt scratch memory.\n       * If ROCr wants to reclain scratch memory, it will set\n       * amd_queue_.alt_scratch_max_use_index to a lower value\n       */\n      amd_queue_.alt_scratch_max_use_index = UINT64_MAX;\n      // Restart the queue.\n      HSA::hsa_signal_store_screlease(amd_queue_.queue_inactive_signal, 0);\n      tool::notify_event_scratch_alloc_end(public_handle(), HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT,\n                                           dispatch_id, scratch.alt_size, dispatch_slots);\n      return;\n    }\n    // Could not allocate enough memory for alternate scratch fallback to primary scratch\n    scratch.alt_size = 0;\n    scratch.alt_size_per_thread = 0;\n  }\n\n  // Use PRIMARY scratch\n  if (scratch.main_queue_base) {\n    tool::notify_event_scratch_free_start(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n    agent_->ReleaseQueueMainScratch(scratch);\n    tool::notify_event_scratch_free_end(public_handle(),\n                              HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE);\n  }\n\n  scratch.main_size = device_size;\n  scratch.main_size_per_thread = size_per_thread;\n  scratch.main_lanes_per_wave = lanes_per_wave;\n  scratch.main_waves_per_group = waves_per_group;\n\n  scratch.dispatch_size = dispatch_size;\n  scratch.dispatch_slots = dispatch_slots;\n\n  agent_->AcquireQueueMainScratch(scratch);\n\n  if (scratch.retry) {\n    dynamicScratchState |= ERROR_HANDLER_SCRATCH_RETRY;\n    changeWait = true;\n    waitVal = error_code;\n  } else if (scratch.main_queue_base == nullptr) {\n    // We could not allocate memory to fit even 1 wave\n    tool::notify_event_scratch_alloc_end(public_handle(), HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_USE_ONCE,\n                                         dispatch_id, scratch.main_size, dispatch_slots);\n    return;\n  }\n\n  // If we had to reduce number of waves\n  if (scratch.large) {\n    amd_queue_.queue_properties |= AMD_QUEUE_PROPERTIES_USE_SCRATCH_ONCE;\n    // Set system release fence to flush scratch stores with older firmware versions.\n    if ((agent_->supported_isas()[0]->GetMajorVersion() == 8) && (agent_->GetMicrocodeVersion() < 729)) {\n      pkt->dispatch.header &=\n          ~(((1 << HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE) - 1)\n            << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n      pkt->dispatch.header |=\n          (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n    }\n  } else if (scratch.alt_size && scratch.main_size > scratch.alt_size) {\n    // Not using use-scratch-once, and dispatches that would fit in alt-scratch would also fit in\n    // main scratch. No need for alt-scratch.\n    tool::notify_event_scratch_async_reclaim_start(public_handle(),\n                                                 HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n    FreeAltScratchSpace();\n    tool::notify_event_scratch_async_reclaim_end(public_handle(),\n                                                 HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT);\n  }\n\n  // Reset scratch memory related entities for the queue\n  InitScratchSRD();\n  /*\n   * Indicate to CP FW that any dispatch may use alt scratch memory.\n   * If ROCr wants to reclain scratch memory, it will set\n   * amd_queue_.alt_scratch_max_use_index to a lower value\n   */\n  amd_queue_.scratch_max_use_index = UINT64_MAX;\n\n  // Restart the queue.\n  HSA::hsa_signal_store_screlease(amd_queue_.queue_inactive_signal, 0);\n\n  auto alloc_flag = (scratch.large) ? HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_USE_ONCE\n                                    : HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE;\n\n  tool::notify_event_scratch_alloc_end(public_handle(), alloc_flag, dispatch_id, scratch.main_size,\n                                       dispatch_slots);\n\n  return;\n}\n\ntemplate <bool HandleExceptions>\nbool AqlQueue::DynamicQueueEventsHandler(hsa_signal_value_t error_code, void* arg) {\n  AqlQueue* queue = (AqlQueue*)arg;\n  hsa_status_t errorCode = HSA_STATUS_SUCCESS;\n  bool fatal = false;\n  bool changeWait = false;\n  hsa_signal_value_t waitVal;\n\n  if ((queue->dynamicScratchState & ERROR_HANDLER_SCRATCH_RETRY) == ERROR_HANDLER_SCRATCH_RETRY) {\n    queue->dynamicScratchState &= ~ERROR_HANDLER_SCRATCH_RETRY;\n    changeWait = true;\n    waitVal = 0;\n    HSA::hsa_signal_and_relaxed(queue->amd_queue_.queue_inactive_signal, ~0x8000000000000000ull);\n    error_code &= ~0x8000000000000000ull;\n  }\n\n  // Process errors only if queue is not terminating.\n  if ((queue->dynamicScratchState & ERROR_HANDLER_TERMINATE) != ERROR_HANDLER_TERMINATE) {\n    if (error_code == 512) {  // Large scratch reclaim\n      tool::notify_event_scratch_free_start(queue->public_handle(),\n                                            HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_USE_ONCE);\n\n      auto& scratch = queue->queue_scratch_;\n      queue->agent_->ReleaseQueueMainScratch(scratch);\n      scratch.main_queue_base = nullptr;\n      scratch.main_size = 0;\n      scratch.main_size_per_thread = 0;\n      scratch.main_queue_process_offset = 0;\n      queue->InitScratchSRD();\n\n      HSA::hsa_signal_store_relaxed(queue->amd_queue_.queue_inactive_signal, 0);\n      // Resumes queue processing.\n      atomic::Store(&queue->amd_queue_.queue_properties,\n                    queue->amd_queue_.queue_properties & (~AMD_QUEUE_PROPERTIES_USE_SCRATCH_ONCE),\n                    std::memory_order_release);\n      atomic::Fence(std::memory_order_release);\n      tool::notify_event_scratch_free_end(queue->public_handle(),\n                                          HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_USE_ONCE);\n      return true;\n    }\n\n    // Process only one queue error.\n    if (error_code & 0x401) {  // insufficient scratch, wave64 or wave32\n      queue->HandleInsufficientScratch(error_code, waitVal, changeWait);\n\n      // Out of scratch - promote error\n      if (queue->queue_scratch_.main_queue_base == nullptr &&\n          queue->queue_scratch_.alt_queue_base == nullptr)\n        errorCode = HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n\n    } else if (HandleExceptions) {\n      if ((error_code & 2) == 2) {  // Invalid dim\n        errorCode = HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n\n      } else if ((error_code & 4) == 4) {  // Invalid group memory\n        errorCode = HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n      } else if ((error_code & 8) == 8) {  // Invalid (or NULL) code\n        errorCode = HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n\n      } else if (((error_code & 32) == 32) ||    // Invalid format: 32 is generic,\n                 ((error_code & 256) == 256)) {  // 256 is vendor specific packets\n        errorCode = HSA_STATUS_ERROR_INVALID_PACKET_FORMAT;\n\n      } else if ((error_code & 64) == 64) {  // Group is too large\n        errorCode = HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n      } else if ((error_code & 128) == 128) {  // Out of VGPRs\n        errorCode = hsa_status_t(HSA_STATUS_ERROR_OUT_OF_REGISTERS);\n\n      } else if ((error_code & 0x20000000) == 0x20000000) {  // Memory violation (>48-bit)\n        errorCode = hsa_status_t(HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION);\n\n      } else if ((error_code & 0x40000000) == 0x40000000) {  // Illegal instruction\n        errorCode = hsa_status_t(HSA_STATUS_ERROR_ILLEGAL_INSTRUCTION);\n\n      } else if ((error_code & 0x80000000) == 0x80000000) {  // Debug trap\n        errorCode = HSA_STATUS_ERROR_EXCEPTION;\n        fatal = true;\n\n      } else {  // Undefined code\n        assert(false && \"Undefined queue error code\");\n        errorCode = HSA_STATUS_ERROR;\n        fatal = true;\n      }\n    } else {\n      // Not handling exceptions, clear so that ExceptionHandler can run.\n      HSA::hsa_signal_store_relaxed(queue->amd_queue_.queue_inactive_signal, 0);\n    }\n\n    if (errorCode == HSA_STATUS_SUCCESS) {\n      if (changeWait) {\n        core::Runtime::runtime_singleton_->SetAsyncSignalHandler(\n            queue->amd_queue_.queue_inactive_signal, HSA_SIGNAL_CONDITION_NE, waitVal,\n            DynamicQueueEventsHandler<HandleExceptions>, queue);\n        return false;\n      }\n      return true;\n    }\n\n    queue->Suspend();\n    if (queue->errors_callback_ != nullptr) {\n      queue->errors_callback_(errorCode, queue->public_handle(), queue->errors_data_);\n    }\n    if (fatal) {\n      // Temporarilly removed until there is clarity on exactly what debugtrap's semantics are.\n      // assert(false && \"Fatal queue error\");\n      // std::abort();\n    }\n  }\n  // Copy here is to protect against queue being released between setting the scratch state and\n  // updating the signal value.  The signal itself is safe to use because it is ref counted rather\n  // than being released with the queue.\n  hsa_signal_t signal = queue->amd_queue_.queue_inactive_signal;\n  queue->dynamicScratchState = ERROR_HANDLER_DONE;\n  HSA::hsa_signal_store_screlease(signal, -1ull);\n  return false;\n}\n\nbool AqlQueue::ExceptionHandler(hsa_signal_value_t error_code, void* arg) {\n  struct queue_error_t {\n    uint32_t code;\n    hsa_status_t status;\n  };\n  static const queue_error_t QueueErrors[] = {\n      // EC_QUEUE_WAVE_ABORT\n      { 1, HSA_STATUS_ERROR_EXCEPTION },\n      // EC_QUEUE_WAVE_TRAP\n      { 2, HSA_STATUS_ERROR_EXCEPTION },\n      // EC_QUEUE_WAVE_MATH_ERROR\n      { 3, HSA_STATUS_ERROR_EXCEPTION },\n      // EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION\n      { 4, (hsa_status_t)HSA_STATUS_ERROR_ILLEGAL_INSTRUCTION },\n      // EC_QUEUE_WAVE_MEMORY_VIOLATION\n      { 5, (hsa_status_t)HSA_STATUS_ERROR_MEMORY_FAULT },\n      // EC_QUEUE_WAVE_APERTURE_VIOLATION\n      { 6, (hsa_status_t)HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION },\n      // EC_QUEUE_PACKET_DISPATCH_DIM_INVALID\n      { 16, HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS },\n      // EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID\n      { 17, HSA_STATUS_ERROR_INVALID_ALLOCATION },\n      // EC_QUEUE_PACKET_DISPATCH_CODE_INVALID\n      { 18, HSA_STATUS_ERROR_INVALID_CODE_OBJECT },\n      // EC_QUEUE_PACKET_UNSUPPORTED\n      { 20, HSA_STATUS_ERROR_INVALID_PACKET_FORMAT },\n      // EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID\n      { 21, HSA_STATUS_ERROR_INVALID_ARGUMENT },\n      // EC_QUEUE_PACKET_DISPATCH_REGISTER_SIZE_INVALID\n      { 22, HSA_STATUS_ERROR_INVALID_ISA },\n      // EC_QUEUE_PACKET_VENDOR_UNSUPPORTED\n      { 23, HSA_STATUS_ERROR_INVALID_PACKET_FORMAT },\n      // EC_QUEUE_PREEMPTION_ERROR\n      { 31, HSA_STATUS_ERROR },\n      // EC_DEVICE_MEMORY_VIOLATION\n      { 33, (hsa_status_t)HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION },\n      // EC_DEVICE_RAS_ERROR\n      { 34, HSA_STATUS_ERROR },\n      // EC_DEVICE_FATAL_HALT\n      { 35, HSA_STATUS_ERROR },\n      // EC_DEVICE_NEW\n      { 36, HSA_STATUS_ERROR },\n      // EC_PROCESS_DEVICE_REMOVE\n      { 50, HSA_STATUS_ERROR }};\n\n  AqlQueue* queue = (AqlQueue*)arg;\n  hsa_status_t errorCode = HSA_STATUS_ERROR;\n  auto exceptionHandlerDone = [&]() {\n    Signal* signal = queue->exception_signal_;\n    queue->exceptionState = ERROR_HANDLER_DONE;\n    signal->StoreRelease(0);\n    return false;\n  };\n\n  if (queue->exceptionState == ERROR_HANDLER_TERMINATE) {\n    return exceptionHandlerDone();\n  }\n\n  for (auto& error : QueueErrors) {\n    if (error_code & (1UL << (error.code - 1))) {\n      errorCode = error.status;\n      break;\n    }\n  }\n\n  // Undefined or unexpected code\n  assert((errorCode != HSA_STATUS_ERROR) && \"Undefined or unexpected queue error code\");\n\n  // Suppress VM fault reporting.  This is more useful when reported through the system error\n  // handler.\n  if (errorCode == static_cast<hsa_status_t>(HSA_STATUS_ERROR_MEMORY_FAULT)) {\n    debug_print(\"Queue error - HSA_STATUS_ERROR_MEMORY_FAULT\\n\");\n    return exceptionHandlerDone();\n  }\n\n  // Fallback if KFD does not support GPU core dump. In this case, there core dump is\n  // generated by hsa-runtime.\n  if (!core::Runtime::runtime_singleton_->KfdVersion().supports_core_dump &&\n                queue->agent_->supported_isas()[0]->GetMajorVersion() != 11) {\n\n    if (pcs::PcsRuntime::instance()->SessionsActive())\n      fprintf(stderr, \"GPU core dump skipped because PC Sampling active\\n\");\n    else if (amd::coredump::dump_gpu_core())\n      fprintf(stderr, \"GPU core dump failed\\n\");\n    // supports_core_dump flag is overwritten to avoid generate core dump file again\n    // caught by a different exception handler. Such as VMFaultHandler.\n    core::Runtime::runtime_singleton_->KfdVersion(\n      core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging, true);\n  }\n\n  queue->Suspend();\n  if (queue->errors_callback_ != nullptr) {\n    queue->errors_callback_(errorCode, queue->public_handle(), queue->errors_data_);\n  }\n  return exceptionHandlerDone();\n}\n\nhsa_status_t AqlQueue::SetCUMasking(uint32_t num_cu_mask_count, const uint32_t* cu_mask) {\n  uint32_t cu_count;\n  agent_->GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &cu_count);\n  size_t mask_dwords = (cu_count + 31) / 32;\n  // Mask to trim the last uint32_t in cu_mask to the physical CU count\n  uint32_t tail_mask = (1 << (cu_count % 32)) - 1;\n\n  auto global_mask = core::Runtime::runtime_singleton_->flag().cu_mask(agent_->enumeration_index());\n  std::vector<uint32_t> mask;\n\n  bool clipped = false;\n\n  // num_cu_mask_count = 0 resets the CU mask.\n  if (num_cu_mask_count == 0) {\n    for (int i = 0; i < mask_dwords; i++) mask.push_back(-1);\n  } else {\n    for (int i = 0; i < num_cu_mask_count / 32; i++) mask.push_back(cu_mask[i]);\n  }\n\n  // Apply global mask to user mask\n  if (!global_mask.empty()) {\n    // Limit mask processing to smallest needed dword range\n    size_t limit = Min(global_mask.size(), mask.size(), mask_dwords);\n\n    // Check for disabling requested cus.\n    for (int i = limit; i < mask.size(); i++) {\n      if (mask[i] != 0) {\n        clipped = true;\n        break;\n      }\n    }\n\n    mask.resize(limit, 0);\n    for (size_t i = 0; i < limit; i++) {\n      clipped |= ((mask[i] & (~global_mask[i])) != 0);\n      mask[i] &= global_mask[i];\n    }\n  } else {\n    // Limit to physical CU range only\n    size_t limit = Min(mask.size(), mask_dwords);\n    mask.resize(limit, 0);\n  }\n\n  // Clip last dword to physical CU limit if necessary\n  if ((mask.size() == mask_dwords) && (tail_mask != 0)) mask[mask_dwords - 1] &= tail_mask;\n\n  // Apply mask if non-default or not queue initialization.\n  ScopedAcquire<KernelMutex> lock(&mask_lock_);\n  if ((!cu_mask_.empty()) || (num_cu_mask_count != 0) || (!global_mask.empty())) {\n\n    // Devices with WGPs must conform to even-indexed contiguous pairwise CU enablement.\n    if (agent_->supported_isas()[0]->GetMajorVersion() >= 10) {\n      for (int i = 0; i < mask.size() * 32; i += 2) {\n        uint32_t cu_pair = (mask[i / 32] >> (i % 32)) & 0x3;\n        if (cu_pair && cu_pair != 0x3) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n    }\n\n    return agent_->driver().SetQueueCUMask(queue_id_, mask.size() * 32,\n                                           reinterpret_cast<HSAuint32*>(&mask[0]));\n  }\n\n  // update current cu masking tracking.\n  cu_mask_ = std::move(mask);\n  return clipped ? (hsa_status_t)HSA_STATUS_CU_MASK_REDUCED : HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AqlQueue::GetCUMasking(uint32_t num_cu_mask_count, uint32_t* cu_mask) {\n  ScopedAcquire<KernelMutex> lock(&mask_lock_);\n  assert(!cu_mask_.empty() && \"No current cu_mask!\");\n\n  uint32_t user_dword_count = num_cu_mask_count / 32;\n  if (user_dword_count > cu_mask_.size()) {\n    memset(&cu_mask[cu_mask_.size()], 0, sizeof(uint32_t) * (user_dword_count - cu_mask_.size()));\n    user_dword_count = cu_mask_.size();\n  }\n  memcpy(cu_mask, &cu_mask_[0], sizeof(uint32_t) * user_dword_count);\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid AqlQueue::SetProfiling(bool enabled) {\n  Queue::SetProfiling(enabled);\n\n  if (enabled) agent_->CheckClockTicks();\n  return;\n}\n\n// If in_signal is NULL then this ExecutePM4 will block and wait for PM4 commands to complete\n// If in_signal is provided, then ExecutePM4 will return and caller may wait for in_signal\n// Note: On gfx8, there is no completion signal support, so ExecutePM4 will block even if\n// in_signal is provided, and it is still valid to check in_signal after ExecutePM4 returns.\nvoid AqlQueue::ExecutePM4(uint32_t* cmd_data, size_t cmd_size_b, hsa_fence_scope_t acquireFence,\n                          hsa_fence_scope_t releaseFence, hsa_signal_t* in_signal) {\n  // pm4_ib_buf_ is a shared resource, so mutually exclude here.\n  ScopedAcquire<KernelMutex> lock(&pm4_ib_mutex_);\n\n  // Obtain reference to any container queue.\n  core::Queue* queue = core::Queue::Convert(public_handle());\n\n  // Obtain a queue slot for a single AQL packet.\n  uint64_t write_idx = queue->AddWriteIndexAcqRel(1);\n\n  while ((write_idx - queue->LoadReadIndexRelaxed()) >= queue->amd_queue_.hsa_queue.size) {\n    os::YieldThread();\n  }\n\n  uint32_t slot_idx = uint32_t(write_idx % queue->amd_queue_.hsa_queue.size);\n  constexpr uint32_t slot_size_b = 0x40;\n  uint32_t* queue_slot =\n      (uint32_t*)(uintptr_t(queue->amd_queue_.hsa_queue.base_address) + (slot_idx * slot_size_b));\n\n  // Copy client PM4 command into IB.\n  assert(cmd_size_b < pm4_ib_size_b_ && \"PM4 exceeds IB size\");\n  memcpy(pm4_ib_buf_, cmd_data, cmd_size_b);\n\n  // Construct a PM4 command to execute the IB.\n  constexpr uint32_t ib_jump_size_dw = 4;\n\n  uint32_t ib_jump_cmd[ib_jump_size_dw] = {\n      PM4_HDR(PM4_HDR_IT_OPCODE_INDIRECT_BUFFER, ib_jump_size_dw,\n                              agent_->supported_isas()[0]->GetMajorVersion()),\n      PM4_INDIRECT_BUFFER_DW1_IB_BASE_LO(uint32_t(uintptr_t(pm4_ib_buf_) >> 2)),\n      PM4_INDIRECT_BUFFER_DW2_IB_BASE_HI(uint32_t(uintptr_t(pm4_ib_buf_) >> 32)),\n      (PM4_INDIRECT_BUFFER_DW3_IB_SIZE(uint32_t(cmd_size_b / sizeof(uint32_t))) |\n       PM4_INDIRECT_BUFFER_DW3_IB_VALID(1))};\n\n  // To respect multi-producer semantics, first buffer commands for the queue slot.\n  constexpr uint32_t slot_size_dw = uint32_t(slot_size_b / sizeof(uint32_t));\n  uint32_t slot_data[slot_size_dw];\n  hsa_signal_t local_signal = {0};\n  hsa_status_t err;\n\n  if (agent_->supported_isas()[0]->GetMajorVersion() <= 8) {\n    // Construct a set of PM4 to fit inside the AQL packet slot.\n    uint32_t slot_dw_idx = 0;\n\n    // Construct a no-op command to pad the queue slot.\n    constexpr uint32_t rel_mem_size_dw = 7;\n    constexpr uint32_t nop_pad_size_dw = slot_size_dw - (ib_jump_size_dw + rel_mem_size_dw);\n\n    uint32_t* nop_pad = &slot_data[slot_dw_idx];\n    slot_dw_idx += nop_pad_size_dw;\n\n    nop_pad[0] = PM4_HDR(PM4_HDR_IT_OPCODE_NOP, nop_pad_size_dw,\n                              agent_->supported_isas()[0]->GetMajorVersion());\n\n    for (uint32_t i = 1; i < nop_pad_size_dw; ++i) {\n      nop_pad[i] = 0;\n    }\n\n    // Copy in command to execute the IB.\n    assert(slot_dw_idx + ib_jump_size_dw <= slot_size_dw && \"PM4 exceeded queue slot size\");\n    uint32_t* ib_jump = &slot_data[slot_dw_idx];\n    slot_dw_idx += ib_jump_size_dw;\n\n    memcpy(ib_jump, ib_jump_cmd, sizeof(ib_jump_cmd));\n\n    // Construct a command to advance the read index and invalidate the packet\n    // header. This must be the last command since this releases the queue slot\n    // for writing.\n    assert(slot_dw_idx + rel_mem_size_dw <= slot_size_dw && \"PM4 exceeded queue slot size\");\n    uint32_t* rel_mem = &slot_data[slot_dw_idx];\n\n    rel_mem[0] = PM4_HDR(PM4_HDR_IT_OPCODE_RELEASE_MEM, rel_mem_size_dw,\n                              agent_->supported_isas()[0]->GetMajorVersion());\n    rel_mem[1] = PM4_RELEASE_MEM_DW1_EVENT_INDEX(PM4_RELEASE_MEM_EVENT_INDEX_AQL);\n    rel_mem[2] = 0;\n    rel_mem[3] = 0;\n    rel_mem[4] = 0;\n    rel_mem[5] = 0;\n    rel_mem[6] = 0;\n  } else if (agent_->supported_isas()[0]->GetMajorVersion() >= 9) {\n    // Construct an AQL packet to jump to the PM4 IB.\n    struct amd_aql_pm4_ib {\n      uint16_t header;\n      uint16_t ven_hdr;\n      uint32_t ib_jump_cmd[4];\n      uint32_t dw_cnt_remain;\n      uint32_t reserved[8];\n      hsa_signal_t completion_signal;\n    };\n\n    if (!in_signal) {\n      err = hsa_signal_create(1, 0, NULL, &local_signal);\n      assert(err == HSA_STATUS_SUCCESS);\n    }\n\n    constexpr uint32_t AMD_AQL_FORMAT_PM4_IB = 0x1;\n\n    amd_aql_pm4_ib aql_pm4_ib{};\n    aql_pm4_ib.header = HSA_PACKET_TYPE_VENDOR_SPECIFIC << HSA_PACKET_HEADER_TYPE |\n                        (acquireFence << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) |\n                        (releaseFence << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n\n    aql_pm4_ib.ven_hdr = AMD_AQL_FORMAT_PM4_IB;\n    aql_pm4_ib.ib_jump_cmd[0] = ib_jump_cmd[0];\n    aql_pm4_ib.ib_jump_cmd[1] = ib_jump_cmd[1];\n    aql_pm4_ib.ib_jump_cmd[2] = ib_jump_cmd[2];\n    aql_pm4_ib.ib_jump_cmd[3] = ib_jump_cmd[3];\n    aql_pm4_ib.dw_cnt_remain = 0xA;\n    aql_pm4_ib.completion_signal = in_signal ? *in_signal : local_signal;\n\n    memcpy(slot_data, &aql_pm4_ib, sizeof(aql_pm4_ib));\n  } else {\n    assert(false && \"AqlQueue::ExecutePM4 not implemented\");\n  }\n\n  // Copy buffered commands into the queue slot.\n  // Overwrite the AQL invalid header (first dword) last.\n  // This prevents the slot from being read until it's fully written.\n  memcpy(&queue_slot[1], &slot_data[1], slot_size_b - sizeof(uint32_t));\n  if (IsDeviceMemRingBuf() && needsPcieOrdering()) {\n    // Ensure the packet body is written as header may get reordered when writing over PCIE\n    _mm_sfence();\n  }\n  atomic::Store(&queue_slot[0], slot_data[0], std::memory_order_release);\n\n  // Submit the packet slot.\n  core::Signal* doorbell = core::Signal::Convert(queue->amd_queue_.hsa_queue.doorbell_signal);\n  doorbell->StoreRelease(write_idx);\n\n  // Wait for the packet to be consumed.\n  if (agent_->supported_isas()[0]->GetMajorVersion() <= 8) {\n    while (queue->LoadReadIndexRelaxed() <= write_idx)\n      os::YieldThread();\n\n    if (in_signal) hsa_signal_store_screlease(*in_signal, 0);\n  } else if (!in_signal) {\n    // On gfx9 and newer, if in_signal is not provided, we block and wait for own signal\n    hsa_signal_value_t ret;\n    ret = hsa_signal_wait_scacquire(local_signal, HSA_SIGNAL_CONDITION_LT, 1, (uint64_t)-1,\n                                    HSA_WAIT_STATE_ACTIVE);\n    err = hsa_signal_destroy(local_signal);\n    assert(ret == 0 && err == HSA_STATUS_SUCCESS);\n  }\n}\n\nvoid AqlQueue::FillBufRsrcWord0() {\n  SQ_BUF_RSRC_WORD0 srd0;\n  uintptr_t scratch_base = uintptr_t(queue_scratch_.main_queue_base);\n\n  srd0.bits.BASE_ADDRESS = uint32_t(scratch_base);\n  amd_queue_.scratch_resource_descriptor[0] = srd0.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord1() {\n  SQ_BUF_RSRC_WORD1 srd1;\n  uint32_t scratch_base_hi = 0;\n\n#ifdef HSA_LARGE_MODEL\n  uintptr_t scratch_base = uintptr_t(queue_scratch_.main_queue_base);\n  scratch_base_hi = uint32_t(scratch_base >> 32);\n  #endif\n\n  srd1.bits.BASE_ADDRESS_HI = scratch_base_hi;\n  srd1.bits.STRIDE = 0;\n  srd1.bits.CACHE_SWIZZLE = 0;\n  srd1.bits.SWIZZLE_ENABLE = 1;\n\n  amd_queue_.scratch_resource_descriptor[1] = srd1.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord1_Gfx11() {\n  SQ_BUF_RSRC_WORD1_GFX11 srd1;\n  uint32_t scratch_base_hi = 0;\n\n#ifdef HSA_LARGE_MODEL\n  uintptr_t scratch_base = uintptr_t(queue_scratch_.main_queue_base);\n  scratch_base_hi = uint32_t(scratch_base >> 32);\n#endif\n\n  srd1.bits.BASE_ADDRESS_HI = scratch_base_hi;\n  srd1.bits.STRIDE = 0;\n  srd1.bits.SWIZZLE_ENABLE = 1;\n\n  amd_queue_.scratch_resource_descriptor[1] = srd1.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord2() {\n  SQ_BUF_RSRC_WORD2 srd2;\n  const auto& agent_props = agent_->properties();\n  const uint32_t num_xcc = agent_props.NumXcc;\n\n   // report size per XCC\n  srd2.bits.NUM_RECORDS = uint32_t(queue_scratch_.main_size / num_xcc);\n\n  amd_queue_.scratch_resource_descriptor[2] = srd2.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord3() {\n  SQ_BUF_RSRC_WORD3 srd3;\n\n  srd3.bits.DST_SEL_X = SQ_SEL_X;\n  srd3.bits.DST_SEL_Y = SQ_SEL_Y;\n  srd3.bits.DST_SEL_Z = SQ_SEL_Z;\n  srd3.bits.DST_SEL_W = SQ_SEL_W;\n  srd3.bits.NUM_FORMAT = BUF_NUM_FORMAT_UINT;\n  srd3.bits.DATA_FORMAT = BUF_DATA_FORMAT_32;\n  srd3.bits.ELEMENT_SIZE = 1;  // 4\n  srd3.bits.INDEX_STRIDE = 3;  // 64\n  srd3.bits.ADD_TID_ENABLE = 1;\n  srd3.bits.ATC__CI__VI = (agent_->profile() == HSA_PROFILE_FULL);\n  srd3.bits.HASH_ENABLE = 0;\n  srd3.bits.HEAP = 0;\n  srd3.bits.MTYPE__CI__VI = 0;\n  srd3.bits.TYPE = SQ_RSRC_BUF;\n\n  amd_queue_.scratch_resource_descriptor[3] = srd3.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord3_Gfx10() {\n  SQ_BUF_RSRC_WORD3_GFX10 srd3;\n\n  srd3.bits.DST_SEL_X = SQ_SEL_X;\n  srd3.bits.DST_SEL_Y = SQ_SEL_Y;\n  srd3.bits.DST_SEL_Z = SQ_SEL_Z;\n  srd3.bits.DST_SEL_W = SQ_SEL_W;\n  srd3.bits.FORMAT = BUF_FORMAT_32_UINT;\n  srd3.bits.RESERVED1 = 0;\n  srd3.bits.INDEX_STRIDE = 0;  // filled in by CP\n  srd3.bits.ADD_TID_ENABLE = 1;\n  srd3.bits.RESOURCE_LEVEL = 1;\n  srd3.bits.RESERVED2 = 0;\n  srd3.bits.OOB_SELECT = 2;  // no bounds check in swizzle mode\n  srd3.bits.TYPE = SQ_RSRC_BUF;\n\n  amd_queue_.scratch_resource_descriptor[3] = srd3.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord3_Gfx11() {\n  SQ_BUF_RSRC_WORD3_GFX11 srd3;\n\n  srd3.bits.DST_SEL_X = SQ_SEL_X;\n  srd3.bits.DST_SEL_Y = SQ_SEL_Y;\n  srd3.bits.DST_SEL_Z = SQ_SEL_Z;\n  srd3.bits.DST_SEL_W = SQ_SEL_W;\n  srd3.bits.FORMAT = BUF_FORMAT_32_UINT;\n  srd3.bits.RESERVED1 = 0;\n  srd3.bits.INDEX_STRIDE = 0;  // filled in by CP\n  srd3.bits.ADD_TID_ENABLE = 1;\n  srd3.bits.RESERVED2 = 0;\n  srd3.bits.OOB_SELECT = 2;  // no bounds check in swizzle mode\n  srd3.bits.TYPE = SQ_RSRC_BUF;\n\n  amd_queue_.scratch_resource_descriptor[3] = srd3.u32All;\n}\n\nvoid AqlQueue::FillBufRsrcWord3_Gfx12() {\n  SQ_BUF_RSRC_WORD3_GFX12 srd3;\n\n  srd3.bits.DST_SEL_X = SQ_SEL_X;\n  srd3.bits.DST_SEL_Y = SQ_SEL_Y;\n  srd3.bits.DST_SEL_Z = SQ_SEL_Z;\n  srd3.bits.DST_SEL_W = SQ_SEL_W;\n  srd3.bits.FORMAT = BUF_FORMAT_32_UINT;\n  srd3.bits.RESERVED1 = 0;\n  srd3.bits.INDEX_STRIDE = 0;  // filled in by CP\n  srd3.bits.ADD_TID_ENABLE = 1;\n  srd3.bits.WRITE_COMPRESS_ENABLE = 0;\n  srd3.bits.COMPRESSION_EN = 0;\n  srd3.bits.COMPRESSION_ACCESS_MODE = 0;\n  srd3.bits.OOB_SELECT = 2;  // no bounds check in swizzle mode\n  srd3.bits.TYPE = SQ_RSRC_BUF;\n\n  amd_queue_.scratch_resource_descriptor[3] = srd3.u32All;\n}\n\n// Set concurrent wavefront limits only when scratch is being used.\nvoid AqlQueue::FillComputeTmpRingSize() {\n  COMPUTE_TMPRING_SIZE tmpring_size = {};\n  if (queue_scratch_.main_size == 0) {\n    amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n    return;\n  }\n\n  const auto& agent_props = agent_->properties();\n  const uint32_t num_xcc = agent_props.NumXcc;\n\n  // Determine the maximum number of waves device can support\n  uint32_t num_cus = agent_props.NumFComputeCores / agent_props.NumSIMDPerCU;\n  uint32_t max_scratch_waves = num_cus * agent_props.MaxSlotsScratchCU;\n\n  // Scratch is allocated program COMPUTE_TMPRING_SIZE register\n  // Scratch Size per Wave is specified in terms of kilobytes\n  uint32_t wave_scratch =\n      (((queue_scratch_.main_lanes_per_wave * queue_scratch_.main_size_per_thread) +\n        queue_scratch_.mem_alignment_size - 1) /\n       queue_scratch_.mem_alignment_size);\n  tmpring_size.bits.WAVESIZE = wave_scratch;\n  assert(wave_scratch == tmpring_size.bits.WAVESIZE && \"WAVESIZE Overflow.\");\n  uint32_t num_waves = (queue_scratch_.main_size / num_xcc) /\n      (tmpring_size.bits.WAVESIZE * queue_scratch_.mem_alignment_size);\n\n  tmpring_size.bits.WAVES = std::min(num_waves, max_scratch_waves);\n  amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n  assert((tmpring_size.bits.WAVES % (agent_props.NumShaderBanks / num_xcc) == 0) &&\n         \"Invalid scratch wave count.  Must be divisible by #SEs.\");\n}\n\n// Set concurrent wavefront limits only when scratch is being used.\nvoid AqlQueue::FillAltComputeTmpRingSize() {\n  COMPUTE_TMPRING_SIZE tmpring_size = {};\n  if (queue_scratch_.alt_size == 0) {\n    amd_queue_.alt_compute_tmpring_size = tmpring_size.u32All;\n    return;\n  }\n\n  const auto& agent_props = agent_->properties();\n  const uint32_t num_xcc = agent_props.NumXcc;\n\n  // Determine the maximum number of waves device can support\n  uint32_t num_cus = agent_props.NumFComputeCores / agent_props.NumSIMDPerCU;\n  uint32_t max_scratch_waves = num_cus * agent_props.MaxSlotsScratchCU;\n\n  // Scratch is allocated program COMPUTE_TMPRING_SIZE register\n  // Scratch Size per Wave is specified in terms of kilobytes\n  uint32_t wave_scratch =\n      (((queue_scratch_.alt_lanes_per_wave * queue_scratch_.alt_size_per_thread) +\n        queue_scratch_.mem_alignment_size - 1) /\n       queue_scratch_.mem_alignment_size);\n  tmpring_size.bits.WAVESIZE = wave_scratch;\n  assert(wave_scratch == tmpring_size.bits.WAVESIZE && \"WAVESIZE Overflow.\");\n  uint32_t num_waves = (queue_scratch_.alt_size / num_xcc) /\n      (tmpring_size.bits.WAVESIZE * queue_scratch_.mem_alignment_size);\n\n  tmpring_size.bits.WAVES = std::min(num_waves, max_scratch_waves);\n  amd_queue_.alt_compute_tmpring_size = tmpring_size.u32All;\n  assert((tmpring_size.bits.WAVES % (agent_props.NumShaderBanks / num_xcc) == 0) &&\n         \"Invalid scratch wave count.  Must be divisible by #SEs.\");\n}\n\n// Set concurrent wavefront limits only when scratch is being used.\nvoid AqlQueue::FillComputeTmpRingSize_Gfx11() {\n  COMPUTE_TMPRING_SIZE_GFX11 tmpring_size = {};\n  if (queue_scratch_.main_size == 0) {\n    amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n    return;\n  }\n\n  const auto& agent_props = agent_->properties();\n  const uint32_t num_xcc = agent_props.NumXcc;\n\n  // Determine the maximum number of waves device can support\n  uint32_t num_cus = agent_props.NumFComputeCores / (agent_props.NumSIMDPerCU * num_xcc);\n  uint32_t max_scratch_waves = num_cus * agent_props.MaxSlotsScratchCU;\n\n  // Scratch is allocated program COMPUTE_TMPRING_SIZE register\n  // Scratch Size per Wave is specified in terms of kilobytes\n  uint32_t wave_scratch =\n      (((queue_scratch_.main_lanes_per_wave * queue_scratch_.main_size_per_thread) +\n        queue_scratch_.mem_alignment_size - 1) /\n       queue_scratch_.mem_alignment_size);\n\n  tmpring_size.bits.WAVESIZE = wave_scratch;\n  assert(wave_scratch == tmpring_size.bits.WAVESIZE && \"WAVESIZE Overflow.\");\n\n  uint32_t num_waves =\n      queue_scratch_.main_size / (tmpring_size.bits.WAVESIZE * queue_scratch_.mem_alignment_size);\n\n  // For GFX11 we specify number of waves per engine instead of total\n  num_waves /= agent_->properties().NumShaderBanks;\n  tmpring_size.bits.WAVES = std::min(num_waves, max_scratch_waves);\n  amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n}\n\n// Set concurrent wavefront limits only when scratch is being used.\nvoid AqlQueue::FillComputeTmpRingSize_Gfx12() {\n  // For GFX12, struct field size changes.\n  // Consider refactoring code for GFX11/GFX12 if no other changes.\n  COMPUTE_TMPRING_SIZE_GFX12 tmpring_size = {};\n  if (queue_scratch_.main_size == 0) {\n    amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n    return;\n  }\n\n  const auto& agent_props = agent_->properties();\n  const uint32_t num_xcc = agent_props.NumXcc;\n\n  // Determine the maximum number of waves device can support\n  uint32_t num_cus = agent_props.NumFComputeCores / (agent_props.NumSIMDPerCU * num_xcc);\n  uint32_t max_scratch_waves = num_cus * agent_props.MaxSlotsScratchCU;\n\n  // Scratch is allocated program COMPUTE_TMPRING_SIZE register\n  // Scratch Size per Wave is specified in terms of kilobytes\n  uint32_t wave_scratch = (((queue_scratch_.main_lanes_per_wave * queue_scratch_.main_size_per_thread) +\n                            queue_scratch_.mem_alignment_size - 1) /\n                           queue_scratch_.mem_alignment_size);\n\n  tmpring_size.bits.WAVESIZE = wave_scratch;\n  assert(wave_scratch == tmpring_size.bits.WAVESIZE && \"WAVESIZE Overflow.\");\n\n  uint32_t num_waves =\n      queue_scratch_.main_size / (tmpring_size.bits.WAVESIZE * queue_scratch_.mem_alignment_size);\n\n  // For GFX11 we specify number of waves per engine instead of total\n  num_waves /= agent_->properties().NumShaderBanks;\n  tmpring_size.bits.WAVES = std::min(num_waves, max_scratch_waves);\n  amd_queue_.compute_tmpring_size = tmpring_size.u32All;\n}\n\n// @brief Define the Scratch Buffer Descriptor and related parameters\n// that enable kernel access scratch memory\nvoid AqlQueue::InitScratchSRD() {\n  switch (agent_->supported_isas()[0]->GetMajorVersion()) {\n    case 12:\n      FillBufRsrcWord0();\n      FillBufRsrcWord1_Gfx11();\n      FillBufRsrcWord2();\n      FillBufRsrcWord3_Gfx12();\n      FillComputeTmpRingSize_Gfx12();\n      break;\n    case 11:\n      FillBufRsrcWord0();\n      FillBufRsrcWord1_Gfx11();\n      FillBufRsrcWord2();\n      FillBufRsrcWord3_Gfx11();\n      FillComputeTmpRingSize_Gfx11();\n      break;\n    case 10:\n      FillBufRsrcWord0();\n      FillBufRsrcWord1();\n      FillBufRsrcWord2();\n      FillBufRsrcWord3_Gfx10();\n      FillComputeTmpRingSize();\n      break;\n    default:\n      FillBufRsrcWord0();\n      FillBufRsrcWord1();\n      FillBufRsrcWord2();\n      FillBufRsrcWord3();\n      FillComputeTmpRingSize();\n      FillAltComputeTmpRingSize();\n      break;\n  }\n\n  // Populate flat scratch parameters in amd_queue_.\n  amd_queue_.scratch_backing_memory_location = queue_scratch_.main_queue_process_offset;\n  amd_queue_.alt_scratch_backing_memory_location = queue_scratch_.alt_queue_process_offset;\n\n  // For backwards compatibility this field records the per-lane scratch\n  // for a 64 lane wavefront. If scratch was allocated for 32 lane waves\n  // then the effective size for a 64 lane wave is halved.\n  amd_queue_.scratch_wave64_lane_byte_size =\n      uint32_t((queue_scratch_.main_size_per_thread * queue_scratch_.main_lanes_per_wave) / 64);\n\n  amd_queue_.alt_scratch_wave64_lane_byte_size =\n      uint32_t((queue_scratch_.alt_size_per_thread * queue_scratch_.alt_lanes_per_wave) / 64);\n\n  amd_queue_.alt_scratch_dispatch_limit_x = queue_scratch_.alt_dispatch_limit_x;\n  amd_queue_.alt_scratch_dispatch_limit_y = queue_scratch_.alt_dispatch_limit_y;\n  amd_queue_.alt_scratch_dispatch_limit_z = queue_scratch_.alt_dispatch_limit_z;\n\n  return;\n}\n\nhsa_status_t AqlQueue::EnableGWS(int gws_slot_count) {\n  uint32_t discard;\n  auto status = agent_->driver().AllocQueueGWS(queue_id_, gws_slot_count, &discard);\n  if (status != HSA_STATUS_SUCCESS) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  amd_queue_.hsa_queue.type = HSA_QUEUE_TYPE_COOPERATIVE;\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_blit_kernel.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_blit_kernel.h\"\n\n#include <algorithm>\n#include <sstream>\n#include <string>\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nstatic std::string& kBlitKernelSource() {\n  static std::string kBlitKernelSource_(R\"(\n  // Compatibility function for GFXIP 7.\n\n  function s_load_dword_offset(byte_offset)\n    if kGFXIPVersion == 7\n      return byte_offset / 4\n    else\n      return byte_offset\n    end\n  end\n\n  // Memory copy for all cases except:\n  //  (src_addr & 0x3) != (dst_addr & 0x3)\n  //\n  // Kernel argument buffer:\n  //   [DW  0, 1]  Phase 1 src start address\n  //   [DW  2, 3]  Phase 1 dst start address\n  //   [DW  4, 5]  Phase 2 src start address\n  //   [DW  6, 7]  Phase 2 dst start address\n  //   [DW  8, 9]  Phase 3 src start address\n  //   [DW 10,11]  Phase 3 dst start address\n  //   [DW 12,13]  Phase 4 src start address\n  //   [DW 14,15]  Phase 4 dst start address\n  //   [DW 16,17]  Phase 4 src end address\n  //   [DW 18,19]  Phase 4 dst end address\n  //   [DW 20   ]  Total number of workitems\n\n  var kCopyAlignedVecWidth = 4\n  var kCopyAlignedUnroll = 1\n\n  shader CopyAligned\n    type(CS)\n    user_sgpr_count(2)\n    sgpr_count(32)\n    vgpr_count(8 + (kCopyAlignedUnroll * kCopyAlignedVecWidth))\n\n    // Retrieve kernel arguments.\n    s_load_dwordx4          s[4:7], s[0:1], s_load_dword_offset(0x0)\n    s_load_dwordx4          s[8:11], s[0:1], s_load_dword_offset(0x10)\n    s_load_dwordx4          s[12:15], s[0:1], s_load_dword_offset(0x20)\n    s_load_dwordx4          s[16:19], s[0:1], s_load_dword_offset(0x30)\n    s_load_dwordx4          s[20:23], s[0:1], s_load_dword_offset(0x40)\n    s_load_dword            s24, s[0:1], s_load_dword_offset(0x50)\n    s_waitcnt               lgkmcnt(0)\n\n    // Compute workitem id.\n    s_lshl_b32              s2, s2, 0x6\n    v_add_u32               v0, vcc, s2, v0\n\n    // =====================================================\n    // Phase 1: Byte copy up to 0x100 destination alignment.\n    // =====================================================\n\n    // Compute phase source address.\n    v_mov_b32               v3, s5\n    v_add_u32               v2, vcc, v0, s4\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s7\n    v_add_u32               v4, vcc, v0, s6\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n  L_COPY_ALIGNED_PHASE_1_LOOP:\n    // Mask off lanes (or branch out) after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[8:9]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_1_DONE\n    s_and_b64               exec, exec, vcc\n\n    // Load from/advance the source address.\n    flat_load_ubyte         v1, v[2:3]\n    s_waitcnt               vmcnt(0)\n    v_add_u32               v2, vcc, v2, s24\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Write to/advance the destination address.\n    flat_store_byte         v[4:5], v1\n    v_add_u32               v4, vcc, v4, s24\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n    // Repeat until branched out.\n    s_branch                L_COPY_ALIGNED_PHASE_1_LOOP\n\n  L_COPY_ALIGNED_PHASE_1_DONE:\n    // Restore EXEC mask for all lanes.\n    s_mov_b64               exec, 0xFFFFFFFFFFFFFFFF\n\n    // ========================================================\n    // Phase 2: Unrolled dword[x4] copy up to last whole block.\n    // ========================================================\n\n    // Compute unrolled dword[x4] stride across all threads.\n    if kCopyAlignedVecWidth == 4\n      s_lshl_b32            s25, s24, 0x4\n    else\n      s_lshl_b32            s25, s24, 0x2\n    end\n\n    // Compute phase source address.\n    if kCopyAlignedVecWidth == 4\n      v_lshlrev_b32         v1, 0x4, v0\n    else\n      v_lshlrev_b32         v1, 0x2, v0\n    end\n\n    v_mov_b32               v3, s9\n    v_add_u32               v2, vcc, v1, s8\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s11\n    v_add_u32               v4, vcc, v1, s10\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n  L_COPY_ALIGNED_PHASE_2_LOOP:\n    // Branch out after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[12:13]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_2_DONE\n\n    // Load from/advance the source address.\n    for var i = 0; i < kCopyAlignedUnroll; i ++\n      if kCopyAlignedVecWidth == 4\n        flat_load_dwordx4   v[8 + (i * 4)], v[2:3]\n      else\n        flat_load_dword     v[8 + i], v[2:3]\n      end\n\n      v_add_u32             v2, vcc, v2, s25\n      v_addc_u32            v3, vcc, v3, 0x0, vcc\n    end\n\n    // Write to/advance the destination address.\n    s_waitcnt               vmcnt(0)\n\n    for var i = 0; i < kCopyAlignedUnroll; i ++\n      if kCopyAlignedVecWidth == 4\n        flat_store_dwordx4  v[4:5], v[8 + (i * 4)]\n      else\n        flat_store_dword    v[4:5], v[8 + i]\n      end\n\n      v_add_u32             v4, vcc, v4, s25\n      v_addc_u32            v5, vcc, v5, 0x0, vcc\n    end\n\n    // Repeat until branched out.\n    s_branch                L_COPY_ALIGNED_PHASE_2_LOOP\n\n  L_COPY_ALIGNED_PHASE_2_DONE:\n\n    // ===========================================\n    // Phase 3: Dword copy up to last whole dword.\n    // ===========================================\n\n    // Compute dword stride across all threads.\n    s_lshl_b32              s25, s24, 0x2\n\n    // Compute phase source address.\n    v_lshlrev_b32           v1, 0x2, v0\n    v_mov_b32               v3, s13\n    v_add_u32               v2, vcc, v1, s12\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s15\n    v_add_u32               v4, vcc, v1, s14\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n  L_COPY_ALIGNED_PHASE_3_LOOP:\n    // Mask off lanes (or branch out) after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[16:17]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_3_DONE\n    s_and_b64               exec, exec, vcc\n\n    // Load from/advance the source address.\n    flat_load_dword         v1, v[2:3]\n    v_add_u32               v2, vcc, v2, s25\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n    s_waitcnt               vmcnt(0)\n\n    // Write to/advance the destination address.\n    flat_store_dword        v[4:5], v1\n    v_add_u32               v4, vcc, v4, s25\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n    // Repeat until branched out.\n    s_branch                L_COPY_ALIGNED_PHASE_3_LOOP\n\n  L_COPY_ALIGNED_PHASE_3_DONE:\n    // Restore EXEC mask for all lanes.\n    s_mov_b64               exec, 0xFFFFFFFFFFFFFFFF\n\n    // =============================\n    // Phase 4: Byte copy up to end.\n    // =============================\n\n    // Compute phase source address.\n    v_mov_b32               v3, s17\n    v_add_u32               v2, vcc, v0, s16\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s19\n    v_add_u32               v4, vcc, v0, s18\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n    // Mask off lanes (or branch out) after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[20:21]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_4_DONE\n    s_and_b64               exec, exec, vcc\n\n    // Load from the source address.\n    flat_load_ubyte         v1, v[2:3]\n    s_waitcnt               vmcnt(0)\n\n    // Write to the destination address.\n    flat_store_byte         v[4:5], v1\n\n  L_COPY_ALIGNED_PHASE_4_DONE:\n    s_endpgm\n  end\n\n  // Memory copy for this case:\n  //  (src_addr & 0x3) != (dst_addr & 0x3)\n  //\n  // Kernel argument buffer:\n  //   [DW  0, 1]  Phase 1 src start address\n  //   [DW  2, 3]  Phase 1 dst start address\n  //   [DW  4, 5]  Phase 2 src start address\n  //   [DW  6, 7]  Phase 2 dst start address\n  //   [DW  8, 9]  Phase 2 src end address\n  //   [DW 10,11]  Phase 2 dst end address\n  //   [DW 12   ]  Total number of workitems\n\n  var kCopyMisalignedUnroll = 4\n\n  shader CopyMisaligned\n    type(CS)\n    user_sgpr_count(2)\n    sgpr_count(23)\n    vgpr_count(6 + kCopyMisalignedUnroll)\n\n    // Retrieve kernel arguments.\n    s_load_dwordx4          s[4:7], s[0:1], s_load_dword_offset(0x0)\n    s_load_dwordx4          s[8:11], s[0:1], s_load_dword_offset(0x10)\n    s_load_dwordx4          s[12:15], s[0:1], s_load_dword_offset(0x20)\n    s_load_dword            s16, s[0:1], s_load_dword_offset(0x30)\n    s_waitcnt               lgkmcnt(0)\n\n    // Compute workitem id.\n    s_lshl_b32              s2, s2, 0x6\n    v_add_u32               v0, vcc, s2, v0\n\n    // ===================================================\n    // Phase 1: Unrolled byte copy up to last whole block.\n    // ===================================================\n\n    // Compute phase source address.\n    v_mov_b32               v3, s5\n    v_add_u32               v2, vcc, v0, s4\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s7\n    v_add_u32               v4, vcc, v0, s6\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n  L_COPY_MISALIGNED_PHASE_1_LOOP:\n    // Branch out after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[8:9]\n    s_cbranch_vccz          L_COPY_MISALIGNED_PHASE_1_DONE\n\n    // Load from/advance the source address.\n    for var i = 0; i < kCopyMisalignedUnroll; i ++\n      flat_load_ubyte       v[6 + i], v[2:3]\n      v_add_u32             v2, vcc, v2, s16\n      v_addc_u32            v3, vcc, v3, 0x0, vcc\n    end\n\n    // Write to/advance the destination address.\n    s_waitcnt               vmcnt(0)\n\n    for var i = 0; i < kCopyMisalignedUnroll; i ++\n      flat_store_byte       v[4:5], v[6 + i]\n      v_add_u32             v4, vcc, v4, s16\n      v_addc_u32            v5, vcc, v5, 0x0, vcc\n    end\n\n    // Repeat until branched out.\n    s_branch                L_COPY_MISALIGNED_PHASE_1_LOOP\n\n  L_COPY_MISALIGNED_PHASE_1_DONE:\n\n    // =============================\n    // Phase 2: Byte copy up to end.\n    // =============================\n\n    // Compute phase source address.\n    v_mov_b32               v3, s9\n    v_add_u32               v2, vcc, v0, s8\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Compute phase destination address.\n    v_mov_b32               v5, s11\n    v_add_u32               v4, vcc, v0, s10\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n  L_COPY_MISALIGNED_PHASE_2_LOOP:\n    // Mask off lanes (or branch out) after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[12:13]\n    s_cbranch_vccz          L_COPY_MISALIGNED_PHASE_2_DONE\n    s_and_b64               exec, exec, vcc\n\n    // Load from/advance the source address.\n    flat_load_ubyte         v1, v[2:3]\n    v_add_u32               v2, vcc, v2, s16\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n    s_waitcnt               vmcnt(0)\n\n    // Write to/advance the destination address.\n    flat_store_byte         v[4:5], v1\n    v_add_u32               v4, vcc, v4, s16\n    v_addc_u32              v5, vcc, v5, 0x0, vcc\n\n    // Repeat until branched out.\n    s_branch                L_COPY_MISALIGNED_PHASE_2_LOOP\n\n  L_COPY_MISALIGNED_PHASE_2_DONE:\n    s_endpgm\n  end\n\n  // Memory fill for dword-aligned region.\n  //\n  // Kernel argument buffer:\n  //   [DW  0, 1]  Phase 1 dst start address\n  //   [DW  2, 3]  Phase 2 dst start address\n  //   [DW  4, 5]  Phase 2 dst end address\n  //   [DW  6   ]  Value to fill memory with\n  //   [DW  7   ]  Total number of workitems\n\n  var kFillVecWidth = 4\n  var kFillUnroll = 1\n\n  shader Fill\n    type(CS)\n    user_sgpr_count(2)\n    sgpr_count(19)\n    vgpr_count(8)\n\n    // Retrieve kernel arguments.\n    s_load_dwordx4          s[4:7], s[0:1], s_load_dword_offset(0x0)\n    s_load_dwordx4          s[8:11], s[0:1], s_load_dword_offset(0x10)\n    s_waitcnt               lgkmcnt(0)\n\n    // Compute workitem id.\n    s_lshl_b32              s2, s2, 0x6\n    v_add_u32               v0, vcc, s2, v0\n\n    // Copy fill pattern into VGPRs.\n    for var i = 0; i < kFillVecWidth; i ++\n      v_mov_b32           v[4 + i], s10\n    end\n\n    // ========================================================\n    // Phase 1: Unrolled dword[x4] fill up to last whole block.\n    // ========================================================\n\n    // Compute unrolled dword[x4] stride across all threads.\n    if kFillVecWidth == 4\n      s_lshl_b32            s12, s11, 0x4\n    else\n      s_lshl_b32            s12, s11, 0x2\n    end\n\n    // Compute phase destination address.\n    if kFillVecWidth == 4\n      v_lshlrev_b32         v1, 0x4, v0\n    else\n      v_lshlrev_b32         v1, 0x2, v0\n    end\n\n    v_mov_b32               v3, s5\n    v_add_u32               v2, vcc, v1, s4\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n  L_FILL_PHASE_1_LOOP:\n    // Branch out after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[6:7]\n    s_cbranch_vccz          L_FILL_PHASE_1_DONE\n\n    // Write to/advance the destination address.\n    for var i = 0; i < kFillUnroll; i ++\n      if kFillVecWidth == 4\n        flat_store_dwordx4  v[2:3], v[4:7]\n      else\n        flat_store_dword    v[2:3], v4\n      end\n\n      v_add_u32             v2, vcc, v2, s12\n      v_addc_u32            v3, vcc, v3, 0x0, vcc\n    end\n\n    // Repeat until branched out.\n    s_branch                L_FILL_PHASE_1_LOOP\n\n  L_FILL_PHASE_1_DONE:\n\n    // ==============================\n    // Phase 2: Dword fill up to end.\n    // ==============================\n\n    // Compute dword stride across all threads.\n    s_lshl_b32              s12, s11, 0x2\n\n    // Compute phase destination address.\n    v_lshlrev_b32           v1, 0x2, v0\n    v_mov_b32               v3, s7\n    v_add_u32               v2, vcc, v1, s6\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n  L_FILL_PHASE_2_LOOP:\n    // Mask off lanes (or branch out) after phase end.\n    v_cmp_lt_u64            vcc, v[2:3], s[8:9]\n    s_cbranch_vccz          L_FILL_PHASE_2_DONE\n    s_and_b64               exec, exec, vcc\n\n    // Write to/advance the destination address.\n    flat_store_dword        v[2:3], v4\n    v_add_u32               v2, vcc, v2, s12\n    v_addc_u32              v3, vcc, v3, 0x0, vcc\n\n    // Repeat until branched out.\n    s_branch                L_FILL_PHASE_2_LOOP\n\n  L_FILL_PHASE_2_DONE:\n    s_endpgm\n  end\n)\");\n  return kBlitKernelSource_;\n}\n\n// Search kernel source for variable definition and return value.\nint GetKernelSourceParam(const char* paramName) {\n  std::stringstream paramDef;\n  paramDef << \"var \" << paramName << \" = \";\n\n  std::string::size_type paramDefLoc =\n                              kBlitKernelSource().find(paramDef.str());\n  assert(paramDefLoc != std::string::npos);\n  std::string::size_type paramValLoc = paramDefLoc + paramDef.str().size();\n  std::string::size_type paramEndLoc =\n      kBlitKernelSource().find('\\n', paramDefLoc);\n  assert(paramDefLoc != std::string::npos);\n\n  std::string paramVal(&kBlitKernelSource()[paramValLoc],\n                       &kBlitKernelSource()[paramEndLoc]);\n  return std::stoi(paramVal);\n}\n\n\n#define DEFINE_KERNEL_PARAM_FUNC(name) \\\nstatic int& name() { \\\n    static std::once_flag initFlag; \\\n    static int val; \\\n    std::call_once(initFlag, [&]() { \\\n        val = GetKernelSourceParam(#name); \\\n    }); \\\n    return val; \\\n}\n\n// Use the macro to define the functions\nDEFINE_KERNEL_PARAM_FUNC(kCopyAlignedVecWidth)\nDEFINE_KERNEL_PARAM_FUNC(kCopyAlignedUnroll)\nDEFINE_KERNEL_PARAM_FUNC(kCopyMisalignedUnroll)\nDEFINE_KERNEL_PARAM_FUNC(kFillVecWidth)\nDEFINE_KERNEL_PARAM_FUNC(kFillUnroll)\n\nstatic unsigned extractAqlBits(unsigned v, unsigned pos, unsigned width) {\n  return (v >> pos) & ((1 << width) - 1);\n};\n\nBlitKernel::BlitKernel(core::Queue* queue)\n    : core::Blit(),\n      queue_(queue),\n      kernarg_async_(NULL),\n      kernarg_async_mask_(0),\n      kernarg_async_counter_(0),\n      bytes_queued_(0),\n      last_queued_(0),\n      pending_search_index_(0),\n      num_cus_(0) {\n  completion_signal_.handle = 0;\n}\n\nBlitKernel::~BlitKernel() {}\n\nhsa_status_t BlitKernel::Initialize(const core::Agent& agent) {\n  queue_bitmask_ = queue_->public_handle()->size - 1;\n\n  bytes_written_.resize(queue_->public_handle()->size);\n  memset(&bytes_written_[0], -1, bytes_written_.size() * sizeof(BytesWritten));\n\n  hsa_status_t status = HSA::hsa_signal_create(1, 0, NULL, &completion_signal_);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  const AMD::GpuAgent& gpuAgent = static_cast<const AMD::GpuAgent&>(agent);\n  kernarg_async_ = reinterpret_cast<KernelArgs*>(\n      gpuAgent.system_allocator()(queue_->public_handle()->size * AlignUp(sizeof(KernelArgs), 16),\n                                  16, core::MemoryRegion::AllocateNoFlags));\n\n  kernarg_async_mask_ = queue_->public_handle()->size - 1;\n\n  // Obtain the number of compute units in the underlying agent.\n  num_cus_ = gpuAgent.properties().NumFComputeCores / 4;\n\n  // Assemble shaders to AQL code objects.\n  std::map<KernelType, const char*> kernel_names = {\n      {KernelType::CopyAligned, \"CopyAligned\"},\n      {KernelType::CopyMisaligned, \"CopyMisaligned\"},\n      {KernelType::Fill, \"Fill\"}};\n\n  for (auto kernel_name : kernel_names) {\n    KernelCode& kernel = kernels_[kernel_name.first];\n    gpuAgent.AssembleShader(kernel_name.second, AMD::GpuAgent::AssembleTarget::AQL, kernel.code_buf_,\n                            kernel.code_buf_size_);\n  }\n\n  if (agent.profiling_enabled()) {\n    return EnableProfiling(true);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::Destroy(const core::Agent& agent) {\n  std::lock_guard<std::mutex> guard(lock_);\n\n  const AMD::GpuAgent& gpuAgent = static_cast<const AMD::GpuAgent&>(agent);\n\n  for (auto kernel_pair : kernels_) {\n    gpuAgent.ReleaseShader(kernel_pair.second.code_buf_,\n                           kernel_pair.second.code_buf_size_);\n  }\n\n  if (kernarg_async_ != NULL) {\n    gpuAgent.system_deallocator()(kernarg_async_);\n  }\n\n  if (completion_signal_.handle != 0) {\n    HSA::hsa_signal_destroy(completion_signal_);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::SubmitLinearCopyCommand(void* dst, const void* src,\n                                                 size_t size) {\n  // Protect completion_signal_.\n  std::lock_guard<std::mutex> guard(lock_);\n\n  HSA::hsa_signal_store_relaxed(completion_signal_, 1);\n\n  std::vector<core::Signal*> dep_signals(0);\n  std::vector<core::Signal*> gang_signals(0);\n\n  hsa_status_t stat = SubmitLinearCopyCommand(\n      dst, src, size, dep_signals, *core::Signal::Convert(completion_signal_), gang_signals);\n\n  if (stat != HSA_STATUS_SUCCESS) {\n    return stat;\n  }\n\n  // Wait for the packet to finish.\n  if (HSA::hsa_signal_wait_scacquire(completion_signal_, HSA_SIGNAL_CONDITION_LT, 1, uint64_t(-1),\n                                     HSA_WAIT_STATE_ACTIVE) != 0) {\n    // Signal wait returned unexpected value.\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::SubmitLinearCopyCommand(\n    void* dst, const void* src, size_t size,\n    std::vector<core::Signal*>& dep_signals, core::Signal& out_signal,\n    std::vector<core::Signal*>& gang_signals) {\n  // Reserve write index for barrier(s) + dispatch packet.\n  const uint32_t num_barrier_packet = uint32_t((dep_signals.size() + 4) / 5);\n  const uint32_t total_num_packet = num_barrier_packet + 1;\n\n  uint64_t write_index;\n  {\n    std::lock_guard<std::mutex> lock(reservation_lock_);\n    write_index = AcquireWriteIndex(total_num_packet);\n    RecordBlitHistory(size, write_index + total_num_packet - 1);\n  }\n\n  uint64_t write_index_temp = write_index;\n\n  // Insert barrier packets to handle dependent signals.\n  // Barrier bit keeps signal checking traffic from competing with a copy.\n  const uint16_t kBarrierPacketHeader = (HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE) |\n      (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) |\n      (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n\n  hsa_barrier_and_packet_t barrier_packet = {0};\n  barrier_packet.header = HSA_PACKET_TYPE_INVALID;\n\n  hsa_barrier_and_packet_t* queue_buffer =\n      reinterpret_cast<hsa_barrier_and_packet_t*>(\n          queue_->public_handle()->base_address);\n\n  const size_t dep_signal_count = dep_signals.size();\n  for (size_t i = 0; i < dep_signal_count; ++i) {\n    const size_t idx = i % 5;\n    barrier_packet.dep_signal[idx] = core::Signal::Convert(dep_signals[i]);\n    if (i == (dep_signal_count - 1) || idx == 4) {\n      std::atomic_thread_fence(std::memory_order_acquire);\n      queue_buffer[(write_index)&queue_bitmask_] = barrier_packet;\n      std::atomic_thread_fence(std::memory_order_release);\n      queue_buffer[(write_index)&queue_bitmask_].header = kBarrierPacketHeader;\n\n      LogPrint(HSA_AMD_LOG_FLAG_BLIT_KERNEL_PKTS,\n      \"HWq=%p, id=%lu, Barrier Header = \"\n      \"0x%x (type=%d, barrier=%d, acquire=%d, release=%d), \"\n      \"dep_signal=[0x%zx 0x%zx 0x%zx 0x%zx 0x%zx], completion_signal=0x%zx \"\n      \"rptr=%lu, wptr=%lu\",\n      queue_->public_handle()->base_address, queue_->public_handle()->id,\n      kBarrierPacketHeader,\n      extractAqlBits(kBarrierPacketHeader,\n                    HSA_PACKET_HEADER_TYPE, HSA_PACKET_HEADER_WIDTH_TYPE),\n      extractAqlBits(kBarrierPacketHeader,\n                    HSA_PACKET_HEADER_BARRIER, HSA_PACKET_HEADER_WIDTH_BARRIER),\n      extractAqlBits(kBarrierPacketHeader, HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE,\n                    HSA_PACKET_HEADER_WIDTH_SCACQUIRE_FENCE_SCOPE),\n      extractAqlBits(kBarrierPacketHeader, HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE,\n                    HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE),\n      barrier_packet.dep_signal[0].handle, \n      barrier_packet.dep_signal[1].handle,\n      barrier_packet.dep_signal[2].handle,\n      barrier_packet.dep_signal[3].handle, \n      barrier_packet.dep_signal[4].handle,\n      barrier_packet.completion_signal.handle, \n      queue_->LoadReadIndexRelaxed(), write_index);\n\n      ++write_index;\n\n      memset(&barrier_packet, 0, sizeof(hsa_barrier_and_packet_t));\n      barrier_packet.header = HSA_PACKET_TYPE_INVALID;\n    }\n  }\n\n  // Insert dispatch packet for copy kernel.\n  KernelArgs* args = ObtainAsyncKernelCopyArg();\n  KernelCode* kernel_code = nullptr;\n  int num_workitems = 0;\n\n  bool aligned = ((uintptr_t(src) & 0x3) == (uintptr_t(dst) & 0x3));\n\n  if (aligned) {\n    // Use dword-based aligned kernel.\n    kernel_code = &kernels_[KernelType::CopyAligned];\n\n    // Compute the size of each copy phase.\n    num_workitems = 64 * 4 * num_cus_;\n\n    // Phase 1 (byte copy) ends when destination is 0x100-aligned.\n    uintptr_t src_start = uintptr_t(src);\n    uintptr_t dst_start = uintptr_t(dst);\n    uint64_t phase1_size =\n        std::min(size, uint64_t(0x100 - (dst_start & 0xFF)) & 0xFF);\n\n    // Phase 2 (unrolled dwordx4 copy) ends when last whole block fits.\n    uint64_t phase2_block = num_workitems * sizeof(uint32_t) *\n                            kCopyAlignedUnroll() * kCopyAlignedVecWidth();\n    uint64_t phase2_size = ((size - phase1_size) / phase2_block) * phase2_block;\n\n    // Phase 3 (dword copy) ends when last whole dword fits.\n    uint64_t phase3_size =\n        ((size - phase1_size - phase2_size) / sizeof(uint32_t)) *\n        sizeof(uint32_t);\n\n    args->copy_aligned.phase1_src_start = src_start;\n    args->copy_aligned.phase1_dst_start = dst_start;\n    args->copy_aligned.phase2_src_start = src_start + phase1_size;\n    args->copy_aligned.phase2_dst_start = dst_start + phase1_size;\n    args->copy_aligned.phase3_src_start = src_start + phase1_size + phase2_size;\n    args->copy_aligned.phase3_dst_start = dst_start + phase1_size + phase2_size;\n    args->copy_aligned.phase4_src_start =\n        src_start + phase1_size + phase2_size + phase3_size;\n    args->copy_aligned.phase4_dst_start =\n        dst_start + phase1_size + phase2_size + phase3_size;\n    args->copy_aligned.phase4_src_end = src_start + size;\n    args->copy_aligned.phase4_dst_end = dst_start + size;\n    args->copy_aligned.num_workitems = num_workitems;\n  } else {\n    // Use byte-based misaligned kernel.\n    kernel_code = &kernels_[KernelType::CopyMisaligned];\n\n    // Compute the size of each copy phase.\n    num_workitems = 64 * 4 * num_cus_;\n\n    // Phase 1 (unrolled byte copy) ends when last whole block fits.\n    uintptr_t src_start = uintptr_t(src);\n    uintptr_t dst_start = uintptr_t(dst);\n    uint64_t phase1_block =\n        num_workitems * sizeof(uint8_t) * kCopyMisalignedUnroll();\n    uint64_t phase1_size = (size / phase1_block) * phase1_block;\n\n    args->copy_misaligned.phase1_src_start = src_start;\n    args->copy_misaligned.phase1_dst_start = dst_start;\n    args->copy_misaligned.phase2_src_start = src_start + phase1_size;\n    args->copy_misaligned.phase2_dst_start = dst_start + phase1_size;\n    args->copy_misaligned.phase2_src_end = src_start + size;\n    args->copy_misaligned.phase2_dst_end = dst_start + size;\n    args->copy_misaligned.num_workitems = num_workitems;\n  }\n\n  hsa_signal_t signal = {(core::Signal::Convert(&out_signal)).handle};\n  PopulateQueue(write_index, uintptr_t(kernel_code->code_buf_), args,\n                num_workitems, signal);\n\n  // Submit barrier(s) and dispatch packets.\n  ReleaseWriteIndex(write_index_temp, total_num_packet);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::SubmitLinearFillCommand(void* ptr, uint32_t value,\n                                                 size_t count) {\n  std::lock_guard<std::mutex> guard(lock_);\n\n  // Reject misaligned base address.\n  if ((uintptr_t(ptr) & 0x3) != 0) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // Compute the size of each fill phase.\n  int num_workitems = 64 * num_cus_;\n\n  // Phase 1 (unrolled dwordx4 copy) ends when last whole block fits.\n  uintptr_t dst_start = uintptr_t(ptr);\n  uint64_t fill_size = count * sizeof(uint32_t);\n\n  uint64_t phase1_block =\n      num_workitems * sizeof(uint32_t) * kFillUnroll() * kFillVecWidth();\n  uint64_t phase1_size = (fill_size / phase1_block) * phase1_block;\n\n  KernelArgs* args = ObtainAsyncKernelCopyArg();\n  args->fill.phase1_dst_start = dst_start;\n  args->fill.phase2_dst_start = dst_start + phase1_size;\n  args->fill.phase2_dst_end = dst_start + fill_size;\n  args->fill.fill_value = value;\n  args->fill.num_workitems = num_workitems;\n\n  // Submit dispatch packet.\n  HSA::hsa_signal_store_relaxed(completion_signal_, 1);\n\n  uint64_t write_index;\n  {\n    std::lock_guard<std::mutex> lock(reservation_lock_);\n    write_index = AcquireWriteIndex(1);\n    RecordBlitHistory(fill_size, write_index);\n  }\n\n  PopulateQueue(write_index, uintptr_t(kernels_[KernelType::Fill].code_buf_),\n                args, num_workitems, completion_signal_);\n\n  ReleaseWriteIndex(write_index, 1);\n\n  // Wait for the packet to finish.\n  if (HSA::hsa_signal_wait_scacquire(completion_signal_, HSA_SIGNAL_CONDITION_LT, 1, uint64_t(-1),\n                                     HSA_WAIT_STATE_ACTIVE) != 0) {\n    // Signal wait returned unexpected value.\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::EnableProfiling(bool enable) {\n  queue_->SetProfiling(enable);\n  return HSA_STATUS_SUCCESS;\n}\n\nuint64_t BlitKernel::AcquireWriteIndex(uint32_t num_packet) {\n  assert(queue_->public_handle()->size >= num_packet);\n\n  uint64_t write_index = queue_->AddWriteIndexAcqRel(num_packet);\n\n  while (write_index + num_packet - queue_->LoadReadIndexRelaxed() > queue_->public_handle()->size) {\n    os::YieldThread();\n  }\n\n  return write_index;\n}\n\nvoid BlitKernel::ReleaseWriteIndex(uint64_t write_index, uint32_t num_packet) {\n  // Update doorbel register with last packet id.\n  core::Signal* doorbell =\n      core::Signal::Convert(queue_->public_handle()->doorbell_signal);\n  doorbell->StoreRelease(write_index + num_packet - 1);\n}\n\nvoid BlitKernel::PopulateQueue(uint64_t index, uint64_t code_handle, void* args,\n                               uint32_t grid_size_x,\n                               hsa_signal_t completion_signal) {\n  assert(IsMultipleOf(args, 16));\n\n  hsa_kernel_dispatch_packet_t packet = { };\n\n  static const uint16_t kDispatchPacketHeader =\n      (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n      (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) |\n      (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n\n  packet.header = kInvalidPacketHeader;\n  packet.kernel_object = code_handle;\n  packet.kernarg_address = args;\n\n  // Setup working size.\n  const int kNumDimension = 1;\n  packet.setup = kNumDimension << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\n  packet.grid_size_x = AlignUp(static_cast<uint32_t>(grid_size_x), 64);\n  packet.grid_size_y = packet.grid_size_z = 1;\n  packet.workgroup_size_x = 64;\n  packet.workgroup_size_y = packet.workgroup_size_z = 1;\n\n  packet.completion_signal = completion_signal;\n\n  // Populate queue buffer with AQL packet.\n  hsa_kernel_dispatch_packet_t* queue_buffer =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(\n          queue_->public_handle()->base_address);\n  std::atomic_thread_fence(std::memory_order_acquire);\n  queue_buffer[index & queue_bitmask_] = packet;\n  std::atomic_thread_fence(std::memory_order_release);\n  if (queue_->IsDeviceMemRingBuf() && queue_->needsPcieOrdering()) {\n    // Ensure the packet body is written as header may get reordered when writing over PCIE\n    _mm_sfence();\n  }\n  __atomic_store_n(&(queue_buffer[index & queue_bitmask_].full_header),\n                    kDispatchPacketHeader | packet.setup << 16, __ATOMIC_RELEASE);\n\n  LogPrint(HSA_AMD_LOG_FLAG_BLIT_KERNEL_PKTS,\n    \"HWq=%p, id=%lu, Dispatch Header = \"\n    \"0x%x (type=%d, barrier=%d, acquire=%d, release=%d), \"\n    \"setup=%d, grid=[%zu, %zu, %zu], workgroup=[%zu, %zu, %zu], private_seg_size=%zu, \"\n    \"group_seg_size=%zu, kernel_obj=0x%zx, kernarg_address=0x%zx, completion_signal=0x%zx \"\n    \"rptr=%lu, wptr=%lu\",\n    queue_->public_handle()->base_address, queue_->public_handle()->id,\n    kDispatchPacketHeader,\n    extractAqlBits(kDispatchPacketHeader,\n                   HSA_PACKET_HEADER_TYPE, HSA_PACKET_HEADER_WIDTH_TYPE),\n    extractAqlBits(kDispatchPacketHeader,\n                   HSA_PACKET_HEADER_BARRIER, HSA_PACKET_HEADER_WIDTH_BARRIER),\n    extractAqlBits(kDispatchPacketHeader, HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE,\n                   HSA_PACKET_HEADER_WIDTH_SCACQUIRE_FENCE_SCOPE),\n    extractAqlBits(kDispatchPacketHeader, HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE,\n                   HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE),\n    packet.setup, static_cast<size_t>(packet.grid_size_x), static_cast<size_t>(packet.grid_size_y), static_cast<size_t>(packet.grid_size_z),\n    static_cast<size_t>(packet.workgroup_size_x), static_cast<size_t>(packet.workgroup_size_y), static_cast<size_t>(packet.workgroup_size_z),\n    static_cast<size_t>(packet.private_segment_size), static_cast<size_t>(packet.group_segment_size),\n    packet.kernel_object,reinterpret_cast<uintptr_t>(packet.kernarg_address),\n    completion_signal.handle, queue_->LoadReadIndexRelaxed(), index);\n}\n\nBlitKernel::KernelArgs* BlitKernel::ObtainAsyncKernelCopyArg() {\n  const uint32_t index =\n      atomic::Add(&kernarg_async_counter_, 1U, std::memory_order_acquire) & kernarg_async_mask_;\n\n  KernelArgs* arg = &kernarg_async_[index];\n  assert(IsMultipleOf(arg, 16));\n  return arg;\n}\n\nvoid BlitKernel::RecordBlitHistory(uint64_t size, uint64_t index) {\n  uint64_t queued = bytes_queued_;\n  bytes_queued_ += size;\n  bytes_written_[index & queue_bitmask_].bytes = queued;\n  bytes_written_[index & queue_bitmask_].index = index;\n  last_queued_ = index;\n}\n\nuint64_t BlitKernel::PendingBytes() {\n  uint64_t read = queue_->LoadReadIndexRelaxed();\n  uint64_t index = pending_search_index_.load();\n  uint64_t last = last_queued_;\n  // If the last blit command has been run then the blit is empty.\n  if (read > last) return 0;\n\n  index = Max(index, read);\n  while (index <= last) {\n    // Ensure any record we use was not wrapped.\n    if (index == bytes_written_[index & queue_bitmask_].index) {\n      uint64_t ret = bytes_queued_ - bytes_written_[index & queue_bitmask_].bytes;\n\n      // Store max search index.\n      uint64_t old = pending_search_index_.load();\n      while (old < index) {\n        if (pending_search_index_.compare_exchange_strong(old, index)) break;\n      }\n\n      return ret;\n    }\n    index++;\n  }\n  debug_warning(false && \"Race between PendingBytes and blit submission detected.\");\n  // Zero is a valid return in this case since the command which was last when the search started is\n  // now complete.\n  return 0;\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_blit_sdma.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_blit_sdma.h\"\n\n#include <algorithm>\n#include <atomic>\n#include <cmath>\n#include <cstring>\n#include <limits>\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/sdma_registers.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/default_signal.h\"\n\nnamespace rocr {\nnamespace AMD {\n\ninline uint32_t ptrlow32(const void* p) {\n  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p));\n}\n\ninline uint32_t ptrhigh32(const void* p) {\n#if defined(HSA_LARGE_MODEL)\n  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p) >> 32);\n#else\n  return 0;\n#endif\n}\n\nconst size_t BlitSdmaBase::kQueueSize = 1024 * 1024;\nconst size_t BlitSdmaBase::kCopyPacketSize = sizeof(SDMA_PKT_COPY_LINEAR);\nconst size_t BlitSdmaBase::kMaxSingleCopySize = SDMA_PKT_COPY_LINEAR::kMaxSize_;\nconst size_t BlitSdmaBase::kMaxSingleFillSize = SDMA_PKT_CONSTANT_FILL::kMaxSize_;\n\n// Initialize size of various sDMA commands use by this module\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::linear_copy_command_size_ = sizeof(SDMA_PKT_COPY_LINEAR);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::fill_command_size_ = sizeof(SDMA_PKT_CONSTANT_FILL);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::fence_command_size_ = sizeof(SDMA_PKT_FENCE);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::poll_command_size_ = sizeof(SDMA_PKT_POLL_REGMEM);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::flush_command_size_ = sizeof(SDMA_PKT_POLL_REGMEM);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::atomic_command_size_ = sizeof(SDMA_PKT_ATOMIC);\n\ntemplate <bool useGCR>\nconst uint32_t BlitSdma<useGCR>::timestamp_command_size_ = sizeof(SDMA_PKT_TIMESTAMP);\n\ntemplate <bool useGCR> const uint32_t BlitSdma<useGCR>::trap_command_size_ = sizeof(SDMA_PKT_TRAP);\n\ntemplate <bool useGCR> const uint32_t BlitSdma<useGCR>::gcr_command_size_ = sizeof(SDMA_PKT_GCR);\n\ntemplate <bool useGCR>\nBlitSdma<useGCR>::BlitSdma()\n    : agent_(NULL),\n      queue_start_addr_(NULL),\n      bytes_queued_(0),\n      parity_(false),\n      cached_reserve_index_(0),\n      cached_commit_index_(0),\n      platform_atomic_support_(true),\n      hdp_flush_support_(false),\n      gang_leader_(false),\n      is_ganged_(false),\n      min_submission_size_(0) {\n  std::memset(&queue_resource_, 0, sizeof(queue_resource_));\n}\n\ntemplate <bool useGCR> BlitSdma<useGCR>::~BlitSdma() {}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::Initialize(const core::Agent& agent, bool use_xgmi,\n                                          size_t linear_copy_size_override, int rec_eng) {\n  if (queue_start_addr_ != NULL) {\n    // Already initialized.\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (agent.device_type() != core::Agent::kAmdGpuDevice) {\n    return HSA_STATUS_ERROR;\n  }\n\n  agent_ = reinterpret_cast<AMD::GpuAgent*>(&const_cast<core::Agent&>(agent));\n\n  if (HSA_PROFILE_FULL == agent_->profile()) {\n    assert(false && \"Only support SDMA for dgpu currently\");\n    return HSA_STATUS_ERROR;\n  }\n\n  // Some GFX9 devices require a minimum of 64 DWORDS per ring buffer submission.\n  if (agent_->supported_isas()[0]->GetVersion() >= core::Isa::Version(9, 0, 0) &&\n     (agent_->supported_isas()[0]->GetVersion() <= core::Isa::Version(9, 0, 4) ||\n     agent_->supported_isas()[0]->GetVersion() == core::Isa::Version(9, 0, 12))) {\n    min_submission_size_ = 256;\n  }\n\n  const core::Runtime::LinkInfo& link =\n            core::Runtime::runtime_singleton_->GetLinkInfo( agent_->node_id(),\n                core::Runtime::runtime_singleton_->cpu_agents()[0]->node_id());\n  if (agent_->supported_isas()[0]->GetVersion() == core::Isa::Version(7, 0, 1)) {\n    platform_atomic_support_ = false;\n  } else {\n    platform_atomic_support_ = link.info.atomic_support_64bit;\n  }\n\n  // HDP flush supported on gfx900 and forward.\n  // gfx90a can support xGMI host to device connections so bypass HDP flush\n  // in this case.\n  // gfx101x seems to have issues with HDP flushes\n  if (agent_->supported_isas()[0]->GetMajorVersion() >= 9 &&\n      !(agent_->supported_isas()[0]->GetMajorVersion() == 10 && agent_->supported_isas()[0]->GetMinorVersion() == 1)) {\n    hdp_flush_support_ = link.info.link_type != HSA_AMD_LINK_INFO_TYPE_XGMI;\n  }\n\n  // Allocate queue buffer.\n  queue_start_addr_ =\n      (char*)agent_->system_allocator()(kQueueSize, 0x1000, core::MemoryRegion::AllocateExecutable);\n\n  if (queue_start_addr_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  MAKE_NAMED_SCOPE_GUARD(cleanupOnException, [&]() { Destroy(agent); };);\n  std::memset(queue_start_addr_, 0, kQueueSize);\n\n  bytes_written_.resize(kQueueSize);\n\n  // Access kernel driver to initialize the queue control block\n  // This call binds user mode queue object to underlying compute\n  // device. ROCr creates queues that are of two kinds: PCIe optimized\n  // and xGMI optimized. Which queue to create is indicated via input\n  // boolean flag\n  const HSA_QUEUE_TYPE kQueueType_ = rec_eng >= 0 ? HSA_QUEUE_SDMA_BY_ENG_ID :\n                                     (use_xgmi ? HSA_QUEUE_SDMA_XGMI : HSA_QUEUE_SDMA);\n  if (agent_->driver().CreateQueue(agent_->node_id(), kQueueType_, 100, HSA_QUEUE_PRIORITY_MAXIMUM,\n                                   rec_eng, queue_start_addr_, kQueueSize, nullptr,\n                                   queue_resource_) != HSA_STATUS_SUCCESS) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  cached_reserve_index_ = *reinterpret_cast<uint64_t*>(queue_resource_.Queue_write_ptr);\n  cached_commit_index_ = cached_reserve_index_;\n\n  if (core::g_use_interrupt_wait) {\n    signals_[0].reset(new core::InterruptSignal(0));\n    signals_[1].reset(new core::InterruptSignal(0));\n  } else {\n    signals_[0].reset(new core::DefaultSignal(0));\n    signals_[1].reset(new core::DefaultSignal(0));\n  }\n\n  max_single_linear_copy_size_ = linear_copy_size_override;\n\n  cleanupOnException.Dismiss();\n  return HSA_STATUS_SUCCESS;\n}\n\ntemplate <bool useGCR> hsa_status_t BlitSdma<useGCR>::Destroy(const core::Agent& agent) {\n  // Release all allocated resources and reset them to zero.\n\n  if (queue_resource_.QueueId != 0) {\n    // Release queue resources from the kernel\n    auto err = agent_->driver().DestroyQueue(queue_resource_.QueueId);\n    assert(err == HSA_STATUS_SUCCESS);\n    memset(&queue_resource_, 0, sizeof(queue_resource_));\n  }\n\n  if (queue_start_addr_ != NULL) {\n    // Release queue buffer.\n    agent_->system_deallocator()(queue_start_addr_);\n  }\n\n  queue_start_addr_ = NULL;\n  cached_reserve_index_ = 0;\n  cached_commit_index_ = 0;\n\n  signals_[0].reset();\n  signals_[1].reset();\n\n  return HSA_STATUS_SUCCESS;\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitBlockingCommand(const void* cmd, size_t cmd_size,\n                                                     uint64_t size) {\n  ScopedAcquire<KernelMutex> lock(&lock_);\n\n  // Alternate between completion signals\n  // Using two allows overlapping command writing and copies\n  core::Signal* completionSignal;\n  if (parity_)\n    completionSignal = signals_[0].get();\n  else\n    completionSignal = signals_[1].get();\n  parity_ ^= true;\n\n  // Wait for prior operation with this signal to complete\n  completionSignal->WaitRelaxed(HSA_SIGNAL_CONDITION_EQ, 0, -1, HSA_WAIT_STATE_BLOCKED);\n\n  // Mark signal as in use, guard against exception leaving the signal in an unusable state.\n  completionSignal->StoreRelaxed(2);\n  MAKE_SCOPE_GUARD([&]() { completionSignal->StoreRelaxed(0); });\n  lock.Release();\n\n  std::vector<core::Signal*> gang_signals(0);\n\n  // Submit command and wait for completion\n  hsa_status_t ret =\n      SubmitCommand(cmd, cmd_size, size, std::vector<core::Signal*>(), *completionSignal,\n                    gang_signals);\n  completionSignal->WaitRelaxed(HSA_SIGNAL_CONDITION_EQ, 1, -1, HSA_WAIT_STATE_BLOCKED);\n  return ret;\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitCommand(const void* cmd, size_t cmd_size, uint64_t size,\n                                             const std::vector<core::Signal*>& dep_signals,\n                                             core::Signal& out_signal,\n                                             std::vector<core::Signal*>& gang_signals) {\n  uint32_t num_poll_command = 0;\n\n  // Cached copy of dep_signals[i]->LoadRelaxed\n  uint64_t dep_signals_value[HSA_MAX_DEP_SIGNALS];\n\n  for (size_t i = 0; i < dep_signals.size(); ++i) {\n    // The signal is 64 bit value, and poll checks for 32 bit value.\n    // If the signal is already 0, then we do not need to poll.\n    // If the upper 32-bits of the signal is 0, then we only need to poll the\n    // lower 32-bits\n    dep_signals_value[i] = dep_signals[i]->LoadRelaxed();\n    if (dep_signals_value[i]) {\n      num_poll_command++;\n      if (dep_signals_value[i] >> 32)\n        num_poll_command++;\n    }\n  }\n\n  // Workaround for rare-issue on gfx908 where SDMA_OP_POLL_REGMEM returns before\n  // polled memory is cleared\n  static bool doublePoll = agent_->supported_isas()[0]->GetMajorVersion() == 9 &&\n                           agent_->supported_isas()[0]->GetMinorVersion() == 0 &&\n                           agent_->supported_isas()[0]->GetStepping() != 10;\n  if (doublePoll)\n    num_poll_command *= 2;\n\n  const uint32_t total_poll_command_size =\n      (num_poll_command * poll_command_size_);\n\n  // Load the profiling state early in case the user disable or enable the\n  // profiling in the middle of the call.\n  const bool profiling_enabled = agent_->profiling_enabled();\n\n  uint64_t* start_ts_addr = nullptr;\n  uint64_t* end_ts_addr = nullptr;\n  uint32_t total_timestamp_command_size = 0;\n\n  // Gang leader polls gang item completions and does final decrement or\n  // completion of gang signal to prevent race between poll and signal\n  // destruction.\n  uint32_t total_gang_complete_command_size = poll_command_size_ +\n         (platform_atomic_support_ ? atomic_command_size_ : fence_command_size_);\n  uint32_t total_gang_command_size = gang_leader_ ?\n          static_cast<uint32_t>(gang_signals.size()) * total_gang_complete_command_size : 0;\n\n  if (profiling_enabled && (gang_leader_ || gang_signals.empty())) {\n    out_signal.GetSdmaTsAddresses(start_ts_addr, end_ts_addr);\n    total_timestamp_command_size = 2 * timestamp_command_size_;\n  }\n\n  // On agent that does not support platform atomic, we replace it with\n  // one or two fence packet(s) to update the signal value. The reason fence\n  // is used and not write packet is because the SDMA engine may overlap a\n  // serial copy/write packets.\n  const uint64_t completion_signal_value =\n      static_cast<uint64_t>(out_signal.LoadRelaxed() - 1);\n  const size_t sync_command_size = (platform_atomic_support_)\n                                       ? atomic_command_size_\n                                       : (completion_signal_value > UINT32_MAX)\n                                             ? 2 * fence_command_size_\n                                             : fence_command_size_;\n\n  // If the signal is an interrupt signal, we also need to make SDMA engine to\n  // send interrupt packet to IH.\n  const size_t interrupt_command_size =\n      (out_signal.signal_.event_mailbox_ptr != 0)\n          ? (fence_command_size_ + trap_command_size_)\n          : 0;\n\n  // Add space for acquire or release Hdp flush command\n  uint32_t flush_cmd_size = 0;\n  if (core::Runtime::runtime_singleton_->flag().enable_sdma_hdp_flush()) {\n    if (hdp_flush_support_) {\n      flush_cmd_size = flush_command_size_;\n    }\n  }\n\n  // Add space for cache flush.\n  if (useGCR) flush_cmd_size += gcr_command_size_ * 2;\n\n  const uint32_t total_command_size = total_poll_command_size + cmd_size + sync_command_size +\n      total_timestamp_command_size + interrupt_command_size + flush_cmd_size + total_gang_command_size;\n  const uint32_t pad_size = total_command_size < min_submission_size_ ?\n                            min_submission_size_ - total_command_size : 0;\n\n  uint64_t curr_index;\n  char* command_addr;\n  uint64_t prior_bytes, post_bytes;\n  {\n    std::lock_guard<std::mutex> lock(reservation_lock_);\n    command_addr = AcquireWriteAddress(total_command_size + pad_size, curr_index);\n    if (command_addr == nullptr) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n    prior_bytes = bytes_queued_;\n    bytes_queued_ += size;\n    post_bytes = bytes_queued_;\n  }\n  uint32_t wrapped_index = WrapIntoRing(curr_index);\n\n  for (size_t i = 0; i < dep_signals.size(); ++i) {\n    if (dep_signals_value[i]) {\n      uint32_t* signal_addr =\n          reinterpret_cast<uint32_t*>(dep_signals[i]->ValueLocation());\n\n      if (dep_signals_value[i] >> 32) {\n        // Wait for the higher 32 bits to 0.\n        BuildPollCommand(command_addr, &signal_addr[1], 0);\n        command_addr += poll_command_size_;\n        bytes_written_[wrapped_index] = prior_bytes;\n        wrapped_index += poll_command_size_;\n\n        if (doublePoll) {\n          BuildPollCommand(command_addr, &signal_addr[1], 0);\n          command_addr += poll_command_size_;\n          bytes_written_[wrapped_index] = prior_bytes;\n          wrapped_index += poll_command_size_;\n        }\n      }\n      // Then wait for the lower 32 bits to 0.\n      BuildPollCommand(command_addr, &signal_addr[0], 0);\n      command_addr += poll_command_size_;\n      bytes_written_[wrapped_index] = prior_bytes;\n      wrapped_index += poll_command_size_;\n\n      if (doublePoll) {\n        BuildPollCommand(command_addr, &signal_addr[0], 0);\n        command_addr += poll_command_size_;\n        bytes_written_[wrapped_index] = prior_bytes;\n        wrapped_index += poll_command_size_;\n      }\n    }\n  }\n\n  if (profiling_enabled && (gang_leader_ || gang_signals.empty())) {\n    BuildGetGlobalTimestampCommand(command_addr, reinterpret_cast<void*>(start_ts_addr));\n    command_addr += timestamp_command_size_;\n    bytes_written_[wrapped_index] = prior_bytes;\n    wrapped_index += timestamp_command_size_;\n  }\n\n  // Issue a Hdp flush cmd\n  if (core::Runtime::runtime_singleton_->flag().enable_sdma_hdp_flush()) {\n    if (hdp_flush_support_) {\n      BuildHdpFlushCommand(command_addr);\n      command_addr += flush_command_size_;\n      bytes_written_[wrapped_index] = prior_bytes;\n      wrapped_index += flush_command_size_;\n    }\n  }\n\n  // Issue cache invalidate\n  if (useGCR) {\n    BuildGCRCommand(command_addr, true);\n    command_addr += gcr_command_size_;\n    bytes_written_[wrapped_index] = prior_bytes;\n    wrapped_index += gcr_command_size_;\n  }\n\n  // Do the command after all polls are satisfied.\n  memcpy(command_addr, cmd, cmd_size);\n  command_addr += cmd_size;\n  bytes_written_.fill(wrapped_index, wrapped_index + cmd_size, prior_bytes);\n  wrapped_index += cmd_size;\n\n  // Issue cache writeback\n  if (useGCR) {\n    BuildGCRCommand(command_addr, false);\n    command_addr += gcr_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += gcr_command_size_;\n  }\n\n  if (profiling_enabled && (gang_leader_ || gang_signals.empty())) {\n    assert(IsMultipleOf(end_ts_addr, 32));\n    BuildGetGlobalTimestampCommand(command_addr,\n                                   reinterpret_cast<void*>(end_ts_addr));\n    command_addr += timestamp_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += timestamp_command_size_;\n  }\n\n  // Wait for non-leaders gang items to complete\n  if (gang_leader_) {\n    for (int i = 0; i < gang_signals.size(); i++) {\n      uint32_t* gang_signal_addr =\n          reinterpret_cast<uint32_t*>(gang_signals[i]->ValueLocation());\n      BuildPollCommand(command_addr, gang_signal_addr, 1);\n      command_addr += poll_command_size_;\n      bytes_written_[wrapped_index] = prior_bytes;\n      wrapped_index += poll_command_size_;\n\n      // After non-leader gang-items have completed, decrement the gang signal value.\n      if (platform_atomic_support_) {\n        BuildAtomicDecrementCommand(command_addr, gang_signal_addr);\n        command_addr += atomic_command_size_;\n        bytes_written_[wrapped_index] = post_bytes;\n        wrapped_index += atomic_command_size_;\n      } else {\n        BuildFenceCommand(command_addr, gang_signal_addr, 0);\n        command_addr += fence_command_size_;\n        bytes_written_[wrapped_index] = post_bytes;\n        wrapped_index += fence_command_size_;\n      }\n    }\n  }\n\n  // After transfer is completed, decrement the signal value.\n  if (platform_atomic_support_) {\n    BuildAtomicDecrementCommand(command_addr, out_signal.ValueLocation());\n    command_addr += atomic_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += atomic_command_size_;\n  } else {\n    uint32_t* signal_value_location = reinterpret_cast<uint32_t*>(out_signal.ValueLocation());\n    if (completion_signal_value > UINT32_MAX) {\n      BuildFenceCommand(command_addr, signal_value_location + 1,\n                        static_cast<uint32_t>(completion_signal_value >> 32));\n      command_addr += fence_command_size_;\n      bytes_written_[wrapped_index] = post_bytes;\n      wrapped_index += fence_command_size_;\n    }\n\n    BuildFenceCommand(command_addr, signal_value_location,\n                      static_cast<uint32_t>(completion_signal_value));\n    command_addr += fence_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += fence_command_size_;\n  }\n\n  // Update mailbox event and send interrupt to IH.\n  if (out_signal.signal_.event_mailbox_ptr != 0) {\n    BuildFenceCommand(command_addr,\n                      reinterpret_cast<uint32_t*>(out_signal.signal_.event_mailbox_ptr),\n                      static_cast<uint32_t>(out_signal.signal_.event_id));\n    command_addr += fence_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += fence_command_size_;\n\n    BuildTrapCommand(command_addr, out_signal.signal_.event_id);\n    command_addr += trap_command_size_;\n    bytes_written_[wrapped_index] = post_bytes;\n    wrapped_index += trap_command_size_;\n  }\n\n  // Pad size is DWORD aligned since all commands are dword aligned.\n  // Insert NOP header DWORD with value of the number of null DWORDs shifted\n  // by 16 bits to pad total submission.\n  if (pad_size) {\n    memset(command_addr, 0, pad_size);\n    uint32_t *dword_command_addr = reinterpret_cast<uint32_t*>(command_addr);\n    dword_command_addr[0] = (pad_size/4 - 1) << 16;\n  }\n\n  ReleaseWriteAddress(curr_index, total_command_size + pad_size);\n\n  return HSA_STATUS_SUCCESS;\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitLinearCopyCommand(void* dst, const void* src, size_t size) {\n  // Break the copy into multiple copy operation incase the copy size exceeds\n  // the SDMA linear copy limit.\n  const size_t max_copy_size = max_single_linear_copy_size_ ? max_single_linear_copy_size_ :\n                               kMaxSingleCopySize;\n  const uint32_t num_copy_command = (size + max_copy_size - 1) / max_copy_size;\n\n  std::vector<SDMA_PKT_COPY_LINEAR> buff(num_copy_command);\n  BuildCopyCommand(reinterpret_cast<char*>(&buff[0]), num_copy_command, dst, src, size);\n\n  return SubmitBlockingCommand(&buff[0], buff.size() * sizeof(SDMA_PKT_COPY_LINEAR), size);\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitLinearCopyCommand(void* dst, const void* src, size_t size,\n                                                       std::vector<core::Signal*>& dep_signals,\n                                                       core::Signal& out_signal,\n                                                       std::vector<core::Signal*>& gang_signals) {\n  // Break the copy into multiple copy operations when the copy size exceeds\n  // the SDMA linear copy limit.\n  const size_t max_copy_size = max_single_linear_copy_size_ ? max_single_linear_copy_size_ :\n                               kMaxSingleCopySize;\n  const uint32_t num_copy_command = (size + max_copy_size - 1) / max_copy_size;\n\n  // Assemble copy packets.\n  std::vector<SDMA_PKT_COPY_LINEAR> buff(num_copy_command);\n  BuildCopyCommand(reinterpret_cast<char*>(&buff[0]), num_copy_command, dst, src, size);\n\n  return SubmitCommand(&buff[0], buff.size() * sizeof(SDMA_PKT_COPY_LINEAR), size, dep_signals,\n                       out_signal, gang_signals);\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitCopyRectCommand(\n    const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,\n    const hsa_dim3_t* src_offset, const hsa_dim3_t* range, std::vector<core::Signal*>& dep_signals,\n    core::Signal& out_signal) {\n  // Hardware requires DWORD alignment for base address, pitches\n  // Also confirm that we have a geometric rect (copied block does not wrap an edge).\n  if (((uintptr_t)dst->base) % 4 != 0 || ((uintptr_t)src->base) % 4 != 0)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                             \"Copy rect base address not aligned.\");\n  if (((uintptr_t)dst->pitch) % 4 != 0 || ((uintptr_t)src->pitch) % 4 != 0)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect pitch not aligned.\");\n  if (((uintptr_t)dst->slice) % 4 != 0 || ((uintptr_t)src->slice) % 4 != 0)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect slice not aligned.\");\n  if (uint64_t(src_offset->x) + range->x > src->pitch ||\n      uint64_t(dst_offset->x) + range->x > dst->pitch)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect width out of range.\");\n  if ((src->slice != 0) && (uint64_t(src_offset->y) + range->y) > src->slice / src->pitch)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect height out of range.\");\n  if ((dst->slice != 0) && (uint64_t(dst_offset->y) + range->y) > dst->slice / dst->pitch)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect height out of range.\");\n  if (range->z > 1 && (src->slice == 0 || dst->slice == 0))\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect slice needed.\");\n\n  // GFX12 or later use a different packet format that is incompatible (fields changed in size and location).\n  const bool isGFX12Plus =\n                        (agent_->supported_isas()[0]->GetMajorVersion() >= 12);\n\n  // Common and GFX12 packet must match in size to use same code for vector/append.\n  static_assert(sizeof(SDMA_PKT_COPY_LINEAR_RECT) == sizeof(SDMA_PKT_COPY_LINEAR_RECT_GFX12), \"\");\n\n  const uint max_pitch = 1 << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::pitch_bits : SDMA_PKT_COPY_LINEAR_RECT::pitch_bits);\n\n  std::vector<SDMA_PKT_COPY_LINEAR_RECT> pkts;\n  std::vector<uint64_t> bytes_moved;\n  auto append = [&](size_t size) {\n    assert(size == sizeof(SDMA_PKT_COPY_LINEAR_RECT) && \"SDMA packet size missmatch\");\n    pkts.emplace_back(SDMA_PKT_COPY_LINEAR_RECT());\n    return &pkts.back();\n  };\n\n  // Do wide pitch 2D copies along X-Z\n  if (range->z == 1 && (src->pitch > max_pitch || dst->pitch > max_pitch)) {\n    hsa_pitched_ptr_t Src = *src;\n    hsa_pitched_ptr_t Dst = *dst;\n    hsa_dim3_t Soff = *src_offset;\n    hsa_dim3_t Doff = *dst_offset;\n    hsa_dim3_t Range = *range;\n\n    Src.base = static_cast<char*>(Src.base) + Soff.z * Src.slice + Soff.y * Src.pitch;\n    Dst.base = static_cast<char*>(Dst.base) + Doff.z * Dst.slice + Doff.y * Dst.pitch;\n    Soff.y = Soff.z = 0;\n    Doff.y = Doff.z = 0;\n\n    Src.slice = Src.pitch;\n    Src.pitch = 0;\n    Dst.slice = Dst.pitch;\n    Dst.pitch = 0;\n\n    Range.z = Range.y;\n    Range.y = 1;\n\n    BuildCopyRectCommand(append, &Dst, &Doff, &Src, &Soff, &Range);\n  } else {\n    BuildCopyRectCommand(append, dst, dst_offset, src, src_offset, range);\n  }\n\n  uint64_t size = static_cast<uint64_t>(range->x) * static_cast<uint64_t>(range->y) * range->z;\n\n  std::vector<core::Signal*> gang_signals(0);\n\n  return SubmitCommand(&pkts[0], pkts.size() * sizeof(SDMA_PKT_COPY_LINEAR_RECT), size, dep_signals,\n                       out_signal, gang_signals);\n}\n\ntemplate <bool useGCR>\nhsa_status_t BlitSdma<useGCR>::SubmitLinearFillCommand(void* ptr, uint32_t value, size_t count) {\n  const size_t size = count * sizeof(uint32_t);\n\n  const uint32_t num_fill_command = (size + kMaxSingleFillSize - 1) / kMaxSingleFillSize;\n\n  std::vector<SDMA_PKT_CONSTANT_FILL> buff(num_fill_command);\n  BuildFillCommand(reinterpret_cast<char*>(&buff[0]), num_fill_command, ptr, value, count);\n\n  return SubmitBlockingCommand(&buff[0], buff.size() * sizeof(SDMA_PKT_CONSTANT_FILL), size);\n}\n\ntemplate <bool useGCR> hsa_status_t BlitSdma<useGCR>::EnableProfiling(bool enable) {\n  return HSA_STATUS_SUCCESS;\n}\n\ntemplate <bool useGCR>\nchar* BlitSdma<useGCR>::AcquireWriteAddress(uint32_t cmd_size, uint64_t& curr_index) {\n  // Ring is full when all but one byte is written.\n  if (cmd_size >= kQueueSize) {\n    return nullptr;\n  }\n\n  while (true) {\n    curr_index = atomic::Load(&cached_reserve_index_, std::memory_order_acquire);\n\n    // Check whether a linear region of the requested size is available.\n    // If == cmd_size: region is at beginning of ring.\n    // If < cmd_size: region intersects end of ring, pad with no-ops and retry.\n    if (WrapIntoRing(curr_index + cmd_size) < cmd_size) {\n      PadRingToEnd(curr_index);\n      continue;\n    }\n\n    // Check whether the engine has finished using this region.\n    const uint64_t new_index = curr_index + cmd_size;\n\n    if (CanWriteUpto(new_index) == false) {\n      // Wait for read index to move and try again.\n      os::YieldThread();\n      continue;\n    }\n\n    // Try to reserve this part of the ring.\n    if (atomic::Cas(&cached_reserve_index_, new_index, curr_index, std::memory_order_release) ==\n        curr_index) {\n      return queue_start_addr_ + WrapIntoRing(curr_index);\n    }\n\n    // Another thread reserved curr_index, try again.\n    os::YieldThread();\n  }\n\n  return nullptr;\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::UpdateWriteAndDoorbellRegister(uint64_t curr_index, uint64_t new_index) {\n  while (true) {\n    // Make sure that the address before ::curr_index is already released.\n    // Otherwise the CP may read invalid packets.\n    if (atomic::Load(&cached_commit_index_, std::memory_order_acquire) == curr_index) {\n      if (core::Runtime::runtime_singleton_->flag().sdma_wait_idle()) {\n        // TODO: remove when sdma wpointer issue is resolved.\n        // Wait until the SDMA engine finish processing all packets before\n        // updating the wptr and doorbell.\n        while (WrapIntoRing(*reinterpret_cast<uint64_t*>(queue_resource_.Queue_read_ptr)) !=\n               WrapIntoRing(curr_index)) {\n          os::YieldThread();\n        }\n      }\n\n      // Update write pointer and doorbell register.\n      *reinterpret_cast<uint64_t*>(queue_resource_.Queue_write_ptr) = new_index;\n\n      // Ensure write pointer is visible to GPU before doorbell.\n      std::atomic_thread_fence(std::memory_order_release);\n\n      *reinterpret_cast<uint64_t*>(queue_resource_.Queue_DoorBell) = new_index;\n\n      atomic::Store(&cached_commit_index_, new_index, std::memory_order_release);\n      break;\n    }\n\n    // Waiting for another thread to submit preceding commands first.\n    os::YieldThread();\n  }\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::ReleaseWriteAddress(uint64_t curr_index, uint32_t cmd_size) {\n  if (cmd_size > kQueueSize) {\n    assert(false && \"cmd_addr is outside the queue buffer range\");\n    return;\n  }\n\n  UpdateWriteAndDoorbellRegister(curr_index, curr_index + cmd_size);\n}\n\ntemplate <bool useGCR> void BlitSdma<useGCR>::PadRingToEnd(uint64_t curr_index) {\n  // Reserve region from here to the end of the ring.\n  uint64_t new_index = curr_index + (kQueueSize - WrapIntoRing(curr_index));\n\n  // Check whether the engine has finished using this region.\n  if (CanWriteUpto(new_index) == false) {\n    // Wait for read index to move and try again.\n    return;\n  }\n\n  if (atomic::Cas(&cached_reserve_index_, new_index, curr_index, std::memory_order_release) ==\n      curr_index) {\n    // Write and submit NOP commands in reserved region.\n    char* nop_address = queue_start_addr_ + WrapIntoRing(curr_index);\n    memset(nop_address, 0, new_index - curr_index);\n\n    // Pad pending bytes tracking\n    bytes_written_.fill(WrapIntoRing(curr_index), WrapIntoRing(new_index), bytes_queued_);\n\n    UpdateWriteAndDoorbellRegister(curr_index, new_index);\n  }\n}\n\ntemplate <bool useGCR> uint32_t BlitSdma<useGCR>::WrapIntoRing(uint64_t index) {\n  return index & (kQueueSize - 1);\n}\n\ntemplate <bool useGCR> bool BlitSdma<useGCR>::CanWriteUpto(uint64_t upto_index) {\n  // Get/calculate the monotonic read index.\n  uint64_t hw_read_index = *reinterpret_cast<uint64_t*>(queue_resource_.Queue_read_ptr);\n\n  // Check whether the read pointer has passed the given index.\n  // At most we can submit (kQueueSize - 1) bytes at a time.\n  return (upto_index - hw_read_index) < kQueueSize;\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildFenceCommand(char* fence_command_addr, uint32_t* fence,\n                                         uint32_t fence_value) {\n  assert(fence_command_addr != NULL);\n  SDMA_PKT_FENCE* packet_addr =\n      reinterpret_cast<SDMA_PKT_FENCE*>(fence_command_addr);\n\n  memset(packet_addr, 0, sizeof(SDMA_PKT_FENCE));\n\n  packet_addr->HEADER_UNION.op = SDMA_OP_FENCE;\n\n  if (agent_->supported_isas()[0]->GetMajorVersion() >= 10) {\n    packet_addr->HEADER_UNION.mtype = 3;\n  }\n\n  packet_addr->ADDR_LO_UNION.addr_31_0 = ptrlow32(fence);\n\n  packet_addr->ADDR_HI_UNION.addr_63_32 = ptrhigh32(fence);\n\n  packet_addr->DATA_UNION.data = fence_value;\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildCopyCommand(char* cmd_addr, uint32_t num_copy_command, void* dst,\n                                        const void* src, size_t size) {\n  size_t cur_size = 0;\n  const size_t max_copy_size = max_single_linear_copy_size_ ? max_single_linear_copy_size_ :\n                                                              kMaxSingleCopySize;\n  for (uint32_t i = 0; i < num_copy_command; ++i) {\n    const uint32_t copy_size =\n        static_cast<uint32_t>(std::min((size - cur_size), max_copy_size));\n\n    void* cur_dst = static_cast<char*>(dst) + cur_size;\n    const void* cur_src = static_cast<const char*>(src) + cur_size;\n\n    SDMA_PKT_COPY_LINEAR* packet_addr =\n        reinterpret_cast<SDMA_PKT_COPY_LINEAR*>(cmd_addr);\n\n    memset(packet_addr, 0, sizeof(SDMA_PKT_COPY_LINEAR));\n\n    packet_addr->HEADER_UNION.op = SDMA_OP_COPY;\n    packet_addr->HEADER_UNION.sub_op = SDMA_SUBOP_COPY_LINEAR;\n\n    if (max_copy_size == (1 << 30) -1)\n      packet_addr->COUNT_UNION.count_ext.count = copy_size - 1; /* count is 1-based */\n    else\n      packet_addr->COUNT_UNION.count.count = copy_size - 1; /* count is 1-based */\n\n    packet_addr->SRC_ADDR_LO_UNION.src_addr_31_0 = ptrlow32(cur_src);\n    packet_addr->SRC_ADDR_HI_UNION.src_addr_63_32 = ptrhigh32(cur_src);\n\n    packet_addr->DST_ADDR_LO_UNION.dst_addr_31_0 = ptrlow32(cur_dst);\n    packet_addr->DST_ADDR_HI_UNION.dst_addr_63_32 = ptrhigh32(cur_dst);\n\n    cmd_addr += linear_copy_command_size_;\n    cur_size += copy_size;\n  }\n\n  assert(cur_size == size);\n}\n\n/*\nCopies are done in terms of elements (1, 2, 4, 8, or 16 bytes) and have alignment restrictions.\nElements are coded by the log2 of the element size in bytes (ie. element 0=1 byte, 4=16 byte).\nThis routine breaks a large rect into tiles that can be handled by hardware.  Pitches and offsets\nmust be representable in terms of elements in all tiles of the copy.\n*/\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildCopyRectCommand(const std::function<void*(size_t)>& append,\n                                            const hsa_pitched_ptr_t* dst,\n                                            const hsa_dim3_t* dst_offset,\n                                            const hsa_pitched_ptr_t* src,\n                                            const hsa_dim3_t* src_offset, const hsa_dim3_t* range) {\n  // Returns the index of the first set bit (ie log2 of the largest power of 2 that evenly divides\n  // width), the largest element that perfectly covers width.\n  // width | 16 ensures that we don't return a higher element than is supported and avoids\n  // issues with 0.\n  auto maxAlignedElement = [](size_t width) {\n    return __builtin_ctz(width | 16);\n  };\n\n  // GFX12 or later use a different packet format that is incompatible (fields changed in size and location).\n  const bool isGFX12Plus =\n                      (agent_->supported_isas()[0]->GetMajorVersion() >= 12);\n\n  // Limits in terms of element count\n  const uint32_t max_pitch = 1    << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::pitch_bits   : SDMA_PKT_COPY_LINEAR_RECT::pitch_bits);\n  const uint64_t max_slice = 1ULL << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::slice_bits   : SDMA_PKT_COPY_LINEAR_RECT::slice_bits);\n  const uint32_t max_x     = 1    << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::rect_xy_bits : SDMA_PKT_COPY_LINEAR_RECT::rect_xy_bits);\n  const uint32_t max_y     = 1    << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::rect_xy_bits : SDMA_PKT_COPY_LINEAR_RECT::rect_xy_bits);\n  const uint32_t max_z     = 1    << (isGFX12Plus ? SDMA_PKT_COPY_LINEAR_RECT_GFX12::rect_z_bits  : SDMA_PKT_COPY_LINEAR_RECT::rect_z_bits);\n\n  // Find maximum element that describes the pitch and slice.\n  // Pitch and slice must both be represented in units of elements.  No element larger than this\n  // may be used in any tile as the pitches would not be exactly represented.\n  int max_ele = Min(maxAlignedElement(src->pitch), maxAlignedElement(dst->pitch));\n  if (range->z != 1)  // Only need to consider slice if HW will copy along Z.\n    max_ele = Min(max_ele, maxAlignedElement(src->slice), maxAlignedElement(dst->slice));\n\n  /*\n  Find the minimum element size that will be needed for any tile.\n\n  No subdivision of a range admits a larger element size for the smallest element in any subdivision\n  than the element size that covers the whole range, though some can be worse (this is easily model\n  checked).  Subdividing with any element larger than the covering element won't change the covering\n  element of the remainder\n  ( Range%Element = (Range-N*LargerElement)%Element since LargerElement%Element=0 ).\n    Ex. range->x=71, assume max range is 16 elements:  We can break at 64 giving tiles:\n    [0,63], [64-70] (width 64 & 7).  64 is covered by element 4 (16B) and 7 is covered by element 0\n    (1B).  Exactly covering 71 requires using element 0.\n\n  Base addresses in each tile must be DWORD aligned, if not then the offset from an aligned address\n  must be represented in elements.  This may reduce the size of the element, but since elements are\n  integer multiples of each other this is harmless.\n\n  src and dst base has already been checked for DWORD alignment so we only need to consider the\n  offset here.\n  */\n  int min_ele = Min(max_ele, maxAlignedElement(range->x), maxAlignedElement(src_offset->x % 4),\n                    maxAlignedElement(dst_offset->x % 4));\n\n  // Check that pitch and slice can be represented in the tile with the smallest element\n  if ((src->pitch >> min_ele) > max_pitch || (dst->pitch >> min_ele) > max_pitch)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Copy rect pitch out of limits.\\n\");\n  if (range->z != 1) {  // Only need to consider slice if HW will copy along Z.\n    if ((src->slice >> min_ele) > max_slice || (dst->slice >> min_ele) > max_slice)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                               \"Copy rect slice out of limits.\\n\");\n  }\n\n  // Break copy into tiles\n  for (uint32_t z = 0; z < range->z; z += max_z) {\n    for (uint32_t y = 0; y < range->y; y += max_y) {\n      uint32_t x = 0;\n      while (x < range->x) {\n        uint32_t width = range->x - x;\n\n        // Get largest element which describes the start of this tile after its base address has\n        // been aligned.  Base addresses must be DWORD (4 byte) aligned.\n        int aligned_ele = Min(maxAlignedElement((src_offset->x + x) % 4),\n                              maxAlignedElement((dst_offset->x + x) % 4), max_ele);\n\n        // Get largest permissible element which exactly covers width\n        int element = Min(maxAlignedElement(width), aligned_ele);\n        int xcount = width >> element;\n\n        // If width is too large then width is at least max_x bytes (bigger than any element) so\n        // drop the width restriction and clip element count to max_x.\n        if (xcount > max_x) {\n          element = aligned_ele;\n          xcount = Min(width >> element, max_x);\n        }\n\n        // Get base addresses and offsets for this tile.\n        uintptr_t sbase = (uintptr_t)src->base + src_offset->x + x +\n            (src_offset->y + y) * src->pitch + (src_offset->z + z) * src->slice;\n        uintptr_t dbase = (uintptr_t)dst->base + dst_offset->x + x +\n            (dst_offset->y + y) * dst->pitch + (dst_offset->z + z) * dst->slice;\n        uint soff = (sbase % 4) >> element;\n        uint doff = (dbase % 4) >> element;\n        sbase &= ~3ull;\n        dbase &= ~3ull;\n\n        x += xcount << element;\n\n        // GFX12 has a different packet format that is incompatible with pre-GFX12.\n        if (isGFX12Plus) {\n          SDMA_PKT_COPY_LINEAR_RECT_GFX12* pkt =\n            (SDMA_PKT_COPY_LINEAR_RECT_GFX12*)append(sizeof(SDMA_PKT_COPY_LINEAR_RECT));\n          *pkt = {};\n          pkt->HEADER_UNION.op = SDMA_OP_COPY;\n          pkt->HEADER_UNION.sub_op = SDMA_SUBOP_COPY_LINEAR_RECT;\n          pkt->HEADER_UNION.element = element;\n          pkt->SRC_ADDR_LO_UNION.src_addr_31_0 = sbase;\n          pkt->SRC_ADDR_HI_UNION.src_addr_63_32 = sbase >> 32;\n          pkt->SRC_PARAMETER_1_UNION.src_offset_x = soff;\n          pkt->SRC_PARAMETER_2_UNION.src_pitch = (src->pitch >> element) - 1;\n          pkt->SRC_PARAMETER_3_UNION.src_slice_pitch =\n            (range->z == 1) ? 0 : (src->slice >> element) - 1;\n          pkt->DST_ADDR_LO_UNION.dst_addr_31_0 = dbase;\n          pkt->DST_ADDR_HI_UNION.dst_addr_63_32 = dbase >> 32;\n          pkt->DST_PARAMETER_1_UNION.dst_offset_x = doff;\n          pkt->DST_PARAMETER_2_UNION.dst_pitch = (dst->pitch >> element) - 1;\n          pkt->DST_PARAMETER_3_UNION.dst_slice_pitch =\n            (range->z == 1) ? 0 : (dst->slice >> element) - 1;\n          pkt->RECT_PARAMETER_1_UNION.rect_x = xcount - 1;\n          pkt->RECT_PARAMETER_1_UNION.rect_y = Min(range->y - y, max_y) - 1;\n          pkt->RECT_PARAMETER_2_UNION.rect_z = Min(range->z - z, max_z) - 1;\n        } else {  // Pre-GFX12, common packet used\n          SDMA_PKT_COPY_LINEAR_RECT* pkt =\n            (SDMA_PKT_COPY_LINEAR_RECT*)append(sizeof(SDMA_PKT_COPY_LINEAR_RECT));\n          *pkt = {};\n          pkt->HEADER_UNION.op = SDMA_OP_COPY;\n          pkt->HEADER_UNION.sub_op = SDMA_SUBOP_COPY_LINEAR_RECT;\n          pkt->HEADER_UNION.element = element;\n          pkt->SRC_ADDR_LO_UNION.src_addr_31_0 = sbase;\n          pkt->SRC_ADDR_HI_UNION.src_addr_63_32 = sbase >> 32;\n          pkt->SRC_PARAMETER_1_UNION.src_offset_x = soff;\n          pkt->SRC_PARAMETER_2_UNION.src_pitch = (src->pitch >> element) - 1;\n          pkt->SRC_PARAMETER_3_UNION.src_slice_pitch =\n            (range->z == 1) ? 0 : (src->slice >> element) - 1;\n          pkt->DST_ADDR_LO_UNION.dst_addr_31_0 = dbase;\n          pkt->DST_ADDR_HI_UNION.dst_addr_63_32 = dbase >> 32;\n          pkt->DST_PARAMETER_1_UNION.dst_offset_x = doff;\n          pkt->DST_PARAMETER_2_UNION.dst_pitch = (dst->pitch >> element) - 1;\n          pkt->DST_PARAMETER_3_UNION.dst_slice_pitch =\n            (range->z == 1) ? 0 : (dst->slice >> element) - 1;\n          pkt->RECT_PARAMETER_1_UNION.rect_x = xcount - 1;\n          pkt->RECT_PARAMETER_1_UNION.rect_y = Min(range->y - y, max_y) - 1;\n          pkt->RECT_PARAMETER_2_UNION.rect_z = Min(range->z - z, max_z) - 1;\n\t}\n      }\n    }\n  }\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildFillCommand(char* cmd_addr, uint32_t num_fill_command, void* ptr,\n                                        uint32_t value, size_t count) {\n  char* cur_ptr = reinterpret_cast<char*>(ptr);\n  const uint32_t maxDwordCount = kMaxSingleFillSize / sizeof(uint32_t);\n  SDMA_PKT_CONSTANT_FILL* packet_addr = reinterpret_cast<SDMA_PKT_CONSTANT_FILL*>(cmd_addr);\n\n  for (uint32_t i = 0; i < num_fill_command; i++) {\n    assert(count != 0 && \"SDMA fill command count error.\");\n    const uint32_t fill_count = Min(count, size_t(maxDwordCount));\n\n    memset(packet_addr, 0, sizeof(SDMA_PKT_CONSTANT_FILL));\n\n    packet_addr->HEADER_UNION.op = SDMA_OP_CONST_FILL;\n    packet_addr->HEADER_UNION.fillsize = 2;  // DW fill\n\n    packet_addr->DST_ADDR_LO_UNION.dst_addr_31_0 = ptrlow32(cur_ptr);\n    packet_addr->DST_ADDR_HI_UNION.dst_addr_63_32 = ptrhigh32(cur_ptr);\n\n    packet_addr->DATA_UNION.src_data_31_0 = value;\n\n    /* count is 1-based */\n    packet_addr->COUNT_UNION.count = (fill_count - 1) * sizeof(uint32_t);\n\n    packet_addr++;\n    cur_ptr += fill_count * sizeof(uint32_t);\n    count -= fill_count;\n  }\n  assert(count == 0 && \"SDMA fill command count error.\");\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildPollCommand(char* cmd_addr, void* addr, uint32_t reference) {\n  SDMA_PKT_POLL_REGMEM* packet_addr =\n      reinterpret_cast<SDMA_PKT_POLL_REGMEM*>(cmd_addr);\n\n  memset(packet_addr, 0, sizeof(SDMA_PKT_POLL_REGMEM));\n\n  packet_addr->HEADER_UNION.op = SDMA_OP_POLL_REGMEM;\n  packet_addr->HEADER_UNION.mem_poll = 1;\n  packet_addr->HEADER_UNION.func = 0x3;  // IsEqual.\n  packet_addr->ADDR_LO_UNION.addr_31_0 = ptrlow32(addr);\n  packet_addr->ADDR_HI_UNION.addr_63_32 = ptrhigh32(addr);\n\n  packet_addr->VALUE_UNION.value = reference;\n\n  packet_addr->MASK_UNION.mask = 0xffffffff;  // Compare the whole content.\n\n  packet_addr->DW5_UNION.interval = 0x04;\n  packet_addr->DW5_UNION.retry_count = 0xfff;  // Retry forever.\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildAtomicDecrementCommand(char* cmd_addr, void* addr) {\n  SDMA_PKT_ATOMIC* packet_addr = reinterpret_cast<SDMA_PKT_ATOMIC*>(cmd_addr);\n\n  memset(packet_addr, 0, sizeof(SDMA_PKT_ATOMIC));\n\n  packet_addr->HEADER_UNION.op = SDMA_OP_ATOMIC;\n  packet_addr->HEADER_UNION.operation = SDMA_ATOMIC_ADD64;\n\n  packet_addr->ADDR_LO_UNION.addr_31_0 = ptrlow32(addr);\n  packet_addr->ADDR_HI_UNION.addr_63_32 = ptrhigh32(addr);\n\n  packet_addr->SRC_DATA_LO_UNION.src_data_31_0 = 0xffffffff;\n  packet_addr->SRC_DATA_HI_UNION.src_data_63_32 = 0xffffffff;\n}\n\ntemplate <bool useGCR>\nvoid BlitSdma<useGCR>::BuildGetGlobalTimestampCommand(char* cmd_addr, void* write_address) {\n  SDMA_PKT_TIMESTAMP* packet_addr =\n      reinterpret_cast<SDMA_PKT_TIMESTAMP*>(cmd_addr);\n\n  memset(packet_addr, 0, sizeof(SDMA_PKT_TIMESTAMP));\n\n  packet_addr->HEADER_UNION.op = SDMA_OP_TIMESTAMP;\n  packet_addr->HEADER_UNION.sub_op = SDMA_SUBOP_TIMESTAMP_GET_GLOBAL;\n\n  packet_addr->ADDR_LO_UNION.addr_31_0 = ptrlow32(write_address);\n  packet_addr->ADDR_HI_UNION.addr_63_32 = ptrhigh32(write_address);\n}\n\ntemplate <bool useGCR> void BlitSdma<useGCR>::BuildTrapCommand(char* cmd_addr, uint32_t event_id) {\n  SDMA_PKT_TRAP* packet_addr =\n      reinterpret_cast<SDMA_PKT_TRAP*>(cmd_addr);\n\n  memset(packet_addr, 0, sizeof(SDMA_PKT_TRAP));\n\n  packet_addr->HEADER_UNION.op = SDMA_OP_TRAP;\n  packet_addr->INT_CONTEXT_UNION.int_ctx = event_id;\n}\n\ntemplate <bool useGCR> void BlitSdma<useGCR>::BuildHdpFlushCommand(char* cmd_addr) {\n  assert(cmd_addr != NULL);\n  SDMA_PKT_POLL_REGMEM* addr = reinterpret_cast<SDMA_PKT_POLL_REGMEM*>(cmd_addr);\n  memcpy(addr, &hdp_flush_cmd, flush_command_size_);\n}\n\ntemplate <bool useGCR> void BlitSdma<useGCR>::BuildGCRCommand(char* cmd_addr, bool invalidate) {\n  assert(cmd_addr != NULL);\n  assert(useGCR && \"Unsupported SDMA command - GCR.\");\n  SDMA_PKT_GCR* addr = reinterpret_cast<SDMA_PKT_GCR*>(cmd_addr);\n  memset(addr, 0, sizeof(SDMA_PKT_GCR));\n  addr->HEADER_UNION.op = SDMA_OP_GCR;\n  addr->HEADER_UNION.sub_op = SDMA_SUBOP_USER_GCR;\n  addr->WORD2_UNION.GCR_CONTROL_GL2_WB = 1;\n  addr->WORD2_UNION.GCR_CONTROL_GLK_WB = 1;\n  if (invalidate) {\n    addr->WORD2_UNION.GCR_CONTROL_GL2_INV = 1;\n    addr->WORD2_UNION.GCR_CONTROL_GL1_INV = 1;\n    addr->WORD2_UNION.GCR_CONTROL_GLV_INV = 1;\n    addr->WORD2_UNION.GCR_CONTROL_GLK_INV = 1;\n  }\n  // Discarding all lines for now.\n  addr->WORD2_UNION.GCR_CONTROL_GL2_RANGE = 0;\n}\n\ntemplate <bool useGCR> uint64_t BlitSdma<useGCR>::PendingBytes() {\n  uint64_t commit = atomic::Load(&cached_commit_index_, std::memory_order_acquire);\n  uint64_t hw_read_index = *reinterpret_cast<uint64_t*>(queue_resource_.Queue_read_ptr);\n\n  if (commit == hw_read_index) return 0;\n  return bytes_queued_ - bytes_written_[WrapIntoRing(hw_read_index)];\n}\n\ntemplate class BlitSdma<false>;\ntemplate class BlitSdma<true>;\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_cpu_agent.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_cpu_agent.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <thread>\n\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/driver.h\"\n#include \"core/inc/host_queue.h\"\n\n#include \"inc/hsa_ext_image.h\"\n\nnamespace rocr {\nnamespace AMD {\nCpuAgent::CpuAgent(HSAuint32 node, const HsaNodeProperties& node_props,\n                   core::DriverType driver_type)\n    : core::Agent(core::Runtime::runtime_singleton_->AgentDriver(driver_type), node, kAmdCpuDevice),\n      properties_(node_props) {\n  InitRegionList();\n\n  InitCacheList();\n}\n\nCpuAgent::~CpuAgent() {\n  std::for_each(regions_.begin(), regions_.end(), DeleteObject());\n  regions_.clear();\n}\n\nvoid CpuAgent::InitRegionList() {\n  const bool is_apu_node = (properties_.NumFComputeCores > 0);\n\n  std::vector<HsaMemoryProperties> mem_props(properties_.NumMemoryBanks);\n  if (HSA_STATUS_SUCCESS == driver().GetMemoryProperties(node_id(), mem_props)) {\n    std::vector<HsaMemoryProperties>::iterator system_prop =\n        std::find_if(mem_props.begin(), mem_props.end(), [](HsaMemoryProperties prop) -> bool {\n          return (prop.SizeInBytes > 0 && prop.HeapType == HSA_HEAPTYPE_SYSTEM);\n        });\n\n    HsaMemoryProperties system_props;\n    std::memset(&system_props, 0, sizeof(HsaMemoryProperties));\n    system_props.HeapType = HSA_HEAPTYPE_SYSTEM;\n    system_props.SizeInBytes = 0;\n    system_props.VirtualBaseAddress = 0;\n\n    if (system_prop != mem_props.end()) system_props = *system_prop;\n\n    // Fine-Grain Memory\n    regions_.push_back(new MemoryRegion(true, false, is_apu_node, false, true, this, system_props));\n\n    // Ext-Fine-Grain Memory\n    regions_.push_back(new MemoryRegion(false, false, is_apu_node, true, true, this, system_props));\n\n    // Kernargs\n    regions_.push_back(new MemoryRegion(true, true, is_apu_node, false, true, this, system_props));\n\n    if (!is_apu_node) {\n      // Coarse Grain\n      regions_.push_back(new MemoryRegion(false, false, is_apu_node, false, true, this, system_props));\n    }\n  }\n}\n\nvoid CpuAgent::InitCacheList() {\n  // Get CPU cache information.\n  cache_props_.resize(properties_.NumCaches);\n  if (HSA_STATUS_SUCCESS !=\n      driver().GetCacheProperties(node_id(), properties_.CComputeIdLo, cache_props_)) {\n    cache_props_.clear();\n  } else {\n    // Only store CPU D-cache.\n    for (size_t cache_id = 0; cache_id < cache_props_.size(); ++cache_id) {\n      const HsaCacheType type = cache_props_[cache_id].CacheType;\n      if (type.ui32.CPU != 1 || type.ui32.Instruction == 1) {\n        cache_props_.erase(cache_props_.begin() + cache_id);\n        --cache_id;\n      }\n    }\n  }\n\n  // Update cache objects\n  caches_.clear();\n  caches_.resize(cache_props_.size());\n  char name[64];\n  GetInfo(HSA_AGENT_INFO_NAME, name);\n  std::string deviceName = name;\n  for (size_t i = 0; i < caches_.size(); i++)\n    caches_[i].reset(new core::Cache(deviceName + \" L\" + std::to_string(cache_props_[i].CacheLevel),\n                                     cache_props_[i].CacheLevel, cache_props_[i].CacheSize));\n}\n\nhsa_status_t CpuAgent::VisitRegion(bool include_peer,\n                                   hsa_status_t (*callback)(hsa_region_t region,\n                                                            void* data),\n                                   void* data) const {\n  if (!include_peer) {\n    return VisitRegion(regions_, callback, data);\n  }\n\n  // Expose all system regions in the system.\n  hsa_status_t stat = VisitRegion(\n      core::Runtime::runtime_singleton_->system_regions_fine(), callback, data);\n  if (stat != HSA_STATUS_SUCCESS) {\n    return stat;\n  }\n\n  return VisitRegion(core::Runtime::runtime_singleton_->system_regions_coarse(),\n                     callback, data);\n}\n\nhsa_status_t CpuAgent::VisitRegion(\n    const std::vector<const core::MemoryRegion*>& regions,\n    hsa_status_t (*callback)(hsa_region_t region, void* data),\n    void* data) const {\n  for (const core::MemoryRegion* region : regions) {\n    if (!region->user_visible()) continue;\n    hsa_region_t region_handle = core::MemoryRegion::Convert(region);\n    hsa_status_t status = callback(region_handle, data);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CpuAgent::IterateRegion(\n    hsa_status_t (*callback)(hsa_region_t region, void* data),\n    void* data) const {\n  return VisitRegion(true, callback, data);\n}\n\nhsa_status_t CpuAgent::IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                                    void* data) const {\n  for (size_t i = 0; i < caches_.size(); i++) {\n    hsa_status_t stat = callback(core::Cache::Convert(caches_[i].get()), data);\n    if (stat != HSA_STATUS_SUCCESS) return stat;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CpuAgent::IterateSupportedIsas(\n                  hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                                          void* data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (const auto& isa : supported_isas()) {\n    hsa_status_t stat = call(core::Isa::Handle(isa), data);\n    if (stat != HSA_STATUS_SUCCESS) return stat;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CpuAgent::GetInfo(hsa_agent_info_t attribute, void* value) const {\n\n  // agent, and vendor name size limit\n  const size_t attribute_u = static_cast<size_t>(attribute);\n\n  switch (attribute_u) {\n\n    // The code copies HsaNodeProperties.MarketingName a Unicode string\n    // which is encoded in UTF-16 as a 7-bit ASCII string. The value of\n    // HsaNodeProperties.MarketingName is obtained from the \"model name\"\n    // property of /proc/cpuinfo file\n    case HSA_AGENT_INFO_NAME:\n    case HSA_AMD_AGENT_INFO_PRODUCT_NAME: {\n      std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n      char* temp = reinterpret_cast<char*>(value);\n      for (uint32_t idx = 0;\n           properties_.MarketingName[idx] != 0 && idx < HSA_PUBLIC_NAME_SIZE - 1; idx++) {\n        temp[idx] = (uint8_t)properties_.MarketingName[idx];\n      }\n      break;\n    }\n    case HSA_AGENT_INFO_VENDOR_NAME:\n      // TODO: hardcode for now, wait until SWDEV-88894 implemented\n      std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n      std::memcpy(value, \"CPU\", sizeof(\"CPU\"));\n      break;\n    case HSA_AGENT_INFO_FEATURE:\n      *((hsa_agent_feature_t*)value) = static_cast<hsa_agent_feature_t>(0);\n      break;\n    case HSA_AGENT_INFO_MACHINE_MODEL:\n#if defined(HSA_LARGE_MODEL)\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_LARGE;\n#else\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_SMALL;\n#endif\n      break;\n    case HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES:\n    case HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE:\n      // TODO: validate if this is true.\n      *((hsa_default_float_rounding_mode_t*)value) =\n          HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR;\n      break;\n    case HSA_AGENT_INFO_FAST_F16_OPERATION:\n      // TODO: validate if this is true.\n      *((bool*)value) = false;\n      break;\n    case HSA_AGENT_INFO_PROFILE:\n      *((hsa_profile_t*)value) = HSA_PROFILE_FULL;\n      break;\n    case HSA_AGENT_INFO_WAVEFRONT_SIZE:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_WORKGROUP_MAX_DIM:\n      std::memset(value, 0, sizeof(uint16_t) * 3);\n      break;\n    case HSA_AGENT_INFO_WORKGROUP_MAX_SIZE:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_GRID_MAX_DIM:\n      std::memset(value, 0, sizeof(hsa_dim3_t));\n      break;\n    case HSA_AGENT_INFO_GRID_MAX_SIZE:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_FBARRIER_MAX_SIZE:\n      // TODO: ?\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_QUEUES_MAX:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_QUEUE_MIN_SIZE:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_QUEUE_MAX_SIZE:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AGENT_INFO_QUEUE_TYPE:\n      *((hsa_queue_type32_t*)value) = HSA_QUEUE_TYPE_MULTI;\n      break;\n    case HSA_AGENT_INFO_NODE:\n      // TODO: associate with OS NUMA support (numactl / GetNumaProcessorNode).\n      *((uint32_t*)value) = node_id();\n      break;\n    case HSA_AGENT_INFO_DEVICE:\n      *((hsa_device_type_t*)value) = HSA_DEVICE_TYPE_CPU;\n      break;\n    case HSA_AGENT_INFO_CACHE_SIZE: {\n      std::memset(value, 0, sizeof(uint32_t) * 4);\n      const size_t num_cache = cache_props_.size();\n      for (size_t i = 0; i < num_cache; ++i) {\n        const uint32_t line_level = cache_props_[i].CacheLevel;\n        ((uint32_t*)value)[line_level - 1] = cache_props_[i].CacheSize * 1024;\n      }\n    } break;\n    case HSA_AGENT_INFO_ISA:\n      ((hsa_isa_t*)value)->handle = 0;\n      break;\n    case HSA_AGENT_INFO_EXTENSIONS:\n      memset(value, 0, sizeof(uint8_t) * 128);\n      break;\n    case HSA_AGENT_INFO_VERSION_MAJOR:\n      *((uint16_t*)value) = 1;\n      break;\n    case HSA_AGENT_INFO_VERSION_MINOR:\n      *((uint16_t*)value) = 1;\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_1DA_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_1DB_MAX_ELEMENTS:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_2D_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DA_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DDEPTH_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DADEPTH_MAX_ELEMENTS:\n      memset(value, 0, sizeof(uint32_t) * 2);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_3D_MAX_ELEMENTS:\n      memset(value, 0, sizeof(uint32_t) * 3);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_EXT_AGENT_INFO_MAX_IMAGE_RD_HANDLES:\n    case HSA_EXT_AGENT_INFO_MAX_IMAGE_RORW_HANDLES:\n    case HSA_EXT_AGENT_INFO_MAX_SAMPLER_HANDLERS:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_CHIP_ID:\n      *((uint32_t*)value) = properties_.DeviceId;\n      break;\n    case HSA_AMD_AGENT_INFO_CACHELINE_SIZE:\n      // TODO: hardcode for now.\n      *((uint32_t*)value) = 64;\n      break;\n    case HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT:\n      *((uint32_t*)value) = properties_.NumCPUCores;\n      break;\n    case HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY:\n      *((uint32_t*)value) = properties_.MaxEngineClockMhzCCompute;\n      break;\n    case HSA_AMD_AGENT_INFO_DRIVER_NODE_ID:\n      *((uint32_t*)value) = node_id();\n      break;\n    case HSA_AMD_AGENT_INFO_MAX_ADDRESS_WATCH_POINTS:\n      *((uint32_t*)value) = static_cast<uint32_t>(\n          1 << properties_.Capability.ui32.WatchPointsTotalBits);\n      break;\n    case HSA_AMD_AGENT_INFO_BDFID:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.LocationId);\n      break;\n    case HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU:\n      *((uint32_t*)value) = static_cast<uint32_t>(\n          properties_.NumSIMDPerCU * properties_.MaxWavesPerSIMD);\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU:\n      *((uint32_t*)value) = properties_.NumSIMDPerCU;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SHADER_ENGINES:\n      *((uint32_t*)value) = properties_.NumShaderBanks;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SHADER_ARRAYS_PER_SE:\n      *((uint32_t*)value) = properties_.NumArrays;\n      break;\n    case HSA_AMD_AGENT_INFO_HDP_FLUSH:\n      *((hsa_amd_hdp_flush_t*)value) = {nullptr, nullptr};\n      break;\n    case HSA_AMD_AGENT_INFO_DOMAIN:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.Domain);\n      break;\n    case HSA_AMD_AGENT_INFO_UUID: {\n      // At this point CPU devices do not support UUID's.\n      char uuid_tmp[] = \"CPU-XX\";\n      snprintf((char*)value, sizeof(uuid_tmp), \"%s\", uuid_tmp);\n      break;\n    }\n    case HSA_AMD_AGENT_INFO_ASIC_REVISION:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.Capability.ui32.ASICRevision);\n      break;\n    case HSA_AMD_AGENT_INFO_SVM_DIRECT_HOST_ACCESS:\n      assert(regions_.size() != 0 && \"No device local memory found!\");\n      *((bool*)value) = true;\n      break;\n    case HSA_AMD_AGENT_INFO_TIMESTAMP_FREQUENCY:\n      return core::Runtime::runtime_singleton_->GetSystemInfo(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY,\n                                                              value);\n      break;\n    case HSA_AMD_AGENT_INFO_ASIC_FAMILY_ID:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.FamilyID);\n      break;\n    case HSA_AMD_AGENT_INFO_UCODE_VERSION:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_SDMA_UCODE_VERSION:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SDMA_ENG:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SDMA_XGMI_ENG:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_IOMMU_SUPPORT:\n      *((hsa_amd_iommu_version_t*)value) = HSA_IOMMU_SUPPORT_NONE;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_XCC:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_DRIVER_UID:\n      *((uint32_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_NEAREST_CPU:\n      ((hsa_agent_t*)value)->handle = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_MEMORY_PROPERTIES:\n      memset(value, 0, sizeof(uint8_t) * 8);\n      break;\n    case HSA_AMD_AGENT_INFO_AQL_EXTENSIONS:\n      memset(value, 0, sizeof(uint8_t) * 8);\n      break;\n    case HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_MAX:\n    case HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_CURRENT:\n      *((uint64_t*)value) = 0;\n      break;\n    case HSA_AMD_AGENT_INFO_CLOCK_COUNTERS:\n      memset(value, 0, sizeof(hsa_amd_clock_counters_t));\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      break;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CpuAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                                   core::HsaEventCallback event_callback, void* data,\n                                   uint32_t private_segment_size, uint32_t group_segment_size,\n                                   core::Queue** queue) {\n  // No HW AQL packet processor on CPU device.\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t CpuAgent::DmaCopy(void* dst, core::Agent& dst_agent, const void* src,\n                               core::Agent& src_agent, size_t size,\n                               std::vector<core::Signal*>& dep_signals, core::Signal& out_signal) {\n  // For cpu to cpu, fire and forget a copy thread.\n  const bool profiling_enabled = (dst_agent.profiling_enabled() || src_agent.profiling_enabled());\n  if (profiling_enabled) out_signal.async_copy_agent(this);\n  std::thread(\n      [](void* dst, const void* src, size_t size, std::vector<core::Signal*> dep_signals,\n         core::Signal* completion_signal, bool profiling_enabled) {\n        for (core::Signal* dep : dep_signals) {\n          dep->WaitRelaxed(HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\n        }\n\n        if (profiling_enabled) {\n          core::Runtime::runtime_singleton_->GetSystemInfo(HSA_SYSTEM_INFO_TIMESTAMP,\n                                                           &completion_signal->signal_.start_ts);\n        }\n\n        memcpy(dst, src, size);\n\n        if (profiling_enabled) {\n          core::Runtime::runtime_singleton_->GetSystemInfo(HSA_SYSTEM_INFO_TIMESTAMP,\n                                                           &completion_signal->signal_.end_ts);\n        }\n\n        completion_signal->SubRelease(1);\n      },\n      dst, src, size, dep_signals, &out_signal, profiling_enabled)\n      .detach();\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_filter_device.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_filter_device.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <vector>\n#include <map>\n#include <string>\n#include <sstream>\n#include <iomanip>\n#include <iostream>\n#include <climits>\n\n#include \"core/util/utils.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/amd_cpu_agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nbool RvdFilter::FilterDevices() {\n  return core::Runtime::runtime_singleton_->flag().filter_visible_gpus();\n}\n\nbool RvdFilter::SelectZeroDevices() {\n  const std::string& envVal = core::Runtime::runtime_singleton_->flag().visible_gpus();\n  return envVal.empty();\n}\n\nvoid RvdFilter::BuildRvdTokenList() {\n  // Determine if user has chosen ZERO devices to be surfaced\n  const std::string& envVal = core::Runtime::runtime_singleton_->flag().visible_gpus();\n  if (envVal.empty()) {\n    return;\n  }\n\n  // Parse env value into tokens separated by comma (',') delimiter\n  std::string token;\n  char separator = ',';\n  std::stringstream stream(envVal);\n  while (getline(stream, token, separator)) {\n    std::transform(token.begin(), token.end(), token.begin(), ::toupper);\n    token = trim(token);\n    rvdTokenList_.push_back(token);\n  }\n}\n\nvoid RvdFilter::BuildDeviceUuidList(const std::vector<HsaNodeProperties>& node_props) {\n  for (const auto& props : node_props) {\n    if (props.NumFComputeCores == 0) {\n      continue;\n    }\n\n    // For devices whose UUID is zero build a string that\n    // will not match user provided value\n    if (props.UniqueID == 0) {\n      devUuidList_.push_back(\"Invalid-UUID\");\n      continue;\n    }\n\n    // For devices that support valid UUID values capture UUID\n    // value into a upper case hex string of length 16 including\n    // leading zeros if necessary\n    std::stringstream stream;\n    stream << \"GPU-\" << std::setfill('0') << std::setw(sizeof(uint64_t) * 2) << std::hex\n           << props.UniqueID;\n    std::string uuidVal(stream.str());\n    std::transform(uuidVal.begin(), uuidVal.end(), uuidVal.begin(), ::toupper);\n    devUuidList_.push_back(std::move(uuidVal));\n  }\n}\n\nint32_t RvdFilter::ProcessUuidToken(const std::string& token) {\n  // Determine if token exceeds max length of a UUID string\n  uint32_t tokenLen = token.length();\n  if ((tokenLen < 5) || (tokenLen > 20)) {\n    return -1;\n  }\n\n  // Track the number of devices user token matches\n  int32_t devIdx = -1;\n  int32_t compareVal = -1;\n  uint32_t numGpus = devUuidList_.size();\n  for (uint32_t idx = 0; idx < numGpus; idx++) {\n    uint32_t uuidLen = devUuidList_[idx].length();\n\n    // Token could match UUID of another device\n    if (tokenLen > uuidLen)\n      continue;\n\n    // Token could match as substring of device UUID\n    compareVal = token.compare(0, tokenLen, devUuidList_[idx], 0, tokenLen);\n\n    // Check if user Uuid matches with ROCt Uuid\n    if (compareVal == 0) {\n      if (devIdx != -1) {\n        return -1;\n      }\n      devIdx = idx;\n    }\n  }\n\n  // Return value includes possibility of both\n  // finding or not finding a device\n  return devIdx;\n}\n\nuint32_t RvdFilter::BuildUsrDeviceList() {\n  // Get number of Gpu devices and user specified tokens\n  uint32_t numGpus = devUuidList_.size();\n  uint32_t loopCnt = std::min(numGpus, uint32_t(rvdTokenList_.size()));\n\n  // Evaluate tokens into device index or UUID values\n  int32_t usrIdx = 0;\n  int32_t devIdx = -1;\n  for (uint32_t idx = 0; idx < loopCnt; idx++) {\n    // User token to be evaluated as UUID or device index\n    std::string& token = rvdTokenList_[idx];\n\n    // Token encodes a UUID valaue\n    if (token.at(0) == 'G') {\n      devIdx = ProcessUuidToken(token);\n      if (devIdx == -1) {\n        return usrDeviceList_.size();\n      }\n\n      // Token encodes device index\n    } else {\n      char* end = nullptr;\n      const char* tmp = token.c_str();\n      devIdx = std::strtol(tmp, &end, 0);\n      if (*end != '\\0') {\n        return usrDeviceList_.size();\n      }\n    }\n\n    // Rvd Token evaluates to wrong device index\n    if ((devIdx < 0) || (devIdx >= numGpus)) {\n      return usrDeviceList_.size();\n    }\n\n    // Determine if device index is previously seen\n    // Such indices are interpreted as terminators\n    bool exists = (usrDeviceList_.find(devIdx) != usrDeviceList_.end());\n    if (exists) {\n      return usrDeviceList_.size();\n    }\n\n    // Add index to the list of devices that will be\n    // surfaced upon device enumeration\n    usrDeviceList_[devIdx] = usrIdx++;\n  }\n\n  return usrDeviceList_.size();\n}\n\nuint32_t RvdFilter::GetUsrDeviceListSize() { return usrDeviceList_.size(); }\n\nint32_t RvdFilter::GetUsrDeviceRank(uint32_t roctIdx) {\n  const auto& it = usrDeviceList_.find(roctIdx);\n  if (it != usrDeviceList_.end()) {\n    return it->second;\n  }\n  return -1;\n}\n\n#ifndef NDEBUG\nvoid RvdFilter::SetDeviceUuidList() {\n  uint64_t dbgUuid[] = {0xBABABABABABABABA, 0xBABABABABABAABBA, 0xBABABABAABBAABBA,\n                        0xBABAABBAABBAABBA, 0xABBAABBAABBAABBA, 0xABBAABBAABBABABA,\n                        0xABBAABBABABABABA, 0xABBABABABABABABA};\n\n  // Override or Set Uuid values for the first four devices\n  uint32_t numGpus = devUuidList_.size();\n  uint32_t numUuids = (sizeof(dbgUuid) / sizeof(uint64_t));\n  for (uint32_t idx = 0; (idx < numGpus && (idx < numUuids)); idx++) {\n    std::stringstream stream;\n\n    // For devices whose UUID is zero\n    if (dbgUuid[idx] == 0) {\n      stream << \"GPU-XX\";\n      continue;\n    }\n\n    // For devices that support valid UUID values\n    stream << \"GPU-\" << std::setfill('0') << std::setw(sizeof(uint64_t) * 2) << std::hex\n           << dbgUuid[idx];\n    std::string uuidVal(stream.str());\n    std::transform(uuidVal.begin(), uuidVal.end(), uuidVal.begin(), ::toupper);\n    devUuidList_[idx] = std::move(uuidVal);\n  }\n}\n\nvoid RvdFilter::PrintDeviceUuidList() {\n  uint32_t numGpus = devUuidList_.size();\n  for (uint32_t idx = 0; idx < numGpus; idx++) {\n    std::cout << \"Dev[\" << idx << \"]: \" << devUuidList_[idx];\n    std::cout << std::endl << std::flush;\n  }\n}\n\nvoid RvdFilter::PrintUsrDeviceList() {\n  // Flip the map values as value indicates surface rank\n  for (auto const& elem : usrDeviceList_) {\n    std::cout << \"UsrDev[\" << elem.second << \"]: \" << elem.first;\n    std::cout << std::endl << std::flush;\n  }\n}\n\nvoid RvdFilter::PrintRvdTokenList() {\n  uint32_t numTokens = rvdTokenList_.size();\n  for (uint32_t idx = 0; idx < numTokens; idx++) {\n    std::cout << \"Token[\" << idx << \"]: \" << rvdTokenList_[idx];\n    std::cout << std::endl << std::flush;\n  }\n}\n#endif\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_gpu_agent.h\"\n\n#include <algorithm>\n#include <atomic>\n#include <cstring>\n#include <climits>\n#include <map>\n#include <string>\n#include <vector>\n#include <memory>\n#include <utility>\n#include <iomanip>\n#include <cmath>\n\n#include \"core/inc/amd_aql_queue.h\"\n#include \"core/inc/amd_blit_kernel.h\"\n#include \"core/inc/amd_blit_sdma.h\"\n#include \"core/inc/amd_gpu_pm4.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/default_signal.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/isa.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/util/os.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"inc/hsa_ven_amd_aqlprofile.h\"\n#include \"inc/hsa_ven_amd_pc_sampling.h\"\n\n#include \"core/inc/amd_trap_handler_v1.h\"\n#include \"core/inc/amd_blit_shaders.h\"\n#include \"core/inc/hsa_api_trace_int.h\"\n// Generated header\n#include \"amd_trap_handler_v2.h\"\n#include \"amd_blit_shaders_v2.h\"\n\n#if defined(__linux__)\n// libdrm headers\n#include <xf86drm.h>\n#include <amdgpu.h>\n#endif\n\n\n// Size of scratch (private) segment pre-allocated per thread, in bytes.\n#define DEFAULT_SCRATCH_BYTES_PER_THREAD 2048\n#define MAX_WAVE_SCRATCH 8387584  // See COMPUTE_TMPRING_SIZE.WAVESIZE\n#define MAX_NUM_DOORBELLS 0x400\n\nnamespace rocr {\n\nnamespace AMD {\nconst uint64_t CP_DMA_DATA_TRANSFER_CNT_MAX = (1 << 26);\n\nGpuAgent::GpuAgent(HSAuint32 node, const HsaNodeProperties& node_props, bool xnack_mode,\n                   uint32_t index, core::DriverType driver_type)\n    : GpuAgentInt(node, driver_type),\n      properties_(node_props),\n      current_coherency_type_(HSA_AMD_COHERENCY_TYPE_COHERENT),\n      scratch_used_large_(0),\n      queues_(),\n      trap_code_buf_(NULL),\n      trap_code_buf_size_(0),\n      doorbell_queue_map_(NULL),\n      memory_bus_width_(0),\n      memory_max_frequency_(0),\n      enum_index_(index),\n      ape1_base_(0),\n      pending_copy_req_ref_(0),\n      pending_copy_stat_check_ref_(0),\n      sdma_blit_used_mask_(0),\n      scratch_limit_async_threshold_(0),\n      scratch_cache_(\n          [this](void* base, size_t size, bool large) { ReleaseScratch(base, size, large); }),\n      trap_handler_tma_region_(NULL),\n      rec_sdma_eng_override_(false),\n      pcs_hosttrap_data_(),\n      pcs_stochastic_data_(),\n      xgmi_cpu_gpu_(false),\n      large_bar_enabled_(false){\n  const bool is_apu_node = (properties_.NumCPUCores > 0);\n  profile_ = (is_apu_node) ? HSA_PROFILE_FULL : HSA_PROFILE_BASE;\n\n  if (node_props.Capability.ui32.DoorbellType != 2)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR, \"Agent creation failed.\\nThe GPU node uses a deprecated doorbell type\\n\");\n\n  hsa_status_t err = driver().GetClockCounters(node_id(), &t0_);\n  t1_ = t0_;\n  historical_clock_ratio_ = 0.0;\n  assert(err == HSA_STATUS_SUCCESS && \"hsaGetClockCounters error\");\n\n  const core::Isa *isa_base;\n\n  if (node_props.OverrideEngineId.Value != 0) {\n     isa_base = core::IsaRegistry::GetIsa(\n         core::Isa::Version(node_props.OverrideEngineId.ui32.Major,\n                            node_props.OverrideEngineId.ui32.Minor,\n                            node_props.OverrideEngineId.ui32.Stepping));\n  } else {\n     isa_base = core::IsaRegistry::GetIsa(\n         core::Isa::Version(node_props.EngineId.ui32.Major,\n                            node_props.EngineId.ui32.Minor,\n                            node_props.EngineId.ui32.Stepping));\n  }\n\n  if (!isa_base) {\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ISA, \"Agent creation failed.\\nThe GPU node has an unrecognized id.\\n\");\n  }\n\n  rocr::core::IsaFeature sramecc = rocr::core::IsaFeature::Unsupported;\n  if (isa_base->IsSrameccSupported()) {\n    switch (core::Runtime::runtime_singleton_->flag().sramecc_enable()) {\n      case Flag::SRAMECC_DISABLED:\n        sramecc = core::IsaFeature::Disabled;\n        break;\n      case Flag::SRAMECC_ENABLED:\n        sramecc = core::IsaFeature::Enabled;\n        break;\n      case Flag::SRAMECC_DEFAULT:\n        sramecc = node_props.Capability.ui32.SRAM_EDCSupport == 1 ? core::IsaFeature::Enabled\n                                                                  : core::IsaFeature::Disabled;\n        break;\n    }\n  }\n\n  rocr::core::IsaFeature xnack = rocr::core::IsaFeature::Unsupported;\n  if (isa_base->IsXnackSupported()) {\n    // TODO: This needs to be obtained form KFD once HMM implemented.\n    xnack = xnack_mode ? core::IsaFeature::Enabled\n                      : core::IsaFeature::Disabled;\n  }\n\n  if (node_props.OverrideEngineId.Value != 0) {\n    isa_ = (core::Isa*)core::IsaRegistry::GetIsa(\n          core::Isa::Version(node_props.OverrideEngineId.ui32.Major, node_props.OverrideEngineId.ui32.Minor,\n                             node_props.OverrideEngineId.ui32.Stepping), sramecc, xnack);\n  } else {\n  // Set instruction set architecture via node property, only on GPU device.\n    isa_ = (core::Isa*)core::IsaRegistry::GetIsa(\n          core::Isa::Version(node_props.EngineId.ui32.Major, node_props.EngineId.ui32.Minor,\n                             node_props.EngineId.ui32.Stepping), sramecc, xnack);\n  }\n\n  assert(isa_ != nullptr && \"ISA registry inconsistency.\");\n\n  supported_isas_.push_back(isa_);\n  if (!isa_->GetIsaGeneric().empty()) {\n    supported_isas_.push_back(core::IsaRegistry::GetIsa(isa_->GetIsaGeneric()));\n  }\n\n  current_coherency_type((profile_ == HSA_PROFILE_FULL)\n                             ? HSA_AMD_COHERENCY_TYPE_COHERENT\n                             : HSA_AMD_COHERENCY_TYPE_NONCOHERENT);\n\n  max_queues_ = core::Runtime::runtime_singleton_->flag().max_queues();\n#if !defined(HSA_LARGE_MODEL) || !defined(__linux__)\n  if (max_queues_ == 0) {\n    max_queues_ = 10;\n  }\n  max_queues_ = std::min(10U, max_queues_);\n#else\n  if (max_queues_ == 0) {\n    max_queues_ = 128;\n  }\n  max_queues_ = std::min(128U, max_queues_);\n#endif\n\n  // Initialize libdrm device handle\n  InitLibDrm();\n\n#if !defined(__linux__)\n  wallclock_frequency_ = 0;\n#else\n  bool model_enabled;\n  hsa_status_t status = driver().IsModelEnabled(&model_enabled);\n  assert(status == HSA_STATUS_SUCCESS && \"IsModelEnabled failed\");\n  if (model_enabled) {\n    wallclock_frequency_ = 0;\n  } else {\n    // Get wallclock freq\n    err = driver().GetWallclockFrequency(node_id(), &wallclock_frequency_);\n    if (err != HSA_STATUS_SUCCESS) {\n      throw AMD::hsa_exception(err, \"Agent creation failed.\\nGetWallclockFrequency error.\\n\");\n    }\n  }\n#endif\n\n  auto& first_cpu = core::Runtime::runtime_singleton_->cpu_agents()[0];\n  auto link_info = core::Runtime::runtime_singleton_->GetLinkInfo(first_cpu->node_id(), node_id());\n  xgmi_cpu_gpu_ = (link_info.info.link_type == HSA_AMD_LINK_INFO_TYPE_XGMI);\n\n  if (link_info.num_hop >= 1) {\n    large_bar_enabled_ = true;\n  }\n\n  // Populate region list.\n  InitRegionList();\n\n  // Populate cache list.\n  InitCacheList();\n\n  // Initialize thresholds for async-scratch handling\n  InitAsyncScratchThresholds();\n}\n\nGpuAgent::~GpuAgent() {\n  std::for_each(regions_.begin(), regions_.end(), DeleteObject());\n  regions_.clear();\n}\n\nvoid GpuAgent::AssembleShader(const char* func_name, AssembleTarget assemble_target,\n                              void*& code_buf, size_t& code_buf_size) const {\n  // Select precompiled shader implementation from name/target.\n  struct ASICShader {\n    const void* code;\n    size_t size;\n    int num_sgprs;\n    int num_vgprs;\n  };\n\n  struct CompiledShader {\n    ASICShader compute_7;\n    ASICShader compute_8;\n    ASICShader compute_9;\n    ASICShader compute_90a;\n    ASICShader compute_942;\n    ASICShader compute_1010;\n    ASICShader compute_10;\n    ASICShader compute_11;\n    ASICShader compute_12;\n  };\n\n  std::map<std::string, CompiledShader> compiled_shaders = {\n      {\"TrapHandler\",\n       {\n           {NULL, 0, 0, 0},                                                 // gfx7\n           {kCodeTrapHandler8, sizeof(kCodeTrapHandler8), 2, 4},            // gfx8\n           {kCodeTrapHandler9, sizeof(kCodeTrapHandler9), 2, 4},            // gfx9\n           {kCodeTrapHandler90a, sizeof(kCodeTrapHandler90a), 2, 4},        // gfx90a\n           {NULL, 0, 0, 0},                                                 // gfx942\n           {kCodeTrapHandler1010, sizeof(kCodeTrapHandler1010), 2, 4},      // gfx1010\n           {kCodeTrapHandler10, sizeof(kCodeTrapHandler10), 2, 4},          // gfx10\n           {NULL, 0, 0, 0},                                                 // gfx11\n           // GFX12_TODO: Using one for GFX10 for now.\n           //             If NULL is used (like GFX11), get an assert.\n           {kCodeTrapHandler10, sizeof(kCodeTrapHandler10), 2, 4},          // gfx12\n       }},\n      {\"TrapHandlerKfdExceptions\",\n       {\n           {NULL, 0, 0, 0},                                                 // gfx7\n           {kCodeTrapHandler8, sizeof(kCodeTrapHandler8), 2, 4},            // gfx8\n           {kCodeTrapHandlerV2_9, sizeof(kCodeTrapHandlerV2_9), 2, 4},      // gfx9\n           {kCodeTrapHandlerV2_9, sizeof(kCodeTrapHandlerV2_9), 2, 4},      // gfx90a\n           {kCodeTrapHandlerV2_942, sizeof(kCodeTrapHandlerV2_942), 2, 4},  // gfx942\n           {kCodeTrapHandlerV2_1010, sizeof(kCodeTrapHandlerV2_1010), 2, 4},// gfx1010\n           {kCodeTrapHandlerV2_10, sizeof(kCodeTrapHandlerV2_10), 2, 4},    // gfx10\n           {kCodeTrapHandlerV2_11, sizeof(kCodeTrapHandlerV2_11), 2, 4},    // gfx11\n           {kCodeTrapHandlerV2_12, sizeof(kCodeTrapHandlerV2_12), 2, 4},    // gfx12\n       }},\n      {\"CopyAligned\",\n       {\n           {kCodeCopyAligned7, sizeof(kCodeCopyAligned7), 32, 12},          // gfx7\n           {kCodeCopyAligned8, sizeof(kCodeCopyAligned8), 32, 12},          // gfx8\n           {kCodeCopyAligned9, sizeof(kCodeCopyAligned9), 32, 12},          // gfx9\n           {kCodeCopyAligned9, sizeof(kCodeCopyAligned9), 32, 12},          // gfx90a\n           {kCodeCopyAligned9, sizeof(kCodeCopyAligned9), 32, 12},          // gfx942\n           {kCodeCopyAligned10, sizeof(kCodeCopyAligned10), 32, 12},        // gfx1010\n           {kCodeCopyAligned10, sizeof(kCodeCopyAligned10), 32, 12},        // gfx10\n           {kCodeCopyAligned11, sizeof(kCodeCopyAligned11), 32, 12},        // gfx11\n           {kCodeCopyAligned12, sizeof(kCodeCopyAligned12), 32, 12},        // gfx12\n       }},\n      {\"CopyMisaligned\",\n       {\n           {kCodeCopyMisaligned7, sizeof(kCodeCopyMisaligned7), 23, 10},    // gfx7\n           {kCodeCopyMisaligned8, sizeof(kCodeCopyMisaligned8), 23, 10},    // gfx8\n           {kCodeCopyMisaligned9, sizeof(kCodeCopyMisaligned9), 23, 10},    // gfx9\n           {kCodeCopyMisaligned9, sizeof(kCodeCopyMisaligned9), 23, 10},    // gfx90a\n           {kCodeCopyMisaligned9, sizeof(kCodeCopyMisaligned9), 23, 10},    // gfx942\n           {kCodeCopyMisaligned10, sizeof(kCodeCopyMisaligned10), 23, 10},  // gfx1010\n           {kCodeCopyMisaligned10, sizeof(kCodeCopyMisaligned10), 23, 10},  // gfx10\n           {kCodeCopyMisaligned11, sizeof(kCodeCopyMisaligned11), 23, 10},  // gfx11\n           {kCodeCopyMisaligned12, sizeof(kCodeCopyMisaligned12), 23, 10},  // gfx12\n       }},\n      {\"Fill\",\n       {\n           {kCodeFill7, sizeof(kCodeFill7), 19, 8},                         // gfx7\n           {kCodeFill8, sizeof(kCodeFill8), 19, 8},                         // gfx8\n           {kCodeFill9, sizeof(kCodeFill9), 19, 8},                         // gfx9\n           {kCodeFill9, sizeof(kCodeFill9), 19, 8},                         // gfx90a\n           {kCodeFill9, sizeof(kCodeFill9), 19, 8},                         // gfx942\n           {kCodeFill10, sizeof(kCodeFill10), 19, 8},                       // gfx1010\n           {kCodeFill10, sizeof(kCodeFill10), 19, 8},                       // gfx10\n           {kCodeFill11, sizeof(kCodeFill11), 19, 8},                       // gfx11\n           {kCodeFill12, sizeof(kCodeFill12), 19, 8},                       // gfx12\n       }}};\n\n  auto compiled_shader_it = compiled_shaders.find(func_name);\n  assert(compiled_shader_it != compiled_shaders.end() &&\n         \"Precompiled shader unavailable\");\n\n  ASICShader* asic_shader = NULL;\n\n  switch (isa_->GetMajorVersion()) {\n    case 7:\n      asic_shader = &compiled_shader_it->second.compute_7;\n      break;\n    case 8:\n      asic_shader = &compiled_shader_it->second.compute_8;\n      break;\n    case 9:\n      if((isa_->GetMinorVersion() == 0) && (isa_->GetStepping() == 10)) {\n        asic_shader = &compiled_shader_it->second.compute_90a;\n      } else if(isa_->GetMinorVersion() == 4 || isa_->GetMinorVersion() == 5) {\n        asic_shader = &compiled_shader_it->second.compute_942;\n      } else {\n        asic_shader = &compiled_shader_it->second.compute_9;\n      }\n      break;\n    case 10:\n      if(isa_->GetMinorVersion() == 1)\n        asic_shader = &compiled_shader_it->second.compute_1010;\n      else\n        asic_shader = &compiled_shader_it->second.compute_10;\n      break;\n    case 11:\n        asic_shader = &compiled_shader_it->second.compute_11;\n      break;\n    case 12:\n        asic_shader = &compiled_shader_it->second.compute_12;\n      break;\n    default:\n      assert(false && \"Precompiled shader unavailable for target\");\n  }\n\n  // Allocate a GPU-visible buffer for the shader.\n  size_t header_size =\n      (assemble_target == AssembleTarget::AQL ? sizeof(amd_kernel_code_t) : 0);\n  code_buf_size = AlignUp(header_size + asic_shader->size, 0x1000);\n\n  code_buf = system_allocator()(code_buf_size, 0x1000,\n    core::MemoryRegion::AllocateExecutable | core::MemoryRegion::AllocateExecutableBlitKernelObject);\n  assert(code_buf != NULL && \"Code buffer allocation failed\");\n\n  memset(code_buf, 0, code_buf_size);\n\n  // Populate optional code object header.\n  if (assemble_target == AssembleTarget::AQL) {\n    amd_kernel_code_t* header = reinterpret_cast<amd_kernel_code_t*>(code_buf);\n\n    int gran_sgprs = std::max(0, (int(asic_shader->num_sgprs) - 1) / 8);\n    int gran_vgprs = std::max(0, (int(asic_shader->num_vgprs) - 1) / 4);\n\n    header->kernel_code_entry_byte_offset = sizeof(amd_kernel_code_t);\n    AMD_HSA_BITS_SET(header->kernel_code_properties,\n                     AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_KERNARG_SEGMENT_PTR,\n                     1);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc1,\n                     AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WAVEFRONT_SGPR_COUNT,\n                     gran_sgprs);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc1,\n                     AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WORKITEM_VGPR_COUNT,\n                     gran_vgprs);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc1,\n                     AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_DENORM_MODE_16_64, 3);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc1,\n                     AMD_COMPUTE_PGM_RSRC_ONE_ENABLE_IEEE_MODE, 1);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc2,\n                     AMD_COMPUTE_PGM_RSRC_TWO_USER_SGPR_COUNT, 2);\n    AMD_HSA_BITS_SET(header->compute_pgm_rsrc2,\n                     AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_X, 1);\n\n    // gfx90a, gfx942, gfx950\n    if ((isa_->GetMajorVersion() == 9) &&\n        (((isa_->GetMinorVersion() == 0) && (isa_->GetStepping() == 10)) ||\n        (isa_->GetMinorVersion() == 4 || isa_->GetMinorVersion() == 5))) {\n      // Program COMPUTE_PGM_RSRC3.ACCUM_OFFSET for 0 ACC VGPRs on gfx90a.\n      // FIXME: Assemble code objects from source at build time\n      int gran_accvgprs = ((gran_vgprs + 1) * 8) / 4 - 1;\n      header->max_scratch_backing_memory_byte_size = uint64_t(gran_accvgprs) << 32;\n    }\n  }\n\n  // Copy shader code into the GPU-visible buffer.\n  memcpy((void*)(uintptr_t(code_buf) + header_size), asic_shader->code,\n         asic_shader->size);\n}\n\nvoid GpuAgent::ReleaseShader(void* code_buf, size_t code_buf_size) const {\n  system_deallocator()(code_buf);\n}\n\nvoid GpuAgent::InitRegionList() {\n  const bool is_apu_node = (properties_.NumCPUCores > 0);\n\n  std::vector<HsaMemoryProperties> mem_props(properties_.NumMemoryBanks);\n  if (HSA_STATUS_SUCCESS == driver().GetMemoryProperties(node_id(), mem_props)) {\n    for (uint32_t mem_idx = 0; mem_idx < properties_.NumMemoryBanks;\n         ++mem_idx) {\n      // Ignore the one(s) with unknown size.\n      if (mem_props[mem_idx].SizeInBytes == 0) {\n        continue;\n      }\n\n      switch (mem_props[mem_idx].HeapType) {\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          if (!is_apu_node) {\n            mem_props[mem_idx].VirtualBaseAddress = 0;\n          }\n\n          memory_bus_width_ = mem_props[mem_idx].Width;\n          memory_max_frequency_ = mem_props[mem_idx].MemoryClockMax;\n        case HSA_HEAPTYPE_GPU_LDS:\n        case HSA_HEAPTYPE_GPU_SCRATCH: {\n          MemoryRegion* region =\n              new MemoryRegion(false, false, false, false, true, this, mem_props[mem_idx]);\n\n          regions_.push_back(region);\n\n          if (region->IsLocalMemory()) {\n            // Extended Fine-Grain memory\n            if (!(isa_->GetMajorVersion() == 12 && isa_->GetMinorVersion() == 0))\n              regions_.push_back(\n                  new MemoryRegion(false, false, false, true, true, this, mem_props[mem_idx]));\n\n            // Expose VRAM as uncached/fine grain over PCIe (if enabled) or XGMI.\n            bool user_visible = (properties_.HiveID != 0) ||\n                core::Runtime::runtime_singleton_->flag().fine_grain_pcie();\n\n            regions_.push_back(new MemoryRegion(true, false, false, false, user_visible, this,\n                                                mem_props[mem_idx]));\n          }\n          break;\n        }\n        case HSA_HEAPTYPE_SYSTEM:\n          if (is_apu_node) {\n            memory_bus_width_ = mem_props[mem_idx].Width;\n            memory_max_frequency_ = mem_props[mem_idx].MemoryClockMax;\n          }\n          break;\n        case HSA_HEAPTYPE_MMIO_REMAP:\n          // Remap offsets defined in kfd_ioctl.h\n          HDP_flush_.HDP_MEM_FLUSH_CNTL = (uint32_t*)mem_props[mem_idx].VirtualBaseAddress;\n          HDP_flush_.HDP_REG_FLUSH_CNTL = HDP_flush_.HDP_MEM_FLUSH_CNTL + 1;\n          break;\n        default:\n          continue;\n      }\n    }\n  }\n}\n\nvoid GpuAgent::InitScratchPool() {\n  scratch_per_thread_ =\n      core::Runtime::runtime_singleton_->flag().scratch_mem_size();\n  if (scratch_per_thread_ == 0)\n    scratch_per_thread_ = DEFAULT_SCRATCH_BYTES_PER_THREAD;\n\n  // Scratch length is: waves/CU * threads/wave * queues * #CUs *\n  // scratch/thread\n  const uint32_t num_cu =\n      properties_.NumFComputeCores / properties_.NumSIMDPerCU;\n  queue_scratch_len_ = AlignUp(32 * 64 * num_cu * scratch_per_thread_, 65536);\n  size_t max_scratch_len = queue_scratch_len_ * max_queues_;\n\n#if defined(HSA_LARGE_MODEL) && defined(__linux__)\n  // For 64-bit linux use max queues unless otherwise specified\n  if ((max_scratch_len == 0) || (max_scratch_len > MaxScratchDevice())) {\n    max_scratch_len = MaxScratchDevice();  // 4GB per XCC aperture max\n  }\n#endif\n\n  void* scratch_base = nullptr;\n  hsa_status_t err = driver().AllocateScratchMemory(node_id(), max_scratch_len, &scratch_base);\n  assert(err == HSA_STATUS_SUCCESS && \"AllocateScratchMemory failed\");\n  assert(IsMultipleOf(scratch_base, 0x1000) &&\n         \"Scratch base is not page aligned!\");\n\n  scratch_pool_. ~SmallHeap();\n  if (HSA_STATUS_SUCCESS == err) {\n    new (&scratch_pool_) SmallHeap(scratch_base, max_scratch_len);\n  } else {\n    new (&scratch_pool_) SmallHeap();\n  }\n}\n\nvoid GpuAgent::InitAsyncScratchThresholds() {\n  if (!AsyncScratchReclaimEnabled()) return;\n\n  scratch_limit_async_threshold_ =\n      core::Runtime::runtime_singleton_->flag().scratch_single_limit_async();\n\n  if (!scratch_limit_async_threshold_) {\n    // User did not set env var HSA_SCRATCH_SINGLE_LIMIT_ASYNC\n    scratch_limit_async_threshold_ =\n      core::Runtime::runtime_singleton_->flag().DEFAULT_SCRATCH_SINGLE_LIMIT_ASYNC_PER_XCC *\n      (uint64_t)(properties().NumXcc);\n  }\n}\n\nvoid GpuAgent::ReserveScratch()\n{\n  size_t reserved_sz = core::Runtime::runtime_singleton_->flag().scratch_single_limit();\n  if (reserved_sz > MaxScratchDevice()) {\n    fprintf(stdout, \"User specified scratch limit exceeds device limits (requested:%lu max:%lu)!\\n\",\n                    reserved_sz, MaxScratchDevice());\n    reserved_sz = MaxScratchDevice();\n  }\n\n  size_t available;\n  hsa_status_t err = driver().AvailableMemory(node_id(), &available);\n  assert(err == HSA_STATUS_SUCCESS && \"AvailableMemory failed\");\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n  if (!scratch_cache_.reserved_bytes() && reserved_sz && available > 8 * reserved_sz) {\n    HSAuint64 alt_va;\n    void* reserved_base = scratch_pool_.alloc(reserved_sz);\n    assert(reserved_base && \"Could not allocate reserved memory\");\n\n    if (driver().MakeMemoryResident(reserved_base, reserved_sz, &alt_va) == HSA_STATUS_SUCCESS)\n      scratch_cache_.reserve(reserved_sz, reserved_base);\n    else\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES, \"Reserve scratch memory failed.\");\n  }\n}\n\nvoid GpuAgent::InitCacheList() {\n  // Get GPU cache information.\n  // Similar to getting CPU cache but here we use FComputeIdLo.\n  cache_props_.resize(properties_.NumCaches);\n  if (HSA_STATUS_SUCCESS !=\n      driver().GetCacheProperties(node_id(), properties_.FComputeIdLo, cache_props_)) {\n    cache_props_.clear();\n  } else {\n    // Only store GPU D-cache.\n    for (size_t cache_id = 0; cache_id < cache_props_.size(); ++cache_id) {\n      const HsaCacheType type = cache_props_[cache_id].CacheType;\n      if (type.ui32.HSACU != 1 || type.ui32.Instruction == 1) {\n        cache_props_.erase(cache_props_.begin() + cache_id);\n        --cache_id;\n      }\n    }\n  }\n\n  // Update cache objects\n  caches_.clear();\n  caches_.resize(cache_props_.size());\n  char name[64];\n  GetInfo(HSA_AGENT_INFO_NAME, name);\n  std::string deviceName = name;\n  for (size_t i = 0; i < caches_.size(); i++)\n    caches_[i].reset(new core::Cache(deviceName + \" L\" + std::to_string(cache_props_[i].CacheLevel),\n                                     cache_props_[i].CacheLevel, cache_props_[i].CacheSize));\n}\n\nvoid GpuAgent::InitLibDrm() {\n  hsa_status_t status;\n\n  HsaAMDGPUDeviceHandle device_handle;\n  status = driver().GetDeviceHandle(node_id(), &device_handle);\n  if (status != HSA_STATUS_SUCCESS)\n    throw AMD::hsa_exception(status,\n                             \"Agent creation failed.\\nlibdrm get device handle failed.\\n\");\n\n  ldrm_dev_ = (amdgpu_device_handle)device_handle;\n}\n\nhsa_status_t GpuAgent::IterateRegion(\n    hsa_status_t (*callback)(hsa_region_t region, void* data),\n    void* data) const {\n  return VisitRegion(true, callback, data);\n}\n\nhsa_status_t GpuAgent::IterateCache(hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                                    void* data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (size_t i = 0; i < caches_.size(); i++) {\n    hsa_status_t stat = call(core::Cache::Convert(caches_[i].get()), data);\n    if (stat != HSA_STATUS_SUCCESS) return stat;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::IterateSupportedIsas(\n                    hsa_status_t (*callback)(hsa_isa_t isa, void* data),\n                                                          void* data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (const auto& isa : supported_isas()) {\n    hsa_status_t stat = call(core::Isa::Handle(isa), data);\n    if (stat != HSA_STATUS_SUCCESS) return stat;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::VisitRegion(bool include_peer,\n                                   hsa_status_t (*callback)(hsa_region_t region,\n                                                            void* data),\n                                   void* data) const {\n  if (include_peer) {\n    // Only expose system, local, and LDS memory of the blit agent.\n    const auto& gpu_ids = core::Runtime::runtime_singleton_->gpu_ids();\n    for (auto& gpu_id : gpu_ids) {\n      if (this->node_id() == gpu_id) {\n        hsa_status_t stat = VisitRegion(regions_, callback, data);\n        if (stat != HSA_STATUS_SUCCESS) {\n          return stat;\n        }\n      }\n    }\n\n    // Also expose system regions accessible by this agent.\n    hsa_status_t stat =\n        VisitRegion(core::Runtime::runtime_singleton_->system_regions_fine(),\n                    callback, data);\n    if (stat != HSA_STATUS_SUCCESS) {\n      return stat;\n    }\n\n    return VisitRegion(\n        core::Runtime::runtime_singleton_->system_regions_coarse(), callback,\n        data);\n  }\n\n  // Only expose system, local, and LDS memory of this agent.\n  return VisitRegion(regions_, callback, data);\n}\n\nhsa_status_t GpuAgent::VisitRegion(\n    const std::vector<const core::MemoryRegion*>& regions,\n    hsa_status_t (*callback)(hsa_region_t region, void* data),\n    void* data) const {\n  AMD::callback_t<decltype(callback)> call(callback);\n  for (const core::MemoryRegion* region : regions) {\n    if (!region->user_visible()) continue;\n\n    const AMD::MemoryRegion* amd_region =\n        reinterpret_cast<const AMD::MemoryRegion*>(region);\n\n    // Only expose system, local, and LDS memory.\n    if (amd_region->IsSystem() || amd_region->IsLocalMemory() ||\n        amd_region->IsLDS()) {\n      hsa_region_t region_handle = core::MemoryRegion::Convert(region);\n      hsa_status_t status = call(region_handle, data);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\ncore::Queue* GpuAgent::CreateInterceptibleQueue(void (*callback)(hsa_status_t status,\n                                                                 hsa_queue_t* source, void* data),\n                                                void* data, const uint32_t in_size) {\n  // Disabled intercept of internal queues pending tools updates.\n  core::Queue* queue = nullptr;\n  uint32_t size = std::max(in_size, minAqlSize_);\n  size = std::min(size, maxAqlSize_);\n\n  QueueCreate(size, HSA_QUEUE_TYPE_MULTI, HSA_AMD_QUEUE_CREATE_SYSTEM_MEM, callback, data, 0, 0,\n              &queue);\n  if (queue != nullptr)\n    core::Runtime::runtime_singleton_->InternalQueueCreateNotify(core::Queue::Convert(queue),\n                                                                 this->public_handle());\n  return queue;\n}\n\ncore::Blit* GpuAgent::CreateBlitSdma(bool use_xgmi, int rec_eng) {\n  AMD::BlitSdmaBase* sdma;\n  size_t copy_size_override = 0;\n  const size_t copy_size_overrides[2] = {0x3fffff, 0x3fffffff};\n\n  switch (isa_->GetMajorVersion()) {\n    case 9:\n      sdma = new BlitSdmaV4();\n      copy_size_override = (isa_->GetMinorVersion() == 0 && isa_->GetStepping() == 10) ?\n                            copy_size_overrides[1] : copy_size_overrides[0];\n      break;\n    case 10:\n      sdma = new BlitSdmaV5();\n      copy_size_override = isa_->GetMinorVersion() < 3 ? copy_size_overrides[0] :\n                                                         copy_size_overrides[1];\n      break;\n    case 11:\n    case 12:\n      sdma = new BlitSdmaV5();\n      copy_size_override = copy_size_overrides[1];\n      break;\n    default:\n      assert(false && \"Unexpected device major version.\");\n      return nullptr;\n  }\n\n  Flag::SDMA_OVERRIDE copy_size_override_setting =\n    core::Runtime::runtime_singleton_->flag().enable_sdma_copy_size_override();\n  if (copy_size_override_setting == Flag::SDMA_DISABLE) copy_size_override = 0;\n\n  rec_eng = uses_rec_sdma_eng_id_mask_ || !use_xgmi ? rec_eng : -1;\n\n  if (sdma->Initialize(*this, use_xgmi, copy_size_override, rec_eng) != HSA_STATUS_SUCCESS) {\n    sdma->Destroy(*this);\n    delete sdma;\n    sdma = nullptr;\n  }\n\n  return sdma;\n}\n\ncore::Blit* GpuAgent::CreateBlitKernel(core::Queue* queue) {\n  AMD::BlitKernel* kernl = new AMD::BlitKernel(queue);\n\n  if (kernl->Initialize(*this) != HSA_STATUS_SUCCESS) {\n    kernl->Destroy(*this);\n    delete kernl;\n    kernl = NULL;\n  }\n\n  return kernl;\n}\n\nvoid GpuAgent::InitDma() {\n  // Setup lazy init pointers on queues and blits.\n  auto queue_lambda = [this](HSA_QUEUE_PRIORITY priority = HSA_QUEUE_PRIORITY_NORMAL) {\n    auto queue = CreateInterceptibleQueue();\n    if (queue == nullptr)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                               \"Internal queue creation failed.\");\n\n    if (priority != HSA_QUEUE_PRIORITY_NORMAL)\n      if (queue->SetPriority(priority) != HSA_STATUS_SUCCESS)\n        throw AMD::hsa_exception(HSA_STATUS_ERROR,\n                                \"Failed to increase queue priority for PC Sampling\");\n    return queue;\n  };\n\n  // Dedicated compute queue for host-to-device blits.\n  queues_[QueueBlitOnly].reset(queue_lambda);\n  // Share utility queue with device-to-host blits.\n  queues_[QueueUtility].reset(queue_lambda);\n\n  // Dedicated compute queue for PC Sampling CP-DMA commands. We need a dedicated queue that runs at\n  // highest priority because we do not want the CP-DMA commands to be delayed/blocked due to\n  // other dispatches/barriers that could be in the other AQL queues.\n  queues_[QueuePCSampling].reset([queue_lambda]() { return queue_lambda(HSA_QUEUE_PRIORITY_MAXIMUM); });\n\n  // Decide which engine to use for blits.\n  auto blit_lambda = [this](bool use_xgmi, lazy_ptr<core::Queue>& queue, bool isHostToDev, uint32_t rec_eng) {\n    Flag::SDMA_OVERRIDE sdma_override = core::Runtime::runtime_singleton_->flag().enable_sdma();\n\n    // User SDMA queues are unstable on gfx8 and unsupported on gfx1013.\n    bool use_sdma =\n        ((isa_->GetMajorVersion() != 8) && (isa_->GetVersion() != std::make_tuple(10, 1, 3)));\n    if (sdma_override != Flag::SDMA_DEFAULT) use_sdma = (sdma_override == Flag::SDMA_ENABLE);\n\n    if (use_sdma && (HSA_PROFILE_BASE == profile_)) {\n      // On gfx90a ensure that HostToDevice queue is created first and so is placed on SDMA0.\n      if ((!use_xgmi) && (!isHostToDev) && (isa_->GetMajorVersion() == 9) &&\n          (isa_->GetMinorVersion() == 0) && (isa_->GetStepping() == 10)) {\n        GetBlitObject(BlitHostToDev);\n        *blits_[BlitHostToDev];\n      }\n\n      // gfx94x is more efficient with reverse order of SDMA0/1 for host<->device copies\n      if (!use_xgmi && isa_->GetMajorVersion() == 9 && isa_->GetMinorVersion() >= 4)\n        rec_eng = (rec_eng + 1) % properties_.NumSdmaEngines;\n\n      // Check support for targeted SDMA engines\n      auto kfd_version = core::Runtime::runtime_singleton_->KfdVersion().version;\n      if (!(kfd_version.KernelInterfaceMajorVersion > 1 ||\n            (kfd_version.KernelInterfaceMajorVersion == 1 &&\n             kfd_version.KernelInterfaceMinorVersion >= 17)))\n        rec_eng = -1;\n\n      // Observing strange behavior when fixing host<->device engines\n      // on GFX9 devices older than GFX90a, so bypass engine fix.\n      if (!use_xgmi && isa_->GetMajorVersion() == 9 && isa_->GetMinorVersion() == 0\n          && isa_->GetStepping() < 10)\n        rec_eng = -1;\n\n      // devices without dedicated xGMI SDMA engines should not target specific\n      // SDMA engines for queue creation as resources are limited\n      if (!properties_.NumSdmaXgmiEngines)\n        rec_eng = -1;\n\n      auto ret = CreateBlitSdma(use_xgmi, rec_eng);\n      if (ret != nullptr) return ret;\n    }\n\n    // pending_copy_stat_check_ref_ will prevent unnecessary compute queue creation\n    // since there is no graceful way to handle lazy loading when the caller needs to know\n    // the status of available SDMA HW resources without a fallback.\n    // Call to isSDMA should be used as a proxy error check if !blit_copy_fallback.\n    auto ret = pending_copy_stat_check_ref_ ? new AMD::BlitKernel(NULL) :\n                                              CreateBlitKernel((*queue).get());\n    if (ret == nullptr)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES, \"Blit creation failed.\");\n    return ret;\n  };\n\n  // Determine and instantiate the number of blit objects to\n  // engage. The total number is sum of three plus number of\n  // sdma-xgmi engines\n  uint32_t blit_cnt_ = DefaultBlitCount + properties_.NumSdmaXgmiEngines;\n  blits_.resize(blit_cnt_);\n\n  // Initialize blit objects used for D2D, H2D, D2H, and\n  // P2P copy operations.\n  // -- Blit at index BlitDevToDev(0) deals with copies within\n  //    local framebuffer and always engages a Blit Kernel\n  // -- Blit at index BlitHostToDev(1) deals with copies from\n  //    Host to Device (H2D) and could engage either a Blit\n  //    Kernel or sDMA\n  // -- Blit at index BlitDevToHost(2) deals with copies from\n  //    Device to Host (D2H) and Peer to Peer (P2P) over PCIe.\n  //    It could engage either a Blit Kernel or sDMA\n  // -- Blit at index DefaultBlitCount(3) and beyond deal\n  //    exclusively P2P over xGMI links\n  blits_[BlitDevToDev].reset([this]() {\n    auto ret = CreateBlitKernel((*queues_[QueueUtility]).get());\n    if (ret == nullptr)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES, \"Blit creation failed.\");\n    return ret;\n  });\n  blits_[BlitHostToDev].reset(\n      [blit_lambda, this]() { return blit_lambda(false, queues_[QueueBlitOnly], true, 0); });\n  blits_[BlitDevToHost].reset(\n      [blit_lambda, this]() { return blit_lambda(false, queues_[QueueUtility], false, 1); });\n\n  // XGMI engines.\n  for (uint32_t idx = DefaultBlitCount; idx < blit_cnt_; idx++) {\n    const int eng = idx - 1;\n    blits_[idx].reset(\n        [blit_lambda, this, eng]() { return blit_lambda(true, queues_[QueueUtility], false, eng); });\n  }\n\n  // GWS queues.\n  InitGWS();\n}\n\nvoid GpuAgent::InitGWS() {\n  gws_queue_.queue_.reset([this]() {\n    if (properties_.NumGws == 0) return (core::Queue*)nullptr;\n    const uint32_t defaultGWSQueueSize = 0x4000; // 16KB\n    std::unique_ptr<core::Queue> queue(CreateInterceptibleQueue(defaultGWSQueueSize));\n    if (queue == nullptr)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                               \"Internal queue creation failed.\");\n\n    auto err = static_cast<AqlQueue*>(queue.get())->EnableGWS(1);\n    if (err != HSA_STATUS_SUCCESS) throw AMD::hsa_exception(err, \"GWS allocation failed.\");\n\n    gws_queue_.ref_ct_ = 0;\n    return queue.release();\n  });\n}\n\nvoid GpuAgent::GWSRelease() {\n  ScopedAcquire<KernelMutex> lock(&gws_queue_.lock_);\n  gws_queue_.ref_ct_--;\n  if (gws_queue_.ref_ct_ != 0) return;\n  InitGWS();\n}\n\nvoid GpuAgent::PreloadBlits() {\n  for (auto& blit : blits_) {\n    blit.touch();\n  }\n}\n\nvoid GpuAgent::ReleaseResources() {\n  if (this->Enabled()) {\n    this->Disable();\n    for (auto& blit : blits_) {\n      if (!blit.empty()) {\n        hsa_status_t status = blit->Destroy(*this);\n        assert(status == HSA_STATUS_SUCCESS);\n      }\n    }\n\n    if (ape1_base_ != 0) {\n      _aligned_free(reinterpret_cast<void*>(ape1_base_));\n    }\n\n    scratch_cache_.trim(true);\n    scratch_cache_.free_reserve();\n\n    if (scratch_pool_.base() != NULL) {\n      driver().FreeMemory(scratch_pool_.base(), scratch_pool_.size());\n    }\n\n    for (int i = 0; i < QueueCount; i++)\n      queues_[i].reset();\n\n    system_deallocator()(doorbell_queue_map_);\n\n    if (trap_code_buf_ != NULL)\n      system_deallocator()(trap_code_buf_);\n  }\n}\n\nhsa_status_t GpuAgent::PostToolsInit() {\n  // Defer memory allocation until agents have been discovered.\n  InitAllocators();\n  InitScratchPool();\n  BindTrapHandler();\n  InitDma();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::DmaCopy(void* dst, const void* src, size_t size) {\n  return blits_[BlitDevToDev]->SubmitLinearCopyCommand(dst, src, size);\n}\n\nvoid GpuAgent::SetCopyRequestRefCount(bool set) {\n  ScopedAcquire<KernelMutex> lock(&blit_lock_);\n  while (pending_copy_stat_check_ref_) {\n    blit_lock_.Release();\n    os::YieldThread();\n    blit_lock_.Acquire();\n  }\n  if (!set && pending_copy_req_ref_) pending_copy_req_ref_--;\n  else pending_copy_req_ref_++;\n}\n\nvoid GpuAgent::SetCopyStatusCheckRefCount(bool set) {\n  ScopedAcquire<KernelMutex> lock(&blit_lock_);\n  while (pending_copy_req_ref_) {\n    blit_lock_.Release();\n    os::YieldThread();\n    blit_lock_.Acquire();\n  }\n  if (!set && pending_copy_stat_check_ref_) pending_copy_stat_check_ref_--;\n  else pending_copy_stat_check_ref_++;\n}\n\n// Assign direct peer gang factor to GPU\nvoid GpuAgent::RegisterGangPeer(core::Agent& peer, unsigned int max_bandwidth_factor) {\n  gang_peers_info_[peer.public_handle().handle] = max_bandwidth_factor;\n}\n\n// Assign direct peer recommended SDMA engine IDs to GPU\nvoid GpuAgent::RegisterRecSdmaEngIdMaskPeer(core::Agent& peer, uint32_t rec_sdma_eng_id_mask) {\n  auto kfd_version = core::Runtime::runtime_singleton_->KfdVersion().version;\n  bool rec_eng_enabled = core::Runtime::runtime_singleton_->flag().enable_sdma_recommended_eng() !=\n                         Flag::SDMA_DISABLE;\n\n  // Assume all recommended masks with single recommended engine (IsPowerOfTwo)\n  // will only support targeting that engine and will not gang.\n  // Also assume support is uniform for every device in the system.\n  uses_rec_sdma_eng_id_mask_ = (kfd_version.KernelInterfaceMajorVersion > 1 ||\n                                 (kfd_version.KernelInterfaceMajorVersion == 1 &&\n                                  kfd_version.KernelInterfaceMinorVersion >= 17)) &&\n                               isa_->GetMajorVersion() == 9 && isa_->GetMinorVersion() >= 4 &&\n                               IsPowerOfTwo(rec_sdma_eng_id_mask) && rec_eng_enabled;\n\n  rec_sdma_eng_id_peers_info_[peer.public_handle().handle] = uses_rec_sdma_eng_id_mask_ ?\n                                                             rec_sdma_eng_id_mask : 0;\n}\n\n// Destroy gang signal\nstatic bool GangCopyCompleteHandler(hsa_signal_value_t, void *arg ) {\n  core::Signal *gang_signal = reinterpret_cast<core::Signal*>(arg);\n  if (gang_signal->IsValid()) {\n    gang_signal->DestroySignal();\n    if (!gang_signal->IsValid()) {\n      return false;\n    }\n  }\n  return true;\n}\n\nhsa_status_t GpuAgent::DmaCopy(void* dst, core::Agent& dst_agent,\n                               const void* src, core::Agent& src_agent,\n                               size_t size,\n                               std::vector<core::Signal*>& dep_signals,\n                               core::Signal& out_signal) {\n  // Recommended SDMA engine copies only have gang factor 1\n  uint32_t rec_sdma_eng = ffs(rec_sdma_eng_id_peers_info_[dst_agent.public_handle().handle]);\n\n  if (rec_sdma_eng)\n    return DmaCopyOnEngine(dst, dst_agent, src, src_agent, size,\n                           dep_signals, out_signal, rec_sdma_eng, false);\n\n  if (profiling_enabled()) {\n    // Track the agent so we could translate the resulting timestamp to system\n    // domain correctly.\n    out_signal.async_copy_agent(core::Agent::Convert(this->public_handle()));\n  }\n\n  // Calculate the number of gang items\n  unsigned int gang_factor = 1;\n  if (core::Runtime::runtime_singleton_->flag().enable_sdma_gang() != Flag::SDMA_DISABLE &&\n      size >= 4096 && dst_agent.device_type() == core::Agent::kAmdGpuDevice)\n    gang_factor = gang_peers_info_[dst_agent.public_handle().handle];\n  // Use non-D2D (auxillary) SDMA engines in the event of xGMI D2D support\n  // when xGMI SDMA context is not available.\n  bool has_aux_gang = gang_factor > 1 &&\n                      gang_factor >= properties_.NumSdmaEngines &&\n                      !!!properties_.NumSdmaXgmiEngines;\n  if (gang_factor > 1) {\n    gang_factor = has_aux_gang ?\n                      std::min(gang_factor, properties_.NumSdmaEngines) :\n                      std::min(gang_factor, properties_.NumSdmaXgmiEngines);\n  }\n\n  ScopedAcquire<KernelMutex> lock(&sdma_gang_lock_);\n  // Manage internal gang signals\n  std::vector<core::Signal*> gang_signals;\n  if (gang_factor > 1) {\n    for (int i = 0; i < gang_factor - 1; i++) {\n      core::Signal *gang_signal;\n\n      // Initial value is 2 where 1 is for gang-leader to ack and\n      // 1 for non-leader gang item to decrement\n      gang_signal = new core::DefaultSignal(2);\n\n      // Fall back to non-gang copy\n      if (!gang_signal->IsValid()) {\n        for (int j = 0; j < gang_signals.size(); j++) gang_signals[j]->DestroySignal();\n        gang_factor = 1;\n        break;\n      }\n\n      core::Runtime::runtime_singleton_->SetAsyncSignalHandler(\n                                         core::Signal::Convert(gang_signal),\n                                         HSA_SIGNAL_CONDITION_EQ, 0, GangCopyCompleteHandler,\n                                         reinterpret_cast<void*>(gang_signal));\n      gang_signals.push_back(gang_signal);\n    }\n  }\n\n  // Bind the Blit object that will drive this copy operation\n  size_t offset = 0, remainder_size = size;\n  int gang_sig_count = 0;\n  for (int i = 0; i < gang_factor; i++) {\n    // Set leader and gang status to blit\n    SetCopyRequestRefCount(true);\n    MAKE_SCOPE_GUARD([&]() { SetCopyRequestRefCount(false); });\n    lazy_ptr<core::Blit>& blit = gang_factor > 1 ?\n                                 (has_aux_gang ? blits_[i + 1] : blits_[i + DefaultBlitCount]) :\n                                 GetBlitObject(dst_agent, src_agent, size);\n    blit->GangLeader(gang_factor > 1 && !i);\n\n    hsa_status_t stat;\n    size_t chunk = std::min(remainder_size, (size + gang_factor - 1)/gang_factor);\n    if (!blit->GangLeader() && !gang_signals.empty()) {\n      stat = blit->SubmitLinearCopyCommand(reinterpret_cast<uint8_t*>(dst) + offset,\n                                           reinterpret_cast<const uint8_t*>(src) + offset,\n                                           chunk, dep_signals,\n                                           *gang_signals[gang_sig_count], gang_signals);\n      gang_sig_count++;\n    } else {\n      stat = blit->SubmitLinearCopyCommand(reinterpret_cast<uint8_t*>(dst) + offset,\n                                           reinterpret_cast<const uint8_t*>(src) + offset,\n                                           chunk, dep_signals,\n                                           out_signal, gang_signals);\n    }\n\n    if (stat)\n      return stat;\n\n    offset += chunk;\n    remainder_size -= chunk;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::DmaCopyOnEngine(void* dst, core::Agent& dst_agent,\n                               const void* src, core::Agent& src_agent,\n                               size_t size,\n                               std::vector<core::Signal*>& dep_signals,\n                               core::Signal& out_signal,\n                               int engine_offset,\n                               bool force_copy_on_sdma) {\n  // At this point it is guaranteed that one of\n  // the two devices is a GPU, potentially both\n  assert(((src_agent.device_type() == core::Agent::kAmdGpuDevice) ||\n          (dst_agent.device_type() == core::Agent::kAmdGpuDevice)) &&\n         (\"Both devices are CPU agents which is not expected\"));\n\n  if (engine_offset > properties_.NumSdmaEngines + properties_.NumSdmaXgmiEngines) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // check if dst and src are the same gpu or over xGMI.\n  bool is_same_gpu = (src_agent.public_handle().handle == dst_agent.public_handle().handle) &&\n                     (dst_agent.public_handle().handle == public_handle_.handle);\n\n  bool is_p2p = !is_same_gpu && src_agent.device_type() == core::Agent::kAmdGpuDevice &&\n                                dst_agent.device_type() == core::Agent::kAmdGpuDevice;\n\n  if ((is_p2p &&\n      core::Runtime::runtime_singleton_->flag().enable_peer_sdma() == Flag::SDMA_DISABLE) ||\n      core::Runtime::runtime_singleton_->flag().enable_sdma() == Flag::SDMA_DISABLE) {\n    // Note  that VDI/HIP will call DmaCopy instead of DmaCopyOnEngine for P2P copies, but\n    // we still want to handle force Blit Kernels in this function in case other libraries\n    // decide to use DmaCopyOnEngine for P2P copies\n\n    engine_offset = BlitDevToDev;\n  } else {\n    bool is_xgmi = is_p2p && dst_agent.HiveId() && src_agent.HiveId() == dst_agent.HiveId() &&\n                         properties_.NumSdmaXgmiEngines;\n\n    // Due to a RAS issue, GFX90a can only support H2D copies on SDMA0\n    bool is_h2d_blit = (src_agent.device_type() == core::Agent::kAmdCpuDevice &&\n      dst_agent.device_type() == core::Agent::kAmdGpuDevice);\n    bool limit_h2d_blit = isa_->GetVersion() == core::Isa::Version(9, 0, 10);\n\n    // Ensure engine selection is within proper range based on transfer type\n    if ((is_xgmi && !rec_sdma_eng_override_ && engine_offset <= properties_.NumSdmaEngines) ||\n        (!is_xgmi && engine_offset > (properties_.NumSdmaEngines +\n                                      properties_.NumSdmaXgmiEngines)) ||\n          (!is_h2d_blit && !is_same_gpu && limit_h2d_blit &&\n            engine_offset == BlitHostToDev)) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    engine_offset = is_same_gpu && !force_copy_on_sdma ? BlitDevToDev : engine_offset;\n  }\n\n  SetCopyRequestRefCount(true);\n  MAKE_SCOPE_GUARD([&]() { SetCopyRequestRefCount(false); });\n  lazy_ptr<core::Blit>& blit = GetBlitObject(engine_offset);\n\n  if (profiling_enabled()) {\n    // Track the agent so we could translate the resulting timestamp to system\n    // domain correctly.\n    out_signal.async_copy_agent(core::Agent::Convert(this->public_handle()));\n  }\n\n  std::vector<core::Signal*> gang_signals(0);\n\n  hsa_status_t stat = blit->SubmitLinearCopyCommand(dst, src, size, dep_signals, out_signal,\n                                                    gang_signals);\n\n  return stat;\n}\n\nbool GpuAgent::DmaEngineIsFree(uint32_t engine_offset) {\n  SetCopyStatusCheckRefCount(true);\n  MAKE_SCOPE_GUARD([&]() { SetCopyStatusCheckRefCount(false); });\n  bool is_free = !!!(sdma_blit_used_mask_ & (1 << engine_offset)) ||\n                    (blits_[engine_offset]->isSDMA() &&\n                     !!!blits_[engine_offset]->PendingBytes());\n  return is_free;\n}\n\nhsa_status_t GpuAgent::DmaCopyStatus(core::Agent& dst_agent, core::Agent& src_agent,\n                                     uint32_t *engine_ids_mask) {\n  assert(((src_agent.device_type() == core::Agent::kAmdGpuDevice) ||\n          (dst_agent.device_type() == core::Agent::kAmdGpuDevice)) &&\n         (\"Both devices are CPU agents which is not expected\"));\n\n  *engine_ids_mask = 0;\n  if (src_agent.device_type() == core::Agent::kAmdGpuDevice &&\n                   dst_agent.device_type() == core::Agent::kAmdGpuDevice &&\n                     dst_agent.HiveId() && src_agent.HiveId() == dst_agent.HiveId() &&\n                       properties_.NumSdmaXgmiEngines) {\n    //Find a free xGMI SDMA engine\n    if (rec_sdma_eng_override_) {\n      for (int i = 0; i < (properties_.NumSdmaEngines + properties_.NumSdmaXgmiEngines); i++) {\n        if (DmaEngineIsFree(BlitHostToDev + i)) {\n          *engine_ids_mask |= (HSA_AMD_SDMA_ENGINE_0 << i);\n        }\n      }\n    } else {\n      for (int i = 0; i < properties_.NumSdmaXgmiEngines; i++) {\n        if (DmaEngineIsFree(DefaultBlitCount + i)) {\n          *engine_ids_mask |= (HSA_AMD_SDMA_ENGINE_2 << i);\n        }\n      }\n    }\n  } else {\n    bool is_h2d_blit = (src_agent.device_type() == core::Agent::kAmdCpuDevice &&\n      dst_agent.device_type() == core::Agent::kAmdGpuDevice);\n    // Due to a RAS issue, GFX90a can only support H2D copies on SDMA0\n    bool limit_h2d_blit = isa_->GetVersion() == core::Isa::Version(9, 0, 10);\n\n    // Check if H2D is free\n    if (DmaEngineIsFree(BlitHostToDev)) {\n      if (is_h2d_blit || !limit_h2d_blit) {\n        *engine_ids_mask |= HSA_AMD_SDMA_ENGINE_0;\n      }\n    }\n\n    // Check is D2H is free\n    if (DmaEngineIsFree(BlitDevToHost)) {\n      *engine_ids_mask |= properties_.NumSdmaEngines > 1 ?\n                          HSA_AMD_SDMA_ENGINE_1 :\n                          HSA_AMD_SDMA_ENGINE_0;\n    }\n    // Find a free xGMI SDMA engine for H2D/D2H though it may be lower bandwidth\n    for (int i = 0; i < properties_.NumSdmaXgmiEngines; i++) {\n      if (DmaEngineIsFree(DefaultBlitCount + i)) {\n         *engine_ids_mask |= (HSA_AMD_SDMA_ENGINE_2 << i);\n      }\n    }\n  }\n\n  return !!(*engine_ids_mask) ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n}\n\nhsa_status_t GpuAgent::DmaPreferredEngine(core::Agent& dst_agent, core::Agent& src_agent,\n                                          uint32_t *recommended_ids_mask) {\n  assert(((src_agent.device_type() == core::Agent::kAmdGpuDevice) ||\n          (dst_agent.device_type() == core::Agent::kAmdGpuDevice)) &&\n         (\"Both devices are CPU agents which is not expected\"));\n\n  *recommended_ids_mask = rec_sdma_eng_id_peers_info_[dst_agent.public_handle().handle];\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::DmaCopyRect(const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset,\n                                   const hsa_pitched_ptr_t* src, const hsa_dim3_t* src_offset,\n                                   const hsa_dim3_t* range, hsa_amd_copy_direction_t dir,\n                                   std::vector<core::Signal*>& dep_signals,\n                                   core::Signal& out_signal) {\n  if (isa_->GetMajorVersion() < 9) return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  SetCopyRequestRefCount(true);\n  MAKE_SCOPE_GUARD([&]() { SetCopyRequestRefCount(false); });\n  lazy_ptr<core::Blit>& blit = GetBlitObject((dir == hsaHostToDevice) ? BlitHostToDev :\n                                                                        BlitDevToHost);\n\n  if (!blit->isSDMA()) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  if (profiling_enabled()) {\n    // Track the agent so we could translate the resulting timestamp to system\n    // domain correctly.\n    out_signal.async_copy_agent(core::Agent::Convert(this->public_handle()));\n  }\n\n  BlitSdmaBase* sdmaBlit = static_cast<BlitSdmaBase*>((*blit).get());\n  hsa_status_t stat = sdmaBlit->SubmitCopyRectCommand(dst, dst_offset, src, src_offset, range,\n                                                      dep_signals, out_signal);\n\n  return stat;\n}\n\nhsa_status_t GpuAgent::DmaFill(void* ptr, uint32_t value, size_t count) {\n  return blits_[BlitDevToDev]->SubmitLinearFillCommand(ptr, value, count);\n}\n\nhsa_status_t GpuAgent::EnableDmaProfiling(bool enable) {\n  for (auto& blit : blits_) {\n    if (!blit.empty()) {\n      const hsa_status_t stat = blit->EnableProfiling(enable);\n      if (stat != HSA_STATUS_SUCCESS) {\n        return stat;\n      }\n    }\n  }\n\n  if (enable) CheckClockTicks();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid GpuAgent::GetInfoMemoryProperties(uint8_t value[8]) const {\n  auto setFlag = [&](uint32_t bit) {\n    assert(bit < 8 * 8 && \"Flag value exceeds input parameter size\");\n\n    uint index = bit / 8;\n    uint subBit = bit % 8;\n    ((uint8_t*)value)[index] |= 1 << subBit;\n  };\n\n  // Fill the HSA_AMD_MEMORY_PROPERTY_AGENT_IS_APU flag\n  if (properties_.Integrated)\n      setFlag(HSA_AMD_MEMORY_PROPERTY_AGENT_IS_APU);\n}\n\nhsa_status_t GpuAgent::GetInfo(hsa_agent_info_t attribute, void* value) const {\n  // agent, and vendor name size limit\n  const size_t attribute_u = static_cast<size_t>(attribute);\n  // agent, and vendor name length limit excluding terminating nul character.\n  constexpr size_t hsa_name_size = 63;\n\n  const bool isa_has_image_support =\n      (isa_->GetMajorVersion() == 9 &&\n      (isa_->GetMinorVersion() == 4 || isa_->GetMinorVersion() == 5)) ? false : true;\n\n  switch (attribute_u) {\n    case HSA_AGENT_INFO_NAME: {\n      std::string name = isa_->GetProcessorName();\n      assert(name.size() <= hsa_name_size);\n      std::memset(value, 0, hsa_name_size);\n      char* temp = reinterpret_cast<char*>(value);\n      std::strcpy(temp, name.c_str());\n      break;\n    }\n    case HSA_AGENT_INFO_VENDOR_NAME:\n      std::memset(value, 0, hsa_name_size);\n      std::memcpy(value, \"AMD\", sizeof(\"AMD\"));\n      break;\n    case HSA_AGENT_INFO_FEATURE:\n      *((hsa_agent_feature_t*)value) = HSA_AGENT_FEATURE_KERNEL_DISPATCH;\n      break;\n    case HSA_AGENT_INFO_MACHINE_MODEL:\n#if defined(HSA_LARGE_MODEL)\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_LARGE;\n#else\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_SMALL;\n#endif\n      break;\n    case HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES:\n    case HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE:\n      *((hsa_default_float_rounding_mode_t*)value) =\n          HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR;\n      break;\n    case HSA_AGENT_INFO_FAST_F16_OPERATION:\n      if (isa_->GetMajorVersion() >= 8) {\n        *((bool*)value) = true;\n      } else {\n        *((bool*)value) = false;\n      }\n      break;\n    case HSA_AGENT_INFO_PROFILE:\n      *((hsa_profile_t*)value) = profile_;\n      break;\n    case HSA_AGENT_INFO_WAVEFRONT_SIZE:\n      *((uint32_t*)value) = properties_.WaveFrontSize;\n      break;\n    case HSA_AGENT_INFO_WORKGROUP_MAX_DIM: {\n      // TODO: must be per-device\n      const uint16_t group_size[3] = {1024, 1024, 1024};\n      std::memcpy(value, group_size, sizeof(group_size));\n    } break;\n    case HSA_AGENT_INFO_WORKGROUP_MAX_SIZE:\n      // TODO: must be per-device\n      *((uint32_t*)value) = 1024;\n      break;\n    case HSA_AGENT_INFO_GRID_MAX_DIM: {\n      const hsa_dim3_t grid_size = {INT32_MAX, UINT16_MAX, UINT16_MAX};\n      std::memcpy(value, &grid_size, sizeof(hsa_dim3_t));\n    } break;\n    case HSA_AGENT_INFO_GRID_MAX_SIZE:\n      *((uint32_t*)value) = UINT32_MAX;\n      break;\n    case HSA_AGENT_INFO_FBARRIER_MAX_SIZE:\n      // TODO: to confirm\n      *((uint32_t*)value) = 32;\n      break;\n    case HSA_AGENT_INFO_QUEUES_MAX:\n      *((uint32_t*)value) = max_queues_;\n      break;\n    case HSA_AGENT_INFO_QUEUE_MIN_SIZE:\n      *((uint32_t*)value) = minAqlSize_;\n      break;\n    case HSA_AGENT_INFO_QUEUE_MAX_SIZE:\n      *((uint32_t*)value) = maxAqlSize_;\n      break;\n    case HSA_AGENT_INFO_QUEUE_TYPE:\n      *((hsa_queue_type32_t*)value) = HSA_QUEUE_TYPE_MULTI;\n      break;\n    case HSA_AGENT_INFO_NODE:\n      // TODO: associate with OS NUMA support (numactl / GetNumaProcessorNode).\n      *((uint32_t*)value) = node_id();\n      break;\n    case HSA_AGENT_INFO_DEVICE:\n      *((hsa_device_type_t*)value) = HSA_DEVICE_TYPE_GPU;\n      break;\n    case HSA_AGENT_INFO_CACHE_SIZE: {\n      std::memset(value, 0, sizeof(uint32_t) * 4);\n      assert(cache_props_.size() > 0 && \"GPU cache info missing.\");\n      const size_t num_cache = cache_props_.size();\n      for (size_t i = 0; i < num_cache; ++i) {\n        const uint32_t line_level = cache_props_[i].CacheLevel;\n          /*\n           * L1 Cache is per CU.\n           * For L2 Cache and above, we report total for the partition so we sum\n           * all the node entries.\n           */\n        if (line_level >= 2)\n          reinterpret_cast<uint32_t*>(value)[line_level - 1] += cache_props_[i].CacheSize * 1024;\n        else if (reinterpret_cast<uint32_t*>(value)[line_level - 1] == 0)\n          reinterpret_cast<uint32_t*>(value)[line_level - 1] = cache_props_[i].CacheSize * 1024;\n      }\n    } break;\n    case HSA_AGENT_INFO_ISA:\n      *((hsa_isa_t*)value) = core::Isa::Handle(isa_);\n      break;\n    case HSA_AGENT_INFO_EXTENSIONS: {\n      memset(value, 0, sizeof(uint8_t) * 128);\n\n      auto setFlag = [&](uint32_t bit) {\n        assert(bit < 128 * 8 && \"Extension value exceeds extension bitmask\");\n        uint index = bit / 8;\n        uint subBit = bit % 8;\n        ((uint8_t*)value)[index] |= 1 << subBit;\n      };\n\n      if (core::hsa_internal_api_table().finalizer_api.hsa_ext_program_finalize_fn != NULL) {\n        setFlag(HSA_EXTENSION_FINALIZER);\n      }\n\n      if (core::hsa_internal_api_table().image_api.hsa_ext_image_create_fn != NULL) {\n        setFlag(HSA_EXTENSION_IMAGES);\n      }\n\n      if (core::hsa_internal_api_table().pcs_api.hsa_ven_amd_pcs_iterate_configuration_fn != NULL) {\n        setFlag(HSA_EXTENSION_AMD_PC_SAMPLING);\n      }\n\n      if (os::LibHandle lib = os::LoadLib(kAqlProfileLib)) {\n        os::CloseLib(lib);\n        setFlag(HSA_EXTENSION_AMD_AQLPROFILE);\n      }\n\n      setFlag(HSA_EXTENSION_AMD_PROFILER);\n\n      break;\n    }\n    case HSA_AGENT_INFO_VERSION_MAJOR:\n      *((uint16_t*)value) = 1;\n      break;\n    case HSA_AGENT_INFO_VERSION_MINOR:\n      *((uint16_t*)value) = 1;\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_1DA_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_1DB_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2D_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DA_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DDEPTH_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_2DADEPTH_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_3D_MAX_ELEMENTS:\n    case HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS:\n      if (!isa_has_image_support)\n        *((uint32_t*)value) = 0;\n      else\n        return hsa_amd_image_get_info_max_dim(public_handle(), attribute, value);\n      break;\n    case HSA_EXT_AGENT_INFO_MAX_IMAGE_RD_HANDLES:\n      // TODO: hardcode based on OCL constants.\n      *((uint32_t*)value) = isa_has_image_support ? 128 : 0;\n      break;\n    case HSA_EXT_AGENT_INFO_MAX_IMAGE_RORW_HANDLES:\n      *((uint32_t*)value) = isa_has_image_support ? 64 : 0;\n      break;\n    case HSA_EXT_AGENT_INFO_MAX_SAMPLER_HANDLERS:\n      *((uint32_t*)value) = isa_has_image_support ? 16 : 0;\n      break;\n    case HSA_AMD_AGENT_INFO_CHIP_ID:\n      *((uint32_t*)value) = properties_.DeviceId;\n      break;\n    case HSA_AMD_AGENT_INFO_CACHELINE_SIZE:\n      for (auto& cache : cache_props_) {\n        if ((cache.CacheLevel == 2) && (cache.CacheLineSize != 0)) {\n          *((uint32_t*)value) = cache.CacheLineSize;\n          return HSA_STATUS_SUCCESS;\n        }\n      }\n      // Fallback for when KFD is returning zero.\n      *((uint32_t*)value) = 64;\n      break;\n    case HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT:\n      *((uint32_t*)value) =\n          (properties_.NumFComputeCores / properties_.NumSIMDPerCU);\n      break;\n    case HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY:\n      *((uint32_t*)value) = properties_.MaxEngineClockMhzFCompute;\n      break;\n    case HSA_AMD_AGENT_INFO_DRIVER_NODE_ID:\n      *((uint32_t*)value) = node_id();\n      break;\n    case HSA_AMD_AGENT_INFO_MAX_ADDRESS_WATCH_POINTS:\n      *((uint32_t*)value) = static_cast<uint32_t>(\n          1 << properties_.Capability.ui32.WatchPointsTotalBits);\n      break;\n    case HSA_AMD_AGENT_INFO_BDFID:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.LocationId);\n      break;\n    case HSA_AMD_AGENT_INFO_MEMORY_WIDTH:\n      *((uint32_t*)value) = memory_bus_width_;\n      break;\n    case HSA_AMD_AGENT_INFO_MEMORY_MAX_FREQUENCY:\n      *((uint32_t*)value) = memory_max_frequency_;\n      break;\n\n    // The code copies HsaNodeProperties.MarketingName a Unicode string\n    // which is encoded in UTF-16 as a 7-bit ASCII string\n    case HSA_AMD_AGENT_INFO_PRODUCT_NAME: {\n      std::memset(value, 0, HSA_PUBLIC_NAME_SIZE);\n      char* temp = reinterpret_cast<char*>(value);\n      for (uint32_t idx = 0;\n           properties_.MarketingName[idx] != 0 && idx < HSA_PUBLIC_NAME_SIZE - 1; idx++) {\n        temp[idx] = (uint8_t)properties_.MarketingName[idx];\n      }\n      break;\n    }\n    case HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU:\n      *((uint32_t*)value) = static_cast<uint32_t>(\n          properties_.NumSIMDPerCU * properties_.MaxWavesPerSIMD);\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU:\n      *((uint32_t*)value) = properties_.NumSIMDPerCU;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SHADER_ENGINES:\n      *((uint32_t*)value) = properties_.NumShaderBanks;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SHADER_ARRAYS_PER_SE:\n      *((uint32_t*)value) = properties_.NumArrays;\n      break;\n    case HSA_AMD_AGENT_INFO_HDP_FLUSH:\n      *((hsa_amd_hdp_flush_t*)value) = HDP_flush_;\n      break;\n    case HSA_AMD_AGENT_INFO_DOMAIN:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.Domain);\n      break;\n    case HSA_AMD_AGENT_INFO_COOPERATIVE_QUEUES:\n      *((bool*)value) = properties_.NumGws != 0;\n      break;\n    case HSA_AMD_AGENT_INFO_UUID: {\n      uint64_t uuid_value = static_cast<uint64_t>(properties_.UniqueID);\n\n      // Either device does not support UUID e.g. a Gfx8 device,\n      // or runtime is using an older thunk library that does not\n      // support UUID's\n      if (uuid_value == 0) {\n        char uuid_tmp[] = \"GPU-XX\";\n        snprintf((char*)value, sizeof(uuid_tmp), \"%s\", uuid_tmp);\n        break;\n      }\n\n      // Device supports UUID, build UUID string to return\n      std::stringstream ss;\n      ss << \"GPU-\" << std::setfill('0') << std::setw(sizeof(uint64_t) * 2) << std::hex\n         << uuid_value;\n      snprintf((char*)value, (ss.str().length() + 1), \"%s\", (char*)ss.str().c_str());\n      break;\n    }\n    case HSA_AMD_AGENT_INFO_ASIC_REVISION:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.Capability.ui32.ASICRevision);\n      break;\n    case HSA_AMD_AGENT_INFO_SVM_DIRECT_HOST_ACCESS:\n      assert(regions_.size() != 0 && \"No device local memory found!\");\n      *((bool*)value) = properties_.Capability.ui32.CoherentHostAccess == 1;\n      break;\n    case HSA_AMD_AGENT_INFO_COOPERATIVE_COMPUTE_UNIT_COUNT:\n      if (core::Runtime::runtime_singleton_->flag().coop_cu_count() &&\n          !(core::Runtime::runtime_singleton_->flag().cu_mask(enum_index_).empty())) {\n        debug_warning(\"Cooperative launch and CU masking are currently incompatible!\");\n        *((uint32_t*)value) = 0;\n        break;\n      }\n\n      if (core::Runtime::runtime_singleton_->flag().coop_cu_count() &&\n          (isa_->GetMajorVersion() == 9) && (isa_->GetMinorVersion() == 0) &&\n          (isa_->GetStepping() == 10)) {\n        uint32_t count = 0;\n        hsa_status_t err = GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &count);\n        assert(err == HSA_STATUS_SUCCESS && \"CU count query failed.\");\n        *((uint32_t*)value) = (count & 0xFFFFFFF8) - 8;  // value = floor(count/8)*8-8\n        break;\n      }\n      return GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, value);\n    case HSA_AMD_AGENT_INFO_MEMORY_AVAIL: {\n      HSAuint64 availableBytes;\n      hsa_status_t status;\n\n      status = driver().AvailableMemory(node_id(), &availableBytes);\n\n      if (status != HSA_STATUS_SUCCESS) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n      for (auto r : regions()) availableBytes += ((AMD::MemoryRegion*)r)->GetCacheSize();\n\n      availableBytes += scratch_cache_.free_bytes() - scratch_cache_.reserved_bytes();\n\n      *((uint64_t*)value) = availableBytes;\n      break;\n    }\n    case HSA_AMD_AGENT_INFO_TIMESTAMP_FREQUENCY:\n      *((uint64_t*)value) = wallclock_frequency_;\n      break;\n    case HSA_AMD_AGENT_INFO_ASIC_FAMILY_ID:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.FamilyID);\n      break;\n    case HSA_AMD_AGENT_INFO_UCODE_VERSION:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.EngineId.ui32.uCode);\n      break;\n    case HSA_AMD_AGENT_INFO_SDMA_UCODE_VERSION:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.uCodeEngineVersions.uCodeSDMA);\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SDMA_ENG:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.NumSdmaEngines);\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_SDMA_XGMI_ENG:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.NumSdmaXgmiEngines);\n      break;\n    case HSA_AMD_AGENT_INFO_IOMMU_SUPPORT:\n      if (properties_.Capability.ui32.HSAMMUPresent)\n        *((hsa_amd_iommu_version_t*)value) = HSA_IOMMU_SUPPORT_V2;\n      else\n        *((hsa_amd_iommu_version_t*)value) = HSA_IOMMU_SUPPORT_NONE;\n      break;\n    case HSA_AMD_AGENT_INFO_NUM_XCC:\n      *((uint32_t*)value) = static_cast<uint32_t>(properties_.NumXcc);\n      break;\n    case HSA_AMD_AGENT_INFO_DRIVER_UID:\n      *((uint32_t*)value) = KfdGpuID();\n      break;\n    case HSA_AMD_AGENT_INFO_NEAREST_CPU:\n      *((hsa_agent_t*)value) = GetNearestCpuAgent()->public_handle();\n      break;\n    case HSA_AMD_AGENT_INFO_MEMORY_PROPERTIES:\n      memset(value, 0, sizeof(uint8_t) * 8);\n      GetInfoMemoryProperties((uint8_t*)value);\n      break;\n    case HSA_AMD_AGENT_INFO_AQL_EXTENSIONS:\n      memset(value, 0, sizeof(uint8_t) * 8);\n      /* Not yet implemented */\n      break;\n    case HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_MAX:\n      *((uint64_t*)value) = MaxScratchDevice();\n      break;\n    case HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_CURRENT:\n      *((uint64_t*)value) = scratch_limit_async_threshold_;\n      break;\n    case HSA_AMD_AGENT_INFO_CLOCK_COUNTERS: {\n      HsaClockCounters hsakmt_counters = {};\n      hsa_amd_clock_counters_t* counters = static_cast<hsa_amd_clock_counters_t*>(value);\n\n      hsa_status_t err = driver().GetClockCounters(node_id(), &hsakmt_counters);\n      if (err == HSA_STATUS_SUCCESS) {\n        counters->cpu_clock_counter = hsakmt_counters.CPUClockCounter;\n        counters->gpu_clock_counter = hsakmt_counters.GPUClockCounter;\n        counters->system_clock_counter = hsakmt_counters.SystemClockCounter;\n        counters->system_clock_frequency = hsakmt_counters.SystemClockFrequencyHz;\n        break;\n      }\n      return HSA_STATUS_ERROR;\n    }\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      break;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::QueueCreate(size_t size, hsa_queue_type32_t queue_type, uint64_t flags,\n                                   core::HsaEventCallback event_callback, void* data,\n                                   uint32_t private_segment_size, uint32_t group_segment_size,\n                                   core::Queue** queue) {\n  // Handle GWS queues.\n  if (queue_type == HSA_QUEUE_TYPE_COOPERATIVE) {\n    ScopedAcquire<KernelMutex> lock(&gws_queue_.lock_);\n    auto ret = (*gws_queue_.queue_).get();\n    if (ret != nullptr) {\n      gws_queue_.ref_ct_++;\n      *queue = ret;\n      return HSA_STATUS_SUCCESS;\n    }\n    return HSA_STATUS_ERROR_INVALID_QUEUE_CREATION;\n  }\n\n  // AQL queues must be a power of two in length.\n  if (!IsPowerOfTwo(size)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Enforce max size\n  if (size > maxAqlSize_) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  // Enforce min size\n  if (size < minAqlSize_) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Allocate scratch memory\n  ScratchInfo scratch = {0};\n  if (private_segment_size == UINT_MAX) {\n    private_segment_size = (profile_ == HSA_PROFILE_BASE) ? 0 : scratch_per_thread_;\n  }\n\n  if (private_segment_size > 262128) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  // Asynchronous reclaim flag bit is set by CP FW on queue-connect, we will update this when\n  // we get the first scratch request.\n  scratch.async_reclaim = false;\n\n  scratch.main_lanes_per_wave = 64;\n  scratch.main_size_per_thread = AlignUp(private_segment_size, 1024 / scratch.main_lanes_per_wave);\n  if (scratch.main_size_per_thread > 262128) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  scratch.main_size_per_thread = private_segment_size;\n\n  const uint32_t num_cu = properties_.NumFComputeCores / properties_.NumSIMDPerCU;\n  scratch.main_size = scratch.main_size_per_thread * properties_.MaxSlotsScratchCU *\n      scratch.main_lanes_per_wave * num_cu;\n  scratch.main_queue_base = nullptr;\n  scratch.main_queue_process_offset = 0;\n\n  MAKE_NAMED_SCOPE_GUARD(scratchGuard, [&]() { ReleaseQueueMainScratch(scratch); });\n\n  if (scratch.main_size != 0) {\n    AcquireQueueMainScratch(scratch);\n    if (scratch.main_queue_base == nullptr) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  // Ensure utility queue has been created.\n  // Deferring longer risks exhausting queue count before ISA upload and invalidation capability is\n  // ensured.\n  queues_[QueueUtility].touch();\n\n  bool dev_mem_queue_descriptor = (flags & HSA_AMD_QUEUE_CREATE_DEVICE_MEM_QUEUE_DESCRIPTOR) != 0;\n\n  // Create an HW AQL queue\n  core::SharedQueue* shared_queue = nullptr;\n\n  if (dev_mem_queue_descriptor) {\n    shared_queue = static_cast<core::SharedQueue*>(\n        finegrain_allocator()(sizeof(core::SharedQueue), core::MemoryRegion::AllocateUncached));\n  } else {\n    shared_queue =\n        static_cast<core::SharedQueue*>(core::Runtime::runtime_singleton_->system_allocator()(\n            sizeof(core::SharedQueue), MemoryRegion::GetPageSize(),\n            isMES() ? (MemoryRegion::AllocateGTTAccess | MemoryRegion::AllocateNonPaged) : 0,\n            node_id()));\n  }\n\n  if (!shared_queue) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  auto aql_queue = new AqlQueue(shared_queue, this, size, node_id(), scratch, event_callback, data,\n                                flags);\n  *queue = aql_queue;\n  aql_queues_.push_back(aql_queue);\n\n  if (doorbell_queue_map_) {\n    // Calculate index of the queue doorbell within the doorbell aperture.\n    auto doorbell_addr = uintptr_t(aql_queue->signal_.hardware_doorbell_ptr);\n    auto doorbell_idx = (doorbell_addr >> 3) & (MAX_NUM_DOORBELLS - 1);\n    doorbell_queue_map_[doorbell_idx] = &aql_queue->amd_queue_;\n  }\n\n  scratchGuard.Dismiss();\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid GpuAgent::AcquireQueueMainScratch(ScratchInfo& scratch) {\n  assert(scratch.main_queue_base == nullptr &&\n         \"AcquireQueueMainScratch called while holding scratch.\");\n  bool need_queue_scratch_base = (isa_->GetMajorVersion() > 8);\n\n  if (scratch.main_size == 0) {\n    scratch.main_size = queue_scratch_len_;\n    scratch.main_size_per_thread = scratch_per_thread_;\n  }\n  scratch.retry = false;\n\n  // Fail scratch allocation if per wave limits are exceeded.\n  uint64_t size_per_wave = AlignUp(scratch.main_size_per_thread * properties_.WaveFrontSize, 1024);\n  if (size_per_wave > MAX_WAVE_SCRATCH) return;\n\n  /*\n  Determine size class needed.\n\n  Scratch allocations come in two flavors based on how it is retired.  Small allocations may be\n  kept bound to a queue and reused by firmware.  This memory can not be reclaimed by the runtime\n  on demand so must be kept small to avoid egregious OOM conditions.  Other allocations, aka large,\n  may be used by firmware only for one dispatch and are then surrendered to the runtime.  This has\n  significant latency so we don't want to make all scratch allocations large (ie single use).\n\n  Note that the designation \"large\" is for contrast with \"small\", which must really be small\n  amounts of memory, and does not always imply a large quantity of memory is needed.  Other\n  properties of the allocation may require single use and so qualify the allocation or use as\n  \"large\".\n\n  Here we decide on the boundaries for small scratch allocations.  Both the largest small single\n  allocation and the maximum amount of memory bound by small allocations are limited.  Additionally\n  some legacy devices do not support large scratch.\n\n  For small scratch we must allocate enough memory for every physical scratch slot.\n  For large scratch compute the minimum memory needed to run the dispatch without limiting\n  occupancy.\n  Limit total bound small scratch allocations to 1/8th of scratch pool and 1/4 of that for a single\n  allocation.\n  */\n  bool large;\n\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n  const size_t small_limit = scratch_pool_.size() >> 3;\n  bool use_reclaim = true;\n\n  large = (scratch.main_size > scratch.use_once_limit) ||\n          (!AsyncScratchReclaimEnabled() &&\n            ((scratch_pool_.size() - scratch_pool_.remaining() - scratch_cache_.free_bytes() +\n             scratch.main_size) > small_limit));\n\n  if ((isa_->GetMajorVersion() < 8) ||\n      core::Runtime::runtime_singleton_->flag().no_scratch_reclaim()) {\n    large = false;\n    use_reclaim = false;\n  }\n\n  // If large is selected then the scratch will not be retained.\n  // In that case allocate the minimum necessary for the dispatch since we don't need all slots.\n  if (large) scratch.main_size = scratch.dispatch_size;\n\n  // Ensure mapping will be in whole pages.\n  scratch.main_size = AlignUp(scratch.main_size, 4096);\n\n  /*\n  Sequence of attempts is:\n    check cache\n    attempt a new allocation\n    trim unused blocks from cache\n    attempt a new allocation\n    check cache for sufficient used block, steal and wait (not implemented)\n    trim used blocks from cache, evaluate retry\n    reduce occupancy\n  */\n\n  // Lambda called in place.\n  // Used to allow exit from nested loops.\n  [&]() {\n    // Check scratch cache\n    scratch.large = large;\n    if (scratch_cache_.allocMain(scratch)) return;\n\n    // Attempt new allocation.\n    for (int i = 0; i < 3; i++) {\n      if (large)\n        scratch.main_queue_base = scratch_pool_.alloc_high(scratch.main_size);\n      else\n        scratch.main_queue_base = scratch_pool_.alloc(scratch.main_size);\n\n      scratch.large = large | (scratch.main_queue_base > scratch_pool_.high_split());\n      assert(((!scratch.large) | use_reclaim) && \"Large scratch used with reclaim disabled.\");\n\n      if (scratch.main_queue_base != nullptr) {\n        HSAuint64 alternate_va;\n        if ((profile_ == HSA_PROFILE_FULL) ||\n            (driver().MakeMemoryResident(scratch.main_queue_base, scratch.main_size,\n                                         &alternate_va) == HSA_STATUS_SUCCESS)) {\n          if (scratch.large) scratch_used_large_ += scratch.main_size;\n          scratch_cache_.insertMain(scratch);\n          return;\n        }\n      }\n\n      // Scratch request failed allocation or mapping.\n      scratch_pool_.free(scratch.main_queue_base);\n      scratch.main_queue_base = nullptr;\n\n      // Release cached scratch and retry.\n      // First iteration trims unused blocks, second trims all. 3rd uses reserved memory\n      switch (i) {\n        case 0:\n          scratch_cache_.trim(false);\n          break;\n        case 1:\n          scratch_cache_.trim(true);\n          break;\n        case 2:\n          if (scratch_cache_.use_reserved(scratch)) return;\n      }\n    }\n\n    // Retry if large may yield needed space.\n    if (scratch_used_large_ != 0) {\n      if (AddScratchNotifier(scratch.queue_retry, 0x8000000000000000ull)) scratch.retry = true;\n      return;\n    }\n\n    // Fail scratch allocation if reducing occupancy is disabled.\n    if (scratch.cooperative || (!use_reclaim) ||\n        core::Runtime::runtime_singleton_->flag().no_scratch_thread_limiter())\n      return;\n\n    // Attempt to trim the maximum number of concurrent waves to allow scratch to fit.\n    if (core::Runtime::runtime_singleton_->flag().enable_queue_fault_message())\n      debug_print(\"Failed to map requested scratch (%ld) - reducing queue occupancy.\\n\",\n                  scratch.main_size);\n    const uint64_t num_cus = properties_.NumFComputeCores / properties_.NumSIMDPerCU;\n    const uint64_t se_per_xcc = properties_.NumShaderBanks / properties_.NumXcc;\n\n    const uint64_t total_waves = scratch.main_size / size_per_wave;\n    uint64_t waves_per_cu = AlignUp(total_waves / num_cus, scratch.main_waves_per_group);\n\n    while (waves_per_cu != 0) {\n      size_t size = waves_per_cu * num_cus * size_per_wave;\n      void* base = scratch_pool_.alloc_high(size);\n      HSAuint64 alternate_va;\n      if ((base != nullptr) &&\n          ((profile_ == HSA_PROFILE_FULL) ||\n           (driver().MakeMemoryResident(base, size, &alternate_va) == HSA_STATUS_SUCCESS))) {\n        // Scratch allocated and either full profile or map succeeded.\n        scratch.main_queue_base = base;\n        scratch.main_size = size;\n        scratch.large = true;\n        scratch_used_large_ += scratch.main_size;\n        scratch_cache_.insertMain(scratch);\n        if (core::Runtime::runtime_singleton_->flag().enable_queue_fault_message())\n          debug_print(\"  %ld scratch mapped, %.2f%% occupancy.\\n\", scratch.main_size,\n                      float(waves_per_cu * num_cus) / scratch.dispatch_slots * 100.0f);\n        return;\n      }\n      scratch_pool_.free(base);\n\n      // Wave count must be divisible by #SEs in an XCC. If occupancy must be reduced\n      // such that waves_per_cu < waves_per_group, continue reducing by #SEs per XCC\n      // (only allowed if waves_per_group is a multiple #SEs per XCC).\n      waves_per_cu -= (waves_per_cu <= scratch.main_waves_per_group &&\n                       se_per_xcc < scratch.main_waves_per_group &&\n                       scratch.main_waves_per_group % se_per_xcc == 0)\n                       ? se_per_xcc\n                       : scratch.main_waves_per_group;\n    }\n\n    // Failed to allocate minimal scratch\n    assert(scratch.main_queue_base == nullptr && \"bad scratch data\");\n    if (core::Runtime::runtime_singleton_->flag().enable_queue_fault_message())\n      debug_print(\"  Could not allocate scratch for one wave per CU.\\n\");\n    return;\n  }();\n\n  scratch.main_queue_process_offset = need_queue_scratch_base\n      ? uintptr_t(scratch.main_queue_base)\n      : uintptr_t(scratch.main_queue_base) - uintptr_t(scratch_pool_.base());\n}\n\n/* Should be called with scratch_lock_ */\nvoid GpuAgent::ReleaseQueueMainScratch(ScratchInfo& scratch) {\n  assert(scratch.main_queue_base);\n\n  scratch_cache_.freeMain(scratch);\n  scratch.main_queue_base = nullptr;\n}\n\nvoid GpuAgent::AcquireQueueAltScratch(ScratchInfo& scratch) {\n  assert(scratch.async_reclaim && \"Acquire Alt Scratch when FW does not support it\");\n  assert(scratch.alt_queue_base == nullptr &&\n         \"AcquireQueueAltScratch called while holding alt scratch.\");\n\n  // Fail scratch allocation if per wave limits are exceeded.\n  uint64_t size_per_wave = AlignUp(scratch.alt_size_per_thread * properties_.WaveFrontSize, 1024);\n  if (size_per_wave > MAX_WAVE_SCRATCH) return;\n\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n\n  // Ensure mapping will be in whole pages.\n  scratch.alt_size = AlignUp(scratch.alt_size, 4096);\n\n  /*\n  Sequence of attempts is:\n    check cache\n    attempt a new allocation\n    trim unused blocks from cache\n    attempt a new allocation\n    check cache for sufficient used block, steal and wait (not implemented)\n    trim used blocks from cache, evaluate retry\n  */\n\n  // Lambda called in place.\n  // Used to allow exit from nested loops.\n  [&]() {\n    // Check scratch cache\n    if (scratch_cache_.allocAlt(scratch)) return;\n\n    // Attempt new allocation.\n    for (int i = 0; i < 2; i++) {\n      scratch.alt_queue_base = scratch_pool_.alloc(scratch.alt_size);\n      if (scratch.alt_queue_base != nullptr) {\n        HSAuint64 alternate_va;\n        if ((profile_ == HSA_PROFILE_FULL) ||\n            (driver().MakeMemoryResident(scratch.alt_queue_base, scratch.alt_size, &alternate_va) ==\n             HSA_STATUS_SUCCESS)) {\n          scratch_cache_.insertAlt(scratch);\n          return;\n        }\n      }\n\n      // Scratch request failed allocation or mapping.\n      scratch_pool_.free(scratch.alt_queue_base);\n      scratch.alt_queue_base = nullptr;\n\n      // Release cached scratch and retry.\n      // First iteration trims unused blocks, second trims all. 3rd uses reserved memory\n      switch (i) {\n        case 0:\n          scratch_cache_.trim(false);\n          break;\n        case 1:\n          scratch_cache_.trim(true);\n          break;\n      }\n    }\n\n    if (core::Runtime::runtime_singleton_->flag().enable_queue_fault_message())\n      debug_print(\"  Could not allocate alt scratch.\\n\");\n    return;\n  }();\n\n  scratch.alt_queue_process_offset = uintptr_t(scratch.alt_queue_base);\n}\n\n/* Should be called with scratch_lock_ */\nvoid GpuAgent::ReleaseQueueAltScratch(ScratchInfo& scratch) {\n  assert(scratch.alt_queue_base);\n\n  scratch_cache_.freeAlt(scratch);\n  scratch.alt_queue_base = nullptr;\n}\n\nvoid GpuAgent::ReleaseScratch(void* base, size_t size, bool large) {\n  if (profile_ == HSA_PROFILE_BASE) {\n    if (HSA_STATUS_SUCCESS != driver().MakeMemoryUnresident(base)) {\n      assert(false && \"Unmap scratch subrange failed!\");\n    }\n  }\n  scratch_pool_.free(base);\n\n  if (large) scratch_used_large_ -= size;\n\n  // Notify waiters that additional scratch may be available.\n  for (auto notifier : scratch_notifiers_) {\n    HSA::hsa_signal_or_relaxed(notifier.first, notifier.second);\n  }\n  ClearScratchNotifiers();\n}\n\n// Go through all the AQL queues and try to release scratch memory\nvoid GpuAgent::AsyncReclaimScratchQueues() {\n  for (auto iter : aql_queues_) {\n    auto aqlQueue = static_cast<AqlQueue*>(iter);\n    aqlQueue->AsyncReclaimMainScratch();\n    aqlQueue->AsyncReclaimAltScratch();\n  }\n}\n\nhsa_status_t GpuAgent::SetAsyncScratchThresholds(size_t use_once_limit) {\n  if (use_once_limit > MaxScratchDevice()) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  scratch_limit_async_threshold_ = use_once_limit;\n\n  for (auto iter : aql_queues_) {\n    auto aqlQueue = static_cast<AqlQueue*>(iter);\n    aqlQueue->CheckScratchLimits();\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid GpuAgent::TranslateTime(core::Signal* signal, hsa_amd_profiling_dispatch_time_t& time) {\n  uint64_t start, end;\n  signal->GetRawTs(false, start, end);\n  // Order is important, we want to translate the end time first to ensure that packet duration is\n  // not impacted by clock measurement latency jitter.\n  time.end = TranslateTime(end);\n  time.start = TranslateTime(start);\n\n  if ((start == 0) || (end == 0) || (start < t0_.GPUClockCounter) || (end < t0_.GPUClockCounter))\n    debug_print(\"Signal %p time stamps may be invalid.\\n\", &signal->signal_);\n}\n\nvoid GpuAgent::TranslateTime(core::Signal* signal, hsa_amd_profiling_async_copy_time_t& time) {\n  uint64_t start, end;\n  signal->GetRawTs(true, start, end);\n  // Order is important, we want to translate the end time first to ensure that packet duration is\n  // not impacted by clock measurement latency jitter.\n  time.end = TranslateTime(end);\n  time.start = TranslateTime(start);\n\n  if ((start == 0) || (end == 0) || (start < t0_.GPUClockCounter) || (end < t0_.GPUClockCounter))\n    debug_print(\"Signal %p time stamps may be invalid.\\n\", &signal->signal_);\n}\n\n/*\nTimes during program execution are interpolated to adjust for relative clock drift.\nInterval timing may appear as ticks well before process start, leading to large errors due to\nfrequency adjustment (ie the profiling with NTP problem).  This is fixed by using a fixed frequency\nfor early times.\nIntervals larger than t0_ will be frequency adjusted.  This admits a numerical error of not more\nthan twice the frequency stability (~10^-5).\n*/\nuint64_t GpuAgent::TranslateTime(uint64_t tick) {\n  // Only allow short (error bounded) extrapolation for times during program execution.\n  // Limit errors due to relative frequency drift to ~0.5us.  Sync clocks at 16Hz.\n  const int64_t max_extrapolation = core::Runtime::runtime_singleton_->sys_clock_freq() >> 4;\n\n  ScopedAcquire<KernelMutex> lock(&t1_lock_);\n  // Limit errors due to correlated pair certainty to ~0.5us.\n  // extrapolated time < (0.5us / half clock read certainty) * delay between clock measures\n  // clock read certainty is <4us.\n  if (((t1_.GPUClockCounter - t0_.GPUClockCounter) >> 2) + t1_.GPUClockCounter < tick) SyncClocks();\n\n  // Good for ~300 yrs\n  // uint64_t sysdelta = t1_.SystemClockCounter - t0_.SystemClockCounter;\n  // uint64_t gpudelta = t1_.GPUClockCounter - t0_.GPUClockCounter;\n  // int64_t offtick = int64_t(tick - t1_.GPUClockCounter);\n  //__int128 num = __int128(sysdelta)*__int128(offtick) +\n  //__int128(gpudelta)*__int128(t1_.SystemClockCounter);\n  //__int128 sysLarge = num / __int128(gpudelta);\n  // return sysLarge;\n\n  // Good for ~3.5 months.\n  uint64_t system_tick = 0;\n  int64_t elapsed = 0;\n  double ratio;\n\n  // Valid ticks only need at most one SyncClocks.\n  for (int i = 0; i < 2; i++) {\n    ratio = double(t1_.SystemClockCounter - t0_.SystemClockCounter) /\n        double(t1_.GPUClockCounter - t0_.GPUClockCounter);\n    elapsed = int64_t(ratio * double(int64_t(tick - t1_.GPUClockCounter)));\n\n    // Skip clock sync if under the extrapolation limit.\n    if (elapsed < max_extrapolation) break;\n    SyncClocks();\n  }\n\n  system_tick = uint64_t(elapsed) + t1_.SystemClockCounter;\n\n  // tick predates HSA startup - extrapolate with fixed clock ratio\n  if (tick < t0_.GPUClockCounter) {\n    if (historical_clock_ratio_ == 0.0) historical_clock_ratio_ = ratio;\n    system_tick = uint64_t(historical_clock_ratio_ * double(int64_t(tick - t0_.GPUClockCounter))) +\n        t0_.SystemClockCounter;\n  }\n\n  return system_tick;\n}\n\n/* This function is deprecated */\nbool GpuAgent::current_coherency_type(hsa_amd_coherency_type_t type) {\n  current_coherency_type_ = type;\n  return true;\n}\n\nuint16_t GpuAgent::GetMicrocodeVersion() const {\n  return (properties_.EngineId.ui32.uCode);\n}\n\nuint16_t GpuAgent::GetSdmaMicrocodeVersion() const {\n  return (properties_.uCodeEngineVersions.uCodeSDMA);\n}\n\nvoid GpuAgent::SyncClocks() {\n  hsa_status_t err = driver().GetClockCounters(node_id(), &t1_);\n  assert(err == HSA_STATUS_SUCCESS && \"hsaGetClockCounters error\");\n}\n\nhsa_status_t GpuAgent::UpdateTrapHandlerWithPCS(pcs_sampling_data_t* pcs_hosttrap_buffers, pcs_sampling_data_t* pcs_stochastic_buffers) {\n  // Assemble the trap handler source code.\n  void* tma_addr = nullptr;\n  uint64_t tma_size = 0;\n\n  assert(core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging);\n\n  AssembleShader(\"TrapHandlerKfdExceptions\", AssembleTarget::ISA, trap_code_buf_,\n                 trap_code_buf_size_);\n\n  /* pcs_hosttrap_buffers and pcs_stochastic_buffers are NULL until PC sampling is enabled */\n  if (pcs_hosttrap_buffers || pcs_stochastic_buffers) {\n    // ON non-large BAR systems, we cannot access device memory so we create a host copy\n    // and then do a DmaCopy to device memory\n    void* tma_region_host = (uint64_t*)system_allocator()(2 * sizeof(uint64_t), 0x1000, 0);\n    if (tma_region_host == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    MAKE_SCOPE_GUARD([&]() { system_deallocator()(tma_region_host); });\n\n    ((uint64_t*)tma_region_host)[0] = (uint64_t)pcs_hosttrap_buffers;\n    ((uint64_t*)tma_region_host)[1] = (uint64_t)pcs_stochastic_buffers;\n\n    if (!trap_handler_tma_region_) {\n      trap_handler_tma_region_ = (uint64_t*)finegrain_allocator()(2 * sizeof(uint64_t), 0);\n      if (trap_handler_tma_region_ == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n      // NearestCpuAgent owns pool returned system_allocator()\n      auto cpuAgent = GetNearestCpuAgent()->public_handle();\n\n      hsa_status_t ret =\n          AMD::hsa_amd_agents_allow_access(1, &cpuAgent, NULL, trap_handler_tma_region_);\n      assert(ret == HSA_STATUS_SUCCESS);\n    }\n\n    /* On non-large BAR systems, we may not be able to access device memory, so do a DmaCopy */\n    if (DmaCopy(trap_handler_tma_region_, tma_region_host, 2 * sizeof(uint64_t)) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n\n    tma_size = 2 * sizeof(uint64_t);\n    tma_addr = trap_handler_tma_region_;\n  } else if (trap_handler_tma_region_) {\n    finegrain_deallocator()(trap_handler_tma_region_);\n    trap_handler_tma_region_ = NULL;\n  }\n\n  // Bind the trap handler to this node.\n  return driver().SetTrapHandler(node_id(), trap_code_buf_, trap_code_buf_size_, tma_addr,\n                                 tma_size);\n}\n\nvoid GpuAgent::BindTrapHandler() {\n  if (isa_->GetMajorVersion() == 7) {\n    // No trap handler support on Gfx7, soft error.\n    return;\n  }\n\n  // Assemble the trap handler source code.\n  void* tma_addr = nullptr;\n  uint64_t tma_size = 0;\n\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging) {\n    AssembleShader(\"TrapHandlerKfdExceptions\", AssembleTarget::ISA, trap_code_buf_,\n                   trap_code_buf_size_);\n  } else {\n    if (isa_->GetMajorVersion() >= 11 ||\n       (isa_->GetMajorVersion() == 9 &&\n        (isa_->GetMinorVersion() == 4 || isa_->GetMinorVersion() == 5))) {\n      // No trap handler support without exception handling, soft error.\n      return;\n    }\n\n    AssembleShader(\"TrapHandler\", AssembleTarget::ISA, trap_code_buf_, trap_code_buf_size_);\n\n    // Make an empty map from doorbell index to queue.\n    // The trap handler uses this to retrieve a wave's amd_queue_v2_t*.\n    auto doorbell_queue_map_size = MAX_NUM_DOORBELLS * sizeof(amd_queue_v2_t*);\n\n    doorbell_queue_map_ = (amd_queue_v2_t**)system_allocator()(doorbell_queue_map_size, 0x1000, 0);\n    assert(doorbell_queue_map_ != NULL && \"Doorbell queue map allocation failed\");\n\n    memset(doorbell_queue_map_, 0, doorbell_queue_map_size);\n\n    tma_addr = doorbell_queue_map_;\n    tma_size = doorbell_queue_map_size;\n  }\n\n  // Bind the trap handler to this node.\n  hsa_status_t err =\n      driver().SetTrapHandler(node_id(), trap_code_buf_, trap_code_buf_size_, tma_addr, tma_size);\n  assert(err == HSA_STATUS_SUCCESS && \"SetTrapHandler() failed\");\n}\n\nvoid GpuAgent::InvalidateCodeCaches(void *ptr, size_t size) {\n  // Check for microcode cache invalidation support.\n  // This is deprecated in later microcode builds.\n  if (isa_->GetMajorVersion() == 7) {\n    if (properties_.EngineId.ui32.uCode < 420) {\n      // Microcode is handling code cache invalidation.\n      return;\n    }\n  } else if (isa_->GetMajorVersion() == 8 && isa_->GetMinorVersion() == 0) {\n    if (properties_.EngineId.ui32.uCode < 685) {\n      // Microcode is handling code cache invalidation.\n      return;\n    }\n  } else if (isa_->GetMajorVersion() > 12) {\n    assert(false && \"Code cache invalidation not implemented for this agent\");\n  }\n\n  // Invalidate caches which may hold lines of code object allocation.\n  uint32_t cache_inv[8] = {0};\n  uint32_t cache_inv_size_dw;\n\n  if (isa_->GetMajorVersion() < 10) {\n      cache_inv[1] = PM4_ACQUIRE_MEM_DW1_COHER_CNTL(\n          PM4_ACQUIRE_MEM_COHER_CNTL_SH_ICACHE_ACTION_ENA |\n          PM4_ACQUIRE_MEM_COHER_CNTL_SH_KCACHE_ACTION_ENA |\n          PM4_ACQUIRE_MEM_COHER_CNTL_TC_ACTION_ENA |\n          PM4_ACQUIRE_MEM_COHER_CNTL_TC_WB_ACTION_ENA);\n\n      cache_inv_size_dw = 7;\n  } else {\n      cache_inv[7] = PM4_ACQUIRE_MEM_DW7_GCR_CNTL(\n          PM4_ACQUIRE_MEM_GCR_CNTL_GLI_INV(1) |\n          PM4_ACQUIRE_MEM_GCR_CNTL_GLK_INV |\n          PM4_ACQUIRE_MEM_GCR_CNTL_GLV_INV |\n          PM4_ACQUIRE_MEM_GCR_CNTL_GL1_INV |\n          PM4_ACQUIRE_MEM_GCR_CNTL_GL2_INV);\n\n      cache_inv_size_dw = 8;\n  }\n\n  cache_inv[0] = PM4_HDR(PM4_HDR_IT_OPCODE_ACQUIRE_MEM, cache_inv_size_dw,\n             isa_->GetMajorVersion());\n\n  if (ptr) {\n    size_t size_granule = (size + 0xFF) >> 8;\n    cache_inv[2] = PM4_ACQUIRE_MEM_DW2_COHER_SIZE(size_granule);\n    cache_inv[3] = PM4_ACQUIRE_MEM_DW3_COHER_SIZE_HI(size_granule >> 32);\n    cache_inv[4] = PM4_ACQUIRE_MEM_DW4_COHER_BASE((uint64_t)ptr);\n    cache_inv[5] = PM4_ACQUIRE_MEM_DW4_COHER_BASE_HI((uint64_t)ptr);\n  } else {\n    cache_inv[2] = PM4_ACQUIRE_MEM_DW2_COHER_SIZE(0xFFFFFFFF);\n    cache_inv[3] = PM4_ACQUIRE_MEM_DW3_COHER_SIZE_HI(0xFF);\n  }\n\n  // Submit the command to the utility queue and wait for it to complete.\n  queues_[QueueUtility]->ExecutePM4(cache_inv, cache_inv_size_dw * sizeof(uint32_t));\n}\n\nlazy_ptr<core::Blit>& GpuAgent::GetBlitObject(uint32_t engine_offset) {\n  sdma_blit_used_mask_ |= 1 << engine_offset;\n  return blits_[engine_offset];\n}\n\nlazy_ptr<core::Blit>& GpuAgent::GetXgmiBlit(const core::Agent& dst_agent) {\n  // Determine if destination is a member xgmi peers list\n  uint32_t xgmi_engine_cnt = properties_.NumSdmaXgmiEngines;\n  assert((xgmi_engine_cnt > 0) && (\"Illegal condition, should not happen\"));\n\n  ScopedAcquire<KernelMutex> lock(&xgmi_peer_list_lock_);\n\n  for (uint32_t idx = 0; idx < xgmi_peer_list_.size(); idx++) {\n    uint64_t dst_handle = dst_agent.public_handle().handle;\n    uint64_t peer_handle = xgmi_peer_list_[idx]->public_handle().handle;\n    if (peer_handle == dst_handle) {\n      return blits_[(idx % xgmi_engine_cnt) + DefaultBlitCount];\n    }\n  }\n\n  // Add agent to the xGMI neighbours list\n  xgmi_peer_list_.push_back(&dst_agent);\n  return GetBlitObject(((xgmi_peer_list_.size() - 1) % xgmi_engine_cnt) + DefaultBlitCount);\n}\n\nlazy_ptr<core::Blit>& GpuAgent::GetPcieBlit(const core::Agent& dst_agent,\n                                            const core::Agent& src_agent) {\n  bool is_h2d = (src_agent.device_type() == core::Agent::kAmdCpuDevice &&\n                 dst_agent.device_type() == core::Agent::kAmdGpuDevice);\n\n  lazy_ptr<core::Blit>& blit = GetBlitObject(is_h2d ? BlitHostToDev : BlitDevToHost);\n  return blit;\n}\n\nlazy_ptr<core::Blit>& GpuAgent::GetBlitObject(const core::Agent& dst_agent,\n                                              const core::Agent& src_agent,\n                                              const size_t size) {\n  // At this point it is guaranteed that one of\n  // the two devices is a GPU, potentially both\n  assert(((src_agent.device_type() == core::Agent::kAmdGpuDevice) ||\n          (dst_agent.device_type() == core::Agent::kAmdGpuDevice)) &&\n         (\"Both devices are CPU agents which is not expected\"));\n\n  // Determine if Src and Dst devices are same and are the copying device\n  // Such a copy is in the device local memory, which can only be saturated by a blit kernel.\n  if ((src_agent.public_handle().handle) == (dst_agent.public_handle().handle) &&\n      (dst_agent.public_handle().handle == public_handle_.handle)) {\n    // If the copy is very small then cache flush overheads can dominate.\n    // Choose a (potentially) SDMA enabled engine to avoid cache flushing.\n    if (size < core::Runtime::runtime_singleton_->flag().force_sdma_size()) {\n      return GetBlitObject(BlitDevToHost);\n    }\n    return blits_[BlitDevToDev];\n  }\n\n  if (core::Runtime::runtime_singleton_->flag().enable_peer_sdma() == Flag::SDMA_DISABLE\n      && src_agent.device_type() == core::Agent::kAmdGpuDevice\n      && dst_agent.device_type() == core::Agent::kAmdGpuDevice) {\n      return blits_[BlitDevToDev];\n  }\n\n  // Acquire Hive Id of Src and Dst devices - ignore hive id for CPU devices.\n  // CPU-GPU connections should always use the host (aka pcie) facing SDMA engines, even if the\n  // connection is XGMI.\n  uint64_t src_hive_id =\n      (src_agent.device_type() == core::Agent::kAmdGpuDevice) ? src_agent.HiveId() : 0;\n  uint64_t dst_hive_id =\n      (dst_agent.device_type() == core::Agent::kAmdGpuDevice) ? dst_agent.HiveId() : 0;\n\n  // Bind to a PCIe facing Blit object if the two\n  // devices have different Hive Ids. This can occur\n  // for following scenarios:\n  //\n  //  Neither device claims membership in a Hive\n  //   srcId = 0 <-> dstId = 0;\n  //\n  //  Src device claims membership in a Hive\n  //   srcId = 0x1926 <-> dstId = 0;\n  //\n  //  Dst device claims membership in a Hive\n  //   srcId = 0 <-> dstId = 0x1123;\n  //\n  //  Both device claims membership in a Hive\n  //  and the  Hives are different\n  //   srcId = 0x1926 <-> dstId = 0x1123;\n  //\n  if ((dst_hive_id != src_hive_id) || (dst_hive_id == 0)) {\n    return GetPcieBlit(dst_agent, src_agent);\n  }\n\n  // Accommodates platforms where devices have xGMI\n  // links but without sdmaXgmiEngines e.g. Vega 20\n  if (properties_.NumSdmaXgmiEngines == 0) {\n    return GetPcieBlit(dst_agent, src_agent);\n  }\n\n  return GetXgmiBlit(dst_agent);\n}\n\nvoid GpuAgent::Trim() {\n  Agent::Trim();\n  AsyncReclaimScratchQueues();\n  ScopedAcquire<KernelMutex> lock(&scratch_lock_);\n  scratch_cache_.trim(false);\n}\n\nvoid GpuAgent::InitAllocators() {\n  for (auto pool : GetNearestCpuAgent()->regions()) {\n    if (pool->kernarg()) {\n      system_allocator_ = [pool](size_t size, size_t alignment,\n                                 MemoryRegion::AllocateFlags alloc_flags) -> void* {\n        assert(alignment <= 4096);\n        void* ptr = nullptr;\n        return (HSA_STATUS_SUCCESS ==\n                core::Runtime::runtime_singleton_->AllocateMemory(pool, size, alloc_flags, &ptr))\n            ? ptr\n            : nullptr;\n      };\n\n      system_deallocator_ = [](void* ptr) { core::Runtime::runtime_singleton_->FreeMemory(ptr); };\n    }\n  }\n  assert(system_allocator_ && \"Nearest NUMA node did not have a kernarg pool.\");\n\n  // Setup this GPU's fine-grain and coarse-grain allocators.\n  for (auto region : regions()) {\n    const AMD::MemoryRegion* amd_region = static_cast<const AMD::MemoryRegion*>(region);\n\n    auto region_allocator = [region](size_t size,\n                                     MemoryRegion::AllocateFlags alloc_flags) -> void* {\n      void* ptr = nullptr;\n       return (HSA_STATUS_SUCCESS ==\n               core::Runtime::runtime_singleton_->AllocateMemory(region, size, alloc_flags, &ptr))\n           ? ptr\n           : nullptr;\n    };\n\n    auto region_deallocator = [](void* ptr) { core::Runtime::runtime_singleton_->FreeMemory(ptr); };\n\n    if (amd_region->IsLocalMemory() && amd_region->fine_grain()) {\n      finegrain_allocator_ = region_allocator;\n      finegrain_deallocator_ = region_deallocator;\n    } else if (amd_region->IsLocalMemory() &&\n               !(amd_region->fine_grain() || amd_region->extended_scope_fine_grain())) {\n      coarsegrain_allocator_ = region_allocator;\n      coarsegrain_deallocator_ = region_deallocator;\n    }\n  }\n  assert(finegrain_allocator_ && \"GPU agent does not have a fine-grain allocator\");\n  assert(coarsegrain_allocator_ && \"GPU agent does not have a coarse-grain allocator\");\n}\n\ncore::Agent* GpuAgent::GetNearestCpuAgent() const {\n  core::Agent* nearCpu = nullptr;\n  uint32_t dist = -1u;\n  for (auto cpu : core::Runtime::runtime_singleton_->cpu_agents()) {\n    const core::Runtime::LinkInfo link_info =\n        core::Runtime::runtime_singleton_->GetLinkInfo(node_id(), cpu->node_id());\n    if (link_info.info.numa_distance < dist) {\n      dist = link_info.info.numa_distance;\n      nearCpu = cpu;\n    }\n  }\n  return nearCpu;\n}\n\nhsa_status_t ConvertHsaKmtPcSamplingInfoToHsa(HsaPcSamplingInfo* hsaKmtPcSampling,\n                                              hsa_ven_amd_pcs_configuration_t* hsaPcSampling) {\n  assert(hsaKmtPcSampling && \"Invalid hsaKmtPcSampling\");\n  assert(hsaPcSampling && \"Invalid hsaPcSampling\");\n\n  switch (hsaKmtPcSampling->method) {\n    case HSA_PC_SAMPLING_METHOD_KIND_HOSTTRAP_V1:\n      hsaPcSampling->method = HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1;\n      break;\n    case HSA_PC_SAMPLING_METHOD_KIND_STOCHASTIC_V1:\n      hsaPcSampling->method = HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1;\n      break;\n    default:\n      // Sampling method not supported do not return this method to the user\n      return HSA_STATUS_ERROR;\n  }\n  switch (hsaKmtPcSampling->units) {\n    case HSA_PC_SAMPLING_UNIT_INTERVAL_MICROSECONDS:\n      hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_MICRO_SECONDS;\n      break;\n    case HSA_PC_SAMPLING_UNIT_INTERVAL_CYCLES:\n      hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_CLOCK_CYCLES;\n      break;\n    case HSA_PC_SAMPLING_UNIT_INTERVAL_INSTRUCTIONS:\n      hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_INSTRUCTIONS;\n      break;\n    default:\n      // Sampling unit not supported do not return this method to the user\n      return HSA_STATUS_ERROR;\n  }\n\n  hsaPcSampling->min_interval = hsaKmtPcSampling->value_min;\n  hsaPcSampling->max_interval = hsaKmtPcSampling->value_max;\n  hsaPcSampling->flags = hsaKmtPcSampling->flags;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb,\n                                               void* cb_data) {\n   uint32_t size = 0;\n\n  if (!core::Runtime::runtime_singleton_->KfdVersion().supports_exception_debugging)\n    return HSA_STATUS_ERROR;\n\n  // First query to get size of list needed\n  hsa_status_t ret = driver().PcSamplingQueryCapabilities(node_id(), NULL, 0, &size);\n  if (ret != HSA_STATUS_SUCCESS || size == 0) return ret;\n\n  std::vector<HsaPcSamplingInfo> sampleInfoList(size);\n  ret = driver().PcSamplingQueryCapabilities(node_id(), sampleInfoList.data(),\n                                             sampleInfoList.size(), &size);\n\n  if (ret != HSA_STATUS_SUCCESS) return ret;\n\n  for (uint32_t i = 0; i < size; i++) {\n    hsa_ven_amd_pcs_configuration_t hsaPcSampling;\n    if (ConvertHsaKmtPcSamplingInfoToHsa(&sampleInfoList[i], &hsaPcSampling) == HSA_STATUS_SUCCESS\n        && cb(&hsaPcSampling, cb_data) == HSA_STATUS_INFO_BREAK)\n          return HSA_STATUS_SUCCESS;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::PcSamplingCreate(pcs::PcsRuntime::PcSamplingSession& session) {\n  hsa_status_t ret;\n  HsaPcSamplingInfo sampleInfo = {};\n  HsaPcSamplingTraceId thunkId;\n\n  // IOCTL id does not exist at the moment, so passing 0 is OK,\n  // since it will be overridden later in this function.\n  ret = PcSamplingCreateFromId(0, session);\n  if (ret != HSA_STATUS_SUCCESS) return ret;\n\n  // Obtain the sampling information from the session.\n  session.GetHsaKmtSamplingInfo(&sampleInfo);\n\n  // Pass the sampling information to the kernel driver to create PC\n  // sampling session.\n  ret = driver().PcSamplingCreate(node_id(), &sampleInfo, &thunkId);\n  if (ret != HSA_STATUS_SUCCESS) {\n    return ret;\n  }\n\n  debug_print(\"Created PC sampling session with thunkId:%d\\n\", thunkId);\n\n  session.SetThunkId(thunkId);\n\n  return ret;\n}\n\nhsa_status_t GpuAgent::PcSamplingCreateFromId(HsaPcSamplingTraceId ioctlId,\n                                              pcs::PcsRuntime::PcSamplingSession& session) {\n  // Determine the sampling method from the session\n  hsa_ven_amd_pcs_method_kind_t sampling_method = session.method();\n\n  pcs_data_t* pcs_data = nullptr;\n\n  if (sampling_method == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n  } else if (sampling_method == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n  } else {\n    // Unsupported sampling method\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Ensure only one session is active at a time for the given method\n  if (pcs_data->session)\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;  // TODO: For now, we can only have\n                                               // 1 pc sampling session at a\n                                               // time. As a final solution, we\n                                               // want to be able to support\n                                               // multiple sessions at a time.\n                                               // But this makes the\n                                               // session.HandleSampleData more\n                                               // complicated if multiple\n                                               // sessions have different buffer\n                                               // sizes.\n\n  // This is current amd_aql_queue->pm4_ib_size_b_\n  pcs_data->cmd_data_sz = 0x1000;  // 4KB\n  pcs_data->cmd_data = (uint32_t*)malloc(pcs_data->cmd_data_sz);\n  if (!pcs_data->cmd_data) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  if (HSA::hsa_signal_create(1, 0, NULL, &pcs_data->exec_pm4_signal) != HSA_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  pcs_data->old_val = (uint64_t*)system_allocator()(sizeof(uint64_t), 0x1000, 0);\n  if (!pcs_data->old_val) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  if (AMD::hsa_amd_agents_allow_access(1, &public_handle_, NULL, pcs_data->old_val))\n    return HSA_STATUS_ERROR;\n\n  // Local copy of pc sampling data - we cannot access device memory directly on non-large BAR\n  // systems\n  pcs_sampling_data_t* device_datahost =\n      (pcs_sampling_data_t*)system_allocator()(sizeof(pcs_sampling_data_t), 0x1000, 0);\n  if (!device_datahost) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  MAKE_SCOPE_GUARD([&]() { system_deallocator()(device_datahost); });\n\n  memset(device_datahost, 0, sizeof(*device_datahost));\n\n  if (AMD::hsa_amd_agents_allow_access(1, &public_handle_, NULL, device_datahost) !=\n      HSA_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  MAKE_NAMED_SCOPE_GUARD(freeResources, [&]() {\n    if (pcs_data->device_data) {\n      if (pcs_data->device_data->done_sig0.handle)\n        HSA::hsa_signal_destroy(pcs_data->device_data->done_sig0);\n      if (pcs_data->device_data->done_sig1.handle)\n        HSA::hsa_signal_destroy(pcs_data->device_data->done_sig1);\n\n      finegrain_deallocator()(pcs_data->device_data);\n    }\n    if (pcs_data->host_buffer) system_deallocator()(pcs_data->host_buffer);\n  });\n\n  // Force creating of PC Sampling queue to trigger exception early in case we exceed max availble\n  // CP queues on this agent\n  queues_[QueuePCSampling].touch();\n\n  /*\n   * When calling queue->ExecutePM4() Indirect Buffer size which is 0x1000 bytes (1024 DW).\n   * The maximum indirect buffer size we need occurs when we enqueue the\n   * WAIT_REG_MEM, DMA_COPY(s), WRITE_DATA ops:\n   * For WAIT_REG_MEM = 7 DW\n   * For each DMA_COPY = 7 DW\n   * For WRITE_DATA_CMD = 6 DW\n   *\n   * So maximum number of DMA_COPY ops is:\n   * (MAX_IB_SIZE - sizeof(WAIT_REG_MEM) - sizeof(WRITE_DATA_CMD)) / sizeof(DMA_COPY)\n   * (1024 - 7 - 6) / 7 = 144\n   *\n   * Each DMA_COPY op can transfer (1 << 26) bytes, which is 9 GB. trap_buffer_size is a 32-bit\n   * number, so the buffer must be < 4 GB. So we are not limited by Indirect Buffer size.\n   * Set current limit to 256 MB to limit device VRAM usage\n   */\n  const size_t max_trap_buffer_size =\n      core::Runtime::runtime_singleton_->flag().pc_sampling_max_device_buffer_size();\n\n  /*\n   * We use a double-buffer mechanism where there are 2 trap-buffers and 1 host-buffer\n   * Warning: This currently assumes that client latency is smaller than time to fill 1\n   * trap-buffer If latency is bigger, we have to increate host-buffer\n   *\n   * host-buffer must be >= client-buffer so that we can copy full size of client-buffer each\n   * time. To avoid having to deal with wrap-arounds, host-buffer must be a multiple of\n   * trap-buffers\n   *\n   * if client-buffer size is greater than 2x max_trap_buffer_size:\n   *    We are limited by max_trap_buffer_size.\n   *    trap-buffer = max-trap-buffer-size\n   *    host-buffer = 2*smallest size greater than client-buffer but multiple of 1 trap-buffer\n   * else:\n   *    We reduce the trap-buffers so that:\n   *    trap-buffer = half of user-buffer\n   *    host-buffer = 2*user-buffer\n   *\n   * TODO: We are currently using a temporary host-buffer so that we can increase host-buffer to\n   * factor in client latency. Using a direct-copy to the client buffer would be more efficient.\n   * Revisit this once we have empirical data of latency vs how long it takes to fill 1\n   * trap-buffer.\n   */\n\n  size_t trap_buffer_size = 0;\n  if (session.buffer_size() > 2 * max_trap_buffer_size) {\n    trap_buffer_size = max_trap_buffer_size;\n    pcs_data->host_buffer_size = 2 * AlignUp(session.buffer_size(), trap_buffer_size);\n    } else {\n      trap_buffer_size = session.buffer_size() / 2;\n      pcs_data->host_buffer_size = 2 * session.buffer_size();\n    }\n\n    pcs_data->host_buffer = (uint8_t*)system_allocator()(pcs_data->host_buffer_size, 0x1000, 0);\n    if (!pcs_data->host_buffer) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    if (AMD::hsa_amd_agents_allow_access(1, &public_handle_, NULL, pcs_data->host_buffer) !=\n        HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n\n    device_datahost->buf_size = trap_buffer_size / session.sample_size();\n\n    if (HSA::hsa_signal_create(1, 0, NULL, &device_datahost->done_sig0) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    if (HSA::hsa_signal_create(1, 0, NULL, &device_datahost->done_sig1) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    // TODO: Once we have things working and can measure\n    // latency after 2nd level trap handler decrements signals and set watermark accordingly\n    device_datahost->buf_watermark0 = 0.8 * device_datahost->buf_size;\n    device_datahost->buf_watermark1 = 0.8 * device_datahost->buf_size;\n\n    // Allocate device memory for 2nd level trap handler TMA\n    size_t deviceAllocSize = sizeof(pcs_sampling_data_t) + (2 * trap_buffer_size);\n    pcs_data->device_data = (pcs_sampling_data_t*)finegrain_allocator()(deviceAllocSize, 0);\n    if (pcs_data->device_data == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    // This cpuAgent is the owner of the system_allocator() pool\n    auto cpuAgent = GetNearestCpuAgent()->public_handle();\n    if (AMD::hsa_amd_agents_allow_access(1, &cpuAgent, NULL, pcs_data->device_data) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n\n    if (DmaCopy(pcs_data->device_data, device_datahost, sizeof(*device_datahost)) !=\n        HSA_STATUS_SUCCESS) {\n      debug_print(\"Failed to dmaCopy!\\n\");\n      return HSA_STATUS_ERROR;\n    }\n\n    uint8_t* device_buf_ptr =\n\treinterpret_cast<uint8_t*>(pcs_data->device_data) + sizeof(pcs_sampling_data_t);\n    size_t count_in_bytes = deviceAllocSize - sizeof(pcs_sampling_data_t);\n    size_t count_in_dwords = count_in_bytes / sizeof(uint32_t);\n\n    if (DmaFill(device_buf_ptr, 0, count_in_dwords) !=\n\t HSA_STATUS_SUCCESS) {\n      debug_print(\"Failed to dmaFill!\\n\");\n      return HSA_STATUS_ERROR;\n    }\n\n    pcs_data->lost_sample_count = 0;\n    pcs_data->host_buffer_wrap_pos = 0;\n    pcs_data->host_write_ptr = pcs_data->host_buffer;\n    pcs_data->host_read_ptr = pcs_data->host_write_ptr;\n\n    pcs_data->session = &session;\n\n    if (UpdateTrapHandlerWithPCS(\n            sampling_method == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1 ? pcs_data->device_data : nullptr,\n            sampling_method == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1\n                ? pcs_data->device_data\n                : nullptr) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR;\n\n    session.SetThunkId(ioctlId);\n\n    freeResources.Dismiss();\n\n    return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::PcSamplingDestroy(pcs::PcsRuntime::PcSamplingSession& session) {\n  if (PcSamplingStop(session) != HSA_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  hsa_status_t ret = driver().PcSamplingDestroy(node_id(), session.ThunkId());\n  hsa_ven_amd_pcs_method_kind_t sampling_method = session.method();\n\n  pcs_data_t* pcs_data = nullptr;\n\n  if (sampling_method == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n  } else if (sampling_method == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n  } else {\n    // Unsupported sampling method\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Mark session as inactive\n  pcs_data->session = nullptr;\n\n  free(pcs_data->cmd_data);\n  system_deallocator()(pcs_data->old_val);\n  HSA::hsa_signal_destroy(pcs_data->exec_pm4_signal);\n  HSA::hsa_signal_destroy(pcs_data->device_data->done_sig0);\n  HSA::hsa_signal_destroy(pcs_data->device_data->done_sig1);\n  finegrain_deallocator()(pcs_data->device_data);\n  system_deallocator()(pcs_data->host_buffer);\n\n  pcs_data->device_data = NULL;\n  pcs_data->host_buffer = NULL;\n  pcs_data->session = NULL;\n\n  // Update the trap handler to clear any associated device data\n  UpdateTrapHandlerWithPCS(nullptr, nullptr);\n\n  return ret;\n}\n\nhsa_status_t GpuAgent::PcSamplingStart(pcs::PcsRuntime::PcSamplingSession& session) {\n  if (session.isActive()) return HSA_STATUS_SUCCESS;\n\n\n  auto method = session.method();\n\n  pcs_data_t* pcs_data = nullptr;\n  const char* thread_name = nullptr;\n  if (method == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n    thread_name = \"PcSamplingHostTrapThread\";\n  } else if (method == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n    thread_name = \"PcSamplingStochasticThread\";\n  } else {\n    // Unsupported sampling method\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Check if a session is already active\n  if (pcs_data->session && pcs_data->session->isActive()) {\n    debug_warning(\"Already have a PC sampling session in progress!\");\n    return (hsa_status_t)HSA_STATUS_ERROR_RESOURCE_BUSY;\n  }\n\n  // Assign the new session and mark it as active\n  pcs_data->session = &session;\n  pcs_data->session->start();\n\n  // Creating thread data\n  struct ThreadData {\n    GpuAgent* agent;\n    pcs_data_t* pcs_data;\n    const char* thread_name;\n  };\n\n  auto* thread_data = new ThreadData{this, pcs_data, thread_name};\n\n  // This thread will handle all PC Sampling sessions on this agent\n  pcs_data->thread = os::CreateThread(\n      [](void* arg) -> void {\n        auto* thread_data = static_cast<ThreadData*>(arg);\n        try {\n          GpuAgent* agent = thread_data->agent;\n          pcs_data_t* pcs_data = thread_data->pcs_data;\n          const char* thread_name = thread_data->thread_name;\n\n          agent->PcSamplingThread(*pcs_data, thread_name);\n        } catch (...) {\n\t   fprintf(stdout, \"Exception caught in PcSamplingThread. Exiting the thread!\");\n        }\n\n        delete thread_data;\n      },\n      thread_data);\n\n  if (!pcs_data->thread) {\n    // if thread creation failed\n    delete thread_data;\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES,\n                             \"Failed to start PC Sampling thread.\");\n  }\n\n  // Start the sampling session in the kernel driver\n  if (driver().PcSamplingStart(node_id(), session.ThunkId()) == HSA_STATUS_SUCCESS) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  debug_print(\"Failed to start PC sampling session with thunkId:%d\\n\", session.ThunkId());\n  // Clean up if starting the session failed\n  pcs_data->session->stop();\n  os::WaitForThread(pcs_data->thread);\n  os::CloseThread(pcs_data->thread);\n  pcs_data->thread = nullptr;\n  pcs_data->session = nullptr;\n\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t GpuAgent::PcSamplingStop(pcs::PcsRuntime::PcSamplingSession& session) {\n  if (!session.isActive()) return HSA_STATUS_SUCCESS;\n\n  // Stop the session\n  session.stop();\n\n  // Stop PC sampling in the kernel driver\n  hsa_status_t ret = driver().PcSamplingStop(node_id(), session.ThunkId());\n  if (ret != HSA_STATUS_SUCCESS)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR, \"Failed to stop PC Sampling session.\");\n\n  // Determine the sampling method and corresponding data\n  pcs_data_t* pcs_data = nullptr;\n  auto method = session.method();\n\n  if (method == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n  } else if (method == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n  } else {\n    // Unsupported sampling method\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  // Wake up pcs_hosttrap_thread_ if it is waiting for data\n  HSA::hsa_signal_store_screlease(pcs_data->device_data->done_sig0, -1);\n  HSA::hsa_signal_store_screlease(pcs_data->device_data->done_sig1, -1);\n\n  // Wait for the thread to finish and clean up\n  os::WaitForThread(pcs_data->thread);\n  os::CloseThread(pcs_data->thread);\n  pcs_data->thread = nullptr;\n  pcs_data->session = nullptr;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t GpuAgent::PcSamplingFlushDeviceBuffers(\n    pcs::PcsRuntime::PcSamplingSession& session) {\n  pcs_data_t* pcs_data = nullptr;\n\n  if (session.method() == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n  } else if (session.method() == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n  } else {\n    // No sampling session active\n    return HSA_STATUS_SUCCESS;\n  }\n\n  /*\n   * Device-buffer to Host-buffer to User-Buffer copy logic\n   *\n   * Device-buffer = buffer written by 2nd level trap handler\n   * Host-buffer = buffer inside ROCr\n   * User-buffer = Session buffer size specified in PCSamplingSessionCreate\n   *\n   * Conditions for the buffer sizes:\n   * Host buffer is at least 2 times bigger than device buffer and Host buffer\n   * is also at least 2 times bigger than User-Buffer.\n   *\n   * Key:\n   * Device-Buffer[==--][----] : Device-Buffer#1 has size 4*N, and is half-full\n   *                             Device-Buffer#2 has size 4*N and is empty\n   *\n   * Host-Buffer[=---------] : Host Buffer has size 10*N and is filled with N.\n   *\n   * N will vary based on the User-buffer size, this example is to show the\n   * relative sizes between each copy.\n   *\n   * 1. Initial state\n   *    - User has created a new session with buffer size = 7*N\n   *\n   *    Device-Buffer[---][---]\n   *    Host-Buffer[--------------] wptr=0 rptr=0 wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   *    -- Device Buffer has size 3*N\n   *    -- Host-Buffer has size 14*N (2x User-Buffer)\n   *    -- User-Buffer has size 7*N\n   *\n   * 2. Device Buffer#1 hits watermark\n   *    State at beginning:\n   *    Device-Buffer[===][---]\n   *    Host-Buffer[--------------]\n   *    User-Buffer[-------]\n   *\n   *    -- Copy 3*N from Device-Buffer#1 to Host-Buffer\n   *    -- In the meantime, 2nd level trap handler is writing to Device-Buffer#2\n   *    -- We do not have enough data to fill User-Buffer\n   *\n   *    State at end:\n   *    Device-Buffer[---][=--]\n   *    Host-Buffer[===-----------] wptr=3 rptr=0, wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   * 3. Device Buffer#2 hits watermark\n   *    State at beginning:\n   *    Device-Buffer[---][===]\n   *    Host-Buffer[===-----------]\n   *    User-Buffer[-------]\n   *\n   *    -- Copy 3*N from Device-Buffer#2 to Host-Buffer\n   *    -- In the meantime, 2nd level trap handler is writing to Device-Buffer#1\n   *    -- We do not have enough data to fill User-Buffer\n   *\n   *    State at end:\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[======--------] wptr=6 rptr=0 wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   * 4. Device Buffer#1 hits watermark\n   *    State at beginning:\n   *    Device-Buffer[---][===]\n   *    Host-Buffer[======--------]\n   *    User-Buffer[-------]\n   *\n   *    -- Copy 3*N from Device-Buffer#2 to Host-Buffer\n   *    -- In the meantime, 2nd level trap handler is writing to Device-Buffer#1\n   *\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[=========-----]\n   *    User-Buffer[-------]\n   *\n   *    -- We have enough data to fill User-Buffer. Callback user data-ready to\n   *    -- copy 7*N to user.\n   *\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[-------==-----]\n   *    User-Buffer[=======]\n   *\n   *    -- User processes User-Buffer\n   *\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[-------==-----] wptr=9 rptr=7 wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   * 6. Device Buffer#1 hits watermark\n   *    State at end:\n   *    Device-Buffer[---][=--]\n   *    Host-Buffer[-------=====--] wptr=12 rptr=7 wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   * 7. Device Buffer#2 hits watermark\n   *    State at beginning:\n   *    Device-Buffer[---][===]\n   *    Host-Buffer[-------=====--] wptr=12 rptr=7 wrap_pos=0\n   *    User-Buffer[-------]\n   *\n   *    -- We do not have enough space after wptr. The CP-DMA copy\n   *    -- can only copy a contiguous range, so copy to the\n   *    -- beginning of Host-Buffer and set wrap_pos\n   *\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[===----=====--] wptr=3 rptr=7 wrap_pos=12\n   *    User-Buffer[-------]\n   *\n   *    -- We have enough data to fill User-Buffer. Callback user data-ready to\n   *    -- copy 7*N to user. We copy the tail end (index 7-12) of Host-Buffer\n   *    -- before copying the beginning of Host-Buffer (index 0-2).\n   *\n   *    Device-Buffer[=--][---]\n   *    Host-Buffer[--=-----------] wptr=3 rptr=2 wrap_pos=0\n   *    User-Buffer[=======]\n   *\n   *     -- User processes User-Buffer\n   *\n   * 8. Device Buffer#1 hits watermark\n   *    State at end:\n   *    Device-Buffer[---][=--]\n   *    Host-Buffer[--====--------] wptr=6 rptr=2 wrap_pos=0\n   *    User-Buffer[-------]\n   */\n\n  uint32_t next_buffer;\n\n  uint64_t reset_write_val;\n  uint32_t to_copy = 0, copy_bytes;\n\n  const uint32_t atomic_ex_cmd_sz = 9;\n  const uint32_t wait_reg_mem_cmd_sz = 7;\n  const uint32_t acquire_mem_cmd_sz = 8;\n  const uint32_t dma_data_cmd_sz = 7;\n  const uint32_t copy_data_cmd_sz = 6;\n  const uint32_t write_data_cmd_sz = 5;\n  const uint32_t pred_exec_cmd_sz = 2;\n\n  uint64_t buf_write_val;\n  uint64_t buf_written_val[2];\n  size_t buf_offset;\n  uint8_t* buffer[2];\n  size_t buf_size;\n\n  uint32_t& which_buffer = pcs_data->which_buffer;\n  uint32_t* cmd_data = pcs_data->cmd_data;\n  size_t cmd_data_sz = pcs_data->cmd_data_sz;\n  uint64_t* old_val = pcs_data->old_val;\n  hsa_signal_t& exec_pm4_signal = pcs_data->exec_pm4_signal;\n\n  uint8_t* host_buffer_begin = pcs_data->host_buffer;\n  size_t& host_buffer_size = pcs_data->host_buffer_size;\n  uint8_t*& host_write_ptr = pcs_data->host_write_ptr;\n  uint8_t* host_buffer_end = host_buffer_begin + host_buffer_size;\n\n  buf_write_val = reinterpret_cast<uint64_t>(&pcs_data->device_data->buf_write_val);\n  buf_written_val[0] = reinterpret_cast<uint64_t>(&pcs_data->device_data->buf_written_val0);\n  buf_written_val[1] = reinterpret_cast<uint64_t>(&pcs_data->device_data->buf_written_val1);\n  buf_size = pcs_data->device_data->buf_size;\n\n  buf_offset =\n      offsetof(pcs_sampling_data_t, reserved1) + sizeof(((pcs_sampling_data_t*)0)->reserved1);\n\n  buffer[0] = reinterpret_cast<uint8_t*>(pcs_data->device_data) + buf_offset;\n  buffer[1] = buffer[0] + buf_size * session.sample_size();\n\n  next_buffer = (which_buffer + 1) % 2;\n  reset_write_val = (uint64_t)next_buffer << 63;\n\n  unsigned int i = 0;\n  if (properties_.NumXcc > 1) i+= pred_exec_cmd_sz;\n  memset(cmd_data, 0, cmd_data_sz);\n\n  /*\n   * ATOMIC_MEM, perform atomic_exchange\n   * We use a double-buffer mechanism so that trap handlers calls are writing to one buffer while\n   * hsa-runtime is copying data from the other buffer.\n   *\n   * 1. Atomically swap buffers on the device. Future trap handler calls will put their data into\n   *    next_buffer.\n   * 2. Return a 64-bit packed value to ROCr; the upper bit is the old buffer and can be ignored.\n   *    The lower 63 bits are how many trap handler entrances happened before the atomic swap\n   *    i.e., what value to wait for in buf_written_val to know all previous trap entries were\n   *    done.\n   */\n\n  cmd_data[i++] = PM4_HDR(PM4_HDR_IT_OPCODE_ATOMIC_MEM, atomic_ex_cmd_sz, isa_->GetMajorVersion());\n  cmd_data[i++] = PM4_ATOMIC_MEM_DW1_ATOMIC(PM4_ATOMIC_MEM_GL2_OP_ATOMIC_SWAP_RTN_64);\n  cmd_data[i++] = PM4_ATOMIC_MEM_DW2_ADDR_LO(buf_write_val);\n  cmd_data[i++] = PM4_ATOMIC_MEM_DW3_ADDR_HI((buf_write_val) >> 32);\n  cmd_data[i++] = PM4_ATOMIC_MEM_DW4_SRC_DATA_LO((uint64_t)reset_write_val);\n  cmd_data[i++] = PM4_ATOMIC_MEM_DW5_SRC_DATA_HI(((uint64_t)reset_write_val) >> 32);\n  i += 3;\n  /* copy data */\n  cmd_data[i++] = PM4_HDR(PM4_HDR_IT_OPCODE_COPY_DATA, copy_data_cmd_sz, isa_->GetMajorVersion());\n  cmd_data[i++] =\n      PM4_COPY_DATA_DW1(PM4_COPY_DATA_SRC_SEL_ATOMIC_RETURN_DATA | PM4_COPY_DATA_DST_SEL_TC_12 |\n                        PM4_COPY_DATA_COUNT_SEL | PM4_COPY_DATA_WR_CONFIRM);\n  i += 2;\n  cmd_data[i++] = PM4_COPY_DATA_DW4_DST_ADDR_LO((uint64_t)old_val);\n  cmd_data[i++] = PM4_COPY_DATA_DW5_DST_ADDR_HI(((uint64_t)old_val) >> 32);\n\n  if (properties_.NumXcc > 1) {\n    cmd_data[0] =\n      PM4_HDR(PM4_HDR_IT_OPCODE_PRED_EXEC, pred_exec_cmd_sz, isa_->GetMajorVersion());\n    cmd_data[1] =\n      PM4_PRED_EXEC_DW2_EXEC_COUNT(i - pred_exec_cmd_sz) | PM4_PRED_EXEC_DW2_VIRTUALXCCID_SELECT(0x1);\n  }\n\n  HSA::hsa_signal_store_screlease(exec_pm4_signal, 1);\n\n  queues_[QueuePCSampling]->ExecutePM4(\n      cmd_data, i * sizeof(uint32_t), HSA_FENCE_SCOPE_NONE, HSA_FENCE_SCOPE_SYSTEM, &exec_pm4_signal);\n  do {\n    hsa_signal_value_t val = HSA::hsa_signal_wait_scacquire(\n        exec_pm4_signal, HSA_SIGNAL_CONDITION_LT, 1, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\n    if (val == -1) return HSA_STATUS_SUCCESS;\n    if (val == 0) break;\n  } while (true);\n\n  *old_val &= (ULLONG_MAX >> 1);\n  /* If the number of entries in old_val is larger than buf_size, then there was a buffer overflow\n   * and the 2nd level trap handler code will skip recording samples, causing lost samples\n   */\n  if (*old_val > buf_size) {\n    pcs_data->lost_sample_count = *old_val - buf_size;\n    *old_val = buf_size;\n  }\n\n  to_copy = *old_val * session.sample_size();\n\n  /* Make sure there is enough space after host_write_ptr */\n  if (host_write_ptr + to_copy >= host_buffer_end) {\n    // Need to wrap around\n    pcs_data->host_buffer_wrap_pos = host_write_ptr;\n    host_write_ptr = host_buffer_begin;\n  }\n\n  i = 0;\n  if (properties_.NumXcc > 1) i+= pred_exec_cmd_sz;\n  memset(cmd_data, 0, cmd_data_sz);\n\n  /*\n   * Do the WAIT_REG_MEM, DMA_DATA(s) and WRITE_DATA\n   *\n   * 1. Wait for all trap handlers have finished writing values to this buffer by waiting for\n   *    buf_written_val to equal to old_val.\n   * 2. Copy the values out of buffer to the host buffers.\n   * 3. Reset buf_written_val so that we start writing to beginning of this buffer on the next\n   *    buffer swap.\n   */\n\n  /* WAIT_REG_MEM, wait on buf_written_val */\n  cmd_data[i++] =\n      PM4_HDR(PM4_HDR_IT_OPCODE_WAIT_REG_MEM, wait_reg_mem_cmd_sz, isa_->GetMajorVersion());\n  cmd_data[i++] = PM4_WAIT_REG_MEM_DW1(PM4_WAIT_REG_MEM_FUNCTION_EQUAL_TO_REFERENCE |\n                                       PM4_WAIT_REG_MEM_MEM_SPACE_MEMORY_SPACE |\n                                       PM4_WAIT_REG_MEM_OPERATION_WAIT_REG_MEM);\n  cmd_data[i++] = PM4_WAIT_REG_MEM_DW2_MEM_POLL_ADDR_LO(buf_written_val[which_buffer]);\n  cmd_data[i++] = PM4_WAIT_REG_MEM_DW3_MEM_POLL_ADDR_HI((buf_written_val[which_buffer]) >> 32);\n  cmd_data[i++] = PM4_WAIT_REG_MEM_DW4_REFERENCE(*old_val);\n  cmd_data[i++] = 0xFFFFFFFF;\n  cmd_data[i++] = PM4_WAIT_REG_MEM_DW6(PM4_WAIT_REG_MEM_POLL_INTERVAL(4) |\n                                       PM4_WAIT_REG_MEM_OPTIMIZE_ACE_OFFLOAD_MODE);\n\n  // For GFX1200 and GFX1201 only - add an ACQUIRE_MEM packet to flush L2 cache before DMA.\n  // This ensures that any data written by the trap handler is visible to the DMA engine.\n  if ((isa_->GetMajorVersion() == 12) && (isa_->GetMinorVersion() == 0)) {\n    cmd_data[i++] =\n        PM4_HDR(PM4_HDR_IT_OPCODE_ACQUIRE_MEM, acquire_mem_cmd_sz, isa_->GetMajorVersion());\n    cmd_data[i++] = 0;                                // DW1: COHER_CNTL\n    cmd_data[i++] = 0;                                // DW2: COHER_SIZE\n    cmd_data[i++] = 0;                                // DW3: COHER_SIZE_HI\n    cmd_data[i++] = 0;                                // DW4: COHER_BASE_LO\n    cmd_data[i++] = 0;                                // DW5: COHER_BASE_HI\n    cmd_data[i++] = 4;                                // DW6: POLL_INTERVAL\n    cmd_data[i++] = PM4_ACQUIRE_MEM_GCR_CNTL_GL2_WB;  // DW7: GCR_CNTL (GL2_WB=1, RANGE=ALL)\n  }\n\n  uint8_t* buffer_temp = buffer[which_buffer];\n\n  for (copy_bytes = std::min(to_copy, (uint32_t)CP_DMA_DATA_TRANSFER_CNT_MAX); 0 < to_copy;\n       to_copy -= copy_bytes) {\n\n    /* DMA_DATA PACKETS, copy buffer using CPDMA */\n    cmd_data[i++] = PM4_HDR(PM4_HDR_IT_OPCODE_DMA_DATA, dma_data_cmd_sz, isa_->GetMajorVersion());\n    cmd_data[i++] = PM4_DMA_DATA_DW1(PM4_DMA_DATA_DST_SEL_DST_ADDR_USING_L2 |\n                                     PM4_DMA_DATA_SRC_SEL_SRC_ADDR_USING_L2);\n    cmd_data[i++] = PM4_DMA_DATA_DW2_SRC_ADDR_LO((uint64_t)buffer_temp);\n    cmd_data[i++] = PM4_DMA_DATA_DW3_SRC_ADDR_HI(((uint64_t)buffer_temp) >> 32);\n    cmd_data[i++] = PM4_DMA_DATA_DW4_DST_ADDR_LO((uint64_t)host_write_ptr);\n    cmd_data[i++] = PM4_DMA_DATA_DW5_DST_ADDR_HI(((uint64_t)host_write_ptr) >> 32);\n    if (copy_bytes >= to_copy) {\n      copy_bytes = to_copy;\n      cmd_data[i++] =\n          PM4_DMA_DATA_DW6(PM4_DMA_DATA_BYTE_COUNT(copy_bytes) | PM4_DMA_DATA_DIS_WC_LAST);\n    } else {\n      cmd_data[i++] = PM4_DMA_DATA_DW6(PM4_DMA_DATA_BYTE_COUNT(copy_bytes) | PM4_DMA_DATA_DIS_WC);\n    }\n    buffer_temp += copy_bytes;\n    host_write_ptr += copy_bytes;\n  }\n\n  /* WRITE_DATA, Reset buf_written_val */\n  cmd_data[i++] = PM4_HDR(PM4_HDR_IT_OPCODE_WRITE_DATA, write_data_cmd_sz, isa_->GetMajorVersion());\n  cmd_data[i++] = PM4_WRITE_DATA_DW1(PM4_WRITE_DATA_DST_SEL_TC_L2 |\n                                     PM4_WRITE_DATA_WR_CONFIRM_WAIT_CONFIRMATION);\n  cmd_data[i++] = PM4_WRITE_DATA_DW2_DST_MEM_ADDR_LO(buf_written_val[which_buffer]);\n  cmd_data[i++] = PM4_WRITE_DATA_DW3_DST_MEM_ADDR_HI((buf_written_val[which_buffer]) >> 32);\n  cmd_data[i++] = PM4_WRITE_DATA_DW4_DATA(0);\n\n  if (properties_.NumXcc > 1) {\n    cmd_data[0] =\n      PM4_HDR(PM4_HDR_IT_OPCODE_PRED_EXEC, pred_exec_cmd_sz, isa_->GetMajorVersion());\n    cmd_data[1] =\n      PM4_PRED_EXEC_DW2_EXEC_COUNT(i - pred_exec_cmd_sz) | PM4_PRED_EXEC_DW2_VIRTUALXCCID_SELECT(0x1);\n  }\n\n  HSA::hsa_signal_store_screlease(exec_pm4_signal, 1);\n  queues_[QueuePCSampling]->ExecutePM4(cmd_data, i * sizeof(uint32_t), HSA_FENCE_SCOPE_NONE,\n                                       HSA_FENCE_SCOPE_SYSTEM, &exec_pm4_signal);\n  do {\n    hsa_signal_value_t val = HSA::hsa_signal_wait_scacquire(\n        exec_pm4_signal, HSA_SIGNAL_CONDITION_LT, 1, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\n    if (val == -1) return HSA_STATUS_SUCCESS;\n    if (val == 0) break;\n  } while (true);\n\n  // save the position of next buffer\n  which_buffer = next_buffer;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid GpuAgent::PcSamplingThread(pcs_data_t& pcs_data, const char* thread_name) {\n  // TODO: Implement lost sample count\n  // TODO: Implement latency\n\n  try {\n    pcs::PcsRuntime::PcSamplingSession& session = *pcs_data.session;\n    uint32_t& which_buffer = pcs_data.which_buffer;\n\n    uint8_t* host_buffer_begin = pcs_data.host_buffer;\n    uint8_t* host_buffer_end = pcs_data.host_buffer + pcs_data.host_buffer_size;\n\n    hsa_signal_t done_sig[] = {pcs_data.device_data->done_sig0, pcs_data.device_data->done_sig1};\n\n    while (pcs_data.session->isActive()) {\n      // Wait for the signal to process the buffer\n      do {\n        hsa_signal_value_t val = HSA::hsa_signal_wait_scacquire(\n            done_sig[which_buffer], HSA_SIGNAL_CONDITION_LT, 1, UINT64_MAX, HSA_WAIT_STATE_BLOCKED);\n        if (val == -1) goto thread_exit;\n        if (val == 0) break;\n      } while (true);\n      HSA::hsa_signal_store_screlease(done_sig[which_buffer], 1);\n\n      // Lock buffer to ensure thread-safe access\n      std::lock_guard<std::mutex> lock(pcs_data.host_buffer_mutex);\n      // Flush device buffers\n      if (PcSamplingFlushDeviceBuffers(session) != HSA_STATUS_SUCCESS)\n\t    goto thread_exit;\n\n      size_t bytes_before_wrap;\n      size_t bytes_after_wrap;\n\n      assert(pcs_data.host_read_ptr >= host_buffer_begin && pcs_data.host_read_ptr < host_buffer_end);\n      assert(pcs_data.host_write_ptr >= host_buffer_begin && pcs_data.host_write_ptr < host_buffer_end);\n      assert(pcs_data.host_buffer_wrap_pos ? (pcs_data.host_read_ptr > pcs_data.host_write_ptr)\n                                           : (pcs_data.host_read_ptr <= pcs_data.host_write_ptr));\n\n      if (pcs_data.host_buffer_wrap_pos) {\n        assert(pcs_data.host_buffer_wrap_pos <= host_buffer_end &&\n               pcs_data.host_buffer_wrap_pos > host_buffer_begin);\n        assert(pcs_data.host_read_ptr <= pcs_data.host_buffer_wrap_pos);\n\n        // Wrapped around\n        bytes_before_wrap = pcs_data.host_buffer_wrap_pos - pcs_data.host_read_ptr;\n        bytes_after_wrap = pcs_data.host_write_ptr - host_buffer_begin;\n\n        while (bytes_before_wrap >= session.buffer_size()) {\n          session.HandleSampleData(pcs_data.host_read_ptr, session.buffer_size(), nullptr, 0,\n                                   pcs_data.lost_sample_count);\n          pcs_data.host_read_ptr += session.buffer_size();\n          bytes_before_wrap = pcs_data.host_buffer_wrap_pos - pcs_data.host_read_ptr;\n          pcs_data.lost_sample_count = 0;\n        }\n\n        if (bytes_before_wrap + bytes_after_wrap >= session.buffer_size()) {\n          session.HandleSampleData(pcs_data.host_read_ptr, bytes_before_wrap, host_buffer_begin,\n                                   (session.buffer_size() - bytes_before_wrap), 0);\n          pcs_data.host_read_ptr = host_buffer_begin + (session.buffer_size() - bytes_before_wrap);\n          bytes_before_wrap = 0;\n          pcs_data.host_buffer_wrap_pos = 0;\n          bytes_after_wrap = pcs_data.host_write_ptr - pcs_data.host_read_ptr;\n          pcs_data.lost_sample_count = 0;\n        }\n\n        while (bytes_after_wrap >= session.buffer_size()) {\n          session.HandleSampleData(pcs_data.host_read_ptr, session.buffer_size(), nullptr, 0,\n                                   pcs_data.lost_sample_count);\n          pcs_data.host_read_ptr += session.buffer_size();\n          bytes_before_wrap = 0;\n          bytes_after_wrap = pcs_data.host_write_ptr - pcs_data.host_read_ptr;\n          pcs_data.lost_sample_count = 0;\n        }\n      } else {\n        // Handle non-wrapped buffer\n        bytes_before_wrap = pcs_data.host_write_ptr - pcs_data.host_read_ptr;\n\n        while (bytes_before_wrap >= session.buffer_size()) {\n          assert(pcs_data.host_read_ptr >= host_buffer_begin &&\n                 pcs_data.host_read_ptr + session.buffer_size() <= host_buffer_end);\n          session.HandleSampleData(pcs_data.host_read_ptr, session.buffer_size(), nullptr, 0,\n                                   pcs_data.lost_sample_count);\n          pcs_data.host_read_ptr += session.buffer_size();\n          bytes_before_wrap = pcs_data.host_write_ptr - pcs_data.host_read_ptr;\n          pcs_data.lost_sample_count = 0;\n        }\n      }\n    }\nthread_exit:\n  debug_print(\"%s::Exiting\\n\", thread_name);\n} catch (const std::exception& e) {\n  debug_print(\"Exception in %s: %s\\n\", thread_name, e.what());\n} catch (...) {\n  debug_print(\"Unknown exception in %s\\n\", thread_name);\n}\n}\n\nhsa_status_t GpuAgent::PcSamplingFlush(pcs::PcsRuntime::PcSamplingSession& session) {\n  pcs_data_t* pcs_data = nullptr;\n\n  if (session.method() == HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1) {\n    pcs_data = &pcs_hosttrap_data_;\n  } else if (session.method() == HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1) {\n    pcs_data = &pcs_stochastic_data_;\n  } else {\n    return HSA_STATUS_SUCCESS;  // Unsupported sampling method\n  }\n\n  uint8_t* host_buffer_begin = pcs_data->host_buffer;\n  uint8_t* host_buffer_end = pcs_data->host_buffer + pcs_data->host_buffer_size;\n\n  size_t bytes_before_wrap;\n  size_t bytes_after_wrap;\n\n  std::lock_guard<std::mutex> lock(pcs_data->host_buffer_mutex);\n  // Flush device buffers\n  if (PcSamplingFlushDeviceBuffers(session) != HSA_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n\n  assert(pcs_data->host_read_ptr >= host_buffer_begin && pcs_data->host_read_ptr < host_buffer_end);\n  assert(pcs_data->host_write_ptr >= host_buffer_begin &&\n         pcs_data->host_write_ptr < host_buffer_end);\n  assert(pcs_data->host_buffer_wrap_pos ? (pcs_data->host_read_ptr > pcs_data->host_write_ptr)\n                                        : (pcs_data->host_read_ptr <= pcs_data->host_write_ptr));\n\n  if (pcs_data->host_buffer_wrap_pos) {\n    assert(pcs_data->host_buffer_wrap_pos <= host_buffer_end &&\n           pcs_data->host_buffer_wrap_pos > host_buffer_begin);\n    assert(pcs_data->host_read_ptr <= pcs_data->host_buffer_wrap_pos);\n\n    // Handle wrapped-around buffer\n    bytes_before_wrap = pcs_data->host_buffer_wrap_pos - pcs_data->host_read_ptr;\n    bytes_after_wrap = pcs_data->host_write_ptr - host_buffer_begin;\n\n    while (bytes_before_wrap > 0) {\n      size_t bytes_to_copy = std::min(bytes_before_wrap, session.buffer_size());\n\n      session.HandleSampleData(pcs_data->host_read_ptr, bytes_to_copy, nullptr, 0,\n                               pcs_data->lost_sample_count);\n      pcs_data->host_read_ptr += bytes_to_copy;\n      bytes_before_wrap = pcs_data->host_buffer_wrap_pos - pcs_data->host_read_ptr;\n      pcs_data->lost_sample_count = 0;\n    }\n\n    assert(pcs_data->host_read_ptr == pcs_data->host_buffer_wrap_pos);\n    pcs_data->host_buffer_wrap_pos = 0;\n    pcs_data->host_read_ptr = host_buffer_begin;\n\n    while (bytes_after_wrap > 0) {\n      size_t bytes_to_copy = std::min(bytes_after_wrap, session.buffer_size());\n\n      session.HandleSampleData(pcs_data->host_read_ptr, bytes_to_copy, nullptr, 0,\n                               pcs_data->lost_sample_count);\n      pcs_data->host_read_ptr += bytes_to_copy;\n      bytes_after_wrap = pcs_data->host_write_ptr - pcs_data->host_read_ptr;\n      pcs_data->lost_sample_count = 0;\n    }\n  } else {\n    bytes_before_wrap = pcs_data->host_write_ptr - pcs_data->host_read_ptr;\n\n    while (bytes_before_wrap > 0) {\n      size_t bytes_to_copy = std::min(bytes_before_wrap, session.buffer_size());\n      assert(pcs_data->host_read_ptr >= host_buffer_begin &&\n             pcs_data->host_read_ptr + bytes_to_copy <= host_buffer_end);\n\n      session.HandleSampleData(pcs_data->host_read_ptr, bytes_to_copy, nullptr, 0,\n                               pcs_data->lost_sample_count);\n      pcs_data->host_read_ptr += bytes_to_copy;\n      bytes_before_wrap = pcs_data->host_write_ptr - pcs_data->host_read_ptr;\n      pcs_data->lost_sample_count = 0;\n    }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_hsa_loader.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_hsa_loader.hpp\"\n#include \"core/inc/runtime.h\"\n\n#include <assert.h>\n#include <link.h>\n#include <linux/limits.h>\n#include <sys/mman.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <cstring>\n#include <fstream>\n#include <iomanip>\n#include <sstream>\n#include <string>\n\nnamespace {\n\n#if !defined(_WIN32) && !defined(_WIN64)\nuintptr_t PAGE_SIZE_MASK{\n    [] () {\n      uintptr_t page_size = sysconf(_SC_PAGE_SIZE);\n      if (page_size == -1) {\n        page_size = 1 << 12; // Default page size to 4KiB.\n      }\n      return ~(page_size - 1);\n    } ()\n  };\n#endif\n\nstd::string EncodePathname(const char *file_path) {\n  std::ostringstream ss;\n  unsigned char c;\n\n  ss.fill('0');\n  ss << \"file://\";\n\n  while ((c = *file_path++) != '\\0') {\n    if (isalnum(c) || c == '/' || c == '-' ||\n        c == '_' || c == '.' || c == '~') {\n      ss << c;\n    } else {\n      ss << std::uppercase;\n      ss << '%' << std::hex << std::setw(2) << static_cast<int>(c);\n      ss << std::nouppercase;\n    }\n  }\n\n  return ss.str();\n}\n\nstd::string GetUriFromMemoryAddress(const void *memory, size_t size) {\n  pid_t pid = getpid();\n  std::ostringstream uri_stream;\n  uri_stream << \"memory://\" << pid\n             << \"#offset=0x\" << std::hex << (uintptr_t)memory << std::dec\n             << \"&size=\" << size;\n  return uri_stream.str();\n}\n\nstd::string GetUriFromMemoryInExecutableFile(const void *memory, size_t size) {\n#if !defined(_WIN32) && !defined(_WIN64)\n  uintptr_t address = reinterpret_cast<uintptr_t>(memory);\n  struct callback_data_s {\n    ElfW(Addr) address;\n    size_t callback_num;\n    const char *file_path;\n    size_t file_offset;\n  } callback_data{address, 0, nullptr, 0};\n\n  // Iterate the loaded shared objects program headers to see if the ELF binary\n  // is allocated in a mapped file.\n  if (dl_iterate_phdr([](struct dl_phdr_info *info, size_t size, void *ptr) -> int {\n    struct callback_data_s *callback_data = (struct callback_data_s *) ptr;\n    const ElfW(Addr) elf_address = callback_data->address - info->dlpi_addr;\n\n    int n = info->dlpi_phnum;\n    while (--n >= 0) {\n      // Check if lib name is not empty and its not a \"vdso.so\" lib,\n      // The vDSO is a special shared object file that is built into\n      // the Linux kernel. It is not a regular shared library and thus\n      // does not have all the properties of regular shared libraries.\n      // The way the vDSO is loaded and organized in memory is different\n      // from regular shared libraries and it's not guaranteed that it\n      // will have a specific segment or section. Hence its skipped.\n      if (info->dlpi_name[0] != '\\0'\n          && std::string(info->dlpi_name).find(\"vdso.so\") != std::string::npos) {\n        continue;\n      }\n\n      if (info->dlpi_phdr[n].p_type == PT_LOAD\n          && elf_address - info->dlpi_phdr[n].p_vaddr >= 0\n          && elf_address - info->dlpi_phdr[n].p_vaddr < info->dlpi_phdr[n].p_memsz) {\n        // The first callback is always the program executable.\n        if (!info->dlpi_name[0] && callback_data->callback_num == 0) {\n          static char argv0[PATH_MAX] = {0};\n          if (!argv0[0] && readlink(\"/proc/self/exe\", argv0, sizeof(argv0)) == -1)\n            return 0;\n          callback_data->file_path = argv0;\n        } else {\n          callback_data->file_path = info->dlpi_name;\n        }\n\n        callback_data->file_offset =\n            elf_address - info->dlpi_phdr[n].p_vaddr + info->dlpi_phdr[n].p_offset;\n        return 1;\n      }\n    }\n\n    ++callback_data->callback_num;\n    return 0;\n  }, &callback_data)) {\n    if (!callback_data.file_path || callback_data.file_path[0] == '\\0') {\n      return GetUriFromMemoryAddress(memory, size);\n    }\n\n    std::ostringstream uri_stream;\n    uri_stream << EncodePathname(callback_data.file_path);\n    uri_stream << \"#offset=\" << callback_data.file_offset;\n    uri_stream << \"&size=\" << size;\n    return uri_stream.str();\n  }\n#endif  // !defined(_WIN32) && !defined(_WIN64)\n  return GetUriFromMemoryAddress(memory, size);\n}\n\nstd::string GetUriFromMemoryInMmapedFile(const void *memory, size_t size) {\n#if !defined(_WIN32) && !defined(_WIN64)\n  std::ifstream proc_maps;\n  proc_maps.open(\"/proc/self/maps\", std::ifstream::in);\n  if (!proc_maps.is_open() || !proc_maps.good()) {\n    return GetUriFromMemoryAddress(memory, size);\n  }\n\n  std::string line;\n  while (std::getline(proc_maps, line)) {\n    std::stringstream tokens(line);\n\n    uintptr_t low_address, high_address;\n    char dash;\n    tokens >> std::hex >> low_address >> std::dec\n           >> dash\n           >> std::hex >> high_address >> std::dec;\n    if (dash != '-') {\n      continue;\n    }\n\n    uintptr_t address = reinterpret_cast<uintptr_t>(memory);\n    if (!(address >= low_address && (address + size) <= high_address)) {\n      continue;\n    }\n\n    std::string permissions, device, uri_file_path;\n    size_t offset;\n    uint64_t inode;\n    tokens >> permissions\n           >> std::hex >> offset >> std::dec\n           >> device\n           >> inode\n           >> uri_file_path;\n\n    if (inode == 0 || uri_file_path.empty()) {\n      return GetUriFromMemoryAddress(memory, size);\n    }\n\n    size_t uri_offset = offset + address - low_address;\n\n    bool is_complete_file = false;\n    if (uri_offset == 0) {\n      std::ifstream uri_file(uri_file_path, std::ios::binary);\n      if (uri_file) {\n        uri_file.seekg(0, std::ios::end);\n        is_complete_file = uri_file.tellg() == size;\n      }\n    }\n\n    std::ostringstream uri_stream;\n    uri_stream << EncodePathname(uri_file_path.c_str());\n    if (!is_complete_file) {\n      uri_stream << \"#offset=\" << uri_offset;\n      uri_stream << \"&size=\" << size;\n    }\n    return uri_stream.str();\n  }\n#endif  // !defined(_WIN32) && !defined(_WIN64)\n  return GetUriFromMemoryAddress(memory, size);\n}\n\nstd::string GetUriFromFile(int file_descriptor, size_t offset, size_t size,\n    bool is_complete_file, const void *memory) {\n#if !defined(_WIN32) && !defined(_WIN64)\n  std::ostringstream proc_fd_path;\n  proc_fd_path << \"/proc/self/fd/\" << file_descriptor;\n\n  char uri_file_path[PATH_MAX];\n  memset(uri_file_path, 0, PATH_MAX);\n\n  if (readlink(proc_fd_path.str().c_str(), uri_file_path, PATH_MAX) == -1) {\n    return GetUriFromMemoryAddress(memory, size);\n  }\n\n  if (uri_file_path[0] == '\\0') {\n    return GetUriFromMemoryAddress(memory, size);\n  }\n\n  std::ostringstream uri_stream;\n  uri_stream << EncodePathname(uri_file_path);\n  if (!is_complete_file) {\n    uri_stream << \"#offset=\" << offset;\n    uri_stream << \"&size=\" << size;\n  }\n  return uri_stream.str();\n#else\n  return GetUriFromMemoryAddress(memory, size);\n#endif  // !defined(_WIN32) && !defined(_WIN64)\n}\n\n}  // namespace\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace loader {\n\n/// @brief Default destructor.\nCodeObjectReaderImpl::~CodeObjectReaderImpl() {\n  if (is_mmap) {\n#if !defined(_WIN32) && !defined(_WIN64)\n    uintptr_t address = reinterpret_cast<uintptr_t>(code_object_memory);\n    uintptr_t adjusted_address = address & PAGE_SIZE_MASK;\n    size_t adjusted_size = code_object_size + (address - adjusted_address);\n    munmap(reinterpret_cast<void *>(adjusted_address), adjusted_size);\n#else\n    delete [] code_object_memory;\n#endif  // !defined(_WIN32) && !defined(_WIN64)\n  }\n}\n\nhsa_status_t CodeObjectReaderImpl::SetFile(\n    hsa_file_t _code_object_file_descriptor,\n    size_t _code_object_offset,\n    size_t _code_object_size) {\n  assert(!code_object_memory && \"Code object reader wrapper is already set\");\n\n  if (_code_object_file_descriptor == -1) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  off_t file_size = __lseek__(_code_object_file_descriptor, 0, SEEK_END);\n  if (file_size == (off_t)-1) {\n    return HSA_STATUS_ERROR_INVALID_FILE;\n  }\n  if (file_size <= _code_object_offset) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n  if (_code_object_size == 0) {\n    _code_object_size = file_size - _code_object_offset;\n  }\n  bool is_complete_file = _code_object_offset == 0 && _code_object_size == file_size;\n\n#if !defined(_WIN32) && !defined(_WIN64)\n  off_t adjusted_offset = _code_object_offset & PAGE_SIZE_MASK;\n  size_t adjusted_size = _code_object_size + (_code_object_offset - adjusted_offset);\n  void *memory = mmap(nullptr, adjusted_size, PROT_READ, MAP_PRIVATE,\n                      _code_object_file_descriptor, adjusted_offset);\n  if (memory == (void *) -1) {\n    return HSA_STATUS_ERROR_INVALID_FILE;\n  }\n  code_object_memory = reinterpret_cast<unsigned char*>(memory) +\n                        (_code_object_offset & ~PAGE_SIZE_MASK);\n  code_object_size = _code_object_size;\n  is_mmap = true;\n#else\n  if (__lseek__(_code_object_file_descriptor, 0, SEEK_SET) == (off_t)-1) {\n    return HSA_STATUS_ERROR_INVALID_FILE;\n  }\n\n  std::unique_ptr<unsigned char> memory(new unsigned char[_code_object_size]);\n  if (!memory) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  if (__read__(_code_object_file_descriptor, mmap_memory,\n                _code_object_size) != _code_object_size) {\n    return HSA_STATUS_ERROR_INVALID_FILE;\n  }\n  mmap_memory = memory.release();\n  mmap_size = _code_object_size;\n  code_object_memory = memory;\n  code_object_size = _code_object_size;\n#endif  // !defined(_WIN32) && !defined(_WIN64)\n\n  uri = GetUriFromFile(_code_object_file_descriptor, _code_object_offset,\n                        _code_object_size, is_complete_file, code_object_memory);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t CodeObjectReaderImpl::SetMemory(\n    const void *_code_object_memory,\n    size_t _code_object_size) {\n  assert(!code_object_memory && \"Code object reader wrapper is already set\");\n\n  if (!_code_object_memory || _code_object_size == 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  code_object_memory = _code_object_memory;\n  code_object_size = _code_object_size;\n\n  bool loader_enable_mmap_uri = core::Runtime::runtime_singleton_->flag().loader_enable_mmap_uri();\n  if (loader_enable_mmap_uri) {\n    uri = GetUriFromMemoryInMmapedFile(_code_object_memory, _code_object_size);\n  } else {\n    uri = GetUriFromMemoryInExecutableFile(_code_object_memory, _code_object_size);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace loader\n}  // namespace hsa\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_loader_context.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_loader_context.hpp\"\n\n#include <algorithm>\n#include <cassert>\n#include <cstring>\n\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/util/os.h\"\n\n#include <cstdlib>\n#include <utility>\n#include \"core/inc/hsa_internal.h\"\n#include \"core/util/utils.h\"\n#include \"inc/hsa_ext_amd.h\"\n\n#if defined(_WIN32) || defined(_WIN64)\n#include <windows.h>\n#else\n#include <sys/mman.h>\n#endif\n\nnamespace rocr {\nnamespace {\n\nclass SegmentMemory {\npublic:\n  virtual ~SegmentMemory() {}\n  virtual void* Address(size_t offset = 0) const = 0;\n  virtual void* HostAddress(size_t offset = 0) const = 0;\n  virtual bool Allocated() const = 0;\n  virtual bool Allocate(size_t size, size_t align, bool zero) = 0;\n  virtual bool Copy(size_t offset, const void *src, size_t size) = 0;\n  virtual void Free() = 0;\n  virtual bool Freeze() = 0;\n\nprotected:\n  SegmentMemory() {}\n\nprivate:\n  SegmentMemory(const SegmentMemory&);\n  SegmentMemory& operator=(const SegmentMemory&);\n};\n\nclass MallocedMemory final: public SegmentMemory {\npublic:\n  MallocedMemory(): SegmentMemory(), ptr_(nullptr), size_(0) {}\n  ~MallocedMemory() {}\n\n  void* Address(size_t offset = 0) const override\n    { assert(this->Allocated()); return (char*)ptr_ + offset; }\n  void* HostAddress(size_t offset = 0) const override\n    { return this->Address(offset); }\n  bool Allocated() const override\n    { return nullptr != ptr_; }\n\n  bool Allocate(size_t size, size_t align, bool zero) override;\n  bool Copy(size_t offset, const void *src, size_t size) override;\n  void Free() override;\n  bool Freeze() override;\n\nprivate:\n  MallocedMemory(const MallocedMemory&);\n  MallocedMemory& operator=(const MallocedMemory&);\n\n  void *ptr_;\n  size_t size_;\n};\n\nbool MallocedMemory::Allocate(size_t size, size_t align, bool zero)\n{\n  assert(!this->Allocated());\n  assert(0 < size);\n  assert(0 < align && 0 == (align & (align - 1)));\n  ptr_ = _aligned_malloc(size, align);\n  if (nullptr == ptr_) {\n    return false;\n  }\n  if (HSA_STATUS_SUCCESS != HSA::hsa_memory_register(ptr_, size)) {\n    _aligned_free(ptr_);\n    ptr_ = nullptr;\n    return false;\n  }\n  if (zero) {\n    memset(ptr_, 0x0, size);\n  }\n  size_ = size;\n  return true;\n}\n\nbool MallocedMemory::Copy(size_t offset, const void *src, size_t size)\n{\n  assert(this->Allocated());\n  assert(nullptr != src);\n  assert(0 < size);\n  memcpy(this->Address(offset), src, size);\n  return true;\n}\n\nvoid MallocedMemory::Free()\n{\n  assert(this->Allocated());\n  HSA::hsa_memory_deregister(ptr_, size_);\n  _aligned_free(ptr_);\n  ptr_ = nullptr;\n  size_ = 0;\n}\n\nbool MallocedMemory::Freeze()\n{\n  assert(this->Allocated());\n  return true;\n}\n\nclass MappedMemory final: public SegmentMemory {\npublic:\n  MappedMemory(): SegmentMemory(), ptr_(nullptr), size_(0) {}\n  ~MappedMemory() {}\n\n  void* Address(size_t offset = 0) const override\n    { assert(this->Allocated()); return (char*)ptr_ + offset; }\n  void* HostAddress(size_t offset = 0) const override\n    { return this->Address(offset); }\n  bool Allocated() const override\n    { return nullptr != ptr_; }\n\n  bool Allocate(size_t size, size_t align, bool zero) override;\n  bool Copy(size_t offset, const void *src, size_t size) override;\n  void Free() override;\n  bool Freeze() override;\n\nprivate:\n  MappedMemory(const MappedMemory&);\n  MappedMemory& operator=(const MappedMemory&);\n\n  void *ptr_;\n  size_t size_;\n};\n\nbool MappedMemory::Allocate(size_t size, size_t align, bool zero)\n{\n  assert(!this->Allocated());\n  assert(0 < size);\n  assert(0 < align && 0 == (align & (align - 1)));\n#if defined(_WIN32) || defined(_WIN64)\n  ptr_ = (void*)VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\n#else\n  ptr_ =\n    mmap(nullptr, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0);\n#endif // _WIN32 || _WIN64\n  if (nullptr == ptr_) {\n    return false;\n  }\n  assert(0 == ((uintptr_t)ptr_) % align);\n  if (HSA_STATUS_SUCCESS != HSA::hsa_memory_register(ptr_, size)) {\n#if defined(_WIN32) || defined(_WIN64)\n    VirtualFree(ptr_, size, MEM_DECOMMIT);\n    VirtualFree(ptr_, 0, MEM_RELEASE);\n#else\n    munmap(ptr_, size);\n#endif // _WIN32 || _WIN64\n    ptr_ = nullptr;\n    return false;\n  }\n  if (zero) {\n    memset(ptr_, 0x0, size);\n  }\n  size_ = size;\n  return true;\n}\n\nbool MappedMemory::Copy(size_t offset, const void *src, size_t size)\n{\n  assert(this->Allocated());\n  assert(nullptr != src);\n  assert(0 < size);\n  memcpy(this->Address(offset), src, size);\n  return true;\n}\n\nvoid MappedMemory::Free()\n{\n  assert(this->Allocated());\n  HSA::hsa_memory_deregister(ptr_, size_);\n#if defined(_WIN32) || defined(_WIN64)\n  VirtualFree(ptr_, size_, MEM_DECOMMIT);\n  VirtualFree(ptr_, 0, MEM_RELEASE);\n#else\n  munmap(ptr_, size_);\n#endif // _WIN32 || _WIN64\n  ptr_ = nullptr;\n  size_ = 0;\n}\n\nbool MappedMemory::Freeze()\n{\n  assert(this->Allocated());\n  return true;\n}\n\nclass RegionMemory final: public SegmentMemory {\npublic:\n static const core::MemoryRegion* AgentLocal(hsa_agent_t agent, bool is_code);\n static const core::MemoryRegion* System(bool is_code);\n\n RegionMemory(const core::MemoryRegion* region, bool is_code)\n     : SegmentMemory(),\n       region_(region),\n       ptr_(nullptr),\n       host_ptr_(nullptr),\n       size_(0),\n       is_code_(is_code) {}\n ~RegionMemory() {}\n\n void* Address(size_t offset = 0) const override {\n   assert(this->Allocated());\n   return (char*)ptr_ + offset; }\n  void* HostAddress(size_t offset = 0) const override\n    { assert(this->Allocated()); return (char*)host_ptr_ + offset; }\n  bool Allocated() const override\n    { return nullptr != ptr_; }\n\n  bool Allocate(size_t size, size_t align, bool zero) override;\n  bool Copy(size_t offset, const void *src, size_t size) override;\n  void Free() override;\n  bool Freeze() override;\n\nprivate:\n  RegionMemory(const RegionMemory&);\n  RegionMemory& operator=(const RegionMemory&);\n\n  const core::MemoryRegion* region_;\n  void *ptr_;\n  void *host_ptr_;\n  size_t size_;\n  bool is_code_;\n};\n\nconst core::MemoryRegion* RegionMemory::AgentLocal(hsa_agent_t agent, bool is_code) {\n  AMD::GpuAgent *amd_agent = (AMD::GpuAgent*)core::Agent::Convert(agent);\n  assert(amd_agent->device_type() == core::Agent::kAmdGpuDevice && \"Invalid agent type.\");\n  auto agent_local_region =\n      std::find_if(amd_agent->regions().begin(), amd_agent->regions().end(),\n                   [&](const core::MemoryRegion* region) {\n                     const AMD::MemoryRegion* amd_region = (const AMD::MemoryRegion*)region;\n                     return amd_region->IsLocalMemory() && (!amd_region->fine_grain());\n                   });\n  return agent_local_region == amd_agent->regions().end() ? nullptr : *agent_local_region;\n}\n\nconst core::MemoryRegion* RegionMemory::System(bool is_code) {\n  if (is_code)\n    return core::Runtime::runtime_singleton_->system_regions_coarse()[0];\n  else\n    return core::Runtime::runtime_singleton_->system_regions_fine()[0];\n}\n\nbool RegionMemory::Allocate(size_t size, size_t align, bool zero) {\n  assert(!this->Allocated());\n  assert(0 < size);\n  assert(0 < align && 0 == (align & (align - 1)));\n  core::MemoryRegion::AllocateFlags flags = core::MemoryRegion::AllocateNoFlags;\n  if (is_code_) flags = core::MemoryRegion::AllocateExecutable;\n  if (HSA_STATUS_SUCCESS !=\n      core::Runtime::runtime_singleton_->AllocateMemory(region_, size, flags, &ptr_)) {\n    ptr_ = nullptr;\n    return false;\n  }\n  assert(0 == ((uintptr_t)ptr_) % align);\n  if (HSA_STATUS_SUCCESS !=\n      core::Runtime::runtime_singleton_->AllocateMemory(\n          RegionMemory::System(false), size, core::MemoryRegion::AllocateNoFlags, &host_ptr_)) {\n    HSA::hsa_memory_free(ptr_);\n    ptr_ = nullptr;\n    host_ptr_ = nullptr;\n    return false;\n  }\n  if (zero) {\n    memset(host_ptr_, 0x0, size);\n  }\n  size_ = size;\n  return true;\n}\n\nbool RegionMemory::Copy(size_t offset, const void* src, size_t size) {\n  assert(this->Allocated() && nullptr != host_ptr_);\n  assert(nullptr != src);\n  assert(0 < size);\n  memcpy((char*)host_ptr_ + offset, src, size);\n  return true;\n}\n\nvoid RegionMemory::Free()\n{\n  assert(this->Allocated());\n  HSA::hsa_memory_free(ptr_);\n  if (nullptr != host_ptr_) {\n    HSA::hsa_memory_free(host_ptr_);\n  }\n  ptr_ = nullptr;\n  host_ptr_ = nullptr;\n  size_ = 0;\n}\n\nbool RegionMemory::Freeze() {\n  assert(this->Allocated() && nullptr != host_ptr_);\n\n  core::Agent* agent = region_->owner();\n\n  const size_t& code_object_dmacopy_size =\n    core::Runtime::runtime_singleton_->flag().co_dmacopy_size();\n\n  const bool isGpuDevice = (agent->device_type() == core::Agent::kAmdGpuDevice);\n  const bool isLargeBarDisabled = isGpuDevice && !reinterpret_cast<AMD::GpuAgent*>(agent)->LargeBarEnabled();\n  const bool shouldDmaCopy = isGpuDevice && (isLargeBarDisabled || size_ > code_object_dmacopy_size);\n\n  if (shouldDmaCopy) {\n      if (HSA_STATUS_SUCCESS != agent->DmaCopy(ptr_, host_ptr_, size_)) return false;\n  } else {\n      memcpy(ptr_, host_ptr_, size_);\n      if (is_code_ && isGpuDevice)\n        reinterpret_cast<AMD::GpuAgent*>(agent)->PcieWcFlush(ptr_, size_);\n  }\n\n  // Invalidate agent caches if needed\n  if (is_code_ && isGpuDevice)\n      reinterpret_cast<AMD::GpuAgent*>(agent)->InvalidateCodeCaches(ptr_, size_);\n\n  return true;\n}\n\n}  // namespace anonymous\nnamespace amd {\n\nhsa_isa_t LoaderContext::IsaFromName(const char *name) {\n  assert(name);\n\n  hsa_status_t hsa_status = HSA_STATUS_SUCCESS;\n  hsa_isa_t isa_handle;\n  isa_handle.handle = 0;\n\n  hsa_status = HSA::hsa_isa_from_name(name, &isa_handle);\n  if (HSA_STATUS_SUCCESS != hsa_status) {\n    isa_handle.handle = 0;\n    return isa_handle;\n  }\n\n  return isa_handle;\n}\n\nbool LoaderContext::IsaSupportedByAgent(hsa_agent_t agent,\n                                        hsa_isa_t code_object_isa,\n                                        unsigned codeGenericVersion) {\n  struct callBackData {\n    std::pair<hsa_isa_t, bool> comparison_data;\n    const unsigned int codeGenericV;\n  } cbData = {{code_object_isa, false}, codeGenericVersion};\n\n  auto IsIsaEquivalent = [](hsa_isa_t agent_isa_h, void *data) {\n    assert(data);\n\n    struct callBackData *inOutCB = reinterpret_cast<decltype(&cbData)>(data);\n\n    std::pair<hsa_isa_t, bool> *data_pair = &inOutCB->comparison_data;\n    const unsigned int codeGenericV = inOutCB->codeGenericV;\n\n    assert(data_pair);\n    assert(!data_pair->second);\n\n    const core::Isa *agent_isa = core::Isa::Object(agent_isa_h);\n    assert(agent_isa);\n    const core::Isa *code_object_isa = core::Isa::Object(data_pair->first);\n    assert(code_object_isa);\n\n    data_pair->second = core::Isa::IsCompatible(*code_object_isa, *agent_isa, codeGenericV);\n    return data_pair->second ? HSA_STATUS_INFO_BREAK : HSA_STATUS_SUCCESS;\n  };\n\n  hsa_status_t status = HSA::hsa_agent_iterate_isas(agent, IsIsaEquivalent, &cbData);\n  if (status != HSA_STATUS_SUCCESS && status != HSA_STATUS_INFO_BREAK) {\n    return false;\n  }\n  return cbData.comparison_data.second;\n}\n\nvoid* LoaderContext::SegmentAlloc(amdgpu_hsa_elf_segment_t segment,\n                                  hsa_agent_t agent,\n                                  size_t size,\n                                  size_t align,\n                                  bool zero)\n{\n  assert(0 < size);\n  assert(0 < align && 0 == (align & (align - 1)));\n\n  hsa_profile_t agent_profile;\n  if (HSA_STATUS_SUCCESS !=\n      HSA::hsa_agent_get_info(agent, HSA_AGENT_INFO_PROFILE, &agent_profile)) {\n    return nullptr;\n  }\n\n  SegmentMemory *mem = nullptr;\n  switch (segment) {\n  case AMDGPU_HSA_SEGMENT_GLOBAL_AGENT:\n  case AMDGPU_HSA_SEGMENT_READONLY_AGENT: {\n    switch (agent_profile) {\n    case HSA_PROFILE_BASE:\n      mem = new (std::nothrow) RegionMemory(RegionMemory::AgentLocal(agent, false), false);\n      break;\n    case HSA_PROFILE_FULL:\n      mem = new (std::nothrow) RegionMemory(RegionMemory::System(false), false);\n      break;\n    default:\n      assert(false);\n    }\n    break;\n  }\n  case AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM: {\n    mem = new (std::nothrow) RegionMemory(RegionMemory::System(false), false);\n    break;\n  }\n  case AMDGPU_HSA_SEGMENT_CODE_AGENT: {\n    switch (agent_profile) {\n    case HSA_PROFILE_BASE:\n      mem = new (std::nothrow) RegionMemory(RegionMemory::AgentLocal(agent, true), true);\n      break;\n    case HSA_PROFILE_FULL:\n      mem = new (std::nothrow) MappedMemory();\n      break;\n    default:\n      assert(false);\n    }\n    break;\n  }\n  default:\n    assert(false);\n  }\n\n  if (nullptr == mem) {\n    return nullptr;\n  }\n\n  if (!mem->Allocate(size, align, zero)) {\n    delete mem;\n    return nullptr;\n  }\n\n  return mem;\n}\n\nbool LoaderContext::SegmentCopy(amdgpu_hsa_elf_segment_t segment, // not used.\n                                hsa_agent_t agent,                // not used.\n                                void* dst,\n                                size_t offset,\n                                const void* src,\n                                size_t size)\n{\n  assert(nullptr != dst);\n  return ((SegmentMemory*)dst)->Copy(offset, src, size);\n}\n\nvoid LoaderContext::SegmentFree(amdgpu_hsa_elf_segment_t segment, // not used.\n                                hsa_agent_t agent,                // not used.\n                                void* seg,\n                                size_t size)                      // not used.\n{\n  assert(nullptr != seg);\n  SegmentMemory *mem = (SegmentMemory*)seg;\n  mem->Free();\n  delete mem;\n  mem = nullptr;\n}\n\nvoid* LoaderContext::SegmentAddress(amdgpu_hsa_elf_segment_t segment, // not used.\n                                    hsa_agent_t agent,                // not used.\n                                    void* seg,\n                                    size_t offset)\n{\n  assert(nullptr != seg);\n  return ((SegmentMemory*)seg)->Address(offset);\n}\n\nvoid* LoaderContext::SegmentHostAddress(amdgpu_hsa_elf_segment_t segment, // not used.\n                                        hsa_agent_t agent,                // not used.\n                                        void* seg,\n                                        size_t offset)\n{\n  assert(nullptr != seg);\n  return ((SegmentMemory*)seg)->HostAddress(offset);\n}\n\nbool LoaderContext::SegmentFreeze(amdgpu_hsa_elf_segment_t segment, // not used.\n                                  hsa_agent_t agent,                // not used.\n                                  void* seg,\n                                  size_t size)                      // not used.\n{\n  assert(nullptr != seg);\n  return ((SegmentMemory*)seg)->Freeze();\n}\n\nbool LoaderContext::ImageExtensionSupported() {\n  hsa_status_t hsa_status = HSA_STATUS_SUCCESS;\n  bool result = false;\n\n  hsa_status =\n      HSA::hsa_system_extension_supported(HSA_EXTENSION_IMAGES, 1, 0, &result);\n  if (HSA_STATUS_SUCCESS != hsa_status) {\n    return false;\n  }\n\n  return result;\n}\n\nhsa_status_t LoaderContext::ImageCreate(\n    hsa_agent_t agent, hsa_access_permission_t image_permission,\n    const hsa_ext_image_descriptor_t *image_descriptor, const void *image_data,\n    hsa_ext_image_t *image_handle) {\n  assert(agent.handle);\n  assert(image_descriptor);\n  assert(image_data);\n  assert(image_handle);\n\n  assert(ImageExtensionSupported());\n\n  return hsa_ext_image_create(agent, image_descriptor, image_data,\n                              image_permission, image_handle);\n}\n\nhsa_status_t LoaderContext::ImageDestroy(hsa_agent_t agent,\n                                         hsa_ext_image_t image_handle) {\n  assert(agent.handle);\n  assert(image_handle.handle);\n\n  assert(ImageExtensionSupported());\n\n  return hsa_ext_image_destroy(agent, image_handle);\n}\n\nhsa_status_t LoaderContext::SamplerCreate(\n    hsa_agent_t agent, const hsa_ext_sampler_descriptor_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler_handle) {\n  assert(agent.handle);\n  assert(sampler_descriptor);\n  assert(sampler_handle);\n\n  assert(ImageExtensionSupported());\n\n  return hsa_ext_sampler_create(agent, sampler_descriptor, sampler_handle);\n}\n\nhsa_status_t LoaderContext::SamplerDestroy(hsa_agent_t agent,\n                                           hsa_ext_sampler_t sampler_handle) {\n  assert(agent.handle);\n  assert(sampler_handle.handle);\n\n  assert(ImageExtensionSupported());\n\n  return hsa_ext_sampler_destroy(agent, sampler_handle);\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_memory_region.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_memory_region.h\"\n\n#include <algorithm>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/amd_cpu_agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/util/utils.h\"\n#include \"core/inc/exceptions.h\"\n#include <unistd.h>\n\nnamespace rocr {\nnamespace AMD {\n\n// Tracks aggregate size of system memory available on platform\nsize_t MemoryRegion::max_sysmem_alloc_size_ = 0;\nconst size_t MemoryRegion::kPageSize_ = sysconf(_SC_PAGESIZE);\n\nMemoryRegion::MemoryRegion(bool fine_grain, bool kernarg, bool full_profile,\n                           bool extended_scope_fine_grain, bool user_visible, core::Agent* owner,\n                           const HsaMemoryProperties& mem_props)\n    : core::MemoryRegion(fine_grain, kernarg, full_profile, extended_scope_fine_grain, user_visible,\n                         owner),\n      mem_props_(mem_props),\n      max_single_alloc_size_(0),\n      virtual_size_(0),\n      fragment_allocator_(BlockAllocator(*this)) {\n  virtual_size_ = GetPhysicalSize();\n\n  // extended_scope_fine_grain and fine_grain memory regions are mutually exclusive\n  assert(!(fine_grain && extended_scope_fine_grain));\n\n  mem_flag_.Value = 0;\n  map_flag_.Value = 0;\n  static const HSAuint64 kGpuVmSize = (1ULL << 40);\n\n  // Bind the memory region based on whether it is\n  // coarse or fine grain or extended scope fine grain.\n  mem_flag_.ui32.CoarseGrain = (fine_grain || extended_scope_fine_grain) ? 0 : 1;\n\n  // Extended scope fine-grained memory: Device scope atomics are promoted\n  // to system scope atomics. Non-compliant systems may require the\n  // application to perform device-specific actions, like HDP flushes,\n  // to achieve system-scope coherence\n  mem_flag_.ui32.ExtendedCoherent = (extended_scope_fine_grain) ? 1 : 0;\n\n  if (IsLocalMemory()) {\n    mem_flag_.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    mem_flag_.ui32.NoSubstitute = 1;\n    mem_flag_.ui32.HostAccess =\n        (mem_props_.HeapType == HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE) ? 0 : 1;\n    mem_flag_.ui32.NonPaged = 1;\n\n    virtual_size_ = kGpuVmSize;\n\n  } else if (IsSystem()) {\n    mem_flag_.ui32.PageSize = GetPageSize();\n    mem_flag_.ui32.NoSubstitute = 0;\n    mem_flag_.ui32.HostAccess = 1;\n    mem_flag_.ui32.CachePolicy = HSA_CACHING_CACHED;\n\n    if (kernarg) mem_flag_.ui32.Uncached = 1;\n\n    virtual_size_ =\n        (full_profile) ? os::GetUserModeVirtualMemorySize() : kGpuVmSize;\n  }\n\n\n  // Adjust allocatable size per page align\n  max_single_alloc_size_ = AlignDown(static_cast<size_t>(GetPhysicalSize()), GetPageSize());\n\n  // Keep track of total system memory available\n  // @note: System memory is surfaced as both coarse\n  // and fine grain memory regions. To track total system\n  // memory only fine grain is considered as it avoids\n  // double counting\n  if (IsSystem() && (fine_grain)) {\n    max_sysmem_alloc_size_ += max_single_alloc_size_;\n  }\n\n  assert(GetVirtualSize() != 0);\n  assert(IsMultipleOf(max_single_alloc_size_, GetPageSize()));\n}\n\nMemoryRegion::~MemoryRegion() {}\n\nhsa_status_t MemoryRegion::Allocate(size_t& size, AllocateFlags alloc_flags, void** address, int agent_node_id) const {\n  ScopedAcquire<KernelMutex> lock(&owner()->agent_memory_lock_);\n  return AllocateImpl(size, alloc_flags, address, agent_node_id);\n}\n\nhsa_status_t MemoryRegion::AllocateImpl(size_t& size, AllocateFlags alloc_flags,\n                                        void** address, int agent_node_id) const {\n  if (address == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (!IsSystem() && !IsLocalMemory()) {\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  // Alocation requests for system memory considers aggregate\n  // memory available on all CPU devices\n  if (size > ((IsSystem() ?\n                max_sysmem_alloc_size_ : max_single_alloc_size_))) {\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  size = AlignUp(size, GetPageSize());\n\n  return owner()->driver().AllocateMemory(*this, alloc_flags, address, size,\n                                          agent_node_id);\n}\n\nhsa_status_t MemoryRegion::Free(void* address, size_t size) const {\n  ScopedAcquire<KernelMutex> lock(&owner()->agent_memory_lock_);\n  return FreeImpl(address, size);\n}\n\nhsa_status_t MemoryRegion::FreeImpl(void* address, size_t size) const {\n  if (fragment_allocator_.free(address)) return HSA_STATUS_SUCCESS;\n\n  return owner()->driver().FreeMemory(address, size);\n}\n\n// TODO:  Look into a better name and/or making this process transparent to exporting.\nhsa_status_t MemoryRegion::IPCFragmentExport(void* address) const {\n  ScopedAcquire<KernelMutex> lock(&owner()->agent_memory_lock_);\n  if (!fragment_allocator_.discardBlock(address)) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t MemoryRegion::GetInfo(hsa_region_info_t attribute,\n                                   void* value) const {\n  switch (attribute) {\n    case HSA_REGION_INFO_SEGMENT:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          *((hsa_region_segment_t*)value) = HSA_REGION_SEGMENT_GLOBAL;\n          break;\n        case HSA_HEAPTYPE_GPU_LDS:\n          *((hsa_region_segment_t*)value) = HSA_REGION_SEGMENT_GROUP;\n          break;\n        default:\n          assert(false && \"Memory region should only be global, group\");\n          break;\n      }\n      break;\n    case HSA_REGION_INFO_GLOBAL_FLAGS:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE: {\n          uint32_t ret = 0;\n\n          ret = fine_grain()                ? HSA_REGION_GLOBAL_FLAG_FINE_GRAINED\n              : extended_scope_fine_grain() ? HSA_REGION_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED\n                                            : HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED;\n\n          if (kernarg()) ret |= HSA_REGION_GLOBAL_FLAG_KERNARG;\n          *((uint32_t*)value) = ret;\n          break;\n        }\n        default:\n          *((uint32_t*)value) = 0;\n          break;\n      }\n      break;\n    case HSA_REGION_INFO_SIZE:\n      *((size_t*)value) = static_cast<size_t>(GetPhysicalSize());\n      break;\n    case HSA_REGION_INFO_ALLOC_MAX_SIZE:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n          *((size_t*)value) = max_sysmem_alloc_size_;\n          break;\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n        case HSA_HEAPTYPE_GPU_SCRATCH:\n          *((size_t*)value) = max_single_alloc_size_;\n          break;\n        default:\n          *((size_t*)value) = 0;\n      }\n      break;\n    case HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          *((bool*)value) = true;\n          break;\n        default:\n          *((bool*)value) = false;\n          break;\n      }\n      break;\n    case HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          *((size_t*)value) = GetPageSize();\n          break;\n        default:\n          *((size_t*)value) = 0;\n          break;\n      }\n      break;\n    case HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n        case HSA_HEAPTYPE_DEVICE_SVM:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          *((size_t*)value) = GetPageSize();\n          break;\n        default:\n          *((size_t*)value) = 0;\n          break;\n      }\n      break;\n    default:\n      switch ((hsa_amd_region_info_t)attribute) {\n        case HSA_AMD_REGION_INFO_HOST_ACCESSIBLE:\n          *((bool*)value) =\n              (mem_props_.HeapType == HSA_HEAPTYPE_SYSTEM) ? true : false;\n          break;\n        case HSA_AMD_REGION_INFO_BASE:\n          *((void**)value) = reinterpret_cast<void*>(GetBaseAddress());\n          break;\n        case HSA_AMD_REGION_INFO_BUS_WIDTH:\n          *((uint32_t*)value) = BusWidth();\n          break;\n        case HSA_AMD_REGION_INFO_MAX_CLOCK_FREQUENCY:\n          *((uint32_t*)value) = MaxMemCloc();\n          break;\n        default:\n          return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n          break;\n      }\n      break;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t MemoryRegion::GetPoolInfo(hsa_amd_memory_pool_info_t attribute,\n                                       void* value) const {\n  switch (attribute) {\n    case HSA_AMD_MEMORY_POOL_INFO_SEGMENT:\n    case HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS:\n    case HSA_AMD_MEMORY_POOL_INFO_SIZE:\n    case HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED:\n    case HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE:\n    case HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT:\n      return GetInfo(static_cast<hsa_region_info_t>(attribute), value);\n    case HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL:\n      *((bool*)value) = IsSystem() ? true : false;\n      break;\n    case HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE:\n      return GetInfo(HSA_REGION_INFO_ALLOC_MAX_SIZE, value);\n    case HSA_AMD_MEMORY_POOL_INFO_LOCATION:\n      if (IsLocalMemory())\n        *((hsa_amd_memory_pool_location_t*)value) = HSA_AMD_MEMORY_POOL_LOCATION_GPU;\n      else if (IsSystem())\n        *((hsa_amd_memory_pool_location_t*)value) = HSA_AMD_MEMORY_POOL_LOCATION_CPU;\n      else\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      break;\n    case HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE:\n      switch (mem_props_.HeapType) {\n        case HSA_HEAPTYPE_SYSTEM:\n          *((size_t*)value) = GetPageSize();\n          break;\n        case HSA_HEAPTYPE_FRAME_BUFFER_PRIVATE:\n        case HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC:\n          *((size_t*)value) = core::Runtime::runtime_singleton_->flag().disable_fragment_alloc()\n              ? GetPageSize()\n              : fragment_allocator_.default_block_size();\n          break;\n        default:\n          *((size_t*)value) = 0;\n          break;\n      }\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_amd_memory_pool_access_t MemoryRegion::GetAccessInfo(\n    const core::Agent& agent, const core::Runtime::LinkInfo& link_info) const {\n\n  // Return allowed by default if memory pool is owned by requesting device\n  if (agent.public_handle().handle == owner()->public_handle().handle) {\n    return HSA_AMD_MEMORY_POOL_ACCESS_ALLOWED_BY_DEFAULT;\n  }\n\n  // Requesting device does not have a link\n  if (link_info.num_hop < 1) {\n    return HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n  }\n\n  // Determine access to fine and coarse grained system memory\n  // Return allowed by default if requesting device is a CPU\n  // Return disallowed by default if requesting device is not a CPU\n  if (IsSystem()) {\n    return (agent.device_type() == core::Agent::kAmdCpuDevice) ?\n            (HSA_AMD_MEMORY_POOL_ACCESS_ALLOWED_BY_DEFAULT) :\n            (HSA_AMD_MEMORY_POOL_ACCESS_DISALLOWED_BY_DEFAULT);\n  }\n\n  // Determine access type for device local memory which is\n  // guaranteed to be HSA_HEAPTYPE_FRAME_BUFFER_PUBLIC\n\n  if (IsLocalMemory()) {\n    // Return disallowed by default if memory is coarse\n    // grained or extended scope fine grained without regard to link type\n    if (fine_grain() == false) {\n      return HSA_AMD_MEMORY_POOL_ACCESS_DISALLOWED_BY_DEFAULT;\n    }\n\n    // Return disallowed by default if memory is fine\n    // grained and requesting device is connected via xGMI link\n    if (agent.HiveId() == owner()->HiveId()) {\n      return HSA_AMD_MEMORY_POOL_ACCESS_DISALLOWED_BY_DEFAULT;\n    }\n\n    // Return never allowed if memory is fine grained\n    // link type is not xGMI i.e. link is PCIe\n    return HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n  }\n\n  // Return never allowed if above conditions are not satisified\n  // This can happen when memory pool references neither system\n  // or device local memory\n  return HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n}\n\nhsa_status_t MemoryRegion::GetAgentPoolInfo(\n    const core::Agent& agent, hsa_amd_agent_memory_pool_info_t attribute,\n    void* value) const {\n  const uint32_t node_id_from = agent.node_id();\n  const uint32_t node_id_to = owner()->node_id();\n\n  const core::Runtime::LinkInfo link_info =\n      core::Runtime::runtime_singleton_->GetLinkInfo(node_id_from, node_id_to);\n\n  const hsa_amd_memory_pool_access_t access_type = GetAccessInfo(agent, link_info);\n\n  switch (attribute) {\n    case HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS:\n      *((hsa_amd_memory_pool_access_t*)value) = access_type;\n      break;\n    case HSA_AMD_AGENT_MEMORY_POOL_INFO_NUM_LINK_HOPS:\n      *((uint32_t*)value) =\n          (access_type != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED)\n              ? link_info.num_hop\n              : 0;\n      break;\n    case HSA_AMD_AGENT_MEMORY_POOL_INFO_LINK_INFO:\n      memset(value, 0, sizeof(hsa_amd_memory_pool_link_info_t));\n      if ((access_type != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) &&\n          (link_info.num_hop > 0)) {\n        memcpy(value, &link_info.info, sizeof(hsa_amd_memory_pool_link_info_t));\n      }\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t MemoryRegion::AllowAccess(uint32_t num_agents,\n                                       const hsa_agent_t* agents,\n                                       const void* ptr, size_t size) const {\n  if (num_agents == 0 || agents == NULL || ptr == NULL || size == 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (!IsSystem() && !IsLocalMemory()) {\n    return HSA_STATUS_ERROR;\n  }\n\n  // Adjust for fragments.  Make accessibility sticky for fragments since this will satisfy the\n  // union of accessible agents between the fragments in the block.\n  hsa_amd_pointer_info_t info = {};\n  uint32_t agent_count = 0;\n  hsa_agent_t* accessible = nullptr;\n  MAKE_SCOPE_GUARD([&]() { free(accessible); });\n  core::Runtime::PtrInfoBlockData blockInfo = {};\n  std::vector<uint64_t> union_agents;\n  info.size = sizeof(info);\n\n  ScopedAcquire<KernelMutex> lock(&access_lock_);\n\n  if (core::Runtime::runtime_singleton_->PtrInfo(const_cast<void*>(ptr), &info, malloc,\n                                                 &agent_count, &accessible,\n                                                 &blockInfo) == HSA_STATUS_SUCCESS) {\n    /*  Thunk may return type = HSA_EXT_POINTER_TYPE_UNKNOWN for userptrs */\n    if (info.type != HSA_EXT_POINTER_TYPE_UNKNOWN &&\n        (blockInfo.length != size || info.sizeInBytes != size)) {\n      for (int i = 0; i < num_agents; i++) union_agents.push_back(agents[i].handle);\n      for (int i = 0; i < agent_count; i++) union_agents.push_back(accessible[i].handle);\n      std::sort(union_agents.begin(), union_agents.end());\n      const auto& last = std::unique(union_agents.begin(), union_agents.end());\n      union_agents.erase(last, union_agents.end());\n\n      agents = reinterpret_cast<hsa_agent_t*>(&union_agents[0]);\n      num_agents = union_agents.size();\n      size = blockInfo.length;\n      ptr = blockInfo.base;\n    }\n  }\n\n  bool cpu_in_list = false;\n\n  std::vector<uint32_t> whitelist_nodes;\n  for (uint32_t i = 0; i < num_agents; ++i) {\n    core::Agent* agent = core::Agent::Convert(agents[i]);\n    if (agent == NULL || !agent->IsValid()) {\n      return HSA_STATUS_ERROR_INVALID_AGENT;\n    }\n\n    switch (agent->device_type()) {\n    case core::Agent::kAmdGpuDevice:\n      whitelist_nodes.push_back(agent->node_id());\n      break;\n    case core::Agent::kAmdCpuDevice:\n      cpu_in_list = true;\n      break;\n    case core::Agent::kAmdAieDevice:\n    default:\n      return HSA_STATUS_ERROR_INVALID_AGENT;\n    }\n  }\n\n  if (whitelist_nodes.size() == 0 && IsSystem()) {\n    assert(cpu_in_list);\n    // This is a system region and only CPU agents in the whitelist.\n    // Remove old mappings.\n    owner()->driver().MakeMemoryUnresident(ptr);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // If this is a local memory region, the owning gpu always needs to be in\n  // the whitelist.\n  if (IsLocalMemory() &&\n      std::find(whitelist_nodes.begin(), whitelist_nodes.end(), owner()->node_id()) ==\n          whitelist_nodes.end()) {\n    whitelist_nodes.push_back(owner()->node_id());\n  }\n\n  HsaMemMapFlags map_flag = map_flag_;\n  map_flag.ui32.HostAccess |= (cpu_in_list) ? 1 : 0;\n\n  {  // Sequence with pointer info since queries to other fragments of the block may be adjusted by\n     // this call.\n    ScopedAcquire<KernelSharedMutex::Shared> lock(\n        core::Runtime::runtime_singleton_->memory_lock_.shared());\n    uint64_t alternate_va = 0;\n    if (owner()->driver().MakeMemoryResident(ptr, size, &alternate_va, &map_flag,\n                                             whitelist_nodes.size(),\n                                             whitelist_nodes.data()) != HSA_STATUS_SUCCESS) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t MemoryRegion::CanMigrate(const MemoryRegion& dst,\n                                      bool& result) const {\n  // TODO: not implemented yet.\n  result = false;\n  return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n}\n\nhsa_status_t MemoryRegion::Migrate(uint32_t flag, const void* ptr) const {\n  // TODO: not implemented yet.\n  return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n}\n\nhsa_status_t MemoryRegion::Lock(uint32_t num_agents, const hsa_agent_t* agents,\n                                void* host_ptr, size_t size,\n                                void** agent_ptr) const {\n  if (!IsSystem()) {\n    return HSA_STATUS_ERROR;\n  }\n\n  if (full_profile()) {\n    // For APU, any host pointer is always accessible by the gpu.\n    *agent_ptr = host_ptr;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  std::vector<HSAuint32> whitelist_nodes;\n  if (num_agents == 0 || agents == NULL) {\n    // Map to all GPU agents.\n    whitelist_nodes = core::Runtime::runtime_singleton_->gpu_ids();\n  } else {\n    for (uint32_t i = 0; i < num_agents; ++i) {\n      core::Agent* agent = core::Agent::Convert(agents[i]);\n      if (agent == NULL || !agent->IsValid()) {\n        return HSA_STATUS_ERROR_INVALID_AGENT;\n      }\n\n      switch (agent->device_type()) {\n      case core::Agent::kAmdGpuDevice:\n        whitelist_nodes.push_back(agent->node_id());\n        break;\n      case core::Agent::kAmdCpuDevice:\n        // Do nothing.\n        break;\n      case core::Agent::kAmdAieDevice:\n      default:\n        return HSA_STATUS_ERROR_INVALID_AGENT;\n      }\n    }\n  }\n\n  if (whitelist_nodes.size() == 0) {\n    // No GPU agents in the whitelist. So no need to register and map since the\n    // platform only has CPUs.\n    *agent_ptr = host_ptr;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Call kernel driver to register and pin the memory.\n  if (owner()->driver().RegisterMemory(host_ptr, size, const_cast<HsaMemFlags&>(mem_flag_)) ==\n      HSA_STATUS_SUCCESS) {\n    uint64_t alternate_va = 0;\n    if (owner()->driver().MakeMemoryResident(host_ptr, size, &alternate_va, &map_flag_,\n                                             whitelist_nodes.size(),\n                                             whitelist_nodes.data()) == HSA_STATUS_SUCCESS) {\n      if (alternate_va != 0) {\n        *agent_ptr = reinterpret_cast<void*>(alternate_va);\n      } else {\n        *agent_ptr = host_ptr;\n      }\n\n      return HSA_STATUS_SUCCESS;\n    }\n    owner()->driver().DeregisterMemory(host_ptr);\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  return HSA_STATUS_ERROR;\n}\n\nhsa_status_t MemoryRegion::Unlock(void* host_ptr) const {\n  if (!IsSystem()) {\n    return HSA_STATUS_ERROR;\n  }\n\n  if (full_profile()) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (owner()->driver().MakeMemoryUnresident(host_ptr) != HSA_STATUS_SUCCESS) {\n    assert(false && \"Failed to unmap host pointer\");\n  }\n  if (owner()->driver().DeregisterMemory(host_ptr) != HSA_STATUS_SUCCESS) {\n    assert(false && \"Failed to deregister host pointer\");\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t MemoryRegion::AssignAgent(void* ptr, size_t size,\n                                       const core::Agent& agent,\n                                       hsa_access_permission_t access) const {\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid MemoryRegion::Trim() const { fragment_allocator_.trim(); }\n\nvoid* MemoryRegion::BlockAllocator::alloc(size_t request_size, size_t& allocated_size) const {\n  void* ret;\n  size_t bsize = AlignUp(request_size, block_size());\n\n  hsa_status_t err = region_.AllocateImpl(\n      bsize, core::MemoryRegion::AllocateRestrict | core::MemoryRegion::AllocateDirect, &ret, 0);\n  if (err != HSA_STATUS_SUCCESS)\n    throw AMD::hsa_exception(err, \"MemoryRegion::BlockAllocator::alloc failed.\");\n  assert(ret != nullptr && \"Region returned nullptr on success.\");\n\n  allocated_size = bsize;\n  return ret;\n}\n\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/amd_topology.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_topology.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <functional>\n\n#ifndef NDEBUG\n#include <iostream>\n#endif\n\n#include <array>\n#include <map>\n#include <memory>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\n#include <link.h>\n\n#include \"core/inc/amd_aie_agent.h\"\n#include \"core/inc/amd_available_drivers.h\"\n#include \"core/inc/amd_cpu_agent.h\"\n#include \"core/inc/amd_filter_device.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/util/utils.h\"\n#ifdef HSAKMT_VIRTIO_ENABLED\n#include \"core/inc/amd_virtio_driver.h\"\n#endif\n\nextern r_debug _amdgpu_r_debug;\n\nnamespace rocr {\nnamespace AMD {\n// Anonymous namespace.\nnamespace {\n\nconst std::array<std::function<hsa_status_t(std::unique_ptr<core::Driver>&)>,\n#if _WIN32\n                 0\n#elif __linux__\n                 static_cast<size_t>(core::DriverType::NUM_DRIVER_TYPES)\n#endif\n                 >\n    discover_driver_funcs = {\n#ifdef __linux__\n        KfdDriver::DiscoverDriver,\n        XdnaDriver::DiscoverDriver,\n#ifdef HSAKMT_VIRTIO_ENABLED\n        KfdVirtioDriver::DiscoverDriver,\n#endif\n#endif\n};\n\nvoid DiscoverDrivers() {\n  for (const auto& discover_driver_fn : discover_driver_funcs) {\n    std::unique_ptr<core::Driver> driver;\n    hsa_status_t ret = discover_driver_fn(driver);\n\n    if (ret != HSA_STATUS_SUCCESS) continue;\n\n    core::Runtime::runtime_singleton_->RegisterDriver(std::move(driver));\n  }\n}\n\nbool InitializeDriver(std::unique_ptr<core::Driver>& driver) {\n  MAKE_NAMED_SCOPE_GUARD(driver_guard, [&]() { driver->Close(); });\n\n  if (driver->Init() != HSA_STATUS_SUCCESS) {\n    return false;\n  }\n\n  driver_guard.Dismiss();\n  return true;\n}\n\nvoid DiscoverCpu(HSAuint32 node_id, HsaNodeProperties& node_prop, core::DriverType driver_type) {\n  CpuAgent* cpu = new CpuAgent(node_id, node_prop, driver_type);\n  cpu->Enable();\n  core::Runtime::runtime_singleton_->RegisterAgent(cpu, true);\n}\n\nGpuAgent* DiscoverGpu(HSAuint32 node_id, HsaNodeProperties& node_prop, bool xnack_mode,\n                      bool enabled, core::DriverType driver_type) {\n  GpuAgent* gpu = nullptr;\n  if (node_prop.NumFComputeCores == 0) {\n      // Ignore non GPUs.\n      return nullptr;\n  }\n  try {\n    gpu = new GpuAgent(node_id, node_prop, xnack_mode,\n                       core::Runtime::runtime_singleton_->gpu_agents().size(), driver_type);\n\n    const HsaVersionInfo& kfd_version = core::Runtime::runtime_singleton_->KfdVersion().version;\n\n    // Check for sramecc incompatibility due to sramecc not being reported correctly in kfd before\n    // 1.4.\n    if (gpu->supported_isas()[0]->IsSrameccSupported() &&\n         (kfd_version.KernelInterfaceMajorVersion <= 1 &&\n              kfd_version.KernelInterfaceMinorVersion < 4)) {\n      // gfx906 has both sramecc modes in use.  Suppress the device.\n      if ((gpu->supported_isas()[0]->GetProcessorName() == \"gfx906\") &&\n          core::Runtime::runtime_singleton_->flag().check_sramecc_validity()) {\n        char name[64];\n        gpu->GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_PRODUCT_NAME, name);\n        name[63] = '\\0';\n        fprintf(stderr,\n                \"HSA Error:  Incompatible kernel and userspace, %s disabled. Upgrade amdgpu.\\n\",\n                name);\n        delete gpu;\n        return nullptr;\n      }\n\n      // gfx908 always has sramecc set to on in vbios.  Set mode bit to on and recreate the device.\n      if (gpu->supported_isas()[0]->GetProcessorName() == \"gfx908\") {\n        node_prop.Capability.ui32.SRAM_EDCSupport = 1;\n        delete gpu;\n        gpu = new GpuAgent(node_id, node_prop, xnack_mode,\n                           core::Runtime::runtime_singleton_->gpu_agents().size(), driver_type);\n      }\n    }\n  } catch (const hsa_exception& e) {\n    if(e.error_code() == HSA_STATUS_ERROR_INVALID_ISA) {\n      ifdebug {\n        if (!strIsEmpty(e.what())) debug_print(\"Warning: %s\\n\", e.what());\n      }\n      // Ignore unrecognized GPUs.\n      return nullptr;\n    } else {\n      // Rethrow remaining exceptions.\n      throw;\n    }\n  }\n  if (enabled) gpu->Enable();\n  core::Runtime::runtime_singleton_->RegisterAgent(gpu, enabled);\n  return gpu;\n}\n\nvoid DiscoverAie(uint32_t node_id, HsaNodeProperties& node_prop) {\n  AieAgent* aie = new AieAgent(node_id, node_prop);\n  core::Runtime::runtime_singleton_->RegisterAgent(aie, true);\n}\n\nvoid RegisterLinkInfo(const std::unique_ptr<core::Driver>& driver, uint32_t node_id,\n                      uint32_t num_link) {\n  // Register connectivity links for this agent to the runtime.\n  if (num_link == 0) {\n    return;\n  }\n\n  std::vector<HsaIoLinkProperties> links(num_link);\n  if (HSA_STATUS_SUCCESS != driver->GetEdgeProperties(links, node_id)) {\n    return;\n  }\n\n  for (HsaIoLinkProperties io_link : links) {\n    // Populate link info with thunk property.\n    hsa_amd_memory_pool_link_info_t link_info = {0};\n\n    switch (io_link.IoLinkType) {\n      case HSA_IOLINKTYPE_HYPERTRANSPORT:\n        link_info.link_type = HSA_AMD_LINK_INFO_TYPE_HYPERTRANSPORT;\n        link_info.atomic_support_32bit = true;\n        link_info.atomic_support_64bit = true;\n        link_info.coherent_support = true;\n        break;\n      case HSA_IOLINKTYPE_PCIEXPRESS:\n        link_info.link_type = HSA_AMD_LINK_INFO_TYPE_PCIE;\n        link_info.atomic_support_32bit = true;\n        link_info.atomic_support_64bit = true;\n        link_info.coherent_support = true;\n        break;\n      case HSA_IOLINK_TYPE_QPI_1_1:\n        link_info.link_type = HSA_AMD_LINK_INFO_TYPE_QPI;\n        link_info.atomic_support_32bit = true;\n        link_info.atomic_support_64bit = true;\n        link_info.coherent_support = true;\n        break;\n      case HSA_IOLINK_TYPE_INFINIBAND:\n        link_info.link_type = HSA_AMD_LINK_INFO_TYPE_INFINBAND;\n        debug_print(\"IOLINK is missing atomic and coherency defaults.\\n\");\n        break;\n      case HSA_IOLINK_TYPE_XGMI:\n        link_info.link_type = HSA_AMD_LINK_INFO_TYPE_XGMI;\n        link_info.atomic_support_32bit = true;\n        link_info.atomic_support_64bit = true;\n        link_info.coherent_support = true;\n        break;\n      default:\n        debug_print(\"Unrecognized IOLINK type.\\n\");\n        break;\n    }\n\n    // KFD is reporting wrong override status for XGMI.  Disallow override for bringup.\n    if (io_link.Flags.ui32.Override == 1) {\n      if (io_link.Flags.ui32.NoPeerToPeerDMA == 1) {\n        // Ignore this link since peer to peer is not allowed.\n        continue;\n      }\n      link_info.atomic_support_32bit = (io_link.Flags.ui32.NoAtomics32bit == 0);\n      link_info.atomic_support_64bit = (io_link.Flags.ui32.NoAtomics64bit == 0);\n      link_info.coherent_support = (io_link.Flags.ui32.NonCoherent == 0);\n    }\n\n    link_info.max_bandwidth = io_link.MaximumBandwidth;\n    link_info.max_latency = io_link.MaximumLatency;\n    link_info.min_bandwidth = io_link.MinimumBandwidth;\n    link_info.min_latency = io_link.MinimumLatency;\n    link_info.numa_distance = io_link.Weight;\n\n    core::Runtime::runtime_singleton_->RegisterLinkInfo(\n        io_link.NodeFrom, io_link.NodeTo, io_link.Weight, io_link.RecSdmaEngIdMask, link_info);\n  }\n}\n\n/**\n * Process the list of Gpus that are surfaced to user\n */\nvoid SurfaceGpuList(std::vector<int32_t>& gpu_list, bool xnack_mode, bool enabled) {\n  // Process user visible Gpu devices\n  const int32_t invalidIdx = -1;\n  int32_t list_sz = gpu_list.size();\n  HsaNodeProperties node_prop = {0};\n  for (const auto& gpu_driver : core::Runtime::runtime_singleton_->AgentDrivers()) {\n    if (!core::Runtime::IsGPUDriver(gpu_driver->kernel_driver_type_)) {\n      continue;\n    }\n\n    for (int32_t idx = 0; idx < list_sz; idx++) {\n      if (gpu_list[idx] == invalidIdx) {\n        break;\n      }\n\n      // Obtain properties of the node\n      hsa_status_t ret = gpu_driver->GetNodeProperties(node_prop, gpu_list[idx]);\n      assert(ret == HSA_STATUS_SUCCESS && \"Error in getting Node Properties\");\n\n      // disable interrupt signal for DTIF platform\n      if (core::Runtime::runtime_singleton_->flag().enable_dtif())\n        core::g_use_interrupt_wait = false;\n\n      // Instantiate a Gpu device. The IO links\n      // of this node have already been registered\n      assert((node_prop.NumFComputeCores != 0) && \"Improper node used for GPU device discovery.\");\n      DiscoverGpu(gpu_list[idx], node_prop, xnack_mode, enabled, gpu_driver->kernel_driver_type_);\n    }\n  }\n}\n\n/// @brief Calls into the user-mode driver for each node to build the topology\n/// of the system.\n///\n/// @details Topology information includes information about each node in the\n/// topology graph, which includes agents, IO links, memory, and caches.\nbool BuildTopology() {\n  auto rt = core::Runtime::runtime_singleton_;\n  std::unordered_map<core::DriverType, HsaSystemProperties> driver_sys_props;\n  std::unordered_map<core::DriverType, std::vector<HsaNodeProperties>> driver_node_props;\n  size_t link_count = 0;\n  /// @todo Currently we can filter out GPU devices using the\n  /// ROCR_VISIBLE_DEVICES environment variable. Eventually this\n  /// should be updated to allow for filtering other agents like\n  /// AIEs.\n  RvdFilter rvdFilter;\n  int32_t invalidIdx = -1;\n  uint32_t visibleCnt = 0;\n  std::vector<int32_t> gpu_usr_list;\n  std::vector<int32_t> gpu_disabled;\n  bool filter = RvdFilter::FilterDevices();\n\n  // Get the system properties from each driver, populate the node properties list\n  // for each driver, then update the runtime's link count before traversing each\n  // driver's individual nodes.\n  for (const auto& driver : rt->AgentDrivers()) {\n    auto &sys_props = driver_sys_props[driver->kernel_driver_type_];\n    auto &node_props_vec = driver_node_props[driver->kernel_driver_type_];\n    if (driver->GetSystemProperties(sys_props) != HSA_STATUS_SUCCESS)\n      return false;\n\n    const auto num_nodes = sys_props.NumNodes;\n\n    if (!num_nodes) {\n      continue;\n    }\n\n    link_count += num_nodes;\n    node_props_vec.resize(num_nodes);\n    uint32_t node_id = 0;\n\n    for (auto& node_props : node_props_vec) {\n      if (driver->GetNodeProperties(node_props, node_id) != HSA_STATUS_SUCCESS) {\n        return false;\n      }\n      ++node_id;\n    }\n  }\n\n  rt->SetLinkCount(link_count);\n\n  // Traverse each driver's nodes and discover their agents.\n  for (const auto& driver : rt->AgentDrivers()) {\n    auto& node_props_vec = driver_node_props[driver->kernel_driver_type_];\n\n    /// @todo: Add support for AIEs.\n    // Query if env ROCR_VISIBLE_DEVICES is defined. If defined\n    // determine number and order of GPU devices to be surfaced.\n    if (filter && (core::Runtime::IsGPUDriver(driver->kernel_driver_type_))) {\n      rvdFilter.BuildRvdTokenList();\n      rvdFilter.BuildDeviceUuidList(node_props_vec);\n      visibleCnt = rvdFilter.BuildUsrDeviceList();\n      for (int32_t idx = 0; idx < visibleCnt; idx++) {\n        gpu_usr_list.push_back(invalidIdx);\n      }\n    }\n\n    // Discover agents on every node in the platform.\n    int32_t kfdIdx = 0;\n    uint32_t node_id = 0;\n    for (auto& node_props : node_props_vec) {\n      if (node_props.NumCPUCores) {\n        // Node has CPU cores so instantiate a CPU agent.\n        DiscoverCpu(node_id, node_props, driver->kernel_driver_type_);\n      }\n\n      if (node_props.NumNeuralCores) {\n        // Node has AIE cores so instantiate an AIE agent.\n        DiscoverAie(node_id, node_props);\n      }\n\n      // Current node is either a dGpu or Apu and might belong\n      // to user visible list. Process node if present in usr\n      // visible list, continue if not found\n      if (node_props.NumFComputeCores != 0) {\n        if (filter) {\n          int32_t devRank = rvdFilter.GetUsrDeviceRank(kfdIdx);\n          if (devRank != (-1)) {\n            gpu_usr_list[devRank] = node_id;\n          } else {\n            gpu_disabled.push_back(node_id);\n          }\n        } else {\n          gpu_usr_list.push_back(node_id);\n        }\n        kfdIdx++;\n      }\n\n      // Register IO links of node without regard to\n      // it being visible to user or not. It is not\n      // possible to access links of nodes that are\n      // not visible\n      RegisterLinkInfo(driver, node_id, node_props.NumIOLinks);\n      ++node_id;\n    }\n  }\n\n  // Instantiate ROCr objects to encapsulate Gpu devices\n  SurfaceGpuList(gpu_usr_list, rt->XnackEnabled(), true);\n  SurfaceGpuList(gpu_disabled, rt->XnackEnabled(), false);\n\n  // Parse HSA_CU_MASK with GPU and CU count limits.\n  uint32_t maxGpu = rt->gpu_agents().size();\n  uint32_t maxCu = 0;\n  uint32_t cus;\n  for (auto& gpu : rt->gpu_agents()) {\n    gpu->GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &cus);\n    maxCu = Max(maxCu, cus);\n  }\n  const_cast<Flag&>(rt->flag()).parse_masks(maxGpu, maxCu);\n\n  // Front load the rec_sdma_eng_id_mask to check whether needs to override old mask\n  bool rec_sdma_engine_override = false;\n  for (auto& src_gpu : rt->gpu_agents()) {\n    uint32_t src_id = src_gpu->node_id();\n\n    // Set RecSdmaEngOverride to true for all gpus\n    if (rec_sdma_engine_override) {\n      ((AMD::GpuAgent*)src_gpu)->SetRecSdmaEngOverride(rec_sdma_engine_override);\n      continue;\n    }\n\n    // skip the pre-loop if NumSdmaXgmiEngines != 6\n    if (((AMD::GpuAgent*)src_gpu)->properties().NumSdmaXgmiEngines != 6)\n      break;\n\n    for (auto& dst_gpu : rt->gpu_agents()) {\n      uint32_t dst_id = dst_gpu->node_id();\n      if (src_id != dst_id) {\n        auto linfo = rt->GetLinkInfo(src_id, dst_id);\n        if (IsPowerOfTwo(linfo.rec_sdma_eng_id_mask)) {\n          rec_sdma_engine_override = true;\n          ((AMD::GpuAgent*)src_gpu)->SetRecSdmaEngOverride(rec_sdma_engine_override);\n          break;\n        }\n      }\n    }\n  }\n\n  // Register destination agents that can SDMA gang copy for source agents\n  for (auto& src_gpu : rt->gpu_agents()) {\n    uint32_t src_id = src_gpu->node_id();\n    for (auto& dst_gpu : rt->gpu_agents()) {\n      uint32_t dst_id = dst_gpu->node_id();\n      uint32_t gang_factor = 1, rec_sdma_eng_id_mask = 0;\n\n      if (src_id != dst_id) {\n        auto linfo = rt->GetLinkInfo(src_id, dst_id);\n        // Ganging can only be done over xGMI and is either fixed or variable\n        // based on topology information:\n        // Weight of 13 - Intra-socket GPU link in multi-partition mode\n        // Weigth of 15 - Direct GPU link in single partition mode\n        // Weight of 41 - Inter-socket GPU link in multi-partition mode\n        if (linfo.info.link_type == HSA_AMD_LINK_INFO_TYPE_XGMI) {\n          // Temporary work-around, disable SDMA ganging on non-APUs in non-SPX modes\n          // Check xGMI APU status\n          const bool isXgmiApu = static_cast<AMD::GpuAgent*>(src_gpu)->is_xgmi_cpu_gpu();\n          if (linfo.info.numa_distance == 13 || linfo.info.numa_distance == 41)\n            gang_factor = isXgmiApu ? 2 : 1;\n          else if (linfo.info.numa_distance == 15 && linfo.info.min_bandwidth)\n            gang_factor = linfo.info.max_bandwidth/linfo.info.min_bandwidth;\n          else gang_factor = 1;\n\n          rec_sdma_eng_id_mask = linfo.rec_sdma_eng_id_mask;\n\n          // Override the old mask if rec sdma eng verride is true\n          // Using one pcie sdma for device to device copy with limited XGMI SDMA engine.\n          // This will help improve all to all copy with limited XGMI SDMA engine.\n          if (rec_sdma_engine_override) {\n            uint32_t sdma_engine_mask = (1 << (((AMD::GpuAgent*)src_gpu)->properties().NumSdmaEngines - 1));\n            rec_sdma_eng_id_mask = !IsPowerOfTwo(rec_sdma_eng_id_mask) ?\n              sdma_engine_mask : rec_sdma_eng_id_mask;\n          }\n        }\n      }\n\n      // Register all GPUs regardless of connection type to take advantage of easy\n      // key-value lookup later on.\n      ((AMD::GpuAgent*)src_gpu)->RegisterGangPeer(*dst_gpu, gang_factor);\n      ((AMD::GpuAgent*)src_gpu)->RegisterRecSdmaEngIdMaskPeer(*dst_gpu, rec_sdma_eng_id_mask);\n    }\n  }\n  return true;\n}\n}  // Anonymous namespace\n\nbool Load() {\n  DiscoverDrivers();\n\n  if (core::Runtime::runtime_singleton_->AgentDrivers().empty()) return false;\n\n  for (auto& d : core::Runtime::runtime_singleton_->AgentDrivers()) {\n    bool is_model_enabled = false;\n    d->IsModelEnabled(&is_model_enabled);\n    if (is_model_enabled) continue;\n    if (!InitializeDriver(d)) return false;\n  }\n\n  return BuildTopology();\n}\n\nbool Unload() {\n  for (auto& driver : core::Runtime::runtime_singleton_->AgentDrivers()) {\n    hsa_status_t ret = driver->ShutDown();\n    if (ret != HSA_STATUS_SUCCESS) return false;\n  }\n\n  return true;\n}\n}  // namespace amd\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/blit_shaders/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2023, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n##\n################################################################################\n\n# Minimum required version of CMake\ncmake_minimum_required ( VERSION 3.7 )\n\n# Find Clang package and LLVM package\nfind_package(Clang REQUIRED HINTS ${CMAKE_PREFIX_PATH}/llvm PATHS /opt/rocm/llvm )\nfind_package(LLVM REQUIRED HINTS ${CMAKE_PREFIX_PATH}/llvm PATHS /opt/rocm/llvm )\n\n# Set the target devices\nset (TARGET_DEVS \"gfx900;gfx1010;gfx1030;gfx1100;gfx1200\")\n\n# Set the postfix for each target device\nset (POSTFIX \"9;1010;10;11;12\")\n\n# If verbose output is enabled, print paths and target devices\nif(${CMAKE_VERBOSE_MAKEFILE})\n\tget_property(clang_path TARGET clang PROPERTY LOCATION)\n\tget_property(objcopy_path TARGET llvm-objcopy PROPERTY LOCATION)\n\tmessage(\"Using clang from: ${clang_path}\")\n\tmessage(\"Using llvm-objcopy from: ${objcopy_path}\")\n\tmessage(\"Blit Shaders assembled for: ${TARGET_DEVS}\")\nendif()\n\n# Function to generate kernel bitcode\nfunction(gen_kernel_bc TARGET_ID INPUT_FILE OUTPUT_FILE)\n\tset(CODE_OBJECT \"${OUTPUT_FILE}.hsaco\")\n\n\t# Separate clang arguments\n\tseparate_arguments(CLANG_ARG_LIST UNIX_COMMAND \"-x assembler -target amdgcn-amd-amdhsa -mcode-object-version=5 -fPIC -mcpu=${TARGET_ID} -o ${CODE_OBJECT} ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE}\")\n\n\t# Add custom command to generate the kernel bitcode\n\tadd_custom_command(OUTPUT ${CODE_OBJECT} COMMAND clang ${CLANG_ARG_LIST}\n\tDEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE} clang\n\tCOMMENT \"BUILDING bitcode for ${OUTPUT_FILE}...\"\n\tVERBATIM)\n\n\tseparate_arguments(OBJCOPY_ARG_LIST UNIX_COMMAND \"--dump-section=.text=${OUTPUT_FILE} ${CODE_OBJECT}\")\n\n\t# Add custom command to extract binary from the bitcode\n\tadd_custom_command(OUTPUT ${OUTPUT_FILE}\n\tCOMMAND llvm-objcopy ${OBJCOPY_ARG_LIST}\n\tDEPENDS ${CODE_OBJECT} llvm-objcopy\n\tCOMMENT \"Extracting binary for ${OUTPUT_FILE}...\"\n\tVERBATIM)\n\n\tif(${CMAKE_VERBOSE_MAKEFILE})\n\t\tmessage(\"     Blit Shader Source: \" ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE})\n\t\tmessage(\"     Blit Shader Binary: \" ${OUTPUT_FILE})\n\tendif()\n\nendfunction(gen_kernel_bc)\n\n# Function to build a kernel for each target device\nfunction(build_kernel BLIT_SHADER_NAME BLIT_FILE TARGET_ID POSTFIX)\n\tset(CODE_OBJECT_FILE \"${BLIT_SHADER_NAME}${POSTFIX}\")\n\tgen_kernel_bc(${TARGET_ID} ${BLIT_FILE} ${CODE_OBJECT_FILE})\n\tlist(APPEND HSACO_TARG_LIST \"${CODE_OBJECT_FILE}\")\n\tset(HSACO_TARG_LIST ${HSACO_TARG_LIST} PARENT_SCOPE)\n\nendfunction(build_kernel)\n\n# Function to build kernels for all devices and shaders\nfunction(build_kernels_for_devices SHADER_NAMES SHADER_FILES)\n\tset(HSACO_TARG_LIST \"\")\n\n\tlist(LENGTH TARGET_DEVS num_target_devices)\n\tmath(EXPR num_target_devices \"${num_target_devices} - 1\")\n\tlist(LENGTH SHADER_NAMES num_shader_names)\n\tmath(EXPR num_shader_names \"${num_shader_names} - 1\")\n\n\tforeach(shader_index RANGE ${num_shader_names})\n\t\tlist(GET SHADER_NAMES ${shader_index} shader_name)\n\t\tlist(GET SHADER_FILES ${shader_index} shader_file)\n\t\tforeach(device_index RANGE ${num_target_devices})\n\t\t\t# Get device from list of target devices\n\t\t\tlist(GET TARGET_DEVS ${device_index} target_device)\n\t\t\t# Get postfix from list of postfixes\n\t\t\tlist(GET POSTFIX ${device_index} postfix)\n\t\t\tif(${CMAKE_VERBOSE_MAKEFILE})\n\t\t\t\tmessage(\"\\n  Generating: ${target_device} for ${shader_name} ...\")\n\t\t\tendif()\n\n\t\t\t# Define the name of the code object file\n\t\t\tset(CODE_OBJECT_FILE \"${shader_name}${postfix}\")\n\n\t\t\t# Generate the kernel bitcode for the current device and shader\n\t\t\tgen_kernel_bc(${target_device} ${shader_file} ${CODE_OBJECT_FILE})\n\t\t\t# Append the code object file to the list\n\t\t\tlist(APPEND HSACO_TARG_LIST \"${CODE_OBJECT_FILE}\")\n\t\tendforeach(device_index)\n\tendforeach(shader_index)\n\n\t# Make the list of code object files available in the parent scope\n\tset(HSACO_TARG_LIST ${HSACO_TARG_LIST} PARENT_SCOPE)\n\nendfunction(build_kernels_for_devices)\n\n\n# Function to generate the bytecode stream and create the header file\nfunction(generate_bytecodeStrm HeaderFILE)\n\tset(ARG_LIST \"${CMAKE_CURRENT_BINARY_DIR}/${HeaderFILE}.h\")\n\n\t# Copy the shell script to the build directory\n\tconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/create_blit_shader_header.sh\n\t\t${CMAKE_CURRENT_BINARY_DIR}/create_blit_shader_header.sh\n\t\tCOPYONLY)\n\n\t# Add a custom command to generate the header file\n\tadd_custom_command(OUTPUT ${HeaderFILE}.h\n\t\tCOMMAND ${CMAKE_CURRENT_BINARY_DIR}/create_blit_shader_header.sh ${ARG_LIST} ${HSACO_TARG_LIST}\n\t\tCOMMENT \"Collating blit shaders...\"\n\t\tDEPENDS ${HSACO_TARG_LIST} ${CMAKE_CURRENT_BINARY_DIR}/create_blit_shader_header.sh)\n\n\t# Add a custom target that depends on the header file\n\tadd_custom_target(${HeaderFILE} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${HeaderFILE}.h)\n\nendfunction(generate_bytecodeStrm)\n\n\n# Build kernels for deviceodeCopyAligned\nbuild_kernels_for_devices(\"kCodeCopyAligned;kCodeCopyMisaligned;kCodeFill\" \"blit_copyAligned.s;blit_copyMisaligned.s;blit_fill.s\")\n\n# Generate bytecode stream\ngenerate_bytecodeStrm(\"amd_blit_shaders_v2\")\n\n\n\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/blit_shaders/blit_copyAligned.s",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n///////////////////////////////////////////////////////////////////////////////////////\n\n.text\n\n.macro V_ADD_CO_U32 vdst, src0, vsrc1\n  .if (.amdgcn.gfx_generation_number >= 10)\n\t\t v_add_co_u32        \\vdst, vcc_lo, \\src0, \\vsrc1\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_add_co_u32        \\vdst, vcc, \\src0, \\vsrc1\n\t.else\n\t\tv_add_u32           \\vdst, vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n\n.macro V_ADD_CO_CI_U32 vdst, src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_add_co_ci_u32     \\vdst, vcc_lo, \\src0, \\vsrc1, vcc_lo\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_addc_co_u32       \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.else\n\t\tv_addc_u32          \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.endif\n.endm\n\n.macro V_CMP_LT_U64 src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_cmp_lt_u64        vcc_lo, \\src0, \\vsrc1\n\t.else\n\t\tv_cmp_lt_u64        vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n.p2align 8\n\nCopyAligned:\n.set kCopyAlignedVecWidth, 4\ncompute_pgm_rsrc2_user_sgpr = 2\ncompute_pgm_rsrc2_tgid_x_en = 1\nenable_sgpr_kernarg_segment_ptr = 1\n\n.set kCopyAlignedUnroll, 1\n.set kCopyAlignedNumSGPRs, 32\n.set kCopyAlignedNumVGPRs, (8 + (kCopyAlignedUnroll * kCopyAlignedVecWidth))\n.set CopyAlignedRsrc1SGPRs, (kCopyAlignedNumSGPRs - 1)/8\n.set CopyAlignedRsrc1VGPRs, (kCopyAlignedNumVGPRs - 1)/4\n\ncompute_pgm_rsrc1_sgprs = CopyAlignedRsrc1SGPRs\ncompute_pgm_rsrc1_vgprs = CopyAlignedRsrc1VGPRs\n\n\n  s_load_dwordx4  s[4:7], s[0:1], 0x0\n  s_load_dwordx4  s[8:11], s[0:1], 0x10\n  s_load_dwordx4  s[12:15], s[0:1], 0x20\n  s_load_dwordx4  s[16:19], s[0:1], 0x30\n  s_load_dwordx4  s[20:23], s[0:1], 0x40\n  s_load_dword    s24, s[0:1], 0x50\n  s_waitcnt                lgkmcnt(0)\n\n  .if (.amdgcn.gfx_generation_number == 12)\n    s_lshl_b32              s2, ttmp9, 0x6\n  .else\n    s_lshl_b32              s2, s2, 0x6\n  .endif\n\n    V_ADD_CO_U32            v0, s2, v0\n\n    v_mov_b32               v3, s5\n    V_ADD_CO_U32            v2, v0, s4\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n\n    v_mov_b32               v5, s7\n    V_ADD_CO_U32            v4, v0, s6\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n  L_COPY_ALIGNED_PHASE_1_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[8:9]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_1_DONE\n    s_and_b64               exec, exec, vcc\n\n\n    FLAT_LOAD_UBYTE         v1, v[2:3]\n    s_waitcnt               vmcnt(0)\n    V_ADD_CO_U32            v2, v2, s24\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n\n    FLAT_STORE_BYTE         v[4:5], v1\n    V_ADD_CO_U32            v4, v4, s24\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n    s_branch                L_COPY_ALIGNED_PHASE_1_LOOP\n\n  L_COPY_ALIGNED_PHASE_1_DONE:\n\n    s_mov_b64               exec, 0xFFFFFFFFFFFFFFFF\n\n.if kCopyAlignedVecWidth == 4\n      s_lshl_b32            s25, s24, 0x4\n  .else\n      s_lshl_b32            s25, s24, 0x2\n  .endif\n\n  .if kCopyAlignedVecWidth == 4\n    v_lshlrev_b32          v1, 0x4, v0\n  .else\n    v_lshlrev_b32          v1, 0x2, v0\n  .endif\n\n\n    v_mov_b32               v3, s9\n    V_ADD_CO_U32            v2, v1, s8\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n    v_mov_b32               v5, s11\n    V_ADD_CO_U32            v4, v1, s10\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n  L_COPY_ALIGNED_PHASE_2_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[12:13]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_2_DONE\n\n.macro mCopyAlignedPhase2Load iter iter_end\n    .if kCopyAlignedVecWidth == 4\n      flat_load_dwordx4    v[8 + (\\iter * 4):8 + (\\iter * 4) + 3], v[2:3]\n    .else\n      flat_load_dword      v[8 + \\iter], v[2:3]\n    .endif\n\n    V_ADD_CO_U32           v2, v2, s25\n    V_ADD_CO_CI_U32        v3, v3, 0x0\n\n    .if (\\iter_end - \\iter)\n      mCopyAlignedPhase2Load (\\iter + 1), \\iter_end\n    .endif\n.endm\n\nmCopyAlignedPhase2Load 0, (kCopyAlignedUnroll - 1)\n\n  s_waitcnt                vmcnt(0)\n\n.macro mCopyAlignedPhase2Store iter iter_end\n    .if kCopyAlignedVecWidth == 4\n      flat_store_dwordX4   v[4:5], v[8 + (\\iter * 4):8 + (\\iter * 4) + 3]\n    .else\n      flat_store_dword     v[4:5], v[8 + \\iter]\n    .endif\n\n\tV_ADD_CO_U32         v4, v4, s25\n\tV_ADD_CO_CI_U32      v5, v5, 0x0\n\n\n    .if (\\iter_end - \\iter)\n      mCopyAlignedPhase2Store (\\iter + 1), \\iter_end\n    .endif\n.endm\n\nmCopyAlignedPhase2Store 0, (kCopyAlignedUnroll - 1)\n\n  s_branch                L_COPY_ALIGNED_PHASE_2_LOOP\n\n  L_COPY_ALIGNED_PHASE_2_DONE:\n\n    s_lshl_b32              s25, s24, 0x2\n\n    v_lshlrev_b32           v1, 0x2, v0\n    v_mov_b32               v3, s13\n    V_ADD_CO_U32            v2, v1, s12\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n    v_mov_b32               v5, s15\n    V_ADD_CO_U32            v4, v1, s14\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n  L_COPY_ALIGNED_PHASE_3_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[16:17]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_3_DONE\n    s_and_b64               exec, exec, vcc\n\n\n    FLAT_LOAD_DWORD         v1, v[2:3]\n    V_ADD_CO_U32            v2, v2, s25\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n    s_waitcnt               vmcnt(0)\n\n\n    flat_store_dword        v[4:5], v1\n    V_ADD_CO_U32            v4, v4, s25\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n    s_branch                L_COPY_ALIGNED_PHASE_3_LOOP\n\n  L_COPY_ALIGNED_PHASE_3_DONE:\n\n    s_mov_b64               exec, 0xFFFFFFFFFFFFFFFF\n\n    v_mov_b32               v3, s17\n    V_ADD_CO_U32            v2, v0, s16\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n    v_mov_b32               v5, s19\n    V_ADD_CO_U32            v4, v0, s18\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n    V_CMP_LT_U64            v[2:3], s[20:21]\n    s_cbranch_vccz          L_COPY_ALIGNED_PHASE_4_DONE\n    s_and_b64               exec, exec, vcc\n\n    FLAT_LOAD_UBYTE         v1, v[2:3]\n    s_waitcnt               vmcnt(0)\n\n    FLAT_STORE_BYTE         v[4:5], v1\n\n  L_COPY_ALIGNED_PHASE_4_DONE:\n    s_endpgm\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/blit_shaders/blit_copyMisaligned.s",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//   \tAMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//     www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////////\n\n.text\n\n.macro V_ADD_CO_U32 vdst, src0, vsrc1\n  .if (.amdgcn.gfx_generation_number >= 10)\n\t\t v_add_co_u32        \\vdst, vcc_lo, \\src0, \\vsrc1\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_add_co_u32        \\vdst, vcc, \\src0, \\vsrc1\n\t.else\n\t\tv_add_u32           \\vdst, vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n\n.macro V_ADD_CO_CI_U32 vdst, src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_add_co_ci_u32     \\vdst, vcc_lo, \\src0, \\vsrc1, vcc_lo\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_addc_co_u32       \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.else\n\t\tv_addc_u32          \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.endif\n.endm\n\n.macro V_CMP_LT_U64 src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_cmp_lt_u64        vcc_lo, \\src0, \\vsrc1\n\t.else\n\t\tv_cmp_lt_u64        vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n.set kCopyMisalignedUnroll, 4\n.set kCopyMisalignedNumSGPRs, 17\n.set kCopyMisalignedNumVGPRs, 6 + kCopyMisalignedUnroll\n.set CopyMisalignedRsrc1SGPRs , (kCopyMisalignedNumSGPRs - 1) / 8\n\n.if CopyMisalignedRsrc1SGPRs  < 0\n    .set CopyMisalignedRsrc1SGPRs , 0\n.endif\n\n.set CopyMisalignedRsrc1VGPRs , (kCopyMisalignedNumVGPRs - 1) / 4\n.if CopyMisalignedRsrc1VGPRs  < 0\n    .set CopyMisalignedRsrc1VGPRs , 0\n.endif\n\n.p2align 8\n\nCopyMisaligned:\n  compute_pgm_rsrc1_sgprs = CopyMisalignedRsrc1SGPRs\n  compute_pgm_rsrc1_vgprs = CopyMisalignedRsrc1VGPRs\n  compute_pgm_rsrc2_user_sgpr = 2\n  compute_pgm_rsrc2_tgid_x_en = 1\n  enable_sgpr_kernarg_segment_ptr = 1\n\n  s_load_dwordx4  s[4:7], s[0:1], 0x0\n  s_load_dwordx4  s[8:11], s[0:1], 0x10\n  s_load_dwordx4  s[12:15], s[0:1], 0x20\n  s_load_dword    s16, s[0:1], 0x30\n  s_waitcnt             lgkmcnt(0)\n\n  .if (.amdgcn.gfx_generation_number == 12)\n    s_lshl_b32          s2, ttmp9, 0x6\n  .else\n    s_lshl_b32          s2, s2, 0x6\n  .endif\n\n  V_ADD_CO_U32          v0, s2, v0\n\n  v_mov_b32             v3, s5\n  V_ADD_CO_U32          v2, v0, s4\n  V_ADD_CO_CI_U32       v3, v3, 0x0\n\n  v_mov_b32              v5, s7\n  V_ADD_CO_U32           v4, v0, s6\n  V_ADD_CO_CI_U32        v5, v5, 0x0\n\n  L_COPY_MISALIGNED_PHASE_1_LOOP:\n\n  V_CMP_LT_U64          v[2:3], s[8:9]\n  s_cbranch_vccz        L_COPY_MISALIGNED_PHASE_1_DONE\n\n\n  .macro mCopyMisalignedPhase1Load iter iter_end\n    flat_load_ubyte     v[6 + \\iter], v[2:3]\n    V_ADD_CO_U32        v2, v2, s16\n    V_ADD_CO_CI_U32     v3, v3, 0x0\n\n    .if (\\iter_end - \\iter)\n      mCopyMisalignedPhase1Load (\\iter + 1), \\iter_end\n    .endif\n  .endm\n\n  mCopyMisalignedPhase1Load 0, (kCopyMisalignedUnroll - 1)\n\n  s_waitcnt                vmcnt(0)\n\n  .macro mCopyMisalignedPhase1Store iter iter_end\n    flat_store_byte        v[4:5], v[6 + \\iter]\n    V_ADD_CO_U32           v4, v4, s16\n    V_ADD_CO_CI_U32        v5, v5, 0x0\n\n    .if (\\iter_end - \\iter)\n      mCopyMisalignedPhase1Store (\\iter + 1), \\iter_end\n    .endif\n  .endm\n\n    mCopyMisalignedPhase1Store 0, (kCopyMisalignedUnroll - 1)\n\n    s_branch                L_COPY_MISALIGNED_PHASE_1_LOOP\n\n  L_COPY_MISALIGNED_PHASE_1_DONE:\n\n    v_mov_b32               v3, s9\n    V_ADD_CO_U32            v2, v0, s8\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n    v_mov_b32               v5, s11\n    V_ADD_CO_U32            v4, v0, s10\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n  L_COPY_MISALIGNED_PHASE_2_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[12:13]\n    s_cbranch_vccz          L_COPY_MISALIGNED_PHASE_2_DONE\n    s_and_b64               exec, exec, vcc\n\n\n    flat_load_ubyte         v1, v[2:3]\n    V_ADD_CO_U32            v2, v2, s16\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n    s_waitcnt               vmcnt(0)\n\n    flat_store_byte         v[4:5], v1\n    V_ADD_CO_U32            v4, v4, s16\n    V_ADD_CO_CI_U32         v5, v5, 0x0\n\n    s_branch                L_COPY_MISALIGNED_PHASE_2_LOOP\n\n  L_COPY_MISALIGNED_PHASE_2_DONE:\n    s_endpgm\n\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/blit_shaders/blit_fill.s",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n////////////////////////////////////////////////////////////////////////////////////\n\n.text\n\n.macro V_ADD_CO_U32 vdst, src0, vsrc1\n  .if (.amdgcn.gfx_generation_number >= 10)\n\t\t v_add_co_u32        \\vdst, vcc_lo, \\src0, \\vsrc1\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_add_co_u32        \\vdst, vcc, \\src0, \\vsrc1\n\t.else\n\t\tv_add_u32           \\vdst, vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n\n.macro V_ADD_CO_CI_U32 vdst, src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_add_co_ci_u32     \\vdst, vcc_lo, \\src0, \\vsrc1, vcc_lo\n\t.elseif (.amdgcn.gfx_generation_number >= 9)\n\t\tv_addc_co_u32       \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.else\n\t\tv_addc_u32          \\vdst, vcc, \\src0, \\vsrc1, vcc\n\t.endif\n.endm\n\n.macro V_CMP_LT_U64 src0, vsrc1\n\t.if (.amdgcn.gfx_generation_number >= 10)\n\t\tv_cmp_lt_u64        vcc_lo, \\src0, \\vsrc1\n\t.else\n\t\tv_cmp_lt_u64        vcc, \\src0, \\vsrc1\n\t.endif\n.endm\n\n.set kFillVecWidth, 4\n.set kFillUnroll, 1\n\n.set kFillNumSGPRs, 13\n.set kFillNumVGPRs, 4 + kFillUnroll\n\n.set FillRsrc1SGPRs , (kFillNumSGPRs - 1) / 8\n  .if FillRsrc1SGPRs  < 0\n    .set FillRsrc1SGPRs , 0\n  .endif\n\n.set FillRsrc1VGPRs , (kFillNumVGPRs - 1) / 4\n  .if FillRsrc1VGPRs  < 0\n    .set FillRsrc1VGPRs , 0\n  .endif\n\n.p2align 8\n\nFill:\n\n    compute_pgm_rsrc1_sgprs = FillRsrc1SGPRs\n    compute_pgm_rsrc1_vgprs = FillRsrc1VGPRs\n    compute_pgm_rsrc2_user_sgpr = 2\n    compute_pgm_rsrc2_tgid_x_en = 1\n    enable_sgpr_kernarg_segment_ptr = 1\n\n    s_load_dwordx4  s[4:7], s[0:1], 0x0\n    s_load_dwordx4  s[8:11], s[0:1], 0x10\n    s_waitcnt       lgkmcnt(0)\n\n   .if (.amdgcn.gfx_generation_number == 12)\n     s_lshl_b32      s2, ttmp9, 0x6\n   .else\n     s_lshl_b32      s2, s2, 0x6\n   .endif\n\n    V_ADD_CO_U32     v0, s2, v0\n\n.macro mFillPattern iter iter_end\n    v_mov_b32              v[4 + \\iter], s10\n\n    .if (\\iter_end - \\iter)\n      mFillPattern (\\iter + 1), \\iter_end\n    .endif\n  .endm\n\n  mFillPattern 0, (kFillVecWidth - 1)\n\n  .if kFillVecWidth == 4\n      s_lshl_b32            s12, s11, 0x4\n  .else\n      s_lshl_b32            s12, s11, 0x2\n  .endif\n\n\n  .if kFillVecWidth == 4\n    v_lshlrev_b32          v1, 0x4, v0\n  .else\n    v_lshlrev_b32          v1, 0x2, v0\n  .endif\n\n   v_mov_b32               v3, s5\n   V_ADD_CO_U32            v2, v1, s4\n   V_ADD_CO_CI_U32         v3, v3, 0x0\n\n  L_FILL_PHASE_1_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[6:7]\n    s_cbranch_vccz          L_FILL_PHASE_1_DONE\n\n.macro mFillPhase1 iter iter_end\n    .if kFillVecWidth == 4\n      flat_store_dwordx4   v[2:3], v[4:7]\n    .else\n      flat_store_dword     v[2:3], v4\n    .endif\n\n     V_ADD_CO_U32          v2, v2, s12\n     V_ADD_CO_CI_U32       v3, v3, 0x0\n\n    .if \\iter < \\iter_end\n      mFillPhase1 (\\iter + 1), \\iter_end\n    .endif\n.endm\n\nmFillPhase1 0, kFillUnroll - 1\n\n  s_branch                L_FILL_PHASE_1_LOOP\n\n  L_FILL_PHASE_1_DONE:\n\n    s_lshl_b32              s12, s11, 0x2\n\n    v_lshlrev_b32           v1, 0x2, v0\n    v_mov_b32               v3, s7\n    V_ADD_CO_U32            v2, v1, s6\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n  L_FILL_PHASE_2_LOOP:\n\n    V_CMP_LT_U64            v[2:3], s[8:9]\n    s_cbranch_vccz          L_FILL_PHASE_2_DONE\n    s_and_b64               exec, exec, vcc\n\n\n    flat_store_dword        v[2:3], v4\n    V_ADD_CO_U32            v2, v2, s12\n    V_ADD_CO_CI_U32         v3, v3, 0x0\n\n    s_branch                L_FILL_PHASE_2_LOOP\n\n  L_FILL_PHASE_2_DONE:\n    s_endpgm\n\n\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/blit_shaders/create_blit_shader_header.sh",
    "content": "#!/bin/bash -e\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\namd_gpu_shaders=\"$1\"\n\nif ! command -v xxd >/dev/null\nthen\n    echo \"xxd not found!\"\n    exit 1\nfi\n\n# Create the file in a temporary location and then move it in atomically\n{\ncat <<EOF\n//==============================================================================\n//  This file is automatically generated during build process, don't modify it\n//==============================================================================\n\nnamespace rocr {\nnamespace AMD {\n\nEOF\n\nshift\nfor file in \"$@\"\ndo\nxxd -i $file\n    echo -e '\\n'\ndone\n\ncat <<EOF\n} // namespace AMD\n} // namespace rocr\n\nEOF\n\n} > \"$amd_gpu_shaders\"\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/cache.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/cache.h\"\n#include \"assert.h\"\n\nnamespace rocr {\nnamespace core {\n\nhsa_status_t Cache::GetInfo(hsa_cache_info_t attribute, void* value) {\n  switch (attribute) {\n    case HSA_CACHE_INFO_NAME_LENGTH:\n      *(uint32_t*)value = name_.size();\n      break;\n    case HSA_CACHE_INFO_NAME:\n      *(const char**)value = name_.c_str();\n      break;\n    case HSA_CACHE_INFO_LEVEL:\n      *(uint8_t*)value = level_;\n      break;\n    case HSA_CACHE_INFO_SIZE:\n      *(uint32_t*)value = size_;\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/default_signal.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/default_signal.h\"\n\n#if defined(__i386__) || defined(__x86_64__)\n#include <mwaitxintrin.h>\n#define MWAITX_ECX_TIMER_ENABLE 0x2  // BIT(1)\n#endif\n\nnamespace rocr {\nnamespace core {\n\nBusyWaitSignal::BusyWaitSignal(SharedSignal* abi_block, bool enableIPC)\n    : Signal(abi_block, enableIPC) {\n  signal_.kind = AMD_SIGNAL_KIND_USER;\n  signal_.event_mailbox_ptr = uint64_t(NULL);\n}\n\nhsa_signal_value_t BusyWaitSignal::LoadRelaxed() {\n  return hsa_signal_value_t(\n      atomic::Load(&signal_.value, std::memory_order_relaxed));\n}\n\nhsa_signal_value_t BusyWaitSignal::LoadAcquire() {\n  return hsa_signal_value_t(\n      atomic::Load(&signal_.value, std::memory_order_acquire));\n}\n\nvoid BusyWaitSignal::StoreRelaxed(hsa_signal_value_t value) {\n  atomic::Store(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::StoreRelease(hsa_signal_value_t value) {\n  atomic::Store(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nhsa_signal_value_t BusyWaitSignal::WaitRelaxed(hsa_signal_condition_t condition,\n                                               hsa_signal_value_t compare_value, uint64_t timeout,\n                                               hsa_wait_state_t wait_hint) {\n  Retain();\n  MAKE_SCOPE_GUARD([&]() { Release(); });\n\n  waiting_++;\n  MAKE_SCOPE_GUARD([&]() { waiting_--; });\n\n  const uint32_t &signal_abort_timeout =\n    core::Runtime::runtime_singleton_->flag().signal_abort_timeout();\n\n  const timer::fast_clock::time_point start_time = timer::fast_clock::now();\n  const timer::fast_clock::duration fast_timeout = timer::GetFastTimeout(timeout);\n\n  while (true) {\n    if (!IsValid()) return 0;\n\n    int64_t value = atomic::Load(&signal_.value, std::memory_order_relaxed);\n\n    if (CheckSignalCondition(value, condition, compare_value)) {\n      return value;\n    }\n\n    if (timer::fast_clock::now() - start_time > fast_timeout) {\n      return value;\n    }\n\n    timer::CheckAbortTimeout(start_time, signal_abort_timeout);\n\n    if (g_use_mwaitx) {\n      // Use timer-enabled mwaitx for busy waiting\n      timer::DoMwaitx(const_cast<int64_t*>(&signal_.value), 60000, true);\n    }\n  }\n}\n\nhsa_signal_value_t BusyWaitSignal::WaitAcquire(hsa_signal_condition_t condition,\n                                               hsa_signal_value_t compare_value, uint64_t timeout,\n                                               hsa_wait_state_t wait_hint) {\n  hsa_signal_value_t ret =\n      WaitRelaxed(condition, compare_value, timeout, wait_hint);\n  std::atomic_thread_fence(std::memory_order_acquire);\n  return ret;\n}\n\nvoid BusyWaitSignal::AndRelaxed(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::AndAcquire(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_acquire);\n}\n\nvoid BusyWaitSignal::AndRelease(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nvoid BusyWaitSignal::AndAcqRel(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n}\n\nvoid BusyWaitSignal::OrRelaxed(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::OrAcquire(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_acquire);\n}\n\nvoid BusyWaitSignal::OrRelease(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nvoid BusyWaitSignal::OrAcqRel(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n}\n\nvoid BusyWaitSignal::XorRelaxed(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::XorAcquire(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_acquire);\n}\n\nvoid BusyWaitSignal::XorRelease(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nvoid BusyWaitSignal::XorAcqRel(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n}\n\nvoid BusyWaitSignal::AddRelaxed(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::AddAcquire(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_acquire);\n}\n\nvoid BusyWaitSignal::AddRelease(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nvoid BusyWaitSignal::AddAcqRel(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n}\n\nvoid BusyWaitSignal::SubRelaxed(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_relaxed);\n}\n\nvoid BusyWaitSignal::SubAcquire(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_acquire);\n}\n\nvoid BusyWaitSignal::SubRelease(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_release);\n}\n\nvoid BusyWaitSignal::SubAcqRel(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n}\n\nhsa_signal_value_t BusyWaitSignal::ExchRelaxed(hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Exchange(&signal_.value, int64_t(value),\n                                             std::memory_order_relaxed));\n}\n\nhsa_signal_value_t BusyWaitSignal::ExchAcquire(hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Exchange(&signal_.value, int64_t(value),\n                                             std::memory_order_acquire));\n}\n\nhsa_signal_value_t BusyWaitSignal::ExchRelease(hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Exchange(&signal_.value, int64_t(value),\n                                             std::memory_order_release));\n}\n\nhsa_signal_value_t BusyWaitSignal::ExchAcqRel(hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Exchange(&signal_.value, int64_t(value),\n                                             std::memory_order_acq_rel));\n}\n\nhsa_signal_value_t BusyWaitSignal::CasRelaxed(hsa_signal_value_t expected,\n                                              hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Cas(&signal_.value, int64_t(value),\n                                        int64_t(expected),\n                                        std::memory_order_relaxed));\n}\n\nhsa_signal_value_t BusyWaitSignal::CasAcquire(hsa_signal_value_t expected,\n                                              hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Cas(&signal_.value, int64_t(value),\n                                        int64_t(expected),\n                                        std::memory_order_acquire));\n}\n\nhsa_signal_value_t BusyWaitSignal::CasRelease(hsa_signal_value_t expected,\n                                              hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Cas(&signal_.value, int64_t(value),\n                                        int64_t(expected),\n                                        std::memory_order_release));\n}\n\nhsa_signal_value_t BusyWaitSignal::CasAcqRel(hsa_signal_value_t expected,\n                                             hsa_signal_value_t value) {\n  return hsa_signal_value_t(atomic::Cas(&signal_.value, int64_t(value),\n                                        int64_t(expected),\n                                        std::memory_order_acq_rel));\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/host_queue.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/host_queue.h\"\n\n#include \"core/inc/runtime.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\nnamespace core {\n\nHostQueue::HostQueue(core::SharedQueue* shared_queue, hsa_region_t region, uint32_t ring_size,\n                     hsa_queue_type32_t type, uint32_t features, hsa_signal_t doorbell_signal)\n    : Queue(shared_queue, 0), size_(ring_size) {\n  HSA::hsa_memory_register(this, sizeof(HostQueue));\n  MAKE_NAMED_SCOPE_GUARD(registerGuard,\n                         [&]() { HSA::hsa_memory_deregister(this, sizeof(HostQueue)); });\n\n  const size_t queue_buffer_size = size_ * sizeof(AqlPacket);\n  if (HSA_STATUS_SUCCESS !=\n      HSA::hsa_memory_allocate(region, queue_buffer_size, &ring_)) {\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_OUT_OF_RESOURCES, \"Host queue buffer alloc failed\\n\");\n  }\n  MAKE_NAMED_SCOPE_GUARD(bufferGuard, [&]() { HSA::hsa_memory_free(&ring_); });\n\n  assert(IsMultipleOf(ring_, kRingAlignment));\n  assert(ring_ != NULL);\n\n  // Fill the ring buffer with invalid packet headers.\n  // Leave packet content uninitialized to help track errors.\n  for (uint32_t pkt_id = 0; pkt_id < size_; pkt_id++) {\n    (((AqlPacket*)ring_)[pkt_id]).dispatch.header = HSA_PACKET_TYPE_INVALID;\n  }\n\n  amd_queue_.hsa_queue.base_address = ring_;\n  amd_queue_.hsa_queue.size = size_;\n  amd_queue_.hsa_queue.doorbell_signal = doorbell_signal;\n  amd_queue_.hsa_queue.id = this->GetQueueId();\n  amd_queue_.hsa_queue.type = type;\n  amd_queue_.hsa_queue.features = features;\n#ifdef HSA_LARGE_MODEL\n  AMD_HSA_BITS_SET(\n      amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_IS_PTR64, 1);\n#else\n  AMD_HSA_BITS_SET(\n      amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_IS_PTR64, 0);\n#endif\n  amd_queue_.write_dispatch_id = amd_queue_.read_dispatch_id = 0;\n  AMD_HSA_BITS_SET(\n      amd_queue_.queue_properties, AMD_QUEUE_PROPERTIES_ENABLE_PROFILING, 0);\n\n  bufferGuard.Dismiss();\n  registerGuard.Dismiss();\n}\n\nHostQueue::~HostQueue() {\n  HSA::hsa_memory_free(shared_queue_);\n  HSA::hsa_memory_free(ring_);\n  HSA::hsa_memory_deregister(this, sizeof(HostQueue));\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/hsa.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA C to C++ interface implementation.\n// This file does argument checking and conversion to C++.\n#include <cstdio>\n#include <cstring>\n#include <string>\n#include <sys/types.h>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/agent.h\"\n#include \"core/inc/host_queue.h\"\n#include \"core/inc/isa.h\"\n#include \"core/inc/memory_region.h\"\n#include \"core/inc/queue.h\"\n#include \"core/inc/signal.h\"\n#include \"core/inc/cache.h\"\n#include \"core/inc/amd_elf_image.hpp\"\n#include \"core/inc/amd_hsa_loader.hpp\"\n#include \"core/inc/amd_loader_context.hpp\"\n#include \"core/inc/hsa_ven_amd_loader_impl.h\"\n#include \"inc/hsa_ven_amd_aqlprofile.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n\nnamespace rocr {\n\nusing namespace amd::hsa;\n\ntemplate <class T>\nstruct ValidityError;\ntemplate <> struct ValidityError<core::Signal*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_SIGNAL };\n};\ntemplate <> struct ValidityError<core::SignalGroup*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP };\n};\ntemplate <> struct ValidityError<core::Agent*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_AGENT };\n};\ntemplate <> struct ValidityError<core::MemoryRegion*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_REGION };\n};\ntemplate <> struct ValidityError<core::Queue*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_QUEUE };\n};\ntemplate <> struct ValidityError<core::Cache*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_CACHE };\n};\ntemplate <> struct ValidityError<core::Isa*> {\n  enum { kValue = HSA_STATUS_ERROR_INVALID_ISA };\n};\ntemplate <class T> struct ValidityError<const T*> {\n  enum { kValue = ValidityError<T*>::kValue };\n};\n\n#define IS_BAD_PTR(ptr)                                                        \\\n  do {                                                                         \\\n    if ((ptr) == nullptr) return HSA_STATUS_ERROR_INVALID_ARGUMENT;            \\\n  } while (false)\n#define IS_BAD_PROFILE(profile)                                                \\\n  do {                                                                         \\\n    if (profile != HSA_PROFILE_BASE &&                                         \\\n        profile != HSA_PROFILE_FULL) {                                         \\\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                \\\n    }                                                                          \\\n  } while (false)\n#define IS_BAD_EXECUTABLE_STATE(executable_state)                              \\\n  do {                                                                         \\\n    if (executable_state != HSA_EXECUTABLE_STATE_FROZEN &&                     \\\n        executable_state != HSA_EXECUTABLE_STATE_UNFROZEN) {                   \\\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                \\\n    }                                                                          \\\n  } while (false)\n#define IS_BAD_ROUNDING_MODE(rounding_mode)                                    \\\n  do {                                                                         \\\n    if (rounding_mode != HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT &&            \\\n        rounding_mode != HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO &&               \\\n        rounding_mode != HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR) {               \\\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                \\\n    }                                                                          \\\n  } while (false)\n#define IS_BAD_FP_TYPE(fp_type)                                                \\\n  do {                                                                         \\\n    if (fp_type != HSA_FP_TYPE_16 &&                                           \\\n        fp_type != HSA_FP_TYPE_32 &&                                           \\\n        fp_type != HSA_FP_TYPE_64) {                                           \\\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                \\\n    }                                                                          \\\n  } while (false)\n#define IS_BAD_FLUSH_MODE(flush_mode)                                          \\\n  do {                                                                         \\\n    if (flush_mode != HSA_FLUSH_MODE_FTZ &&                                    \\\n        flush_mode != HSA_FLUSH_MODE_NON_FTZ) {                                \\\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                \\\n    }                                                                          \\\n  } while (false)\n#define IS_VALID(ptr)                                                          \\\n  do {                                                                         \\\n    if (((ptr) == NULL) || !((ptr)->IsValid()))                                \\\n      return hsa_status_t(ValidityError<decltype(ptr)>::kValue);               \\\n  } while (false)\n#define CHECK_STATUS(status)                                                   \\\n  do {                                                                         \\\n    if ((status) != HSA_STATUS_SUCCESS) return status;                         \\\n  } while (false)\n#define CHECK_ALLOC(ptr)                                                       \\\n  do {                                                                         \\\n    if ((ptr) == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;            \\\n  } while (false)\n#define IS_OPEN()                                                              \\\n  do {                                                                         \\\n    if (!core::Runtime::runtime_singleton_->IsOpen())                          \\\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;                                 \\\n  } while (false)\n\ntemplate <class T>\nstatic __forceinline bool IsValid(T* ptr) {\n  return (ptr == NULL) ? NULL : ptr->IsValid();\n}\n\nnamespace AMD {\nhsa_status_t handleException();\n\ntemplate <class T> static __forceinline T handleExceptionT() {\n  handleException();\n  abort();\n  return T();\n}\n}   // namespace amd\n\n#define TRY try {\n#define CATCH } catch(...) { return AMD::handleException(); }\n#define CATCHRET(RETURN_TYPE) } catch(...) { return AMD::handleExceptionT<RETURN_TYPE>(); }\n\n//-----------------------------------------------------------------------------\n// Basic Checks\n//-----------------------------------------------------------------------------\nstatic_assert(sizeof(hsa_barrier_and_packet_t) ==\n                  sizeof(hsa_kernel_dispatch_packet_t),\n              \"AQL packet definitions have wrong sizes!\");\nstatic_assert(sizeof(hsa_barrier_and_packet_t) ==\n                  sizeof(hsa_agent_dispatch_packet_t),\n              \"AQL packet definitions have wrong sizes!\");\nstatic_assert(sizeof(hsa_barrier_and_packet_t) == 64,\n              \"AQL packet definitions have wrong sizes!\");\nstatic_assert(sizeof(hsa_barrier_and_packet_t) ==\n                  sizeof(hsa_barrier_or_packet_t),\n              \"AQL packet definitions have wrong sizes!\");\n#ifdef HSA_LARGE_MODEL\nstatic_assert(sizeof(void*) == 8, \"HSA_LARGE_MODEL is set incorrectly!\");\n#else\nstatic_assert(sizeof(void*) == 4, \"HSA_LARGE_MODEL is set incorrectly!\");\n#endif\n\n#if !defined(HSA_LARGE_MODEL) || !defined(__linux__)\n// static_assert(false, \"Only HSA_LARGE_MODEL (64bit mode) and Linux supported.\");\n#endif\n\nnamespace HSA {\n\n//---------------------------------------------------------------------------//\n//  Init/Shutdown routines\n//---------------------------------------------------------------------------//\nhsa_status_t hsa_init() {\n  TRY;\n  return core::Runtime::runtime_singleton_->Acquire();\n  CATCH;\n}\n\nhsa_status_t hsa_shut_down() {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->Release();\n  CATCH;\n}\n\n//---------------------------------------------------------------------------//\n//  System\n//---------------------------------------------------------------------------//\nhsa_status_t\n    hsa_system_get_info(hsa_system_info_t attribute, void* value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n  return core::Runtime::runtime_singleton_->GetSystemInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_extension_get_name(uint16_t extension, const char** name) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(name);\n  switch (extension) {\n    case HSA_EXTENSION_FINALIZER:\n      *name = \"HSA_EXTENSION_FINALIZER\";\n      break;\n    case HSA_EXTENSION_IMAGES:\n      *name = \"HSA_EXTENSION_IMAGES\";\n      break;\n    case HSA_EXTENSION_PERFORMANCE_COUNTERS:\n      *name = \"HSA_EXTENSION_PERFORMANCE_COUNTERS\";\n      break;\n    case HSA_EXTENSION_PROFILING_EVENTS:\n      *name = \"HSA_EXTENSION_PROFILING_EVENTS\";\n      break;\n    case HSA_EXTENSION_AMD_PROFILER:\n      *name = \"HSA_EXTENSION_AMD_PROFILER\";\n      break;\n    case HSA_EXTENSION_AMD_LOADER:\n      *name = \"HSA_EXTENSION_AMD_LOADER\";\n      break;\n    case HSA_EXTENSION_AMD_AQLPROFILE:\n      *name = \"HSA_EXTENSION_AMD_AQLPROFILE\";\n      break;\n    default:\n      *name = \"HSA_EXTENSION_INVALID\";\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t\n    hsa_system_extension_supported(uint16_t extension, uint16_t version_major,\n                                   uint16_t version_minor, bool* result) {\n  TRY;\n  IS_OPEN();\n\n  if ((extension > HSA_EXTENSION_STD_LAST &&\n       (extension < HSA_AMD_FIRST_EXTENSION || extension > HSA_AMD_LAST_EXTENSION)) ||\n      result == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  *result = false;\n\n  if (extension == HSA_EXTENSION_PERFORMANCE_COUNTERS ||\n      extension == HSA_EXTENSION_PROFILING_EVENTS)\n    return HSA_STATUS_SUCCESS;\n\n  uint16_t system_version_major = 0;\n  hsa_status_t status = core::Runtime::runtime_singleton_->GetSystemInfo(\n      HSA_SYSTEM_INFO_VERSION_MAJOR, &system_version_major);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  if (version_major <= system_version_major) {\n    uint16_t system_version_minor = 0;\n    if (version_minor <= system_version_minor) {\n      *result = true;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_system_major_extension_supported(uint16_t extension, uint16_t version_major,\n                                                  uint16_t* version_minor, bool* result) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(version_minor);\n  IS_BAD_PTR(result);\n\n  if ((extension == HSA_EXTENSION_IMAGES) && (version_major == 1)) {\n    *version_minor = 0;\n    *result = true;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if ((extension == HSA_EXTENSION_FINALIZER) && (version_major == 1)) {\n    *version_minor = 0;\n    *result = true;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if ((extension == HSA_EXTENSION_AMD_LOADER) && (version_major == 1)) {\n    *version_minor = 0;\n    *result = true;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if ((extension == HSA_EXTENSION_AMD_AQLPROFILE) && (version_major == 1)) {\n    *version_minor = 0;\n    *result = true;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  *result = false;\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nstatic size_t get_extension_table_length(uint16_t extension, uint16_t major, uint16_t minor) {\n  // Table to convert from major/minor to major/length\n  struct sizes_t {\n    std::string name;\n    size_t size;\n  };\n  static sizes_t sizes[] = {\n      {\"hsa_ext_images_1_00_pfn_t\", sizeof(hsa_ext_images_1_00_pfn_t)},\n      {\"hsa_ext_finalizer_1_00_pfn_t\", sizeof(hsa_ext_finalizer_1_00_pfn_t)},\n      {\"hsa_ven_amd_loader_1_00_pfn_t\", sizeof(hsa_ven_amd_loader_1_00_pfn_t)},\n      {\"hsa_ven_amd_loader_1_01_pfn_t\", sizeof(hsa_ven_amd_loader_1_01_pfn_t)},\n      {\"hsa_ven_amd_loader_1_02_pfn_t\", sizeof(hsa_ven_amd_loader_1_02_pfn_t)},\n      {\"hsa_ven_amd_loader_1_03_pfn_t\", sizeof(hsa_ven_amd_loader_1_03_pfn_t)},\n      {\"hsa_ven_amd_aqlprofile_1_00_pfn_t\", sizeof(hsa_ven_amd_aqlprofile_1_00_pfn_t)},\n      {\"hsa_ven_amd_pc_sampling_1_00_pfn_t\", sizeof(hsa_ven_amd_pc_sampling_1_00_pfn_t)}};\n  static const size_t num_tables = sizeof(sizes) / sizeof(sizes_t);\n\n  if (minor > 99) return 0;\n\n  std::string name;\n\n  switch (extension) {\n    case HSA_EXTENSION_FINALIZER:\n      name = \"hsa_ext_finalizer_\";\n      break;\n    case HSA_EXTENSION_IMAGES:\n      name = \"hsa_ext_images_\";\n      break;\n    // case HSA_EXTENSION_PERFORMANCE_COUNTERS:\n    //  name = \"hsa_ext_perf_counter_\";\n    //  break;\n    // case HSA_EXTENSION_PROFILING_EVENTS:\n    //  name = \"hsa_ext_profiling_event_\";\n    //  break;\n    // case HSA_EXTENSION_AMD_PROFILER:\n    //  name = \"hsa_ven_amd_profiler_\";\n    //  break;\n    case HSA_EXTENSION_AMD_LOADER:\n      name = \"hsa_ven_amd_loader_\";\n      break;\n    case HSA_EXTENSION_AMD_AQLPROFILE:\n      name = \"hsa_ven_amd_aqlprofile_\";\n      break;\n    case HSA_EXTENSION_AMD_PC_SAMPLING:\n      name = \"hsa_ven_amd_pc_sampling_\";\n      break;\n    default:\n      return 0;\n  }\n\n  char buff[6];\n  sprintf(buff, \"%02u\", minor);\n  name += std::to_string(major) + \"_\" + buff + \"_pfn_t\";\n\n  for (size_t i = 0; i < num_tables; i++) {\n    if (sizes[i].name == name) return sizes[i].size;\n  }\n  return 0;\n}\n\nhsa_status_t hsa_system_get_extension_table(uint16_t extension, uint16_t version_major,\n                                            uint16_t version_minor, void* table) {\n  TRY;\n  return HSA::hsa_system_get_major_extension_table(\n      extension, version_major, get_extension_table_length(extension, version_major, version_minor),\n      table);\n  CATCH;\n}\n\nhsa_status_t hsa_system_get_major_extension_table(uint16_t extension, uint16_t version_major,\n                                                  size_t table_length, void* table) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(table);\n\n  if (table_length == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  if (extension == HSA_EXTENSION_IMAGES) {\n    if (version_major !=\n        core::Runtime::runtime_singleton_->extensions_.image_api.version.major_id) {\n      return HSA_STATUS_ERROR;\n    }\n\n    hsa_ext_images_1_pfn_t ext_table;\n    ext_table.hsa_ext_image_clear = hsa_ext_image_clear;\n    ext_table.hsa_ext_image_copy = hsa_ext_image_copy;\n    ext_table.hsa_ext_image_create = hsa_ext_image_create;\n    ext_table.hsa_ext_image_data_get_info = hsa_ext_image_data_get_info;\n    ext_table.hsa_ext_image_destroy = hsa_ext_image_destroy;\n    ext_table.hsa_ext_image_export = hsa_ext_image_export;\n    ext_table.hsa_ext_image_get_capability = hsa_ext_image_get_capability;\n    ext_table.hsa_ext_image_import = hsa_ext_image_import;\n    ext_table.hsa_ext_sampler_create = hsa_ext_sampler_create;\n    ext_table.hsa_ext_sampler_destroy = hsa_ext_sampler_destroy;\n    ext_table.hsa_ext_image_get_capability_with_layout = hsa_ext_image_get_capability_with_layout;\n    ext_table.hsa_ext_image_data_get_info_with_layout = hsa_ext_image_data_get_info_with_layout;\n    ext_table.hsa_ext_image_create_with_layout = hsa_ext_image_create_with_layout;\n    ext_table.hsa_ext_sampler_create_v2 = hsa_ext_sampler_create_v2;\n\n    memcpy(table, &ext_table, Min(sizeof(ext_table), table_length));\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (extension == HSA_EXTENSION_AMD_PC_SAMPLING) {\n    if (version_major != core::Runtime::runtime_singleton_->extensions_.pcs_api.version.major_id) {\n      return HSA_STATUS_ERROR;\n    }\n    hsa_ven_amd_pc_sampling_1_00_pfn_t ext_table;\n    ext_table.hsa_ven_amd_pcs_create = hsa_ven_amd_pcs_create;\n    ext_table.hsa_ven_amd_pcs_create_from_id = hsa_ven_amd_pcs_create_from_id;\n    ext_table.hsa_ven_amd_pcs_destroy = hsa_ven_amd_pcs_destroy;\n    ext_table.hsa_ven_amd_pcs_start = hsa_ven_amd_pcs_start;\n    ext_table.hsa_ven_amd_pcs_stop = hsa_ven_amd_pcs_stop;\n    ext_table.hsa_ven_amd_pcs_flush = hsa_ven_amd_pcs_flush;\n\n    memcpy(table, &ext_table, Min(sizeof(ext_table), table_length));\n  }\n\n  if (extension == HSA_EXTENSION_FINALIZER) {\n    if (version_major !=\n        core::Runtime::runtime_singleton_->extensions_.finalizer_api.version.major_id) {\n      return HSA_STATUS_ERROR;\n    }\n\n    hsa_ext_finalizer_1_00_pfn_t ext_table;\n    ext_table.hsa_ext_program_add_module = hsa_ext_program_add_module;\n    ext_table.hsa_ext_program_create = hsa_ext_program_create;\n    ext_table.hsa_ext_program_destroy = hsa_ext_program_destroy;\n    ext_table.hsa_ext_program_finalize = hsa_ext_program_finalize;\n    ext_table.hsa_ext_program_get_info = hsa_ext_program_get_info;\n    ext_table.hsa_ext_program_iterate_modules = hsa_ext_program_iterate_modules;\n\n    memcpy(table, &ext_table, Min(sizeof(ext_table), table_length));\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (extension == HSA_EXTENSION_AMD_LOADER) {\n    if (version_major != 1) return HSA_STATUS_ERROR;\n    hsa_ven_amd_loader_1_03_pfn_t ext_table;\n    ext_table.hsa_ven_amd_loader_query_host_address =\n        hsa_ven_amd_loader_query_host_address;\n    ext_table.hsa_ven_amd_loader_query_segment_descriptors =\n        hsa_ven_amd_loader_query_segment_descriptors;\n    ext_table.hsa_ven_amd_loader_query_executable =\n        hsa_ven_amd_loader_query_executable;\n    ext_table.hsa_ven_amd_loader_executable_iterate_loaded_code_objects =\n        hsa_ven_amd_loader_executable_iterate_loaded_code_objects;\n    ext_table.hsa_ven_amd_loader_loaded_code_object_get_info =\n        hsa_ven_amd_loader_loaded_code_object_get_info;\n    ext_table.hsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size =\n        hsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size;\n    ext_table.hsa_ven_amd_loader_iterate_executables =\n        hsa_ven_amd_loader_iterate_executables;\n\n    memcpy(table, &ext_table, Min(sizeof(ext_table), table_length));\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (extension == HSA_EXTENSION_AMD_AQLPROFILE) {\n    if (version_major != hsa_ven_amd_aqlprofile_VERSION_MAJOR) {\n      debug_print(\"aqlprofile API incompatible ver %d, current ver %d\\n\",\n        version_major, hsa_ven_amd_aqlprofile_VERSION_MAJOR);\n      return HSA_STATUS_ERROR;\n    }\n\n    os::LibHandle lib = os::LoadLib(kAqlProfileLib);\n    if (lib == NULL) {\n      debug_print(\"Loading '%s' failed\\n\", kAqlProfileLib);\n      return HSA_STATUS_ERROR;\n    }\n\n    hsa_ven_amd_aqlprofile_pfn_t ext_table;\n    ext_table.hsa_ven_amd_aqlprofile_version_major =\n      (decltype(::hsa_ven_amd_aqlprofile_version_major)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_version_major\");\n    ext_table.hsa_ven_amd_aqlprofile_version_minor =\n      (decltype(::hsa_ven_amd_aqlprofile_version_minor)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_version_minor\");\n    ext_table.hsa_ven_amd_aqlprofile_error_string =\n      (decltype(::hsa_ven_amd_aqlprofile_error_string)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_error_string\");\n    ext_table.hsa_ven_amd_aqlprofile_validate_event =\n      (decltype(::hsa_ven_amd_aqlprofile_validate_event)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_validate_event\");\n    ext_table.hsa_ven_amd_aqlprofile_start =\n      (decltype(::hsa_ven_amd_aqlprofile_start)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_start\");\n    ext_table.hsa_ven_amd_aqlprofile_stop =\n      (decltype(::hsa_ven_amd_aqlprofile_stop)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_stop\");\n    ext_table.hsa_ven_amd_aqlprofile_read =\n      (decltype(::hsa_ven_amd_aqlprofile_read)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_read\");\n    ext_table.hsa_ven_amd_aqlprofile_legacy_get_pm4 =\n      (decltype(::hsa_ven_amd_aqlprofile_legacy_get_pm4)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_legacy_get_pm4\");\n    ext_table.hsa_ven_amd_aqlprofile_get_info =\n      (decltype(::hsa_ven_amd_aqlprofile_get_info)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_get_info\");\n    ext_table.hsa_ven_amd_aqlprofile_iterate_data =\n      (decltype(::hsa_ven_amd_aqlprofile_iterate_data)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_iterate_data\");\n    ext_table.hsa_ven_amd_aqlprofile_iterate_event_ids =\n      (decltype(::hsa_ven_amd_aqlprofile_iterate_event_ids)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_iterate_event_ids\");\n    ext_table.hsa_ven_amd_aqlprofile_iterate_event_coord =\n      (decltype(::hsa_ven_amd_aqlprofile_iterate_event_coord)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_iterate_event_coord\");\n    ext_table.hsa_ven_amd_aqlprofile_att_marker =\n      (decltype(::hsa_ven_amd_aqlprofile_att_marker)*)\n        os::GetExportAddress(lib, \"hsa_ven_amd_aqlprofile_att_marker\");\n\n    bool version_incompatible = true;\n    uint32_t version_curr = 0;\n    version_major = HSA_AQLPROFILE_VERSION_MAJOR;\n    if (ext_table.hsa_ven_amd_aqlprofile_version_major != NULL) {\n      version_curr = ext_table.hsa_ven_amd_aqlprofile_version_major();\n      version_incompatible = (version_major != version_curr);\n    }\n    if (version_incompatible == true) {\n      debug_print(\"Loading '%s' failed, incompatible ver %d, current ver %d\\n\",\n        kAqlProfileLib, version_major, version_curr);\n      return HSA_STATUS_ERROR;\n    }\n\n    memcpy(table, &ext_table, Min(sizeof(ext_table), table_length));\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR;\n  CATCH;\n}\n\n//---------------------------------------------------------------------------//\n//  Agent\n//---------------------------------------------------------------------------//\nhsa_status_t\n    hsa_iterate_agents(hsa_status_t (*callback)(hsa_agent_t agent, void* data),\n                       void* data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n  return core::Runtime::runtime_singleton_->IterateAgent(callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_agent_get_info(hsa_agent_t agent_handle,\n                                        hsa_agent_info_t attribute,\n                                        void* value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n  return agent->GetInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_agent_get_exception_policies(hsa_agent_t agent_handle,\n                                                      hsa_profile_t profile,\n                                                      uint16_t* mask) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(mask);\n  IS_BAD_PROFILE(profile);\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  *mask = 0;\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_cache_get_info(hsa_cache_t cache, hsa_cache_info_t attribute, void* value) {\n  TRY;\n  IS_OPEN();\n  core::Cache* Cache = core::Cache::Convert(cache);\n  IS_VALID(Cache);\n  IS_BAD_PTR(value);\n  return Cache->GetInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_agent_iterate_caches(hsa_agent_t agent_handle,\n                                      hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n                                      void* data) {\n  TRY;\n  IS_OPEN();\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n  IS_BAD_PTR(callback);\n  return agent->IterateCache(callback, data);\n  CATCH;\n}\n\nhsa_status_t\n    hsa_agent_extension_supported(uint16_t extension, hsa_agent_t agent_handle,\n                                  uint16_t version_major,\n                                  uint16_t version_minor, bool* result) {\n  TRY;\n  IS_OPEN();\n\n  if ((extension > HSA_EXTENSION_STD_LAST &&\n       (extension < HSA_AMD_FIRST_EXTENSION || extension > HSA_AMD_LAST_EXTENSION)) ||\n      result == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  *result = false;\n\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  if (agent->device_type() == core::Agent::kAmdGpuDevice) {\n    uint16_t agent_version_major = 0;\n    hsa_status_t status =\n        agent->GetInfo(HSA_AGENT_INFO_VERSION_MAJOR, &agent_version_major);\n    assert(status == HSA_STATUS_SUCCESS);\n\n    if (version_major <= agent_version_major) {\n      uint16_t agent_version_minor = 0;\n      if (version_minor <= agent_version_minor) {\n        *result = true;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_agent_major_extension_supported(uint16_t extension, hsa_agent_t agent_handle,\n                                                 uint16_t version_major, uint16_t* version_minor,\n                                                 bool* result) {\n  TRY;\n  IS_OPEN();\n\n  if ((extension > HSA_EXTENSION_STD_LAST &&\n       (extension < HSA_AMD_FIRST_EXTENSION || extension > HSA_AMD_LAST_EXTENSION)) ||\n      result == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  *result = false;\n\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  if (agent->device_type() == core::Agent::kAmdGpuDevice) {\n    uint16_t agent_version_major = 0;\n    hsa_status_t status = agent->GetInfo(HSA_AGENT_INFO_VERSION_MAJOR, &agent_version_major);\n    assert(status == HSA_STATUS_SUCCESS);\n\n    if (version_major <= agent_version_major) {\n      *version_minor = 0;\n      *result = true;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/// @brief Api to create a user mode queue.\n///\n/// @param agent Hsa Agent which will execute Aql commands\n///\n/// @param size Size of Queue in terms of Aql packet size\n///\n/// @param type of Queue Single Writer or Multiple Writer\n///\n/// @param callback Callback function to register in case Quee\n/// encounters an error\n///\n/// @param service_queue Pointer to a service queue\n///\n/// @param queue Output parameter updated with a pointer to the\n/// queue being created\n///\n/// @return hsa_status\nhsa_status_t hsa_queue_create(\n    hsa_agent_t agent_handle, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),\n    void* data, uint32_t private_segment_size, uint32_t group_segment_size,\n    hsa_queue_t** queue) {\n  TRY;\n  IS_OPEN();\n\n  if ((queue == nullptr) || (size == 0) || (!IsPowerOfTwo(size)) ||\n      (type > HSA_QUEUE_TYPE_COOPERATIVE)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  hsa_queue_type32_t agent_queue_type = HSA_QUEUE_TYPE_MULTI;\n  hsa_status_t status =\n      agent->GetInfo(HSA_AGENT_INFO_QUEUE_TYPE, &agent_queue_type);\n  assert(HSA_STATUS_SUCCESS == status);\n\n  if ((agent_queue_type == HSA_QUEUE_TYPE_SINGLE) &&\n      (type != HSA_QUEUE_TYPE_SINGLE)) {\n    return HSA_STATUS_ERROR_INVALID_QUEUE_CREATION;\n  }\n\n  if (callback == nullptr) callback = core::Queue::DefaultErrorHandler;\n\n  uint64_t queue_create_flags = 0;\n\n  if (core::Runtime::runtime_singleton_->flag().dev_mem_queue_buf())\n    queue_create_flags = HSA_AMD_QUEUE_CREATE_DEVICE_MEM_RING_BUF;\n\n  core::Queue* cmd_queue = nullptr;\n  status = agent->QueueCreate(size, type, queue_create_flags, callback, data, private_segment_size,\n                              group_segment_size, &cmd_queue);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  assert(cmd_queue != nullptr && \"Queue not returned but status was success.\\n\");\n  *queue = core::Queue::Convert(cmd_queue);\n  return status;\n\n  CATCH;\n}\n\nhsa_status_t hsa_soft_queue_create(hsa_region_t region, uint32_t size,\n                                   hsa_queue_type32_t type, uint32_t features,\n                                   hsa_signal_t doorbell_signal,\n                                   hsa_queue_t** queue) {\n  TRY;\n  IS_OPEN();\n\n  if ((queue == NULL) || (region.handle == 0) ||\n      (doorbell_signal.handle == 0) || (size == 0) || (!IsPowerOfTwo(size)) ||\n      (type < HSA_QUEUE_TYPE_MULTI) || (type > HSA_QUEUE_TYPE_SINGLE) ||\n      (features == 0)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);\n  IS_VALID(mem_region);\n\n  const core::Signal* signal = core::Signal::Convert(doorbell_signal);\n  IS_VALID(signal);\n\n  void* shared_queue = nullptr;\n  hsa_status_t err = HSA::hsa_memory_allocate(region, sizeof(core::SharedQueue), &shared_queue);\n  if (err != HSA_STATUS_SUCCESS) return err;\n  assert(shared_queue && \"Queue struct is NULL when creating host queue.\");\n\n  core::HostQueue* host_queue = new core::HostQueue(static_cast<core::SharedQueue*>(shared_queue),\n                                                    region, size, type, features, doorbell_signal);\n\n  *queue = core::Queue::Convert(host_queue);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/// @brief Api to destroy a user mode queue\n///\n/// @param queue Pointer to the queue being destroyed\n///\n/// @return hsa_status\nhsa_status_t hsa_queue_destroy(hsa_queue_t* queue) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(queue);\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n  cmd_queue->Destroy();\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/// @brief Api to inactivate a user mode queue\n///\n/// @param queue Pointer to the queue being inactivated\n///\n/// @return hsa_status\nhsa_status_t hsa_queue_inactivate(hsa_queue_t* queue) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(queue);\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n  cmd_queue->Inactivate();\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/// @brief Api to read the Read Index of Queue using Acquire semantics\n///\n/// @param queue Pointer to the queue whose read index is being read\n///\n/// @return uint64_t Value of Read index\nuint64_t hsa_queue_load_read_index_scacquire(const hsa_queue_t* queue) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->LoadReadIndexAcquire();\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to read the Read Index of Queue using Relaxed semantics\n///\n/// @param queue Pointer to the queue whose read index is being read\n///\n/// @return uint64_t Value of Read index\nuint64_t hsa_queue_load_read_index_relaxed(const hsa_queue_t* queue) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->LoadReadIndexRelaxed();\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to read the Write Index of Queue using Acquire semantics\n///\n/// @param queue Pointer to the queue whose write index is being read\n///\n/// @return uint64_t Value of Write index\nuint64_t hsa_queue_load_write_index_scacquire(const hsa_queue_t* queue) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->LoadWriteIndexAcquire();\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to read the Write Index of Queue using Relaxed semantics\n///\n/// @param queue Pointer to the queue whose write index is being read\n///\n/// @return uint64_t Value of Write index\nuint64_t hsa_queue_load_write_index_relaxed(const hsa_queue_t* queue) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->LoadWriteIndexRelaxed();\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to store the Read Index of Queue using Relaxed semantics\n///\n/// @param queue Pointer to the queue whose read index is being updated\n///\n/// @param value Value of new read index\nvoid hsa_queue_store_read_index_relaxed(const hsa_queue_t* queue,\n                                                uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  cmd_queue->StoreReadIndexRelaxed(value);\n  CATCHRET(void);\n}\n\n/// @brief Api to store the Read Index of Queue using Release semantics\n///\n/// @param queue Pointer to the queue whose read index is being updated\n///\n/// @param value Value of new read index\nvoid hsa_queue_store_read_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  cmd_queue->StoreReadIndexRelease(value);\n  CATCHRET(void);\n}\n\n/// @brief Api to store the Write Index of Queue using Relaxed semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value of new write index\nvoid hsa_queue_store_write_index_relaxed(const hsa_queue_t* queue,\n                                                 uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  cmd_queue->StoreWriteIndexRelaxed(value);\n  CATCHRET(void);\n}\n\n/// @brief Api to store the Write Index of Queue using Release semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value of new write index\nvoid hsa_queue_store_write_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  cmd_queue->StoreWriteIndexRelease(value);\n  CATCHRET(void);\n}\n\n/// @brief Api to compare and swap the Write Index of Queue using Acquire and\n/// Release semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param expected Current value of write index\n///\n/// @param value Value of new write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_cas_write_index_scacq_screl(const hsa_queue_t* queue, uint64_t expected,\n                                               uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->CasWriteIndexAcqRel(expected, value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to compare and swap the Write Index of Queue using Acquire\n/// Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param expected Current value of write index\n///\n/// @param value Value of new write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_cas_write_index_scacquire(const hsa_queue_t* queue, uint64_t expected,\n                                             uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->CasWriteIndexAcquire(expected, value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to compare and swap the Write Index of Queue using Relaxed\n/// Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param expected Current value of write index\n///\n/// @param value Value of new write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_cas_write_index_relaxed(const hsa_queue_t* queue,\n                                                   uint64_t expected,\n                                                   uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->CasWriteIndexRelaxed(expected, value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to compare and swap the Write Index of Queue using Release\n/// Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param expected Current value of write index\n///\n/// @param value Value of new write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_cas_write_index_screlease(const hsa_queue_t* queue, uint64_t expected,\n                                             uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->CasWriteIndexRelease(expected, value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to Add to the Write Index of Queue using Acquire and Release\n/// Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value to add to write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_add_write_index_scacq_screl(const hsa_queue_t* queue, uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->AddWriteIndexAcqRel(value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to Add to the Write Index of Queue using Acquire Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value to add to write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_add_write_index_scacquire(const hsa_queue_t* queue, uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->AddWriteIndexAcquire(value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to Add to the Write Index of Queue using Relaxed Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value to add to write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_add_write_index_relaxed(const hsa_queue_t* queue,\n                                                   uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->AddWriteIndexRelaxed(value);\n  CATCHRET(uint64_t);\n}\n\n/// @brief Api to Add to the Write Index of Queue using Release Semantics\n///\n/// @param queue Pointer to the queue whose write index is being updated\n///\n/// @param value Value to add to write index\n///\n/// @return uint64_t Value of write index before the update\nuint64_t hsa_queue_add_write_index_screlease(const hsa_queue_t* queue, uint64_t value) {\n  TRY;\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  assert(IsValid(cmd_queue));\n  return cmd_queue->AddWriteIndexRelease(value);\n  CATCHRET(uint64_t);\n}\n\n//-----------------------------------------------------------------------------\n// Memory\n//-----------------------------------------------------------------------------\nhsa_status_t hsa_agent_iterate_regions(\n    hsa_agent_t agent_handle,\n    hsa_status_t (*callback)(hsa_region_t region, void* data), void* data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n  return agent->IterateRegion(callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_region_get_info(hsa_region_t region,\n                                         hsa_region_info_t attribute,\n                                         void* value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);\n  IS_VALID(mem_region);\n\n  return mem_region->GetInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_memory_register(void* address, size_t size) {\n  TRY;\n  IS_OPEN();\n\n  if (size == 0 && address != NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_memory_deregister(void* address, size_t size) {\n  TRY;\n  IS_OPEN();\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t\n    hsa_memory_allocate(hsa_region_t region, size_t size, void** ptr) {\n  TRY;\n  IS_OPEN();\n\n  core::MemoryRegion::AllocateFlags alloc_flag = core::MemoryRegion::AllocateNoFlags;\n\n  if (size == 0 || ptr == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);\n  IS_VALID(mem_region);\n\n  return core::Runtime::runtime_singleton_->AllocateMemory(mem_region, size, alloc_flag, ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_memory_free(void* ptr) {\n  TRY;\n  IS_OPEN();\n\n  if (ptr == NULL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return core::Runtime::runtime_singleton_->FreeMemory(ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_memory_assign_agent(void* ptr,\n                                             hsa_agent_t agent_handle,\n                                             hsa_access_permission_t access) {\n  TRY;\n  IS_OPEN();\n\n  if ((ptr == NULL) || (access < HSA_ACCESS_PERMISSION_RO) ||\n      (access > HSA_ACCESS_PERMISSION_RW)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_memory_copy(void* dst, const void* src, size_t size) {\n  TRY;\n  IS_OPEN();\n\n  if (dst == NULL || src == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (size == 0) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return core::Runtime::runtime_singleton_->CopyMemory(dst, src, size);\n  CATCH;\n}\n\n//-----------------------------------------------------------------------------\n// Signals\n//-----------------------------------------------------------------------------\n\nhsa_status_t\n    hsa_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                      const hsa_agent_t* consumers, hsa_signal_t* hsa_signal) {\n  return AMD::hsa_amd_signal_create(initial_value, num_consumers, consumers, 0, hsa_signal);\n}\n\nhsa_status_t hsa_signal_destroy(hsa_signal_t hsa_signal) {\n  TRY;\n  IS_OPEN();\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  signal->DestroySignal();\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_signal_value_t hsa_signal_load_relaxed(hsa_signal_t hsa_signal) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->LoadRelaxed();\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_load_scacquire(hsa_signal_t hsa_signal) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->LoadAcquire();\n  CATCHRET(hsa_signal_value_t);\n}\n\nvoid hsa_signal_store_relaxed(hsa_signal_t hsa_signal,\n                                      hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->StoreRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_store_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->StoreRelease(value);\n  CATCHRET(void);\n}\n\nhsa_signal_value_t\n    hsa_signal_wait_relaxed(hsa_signal_t hsa_signal,\n                            hsa_signal_condition_t condition,\n                            hsa_signal_value_t compare_value,\n                            uint64_t timeout_hint,\n                            hsa_wait_state_t wait_state_hint) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->WaitRelaxed(condition, compare_value, timeout_hint,\n                             wait_state_hint);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_wait_scacquire(hsa_signal_t hsa_signal,\n                                             hsa_signal_condition_t condition,\n                                             hsa_signal_value_t compare_value,\n                                             uint64_t timeout_hint,\n                                             hsa_wait_state_t wait_state_hint) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->WaitAcquire(condition, compare_value, timeout_hint,\n                             wait_state_hint);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_status_t hsa_signal_group_create(uint32_t num_signals, const hsa_signal_t* signals,\n                                     uint32_t num_consumers, const hsa_agent_t* consumers,\n                                     hsa_signal_group_t* signal_group) {\n  TRY;\n  IS_OPEN();\n  if (num_signals == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  for (uint i = 0; i < num_signals; i++) IS_VALID(core::Signal::Convert(signals[i]));\n  for (uint i = 0; i < num_consumers; i++) IS_VALID(core::Agent::Convert(consumers[i]));\n  core::SignalGroup* group = new core::SignalGroup(num_signals, signals);\n  CHECK_ALLOC(group);\n  if (!group->IsValid()) {\n    delete group;\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  *signal_group = core::SignalGroup::Convert(group);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_signal_group_destroy(hsa_signal_group_t signal_group) {\n  TRY;\n  IS_OPEN();\n  core::SignalGroup* group = core::SignalGroup::Convert(signal_group);\n  IS_VALID(group);\n  delete group;\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_signal_group_wait_any_relaxed(hsa_signal_group_t signal_group,\n                                               const hsa_signal_condition_t* conditions,\n                                               const hsa_signal_value_t* compare_values,\n                                               hsa_wait_state_t wait_state_hint,\n                                               hsa_signal_t* signal, hsa_signal_value_t* value) {\n  TRY;\n  IS_OPEN();\n  const core::SignalGroup* group = core::SignalGroup::Convert(signal_group);\n  IS_VALID(group);\n  const uint32_t index = AMD::hsa_amd_signal_wait_any(\n      group->Count(), const_cast<hsa_signal_t*>(group->List()),\n      const_cast<hsa_signal_condition_t*>(conditions),\n      const_cast<hsa_signal_value_t*>(compare_values), uint64_t(-1), wait_state_hint, value);\n  if (index >= group->Count()) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  *signal = group->List()[index];\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_signal_group_wait_any_scacquire(hsa_signal_group_t signal_group,\n                                                 const hsa_signal_condition_t* conditions,\n                                                 const hsa_signal_value_t* compare_values,\n                                                 hsa_wait_state_t wait_state_hint,\n                                                 hsa_signal_t* signal, hsa_signal_value_t* value) {\n  TRY;\n  hsa_status_t ret = HSA::hsa_signal_group_wait_any_relaxed(\n      signal_group, conditions, compare_values, wait_state_hint, signal, value);\n  std::atomic_thread_fence(std::memory_order_acquire);\n  return ret;\n  CATCH;\n}\n\nvoid hsa_signal_and_relaxed(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AndRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_and_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AndAcquire(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_and_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AndRelease(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_and_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AndAcqRel(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_or_relaxed(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->OrRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_or_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->OrAcquire(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_or_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->OrRelease(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_or_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->OrAcqRel(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_xor_relaxed(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->XorRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_xor_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->XorAcquire(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_xor_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->XorRelease(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_xor_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->XorAcqRel(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_add_relaxed(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AddRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_add_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AddAcquire(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_add_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AddRelease(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_add_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->AddAcqRel(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_subtract_relaxed(hsa_signal_t hsa_signal,\n                                         hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->SubRelaxed(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_subtract_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->SubAcquire(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_subtract_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->SubRelease(value);\n  CATCHRET(void);\n}\n\nvoid hsa_signal_subtract_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  signal->SubAcqRel(value);\n  CATCHRET(void);\n}\n\nhsa_signal_value_t\n    hsa_signal_exchange_relaxed(hsa_signal_t hsa_signal,\n                                hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->ExchRelaxed(value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_exchange_scacquire(hsa_signal_t hsa_signal,\n                                                 hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->ExchAcquire(value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_exchange_screlease(hsa_signal_t hsa_signal,\n                                                 hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->ExchRelease(value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_exchange_scacq_screl(hsa_signal_t hsa_signal,\n                                                   hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->ExchAcqRel(value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_cas_relaxed(hsa_signal_t hsa_signal,\n                                                  hsa_signal_value_t expected,\n                                                  hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->CasRelaxed(expected, value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_cas_scacquire(hsa_signal_t hsa_signal, hsa_signal_value_t expected,\n                                            hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->CasAcquire(expected, value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_cas_screlease(hsa_signal_t hsa_signal, hsa_signal_value_t expected,\n                                            hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->CasRelease(expected, value);\n  CATCHRET(hsa_signal_value_t);\n}\n\nhsa_signal_value_t hsa_signal_cas_scacq_screl(hsa_signal_t hsa_signal, hsa_signal_value_t expected,\n                                              hsa_signal_value_t value) {\n  TRY;\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  assert(IsValid(signal));\n  return signal->CasAcqRel(expected, value);\n  CATCHRET(hsa_signal_value_t);\n}\n\n//===--- Instruction Set Architecture -------------------------------------===//\n\nusing core::Isa;\nusing core::IsaRegistry;\nusing core::Wavefront;\n\nhsa_status_t hsa_isa_from_name(\n    const char *name,\n    hsa_isa_t *isa) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(name);\n  IS_BAD_PTR(isa);\n\n  const Isa *isa_object = IsaRegistry::GetIsa(name);\n  if (!isa_object) {\n    return HSA_STATUS_ERROR_INVALID_ISA_NAME;\n  }\n\n  *isa = Isa::Handle(isa_object);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_agent_iterate_isas(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_isa_t isa,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  const core::Agent *agent_object = core::Agent::Convert(agent);\n  IS_VALID(agent_object);\n\n  return agent_object->IterateSupportedIsas(callback, data);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_isa_get_info(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    uint32_t index,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  if (index != 0) {\n    return HSA_STATUS_ERROR_INVALID_INDEX;\n  }\n\n  const Isa *isa_object = Isa::Object(isa);\n  IS_VALID(isa_object);\n\n  return isa_object->GetInfo(attribute, value) ?\n      HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  CATCH;\n}\n\nhsa_status_t hsa_isa_get_info_alt(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  const Isa *isa_object = Isa::Object(isa);\n  IS_VALID(isa_object);\n\n  return isa_object->GetInfo(attribute, value) ?\n      HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  CATCH;\n}\n\nhsa_status_t hsa_isa_get_exception_policies(\n    hsa_isa_t isa,\n    hsa_profile_t profile,\n    uint16_t *mask) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PROFILE(profile);\n  IS_BAD_PTR(mask);\n\n  const Isa *isa_object = Isa::Object(isa);\n  IS_VALID(isa_object);\n\n  // FIXME: update when exception policies are supported.\n  *mask = 0;\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_isa_get_round_method(\n    hsa_isa_t isa,\n    hsa_fp_type_t fp_type,\n    hsa_flush_mode_t flush_mode,\n    hsa_round_method_t *round_method) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_FP_TYPE(fp_type);\n  IS_BAD_FLUSH_MODE(flush_mode);\n  IS_BAD_PTR(round_method);\n\n  const Isa *isa_object = Isa::Object(isa);\n  IS_VALID(isa_object);\n\n  *round_method = isa_object->GetRoundMethod(fp_type, flush_mode);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_wavefront_get_info(\n    hsa_wavefront_t wavefront,\n    hsa_wavefront_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  const Wavefront *wavefront_object = Wavefront::Object(wavefront);\n  if (!wavefront_object) {\n    return HSA_STATUS_ERROR_INVALID_WAVEFRONT;\n  }\n\n  return wavefront_object->GetInfo(attribute, value) ?\n      HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  CATCH;\n}\n\nhsa_status_t hsa_isa_iterate_wavefronts(\n    hsa_isa_t isa,\n    hsa_status_t (*callback)(hsa_wavefront_t wavefront,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  const Isa *isa_object = Isa::Object(isa);\n  IS_VALID(isa_object);\n\n  const Wavefront &wavefront_object = isa_object->GetWavefront();\n\n  return callback(Wavefront::Handle(&wavefront_object), data);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_isa_compatible(\n    hsa_isa_t code_object_isa,\n    hsa_isa_t agent_isa,\n    bool *result) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(result);\n\n  const Isa *code_object_isa_object = Isa::Object(code_object_isa);\n  IS_VALID(code_object_isa_object);\n\n  const Isa *agent_isa_object = Isa::Object(agent_isa);\n  IS_VALID(agent_isa_object);\n\n  *result = Isa::IsCompatible(*code_object_isa_object, *agent_isa_object, 0);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n//===--- Code Objects (deprecated) ----------------------------------------===//\n\nnamespace {\n\nhsa_status_t IsCodeObjectAllocRegion(\n    hsa_region_t region,\n    void *data) {\n  assert(data);\n  assert(((hsa_region_t*)data)->handle == 0);\n\n  bool runtime_alloc_allowed = false;\n  hsa_status_t status = HSA::hsa_region_get_info(\n      region, HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED, &runtime_alloc_allowed);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  if (runtime_alloc_allowed) {\n    ((hsa_region_t*)data)->handle = region.handle;\n    return HSA_STATUS_INFO_BREAK;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindCodeObjectAllocRegionForAgent(\n    hsa_agent_t agent,\n    void *data) {\n  assert(data);\n  assert(((hsa_region_t*)data)->handle == 0);\n\n  hsa_device_type_t device = HSA_DEVICE_TYPE_CPU;\n  hsa_status_t status = HSA::hsa_agent_get_info(\n      agent, HSA_AGENT_INFO_DEVICE, &device);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  if (device == HSA_DEVICE_TYPE_CPU) {\n    return HSA::hsa_agent_iterate_regions(agent, IsCodeObjectAllocRegion, data);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindCodeObjectAllocRegion(\n    void *data) {\n  assert(data);\n  assert(((hsa_region_t*)data)->handle == 0);\n\n  return HSA::hsa_iterate_agents(FindCodeObjectAllocRegionForAgent, data);\n}\n\namd::hsa::code::AmdHsaCodeManager *GetCodeManager() {\n  return core::Runtime::runtime_singleton_->code_manager();\n}\n\n} // namespace anonymous\n\n/* deprecated */\nhsa_status_t hsa_code_object_serialize(\n    hsa_code_object_t code_object,\n    hsa_status_t (*alloc_callback)(size_t size,\n                                   hsa_callback_data_t data,\n                                   void **address),\n    hsa_callback_data_t callback_data,\n    const char *options,\n    void **serialized_code_object,\n    size_t *serialized_code_object_size) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(alloc_callback);\n  IS_BAD_PTR(serialized_code_object);\n  IS_BAD_PTR(serialized_code_object_size);\n\n  amd::hsa::code::AmdHsaCode *code = GetCodeManager()->FromHandle(code_object);\n  if (!code) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  hsa_status_t status = alloc_callback(\n      code->ElfSize(), callback_data, serialized_code_object);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n  assert(*serialized_code_object);\n\n  memcpy(*serialized_code_object, code->ElfData(), code->ElfSize());\n  *serialized_code_object_size = code->ElfSize();\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_deserialize(\n    void *serialized_code_object,\n    size_t serialized_code_object_size,\n    const char *options,\n    hsa_code_object_t *code_object) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(serialized_code_object);\n  IS_BAD_PTR(code_object);\n\n  if (serialized_code_object_size == 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_t code_object_alloc_region = {0};\n  hsa_status_t status = FindCodeObjectAllocRegion(&code_object_alloc_region);\n  if (status != HSA_STATUS_SUCCESS && status != HSA_STATUS_INFO_BREAK) {\n    return status;\n  }\n  assert(code_object_alloc_region.handle != 0);\n\n  void *code_object_alloc_data = nullptr;\n  status = HSA::hsa_memory_allocate(\n      code_object_alloc_region, serialized_code_object_size,\n      &code_object_alloc_data);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n  assert(code_object_alloc_data);\n\n  memcpy(\n      code_object_alloc_data, serialized_code_object,\n      serialized_code_object_size);\n  code_object->handle = reinterpret_cast<uint64_t>(code_object_alloc_data);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_destroy(\n    hsa_code_object_t code_object) {\n  TRY;\n  IS_OPEN();\n\n  void *code_object_data = reinterpret_cast<void*>(code_object.handle);\n  if (!code_object_data) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  if (!GetCodeManager()->Destroy(code_object)) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  HSA::hsa_memory_free(code_object_data);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nstatic std::string ConvertOldTargetNameToNew(\n    const std::string &OldName, bool IsFinalizer, uint32_t EFlags) {\n  std::string NewName = \"\";\n  bool xnack_supported = false;\n\n  // FIXME #1: Should 9:0:3 be completely (loader, sc, etc.) removed?\n  // FIXME #2: What does PAL do with respect to boltzmann/usual fiji/tonga?\n  if (OldName == \"AMD:AMDGPU:6:0:0\")\n    NewName = \"amdgcn-amd-amdhsa--gfx600\";\n  else if (OldName == \"AMD:AMDGPU:6:0:1\")\n    NewName = \"amdgcn-amd-amdhsa--gfx601\";\n  else if (OldName == \"AMD:AMDGPU:6:0:2\")\n    NewName = \"amdgcn-amd-amdhsa--gfx602\";\n  else if (OldName == \"AMD:AMDGPU:7:0:0\")\n    NewName = \"amdgcn-amd-amdhsa--gfx700\";\n  else if (OldName == \"AMD:AMDGPU:7:0:1\")\n    NewName = \"amdgcn-amd-amdhsa--gfx701\";\n  else if (OldName == \"AMD:AMDGPU:7:0:2\")\n    NewName = \"amdgcn-amd-amdhsa--gfx702\";\n  else if (OldName == \"AMD:AMDGPU:7:0:3\")\n    NewName = \"amdgcn-amd-amdhsa--gfx703\";\n  else if (OldName == \"AMD:AMDGPU:7:0:4\")\n    NewName = \"amdgcn-amd-amdhsa--gfx704\";\n  else if (OldName == \"AMD:AMDGPU:7:0:5\")\n    NewName = \"amdgcn-amd-amdhsa--gfx705\";\n  else if (OldName == \"AMD:AMDGPU:8:0:1\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx801\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:8:0:0\" || OldName == \"AMD:AMDGPU:8:0:2\")\n    NewName = \"amdgcn-amd-amdhsa--gfx802\";\n  else if (OldName == \"AMD:AMDGPU:8:0:3\" || OldName == \"AMD:AMDGPU:8:0:4\")\n    NewName = \"amdgcn-amd-amdhsa--gfx803\";\n  else if (OldName == \"AMD:AMDGPU:8:0:5\")\n    NewName = \"amdgcn-amd-amdhsa--gfx805\";\n  else if (OldName == \"AMD:AMDGPU:8:1:0\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx810\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:9:0:0\" || OldName == \"AMD:AMDGPU:9:0:1\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx900\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:9:0:2\" || OldName == \"AMD:AMDGPU:9:0:3\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx902\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:9:0:4\" || OldName == \"AMD:AMDGPU:9:0:5\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx904\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:9:0:6\" || OldName == \"AMD:AMDGPU:9:0:7\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx906\";\n    xnack_supported = true;\n  }\n  else if (OldName == \"AMD:AMDGPU:9:0:12\") {\n    NewName = \"amdgcn-amd-amdhsa--gfx90c\";\n    xnack_supported = true;\n  }\n  else {\n    // Code object v2 only supports asics up to gfx906 plus gfx90c. Do NOT add\n    // handling of new asics into this if-else-if* block.\n    return \"\";\n  }\n\n  if (IsFinalizer) {\n    if (EFlags & ELF::EF_AMDGPU_FEATURE_XNACK_V2)\n      NewName = NewName + \":xnack+\";\n    else if (xnack_supported)\n      NewName = NewName + \":xnack-\";\n  } else {\n    if (OldName == \"AMD:AMDGPU:8:0:1\")\n      NewName = NewName + \":xnack+\";\n    else if (OldName == \"AMD:AMDGPU:8:1:0\")\n      NewName = NewName + \":xnack+\";\n    else if (OldName == \"AMD:AMDGPU:9:0:1\")\n      NewName = NewName + \":xnack+\";\n    else if (OldName == \"AMD:AMDGPU:9:0:3\")\n      NewName = NewName + \":xnack+\";\n    else if (OldName == \"AMD:AMDGPU:9:0:5\")\n      NewName = NewName + \":xnack+\";\n    else if (OldName == \"AMD:AMDGPU:9:0:7\")\n      NewName = NewName + \":xnack+\";\n    else if (xnack_supported)\n      NewName = NewName + \":xnack-\";\n  }\n\n  return NewName;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_get_info(\n    hsa_code_object_t code_object,\n    hsa_code_object_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  amd::hsa::code::AmdHsaCode *code = GetCodeManager()->FromHandle(code_object);\n  if (!code) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  switch (attribute) {\n    case HSA_CODE_OBJECT_INFO_ISA: {\n      char isa_name[64];\n      hsa_status_t status = code->GetInfo(attribute, &isa_name);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n\n      std::string isa_name_str(isa_name);\n\n      bool IsFinalizer = true;\n      uint32_t codeHsailMajor;\n      uint32_t codeHsailMinor;\n      hsa_profile_t codeProfile;\n      hsa_machine_model_t codeMachineModel;\n      hsa_default_float_rounding_mode_t codeRoundingMode;\n      if (!code->GetNoteHsail(&codeHsailMajor, &codeHsailMinor,\n                              &codeProfile, &codeMachineModel,\n                              &codeRoundingMode)) {\n        // Only finalizer generated the \"HSAIL\" note.\n        IsFinalizer = false;\n      }\n\n      std::string new_isa_name_str =\n          ConvertOldTargetNameToNew(isa_name_str, IsFinalizer, code->EFlags());\n\n      hsa_isa_t isa_handle = {0};\n      status = HSA::hsa_isa_from_name(new_isa_name_str.c_str(), &isa_handle);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n\n      *((hsa_isa_t*)value) = isa_handle;\n      return HSA_STATUS_SUCCESS;\n    }\n    default: {\n      return code->GetInfo(attribute, value);\n    }\n  }\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_get_symbol(\n    hsa_code_object_t code_object,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(symbol_name);\n  IS_BAD_PTR(symbol);\n\n  amd::hsa::code::AmdHsaCode *code = GetCodeManager()->FromHandle(code_object);\n  if (!code) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  return code->GetSymbol(nullptr, symbol_name, symbol);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_get_symbol_from_name(\n    hsa_code_object_t code_object,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(symbol_name);\n  IS_BAD_PTR(symbol);\n\n  amd::hsa::code::AmdHsaCode *code = GetCodeManager()->FromHandle(code_object);\n  if (!code) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  return code->GetSymbol(module_name, symbol_name, symbol);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_symbol_get_info(\n    hsa_code_symbol_t code_symbol,\n    hsa_code_symbol_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  code::Symbol *symbol = code::Symbol::FromHandle(code_symbol);\n  if (!symbol) {\n    return HSA_STATUS_ERROR_INVALID_CODE_SYMBOL;\n  }\n\n  return symbol->GetInfo(attribute, value);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_code_object_iterate_symbols(\n    hsa_code_object_t code_object,\n    hsa_status_t (*callback)(hsa_code_object_t code_object,\n                             hsa_code_symbol_t symbol,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  amd::hsa::code::AmdHsaCode *code = GetCodeManager()->FromHandle(code_object);\n  if (!code) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  return code->IterateSymbols(code_object, callback, data);\n  CATCH;\n}\n\n//===--- Executable -------------------------------------------------------===//\n\nusing amd::hsa::common::Signed;\nusing amd::hsa::loader::Loader;\nusing amd::hsa::loader::Executable;\nusing amd::hsa::loader::CodeObjectReaderImpl;\n\nnamespace {\n\nLoader *GetLoader() {\n  return core::Runtime::runtime_singleton_->loader();\n}\n\n} // namespace anonymous\n\nhsa_status_t hsa_code_object_reader_create_from_file(\n    hsa_file_t file,\n    hsa_code_object_reader_t *code_object_reader) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(code_object_reader);\n\n  std::unique_ptr<CodeObjectReaderImpl> reader(\n    new (std::nothrow) CodeObjectReaderImpl());\n  CHECK_ALLOC(reader);\n\n  hsa_status_t status = reader->SetFile(file);\n  CHECK_STATUS(status);\n\n  *code_object_reader = CodeObjectReaderImpl::Handle(reader.release());\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_code_object_reader_create_from_memory(\n    const void *code_object,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(code_object);\n  IS_BAD_PTR(code_object_reader);\n\n  if (size == 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  std::unique_ptr<CodeObjectReaderImpl> reader(\n    new (std::nothrow) CodeObjectReaderImpl());\n  CHECK_ALLOC(reader);\n\n  hsa_status_t status = reader->SetMemory(code_object, size);\n  CHECK_STATUS(status);\n\n  *code_object_reader =\n      CodeObjectReaderImpl::Handle(reader.release());\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_code_object_reader_destroy(\n    hsa_code_object_reader_t code_object_reader) {\n  TRY;\n  IS_OPEN();\n\n  CodeObjectReaderImpl *reader =\n      CodeObjectReaderImpl::Object(code_object_reader);\n  if (!reader) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER;\n  }\n\n  delete reader;\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_executable_create(\n    hsa_profile_t profile,\n    hsa_executable_state_t executable_state,\n    const char *options,\n    hsa_executable_t *executable) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PROFILE(profile);\n  IS_BAD_EXECUTABLE_STATE(executable_state);\n  IS_BAD_PTR(executable);\n\n  // Invoke non-deprecated API.\n  hsa_status_t status = HSA::hsa_executable_create_alt(\n      profile, HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT, options, executable);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  Executable *exec = Executable::Object(*executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  if (executable_state == HSA_EXECUTABLE_STATE_FROZEN) {\n    exec->Freeze(nullptr);\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_executable_create_alt(\n    hsa_profile_t profile,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode,\n    const char *options,\n    hsa_executable_t *executable) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PROFILE(profile);\n  IS_BAD_ROUNDING_MODE(default_float_rounding_mode); // NOTES: should we check\n                                                     // if default float\n                                                     // rounding mode is valid?\n                                                     // spec does not say so.\n  IS_BAD_PTR(executable);\n\n  Executable *exec = GetLoader()->CreateExecutable(\n      std::unique_ptr<amd::LoaderContext>(new amd::LoaderContext()),\n      profile, options, default_float_rounding_mode);\n  CHECK_ALLOC(exec);\n\n  *executable = Executable::Handle(exec);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_executable_destroy(\n    hsa_executable_t executable) {\n  TRY;\n  IS_OPEN();\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  GetLoader()->DestroyExecutable(exec);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_executable_load_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    const char *options) {\n  TRY;\n  IS_OPEN();\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  void *code_object_p = reinterpret_cast<void*>(code_object.handle);\n  if (!code_object_p) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n  CodeObjectReaderImpl reader;\n  reader.SetMemory(code_object_p, amd::elf::ElfSize(code_object_p));\n\n  return exec->LoadCodeObject(agent, code_object, options, reader.GetUri());\n  CATCH;\n}\n\nhsa_status_t hsa_executable_load_program_code_object(\n    hsa_executable_t executable,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object) {\n  TRY;\n  IS_OPEN();\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  CodeObjectReaderImpl *reader = CodeObjectReaderImpl::Object(\n      code_object_reader);\n  if (!reader) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER;\n  }\n\n  hsa_code_object_t code_object =\n      {reinterpret_cast<uint64_t>(reader->GetCodeObjectMemory())};\n  return exec->LoadCodeObject(\n      {0}, code_object, options, reader->GetUri(), loaded_code_object);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_load_agent_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object) {\n  TRY;\n  IS_OPEN();\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  CodeObjectReaderImpl *reader = CodeObjectReaderImpl::Object(\n      code_object_reader);\n  if (!reader) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER;\n  }\n\n  hsa_code_object_t code_object =\n      {reinterpret_cast<uint64_t>(reader->GetCodeObjectMemory())};\n  return exec->LoadCodeObject( agent, code_object, options,\n                              reader->GetUri(), loaded_code_object);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_freeze(\n    hsa_executable_t executable,\n    const char *options) {\n  TRY;\n  IS_OPEN();\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return GetLoader()->FreezeExecutable(exec, options);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_get_info(\n    hsa_executable_t executable,\n    hsa_executable_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->GetInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_global_variable_define(\n    hsa_executable_t executable,\n    const char *variable_name,\n    void *address) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(variable_name);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->DefineProgramExternalVariable(variable_name, address);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_agent_global_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(variable_name);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->DefineAgentExternalVariable(\n      variable_name, agent, HSA_VARIABLE_SEGMENT_GLOBAL, address);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_readonly_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(variable_name);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->DefineAgentExternalVariable(\n      variable_name, agent, HSA_VARIABLE_SEGMENT_READONLY, address);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_validate(\n    hsa_executable_t executable,\n    uint32_t *result) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(result);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->Validate(result);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_validate_alt(\n    hsa_executable_t executable,\n    const char *options,\n    uint32_t *result) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(result);\n\n  return HSA::hsa_executable_validate(executable, result);\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_executable_get_symbol(\n    hsa_executable_t executable,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_agent_t agent,\n    int32_t call_convention,\n    hsa_executable_symbol_t *symbol) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(symbol_name);\n  IS_BAD_PTR(symbol);\n\n  std::string mangled_name(symbol_name);\n  if (mangled_name.empty()) {\n    return HSA_STATUS_ERROR_INVALID_SYMBOL_NAME;\n  }\n  if (module_name && !std::string(module_name).empty()) {\n    mangled_name.insert(0, \"::\");\n    mangled_name.insert(0, std::string(module_name));\n  }\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  // Invoke non-deprecated API.\n  return HSA::hsa_executable_get_symbol_by_name(\n      executable, mangled_name.c_str(),\n      exec->IsProgramSymbol(mangled_name.c_str()) ? nullptr : &agent, symbol);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_get_symbol_by_name(\n    hsa_executable_t executable,\n    const char *symbol_name,\n    const hsa_agent_t *agent, // NOTES: this is not consistent with the rest of\n                              // of the specification, but seems like a better\n                              // approach to distinguish program/agent symbols.\n    hsa_executable_symbol_t *symbol) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(symbol_name);\n  IS_BAD_PTR(symbol);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  loader::Symbol *sym = exec->GetSymbol(symbol_name, agent);\n  if (!sym) {\n    return HSA_STATUS_ERROR_INVALID_SYMBOL_NAME;\n  }\n\n  *symbol = loader::Symbol::Handle(sym);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_executable_symbol_get_info(\n    hsa_executable_symbol_t executable_symbol,\n    hsa_executable_symbol_info_t attribute,\n    void *value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  loader::Symbol *sym = loader::Symbol::Object(executable_symbol);\n  if (!sym) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE_SYMBOL;\n  }\n\n  return sym->GetInfo(attribute, value) ?\n    HSA_STATUS_SUCCESS : HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  CATCH;\n}\n\n/* deprecated */\nhsa_status_t hsa_executable_iterate_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t executable,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->IterateSymbols(callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_iterate_agent_symbols(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_agent_t agent,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  // NOTES: should we check if agent is valid? spec does not say so.\n  const core::Agent *agent_object = core::Agent::Convert(agent);\n  IS_VALID(agent_object);\n\n  Executable *exec = Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->IterateAgentSymbols(agent, callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_executable_iterate_program_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n\n  amd::hsa::loader::Executable *exec = amd::hsa::loader::Executable::Object(executable);\n  if (!exec) {\n    return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n  }\n\n  return exec->IterateProgramSymbols(callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_get_tile_config(hsa_agent_t agent_handle, void* config) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(config);\n\n  const core::Agent* agent_object = core::Agent::Convert(agent_handle);\n  IS_VALID(agent_object);\n\n  return agent_object->driver().GetTileConfig(agent_object->node_id(),\n                                              static_cast<HsaGpuTileConfig*>(config));\n  CATCH;\n}\n\n//===--- Runtime Notifications --------------------------------------------===//\n\nhsa_status_t hsa_status_string(\n    hsa_status_t status,\n    const char **status_string) {\n  IS_BAD_PTR(status_string);\n  const size_t status_u = static_cast<size_t>(status);\n  switch (status_u) {\n    case HSA_STATUS_SUCCESS:\n      *status_string = \"HSA_STATUS_SUCCESS: The function has been executed successfully.\";\n      break;\n    case HSA_STATUS_INFO_BREAK:\n      *status_string =\n          \"HSA_STATUS_INFO_BREAK: A traversal over a list of elements has been interrupted by the \"\n          \"application before completing.\";\n      break;\n    case HSA_STATUS_ERROR:\n      *status_string = \"HSA_STATUS_ERROR: A generic error has occurred.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_ARGUMENT:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_ARGUMENT: One of the actual arguments does not meet a \"\n          \"precondition stated in the documentation of the corresponding formal argument.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_QUEUE_CREATION:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_QUEUE_CREATION: The requested queue creation is not valid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_ALLOCATION:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_ALLOCATION: The requested allocation is not valid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_AGENT:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_AGENT: The agent is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_REGION:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_REGION: The memory region is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_SIGNAL:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_SIGNAL: The signal is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_QUEUE:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_QUEUE: The queue is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_OUT_OF_RESOURCES:\n      *status_string =\n          \"HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to allocate the necessary \"\n          \"resources. This error may also occur when the core runtime library needs to spawn \"\n          \"threads or create internal OS-specific events.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_PACKET_FORMAT:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_PACKET_FORMAT: The AQL packet is malformed.\";\n      break;\n    case HSA_STATUS_ERROR_RESOURCE_FREE:\n      *status_string =\n          \"HSA_STATUS_ERROR_RESOURCE_FREE: An error has been detected while releasing a resource.\";\n      break;\n    case HSA_STATUS_ERROR_NOT_INITIALIZED:\n      *status_string =\n          \"HSA_STATUS_ERROR_NOT_INITIALIZED: An API other than hsa_init has been invoked while the \"\n          \"reference count of the HSA runtime is zero.\";\n      break;\n    case HSA_STATUS_ERROR_REFCOUNT_OVERFLOW:\n      *status_string =\n          \"HSA_STATUS_ERROR_REFCOUNT_OVERFLOW: The maximum reference count for the object has been \"\n          \"reached.\";\n      break;\n    case HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS:\n      *status_string =\n          \"HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS: The arguments passed to a functions are not \"\n          \"compatible.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_INDEX:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_INDEX: The index is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_ISA:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_ISA: The instruction set architecture is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_ISA_NAME:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_ISA_NAME: The instruction set architecture name is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_CODE_OBJECT: The code object is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_EXECUTABLE:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_EXECUTABLE: The executable is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_FROZEN_EXECUTABLE:\n      *status_string = \"HSA_STATUS_ERROR_FROZEN_EXECUTABLE: The executable is frozen.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_SYMBOL_NAME:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_SYMBOL_NAME: There is no symbol with the given name.\";\n      break;\n    case HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED:\n      *status_string =\n          \"HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED: The variable is already defined.\";\n      break;\n    case HSA_STATUS_ERROR_VARIABLE_UNDEFINED:\n      *status_string = \"HSA_STATUS_ERROR_VARIABLE_UNDEFINED: The variable is undefined.\";\n      break;\n    case HSA_STATUS_ERROR_EXCEPTION:\n      *status_string =\n          \"HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_CODE_SYMBOL:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_CODE_SYMBOL: The code object symbol is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_EXECUTABLE_SYMBOL:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_EXECUTABLE_SYMBOL: The executable symbol is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_FILE:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_FILE: The file descriptor is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER: The code object reader is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_CACHE:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_CACHE: The cache is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_WAVEFRONT:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_WAVEFRONT: The wavefront is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP: The signal group is invalid.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_RUNTIME_STATE:\n      *status_string =\n          \"HSA_STATUS_ERROR_INVALID_RUNTIME_STATE: The HSA runtime is not in the configuration \"\n          \"state.\";\n      break;\n    case HSA_STATUS_ERROR_FATAL:\n      *status_string =\n          \"HSA_STATUS_ERROR_FATAL: The queue received an error that may require process \"\n          \"termination.\";\n      break;\n    case HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION:\n      *status_string =\n          \"HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION: The agent attempted to access memory beyond \"\n          \"the largest legal address.\";\n      break;\n    case HSA_STATUS_ERROR_ILLEGAL_INSTRUCTION:\n      *status_string =\n          \"HSA_STATUS_ERROR_ILLEGAL_INSTRUCTION: The agent attempted to execute an illegal shader \"\n          \"instruction.\";\n      break;\n    case HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED:\n      *status_string =\n          \"HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED: Image format is not supported.\";\n      break;\n    case HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED:\n      *status_string = \"HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED: Image size is not supported.\";\n      break;\n    case HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED:\n      *status_string =\n          \"HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED: Image pitch is not supported or invalid.\";\n      break;\n    case HSA_EXT_STATUS_ERROR_SAMPLER_DESCRIPTOR_UNSUPPORTED:\n      *status_string =\n          \"HSA_EXT_STATUS_ERROR_SAMPLER_DESCRIPTOR_UNSUPPORTED: Sampler descriptor is not \"\n          \"supported or invalid.\";\n      break;\n    case HSA_EXT_STATUS_ERROR_INVALID_PROGRAM:\n      *status_string = \"HSA_EXT_STATUS_ERROR_INVALID_PROGRAM: Invalid program\";\n      break;\n    case HSA_EXT_STATUS_ERROR_INVALID_MODULE:\n      *status_string = \"HSA_EXT_STATUS_ERROR_INVALID_MODULE: Invalid module\";\n      break;\n    case HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE:\n      *status_string = \"HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE: Incompatible module\";\n      break;\n    case HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED:\n      *status_string = \"HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED: Module already included\";\n      break;\n    case HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH:\n      *status_string = \"HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH: Symbol mismatch\";\n      break;\n    case HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED:\n      *status_string = \"HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED: Finalization failed\";\n      break;\n    case HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH:\n      *status_string = \"HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH: Directive mismatch\";\n      break;\n    case HSA_STATUS_ERROR_MEMORY_FAULT:\n      *status_string =\n          \"HSA_STATUS_ERROR_MEMORY_FAULT: Agent attempted to access an inaccessible address.\";\n      break;\n    case HSA_STATUS_ERROR_INVALID_MEMORY_POOL:\n      *status_string = \"HSA_STATUS_ERROR_INVALID_MEMORY_POOL: The memory pool is invalid.\";\n      break;\n    case HSA_STATUS_CU_MASK_REDUCED:\n      *status_string =\n          \"HSA_STATUS_CU_MASK_REDUCED: The CU mask was successfully set but the mask attempted to \"\n          \"enable a CU which was disabled for the process.  CUs disabled for the process remain \"\n          \"disabled.\";\n      break;\n    case HSA_STATUS_ERROR_OUT_OF_REGISTERS:\n      *status_string =\n          \"HSA_STATUS_ERROR_OUT_OF_REGISTERS: Kernel has requested more VGPRs than are available \"\n          \"on this agent\";\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace HSA\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/hsa_api_trace.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/hsa_api_trace_int.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"core/inc/hsa_table_interface.h\"\n\n#include <iostream>\n\n// Tools only APIs.\nnamespace rocr {\nnamespace AMD {\nhsa_status_t hsa_amd_queue_intercept_register(hsa_queue_t* queue,\n                                              hsa_amd_queue_intercept_handler callback,\n                                              void* user_data);\nhsa_status_t hsa_amd_queue_intercept_create(\n    hsa_agent_t agent_handle, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,\n    uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue);\n\nhsa_status_t hsa_amd_runtime_queue_create_register(hsa_amd_runtime_queue_notifier callback,\n                                                   void* user_data);\n}   //  namespace amd\n\nnamespace core {\n\nHsaApiTable& hsa_api_table() {\n  static HsaApiTable table;\n  return table;\n}\n\nHsaApiTable& hsa_internal_api_table() {\n  static HsaApiTable table;\n  return table;\n}\n\nHsaApiTable::HsaApiTable() {\n  Init();\n}\n\n// Initialize member fields for Hsa Core and Amd Extension Api's\n// Member fields for Finalizer and Image extensions will be\n// updated as part of Hsa Runtime initialization.\nvoid HsaApiTable::Init() {\n  // Compile time checks to make sure we increment STEPPING when new APIs are added.\n  // Profiler team needs STEPPING to change every time we add functions to the tables so that\n  // they can add preprocessor macros on the new functions\n\n  constexpr size_t expected_core_api_table_size = 1016;\n  constexpr size_t expected_amd_ext_table_size = 608;\n  constexpr size_t expected_image_ext_table_size = 128;\n  constexpr size_t expected_finalizer_ext_table_size = 64;\n  constexpr size_t expected_tools_table_size = 64;\n  constexpr size_t expected_pc_sampling_ext_table_size = 72;\n\n  static_assert(sizeof(CoreApiTable) == expected_core_api_table_size,\n                \"HSA core API table size changed, bump HSA_CORE_API_TABLE_STEP_VERSION and set \"\n                \"expected_core_api_table_size to the new size of the struct\");\n  static_assert(sizeof(AmdExtTable) == expected_amd_ext_table_size,\n                \"HSA AMD ext table size changed, bump HSA_AMD_EXT_API_TABLE_STEP_VERSION, \"\n                \"HSA_AMD_INTERFACE_VERSION_MINOR and set expected_amd_ext_table_size to the new \"\n                \"size of the struct\");\n  static_assert(sizeof(ImageExtTable) == expected_image_ext_table_size,\n                \"HSA image ext table size changed, bump HSA_IMAGE_API_TABLE_STEP_VERSION and set \"\n                \"expected_image_ext_table_size to the new size of the struct\");\n  static_assert(sizeof(FinalizerExtTable) == expected_finalizer_ext_table_size,\n                \"HSA finalizer ext table size changed, bump HSA_FINALIZER_API_TABLE_STEP_VERSION \"\n                \"and set expected_finalizer_ext_table_size to the new size of the struct\");\n  static_assert(sizeof(ToolsApiTable) == expected_tools_table_size,\n                \"HSA tools table size changed, bump HSA_TOOLS_API_TABLE_STEP_VERSION \"\n                \"and set expected_tools_table_size to the new size of the struct\");\n  static_assert(sizeof(PcSamplingExtTable) == expected_pc_sampling_ext_table_size,\n                \"HSA finalizer ext table size changed, bump HSA_PC_SAMPLING_API_TABLE_STEP_VERSION \"\n                \"and set expected_pc_sampling_ext_table_size to the new size of the struct\");\n\n  // Initialize Version of Api Table\n  hsa_api.version.major_id = HSA_API_TABLE_MAJOR_VERSION;\n  hsa_api.version.minor_id = sizeof(::HsaApiTable);\n  hsa_api.version.step_id = HSA_API_TABLE_STEP_VERSION;\n\n  // Update Api table for Core and its major id\n  UpdateCore();\n  hsa_api.core_ = &core_api;\n\n  // Update Api table for Amd Extensions and its major id\n  UpdateAmdExts();\n  hsa_api.amd_ext_ = &amd_ext_api;\n\n  // Initialize Api tables for Finalizer, Image to NULL\n  // The tables are initialized as part\n  // of Hsa Runtime initialization, including their major ids\n  hsa_api.finalizer_ext_ = NULL;\n  hsa_api.image_ext_ = NULL;\n  hsa_api.pc_sampling_ext_ = NULL;\n\n  UpdateTools();\n  hsa_api.tools_ = &tools_api;\n}\n\nvoid HsaApiTable::Reset() {\n  Init();\n}\n\nvoid HsaApiTable::CloneExts(void* ext_table, uint32_t table_id) {\n\n  assert(ext_table != NULL && \"Invalid extension table linked.\");\n\n  // Update HSA Extension Finalizer Api table\n  if (table_id == HSA_EXT_FINALIZER_API_TABLE_ID) {\n    finalizer_api = *reinterpret_cast<FinalizerExtTable*>(ext_table);\n    hsa_api.finalizer_ext_ = &finalizer_api;\n    return;\n  }\n\n  // Update HSA Extension Image Api table\n  if (table_id == HSA_EXT_IMAGE_API_TABLE_ID) {\n    image_api = *reinterpret_cast<ImageExtTable*>(ext_table);\n    hsa_api.image_ext_ = &image_api;\n    return;\n  }\n\n  // Update HSA Extension PC Sampling Api table\n  if (table_id == HSA_EXT_PC_SAMPLING_API_TABLE_ID) {\n    pcs_api = *reinterpret_cast<PcSamplingExtTable*>(ext_table);\n    hsa_api.pc_sampling_ext_ = &pcs_api;\n    return;\n  }\n}\n\nvoid HsaApiTable::LinkExts(void* ext_table, uint32_t table_id) {\n\n  assert(ext_table != NULL && \"Invalid extension table linked.\");\n\n  // Update HSA Extension Finalizer Api table\n  if (table_id == HSA_EXT_FINALIZER_API_TABLE_ID) {\n    finalizer_api = *reinterpret_cast<FinalizerExtTable*>(ext_table);\n    hsa_api.finalizer_ext_ = reinterpret_cast<FinalizerExtTable*>(ext_table);\n    return;\n  }\n\n  // Update HSA Extension Image Api table\n  if (table_id == HSA_EXT_IMAGE_API_TABLE_ID) {\n    image_api = *reinterpret_cast<ImageExtTable*>(ext_table);\n    hsa_api.image_ext_ = reinterpret_cast<ImageExtTable*>(ext_table);\n    return;\n  }\n\n  // Update HSA Extension PC Sampling Api table\n  if (table_id == HSA_EXT_PC_SAMPLING_API_TABLE_ID) {\n    pcs_api = *reinterpret_cast<PcSamplingExtTable*>(ext_table);\n    hsa_api.pc_sampling_ext_ = &pcs_api;\n    return;\n  }\n}\n\n// Update Api table for Hsa Core Runtime\nvoid HsaApiTable::UpdateCore() {\n\n  // Initialize Version of Api Table\n  core_api.version.major_id = HSA_CORE_API_TABLE_MAJOR_VERSION;\n  core_api.version.minor_id = sizeof(::CoreApiTable);\n  core_api.version.step_id = HSA_CORE_API_TABLE_STEP_VERSION;\n\n  // Initialize function pointers for Hsa Core Runtime Api's\n  core_api.hsa_init_fn = HSA::hsa_init;\n  core_api.hsa_shut_down_fn = HSA::hsa_shut_down;\n  core_api.hsa_system_get_info_fn = HSA::hsa_system_get_info;\n  core_api.hsa_system_extension_supported_fn = HSA::hsa_system_extension_supported;\n  core_api.hsa_system_get_extension_table_fn = HSA::hsa_system_get_extension_table;\n  core_api.hsa_iterate_agents_fn = HSA::hsa_iterate_agents;\n  core_api.hsa_agent_get_info_fn = HSA::hsa_agent_get_info;\n  core_api.hsa_agent_get_exception_policies_fn =\n      HSA::hsa_agent_get_exception_policies;\n  core_api.hsa_agent_extension_supported_fn = HSA::hsa_agent_extension_supported;\n  core_api.hsa_queue_create_fn = HSA::hsa_queue_create;\n  core_api.hsa_soft_queue_create_fn = HSA::hsa_soft_queue_create;\n  core_api.hsa_queue_destroy_fn = HSA::hsa_queue_destroy;\n  core_api.hsa_queue_inactivate_fn = HSA::hsa_queue_inactivate;\n  core_api.hsa_queue_load_read_index_scacquire_fn = HSA::hsa_queue_load_read_index_scacquire;\n  core_api.hsa_queue_load_read_index_relaxed_fn =\n      HSA::hsa_queue_load_read_index_relaxed;\n  core_api.hsa_queue_load_write_index_scacquire_fn = HSA::hsa_queue_load_write_index_scacquire;\n  core_api.hsa_queue_load_write_index_relaxed_fn =\n      HSA::hsa_queue_load_write_index_relaxed;\n  core_api.hsa_queue_store_write_index_relaxed_fn =\n      HSA::hsa_queue_store_write_index_relaxed;\n  core_api.hsa_queue_store_write_index_screlease_fn = HSA::hsa_queue_store_write_index_screlease;\n  core_api.hsa_queue_cas_write_index_scacq_screl_fn = HSA::hsa_queue_cas_write_index_scacq_screl;\n  core_api.hsa_queue_cas_write_index_scacquire_fn = HSA::hsa_queue_cas_write_index_scacquire;\n  core_api.hsa_queue_cas_write_index_relaxed_fn =\n      HSA::hsa_queue_cas_write_index_relaxed;\n  core_api.hsa_queue_cas_write_index_screlease_fn = HSA::hsa_queue_cas_write_index_screlease;\n  core_api.hsa_queue_add_write_index_scacq_screl_fn = HSA::hsa_queue_add_write_index_scacq_screl;\n  core_api.hsa_queue_add_write_index_scacquire_fn = HSA::hsa_queue_add_write_index_scacquire;\n  core_api.hsa_queue_add_write_index_relaxed_fn =\n      HSA::hsa_queue_add_write_index_relaxed;\n  core_api.hsa_queue_add_write_index_screlease_fn = HSA::hsa_queue_add_write_index_screlease;\n  core_api.hsa_queue_store_read_index_relaxed_fn =\n      HSA::hsa_queue_store_read_index_relaxed;\n  core_api.hsa_queue_store_read_index_screlease_fn = HSA::hsa_queue_store_read_index_screlease;\n  core_api.hsa_agent_iterate_regions_fn = HSA::hsa_agent_iterate_regions;\n  core_api.hsa_region_get_info_fn = HSA::hsa_region_get_info;\n  core_api.hsa_memory_register_fn = HSA::hsa_memory_register;\n  core_api.hsa_memory_deregister_fn = HSA::hsa_memory_deregister;\n  core_api.hsa_memory_allocate_fn = HSA::hsa_memory_allocate;\n  core_api.hsa_memory_free_fn = HSA::hsa_memory_free;\n  core_api.hsa_memory_copy_fn = HSA::hsa_memory_copy;\n  core_api.hsa_memory_assign_agent_fn = HSA::hsa_memory_assign_agent;\n  core_api.hsa_signal_create_fn = HSA::hsa_signal_create;\n  core_api.hsa_signal_destroy_fn = HSA::hsa_signal_destroy;\n  core_api.hsa_signal_load_relaxed_fn = HSA::hsa_signal_load_relaxed;\n  core_api.hsa_signal_load_scacquire_fn = HSA::hsa_signal_load_scacquire;\n  core_api.hsa_signal_store_relaxed_fn = HSA::hsa_signal_store_relaxed;\n  core_api.hsa_signal_store_screlease_fn = HSA::hsa_signal_store_screlease;\n  core_api.hsa_signal_wait_relaxed_fn = HSA::hsa_signal_wait_relaxed;\n  core_api.hsa_signal_wait_scacquire_fn = HSA::hsa_signal_wait_scacquire;\n  core_api.hsa_signal_and_relaxed_fn = HSA::hsa_signal_and_relaxed;\n  core_api.hsa_signal_and_scacquire_fn = HSA::hsa_signal_and_scacquire;\n  core_api.hsa_signal_and_screlease_fn = HSA::hsa_signal_and_screlease;\n  core_api.hsa_signal_and_scacq_screl_fn = HSA::hsa_signal_and_scacq_screl;\n  core_api.hsa_signal_or_relaxed_fn = HSA::hsa_signal_or_relaxed;\n  core_api.hsa_signal_or_scacquire_fn = HSA::hsa_signal_or_scacquire;\n  core_api.hsa_signal_or_screlease_fn = HSA::hsa_signal_or_screlease;\n  core_api.hsa_signal_or_scacq_screl_fn = HSA::hsa_signal_or_scacq_screl;\n  core_api.hsa_signal_xor_relaxed_fn = HSA::hsa_signal_xor_relaxed;\n  core_api.hsa_signal_xor_scacquire_fn = HSA::hsa_signal_xor_scacquire;\n  core_api.hsa_signal_xor_screlease_fn = HSA::hsa_signal_xor_screlease;\n  core_api.hsa_signal_xor_scacq_screl_fn = HSA::hsa_signal_xor_scacq_screl;\n  core_api.hsa_signal_exchange_relaxed_fn = HSA::hsa_signal_exchange_relaxed;\n  core_api.hsa_signal_exchange_scacquire_fn = HSA::hsa_signal_exchange_scacquire;\n  core_api.hsa_signal_exchange_screlease_fn = HSA::hsa_signal_exchange_screlease;\n  core_api.hsa_signal_exchange_scacq_screl_fn = HSA::hsa_signal_exchange_scacq_screl;\n  core_api.hsa_signal_add_relaxed_fn = HSA::hsa_signal_add_relaxed;\n  core_api.hsa_signal_add_scacquire_fn = HSA::hsa_signal_add_scacquire;\n  core_api.hsa_signal_add_screlease_fn = HSA::hsa_signal_add_screlease;\n  core_api.hsa_signal_add_scacq_screl_fn = HSA::hsa_signal_add_scacq_screl;\n  core_api.hsa_signal_subtract_relaxed_fn = HSA::hsa_signal_subtract_relaxed;\n  core_api.hsa_signal_subtract_scacquire_fn = HSA::hsa_signal_subtract_scacquire;\n  core_api.hsa_signal_subtract_screlease_fn = HSA::hsa_signal_subtract_screlease;\n  core_api.hsa_signal_subtract_scacq_screl_fn = HSA::hsa_signal_subtract_scacq_screl;\n  core_api.hsa_signal_cas_relaxed_fn = HSA::hsa_signal_cas_relaxed;\n  core_api.hsa_signal_cas_scacquire_fn = HSA::hsa_signal_cas_scacquire;\n  core_api.hsa_signal_cas_screlease_fn = HSA::hsa_signal_cas_screlease;\n  core_api.hsa_signal_cas_scacq_screl_fn = HSA::hsa_signal_cas_scacq_screl;\n\n  //===--- Instruction Set Architecture -----------------------------------===//\n\n  core_api.hsa_isa_from_name_fn = HSA::hsa_isa_from_name;\n  // Deprecated since v1.1.\n  core_api.hsa_isa_get_info_fn = HSA::hsa_isa_get_info;\n  // Deprecated since v1.1.\n  core_api.hsa_isa_compatible_fn = HSA::hsa_isa_compatible;\n\n  //===--- Code Objects (deprecated) --------------------------------------===//\n\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_serialize_fn = HSA::hsa_code_object_serialize;\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_deserialize_fn = HSA::hsa_code_object_deserialize;\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_destroy_fn = HSA::hsa_code_object_destroy;\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_get_info_fn = HSA::hsa_code_object_get_info;\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_get_symbol_fn = HSA::hsa_code_object_get_symbol;\n  // Deprecated since v1.1.\n  core_api.hsa_code_symbol_get_info_fn = HSA::hsa_code_symbol_get_info;\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_iterate_symbols_fn =\n      HSA::hsa_code_object_iterate_symbols;\n\n  //===--- Executable -----------------------------------------------------===//\n\n  // Deprecated since v1.1.\n  core_api.hsa_executable_create_fn = HSA::hsa_executable_create;\n  core_api.hsa_executable_destroy_fn = HSA::hsa_executable_destroy;\n  // Deprecated since v1.1.\n  core_api.hsa_executable_load_code_object_fn =\n      HSA::hsa_executable_load_code_object;\n  core_api.hsa_executable_freeze_fn = HSA::hsa_executable_freeze;\n  core_api.hsa_executable_get_info_fn = HSA::hsa_executable_get_info;\n  core_api.hsa_executable_global_variable_define_fn =\n      HSA::hsa_executable_global_variable_define;\n  core_api.hsa_executable_agent_global_variable_define_fn =\n      HSA::hsa_executable_agent_global_variable_define;\n  core_api.hsa_executable_readonly_variable_define_fn =\n      HSA::hsa_executable_readonly_variable_define;\n  core_api.hsa_executable_validate_fn = HSA::hsa_executable_validate;\n  // Deprecated since v1.1.\n  core_api.hsa_executable_get_symbol_fn = HSA::hsa_executable_get_symbol;\n  core_api.hsa_executable_symbol_get_info_fn =\n      HSA::hsa_executable_symbol_get_info;\n  // Deprecated since v1.1.\n  core_api.hsa_executable_iterate_symbols_fn =\n      HSA::hsa_executable_iterate_symbols;\n\n  //===--- Runtime Notifications ------------------------------------------===//\n\n  core_api.hsa_status_string_fn = HSA::hsa_status_string;\n\n  // Start HSA v1.1 additions\n  core_api.hsa_extension_get_name_fn = HSA::hsa_extension_get_name;\n  core_api.hsa_system_major_extension_supported_fn = HSA::hsa_system_major_extension_supported;\n  core_api.hsa_system_get_major_extension_table_fn = HSA::hsa_system_get_major_extension_table;\n  core_api.hsa_agent_major_extension_supported_fn = HSA::hsa_agent_major_extension_supported;\n  core_api.hsa_cache_get_info_fn = HSA::hsa_cache_get_info;\n  core_api.hsa_agent_iterate_caches_fn = HSA::hsa_agent_iterate_caches;\n  // Silent store optimization is present in all signal ops when no agents are sleeping.\n  core_api.hsa_signal_silent_store_relaxed_fn = HSA::hsa_signal_store_relaxed;\n  core_api.hsa_signal_silent_store_screlease_fn = HSA::hsa_signal_store_screlease;\n  core_api.hsa_signal_group_create_fn = HSA::hsa_signal_group_create;\n  core_api.hsa_signal_group_destroy_fn = HSA::hsa_signal_group_destroy;\n  core_api.hsa_signal_group_wait_any_scacquire_fn = HSA::hsa_signal_group_wait_any_scacquire;\n  core_api.hsa_signal_group_wait_any_relaxed_fn = HSA::hsa_signal_group_wait_any_relaxed;\n\n  //===--- Instruction Set Architecture - HSA v1.1 additions --------------===//\n\n  core_api.hsa_agent_iterate_isas_fn = HSA::hsa_agent_iterate_isas;\n  core_api.hsa_isa_get_info_alt_fn = HSA::hsa_isa_get_info_alt;\n  core_api.hsa_isa_get_exception_policies_fn =\n      HSA::hsa_isa_get_exception_policies;\n  core_api.hsa_isa_get_round_method_fn = HSA::hsa_isa_get_round_method;\n  core_api.hsa_wavefront_get_info_fn = HSA::hsa_wavefront_get_info;\n  core_api.hsa_isa_iterate_wavefronts_fn = HSA::hsa_isa_iterate_wavefronts;\n\n  //===--- Code Objects (deprecated) - HSA v1.1 additions -----------------===//\n\n  // Deprecated since v1.1.\n  core_api.hsa_code_object_get_symbol_from_name_fn =\n      HSA::hsa_code_object_get_symbol_from_name;\n\n  //===--- Executable - HSA v1.1 additions --------------------------------===//\n\n  core_api.hsa_code_object_reader_create_from_file_fn =\n      HSA::hsa_code_object_reader_create_from_file;\n  core_api.hsa_code_object_reader_create_from_memory_fn =\n      HSA::hsa_code_object_reader_create_from_memory;\n  core_api.hsa_code_object_reader_destroy_fn =\n      HSA::hsa_code_object_reader_destroy;\n  core_api.hsa_executable_create_alt_fn = HSA::hsa_executable_create_alt;\n  core_api.hsa_executable_load_program_code_object_fn =\n      HSA::hsa_executable_load_program_code_object;\n  core_api.hsa_executable_load_agent_code_object_fn =\n      HSA::hsa_executable_load_agent_code_object;\n  core_api.hsa_executable_validate_alt_fn = HSA::hsa_executable_validate_alt;\n  core_api.hsa_executable_get_symbol_by_name_fn =\n      HSA::hsa_executable_get_symbol_by_name;\n  core_api.hsa_executable_iterate_agent_symbols_fn =\n      HSA::hsa_executable_iterate_agent_symbols;\n  core_api.hsa_executable_iterate_program_symbols_fn =\n      HSA::hsa_executable_iterate_program_symbols;\n}\n\n// Update Api table for Amd Extensions.\n// @note: Current implementation will initialize the\n// member variable hsa_amd_image_create_fn while loading\n// Image extension library\nvoid HsaApiTable::UpdateAmdExts() {\n\n  // Initialize Version of Api Table\n  amd_ext_api.version.major_id = HSA_AMD_EXT_API_TABLE_MAJOR_VERSION;\n  amd_ext_api.version.minor_id = sizeof(::AmdExtTable);\n  amd_ext_api.version.step_id = HSA_AMD_EXT_API_TABLE_STEP_VERSION;\n\n  // Initialize function pointers for Amd Extension Api's\n  amd_ext_api.hsa_amd_coherency_get_type_fn = AMD::hsa_amd_coherency_get_type;\n  amd_ext_api.hsa_amd_coherency_set_type_fn = AMD::hsa_amd_coherency_set_type;\n  amd_ext_api.hsa_amd_profiling_set_profiler_enabled_fn = AMD::hsa_amd_profiling_set_profiler_enabled;\n  amd_ext_api.hsa_amd_profiling_async_copy_enable_fn = AMD::hsa_amd_profiling_async_copy_enable;\n  amd_ext_api.hsa_amd_profiling_get_dispatch_time_fn = AMD::hsa_amd_profiling_get_dispatch_time;\n  amd_ext_api.hsa_amd_profiling_get_async_copy_time_fn = AMD::hsa_amd_profiling_get_async_copy_time;\n  amd_ext_api.hsa_amd_profiling_convert_tick_to_system_domain_fn = AMD::hsa_amd_profiling_convert_tick_to_system_domain;\n  amd_ext_api.hsa_amd_signal_async_handler_fn = AMD::hsa_amd_signal_async_handler;\n  amd_ext_api.hsa_amd_async_function_fn = AMD::hsa_amd_async_function;\n  amd_ext_api.hsa_amd_signal_wait_any_fn = AMD::hsa_amd_signal_wait_any;\n  amd_ext_api.hsa_amd_queue_cu_set_mask_fn = AMD::hsa_amd_queue_cu_set_mask;\n  amd_ext_api.hsa_amd_queue_cu_get_mask_fn = AMD::hsa_amd_queue_cu_get_mask;\n  amd_ext_api.hsa_amd_memory_pool_get_info_fn = AMD::hsa_amd_memory_pool_get_info;\n  amd_ext_api.hsa_amd_agent_iterate_memory_pools_fn = AMD::hsa_amd_agent_iterate_memory_pools;\n  amd_ext_api.hsa_amd_memory_pool_allocate_fn = AMD::hsa_amd_memory_pool_allocate;\n  amd_ext_api.hsa_amd_memory_pool_free_fn = AMD::hsa_amd_memory_pool_free;\n  amd_ext_api.hsa_amd_memory_async_copy_fn = AMD::hsa_amd_memory_async_copy;\n  amd_ext_api.hsa_amd_memory_async_copy_on_engine_fn = AMD::hsa_amd_memory_async_copy_on_engine;\n  amd_ext_api.hsa_amd_memory_copy_engine_status_fn = AMD::hsa_amd_memory_copy_engine_status;\n  amd_ext_api.hsa_amd_agent_memory_pool_get_info_fn = AMD::hsa_amd_agent_memory_pool_get_info;\n  amd_ext_api.hsa_amd_agents_allow_access_fn = AMD::hsa_amd_agents_allow_access;\n  amd_ext_api.hsa_amd_memory_pool_can_migrate_fn = AMD::hsa_amd_memory_pool_can_migrate;\n  amd_ext_api.hsa_amd_memory_migrate_fn = AMD::hsa_amd_memory_migrate;\n  amd_ext_api.hsa_amd_memory_lock_fn = AMD::hsa_amd_memory_lock;\n  amd_ext_api.hsa_amd_memory_unlock_fn = AMD::hsa_amd_memory_unlock;\n  amd_ext_api.hsa_amd_memory_fill_fn = AMD::hsa_amd_memory_fill;\n  amd_ext_api.hsa_amd_interop_map_buffer_fn = AMD::hsa_amd_interop_map_buffer;\n  amd_ext_api.hsa_amd_interop_unmap_buffer_fn = AMD::hsa_amd_interop_unmap_buffer;\n  amd_ext_api.hsa_amd_pointer_info_fn = AMD::hsa_amd_pointer_info;\n  amd_ext_api.hsa_amd_pointer_info_set_userdata_fn = AMD::hsa_amd_pointer_info_set_userdata;\n  amd_ext_api.hsa_amd_ipc_memory_create_fn = AMD::hsa_amd_ipc_memory_create;\n  amd_ext_api.hsa_amd_ipc_memory_attach_fn = AMD::hsa_amd_ipc_memory_attach;\n  amd_ext_api.hsa_amd_ipc_memory_detach_fn = AMD::hsa_amd_ipc_memory_detach;\n  amd_ext_api.hsa_amd_signal_create_fn = AMD::hsa_amd_signal_create;\n  amd_ext_api.hsa_amd_ipc_signal_create_fn = AMD::hsa_amd_ipc_signal_create;\n  amd_ext_api.hsa_amd_ipc_signal_attach_fn = AMD::hsa_amd_ipc_signal_attach;\n  amd_ext_api.hsa_amd_register_system_event_handler_fn = AMD::hsa_amd_register_system_event_handler;\n  amd_ext_api.hsa_amd_queue_intercept_create_fn = AMD::hsa_amd_queue_intercept_create;\n  amd_ext_api.hsa_amd_queue_intercept_register_fn = AMD::hsa_amd_queue_intercept_register;\n  amd_ext_api.hsa_amd_queue_set_priority_fn = AMD::hsa_amd_queue_set_priority;\n  amd_ext_api.hsa_amd_memory_async_copy_rect_fn = AMD::hsa_amd_memory_async_copy_rect;\n  amd_ext_api.hsa_amd_runtime_queue_create_register_fn = AMD::hsa_amd_runtime_queue_create_register;\n  amd_ext_api.hsa_amd_memory_lock_to_pool_fn = AMD::hsa_amd_memory_lock_to_pool;\n  amd_ext_api.hsa_amd_register_deallocation_callback_fn = AMD::hsa_amd_register_deallocation_callback;\n  amd_ext_api.hsa_amd_deregister_deallocation_callback_fn = AMD::hsa_amd_deregister_deallocation_callback;\n  amd_ext_api.hsa_amd_signal_value_pointer_fn = AMD::hsa_amd_signal_value_pointer;\n  amd_ext_api.hsa_amd_svm_attributes_set_fn = AMD::hsa_amd_svm_attributes_set;\n  amd_ext_api.hsa_amd_svm_attributes_get_fn = AMD::hsa_amd_svm_attributes_get;\n  amd_ext_api.hsa_amd_svm_prefetch_async_fn = AMD::hsa_amd_svm_prefetch_async;\n  amd_ext_api.hsa_amd_spm_acquire_fn = AMD::hsa_amd_spm_acquire;\n  amd_ext_api.hsa_amd_spm_release_fn = AMD::hsa_amd_spm_release;\n  amd_ext_api.hsa_amd_spm_set_dest_buffer_fn = AMD::hsa_amd_spm_set_dest_buffer;\n  amd_ext_api.hsa_amd_portable_export_dmabuf_fn = AMD::hsa_amd_portable_export_dmabuf;\n  amd_ext_api.hsa_amd_portable_close_dmabuf_fn = AMD::hsa_amd_portable_close_dmabuf;\n  amd_ext_api.hsa_amd_vmem_address_reserve_fn = AMD::hsa_amd_vmem_address_reserve;\n  amd_ext_api.hsa_amd_vmem_address_reserve_align_fn = AMD::hsa_amd_vmem_address_reserve_align;\n  amd_ext_api.hsa_amd_vmem_address_free_fn = AMD::hsa_amd_vmem_address_free;\n  amd_ext_api.hsa_amd_vmem_handle_create_fn = AMD::hsa_amd_vmem_handle_create;\n  amd_ext_api.hsa_amd_vmem_handle_release_fn = AMD::hsa_amd_vmem_handle_release;\n  amd_ext_api.hsa_amd_vmem_map_fn = AMD::hsa_amd_vmem_map;\n  amd_ext_api.hsa_amd_vmem_unmap_fn = AMD::hsa_amd_vmem_unmap;\n  amd_ext_api.hsa_amd_vmem_set_access_fn = AMD::hsa_amd_vmem_set_access;\n  amd_ext_api.hsa_amd_vmem_get_access_fn = AMD::hsa_amd_vmem_get_access;\n  amd_ext_api.hsa_amd_vmem_export_shareable_handle_fn = AMD::hsa_amd_vmem_export_shareable_handle;\n  amd_ext_api.hsa_amd_vmem_import_shareable_handle_fn = AMD::hsa_amd_vmem_import_shareable_handle;\n  amd_ext_api.hsa_amd_vmem_retain_alloc_handle_fn = AMD::hsa_amd_vmem_retain_alloc_handle;\n  amd_ext_api.hsa_amd_vmem_get_alloc_properties_from_handle_fn =\n      AMD::hsa_amd_vmem_get_alloc_properties_from_handle;\n  amd_ext_api.hsa_amd_agent_set_async_scratch_limit_fn = AMD::hsa_amd_agent_set_async_scratch_limit;\n  amd_ext_api.hsa_amd_queue_get_info_fn = AMD::hsa_amd_queue_get_info;\n  amd_ext_api.hsa_amd_enable_logging_fn = AMD::hsa_amd_enable_logging;\n  amd_ext_api.hsa_amd_signal_wait_all_fn = AMD::hsa_amd_signal_wait_all;\n  amd_ext_api.hsa_amd_memory_get_preferred_copy_engine_fn = AMD::hsa_amd_memory_get_preferred_copy_engine;\n  amd_ext_api.hsa_amd_portable_export_dmabuf_v2_fn = AMD::hsa_amd_portable_export_dmabuf_v2;\n}\n\nvoid HsaApiTable::UpdateTools() {\n  tools_api.version.major_id = HSA_TOOLS_API_TABLE_MAJOR_VERSION;\n  tools_api.version.minor_id = sizeof(::ToolsApiTable);\n  tools_api.version.step_id = HSA_TOOLS_API_TABLE_STEP_VERSION;\n\n  tools_api.hsa_amd_tool_scratch_event_alloc_start_fn = nullptr;\n  tools_api.hsa_amd_tool_scratch_event_alloc_end_fn = nullptr;\n  tools_api.hsa_amd_tool_scratch_event_free_start_fn = nullptr;\n  tools_api.hsa_amd_tool_scratch_event_free_end_fn = nullptr;\n  tools_api.hsa_amd_tool_scratch_event_async_reclaim_start_fn = nullptr;\n  tools_api.hsa_amd_tool_scratch_event_async_reclaim_end_fn = nullptr;\n}\n\nvoid LoadInitialHsaApiTable() {\n  hsa_table_interface_init(&hsa_api_table().hsa_api);\n}\n\n}   //  namespace core\n}   //  namespace rocr\n\nclass Init {\n public:\n  Init() { rocr::core::LoadInitialHsaApiTable(); }\n};\nstatic Init LinkAtLoadOrFirstTranslationUnitAccess;\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/hsa_ext_amd.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <algorithm>\n#include <exception>\n#include <map>\n#include <memory>\n#include <new>\n#include <set>\n#include <typeinfo>\n#include <utility>\n#include <vector>\n\n#include \"core/inc/agent.h\"\n#include \"core/inc/amd_aie_agent.h\"\n#include \"core/inc/amd_cpu_agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/default_signal.h\"\n#include \"core/inc/exceptions.h\"\n#include \"core/inc/intercept_queue.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/ipc_signal.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/signal.h\"\n\nnamespace rocr {\n\ntemplate <class T>\nstruct ValidityError;\ntemplate <>\nstruct ValidityError<core::Signal*> {\n  enum { value = HSA_STATUS_ERROR_INVALID_SIGNAL };\n};\n\ntemplate <>\nstruct ValidityError<core::Agent*> {\n  enum { value = HSA_STATUS_ERROR_INVALID_AGENT };\n};\n\ntemplate <>\nstruct ValidityError<core::MemoryRegion*> {\n  enum { value = HSA_STATUS_ERROR_INVALID_REGION };\n};\n\ntemplate <>\nstruct ValidityError<AMD::MemoryRegion*> {\n  enum { value = HSA_STATUS_ERROR_INVALID_REGION };\n};\n\ntemplate <>\nstruct ValidityError<core::Queue*> {\n  enum { value = HSA_STATUS_ERROR_INVALID_QUEUE };\n};\n\ntemplate <class T>\nstruct ValidityError<const T*> {\n  enum { value = ValidityError<T*>::value };\n};\n\n#define IS_TRUE(var)                                                                               \\\n  do {                                                                                             \\\n    if ((var) != true) return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                   \\\n  } while (false)\n\n#define IS_BAD_PTR(ptr)                                          \\\n  do {                                                           \\\n    if ((ptr) == NULL) return HSA_STATUS_ERROR_INVALID_ARGUMENT; \\\n  } while (false)\n\n#define IS_ZERO(arg)                                                                               \\\n  do {                                                                                             \\\n    if ((arg) == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                      \\\n  } while (false)\n\n#define IS_VALID_FD(fd)                                                                            \\\n  do {                                                                                             \\\n    if ((fd) < 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;                                        \\\n  } while (false)\n\n#define IS_VALID(ptr)                                           \\\n  do {                                                          \\\n    if ((ptr) == NULL || !(ptr)->IsValid())                     \\\n      return hsa_status_t(ValidityError<decltype(ptr)>::value); \\\n  } while (false)\n\n#define IS_NULL_OR_VALID(ptr)                                                                      \\\n  do {                                                                                             \\\n    if ((ptr) != NULL && !(ptr)->IsValid())                                                        \\\n      return hsa_status_t(ValidityError<decltype(ptr)>::value);                                    \\\n  } while (false)\n\n#define CHECK_ALLOC(ptr)                                         \\\n  do {                                                           \\\n    if ((ptr) == NULL) return HSA_STATUS_ERROR_OUT_OF_RESOURCES; \\\n  } while (false)\n\n#define IS_OPEN()                                     \\\n  do {                                                \\\n    if (!core::Runtime::runtime_singleton_->IsOpen()) \\\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;        \\\n  } while (false)\n\ntemplate <class T>\nstatic __forceinline bool IsValid(T* ptr) {\n  return (ptr == NULL) ? NULL : ptr->IsValid();\n}\n\n#define TRY try {\n#define CATCH } catch(...) { return AMD::handleException(); }\n#define CATCHRET(RETURN_TYPE) } catch(...) { return AMD::handleExceptionT<RETURN_TYPE>(); }\n\nnamespace AMD {\n\nhsa_status_t handleException() {\n  try {\n    throw;\n  } catch (const std::bad_alloc& e) {\n    debug_print(\"HSA exception: BadAlloc\\n\");\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  } catch (const hsa_exception& e) {\n    ifdebug {\n      if (!strIsEmpty(e.what())) debug_print(\"HSA exception: %s\\n\", e.what());\n    }\n    return e.error_code();\n  } catch (const std::exception& e) {\n    debug_print(\"Unhandled exception: %s\\n\", e.what());\n    assert(false && \"Unhandled exception.\");\n    return HSA_STATUS_ERROR;\n  } catch (const std::nested_exception& e) {\n    debug_print(\"Callback threw, forwarding.\\n\");\n    e.rethrow_nested();\n    return HSA_STATUS_ERROR;\n  } catch (...) {\n    assert(false && \"Unhandled exception.\");\n    abort();\n    return HSA_STATUS_ERROR;\n  }\n}\n\ntemplate <class T> static __forceinline T handleExceptionT() {\n  handleException();\n  abort();\n  return T();\n}\n\nhsa_status_t hsa_amd_coherency_get_type(hsa_agent_t agent_handle, hsa_amd_coherency_type_t* type) {\n  TRY;\n  IS_OPEN();\n\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n\n  IS_VALID(agent);\n\n  IS_BAD_PTR(type);\n\n  if (agent->device_type() != core::Agent::kAmdGpuDevice) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  const AMD::GpuAgentInt* gpu_agent =\n      static_cast<const AMD::GpuAgentInt*>(agent);\n\n  *type = gpu_agent->current_coherency_type();\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent_handle,\n                                        hsa_amd_coherency_type_t type) {\n  TRY;\n  IS_OPEN();\n\n  core::Agent* agent = core::Agent::Convert(agent_handle);\n\n  IS_VALID(agent);\n\n  if (type < HSA_AMD_COHERENCY_TYPE_COHERENT ||\n      type > HSA_AMD_COHERENCY_TYPE_NONCOHERENT) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (agent->device_type() != core::Agent::kAmdGpuDevice) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  AMD::GpuAgent* gpu_agent = static_cast<AMD::GpuAgent*>(agent);\n\n  if (!gpu_agent->current_coherency_type(type)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {\n  TRY;\n  IS_OPEN();\n\n  if ((ptr == nullptr) || (uintptr_t(ptr) % 4 != 0)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (count == 0) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return core::Runtime::runtime_singleton_->FillMemory(ptr, value, count);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent_handle, const void* src,\n                                       hsa_agent_t src_agent_handle, size_t size,\n                                       uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                       hsa_signal_t completion_signal) {\n  TRY;\n  IS_BAD_PTR(dst);\n  IS_BAD_PTR(src);\n\n  if ((num_dep_signals == 0 && dep_signals != nullptr) ||\n      (num_dep_signals > 0 && dep_signals == nullptr)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  core::Agent* dst_agent = core::Agent::Convert(dst_agent_handle);\n  IS_VALID(dst_agent);\n\n  core::Agent* src_agent = core::Agent::Convert(src_agent_handle);\n  IS_VALID(src_agent);\n\n  std::vector<core::Signal*> dep_signal_list(num_dep_signals);\n  if (num_dep_signals > 0) {\n    for (size_t i = 0; i < num_dep_signals; ++i) {\n      core::Signal* dep_signal_obj = core::Signal::Convert(dep_signals[i]);\n      IS_VALID(dep_signal_obj);\n      dep_signal_list[i] = dep_signal_obj;\n    }\n  }\n\n  core::Signal* out_signal_obj = core::Signal::Convert(completion_signal);\n  IS_VALID(out_signal_obj);\n\n  bool rev_copy_dir = core::Runtime::runtime_singleton_->flag().rev_copy_dir();\n  if (size > 0) {\n    return core::Runtime::runtime_singleton_->CopyMemory(\n        dst, (rev_copy_dir ? src_agent : dst_agent),\n        src, (rev_copy_dir ? dst_agent : src_agent),\n        size, dep_signal_list, *out_signal_obj);\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_async_copy_on_engine(void* dst, hsa_agent_t dst_agent_handle,\n                                       const void* src, hsa_agent_t src_agent_handle, size_t size,\n                                       uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                       hsa_signal_t completion_signal,\n                                       hsa_amd_sdma_engine_id_t engine_id,\n                                       bool force_copy_on_sdma) {\n  TRY;\n  IS_BAD_PTR(dst);\n  IS_BAD_PTR(src);\n\n  if ((num_dep_signals == 0 && dep_signals != nullptr) ||\n      (num_dep_signals > 0 && dep_signals == nullptr)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  core::Agent* dst_agent = core::Agent::Convert(dst_agent_handle);\n  IS_VALID(dst_agent);\n\n  core::Agent* src_agent = core::Agent::Convert(src_agent_handle);\n  IS_VALID(src_agent);\n\n  std::vector<core::Signal*> dep_signal_list(num_dep_signals);\n  if (num_dep_signals > 0) {\n    for (size_t i = 0; i < num_dep_signals; ++i) {\n      core::Signal* dep_signal_obj = core::Signal::Convert(dep_signals[i]);\n      IS_VALID(dep_signal_obj);\n      dep_signal_list[i] = dep_signal_obj;\n    }\n  }\n\n  core::Signal* out_signal_obj = core::Signal::Convert(completion_signal);\n  IS_VALID(out_signal_obj);\n\n  bool rev_copy_dir = core::Runtime::runtime_singleton_->flag().rev_copy_dir();\n  if (size > 0) {\n    return core::Runtime::runtime_singleton_->CopyMemoryOnEngine(\n        dst, (rev_copy_dir ? src_agent : dst_agent),\n        src, (rev_copy_dir ? dst_agent : src_agent),\n        size, dep_signal_list, *out_signal_obj, engine_id, force_copy_on_sdma);\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_copy_engine_status(hsa_agent_t dst_agent_handle,\n                                               hsa_agent_t src_agent_handle,\n                                               uint32_t *engine_ids_mask) {\n  core::Agent* dst_agent = core::Agent::Convert(dst_agent_handle);\n  IS_VALID(dst_agent);\n\n  core::Agent* src_agent = core::Agent::Convert(src_agent_handle);\n  IS_VALID(src_agent);\n\n  return core::Runtime::runtime_singleton_->CopyMemoryStatus(dst_agent, src_agent,\n                                                             engine_ids_mask);\n}\n\nhsa_status_t hsa_amd_memory_get_preferred_copy_engine(hsa_agent_t dst_agent_handle,\n                                                      hsa_agent_t src_agent_handle,\n                                                      uint32_t* recommended_ids_mask) {\n  core::Agent* dst_agent = core::Agent::Convert(dst_agent_handle);\n  IS_VALID(dst_agent);\n\n  core::Agent* src_agent = core::Agent::Convert(src_agent_handle);\n  IS_VALID(src_agent);\n\n  return core::Runtime::runtime_singleton_->GetPreferredEngine(dst_agent, src_agent,\n                                                               recommended_ids_mask);\n}\n\nhsa_status_t hsa_amd_memory_async_copy_rect(\n    const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,\n    const hsa_dim3_t* src_offset, const hsa_dim3_t* range, hsa_agent_t copy_agent,\n    hsa_amd_copy_direction_t dir, uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n    hsa_signal_t completion_signal) {\n  TRY;\n  if (dst == nullptr || src == nullptr || dst_offset == nullptr || src_offset == nullptr ||\n      range == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if ((num_dep_signals == 0 && dep_signals != NULL) ||\n      (num_dep_signals > 0 && dep_signals == NULL)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (dir == hsaHostToHost) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  core::Agent* base_agent = core::Agent::Convert(copy_agent);\n  IS_VALID(base_agent);\n  if (base_agent->device_type() != core::Agent::DeviceType::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  AMD::GpuAgent* agent = static_cast<AMD::GpuAgent*>(base_agent);\n\n  std::vector<core::Signal*> dep_signal_list(num_dep_signals);\n  if (num_dep_signals > 0) {\n    for (size_t i = 0; i < num_dep_signals; ++i) {\n      core::Signal* dep_signal_obj = core::Signal::Convert(dep_signals[i]);\n      IS_VALID(dep_signal_obj);\n      dep_signal_list[i] = dep_signal_obj;\n    }\n  }\n\n  core::Signal* out_signal_obj = core::Signal::Convert(completion_signal);\n  IS_VALID(out_signal_obj);\n\n  if ((range->x != 0) && (range->y != 0) && (range->z != 0)) {\n    return agent->DmaCopyRect(dst, dst_offset, src, src_offset, range, dir, dep_signal_list,\n                              *out_signal_obj);\n  }\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n\nhsa_status_t hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {\n  TRY;\n  IS_OPEN();\n\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n\n  cmd_queue->SetProfiling(enable);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_profiling_async_copy_enable(bool enable) {\n  TRY;\n  IS_OPEN();\n\n  hsa_status_t ret = HSA_STATUS_SUCCESS;\n  for (core::Agent* agent : core::Runtime::runtime_singleton_->gpu_agents()) {\n    hsa_status_t err = agent->profiling_enabled(enable);\n    if (err != HSA_STATUS_SUCCESS) ret = err;\n  }\n\n  for (core::Agent* agent : core::Runtime::runtime_singleton_->cpu_agents()) {\n    hsa_status_t err = agent->profiling_enabled(enable);\n    if (err != HSA_STATUS_SUCCESS) ret = err;\n  }\n  return ret;\n\n  CATCH;\n}\n\nhsa_status_t hsa_amd_profiling_get_dispatch_time(\n    hsa_agent_t agent_handle, hsa_signal_t hsa_signal,\n    hsa_amd_profiling_dispatch_time_t* time) {\n  TRY;\n  IS_OPEN();\n\n  IS_BAD_PTR(time);\n\n  core::Agent* agent = core::Agent::Convert(agent_handle);\n\n  IS_VALID(agent);\n\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n\n  IS_VALID(signal);\n\n  if (agent->device_type() != core::Agent::kAmdGpuDevice) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(agent);\n\n  // Translate timestamp from GPU to system domain.\n  gpu_agent->TranslateTime(signal, *time);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_profiling_get_async_copy_time(\n    hsa_signal_t hsa_signal, hsa_amd_profiling_async_copy_time_t* time) {\n  TRY;\n  IS_OPEN();\n\n  IS_BAD_PTR(time);\n\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n\n  IS_VALID(signal);\n\n  core::Agent* agent = signal->async_copy_agent();\n\n  if (agent == nullptr) {\n    return HSA_STATUS_ERROR;\n  }\n\n  if (agent->device_type() == core::Agent::DeviceType::kAmdGpuDevice) {\n    // Translate timestamp from GPU to system domain.\n    static_cast<AMD::GpuAgentInt*>(agent)->TranslateTime(signal, *time);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // The timestamp is already in system domain.\n  time->start = signal->signal_.start_ts;\n  time->end = signal->signal_.end_ts;\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent_handle,\n                                                             uint64_t agent_tick,\n                                                             uint64_t* system_tick) {\n  TRY;\n  IS_OPEN();\n\n  IS_BAD_PTR(system_tick);\n\n  core::Agent* agent = core::Agent::Convert(agent_handle);\n\n  IS_VALID(agent);\n\n  if (agent->device_type() != core::Agent::kAmdGpuDevice) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(agent);\n\n  *system_tick = gpu_agent->TranslateTime(agent_tick);\n\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                                   const hsa_agent_t* consumers, uint64_t attributes,\n                                   hsa_signal_t* hsa_signal) {\n  struct AgentHandleCompare {\n    bool operator()(const hsa_agent_t& lhs, const hsa_agent_t& rhs) const {\n      return lhs.handle < rhs.handle;\n    }\n  };\n\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(hsa_signal);\n\n  core::Signal* ret;\n\n  bool enable_ipc = attributes & HSA_AMD_SIGNAL_IPC;\n  bool use_default =\n      enable_ipc || (attributes & HSA_AMD_SIGNAL_AMD_GPU_ONLY) || (!core::g_use_interrupt_wait);\n\n  if ((!use_default) && (num_consumers != 0)) {\n    IS_BAD_PTR(consumers);\n\n    // Check for duplicates in consumers.\n    std::set<hsa_agent_t, AgentHandleCompare> consumer_set(consumers, consumers + num_consumers);\n    if (consumer_set.size() != num_consumers) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    use_default = true;\n    for (const core::Agent* cpu_agent : core::Runtime::runtime_singleton_->cpu_agents()) {\n      use_default &= (consumer_set.find(cpu_agent->public_handle()) == consumer_set.end());\n    }\n  }\n\n  if (use_default) {\n    ret = new core::DefaultSignal(initial_value, enable_ipc);\n  } else {\n    ret = new core::InterruptSignal(initial_value);\n  }\n\n  *hsa_signal = core::Signal::Convert(ret);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_signal_value_pointer(hsa_signal_t hsa_signal,\n                                          volatile hsa_signal_value_t** value_ptr) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value_ptr);\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  IS_VALID(signal);\n\n  if(!core::BusyWaitSignal::IsType(signal))\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  *value_ptr = (volatile hsa_signal_value_t*)&signal->signal_.value;\n  return HSA_STATUS_SUCCESS;\n\n  CATCH;\n}\n\nuint32_t hsa_amd_signal_wait_all(uint32_t signal_count, hsa_signal_t* hsa_signals,\n                                 hsa_signal_condition_t* conds, hsa_signal_value_t* values,\n                                 uint64_t timeout_hint, hsa_wait_state_t wait_hint,\n                                 hsa_signal_value_t* satisfying_values) {\n  TRY;\n  if (!core::Runtime::runtime_singleton_->IsOpen()) {\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_NOT_INITIALIZED, \"hsa_amd_signal_wait_all called while not initialized\");\n  }\n\n  // Treat NULL and invalid signals as already satisfied their condition and skip them\n  std::vector<hsa_signal_t> valid_signals;\n  std::vector<uint32_t> valid_signal_ids;\n  for (uint32_t i = 0; i < signal_count; i++){\n    if (hsa_signals[i].handle != 0 && core::SharedSignal::Convert(hsa_signals[i])->IsValid()){\n      valid_signals.emplace_back(hsa_signals[i]);\n      valid_signal_ids.emplace_back(i);\n    }\n  }\n\n  // Return if there's no valid signal to wait on\n  if (valid_signals.empty()){\n    if (satisfying_values) {\n      // Set 0 as satisfying value for NULL and invalid signals\n      std::fill(satisfying_values, satisfying_values + signal_count, 0);\n    }\n    return uint32_t(0);\n  }\n\n  uint32_t valid_signal_count = valid_signals.size();\n\n  std::vector<hsa_signal_value_t> satisfying_values_vec(valid_signal_count);\n  uint32_t first_satysifying_signal_idx =\n      core::Signal::WaitMultiple(valid_signal_count, valid_signals.data(), conds, values, timeout_hint, wait_hint,\n                                 satisfying_values_vec, true);\n\n  if (satisfying_values) {\n    // Set 0 as satisfying value for NULL and invalid signals\n    std::vector<hsa_signal_value_t> satisfying_values_vec_result(signal_count, 0);\n    for (uint32_t i = 0; i < valid_signal_count; i++){\n      satisfying_values_vec_result[valid_signal_ids[i]] = satisfying_values_vec[i];\n    }\n    std::copy(satisfying_values_vec_result.begin(), satisfying_values_vec_result.end(), satisfying_values);\n  }\n\n  return first_satysifying_signal_idx;\n  CATCHRET(uint32_t);\n}\n\nuint32_t hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* hsa_signals,\n                                 hsa_signal_condition_t* conds, hsa_signal_value_t* values,\n                                 uint64_t timeout_hint, hsa_wait_state_t wait_hint,\n                                 hsa_signal_value_t* satisfying_value) {\n  TRY;\n  if (!core::Runtime::runtime_singleton_->IsOpen()) {\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_NOT_INITIALIZED, \"hsa_amd_signal_wait_any called while not initialized\");\n  }\n\n  // Ignore NULL and invalid signals\n  std::vector<hsa_signal_t> valid_signals;\n  std::vector<uint32_t> valid_signal_ids;\n  for (uint32_t i = 0; i < signal_count; i++){\n    if (hsa_signals[i].handle != 0 && core::SharedSignal::Convert(hsa_signals[i])->IsValid()){\n      valid_signals.emplace_back(hsa_signals[i]);\n      valid_signal_ids.emplace_back(i);\n    }\n  }\n\n  // Return if there's no valid signal to wait on\n  // satisfying_value is ignored\n  if (valid_signals.empty()){\n    return std::numeric_limits<uint32_t>::max();\n  }\n\n  std::vector<hsa_signal_value_t> satisfying_value_vec(1);\n  uint32_t satisfying_signal_idx =\n      core::Signal::WaitMultiple(valid_signals.size(), valid_signals.data(), conds, values, timeout_hint, wait_hint,\n                                 satisfying_value_vec, false);\n\n  //  Map back the index\n  satisfying_signal_idx = valid_signal_ids[satisfying_signal_idx];\n\n  if (satisfying_value) *satisfying_value = satisfying_value_vec.at(0);\n\n  return satisfying_signal_idx;\n  CATCHRET(uint32_t);\n}\n\nhsa_status_t hsa_amd_signal_async_handler(hsa_signal_t hsa_signal, hsa_signal_condition_t cond,\n                                          hsa_signal_value_t value, hsa_amd_signal_handler handler,\n                                          void* arg) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(handler);\n\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  IS_VALID(signal);\n\n  if ((core::g_use_interrupt_wait && (!core::InterruptSignal::IsType(signal)) &&\n      !core::IPCSignal::IsType(signal)))\n    return HSA_STATUS_ERROR_INVALID_SIGNAL;\n  return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(\n      hsa_signal, cond, value, handler, arg);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_async_function(void (*callback)(void* arg), void* arg) {\n  TRY;\n  IS_OPEN();\n\n  IS_BAD_PTR(callback);\n  static const hsa_signal_t null_signal = {0};\n  return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(\n      null_signal, HSA_SIGNAL_CONDITION_EQ, 0, (hsa_amd_signal_handler)callback,\n      arg);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue, uint32_t num_cu_mask_count,\n                                       const uint32_t* cu_mask) {\n  TRY;\n  IS_OPEN();\n\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n  if (num_cu_mask_count != 0) IS_BAD_PTR(cu_mask);\n  if (num_cu_mask_count % 32 != 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  return cmd_queue->SetCUMasking(num_cu_mask_count, cu_mask);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_queue_cu_get_mask(const hsa_queue_t* queue, uint32_t num_cu_mask_count,\n                                       uint32_t* cu_mask) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(cu_mask);\n\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n  if ((num_cu_mask_count == 0) || (num_cu_mask_count % 32 != 0))\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  return cmd_queue->GetCUMasking(num_cu_mask_count, cu_mask);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,\n                                 hsa_agent_t* agents, int num_agent,\n                                 void** agent_ptr) {\n  TRY;\n  IS_OPEN();\n\n  if (size == 0 || host_ptr == nullptr || agent_ptr == nullptr) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  *agent_ptr = nullptr;\n\n  if ((agents != nullptr && num_agent == 0) || (agents == nullptr && num_agent != 0)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  // Check for APU\n  if (core::Runtime::runtime_singleton_->system_regions_coarse().size() == 0) {\n    assert(core::Runtime::runtime_singleton_->system_regions_fine()[0]->full_profile() &&\n           \"Missing coarse grain host memory on dGPU system.\");\n    *agent_ptr = host_ptr;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  const AMD::MemoryRegion* system_region = static_cast<const AMD::MemoryRegion*>(\n      core::Runtime::runtime_singleton_->system_regions_coarse()[0]);\n\n  return system_region->Lock(num_agent, agents, host_ptr, size, agent_ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_lock_to_pool(void* host_ptr, size_t size, hsa_agent_t* agents,\n                                         int num_agent, hsa_amd_memory_pool_t pool, uint32_t flags,\n                                         void** agent_ptr) {\n  TRY;\n  IS_OPEN();\n\n  if (size == 0 || host_ptr == nullptr || agent_ptr == nullptr || flags != 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  *agent_ptr = nullptr;\n\n  if ((agents != nullptr && num_agent == 0) || (agents == nullptr && num_agent != 0)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_t region = {pool.handle};\n  const AMD::MemoryRegion* mem_region = AMD::MemoryRegion::Convert(region);\n  if (mem_region == nullptr) {\n    return (hsa_status_t)HSA_STATUS_ERROR_INVALID_MEMORY_POOL;\n  }\n  if (mem_region->owner()->device_type() != core::Agent::kAmdCpuDevice)\n    return (hsa_status_t)HSA_STATUS_ERROR_INVALID_MEMORY_POOL;\n\n  return mem_region->Lock(num_agent, agents, host_ptr, size, agent_ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_unlock(void* host_ptr) {\n  TRY;\n  IS_OPEN();\n\n  const AMD::MemoryRegion* system_region =\n      reinterpret_cast<const AMD::MemoryRegion*>(\n          core::Runtime::runtime_singleton_->system_regions_fine()[0]);\n\n  return system_region->Unlock(host_ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,\n                                          hsa_amd_memory_pool_info_t attribute, void* value) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(value);\n\n  hsa_region_t region = {memory_pool.handle};\n  const AMD::MemoryRegion* mem_region = AMD::MemoryRegion::Convert(region);\n  if (mem_region == NULL) {\n    return (hsa_status_t)HSA_STATUS_ERROR_INVALID_MEMORY_POOL;\n  }\n\n  return mem_region->GetPoolInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_agent_iterate_memory_pools(\n    hsa_agent_t agent_handle,\n    hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),\n    void* data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  switch (agent->device_type()) {\n  case core::Agent::kAmdCpuDevice:\n    return reinterpret_cast<const AMD::CpuAgent *>(agent)->VisitRegion(\n        false,\n        reinterpret_cast<hsa_status_t (*)(hsa_region_t memory_pool,\n                                          void *data)>(callback),\n        data);\n  case core::Agent::kAmdAieDevice:\n    return reinterpret_cast<const AMD::AieAgent *>(agent)->VisitRegion(\n        false,\n        reinterpret_cast<hsa_status_t (*)(hsa_region_t memory_pool,\n                                          void *data)>(callback),\n        data);\n  case core::Agent::kAmdGpuDevice:\n    return reinterpret_cast<const AMD::GpuAgentInt *>(agent)->VisitRegion(\n        false,\n        reinterpret_cast<hsa_status_t (*)(hsa_region_t memory_pool,\n                                          void *data)>(callback),\n        data);\n  default:\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,\n                                          uint32_t flags, void** ptr) {\n  TRY;\n  IS_OPEN();\n\n  if (size == 0 || ptr == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_t region = {memory_pool.handle};\n  const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);\n\n  if (mem_region == NULL || !mem_region->IsValid()) {\n    return (hsa_status_t)HSA_STATUS_ERROR_INVALID_MEMORY_POOL;\n  }\n\n  MemoryRegion::AllocateFlags alloc_flag = core::MemoryRegion::AllocateRestrict;\n\n  if (flags & HSA_AMD_MEMORY_POOL_PCIE_FLAG)\n    alloc_flag |= core::MemoryRegion::AllocatePCIeRW;\n\n  if (flags & HSA_AMD_MEMORY_POOL_CONTIGUOUS_FLAG)\n    alloc_flag |= core::MemoryRegion::AllocateContiguous;\n\n  if (flags & HSA_AMD_MEMORY_POOL_EXECUTABLE_FLAG)\n    alloc_flag |= core::MemoryRegion::AllocateExecutable;\n\n#ifdef SANITIZER_AMDGPU\n  if (mem_region->owner()->device_type() == core::Agent::kAmdGpuDevice)\n    alloc_flag |= core::MemoryRegion::AllocateAsan;\n#endif\n\n  return core::Runtime::runtime_singleton_->AllocateMemory(mem_region, size, alloc_flag, ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_pool_free(void* ptr) {\n  return HSA::hsa_memory_free(ptr);\n}\n\nhsa_status_t hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,\n                                         const uint32_t* flags, const void* ptr) {\n  TRY;\n  IS_OPEN();\n\n  if (num_agents == 0 || agents == NULL || flags != NULL || ptr == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return core::Runtime::runtime_singleton_->AllowAccess(num_agents, agents,\n                                                        ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,\n                                             hsa_amd_memory_pool_t dst_memory_pool, bool* result) {\n  TRY;\n  IS_OPEN();\n\n  if (result == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_t src_region_handle = {src_memory_pool.handle};\n  const AMD::MemoryRegion* src_mem_region =\n      AMD::MemoryRegion::Convert(src_region_handle);\n\n  if (src_mem_region == NULL || !src_mem_region->IsValid()) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_INVALID_MEMORY_POOL);\n  }\n\n  hsa_region_t dst_region_handle = {dst_memory_pool.handle};\n  const AMD::MemoryRegion* dst_mem_region =\n      AMD::MemoryRegion::Convert(dst_region_handle);\n\n  if (dst_mem_region == NULL || !dst_mem_region->IsValid()) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_INVALID_MEMORY_POOL);\n  }\n\n  return src_mem_region->CanMigrate(*dst_mem_region, *result);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_memory_migrate(const void* ptr,\n                                    hsa_amd_memory_pool_t memory_pool,\n                                    uint32_t flags) {\n  TRY;\n  IS_OPEN();\n\n  if (ptr == NULL || flags != 0) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_t dst_region_handle = {memory_pool.handle};\n  const AMD::MemoryRegion* dst_mem_region =\n      AMD::MemoryRegion::Convert(dst_region_handle);\n\n  if (dst_mem_region == NULL || !dst_mem_region->IsValid()) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_INVALID_MEMORY_POOL);\n  }\n\n  return dst_mem_region->Migrate(flags, ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_agent_memory_pool_get_info(\n    hsa_agent_t agent_handle, hsa_amd_memory_pool_t memory_pool,\n    hsa_amd_agent_memory_pool_info_t attribute, void* value) {\n  TRY;\n  IS_OPEN();\n\n  if (value == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  const core::Agent* agent = core::Agent::Convert(agent_handle);\n  IS_VALID(agent);\n\n  hsa_region_t region_handle = {memory_pool.handle};\n  const AMD::MemoryRegion* mem_region =\n      AMD::MemoryRegion::Convert(region_handle);\n\n  if (mem_region == NULL || !mem_region->IsValid()) {\n    return static_cast<hsa_status_t>(HSA_STATUS_ERROR_INVALID_MEMORY_POOL);\n  }\n\n  return mem_region->GetAgentPoolInfo(*agent, attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,\n                                        hsa_agent_t* agents, int interop_handle,\n                                        uint32_t flags, size_t* size,\n                                        void** ptr, size_t* metadata_size,\n                                        const void** metadata) {\n  static const int tinyArraySize=8;\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(agents);\n  IS_BAD_PTR(size);\n  IS_BAD_PTR(ptr);\n  if (flags != 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  if (num_agents == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  core::Agent* short_agents[tinyArraySize];\n  core::Agent** core_agents = short_agents;\n  if (num_agents > tinyArraySize) {\n    core_agents = new core::Agent* [num_agents];\n    if (core_agents == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  MAKE_SCOPE_GUARD([&]() {\n    if (num_agents > tinyArraySize) delete[] core_agents;\n  });\n\n  for (uint32_t i = 0; i < num_agents; i++) {\n    core::Agent* device = core::Agent::Convert(agents[i]);\n    IS_VALID(device);\n    core_agents[i] = device;\n  }\n\n  auto ret = core::Runtime::runtime_singleton_->InteropMap(\n      num_agents, core_agents, interop_handle, flags, size, ptr, metadata_size,\n      metadata);\n\n  return ret;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_interop_unmap_buffer(void* ptr) {\n  TRY;\n  IS_OPEN();\n  if (ptr != NULL) core::Runtime::runtime_singleton_->InteropUnmap(ptr);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_pointer_info(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),\n                                  uint32_t* num_accessible, hsa_agent_t** accessible) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  IS_BAD_PTR(info);\n  return core::Runtime::runtime_singleton_->PtrInfo(ptr, info, alloc, num_accessible, accessible);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_pointer_info_set_userdata(const void* ptr, void* userdata) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  return core::Runtime::runtime_singleton_->SetPtrInfoData(ptr, userdata);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_ipc_memory_create(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  IS_BAD_PTR(handle);\n  return core::Runtime::runtime_singleton_->IPCCreate(ptr, len, handle);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t len,\n                                       uint32_t num_agents, const hsa_agent_t* mapping_agents,\n                                       void** mapped_ptr) {\n  static const int tinyArraySize = 8;\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(mapped_ptr);\n  if (num_agents != 0) IS_BAD_PTR(mapping_agents);\n\n  core::Agent** core_agents = nullptr;\n  if (num_agents > tinyArraySize)\n    core_agents = new core::Agent*[num_agents];\n  else\n    core_agents = (core::Agent**)alloca(sizeof(core::Agent*) * num_agents);\n  if (core_agents == NULL) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  MAKE_SCOPE_GUARD([&]() {\n    if (num_agents > tinyArraySize) delete[] core_agents;\n  });\n\n  for (uint32_t i = 0; i < num_agents; i++) {\n    core::Agent* device = core::Agent::Convert(mapping_agents[i]);\n    IS_VALID(device);\n    core_agents[i] = device;\n  }\n\n  return core::Runtime::runtime_singleton_->IPCAttach(ipc, len, num_agents, core_agents,\n                                                      mapped_ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_ipc_memory_detach(void* mapped_ptr) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(mapped_ptr);\n  return core::Runtime::runtime_singleton_->IPCDetach(mapped_ptr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_ipc_signal_create(hsa_signal_t hsa_signal, hsa_amd_ipc_signal_t* handle) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(handle);\n  core::Signal* signal = core::Signal::Convert(hsa_signal);\n  IS_VALID(signal);\n  core::IPCSignal::CreateHandle(signal, handle);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handle,\n                                       hsa_signal_t* hsa_signal) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(handle);\n  IS_BAD_PTR(hsa_signal);\n  core::Signal* signal = core::IPCSignal::Attach(handle);\n  *hsa_signal = core::Signal::Convert(signal);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n// For use by tools only - not in library export table.\nhsa_status_t hsa_amd_queue_intercept_create(\n    hsa_agent_t agent_handle, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,\n    uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(queue);\n\n  // A wrapped queue for the intercept queue must have at least 3 slots so\n  // there is space for a packet, a new retry barrier packet, and an existing\n  // retry packet that is in the process of being processed.\n  if (size < 3) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  hsa_queue_t* lower_queue;\n  hsa_status_t err = HSA::hsa_queue_create(agent_handle, size, type, callback, data,\n                                           private_segment_size, group_segment_size, &lower_queue);\n  if (err != HSA_STATUS_SUCCESS) return err;\n  std::unique_ptr<core::Queue> lowerQueue(core::Queue::Convert(lower_queue));\n\n  std::unique_ptr<core::InterceptQueue> upperQueue(new core::InterceptQueue(std::move(lowerQueue)));\n\n  *queue = core::Queue::Convert(upperQueue.release());\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\n// For use by tools only - not in library export table.\nhsa_status_t hsa_amd_queue_intercept_register(hsa_queue_t* queue,\n                                              hsa_amd_queue_intercept_handler callback,\n                                              void* user_data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(callback);\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n  if (!core::InterceptQueue::IsType(cmd_queue)) return HSA_STATUS_ERROR_INVALID_QUEUE;\n  core::InterceptQueue* iQueue = static_cast<core::InterceptQueue*>(cmd_queue);\n  iQueue->AddInterceptor(callback, user_data);\n  return HSA_STATUS_SUCCESS;\n  CATCH;\n}\n\nhsa_status_t hsa_amd_register_system_event_handler(hsa_amd_system_event_callback_t callback,\n                                                   void* data) {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->SetCustomSystemEventHandler(callback, data);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_queue_set_priority(hsa_queue_t* queue,\n                                                hsa_amd_queue_priority_t priority) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(queue);\n  core::Queue* cmd_queue = core::Queue::Convert(queue);\n  IS_VALID(cmd_queue);\n\n  // Highest queue priority allowed for HSA user is HSA_QUEUE_PRIORITY_HIGH\n  // HSA_QUEUE_PRIORITY_MAXIMUM is reserved for PC Sampling and can only be allocated internally\n  // in ROCR\n  static std::map<hsa_amd_queue_priority_t, HSA_QUEUE_PRIORITY> ext_kmt_priomap = {\n      {HSA_AMD_QUEUE_PRIORITY_LOW, HSA_QUEUE_PRIORITY_MINIMUM},\n      {HSA_AMD_QUEUE_PRIORITY_NORMAL, HSA_QUEUE_PRIORITY_NORMAL},\n      {HSA_AMD_QUEUE_PRIORITY_HIGH, HSA_QUEUE_PRIORITY_HIGH},\n  };\n\n  auto priority_it = ext_kmt_priomap.find(priority);\n\n  if (priority_it == ext_kmt_priomap.end()) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return cmd_queue->SetPriority(priority_it->second);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_register_deallocation_callback(void* ptr,\n                                                    hsa_amd_deallocation_callback_t callback,\n                                                    void* user_data) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  IS_BAD_PTR(callback);\n\n  return core::Runtime::runtime_singleton_->RegisterReleaseNotifier(ptr, callback, user_data);\n\n  CATCH;\n}\n\nhsa_status_t hsa_amd_deregister_deallocation_callback(void* ptr,\n                                                      hsa_amd_deallocation_callback_t callback) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  IS_BAD_PTR(callback);\n\n  return core::Runtime::runtime_singleton_->DeregisterReleaseNotifier(ptr, callback);\n\n  CATCH;\n}\n\n// For use by tools only - not in library export table.\nhsa_status_t hsa_amd_runtime_queue_create_register(hsa_amd_runtime_queue_notifier callback,\n                                                   void* user_data) {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->SetInternalQueueCreateNotifier(callback, user_data);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_svm_attributes_set(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count) {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->SetSvmAttrib(ptr, size, attribute_list,\n                                                         attribute_count);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_svm_attributes_get(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count) {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->GetSvmAttrib(ptr, size, attribute_list,\n                                                         attribute_count);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_svm_prefetch_async(void* ptr, size_t size, hsa_agent_t agent,\n                                        uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                        hsa_signal_t completion_signal) {\n  TRY;\n  IS_OPEN();\n  // Validate inputs.\n  // if (core::g_use_interrupt_wait && (!core::InterruptSignal::IsType(signal)))\n  return core::Runtime::runtime_singleton_->SvmPrefetch(ptr, size, agent, num_dep_signals,\n                                                        dep_signals, completion_signal);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_spm_acquire(hsa_agent_t preferred_agent) {\n  TRY;\n  IS_OPEN();\n  const core::Agent* agent = core::Agent::Convert(preferred_agent);\n  // Currently, the SPM API is only supported for GPU agents.\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return agent->driver().SPMAcquire(agent->node_id());\n\n  CATCH;\n}\n\nhsa_status_t hsa_amd_spm_release(hsa_agent_t preferred_agent) {\n  TRY;\n  IS_OPEN();\n\n  const core::Agent* agent = core::Agent::Convert(preferred_agent);\n  // Currently, the SPM API is only supported for GPU agents.\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return agent->driver().SPMRelease(agent->node_id());\n\n  CATCH;\n}\n\nhsa_status_t hsa_amd_spm_set_dest_buffer(hsa_agent_t preferred_agent, size_t size_in_bytes,\n                                         uint32_t* timeout, uint32_t* size_copied, void* dest,\n                                         bool* is_data_loss) {\n  TRY;\n  IS_OPEN();\n\n  const core::Agent* agent = core::Agent::Convert(preferred_agent);\n  // Currently, the SPM API is only supported for GPU agents.\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return agent->driver().SPMSetDestBuffer(agent->node_id(), size_in_bytes, timeout, size_copied,\n                                          dest, is_data_loss);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_portable_export_dmabuf(const void* ptr, size_t size, int* dmabuf,\n  uint64_t* offset) {\nTRY;\nIS_OPEN();\nIS_BAD_PTR(ptr);\nIS_BAD_PTR(dmabuf);\nIS_BAD_PTR(offset);\nIS_ZERO(size);\nreturn core::Runtime::runtime_singleton_->DmaBufExport(ptr, size, dmabuf,\n                                    offset, HSA_AMD_DMABUF_MAPPING_TYPE_NONE);\nCATCH;\n}\n\nhsa_status_t hsa_amd_portable_export_dmabuf_v2(const void* ptr, size_t size,\n                              int* dmabuf, uint64_t* offset, uint64_t flags) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(ptr);\n  IS_BAD_PTR(dmabuf);\n  IS_BAD_PTR(offset);\n  IS_ZERO(size);\n  return core::Runtime::runtime_singleton_->DmaBufExport(ptr, size,\n                                                      dmabuf, offset, flags);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_portable_close_dmabuf(int dmabuf) {\n  TRY;\n  return core::Runtime::runtime_singleton_->DmaBufClose(dmabuf);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_address_reserve(void** va, size_t size, uint64_t address,\n                                          uint64_t flags) {\n  TRY;\n  IS_OPEN();\n  IS_ZERO(size);\n\n  if (!(flags & HSA_AMD_VMEM_ADDRESS_NO_REGISTER))\n    IS_TRUE(core::Runtime::runtime_singleton_->VirtualMemApiSupported());\n\n  return core::Runtime::runtime_singleton_->VMemoryAddressReserve(va, size, address, 0, flags);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_address_reserve_align(void** va, size_t size, uint64_t address,\n                                          uint64_t alignment, uint64_t flags) {\n  TRY;\n  IS_OPEN();\n  IS_ZERO(size);\n  IS_TRUE(core::Runtime::runtime_singleton_->VirtualMemApiSupported());\n  return core::Runtime::runtime_singleton_->VMemoryAddressReserve(va, size, address, alignment, flags);\n  CATCH;\n}\n\n\nhsa_status_t hsa_amd_vmem_address_free(void* va, size_t size) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(va);\n  IS_ZERO(size);\n  return core::Runtime::runtime_singleton_->VMemoryAddressFree(va, size);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_handle_create(hsa_amd_memory_pool_t memory_pool, size_t size,\n                                        hsa_amd_memory_type_t type, uint64_t flags,\n                                        hsa_amd_vmem_alloc_handle_t* memory_handle) {\n  TRY;\n  IS_OPEN();\n  IS_ZERO(size);\n  IS_TRUE(core::Runtime::runtime_singleton_->VirtualMemApiSupported());\n\n  if (type != MEMORY_TYPE_NONE && type != MEMORY_TYPE_PINNED)\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  hsa_region_t region = {memory_pool.handle};\n  const core::MemoryRegion* mem_region = core::MemoryRegion::Convert(region);\n\n  if (mem_region == NULL || !mem_region->IsValid()) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  MemoryRegion::AllocateFlags alloc_flag = core::MemoryRegion::AllocateMemoryOnly;\n  if (type == MEMORY_TYPE_PINNED) alloc_flag |= core::MemoryRegion::AllocatePinned;\n\n  return core::Runtime::runtime_singleton_->VMemoryHandleCreate(mem_region, size, alloc_flag, flags,\n                                                                memory_handle);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_handle_release(hsa_amd_vmem_alloc_handle_t memory_handle) {\n  TRY;\n  IS_OPEN();\n  return core::Runtime::runtime_singleton_->VMemoryHandleRelease(memory_handle);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_map(void* va, size_t size, size_t in_offset,\n                              hsa_amd_vmem_alloc_handle_t memory_handle, uint64_t flags) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(va);\n  IS_ZERO(size);\n\n  return core::Runtime::runtime_singleton_->VMemoryHandleMap(va, size, in_offset, memory_handle,\n                                                             flags);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_unmap(void* va, size_t size) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(va);\n  IS_ZERO(size);\n\n  return core::Runtime::runtime_singleton_->VMemoryHandleUnmap(va, size);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_set_access(void* va, size_t size,\n                                     const hsa_amd_memory_access_desc_t* desc,\n                                     size_t desc_cnt) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(va);\n  IS_ZERO(size);\n  IS_BAD_PTR(desc);\n  IS_ZERO(desc_cnt);\n\n  return core::Runtime::runtime_singleton_->VMemorySetAccess(va, size, desc, desc_cnt);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_get_access(void* va, hsa_access_permission_t* perms,\n                                     hsa_agent_t agent_handle) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(va);\n  IS_BAD_PTR(perms);\n\n  return core::Runtime::runtime_singleton_->VMemoryGetAccess(va, perms, agent_handle);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_export_shareable_handle(int* dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t handle,\n                                                  uint64_t flags) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(dmabuf_fd);\n\n  return core::Runtime::runtime_singleton_->VMemoryExportShareableHandle(dmabuf_fd, handle, flags);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_import_shareable_handle(int dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t* handle) {\n  TRY;\n  IS_BAD_PTR(handle);\n  IS_VALID_FD(dmabuf_fd);\n\n  return core::Runtime::runtime_singleton_->VMemoryImportShareableHandle(dmabuf_fd, handle);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_retain_alloc_handle(hsa_amd_vmem_alloc_handle_t* allocHandle,\n                                              void* addr) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(addr);\n\n  return core::Runtime::runtime_singleton_->VMemoryRetainAllocHandle(allocHandle, addr);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_vmem_get_alloc_properties_from_handle(hsa_amd_vmem_alloc_handle_t allocHandle,\n                                                           hsa_amd_memory_pool_t* pool,\n                                                           hsa_amd_memory_type_t* type) {\n  TRY;\n  IS_OPEN();\n  IS_BAD_PTR(pool);\n  IS_BAD_PTR(type);\n\n  const core::MemoryRegion* mem_region = NULL;\n  hsa_status_t ret = core::Runtime::runtime_singleton_->VMemoryGetAllocPropertiesFromHandle(\n      allocHandle, &mem_region, type);\n  if (ret == HSA_STATUS_SUCCESS) {\n    hsa_region_t region = core::MemoryRegion::Convert(mem_region);\n    pool->handle = region.handle;\n  }\n\n  return ret;\n  CATCH;\n}\n\nhsa_status_t HSA_API hsa_amd_agent_set_async_scratch_limit(hsa_agent_t _agent, size_t threshold) {\n  TRY;\n  IS_OPEN();\n\n  core::Agent* agent = core::Agent::Convert(_agent);\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(agent);\n\n  if (!core::Runtime::runtime_singleton_->flag().enable_scratch_async_reclaim() ||\n      !gpu_agent->AsyncScratchReclaimEnabled())\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  return gpu_agent->SetAsyncScratchThresholds(threshold);\n  CATCH;\n}\n\nhsa_status_t HSA_API hsa_amd_queue_get_info(hsa_queue_t* _queue,\n                                            hsa_queue_info_attribute_t attribute, void* value) {\n  TRY;\n  IS_OPEN();\n\n  core::Queue* queue = core::Queue::Convert(_queue);\n  IS_VALID(queue);\n\n  return queue->GetInfo(attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_enable_logging(uint8_t* flags, void *file) {\n  TRY;\n  return core::Runtime::runtime_singleton_->EnableLogging(flags, file);\n  CATCH;\n}\n\n}   //  namespace amd\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"image/inc/hsa_ext_image_impl.h\"\n#include \"pcs/inc/hsa_ven_amd_pc_sampling_impl.h\"\n#include \"core/inc/hsa_ext_interface.h\"\n#include \"core/inc/runtime.h\"\n\n#include <string>\n\nnamespace rocr {\n// Implementations for missing / unsupported extensions\ntemplate <class R, class... ARGS> static R hsa_ext_null(ARGS...) {\n  return HSA_STATUS_ERROR_NOT_INITIALIZED;\n}\n\nnamespace core {\nExtensionEntryPoints::ExtensionEntryPoints() {\n  InitFinalizerExtTable();\n  InitImageExtTable();\n  InitPcSamplingExtTable();\n  InitAmdExtTable();\n}\n\n// Initialize Finalizer function table to be NULLs\nvoid ExtensionEntryPoints::InitFinalizerExtTable() {\n  \n  // Initialize Version of Api Table\n  finalizer_api.version.major_id = 0x00;\n  finalizer_api.version.minor_id = 0x00;\n  finalizer_api.version.step_id = 0x00;\n\n  finalizer_api.hsa_ext_program_create_fn = hsa_ext_null;\n  finalizer_api.hsa_ext_program_destroy_fn = hsa_ext_null;\n  finalizer_api.hsa_ext_program_add_module_fn = hsa_ext_null;\n  finalizer_api.hsa_ext_program_iterate_modules_fn = hsa_ext_null;\n  finalizer_api.hsa_ext_program_get_info_fn = hsa_ext_null;\n  finalizer_api.hsa_ext_program_finalize_fn = hsa_ext_null;\n}\n\n// Initialize Image function table to be NULLs\nvoid ExtensionEntryPoints::InitImageExtTable() {\n \n  // Initialize Version of Api Table\n  image_api.version.major_id = 0x00;\n  image_api.version.minor_id = 0x00;\n  image_api.version.step_id = 0x00;\n\n  image_api.hsa_ext_image_get_capability_fn = hsa_ext_null;\n  image_api.hsa_ext_image_data_get_info_fn = hsa_ext_null;\n  image_api.hsa_ext_image_create_fn = hsa_ext_null;\n  image_api.hsa_ext_image_import_fn = hsa_ext_null;\n  image_api.hsa_ext_image_export_fn = hsa_ext_null;\n  image_api.hsa_ext_image_copy_fn = hsa_ext_null;\n  image_api.hsa_ext_image_clear_fn = hsa_ext_null;\n  image_api.hsa_ext_image_destroy_fn = hsa_ext_null;\n  image_api.hsa_ext_sampler_create_fn = hsa_ext_null;\n  image_api.hsa_ext_sampler_destroy_fn = hsa_ext_null;\n  image_api.hsa_amd_image_get_info_max_dim_fn = hsa_ext_null;\n  image_api.hsa_ext_image_get_capability_with_layout_fn = hsa_ext_null;\n  image_api.hsa_ext_image_data_get_info_with_layout_fn = hsa_ext_null;\n  image_api.hsa_ext_image_create_with_layout_fn = hsa_ext_null;\n}\n\n// Initialize PC Sampling function table to be NULLs\nvoid ExtensionEntryPoints::InitPcSamplingExtTable() {\n  // Initialize Version of Api Table\n  pcs_api.version.major_id = 0x00;\n  pcs_api.version.minor_id = 0x00;\n  pcs_api.version.step_id = 0x00;\n\n  pcs_api.hsa_ven_amd_pcs_iterate_configuration_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_create_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_create_from_id_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_destroy_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_start_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_stop_fn = hsa_ext_null;\n  pcs_api.hsa_ven_amd_pcs_flush_fn = hsa_ext_null;\n}\n\n// Initialize Amd Ext table for Api related to Images\nvoid ExtensionEntryPoints::InitAmdExtTable() {\n  hsa_api_table().amd_ext_api.hsa_amd_image_create_fn = hsa_ext_null;\n  hsa_internal_api_table().amd_ext_api.hsa_amd_image_create_fn = hsa_ext_null;\n}\n\n// Update Amd Ext table for Api related to Images.\n// @note: Interface should be updated when Amd Ext table\n// begins hosting Api's from other extension libraries\nvoid ExtensionEntryPoints::UpdateAmdExtTable(decltype(::hsa_amd_image_create)* func_ptr) {\n  assert(hsa_api_table().amd_ext_api.hsa_amd_image_create_fn ==\n             (decltype(hsa_amd_image_create)*)hsa_ext_null && \n             \"Duplicate load of extension import.\");\n  assert(hsa_internal_api_table().amd_ext_api.hsa_amd_image_create_fn ==\n             (decltype(hsa_amd_image_create)*)hsa_ext_null && \n             \"Duplicate load of extension import.\");\n  hsa_api_table().amd_ext_api.hsa_amd_image_create_fn = func_ptr;\n  hsa_internal_api_table().amd_ext_api.hsa_amd_image_create_fn = func_ptr;\n}\n\nvoid ExtensionEntryPoints::UnloadImage() {\n  InitAmdExtTable();\n  InitImageExtTable();\n  core::hsa_internal_api_table().Reset();\n#ifdef HSA_IMAGE_SUPPORT\n  rocr::image::ReleaseImageRsrcs();\n#endif\n}\n\nvoid ExtensionEntryPoints::Unload() {\n  // Reset Image apis to hsa_ext_null function\n  UnloadImage();\n#ifdef HSA_PC_SAMPLING_SUPPORT\n  rocr::pcs::ReleasePcSamplingRsrcs();\n#endif\n\n  for (auto lib : libs_) {\n    void* ptr = os::GetExportAddress(lib, \"Unload\");\n    if (ptr) {\n      ((Unload_t)ptr)();\n    }\n  }\n  // Due to valgrind bug, runtime cannot dlclose extensions see:\n  // http://valgrind.org/docs/manual/faq.html#faq.unhelpful\n  if (!core::Runtime::runtime_singleton_->flag().running_valgrind()) {\n    for (auto lib : libs_) {\n      os::CloseLib(lib);\n    }\n  }\n  libs_.clear();\n\n  InitFinalizerExtTable();\n  InitPcSamplingExtTable();\n  InitImageExtTable();\n  InitAmdExtTable();\n  core::hsa_internal_api_table().Reset();\n}\n\nbool ExtensionEntryPoints::LoadImage() {\n#ifdef HSA_IMAGE_SUPPORT\n  // Consult user input on linking to Image implementation\n  bool disable_image = core::Runtime::runtime_singleton_->flag().disable_image();\n  if (disable_image) {\n    return true;\n  }\n\n  // Bind to Image implementation api's\n  decltype(::hsa_amd_image_create)* func;\n  rocr::image::LoadImage(&image_api, &func);\n\n  // Initialize Version of Api Table\n  image_api.version.major_id = HSA_IMAGE_API_TABLE_MAJOR_VERSION;\n  image_api.version.minor_id = sizeof(ImageExtTable);\n  image_api.version.step_id = HSA_IMAGE_API_TABLE_STEP_VERSION;\n\n  // Update private copy of Api table with handle for Image extensions\n  hsa_internal_api_table().CloneExts(&image_api,\n                                    core::HsaApiTable::HSA_EXT_IMAGE_API_TABLE_ID);\n\n  // Update Amd Ext Api table Api that deals with Images\n  UpdateAmdExtTable(func);\n#endif\n  return true;\n}\n\nvoid ExtensionEntryPoints::LoadPcSampling() {\n#ifdef HSA_PC_SAMPLING_SUPPORT\n  if (core::Runtime::runtime_singleton_->flag().disable_pc_sampling()) return;\n\n  // Bind to Image implementation api's\n  rocr::pcs::LoadPcSampling(&pcs_api);\n\n  // Initialize Version of Api Table\n  pcs_api.version.major_id = HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION;\n  pcs_api.version.minor_id = sizeof(PcSamplingExtTable);\n  pcs_api.version.step_id = HSA_PC_SAMPLING_API_TABLE_STEP_VERSION;\n\n  // Update private copy of Api table with handle for Image extensions\n  hsa_internal_api_table().CloneExts(&pcs_api,\n                        core::HsaApiTable::HSA_EXT_PC_SAMPLING_API_TABLE_ID);\n#endif\n}\n\nbool ExtensionEntryPoints::LoadFinalizer(std::string library_name) {\n  os::LibHandle lib = os::LoadLib(library_name);\n  if (lib == NULL) {\n    return false;\n  }\n  libs_.push_back(lib);\n  \n  void* ptr;\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_create_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_create_fn ==\n               (decltype(::hsa_ext_program_create)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_create_fn = (decltype(::hsa_ext_program_create)*)ptr;\n  }\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_destroy_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_destroy_fn ==\n               (decltype(::hsa_ext_program_destroy)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_destroy_fn =\n        (decltype(::hsa_ext_program_destroy)*)ptr;\n  }\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_add_module_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_add_module_fn ==\n               (decltype(::hsa_ext_program_add_module)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_add_module_fn =\n        (decltype(::hsa_ext_program_add_module)*)ptr;\n  }\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_iterate_modules_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_iterate_modules_fn ==\n               (decltype(::hsa_ext_program_iterate_modules)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_iterate_modules_fn =\n        (decltype(::hsa_ext_program_iterate_modules)*)ptr;\n  }\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_get_info_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_get_info_fn ==\n               (decltype(::hsa_ext_program_get_info)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_get_info_fn =\n        (decltype(::hsa_ext_program_get_info)*)ptr;\n  }\n\n  ptr = os::GetExportAddress(lib, \"hsa_ext_program_finalize_impl\");\n  if (ptr != NULL) {\n    assert(finalizer_api.hsa_ext_program_finalize_fn ==\n               (decltype(::hsa_ext_program_finalize)*)hsa_ext_null &&\n           \"Duplicate load of extension import.\");\n    finalizer_api.hsa_ext_program_finalize_fn =\n        (decltype(::hsa_ext_program_finalize)*)ptr;\n  }\n  \n  // Initialize Version of Api Table\n  finalizer_api.version.major_id = HSA_FINALIZER_API_TABLE_MAJOR_VERSION;\n  finalizer_api.version.minor_id = sizeof(::FinalizerExtTable);\n  finalizer_api.version.step_id = HSA_FINALIZER_API_TABLE_STEP_VERSION;\n \n  // Update handle of table of HSA extensions\n  hsa_internal_api_table().CloneExts(&finalizer_api,\n                                    core::HsaApiTable::HSA_EXT_FINALIZER_API_TABLE_ID);\n\n  ptr = os::GetExportAddress(lib, \"Load\");\n  if (ptr != NULL) {\n    ((Load_t)ptr)(&core::hsa_internal_api_table().hsa_api);\n  }\n\n  return true;\n}\n\n}  // namespace core\n}  // namespace rocr\n\n//---------------------------------------------------------------------------//\n//   Exported extension stub functions\n//---------------------------------------------------------------------------//\n\nhsa_status_t hsa_ext_program_create(\n    hsa_machine_model_t machine_model, hsa_profile_t profile,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode,\n    const char* options, hsa_ext_program_t* program) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_create_fn(machine_model, profile,\n                                 default_float_rounding_mode, options, program);\n}\n\nhsa_status_t hsa_ext_program_destroy(hsa_ext_program_t program) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_destroy_fn(program);\n}\n\nhsa_status_t hsa_ext_program_add_module(hsa_ext_program_t program,\n                                        hsa_ext_module_t module) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_add_module_fn(program, module);\n}\n\nhsa_status_t hsa_ext_program_iterate_modules(\n    hsa_ext_program_t program,\n    hsa_status_t (*callback)(hsa_ext_program_t program, hsa_ext_module_t module,\n                             void* data),\n    void* data) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_iterate_modules_fn(program, callback, data);\n}\n\nhsa_status_t hsa_ext_program_get_info(hsa_ext_program_t program,\n                                      hsa_ext_program_info_t attribute,\n                                      void* value) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_get_info_fn(program, attribute, value);\n}\n\nhsa_status_t hsa_ext_program_finalize(\n    hsa_ext_program_t program, hsa_isa_t isa, int32_t call_convention,\n    hsa_ext_control_directives_t control_directives, const char* options,\n    hsa_code_object_type_t code_object_type, hsa_code_object_t* code_object) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.finalizer_api\n      .hsa_ext_program_finalize_fn(program, isa, call_convention,\n                                   control_directives, options,\n                                   code_object_type, code_object);\n}\n\nhsa_status_t hsa_ext_image_get_capability(\n    hsa_agent_t agent, hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t* image_format, uint32_t* capability_mask) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_get_capability_fn(agent, geometry, image_format,\n                                       capability_mask);\n}\n\nhsa_status_t hsa_ext_image_data_get_info(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_info_t* image_data_info) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_data_get_info_fn(agent, image_descriptor,\n                                      access_permission, image_data_info);\n}\n\nhsa_status_t hsa_ext_image_create(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    const void* image_data, hsa_access_permission_t access_permission,\n    hsa_ext_image_t* image) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_create_fn(agent, image_descriptor, image_data,\n                               access_permission, image);\n}\n\nhsa_status_t hsa_ext_image_import(hsa_agent_t agent, const void* src_memory,\n                                  size_t src_row_pitch, size_t src_slice_pitch,\n                                  hsa_ext_image_t dst_image,\n                                  const hsa_ext_image_region_t* image_region) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_import_fn(agent, src_memory, src_row_pitch,\n                               src_slice_pitch, dst_image, image_region);\n}\n\nhsa_status_t hsa_ext_image_export(hsa_agent_t agent, hsa_ext_image_t src_image,\n                                  void* dst_memory, size_t dst_row_pitch,\n                                  size_t dst_slice_pitch,\n                                  const hsa_ext_image_region_t* image_region) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_export_fn(agent, src_image, dst_memory, dst_row_pitch,\n                               dst_slice_pitch, image_region);\n}\n\nhsa_status_t hsa_ext_image_copy(hsa_agent_t agent, hsa_ext_image_t src_image,\n                                const hsa_dim3_t* src_offset,\n                                hsa_ext_image_t dst_image,\n                                const hsa_dim3_t* dst_offset,\n                                const hsa_dim3_t* range) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_copy_fn(agent, src_image, src_offset, dst_image,\n                             dst_offset, range);\n}\n\nhsa_status_t hsa_ext_image_clear(hsa_agent_t agent, hsa_ext_image_t image,\n                                 const void* data,\n                                 const hsa_ext_image_region_t* image_region) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_clear_fn(agent, image, data, image_region);\n}\n\nhsa_status_t hsa_ext_image_destroy(hsa_agent_t agent, hsa_ext_image_t image) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_destroy_fn(agent, image);\n}\n\nhsa_status_t hsa_ext_sampler_create(\n    hsa_agent_t agent, const hsa_ext_sampler_descriptor_t* sampler_descriptor,\n    hsa_ext_sampler_t* sampler) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_sampler_create_fn(agent, sampler_descriptor, sampler);\n}\n\nhsa_status_t hsa_ext_sampler_create_v2(\n    hsa_agent_t agent, const hsa_ext_sampler_descriptor_v2_t* sampler_descriptor,\n    hsa_ext_sampler_t* sampler) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_sampler_create_v2_fn(agent, sampler_descriptor, sampler);\n}\n\nhsa_status_t hsa_ext_sampler_destroy(hsa_agent_t agent,\n                                     hsa_ext_sampler_t sampler) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_sampler_destroy_fn(agent, sampler);\n}\n\nhsa_status_t hsa_ext_image_get_capability_with_layout(\n    hsa_agent_t agent, hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t* image_format,\n    hsa_ext_image_data_layout_t image_data_layout,\n    uint32_t* capability_mask) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_get_capability_with_layout_fn(agent, geometry, image_format,\n                                       image_data_layout, capability_mask);\n}\n\nhsa_status_t hsa_ext_image_data_get_info_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t* image_data_info) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_data_get_info_with_layout_fn(agent, image_descriptor,\n                                      access_permission, image_data_layout,\n                                      image_data_row_pitch, image_data_slice_pitch,\n                                      image_data_info);\n}\n\nhsa_status_t hsa_ext_image_create_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    const void* image_data, hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_t* image) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_ext_image_create_with_layout_fn(agent, image_descriptor, image_data,\n                               access_permission, image_data_layout,\n                               image_data_row_pitch, image_data_slice_pitch,\n                               image);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_iterate_configuration(\n    hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n    void* callback_data) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api\n      .hsa_ven_amd_pcs_iterate_configuration_fn(agent, configuration_callback, callback_data);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_create(\n    hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method, hsa_ven_amd_pcs_units_t units,\n    size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data,\n    hsa_ven_amd_pcs_t* pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_create_fn(\n      agent, method, units, interval, latency, buffer_size, data_ready_callback,\n      client_callback_data, pc_sampling);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_create_from_id(\n    uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data,\n    hsa_ven_amd_pcs_t* pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api\n      .hsa_ven_amd_pcs_create_from_id_fn(pcs_id, agent, method, units, interval, latency,\n                                         buffer_size, data_ready_callback, client_callback_data,\n                                         pc_sampling);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_destroy(hsa_ven_amd_pcs_t pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_destroy_fn(\n      pc_sampling);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_start(hsa_ven_amd_pcs_t pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_start_fn(\n      pc_sampling);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_stop(hsa_ven_amd_pcs_t pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_stop_fn(\n      pc_sampling);\n}\n\nhsa_status_t HSA_API hsa_ven_amd_pcs_flush(hsa_ven_amd_pcs_t pc_sampling) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_flush_fn(\n      pc_sampling);\n}\n\n//---------------------------------------------------------------------------//\n//  Stubs for internal extension functions\n//---------------------------------------------------------------------------//\n\n// Use the function pointer from local instance Image Extension\nhsa_status_t hsa_amd_image_get_info_max_dim(hsa_agent_t component,\n                                            hsa_agent_info_t attribute,\n                                            void* value) {\n  return rocr::core::Runtime::runtime_singleton_->extensions_.image_api\n      .hsa_amd_image_get_info_max_dim_fn(component, attribute, value);\n}\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/hsa_ven_amd_loader.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/hsa_ven_amd_loader_impl.h\"\n\n#include \"core/inc/amd_hsa_loader.hpp\"\n#include \"core/inc/runtime.h\"\n\nnamespace rocr {\n\nusing namespace amd::hsa;\nusing namespace core;\n\nusing loader::CodeObjectReaderImpl;\nusing loader::Executable;\nusing loader::LoadedCodeObject;\nusing loader::Loader;\n\nnamespace AMD {\n\nhsa_status_t handleException();\n\n}   // namespace amd\n\nhsa_status_t hsa_ven_amd_loader_query_host_address(\n  const void *device_address,\n  const void **host_address) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if (nullptr == device_address) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n    if (nullptr == host_address) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    uintptr_t udaddr = reinterpret_cast<uintptr_t>(device_address);\n    uintptr_t uhaddr = Runtime::runtime_singleton_->loader()->FindHostAddress(udaddr);\n    if (0 == uhaddr) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    *host_address = reinterpret_cast<void*>(uhaddr);\n    return HSA_STATUS_SUCCESS;\n  } catch(...) { return AMD::handleException(); }\n}\n\nhsa_status_t hsa_ven_amd_loader_query_segment_descriptors(\n  hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n  size_t *num_segment_descriptors) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n\n    // Arguments are checked by the loader.\n    return Runtime::runtime_singleton_->loader()->QuerySegmentDescriptors(segment_descriptors, num_segment_descriptors);\n  } catch(...) { return AMD::handleException(); }\n}\n\nhsa_status_t hsa_ven_amd_loader_query_executable(\n  const void *device_address,\n  hsa_executable_t *executable) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if ((nullptr == device_address) || (nullptr == executable)) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    uintptr_t udaddr = reinterpret_cast<uintptr_t>(device_address);\n    hsa_executable_t exec = Runtime::runtime_singleton_->loader()->FindExecutable(udaddr);\n    if (0 == exec.handle) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    *executable = exec;\n    return HSA_STATUS_SUCCESS;\n  } catch(...) { return AMD::handleException(); }\n}\n\nhsa_status_t hsa_ven_amd_loader_executable_iterate_loaded_code_objects(\n  hsa_executable_t executable,\n  hsa_status_t (*callback)(\n    hsa_executable_t executable,\n    hsa_loaded_code_object_t loaded_code_object,\n    void *data),\n  void *data) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if (nullptr == callback) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    Executable *exec = Executable::Object(executable);\n    if (!exec) {\n      return HSA_STATUS_ERROR_INVALID_EXECUTABLE;\n    }\n\n    return exec->IterateLoadedCodeObjects(callback, data);\n  } catch(...) { return AMD::handleException(); }\n}\n\nhsa_status_t hsa_ven_amd_loader_loaded_code_object_get_info(\n  hsa_loaded_code_object_t loaded_code_object,\n  hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n  void *value) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if (nullptr == value) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    const LoadedCodeObject *lcobj = LoadedCodeObject::Object(loaded_code_object);\n    if (!lcobj) {\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n    }\n\n    switch (attribute) {\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_EXECUTABLE: {\n        *((hsa_executable_t*)value) = lcobj->getExecutable();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_KIND: {\n        *((uint32_t*)value) = lcobj->getAgent().handle == 0\n            ? HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_KIND_PROGRAM\n            : HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_KIND_AGENT;\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_AGENT: {\n        hsa_agent_t agent = lcobj->getAgent();\n        if (agent.handle == 0) {\n            return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n        }\n        *((hsa_agent_t*)value) = agent;\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE: {\n        // TODO Update loader so it keeps track if code object was loaded from a\n        // file or memory.\n        *((uint32_t*)value) = HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY;\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_BASE: {\n        *((uint64_t*)value) = lcobj->getElfData();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_SIZE: {\n        *((uint64_t*)value) = lcobj->getElfSize();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_FILE: {\n        // TODO Update loader so it keeps track if code object was loaded from a\n        // file or memory.\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_DELTA: {\n        // TODO Check if executable is frozen.\n        // This suggests this code should be moved into LoadedCodeObjectImpl::getinfo\n        // as is done for other *_get_info methods. Currently LoadedCodeObject has a\n        // GetInfo method which is likely not used.\n        // Also should this have a *NOT_FROZEN ststus code added?\n        // if (state_ != HSA_EXECUTABLE_STATE_FROZEN) {\n        //   return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n        // }\n        *((int64_t*)value) = lcobj->getDelta();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_BASE: {\n        // TODO Check if executable is frozen.\n        *((uint64_t*)value) = lcobj->getLoadBase();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_SIZE: {\n        // TODO Check if executable is frozen.\n        *((uint64_t*)value) = lcobj->getLoadSize();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI_LENGTH: {\n        *(reinterpret_cast<uint32_t*>(value)) = lcobj->getUri().size();\n        break;\n      }\n      case HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI: {\n        memcpy(value, lcobj->getUri().c_str(), lcobj->getUri().size());\n        break;\n      }\n      default: {\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n    }\n\n    return HSA_STATUS_SUCCESS;\n  } catch(...) { return AMD::handleException(); }\n}\n\nhsa_status_t\nhsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size(\n    hsa_file_t file,\n    size_t offset,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if (nullptr == code_object_reader) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    if (size == 0) {\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n    }\n\n    std::unique_ptr<CodeObjectReaderImpl> reader(\n        new (std::nothrow) CodeObjectReaderImpl());\n    if (!reader) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n\n    hsa_status_t status = reader->SetFile(file, offset, size);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n\n    *code_object_reader = CodeObjectReaderImpl::Handle(reader.release());\n    return HSA_STATUS_SUCCESS;\n  } catch(...) { return AMD::handleException(); }\n}\n\nnamespace {\n\nLoader *GetLoader() {\n  return Runtime::runtime_singleton_->loader();\n}\n\n} // namespace anonymous\n\nhsa_status_t\nhsa_ven_amd_loader_iterate_executables(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      void *data),\n    void *data) {\n  try {\n    if (!Runtime::runtime_singleton_->IsOpen()) {\n      return HSA_STATUS_ERROR_NOT_INITIALIZED;\n    }\n    if (nullptr == callback) {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    return GetLoader()->IterateExecutables(callback, data);\n  } catch(...) { return AMD::handleException(); }\n}\n\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/intercept_queue.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/intercept_queue.h\"\n#include \"core/inc/amd_aql_queue.h\"\n#include \"core/inc/default_signal.h\"\n#include \"core/util/utils.h\"\n#include \"inc/hsa_api_trace.h\"\n\nnamespace rocr {\nnamespace core {\n\nnamespace {\n\n// Determine if a packet is the AMD_AQL_FORMAT_INTERCEPT_MARKER packet. Loads\n// the packet header non-atomically. That is permissable if the calling thread\n// has previously loaded the header atomically to determine if it is not an\n// INVALID packet. Once a packet is no longer INVALID its ownership belongs to\n// the packer processor.\nbool inline IsInterceptMarkerPacket(const AqlPacket* packet) {\n  return (AqlPacket::type(packet->packet.header) == HSA_PACKET_TYPE_VENDOR_SPECIFIC) &&\n      (packet->amd_vendor.format == AMD_AQL_FORMAT_INTERCEPT_MARKER);\n}\n\n}  // namespace\n\nstruct InterceptFrame {\n  InterceptQueue* queue;\n  uint64_t pkt_index;\n  size_t interceptor_index;\n};\n\nstatic thread_local InterceptFrame Cursor = {nullptr, 0, 0};\n\nstatic const uint16_t kInvalidHeader = (HSA_PACKET_TYPE_INVALID << HSA_PACKET_HEADER_TYPE) |\n    (1 << HSA_PACKET_HEADER_BARRIER) |\n    (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE) |\n    (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE);\n\nstatic const uint16_t kBarrierHeader = (HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE) |\n    (1 << HSA_PACKET_HEADER_BARRIER) |\n    (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE) |\n    (HSA_FENCE_SCOPE_NONE << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE);\n\nbool InterceptQueue::IsPendingRetryPoint(uint64_t wrapped_current_read_index) const {\n  // This function is intended to determine if the last retry barrier packet\n  // has definitely not been processed in order to avoid putting multiple retry\n  // packets on the wrapped queue.\n  //\n  // The AQL protocol allows the packet processor to advance the read index any\n  // time after the producer advances the write index. It does not specify the\n  // latest that the read index must be advanced. This makes it impossible to\n  // use the read index to determine if a packet has definitely not been\n  // processed.\n  //\n  // This code assumes that the read index will be advanced no later than the\n  // start of processing the next packet. So at worst, if the read index equals\n  // the retry index the packet may have already been processed, and its\n  // completion signal updated (perhaps that was the cause of entering\n  // InterceptQueue::StoreRelaxed that is now invoking this function). But if\n  // the read index is less than the retry index, then the packet has not yet\n  // been processed, This implies that the minimum queue size is 3 (enforced in\n  // hsa_amd_queue_intercept_create): a non-retry packet, a retry packet that\n  // is being processed, and space for a new retry packet.\n  //\n  // FIXME: The above assumption can be removed by using a distinct interrupt\n  // signal for the retry packet completion signal, and tracking when that\n  // signal is updated and invokes its async handler. Currently the wrapped\n  // queue doorbell signal is also being used as the retry completion signal.\n  // If that is done then the minimum queue size needs to be changed from 3 to\n  // 2 (enforced in hsa_amd_queue_intercept_create).\n  return retry_index_ > wrapped_current_read_index;\n}\n\nInterceptQueue::InterceptQueue(std::unique_ptr<Queue> queue)\n    : QueueProxy(std::move(queue)),\n      LocalSignal(0, false),\n      DoorbellSignal(signal()),\n      next_packet_(0),\n      retry_index_(0),\n      quit_(false),\n      active_(true) {\n  // Initial retry_index_ value must ensure that\n  // InterceptQueue::IsPendingRetryPoint will return false before the first\n  // retry barrier packet is inserted.\n  assert(!IsPendingRetryPoint(next_packet_) &&\n         \"Packet intercept error: initial retry index is incompatible with IsPendingRetryPoint.\\n\");\n  buffer_ = SharedArray<AqlPacket, 4096>(wrapped->amd_queue_.hsa_queue.size);\n  amd_queue_.hsa_queue.base_address = reinterpret_cast<void*>(&buffer_[0]);\n\n  // Fill the ring buffer with invalid packet headers.\n  // Leave packet content uninitialized to help trigger application errors.\n  for (uint32_t pkt_id = 0; pkt_id < wrapped->amd_queue_.hsa_queue.size; ++pkt_id) {\n    buffer_[pkt_id].packet.header = HSA_PACKET_TYPE_INVALID;\n  }\n\n  // Match the queue's signal ABI block to async_doorbell_'s\n  // This allows us to use the queue's signal ABI block from devices to trigger async_doorbell while\n  // host side use jumps directly to the queue's signal implementation.\n  if (!core::g_use_interrupt_wait)\n    async_doorbell_ = new DefaultSignal(DOORBELL_MAX);\n  else\n    async_doorbell_ = new InterruptSignal(DOORBELL_MAX);\n  MAKE_NAMED_SCOPE_GUARD(sigGuard, [&]() { async_doorbell_->DestroySignal(); });\n  this->signal_ = async_doorbell_->signal_;\n  amd_queue_.hsa_queue.doorbell_signal = Signal::Convert(this);\n\n  // Install an async handler for device side dispatches.\n  auto err = Runtime::runtime_singleton_->SetAsyncSignalHandler(\n      core::Signal::Convert(async_doorbell_), HSA_SIGNAL_CONDITION_NE,\n      async_doorbell_->LoadRelaxed(), HandleAsyncDoorbell, this);\n  if (err != HSA_STATUS_SUCCESS)\n    throw AMD::hsa_exception(err, \"Doorbell handler registration failed.\\n\");\n\n  // Install copy submission interceptor.\n  AddInterceptor(Submit, this);\n\n  sigGuard.Dismiss();\n}\n\nInterceptQueue::~InterceptQueue() {\n  active_ = false;\n\n  // Kill the async doorbell handler\n  // Doorbell may not be used during or after queue destroy, however an interrupt may be in flight.\n  // Ensure doorbell value is not 0, mark for exit, wake handler and wait for termination value.\n  async_doorbell_->StoreRelaxed(DOORBELL_MAX);\n  quit_ = true;\n  hsa_signal_value_t val = async_doorbell_->ExchRelaxed(1);\n  if (val != 0)\n    async_doorbell_->WaitRelaxed(HSA_SIGNAL_CONDITION_EQ, 0, -1, HSA_WAIT_STATE_BLOCKED);\n  async_doorbell_->DestroySignal();\n}\n\nbool InterceptQueue::HandleAsyncDoorbell(hsa_signal_value_t value, void* arg) {\n  InterceptQueue* queue = reinterpret_cast<InterceptQueue*>(arg);\n  if (queue->quit_) {\n    queue->async_doorbell_->StoreRelaxed(0);\n    return false;\n  }\n  queue->async_doorbell_->StoreRelaxed(DOORBELL_MAX);\n  queue->StoreRelease(value);\n  return true;\n}\n\nvoid InterceptQueue::PacketWriter(const void* pkts, uint64_t pkt_count) {\n  assert(Cursor.interceptor_index > 0 &&\n         \"Packet intercept error: final submit handler must not call PacketWritter.\\n\");\n  --Cursor.interceptor_index;\n  auto& handler = Cursor.queue->interceptors[Cursor.interceptor_index];\n  handler.first(pkts, pkt_count, Cursor.pkt_index, handler.second, PacketWriter);\n  // Restore index as the same rewrite handler may call the PacketWriter more than once.\n  ++Cursor.interceptor_index;\n}\n\nvoid InterceptQueue::Submit(const void* pkts, uint64_t pkt_count, uint64_t user_pkt_index,\n                            void* data, hsa_amd_queue_intercept_packet_writer writer) {\n  InterceptQueue* queue = reinterpret_cast<InterceptQueue*>(data);\n  const AqlPacket* packets = (const AqlPacket*)pkts;\n\n  // Submit final packet transform to hardware.\n  uint64_t submitted_count = queue->Submit(packets, pkt_count);\n  if (submitted_count == pkt_count) return;\n\n  // Could not submit all the final packets, stash unsubmitted ones for later.\n  assert(queue->overflow_.empty() && \"Packet intercept error: overflow buffer not empty.\\n\");\n  for (uint64_t i = submitted_count; i < pkt_count; i++)\n    queue->overflow_.push_back(packets[i]);\n}\n\nuint64_t InterceptQueue::Submit(const AqlPacket* packets, uint64_t count) {\n  if (count == 0) return 0;\n\n  uint64_t marker_count = 0;\n  for (uint64_t i = 0; i < count; i++) {\n    if (IsInterceptMarkerPacket(&packets[i])) ++marker_count;\n  }\n\n  AqlPacket* ring = reinterpret_cast<AqlPacket*>(wrapped->amd_queue_.hsa_queue.base_address);\n  uint64_t mask = wrapped->amd_queue_.hsa_queue.size - 1;\n\n  while (true) {\n    uint64_t write = wrapped->LoadWriteIndexRelaxed();\n    uint64_t read = wrapped->LoadReadIndexRelaxed();\n    uint64_t free_slots = wrapped->amd_queue_.hsa_queue.size - (write - read);\n    bool pending_retry_point = IsPendingRetryPoint(read);\n\n    uint64_t submitted_count = count - marker_count;\n\n    // If the number of packets is greater than the wrapped queue size, then we\n    // can never submit them all at once. So submit what will fit, leaving one\n    // slot free for the retry barrier packet if it is not already on the\n    // queue.\n    if (submitted_count >= wrapped->amd_queue_.hsa_queue.size) {\n      submitted_count = free_slots - (pending_retry_point ? 0 : 1);\n    }\n\n    // Prefer to either submit all the packets, or none of the packets. This\n    // ensures that all the packets of a rewrite will be on the queue at the\n    // same time. This may be desirable for some rewrites. So if out of space\n    // defer packet insertion. Always make sure there is a free slot available\n    // for the retry barrier packet if there is not already one present.\n    else if (free_slots < submitted_count + (pending_retry_point ? 0 : 1)) {\n      submitted_count = 0;\n    }\n\n    // If we are not submitting all the packets, we need to ensure there is a\n    // retry packet to cause the remaining packets to be submitted. If there is\n    // not already a pending retry point add one.\n    if (submitted_count < (count - marker_count) && !pending_retry_point) {\n      // Reserve one slot for the barrier packet. There will always be at least\n      // one free slot.\n      assert(free_slots >= 1 &&\n             \"Packet intercept error: there is no free slot for a retry barrier packet.\\n\");\n      // Reserve a slot for the barrier packet.\n      uint64_t barrier = wrapped->AddWriteIndexRelaxed(1);\n      assert(barrier == write &&\n             \"Packet intercept error: wrapped queue has been updated by another thread.\\n\");\n      ++write;\n\n      // Submit barrier which will wake async queue processing.\n      ring[barrier & mask].packet.body = {};\n      ring[barrier & mask].barrier_and.completion_signal = Signal::Convert(async_doorbell_);\n      if (wrapped->IsDeviceMemRingBuf() && needsPcieOrdering()) {\n        // Ensure the packet body is written as header may get reordered when writing over PCIE\n        _mm_sfence();\n      }\n      atomic::Store(&ring[barrier & mask].barrier_and.header, kBarrierHeader,\n                    std::memory_order_release);\n      // Update the wrapped queue's doorbell so it knows there is a new packet in the queue.\n      HSA::hsa_signal_store_screlease(wrapped->amd_queue_.hsa_queue.doorbell_signal, barrier);\n\n      // Record the retry point\n      retry_index_ = barrier;\n    }\n\n    // Attempt to reserve useable queue space if some packets need to be\n    // submitted.\n    uint64_t new_write = submitted_count == 0\n        ? write\n        : wrapped->CasWriteIndexRelaxed(write, write + submitted_count);\n    if (new_write == write) {\n      uint64_t packets_index = 0;\n      uint64_t write_index = 0;\n      uint64_t first_written_packet_index;\n      while (submitted_count > 0 || (packets_index < count && IsInterceptMarkerPacket(&packets[packets_index]))) {\n        // Ensure the marker packet callback is invoked before following\n        // packets are made available for the packet processor.\n        if (IsInterceptMarkerPacket(&packets[packets_index])) {\n          const amd_aql_intercept_marker_t* marker_packet =\n              reinterpret_cast<const amd_aql_intercept_marker_t*>(&packets[packets_index]);\n          marker_packet->callback(marker_packet, &wrapped->amd_queue_.hsa_queue,\n                                  write + write_index);\n        } else {\n          if (write_index == 0) {\n            // Leave the header of the first packet as INVALID so packet\n            // processor will not start processing any packets until all have\n            // been written and the first packet header atomically store\n            // released.\n            ring[(write + write_index) & mask].packet.body = packets[packets_index].packet.body;\n            first_written_packet_index = packets_index;\n          } else {\n            ring[(write + write_index) & mask] = packets[packets_index];\n          }\n          ++write_index;\n          --submitted_count;\n        }\n        ++packets_index;\n      }\n      if (write_index != 0) {\n        if (wrapped->IsDeviceMemRingBuf() && needsPcieOrdering()) {\n          // Ensure the packet body is written as header may get reordered when writing over PCIE\n          _mm_sfence();\n        }\n        atomic::Store(&ring[write & mask].packet.header, packets[first_written_packet_index].packet.header,\n                      std::memory_order_release);\n        HSA::hsa_signal_store_screlease(wrapped->amd_queue_.hsa_queue.doorbell_signal,\n                                        write + write_index - 1);\n      }\n      return packets_index;\n    }\n  }\n}\n\nvoid InterceptQueue::StoreRelaxed(hsa_signal_value_t value) {\n  if (!active_) return;\n\n  // If called recursively defer to async doorbell thread.\n  if (Cursor.queue != nullptr) {\n    debug_print(\"Likely incorrect queue use observed in an interceptor.\\n\");\n    async_doorbell_->StoreRelaxed(value);\n    return;\n  }\n\n  ScopedAcquire<KernelMutex> lock(&lock_);\n\n  // Submit overflow packets.\n  if (!overflow_.empty()) {\n    uint64_t submitted_count = Submit(&overflow_[0], overflow_.size());\n\n    if (submitted_count < overflow_.size()) {\n      overflow_.erase(overflow_.begin(), overflow_.begin() + submitted_count);\n      // Since there was no space to submit all the overflow packets, there is\n      // no space for other packets either.\n      return;\n    }\n\n    // All overflow packets have been submitted.\n    overflow_.clear();\n  }\n\n  Cursor.queue = this;\n\n  AqlPacket* ring = reinterpret_cast<AqlPacket*>(amd_queue_.hsa_queue.base_address);\n  uint64_t mask = wrapped->amd_queue_.hsa_queue.size - 1;\n\n  // Loop over valid packets and process.\n  uint64_t end = LoadWriteIndexAcquire();\n\n  // Can only process packets that are occupying slots in the queue buffer. No\n  // need to add a barrier packet to ensure the extra packets are processed as\n  // the producer must ring the doorbell once the extra packets are made valid.\n  if (end > next_packet_ + amd_queue_.hsa_queue.size)\n    end = next_packet_ + amd_queue_.hsa_queue.size;\n\n  uint64_t i = next_packet_;\n  while (i < end) {\n    // Load the packet header as atomic acquire as it may have been written by\n    // another thread as atomic release. This ensures the rest of the packet\n    // fields are visible. Once loaded and proven not to be INVALID, further\n    // loads by this thread can be non-atomic.\n    uint16_t header = atomic::Load(&ring[i & mask].packet.header, std::memory_order_acquire);\n    if (!AqlPacket::IsValid(header)) break;\n\n    // Process callbacks.\n    Cursor.interceptor_index = interceptors.size() - 1;\n    Cursor.pkt_index = i;\n    auto& handler = interceptors[Cursor.interceptor_index];\n    handler.first(&ring[i & mask], 1, i, handler.second, PacketWriter);\n    if (IsDeviceMemRingBuf() && needsPcieOrdering()) {\n      // Ensure the packet body is written as header may get reordered when writing over PCIE\n      _mm_sfence();\n    }\n    // Invalidate consumed packet.\n    atomic::Store(&ring[i & mask].packet.header, kInvalidHeader, std::memory_order_release);\n\n    // Packet has now been processed so advance the read index.\n    ++i;\n\n    // Only allow the rewrite of one packet to be on the overflow queue. When\n    // packets are put on the overflow queue a barrier packet will also be\n    // added which has an async handler that will ring the doorbell, That\n    // doorbell ring will ensure this function is re-invoked to put the\n    // overflow packets on the hardware queue and continue rewriting packets on\n    // the intercept queue.\n    if (!overflow_.empty()) break;\n  }\n\n  next_packet_ = i;\n  Cursor.queue = nullptr;\n  atomic::Store(&amd_queue_.read_dispatch_id, next_packet_, std::memory_order_release);\n}\n\nhsa_status_t InterceptQueue::GetInfo(hsa_queue_info_attribute_t attribute, void* value) {\n  switch (attribute) {\n    case HSA_AMD_QUEUE_INFO_AGENT:\n    case HSA_AMD_QUEUE_INFO_DOORBELL_ID: {\n      if (!AMD::AqlQueue::IsType(wrapped.get())) return HSA_STATUS_ERROR_INVALID_QUEUE;\n\n      AMD::AqlQueue* aqlQueue = static_cast<AMD::AqlQueue*>(wrapped.get());\n      return aqlQueue->GetInfo(attribute, value);\n    }\n  }\n  return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/interrupt_signal.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/util/locks.h\"\n\nnamespace rocr {\nnamespace core {\n\nHsaEvent* InterruptSignal::EventPool::alloc() {\n  ScopedAcquire<HybridMutex> lock(&lock_);\n  if (events_.empty()) {\n    if (!allEventsAllocated) {\n      HsaEvent* evt = InterruptSignal::CreateEvent(HSA_EVENTTYPE_SIGNAL, false);\n      if (evt == nullptr) allEventsAllocated = true;\n      return evt;\n    }\n    return nullptr;\n  }\n  HsaEvent* ret = events_.back().release();\n  events_.pop_back();\n  return ret;\n}\n\nvoid InterruptSignal::EventPool::free(HsaEvent* evt) {\n  if (evt == nullptr) return;\n  ScopedAcquire<HybridMutex> lock(&lock_);\n  events_.push_back(unique_event_ptr(evt));\n}\n\nHsaEvent* InterruptSignal::CreateEvent(HSA_EVENTTYPE type, bool manual_reset) {\n  HsaEventDescriptor event_descriptor;\n  event_descriptor.EventType = type;\n  event_descriptor.SyncVar.SyncVar.UserData = NULL;\n  event_descriptor.SyncVar.SyncVarSize = sizeof(hsa_signal_value_t);\n  event_descriptor.NodeId = 0;\n\n  HsaEvent* ret = NULL;\n  if (HSAKMT_STATUS_SUCCESS ==\n      HSAKMT_CALL(hsaKmtCreateEvent(&event_descriptor, manual_reset, false, &ret))) {\n    if (type == HSA_EVENTTYPE_MEMORY) {\n      memset(&ret->EventData.EventData.MemoryAccessFault.Failure, 0,\n             sizeof(HsaAccessAttributeFailure));\n    } else if (type == HSA_EVENTTYPE_HW_EXCEPTION) {\n      memset(&ret->EventData.EventData.HwException, 0, sizeof(HsaHwException));\n    }\n  }\n\n  return ret;\n}\n\nvoid InterruptSignal::DestroyEvent(HsaEvent* evt) { HSAKMT_CALL(hsaKmtDestroyEvent(evt)); }\n\nInterruptSignal::InterruptSignal(hsa_signal_value_t initial_value, HsaEvent* use_event)\n    : LocalSignal(initial_value, false), Signal(signal()) {\n  if (use_event != nullptr) {\n    event_ = use_event;\n    free_event_ = false;\n  } else {\n    event_ = Runtime::runtime_singleton_->GetEventPool()->alloc();\n    free_event_ = true;\n  }\n\n  if (event_ != nullptr) {\n    signal_.event_id = event_->EventId;\n    signal_.event_mailbox_ptr = event_->EventData.HWData2;\n  } else {\n    signal_.event_id = 0;\n    signal_.event_mailbox_ptr = 0;\n  }\n  signal_.kind = AMD_SIGNAL_KIND_USER;\n}\n\nInterruptSignal::~InterruptSignal() {\n  if (free_event_) Runtime::runtime_singleton_->GetEventPool()->free(event_);\n}\n\nhsa_signal_value_t InterruptSignal::LoadRelaxed() {\n  return hsa_signal_value_t(\n      atomic::Load(&signal_.value, std::memory_order_relaxed));\n}\n\nhsa_signal_value_t InterruptSignal::LoadAcquire() {\n  return hsa_signal_value_t(\n      atomic::Load(&signal_.value, std::memory_order_acquire));\n}\n\nvoid InterruptSignal::StoreRelaxed(hsa_signal_value_t value) {\n  atomic::Store(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::StoreRelease(hsa_signal_value_t value) {\n  atomic::Store(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nhsa_signal_value_t InterruptSignal::WaitRelaxed(hsa_signal_condition_t condition,\n                                               hsa_signal_value_t compare_value,\n                                               uint64_t timeout,\n                                               hsa_wait_state_t wait_hint) {\n  Retain();\n  MAKE_SCOPE_GUARD([&]() { Release(); });\n\n  uint32_t prior = waiting_++;\n  MAKE_SCOPE_GUARD([&]() { waiting_--; });\n\n  uint64_t event_age = core::Runtime::runtime_singleton_->KfdVersion().supports_event_age ? 1 : 0;\n  if (!event_age && prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE;\n\n  const timer::fast_clock::time_point start_time = timer::fast_clock::now();\n  const timer::fast_clock::duration fast_timeout = timer::GetFastTimeout(timeout);\n  const timer::fast_clock::duration kMaxElapsed = std::chrono::microseconds(200);\n  const uint32_t &signal_abort_timeout =\n    core::Runtime::runtime_singleton_->flag().signal_abort_timeout();\n\n  while (true) {\n    if (!IsValid()) return 0;\n\n    int64_t value = atomic::Load(&signal_.value, std::memory_order_relaxed);\n\n    if (CheckSignalCondition(value, condition, compare_value)) {\n      return value;\n    }\n\n    auto now = timer::fast_clock::now();\n    if (now - start_time > fast_timeout) {\n      return value;\n    }\n\n    timer::CheckAbortTimeout(start_time, signal_abort_timeout);\n\n    if (wait_hint == HSA_WAIT_STATE_ACTIVE) {\n      if (g_use_mwaitx) {\n        // Short timeout for active waiting\n        timer::DoMwaitx(const_cast<int64_t*>(&signal_.value), 1000);\n      }\n      continue;\n    }\n\n    if (now - start_time < kMaxElapsed) {\n      if (g_use_mwaitx) {\n        // Longer timeout with timer for passive waiting\n        timer::DoMwaitx(const_cast<int64_t*>(&signal_.value), 60000, true);\n      }\n      continue;\n    }\n\n    auto remaining_ms = timer::duration_cast<std::chrono::milliseconds>(\n      fast_timeout - (now - start_time)).count();\n\n    uint32_t wait_ms = std::min<uint32_t>(\n      static_cast<uint32_t>(std::min<uint64_t>(remaining_ms, 0xFFFFFFFEUL)),\n      static_cast<uint32_t>(signal_abort_timeout ? signal_abort_timeout * 1000 : 0xFFFFFFFFUL)\n    );\n\n    HSAKMT_CALL(hsaKmtWaitOnEvent_Ext(event_, wait_ms, &event_age));\n  }\n}\n\nhsa_signal_value_t InterruptSignal::WaitAcquire(\n    hsa_signal_condition_t condition, hsa_signal_value_t compare_value,\n    uint64_t timeout, hsa_wait_state_t wait_hint) {\n  hsa_signal_value_t ret =\n      WaitRelaxed(condition, compare_value, timeout, wait_hint);\n  std::atomic_thread_fence(std::memory_order_acquire);\n  return ret;\n}\n\nvoid InterruptSignal::AndRelaxed(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::AndAcquire(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_acquire);\n  SetEvent();\n}\n\nvoid InterruptSignal::AndRelease(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nvoid InterruptSignal::AndAcqRel(hsa_signal_value_t value) {\n  atomic::And(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n  SetEvent();\n}\n\nvoid InterruptSignal::OrRelaxed(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::OrAcquire(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_acquire);\n  SetEvent();\n}\n\nvoid InterruptSignal::OrRelease(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nvoid InterruptSignal::OrAcqRel(hsa_signal_value_t value) {\n  atomic::Or(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n  SetEvent();\n}\n\nvoid InterruptSignal::XorRelaxed(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::XorAcquire(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_acquire);\n  SetEvent();\n}\n\nvoid InterruptSignal::XorRelease(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nvoid InterruptSignal::XorAcqRel(hsa_signal_value_t value) {\n  atomic::Xor(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n  SetEvent();\n}\n\nvoid InterruptSignal::AddRelaxed(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::AddAcquire(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_acquire);\n  SetEvent();\n}\n\nvoid InterruptSignal::AddRelease(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nvoid InterruptSignal::AddAcqRel(hsa_signal_value_t value) {\n  atomic::Add(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n  SetEvent();\n}\n\nvoid InterruptSignal::SubRelaxed(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_relaxed);\n  SetEvent();\n}\n\nvoid InterruptSignal::SubAcquire(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_acquire);\n  SetEvent();\n}\n\nvoid InterruptSignal::SubRelease(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_release);\n  SetEvent();\n}\n\nvoid InterruptSignal::SubAcqRel(hsa_signal_value_t value) {\n  atomic::Sub(&signal_.value, int64_t(value), std::memory_order_acq_rel);\n  SetEvent();\n}\n\nhsa_signal_value_t InterruptSignal::ExchRelaxed(hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(atomic::Exchange(\n      &signal_.value, int64_t(value), std::memory_order_relaxed));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::ExchAcquire(hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(atomic::Exchange(\n      &signal_.value, int64_t(value), std::memory_order_acquire));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::ExchRelease(hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(atomic::Exchange(\n      &signal_.value, int64_t(value), std::memory_order_release));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::ExchAcqRel(hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(atomic::Exchange(\n      &signal_.value, int64_t(value), std::memory_order_acq_rel));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::CasRelaxed(hsa_signal_value_t expected,\n                                               hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(\n      atomic::Cas(&signal_.value, int64_t(value), int64_t(expected),\n                  std::memory_order_relaxed));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::CasAcquire(hsa_signal_value_t expected,\n                                               hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(\n      atomic::Cas(&signal_.value, int64_t(value), int64_t(expected),\n                  std::memory_order_acquire));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::CasRelease(hsa_signal_value_t expected,\n                                               hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(\n      atomic::Cas(&signal_.value, int64_t(value), int64_t(expected),\n                  std::memory_order_release));\n  SetEvent();\n  return ret;\n}\n\nhsa_signal_value_t InterruptSignal::CasAcqRel(hsa_signal_value_t expected,\n                                              hsa_signal_value_t value) {\n  hsa_signal_value_t ret = hsa_signal_value_t(\n      atomic::Cas(&signal_.value, int64_t(value), int64_t(expected),\n                  std::memory_order_acq_rel));\n  SetEvent();\n  return ret;\n}\n  /// @brief Notify driver of signal value change if necessary.\n  void InterruptSignal::SetEvent() {\n    std::atomic_signal_fence(std::memory_order_seq_cst);\n    if (InWaiting()) HSAKMT_CALL(hsaKmtSetEvent(event_));\n  }\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/ipc_signal.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/ipc_signal.h\"\n\n#include <utility>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/exceptions.h\"\n\nnamespace rocr {\nnamespace core {\n\nKernelMutex IPCSignal::lock_;\n\nSharedMemory::SharedMemory(const hsa_amd_ipc_memory_t* handle, size_t len) {\n  hsa_status_t err = Runtime::runtime_singleton_->IPCAttach(handle, len, 0, NULL, &ptr_);\n  if (err != HSA_STATUS_SUCCESS) throw AMD::hsa_exception(err, \"IPC memory attach failed.\");\n}\n\nSharedMemory::SharedMemory(SharedMemory&& rhs) {\n  ptr_ = rhs.ptr_;\n  rhs.ptr_ = nullptr;\n}\n\nSharedMemory::~SharedMemory() {\n  if (ptr_ == nullptr) return;\n  auto err = Runtime::runtime_singleton_->IPCDetach(ptr_);\n  assert(err == HSA_STATUS_SUCCESS && \"IPC detach failed.\");\n}\n\nvoid IPCSignal::CreateHandle(Signal* signal, hsa_amd_ipc_signal_t* ipc_handle) {\n  if (!signal->isIPC())\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT, \"Signal must be IPC enabled.\");\n  SharedSignal* shared = SharedSignal::Convert(Convert(signal));\n  hsa_status_t err = Runtime::runtime_singleton_->IPCCreate(shared, 4096, ipc_handle);\n  if (err != HSA_STATUS_SUCCESS) throw AMD::hsa_exception(err, \"IPC memory create failed.\");\n}\n\nSignal* IPCSignal::Attach(const hsa_amd_ipc_signal_t* ipc_signal_handle) {\n  SharedMemorySignal shared(ipc_signal_handle);\n\n  if (!(shared.signal()->IsIPC()))\n    throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                             \"IPC memory does not contain an IPC signal abi block.\");\n\n  hsa_signal_t handle = SharedSignal::Convert(shared.signal());\n\n  ScopedAcquire<KernelMutex> lock(&lock_);\n  Signal* ret = core::Signal::DuplicateHandle(handle);\n  if (ret == nullptr) ret = new IPCSignal(std::move(shared));\n  return ret;\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/isa.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/isa.h\"\n#include \"core/util/utils.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <iostream>\n#include <sstream>\n#include <utility>\n\nnamespace rocr {\nnamespace core {\n\nbool Wavefront::GetInfo(\n    const hsa_wavefront_info_t &attribute,\n    void *value) const {\n  if (!value) {\n    return false;\n  }\n\n  switch (attribute) {\n    case HSA_WAVEFRONT_INFO_SIZE: {\n      *((uint32_t*)value) = num_threads_;\n      return true;\n    }\n    default: {\n      return false;\n    }\n  }\n}\n\nstatic __forceinline std::string strip_features(const std::string &isa_name) {\n  return isa_name.substr(0, isa_name.find(':'));\n}\n\n/* static */\nbool Isa::IsCompatible(const Isa &code_object_isa,\n                       const Isa &agent_isa, unsigned int codeGenericVersion) {\n\n  bool code_obj_isa_is_generic = false;\n  auto generic_it = IsaRegistry::GetSupportedGenericVersions().find(\n                                                 code_object_isa.GetIsaName());\n\n  if (generic_it != IsaRegistry::GetSupportedGenericVersions().end()) {\n    code_obj_isa_is_generic = true;\n  }\n\n  assert(code_object_isa.IsSrameccSupported() == agent_isa.IsSrameccSupported()\n                                 && agent_isa.GetSramecc() != IsaFeature::Any);\n  if ((code_object_isa.GetSramecc() == IsaFeature::Enabled ||\n        code_object_isa.GetSramecc() == IsaFeature::Disabled) &&\n      code_object_isa.GetSramecc() != agent_isa.GetSramecc())\n    return false;\n\n  assert(code_object_isa.IsXnackSupported() == agent_isa.IsXnackSupported() && agent_isa.GetXnack() != IsaFeature::Any);\n  if ((code_object_isa.GetXnack() == IsaFeature::Enabled ||\n        code_object_isa.GetXnack() == IsaFeature::Disabled) &&\n      code_object_isa.GetXnack() != agent_isa.GetXnack())\n    return false;\n\n  if (code_obj_isa_is_generic) {\n      // Verify the generic code object corresponds to the generic for\n      // this isa agent.\n      if (strip_features(agent_isa.GetIsaGeneric()) !=\n                              strip_features(code_object_isa.GetIsaName())) {\n        return false;\n      }\n      // Verify the generic code object version is greater than or equal to\n      // the generic version for this isa agent.\n      if (codeGenericVersion < generic_it->second) {\n        return false;\n      }\n  } else if (code_object_isa.GetVersion() != agent_isa.GetVersion()) {\n    return false;\n  }\n\n  return true;\n}\n\nstd::string Isa::GetProcessorName() const {\n  return strip_features(targetid_);\n}\n\nstatic __forceinline std::string prepend_isa_prefix(const std::string &isa_name) {\n  constexpr char hsa_isa_name_prefix[] = \"amdgcn-amd-amdhsa--\";\n  return hsa_isa_name_prefix + isa_name;\n}\n\nstd::string Isa::GetIsaName() const {\n  return prepend_isa_prefix(targetid_);\n}\n\nbool Isa::GetInfo(const hsa_isa_info_t &attribute, void *value) const {\n  if (!value) {\n    return false;\n  }\n\n  switch (attribute) {\n    case HSA_ISA_INFO_NAME_LENGTH: {\n      std::string isa_name = GetIsaName();\n      *((uint32_t*)value) = static_cast<uint32_t>(isa_name.size() + 1);\n      return true;\n    }\n    case HSA_ISA_INFO_NAME: {\n      std::string isa_name = GetIsaName();\n      memset(value, 0x0, isa_name.size() + 1);\n      memcpy(value, isa_name.c_str(), isa_name.size());\n      return true;\n    }\n    // deprecated.\n    case HSA_ISA_INFO_CALL_CONVENTION_COUNT: {\n      *((uint32_t*)value) = 1;\n      return true;\n    }\n    // deprecated.\n    case HSA_ISA_INFO_CALL_CONVENTION_INFO_WAVEFRONT_SIZE: {\n      *((uint32_t*)value) = 64;\n      return true;\n    }\n    // deprecated.\n    case HSA_ISA_INFO_CALL_CONVENTION_INFO_WAVEFRONTS_PER_COMPUTE_UNIT: {\n      *((uint32_t*)value) = 40;\n      return true;\n    }\n    case HSA_ISA_INFO_MACHINE_MODELS: {\n      const bool machine_models[2] = {false, true};\n      memcpy(value, machine_models, sizeof(machine_models));\n      return true;\n    }\n    case HSA_ISA_INFO_PROFILES: {\n      bool profiles[2] = {true, false};\n      if (this->GetVersion() == Version(7, 0, 0) ||\n          this->GetVersion() == Version(8, 0, 1)) {\n        profiles[1] = true;\n      }\n      memcpy(value, profiles, sizeof(profiles));\n      return true;\n    }\n    case HSA_ISA_INFO_DEFAULT_FLOAT_ROUNDING_MODES: {\n      const bool rounding_modes[3] = {false, false, true};\n      memcpy(value, rounding_modes, sizeof(rounding_modes));\n      return true;\n    }\n    case HSA_ISA_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES: {\n      const bool rounding_modes[3] = {false, false, true};\n      memcpy(value, rounding_modes, sizeof(rounding_modes));\n      return true;\n    }\n    case HSA_ISA_INFO_FAST_F16_OPERATION: {\n      if (this->GetMajorVersion() >= 8) {\n        *((bool*)value) = true;\n      } else {\n        *((bool*)value) = false;\n      }\n      return true;\n    }\n    case HSA_ISA_INFO_WORKGROUP_MAX_DIM: {\n      const uint16_t workgroup_max_dim[3] = {1024, 1024, 1024};\n      memcpy(value, workgroup_max_dim, sizeof(workgroup_max_dim));\n      return true;\n    }\n    case HSA_ISA_INFO_WORKGROUP_MAX_SIZE: {\n      *((uint32_t*)value) = 1024;\n      return true;\n    }\n    case HSA_ISA_INFO_GRID_MAX_DIM: {\n      const hsa_dim3_t grid_max_dim = {INT32_MAX, UINT16_MAX, UINT16_MAX};\n      memcpy(value, &grid_max_dim, sizeof(grid_max_dim));\n      return true;\n    }\n    case HSA_ISA_INFO_GRID_MAX_SIZE: {\n      *((uint64_t*)value) = UINT64_MAX;\n      return true;\n    }\n    case HSA_ISA_INFO_FBARRIER_MAX_SIZE: {\n      *((uint32_t*)value) = 32;\n      return true;\n    }\n    default: {\n      return false;\n    }\n  }\n}\n\nhsa_round_method_t Isa::GetRoundMethod(\n    hsa_fp_type_t fp_type,\n    hsa_flush_mode_t flush_mode) const {\n  return HSA_ROUND_METHOD_SINGLE;\n}\n\nconst Isa *IsaRegistry::GetIsa(const std::string &full_name) {\n  auto isareg_iter = GetSupportedIsas().find(full_name);\n  return isareg_iter == GetSupportedIsas().end() ?\n                                              nullptr : &isareg_iter->second;\n}\n\nconst Isa *IsaRegistry::GetIsa(const Isa::Version &version, IsaFeature sramecc, IsaFeature xnack) {\n  auto isareg_iter = std::find_if(GetSupportedIsas().begin(),\n                                  GetSupportedIsas().end(),\n                                  [&](const IsaMap::value_type& isareg) {\n                                    return isareg.second.GetVersion() == version &&\n                                        (isareg.second.GetSramecc() == IsaFeature::Unsupported ||\n                                         isareg.second.GetSramecc() == sramecc) &&\n                                        (isareg.second.GetXnack() == IsaFeature::Unsupported ||\n                                         isareg.second.GetXnack() == xnack);\n                                  });\n  return isareg_iter == GetSupportedIsas().end() ?\n                                              nullptr : &isareg_iter->second;\n}\n\n\n// TODO: c++20 use constexpr or consteval\nconst std::unordered_map<std::string, unsigned int> &\nIsaRegistry::GetSupportedGenericVersions() {\n  static const\n    std::unordered_map<std::string, unsigned int> * min_gen_versions =\n                          new std::unordered_map<std::string, unsigned int> {\n    {prepend_isa_prefix(\"gfx9-generic\"), 1},\n    {prepend_isa_prefix(\"gfx9-generic:xnack-\"), 1},\n    {prepend_isa_prefix(\"gfx9-generic:xnack+\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:xnack-\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:xnack+\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc-\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc+\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc-:xnack-\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc-:xnack+\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc+:xnack-\"), 1},\n    {prepend_isa_prefix(\"gfx9-4-generic:sramecc+:xnack+\"), 1},\n    {prepend_isa_prefix(\"gfx10-1-generic\"), 1},\n    {prepend_isa_prefix(\"gfx10-1-generic:xnack-\"), 1},\n    {prepend_isa_prefix(\"gfx10-1-generic:xnack+\"), 1},\n    {prepend_isa_prefix(\"gfx10-3-generic\"), 1},\n    {prepend_isa_prefix(\"gfx11-generic\"), 1},\n    {prepend_isa_prefix(\"gfx12-generic\"), 1}\n  };\n  return *min_gen_versions;\n}\n\nconst IsaRegistry::IsaMap& IsaRegistry::GetSupportedIsas() {\n  // agent, and vendor name length limit excluding terminating nul character.\n  constexpr size_t hsa_name_size = 63;\n  // This allocation is meant to last until the last thread has exited.\n  // It is intentionally not freed.\n  static IsaMap* supported_isas = new IsaMap();\n\n  if (supported_isas->size() > 0) {\n    return *supported_isas;\n  }\n  \n  auto parse_out_minor_ver = [&](const std::string& generic_name) -> int32_t {\n      size_t dot_pos = generic_name.find('.');\n      int32_t min;\n      if (dot_pos != std::string::npos) {\n          std::string minor_version_str = generic_name.substr(dot_pos + 1);\n          size_t dash_pos = minor_version_str.find('-');\n          if (dash_pos != std::string::npos) {\n              minor_version_str = minor_version_str.substr(0, dash_pos);\n          }\n          min = std::stoi(minor_version_str);\n      } else {\n          min = 0xFF;\n      }\n      return min;\n  };\n\n// FIXME: Use static_assert when C++17 used.\n#define ISAREG_ENTRY_GEN(name, maj, min, stp, sramecc, xnack, wavefrontsize, gen_name) \\\n {                                                                                     \\\n  assert(std::char_traits<char>::length(name) <= hsa_name_size);                       \\\n  std::string isa_name = prepend_isa_prefix(name);                                     \\\n  (*supported_isas)[isa_name].targetid_ = name;                                           \\\n  (*supported_isas)[isa_name].version_ = Isa::Version(maj, min, stp);                     \\\n  (*supported_isas)[isa_name].sramecc_ = sramecc;                                         \\\n  (*supported_isas)[isa_name].xnack_ = xnack;                                             \\\n  (*supported_isas)[isa_name].wavefront_.num_threads_ = wavefrontsize;                    \\\n  std::string genericname(gen_name);                                                   \\\n  if (genericname.size() != 0) {                                                       \\\n    std::string gen_isa_name = prepend_isa_prefix(genericname);                        \\\n    (*supported_isas)[isa_name].generic_ = gen_isa_name;                                  \\\n    if ((*supported_isas).find(gen_isa_name) == (*supported_isas).end()) {                   \\\n      (*supported_isas)[gen_isa_name].targetid_ = genericname;                            \\\n      (*supported_isas)[gen_isa_name].version_ = Isa::Version(maj, parse_out_minor_ver(genericname), 0xFF); \\\n      (*supported_isas)[gen_isa_name].sramecc_ = sramecc;                                \\\n      (*supported_isas)[gen_isa_name].xnack_ = xnack;                                    \\\n      (*supported_isas)[gen_isa_name].wavefront_.num_threads_ = wavefrontsize;           \\\n    }                                                                                \\\n  }                                                                                  \\\n }\n\n  const IsaFeature unsupported = IsaFeature::Unsupported;\n  const IsaFeature any = IsaFeature::Any;\n  const IsaFeature disabled = IsaFeature::Disabled;\n  const IsaFeature enabled = IsaFeature::Enabled;\n\n  //               Target ID                 Version   SRAMECC      XNACK\n  ISAREG_ENTRY_GEN(\"gfx700\",                 7, 0, 0,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx701\",                 7, 0, 1,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx702\",                 7, 0, 2,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx801\",                 8, 0, 1,  unsupported, any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx801:xnack-\",          8, 0, 1,  unsupported, disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx801:xnack+\",          8, 0, 1,  unsupported, enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx802\",                 8, 0, 2,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx803\",                 8, 0, 3,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx805\",                 8, 0, 5,  unsupported, unsupported, 64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx810\",                 8, 1, 0,  unsupported, any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx810:xnack-\",          8, 1, 0,  unsupported, disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx810:xnack+\",          8, 1, 0,  unsupported, enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx900\",                 9, 0, 0,  unsupported, any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx900:xnack-\",          9, 0, 0,  unsupported, disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx900:xnack+\",          9, 0, 0,  unsupported, enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx902\",                 9, 0, 2,  unsupported, any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx902:xnack-\",          9, 0, 2,  unsupported, disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx902:xnack+\",          9, 0, 2,  unsupported, enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx904\",                 9, 0, 4,  unsupported, any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx904:xnack-\",          9, 0, 4,  unsupported, disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx904:xnack+\",          9, 0, 4,  unsupported, enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx906\",                 9, 0, 6,  any,         any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx906:xnack-\",          9, 0, 6,  any,         disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx906:xnack+\",          9, 0, 6,  any,         enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc-\",        9, 0, 6,  disabled,    any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc+\",        9, 0, 6,  enabled,     any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc-:xnack-\", 9, 0, 6,  disabled,    disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc-:xnack+\", 9, 0, 6,  disabled,    enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc+:xnack-\", 9, 0, 6,  enabled,     disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx906:sramecc+:xnack+\", 9, 0, 6,  enabled,     enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx908\",                 9, 0, 8,  any,         any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:xnack-\",          9, 0, 8,  any,         disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:xnack+\",          9, 0, 8,  any,         enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc-\",        9, 0, 8,  disabled,    any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc+\",        9, 0, 8,  enabled,     any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc-:xnack-\", 9, 0, 8,  disabled,    disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc-:xnack+\", 9, 0, 8,  disabled,    enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc+:xnack-\", 9, 0, 8,  enabled,     disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx908:sramecc+:xnack+\", 9, 0, 8,  enabled,     enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx909\",                 9, 0, 9,  unsupported, any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx909:xnack-\",          9, 0, 9,  unsupported, disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx909:xnack+\",          9, 0, 9,  unsupported, enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx90a\",                 9, 0, 10, any,         any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:xnack-\",          9, 0, 10, any,         disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:xnack+\",          9, 0, 10, any,         enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc-\",        9, 0, 10, disabled,    any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc+\",        9, 0, 10, enabled,     any,         64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc-:xnack-\", 9, 0, 10, disabled,    disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc-:xnack+\", 9, 0, 10, disabled,    enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc+:xnack-\", 9, 0, 10, enabled,     disabled,    64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90a:sramecc+:xnack+\", 9, 0, 10, enabled,     enabled,     64, \"\")\n  ISAREG_ENTRY_GEN(\"gfx90c\",                 9, 0, 12, unsupported, any,         64, \"gfx9-generic\")\n  ISAREG_ENTRY_GEN(\"gfx90c:xnack-\",          9, 0, 12, unsupported, disabled,    64, \"gfx9-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx90c:xnack+\",          9, 0, 12, unsupported, enabled,     64, \"gfx9-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx942\",                 9, 4, 2,  any,         any,         64, \"gfx9-4-generic\")\n  ISAREG_ENTRY_GEN(\"gfx942:xnack-\",          9, 4, 2,  any,         disabled,    64, \"gfx9-4-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx942:xnack+\",          9, 4, 2,  any,         enabled,     64, \"gfx9-4-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc-\",        9, 4, 2,  disabled,    any,         64, \"gfx9-4-generic:sramecc-\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc+\",        9, 4, 2,  enabled,     any,         64, \"gfx9-4-generic:sramecc+\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc-:xnack-\", 9, 4, 2,  disabled,    disabled,    64, \"gfx9-4-generic:sramecc-:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc-:xnack+\", 9, 4, 2,  disabled,    enabled,     64, \"gfx9-4-generic:sramecc-:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc+:xnack-\", 9, 4, 2,  enabled,     disabled,    64, \"gfx9-4-generic:sramecc+:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx942:sramecc+:xnack+\", 9, 4, 2,  enabled,     enabled,     64, \"gfx9-4-generic:sramecc+:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx950\",                 9, 5, 0,  any,         any,         64, \"gfx9-4-generic\")\n  ISAREG_ENTRY_GEN(\"gfx950:xnack-\",          9, 5, 0,  any,         disabled,    64, \"gfx9-4-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx950:xnack+\",          9, 5, 0,  any,         enabled,     64, \"gfx9-4-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc-\",        9, 5, 0,  disabled,    any,         64, \"gfx9-4-generic:sramecc-\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc+\",        9, 5, 0,  enabled,     any,         64, \"gfx9-4-generic:sramecc+\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc-:xnack-\", 9, 5, 0,  disabled,    disabled,    64, \"gfx9-4-generic:sramecc-:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc-:xnack+\", 9, 5, 0,  disabled,    enabled,     64, \"gfx9-4-generic:sramecc-:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc+:xnack-\", 9, 5, 0,  enabled,     disabled,    64, \"gfx9-4-generic:sramecc+:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx950:sramecc+:xnack+\", 9, 5, 0,  enabled,     enabled,     64, \"gfx9-4-generic:sramecc+:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx1010\",                10, 1, 0, unsupported, any,         32, \"gfx10-1-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1010:xnack-\",         10, 1, 0, unsupported, disabled,    32, \"gfx10-1-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx1010:xnack+\",         10, 1, 0, unsupported, enabled,     32, \"gfx10-1-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx1011\",                10, 1, 1, unsupported, any,         32, \"gfx10-1-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1011:xnack-\",         10, 1, 1, unsupported, disabled,    32, \"gfx10-1-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx1011:xnack+\",         10, 1, 1, unsupported, enabled,     32, \"gfx10-1-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx1012\",                10, 1, 2, unsupported, any,         32, \"gfx10-1-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1012:xnack-\",         10, 1, 2, unsupported, disabled,    32, \"gfx10-1-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx1012:xnack+\",         10, 1, 2, unsupported, enabled,     32, \"gfx10-1-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx1013\",                10, 1, 3, unsupported, any,         32, \"gfx10-1-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1013:xnack-\",         10, 1, 3, unsupported, disabled,    32, \"gfx10-1-generic:xnack-\")\n  ISAREG_ENTRY_GEN(\"gfx1013:xnack+\",         10, 1, 3, unsupported, enabled,     32, \"gfx10-1-generic:xnack+\")\n  ISAREG_ENTRY_GEN(\"gfx1030\",                10, 3, 0, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1031\",                10, 3, 1, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1032\",                10, 3, 2, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1033\",                10, 3, 3, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1034\",                10, 3, 4, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1035\",                10, 3, 5, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1036\",                10, 3, 6, unsupported, unsupported, 32, \"gfx10-3-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1100\",                11, 0, 0, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1101\",                11, 0, 1, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1102\",                11, 0, 2, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1103\",                11, 0, 3, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1150\",                11, 5, 0, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1151\",                11, 5, 1, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1152\",                11, 5, 2, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1153\",                11, 5, 3, unsupported, unsupported, 32, \"gfx11-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1200\",                12, 0, 0, unsupported, unsupported, 32, \"gfx12-generic\")\n  ISAREG_ENTRY_GEN(\"gfx1201\",                12, 0, 1, unsupported, unsupported, 32, \"gfx12-generic\")\n#undef ISAREG_ENTRY_GEN\n\n  return *supported_isas;\n}\n\n} // namespace core\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/queue.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/queue.h\"\n#include \"core/inc/runtime.h\"\n\nnamespace rocr {\nnamespace core {\n\n// HSA Queue ID - used to bind a unique ID\nstd::atomic<uint64_t> Queue::hsa_queue_counter_(0);\n\nvoid Queue::DefaultErrorHandler(hsa_status_t status, hsa_queue_t* source, void* data) {\n  if (core::Runtime::runtime_singleton_->flag().enable_queue_fault_message()) {\n    const char* msg = \"UNKNOWN ERROR\";\n    HSA::hsa_status_string(status, &msg);\n    fprintf(stderr, \"Queue at %p inactivated due to async error:\\n\\t%s\\n\", source, msg);\n    abort();\n  }\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/runtime.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <algorithm>\n#include <atomic>\n#include <climits>\n#include <cstring>\n#include <regex>\n#include <string>\n#include <vector>\n#include <list>\n#include <link.h>\n#include <dlfcn.h>\n#include <amdgpu_drm.h>\n#include <sys/mman.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <thread>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/hsa_table_interface.h\"\n\n#if defined(HSA_ROCPROFILER_REGISTER) && HSA_ROCPROFILER_REGISTER > 0\n#include <rocprofiler-register/rocprofiler-register.h>\n#endif\n\n#include \"core/common/shared.h\"\n#include \"core/inc/amd_core_dump.hpp\"\n#include \"core/inc/amd_cpu_agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/amd_memory_region.h\"\n#include \"core/inc/amd_topology.h\"\n#include \"core/inc/exceptions.h\"\n#include \"core/inc/host_queue.h\"\n#include \"core/inc/hsa_api_trace_int.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"core/inc/hsa_ext_interface.h\"\n#include \"core/inc/interrupt_signal.h\"\n#include \"core/inc/signal.h\"\n#include \"core/util/memory.h\"\n#include \"core/util/os.h\"\n#include \"inc/hsa_ven_amd_aqlprofile.h\"\n\n#ifndef HSA_VERSION_MAJOR\n#define HSA_VERSION_MAJOR 1\n#endif\n#ifndef HSA_VERSION_MINOR\n#define HSA_VERSION_MINOR 1\n#endif\n#ifndef HSA_VERSION_PATCH\n#define HSA_VERSION_PATCH 0\n#endif\n\n#if defined(HSA_ROCPROFILER_REGISTER) && HSA_ROCPROFILER_REGISTER > 0\n#define ROCP_REG_VERSION                                                                           \\\n  ROCPROFILER_REGISTER_COMPUTE_VERSION_3(HSA_VERSION_MAJOR, HSA_VERSION_MINOR, HSA_VERSION_PATCH)\n\nROCPROFILER_REGISTER_DEFINE_IMPORT(hsa, ROCP_REG_VERSION)\n#endif\n\nconst char rocrbuildid[] __attribute__((used)) = \"ROCR BUILD ID: \" STRING(ROCR_BUILD_ID);\n\nextern r_debug _amdgpu_r_debug;\n\nnamespace rocr {\nextern void _loader_debug_state();\nnamespace core {\nbool g_use_interrupt_wait;\nbool g_use_mwaitx;\nRuntime* Runtime::runtime_singleton_ = NULL;\n\nhsa_status_t Runtime::Acquire() {\n  ScopedAcquire<KernelMutex> boot(&bootstrap_lock());\n\n  if (runtime_singleton_ == NULL) {\n    memset(log_flags, 0, sizeof(log_flags));\n    runtime_singleton_ = new Runtime();\n  }\n\n  if (runtime_singleton_->ref_count_ == INT32_MAX) {\n    return HSA_STATUS_ERROR_REFCOUNT_OVERFLOW;\n  }\n\n  runtime_singleton_->ref_count_++;\n  MAKE_NAMED_SCOPE_GUARD(refGuard, [&]() { runtime_singleton_->ref_count_--; });\n\n  if (runtime_singleton_->ref_count_ == 1) {\n    hsa_status_t status = runtime_singleton_->Load();\n\n    if (status != HSA_STATUS_SUCCESS) {\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  refGuard.Dismiss();\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::Release() {\n  ScopedAcquire<KernelMutex> boot(&bootstrap_lock());\n\n  if (runtime_singleton_ == nullptr) return HSA_STATUS_ERROR_NOT_INITIALIZED;\n\n  if (runtime_singleton_->ref_count_ == 1) {\n    // Release all registered memory, then unload backends\n    runtime_singleton_->Unload();\n  }\n\n  runtime_singleton_->ref_count_--;\n\n  if (runtime_singleton_->ref_count_ == 0) {\n    delete runtime_singleton_;\n    runtime_singleton_ = nullptr;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool Runtime::IsOpen() {\n  return (Runtime::runtime_singleton_ != NULL) &&\n         (Runtime::runtime_singleton_->ref_count_ != 0);\n}\n\n// Register agent information only.  Must not call anything that may use the registered information\n// since those tables are incomplete.\nvoid Runtime::RegisterAgent(Agent* agent, bool Enabled) {\n  // Record the agent in the node-to-agent reverse lookup table.\n  agents_by_node_[agent->node_id()].push_back(agent);\n\n  // Process agent as a CPU, GPU, or AIE device.\n  if (agent->device_type() == Agent::DeviceType::kAmdCpuDevice) {\n    cpu_agents_.push_back(agent);\n\n    agents_by_gpuid_[0] = agent;\n\n    // Add cpu regions to the system region list.\n    for (const core::MemoryRegion* region : agent->regions()) {\n      if (region->fine_grain()) {\n        system_regions_fine_.push_back(region);\n      } else {\n        system_regions_coarse_.push_back(region);\n      }\n    }\n\n    assert(system_regions_fine_.size() > 0);\n\n    // Init default fine grain system region allocator using fine grain\n    // system region of the first discovered CPU agent.\n    if (cpu_agents_.size() == 1) {\n      // Might need memory pooling to cover allocation that\n      // requires less than 4096 bytes.\n\n      // Default system pool must support kernarg\n      for (auto pool : system_regions_fine_) {\n        if (pool->kernarg()) {\n          system_allocator_ = [pool](size_t size, size_t alignment,\n                                     MemoryRegion::AllocateFlags alloc_flags, int agent_node_id) -> void* {\n            assert(alignment <= 4096);\n            void* ptr = NULL;\n            return (HSA_STATUS_SUCCESS ==\n                    core::Runtime::runtime_singleton_->AllocateMemory(pool, size, alloc_flags,\n                                                                      &ptr, agent_node_id))\n                ? ptr\n                : NULL;\n          };\n\n          system_deallocator_ = [](void* ptr) {\n            core::Runtime::runtime_singleton_->FreeMemory(ptr);\n          };\n\n          BaseShared::SetAllocateAndFree(system_allocator_, system_deallocator_);\n          break;\n        }\n      }\n    }\n  } else if (agent->device_type() == Agent::DeviceType::kAmdGpuDevice) {\n    if (Enabled) {\n      gpu_agents_.push_back(agent);\n      gpu_ids_.push_back(agent->node_id());\n      agents_by_gpuid_[((AMD::GpuAgent*)agent)->KfdGpuID()] = agent;\n\n      // Assign the first discovered gpu agent as region gpu.\n      if (region_gpu_ == NULL) region_gpu_ = agent;\n    } else {\n      disabled_gpu_agents_.push_back(agent);\n    }\n  } else if (agent->device_type() == Agent::DeviceType::kAmdAieDevice) {\n    aie_agents_.push_back(agent);\n  }\n}\n\n// Register driver.\nvoid Runtime::RegisterDriver(std::unique_ptr<Driver> driver) {\n  agent_drivers_.push_back(std::move(driver));\n}\n\nvoid Runtime::DestroyAgents() {\n  agents_by_node_.clear();\n\n  std::for_each(gpu_agents_.begin(), gpu_agents_.end(), DeleteObject());\n  gpu_agents_.clear();\n\n  std::for_each(disabled_gpu_agents_.begin(), disabled_gpu_agents_.end(), DeleteObject());\n  disabled_gpu_agents_.clear();\n\n  gpu_ids_.clear();\n\n  std::for_each(cpu_agents_.begin(), cpu_agents_.end(), DeleteObject());\n  cpu_agents_.clear();\n\n  std::for_each(aie_agents_.begin(), aie_agents_.end(), DeleteObject());\n  aie_agents_.clear();\n\n  region_gpu_ = NULL;\n\n  system_regions_fine_.clear();\n  system_regions_coarse_.clear();\n}\n\nvoid Runtime::DestroyDrivers() {\n  agent_drivers_.clear();\n}\n\nvoid Runtime::SetLinkCount(size_t num_nodes) {\n  num_nodes_ = num_nodes;\n  link_matrix_.resize(num_nodes * num_nodes);\n}\n\nvoid Runtime::RegisterLinkInfo(uint32_t node_id_from, uint32_t node_id_to,\n                               uint32_t num_hop, uint32_t rec_sdma_eng_id_mask,\n                               hsa_amd_memory_pool_link_info_t& link_info) {\n  const uint32_t idx = GetIndexLinkInfo(node_id_from, node_id_to);\n  link_matrix_[idx].num_hop = num_hop;\n  link_matrix_[idx].rec_sdma_eng_id_mask = rec_sdma_eng_id_mask;\n  link_matrix_[idx].info = link_info;\n\n  // Limit the number of hop to 1 since the runtime does not have enough\n  // information to share to the user about each hop.\n  link_matrix_[idx].num_hop = std::min(link_matrix_[idx].num_hop , 1U);\n}\n\nconst Runtime::LinkInfo Runtime::GetLinkInfo(uint32_t node_id_from,\n                                             uint32_t node_id_to) {\n  return (node_id_from != node_id_to)\n             ? link_matrix_[GetIndexLinkInfo(node_id_from, node_id_to)]\n             : LinkInfo();  // No link.\n}\n\nuint32_t Runtime::GetIndexLinkInfo(uint32_t node_id_from, uint32_t node_id_to) {\n  return ((node_id_from * num_nodes_) + node_id_to);\n}\n\nhsa_status_t Runtime::IterateAgent(hsa_status_t (*callback)(hsa_agent_t agent,\n                                                            void* data),\n                                   void* data) {\n  AMD::callback_t<decltype(callback)> call(callback);\n\n  std::vector<core::Agent *> *agent_lists[3] = {&cpu_agents_, &gpu_agents_,\n                                                &aie_agents_};\n  for (std::vector<core::Agent*>* agent_list : agent_lists) {\n    for (size_t i = 0; i < agent_list->size(); ++i) {\n      hsa_agent_t agent = Agent::Convert(agent_list->at(i));\n      hsa_status_t status = call(agent, data);\n\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::AllocateMemory(const MemoryRegion* region, size_t size,\n                                     MemoryRegion::AllocateFlags alloc_flags,\n                                     void** address, int agent_node_id) {\n  size_t size_requested = size;  // region->Allocate(...) may align-up size to granularity\n  hsa_status_t status = region->Allocate(size, alloc_flags, address, agent_node_id);\n  // Track the allocation result so that it could be freed properly.\n  if (status == HSA_STATUS_SUCCESS) {\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n    allocation_map_[*address] = AllocationRegion(region, size, size_requested, alloc_flags);\n  }\n\n  return status;\n}\n\nhsa_status_t Runtime::FreeMemory(void* ptr) {\n  if (ptr == nullptr) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  const MemoryRegion* region = nullptr;\n  size_t size = 0;\n  std::unique_ptr<std::vector<AllocationRegion::notifier_t>> notifiers;\n  MemoryRegion::AllocateFlags alloc_flags = core::MemoryRegion::AllocateNoFlags;\n\n  {\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n    std::map<const void*, AllocationRegion>::iterator it = allocation_map_.find(ptr);\n\n    if (it == allocation_map_.end()) {\n      debug_warning(false && \"Can't find address in allocation map\");\n      return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n    }\n    region = it->second.region;\n    size = it->second.size;\n    alloc_flags = it->second.alloc_flags;\n\n    // Imported fragments can't be released with FreeMemory.\n    if (region == nullptr) {\n      assert(false && \"Can't release imported memory with free.\");\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n\n    notifiers = std::move(it->second.notifiers);\n\n    allocation_map_.erase(it);\n  }\n\n  // Notifiers can't run while holding the lock or the callback won't be able to manage memory.\n  // The memory triggering the notification has already been removed from the memory map so can't\n  // be double released during the callback.\n  if (notifiers) {\n    for (auto& notifier : *notifiers) {\n      notifier.callback(notifier.ptr, notifier.user_data);\n    }\n  }\n\n  if (alloc_flags & core::MemoryRegion::AllocateAsan)\n    assert(region->owner()->driver().ReturnAsanHeaderPage(ptr) == HSA_STATUS_SUCCESS);\n\n  const hsa_status_t err = region->Free(ptr, size);\n  if (err != HSA_STATUS_SUCCESS) {\n    // hsaKmtFreeMemory failed to free this pointer. Throw a memory error event\n\n    // Note: This should be treated as a fatal exception by the System Event Handler because:\n    //  - This leaves allocation_map_ in an inconsistent state as this pointer entry has already\n    //  been removed.\n    //  - We already called back the notifier, but did not actually free.\n    //  - We removed the ASAN Header but did not actually free.\n    //\n    // But this is a very unlikely use case and calling region->Free(..) before updating\n    // allocation_map_ would require us to hold the memory_lock_ for much longer and we would not be\n    // able to call hsaKmtReturnAsanHeaderPage after calling region->Free(..)\n\n    const core::Agent* agentOwner = region->owner();\n    hsa_status_t custom_handler_status = HSA_STATUS_ERROR;\n    auto system_event_handlers = runtime_singleton_->GetSystemEventHandlers();\n\n    if (!system_event_handlers.empty()) {\n      hsa_amd_event_t memory_error_event;\n      memory_error_event.event_type = HSA_AMD_GPU_MEMORY_ERROR_EVENT;\n      hsa_amd_gpu_memory_error_info_t& error_info = memory_error_event.memory_error;\n\n      error_info.virtual_address = reinterpret_cast<const uint64_t>(ptr);\n      error_info.error_reason_mask = HSA_AMD_MEMORY_ERROR_MEMORY_IN_USE;\n      error_info.agent = Agent::Convert(agentOwner);\n\n      for (auto& callback : system_event_handlers) {\n        hsa_status_t err = callback.first(&memory_error_event, callback.second);\n        if (err == HSA_STATUS_SUCCESS) custom_handler_status = HSA_STATUS_SUCCESS;\n      }\n    }\n    // No custom VM fault handler registered or it failed.\n    if (custom_handler_status != HSA_STATUS_SUCCESS) {\n      fprintf(stderr,\n              \"Memory critical error by agent node-%u (Agent handle: %p) on address %p. Reason: \"\n              \"Memory in use. \\n\",\n              agentOwner->node_id(), reinterpret_cast<void*>(agentOwner->public_handle().handle),\n              ptr);\n\n      assert(false && \"GPU memory error.\");\n      std::abort();\n    }\n    return HSA_STATUS_ERROR;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::RegisterReleaseNotifier(void* ptr, hsa_amd_deallocation_callback_t callback,\n                                              void* user_data) {\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  auto mem = allocation_map_.upper_bound(ptr);\n  if (mem != allocation_map_.begin()) {\n    mem--;\n\n    // No support for imported fragments yet.\n    if (mem->second.region == nullptr) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n    if ((mem->first <= ptr) &&\n        (ptr < reinterpret_cast<const uint8_t*>(mem->first) + mem->second.size)) {\n      auto& notifiers = mem->second.notifiers;\n      if (!notifiers) notifiers.reset(new std::vector<AllocationRegion::notifier_t>);\n      AllocationRegion::notifier_t notifier = {\n          ptr, AMD::callback_t<hsa_amd_deallocation_callback_t>(callback), user_data};\n      notifiers->push_back(notifier);\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n  return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n}\n\nhsa_status_t Runtime::DeregisterReleaseNotifier(void* ptr,\n                                                hsa_amd_deallocation_callback_t callback) {\n  hsa_status_t ret = HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  auto mem = allocation_map_.upper_bound(ptr);\n  if (mem != allocation_map_.begin()) {\n    mem--;\n    if ((mem->first <= ptr) &&\n        (ptr < reinterpret_cast<const uint8_t*>(mem->first) + mem->second.size)) {\n      auto& notifiers = mem->second.notifiers;\n      if (!notifiers) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      for (size_t i = 0; i < notifiers->size(); i++) {\n        if (((*notifiers)[i].ptr == ptr) && ((*notifiers)[i].callback) == callback) {\n          (*notifiers)[i] = std::move((*notifiers)[notifiers->size() - 1]);\n          notifiers->pop_back();\n          i--;\n          ret = HSA_STATUS_SUCCESS;\n        }\n      }\n    }\n  }\n  return ret;\n}\n\nhsa_status_t Runtime::CopyMemory(void* dst, const void* src, size_t size) {\n  void* source = const_cast<void*>(src);\n\n  // Choose agents from pointer info\n  bool is_src_system = false;\n  bool is_dst_system = false;\n  core::Agent* src_agent;\n  core::Agent* dst_agent;\n\n  // Fetch ownership\n  const auto& is_system_mem = [&](void* ptr, core::Agent*& agent, bool& need_lock) {\n    hsa_amd_pointer_info_t info = {};\n    uint32_t count = 0;\n    hsa_agent_t* accessible = nullptr;\n    MAKE_SCOPE_GUARD([&]() { free(accessible); });\n    info.size = sizeof(info);\n    hsa_status_t err = PtrInfo(ptr, &info, malloc, &count, &accessible);\n    if (err != HSA_STATUS_SUCCESS)\n      throw AMD::hsa_exception(err, \"PtrInfo failed in hsa_memory_copy.\");\n    ptrdiff_t endPtr = (ptrdiff_t)ptr + size;\n    if (info.agentBaseAddress <= ptr &&\n        endPtr <= (ptrdiff_t)info.agentBaseAddress + info.sizeInBytes) {\n      if (info.agentOwner.handle == 0) info.agentOwner = accessible[0];\n      agent = core::Agent::Convert(info.agentOwner);\n      need_lock = false;\n      return agent->device_type() != core::Agent::DeviceType::kAmdGpuDevice;\n    } else {\n      need_lock = true;\n      agent = cpu_agents_[0];\n      return true;\n    }\n  };\n\n  bool src_lock, dst_lock;\n  is_src_system = is_system_mem(source, src_agent, src_lock);\n  is_dst_system = is_system_mem(dst, dst_agent, dst_lock);\n\n  // CPU-CPU\n  if (is_src_system && is_dst_system) {\n    memcpy(dst, source, size);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Same GPU\n  if (src_agent->node_id() == dst_agent->node_id()) return dst_agent->DmaCopy(dst, source, size);\n\n  // GPU-CPU\n  // Must ensure that system memory is visible to the GPU during the copy.\n  const AMD::MemoryRegion* system_region =\n      static_cast<const AMD::MemoryRegion*>(system_regions_fine_[0]);\n\n  void* gpuPtr = nullptr;\n  const auto& locked_copy = [&](void*& ptr, core::Agent* locking_agent) {\n    void* tmp;\n    hsa_agent_t agent = locking_agent->public_handle();\n    hsa_status_t err = system_region->Lock(1, &agent, ptr, size, &tmp);\n    if (err != HSA_STATUS_SUCCESS) throw AMD::hsa_exception(err, \"Lock failed in hsa_memory_copy.\");\n    gpuPtr = ptr;\n    ptr = tmp;\n  };\n\n  MAKE_SCOPE_GUARD([&]() {\n    if (gpuPtr != nullptr) system_region->Unlock(gpuPtr);\n  });\n\n  if (src_lock) locked_copy(source, dst_agent);\n  if (dst_lock) locked_copy(dst, src_agent);\n  if (is_src_system) return dst_agent->DmaCopy(dst, source, size);\n  if (is_dst_system) return src_agent->DmaCopy(dst, source, size);\n\n  /*\n  GPU-GPU - functional support, not a performance path.\n\n  This goes through system memory because we have to support copying between non-peer GPUs\n  and we can't use P2P pointers even if the GPUs are peers.  Because hsa_amd_agents_allow_access\n  requires the caller to specify all allowed agents we can't assume that a peer mapped pointer\n  would remain mapped for the duration of the copy.\n  */\n  void* temp = system_allocator_(size, 0, core::MemoryRegion::AllocateNoFlags, 0);\n  MAKE_SCOPE_GUARD([&]() { system_deallocator_(temp); });\n  hsa_status_t err = src_agent->DmaCopy(temp, source, size);\n  if (err == HSA_STATUS_SUCCESS) err = dst_agent->DmaCopy(dst, temp, size);\n  return err;\n}\n\nhsa_status_t Runtime::CopyMemory(void* dst, core::Agent* dst_agent, const void* src,\n                                 core::Agent* src_agent, size_t size,\n                                 std::vector<core::Signal*>& dep_signals,\n                                 core::Signal& completion_signal) {\n  auto lookupAgent = [this](core::Agent* agent, const void* ptr) {\n    hsa_amd_pointer_info_t info = {};\n    PtrInfoBlockData block = {};\n    info.size = sizeof(info);\n    hsa_status_t err = PtrInfo(ptr, &info, nullptr, nullptr, nullptr, &block);\n    if (err != HSA_STATUS_SUCCESS)\n      throw AMD::hsa_exception(err, \"PtrInfo failed in hsa_memory_copy.\");\n    // Limit to IPC and GFX types for now.  These are the only types for which the application may\n    // not posess a proper agent handle.\n    if ((info.type != HSA_EXT_POINTER_TYPE_IPC) && (info.type != HSA_EXT_POINTER_TYPE_GRAPHICS)) {\n      return agent;\n    }\n    return block.agentOwner;\n  };\n\n  const bool src_gpu = (src_agent->device_type() == core::Agent::DeviceType::kAmdGpuDevice);\n  core::Agent* copy_agent = (src_gpu) ? src_agent : dst_agent;\n\n  // Lookup owning agent if blit kernel is selected or if flag override is set.\n  if ((dst_agent == src_agent) || flag().discover_copy_agents()) {\n    dst_agent = lookupAgent(dst_agent, dst);\n    src_agent = lookupAgent(src_agent, src);\n  }\n  return copy_agent->DmaCopy(dst, *dst_agent, src, *src_agent, size, dep_signals,\n                             completion_signal);\n}\n\nhsa_status_t Runtime::CopyMemoryOnEngine(void* dst, core::Agent* dst_agent, const void* src,\n                                 core::Agent* src_agent, size_t size,\n                                 std::vector<core::Signal*>& dep_signals,\n                                 core::Signal& completion_signal,\n                                 hsa_amd_sdma_engine_id_t engine_id, bool force_copy_on_sdma) {\n  const bool src_gpu = (src_agent->device_type() == core::Agent::DeviceType::kAmdGpuDevice);\n  core::Agent* copy_agent = (src_gpu) ? src_agent : dst_agent;\n\n  // engine_id is single bitset unique.\n  int engine_offset = ffs(engine_id);\n  if (!engine_id || !!((engine_id >> engine_offset))) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return copy_agent->DmaCopyOnEngine(dst, *dst_agent, src, *src_agent, size, dep_signals,\n                             completion_signal, engine_offset, force_copy_on_sdma);\n}\n\nhsa_status_t Runtime::CopyMemoryStatus(core::Agent* dst_agent, core::Agent* src_agent,\n                                       uint32_t *engine_ids_mask) {\n  const bool src_gpu = (src_agent->device_type() == core::Agent::DeviceType::kAmdGpuDevice);\n  core::Agent* copy_agent = (src_gpu) ? src_agent : dst_agent;\n\n  if (dst_agent == src_agent) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  return copy_agent->DmaCopyStatus(*dst_agent, *src_agent, engine_ids_mask);\n}\n\nhsa_status_t Runtime::GetPreferredEngine(core::Agent* dst_agent, core::Agent* src_agent,\n                                         uint32_t* recommended_ids_mask) {\n  const bool src_gpu = (src_agent->device_type() == core::Agent::DeviceType::kAmdGpuDevice);\n  core::Agent* copy_agent = (src_gpu) ? src_agent : dst_agent;\n\n  if (dst_agent == src_agent) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  return copy_agent->DmaPreferredEngine(*dst_agent, *src_agent, recommended_ids_mask);\n}\n\nhsa_status_t Runtime::FillMemory(void* ptr, uint32_t value, size_t count) {\n  // Choose blit agent from pointer info\n  hsa_amd_pointer_info_t info = {};\n  uint32_t agent_count = 0;\n  hsa_agent_t* accessible = nullptr;\n  info.size = sizeof(info);\n  MAKE_SCOPE_GUARD([&]() { free(accessible); });\n  hsa_status_t err = PtrInfo(ptr, &info, malloc, &agent_count, &accessible);\n  if (err != HSA_STATUS_SUCCESS) return err;\n\n  ptrdiff_t endPtr = (ptrdiff_t)ptr + count * sizeof(uint32_t);\n\n  // Check for GPU fill\n  // Selects GPU fill for SVM and Locked allocations if a GPU address is given and is mapped.\n  if (info.agentBaseAddress <= ptr &&\n      endPtr <= (ptrdiff_t)info.agentBaseAddress + info.sizeInBytes) {\n    core::Agent* blit_agent = core::Agent::Convert(info.agentOwner);\n    if (blit_agent->device_type() != core::Agent::DeviceType::kAmdGpuDevice) {\n      blit_agent = nullptr;\n      for (uint32_t i = 0; i < agent_count; i++) {\n        if (core::Agent::Convert(accessible[i])->device_type() ==\n            core::Agent::DeviceType::kAmdGpuDevice) {\n          blit_agent = core::Agent::Convert(accessible[i]);\n          break;\n        }\n      }\n    }\n    if (blit_agent) return blit_agent->DmaFill(ptr, value, count);\n  }\n\n  // Host and unmapped SVM addresses copy via host.\n  if (info.hostBaseAddress <= ptr && endPtr <= (ptrdiff_t)info.hostBaseAddress + info.sizeInBytes) {\n    memset(ptr, value, count * sizeof(uint32_t));\n    return HSA_STATUS_SUCCESS;\n  }\n\n  return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n}\n\nhsa_status_t Runtime::AllowAccess(uint32_t num_agents,\n                                  const hsa_agent_t* agents, const void* ptr) {\n  const AMD::MemoryRegion* amd_region = NULL;\n  size_t alloc_size = 0;\n\n  {\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n    std::map<const void*, AllocationRegion>::const_iterator it = allocation_map_.find(ptr);\n\n    if (it == allocation_map_.end()) {\n      /* See if this address was mapped via VMM */\n      return VMemoryMapAllowAccess(ptr, HSA_ACCESS_PERMISSION_RW, agents,\n                                   num_agents);\n    }\n\n    amd_region = reinterpret_cast<const AMD::MemoryRegion*>(it->second.region);\n\n    // Imported IPC handle entries inside allocation_map_ do not have an amd_region because they\n    // were allocated in the other process. Access is already granted during IPCAttach().\n    if (!amd_region)\n      return HSA_STATUS_SUCCESS;\n\n    alloc_size = it->second.size;\n  }\n\n  return amd_region->AllowAccess(num_agents, agents, ptr, alloc_size);\n}\n\nhsa_status_t Runtime::GetSystemInfo(hsa_system_info_t attribute, void* value) {\n  switch (attribute) {\n    case HSA_SYSTEM_INFO_VERSION_MAJOR:\n      *((uint16_t*)value) = HSA_VERSION_MAJOR;\n      break;\n    case HSA_SYSTEM_INFO_VERSION_MINOR:\n      *((uint16_t*)value) = HSA_VERSION_MINOR;\n      break;\n    case HSA_SYSTEM_INFO_TIMESTAMP: {\n      *((uint64_t*)value) = os::ReadSystemClock();\n      break;\n    }\n    case HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY: {\n      assert(sys_clock_freq_ != 0 &&\n             \"Use of HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY before HSA \"\n             \"initialization completes.\");\n      *(uint64_t*)value = sys_clock_freq_;\n      break;\n    }\n    case HSA_SYSTEM_INFO_SIGNAL_MAX_WAIT:\n      *((uint64_t*)value) = 0xFFFFFFFFFFFFFFFF;\n      break;\n    case HSA_SYSTEM_INFO_ENDIANNESS:\n#if defined(HSA_LITTLE_ENDIAN)\n      *((hsa_endianness_t*)value) = HSA_ENDIANNESS_LITTLE;\n#else\n      *((hsa_endianness_t*)value) = HSA_ENDIANNESS_BIG;\n#endif\n      break;\n    case HSA_SYSTEM_INFO_MACHINE_MODEL:\n#if defined(HSA_LARGE_MODEL)\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_LARGE;\n#else\n      *((hsa_machine_model_t*)value) = HSA_MACHINE_MODEL_SMALL;\n#endif\n      break;\n    case HSA_SYSTEM_INFO_EXTENSIONS: {\n      memset(value, 0, sizeof(uint8_t) * 128);\n\n      auto setFlag = [&](uint32_t bit) {\n        assert(bit < 128 * 8 && \"Extension value exceeds extension bitmask\");\n        uint index = bit / 8;\n        uint subBit = bit % 8;\n        ((uint8_t*)value)[index] |= 1 << subBit;\n      };\n\n      if (hsa_internal_api_table().finalizer_api.hsa_ext_program_finalize_fn != NULL) {\n        setFlag(HSA_EXTENSION_FINALIZER);\n      }\n\n      if (hsa_internal_api_table().image_api.hsa_ext_image_create_fn != NULL) {\n        setFlag(HSA_EXTENSION_IMAGES);\n      }\n\n      if (os::LibHandle lib = os::LoadLib(kAqlProfileLib)) {\n        os::CloseLib(lib);\n        setFlag(HSA_EXTENSION_AMD_AQLPROFILE);\n      }\n\n      setFlag(HSA_EXTENSION_AMD_PROFILER);\n\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_BUILD_VERSION: {\n      *(const char**)value = STRING(ROCR_BUILD_ID);\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_SVM_SUPPORTED: {\n      bool ret = true;\n      for (auto agent : gpu_agents_) {\n        AMD::GpuAgent* gpu = (AMD::GpuAgent*)agent;\n        ret &= (gpu->properties().Capability.ui32.SVMAPISupported == 1);\n      }\n      *(bool*)value = ret;\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_SVM_ACCESSIBLE_BY_DEFAULT: {\n      bool ret = true;\n      for(auto agent : gpu_agents_)\n        ret &= (agent->supported_isas()[0]->GetXnack() == IsaFeature::Enabled);\n      *(bool*)value = ret;\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_MWAITX_ENABLED: {\n      *((bool*)value) = g_use_mwaitx;\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_DMABUF_SUPPORTED: {\n      auto kfd_version = core::Runtime::runtime_singleton_->KfdVersion().version;\n\n      // Implemented in KFD in 1.12\n      if (kfd_version.KernelInterfaceMajorVersion > 1 ||\n          (kfd_version.KernelInterfaceMajorVersion == 1 &&\n              kfd_version.KernelInterfaceMinorVersion >= 12))\n        *(reinterpret_cast<bool*>(value)) = true;\n      else\n        *(reinterpret_cast<bool*>(value)) = false;\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED: {\n      *((bool*)value) = core::Runtime::runtime_singleton_->VirtualMemApiSupported();\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_XNACK_ENABLED: {\n      *((bool*)value) = core::Runtime::runtime_singleton_->XnackEnabled();\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_EXT_VERSION_MAJOR: {\n      *((uint16_t*)value) = HSA_AMD_INTERFACE_VERSION_MAJOR;\n      break;\n    }\n    case HSA_AMD_SYSTEM_INFO_EXT_VERSION_MINOR: {\n      *((uint16_t*)value) = HSA_AMD_INTERFACE_VERSION_MINOR;\n      break;\n    }\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::SetAsyncSignalHandler(hsa_signal_t signal,\n                                            hsa_signal_condition_t cond,\n                                            hsa_signal_value_t value,\n                                            hsa_amd_signal_handler handler,\n                                            void* arg) {\n\n  struct AsyncEventsInfo* asyncInfo = &asyncSignals_;\n  int priority = runtime_singleton_->flag().async_events_thread_priority();\n\n  if (signal.handle != 0) {\n    // Indicate that this signal is in use.\n    hsa_signal_handle(signal)->Retain();\n\n    core::Signal* coreSignal = core::Signal::Convert(signal);\n    if (coreSignal->EopEvent() && coreSignal->EopEvent()->EventData.EventType != HSA_EVENTTYPE_SIGNAL) {\n      priority = os::OS_THREAD_PRIORITY_DEFAULT;\n      asyncInfo = &asyncExceptions_;\n    }\n  }\n\n  ScopedAcquire<HybridMutex> scope_lock(&asyncInfo->control.lock);\n\n  // Lazy initializer\n  if (asyncInfo->control.async_events_thread_ == NULL) {\n    // Create monitoring thread control signal\n    auto err = HSA::hsa_signal_create(0, 0, NULL, &asyncInfo->control.wake);\n    if (err != HSA_STATUS_SUCCESS) {\n      assert(false && \"Asyncronous events control signal creation error.\");\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n    asyncInfo->events.PushBack(asyncInfo->control.wake, HSA_SIGNAL_CONDITION_NE,\n                          0, NULL, NULL);\n\n    // Start event monitoring thread\n    asyncInfo->control.exit = false;\n    asyncInfo->control.async_events_thread_ =\n        os::CreateThread(AsyncEventsLoop, asyncInfo, 0, priority);\n    if (asyncInfo->control.async_events_thread_ == NULL) {\n      assert(false && \"Asyncronous events thread creation error.\");\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  asyncInfo->new_events.PushBack(signal, cond, value, handler, arg);\n\n  hsa_signal_handle(asyncInfo->control.wake)->StoreRelease(1);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::InteropMap(uint32_t num_agents, Agent** agents,\n                                 int interop_handle, uint32_t flags,\n                                 size_t* size, void** ptr,\n                                 size_t* metadata_size, const void** metadata) {\n  static const int tinyArraySize=8;\n  HsaGraphicsResourceInfo info;\n\n  HSAuint32 short_nodes[tinyArraySize];\n  HSAuint32* nodes = short_nodes;\n  if (num_agents > tinyArraySize) {\n    nodes = new HSAuint32[num_agents];\n    if (nodes == NULL) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  MAKE_SCOPE_GUARD([&]() {\n    if (num_agents > tinyArraySize) delete[] nodes;\n  });\n\n  for (uint32_t i = 0; i < num_agents; i++)\n    agents[i]->GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_DRIVER_NODE_ID,\n                       &nodes[i]);\n\n  if (HSAKMT_CALL(hsaKmtRegisterGraphicsHandleToNodes(interop_handle, &info, num_agents,\n                                          nodes)) != HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR;\n\n  HSAuint64 altAddress;\n  HsaMemMapFlags map_flags;\n  map_flags.Value = 0;\n  map_flags.ui32.PageSize = HSA_PAGE_SIZE_64KB;\n  if (HSAKMT_CALL(hsaKmtMapMemoryToGPUNodes(info.MemoryAddress, info.SizeInBytes,\n                                &altAddress, map_flags, num_agents,\n                                nodes)) != HSAKMT_STATUS_SUCCESS) {\n    map_flags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n    if (HSAKMT_CALL(hsaKmtMapMemoryToGPUNodes(info.MemoryAddress, info.SizeInBytes, &altAddress, map_flags,\n                                  num_agents, nodes)) != HSAKMT_STATUS_SUCCESS) {\n      HSAKMT_CALL(hsaKmtDeregisterMemory(info.MemoryAddress));\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    }\n  }\n\n  if (metadata_size != NULL) *metadata_size = info.MetadataSizeInBytes;\n  if (metadata != NULL) *metadata = info.Metadata;\n\n  *size = info.SizeInBytes;\n  *ptr = info.MemoryAddress;\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  allocation_map_[info.MemoryAddress] = AllocationRegion(\n      nullptr, info.SizeInBytes, info.SizeInBytes, core::MemoryRegion::AllocateNoFlags);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::InteropUnmap(void* ptr) {\n  if(HSAKMT_CALL(hsaKmtUnmapMemoryToGPU(ptr))!=HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  if(HSAKMT_CALL(hsaKmtDeregisterMemory(ptr))!=HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::PtrInfo(const void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),\n                              uint32_t* num_agents_accessible, hsa_agent_t** accessible,\n                              PtrInfoBlockData* block_info) {\n  static_assert(static_cast<int>(HSA_POINTER_UNKNOWN) == static_cast<int>(HSA_EXT_POINTER_TYPE_UNKNOWN),\n                \"Thunk pointer info mismatch\");\n  static_assert(static_cast<int>(HSA_POINTER_ALLOCATED) == static_cast<int>(HSA_EXT_POINTER_TYPE_HSA),\n                \"Thunk pointer info mismatch\");\n  static_assert(static_cast<int>(HSA_POINTER_REGISTERED_USER) == static_cast<int>(HSA_EXT_POINTER_TYPE_LOCKED),\n                \"Thunk pointer info mismatch\");\n  static_assert(static_cast<int>(HSA_POINTER_REGISTERED_GRAPHICS) == static_cast<int>(HSA_EXT_POINTER_TYPE_GRAPHICS),\n                \"Thunk pointer info mismatch\");\n\n  HsaPointerInfo thunkInfo;\n  uint32_t* mappedNodes;\n\n  hsa_amd_pointer_info_t retInfo = {0};\n\n  // check output struct has an initialized size.\n  if (info->size == 0) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  retInfo.size = Min(size_t(info->size), sizeof(hsa_amd_pointer_info_t));\n\n  bool returnListData =\n      ((alloc != nullptr) && (num_agents_accessible != nullptr) && (accessible != nullptr));\n\n  bool allocation_map_entry_found = false;\n\n  {  // memory_lock protects access to the NMappedNodes array and fragment user data since these may\n     // change with calls to memory APIs.\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n    // We don't care if this returns an error code.\n    // The type will be HSA_EXT_POINTER_TYPE_UNKNOWN if so.\n    auto err = HSAKMT_CALL(hsaKmtQueryPointerInfo(ptr, &thunkInfo));\n    if (err != HSAKMT_STATUS_SUCCESS || thunkInfo.Type == HSA_POINTER_UNKNOWN) {\n      retInfo.type = HSA_EXT_POINTER_TYPE_UNKNOWN;\n      memcpy(info, &retInfo, retInfo.size);\n      return HSA_STATUS_SUCCESS;\n    }\n\n    if (returnListData) {\n      assert(thunkInfo.NMappedNodes <= agents_by_node_.size() &&\n             \"PointerInfo: Thunk returned more than all agents in NMappedNodes.\");\n      mappedNodes = (uint32_t*)alloca(thunkInfo.NMappedNodes * sizeof(uint32_t));\n      memcpy(mappedNodes, thunkInfo.MappedNodes, thunkInfo.NMappedNodes * sizeof(uint32_t));\n    }\n    retInfo.type = (hsa_amd_pointer_type_t)thunkInfo.Type;\n    retInfo.agentBaseAddress = reinterpret_cast<void*>(thunkInfo.GPUAddress);\n    retInfo.hostBaseAddress = thunkInfo.CPUAddress;\n    retInfo.sizeInBytes = thunkInfo.SizeInBytes;\n    retInfo.userData = thunkInfo.UserData;\n    retInfo.global_flags = thunkInfo.MemFlags.ui32.CoarseGrain\n        ? HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED\n        : HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED;\n    retInfo.global_flags |=\n        thunkInfo.MemFlags.ui32.Uncached ? HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT : 0;\n    if (block_info != nullptr) {\n      // Block_info reports the thunk allocation from which we may have suballocated.\n      // For locked memory we want to return the host address since hostBaseAddress is used to\n      // manipulate locked memory and it is possible that hostBaseAddress is different from\n      // agentBaseAddress.\n      // For device memory, hostBaseAddress is either equal to agentBaseAddress or is NULL when the\n      // CPU does not have access.\n      assert((retInfo.hostBaseAddress || retInfo.agentBaseAddress) && \"Thunk pointer info returned no base address.\");\n      block_info->base = (retInfo.hostBaseAddress ? retInfo.hostBaseAddress : retInfo.agentBaseAddress);\n      block_info->length = retInfo.sizeInBytes;\n\n      // Report the owning agent, even if such an agent is not usable in the process.\n      auto nodeAgents = agents_by_node_.find(thunkInfo.Node);\n      assert(nodeAgents != agents_by_node_.end() && \"Node id not found!\");\n      block_info->agentOwner = nodeAgents->second[0];\n    }\n    auto fragment = allocation_map_.upper_bound(ptr);\n    if (fragment != allocation_map_.begin()) {\n      fragment--;\n      if ((fragment->first <= ptr) &&\n          (ptr < reinterpret_cast<const uint8_t*>(fragment->first) + fragment->second.size_requested)) {\n        // agent and host address must match here. Only lock memory is allowed to have differing\n        // addresses but lock memory has type HSA_EXT_POINTER_TYPE_LOCKED and cannot be\n        // suballocated.\n        retInfo.agentBaseAddress = const_cast<void*>(fragment->first);\n        retInfo.hostBaseAddress = retInfo.agentBaseAddress;\n        retInfo.sizeInBytes = fragment->second.size_requested;\n        retInfo.userData = fragment->second.user_ptr;\n        allocation_map_entry_found = true;\n      }\n    }\n  }  // end lock scope\n\n  // Return type UNKNOWN for released fragments.  Do not report the underlying block info to users!\n  if ((!allocation_map_entry_found) &&\n      ((retInfo.type == HSA_EXT_POINTER_TYPE_HSA) || (retInfo.type == HSA_EXT_POINTER_TYPE_IPC))) {\n    retInfo.type = HSA_EXT_POINTER_TYPE_UNKNOWN;\n  }\n\n  // IPC and Graphics memory may come from a node that does not have an agent in this process.\n  // Ex. ROCR_VISIBLE_DEVICES or peer GPU is not supported by ROCm.\n  retInfo.agentOwner.handle = 0;\n  auto nodeAgents = agents_by_node_.find(thunkInfo.Node);\n  assert(nodeAgents != agents_by_node_.end() && \"Node id not found!\");\n  for (auto agent : nodeAgents->second) {\n    if (agent->Enabled()) {\n      retInfo.agentOwner = agent->public_handle();\n      break;\n    }\n  }\n\n  // Correct agentOwner for locked memory.  Thunk reports the GPU that owns the\n  // alias but users are expecting to see a CPU when the memory is system.\n  if (retInfo.type == HSA_EXT_POINTER_TYPE_LOCKED) {\n    if ((nodeAgents == agents_by_node_.end()) ||\n        (nodeAgents->second[0]->device_type() != core::Agent::kAmdCpuDevice)) {\n      retInfo.agentOwner = cpu_agents_[0]->public_handle();\n    }\n  }\n\n  memcpy(info, &retInfo, retInfo.size);\n\n  if (returnListData) {\n    uint32_t count = 0;\n    for (HSAuint32 i = 0; i < thunkInfo.NMappedNodes; i++) {\n      assert(mappedNodes[i] <= max_node_id() &&\n             \"PointerInfo: Invalid node ID returned from thunk.\");\n      count += agents_by_node_[mappedNodes[i]].size();\n    }\n\n    AMD::callback_t<decltype(alloc)> Alloc(alloc);\n    *accessible = (hsa_agent_t*)Alloc(sizeof(hsa_agent_t) * count);\n    if ((*accessible) == nullptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n    *num_agents_accessible = count;\n\n    uint32_t index = 0;\n    for (HSAuint32 i = 0; i < thunkInfo.NMappedNodes; i++) {\n      auto& list = agents_by_node_[mappedNodes[i]];\n      for (auto agent : list) {\n        (*accessible)[index] = agent->public_handle();\n        index++;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::SetPtrInfoData(const void* ptr, void* userptr) {\n  {  // Use allocation map if possible to handle fragments.\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n    const auto& it = allocation_map_.find(ptr);\n    if (it != allocation_map_.end()) {\n      it->second.user_ptr = userptr;\n      return HSA_STATUS_SUCCESS;\n    }\n  }\n  // Cover entries not in the allocation map (graphics, lock,...)\n  if (HSAKMT_CALL(hsaKmtSetMemoryUserData(ptr, userptr)) == HSAKMT_STATUS_SUCCESS)\n    return HSA_STATUS_SUCCESS;\n  return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n}\n\n// Send the dmabuf_fd to from process via Unix socket\nstatic int SendDmaBufFd(int socket, int dmabuf_fd) {\n  char iov_buf[1];\n  struct msghdr msg = {0};\n  char buf[CMSG_SPACE(sizeof(dmabuf_fd))];\n\n  memset(buf, 0, sizeof(buf));\n  memset(iov_buf, 0, sizeof(iov_buf));\n  iov_buf[0] = 'y';\n\n  struct iovec io = {.iov_base = iov_buf, .iov_len = 1};\n\n  msg.msg_iov = &io;\n  msg.msg_iovlen = 1;\n  msg.msg_control = buf;\n  msg.msg_controllen = sizeof(buf);\n\n  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);\n  cmsg->cmsg_level = SOL_SOCKET;\n  cmsg->cmsg_type = SCM_RIGHTS;\n  cmsg->cmsg_len = CMSG_LEN(sizeof(dmabuf_fd));\n\n  memcpy(CMSG_DATA(cmsg), &dmabuf_fd, sizeof(dmabuf_fd));\n\n  msg.msg_controllen = CMSG_SPACE(sizeof(dmabuf_fd));\n\n  ssize_t sent = sendmsg(socket, &msg, 0);\n\n  return (sent < 0) ? -1 : 0;\n}\n\n// Receive the dmabuf_fd to from process via Unix socket\nstatic int ReceiveDmaBufFd(int socket) {\n  struct msghdr msg = {0};\n\n  // The struct iovec is needed, even if it points to minimal data\n  char m_buffer[1];\n  struct iovec io = {.iov_base = m_buffer, .iov_len = sizeof(m_buffer)};\n  msg.msg_iov = &io;\n  msg.msg_iovlen = 1;\n\n  char c_buffer[256];\n  msg.msg_control = c_buffer;\n  msg.msg_controllen = sizeof(c_buffer);\n\n  ssize_t rcv = recvmsg(socket, &msg, MSG_WAITALL);\n  if (rcv < 0) return -1;\n\n  while (!rcv)\n    rcv = recvmsg(socket, &msg, MSG_WAITALL);\n\n  struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);\n\n  int fd;\n  memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));\n\n  return fd;\n}\n\n#define IPC_SOCK_SERVER_DMABUF_FD_HANDLE_LENGTH 64\n#define IPC_SOCK_SERVER_NAME_LENGTH 32\n#define IPC_SOCK_SERVER_CONN_CLOSE_HANDLE UINT64_MAX\nvoid Runtime::AsyncIPCSockServerConnLoop(void*) {\n   auto& ipc_sock_server_fd_ = runtime_singleton_->ipc_sock_server_fd_;\n   auto& ipc_sock_server_conns_ = runtime_singleton_->ipc_sock_server_conns_;\n   auto& ipc_sock_server_lock_ = runtime_singleton_->ipc_sock_server_lock_;\n\n   int connection_fd;\n   char buf[IPC_SOCK_SERVER_DMABUF_FD_HANDLE_LENGTH];\n   // Wait until the client has connected\n   while (1) {\n     connection_fd = accept(ipc_sock_server_fd_, NULL, NULL);\n     if (connection_fd == -1) continue;\n     MAKE_SCOPE_GUARD([&]() { close(connection_fd); });\n     if (read(connection_fd, buf, sizeof(buf)) == -1)\n       continue;\n\n     // Request to kill the server.\n     uint64_t conn_handle = strtoull(buf, NULL, 10);\n     if (conn_handle == IPC_SOCK_SERVER_CONN_CLOSE_HANDLE)\n       break;\n\n     int dmabuf_fd = -1;\n     uint64_t fragOffset;\n     void *ptr = NULL;\n     size_t len = 0;\n\n     // Search for registered export pointer\n     ScopedAcquire<KernelMutex> lock(&ipc_sock_server_lock_);\n     for (auto& conns : ipc_sock_server_conns_) {\n       if (conn_handle == conns.first) {\n         ptr = reinterpret_cast<void *>(conn_handle);\n         len = conns.second;\n         break;\n       }\n     }\n\n     if (!ptr) continue;\n\n     // Export DMA Buf FD and wait for client import\n     int err = HSAKMT_CALL(hsaKmtExportDMABufHandle(ptr, len, &dmabuf_fd, &fragOffset));\n     if (err != HSAKMT_STATUS_SUCCESS) continue;\n     SendDmaBufFd(connection_fd, dmabuf_fd);\n     err = read(connection_fd, buf, sizeof(buf));\n     close(dmabuf_fd);\n     if (err == -1) break; // Client failed to confirm import so end server\n   }\n\n   // Clean up\n   ipc_sock_server_conns_.clear();\n   close(ipc_sock_server_fd_);\n}\n\nhsa_status_t Runtime::IPCCreate(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle) {\n  static_assert(sizeof(hsa_amd_ipc_memory_t) == sizeof(HsaSharedMemoryHandle),\n                \"Thunk IPC mismatch.\");\n\n  static const size_t pageSize = 4096;\n\n  // Reject sharing allocations larger than ~8TB due to thunk limitations.\n  if (len > 0x7FFFFFFF000ull) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  memset(handle->handle, 0, sizeof(handle->handle));\n\n  // Check for fragment sharing.\n  PtrInfoBlockData block = {};\n  hsa_amd_pointer_info_t info = {};\n  info.size = sizeof(info);\n  if (PtrInfo(ptr, &info, nullptr, nullptr, nullptr, &block) != HSA_STATUS_SUCCESS)\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  if (info.agentBaseAddress != ptr || info.sizeInBytes != len)\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  Agent* agent = Agent::Convert(info.agentOwner);\n  bool useFrag = (block.base != ptr || block.length != len);\n  // Assume all pointers and blocks are 4Kb aligned.\n  uint32_t fragOffset = (reinterpret_cast<uint8_t*>(ptr) -\n                         reinterpret_cast<uint8_t*>(block.base))/pageSize;\n  if (useFrag) {\n    if (!IsMultipleOf(block.base, 2 * 1024 * 1024)) {\n      assert(false && \"Fragment's block not aligned to 2MB!\");\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n  }\n\n  if (!ipc_dmabuf_supported_) {\n    HsaSharedMemoryHandle *sHandle = reinterpret_cast<HsaSharedMemoryHandle*>(handle);\n    if (agent->driver().ShareMemory(block.base, block.length, sHandle) != HSA_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n    hsa_status_t err = HSA_STATUS_SUCCESS;\n    if (useFrag) {\n      handle->handle[6] |= 0x80000000 | fragOffset;\n      // Prevent realloction of fragment for better performance.\n      ScopedAcquire<KernelSharedMutex::Shared> lock(memory_lock_.shared());\n      err = allocation_map_[ptr].region->IPCFragmentExport(ptr);\n      assert(err == HSA_STATUS_SUCCESS && \"Region inconsistent with address map.\");\n    }\n    return err;\n  }\n\n  // User ptr as dmabuf FD handle ID for client to request the actual dmabuf FD.\n  uint32_t dmaBufFdHandleLo = (reinterpret_cast<uint64_t>(ptr) & 0xffffffff);\n  uint32_t dmaBufFdHandleHi = (reinterpret_cast<uint64_t>(ptr) >> 32);\n  handle->handle[0] = dmaBufFdHandleLo;\n  handle->handle[1] = dmaBufFdHandleHi;\n  handle->handle[2] = getpid(); // socket server name handle\n\n  handle->handle[3] = agent->device_type() == Agent::kAmdCpuDevice;\n  // System sub allocations are not supported for now.\n  if (handle->handle[3] && useFrag) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  handle->handle[4] = agent->node_id();\n  if (useFrag) handle->handle[6] |= 0x80000000 | fragOffset;\n\n  // Work around to defer export on import call to minimize FD creation.\n  // Without this, a deferred export may fail due to the kernel mode driver not\n  // holding the GEM object reference.\n  // Export the dmabuf then close the file to get the reference to ensure the\n  // deferred export will not run into this problem.\n  int dmabuf_fd;\n  uint64_t dmabufOffset;\n  hsa_status_t err = agent->driver().ExportDMABuf(ptr, len, &dmabuf_fd, &dmabufOffset);\n  assert(dmabufOffset/pageSize == fragOffset && \"DMA Buf inconsistent with pointer offset.\");\n  if (err != HSA_STATUS_SUCCESS) return err;\n  close(dmabuf_fd);\n\n  ScopedAcquire<KernelMutex> lock(&ipc_sock_server_lock_);\n  if (!ipc_sock_server_conns_.size()) { // create new runtime socket server\n    struct sockaddr_un address;\n    ipc_sock_server_fd_ = socket(AF_UNIX, SOCK_STREAM, 0);\n    assert(ipc_sock_server_fd_ > -1 && \"DMA buffer could not be exported for IPC!\");\n    if (ipc_sock_server_fd_ == -1) return HSA_STATUS_ERROR;\n\n    // Use the PID as unique socket server name.\n    char socketName[IPC_SOCK_SERVER_NAME_LENGTH];\n    snprintf(socketName, IPC_SOCK_SERVER_NAME_LENGTH, \"xhsa%i\", handle->handle[2]);\n\n    // Initialize os socket server with client acceptance limit.\n    // Socket servers sill serialize connections and drop connections over the listen limit.\n    // The client can try and reconnect and it's unlikely that INT_MAX concurrent\n    // connections will occur.\n    memset(&address, 0, sizeof(struct sockaddr_un));\n    address.sun_family = AF_UNIX;\n    strncpy(address.sun_path, socketName, IPC_SOCK_SERVER_NAME_LENGTH);\n    address.sun_path[0] = 0; // first NULL char creates unlisted abstract socket\n    int err = bind(ipc_sock_server_fd_, (struct sockaddr *)&address, sizeof(struct sockaddr_un));\n    assert(!err && \"Connection to export DMA buffer not made!\");\n    if (err) return HSA_STATUS_ERROR;\n    err = listen(ipc_sock_server_fd_, 1);\n    assert(!err && \"Connection to export DMA buffer not made!\");\n    if (err) return HSA_STATUS_ERROR;\n\n    // Spin server client acceptance into a socket server thread.\n    // Socket server needs to last for the lifetime of the runtime instance\n    // as the attach life cycle is unknown.\n    os::CreateThread(AsyncIPCSockServerConnLoop, NULL);\n  }\n\n  ipc_sock_server_conns_[reinterpret_cast<uint64_t>(ptr)] = len;\n\n  // TODO: fragment block discard for better memory performance causes memory violations\n  // with DMABuf export even when synchronously called. Bypass for now.\n\n  return HSA_STATUS_SUCCESS;\n}\n\nint Runtime::IPCClientImport(uint32_t conn_handle, uint64_t dmabuf_fd_handle,\n                             amdgpu_bo_import_result *res,\n                             unsigned int numNodes, HSAuint32 *nodes,\n                             void **importAddress, HSAuint64 *importSize) {\n    struct sockaddr_un address;\n    int dmabuf_fd = -1, socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);\n    assert(socket_fd > -1 && \"DMA buffer could not be imported for IPC!\");\n    if (socket_fd == -1) return -1;\n\n    // Set 10 second timeout for ReceiveDmaBufFd\n    struct timeval tv;\n    tv.tv_sec = 10;\n    tv.tv_usec = 0;\n    int status = setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));\n    assert(status == 0 && \"DMA buffer FD could not be received for IPC!\");\n    if (status) return -1;\n\n    char buf[IPC_SOCK_SERVER_DMABUF_FD_HANDLE_LENGTH];\n    memset(&address, 0, sizeof(struct sockaddr_un));\n    memset(buf, 0, sizeof(buf));\n    address.sun_family = AF_UNIX;\n    snprintf(address.sun_path, IPC_SOCK_SERVER_NAME_LENGTH, \"xhsa%i\", conn_handle);\n    address.sun_path[0] = 0; // first NULL char creates unlisted abstract socket\n\n    int timeoutLimitMs = 10000, timeoutMs = 0, timeoutIntervalMs = 1;\n    while (timeoutMs < timeoutLimitMs) {\n      if (connect(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un))) {\n        timeoutMs  += timeoutIntervalMs;\n        std::this_thread::sleep_for(std::chrono::milliseconds(timeoutIntervalMs));\n      } else {\n        break;\n      }\n    }\n\n    MAKE_SCOPE_GUARD([&]() { close(socket_fd); });\n\n    if (timeoutMs >= timeoutLimitMs) return -1;\n\n    // Ping server to export and send DMABUF FD on handle\n    snprintf(buf, sizeof(buf), \"%li\", dmabuf_fd_handle);\n    if (write(socket_fd, buf, sizeof(buf)) == -1) return -1;\n\n    if (dmabuf_fd_handle == IPC_SOCK_SERVER_CONN_CLOSE_HANDLE) return 0;\n\n    dmabuf_fd = ReceiveDmaBufFd(socket_fd);\n    if (dmabuf_fd == -1) return -1;\n\n    HsaGraphicsResourceInfo info;\n    HSA_REGISTER_MEM_FLAGS regFlags;\n    regFlags.ui32.requiresVAddr = !!res ? 0 : 1;\n    int err = HSAKMT_CALL(hsaKmtRegisterGraphicsHandleToNodesExt(dmabuf_fd, &info, numNodes, nodes, regFlags));\n    if (err == HSAKMT_STATUS_SUCCESS) {\n      *importAddress = info.MemoryAddress;\n      *importSize = info.SizeInBytes;\n      if (res) {\n        HSAKMT_CALL(hsaKmtDeregisterMemory(*importAddress));\n\n        // Manually libDRM import and GPU map system memory\n        AMD::GpuAgent* agent = reinterpret_cast<AMD::GpuAgent*>(agents_by_node_[info.NodeId][0]);\n        err = DRM_CALL(amdgpu_bo_import(agent->libDrmDev(), amdgpu_bo_handle_type_dma_buf_fd,\n                               dmabuf_fd, res));\n      }\n      close(dmabuf_fd);\n    }\n\n    // Ping socket server to close exporter\n    if (write(socket_fd, buf, sizeof(buf)) == -1) return -1;\n    return err;\n}\n\nhsa_status_t Runtime::IPCAttach(const hsa_amd_ipc_memory_t* handle, size_t len, uint32_t num_agents,\n                                Agent** agents, void** mapped_ptr) {\n  static const int tinyArraySize = 8;\n  void* importAddress;\n  HSAuint64 importSize;\n  uint64_t dmaBufFDHandle = 0;\n  hsa_amd_ipc_memory_t importHandle = *handle;\n\n  // Extract fragment info\n  bool isFragment = false;\n  uint32_t fragOffset = 0;\n\n  if (Runtime::IsDifferentDriver(*agents, num_agents)) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  core::Driver* driver = &agents[0]->driver();\n\n  auto fixFragment = [&](amdgpu_bo_handle ldrm_bo) {\n    if (isFragment) {\n      importAddress = reinterpret_cast<uint8_t*>(importAddress) + fragOffset;\n      len = Min(len, importSize - fragOffset);\n    }\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n    allocation_map_[importAddress] =\n        AllocationRegion(nullptr, len, len, core::MemoryRegion::AllocateNoFlags);\n    allocation_map_[importAddress].ldrm_bo = ldrm_bo;\n  };\n\n  auto importMemory = [&](unsigned int numNodes, HSAuint32* nodes, amdgpu_bo_import_result* res) {\n    if (ipc_dmabuf_supported_) {\n      int ret = IPCClientImport(importHandle.handle[2], dmaBufFDHandle, res, numNodes, nodes,\n                                &importAddress, &importSize);\n      if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    } else {\n      hsa_status_t ret = driver->RegisterSharedHandle(\n          reinterpret_cast<const HsaSharedMemoryHandle*>(&importHandle), &importAddress,\n          &importSize);\n      if (ret != HSA_STATUS_SUCCESS) return ret;\n    }\n\n    return HSA_STATUS_SUCCESS;\n  };\n\n  auto mapMemoryToNodes = [&](unsigned int numNodes, HSAuint32 *nodes) {\n    HSAuint64 altAddress;\n    if (!numNodes) {\n      if (HSAKMT_CALL(hsaKmtMapMemoryToGPU(importAddress, importSize, &altAddress)) != HSAKMT_STATUS_SUCCESS) {\n        HSAKMT_CALL(hsaKmtDeregisterMemory(importAddress));\n        return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n      }\n    } else {\n      HsaMemMapFlags map_flags;\n      map_flags.Value = 0;\n      map_flags.ui32.PageSize = HSA_PAGE_SIZE_64KB;\n      if (HSAKMT_CALL(hsaKmtMapMemoryToGPUNodes(importAddress, importSize, &altAddress, map_flags, numNodes,\n                                    nodes)) != HSAKMT_STATUS_SUCCESS) {\n        map_flags.ui32.PageSize = HSA_PAGE_SIZE_4KB;\n        if (HSAKMT_CALL(hsaKmtMapMemoryToGPUNodes(importAddress, importSize, &altAddress, map_flags, numNodes,\n                                      nodes)) != HSAKMT_STATUS_SUCCESS) {\n          HSAKMT_CALL(hsaKmtDeregisterMemory(importAddress));\n          return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n        }\n      }\n    }\n    fixFragment(NULL);\n    *mapped_ptr = importAddress;\n    return HSA_STATUS_SUCCESS;\n  };\n\n  if ((importHandle.handle[6] & 0x80000000) != 0) {\n    isFragment = true;\n    fragOffset = (importHandle.handle[6] & 0x1FF) * 4096;\n    importHandle.handle[6] &= ~(0x80000000 | 0x1FF);\n  }\n\n  if (ipc_dmabuf_supported_) {\n    uint64_t dmaBufFDHandleLo = importHandle.handle[0];\n    uint64_t dmaBufFDHandleHi = importHandle.handle[1];\n    dmaBufFDHandle = (dmaBufFDHandleHi << 32) | dmaBufFDHandleLo;\n  }\n\n  if (num_agents == 0) {\n    amdgpu_bo_import_result res;\n    bool isDmabufSysMem = ipc_dmabuf_supported_ && importHandle.handle[3];\n\n    hsa_status_t err = importMemory(0, NULL, isDmabufSysMem ? &res : NULL);\n    if (err != HSA_STATUS_SUCCESS) return err;\n    if (!isDmabufSysMem) return mapMemoryToNodes(0, NULL);\n\n    // System memory DMA Buf import\n    auto errCleanup = [&](amdgpu_bo_handle bo)\n    {\n      DRM_CALL(amdgpu_bo_free(bo)); // auto frees cpu map\n      return HSA_STATUS_ERROR;\n    };\n\n    // Create a shared cpu access pointer for user\n    void *cpuPtr;\n    amdgpu_bo_handle bo = res.buf_handle;\n    int ret = DRM_CALL(amdgpu_bo_cpu_map(bo, &cpuPtr));\n    if (ret) return errCleanup(bo);\n\n    // Note VA ops will always override flags to allow read/write/exec permissions.\n    ret = DRM_CALL(amdgpu_bo_va_op(bo, 0, importSize,\n                          reinterpret_cast<uint64_t>(cpuPtr), 0, AMDGPU_VA_OP_MAP));\n    if (ret) return errCleanup(bo);\n    importAddress = cpuPtr;\n    fixFragment(bo);\n    *mapped_ptr = importAddress;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  HSAuint32* nodes = nullptr;\n  if (num_agents > tinyArraySize)\n    nodes = new HSAuint32[num_agents];\n  else\n    nodes = (HSAuint32*)alloca(sizeof(HSAuint32) * num_agents);\n  if (nodes == NULL) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  MAKE_SCOPE_GUARD([&]() {\n    if (num_agents > tinyArraySize) delete[] nodes;\n  });\n\n  for (uint32_t i = 0; i < num_agents; i++)\n    agents[i]->GetInfo((hsa_agent_info_t)HSA_AMD_AGENT_INFO_DRIVER_NODE_ID, &nodes[i]);\n\n  hsa_status_t err = importMemory(num_agents, nodes, NULL);\n  if (err != HSA_STATUS_SUCCESS) return err;\n  return mapMemoryToNodes(num_agents, nodes);\n}\n\nhsa_status_t Runtime::IPCDetach(void* ptr) {\n  bool ldrmImportCleaned = false;\n  {  // Handle imported fragments.\n    ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n    const auto& it = allocation_map_.find(ptr);\n    if (it != allocation_map_.end()) {\n      if (it->second.region != nullptr) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      if (it->second.ldrm_bo) {\n         if (DRM_CALL(amdgpu_bo_va_op(it->second.ldrm_bo, 0, it->second.size,\n                             reinterpret_cast<uint64_t>(ptr), 0, AMDGPU_VA_OP_UNMAP)))\n           return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n         if (DRM_CALL(amdgpu_bo_free(it->second.ldrm_bo))) // auto unmaps from cpu\n           return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n         ldrmImportCleaned = true;\n      }\n      allocation_map_.erase(it);\n      lock.Release();  // Can't hold memory lock when using pointer info.\n\n      PtrInfoBlockData block = {};\n      hsa_amd_pointer_info_t info = {};\n      info.size = sizeof(info);\n      if (PtrInfo(ptr, &info, nullptr, nullptr, nullptr, &block) != HSA_STATUS_SUCCESS)\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      ptr = block.base;\n    }\n  }\n\n  if (!ldrmImportCleaned) {\n    if (HSAKMT_CALL(hsaKmtUnmapMemoryToGPU(ptr)) != HSAKMT_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    if (HSAKMT_CALL(hsaKmtDeregisterMemory(ptr)) != HSAKMT_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid Runtime::AsyncEventsLoop(void* _eventsInfo) {\n  AsyncEventsInfo* eventsInfo = reinterpret_cast<AsyncEventsInfo*>(_eventsInfo);\n\n  auto& async_events_control_ = eventsInfo->control;\n  auto& async_events_ = eventsInfo->events;\n  auto& new_async_events_ = eventsInfo->new_events;\n  auto& hsa_events = eventsInfo->events.hsa_events_;\n  auto& event_age = eventsInfo->events.age_;\n  uint32_t unique_evts = 0;\n  auto hsa_signals = reinterpret_cast<hsa_signal_handle*>(&async_events_.signal_[0]);\n\n  auto processEvent = [&](size_t index, hsa_signal_value_t value, bool wait_any) {\n    // No error or timeout occured, process the handlers\n    // Call handler for the known satisfied signal.\n    assert(async_events_.handler_[index] != nullptr);\n    bool keep = async_events_.handler_[index](value, async_events_.arg_[index]);\n    if (!keep) {\n      if (!wait_any) {\n        hsa_signals[index]->WaitingDec();\n      }\n      hsa_signal_handle(async_events_.signal_[index])->Release();\n      async_events_.CopyIndex(index, async_events_.Size() - 1);\n      async_events_.PopBack();\n    }\n    return keep;\n  };\n\n  // Prepares a list of events for a wait inside KFD\n  auto PrepareInterrupt = [&](size_t idx, bool init_age) {\n    HsaEvent* hsa_event = hsa_signals[idx]->EopEvent();\n    // If any signal doesn't have an interrupt, then switch to polling\n    if (hsa_event == nullptr) {\n      unique_evts = 0;\n      return false;\n    } else {\n      if (hsa_events.size() <= unique_evts) {\n          hsa_events.resize(unique_evts + 10);\n          event_age.resize(unique_evts + 10);\n      }\n      if (init_age || hsa_events[unique_evts] != hsa_event ) {\n        event_age[unique_evts] = runtime_singleton_->KfdVersion().supports_event_age ? 1 : 0;\n      }\n      hsa_events[unique_evts] = hsa_event;\n      unique_evts++;\n      return true;\n    }\n  };\n\n  // KFD will move this thread into sleep, until any event from the list is complete or\n  // if ROCR can wake it up with hsaKmtSetEvent()\n  auto WaitForInterrupt = [&]() {\n    constexpr uint32_t wait_ms = 0xFFFFFFFEu;\n    HsaEvent** end = std::unique(&hsa_events[0], &hsa_events[0] + unique_evts);\n    unique_evts = uint32_t(end - &hsa_events[0]);\n    HSAKMT_CALL(hsaKmtWaitOnMultipleEvents_Ext(&hsa_events[0], unique_evts, false, wait_ms, &event_age[0]));\n  };\n\n  while (!async_events_control_.exit) {\n    // Wait for a signal\n    std::vector<hsa_signal_value_t> value(1);\n    value[0] = 0;\n    uint32_t index = 0;\n    uint32_t wait_any = true;\n    if (eventsInfo->monitor_exceptions) {\n      index =\n          Signal::WaitAnyExceptions(uint32_t(async_events_.Size()), &async_events_.signal_[0],\n                                    &async_events_.cond_[0], &async_events_.value_[0], &value[0]);\n    } else {\n     if (core::Runtime::runtime_singleton_->flag().wait_any()) {\n       index = Signal::WaitMultiple(uint32_t(async_events_.Size()), &async_events_.signal_[0],\n                                    &async_events_.cond_[0], &async_events_.value_[0], uint64_t(-1),\n                                    HSA_WAIT_STATE_BLOCKED, value, false);\n     } else {\n      // Skip wake-up signal logic\n      index = 1;\n      wait_any = false;\n      // The new events can reallocate the signals, hence update the pointer\n      hsa_signals = reinterpret_cast<hsa_signal_handle*>(&async_events_.signal_[0]);\n     }\n    }\n\n    // Reset the control signal\n    if (index == 0) {\n      hsa_signal_handle(async_events_control_.wake)->StoreRelaxed(0);\n    } else if (index != -1) {\n      if (wait_any) {\n        processEvent(index, value[0], wait_any);\n      } else {\n        index = 0;\n      }\n      // Process all signals on the CPU first\n      bool finish = false;\n      bool polling = false;\n      bool init_age = true;\n\n      // Mark all signals with a waiting tag\n      // @note: Waiting tag must be marked before the signal state check on CPU to\n      // avoid a possible race condition between KFD sleep and rocr's awake call\n      if (!wait_any) {\n        for (size_t e = 0; e < async_events_.Size(); e++) {\n          hsa_signals[e]->WaitingInc();\n        }\n      }\n      while (!finish) {\n        // If exception or WaitAny(), then finish with just one iterration\n        if (wait_any) {\n          finish = true;\n        }\n        bool interrupt_wait = false;\n        unique_evts = 0;\n\n        // Check remaining signals before sleeping.\n        for (size_t i = index; i < async_events_.Size(); i++) {\n          hsa_signal_handle sig(async_events_.signal_[i]);\n          value[0] = atomic::Load(&sig->signal_.value, std::memory_order_relaxed);\n          if (CheckSignalCondition(value[0], async_events_.cond_[i], async_events_.value_[i])) {\n            if (i == 0) {\n              hsa_signal_handle(async_events_control_.wake)->StoreRelaxed(0);\n            } else {\n              if (!processEvent(i, value[0], wait_any)) {\n                i--;\n              }\n            }\n            if (!wait_any) {\n              finish = true;\n              init_age = true;\n            }\n          }\n\n          // If the current signal isn't complete and polling is disabled, then prepare KFD wait for an interrupt\n          if (!finish && !polling) {\n            interrupt_wait = PrepareInterrupt(i, init_age);\n            // If the interrupt was disabled, then force polling\n            if (!interrupt_wait) {\n              polling = true;\n              finish = false;\n            }\n          } else if (unique_evts > 0) {\n            unique_evts = 0;\n            interrupt_wait = false;\n          }\n        }\n        // If nothing was complete and an interrupt wait was requested, then call KFD\n        if (interrupt_wait) {\n          WaitForInterrupt();\n          init_age = false;\n        }\n      }\n    }\n\n    if (!wait_any) {\n      // Remove the waiting tags from events\n      for (size_t e = 0; e < async_events_.Size(); e++) {\n        hsa_signals[e]->WaitingDec();\n      }\n    }\n\n    // Insert new signals and find plain functions\n    typedef std::pair<void (*)(void*), void*> func_arg_t;\n    std::vector<func_arg_t> functions;\n    {\n      ScopedAcquire<HybridMutex> scope_lock(&async_events_control_.lock);\n      for (size_t i = 0; i < new_async_events_.Size(); i++) {\n        if (new_async_events_.signal_[i].handle == 0) {\n          functions.push_back(\n              func_arg_t((void (*)(void*))new_async_events_.handler_[i],\n                         new_async_events_.arg_[i]));\n          continue;\n        }\n        async_events_.PushBack(\n            new_async_events_.signal_[i], new_async_events_.cond_[i],\n            new_async_events_.value_[i], new_async_events_.handler_[i],\n            new_async_events_.arg_[i]);\n      }\n      new_async_events_.Clear();\n    }\n\n    // Call plain functions\n    for (size_t i = 0; i < functions.size(); i++)\n      functions[i].first(functions[i].second);\n    functions.clear();\n  }\n\n  // Release wait count of all pending signals\n  for (size_t i = 1; i < async_events_.Size(); i++)\n    hsa_signal_handle(async_events_.signal_[i])->Release();\n  async_events_.Clear();\n\n  for (size_t i = 0; i < new_async_events_.Size(); i++)\n    hsa_signal_handle(new_async_events_.signal_[i])->Release();\n  new_async_events_.Clear();\n}\n\nvoid Runtime::BindErrorHandlers() {\n  if (!core::g_use_interrupt_wait || gpu_agents_.empty()) return;\n\n  // Create memory event with manual reset to avoid racing condition\n  // with driver in case of multiple concurrent VM faults.\n  vm_fault_event_ = core::InterruptSignal::CreateEvent(HSA_EVENTTYPE_MEMORY, true);\n\n  // Create an interrupt signal object to contain the memory event.\n  // This signal object will be registered with the async handler global\n  // thread.\n  vm_fault_signal_ = new core::InterruptSignal(0, vm_fault_event_);\n\n  if (!vm_fault_signal_->IsValid() || vm_fault_signal_->EopEvent() == NULL) {\n    assert(false && \"Failed on creating VM fault signal\");\n    return;\n  }\n\n  SetAsyncSignalHandler(core::Signal::Convert(vm_fault_signal_), HSA_SIGNAL_CONDITION_NE, 0,\n                        VMFaultHandler, reinterpret_cast<void*>(vm_fault_signal_));\n\n  // Create HW exception event which is for Non-RAS events\n  hw_exception_event_ = core::InterruptSignal::CreateEvent(HSA_EVENTTYPE_HW_EXCEPTION, true);\n\n  hw_exception_signal_ = new core::InterruptSignal(0, hw_exception_event_);\n\n  if (!hw_exception_signal_->IsValid() || hw_exception_signal_->EopEvent() == NULL) {\n    assert(false && \"Failed on creating HW Exception signal\");\n    return;\n  }\n\n  SetAsyncSignalHandler(core::Signal::Convert(hw_exception_signal_), HSA_SIGNAL_CONDITION_NE, 0,\n                        HwExceptionHandler, reinterpret_cast<void*>(hw_exception_signal_));\n}\n\nbool Runtime::HwExceptionHandler(hsa_signal_value_t val, void* arg) {\n  core::InterruptSignal* hw_exception_signal = reinterpret_cast<core::InterruptSignal*>(arg);\n\n  assert(hw_exception_signal != NULL);\n\n  if (hw_exception_signal == NULL) return false;\n\n  HsaEvent* exception_event = hw_exception_signal->EopEvent();\n\n  HsaHwException& exception = exception_event->EventData.EventData.HwException;\n\n  hsa_status_t custom_handler_status = HSA_STATUS_ERROR;\n  auto system_event_handlers = runtime_singleton_->GetSystemEventHandlers();\n  // If custom handler is registered, pack the fault info and call the handler\n\n  if (!system_event_handlers.empty()) {\n    hsa_amd_event_t hw_exception_event;\n    hw_exception_event.event_type = HSA_AMD_GPU_HW_EXCEPTION_EVENT;\n    hsa_amd_gpu_hw_exception_info_t& exception_info = hw_exception_event.hw_exception;\n\n    // Find the faulty agent\n    auto it = runtime_singleton_->agents_by_node_.find(exception.NodeId);\n    assert(it != runtime_singleton_->agents_by_node_.end() && \"Can't find faulty agent.\");\n    Agent* faulty_agent = it->second.front();\n    exception_info.agent = Agent::Convert(faulty_agent);\n\n    // This field is not set by KFD at the moment\n    exception_info.reset_type = HSA_AMD_HW_EXCEPTION_RESET_TYPE_OTHER;\n\n    exception_info.reset_cause = (exception.ResetCause == HSA_EVENTID_HW_EXCEPTION_ECC)\n        ? HSA_AMD_HW_EXCEPTION_CAUSE_ECC\n        : HSA_AMD_HW_EXCEPTION_CAUSE_GPU_HANG;\n\n    for (auto& callback : system_event_handlers) {\n      hsa_status_t err = callback.first(&hw_exception_event, callback.second);\n      if (err == HSA_STATUS_SUCCESS) custom_handler_status = HSA_STATUS_SUCCESS;\n    }\n  }\n\n  if (custom_handler_status != HSA_STATUS_SUCCESS) {\n    core::Agent* faultingAgent = runtime_singleton_->agents_by_node_[exception.NodeId][0];\n    fprintf(stderr, \"HW Exception by GPU node-%u (Agent handle: %p) reason :%s\\n\", exception.NodeId,\n            reinterpret_cast<void*>(faultingAgent->public_handle().handle),\n            (exception.ResetCause == HSA_EVENTID_HW_EXCEPTION_ECC) ? \"ECC\" : \"GPU Hang\");\n\n    assert(false && \"GPU HW Exception\");\n    std::abort();\n  }\n  // No need to keep the signal because we are done.\n  return false;\n}\n\nbool Runtime::VMFaultHandler(hsa_signal_value_t val, void* arg) {\n  core::InterruptSignal* vm_fault_signal =\n      reinterpret_cast<core::InterruptSignal*>(arg);\n\n  assert(vm_fault_signal != NULL);\n\n  if (vm_fault_signal == NULL) {\n    return false;\n  }\n\n  HsaEvent* vm_fault_event = vm_fault_signal->EopEvent();\n\n  HsaMemoryAccessFault& fault =\n      vm_fault_event->EventData.EventData.MemoryAccessFault;\n\n  hsa_status_t custom_handler_status = HSA_STATUS_ERROR;\n  auto system_event_handlers = runtime_singleton_->GetSystemEventHandlers();\n  Agent* faulty_agent = nullptr;\n  // If custom handler is registered, pack the fault info and call the handler\n  if (!system_event_handlers.empty()) {\n    hsa_amd_event_t memory_fault_event;\n    memory_fault_event.event_type = HSA_AMD_GPU_MEMORY_FAULT_EVENT;\n    hsa_amd_gpu_memory_fault_info_t& fault_info = memory_fault_event.memory_fault;\n\n    // Find the faulty agent\n    auto it = runtime_singleton_->agents_by_node_.find(fault.NodeId);\n    assert(it != runtime_singleton_->agents_by_node_.end() && \"Can't find faulty agent.\");\n    faulty_agent = it->second.front();\n    fault_info.agent = Agent::Convert(faulty_agent);\n\n    fault_info.virtual_address = fault.VirtualAddress;\n    fault_info.fault_reason_mask = 0;\n    if (fault.Failure.NotPresent == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_PAGE_NOT_PRESENT;\n    }\n    if (fault.Failure.ReadOnly == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_READ_ONLY;\n    }\n    if (fault.Failure.NoExecute == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_NX;\n    }\n    if (fault.Failure.GpuAccess == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_HOST_ONLY;\n    }\n    if (fault.Failure.Imprecise == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_IMPRECISE;\n    }\n    if (fault.Failure.ECC == 1 && fault.Failure.ErrorType == 0) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_DRAMECC;\n    }\n    if (fault.Failure.ErrorType == 1) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_SRAMECC;\n    }\n    if (fault.Failure.ErrorType == 2) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_DRAMECC;\n    }\n    if (fault.Failure.ErrorType == 3) {\n      fault_info.fault_reason_mask |= HSA_AMD_MEMORY_FAULT_HANG;\n    }\n\n    for (auto& callback : system_event_handlers) {\n      hsa_status_t err = callback.first(&memory_fault_event, callback.second);\n      if (err == HSA_STATUS_SUCCESS) custom_handler_status = HSA_STATUS_SUCCESS;\n    }\n  }\n\n  // No custom VM fault handler registered or it failed.\n  if (custom_handler_status != HSA_STATUS_SUCCESS) {\n    if (runtime_singleton_->flag().enable_vm_fault_message()) {\n      std::string reason = \"\";\n      if (fault.Failure.NotPresent == 1) {\n        reason += \"Page not present or supervisor privilege\";\n      } else if (fault.Failure.ReadOnly == 1) {\n        reason += \"Write access to a read-only page\";\n      } else if (fault.Failure.NoExecute == 1) {\n        reason += \"Execute access to a page marked NX\";\n      } else if (fault.Failure.GpuAccess == 1) {\n        reason += \"Host access only\";\n      } else if ((fault.Failure.ECC == 1 && fault.Failure.ErrorType == 0) ||\n                 fault.Failure.ErrorType == 2) {\n        reason += \"DRAM ECC failure\";\n      } else if (fault.Failure.ErrorType == 1) {\n        reason += \"SRAM ECC failure\";\n      } else if (fault.Failure.ErrorType == 3) {\n        reason += \"Generic hang recovery\";\n      } else {\n        reason += \"Unknown\";\n      }\n\n      faulty_agent = runtime_singleton_->agents_by_node_[fault.NodeId][0];\n\n      fprintf(\n          stderr,\n          \"Memory access fault by GPU node-%u (Agent handle: %p) on address %p%s. Reason: %s.\\n\",\n          fault.NodeId, reinterpret_cast<void*>(faulty_agent->public_handle().handle),\n          reinterpret_cast<const void*>(fault.VirtualAddress),\n          (fault.Failure.Imprecise == 1) ? \"(may not be exact address)\" : \"\", reason.c_str());\n\n#ifndef NDEBUG\n      PrintMemoryMapNear(reinterpret_cast<void*>(fault.VirtualAddress));\n#endif\n    }\n    // Fallback if KFD does not support GPU core dump. In this case, there core dump is\n    // generated by hsa-runtime.\n    if (faulty_agent &&\n        faulty_agent->supported_isas()[0]->GetMajorVersion() != 11 &&\n                      !runtime_singleton_->KfdVersion().supports_core_dump) {\n\n      if (pcs::PcsRuntime::instance()->SessionsActive())\n        fprintf(stderr, \"GPU core dump skipped because PC Sampling active\\n\");\n      else if (amd::coredump::dump_gpu_core())\n        fprintf(stderr, \"GPU core dump failed\\n\");\n    }\n    assert(false && \"GPU memory access fault.\");\n    std::abort();\n  }\n  // No need to keep the signal because we are done.\n  return false;\n}\n\nvoid Runtime::PrintMemoryMapNear(void* ptr) {\n  runtime_singleton_->memory_lock_.Acquire();\n  auto it = runtime_singleton_->allocation_map_.upper_bound(ptr);\n  for (int i = 0; i < 2; i++) {\n    if (it != runtime_singleton_->allocation_map_.begin()) it--;\n  }\n  fprintf(stderr, \"Nearby memory map:\\n\");\n  auto start = it;\n  for (int i = 0; i < 3; i++) {\n    if (it == runtime_singleton_->allocation_map_.end()) break;\n    std::string kind = \"Non-HSA\";\n    if (it->second.region != nullptr) {\n      const AMD::MemoryRegion* region = static_cast<const AMD::MemoryRegion*>(it->second.region);\n      if (region->IsSystem())\n        kind = \"System\";\n      else if (region->IsLocalMemory())\n        kind = \"VRAM\";\n      else if (region->IsScratch())\n        kind = \"Scratch\";\n      else if (region->IsLDS())\n        kind = \"LDS\";\n    }\n    fprintf(stderr, \"%p, 0x%lx, %s\\n\", it->first, it->second.size, kind.c_str());\n    it++;\n  }\n  fprintf(stderr, \"\\n\");\n  it = start;\n  runtime_singleton_->memory_lock_.Release();\n  hsa_amd_pointer_info_t info = {};\n  PtrInfoBlockData block = {};\n  uint32_t count = 0;\n  hsa_agent_t* canAccess = nullptr;\n  info.size = sizeof(info);\n  for (int i = 0; i < 3; i++) {\n    if (it == runtime_singleton_->allocation_map_.end()) break;\n    hsa_status_t err = runtime_singleton_->PtrInfo(const_cast<void*>(it->first), &info, malloc,\n                                                   &count, &canAccess, &block);\n    if (err == HSA_STATUS_SUCCESS) {\n      fprintf(stderr, \"PtrInfo:\\n\\tAddress: %p-%p/%p-%p\\n\\tSize: 0x%lx\\n\\tType: %u\\n\\tOwner: %p\\n\",\n              info.agentBaseAddress, (char*)info.agentBaseAddress + info.sizeInBytes,\n              info.hostBaseAddress, (char*)info.hostBaseAddress + info.sizeInBytes, info.sizeInBytes,\n              info.type, reinterpret_cast<void*>(info.agentOwner.handle));\n      fprintf(stderr, \"\\tCanAccess: %u\\n\", count);\n      for (int t = 0; t < count; t++)\n        fprintf(stderr, \"\\t\\t%p\\n\", reinterpret_cast<void*>(canAccess[t].handle));\n      fprintf(stderr, \"\\tIn block: %p, 0x%lx\\n\", block.base, block.length);\n      free(canAccess);\n    }\n    it++;\n  }\n}\n\nRuntime::Runtime()\n    : loader_(nullptr),\n      region_gpu_(nullptr),\n      sys_clock_freq_(0),\n      num_nodes_(0),\n      vm_fault_event_(nullptr),\n      vm_fault_signal_(nullptr),\n      hw_exception_event_(nullptr),\n      hw_exception_signal_(nullptr),\n      internal_queue_create_notifier_user_data_(nullptr),\n      ref_count_(0),\n      kfd_version{},\n      ipc_sock_server_fd_(0) {\n\n  virtual_mem_api_supported_ = false;\n  ipc_dmabuf_supported_ = false;\n  xnack_enabled_ = false;\n  asyncSignals_.monitor_exceptions = false;\n  asyncExceptions_.monitor_exceptions = true;\n  g_use_interrupt_wait = true;\n  g_use_mwaitx = true;\n  ::_amdgpu_r_debug = {11,\n                     nullptr,\n                     reinterpret_cast<uintptr_t>(\n                                &_loader_debug_state),\n                     r_debug::RT_CONSISTENT,\n                     0};\n\n  log_file = stderr;\n}\n\nhsa_status_t Runtime::Load() {\n  os::cpuid_t cpuinfo;\n\n  // Assume features are not supported if parse CPUID fails\n  if (!os::ParseCpuID(&cpuinfo)) {\n    /*\n     * This is not a failure, in some environments such as SRIOV, not all CPUID info is\n     * exposed inside the guest\n     */\n    debug_warning(\"Parsing CPUID failed.\");\n  }\n\n  flag_.Refresh();\n\n  thunkLoader_ = new ThunkLoader();\n  thunkLoader_->LoadThunkApiTable();\n\n  if (!thunkLoader_->CreateThunkInstance()) {\n    return HSA_STATUS_ERROR_NOT_INITIALIZED;\n  }\n\n  g_use_interrupt_wait = flag_.enable_interrupt();\n  g_use_mwaitx = flag_.check_mwaitx(cpuinfo.mwaitx);\n\n  if (!AMD::Load()) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  // Setup system clock frequency for the first time.\n  if (sys_clock_freq_ == 0) {\n    sys_clock_freq_ = os::SystemClockFrequency();\n    if (sys_clock_freq_ < 100000) debug_warning(\"System clock resolution is low.\");\n  }\n\n  BindErrorHandlers();\n\n  loader_ = amd::hsa::loader::Loader::Create(&loader_context_);\n\n  // Load extensions\n  LoadExtensions();\n\n  // Initialize per GPU scratch, blits, and trap handler\n  for (core::Agent* agent : gpu_agents_) {\n    hsa_status_t status =\n        reinterpret_cast<AMD::GpuAgentInt*>(agent)->PostToolsInit();\n\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  // Load tools libraries\n  LoadTools();\n\n  // Initialize libdrm helper function\n  CheckVirtualMemApiSupport();\n\n  // Initialize IPC support mode\n  InitIPCDmaBufSupport();\n\n  // Load svm profiler\n  svm_profile_.reset(new AMD::SvmProfileControl);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid Runtime::Unload() {\n  // Close IPC socket server\n  if (ipc_sock_server_conns_.size())\n    IPCClientImport(getpid(), IPC_SOCK_SERVER_CONN_CLOSE_HANDLE,\n                    NULL, 0, NULL, NULL, NULL);\n\n  svm_profile_.reset(nullptr);\n\n  UnloadTools();\n  UnloadExtensions();\n\n  amd::hsa::loader::Loader::Destroy(loader_);\n  loader_ = nullptr;\n\n  for(auto nodeAgent: agents_by_node_) {\n    for (auto agent: nodeAgent.second)\n      agent->ReleaseResources();\n  }\n\n  asyncSignals_.control.Shutdown();\n  asyncExceptions_.control.Shutdown();\n\n  if (vm_fault_signal_ != nullptr) {\n    vm_fault_signal_->DestroySignal();\n    vm_fault_signal_ = nullptr;\n  }\n  core::InterruptSignal::DestroyEvent(vm_fault_event_);\n  vm_fault_event_ = nullptr;\n\n  if (hw_exception_signal_ != nullptr) {\n    hw_exception_signal_->DestroySignal();\n    hw_exception_signal_ = nullptr;\n  }\n  core::InterruptSignal::DestroyEvent(hw_exception_event_);\n  hw_exception_event_ = nullptr;\n\n  SharedSignalPool.clear();\n\n  EventPool.clear();\n\n  mapped_handle_map_.clear();\n  memory_handle_map_.clear();\n\n  DestroyAgents();\n\n  CloseTools();\n\n  AMD::Unload();\n\n  DestroyDrivers();\n\n  thunkLoader_->DestroyThunkInstance();\n\n  delete thunkLoader_;\n}\n\nvoid Runtime::LoadExtensions() {\n// Load finalizer and extension library\n#ifdef HSA_LARGE_MODEL\n  static const std::string kFinalizerLib[] = {\"hsa-ext-finalize64.dll\",\n                                              \"libhsa-ext-finalize64.so.1\"};\n#else\n  static const std::string kFinalizerLib[] = {\"hsa-ext-finalize.dll\",\n                                              \"libhsa-ext-finalize.so.1\"};\n#endif\n\n  // Update Hsa Api Table with handle of Finalizer extension Apis\n  // Skipping finalizer loading since finalizer is no longer distributed.\n  // LinkExts will expose the finalizer-not-present implementation.\n  // extensions_.LoadFinalizer(kFinalizerLib[os_index(os::current_os)]);\n  hsa_api_table().LinkExts(&extensions_.finalizer_api,\n                          core::HsaApiTable::HSA_EXT_FINALIZER_API_TABLE_ID);\n\n  // Update Hsa Api Table with handle of Image extension Apis\n  extensions_.LoadImage();\n  hsa_api_table().LinkExts(&extensions_.image_api,\n                          core::HsaApiTable::HSA_EXT_IMAGE_API_TABLE_ID);\n\n  // Update Hsa Api Table with handle of PCS extension Apis\n  extensions_.LoadPcSampling();\n  hsa_api_table().LinkExts(&extensions_.pcs_api,\n                          core::HsaApiTable::HSA_EXT_PC_SAMPLING_API_TABLE_ID);\n}\n\nvoid Runtime::UnloadExtensions() { extensions_.Unload(); }\n\nstatic std::vector<std::string> parse_tool_names(std::string tool_names) {\n  std::vector<std::string> names;\n  std::string name = \"\";\n  bool quoted = false;\n  while (tool_names.size() != 0) {\n    auto index = tool_names.find_first_of(\" \\\"\\\\\");\n    if (index == std::string::npos) {\n      name += tool_names;\n      break;\n    }\n    switch (tool_names[index]) {\n      case ' ': {\n        if (!quoted) {\n          name += tool_names.substr(0, index);\n          tool_names.erase(0, index + 1);\n          names.push_back(name);\n          name = \"\";\n        } else {\n          name += tool_names.substr(0, index + 1);\n          tool_names.erase(0, index + 1);\n        }\n        break;\n      }\n      case '\\\"': {\n        if (quoted) {\n          quoted = false;\n          name += tool_names.substr(0, index);\n          tool_names.erase(0, index + 1);\n          names.push_back(name);\n          name = \"\";\n        } else {\n          quoted = true;\n          tool_names.erase(0, index + 1);\n        }\n        break;\n      }\n      case '\\\\': {\n        if (tool_names.size() > index + 1) {\n          name += tool_names.substr(0, index) + tool_names[index + 1];\n          tool_names.erase(0, index + 2);\n        }\n        break;\n      }\n    }  // end switch\n  }    // end while\n\n  if (name != \"\") names.push_back(name);\n  return names;\n}\n\n\nstatic int (*fn_amdgpu_device_get_fd)(HsaAMDGPUDeviceHandle device_handle) = NULL;\n\nint fn_amdgpu_device_get_fd_nosupport(HsaAMDGPUDeviceHandle device_handle) {\n  fprintf(stderr, \"amdgpu_device_get_fd not available. Please update version of libdrm\");\n  return -1;\n}\n\nint Runtime::GetAmdgpuDeviceArgs(Agent *agent, ShareableHandle handle,\n                                 int *drm_fd, uint64_t *cpu_addr) {\n  int renderFd = fn_amdgpu_device_get_fd(static_cast<AMD::GpuAgent*>(agent)->libDrmDev());\n  if (renderFd < 0) return HSA_STATUS_ERROR;\n\n  uint32_t gem_handle = 0;\n  if (DRM_CALL(amdgpu_bo_export(reinterpret_cast<amdgpu_bo_handle>(handle.handle),\n                       amdgpu_bo_handle_type_kms, &gem_handle)))\n    return HSA_STATUS_ERROR;\n\n  union drm_amdgpu_gem_mmap args;\n  memset(&args, 0, sizeof(args));\n  /* Query the buffer address (args.addr_ptr).\n   * The kernel driver ignores the offset and size parameters. */\n  args.in.handle = gem_handle;\n  if (DRM_CALL(drmCommandWriteRead(renderFd, DRM_AMDGPU_GEM_MMAP, &args, sizeof(args))))\n    return HSA_STATUS_ERROR;\n\n  *drm_fd = renderFd;\n  *cpu_addr = args.out.addr_ptr;\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid Runtime::CheckVirtualMemApiSupport() {\n\n  auto kfd_version = core::Runtime::runtime_singleton_->KfdVersion().version;\n\n  if (kfd_version.KernelInterfaceMajorVersion > 1 ||\n      (kfd_version.KernelInterfaceMajorVersion == 1 &&\n          kfd_version.KernelInterfaceMinorVersion >= 15)) {\n    char* error;\n\n    fn_amdgpu_device_get_fd =\n        (int (*)(HsaAMDGPUDeviceHandle device_handle))dlsym(RTLD_DEFAULT, \"amdgpu_device_get_fd\");\n    if ((error = dlerror()) != NULL) {\n      debug_warning(\"amdgpu_device_get_fd not available. Please update version of libdrm\");\n      fn_amdgpu_device_get_fd = &fn_amdgpu_device_get_fd_nosupport;\n    } else {\n      virtual_mem_api_supported_ = true;\n    }\n  }\n}\n\nvoid Runtime::InitIPCDmaBufSupport() {\n  bool dmabuf_supported = false;\n\n  // Early exit so we don't double load lib DRM\n  if (virtual_mem_api_supported_) {\n    ipc_dmabuf_supported_ = !flag().enable_ipc_mode_legacy();\n    return;\n  }\n\n  GetSystemInfo(HSA_AMD_SYSTEM_INFO_DMABUF_SUPPORTED, &dmabuf_supported);\n  if (!dmabuf_supported) return;\n\n  char* error;\n  fn_amdgpu_device_get_fd =\n      (int (*)(HsaAMDGPUDeviceHandle device_handle))dlsym(RTLD_DEFAULT, \"amdgpu_device_get_fd\");\n  if ((error = dlerror()) != NULL) {\n    debug_warning(\"amdgpu_device_get_fd not available. Please update version of libdrm\");\n    fn_amdgpu_device_get_fd = &fn_amdgpu_device_get_fd_nosupport;\n  } else {\n    ipc_dmabuf_supported_ = !flag().enable_ipc_mode_legacy();\n  }\n}\n\nvoid Runtime::LoadTools() {\n  typedef bool (*tool_init_t)(::HsaApiTable*, uint64_t, uint64_t,\n                              const char* const*);\n  typedef Agent* (*tool_wrap_t)(Agent*);\n  typedef void (*tool_add_t)(Runtime*);\n\n#if defined(HSA_ROCPROFILER_REGISTER) && HSA_ROCPROFILER_REGISTER > 0\n  if (!flag().disable_tool_register()) {\n    auto* profiler_api_table_ = static_cast<void*>(&hsa_api_table());\n    auto lib_id = rocprofiler_register_library_indentifier_t{};\n    auto rocp_reg_status =\n        rocprofiler_register_library_api_table(\"hsa\", &ROCPROFILER_REGISTER_IMPORT_FUNC(hsa),\n                                               ROCP_REG_VERSION, &profiler_api_table_, 1, &lib_id);\n\n    if (rocp_reg_status != ROCP_REG_SUCCESS && flag().report_tool_register_failures()) {\n      fprintf(stderr, \"[hsa-runtime][%i] rocprofiler-register returned status code %i: %s\\n\",\n              getpid(), rocp_reg_status, rocprofiler_register_error_string(rocp_reg_status));\n    }\n\n    bool allow_v1_registration = false;\n    if (os::IsEnvVarSet(\"HSA_TOOLS_ROCPROFILER_V1_TOOLS\")) {\n      // assume true if env variable is set\n      allow_v1_registration = true;\n      auto allow_v1_value = os::GetEnvVar(\"HSA_TOOLS_ROCPROFILER_V1_TOOLS\");\n      // support using numbers, off, false, no, n, or f\n      if (!allow_v1_value.empty()) {\n        if (allow_v1_value.find_first_not_of(\"0123456789\") == std::string::npos) {\n          allow_v1_registration = (std::stoi(allow_v1_value) != 0);\n        } else if (std::regex_match(\n                       allow_v1_value,\n                       std::regex{\"^(off|false|no|n|f)$\", std::regex_constants::icase})) {\n          allow_v1_registration = false;\n        }\n      }\n    }\n\n    // if rocprofiler library supports registration and v1 support not explicitly requested,\n    // do not use old method\n    if (rocp_reg_status == ROCP_REG_SUCCESS && !allow_v1_registration) return;\n  }\n#endif\n\n  std::vector<const char*> failed;\n\n  //Get loaded libs and filter to tool libraries.\n  struct lib_t {\n    lib_t(os::LibHandle lib, uint32_t order, std::string name) : lib_(lib), order_(order), name_(name) {}\n    os::LibHandle lib_;\n    uint32_t order_;\n    std::string name_;\n  };\n\n  std::list<lib_t> sorted;\n  uint32_t env_count=0;\n\n  // Load env var tool lib names and determine ordering offset.\n  std::string tool_names = flag_.tools_lib_names();\n  std::vector<std::string> names;\n  if (tool_names != \"\") {\n    names = parse_tool_names(std::move(tool_names));\n    env_count = names.size();\n  }\n\n  // Discover loaded tools.\n  std::vector<os::LibHandle> loaded_hds = os::GetLoadedToolsLib();\n  for(auto& handle : loaded_hds) {\n    const uint32_t* order = (const uint32_t*)os::GetExportAddress(handle, \"HSA_AMD_TOOL_PRIORITY\");\n    if(order) {\n      sorted.push_back(lib_t(handle, *order+env_count, os::GetLibraryName(handle)));\n    } else {\n      os::CloseLib(handle);\n    }\n  }\n\n  // Load env var tools.\n  env_count=0;\n  for (auto& name : names) {\n    os::LibHandle tool = os::LoadLib(name);\n\n    if (tool != nullptr) {\n      sorted.push_back(lib_t(tool, env_count, name));\n      env_count++;\n    } else {\n      failed.push_back(name.c_str());\n      if (flag().report_tool_load_failures())\n        fprintf(stderr, \"Tool lib \\\"%s\\\" failed to load.\\n\", name.c_str());\n    }\n  }\n\n  if(!sorted.empty()) {\n    // Close duplicate handles\n    sorted.sort([](const lib_t& lhs, const lib_t& rhs) {\n      if(lhs.lib_ == rhs.lib_)\n        return lhs.order_ < rhs.order_;\n      return lhs.lib_ < rhs.lib_;\n    });\n\n    os::LibHandle current = sorted.front().lib_;\n    auto it = sorted.begin();\n    it++;\n    while(it != sorted.end()) {\n      if(it->lib_==current) {\n        os::CloseLib(current);\n        auto rem = it;\n        it = sorted.erase(rem);\n      } else {\n        current = it->lib_;\n        it++;\n      }\n    }\n\n    // Sort to load order\n    sorted.sort([](const lib_t& lhs, const lib_t& rhs) {\n      return lhs.order_ < rhs.order_;\n    });\n\n    for(auto& lib : sorted) {\n      auto& tool = lib.lib_;\n\n      rocr::AMD::callback_t<tool_init_t> ld = (tool_init_t)os::GetExportAddress(tool, \"OnLoad\");\n      if (!ld) {\n        failed.push_back(lib.name_.c_str());\n        os::CloseLib(tool);\n        continue;\n      }\n      if (!ld(&hsa_api_table().hsa_api,\n        hsa_api_table().hsa_api.version.major_id,\n        failed.size(), failed.data())) {\n          failed.push_back(lib.name_.c_str());\n          os::CloseLib(tool);\n          continue;\n      }\n      tool_libs_.push_back(tool);\n\n      rocr::AMD::callback_t<tool_wrap_t> wrap =\n        (tool_wrap_t)os::GetExportAddress(tool, \"WrapAgent\");\n      if (wrap) {\n        std::vector<core::Agent*>* agent_lists[2] = {&cpu_agents_,\n          &gpu_agents_};\n        for (std::vector<core::Agent*>* agent_list : agent_lists) {\n          for (size_t agent_idx = 0; agent_idx < agent_list->size();\n            ++agent_idx) {\n              Agent* agent = wrap(agent_list->at(agent_idx));\n              if (agent != NULL) {\n                assert(agent->IsValid() &&\n                  \"Agent returned from WrapAgent is not valid\");\n                agent_list->at(agent_idx) = agent;\n              }\n          }\n        }\n      }\n\n      rocr::AMD::callback_t<tool_add_t> add = (tool_add_t)os::GetExportAddress(tool, \"AddAgent\");\n      if (add) add(this);\n    }\n  }\n}\n\nvoid Runtime::UnloadTools() {\n  typedef void (*tool_unload_t)();\n  for (size_t i = tool_libs_.size(); i != 0; i--) {\n    tool_unload_t unld;\n    unld = (tool_unload_t)os::GetExportAddress(tool_libs_[i - 1], \"OnUnload\");\n    if (unld) unld();\n  }\n\n  // Reset API table in case some tool doesn't cleanup properly\n  hsa_api_table().Reset();\n}\n\nvoid Runtime::CloseTools() {\n  // Due to valgrind bug, runtime cannot dlclose extensions see:\n  // http://valgrind.org/docs/manual/faq.html#faq.unhelpful\n  if (!flag_.running_valgrind()) {\n    for (auto& lib : tool_libs_) os::CloseLib(lib);\n  }\n  tool_libs_.clear();\n}\n\nvoid Runtime::AsyncEventsControl::Shutdown() {\n  if (async_events_thread_ != NULL) {\n    exit = true;\n    hsa_signal_handle(wake)->StoreRelaxed(1);\n    os::WaitForThread(async_events_thread_);\n    os::CloseThread(async_events_thread_);\n    async_events_thread_ = NULL;\n    HSA::hsa_signal_destroy(wake);\n  }\n}\n\nvoid Runtime::AsyncEvents::PushBack(hsa_signal_t signal,\n                                    hsa_signal_condition_t cond,\n                                    hsa_signal_value_t value,\n                                    hsa_amd_signal_handler handler, void* arg) {\n  signal_.push_back(signal);\n  cond_.push_back(cond);\n  value_.push_back(value);\n  handler_.push_back(handler);\n  arg_.push_back(arg);\n}\n\nvoid Runtime::AsyncEvents::CopyIndex(size_t dst, size_t src) {\n  signal_[dst] = signal_[src];\n  cond_[dst] = cond_[src];\n  value_[dst] = value_[src];\n  handler_[dst] = handler_[src];\n  arg_[dst] = arg_[src];\n}\n\nsize_t Runtime::AsyncEvents::Size() { return signal_.size(); }\n\nvoid Runtime::AsyncEvents::PopBack() {\n  signal_.pop_back();\n  cond_.pop_back();\n  value_.pop_back();\n  handler_.pop_back();\n  arg_.pop_back();\n}\n\nvoid Runtime::AsyncEvents::Clear() {\n  signal_.clear();\n  cond_.clear();\n  value_.clear();\n  handler_.clear();\n  arg_.clear();\n}\n\nhsa_status_t Runtime::SetCustomSystemEventHandler(hsa_amd_system_event_callback_t callback,\n                                                  void* data) {\n  ScopedAcquire<KernelMutex> lock(&system_event_lock_);\n  system_event_handlers_.push_back(\n      std::make_pair(AMD::callback_t<hsa_amd_system_event_callback_t>(callback), data));\n  return HSA_STATUS_SUCCESS;\n}\n\nstd::vector<std::pair<AMD::callback_t<hsa_amd_system_event_callback_t>, void*>>\nRuntime::GetSystemEventHandlers() {\n  ScopedAcquire<KernelMutex> lock(&system_event_lock_);\n  return system_event_handlers_;\n}\n\nhsa_status_t Runtime::SetInternalQueueCreateNotifier(hsa_amd_runtime_queue_notifier callback,\n                                                     void* user_data) {\n  if (internal_queue_create_notifier_) {\n    return HSA_STATUS_ERROR;\n  } else {\n    internal_queue_create_notifier_ = callback;\n    internal_queue_create_notifier_user_data_ = user_data;\n    return HSA_STATUS_SUCCESS;\n  }\n}\n\nvoid Runtime::InternalQueueCreateNotify(const hsa_queue_t* queue, hsa_agent_t agent) {\n  if (internal_queue_create_notifier_)\n    internal_queue_create_notifier_(queue, agent, internal_queue_create_notifier_user_data_);\n}\n\nhsa_status_t Runtime::SetSvmAttrib(void* ptr, size_t size,\n                                   hsa_amd_svm_attribute_pair_t* attribute_list,\n                                   size_t attribute_count) {\n  uint32_t set_attribs = 0;\n  std::vector<bool> agent_seen(max_node_id() + 1, false);\n\n  std::vector<HSA_SVM_ATTRIBUTE> attribs;\n  attribs.reserve(attribute_count);\n  uint32_t set_flags = 0;\n  uint32_t clear_flags = 0;\n\n  auto Convert = [&](uint64_t value) -> Agent* {\n    hsa_agent_t handle = {value};\n    Agent* agent = Agent::Convert(handle);\n    if ((agent == nullptr) || !agent->IsValid())\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_AGENT,\n                               \"Invalid agent handle in Runtime::SetSvmAttrib.\");\n    return agent;\n  };\n\n  auto ConvertAllowNull = [&](uint64_t value) -> Agent* {\n    hsa_agent_t handle = {value};\n    Agent* agent = Agent::Convert(handle);\n    if ((agent != nullptr) && (!agent->IsValid()))\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_AGENT,\n                               \"Invalid agent handle in Runtime::SetSvmAttrib.\");\n    return agent;\n  };\n\n  auto ConfirmNew = [&](Agent* agent) {\n    if (agent_seen[agent->node_id()])\n      throw AMD::hsa_exception(\n          HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS,\n          \"Multiple attributes given for the same agent in Runtime::SetSvmAttrib.\");\n    agent_seen[agent->node_id()] = true;\n  };\n\n  auto Check = [&](uint64_t attrib) {\n    if (set_attribs & (1 << attrib))\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS,\n                               \"Attribute given multiple times in Runtime::SetSvmAttrib.\");\n    set_attribs |= (1 << attrib);\n  };\n\n  auto kmtPair = [](uint32_t attrib, uint32_t value) {\n    HSA_SVM_ATTRIBUTE pair = {attrib, value};\n    return pair;\n  };\n\n  for (uint32_t i = 0; i < attribute_count; i++) {\n    auto attrib = attribute_list[i].attribute;\n    auto value = attribute_list[i].value;\n\n    switch (attrib) {\n      case HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG: {\n        Check(attrib);\n        switch (value) {\n          case HSA_AMD_SVM_GLOBAL_FLAG_FINE_GRAINED:\n            set_flags |= HSA_SVM_FLAG_COHERENT;\n            break;\n          case HSA_AMD_SVM_GLOBAL_FLAG_COARSE_GRAINED:\n            clear_flags |= HSA_SVM_FLAG_COHERENT;\n            break;\n          default:\n            throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                                     \"Invalid HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG value.\");\n        }\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_READ_ONLY: {\n        Check(attrib);\n        if (value)\n          set_flags |= HSA_SVM_FLAG_GPU_RO;\n        else\n          clear_flags |= HSA_SVM_FLAG_GPU_RO;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_HIVE_LOCAL: {\n        Check(attrib);\n        if (value)\n          set_flags |= HSA_SVM_FLAG_HIVE_LOCAL;\n        else\n          clear_flags |= HSA_SVM_FLAG_HIVE_LOCAL;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_MIGRATION_GRANULARITY: {\n        Check(attrib);\n        // Max migration size is 1GB.\n        if (value > 18) value = 18;\n        attribs.push_back(kmtPair(HSA_SVM_ATTR_GRANULARITY, value));\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION: {\n        Check(attrib);\n        Agent* agent = ConvertAllowNull(value);\n        if (agent == nullptr)\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_PREFERRED_LOC, INVALID_NODEID));\n        else\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_PREFERRED_LOC, agent->node_id()));\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_READ_MOSTLY: {\n        Check(attrib);\n        if (value)\n          set_flags |= HSA_SVM_FLAG_GPU_READ_MOSTLY;\n        else\n          clear_flags |= HSA_SVM_FLAG_GPU_READ_MOSTLY;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_GPU_EXEC: {\n        Check(attrib);\n        if (value)\n          set_flags |= HSA_SVM_FLAG_GPU_EXEC;\n        else\n          clear_flags |= HSA_SVM_FLAG_GPU_EXEC;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE: {\n        Agent* agent = Convert(value);\n        ConfirmNew(agent);\n        if (agent->device_type() == Agent::kAmdCpuDevice) {\n          set_flags |= HSA_SVM_FLAG_HOST_ACCESS;\n        } else {\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_ACCESS, agent->node_id()));\n        }\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE: {\n        Agent* agent = Convert(value);\n        ConfirmNew(agent);\n        if (agent->device_type() == Agent::kAmdCpuDevice) {\n          set_flags |= HSA_SVM_FLAG_HOST_ACCESS;\n        } else {\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_ACCESS_IN_PLACE, agent->node_id()));\n        }\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_AGENT_NO_ACCESS: {\n        Agent* agent = Convert(value);\n        ConfirmNew(agent);\n        if (agent->device_type() == Agent::kAmdCpuDevice) {\n          clear_flags |= HSA_SVM_FLAG_HOST_ACCESS;\n        } else {\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_NO_ACCESS, agent->node_id()));\n        }\n        break;\n      }\n      default:\n        throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                                 \"Illegal or invalid attribute in Runtime::SetSvmAttrib\");\n    }\n  }\n\n  // Merge CPU access properties - grant access if any CPU needs access.\n  // Probably wrong.\n  if (set_flags & HSA_SVM_FLAG_HOST_ACCESS) clear_flags &= ~HSA_SVM_FLAG_HOST_ACCESS;\n\n  // Add flag updates\n  if (clear_flags) attribs.push_back(kmtPair(HSA_SVM_ATTR_CLR_FLAGS, clear_flags));\n  if (set_flags) attribs.push_back(kmtPair(HSA_SVM_ATTR_SET_FLAGS, set_flags));\n\n  uint8_t* base = AlignDown((uint8_t*)ptr, 4096);\n  uint8_t* end = AlignUp((uint8_t*)ptr + size, 4096);\n  size_t len = end - base;\n  HSAKMT_STATUS error = HSAKMT_CALL(hsaKmtSVMSetAttr(base, len, attribs.size(), &attribs[0]));\n  if (error != HSAKMT_STATUS_SUCCESS)\n    throw AMD::hsa_exception(HSA_STATUS_ERROR, \"hsaKmtSVMSetAttr failed.\");\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::GetSvmAttrib(void* ptr, size_t size,\n                                   hsa_amd_svm_attribute_pair_t* attribute_list,\n                                   size_t attribute_count) {\n  std::vector<HSA_SVM_ATTRIBUTE> attribs;\n  attribs.reserve(attribute_count);\n\n  std::vector<int> kmtIndices(attribute_count);\n\n  bool getFlags = false;\n\n  auto Convert = [&](uint64_t value) -> Agent* {\n    hsa_agent_t handle = {value};\n    Agent* agent = Agent::Convert(handle);\n    if ((agent == nullptr) || !agent->IsValid())\n      throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_AGENT,\n                               \"Invalid agent handle in Runtime::GetSvmAttrib.\");\n    return agent;\n  };\n\n  auto kmtPair = [](uint32_t attrib, uint32_t value) {\n    HSA_SVM_ATTRIBUTE pair = {attrib, value};\n    return pair;\n  };\n\n  for (uint32_t i = 0; i < attribute_count; i++) {\n    auto& attrib = attribute_list[i].attribute;\n    auto& value = attribute_list[i].value;\n\n    switch (attrib) {\n      case HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG:\n      case HSA_AMD_SVM_ATTRIB_READ_ONLY:\n      case HSA_AMD_SVM_ATTRIB_HIVE_LOCAL:\n      case HSA_AMD_SVM_ATTRIB_READ_MOSTLY: {\n        getFlags = true;\n        kmtIndices[i] = -1;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_MIGRATION_GRANULARITY: {\n        kmtIndices[i] = attribs.size();\n        attribs.push_back(kmtPair(HSA_SVM_ATTR_GRANULARITY, 0));\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION: {\n        kmtIndices[i] = attribs.size();\n        attribs.push_back(kmtPair(HSA_SVM_ATTR_PREFERRED_LOC, 0));\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION: {\n        value = Agent::Convert(GetSVMPrefetchAgent(ptr, size)).handle;\n        kmtIndices[i] = -1;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_ACCESS_QUERY: {\n        Agent* agent = Convert(value);\n        if (agent->device_type() == Agent::kAmdCpuDevice) {\n          getFlags = true;\n          kmtIndices[i] = -1;\n        } else {\n          kmtIndices[i] = attribs.size();\n          attribs.push_back(kmtPair(HSA_SVM_ATTR_ACCESS, agent->node_id()));\n        }\n        break;\n      }\n      default:\n        throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                                 \"Illegal or invalid attribute in Runtime::SetSvmAttrib\");\n    }\n  }\n\n  if (getFlags) {\n    // Order is important to later code.\n    attribs.push_back(kmtPair(HSA_SVM_ATTR_CLR_FLAGS, 0));\n    attribs.push_back(kmtPair(HSA_SVM_ATTR_SET_FLAGS, 0));\n  }\n\n  uint8_t* base = AlignDown((uint8_t*)ptr, 4096);\n  uint8_t* end = AlignUp((uint8_t*)ptr + size, 4096);\n  size_t len = end - base;\n  if (attribs.size() != 0) {\n    HSAKMT_STATUS error = HSAKMT_CALL(hsaKmtSVMGetAttr(base, len, attribs.size(), &attribs[0]));\n    if (error != HSAKMT_STATUS_SUCCESS)\n      throw AMD::hsa_exception(HSA_STATUS_ERROR, \"hsaKmtSVMGetAttr failed.\");\n  }\n\n  for (uint32_t i = 0; i < attribute_count; i++) {\n    auto& attrib = attribute_list[i].attribute;\n    auto& value = attribute_list[i].value;\n\n    switch (attrib) {\n      case HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG: {\n        if (attribs[attribs.size() - 1].value & HSA_SVM_FLAG_COHERENT) {\n          value = HSA_AMD_SVM_GLOBAL_FLAG_FINE_GRAINED;\n          break;\n        }\n        if (attribs[attribs.size() - 2].value & HSA_SVM_FLAG_COHERENT)\n          value = HSA_AMD_SVM_GLOBAL_FLAG_COARSE_GRAINED;\n        else\n          value = HSA_AMD_SVM_GLOBAL_FLAG_INDETERMINATE;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_READ_ONLY: {\n        value = (attribs[attribs.size() - 1].value & HSA_SVM_FLAG_GPU_RO);\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_HIVE_LOCAL: {\n        value = (attribs[attribs.size() - 1].value & HSA_SVM_FLAG_HIVE_LOCAL);\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_MIGRATION_GRANULARITY: {\n        value = attribs[kmtIndices[i]].value;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION: {\n        uint64_t node = attribs[kmtIndices[i]].value;\n        Agent* agent = nullptr;\n        if (node != INVALID_NODEID) agent = agents_by_node_[node][0];\n        value = Agent::Convert(agent).handle;\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION: {\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_READ_MOSTLY: {\n        value = (attribs[attribs.size() - 1].value & HSA_SVM_FLAG_GPU_READ_MOSTLY);\n        break;\n      }\n      case HSA_AMD_SVM_ATTRIB_ACCESS_QUERY: {\n        if (kmtIndices[i] == -1) {\n          if (attribs[attribs.size() - 1].value & HSA_SVM_FLAG_HOST_ACCESS)\n            attrib = HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE;\n        } else {\n          switch (attribs[kmtIndices[i]].type) {\n            case HSA_SVM_ATTR_ACCESS:\n              attrib = HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE;\n              break;\n            case HSA_SVM_ATTR_ACCESS_IN_PLACE:\n              attrib = HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE;\n              break;\n            case HSA_SVM_ATTR_NO_ACCESS:\n              attrib = HSA_AMD_SVM_ATTRIB_AGENT_NO_ACCESS;\n              break;\n            default:\n              assert(false && \"Bad agent accessibility from KFD.\");\n          }\n        }\n        break;\n      }\n      default:\n        throw AMD::hsa_exception(HSA_STATUS_ERROR_INVALID_ARGUMENT,\n                                 \"Illegal or invalid attribute in Runtime::GetSvmAttrib\");\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::SvmPrefetch(void* ptr, size_t size, hsa_agent_t agent,\n                                  uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                  hsa_signal_t completion_signal) {\n  uintptr_t base = reinterpret_cast<uintptr_t>(AlignDown(ptr, 4096));\n  uintptr_t end = AlignUp(reinterpret_cast<uintptr_t>(ptr) + size, 4096);\n  size_t len = end - base;\n\n  PrefetchOp* op = new PrefetchOp();\n  MAKE_NAMED_SCOPE_GUARD(OpGuard, [&]() { delete op; });\n\n  Agent* dest = Agent::Convert(agent);\n  if (dest->device_type() == Agent::kAmdCpuDevice)\n    op->node_id = 0;\n  else\n    op->node_id = dest->node_id();\n\n  op->base = reinterpret_cast<void*>(base);\n  op->size = len;\n  op->completion = completion_signal;\n  if (num_dep_signals > 1) {\n    op->remaining_deps = num_dep_signals - 1;\n    for (int i = 0; i < num_dep_signals - 1; i++) op->dep_signals.push_back(dep_signals[i]);\n  } else {\n    op->remaining_deps = 0;\n  }\n\n  {\n    ScopedAcquire<KernelMutex> lock(&prefetch_lock_);\n    // Remove all fully overlapped and trim partially overlapped ranges.\n    // Get iteration bounds\n    auto start = prefetch_map_.upper_bound(base);\n    if (start != prefetch_map_.begin()) start--;\n    auto stop = prefetch_map_.lower_bound(end);\n\n    auto isEndNode = [&](decltype(start) node) { return node->second.next == prefetch_map_.end(); };\n    auto isFirstNode = [&](decltype(start) node) {\n      return node->second.prev == prefetch_map_.end();\n    };\n\n    // Trim and remove old ranges.\n    while (start != stop) {\n      uintptr_t startBase = start->first;\n      uintptr_t startEnd = startBase + start->second.bytes;\n\n      auto ibase = Max(startBase, base);\n      auto iend = Min(startEnd, end);\n      // Check for overlap\n      if (ibase < iend) {\n        // Second range check\n        if (iend < startEnd) {\n          auto ret = prefetch_map_.insert(\n              std::make_pair(iend, PrefetchRange(startEnd - iend, start->second.op)));\n          assert(ret.second && \"Prefetch map insert failed during range split.\");\n\n          auto it = ret.first;\n          it->second.prev = start;\n          it->second.next = start->second.next;\n          start->second.next = it;\n          if (!isEndNode(it)) it->second.next->second.prev = it;\n        }\n\n        // Is the first interval of the old range valid\n        if (startBase < ibase) {\n          start->second.bytes = ibase - startBase;\n        } else {\n          if (isFirstNode(start)) {\n            start->second.op->prefetch_map_entry = start->second.next;\n            if (!isEndNode(start)) start->second.next->second.prev = prefetch_map_.end();\n          } else {\n            start->second.prev->second.next = start->second.next;\n            if (!isEndNode(start)) start->second.next->second.prev = start->second.prev;\n          }\n          start = prefetch_map_.erase(start);\n          continue;\n        }\n      }\n      start++;\n    }\n\n    // Insert new range.\n    auto ret = prefetch_map_.insert(std::make_pair(base, PrefetchRange(len, op)));\n    assert(ret.second && \"Prefetch map insert failed.\");\n\n    auto it = ret.first;\n    op->prefetch_map_entry = it;\n    it->second.next = it->second.prev = prefetch_map_.end();\n  }\n\n  // Remove the prefetch's ranges from the map.\n  static auto removePrefetchRanges = [](PrefetchOp* op) {\n    ScopedAcquire<KernelMutex> lock(&Runtime::runtime_singleton_->prefetch_lock_);\n    auto it = op->prefetch_map_entry;\n    while (it != Runtime::runtime_singleton_->prefetch_map_.end()) {\n      auto next = it->second.next;\n      Runtime::runtime_singleton_->prefetch_map_.erase(it);\n      it = next;\n    }\n  };\n\n  // Prefetch Signal handler for synchronization.\n  static hsa_amd_signal_handler signal_handler = [](hsa_signal_value_t value, void* arg) {\n    PrefetchOp* op = reinterpret_cast<PrefetchOp*>(arg);\n\n    if (op->remaining_deps > 0) {\n      op->remaining_deps--;\n      Runtime::runtime_singleton_->SetAsyncSignalHandler(\n          op->dep_signals[op->remaining_deps], HSA_SIGNAL_CONDITION_EQ, 0, signal_handler, arg);\n      return false;\n    }\n\n    HSA_SVM_ATTRIBUTE attrib;\n    attrib.type = HSA_SVM_ATTR_PREFETCH_LOC;\n    attrib.value = op->node_id;\n    HSAKMT_STATUS error = HSAKMT_CALL(hsaKmtSVMSetAttr(op->base, op->size, 1, &attrib));\n    assert(error == HSAKMT_STATUS_SUCCESS && \"KFD Prefetch failed.\");\n\n    removePrefetchRanges(op);\n\n    if (op->completion.handle != 0) Signal::Convert(op->completion)->SubRelaxed(1);\n    delete op;\n\n    return false;\n  };\n\n  auto no_dependencies = [](void* arg) { signal_handler(0, arg); };\n\n  MAKE_NAMED_SCOPE_GUARD(RangeGuard, [&]() { removePrefetchRanges(op); });\n\n  hsa_status_t err;\n  if (num_dep_signals == 0)\n    err = AMD::hsa_amd_async_function(no_dependencies, op);\n  else\n    err = SetAsyncSignalHandler(dep_signals[num_dep_signals - 1], HSA_SIGNAL_CONDITION_EQ, 0,\n                                signal_handler, op);\n  if (err != HSA_STATUS_SUCCESS) throw AMD::hsa_exception(err, \"Signal handler unable to be set.\");\n\n  RangeGuard.Dismiss();\n  OpGuard.Dismiss();\n  return HSA_STATUS_SUCCESS;\n}\n\nAgent* Runtime::GetSVMPrefetchAgent(void* ptr, size_t size) {\n  uintptr_t base = reinterpret_cast<uintptr_t>(AlignDown(ptr, 4096));\n  uintptr_t end = AlignUp(reinterpret_cast<uintptr_t>(ptr) + size, 4096);\n\n  std::vector<std::pair<uintptr_t, uintptr_t>> holes;\n\n  ScopedAcquire<KernelMutex> lock(&Runtime::runtime_singleton_->prefetch_lock_);\n  auto start = prefetch_map_.upper_bound(base);\n  if (start != prefetch_map_.begin()) start--;\n  auto stop = prefetch_map_.lower_bound(end);\n\n  // KFD returns -1 for no or mixed destinations.\n  uint32_t prefetch_node = -2;\n  if (start != stop) {\n    prefetch_node = start->second.op->node_id;\n  }\n\n  while (start != stop) {\n    uintptr_t startBase = start->first;\n    uintptr_t startEnd = startBase + start->second.bytes;\n\n    auto ibase = Max(base, startBase);\n    auto iend = Min(end, startEnd);\n    // Check for intersection with the query\n    if (ibase < iend) {\n      // If prefetch locations are different then we report null agent.\n      if (prefetch_node != start->second.op->node_id) return nullptr;\n\n      // Push leading gap to an array for checking KFD.\n      if (base < ibase) holes.push_back(std::make_pair(base, ibase - base));\n\n      // Trim query range.\n      base = iend;\n    }\n    start++;\n  }\n  if (base < end) holes.push_back(std::make_pair(base, end - base));\n\n  HSA_SVM_ATTRIBUTE attrib;\n  attrib.type = HSA_SVM_ATTR_PREFETCH_LOC;\n  for (auto& range : holes) {\n    HSAKMT_STATUS error =\n        HSAKMT_CALL(hsaKmtSVMGetAttr(reinterpret_cast<void*>(range.first), range.second, 1, &attrib));\n    assert(error == HSAKMT_STATUS_SUCCESS && \"KFD prefetch query failed.\");\n\n    if (attrib.value == -1) return nullptr;\n    if (prefetch_node == -2) prefetch_node = attrib.value;\n    if (prefetch_node != attrib.value) return nullptr;\n  }\n\n  assert(prefetch_node != -2 && \"prefetch_node was not updated.\");\n  assert(prefetch_node != -1 && \"Should have already returned.\");\n  return agents_by_node_[prefetch_node][0];\n}\n\nhsa_status_t Runtime::DmaBufExport(const void* ptr, size_t size, int* dmabuf, uint64_t* offset,\n                                   uint64_t flags) {\n#ifdef __linux__\n  ScopedAcquire<KernelSharedMutex::Shared> lock(memory_lock_.shared());\n  // Lookup containing allocation.\n  auto mem = allocation_map_.upper_bound(ptr);\n  if (mem != allocation_map_.begin()) {\n    mem--;\n    if ((mem->first <= ptr) &&\n        (ptr < reinterpret_cast<const uint8_t*>(mem->first) + mem->second.size)) {\n      // Check size is in bounds.\n      if (uintptr_t(ptr) - uintptr_t(mem->first) + size <= mem->second.size) {\n        switch (mem->second.region->owner()->device_type()) {\n          case Agent::kAmdGpuDevice: {\n            auto* owner = static_cast<AMD::GpuAgent*>(mem->second.region->owner());\n\n            if (flags & HSA_AMD_DMABUF_MAPPING_TYPE_PCIE && !owner->is_xgmi_cpu_gpu() &&\n                !owner->LargeBarEnabled()) {\n              return static_cast<hsa_status_t>(HSA_STATUS_ERROR_NOT_SUPPORTED);\n            }\n          } break;\n          case Agent::kAmdCpuDevice:\n            return HSA_STATUS_ERROR_INVALID_AGENT;\n          case Agent::kAmdAieDevice:\n            break;\n          case Agent::kUnknownDevice:\n            return HSA_STATUS_ERROR_INVALID_AGENT;\n        }\n\n        int fd;\n        uint64_t off;\n        hsa_status_t err = mem->second.region->owner()->driver().ExportDMABuf(\n            const_cast<void*>(ptr), size, &fd, &off);\n\n        if (err != HSA_STATUS_SUCCESS) {\n          assert((err != HSA_STATUS_ERROR_INVALID_ARGUMENT) &&\n                 \"Thunk does not recognize an expected allocation.\");\n          return err;\n        }\n\n        *dmabuf = fd;\n        *offset = off;\n        return HSA_STATUS_SUCCESS;\n      }\n    }\n  }\n  return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n#else\n  return HSA_STATUS_ERROR_NOT_INITIALIZED;\n#endif\n}\n\nhsa_status_t Runtime::DmaBufClose(int dmabuf) {\n#ifdef __linux__\n  int err = close(dmabuf);\n  if (err == 0) return HSA_STATUS_SUCCESS;\n  return HSA_STATUS_ERROR_RESOURCE_FREE;\n#else\n  return HSA_STATUS_ERROR_NOT_INITIALIZED;\n#endif\n}\n\nhsa_status_t Runtime::VMemoryAddressReserve(void** va, size_t size, uint64_t address,\n                                            uint64_t alignment, uint64_t flags) {\n  void* addr = (void*)address;\n  HsaMemFlags memFlags = {};\n\n  if (!alignment)\n    alignment = sysconf(_SC_PAGE_SIZE);\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n  if (flags & HSA_AMD_VMEM_ADDRESS_NO_REGISTER) {\n    size_t requested = size + alignment - sysconf(_SC_PAGE_SIZE);\n    auto mem = mmap(addr, requested, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);\n    if (mem == MAP_FAILED)\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n    auto aligned = AlignUp(mem, alignment);\n\n    // Hint to enable THP for large host allocations which can help in performance gain\n    constexpr size_t kLargePageSize = 2*1024*1024;\n    if (size >= kLargePageSize) {\n      if (madvise(aligned, size, MADV_HUGEPAGE))\n        debug_warning(false && \"madvise with MADV_HUGEPAGE failed\");\n    }\n\n    reserved_address_map_[aligned] = AddressHandle(mem, size, false);\n    *va = aligned;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  memFlags.ui32.OnlyAddress = 1;\n  memFlags.ui32.FixedAddress = 1;\n\n  /* Try to reserving the VA requested by user */\n  if (HSAKMT_CALL(hsaKmtAllocMemoryAlign(0, size, alignment, memFlags, &addr)) != HSAKMT_STATUS_SUCCESS) {\n    memFlags.ui32.FixedAddress = 0;\n    /* Could not reserved VA requested, allocate alternate VA */\n    if (HSAKMT_CALL(hsaKmtAllocMemoryAlign(0, size, alignment, memFlags, &addr)) != HSAKMT_STATUS_SUCCESS)\n      return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  reserved_address_map_[addr] = AddressHandle(addr, size, true);\n  *va = addr;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryAddressFree(void* va, size_t size) {\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  std::map<const void*, AddressHandle>::iterator it = reserved_address_map_.find(va);\n\n  if (it == reserved_address_map_.end()) {\n    debug_warning(false && \"Can't find address in reserved address\");\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  if (size != it->second.size) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  if (it->second.use_count > 0) return HSA_STATUS_ERROR_RESOURCE_FREE;\n\n  if (it->second.registered) {\n    if (HSAKMT_CALL(hsaKmtFreeMemory(it->second.os_addr, size)) != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR;\n  } else {\n    if (munmap(it->second.os_addr, size)) return HSA_STATUS_ERROR;\n  }\n\n  reserved_address_map_.erase(it);\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryHandleCreate(const MemoryRegion* region, size_t size,\n                                          MemoryRegion::AllocateFlags alloc_flags,\n                                          uint64_t flags_unused,\n                                          hsa_amd_vmem_alloc_handle_t* memoryOnlyHandle) {\n  const AMD::MemoryRegion* memRegion = static_cast<const AMD::MemoryRegion*>(region);\n\n  if (!IsMultipleOf(size, memRegion->GetPageSize()))\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  ThunkHandle user_mode_driver_handle;\n  hsa_status_t status =\n      region->Allocate(size, alloc_flags, &user_mode_driver_handle, 0);\n  if (status == HSA_STATUS_SUCCESS) {\n    memory_handle_map_.emplace(std::piecewise_construct,\n                               std::forward_as_tuple(user_mode_driver_handle),\n                               std::forward_as_tuple(region, size, flags_unused,\n                                                     user_mode_driver_handle,\n                                                     alloc_flags));\n\n    *memoryOnlyHandle = MemoryHandle::Convert(user_mode_driver_handle);\n  }\n  return status;\n}\n\nhsa_status_t Runtime::VMemoryHandleRelease(hsa_amd_vmem_alloc_handle_t memoryOnlyHandle) {\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  auto memoryHandleIt = memory_handle_map_.find(MemoryHandle::Convert(memoryOnlyHandle));\n\n  if (memoryHandleIt == memory_handle_map_.end()) {\n    debug_warning(false && \"Can't find memory handle\");\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  if (!memoryHandleIt->second.ref_count) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  if (--(memoryHandleIt->second.ref_count) == 0) {\n    // From documentation, the handle can be released while there are still outstanding mappings. If\n    // there are outstanding mappings, then we just decrement the ref count and exit. We will free\n    // this handle when the last MappedHandle is deleted\n    // and use_count == 0 and ref_count == 0.\n\n    if (memoryHandleIt->second.use_count > 0) return HSA_STATUS_SUCCESS;\n\n    memoryHandleIt->second.region->Free(memoryHandleIt->first, memoryHandleIt->second.size);\n    memory_handle_map_.erase(memoryHandleIt);\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryHandleMap(void* va, size_t size, size_t in_offset,\n                                       hsa_amd_vmem_alloc_handle_t memoryOnlyHandle,\n                                       uint64_t flags) {\n  int drm_fd, dmabuf_fd = 0;\n  uint64_t offset = 0, ret;\n  uint64_t drm_cpu_addr = 0;\n  bool reservedAddressFound = false;\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  auto reservedAddressIt = reserved_address_map_.upper_bound(va);\n  if (reservedAddressIt != reserved_address_map_.begin()) {\n    reservedAddressIt--;\n    if ((reservedAddressIt->first <= va) &&\n        ((reinterpret_cast<uint8_t*>(va) + size) <=\n         (reinterpret_cast<const uint8_t*>(reservedAddressIt->first) + reservedAddressIt->second.size))) {\n      reservedAddressFound = true;\n    }\n  }\n  if (!reservedAddressFound) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  /* Confirm that this VA range has not been mapped yet */\n  auto upperMappedHandleIt = mapped_handle_map_.upper_bound(va);\n  if (upperMappedHandleIt != mapped_handle_map_.begin()) {\n    upperMappedHandleIt--;\n    if ((reinterpret_cast<const uint8_t*>(upperMappedHandleIt->first) + upperMappedHandleIt->second.size) > va)\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  auto lowerMappedHandleIt = mapped_handle_map_.lower_bound(va);\n  if (lowerMappedHandleIt != mapped_handle_map_.end()) {\n    if (reinterpret_cast<uint8_t*>(va) + size > lowerMappedHandleIt->first) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  auto memoryHandleIt = memory_handle_map_.find(MemoryHandle::Convert(memoryOnlyHandle));\n  if (memoryHandleIt == memory_handle_map_.end()) {\n    debug_warning(false && \"Can't find memory handle\");\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  auto *agent = memoryHandleIt->second.agentOwner();\n\n  // For now, this is only supported for KFD due to the call to\n  // GetAmdgpuDeviceArgs\n  if (agent->device_type() != core::Agent::DeviceType::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  // Create handle by exporting and importing the memory from the owning agent\n  auto &agent_driver = agent->driver();\n  hsa_status_t status = agent_driver.ExportDMABuf(memoryHandleIt->first, size,\n                                                  &dmabuf_fd, &offset);\n  if (status != HSA_STATUS_SUCCESS)\n    return status;\n  assert(offset == 0);\n\n  ShareableHandle shareable_handle;\n  status = agent_driver.ImportDMABuf(dmabuf_fd, *agent, shareable_handle);\n  if (status != HSA_STATUS_SUCCESS)\n    return status;\n\n  close(dmabuf_fd);\n\n  // Get address that memory is mapped to\n  ret = GetAmdgpuDeviceArgs(agent, shareable_handle, &drm_fd, &drm_cpu_addr);\n  if (ret) return HSA_STATUS_ERROR;\n\n  mapped_handle_map_.emplace(\n      std::piecewise_construct, std::forward_as_tuple(va),\n      std::forward_as_tuple(&memoryHandleIt->second, &reservedAddressIt->second,\n                            offset, size, drm_fd,\n                            reinterpret_cast<void *>(drm_cpu_addr),\n                            HSA_ACCESS_PERMISSION_NONE, shareable_handle));\n\n  reservedAddressIt->second.use_count++;\n  memoryHandleIt->second.use_count++;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryHandleUnmap(void* va, size_t size) {\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n  std::list<std::pair<void*, MappedHandle*>> mappedHandles;\n\n  // va + size may consist of multiple MappedHandle's.\n  // Build a list lf MappedHandles within this VA range.\n\n  uint8_t* va_ptr = reinterpret_cast<uint8_t*>(va);\n  uint8_t* va_chunk = va_ptr;\n  while (va_chunk < va_ptr + size) {\n    auto mappedHandleIt = mapped_handle_map_.find(va_chunk);\n    // Cannot find a contiguous list of MappedHandles for the full VA range\n    if (mappedHandleIt == mapped_handle_map_.end()) {\n      return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n    }\n\n    mappedHandles.push_back(std::make_pair(va_chunk, &mappedHandleIt->second));\n    va_chunk += mappedHandleIt->second.size;\n  }\n  if (va_chunk != va_ptr + size) {\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  for (auto mappedHandleIt : mappedHandles) {\n    // Remove access from all agents that were allowed access\n    for (auto agentPermsIt = mappedHandleIt.second->allowed_agents.begin();\n              agentPermsIt != mappedHandleIt.second->allowed_agents.end();) {\n      assert(mappedHandleIt.first == agentPermsIt->second.va);\n      hsa_status_t status = agentPermsIt->second.RemoveAccess();\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n      agentPermsIt = mappedHandleIt.second->allowed_agents.erase(agentPermsIt);\n    }\n\n    if (mappedHandleIt.second->shareable_handle.IsValid()) {\n      hsa_status_t status =\n        mappedHandleIt.second->agentOwner()->driver().ReleaseShareableHandle(\n                                      mappedHandleIt.second->shareable_handle);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n    }\n\n    assert(mappedHandleIt.second->address_handle->use_count >= 1);\n    mappedHandleIt.second->address_handle->use_count--;\n    assert(mappedHandleIt.second->mem_handle->use_count >= 1);\n    mappedHandleIt.second->mem_handle->use_count--;\n\n    if (!mappedHandleIt.second->mem_handle->use_count &&\n        !mappedHandleIt.second->mem_handle->ref_count) {\n        // User called VMemoryHandleRelease while this mapping was still\n        // outstanding. We need to delete the MemoryHandle as it is the last\n        // MappedHandle that was using it.\n      mappedHandleIt.second->mem_handle->region->Free(mappedHandleIt.second->mem_handle->thunk_handle,\n                                                      mappedHandleIt.second->mem_handle->size);\n      memory_handle_map_.erase(mappedHandleIt.second->mem_handle->thunk_handle);\n    }\n\n    mapped_handle_map_.erase(mappedHandleIt.first);\n\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nRuntime::MappedHandleAllowedAgent::MappedHandleAllowedAgent(\n    MappedHandle *mappedHandle, Agent *targetAgent, void *va, size_t size,\n    hsa_access_permission_t perms)\n    : va(va), size(size), targetAgent(targetAgent), permissions(perms),\n      mappedHandle(mappedHandle) {\n\n  // CPU agents have access as the memory is already mapped to the host.\n  if (targetAgent->device_type() == core::Agent::DeviceType::kAmdCpuDevice) return;\n\n  int dmabuf_fd = 0;\n  uint64_t offset = 0;\n  MemoryHandle *memHandle = mappedHandle->mem_handle;\n\n  // Export memory from owner agent.\n  hsa_status_t status = memHandle->agentOwner()->driver().ExportDMABuf(\n      memHandle->thunk_handle, mappedHandle->size, &dmabuf_fd, &offset);\n  assert(status == HSA_STATUS_SUCCESS);\n  if (status != HSA_STATUS_SUCCESS)\n    return;\n  assert(offset == 0);\n\n  // Import to target agent.\n  status = targetAgent->driver().ImportDMABuf(dmabuf_fd, *targetAgent,\n                                              shareable_handle);\n  assert(status == HSA_STATUS_SUCCESS);\n  close(dmabuf_fd);\n  if (status != HSA_STATUS_SUCCESS)\n    return;\n}\n\nRuntime::MappedHandleAllowedAgent::~MappedHandleAllowedAgent() {\n  if (targetAgent->device_type() == core::Agent::DeviceType::kAmdCpuDevice) return;\n\n  hsa_status_t status =\n      targetAgent->driver().ReleaseShareableHandle(shareable_handle);\n  assert(status == HSA_STATUS_SUCCESS);\n}\n\nhsa_status_t Runtime::MappedHandleAllowedAgent::EnableAccess(hsa_access_permission_t perms) {\n  if (targetAgent->device_type() == core::Agent::DeviceType::kAmdCpuDevice) {\n    void* mapped_ptr =\n        mmap(va, size, PermissionsToMmapFlags(perms), MAP_SHARED | MAP_FIXED, mappedHandle->drm_fd,\n             reinterpret_cast<uint64_t>(mappedHandle->drm_cpu_addr));\n    if (mapped_ptr != va)\n      return HSA_STATUS_ERROR;\n  } else {\n    hsa_status_t status = targetAgent->driver().Map(\n        shareable_handle, va, mappedHandle->offset, size, perms);\n    if (status != HSA_STATUS_SUCCESS)\n      return status;\n  }\n  permissions = perms;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::MappedHandleAllowedAgent::RemoveAccess() {\n  if (targetAgent->device_type() == core::Agent::DeviceType::kAmdCpuDevice) {\n    if (munmap(va, size) != 0)\n      return HSA_STATUS_ERROR;\n    return HSA_STATUS_SUCCESS;\n  } else {\n    return targetAgent->driver().Unmap(\n        shareable_handle, va, mappedHandle->offset, mappedHandle->size);\n  }\n}\n\n// Note: VMemorySetAccessPerHandle should be called with &memory_lock_ held\nhsa_status_t\nRuntime::VMemorySetAccessPerHandle(void *va, MappedHandle &mappedHandle,\n                                   const hsa_amd_memory_access_desc_t *desc,\n                                   const size_t desc_cnt) {\n  for (int i = 0; i < desc_cnt; i++) {\n    Agent *targetAgent = Agent::Convert(desc[i].agent_handle);\n\n    const size_t &size = mappedHandle.size;\n    const hsa_access_permission_t &perm = desc[i].permissions;\n\n    auto agentPermsIt = mappedHandle.allowed_agents.find(targetAgent);\n    if (agentPermsIt == mappedHandle.allowed_agents.end()) {\n      /* Agent not previously allowed, we need a new entry */\n      agentPermsIt =\n          mappedHandle.allowed_agents\n              .emplace(std::piecewise_construct,\n                       std::forward_as_tuple(targetAgent),\n                       std::forward_as_tuple(&mappedHandle, targetAgent, va,\n                                             size, perm))\n              .first;\n\n      if (agentPermsIt->second.EnableAccess(perm) != HSA_STATUS_SUCCESS) {\n        mappedHandle.allowed_agents.erase(agentPermsIt);\n        return HSA_STATUS_ERROR;\n      }\n    } else {\n      /* Previous permissions are same as current permission */\n      if (agentPermsIt->second.permissions == perm)\n        continue;\n\n      /* Permissions are different - update access */\n      if (agentPermsIt->second.RemoveAccess() != HSA_STATUS_SUCCESS)\n        throw AMD::hsa_exception(HSA_STATUS_ERROR, \"Failed to remove access for memory handle.\");\n\n      if (agentPermsIt->second.EnableAccess(perm) != HSA_STATUS_SUCCESS) {\n        mappedHandle.allowed_agents.erase(agentPermsIt);\n        return HSA_STATUS_ERROR;\n      }\n    }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemorySetAccess(void* va, size_t size,\n                                       const hsa_amd_memory_access_desc_t* desc,\n                                       const size_t desc_cnt) {\n  std::list<std::pair<void*, MappedHandle*>> mappedHandles;\n  bool reservedAddressFound = false;\n\n  // Validate all agents\n  for (int i = 0; i < desc_cnt; i++) {\n    Agent* targetAgent = Agent::Convert(desc[i].agent_handle);\n\n    if (targetAgent == NULL || !targetAgent->IsValid()) return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n  auto reservedAddressIt = reserved_address_map_.upper_bound(va);\n  if (reservedAddressIt != reserved_address_map_.begin()) {\n    reservedAddressIt--;\n    if ((reservedAddressIt->first <= va) &&\n        ((reinterpret_cast<uint8_t*>(va) + size) <=\n         (reinterpret_cast<const uint8_t*>(reservedAddressIt->first) +\n          reservedAddressIt->second.size))) {\n      reservedAddressFound = true;\n    }\n  }\n  if (!reservedAddressFound) return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\n  // va + size may consist of multiple MappedHandle's. Build a list lf MappedHandles within this VA\n  // range\n  uint8_t* va_chunk = reinterpret_cast<uint8_t*>(va);\n  while (va_chunk < reinterpret_cast<uint8_t*>(va) + size) {\n    auto mappedHandleIt = mapped_handle_map_.find(va_chunk);\n    // Cannot find a contiguous list of MappedHandles for the full VA range\n    if (mappedHandleIt == mapped_handle_map_.end()) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n    mappedHandles.push_back(std::make_pair(va_chunk, &mappedHandleIt->second));\n    va_chunk += mappedHandleIt->second.size;\n  }\n\n  hsa_status_t status;\n  for (auto mappedHandleIt : mappedHandles) {\n    status = VMemorySetAccessPerHandle(mappedHandleIt.first,\n                                       *mappedHandleIt.second, desc, desc_cnt);\n    if (status != HSA_STATUS_SUCCESS)\n      return status;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\n// Note: VMemoryMapAllowAccess should be called with &memory_lock_ held\nhsa_status_t Runtime::VMemoryMapAllowAccess(const void *va,\n                                            const hsa_access_permission_t perm,\n                                            const hsa_agent_t *agents,\n                                            size_t num_agents) {\n  hsa_amd_memory_access_desc_t *desc =\n      new (std::nothrow) hsa_amd_memory_access_desc_t[num_agents];\n  if (desc == nullptr)\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  MAKE_SCOPE_GUARD([&]() { delete[] desc; });\n\n  for (size_t i = 0; i < num_agents; i++) {\n    Agent *targetAgent = Agent::Convert(agents[i]);\n    if (targetAgent == nullptr || !targetAgent->IsValid())\n      return HSA_STATUS_ERROR_INVALID_AGENT;\n\n    desc[i].permissions = perm;\n    desc[i].agent_handle = agents[i];\n  }\n\n  std::list<std::pair<void *, MappedHandle *>> mappedHandles;\n\n  auto mappedHandleIt = mapped_handle_map_.upper_bound(va);\n  if (mappedHandleIt != mapped_handle_map_.begin()) {\n    mappedHandleIt--;\n\n    if ((reinterpret_cast<const uint8_t *>(mappedHandleIt->first) +\n         mappedHandleIt->second.size) > va) {\n      // We found a mapped handle. See if there are more contiguous mapped\n      // handles and add them to the list\n\n      uint8_t *va_chunk = (uint8_t *)mappedHandleIt->first;\n      do {\n        mappedHandles.push_back(\n            std::make_pair(va_chunk, &mappedHandleIt->second));\n        va_chunk += mappedHandleIt->second.size;\n\n        mappedHandleIt++;\n        if (mappedHandleIt == mapped_handle_map_.end())\n          break;\n      } while (va_chunk == mappedHandleIt->first);\n    }\n  }\n\n  if (mappedHandles.empty())\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  hsa_status_t status;\n  for (auto mappedHandleIt : mappedHandles) {\n    status = VMemorySetAccessPerHandle(\n        mappedHandleIt.first, *mappedHandleIt.second, desc, num_agents);\n    if (status != HSA_STATUS_SUCCESS)\n      return status;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryGetAccess(const void* va, hsa_access_permission_t* perms,\n                                       hsa_agent_t agent_handle) {\n  *perms = HSA_ACCESS_PERMISSION_NONE;\n  bool mappedHandleFound = false;\n\n  ScopedAcquire<KernelSharedMutex> lock(&memory_lock_);\n\n  auto mappedHandleIt = mapped_handle_map_.upper_bound(va);\n  if (mappedHandleIt != mapped_handle_map_.begin()) {\n    mappedHandleIt--;\n    if ((mappedHandleIt->first <= va) &&\n        reinterpret_cast<const uint8_t*>(va) <=\n         (reinterpret_cast<const uint8_t*>(mappedHandleIt->first) + mappedHandleIt->second.size)) {\n      mappedHandleFound = true;\n    }\n  }\n  if (!mappedHandleFound) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  Agent* agent = Agent::Convert(agent_handle);\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  auto agentPermsIt = mappedHandleIt->second.allowed_agents.find(agent);\n  if (agentPermsIt != mappedHandleIt->second.allowed_agents.end()) {\n    *perms = agentPermsIt->second.permissions;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  /* Set access was not called on this memory handle */\n  *perms = HSA_ACCESS_PERMISSION_NONE;\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryExportShareableHandle(int* dmabuf_fd,\n                                                   hsa_amd_vmem_alloc_handle_t handle,\n                                                   uint64_t flags) {\n  *dmabuf_fd = -1;\n  auto memoryHandle = memory_handle_map_.find(MemoryHandle::Convert(handle));\n  if (memoryHandle == memory_handle_map_.end()) {\n    debug_warning(false && \"Can't find memory handle\");\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n  }\n\n  uint64_t offset;\n\n  hsa_status_t err = memoryHandle->second.region->owner()->driver().ExportDMABuf(\n      memoryHandle->second.thunk_handle, memoryHandle->second.size, dmabuf_fd, &offset);\n  if (err != HSA_STATUS_SUCCESS) return err;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryImportShareableHandle(int dmabuf_fd,\n                                                   hsa_amd_vmem_alloc_handle_t* memoryOnlyHandle) {\n  auto lookupRegion = [this](int nodeid, const AMD::MemoryRegion** ret) {\n    auto nodeAgent = agents_by_node_.find(nodeid);\n    if (nodeAgent == agents_by_node_.end()) {\n      *ret = NULL;\n      return;\n    }\n\n    Agent* agent = nodeAgent->second.front();\n    if (agent == nullptr || !agent->IsValid() || agent->device_type() != Agent::kAmdGpuDevice) {\n      *ret = NULL;\n      return;\n    }\n\n    for (const core::MemoryRegion* region : agent->regions()) {\n      const AMD::MemoryRegion* amd_region = reinterpret_cast<const AMD::MemoryRegion*>(region);\n\n      // TODO: Verify that this works on a system with FINE_GRAINED memory.\n      // System's with FINE_GRAINED will have both COARSE and FINE grain... need to get the\n      // rigtht one.\n\n      bool alloc_allowed;\n      hsa_status_t status =\n          amd_region->GetInfo(HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED, &alloc_allowed);\n      if (status == HSA_STATUS_SUCCESS && alloc_allowed) *ret = amd_region;\n    }\n  };\n\n  HsaGraphicsResourceInfo info;\n  int ret = HSAKMT_CALL(hsaKmtRegisterGraphicsHandleToNodes(dmabuf_fd, &info, 0, NULL));\n  if (ret) return HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n\n  ThunkHandle thunk_handle = info.MemoryAddress;\n  size_t size = info.SizeInBytes;\n  int gpuid = info.NodeId;\n\n\n  auto memoryHandleIt = memory_handle_map_.find(thunk_handle);\n  if (memoryHandleIt != memory_handle_map_.end()) {\n    /* This handle was already imported, increment ref_count and return */\n    memoryHandleIt->second.ref_count++;\n    *memoryOnlyHandle = MemoryHandle::Convert(thunk_handle);\n    return HSA_STATUS_SUCCESS;\n  }\n\n  const AMD::MemoryRegion* region = NULL;\n  lookupRegion(gpuid, &region);\n  if (!region) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  HsaPointerInfo ptrInfo;\n  ret = HSAKMT_CALL(hsaKmtQueryPointerInfo(info.MemoryAddress, &ptrInfo));\n  if (ret != HSA_STATUS_SUCCESS || ptrInfo.Type == HSA_POINTER_UNKNOWN)\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  MemoryRegion::AllocateFlags alloc_flag = core::MemoryRegion::AllocateNoFlags;\n  if (ptrInfo.MemFlags.ui32.NoSubstitute) alloc_flag |= core::MemoryRegion::AllocatePinned;\n\n  memory_handle_map_.emplace(std::piecewise_construct,\n          std::forward_as_tuple(thunk_handle),\n          std::forward_as_tuple(region, size, 0, thunk_handle, alloc_flag));\n  *memoryOnlyHandle = MemoryHandle::Convert(thunk_handle);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryRetainAllocHandle(hsa_amd_vmem_alloc_handle_t* mapped_handle,\n                                               void* va) {\n  auto mappedHandleIt = mapped_handle_map_.find(va);\n  if (mappedHandleIt == mapped_handle_map_.end()) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  MemoryHandle* memoryHandle = mappedHandleIt->second.mem_handle;\n  memoryHandle->ref_count++;\n  *mapped_handle = MemoryHandle::Convert(memoryHandle->thunk_handle);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::VMemoryGetAllocPropertiesFromHandle(hsa_amd_vmem_alloc_handle_t allocHandle,\n                                                          const core::MemoryRegion** mem_region,\n                                                          hsa_amd_memory_type_t* type) {\n  auto memoryHandleIt = memory_handle_map_.find(MemoryHandle::Convert(allocHandle));\n  if (memoryHandleIt == memory_handle_map_.end()) return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  *mem_region = memoryHandleIt->second.region;\n  *type = (memoryHandleIt->second.alloc_flag & core::MemoryRegion::AllocatePinned)\n      ? MEMORY_TYPE_PINNED\n      : MEMORY_TYPE_NONE;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t Runtime::EnableLogging(uint8_t* flags, void* file) {\n  memcpy(log_flags, flags, sizeof(log_flags));\n\n  if (file)\n    log_file = reinterpret_cast<FILE*>(file);\n  else\n    log_file = stderr;\n\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace core\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/signal.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTME_CORE_SIGNAL_CPP_\n#define HSA_RUNTME_CORE_SIGNAL_CPP_\n\n#include \"core/inc/signal.h\"\n\n#include <algorithm>\n#include <numeric>\n#include <vector>\n\n#include \"core/util/timer.h\"\n#include \"core/inc/runtime.h\"\n\nnamespace rocr {\nnamespace core {\n\nKernelMutex Signal::ipcLock_;\nstd::map<decltype(hsa_signal_t::handle), Signal*> Signal::ipcMap_;\n\nvoid SharedSignalPool_t::clear() {\n  ifdebug {\n    size_t capacity = 0;\n    for (auto& block : block_list_) capacity += block.second;\n    if (capacity != free_list_.size())\n      debug_print(\"Warning: Resource leak detected by SharedSignalPool, %ld Signals leaked.\\n\",\n                  capacity - free_list_.size());\n  }\n\n  for (auto& block : block_list_) free_()(block.first);\n  block_list_.clear();\n  free_list_.clear();\n}\n\nSharedSignal* SharedSignalPool_t::alloc() {\n  ScopedAcquire<HybridMutex> lock(&lock_);\n  if (free_list_.empty()) {\n    SharedSignal* block = reinterpret_cast<SharedSignal*>(\n        allocate_()(block_size_ * sizeof(SharedSignal), __alignof(SharedSignal), 0, 0));\n    if (block == nullptr) {\n      block_size_ = minblock_;\n      block = reinterpret_cast<SharedSignal*>(\n          allocate_()(block_size_ * sizeof(SharedSignal), __alignof(SharedSignal), 0, 0));\n      if (block == nullptr) throw std::bad_alloc();\n    }\n\n    MAKE_NAMED_SCOPE_GUARD(throwGuard, [&]() { free_()(block); });\n    block_list_.push_back(std::make_pair(block, block_size_));\n    throwGuard.Dismiss();\n\n\n    for (int i = 0; i < block_size_; i++) {\n      free_list_.push_back(&block[i]);\n    }\n\n    block_size_ *= 2;\n  }\n\n  SharedSignal* ret = free_list_.back();\n  new (ret) SharedSignal();\n  free_list_.pop_back();\n  return ret;\n}\n\nvoid SharedSignalPool_t::free(SharedSignal* ptr) {\n  if (ptr == nullptr) return;\n\n  ptr->~SharedSignal();\n  ScopedAcquire<HybridMutex> lock(&lock_);\n\n  ifdebug {\n    bool valid = false;\n    for (auto& block : block_list_) {\n      if ((block.first <= ptr) &&\n          (uintptr_t(ptr) < uintptr_t(block.first) + block.second * sizeof(SharedSignal))) {\n        valid = true;\n        break;\n      }\n    }\n    assert(valid && \"Object does not belong to pool.\");\n  }\n\n  free_list_.push_back(ptr);\n}\n\nLocalSignal::LocalSignal(hsa_signal_value_t initial_value, bool exportable)\n    : local_signal_(exportable ? nullptr\n                               : core::Runtime::runtime_singleton_->GetSharedSignalPool(),\n                    exportable ? core::MemoryRegion::AllocateIPC : 0) {\n  local_signal_.shared_object()->amd_signal.value = initial_value;\n}\n\nvoid Signal::registerIpc() {\n  ScopedAcquire<KernelMutex> lock(&ipcLock_);\n  auto handle = Convert(this);\n  assert(ipcMap_.find(handle.handle) == ipcMap_.end() &&\n         \"Can't register the same IPC signal twice.\");\n  ipcMap_[handle.handle] = this;\n}\n\nbool Signal::deregisterIpc() {\n  ScopedAcquire<KernelMutex> lock(&ipcLock_);\n  if (refcount_ != 0) return false;\n  auto handle = Convert(this);\n  const auto& it = ipcMap_.find(handle.handle);\n  assert(it != ipcMap_.end() && \"Deregister on non-IPC signal.\");\n  ipcMap_.erase(it);\n  return true;\n}\n\nSignal* Signal::lookupIpc(hsa_signal_t signal) {\n  ScopedAcquire<KernelMutex> lock(&ipcLock_);\n  const auto& it = ipcMap_.find(signal.handle);\n  if (it == ipcMap_.end()) return nullptr;\n  return it->second;\n}\n\nSignal* Signal::duplicateIpc(hsa_signal_t signal) {\n  ScopedAcquire<KernelMutex> lock(&ipcLock_);\n  const auto& it = ipcMap_.find(signal.handle);\n  if (it == ipcMap_.end()) return nullptr;\n  it->second->refcount_++;\n  it->second->Retain();\n  return it->second;\n}\n\nvoid Signal::Release() {\n  if (--retained_ != 0) return;\n  if (!isIPC())\n    doDestroySignal();\n  else if (deregisterIpc())\n    doDestroySignal();\n}\n\nSignal::~Signal() {\n  signal_.kind = AMD_SIGNAL_KIND_INVALID;\n  if (refcount_ == 1 && isIPC()) {\n    refcount_ = 0;\n    deregisterIpc();\n  }\n}\n\nuint32_t Signal::WaitMultiple(uint32_t signal_count, const hsa_signal_t* hsa_signals,\n                              const hsa_signal_condition_t* conds, const hsa_signal_value_t* values,\n                              uint64_t timeout, hsa_wait_state_t wait_hint,\n                              std::vector<hsa_signal_value_t>& satisfying_values,\n                              bool wait_on_all) {\n  hsa_signal_handle* signals =\n      reinterpret_cast<hsa_signal_handle*>(const_cast<hsa_signal_t*>(hsa_signals));\n\n  for (uint32_t i = 0; i < signal_count; i++) signals[i]->Retain();\n\n  MAKE_SCOPE_GUARD([&]() {\n    for (uint32_t i = 0; i < signal_count; i++) signals[i]->Release();\n  });\n\n  uint32_t prior = 0;\n  for (uint32_t i = 0; i < signal_count; i++) prior = Max(prior, signals[i]->waiting_++);\n\n  MAKE_SCOPE_GUARD([&]() {\n    for (uint32_t i = 0; i < signal_count; i++) signals[i]->waiting_--;\n  });\n\n  if (!core::Runtime::runtime_singleton_->KfdVersion().supports_event_age)\n      // Allow only the first waiter to sleep. Without event age tracking,\n      // race condition can cause some threads to sleep without wakeup since missing interrupt.\n      if (prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE;\n\n  // Ensure that all signals in the list can be slept on.\n  if (wait_hint != HSA_WAIT_STATE_ACTIVE) {\n    for (uint32_t i = 0; i < signal_count; i++) {\n      if (signals[i]->EopEvent() == NULL) {\n        wait_hint = HSA_WAIT_STATE_ACTIVE;\n        break;\n      }\n    }\n  }\n\n  const uint32_t small_size = 10;\n  HsaEvent* short_evts[small_size];\n  HsaEvent** evts = NULL;\n  uint32_t unique_evts = 0;\n  if (wait_hint != HSA_WAIT_STATE_ACTIVE) {\n    if (signal_count > small_size)\n      evts = new HsaEvent* [signal_count];\n    else\n      evts = short_evts;\n    for (uint32_t i = 0; i < signal_count; i++)\n      evts[i] = signals[i]->EopEvent();\n    std::sort(evts, evts + signal_count);\n    HsaEvent** end = std::unique(evts, evts + signal_count);\n    unique_evts = uint32_t(end - evts);\n  }\n  MAKE_SCOPE_GUARD([&]() {\n    if (signal_count > small_size) delete[] evts;\n  });\n\n  uint64_t event_age[unique_evts];\n  memset(event_age, 0, unique_evts * sizeof(uint64_t));\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_event_age)\n    for (uint32_t i = 0; i < unique_evts; i++)\n      event_age[i] = 1;\n\n  int64_t value;\n\n  timer::fast_clock::time_point start_time = timer::fast_clock::now();\n\n  // Set a polling timeout value\n  const timer::fast_clock::duration kMaxElapsed = std::chrono::microseconds(200);\n\n  // Convert timeout value into the fast_clock domain\n  uint64_t hsa_freq = 0;\n  HSA::hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &hsa_freq);\n  const timer::fast_clock::duration fast_timeout =\n      timer::duration_from_seconds<timer::fast_clock::duration>(\n          double(timeout) / double(hsa_freq));\n\n  std::vector<uint32_t> unmet_condition_ids(signal_count);\n  std::iota(unmet_condition_ids.begin(), unmet_condition_ids.end(), 0);\n\n  while (true) {\n    // Cannot mwaitx - polling multiple signals\n    for (auto it = unmet_condition_ids.begin(); it != unmet_condition_ids.end();) {\n      auto i = *it;\n      bool condition_met = false;\n      if (!signals[i]->IsValid())\n        return uint32_t(-1);\n\n      value =\n          atomic::Load(&signals[i]->signal_.value, std::memory_order_relaxed);\n\n      switch (conds[i]) {\n        case HSA_SIGNAL_CONDITION_EQ: {\n          condition_met = (value == values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_NE: {\n          condition_met = (value != values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_GTE: {\n          condition_met = (value >= values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_LT: {\n          condition_met = (value < values[i]);\n          break;\n        }\n        default:\n          return uint32_t(-1);\n      }\n      if (condition_met) {\n        it = unmet_condition_ids.erase(it);\n        satisfying_values[i] = value;\n        if (!wait_on_all)\n          return i;\n        else if (unmet_condition_ids.empty())\n          return 0;\n      } else {\n        ++it;\n      }\n    }\n\n    timer::fast_clock::time_point time = timer::fast_clock::now();\n    if (time - start_time > fast_timeout) {\n      return uint32_t(-1);\n    }\n\n    if (wait_hint == HSA_WAIT_STATE_ACTIVE) {\n      continue;\n    }\n\n    if (time - start_time < kMaxElapsed) {\n    //  os::uSleep(20);\n      continue;\n    }\n\n    uint32_t wait_ms;\n    auto time_remaining = fast_timeout - (time - start_time);\n    uint64_t ct=timer::duration_cast<std::chrono::milliseconds>(\n      time_remaining).count();\n    wait_ms = (ct>0xFFFFFFFEu) ? 0xFFFFFFFEu : ct;\n    HSAKMT_CALL(hsaKmtWaitOnMultipleEvents_Ext(evts, unique_evts, wait_on_all, wait_ms, event_age));\n  }\n}\n\n/*\n * Special handler to wait listen for exceptions from underlying driver.\n */\nuint32_t Signal::WaitAnyExceptions(uint32_t signal_count, const hsa_signal_t* hsa_signals,\n                         const hsa_signal_condition_t* conds, const hsa_signal_value_t* values,\n                         hsa_signal_value_t* satisfying_value) {\n\n  uint32_t wait_ms = uint32_t(-1);\n  hsa_signal_handle* signals =\n      reinterpret_cast<hsa_signal_handle*>(const_cast<hsa_signal_t*>(hsa_signals));\n\n  for (uint32_t i = 0; i < signal_count; i++) signals[i]->Retain();\n\n  MAKE_SCOPE_GUARD([&]() {\n    for (uint32_t i = 0; i < signal_count; i++) signals[i]->Release();\n  });\n\n  uint32_t prior = 0;\n  for (uint32_t i = 0; i < signal_count; i++) prior = Max(prior, signals[i]->waiting_++);\n\n\n  MAKE_SCOPE_GUARD([&]() {\n    for (uint32_t i = 0; i < signal_count; i++) signals[i]->waiting_--;\n  });\n\n  if (!core::Runtime::runtime_singleton_->KfdVersion().supports_event_age)\n      // Allow only the first waiter to sleep. Without event age tracking,\n      // race condition can cause some threads to sleep without wakeup since missing interrupt.\n      if (prior != 0) wait_ms = 0;\n\n  HsaEvent** evts = new HsaEvent* [signal_count];\n  MAKE_SCOPE_GUARD([&]() { delete[] evts; });\n\n  uint32_t unique_evts = 0;\n\n  for (uint32_t i = 0; i < signal_count; i++) {\n    assert(signals[i]->EopEvent() != NULL);\n    evts[i] = signals[i]->EopEvent();\n  }\n\n  std::sort(evts, evts + signal_count);\n  HsaEvent** end = std::unique(evts, evts + signal_count);\n  unique_evts = uint32_t(end - evts);\n\n  uint64_t event_age[unique_evts];\n  memset(event_age, 0, unique_evts * sizeof(uint64_t));\n  if (core::Runtime::runtime_singleton_->KfdVersion().supports_event_age)\n    for (uint32_t i = 0; i < unique_evts; i++)\n      event_age[i] = 1;\n\n  int64_t value;\n\n  bool condition_met = false;\n  while (true) {\n    // Cannot mwaitx - polling multiple signals\n\n    for (uint32_t i = 0; i < signal_count; i++) {\n      if (!signals[i]->IsValid())\n        return uint32_t(-1);\n\n      const HSA_EVENTTYPE event_type = signals[i]->EopEvent()->EventData.EventType;\n      if (event_type == HSA_EVENTTYPE_MEMORY) {\n        const HsaMemoryAccessFault& fault =\n            signals[i]->EopEvent()->EventData.EventData.MemoryAccessFault;\n        if (fault.Flags == HSA_EVENTID_MEMORY_FATAL_PROCESS) return i;\n      } else if (event_type == HSA_EVENTTYPE_HW_EXCEPTION) {\n        const HsaHwException& exception =\n            signals[i]->EopEvent()->EventData.EventData.HwException;\n        if (exception.MemoryLost) return i;\n      }\n\n      value = atomic::Load(&signals[i]->signal_.value, std::memory_order_relaxed);\n\n      switch (conds[i]) {\n        case HSA_SIGNAL_CONDITION_EQ: {\n          condition_met = (value == values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_NE: {\n          condition_met = (value != values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_GTE: {\n          condition_met = (value >= values[i]);\n          break;\n        }\n        case HSA_SIGNAL_CONDITION_LT: {\n          condition_met = (value < values[i]);\n          break;\n        }\n        default: {\n          return uint32_t(-1);\n        }\n      }\n      if (condition_met) {\n        if (satisfying_value != NULL) *satisfying_value = value;\n        // Some other signal in the list satisfied condition\n        return i;\n      }\n    }\n\n    HSAKMT_CALL(hsaKmtWaitOnMultipleEvents_Ext(evts, unique_evts, false, wait_ms, event_age));\n  } //while\n}\n\nSignalGroup::SignalGroup(uint32_t num_signals, const hsa_signal_t* hsa_signals)\n    : count(num_signals) {\n  if (count != 0) {\n    signals = new hsa_signal_t[count];\n  } else {\n    signals = NULL;\n  }\n  if (signals == NULL) return;\n  for (uint32_t i = 0; i < count; i++) signals[i] = hsa_signals[i];\n}\n\n}  // namespace core\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/svm_profiler.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/svm_profiler.h\"\n\n#include <stdint.h>\n#include <algorithm>\n#include <sys/eventfd.h>\n#include <poll.h>\n\n#include \"core/util/utils.h\"\n#include \"core/inc/runtime.h\"\n#include \"core/inc/agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/util/os.h\"\n\nnamespace rocr {\nnamespace AMD {\n\nstatic const char* smi_event_string(uint32_t event) {\n  static const char* strings[] = {\"NONE\",\n                                  \"VMFAULT\",\n                                  \"THERMAL_THROTTLE\",\n                                  \"GPU_PRE_RESET\",\n                                  \"GPU_POST_RESET\",\n                                  \"MIGRATE_START\",\n                                  \"MIGRATE_END\",\n                                  \"PAGE_FAULT_START\",\n                                  \"PAGE_FAULT_END\",\n                                  \"QUEUE_EVICTION\",\n                                  \"QUEUE_RESTORE\",\n                                  \"UNMAP_FROM_GPU\",\n                                  \"UNKNOWN\"};\n\n  event = std::min<uint32_t>(event, sizeof(strings) / sizeof(char*) - 1);\n  return strings[event];\n}\n\nstatic const char* smi_migrate_string(uint32_t trigger) {\n  static const char* strings[] = {\"PREFETCH\",\n                                  \"PAGEFAULT_GPU\",\n                                  \"PAGEFAULT_CPU\",\n                                  \"TTM_EVICTION\",\n                                  \"UNKNOWN\"};\n\n  trigger = std::min<uint32_t>(trigger, sizeof(strings) / sizeof(char*) - 1);\n  return strings[trigger];\n}\n\nstatic const char* smi_eviction_string(uint32_t trigger) {\n  static const char* strings[] = {\"SVM\",\n                                  \"USERPTR\",\n                                  \"TTM\",\n                                  \"SUSPEND\",\n                                  \"CRIU_CHECKPOINT\",\n                                  \"CRIU_RESTORE\",\n                                  \"UNKNOWN\"};\n\n  trigger = std::min<uint32_t>(trigger, sizeof(strings) / sizeof(char*) - 1);\n  return strings[trigger];\n}\n\nstatic const char* smi_unmap_string(uint32_t trigger) {\n  static const char* strings[] = {\"MMU_NOTIFY\",\n                                  \"MMU_NOTIFY_MIGRATE\",\n                                  \"UNMAP_FROM_CPU\",\n                                  \"UNKNOWN\"};\n\n  trigger = std::min<uint32_t>(trigger, sizeof(strings) / sizeof(char*) - 1);\n  return strings[trigger];\n}\n\nvoid SvmProfileControl::PollSmiRun(void* _profileControl) {\n  SvmProfileControl* profileControl = (SvmProfileControl*)_profileControl;\n\n  profileControl->PollSmi();\n}\n\nvoid SvmProfileControl::PollSmi() {\n  if (core::Runtime::runtime_singleton_->flag().svm_profile().empty()) {\n    return;\n  }\n  FILE* logFile = fopen(core::Runtime::runtime_singleton_->flag().svm_profile().c_str(), \"a\");\n  if (logFile == NULL) {\n    return;\n  }\n  MAKE_NAMED_SCOPE_GUARD(logGuard, [&]() { fclose(logFile); });\n\n  std::vector<pollfd> files;\n  files.resize(core::Runtime::runtime_singleton_->gpu_agents().size() + 1);\n  files[0].fd = event;\n  files[0].events = POLLIN;\n  files[0].revents = 0;\n\n  HSAuint64 events = 0;\n  events = HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_MIGRATE_START) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_MIGRATE_END) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_PAGE_FAULT_START) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_PAGE_FAULT_END) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_QUEUE_EVICTION) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_QUEUE_RESTORE) |\n      HSA_SMI_EVENT_MASK_FROM_INDEX(HSA_SMI_EVENT_UNMAP_FROM_GPU);\n\n  for (int i = 0; i < core::Runtime::runtime_singleton_->gpu_agents().size(); i++) {\n    auto gpu_agent = core::Runtime::runtime_singleton_->gpu_agents()[i];\n    auto err = gpu_agent->driver().OpenSMI(gpu_agent->node_id(), &files[i + 1].fd);\n    assert(err == HSA_STATUS_SUCCESS);\n    files[i + 1].events = POLLIN;\n    files[i + 1].revents = 0;\n    // Enable collecting masked events.\n    auto wrote = write(files[i + 1].fd, &events, sizeof(events));\n    assert(wrote == sizeof(events));\n  }\n  MAKE_NAMED_SCOPE_GUARD(smiGuard, [&]() {\n    for (int i = 1; i < files.size(); i++) {\n      close(files[i].fd);\n    }\n  });\n\n  std::vector<std::string> smi_records;\n  smi_records.resize(core::Runtime::runtime_singleton_->gpu_agents().size() + 1);\n  char buffer[HSA_SMI_EVENT_MSG_SIZE + 1];\n\n  auto format_agent = [this](uint32_t gpuid) {\n    std::string ret;\n    core::Agent* agent = core::Runtime::runtime_singleton_->agent_by_gpuid(gpuid);\n    if (agent->device_type() == core::Agent::kAmdCpuDevice)\n      return std::string(\"CPU\");\n    else\n      return format(\"GPU%u(%p)\", ((AMD::GpuAgent*)agent)->enumeration_index(),\n                    agent->public_handle());\n  };\n\n  while (!exit) {\n    int ready = poll(&files[0], files.size(), -1);\n    if (ready < 1) {\n      assert(false && \"poll failed!\");\n      return;\n    }\n\n    for (int i = 1; i < files.size(); i++) {\n      if (files[i].revents & POLLIN) {\n        memset(buffer, 0, sizeof(buffer));\n        auto len = read(files[i].fd, buffer, sizeof(buffer) - 1);\n        if (len > 0) {\n          buffer[len] = '\\0';\n          // printf(\"%s\\n\", buffer);\n          // fprintf(logFile, \"%s\\n\", buffer);\n\n          smi_records[i] += buffer;\n\n          while (true) {\n            size_t pos = smi_records[i].find('\\n');\n            if (pos == std::string::npos) break;\n\n            std::string line = smi_records[i].substr(0, pos);\n            smi_records[i].erase(0, pos + 1);\n\n            const char* cursor;\n            cursor = line.c_str();\n\n            // Event records follow the format:\n            // event_id timestamp -pid event_specific_info trigger\n            // timestamp, pid, and trigger are in dec.  All other are hex.\n            // event_specific substring is listed for each event type.\n            // See kfd_ioctl.h for more info.\n            int event_id;\n            uint64_t time;\n            int pid;\n            int offset = 0;\n            int args = sscanf(cursor, \"%x %lu -%u%n\", &event_id, &time, &pid, &offset);\n            assert(args == 3 && \"Parsing error!\");\n\n            std::string detail;\n            cursor += offset + 1;\n            switch (event_id) {\n              //@addr(size) from->to prefetch_location:preferred_location\n              case HSA_SMI_EVENT_MIGRATE_START: {\n                uint64_t addr;\n                uint32_t size;\n                uint32_t from, to;\n                uint32_t trigger = 0;\n                uint32_t fetch, pref;\n                args = sscanf(cursor, \"@%lx(%x) %x->%x %x:%x %u\", &addr, &size, &from, &to, &fetch,\n                              &pref, &trigger);\n                assert(args == 7 && \"Parsing error!\");\n\n                addr *= 4096;\n                size *= 4096;\n\n                std::string from_agent = format_agent(from);\n                std::string to_agent = format_agent(to);\n                std::string range = format(\"[%p, %p]\", addr, addr + size - 1);\n                std::string cause = smi_migrate_string(trigger);\n                detail = cause + \" \" + from_agent + \"->\" + to_agent + \" \" + range;\n                break;\n              }\n              //@addr(size) from->to\n              case HSA_SMI_EVENT_MIGRATE_END: {\n                uint64_t addr;\n                uint32_t size;\n                uint32_t from, to;\n                uint32_t trigger;\n                args = sscanf(cursor, \"@%lx(%x) %x->%x %u\", &addr, &size, &from, &to, &trigger);\n                assert(args == 5 && \"Parsing error!\");\n\n                addr *= 4096;\n                size *= 4096;\n\n                std::string from_agent = format_agent(from);\n                std::string to_agent = format_agent(to);\n                std::string range = format(\"[%p, %p]\", addr, addr + size - 1);\n                std::string cause = smi_migrate_string(trigger);\n                detail = cause + \" \" + from_agent + \"->\" + to_agent + \" \" + range;\n                break;\n              }\n              //@addr(gpu_id) W/R\n              case HSA_SMI_EVENT_PAGE_FAULT_START: {\n                uint64_t addr;\n                uint32_t gpuid;\n                char mode;\n                args = sscanf(cursor, \"@%lx(%x) %c\", &addr, &gpuid, &mode);\n\n                addr *= 4096;\n\n                assert(args == 3 && \"Parsing error!\");\n                std::string agent = format_agent(gpuid);\n                std::string range = std::to_string(addr);\n                std::string cause = (mode == 'W') ? \"Write\" : \"Read\";\n                detail = cause + \" \" + agent + \" \" + range;\n                break;\n              }\n              //@addr(gpu_id) M/U  (migration / page table update)\n              case HSA_SMI_EVENT_PAGE_FAULT_END: {\n                uint64_t addr;\n                uint32_t gpuid;\n                char mode;\n                args = sscanf(cursor, \"@%lx(%x) %c\", &addr, &gpuid, &mode);\n                assert(args == 3 && \"Parsing error!\");\n\n                addr *= 4096;\n\n                std::string agent = format_agent(gpuid);\n                std::string range = std::to_string(addr);\n                std::string cause = (mode == 'M') ? \"Migration\" : \"Map\";\n                detail = cause + \" \" + agent + \" \" + range;\n                break;\n              }\n              // gpu_id\n              case HSA_SMI_EVENT_QUEUE_EVICTION: {\n                uint32_t gpuid;\n                uint32_t trigger;\n                args = sscanf(cursor, \"%x %u\", &gpuid, &trigger);\n                assert(args == 2 && \"Parsing error!\");\n                std::string agent = format_agent(gpuid);\n                std::string cause = smi_eviction_string(trigger);\n                detail = cause + \" \" + agent;\n                break;\n              }\n              // gpu_id\n              case HSA_SMI_EVENT_QUEUE_RESTORE: {\n                uint32_t gpuid;\n                args = sscanf(cursor, \"%x\", &gpuid);\n                assert(args == 1 && \"Parsing error!\");\n                std::string agent = format_agent(gpuid);\n                detail = agent;\n                break;\n              }\n              //@addr(size) gpu_id\n              case HSA_SMI_EVENT_UNMAP_FROM_GPU: {\n                uint64_t addr;\n                uint32_t size;\n                uint32_t gpuid;\n                uint32_t trigger;\n                args = sscanf(cursor, \"@%lx(%x) %x %u\", &addr, &size, &gpuid, &trigger);\n                assert(args == 4 && \"Parsing error!\");\n\n                addr *= 4096;\n                size *= 4096;\n\n                std::string gpu = format_agent(gpuid);\n                std::string range = format(\"[%p, %p]\", addr, addr + size - 1);\n                std::string cause = smi_unmap_string(trigger);\n                detail = cause + \" \" + gpu + \" \" + range;\n                break;\n              }\n              default:;\n            }\n\n            std::string record = std::string(\"ROCr HMM event: \") + std::to_string(time) + \" \" +\n                smi_event_string(event_id) + \" \" + detail;\n            // printf(\"%s\\n\", record.c_str());\n            fprintf(logFile, \"%s\\n\", record.c_str());\n          }\n        } else {\n          auto err = errno;\n          const char* msg = strerror(err);\n          // printf(\"ROCr HMM event error: Read returned %ld, %s (%d)\\n\", len, msg, err);\n          fprintf(logFile, \"ROCr HMM event error: Read returned %ld, %s (%d)\\n\", len, msg, err);\n        }\n        files[i].revents = 0;\n      }\n    }\n    if (files[0].revents & POLLIN) return;\n  }\n}\n\nSvmProfileControl::SvmProfileControl() : event(-1), exit(false) {\n  event = eventfd(0, EFD_CLOEXEC);\n  if (event == -1) return;\n\n  poll_smi_thread_ = os::CreateThread(PollSmiRun, (void*)this);\n  if (poll_smi_thread_ == NULL) {\n    assert(false && \"Poll SMI thread creation error.\");\n    return;\n  }\n}\n\nSvmProfileControl::~SvmProfileControl() {\n  if (event != -1) eventfd_write(event, 1);\n  if (poll_smi_thread_ != NULL) {\n    exit = true;\n    os::WaitForThread(poll_smi_thread_);\n    os::CloseThread(poll_smi_thread_);\n    poll_smi_thread_ = NULL;\n  }\n  close(event);\n}\n\ntemplate <typename... Args>\nstd::string SvmProfileControl::format(const char* format, Args... args) {\n  int len = snprintf(&format_buffer[0], format_buffer.size(), format, args...);\n  if (len + 1 > format_buffer.size()) {\n    format_buffer.resize(len + 1);\n    snprintf(&format_buffer[0], format_buffer.size(), format, args...);\n  }\n  return std::string(&format_buffer[0]);\n}\n\n} // namespace AMD\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/thunk_loader.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/thunk_loader.h\"\n#include \"core/inc/runtime.h\"\n\n#include <dlfcn.h>\n#include <iostream>\n\nnamespace rocr {\nnamespace core {\n\n  ThunkLoader::ThunkLoader() {\n    if (core::Runtime::runtime_singleton_->flag().enable_dtif()) {\n      dlerror(); // Clear any existing error messages\n      dtif_handle = dlopen(\"libdtif.so\", RTLD_LAZY);\n      if (dtif_handle == NULL)\n        fprintf(stderr, \"Cannot load libdtif.so, failed:%s\\n\", dlerror());\n      else\n        debug_print(\"Load libdtif.so successully!\\n\");\n    }\n  }\n\n  ThunkLoader::~ThunkLoader() {\n    if (core::Runtime::runtime_singleton_->flag().enable_dtif()\n      && (dtif_handle != NULL)) {\n        if (dlclose(dtif_handle) != 0) {\n          fprintf(stderr, \"Cannot unload libdtif.so, failed:%s\\n\", dlerror());\n        } else {\n          debug_print(\"Unload libdtif.so successully!\\n\");\n        }\n    }\n  }\n\n  void ThunkLoader::LoadThunkApiTable() {\n    if (core::Runtime::runtime_singleton_->flag().enable_dtif()) {\n      dlerror(); // Clear any existing error messages\n\n      HSAKMT_PFN(hsaKmtOpenKFD) = (HSAKMT_DEF(hsaKmtOpenKFD)*)dlsym(dtif_handle, \"hsaKmtOpenKFD\");\n      if (HSAKMT_PFN(hsaKmtOpenKFD) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtCloseKFD) = (HSAKMT_DEF(hsaKmtCloseKFD)*)dlsym(dtif_handle, \"hsaKmtCloseKFD\");\n      if (HSAKMT_PFN(hsaKmtCloseKFD) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetVersion) = (HSAKMT_DEF(hsaKmtGetVersion)*)dlsym(dtif_handle, \"hsaKmtGetVersion\");\n      if (HSAKMT_PFN(hsaKmtGetVersion) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtAcquireSystemProperties) = (HSAKMT_DEF(hsaKmtAcquireSystemProperties)*)dlsym(dtif_handle, \"hsaKmtAcquireSystemProperties\");\n      if (HSAKMT_PFN(hsaKmtAcquireSystemProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtReleaseSystemProperties) = (HSAKMT_DEF(hsaKmtReleaseSystemProperties)*)dlsym(dtif_handle, \"hsaKmtReleaseSystemProperties\");\n      if (HSAKMT_PFN(hsaKmtReleaseSystemProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetNodeProperties) = (HSAKMT_DEF(hsaKmtGetNodeProperties)*)dlsym(dtif_handle, \"hsaKmtGetNodeProperties\");\n      if (HSAKMT_PFN(hsaKmtGetNodeProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetNodeMemoryProperties) = (HSAKMT_DEF(hsaKmtGetNodeMemoryProperties)*)dlsym(dtif_handle, \"hsaKmtGetNodeMemoryProperties\");\n      if (HSAKMT_PFN(hsaKmtGetNodeMemoryProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetNodeCacheProperties) = (HSAKMT_DEF(hsaKmtGetNodeCacheProperties)*)dlsym(dtif_handle, \"hsaKmtGetNodeCacheProperties\");\n      if (HSAKMT_PFN(hsaKmtGetNodeCacheProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetNodeIoLinkProperties) = (HSAKMT_DEF(hsaKmtGetNodeIoLinkProperties)*)dlsym(dtif_handle, \"hsaKmtGetNodeIoLinkProperties\");\n      if (HSAKMT_PFN(hsaKmtGetNodeIoLinkProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtCreateEvent) = (HSAKMT_DEF(hsaKmtCreateEvent)*)dlsym(dtif_handle, \"hsaKmtCreateEvent\");\n      if (HSAKMT_PFN(hsaKmtCreateEvent) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDestroyEvent) = (HSAKMT_DEF(hsaKmtDestroyEvent)*)dlsym(dtif_handle, \"hsaKmtDestroyEvent\");\n      if (HSAKMT_PFN(hsaKmtDestroyEvent) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetEvent) = (HSAKMT_DEF(hsaKmtSetEvent)*)dlsym(dtif_handle, \"hsaKmtSetEvent\");\n      if (HSAKMT_PFN(hsaKmtSetEvent) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtResetEvent) = (HSAKMT_DEF(hsaKmtResetEvent)*)dlsym(dtif_handle, \"hsaKmtResetEvent\");\n      if (HSAKMT_PFN(hsaKmtResetEvent) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtQueryEventState) = (HSAKMT_DEF(hsaKmtQueryEventState)*)dlsym(dtif_handle, \"hsaKmtQueryEventState\");\n      if (HSAKMT_PFN(hsaKmtQueryEventState) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtWaitOnEvent) = (HSAKMT_DEF(hsaKmtWaitOnEvent)*)dlsym(dtif_handle, \"hsaKmtWaitOnEvent\");\n      if (HSAKMT_PFN(hsaKmtWaitOnEvent) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtWaitOnMultipleEvents) = (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents)*)dlsym(dtif_handle, \"hsaKmtWaitOnMultipleEvents\");\n      if (HSAKMT_PFN(hsaKmtWaitOnMultipleEvents) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtCreateQueue) = (HSAKMT_DEF(hsaKmtCreateQueue)*)dlsym(dtif_handle, \"hsaKmtCreateQueue\");\n      if (HSAKMT_PFN(hsaKmtCreateQueue) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtCreateQueueExt) = (HSAKMT_DEF(hsaKmtCreateQueueExt)*)dlsym(dtif_handle, \"hsaKmtCreateQueueExt\");\n      if (HSAKMT_PFN(hsaKmtCreateQueueExt) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtUpdateQueue) = (HSAKMT_DEF(hsaKmtUpdateQueue)*)dlsym(dtif_handle, \"hsaKmtUpdateQueue\");\n      if (HSAKMT_PFN(hsaKmtUpdateQueue) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDestroyQueue) = (HSAKMT_DEF(hsaKmtDestroyQueue)*)dlsym(dtif_handle, \"hsaKmtDestroyQueue\");\n      if (HSAKMT_PFN(hsaKmtDestroyQueue) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetQueueCUMask) = (HSAKMT_DEF(hsaKmtSetQueueCUMask)*)dlsym(dtif_handle, \"hsaKmtSetQueueCUMask\");\n      if (HSAKMT_PFN(hsaKmtSetQueueCUMask) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetMemoryPolicy) = (HSAKMT_DEF(hsaKmtSetMemoryPolicy)*)dlsym(dtif_handle, \"hsaKmtSetMemoryPolicy\");\n      if (HSAKMT_PFN(hsaKmtSetMemoryPolicy) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtAllocMemory) = (HSAKMT_DEF(hsaKmtAllocMemory)*)dlsym(dtif_handle, \"hsaKmtAllocMemory\");\n      if (HSAKMT_PFN(hsaKmtAllocMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtAllocMemoryAlign) = (HSAKMT_DEF(hsaKmtAllocMemoryAlign)*)dlsym(dtif_handle, \"hsaKmtAllocMemoryAlign\");\n      if (HSAKMT_PFN(hsaKmtAllocMemoryAlign) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtFreeMemory) = (HSAKMT_DEF(hsaKmtFreeMemory)*)dlsym(dtif_handle, \"hsaKmtFreeMemory\");\n      if (HSAKMT_PFN(hsaKmtFreeMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtAvailableMemory) = (HSAKMT_DEF(hsaKmtAvailableMemory)*)dlsym(dtif_handle, \"hsaKmtAvailableMemory\");\n      if (HSAKMT_PFN(hsaKmtAvailableMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterMemory) = (HSAKMT_DEF(hsaKmtRegisterMemory)*)dlsym(dtif_handle, \"hsaKmtRegisterMemory\");\n      if (HSAKMT_PFN(hsaKmtRegisterMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterMemoryToNodes) = (HSAKMT_DEF(hsaKmtRegisterMemoryToNodes)*)dlsym(dtif_handle, \"hsaKmtRegisterMemoryToNodes\");\n      if (HSAKMT_PFN(hsaKmtRegisterMemoryToNodes) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterMemoryWithFlags) = (HSAKMT_DEF(hsaKmtRegisterMemoryWithFlags)*)dlsym(dtif_handle, \"hsaKmtRegisterMemoryWithFlags\");\n      if (HSAKMT_PFN(hsaKmtRegisterMemoryWithFlags) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodes) = (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodes)*)dlsym(dtif_handle, \"hsaKmtRegisterGraphicsHandleToNodes\");\n      if (HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodes) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodesExt) = (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodesExt)*)dlsym(dtif_handle, \"hsaKmtRegisterGraphicsHandleToNodesExt\");\n      if (HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodesExt) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtShareMemory) = (HSAKMT_DEF(hsaKmtShareMemory)*)dlsym(dtif_handle, \"hsaKmtShareMemory\");\n      if (HSAKMT_PFN(hsaKmtShareMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterSharedHandle) = (HSAKMT_DEF(hsaKmtRegisterSharedHandle)*)dlsym(dtif_handle, \"hsaKmtRegisterSharedHandle\");\n      if (HSAKMT_PFN(hsaKmtRegisterSharedHandle) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRegisterSharedHandleToNodes) = (HSAKMT_DEF(hsaKmtRegisterSharedHandleToNodes)*)dlsym(dtif_handle, \"hsaKmtRegisterSharedHandleToNodes\");\n      if (HSAKMT_PFN(hsaKmtRegisterSharedHandleToNodes) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtProcessVMRead) = (HSAKMT_DEF(hsaKmtProcessVMRead)*)dlsym(dtif_handle, \"hsaKmtProcessVMRead\");\n      if (HSAKMT_PFN(hsaKmtProcessVMRead) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtProcessVMWrite) = (HSAKMT_DEF(hsaKmtProcessVMWrite)*)dlsym(dtif_handle, \"hsaKmtProcessVMWrite\");\n      if (HSAKMT_PFN(hsaKmtProcessVMWrite) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDeregisterMemory) = (HSAKMT_DEF(hsaKmtDeregisterMemory)*)dlsym(dtif_handle, \"hsaKmtDeregisterMemory\");\n      if (HSAKMT_PFN(hsaKmtDeregisterMemory) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtMapMemoryToGPU) = (HSAKMT_DEF(hsaKmtMapMemoryToGPU)*)dlsym(dtif_handle, \"hsaKmtMapMemoryToGPU\");\n      if (HSAKMT_PFN(hsaKmtMapMemoryToGPU) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtMapMemoryToGPUNodes) = (HSAKMT_DEF(hsaKmtMapMemoryToGPUNodes)*)dlsym(dtif_handle, \"hsaKmtMapMemoryToGPUNodes\");\n      if (HSAKMT_PFN(hsaKmtMapMemoryToGPUNodes) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtUnmapMemoryToGPU) = (HSAKMT_DEF(hsaKmtUnmapMemoryToGPU)*)dlsym(dtif_handle, \"hsaKmtUnmapMemoryToGPU\");\n      if (HSAKMT_PFN(hsaKmtUnmapMemoryToGPU) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgRegister) = (HSAKMT_DEF(hsaKmtDbgRegister)*)dlsym(dtif_handle, \"hsaKmtDbgRegister\");\n      if (HSAKMT_PFN(hsaKmtDbgRegister) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgUnregister) = (HSAKMT_DEF(hsaKmtDbgUnregister)*)dlsym(dtif_handle, \"hsaKmtDbgUnregister\");\n      if (HSAKMT_PFN(hsaKmtDbgUnregister) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgWavefrontControl) = (HSAKMT_DEF(hsaKmtDbgWavefrontControl)*)dlsym(dtif_handle, \"hsaKmtDbgWavefrontControl\");\n      if (HSAKMT_PFN(hsaKmtDbgWavefrontControl) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgAddressWatch) = (HSAKMT_DEF(hsaKmtDbgAddressWatch)*)dlsym(dtif_handle, \"hsaKmtDbgAddressWatch\");\n      if (HSAKMT_PFN(hsaKmtDbgAddressWatch) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgEnable) = (HSAKMT_DEF(hsaKmtDbgEnable)*)dlsym(dtif_handle, \"hsaKmtDbgEnable\");\n      if (HSAKMT_PFN(hsaKmtDbgEnable) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgDisable) = (HSAKMT_DEF(hsaKmtDbgDisable)*)dlsym(dtif_handle, \"hsaKmtDbgDisable\");\n      if (HSAKMT_PFN(hsaKmtDbgDisable) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgGetDeviceData) = (HSAKMT_DEF(hsaKmtDbgGetDeviceData)*)dlsym(dtif_handle, \"hsaKmtDbgGetDeviceData\");\n      if (HSAKMT_PFN(hsaKmtDbgGetDeviceData) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDbgGetQueueData) = (HSAKMT_DEF(hsaKmtDbgGetQueueData)*)dlsym(dtif_handle, \"hsaKmtDbgGetQueueData\");\n      if (HSAKMT_PFN(hsaKmtDbgGetQueueData) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetClockCounters) = (HSAKMT_DEF(hsaKmtGetClockCounters)*)dlsym(dtif_handle, \"hsaKmtGetClockCounters\");\n      if (HSAKMT_PFN(hsaKmtGetClockCounters) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcGetCounterProperties) = (HSAKMT_DEF(hsaKmtPmcGetCounterProperties)*)dlsym(dtif_handle, \"hsaKmtPmcGetCounterProperties\");\n      if (HSAKMT_PFN(hsaKmtPmcGetCounterProperties) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcRegisterTrace) = (HSAKMT_DEF(hsaKmtPmcRegisterTrace)*)dlsym(dtif_handle, \"hsaKmtPmcRegisterTrace\");\n      if (HSAKMT_PFN(hsaKmtPmcRegisterTrace) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcUnregisterTrace) = (HSAKMT_DEF(hsaKmtPmcUnregisterTrace)*)dlsym(dtif_handle, \"hsaKmtPmcUnregisterTrace\");\n      if (HSAKMT_PFN(hsaKmtPmcUnregisterTrace) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcAcquireTraceAccess) = (HSAKMT_DEF(hsaKmtPmcAcquireTraceAccess)*)dlsym(dtif_handle, \"hsaKmtPmcAcquireTraceAccess\");\n      if (HSAKMT_PFN(hsaKmtPmcAcquireTraceAccess) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcReleaseTraceAccess) = (HSAKMT_DEF(hsaKmtPmcReleaseTraceAccess)*)dlsym(dtif_handle, \"hsaKmtPmcReleaseTraceAccess\");\n      if (HSAKMT_PFN(hsaKmtPmcReleaseTraceAccess) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcStartTrace) = (HSAKMT_DEF(hsaKmtPmcStartTrace)*)dlsym(dtif_handle, \"hsaKmtPmcStartTrace\");\n      if (HSAKMT_PFN(hsaKmtPmcStartTrace) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcQueryTrace) = (HSAKMT_DEF(hsaKmtPmcQueryTrace)*)dlsym(dtif_handle, \"hsaKmtPmcQueryTrace\");\n      if (HSAKMT_PFN(hsaKmtPmcQueryTrace) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPmcStopTrace) = (HSAKMT_DEF(hsaKmtPmcStopTrace)*)dlsym(dtif_handle, \"hsaKmtPmcStopTrace\");\n      if (HSAKMT_PFN(hsaKmtPmcStopTrace) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtMapGraphicHandle) = (HSAKMT_DEF(hsaKmtMapGraphicHandle)*)dlsym(dtif_handle, \"hsaKmtMapGraphicHandle\");\n      if (HSAKMT_PFN(hsaKmtMapGraphicHandle) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtUnmapGraphicHandle) = (HSAKMT_DEF(hsaKmtUnmapGraphicHandle)*)dlsym(dtif_handle, \"hsaKmtUnmapGraphicHandle\");\n      if (HSAKMT_PFN(hsaKmtUnmapGraphicHandle) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetTrapHandler) = (HSAKMT_DEF(hsaKmtSetTrapHandler)*)dlsym(dtif_handle, \"hsaKmtSetTrapHandler\");\n      if (HSAKMT_PFN(hsaKmtSetTrapHandler) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetTileConfig) = (HSAKMT_DEF(hsaKmtGetTileConfig)*)dlsym(dtif_handle, \"hsaKmtGetTileConfig\");\n      if (HSAKMT_PFN(hsaKmtGetTileConfig) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtQueryPointerInfo) = (HSAKMT_DEF(hsaKmtQueryPointerInfo)*)dlsym(dtif_handle, \"hsaKmtQueryPointerInfo\");\n      if (HSAKMT_PFN(hsaKmtQueryPointerInfo) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetMemoryUserData) = (HSAKMT_DEF(hsaKmtSetMemoryUserData)*)dlsym(dtif_handle, \"hsaKmtSetMemoryUserData\");\n      if (HSAKMT_PFN(hsaKmtSetMemoryUserData) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetQueueInfo) = (HSAKMT_DEF(hsaKmtGetQueueInfo)*)dlsym(dtif_handle, \"hsaKmtGetQueueInfo\");\n      if (HSAKMT_PFN(hsaKmtGetQueueInfo) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtAllocQueueGWS) = (HSAKMT_DEF(hsaKmtAllocQueueGWS)*)dlsym(dtif_handle, \"hsaKmtAllocQueueGWS\");\n      if (HSAKMT_PFN(hsaKmtAllocQueueGWS) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRuntimeEnable) = (HSAKMT_DEF(hsaKmtRuntimeEnable)*)dlsym(dtif_handle, \"hsaKmtRuntimeEnable\");\n      if (HSAKMT_PFN(hsaKmtRuntimeEnable) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtRuntimeDisable) = (HSAKMT_DEF(hsaKmtRuntimeDisable)*)dlsym(dtif_handle, \"hsaKmtRuntimeDisable\");\n      if (HSAKMT_PFN(hsaKmtRuntimeDisable) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtCheckRuntimeDebugSupport) = (HSAKMT_DEF(hsaKmtCheckRuntimeDebugSupport)*)dlsym(dtif_handle, \"hsaKmtCheckRuntimeDebugSupport\");\n      if (HSAKMT_PFN(hsaKmtCheckRuntimeDebugSupport) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetRuntimeCapabilities) = (HSAKMT_DEF(hsaKmtGetRuntimeCapabilities)*)dlsym(dtif_handle, \"hsaKmtGetRuntimeCapabilities\");\n      if (HSAKMT_PFN(hsaKmtGetRuntimeCapabilities) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtDebugTrapIoctl) = (HSAKMT_DEF(hsaKmtDebugTrapIoctl)*)dlsym(dtif_handle, \"hsaKmtDebugTrapIoctl\");\n      if (HSAKMT_PFN(hsaKmtDebugTrapIoctl) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSPMAcquire) = (HSAKMT_DEF(hsaKmtSPMAcquire)*)dlsym(dtif_handle, \"hsaKmtSPMAcquire\");\n      if (HSAKMT_PFN(hsaKmtSPMAcquire) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSPMRelease) = (HSAKMT_DEF(hsaKmtSPMRelease)*)dlsym(dtif_handle, \"hsaKmtSPMRelease\");\n      if (HSAKMT_PFN(hsaKmtSPMRelease) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSPMSetDestBuffer) = (HSAKMT_DEF(hsaKmtSPMSetDestBuffer)*)dlsym(dtif_handle, \"hsaKmtSPMSetDestBuffer\");\n      if (HSAKMT_PFN(hsaKmtSPMSetDestBuffer) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSVMSetAttr) = (HSAKMT_DEF(hsaKmtSVMSetAttr)*)dlsym(dtif_handle, \"hsaKmtSVMSetAttr\");\n      if (HSAKMT_PFN(hsaKmtSVMSetAttr) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSVMGetAttr) = (HSAKMT_DEF(hsaKmtSVMGetAttr)*)dlsym(dtif_handle, \"hsaKmtSVMGetAttr\");\n      if (HSAKMT_PFN(hsaKmtSVMGetAttr) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtSetXNACKMode) = (HSAKMT_DEF(hsaKmtSetXNACKMode)*)dlsym(dtif_handle, \"hsaKmtSetXNACKMode\");\n      if (HSAKMT_PFN(hsaKmtSetXNACKMode) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetXNACKMode) = (HSAKMT_DEF(hsaKmtGetXNACKMode)*)dlsym(dtif_handle, \"hsaKmtGetXNACKMode\");\n      if (HSAKMT_PFN(hsaKmtGetXNACKMode) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtOpenSMI) = (HSAKMT_DEF(hsaKmtOpenSMI)*)dlsym(dtif_handle, \"hsaKmtOpenSMI\");\n      if (HSAKMT_PFN(hsaKmtOpenSMI) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtExportDMABufHandle) = (HSAKMT_DEF(hsaKmtExportDMABufHandle)*)dlsym(dtif_handle, \"hsaKmtExportDMABufHandle\");\n      if (HSAKMT_PFN(hsaKmtExportDMABufHandle) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtWaitOnEvent_Ext) = (HSAKMT_DEF(hsaKmtWaitOnEvent_Ext)*)dlsym(dtif_handle, \"hsaKmtWaitOnEvent_Ext\");\n      if (HSAKMT_PFN(hsaKmtWaitOnEvent_Ext) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtWaitOnMultipleEvents_Ext) = (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents_Ext)*)dlsym(dtif_handle, \"hsaKmtWaitOnMultipleEvents_Ext\");\n      if (HSAKMT_PFN(hsaKmtWaitOnMultipleEvents_Ext) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtReplaceAsanHeaderPage) = (HSAKMT_DEF(hsaKmtReplaceAsanHeaderPage)*)dlsym(dtif_handle, \"hsaKmtReplaceAsanHeaderPage\");\n      if (HSAKMT_PFN(hsaKmtReplaceAsanHeaderPage) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtReturnAsanHeaderPage) = (HSAKMT_DEF(hsaKmtReturnAsanHeaderPage)*)dlsym(dtif_handle, \"hsaKmtReturnAsanHeaderPage\");\n      if (HSAKMT_PFN(hsaKmtReturnAsanHeaderPage) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtGetAMDGPUDeviceHandle) = (HSAKMT_DEF(hsaKmtGetAMDGPUDeviceHandle)*)dlsym(dtif_handle, \"hsaKmtGetAMDGPUDeviceHandle\");\n      if (HSAKMT_PFN(hsaKmtGetAMDGPUDeviceHandle) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingQueryCapabilities) = (HSAKMT_DEF(hsaKmtPcSamplingQueryCapabilities)*)dlsym(dtif_handle, \"hsaKmtPcSamplingQueryCapabilities\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingQueryCapabilities) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingCreate) = (HSAKMT_DEF(hsaKmtPcSamplingCreate)*)dlsym(dtif_handle, \"hsaKmtPcSamplingCreate\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingCreate) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingDestroy) = (HSAKMT_DEF(hsaKmtPcSamplingDestroy)*)dlsym(dtif_handle, \"hsaKmtPcSamplingDestroy\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingDestroy) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingStart) = (HSAKMT_DEF(hsaKmtPcSamplingStart)*)dlsym(dtif_handle, \"hsaKmtPcSamplingStart\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingStart) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingStop) = (HSAKMT_DEF(hsaKmtPcSamplingStop)*)dlsym(dtif_handle, \"hsaKmtPcSamplingStop\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingStop) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtPcSamplingSupport) = (HSAKMT_DEF(hsaKmtPcSamplingSupport)*)dlsym(dtif_handle, \"hsaKmtPcSamplingSupport\");\n      if (HSAKMT_PFN(hsaKmtPcSamplingSupport) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtModelEnabled) = (HSAKMT_DEF(hsaKmtModelEnabled)*)dlsym(dtif_handle, \"hsaKmtModelEnabled\");\n      if (HSAKMT_PFN(hsaKmtModelEnabled) == NULL) goto ERROR;\n\n      HSAKMT_PFN(hsaKmtQueueRingDoorbell) = (HSAKMT_DEF(hsaKmtQueueRingDoorbell)*)dlsym(dtif_handle, \"hsaKmtQueueRingDoorbell\");\n      if (HSAKMT_PFN(hsaKmtQueueRingDoorbell) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_device_initialize) = (DRM_DEF(amdgpu_device_initialize)*)dlsym(dtif_handle, \"amdgpu_device_initialize\");\n      if (DRM_PFN(amdgpu_device_initialize) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_device_deinitialize) = (DRM_DEF(amdgpu_device_deinitialize)*)dlsym(dtif_handle, \"amdgpu_device_deinitialize\");\n      if (DRM_PFN(amdgpu_device_deinitialize) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_query_gpu_info) = (DRM_DEF(amdgpu_query_gpu_info)*)dlsym(dtif_handle, \"amdgpu_query_gpu_info\");\n      if (DRM_PFN(amdgpu_query_gpu_info) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_bo_cpu_map) = (DRM_DEF(amdgpu_bo_cpu_map)*)dlsym(dtif_handle, \"amdgpu_bo_cpu_map\");\n      if (DRM_PFN(amdgpu_bo_cpu_map) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_bo_free) = (DRM_DEF(amdgpu_bo_free)*)dlsym(dtif_handle, \"amdgpu_bo_free\");\n      if (DRM_PFN(amdgpu_bo_free) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_bo_export) = (DRM_DEF(amdgpu_bo_export)*)dlsym(dtif_handle, \"amdgpu_bo_export\");\n      if (DRM_PFN(amdgpu_bo_export) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_bo_import) = (DRM_DEF(amdgpu_bo_import)*)dlsym(dtif_handle, \"amdgpu_bo_import\");\n      if (DRM_PFN(amdgpu_bo_import) == NULL) goto ERROR;\n\n      DRM_PFN(amdgpu_bo_va_op) = (DRM_DEF(amdgpu_bo_va_op)*)dlsym(dtif_handle, \"amdgpu_bo_va_op\");\n      if (DRM_PFN(amdgpu_bo_va_op) == NULL) goto ERROR;\n\n      DRM_PFN(drmCommandWriteRead) = (DRM_DEF(drmCommandWriteRead)*)dlsym(dtif_handle, \"drmCommandWriteRead\");\n      if (DRM_PFN(drmCommandWriteRead) == NULL) goto ERROR;\n\n      debug_print(\"Load all DTIF APIs OK!\\n\");\n      return;\n\nERROR:\n      fprintf(stderr, \"dlsym failed: %s\\n\", dlerror());\n    } else {\n      HSAKMT_PFN(hsaKmtOpenKFD) = (HSAKMT_DEF(hsaKmtOpenKFD)*)(&hsaKmtOpenKFD);\n      HSAKMT_PFN(hsaKmtCloseKFD) = (HSAKMT_DEF(hsaKmtCloseKFD)*)(&hsaKmtCloseKFD);\n      HSAKMT_PFN(hsaKmtGetVersion) = (HSAKMT_DEF(hsaKmtGetVersion)*)(&hsaKmtGetVersion);\n      HSAKMT_PFN(hsaKmtAcquireSystemProperties) = (HSAKMT_DEF(hsaKmtAcquireSystemProperties)*)(&hsaKmtAcquireSystemProperties);\n      HSAKMT_PFN(hsaKmtReleaseSystemProperties) = (HSAKMT_DEF(hsaKmtReleaseSystemProperties)*)(&hsaKmtReleaseSystemProperties);\n      HSAKMT_PFN(hsaKmtGetNodeProperties) = (HSAKMT_DEF(hsaKmtGetNodeProperties)*)(&hsaKmtGetNodeProperties);\n      HSAKMT_PFN(hsaKmtGetNodeMemoryProperties) = (HSAKMT_DEF(hsaKmtGetNodeMemoryProperties)*)(&hsaKmtGetNodeMemoryProperties);\n      HSAKMT_PFN(hsaKmtGetNodeCacheProperties) = (HSAKMT_DEF(hsaKmtGetNodeCacheProperties)*)(&hsaKmtGetNodeCacheProperties);\n      HSAKMT_PFN(hsaKmtGetNodeIoLinkProperties) = (HSAKMT_DEF(hsaKmtGetNodeIoLinkProperties)*)(&hsaKmtGetNodeIoLinkProperties);\n      HSAKMT_PFN(hsaKmtCreateEvent) = (HSAKMT_DEF(hsaKmtCreateEvent)*)(&hsaKmtCreateEvent);\n      HSAKMT_PFN(hsaKmtDestroyEvent) = (HSAKMT_DEF(hsaKmtDestroyEvent)*)(&hsaKmtDestroyEvent);\n      HSAKMT_PFN(hsaKmtSetEvent) = (HSAKMT_DEF(hsaKmtSetEvent)*)(&hsaKmtSetEvent);\n      HSAKMT_PFN(hsaKmtResetEvent) = (HSAKMT_DEF(hsaKmtResetEvent)*)(&hsaKmtResetEvent);\n      HSAKMT_PFN(hsaKmtQueryEventState) = (HSAKMT_DEF(hsaKmtQueryEventState)*)(&hsaKmtQueryEventState);\n      HSAKMT_PFN(hsaKmtWaitOnEvent) = (HSAKMT_DEF(hsaKmtWaitOnEvent)*)(&hsaKmtWaitOnEvent);\n      HSAKMT_PFN(hsaKmtWaitOnMultipleEvents) = (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents)*)(&hsaKmtWaitOnMultipleEvents);\n      HSAKMT_PFN(hsaKmtCreateQueue) = (HSAKMT_DEF(hsaKmtCreateQueue)*)(&hsaKmtCreateQueue);\n      HSAKMT_PFN(hsaKmtCreateQueueExt) = (HSAKMT_DEF(hsaKmtCreateQueueExt)*)(&hsaKmtCreateQueueExt);\n      HSAKMT_PFN(hsaKmtUpdateQueue) = (HSAKMT_DEF(hsaKmtUpdateQueue)*)(&hsaKmtUpdateQueue);\n      HSAKMT_PFN(hsaKmtDestroyQueue) = (HSAKMT_DEF(hsaKmtDestroyQueue)*)(&hsaKmtDestroyQueue);\n      HSAKMT_PFN(hsaKmtSetQueueCUMask) = (HSAKMT_DEF(hsaKmtSetQueueCUMask)*)(&hsaKmtSetQueueCUMask);\n      HSAKMT_PFN(hsaKmtSetMemoryPolicy) = (HSAKMT_DEF(hsaKmtSetMemoryPolicy)*)(&hsaKmtSetMemoryPolicy);\n      HSAKMT_PFN(hsaKmtAllocMemory) = (HSAKMT_DEF(hsaKmtAllocMemory)*)(&hsaKmtAllocMemory);\n      HSAKMT_PFN(hsaKmtAllocMemoryAlign) = (HSAKMT_DEF(hsaKmtAllocMemoryAlign)*)(&hsaKmtAllocMemoryAlign);\n      HSAKMT_PFN(hsaKmtFreeMemory) = (HSAKMT_DEF(hsaKmtFreeMemory)*)(&hsaKmtFreeMemory);\n      HSAKMT_PFN(hsaKmtAvailableMemory) = (HSAKMT_DEF(hsaKmtAvailableMemory)*)(&hsaKmtAvailableMemory);\n      HSAKMT_PFN(hsaKmtRegisterMemory) = (HSAKMT_DEF(hsaKmtRegisterMemory)*)(&hsaKmtRegisterMemory);\n      HSAKMT_PFN(hsaKmtRegisterMemoryToNodes) = (HSAKMT_DEF(hsaKmtRegisterMemoryToNodes)*)(&hsaKmtRegisterMemoryToNodes);\n      HSAKMT_PFN(hsaKmtRegisterMemoryWithFlags) = (HSAKMT_DEF(hsaKmtRegisterMemoryWithFlags)*)(&hsaKmtRegisterMemoryWithFlags);\n      HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodes) = (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodes)*)(&hsaKmtRegisterGraphicsHandleToNodes);\n      HSAKMT_PFN(hsaKmtRegisterGraphicsHandleToNodesExt) = (HSAKMT_DEF(hsaKmtRegisterGraphicsHandleToNodesExt)*)(&hsaKmtRegisterGraphicsHandleToNodesExt);\n      HSAKMT_PFN(hsaKmtShareMemory) = (HSAKMT_DEF(hsaKmtShareMemory)*)(&hsaKmtShareMemory);\n      HSAKMT_PFN(hsaKmtRegisterSharedHandle) = (HSAKMT_DEF(hsaKmtRegisterSharedHandle)*)(&hsaKmtRegisterSharedHandle);\n      HSAKMT_PFN(hsaKmtRegisterSharedHandleToNodes) = (HSAKMT_DEF(hsaKmtRegisterSharedHandleToNodes)*)(&hsaKmtRegisterSharedHandleToNodes);\n      HSAKMT_PFN(hsaKmtProcessVMRead) = (HSAKMT_DEF(hsaKmtProcessVMRead)*)(&hsaKmtProcessVMRead);\n      HSAKMT_PFN(hsaKmtProcessVMWrite) = (HSAKMT_DEF(hsaKmtProcessVMWrite)*)(&hsaKmtProcessVMWrite);\n      HSAKMT_PFN(hsaKmtDeregisterMemory) = (HSAKMT_DEF(hsaKmtDeregisterMemory)*)(&hsaKmtDeregisterMemory);\n      HSAKMT_PFN(hsaKmtMapMemoryToGPU) = (HSAKMT_DEF(hsaKmtMapMemoryToGPU)*)(&hsaKmtMapMemoryToGPU);\n      HSAKMT_PFN(hsaKmtMapMemoryToGPUNodes) = (HSAKMT_DEF(hsaKmtMapMemoryToGPUNodes)*)(&hsaKmtMapMemoryToGPUNodes);\n      HSAKMT_PFN(hsaKmtUnmapMemoryToGPU) = (HSAKMT_DEF(hsaKmtUnmapMemoryToGPU)*)(&hsaKmtUnmapMemoryToGPU);\n      HSAKMT_PFN(hsaKmtDbgRegister) = (HSAKMT_DEF(hsaKmtDbgRegister)*)(&hsaKmtDbgRegister);\n      HSAKMT_PFN(hsaKmtDbgUnregister) = (HSAKMT_DEF(hsaKmtDbgUnregister)*)(&hsaKmtDbgUnregister);\n      HSAKMT_PFN(hsaKmtDbgWavefrontControl) = (HSAKMT_DEF(hsaKmtDbgWavefrontControl)*)(&hsaKmtDbgWavefrontControl);\n      HSAKMT_PFN(hsaKmtDbgAddressWatch) = (HSAKMT_DEF(hsaKmtDbgAddressWatch)*)(&hsaKmtDbgAddressWatch);\n      HSAKMT_PFN(hsaKmtDbgEnable) = (HSAKMT_DEF(hsaKmtDbgEnable)*)(&hsaKmtDbgEnable);\n      HSAKMT_PFN(hsaKmtDbgDisable) = (HSAKMT_DEF(hsaKmtDbgDisable)*)(&hsaKmtDbgDisable);\n      HSAKMT_PFN(hsaKmtDbgGetDeviceData) = (HSAKMT_DEF(hsaKmtDbgGetDeviceData)*)(&hsaKmtDbgGetDeviceData);\n      HSAKMT_PFN(hsaKmtDbgGetQueueData) = (HSAKMT_DEF(hsaKmtDbgGetQueueData)*)(&hsaKmtDbgGetQueueData);\n      HSAKMT_PFN(hsaKmtGetClockCounters) = (HSAKMT_DEF(hsaKmtGetClockCounters)*)(&hsaKmtGetClockCounters);\n      HSAKMT_PFN(hsaKmtPmcGetCounterProperties) = (HSAKMT_DEF(hsaKmtPmcGetCounterProperties)*)(&hsaKmtPmcGetCounterProperties);\n      HSAKMT_PFN(hsaKmtPmcRegisterTrace) = (HSAKMT_DEF(hsaKmtPmcRegisterTrace)*)(&hsaKmtPmcRegisterTrace);\n      HSAKMT_PFN(hsaKmtPmcUnregisterTrace) = (HSAKMT_DEF(hsaKmtPmcUnregisterTrace)*)(&hsaKmtPmcUnregisterTrace);\n      HSAKMT_PFN(hsaKmtPmcAcquireTraceAccess) = (HSAKMT_DEF(hsaKmtPmcAcquireTraceAccess)*)(&hsaKmtPmcAcquireTraceAccess);\n      HSAKMT_PFN(hsaKmtPmcReleaseTraceAccess) = (HSAKMT_DEF(hsaKmtPmcReleaseTraceAccess)*)(&hsaKmtPmcReleaseTraceAccess);\n      HSAKMT_PFN(hsaKmtPmcStartTrace) = (HSAKMT_DEF(hsaKmtPmcStartTrace)*)(&hsaKmtPmcStartTrace);\n      HSAKMT_PFN(hsaKmtPmcQueryTrace) = (HSAKMT_DEF(hsaKmtPmcQueryTrace)*)(&hsaKmtPmcQueryTrace);\n      HSAKMT_PFN(hsaKmtPmcStopTrace) = (HSAKMT_DEF(hsaKmtPmcStopTrace)*)(&hsaKmtPmcStopTrace);\n      HSAKMT_PFN(hsaKmtMapGraphicHandle) = (HSAKMT_DEF(hsaKmtMapGraphicHandle)*)(&hsaKmtMapGraphicHandle);\n      HSAKMT_PFN(hsaKmtUnmapGraphicHandle) = (HSAKMT_DEF(hsaKmtUnmapGraphicHandle)*)(&hsaKmtUnmapGraphicHandle);\n      HSAKMT_PFN(hsaKmtSetTrapHandler) = (HSAKMT_DEF(hsaKmtSetTrapHandler)*)(&hsaKmtSetTrapHandler);\n      HSAKMT_PFN(hsaKmtGetTileConfig) = (HSAKMT_DEF(hsaKmtGetTileConfig)*)(&hsaKmtGetTileConfig);\n      HSAKMT_PFN(hsaKmtQueryPointerInfo) = (HSAKMT_DEF(hsaKmtQueryPointerInfo)*)(&hsaKmtQueryPointerInfo);\n      HSAKMT_PFN(hsaKmtSetMemoryUserData) = (HSAKMT_DEF(hsaKmtSetMemoryUserData)*)(&hsaKmtSetMemoryUserData);\n      HSAKMT_PFN(hsaKmtGetQueueInfo) = (HSAKMT_DEF(hsaKmtGetQueueInfo)*)(&hsaKmtGetQueueInfo);\n      HSAKMT_PFN(hsaKmtAllocQueueGWS) = (HSAKMT_DEF(hsaKmtAllocQueueGWS)*)(&hsaKmtAllocQueueGWS);\n      HSAKMT_PFN(hsaKmtRuntimeEnable) = (HSAKMT_DEF(hsaKmtRuntimeEnable)*)(&hsaKmtRuntimeEnable);\n      HSAKMT_PFN(hsaKmtRuntimeDisable) = (HSAKMT_DEF(hsaKmtRuntimeDisable)*)(&hsaKmtRuntimeDisable);\n      HSAKMT_PFN(hsaKmtCheckRuntimeDebugSupport) = (HSAKMT_DEF(hsaKmtCheckRuntimeDebugSupport)*)(&hsaKmtCheckRuntimeDebugSupport);\n      HSAKMT_PFN(hsaKmtGetRuntimeCapabilities) = (HSAKMT_DEF(hsaKmtGetRuntimeCapabilities)*)(&hsaKmtGetRuntimeCapabilities);\n      HSAKMT_PFN(hsaKmtDebugTrapIoctl) = (HSAKMT_DEF(hsaKmtDebugTrapIoctl)*)(&hsaKmtDebugTrapIoctl);\n      HSAKMT_PFN(hsaKmtSPMAcquire) = (HSAKMT_DEF(hsaKmtSPMAcquire)*)(&hsaKmtSPMAcquire);\n      HSAKMT_PFN(hsaKmtSPMRelease) = (HSAKMT_DEF(hsaKmtSPMRelease)*)(&hsaKmtSPMRelease);\n      HSAKMT_PFN(hsaKmtSPMSetDestBuffer) = (HSAKMT_DEF(hsaKmtSPMSetDestBuffer)*)(&hsaKmtSPMSetDestBuffer);\n      HSAKMT_PFN(hsaKmtSVMSetAttr) = (HSAKMT_DEF(hsaKmtSVMSetAttr)*)(&hsaKmtSVMSetAttr);\n      HSAKMT_PFN(hsaKmtSVMGetAttr) = (HSAKMT_DEF(hsaKmtSVMGetAttr)*)(&hsaKmtSVMGetAttr);\n      HSAKMT_PFN(hsaKmtSetXNACKMode) = (HSAKMT_DEF(hsaKmtSetXNACKMode)*)(&hsaKmtSetXNACKMode);\n      HSAKMT_PFN(hsaKmtGetXNACKMode) = (HSAKMT_DEF(hsaKmtGetXNACKMode)*)(&hsaKmtGetXNACKMode);\n      HSAKMT_PFN(hsaKmtOpenSMI) = (HSAKMT_DEF(hsaKmtOpenSMI)*)(&hsaKmtOpenSMI);\n      HSAKMT_PFN(hsaKmtExportDMABufHandle) = (HSAKMT_DEF(hsaKmtExportDMABufHandle)*)(&hsaKmtExportDMABufHandle);\n      HSAKMT_PFN(hsaKmtWaitOnEvent_Ext) = (HSAKMT_DEF(hsaKmtWaitOnEvent_Ext)*)(&hsaKmtWaitOnEvent_Ext);\n      HSAKMT_PFN(hsaKmtWaitOnMultipleEvents_Ext) = (HSAKMT_DEF(hsaKmtWaitOnMultipleEvents_Ext)*)(&hsaKmtWaitOnMultipleEvents_Ext);\n      HSAKMT_PFN(hsaKmtReplaceAsanHeaderPage) = (HSAKMT_DEF(hsaKmtReplaceAsanHeaderPage)*)(&hsaKmtReplaceAsanHeaderPage);\n      HSAKMT_PFN(hsaKmtReturnAsanHeaderPage) = (HSAKMT_DEF(hsaKmtReturnAsanHeaderPage)*)(&hsaKmtReturnAsanHeaderPage);\n      HSAKMT_PFN(hsaKmtGetAMDGPUDeviceHandle) = (HSAKMT_DEF(hsaKmtGetAMDGPUDeviceHandle)*)(&hsaKmtGetAMDGPUDeviceHandle);\n      HSAKMT_PFN(hsaKmtPcSamplingQueryCapabilities) = (HSAKMT_DEF(hsaKmtPcSamplingQueryCapabilities)*)(&hsaKmtPcSamplingQueryCapabilities);\n      HSAKMT_PFN(hsaKmtPcSamplingCreate) = (HSAKMT_DEF(hsaKmtPcSamplingCreate)*)(&hsaKmtPcSamplingCreate);\n      HSAKMT_PFN(hsaKmtPcSamplingDestroy) = (HSAKMT_DEF(hsaKmtPcSamplingDestroy)*)(&hsaKmtPcSamplingDestroy);\n      HSAKMT_PFN(hsaKmtPcSamplingStart) = (HSAKMT_DEF(hsaKmtPcSamplingStart)*)(&hsaKmtPcSamplingStart);\n      HSAKMT_PFN(hsaKmtPcSamplingStop) = (HSAKMT_DEF(hsaKmtPcSamplingStop)*)(&hsaKmtPcSamplingStop);\n      HSAKMT_PFN(hsaKmtPcSamplingSupport) = (HSAKMT_DEF(hsaKmtPcSamplingSupport)*)(&hsaKmtPcSamplingSupport);\n      HSAKMT_PFN(hsaKmtModelEnabled) = (HSAKMT_DEF(hsaKmtModelEnabled)*)(&hsaKmtModelEnabled);\n\n      DRM_PFN(amdgpu_device_initialize) = (DRM_DEF(amdgpu_device_initialize)*)(&amdgpu_device_initialize);\n      DRM_PFN(amdgpu_device_deinitialize) = (DRM_DEF(amdgpu_device_deinitialize)*)(&amdgpu_device_deinitialize);\n      DRM_PFN(amdgpu_query_gpu_info) = (DRM_DEF(amdgpu_query_gpu_info)*)(&amdgpu_query_gpu_info);\n      DRM_PFN(amdgpu_bo_cpu_map) = (DRM_DEF(amdgpu_bo_cpu_map)*)(&amdgpu_bo_cpu_map);\n      DRM_PFN(amdgpu_bo_free) = (DRM_DEF(amdgpu_bo_free)*)(&amdgpu_bo_free);\n      DRM_PFN(amdgpu_bo_export) = (DRM_DEF(amdgpu_bo_export)*)(&amdgpu_bo_export);\n      DRM_PFN(amdgpu_bo_import) = (DRM_DEF(amdgpu_bo_import)*)(&amdgpu_bo_import);\n      DRM_PFN(amdgpu_bo_va_op) = (DRM_DEF(amdgpu_bo_va_op)*)(&amdgpu_bo_va_op);\n      DRM_PFN(drmCommandWriteRead) = (DRM_DEF(drmCommandWriteRead)*)(&drmCommandWriteRead);\n    }\n  }\n\n  bool ThunkLoader::CreateThunkInstance() {\n    if (!core::Runtime::runtime_singleton_->flag().enable_dtif())\n      return true;\n\n    DtifCreateFunc* pfnDtifCreate = (DtifCreateFunc*)dlsym(dtif_handle, \"DtifCreate\");\n    if (pfnDtifCreate != NULL) {\n      if (pfnDtifCreate(\"HSA\") != NULL) {\n        debug_print(\"DtifCreate OK!\\n\");\n        return true;\n      } else {\n        debug_print(\"DtifCreate failed!\\n\");\n        return false;\n      }\n    }\n    return false;\n  }\n\n  bool ThunkLoader::DestroyThunkInstance() {\n    if (!core::Runtime::runtime_singleton_->flag().enable_dtif())\n      return true;\n\n    if (dtif_handle == NULL)\n      return false;\n\n    DtifDestroyFunc* pfnDtifDestroy = (DtifDestroyFunc*)dlsym(dtif_handle, \"DtifDestroy\");\n    if (pfnDtifDestroy != NULL) {\n      pfnDtifDestroy();\n      debug_print(\"DtifDestroy OK!\\n\");\n      return true;\n    }\n    return false;\n  }\n}   //  namespace core\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/trap_handler/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.7 )\n\n# Import target 'clang' and 'llvm-objcopy'\nfind_package(Clang REQUIRED HINTS ${CMAKE_PREFIX_PATH}/llvm PATHS /opt/rocm/llvm )\nfind_package(LLVM REQUIRED HINTS ${CMAKE_PREFIX_PATH}/llvm PATHS /opt/rocm/llvm )\n\nset (TARGET_DEVS \"gfx900;gfx942;gfx950;gfx1010;gfx1030;gfx1100;gfx1200\")\nset (POSTFIX \"9;942;950;1010;10;11;12\")\nset (SOURCE_SUFFIX \";;;;;;_gfx12\")\n\nif(${CMAKE_VERBOSE_MAKEFILE})\n  get_property(clang_path TARGET clang PROPERTY LOCATION)\n  get_property(objcopy_path TARGET llvm-objcopy PROPERTY LOCATION)\n  message(\"Using clang from: ${clang_path}\")\n  message(\"Using llvm-objcopy from: ${objcopy_path}\")\n  message(\"Trap handlers assembled for: ${TARGET_DEVS}\")\nendif()\n\n##==========================================\n##  Add custom command to generate a kernel code object file\n##==========================================\nfunction(gen_kernel_bc TARGET_ID INPUT_FILE OUTPUT_FILE)\n\n  set(CODE_OBJECT \"${OUTPUT_FILE}.hsaco\")\n\n  separate_arguments(CLANG_ARG_LIST UNIX_COMMAND\n  \"-x assembler -target amdgcn-amd-amdhsa -mcpu=${TARGET_ID} -o ${CODE_OBJECT} ${INPUT_FILE}\")\n\n  ## Add custom command to produce a code object file.\n  add_custom_command(OUTPUT ${CODE_OBJECT} COMMAND clang ${CLANG_ARG_LIST}\n    DEPENDS ${INPUT_FILE} clang\n    COMMENT \"BUILDING bitcode for ${OUTPUT_FILE}...\"\n    VERBATIM)\n\n  separate_arguments(OBJCOPY_ARG_LIST UNIX_COMMAND \"--dump-section=.text=${OUTPUT_FILE} ${CODE_OBJECT}\")\n\n  ## Extract .text segment\n  add_custom_command(OUTPUT ${OUTPUT_FILE}\n                     COMMAND llvm-objcopy ${OBJCOPY_ARG_LIST}\n                     DEPENDS ${CODE_OBJECT} llvm-objcopy\n                     COMMENT \"Extracting binary for ${OUTPUT_FILE}...\"\n                     VERBATIM)\n\n  if(${CMAKE_VERBOSE_MAKEFILE})\n    message(\"     Trap Handler Source: \" ${INPUT_FILE})\n    message(\"     Trap Handler Binary: \" ${OUTPUT_FILE})\n  endif()\n\nendfunction(gen_kernel_bc)\n\n##==========================================\n## Find device code object name and forward to custom command\n##==========================================\nfunction(build_kernel TRAP_HANDLER_NAME TARGET_ID POSTFIX SOURCE_SUFFIX)\n\n  ## generate trap handler object code files\n  set (CODE_OBJECT_FILE \"${TRAP_HANDLER_NAME}_${POSTFIX}\")\n  set (TRAP_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/trap_handler${SOURCE_SUFFIX}.s\")\n  gen_kernel_bc(${TARGET_ID} ${TRAP_FILE} ${CODE_OBJECT_FILE})\n\n  ## Build a list of code object file names\n  ## These will be target dependencies.\n  set (HSACO_TARG_LIST ${HSACO_TARG_LIST} \"${CODE_OBJECT_FILE}\" PARENT_SCOPE)\n\nendfunction(build_kernel)\n\n##==========================================\n## Build the kernel for a list of devices\n##==========================================\nfunction(build_kernel_for_devices TRAP_HANDLER_NAME)\n\n  set(HSACO_TARG_LIST \"\")\n\n  list(LENGTH TARGET_DEVS dev_count)\n  math(EXPR dev_count \"${dev_count} - 1\")\n  foreach(ind RANGE ${dev_count})\n    list(GET TARGET_DEVS ${ind} dev)\n    list(GET POSTFIX ${ind} post)\n    list(GET SOURCE_SUFFIX ${ind} suffix)\n    if(${CMAKE_VERBOSE_MAKEFILE})\n      message(\"\\n  Generating: ${dev} ...\")\n    endif()\n    build_kernel(${TRAP_HANDLER_NAME} ${dev} ${post} \"${suffix}\")\n  endforeach(ind)\n\n  set(HSACO_TARG_LIST ${HSACO_TARG_LIST} PARENT_SCOPE)\n\nendfunction(build_kernel_for_devices)\n\n##==========================================\n## Create Trap Handler Object Code blobs file\n##==========================================\nfunction(generate_bytecodeStrm HeaderFILE)\n\n  separate_arguments(ARG_LIST UNIX_COMMAND \"${CMAKE_CURRENT_BINARY_DIR}/${HeaderFILE}.h\")\n  set(ARG_LIST ${ARG_LIST} ${HSACO_TARG_LIST})\n\n  ## Add a custom command that generates amd_trap_handler_v2.h\n  ## This depends on all the generated code object files and the C++ generator script.\n  add_custom_command(OUTPUT ${HeaderFILE}.h\n                     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create_trap_handler_header.sh ${ARG_LIST}\n                     COMMENT \"Collating trap handlers...\"\n                     DEPENDS ${HSACO_TARG_LIST} create_trap_handler_header.sh )\n\n  ## Export a target that builds (and depends on) amd_trap_handler_v2.h\n  add_custom_target( ${HeaderFILE} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${HeaderFILE}.h )\n\nendfunction(generate_bytecodeStrm)\n\n##==========================================\n## Main function calls\n##==========================================\n\nbuild_kernel_for_devices(\"kCodeTrapHandlerV2\")\ngenerate_bytecodeStrm(\"amd_trap_handler_v2\")\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/trap_handler/create_trap_handler_header.sh",
    "content": "#!/bin/bash -e\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\namd_gpu_shaders=\"$1\"\n\nif ! command -v xxd >/dev/null\nthen\n    echo \"xxd not found!\"\n    exit 1\nfi\n\n# Create the file in a temporary location and then move it in atomically\n{\ncat <<EOF\n//==============================================================================\n//  This file is automatically generated during build process, don't modify it\n//==============================================================================\n\nnamespace rocr {\nnamespace AMD {\n\nEOF\n\nshift\nfor file in \"$@\"\ndo\nxxd -i $file\n    echo -e '\\n'\ndone\n\ncat <<EOF\n} // namespace AMD\n} // namespace rocr\n\nEOF\n\n} > \"$amd_gpu_shaders\"\n\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/trap_handler/trap_handler.s",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n/// Trap Handler V2 source\n.set SQ_WAVE_PC_HI_ADDRESS_MASK              , 0xFFFF\n.set SQ_WAVE_PC_HI_HT_SHIFT                  , 24\n.set SQ_WAVE_PC_HI_TRAP_ID_SHIFT             , 16\n.set SQ_WAVE_PC_HI_TRAP_ID_SIZE              , 8\n.set SQ_WAVE_PC_HI_TRAP_ID_BFE               , (SQ_WAVE_PC_HI_TRAP_ID_SHIFT | (SQ_WAVE_PC_HI_TRAP_ID_SIZE << 16))\n.set SQ_WAVE_STATUS_HALT_SHIFT               , 13\n.set SQ_WAVE_STATUS_TRAP_SKIP_EXPORT_SHIFT   , 18\n.set SQ_WAVE_STATUS_HALT_BFE                 , (SQ_WAVE_STATUS_HALT_SHIFT | (1 << 16))\n.set SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT          , 8\n.set SQ_WAVE_TRAPSTS_ILLEGAL_INST_SHIFT      , 11\n.set SQ_WAVE_TRAPSTS_XNACK_ERROR_SHIFT       , 28\n.set SQ_WAVE_TRAPSTS_MATH_EXCP               , 0x7F\n.set SQ_WAVE_TRAPSTS_PERF_SNAPSHOT_SHIFT     , 26\n.set SQ_WAVE_TRAPSTS_HOST_TRAP_SHIFT         , 22\n.set SQ_WAVE_MODE_EXCP_EN_SHIFT              , 12\n.set SQ_WAVE_MODE_EXCP_EN_SIZE               , 8\n.set TRAP_ID_ABORT                           , 2\n.set TRAP_ID_DEBUGTRAP                       , 3\n.set DOORBELL_ID_SIZE                        , 10\n.set DOORBELL_ID_MASK                        , ((1 << DOORBELL_ID_SIZE) - 1)\n.set EC_QUEUE_WAVE_ABORT_M0                  , (1 << (DOORBELL_ID_SIZE + 0))\n.set EC_QUEUE_WAVE_TRAP_M0                   , (1 << (DOORBELL_ID_SIZE + 1))\n.set EC_QUEUE_WAVE_MATH_ERROR_M0             , (1 << (DOORBELL_ID_SIZE + 2))\n.set EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION_M0    , (1 << (DOORBELL_ID_SIZE + 3))\n.set EC_QUEUE_WAVE_MEMORY_VIOLATION_M0       , (1 << (DOORBELL_ID_SIZE + 4))\n.set EC_QUEUE_WAVE_APERTURE_VIOLATION_M0     , (1 << (DOORBELL_ID_SIZE + 5))\n\n.set TTMP6_SPI_TTMPS_SETUP_DISABLED_SHIFT    , 31\n.set TTMP6_WAVE_STOPPED_SHIFT                , 30\n.set TTMP6_SAVED_STATUS_HALT_SHIFT           , 29\n.set TTMP6_SAVED_STATUS_HALT_MASK            , (1 << TTMP6_SAVED_STATUS_HALT_SHIFT)\n.set TTMP6_SAVED_TRAP_ID_SHIFT               , 25\n.set TTMP6_SAVED_TRAP_ID_SIZE                , 4\n.set TTMP6_SAVED_TRAP_ID_MASK                , (((1 << TTMP6_SAVED_TRAP_ID_SIZE) - 1) << TTMP6_SAVED_TRAP_ID_SHIFT)\n.set TTMP6_SAVED_TRAP_ID_BFE                 , (TTMP6_SAVED_TRAP_ID_SHIFT | (TTMP6_SAVED_TRAP_ID_SIZE << 16))\n\n.set TTMP_PC_HI_SHIFT                        , 7\n.set TTMP_DEBUG_ENABLED_SHIFT                , 23\n\n.if .amdgcn.gfx_generation_number == 9\n  .set TTMP_SAVE_RCNT_FIRST_REPLAY_SHIFT     , 26\n  .set SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT     , 15\n  .set SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK , 0x1F8000\n.elseif .amdgcn.gfx_generation_number == 10 && .amdgcn.gfx_generation_minor < 3\n  .set TTMP_SAVE_REPLAY_W64H_SHIFT           , 31\n  .set TTMP_SAVE_RCNT_FIRST_REPLAY_SHIFT     , 24\n  .set SQ_WAVE_IB_STS_REPLAY_W64H_SHIFT      , 25\n  .set SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT     , 15\n  .set SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK , 0x3F8000\n  .set SQ_WAVE_IB_STS_REPLAY_W64H_MASK       , 0x2000000\n.endif\n\n// Defining TTMP_REG1 and TTMP_REG2 for clarity in comments\n// TTMP_REG1 means ttmp6 register if gfx>=942 and means ttmp13 register if gfx<942\n// TTMP_REG2 means ttmp11 register if gfx>=942 and means ttmp6 register if gfx<942\n\n.if .amdgcn.gfx_generation_number == 9\n  .set TTMP11_TTMPS_SETUP_SHIFT              , 31\n\n.if (.amdgcn.gfx_generation_minor >= 4)\n  .set TTMP11_WAVE_IN_WG_MASK                , 0x3F\n\n  // Bit to indicate that this is a stochastic trap\n  .set TTMP13_PCS_IS_STOCHASTIC              , 21\n\n  // Bit to indicate that this is a host trap\n  .set TTMP13_PCS_IS_HOSTTRAP                , 22\n\n.else\n\n  // Bit to indicate that this is a host trap\n  .set TTMP11_PCS_IS_HOSTTRAP                , 22\n.endif\n.endif\n\n.if (.amdgcn.gfx_generation_number == 9)\n\n .macro S_LOAD_DWORD_PCS_TTMP_REG1 base, offset\n  .if (.amdgcn.gfx_generation_minor >= 4)\n     s_load_dword      ttmp6, \\base, \\offset\n  .else\n     s_load_dword      ttmp13,\\base, \\offset\n  .endif\n .endm\n\n .macro S_BITSET0_B32_PCS_TTMP_REG2 bit_index\n  .if (.amdgcn.gfx_generation_minor >= 4)\n     s_bitset0_b32     ttmp11, \\bit_index\n  .else\n     s_bitset0_b32     ttmp6, \\bit_index\n  .endif\n .endm\n\n .macro S_BITSET1_B32_PCS_TTMP_REG2 bit_index\n  .if (.amdgcn.gfx_generation_minor >= 4)\n     s_bitset1_b32    ttmp11, \\bit_index\n  .else\n     s_bitset1_b32    ttmp6, \\bit_index\n  .endif\n .endm\n\n .macro S_CMP_GE_U32_PCS_TTMP_REG1 src0\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_cmp_ge_u32      \\src0, ttmp6\n  .else\n    s_cmp_ge_u32      \\src0, ttmp13\n  .endif\n .endm\n\n .macro S_MOV_B32_SRC_PCS_TTMP_REG1 src0\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_mov_b32        ttmp6, \\src0\n  .else\n    s_mov_b32        ttmp13, \\src0\n  .endif\n .endm\n\n .macro S_MOV_B32_DST_PCS_TTMP_REG1 dst\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_mov_b32       \\dst, ttmp6\n  .else\n    s_mov_b32       \\dst, ttmp13\n  .endif\n .endm\n\n .macro S_LSHR_B32_PCS_TTMP_REG1_REG2 src1\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_lshr_b32       ttmp6, ttmp11, \\src1\n  .else\n    s_lshr_b32       ttmp13, ttmp6, \\src1\n  .endif\n .endm\n\n .macro  S_STORE_DWORD_PCS_TTMP_REG1 base, offset\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_store_dword    ttmp6, \\base, \\offset\n  .else\n    s_store_dword    ttmp13, \\base, \\offset\n  .endif\n .endm\n\n .macro S_MULK_I32_PCS_TTMP_REG1 const_val\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_mulk_i32       ttmp6, \\const_val\n  .else\n    s_mulk_i32       ttmp13, \\const_val\n  .endif\n .endm\n\n .macro S_ADD_U32_PCS_TTMP_REG1  dst, src0\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_add_u32        \\dst, \\src0, ttmp6\n  .else\n    s_add_u32        \\dst, \\src0, ttmp13\n  .endif\n .endm\n\n .macro S_CMP_LG_U32_PCS_TTMP_REG1 src0\n  .if (.amdgcn.gfx_generation_minor >= 4)\n    s_cmp_lg_u32     \\src0, ttmp6\n  .else\n    s_cmp_lg_u32     \\src0, ttmp13\n  .endif\n .endm\n\n.endif\n\n// ABI between first and second level trap handler:\n//   ttmp0  = PC[31:0]\n//   ttmp8  = WorkgroupIdX\n//   ttmp9  = WorkgroupIdY\n//   ttmp10 = WorkgroupIdZ\n//   ttmp12 = SQ_WAVE_STATUS\n//   ttmp14 = TMA[31:0]\n//   ttmp15 = TMA[63:32]\n// gfx9:\n//   ttmp1 = 0[2:0], PCRewind[3:0], HostTrap[0], TrapId[7:0], PC[47:32]\n// For all gfx9 (except gfx940, gfx941, gfx942):\n//   ttmp6 = 0[6:0], DispatchPktIndx[24:0]\n//   ttmp11 = SQ_WAVE_IB_STS[20:15], 0[1:0], DebugEnabled[0], 0[15:0], NoScratch[0], WaveInWg[5:0]\n//\n// For gfx940/gfx941/gfx942:\n//   ttmp11 = 0[0], DispatchPktIndx[24:0], WaveIdInWg[5:0]\n//   ttmp13:\n//       Bits 31:26 : SQ_WAVE_IB_STS[20:15] (1TH)\n//            25:24 : 0 on 2TH entry. Used by 1st level TH but also\n//                    free to be used in the 2nd level TH\n//            23    : Debug Enabled (1TH)\n//            22:0  : values are unspecified on 2TH entry. Free.\n//\n// gfx10:\n//   ttmp1 = 0[0], PCRewind[5:0], HostTrap[0], TrapId[7:0], PC[47:32]\n//\n// gfx10/gfx11:\n//   ttmp6 = 0[6:0], DispatchPktIndx[24:0]\n//\n// gfx1010:\n//   ttmp11 = SQ_WAVE_IB_STS[25], SQ_WAVE_IB_STS[21:15], DebugEnabled[0], 0[15:0], NoScratch[0], WaveIdInWG[5:0]\n//\n// gfx1030/gfx1100:\n//   ttmp11 = 0[7:0], DebugEnabled[0], 0[15:0], NoScratch[0], WaveIdInWG[5:0]\n//\n// ttmp[14:15] points to TMA2; Available: ttmp[2:3], ttmp[4:5]\n//\n// ttmp7 : gfx9, gfx1010, gfx1030, gfx11 - 31:0 : PC[31:0]  (2TH, DBG);\n//       : gfx940 - free;\n//       : gfx12 - ttmp7 - 31:16 : workgroup_z[15:0]  (SPI) and 15:0 : workgroup_y[15:0]  (SPI)\n\ntrap_entry:\n  // Extract trap_id from ttmp2\n  s_bfe_u32                             ttmp2, ttmp1, SQ_WAVE_PC_HI_TRAP_ID_BFE\n  s_cbranch_scc0                        .not_s_trap                      // If trap_id == 0, it's not an s_trap nor host trap\n\n  // Check if the it was an host trap.\n  s_bitcmp1_b32                         ttmp1, SQ_WAVE_PC_HI_HT_SHIFT\n  s_cbranch_scc0                        .not_host_trap\n\n.if (.amdgcn.gfx_generation_number == 9) // PC_SAMPLING_GFX9\n  // ttmp[14:15] is TMA2; Available: ttmp[2:3], ttmp[4:5], ttmp7, TTMP_REG1\n  // Check if this is a host-trap. For now, if so, that means we are sampling\n  //\n  // TMA2 layout:\n  //   [0x00] out_buf_t* host_trap_buffers;\n  //   [0x08] out_buf_t* stochastic_trap_buffers;\n  //\n  // --- Start profile trap handlers GFX9 --- //\n  // If the wave entered the trap handler: \n  // If on gfx9:\n  // - Check SQ_WAVE_PC_HI_HT_SHIFT bit on TTMP1 register to\n  //   identify if it was a host trap.\n  // If a host trap is detected:\n  // - Mark TTMP13(gfx94x) or TTMP11(gfx9) hosttrap bit\n  // - Load host_trap_buffers\n  // - Branch to the profile trap handler logic.\n  //\n  // If on gfx9.4+:\n  // - Check TRAPSTS bit 26 (SQ_WAVE_TRAPSTS_PERF_SNAPSHOT_SHIFT) to\n  //   identify stochastic traps.\n  // If a stochastic trap is detected:\n  // - Set bit 21 in TTMP13 to indicate a stochastic trap.\n  // - Branch to the profile trap handler logic.\n\n  s_load_dwordx2                        ttmp[2:3], ttmp[14:15], 0 glc   // ttmp[14:15]=*host_trap_buffers\n.if .amdgcn.gfx_generation_minor >= 4\n  s_setreg_imm32_b32                    hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_HOST_TRAP_SHIFT, 1), 0\n  s_bitset0_b32                         ttmp13, TTMP13_PCS_IS_STOCHASTIC\n  s_bitset1_b32                         ttmp13, TTMP13_PCS_IS_HOSTTRAP   // set bit 22 in TTMP13\n.else\n  s_bitset1_b32                         ttmp11, TTMP11_PCS_IS_HOSTTRAP    // Set bit 22 in TTMP11\n.endif\n  s_waitcnt                             lgkmcnt(0)\n  s_mov_b64                             ttmp[14:15], ttmp[2:3]          //now ttmp[14:15] = host_trap_buffers\n  s_branch                              .profile_trap_handlers_gfx9     // Off to the profile handlers\n.else\n  // Ignore host traps.  They should be masked by the driver anyway.\n  s_branch .not_s_trap\n.endif\n\n.not_host_trap:\n  // It's an s_trap; advance the PC\n  s_add_u32                             ttmp0, ttmp0, 0x4\n  s_addc_u32                            ttmp1, ttmp1, 0x0\n\n  // If llvm.debugtrap and debugger is not attached.\n  s_cmp_eq_u32                          ttmp2, TRAP_ID_DEBUGTRAP\n  s_cbranch_scc0                        .no_skip_debugtrap\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor < 4) || .amdgcn.gfx_generation_number >= 10\n  s_bitcmp0_b32                         ttmp11, TTMP_DEBUG_ENABLED_SHIFT\n.else\n  s_bitcmp0_b32                         ttmp13, TTMP_DEBUG_ENABLED_SHIFT\n.endif\n  s_cbranch_scc0                        .no_skip_debugtrap\n\n  // Ignore llvm.debugtrap.\n  s_branch                              .exit_trap\n\n.not_s_trap:\n.if .amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4\n  //Check for stochastic trap on gfx9.4+\n  s_getreg_b32                          ttmp7, hwreg(HW_REG_TRAPSTS)             // On gfx94x, TRAPSTS bit 26 ...\n  s_bitcmp1_b32                         ttmp7, SQ_WAVE_TRAPSTS_PERF_SNAPSHOT_SHIFT   // is stochastic_sample_trap\n  s_cbranch_scc0                        .no_skip_debugtrap\n\n  // Handle stochastic trap\n  s_setreg_imm32_b32                    hwreg(HW_REG_TRAPSTS, SQ_WAVE_TRAPSTS_PERF_SNAPSHOT_SHIFT, 1), 0\n  s_load_dwordx2                        ttmp[2:3], ttmp[14:15], 0x8 glc // ttmp[14:15]=*stoch_trap_buf\n  s_bitset0_b32                         ttmp13, TTMP13_PCS_IS_HOSTTRAP\n  s_bitset1_b32                         ttmp13, TTMP13_PCS_IS_STOCHASTIC  // set bit 25 in TTMP13\n  s_waitcnt                             lgkmcnt(0)\n  s_mov_b64                             ttmp[14:15], ttmp[2:3]\n  s_branch                              .profile_trap_handlers_gfx9      // Off to the profile handlers\n.else\n  s_branch                              .no_skip_debugtrap\n.endif // PC_SAMPLING_GFX9\n\n.if (.amdgcn.gfx_generation_number == 9) // PC_SAMPLING_GFX9\n  // tma->host_trap_buffers Offsets:\n  //    [0x00]  uint64_t buf_write_val;\n  //    [0x08]  uint32_t buf_size;\n  //    [0x0c]  uint32_t reserved0;\n  //    [0x10]  uint32_t buf_written_val0;\n  //    [0x14]  uint32_t buf_watermark0;\n  //    [0x18]  hsa_signal_t done_sig0;\n  //    [0x20]  uint32_t buf_written_val1;\n  //    [0x24]  uint32_t buf_watermark1;\n  //    [0x28]  hsa_signal_t done_sig1;\n  //    [0x30]  uint8_t  reserved1[16];\n  //    [0x40]  sample_t buffer0[buf_size];\n  //    [0x40+(buf_size*sizeof(sample_t))]sample_t buffer1[buf_size];\n  //\n  //__global__ void profiling_trap_handler(out_buf_t* tma) {\n  //  uint64_t local_entry = atomicAdd(&tma->buf_write_val, 1);\n  //  int buf_to_use = local_entry >> 63;\n  //  local_entry &= (ULLONG_MAX >> 1);\n  //\n  //  if (local_entry < tma->buf_size) {\n  //    sample_t *buf_base = buf_to_use ? tma->buffer1 : tma->buffer0;\n  //    fill_sample(&buf_base[local_entry]); // reads TTMP11 as well\n  //\n  //    uint32_t * written = buf_to_use ? &(tma->buf_written_val1) :\n  //                                      &(tma->buf_written_val0);\n  //\n  //    uint64_t done = __atomic_fetch_add(&written, 1,\n  //                memory_order_release, memory_scope_system);\n  //\n  //    uint32_t watermark = buf_to_use ? tma->buf_watermark0 :\n  //                                      tma->buf_watermark1;\n  //    if (done == watermark) {\n  //       hsa_signal_t done_sig = buf_to_use ? tma->done_sig1 :\n  //                                            tma->done_sig0;\n  //       send_signal(done_sig);\n  //    }\n  //  }\n  //}\n\n  // ttmp[14:15] is tma->host_trap_buffers; Available: ttmp[2:3], ttmp[4:5], ttmp7, ttmp13\n.profile_trap_handlers_gfx9:\n  s_mov_b64                             ttmp[2:3], 1                    // atomic increment buf_write_val\n  s_atomic_add_x2                       ttmp[2:3], ttmp[14:15], glc     // ttmp[2:3] = packed local_entry\n  S_LOAD_DWORD_PCS_TTMP_REG1            ttmp[14:15], 0x8                // TTMP_REG1 = tma->buf_size\n  s_waitcnt                             lgkmcnt(0)\n  s_lshr_b32                            ttmp7, ttmp3, 31                // ttmp7 = buf_to_use\n  S_BITSET0_B32_PCS_TTMP_REG2           31                              // clear out TTMP_REG2  bit31\n  s_cmp_eq_u32                          ttmp7, 0                        // store off buf_to_use ...\n  s_cbranch_scc1                        .skip_ttmp_set_gfx9             // into bit31 of TTMP_REG2\n  S_BITSET1_B32_PCS_TTMP_REG2           31\n.skip_ttmp_set_gfx9:\n  s_bfe_u64                             ttmp[2:3], ttmp[2:3], (63<<16)  // ttmp[2:3] = new local_entry\n  s_cmp_lg_u32                          ttmp3, 0                        // if entry >= 2^32, always lost\n  s_cbranch_scc1                        .pc_sampling_exit\n  S_CMP_GE_U32_PCS_TTMP_REG1            ttmp2                           // if local_entry >= buf_size\n  s_cbranch_scc1                        .pc_sampling_exit\n\n  // ttmp2=local_entry, ttmp7=buf_to_use (also in bit31 of TTMP_REG2), TTMP_REG1=buf_size\n  // ttmp[14:15] is tma->host_trap_buffers. Available: ttmp3, ttmp[4:5]\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor == 4)\n  s_mul_i32                             ttmp6, ttmp6, ttmp7             // ttmp[4:5]=buf_size if ...\n  s_mul_i32                             ttmp4, ttmp6, 0x40              // buf_to_use=1, 0 otherwise\n  s_mul_hi_u32                          ttmp5, ttmp6, 0x40\n.else\n  s_mul_i32                             ttmp13, ttmp13, ttmp7           // ttmp[4:5]=buf_size if ...\n  s_mul_i32                             ttmp4, ttmp13, 0x40             // buf_to_use=1, 0 otherwise\n  s_mul_hi_u32                          ttmp5, ttmp13, 0x40\n.endif\n\n  s_add_u32                             ttmp4, ttmp4, 0x40              // now ttmp[4:5]=offset from ...\n  s_addc_u32                            ttmp5, ttmp5, 0                 // tma to start of target buffer;\n  s_add_u32                             ttmp4, ttmp14, ttmp4            // ttmp[4:5] now points to ...\n  s_addc_u32                            ttmp5, ttmp15, ttmp5            // buffer0 or buffer1\n  s_mov_b32                             ttmp7, ttmp2\n\n .if .amdgcn.gfx_generation_number == 9\n\n .if .amdgcn.gfx_generation_minor >= 4\n  // Check if it's a stochastic trap\n  s_bitcmp1_b32                         ttmp13, TTMP13_PCS_IS_STOCHASTIC\n  s_cbranch_scc1                        .fill_sample_stochastic\n  // Check if it's a host trap\n  s_bitcmp1_b32                         ttmp13, TTMP13_PCS_IS_HOSTTRAP\n  s_cbranch_scc1                        .fill_sample_hosttrap\n.else\n // Check if it's a host trap\n  s_bitcmp1_b32                         ttmp11, TTMP11_PCS_IS_HOSTTRAP\n  s_cbranch_scc1                        .fill_sample_hosttrap\n\n.endif\n.endif\n  // If neither bit is set, this is unexpected.\n  // This branch is not expected to be taken.\n  s_branch                              .no_skip_debugtrap\n\n  // ttmp7 contains local_entry, ttmp[4:5] contains \"&bufferX\",\n  // ttmp[14:15] holds 'tma->host_trap_buffers' pointer\n  // ttmp[2:3] and ttmp13 are available for gathering perf sample info\n  // ttmp[14:15] is live out\n\n  // fill_sample(...) - begin //\n  // typedef struct {\n  // [0x00]  uint64_t pc;\n  // [0x08]  uint64_t exec_mask;\n  // [0x10]  uint32_t workgroup_id_x;\n  // [0x14]  uint32_t workgroup_id_y;\n  // [0x18]  uint32_t workgroup_id_z;\n  // [0x1c]  uint32_t wave_in_wg : 6;\n  //         uint32_t chiplet    : 3;    // Currently not used\n  //         uint32_t reserved   : 23;\n  // [0x20]  uint32_t hw_id;\n  // [0x24]  uint32_t reserved0;\n  // [0x28]  uint64_t reserved1;\n  // [0x30]  uint64_t timestamp;\n  // [0x38]  uint64_t correlation_id;\n  // } perf_sample_hosttrap_v1_t;\n  //\n  // __device__ void fill_sample_hosttrap_v1(perf_sample_hosttrap_v1_t* buf) {\n  //    buf->pc = ((ttmp1 & 0xffff) << 32) | ttmp0;\n  //    buf->exec_mask = EXEC;\n  //    buf->workgroup_id_x = ttmp8;\n  //    buf->workgroup_id_y = ttmp9;\n  //    buf->workgroup_id_z = ttmp10;\n  //    buf->chiplet_and_wave_id = ttmp11 & 0x3f;\n  //    buf->hw_id = s_getreg_b32(HW_REG_HW_ID);\n  //    buf->timestamp = s_memrealtime;\n  //    buf->correlation_id = get_correlation_id();\n  // }\n.fill_sample_hosttrap:\n  s_mul_i32                             ttmp2, ttmp7, 0x40              // offset into buffer for 64B objects\n  s_mul_hi_u32                          ttmp3, ttmp7, 0x40              // ttmp[2:3] will contain byte ...\n  s_add_u32                             ttmp2, ttmp2, ttmp4\n  s_addc_u32                            ttmp3, ttmp3, ttmp5             // ttmp[2:3]=&bufferX[local_entry]\n  s_memrealtime                         ttmp[4:5]\n  s_and_b32                             ttmp1, ttmp1, 0xffff            // clear out extra data from PC_HI\n  s_store_dwordx2                       ttmp[0:1], ttmp[2:3]            // store PC\n  s_waitcnt                             lgkmcnt(0)                      // wait for timestamp\n  S_MOV_B32_SRC_PCS_TTMP_REG1           exec_lo\n  S_STORE_DWORD_PCS_TTMP_REG1           ttmp[2:3], 0x8                  // store EXEC_LO\n  S_MOV_B32_SRC_PCS_TTMP_REG1           exec_hi\n  S_STORE_DWORD_PCS_TTMP_REG1           ttmp[2:3], 0xc                  // store EXEC_HI\n  s_store_dwordx2                       ttmp[8:9], ttmp[2:3], 0x10      // store wg_id_x and wg_id_y\n  s_store_dword                         ttmp10, ttmp[2:3], 0x18         // store wg_id_z\n  s_store_dwordx2                       ttmp[4:5], ttmp[2:3], 0x30      // store timestamp\n\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_XCC_ID)     //store XCC_ID\n  s_lshl_b32                            ttmp4, ttmp4, 8\n  s_and_b32                             ttmp5, ttmp11, TTMP11_WAVE_IN_WG_MASK\n  s_or_b32                              ttmp4, ttmp4, ttmp5\n  s_store_dword                         ttmp4, ttmp[2:3], 0x1c          // store wave_in_wg\n.else\n  s_and_b32                             ttmp4, ttmp11, 0x3f\n  s_store_dword                         ttmp4, ttmp[2:3], 0x1c          // store wave_in_wg\n.endif\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_HW_ID)\n  s_store_dword                         ttmp4, ttmp[2:3], 0x20          // store HW_ID\n\n  s_branch                              .get_correlation_id\n\n.if .amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4\n.fill_sample_stochastic:\n  s_mul_i32                             ttmp2, ttmp7, 0x40              // offset into buffer for 64B objects\n  s_mul_hi_u32                          ttmp3, ttmp7, 0x40\n  s_add_u32                             ttmp2, ttmp2, ttmp4\n  s_addc_u32                            ttmp3, ttmp3, ttmp5             // ttmp[2:3]=&buffer[local_entry]\n  s_memrealtime                         ttmp[4:5]\n  s_waitcnt                             lgkmcnt(0)                      // Wait for timestamp\n  s_store_dwordx2                       ttmp[4:5], ttmp[2:3] 0x30       // Store timestamp\n\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_LO)\n  s_getreg_b32                          ttmp5, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_HI)\n  s_store_dwordx2                       ttmp[4:5], ttmp[2:3] 0x00       // store snapshot data\n  s_getreg_b32                          ttmp5, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA1)\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA)\n  s_store_dwordx2                       ttmp[4:5], ttmp[2:3], 0x24            // store snapshot PC\n\n  s_mov_b32                             ttmp6, exec_lo\n  s_store_dword                         ttmp6, ttmp[2:3], 0x8           // store EXEC_LO\n  s_mov_b32                             ttmp6, exec_hi\n  s_store_dword                         ttmp6, ttmp[2:3], 0xc           // store EXEC_HI\n\n  s_store_dwordx2                       ttmp[8:9], ttmp[2:3], 0x10      // store wg_id_x and wg_id_y\n  s_store_dword                         ttmp10, ttmp[2:3], 0x18         // store wg_id_z\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_XCC_ID)\n  s_lshl_b32                            ttmp4, ttmp4, 8\n  s_and_b32                             ttmp5, ttmp11, TTMP11_WAVE_IN_WG_MASK\n  s_or_b32                              ttmp4, ttmp4, ttmp5\n  s_store_dword                         ttmp4, ttmp[2:3], 0x1c          // store chiplet_and_wave_id\n  s_getreg_b32                          ttmp4, hwreg(HW_REG_HW_ID)\n  s_store_dword                         ttmp4, ttmp[2:3], 0x20          // store HW_ID\n  // ttmp[2:3]=&buffer[local_entry]; ttmp[4:5], ttmp[6:7] are free\n  // ttmp[14:15]=ptr to ‘tma’ and is live out; ttmp11.b31 is buf_to_use, 0 or 1\n  s_branch                              .get_correlation_id\n\n.endif\n\n.get_correlation_id:\n\n  // get_correlation_id() -- begin //\n  // Returns a value to use as a correlation ID.\n  // Returns a 64bit number made up of the 9-bit queue ID and the\n  // 25-bit dispatch_pkt concatenated together as:\n  // Upper 32 bits: {23 0s}{9b queue_id}\n  // Lower 32 bits: { 7 0s}{25b dispatch_pkt}\n  // __device__ uint64_t get_correlation_id() {\n  //   uint64_t output;\n  //   // Get bottom 10 bits of queue's doorbell, in doorbell region.\n  //   // Doorbell is 8B (3b per); region is 8K (13b total) so 10 bits.\n  //   output = s_sendmsg(MSG_GET_DOORBELL);\n  //   output &= 0x3ff;\n  //   output <<= 32;\n  //   // TTMP6 contains this packet dispatch ID modulus the queue size\n  //   output |= TTMP6;\n  //   return output;\n  // }\n\n  // ttmp[2:3] = &buffer[local_entry]\n  // ttmp[4:5], ttmp7, and ttmp13 are free\n  // ttmp[14:15] = tma->host_trap_buffers and is live out\n  // ttmp6.b31 is buf_to_use, 0 or 1 and is live out\n\n  s_mov_b64                             ttmp[4:5], exec                 // back up EXEC mask\n  s_mov_b32                             exec_lo, 0x80000000             // prepare EXEC for doorbell spin\n  s_sendmsg                             sendmsg(MSG_GET_DOORBELL)       // message 10, puts doorbell in EXEC\n.wait_for_doorbell:\n  s_nop                                 0x7                             // wait a bit for message to return\n  s_bitcmp0_b32                         exec_lo, 0x1f                   // returned message  will 0 bit 31\n  s_cbranch_scc0                        .wait_for_doorbell              // wait some more if no data yet\n  s_mov_b32                             exec_hi, ttmp5                  // do not care about message[63:32]\n  s_and_b32                             ttmp5, exec_lo, DOORBELL_ID_MASK // doorbell now in ttmp5\n  s_mov_b32                             exec_lo, ttmp4                  // exec mask restored\n\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n  s_bfe_u32                             ttmp4, ttmp11, (6 | 25 << 16)    // extract dispatch ID from ttmp11\n.else\n  s_and_b32                             ttmp4, ttmp6, 0x1ffffff         // extract low 25 bits from ttmp6 (DispatchPktIndx[24:0])\n.endif\n  s_store_dwordx2                       ttmp[4:5], ttmp[2:3], 0x38      // ttmp[4:5] is correlation ID. Store correlation_id to sample\n  // get_correlation_id() -- end //\n\n  // complete stores before returning\n  s_dcache_wb\n  s_waitcnt                             lgkmcnt(0)\n  // fill_sample(...) - end //\n\n  // ttmp[2:3], ttmp[4:5], ttmp7, and ttmp13 are free\n  // ttmp[14:15] = tma->host_trap_buffers; ttmp6.b31 is buf_to_use, 0 or 1\n  S_LSHR_B32_PCS_TTMP_REG1_REG2         31                              // TTMP_REG1 is buf_to_use\n  S_MULK_I32_PCS_TTMP_REG1              0x10                            // written_val0 to written_val_X\n  S_ADD_U32_PCS_TTMP_REG1               ttmp14, ttmp14                  // now ttmp[14:15] points to ...\n  s_addc_u32                            ttmp15, ttmp15, 0x0             // buf_written_valX-0x10\n  s_mov_b32                             ttmp7, 1                        // atomic increment buf_written_valX\n  s_atomic_add                          ttmp7, ttmp[14:15], 0x10 glc    // ttmp7 will contain 'done'\n  S_LOAD_DWORD_PCS_TTMP_REG1            ttmp[14:15], 0x14               // TTMP_REG1 will hold watermark\n  s_waitcnt                             lgkmcnt(0)\n  S_CMP_LG_U32_PCS_TTMP_REG1            ttmp7                          // if 'done' not at watermark, exit\n  s_cbranch_scc1                        .pc_sampling_exit\n\n  // ttmp[2:3], [4:5], ttmp7, and ttmp13 are free\n  // ttmp[14:15] = buf_written_valX-0x10\n\n  // send_signal(...) - begin //\n  //__device__ void send_signal(hsa_signal_t* signal) {\n  //\n  //   amd_signal_t *sig = (amd_signal_t *)signal->handle;\n  //   __atomic_store(&(sig->value), 0, memory_order_relaxed, memory_scope_system);\n  //   if (sig->event_mailbox_ptr != NULL && sig->event_id != NULL) {\n  //     uint32_t id = sig->event_id;\n  //     __atomic_store(sig->event_mailbox_ptr, id,\n  //            memory_order_relaxed, memory_scope_system);\n  //     __builtin_amdgcn_s_sendmsg(1, id);\n  //   }\n  //}\n  // We jump to the trap handler exit after this, so no live-out registers except\n  // those that must survive the trap handler\n\n  s_load_dwordx2                        ttmp[2:3], ttmp[14:15], 0x18    // load done_sig into ttmp[2:3]\n  s_waitcnt                             lgkmcnt(0)                      // it's actually an amd_signal_t*\n  s_load_dwordx2                        ttmp[4:5], ttmp[2:3], 0x10      // load event mailbox ptr into 4:5\n  s_load_dword                          ttmp7, ttmp[2:3], 0x18          // load event_id into ttmp7\n  s_mov_b64                             ttmp[14:15], 0\n  s_store_dwordx2                       ttmp[14:15], ttmp[2:3], 0x8 glc // zero out signal value\n  s_waitcnt                             lgkmcnt(0)                      // wait for value store to complete\n  s_cmp_eq_u64                          ttmp[4:5], 0\n  s_cbranch_scc1                        .pc_sampling_exit               // null mailbox means no interrupt\n  s_cmp_eq_u32                          ttmp7, 0\n  s_cbranch_scc1                        .pc_sampling_exit               // event_id zero means no interrupt\n  s_store_dword                         ttmp7, ttmp[4:5] glc            // send event ID to the mailbox\n  s_waitcnt                             lgkmcnt(0)\n  S_MOV_B32_SRC_PCS_TTMP_REG1           m0                              // save off m0\n  s_mov_b32                             m0, ttmp7                       // put ID into message payload\n  s_nop                                 0x0                             // Manually inserted wait states\n  s_sendmsg                             sendmsg(MSG_INTERRUPT)          // send interrupt message\n  s_waitcnt                             lgkmcnt(0)                      // wait for message to be sent\n  S_MOV_B32_DST_PCS_TTMP_REG1           m0                              // restore m0\n  // send_signal(...) - end //\n.pc_sampling_exit:\n  // We can receive regular exceptions while doing PC-Sampling so we need to make sure we\n  // handle these exceptions here\n  s_getreg_b32                          ttmp2, hwreg(HW_REG_TRAPSTS)\n  s_getreg_b32                          ttmp3, hwreg(HW_REG_MODE, SQ_WAVE_MODE_EXCP_EN_SHIFT, SQ_WAVE_MODE_EXCP_EN_SIZE) // ttmp3[7:0] = MODE.EXCP_EN\n  // Set bits corresponding to TRAPSTS.MEM_VIOL, TRAPSTS.ILLEGAL_INST and TRAPSTS.XNACK_ERROR\n  s_or_b32                              ttmp3, ttmp3, (1 << SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT | 1 << SQ_WAVE_TRAPSTS_ILLEGAL_INST_SHIFT | 1 << SQ_WAVE_TRAPSTS_XNACK_ERROR_SHIFT)\n  s_and_b32                             ttmp2, ttmp2, ttmp3\n  // SCC will be 1 if either a maskable instruction was set, or one of MEM_VIOL, ILL_INST, XNACK_ERROR\n  s_cbranch_scc1                        .no_skip_debugtrap              // if any of those are set, handle exceptions\n\n  // Check for maskable exceptions\n  s_getreg_b32                          ttmp3, hwreg(HW_REG_MODE, SQ_WAVE_MODE_EXCP_EN_SHIFT, SQ_WAVE_MODE_EXCP_EN_SIZE)\n  s_and_b32                             ttmp3, ttmp2, ttmp3\n  s_cbranch_scc1                        .no_skip_debugtrap\n\n  // Since we are in PC sampling, it is safe to ignore watch1/2/3 and single step\n  // as those should only be enabled by the debugger.\n  // We could add them for completeness, i.e. check MODE.DEBUG_EN (bit 11)\n  // and \"MODE.EXCP_EN.WATCH (bit 19) && (TRAPSTS.EXCP_HI.ADDR_WATCH1 (bit 12) || TRAPSTS.EXCP_HI.ADDR_WATCH2 (bit 13) || TRAPSTS.EXCP_HI.ADDR_WATCH3 (bit 14)).\n  s_branch                              .exit_trap\n\n.endif // PC_SAMPLING_GFX9\n.no_skip_debugtrap:\n  // Save trap id and halt status in ttmp6.\n  s_andn2_b32                           ttmp6, ttmp6, (TTMP6_SAVED_TRAP_ID_MASK | TTMP6_SAVED_STATUS_HALT_MASK)\n  s_bfe_u32                             ttmp2, ttmp1, SQ_WAVE_PC_HI_TRAP_ID_BFE\n  s_min_u32                             ttmp2, ttmp2, 0xF\n  s_lshl_b32                            ttmp2, ttmp2, TTMP6_SAVED_TRAP_ID_SHIFT\n  s_or_b32                              ttmp6, ttmp6, ttmp2\n  s_bfe_u32                             ttmp2, ttmp12, SQ_WAVE_STATUS_HALT_BFE\n  s_lshl_b32                            ttmp2, ttmp2, TTMP6_SAVED_STATUS_HALT_SHIFT\n  s_or_b32                              ttmp6, ttmp6, ttmp2\n\n  // Fetch doorbell id for our queue.\n.if .amdgcn.gfx_generation_number < 11\n  s_mov_b32                             ttmp2, exec_lo\n  s_mov_b32                             ttmp3, exec_hi\n  s_mov_b32                             exec_lo, 0x80000000\n  s_sendmsg                             sendmsg(MSG_GET_DOORBELL)\n.wait_sendmsg:\n  s_nop                                 0x7\n  s_bitcmp0_b32                         exec_lo, 0x1F\n  s_cbranch_scc0                        .wait_sendmsg\n  s_mov_b32                             exec_hi, ttmp3\n  // Restore exec_lo, move the doorbell_id into ttmp3\n  s_and_b32                             ttmp3, exec_lo, DOORBELL_ID_MASK\n  s_mov_b32                             exec_lo, ttmp2\n.else\n  s_sendmsg_rtn_b32                     ttmp3, sendmsg(MSG_RTN_GET_DOORBELL)\n  s_waitcnt                             lgkmcnt(0)\n  s_and_b32                             ttmp3, ttmp3, DOORBELL_ID_MASK\n.endif\n\n  // Map trap reason to an exception code.\n  s_getreg_b32                          ttmp2, hwreg(HW_REG_TRAPSTS)\n\n  s_bitcmp1_b32                         ttmp2, SQ_WAVE_TRAPSTS_XNACK_ERROR_SHIFT\n  s_cbranch_scc0                        .not_memory_violation\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_MEMORY_VIOLATION_M0\n\n  // Aperture violation requires XNACK_ERROR == 0.\n  s_branch                              .not_aperture_violation\n\n.not_memory_violation:\n  s_bitcmp1_b32                         ttmp2, SQ_WAVE_TRAPSTS_MEM_VIOL_SHIFT\n  s_cbranch_scc0                        .not_aperture_violation\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_APERTURE_VIOLATION_M0\n\n.not_aperture_violation:\n  s_bitcmp1_b32                         ttmp2, SQ_WAVE_TRAPSTS_ILLEGAL_INST_SHIFT\n  s_cbranch_scc0                        .not_illegal_instruction\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION_M0\n\n.not_illegal_instruction:\n  s_and_b32                             ttmp2, ttmp2, SQ_WAVE_TRAPSTS_MATH_EXCP\n  s_cbranch_scc0                        .not_math_exception\n  s_getreg_b32                          ttmp7, hwreg(HW_REG_MODE)\n  s_lshl_b32                            ttmp2, ttmp2, SQ_WAVE_MODE_EXCP_EN_SHIFT\n  s_and_b32                             ttmp2, ttmp2, ttmp7\n  s_cbranch_scc0                        .not_math_exception\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_MATH_ERROR_M0\n\n.not_math_exception:\n  s_bfe_u32                             ttmp2, ttmp6, TTMP6_SAVED_TRAP_ID_BFE\n  s_cmp_eq_u32                          ttmp2, TRAP_ID_ABORT\n  s_cbranch_scc0                        .not_abort_trap\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_ABORT_M0\n\n.not_abort_trap:\n  // If no other exception was flagged then report a generic error.\n  s_andn2_b32                           ttmp2, ttmp3, DOORBELL_ID_MASK\n  s_cbranch_scc1                        .send_interrupt\n  s_or_b32                              ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.send_interrupt:\n  // m0 = interrupt data = (exception_code << DOORBELL_ID_SIZE) | doorbell_id\n  s_mov_b32                             ttmp2, m0\n  s_mov_b32                             m0, ttmp3\n  s_nop                                 0x0                             // Manually inserted wait states\n  s_sendmsg                             sendmsg(MSG_INTERRUPT)\n  s_waitcnt                             lgkmcnt(0)                      // Wait for the message to go out.\n  s_mov_b32                             m0, ttmp2\n\n  // Parking the wave requires saving the original pc in the preserved ttmps.\n  // Register layout before parking the wave:\n  //\n  // ttmp7: 0[31:0]\n  // ttmp11: 1st_level_ttmp11[31:23] 0[15:0] 1st_level_ttmp11[6:0]\n  //\n  // After parking the wave:\n  //\n  // ttmp7:  pc_lo[31:0]\n  // ttmp11: 1st_level_ttmp11[31:23] pc_hi[15:0] 1st_level_ttmp11[6:0]\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor < 4) || (.amdgcn.gfx_generation_number == 10 && .amdgcn.gfx_generation_minor < 3) || (.amdgcn.gfx_generation_number == 11)\n  // Save the PC\n  s_mov_b32                             ttmp7, ttmp0\n  s_and_b32                             ttmp1, ttmp1, SQ_WAVE_PC_HI_ADDRESS_MASK\n  s_lshl_b32                            ttmp1, ttmp1, TTMP_PC_HI_SHIFT\n  s_andn2_b32                           ttmp11, ttmp11, (SQ_WAVE_PC_HI_ADDRESS_MASK << TTMP_PC_HI_SHIFT)\n  s_or_b32                              ttmp11, ttmp11, ttmp1\n\n  // Park the wave\n  s_getpc_b64                           [ttmp0, ttmp1]\n  s_add_u32                             ttmp0, ttmp0, .parked - .\n  s_addc_u32                            ttmp1, ttmp1, 0x0\n.endif\n\n.halt_wave:\n  // Halt the wavefront upon restoring STATUS below.\n  s_bitset1_b32                         ttmp6, TTMP6_WAVE_STOPPED_SHIFT\n  s_bitset1_b32                         ttmp12, SQ_WAVE_STATUS_HALT_SHIFT\n  // Set WAVE.SKIP_EXPORT as a maker so the debugger knows the trap handler was\n  // entered and has decided to halt the wavee.\n  s_bitset1_b32                         ttmp12, SQ_WAVE_STATUS_TRAP_SKIP_EXPORT_SHIFT\n\n.if (.amdgcn.gfx_generation_number == 9 && .amdgcn.gfx_generation_minor >= 4)\n  s_bitcmp1_b32                         ttmp11, TTMP11_TTMPS_SETUP_SHIFT\n  s_cbranch_scc1                        .ttmps_initialized\n  s_mov_b32                             ttmp4, 0\n  s_mov_b32                             ttmp5, 0\n  s_bitset0_b32                         ttmp6, TTMP6_SPI_TTMPS_SETUP_DISABLED_SHIFT\n  s_bitset1_b32                         ttmp11, TTMP11_TTMPS_SETUP_SHIFT\n.ttmps_initialized:\n.endif\n\n.exit_trap:\n  // Restore SQ_WAVE_IB_STS.\n.if .amdgcn.gfx_generation_number == 9\n.if .amdgcn.gfx_generation_minor < 4\n  s_lshr_b32                            ttmp2, ttmp11, (TTMP_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)\n.else\n  s_lshr_b32                            ttmp2, ttmp13, (TTMP_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)\n.endif\n  s_and_b32                             ttmp2, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK\n  s_setreg_b32                          hwreg(HW_REG_IB_STS), ttmp2\n.elseif .amdgcn.gfx_generation_number == 10 && .amdgcn.gfx_generation_minor < 3\n  s_lshr_b32                            ttmp2, ttmp11, (TTMP_SAVE_RCNT_FIRST_REPLAY_SHIFT - SQ_WAVE_IB_STS_FIRST_REPLAY_SHIFT)\n  s_and_b32                             ttmp3, ttmp2, SQ_WAVE_IB_STS_RCNT_FIRST_REPLAY_MASK\n  s_lshr_b32                            ttmp2, ttmp11, (TTMP_SAVE_REPLAY_W64H_SHIFT - SQ_WAVE_IB_STS_REPLAY_W64H_SHIFT)\n  s_and_b32                             ttmp2, ttmp2, SQ_WAVE_IB_STS_REPLAY_W64H_MASK\n  s_or_b32                              ttmp2, ttmp2, ttmp3\n  s_setreg_b32                          hwreg(HW_REG_IB_STS), ttmp2\n.endif\n\n  // Restore SQ_WAVE_STATUS.\n  s_and_b64                             exec, exec, exec               // restore STATUS.EXECZ, not writable by s_setreg_b32\n  s_and_b64                             vcc, vcc, vcc                  // restore STATUS.VCCZ, not writable by s_setreg_b32\n  s_setreg_b32                          hwreg(HW_REG_STATUS), ttmp12\n\n  // Return to original (possibly modified) PC.\n  s_rfe_b64                             [ttmp0, ttmp1]\n\n.parked:\n  s_trap                                0x2\n  s_branch                              .parked\n\n// For gfx11, add padding instructions so we can ensure instruction cache\n// prefetch always has something to load.\n.if .amdgcn.gfx_generation_number == 11\n.rept (256 - ((. - trap_entry) % 64)) / 4\n  s_code_end\n.endr\n.endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/runtime/trap_handler/trap_handler_gfx12.s",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n/// Trap Handler V2 source\n.set DOORBELL_ID_SIZE                          , 10\n.set DOORBELL_ID_MASK                          , ((1 << DOORBELL_ID_SIZE) - 1)\n.set EC_QUEUE_WAVE_ABORT_M0                    , (1 << (DOORBELL_ID_SIZE + 0))\n.set EC_QUEUE_WAVE_TRAP_M0                     , (1 << (DOORBELL_ID_SIZE + 1))\n.set EC_QUEUE_WAVE_MATH_ERROR_M0               , (1 << (DOORBELL_ID_SIZE + 2))\n.set EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION_M0      , (1 << (DOORBELL_ID_SIZE + 3))\n.set EC_QUEUE_WAVE_MEMORY_VIOLATION_M0         , (1 << (DOORBELL_ID_SIZE + 4))\n.set EC_QUEUE_WAVE_APERTURE_VIOLATION_M0       , (1 << (DOORBELL_ID_SIZE + 5))\n\n.set SQ_WAVE_EXCP_FLAG_PRIV_ADDR_WATCH_MASK    , (1 << 4) - 1\n.set SQ_WAVE_EXCP_FLAG_PRIV_MEMVIOL_SHIFT      , 4\n.set SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_SHIFT , 6\n.set SQ_WAVE_EXCP_FLAG_PRIV_HT_SHIFT           , 7\n.set SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT   , 8\n.set SQ_WAVE_EXCP_FLAG_PRIV_WAVE_END_SHIFT     , 9\n.set SQ_WAVE_EXCP_FLAG_PRIV_PERF_SNAPSHOT      , 10\n.set SQ_WAVE_EXCP_FLAG_PRIV_TRAP_AFTER_INST_SHIFT , 11\n.set SQ_WAVE_EXCP_FLAG_PRIV_XNACK_ERROR_SHIFT  , 12\n\n.set SQ_WAVE_EXCP_FLAG_USER_MATH_EXCP_SHIFT    , 0\n.set SQ_WAVE_EXCP_FLAG_USER_MATH_EXCP_SIZE     , 7\n\n.set SQ_WAVE_TRAP_CTRL_MATH_EXCP_MASK          , ((1 << 7) - 1)\n.set SQ_WAVE_TRAP_CTRL_ADDR_WATCH_SHIFT        , 7\n.set SQ_WAVE_TRAP_CTRL_WAVE_END_SHIFT          , 8\n.set SQ_WAVE_TRAP_CTRL_TRAP_AFTER_INST         , 9\n\n.set SQ_WAVE_PC_HI_ADDRESS_MASK                , 0xFFFF\n.set SQ_WAVE_PC_HI_TRAP_ID_BFE                 , (SQ_WAVE_PC_HI_TRAP_ID_SHIFT | (SQ_WAVE_PC_HI_TRAP_ID_SIZE << 16))\n.set SQ_WAVE_PC_HI_TRAP_ID_SHIFT               , 28\n.set SQ_WAVE_PC_HI_TRAP_ID_SIZE                , 4\n.set SQ_WAVE_STATE_PRIV_HALT_BFE               , (SQ_WAVE_STATE_PRIV_HALT_SHIFT | (1 << 16))\n.set SQ_WAVE_STATE_PRIV_HALT_SHIFT             , 14\n.set SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_SHIFT , 2\n\n.set TRAP_ID_ABORT                             , 2\n.set TRAP_ID_DEBUGTRAP                         , 3\n.set TTMP6_SAVED_STATUS_HALT_MASK              , (1 << TTMP6_SAVED_STATUS_HALT_SHIFT)\n.set TTMP6_SAVED_STATUS_HALT_SHIFT             , 29\n.set TTMP6_SAVED_TRAP_ID_BFE                   , (TTMP6_SAVED_TRAP_ID_SHIFT | (TTMP6_SAVED_TRAP_ID_SIZE << 16))\n.set TTMP6_SAVED_TRAP_ID_MASK                  , (((1 << TTMP6_SAVED_TRAP_ID_SIZE) - 1) << TTMP6_SAVED_TRAP_ID_SHIFT)\n.set TTMP6_SAVED_TRAP_ID_SHIFT                 , 25\n.set TTMP6_SAVED_TRAP_ID_SIZE                  , 4\n.set TTMP6_WAVE_STOPPED_SHIFT                  , 30\n.set TTMP8_DEBUG_FLAG_SHIFT                    , 31\n.set TTMP11_DEBUG_ENABLED_SHIFT                , 23\n.set TTMP_PC_HI_SHIFT                          , 7\n\n.set TTMP13_HT_FLAG_BIT                        , 22           // TTMP13 bit for host‑trap\n.set TTMP13_STOCH_FLAG_BIT                     , 21           // TTMP13 bit for stochastic\n.set TTMP13_BUF_FULL_BIT                       , 31           // TTMP13 bit – buf full mark\n.set TTMP8_DISPATCH_ID_MASK                    , 0X1FFFFFF\n// Per-sample data layout within the device buffer. Each sample is 64 bytes.\n// These are offsets from the start of a specific sample slot in the device buffer.\n\n.set SAMPLE_OFF_BYTES_PER_SAMPLE               , 0x40         // bytes per sample slot\n\n.set SAMPLE_OFF_PC_HOST                        , 0x00         // original PC (host only)\n.set SAMPLE_OFF_EXEC_LOHI                      , 0x08         // saved EXEC low/high\n.set SAMPLE_OFF_WGID_XY                        , 0x10         // WG id X / Y\n.set SAMPLE_OFF_WGID_Z_WAVE                    , 0x18         // WG id Z\n.set SAMPLE_OFF_TIMESTAMP                      , 0x30         // 64 bit realtime counter\n.set SAMPLE_OFF_HW_ID                          , 0x20         // HW_ID (values combined from the HW_ID1 + HW_ID2)\n.set SAMPLE_OFF_SNAPSHOT_DATA                  , 0x24\n.set SAMPLE_OFF_CORRELATION                    , 0x38         // doorbell + dispatch id\n.set SAMPLE_OFF_BUF_WRITTEN_VAL                , 0x10         // Offset to buf_written_val0/1 in pcs_sampling_data_t\n.set SAMPLE_OFF_BUF_SIZE                       , 0x8          // Offset to buf_size in pcs_sampling_data_t\n.set SAMPLE_OFF_DONE_SIG0                      , 0x18         // Offset for done_sig0 (hsa_signal_t handle for buffer 0)\n.set SAMPLE_OFF_DONE_SIG1                      , 0x28         // Offset for done_sig1 (hsa_signal_t handle for buffer 1)\n.set SAMPLE_OFF_SIGNAL_VALUE                   , 0x8          // Offset within signal structure to value field\n.set SAMPLE_OFF_EVENT_MAILBOX0                 , 0x10         // Offset for event mailbox pointer for buffer 0\n.set SAMPLE_OFF_EVENT_MAILBOX1                 , 0x20         // Offset for event mailbox pointer for buffer 1\n\n.set WAVE_ID_MASK                              , 0x1f         // Mask to extract Wave ID from TTMP register.\n.set BUF_INDEX_MASK                            , 0x7fffffff   // strip bit31 from add_x2\n.set SAMPLE_OFF_BUF_WRITTEN_VAL                , 0x10         // Offset to buf_written_val0/1 in pcs_sampling_data_t\n.set SAMPLE_INDEX_WIDTH                        , 31           // The sample index is 63 bits; the high part is 31 bits.\n\n.set HW_REG_SHADER_HW_ID1                      , 0xf817\n.set HW_REG_SHADER_HW_ID2                      , 0xf818\n.set HW_REG_SQ_PERF_SNAPSHOT_PC_LO             , 0xf80b\n.set HW_REG_SQ_PERF_SNAPSHOT_PC_HI             , 0xf80c\n.set HW_REG_SQ_PERF_SNAPSHOT_DATA1             , 0xf80f\n.set HW_REG_SQ_PERF_SNAPSHOT_DATA2             , 0xf810\n.set HW_REG_SQ_PERF_SNAPSHOT_DATA              , 0xf81b\n\n  // Macro to store the Correlation ID (Dispatch ID and Doorbell ID) into the current sample slot\n  //\n  // Assumes the following registers are set before it is called:\n  //   v[0:1]:Must contain the 64-bit base address of the target sample slot\n  //   ttmp8 :Must contain the dispatch ID in bits [24:0]\n  //   exec  :Must be set to 0x1 to ensure operations apply only to lane 0\n  //\n  // Clobbers the following registers:\n  //   v[2:3]:Used for [dispatch_id, doorbell_id]\n  //   ttmp6 :Used as scratch register\n.macro STORE_CORRELATION_ID\n  s_sendmsg_rtn_b32 ttmp6, sendmsg(MSG_RTN_GET_DOORBELL)    // Gets current queue's doorbell ID into ttmp6.\n  s_wait_kmcnt      0\n  s_and_b32         ttmp6, ttmp6, DOORBELL_ID_MASK          // Mask to get actual doorbell ID.\n  v_writelane_b32   v3, ttmp6, 0                            // Store doorbell ID into high part of v[2:3] (via v3).\n  s_and_b32         ttmp6, ttmp8, TTMP8_DISPATCH_ID_MASK    // Get dispatch ID from ttmp8 into ttmp6\n  v_writelane_b32   v2, ttmp6, 0                            // Store dispatch ID into low part of v[2:3] (via v2)\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_CORRELATION, scope:SCOPE_SYS  // Store {dispatch_id, doorbell_id} into sample slot.\n                                                                       // v[0:1] = sample slot base address.\n                                                                       // v[2] = dispatch_id, v[3] = doorbell_id.\n.endm\n\n  // Macro to store the HW_ID registers into the current sample slot\n  //\n  // Assumes the following registers are set before it is called:\n  //   v[0:1]: Must contain the 64-bit base address of the target sample slot.\n  //   exec  : Must be set to 0x1 to ensure operations apply only to lane 0.\n  //\n  // Clobbers the following registers:\n  //   v[2:3]: Used to stage the data for the global store.\n  //   ttmp6 : Used as scratch registers.\n.macro STORE_HW_ID\n  // Current ROCr API determines single dword for HW_ID, while this information is scattered accross two\n  // dword registers HW_ID1 and HW_ID2 on GFX10+ architectures.\n  // Thus, we combine values from HW_ID1 and HW_ID2 into a single dword HW_ID with the following layout:\n  // WAVE_ID[4:0]\n  // QUEUE_ID[8:5]\n  // RESERVED [9]\n  // WGP_ID[13:10]\n  // SIMD_ID[15:14]\n  // SA_ID[16]\n  // ME_ID[17]\n  // SE_ID[19:18]\n  // PIPE_ID[21:20]\n  // RESERVED [22]\n  // WG_ID[27:23]\n  // VM_ID[31:28]\n\n  // Note: We don't show DP_RATE and STATE_ID that are useless for compute kernels\n  // Also, we reduced SE_ID to 2 bits as there's only a maximum of 4 SEs on existing gfx12.0 parts\n  // Finally, ME_ID is reduced to 1 bit as wavefronts are dispatched from either ME0 or ME1 in gfx12.\n  // Bits 9 and 22 are reserved for a future use.\n\n  s_getreg_b32      ttmp6, HW_REG_SHADER_HW_ID1             // Put HW_ID1 in ttmp6\n  v_and_b32         v2, ttmp6, 0x1feffcff                   // Mask DP_RATE, SE_ID[2] and SIMD_ID\n  v_and_b32         v3, ttmp6, 0x300                        // Put SIMD_ID into ttmp6[8:9]\n  v_lshl_or_b32     v2, v3, 6, v2                           // Put SIMD_ID into v2[15:14]\n  s_getreg_b32      ttmp6, HW_REG_SHADER_HW_ID2             // Put HW_ID2 in ttmp6\n  v_and_b32         v3, ttmp6, 0xf000000                    // v3 = VM_ID in bits 27:24\n  v_lshl_or_b32     v2, v3, 4, v2                           // Put VM_ID into v2[31:28]\n  v_and_b32         v3, ttmp6, 0x1f0000                     // v3 = WG_ID in bits 20:16\n  v_lshl_or_b32     v2, v3, 7, v2                           // Put WG_ID in v2[27:23]\n  v_and_b32         v3, ttmp6, 0x100                        // v3 = ME_ID[0] in bit 8\n  v_lshl_or_b32     v2, v3, 9, v2                           // Put ME_ID in v2[17]\n  v_and_b32         v3, ttmp6, 0x30                         // v3 = PIPE_ID in bits 5:4\n  v_lshl_or_b32     v2, v3, 16, v2                          // Put PIPE_ID in v2[21:20]\n  v_and_b32         v3, ttmp6, 0xf                          // v3 = QUEUE_ID in bits 3:0\n  v_lshl_or_b32     v2, v3, 5, v2                           // Put QUEUE_ID in v2[8:5]\n  global_store_b32  v[0:1], v2, off, offset:SAMPLE_OFF_HW_ID, scope:SCOPE_SYS  // store HW_ID\n.endm\n\n// ABI (Application Binary Interface) between first and second-level trap handler:\n//   ttmp0: PC_LO[31:0] (Program Counter Low)\n//   ttmp1: PC_HI[15:0] (Program Counter High, bits 0-15), TrapID[3:0] (in bits 28-31 of original PC_HI)\n//   ttmp11: 0[7:0], DebugEnabled[0], 0[15:0], NoScratch[0], 0[5:0]\n//   ttmp12: SQ_WAVE_STATE_PRIV (Private wave state register value).\n//   ttmp14: TMA[31:0] - TMA_LO (Trap Memory Argument Low - base address for trap handler data, low 32 bits).\n//   ttmp15: TTMA[63:32] - TMA_HI (Trap Memory Argument High - base address for trap handler data, high 32 bits).\n//   For PC Sampling, this points to pcs_hosttrap_data_ or pcs_stochastic_data_\n trap_entry:\n\n  s_mov_b32         ttmp3, 0\n\n.check_hosttrap:\n\n  // ttmp[14:15] points to TMA.\n  // Available: ttmp[2:3], ttmp[4:5], ttmp6, ttmp[10:11]\n  s_getreg_b32      ttmp2, hwreg(HW_REG_EXCP_FLAG_PRIV)     // On gfx12, EXCP_FLAG_PRIV.b7\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_HT_SHIFT\n  s_cbranch_scc0    .check_stochastic\n\n  // It's a Host Trap event.\n  s_load_b64        ttmp[14:15], ttmp[14:15], 0x0, scope:SCOPE_CU         // ttmp[14:15]=*host_trap_buffers\n  s_bitset1_b32     ttmp13, TTMP13_HT_FLAG_BIT              // set bit 22 in TTMP13\n\n  // Clear the Host Trap flag in the hardware register to acknowledge the event\n  s_setreg_imm32_b32 hwreg(HW_REG_EXCP_FLAG_PRIV, SQ_WAVE_EXCP_FLAG_PRIV_HT_SHIFT,1), 0\n  s_wait_kmcnt      0                                       // Ensure previous load is complete.\n  s_branch          .profile_trap_handlers\n\n.check_stochastic:\n  s_getreg_b32      ttmp2, hwreg(HW_REG_EXCP_FLAG_PRIV)     // EXCP_FLAG_PRIV.b10=stochastic_sample_trap\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_PERF_SNAPSHOT // Test Performance Snapshot bit.\n\n  s_cbranch_scc0    .check_exceptions                       // If not Stochastic, check for other exceptions.\n\n  s_load_b64           ttmp[14:15], ttmp[14:15], 0x8, scope:SCOPE_CU         // ttmp[14:15]=*stoch_trap_buf\n  s_wait_kmcnt      0\n\n  s_bitset1_b32     ttmp13, TTMP13_STOCH_FLAG_BIT           // set bit 21 in TTMP13\n\n  s_setreg_imm32_b32 hwreg(HW_REG_EXCP_FLAG_PRIV, SQ_WAVE_EXCP_FLAG_PRIV_PERF_SNAPSHOT,1), 0 // Clear the perf_snapshot flag\n  s_branch          .profile_trap_handlers\n\n  // Check if this is a trap (s_trap instruction) or a hardware exception.\n  // Extract TrapID from ttmp1 (which contains PC_HI).\n  // Branch if not a trap (an exception instead).\n  s_bfe_u32         ttmp2, ttmp1, SQ_WAVE_PC_HI_TRAP_ID_BFE // ttmp2 = TrapID\n  s_cbranch_scc0       .check_exceptions\t\t\t             // If TrapID is 0, it's an exception, so branch.\n\n  // If caused by s_trap then advance PC, then figure out the trap ID:\n  // - if trapID is DEBUGTRAP and debugger is attach, report WAVE_TRAP,\n  // - if trapID is ABORTTRAP, report WAVE_ABORT,\n  // - report WAVE_TRAP for any other trap ID.\n  s_add_u32         ttmp0, ttmp0, 0x4                       // PC_LO += 4\n  s_addc_u32        ttmp1, ttmp1, 0x0                       // PC_HI += carry.\n\n  // If llvm.debugtrap and debugger is not attached.\n  s_cmp_eq_u32      ttmp2, TRAP_ID_DEBUGTRAP\n  s_cbranch_scc0    .not_debug_trap\n\n  s_bitcmp1_b32     ttmp11, TTMP11_DEBUG_ENABLED_SHIFT\n  s_cbranch_scc0    .check_exceptions\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.not_debug_trap:\n  s_cmp_eq_u32      ttmp2, TRAP_ID_ABORT\n  s_cbranch_scc0    .not_abort_trap\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_ABORT_M0\n  s_branch          .check_exceptions\n\n.not_abort_trap:\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n  s_bitcmp1_b32     ttmp8, TTMP8_DEBUG_FLAG_SHIFT\n  s_cbranch_scc0    .check_exceptions\n\n.check_exceptions:\n  s_getreg_b32      ttmp2, hwreg(HW_REG_EXCP_FLAG_PRIV)\n  s_getreg_b32      ttmp13, hwreg(HW_REG_TRAP_CTRL)\n\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_XNACK_ERROR_SHIFT\n  s_cbranch_scc0    .not_memory_violation\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_MEMORY_VIOLATION_M0\n\n  // Aperture violation requires XNACK_ERROR == 0.\n  s_branch          .not_aperture_violation\n\n.not_memory_violation:\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_MEMVIOL_SHIFT\n  s_cbranch_scc0    .not_aperture_violation\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_APERTURE_VIOLATION_M0\n\n.not_aperture_violation:\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_ILLEGAL_INST_SHIFT\n  s_cbranch_scc0    .not_illegal_instruction\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION_M0\n\n.not_illegal_instruction:\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT\n  s_cbranch_scc0    .not_wave_end\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.not_wave_start:\n  s_bitcmp1_b32     ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_WAVE_END_SHIFT\n  s_cbranch_scc0    .not_wave_end\n  s_bitcmp1_b32     ttmp13, SQ_WAVE_TRAP_CTRL_WAVE_END_SHIFT\n  s_cbranch_scc0    .not_wave_end\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.not_wave_end:\n  s_bitcmp1_b32     ttmp13, SQ_WAVE_TRAP_CTRL_TRAP_AFTER_INST\n  s_cbranch_scc0    .not_trap_after_inst\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.not_trap_after_inst:\n  s_and_b32         ttmp2, ttmp2, SQ_WAVE_EXCP_FLAG_PRIV_ADDR_WATCH_MASK\n  s_cbranch_scc0    .not_addr_watch\n  s_bitcmp1_b32     ttmp13, SQ_WAVE_TRAP_CTRL_ADDR_WATCH_SHIFT\n  s_cbranch_scc0    .not_addr_watch\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_TRAP_M0\n\n.not_addr_watch:\n  s_getreg_b32      ttmp2, hwreg(HW_REG_EXCP_FLAG_USER, SQ_WAVE_EXCP_FLAG_USER_MATH_EXCP_SHIFT, SQ_WAVE_EXCP_FLAG_USER_MATH_EXCP_SIZE)\n  s_and_b32         ttmp13, ttmp13, SQ_WAVE_TRAP_CTRL_MATH_EXCP_MASK\n  s_and_b32         ttmp2, ttmp2, ttmp13\n  s_cbranch_scc0    .not_math_exception\n  s_or_b32          ttmp3, ttmp3, EC_QUEUE_WAVE_MATH_ERROR_M0\n\n.not_math_exception:\n  s_cmp_eq_u32      ttmp3, 0\n  // This was not a s_trap we are interested in or an exception, return to\n  // the user code.\n  s_cbranch_scc1    .exit_trap\n\n.send_interrupt:\n  // Fetch doorbell id for our queue.\n  s_sendmsg_rtn_b32 ttmp2, sendmsg(MSG_RTN_GET_DOORBELL)\n  s_wait_kmcnt      0\n  s_and_b32         ttmp2, ttmp2, DOORBELL_ID_MASK\n  s_or_b32          ttmp3, ttmp2, ttmp3\n\n  // Save trap id and halt status in ttmp6.\n  s_andn2_b32       ttmp6, ttmp6, (TTMP6_SAVED_TRAP_ID_MASK | TTMP6_SAVED_STATUS_HALT_MASK)\n  s_bfe_u32         ttmp2, ttmp1, SQ_WAVE_PC_HI_TRAP_ID_BFE\n  s_min_u32         ttmp2, ttmp2, 0xF\n  s_lshl_b32        ttmp2, ttmp2, TTMP6_SAVED_TRAP_ID_SHIFT\n  s_or_b32          ttmp6, ttmp6, ttmp2\n  s_bfe_u32         ttmp2, ttmp12, SQ_WAVE_STATE_PRIV_HALT_BFE\n  s_lshl_b32        ttmp2, ttmp2, TTMP6_SAVED_STATUS_HALT_SHIFT\n  s_or_b32          ttmp6, ttmp6, ttmp2\n\n  // m0 = interrupt data = (exception_code << DOORBELL_ID_SIZE) | doorbell_id\n  s_mov_b32         ttmp2, m0\n  s_mov_b32         m0, ttmp3\n  s_sendmsg         sendmsg(MSG_INTERRUPT)\n  // Wait for the message to go out.\n  s_wait_kmcnt      0\n  s_mov_b32         m0, ttmp2\n\n  // Parking the wave requires saving the original pc in the preserved ttmps.\n  // Register layout before parking the wave:\n  //\n  // ttmp10: ?[31:0]\n  // ttmp11: 1st_level_ttmp11[31:23] 0[15:0] 1st_level_ttmp11[6:0]\n  //\n  // After parking the wave:\n  //\n  // ttmp10: pc_lo[31:0]\n  // ttmp11: 1st_level_ttmp11[31:23] pc_hi[15:0] 1st_level_ttmp11[6:0]\n  //\n  // Save the PC\n  s_mov_b32         ttmp10, ttmp0\n  s_and_b32         ttmp1, ttmp1, SQ_WAVE_PC_HI_ADDRESS_MASK\n  s_lshl_b32        ttmp1, ttmp1, TTMP_PC_HI_SHIFT\n  s_andn2_b32       ttmp11, ttmp11, (SQ_WAVE_PC_HI_ADDRESS_MASK << TTMP_PC_HI_SHIFT)\n  s_or_b32          ttmp11, ttmp11, ttmp1\n\n  // Park the wave\n  s_getpc_b64       [ttmp0, ttmp1]\n  s_add_u32         ttmp0, ttmp0, .parked - .\n  s_addc_u32        ttmp1, ttmp1, 0x0\n\n.halt_wave:\n  // Halt the wavefront upon restoring STATUS below.\n  s_bitset1_b32     ttmp6, TTMP6_WAVE_STOPPED_SHIFT\n  s_bitset1_b32     ttmp12, SQ_WAVE_STATE_PRIV_HALT_SHIFT\n\n  // Initialize TTMP registers\n  s_bitcmp1_b32     ttmp8, TTMP8_DEBUG_FLAG_SHIFT\n  s_cbranch_scc1    .ttmps_initialized\n  s_mov_b32         ttmp4, 0\n  s_mov_b32         ttmp5, 0\n  s_bitset1_b32     ttmp8, TTMP8_DEBUG_FLAG_SHIFT\n.ttmps_initialized:\n  s_branch          .exit_trap\n\n.profile_trap_handlers:\n  // Register state at the start of profile_trap_handlers:\n  //\n  // ttmp0:  PC_LO[31:0] - Contains program counter low bits\n  // ttmp1:  PC_HI[15:0] - Contains program counter high bits\n  // ttmp2:  Contains HW_REG_EXCP_FLAG_PRIV\n  // ttmp3:  Initialized to 0, available for use\n  // ttmp4:  Available - Can be freely used\n  // ttmp5:  Available - Can be freely used\n  // ttmp6:  Initially contains flags  - trap ID and halt status - reused after saving\n  // ttmp7:  Contains WGID_Y in high 16 bits, WGID_Z in low 16 bits\n  // ttmp8:  Contains dispatch ID in bits [24:0] and debug flag\n  // ttmp9:  Contains WGID_X\n  // ttmp10: Available - Used next to save exec_lo\n  // ttmp11: Contains debug flags - Used next to save exec_hi\n  // ttmp12: Contains SQ_WAVE_STATE_PRIV\n  // ttmp13: Contains flag bits for sampling type - HT_FLAG_BIT or STOCH_FLAG_BIT\n  // ttmp[14:15]: Contains HT or ST buffer base address\n  //\n  // v[0:3] contain user shader data that must be preserved/restored\n  // exec: Contains user's execution mask\n  s_mov_b64         ttmp[10:11], exec                       // save exec to ttmp[10:11]\n  s_mov_b64         exec, 0x1                               // turn on lane 0 only\n\n  v_readlane_b32    ttmp2, v0, 0\n  v_readlane_b32    ttmp3, v1, 0                            // Save out lane 0’s first 2 VGPRs\n\n  // At this point, ttmp[4:5], ttmp6 and v[0:1] are free\n  // Atomically get current sample slot index and select buffer\n  // pcs_sampling_data_t.buf_write_val (uint64_t) stores:\n  //   Bit 63: current_buffer_id (0 or 1)\n  //   Bits 62-0: current_sample_index_in_buffer\n  // v0 = 1 (value to add to the low part of buf_write_val)\n  // v1 = 0 (value to add to the high part of buf_write_val, bit 63 is buffer selector)\n\n  v_mov_b32         v0, 1\n  v_mov_b32         v1, 0\n\n  global_atomic_add_u64 v[0:1], v1, v[0:1], ttmp[14:15], scope:SCOPE_SYS th:TH_ATOMIC_RETURN\n  s_wait_loadcnt    0                                       // Wait for atomic operation to complete and return value\n\n  // At this point, ttmp[4:5] and ttmp6 are free\n  // v[0:1] (lane 0) now holds the previous value of buf_write_val.\n  // This previous value gives the slot index for the current sample.\n\n  v_readlane_b32    ttmp6, v1, 0x0                          // previous buf_write_val[63:32]\n  s_lshr_b32        ttmp6, ttmp6, TTMP13_BUF_FULL_BIT       // ttmp6 = previous_buffer_id (0 or 1, from bit 63 of original uint64_t)\n                                                            // This ttmp6 is used to select which buffer's metadata (size, watermark, signal) to use.\n                                                            // It's also used to calculate the base address of the sample buffer.\n  s_bitset0_b32     ttmp13, TTMP13_BUF_FULL_BIT             // Clear our local buffer full flag for now\n\n  s_cmp_eq_u32      ttmp6, 0                                // store off buf_to_use\n  s_cbranch_scc1    .skip_bufbit_set                        // into bit31 of ttmp13\n  s_bitset1_b32     ttmp13, TTMP13_BUF_FULL_BIT\n\n.skip_bufbit_set:\n  // ttmp[2:3]=v[0:1]-backup, ttmp[4:5]=free, ttmp6=buf_to_use (also in ttmp13.b31)\n  // ttmp[10:11]=EXEC backup. ttmp[14:15]=tma\n  // v[0:1].lane0=local_entry, v[2:3]=original, EXEC=0x1\n\n  v_bfe_u32         v1, v1, 0, SAMPLE_INDEX_WIDTH           // v[0:1] = new local_entry\n                                                            // removes bit 31 from v1, returning v1 & 0x7FFFFFFF.\n\n  v_readlane_b32    ttmp5, v1, 0                            // ttmp5 = high 31 bits of sample index (if index > 2^32-1).\n  s_cmp_lg_u32      ttmp5, 0                                // Check if sample index is very large (overflowed 32 bits).\n\n  s_cbranch_scc1    .lost_sample                            // If ttmp5 > 0, index is too large, treat as lost sample.\n\n  s_load_b32           ttmp5, ttmp[14:15], SAMPLE_OFF_BUF_SIZE, scope:SCOPE_CU // ttmp5 = pcs_sampling_data_t.buf_size\n  v_readlane_b32    ttmp4, v0, 0                            // ttmp4 = sample_index_for_current_sample (from v0)\n  s_wait_kmcnt      0                                       // Wait for buf_size load.\n\n  s_cmp_ge_u32      ttmp4, ttmp5                            // if local_entry >= buf_size\n  s_cbranch_scc1    .lost_sample                            // If index >= buf_size, buffer is full, sample is lost.\n                                                            // This also sets TTMP13_BUF_FULL_BIT implicitly by branching.\n\n  // Register state before calculating the sample buffer address:\n  // ttmp2 = backup of original shader's v0\n  // ttmp3 = backup of original shader's v1\n  // ttmp4 = sample_index_for_current_sample (from v0)\n  // ttmp5 = buf_size\n  // ttmp6 = buffer_id (0 or 1)\n  // ttmp[10:11] = original shader's [exec_lo, exec_hi]\n  // ttmp[14:15] = base_address_of_pcs_sampling_data_t (TMA)\n  // ttmp13.b31 = buffer_id (0 or 1, same as ttmp6)\n  // v[0:1].lane0 = sample index value from atomic\n  // v[2:3] = original user shader's v[2:3] values\n  // exec = backup of user shader's v[0:1]\n  s_mov_b64         exec, ttmp[2:3]                         // stash into EXEC to free up ttmp\n\n  // Calculate the base address of the correct sample buffer (buffer0 or buffer1).\n  // The buffers are located after the pcs_sampling_data_t struct header.\n  // Address = (TMA + SAMPLE_OFF_BYTES_PER_SAMPLE) + (buffer_id * buf_size * 64)\n  s_mul_i32         ttmp2, ttmp5, ttmp6                     // low 32 bits\n  s_mul_hi_u32      ttmp3, ttmp5, ttmp6                     // high 32 bits\n\n  // Multiply by 64 bytes per sample slot (shift left by 6 bits)\n  // This converts from units of samples to units of bytes\n  s_lshl_b64        ttmp[2:3], ttmp[2:3], 6\n  s_add_u32         ttmp2, ttmp2, SAMPLE_OFF_BYTES_PER_SAMPLE\n  s_addc_u32        ttmp3, ttmp3, 0\n  s_add_u32         ttmp4, ttmp14, ttmp2                    // ttmp4 = TMA_base_lo + total_offset_lo. This is low part of &bufferX\n  s_addc_u32        ttmp5, ttmp15, ttmp3                    // ttmp5 = TMA_base_hi + total_offset_hi + carry. This is high part of &bufferX\n                                                            // ttmp[4:5] now correctly points to the base of the selected sample buffer array\n\n  s_bitcmp1_b32     ttmp13, TTMP13_HT_FLAG_BIT              // if ttmp13.b22==1, this is hosttrap\n  s_cbranch_scc1    .fill_sample_ht\n  s_bitcmp1_b32     ttmp13, TTMP13_STOCH_FLAG_BIT\n  s_cbranch_scc1    .fill_sample_stoch\n\n  s_mov_b64         ttmp[2:3], exec                         // Restore user v[0:1] backup to ttmp[2:3]\n  v_readlane_b32    ttmp4, v2, 0                            // Backup user v[2:3] to ttmp[4:5] for restore.\n  v_readlane_b32    ttmp5, v3, 0\n  s_branch          .restore_vector_before_exit_trap\n\n.fill_sample_ht:\n  // At this point, v[0:1] is local_entry (but v1 is 0)\n  // v[2:3] is original user-data\n  // ttmp[2:3] is free\n  // ttmp[4:5] holds &buffer\n  // ttmp6 holds buf_to_use\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // [ttmp14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC holds holds backup of original shader’s v[0:1]\n\n  v_readlane_b32    ttmp6, v0, 0                              // ttmp6=local_entry\n  s_mul_i32         ttmp2, ttmp6, SAMPLE_OFF_BYTES_PER_SAMPLE // into buffer for 64B objects\n  s_mul_hi_u32      ttmp3, ttmp6, SAMPLE_OFF_BYTES_PER_SAMPLE // ttmp[2:3] now holds the offset\n  s_add_u32         ttmp2, ttmp2, ttmp4\n  s_addc_u32        ttmp3, ttmp3, ttmp5                     // ttmp[2:3]=&bufferX[local_entry]\n  v_readlane_b32    ttmp4, v2, 0x0                          // ttmp[4:5] now holds backup of\n  v_readlane_b32    ttmp5, v3, 0x0                          // user-data from v[2:3]\n  v_writelane_b32   v0, ttmp2, 0x0\n  v_writelane_b32   v1, ttmp3, 0x0                          // v[0:1]=&buffer[local_entry]\n\n  s_sendmsg_rtn_b64 ttmp[2:3], sendmsg(MSG_RTN_GET_REALTIME)\n  s_wait_kmcnt      0                                       // Wait for timestamp\n\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds the thing we want to store\n  // ttmp[4:5] holds backup of original shaders v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shaders [exec_lo,exec_hi]\n  // ttmp[14:15]=tma, ttmp13.b31 = buf_to_use\n  // EXEC holds backup of original shaders v[0:1]\n\n  v_writelane_b32   v2, ttmp2, 0                            // bring output data to v[2:3]\n  v_writelane_b32   v3, ttmp3, 0\n\n  s_mov_b64         ttmp[2:3], exec                         // vector stores need EXEC set\n  s_mov_b64         exec, 1                                 // so ttmp[2:3] holds it for now\n\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_TIMESTAMP, scope:SCOPE_SYS // store out timestamp\n\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC is 0x1\n\n  s_and_b32         ttmp1, ttmp1, SQ_WAVE_PC_HI_ADDRESS_MASK // Clear out extra data from PC_HI\n  v_writelane_b32   v2, ttmp0, 0\n  v_writelane_b32   v3, ttmp1, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_PC_HOST, scope:SCOPE_SYS  // store out PC\n\n  v_writelane_b32   v2, ttmp10, 0\n  v_writelane_b32   v3, ttmp11, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_EXEC_LOHI, scope:SCOPE_SYS  // store out original EXEC\n\n  // Store Workgroup ID X and Y at offset SAMPLE_OFF_WGID_XY (0x10).\n  // ttmp9 = WGID_X (from first-level handler).\n  // ttmp7 contains WGID_Y in high 16 bits.\n  v_writelane_b32   v2, ttmp9, 0                            // wg_id_x\n  s_bfe_u32         ttmp6, ttmp7, (16<<16)                  // extract bits 15:0, wg_id_y\n  v_writelane_b32   v3, ttmp6, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_WGID_XY, scope:SCOPE_SYS  // store wg_id_x and wg_id_y\n\n  // Store Workgroup ID Z and Wave ID at offset SAMPLE_OFF_WGID_Z_WAVE (0x18).\n  // ttmp7 contains WGID_Z in low 16 bits.\n  // ttmp11 contains Wave ID in low 6 bits (from EXEC_hi).\n  s_bfe_u32         ttmp6, ttmp7, (16|16<<16)               // extract bits 31:16, wg_id_z\n  v_writelane_b32   v2, ttmp6, 0\n  v_writelane_b32   v3, ttmp8, 0x0                          // wave_in_wg is bits 29:25\n  v_lshrrev_b32     v3, 25, v3                              // Shift wave_in_wg to 4:0\n  v_and_b32         v3, v3, WAVE_ID_MASK                    // put (ttmp8>>25)&0x1f into v3\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_WGID_Z_WAVE, scope:SCOPE_SYS  // store wg_id_z and wave_id\n\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC is 0x1\n  // Get HW_ID1 & 2 with S_GETREG_B32 with size=32 (F8 in upper bits), offset=0, and:\n  // HW_ID1 = 23 (0x17), HW_ID2 = 24 (0x18)\n\n  STORE_HW_ID\n\n  // The following is still true as we get ready to jump to correlation ID check\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC is 0x1\n\n  STORE_CORRELATION_ID\n  // Ensure all stores have completed before returning and incrementing written_val\n  s_wait_storecnt   0\n\n  // Still true after returning back from correlation ID check\n  // v[0:1] = &buffer[local_entry], but we no longer need it\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC is 0x1\n  //\n  s_branch          .ret_from_fill_sample\n\n.fill_sample_stoch:\n  // v0 contains local_entry, v1 is free\n  // v[2:3] is original user-data\n  // ttmp[2:3] is free\n  // ttmp[4:5] holds &buffer\n  // ttmp6 holds buf_to_use\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // [ttmp14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC holds holds backup of original shader’s v[0:1]\n\n  v_readlane_b32    ttmp6, v0, 0x0                            // ttmp2=local_entry\n  s_mul_i32         ttmp2, ttmp6, SAMPLE_OFF_BYTES_PER_SAMPLE // into buffer for 64B objects\n  s_mul_hi_u32      ttmp3, ttmp6, SAMPLE_OFF_BYTES_PER_SAMPLE // ttmp[2:3] now holds the offset\n  s_add_u32         ttmp2, ttmp2, ttmp4\n  s_addc_u32        ttmp3, ttmp3, ttmp5                       // ttmp[2:3]=&bufferX[local_entry]\n  v_readlane_b32    ttmp4, v2, 0x0                            // ttmp[4:5] now holds backup of\n  v_readlane_b32    ttmp5, v3, 0x0                            // user-data from v[2:3]\n  v_writelane_b32   v0, ttmp2, 0x0\n  v_writelane_b32   v1, ttmp3, 0x0                            // v[0:1]=&buffer[local_entry]\n  s_sendmsg_rtn_b64 ttmp[2:3], sendmsg(MSG_RTN_GET_REALTIME)\n  s_wait_kmcnt      0                                         // Wait for timestamp\n\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds the thing we want to store\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC holds backup of original shader’s v[0:1]\n\n  v_writelane_b32   v2, ttmp2, 0                            // bring output data to v[2:3]\n  v_writelane_b32   v3, ttmp3, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_TIMESTAMP, scope:SCOPE_SYS  // store out timestamp\n\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 = buf_to_use\n  // EXEC is 0x1\n  v_writelane_b32   v2, ttmp10, 0\n  v_writelane_b32   v3, ttmp11, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_EXEC_LOHI, scope:SCOPE_SYS  // store out original EXEC\n  v_writelane_b32   v2, ttmp9, 0                            // wg_id_x\n  s_bfe_u32         ttmp6, ttmp7, (0 | (16 << 16))          // extract bits 15:0, wg_id_y\n  v_writelane_b32   v3, ttmp6, 0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_WGID_XY, scope:SCOPE_SYS  // store wg_id_x and wg_id_y\n  s_bfe_u32         ttmp6, ttmp7, (16|16<<16)               // extract bits 31:16, wg_id_z\n  v_writelane_b32   v2, ttmp6, 0                            // put wg_id_z in v2\n  v_writelane_b32   v3, ttmp8, 0x0                          // wave_in_wg is bits 29:25\n\n  v_lshrrev_b32     v3, 25, v3                              // Shift wave_in_wg to 4:0\n\n  v_and_b32         v3, v3, WAVE_ID_MASK                    // put (ttmp8>>25)&0x1f into v3\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_WGID_Z_WAVE, scope:SCOPE_SYS  // store wg_id_z and wave_id\n\n  STORE_HW_ID\n\n  //Read SNAPSHOT Data\n  s_getreg_b32      ttmp6, HW_REG_SQ_PERF_SNAPSHOT_DATA1\n  v_writelane_b32   v2, ttmp6, 0x0\n  s_getreg_b32      ttmp6, HW_REG_SQ_PERF_SNAPSHOT_DATA2\n  v_writelane_b32   v3, ttmp6, 0x0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_SNAPSHOT_DATA + 4, scope:SCOPE_SYS  // store snapshot DATA1 and DATA2\n\n  s_getreg_b32      ttmp2, HW_REG_SQ_PERF_SNAPSHOT_DATA\n  v_writelane_b32   v2, ttmp2, 0\n  global_store_b32  v[0:1], v2, off, offset:SAMPLE_OFF_SNAPSHOT_DATA, scope:SCOPE_SYS  // store perf snapshot DATA\n\n  s_getreg_b32      ttmp6, HW_REG_SQ_PERF_SNAPSHOT_PC_LO\n  v_writelane_b32   v2, ttmp6, 0x0\n  s_getreg_b32      ttmp6, HW_REG_SQ_PERF_SNAPSHOT_PC_HI\n  v_writelane_b32   v3, ttmp6, 0x0\n  global_store_b64  v[0:1], v[2:3], off, offset:SAMPLE_OFF_PC_HOST, scope:SCOPE_SYS  // store PC_HI:PC_LO\n\n  // The following is still true as we get ready to jump to correlation ID check\n  // v[0:1] = &buffer[local_entry]\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=tma, ttmp13.b31 tells us buf_to_use\n  // EXEC is 0x1\n\n  STORE_CORRELATION_ID\n  // Ensure all stores have completed before returning and incrementing written_val\n  s_wait_storecnt   0\n\n.ret_from_fill_sample:\n  // v[0:1] = free\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=‘tma’, ttmp13.b31 tells us buf_to_use\n  // EXEC is 0x1\n\n  // Sample data has been written to the device buffer.\n  // Now, atomically increment the count of written samples for the current buffer.\n  // This is pcs_sampling_data_t.buf_written_val0 or buf_written_val1.\n  s_lshr_b32        ttmp6, ttmp13, 31                       // ttmp6 is buf_to_use\n  s_mulk_i32        ttmp6, 0x10                             // ttmp6=offset from\n                                                            // written_val0 to written_val_X\n  s_add_u32         ttmp14, ttmp14, ttmp6                   // now ttmp[14:15] points to base for\n  s_addc_u32        ttmp15, ttmp15, 0                       // buf_written_valX atomic operation\n\n  // Atomically increment the chosen buf_written_val.\n  // v0 = 0 (value to add - low part), v1 = 1 (value to add - high part, effectively just adding 1 to uint32_t)\n\n  v_mov_b32         v0, 0                                   // want to atomic increment\n  v_mov_b32         v1, 1                                   // buf_written_valX\n  global_atomic_add_u32 v0, v0, v1, ttmp[14:15], offset:SAMPLE_OFF_BUF_WRITTEN_VAL, scope:SCOPE_SYS th:TH_ATOMIC_RETURN\n  s_wait_loadcnt    0\n\n  // v0 = done, v1 = free, v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=buf_written_valX-0x10, EXEC=0x1\n  // Check Watermark and Signal Host\n\n  s_mov_b64         exec, ttmp[4:5]                         // stash user’s v[2:3] in EXEC\n  s_load_b32        ttmp5, ttmp[14:15], 0x14, scope:SCOPE_CU // load watermark into ttmp5\n  v_readlane_b32    ttmp4, v0, 0                            // put done into ttmp4\n  s_wait_kmcnt      0                                       // wait for watermark to load\n  s_cmp_lg_u32      ttmp4, ttmp5                            // if done != watermark, exit\n  s_add_u32         ttmp4, ttmp4, 1                         // ttmp4 is now current_sample_count (count_before_inc + 1)\n  s_cmp_lt_u32      ttmp4, ttmp5                            // if (current_sample_count < watermark), don't signal\n  s_mov_b64         ttmp[4:5], exec                         // restore user’s v[2:3]\n  s_mov_b64         exec, 1\n  s_cbranch_scc1    .restore_vector_before_exit_trap\n\n.send_signal:\n  // v[0:3] = free, ttmp[2:5] = backups of original v[0:3], ttmp6=free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=buf_written_valX-0x10, EXEC=old copy of original shader v[2:3]\n  // write done-signal and optional interrupt\n\n  // Watermark reached or exceeded. Signal the host.\n  // Load the hsa_signal_t handle for the current buffer.\n  // done_sig0 is at offset 0x18. done_sig1 is at 0x28.\n  // addr = ttmp[14:15] + 0x18 + (buffer_id * 0x10).\n  // ttmp0 still holds buffer_id * 0x10.\n\n  s_load_b64           ttmp[14:15], ttmp[14:15], SAMPLE_OFF_DONE_SIG0, scope:SCOPE_CU // load done_sig into ttmp[14:15]\n  s_mov_b64         exec, 1\n  s_wait_kmcnt      0\n\n  v_mov_b32         v0, 0\n  v_mov_b32         v1, 0                                   // value to store into v[0:1]\n  v_writelane_b32   v2, ttmp14, 0\n  v_writelane_b32   v3, ttmp15, 0                           // Put signal address into v[2:3]\n  global_store_b64  v[2:3], v[0:1], off, offset:SAMPLE_OFF_SIGNAL_VALUE, scope:SCOPE_SYS // zero out signal value\n\n  s_load_b32           ttmp6, ttmp[14:15], 0x18, scope:SCOPE_CU           // load event_id into ttmp6\n  s_load_b64           ttmp[14:15], ttmp[14:15], SAMPLE_OFF_EVENT_MAILBOX0, scope:SCOPE_CU     // load event mailbox ptr into 14:15\n  s_wait_kmcnt      0\n\n  s_cmp_eq_u64      ttmp[14:15], 0                          // null mailbox means no interrupt\n  s_cbranch_scc1    .restore_vector_before_exit_trap\n  s_cmp_eq_u32      ttmp6, 0                                // event_id zero means no interrupt\n  s_cbranch_scc1    .restore_vector_before_exit_trap\n  v_writelane_b32   v2, ttmp14, 0\n  v_writelane_b32   v3, ttmp15, 0                           // Put mailbox address into v[2:3]\n\n  s_wait_storecnt   0\n  v_writelane_b32   v0, ttmp6, 0x0                          // put event_id into v0\n  global_store_b32  v[2:3], v0, off, offset:0x0, scope:SCOPE_SYS // Send event ID to the mailbox\n  s_wait_storecnt   0\n  s_mov_b32         ttmp14, m0                              // save off m0\n  v_readlane_b32    ttmp15, v0, 0                           // Put ID into message payload\n  s_mov_b32         m0, ttmp15\n  s_sendmsg         sendmsg(MSG_INTERRUPT)                  // send interrupt message\n  s_wait_kmcnt      0\n  s_mov_b32         m0, ttmp14                              // restore m0\n\n  // v[0:1] = free\n  // v[2:3] = free\n  // ttmp[2:3] holds backup of original shader’s v[0:1]\n  // ttmp[4:5] holds backup of original shader’s v[2:3]\n  // ttmp6 = free\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=somewhere in tma region, EXEC is junk\n\n.restore_vector_before_exit_trap:\n  v_writelane_b32   v2, ttmp4, 0\n  v_writelane_b32   v3, ttmp5, 0\n\n.lost_sample:\n  // v0 contains local_entry, v1 is free\n  // v[2:3] is original user-data\n  // ttmp[2:3] [local_entry, buf_size]\n  // ttmp[4:5] = free\n  // ttmp6=buf_to_use (also in ttmp13.b31)\n  // ttmp[10:11] holds original shader’s [exec_lo,exec_hi]\n  // ttmp[14:15]=tma\n  // EXEC=0x1\n  // Restore vector registers before exiting\n\n  s_bitcmp1_b32     ttmp13, TTMP13_STOCH_FLAG_BIT           // Check if stochastic sampling\n  s_cbranch_scc0    .lost_sample_restore                    // If not, just restore and exit\n  s_getreg_b32      ttmp6, HW_REG_SQ_PERF_SNAPSHOT_PC_HI    // Read PC_HI to release lock\n\n.lost_sample_restore:\n  v_writelane_b32   v0, ttmp2, 0                            // restore v[0:1] to user data\n  v_writelane_b32   v1, ttmp3, 0\n  s_mov_b64         exec, ttmp[10:11]                       // restore exec mask\n\n.exit_trap:\n  // Restore SQ_WAVE_STATUS.\n  s_and_b64         exec, exec, exec                        // Restore STATUS.EXECZ, not writable by s_setreg_b32\n  s_and_b64         vcc, vcc, vcc                           // Restore STATUS.VCCZ, not writable by s_setreg_b32\n  s_setreg_b32      hwreg(HW_REG_STATE_PRIV, 0, SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_SHIFT), ttmp12\n  s_lshr_b32        ttmp12, ttmp12, (SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_SHIFT + 1)\n  s_setreg_b32      hwreg(HW_REG_STATE_PRIV, SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_SHIFT + 1, 32 - SQ_WAVE_STATE_PRIV_BARRIER_COMPLETE_SHIFT - 1), ttmp12\n\n  s_rfe_b64         [ttmp0, ttmp1]\n\n.parked:\n  s_trap            0x2\n  s_branch          .parked\n\n// Add s_code_end padding so instruction prefetch always has something to read.\n.rept (256 - ((. - trap_entry) % 64)) / 4\n  s_code_end\n.endr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/atomic_helpers.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n/*\n  Helpers to use native types with C++11 atomic operations.\n  Fixes GCC builtin functionality for x86 with respect to WC and non-temporal\n  stores.\n*/\n#ifndef HSA_RUNTIME_CORE_UTIL_ATOMIC_HELPERS_H_\n#define HSA_RUNTIME_CORE_UTIL_ATOMIC_HELPERS_H_\n\n#include <atomic>\n\n//ALWAYS_CONSERVATIVE will very likely overfence your code.\n//For use as a debugging aid only.\n#define ALWAYS_CONSERVATIVE 0\n\n#if !ALWAYS_CONSERVATIVE\n#if defined(__x86_64__) || defined(_M_X64)\n#define X64_ORDER_WC 1\n#endif\n#if X64_ORDER_WC\n#include <xmmintrin.h>\n#endif\n#endif\n\nnamespace rocr {\nnamespace atomic {\n\nstatic constexpr int c11ToBuiltInFlags(std::memory_order order)\n{\n#if ALWAYS_CONSERVATIVE\n  return __ATOMIC_RELAXED;\n#elif X64_ORDER_WC\n  return __ATOMIC_RELAXED;\n#else\n  return (order == std::memory_order_relaxed) ? __ATOMIC_RELAXED :\n    (order == std::memory_order_acquire) ? __ATOMIC_ACQUIRE :\n    (order == std::memory_order_release) ? __ATOMIC_RELEASE :\n    (order == std::memory_order_seq_cst) ? __ATOMIC_SEQ_CST :\n    (order == std::memory_order_consume) ? __ATOMIC_CONSUME :\n    (order == std::memory_order_acq_rel) ? __ATOMIC_ACQ_REL :\n    __ATOMIC_SEQ_CST;\n#endif\n}\n\nstatic __forceinline void PreFence(std::memory_order order) {\n#if ALWAYS_CONSERVATIVE\n  switch (order) {\n    case std::memory_order_release:\n    case std::memory_order_seq_cst:\n    case std::memory_order_acq_rel:\n      __atomic_thread_fence(__ATOMIC_SEQ_CST);\n    default:;\n  }\n#elif X64_ORDER_WC\n  switch (order) {\n    case std::memory_order_release:\n    case std::memory_order_seq_cst:\n    case std::memory_order_acq_rel:\n      _mm_sfence();\n    default:;\n  }\n#endif\n}\n\nstatic __forceinline void PostFence(std::memory_order order) {\n#if ALWAYS_CONSERVATIVE\n  switch (order) {\n    case std::memory_order_seq_cst:\n    case std::memory_order_acq_rel:\n    case std::memory_order_acquire:\n      __atomic_thread_fence(__ATOMIC_SEQ_CST);\n    default:;\n  }\n#elif X64_ORDER_WC\n  switch (order) {\n    case std::memory_order_seq_cst:\n      return _mm_mfence();\n    case std::memory_order_acq_rel:\n    case std::memory_order_acquire:\n      return _mm_lfence();\n    default:;\n  }\n#endif\n}\n\nstatic __forceinline void Fence(std::memory_order order=std::memory_order_seq_cst) {\n#if ALWAYS_CONSERVATIVE\n  __atomic_thread_fence(__ATOMIC_SEQ_CST);\n#elif X64_ORDER_WC\n  switch (order) {\n    case std::memory_order_seq_cst:\n    case std::memory_order_acq_rel:\n      return _mm_mfence();\n    case std::memory_order_acquire:\n      return _mm_lfence();\n    case std::memory_order_release:\n      return _mm_sfence();\n    default:;\n  }\n#else\n  std::atomic_thread_fence(order);\n#endif\n}\n\ntemplate <class T>\nstatic __forceinline void BasicCheck(const T* ptr) {\n  constexpr bool value = __atomic_always_lock_free(sizeof(T), 0);\n  static_assert(value, \"Atomic type may not be compatible with peripheral atomics.\");\n};\n\ntemplate <class T>\nstatic __forceinline void BasicCheck(const volatile T* ptr) {\n  constexpr bool value = __atomic_always_lock_free(sizeof(T), 0);\n  static_assert(value, \"Atomic type may not be compatible with peripheral atomics.\");\n};\n\n/// @brief: Load value of type T atomically with specified memory order.\n/// @param: ptr(Input), a pointer to type T.\n/// @param: order(Input), memory order with atomic load, relaxed by default.\n/// @return: T, loaded value.\ntemplate <class T>\nstatic __forceinline T\n    Load(const T* ptr, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  T ret;\n  PreFence(order);\n  __atomic_load(ptr, &ret, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: function overloading, for more info, see previous one.\n/// @param: ptr(Input), a pointer to volatile type T.\n/// @param: order(Input), memory order with atomic load, relaxed by default.\n/// @return: T, loaded value.\ntemplate <class T>\nstatic __forceinline T\n    Load(const volatile T* ptr,\n         std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  T ret;\n  PreFence(order);\n  __atomic_load(ptr, &ret, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Store value of type T with specified memory order.\n/// @param: ptr(Input), a pointer to instance which will be stored.\n/// @param: val(Input), value to be stored.\n/// @param: order(Input), memory order with atomic store, relaxed by default.\n/// @return: void.\ntemplate <class T>\nstatic __forceinline void Store(\n    T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  __atomic_store(ptr, &val, c11ToBuiltInFlags(order));\n  PostFence(order);\n}\n\n/// @brief: Function overloading, for more info, see previous one.\n/// @param: ptr(Input), a pointer to volatile instance which will be stored.\n/// @param: val(Input), value to be stored.\n/// @param: order(Input), memory order with atomic store, relaxed by default.\n/// @return: void.\ntemplate <class T>\nstatic __forceinline void Store(\n    volatile T* ptr, T val,\n    std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  __atomic_store(ptr, &val, c11ToBuiltInFlags(order));\n  PostFence(order);\n}\n\n/// @brief: Compare and swap value atomically with specified memory order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value to be stored if condition is satisfied.\n/// @param: expected(Input), value which is expected.\n/// @param: order(Input), memory order with atomic operation.\n/// @return: T, observed value of type T.\ntemplate <class T>\nstatic __forceinline T\n    Cas(T* ptr, T val, T expected,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  __atomic_compare_exchange(ptr, &expected, &val, false, c11ToBuiltInFlags(order), __ATOMIC_RELAXED);\n  PostFence(order);\n  return expected;\n}\n\n/// @brief: Function overloading, for more info, see previous one.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value to be stored if condition is satisfied.\n/// @param: expected(Input), value which is expected.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, observed value of type T.\ntemplate <class T>\nstatic __forceinline T\n    Cas(volatile T* ptr, T val, T expected,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  __atomic_compare_exchange(ptr, &expected, &val, false, c11ToBuiltInFlags(order), __ATOMIC_RELAXED);\n  PostFence(order);\n  return expected;\n}\n\n/// @brief: Exchange the value atomically with specified memory order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value to be stored.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, the value prior to the exchange.\ntemplate <class T>\nstatic __forceinline T\n    Exchange(T* ptr, T val,\n             std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  T ret;\n  PreFence(order);\n  __atomic_exchange(ptr, &val, &ret, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Function overloading, for more info, see previous one.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value to be stored.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, the value prior to the exchange.\ntemplate <class T>\nstatic __forceinline T\n    Exchange(volatile T* ptr, T val,\n             std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  T ret;\n  PreFence(order);\n  __atomic_exchange(ptr, &val, &ret, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Add value to variable atomically with specified memory order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value to be added.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, the value of the variable prior to the addition.\ntemplate <class T>\nstatic __forceinline T\n    Add(T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_add(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Subtract value from the variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value to be subtraced.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of the variable prior to the subtraction.\ntemplate <class T>\nstatic __forceinline T\n    Sub(T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_sub(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit And operation on variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value which is ANDed with variable.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    And(T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_and(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit Or operation on variable atomically with specified memory order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value which is ORed with variable.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    Or(T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_or(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit Xor operation on variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: val(Input), value which is XORed with variable.\n/// @order: order(Input), memory order which is relaxed by default.\n/// @return: T, valud of variable prior to the opertaion.\ntemplate <class T>\nstatic __forceinline T\n    Xor(T* ptr, T val, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_xor(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Increase the value of variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    Increment(T* ptr, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_add(ptr, 1, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Decrease the value of the variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to variable which is operated on.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    Decrement(T* ptr, std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_sub(ptr, 1, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Add value to variable atomically with specified memory order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value to be added.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, the value of the variable prior to the addition.\ntemplate <class T>\nstatic __forceinline T\n    Add(volatile T* ptr, T val,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_add(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Subtract value from the variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value to be subtraced.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of the variable prior to the subtraction.\ntemplate <class T>\nstatic __forceinline T\n    Sub(volatile T* ptr, T val,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_sub(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit And operation on variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value which is ANDed with variable.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    And(volatile T* ptr, T val,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_and(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit Or operation on variable atomically with specified memory order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value which is ORed with variable.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T Or(volatile T* ptr, T val,\n                          std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_or(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Bit Xor operation on variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: val(Input), value which is XORed with variable.\n/// @order: order(Input), memory order which is relaxed by default.\n/// @return: T, valud of variable prior to the opertaion.\ntemplate <class T>\nstatic __forceinline T\n    Xor(volatile T* ptr, T val,\n        std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_xor(ptr, val, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Increase the value of variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    Increment(volatile T* ptr,\n              std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_add(ptr, 1, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n\n/// @brief: Decrease the value of the variable atomically with specified memory\n/// order.\n/// @param: ptr(Input), a pointer to volatile variable which is operated on.\n/// @param: order(Input), memory order which is relaxed by default.\n/// @return: T, value of variable prior to the operation.\ntemplate <class T>\nstatic __forceinline T\n    Decrement(volatile T* ptr,\n              std::memory_order order = std::memory_order_relaxed) {\n  BasicCheck<T>(ptr);\n  PreFence(order);\n  T ret = __atomic_fetch_sub(ptr, 1, c11ToBuiltInFlags(order));\n  PostFence(order);\n  return ret;\n}\n}   //  namespace atomic\n}   //  namespace rocr\n\n#ifdef X64_ORDER_WC\n#undef X64_ORDER_WC\n#endif\n\n#ifdef ALWAYS_CONSERVATIVE\n#undef ALWAYS_CONSERVATIVE\n#endif\n\n#endif  // HSA_RUNTIME_CORE_UTIL_ATOMIC_HELPERS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/flag.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2021-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIESd OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/util/flag.h\"\n#include \"core/util/utils.h\"\n#include \"core/util/os.h\"\n\n#include <vector>\n#include <map>\n#include <string>\n#include <algorithm>\n#include <locale>\n\nnamespace rocr {\nFILE* log_file = stderr;\nuint8_t log_flags[8];\n\nvoid log_printf(const char* file, int line, const char* format, ...) {\n    va_list ap;\n    std::stringstream str_thrd_id;\n    str_thrd_id << std::hex << std::this_thread::get_id();\n    va_start(ap, format);\n    char message[4096];\n    vsnprintf(message, sizeof(message), format, ap);\n    va_end(ap);\n    fprintf(log_file, \":%-25s:%-4d: %010lld us: [pid:%-5d tid:0x%s] [***rocr***] %s\\n\",\n            file, line, os::ReadAccurateClock()/1000ULL, os::GetProcessId(),\n            str_thrd_id.str().c_str(), message);\n    fflush(log_file);\n}\n\n// split at separators\nstatic std::vector<std::string> split(std::string& str, char sep) {\n  std::vector<std::string> ret;\n  while (!str.empty()) {\n    size_t pos = str.find(sep);\n    if (pos == std::string::npos) {\n      ret.push_back(str);\n      return ret;\n    }\n    ret.push_back(str.substr(0, pos));\n    str.erase(0, pos + 1);\n  }\n  return ret;\n};\n\n// Parse id,id-id,... strings into id lists\nstatic std::vector<uint32_t> get_elements(std::string& str, uint32_t maxElement) {\n  std::vector<uint32_t> ret;\n  MAKE_NAMED_SCOPE_GUARD(error, [&]() { ret.clear(); });\n\n  std::vector<std::string> ranges = split(str, ',');\n  for (auto& str : ranges) {\n    auto range = split(str, '-');\n    // failure, too many -'s.\n    if (range.size() > 2) return ret;\n\n    char* end;\n    uint32_t index = strtoul(range[0].c_str(), &end, 10);\n    // Invalid syntax - id's must be base 10 digits only.\n    if (*end != '\\0') return ret;\n    if (index <= maxElement) ret.push_back(index);\n\n    if (range.size() == 2) {\n      uint32_t secondindex = strtoul(range[1].c_str(), &end, 10);\n      if (*end != '\\0') return ret;         // bad syntax\n      if (secondindex < index) return ret;  // inverted range\n      secondindex = Min(secondindex, maxElement);\n      for (uint32_t i = index + 1; i < secondindex + 1; i++) ret.push_back(i);\n    }\n  }\n\n  // Confirm no duplicate ids.\n  std::sort(ret.begin(), ret.end());\n  if (std::adjacent_find(ret.begin(), ret.end()) != ret.end()) return ret;\n\n  // Good parse, keep result.\n  error.Dismiss();\n  return ret;\n};\n\n/*\nParse env var per the following syntax, all whitespace is ignored:\n\nID = [0-9][0-9]*                         ex. base 10 numbers\nID_list = (ID | ID-ID)[, (ID | ID-ID)]*  ex. 0,2-4,7\nGPU_list = ID_list                       ex. 0,2-4,7\nCU_list = 0x[0-F]* | ID_list             ex. 0x337F OR 0,2-4,7\nCU_Set = GPU_list : CU_list              ex. 0,2-4,7:0-15,32-47 OR 0,2-4,7:0x337F\nHSA_CU_MASK =  CU_Set [; CU_Set]*        ex. 0,2-4,7:0-15,32-47; 3-9:0x337F\n\nGPU indexes are taken post ROCR_VISIBLE_DEVICES reordering.\nListed or bit set CUs will be enabled at queue creation on the associated GPU.\nAll other CUs on the associated GPUs will be disabled.\nCU masks of unlisted GPUs are not restricted.\n\nRepeating a GPU or CU ID is a syntax error.\nParsing stops at the first CU_Set that has a syntax error, that set and all\nfollowing sets are ignored.\nSpecifying a mask with no usable CUs (CU_list is 0x0) is a syntax error.\nUsers should use ROCR_VISIBLE_DEVICES if they want to exclude use of a\nparticular GPU.\n*/\nvoid Flag::parse_masks(std::string& var, uint32_t maxGpu, uint32_t maxCU) {\n  if (var.empty()) return;\n\n  // Remove whitespace\n  auto end = std::remove_if(var.begin(), var.end(),\n                            [](char c) { return std::isspace<char>(c, std::locale::classic()); });\n  var.erase(end, var.end());\n\n  // Switch to uppercase\n  for (auto& c : var) c = toupper(c);\n\n  // Iterate over cu sets\n  auto sets = split(var, ';');\n  for (auto& set : sets) {\n    auto parts = split(set, ':');\n    if (parts.size() != 2) return;\n\n    // temp storage for cu_set parsing.\n    std::vector<uint32_t> gpu_index;\n    std::vector<uint32_t> mask;\n\n    // parse cu list first, check for bitmask format\n    if (parts[1][1] == 'X') {\n      // Confirm hex format and strip prefix\n      auto& cu = parts[1];\n      if (cu[0] != '0') return;\n      cu.erase(0, 2);\n\n      // Ensure all valid hex characters\n      for (auto& c : cu) {\n        if (!isxdigit(c)) return;\n      }\n\n      // Convert to uint32_t, lsb first.\n      size_t len = cu.length();\n      while (len != 0) {\n        size_t trim = Min(len, size_t(8));\n        len -= trim;\n        auto tmp = cu.substr(len, trim);\n        auto chunk = stoul(tmp, nullptr, 16);\n        mask.push_back(chunk);\n      }\n\n      // Trim dwords beyond maxCUs\n      uint32_t maxDwords = maxCU / 32 + 1;\n      if (maxDwords < mask.size()) mask.resize(maxDwords);\n\n      // Trim leading zeros\n      while (!mask.empty() && mask.back() == 0) mask.pop_back();\n\n      // Mask 0x0 is an error.\n      if (mask.empty()) return;\n\n    } else {\n      // parse cu lists\n      auto cu_indices = get_elements(parts[1], maxCU);\n      if (cu_indices.empty()) return;\n      uint32_t maxdword = cu_indices.back() / 32 + 1;\n      mask.resize(maxdword, 0);\n      for (auto id : cu_indices) {\n        uint32_t index, offset;\n        index = id / 32;\n        offset = id % 32;\n        mask[index] |= 1ul << offset;\n      }\n    }\n\n    // parse device list\n    gpu_index = get_elements(parts[0], maxGpu);\n    if (gpu_index.empty()) return;\n\n    // Ensure that no GPU was repeated across cu_sets\n    for (auto id : gpu_index) {\n      if (cu_mask_.find(id) != cu_mask_.end()) return;\n    }\n\n    // Insert into map\n    for (auto id : gpu_index) {\n      cu_mask_[id] = mask;\n    }\n  }\n}\n\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/flag.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIESd OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_FLAG_H_\n#define HSA_RUNTIME_CORE_INC_FLAG_H_\n\n#include <stdint.h>\n\n#include <vector>\n#include <map>\n#include <string>\n\n#include \"core/util/os.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\n\nclass Flag {\n public:\n  enum SDMA_OVERRIDE { SDMA_DISABLE, SDMA_ENABLE, SDMA_DEFAULT };\n  enum SRAMECC_ENABLE { SRAMECC_DISABLED, SRAMECC_ENABLED, SRAMECC_DEFAULT };\n\n  // The values are meaningful and chosen to satisfy the thunk API.\n  enum XNACK_REQUEST { XNACK_DISABLE = 0, XNACK_ENABLE = 1, XNACK_UNCHANGED = 2 };\n  static_assert(XNACK_DISABLE == 0, \"XNACK_REQUEST enum values improperly changed.\");\n  static_assert(XNACK_ENABLE == 1, \"XNACK_REQUEST enum values improperly changed.\");\n\n  // Lift limit for 2.10 release RCCL workaround. This limit is not used when asynchronous scratch\n  // reclaim is supported\n  const size_t DEFAULT_SCRATCH_SINGLE_LIMIT = (140 * (1UL<<20));  // small_limit >> 2;\n  const size_t DEFAULT_SCRATCH_SINGLE_LIMIT_ASYNC_PER_XCC = (3 * (1UL<<30));  // 3 GB\n  const size_t DEFAULT_PCS_MAX_DEVICE_BUFFER_SIZE = (256 * (1UL<<20)); //256 MB\n\n  Flag() {}\n\n  virtual ~Flag() {}\n\n  void Refresh() {\n    std::string var = os::GetEnvVar(\"HSA_CHECK_FLAT_SCRATCH\");\n    check_flat_scratch_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_VM_FAULT_MESSAGE\");\n    enable_vm_fault_message_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_QUEUE_FAULT_MESSAGE\");\n    enable_queue_fault_message_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_INTERRUPT\");\n    enable_interrupt_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SDMA\");\n    enable_sdma_ = (var == \"0\") ? SDMA_DISABLE : ((var == \"1\") ? SDMA_ENABLE : SDMA_DEFAULT);\n\n    var = os::GetEnvVar(\"HSA_ENABLE_PEER_SDMA\");\n    enable_peer_sdma_ = (var == \"0\") ? SDMA_DISABLE : ((var == \"1\") ? SDMA_ENABLE : SDMA_DEFAULT);\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SDMA_GANG\");\n    enable_sdma_gang_ = (var == \"0\") ? SDMA_DISABLE :\n                       ((var == \"1\") ? SDMA_ENABLE : SDMA_DEFAULT);\n    if (enable_sdma_ == SDMA_DISABLE) enable_sdma_gang_ = SDMA_DISABLE;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SDMA_COPY_SIZE_OVERRIDE\");\n    enable_sdma_copy_size_override_ = (var == \"0\") ? SDMA_DISABLE :\n                                      ((var == \"1\") ? SDMA_ENABLE : SDMA_DEFAULT);\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SDMA_RECOMMENDED_ENG\");\n    enable_sdma_recommended_eng_ = (var == \"0\") ? SDMA_DISABLE :\n                                   ((var == \"1\") ? SDMA_ENABLE : SDMA_DEFAULT);\n\n    visible_gpus_ = os::GetEnvVar(\"ROCR_VISIBLE_DEVICES\");\n    filter_visible_gpus_ = os::IsEnvVarSet(\"ROCR_VISIBLE_DEVICES\");\n\n    var = os::GetEnvVar(\"HSA_RUNNING_UNDER_VALGRIND\");\n    running_valgrind_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_SDMA_WAIT_IDLE\");\n    sdma_wait_idle_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_MAX_QUEUES\");\n    max_queues_ = static_cast<uint32_t>(atoi(var.c_str()));\n\n    // Maximum amount of scratch mem that can be used per process per gpu\n    var = os::GetEnvVar(\"HSA_SCRATCH_MEM\");\n    scratch_mem_size_ = atoi(var.c_str());\n\n    // Scratch memory sizes > HSA_SCRATCH_SINGLE_LIMIT will trigger a use-once scheme\n    // We also reserve HSA_SCRATCH_SINGLE_LIMIT per process per gpu to guarrantee we\n    // have sufficient memory to for scratch in case user tried to allocate all device\n    // memory\n    if (os::IsEnvVarSet(\"HSA_SCRATCH_SINGLE_LIMIT\")) {\n      var = os::GetEnvVar(\"HSA_SCRATCH_SINGLE_LIMIT\");\n      char* end;\n      scratch_single_limit_ = strtoul(var.c_str(), &end, 10);\n    } else {\n      scratch_single_limit_ = DEFAULT_SCRATCH_SINGLE_LIMIT;\n    }\n\n    // On GPUs that support asynchronous scratch reclaim\n    // Scratch memory sizes > HSA_SCRATCH_SINGLE_LIMIT_ASYNC will trigger a use-once scheme\n    // Note: This only sets the initial value for the threshold. If\n    // hsa_amd_agent_set_async_scratch_limit is called after initialization, the threshold\n    // will be updated.\n    if (os::IsEnvVarSet(\"HSA_SCRATCH_SINGLE_LIMIT_ASYNC\")) {\n      var = os::GetEnvVar(\"HSA_SCRATCH_SINGLE_LIMIT_ASYNC\");\n      char* end;\n      scratch_single_limit_async_ = strtoul(var.c_str(), &end, 10);\n    } else {\n      scratch_single_limit_async_ = 0;  // DEFAULT_SCRATCH_SINGLE_LIMIT_ASYNC_PER_XCC;\n    }\n\n    // On GPUs that support asynchronous scratch reclaim this can be used to disable this feature.\n    // Disabling asynchronous scratch reclaim also disables use of alternate scratch\n    // HSA_ENABLE_SCRATCH_ALT\n    var = os::GetEnvVar(\"HSA_ENABLE_SCRATCH_ASYNC_RECLAIM\");\n    enable_scratch_async_reclaim_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SCRATCH_ALT\");\n    // Temporary: Completely disable alternate scratch because we need to update\n    // the debugger so that it can tell whether a dispatch is using alternate scratch\n    // instead of main scratch\n    // enable_scratch_alt_ = (var == \"0\") || !enable_scratch_async_reclaim_ ? false : true;\n    enable_scratch_alt_ = false;\n\n    tools_lib_names_ = os::GetEnvVar(\"HSA_TOOLS_LIB\");\n\n    var = os::GetEnvVar(\"HSA_TOOLS_REPORT_LOAD_FAILURE\");\n\n    ifdebug {\n      report_tool_load_failures_ = (var == \"1\") ? true : false;\n    } else {\n      report_tool_load_failures_ = (var == \"0\") ? false : true;\n    }\n\n    var = os::GetEnvVar(\"HSA_TOOLS_DISABLE_REGISTER\");\n    disable_tool_register_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_TOOLS_REPORT_REGISTER_FAILURE\");\n    report_tool_register_failures_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_DISABLE_FRAGMENT_ALLOCATOR\");\n    disable_fragment_alloc_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SDMA_HDP_FLUSH\");\n    enable_sdma_hdp_flush_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_REV_COPY_DIR\");\n    rev_copy_dir_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_FORCE_FINE_GRAIN_PCIE\");\n    fine_grain_pcie_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_NO_SCRATCH_RECLAIM\");\n    no_scratch_reclaim_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_NO_SCRATCH_THREAD_LIMITER\");\n    no_scratch_thread_limit_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_DISABLE_IMAGE\");\n    disable_image_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_DISABLE_PC_SAMPLING\");\n    disable_pc_sampling_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_LOADER_ENABLE_MMAP_URI\");\n    loader_enable_mmap_uri_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_FORCE_SDMA_SIZE\");\n    force_sdma_size_ = var.empty() ? 1024 * 1024 : atoi(var.c_str());\n\n    var = os::GetEnvVar(\"HSA_IGNORE_SRAMECC_MISREPORT\");\n    check_sramecc_validity_ = (var == \"1\") ? false : true;\n\n    // Legal values are zero \"0\" or one \"1\". Any other value will\n    // be interpreted as not defining the env variable.\n    var = os::GetEnvVar(\"HSA_XNACK\");\n    xnack_ = (var == \"0\") ? XNACK_DISABLE : ((var == \"1\") ? XNACK_ENABLE : XNACK_UNCHANGED);\n\n    var = os::GetEnvVar(\"HSA_ENABLE_DEBUG\");\n    debug_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_CU_MASK_SKIP_INIT\");\n    cu_mask_skip_init_ = (var == \"1\") ? true : false;\n\n    // Temporary opt-in for corrected HSA_AMD_AGENT_INFO_COOPERATIVE_COMPUTE_UNIT_COUNT behavior.\n    // Will become opt-out and possibly removed in future releases.\n    var = os::GetEnvVar(\"HSA_COOP_CU_COUNT\");\n    coop_cu_count_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_DISCOVER_COPY_AGENTS\");\n    discover_copy_agents_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_SVM_PROFILE\");\n    svm_profile_ = var;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_SRAMECC\");\n    sramecc_enable_ =\n        (var == \"0\") ? SRAMECC_DISABLED : ((var == \"1\") ? SRAMECC_ENABLED : SRAMECC_DEFAULT);\n\n    var = os::GetEnvVar(\"HSA_IMAGE_PRINT_SRD\");\n    image_print_srd_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_MWAITX\");\n    enable_mwaitx_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_ENABLE_IPC_MODE_LEGACY\");\n    enable_ipc_mode_legacy_ = (var == \"0\") ? false : true; // Legacy mode by default\n    if (os::IsEnvVarSet(\"HSA_PCS_MAX_DEVICE_BUFFER_SIZE\")) {\n      var = os::GetEnvVar(\"HSA_PCS_MAX_DEVICE_BUFFER_SIZE\");\n      char* end;\n      pc_sampling_max_device_buffer_size_ = strtoul(var.c_str(), &end, 10);\n    } else {\n      pc_sampling_max_device_buffer_size_ = DEFAULT_PCS_MAX_DEVICE_BUFFER_SIZE;\n    }\n\n    // Temporary environment variable to disable CPU affinity override\n    // Will either rename to HSA_OVERRIDE_CPU_AFFINITY later or remove completely.\n    var = os::GetEnvVar(\"HSA_OVERRIDE_CPU_AFFINITY_DEBUG\");\n    override_cpu_affinity_ = (var == \"0\") ? false : true;\n\n    var = os::GetEnvVar(\"HSA_ALLOCATE_QUEUE_DEV_MEM\");\n    dev_mem_queue_buf_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_WAIT_ANY_DEBUG\");\n    wait_any_ = (var == \"1\") ? true : false;\n\n    /* hsa_signal_wait_relaxed abort timeout  */\n    var = os::GetEnvVar(\"HSA_SIGNAL_WAIT_ABORT_TIMEOUT\");\n    signal_abort_timeout_ = var.empty() ? 0 : atoi(var.c_str());\n\n    /* Valid inputs are 0-99, HIGH, MAX */\n    var = os::GetEnvVar(\"HSA_ASYNCEVENTS_THREAD_PRIORITY\");\n    async_events_thread_priority_ = os::OS_THREAD_PRIORITY_DEFAULT;\n    if (var == \"MAX\") {\n      async_events_thread_priority_ = os::OS_THREAD_PRIORITY_MAX;\n    } else if (var == \"HIGH\") {\n      async_events_thread_priority_ = os::OS_THREAD_PRIORITY_HIGH;\n    } else if (var != \"\") {\n      char* end;\n      int input = strtol(var.c_str(), &end, 10);\n      if (input >= 0 && input <= 99)\n        async_events_thread_priority_ = input;\n      else\n        fprintf(stderr, \"Failed to parse HSA_ASYNCEVENTS_THREAD_PRIORITY\");\n    }\n\n    var = os::GetEnvVar(\"HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG\");\n    enable_3d_swizzle_ = (var == \"1\") ? true : false;\n\n    // This allows convient usage in scripting for enabling dtif.\n    // IE the user should set HSA_DTIF_ENABLED = 1 to enable DTIF.\n    // HSA_DTIF_ENABLED = 0 will disable DTIF backend.\n    var = os::GetEnvVar(\"HSA_ENABLE_DTIF\");\n    enable_dtif_ = (var == \"1\") ? true : false;\n\n    var = os::GetEnvVar(\"HSA_CO_DMACOPY_SIZE\");\n    co_dmacopy_size_ = var.empty() ? 1024*1024 : atoi(var.c_str());\n  }\n\n  void parse_masks(uint32_t maxGpu, uint32_t maxCU) {\n    std::string var = os::GetEnvVar(\"HSA_CU_MASK\");\n    parse_masks(var, maxGpu, maxCU);\n  }\n\n  bool wait_any() const { return wait_any_; }\n\n  bool check_flat_scratch() const { return check_flat_scratch_; }\n\n  bool enable_vm_fault_message() const { return enable_vm_fault_message_; }\n\n  bool enable_queue_fault_message() const { return enable_queue_fault_message_; }\n\n  bool enable_interrupt() const { return enable_interrupt_; }\n\n  bool enable_sdma_hdp_flush() const { return enable_sdma_hdp_flush_; }\n\n  bool running_valgrind() const { return running_valgrind_; }\n\n  bool sdma_wait_idle() const { return sdma_wait_idle_; }\n\n  bool report_tool_load_failures() const { return report_tool_load_failures_; }\n\n  bool report_tool_register_failures() const { return report_tool_register_failures_; }\n\n  bool disable_tool_register() const { return disable_tool_register_; }\n\n  bool disable_fragment_alloc() const { return disable_fragment_alloc_; }\n\n  bool rev_copy_dir() const { return rev_copy_dir_; }\n\n  bool fine_grain_pcie() const { return fine_grain_pcie_; }\n\n  bool no_scratch_reclaim() const { return no_scratch_reclaim_; }\n\n  bool no_scratch_thread_limiter() const { return no_scratch_thread_limit_; }\n\n  SDMA_OVERRIDE enable_sdma() const { return enable_sdma_; }\n\n  SDMA_OVERRIDE enable_peer_sdma() const { return enable_peer_sdma_; }\n\n  SDMA_OVERRIDE enable_sdma_gang() const { return enable_sdma_gang_; }\n\n  SDMA_OVERRIDE enable_sdma_copy_size_override() const { return enable_sdma_copy_size_override_; }\n\n  SDMA_OVERRIDE enable_sdma_recommended_eng() const { return enable_sdma_recommended_eng_; }\n\n  std::string visible_gpus() const { return visible_gpus_; }\n\n  bool filter_visible_gpus() const { return filter_visible_gpus_; }\n\n  uint32_t max_queues() const { return max_queues_; }\n\n  size_t scratch_mem_size() const { return scratch_mem_size_; }\n\n  size_t scratch_single_limit() const { return scratch_single_limit_; }\n\n  bool enable_scratch_async_reclaim() const { return enable_scratch_async_reclaim_; }\n\n  bool enable_scratch_alt() const { return enable_scratch_alt_; }\n\n  size_t scratch_single_limit_async() const { return scratch_single_limit_async_; }\n\n  std::string tools_lib_names() const { return tools_lib_names_; }\n\n  bool disable_image() const { return disable_image_; }\n\n  bool disable_pc_sampling() const { return disable_pc_sampling_; }\n\n  bool loader_enable_mmap_uri() const { return loader_enable_mmap_uri_; }\n\n  size_t force_sdma_size() const { return force_sdma_size_; }\n\n  bool check_sramecc_validity() const { return check_sramecc_validity_; }\n\n  bool override_cpu_affinity() const { return override_cpu_affinity_; }\n\n  bool image_print_srd() const { return image_print_srd_; }\n\n  bool check_mwaitx(bool mwaitx_supported) {\n    if (enable_mwaitx_ && !mwaitx_supported) enable_mwaitx_ = false;\n\n    return enable_mwaitx_;\n  }\n\n  XNACK_REQUEST xnack() const { return xnack_; }\n\n  bool debug() const { return debug_; }\n\n  const std::vector<uint32_t>& cu_mask(uint32_t gpu_index) const {\n    static const std::vector<uint32_t> empty;\n    auto it = cu_mask_.find(gpu_index);\n    if (it == cu_mask_.end()) return empty;\n    return it->second;\n  }\n\n  bool cu_mask_skip_init() const { return cu_mask_skip_init_; }\n\n  bool coop_cu_count() const { return coop_cu_count_; }\n\n  bool discover_copy_agents() const { return discover_copy_agents_; }\n\n  const std::string& svm_profile() const { return svm_profile_; }\n\n  SRAMECC_ENABLE sramecc_enable() const { return sramecc_enable_; }\n\n  bool enable_ipc_mode_legacy() const { return enable_ipc_mode_legacy_; }\n\n  size_t pc_sampling_max_device_buffer_size() const { return pc_sampling_max_device_buffer_size_; }\n\n  size_t co_dmacopy_size() const { return co_dmacopy_size_; }\n\n  bool dev_mem_queue_buf() const { return dev_mem_queue_buf_; }\n\n  uint32_t signal_abort_timeout() const { return signal_abort_timeout_; }\n\n  int async_events_thread_priority() const { return async_events_thread_priority_; }\n\n  bool enable_3d_swizzle() const { return enable_3d_swizzle_; }\n\n  bool enable_dtif() const { return enable_dtif_; }\n private:\n  bool check_flat_scratch_;\n  bool enable_vm_fault_message_;\n  bool enable_interrupt_;\n  bool enable_sdma_hdp_flush_;\n  bool running_valgrind_;\n  bool sdma_wait_idle_;\n  bool enable_queue_fault_message_;\n  bool report_tool_load_failures_;\n  bool report_tool_register_failures_ = false;\n  bool disable_tool_register_ = false;\n  bool disable_fragment_alloc_;\n  bool rev_copy_dir_;\n  bool fine_grain_pcie_;\n  bool no_scratch_reclaim_;\n  bool no_scratch_thread_limit_;\n  bool disable_image_;\n  bool disable_pc_sampling_;\n  bool loader_enable_mmap_uri_;\n  bool check_sramecc_validity_;\n  bool debug_;\n  bool cu_mask_skip_init_;\n  bool coop_cu_count_;\n  bool discover_copy_agents_;\n  bool override_cpu_affinity_;\n  bool image_print_srd_;\n  bool enable_mwaitx_;\n  bool enable_ipc_mode_legacy_;\n  bool wait_any_;\n  bool dev_mem_queue_buf_;\n  uint32_t signal_abort_timeout_;\n  int  async_events_thread_priority_;\n  bool enable_3d_swizzle_ = false;\n  bool enable_dtif_;\n\n  SDMA_OVERRIDE enable_sdma_;\n  SDMA_OVERRIDE enable_peer_sdma_;\n  SDMA_OVERRIDE enable_sdma_gang_;\n  SDMA_OVERRIDE enable_sdma_copy_size_override_;\n  SDMA_OVERRIDE enable_sdma_recommended_eng_;\n\n  bool filter_visible_gpus_;\n  std::string visible_gpus_;\n\n  uint32_t max_queues_;\n\n  size_t scratch_mem_size_;\n  size_t scratch_single_limit_;\n  size_t scratch_single_limit_async_;\n  bool enable_scratch_async_reclaim_;\n  bool enable_scratch_alt_;\n\n  std::string tools_lib_names_;\n  std::string svm_profile_;\n\n  size_t force_sdma_size_;\n\n  // Indicates user preference for Xnack state.\n  XNACK_REQUEST xnack_;\n\n  SRAMECC_ENABLE sramecc_enable_;\n\n  size_t pc_sampling_max_device_buffer_size_;\n\n  size_t co_dmacopy_size_;\n\n  // Map GPU index post RVD to its default cu mask.\n  std::map<uint32_t, std::vector<uint32_t>> cu_mask_;\n\n  void parse_masks(std::string& args, uint32_t maxGpu, uint32_t maxCU);\n\n  DISALLOW_COPY_AND_ASSIGN(Flag);\n};\n\n}  // namespace rocr\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/lazy_ptr.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIESd OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_UTIL_LAZY_PTR_H_\n#define HSA_RUNTIME_CORE_UTIL_LAZY_PTR_H_\n\n#include <memory>\n#include <utility>\n#include <functional>\n\n#include \"core/util/locks.h\"\n#include \"core/util/utils.h\"\n\nnamespace rocr {\n\n/*\n * Wrapper for a std::unique_ptr that initializes its object at first use.\n */\ntemplate <typename T> class lazy_ptr {\n public:\n  lazy_ptr() {}\n\n  explicit lazy_ptr(std::function<T*()> Constructor) { reset(Constructor); }\n\n  lazy_ptr(lazy_ptr&& rhs) {\n    obj = std::move(rhs.obj);\n    func = std::move(rhs.func);\n  }\n\n  lazy_ptr& operator=(lazy_ptr&& rhs) {\n    obj = std::move(rhs.obj);\n    func = std::move(rhs.func);\n  }\n\n  lazy_ptr(lazy_ptr&) = delete;\n  lazy_ptr& operator=(lazy_ptr&) = delete;\n\n  void reset(std::function<T*()> Constructor = nullptr) {\n    obj.reset();\n    func = std::move(Constructor);\n  }\n\n  void reset(T* ptr) {\n    obj.reset(ptr);\n    func = nullptr;\n  }\n\n  bool operator==(T* rhs) const { return obj.get() == rhs; }\n  bool operator!=(T* rhs) const { return obj.get() != rhs; }\n\n  const std::unique_ptr<T>& operator->() const {\n    make(true);\n    assert(obj != nullptr && \"Null dereference through lazy_ptr.\");\n    return obj;\n  }\n\n  std::unique_ptr<T>& operator*() {\n    make(true);\n    return obj;\n  }\n\n  const std::unique_ptr<T>& operator*() const {\n    make(true);\n    return obj;\n  }\n\n  /*\n   * Ensures that the object is created or is being created.\n   * This is useful when early construction of the object is required.\n   */\n  void touch() const { make(false); }\n\n  // Tells if the lazy object has been constructed or not.\n  // Construction may fail silently (return nullptr).\n  bool created() const {\n    std::atomic_thread_fence(std::memory_order_acquire);\n    return func == nullptr;\n  }\n\n  // Tells if the lazy object exists or not.\n  bool empty() const {\n    std::atomic_thread_fence(std::memory_order_acquire);\n    return obj == nullptr;\n  }\n\n private:\n  mutable std::unique_ptr<T> obj;\n  mutable std::function<T*(void)> func;\n  mutable KernelMutex lock;\n\n  // Separated from make to improve inlining.\n  void make_body(bool block) const {\n    if (block) {\n      lock.Acquire();\n    } else if (!lock.Try()) {\n      return;\n    }\n    MAKE_SCOPE_GUARD([&]() { lock.Release(); });\n    if (func == nullptr) return;\n    T* ptr = func();\n    obj.reset(ptr);\n    std::atomic_thread_fence(std::memory_order_release);\n    func = nullptr;\n  }\n\n  __forceinline void make(bool block) const {\n    if (!created()) {\n      make_body(block);\n    }\n  }\n\n};\n\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_UTIL_LAZY_PTR_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/lnx/os_linux.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifdef __linux__\n#include \"core/util/os.h\"\n#include \"core/util/utils.h\"\n\n#include <link.h>\n#include <dlfcn.h>\n#include <pthread.h>\n#include <limits.h>\n#include <sched.h>\n#include <sys/sysinfo.h>\n#include <sys/time.h>\n#include <sys/utsname.h>\n#include <unistd.h>\n#include <errno.h>\n#include <cstring>\n#include <atomic>\n#include <memory>\n#include <string>\n#include <utility>\n#include <semaphore.h>\n#include \"core/inc/runtime.h\"\n#if defined(__i386__) || defined(__x86_64__)\n#include <cpuid.h>\n#endif\n\n#ifdef __GLIBC__\n#define ABS_ADDR(base, ptr) (ptr)\n#else\n#define ABS_ADDR(base, ptr) ((base) + (ptr))\n#endif\n\nnamespace rocr {\nnamespace os {\n\nstruct ThreadArgs {\n  void* entry_args;\n  ThreadEntry entry_function;\n};\n\nvoid* __stdcall ThreadTrampoline(void* arg) {\n  ThreadArgs* ar = (ThreadArgs*)arg;\n  ThreadEntry CallMe = ar->entry_function;\n  void* Data = ar->entry_args;\n  CallMe(Data);\n  return nullptr;\n}\n\n// Thread container allows multiple waits and separate close (destroy).\nclass os_thread {\n public:\n  explicit os_thread(ThreadEntry function,\n                      void* threadArgument,\n                      uint stackSize,\n                      int priority)\n      : thread(0), lock(nullptr), state(RUNNING) {\n    int err;\n    lock = CreateMutex();\n    if (lock == nullptr) return;\n\n    args.entry_args = threadArgument;\n    args.entry_function = function;\n\n    pthread_attr_t attrib;\n    err = pthread_attr_init(&attrib);\n    if (err != 0) {\n      fprintf(stderr, \"pthread_attr_init failed: %s\\n\", strerror(err));\n      return;\n    }\n\n    MAKE_SCOPE_GUARD([&]() {\n      if (pthread_attr_destroy(&attrib))\n        fprintf(stderr, \"pthread_attr_destroy failed: %s\\n\", strerror(err));\n    });\n\n    if (stackSize != 0) {\n      stackSize = Max(uint(PTHREAD_STACK_MIN), stackSize);\n      stackSize = AlignUp(stackSize, 4096);\n      err = pthread_attr_setstacksize(&attrib, stackSize);\n      if (err != 0) {\n        fprintf(stderr, \"pthread_attr_setstacksize failed: %s\\n\", strerror(err));\n        return;\n      }\n    }\n\n    int cores = 0;\n    cpu_set_t* cpuset = nullptr;\n\n    if (core::Runtime::runtime_singleton_->flag().override_cpu_affinity()) {\n      cores = get_nprocs_conf();\n      cpuset = CPU_ALLOC(cores);\n      if (cpuset == nullptr) {\n        fprintf(stderr, \"CPU_ALLOC failed: %s\\n\", strerror(errno));\n        return;\n      }\n      CPU_ZERO_S(CPU_ALLOC_SIZE(cores), cpuset);\n      for (int i = 0; i < cores; i++) {\n        CPU_SET_S(i, CPU_ALLOC_SIZE(cores), cpuset);\n      }\n#ifdef HAVE_PTHREAD_ATTR_SETAFFINITY_NP\n      err = pthread_attr_setaffinity_np(&attrib, CPU_ALLOC_SIZE(cores), cpuset);\n      CPU_FREE(cpuset);\n      if (err != 0) {\n        fprintf(stderr, \"pthread_setaffinity_np failed: %s\\n\", strerror(err));\n        return;\n      }\n#endif\n    }\n\n    do {\n      err = pthread_create(&thread, &attrib, ThreadTrampoline, &args);\n      if (!err) break;\n\n      if (err != EINVAL || stackSize == 0) {\n        fprintf(stderr, \"pthread_create failed %d (%s)\\n\", errno, strerror(errno));\n        thread = 0;\n        return;\n      }\n\n      // Probably a stack size error since system limits can be different from PTHREAD_STACK_MIN\n      // Attempt to grow the stack within reason.\n      stackSize *= 2;\n      if (pthread_attr_setstacksize(&attrib, stackSize)) {\n        fprintf(stderr, \"pthread_attr_setstacksize failed: %s\\n\", strerror(err));\n        thread = 0;\n        return;\n      }\n    } while (stackSize < 20 * 1024 * 1024);\n\n#ifndef HAVE_PTHREAD_ATTR_SETAFFINITY_NP\n    if (cores && cpuset) {\n      err = pthread_setaffinity_np(thread, CPU_ALLOC_SIZE(cores), cpuset);\n      CPU_FREE(cpuset);\n      if (err != 0) {\n        fprintf(stderr, \"pthread_setaffinity_np failed: %s\\n\", strerror(err));\n        thread = 0;\n        return;\n      }\n    }\n#endif\n    struct sched_param param = {};\n    if (priority != OS_THREAD_PRIORITY_DEFAULT) {\n      int set_priority;\n      int max_priority = sched_get_priority_max(SCHED_FIFO);\n\n      if (priority == OS_THREAD_PRIORITY_MAX)\n        set_priority = max_priority;\n      else if (priority == OS_THREAD_PRIORITY_HIGH)\n        set_priority = max_priority - 1;\n      else if (priority > max_priority)\n        set_priority = max_priority;\n      else\n        set_priority = priority;\n\n      param.sched_priority = set_priority;\n      if (pthread_setschedparam(thread, SCHED_FIFO, &param)) {\n        fprintf(stderr, \"pthread_setschedparam failed\\n\");\n        return;\n      }\n\n      int policy = 0;\n      if (pthread_getschedparam(thread, &policy, &param))\n        fprintf(stderr, \"pthread_getschedparam failed: %s\\n\", strerror(err));\n\n      if (policy != SCHED_FIFO || param.sched_priority != set_priority)\n        fprintf(stderr, \"Failed to adjust thread priority (policy:%s requested:%d current:%d)\\n\",\n                          policy == SCHED_FIFO ? \"FIFO\" :\n                          policy == SCHED_OTHER ? \"OTHER\" :\n                          policy == SCHED_RR ? \"RR\" : \"Unknown\",\n                          set_priority, param.sched_priority);\n    }\n  }\n\n  os_thread(os_thread&& rhs) {\n    thread = rhs.thread;\n    args = rhs.args;\n    lock = rhs.lock;\n    state = int(rhs.state);\n    rhs.thread = 0;\n    rhs.lock = nullptr;\n  }\n\n  os_thread(os_thread&) = delete;\n\n  ~os_thread() {\n    if (lock != nullptr) DestroyMutex(lock);\n    if ((state == RUNNING) && (thread != 0)) {\n      int err = pthread_detach(thread);\n      if (err != 0) fprintf(stderr, \"pthread_detach failed: %s\\n\", strerror(err));\n    }\n  }\n\n  bool Valid() { return (lock != nullptr) && (thread != 0); }\n\n  bool Wait() {\n    if (state == FINISHED) return true;\n    AcquireMutex(lock);\n    if (state == FINISHED) {\n      ReleaseMutex(lock);\n      return true;\n    }\n    int err = pthread_join(thread, NULL);\n    bool success = (err == 0);\n    if (success) state = FINISHED;\n    ReleaseMutex(lock);\n    return success;\n  }\n\n private:\n  pthread_t thread;\n  struct ThreadArgs args;\n  Mutex lock;\n  std::atomic<int> state;\n  enum { FINISHED = 0, RUNNING = 1 };\n};\n\nstatic_assert(sizeof(LibHandle) == sizeof(void*), \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Semaphore) == sizeof(sem_t*), \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Mutex) == sizeof(pthread_mutex_t*), \"OS abstraction size mismatch\");\nstatic_assert(sizeof(SharedMutex) == sizeof(pthread_rwlock_t*), \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Thread) == sizeof(os_thread*), \"OS abstraction size mismatch\");\n\nLibHandle LoadLib(std::string filename) {\n  void* ret = dlopen(filename.c_str(), RTLD_LAZY);\n  if (ret == nullptr) debug_print(\"LoadLib(%s) failed: %s\\n\", filename.c_str(), dlerror());\n  return *(LibHandle*)&ret;\n}\n\nvoid* GetExportAddress(LibHandle lib, std::string export_name) {\n  void* ret = dlsym(*(void**)&lib, export_name.c_str());\n\n  // dlsym searches the given library and all the library's load dependencies.\n  // Remaining code limits symbol lookup to only the library handle given.\n  // This lookup pattern matches Windows.\n  if (ret == NULL) return ret;\n\n  link_map* map;\n  int err = dlinfo(*(void**)&lib, RTLD_DI_LINKMAP, &map);\n  if (err == -1) {\n    fprintf(stderr, \"dlinfo failed: %s\\n\", dlerror());\n    return nullptr;\n  }\n\n  Dl_info info;\n  err = dladdr(ret, &info);\n  if (err == 0) {\n    fprintf(stderr, \"dladdr failed.\\n\");\n    return nullptr;\n  }\n\n  if (strcmp(info.dli_fname, map->l_name) == 0) return ret;\n\n  return NULL;\n}\n\nvoid CloseLib(LibHandle lib) { dlclose(*(void**)&lib); }\n\n/*\n * @brief Look for a symbol called \"HSA_AMD_TOOL_PRIORITY\" across all loaded\n * shared libraries, and if found, store the name of the library\n *\n * @param[in]: info A dl_phdr_info struct pointer, which contains information\n * about library's load address, header, and name.\n *\n * @param[in]: size integer size of dl_phdr_info struct\n *\n * @param[out]: data copy of the data argument to dl_phdr_iterate call\n *\n * @retval:: Return 0 on Success. If callback returns a non-zero value,\n * dl_iterate_phdr() will stop processing, even if there are unprocessed\n * shared objects.\n */\n\nstatic int callback(struct dl_phdr_info* info, size_t size, void* data) {\n  std::vector<std::string>* loadedToolsLib = (std::vector<std::string>*)data;\n  assert(loadedToolsLib != nullptr);\n  /*\n   * Check if lib name is not empty and its not a \"vdso.so\" lib,\n   * The vDSO is a special shared object file that is built into the Linux kernel.\n   * It is not a regular shared library and thus does not have all the properties\n   * of regular shared libraries. The way the vDSO is loaded and organized in memory\n   * is different from regular shared libraries and it's not guaranteed that it\n   * will have a specific segment or section. Hence its skipped.\n   */\n\n  if ((info) && (info->dlpi_name[0] != '\\0')) {\n    if (std::string(info->dlpi_name).find(\"vdso.so\") != std::string::npos) return 0;\n\n    /*\n     * Iterate through the program headers of the loaded lib and check for PT_DYNAMIC program\n     * header. If the PT_DYNAMIC program header is found, use dlpi_addr and dlpi_phdr members\n     * of dl_phdr_info struct to get the address of the dynamic section of the loaded\n     * library in memory\n     */\n\n    for (int i = 0; i < info->dlpi_phnum; i++) {\n      if (info->dlpi_phdr[i].p_type == PT_DYNAMIC) {\n        Elf64_Dyn* dyn_section = (Elf64_Dyn*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);\n\n        char* strings = nullptr;\n        Elf64_Xword limit = 0;\n\n        /*\n         * The dynamic section is searched for DT_STRTAB (address of string table),\n         * and DT_STRSZ (size of string table)\n         * DT_NULL - Marks the end of the _DYNAMIC array\n         */\n\n        for (int j = 0;; j++) {\n          if (dyn_section[j].d_tag == DT_NULL) break;\n\n          if (dyn_section[j].d_tag == DT_STRTAB) strings = (char*)ABS_ADDR(info->dlpi_addr, dyn_section[j].d_un.d_ptr);\n\n          if (dyn_section[j].d_tag == DT_STRSZ) limit = dyn_section[j].d_un.d_val;\n        }\n\n        if (strings == nullptr) debug_print(\"String table not found\");\n\n        /*\n         * Hacky lookup, if string and symbol tables are found,\n         * iterate through the strings in string table and check if\n         * any string matches \"HSA_AMD_TOOL_PRIORITY\".\n         * If yes, then add the name of the library to the vector of\n         * lib names\n         */\n        if (strings != nullptr) {\n          char* end = strings + limit;\n          while (strings < end) {\n            if (strcmp(strings, \"HSA_AMD_TOOL_PRIORITY\") == 0) {\n              loadedToolsLib->push_back(info->dlpi_name);\n              return 0;\n            }\n            strings += (strlen(strings) + 1);\n          }\n        }\n      }\n    }\n  }\n  return 0;\n}\n\nstd::vector<LibHandle> GetLoadedToolsLib() {\n  std::vector<LibHandle> ret;\n  std::vector<std::string> names;\n\n  /* Iterate through all of the loaded shared libraries in the process */\n  dl_iterate_phdr(callback, &names);\n\n  if (!names.empty()) {\n    for (auto& name : names) ret.push_back(LoadLib(name));\n  }\n\n  return ret;\n}\n\nstd::string GetLibraryName(LibHandle lib) {\n  link_map *map;\n  if(dlinfo(lib, RTLD_DI_LINKMAP, &map)!=0)\n    return \"\";\n  return map->l_name;\n}\n\nSemaphore CreateSemaphore() {\n  sem_t *sem = new sem_t;\n  sem_init(sem, 0, 0);\n  return *(Semaphore*)&sem;\n}\n\nbool WaitSemaphore(Semaphore sem) {\n  while(sem_wait(*(sem_t**)&sem))\n    if (errno != EINTR) return false;\n\n  return true;\n}\n\nvoid PostSemaphore(Semaphore sem) {\n  int waitval = 1;\n  if (sem_getvalue(*(sem_t**)&sem, &waitval))\n    assert(false && \"Failed to get semaphore waiters\");\n\n  /* sem_getvalue return <= 0 when there are threads blocked on sem_wait */\n  if (waitval > 0)\n    return;\n\n  if (sem_post(*(sem_t**)&sem))\n    assert(false && \"Failed to post semaphore\");\n}\n\nvoid DestroySemaphore(Semaphore sem) {\n  sem_destroy(*(sem_t**)&sem);\n  delete *(sem_t**)&sem;\n}\n\nMutex CreateMutex() {\n  pthread_mutex_t* mutex = new pthread_mutex_t;\n  pthread_mutex_init(mutex, NULL);\n  return *(Mutex*)&mutex;\n}\n\nbool TryAcquireMutex(Mutex lock) {\n  return pthread_mutex_trylock(*(pthread_mutex_t**)&lock) == 0;\n}\n\nbool AcquireMutex(Mutex lock) {\n  return pthread_mutex_lock(*(pthread_mutex_t**)&lock) == 0;\n}\n\nvoid ReleaseMutex(Mutex lock) {\n  pthread_mutex_unlock(*(pthread_mutex_t**)&lock);\n}\n\nvoid DestroyMutex(Mutex lock) {\n  pthread_mutex_destroy(*(pthread_mutex_t**)&lock);\n  delete *(pthread_mutex_t**)&lock;\n}\n\nvoid Sleep(int delay_in_millisec) { usleep(delay_in_millisec * 1000); }\n\nvoid uSleep(int delayInUs) { usleep(delayInUs); }\n\nvoid YieldThread() { sched_yield(); }\n\nThread CreateThread(ThreadEntry function, void* threadArgument, uint stackSize, int priority) {\n  os_thread* result = new os_thread(function, threadArgument, stackSize, priority);\n  if (!result->Valid()) {\n    delete result;\n    return nullptr;\n  }\n\n  return reinterpret_cast<Thread>(result);\n}\n\nvoid CloseThread(Thread thread) { delete reinterpret_cast<os_thread*>(thread); }\n\nbool WaitForThread(Thread thread) { return reinterpret_cast<os_thread*>(thread)->Wait(); }\n\nbool WaitForAllThreads(Thread* threads, uint threadCount) {\n  for (uint i = 0; i < threadCount; i++) WaitForThread(threads[i]);\n  return true;\n}\n\nbool IsEnvVarSet(std::string env_var_name) {\n  char* buff = NULL;\n  buff = getenv(env_var_name.c_str());\n  return (buff != NULL);\n}\n\nvoid SetEnvVar(std::string env_var_name, std::string env_var_value) {\n  setenv(env_var_name.c_str(), env_var_value.c_str(), 1);\n}\n\nint GetProcessId() {\n  return ::getpid();\n}\n\nstd::string GetEnvVar(std::string env_var_name) {\n  char* buff;\n  buff = getenv(env_var_name.c_str());\n  std::string ret;\n  if (buff) {\n    ret = buff;\n  }\n  return ret;\n}\n\nsize_t GetUserModeVirtualMemorySize() {\n#ifdef _LP64\n  // https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt :\n  // user space is 0000000000000000 - 00007fffffffffff (=47 bits)\n  return (size_t)(0x800000000000);\n#else\n  return (size_t)(0xffffffff);  // ~4GB\n#endif\n}\n\nsize_t GetUsablePhysicalHostMemorySize() {\n  struct sysinfo info = {0};\n  if (sysinfo(&info) != 0) {\n    return 0;\n  }\n\n  const size_t physical_size =\n      static_cast<size_t>(info.totalram * info.mem_unit);\n  return std::min(GetUserModeVirtualMemorySize(), physical_size);\n}\n\nuintptr_t GetUserModeVirtualMemoryBase() { return (uintptr_t)0; }\n\n// Os event implementation\ntypedef struct EventDescriptor_ {\n  pthread_cond_t event;\n  pthread_mutex_t mutex;\n  bool state;\n  bool auto_reset;\n} EventDescriptor;\n\nEventHandle CreateOsEvent(bool auto_reset, bool init_state) {\n  EventDescriptor* eventDescrp;\n  eventDescrp = (EventDescriptor*)malloc(sizeof(EventDescriptor));\n\n  pthread_mutex_init(&eventDescrp->mutex, NULL);\n  pthread_cond_init(&eventDescrp->event, NULL);\n  eventDescrp->auto_reset = auto_reset;\n  eventDescrp->state = init_state;\n\n  EventHandle handle = reinterpret_cast<EventHandle>(eventDescrp);\n\n  return handle;\n}\n\nint DestroyOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n\n  EventDescriptor* eventDescrp = reinterpret_cast<EventDescriptor*>(event);\n  int ret_code = pthread_cond_destroy(&eventDescrp->event);\n  ret_code |= pthread_mutex_destroy(&eventDescrp->mutex);\n  free(eventDescrp);\n  return ret_code;\n}\n\nint WaitForOsEvent(EventHandle event, unsigned int milli_seconds) {\n  if (event == NULL) {\n    return -1;\n  }\n\n  EventDescriptor* eventDescrp = reinterpret_cast<EventDescriptor*>(event);\n  // Event wait time is 0 and state is non-signaled, return directly\n  if (milli_seconds == 0) {\n    int tmp_ret = pthread_mutex_trylock(&eventDescrp->mutex);\n    if (tmp_ret == EBUSY) {\n      // Timeout\n      return 1;\n    }\n  } else {\n      pthread_mutex_lock(&eventDescrp->mutex);\n  }\n\n  int ret_code = 0;\n  \n  if (!eventDescrp->state) {\n    if (milli_seconds == 0) {\n      ret_code = 1;\n    } else {\n      struct timespec ts;\n      struct timeval tp;\n\n      ret_code = gettimeofday(&tp, NULL);\n      ts.tv_sec = tp.tv_sec;\n      ts.tv_nsec = tp.tv_usec * 1000;\n\n      unsigned int sec = milli_seconds / 1000;\n      unsigned int mSec = milli_seconds % 1000;\n\n      ts.tv_sec += sec;\n      ts.tv_nsec += mSec * 1000000;\n\n      // More then one second, add 1 sec to the tv_sec elem\n      if (ts.tv_nsec > 1000000000) {\n        ts.tv_sec += 1;\n        ts.tv_nsec = ts.tv_nsec - 1000000000;\n      }\n\n      ret_code =\n          pthread_cond_timedwait(&eventDescrp->event, &eventDescrp->mutex, &ts);\n      // Time out\n      if (ret_code == 110) {\n        ret_code = 0x14003;  // 1 means time out in HSA\n      }\n\n      if (ret_code == 0 && eventDescrp->auto_reset) {\n        eventDescrp->state = false;\n      }\n    }\n  } else if (eventDescrp->auto_reset) {\n    eventDescrp->state = false;\n  }\n  pthread_mutex_unlock(&eventDescrp->mutex);\n\n  return ret_code;\n}\n\nint SetOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n\n  EventDescriptor* eventDescrp = reinterpret_cast<EventDescriptor*>(event);\n  int ret_code = 0;\n  ret_code = pthread_mutex_lock(&eventDescrp->mutex);\n  eventDescrp->state = true;\n  ret_code = pthread_mutex_unlock(&eventDescrp->mutex);\n  ret_code |= pthread_cond_signal(&eventDescrp->event);\n\n  return ret_code;\n}\n\nint ResetOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n\n  EventDescriptor* eventDescrp = reinterpret_cast<EventDescriptor*>(event);\n  int ret_code = 0;\n  ret_code = pthread_mutex_lock(&eventDescrp->mutex);\n  eventDescrp->state = false;\n  ret_code = pthread_mutex_unlock(&eventDescrp->mutex);\n\n  return ret_code;\n}\n\nstatic double invPeriod = 0.0;\n\nuint64_t ReadAccurateClock() {\n  if (invPeriod == 0.0) AccurateClockFrequency();\n  timespec time;\n  int err = clock_gettime(CLOCK_MONOTONIC_RAW, &time);\n  if (err != 0) {\n    perror(\"clock_gettime(CLOCK_MONOTONIC_RAW,...) failed\");\n    abort();\n  }\n  return (uint64_t(time.tv_sec) * 1000000000ull + uint64_t(time.tv_nsec)) * invPeriod;\n}\n\nuint64_t AccurateClockFrequency() {\n  static clockid_t clock = CLOCK_MONOTONIC;\n  static std::atomic<bool> first(true);\n  // Check kernel version - not a concurrency concern.\n  // use non-RAW for getres due to bug in older 2.6.x kernels\n  if (first.load(std::memory_order_acquire)) {\n    utsname kernelInfo;\n    if (uname(&kernelInfo) == 0) {\n      try {\n        std::string ver = kernelInfo.release;\n        size_t idx;\n        int major = std::stoi(ver, &idx);\n        int minor = std::stoi(ver.substr(idx + 1));\n        if ((major >= 4) && (minor >= 4)) {\n          clock = CLOCK_MONOTONIC_RAW;\n        }\n      } catch (...) {\n        // Kernel version string doesn't conform to the standard pattern.\n        // Keep using the \"safe\" (non-RAW) clock.\n      }\n    }\n    first.store(false, std::memory_order_release);\n  }\n  timespec time;\n  int err = clock_getres(clock, &time);\n  if (err != 0) {\n    perror(\"clock_getres failed\");\n    abort();\n  }\n  if (time.tv_sec != 0 || time.tv_nsec >= 0xFFFFFFFF) {\n    fprintf(stderr,\n            \"clock_getres(CLOCK_MONOTONIC(_RAW),...) returned very low \"\n            \"frequency (<1Hz).\\n\");\n    abort();\n  }\n  if (invPeriod == 0.0) invPeriod = 1.0 / double(time.tv_nsec);\n  return 1000000000ull / uint64_t(time.tv_nsec);\n}\n\nSharedMutex CreateSharedMutex() {\n  pthread_rwlockattr_t attrib;\n  int err = pthread_rwlockattr_init(&attrib);\n  if (err != 0) {\n    fprintf(stderr, \"rw lock attribute init failed: %s\\n\", strerror(err));\n    return nullptr;\n  }\n\n#ifdef HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP\n  err = pthread_rwlockattr_setkind_np(&attrib, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);\n  if (err != 0) {\n    fprintf(stderr, \"Set rw lock attribute failure: %s\\n\", strerror(err));\n    return nullptr;\n  }\n#endif\n\n  std::unique_ptr<pthread_rwlock_t> lock(new pthread_rwlock_t);\n  err = pthread_rwlock_init(lock.get(), &attrib);\n  if (err != 0) {\n    fprintf(stderr, \"rw lock init failed: %s\\n\", strerror(err));\n    return nullptr;\n  }\n\n  pthread_rwlockattr_destroy(&attrib);\n  return lock.release();\n}\n\nbool TryAcquireSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_trywrlock(*(pthread_rwlock_t**)&lock);\n  return err == 0;\n}\n\nbool AcquireSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_wrlock(*(pthread_rwlock_t**)&lock);\n  return err == 0;\n}\n\nvoid ReleaseSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_unlock(*(pthread_rwlock_t**)&lock);\n  if (err != 0) {\n    fprintf(stderr, \"SharedMutex unlock failed: %s\\n\", strerror(err));\n    abort();\n  }\n}\n\nbool TrySharedAcquireSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_tryrdlock(*(pthread_rwlock_t**)&lock);\n  return err == 0;\n}\n\nbool SharedAcquireSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_rdlock(*(pthread_rwlock_t**)&lock);\n  return err == 0;\n}\n\nvoid SharedReleaseSharedMutex(SharedMutex lock) {\n  int err = pthread_rwlock_unlock(*(pthread_rwlock_t**)&lock);\n  if (err != 0) {\n    fprintf(stderr, \"SharedMutex unlock failed: %s\\n\", strerror(err));\n    abort();\n  }\n}\n\nvoid DestroySharedMutex(SharedMutex lock) {\n  pthread_rwlock_destroy(*(pthread_rwlock_t**)&lock);\n  delete *(pthread_rwlock_t**)&lock;\n}\n\nstatic uint64_t sys_clock_period_ = 0;\n\nuint64_t ReadSystemClock() {\n  struct timespec ts;\n  clock_gettime(CLOCK_BOOTTIME, &ts);\n  uint64_t time = (uint64_t(ts.tv_sec) * 1000000000 + uint64_t(ts.tv_nsec));\n  if (sys_clock_period_ != 1)\n    return time / sys_clock_period_;\n  else\n    return time;\n}\n\nuint64_t SystemClockFrequency() {\n  struct timespec ts;\n  clock_getres(CLOCK_BOOTTIME, &ts);\n  sys_clock_period_ = (uint64_t(ts.tv_sec) * 1000000000 + uint64_t(ts.tv_nsec));\n  return 1000000000 / sys_clock_period_;\n}\n\nbool ParseCpuID(cpuid_t* cpuinfo) {\n#if defined(__i386__) || defined(__x86_64__)\n  uint32_t eax, ebx, ecx, edx, max_eax = 0;\n  memset(cpuinfo, 0, sizeof(*cpuinfo));\n\n  /* Make sure current CPU supports at least EAX 4 */\n  if (!__get_cpuid_max(0x80000004, NULL)) return false;\n\n  // Manufacturer ID is a twelve-character ASCII string stored in order EBX, EDX, ECX.\n  if (!__get_cpuid(0, &max_eax, (uint32_t*)&cpuinfo->ManufacturerID[0],\n                   (uint32_t*)&cpuinfo->ManufacturerID[8],\n                   (uint32_t*)&cpuinfo->ManufacturerID[4])) {\n    return false;\n  }\n\n  if (!strcmp(cpuinfo->ManufacturerID, \"AuthenticAMD\")) {\n    if (__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx)) {\n      cpuinfo->mwaitx = !!((ecx >> 29) & 0x1);\n    }\n  }\n  return true;\n#else\n  return false;\n#endif\n}\n\n}   //  namespace os\n}   //  namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/locks.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// Library of syncronization primitives - to be added to as needed.\n\n#ifndef HSA_RUNTIME_CORE_UTIL_LOCKS_H_\n#define HSA_RUNTIME_CORE_UTIL_LOCKS_H_\n\n#include \"utils.h\"\n#include \"os.h\"\n\nnamespace rocr {\n\nclass HybridMutex {\n public:\n  HybridMutex():lock_(0) { \n    sem_ = os::CreateSemaphore(); \n  }\n\n  ~HybridMutex() { \n    os::DestroySemaphore(sem_); \n  }\n\n  bool Try() {\n    int old = 0;\n    return lock_.compare_exchange_strong(old, 1);\n  }\n\n  bool Acquire() {\n    int cnt = maxSpinIterPause + maxSpinIterYield;\n\n    int old = 0;\n    while (!lock_.compare_exchange_strong(old, 1)) {\n      cnt--;\n      if (cnt > maxSpinIterPause) {\n        _mm_pause();\n      } else if (cnt-- > maxSpinIterYield) {\n        os::YieldThread();\n      } else {\n        os::WaitSemaphore(sem_);\n        cnt = maxSpinIterPause + maxSpinIterYield;\n      }\n      old = 0;\n    }\n    return true;\n  }\n\n  void Release() {\n    int old = 1;\n    if (lock_.compare_exchange_strong(old, 0))\n      os::PostSemaphore(sem_);\n  }\n\n private:\n  std::atomic<int> lock_;\n  os::Semaphore sem_;\n  const uint32_t maxSpinIterPause = 55;\n  const uint32_t maxSpinIterYield = 55;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(HybridMutex);\n};\n\n\n/// @brief: a class represents a kernel mutex.\n/// Uses the kernel's scheduler to keep the waiting thread from being scheduled\n/// until the lock is released (Best for long waits, though anything using\n/// a kernel object is a long wait).\nclass KernelMutex {\n public:\n  KernelMutex() { lock_ = os::CreateMutex(); }\n  ~KernelMutex() { os::DestroyMutex(lock_); }\n\n  bool Try() { return os::TryAcquireMutex(lock_); }\n  bool Acquire() { return os::AcquireMutex(lock_); }\n  void Release() { os::ReleaseMutex(lock_); }\n\n private:\n  os::Mutex lock_;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(KernelMutex);\n};\n\n/// @brief: represents a spin lock.\n/// For very short hold durations on the order of the thread scheduling\n/// quanta or less.\nclass SpinMutex {\n public:\n  SpinMutex() { lock_ = 0; }\n\n  bool Try() {\n    int old = 0;\n    return lock_.compare_exchange_strong(old, 1);\n  }\n  bool Acquire() {\n    int old = 0;\n    while (!lock_.compare_exchange_strong(old, 1))\n\t{\n\t\told=0;\n    os::YieldThread();\n\t}\n    return true;\n  }\n  void Release() { lock_ = 0; }\n\n private:\n  std::atomic<int> lock_;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(SpinMutex);\n};\n\nclass KernelEvent {\n public:\n  KernelEvent() { evt_ = os::CreateOsEvent(true, true); }\n  ~KernelEvent() { os::DestroyOsEvent(evt_); }\n\n  bool IsSet() { return os::WaitForOsEvent(evt_, 0)==0; }\n  bool WaitForSet() { return os::WaitForOsEvent(evt_, 0xFFFFFFFF)==0; }\n  void Set() { os::SetOsEvent(evt_); }\n  void Reset() { os::ResetOsEvent(evt_); }\n\n private:\n  os::EventHandle evt_;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(KernelEvent);\n};\n\n/// @brief: represents a yielding shared mutex.\n/// aka read/write mutex\nclass KernelSharedMutex {\n public:\n  /// @brief: Interfaces ScopedAcquire to shared operations.\n  class Shared {\n   public:\n    explicit Shared(KernelSharedMutex* lock) : lock_(lock) {}\n    bool Try() { return lock_->TryShared(); }\n    bool Acquire() { return lock_->AcquireShared(); }\n    void Release() { lock_->ReleaseShared(); }\n\n   private:\n    KernelSharedMutex* lock_;\n  };\n\n  KernelSharedMutex() { lock_ = os::CreateSharedMutex(); }\n  ~KernelSharedMutex() { os::DestroySharedMutex(lock_); }\n\n  // Exclusive mode operations\n  bool Try() { return os::TryAcquireSharedMutex(lock_); }\n  bool Acquire() { return os::AcquireSharedMutex(lock_); }\n  void Release() { os::ReleaseSharedMutex(lock_); }\n\n  // Shared mode operations\n  bool TryShared() { return os::TrySharedAcquireSharedMutex(lock_); }\n  bool AcquireShared() { return os::SharedAcquireSharedMutex(lock_); }\n  void ReleaseShared() { os::SharedReleaseSharedMutex(lock_); }\n\n  // Return shared operations interface\n  Shared shared() { return Shared(this); }\n\n private:\n  os::SharedMutex lock_;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(KernelSharedMutex);\n};\n\n/// @brief: Type trait to identify mutex types\ntemplate <class T> class isMutex {\n public:\n  enum { value = false };\n};\ntemplate <> class isMutex<HybridMutex> {\n public:\n  enum { value = true };\n};\ntemplate <> class isMutex<KernelMutex> {\n public:\n  enum { value = true };\n};\ntemplate <> class isMutex<SpinMutex> {\n public:\n  enum { value = true };\n};\ntemplate <> class isMutex<KernelSharedMutex> {\n public:\n  enum { value = true };\n};\n\n/// @brief: A class behaves as a lock in a scope. When trying to enter into the\n/// critical section, creat a object of this class. After the control path goes\n/// out of the scope, it will release the lock automatically.\ntemplate <class LockType> class ScopedAcquire {\n public:\n  /// @brief: When constructing, acquire the lock.\n  /// @param: lock(Input), pointer to an existing lock.\n  explicit ScopedAcquire(LockType* lock) : lock_(lock), doRelease(true) {\n    static_assert(isMutex<LockType>::value, \"ScopedAcquire requires a mutex type.\");\n    lock_.Acquire();\n  }\n  explicit ScopedAcquire(LockType lock) : lock_(lock), doRelease(true) {\n    static_assert(!isMutex<LockType>::value, \"Mutex types are not copyable.\");\n    lock_.Acquire();\n  }\n\n  /// @brief: when destructing, release the lock.\n  ~ScopedAcquire() {\n    if (doRelease) lock_.Release();\n  }\n\n  /// @brief: Release the lock early.  Avoid using when possible.\n  void Release() {\n    lock_.Release();\n    doRelease = false;\n  }\n\n private:\n  /// @brief: Adapts between pointers to mutex types and mutex pointer types.\n  template <class T, bool B> class container {\n   public:\n    container(T* lock) : lock_(lock) {}\n    __forceinline bool Acquire() { return lock_->Acquire(); }\n    __forceinline void Release() { return lock_->Release(); }\n\n   private:\n    T* lock_;\n  };\n\n  /// @brief: Specialization for mutex pointer types.\n  template <class T> class container<T, false> {\n   public:\n    container(T lock) : lock_(lock) {}\n    __forceinline bool Acquire() { return lock_.Acquire(); }\n    __forceinline void Release() { return lock_.Release(); }\n\n   private:\n    T lock_;\n  };\n\n  container<LockType, isMutex<LockType>::value> lock_;\n  bool doRelease;\n\n  /// @brief: Disable copiable and assignable ability.\n  DISALLOW_COPY_AND_ASSIGN(ScopedAcquire);\n};\n\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_SUTIL_LOCKS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/memory.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// Memory related utility functions.\n\n#ifndef HSA_RUNTIME_CORE_UTIL_MEMORY_H_\n#define HSA_RUNTIME_CORE_UTIL_MEMORY_H_\n\n#ifdef __linux__\n#include \"inc/hsa.h\"\n#include <sys/mman.h>\n#endif\n\nnamespace rocr {\n\n#ifdef __linux__\n/// @brief Converts @ref hsa_access_permission_t to mmap memory protection\n///        flags.\n__forceinline int PermissionsToMmapFlags(hsa_access_permission_t perms) {\n  switch (perms) {\n    case HSA_ACCESS_PERMISSION_RO:\n      return PROT_READ;\n    case HSA_ACCESS_PERMISSION_WO:\n      return PROT_WRITE;\n    case HSA_ACCESS_PERMISSION_RW:\n      return PROT_READ | PROT_WRITE;\n    case HSA_ACCESS_PERMISSION_NONE:\n    default:\n      return PROT_NONE;\n  }\n}\n#endif\n\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_UTIL_MEMORY_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/os.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// Minimal operating system abstraction interfaces.\n\n#ifndef HSA_RUNTIME_CORE_UTIL_OS_H_\n#define HSA_RUNTIME_CORE_UTIL_OS_H_\n\n#include <string>\n#include <vector>\n#include \"utils.h\"\n\nnamespace rocr {\nnamespace os {\ntypedef void* LibHandle;\ntypedef void* Semaphore;\ntypedef void* Mutex;\ntypedef void* SharedMutex;\ntypedef void* Thread;\ntypedef void* EventHandle;\n\ntypedef enum {\n  OS_THREAD_PRIORITY_DEFAULT    = -1,\n  OS_THREAD_PRIORITY_HIGH       = 254,\n  OS_THREAD_PRIORITY_MAX        = 255,\n} ThreadPriority;\n\nenum class os_t { OS_WIN = 0, OS_LINUX, COUNT };\nstatic __forceinline std::underlying_type<os_t>::type os_index(os_t val) {\n  return std::underlying_type<os_t>::type(val);\n}\n\n#ifdef _WIN32\nstatic const os_t current_os = os_t::OS_WIN;\n#elif __linux__\nstatic const os_t current_os = os_t::OS_LINUX;\n#else\nstatic_assert(false, \"Operating System not detected!\");\n#endif\n\n/// @brief: Loads dynamic library based on file name. Return value will be NULL\n/// if failed.\n/// @param: filename(Input), file name of the library.\n/// @return: LibHandle.\nLibHandle LoadLib(std::string filename);\n\n/// @brief: Gets the address of exported symbol. Return NULl if failed.\n/// @param: lib(Input), library handle which exporting from.\n/// @param: export_name(Input), the name of the exported symbol.\n/// @return: void*.\nvoid* GetExportAddress(LibHandle lib, std::string export_name);\n\n/// @brief: Unloads the dynamic library.\n/// @param: lib(Input), library handle which will be unloaded.\nvoid CloseLib(LibHandle lib);\n\n/// @brief: Lists loaded tool libraries that contain\n/// symbol HSA_AMD_TOOL_PRIORITY\n/// @return: List of library handles\nstd::vector<LibHandle> GetLoadedToolsLib();\n\n/// @brief: Returns the library's path name.\n/// @param: lib(Input), libray handle\n/// @return: Path name of library\nstd::string GetLibraryName(LibHandle lib);\n\n/// @brief: Creates a Semaphore, will return NULL if failed.\n/// @param: void.\n/// @return: Semaphore.\nSemaphore CreateSemaphore();\n\n/// @brief: Waits for the semaphore. This is a blocking wait.\n/// If the Semaphore is signalled, this function will return.\n/// @param: sem(Input), handle to the semaphore.\n/// @return: void.\nbool WaitSemaphore(Semaphore sem);\n\n/// @brief: Post/Signal/Wake-up the semaphore\n/// @param: sem(Input), handle to the semaphore.\n/// @return: void.\nvoid PostSemaphore(Semaphore sem);\n\n/// @brief: Destroys the semaphore.\n/// @param: sem(Input), handle to the semaphore.\n/// @return: void.\nvoid DestroySemaphore(Semaphore sem);\n\n/// @brief: Creates a mutex, will return NULL if failed.\n/// @param: void.\n/// @return: Mutex.\nMutex CreateMutex();\n\n/// @brief: Tries to acquire the mutex once, if successed, return true.\n/// @param: lock(Input), handle to the mutex.\n/// @return: bool.\nbool TryAcquireMutex(Mutex lock);\n\n/// @brief: Aquires the mutex, if the mutex is locked, it will wait until it is\n/// released. If the mutex is acquired successfully, it will return true.\n/// @param: lock(Input), handle to the mutex.\n/// @return: bool.\nbool AcquireMutex(Mutex lock);\n\n/// @brief: Releases the mutex.\n/// @param: lock(Input), handle to the mutex.\n/// @return: void.\nvoid ReleaseMutex(Mutex lock);\n\n/// @brief: Destroys the mutex.\n/// @param: lock(Input), handle to the mutex.\n/// @return: void.\nvoid DestroyMutex(Mutex lock);\n\n/// @brief: Creates a shared mutex, will return NULL if failed.\n/// @param: void.\n/// @return: SharedMutex.\nSharedMutex CreateSharedMutex();\n\n/// @brief: Tries to acquire the mutex in exclusive mode once, if successed, return true.\n/// @param: lock(Input), handle to the shared mutex.\n/// @return: bool.\nbool TryAcquireSharedMutex(SharedMutex lock);\n\n/// @brief: Aquires the mutex in exclusive mode, if the mutex is locked, it will wait until it is\n/// released. If the mutex is acquired successfully, it will return true.\n/// @param: lock(Input), handle to the mutex.\n/// @return: bool.\nbool AcquireSharedMutex(SharedMutex lock);\n\n/// @brief: Releases the mutex from exclusive mode.\n/// @param: lock(Input), handle to the mutex.\n/// @return: void.\nvoid ReleaseSharedMutex(SharedMutex lock);\n\n/// @brief: Tries to acquire the mutex in shared mode once, if successed, return true.\n/// @param: lock(Input), handle to the mutex.\n/// @return: bool.\nbool TrySharedAcquireSharedMutex(SharedMutex lock);\n\n/// @brief: Aquires the mutex in shared mode, if the mutex in exclusive mode, it will wait until it\n/// is released. If the mutex is acquired successfully, it will return true.\n/// @param: lock(Input), handle to the mutex.\n/// @return: bool.\nbool SharedAcquireSharedMutex(SharedMutex lock);\n\n/// @brief: Releases the mutex from shared mode.\n/// @param: lock(Input), handle to the mutex.\n/// @return: void.\nvoid SharedReleaseSharedMutex(SharedMutex lock);\n\n/// @brief: Destroys the mutex.\n/// @param: lock(Input), handle to the mutex.\n/// @return: void.\nvoid DestroySharedMutex(SharedMutex lock);\n\n/// @brief: Puts current thread to sleep.\n/// @param: delayInMs(Input), time in millisecond for sleeping.\n/// @return: void.\nvoid Sleep(int delayInMs);\n\n/// @brief: Puts current thread to sleep.\n/// @param: delayInMs(Input), time in millisecond for sleeping.\n/// @return: void.\nvoid uSleep(int delayInUs);\n\n/// @brief: Yields current thread.\n/// @param: void.\n/// @return: void.\nvoid YieldThread();\n\ntypedef void (*ThreadEntry)(void*);\n\n/// @brief: Creates a thread will return NULL if failed.\n/// @param: entry_function(Input), a pointer to the function which the thread\n/// starts from.\n/// @param: entry_argument(Input), a pointer to the argument of the thread\n/// function.\n/// @param: stack_size(Input), size of the thread's stack, 0 by default.\n/// @param: priority(Input), thread priority.\n/// @return: Thread, a handle to thread created.\nThread CreateThread(ThreadEntry entry_function, void* entry_argument,\n                    uint stack_size = 0, int priority = OS_THREAD_PRIORITY_DEFAULT);\n\n/// @brief: Destroys the thread.\n/// @param: thread(Input), thread handle to what will be destroyed.\n/// @return: void.\nvoid CloseThread(Thread thread);\n\n/// @brief: Waits for specific thread to finish, if successful, return true.\n/// @param: thread(Input), handle to waiting thread.\n/// @return: bool.\nbool WaitForThread(Thread thread);\n\n/// @brief: Waits for multiple threads to finish, if successful, return true.\n/// @param; threads(Input), a pointer to a list of thread handle.\n/// @param: thread_count(Input), number of threads to be waited on.\n/// @return: bool.\nbool WaitForAllThreads(Thread* threads, uint thread_count);\n\n/// @brief: Determines if environment key is set.\n/// @param: env_var_name(Input), name of the environment value.\n/// @return: bool, true for binding any value to environment key,\n/// including an empty string. False otherwise\nbool IsEnvVarSet(std::string env_var_name);\n\n/// @brief: Sets the environment value.\n/// @param: env_var_name(Input), name of the environment value.\n/// @param: env_var_value(Input), value of the environment value.s\n/// @return: void.\nvoid SetEnvVar(std::string env_var_name, std::string env_var_value);\n\n/// @brief: Gets the value of environment value.\n/// @param: env_var_name(Input), name of the environment value.\n/// @return: std::string, value of the environment value, returned as string.\nstd::string GetEnvVar(std::string env_var_name);\n\n/// @brief: Gets the process ID.\n/// @param: void\n/// @return: int, process ID returned as int.\nint GetProcessId();\n\n/// @brief: Gets the max virtual memory size accessible to the application.\n/// @param: void.\n/// @return: size_t, size of the accessible memory to the application.\nsize_t GetUserModeVirtualMemorySize();\n\n/// @brief: Gets the max physical host system memory size.\n/// @param: void.\n/// @return: size_t, size of the physical host system memory.\nsize_t GetUsablePhysicalHostMemorySize();\n\n/// @brief: Gets the virtual memory base address. It is hardcoded to 0.\n/// @param: void.\n/// @return: uintptr_t, always 0.\nuintptr_t GetUserModeVirtualMemoryBase();\n\n/// @brief os event api, create an event\n/// @param: auto_reset whether an event can reset the status automatically\n/// @param: init_state initial state of the event\n/// @return: event handle\nEventHandle CreateOsEvent(bool auto_reset, bool init_state);\n\n/// @brief os event api, destroy an event\n/// @param: event handle\n/// @return: whether destroy is correct\nint DestroyOsEvent(EventHandle event);\n\n/// @brief os event api, wait on event\n/// @param: event Event handle\n/// @param: milli_seconds wait time\n/// @return: Indicate success or timeout\nint WaitForOsEvent(EventHandle event, unsigned int milli_seconds);\n\n/// @brief os event api, set event state\n/// @param: event Event handle\n/// @return: Whether event set is correct\nint SetOsEvent(EventHandle event);\n\n/// @brief os event api, reset event state\n/// @param: event Event handle\n/// @return: Whether event reset is correct\nint ResetOsEvent(EventHandle event);\n\n/// @brief reads a clock which is deemed to be accurate for elapsed time\n/// measurements, though not necessarilly fast to query\n/// @return clock counter value\nuint64_t ReadAccurateClock();\n\n/// @brief retrieves the frequency in Hz of the unit used in ReadAccurateClock.\n/// It does not necessarilly reflect the resolution of the clock, but is the\n/// value needed to convert a difference in the clock's counter value to elapsed\n/// seconds.  This frequency does not change at runtime.\n/// @return returns the frequency\nuint64_t AccurateClockFrequency();\n\n/// @brief read the system clock which serves as the HSA system clock\n/// counter in KFD.\nuint64_t ReadSystemClock();\n\n/// @brief read the system clock frequency\nuint64_t SystemClockFrequency();\n\ntypedef struct cpuid_s {\n  char ManufacturerID[13];  // 12 char, NULL terminated\n  bool mwaitx;\n} cpuid_t;\n\n/// @brief parse CPUID\n/// @param: cpuinfo struct to be filled\nbool ParseCpuID(cpuid_t* cpuinfo);\n\n}   //  namespace os\n}   //  namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_UTIL_OS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/simple_heap.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// A simple best fit memory allocator with eager compaction.  Manages block sub-allocation.\n// For use when memory efficiency is more important than allocation speed.\n// O(log n) time.\n\n#ifndef HSA_RUNTME_CORE_UTIL_SIMPLE_HEAP_H_\n#define HSA_RUNTME_CORE_UTIL_SIMPLE_HEAP_H_\n\n#include <map>\n#include <deque>\n#include <utility>\n\n#include \"core/util/utils.h\"\n\nnamespace rocr {\n\ntemplate <typename Allocator> class SimpleHeap {\n private:\n  struct Fragment_T {\n    typedef std::multimap<size_t, uintptr_t>::iterator ptr_t;\n    ptr_t free_list_entry_;\n    struct {\n      size_t size : 62;\n      bool discard : 1;\n      bool free : 1;\n    };\n\n    Fragment_T(ptr_t Iterator, size_t Len, bool Free)\n        : free_list_entry_(Iterator), size(Len), discard(false), free(Free) {}\n    Fragment_T() = default;\n  };\n\n  struct Block {\n    uintptr_t base_ptr_;\n    size_t length_;\n\n    Block(uintptr_t base, size_t length) : base_ptr_(base), length_(length) {}\n    Block() = default;\n  };\n\n  Allocator block_allocator_;\n\n  std::multimap<size_t, uintptr_t> free_list_;\n  std::map<uintptr_t, std::map<uintptr_t, Fragment_T>> block_list_;\n  std::deque<Block> block_cache_;\n\n  // Size of blocks that are at least partially in use.\n  size_t in_use_size_;\n  // Total size of block cache\n  size_t cache_size_;\n\n  __forceinline bool isFree(const Fragment_T& node) { return node.free; }\n  __forceinline void setUsed(Fragment_T& node) {\n    node.free = false;\n    node.free_list_entry_ = free_list_.end();\n  }\n  __forceinline void setFree(Fragment_T& node, typename Fragment_T::ptr_t Iterator) {\n    node.free_list_entry_ = Iterator;\n    node.free = true;\n  }\n  __forceinline Fragment_T makeFragment(size_t Len) {\n    return Fragment_T(free_list_.end(), Len, false);\n  }\n  __forceinline Fragment_T makeFragment(typename Fragment_T::ptr_t Iterator, size_t Len) {\n    return Fragment_T(Iterator, Len, true);\n  }\n  __forceinline void removeFreeListEntry(Fragment_T& node) {\n    if (node.free_list_entry_ != free_list_.end()) {\n      free_list_.erase(node.free_list_entry_);\n      node.free_list_entry_ = free_list_.end();\n    }\n  }\n  __forceinline void discard(Fragment_T& node) {\n    removeFreeListEntry(node);\n    node.discard = true;\n  }\n\n public:\n  explicit SimpleHeap(const Allocator& BlockAllocator = Allocator())\n      : block_allocator_(BlockAllocator), in_use_size_(0), cache_size_(0) {}\n  ~SimpleHeap() {\n    trim();\n    // Leak here may be due to the user.  Check is for debugging only.\n    // assert(in_use_size_ == 0 && \"Leak in SimpleHeap.\");\n  }\n\n  SimpleHeap(const SimpleHeap& rhs) = delete;\n  SimpleHeap(SimpleHeap&& rhs) = delete;\n  SimpleHeap& operator=(const SimpleHeap& rhs) = delete;\n  SimpleHeap& operator=(SimpleHeap&& rhs) = delete;\n\n  void* alloc(size_t bytes) {\n    // Find best fit.\n    auto free_fragment = free_list_.lower_bound(bytes);\n    uintptr_t base;\n    size_t size;\n\n    if (free_fragment != free_list_.end()) {\n      base = free_fragment->second;\n      size = free_fragment->first;\n      free_list_.erase(free_fragment);\n\n      assert(size >= bytes && \"SimpleHeap: map lower_bound failure.\");\n\n      // Find the containing block and fragment\n      auto it = block_list_.upper_bound(base);\n      it--;\n      auto& frag_map = it->second;\n      const auto& fragment = frag_map.find(base);\n\n      assert(fragment != frag_map.end() && \"Inconsistency in SimpleHeap.\");\n      assert(size == fragment->second.size && \"Inconsistency in SimpleHeap.\");\n\n      // Sub-allocate from fragment.\n      fragment->second.size = bytes;\n      setUsed(fragment->second);\n      // Record remaining free space.\n      if (size > bytes) {\n        free_fragment = free_list_.insert(std::make_pair(size - bytes, base + bytes));\n        frag_map[base + bytes] = makeFragment(free_fragment, size - bytes);\n      }\n      return reinterpret_cast<void*>(base);\n    }\n\n    // No usable fragment, check block cache\n    if (bytes < default_block_size() && !block_cache_.empty()) {\n      const auto& block = block_cache_.back();\n      base = block.base_ptr_;\n      size = block.length_;\n      block_cache_.pop_back();\n      cache_size_ -= size;\n    } else {  // Alloc new block - new block may be larger than default.\n      void* ptr = block_allocator_.alloc(bytes, size);\n      base = reinterpret_cast<uintptr_t>(ptr);\n      assert(ptr != nullptr && \"Block allocation failed, Allocator is expected to throw.\");\n    }\n\n    in_use_size_ += size;\n    assert(size >= bytes && \"Alloc exceeds block size.\");\n    // Sub alloc and insert free region.\n    if (size > bytes) {\n      free_fragment = free_list_.insert(std::make_pair(size - bytes, base + bytes));\n      block_list_[base][base + bytes] = makeFragment(free_fragment, size - bytes);\n    }\n    // Track used region\n    block_list_[base][base] = makeFragment(bytes);\n\n    // Disallow multiple suballocation from large blocks.\n    // Prevents a small allocation from retaining a large block.\n    if (bytes > default_block_size()) {\n      bool err = discardBlock(reinterpret_cast<void*>(base));\n      assert(err && \"Large block discard failed.\");\n    }\n\n    return reinterpret_cast<void*>(base);\n  }\n\n  bool free(void* ptr) {\n    if (ptr == nullptr) return true;\n\n    uintptr_t base = reinterpret_cast<uintptr_t>(ptr);\n\n    // Find fragment and validate.\n    auto frag_map_it = block_list_.upper_bound(base);\n    if (frag_map_it == block_list_.begin()) return false;\n    frag_map_it--;\n    auto& frag_map = frag_map_it->second;\n    auto fragment = frag_map.find(base);\n    if (fragment == frag_map.end() || isFree(fragment->second)) return false;\n\n    bool discard = fragment->second.discard;\n\n    // Merge lower\n    if (fragment != frag_map.begin()) {\n      auto lower = fragment;\n      lower--;\n      if (isFree(lower->second)) {\n        removeFreeListEntry(lower->second);\n        lower->second.size += fragment->second.size;\n        frag_map.erase(fragment);\n        fragment = lower;\n      }\n    }\n\n    // Merge upper\n    {\n      auto upper = fragment;\n      upper++;\n      if ((upper != frag_map.end()) && isFree(upper->second)) {\n        removeFreeListEntry(upper->second);\n        fragment->second.size += upper->second.size;\n        frag_map.erase(upper);\n      }\n    }\n\n    // Release whole free blocks.\n    if (frag_map.size() == 1) {\n      Block block(fragment->first, fragment->second.size);\n      block_list_.erase(frag_map_it);\n\n      // Discard or add to the block cache.\n      if (discard) {\n        block_allocator_.free(reinterpret_cast<void*>(block.base_ptr_), block.length_);\n      } else {\n        block_cache_.push_back(block);\n        cache_size_ += block.length_;\n        in_use_size_ -= block.length_;\n      }\n\n      balance();\n\n      // Don't publish free space since block was moved to the cache.\n      return true;\n    }\n\n    // Don't report free memory if discarding the fragment.\n    if (discard) return true;\n\n    // Report free fragment\n    const auto& freeEntry =\n        free_list_.insert(std::make_pair(size_t(fragment->second.size), fragment->first));\n    setFree(fragment->second, freeEntry);\n\n    return true;\n  }\n\n  void balance() {\n    // Release old blocks when over cache limit.\n    while ((block_cache_.size() > 1) && (cache_size_ > in_use_size_ * 2)) {\n      const auto& block = block_cache_.front();\n      block_allocator_.free(reinterpret_cast<void*>(block.base_ptr_), block.length_);\n      cache_size_ -= block.length_;\n      block_cache_.pop_front();\n    }\n  }\n\n  void trim() {\n    for (const auto& block : block_cache_)\n      block_allocator_.free(reinterpret_cast<void*>(block.base_ptr_), block.length_);\n    block_cache_.clear();\n    cache_size_ = 0;\n  }\n\n  size_t cache_size() const { return cache_size_; }\n\n  size_t default_block_size() const { return block_allocator_.block_size(); }\n\n  // Prevent reuse of the block containing ptr.  No further fragments will be allocated from the\n  // block and the block will not be added to the block cache when it is free.\n  bool discardBlock(void* ptr) {\n    if (ptr == nullptr) return true;\n\n    uintptr_t base = reinterpret_cast<uintptr_t>(ptr);\n\n    // Find block validate.\n    auto frag_map_it = block_list_.upper_bound(base);\n    if (frag_map_it == block_list_.begin()) return false;\n    frag_map_it--;\n    auto& frag_map = frag_map_it->second;\n    if ((base < frag_map.begin()->first) ||\n        (frag_map.rbegin()->first + frag_map.rbegin()->second.size <= base))\n      return false;\n\n    // Is block already discarded?\n    if (frag_map.begin()->second.discard) return true;\n\n    // Mark all fragments for discard and compute block size.  Removes freelist records for all\n    // fragments in the block.\n    size_t size = 0;\n    for (auto& frag : frag_map) {\n      discard(frag.second);\n      size += frag.second.size;\n    }\n\n    // Remove discarded block from in-use tracking and rebalance the block cache.\n    in_use_size_ -= size;\n    balance();\n\n    return true;\n  }\n};\n\n}  // namespace rocr\n\n#endif  // HSA_RUNTME_CORE_UTIL_SIMPLE_HEAP_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/small_heap.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"small_heap.h\"\n\nnamespace rocr {\n\n// Inserts node into freelist after place.\n// Assumes node will not be an end of the list (list has guard nodes).\nvoid SmallHeap::insertafter(SmallHeap::iterator_t place, SmallHeap::iterator_t node) {\n  assert(place->first < node->first && \"Order violation\");\n  assert(isfree(place->second) && \"Freelist operation error.\");\n  iterator_t next = place->second.next;\n  node->second.next = next;\n  node->second.prior = place;\n  place->second.next = node;\n  next->second.prior = node;\n}\n\n// Removes node from freelist.\n// Assumes node will not be an end of the list (list has guard nodes).\nvoid SmallHeap::remove(SmallHeap::iterator_t node) {\n  assert(isfree(node->second) && \"Freelist operation error.\");\n  node->second.prior->second.next = node->second.next;\n  node->second.next->second.prior = node->second.prior;\n  setused(node->second);\n}\n\n// Returns high if merge failed or the merged node.\nSmallHeap::memory_t::iterator SmallHeap::merge(SmallHeap::memory_t::iterator low,\n                                               SmallHeap::memory_t::iterator high) {\n  assert(isfree(low->second) && \"Merge with allocated block\");\n  assert(isfree(high->second) && \"Merge with allocated block\");\n\n  if ((char*)low->first + low->second.len != (char*)high->first) return high;\n\n  assert(!islastfree(high->second) && \"Illegal merge.\");\n\n  low->second.len += high->second.len;\n  low->second.next = high->second.next;\n  high->second.next->second.prior = low;\n\n  memory.erase(high);\n  return low;\n}\n\nvoid SmallHeap::free(void* ptr) {\n  if (ptr == nullptr) return;\n\n  auto iterator = memory.find(ptr);\n\n  // Check for illegal free\n  if (iterator == memory.end()) {\n    assert(false && \"Illegal free.\");\n    return;\n  }\n\n  // Return memory to total and link node into free list\n  total_free += iterator->second.len;\n\n  // Could also traverse the free list which might be faster in some cases.\n  auto before = iterator;\n  before--;\n  while (!isfree(before->second)) before--;\n  assert(before->second.next->first > iterator->first && \"Inconsistency in small heap.\");\n  insertafter(before, iterator);\n\n  // Attempt compaction\n  iterator = merge(before, iterator);\n  merge(iterator, iterator->second.next);\n\n  // Update lowHighBondary\n  high.erase(ptr);\n}\n\nvoid* SmallHeap::alloc(size_t bytes) {\n  // Is enough memory available?\n  if ((bytes > total_free) || (bytes == 0)) return nullptr;\n\n  iterator_t current;\n\n  // Walk the free list and allocate at first fitting location\n  current = firstfree();\n  while (!islastfree(current->second)) {\n    if (bytes <= current->second.len) {\n      // Decrement from total\n      total_free -= bytes;\n\n      // Split node\n      if (bytes != current->second.len) {\n        void* remaining = (char*)current->first + bytes;\n        Node& node = memory[remaining];\n        node.len = current->second.len - bytes;\n        current->second.len = bytes;\n        insertafter(current, memory.find(remaining));\n      }\n\n      remove(current);\n      return current->first;\n    }\n    current = current->second.next;\n  }\n  assert(current->second.len == 0 && \"Freelist corruption.\");\n\n  // Can't service the request due to fragmentation\n  return nullptr;\n}\n\nvoid* SmallHeap::alloc_high(size_t bytes) {\n  // Is enough memory available?\n  if ((bytes > total_free) || (bytes == 0)) return nullptr;\n\n  iterator_t current;\n\n  // Walk the free list and allocate at first fitting location\n  current = lastfree();\n  while (!isfirstfree(current->second)) {\n    if (bytes <= current->second.len) {\n      // Decrement from total\n      total_free -= bytes;\n\n      void* alloc;\n      // Split node\n      if (bytes != current->second.len) {\n        alloc = (char*)current->first + current->second.len - bytes;\n        current->second.len -= bytes;\n        Node& node = memory[alloc];\n        node.len = bytes;\n        setused(node);\n      } else {\n        alloc = current->first;\n        remove(current);\n      }\n\n      high.insert(alloc);\n      return alloc;\n    }\n    current = current->second.prior;\n  }\n  assert(current->second.len == 0 && \"Freelist corruption.\");\n\n  // Can't service the request due to fragmentation\n  return nullptr;\n}\n\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/small_heap.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// A simple first fit memory allocator with eager compaction.  For use with few\n// items (where list iteration is faster than trees).\n// Not thread safe!\n\n#ifndef HSA_RUNTME_CORE_UTIL_SMALL_HEAP_H_\n#define HSA_RUNTME_CORE_UTIL_SMALL_HEAP_H_\n\n#include <map>\n#include <set>\n\n#include \"utils.h\"\n\nnamespace rocr {\n\nclass SmallHeap {\n private:\n  struct Node;\n  typedef std::map<void*, Node> memory_t;\n  typedef memory_t::iterator iterator_t;\n\n  struct Node {\n    size_t len;\n    iterator_t next;\n    iterator_t prior;\n  };\n\n  SmallHeap(const SmallHeap& rhs) = delete;\n  SmallHeap& operator=(const SmallHeap& rhs) = delete;\n\n  void* const pool;\n  const size_t length;\n\n  size_t total_free;\n  memory_t memory;\n  std::set<void*> high;\n\n  __forceinline bool isfree(const Node& node) const { return node.next != memory.begin(); }\n  __forceinline bool islastfree(const Node& node) const { return node.next == memory.end(); }\n  __forceinline bool isfirstfree(const Node& node) const { return node.prior == memory.end(); }\n  __forceinline void setlastfree(Node& node) { node.next = memory.end(); }\n  __forceinline void setfirstfree(Node& node) { node.prior = memory.end(); }\n  __forceinline void setused(Node& node) { node.next = memory.begin(); }\n\n  __forceinline iterator_t firstfree() { return memory.begin()->second.next; }\n  __forceinline iterator_t lastfree() { return memory.rbegin()->second.prior; }\n  void insertafter(iterator_t place, iterator_t node);\n  void remove(iterator_t node);\n  iterator_t merge(iterator_t low, iterator_t high);\n\n public:\n  SmallHeap() : pool(nullptr), length(0), total_free(0) {}\n  SmallHeap(void* base, size_t length)\n      : pool(base), length(length), total_free(length) {\n    assert(pool != nullptr && \"Invalid base address.\");\n    assert(pool != (void*)0xFFFFFFFFFFFFFFFFull && \"Invalid base address.\");\n    assert((char*)pool + length != (char*)0xFFFFFFFFFFFFFFFFull && \"Invalid pool bounds.\");\n\n    Node& start = memory[0];\n    Node& node = memory[pool];\n    Node& end = memory[(void*)0xFFFFFFFFFFFFFFFFull];\n\n    start.len = 0;\n    start.next = memory.find(pool);\n    setfirstfree(start);\n\n    node.len = length;\n    node.prior = memory.begin();\n    node.next = --memory.end();\n\n    end.len = 0;\n    end.prior = start.next;\n    setlastfree(end);\n\n    high.insert((void*)0xFFFFFFFFFFFFFFFFull);\n  }\n\n  void* alloc(size_t bytes);\n  void* alloc_high(size_t bytes);\n  void free(void* ptr);\n\n  void* base() const { return pool; }\n  size_t size() const { return length; }\n  size_t remaining() const { return total_free; }\n  void* high_split() const { return *high.begin(); }\n};\n\n}  // namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/timer.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/util/timer.h\"\n\nnamespace rocr {\nnamespace timer {\n\naccurate_clock::init::init() {\n  freq = os::AccurateClockFrequency();\n  accurate_clock::period_ns = 1e9 / double(freq);\n}\n\n// Calibrates the fast clock using the accurate clock.\nfast_clock::init::init() {\n  typedef accurate_clock clock;\n  clock::duration delay(std::chrono::milliseconds(1));\n\n  // calibrate clock\n  fast_clock::raw_rep min = 0;\n  clock::duration elapsed;\n\n  do {\n    elapsed = clock::duration::max();\n\n    for (int t = 0; t < 10; t++) {\n      fast_clock::raw_rep r1, r2;\n      clock::time_point t0, t1, t2, t3;\n\n      t0 = clock::now();\n      std::atomic_signal_fence(std::memory_order_acq_rel);\n      r1 = fast_clock::raw_now();\n      std::atomic_signal_fence(std::memory_order_acq_rel);\n      t1 = clock::now();\n      std::atomic_signal_fence(std::memory_order_acq_rel);\n\n      do {\n        t2 = clock::now();\n      } while (t2 - t1 < delay);\n\n      std::atomic_signal_fence(std::memory_order_acq_rel);\n      r2 = fast_clock::raw_now();\n      std::atomic_signal_fence(std::memory_order_acq_rel);\n      t3 = clock::now();\n\n      // If elapsed time is shorter than last recorded time and both the start\n      // and end times are confirmed correlated then record the clock readings.\n      // This protects against inaccuracy due to thread switching\n      if ((t3 - t1 < elapsed) && ((t1 - t0) * 10 < (t2 - t1)) &&\n          ((t3 - t2) * 10 < (t2 - t1))) {\n        elapsed = t3 - t1;\n        min = r2 - r1;\n      }\n    }\n    delay += delay;\n  } while (min < 1000);\n\n  fast_clock::freq = double(min) / duration_in_seconds(elapsed);\n  fast_clock::period_ps = 1e12 / fast_clock::freq;\n  // printf(\"Timer setup took %f ms\\n\", duration_in_seconds(elapsed)*1000.0f);\n  // printf(\"Fast clock frequency: %f MHz\\n\", double(fast_clock::freq)/1e6);\n}\n\ndouble accurate_clock::period_ns;\naccurate_clock::raw_frequency accurate_clock::freq;\naccurate_clock::init accurate_clock::accurate_clock_init;\n\ndouble fast_clock::period_ps;\nfast_clock::raw_frequency fast_clock::freq;\nfast_clock::init fast_clock::fast_clock_init;\n}   //  namespace timer\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/timer.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_UTIL_TIMER_H_\n#define HSA_RUNTIME_CORE_UTIL_TIMER_H_\n\n#include \"core/util/utils.h\"\n#include \"core/util/os.h\"\n#include <chrono>\n#include <time.h>\n#include <type_traits>\n\nnamespace rocr {\nnamespace timer {\n\n// Needed to patch around a mixed arithmetic bug in MSVC's duration_cast as of\n// VS 2013.\ntemplate <bool isFloat, bool isSigned>\nstruct wide_type {\n  typedef double type;\n};\ntemplate <>\nstruct wide_type<false, false> {\n  typedef uintmax_t type;\n};\ntemplate <>\nstruct wide_type<false, true> {\n  typedef intmax_t type;\n};\n\ntemplate <typename To, typename Rep, typename Period>\nstatic __forceinline To\n    duration_cast(const std::chrono::duration<Rep, Period>& d) {\n  typedef typename wide_type<std::is_floating_point<Rep>::value,\n                             std::is_signed<Rep>::value>::type wide;\n  typedef std::chrono::duration<wide, typename To::period> unit_convert_t;\n\n  unit_convert_t temp = std::chrono::duration_cast<unit_convert_t>(d);\n  return To(static_cast<typename To::rep>(temp.count()));\n}\n// End patch\n\ntemplate <typename Rep, typename Period>\nstatic __forceinline double duration_in_seconds(\n    std::chrono::duration<Rep, Period> delta) {\n  typedef std::chrono::duration<double, std::ratio<1, 1>> seconds;\n  return seconds(delta).count();\n}\n\ntemplate <typename rep>\nstatic __forceinline rep duration_from_seconds(double delta) {\n  typedef std::chrono::duration<double, std::ratio<1, 1>> seconds;\n  return std::chrono::duration_cast<rep>(seconds(delta));\n}\n\n// Provices a C++11 standard clock interface to the os::AccurateClock functions\nclass accurate_clock {\n public:\n  typedef double rep;\n  typedef std::nano period;\n  typedef std::chrono::duration<rep, period> duration;\n  typedef std::chrono::time_point<accurate_clock> time_point;\n\n  static const bool is_steady = true;\n\n  static __forceinline time_point now() {\n    return time_point(duration(raw_now() * period_ns));\n  }\n\n  // These two extra APIs and types let us use clocks without conversion to the\n  // arbitrary period unit\n  typedef uint64_t raw_rep;\n  typedef uint64_t raw_frequency;\n\n  static __forceinline raw_rep raw_now() { return os::ReadAccurateClock(); }\n  static __forceinline raw_frequency raw_freq() { return freq; }\n\n private:\n  static double period_ns;\n  static raw_frequency freq;\n\n  class init {\n   public:\n    init();\n  };\n  static init accurate_clock_init;\n};\n\n// Provices a C++11 standard clock interface to the lowest latency approximate\n// clock\nclass fast_clock {\n public:\n  typedef double rep;\n  typedef std::pico period;\n  typedef std::chrono::duration<rep, period> duration;\n  typedef std::chrono::time_point<fast_clock> time_point;\n\n  static const bool is_steady = true;\n\n  static __forceinline time_point now() {\n    return time_point(duration(raw_now() * period_ps));\n  }\n\n  // These two extra APIs and types let us use clocks without conversion to the\n  // arbitrary period unit\n  typedef uint64_t raw_rep;\n  typedef double raw_frequency;\n\n#if defined(__x86_64__) || defined(_M_X64)\n  static __forceinline raw_rep raw_now() { return __rdtsc(); }\n  static __forceinline raw_frequency raw_freq() { return freq; }\n#else\n  static __forceinline raw_rep raw_now() {\n    struct timespec ts;\n    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);\n    return (raw_rep(ts.tv_sec) * 1000000000 + raw_rep(ts.tv_nsec));\n  }\n  static __forceinline raw_frequency raw_freq() { return 1.e-9; }\n#endif\n\n private:\n  static double period_ps;\n  static raw_frequency freq;\n\n  class init {\n   public:\n    init();\n  };\n  static init fast_clock_init;\n};\n}   //  namespace timer\n}   //  namespace rocr  \n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/utils.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// Generally useful utility functions\n\n#ifndef HSA_RUNTIME_CORE_UTIL_UTILS_H_\n#define HSA_RUNTIME_CORE_UTIL_UTILS_H_\n\n#include \"stdint.h\"\n#include \"stddef.h\"\n#include \"stdlib.h\"\n#include \"stdarg.h\"\n#include \"unistd.h\"\n#include <assert.h>\n#include <iostream>\n#include <string>\n#include <algorithm>\n#include <sstream>\n#include <thread>\n\nnamespace rocr {\nextern FILE* log_file;\nextern uint8_t log_flags[8];\n\ntypedef unsigned int uint;\ntypedef uint64_t uint64;\n\n#if defined(__GNUC__)\n#if defined(__i386__) || defined(__x86_64__)\n#include <x86intrin.h>\n#endif\n\n#define __forceinline __inline__ __attribute__((always_inline))\n#define __declspec(x) __attribute__((x))\n#undef __stdcall\n#define __stdcall  // __attribute__((__stdcall__))\n#define __ALIGNED__(x) __attribute__((aligned(x)))\n\nvoid log_printf(const char* file, int line, const char* format, ...);\n\nstatic __forceinline void* _aligned_malloc(size_t size, size_t alignment) {\n#ifdef _ISOC11_SOURCE\n  return aligned_alloc(alignment, size);\n#else\n  void *mem = NULL;\n  if (0 != posix_memalign(&mem, alignment, size)) return NULL;\n  return mem;\n#endif\n}\nstatic __forceinline void _aligned_free(void* ptr) { return free(ptr); }\n#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))\n#include \"intrin.h\"\n#define __ALIGNED__(x) __declspec(align(x))\n#if (_MSC_VER < 1800)  // < VS 2013\nstatic __forceinline unsigned long long int strtoull(const char* str,\n                                                     char** endptr, int base) {\n  return static_cast<unsigned long long>(_strtoui64(str, endptr, base));\n}\n#endif\n#if (_MSC_VER < 1900)  // < VS 2015\n#define thread_local __declspec(thread)\n#endif\n#else\n#error \"Compiler and/or processor not identified.\"\n#endif\n\n#define STRING2(x) #x\n#define STRING(x) STRING2(x)\n\n#define PASTE2(x, y) x##y\n#define PASTE(x, y) PASTE2(x, y)\n\n#ifdef NDEBUG\n#define debug_warning_n(exp, limit)                                                                \\\n  do {                                                                                             \\\n  } while (false)\n#else\n#define debug_warning_n(exp, limit)                                                                \\\n  do {                                                                                             \\\n    static std::atomic<int> count(0);                                                              \\\n    if (!(exp) && (limit == 0 || count < limit)) {                                                 \\\n      fprintf(stderr, \"Warning: \" STRING(exp) \" in %s, \" __FILE__ \":\" STRING(__LINE__) \"\\n\",       \\\n              __PRETTY_FUNCTION__);                                                                \\\n      count++;                                                                                     \\\n    }                                                                                              \\\n  } while (false)\n#endif\n#define debug_warning(exp) debug_warning_n((exp), 0)\n\n#ifdef NDEBUG\n#define debug_print(fmt, ...)                                                                      \\\n  do {                                                                                             \\\n  } while (false)\n#else\n#define debug_print(fmt, ...)                                                                      \\\n  do {                                                                                             \\\n    fprintf(stderr, fmt, ##__VA_ARGS__);                                                           \\\n  } while (false)\n#endif\n\n#ifdef NDEBUG\n#define ifdebug if (false)\n#else\n#define ifdebug if (true)\n#endif\n\n#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)\n\n#define LogPrint(flag, format, ...)                                                                \\\n  do {                                                                                             \\\n    if (hsa_flag_isset64(log_flags, flag))                                                         \\\n      rocr::log_printf(__FILENAME__, __LINE__, format, ##__VA_ARGS__);                             \\\n  } while (false);\n\n// A macro to remove unused variable warnings\n#define UNUSED(x) (void)(x)\n\n// A macro to disallow the copy and move constructor and operator= functions\n#define DISALLOW_COPY_AND_ASSIGN(TypeName)                                                         \\\n  TypeName(const TypeName&) = delete;                                                              \\\n  TypeName(TypeName&&) = delete;                                                                   \\\n  void operator=(const TypeName&) = delete;                                                        \\\n  void operator=(TypeName&&) = delete;\n\ntemplate <typename lambda>\nclass ScopeGuard {\n public:\n  explicit __forceinline ScopeGuard(const lambda& release)\n      : release_(release), dismiss_(false) {}\n\n  ScopeGuard(ScopeGuard& rhs) { *this = rhs; }\n\n  __forceinline ~ScopeGuard() {\n    if (!dismiss_) release_();\n  }\n  __forceinline ScopeGuard& operator=(ScopeGuard& rhs) {\n    dismiss_ = rhs.dismiss_;\n    release_ = rhs.release_;\n    rhs.dismiss_ = true;\n    return *this;\n  }\n  __forceinline void Dismiss() { dismiss_ = true; }\n\n private:\n  lambda release_;\n  bool dismiss_;\n};\n\ntemplate <typename lambda>\nstatic __forceinline ScopeGuard<lambda> MakeScopeGuard(lambda rel) {\n  return ScopeGuard<lambda>(rel);\n}\n\n#define MAKE_SCOPE_GUARD_HELPER(lname, sname, ...) \\\n  auto lname = __VA_ARGS__;                        \\\n  ScopeGuard<decltype(lname)> sname(lname);\n#define MAKE_SCOPE_GUARD(...)                                   \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), \\\n                          PASTE(scopeGuard, __COUNTER__), __VA_ARGS__)\n#define MAKE_NAMED_SCOPE_GUARD(name, ...)                             \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), name, \\\n                          __VA_ARGS__)\n\n/// @brief: Finds out the min one of two inputs, input must support \">\"\n/// operator.\n/// @param: a(Input), a reference to type T.\n/// @param: b(Input), a reference to type T.\n/// @return: T.\ntemplate <class T>\nstatic __forceinline T Min(const T& a, const T& b) {\n  return (a > b) ? b : a;\n}\n\ntemplate <class T, class... Arg>\nstatic __forceinline T Min(const T& a, const T& b, Arg... args) {\n  return Min(a, Min(b, args...));\n}\n\n/// @brief: Find out the max one of two inputs, input must support \">\" operator.\n/// @param: a(Input), a reference to type T.\n/// @param: b(Input), a reference to type T.\n/// @return: T.\ntemplate <class T>\nstatic __forceinline T Max(const T& a, const T& b) {\n  return (b > a) ? b : a;\n}\n\ntemplate <class T, class... Arg>\nstatic __forceinline T Max(const T& a, const T& b, Arg... args) {\n  return Max(a, Max(b, args...));\n}\n\n/// @brief: Free the memory space which is newed previously.\n/// @param: ptr(Input), a pointer to memory space. Can't be NULL.\n/// @return: void.\nstruct DeleteObject {\n  template <typename T>\n  void operator()(const T* ptr) const {\n    delete ptr;\n  }\n};\n\n/// @brief: Checks if a value is power of two, if it is, return true. Be careful\n/// when passing 0.\n/// @param: val(Input), the data to be checked.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsPowerOfTwo(T val) {\n  return (val & (val - 1)) == 0;\n}\n\n/// @brief: Calculates the floor value aligned based on parameter of alignment.\n/// If value is at the boundary of alignment, it is unchanged.\n/// @param: value(Input), value to be calculated.\n/// @param: alignment(Input), alignment value.\n/// @return: T.\ntemplate <typename T>\nstatic __forceinline T AlignDown(T value, size_t alignment) {\n  return (T)((value / alignment) * alignment);\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: T*, pointer to type T.\ntemplate <typename T>\nstatic __forceinline T* AlignDown(T* value, size_t alignment) {\n  return (T*)AlignDown((intptr_t)value, alignment);\n}\n\n/// @brief: Calculates the ceiling value aligned based on parameter of\n/// alignment.\n/// If value is at the boundary of alignment, it is unchanged.\n/// @param: value(Input), value to be calculated.\n/// @param: alignment(Input), alignment value.\n/// @param: T.\ntemplate <typename T>\nstatic __forceinline T AlignUp(T value, size_t alignment) {\n  return AlignDown((T)(value + alignment - 1), alignment);\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: T*, pointer to type T.\ntemplate <typename T>\nstatic __forceinline T* AlignUp(T* value, size_t alignment) {\n  return (T*)AlignDown((intptr_t)((uint8_t*)value + alignment - 1), alignment);\n}\n\n/// @brief: Checks if the input value is at the boundary of alignment, if it is,\n/// @return true.\n/// @param: value(Input), value to be checked.\n/// @param: alignment(Input), alignment value.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsMultipleOf(T value, size_t alignment) {\n  return (AlignUp(value, alignment) == value);\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsMultipleOf(T* value, size_t alignment) {\n  return (AlignUp(value, alignment) == value);\n}\n\nstatic __forceinline uint32_t NextPow2(uint32_t value) {\n  if (value == 0) return 1;\n  uint32_t v = value - 1;\n  v |= v >> 1;\n  v |= v >> 2;\n  v |= v >> 4;\n  v |= v >> 8;\n  v |= v >> 16;\n  return v + 1;\n}\n\nstatic __forceinline uint64_t NextPow2(uint64_t value) {\n  if (value == 0) return 1;\n  uint64_t v = value - 1;\n  v |= v >> 1;\n  v |= v >> 2;\n  v |= v >> 4;\n  v |= v >> 8;\n  v |= v >> 16;\n  v |= v >> 32;\n  return v + 1;\n}\n\nstatic __forceinline bool strIsEmpty(const char* str) noexcept { return str[0] == '\\0'; }\n\nstatic __forceinline std::string& ltrim(std::string& s) {\n  auto it = std::find_if(s.begin(), s.end(),\n                         [](char c) { return !std::isspace<char>(c, std::locale::classic()); });\n  s.erase(s.begin(), it);\n  return s;\n}\n\nstatic __forceinline std::string& rtrim(std::string& s) {\n  auto it = std::find_if(s.rbegin(), s.rend(),\n                         [](char c) { return !std::isspace<char>(c, std::locale::classic()); });\n  s.erase(it.base(), s.end());\n  return s;\n}\n\nstatic __forceinline std::string& trim(std::string& s) { return ltrim(rtrim(s)); }\n\n/// @brief: Flush the cachelines associated with the\n/// provided address, offset, and length\n/// @param: base(Input), base address to flush\n/// @param: offset(Input), offset of base address to flush\n/// @param: len(Input), length of buffer to flush\ninline void FlushCpuCache(const void* base, size_t offset, size_t len) {\n  static long cacheline_size = 0;\n\n  if (!cacheline_size) {\n#ifdef _SC_LEVEL1_DCACHE_LINESIZE\n\t\tlong sz = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);\n#else\n\t\tlong sz = 0;\n#endif\n    if (sz <= 0) return;\n    cacheline_size = sz;\n  }\n\n  const char* cur = (const char*)base;\n  cur += offset;\n  uintptr_t lastline = (uintptr_t)(cur + len - 1) | (cacheline_size - 1);\n  do {\n    _mm_clflush((const void*)cur);\n    cur += cacheline_size;\n  } while (cur <= (const char*)lastline);\n}\n\n}  // namespace rocr\n\ntemplate <uint32_t lowBit, uint32_t highBit, typename T>\nstatic __forceinline uint32_t BitSelect(T p) {\n  static_assert(sizeof(T) <= sizeof(uintptr_t), \"Type out of range.\");\n  static_assert(highBit < sizeof(uintptr_t) * 8, \"Bit index out of range.\");\n\n  uintptr_t ptr = p;\n  if (highBit != (sizeof(uintptr_t) * 8 - 1))\n    return (uint32_t)((ptr & ((1ull << (highBit + 1)) - 1)) >> lowBit);\n  else\n    return (uint32_t)(ptr >> lowBit);\n}\n\ninline uint32_t PtrLow16Shift8(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFULL) >> 8);\n}\n\ninline uint32_t PtrHigh64Shift16(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFFFFFFFF0000ULL) >> 16);\n}\n\ninline uint32_t PtrLow40Shift8(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFFFFFFULL) >> 8);\n}\n\ninline uint32_t PtrHigh64Shift40(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFF0000000000ULL) >> 40);\n}\n\ninline uint32_t PtrLow32(const void* p) {\n  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p));\n}\n\ninline uint32_t PtrHigh32(const void* p) {\n  uint32_t ptr = 0;\n#ifdef HSA_LARGE_MODEL\n  ptr = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p) >> 32);\n#endif\n  return ptr;\n}\n\n/// @brief: Concatenates two numbers of type InType to a number of type OutType\n/// @param: hi(Input), To be placed in the upper bits of the output\n/// @param: lo(Input), To be placed in the lower bits of the output\n/// @return: OutType, Concatenation of hi and lo\ntemplate <typename OutType, typename InType>\ntypename std::enable_if<std::is_integral<OutType>::value && std::is_integral<InType>::value &&\n                            sizeof(OutType) >= 2 * sizeof(InType),\n                        OutType>::type\nConcat(InType hi, InType lo) {\n  OutType res = ((static_cast<OutType>(hi) << sizeof(InType) * 8) | static_cast<OutType>(lo));\n  return res;\n}\n\n\n#include \"atomic_helpers.h\"\n\n#endif  // HSA_RUNTIME_CORE_UTIL_UTILS_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/core/util/win/os_win.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifdef _WIN32  // Are we compiling for windows?\n#define NOMINMAX\n\n#include \"core/util/os.h\"\n\n#include <algorithm>\n#include <process.h>\n#include <string>\n#include <windows.h>\n\n#include <emmintrin.h>\n#include <pmmintrin.h>\n#include <xmmintrin.h>\n\n#undef Yield\n#undef CreateMutex\n\nnamespace rocr {\nnamespace os {\n\nstatic_assert(sizeof(LibHandle) == sizeof(HMODULE),\n              \"OS abstraction size mismatch\");\nstatic_assert(sizeof(LibHandle) == sizeof(::HANDLE),\n              \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Semaphore) == sizeof(::HANDLE),\n              \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Mutex) == sizeof(::HANDLE),\n              \"OS abstraction size mismatch\");\nstatic_assert(sizeof(Thread) == sizeof(::HANDLE),\n              \"OS abstraction size mismatch\");\nstatic_assert(sizeof(EventHandle) == sizeof(::HANDLE),\n              \"OS abstraction size mismatch\");\n\nLibHandle LoadLib(std::string filename) {\n  HMODULE ret = LoadLibrary(filename.c_str());\n  return *(LibHandle*)&ret;\n}\n\nvoid* GetExportAddress(LibHandle lib, std::string export_name) {\n  return GetProcAddress(*(HMODULE*)&lib, export_name.c_str());\n}\n\nvoid CloseLib(LibHandle lib) { FreeLibrary(*(::HMODULE*)&lib); }\n\nstd::vector<LibHandle> GetLoadedLibs() {\n  // Use EnumProcessModulesEx\n  static_assert(false, \"Not implemented.\");\n}\n\nstd::string GetLibraryName(LibHandle lib) {\n  static_assert(false, \"Not implemented.\");\n}\n\nSemaphore CreateSemaphore() {\n  sem = static_cast<void*>(CreateSemaphore(NULL, 0, LONG_MAX, NULL));\n  assert(sem != NULL && \"CreateSemaphore failed\");\n\n  return *(Semaphore*)&sem;\n}\n\nbool WaitSemaphore(Semaphore sem) {\n  return WaitForSingleObject(*(::HANDLE*)&lock, INFINITE) == WAIT_OBJECT_0;\n}\n\nvoid PostSemaphore(Semaphore sem) {\n  ReleaseSemaphore(static_cast<HANDLE>(*sem), 1, NULL);\n}\n\nvoid DestroySemaphore(Semaphore sem) {\n  if (!CloseHandle(static_cast<HANDLE>(*sem))) {\n    assert(\"CloseHandle() failed\");\n  }\n  *sem = NULL;\n}\n\nMutex CreateMutex() { return CreateEvent(NULL, false, true, NULL); }\n\nbool TryAcquireMutex(Mutex lock) {\n  return WaitForSingleObject(*(::HANDLE*)&lock, 0) == WAIT_OBJECT_0;\n}\n\nbool AcquireMutex(Mutex lock) {\n  return WaitForSingleObject(*(::HANDLE*)&lock, INFINITE) == WAIT_OBJECT_0;\n}\n\nvoid ReleaseMutex(Mutex lock) { SetEvent(*(::HANDLE*)&lock); }\n\nvoid DestroyMutex(Mutex lock) { CloseHandle(*(::HANDLE*)&lock); }\n\nvoid Sleep(int delay_in_millisecond) { ::Sleep(delay_in_millisecond); }\n\nvoid uSleep(int delayInUs) { ::Sleep(delayInUs / 1000); }\n\nvoid YieldThread() { ::Sleep(0); }\n\nstruct ThreadArgs {\n  void* entry_args;\n  ThreadEntry entry_function;\n};\n\nunsigned __stdcall ThreadTrampoline(void* arg) {\n  ThreadArgs* thread_args = (ThreadArgs*)arg;\n  ThreadEntry entry = thread_args->entry_function;\n  void* data = thread_args->entry_args;\n  delete thread_args;\n  entry(data);\n  _endthreadex(0);\n  return 0;\n}\n\nThread CreateThread(ThreadEntry entry_function, void* entry_argument,\n                    uint stack_size, int priority_unused) {\n  ThreadArgs* thread_args = new ThreadArgs();\n  thread_args->entry_args = entry_argument;\n  thread_args->entry_function = entry_function;\n  uintptr_t ret =\n      _beginthreadex(NULL, stack_size, ThreadTrampoline, thread_args, 0, NULL);\n  return *(Thread*)&ret;\n}\n\nvoid CloseThread(Thread thread) { CloseHandle(*(::HANDLE*)&thread); }\n\nbool WaitForThread(Thread thread) {\n  return WaitForSingleObject(*(::HANDLE*)&thread, INFINITE) == WAIT_OBJECT_0;\n}\n\nbool WaitForAllThreads(Thread* threads, uint thread_count) {\n  return WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE) ==\n         WAIT_OBJECT_0;\n}\n\nvoid SetEnvVar(std::string env_var_name, std::string env_var_value) {\n  SetEnvironmentVariable(env_var_name.c_str(), env_var_value.c_str());\n}\n\nstd::string GetEnvVar(std::string env_var_name) {\n  char* buff;\n  DWORD char_count = GetEnvironmentVariable(env_var_name.c_str(), NULL, 0);\n  if (char_count == 0) return \"\";\n  buff = (char*)alloca(sizeof(char) * char_count);\n  GetEnvironmentVariable(env_var_name.c_str(), buff, char_count);\n  buff[char_count - 1] = '\\0';\n  std::string ret = buff;\n  return ret;\n}\n\nsize_t GetUserModeVirtualMemorySize() {\n  SYSTEM_INFO system_info = {0};\n  GetSystemInfo(&system_info);\n  return ((size_t)system_info.lpMaximumApplicationAddress + 1);\n}\n\nsize_t GetUsablePhysicalHostMemorySize() {\n  MEMORYSTATUSEX memory_status = {0};\n  memory_status.dwLength = sizeof(memory_status);\n  if (GlobalMemoryStatusEx(&memory_status) == 0) {\n    return 0;\n  }\n\n  const size_t physical_size = static_cast<size_t>(memory_status.ullTotalPhys);\n  return std::min(GetUserModeVirtualMemorySize(), physical_size);\n}\n\nuintptr_t GetUserModeVirtualMemoryBase() { return (uintptr_t)0; }\n\n// Os event wrappers\nEventHandle CreateOsEvent(bool auto_reset, bool init_state) {\n  EventHandle evt = reinterpret_cast<EventHandle>(\n      CreateEvent(NULL, (BOOL)(!auto_reset), (BOOL)init_state, NULL));\n  return evt;\n}\n\nint DestroyOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n  return CloseHandle(reinterpret_cast<::HANDLE>(event));\n}\n\nint WaitForOsEvent(EventHandle event, unsigned int milli_seconds) {\n  if (event == NULL) {\n    return -1;\n  }\n\n  int ret_code =\n      WaitForSingleObject(reinterpret_cast<::HANDLE>(event), milli_seconds);\n  if (ret_code == WAIT_TIMEOUT) {\n    ret_code = 0x14003;  // 0x14003 indicates timeout\n  }\n  return ret_code;\n}\n\nint SetOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n  return SetEvent(reinterpret_cast<::HANDLE>(event));\n}\n\nint ResetOsEvent(EventHandle event) {\n  if (event == NULL) {\n    return -1;\n  }\n  return ResetEvent(reinterpret_cast<::HANDLE>(event));\n}\n\nuint64_t ReadAccurateClock() {\n  uint64_t ret;\n  QueryPerformanceCounter((LARGE_INTEGER*)&ret);\n  return ret;\n}\n\nuint64_t AccurateClockFrequency() {\n  uint64_t ret;\n  QueryPerformanceFrequency((LARGE_INTEGER*)&ret);\n  return ret;\n}\n\nSharedMutex CreateSharedMutex() {\n  assert(false && \"Not implemented.\");\n  abort();\n  return nullptr;\n}\n\nbool TryAcquireSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n  return false;\n}\n\nbool AcquireSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n  return false;\n}\n\nvoid ReleaseSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n}\n\nbool TrySharedAcquireSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n  return false;\n}\n\nbool SharedAcquireSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n  return false;\n}\n\nvoid SharedReleaseSharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n}\n\nvoid DestroySharedMutex(SharedMutex lock) {\n  assert(false && \"Not implemented.\");\n  abort();\n}\n\nuint64_t ReadSystemClock() {\n  assert(false && \"Not implemented.\");\n  abort();\n  return 0;\n}\n\nuint64_t SystemClockFrequency() {\n  assert(false && \"Not implemented.\");\n  abort();\n  return 0;\n}\n\nbool ParseCpuID(cpuid_t* cpuinfo) {\n  assert(false && \"Not implemented.\");\n  abort();\n  return false;\n}\n\n}   //  namespace os\n}   //  namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/hsa-runtime64-config.cmake.in",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2020-2021, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\n@PACKAGE_INIT@\n\ninclude( CMakeFindDependencyMacro )\n\n# Client apps only need our private dependencies if rocr is a static lib.\nset( _is_hsa_runtime_dynamic @BUILD_SHARED_LIBS@ )\nif( NOT _is_hsa_runtime_dynamic )\n\n  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} \"${CMAKE_CURRENT_LIST_DIR}\")\n\n  find_dependency(hsakmt 1.0)\n  find_dependency(LibElf)\n\nendif()\n\ninclude( \"${CMAKE_CURRENT_LIST_DIR}/@CORE_RUNTIME_NAME@Targets.cmake\" )\n\ncheck_required_components(@CORE_RUNTIME_NAME@)\n"
  },
  {
    "path": "runtime/hsa-runtime/hsacore.so.def",
    "content": "ROCR_1\n{\nglobal:\n\thsa_init;\n\thsa_shut_down;\n\thsa_system_get_info;\n\thsa_extension_get_name;\n\thsa_system_extension_supported;\n\thsa_system_major_extension_supported;\n\thsa_system_get_extension_table;\n\thsa_system_get_major_extension_table;\n\thsa_iterate_agents;\n\thsa_agent_get_info;\n\thsa_agent_get_exception_policies;\n\thsa_cache_get_info;\n\thsa_agent_iterate_caches;\n\thsa_agent_extension_supported;\n\thsa_agent_major_extension_supported;\n\thsa_queue_create;\n\thsa_soft_queue_create;\n\thsa_queue_destroy;\n\thsa_queue_inactivate;\n\thsa_queue_load_read_index_scacquire;\n\thsa_queue_load_read_index_acquire;\n\thsa_queue_load_read_index_relaxed;\n\thsa_queue_load_write_index_scacquire;\n\thsa_queue_load_write_index_acquire;\n\thsa_queue_load_write_index_relaxed;\n\thsa_queue_store_write_index_relaxed;\n\thsa_queue_store_write_index_screlease;\n\thsa_queue_store_write_index_release;\n\thsa_queue_cas_write_index_scacq_screl;\n\thsa_queue_cas_write_index_acq_rel;\n\thsa_queue_cas_write_index_scacquire;\n\thsa_queue_cas_write_index_acquire;\n\thsa_queue_cas_write_index_relaxed;\n\thsa_queue_cas_write_index_screlease;\n\thsa_queue_cas_write_index_release;\n\thsa_queue_add_write_index_scacq_screl;\n\thsa_queue_add_write_index_acq_rel;\n\thsa_queue_add_write_index_scacquire;\n\thsa_queue_add_write_index_acquire;\n\thsa_queue_add_write_index_relaxed;\n\thsa_queue_add_write_index_screlease;\n\thsa_queue_add_write_index_release;\n\thsa_queue_store_read_index_relaxed;\n\thsa_queue_store_read_index_screlease;\n\thsa_queue_store_read_index_release;\n\thsa_agent_iterate_regions;\n\thsa_region_get_info;\n\thsa_memory_register;\n\thsa_memory_deregister;\n\thsa_memory_allocate;\n\thsa_memory_free;\n\thsa_memory_copy;\n\thsa_memory_assign_agent;\n\thsa_signal_create;\n\thsa_signal_destroy;\n\thsa_signal_load_relaxed;\n\thsa_signal_load_scacquire;\n\thsa_signal_load_acquire;\n\thsa_signal_store_relaxed;\n\thsa_signal_store_screlease;\n\thsa_signal_store_release;\n\thsa_signal_silent_store_relaxed;\n\thsa_signal_silent_store_screlease;\n\thsa_signal_wait_relaxed;\n\thsa_signal_wait_scacquire;\n\thsa_signal_wait_acquire;\n\thsa_signal_group_create;\n\thsa_signal_group_destroy;\n\thsa_signal_group_wait_any_scacquire;\n\thsa_signal_group_wait_any_relaxed;\n\thsa_signal_and_relaxed;\n\thsa_signal_and_scacquire;\n\thsa_signal_and_acquire;\n\thsa_signal_and_screlease;\n\thsa_signal_and_release;\n\thsa_signal_and_scacq_screl;\n\thsa_signal_and_acq_rel;\n\thsa_signal_or_relaxed;\n\thsa_signal_or_scacquire;\n\thsa_signal_or_acquire;\n\thsa_signal_or_screlease;\n\thsa_signal_or_release;\n\thsa_signal_or_scacq_screl;\n\thsa_signal_or_acq_rel;\n\thsa_signal_xor_relaxed;\n\thsa_signal_xor_scacquire;\n\thsa_signal_xor_acquire;\n\thsa_signal_xor_screlease;\n\thsa_signal_xor_release;\n\thsa_signal_xor_scacq_screl;\n\thsa_signal_xor_acq_rel;\n\thsa_signal_exchange_relaxed;\n\thsa_signal_exchange_scacquire;\n\thsa_signal_exchange_acquire;\n\thsa_signal_exchange_screlease;\n\thsa_signal_exchange_release;\n\thsa_signal_exchange_scacq_screl;\n\thsa_signal_exchange_acq_rel;\n\thsa_signal_add_relaxed;\n\thsa_signal_add_scacquire;\n\thsa_signal_add_acquire;\n\thsa_signal_add_screlease;\n\thsa_signal_add_release;\n\thsa_signal_add_scacq_screl;\n\thsa_signal_add_acq_rel;\n\thsa_signal_subtract_relaxed;\n\thsa_signal_subtract_scacquire;\n\thsa_signal_subtract_acquire;\n\thsa_signal_subtract_screlease;\n\thsa_signal_subtract_release;\n\thsa_signal_subtract_scacq_screl;\n\thsa_signal_subtract_acq_rel;\n\thsa_signal_cas_relaxed;\n\thsa_signal_cas_scacquire;\n\thsa_signal_cas_acquire;\n\thsa_signal_cas_screlease;\n\thsa_signal_cas_release;\n\thsa_signal_cas_scacq_screl;\n\thsa_signal_cas_acq_rel;\n\thsa_isa_from_name;\n\thsa_agent_iterate_isas;\n\thsa_isa_get_info;\n\thsa_isa_get_info_alt;\n\thsa_isa_get_exception_policies;\n\thsa_isa_get_round_method;\n\thsa_wavefront_get_info;\n\thsa_isa_iterate_wavefronts;\n\thsa_isa_compatible;\n\thsa_code_object_serialize;\n\thsa_code_object_deserialize;\n\thsa_code_object_destroy;\n\thsa_code_object_get_info;\n\thsa_code_object_get_symbol;\n\thsa_code_object_get_symbol_from_name;\n\thsa_code_symbol_get_info;\n\thsa_code_object_iterate_symbols;\n\thsa_code_object_reader_create_from_file;\n\thsa_code_object_reader_create_from_memory;\n\thsa_code_object_reader_destroy;\n\thsa_executable_create;\n\thsa_executable_create_alt;\n\thsa_executable_destroy;\n\thsa_executable_load_code_object;\n\thsa_executable_load_program_code_object;\n\thsa_executable_load_agent_code_object;\n\thsa_executable_freeze;\n\thsa_executable_get_info;\n\thsa_executable_global_variable_define;\n\thsa_executable_agent_global_variable_define;\n\thsa_executable_readonly_variable_define;\n\thsa_executable_validate;\n\thsa_executable_validate_alt;\n\thsa_executable_get_symbol;\n\thsa_executable_get_symbol_by_name;\n\thsa_executable_symbol_get_info;\n\thsa_executable_iterate_symbols;\n\thsa_executable_iterate_agent_symbols;\n\thsa_executable_iterate_program_symbols;\n\thsa_status_string;\n\thsa_ext_program_create;\n\thsa_ext_program_destroy;\n\thsa_ext_program_add_module;\n\thsa_ext_program_iterate_modules;\n\thsa_ext_program_get_info;\n\thsa_ext_program_finalize;\n\thsa_amd_coherency_get_type;\n\thsa_amd_coherency_set_type;\n\thsa_amd_profiling_set_profiler_enabled;\n\thsa_amd_profiling_get_dispatch_time;\n\thsa_amd_profiling_async_copy_enable;\n\thsa_amd_profiling_get_async_copy_time;\n\thsa_amd_profiling_convert_tick_to_system_domain;\n\thsa_amd_signal_create;\n\thsa_amd_signal_wait_any;\n\thsa_amd_signal_async_handler;\n\thsa_amd_async_function;\n\thsa_amd_image_get_info_max_dim;\n\thsa_amd_queue_cu_set_mask;\n\thsa_amd_queue_cu_get_mask;\n\thsa_amd_memory_fill;\n\thsa_amd_memory_async_copy;\n\thsa_amd_memory_async_copy_on_engine;\n\thsa_amd_memory_copy_engine_status;\n\thsa_amd_memory_get_preferred_copy_engine;\n\thsa_amd_memory_async_copy_rect;\n\thsa_amd_memory_lock;\n\thsa_amd_memory_lock_to_pool;\n\thsa_amd_memory_unlock;\n\thsa_amd_agent_iterate_memory_pools;\n\thsa_amd_agent_memory_pool_get_info;\n\thsa_amd_agents_allow_access;\n\thsa_amd_memory_pool_get_info;\n\thsa_amd_memory_pool_allocate;\n\thsa_amd_memory_pool_free;\n\thsa_amd_memory_pool_can_migrate;\n\thsa_amd_memory_migrate;\n\thsa_amd_interop_map_buffer;\n\thsa_amd_interop_unmap_buffer;\n\thsa_amd_image_create;\n\thsa_ext_image_get_capability;\n\thsa_ext_image_data_get_info;\n\thsa_ext_image_create;\n\thsa_ext_image_import;\n\thsa_ext_image_export;\n\thsa_ext_image_copy;\n\thsa_ext_image_clear;\n\thsa_ext_image_destroy;\n\thsa_ext_sampler_create;\n\thsa_ext_sampler_create_v2;\n\thsa_ext_sampler_destroy;\n\thsa_ext_image_get_capability_with_layout;\n\thsa_ext_image_data_get_info_with_layout;\n\thsa_ext_image_create_with_layout;\n\thsa_amd_pointer_info;\n\thsa_amd_pointer_info_set_userdata;\n\thsa_amd_ipc_memory_create;\n\thsa_amd_ipc_memory_attach;\n\thsa_amd_ipc_memory_detach;\n\thsa_amd_ipc_signal_create;\n\thsa_amd_ipc_signal_attach;\n\thsa_amd_register_system_event_handler;\n\thsa_amd_queue_set_priority;\n\thsa_amd_register_deallocation_callback;\n\thsa_amd_deregister_deallocation_callback;\n\thsa_amd_signal_value_pointer;\n\t_amdgpu_r_debug;\n\thsa_amd_svm_attributes_set;\n\thsa_amd_svm_attributes_get;\n\thsa_amd_svm_prefetch_async;\n\thsa_amd_spm_acquire;\n\thsa_amd_spm_release;\n\thsa_amd_spm_set_dest_buffer;\n\thsa_amd_portable_export_dmabuf;\n\thsa_amd_portable_close_dmabuf;\n\thsa_amd_vmem_address_reserve;\n\thsa_amd_vmem_address_reserve_align;\n\thsa_amd_vmem_address_free;\n\thsa_amd_vmem_handle_create;\n\thsa_amd_vmem_handle_release;\n\thsa_amd_vmem_map;\n\thsa_amd_vmem_unmap;\n\thsa_amd_vmem_set_access;\n\thsa_amd_vmem_get_access;\n\thsa_amd_vmem_export_shareable_handle;\n\thsa_amd_vmem_import_shareable_handle;\n\thsa_amd_vmem_retain_alloc_handle;\n\thsa_amd_vmem_get_alloc_properties_from_handle;\n\thsa_amd_agent_set_async_scratch_limit;\n\thsa_ven_amd_pcs_iterate_configuration;\n\thsa_ven_amd_pcs_create;\n\thsa_ven_amd_pcs_create_from_id;\n\thsa_ven_amd_pcs_destroy;\n\thsa_ven_amd_pcs_start;\n\thsa_ven_amd_pcs_stop;\n\thsa_ven_amd_pcs_flush;\n\thsa_amd_queue_get_info;\n\thsa_amd_enable_logging;\n\thsa_amd_signal_wait_all;\n\thsa_amd_portable_export_dmabuf_v2;\nlocal:\n    *;\n};\n"
  },
  {
    "path": "runtime/hsa-runtime/hsacore.so.link",
    "content": "hsa_queue_load_read_index_acquire = hsa_queue_load_read_index_scacquire;\nhsa_queue_load_write_index_acquire = hsa_queue_load_write_index_scacquire;\nhsa_queue_store_write_index_release = hsa_queue_store_write_index_screlease;\nhsa_queue_cas_write_index_acq_rel = hsa_queue_cas_write_index_scacq_screl;\nhsa_queue_cas_write_index_acquire = hsa_queue_cas_write_index_scacquire;\nhsa_queue_cas_write_index_release = hsa_queue_cas_write_index_screlease;\nhsa_queue_add_write_index_acq_rel = hsa_queue_add_write_index_scacq_screl;\nhsa_queue_add_write_index_acquire = hsa_queue_add_write_index_scacquire;\nhsa_queue_add_write_index_release = hsa_queue_add_write_index_screlease;\nhsa_queue_store_read_index_release = hsa_queue_store_read_index_screlease;\nhsa_signal_load_acquire = hsa_signal_load_scacquire;\nhsa_signal_store_release = hsa_signal_store_screlease;\nhsa_signal_wait_acquire = hsa_signal_wait_scacquire;\nhsa_signal_and_acquire = hsa_signal_and_scacquire;\nhsa_signal_and_release = hsa_signal_and_screlease;\nhsa_signal_and_acq_rel = hsa_signal_and_scacq_screl;\nhsa_signal_or_acquire = hsa_signal_or_scacquire;\nhsa_signal_or_release = hsa_signal_or_screlease;\nhsa_signal_or_acq_rel = hsa_signal_or_scacq_screl;\nhsa_signal_xor_acquire = hsa_signal_xor_scacquire;\nhsa_signal_xor_release = hsa_signal_xor_screlease;\nhsa_signal_xor_acq_rel = hsa_signal_xor_scacq_screl;\nhsa_signal_exchange_acquire = hsa_signal_exchange_scacquire;\nhsa_signal_exchange_release = hsa_signal_exchange_screlease;\nhsa_signal_exchange_acq_rel = hsa_signal_exchange_scacq_screl;\nhsa_signal_add_acquire = hsa_signal_add_scacquire;\nhsa_signal_add_release = hsa_signal_add_screlease;\nhsa_signal_add_acq_rel = hsa_signal_add_scacq_screl;\nhsa_signal_subtract_acquire = hsa_signal_subtract_scacquire;\nhsa_signal_subtract_release = hsa_signal_subtract_screlease;\nhsa_signal_subtract_acq_rel = hsa_signal_subtract_scacq_screl;\nhsa_signal_cas_acquire = hsa_signal_cas_scacquire;\nhsa_signal_cas_release = hsa_signal_cas_screlease;\nhsa_signal_cas_acq_rel = hsa_signal_cas_scacq_screl;\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/inc/addrinterface.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrinterface.h\n* @brief Contains the addrlib interfaces declaration and parameter defines\n****************************************************************************************************\n*/\n#ifndef __ADDR_INTERFACE_H__\n#define __ADDR_INTERFACE_H__\n\n// Includes should be before extern \"C\"\n#include \"addrtypes.h\"\n\nnamespace rocr {\n#define ADDRLIB_VERSION_MAJOR 8\n#define ADDRLIB_VERSION_MINOR 10\n#define ADDRLIB_VERSION ((ADDRLIB_VERSION_MAJOR << 16) | ADDRLIB_VERSION_MINOR)\n\n/// Virtually all interface functions need ADDR_HANDLE as first parameter\ntypedef VOID*   ADDR_HANDLE;\n\n/// Client handle used in callbacks\ntypedef VOID*   ADDR_CLIENT_HANDLE;\n\ntypedef struct _ADDR_EXTENT3D\n{\n    UINT_32  width;\n    UINT_32  height;\n    UINT_32  depth;  // also slices for 2D images\n} ADDR_EXTENT3D;\n\n/**\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                                  Callback functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*    typedef VOID* (ADDR_API* ADDR_ALLOCSYSMEM)(\n*         const ADDR_ALLOCSYSMEM_INPUT* pInput);\n*    typedef ADDR_E_RETURNCODE (ADDR_API* ADDR_FREESYSMEM)(\n*         VOID* pVirtAddr);\n*    typedef ADDR_E_RETURNCODE (ADDR_API* ADDR_DEBUGPRINT)(\n*         const ADDR_DEBUGPRINT_INPUT* pInput);\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                               Create/Destroy/Config functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     AddrCreate()\n*     AddrDestroy()\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                                  Surface functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     AddrComputeSurfaceInfo()\n*     AddrComputeSurfaceAddrFromCoord()\n*     AddrComputeSurfaceCoordFromAddr()\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                                   HTile functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     AddrComputeHtileInfo()\n*     AddrComputeHtileAddrFromCoord()\n*     AddrComputeHtileCoordFromAddr()\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                                   C-mask functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     AddrComputeCmaskInfo()\n*     AddrComputeCmaskAddrFromCoord()\n*     AddrComputeCmaskCoordFromAddr()\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                                   F-mask functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     AddrComputeFmaskInfo()\n*     AddrComputeFmaskAddrFromCoord()\n*     AddrComputeFmaskCoordFromAddr()\n*\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n* //                               Element/Utility functions\n* /////////////////////////////////////////////////////////////////////////////////////////////////\n*     ElemFlt32ToDepthPixel()\n*     ElemFlt32ToColorPixel()\n*     AddrExtractBankPipeSwizzle()\n*     AddrCombineBankPipeSwizzle()\n*     AddrComputeSliceSwizzle()\n*     AddrConvertTileInfoToHW()\n*     AddrConvertTileIndex()\n*     AddrConvertTileIndex1()\n*     AddrGetTileIndex()\n*     AddrComputeBaseSwizzle()\n*     AddrUseTileIndex()\n*     AddrUseCombinedSwizzle()\n*\n**/\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                      Callback functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n* @brief channel setting structure\n****************************************************************************************************\n*/\ntypedef union _ADDR_CHANNEL_SETTING\n{\n    struct\n    {\n        UINT_8 valid   : 1;    ///< Indicate whehter this channel setting is valid\n        UINT_8 channel : 2;    ///< 0 for x channel, 1 for y channel, 2 for z channel, 3 for MSAA sample index\n        UINT_8 index   : 5;    ///< Channel index\n    };\n    UINT_8 value;              ///< Value\n} ADDR_CHANNEL_SETTING;\n\n/**\n****************************************************************************************************\n* @brief address equation key structure\n****************************************************************************************************\n*/\ntypedef union _ADDR_EQUATION_KEY\n{\n    struct\n    {\n        UINT_32 log2ElementBytes : 3; ///< Log2 of Bytes per pixel\n        UINT_32 tileMode         : 5; ///< Tile mode\n        UINT_32 microTileType    : 3; ///< Micro tile type\n        UINT_32 pipeConfig       : 5; ///< pipe config\n        UINT_32 numBanksLog2     : 3; ///< Number of banks log2\n        UINT_32 bankWidth        : 4; ///< Bank width\n        UINT_32 bankHeight       : 4; ///< Bank height\n        UINT_32 macroAspectRatio : 3; ///< Macro tile aspect ratio\n        UINT_32 prt              : 1; ///< SI only, indicate whether this equation is for prt\n        UINT_32 reserved         : 1; ///< Reserved bit\n    } fields;\n    UINT_32 value;\n} ADDR_EQUATION_KEY;\n\n/**\n****************************************************************************************************\n* @brief address equation structure\n****************************************************************************************************\n*/\n#define ADDR_MAX_LEGACY_EQUATION_COMP 3u\n#define ADDR_MAX_EQUATION_COMP        5u\n#define ADDR_MAX_EQUATION_BIT         20u\n\n// Invalid equation index\n#define ADDR_INVALID_EQUATION_INDEX 0xFFFFFFFF\n\ntypedef struct _ADDR_EQUATION\n{\n    union\n    {\n        struct {\n            ADDR_CHANNEL_SETTING addr[ADDR_MAX_EQUATION_BIT];  ///< addr setting\n            ADDR_CHANNEL_SETTING xor1[ADDR_MAX_EQUATION_BIT];  ///< xor setting\n            ADDR_CHANNEL_SETTING xor2[ADDR_MAX_EQUATION_BIT];  ///< xor2 setting\n            ADDR_CHANNEL_SETTING xor3[ADDR_MAX_EQUATION_BIT];  ///< xor3 setting\n            ADDR_CHANNEL_SETTING xor4[ADDR_MAX_EQUATION_BIT];  ///< xor4 setting\n        };\n        ///< Components showing the sources of each bit; each bit is result of addr ^ xor ^ xor2...\n        ADDR_CHANNEL_SETTING comps[ADDR_MAX_EQUATION_COMP][ADDR_MAX_EQUATION_BIT];\n    };\n    UINT_32              numBits;                      ///< The number of bits in equation\n    UINT_32              numBitComponents;             ///< The max number of channels contributing to a bit\n    BOOL_32              stackedDepthSlices;           ///< TRUE if depth slices are treated as being\n                                                       ///< stacked vertically prior to swizzling\n} ADDR_EQUATION;\n\n\n/**\n****************************************************************************************************\n* @brief Alloc system memory flags.\n* @note These flags are reserved for future use and if flags are added will minimize the impact\n*       of the client.\n****************************************************************************************************\n*/\ntypedef union _ADDR_ALLOCSYSMEM_FLAGS\n{\n    struct\n    {\n        UINT_32 reserved    : 32;  ///< Reserved for future use.\n    } fields;\n    UINT_32 value;\n\n} ADDR_ALLOCSYSMEM_FLAGS;\n\n/**\n****************************************************************************************************\n* @brief Alloc system memory input structure\n****************************************************************************************************\n*/\ntypedef struct _ADDR_ALLOCSYSMEM_INPUT\n{\n    UINT_32                 size;           ///< Size of this structure in bytes\n\n    ADDR_ALLOCSYSMEM_FLAGS  flags;          ///< System memory flags.\n    UINT_32                 sizeInBytes;    ///< System memory allocation size in bytes.\n    ADDR_CLIENT_HANDLE      hClient;        ///< Client handle\n} ADDR_ALLOCSYSMEM_INPUT;\n\n/**\n****************************************************************************************************\n* ADDR_ALLOCSYSMEM\n*   @brief\n*       Allocate system memory callback function. Returns valid pointer on success.\n****************************************************************************************************\n*/\ntypedef VOID* (ADDR_API* ADDR_ALLOCSYSMEM)(\n    const ADDR_ALLOCSYSMEM_INPUT* pInput);\n\n/**\n****************************************************************************************************\n* @brief Free system memory input structure\n****************************************************************************************************\n*/\ntypedef struct _ADDR_FREESYSMEM_INPUT\n{\n    UINT_32                 size;           ///< Size of this structure in bytes\n\n    VOID*                   pVirtAddr;      ///< Virtual address\n    ADDR_CLIENT_HANDLE      hClient;        ///< Client handle\n} ADDR_FREESYSMEM_INPUT;\n\n/**\n****************************************************************************************************\n* ADDR_FREESYSMEM\n*   @brief\n*       Free system memory callback function.\n*       Returns ADDR_OK on success.\n****************************************************************************************************\n*/\ntypedef ADDR_E_RETURNCODE (ADDR_API* ADDR_FREESYSMEM)(\n    const ADDR_FREESYSMEM_INPUT* pInput);\n\n/**\n****************************************************************************************************\n* @brief Print debug message input structure\n****************************************************************************************************\n*/\ntypedef struct _ADDR_DEBUGPRINT_INPUT\n{\n    UINT_32             size;           ///< Size of this structure in bytes\n\n    CHAR*               pDebugString;   ///< Debug print string\n    va_list             ap;             ///< Variable argument list\n    ADDR_CLIENT_HANDLE  hClient;        ///< Client handle\n} ADDR_DEBUGPRINT_INPUT;\n\n/**\n****************************************************************************************************\n* ADDR_DEBUGPRINT\n*   @brief\n*       Print debug message callback function.\n*       Returns ADDR_OK on success.\n****************************************************************************************************\n*/\ntypedef ADDR_E_RETURNCODE (ADDR_API* ADDR_DEBUGPRINT)(\n    const ADDR_DEBUGPRINT_INPUT* pInput);\n\n/**\n****************************************************************************************************\n* ADDR_CALLBACKS\n*\n*   @brief\n*       Address Library needs client to provide system memory alloc/free routines.\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CALLBACKS\n{\n    ADDR_ALLOCSYSMEM allocSysMem;   ///< Routine to allocate system memory\n    ADDR_FREESYSMEM  freeSysMem;    ///< Routine to free system memory\n    ADDR_DEBUGPRINT  debugPrint;    ///< Routine to print debug message\n} ADDR_CALLBACKS;\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Create/Destroy functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n* ADDR_CREATE_FLAGS\n*\n*   @brief\n*       This structure is used to pass some setup in creation of AddrLib\n*   @note\n****************************************************************************************************\n*/\ntypedef union _ADDR_CREATE_FLAGS\n{\n    struct\n    {\n        UINT_32 noCubeMipSlicesPad     : 1;    ///< Turn cubemap faces padding off\n        UINT_32 fillSizeFields         : 1;    ///< If clients fill size fields in all input and\n                                               ///  output structure\n        UINT_32 useTileIndex           : 1;    ///< Make tileIndex field in input valid\n        UINT_32 useCombinedSwizzle     : 1;    ///< Use combined tile swizzle\n        UINT_32 checkLast2DLevel       : 1;    ///< Check the last 2D mip sub level\n        UINT_32 useHtileSliceAlign     : 1;    ///< Do htile single slice alignment\n        UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize\n        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility\n        UINT_32 nonPower2MemConfig     : 1;    ///< Video memory bit width is not power of 2\n        UINT_32 enableAltTiling        : 1;    ///< Enable alt tile mode\n        UINT_32 reserved               : 22;   ///< Reserved bits for future use\n    };\n\n    UINT_32 value;\n} ADDR_CREATE_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR_REGISTER_VALUE\n*\n*   @brief\n*       Data from registers to setup AddrLib global data, used in AddrCreate\n****************************************************************************************************\n*/\ntypedef struct _ADDR_REGISTER_VALUE\n{\n    UINT_32  gbAddrConfig;       ///< For R8xx, use GB_ADDR_CONFIG register value.\n                                 ///  For R6xx/R7xx, use GB_TILING_CONFIG.\n                                 ///  But they can be treated as the same.\n                                 ///  if this value is 0, use chip to set default value\n    UINT_32  backendDisables;    ///< 1 bit per backend, starting with LSB. 1=disabled,0=enabled.\n                                 ///  Register value of CC_RB_BACKEND_DISABLE.BACKEND_DISABLE\n\n                                 ///  R800 registers-----------------------------------------------\n    UINT_32  noOfBanks;          ///< Number of h/w ram banks - For r800: MC_ARB_RAMCFG.NOOFBANK\n                                 ///  No enums for this value in h/w header files\n                                 ///  0: 4\n                                 ///  1: 8\n                                 ///  2: 16\n    UINT_32  noOfRanks;          ///  MC_ARB_RAMCFG.NOOFRANK\n                                 ///  0: 1\n                                 ///  1: 2\n                                 ///  SI (R1000) registers-----------------------------------------\n    const UINT_32* pTileConfig;  ///< Global tile setting tables\n    UINT_32  noOfEntries;        ///< Number of entries in pTileConfig\n\n                                 ///< CI registers-------------------------------------------------\n    const UINT_32* pMacroTileConfig;    ///< Global macro tile mode table\n    UINT_32  noOfMacroEntries;   ///< Number of entries in pMacroTileConfig\n} ADDR_REGISTER_VALUE;\n\n/**\n****************************************************************************************************\n* ADDR_CREATE_INPUT\n*\n*   @brief\n*       Parameters use to create an AddrLib Object. Caller must provide all fields.\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CREATE_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_32             chipEngine;          ///< Chip Engine\n    UINT_32             chipFamily;          ///< Chip Family\n    UINT_32             chipRevision;        ///< Chip Revision\n    ADDR_CALLBACKS      callbacks;           ///< Callbacks for sysmem alloc/free/print\n    ADDR_CREATE_FLAGS   createFlags;         ///< Flags to setup AddrLib\n    ADDR_REGISTER_VALUE regValue;            ///< Data from registers to setup AddrLib global data\n    ADDR_CLIENT_HANDLE  hClient;             ///< Client handle\n    UINT_32             minPitchAlignPixels; ///< Minimum pitch alignment in pixels\n} ADDR_CREATE_INPUT;\n\n/**\n****************************************************************************************************\n* ADDR_CREATEINFO_OUTPUT\n*\n*   @brief\n*       Return AddrLib handle to client driver\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CREATE_OUTPUT\n{\n    UINT_32              size;            ///< Size of this structure in bytes\n\n    ADDR_HANDLE          hLib;            ///< Address lib handle\n\n    UINT_32              numEquations;    ///< Number of equations in the table\n    const ADDR_EQUATION* pEquationTable;  ///< Pointer to the equation table\n} ADDR_CREATE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrCreate\n*\n*   @brief\n*       Create AddrLib object, must be called before any interface calls\n*\n*   @return\n*       ADDR_OK if successful\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrCreate(\n    const ADDR_CREATE_INPUT*    pAddrCreateIn,\n    ADDR_CREATE_OUTPUT*         pAddrCreateOut);\n\n\n\n/**\n****************************************************************************************************\n*   AddrDestroy\n*\n*   @brief\n*       Destroy AddrLib object, must be called to free internally allocated resources.\n*\n*   @return\n*      ADDR_OK if successful\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrDestroy(\n    ADDR_HANDLE hLib);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                    Surface functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n* @brief\n*       Bank/tiling parameters. On function input, these can be set as desired or\n*       left 0 for AddrLib to calculate/default. On function output, these are the actual\n*       parameters used.\n* @note\n*       Valid bankWidth/bankHeight value:\n*       1,2,4,8. They are factors instead of pixels or bytes.\n*\n*       The bank number remains constant across each row of the\n*       macro tile as each pipe is selected, so the number of\n*       tiles in the x direction with the same bank number will\n*       be bank_width * num_pipes.\n****************************************************************************************************\n*/\ntypedef struct _ADDR_TILEINFO\n{\n    ///  Any of these parameters can be set to 0 to use the HW default.\n    UINT_32     banks;              ///< Number of banks, numerical value\n    UINT_32     bankWidth;          ///< Number of tiles in the X direction in the same bank\n    UINT_32     bankHeight;         ///< Number of tiles in the Y direction in the same bank\n    UINT_32     macroAspectRatio;   ///< Macro tile aspect ratio. 1-1:1, 2-4:1, 4-16:1, 8-64:1\n    UINT_32     tileSplitBytes;     ///< Tile split size, in bytes\n    AddrPipeCfg pipeConfig;         ///< Pipe Config = HW enum + 1\n} ADDR_TILEINFO;\n\n// Create a define to avoid client change. The removal of R800 is because we plan to implement SI\n// within 800 HWL - An AddrPipeCfg is added in above data structure\ntypedef ADDR_TILEINFO ADDR_R800_TILEINFO;\n\n/**\n****************************************************************************************************\n* @brief\n*       Information needed by quad buffer stereo support\n****************************************************************************************************\n*/\ntypedef struct _ADDR_QBSTEREOINFO\n{\n    UINT_32         eyeHeight;          ///< Height (in pixel rows) to right eye\n    UINT_32         rightOffset;        ///< Offset (in bytes) to right eye\n    UINT_32         rightSwizzle;       ///< TileSwizzle for right eyes\n} ADDR_QBSTEREOINFO;\n\n/**\n****************************************************************************************************\n*   ADDR_SURFACE_FLAGS\n*\n*   @brief\n*       Surface flags\n****************************************************************************************************\n*/\ntypedef union _ADDR_SURFACE_FLAGS\n{\n    struct\n    {\n        UINT_32 color                : 1; ///< Flag indicates this is a color buffer\n        UINT_32 depth                : 1; ///< Flag indicates this is a depth/stencil buffer\n        UINT_32 stencil              : 1; ///< Flag indicates this is a stencil buffer\n        UINT_32 texture              : 1; ///< Flag indicates this is a texture\n        UINT_32 cube                 : 1; ///< Flag indicates this is a cubemap\n        UINT_32 volume               : 1; ///< Flag indicates this is a volume texture\n        UINT_32 fmask                : 1; ///< Flag indicates this is an fmask\n        UINT_32 cubeAsArray          : 1; ///< Flag indicates if treat cubemap as arrays\n        UINT_32 compressZ            : 1; ///< Flag indicates z buffer is compressed\n        UINT_32 overlay              : 1; ///< Flag indicates this is an overlay surface\n        UINT_32 noStencil            : 1; ///< Flag indicates this depth has no separate stencil\n        UINT_32 display              : 1; ///< Flag indicates this should match display controller req.\n        UINT_32 opt4Space            : 1; ///< Flag indicates this surface should be optimized for space\n                                          ///  i.e. save some memory but may lose performance\n        UINT_32 prt                  : 1; ///< Flag for partially resident texture\n        UINT_32 qbStereo             : 1; ///< Quad buffer stereo surface\n        UINT_32 pow2Pad              : 1; ///< SI: Pad to pow2, must set for mipmap (include level0)\n        UINT_32 interleaved          : 1; ///< Special flag for interleaved YUV surface padding\n        UINT_32 tcCompatible         : 1; ///< Flag indicates surface needs to be shader readable\n        UINT_32 dispTileType         : 1; ///< NI: force display Tiling for 128 bit shared resoruce\n        UINT_32 dccCompatible        : 1; ///< VI: whether to make MSAA surface support dcc fast clear\n        UINT_32 dccPipeWorkaround    : 1; ///< VI: whether to workaround the HW limit that\n                                          ///  dcc can't be enabled if pipe config of tile mode\n                                          ///  is different from that of ASIC, this flag\n                                          ///  is address lib internal flag, client should ignore it\n        UINT_32 czDispCompatible     : 1; ///< SI+: CZ family has a HW bug needs special alignment.\n                                          ///  This flag indicates we need to follow the\n                                          ///  alignment with CZ families or other ASICs under\n                                          ///  PX configuration + CZ.\n        UINT_32 nonSplit             : 1; ///< CI: depth texture should not be split\n        UINT_32 disableLinearOpt     : 1; ///< Disable tile mode optimization to linear\n        UINT_32 needEquation         : 1; ///< Make the surface tile setting equation compatible.\n                                          ///  This flag indicates we need to override tile\n                                          ///  mode to PRT_* tile mode to disable slice rotation,\n                                          ///  which is needed by swizzle pattern equation.\n        UINT_32 skipIndicesOutput    : 1; ///< Skipping indices in output.\n        UINT_32 rotateDisplay        : 1; ///< Rotate micro tile type\n        UINT_32 minimizeAlignment    : 1; ///< Minimize alignment\n        UINT_32 preferEquation       : 1; ///< Return equation index without adjusting tile mode\n        UINT_32 matchStencilTileCfg  : 1; ///< Select tile index of stencil as well as depth surface\n                                          ///  to make sure they share same tile config parameters\n        UINT_32 disallowLargeThickDegrade   : 1;    ///< Disallow large thick tile degrade\n        UINT_32 reserved             : 1; ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR_SURFACE_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_INFO_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeSurfaceInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_INFO_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    AddrTileMode        tileMode;           ///< Tile mode\n    AddrFormat          format;             ///< If format is set to valid one, bpp/width/height\n                                            ///  might be overwritten\n    UINT_32             bpp;                ///< Bits per pixel\n    UINT_32             numSamples;         ///< Number of samples\n    UINT_32             width;              ///< Width, in pixels\n    UINT_32             height;             ///< Height, in pixels\n    UINT_32             numSlices;          ///< Number of surface slices or depth\n    UINT_32             slice;              ///< Slice index\n    UINT_32             mipLevel;           ///< Current mipmap level\n    UINT_32             numMipLevels;       ///< Number of mips in mip chain\n    ADDR_SURFACE_FLAGS  flags;              ///< Surface type flags\n    UINT_32             numFrags;           ///< Number of fragments, leave it zero or the same as\n                                            ///  number of samples for normal AA; Set it to the\n                                            ///  number of fragments for EQAA\n    /// r800 and later HWL parameters\n    // Needed by 2D tiling, for linear and 1D tiling, just keep them 0's\n    ADDR_TILEINFO*      pTileInfo;          ///< 2D tile parameters. Set to 0 to default/calculate\n    AddrTileType        tileType;           ///< Micro tiling type, not needed when tileIndex != -1\n    INT_32              tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                            ///  while the global useTileIndex is set to 1\n    UINT_32             basePitch;          ///< Base level pitch in pixels, 0 means ignored, is a\n                                            ///  must for mip levels from SI+.\n                                            ///  Don't use pitch in blocks for compressed formats!\n    UINT_32             maxBaseAlign;       ///< Max base alignment request from client\n    UINT_32             pitchAlign;         ///< Pitch alignment request from client\n    UINT_32             heightAlign;        ///< Height alignment request from client\n} ADDR_COMPUTE_SURFACE_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_INFO_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeSurfInfo\n*   @note\n        Element: AddrLib unit for computing. e.g. BCn: 4x4 blocks; R32B32B32: 32bit with 3x pitch\n        Pixel: Original pixel\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_INFO_OUTPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    UINT_32         pitch;          ///< Pitch in elements (in blocks for compressed formats)\n    UINT_32         height;         ///< Height in elements (in blocks for compressed formats)\n    UINT_32         depth;          ///< Number of slice/depth\n    UINT_64         surfSize;       ///< Surface size in bytes\n    AddrTileMode    tileMode;       ///< Actual tile mode. May differ from that in input\n    UINT_32         baseAlign;      ///< Base address alignment\n    UINT_32         pitchAlign;     ///< Pitch alignment, in elements\n    UINT_32         heightAlign;    ///< Height alignment, in elements\n    UINT_32         depthAlign;     ///< Depth alignment, aligned to thickness, for 3d texture\n    UINT_32         bpp;            ///< Bits per elements (e.g. blocks for BCn, 1/3 for 96bit)\n    UINT_32         pixelPitch;     ///< Pitch in original pixels\n    UINT_32         pixelHeight;    ///< Height in original pixels\n    UINT_32         pixelBits;      ///< Original bits per pixel, passed from input\n    UINT_64         sliceSize;      ///< Size of slice specified by input's slice\n                                    ///  The result is controlled by surface flags & createFlags\n                                    ///  By default this value equals to surfSize for volume\n    UINT_32         pitchTileMax;   ///< PITCH_TILE_MAX value for h/w register\n    UINT_32         heightTileMax;  ///< HEIGHT_TILE_MAX value for h/w register\n    UINT_32         sliceTileMax;   ///< SLICE_TILE_MAX value for h/w register\n\n    UINT_32         numSamples;     ///< Pass the effective numSamples processed in this call\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;      ///< Tile parameters used. Filled in if 0 on input\n    AddrTileType    tileType;       ///< Micro tiling type, only valid when tileIndex != -1\n    INT_32          tileIndex;      ///< Tile index, MAY be \"downgraded\"\n\n    INT_32          macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n    /// Output flags\n    struct\n    {\n        /// Special information to work around SI mipmap swizzle bug UBTS #317508\n        UINT_32     last2DLevel  : 1;  ///< TRUE if this is the last 2D(3D) tiled\n                                       ///< Only meaningful when create flag checkLast2DLevel is set\n        UINT_32     tcCompatible : 1;  ///< If the surface can be shader compatible\n        UINT_32     dccUnsupport : 1;  ///< If the surface can support DCC compressed rendering\n        UINT_32     prtTileIndex : 1;  ///< SI only, indicate the returned tile index is for PRT\n                                       ///< If address lib return true for mip 0, client should set prt flag\n                                       ///< for child mips in subsequent compute surface info calls\n        UINT_32     reserved     :28;  ///< Reserved bits\n    };\n\n    UINT_32         equationIndex;     ///< Equation index in the equation table;\n\n    UINT_32         blockWidth;        ///< Width in element inside one block(1D->Micro, 2D->Macro)\n    UINT_32         blockHeight;       ///< Height in element inside one block(1D->Micro, 2D->Macro)\n    UINT_32         blockSlices;       ///< Slice number inside one block(1D->Micro, 2D->Macro)\n\n    /// Stereo info\n    ADDR_QBSTEREOINFO*  pStereoInfo;///< Stereo information, needed when .qbStereo flag is TRUE\n\n    INT_32          stencilTileIdx; ///< stencil tile index output when matchStencilTileCfg was set\n} ADDR_COMPUTE_SURFACE_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceInfo\n*\n*   @brief\n*       Compute surface width/height/depth/alignments and suitable tiling mode\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceInfo(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    UINT_32         x;                  ///< X coordinate\n    UINT_32         y;                  ///< Y coordinate\n    UINT_32         slice;              ///< Slice index\n    UINT_32         sample;             ///< Sample index, use fragment index for EQAA\n\n    UINT_32         bpp;                ///< Bits per pixel\n    UINT_32         pitch;              ///< Surface pitch, in pixels\n    UINT_32         height;             ///< Surface height, in pixels\n    UINT_32         numSlices;          ///< Surface depth\n    UINT_32         numSamples;         ///< Number of samples\n\n    AddrTileMode    tileMode;           ///< Tile mode\n    BOOL_32         isDepth;            ///< TRUE if the surface uses depth sample ordering within\n                                        ///  micro tile. Textures can also choose depth sample order\n    UINT_32         tileBase;           ///< Base offset (in bits) inside micro tile which handles\n                                        ///  the case that components are stored separately\n    UINT_32         compBits;           ///< The component bits actually needed(for planar surface)\n\n    UINT_32         numFrags;           ///< Number of fragments, leave it zero or the same as\n                                        ///  number of samples for normal AA; Set it to the\n                                        ///  number of fragments for EQAA\n    /// r800 and later HWL parameters\n    // Used for 1D tiling above\n    AddrTileType    tileType;           ///< See defintion of AddrTileType\n    struct\n    {\n        UINT_32     ignoreSE : 1;       ///< TRUE if shader engines are ignored. This is texture\n                                        ///  only flag. Only non-RT texture can set this to TRUE\n        UINT_32     reserved :31;       ///< Reserved for future use.\n    };\n    // 2D tiling needs following structure\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tile parameters. Client must provide all data\n    INT_32          tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    union\n    {\n        struct\n        {\n            UINT_32  bankSwizzle;       ///< Bank swizzle\n            UINT_32  pipeSwizzle;       ///< Pipe swizzle\n        };\n        UINT_32     tileSwizzle;        ///< Combined swizzle, if useCombinedSwizzle is TRUE\n    };\n} ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_64 addr;           ///< Byte address\n    UINT_32 bitPosition;    ///< Bit position within surfaceAddr, 0-7.\n                            ///  For surface bpp < 8, e.g. FMT_1.\n    UINT_32 prtBlockIndex;  ///< Index of a PRT tile (64K block)\n} ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address from a given coordinate.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n    ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeSurfaceCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    UINT_64         addr;               ///< Address in bytes\n    UINT_32         bitPosition;        ///< Bit position in addr. 0-7. for surface bpp < 8,\n                                        ///  e.g. FMT_1;\n    UINT_32         bpp;                ///< Bits per pixel\n    UINT_32         pitch;              ///< Pitch, in pixels\n    UINT_32         height;             ///< Height in pixels\n    UINT_32         numSlices;          ///< Surface depth\n    UINT_32         numSamples;         ///< Number of samples\n\n    AddrTileMode    tileMode;           ///< Tile mode\n    BOOL_32         isDepth;            ///< Surface uses depth sample ordering within micro tile.\n                                        ///  Note: Textures can choose depth sample order as well.\n    UINT_32         tileBase;           ///< Base offset (in bits) inside micro tile which handles\n                                        ///  the case that components are stored separately\n    UINT_32         compBits;           ///< The component bits actually needed(for planar surface)\n\n    UINT_32         numFrags;           ///< Number of fragments, leave it zero or the same as\n                                        ///  number of samples for normal AA; Set it to the\n                                        ///  number of fragments for EQAA\n    /// r800 and later HWL parameters\n    // Used for 1D tiling above\n    AddrTileType    tileType;           ///< See defintion of AddrTileType\n    struct\n    {\n        UINT_32     ignoreSE : 1;       ///< TRUE if shader engines are ignored. This is texture\n                                        ///  only flag. Only non-RT texture can set this to TRUE\n        UINT_32     reserved :31;       ///< Reserved for future use.\n    };\n    // 2D tiling needs following structure\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tile parameters. Client must provide all data\n    INT_32          tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    union\n    {\n        struct\n        {\n            UINT_32  bankSwizzle;       ///< Bank swizzle\n            UINT_32  pipeSwizzle;       ///< Pipe swizzle\n        };\n        UINT_32     tileSwizzle;        ///< Combined swizzle, if useCombinedSwizzle is TRUE\n    };\n} ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeSurfaceCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT\n{\n    UINT_32 size;   ///< Size of this structure in bytes\n\n    UINT_32 x;      ///< X coordinate\n    UINT_32 y;      ///< Y coordinate\n    UINT_32 slice;  ///< Index of slices\n    UINT_32 sample; ///< Index of samples, means fragment index for EQAA\n} ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Compute coordinate from a given surface address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceCoordFromAddr(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,\n    ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut);\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                   HTile functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR_HTILE_FLAGS\n*\n*   @brief\n*       HTILE flags\n****************************************************************************************************\n*/\ntypedef union _ADDR_HTILE_FLAGS\n{\n    struct\n    {\n        UINT_32 tcCompatible          : 1;  ///< Flag indicates surface needs to be shader readable\n        UINT_32 skipTcCompatSizeAlign : 1;  ///< Flag indicates that addrLib will not align htile\n                                            ///  size to 256xBankxPipe when computing tc-compatible\n                                            ///  htile info.\n        UINT_32 reserved              : 30; ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR_HTILE_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_INFO_INPUT\n*\n*   @brief\n*       Input structure of AddrComputeHtileInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_INFO_INPUT\n{\n    UINT_32            size;            ///< Size of this structure in bytes\n\n    ADDR_HTILE_FLAGS   flags;           ///< HTILE flags\n    UINT_32            pitch;           ///< Surface pitch, in pixels\n    UINT_32            height;          ///< Surface height, in pixels\n    UINT_32            numSlices;       ///< Number of slices\n    BOOL_32            isLinear;        ///< Linear or tiled HTILE layout\n    AddrHtileBlockSize blockWidth;      ///< 4 or 8. EG above only support 8\n    AddrHtileBlockSize blockHeight;     ///< 4 or 8. EG above only support 8\n    ADDR_TILEINFO*     pTileInfo;       ///< Tile info\n\n    INT_32             tileIndex;       ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32             macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_HTILE_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_INFO_OUTPUT\n*\n*   @brief\n*       Output structure of AddrComputeHtileInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_INFO_OUTPUT\n{\n    UINT_32 size;               ///< Size of this structure in bytes\n\n    UINT_32 pitch;              ///< Pitch in pixels of depth buffer represented in this\n                                ///  HTile buffer. This might be larger than original depth\n                                ///  buffer pitch when called with an unaligned pitch.\n    UINT_32 height;             ///< Height in pixels, as above\n    UINT_64 htileBytes;         ///< Size of HTILE buffer, in bytes\n    UINT_32 baseAlign;          ///< Base alignment\n    UINT_32 bpp;                ///< Bits per pixel for HTILE is how many bits for an 8x8 block!\n    UINT_32 macroWidth;         ///< Macro width in pixels, actually squared cache shape\n    UINT_32 macroHeight;        ///< Macro height in pixels\n    UINT_64 sliceSize;          ///< Slice size, in bytes.\n    BOOL_32 sliceInterleaved;   ///< Flag to indicate if different slice's htile is interleaved\n                                ///  Compute engine clear can't be used if htile is interleaved\n    BOOL_32 nextMipLevelCompressible;   ///< Flag to indicate whether HTILE can be enabled in\n                                        ///  next mip level, it also indicates if memory set based\n                                        ///  fast clear can be used for current mip level.\n} ADDR_COMPUTE_HTILE_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileInfo\n*\n*   @brief\n*       Compute Htile pitch, height, base alignment and size in bytes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileInfo(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,\n    ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeHtileAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT\n{\n    UINT_32            size;            ///< Size of this structure in bytes\n\n    UINT_32            pitch;           ///< Pitch, in pixels\n    UINT_32            height;          ///< Height in pixels\n    UINT_32            x;               ///< X coordinate\n    UINT_32            y;               ///< Y coordinate\n    UINT_32            slice;           ///< Index of slice\n    UINT_32            numSlices;       ///< Number of slices\n    BOOL_32            isLinear;        ///< Linear or tiled HTILE layout\n    ADDR_HTILE_FLAGS   flags;           ///< htile flags\n    AddrHtileBlockSize blockWidth;      ///< 4 or 8. 1 means 8, 0 means 4. EG above only support 8\n    AddrHtileBlockSize blockHeight;     ///< 4 or 8. 1 means 8, 0 means 4. EG above only support 8\n    ADDR_TILEINFO*     pTileInfo;       ///< Tile info\n\n    INT_32             tileIndex;       ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32             macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n    UINT_32            bpp;             ///< depth/stencil buffer bit per pixel size\n    UINT_32            zStencilAddr;    ///< tcCompatible Z/Stencil surface address\n} ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeHtileAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_64 addr;           ///< Address in bytes\n    UINT_32 bitPosition;    ///< Bit position, 0 or 4. CMASK and HTILE shares some lib method.\n                            ///  So we keep bitPosition for HTILE as well\n} ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileAddrFromCoord\n*\n*   @brief\n*       Compute Htile address according to coordinates (of depth buffer)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileAddrFromCoord(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,\n    ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeHtileCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT\n{\n    UINT_32            size;            ///< Size of this structure in bytes\n\n    UINT_64            addr;            ///< Address\n    UINT_32            bitPosition;     ///< Bit position 0 or 4. CMASK and HTILE share some methods\n                                        ///  so we keep bitPosition for HTILE as well\n    UINT_32            pitch;           ///< Pitch, in pixels\n    UINT_32            height;          ///< Height, in pixels\n    UINT_32            numSlices;       ///< Number of slices\n    BOOL_32            isLinear;        ///< Linear or tiled HTILE layout\n    AddrHtileBlockSize blockWidth;      ///< 4 or 8. 1 means 8, 0 means 4. R8xx/R9xx only support 8\n    AddrHtileBlockSize blockHeight;     ///< 4 or 8. 1 means 8, 0 means 4. R8xx/R9xx only support 8\n    ADDR_TILEINFO*     pTileInfo;       ///< Tile info\n\n    INT_32             tileIndex;       ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32             macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeHtileCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT\n{\n    UINT_32 size;   ///< Size of this structure in bytes\n\n    UINT_32 x;      ///< X coordinate\n    UINT_32 y;      ///< Y coordinate\n    UINT_32 slice;  ///< Slice index\n} ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within depth buffer (1st pixel of a micro tile) according to\n*       Htile address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileCoordFromAddr(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,\n    ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     C-mask functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR_CMASK_FLAGS\n*\n*   @brief\n*       CMASK flags\n****************************************************************************************************\n*/\ntypedef union _ADDR_CMASK_FLAGS\n{\n    struct\n    {\n        UINT_32 tcCompatible  : 1; ///< Flag indicates surface needs to be shader readable\n        UINT_32 reserved      :31; ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR_CMASK_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_INFO_INPUT\n*\n*   @brief\n*       Input structure of AddrComputeCmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASKINFO_INPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n\n    ADDR_CMASK_FLAGS    flags;           ///< CMASK flags\n    UINT_32             pitch;           ///< Pitch, in pixels, of color buffer\n    UINT_32             height;          ///< Height, in pixels, of color buffer\n    UINT_32             numSlices;       ///< Number of slices, of color buffer\n    BOOL_32             isLinear;        ///< Linear or tiled layout, Only SI can be linear\n    ADDR_TILEINFO*      pTileInfo;       ///< Tile info\n\n    INT_32              tileIndex;       ///< Tile index, MUST be -1 if you don't want to use it\n                                         ///  while the global useTileIndex is set to 1\n    INT_32              macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                         ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_CMASK_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_INFO_OUTPUT\n*\n*   @brief\n*       Output structure of AddrComputeCmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASK_INFO_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_32 pitch;          ///< Pitch in pixels of color buffer which\n                            ///  this Cmask matches. The size might be larger than\n                            ///  original color buffer pitch when called with\n                            ///  an unaligned pitch.\n    UINT_32 height;         ///< Height in pixels, as above\n    UINT_64 cmaskBytes;     ///< Size in bytes of CMask buffer\n    UINT_32 baseAlign;      ///< Base alignment\n    UINT_32 blockMax;       ///< Cmask block size. Need this to set CB_COLORn_MASK register\n    UINT_32 macroWidth;     ///< Macro width in pixels, actually squared cache shape\n    UINT_32 macroHeight;    ///< Macro height in pixels\n    UINT_64 sliceSize;      ///< Slice size, in bytes.\n} ADDR_COMPUTE_CMASK_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskInfo\n*\n*   @brief\n*       Compute Cmask pitch, height, base alignment and size in bytes from color buffer\n*       info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskInfo(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,\n    ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeCmaskAddrFromCoord\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT\n{\n    UINT_32          size;           ///< Size of this structure in bytes\n    UINT_32          x;              ///< X coordinate\n    UINT_32          y;              ///< Y coordinate\n    UINT_64          fmaskAddr;      ///< Fmask addr for tc compatible Cmask\n    UINT_32          slice;          ///< Slice index\n    UINT_32          pitch;          ///< Pitch in pixels, of color buffer\n    UINT_32          height;         ///< Height in pixels, of color buffer\n    UINT_32          numSlices;      ///< Number of slices\n    UINT_32          bpp;\n    BOOL_32          isLinear;       ///< Linear or tiled layout, Only SI can be linear\n    ADDR_CMASK_FLAGS flags;          ///< CMASK flags\n    ADDR_TILEINFO*   pTileInfo;      ///< Tile info\n\n    INT_32           tileIndex;      ///< Tile index, MUST be -1 if you don't want to use it\n                                     ///< while the global useTileIndex is set to 1\n    INT_32           macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n                                     ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeCmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_64 addr;           ///< CMASK address in bytes\n    UINT_32 bitPosition;    ///< Bit position within addr, 0-7. CMASK is 4 bpp,\n                            ///  so the address may be located in bit 0 (0) or 4 (4)\n} ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Compute Cmask address according to coordinates (of MSAA color buffer)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskAddrFromCoord(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,\n    ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeCmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT\n{\n    UINT_32        size;            ///< Size of this structure in bytes\n\n    UINT_64        addr;            ///< CMASK address in bytes\n    UINT_32        bitPosition;     ///< Bit position within addr, 0-7. CMASK is 4 bpp,\n                                    ///  so the address may be located in bit 0 (0) or 4 (4)\n    UINT_32        pitch;           ///< Pitch, in pixels\n    UINT_32        height;          ///< Height in pixels\n    UINT_32        numSlices;       ///< Number of slices\n    BOOL_32        isLinear;        ///< Linear or tiled layout, Only SI can be linear\n    ADDR_TILEINFO* pTileInfo;       ///< Tile info\n\n    INT_32         tileIndex;       ///< Tile index, MUST be -1 if you don't want to use it\n                                    ///  while the global useTileIndex is set to 1\n    INT_32         macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                    ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeCmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT\n{\n    UINT_32 size;   ///< Size of this structure in bytes\n\n    UINT_32 x;      ///< X coordinate\n    UINT_32 y;      ///< Y coordinate\n    UINT_32 slice;  ///< Slice index\n} ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within color buffer (1st pixel of a micro tile) according to\n*       Cmask address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskCoordFromAddr(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,\n    ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     F-mask functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_INFO_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeFmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_INFO_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    AddrTileMode    tileMode;           ///< Tile mode\n    UINT_32         pitch;              ///< Surface pitch, in pixels\n    UINT_32         height;             ///< Surface height, in pixels\n    UINT_32         numSlices;          ///< Number of slice/depth\n    UINT_32         numSamples;         ///< Number of samples\n    UINT_32         numFrags;           ///< Number of fragments, leave it zero or the same as\n                                        ///  number of samples for normal AA; Set it to the\n                                        ///  number of fragments for EQAA\n    /// r800 and later HWL parameters\n    struct\n    {\n        UINT_32 resolved:   1;          ///< TRUE if the surface is for resolved fmask, only used\n                                        ///  by H/W clients. S/W should always set it to FALSE.\n        UINT_32 reserved:  31;          ///< Reserved for future use.\n    };\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tiling parameters. Clients must give valid data\n    INT_32          tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n} ADDR_COMPUTE_FMASK_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_INFO_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeFmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_INFO_OUTPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    UINT_32         pitch;          ///< Pitch of fmask in pixels\n    UINT_32         height;         ///< Height of fmask in pixels\n    UINT_32         numSlices;      ///< Slices of fmask\n    UINT_64         fmaskBytes;     ///< Size of fmask in bytes\n    UINT_32         baseAlign;      ///< Base address alignment\n    UINT_32         pitchAlign;     ///< Pitch alignment\n    UINT_32         heightAlign;    ///< Height alignment\n    UINT_32         bpp;            ///< Bits per pixel of FMASK is: number of bit planes\n    UINT_32         numSamples;     ///< Number of samples, used for dump, export this since input\n                                    ///  may be changed in 9xx and above\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;      ///< Tile parameters used. Fmask can have different\n                                    ///  bank_height from color buffer\n    INT_32          tileIndex;      ///< Tile index, MUST be -1 if you don't want to use it\n                                    ///  while the global useTileIndex is set to 1\n    INT_32          macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n    UINT_64         sliceSize;      ///< Size of slice in bytes\n} ADDR_COMPUTE_FMASK_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskInfo\n*\n*   @brief\n*       Compute Fmask pitch/height/depth/alignments and size in bytes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskInfo(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,\n    ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeFmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    UINT_32         x;                  ///< X coordinate\n    UINT_32         y;                  ///< Y coordinate\n    UINT_32         slice;              ///< Slice index\n    UINT_32         plane;              ///< Plane number\n    UINT_32         sample;             ///< Sample index (fragment index for EQAA)\n\n    UINT_32         pitch;              ///< Surface pitch, in pixels\n    UINT_32         height;             ///< Surface height, in pixels\n    UINT_32         numSamples;         ///< Number of samples\n    UINT_32         numFrags;           ///< Number of fragments, leave it zero or the same as\n                                        ///  number of samples for normal AA; Set it to the\n                                        ///  number of fragments for EQAA\n\n    AddrTileMode    tileMode;           ///< Tile mode\n    union\n    {\n        struct\n        {\n            UINT_32  bankSwizzle;       ///< Bank swizzle\n            UINT_32  pipeSwizzle;       ///< Pipe swizzle\n        };\n        UINT_32     tileSwizzle;        ///< Combined swizzle, if useCombinedSwizzle is TRUE\n    };\n\n    /// r800 and later HWL parameters\n    struct\n    {\n        UINT_32 resolved:   1;          ///< TRUE if this is a resolved fmask, used by H/W clients\n        UINT_32 ignoreSE:   1;          ///< TRUE if shader engines are ignored.\n        UINT_32 reserved:  30;          ///< Reserved for future use.\n    };\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tiling parameters. Client must provide all data\n\n} ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeFmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_64 addr;           ///< Fmask address\n    UINT_32 bitPosition;    ///< Bit position within fmaskAddr, 0-7.\n} ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Compute Fmask address according to coordinates (x,y,slice,sample,plane)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskAddrFromCoord(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,\n    ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for AddrComputeFmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    UINT_64         addr;               ///< Address\n    UINT_32         bitPosition;        ///< Bit position within addr, 0-7.\n\n    UINT_32         pitch;              ///< Pitch, in pixels\n    UINT_32         height;             ///< Height in pixels\n    UINT_32         numSamples;         ///< Number of samples\n    UINT_32         numFrags;           ///< Number of fragments\n    AddrTileMode    tileMode;           ///< Tile mode\n    union\n    {\n        struct\n        {\n            UINT_32  bankSwizzle;       ///< Bank swizzle\n            UINT_32  pipeSwizzle;       ///< Pipe swizzle\n        };\n        UINT_32     tileSwizzle;        ///< Combined swizzle, if useCombinedSwizzle is TRUE\n    };\n\n    /// r800 and later HWL parameters\n    struct\n    {\n        UINT_32 resolved:   1;          ///< TRUE if this is a resolved fmask, used by HW components\n        UINT_32 ignoreSE:   1;          ///< TRUE if shader engines are ignored.\n        UINT_32 reserved:  30;          ///< Reserved for future use.\n    };\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tile parameters. Client must provide all data\n\n} ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for AddrComputeFmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT\n{\n    UINT_32 size;       ///< Size of this structure in bytes\n\n    UINT_32 x;          ///< X coordinate\n    UINT_32 y;          ///< Y coordinate\n    UINT_32 slice;      ///< Slice index\n    UINT_32 plane;      ///< Plane number\n    UINT_32 sample;     ///< Sample index (fragment index for EQAA)\n} ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Compute FMASK coordinate from an given address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskCoordFromAddr(\n    ADDR_HANDLE                                     hLib,\n    const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*   pIn,\n    ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*        pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                          Element/utility functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrGetVersion\n*\n*   @brief\n*       Get AddrLib version number\n****************************************************************************************************\n*/\nUINT_32 ADDR_API AddrGetVersion(ADDR_HANDLE hLib);\n\n/**\n****************************************************************************************************\n*   AddrUseTileIndex\n*\n*   @brief\n*       Return TRUE if tileIndex is enabled in this address library\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API AddrUseTileIndex(ADDR_HANDLE hLib);\n\n/**\n****************************************************************************************************\n*   AddrUseCombinedSwizzle\n*\n*   @brief\n*       Return TRUE if combined swizzle is enabled in this address library\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API AddrUseCombinedSwizzle(ADDR_HANDLE hLib);\n\n/**\n****************************************************************************************************\n*   ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT\n*\n*   @brief\n*       Input structure of AddrExtractBankPipeSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    UINT_32         base256b;       ///< Base256b value\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;      ///< 2D tile parameters. Client must provide all data\n\n    INT_32          tileIndex;      ///< Tile index, MUST be -1 if you don't want to use it\n                                    ///  while the global useTileIndex is set to 1\n    INT_32          macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n                                    ///< README: When tileIndex is not -1, this must be valid\n} ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT\n*\n*   @brief\n*       Output structure of AddrExtractBankPipeSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_32 bankSwizzle;    ///< Bank swizzle\n    UINT_32 pipeSwizzle;    ///< Pipe swizzle\n} ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrExtractBankPipeSwizzle\n*\n*   @brief\n*       Extract Bank and Pipe swizzle from base256b\n*   @return\n*       ADDR_OK if no error\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrExtractBankPipeSwizzle(\n    ADDR_HANDLE                                 hLib,\n    const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,\n    ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut);\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT\n*\n*   @brief\n*       Input structure of AddrCombineBankPipeSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    UINT_32         bankSwizzle;    ///< Bank swizzle\n    UINT_32         pipeSwizzle;    ///< Pipe swizzle\n    UINT_64         baseAddr;       ///< Base address (leave it zero for driver clients)\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;      ///< 2D tile parameters. Client must provide all data\n\n    INT_32          tileIndex;      ///< Tile index, MUST be -1 if you don't want to use it\n                                    ///  while the global useTileIndex is set to 1\n    INT_32          macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n                                    ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT\n*\n*   @brief\n*       Output structure of AddrCombineBankPipeSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_32 tileSwizzle;    ///< Combined swizzle\n} ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrCombineBankPipeSwizzle\n*\n*   @brief\n*       Combine Bank and Pipe swizzle\n*   @return\n*       ADDR_OK if no error\n*   @note\n*       baseAddr here is full MCAddress instead of base256b\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrCombineBankPipeSwizzle(\n    ADDR_HANDLE                                 hLib,\n    const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,\n    ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SLICESWIZZLE_INPUT\n*\n*   @brief\n*       Input structure of AddrComputeSliceSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SLICESWIZZLE_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    AddrTileMode    tileMode;           ///< Tile Mode\n    UINT_32         baseSwizzle;        ///< Base tile swizzle\n    UINT_32         slice;              ///< Slice index\n    UINT_64         baseAddr;           ///< Base address, driver should leave it 0 in most cases\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;          ///< 2D tile parameters. Actually banks needed here!\n\n    INT_32          tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32          macroModeIndex;     ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_SLICESWIZZLE_INPUT;\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_SLICESWIZZLE_OUTPUT\n*\n*   @brief\n*       Output structure of AddrComputeSliceSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_SLICESWIZZLE_OUTPUT\n{\n    UINT_32  size;           ///< Size of this structure in bytes\n\n    UINT_32  tileSwizzle;    ///< Recalculated tileSwizzle value\n} ADDR_COMPUTE_SLICESWIZZLE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeSliceSwizzle\n*\n*   @brief\n*       Extract Bank and Pipe swizzle from base256b\n*   @return\n*       ADDR_OK if no error\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSliceSwizzle(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,\n    ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut);\n\n\n/**\n****************************************************************************************************\n*   AddrSwizzleGenOption\n*\n*   @brief\n*       Which swizzle generating options: legacy or linear\n****************************************************************************************************\n*/\ntypedef enum _AddrSwizzleGenOption\n{\n    ADDR_SWIZZLE_GEN_DEFAULT    = 0,    ///< As is in client driver implemention for swizzle\n    ADDR_SWIZZLE_GEN_LINEAR     = 1,    ///< Using a linear increment of swizzle\n} AddrSwizzleGenOption;\n\n/**\n****************************************************************************************************\n*   AddrBlockType\n*\n*   @brief\n*       Macro define resource block type\n****************************************************************************************************\n*/\ntypedef enum\n{\n    AddrBlockLinear = 0, // Resource uses linear swizzle mode\n    AddrBlockMicro = 1, // Resource uses 256B block\n    AddrBlockThin4KB = 2, // Resource uses thin 4KB block\n    AddrBlockThick4KB = 3, // Resource uses thick 4KB block\n    AddrBlockThin64KB = 4, // Resource uses thin 64KB block\n    AddrBlockThick64KB = 5, // Resource uses thick 64KB block\n    AddrBlockThinVar = 6, // Resource uses thin var block\n    AddrBlockThickVar = 7, // Resource uses thick var block\n    AddrBlockMaxTiledType,\n\n    AddrBlockThin256KB = AddrBlockThinVar,\n    AddrBlockThick256KB = AddrBlockThickVar,\n} AddrBlockType;\n\n/**\n****************************************************************************************************\n*   AddrSwizzleOption\n*\n*   @brief\n*       Controls how swizzle is generated\n****************************************************************************************************\n*/\ntypedef union _ADDR_SWIZZLE_OPTION\n{\n    struct\n    {\n        UINT_32 genOption       : 1;    ///< The way swizzle is generated, see AddrSwizzleGenOption\n        UINT_32 reduceBankBit   : 1;    ///< TRUE if we need reduce swizzle bits\n        UINT_32 reserved        :30;    ///< Reserved bits\n    };\n\n    UINT_32 value;\n\n} ADDR_SWIZZLE_OPTION;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_BASE_SWIZZLE_INPUT\n*\n*   @brief\n*       Input structure of AddrComputeBaseSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_BASE_SWIZZLE_INPUT\n{\n    UINT_32             size;           ///< Size of this structure in bytes\n\n    ADDR_SWIZZLE_OPTION option;         ///< Swizzle option\n    UINT_32             surfIndex;      ///< Index of this surface type\n    AddrTileMode        tileMode;       ///< Tile Mode\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*      pTileInfo;      ///< 2D tile parameters. Actually banks needed here!\n\n    INT_32              tileIndex;      ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32              macroModeIndex; ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_BASE_SWIZZLE_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT\n*\n*   @brief\n*       Output structure of AddrComputeBaseSwizzle\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_32 tileSwizzle;    ///< Combined swizzle\n} ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeBaseSwizzle\n*\n*   @brief\n*       Return a Combined Bank and Pipe swizzle base on surface based on surface type/index\n*   @return\n*       ADDR_OK if no error\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeBaseSwizzle(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,\n    ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT*       pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ELEM_GETEXPORTNORM_INPUT\n*\n*   @brief\n*       Input structure for ElemGetExportNorm\n*\n****************************************************************************************************\n*/\ntypedef struct _ELEM_GETEXPORTNORM_INPUT\n{\n    UINT_32             size;       ///< Size of this structure in bytes\n\n    AddrColorFormat     format;     ///< Color buffer format; Client should use ColorFormat\n    AddrSurfaceNumber   num;        ///< Surface number type; Client should use NumberType\n    AddrSurfaceSwap     swap;       ///< Surface swap byte swap; Client should use SurfaceSwap\n    UINT_32             numSamples; ///< Number of samples\n} ELEM_GETEXPORTNORM_INPUT;\n\n/**\n****************************************************************************************************\n*  ElemGetExportNorm\n*\n*   @brief\n*       Helper function to check one format can be EXPORT_NUM, which is a register\n*       CB_COLOR_INFO.SURFACE_FORMAT. FP16 can be reported as EXPORT_NORM for rv770 in r600\n*       family\n*   @note\n*       The implementation is only for r600.\n*       00 - EXPORT_FULL: PS exports are 4 pixels with 4 components with 32-bits-per-component. (two\n*       clocks per export)\n*       01 - EXPORT_NORM: PS exports are 4 pixels with 4 components with 16-bits-per-component. (one\n*       clock per export)\n*\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API ElemGetExportNorm(\n    ADDR_HANDLE                     hLib,\n    const ELEM_GETEXPORTNORM_INPUT* pIn);\n\n\n\n/**\n****************************************************************************************************\n*   ELEM_FLT32TODEPTHPIXEL_INPUT\n*\n*   @brief\n*       Input structure for addrFlt32ToDepthPixel\n*\n****************************************************************************************************\n*/\ntypedef struct _ELEM_FLT32TODEPTHPIXEL_INPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    AddrDepthFormat format;         ///< Depth buffer format\n    ADDR_FLT_32     comps[2];       ///< Component values (Z/stencil)\n} ELEM_FLT32TODEPTHPIXEL_INPUT;\n\n/**\n****************************************************************************************************\n*   ELEM_FLT32TODEPTHPIXEL_INPUT\n*\n*   @brief\n*       Output structure for ElemFlt32ToDepthPixel\n*\n****************************************************************************************************\n*/\ntypedef struct _ELEM_FLT32TODEPTHPIXEL_OUTPUT\n{\n    UINT_32 size;           ///< Size of this structure in bytes\n\n    UINT_8* pPixel;         ///< Real depth value. Same data type as depth buffer.\n                            ///  Client must provide enough storage for this type.\n    UINT_32 depthBase;      ///< Tile base in bits for depth bits\n    UINT_32 stencilBase;    ///< Tile base in bits for stencil bits\n    UINT_32 depthBits;      ///< Bits for depth\n    UINT_32 stencilBits;    ///< Bits for stencil\n} ELEM_FLT32TODEPTHPIXEL_OUTPUT;\n\n/**\n****************************************************************************************************\n*   ElemFlt32ToDepthPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a depth/stencil pixel value\n*\n*   @return\n*       Return code\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API ElemFlt32ToDepthPixel(\n    ADDR_HANDLE                         hLib,\n    const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,\n    ELEM_FLT32TODEPTHPIXEL_OUTPUT*      pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ELEM_FLT32TOCOLORPIXEL_INPUT\n*\n*   @brief\n*       Input structure for addrFlt32ToColorPixel\n*\n****************************************************************************************************\n*/\ntypedef struct _ELEM_FLT32TOCOLORPIXEL_INPUT\n{\n    UINT_32            size;           ///< Size of this structure in bytes\n\n    AddrColorFormat    format;         ///< Color buffer format\n    AddrSurfaceNumber  surfNum;        ///< Surface number\n    AddrSurfaceSwap    surfSwap;       ///< Surface swap\n    ADDR_FLT_32        comps[4];       ///< Component values (r/g/b/a)\n} ELEM_FLT32TOCOLORPIXEL_INPUT;\n\n/**\n****************************************************************************************************\n*   ELEM_FLT32TOCOLORPIXEL_INPUT\n*\n*   @brief\n*       Output structure for ElemFlt32ToColorPixel\n*\n****************************************************************************************************\n*/\ntypedef struct _ELEM_FLT32TOCOLORPIXEL_OUTPUT\n{\n    UINT_32 size;       ///< Size of this structure in bytes\n\n    UINT_8* pPixel;     ///< Real color value. Same data type as color buffer.\n                        ///  Client must provide enough storage for this type.\n} ELEM_FLT32TOCOLORPIXEL_OUTPUT;\n\n/**\n****************************************************************************************************\n*   ElemFlt32ToColorPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a red/green/blue/alpha pixel value\n*\n*   @return\n*       Return code\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API ElemFlt32ToColorPixel(\n    ADDR_HANDLE                         hLib,\n    const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,\n    ELEM_FLT32TOCOLORPIXEL_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ElemSize\n*\n*   @brief\n*       Get bits-per-element for specified format\n*\n*   @return\n*       Bits-per-element of specified format\n*\n****************************************************************************************************\n*/\nUINT_32 ADDR_API ElemSize(\n    ADDR_HANDLE hLib,\n    AddrFormat  format);\n\n/**\n****************************************************************************************************\n*   ADDR_CONVERT_TILEINFOTOHW_INPUT\n*\n*   @brief\n*       Input structure for AddrConvertTileInfoToHW\n*   @note\n*       When reverse is TRUE, indices are igonred\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CONVERT_TILEINFOTOHW_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n    BOOL_32         reverse;            ///< Convert control flag.\n                                        ///  FALSE: convert from real value to HW value;\n                                        ///  TRUE: convert from HW value to real value.\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*  pTileInfo;          ///< Tile parameters with real value\n\n    INT_32          tileIndex;          ///< Tile index, MUST be -1 if you don't want to use it\n                                        ///  while the global useTileIndex is set to 1\n    INT_32          macroModeIndex;     ///< Index in macro tile mode table if there is one (CI)\n                                        ///< README: When tileIndex is not -1, this must be valid\n    UINT_32         bpp;                ///< Bits per pixel\n} ADDR_CONVERT_TILEINFOTOHW_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_CONVERT_TILEINFOTOHW_OUTPUT\n*\n*   @brief\n*       Output structure for AddrConvertTileInfoToHW\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CONVERT_TILEINFOTOHW_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    /// r800 and later HWL parameters\n    ADDR_TILEINFO*      pTileInfo;          ///< Tile parameters with hardware register value\n\n} ADDR_CONVERT_TILEINFOTOHW_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrConvertTileInfoToHW\n*\n*   @brief\n*       Convert tile info from real value to hardware register value\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileInfoToHW(\n    ADDR_HANDLE                             hLib,\n    const ADDR_CONVERT_TILEINFOTOHW_INPUT*  pIn,\n    ADDR_CONVERT_TILEINFOTOHW_OUTPUT*       pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_CONVERT_TILEINDEX_INPUT\n*\n*   @brief\n*       Input structure for AddrConvertTileIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CONVERT_TILEINDEX_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    INT_32          tileIndex;          ///< Tile index\n    INT_32          macroModeIndex;     ///< Index in macro tile mode table if there is one (CI)\n    UINT_32         bpp;                ///< Bits per pixel\n    BOOL_32         tileInfoHw;         ///< Set to TRUE if client wants HW enum, otherwise actual\n} ADDR_CONVERT_TILEINDEX_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_CONVERT_TILEINDEX_OUTPUT\n*\n*   @brief\n*       Output structure for AddrConvertTileIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CONVERT_TILEINDEX_OUTPUT\n{\n    UINT_32             size;           ///< Size of this structure in bytes\n\n    AddrTileMode        tileMode;       ///< Tile mode\n    AddrTileType        tileType;       ///< Tile type\n    ADDR_TILEINFO*      pTileInfo;      ///< Tile info\n\n} ADDR_CONVERT_TILEINDEX_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrConvertTileIndex\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileIndex(\n    ADDR_HANDLE                         hLib,\n    const ADDR_CONVERT_TILEINDEX_INPUT* pIn,\n    ADDR_CONVERT_TILEINDEX_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR_GET_MACROMODEINDEX_INPUT\n*\n*   @brief\n*       Input structure for AddrGetMacroModeIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_GET_MACROMODEINDEX_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    ADDR_SURFACE_FLAGS  flags;              ///< Surface flag\n    INT_32              tileIndex;          ///< Tile index\n    UINT_32             bpp;                ///< Bits per pixel\n    UINT_32             numFrags;           ///< Number of color fragments\n} ADDR_GET_MACROMODEINDEX_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_GET_MACROMODEINDEX_OUTPUT\n*\n*   @brief\n*       Output structure for AddrGetMacroModeIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_GET_MACROMODEINDEX_OUTPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n    INT_32              macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n} ADDR_GET_MACROMODEINDEX_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrGetMacroModeIndex\n*\n*   @brief\n*       Get macro mode index based on input parameters\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMacroModeIndex(\n    ADDR_HANDLE                          hLib,\n    const ADDR_GET_MACROMODEINDEX_INPUT* pIn,\n    ADDR_GET_MACROMODEINDEX_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR_CONVERT_TILEINDEX1_INPUT\n*\n*   @brief\n*       Input structure for AddrConvertTileIndex1 (without macro mode index)\n****************************************************************************************************\n*/\ntypedef struct _ADDR_CONVERT_TILEINDEX1_INPUT\n{\n    UINT_32         size;               ///< Size of this structure in bytes\n\n    INT_32          tileIndex;          ///< Tile index\n    UINT_32         bpp;                ///< Bits per pixel\n    UINT_32         numSamples;         ///< Number of samples\n    BOOL_32         tileInfoHw;         ///< Set to TRUE if client wants HW enum, otherwise actual\n} ADDR_CONVERT_TILEINDEX1_INPUT;\n\n/**\n****************************************************************************************************\n*   AddrConvertTileIndex1\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileIndex1(\n    ADDR_HANDLE                             hLib,\n    const ADDR_CONVERT_TILEINDEX1_INPUT*    pIn,\n    ADDR_CONVERT_TILEINDEX_OUTPUT*          pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_GET_TILEINDEX_INPUT\n*\n*   @brief\n*       Input structure for AddrGetTileIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_GET_TILEINDEX_INPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    AddrTileMode    tileMode;       ///< Tile mode\n    AddrTileType    tileType;       ///< Tile-type: disp/non-disp/...\n    ADDR_TILEINFO*  pTileInfo;      ///< Pointer to tile-info structure, can be NULL for linear/1D\n} ADDR_GET_TILEINDEX_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_GET_TILEINDEX_OUTPUT\n*\n*   @brief\n*       Output structure for AddrGetTileIndex\n****************************************************************************************************\n*/\ntypedef struct _ADDR_GET_TILEINDEX_OUTPUT\n{\n    UINT_32         size;           ///< Size of this structure in bytes\n\n    INT_32          index;          ///< index in table\n} ADDR_GET_TILEINDEX_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrGetTileIndex\n*\n*   @brief\n*       Get the tiling mode index in table\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetTileIndex(\n    ADDR_HANDLE                     hLib,\n    const ADDR_GET_TILEINDEX_INPUT* pIn,\n    ADDR_GET_TILEINDEX_OUTPUT*      pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_PRT_INFO_INPUT\n*\n*   @brief\n*       Input structure for AddrComputePrtInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_PRT_INFO_INPUT\n{\n    AddrFormat          format;        ///< Surface format\n    UINT_32             baseMipWidth;  ///< Base mipmap width\n    UINT_32             baseMipHeight; ///< Base mipmap height\n    UINT_32             baseMipDepth;  ///< Base mipmap depth\n    UINT_32             numFrags;      ///< Number of fragments,\n} ADDR_PRT_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_PRT_INFO_OUTPUT\n*\n*   @brief\n*       Input structure for AddrComputePrtInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_PRT_INFO_OUTPUT\n{\n    UINT_32             prtTileWidth;\n    UINT_32             prtTileHeight;\n} ADDR_PRT_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputePrtInfo\n*\n*   @brief\n*       Compute prt surface related information\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputePrtInfo(\n    ADDR_HANDLE                 hLib,\n    const ADDR_PRT_INFO_INPUT*  pIn,\n    ADDR_PRT_INFO_OUTPUT*       pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     DCC key functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   _ADDR_COMPUTE_DCCINFO_INPUT\n*\n*   @brief\n*       Input structure of AddrComputeDccInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_DCCINFO_INPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n    UINT_32             bpp;             ///< BitPP of color surface\n    UINT_32             numSamples;      ///< Sample number of color surface\n    UINT_64             colorSurfSize;   ///< Size of color surface to which dcc key is bound\n    AddrTileMode        tileMode;        ///< Tile mode of color surface\n    ADDR_TILEINFO       tileInfo;        ///< Tile info of color surface\n    UINT_32             tileSwizzle;     ///< Tile swizzle\n    INT_32              tileIndex;       ///< Tile index of color surface,\n                                         ///< MUST be -1 if you don't want to use it\n                                         ///< while the global useTileIndex is set to 1\n    INT_32              macroModeIndex;  ///< Index in macro tile mode table if there is one (CI)\n                                         ///< README: When tileIndex is not -1, this must be valid\n} ADDR_COMPUTE_DCCINFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR_COMPUTE_DCCINFO_OUTPUT\n*\n*   @brief\n*       Output structure of AddrComputeDccInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR_COMPUTE_DCCINFO_OUTPUT\n{\n    UINT_32 size;                 ///< Size of this structure in bytes\n    UINT_32 dccRamBaseAlign;      ///< Base alignment of dcc key\n    UINT_64 dccRamSize;           ///< Size of dcc key\n    UINT_64 dccFastClearSize;     ///< Size of dcc key portion that can be fast cleared\n    BOOL_32 subLvlCompressible;   ///< Whether sub resource is compressiable\n    BOOL_32 dccRamSizeAligned;    ///< Whether the dcc key size is aligned\n} ADDR_COMPUTE_DCCINFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrComputeDccInfo\n*\n*   @brief\n*       Compute DCC key size, base alignment\n*       info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeDccInfo(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_DCCINFO_INPUT*       pIn,\n    ADDR_COMPUTE_DCCINFO_OUTPUT*            pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR_GET_MAX_ALIGNMENTS_OUTPUT\n*\n*   @brief\n*       Output structure of AddrGetMaxAlignments\n****************************************************************************************************\n*/\ntypedef struct ADDR_GET_MAX_ALINGMENTS_OUTPUT\n{\n    UINT_32 size;                   ///< Size of this structure in bytes\n    UINT_32 baseAlign;              ///< Maximum base alignment in bytes\n} ADDR_GET_MAX_ALIGNMENTS_OUTPUT;\n\n/**\n****************************************************************************************************\n*   AddrGetMaxAlignments\n*\n*   @brief\n*       Gets maximnum alignments\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMaxAlignments(\n    ADDR_HANDLE                     hLib,\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut);\n\n/**\n****************************************************************************************************\n*   AddrGetMaxMetaAlignments\n*\n*   @brief\n*       Gets maximnum alignments for metadata\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMaxMetaAlignments(\n    ADDR_HANDLE                     hLib,\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut);\n\n/**\n****************************************************************************************************\n*                                Address library interface version 2\n*                                    available from Gfx9 hardware\n****************************************************************************************************\n*     Addr2ComputeSurfaceInfo()\n*     Addr2ComputeSurfaceAddrFromCoord()\n*     Addr2ComputeSurfaceCoordFromAddr()\n\n*     Addr2ComputeHtileInfo()\n*     Addr2ComputeHtileAddrFromCoord()\n*     Addr2ComputeHtileCoordFromAddr()\n*\n*     Addr2ComputeCmaskInfo()\n*     Addr2ComputeCmaskAddrFromCoord()\n*     Addr2ComputeCmaskCoordFromAddr()\n*\n*     Addr2ComputeFmaskInfo()\n*     Addr2ComputeFmaskAddrFromCoord()\n*     Addr2ComputeFmaskCoordFromAddr()\n*\n*     Addr2ComputeDccInfo()\n*\n**/\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                    Surface functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR2_SURFACE_FLAGS\n*\n*   @brief\n*       Surface flags\n****************************************************************************************************\n*/\ntypedef union _ADDR2_SURFACE_FLAGS\n{\n    struct\n    {\n        UINT_32 color             :  1; ///< This resource is a color buffer, can be used with RTV\n        UINT_32 depth             :  1; ///< Thie resource is a depth buffer, can be used with DSV\n        UINT_32 stencil           :  1; ///< Thie resource is a stencil buffer, can be used with DSV\n        UINT_32 fmask             :  1; ///< This is an fmask surface\n        UINT_32 overlay           :  1; ///< This is an overlay surface\n        UINT_32 display           :  1; ///< This resource is displable, can be used with DRV\n        UINT_32 prt               :  1; ///< This is a partially resident texture\n        UINT_32 qbStereo          :  1; ///< This is a quad buffer stereo surface\n        UINT_32 interleaved       :  1; ///< Special flag for interleaved YUV surface padding\n        UINT_32 texture           :  1; ///< This resource can be used with SRV\n        UINT_32 unordered         :  1; ///< This resource can be used with UAV\n        UINT_32 rotated           :  1; ///< This resource is rotated and displable\n        UINT_32 needEquation      :  1; ///< This resource needs equation to be generated if possible\n        UINT_32 opt4space         :  1; ///< This resource should be optimized for space\n        UINT_32 minimizeAlign     :  1; ///< This resource should use minimum alignment\n        UINT_32 noMetadata        :  1; ///< This resource has no metadata\n        UINT_32 metaRbUnaligned   :  1; ///< This resource has rb unaligned metadata\n        UINT_32 metaPipeUnaligned :  1; ///< This resource has pipe unaligned metadata\n        UINT_32 view3dAs2dArray   :  1; ///< This resource is a 3D resource viewed as 2D array\n        UINT_32 allowExtEquation  :  1; ///< If unset, only legacy DX eqs are allowed (2 XORs)\n        UINT_32 reserved          : 12; ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR2_SURFACE_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_INFO_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeSurfaceInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_INFO_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n\n    ADDR2_SURFACE_FLAGS   flags;             ///< Surface flags\n    AddrSwizzleMode       swizzleMode;       ///< Swizzle Mode for Gfx9\n    AddrResourceType      resourceType;      ///< Surface type\n    AddrFormat            format;            ///< Surface format\n    UINT_32               bpp;               ///< bits per pixel\n    UINT_32               width;             ///< Width (of mip0), in pixels\n    UINT_32               height;            ///< Height (of mip0), in pixels\n    UINT_32               numSlices;         ///< Number surface slice/depth (of mip0),\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               numSamples;        ///< Number of samples\n    UINT_32               numFrags;          ///< Number of fragments, leave it zero or the same as\n                                             ///  number of samples for normal AA; Set it to the\n                                             ///  number of fragments for EQAA\n    UINT_32               pitchInElement;    ///< Pitch in elements (blocks for compressed formats)\n    UINT_32               sliceAlign;        ///< Required slice size in bytes\n} ADDR2_COMPUTE_SURFACE_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_MIP_INFO\n*\n*   @brief\n*       Structure that contains information for mip level\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_MIP_INFO\n{\n    UINT_32             pitch;              ///< Pitch in elements\n    UINT_32             height;             ///< Padded height in elements\n    UINT_32             depth;              ///< Padded depth\n    UINT_32             pixelPitch;         ///< Pitch in pixels\n    UINT_32             pixelHeight;        ///< Padded height in pixels\n    UINT_32             equationIndex;      ///< Equation index in the equation table\n    UINT_64             offset;             ///< Offset in bytes from mip base, should only be used\n                                            ///< to setup vam surface descriptor, can't be used\n                                            ///< to setup swizzle pattern\n    UINT_64             macroBlockOffset;   ///< macro block offset in bytes from mip base\n    UINT_32             mipTailOffset;      ///< mip tail offset in bytes\n    UINT_32             mipTailCoordX;      ///< mip tail coord x\n    UINT_32             mipTailCoordY;      ///< mip tail coord y\n    UINT_32             mipTailCoordZ;      ///< mip tail coord z\n} ADDR2_MIP_INFO;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_INFO_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeSurfInfo\n*   @note\n        Element: AddrLib unit for computing. e.g. BCn: 4x4 blocks; R32B32B32: 32bit with 3x pitch\n        Pixel: Original pixel\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_INFO_OUTPUT\n{\n    UINT_32             size;                 ///< Size of this structure in bytes\n\n    UINT_32             pitch;                ///< Pitch in elements (blocks for compressed formats)\n    UINT_32             height;               ///< Padded height (of mip0) in elements\n    UINT_32             numSlices;            ///< Padded depth for 3d resource\n                                              ///< or padded number of slices for 2d array resource\n    UINT_32             mipChainPitch;        ///< Pitch (of total mip chain) in elements\n    UINT_32             mipChainHeight;       ///< Padded height (of total mip chain) in elements\n    UINT_32             mipChainSlice;        ///< Padded depth (of total mip chain)\n    UINT_64             sliceSize;            ///< Slice (total mip chain) size in bytes\n    UINT_64             surfSize;             ///< Surface (total mip chain) size in bytes\n    UINT_32             baseAlign;            ///< Base address alignment\n    UINT_32             bpp;                  ///< Bits per elements\n                                              ///  (e.g. blocks for BCn, 1/3 for 96bit)\n    UINT_32             pixelMipChainPitch;   ///< Mip chain pitch in original pixels\n    UINT_32             pixelMipChainHeight;  ///< Mip chain height in original pixels\n    UINT_32             pixelPitch;           ///< Pitch in original pixels\n    UINT_32             pixelHeight;          ///< Height in original pixels\n    UINT_32             pixelBits;            ///< Original bits per pixel, passed from input\n\n    UINT_32             blockWidth;           ///< Width in element inside one block\n    UINT_32             blockHeight;          ///< Height in element inside one block\n    UINT_32             blockSlices;          ///< Slice number inside one block\n                                              ///< Prt tile is one block, its width/height/slice\n                                              ///< equals to blcok width/height/slice\n\n    BOOL_32             epitchIsHeight;       ///< Whether to use height to program epitch register\n    /// Stereo info\n    ADDR_QBSTEREOINFO*  pStereoInfo;          ///< Stereo info, needed if qbStereo flag is TRUE\n    /// Mip info\n    ADDR2_MIP_INFO*     pMipInfo;             ///< Pointer to mip information array\n                                              ///  if it is not NULL, the array is assumed to\n                                              ///  contain numMipLevels entries\n\n    UINT_32             equationIndex;        ///< Equation index in the equation table of mip0\n    BOOL_32             mipChainInTail;       ///< If whole mipchain falls into mip tail block\n    UINT_32             firstMipIdInTail;     ///< The id of first mip in tail, if there is no mip\n                                              ///  in tail, it will be set to number of mip levels\n} ADDR2_COMPUTE_SURFACE_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceInfo\n*\n*   @brief\n*       Compute surface width/height/slices/alignments and suitable tiling mode\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceInfo(\n    ADDR_HANDLE                                hLib,\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT*    pIn,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n\n    UINT_32             x;               ///< X coordinate\n    UINT_32             y;               ///< Y coordinate\n    UINT_32             slice;           ///< Slice index\n    UINT_32             sample;          ///< Sample index, use fragment index for EQAA\n    UINT_32             mipId;           ///< the mip ID in mip chain\n\n    AddrSwizzleMode     swizzleMode;     ///< Swizzle mode for Gfx9\n    ADDR2_SURFACE_FLAGS flags;           ///< Surface flags\n    AddrResourceType    resourceType;    ///< Surface type\n    UINT_32             bpp;             ///< Bits per pixel\n    UINT_32             unalignedWidth;  ///< Surface original width (of mip0)\n    UINT_32             unalignedHeight; ///< Surface original height (of mip0)\n    UINT_32             numSlices;       ///< Surface original slices (of mip0)\n    UINT_32             numMipLevels;    ///< Total mipmap levels\n    UINT_32             numSamples;      ///< Number of samples\n    UINT_32             numFrags;        ///< Number of fragments, leave it zero or the same as\n                                         ///  number of samples for normal AA; Set it to the\n                                         ///  number of fragments for EQAA\n\n    UINT_32             pipeBankXor;     ///< Combined swizzle used to do bank/pipe rotation\n    UINT_32             pitchInElement;  ///< Pitch in elements (blocks for compressed formats)\n} ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;             ///< Size of this structure in bytes\n\n    UINT_64    addr;             ///< Byte offset from the image starting address\n    UINT_32    bitPosition;      ///< Bit position within surfaceAddr, 0-7.\n                                 ///  For surface bpp < 8, e.g. FMT_1.\n    UINT_32    prtBlockIndex;    ///< Index of a PRT tile (64K block)\n} ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address from a given coordinate.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                         hLib,\n    const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT*    pIn,\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeSurfaceCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n\n    UINT_64             addr;            ///< Address in bytes\n    UINT_32             bitPosition;     ///< Bit position in addr. 0-7. for surface bpp < 8,\n                                         ///  e.g. FMT_1;\n\n    AddrSwizzleMode     swizzleMode;     ///< Swizzle mode for Gfx9\n    ADDR2_SURFACE_FLAGS flags;           ///< Surface flags\n    AddrResourceType    resourceType;    ///< Surface type\n    UINT_32             bpp;             ///< Bits per pixel\n    UINT_32             unalignedWidth;  ///< Surface original width (of mip0)\n    UINT_32             unalignedHeight; ///< Surface original height (of mip0)\n    UINT_32             numSlices;       ///< Surface original slices (of mip0)\n    UINT_32             numMipLevels;    ///< Total mipmap levels.\n    UINT_32             numSamples;      ///< Number of samples\n    UINT_32             numFrags;        ///< Number of fragments, leave it zero or the same as\n                                         ///  number of samples for normal AA; Set it to the\n                                         ///  number of fragments for EQAA\n\n    UINT_32             pipeBankXor;     ///< Combined swizzle used to do bank/pipe rotation\n    UINT_32             pitchInElement;  ///< Pitch in elements (blocks for compressed formats)\n} ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeSurfaceCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT\n{\n    UINT_32    size;       ///< Size of this structure in bytes\n\n    UINT_32    x;          ///< X coordinate\n    UINT_32    y;          ///< Y coordinate\n    UINT_32    slice;      ///< Index of slices\n    UINT_32    sample;     ///< Index of samples, means fragment index for EQAA\n    UINT_32    mipId;      ///< mipmap level id\n} ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Compute coordinate from a given surface address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceCoordFromAddr(\n    ADDR_HANDLE                                         hLib,\n    const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT*    pIn,\n    ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*         pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                   HTile functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR2_META_FLAGS\n*\n*   @brief\n*       Metadata flags\n****************************************************************************************************\n*/\ntypedef union _ADDR2_META_FLAGS\n{\n    struct\n    {\n        UINT_32 pipeAligned :  1;    ///< if Metadata being pipe aligned\n        UINT_32 rbAligned   :  1;    ///< if Metadata being RB aligned\n        UINT_32 linear      :  1;    ///< if Metadata linear, GFX9 does not suppord this!\n        UINT_32 reserved    : 29;    ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR2_META_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR2_META_MIP_INFO\n*\n*   @brief\n*       Structure to store per mip metadata information\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_META_MIP_INFO\n{\n    BOOL_32    inMiptail;\n    union\n    {\n        struct\n        {\n            UINT_32    startX;\n            UINT_32    startY;\n            UINT_32    startZ;\n            UINT_32    width;\n            UINT_32    height;\n            UINT_32    depth;\n        };\n\n        // GFX10\n        struct\n        {\n            UINT_32    offset;      ///< Metadata offset within one slice,\n                                    ///  the thickness of a slice is meta block depth.\n            UINT_32    sliceSize;   ///< Metadata size within one slice,\n                                    ///  the thickness of a slice is meta block depth.\n        };\n    };\n} ADDR2_META_MIP_INFO;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_INFO_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeHtileInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_INFO_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    ADDR2_META_FLAGS    hTileFlags;         ///< HTILE flags\n    ADDR2_SURFACE_FLAGS depthFlags;         ///< Depth surface flags\n    AddrSwizzleMode     swizzleMode;        ///< Depth surface swizzle mode\n    UINT_32             unalignedWidth;     ///< Depth surface original width (of mip0)\n    UINT_32             unalignedHeight;    ///< Depth surface original height (of mip0)\n    UINT_32             numSlices;          ///< Number of slices of depth surface (of mip0)\n    UINT_32             numMipLevels;       ///< Total mipmap levels of color surface\n    UINT_32             firstMipIdInTail;   ///  Id of the first mip in tail,\n                                            ///  if no mip is in tail, it should be set to\n                                            ///  number of mip levels\n                                            ///  Only for GFX10\n} ADDR2_COMPUTE_HTILE_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_INFO_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeHtileInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_INFO_OUTPUT\n{\n    UINT_32    size;                ///< Size of this structure in bytes\n\n    UINT_32    pitch;               ///< Pitch in pixels of depth buffer represented in this\n                                    ///  HTile buffer. This might be larger than original depth\n                                    ///  buffer pitch when called with an unaligned pitch.\n    UINT_32    height;              ///< Height in pixels, as above\n    UINT_32    baseAlign;           ///< Base alignment\n    UINT_32    sliceSize;           ///< Slice size, in bytes.\n    UINT_32    htileBytes;          ///< Size of HTILE buffer, in bytes\n    UINT_32    metaBlkWidth;        ///< Meta block width\n    UINT_32    metaBlkHeight;       ///< Meta block height\n    UINT_32    metaBlkNumPerSlice;  ///< Number of metablock within one slice\n\n    ADDR2_META_MIP_INFO* pMipInfo;  ///< HTILE mip information\n\n    struct {\n      UINT_16* gfx10_bits; /* 72 2-byte elements */\n   } equation;\n} ADDR2_COMPUTE_HTILE_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileInfo\n*\n*   @brief\n*       Compute Htile pitch, height, base alignment and size in bytes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileInfo(\n    ADDR_HANDLE                              hLib,\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeHtileAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_32             x;                   ///< X coordinate\n    UINT_32             y;                   ///< Y coordinate\n    UINT_32             slice;               ///< Index of slices\n    UINT_32             mipId;               ///< mipmap level id\n\n    ADDR2_META_FLAGS    hTileFlags;          ///< HTILE flags\n    ADDR2_SURFACE_FLAGS depthflags;          ///< Depth surface flags\n    AddrSwizzleMode     swizzleMode;         ///< Depth surface swizzle mode\n    UINT_32             bpp;                 ///< Depth surface bits per pixel\n    UINT_32             unalignedWidth;      ///< Depth surface original width (of mip0)\n    UINT_32             unalignedHeight;     ///< Depth surface original height (of mip0)\n    UINT_32             numSlices;           ///< Depth surface original depth (of mip0)\n    UINT_32             numMipLevels;        ///< Depth surface total mipmap levels\n    UINT_32             numSamples;          ///< Depth surface number of samples\n    UINT_32             pipeXor;             ///< Pipe xor setting\n} ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeHtileAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;    ///< Size of this structure in bytes\n\n    UINT_64    addr;    ///< Address in bytes\n} ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileAddrFromCoord\n*\n*   @brief\n*       Compute Htile address according to coordinates (of depth buffer)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileAddrFromCoord(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*    pIn,\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeHtileCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_64             addr;                ///< Address\n\n    ADDR2_META_FLAGS    hTileFlags;          ///< HTILE flags\n    ADDR2_SURFACE_FLAGS depthFlags;          ///< Depth surface flags\n    AddrSwizzleMode     swizzleMode;         ///< Depth surface swizzle mode\n    UINT_32             bpp;                 ///< Depth surface bits per pixel\n    UINT_32             unalignedWidth;      ///< Depth surface original width (of mip0)\n    UINT_32             unalignedHeight;     ///< Depth surface original height (of mip0)\n    UINT_32             numSlices;           ///< Depth surface original depth (of mip0)\n    UINT_32             numMipLevels;        ///< Depth surface total mipmap levels\n    UINT_32             numSamples;          ///< Depth surface number of samples\n    UINT_32             pipeXor;             ///< Pipe xor setting\n} ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeHtileCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT\n{\n    UINT_32    size;        ///< Size of this structure in bytes\n\n    UINT_32    x;           ///< X coordinate\n    UINT_32    y;           ///< Y coordinate\n    UINT_32    slice;       ///< Index of slices\n    UINT_32    mipId;       ///< mipmap level id\n} ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within depth buffer (1st pixel of a micro tile) according to\n*       Htile address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileCoordFromAddr(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*    pIn,\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*         pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     C-mask functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_INFO_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeCmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASKINFO_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    ADDR2_META_FLAGS    cMaskFlags;         ///< CMASK flags\n    ADDR2_SURFACE_FLAGS colorFlags;         ///< Color surface flags\n    AddrResourceType    resourceType;       ///< Color surface type\n    AddrSwizzleMode     swizzleMode;        ///< FMask surface swizzle mode\n    UINT_32             unalignedWidth;     ///< Color surface original width\n    UINT_32             unalignedHeight;    ///< Color surface original height\n    UINT_32             numSlices;          ///< Number of slices of color buffer\n    UINT_32             numMipLevels;       ///< Number of mip levels\n    UINT_32             firstMipIdInTail;   ///< The id of first mip in tail, if no mip is in tail,\n                                            ///  it should be number of mip levels\n                                            ///  Only for GFX10\n} ADDR2_COMPUTE_CMASK_INFO_INPUT;\n\n/* DCC addr meta equation for GFX9. */\nstruct gfx9_addr_meta_equation {\n   UINT_8 num_bits;\n\n   struct {\n      struct {\n         UINT_8 dim; /* 0..4 as index, 5 means invalid */\n         UINT_8 ord; /* 0..31 */\n      } coord[8]; /* 0..num_coords */\n   } bit[32]; /* 0..num_bits */\n\n   UINT_8 numPipeBits;\n};\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_INFO_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeCmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASK_INFO_OUTPUT\n{\n    UINT_32    size;          ///< Size of this structure in bytes\n\n    UINT_32    pitch;         ///< Pitch in pixels of color buffer which\n                              ///  this Cmask matches. The size might be larger than\n                              ///  original color buffer pitch when called with\n                              ///  an unaligned pitch.\n    UINT_32    height;        ///< Height in pixels, as above\n    UINT_32    baseAlign;     ///< Base alignment\n    UINT_32    sliceSize;     ///< Slice size, in bytes.\n    UINT_32    cmaskBytes;    ///< Size in bytes of CMask buffer\n    UINT_32    metaBlkWidth;  ///< Meta block width\n    UINT_32    metaBlkHeight; ///< Meta block height\n\n    UINT_32    metaBlkNumPerSlice;  ///< Number of metablock within one slice\n\n    ADDR2_META_MIP_INFO* pMipInfo;  ///< CMASK mip information\n\n    /* The equation for doing CMASK address computations in shaders. */\n    union {\n       /* This is chip-specific, and it varies with:\n        * - resource type\n        * - swizzle_mode\n        * - bpp\n        * - pipe_aligned\n        * - rb_aligned\n        */\n       struct gfx9_addr_meta_equation gfx9;\n\n       /* This is chip-specific, it requires 64KB_Z_X. */\n       UINT_16 *gfx10_bits; /* 68 2-byte elements */\n    } equation;\n} ADDR2_COMPUTE_CMASK_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskInfo\n*\n*   @brief\n*       Compute Cmask pitch, height, base alignment and size in bytes from color buffer\n*       info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskInfo(\n    ADDR_HANDLE                              hLib,\n    const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeCmaskAddrFromCoord\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_32             x;                   ///< X coordinate\n    UINT_32             y;                   ///< Y coordinate\n    UINT_32             slice;               ///< Index of slices\n\n    ADDR2_META_FLAGS    cMaskFlags;          ///< CMASK flags\n    ADDR2_SURFACE_FLAGS colorFlags;          ///< Color surface flags\n    AddrResourceType    resourceType;        ///< Color surface type\n    AddrSwizzleMode     swizzleMode;         ///< FMask surface swizzle mode\n\n    UINT_32             unalignedWidth;      ///< Color surface original width (of mip0)\n    UINT_32             unalignedHeight;     ///< Color surface original height (of mip0)\n    UINT_32             numSlices;           ///< Color surface original slices (of mip0)\n\n    UINT_32             numSamples;          ///< Color surfae sample number\n    UINT_32             numFrags;            ///< Color surface fragment number\n\n    UINT_32             pipeXor;             ///< pipe Xor setting\n} ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeCmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;           ///< Size of this structure in bytes\n\n    UINT_64    addr;           ///< CMASK address in bytes\n    UINT_32    bitPosition;    ///< Bit position within addr, 0 or 4\n} ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Compute Cmask address according to coordinates (of MSAA color buffer)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskAddrFromCoord(\n    ADDR_HANDLE                                      hLib,\n    const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,\n    ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeCmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_64             addr;                ///< CMASK address in bytes\n    UINT_32             bitPosition;         ///< Bit position within addr, 0 or 4\n\n    ADDR2_META_FLAGS    cMaskFlags;          ///< CMASK flags\n    ADDR2_SURFACE_FLAGS colorFlags;          ///< Color surface flags\n    AddrResourceType    resourceType;        ///< Color surface type\n    AddrSwizzleMode     swizzleMode;         ///< FMask surface swizzle mode\n\n    UINT_32             unalignedWidth;      ///< Color surface original width (of mip0)\n    UINT_32             unalignedHeight;     ///< Color surface original height (of mip0)\n    UINT_32             numSlices;           ///< Color surface original slices (of mip0)\n    UINT_32             numMipLevels;        ///< Color surface total mipmap levels.\n} ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeCmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT\n{\n    UINT_32    size;        ///< Size of this structure in bytes\n\n    UINT_32    x;           ///< X coordinate\n    UINT_32    y;           ///< Y coordinate\n    UINT_32    slice;       ///< Index of slices\n    UINT_32    mipId;       ///< mipmap level id\n} ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within color buffer (1st pixel of a micro tile) according to\n*       Cmask address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskCoordFromAddr(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT*    pIn,\n    ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*         pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     F-mask functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR2_FMASK_FLAGS\n*\n*   @brief\n*       FMASK flags\n****************************************************************************************************\n*/\ntypedef union _ADDR2_FMASK_FLAGS\n{\n    struct\n    {\n        UINT_32 resolved :  1;    ///< TRUE if this is a resolved fmask, used by H/W clients\n                                  ///  by H/W clients. S/W should always set it to FALSE.\n        UINT_32 reserved : 31;    ///< Reserved for future use.\n    };\n\n    UINT_32 value;\n} ADDR2_FMASK_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_INFO_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeFmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_INFO_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    AddrSwizzleMode     swizzleMode;        ///< FMask surface swizzle mode\n    UINT_32             unalignedWidth;     ///< Color surface original width\n    UINT_32             unalignedHeight;    ///< Color surface original height\n    UINT_32             numSlices;          ///< Number of slices/depth\n    UINT_32             numSamples;         ///< Number of samples\n    UINT_32             numFrags;           ///< Number of fragments, leave it zero or the same as\n                                            ///  number of samples for normal AA; Set it to the\n                                            ///  number of fragments for EQAA\n    ADDR2_FMASK_FLAGS   fMaskFlags;         ///< FMASK flags\n} ADDR2_COMPUTE_FMASK_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_INFO_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeFmaskInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_INFO_OUTPUT\n{\n    UINT_32    size;           ///< Size of this structure in bytes\n\n    UINT_32    pitch;          ///< Pitch of fmask in pixels\n    UINT_32    height;         ///< Height of fmask in pixels\n    UINT_32    baseAlign;      ///< Base alignment\n    UINT_32    numSlices;      ///< Slices of fmask\n    UINT_32    fmaskBytes;     ///< Size of fmask in bytes\n    UINT_32    bpp;            ///< Bits per pixel of FMASK is: number of bit planes\n    UINT_32    numSamples;     ///< Number of samples\n    UINT_32    sliceSize;      ///< Size of slice in bytes\n} ADDR2_COMPUTE_FMASK_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskInfo\n*\n*   @brief\n*       Compute Fmask pitch/height/slices/alignments and size in bytes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskInfo(\n    ADDR_HANDLE                              hLib,\n    const ADDR2_COMPUTE_FMASK_INFO_INPUT*    pIn,\n    ADDR2_COMPUTE_FMASK_INFO_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeFmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT\n{\n    UINT_32            size;               ///< Size of this structure in bytes\n\n    AddrSwizzleMode    swizzleMode;        ///< FMask surface swizzle mode\n    UINT_32            x;                  ///< X coordinate\n    UINT_32            y;                  ///< Y coordinate\n    UINT_32            slice;              ///< Slice index\n    UINT_32            sample;             ///< Sample index (fragment index for EQAA)\n    UINT_32            plane;              ///< Plane number\n\n    UINT_32            unalignedWidth;     ///< Color surface original width\n    UINT_32            unalignedHeight;    ///< Color surface original height\n    UINT_32            numSamples;         ///< Number of samples\n    UINT_32            numFrags;           ///< Number of fragments, leave it zero or the same as\n                                           ///  number of samples for normal AA; Set it to the\n                                           ///  number of fragments for EQAA\n    UINT_32            tileSwizzle;        ///< Combined swizzle used to do bank/pipe rotation\n\n    ADDR2_FMASK_FLAGS  fMaskFlags; ///< FMASK flags\n} ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeFmaskAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;           ///< Size of this structure in bytes\n\n    UINT_64    addr;           ///< Fmask address\n    UINT_32    bitPosition;    ///< Bit position within fmaskAddr, 0-7.\n} ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Compute Fmask address according to coordinates (x,y,slice,sample,plane)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskAddrFromCoord(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*    pIn,\n    ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*         pOut);\n\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeFmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT\n{\n    UINT_32            size;               ///< Size of this structure in bytes\n\n    UINT_64            addr;               ///< Address\n    UINT_32            bitPosition;        ///< Bit position within addr, 0-7.\n    AddrSwizzleMode    swizzleMode;        ///< FMask surface swizzle mode\n\n    UINT_32            unalignedWidth;     ///< Color surface original width\n    UINT_32            unalignedHeight;    ///< Color surface original height\n    UINT_32            numSamples;         ///< Number of samples\n    UINT_32            numFrags;           ///< Number of fragments\n\n    UINT_32            tileSwizzle;        ///< Combined swizzle used to do bank/pipe rotation\n\n    ADDR2_FMASK_FLAGS  fMaskFlags; ///< FMASK flags\n} ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeFmaskCoordFromAddr\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT\n{\n    UINT_32    size;      ///< Size of this structure in bytes\n\n    UINT_32    x;         ///< X coordinate\n    UINT_32    y;         ///< Y coordinate\n    UINT_32    slice;     ///< Slice index\n    UINT_32    sample;    ///< Sample index (fragment index for EQAA)\n    UINT_32    plane;     ///< Plane number\n} ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Compute FMASK coordinate from an given address\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskCoordFromAddr(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT*    pIn,\n    ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*         pOut);\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     DCC key functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   _ADDR2_COMPUTE_DCCINFO_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeDccInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_DCCINFO_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n\n    ADDR2_META_FLAGS    dccKeyFlags;        ///< DCC key flags\n    ADDR2_SURFACE_FLAGS colorFlags;         ///< Color surface flags\n    AddrResourceType    resourceType;       ///< Color surface type\n    AddrSwizzleMode     swizzleMode;        ///< Color surface swizzle mode\n    UINT_32             bpp;                ///< bits per pixel\n    UINT_32             unalignedWidth;     ///< Color surface original width (of mip0)\n    UINT_32             unalignedHeight;    ///< Color surface original height (of mip0)\n    UINT_32             numSlices;          ///< Number of slices, of color surface (of mip0)\n    UINT_32             numFrags;           ///< Fragment number of color surface\n    UINT_32             numMipLevels;       ///< Total mipmap levels of color surface\n    UINT_32             dataSurfaceSize;    ///< The padded size of all slices and mip levels\n                                            ///< useful in meta linear case\n    UINT_32             firstMipIdInTail;   ///< The id of first mip in tail, if no mip is in tail,\n                                            ///  it should be number of mip levels\n                                            ///  Only for GFX10\n} ADDR2_COMPUTE_DCCINFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_DCCINFO_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeDccInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_DCCINFO_OUTPUT\n{\n    UINT_32    size;               ///< Size of this structure in bytes\n\n    UINT_32    dccRamBaseAlign;    ///< Base alignment of dcc key\n    UINT_32    dccRamSize;         ///< Size of dcc key\n\n    UINT_32    pitch;              ///< DCC surface mip chain pitch\n    UINT_32    height;             ///< DCC surface mip chain height\n    UINT_32    depth;              ///< DCC surface mip chain depth\n\n    UINT_32    compressBlkWidth;   ///< DCC compress block width\n    UINT_32    compressBlkHeight;  ///< DCC compress block height\n    UINT_32    compressBlkDepth;   ///< DCC compress block depth\n\n    UINT_32    metaBlkWidth;       ///< DCC meta block width\n    UINT_32    metaBlkHeight;      ///< DCC meta block height\n    UINT_32    metaBlkDepth;       ///< DCC meta block depth\n    UINT_32    metaBlkSize;        ///< DCC meta block size in bytes\n    UINT_32    metaBlkNumPerSlice; ///< Number of metablock within one slice\n\n    union\n    {\n        UINT_32 fastClearSizePerSlice;  ///< Size of DCC within a slice should be fast cleared\n        UINT_32 dccRamSliceSize;        ///< DCC ram size per slice. For mipmap, it's\n                                        ///  the slize size of a mip chain, the thickness of a\n                                        ///  a slice is meta block depth\n                                        ///  Only for GFX10\n    };\n\n    ADDR2_META_MIP_INFO* pMipInfo;      ///< DCC mip information\n\n    /* The equation for doing DCC address computations in shaders. */\n    union {\n       /* This is chip-specific, and it varies with:\n        * - resource type\n        * - swizzle_mode\n        * - bpp\n        * - number of fragments\n        * - pipe_aligned\n        * - rb_aligned\n        */\n       struct gfx9_addr_meta_equation gfx9;\n\n       /* This is chip-specific, it requires 64KB_R_X, and it varies with:\n        * - bpp\n        * - pipe_aligned\n        */\n       UINT_16 *gfx10_bits; /* 68 2-byte elements */\n    } equation;\n} ADDR2_COMPUTE_DCCINFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeDccInfo\n*\n*   @brief\n*       Compute DCC key size, base alignment\n*       info\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeDccInfo(\n    ADDR_HANDLE                           hLib,\n    const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut);\n\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr2ComputeDccAddrFromCoord\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT\n{\n    UINT_32             size;                ///< Size of this structure in bytes\n\n    UINT_32             x;                   ///< X coordinate\n    UINT_32             y;                   ///< Y coordinate\n    UINT_32             slice;               ///< Index of slices\n    UINT_32             sample;              ///< Index of samples, means fragment index for EQAA\n    UINT_32             mipId;               ///< mipmap level id\n\n    ADDR2_META_FLAGS    dccKeyFlags;         ///< DCC flags\n    ADDR2_SURFACE_FLAGS colorFlags;          ///< Color surface flags\n    AddrResourceType    resourceType;        ///< Color surface type\n    AddrSwizzleMode     swizzleMode;         ///< Color surface swizzle mode\n    UINT_32             bpp;                 ///< Color surface bits per pixel\n    UINT_32             unalignedWidth;      ///< Color surface original width (of mip0)\n    UINT_32             unalignedHeight;     ///< Color surface original height (of mip0)\n    UINT_32             numSlices;           ///< Color surface original slices (of mip0)\n    UINT_32             numMipLevels;        ///< Color surface mipmap levels\n    UINT_32             numFrags;            ///< Color surface fragment number\n\n    UINT_32             pipeXor;             ///< pipe Xor setting\n    UINT_32             pitch;               ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::pitch\n    UINT_32             height;              ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::height\n    UINT_32             compressBlkWidth;    ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::compressBlkWidth\n    UINT_32             compressBlkHeight;   ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::compressBlkHeight\n    UINT_32             compressBlkDepth;    ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::compressBlkDepth\n    UINT_32             metaBlkWidth;        ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::metaBlkWidth\n    UINT_32             metaBlkHeight;       ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::metaBlkHeight\n    UINT_32             metaBlkDepth;        ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::metaBlkDepth\n    UINT_32             dccRamSliceSize;     ///< ADDR2_COMPUTE_DCC_INFO_OUTPUT::dccRamSliceSize\n} ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr2ComputeDccAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;           ///< Size of this structure in bytes\n\n    UINT_64    addr;           ///< DCC address in bytes\n} ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeDccAddrFromCoord\n*\n*   @brief\n*       Compute DCC address according to coordinates (of MSAA color buffer)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeDccAddrFromCoord(\n    ADDR_HANDLE                                    hLib,\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT*   pIn,\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*        pOut);\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     Misc functions for Gfx9\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_PIPEBANKXOR_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputePipebankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_PIPEBANKXOR_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             surfIndex;          ///< Input surface index\n    ADDR2_SURFACE_FLAGS flags;              ///< Surface flag\n    AddrSwizzleMode     swizzleMode;        ///< Surface swizzle mode\n    AddrResourceType    resourceType;       ///< Surface resource type\n    AddrFormat          format;             ///< Surface format\n    UINT_32             numSamples;         ///< Number of samples\n    UINT_32             numFrags;           ///< Number of fragments, leave it zero or the same as\n                                            ///  number of samples for normal AA; Set it to the\n                                            ///  number of fragments for EQAA\n} ADDR2_COMPUTE_PIPEBANKXOR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputePipebankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             pipeBankXor;        ///< Pipe bank xor\n} ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputePipeBankXor\n*\n*   @brief\n*       Calculate a valid bank pipe xor value for client to use.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputePipeBankXor(\n    ADDR_HANDLE                            hLib,\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeSlicePipeBankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    AddrSwizzleMode     swizzleMode;        ///< Surface swizzle mode\n    AddrResourceType    resourceType;       ///< Surface resource type\n    UINT_32             bpe;                ///< bits per element (e.g. block size for BCn format)\n    UINT_32             basePipeBankXor;    ///< Base pipe bank xor\n    UINT_32             slice;              ///< Slice id\n    UINT_32             numSamples;         ///< Number of samples\n} ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeSlicePipeBankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             pipeBankXor;        ///< Pipe bank xor\n} ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSlicePipeBankXor\n*\n*   @brief\n*       Calculate slice pipe bank xor value based on base pipe bank xor and slice id.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSlicePipeBankXor(\n    ADDR_HANDLE                                  hLib,\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeSubResourceOffsetForSwizzlePattern\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    AddrSwizzleMode     swizzleMode;        ///< Surface swizzle mode\n    AddrResourceType    resourceType;       ///< Surface resource type\n    UINT_32             pipeBankXor;        ///< Per resource xor\n    UINT_32             slice;              ///< Slice id\n    UINT_64             sliceSize;          ///< Slice size of a mip chain\n    UINT_64             macroBlockOffset;   ///< Macro block offset, returned in ADDR2_MIP_INFO\n    UINT_32             mipTailOffset;      ///< Mip tail offset, returned in ADDR2_MIP_INFO\n} ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeSubResourceOffsetForSwizzlePattern\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_64             offset;             ///< offset\n} ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Calculate sub resource offset to support swizzle pattern.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSubResourceOffsetForSwizzlePattern(\n    ADDR_HANDLE                                                     hLib,\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeNonBlockCompressedView\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n    ADDR2_SURFACE_FLAGS   flags;             ///< Surface flags\n    AddrSwizzleMode       swizzleMode;       ///< Swizzle Mode for Gfx9\n    AddrResourceType      resourceType;      ///< Surface type\n    AddrFormat            format;            ///< Surface format\n    UINT_32               width;             ///< Width of mip0 in texels (not in compressed block)\n    UINT_32               height;            ///< Height of mip0 in texels (not in compressed block)\n    UINT_32               numSlices;         ///< Number surface slice/depth of mip0\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               pipeBankXor;       ///< Combined swizzle used to do bank/pipe rotation\n    UINT_32               slice;             ///< Index of slice to view\n    UINT_32               mipId;             ///< Id of mip to view\n} ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2ComputeNonBlockCompressedView\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_64             offset;             ///< Offset shifted from resource base for the view\n    UINT_32             pipeBankXor;        ///< Pipe bank xor for the view\n    UINT_32             unalignedWidth;     ///< Mip0 width (in element) for the view\n    UINT_32             unalignedHeight;    ///< Mip0 height (in element) for the view\n    UINT_32             numMipLevels;       ///< Total mipmap levels for the view\n    UINT_32             mipId;              ///< Mip ID for the view\n} ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2ComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeNonBlockCompressedView(\n    ADDR_HANDLE                                       hLib,\n    const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n    ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR2_BLOCK_SET\n*\n*   @brief\n*       Bit field that defines block type\n****************************************************************************************************\n*/\ntypedef union _ADDR2_BLOCK_SET\n{\n    struct\n    {\n        UINT_32 micro          : 1;   // 256B block for 2D resource\n        UINT_32 macroThin4KB   : 1;   // Thin 4KB for 2D/3D resource\n        UINT_32 macroThick4KB  : 1;   // Thick 4KB for 3D resource\n        UINT_32 macroThin64KB  : 1;   // Thin 64KB for 2D/3D resource\n        UINT_32 macroThick64KB : 1;   // Thick 64KB for 3D resource\n        UINT_32 var            : 1;   // VAR block\n        UINT_32                : 1;\n        UINT_32 linear         : 1;   // Linear block\n        UINT_32 reserved       : 24;\n    };\n\n    struct\n    {\n        UINT_32                : 5;\n        UINT_32 thin256KB      : 1;   // Thin 256KB block\n        UINT_32 thick256KB     : 1;   // Thick 256KB block\n        UINT_32                : 25;\n    } gfx11;\n\n    UINT_32 value;\n} ADDR2_BLOCK_SET;\n\n/**\n****************************************************************************************************\n*   ADDR2_SWTYPE_SET\n*\n*   @brief\n*       Bit field that defines swizzle type\n****************************************************************************************************\n*/\ntypedef union _ADDR2_SWTYPE_SET\n{\n    struct\n    {\n        UINT_32 sw_Z     : 1;   // SW_*_Z_*\n        UINT_32 sw_S     : 1;   // SW_*_S_*\n        UINT_32 sw_D     : 1;   // SW_*_D_*\n        UINT_32 sw_R     : 1;   // SW_*_R_*\n        UINT_32 reserved : 28;\n    };\n\n    UINT_32 value;\n} ADDR2_SWTYPE_SET;\n\n/**\n****************************************************************************************************\n*   ADDR2_SWMODE_SET\n*\n*   @brief\n*       Bit field that defines swizzle type\n****************************************************************************************************\n*/\ntypedef union _ADDR2_SWMODE_SET\n{\n    struct\n    {\n        UINT_32 swLinear    : 1;\n        UINT_32 sw256B_S    : 1;\n        UINT_32 sw256B_D    : 1;\n        UINT_32 sw256B_R    : 1;\n        UINT_32 sw4KB_Z     : 1;\n        UINT_32 sw4KB_S     : 1;\n        UINT_32 sw4KB_D     : 1;\n        UINT_32 sw4KB_R     : 1;\n        UINT_32 sw64KB_Z    : 1;\n        UINT_32 sw64KB_S    : 1;\n        UINT_32 sw64KB_D    : 1;\n        UINT_32 sw64KB_R    : 1;\n        UINT_32 swMiscDef12 : 1;\n        UINT_32 swMiscDef13 : 1;\n        UINT_32 swMiscDef14 : 1;\n        UINT_32 swMiscDef15 : 1;\n        UINT_32 sw64KB_Z_T  : 1;\n        UINT_32 sw64KB_S_T  : 1;\n        UINT_32 sw64KB_D_T  : 1;\n        UINT_32 sw64KB_R_T  : 1;\n        UINT_32 sw4KB_Z_X   : 1;\n        UINT_32 sw4KB_S_X   : 1;\n        UINT_32 sw4KB_D_X   : 1;\n        UINT_32 sw4KB_R_X   : 1;\n        UINT_32 sw64KB_Z_X  : 1;\n        UINT_32 sw64KB_S_X  : 1;\n        UINT_32 sw64KB_D_X  : 1;\n        UINT_32 sw64KB_R_X  : 1;\n        UINT_32 swMiscDef28 : 1;\n        UINT_32 swMiscDef29 : 1;\n        UINT_32 swMiscDef30 : 1;\n        UINT_32 swMiscDef31 : 1;\n    };\n\n    struct\n    {\n        UINT_32             : 28;\n        UINT_32 swVar_Z_X   : 1;\n        UINT_32             : 2;\n        UINT_32 swVar_R_X   : 1;\n    } gfx10;\n\n    struct\n    {\n        UINT_32             : 28;\n        UINT_32 sw256KB_Z_X : 1;\n        UINT_32 sw256KB_S_X : 1;\n        UINT_32 sw256KB_D_X : 1;\n        UINT_32 sw256KB_R_X : 1;\n    } gfx11;\n\n    UINT_32 value;\n} ADDR2_SWMODE_SET;\n\n/**\n****************************************************************************************************\n*   ADDR2_GET_PREFERRED_SURF_SETTING_INPUT\n*\n*   @brief\n*       Input structure of Addr2GetPreferredSurfaceSetting\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_GET_PREFERRED_SURF_SETTING_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n\n    ADDR2_SURFACE_FLAGS   flags;             ///< Surface flags\n    AddrResourceType      resourceType;      ///< Surface type\n    AddrFormat            format;            ///< Surface format\n    AddrResrouceLocation  resourceLoction;   ///< Surface heap choice\n    ADDR2_BLOCK_SET       forbiddenBlock;    ///< Client can use it to disable some block setting\n                                             ///< such as linear for DXTn, tiled for YUV\n    ADDR2_SWTYPE_SET      preferredSwSet;    ///< Client can use it to specify sw type(s) wanted\n    BOOL_32               noXor;             ///< Do not use xor mode for this resource\n    UINT_32               bpp;               ///< bits per pixel\n    UINT_32               width;             ///< Width (of mip0), in pixels\n    UINT_32               height;            ///< Height (of mip0), in pixels\n    UINT_32               numSlices;         ///< Number surface slice/depth (of mip0),\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               numSamples;        ///< Number of samples\n    UINT_32               numFrags;          ///< Number of fragments, leave it zero or the same as\n                                             ///  number of samples for normal AA; Set it to the\n                                             ///  number of fragments for EQAA\n    UINT_32               maxAlign;          ///< maximum base/size alignment requested by client\n    UINT_32               minSizeAlign;      ///< memory allocated for surface in client driver will\n                                             ///  be padded to multiple of this value (in bytes)\n    DOUBLE                memoryBudget;      ///< Memory consumption ratio based on minimum possible\n                                             ///  size.\n} ADDR2_GET_PREFERRED_SURF_SETTING_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT\n*\n*   @brief\n*       Output structure of Addr2GetPreferredSurfaceSetting\n****************************************************************************************************\n*/\ntypedef struct _ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT\n{\n    UINT_32               size;                 ///< Size of this structure in bytes\n\n    AddrSwizzleMode       swizzleMode;          ///< Suggested swizzle mode to be used\n    AddrResourceType      resourceType;         ///< Suggested resource type to program HW\n    ADDR2_BLOCK_SET       validBlockSet;        ///< Valid block type bit conbination\n    BOOL_32               canXor;               ///< If client can use xor on a valid macro block\n                                                ///  type\n    ADDR2_SWTYPE_SET      validSwTypeSet;       ///< Valid swizzle type bit combination\n    ADDR2_SWTYPE_SET      clientPreferredSwSet; ///< Client-preferred swizzle type bit combination\n    ADDR2_SWMODE_SET      validSwModeSet;       ///< Valid swizzle mode bit combination\n} ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr2GetPreferredSurfaceSetting\n*\n*   @brief\n*       Suggest a preferred setting for client driver to program HW register\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetPreferredSurfaceSetting(\n    ADDR_HANDLE                                   hLib,\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   Addr2GetPossibleSwizzleModes\n*\n*   @brief\n*       Returns a list of swizzle modes that are valid from the hardware's perspective for the\n*       client to choose from\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetPossibleSwizzleModes(\n    ADDR_HANDLE                                   hLib,\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   Addr2IsValidDisplaySwizzleMode\n*\n*   @brief\n*       Return whether the swizzle mode is supported by display engine\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2IsValidDisplaySwizzleMode(\n    ADDR_HANDLE     hLib,\n    AddrSwizzleMode swizzleMode,\n    UINT_32         bpp,\n    BOOL_32         *pResult);\n\n/**\n****************************************************************************************************\n*   Addr2GetAllowedBlockSet\n*\n*   @brief\n*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetAllowedBlockSet(\n    ADDR_HANDLE      hLib,\n    ADDR2_SWMODE_SET allowedSwModeSet,\n    AddrResourceType rsrcType,\n    ADDR2_BLOCK_SET* pAllowedBlockSet);\n\n/**\n****************************************************************************************************\n*   Addr2GetAllowedSwSet\n*\n*   @brief\n*       Returns the set of allowed swizzle types given the allowed swizzle modes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetAllowedSwSet(\n    ADDR_HANDLE       hLib,\n    ADDR2_SWMODE_SET  allowedSwModeSet,\n    ADDR2_SWTYPE_SET* pAllowedSwSet);\n\n/**\n****************************************************************************************************\n*   Addr2IsBlockTypeAvailable\n*\n*   @brief\n*       Determine whether a block type is allowed in a given blockSet\n****************************************************************************************************\n*/\nBOOL_32 Addr2IsBlockTypeAvailable(ADDR2_BLOCK_SET blockSet, AddrBlockType blockType);\n\n/**\n****************************************************************************************************\n*   Addr2BlockTypeWithinMemoryBudget\n*\n*   @brief\n*       Determine whether a new block type is acceptable based on memory waste ratio. Will favor\n*       larger block types.\n****************************************************************************************************\n*/\nBOOL_32 Addr2BlockTypeWithinMemoryBudget(\n    UINT_64 minSize,\n    UINT_64 newBlockTypeSize,\n    UINT_32 ratioLow,\n    UINT_32 ratioHi,\n#if defined(__cplusplus)\n    DOUBLE  memoryBudget = 0.0f,\n    BOOL_32 newBlockTypeBigger = TRUE);\n#else\n    DOUBLE  memoryBudget,\n    BOOL_32 newBlockTypeBigger);\n#endif\n\n/**\n****************************************************************************************************\n*   ADDR3_SURFACE_FLAGS\n*\n*   @brief\n*       Surface flags\n****************************************************************************************************\n*/\ntypedef union _ADDR3_SURFACE_FLAGS\n{\n    struct\n    {\n        UINT_32 color              : 1; ///< This resource is a color buffer, can be used with RTV\n        UINT_32 depth              : 1; ///< This resource is a depth buffer, can be used with DSV\n        UINT_32 stencil            : 1; ///< This resource is a stencil buffer, can be used with DSV\n        UINT_32 texture            : 1; ///< This resource can be used with SRV\n        UINT_32 unordered          : 1; ///< This resource can be used with UAV\n        UINT_32 hiZHiS             : 1;\n        UINT_32 blockCompressed    : 1;\n        UINT_32 nv12               : 1;\n        UINT_32 p010               : 1;\n        UINT_32 view3dAs2dArray    : 1;\n        UINT_32 isVrsImage         : 1; ///< This resource is a VRS source image\n        UINT_32 reserved           : 21; ///< Reserved bits\n    };\n\n    UINT_32 value;\n} ADDR3_SURFACE_FLAGS;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SURFACE_INFO_INPUT\n*\n*   @brief\n*       Input structure for Addr3ComputeSurfaceInfo\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SURFACE_INFO_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n\n    ADDR3_SURFACE_FLAGS   flags;             ///< Surface flags\n    Addr3SwizzleMode      swizzleMode;       ///< Swizzle Mode for Gfx12\n    AddrResourceType      resourceType;      ///< Surface type\n    AddrFormat            format;            ///< Surface format\n    UINT_32               bpp;               ///< bits per pixel\n    UINT_32               width;             ///< Width (of mip0), in pixels\n    UINT_32               height;            ///< Height (of mip0), in pixels\n    UINT_32               numSlices;         ///< Number surface slice/depth (of mip0),\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               numSamples;        ///< Number of samples\n    UINT_32               pitchInElement;    ///< Pitch in elements (blocks for compressed formats)\n    UINT_32               sliceAlign;        ///< Required slice size in bytes\n} ADDR3_COMPUTE_SURFACE_INFO_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_MIP_INFO\n*\n*   @brief\n*       Structure that contains information for mip level\n*\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_MIP_INFO\n{\n    UINT_32             pitch;              ///< Pitch in elements\n    UINT_32             height;             ///< Padded height in elements\n    UINT_32             depth;              ///< Padded depth\n    UINT_32             pixelPitch;         ///< Pitch in pixels\n    UINT_32             pixelHeight;        ///< Padded height in pixels\n    UINT_32             equationIndex;      ///< Equation index in the equation table\n    UINT_64             offset;             ///< Offset in bytes from mip base, should only be used\n                                            ///< to setup vam surface descriptor, can't be used\n                                            ///< to setup swizzle pattern\n    UINT_64             macroBlockOffset;   ///< macro block offset in bytes from mip base\n    UINT_32             mipTailOffset;      ///< mip tail offset in bytes\n    UINT_32             mipTailCoordX;      ///< mip tail coord x\n    UINT_32             mipTailCoordY;      ///< mip tail coord y\n    UINT_32             mipTailCoordZ;      ///< mip tail coord z\n} ADDR3_MIP_INFO;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SURFACE_INFO_OUTPUT\n*\n*   @brief\n*       Output structure for Addr3ComputeSurfaceInfo\n*   @note\n        Element: AddrLib unit for computing. e.g. BCn: 4x4 blocks; R32B32B32: 32bit with 3x pitch\n        Pixel: Original pixel\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SURFACE_INFO_OUTPUT\n{\n    UINT_32             size;                 ///< Size of this structure in bytes\n    UINT_32             pitch;                ///< Pitch in elements (blocks for compressed formats)\n    UINT_32             pixelPitch;           ///< Pitch in original pixels\n    UINT_32             pixelHeight;          ///< Height in original pixels\n    UINT_32             pixelBits;            ///< Original bits per pixel, passed from input\n    UINT_32             bpp;                  ///< Bits per elements\n                                              ///  (e.g. blocks for BCn, 1/3 for 96bit)\n    UINT_32             numSlices;            ///< Padded depth for 3d resource\n                                              ///  or padded number of slices for 2d array resource\n    UINT_32             height;               ///< Padded height (of mip0) in elements\n    UINT_64             sliceSize;            ///< Slice (total mip chain) size in bytes\n    UINT_64             surfSize;             ///< Surface (total mip chain) size in bytes\n    UINT_32             baseAlign;            ///< Base address alignment\n    ADDR_EXTENT3D       blockExtent;          ///< Dimensions in element inside one block\n    UINT_32             pixelMipChainPitch;   ///< Mip chain pitch in original pixels\n    UINT_32             pixelMipChainHeight;  ///< Mip chain height in original pixels\n    ADDR3_MIP_INFO*     pMipInfo;             ///< Info regarding the start, sizes of the mip levels\n    BOOL_32             mipChainInTail;       ///< If whole mipchain falls into mip tail block\n    UINT_32             firstMipIdInTail;     ///< The id of first mip in tail, if there is no mip\n                                              ///  in tail, it will be set to number of mip levels\n} ADDR3_COMPUTE_SURFACE_INFO_OUTPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_SWMODE_SET\n*\n*   @brief\n*       Bit field that defines swizzle type\n****************************************************************************************************\n*/\n// The bit order MUST be the same as Addr3SwizzleMode enumerations, otherwise using bitset to enable\n// or disable swizzle modes will be problematic.\ntypedef union _ADDR3_SWMODE_SET\n{\n    struct\n    {\n        UINT_32 swLinear    :  1;\n        UINT_32 sw2d256B    :  1;\n        UINT_32 sw2d4kB     :  1;\n        UINT_32 sw2d64kB    :  1;\n        UINT_32 sw2d256kB   :  1;\n        UINT_32 sw3d4kB     :  1;\n        UINT_32 sw3d64kB    :  1;\n        UINT_32 sw3d256kB   :  1;\n        UINT_32 reserved    : 24;\n    };\n\n    UINT_32 value;\n} ADDR3_SWMODE_SET;\n\n/**\n****************************************************************************************************\n*   ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT\n*\n*   @brief\n*       Input structure of Addr3GetPossibleSwizzleModes\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n\n    ADDR3_SURFACE_FLAGS   flags;             ///< Surface flags\n    AddrResourceType      resourceType;      ///< Surface type\n    UINT_32               bpp;               ///< bits per pixel\n    UINT_32               width;             ///< Width (of mip0), in pixels\n    UINT_32               height;            ///< Height (of mip0), in pixels\n    UINT_32               numSlices;         ///< Number surface slice/depth (of mip0),\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               numSamples;        ///< Number of samples\n    UINT_32               maxAlign;          ///< maximum base/size alignment requested by client\n} ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT\n*\n*   @brief\n*       Output structure of Addr3GetPossibleSwizzleModes\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT\n{\n    UINT_32           size;             ///< Size of this structure in bytes\n    ADDR3_SWMODE_SET  validModes;       ///< List of valid swizzle modes for this function.\n} ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSurfaceInfo\n*\n*   @brief\n*       Compute surface width/height/slices/alignments and suitable tiling mode\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSurfaceInfo(\n    ADDR_HANDLE                              hLib,\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn,\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*       pOut);\n\n/**\n****************************************************************************************************\n*   Addr3GetPossibleSwizzleModes\n*\n*   @brief\n*       Returns a list of swizzle modes that are valid from the hardware's perspective for the\n*       client to choose from\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3GetPossibleSwizzleModes(\n    ADDR_HANDLE                                  hLib,\n    const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn,\n    ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n*\n*   @brief\n*       Input structure for Addr3ComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT\n{\n    UINT_32             size;            ///< Size of this structure in bytes\n\n    UINT_32             x;               ///< X coordinate\n    UINT_32             y;               ///< Y coordinate\n    UINT_32             slice;           ///< Slice index\n    UINT_32             sample;          ///< Sample index, use fragment index for EQAA\n    UINT_32             mipId;           ///< the mip ID in mip chain\n\n    Addr3SwizzleMode    swizzleMode;     ///< Swizzle mode for Gfx12\n    ADDR3_SURFACE_FLAGS flags;           ///< Surface flags\n    AddrResourceType    resourceType;    ///< Surface type\n    UINT_32             bpp;             ///< Bits per pixel\n    ADDR_EXTENT3D       unAlignedDims;   ///< Surface original dimensions (of mip0)\n    UINT_32             numMipLevels;    ///< Total mipmap levels\n    UINT_32             numSamples;      ///< Number of samples\n    UINT_32             pitchInElement;  ///< Pitch in elements (blocks for compressed formats)\n} ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n*\n*   @brief\n*       Output structure for Addr3ComputeSurfaceAddrFromCoord\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT\n{\n    UINT_32    size;             ///< Size of this structure in bytes\n\n    UINT_64    addr;             ///< Byte offset from the image starting address\n    UINT_32    bitPosition;      ///< Bit position within surfaceAddr, 0-7.\n                                 ///  For surface bpp < 8, e.g. FMT_1.\n    UINT_32    prtBlockIndex;    ///< Index of a PRT tile (64K block)\n} ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address from a given coordinate.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                         hLib,\n    const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT*    pIn,\n    ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*         pOut);\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_PIPEBANKXOR_INPUT\n*\n*   @brief\n*       Input structure of Addr3ComputePipebankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_PIPEBANKXOR_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             surfIndex;          ///< Input surface index\n    Addr3SwizzleMode    swizzleMode;        ///< Surface swizzle mode\n} ADDR3_COMPUTE_PIPEBANKXOR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT\n*\n*   @brief\n*       Output structure of Addr3ComputePipebankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             pipeBankXor;        ///< Pipe bank xor\n} ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputePipeBankXor\n*\n*   @brief\n*       Calculate a valid bank pipe xor value for client to use.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputePipeBankXor(\n    ADDR_HANDLE                            hLib,\n    const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n    ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT\n*\n*   @brief\n*       Input structure of Addr3ComputeNonBlockCompressedView\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT\n{\n    UINT_32               size;              ///< Size of this structure in bytes\n    ADDR3_SURFACE_FLAGS   flags;             ///< Surface flags\n    Addr3SwizzleMode      swizzleMode;       ///< Swizzle Mode for Gfx12\n    AddrResourceType      resourceType;      ///< Surface type\n    AddrFormat            format;            ///< Surface format\n    ADDR_EXTENT3D         unAlignedDims;     ///< Surface original dimensions (of mip0)\n    UINT_32               numMipLevels;      ///< Total mipmap levels.\n    UINT_32               pipeBankXor;       ///< Combined swizzle used to do bank/pipe rotation\n    UINT_32               slice;             ///< Index of slice to view\n    UINT_32               mipId;             ///< Id of mip to view\n} ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT\n*\n*   @brief\n*       Output structure of Addr3ComputeNonBlockCompressedView\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_64             offset;             ///< Offset from resource base for the view\n    UINT_32             pipeBankXor;        ///< Pipe bank xor for the view\n    ADDR_EXTENT3D       unAlignedDims;      ///< Mip0 dimens (in element) for the view\n    UINT_32             numMipLevels;       ///< Total mipmap levels for the view\n    UINT_32             mipId;              ///< Mip ID for the view\n} ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeNonBlockCompressedView(\n    ADDR_HANDLE                                       hLib,\n    const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n    ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT\n*\n*   @brief\n*       Input structure of Addr3ComputeSubResourceOffsetForSwizzlePattern\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    Addr3SwizzleMode    swizzleMode;        ///< Surface swizzle mode\n    AddrResourceType    resourceType;       ///< Surface resource type\n    UINT_32             pipeBankXor;        ///< Per resource xor\n    UINT_32             slice;              ///< Slice id\n    UINT_64             sliceSize;          ///< Slice size of a mip chain\n    UINT_64             macroBlockOffset;   ///< Macro block offset, returned in ADDR3_MIP_INFO\n    UINT_32             mipTailOffset;      ///< Mip tail offset, returned in ADDR3_MIP_INFO\n} ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT\n*\n*   @brief\n*       Output structure of Addr3ComputeSubResourceOffsetForSwizzlePattern\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_64             offset;             ///< offset\n} ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Calculate sub resource offset to support swizzle pattern.\n****************************************************************************************************\n*/\nVOID ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern(\n    ADDR_HANDLE                                                     hLib,\n    const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n    ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut);\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT\n*\n*   @brief\n*       Input structure of Addr2ComputeSlicePipeBankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    Addr3SwizzleMode    swizzleMode;        ///< Surface swizzle mode\n    AddrResourceType    resourceType;       ///< Surface resource type\n    UINT_32             bpe;                ///< bits per element (e.g. block size for BCn format)\n    UINT_32             basePipeBankXor;    ///< Base pipe bank xor\n    UINT_32             slice;              ///< Slice id\n    UINT_32             numSamples;         ///< Number of samples\n} ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT;\n\n/**\n****************************************************************************************************\n*   ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT\n*\n*   @brief\n*       Output structure of Addr3ComputeSlicePipeBankXor\n****************************************************************************************************\n*/\ntypedef struct _ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT\n{\n    UINT_32             size;               ///< Size of this structure in bytes\n    UINT_32             pipeBankXor;        ///< Pipe bank xor\n} ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT;\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSlicePipeBankXor\n*\n*   @brief\n*       Calculate slice pipe bank xor value based on base pipe bank xor and slice id.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSlicePipeBankXor(\n    ADDR_HANDLE                                  hLib,\n    const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n    ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut);\n\n} // namespace rocr\n#endif // __ADDR_INTERFACE_H__\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/inc/addrtypes.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrtypes.h\n* @brief Contains the helper function and constants\n****************************************************************************************************\n*/\n#ifndef __ADDR_TYPES_H__\n#define __ADDR_TYPES_H__\n\n#if defined(__APPLE__) && !defined(HAVE_TSERVER)\n// External definitions header maintained by Apple driver team, but not for diag team under Mac.\n// Helps address compilation issues & reduces code covered by NDA\n#include \"addrExtDef.h\"\n\n#else\n\n// Windows and/or Linux\n#if !defined(VOID)\ntypedef void           VOID;\n#endif\n\n#if !defined(FLOAT)\ntypedef float          FLOAT;\n#endif\n\n#if !defined(DOUBLE)\ntypedef double         DOUBLE;\n#endif\n\n#if !defined(CHAR)\ntypedef char           CHAR;\n#endif\n\n#if !defined(INT)\ntypedef int            INT;\n#endif\n\n#include <stdarg.h> // va_list...etc need this header\n\n#endif // defined (__APPLE__) && !defined(HAVE_TSERVER)\n\n/**\n****************************************************************************************************\n*   Calling conventions\n****************************************************************************************************\n*/\n#ifndef ADDR_CDECL\n    #if defined(__GNUC__)\n        #if defined(__i386__)\n            #define ADDR_CDECL __attribute__((cdecl))\n        #else\n            #define ADDR_CDECL\n        #endif\n    #else\n        #define ADDR_CDECL __cdecl\n    #endif\n#endif\n\n#ifndef ADDR_STDCALL\n    #if defined(__GNUC__)\n        #if defined(__i386__)\n            #define ADDR_STDCALL __attribute__((stdcall))\n        #else\n            #define ADDR_STDCALL\n        #endif\n    #else\n        #define ADDR_STDCALL __stdcall\n    #endif\n#endif\n\n#ifndef ADDR_FASTCALL\n    #if defined(__GNUC__)\n        #if defined(__i386__) || defined(__amd64__) || defined(__x86_64__)\n            #define ADDR_FASTCALL __attribute__((regparm(0)))\n        #else\n            #define ADDR_FASTCALL\n        #endif\n    #else\n        #define ADDR_FASTCALL __fastcall\n    #endif\n#endif\n\n#ifndef GC_CDECL\n    #define GC_CDECL  ADDR_CDECL\n#endif\n\n#ifndef GC_STDCALL\n    #define GC_STDCALL  ADDR_STDCALL\n#endif\n\n#ifndef GC_FASTCALL\n    #define GC_FASTCALL  ADDR_FASTCALL\n#endif\n\n\n#if defined(__GNUC__)\n    #define ADDR_INLINE static inline   // inline needs to be static to link\n#else\n    // win32, win64, other platforms\n    #define ADDR_INLINE   __inline\n#endif // #if defined(__GNUC__)\n\n#define ADDR_API ADDR_FASTCALL //default call convention is fast call\n\n/**\n****************************************************************************************************\n* Global defines used by other modules\n****************************************************************************************************\n*/\n#if !defined(TILEINDEX_INVALID)\n#define TILEINDEX_INVALID                -1\n#endif\n\n#if !defined(TILEINDEX_LINEAR_GENERAL)\n#define TILEINDEX_LINEAR_GENERAL         -2\n#endif\n\n#if !defined(TILEINDEX_LINEAR_ALIGNED)\n#define TILEINDEX_LINEAR_ALIGNED          8\n#endif\n\n/**\n****************************************************************************************************\n* Return codes\n****************************************************************************************************\n*/\ntypedef enum _ADDR_E_RETURNCODE\n{\n    // General Return\n    ADDR_OK    = 0,\n    ADDR_ERROR = 1,\n\n    // Specific Errors\n    ADDR_OUTOFMEMORY,\n    ADDR_INVALIDPARAMS,\n    ADDR_NOTSUPPORTED,\n    ADDR_NOTIMPLEMENTED,\n    ADDR_PARAMSIZEMISMATCH,\n    ADDR_INVALIDGBREGVALUES,\n\n} ADDR_E_RETURNCODE;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define tile modes for all H/W\n* @note\n*   R600/R800 tiling mode can be cast to hw enums directly but never cast into HW enum from\n*   ADDR_TM_2D_TILED_XTHICK\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrTileMode\n{\n    ADDR_TM_LINEAR_GENERAL      = 0,    ///< Least restrictions, pitch: multiple of 8 if not buffer\n    ADDR_TM_LINEAR_ALIGNED      = 1,    ///< Requests pitch or slice to be multiple of 64 pixels\n    ADDR_TM_1D_TILED_THIN1      = 2,    ///< Linear array of 8x8 tiles\n    ADDR_TM_1D_TILED_THICK      = 3,    ///< Linear array of 8x8x4 tiles\n    ADDR_TM_2D_TILED_THIN1      = 4,    ///< A set of macro tiles consist of 8x8 tiles\n    ADDR_TM_2D_TILED_THIN2      = 5,    ///< 600 HWL only, macro tile ratio is 1:4\n    ADDR_TM_2D_TILED_THIN4      = 6,    ///< 600 HWL only, macro tile ratio is 1:16\n    ADDR_TM_2D_TILED_THICK      = 7,    ///< A set of macro tiles consist of 8x8x4 tiles\n    ADDR_TM_2B_TILED_THIN1      = 8,    ///< 600 HWL only, with bank swap\n    ADDR_TM_2B_TILED_THIN2      = 9,    ///< 600 HWL only, with bank swap and ratio is 1:4\n    ADDR_TM_2B_TILED_THIN4      = 10,   ///< 600 HWL only, with bank swap and ratio is 1:16\n    ADDR_TM_2B_TILED_THICK      = 11,   ///< 600 HWL only, with bank swap, consists of 8x8x4 tiles\n    ADDR_TM_3D_TILED_THIN1      = 12,   ///< Macro tiling w/ pipe rotation between slices\n    ADDR_TM_3D_TILED_THICK      = 13,   ///< Macro tiling w/ pipe rotation bwtween slices, thick\n    ADDR_TM_3B_TILED_THIN1      = 14,   ///< 600 HWL only, with bank swap\n    ADDR_TM_3B_TILED_THICK      = 15,   ///< 600 HWL only, with bank swap, thick\n    ADDR_TM_2D_TILED_XTHICK     = 16,   ///< Tile is 8x8x8, valid from NI\n    ADDR_TM_3D_TILED_XTHICK     = 17,   ///< Tile is 8x8x8, valid from NI\n    ADDR_TM_POWER_SAVE          = 18,   ///< Power save mode, only used by KMD on NI\n    ADDR_TM_PRT_TILED_THIN1     = 19,   ///< No bank/pipe rotation or hashing beyond macrotile size\n    ADDR_TM_PRT_2D_TILED_THIN1  = 20,   ///< Same as 2D_TILED_THIN1, PRT only\n    ADDR_TM_PRT_3D_TILED_THIN1  = 21,   ///< Same as 3D_TILED_THIN1, PRT only\n    ADDR_TM_PRT_TILED_THICK     = 22,   ///< No bank/pipe rotation or hashing beyond macrotile size\n    ADDR_TM_PRT_2D_TILED_THICK  = 23,   ///< Same as 2D_TILED_THICK, PRT only\n    ADDR_TM_PRT_3D_TILED_THICK  = 24,   ///< Same as 3D_TILED_THICK, PRT only\n    ADDR_TM_UNKNOWN             = 25,   ///< Unkown tile mode, should be decided by address lib\n    ADDR_TM_COUNT               = 26,   ///< Must be the value of the last tile mode\n} AddrTileMode;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define swizzle modes for Gfx9+ ASIC\n* @note\n*\n*   ADDR_SW_LINEAR linear aligned addressing mode, for 1D/2D/3D resource\n*   ADDR_SW_256B_* addressing block aligned size is 256B, for 2D resource\n*   ADDR_SW_4KB_*  addressing block aligned size is 4KB, for 2D/3D resource\n*   ADDR_SW_64KB_* addressing block aligned size is 64KB, for 1D/2D/3D resource\n*   ADDR_SW_VAR_*  addressing block aligned size is ASIC specific\n*\n*   ADDR_SW_*_Z    For GFX9:\n                   - for 2D resource, represents Z-order swizzle mode for depth/stencil/FMask\n                   - for 3D resource, represents a swizzle mode similar to legacy thick tile mode\n                   For GFX10:\n                   - represents Z-order swizzle mode for depth/stencil/FMask\n*   ADDR_SW_*_S    For GFX9+:\n                   - represents standard swizzle mode defined by MS\n*   ADDR_SW_*_D    For GFX9:\n                   - for 2D resource, represents a swizzle mode for displayable resource\n*                  - for 3D resource, represents a swizzle mode which places each slice in order & pixel\n                   For GFX10:\n                   - for 2D resource, represents a swizzle mode for displayable resource\n                   - for 3D resource, represents a swizzle mode similar to legacy thick tile mode\n                   within slice is placed as 2D ADDR_SW_*_S. Don't use this combination if possible!\n*   ADDR_SW_*_R    For GFX9:\n                   - 2D resource only, represents a swizzle mode for rotated displayable resource\n                   For GFX10:\n                   - represents a swizzle mode for render target resource\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrSwizzleMode\n{\n    ADDR_SW_LINEAR          = 0,\n    ADDR_SW_256B_S          = 1,\n    ADDR_SW_256B_D          = 2,\n    ADDR_SW_256B_R          = 3,\n    ADDR_SW_4KB_Z           = 4,\n    ADDR_SW_4KB_S           = 5,\n    ADDR_SW_4KB_D           = 6,\n    ADDR_SW_4KB_R           = 7,\n    ADDR_SW_64KB_Z          = 8,\n    ADDR_SW_64KB_S          = 9,\n    ADDR_SW_64KB_D          = 10,\n    ADDR_SW_64KB_R          = 11,\n    ADDR_SW_MISCDEF12       = 12,\n    ADDR_SW_MISCDEF13       = 13,\n    ADDR_SW_MISCDEF14       = 14,\n    ADDR_SW_MISCDEF15       = 15,\n    ADDR_SW_64KB_Z_T        = 16,\n    ADDR_SW_64KB_S_T        = 17,\n    ADDR_SW_64KB_D_T        = 18,\n    ADDR_SW_64KB_R_T        = 19,\n    ADDR_SW_4KB_Z_X         = 20,\n    ADDR_SW_4KB_S_X         = 21,\n    ADDR_SW_4KB_D_X         = 22,\n    ADDR_SW_4KB_R_X         = 23,\n    ADDR_SW_64KB_Z_X        = 24,\n    ADDR_SW_64KB_S_X        = 25,\n    ADDR_SW_64KB_D_X        = 26,\n    ADDR_SW_64KB_R_X        = 27,\n    ADDR_SW_MISCDEF28       = 28,\n    ADDR_SW_MISCDEF29       = 29,\n    ADDR_SW_MISCDEF30       = 30,\n    ADDR_SW_MISCDEF31       = 31,\n    ADDR_SW_LINEAR_GENERAL  = 32,\n    ADDR_SW_MAX_TYPE        = 33,\n\n    ADDR_SW_RESERVED0       = ADDR_SW_MISCDEF12,\n    ADDR_SW_RESERVED1       = ADDR_SW_MISCDEF13,\n    ADDR_SW_RESERVED2       = ADDR_SW_MISCDEF14,\n    ADDR_SW_RESERVED3       = ADDR_SW_MISCDEF15,\n    ADDR_SW_RESERVED4       = ADDR_SW_MISCDEF29,\n    ADDR_SW_RESERVED5       = ADDR_SW_MISCDEF30,\n\n    ADDR_SW_VAR_Z_X         = ADDR_SW_MISCDEF28,\n    ADDR_SW_VAR_R_X         = ADDR_SW_MISCDEF31,\n\n    ADDR_SW_256KB_Z_X       = ADDR_SW_MISCDEF28,\n    ADDR_SW_256KB_S_X       = ADDR_SW_MISCDEF29,\n    ADDR_SW_256KB_D_X       = ADDR_SW_MISCDEF30,\n    ADDR_SW_256KB_R_X       = ADDR_SW_MISCDEF31,\n} AddrSwizzleMode;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define swizzle modes for Gfx12+ ASIC\n*\n****************************************************************************************************\n*/\ntypedef enum _Addr3SwizzleMode\n{\n    ADDR3_LINEAR    = 0,\n    ADDR3_256B_2D   = 1,\n    ADDR3_4KB_2D    = 2,\n    ADDR3_64KB_2D   = 3,\n    ADDR3_256KB_2D  = 4,\n    ADDR3_4KB_3D    = 5,\n    ADDR3_64KB_3D   = 6,\n    ADDR3_256KB_3D  = 7,\n    ADDR3_MAX_TYPE  = 8,\n} Addr3SwizzleMode;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define image type\n* @note\n*   this is new for address library interface version 2\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrResourceType\n{\n    ADDR_RSRC_TEX_1D = 0,\n    ADDR_RSRC_TEX_2D = 1,\n    ADDR_RSRC_TEX_3D = 2,\n    ADDR_RSRC_MAX_TYPE = 3,\n} AddrResourceType;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define resource heap location\n* @note\n*   this is new for address library interface version 2\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrResrouceLocation\n{\n    ADDR_RSRC_LOC_UNDEF  = 0,   // Resource heap is undefined/unknown\n    ADDR_RSRC_LOC_LOCAL  = 1,   // CPU visable and CPU invisable local heap\n    ADDR_RSRC_LOC_USWC   = 2,   // CPU write-combined non-cached nonlocal heap\n    ADDR_RSRC_LOC_CACHED = 3,   // CPU cached nonlocal heap\n    ADDR_RSRC_LOC_INVIS  = 4,   // CPU invisable local heap only\n    ADDR_RSRC_LOC_MAX_TYPE = 5,\n} AddrResrouceLocation;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define resource basic swizzle mode\n* @note\n*   this is new for address library interface version 2\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrSwType\n{\n    ADDR_SW_Z  = 0,   // Resource basic swizzle mode is ZOrder\n    ADDR_SW_S  = 1,   // Resource basic swizzle mode is Standard\n    ADDR_SW_D  = 2,   // Resource basic swizzle mode is Display\n    ADDR_SW_R  = 3,   // Resource basic swizzle mode is Rotated/Render optimized\n    ADDR_SW_L  = 4,   // Resource basic swizzle mode is Linear\n    ADDR_SW_MAX_SWTYPE\n} AddrSwType;\n\n/**\n****************************************************************************************************\n* @brief\n*   Neutral enums that define mipmap major mode\n* @note\n*   this is new for address library interface version 2\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrMajorMode\n{\n    ADDR_MAJOR_X = 0,\n    ADDR_MAJOR_Y = 1,\n    ADDR_MAJOR_Z = 2,\n    ADDR_MAJOR_MAX_TYPE = 3,\n} AddrMajorMode;\n\n/**\n****************************************************************************************************\n*   AddrFormat\n*\n*   @brief\n*       Neutral enum for SurfaceFormat\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrFormat {\n    ADDR_FMT_INVALID                              = 0x00000000,\n    ADDR_FMT_8                                    = 0x00000001,\n    ADDR_FMT_4_4                                  = 0x00000002,\n    ADDR_FMT_3_3_2                                = 0x00000003,\n    ADDR_FMT_RESERVED_4                           = 0x00000004,\n    ADDR_FMT_16                                   = 0x00000005,\n    ADDR_FMT_16_FLOAT                             = ADDR_FMT_16,\n    ADDR_FMT_8_8                                  = 0x00000007,\n    ADDR_FMT_5_6_5                                = 0x00000008,\n    ADDR_FMT_6_5_5                                = 0x00000009,\n    ADDR_FMT_1_5_5_5                              = 0x0000000a,\n    ADDR_FMT_4_4_4_4                              = 0x0000000b,\n    ADDR_FMT_5_5_5_1                              = 0x0000000c,\n    ADDR_FMT_32                                   = 0x0000000d,\n    ADDR_FMT_32_FLOAT                             = ADDR_FMT_32,\n    ADDR_FMT_16_16                                = 0x0000000f,\n    ADDR_FMT_16_16_FLOAT                          = ADDR_FMT_16_16,\n    ADDR_FMT_8_24                                 = 0x00000011,\n    ADDR_FMT_8_24_FLOAT                           = ADDR_FMT_8_24,\n    ADDR_FMT_24_8                                 = 0x00000013,\n    ADDR_FMT_24_8_FLOAT                           = ADDR_FMT_24_8,\n    ADDR_FMT_10_11_11                             = 0x00000015,\n    ADDR_FMT_10_11_11_FLOAT                       = ADDR_FMT_10_11_11,\n    ADDR_FMT_11_11_10                             = 0x00000017,\n    ADDR_FMT_11_11_10_FLOAT                       = ADDR_FMT_11_11_10,\n    ADDR_FMT_2_10_10_10                           = 0x00000019,\n    ADDR_FMT_8_8_8_8                              = 0x0000001a,\n    ADDR_FMT_10_10_10_2                           = 0x0000001b,\n    ADDR_FMT_X24_8_32_FLOAT                       = 0x0000001c,\n    ADDR_FMT_32_32                                = 0x0000001d,\n    ADDR_FMT_32_32_FLOAT                          = ADDR_FMT_32_32,\n    ADDR_FMT_16_16_16_16                          = 0x0000001f,\n    ADDR_FMT_16_16_16_16_FLOAT                    = ADDR_FMT_16_16_16_16,\n    ADDR_FMT_RESERVED_33                          = 0x00000021,\n    ADDR_FMT_32_32_32_32                          = 0x00000022,\n    ADDR_FMT_32_32_32_32_FLOAT                    = ADDR_FMT_32_32_32_32,\n    ADDR_FMT_RESERVED_36                          = 0x00000024,\n    ADDR_FMT_1                                    = 0x00000025,\n    ADDR_FMT_1_REVERSED                           = 0x00000026,\n    ADDR_FMT_GB_GR                                = 0x00000027,\n    ADDR_FMT_BG_RG                                = 0x00000028,\n    ADDR_FMT_32_AS_8                              = 0x00000029,\n    ADDR_FMT_32_AS_8_8                            = 0x0000002a,\n    ADDR_FMT_5_9_9_9_SHAREDEXP                    = 0x0000002b,\n    ADDR_FMT_8_8_8                                = 0x0000002c,\n    ADDR_FMT_16_16_16                             = 0x0000002d,\n    ADDR_FMT_16_16_16_FLOAT                       = ADDR_FMT_16_16_16,\n    ADDR_FMT_32_32_32                             = 0x0000002f,\n    ADDR_FMT_32_32_32_FLOAT                       = ADDR_FMT_32_32_32,\n    ADDR_FMT_BC1                                  = 0x00000031,\n    ADDR_FMT_BC2                                  = 0x00000032,\n    ADDR_FMT_BC3                                  = 0x00000033,\n    ADDR_FMT_BC4                                  = 0x00000034,\n    ADDR_FMT_BC5                                  = 0x00000035,\n    ADDR_FMT_BC6                                  = 0x00000036,\n    ADDR_FMT_BC7                                  = 0x00000037,\n    ADDR_FMT_32_AS_32_32_32_32                    = 0x00000038,\n    ADDR_FMT_APC3                                 = 0x00000039,\n    ADDR_FMT_APC4                                 = 0x0000003a,\n    ADDR_FMT_APC5                                 = 0x0000003b,\n    ADDR_FMT_APC6                                 = 0x0000003c,\n    ADDR_FMT_APC7                                 = 0x0000003d,\n    ADDR_FMT_CTX1                                 = 0x0000003e,\n    ADDR_FMT_RESERVED_63                          = 0x0000003f,\n    ADDR_FMT_ASTC_4x4                             = 0x00000040,\n    ADDR_FMT_ASTC_5x4                             = 0x00000041,\n    ADDR_FMT_ASTC_5x5                             = 0x00000042,\n    ADDR_FMT_ASTC_6x5                             = 0x00000043,\n    ADDR_FMT_ASTC_6x6                             = 0x00000044,\n    ADDR_FMT_ASTC_8x5                             = 0x00000045,\n    ADDR_FMT_ASTC_8x6                             = 0x00000046,\n    ADDR_FMT_ASTC_8x8                             = 0x00000047,\n    ADDR_FMT_ASTC_10x5                            = 0x00000048,\n    ADDR_FMT_ASTC_10x6                            = 0x00000049,\n    ADDR_FMT_ASTC_10x8                            = 0x0000004a,\n    ADDR_FMT_ASTC_10x10                           = 0x0000004b,\n    ADDR_FMT_ASTC_12x10                           = 0x0000004c,\n    ADDR_FMT_ASTC_12x12                           = 0x0000004d,\n    ADDR_FMT_ETC2_64BPP                           = 0x0000004e,\n    ADDR_FMT_ETC2_128BPP                          = 0x0000004f,\n    ADDR_FMT_BG_RG_16_16_16_16                    = 0x00000050,\n} AddrFormat;\n\n/**\n****************************************************************************************************\n*   AddrDepthFormat\n*\n*   @brief\n*       Neutral enum for addrFlt32ToDepthPixel\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrDepthFormat\n{\n    ADDR_DEPTH_INVALID                            = 0x00000000,\n    ADDR_DEPTH_16                                 = 0x00000001,\n    ADDR_DEPTH_X8_24                              = 0x00000002,\n    ADDR_DEPTH_8_24                               = 0x00000003,\n    ADDR_DEPTH_X8_24_FLOAT                        = 0x00000004,\n    ADDR_DEPTH_8_24_FLOAT                         = 0x00000005,\n    ADDR_DEPTH_32_FLOAT                           = 0x00000006,\n    ADDR_DEPTH_X24_8_32_FLOAT                     = 0x00000007,\n\n} AddrDepthFormat;\n\n/**\n****************************************************************************************************\n*   AddrColorFormat\n*\n*   @brief\n*       Neutral enum for ColorFormat\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrColorFormat\n{\n    ADDR_COLOR_INVALID                            = 0x00000000,\n    ADDR_COLOR_8                                  = 0x00000001,\n    ADDR_COLOR_4_4                                = 0x00000002,\n    ADDR_COLOR_3_3_2                              = 0x00000003,\n    ADDR_COLOR_RESERVED_4                         = 0x00000004,\n    ADDR_COLOR_16                                 = 0x00000005,\n    ADDR_COLOR_16_FLOAT                           = 0x00000006,\n    ADDR_COLOR_8_8                                = 0x00000007,\n    ADDR_COLOR_5_6_5                              = 0x00000008,\n    ADDR_COLOR_6_5_5                              = 0x00000009,\n    ADDR_COLOR_1_5_5_5                            = 0x0000000a,\n    ADDR_COLOR_4_4_4_4                            = 0x0000000b,\n    ADDR_COLOR_5_5_5_1                            = 0x0000000c,\n    ADDR_COLOR_32                                 = 0x0000000d,\n    ADDR_COLOR_32_FLOAT                           = 0x0000000e,\n    ADDR_COLOR_16_16                              = 0x0000000f,\n    ADDR_COLOR_16_16_FLOAT                        = 0x00000010,\n    ADDR_COLOR_8_24                               = 0x00000011,\n    ADDR_COLOR_8_24_FLOAT                         = 0x00000012,\n    ADDR_COLOR_24_8                               = 0x00000013,\n    ADDR_COLOR_24_8_FLOAT                         = 0x00000014,\n    ADDR_COLOR_10_11_11                           = 0x00000015,\n    ADDR_COLOR_10_11_11_FLOAT                     = 0x00000016,\n    ADDR_COLOR_11_11_10                           = 0x00000017,\n    ADDR_COLOR_11_11_10_FLOAT                     = 0x00000018,\n    ADDR_COLOR_2_10_10_10                         = 0x00000019,\n    ADDR_COLOR_8_8_8_8                            = 0x0000001a,\n    ADDR_COLOR_10_10_10_2                         = 0x0000001b,\n    ADDR_COLOR_X24_8_32_FLOAT                     = 0x0000001c,\n    ADDR_COLOR_32_32                              = 0x0000001d,\n    ADDR_COLOR_32_32_FLOAT                        = 0x0000001e,\n    ADDR_COLOR_16_16_16_16                        = 0x0000001f,\n    ADDR_COLOR_16_16_16_16_FLOAT                  = 0x00000020,\n    ADDR_COLOR_RESERVED_33                        = 0x00000021,\n    ADDR_COLOR_32_32_32_32                        = 0x00000022,\n    ADDR_COLOR_32_32_32_32_FLOAT                  = 0x00000023,\n} AddrColorFormat;\n\n/**\n****************************************************************************************************\n*   AddrSurfaceNumber\n*\n*   @brief\n*       Neutral enum for SurfaceNumber\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrSurfaceNumber {\n    ADDR_NUMBER_UNORM                             = 0x00000000,\n    ADDR_NUMBER_SNORM                             = 0x00000001,\n    ADDR_NUMBER_USCALED                           = 0x00000002,\n    ADDR_NUMBER_SSCALED                           = 0x00000003,\n    ADDR_NUMBER_UINT                              = 0x00000004,\n    ADDR_NUMBER_SINT                              = 0x00000005,\n    ADDR_NUMBER_SRGB                              = 0x00000006,\n    ADDR_NUMBER_FLOAT                             = 0x00000007,\n} AddrSurfaceNumber;\n\n/**\n****************************************************************************************************\n*   AddrSurfaceSwap\n*\n*   @brief\n*       Neutral enum for SurfaceSwap\n*\n****************************************************************************************************\n*/\ntypedef enum _AddrSurfaceSwap {\n    ADDR_SWAP_STD                                 = 0x00000000,\n    ADDR_SWAP_ALT                                 = 0x00000001,\n    ADDR_SWAP_STD_REV                             = 0x00000002,\n    ADDR_SWAP_ALT_REV                             = 0x00000003,\n} AddrSurfaceSwap;\n\n/**\n****************************************************************************************************\n*   AddrHtileBlockSize\n*\n*   @brief\n*       Size of HTILE blocks, valid values are 4 or 8 for now\n****************************************************************************************************\n*/\ntypedef enum _AddrHtileBlockSize\n{\n    ADDR_HTILE_BLOCKSIZE_4 = 4,\n    ADDR_HTILE_BLOCKSIZE_8 = 8,\n} AddrHtileBlockSize;\n\n\n/**\n****************************************************************************************************\n*   AddrPipeCfg\n*\n*   @brief\n*       The pipe configuration field specifies both the number of pipes and\n*       how pipes are interleaved on the surface.\n*       The expression of number of pipes, the shader engine tile size, and packer tile size\n*       is encoded in a PIPE_CONFIG register field.\n*       In general the number of pipes usually matches the number of memory channels of the\n*       hardware configuration.\n*       For hw configurations w/ non-pow2 memory number of memory channels, it usually matches\n*       the number of ROP units(? TODO: which registers??)\n*       The enum value = hw enum + 1 which is to reserve 0 for requesting default.\n****************************************************************************************************\n*/\ntypedef enum _AddrPipeCfg\n{\n    ADDR_PIPECFG_INVALID              = 0,\n    ADDR_PIPECFG_P2                   = 1, /// 2 pipes,\n    ADDR_PIPECFG_P4_8x16              = 5, /// 4 pipes,\n    ADDR_PIPECFG_P4_16x16             = 6,\n    ADDR_PIPECFG_P4_16x32             = 7,\n    ADDR_PIPECFG_P4_32x32             = 8,\n    ADDR_PIPECFG_P8_16x16_8x16        = 9, /// 8 pipes\n    ADDR_PIPECFG_P8_16x32_8x16        = 10,\n    ADDR_PIPECFG_P8_32x32_8x16        = 11,\n    ADDR_PIPECFG_P8_16x32_16x16       = 12,\n    ADDR_PIPECFG_P8_32x32_16x16       = 13,\n    ADDR_PIPECFG_P8_32x32_16x32       = 14,\n    ADDR_PIPECFG_P8_32x64_32x32       = 15,\n    ADDR_PIPECFG_P16_32x32_8x16       = 17, /// 16 pipes\n    ADDR_PIPECFG_P16_32x32_16x16      = 18,\n    ADDR_PIPECFG_UNUSED               = 19,\n    ADDR_PIPECFG_MAX                  = 20,\n} AddrPipeCfg;\n\n/**\n****************************************************************************************************\n* AddrTileType\n*\n*   @brief\n*       Neutral enums that specifies micro tile type (MICRO_TILE_MODE)\n****************************************************************************************************\n*/\ntypedef enum _AddrTileType\n{\n    ADDR_DISPLAYABLE        = 0,    ///< Displayable tiling\n    ADDR_NON_DISPLAYABLE    = 1,    ///< Non-displayable tiling, a.k.a thin micro tiling\n    ADDR_DEPTH_SAMPLE_ORDER = 2,    ///< Same as non-displayable plus depth-sample-order\n    ADDR_ROTATED            = 3,    ///< Rotated displayable tiling\n    ADDR_THICK              = 4,    ///< Thick micro-tiling, only valid for THICK and XTHICK\n} AddrTileType;\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//\n//  Type definitions: short system-independent names for address library types\n//\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n#if !defined(__APPLE__) || defined(HAVE_TSERVER)\n\n#ifndef BOOL_32        // no bool type in C\n/// @brief Boolean type, since none is defined in C\n/// @ingroup type\n#define BOOL_32 int\n#endif\n\n#ifndef INT_32\n#define INT_32  int\n#endif\n\n#ifndef UINT_32\n#define UINT_32 unsigned int\n#endif\n\n#ifndef INT_16\n#define INT_16  short\n#endif\n\n#ifndef UINT_16\n#define UINT_16 unsigned short\n#endif\n\n#ifndef INT_8\n#define INT_8   signed char // signed must be used because of aarch64\n#endif\n\n#ifndef UINT_8\n#define UINT_8  unsigned char\n#endif\n\n#ifndef NULL\n#define NULL 0\n#endif\n\n#ifndef TRUE\n#define TRUE 1\n#endif\n\n#ifndef FALSE\n#define FALSE 0\n#endif\n\n//\n//  64-bit integer types depend on the compiler\n//\n#if defined( __GNUC__ ) || defined( __WATCOMC__ )\n#define INT_64   long long\n#define UINT_64  unsigned long long\n\n#elif defined( _WIN32 )\n#define INT_64   __int64\n#define UINT_64  unsigned __int64\n\n#else\n#error Unsupported compiler and/or operating system for 64-bit integers\n\n/// @brief 64-bit signed integer type (compiler dependent)\n/// @ingroup type\n///\n/// The addrlib defines a 64-bit signed integer type for either\n/// Gnu/Watcom compilers (which use the first syntax) or for\n/// the Windows VCC compiler (which uses the second syntax).\n#define INT_64  long long OR __int64\n\n/// @brief 64-bit unsigned integer type (compiler dependent)\n/// @ingroup type\n///\n/// The addrlib defines a 64-bit unsigned integer type for either\n/// Gnu/Watcom compilers (which use the first syntax) or for\n/// the Windows VCC compiler (which uses the second syntax).\n///\n#define UINT_64  unsigned long long OR unsigned __int64\n#endif\n\n#endif // #if !defined(__APPLE__) || defined(HAVE_TSERVER)\n\n//  ADDR64X is used to print addresses in hex form on both Windows and Linux\n//\n#if defined( __GNUC__ ) || defined( __WATCOMC__ )\n#define ADDR64X \"llx\"\n#define ADDR64D \"lld\"\n\n#elif defined( _WIN32 )\n#define ADDR64X \"I64x\"\n#define ADDR64D \"I64d\"\n\n#else\n#error Unsupported compiler and/or operating system for 64-bit integers\n\n/// @brief Addrlib device address 64-bit printf tag  (compiler dependent)\n/// @ingroup type\n///\n/// This allows printf to display an ADDR_64 for either the Windows VCC compiler\n/// (which used this value) or the Gnu/Watcom compilers (which use \"llx\".\n/// An example of use is printf(\"addr 0x%\"ADDR64X\"\\n\", address);\n///\n#define ADDR64X \"llx\" OR \"I64x\"\n#define ADDR64D \"lld\" OR \"I64d\"\n#endif\n\n\n/// @brief Union for storing a 32-bit float or 32-bit integer\n/// @ingroup type\n///\n/// This union provides a simple way to convert between a 32-bit float\n/// and a 32-bit integer. It also prevents the compiler from producing\n/// code that alters NaN values when assiging or coying floats.\n/// Therefore, all address library routines that pass or return 32-bit\n/// floating point data do so by passing or returning a FLT_32.\n///\ntypedef union {\n    INT_32   i;\n    UINT_32  u;\n    float    f;\n} ADDR_FLT_32;\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//\n//  Macros for controlling linking and building on multiple systems\n//\n////////////////////////////////////////////////////////////////////////////////////////////////////\n#if defined(_MSC_VER)\n#if defined(va_copy)\n#undef va_copy  //redefine va_copy to support VC2013\n#endif\n#endif\n\n#if !defined(va_copy)\n#define va_copy(dst, src) \\\n    ((void) memcpy(&(dst), &(src), sizeof(va_list)))\n#endif\n\n#endif // __ADDR_TYPES_H__\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/addrinterface.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrinterface.cpp\n* @brief Contains the addrlib interface functions\n****************************************************************************************************\n*/\n#include \"addrinterface.h\"\n#include \"addrlib1.h\"\n#include \"addrlib2.h\"\n#include \"addrlib3.h\"\n\n#include \"addrcommon.h\"\n\nnamespace rocr {\nusing namespace Addr;\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Create/Destroy/Config functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrCreate\n*\n*   @brief\n*       Create address lib object\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrCreate(\n    const ADDR_CREATE_INPUT*    pAddrCreateIn,  ///< [in] infomation for creating address lib object\n    ADDR_CREATE_OUTPUT*         pAddrCreateOut) ///< [out] address lib handle\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n    {\n        returnCode = Lib::Create(pAddrCreateIn, pAddrCreateOut);\n    }\n\n    return returnCode;\n}\n\n\n\n/**\n****************************************************************************************************\n*   AddrDestroy\n*\n*   @brief\n*       Destroy address lib object\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrDestroy(\n    ADDR_HANDLE hLib) ///< address lib handle\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (hLib)\n    {\n        Lib* pLib = Lib::GetLib(hLib);\n        pLib->Destroy();\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                    Surface functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceInfo\n*\n*   @brief\n*       Calculate surface width/height/depth/alignments and suitable tiling mode\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceInfo(\n    ADDR_HANDLE                             hLib, ///< address lib handle\n    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,  ///< [in] surface information\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut) ///< [out] surface parameters and alignments\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address according to coordinates\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,  ///< [in] surface info and coordinates\n    ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) ///< [out] surface address\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Compute coordinates according to surface address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSurfaceCoordFromAddr(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,  ///< [in] surface info and address\n    ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut) ///< [out] coordinates\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                   HTile functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileInfo\n*\n*   @brief\n*       Compute Htile pitch, height, base alignment and size in bytes\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileInfo(\n    ADDR_HANDLE                             hLib, ///< address lib handle\n    const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,  ///< [in] Htile information\n    ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut) ///< [out] Htile pitch, height and size in bytes\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileAddrFromCoord\n*\n*   @brief\n*       Compute Htile address according to coordinates (of depth buffer)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileAddrFromCoord(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,  ///< [in] Htile info and coordinates\n    ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut) ///< [out] Htile address\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeHtileCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within depth buffer (1st pixel of a micro tile) according to\n*       Htile address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeHtileCoordFromAddr(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,  ///< [in] Htile info and address\n    ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut) ///< [out] Htile coordinates\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     C-mask functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskInfo\n*\n*   @brief\n*       Compute Cmask pitch, height, base alignment and size in bytes from color buffer\n*       info\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskInfo(\n    ADDR_HANDLE                             hLib, ///< address lib handle\n    const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,  ///< [in] Cmask pitch and height\n    ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut) ///< [out] Cmask pitch, height and size in bytes\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Compute Cmask address according to coordinates (of MSAA color buffer)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskAddrFromCoord(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,  ///< [in] Cmask info and coordinates\n    ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut) ///< [out] Cmask address\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within color buffer (1st pixel of a micro tile) according to\n*       Cmask address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeCmaskCoordFromAddr(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,  ///< [in] Cmask info and address\n    ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut) ///< [out] Cmask coordinates\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     F-mask functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskInfo\n*\n*   @brief\n*       Compute Fmask pitch/height/depth/alignments and size in bytes\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskInfo(\n    ADDR_HANDLE                             hLib, ///< address lib handle\n    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,  ///< [in] Fmask information\n    ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut) ///< [out] Fmask pitch and height\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Compute Fmask address according to coordinates (x,y,slice,sample,plane)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskAddrFromCoord(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,  ///< [in] Fmask info and coordinates\n    ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut) ///< [out] Fmask address\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates (x,y,slice,sample,plane) according to Fmask address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeFmaskCoordFromAddr(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*   pIn,  ///< [in] Fmask info and address\n    ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*        pOut) ///< [out] Fmask coordinates\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     DCC key functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrComputeDccInfo\n*\n*   @brief\n*       Compute DCC key size, base alignment based on color surface size, tile info or tile index\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeDccInfo(\n    ADDR_HANDLE                             hLib,   ///< handle of addrlib\n    const ADDR_COMPUTE_DCCINFO_INPUT*       pIn,    ///< [in] input\n    ADDR_COMPUTE_DCCINFO_OUTPUT*            pOut)   ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeDccInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n///////////////////////////////////////////////////////////////////////////////\n// Below functions are element related or helper functions\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrGetVersion\n*\n*   @brief\n*       Get AddrLib version number. Client may check this return value against ADDRLIB_VERSION\n*       defined in addrinterface.h to see if there is a mismatch.\n****************************************************************************************************\n*/\nUINT_32 ADDR_API AddrGetVersion(ADDR_HANDLE hLib)\n{\n    UINT_32 version = 0;\n\n    Addr::Lib* pLib = Lib::GetLib(hLib);\n\n    ADDR_ASSERT(pLib != NULL);\n\n    if (pLib)\n    {\n        version = pLib->GetVersion();\n    }\n\n    return version;\n}\n\n/**\n****************************************************************************************************\n*   AddrUseTileIndex\n*\n*   @brief\n*       Return TRUE if tileIndex is enabled in this address library\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API AddrUseTileIndex(ADDR_HANDLE hLib)\n{\n    BOOL_32 useTileIndex = FALSE;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_ASSERT(pLib != NULL);\n\n    if (pLib)\n    {\n        useTileIndex = pLib->UseTileIndex(0);\n    }\n\n    return useTileIndex;\n}\n\n/**\n****************************************************************************************************\n*   AddrUseCombinedSwizzle\n*\n*   @brief\n*       Return TRUE if combined swizzle is enabled in this address library\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API AddrUseCombinedSwizzle(ADDR_HANDLE hLib)\n{\n    BOOL_32 useCombinedSwizzle = FALSE;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_ASSERT(pLib != NULL);\n\n    if (pLib)\n    {\n        useCombinedSwizzle = pLib->UseCombinedSwizzle();\n    }\n\n    return useCombinedSwizzle;\n}\n\n/**\n****************************************************************************************************\n*   AddrExtractBankPipeSwizzle\n*\n*   @brief\n*       Extract Bank and Pipe swizzle from base256b\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrExtractBankPipeSwizzle(\n    ADDR_HANDLE                                 hLib,     ///< addrlib handle\n    const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,      ///< [in] input structure\n    ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut)     ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ExtractBankPipeSwizzle(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrCombineBankPipeSwizzle\n*\n*   @brief\n*       Combine Bank and Pipe swizzle\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrCombineBankPipeSwizzle(\n    ADDR_HANDLE                                 hLib,\n    const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,\n    ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->CombineBankPipeSwizzle(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeSliceSwizzle\n*\n*   @brief\n*       Compute a swizzle for slice from a base swizzle\n*   @return\n*       ADDR_OK if no error\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeSliceSwizzle(\n    ADDR_HANDLE                                 hLib,\n    const ADDR_COMPUTE_SLICESWIZZLE_INPUT*      pIn,\n    ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*           pOut)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSliceTileSwizzle(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputeBaseSwizzle\n*\n*   @brief\n*       Return a Combined Bank and Pipe swizzle base on surface based on surface type/index\n*   @return\n*       ADDR_OK if no error\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputeBaseSwizzle(\n    ADDR_HANDLE                             hLib,\n    const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,\n    ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT*       pOut)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeBaseSwizzle(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   ElemFlt32ToDepthPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a depth/stencil pixel value\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API ElemFlt32ToDepthPixel(\n    ADDR_HANDLE                         hLib,    ///< addrlib handle\n    const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,     ///< [in] per-component value\n    ELEM_FLT32TODEPTHPIXEL_OUTPUT*      pOut)    ///< [out] final pixel value\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    Lib* pLib = Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        pLib->Flt32ToDepthPixel(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   ElemFlt32ToColorPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a red/green/blue/alpha pixel value\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API ElemFlt32ToColorPixel(\n    ADDR_HANDLE                         hLib,    ///< addrlib handle\n    const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,     ///< [in] format, surface number and swap value\n    ELEM_FLT32TOCOLORPIXEL_OUTPUT*      pOut)    ///< [out] final pixel value\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    Lib* pLib = Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        pLib->Flt32ToColorPixel(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   ElemGetExportNorm\n*\n*   @brief\n*       Helper function to check one format can be EXPORT_NUM,\n*       which is a register CB_COLOR_INFO.SURFACE_FORMAT.\n*       FP16 can be reported as EXPORT_NORM for rv770 in r600\n*       family\n*\n****************************************************************************************************\n*/\nBOOL_32 ADDR_API ElemGetExportNorm(\n    ADDR_HANDLE                     hLib, ///< addrlib handle\n    const ELEM_GETEXPORTNORM_INPUT* pIn)  ///< [in] input structure\n{\n    Addr::Lib* pLib = Lib::GetLib(hLib);\n    BOOL_32 enabled = FALSE;\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        enabled = pLib->GetExportNorm(pIn);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    ADDR_ASSERT(returnCode == ADDR_OK);\n\n    return enabled;\n}\n\n/**\n****************************************************************************************************\n*   ElemSize\n*\n*   @brief\n*       Get bits-per-element for specified format\n*\n*   @return\n*       Bits-per-element of specified format\n*\n****************************************************************************************************\n*/\nUINT_32 ADDR_API ElemSize(\n    ADDR_HANDLE hLib,\n    AddrFormat  format)\n{\n    UINT_32 bpe = 0;\n\n    Addr::Lib* pLib = Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        bpe = pLib->GetBpe(format);\n    }\n\n    return bpe;\n}\n\n/**\n****************************************************************************************************\n*   AddrConvertTileInfoToHW\n*\n*   @brief\n*       Convert tile info from real value to hardware register value\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileInfoToHW(\n    ADDR_HANDLE                             hLib, ///< address lib handle\n    const ADDR_CONVERT_TILEINFOTOHW_INPUT*  pIn,  ///< [in] tile info with real value\n    ADDR_CONVERT_TILEINFOTOHW_OUTPUT*       pOut) ///< [out] tile info with HW register value\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ConvertTileInfoToHW(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrConvertTileIndex\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileIndex(\n    ADDR_HANDLE                          hLib, ///< address lib handle\n    const ADDR_CONVERT_TILEINDEX_INPUT*  pIn,  ///< [in] input - tile index\n    ADDR_CONVERT_TILEINDEX_OUTPUT*       pOut) ///< [out] tile mode/type/info\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ConvertTileIndex(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrGetMacroModeIndex\n*\n*   @brief\n*       Get macro mode index based on input parameters\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMacroModeIndex(\n    ADDR_HANDLE                          hLib, ///< address lib handle\n    const ADDR_GET_MACROMODEINDEX_INPUT* pIn,  ///< [in] input\n    ADDR_GET_MACROMODEINDEX_OUTPUT*      pOut) ///< [out] macro mode index\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetMacroModeIndex(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrConvertTileIndex1\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrConvertTileIndex1(\n    ADDR_HANDLE                          hLib, ///< address lib handle\n    const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,  ///< [in] input - tile index\n    ADDR_CONVERT_TILEINDEX_OUTPUT*       pOut) ///< [out] tile mode/type/info\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ConvertTileIndex1(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrGetTileIndex\n*\n*   @brief\n*       Get tile index from tile mode/type/info\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n*\n*   @note\n*       Only meaningful for SI (and above)\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetTileIndex(\n    ADDR_HANDLE                     hLib,\n    const ADDR_GET_TILEINDEX_INPUT* pIn,\n    ADDR_GET_TILEINDEX_OUTPUT*      pOut)\n{\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetTileIndex(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrComputePrtInfo\n*\n*   @brief\n*       Interface function for ComputePrtInfo\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrComputePrtInfo(\n    ADDR_HANDLE                 hLib,\n    const ADDR_PRT_INFO_INPUT*  pIn,\n    ADDR_PRT_INFO_OUTPUT*       pOut)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    V1::Lib* pLib = V1::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputePrtInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrGetMaxAlignments\n*\n*   @brief\n*       Convert maximum alignments\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMaxAlignments(\n    ADDR_HANDLE                     hLib, ///< address lib handle\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut) ///< [out] output structure\n{\n    Addr::Lib* pLib = Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetMaxAlignments(pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   AddrGetMaxMetaAlignments\n*\n*   @brief\n*       Convert maximum alignments for metadata\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API AddrGetMaxMetaAlignments(\n    ADDR_HANDLE                     hLib, ///< address lib handle\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut) ///< [out] output structure\n{\n    Addr::Lib* pLib = Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetMaxMetaAlignments(pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                    Surface functions for Addr2\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceInfo\n*\n*   @brief\n*       Calculate surface width/height/depth/alignments and suitable tiling mode\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceInfo(\n    ADDR_HANDLE                                hLib, ///< address lib handle\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT*    pIn,  ///< [in] surface information\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*         pOut) ///< [out] surface parameters and alignments\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address according to coordinates\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                         hLib, ///< address lib handle\n    const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] surface info and coordinates\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] surface address\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Compute coordinates according to surface address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSurfaceCoordFromAddr(\n    ADDR_HANDLE                                         hLib, ///< address lib handle\n    const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT*    pIn,  ///< [in] surface info and address\n    ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*         pOut) ///< [out] coordinates\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                   HTile functions for Addr2\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileInfo\n*\n*   @brief\n*       Compute Htile pitch, height, base alignment and size in bytes\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileInfo(\n    ADDR_HANDLE                              hLib, ///< address lib handle\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,  ///< [in] Htile information\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut) ///< [out] Htile pitch, height and size in bytes\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileAddrFromCoord\n*\n*   @brief\n*       Compute Htile address according to coordinates (of depth buffer)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileAddrFromCoord(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] Htile info and coordinates\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] Htile address\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeHtileCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within depth buffer (1st pixel of a micro tile) according to\n*       Htile address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeHtileCoordFromAddr(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*    pIn,  ///< [in] Htile info and address\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*         pOut) ///< [out] Htile coordinates\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeHtileCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     C-mask functions for Addr2\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskInfo\n*\n*   @brief\n*       Compute Cmask pitch, height, base alignment and size in bytes from color buffer\n*       info\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskInfo(\n    ADDR_HANDLE                              hLib, ///< address lib handle\n    const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,  ///< [in] Cmask pitch and height\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut) ///< [out] Cmask pitch, height and size in bytes\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Compute Cmask address according to coordinates (of MSAA color buffer)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskAddrFromCoord(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] Cmask info and coordinates\n    ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] Cmask address\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates within color buffer (1st pixel of a micro tile) according to\n*       Cmask address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeCmaskCoordFromAddr(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT*    pIn,  ///< [in] Cmask info and address\n    ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*         pOut) ///< [out] Cmask coordinates\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeCmaskCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     F-mask functions for Addr2\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskInfo\n*\n*   @brief\n*       Compute Fmask pitch/height/depth/alignments and size in bytes\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskInfo(\n    ADDR_HANDLE                              hLib, ///< address lib handle\n    const ADDR2_COMPUTE_FMASK_INFO_INPUT*    pIn,  ///< [in] Fmask information\n    ADDR2_COMPUTE_FMASK_INFO_OUTPUT*         pOut) ///< [out] Fmask pitch and height\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Compute Fmask address according to coordinates (x,y,slice,sample,plane)\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskAddrFromCoord(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] Fmask info and coordinates\n    ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] Fmask address\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Addr2ComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Compute coordinates (x,y,slice,sample,plane) according to Fmask address\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeFmaskCoordFromAddr(\n    ADDR_HANDLE                                       hLib, ///< address lib handle\n    const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT*    pIn,  ///< [in] Fmask info and address\n    ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*         pOut) ///< [out] Fmask coordinates\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeFmaskCoordFromAddr(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                     DCC key functions for Addr2\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr2ComputeDccInfo\n*\n*   @brief\n*       Compute DCC key size, base alignment based on color surface size, tile info or tile index\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeDccInfo(\n    ADDR_HANDLE                           hLib,   ///< handle of addrlib\n    const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut)   ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeDccInfo(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2ComputeDccAddrFromCoord\n*\n*   @brief\n*       Compute DCC key address according to coordinates\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeDccAddrFromCoord(\n    ADDR_HANDLE                                     hLib, ///< address lib handle\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] Dcc info and coordinates\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] Dcc address\n{\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeDccAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2ComputePipeBankXor\n*\n*   @brief\n*       Calculate a valid bank pipe xor value for client to use.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputePipeBankXor(\n    ADDR_HANDLE                            hLib, ///< handle of addrlib\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,  ///< [in] input\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputePipeBankXor(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSlicePipeBankXor\n*\n*   @brief\n*       Calculate slice pipe bank xor value based on base pipe bank xor and slice id.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSlicePipeBankXor(\n    ADDR_HANDLE                                  hLib, ///< handle of addrlib\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,  ///< [in] input\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSlicePipeBankXor(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Calculate sub resource offset for swizzle pattern.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeSubResourceOffsetForSwizzlePattern(\n    ADDR_HANDLE                                                     hLib, ///< handle of addrlib\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,  ///< [in] input\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2ComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2ComputeNonBlockCompressedView(\n    ADDR_HANDLE                                       hLib, ///< handle of addrlib\n    const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,  ///< [in] input\n    ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeNonBlockCompressedView(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2GetPreferredSurfaceSetting\n*\n*   @brief\n*       Suggest a preferred setting for client driver to program HW register\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetPreferredSurfaceSetting(\n    ADDR_HANDLE                                   hLib, ///< handle of addrlib\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->Addr2GetPreferredSurfaceSetting(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2IsValidDisplaySwizzleMode\n*\n*   @brief\n*       Return whether the swizzle mode is supported by display engine\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2IsValidDisplaySwizzleMode(\n    ADDR_HANDLE     hLib,\n    AddrSwizzleMode swizzleMode,\n    UINT_32         bpp,\n    BOOL_32         *pResult)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT in = {};\n        in.resourceType = ADDR_RSRC_TEX_2D;\n        in.swizzleMode  = swizzleMode;\n        in.bpp          = bpp;\n\n        *pResult   = pLib->IsValidDisplaySwizzleMode(&in);\n        returnCode = ADDR_OK;\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2GetPossibleSwizzleModes\n*\n*   @brief\n*       Returns a list of swizzle modes that are valid from the hardware's perspective for the\n*       client to choose from\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetPossibleSwizzleModes(\n    ADDR_HANDLE                                   hLib, ///< handle of addrlib\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetPossibleSwizzleModes(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n/**\n****************************************************************************************************\n*   Addr2GetAllowedBlockSet\n*\n*   @brief\n*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetAllowedBlockSet(\n    ADDR_HANDLE      hLib,              ///< handle of addrlib\n    ADDR2_SWMODE_SET allowedSwModeSet,  ///< [in] allowed swizzle modes\n    AddrResourceType rsrcType,          ///< [in] resource type\n    ADDR2_BLOCK_SET* pAllowedBlockSet)  ///< [out] allowed block sizes\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2GetAllowedSwSet\n*\n*   @brief\n*       Returns the set of allowed swizzle types given the allowed swizzle modes\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr2GetAllowedSwSet(\n    ADDR_HANDLE       hLib,              ///< handle of addrlib\n    ADDR2_SWMODE_SET  allowedSwModeSet,  ///< [in] allowed swizzle modes\n    ADDR2_SWTYPE_SET* pAllowedSwSet)     ///< [out] allowed swizzle types\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V2::Lib* pLib = V2::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr2IsBlockTypeAvailable\n*\n*   @brief\n*       Determine whether a block type is allowed in a given blockSet\n****************************************************************************************************\n*/\nBOOL_32 Addr2IsBlockTypeAvailable(\n    ADDR2_BLOCK_SET blockSet,\n    AddrBlockType   blockType)\n{\n    BOOL_32 avail;\n\n    if (blockType == AddrBlockLinear)\n    {\n        avail = blockSet.linear ? TRUE : FALSE;\n    }\n    else\n    {\n        avail = blockSet.value & (1 << (static_cast<UINT_32>(blockType) - 1)) ? TRUE : FALSE;\n    }\n\n    return avail;\n}\n\n/**\n****************************************************************************************************\n*   Addr2BlockTypeWithinMemoryBudget\n*\n*   @brief\n*       Determine whether a new block type is acceptable based on memory waste ratio. Will favor\n*       larger block types.\n****************************************************************************************************\n*/\nBOOL_32 Addr2BlockTypeWithinMemoryBudget(\n    UINT_64 minSize,\n    UINT_64 newBlockTypeSize,\n    UINT_32 ratioLow,\n    UINT_32 ratioHi,\n    DOUBLE  memoryBudget,\n    BOOL_32 newBlockTypeBigger)\n{\n    BOOL_32 accept = FALSE;\n\n    if (memoryBudget >= 1.0)\n    {\n        if (newBlockTypeBigger)\n        {\n            if ((static_cast<DOUBLE>(newBlockTypeSize) / minSize) <= memoryBudget)\n            {\n                accept = TRUE;\n            }\n        }\n        else\n        {\n            if ((static_cast<DOUBLE>(minSize) / newBlockTypeSize) > memoryBudget)\n            {\n                accept = TRUE;\n            }\n        }\n    }\n    else\n    {\n        if (newBlockTypeBigger)\n        {\n            if ((newBlockTypeSize * ratioHi) <= (minSize * ratioLow))\n            {\n                accept = TRUE;\n            }\n        }\n        else\n        {\n            if ((newBlockTypeSize * ratioLow) < (minSize * ratioHi))\n            {\n                accept = TRUE;\n            }\n        }\n    }\n\n    return accept;\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                                    Surface functions for Addr3\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSurfaceInfo\n*\n*   @brief\n*       Calculate surface width/height/depth/alignments and suitable tiling mode\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSurfaceInfo(\n    ADDR_HANDLE                                hLib, ///< address lib handle\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*    pIn,  ///< [in] surface information\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*         pOut) ///< [out] surface parameters and alignments\n{\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceInfo(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr3GetPossibleSwizzleModes\n*\n*   @brief\n*       Get valid swizzle mode options given image input for further optimal selection\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_PARAMSIZEMISMATCH\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3GetPossibleSwizzleModes(\n    ADDR_HANDLE                                    hLib, ///< address lib handle\n    const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT*   pIn,  ///< [in] surface information\n    ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT*        pOut) ///< [out] allowable swizzle mdoes\n{\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->GetPossibleSwizzleModes(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Compute surface address according to coordinates\n*\n*   @return\n*       ADDR_OK if successful, otherwise an error code of ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSurfaceAddrFromCoord(\n    ADDR_HANDLE                                         hLib, ///< address lib handle\n    const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT*    pIn,  ///< [in] surface info and coordinates\n    ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*         pOut) ///< [out] surface address\n{\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSurfaceAddrFromCoord(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr3ComputePipeBankXor\n*\n*   @brief\n*       Calculate a valid bank pipe xor value for client to use.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputePipeBankXor(\n    ADDR_HANDLE                            hLib, ///< handle of addrlib\n    const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,  ///< [in] input\n    ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputePipeBankXor(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr3ComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeNonBlockCompressedView(\n    ADDR_HANDLE                                       hLib, ///< handle of addrlib\n    const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,  ///< [in] input\n    ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeNonBlockCompressedView(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Calculate sub resource offset for swizzle pattern.\n****************************************************************************************************\n*/\nVOID ADDR_API Addr3ComputeSubResourceOffsetForSwizzlePattern(\n    ADDR_HANDLE                                                     hLib, ///< handle of addrlib\n    const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,  ///< [in] input\n    ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) ///< [out] output\n{\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        pLib->ComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);\n    }\n}\n\n/**\n****************************************************************************************************\n*   Addr3ComputeSlicePipeBankXor\n*\n*   @brief\n*       Calculate slice pipe bank xor value based on base pipe bank xor and slice id.\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE ADDR_API Addr3ComputeSlicePipeBankXor(\n    ADDR_HANDLE                                  hLib, ///< handle of addrlib\n    const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,  ///< [in] input\n    ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) ///< [out] output\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    V3::Lib* pLib = V3::Lib::GetLib(hLib);\n\n    if (pLib != NULL)\n    {\n        returnCode = pLib->ComputeSlicePipeBankXor(pIn, pOut);\n    }\n    else\n    {\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n} //namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/amdgpu_asic_addr.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2017-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#ifndef _AMDGPU_ASIC_ADDR_H\n#define _AMDGPU_ASIC_ADDR_H\n\n#define ATI_VENDOR_ID         0x1002\n#define AMD_VENDOR_ID         0x1022\n\n// AMDGPU_VENDOR_IS_AMD(vendorId)\n#define AMDGPU_VENDOR_IS_AMD(v) ((v == ATI_VENDOR_ID) || (v == AMD_VENDOR_ID))\n\n#define FAMILY_UNKNOWN 0x00\n#define FAMILY_TN      0x69 //# 105 / Trinity APUs\n#define FAMILY_SI      0x6E //# 110 / Southern Islands: Tahiti, Pitcairn, CapeVerde, Oland, Hainan\n#define FAMILY_CI      0x78 //# 120 / Sea Islands: Bonaire, Hawaii\n#define FAMILY_KV      0x7D //# 125 / Kaveri APUs: Spectre, Spooky, Kalindi, Godavari\n#define FAMILY_VI      0x82 //# 130 / Volcanic Islands: Iceland, Tonga, Fiji\n#define FAMILY_CZ      0x87 //# 135 / Carrizo APUs: Carrizo, Stoney\n#define FAMILY_AI      0x8D //# 141 / Vega: 10, 20\n#define FAMILY_RV      0x8E //# 142 / Raven\n#define FAMILY_NV      0x8F //# 143 / Navi: 10\n#define FAMILY_VGH     0x90 //# 144 / Van Gogh\n#define FAMILY_NV3     0x91 //# 145 / Navi: 3x\n#define FAMILY_GFX1150 0x96\n#define FAMILY_GFX1103 0x94\n#define FAMILY_RMB     0x92 //# 146 / Rembrandt\n#define FAMILY_RPL     0x95 //# 149 / Raphael\n#define FAMILY_MDN     0x97 //# 151 / Mendocino\n#define FAMILY_GFX12   0x98\n\n// AMDGPU_FAMILY_IS(familyId, familyName)\n#define FAMILY_IS(f, fn)     (f == FAMILY_##fn)\n#define FAMILY_IS_TN(f)      FAMILY_IS(f, TN)\n#define FAMILY_IS_SI(f)      FAMILY_IS(f, SI)\n#define FAMILY_IS_CI(f)      FAMILY_IS(f, CI)\n#define FAMILY_IS_KV(f)      FAMILY_IS(f, KV)\n#define FAMILY_IS_VI(f)      FAMILY_IS(f, VI)\n#define FAMILY_IS_POLARIS(f) FAMILY_IS(f, POLARIS)\n#define FAMILY_IS_CZ(f)      FAMILY_IS(f, CZ)\n#define FAMILY_IS_AI(f)      FAMILY_IS(f, AI)\n#define FAMILY_IS_RV(f)      FAMILY_IS(f, RV)\n#define FAMILY_IS_NV(f)      FAMILY_IS(f, NV)\n#define FAMILY_IS_NV3(f)     FAMILY_IS(f, NV3)\n#define FAMILY_IS_RMB(f)     FAMILY_IS(f, RMB)\n#define FAMILY_IS_GFX12(f)   FAMILY_IS(f, GFX12)\n\n#define AMDGPU_UNKNOWN          0xFF\n\n#define AMDGPU_TAHITI_RANGE     0x05, 0x14 //#  5 <= x < 20\n#define AMDGPU_PITCAIRN_RANGE   0x15, 0x28 //# 21 <= x < 40\n#define AMDGPU_CAPEVERDE_RANGE  0x29, 0x3C //# 41 <= x < 60\n#define AMDGPU_OLAND_RANGE      0x3C, 0x46 //# 60 <= x < 70\n#define AMDGPU_HAINAN_RANGE     0x46, 0xFF //# 70 <= x < max\n\n#define AMDGPU_BONAIRE_RANGE    0x14, 0x28 //# 20 <= x < 40\n#define AMDGPU_HAWAII_RANGE     0x28, 0x3C //# 40 <= x < 60\n\n#define AMDGPU_SPECTRE_RANGE    0x01, 0x41 //#   1 <= x < 65\n#define AMDGPU_SPOOKY_RANGE     0x41, 0x81 //#  65 <= x < 129\n#define AMDGPU_KALINDI_RANGE    0x81, 0xA1 //# 129 <= x < 161\n#define AMDGPU_GODAVARI_RANGE   0xA1, 0xFF //# 161 <= x < max\n\n#define AMDGPU_ICELAND_RANGE    0x01, 0x14 //#  1 <= x < 20\n#define AMDGPU_TONGA_RANGE      0x14, 0x28 //# 20 <= x < 40\n#define AMDGPU_FIJI_RANGE       0x3C, 0x50 //# 60 <= x < 80\n\n#define AMDGPU_POLARIS10_RANGE  0x50, 0x5A //#  80 <= x < 90\n#define AMDGPU_POLARIS11_RANGE  0x5A, 0x64 //#  90 <= x < 100\n#define AMDGPU_POLARIS12_RANGE  0x64, 0x6E //# 100 <= x < 110\n#define AMDGPU_VEGAM_RANGE      0x6E, 0xFF //# 110 <= x < max\n\n#define AMDGPU_CARRIZO_RANGE    0x01, 0x21 //#  1 <= x < 33\n#define AMDGPU_BRISTOL_RANGE    0x10, 0x21 //# 16 <= x < 33\n#define AMDGPU_STONEY_RANGE     0x61, 0xFF //# 97 <= x < max\n\n#define AMDGPU_VEGA10_RANGE     0x01, 0x14 //#  1 <= x < 20\n#define AMDGPU_VEGA12_RANGE     0x14, 0x28 //# 20 <= x < 40\n#define AMDGPU_VEGA20_RANGE     0x28, 0xFF //# 40 <= x < max\n\n#define AMDGPU_RAVEN_RANGE      0x01, 0x81 //#   1 <= x < 129\n#define AMDGPU_RAVEN2_RANGE     0x81, 0x90 //# 129 <= x < 144\n#define AMDGPU_RENOIR_RANGE     0x91, 0xFF //# 145 <= x < max\n\n#define AMDGPU_NAVI10_RANGE     0x01, 0x0A //# 1  <= x < 10\n#define AMDGPU_NAVI12_RANGE     0x0A, 0x14 //# 10 <= x < 20\n#define AMDGPU_NAVI14_RANGE     0x14, 0x28 //# 20 <= x < 40\n#define AMDGPU_NAVI21_RANGE     0x28, 0x32 //# 40  <= x < 50\n#define AMDGPU_NAVI22_RANGE     0x32, 0x3C //# 50  <= x < 60\n#define AMDGPU_NAVI23_RANGE     0x3C, 0x46 //# 60  <= x < 70\n#define AMDGPU_NAVI24_RANGE     0x46, 0x50 //# 70  <= x < 80\n\n#define AMDGPU_VANGOGH_RANGE    0x01, 0xFF //# 1 <= x < max\n\n#define AMDGPU_NAVI31_RANGE     0x01, 0x10 //# 01 <= x < 16\n#define AMDGPU_NAVI32_RANGE     0x20, 0xFF //# 32 <= x < 255\n#define AMDGPU_NAVI33_RANGE     0x10, 0x20 //# 16 <= x < 32\n#define AMDGPU_GFX1103_R1_RANGE 0x01, 0x80 //# 1 <= x < 128\n#define AMDGPU_GFX1103_R2_RANGE 0x80, 0xC0 //# 128 <= x < 192\n\n#define AMDGPU_GFX1150_RANGE    0x01, 0xFF //# 1 <= x < max\n\n#define AMDGPU_REMBRANDT_RANGE  0x01, 0xFF //# 01 <= x < 255\n\n#define AMDGPU_RAPHAEL_RANGE    0x01, 0xFF //# 1 <= x < max\n\n#define AMDGPU_MENDOCINO_RANGE  0x01, 0xFF //# 1 <= x < max\n\n#define AMDGPU_GFX12_TBD1_RANGE 0x40, 0xFF //# 64 <= x < max\n\n#define AMDGPU_EXPAND_FIX(x) x\n#define AMDGPU_RANGE_HELPER(val, min, max) ((val >= min) && (val < max))\n#define AMDGPU_IN_RANGE(val, ...)   AMDGPU_EXPAND_FIX(AMDGPU_RANGE_HELPER(val, __VA_ARGS__))\n\n\n// ASICREV_IS(eRevisionId, revisionName)\n#define ASICREV_IS(r, rn)              AMDGPU_IN_RANGE(r, AMDGPU_##rn##_RANGE)\n#define ASICREV_IS_TAHITI_P(r)         ASICREV_IS(r, TAHITI)\n#define ASICREV_IS_PITCAIRN_PM(r)      ASICREV_IS(r, PITCAIRN)\n#define ASICREV_IS_CAPEVERDE_M(r)      ASICREV_IS(r, CAPEVERDE)\n#define ASICREV_IS_OLAND_M(r)          ASICREV_IS(r, OLAND)\n#define ASICREV_IS_HAINAN_V(r)         ASICREV_IS(r, HAINAN)\n\n#define ASICREV_IS_BONAIRE_M(r)        ASICREV_IS(r, BONAIRE)\n#define ASICREV_IS_HAWAII_P(r)         ASICREV_IS(r, HAWAII)\n\n#define ASICREV_IS_SPECTRE(r)          ASICREV_IS(r, SPECTRE)\n#define ASICREV_IS_SPOOKY(r)           ASICREV_IS(r, SPOOKY)\n#define ASICREV_IS_KALINDI(r)          ASICREV_IS(r, KALINDI)\n#define ASICREV_IS_KALINDI_GODAVARI(r) ASICREV_IS(r, GODAVARI)\n\n#define ASICREV_IS_ICELAND_M(r)        ASICREV_IS(r, ICELAND)\n#define ASICREV_IS_TONGA_P(r)          ASICREV_IS(r, TONGA)\n#define ASICREV_IS_FIJI_P(r)           ASICREV_IS(r, FIJI)\n\n#define ASICREV_IS_POLARIS10_P(r)      ASICREV_IS(r, POLARIS10)\n#define ASICREV_IS_POLARIS11_M(r)      ASICREV_IS(r, POLARIS11)\n#define ASICREV_IS_POLARIS12_V(r)      ASICREV_IS(r, POLARIS12)\n#define ASICREV_IS_VEGAM_P(r)          ASICREV_IS(r, VEGAM)\n\n#define ASICREV_IS_CARRIZO(r)          ASICREV_IS(r, CARRIZO)\n#define ASICREV_IS_CARRIZO_BRISTOL(r)  ASICREV_IS(r, BRISTOL)\n#define ASICREV_IS_STONEY(r)           ASICREV_IS(r, STONEY)\n\n#define ASICREV_IS_VEGA10_M(r)         ASICREV_IS(r, VEGA10)\n#define ASICREV_IS_VEGA10_P(r)         ASICREV_IS(r, VEGA10)\n#define ASICREV_IS_VEGA12_P(r)         ASICREV_IS(r, VEGA12)\n#define ASICREV_IS_VEGA12_p(r)         ASICREV_IS(r, VEGA12)\n#define ASICREV_IS_VEGA20_P(r)         ASICREV_IS(r, VEGA20)\n\n#define ASICREV_IS_RAVEN(r)            ASICREV_IS(r, RAVEN)\n#define ASICREV_IS_RAVEN2(r)           ASICREV_IS(r, RAVEN2)\n#define ASICREV_IS_RENOIR(r)           ASICREV_IS(r, RENOIR)\n\n#define ASICREV_IS_NAVI10_P(r)         ASICREV_IS(r, NAVI10)\n\n#define ASICREV_IS_NAVI12_P(r)         ASICREV_IS(r, NAVI12)\n\n#define ASICREV_IS_NAVI14_M(r)         ASICREV_IS(r, NAVI14)\n\n#define ASICREV_IS_NAVI21_M(r)         ASICREV_IS(r, NAVI21)\n\n#define ASICREV_IS_NAVI22_P(r)         ASICREV_IS(r, NAVI22)\n\n#define ASICREV_IS_NAVI23_P(r)         ASICREV_IS(r, NAVI23)\n\n#define ASICREV_IS_NAVI24_P(r)         ASICREV_IS(r, NAVI24)\n\n#define ASICREV_IS_VANGOGH(r)          ASICREV_IS(r, VANGOGH)\n\n#define ASICREV_IS_NAVI31_P(r)         ASICREV_IS(r, NAVI31)\n#define ASICREV_IS_NAVI32_P(r)         ASICREV_IS(r, NAVI32)\n#define ASICREV_IS_NAVI33_P(r)         ASICREV_IS(r, NAVI33)\n#define ASICREV_IS_GFX1103_R1(r)       ASICREV_IS(r, GFX1103_R1)\n#define ASICREV_IS_GFX1103_R2(r)       ASICREV_IS(r, GFX1103_R2)\n#define ASICREV_IS_GFX1150(r)          ASICREV_IS(r, GFX1150)\n\n#define ASICREV_IS_REMBRANDT(r)        ASICREV_IS(r, REMBRANDT)\n\n#define ASICREV_IS_RAPHAEL(r)          ASICREV_IS(r, RAPHAEL)\n\n#define ASICREV_IS_MENDOCINO(r)        ASICREV_IS(r, MENDOCINO)\n\n#define ASICREV_IS_GFX12_TBD1_P(r)     ASICREV_IS(r, GFX12_TBD1)\n\n#endif // _AMDGPU_ASIC_ADDR_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/chip/gfx10/gfx10_gb_reg.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#if !defined (__GFX10_GB_REG_H__)\n#define __GFX10_GB_REG_H__\n\n/*\n*    gfx10_gb_reg.h\n*\n*    Register Spec Release:  1.0\n*\n*/\n\n//\n// Make sure the necessary endian defines are there.\n//\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nunion GB_ADDR_CONFIG_GFX10\n{\n    struct\n    {\n#if defined(LITTLEENDIAN_CPU)\n        unsigned int                       NUM_PIPES : 3;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int                       NUM_PKRS  : 3;\n        unsigned int                                 : 21;\n#elif defined(BIGENDIAN_CPU)\n        unsigned int                                 : 21;\n        unsigned int                       NUM_PKRS  : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int                       NUM_PIPES : 3;\n#endif\n    } bitfields, bits;\n    unsigned int    u32All;\n    int             i32All;\n    float           f32All;\n};\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/chip/gfx11/gfx11_gb_reg.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#if !defined (__GFX11_GB_REG_H__)\n#define __GFX11_GB_REG_H__\n\n/*\n*    gfx11_gb_reg.h\n*\n*    Register Spec Release:  1.0\n*\n*/\n\n//\n// Make sure the necessary endian defines are there.\n//\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nunion GB_ADDR_CONFIG_GFX11\n{\n    struct\n    {\n#if defined(LITTLEENDIAN_CPU)\n                unsigned int NUM_PIPES            :  3;\n                unsigned int PIPE_INTERLEAVE_SIZE :  3;\n                unsigned int MAX_COMPRESSED_FRAGS :  2;\n                unsigned int NUM_PKRS             :  3;\n                unsigned int                      :  8;\n                unsigned int NUM_SHADER_ENGINES   :  2;\n                unsigned int                      :  5;\n                unsigned int NUM_RB_PER_SE        :  2;\n                unsigned int                      :  4;\n#elif defined(BIGENDIAN_CPU)\n                unsigned int                      :  4;\n                unsigned int NUM_RB_PER_SE        :  2;\n                unsigned int                      :  5;\n                unsigned int NUM_SHADER_ENGINES   :  2;\n                unsigned int                      :  8;\n                unsigned int NUM_PKRS             :  3;\n                unsigned int MAX_COMPRESSED_FRAGS :  2;\n                unsigned int PIPE_INTERLEAVE_SIZE :  3;\n                unsigned int NUM_PIPES            :  3;\n#endif\n    } bitfields, bits;\n    unsigned int    u32All;\n    int             i32All;\n    float           f32All;\n};\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/chip/gfx12/gfx12_gb_reg.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2023 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#if !defined (__GFX12_GB_REG_H__)\n#define __GFX12_GB_REG_H__\n\n/*\n*    gfx12_gb_reg.h\n*\n*    Register Spec Release:  1.0\n*\n*/\n\n//\n// Make sure the necessary endian defines are there.\n//\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nunion GB_ADDR_CONFIG_GFX12 {\n    struct {\n#if defined(LITTLEENDIAN_CPU)\n        unsigned int                       NUM_PIPES : 3;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int                        NUM_PKRS : 3;\n        unsigned int                                 : 8;\n        unsigned int              NUM_SHADER_ENGINES : 4;\n        unsigned int                                 : 3;\n        unsigned int                   NUM_RB_PER_SE : 2;\n        unsigned int                                 : 4;\n#elif defined(BIGENDIAN_CPU)\n        unsigned int                                 : 4;\n        unsigned int                   NUM_RB_PER_SE : 2;\n        unsigned int                                 : 3;\n        unsigned int              NUM_SHADER_ENGINES : 4;\n        unsigned int                                 : 8;\n        unsigned int                        NUM_PKRS : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int                       NUM_PIPES : 3;\n#endif\n    } bitfields, bits;\n    unsigned int    u32All;\n    int             i32All;\n    float           f32All;\n};\n\n#endif"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/chip/gfx9/gfx9_gb_reg.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#if !defined (__GFX9_GB_REG_H__)\n#define __GFX9_GB_REG_H__\n\n/*\n*    gfx9_gb_reg.h\n*\n*    Register Spec Release:  1.0\n*\n*/\n\n//\n// Make sure the necessary endian defines are there.\n//\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nunion GB_ADDR_CONFIG_GFX9 {\n    struct {\n#if        defined(LITTLEENDIAN_CPU)\n        unsigned int                       NUM_PIPES : 3;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int            BANK_INTERLEAVE_SIZE : 3;\n        unsigned int                                 : 1;\n        unsigned int                       NUM_BANKS : 3;\n        unsigned int                                 : 1;\n        unsigned int         SHADER_ENGINE_TILE_SIZE : 3;\n        unsigned int              NUM_SHADER_ENGINES : 2;\n        unsigned int                        NUM_GPUS : 3;\n        unsigned int             MULTI_GPU_TILE_SIZE : 2;\n        unsigned int                   NUM_RB_PER_SE : 2;\n        unsigned int                        ROW_SIZE : 2;\n        unsigned int                 NUM_LOWER_PIPES : 1;\n        unsigned int                       SE_ENABLE : 1;\n#elif        defined(BIGENDIAN_CPU)\n        unsigned int                       SE_ENABLE : 1;\n        unsigned int                 NUM_LOWER_PIPES : 1;\n        unsigned int                        ROW_SIZE : 2;\n        unsigned int                   NUM_RB_PER_SE : 2;\n        unsigned int             MULTI_GPU_TILE_SIZE : 2;\n        unsigned int                        NUM_GPUS : 3;\n        unsigned int              NUM_SHADER_ENGINES : 2;\n        unsigned int         SHADER_ENGINE_TILE_SIZE : 3;\n        unsigned int                                 : 1;\n        unsigned int                       NUM_BANKS : 3;\n        unsigned int                                 : 1;\n        unsigned int            BANK_INTERLEAVE_SIZE : 3;\n        unsigned int            MAX_COMPRESSED_FRAGS : 2;\n        unsigned int            PIPE_INTERLEAVE_SIZE : 3;\n        unsigned int                       NUM_PIPES : 3;\n#endif\n    } bitfields, bits;\n    unsigned int    u32All;\n    signed int    i32All;\n    float    f32All;\n};\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/chip/r800/si_gb_reg.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n#if !defined (__SI_GB_REG_H__)\n#define __SI_GB_REG_H__\n\n/*****************************************************************************************************************\n *\n *  si_gb_reg.h\n *\n *  Register Spec Release:  Chip Spec 0.28\n *\n *****************************************************************************************************************/\n\n//\n// Make sure the necessary endian defines are there.\n//\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\n/*\n * GB_ADDR_CONFIG struct\n */\n\n#if     defined(LITTLEENDIAN_CPU)\n\n     typedef struct _GB_ADDR_CONFIG_T {\n          unsigned int num_pipes                      : 3;\n          unsigned int                                : 1;\n          unsigned int pipe_interleave_size           : 3;\n          unsigned int                                : 1;\n          unsigned int bank_interleave_size           : 3;\n          unsigned int                                : 1;\n          unsigned int num_shader_engines             : 2;\n          unsigned int                                : 2;\n          unsigned int shader_engine_tile_size        : 3;\n          unsigned int                                : 1;\n          unsigned int num_gpus                       : 3;\n          unsigned int                                : 1;\n          unsigned int multi_gpu_tile_size            : 2;\n          unsigned int                                : 2;\n          unsigned int row_size                       : 2;\n          unsigned int num_lower_pipes                : 1;\n          unsigned int                                : 1;\n     } GB_ADDR_CONFIG_T;\n\n#elif       defined(BIGENDIAN_CPU)\n\n     typedef struct _GB_ADDR_CONFIG_T {\n          unsigned int                                : 1;\n          unsigned int num_lower_pipes                : 1;\n          unsigned int row_size                       : 2;\n          unsigned int                                : 2;\n          unsigned int multi_gpu_tile_size            : 2;\n          unsigned int                                : 1;\n          unsigned int num_gpus                       : 3;\n          unsigned int                                : 1;\n          unsigned int shader_engine_tile_size        : 3;\n          unsigned int                                : 2;\n          unsigned int num_shader_engines             : 2;\n          unsigned int                                : 1;\n          unsigned int bank_interleave_size           : 3;\n          unsigned int                                : 1;\n          unsigned int pipe_interleave_size           : 3;\n          unsigned int                                : 1;\n          unsigned int num_pipes                      : 3;\n     } GB_ADDR_CONFIG_T;\n\n#endif\n\n#if     defined(LITTLEENDIAN_CPU)\n\n     typedef struct _GB_ADDR_CONFIG_N {\n          unsigned int num_pipes                      : 3;\n          unsigned int pipe_interleave_size           : 3;\n          unsigned int max_compressed_frags           : 2;\n          unsigned int bank_interleave_size           : 3;\n          unsigned int                                : 1;\n          unsigned int num_banks                      : 3;\n          unsigned int                                : 1;\n          unsigned int shader_engine_tile_size        : 3;\n          unsigned int num_shader_engines             : 2;\n          unsigned int num_gpus                       : 3;\n          unsigned int multi_gpu_tile_size            : 2;\n          unsigned int num_rb_per_se                  : 2;\n          unsigned int row_size                       : 2;\n          unsigned int num_lower_pipes                : 1;\n          unsigned int se_enable                      : 1;\n     } GB_ADDR_CONFIG_N;\n\n#elif       defined(BIGENDIAN_CPU)\n\n     typedef struct _GB_ADDR_CONFIG_N {\n          unsigned int se_enable                      : 1;\n          unsigned int num_lower_pipes                : 1;\n          unsigned int row_size                       : 2;\n          unsigned int num_rb_per_se                  : 2;\n          unsigned int multi_gpu_tile_size            : 2;\n          unsigned int num_gpus                       : 3;\n          unsigned int num_shader_engines             : 2;\n          unsigned int shader_engine_tile_size        : 3;\n          unsigned int                                : 1;\n          unsigned int num_banks                      : 3;\n          unsigned int                                : 1;\n          unsigned int bank_interleave_size           : 3;\n          unsigned int max_compressed_frags           : 2;\n          unsigned int pipe_interleave_size           : 3;\n          unsigned int num_pipes                      : 3;\n     } GB_ADDR_CONFIG_N;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     GB_ADDR_CONFIG_T f;\n     GB_ADDR_CONFIG_N n;\n} GB_ADDR_CONFIG;\n\n#if       defined(LITTLEENDIAN_CPU)\n\n     typedef struct _GB_TILE_MODE_T {\n          unsigned int micro_tile_mode                : 2;\n          unsigned int array_mode                     : 4;\n          unsigned int pipe_config                    : 5;\n          unsigned int tile_split                     : 3;\n          unsigned int bank_width                     : 2;\n          unsigned int bank_height                    : 2;\n          unsigned int macro_tile_aspect              : 2;\n          unsigned int num_banks                      : 2;\n          unsigned int micro_tile_mode_new            : 3;\n          unsigned int sample_split                   : 2;\n          unsigned int alt_pipe_config                : 5;\n     } GB_TILE_MODE_T;\n\n     typedef struct _GB_MACROTILE_MODE_T {\n          unsigned int bank_width                     : 2;\n          unsigned int bank_height                    : 2;\n          unsigned int macro_tile_aspect              : 2;\n          unsigned int num_banks                      : 2;\n          unsigned int alt_bank_height                : 2;\n          unsigned int alt_macro_tile_aspect          : 2;\n          unsigned int alt_num_banks                  : 2;\n          unsigned int                                : 18;\n     } GB_MACROTILE_MODE_T;\n\n#elif          defined(BIGENDIAN_CPU)\n\n     typedef struct _GB_TILE_MODE_T {\n          unsigned int alt_pipe_config                : 5;\n          unsigned int sample_split                   : 2;\n          unsigned int micro_tile_mode_new            : 3;\n          unsigned int num_banks                      : 2;\n          unsigned int macro_tile_aspect              : 2;\n          unsigned int bank_height                    : 2;\n          unsigned int bank_width                     : 2;\n          unsigned int tile_split                     : 3;\n          unsigned int pipe_config                    : 5;\n          unsigned int array_mode                     : 4;\n          unsigned int micro_tile_mode                : 2;\n     } GB_TILE_MODE_T;\n\n     typedef struct _GB_MACROTILE_MODE_T {\n          unsigned int                                : 18;\n          unsigned int alt_num_banks                  : 2;\n          unsigned int alt_macro_tile_aspect          : 2;\n          unsigned int alt_bank_height                : 2;\n          unsigned int num_banks                      : 2;\n          unsigned int macro_tile_aspect              : 2;\n          unsigned int bank_height                    : 2;\n          unsigned int bank_width                     : 2;\n     } GB_MACROTILE_MODE_T;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     GB_TILE_MODE_T f;\n} GB_TILE_MODE;\n\ntypedef union {\n     unsigned int val : 32;\n     GB_MACROTILE_MODE_T f;\n} GB_MACROTILE_MODE;\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrcommon.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrcommon.h\n* @brief Contains the helper function and constants.\n****************************************************************************************************\n*/\n\n#ifndef __ADDR_COMMON_H__\n#define __ADDR_COMMON_H__\n\n#include \"addrinterface.h\"\n\n\n#if !defined(__APPLE__) || defined(HAVE_TSERVER)\n    #include <stdlib.h>\n    #include <string.h>\n#endif\n\n#if defined(__GNUC__)\n    #include <signal.h>\n    #include <assert.h>\n#endif\n\n#if defined(_WIN32)\n#include <intrin.h>\n#endif\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Platform specific debug break defines\n////////////////////////////////////////////////////////////////////////////////////////////////////\n#if !defined(DEBUG)\n    #ifdef NDEBUG\n        #define DEBUG 0\n    #else\n        #define DEBUG 1\n    #endif\n#endif\n\n#if DEBUG\n    #if defined(__GNUC__)\n        #define ADDR_DBG_BREAK()    { assert(false); }\n    #elif defined(__APPLE__)\n        #define ADDR_DBG_BREAK()    { IOPanic(\"\");}\n    #else\n        #define ADDR_DBG_BREAK()    { __debugbreak(); }\n    #endif\n#else\n    #define ADDR_DBG_BREAK()\n#endif\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Debug assertions used in AddrLib\n////////////////////////////////////////////////////////////////////////////////////////////////////\n#if defined(_WIN32) && (_MSC_VER >= 1400)\n    #define ADDR_ANALYSIS_ASSUME(expr) __analysis_assume(expr)\n#else\n    #define ADDR_ANALYSIS_ASSUME(expr) do { (void)(expr); } while (0)\n#endif\n\n#if DEBUG\n    #if defined( _WIN32 )\n        #define ADDR_ASSERT(__e)                                \\\n        {                                                       \\\n            ADDR_ANALYSIS_ASSUME(__e);                          \\\n            if ( !((__e) ? TRUE : FALSE)) { ADDR_DBG_BREAK(); } \\\n        }\n    #else\n        #define ADDR_ASSERT(__e) if ( !((__e) ? TRUE : FALSE)) { ADDR_DBG_BREAK(); }\n    #endif\n\n    #if ADDR_SILENCE_ASSERT_ALWAYS\n        #define ADDR_ASSERT_ALWAYS()\n    #else\n        #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK()\n    #endif\n\n    #define ADDR_UNHANDLED_CASE() ADDR_ASSERT(!\"Unhandled case\")\n    #define ADDR_NOT_IMPLEMENTED() ADDR_ASSERT(!\"Not implemented\");\n#else //DEBUG\n    #if defined( _WIN32 )\n        #define ADDR_ASSERT(__e) { ADDR_ANALYSIS_ASSUME(__e); }\n    #else\n        #define ADDR_ASSERT(__e)\n    #endif\n    #define ADDR_ASSERT_ALWAYS()\n    #define ADDR_UNHANDLED_CASE()\n    #define ADDR_NOT_IMPLEMENTED()\n#endif //DEBUG\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Debug print macro from legacy address library\n////////////////////////////////////////////////////////////////////////////////////////////////////\n#if DEBUG\n\n#define ADDR_PRNT(a)    Object::DebugPrint a\n\n/// @brief Macro for reporting informational messages\n/// @ingroup util\n///\n/// This macro optionally prints an informational message to stdout.\n/// The first parameter is a condition -- if it is true, nothing is done.\n/// The second pararmeter MUST be a parenthesis-enclosed list of arguments,\n/// starting with a string. This is passed to printf() or an equivalent\n/// in order to format the informational message. For example,\n/// ADDR_INFO(0, (\"test %d\",3) ); prints out \"test 3\".\n///\n#define ADDR_INFO(cond, a)         \\\n{ if (!(cond)) { ADDR_PRNT(a); } }\n\n\n/// @brief Macro for reporting error warning messages\n/// @ingroup util\n///\n/// This macro optionally prints an error warning message to stdout,\n/// followed by the file name and line number where the macro was called.\n/// The first parameter is a condition -- if it is true, nothing is done.\n/// The second pararmeter MUST be a parenthesis-enclosed list of arguments,\n/// starting with a string. This is passed to printf() or an equivalent\n/// in order to format the informational message. For example,\n/// ADDR_WARN(0, (\"test %d\",3) ); prints out \"test 3\" followed by\n/// a second line with the file name and line number.\n///\n#define ADDR_WARN(cond, a)         \\\n{ if (!(cond))                     \\\n  { ADDR_PRNT(a);                  \\\n    ADDR_PRNT((\"  WARNING in file %s, line %d\\n\", __FILE__, __LINE__)); \\\n} }\n\n\n/// @brief Macro for reporting fatal error conditions\n/// @ingroup util\n///\n/// This macro optionally stops execution of the current routine\n/// after printing an error warning message to stdout,\n/// followed by the file name and line number where the macro was called.\n/// The first parameter is a condition -- if it is true, nothing is done.\n/// The second pararmeter MUST be a parenthesis-enclosed list of arguments,\n/// starting with a string. This is passed to printf() or an equivalent\n/// in order to format the informational message. For example,\n/// ADDR_EXIT(0, (\"test %d\",3) ); prints out \"test 3\" followed by\n/// a second line with the file name and line number, then stops execution.\n///\n#define ADDR_EXIT(cond, a)         \\\n{ if (!(cond))                     \\\n  { ADDR_PRNT(a); ADDR_DBG_BREAK();\\\n} }\n\n#else // DEBUG\n\n#define ADDRDPF 1 ? (void)0 : (void)\n\n#define ADDR_PRNT(a)\n\n#define ADDR_DBG_BREAK()\n\n#define ADDR_INFO(cond, a)\n\n#define ADDR_WARN(cond, a)\n\n#define ADDR_EXIT(cond, a)\n\n#endif // DEBUG\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n#if defined(static_assert)\n#define ADDR_C_ASSERT(__e) static_assert(__e, \"\")\n#else\n   /* This version of STATIC_ASSERT() relies on VLAs.  If COND is\n    * false/zero, the array size will be -1 and we'll get a compile\n    * error\n    */\n#  define ADDR_C_ASSERT(__e) do {         \\\n      (void) sizeof(char [1 - 2*!(__e)]); \\\n   } while (0)\n#endif\n\nnamespace rocr {\nnamespace Addr\n{\n\nnamespace V1\n{\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Common constants\n////////////////////////////////////////////////////////////////////////////////////////////////////\nstatic const UINT_32 MicroTileWidth      = 8;       ///< Micro tile width, for 1D and 2D tiling\nstatic const UINT_32 MicroTileHeight     = 8;       ///< Micro tile height, for 1D and 2D tiling\nstatic const UINT_32 ThickTileThickness  = 4;       ///< Micro tile thickness, for THICK modes\nstatic const UINT_32 XThickTileThickness = 8;       ///< Extra thick tiling thickness\nstatic const UINT_32 PowerSaveTileBytes  = 64;      ///< Nuber of bytes per tile for power save 64\nstatic const UINT_32 CmaskCacheBits      = 1024;    ///< Number of bits for CMASK cache\nstatic const UINT_32 CmaskElemBits       = 4;       ///< Number of bits for CMASK element\nstatic const UINT_32 HtileCacheBits      = 16384;   ///< Number of bits for HTILE cache 512*32\n\nstatic const UINT_32 MicroTilePixels     = MicroTileWidth * MicroTileHeight;\n\nstatic const INT_32 TileIndexInvalid        = TILEINDEX_INVALID;\nstatic const INT_32 TileIndexLinearGeneral  = TILEINDEX_LINEAR_GENERAL;\nstatic const INT_32 TileIndexNoMacroIndex   = -3;\n\n} // V1\n\nnamespace V2\n{\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Common constants\n////////////////////////////////////////////////////////////////////////////////////////////////////\nstatic const UINT_32 MaxSurfaceHeight = 16384;\n\n} // V2\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Common macros\n////////////////////////////////////////////////////////////////////////////////////////////////////\n#define BITS_PER_BYTE 8\n#define BITS_TO_BYTES(x) ( ((x) + (BITS_PER_BYTE-1)) / BITS_PER_BYTE )\n#define BYTES_TO_BITS(x) ( (x) * BITS_PER_BYTE )\n\n/// Helper macros to select a single bit from an int (undefined later in section)\n#define _BIT(v,b)      (((v) >> (b) ) & 1)\n\n/**\n****************************************************************************************************\n* ChipFamily\n*\n*   @brief\n*       Neutral enums that specifies chip family.\n*\n****************************************************************************************************\n*/\nenum ChipFamily\n{\n    ADDR_CHIP_FAMILY_IVLD,    ///< Invalid family\n    ADDR_CHIP_FAMILY_R6XX,\n    ADDR_CHIP_FAMILY_R7XX,\n    ADDR_CHIP_FAMILY_R8XX,\n    ADDR_CHIP_FAMILY_NI,\n    ADDR_CHIP_FAMILY_SI,\n    ADDR_CHIP_FAMILY_CI,\n    ADDR_CHIP_FAMILY_VI,\n    ADDR_CHIP_FAMILY_AI,\n    ADDR_CHIP_FAMILY_NAVI,\n};\n\n/**\n****************************************************************************************************\n* ConfigFlags\n*\n*   @brief\n*       This structure is used to set configuration flags.\n****************************************************************************************************\n*/\nunion ConfigFlags\n{\n    struct\n    {\n        /// These flags are set up internally thru AddrLib::Create() based on ADDR_CREATE_FLAGS\n        UINT_32 optimalBankSwap        : 1;    ///< New bank tiling for RV770 only\n        UINT_32 noCubeMipSlicesPad     : 1;    ///< Disables faces padding for cubemap mipmaps\n        UINT_32 fillSizeFields         : 1;    ///< If clients fill size fields in all input and\n                                               ///  output structure\n        UINT_32 ignoreTileInfo         : 1;    ///< Don't use tile info structure\n        UINT_32 useTileIndex           : 1;    ///< Make tileIndex field in input valid\n        UINT_32 useCombinedSwizzle     : 1;    ///< Use combined swizzle\n        UINT_32 checkLast2DLevel       : 1;    ///< Check the last 2D mip sub level\n        UINT_32 useHtileSliceAlign     : 1;    ///< Do htile single slice alignment\n        UINT_32 allowLargeThickTile    : 1;    ///< Allow 64*thickness*bytesPerPixel > rowSize\n        UINT_32 disableLinearOpt       : 1;    ///< Disallow tile modes to be optimized to linear\n        UINT_32 use32bppFor422Fmt      : 1;    ///< View 422 formats as 32 bits per pixel element\n        UINT_32 forceDccAndTcCompat    : 1;    ///< Force enable DCC and TC compatibility\n        UINT_32 nonPower2MemConfig     : 1;    ///< Video memory bit width is not power of 2\n        UINT_32 enableAltTiling        : 1;    ///< Enable alt tile mode\n        UINT_32 reserved               : 18;   ///< Reserved bits for future use\n    };\n\n    UINT_32 value;\n};\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Misc helper functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   AddrXorReduce\n*\n*   @brief\n*       Xor the right-side numberOfBits bits of x.\n****************************************************************************************************\n*/\nstatic inline UINT_32 XorReduce(\n    UINT_32 x,\n    UINT_32 numberOfBits)\n{\n    UINT_32 i;\n    UINT_32 result = x & 1;\n\n    for (i=1; i<numberOfBits; i++)\n    {\n        result ^= ((x>>i) & 1);\n    }\n\n    return result;\n}\n\n/**\n****************************************************************************************************\n*   Unset least bit\n*\n*   @brief\n*       Returns a copy of the value with the least-significant '1' bit unset\n****************************************************************************************************\n*/\nstatic inline UINT_32 UnsetLeastBit(\n    UINT_32 val)\n{\n    return val & (val - 1);\n}\n\n/**\n****************************************************************************************************\n*   BitScanForward\n*\n*   @brief\n*       Returns the index-position of the least-significant '1' bit. Must not be 0.\n****************************************************************************************************\n*/\nstatic inline UINT_32 BitScanForward(\n    UINT_32 mask) ///< [in] Bitmask to scan\n{\n    ADDR_ASSERT(mask > 0);\n    unsigned long out = 0;\n#if (defined(_WIN64) && defined(_M_X64)) || (defined(_WIN32) && defined(_M_IX64))\n    out = ::_tzcnt_u32(mask);\n#elif (defined(_WIN32) || defined(_WIN64))\n    ::_BitScanForward(&out, mask);\n#elif defined(__GNUC__)\n    out = __builtin_ctz(mask);\n#else\n    while ((mask & 1) == 0)\n    {\n        mask >>= 1;\n        out++;\n    }\n#endif\n    return out;\n}\n\n/**\n****************************************************************************************************\n*   IsPow2\n*\n*   @brief\n*       Check if the size (UINT_32) is pow 2\n****************************************************************************************************\n*/\nstatic inline UINT_32 IsPow2(\n    UINT_32 dim)        ///< [in] dimension of miplevel\n{\n    ADDR_ASSERT(dim > 0);\n    return !(dim & (dim - 1));\n}\n\n/**\n****************************************************************************************************\n*   IsPow2\n*\n*   @brief\n*       Check if the size (UINT_64) is pow 2\n****************************************************************************************************\n*/\nstatic inline UINT_64 IsPow2(\n    UINT_64 dim)        ///< [in] dimension of miplevel\n{\n    ADDR_ASSERT(dim > 0);\n    return !(dim & (dim - 1));\n}\n\n/**\n****************************************************************************************************\n*   ByteAlign\n*\n*   @brief\n*       Align UINT_32 \"x\" to \"align\" alignment, \"align\" should be power of 2\n****************************************************************************************************\n*/\nstatic inline UINT_32 PowTwoAlign(\n    UINT_32 x,\n    UINT_32 align)\n{\n    //\n    // Assert that x is a power of two.\n    //\n    ADDR_ASSERT(IsPow2(align));\n    return (x + (align - 1)) & (~(align - 1));\n}\n\n/**\n****************************************************************************************************\n*   ByteAlign\n*\n*   @brief\n*       Align UINT_64 \"x\" to \"align\" alignment, \"align\" should be power of 2\n****************************************************************************************************\n*/\nstatic inline UINT_64 PowTwoAlign(\n    UINT_64 x,\n    UINT_64 align)\n{\n    //\n    // Assert that x is a power of two.\n    //\n    ADDR_ASSERT(IsPow2(align));\n    return (x + (align - 1)) & (~(align - 1));\n}\n\n/**\n****************************************************************************************************\n*   Min\n*\n*   @brief\n*       Get the min value between two unsigned values\n****************************************************************************************************\n*/\nstatic inline UINT_32 Min(\n    UINT_32 value1,\n    UINT_32 value2)\n{\n    return ((value1 < (value2)) ? (value1) : value2);\n}\n\n/**\n****************************************************************************************************\n*   Min\n*\n*   @brief\n*       Get the min value between two signed values\n****************************************************************************************************\n*/\nstatic inline INT_32 Min(\n    INT_32 value1,\n    INT_32 value2)\n{\n    return ((value1 < (value2)) ? (value1) : value2);\n}\n\n/**\n****************************************************************************************************\n*   Max\n*\n*   @brief\n*       Get the max value between two unsigned values\n****************************************************************************************************\n*/\nstatic inline UINT_32 Max(\n    UINT_32 value1,\n    UINT_32 value2)\n{\n    return ((value1 > (value2)) ? (value1) : value2);\n}\n\n/**\n****************************************************************************************************\n*   Max\n*\n*   @brief\n*       Get the max value between two signed values\n****************************************************************************************************\n*/\nstatic inline INT_32 Max(\n    INT_32 value1,\n    INT_32 value2)\n{\n    return ((value1 > (value2)) ? (value1) : value2);\n}\n\n/**\n****************************************************************************************************\n*   RoundUpQuotient\n*\n*   @brief\n*       Divides two numbers, rounding up any remainder.\n****************************************************************************************************\n*/\nstatic inline UINT_32 RoundUpQuotient(\n    UINT_32 numerator,\n    UINT_32 denominator)\n{\n    ADDR_ASSERT(denominator > 0);\n    return ((numerator + (denominator - 1)) / denominator);\n}\n\n/**\n****************************************************************************************************\n*   RoundUpQuotient\n*\n*   @brief\n*       Divides two numbers, rounding up any remainder.\n****************************************************************************************************\n*/\nstatic inline UINT_64 RoundUpQuotient(\n    UINT_64 numerator,\n    UINT_64 denominator)\n{\n    ADDR_ASSERT(denominator > 0);\n    return ((numerator + (denominator - 1)) / denominator);\n}\n\n/**\n****************************************************************************************************\n*   NextPow2\n*\n*   @brief\n*       Compute the mipmap's next level dim size\n****************************************************************************************************\n*/\nstatic inline UINT_32 NextPow2(\n    UINT_32 dim)        ///< [in] dimension of miplevel\n{\n    UINT_32 newDim = 1;\n\n    if (dim > 0x7fffffff)\n    {\n        ADDR_ASSERT_ALWAYS();\n        newDim = 0x80000000;\n    }\n    else\n    {\n        while (newDim < dim)\n        {\n            newDim <<= 1;\n        }\n    }\n\n    return newDim;\n}\n\n/**\n****************************************************************************************************\n*   Log2NonPow2\n*\n*   @brief\n*       Compute log of base 2 no matter the target is power of 2 or not\n****************************************************************************************************\n*/\nstatic inline UINT_32 Log2NonPow2(\n    UINT_32 x)      ///< [in] the value should calculate log based 2\n{\n    UINT_32 y;\n\n    y = 0;\n    while (x > 1)\n    {\n        x >>= 1;\n        y++;\n    }\n\n    return y;\n}\n\n/**\n****************************************************************************************************\n*   Log2\n*\n*   @brief\n*       Compute log of base 2\n****************************************************************************************************\n*/\nstatic inline UINT_32 Log2(\n    UINT_32 x)      ///< [in] the value should calculate log based 2\n{\n    // Assert that x is a power of two.\n    ADDR_ASSERT(IsPow2(x));\n\n    return Log2NonPow2(x);\n}\n\n/**\n****************************************************************************************************\n*   QLog2\n*\n*   @brief\n*       Compute log of base 2 quickly (<= 16)\n****************************************************************************************************\n*/\nstatic inline UINT_32 QLog2(\n    UINT_32 x)      ///< [in] the value should calculate log based 2\n{\n    ADDR_ASSERT(x <= 16);\n\n    UINT_32 y = 0;\n\n    switch (x)\n    {\n        case 1:\n            y = 0;\n            break;\n        case 2:\n            y = 1;\n            break;\n        case 4:\n            y = 2;\n            break;\n        case 8:\n            y = 3;\n            break;\n        case 16:\n            y = 4;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n    }\n\n    return y;\n}\n\n/**\n****************************************************************************************************\n*   SafeAssign\n*\n*   @brief\n*       NULL pointer safe assignment\n****************************************************************************************************\n*/\nstatic inline VOID SafeAssign(\n    UINT_32*    pLVal,  ///< [in] Pointer to left val\n    UINT_32     rVal)   ///< [in] Right value\n{\n    if (pLVal)\n    {\n        *pLVal = rVal;\n    }\n}\n\n/**\n****************************************************************************************************\n*   SafeAssign\n*\n*   @brief\n*       NULL pointer safe assignment for 64bit values\n****************************************************************************************************\n*/\nstatic inline VOID SafeAssign(\n    UINT_64*    pLVal,  ///< [in] Pointer to left val\n    UINT_64     rVal)   ///< [in] Right value\n{\n    if (pLVal)\n    {\n        *pLVal = rVal;\n    }\n}\n\n/**\n****************************************************************************************************\n*   SafeAssign\n*\n*   @brief\n*       NULL pointer safe assignment for AddrTileMode\n****************************************************************************************************\n*/\nstatic inline VOID SafeAssign(\n    AddrTileMode*    pLVal, ///< [in] Pointer to left val\n    AddrTileMode     rVal)  ///< [in] Right value\n{\n    if (pLVal)\n    {\n        *pLVal = rVal;\n    }\n}\n\n/**\n****************************************************************************************************\n*   RoundHalf\n*\n*   @brief\n*       return (x + 1) / 2\n****************************************************************************************************\n*/\nstatic inline UINT_32 RoundHalf(\n    UINT_32     x)     ///< [in] input value\n{\n    ADDR_ASSERT(x != 0);\n\n#if 1\n    return (x >> 1) + (x & 1);\n#else\n    return (x + 1) >> 1;\n#endif\n}\n\n/**\n****************************************************************************************************\n*   SumGeo\n*\n*   @brief\n*       Calculate sum of a geometric progression whose ratio is 1/2\n****************************************************************************************************\n*/\nstatic inline UINT_32 SumGeo(\n    UINT_32     base,   ///< [in] First term in the geometric progression\n    UINT_32     num)    ///< [in] Number of terms to be added into sum\n{\n    ADDR_ASSERT(base > 0);\n\n    UINT_32 sum = 0;\n    UINT_32 i = 0;\n    for (; (i < num) && (base > 1); i++)\n    {\n        sum += base;\n        base = RoundHalf(base);\n    }\n    sum += num - i;\n\n    return sum;\n}\n\n/**\n****************************************************************************************************\n*   GetBit\n*\n*   @brief\n*       Extract bit N value (0 or 1) of a UINT32 value.\n****************************************************************************************************\n*/\nstatic inline UINT_32 GetBit(\n    UINT_32     u32,   ///< [in] UINT32 value\n    UINT_32     pos)   ///< [in] bit position from LSB, valid range is [0..31]\n{\n    ADDR_ASSERT(pos <= 31);\n\n    return (u32 >> pos) & 0x1;\n}\n\n/**\n****************************************************************************************************\n*   GetBits\n*\n*   @brief\n*       Copy 'bitsNum' bits from src start from srcStartPos into destination from dstStartPos\n*       srcStartPos: 0~31 for UINT_32\n*       bitsNum    : 1~32 for UINT_32\n*       srcStartPos: 0~31 for UINT_32\n*                                                                 src start position\n*                                                                          |\n*       src : b[31] b[30] b[29] ... ... ... ... ... ... ... ... b[end]..b[beg] ... b[1] b[0]\n*                                   || Bits num || copy length  || Bits num ||\n*       dst : b[31] b[30] b[29] ... b[end]..b[beg] ... ... ... ... ... ... ... ... b[1] b[0]\n*                                              |\n*                                     dst start position\n****************************************************************************************************\n*/\nstatic inline UINT_32 GetBits(\n    UINT_32 src,\n    UINT_32 srcStartPos,\n    UINT_32 bitsNum,\n    UINT_32 dstStartPos)\n{\n    ADDR_ASSERT((srcStartPos < 32) && (dstStartPos < 32) && (bitsNum > 0));\n    ADDR_ASSERT((bitsNum + dstStartPos <= 32) && (bitsNum + srcStartPos <= 32));\n\n    return ((src >> srcStartPos) << (32 - bitsNum)) >> (32 - bitsNum - dstStartPos);\n}\n\n/**\n****************************************************************************************************\n*   MortonGen2d\n*\n*   @brief\n*       Generate 2D Morton interleave code with num lowest bits in each channel\n****************************************************************************************************\n*/\nstatic inline UINT_32 MortonGen2d(\n    UINT_32     x,     ///< [in] First channel\n    UINT_32     y,     ///< [in] Second channel\n    UINT_32     num)   ///< [in] Number of bits extracted from each channel\n{\n    UINT_32 mort = 0;\n\n    for (UINT_32 i = 0; i < num; i++)\n    {\n        mort |= (GetBit(y, i) << (2 * i));\n        mort |= (GetBit(x, i) << (2 * i + 1));\n    }\n\n    return mort;\n}\n\n/**\n****************************************************************************************************\n*   MortonGen3d\n*\n*   @brief\n*       Generate 3D Morton interleave code with num lowest bits in each channel\n****************************************************************************************************\n*/\nstatic inline UINT_32 MortonGen3d(\n    UINT_32     x,     ///< [in] First channel\n    UINT_32     y,     ///< [in] Second channel\n    UINT_32     z,     ///< [in] Third channel\n    UINT_32     num)   ///< [in] Number of bits extracted from each channel\n{\n    UINT_32 mort = 0;\n\n    for (UINT_32 i = 0; i < num; i++)\n    {\n        mort |= (GetBit(z, i) << (3 * i));\n        mort |= (GetBit(y, i) << (3 * i + 1));\n        mort |= (GetBit(x, i) << (3 * i + 2));\n    }\n\n    return mort;\n}\n\n/**\n****************************************************************************************************\n*   ReverseBitVector\n*\n*   @brief\n*       Return reversed lowest num bits of v: v[0]v[1]...v[num-2]v[num-1]\n****************************************************************************************************\n*/\nstatic inline UINT_32 ReverseBitVector(\n    UINT_32     v,     ///< [in] Reverse operation base value\n    UINT_32     num)   ///< [in] Number of bits used in reverse operation\n{\n    UINT_32 reverse = 0;\n\n    for (UINT_32 i = 0; i < num; i++)\n    {\n        reverse |= (GetBit(v, num - 1 - i) << i);\n    }\n\n    return reverse;\n}\n\n/**\n****************************************************************************************************\n*   FoldXor2d\n*\n*   @brief\n*       Xor bit vector v[num-1]v[num-2]...v[1]v[0] with v[num]v[num+1]...v[2*num-2]v[2*num-1]\n****************************************************************************************************\n*/\nstatic inline UINT_32 FoldXor2d(\n    UINT_32     v,     ///< [in] Xor operation base value\n    UINT_32     num)   ///< [in] Number of bits used in fold xor operation\n{\n    return (v & ((1 << num) - 1)) ^ ReverseBitVector(v >> num, num);\n}\n\n/**\n****************************************************************************************************\n*   DeMort\n*\n*   @brief\n*       Return v[0] | v[2] | v[4] | v[6]... | v[2*num - 2]\n****************************************************************************************************\n*/\nstatic inline UINT_32 DeMort(\n    UINT_32     v,     ///< [in] DeMort operation base value\n    UINT_32     num)   ///< [in] Number of bits used in fold DeMort operation\n{\n    UINT_32 d = 0;\n\n    for (UINT_32 i = 0; i < num; i++)\n    {\n        d |= ((v & (1 << (i << 1))) >> i);\n    }\n\n    return d;\n}\n\n/**\n****************************************************************************************************\n*   FoldXor3d\n*\n*   @brief\n*       v[0]...v[num-1] ^ v[3*num-1]v[3*num-3]...v[num+2]v[num] ^ v[3*num-2]...v[num+1]v[num-1]\n****************************************************************************************************\n*/\nstatic inline UINT_32 FoldXor3d(\n    UINT_32     v,     ///< [in] Xor operation base value\n    UINT_32     num)   ///< [in] Number of bits used in fold xor operation\n{\n    UINT_32 t = v & ((1 << num) - 1);\n    t ^= ReverseBitVector(DeMort(v >> num, num), num);\n    t ^= ReverseBitVector(DeMort(v >> (num + 1), num), num);\n\n    return t;\n}\n\n/**\n****************************************************************************************************\n*   InitChannel\n*\n*   @brief\n*       Set channel initialization value via a return value\n****************************************************************************************************\n*/\nstatic inline ADDR_CHANNEL_SETTING InitChannel(\n    UINT_32     valid,     ///< [in] valid setting\n    UINT_32     channel,   ///< [in] channel setting\n    UINT_32     index)     ///< [in] index setting\n{\n    ADDR_CHANNEL_SETTING t;\n    t.valid = valid;\n    t.channel = channel;\n    t.index = index;\n\n    return t;\n}\n\n/**\n****************************************************************************************************\n*   InitChannel\n*\n*   @brief\n*       Set channel initialization value via channel pointer\n****************************************************************************************************\n*/\nstatic inline VOID InitChannel(\n    UINT_32     valid,              ///< [in] valid setting\n    UINT_32     channel,            ///< [in] channel setting\n    UINT_32     index,              ///< [in] index setting\n    ADDR_CHANNEL_SETTING *pChanSet) ///< [out] channel setting to be initialized\n{\n    pChanSet->valid = valid;\n    pChanSet->channel = channel;\n    pChanSet->index = index;\n}\n\n\n/**\n****************************************************************************************************\n*   InitChannel\n*\n*   @brief\n*       Set channel initialization value via another channel\n****************************************************************************************************\n*/\nstatic inline VOID InitChannel(\n    ADDR_CHANNEL_SETTING *pChanDst, ///< [in] channel setting to be copied from\n    ADDR_CHANNEL_SETTING *pChanSrc) ///< [out] channel setting to be initialized\n{\n    pChanDst->valid = pChanSrc->valid;\n    pChanDst->channel = pChanSrc->channel;\n    pChanDst->index = pChanSrc->index;\n}\n\n/**\n****************************************************************************************************\n*   GetMaxValidChannelIndex\n*\n*   @brief\n*       Get max valid index for a specific channel\n****************************************************************************************************\n*/\nstatic inline UINT_32 GetMaxValidChannelIndex(\n    const ADDR_CHANNEL_SETTING *pChanSet,   ///< [in] channel setting to be initialized\n    UINT_32                     searchCount,///< [in] number of channel setting to be searched\n    UINT_32                     channel)    ///< [in] channel to be searched\n{\n    UINT_32 index = 0;\n\n    for (UINT_32 i = 0; i < searchCount; i++)\n    {\n        if (pChanSet[i].valid && (pChanSet[i].channel == channel))\n        {\n            index = Max(index, static_cast<UINT_32>(pChanSet[i].index));\n        }\n    }\n\n    return index;\n}\n\n/**\n****************************************************************************************************\n*   GetCoordActiveMask\n*\n*   @brief\n*       Get bit mask which indicates which positions in the equation match the target coord\n****************************************************************************************************\n*/\nstatic inline UINT_32 GetCoordActiveMask(\n    const ADDR_CHANNEL_SETTING *pChanSet,   ///< [in] channel setting to be initialized\n    UINT_32                     searchCount,///< [in] number of channel setting to be searched\n    UINT_32                     channel,    ///< [in] channel to be searched\n    UINT_32                     index)      ///< [in] index to be searched\n{\n    UINT_32 mask = 0;\n\n    for (UINT_32 i = 0; i < searchCount; i++)\n    {\n        if ((pChanSet[i].valid   == TRUE)    &&\n            (pChanSet[i].channel == channel) &&\n            (pChanSet[i].index   == index))\n        {\n            mask |= (1 << i);\n        }\n    }\n\n    return mask;\n}\n\n/**\n****************************************************************************************************\n*   FillEqBitComponents\n*\n*   @brief\n*       Fill the 'numBitComponents' field based on the equation.\n****************************************************************************************************\n*/\nstatic inline void FillEqBitComponents(\n    ADDR_EQUATION *pEquation) // [in,out] Equation to calculate bit components for\n{\n    pEquation->numBitComponents = 1; // We always have at least the address\n    for (UINT_32 xorN = 1; xorN < ADDR_MAX_EQUATION_COMP; xorN++)\n    {\n        for (UINT_32 bit = 0; bit < ADDR_MAX_EQUATION_BIT; bit++)\n        {\n            if (pEquation->comps[xorN][bit].valid)\n            {\n                pEquation->numBitComponents = xorN + 1;\n                break;\n            }\n        }\n\n        if (pEquation->numBitComponents != (xorN + 1))\n        {\n            // Skip following components if this one wasn't valid\n            break;\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   ShiftCeil\n*\n*   @brief\n*       Apply right-shift with ceiling\n****************************************************************************************************\n*/\nstatic inline UINT_32 ShiftCeil(\n    UINT_32 a,  ///< [in] value to be right-shifted\n    UINT_32 b)  ///< [in] number of bits to shift\n{\n    return (a >> b) + (((a & ((1 << b) - 1)) != 0) ? 1 : 0);\n}\n\n/**\n****************************************************************************************************\n*   ShiftRight\n*\n*   @brief\n*       Return right-shift value and minimum is 1\n****************************************************************************************************\n*/\nstatic inline UINT_32 ShiftRight(\n    UINT_32 a,  ///< [in] value to be right-shifted\n    UINT_32 b)  ///< [in] number of bits to shift\n{\n    return Max(a >> b, 1u);\n}\n\n} // Addr\n} // namespace rocr\n\n#endif // __ADDR_COMMON_H__\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrelemlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrelemlib.cpp\n* @brief Contains the class implementation for element/pixel related functions.\n****************************************************************************************************\n*/\n\n#include \"addrelemlib.h\"\n#include \"addrlib.h\"\n\nnamespace rocr {\nnamespace Addr\n{\n\n/**\n****************************************************************************************************\n*   ElemLib::ElemLib\n*\n*   @brief\n*       constructor\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nElemLib::ElemLib(\n    Lib* pAddrLib)  ///< [in] Parent addrlib instance pointer\n    :\n    Object(pAddrLib->GetClient()),\n    m_pAddrLib(pAddrLib)\n{\n    switch (m_pAddrLib->GetChipFamily())\n    {\n        case ADDR_CHIP_FAMILY_R6XX:\n            m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;\n            m_fp16ExportNorm = 0;\n            break;\n        case ADDR_CHIP_FAMILY_R7XX:\n            m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;\n            m_fp16ExportNorm = 1;\n            break;\n        case ADDR_CHIP_FAMILY_R8XX:\n        case ADDR_CHIP_FAMILY_NI: // Same as 8xx\n            m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;\n            m_fp16ExportNorm = 1;\n            break;\n        default:\n            m_fp16ExportNorm = 1;\n            m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;\n            break;\n    }\n\n    m_configFlags.value = 0;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::~ElemLib\n*\n*   @brief\n*       destructor\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nElemLib::~ElemLib()\n{\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::Create\n*\n*   @brief\n*       Creates and initializes AddrLib object.\n*\n*   @return\n*       Returns point to ADDR_CREATEINFO if successful.\n****************************************************************************************************\n*/\nElemLib* ElemLib::Create(\n    const Lib* pAddrLib)   ///< [in] Pointer of parent AddrLib instance\n{\n    ElemLib* pElemLib = NULL;\n\n    if (pAddrLib)\n    {\n        VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient());\n        if (pObj)\n        {\n            pElemLib = new(pObj) ElemLib(const_cast<Lib* const>(pAddrLib));\n        }\n    }\n\n    return pElemLib;\n}\n\n/**************************************************************************************************\n*   ElemLib::Flt32sToInt32s\n*\n*   @brief\n*       Convert a ADDR_FLT_32 value to Int32 value\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::Flt32sToInt32s(\n    ADDR_FLT_32     value,      ///< [in] ADDR_FLT_32 value\n    UINT_32         bits,       ///< [in] nubmer of bits in value\n    NumberType      numberType, ///< [in] the type of number\n    UINT_32*        pResult)    ///< [out] Int32 value\n{\n    UINT_8 round = 128;    //ADDR_ROUND_BY_HALF\n    UINT_32 uscale;\n    UINT_32 sign;\n\n    //convert each component to an INT_32\n    switch ( numberType )\n    {\n        case ADDR_NO_NUMBER:    //fall through\n        case ADDR_ZERO:         //fall through\n        case ADDR_ONE:          //fall through\n        case ADDR_EPSILON:      //fall through\n            return;        // these are zero-bit components, so don't set result\n\n        case ADDR_UINT_BITS:            // unsigned integer bit field, clamped to range\n            uscale = (1<<bits) - 1;\n            if (bits == 32)               // special case unsigned 32-bit int\n            {\n                *pResult = value.i;\n            }\n            else\n            {\n                if ((value.i < 0) || (value.u > uscale))\n                {\n                    *pResult = uscale;\n                }\n                else\n                {\n                    *pResult = value.i;\n                }\n                return;\n            }\n\n        // The algorithm used in the DB and TX differs at one value for 24-bit unorms\n        case ADDR_UNORM_R6XXDB:        // unsigned repeating fraction\n            if ((bits==24) && (value.i == 0x33000000))\n            {\n                *pResult = 1;\n                return;\n            }              // Else treat like ADDR_UNORM_R6XX\n\n        case ADDR_UNORM_R6XX:            // unsigned repeating fraction\n            if (value.f <= 0)\n            {\n                *pResult = 0;            // first clamp to [0..1]\n            }\n            else\n            {\n                if (value.f >= 1)\n                {\n                     *pResult = (1<<bits) - 1;\n                }\n                else\n                {\n                    if ((value.i | 0x87FFFFFF) == 0xFFFFFFFF)\n                    {\n                        *pResult = 0;                        // NaN, so force to 0\n                    }\n\n                    #if 0 // floating point version for documentation\n                    else\n                    {\n                        FLOAT f = value.f * ((1<<bits) - 1);\n                        *pResult = static_cast<INT_32>(f + (round/256.0f));\n                    }\n                    #endif\n                    else\n                    {\n                        ADDR_FLT_32 scaled;\n                        ADDR_FLT_32 shifted;\n                        UINT_64 truncated, rounded;\n                        UINT_32 altShift;\n                        UINT_32 mask = (1 << bits) - 1;\n                        UINT_32 half = 1 << (bits - 1);\n                        UINT_32 mant24 = (value.i & 0x7FFFFF) + 0x800000;\n                        UINT_64 temp = mant24 - (mant24>>bits) -\n                            static_cast<INT_32>((mant24 & mask) > half);\n                        UINT_32 exp8 = value.i >> 23;\n                        UINT_32 shift = 126 - exp8 + 24 - bits;\n                        UINT_64 final;\n\n                        if (shift >= 32) // This is zero, even with maximum dither add\n                        {\n                            final = 0;\n                        }\n                        else\n                        {\n                            final = ((temp<<8) + (static_cast<UINT_64>(round)<<shift)) >> (shift+8);\n                        }\n                        //ADDR_EXIT( *pResult == final,\n                        //    (\"Float %x converted to %d-bit Unorm %x != bitwise %x\",\n                        //     value.u, bits, (UINT_32)*pResult, (UINT_32)final) );\n                        if (final > mask)\n                        {\n                            final = mask;\n                        }\n\n                        scaled.f  = value.f * ((1<<bits) - 1);\n                        shifted.f = (scaled.f * 256);\n                        truncated = ((shifted.i&0x7FFFFF) + (INT_64)0x800000) << 8;\n                        altShift  = 126 + 24 + 8 - ((shifted.i>>23)&0xFF);\n                        truncated = (altShift > 60) ? 0 : truncated >> altShift;\n                        rounded   = static_cast<INT_32>((round + truncated) >> 8);\n                        //if (rounded > ((1<<bits) - 1))\n                        //    rounded = ((1<<bits) - 1);\n                        *pResult = static_cast<INT_32>(rounded); //(INT_32)final;\n                    }\n                }\n            }\n\n            return;\n\n        case ADDR_S8FLOAT32:    // 32-bit IEEE float, passes through NaN values\n            *pResult = value.i;\n            return;\n\n        // @@ FIX ROUNDING in this code, fix the denorm case\n        case ADDR_U4FLOATC:         // Unsigned float, 4-bit exponent. bias 15, clamped [0..1]\n            sign = (value.i >> 31) & 1;\n            if ((value.i&0x7F800000) == 0x7F800000)    // If NaN or INF:\n            {\n                if ((value.i&0x007FFFFF) != 0)             // then if NaN\n                {\n                    *pResult = 0;                       // return 0\n                }\n                else\n                {\n                    *pResult = (sign)?0:0xF00000;           // else +INF->+1, -INF->0\n                }\n                return;\n            }\n            if (value.f <= 0)\n            {\n                *pResult = 0;\n            }\n            else\n            {\n                if (value.f>=1)\n                {\n                    *pResult = 0xF << (bits-4);\n                }\n                else\n                {\n                    if ((value.i>>23) > 112 )\n                    {\n                        // 24-bit float: normalized\n                        // value.i += 1 << (22-bits+4);\n                        // round the IEEE mantissa to mantissa size\n                        // @@ NOTE: add code to support rounding\n                        value.u &= 0x7FFFFFF;             // mask off high 4 exponent bits\n                        *pResult = value.i >> (23-bits+4);// shift off unused mantissa bits\n                    }\n                    else\n                    {\n                        // 24-bit float: denormalized\n                        value.f = value.f / (1<<28) / (1<<28);\n                        value.f = value.f / (1<<28) / (1<<28);    // convert to IEEE denorm\n                        // value.i += 1 << (22-bits+4);\n                        // round the IEEE mantissa to mantissa size\n                        // @@ NOTE: add code to support rounding\n                        *pResult = value.i >> (23-bits+4);    // shift off unused mantissa bits\n                    }\n                }\n            }\n\n            return;\n\n        default:                    // invalid number mode\n            //ADDR_EXIT(0, (\"Invalid AddrNumber %d\", numberType) );\n            break;\n\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::Int32sToPixel\n*\n*   @brief\n*       Pack 32-bit integer values into an uncompressed pixel,\n*       in the proper order\n*\n*   @return\n*       N/A\n*\n*   @note\n*       This entry point packes four 32-bit integer values into\n*       an uncompressed pixel. The pixel values are specifies in\n*       standard order, e.g. depth/stencil. This routine asserts\n*       if called on compressed pixel.\n****************************************************************************************************\n*/\nVOID ElemLib::Int32sToPixel(\n    UINT_32              numComps,      ///< [in] number of components\n    UINT_32*             pComps,        ///< [in] compnents\n    UINT_32*             pCompBits,     ///< [in] total bits in each component\n    UINT_32*             pCompStart,    ///< [in] the first bit position of each component\n    ComponentFlags       properties,    ///< [in] properties about byteAligned, exportNorm\n    UINT_32              resultBits,    ///< [in] result bits: total bpp after decompression\n    UINT_8*              pPixel)        ///< [out] a depth/stencil pixel value\n{\n    UINT_32 i;\n    UINT_32 j;\n    UINT_32 start;\n    UINT_32 size;\n    UINT_32 byte;\n    UINT_32 value = 0;\n    UINT_32 compMask;\n    UINT_32 elemMask=0;\n    UINT_32 elementXor = 0;  // address xor when reading bytes from elements\n\n\n    // @@ NOTE: assert if called on a compressed format!\n\n    if (properties.byteAligned)    // Components are all byte-sized\n    {\n        for (i = 0; i < numComps; i++)        // Then for each component\n        {\n            // Copy the bytes of the component into the element\n            start = pCompStart[i] / 8;\n            size  = pCompBits[i]  / 8;\n            for (j = 0; j < size; j++)\n            {\n                pPixel[(j+start)^elementXor] = static_cast<UINT_8>(pComps[i] >> (8*j));\n            }\n        }\n    }\n    else                        // Element is 32-bits or less, components are bit fields\n    {\n        // First, extract each component in turn and combine it into a 32-bit value\n        for (i = 0; i < numComps; i++)\n        {\n            compMask = (1 << pCompBits[i]) - 1;\n            elemMask |= compMask << pCompStart[i];\n            value |= (pComps[i] & compMask) << pCompStart[i];\n        }\n\n        // Mext, copy the masked value into the element\n        size = (resultBits + 7) / 8;\n        for (i = 0; i < size; i++)\n        {\n            byte = pPixel[i^elementXor] & ~(elemMask >> (8*i));\n            pPixel[i^elementXor] = static_cast<UINT_8>(byte | ((elemMask & value) >> (8*i)));\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   Flt32ToDepthPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a depth/stencil pixel value\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::Flt32ToDepthPixel(\n    AddrDepthFormat     format,     ///< [in] Depth format\n    const ADDR_FLT_32   comps[2],   ///< [in] two components of depth\n    UINT_8*             pPixel      ///< [out] depth pixel value\n    ) const\n{\n    UINT_32 i;\n    UINT_32 values[2];\n    ComponentFlags properties;  // byteAligned, exportNorm\n    UINT_32 resultBits = 0;     // result bits: total bits per pixel after decompression\n\n    PixelFormatInfo fmt;\n\n    // get type for each component\n    PixGetDepthCompInfo(format, &fmt);\n\n    //initialize properties\n    properties.byteAligned = TRUE;\n    properties.exportNorm  = TRUE;\n    properties.floatComp   = FALSE;\n\n    //set properties and result bits\n    for (i = 0; i < 2; i++)\n    {\n        if ((fmt.compBit[i] & 7) || (fmt.compStart[i] & 7))\n        {\n            properties.byteAligned = FALSE;\n        }\n\n        if (resultBits < fmt.compStart[i] + fmt.compBit[i])\n        {\n            resultBits = fmt.compStart[i] + fmt.compBit[i];\n        }\n\n        // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format\n        if (fmt.compBit[i] > 11 || fmt.numType[i] >= ADDR_USCALED)\n        {\n            properties.exportNorm = FALSE;\n        }\n\n        // Mark if there are any floating point components\n        if ((fmt.numType[i] == ADDR_U4FLOATC) || (fmt.numType[i] >= ADDR_S8FLOAT) )\n        {\n            properties.floatComp = TRUE;\n        }\n    }\n\n    // Convert the two input floats to integer values\n    for (i = 0; i < 2; i++)\n    {\n        Flt32sToInt32s(comps[i], fmt.compBit[i], fmt.numType[i], &values[i]);\n    }\n\n    // Then pack the two integer components, in the proper order\n    Int32sToPixel(2, values, fmt.compBit, fmt.compStart, properties, resultBits, pPixel );\n\n}\n\n/**\n****************************************************************************************************\n*   Flt32ToColorPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a red/green/blue/alpha pixel value\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::Flt32ToColorPixel(\n    AddrColorFormat     format,     ///< [in] Color format\n    AddrSurfaceNumber   surfNum,    ///< [in] Surface number\n    AddrSurfaceSwap     surfSwap,   ///< [in] Surface swap\n    const ADDR_FLT_32   comps[4],   ///< [in] four components of color\n    UINT_8*             pPixel      ///< [out] a red/green/blue/alpha pixel value\n    ) const\n{\n    PixelFormatInfo pixelInfo;\n\n    UINT_32 i;\n    UINT_32 values[4];\n    ComponentFlags properties;    // byteAligned, exportNorm\n    UINT_32 resultBits = 0;       // result bits: total bits per pixel after decompression\n\n    memset(&pixelInfo, 0, sizeof(PixelFormatInfo));\n\n    PixGetColorCompInfo(format, surfNum, surfSwap, &pixelInfo);\n\n    //initialize properties\n    properties.byteAligned = TRUE;\n    properties.exportNorm  = TRUE;\n    properties.floatComp   = FALSE;\n\n    //set properties and result bits\n    for (i = 0; i < 4; i++)\n    {\n        if ( (pixelInfo.compBit[i] & 7) || (pixelInfo.compStart[i] & 7) )\n        {\n            properties.byteAligned = FALSE;\n        }\n\n        if (resultBits < pixelInfo.compStart[i] + pixelInfo.compBit[i])\n        {\n            resultBits = pixelInfo.compStart[i] + pixelInfo.compBit[i];\n        }\n\n        if (m_fp16ExportNorm)\n        {\n            // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format\n            // or if it's not FP and <=16 bits\n            if (((pixelInfo.compBit[i] > 11) || (pixelInfo.numType[i] >= ADDR_USCALED))\n                && (pixelInfo.numType[i] !=ADDR_U4FLOATC))\n            {\n                properties.exportNorm = FALSE;\n            }\n        }\n        else\n        {\n            // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format\n            if (pixelInfo.compBit[i] > 11 || pixelInfo.numType[i] >= ADDR_USCALED)\n            {\n                properties.exportNorm = FALSE;\n            }\n        }\n\n        // Mark if there are any floating point components\n        if ( (pixelInfo.numType[i] == ADDR_U4FLOATC) ||\n             (pixelInfo.numType[i] >= ADDR_S8FLOAT) )\n        {\n            properties.floatComp = TRUE;\n        }\n    }\n\n    // Convert the four input floats to integer values\n    for (i = 0; i < 4; i++)\n    {\n        Flt32sToInt32s(comps[i], pixelInfo.compBit[i], pixelInfo.numType[i], &values[i]);\n    }\n\n    // Then pack the four integer components, in the proper order\n    Int32sToPixel(4, values, &pixelInfo.compBit[0], &pixelInfo.compStart[0],\n                  properties, resultBits, pPixel);\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetCompType\n*\n*   @brief\n*       Fill per component info\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID ElemLib::GetCompType(\n    AddrColorFormat   format,     ///< [in] surface format\n    AddrSurfaceNumber numType,  ///< [in] number type\n    PixelFormatInfo*  pInfo)       ///< [in][out] per component info out\n{\n    BOOL_32 handled = FALSE;\n\n    // Floating point formats override the number format\n    switch (format)\n    {\n        case ADDR_COLOR_16_FLOAT:            // fall through for all pure floating point format\n        case ADDR_COLOR_16_16_FLOAT:\n        case ADDR_COLOR_16_16_16_16_FLOAT:\n        case ADDR_COLOR_32_FLOAT:\n        case ADDR_COLOR_32_32_FLOAT:\n        case ADDR_COLOR_32_32_32_32_FLOAT:\n        case ADDR_COLOR_10_11_11_FLOAT:\n        case ADDR_COLOR_11_11_10_FLOAT:\n            numType = ADDR_NUMBER_FLOAT;\n            break;\n            // Special handling for the depth formats\n        case ADDR_COLOR_8_24:                // fall through for these 2 similar format\n        case ADDR_COLOR_24_8:\n            for (UINT_32 c = 0; c < 4; c++)\n            {\n                if (pInfo->compBit[c] == 8)\n                {\n                    pInfo->numType[c] = ADDR_UINT_BITS;\n                }\n                else if (pInfo->compBit[c]  == 24)\n                {\n                    pInfo->numType[c] = ADDR_UNORM_R6XX;\n                }\n                else\n                {\n                    pInfo->numType[c] = ADDR_NO_NUMBER;\n                }\n            }\n            handled = TRUE;\n            break;\n        case ADDR_COLOR_8_24_FLOAT:          // fall through for these 3 similar format\n        case ADDR_COLOR_24_8_FLOAT:\n        case ADDR_COLOR_X24_8_32_FLOAT:\n            for (UINT_32 c = 0; c < 4; c++)\n            {\n                if (pInfo->compBit[c] == 8)\n                {\n                    pInfo->numType[c] = ADDR_UINT_BITS;\n                }\n                else if (pInfo->compBit[c] == 24)\n                {\n                    pInfo->numType[c] = ADDR_U4FLOATC;\n                }\n                else if (pInfo->compBit[c] == 32)\n                {\n                    pInfo->numType[c] = ADDR_S8FLOAT32;\n                }\n                else\n                {\n                    pInfo->numType[c] = ADDR_NO_NUMBER;\n                }\n            }\n            handled = TRUE;\n            break;\n        default:\n            break;\n    }\n\n    if (!handled)\n    {\n        for (UINT_32 c = 0; c < 4; c++)\n        {\n            // Assign a number type for each component\n            AddrSurfaceNumber cnum;\n\n            // First handle default component values\n            if (pInfo->compBit[c] == 0)\n            {\n                if (c < 3)\n                {\n                    pInfo->numType[c] = ADDR_ZERO;      // Default is zero for RGB\n                }\n                else if (numType == ADDR_NUMBER_UINT || numType == ADDR_NUMBER_SINT)\n                {\n                    pInfo->numType[c] = ADDR_EPSILON;   // Alpha INT_32 bits default is 0x01\n                }\n                else\n                {\n                    pInfo->numType[c] = ADDR_ONE;       // Alpha normal default is float 1.0\n                }\n                continue;\n            }\n            // Now handle small components\n            else if (pInfo->compBit[c] == 1)\n            {\n                if (numType == ADDR_NUMBER_UINT || numType == ADDR_NUMBER_SINT)\n                {\n                    cnum = ADDR_NUMBER_UINT;\n                }\n                else\n                {\n                    cnum = ADDR_NUMBER_UNORM;\n                }\n            }\n            else\n            {\n                cnum = numType;\n            }\n\n            // If no default, set the number type fom num, compbits, and architecture\n            switch (cnum)\n            {\n                case ADDR_NUMBER_SRGB:\n                    pInfo->numType[c] = (c < 3) ? ADDR_GAMMA8_R6XX : ADDR_UNORM_R6XX;\n                    break;\n                case ADDR_NUMBER_UNORM:\n                    pInfo->numType[c] = ADDR_UNORM_R6XX;\n                    break;\n                case ADDR_NUMBER_SNORM:\n                    pInfo->numType[c] = ADDR_SNORM_R6XX;\n                    break;\n                case ADDR_NUMBER_USCALED:\n                    pInfo->numType[c] = ADDR_USCALED;  // @@ Do we need separate Pele routine?\n                    break;\n                case ADDR_NUMBER_SSCALED:\n                    pInfo->numType[c] = ADDR_SSCALED;  // @@ Do we need separate Pele routine?\n                    break;\n                case ADDR_NUMBER_FLOAT:\n                    if (pInfo->compBit[c] == 32)\n                    {\n                        pInfo->numType[c] = ADDR_S8FLOAT32;\n                    }\n                    else if (pInfo->compBit[c] == 16)\n                    {\n                        pInfo->numType[c] = ADDR_S5FLOAT;\n                    }\n                    else if (pInfo->compBit[c] >= 10)\n                    {\n                        pInfo->numType[c] = ADDR_U5FLOAT;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                    break;\n                case ADDR_NUMBER_SINT:\n                    pInfo->numType[c] = ADDR_SINT_BITS;\n                    break;\n                case ADDR_NUMBER_UINT:\n                    pInfo->numType[c] = ADDR_UINT_BITS;\n                    break;\n\n                default:\n                    ADDR_ASSERT(!\"Invalid number type\");\n                    pInfo->numType[c] = ADDR_NO_NUMBER;\n                    break;\n             }\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetCompSwap\n*\n*   @brief\n*       Get components swapped for color surface\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID ElemLib::GetCompSwap(\n    AddrSurfaceSwap  swap,   ///< [in] swap mode\n    PixelFormatInfo* pInfo)  ///< [in,out] output per component info\n{\n    switch (pInfo->comps)\n    {\n        case 4:\n            switch (swap)\n            {\n                case ADDR_SWAP_ALT:\n                    SwapComps( 0, 2, pInfo );\n                    break;    // BGRA\n                case ADDR_SWAP_STD_REV:\n                    SwapComps( 0, 3, pInfo );\n                    SwapComps( 1, 2, pInfo );\n                    break;    // ABGR\n                case ADDR_SWAP_ALT_REV:\n                    SwapComps( 0, 3, pInfo );\n                    SwapComps( 0, 2, pInfo );\n                    SwapComps( 0, 1, pInfo );\n                    break;    // ARGB\n                default:\n                    break;\n            }\n            break;\n        case 3:\n            switch (swap)\n            {\n                case ADDR_SWAP_ALT_REV:\n                    SwapComps( 0, 3, pInfo );\n                    SwapComps( 0, 2, pInfo );\n                    break;    // AGR\n                case ADDR_SWAP_STD_REV:\n                    SwapComps( 0, 2, pInfo );\n                    break;    // BGR\n                case ADDR_SWAP_ALT:\n                    SwapComps( 2, 3, pInfo );\n                    break;    // RGA\n                default:\n                    break;    // RGB\n            }\n            break;\n        case 2:\n            switch (swap)\n            {\n                case ADDR_SWAP_ALT_REV:\n                    SwapComps( 0, 1, pInfo );\n                    SwapComps( 1, 3, pInfo );\n                    break;    // AR\n                case ADDR_SWAP_STD_REV:\n                    SwapComps( 0, 1, pInfo );\n                    break;    // GR\n                case ADDR_SWAP_ALT:\n                    SwapComps( 1, 3, pInfo );\n                    break;    // RA\n                default:\n                    break;    // RG\n            }\n            break;\n        case 1:\n            switch (swap)\n            {\n                case ADDR_SWAP_ALT_REV:\n                    SwapComps( 0, 3, pInfo );\n                    break;    // A\n                case ADDR_SWAP_STD_REV:\n                    SwapComps( 0, 2, pInfo );\n                    break;    // B\n                case ADDR_SWAP_ALT:\n                    SwapComps( 0, 1, pInfo );\n                    break;    // G\n                default:\n                    break;    // R\n            }\n            break;\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetCompSwap\n*\n*   @brief\n*       Get components swapped for color surface\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID ElemLib::SwapComps(\n    UINT_32          c0,     ///< [in] component index 0\n    UINT_32          c1,     ///< [in] component index 1\n    PixelFormatInfo* pInfo)  ///< [in,out] output per component info\n{\n    UINT_32 start;\n    UINT_32 bits;\n\n    start = pInfo->compStart[c0];\n    pInfo->compStart[c0] = pInfo->compStart[c1];\n    pInfo->compStart[c1] = start;\n\n    bits  = pInfo->compBit[c0];\n    pInfo->compBit[c0] = pInfo->compBit[c1];\n    pInfo->compBit[c1] = bits;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::PixGetColorCompInfo\n*\n*   @brief\n*       Get per component info for color surface\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID ElemLib::PixGetColorCompInfo(\n    AddrColorFormat   format, ///< [in] surface format, read from register\n    AddrSurfaceNumber number, ///< [in] pixel number type\n    AddrSurfaceSwap   swap,   ///< [in] component swap mode\n    PixelFormatInfo*  pInfo   ///< [out] output per component info\n    ) const\n{\n    // 1. Get componet bits\n    switch (format)\n    {\n        case ADDR_COLOR_8:\n            GetCompBits(8, 0, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_1_5_5_5:\n            GetCompBits(5, 5, 5, 1, pInfo);\n            break;\n        case ADDR_COLOR_5_6_5:\n            GetCompBits(8, 6, 5, 0, pInfo);\n            break;\n        case ADDR_COLOR_6_5_5:\n            GetCompBits(5, 5, 6, 0, pInfo);\n            break;\n        case ADDR_COLOR_8_8:\n            GetCompBits(8, 8, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_4_4_4_4:\n            GetCompBits(4, 4, 4, 4, pInfo);\n            break;\n        case ADDR_COLOR_16:\n            GetCompBits(16, 0, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_8_8_8_8:\n            GetCompBits(8, 8, 8, 8, pInfo);\n            break;\n        case ADDR_COLOR_2_10_10_10:\n            GetCompBits(10, 10, 10, 2, pInfo);\n            break;\n        case ADDR_COLOR_10_11_11:\n            GetCompBits(11, 11, 10, 0, pInfo);\n            break;\n        case ADDR_COLOR_11_11_10:\n            GetCompBits(10, 11, 11, 0, pInfo);\n            break;\n        case ADDR_COLOR_16_16:\n            GetCompBits(16, 16, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_16_16_16_16:\n            GetCompBits(16, 16, 16, 16, pInfo);\n            break;\n        case ADDR_COLOR_16_FLOAT:\n            GetCompBits(16, 0, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_16_16_FLOAT:\n            GetCompBits(16, 16, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_32_FLOAT:\n            GetCompBits(32, 0, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_32_32_FLOAT:\n            GetCompBits(32, 32, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_16_16_16_16_FLOAT:\n            GetCompBits(16, 16, 16, 16, pInfo);\n            break;\n        case ADDR_COLOR_32_32_32_32_FLOAT:\n            GetCompBits(32, 32, 32, 32, pInfo);\n            break;\n\n        case ADDR_COLOR_32:\n            GetCompBits(32, 0, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_32_32:\n            GetCompBits(32, 32, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_32_32_32_32:\n            GetCompBits(32, 32, 32, 32, pInfo);\n            break;\n        case ADDR_COLOR_10_10_10_2:\n            GetCompBits(2, 10, 10, 10, pInfo);\n            break;\n        case ADDR_COLOR_10_11_11_FLOAT:\n            GetCompBits(11, 11, 10, 0, pInfo);\n            break;\n        case ADDR_COLOR_11_11_10_FLOAT:\n            GetCompBits(10, 11, 11, 0, pInfo);\n            break;\n        case ADDR_COLOR_5_5_5_1:\n            GetCompBits(1, 5, 5, 5, pInfo);\n            break;\n        case ADDR_COLOR_3_3_2:\n            GetCompBits(2, 3, 3, 0, pInfo);\n            break;\n        case ADDR_COLOR_4_4:\n            GetCompBits(4, 4, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_8_24:\n        case ADDR_COLOR_8_24_FLOAT:  // same bit count, fall through\n            GetCompBits(24, 8, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_24_8:\n        case ADDR_COLOR_24_8_FLOAT:  // same bit count, fall through\n            GetCompBits(8, 24, 0, 0, pInfo);\n            break;\n        case ADDR_COLOR_X24_8_32_FLOAT:\n            GetCompBits(32, 8, 0, 0, pInfo);\n            break;\n\n        case ADDR_COLOR_INVALID:\n            GetCompBits(0, 0, 0, 0, pInfo);\n            break;\n        default:\n            ADDR_ASSERT(0);\n            GetCompBits(0, 0, 0, 0, pInfo);\n            break;\n    }\n\n    // 2. Get component number type\n\n    GetCompType(format, number, pInfo);\n\n    // 3. Swap components if needed\n\n    GetCompSwap(swap, pInfo);\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::PixGetDepthCompInfo\n*\n*   @brief\n*       Get per component info for depth surface\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID ElemLib::PixGetDepthCompInfo(\n    AddrDepthFormat  format,     ///< [in] surface format, read from register\n    PixelFormatInfo* pInfo       ///< [out] output per component bits and type\n    ) const\n{\n    if (m_depthPlanarType == ADDR_DEPTH_PLANAR_R800)\n    {\n        if (format == ADDR_DEPTH_8_24_FLOAT)\n        {\n            format = ADDR_DEPTH_X24_8_32_FLOAT; // Use this format to represent R800's D24FS8\n        }\n\n        if (format == ADDR_DEPTH_X8_24_FLOAT)\n        {\n            format = ADDR_DEPTH_32_FLOAT;\n        }\n    }\n\n    switch (format)\n    {\n        case ADDR_DEPTH_16:\n            GetCompBits(16, 0, 0, 0, pInfo);\n            break;\n        case ADDR_DEPTH_8_24:\n        case ADDR_DEPTH_8_24_FLOAT:      // similar format, fall through\n            GetCompBits(24, 8, 0, 0, pInfo);\n            break;\n        case ADDR_DEPTH_X8_24:\n        case ADDR_DEPTH_X8_24_FLOAT:     // similar format, fall through\n            GetCompBits(24, 0, 0, 0, pInfo);\n            break;\n        case ADDR_DEPTH_32_FLOAT:\n            GetCompBits(32, 0, 0, 0, pInfo);\n            break;\n        case ADDR_DEPTH_X24_8_32_FLOAT:\n            GetCompBits(32, 8, 0, 0, pInfo);\n            break;\n        case ADDR_DEPTH_INVALID:\n            GetCompBits(0, 0, 0, 0, pInfo);\n            break;\n        default:\n            ADDR_ASSERT(0);\n            GetCompBits(0, 0, 0, 0, pInfo);\n            break;\n    }\n\n    switch (format)\n    {\n        case ADDR_DEPTH_16:\n            pInfo->numType [0] = ADDR_UNORM_R6XX;\n            pInfo->numType [1] = ADDR_ZERO;\n            break;\n        case ADDR_DEPTH_8_24:\n            pInfo->numType [0] = ADDR_UNORM_R6XXDB;\n            pInfo->numType [1] = ADDR_UINT_BITS;\n            break;\n        case ADDR_DEPTH_8_24_FLOAT:\n            pInfo->numType [0] = ADDR_U4FLOATC;\n            pInfo->numType [1] = ADDR_UINT_BITS;\n            break;\n        case ADDR_DEPTH_X8_24:\n            pInfo->numType [0] = ADDR_UNORM_R6XXDB;\n            pInfo->numType [1] = ADDR_ZERO;\n            break;\n        case ADDR_DEPTH_X8_24_FLOAT:\n            pInfo->numType [0] = ADDR_U4FLOATC;\n            pInfo->numType [1] = ADDR_ZERO;\n            break;\n        case ADDR_DEPTH_32_FLOAT:\n            pInfo->numType [0] = ADDR_S8FLOAT32;\n            pInfo->numType [1] = ADDR_ZERO;\n            break;\n        case ADDR_DEPTH_X24_8_32_FLOAT:\n            pInfo->numType [0] = ADDR_S8FLOAT32;\n            pInfo->numType [1] = ADDR_UINT_BITS;\n            break;\n        default:\n            pInfo->numType [0] = ADDR_NO_NUMBER;\n            pInfo->numType [1] = ADDR_NO_NUMBER;\n            break;\n    }\n\n    pInfo->numType [2] = ADDR_NO_NUMBER;\n    pInfo->numType [3] = ADDR_NO_NUMBER;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::PixGetExportNorm\n*\n*   @brief\n*       Check if fp16 export norm can be enabled.\n*\n*   @return\n*       TRUE if this can be enabled.\n*\n****************************************************************************************************\n*/\nBOOL_32 ElemLib::PixGetExportNorm(\n    AddrColorFormat     colorFmt,       ///< [in] surface format, read from register\n    AddrSurfaceNumber   numberFmt,      ///< [in] pixel number type\n    AddrSurfaceSwap     swap            ///< [in] components swap type\n    ) const\n{\n    BOOL_32 enabled = TRUE;\n\n    PixelFormatInfo formatInfo;\n\n    PixGetColorCompInfo(colorFmt, numberFmt, swap, &formatInfo);\n\n    for (UINT_32 c = 0; c < 4; c++)\n    {\n        if (m_fp16ExportNorm)\n        {\n            if (((formatInfo.compBit[c] > 11) || (formatInfo.numType[c] > ADDR_USCALED)) &&\n                (formatInfo.numType[c] != ADDR_U4FLOATC)    &&\n                (formatInfo.numType[c] != ADDR_S5FLOAT)     &&\n                (formatInfo.numType[c] != ADDR_S5FLOATM)    &&\n                (formatInfo.numType[c] != ADDR_U5FLOAT)     &&\n                (formatInfo.numType[c] != ADDR_U3FLOATM))\n            {\n                enabled = FALSE;\n                break;\n            }\n        }\n        else\n        {\n            if ((formatInfo.compBit[c] > 11) || (formatInfo.numType[c] > ADDR_USCALED))\n            {\n                enabled = FALSE;\n                break;\n            }\n        }\n    }\n\n    return enabled;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::AdjustSurfaceInfo\n*\n*   @brief\n*       Adjust bpp/base pitch/width/height according to elemMode and expandX/Y\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::AdjustSurfaceInfo(\n    ElemMode        elemMode,       ///< [in] element mode\n    UINT_32         expandX,        ///< [in] decompression expansion factor in X\n    UINT_32         expandY,        ///< [in] decompression expansion factor in Y\n    UINT_32*        pBpp,           ///< [in,out] bpp\n    UINT_32*        pBasePitch,     ///< [in,out] base pitch\n    UINT_32*        pWidth,         ///< [in,out] width\n    UINT_32*        pHeight)        ///< [in,out] height\n{\n    UINT_32 packedBits;\n    UINT_32 basePitch;\n    UINT_32 width;\n    UINT_32 height;\n    UINT_32 bpp;\n    BOOL_32 bBCnFormat = FALSE;\n\n    ADDR_ASSERT(pBpp != NULL);\n    ADDR_ASSERT(pWidth != NULL && pHeight != NULL && pBasePitch != NULL);\n\n    if (pBpp)\n    {\n        bpp = *pBpp;\n\n        switch (elemMode)\n        {\n            case ADDR_EXPANDED:\n                packedBits = bpp / expandX / expandY;\n                break;\n            case ADDR_PACKED_STD: // Different bit order\n            case ADDR_PACKED_REV:\n                packedBits = bpp * expandX * expandY;\n                break;\n            case ADDR_PACKED_GBGR:\n            case ADDR_PACKED_BGRG:\n                packedBits = bpp; // 32-bit packed ==> 2 32-bit result\n                break;\n            case ADDR_PACKED_BC1: // Fall through\n            case ADDR_PACKED_BC4:\n                packedBits = 64;\n                bBCnFormat = TRUE;\n                break;\n            case ADDR_PACKED_BC2: // Fall through\n            case ADDR_PACKED_BC3: // Fall through\n            case ADDR_PACKED_BC5: // Fall through\n                bBCnFormat = TRUE;\n                // fall through\n            case ADDR_PACKED_ASTC:\n            case ADDR_PACKED_ETC2_128BPP:\n                packedBits = 128;\n                break;\n            case ADDR_PACKED_ETC2_64BPP:\n                packedBits = 64;\n                break;\n            case ADDR_ROUND_BY_HALF:  // Fall through\n            case ADDR_ROUND_TRUNCATE: // Fall through\n            case ADDR_ROUND_DITHER:   // Fall through\n            case ADDR_UNCOMPRESSED:\n                packedBits = bpp;\n                break;\n            default:\n                packedBits = bpp;\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        *pBpp = packedBits;\n    }\n\n    if (pWidth && pHeight && pBasePitch)\n    {\n        basePitch = *pBasePitch;\n        width     = *pWidth;\n        height    = *pHeight;\n\n        if ((expandX > 1) || (expandY > 1))\n        {\n            if (elemMode == ADDR_EXPANDED)\n            {\n                basePitch *= expandX;\n                width     *= expandX;\n                height    *= expandY;\n            }\n            else\n            {\n                // Evergreen family workaround\n                if (bBCnFormat && (m_pAddrLib->GetChipFamily() == ADDR_CHIP_FAMILY_R8XX))\n                {\n                    // For BCn we now pad it to POW2 at the beginning so it is safe to\n                    // divide by 4 directly\n                    basePitch = basePitch / expandX;\n                    width     = width  / expandX;\n                    height    = height / expandY;\n#if DEBUG\n                    width     = (width == 0) ? 1 : width;\n                    height    = (height == 0) ? 1 : height;\n\n                    if ((*pWidth > PowTwoAlign(width, 8) * expandX) ||\n                        (*pHeight > PowTwoAlign(height, 8) * expandY)) // 8 is 1D tiling alignment\n                    {\n                        // if this assertion is hit we may have issues if app samples\n                        // rightmost/bottommost pixels\n                        ADDR_ASSERT_ALWAYS();\n                    }\n#endif\n                }\n                else // Not BCn format we still keep old way (FMT_1? No real test yet)\n                {\n                    basePitch = (basePitch + expandX - 1) / expandX;\n                    width     = (width + expandX - 1) / expandX;\n                    height    = (height + expandY - 1) / expandY;\n                }\n            }\n\n            *pBasePitch = basePitch; // 0 is legal value for base pitch.\n            *pWidth     = (width == 0) ? 1 : width;\n            *pHeight    = (height == 0) ? 1 : height;\n        } //if (pWidth && pHeight && pBasePitch)\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::RestoreSurfaceInfo\n*\n*   @brief\n*       Reverse operation of AdjustSurfaceInfo\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::RestoreSurfaceInfo(\n    ElemMode        elemMode,       ///< [in] element mode\n    UINT_32         expandX,        ///< [in] decompression expansion factor in X\n    UINT_32         expandY,        ///< [out] decompression expansion factor in Y\n    UINT_32*        pBpp,           ///< [in,out] bpp\n    UINT_32*        pWidth,         ///< [in,out] width\n    UINT_32*        pHeight)        ///< [in,out] height\n{\n    UINT_32 originalBits;\n    UINT_32 width;\n    UINT_32 height;\n    UINT_32 bpp;\n\n    BOOL_32 bBCnFormat = FALSE;\n\n    ADDR_ASSERT(pBpp != NULL);\n    ADDR_ASSERT(pWidth != NULL && pHeight != NULL);\n\n    if (pBpp)\n    {\n        bpp = *pBpp;\n\n        switch (elemMode)\n        {\n        case ADDR_EXPANDED:\n            originalBits = bpp * expandX * expandY;\n            break;\n        case ADDR_PACKED_STD: // Different bit order\n        case ADDR_PACKED_REV:\n            originalBits = bpp / expandX / expandY;\n            break;\n        case ADDR_PACKED_GBGR:\n        case ADDR_PACKED_BGRG:\n            originalBits = bpp; // 32-bit packed ==> 2 32-bit result\n            break;\n        case ADDR_PACKED_BC1: // Fall through\n        case ADDR_PACKED_BC4:\n            originalBits = 64;\n            bBCnFormat = TRUE;\n            break;\n        case ADDR_PACKED_BC2: // Fall through\n        case ADDR_PACKED_BC3: // Fall through\n        case ADDR_PACKED_BC5:\n            bBCnFormat = TRUE;\n            // fall through\n        case ADDR_PACKED_ASTC:\n        case ADDR_PACKED_ETC2_128BPP:\n            originalBits = 128;\n            break;\n        case ADDR_PACKED_ETC2_64BPP:\n            originalBits = 64;\n            break;\n        case ADDR_ROUND_BY_HALF:  // Fall through\n        case ADDR_ROUND_TRUNCATE: // Fall through\n        case ADDR_ROUND_DITHER:   // Fall through\n        case ADDR_UNCOMPRESSED:\n            originalBits = bpp;\n            break;\n        default:\n            originalBits = bpp;\n            ADDR_ASSERT_ALWAYS();\n            break;\n        }\n\n        *pBpp = originalBits;\n    }\n\n    if (pWidth && pHeight)\n    {\n        width    = *pWidth;\n        height   = *pHeight;\n\n        if ((expandX > 1) || (expandY > 1))\n        {\n            if (elemMode == ADDR_EXPANDED)\n            {\n                width /= expandX;\n                height /= expandY;\n            }\n            else\n            {\n                width *= expandX;\n                height *= expandY;\n            }\n        }\n\n        *pWidth  = (width == 0) ? 1 : width;\n        *pHeight = (height == 0) ? 1 : height;\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetBitsPerPixel\n*\n*   @brief\n*       Compute the total bits per element according to a format\n*       code. For compressed formats, this is not the same as\n*       the number of bits per decompressed element.\n*\n*   @return\n*       Bits per pixel\n****************************************************************************************************\n*/\nUINT_32 ElemLib::GetBitsPerPixel(\n    AddrFormat          format,         ///< [in] surface format code\n    ElemMode*           pElemMode,      ///< [out] element mode\n    UINT_32*            pExpandX,       ///< [out] decompression expansion factor in X\n    UINT_32*            pExpandY,       ///< [out] decompression expansion factor in Y\n    UINT_32*            pUnusedBits)    ///< [out] bits unused\n{\n    UINT_32 bpp;\n    UINT_32 expandX = 1;\n    UINT_32 expandY = 1;\n    UINT_32 bitUnused = 0;\n    ElemMode elemMode = ADDR_UNCOMPRESSED; // default value\n\n    switch (format)\n    {\n        case ADDR_FMT_8:\n            bpp = 8;\n            break;\n        case ADDR_FMT_1_5_5_5:\n        case ADDR_FMT_5_6_5:\n        case ADDR_FMT_6_5_5:\n        case ADDR_FMT_8_8:\n        case ADDR_FMT_4_4_4_4:\n        case ADDR_FMT_16:\n            bpp = 16;\n            break;\n        case ADDR_FMT_GB_GR:\n            elemMode = ADDR_PACKED_GBGR;\n            bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;\n            expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;\n            break;\n        case ADDR_FMT_BG_RG:\n            elemMode = ADDR_PACKED_BGRG;\n            bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;\n            expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;\n            break;\n        case ADDR_FMT_8_8_8_8:\n        case ADDR_FMT_2_10_10_10:\n        case ADDR_FMT_10_11_11:\n        case ADDR_FMT_11_11_10:\n        case ADDR_FMT_16_16:\n        case ADDR_FMT_32:\n        case ADDR_FMT_24_8:\n            bpp = 32;\n            break;\n        case ADDR_FMT_BG_RG_16_16_16_16:\n            elemMode = ADDR_PACKED_BGRG;\n            bpp = 32;\n            break;\n        case ADDR_FMT_16_16_16_16:\n        case ADDR_FMT_32_32:\n        case ADDR_FMT_CTX1:\n            bpp = 64;\n            break;\n        case ADDR_FMT_32_32_32_32:\n            bpp = 128;\n            break;\n        case ADDR_FMT_INVALID:\n            bpp = 0;\n            break;\n        case ADDR_FMT_1_REVERSED:\n            elemMode = ADDR_PACKED_REV;\n            expandX = 8;\n            bpp = 1;\n            break;\n        case ADDR_FMT_1:\n            elemMode = ADDR_PACKED_STD;\n            expandX = 8;\n            bpp = 1;\n            break;\n        case ADDR_FMT_4_4:\n        case ADDR_FMT_3_3_2:\n            bpp = 8;\n            break;\n        case ADDR_FMT_5_5_5_1:\n            bpp = 16;\n            break;\n        case ADDR_FMT_32_AS_8:\n        case ADDR_FMT_32_AS_8_8:\n        case ADDR_FMT_8_24:\n        case ADDR_FMT_10_10_10_2:\n        case ADDR_FMT_5_9_9_9_SHAREDEXP:\n            bpp = 32;\n            break;\n        case ADDR_FMT_X24_8_32_FLOAT:\n            bpp = 64;\n            bitUnused = 24;\n            break;\n        case ADDR_FMT_8_8_8:\n            elemMode = ADDR_EXPANDED;\n            bpp = 24;//@@ 8;      // read 3 elements per pixel\n            expandX = 3;\n            break;\n        case ADDR_FMT_16_16_16:\n            elemMode = ADDR_EXPANDED;\n            bpp = 48;//@@ 16;      // read 3 elements per pixel\n            expandX = 3;\n            break;\n        case ADDR_FMT_32_32_32:\n            elemMode = ADDR_EXPANDED;\n            expandX = 3;\n            bpp = 96;//@@ 32;      // read 3 elements per pixel\n            break;\n        case ADDR_FMT_BC1:\n            elemMode = ADDR_PACKED_BC1;\n            expandX = 4;\n            expandY = 4;\n            bpp = 64;\n            break;\n        case ADDR_FMT_BC4:\n            elemMode = ADDR_PACKED_BC4;\n            expandX = 4;\n            expandY = 4;\n            bpp = 64;\n            break;\n        case ADDR_FMT_BC2:\n            elemMode = ADDR_PACKED_BC2;\n            expandX = 4;\n            expandY = 4;\n            bpp = 128;\n            break;\n        case ADDR_FMT_BC3:\n            elemMode = ADDR_PACKED_BC3;\n            expandX = 4;\n            expandY = 4;\n            bpp = 128;\n            break;\n        case ADDR_FMT_BC5:\n        case ADDR_FMT_BC6: // reuse ADDR_PACKED_BC5\n        case ADDR_FMT_BC7: // reuse ADDR_PACKED_BC5\n            elemMode = ADDR_PACKED_BC5;\n            expandX = 4;\n            expandY = 4;\n            bpp = 128;\n            break;\n\n        case ADDR_FMT_ETC2_64BPP:\n            elemMode = ADDR_PACKED_ETC2_64BPP;\n            expandX  = 4;\n            expandY  = 4;\n            bpp      = 64;\n            break;\n\n        case ADDR_FMT_ETC2_128BPP:\n            elemMode = ADDR_PACKED_ETC2_128BPP;\n            expandX  = 4;\n            expandY  = 4;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_4x4:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 4;\n            expandY  = 4;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_5x4:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 5;\n            expandY  = 4;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_5x5:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 5;\n            expandY  = 5;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_6x5:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 6;\n            expandY  = 5;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_6x6:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 6;\n            expandY  = 6;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_8x5:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 8;\n            expandY  = 5;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_8x6:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 8;\n            expandY  = 6;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_8x8:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 8;\n            expandY  = 8;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_10x5:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 10;\n            expandY  = 5;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_10x6:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 10;\n            expandY  = 6;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_10x8:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 10;\n            expandY  = 8;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_10x10:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 10;\n            expandY  = 10;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_12x10:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 12;\n            expandY  = 10;\n            bpp      = 128;\n            break;\n\n        case ADDR_FMT_ASTC_12x12:\n            elemMode = ADDR_PACKED_ASTC;\n            expandX  = 12;\n            expandY  = 12;\n            bpp      = 128;\n            break;\n\n        default:\n            bpp = 0;\n            ADDR_ASSERT_ALWAYS();\n            break;\n            // @@ or should this be an error?\n    }\n\n    SafeAssign(pExpandX, expandX);\n    SafeAssign(pExpandY, expandY);\n    SafeAssign(pUnusedBits, bitUnused);\n    SafeAssign(reinterpret_cast<UINT_32*>(pElemMode), elemMode);\n\n    return bpp;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetCompBits\n*\n*   @brief\n*       Set each component's bit size and bit start. And set element mode and number type\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::GetCompBits(\n    UINT_32          c0,        ///< [in] bits of component 0\n    UINT_32          c1,        ///< [in] bits of component 1\n    UINT_32          c2,        ///< [in] bits of component 2\n    UINT_32          c3,        ///< [in] bits of component 3\n    PixelFormatInfo* pInfo,     ///< [out] per component info out\n    ElemMode         elemMode)  ///< [in] element mode\n{\n    pInfo->comps = 0;\n\n    pInfo->compBit[0] = c0;\n    pInfo->compBit[1] = c1;\n    pInfo->compBit[2] = c2;\n    pInfo->compBit[3] = c3;\n\n    pInfo->compStart[0] = 0;\n    pInfo->compStart[1] = c0;\n    pInfo->compStart[2] = c0+c1;\n    pInfo->compStart[3] = c0+c1+c2;\n\n    pInfo->elemMode = elemMode;\n    // still needed since component swap may depend on number of components\n    for (INT i=0; i<4; i++)\n    {\n        if (pInfo->compBit[i] == 0)\n        {\n            pInfo->compStart[i]  = 0;       // all null components start at bit 0\n            pInfo->numType[i] = ADDR_NO_NUMBER; // and have no number type\n        }\n        else\n        {\n            pInfo->comps++;\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::GetCompBits\n*\n*   @brief\n*       Set the clear color (or clear depth/stencil) for a surface\n*\n*   @note\n*       If clearColor is zero, a default clear value is used in place of comps[4].\n*       If float32 is set, full precision is used, else the mantissa is reduced to 12-bits\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID ElemLib::SetClearComps(\n    ADDR_FLT_32 comps[4],   ///< [in,out] components\n    BOOL_32 clearColor,     ///< [in] TRUE if clear color is set (CLEAR_COLOR)\n    BOOL_32 float32)        ///< [in] TRUE if float32 component (BLEND_FLOAT32)\n{\n    INT_32 i;\n\n    // Use default clearvalues if clearColor is disabled\n    if (clearColor == FALSE)\n    {\n        for (i=0; i<3; i++)\n        {\n            comps[i].f = 0.0;\n        }\n        comps[3].f = 1.0;\n    }\n\n    // Otherwise use the (modified) clear value\n    else\n    {\n        for (i=0; i<4; i++)\n        {   // If full precision, use clear value unchanged\n            if (float32)\n            {\n                // Do nothing\n                //comps[i] = comps[i];\n            }\n            // Else if it is a NaN, use the standard NaN value\n            else if ((comps[i].u & 0x7FFFFFFF) > 0x7F800000)\n            {\n                comps[i].u = 0xFFC00000;\n            }\n            // Else reduce the mantissa precision\n            else\n            {\n                comps[i].u = comps[i].u & 0xFFFFF000;\n            }\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::IsBlockCompressed\n*\n*   @brief\n*       TRUE if this is block compressed format\n*\n*   @note\n*\n*   @return\n*       BOOL_32\n****************************************************************************************************\n*/\nBOOL_32 ElemLib::IsBlockCompressed(\n    AddrFormat format)  ///< [in] Format\n{\n    return (((format >= ADDR_FMT_BC1) && (format <= ADDR_FMT_BC7)) ||\n            ((format >= ADDR_FMT_ASTC_4x4) && (format <= ADDR_FMT_ETC2_128BPP)));\n}\n\n\n/**\n****************************************************************************************************\n*   ElemLib::IsCompressed\n*\n*   @brief\n*       TRUE if this is block compressed format or 1 bit format\n*\n*   @note\n*\n*   @return\n*       BOOL_32\n****************************************************************************************************\n*/\nBOOL_32 ElemLib::IsCompressed(\n    AddrFormat format)  ///< [in] Format\n{\n    return IsBlockCompressed(format) || format == ADDR_FMT_BC1 || format == ADDR_FMT_BC7;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::IsExpand3x\n*\n*   @brief\n*       TRUE if this is 3x expand format\n*\n*   @note\n*\n*   @return\n*       BOOL_32\n****************************************************************************************************\n*/\nBOOL_32 ElemLib::IsExpand3x(\n    AddrFormat format)  ///< [in] Format\n{\n    BOOL_32 is3x = FALSE;\n\n    switch (format)\n    {\n        case ADDR_FMT_8_8_8:\n        case ADDR_FMT_16_16_16:\n        case ADDR_FMT_32_32_32:\n            is3x = TRUE;\n            break;\n        default:\n            break;\n    }\n\n    return is3x;\n}\n\n/**\n****************************************************************************************************\n*   ElemLib::IsMacroPixelPacked\n*\n*   @brief\n*       TRUE if this is a macro-pixel-packed format.\n*\n*   @note\n*\n*   @return\n*       BOOL_32\n****************************************************************************************************\n*/\nBOOL_32 ElemLib::IsMacroPixelPacked(\n    AddrFormat format)  ///< [in] Format\n{\n    BOOL_32 isMacroPixelPacked = FALSE;\n\n    switch (format)\n    {\n        case ADDR_FMT_BG_RG:\n        case ADDR_FMT_GB_GR:\n        case ADDR_FMT_BG_RG_16_16_16_16:\n            isMacroPixelPacked = TRUE;\n            break;\n        default:\n            break;\n    }\n\n    return isMacroPixelPacked;\n}\n\n}\n} //namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrelemlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n****************************************************************************************************\n* @file  addrelemlib.h\n* @brief Contains the class for element/pixel related functions.\n****************************************************************************************************\n*/\n\n#ifndef __ELEM_LIB_H__\n#define __ELEM_LIB_H__\n\n#include \"addrinterface.h\"\n#include \"addrobject.h\"\n#include \"addrcommon.h\"\n\nnamespace rocr {\nnamespace Addr\n{\n\nclass Lib;\n\n// The masks for property bits within the Properties INT_32\nunion ComponentFlags\n{\n    struct\n    {\n        UINT_32 byteAligned    : 1;    ///< all components are byte aligned\n        UINT_32 exportNorm     : 1;    ///< components support R6xx NORM compression\n        UINT_32 floatComp      : 1;    ///< there is at least one floating point component\n    };\n\n    UINT_32 value;\n};\n\n// Copy from legacy lib's NumberType\nenum NumberType\n{\n    // The following number types have the range [-1..1]\n    ADDR_NO_NUMBER,         // This component doesn't exist and has no default value\n    ADDR_EPSILON,           // Force component value to integer 0x00000001\n    ADDR_ZERO,              // Force component value to integer 0x00000000\n    ADDR_ONE,               // Force component value to floating point 1.0\n    // Above values don't have any bits per component (keep ADDR_ONE the last of these)\n\n    ADDR_UNORM,             // Unsigned normalized (repeating fraction) full precision\n    ADDR_SNORM,             // Signed normalized (repeating fraction) full precision\n    ADDR_GAMMA,             // Gamma-corrected, full precision\n\n    ADDR_UNORM_R5XXRB,      // Unsigned normalized (repeating fraction) for r5xx RB\n    ADDR_SNORM_R5XXRB,      // Signed normalized (repeating fraction) for r5xx RB\n    ADDR_GAMMA_R5XXRB,      // Gamma-corrected for r5xx RB (note: unnormalized value)\n    ADDR_UNORM_R5XXBC,      // Unsigned normalized (repeating fraction) for r5xx BC\n    ADDR_SNORM_R5XXBC,      // Signed normalized (repeating fraction) for r5xx BC\n    ADDR_GAMMA_R5XXBC,      // Gamma-corrected for r5xx BC (note: unnormalized value)\n\n    ADDR_UNORM_R6XX,        // Unsigned normalized (repeating fraction) for R6xx\n    ADDR_UNORM_R6XXDB,      // Unorms for 24-bit depth: one value differs from ADDR_UNORM_R6XX\n    ADDR_SNORM_R6XX,        // Signed normalized (repeating fraction) for R6xx\n    ADDR_GAMMA8_R6XX,       // Gamma-corrected for r6xx\n    ADDR_GAMMA8_R7XX_TP,    // Gamma-corrected for r7xx TP 12bit unorm 8.4.\n\n    ADDR_U4FLOATC,          // Unsigned float: 4-bit exponent, bias=15, no NaN, clamp [0..1]\n    ADDR_GAMMA_4SEG,        // Gamma-corrected, four segment approximation\n    ADDR_U0FIXED,           // Unsigned 0.N-bit fixed point\n\n    // The following number types have large ranges (LEAVE ADDR_USCALED first or fix Finish routine)\n    ADDR_USCALED,           // Unsigned integer converted to/from floating point\n    ADDR_SSCALED,           // Signed integer converted to/from floating point\n    ADDR_USCALED_R5XXRB,    // Unsigned integer to/from floating point for r5xx RB\n    ADDR_SSCALED_R5XXRB,    // Signed integer to/from floating point for r5xx RB\n    ADDR_UINT_BITS,         // Keep in unsigned integer form, clamped to specified range\n    ADDR_SINT_BITS,         // Keep in signed integer form, clamped to specified range\n    ADDR_UINTBITS,          // @@ remove Keep in unsigned integer form, use modulus to reduce bits\n    ADDR_SINTBITS,          // @@ remove Keep in signed integer form, use modulus to reduce bits\n\n    // The following number types and ADDR_U4FLOATC have exponents\n    // (LEAVE ADDR_S8FLOAT first or fix Finish routine)\n    ADDR_S8FLOAT,           // Signed floating point with 8-bit exponent, bias=127\n    ADDR_S8FLOAT32,         // 32-bit IEEE float, passes through NaN values\n    ADDR_S5FLOAT,           // Signed floating point with 5-bit exponent, bias=15\n    ADDR_S5FLOATM,          // Signed floating point with 5-bit exponent, bias=15, no NaN/Inf\n    ADDR_U5FLOAT,           // Signed floating point with 5-bit exponent, bias=15\n    ADDR_U3FLOATM,          // Unsigned floating point with 3-bit exponent, bias=3\n\n    ADDR_S5FIXED,           // Signed 5.N-bit fixed point, with rounding\n\n    ADDR_END_NUMBER         // Used for range comparisons\n};\n\n// Copy from legacy lib's AddrElement\nenum ElemMode\n{\n    // These formats allow both packing an unpacking\n    ADDR_ROUND_BY_HALF,      // add 1/2 and truncate when packing this element\n    ADDR_ROUND_TRUNCATE,     // truncate toward 0 for sign/mag, else toward neg\n    ADDR_ROUND_DITHER,       // Pack by dithering -- requires (x,y) position\n\n    // These formats only allow unpacking, no packing\n    ADDR_UNCOMPRESSED,       // Elements are not compressed: one data element per pixel/texel\n    ADDR_EXPANDED,           // Elements are split up and stored in multiple data elements\n    ADDR_PACKED_STD,         // Elements are compressed into ExpandX by ExpandY data elements\n    ADDR_PACKED_REV,         // Like ADDR_PACKED, but X order of pixels is reverved\n    ADDR_PACKED_GBGR,        // Elements are compressed 4:2:2 in G1B_G0R order (high to low)\n    ADDR_PACKED_BGRG,        // Elements are compressed 4:2:2 in BG1_RG0 order (high to low)\n    ADDR_PACKED_BC1,         // Each data element is uncompressed to a 4x4 pixel/texel array\n    ADDR_PACKED_BC2,         // Each data element is uncompressed to a 4x4 pixel/texel array\n    ADDR_PACKED_BC3,         // Each data element is uncompressed to a 4x4 pixel/texel array\n    ADDR_PACKED_BC4,         // Each data element is uncompressed to a 4x4 pixel/texel array\n    ADDR_PACKED_BC5,         // Each data element is uncompressed to a 4x4 pixel/texel array\n    ADDR_PACKED_ETC2_64BPP,  // ETC2 formats that use 64bpp to represent each 4x4 block\n    ADDR_PACKED_ETC2_128BPP, // ETC2 formats that use 128bpp to represent each 4x4 block\n    ADDR_PACKED_ASTC,        // Various ASTC formats, all are 128bpp with varying block sizes\n\n    // These formats provide various kinds of compression\n    ADDR_ZPLANE_R5XX,        // Compressed Zplane using r5xx architecture format\n    ADDR_ZPLANE_R6XX,        // Compressed Zplane using r6xx architecture format\n    //@@ Fill in the compression modes\n\n    ADDR_END_ELEMENT         // Used for range comparisons\n};\n\nenum DepthPlanarType\n{\n    ADDR_DEPTH_PLANAR_NONE = 0, // No plane z/stencl\n    ADDR_DEPTH_PLANAR_R600 = 1, // R600 z and stencil planes are store within a tile\n    ADDR_DEPTH_PLANAR_R800 = 2, // R800 has separate z and stencil planes\n};\n\n/**\n****************************************************************************************************\n*   PixelFormatInfo\n*\n*   @brief\n*       Per component info\n*\n****************************************************************************************************\n*/\nstruct PixelFormatInfo\n{\n    UINT_32             compBit[4];\n    NumberType          numType[4];\n    UINT_32             compStart[4];\n    ElemMode            elemMode;\n    UINT_32             comps;          ///< Number of components\n};\n\n/**\n****************************************************************************************************\n* @brief This class contains asic indepentent element related attributes and operations\n****************************************************************************************************\n*/\nclass ElemLib : public Object\n{\nprotected:\n    ElemLib(Lib* pAddrLib);\n\npublic:\n\n    /// Makes this class virtual\n    virtual ~ElemLib();\n\n    static ElemLib* Create(\n        const Lib* pAddrLib);\n\n    /// The implementation is only for R6xx/R7xx, so make it virtual in case we need for R8xx\n    BOOL_32 PixGetExportNorm(\n        AddrColorFormat colorFmt,\n        AddrSurfaceNumber numberFmt, AddrSurfaceSwap swap) const;\n\n    /// Below method are asic independent, so make them just static.\n    /// Remove static if we need different operation in hwl.\n\n    VOID    Flt32ToDepthPixel(\n        AddrDepthFormat format, const ADDR_FLT_32 comps[2], UINT_8 *pPixel) const;\n\n    VOID    Flt32ToColorPixel(\n        AddrColorFormat format, AddrSurfaceNumber surfNum, AddrSurfaceSwap surfSwap,\n        const ADDR_FLT_32 comps[4], UINT_8 *pPixel) const;\n\n    static VOID    Flt32sToInt32s(\n        ADDR_FLT_32 value, UINT_32 bits, NumberType numberType, UINT_32* pResult);\n\n    static VOID    Int32sToPixel(\n        UINT_32 numComps, UINT_32* pComps, UINT_32* pCompBits, UINT_32* pCompStart,\n        ComponentFlags properties, UINT_32 resultBits, UINT_8* pPixel);\n\n    VOID    PixGetColorCompInfo(\n        AddrColorFormat format, AddrSurfaceNumber number, AddrSurfaceSwap swap,\n        PixelFormatInfo* pInfo) const;\n\n    VOID    PixGetDepthCompInfo(\n        AddrDepthFormat format, PixelFormatInfo* pInfo) const;\n\n    UINT_32 GetBitsPerPixel(\n        AddrFormat format, ElemMode* pElemMode = NULL,\n        UINT_32* pExpandX = NULL, UINT_32* pExpandY = NULL, UINT_32* pBitsUnused = NULL);\n\n    static VOID    SetClearComps(\n        ADDR_FLT_32 comps[4], BOOL_32 clearColor, BOOL_32 float32);\n\n    VOID    AdjustSurfaceInfo(\n        ElemMode elemMode, UINT_32 expandX, UINT_32 expandY,\n        UINT_32* pBpp, UINT_32* pBasePitch, UINT_32* pWidth, UINT_32* pHeight);\n\n    VOID    RestoreSurfaceInfo(\n        ElemMode elemMode, UINT_32 expandX, UINT_32 expandY,\n        UINT_32* pBpp, UINT_32* pWidth, UINT_32* pHeight);\n\n    /// Checks if depth and stencil are planar inside a tile\n    BOOL_32 IsDepthStencilTilePlanar()\n    {\n        return (m_depthPlanarType == ADDR_DEPTH_PLANAR_R600) ? TRUE : FALSE;\n    }\n\n    /// Sets m_configFlags, copied from AddrLib\n    VOID    SetConfigFlags(ConfigFlags flags)\n    {\n        m_configFlags = flags;\n    }\n\n    static BOOL_32 IsCompressed(AddrFormat format);\n    static BOOL_32 IsBlockCompressed(AddrFormat format);\n    static BOOL_32 IsExpand3x(AddrFormat format);\n    static BOOL_32 IsMacroPixelPacked(AddrFormat format);\n\nprotected:\n\n    static VOID    GetCompBits(\n        UINT_32 c0, UINT_32 c1, UINT_32 c2, UINT_32 c3,\n        PixelFormatInfo* pInfo,\n        ElemMode elemMode = ADDR_ROUND_BY_HALF);\n\n    static VOID    GetCompType(\n        AddrColorFormat format, AddrSurfaceNumber numType,\n        PixelFormatInfo* pInfo);\n\n    static VOID    GetCompSwap(\n        AddrSurfaceSwap swap, PixelFormatInfo* pInfo);\n\n    static VOID    SwapComps(\n        UINT_32 c0, UINT_32 c1, PixelFormatInfo* pInfo);\n\nprivate:\n\n    UINT_32             m_fp16ExportNorm;   ///< If allow FP16 to be reported as EXPORT_NORM\n    DepthPlanarType     m_depthPlanarType;\n\n    ConfigFlags         m_configFlags;      ///< Copy of AddrLib's configFlags\n    Addr::Lib* const    m_pAddrLib;         ///< Pointer to parent addrlib instance\n};\n\n} //Addr\n} //namespace rocr\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrlib.cpp\n* @brief Contains the implementation for the Addr::Lib class.\n****************************************************************************************************\n*/\n\n#include \"addrinterface.h\"\n#include \"addrlib.h\"\n#include \"addrcommon.h\"\n\n#if defined(__APPLE__)\n\nUINT_32 div64_32(UINT_64 n, UINT_32 base)\n{\n    UINT_64 rem = n;\n    UINT_64 b = base;\n    UINT_64 res, d = 1;\n    UINT_32 high = rem >> 32;\n\n    res = 0;\n    if (high >= base)\n    {\n        high /= base;\n        res = (UINT_64) high << 32;\n        rem -= (UINT_64) (high * base) << 32;\n    }\n\n    while (((INT_64)b > 0) && (b < rem))\n    {\n        b = b + b;\n        d = d + d;\n    }\n\n    do\n    {\n        if (rem >= b)\n        {\n            rem -= b;\n            res += d;\n        }\n        b >>= 1;\n        d >>= 1;\n    } while (d);\n\n    n = res;\n    return rem;\n}\n\nextern \"C\"\nUINT_32 __umoddi3(UINT_64 n, UINT_32 base)\n{\n    return div64_32(n, base);\n}\n\n#endif // __APPLE__\n\nnamespace rocr {\nnamespace Addr\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Constructor/Destructor\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the AddrLib class\n*\n****************************************************************************************************\n*/\nLib::Lib() :\n    m_chipFamily(ADDR_CHIP_FAMILY_IVLD),\n    m_chipRevision(0),\n    m_version(ADDRLIB_VERSION),\n    m_pipes(0),\n    m_banks(0),\n    m_pipeInterleaveBytes(0),\n    m_rowSize(0),\n    m_minPitchAlignPixels(1),\n    m_maxSamples(8),\n    m_maxBaseAlign(0),\n    m_maxMetaBaseAlign(0),\n    m_pElemLib(NULL)\n{\n    m_configFlags.value = 0;\n}\n\n/**\n****************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the AddrLib class with hClient as parameter\n*\n****************************************************************************************************\n*/\nLib::Lib(const Client* pClient) :\n    Object(pClient),\n    m_chipFamily(ADDR_CHIP_FAMILY_IVLD),\n    m_chipRevision(0),\n    m_version(ADDRLIB_VERSION),\n    m_pipes(0),\n    m_banks(0),\n    m_pipeInterleaveBytes(0),\n    m_rowSize(0),\n    m_minPitchAlignPixels(1),\n    m_maxSamples(8),\n    m_maxBaseAlign(0),\n    m_maxMetaBaseAlign(0),\n    m_pElemLib(NULL)\n{\n    m_configFlags.value = 0;\n}\n\n/**\n****************************************************************************************************\n*   Lib::~AddrLib\n*\n*   @brief\n*       Destructor for the AddrLib class\n*\n****************************************************************************************************\n*/\nLib::~Lib()\n{\n    if (m_pElemLib)\n    {\n        delete m_pElemLib;\n        m_pElemLib = NULL;\n    }\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Initialization/Helper\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Lib::Create\n*\n*   @brief\n*       Creates and initializes AddrLib object.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::Create(\n    const ADDR_CREATE_INPUT* pCreateIn,     ///< [in] pointer to ADDR_CREATE_INPUT\n    ADDR_CREATE_OUTPUT*      pCreateOut)    ///< [out] pointer to ADDR_CREATE_OUTPUT\n{\n    Lib* pLib = NULL;\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pCreateIn->createFlags.fillSizeFields == TRUE)\n    {\n        if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||\n            (pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if ((returnCode == ADDR_OK)                    &&\n        (pCreateIn->callbacks.allocSysMem != NULL) &&\n        (pCreateIn->callbacks.freeSysMem != NULL))\n    {\n        Client client = {\n            pCreateIn->hClient,\n            pCreateIn->callbacks\n        };\n\n        switch (pCreateIn->chipEngine)\n        {\n            case CIASICIDGFXENGINE_ARCTICISLAND:\n                switch (pCreateIn->chipFamily)\n                {\n                    case FAMILY_AI:\n                    case FAMILY_RV:\n                        pLib = Gfx9HwlInit(&client);\n                        break;\n                    case FAMILY_NV:\n                    case FAMILY_VGH:\n                    case FAMILY_RMB:\n                    case FAMILY_RPL:\n                    case FAMILY_MDN:\n                        pLib = Gfx10HwlInit(&client);\n                        break;\n                    case FAMILY_NV3:\n                    case FAMILY_GFX1150:\n                    case FAMILY_GFX1103:\n                        pLib = Gfx11HwlInit(&client);\n                        break;\n                    case FAMILY_GFX12:\n                        pLib = Gfx12HwlInit(&client);\n                        break;\n                    default:\n                        ADDR_ASSERT_ALWAYS();\n                        break;\n                }\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n    }\n    if(pLib == NULL)\n    {\n        returnCode = ADDR_OUTOFMEMORY;\n    }\n    if (pLib != NULL)\n    {\n        BOOL_32 initValid;\n\n        // Pass createFlags to configFlags first since these flags may be overwritten\n        pLib->m_configFlags.noCubeMipSlicesPad  = pCreateIn->createFlags.noCubeMipSlicesPad;\n        pLib->m_configFlags.fillSizeFields      = pCreateIn->createFlags.fillSizeFields;\n        pLib->m_configFlags.useTileIndex        = pCreateIn->createFlags.useTileIndex;\n        pLib->m_configFlags.useCombinedSwizzle  = pCreateIn->createFlags.useCombinedSwizzle;\n        pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;\n        pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;\n        pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;\n        pLib->m_configFlags.forceDccAndTcCompat = pCreateIn->createFlags.forceDccAndTcCompat;\n        pLib->m_configFlags.nonPower2MemConfig  = pCreateIn->createFlags.nonPower2MemConfig;\n        pLib->m_configFlags.enableAltTiling     = pCreateIn->createFlags.enableAltTiling;\n        pLib->m_configFlags.disableLinearOpt    = FALSE;\n\n        pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);\n\n        pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);\n\n        // Global parameters initialized and remaining configFlags bits are set as well\n        initValid = pLib->HwlInitGlobalParams(pCreateIn);\n\n        if (initValid)\n        {\n            pLib->m_pElemLib = ElemLib::Create(pLib);\n        }\n        else\n        {\n            pLib->m_pElemLib = NULL; // Don't go on allocating element lib\n            returnCode = ADDR_INVALIDGBREGVALUES;\n        }\n\n        if (pLib->m_pElemLib == NULL)\n        {\n            delete pLib;\n            pLib = NULL;\n            returnCode = ADDR_OUTOFMEMORY;\n            ADDR_ASSERT_ALWAYS();\n        }\n        else\n        {\n            pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);\n        }\n    }\n\n    pCreateOut->hLib = pLib;\n\n    if ((pLib != NULL) &&\n        (returnCode == ADDR_OK))\n    {\n        pCreateOut->numEquations =\n            pLib->HwlGetEquationTableInfo(&pCreateOut->pEquationTable);\n\n        pLib->SetMaxAlignments();\n\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::SetChipFamily\n*\n*   @brief\n*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision\n*   @return\n*      N/A\n****************************************************************************************************\n*/\nVOID Lib::SetChipFamily(\n    UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h\n    UINT_32 uChipRevision)      ///< [in] chip revision defined in \"asic_family\"_id.h\n{\n    ChipFamily family = HwlConvertChipFamily(uChipFamily, uChipRevision);\n\n    ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);\n\n    m_chipFamily   = family;\n    m_chipRevision = uChipRevision;\n}\n\n/**\n****************************************************************************************************\n*   Lib::SetMinPitchAlignPixels\n*\n*   @brief\n*       Set m_minPitchAlignPixels with input param\n*\n*   @return\n*      N/A\n****************************************************************************************************\n*/\nVOID Lib::SetMinPitchAlignPixels(\n    UINT_32 minPitchAlignPixels)    ///< [in] minmum pitch alignment in pixels\n{\n    m_minPitchAlignPixels = (minPitchAlignPixels == 0) ? 1 : minPitchAlignPixels;\n}\n\n/**\n****************************************************************************************************\n*   Lib::SetMaxAlignments\n*\n*   @brief\n*       Set max alignments\n*\n*   @return\n*      N/A\n****************************************************************************************************\n*/\nVOID Lib::SetMaxAlignments()\n{\n    m_maxBaseAlign     = HwlComputeMaxBaseAlignments();\n    m_maxMetaBaseAlign = HwlComputeMaxMetaBaseAlignments();\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetLib\n*\n*   @brief\n*       Get AddrLib pointer\n*\n*   @return\n*      An AddrLib class pointer\n****************************************************************************************************\n*/\nLib* Lib::GetLib(\n    ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE\n{\n    return static_cast<Addr::Lib*>(hLib);\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetMaxAlignments\n*\n*   @brief\n*       Gets maximum alignments for data surface (include FMask)\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetMaxAlignments(\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        if (m_maxBaseAlign != 0)\n        {\n            pOut->baseAlign = m_maxBaseAlign;\n        }\n        else\n        {\n            returnCode = ADDR_NOTIMPLEMENTED;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetMaxMetaAlignments\n*\n*   @brief\n*       Gets maximum alignments for metadata (CMask, DCC and HTile)\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetMaxMetaAlignments(\n    ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        if (m_maxMetaBaseAlign != 0)\n        {\n            pOut->baseAlign = m_maxMetaBaseAlign;\n        }\n        else\n        {\n            returnCode = ADDR_NOTIMPLEMENTED;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::Bits2Number\n*\n*   @brief\n*       Cat a array of binary bit to a number\n*\n*   @return\n*       The number combined with the array of bits\n****************************************************************************************************\n*/\nUINT_32 Lib::Bits2Number(\n    UINT_32 bitNum,     ///< [in] how many bits\n    ...)                ///< [in] varaible bits value starting from MSB\n{\n    UINT_32 number = 0;\n    UINT_32 i;\n    va_list bits_ptr;\n\n    va_start(bits_ptr, bitNum);\n\n    for(i = 0; i < bitNum; i++)\n    {\n        number |= va_arg(bits_ptr, UINT_32);\n        number <<= 1;\n    }\n\n    number >>= 1;\n\n    va_end(bits_ptr);\n\n    return number;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Element lib\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n****************************************************************************************************\n*   Lib::Flt32ToColorPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a depth/stencil pixel value\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::Flt32ToDepthPixel(\n    const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,\n    ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||\n            (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        GetElemLib()->Flt32ToDepthPixel(pIn->format, pIn->comps, pOut->pPixel);\n\n        UINT_32 depthBase = 0;\n        UINT_32 stencilBase = 0;\n        UINT_32 depthBits = 0;\n        UINT_32 stencilBits = 0;\n\n        switch (pIn->format)\n        {\n            case ADDR_DEPTH_16:\n                depthBits = 16;\n                break;\n            case ADDR_DEPTH_X8_24:\n            case ADDR_DEPTH_8_24:\n            case ADDR_DEPTH_X8_24_FLOAT:\n            case ADDR_DEPTH_8_24_FLOAT:\n                depthBase = 8;\n                depthBits = 24;\n                stencilBits = 8;\n                break;\n            case ADDR_DEPTH_32_FLOAT:\n                depthBits = 32;\n                break;\n            case ADDR_DEPTH_X24_8_32_FLOAT:\n                depthBase = 8;\n                depthBits = 32;\n                stencilBits = 8;\n                break;\n            default:\n                break;\n        }\n\n        // Overwrite base since R800 has no \"tileBase\"\n        if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)\n        {\n            depthBase = 0;\n            stencilBase = 0;\n        }\n\n        depthBase *= 64;\n        stencilBase *= 64;\n\n        pOut->stencilBase = stencilBase;\n        pOut->depthBase = depthBase;\n        pOut->depthBits = depthBits;\n        pOut->stencilBits = stencilBits;\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::Flt32ToColorPixel\n*\n*   @brief\n*       Convert a FLT_32 value to a red/green/blue/alpha pixel value\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::Flt32ToColorPixel(\n    const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,\n    ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||\n            (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        GetElemLib()->Flt32ToColorPixel(pIn->format,\n                                        pIn->surfNum,\n                                        pIn->surfSwap,\n                                        pIn->comps,\n                                        pOut->pPixel);\n    }\n\n    return returnCode;\n}\n\n\n/**\n****************************************************************************************************\n*   Lib::GetExportNorm\n*\n*   @brief\n*       Check one format can be EXPORT_NUM\n*   @return\n*       TRUE if EXPORT_NORM can be used\n****************************************************************************************************\n*/\nBOOL_32 Lib::GetExportNorm(\n    const ELEM_GETEXPORTNORM_INPUT* pIn) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    BOOL_32 enabled = FALSE;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        enabled = GetElemLib()->PixGetExportNorm(pIn->format, pIn->num, pIn->swap);\n    }\n\n    return enabled;\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetBpe\n*\n*   @brief\n*       Get bits-per-element for specified format\n*   @return\n*       bits-per-element of specified format\n****************************************************************************************************\n*/\nUINT_32 Lib::GetBpe(AddrFormat format) const\n{\n    return GetElemLib()->GetBitsPerPixel(format);\n}\n\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addrlib.h\n* @brief Contains the Addr::Lib base class definition.\n****************************************************************************************************\n*/\n\n#ifndef __ADDR_LIB_H__\n#define __ADDR_LIB_H__\n\n#include \"addrinterface.h\"\n#include \"addrtypes.h\"\n#include \"addrobject.h\"\n#include \"addrelemlib.h\"\n\n#include \"amdgpu_asic_addr.h\"\n\n#ifndef CIASICIDGFXENGINE_R600\n#define CIASICIDGFXENGINE_R600 0x00000006\n#endif\n\n#ifndef CIASICIDGFXENGINE_R800\n#define CIASICIDGFXENGINE_R800 0x00000008\n#endif\n\n#ifndef CIASICIDGFXENGINE_SOUTHERNISLAND\n#define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A\n#endif\n\n#ifndef CIASICIDGFXENGINE_ARCTICISLAND\n#define CIASICIDGFXENGINE_ARCTICISLAND 0x0000000D\n#endif\n\nnamespace rocr {\nnamespace Addr\n{\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define pipeinterleave\n****************************************************************************************************\n*/\nenum PipeInterleave\n{\n    ADDR_PIPEINTERLEAVE_256B = 256,\n    ADDR_PIPEINTERLEAVE_512B = 512,\n    ADDR_PIPEINTERLEAVE_1KB  = 1024,\n    ADDR_PIPEINTERLEAVE_2KB  = 2048,\n};\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define DRAM row size\n****************************************************************************************************\n*/\nenum RowSize\n{\n    ADDR_ROWSIZE_1KB = 1024,\n    ADDR_ROWSIZE_2KB = 2048,\n    ADDR_ROWSIZE_4KB = 4096,\n    ADDR_ROWSIZE_8KB = 8192,\n};\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define bank interleave\n****************************************************************************************************\n*/\nenum BankInterleave\n{\n    ADDR_BANKINTERLEAVE_1 = 1,\n    ADDR_BANKINTERLEAVE_2 = 2,\n    ADDR_BANKINTERLEAVE_4 = 4,\n    ADDR_BANKINTERLEAVE_8 = 8,\n};\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define shader engine tile size\n****************************************************************************************************\n*/\nenum ShaderEngineTileSize\n{\n    ADDR_SE_TILESIZE_16 = 16,\n    ADDR_SE_TILESIZE_32 = 32,\n};\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define bank swap size\n****************************************************************************************************\n*/\nenum BankSwapSize\n{\n    ADDR_BANKSWAP_128B = 128,\n    ADDR_BANKSWAP_256B = 256,\n    ADDR_BANKSWAP_512B = 512,\n    ADDR_BANKSWAP_1KB = 1024,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define max compressed fragments config\n****************************************************************************************************\n*/\nenum NumMaxCompressedFragmentsConfig\n{\n    ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS   = 0x00000000,\n    ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS   = 0x00000001,\n    ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS   = 0x00000002,\n    ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS   = 0x00000003,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define num pipes config\n****************************************************************************************************\n*/\nenum NumPipesConfig\n{\n    ADDR_CONFIG_1_PIPE                       = 0x00000000,\n    ADDR_CONFIG_2_PIPE                       = 0x00000001,\n    ADDR_CONFIG_4_PIPE                       = 0x00000002,\n    ADDR_CONFIG_8_PIPE                       = 0x00000003,\n    ADDR_CONFIG_16_PIPE                      = 0x00000004,\n    ADDR_CONFIG_32_PIPE                      = 0x00000005,\n    ADDR_CONFIG_64_PIPE                      = 0x00000006,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define num banks config\n****************************************************************************************************\n*/\nenum NumBanksConfig\n{\n    ADDR_CONFIG_1_BANK                       = 0x00000000,\n    ADDR_CONFIG_2_BANK                       = 0x00000001,\n    ADDR_CONFIG_4_BANK                       = 0x00000002,\n    ADDR_CONFIG_8_BANK                       = 0x00000003,\n    ADDR_CONFIG_16_BANK                      = 0x00000004,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define num rb per shader engine config\n****************************************************************************************************\n*/\nenum NumRbPerShaderEngineConfig\n{\n    ADDR_CONFIG_1_RB_PER_SHADER_ENGINE       = 0x00000000,\n    ADDR_CONFIG_2_RB_PER_SHADER_ENGINE       = 0x00000001,\n    ADDR_CONFIG_4_RB_PER_SHADER_ENGINE       = 0x00000002,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define num shader engines config\n****************************************************************************************************\n*/\nenum NumShaderEnginesConfig\n{\n    ADDR_CONFIG_1_SHADER_ENGINE              = 0x00000000,\n    ADDR_CONFIG_2_SHADER_ENGINE              = 0x00000001,\n    ADDR_CONFIG_4_SHADER_ENGINE              = 0x00000002,\n    ADDR_CONFIG_8_SHADER_ENGINE              = 0x00000003,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define pipe interleave size config\n****************************************************************************************************\n*/\nenum PipeInterleaveSizeConfig\n{\n    ADDR_CONFIG_PIPE_INTERLEAVE_256B         = 0x00000000,\n    ADDR_CONFIG_PIPE_INTERLEAVE_512B         = 0x00000001,\n    ADDR_CONFIG_PIPE_INTERLEAVE_1KB          = 0x00000002,\n    ADDR_CONFIG_PIPE_INTERLEAVE_2KB          = 0x00000003,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define row size config\n****************************************************************************************************\n*/\nenum RowSizeConfig\n{\n    ADDR_CONFIG_1KB_ROW                      = 0x00000000,\n    ADDR_CONFIG_2KB_ROW                      = 0x00000001,\n    ADDR_CONFIG_4KB_ROW                      = 0x00000002,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define bank interleave size config\n****************************************************************************************************\n*/\nenum BankInterleaveSizeConfig\n{\n    ADDR_CONFIG_BANK_INTERLEAVE_1            = 0x00000000,\n    ADDR_CONFIG_BANK_INTERLEAVE_2            = 0x00000001,\n    ADDR_CONFIG_BANK_INTERLEAVE_4            = 0x00000002,\n    ADDR_CONFIG_BANK_INTERLEAVE_8            = 0x00000003,\n};\n\n/**\n****************************************************************************************************\n* @brief Enums that define engine tile size config\n****************************************************************************************************\n*/\nenum ShaderEngineTileSizeConfig\n{\n    ADDR_CONFIG_SE_TILE_16                   = 0x00000000,\n    ADDR_CONFIG_SE_TILE_32                   = 0x00000001,\n};\n\n/**\n****************************************************************************************************\n* @brief This class contains asic independent address lib functionalities\n****************************************************************************************************\n*/\nclass Lib : public Object\n{\npublic:\n    virtual ~Lib();\n\n    static ADDR_E_RETURNCODE Create(\n        const ADDR_CREATE_INPUT* pCreateInfo, ADDR_CREATE_OUTPUT* pCreateOut);\n\n    /// Pair of Create\n    VOID Destroy()\n    {\n        delete this;\n    }\n\n    static Lib* GetLib(ADDR_HANDLE hLib);\n\n    /// Returns AddrLib version (from compiled binary instead include file)\n    UINT_32 GetVersion()\n    {\n        return m_version;\n    }\n\n    /// Returns asic chip family name defined by AddrLib\n    ChipFamily GetChipFamily() const\n    {\n        return m_chipFamily;\n    }\n\n    ADDR_E_RETURNCODE Flt32ToDepthPixel(\n        const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,\n        ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE Flt32ToColorPixel(\n        const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,\n        ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const;\n\n    BOOL_32 GetExportNorm(const ELEM_GETEXPORTNORM_INPUT* pIn) const;\n\n    ADDR_E_RETURNCODE GetMaxAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE GetMaxMetaAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut) const;\n\n    UINT_32 GetBpe(AddrFormat format) const;\n\nprotected:\n    Lib();  // Constructor is protected\n    Lib(const Client* pClient);\n\n    /// Pure virtual function to get max base alignments\n    virtual UINT_32 HwlComputeMaxBaseAlignments() const = 0;\n\n    /// Gets maximum alignements for metadata\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const\n    {\n        ADDR_NOT_IMPLEMENTED();\n\n        return 0;\n    }\n\n    VOID ValidBaseAlignments(UINT_32 alignment) const\n    {\n#if DEBUG\n        ADDR_ASSERT(alignment <= m_maxBaseAlign);\n#endif\n    }\n\n    VOID ValidMetaBaseAlignments(UINT_32 metaAlignment) const\n    {\n#if DEBUG\n        ADDR_ASSERT(metaAlignment <= m_maxMetaBaseAlign);\n#endif\n    }\n\n    static BOOL_32 IsTex1d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_1D);\n    }\n\n    static BOOL_32 IsTex2d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_2D);\n    }\n\n    static BOOL_32 IsTex3d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_3D);\n    }\n\n    //\n    // Initialization\n    //\n    /// Pure Virtual function for Hwl computing internal global parameters from h/w registers\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn) = 0;\n\n    /// Pure Virtual function for Hwl converting chip family\n    virtual ChipFamily HwlConvertChipFamily(UINT_32 uChipFamily, UINT_32 uChipRevision) = 0;\n\n    /// Get equation table pointer and number of equations\n    virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const\n    {\n        *ppEquationTable = NULL;\n\n        return 0;\n    }\n\n    //\n    // Misc helper\n    //\n    static UINT_32 Bits2Number(UINT_32 bitNum, ...);\n\n    static UINT_32 GetNumFragments(UINT_32 numSamples, UINT_32 numFrags)\n    {\n        return (numFrags != 0) ? numFrags : Max(1u, numSamples);\n    }\n\n    /// Returns pointer of ElemLib\n    ElemLib* GetElemLib() const\n    {\n        return m_pElemLib;\n    }\n\n    /// Returns fillSizeFields flag\n    UINT_32 GetFillSizeFieldsFlags() const\n    {\n        return m_configFlags.fillSizeFields;\n    }\n\nprivate:\n    // Disallow the copy constructor\n    Lib(const Lib& a);\n\n    // Disallow the assignment operator\n    Lib& operator=(const Lib& a);\n\n    VOID SetChipFamily(UINT_32 uChipFamily, UINT_32 uChipRevision);\n\n    VOID SetMinPitchAlignPixels(UINT_32 minPitchAlignPixels);\n\n    VOID SetMaxAlignments();\n\nprotected:\n    ChipFamily  m_chipFamily;   ///< Chip family translated from the one in atiid.h\n\n    UINT_32     m_chipRevision; ///< Revision id from xxx_id.h\n\n    UINT_32     m_version;      ///< Current version\n\n    //\n    // Global parameters\n    //\n    ConfigFlags m_configFlags;          ///< Global configuration flags. Note this is setup by\n                                        ///  AddrLib instead of Client except forceLinearAligned\n\n    UINT_32     m_pipes;                ///< Number of pipes\n    UINT_32     m_banks;                ///< Number of banks\n                                        ///  For r800 this is MC_ARB_RAMCFG.NOOFBANK\n                                        ///  Keep it here to do default parameter calculation\n\n    UINT_32     m_pipeInterleaveBytes;\n                                        ///< Specifies the size of contiguous address space\n                                        ///  within each tiling pipe when making linear\n                                        ///  accesses. (Formerly Group Size)\n\n    UINT_32     m_rowSize;              ///< DRAM row size, in bytes\n\n    UINT_32     m_minPitchAlignPixels;  ///< Minimum pitch alignment in pixels\n    UINT_32     m_maxSamples;           ///< Max numSamples\n\n    UINT_32     m_maxBaseAlign;         ///< Max base alignment for data surface\n    UINT_32     m_maxMetaBaseAlign;     ///< Max base alignment for metadata\n\nprivate:\n    ElemLib*    m_pElemLib;             ///< Element Lib pointer\n};\n\nLib* Gfx9HwlInit (const Client* pClient);\nLib* Gfx10HwlInit(const Client* pClient);\nLib* Gfx11HwlInit(const Client* pClient);\nLib* Gfx12HwlInit(const Client* pClient);\n} // Addr\n} // namespace rocr\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib1.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n****************************************************************************************************\n* @file  addr1lib.cpp\n* @brief Contains the implementation for the Addr::V1::Lib base class.\n****************************************************************************************************\n*/\n\n#include \"addrinterface.h\"\n#include \"addrlib1.h\"\n#include \"addrcommon.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V1\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst TileModeFlags Lib::ModeFlags[ADDR_TM_COUNT] =\n{// T   L  1  2  3  P  Pr B\n    {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL\n    {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED\n    {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1\n    {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK\n    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1\n    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2\n    {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4\n    {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK\n    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1\n    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2\n    {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4\n    {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK\n    {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1\n    {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK\n    {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1\n    {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK\n    {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK\n    {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK\n    {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE\n    {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1\n    {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1\n    {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1\n    {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK\n    {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK\n    {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK\n    {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN\n};\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Constructor/Destructor\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Lib::AddrLib1\n*\n*   @brief\n*       Constructor for the AddrLib1 class\n*\n****************************************************************************************************\n*/\nLib::Lib()\n    :\n    Addr::Lib()\n{\n}\n\n/**\n****************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the Addr::V1::Lib class with hClient as parameter\n*\n****************************************************************************************************\n*/\nLib::Lib(const Client* pClient)\n    :\n    Addr::Lib(pClient)\n{\n}\n\n/**\n****************************************************************************************************\n*   Lib::~AddrLib1\n*\n*   @brief\n*       Destructor for the AddrLib1 class\n*\n****************************************************************************************************\n*/\nLib::~Lib()\n{\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetLib\n*\n*   @brief\n*       Get AddrLib1 pointer\n*\n*   @return\n*      An Addr::V1::Lib class pointer\n****************************************************************************************************\n*/\nLib* Lib::GetLib(\n    ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE\n{\n    Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);\n    if ((pAddrLib != NULL) &&\n        ((pAddrLib->GetChipFamily() == ADDR_CHIP_FAMILY_IVLD) ||\n         (pAddrLib->GetChipFamily() > ADDR_CHIP_FAMILY_VI)))\n    {\n        // only valid and pre-VI ASIC can use AddrLib1 function.\n        ADDR_ASSERT_ALWAYS();\n        hLib = NULL;\n    }\n    return static_cast<Lib*>(hLib);\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Surface Methods\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(\n     const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    // We suggest client do sanity check but a check here is also good\n    if (pIn->bpp > 128)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if ((pIn->tileMode == ADDR_TM_UNKNOWN) && (pIn->mipLevel > 0))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    // Thick modes don't support multisample\n    if ((Thickness(pIn->tileMode) > 1) && (pIn->numSamples > 1))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        // Get a local copy of input structure and only reference pIn for unadjusted values\n        ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;\n        ADDR_TILEINFO tileInfoNull = {0};\n\n        if (UseTileInfo())\n        {\n            // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.\n            // Otherwise the default 0's in tileInfoNull are used.\n            if (pIn->pTileInfo)\n            {\n                tileInfoNull = *pIn->pTileInfo;\n            }\n            localIn.pTileInfo  = &tileInfoNull;\n        }\n\n        localIn.numSamples = (pIn->numSamples == 0) ? 1 : pIn->numSamples;\n\n        // Do mipmap check first\n        // If format is BCn, pre-pad dimension to power-of-two according to HWL\n        ComputeMipLevel(&localIn);\n\n        if (m_configFlags.checkLast2DLevel)\n        {\n            // Save this level's original height in pixels\n            pOut->height = pIn->height;\n        }\n\n        UINT_32 expandX = 1;\n        UINT_32 expandY = 1;\n        ElemMode elemMode;\n\n        // Save outputs that may not go through HWL\n        pOut->pixelBits = localIn.bpp;\n        pOut->numSamples = localIn.numSamples;\n        pOut->last2DLevel = FALSE;\n        pOut->tcCompatible = FALSE;\n\n#if !ALT_TEST\n        if (localIn.numSamples > 1)\n        {\n            ADDR_ASSERT(localIn.mipLevel == 0);\n        }\n#endif\n\n        if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion\n        {\n            // Get compression/expansion factors and element mode\n            // (which indicates compression/expansion\n            localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,\n                                                        &elemMode,\n                                                        &expandX,\n                                                        &expandY);\n\n            // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is\n            // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-\n            // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw\n            // restrictions are different.\n            // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround\n            // but we use this flag to skip RestoreSurfaceInfo below\n\n            if ((elemMode == ADDR_EXPANDED) && (expandX > 1))\n            {\n                ADDR_ASSERT(IsLinear(localIn.tileMode));\n            }\n\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &localIn.bpp,\n                                            &localIn.basePitch,\n                                            &localIn.width,\n                                            &localIn.height);\n\n            // Overwrite these parameters if we have a valid format\n        }\n        else if (localIn.bpp != 0)\n        {\n            localIn.width  = (localIn.width != 0) ? localIn.width : 1;\n            localIn.height = (localIn.height != 0) ? localIn.height : 1;\n        }\n        else // Rule out some invalid parameters\n        {\n            ADDR_ASSERT_ALWAYS();\n\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n\n        // Check mipmap after surface expansion\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = PostComputeMipLevel(&localIn, pOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (UseTileIndex(localIn.tileIndex))\n            {\n                // Make sure pTileInfo is not NULL\n                ADDR_ASSERT(localIn.pTileInfo);\n\n                UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);\n\n                INT_32 macroModeIndex = TileIndexNoMacroIndex;\n\n                if (localIn.tileIndex != TileIndexLinearGeneral)\n                {\n                    // Try finding a macroModeIndex\n                    macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,\n                                                              localIn.flags,\n                                                              localIn.bpp,\n                                                              numSamples,\n                                                              localIn.pTileInfo,\n                                                              &localIn.tileMode,\n                                                              &localIn.tileType);\n                }\n\n                // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info\n                if (macroModeIndex == TileIndexNoMacroIndex)\n                {\n                    returnCode = HwlSetupTileCfg(localIn.bpp,\n                                                 localIn.tileIndex, macroModeIndex,\n                                                 localIn.pTileInfo,\n                                                 &localIn.tileMode, &localIn.tileType);\n                }\n                // If macroModeIndex is invalid, then assert this is not macro tiled\n                else if (macroModeIndex == TileIndexInvalid)\n                {\n                    ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));\n                }\n\n                pOut->macroModeIndex = macroModeIndex;\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            localIn.flags.dccPipeWorkaround = localIn.flags.dccCompatible;\n\n            if (localIn.tileMode == ADDR_TM_UNKNOWN)\n            {\n                // HWL layer may override tile mode if necessary\n                HwlSelectTileMode(&localIn);\n            }\n            else\n            {\n                // HWL layer may override tile mode if necessary\n                HwlOverrideTileMode(&localIn);\n\n                // Optimize tile mode if possible\n                OptimizeTileMode(&localIn);\n            }\n        }\n\n        // Call main function to compute surface info\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlComputeSurfaceInfo(&localIn, pOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            // Since bpp might be changed we just pass it through\n            pOut->bpp  = localIn.bpp;\n\n            // Also original width/height/bpp\n            pOut->pixelPitch    = pOut->pitch;\n            pOut->pixelHeight   = pOut->height;\n\n#if DEBUG\n            if (localIn.flags.display)\n            {\n                ADDR_ASSERT((pOut->pitchAlign % 32) == 0);\n            }\n#endif //DEBUG\n\n            if (localIn.format != ADDR_FMT_INVALID)\n            {\n                //\n                // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it\n                // is okay to program texture pitch as HW's mip calculator would multiply 3 first,\n                // then do the appropriate paddings (linear alignment requirement and possible the\n                // nearest power-of-two for mipmaps), which results in the original pitch.\n                //\n                GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                 expandX,\n                                                 expandY,\n                                                 &localIn.bpp,\n                                                 &pOut->pixelPitch,\n                                                 &pOut->pixelHeight);\n            }\n\n            if (localIn.flags.qbStereo)\n            {\n                if (pOut->pStereoInfo)\n                {\n                    ComputeQbStereoInfo(pOut);\n                }\n            }\n\n            if (localIn.flags.volume) // For volume sliceSize equals to all z-slices\n            {\n                pOut->sliceSize = pOut->surfSize;\n            }\n            else // For array: sliceSize is likely to have slice-padding (the last one)\n            {\n                pOut->sliceSize = pOut->surfSize / pOut->depth;\n\n                // array or cubemap\n                if (pIn->numSlices > 1)\n                {\n                    // If this is the last slice then add the padding size to this slice\n                    if (pIn->slice == (pIn->numSlices - 1))\n                    {\n                        pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);\n                    }\n                    else if (m_configFlags.checkLast2DLevel)\n                    {\n                        // Reset last2DLevel flag if this is not the last array slice\n                        pOut->last2DLevel = FALSE;\n                    }\n                }\n            }\n\n            pOut->pitchTileMax = pOut->pitch / 8 - 1;\n            pOut->heightTileMax = pOut->height / 8 - 1;\n            pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;\n        }\n    }\n\n    ValidBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(\n    const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            const ADDR_SURFACE_FLAGS flags = {{0}};\n            UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);\n\n            // Try finding a macroModeIndex\n            INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,\n                                                             flags,\n                                                             input.bpp,\n                                                             numSamples,\n                                                             input.pTileInfo,\n                                                             &input.tileMode,\n                                                             &input.tileType);\n\n            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info\n            if (macroModeIndex == TileIndexNoMacroIndex)\n            {\n                returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,\n                                             input.pTileInfo, &input.tileMode, &input.tileType);\n            }\n            // If macroModeIndex is invalid, then assert this is not macro tiled\n            else if (macroModeIndex == TileIndexInvalid)\n            {\n                ADDR_ASSERT(!IsMacroTiled(input.tileMode));\n            }\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);\n\n            if (returnCode == ADDR_OK)\n            {\n                pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Interface function stub of ComputeSurfaceCoordFromAddr.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(\n    const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n    ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            const ADDR_SURFACE_FLAGS flags = {{0}};\n            UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);\n\n            // Try finding a macroModeIndex\n            INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,\n                                                             flags,\n                                                             input.bpp,\n                                                             numSamples,\n                                                             input.pTileInfo,\n                                                             &input.tileMode,\n                                                             &input.tileType);\n\n            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info\n            if (macroModeIndex == TileIndexNoMacroIndex)\n            {\n                returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,\n                                             input.pTileInfo, &input.tileMode, &input.tileType);\n            }\n            // If macroModeIndex is invalid, then assert this is not macro tiled\n            else if (macroModeIndex == TileIndexInvalid)\n            {\n                ADDR_ASSERT(!IsMacroTiled(input.tileMode));\n            }\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSliceTileSwizzle\n*\n*   @brief\n*       Interface function stub of ComputeSliceTileSwizzle.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSliceTileSwizzle(\n    const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,    ///< [in] input structure\n    ADDR_COMPUTE_SLICESWIZZLE_OUTPUT*       pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_SLICESWIZZLE_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex,\n                                         input.pTileInfo, &input.tileMode);\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ExtractBankPipeSwizzle\n*\n*   @brief\n*       Interface function stub of AddrExtractBankPipeSwizzle.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ExtractBankPipeSwizzle(\n    const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure\n    ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||\n            (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::CombineBankPipeSwizzle\n*\n*   @brief\n*       Interface function stub of AddrCombineBankPipeSwizzle.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::CombineBankPipeSwizzle(\n    const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,    ///< [in] input structure\n    ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT*       pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,\n                                                   pIn->pipeSwizzle,\n                                                   pIn->pTileInfo,\n                                                   pIn->baseAddr,\n                                                   &pOut->tileSwizzle);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeBaseSwizzle\n*\n*   @brief\n*       Interface function stub of AddrCompueBaseSwizzle.\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeBaseSwizzle(\n    const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,\n    ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (IsMacroTiled(pIn->tileMode))\n            {\n                returnCode = HwlComputeBaseSwizzle(pIn, pOut);\n            }\n            else\n            {\n                pOut->tileSwizzle = 0;\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeFmaskInfo\n*\n*   @brief\n*       Interface function stub of ComputeFmaskInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskInfo(\n    const ADDR_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure\n    )\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    // No thick MSAA\n    if (Thickness(pIn->tileMode) > 1)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_FMASK_INFO_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n\n            if (pOut->pTileInfo)\n            {\n                // Use temp tile info for calcalation\n                input.pTileInfo = pOut->pTileInfo;\n            }\n            else\n            {\n                input.pTileInfo = &tileInfoNull;\n            }\n\n            ADDR_SURFACE_FLAGS flags = {{0}};\n            flags.fmask = 1;\n\n            // Try finding a macroModeIndex\n            INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,\n                                                             flags,\n                                                             HwlComputeFmaskBits(pIn, NULL),\n                                                             pIn->numSamples,\n                                                             input.pTileInfo,\n                                                             &input.tileMode);\n\n            // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info\n            if (macroModeIndex == TileIndexNoMacroIndex)\n            {\n                returnCode = HwlSetupTileCfg(0, input.tileIndex, macroModeIndex,\n                                             input.pTileInfo, &input.tileMode);\n            }\n\n            ADDR_ASSERT(macroModeIndex != TileIndexInvalid);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (pIn->numSamples > 1)\n            {\n                returnCode = HwlComputeFmaskInfo(pIn, pOut);\n            }\n            else\n            {\n                memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));\n\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n        }\n    }\n\n    ValidBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of ComputeFmaskAddrFromCoord.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(\n    const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_ASSERT(pIn->numSamples > 1);\n\n        if (pIn->numSamples > 1)\n        {\n            returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);\n        }\n        else\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Interface function stub of ComputeFmaskAddrFromCoord.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(\n    const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure\n    ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut           ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_ASSERT(pIn->numSamples > 1);\n\n        if (pIn->numSamples > 1)\n        {\n            returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);\n        }\n        else\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ConvertTileInfoToHW\n*\n*   @brief\n*       Convert tile info from real value to HW register value in HW layer\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ConvertTileInfoToHW(\n    const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure\n    ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut      ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||\n            (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_CONVERT_TILEINFOTOHW_INPUT input;\n        // if pIn->reverse is TRUE, indices are ignored\n        if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex,\n                                         input.macroModeIndex, input.pTileInfo);\n\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = HwlConvertTileInfoToHW(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ConvertTileIndex\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ConvertTileIndex(\n    const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure\n    ADDR_CONVERT_TILEINDEX_OUTPUT* pOut      ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||\n            (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n\n        returnCode = HwlSetupTileCfg(pIn->bpp, pIn->tileIndex, pIn->macroModeIndex,\n                                     pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);\n\n        if (returnCode == ADDR_OK && pIn->tileInfoHw)\n        {\n            ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};\n            ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};\n\n            hwInput.pTileInfo = pOut->pTileInfo;\n            hwInput.tileIndex = -1;\n            hwOutput.pTileInfo = pOut->pTileInfo;\n\n            returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetMacroModeIndex\n*\n*   @brief\n*       Get macro mode index based on input info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetMacroModeIndex(\n    const ADDR_GET_MACROMODEINDEX_INPUT* pIn, ///< [in] input structure\n    ADDR_GET_MACROMODEINDEX_OUTPUT*      pOut ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags())\n    {\n        if ((pIn->size != sizeof(ADDR_GET_MACROMODEINDEX_INPUT)) ||\n            (pOut->size != sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfo = {0};\n        pOut->macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex, pIn->flags, pIn->bpp,\n                                                        pIn->numFrags, &tileInfo);\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ConvertTileIndex1\n*\n*   @brief\n*       Convert tile index to tile mode/type/info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ConvertTileIndex1(\n    const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,   ///< [in] input structure\n    ADDR_CONVERT_TILEINDEX_OUTPUT* pOut         ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||\n            (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_SURFACE_FLAGS flags = {{0}};\n\n        HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,\n                                 pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);\n\n        if (pIn->tileInfoHw)\n        {\n            ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};\n            ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};\n\n            hwInput.pTileInfo = pOut->pTileInfo;\n            hwInput.tileIndex = -1;\n            hwOutput.pTileInfo = pOut->pTileInfo;\n\n            returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::GetTileIndex\n*\n*   @brief\n*       Get tile index from tile mode/type/info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetTileIndex(\n    const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure\n    ADDR_GET_TILEINDEX_OUTPUT* pOut      ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||\n            (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        returnCode = HwlGetTileIndex(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::Thickness\n*\n*   @brief\n*       Get tile mode thickness\n*\n*   @return\n*       Tile mode thickness\n****************************************************************************************************\n*/\nUINT_32 Lib::Thickness(\n    AddrTileMode tileMode)    ///< [in] tile mode\n{\n    return ModeFlags[tileMode].thickness;\n}\n\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               CMASK/HTILE\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Lib::ComputeHtileInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeHtilenfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileInfo(\n    const ADDR_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;\n    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_HTILE_INFO_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (pIn->flags.tcCompatible)\n            {\n                const UINT_32 sliceSize = pIn->pitch * pIn->height * 4 / (8 * 8);\n                const UINT_32 align     = HwlGetPipes(pIn->pTileInfo) * pIn->pTileInfo->banks * m_pipeInterleaveBytes;\n\n                if (pIn->numSlices > 1)\n                {\n                    const UINT_32 surfBytes = (sliceSize * pIn->numSlices);\n\n                    pOut->sliceSize        = sliceSize;\n                    pOut->htileBytes       = pIn->flags.skipTcCompatSizeAlign ?\n                                             surfBytes : PowTwoAlign(surfBytes, align);\n                    pOut->sliceInterleaved = ((sliceSize % align) != 0) ? TRUE : FALSE;\n                }\n                else\n                {\n                    pOut->sliceSize        = pIn->flags.skipTcCompatSizeAlign ?\n                                             sliceSize : PowTwoAlign(sliceSize, align);\n                    pOut->htileBytes       = pOut->sliceSize;\n                    pOut->sliceInterleaved = FALSE;\n                }\n\n                pOut->nextMipLevelCompressible = ((sliceSize % align) == 0) ? TRUE : FALSE;\n\n                pOut->pitch       = pIn->pitch;\n                pOut->height      = pIn->height;\n                pOut->baseAlign   = align;\n                pOut->macroWidth  = 0;\n                pOut->macroHeight = 0;\n                pOut->bpp         = 32;\n            }\n            else\n            {\n                pOut->bpp = ComputeHtileInfo(pIn->flags,\n                                             pIn->pitch,\n                                             pIn->height,\n                                             pIn->numSlices,\n                                             pIn->isLinear,\n                                             isWidth8,\n                                             isHeight8,\n                                             pIn->pTileInfo,\n                                             &pOut->pitch,\n                                             &pOut->height,\n                                             &pOut->htileBytes,\n                                             &pOut->macroWidth,\n                                             &pOut->macroHeight,\n                                             &pOut->sliceSize,\n                                             &pOut->baseAlign);\n            }\n        }\n    }\n\n    ValidMetaBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskInfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskInfo(\n    const ADDR_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_CMASK_INFO_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            returnCode = ComputeCmaskInfo(pIn->flags,\n                                          pIn->pitch,\n                                          pIn->height,\n                                          pIn->numSlices,\n                                          pIn->isLinear,\n                                          pIn->pTileInfo,\n                                          &pOut->pitch,\n                                          &pOut->height,\n                                          &pOut->cmaskBytes,\n                                          &pOut->macroWidth,\n                                          &pOut->macroHeight,\n                                          &pOut->sliceSize,\n                                          &pOut->baseAlign,\n                                          &pOut->blockMax);\n        }\n    }\n\n    ValidMetaBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeDccInfo\n*\n*   @brief\n*       Interface function to compute DCC key info\n*\n*   @return\n*       return code of HwlComputeDccInfo\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeDccInfo(\n    const ADDR_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))\n        {\n            ret = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (ret == ADDR_OK)\n    {\n        ADDR_COMPUTE_DCCINFO_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n\n            ret = HwlSetupTileCfg(input.bpp, input.tileIndex, input.macroModeIndex,\n                                  &input.tileInfo, &input.tileMode);\n\n            pIn = &input;\n        }\n\n        if (ret == ADDR_OK)\n        {\n            ret = HwlComputeDccInfo(pIn, pOut);\n\n            ValidMetaBaseAlignments(pOut->dccRamBaseAlign);\n        }\n    }\n\n    return ret;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeHtileAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(\n    const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;\n    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (pIn->flags.tcCompatible)\n            {\n                HwlComputeHtileAddrFromCoord(pIn, pOut);\n            }\n            else\n            {\n                pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,\n                                                          pIn->height,\n                                                          pIn->x,\n                                                          pIn->y,\n                                                          pIn->slice,\n                                                          pIn->numSlices,\n                                                          1,\n                                                          pIn->isLinear,\n                                                          isWidth8,\n                                                          isHeight8,\n                                                          pIn->pTileInfo,\n                                                          &pOut->bitPosition);\n            }\n        }\n    }\n\n    return returnCode;\n\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeHtileCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(\n    const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure\n    ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    BOOL_32 isWidth8  = (pIn->blockWidth == 8) ? TRUE : FALSE;\n    BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            HwlComputeXmaskCoordFromAddr(pIn->addr,\n                                         pIn->bitPosition,\n                                         pIn->pitch,\n                                         pIn->height,\n                                         pIn->numSlices,\n                                         1,\n                                         pIn->isLinear,\n                                         isWidth8,\n                                         isHeight8,\n                                         pIn->pTileInfo,\n                                         &pOut->x,\n                                         &pOut->y,\n                                         &pOut->slice);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(\n    const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (pIn->flags.tcCompatible == TRUE)\n            {\n                returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);\n            }\n            else\n            {\n                pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,\n                                                          pIn->height,\n                                                          pIn->x,\n                                                          pIn->y,\n                                                          pIn->slice,\n                                                          pIn->numSlices,\n                                                          2,\n                                                          pIn->isLinear,\n                                                          FALSE, //this is cmask, isWidth8 is not needed\n                                                          FALSE, //this is cmask, isHeight8 is not needed\n                                                          pIn->pTileInfo,\n                                                          &pOut->bitPosition);\n            }\n\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(\n    const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure\n    ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||\n            (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        ADDR_TILEINFO tileInfoNull;\n        ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;\n\n        if (UseTileIndex(pIn->tileIndex))\n        {\n            input = *pIn;\n            // Use temp tile info for calcalation\n            input.pTileInfo = &tileInfoNull;\n\n            returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);\n\n            // Change the input structure\n            pIn = &input;\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            HwlComputeXmaskCoordFromAddr(pIn->addr,\n                                         pIn->bitPosition,\n                                         pIn->pitch,\n                                         pIn->height,\n                                         pIn->numSlices,\n                                         2,\n                                         pIn->isLinear,\n                                         FALSE,\n                                         FALSE,\n                                         pIn->pTileInfo,\n                                         &pOut->x,\n                                         &pOut->y,\n                                         &pOut->slice);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeTileDataWidthAndHeight\n*\n*   @brief\n*       Compute the squared cache shape for per-tile data (CMASK and HTILE)\n*\n*   @return\n*       N/A\n*\n*   @note\n*       MacroWidth and macroHeight are measured in pixels\n****************************************************************************************************\n*/\nVOID Lib::ComputeTileDataWidthAndHeight(\n    UINT_32         bpp,             ///< [in] bits per pixel\n    UINT_32         cacheBits,       ///< [in] bits of cache\n    ADDR_TILEINFO*  pTileInfo,       ///< [in] Tile info\n    UINT_32*        pMacroWidth,     ///< [out] macro tile width\n    UINT_32*        pMacroHeight     ///< [out] macro tile height\n    ) const\n{\n    UINT_32 height = 1;\n    UINT_32 width  = cacheBits / bpp;\n    UINT_32 pipes  = HwlGetPipes(pTileInfo);\n\n    // Double height until the macro-tile is close to square\n    // Height can only be doubled if width is even\n\n    while ((width > height * 2 * pipes) && !(width & 1))\n    {\n        width  /= 2;\n        height *= 2;\n    }\n\n    *pMacroWidth  = 8 * width;\n    *pMacroHeight = 8 * height * pipes;\n\n    // Note: The above iterative comptuation is equivalent to the following\n    //\n    //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);\n    //int macroHeight = pow2( 3+log2(pipes)+log2_height );\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlComputeTileDataWidthAndHeightLinear\n*\n*   @brief\n*       Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout\n*\n*   @return\n*       N/A\n*\n*   @note\n*       MacroWidth and macroHeight are measured in pixels\n****************************************************************************************************\n*/\nVOID Lib::HwlComputeTileDataWidthAndHeightLinear(\n    UINT_32*        pMacroWidth,     ///< [out] macro tile width\n    UINT_32*        pMacroHeight,    ///< [out] macro tile height\n    UINT_32         bpp,             ///< [in] bits per pixel\n    ADDR_TILEINFO*  pTileInfo        ///< [in] tile info\n    ) const\n{\n    ADDR_ASSERT(bpp != 4);              // Cmask does not support linear layout prior to SI\n    *pMacroWidth  = 8 * 512 / bpp;      // Align width to 512-bit memory accesses\n    *pMacroHeight = 8 * m_pipes;        // Align height to number of pipes\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeHtileInfo\n*\n*   @brief\n*       Compute htile pitch,width, bytes per 2D slice\n*\n*   @return\n*       Htile bpp i.e. How many bits for an 8x8 tile\n*       Also returns by output parameters:\n*       *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*\n****************************************************************************************************\n*/\nUINT_32 Lib::ComputeHtileInfo(\n    ADDR_HTILE_FLAGS flags,             ///< [in] htile flags\n    UINT_32          pitchIn,           ///< [in] pitch input\n    UINT_32          heightIn,          ///< [in] height input\n    UINT_32          numSlices,         ///< [in] number of slices\n    BOOL_32          isLinear,          ///< [in] if it is linear mode\n    BOOL_32          isWidth8,          ///< [in] if htile block width is 8\n    BOOL_32          isHeight8,         ///< [in] if htile block height is 8\n    ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info\n    UINT_32*         pPitchOut,         ///< [out] pitch output\n    UINT_32*         pHeightOut,        ///< [out] height output\n    UINT_64*         pHtileBytes,       ///< [out] bytes per 2D slice\n    UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels\n    UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels\n    UINT_64*         pSliceSize,        ///< [out] slice size in bytes\n    UINT_32*         pBaseAlign         ///< [out] base alignment\n    ) const\n{\n\n    UINT_32 macroWidth;\n    UINT_32 macroHeight;\n    UINT_32 baseAlign;\n    UINT_64 surfBytes;\n    UINT_64 sliceBytes;\n\n    numSlices = Max(1u, numSlices);\n\n    const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);\n    const UINT_32 cacheBits = HtileCacheBits;\n\n    if (isLinear)\n    {\n        HwlComputeTileDataWidthAndHeightLinear(&macroWidth,\n                                               &macroHeight,\n                                               bpp,\n                                               pTileInfo);\n    }\n    else\n    {\n        ComputeTileDataWidthAndHeight(bpp,\n                                      cacheBits,\n                                      pTileInfo,\n                                      &macroWidth,\n                                      &macroHeight);\n    }\n\n    *pPitchOut = PowTwoAlign(pitchIn,  macroWidth);\n    *pHeightOut = PowTwoAlign(heightIn,  macroHeight);\n\n    baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);\n\n    surfBytes = HwlComputeHtileBytes(*pPitchOut,\n                                     *pHeightOut,\n                                     bpp,\n                                     isLinear,\n                                     numSlices,\n                                     &sliceBytes,\n                                     baseAlign);\n\n    *pHtileBytes = surfBytes;\n\n    //\n    // Use SafeAssign since they are optional\n    //\n    SafeAssign(pMacroWidth, macroWidth);\n\n    SafeAssign(pMacroHeight, macroHeight);\n\n    SafeAssign(pSliceSize,  sliceBytes);\n\n    SafeAssign(pBaseAlign, baseAlign);\n\n    return bpp;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskBaseAlign\n*\n*   @brief\n*       Compute cmask base alignment\n*\n*   @return\n*       Cmask base alignment\n****************************************************************************************************\n*/\nUINT_32 Lib::ComputeCmaskBaseAlign(\n    ADDR_CMASK_FLAGS flags,           ///< [in] Cmask flags\n    ADDR_TILEINFO*   pTileInfo        ///< [in] Tile info\n    ) const\n{\n    UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);\n\n    if (flags.tcCompatible)\n    {\n        ADDR_ASSERT(pTileInfo != NULL);\n        if (pTileInfo)\n        {\n            baseAlign *= pTileInfo->banks;\n        }\n    }\n\n    return baseAlign;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskBytes\n*\n*   @brief\n*       Compute cmask size in bytes\n*\n*   @return\n*       Cmask size in bytes\n****************************************************************************************************\n*/\nUINT_64 Lib::ComputeCmaskBytes(\n    UINT_32 pitch,        ///< [in] pitch\n    UINT_32 height,       ///< [in] height\n    UINT_32 numSlices     ///< [in] number of slices\n    ) const\n{\n    return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /\n        MicroTilePixels;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeCmaskInfo\n*\n*   @brief\n*       Compute cmask pitch,width, bytes per 2D slice\n*\n*   @return\n*       BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,\n*       macro-tile dimensions\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskInfo(\n    ADDR_CMASK_FLAGS flags,            ///< [in] cmask flags\n    UINT_32          pitchIn,           ///< [in] pitch input\n    UINT_32          heightIn,          ///< [in] height input\n    UINT_32          numSlices,         ///< [in] number of slices\n    BOOL_32          isLinear,          ///< [in] is linear mode\n    ADDR_TILEINFO*   pTileInfo,         ///< [in] Tile info\n    UINT_32*         pPitchOut,         ///< [out] pitch output\n    UINT_32*         pHeightOut,        ///< [out] height output\n    UINT_64*         pCmaskBytes,       ///< [out] bytes per 2D slice\n    UINT_32*         pMacroWidth,       ///< [out] macro-tile width in pixels\n    UINT_32*         pMacroHeight,      ///< [out] macro-tile width in pixels\n    UINT_64*         pSliceSize,        ///< [out] slice size in bytes\n    UINT_32*         pBaseAlign,        ///< [out] base alignment\n    UINT_32*         pBlockMax          ///< [out] block max == slice / 128 / 128 - 1\n    ) const\n{\n    UINT_32 macroWidth;\n    UINT_32 macroHeight;\n    UINT_32 baseAlign;\n    UINT_64 surfBytes;\n    UINT_64 sliceBytes;\n\n    numSlices = Max(1u, numSlices);\n\n    const UINT_32 bpp = CmaskElemBits;\n    const UINT_32 cacheBits = CmaskCacheBits;\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (isLinear)\n    {\n        HwlComputeTileDataWidthAndHeightLinear(&macroWidth,\n                                               &macroHeight,\n                                               bpp,\n                                               pTileInfo);\n    }\n    else\n    {\n        ComputeTileDataWidthAndHeight(bpp,\n                                      cacheBits,\n                                      pTileInfo,\n                                      &macroWidth,\n                                      &macroHeight);\n    }\n\n    *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);\n    *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);\n\n\n    sliceBytes = ComputeCmaskBytes(*pPitchOut,\n                                   *pHeightOut,\n                                   1);\n\n    baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);\n\n    while (sliceBytes % baseAlign)\n    {\n        *pHeightOut += macroHeight;\n\n        sliceBytes = ComputeCmaskBytes(*pPitchOut,\n                                       *pHeightOut,\n                                       1);\n    }\n\n    surfBytes = sliceBytes * numSlices;\n\n    *pCmaskBytes = surfBytes;\n\n    //\n    // Use SafeAssign since they are optional\n    //\n    SafeAssign(pMacroWidth, macroWidth);\n\n    SafeAssign(pMacroHeight, macroHeight);\n\n    SafeAssign(pBaseAlign, baseAlign);\n\n    SafeAssign(pSliceSize, sliceBytes);\n\n    UINT_32 slice = (*pPitchOut) * (*pHeightOut);\n    UINT_32 blockMax = slice / 128 / 128 - 1;\n\n#if DEBUG\n    if (slice % (64*256) != 0)\n    {\n        ADDR_ASSERT_ALWAYS();\n    }\n#endif //DEBUG\n\n    UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();\n\n    if (blockMax > maxBlockMax)\n    {\n        blockMax = maxBlockMax;\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    SafeAssign(pBlockMax, blockMax);\n\n    return returnCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeXmaskCoordYFromPipe\n*\n*   @brief\n*       Compute the Y coord from pipe number for cmask/htile\n*\n*   @return\n*       Y coordinate\n*\n****************************************************************************************************\n*/\nUINT_32 Lib::ComputeXmaskCoordYFromPipe(\n    UINT_32         pipe,       ///< [in] pipe number\n    UINT_32         x           ///< [in] x coordinate\n    ) const\n{\n    UINT_32 pipeBit0;\n    UINT_32 pipeBit1;\n    UINT_32 xBit0;\n    UINT_32 xBit1;\n    UINT_32 yBit0;\n    UINT_32 yBit1;\n\n    UINT_32 y = 0;\n\n    UINT_32 numPipes = m_pipes; // SI has its implementation\n    //\n    // Convert pipe + x to y coordinate.\n    //\n    switch (numPipes)\n    {\n        case 1:\n            //\n            // 1 pipe\n            //\n            // p0 = 0\n            //\n            y = 0;\n            break;\n        case 2:\n            //\n            // 2 pipes\n            //\n            // p0 = x0 ^ y0\n            //\n            // y0 = p0 ^ x0\n            //\n            pipeBit0 = pipe & 0x1;\n\n            xBit0 = x & 0x1;\n\n            yBit0 = pipeBit0 ^ xBit0;\n\n            y = yBit0;\n            break;\n        case 4:\n            //\n            // 4 pipes\n            //\n            // p0 = x1 ^ y0\n            // p1 = x0 ^ y1\n            //\n            // y0 = p0 ^ x1\n            // y1 = p1 ^ x0\n            //\n            pipeBit0 =  pipe & 0x1;\n            pipeBit1 = (pipe & 0x2) >> 1;\n\n            xBit0 =  x & 0x1;\n            xBit1 = (x & 0x2) >> 1;\n\n            yBit0 = pipeBit0 ^ xBit1;\n            yBit1 = pipeBit1 ^ xBit0;\n\n            y = (yBit0 |\n                 (yBit1 << 1));\n            break;\n        case 8:\n            //\n            // 8 pipes\n            //\n            // r600 and r800 have different method\n            //\n            y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);\n            break;\n        default:\n            break;\n    }\n    return y;\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlComputeXmaskCoordFromAddr\n*\n*   @brief\n*       Compute the coord from an address of a cmask/htile\n*\n*   @return\n*       N/A\n*\n*   @note\n*       This method is reused by htile, so rename to Xmask\n****************************************************************************************************\n*/\nVOID Lib::HwlComputeXmaskCoordFromAddr(\n    UINT_64         addr,           ///< [in] address\n    UINT_32         bitPosition,    ///< [in] bitPosition in a byte\n    UINT_32         pitch,          ///< [in] pitch\n    UINT_32         height,         ///< [in] height\n    UINT_32         numSlices,      ///< [in] number of slices\n    UINT_32         factor,         ///< [in] factor that indicates cmask or htile\n    BOOL_32         isLinear,       ///< [in] linear or tiled HTILE layout\n    BOOL_32         isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value\n    BOOL_32         isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value\n    ADDR_TILEINFO*  pTileInfo,      ///< [in] Tile info\n    UINT_32*        pX,             ///< [out] x coord\n    UINT_32*        pY,             ///< [out] y coord\n    UINT_32*        pSlice          ///< [out] slice index\n    ) const\n{\n    UINT_32 pipe;\n    UINT_32 numPipes;\n    UINT_32 numGroupBits;\n    UINT_32 numPipeBits;\n    UINT_32 macroTilePitch;\n    UINT_32 macroTileHeight;\n\n    UINT_64 bitAddr;\n\n    UINT_32 microTileCoordY;\n\n    UINT_32 elemBits;\n\n    UINT_32 pitchAligned = pitch;\n    UINT_32 heightAligned = height;\n    UINT_64 totalBytes;\n\n    UINT_64 elemOffset;\n\n    UINT_64 macroIndex;\n    UINT_32 microIndex;\n\n    UINT_64 macroNumber;\n    UINT_32 microNumber;\n\n    UINT_32 macroX;\n    UINT_32 macroY;\n    UINT_32 macroZ;\n\n    UINT_32 microX;\n    UINT_32 microY;\n\n    UINT_32 tilesPerMacro;\n    UINT_32 macrosPerPitch;\n    UINT_32 macrosPerSlice;\n\n    //\n    // Extract pipe.\n    //\n    numPipes = HwlGetPipes(pTileInfo);\n    pipe = ComputePipeFromAddr(addr, numPipes);\n\n    //\n    // Compute the number of group and pipe bits.\n    //\n    numGroupBits = Log2(m_pipeInterleaveBytes);\n    numPipeBits  = Log2(numPipes);\n\n    UINT_32 groupBits = 8 * m_pipeInterleaveBytes;\n    UINT_32 pipes = numPipes;\n\n\n    //\n    // Compute the micro tile size, in bits. And macro tile pitch and height.\n    //\n    if (factor == 2) //CMASK\n    {\n        ADDR_CMASK_FLAGS flags = {{0}};\n\n        elemBits = CmaskElemBits;\n\n        ComputeCmaskInfo(flags,\n                         pitch,\n                         height,\n                         numSlices,\n                         isLinear,\n                         pTileInfo,\n                         &pitchAligned,\n                         &heightAligned,\n                         &totalBytes,\n                         &macroTilePitch,\n                         &macroTileHeight);\n    }\n    else  //HTILE\n    {\n        ADDR_HTILE_FLAGS flags = {{0}};\n\n        if (factor != 1)\n        {\n            factor = 1;\n        }\n\n        elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);\n\n        ComputeHtileInfo(flags,\n                         pitch,\n                         height,\n                         numSlices,\n                         isLinear,\n                         isWidth8,\n                         isHeight8,\n                         pTileInfo,\n                         &pitchAligned,\n                         &heightAligned,\n                         &totalBytes,\n                         &macroTilePitch,\n                         &macroTileHeight);\n    }\n\n    // Should use aligned dims\n    //\n    pitch = pitchAligned;\n    height = heightAligned;\n\n\n    //\n    // Convert byte address to bit address.\n    //\n    bitAddr = BYTES_TO_BITS(addr) + bitPosition;\n\n\n    //\n    // Remove pipe bits from address.\n    //\n\n    bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);\n\n\n    elemOffset = bitAddr / elemBits;\n\n    tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;\n\n    macrosPerPitch = pitch / (macroTilePitch/factor);\n    macrosPerSlice = macrosPerPitch * height / macroTileHeight;\n\n    macroIndex = elemOffset / factor / tilesPerMacro;\n    microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));\n\n    macroNumber = macroIndex * factor + microIndex % factor;\n    microNumber = microIndex / factor;\n\n    macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));\n    macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);\n    macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));\n\n\n    microX = microNumber % (macroTilePitch / factor / MicroTileWidth);\n    microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));\n\n    *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;\n    *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);\n    *pSlice = macroZ;\n\n    microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,\n                                                 *pX/MicroTileWidth);\n\n\n    //\n    // Assemble final coordinates.\n    //\n    *pY += microTileCoordY * MicroTileHeight;\n\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlComputeXmaskAddrFromCoord\n*\n*   @brief\n*       Compute the address from an address of cmask (prior to si)\n*\n*   @return\n*       Address in bytes\n*\n****************************************************************************************************\n*/\nUINT_64 Lib::HwlComputeXmaskAddrFromCoord(\n    UINT_32        pitch,          ///< [in] pitch\n    UINT_32        height,         ///< [in] height\n    UINT_32        x,              ///< [in] x coord\n    UINT_32        y,              ///< [in] y coord\n    UINT_32        slice,          ///< [in] slice/depth index\n    UINT_32        numSlices,      ///< [in] number of slices\n    UINT_32        factor,         ///< [in] factor that indicates cmask(2) or htile(1)\n    BOOL_32        isLinear,       ///< [in] linear or tiled HTILE layout\n    BOOL_32        isWidth8,       ///< [in] TRUE if width is 8, FALSE means 4. It's register value\n    BOOL_32        isHeight8,      ///< [in] TRUE if width is 8, FALSE means 4. It's register value\n    ADDR_TILEINFO* pTileInfo,      ///< [in] Tile info\n    UINT_32*       pBitPosition    ///< [out] bit position inside a byte\n    ) const\n{\n    UINT_64 addr;\n    UINT_32 numGroupBits;\n    UINT_32 numPipeBits;\n    UINT_32 newPitch = 0;\n    UINT_32 newHeight = 0;\n    UINT_64 sliceBytes = 0;\n    UINT_64 totalBytes = 0;\n    UINT_64 sliceOffset;\n    UINT_32 pipe;\n    UINT_32 macroTileWidth;\n    UINT_32 macroTileHeight;\n    UINT_32 macroTilesPerRow;\n    UINT_32 macroTileBytes;\n    UINT_32 macroTileIndexX;\n    UINT_32 macroTileIndexY;\n    UINT_64 macroTileOffset;\n    UINT_32 pixelBytesPerRow;\n    UINT_32 pixelOffsetX;\n    UINT_32 pixelOffsetY;\n    UINT_32 pixelOffset;\n    UINT_64 totalOffset;\n    UINT_64 offsetLo;\n    UINT_64 offsetHi;\n    UINT_64 groupMask;\n\n\n    UINT_32 elemBits = 0;\n\n    UINT_32 numPipes = m_pipes; // This function is accessed prior to si only\n\n    if (factor == 2) //CMASK\n    {\n        elemBits = CmaskElemBits;\n\n        // For asics before SI, cmask is always tiled\n        isLinear = FALSE;\n    }\n    else //HTILE\n    {\n        if (factor != 1) // Fix compile warning\n        {\n            factor = 1;\n        }\n\n        elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);\n    }\n\n    //\n    // Compute the number of group bits and pipe bits.\n    //\n    numGroupBits = Log2(m_pipeInterleaveBytes);\n    numPipeBits  = Log2(numPipes);\n\n    //\n    // Compute macro tile dimensions.\n    //\n    if (factor == 2) // CMASK\n    {\n        ADDR_CMASK_FLAGS flags = {{0}};\n\n        ComputeCmaskInfo(flags,\n                         pitch,\n                         height,\n                         numSlices,\n                         isLinear,\n                         pTileInfo,\n                         &newPitch,\n                         &newHeight,\n                         &totalBytes,\n                         &macroTileWidth,\n                         &macroTileHeight);\n\n        sliceBytes = totalBytes / numSlices;\n    }\n    else // HTILE\n    {\n        ADDR_HTILE_FLAGS flags = {{0}};\n\n        ComputeHtileInfo(flags,\n                         pitch,\n                         height,\n                         numSlices,\n                         isLinear,\n                         isWidth8,\n                         isHeight8,\n                         pTileInfo,\n                         &newPitch,\n                         &newHeight,\n                         &totalBytes,\n                         &macroTileWidth,\n                         &macroTileHeight,\n                         &sliceBytes);\n    }\n\n    sliceOffset = slice * sliceBytes;\n\n    //\n    // Get the pipe.  Note that neither slice rotation nor pipe swizzling apply for CMASK.\n    //\n    pipe = ComputePipeFromCoord(x,\n                                y,\n                                0,\n                                ADDR_TM_2D_TILED_THIN1,\n                                0,\n                                FALSE,\n                                pTileInfo);\n\n    //\n    // Compute the number of macro tiles per row.\n    //\n    macroTilesPerRow = newPitch / macroTileWidth;\n\n    //\n    // Compute the number of bytes per macro tile.\n    //\n    macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);\n\n    //\n    // Compute the offset to the macro tile containing the specified coordinate.\n    //\n    macroTileIndexX = x / macroTileWidth;\n    macroTileIndexY = y / macroTileHeight;\n    macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;\n\n    //\n    // Compute the pixel offset within the macro tile.\n    //\n    pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;\n\n    //\n    // The nibbles are interleaved (see below), so the part of the offset relative to the x\n    // coordinate repeats halfway across the row. (Not for HTILE)\n    //\n    if (factor == 2)\n    {\n        pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;\n    }\n    else\n    {\n        pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);\n    }\n\n    //\n    // Compute the y offset within the macro tile.\n    //\n    pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;\n\n    pixelOffset = pixelOffsetX + pixelOffsetY;\n\n    //\n    // Combine the slice offset and macro tile offset with the pixel offset, accounting for the\n    // pipe bits in the middle of the address.\n    //\n    totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;\n\n    //\n    // Split the offset to put some bits below the pipe bits and some above.\n    //\n    groupMask = (1 << numGroupBits) - 1;\n    offsetLo  = totalOffset &  groupMask;\n    offsetHi  = (totalOffset & ~groupMask) << numPipeBits;\n\n    //\n    // Assemble the address from its components.\n    //\n    addr  = offsetLo;\n    addr |= offsetHi;\n    // This is to remove warning with /analyze option\n    UINT_32 pipeBits = pipe << numGroupBits;\n    addr |= pipeBits;\n\n    //\n    // Compute the bit position.  The lower nibble is used when the x coordinate within the macro\n    // tile is less than half of the macro tile width, and the upper nibble is used when the x\n    // coordinate within the macro tile is greater than or equal to half the macro tile width.\n    //\n    *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;\n\n    return addr;\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Surface Addressing Shared\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoordLinear\n*\n*   @brief\n*       Compute address from coord for linear surface\n*\n*   @return\n*       Address in bytes\n*\n****************************************************************************************************\n*/\nUINT_64 Lib::ComputeSurfaceAddrFromCoordLinear(\n    UINT_32  x,              ///< [in] x coord\n    UINT_32  y,              ///< [in] y coord\n    UINT_32  slice,          ///< [in] slice/depth index\n    UINT_32  sample,         ///< [in] sample index\n    UINT_32  bpp,            ///< [in] bits per pixel\n    UINT_32  pitch,          ///< [in] pitch\n    UINT_32  height,         ///< [in] height\n    UINT_32  numSlices,      ///< [in] number of slices\n    UINT_32* pBitPosition    ///< [out] bit position inside a byte\n    ) const\n{\n    const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;\n\n    UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;\n    UINT_64 rowOffset   = static_cast<UINT_64>(y) * pitch;\n    UINT_64 pixOffset   = x;\n\n    UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;\n\n    *pBitPosition = static_cast<UINT_32>(addr % 8);\n    addr /= 8;\n\n    return addr;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddrLinear\n*\n*   @brief\n*       Compute the coord from an address of a linear surface\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID Lib::ComputeSurfaceCoordFromAddrLinear(\n    UINT_64  addr,           ///< [in] address\n    UINT_32  bitPosition,    ///< [in] bitPosition in a byte\n    UINT_32  bpp,            ///< [in] bits per pixel\n    UINT_32  pitch,          ///< [in] pitch\n    UINT_32  height,         ///< [in] height\n    UINT_32  numSlices,      ///< [in] number of slices\n    UINT_32* pX,             ///< [out] x coord\n    UINT_32* pY,             ///< [out] y coord\n    UINT_32* pSlice,         ///< [out] slice/depth index\n    UINT_32* pSample         ///< [out] sample index\n    ) const\n{\n    const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;\n    const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;\n\n    *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);\n    *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);\n    *pSlice  = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);\n    *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddrMicroTiled\n*\n*   @brief\n*       Compute the coord from an address of a micro tiled surface\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID Lib::ComputeSurfaceCoordFromAddrMicroTiled(\n    UINT_64         addr,               ///< [in] address\n    UINT_32         bitPosition,        ///< [in] bitPosition in a byte\n    UINT_32         bpp,                ///< [in] bits per pixel\n    UINT_32         pitch,              ///< [in] pitch\n    UINT_32         height,             ///< [in] height\n    UINT_32         numSamples,         ///< [in] number of samples\n    AddrTileMode    tileMode,           ///< [in] tile mode\n    UINT_32         tileBase,           ///< [in] base offset within a tile\n    UINT_32         compBits,           ///< [in] component bits actually needed(for planar surface)\n    UINT_32*        pX,                 ///< [out] x coord\n    UINT_32*        pY,                 ///< [out] y coord\n    UINT_32*        pSlice,             ///< [out] slice/depth index\n    UINT_32*        pSample,            ///< [out] sample index,\n    AddrTileType    microTileType,      ///< [in] micro tiling order\n    BOOL_32         isDepthSampleOrder  ///< [in] TRUE if in depth sample order\n    ) const\n{\n    UINT_64 bitAddr;\n    UINT_32 microTileThickness;\n    UINT_32 microTileBits;\n    UINT_64 sliceBits;\n    UINT_64 rowBits;\n    UINT_32 sliceIndex;\n    UINT_32 microTileCoordX;\n    UINT_32 microTileCoordY;\n    UINT_32 pixelOffset;\n    UINT_32 pixelCoordX = 0;\n    UINT_32 pixelCoordY = 0;\n    UINT_32 pixelCoordZ = 0;\n    UINT_32 pixelCoordS = 0;\n\n    //\n    // Convert byte address to bit address.\n    //\n    bitAddr = BYTES_TO_BITS(addr) + bitPosition;\n\n    //\n    // Compute the micro tile size, in bits.\n    //\n    switch (tileMode)\n    {\n        case ADDR_TM_1D_TILED_THICK:\n            microTileThickness = ThickTileThickness;\n            break;\n        default:\n            microTileThickness = 1;\n            break;\n    }\n\n    microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;\n\n    //\n    // Compute number of bits per slice and number of bits per row of micro tiles.\n    //\n    sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;\n\n    rowBits   = (pitch / MicroTileWidth) * microTileBits;\n\n    //\n    // Extract the slice index.\n    //\n    sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);\n    bitAddr -= sliceIndex * sliceBits;\n\n    //\n    // Extract the y coordinate of the micro tile.\n    //\n    microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;\n    bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;\n\n    //\n    // Extract the x coordinate of the micro tile.\n    //\n    microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;\n\n    //\n    // Compute the pixel offset within the micro tile.\n    //\n    pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);\n\n    //\n    // Extract pixel coordinates from the offset.\n    //\n    HwlComputePixelCoordFromOffset(pixelOffset,\n                                   bpp,\n                                   numSamples,\n                                   tileMode,\n                                   tileBase,\n                                   compBits,\n                                   &pixelCoordX,\n                                   &pixelCoordY,\n                                   &pixelCoordZ,\n                                   &pixelCoordS,\n                                   microTileType,\n                                   isDepthSampleOrder);\n\n    //\n    // Assemble final coordinates.\n    //\n    *pX     = microTileCoordX + pixelCoordX;\n    *pY     = microTileCoordY + pixelCoordY;\n    *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;\n    *pSample = pixelCoordS;\n\n    if (microTileThickness > 1)\n    {\n        *pSample = 0;\n    }\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputePipeFromAddr\n*\n*   @brief\n*       Compute the pipe number from an address\n*\n*   @return\n*       Pipe number\n*\n****************************************************************************************************\n*/\nUINT_32 Lib::ComputePipeFromAddr(\n    UINT_64 addr,        ///< [in] address\n    UINT_32 numPipes     ///< [in] number of banks\n    ) const\n{\n    UINT_32 pipe;\n\n    UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms\n\n    // R600\n    // The LSBs of the address are arranged as follows:\n    //   bank | pipe | group\n    //\n    // To get the pipe number, shift off the group bits and mask the pipe bits.\n    //\n\n    // R800\n    // The LSBs of the address are arranged as follows:\n    //   bank | bankInterleave | pipe | pipeInterleave\n    //\n    // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.\n    //\n\n    pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);\n\n    return pipe;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeMicroTileEquation\n*\n*   @brief\n*       Compute micro tile equation\n*\n*   @return\n*       If equation can be computed\n*\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeMicroTileEquation(\n    UINT_32         log2BytesPP,    ///< [in] log2 of bytes per pixel\n    AddrTileMode    tileMode,       ///< [in] tile mode\n    AddrTileType    microTileType,  ///< [in] pixel order in display/non-display mode\n    ADDR_EQUATION*  pEquation       ///< [out] equation\n    ) const\n{\n    ADDR_E_RETURNCODE retCode = ADDR_OK;\n\n    for (UINT_32 i = 0; i < log2BytesPP; i++)\n    {\n        pEquation->addr[i].valid = 1;\n        pEquation->addr[i].channel = 0;\n        pEquation->addr[i].index = i;\n    }\n\n    ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[log2BytesPP];\n\n    ADDR_CHANNEL_SETTING x0 = InitChannel(1, 0, log2BytesPP + 0);\n    ADDR_CHANNEL_SETTING x1 = InitChannel(1, 0, log2BytesPP + 1);\n    ADDR_CHANNEL_SETTING x2 = InitChannel(1, 0, log2BytesPP + 2);\n    ADDR_CHANNEL_SETTING y0 = InitChannel(1, 1, 0);\n    ADDR_CHANNEL_SETTING y1 = InitChannel(1, 1, 1);\n    ADDR_CHANNEL_SETTING y2 = InitChannel(1, 1, 2);\n    ADDR_CHANNEL_SETTING z0 = InitChannel(1, 2, 0);\n    ADDR_CHANNEL_SETTING z1 = InitChannel(1, 2, 1);\n    ADDR_CHANNEL_SETTING z2 = InitChannel(1, 2, 2);\n\n    UINT_32 thickness = Thickness(tileMode);\n    UINT_32 bpp = 1 << (log2BytesPP + 3);\n\n    if (microTileType != ADDR_THICK)\n    {\n        if (microTileType == ADDR_DISPLAYABLE)\n        {\n            switch (bpp)\n            {\n                case 8:\n                    pixelBit[0] = x0;\n                    pixelBit[1] = x1;\n                    pixelBit[2] = x2;\n                    pixelBit[3] = y1;\n                    pixelBit[4] = y0;\n                    pixelBit[5] = y2;\n                    break;\n                case 16:\n                    pixelBit[0] = x0;\n                    pixelBit[1] = x1;\n                    pixelBit[2] = x2;\n                    pixelBit[3] = y0;\n                    pixelBit[4] = y1;\n                    pixelBit[5] = y2;\n                    break;\n                case 32:\n                    pixelBit[0] = x0;\n                    pixelBit[1] = x1;\n                    pixelBit[2] = y0;\n                    pixelBit[3] = x2;\n                    pixelBit[4] = y1;\n                    pixelBit[5] = y2;\n                    break;\n                case 64:\n                    pixelBit[0] = x0;\n                    pixelBit[1] = y0;\n                    pixelBit[2] = x1;\n                    pixelBit[3] = x2;\n                    pixelBit[4] = y1;\n                    pixelBit[5] = y2;\n                    break;\n                case 128:\n                    pixelBit[0] = y0;\n                    pixelBit[1] = x0;\n                    pixelBit[2] = x1;\n                    pixelBit[3] = x2;\n                    pixelBit[4] = y1;\n                    pixelBit[5] = y2;\n                    break;\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    break;\n            }\n        }\n        else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)\n        {\n            pixelBit[0] = x0;\n            pixelBit[1] = y0;\n            pixelBit[2] = x1;\n            pixelBit[3] = y1;\n            pixelBit[4] = x2;\n            pixelBit[5] = y2;\n        }\n        else if (microTileType == ADDR_ROTATED)\n        {\n            ADDR_ASSERT(thickness == 1);\n\n            switch (bpp)\n            {\n                case 8:\n                    pixelBit[0] = y0;\n                    pixelBit[1] = y1;\n                    pixelBit[2] = y2;\n                    pixelBit[3] = x1;\n                    pixelBit[4] = x0;\n                    pixelBit[5] = x2;\n                    break;\n                case 16:\n                    pixelBit[0] = y0;\n                    pixelBit[1] = y1;\n                    pixelBit[2] = y2;\n                    pixelBit[3] = x0;\n                    pixelBit[4] = x1;\n                    pixelBit[5] = x2;\n                    break;\n                case 32:\n                    pixelBit[0] = y0;\n                    pixelBit[1] = y1;\n                    pixelBit[2] = x0;\n                    pixelBit[3] = y2;\n                    pixelBit[4] = x1;\n                    pixelBit[5] = x2;\n                    break;\n                case 64:\n                    pixelBit[0] = y0;\n                    pixelBit[1] = x0;\n                    pixelBit[2] = y1;\n                    pixelBit[3] = x1;\n                    pixelBit[4] = x2;\n                    pixelBit[5] = y2;\n                    break;\n                default:\n                    retCode = ADDR_NOTSUPPORTED;\n                    break;\n            }\n        }\n\n        if (thickness > 1)\n        {\n            pixelBit[6] = z0;\n            pixelBit[7] = z1;\n            pEquation->numBits = 8 + log2BytesPP;\n        }\n        else\n        {\n            pEquation->numBits = 6 + log2BytesPP;\n        }\n    }\n    else // ADDR_THICK\n    {\n        ADDR_ASSERT(thickness > 1);\n\n        switch (bpp)\n        {\n            case 8:\n            case 16:\n                pixelBit[0] = x0;\n                pixelBit[1] = y0;\n                pixelBit[2] = x1;\n                pixelBit[3] = y1;\n                pixelBit[4] = z0;\n                pixelBit[5] = z1;\n                break;\n            case 32:\n                pixelBit[0] = x0;\n                pixelBit[1] = y0;\n                pixelBit[2] = x1;\n                pixelBit[3] = z0;\n                pixelBit[4] = y1;\n                pixelBit[5] = z1;\n                break;\n            case 64:\n            case 128:\n                pixelBit[0] = x0;\n                pixelBit[1] = y0;\n                pixelBit[2] = z0;\n                pixelBit[3] = x1;\n                pixelBit[4] = y1;\n                pixelBit[5] = z1;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        pixelBit[6] = x2;\n        pixelBit[7] = y2;\n        pEquation->numBits = 8 + log2BytesPP;\n    }\n\n    if (thickness == 8)\n    {\n        pixelBit[8] = z2;\n        pEquation->numBits = 9 + log2BytesPP;\n    }\n\n    // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,\n    // which is not supported by our address lib\n    pEquation->stackedDepthSlices = FALSE;\n    pEquation->numBitComponents   = 1;\n\n    return retCode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputePixelIndexWithinMicroTile\n*\n*   @brief\n*       Compute the pixel index inside a micro tile of surface\n*\n*   @return\n*       Pixel index\n*\n****************************************************************************************************\n*/\nUINT_32 Lib::ComputePixelIndexWithinMicroTile(\n    UINT_32         x,              ///< [in] x coord\n    UINT_32         y,              ///< [in] y coord\n    UINT_32         z,              ///< [in] slice/depth index\n    UINT_32         bpp,            ///< [in] bits per pixel\n    AddrTileMode    tileMode,       ///< [in] tile mode\n    AddrTileType    microTileType   ///< [in] pixel order in display/non-display mode\n    ) const\n{\n    UINT_32 pixelBit0 = 0;\n    UINT_32 pixelBit1 = 0;\n    UINT_32 pixelBit2 = 0;\n    UINT_32 pixelBit3 = 0;\n    UINT_32 pixelBit4 = 0;\n    UINT_32 pixelBit5 = 0;\n    UINT_32 pixelBit6 = 0;\n    UINT_32 pixelBit7 = 0;\n    UINT_32 pixelBit8 = 0;\n    UINT_32 pixelNumber;\n\n    UINT_32 x0 = _BIT(x, 0);\n    UINT_32 x1 = _BIT(x, 1);\n    UINT_32 x2 = _BIT(x, 2);\n    UINT_32 y0 = _BIT(y, 0);\n    UINT_32 y1 = _BIT(y, 1);\n    UINT_32 y2 = _BIT(y, 2);\n    UINT_32 z0 = _BIT(z, 0);\n    UINT_32 z1 = _BIT(z, 1);\n    UINT_32 z2 = _BIT(z, 2);\n\n    UINT_32 thickness = Thickness(tileMode);\n\n    // Compute the pixel number within the micro tile.\n\n    if (microTileType != ADDR_THICK)\n    {\n        if (microTileType == ADDR_DISPLAYABLE)\n        {\n            switch (bpp)\n            {\n                case 8:\n                    pixelBit0 = x0;\n                    pixelBit1 = x1;\n                    pixelBit2 = x2;\n                    pixelBit3 = y1;\n                    pixelBit4 = y0;\n                    pixelBit5 = y2;\n                    break;\n                case 16:\n                    pixelBit0 = x0;\n                    pixelBit1 = x1;\n                    pixelBit2 = x2;\n                    pixelBit3 = y0;\n                    pixelBit4 = y1;\n                    pixelBit5 = y2;\n                    break;\n                case 32:\n                    pixelBit0 = x0;\n                    pixelBit1 = x1;\n                    pixelBit2 = y0;\n                    pixelBit3 = x2;\n                    pixelBit4 = y1;\n                    pixelBit5 = y2;\n                    break;\n                case 64:\n                    pixelBit0 = x0;\n                    pixelBit1 = y0;\n                    pixelBit2 = x1;\n                    pixelBit3 = x2;\n                    pixelBit4 = y1;\n                    pixelBit5 = y2;\n                    break;\n                case 128:\n                    pixelBit0 = y0;\n                    pixelBit1 = x0;\n                    pixelBit2 = x1;\n                    pixelBit3 = x2;\n                    pixelBit4 = y1;\n                    pixelBit5 = y2;\n                    break;\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    break;\n            }\n        }\n        else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)\n        {\n            pixelBit0 = x0;\n            pixelBit1 = y0;\n            pixelBit2 = x1;\n            pixelBit3 = y1;\n            pixelBit4 = x2;\n            pixelBit5 = y2;\n        }\n        else if (microTileType == ADDR_ROTATED)\n        {\n            ADDR_ASSERT(thickness == 1);\n\n            switch (bpp)\n            {\n                case 8:\n                    pixelBit0 = y0;\n                    pixelBit1 = y1;\n                    pixelBit2 = y2;\n                    pixelBit3 = x1;\n                    pixelBit4 = x0;\n                    pixelBit5 = x2;\n                    break;\n                case 16:\n                    pixelBit0 = y0;\n                    pixelBit1 = y1;\n                    pixelBit2 = y2;\n                    pixelBit3 = x0;\n                    pixelBit4 = x1;\n                    pixelBit5 = x2;\n                    break;\n                case 32:\n                    pixelBit0 = y0;\n                    pixelBit1 = y1;\n                    pixelBit2 = x0;\n                    pixelBit3 = y2;\n                    pixelBit4 = x1;\n                    pixelBit5 = x2;\n                    break;\n                case 64:\n                    pixelBit0 = y0;\n                    pixelBit1 = x0;\n                    pixelBit2 = y1;\n                    pixelBit3 = x1;\n                    pixelBit4 = x2;\n                    pixelBit5 = y2;\n                    break;\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    break;\n            }\n        }\n\n        if (thickness > 1)\n        {\n            pixelBit6 = z0;\n            pixelBit7 = z1;\n        }\n    }\n    else // ADDR_THICK\n    {\n        ADDR_ASSERT(thickness > 1);\n\n        switch (bpp)\n        {\n            case 8:\n            case 16:\n                pixelBit0 = x0;\n                pixelBit1 = y0;\n                pixelBit2 = x1;\n                pixelBit3 = y1;\n                pixelBit4 = z0;\n                pixelBit5 = z1;\n                break;\n            case 32:\n                pixelBit0 = x0;\n                pixelBit1 = y0;\n                pixelBit2 = x1;\n                pixelBit3 = z0;\n                pixelBit4 = y1;\n                pixelBit5 = z1;\n                break;\n            case 64:\n            case 128:\n                pixelBit0 = x0;\n                pixelBit1 = y0;\n                pixelBit2 = z0;\n                pixelBit3 = x1;\n                pixelBit4 = y1;\n                pixelBit5 = z1;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        pixelBit6 = x2;\n        pixelBit7 = y2;\n    }\n\n    if (thickness == 8)\n    {\n        pixelBit8 = z2;\n    }\n\n    pixelNumber = ((pixelBit0     ) |\n                   (pixelBit1 << 1) |\n                   (pixelBit2 << 2) |\n                   (pixelBit3 << 3) |\n                   (pixelBit4 << 4) |\n                   (pixelBit5 << 5) |\n                   (pixelBit6 << 6) |\n                   (pixelBit7 << 7) |\n                   (pixelBit8 << 8));\n\n    return pixelNumber;\n}\n\n/**\n****************************************************************************************************\n*   Lib::AdjustPitchAlignment\n*\n*   @brief\n*       Adjusts pitch alignment for flipping surface\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID Lib::AdjustPitchAlignment(\n    ADDR_SURFACE_FLAGS  flags,      ///< [in] Surface flags\n    UINT_32*            pPitchAlign ///< [out] Pointer to pitch alignment\n    ) const\n{\n    // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment\n    // Maybe it will be fixed in future but let's make it general for now.\n    if (flags.display || flags.overlay)\n    {\n        *pPitchAlign = PowTwoAlign(*pPitchAlign, 32);\n\n        if(flags.display)\n        {\n            *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   Lib::PadDimensions\n*\n*   @brief\n*       Helper function to pad dimensions\n*\n*   @return\n*       N/A\n*\n****************************************************************************************************\n*/\nVOID Lib::PadDimensions(\n    AddrTileMode        tileMode,    ///< [in] tile mode\n    UINT_32             bpp,         ///< [in] bits per pixel\n    ADDR_SURFACE_FLAGS  flags,       ///< [in] surface flags\n    UINT_32             numSamples,  ///< [in] number of samples\n    ADDR_TILEINFO*      pTileInfo,   ///< [in,out] bank structure.\n    UINT_32             padDims,     ///< [in] Dimensions to pad valid value 1,2,3\n    UINT_32             mipLevel,    ///< [in] MipLevel\n    UINT_32*            pPitch,      ///< [in,out] pitch in pixels\n    UINT_32*            pPitchAlign, ///< [in,out] pitch align could be changed in HwlPadDimensions\n    UINT_32*            pHeight,     ///< [in,out] height in pixels\n    UINT_32             heightAlign, ///< [in] height alignment\n    UINT_32*            pSlices,     ///< [in,out] number of slices\n    UINT_32             sliceAlign   ///< [in] number of slice alignment\n    ) const\n{\n    UINT_32 pitchAlign = *pPitchAlign;\n    UINT_32 thickness = Thickness(tileMode);\n\n    ADDR_ASSERT(padDims <= 3);\n\n    //\n    // Override padding for mip levels\n    //\n    if (mipLevel > 0)\n    {\n        if (flags.cube)\n        {\n            // for cubemap, we only pad when client call with 6 faces as an identity\n            if (*pSlices > 1)\n            {\n                padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture\n            }\n            else\n            {\n                padDims = 2;\n            }\n        }\n    }\n\n    // Any possibilities that padDims is 0?\n    if (padDims == 0)\n    {\n        padDims = 3;\n    }\n\n    if (IsPow2(pitchAlign))\n    {\n        *pPitch = PowTwoAlign((*pPitch), pitchAlign);\n    }\n    else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear\n    {\n        *pPitch += pitchAlign - 1;\n        *pPitch /= pitchAlign;\n        *pPitch *= pitchAlign;\n    }\n\n    if (padDims > 1)\n    {\n        if (IsPow2(heightAlign))\n        {\n            *pHeight = PowTwoAlign((*pHeight), heightAlign);\n        }\n        else\n        {\n            *pHeight += heightAlign - 1;\n            *pHeight /= heightAlign;\n            *pHeight *= heightAlign;\n        }\n    }\n\n    if (padDims > 2 || thickness > 1)\n    {\n        // for cubemap single face, we do not pad slices.\n        // if we pad it, the slice number should be set to 6 and current mip level > 1\n        if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))\n        {\n            *pSlices = NextPow2(*pSlices);\n        }\n\n        // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)\n        if (thickness > 1)\n        {\n            *pSlices = PowTwoAlign((*pSlices), sliceAlign);\n        }\n\n    }\n\n    HwlPadDimensions(tileMode,\n                     bpp,\n                     flags,\n                     numSamples,\n                     pTileInfo,\n                     mipLevel,\n                     pPitch,\n                     pPitchAlign,\n                     *pHeight,\n                     heightAlign);\n}\n\n\n/**\n****************************************************************************************************\n*   Lib::HwlPreHandleBaseLvl3xPitch\n*\n*   @brief\n*       Pre-handler of 3x pitch (96 bit) adjustment\n*\n*   @return\n*       Expected pitch\n****************************************************************************************************\n*/\nUINT_32 Lib::HwlPreHandleBaseLvl3xPitch(\n    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input\n    UINT_32                                 expPitch    ///< [in] pitch\n    ) const\n{\n    ADDR_ASSERT(pIn->width == expPitch);\n    //\n    // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size\n    //\n    if (ElemLib::IsExpand3x(pIn->format) &&\n        pIn->mipLevel == 0 &&\n        pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)\n    {\n        expPitch /= 3;\n        expPitch = NextPow2(expPitch);\n    }\n\n    return expPitch;\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlPostHandleBaseLvl3xPitch\n*\n*   @brief\n*       Post-handler of 3x pitch adjustment\n*\n*   @return\n*       Expected pitch\n****************************************************************************************************\n*/\nUINT_32 Lib::HwlPostHandleBaseLvl3xPitch(\n    const ADDR_COMPUTE_SURFACE_INFO_INPUT*  pIn,        ///< [in] input\n    UINT_32                                 expPitch    ///< [in] pitch\n    ) const\n{\n    //\n    // 96 bits surface of sub levels require element pitch of 32 bits instead\n    // So we just return pitch in 32 bit pixels without timing 3\n    //\n    if (ElemLib::IsExpand3x(pIn->format) &&\n        pIn->mipLevel == 0 &&\n        pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)\n    {\n        expPitch *= 3;\n    }\n\n    return expPitch;\n}\n\n\n/**\n****************************************************************************************************\n*   Lib::IsMacroTiled\n*\n*   @brief\n*       Check if the tile mode is macro tiled\n*\n*   @return\n*       TRUE if it is macro tiled (2D/2B/3D/3B)\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsMacroTiled(\n    AddrTileMode tileMode)  ///< [in] tile mode\n{\n   return ModeFlags[tileMode].isMacro;\n}\n\n/**\n****************************************************************************************************\n*   Lib::IsMacro3dTiled\n*\n*   @brief\n*       Check if the tile mode is 3D macro tiled\n*\n*   @return\n*       TRUE if it is 3D macro tiled\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsMacro3dTiled(\n    AddrTileMode tileMode)  ///< [in] tile mode\n{\n    return ModeFlags[tileMode].isMacro3d;\n}\n\n/**\n****************************************************************************************************\n*   Lib::IsMicroTiled\n*\n*   @brief\n*       Check if the tile mode is micro tiled\n*\n*   @return\n*       TRUE if micro tiled\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsMicroTiled(\n    AddrTileMode tileMode)  ///< [in] tile mode\n{\n    return ModeFlags[tileMode].isMicro;\n}\n\n/**\n****************************************************************************************************\n*   Lib::IsLinear\n*\n*   @brief\n*       Check if the tile mode is linear\n*\n*   @return\n*       TRUE if linear\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsLinear(\n    AddrTileMode tileMode)  ///< [in] tile mode\n{\n    return ModeFlags[tileMode].isLinear;\n}\n\n/**\n****************************************************************************************************\n*   Lib::IsPrtNoRotationTileMode\n*\n*   @brief\n*       Return TRUE if it is prt tile without rotation\n*   @note\n*       This function just used by CI\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsPrtNoRotationTileMode(\n    AddrTileMode tileMode)\n{\n    return ModeFlags[tileMode].isPrtNoRotation;\n}\n\n/**\n****************************************************************************************************\n*   Lib::IsPrtTileMode\n*\n*   @brief\n*       Return TRUE if it is prt tile\n*   @note\n*       This function just used by CI\n****************************************************************************************************\n*/\nBOOL_32 Lib::IsPrtTileMode(\n    AddrTileMode tileMode)\n{\n    return ModeFlags[tileMode].isPrt;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeMipLevel\n*\n*   @brief\n*       Compute mipmap level width/height/slices\n*   @return\n*      N/A\n****************************************************************************************************\n*/\nVOID Lib::ComputeMipLevel(\n    ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure\n    ) const\n{\n    // Check if HWL has handled\n    BOOL_32 hwlHandled = FALSE;\n\n    if (ElemLib::IsBlockCompressed(pIn->format))\n    {\n        if (pIn->mipLevel == 0)\n        {\n            // DXTn's level 0 must be multiple of 4\n            // But there are exceptions:\n            // 1. Internal surface creation in hostblt/vsblt/etc...\n            // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4\n            pIn->width = PowTwoAlign(pIn->width, 4);\n            pIn->height = PowTwoAlign(pIn->height, 4);\n        }\n    }\n\n    hwlHandled = HwlComputeMipLevel(pIn);\n}\n\n/**\n****************************************************************************************************\n*   Lib::DegradeTo1D\n*\n*   @brief\n*       Check if surface can be degraded to 1D\n*   @return\n*       TRUE if degraded\n****************************************************************************************************\n*/\nBOOL_32 Lib::DegradeTo1D(\n    UINT_32 width,                  ///< surface width\n    UINT_32 height,                 ///< surface height\n    UINT_32 macroTilePitchAlign,    ///< macro tile pitch align\n    UINT_32 macroTileHeightAlign    ///< macro tile height align\n    )\n{\n    BOOL_32 degrade = ((width < macroTilePitchAlign) || (height < macroTileHeightAlign));\n\n    // Check whether 2D tiling still has too much footprint\n    if (degrade == FALSE)\n    {\n        // Only check width and height as slices are aligned to thickness\n        UINT_64 unalignedSize = width * height;\n\n        UINT_32 alignedPitch = PowTwoAlign(width, macroTilePitchAlign);\n        UINT_32 alignedHeight = PowTwoAlign(height, macroTileHeightAlign);\n        UINT_64 alignedSize = alignedPitch * alignedHeight;\n\n        // alignedSize > 1.5 * unalignedSize\n        if (2 * alignedSize > 3 * unalignedSize)\n        {\n            degrade = TRUE;\n        }\n    }\n\n    return degrade;\n}\n\n/**\n****************************************************************************************************\n*   Lib::OptimizeTileMode\n*\n*   @brief\n*       Check if base level's tile mode can be optimized (degraded)\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID Lib::OptimizeTileMode(\n    ADDR_COMPUTE_SURFACE_INFO_INPUT*  pInOut     ///< [in, out] structure for surface info\n    ) const\n{\n    AddrTileMode tileMode = pInOut->tileMode;\n\n    BOOL_32 doOpt = (pInOut->flags.opt4Space == TRUE) ||\n                    (pInOut->flags.minimizeAlignment == TRUE) ||\n                    (pInOut->maxBaseAlign != 0);\n\n    BOOL_32 convertToPrt = FALSE;\n\n    // Optimization can only be done on level 0 and samples <= 1\n    if ((doOpt == TRUE)                     &&\n        (pInOut->mipLevel == 0)             &&\n        (IsPrtTileMode(tileMode) == FALSE)  &&\n        (pInOut->flags.prt == FALSE))\n    {\n        UINT_32 width = pInOut->width;\n        UINT_32 height = pInOut->height;\n        UINT_32 thickness = Thickness(tileMode);\n        BOOL_32 macroTiledOK = TRUE;\n        UINT_32 macroWidthAlign = 0;\n        UINT_32 macroHeightAlign = 0;\n        UINT_32 macroSizeAlign = 0;\n\n        if (IsMacroTiled(tileMode))\n        {\n            macroTiledOK = HwlGetAlignmentInfoMacroTiled(pInOut,\n                                                         &macroWidthAlign,\n                                                         &macroHeightAlign,\n                                                         &macroSizeAlign);\n        }\n\n        if (macroTiledOK)\n        {\n            if ((pInOut->flags.display == FALSE) &&\n                (pInOut->flags.opt4Space == TRUE) &&\n                (pInOut->numSamples <= 1))\n            {\n                // Check if linear mode is optimal\n                if ((pInOut->height == 1) &&\n                    (IsLinear(tileMode) == FALSE) &&\n                    (ElemLib::IsBlockCompressed(pInOut->format) == FALSE) &&\n                    (pInOut->flags.depth == FALSE) &&\n                    (pInOut->flags.stencil == FALSE) &&\n                    (m_configFlags.disableLinearOpt == FALSE) &&\n                    (pInOut->flags.disableLinearOpt == FALSE))\n                {\n                    tileMode = ADDR_TM_LINEAR_ALIGNED;\n                }\n                else if (IsMacroTiled(tileMode) && (pInOut->flags.tcCompatible == FALSE))\n                {\n                    if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))\n                    {\n                        tileMode = (thickness == 1) ?\n                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;\n                    }\n                    else if ((thickness > 1) && (pInOut->flags.disallowLargeThickDegrade == 0))\n                    {\n                        // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to\n                        // thinner modes, we should re-evaluate whether the corresponding\n                        // thinner modes should be degraded. If so, we choose 1D thick mode instead.\n                        tileMode = DegradeLargeThickTile(pInOut->tileMode, pInOut->bpp);\n\n                        if (tileMode != pInOut->tileMode)\n                        {\n                            // Get thickness again after large thick degrade\n                            thickness = Thickness(tileMode);\n\n                            ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pInOut;\n                            input.tileMode = tileMode;\n\n                            macroTiledOK = HwlGetAlignmentInfoMacroTiled(&input,\n                                                                         &macroWidthAlign,\n                                                                         &macroHeightAlign,\n                                                                         &macroSizeAlign);\n\n                            if (macroTiledOK &&\n                                DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))\n                            {\n                                tileMode = ADDR_TM_1D_TILED_THICK;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (macroTiledOK)\n            {\n                if ((pInOut->flags.minimizeAlignment == TRUE) &&\n                    (pInOut->numSamples <= 1) &&\n                    (IsMacroTiled(tileMode) == TRUE))\n                {\n                    UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *\n                                        PowTwoAlign(height, macroHeightAlign);\n                    UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *\n                                        PowTwoAlign(height, MicroTileHeight);\n\n                    if (macroSize > microSize)\n                    {\n                        tileMode = (thickness == 1) ?\n                                   ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;\n                    }\n                }\n\n                if ((pInOut->maxBaseAlign != 0) &&\n                    (IsMacroTiled(tileMode) == TRUE))\n                {\n                    if (macroSizeAlign > pInOut->maxBaseAlign)\n                    {\n                        if (pInOut->numSamples > 1)\n                        {\n                            ADDR_ASSERT(pInOut->maxBaseAlign >= Block64K);\n\n                            convertToPrt = TRUE;\n                        }\n                        else if (pInOut->maxBaseAlign < Block64K)\n                        {\n                            tileMode = (thickness == 1) ?\n                                       ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;\n                        }\n                        else\n                        {\n                            convertToPrt = TRUE;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (convertToPrt)\n    {\n        if ((pInOut->flags.matchStencilTileCfg == TRUE) && (pInOut->numSamples <= 1))\n        {\n            pInOut->tileMode = ADDR_TM_1D_TILED_THIN1;\n        }\n        else\n        {\n            HwlSetPrtTileMode(pInOut);\n        }\n    }\n    else if (tileMode != pInOut->tileMode)\n    {\n        pInOut->tileMode = tileMode;\n    }\n\n    HwlOptimizeTileMode(pInOut);\n}\n\n/**\n****************************************************************************************************\n*   Lib::DegradeLargeThickTile\n*\n*   @brief\n*       Check if the thickness needs to be reduced if a tile is too large\n*   @return\n*       The degraded tile mode (unchanged if not degraded)\n****************************************************************************************************\n*/\nAddrTileMode Lib::DegradeLargeThickTile(\n    AddrTileMode tileMode,\n    UINT_32 bpp) const\n{\n    // Override tilemode\n    // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,\n    // it is better to just use THIN mode in this case\n    UINT_32 thickness = Thickness(tileMode);\n\n    if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)\n    {\n        UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);\n\n        if (tileSize > m_rowSize)\n        {\n            switch (tileMode)\n            {\n                case ADDR_TM_2D_TILED_XTHICK:\n                    if ((tileSize >> 1) <= m_rowSize)\n                    {\n                        tileMode = ADDR_TM_2D_TILED_THICK;\n                        break;\n                    }\n                    // else fall through\n                case ADDR_TM_2D_TILED_THICK:\n                    tileMode    = ADDR_TM_2D_TILED_THIN1;\n                    break;\n\n                case ADDR_TM_3D_TILED_XTHICK:\n                    if ((tileSize >> 1) <= m_rowSize)\n                    {\n                        tileMode = ADDR_TM_3D_TILED_THICK;\n                        break;\n                    }\n                    // else fall through\n                case ADDR_TM_3D_TILED_THICK:\n                    tileMode    = ADDR_TM_3D_TILED_THIN1;\n                    break;\n\n                case ADDR_TM_PRT_TILED_THICK:\n                    tileMode    = ADDR_TM_PRT_TILED_THIN1;\n                    break;\n\n                case ADDR_TM_PRT_2D_TILED_THICK:\n                    tileMode    = ADDR_TM_PRT_2D_TILED_THIN1;\n                    break;\n\n                case ADDR_TM_PRT_3D_TILED_THICK:\n                    tileMode    = ADDR_TM_PRT_3D_TILED_THIN1;\n                    break;\n\n                default:\n                    break;\n            }\n        }\n    }\n\n    return tileMode;\n}\n\n/**\n****************************************************************************************************\n*   Lib::PostComputeMipLevel\n*   @brief\n*       Compute MipLevel info (including level 0) after surface adjustment\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::PostComputeMipLevel(\n    ADDR_COMPUTE_SURFACE_INFO_INPUT*    pIn,   ///< [in,out] Input structure\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*   pOut   ///< [out] Output structure\n    ) const\n{\n    // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is\n    // required by CFX  for Hw Compatibility between NI and SI. Otherwise it is only needed for\n    // mipLevel > 0. Any h/w has different requirement should implement its own virtual function\n\n    if (pIn->flags.pow2Pad)\n    {\n        pIn->width      = NextPow2(pIn->width);\n        pIn->height     = NextPow2(pIn->height);\n        pIn->numSlices  = NextPow2(pIn->numSlices);\n    }\n    else if (pIn->mipLevel > 0)\n    {\n        pIn->width      = NextPow2(pIn->width);\n        pIn->height     = NextPow2(pIn->height);\n\n        if (!pIn->flags.cube)\n        {\n            pIn->numSlices = NextPow2(pIn->numSlices);\n        }\n\n        // for cubemap, we keep its value at first\n    }\n\n    return ADDR_OK;\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlSetupTileCfg\n*\n*   @brief\n*       Map tile index to tile setting.\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::HwlSetupTileCfg(\n    UINT_32         bpp,              ///< Bits per pixel\n    INT_32          index,            ///< [in] Tile index\n    INT_32          macroModeIndex,   ///< [in] Index in macro tile mode table(CI)\n    ADDR_TILEINFO*  pInfo,            ///< [out] Tile Info\n    AddrTileMode*   pMode,            ///< [out] Tile mode\n    AddrTileType*   pType             ///< [out] Tile type\n    ) const\n{\n    return ADDR_NOTSUPPORTED;\n}\n\n/**\n****************************************************************************************************\n*   Lib::HwlGetPipes\n*\n*   @brief\n*       Get number pipes\n*   @return\n*       num pipes\n****************************************************************************************************\n*/\nUINT_32 Lib::HwlGetPipes(\n    const ADDR_TILEINFO* pTileInfo    ///< [in] Tile info\n    ) const\n{\n    //pTileInfo can be NULL when asic is 6xx and 8xx.\n    return m_pipes;\n}\n\n/**\n****************************************************************************************************\n*   Lib::ComputeQbStereoInfo\n*\n*   @brief\n*       Get quad buffer stereo information\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID Lib::ComputeQbStereoInfo(\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT*       pOut    ///< [in,out] updated pOut+pStereoInfo\n    ) const\n{\n    ADDR_ASSERT(pOut->bpp >= 8);\n    ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);\n\n    // Save original height\n    pOut->pStereoInfo->eyeHeight = pOut->height;\n\n    // Right offset\n    pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);\n\n    pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);\n    // Double height\n    pOut->height <<= 1;\n    pOut->pixelHeight <<= 1;\n\n    // Double size\n    pOut->surfSize <<= 1;\n\n    // Right start address meets the base align since it is guaranteed by AddrLib1\n\n    // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.\n}\n\n\n/**\n****************************************************************************************************\n*   Lib::ComputePrtInfo\n*\n*   @brief\n*       Compute prt surface related info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n****************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputePrtInfo(\n    const ADDR_PRT_INFO_INPUT*  pIn,\n    ADDR_PRT_INFO_OUTPUT*       pOut) const\n{\n    ADDR_ASSERT(pOut != NULL);\n\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    UINT_32     expandX = 1;\n    UINT_32     expandY = 1;\n    ElemMode    elemMode;\n\n    UINT_32     bpp = GetElemLib()->GetBitsPerPixel(pIn->format,\n                                                    &elemMode,\n                                                    &expandX,\n                                                    &expandY);\n\n    if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    UINT_32     numFrags = pIn->numFrags;\n    ADDR_ASSERT(numFrags <= 8);\n\n    UINT_32     tileWidth = 0;\n    UINT_32     tileHeight = 0;\n    if (returnCode == ADDR_OK)\n    {\n        // 3D texture without depth or 2d texture\n        if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)\n        {\n            if (bpp == 8)\n            {\n                tileWidth = 256;\n                tileHeight = 256;\n            }\n            else if (bpp == 16)\n            {\n                tileWidth = 256;\n                tileHeight = 128;\n            }\n            else if (bpp == 32)\n            {\n                tileWidth = 128;\n                tileHeight = 128;\n            }\n            else if (bpp == 64)\n            {\n                // assume it is BC1/4\n                tileWidth = 512;\n                tileHeight = 256;\n\n                if (elemMode == ADDR_UNCOMPRESSED)\n                {\n                    tileWidth = 128;\n                    tileHeight = 64;\n                }\n            }\n            else if (bpp == 128)\n            {\n                // assume it is BC2/3/5/6H/7\n                tileWidth = 256;\n                tileHeight = 256;\n\n                if (elemMode == ADDR_UNCOMPRESSED)\n                {\n                    tileWidth = 64;\n                    tileHeight = 64;\n                }\n            }\n\n            if (numFrags == 2)\n            {\n                tileWidth = tileWidth / 2;\n            }\n            else if (numFrags == 4)\n            {\n                tileWidth = tileWidth / 2;\n                tileHeight = tileHeight / 2;\n            }\n            else if (numFrags == 8)\n            {\n                tileWidth = tileWidth / 4;\n                tileHeight = tileHeight / 2;\n            }\n        }\n        else    // 1d\n        {\n            tileHeight = 1;\n            if (bpp == 8)\n            {\n                tileWidth = 65536;\n            }\n            else if (bpp == 16)\n            {\n                tileWidth = 32768;\n            }\n            else if (bpp == 32)\n            {\n                tileWidth = 16384;\n            }\n            else if (bpp == 64)\n            {\n                tileWidth = 8192;\n            }\n            else if (bpp == 128)\n            {\n                tileWidth = 4096;\n            }\n        }\n    }\n\n    pOut->prtTileWidth = tileWidth;\n    pOut->prtTileHeight = tileHeight;\n\n    return returnCode;\n}\n\n} // V1\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib1.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n****************************************************************************************************\n* @file  addrlib1.h\n* @brief Contains the Addr::V1::Lib class definition.\n****************************************************************************************************\n*/\n\n#ifndef __ADDR_LIB1_H__\n#define __ADDR_LIB1_H__\n\n#include \"addrlib.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V1\n{\n\n/**\n****************************************************************************************************\n* @brief Neutral enums that define bank swap size\n****************************************************************************************************\n*/\nenum SampleSplitSize\n{\n    ADDR_SAMPLESPLIT_1KB = 1024,\n    ADDR_SAMPLESPLIT_2KB = 2048,\n    ADDR_SAMPLESPLIT_4KB = 4096,\n    ADDR_SAMPLESPLIT_8KB = 8192,\n};\n\n/**\n****************************************************************************************************\n* @brief Flags for AddrTileMode\n****************************************************************************************************\n*/\nstruct TileModeFlags\n{\n    UINT_32 thickness       : 4;\n    UINT_32 isLinear        : 1;\n    UINT_32 isMicro         : 1;\n    UINT_32 isMacro         : 1;\n    UINT_32 isMacro3d       : 1;\n    UINT_32 isPrt           : 1;\n    UINT_32 isPrtNoRotation : 1;\n    UINT_32 isBankSwapped   : 1;\n};\n\nstatic const UINT_32 Block64K = 0x10000;\nstatic const UINT_32 PrtTileSize = Block64K;\n\n/**\n****************************************************************************************************\n* @brief This class contains asic independent address lib functionalities\n****************************************************************************************************\n*/\nclass Lib : public Addr::Lib\n{\npublic:\n    virtual ~Lib();\n\n    static Lib* GetLib(\n        ADDR_HANDLE hLib);\n\n    /// Returns tileIndex support\n    BOOL_32 UseTileIndex(INT_32 index) const\n    {\n        return m_configFlags.useTileIndex && (index != TileIndexInvalid);\n    }\n\n    /// Returns combined swizzle support\n    BOOL_32 UseCombinedSwizzle() const\n    {\n        return m_configFlags.useCombinedSwizzle;\n    }\n\n    //\n    // Interface stubs\n    //\n    ADDR_E_RETURNCODE ComputeSurfaceInfo(\n        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoord(\n        const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceCoordFromAddr(\n        const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT*  pIn,\n        ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSliceTileSwizzle(\n        const ADDR_COMPUTE_SLICESWIZZLE_INPUT*  pIn,\n        ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ExtractBankPipeSwizzle(\n        const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn,\n        ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE CombineBankPipeSwizzle(\n        const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT*  pIn,\n        ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeBaseSwizzle(\n        const ADDR_COMPUTE_BASE_SWIZZLE_INPUT*  pIn,\n        ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeFmaskInfo(\n        const ADDR_COMPUTE_FMASK_INFO_INPUT*  pIn,\n        ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut);\n\n    ADDR_E_RETURNCODE ComputeFmaskAddrFromCoord(\n        const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*  pIn,\n        ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeFmaskCoordFromAddr(\n        const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,\n        ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ConvertTileInfoToHW(\n        const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn,\n        ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ConvertTileIndex(\n        const ADDR_CONVERT_TILEINDEX_INPUT* pIn,\n        ADDR_CONVERT_TILEINDEX_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE GetMacroModeIndex(\n        const ADDR_GET_MACROMODEINDEX_INPUT* pIn,\n        ADDR_GET_MACROMODEINDEX_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ConvertTileIndex1(\n        const ADDR_CONVERT_TILEINDEX1_INPUT* pIn,\n        ADDR_CONVERT_TILEINDEX_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE GetTileIndex(\n        const ADDR_GET_TILEINDEX_INPUT* pIn,\n        ADDR_GET_TILEINDEX_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeHtileInfo(\n        const ADDR_COMPUTE_HTILE_INFO_INPUT* pIn,\n        ADDR_COMPUTE_HTILE_INFO_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeCmaskInfo(\n        const ADDR_COMPUTE_CMASK_INFO_INPUT* pIn,\n        ADDR_COMPUTE_CMASK_INFO_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeDccInfo(\n        const ADDR_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeHtileAddrFromCoord(\n        const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*  pIn,\n        ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeCmaskAddrFromCoord(\n        const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*  pIn,\n        ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeHtileCoordFromAddr(\n        const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT*  pIn,\n        ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputeCmaskCoordFromAddr(\n        const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT*  pIn,\n        ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut) const;\n\n    ADDR_E_RETURNCODE ComputePrtInfo(\n        const ADDR_PRT_INFO_INPUT*  pIn,\n        ADDR_PRT_INFO_OUTPUT*       pOut) const;\nprotected:\n    Lib();  // Constructor is protected\n    Lib(const Client* pClient);\n\n    /// Pure Virtual function for Hwl computing surface info\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(\n        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl computing surface address from coord\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoord(\n        const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl computing surface coord from address\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceCoordFromAddr(\n        const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl computing surface tile swizzle\n    virtual ADDR_E_RETURNCODE HwlComputeSliceTileSwizzle(\n        const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn,\n        ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl extracting bank/pipe swizzle from base256b\n    virtual ADDR_E_RETURNCODE HwlExtractBankPipeSwizzle(\n        const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn,\n        ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl combining bank/pipe swizzle\n    virtual ADDR_E_RETURNCODE HwlCombineBankPipeSwizzle(\n        UINT_32 bankSwizzle, UINT_32 pipeSwizzle, ADDR_TILEINFO*  pTileInfo,\n        UINT_64 baseAddr, UINT_32* pTileSwizzle) const = 0;\n\n    /// Pure Virtual function for Hwl computing base swizzle\n    virtual ADDR_E_RETURNCODE HwlComputeBaseSwizzle(\n        const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,\n        ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl computing HTILE base align\n    virtual UINT_32 HwlComputeHtileBaseAlign(\n        BOOL_32 isTcCompatible, BOOL_32 isLinear, ADDR_TILEINFO* pTileInfo) const = 0;\n\n    /// Pure Virtual function for Hwl computing HTILE bpp\n    virtual UINT_32 HwlComputeHtileBpp(\n        BOOL_32 isWidth8, BOOL_32 isHeight8) const = 0;\n\n    /// Pure Virtual function for Hwl computing HTILE bytes\n    virtual UINT_64 HwlComputeHtileBytes(\n        UINT_32 pitch, UINT_32 height, UINT_32 bpp,\n        BOOL_32 isLinear, UINT_32 numSlices, UINT_64* pSliceBytes, UINT_32 baseAlign) const = 0;\n\n    /// Pure Virtual function for Hwl computing FMASK info\n    virtual ADDR_E_RETURNCODE HwlComputeFmaskInfo(\n        const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,\n        ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) = 0;\n\n    /// Pure Virtual function for Hwl FMASK address from coord\n    virtual ADDR_E_RETURNCODE HwlComputeFmaskAddrFromCoord(\n        const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl FMASK coord from address\n    virtual ADDR_E_RETURNCODE HwlComputeFmaskCoordFromAddr(\n        const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn,\n        ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl convert tile info from real value to HW value\n    virtual ADDR_E_RETURNCODE HwlConvertTileInfoToHW(\n        const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn,\n        ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut) const = 0;\n\n    /// Pure Virtual function for Hwl compute mipmap info\n    virtual BOOL_32 HwlComputeMipLevel(\n        ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const = 0;\n\n    /// Pure Virtual function for Hwl compute max cmask blockMax value\n    virtual BOOL_32 HwlGetMaxCmaskBlockMax() const = 0;\n\n    /// Pure Virtual function for Hwl compute fmask bits\n    virtual UINT_32 HwlComputeFmaskBits(\n        const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn,\n        UINT_32* pNumSamples) const = 0;\n\n    /// Virtual function to get index (not pure then no need to implement this in all hwls\n    virtual ADDR_E_RETURNCODE HwlGetTileIndex(\n        const ADDR_GET_TILEINDEX_INPUT* pIn,\n        ADDR_GET_TILEINDEX_OUTPUT*      pOut) const\n    {\n        return ADDR_NOTSUPPORTED;\n    }\n\n    /// Virtual function for Hwl to compute Dcc info\n    virtual ADDR_E_RETURNCODE HwlComputeDccInfo(\n        const ADDR_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR_COMPUTE_DCCINFO_OUTPUT* pOut) const\n    {\n        return ADDR_NOTSUPPORTED;\n    }\n\n    /// Virtual function to get cmask address for tc compatible cmask\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(\n        const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) const\n    {\n        return ADDR_NOTSUPPORTED;\n    }\n\n    /// Virtual function to get htile address for tc compatible htile\n    virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(\n        const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) const\n    {\n        return ADDR_NOTSUPPORTED;\n    }\n\n    // Compute attributes\n\n    // HTILE\n    UINT_32    ComputeHtileInfo(\n        ADDR_HTILE_FLAGS flags,\n        UINT_32 pitchIn, UINT_32 heightIn, UINT_32 numSlices,\n        BOOL_32 isLinear, BOOL_32 isWidth8, BOOL_32 isHeight8,\n        ADDR_TILEINFO*  pTileInfo,\n        UINT_32* pPitchOut, UINT_32* pHeightOut, UINT_64* pHtileBytes,\n        UINT_32* pMacroWidth = NULL, UINT_32* pMacroHeight = NULL,\n        UINT_64* pSliceSize = NULL, UINT_32* pBaseAlign = NULL) const;\n\n    // CMASK\n    ADDR_E_RETURNCODE ComputeCmaskInfo(\n        ADDR_CMASK_FLAGS flags,\n        UINT_32 pitchIn, UINT_32 heightIn, UINT_32 numSlices, BOOL_32 isLinear,\n        ADDR_TILEINFO* pTileInfo, UINT_32* pPitchOut, UINT_32* pHeightOut, UINT_64* pCmaskBytes,\n        UINT_32* pMacroWidth, UINT_32* pMacroHeight, UINT_64* pSliceSize = NULL,\n        UINT_32* pBaseAlign = NULL, UINT_32* pBlockMax = NULL) const;\n\n    virtual VOID HwlComputeTileDataWidthAndHeightLinear(\n        UINT_32* pMacroWidth, UINT_32* pMacroHeight,\n        UINT_32 bpp, ADDR_TILEINFO* pTileInfo) const;\n\n    // CMASK & HTILE addressing\n    virtual UINT_64 HwlComputeXmaskAddrFromCoord(\n        UINT_32 pitch, UINT_32 height, UINT_32 x, UINT_32 y, UINT_32 slice,\n        UINT_32 numSlices, UINT_32 factor, BOOL_32 isLinear, BOOL_32 isWidth8,\n        BOOL_32 isHeight8, ADDR_TILEINFO* pTileInfo,\n        UINT_32* bitPosition) const;\n\n    virtual VOID HwlComputeXmaskCoordFromAddr(\n        UINT_64 addr, UINT_32 bitPosition, UINT_32 pitch, UINT_32 height, UINT_32 numSlices,\n        UINT_32 factor, BOOL_32 isLinear, BOOL_32 isWidth8, BOOL_32 isHeight8,\n        ADDR_TILEINFO* pTileInfo, UINT_32* pX, UINT_32* pY, UINT_32* pSlice) const;\n\n    // Surface mipmap\n    VOID    ComputeMipLevel(\n        ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    /// Pure Virtual function for Hwl to get macro tiled alignment info\n    virtual BOOL_32 HwlGetAlignmentInfoMacroTiled(\n        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        UINT_32* pPitchAlign, UINT_32* pHeightAlign, UINT_32* pSizeAlign) const = 0;\n\n\n    virtual VOID HwlOverrideTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const\n    {\n        // not supported in hwl layer\n    }\n\n    virtual VOID HwlOptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const\n    {\n        // not supported in hwl layer\n    }\n\n    virtual VOID HwlSelectTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const\n    {\n        // not supported in hwl layer\n    }\n\n    AddrTileMode DegradeLargeThickTile(AddrTileMode tileMode, UINT_32 bpp) const;\n\n    VOID PadDimensions(\n        AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,\n        UINT_32 numSamples, ADDR_TILEINFO* pTileInfo, UINT_32 padDims, UINT_32 mipLevel,\n        UINT_32* pPitch, UINT_32* pPitchAlign, UINT_32* pHeight, UINT_32 heightAlign,\n        UINT_32* pSlices, UINT_32 sliceAlign) const;\n\n    virtual VOID HwlPadDimensions(\n        AddrTileMode tileMode, UINT_32 bpp, ADDR_SURFACE_FLAGS flags,\n        UINT_32 numSamples, ADDR_TILEINFO* pTileInfo, UINT_32 mipLevel,\n        UINT_32* pPitch, UINT_32* pPitchAlign, UINT_32 height, UINT_32 heightAlign) const\n    {\n    }\n\n    //\n    // Addressing shared for linear/1D tiling\n    //\n    UINT_64 ComputeSurfaceAddrFromCoordLinear(\n        UINT_32 x, UINT_32 y, UINT_32 slice, UINT_32 sample,\n        UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSlices,\n        UINT_32* pBitPosition) const;\n\n    VOID    ComputeSurfaceCoordFromAddrLinear(\n        UINT_64 addr, UINT_32 bitPosition, UINT_32 bpp,\n        UINT_32 pitch, UINT_32 height, UINT_32 numSlices,\n        UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample) const;\n\n    VOID    ComputeSurfaceCoordFromAddrMicroTiled(\n        UINT_64 addr, UINT_32 bitPosition,\n        UINT_32 bpp, UINT_32 pitch, UINT_32 height, UINT_32 numSamples,\n        AddrTileMode tileMode, UINT_32 tileBase, UINT_32 compBits,\n        UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample,\n        AddrTileType microTileType, BOOL_32 isDepthSampleOrder) const;\n\n    ADDR_E_RETURNCODE ComputeMicroTileEquation(\n        UINT_32 bpp, AddrTileMode tileMode,\n        AddrTileType microTileType, ADDR_EQUATION* pEquation) const;\n\n    UINT_32 ComputePixelIndexWithinMicroTile(\n        UINT_32 x, UINT_32 y, UINT_32 z,\n        UINT_32 bpp, AddrTileMode tileMode, AddrTileType microTileType) const;\n\n    /// Pure Virtual function for Hwl computing coord from offset inside micro tile\n    virtual VOID HwlComputePixelCoordFromOffset(\n        UINT_32 offset, UINT_32 bpp, UINT_32 numSamples,\n        AddrTileMode tileMode, UINT_32 tileBase, UINT_32 compBits,\n        UINT_32* pX, UINT_32* pY, UINT_32* pSlice, UINT_32* pSample,\n        AddrTileType microTileType, BOOL_32 isDepthSampleOrder) const = 0;\n\n    //\n    // Addressing shared by all\n    //\n    virtual UINT_32 HwlGetPipes(\n        const ADDR_TILEINFO* pTileInfo) const;\n\n    UINT_32 ComputePipeFromAddr(\n        UINT_64 addr, UINT_32 numPipes) const;\n\n    virtual ADDR_E_RETURNCODE ComputePipeEquation(\n        UINT_32 log2BytesPP, UINT_32 threshX, UINT_32 threshY, ADDR_TILEINFO* pTileInfo, ADDR_EQUATION* pEquation) const\n    {\n        return ADDR_NOTSUPPORTED;\n    }\n\n    /// Pure Virtual function for Hwl computing pipe from coord\n    virtual UINT_32 ComputePipeFromCoord(\n        UINT_32 x, UINT_32 y, UINT_32 slice, AddrTileMode tileMode,\n        UINT_32 pipeSwizzle, BOOL_32 flags, ADDR_TILEINFO* pTileInfo) const = 0;\n\n    /// Pure Virtual function for Hwl computing coord Y for 8 pipe cmask/htile\n    virtual UINT_32 HwlComputeXmaskCoordYFrom8Pipe(\n        UINT_32 pipe, UINT_32 x) const = 0;\n\n    //\n    // Misc helper\n    //\n    static const TileModeFlags ModeFlags[ADDR_TM_COUNT];\n\n    static UINT_32 Thickness(\n        AddrTileMode tileMode);\n\n    // Checking tile mode\n    static BOOL_32 IsMacroTiled(AddrTileMode tileMode);\n    static BOOL_32 IsMacro3dTiled(AddrTileMode tileMode);\n    static BOOL_32 IsLinear(AddrTileMode tileMode);\n    static BOOL_32 IsMicroTiled(AddrTileMode tileMode);\n    static BOOL_32 IsPrtTileMode(AddrTileMode tileMode);\n    static BOOL_32 IsPrtNoRotationTileMode(AddrTileMode tileMode);\n\n    /// Return TRUE if tile info is needed\n    BOOL_32 UseTileInfo() const\n    {\n        return !m_configFlags.ignoreTileInfo;\n    }\n\n    /// Adjusts pitch alignment for flipping surface\n    VOID    AdjustPitchAlignment(\n        ADDR_SURFACE_FLAGS flags, UINT_32* pPitchAlign) const;\n\n    /// Overwrite tile config according to tile index\n    virtual ADDR_E_RETURNCODE HwlSetupTileCfg(\n        UINT_32 bpp, INT_32 index, INT_32 macroModeIndex,\n        ADDR_TILEINFO* pInfo, AddrTileMode* mode = NULL, AddrTileType* type = NULL) const;\n\n    /// Overwrite macro tile config according to tile index\n    virtual INT_32 HwlComputeMacroModeIndex(\n        INT_32 index, ADDR_SURFACE_FLAGS flags, UINT_32 bpp, UINT_32 numSamples,\n        ADDR_TILEINFO* pTileInfo, AddrTileMode *pTileMode = NULL, AddrTileType *pTileType = NULL\n        ) const\n    {\n        return TileIndexNoMacroIndex;\n    }\n\n    /// Pre-handler of 3x pitch (96 bit) adjustment\n    virtual UINT_32 HwlPreHandleBaseLvl3xPitch(\n        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, UINT_32 expPitch) const;\n    /// Post-handler of 3x pitch adjustment\n    virtual UINT_32 HwlPostHandleBaseLvl3xPitch(\n        const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, UINT_32 expPitch) const;\n    /// Check miplevel after surface adjustment\n    ADDR_E_RETURNCODE PostComputeMipLevel(\n        ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;\n\n    /// Quad buffer stereo support, has its implementation in ind. layer\n    VOID ComputeQbStereoInfo(\n        ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;\n\n    /// Pure virutual function to compute stereo bank swizzle for right eye\n    virtual UINT_32 HwlComputeQbStereoRightSwizzle(\n        ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const = 0;\n\n    VOID OptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const;\n\n    /// Overwrite tile setting to PRT\n    virtual VOID HwlSetPrtTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut) const\n    {\n    }\n\n    static BOOL_32 DegradeTo1D(\n        UINT_32 width, UINT_32 height,\n        UINT_32 macroTilePitchAlign, UINT_32 macroTileHeightAlign);\n\nprivate:\n    // Disallow the copy constructor\n    Lib(const Lib& a);\n\n    // Disallow the assignment operator\n    Lib& operator=(const Lib& a);\n\n    UINT_32 ComputeCmaskBaseAlign(\n        ADDR_CMASK_FLAGS flags, ADDR_TILEINFO*  pTileInfo) const;\n\n    UINT_64 ComputeCmaskBytes(\n        UINT_32 pitch, UINT_32 height, UINT_32 numSlices) const;\n\n    //\n    // CMASK/HTILE shared methods\n    //\n    VOID    ComputeTileDataWidthAndHeight(\n        UINT_32 bpp, UINT_32 cacheBits, ADDR_TILEINFO* pTileInfo,\n        UINT_32* pMacroWidth, UINT_32* pMacroHeight) const;\n\n    UINT_32 ComputeXmaskCoordYFromPipe(\n        UINT_32 pipe, UINT_32 x) const;\n};\n\n} // V1\n} // Addr\n} // namespace rocr\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib2.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n************************************************************************************************************************\n* @file  addrlib2.cpp\n* @brief Contains the implementation for the AddrLib2 base class.\n************************************************************************************************************************\n*/\n\n#include \"addrinterface.h\"\n#include \"addrlib2.h\"\n#include \"addrcommon.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};\n\nconst Dim3d Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Constructor/Destructor\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n************************************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the Addr::V2::Lib class\n*\n************************************************************************************************************************\n*/\nLib::Lib()\n    :\n    Addr::Lib(),\n    m_se(0),\n    m_rbPerSe(0),\n    m_maxCompFrag(0),\n    m_banksLog2(0),\n    m_pipesLog2(0),\n    m_seLog2(0),\n    m_rbPerSeLog2(0),\n    m_maxCompFragLog2(0),\n    m_pipeInterleaveLog2(0),\n    m_blockVarSizeLog2(0),\n    m_numEquations(0)\n{\n}\n\n/**\n************************************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the AddrLib2 class with hClient as parameter\n*\n************************************************************************************************************************\n*/\nLib::Lib(const Client* pClient)\n    :\n    Addr::Lib(pClient),\n    m_se(0),\n    m_rbPerSe(0),\n    m_maxCompFrag(0),\n    m_banksLog2(0),\n    m_pipesLog2(0),\n    m_seLog2(0),\n    m_rbPerSeLog2(0),\n    m_maxCompFragLog2(0),\n    m_pipeInterleaveLog2(0),\n    m_blockVarSizeLog2(0),\n    m_numEquations(0)\n{\n}\n\n/**\n************************************************************************************************************************\n*   Lib::~Lib\n*\n*   @brief\n*       Destructor for the AddrLib2 class\n*\n************************************************************************************************************************\n*/\nLib::~Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetLib\n*\n*   @brief\n*       Get Addr::V2::Lib pointer\n*\n*   @return\n*      An Addr::V2::Lib class pointer\n************************************************************************************************************************\n*/\nLib* Lib::GetLib(\n    ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE\n{\n    Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);\n    if ((pAddrLib != NULL) &&\n        (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))\n    {\n        // only valid and GFX9+ ASIC can use AddrLib2 function.\n        ADDR_ASSERT_ALWAYS();\n        hLib = NULL;\n    }\n    return static_cast<Lib*>(hLib);\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Surface Methods\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    // Adjust coming parameters.\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;\n    localIn.width        = Max(pIn->width, 1u);\n    localIn.height       = Max(pIn->height, 1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n    localIn.numSlices    = Max(pIn->numSlices, 1u);\n    localIn.numSamples   = Max(pIn->numSamples, 1u);\n    localIn.numFrags     = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;\n\n    UINT_32  expandX  = 1;\n    UINT_32  expandY  = 1;\n    ElemMode elemMode = ADDR_UNCOMPRESSED;\n\n    if (returnCode == ADDR_OK)\n    {\n        // Set format to INVALID will skip this conversion\n        if (localIn.format != ADDR_FMT_INVALID)\n        {\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,\n                                                        &elemMode,\n                                                        &expandX,\n                                                        &expandY);\n\n            // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is\n            // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-\n            // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw\n            // restrictions are different.\n            // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround\n            // but we use this flag to skip RestoreSurfaceInfo below\n\n            if ((elemMode == ADDR_EXPANDED) && (expandX > 1))\n            {\n                ADDR_ASSERT(IsLinear(localIn.swizzleMode));\n            }\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &localIn.bpp,\n                                            &basePitch,\n                                            &localIn.width,\n                                            &localIn.height);\n\n            // Overwrite these parameters if we have a valid format\n        }\n\n        if (localIn.bpp != 0)\n        {\n            localIn.width  = Max(localIn.width, 1u);\n            localIn.height = Max(localIn.height, 1u);\n        }\n        else // Rule out some invalid parameters\n        {\n            ADDR_ASSERT_ALWAYS();\n\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        returnCode = ComputeSurfaceInfoSanityCheck(&localIn);\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        VerifyMipLevelInfo(pIn);\n\n        if (IsLinear(pIn->swizzleMode))\n        {\n            // linear mode\n            returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);\n        }\n        else\n        {\n            // tiled mode\n            returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->bpp = localIn.bpp;\n            pOut->pixelPitch = pOut->pitch;\n            pOut->pixelHeight = pOut->height;\n            pOut->pixelMipChainPitch = pOut->mipChainPitch;\n            pOut->pixelMipChainHeight = pOut->mipChainHeight;\n            pOut->pixelBits = localIn.bpp;\n\n            if (localIn.format != ADDR_FMT_INVALID)\n            {\n                UINT_32 pixelBits = pOut->pixelBits;\n\n                GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                 expandX,\n                                                 expandY,\n                                                 &pOut->pixelBits,\n                                                 &pOut->pixelPitch,\n                                                 &pOut->pixelHeight);\n\n                GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                 expandX,\n                                                 expandY,\n                                                 &pixelBits,\n                                                 &pOut->pixelMipChainPitch,\n                                                 &pOut->pixelMipChainHeight);\n\n                if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))\n                {\n                    for (UINT_32 i = 0; i < localIn.numMipLevels; i++)\n                    {\n                        pOut->pMipInfo[i].pixelPitch  = pOut->pMipInfo[i].pitch;\n                        pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;\n\n                        GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                         expandX,\n                                                         expandY,\n                                                         &pixelBits,\n                                                         &pOut->pMipInfo[i].pixelPitch,\n                                                         &pOut->pMipInfo[i].pixelHeight);\n                    }\n                }\n            }\n\n            if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))\n            {\n                pOut->equationIndex = GetEquationIndex(&localIn, pOut);\n                if ((localIn.flags.allowExtEquation == 0) &&\n                    (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX) &&\n                    (m_equationTable[pOut->equationIndex].numBitComponents > ADDR_MAX_LEGACY_EQUATION_COMP))\n                {\n                    pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;\n                }\n            }\n\n            if (localIn.flags.qbStereo)\n            {\n                if (pOut->pStereoInfo != NULL)\n                {\n                    ComputeQbStereoInfo(pOut);\n#if DEBUG\n                    ValidateStereoInfo(pIn, pOut);\n#endif\n                }\n            }\n        }\n    }\n\n    ADDR_ASSERT(pOut->surfSize != 0);\n\n    ValidBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(\n    const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;\n    localIn.unalignedWidth  = Max(pIn->unalignedWidth, 1u);\n    localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n    localIn.numMipLevels    = Max(pIn->numMipLevels, 1u);\n    localIn.numSlices       = Max(pIn->numSlices, 1u);\n    localIn.numSamples      = Max(pIn->numSamples, 1u);\n    localIn.numFrags        = Max(pIn->numFrags, 1u);\n\n    if ((localIn.bpp < 8)        ||\n        (localIn.bpp > 128)      ||\n        ((localIn.bpp % 8) != 0) ||\n        (localIn.sample >= localIn.numSamples)  ||\n        (localIn.slice >= localIn.numSlices)    ||\n        (localIn.mipId >= localIn.numMipLevels) ||\n        (IsTex3d(localIn.resourceType) &&\n         (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        if (IsLinear(localIn.swizzleMode))\n        {\n            returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);\n        }\n        else\n        {\n            returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddr\n*\n*   @brief\n*       Interface function stub of ComputeSurfaceCoordFromAddr.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(\n    const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||\n            (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if ((pIn->bpp < 8)        ||\n        (pIn->bpp > 128)      ||\n        ((pIn->bpp % 8) != 0) ||\n        (pIn->bitPosition >= 8))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        if (IsLinear(pIn->swizzleMode))\n        {\n            returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);\n        }\n        else\n        {\n            returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               CMASK/HTILE\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeHtileInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeHtilenfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileInfo(\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeHtileInfo(pIn, pOut);\n\n        ValidMetaBaseAlignments(pOut->baseAlign);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeHtileAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeHtileCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeCmaskInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskInfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskInfo(\n    const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else if (pIn->cMaskFlags.linear)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeCmaskInfo(pIn, pOut);\n\n        ValidMetaBaseAlignments(pOut->baseAlign);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(\n    const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeCmaskCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(\n    const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;\n\n    ADDR_NOT_IMPLEMENTED();\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeFmaskInfo\n*\n*   @brief\n*       Interface function stub of ComputeFmaskInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskInfo(\n    const ADDR2_COMPUTE_FMASK_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_FMASK_INFO_OUTPUT*         pOut    ///< [out] output structure\n    )\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&\n                    ((pIn->numSamples > 0) || (pIn->numFrags > 0));\n\n    if (GetFillSizeFieldsFlags())\n    {\n        if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))\n        {\n            valid = FALSE;\n        }\n    }\n\n    if (valid == FALSE)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn = {0};\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n\n        localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);\n        localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);\n\n        localIn.swizzleMode  = pIn->swizzleMode;\n        localIn.numSlices    = Max(pIn->numSlices, 1u);\n        localIn.width        = Max(pIn->unalignedWidth, 1u);\n        localIn.height       = Max(pIn->unalignedHeight, 1u);\n        localIn.bpp          = GetFmaskBpp(pIn->numSamples, pIn->numFrags);\n        localIn.flags.fmask  = 1;\n        localIn.numFrags     = 1;\n        localIn.numSamples   = 1;\n        localIn.resourceType = ADDR_RSRC_TEX_2D;\n\n        if (localIn.bpp == 8)\n        {\n            localIn.format = ADDR_FMT_8;\n        }\n        else if (localIn.bpp == 16)\n        {\n            localIn.format = ADDR_FMT_16;\n        }\n        else if (localIn.bpp == 32)\n        {\n            localIn.format = ADDR_FMT_32;\n        }\n        else\n        {\n            localIn.format = ADDR_FMT_32_32;\n        }\n\n        returnCode = ComputeSurfaceInfo(&localIn, &localOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->pitch      = localOut.pitch;\n            pOut->height     = localOut.height;\n            pOut->baseAlign  = localOut.baseAlign;\n            pOut->numSlices  = localOut.numSlices;\n            pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);\n            pOut->sliceSize  = static_cast<UINT_32>(localOut.sliceSize);\n            pOut->bpp        = localIn.bpp;\n            pOut->numSamples = 1;\n        }\n    }\n\n    ValidBaseAlignments(pOut->baseAlign);\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeFmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of ComputeFmaskAddrFromCoord.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(\n    const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*        pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;\n\n    ADDR_NOT_IMPLEMENTED();\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeFmaskCoordFromAddr\n*\n*   @brief\n*       Interface function stub of ComputeFmaskAddrFromCoord.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(\n    const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT*  pIn,     ///< [in] input structure\n    ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*       pOut     ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;\n\n    ADDR_NOT_IMPLEMENTED();\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeDccInfo\n*\n*   @brief\n*       Interface function to compute DCC key info\n*\n*   @return\n*       return code of HwlComputeDccInfo\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeDccInfo(\n    const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeDccInfo(pIn, pOut);\n\n        ValidMetaBaseAlignments(pOut->dccRamBaseAlign);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeDccAddrFromCoord\n*\n*   @brief\n*       Interface function stub of ComputeDccAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlSupportComputeDccAddrFromCoord(pIn);\n\n        if (returnCode == ADDR_OK)\n        {\n            HwlComputeDccAddrFromCoord(pIn, pOut);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputePipeBankXor\n*\n*   @brief\n*       Interface function stub of Addr2ComputePipeBankXor.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputePipeBankXor(\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputePipeBankXor(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSlicePipeBankXor\n*\n*   @brief\n*       Interface function stub of Addr2ComputeSlicePipeBankXor.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||\n             (IsNonPrtXor(pIn->swizzleMode) == FALSE) ||\n             (pIn->numSamples > 1))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else if ((pIn->bpe != 0) &&\n             (pIn->bpe != 8) &&\n             (pIn->bpe != 16) &&\n             (pIn->bpe != 32) &&\n             (pIn->bpe != 64) &&\n             (pIn->bpe != 128))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeNonBlockCompressedView\n*\n*   @brief\n*       Interface function stub of Addr2ComputeNonBlockCompressedView.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeNonBlockCompressedView(\n    const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n    ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeNonBlockCompressedView(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ExtractPipeBankXor\n*\n*   @brief\n*       Internal function to extract bank and pipe xor bits from combined xor bits.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ExtractPipeBankXor(\n    UINT_32  pipeBankXor,\n    UINT_32  bankBits,\n    UINT_32  pipeBits,\n    UINT_32* pBankX,\n    UINT_32* pPipeX)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if (pipeBankXor < (1u << (pipeBits + bankBits)))\n    {\n        *pPipeX = pipeBankXor % (1 << pipeBits);\n        *pBankX = pipeBankXor >> pipeBits;\n        returnCode = ADDR_OK;\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfoSanityCheck\n*\n*   @brief\n*       Internal function to do basic sanity check before compute surface info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT*  pIn   ///< [in] input structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ApplyCustomizedPitchHeight\n*\n*   @brief\n*       Helper function to override hw required row pitch/slice pitch by customrized one\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n    UINT_32  elementBytes,                          ///< [in] element bytes per element\n    UINT_32  pitchAlignInElement,                   ///< [in] pitch alignment in element\n    UINT_32* pPitch,                                ///< [in,out] pitch\n    UINT_32* pHeight                                ///< [in,out] height\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->numMipLevels <= 1)\n    {\n        if (pIn->pitchInElement > 0)\n        {\n            if ((pIn->pitchInElement % pitchAlignInElement) != 0)\n            {\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n            else if (pIn->pitchInElement < (*pPitch))\n            {\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n            else\n            {\n                *pPitch = pIn->pitchInElement;\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            if (pIn->sliceAlign > 0)\n            {\n                UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);\n\n                if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)\n                {\n                    returnCode = ADDR_INVALIDPARAMS;\n                }\n                else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))\n                {\n                    returnCode = ADDR_INVALIDPARAMS;\n                }\n                else\n                {\n                    *pHeight = customizedHeight;\n                }\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfoLinear\n*\n*   @brief\n*       Internal function to calculate alignment for linear swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    return HwlComputeSurfaceInfoLinear(pIn, pOut);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfoTiled\n*\n*   @brief\n*       Internal function to calculate alignment for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    return HwlComputeSurfaceInfoTiled(pIn, pOut);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoordLinear\n*\n*   @brief\n*       Internal function to calculate address from coord for linear swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n    BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);\n\n    if (valid)\n    {\n        if (IsTex1d(pIn->resourceType))\n        {\n            valid = (pIn->y == 0);\n        }\n    }\n\n    if (valid)\n    {\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n        ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];\n        ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n\n        localIn.bpp          = pIn->bpp;\n        localIn.flags        = pIn->flags;\n        localIn.width        = Max(pIn->unalignedWidth, 1u);\n        localIn.height       = Max(pIn->unalignedHeight, 1u);\n        localIn.numSlices    = Max(pIn->numSlices, 1u);\n        localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n        localIn.resourceType = pIn->resourceType;\n\n        if (localIn.numMipLevels <= 1)\n        {\n            localIn.pitchInElement = pIn->pitchInElement;\n        }\n\n        localOut.pMipInfo = mipInfo;\n\n        returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->addr        = (localOut.sliceSize * pIn->slice) +\n                                mipInfo[pIn->mipId].offset +\n                                (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);\n            pOut->bitPosition = 0;\n        }\n        else\n        {\n            valid = FALSE;\n        }\n    }\n\n    if (valid == FALSE)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddrLinear\n*\n*   @brief\n*       Internal function to calculate coord from address for linear swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(\n     const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);\n\n    if (valid)\n    {\n        if (IsTex1d(pIn->resourceType))\n        {\n            valid = (pIn->unalignedHeight == 1);\n        }\n    }\n\n    if (valid)\n    {\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n        localIn.bpp          = pIn->bpp;\n        localIn.flags        = pIn->flags;\n        localIn.width        = Max(pIn->unalignedWidth, 1u);\n        localIn.height       = Max(pIn->unalignedHeight, 1u);\n        localIn.numSlices    = Max(pIn->numSlices, 1u);\n        localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n        localIn.resourceType = pIn->resourceType;\n        if (localIn.numMipLevels <= 1)\n        {\n            localIn.pitchInElement = pIn->pitchInElement;\n        }\n        returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);\n            pOut->sample = 0;\n\n            UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);\n            UINT_32 elementBytes = pIn->bpp >> 3;\n            UINT_32 mipOffsetInSlice = 0;\n            UINT_32 mipSize = 0;\n            UINT_32 mipId = 0;\n            for (; mipId < pIn->numMipLevels ; mipId++)\n            {\n                if (IsTex1d(pIn->resourceType))\n                {\n                    mipSize = localOut.pitch * elementBytes;\n                }\n                else\n                {\n                    UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;\n                    mipSize = currentMipHeight * localOut.pitch * elementBytes;\n                }\n\n                if (mipSize == 0)\n                {\n                    valid = FALSE;\n                    break;\n                }\n                else if ((mipSize + mipOffsetInSlice) > offsetInSlice)\n                {\n                    break;\n                }\n                else\n                {\n                    mipOffsetInSlice += mipSize;\n                    if ((mipId == (pIn->numMipLevels - 1)) ||\n                        (mipOffsetInSlice >= localOut.sliceSize))\n                    {\n                        valid = FALSE;\n                    }\n                }\n            }\n\n            if (valid)\n            {\n                pOut->mipId = mipId;\n\n                UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;\n                if (IsTex1d(pIn->resourceType))\n                {\n                    if (elemOffsetInMip < localOut.pitch)\n                    {\n                        pOut->x = elemOffsetInMip;\n                        pOut->y = 0;\n                    }\n                    else\n                    {\n                        valid = FALSE;\n                    }\n                }\n                else\n                {\n                    pOut->y = elemOffsetInMip / localOut.pitch;\n                    pOut->x = elemOffsetInMip % localOut.pitch;\n                }\n\n                if ((pOut->slice >= pIn->numSlices)    ||\n                    (pOut->mipId >= pIn->numMipLevels) ||\n                    (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u))  ||\n                    (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||\n                    (IsTex3d(pIn->resourceType) &&\n                     (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,\n                                                           pOut->mipId,\n                                                           pOut->slice))))\n                {\n                    valid = FALSE;\n                }\n            }\n        }\n        else\n        {\n            valid = FALSE;\n        }\n    }\n\n    if (valid == FALSE)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceCoordFromAddrTiled\n*\n*   @brief\n*       Internal function to calculate coord from address for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(\n     const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;\n\n    ADDR_NOT_IMPLEMENTED();\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeBlockDimensionForSurf\n*\n*   @brief\n*       Internal function to get block width/height/depth in element from surface input params.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(\n    UINT_32*         pWidth,\n    UINT_32*         pHeight,\n    UINT_32*         pDepth,\n    UINT_32          bpp,\n    UINT_32          numSamples,\n    AddrResourceType resourceType,\n    AddrSwizzleMode  swizzleMode) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsThick(resourceType, swizzleMode))\n    {\n        ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);\n    }\n    else if (IsThin(resourceType, swizzleMode))\n    {\n        ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, numSamples, resourceType, swizzleMode);\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeThinBlockDimension\n*\n*   @brief\n*       Internal function to get thin block width/height/depth in element from surface input params.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Lib::ComputeThinBlockDimension(\n    UINT_32*         pWidth,\n    UINT_32*         pHeight,\n    UINT_32*         pDepth,\n    UINT_32          bpp,\n    UINT_32          numSamples,\n    AddrResourceType resourceType,\n    AddrSwizzleMode  swizzleMode) const\n{\n    ADDR_ASSERT(IsThin(resourceType, swizzleMode));\n\n    // GFX9/GFX10 use different dimension amplifying logic: say for 128KB block + 1xAA + 1BPE, the dimension of thin\n    // swizzle mode will be [256W * 512H] on GFX9 ASICs and [512W * 256H] on GFX10 ASICs. Since GFX10 is newer HWL so we\n    // make its implementation into base class (in order to save future change on new HWLs)\n    const UINT_32 log2BlkSize  = GetBlockSizeLog2(swizzleMode);\n    const UINT_32 log2EleBytes = Log2(bpp >> 3);\n    const UINT_32 log2Samples  = Log2(Max(numSamples, 1u));\n    const UINT_32 log2NumEle   = log2BlkSize - log2EleBytes - log2Samples;\n\n    // For \"1xAA/4xAA cases\" or \"2xAA/8xAA + odd log2BlkSize cases\", width == height or width == 2 * height;\n    // For other cases, height == width or height == 2 * width\n    const BOOL_32 widthPrecedent = ((log2Samples & 1) == 0) || ((log2BlkSize & 1) != 0);\n    const UINT_32 log2Width      = (log2NumEle + (widthPrecedent ? 1 : 0)) / 2;\n\n    *pWidth  = 1u << log2Width;\n    *pHeight = 1u << (log2NumEle - log2Width);\n    *pDepth  = 1;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeBlockDimension\n*\n*   @brief\n*       Internal function to get block width/height/depth in element without considering MSAA case\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeBlockDimension(\n    UINT_32*         pWidth,\n    UINT_32*         pHeight,\n    UINT_32*         pDepth,\n    UINT_32          bpp,\n    AddrResourceType resourceType,\n    AddrSwizzleMode  swizzleMode) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsThick(resourceType, swizzleMode))\n    {\n        ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);\n    }\n    else if (IsThin(resourceType, swizzleMode))\n    {\n        ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, 0, resourceType, swizzleMode);\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeThickBlockDimension\n*\n*   @brief\n*       Internal function to get block width/height/depth in element for thick swizzle mode\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Lib::ComputeThickBlockDimension(\n    UINT_32*         pWidth,\n    UINT_32*         pHeight,\n    UINT_32*         pDepth,\n    UINT_32          bpp,\n    AddrResourceType resourceType,\n    AddrSwizzleMode  swizzleMode) const\n{\n    ADDR_ASSERT(IsThick(resourceType, swizzleMode));\n\n    const UINT_32 log2BlkSize              = GetBlockSizeLog2(swizzleMode);\n    const UINT_32 eleBytes                 = bpp >> 3;\n    const UINT_32 microBlockSizeTableIndex = Log2(eleBytes);\n\n    ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));\n\n    const UINT_32 log2blkSizeIn1KB = log2BlkSize - 10;\n    const UINT_32 averageAmp       = log2blkSizeIn1KB / 3;\n    const UINT_32 restAmp          = log2blkSizeIn1KB % 3;\n\n    *pWidth  = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;\n    *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));\n    *pDepth  = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetMipTailDim\n*\n*   @brief\n*       Internal function to get out max dimension of first level in mip tail\n*\n*   @return\n*       Max Width/Height/Depth value of the first mip fitted in mip tail\n************************************************************************************************************************\n*/\nDim3d Lib::GetMipTailDim(\n    AddrResourceType  resourceType,\n    AddrSwizzleMode   swizzleMode,\n    UINT_32           blockWidth,\n    UINT_32           blockHeight,\n    UINT_32           blockDepth) const\n{\n    Dim3d   out         = {blockWidth, blockHeight, blockDepth};\n    UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);\n\n    if (IsThick(resourceType, swizzleMode))\n    {\n        UINT_32 dim = log2BlkSize % 3;\n\n        if (dim == 0)\n        {\n            out.h >>= 1;\n        }\n        else if (dim == 1)\n        {\n            out.w >>= 1;\n        }\n        else\n        {\n            out.d >>= 1;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT(IsThin(resourceType, swizzleMode));\n\n#if DEBUG\n        // GFX9/GFX10 use different dimension shrinking logic for mipmap tail: say for 128KB block + 2BPE, the maximum\n        // dimension of mipmap tail level will be [256W * 128H] on GFX9 ASICs and [128W * 256H] on GFX10 ASICs. Since\n        // GFX10 is newer HWL so we make its implementation into base class, in order to save future change on new HWLs.\n        // And assert log2BlkSize will always be an even value on GFX9, so we never need the logic wrapped by DEBUG...\n        if ((log2BlkSize & 1) && (m_chipFamily == ADDR_CHIP_FAMILY_AI))\n        {\n            // Should never go here...\n            ADDR_ASSERT_ALWAYS();\n\n            out.h >>= 1;\n        }\n        else\n#endif\n        {\n            out.w >>= 1;\n        }\n    }\n\n    return out;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurface2DMicroBlockOffset\n*\n*   @brief\n*       Internal function to calculate micro block (256B) offset from coord for 2D resource\n*\n*   @return\n*       micro block (256B) offset for 2D resource\n************************************************************************************************************************\n*/\nUINT_32 Lib::ComputeSurface2DMicroBlockOffset(\n    const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const\n{\n    ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));\n\n    UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);\n    UINT_32 microBlockOffset = 0;\n    if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))\n    {\n        UINT_32 xBits = pIn->x << log2ElementBytes;\n        microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);\n        if (log2ElementBytes < 3)\n        {\n            microBlockOffset |= (pIn->y & 0x4) << 4;\n            if (log2ElementBytes == 0)\n            {\n                microBlockOffset |= (pIn->y & 0x8) << 4;\n            }\n            else\n            {\n                microBlockOffset |= (xBits & 0x10) << 3;\n            }\n        }\n        else\n        {\n            microBlockOffset |= (xBits & 0x30) << 2;\n        }\n    }\n    else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))\n    {\n        if (log2ElementBytes == 4)\n        {\n            microBlockOffset = (GetBit(pIn->x, 0) << 4) |\n                               (GetBit(pIn->y, 0) << 5) |\n                               (GetBit(pIn->x, 1) << 6) |\n                               (GetBit(pIn->y, 1) << 7);\n        }\n        else\n        {\n            microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes)     |\n                               GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |\n                               GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |\n                               GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);\n            microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |\n                               (GetBit(pIn->y, 0) << 4) |\n                               GetBits(microBlockOffset, 4, 3, 5);\n        }\n    }\n    else if (IsRotateSwizzle(pIn->swizzleMode))\n    {\n        microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |\n                           GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |\n                           GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |\n                           GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);\n        microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |\n                           (GetBit(pIn->x, 0) << 4) |\n                           GetBits(microBlockOffset, 4, 3, 5);\n        if (log2ElementBytes == 3)\n        {\n           microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |\n                              GetBits(pIn->x, 1, 2, 6);\n        }\n    }\n\n    return microBlockOffset;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurface3DMicroBlockOffset\n*\n*   @brief\n*       Internal function to calculate micro block (1KB) offset from coord for 3D resource\n*\n*   @return\n*       micro block (1KB) offset for 3D resource\n************************************************************************************************************************\n*/\nUINT_32 Lib::ComputeSurface3DMicroBlockOffset(\n    const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const\n{\n    ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));\n\n    UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);\n    UINT_32 microBlockOffset = 0;\n    if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))\n    {\n        if (log2ElementBytes == 0)\n        {\n            microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);\n        }\n        else if (log2ElementBytes == 1)\n        {\n            microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);\n        }\n        else if (log2ElementBytes == 2)\n        {\n            microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);\n        }\n        else if (log2ElementBytes == 3)\n        {\n            microBlockOffset = (pIn->x & 6) >> 1;\n        }\n        else\n        {\n            microBlockOffset = pIn->x & 3;\n        }\n\n        microBlockOffset <<= 8;\n\n        UINT_32 xBits = pIn->x << log2ElementBytes;\n        microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);\n    }\n    else if (IsZOrderSwizzle(pIn->swizzleMode))\n    {\n        UINT_32 xh, yh, zh;\n\n        if (log2ElementBytes == 0)\n        {\n            microBlockOffset =\n                (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);\n            microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);\n\n            xh = pIn->x >> 3;\n            yh = pIn->y >> 2;\n            zh = pIn->slice >> 2;\n        }\n        else if (log2ElementBytes == 1)\n        {\n            microBlockOffset =\n                (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);\n            microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);\n\n            xh = pIn->x >> 2;\n            yh = pIn->y >> 2;\n            zh = pIn->slice >> 2;\n        }\n        else if (log2ElementBytes == 2)\n        {\n            microBlockOffset =\n                (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);\n            microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);\n\n            xh = pIn->x >> 2;\n            yh = pIn->y >> 2;\n            zh = pIn->slice >> 1;\n        }\n        else if (log2ElementBytes == 3)\n        {\n            microBlockOffset =\n                (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);\n            microBlockOffset <<= 3;\n\n            xh = pIn->x >> 2;\n            yh = pIn->y >> 1;\n            zh = pIn->slice >> 1;\n        }\n        else\n        {\n            microBlockOffset =\n                (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);\n\n            xh = pIn->x >> 1;\n            yh = pIn->y >> 1;\n            zh = pIn->slice >> 1;\n        }\n\n        microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);\n    }\n\n    return microBlockOffset;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetPipeXorBits\n*\n*   @brief\n*       Internal function to get bits number for pipe/se xor operation\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nUINT_32 Lib::GetPipeXorBits(\n    UINT_32 macroBlockBits) const\n{\n    ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);\n\n    // Total available xor bits\n    UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;\n\n    // Pipe/Se xor bits\n    UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);\n\n    return pipeBits;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::Addr2GetPreferredSurfaceSetting\n*\n*   @brief\n*       Internal function to get suggested surface information for cliet to use\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetPossibleSwizzleModes\n*\n*   @brief\n*       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const\n{\n    return HwlGetPossibleSwizzleModes(pIn, pOut);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetAllowedBlockSet\n*\n*   @brief\n*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetAllowedBlockSet(\n    ADDR2_SWMODE_SET allowedSwModeSet,\n    AddrResourceType rsrcType,\n    ADDR2_BLOCK_SET* pAllowedBlockSet) const\n{\n    return HwlGetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetAllowedSwSet\n*\n*   @brief\n*       Returns the set of allowed swizzle types given the allowed swizzle modes\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetAllowedSwSet(\n    ADDR2_SWMODE_SET  allowedSwModeSet,\n    ADDR2_SWTYPE_SET* pAllowedSwSet) const\n{\n    return HwlGetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeBlock256Equation\n*\n*   @brief\n*       Compute equation for block 256B\n*\n*   @return\n*       If equation computed successfully\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeBlock256Equation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode swMode,\n    UINT_32 elementBytesLog2,\n    ADDR_EQUATION* pEquation) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    if (IsBlock256b(swMode))\n    {\n        ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        ret = ADDR_INVALIDPARAMS;\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeThinEquation\n*\n*   @brief\n*       Compute equation for 2D/3D resource which use THIN mode\n*\n*   @return\n*       If equation computed successfully\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeThinEquation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode swMode,\n    UINT_32 elementBytesLog2,\n    ADDR_EQUATION* pEquation) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    if (IsThin(rsrcType, swMode))\n    {\n        ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        ret = ADDR_INVALIDPARAMS;\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeThickEquation\n*\n*   @brief\n*       Compute equation for 3D resource which use THICK mode\n*\n*   @return\n*       If equation computed successfully\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeThickEquation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode swMode,\n    UINT_32 elementBytesLog2,\n    ADDR_EQUATION* pEquation) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    if (IsThick(rsrcType, swMode))\n    {\n        ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        ret = ADDR_INVALIDPARAMS;\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeQbStereoInfo\n*\n*   @brief\n*       Get quad buffer stereo information\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Lib::ComputeQbStereoInfo(\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut    ///< [in,out] updated pOut+pStereoInfo\n    ) const\n{\n    ADDR_ASSERT(pOut->bpp >= 8);\n    ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);\n\n    // Save original height\n    pOut->pStereoInfo->eyeHeight = pOut->height;\n\n    // Right offset\n    pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);\n\n    // Double height\n    pOut->height <<= 1;\n\n    ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);\n\n    pOut->pixelHeight <<= 1;\n\n    // Double size\n    pOut->surfSize  <<= 1;\n    pOut->sliceSize <<= 1;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::FilterInvalidEqSwizzleMode\n*\n*   @brief\n*       Filter out swizzle mode(s) if it doesn't have valid equation index\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Lib::FilterInvalidEqSwizzleMode(\n    ADDR2_SWMODE_SET& allowedSwModeSet,\n    AddrResourceType  resourceType,\n    UINT_32           elemLog2,\n    UINT_32           maxComponents\n    ) const\n{\n    if (resourceType != ADDR_RSRC_TEX_1D)\n    {\n        UINT_32       allowedSwModeSetVal = allowedSwModeSet.value;\n        const UINT_32 rsrcTypeIdx         = static_cast<UINT_32>(resourceType) - 1;\n        UINT_32       validSwModeSet      = allowedSwModeSetVal;\n\n        for (UINT_32 swModeIdx = 1; validSwModeSet != 0; swModeIdx++)\n        {\n            if (validSwModeSet & 1)\n            {\n                UINT_32 equation = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];\n                if (equation == ADDR_INVALID_EQUATION_INDEX)\n                {\n                    allowedSwModeSetVal &= ~(1u << swModeIdx);\n                }\n                else if (m_equationTable[equation].numBitComponents > maxComponents)\n                {\n                    allowedSwModeSetVal &= ~(1u << swModeIdx);\n                }\n            }\n\n            validSwModeSet >>= 1;\n        }\n\n        // Only apply the filtering if at least one valid swizzle mode remains\n        if (allowedSwModeSetVal != 0)\n        {\n            allowedSwModeSet.value = allowedSwModeSetVal;\n        }\n    }\n}\n\n#if DEBUG\n/**\n************************************************************************************************************************\n*   Lib::ValidateStereoInfo\n*\n*   @brief\n*       Validate stereo info by checking a few typical cases\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Lib::ValidateStereoInfo(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT*  pIn,   ///< [in] input structure\n    const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut   ///< [in] output structure\n    ) const\n{\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT addrIn = {};\n    addrIn.size            = sizeof(addrIn);\n    addrIn.swizzleMode     = pIn->swizzleMode;\n    addrIn.flags           = pIn->flags;\n    addrIn.flags.qbStereo  = 0;\n    addrIn.resourceType    = pIn->resourceType;\n    addrIn.bpp             = pIn->bpp;\n    addrIn.unalignedWidth  = pIn->width;\n    addrIn.numSlices       = pIn->numSlices;\n    addrIn.numMipLevels    = pIn->numMipLevels;\n    addrIn.numSamples      = pIn->numSamples;\n    addrIn.numFrags        = pIn->numFrags;\n\n    // Call Addr2ComputePipeBankXor() and validate different pbXor value if necessary...\n    const UINT_32 pbXor = 0;\n\n    ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT addrOut = {};\n    addrOut.size = sizeof(addrOut);\n\n    // Make the array to be {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096} for full test\n    const UINT_32 TestCoord[] = {0};\n\n    for (UINT_32 xIdx = 0; xIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); xIdx++)\n    {\n        if (TestCoord[xIdx] < pIn->width)\n        {\n            addrIn.x = TestCoord[xIdx];\n\n            for (UINT_32 yIdx = 0; yIdx  < sizeof(TestCoord) / sizeof(TestCoord[0]); yIdx++)\n            {\n                if (TestCoord[yIdx] < pIn->height)\n                {\n                    addrIn.y               = TestCoord[yIdx] + pOut->pStereoInfo->eyeHeight;\n                    addrIn.pipeBankXor     = pbXor ^ pOut->pStereoInfo->rightSwizzle;\n                    addrIn.unalignedHeight = pIn->height + pOut->pStereoInfo->eyeHeight;\n\n                    ADDR_E_RETURNCODE ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);\n                    ADDR_ASSERT(ret == ADDR_OK);\n\n                    const UINT_64 rightEyeOffsetFromBase = addrOut.addr;\n\n                    addrIn.y               = TestCoord[yIdx];\n                    addrIn.pipeBankXor     = pbXor;\n                    addrIn.unalignedHeight = pIn->height;\n\n                    ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);\n                    ADDR_ASSERT(ret == ADDR_OK);\n\n                    const UINT_64 rightEyeOffsetRelative = addrOut.addr;\n\n                    ADDR_ASSERT(rightEyeOffsetFromBase == rightEyeOffsetRelative + pOut->pStereoInfo->rightOffset);\n                }\n            }\n        }\n    }\n}\n#endif\n\n} // V2\n} // Addr\n} // namespace rocr\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib2.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n************************************************************************************************************************\n* @file  addrlib2.h\n* @brief Contains the Addr::V2::Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __ADDR2_LIB2_H__\n#define __ADDR2_LIB2_H__\n\n#include \"addrlib.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\n/**\n************************************************************************************************************************\n* @brief Flags for SwizzleModeTable\n************************************************************************************************************************\n*/\nunion SwizzleModeFlags\n{\n    struct\n    {\n        // Swizzle mode\n        UINT_32 isLinear        : 1;    // Linear\n\n        // Block size\n        UINT_32 is256b          : 1;    // Block size is 256B\n        UINT_32 is4kb           : 1;    // Block size is 4KB\n        UINT_32 is64kb          : 1;    // Block size is 64KB\n        UINT_32 isVar           : 1;    // Block size is variable\n\n        UINT_32 isZ             : 1;    // Z order swizzle mode\n        UINT_32 isStd           : 1;    // Standard swizzle mode\n        UINT_32 isDisp          : 1;    // Display swizzle mode\n        UINT_32 isRot           : 1;    // Rotate swizzle mode\n\n        // XOR mode\n        UINT_32 isXor           : 1;    // XOR after swizzle if set\n\n        UINT_32 isT             : 1;    // T mode\n\n        // GFX10\n        UINT_32 isRtOpt         : 1;    // mode opt for render target\n\n        UINT_32 reserved        : 20;   // Reserved bits\n    };\n\n    UINT_32 u32All;\n};\n\nstruct Dim2d\n{\n    UINT_32 w;\n    UINT_32 h;\n};\n\nstruct Dim3d\n{\n    UINT_32 w;\n    UINT_32 h;\n    UINT_32 d;\n};\n\n// Macro define resource block type\nenum AddrBlockType\n{\n    AddrBlockLinear    = 0, // Resource uses linear swizzle mode\n    AddrBlockMicro     = 1, // Resource uses 256B block\n    AddrBlockThin4KB   = 2, // Resource uses thin 4KB block\n    AddrBlockThick4KB  = 3, // Resource uses thick 4KB block\n    AddrBlockThin64KB  = 4, // Resource uses thin 64KB block\n    AddrBlockThick64KB = 5, // Resource uses thick 64KB block\n    AddrBlockThinVar   = 6, // Resource uses thin var block\n    AddrBlockThickVar  = 7, // Resource uses thick var block\n    AddrBlockMaxTiledType,\n\n    AddrBlockThin256KB  = AddrBlockThinVar,\n    AddrBlockThick256KB = AddrBlockThickVar,\n};\n\nenum AddrSwSet\n{\n    AddrSwSetZ = 1 << ADDR_SW_Z,\n    AddrSwSetS = 1 << ADDR_SW_S,\n    AddrSwSetD = 1 << ADDR_SW_D,\n    AddrSwSetR = 1 << ADDR_SW_R,\n\n    AddrSwSetAll = AddrSwSetZ | AddrSwSetS | AddrSwSetD | AddrSwSetR,\n};\n\nconst UINT_32 Size256 = 256u;\nconst UINT_32 Size4K  = 4096u;\nconst UINT_32 Size64K = 65536u;\n\nconst UINT_32 Log2Size256 = 8u;\nconst UINT_32 Log2Size4K  = 12u;\nconst UINT_32 Log2Size64K = 16u;\n\n/**\n************************************************************************************************************************\n* @brief Bit setting for swizzle pattern\n************************************************************************************************************************\n*/\nunion ADDR_BIT_SETTING\n{\n    struct\n    {\n        UINT_16 x;\n        UINT_16 y;\n        UINT_16 z;\n        UINT_16 s;\n    };\n    UINT_64 value;\n};\n\n/**\n************************************************************************************************************************\n* @brief Swizzle pattern information\n************************************************************************************************************************\n*/\n// Accessed by index representing the logbase2 of (8bpp/16bpp/32bpp/64bpp/128bpp)\n// contains the indices which map to 2D arrays SW_PATTERN_NIBBLE[0-9] which contain sections of an index equation. They are dependant on pipe# and bpe #\nstruct ADDR_SW_PATINFO\n{\n    UINT_8  maxItemCount;\n    UINT_8  nibble01Idx;\n    UINT_16 nibble2Idx;\n    UINT_16 nibble3Idx;\n    UINT_8  nibble4Idx;\n};\n\n/**\n************************************************************************************************************************\n*   InitBit\n*\n*   @brief\n*       Initialize bit setting value via a return value\n************************************************************************************************************************\n*/\n#define InitBit(c, index) (1ull << ((c << 4) + index))\n\nconst UINT_64 X0  = InitBit(0,  0);\nconst UINT_64 X1  = InitBit(0,  1);\nconst UINT_64 X2  = InitBit(0,  2);\nconst UINT_64 X3  = InitBit(0,  3);\nconst UINT_64 X4  = InitBit(0,  4);\nconst UINT_64 X5  = InitBit(0,  5);\nconst UINT_64 X6  = InitBit(0,  6);\nconst UINT_64 X7  = InitBit(0,  7);\nconst UINT_64 X8  = InitBit(0,  8);\nconst UINT_64 X9  = InitBit(0,  9);\nconst UINT_64 X10 = InitBit(0, 10);\nconst UINT_64 X11 = InitBit(0, 11);\n\nconst UINT_64 Y0  = InitBit(1,  0);\nconst UINT_64 Y1  = InitBit(1,  1);\nconst UINT_64 Y2  = InitBit(1,  2);\nconst UINT_64 Y3  = InitBit(1,  3);\nconst UINT_64 Y4  = InitBit(1,  4);\nconst UINT_64 Y5  = InitBit(1,  5);\nconst UINT_64 Y6  = InitBit(1,  6);\nconst UINT_64 Y7  = InitBit(1,  7);\nconst UINT_64 Y8  = InitBit(1,  8);\nconst UINT_64 Y9  = InitBit(1,  9);\nconst UINT_64 Y10 = InitBit(1, 10);\nconst UINT_64 Y11 = InitBit(1, 11);\n\nconst UINT_64 Z0  = InitBit(2,  0);\nconst UINT_64 Z1  = InitBit(2,  1);\nconst UINT_64 Z2  = InitBit(2,  2);\nconst UINT_64 Z3  = InitBit(2,  3);\nconst UINT_64 Z4  = InitBit(2,  4);\nconst UINT_64 Z5  = InitBit(2,  5);\nconst UINT_64 Z6  = InitBit(2,  6);\nconst UINT_64 Z7  = InitBit(2,  7);\nconst UINT_64 Z8  = InitBit(2,  8);\n\nconst UINT_64 S0  = InitBit(3,  0);\nconst UINT_64 S1  = InitBit(3,  1);\nconst UINT_64 S2  = InitBit(3,  2);\n\n/**\n************************************************************************************************************************\n* @brief This class contains asic independent address lib functionalities\n************************************************************************************************************************\n*/\nclass Lib : public Addr::Lib\n{\npublic:\n    virtual ~Lib();\n\n    static Lib* GetLib(\n        ADDR_HANDLE hLib);\n\n    //\n    // Interface stubs\n    //\n\n    // For data surface\n    ADDR_E_RETURNCODE ComputeSurfaceInfo(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoord(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceCoordFromAddr(\n        const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut) const;\n\n    // For HTile\n    ADDR_E_RETURNCODE ComputeHtileInfo(\n        const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeHtileAddrFromCoord(\n        const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeHtileCoordFromAddr(\n        const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut);\n\n    // For CMask\n    ADDR_E_RETURNCODE ComputeCmaskInfo(\n        const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeCmaskAddrFromCoord(\n        const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeCmaskCoordFromAddr(\n        const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT*      pOut) const;\n\n    // For FMask\n    ADDR_E_RETURNCODE ComputeFmaskInfo(\n        const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_FMASK_INFO_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeFmaskAddrFromCoord(\n        const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeFmaskCoordFromAddr(\n        const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT*      pOut) const;\n\n    // For DCC key\n    ADDR_E_RETURNCODE ComputeDccInfo(\n        const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    // Misc\n    ADDR_E_RETURNCODE ComputePipeBankXor(\n        const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeSlicePipeBankXor(\n        const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeNonBlockCompressedView(\n        const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE Addr2GetPreferredSurfaceSetting(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE GetPossibleSwizzleModes(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const;\n\n    virtual BOOL_32 IsValidDisplaySwizzleMode(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    ADDR_E_RETURNCODE GetAllowedBlockSet(\n        ADDR2_SWMODE_SET allowedSwModeSet,\n        AddrResourceType rsrcType,\n        ADDR2_BLOCK_SET* pAllowedBlockSet) const;\n\n    ADDR_E_RETURNCODE GetAllowedSwSet(\n        ADDR2_SWMODE_SET  allowedSwModeSet,\n        ADDR2_SWTYPE_SET* pAllowedSwSet) const;\n\nprotected:\n    Lib();  // Constructor is protected\n    Lib(const Client* pClient);\n\n    static const UINT_32 MaxNumOfBpp = 5;\n    static const UINT_32 MaxNumOfBppCMask = 4;\n    static const UINT_32 MaxNumOfAA  = 4;\n\n    static const Dim2d Block256_2d[MaxNumOfBpp];\n    static const Dim3d Block1K_3d[MaxNumOfBpp];\n\n    static const UINT_32 PrtAlignment = 64 * 1024;\n    static const UINT_32 MaxMacroBits = 20;\n\n    static const UINT_32 MaxMipLevels = 16;\n\n    BOOL_32 IsValidSwMode(AddrSwizzleMode swizzleMode) const\n    {\n        return (m_swizzleModeTable[swizzleMode].u32All != 0);\n    }\n\n    // Checking block size\n    BOOL_32 IsBlock256b(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is256b;\n    }\n\n    BOOL_32 IsBlock4kb(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is4kb;\n    }\n\n    BOOL_32 IsBlock64kb(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is64kb;\n    }\n\n    BOOL_32 IsBlockVariable(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isVar;\n    }\n\n    // Checking swizzle mode\n    BOOL_32 IsLinear(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isLinear;\n    }\n\n    BOOL_32 IsRtOptSwizzle(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isRtOpt;\n    }\n\n    BOOL_32 IsZOrderSwizzle(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isZ;\n    }\n\n    BOOL_32 IsStandardSwizzle(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isStd;\n    }\n\n    BOOL_32 IsDisplaySwizzle(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isDisp;\n    }\n\n    BOOL_32 IsRotateSwizzle(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isRot;\n    }\n\n    BOOL_32 IsStandardSwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const\n    {\n        return HwlIsStandardSwizzle(resourceType, swizzleMode);\n    }\n\n    BOOL_32 IsDisplaySwizzle(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const\n    {\n        return HwlIsDisplaySwizzle(resourceType, swizzleMode);\n    }\n\n    BOOL_32 IsXor(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isXor;\n    }\n\n    BOOL_32 IsPrt(AddrSwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isT;\n    }\n\n    BOOL_32 IsNonPrtXor(AddrSwizzleMode swizzleMode) const\n    {\n        return (IsXor(swizzleMode) && (IsPrt(swizzleMode) == FALSE));\n    }\n\n    // Checking resource type\n    static BOOL_32 IsTex1d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_1D);\n    }\n\n    static BOOL_32 IsTex2d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_2D);\n    }\n\n    static BOOL_32 IsTex3d(AddrResourceType resourceType)\n    {\n        return (resourceType == ADDR_RSRC_TEX_3D);\n    }\n\n    BOOL_32 IsThick(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const\n    {\n        return HwlIsThick(resourceType, swizzleMode);\n    }\n\n    BOOL_32 IsThin(AddrResourceType resourceType, AddrSwizzleMode swizzleMode) const\n    {\n        return HwlIsThin(resourceType, swizzleMode);\n    }\n\n    UINT_32 GetBlockSizeLog2(AddrSwizzleMode swizzleMode) const\n    {\n        UINT_32 blockSizeLog2 = 0;\n\n        if (IsBlock256b(swizzleMode) || IsLinear(swizzleMode))\n        {\n            blockSizeLog2 = 8;\n        }\n        else if (IsBlock4kb(swizzleMode))\n        {\n            blockSizeLog2 = 12;\n        }\n        else if (IsBlock64kb(swizzleMode))\n        {\n            blockSizeLog2 = 16;\n        }\n        else if (IsBlockVariable(swizzleMode) && (m_blockVarSizeLog2 != 0))\n        {\n            blockSizeLog2 = m_blockVarSizeLog2;\n        }\n        else\n        {\n            ADDR_ASSERT_ALWAYS();\n        }\n\n        return blockSizeLog2;\n    }\n\n    UINT_32 GetBlockSize(AddrSwizzleMode swizzleMode) const\n    {\n        return (1 << GetBlockSizeLog2(swizzleMode));\n    }\n\n    static UINT_32 GetFmaskBpp(UINT_32 sample, UINT_32 frag)\n    {\n        sample = (sample == 0) ? 1 : sample;\n        frag   = (frag   == 0) ? sample : frag;\n\n        UINT_32 fmaskBpp = QLog2(frag);\n\n        if (sample > frag)\n        {\n            fmaskBpp++;\n        }\n\n        if (fmaskBpp == 3)\n        {\n            fmaskBpp = 4;\n        }\n\n        fmaskBpp = Max(8u, fmaskBpp * sample);\n\n        return fmaskBpp;\n    }\n\n    virtual BOOL_32 HwlIsStandardSwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return FALSE;\n    }\n\n    virtual BOOL_32 HwlIsDisplaySwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return FALSE;\n    }\n\n    virtual BOOL_32 HwlIsThin(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return FALSE;\n    }\n\n    virtual BOOL_32 HwlIsThick(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return FALSE;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileInfo(\n        const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskInfo(\n        const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,\n        ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeDccInfo(\n        const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,\n        ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlSupportComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual VOID HwlComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut)\n    {\n        ADDR_NOT_IMPLEMENTED();\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(\n        const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*      pOut)\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(\n        const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut)\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileCoordFromAddr(\n        const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut)\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeBlock256Equation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeThinEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeThickEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual UINT_32 HwlGetEquationIndex(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_INVALID_EQUATION_INDEX;\n    }\n\n    UINT_32 GetEquationIndex(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const\n    {\n        return HwlGetEquationIndex(pIn, pOut);\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView(\n        const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlGetAllowedBlockSet(\n        ADDR2_SWMODE_SET allowedSwModeSet,\n        AddrResourceType rsrcType,\n        ADDR2_BLOCK_SET* pAllowedBlockSet) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlGetAllowedSwSet(\n        ADDR2_SWMODE_SET  allowedSwModeSet,\n        ADDR2_SWTYPE_SET* pAllowedSwSet) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoLinear(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    ADDR_E_RETURNCODE ComputeBlock256Equation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    ADDR_E_RETURNCODE ComputeThinEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    ADDR_E_RETURNCODE ComputeThickEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoSanityCheck(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoLinear(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoTiled(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordLinear(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceCoordFromAddrLinear(\n        const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceCoordFromAddrTiled(\n        const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT*      pOut) const;\n\n    UINT_32 ComputeSurface2DMicroBlockOffset(\n        const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const;\n\n    UINT_32 ComputeSurface3DMicroBlockOffset(\n        const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const;\n\n    // Misc\n    ADDR_E_RETURNCODE ComputeBlockDimensionForSurf(\n        UINT_32*         pWidth,\n        UINT_32*         pHeight,\n        UINT_32*         pDepth,\n        UINT_32          bpp,\n        UINT_32          numSamples,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    ADDR_E_RETURNCODE ComputeBlockDimension(\n        UINT_32*         pWidth,\n        UINT_32*         pHeight,\n        UINT_32*         pDepth,\n        UINT_32          bpp,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    virtual VOID ComputeThinBlockDimension(\n        UINT_32*         pWidth,\n        UINT_32*         pHeight,\n        UINT_32*         pDepth,\n        UINT_32          bpp,\n        UINT_32          numSamples,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    VOID ComputeThickBlockDimension(\n        UINT_32*         pWidth,\n        UINT_32*         pHeight,\n        UINT_32*         pDepth,\n        UINT_32          bpp,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    static UINT_64 ComputePadSize(\n        const Dim3d*      pBlkDim,\n        UINT_32           width,\n        UINT_32           height,\n        UINT_32           numSlices,\n        Dim3d*            pPadDim)\n    {\n        pPadDim->w = PowTwoAlign(width ,pBlkDim->w);\n        pPadDim->h = PowTwoAlign(height ,pBlkDim->h);\n        pPadDim->d = PowTwoAlign(numSlices, pBlkDim->d);\n        return static_cast<UINT_64>(pPadDim->w) * pPadDim->h * pPadDim->d;\n    }\n\n    static ADDR_E_RETURNCODE ExtractPipeBankXor(\n        UINT_32  pipeBankXor,\n        UINT_32  bankBits,\n        UINT_32  pipeBits,\n        UINT_32* pBankX,\n        UINT_32* pPipeX);\n\n    static BOOL_32 Valid3DMipSliceIdConstraint(\n        UINT_32 numSlices,\n        UINT_32 mipId,\n        UINT_32 slice)\n    {\n        return (Max((numSlices >> mipId), 1u) > slice);\n    }\n\n    Dim3d GetMipTailDim(\n        AddrResourceType  resourceType,\n        AddrSwizzleMode   swizzleMode,\n        UINT_32           blockWidth,\n        UINT_32           blockHeight,\n        UINT_32           blockDepth) const;\n\n    static BOOL_32 IsLocalHeap(AddrResrouceLocation resourceType)\n    {\n        return ((resourceType == ADDR_RSRC_LOC_LOCAL) ||\n                (resourceType == ADDR_RSRC_LOC_INVIS));\n    }\n\n    static BOOL_32 IsInvisibleHeap(AddrResrouceLocation resourceType)\n    {\n        return (resourceType == ADDR_RSRC_LOC_INVIS);\n    }\n\n    static BOOL_32 IsNonlocalHeap(AddrResrouceLocation resourceType)\n    {\n        return ((resourceType == ADDR_RSRC_LOC_USWC) ||\n                (resourceType == ADDR_RSRC_LOC_CACHED));\n    }\n\n    UINT_32 GetPipeLog2ForMetaAddressing(BOOL_32 pipeAligned, AddrSwizzleMode swizzleMode) const\n    {\n        UINT_32 numPipeLog2 = pipeAligned ? Min(m_pipesLog2 + m_seLog2, 5u) : 0;\n\n        if (IsXor(swizzleMode))\n        {\n            UINT_32 maxPipeLog2 = GetBlockSizeLog2(swizzleMode) - m_pipeInterleaveLog2;\n\n            numPipeLog2 = Min(numPipeLog2, maxPipeLog2);\n        }\n\n        return numPipeLog2;\n    }\n\n    UINT_32 GetPipeNumForMetaAddressing(BOOL_32 pipeAligned, AddrSwizzleMode swizzleMode) const\n    {\n        return (1 << GetPipeLog2ForMetaAddressing(pipeAligned, swizzleMode));\n    }\n\n    VOID VerifyMipLevelInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n    {\n#if DEBUG\n        if (pIn->numMipLevels > 1)\n        {\n            UINT_32 actualMipLevels = 1;\n            switch (pIn->resourceType)\n            {\n                case ADDR_RSRC_TEX_3D:\n                    // Fall through to share 2D case\n                    actualMipLevels = Max(actualMipLevels, Log2NonPow2(pIn->numSlices) + 1);\n                case ADDR_RSRC_TEX_2D:\n                    // Fall through to share 1D case\n                    actualMipLevels = Max(actualMipLevels, Log2NonPow2(pIn->height) + 1);\n                case ADDR_RSRC_TEX_1D:\n                    // Base 1D case\n                    actualMipLevels = Max(actualMipLevels, Log2NonPow2(pIn->width) + 1);\n                    break;\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    break;\n            }\n            // Client pass wrong number of MipLevels to addrlib and result will be bad.\n            // Not sure if we should fail this calling instead of putting an assertion here.\n            ADDR_ASSERT(actualMipLevels >= pIn->numMipLevels);\n        }\n#endif\n    }\n\n    ADDR_E_RETURNCODE ApplyCustomerPipeBankXor(\n        AddrSwizzleMode swizzleMode,\n        UINT_32         pipeBankXor,\n        UINT_32         bankBits,\n        UINT_32         pipeBits,\n        UINT_32*        pBlockOffset) const\n    {\n        ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n        if (IsXor(swizzleMode))\n        {\n            // Apply driver set bankPipeXor\n            UINT_32 bankX = 0;\n            UINT_32 pipeX = 0;\n            returnCode = ExtractPipeBankXor(pipeBankXor, bankBits, pipeBits, &bankX, &pipeX);\n            *pBlockOffset ^= (pipeX << m_pipeInterleaveLog2);\n            *pBlockOffset ^= (bankX << (m_pipeInterleaveLog2 + pipeBits));\n        }\n\n        return returnCode;\n    }\n\n    UINT_32 GetPipeXorBits(UINT_32 macroBlockBits) const;\n\n    ADDR_E_RETURNCODE ApplyCustomizedPitchHeight(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        UINT_32                                 elementBytes,\n        UINT_32                                 pitchAlignInElement,\n        UINT_32*                                pPitch,\n        UINT_32*                                pHeight) const;\n\n    VOID ComputeQbStereoInfo(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;\n\n    VOID FilterInvalidEqSwizzleMode(\n        ADDR2_SWMODE_SET& allowedSwModeSet,\n        AddrResourceType  resourceType,\n        UINT_32           elemLog2,\n        UINT_32           maxComponents) const;\n\n#if DEBUG\n    VOID ValidateStereoInfo(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const;\n#endif\n\n    UINT_32 m_se;                       ///< Number of shader engine\n    UINT_32 m_rbPerSe;                  ///< Number of render backend per shader engine\n    UINT_32 m_maxCompFrag;              ///< Number of max compressed fragment\n\n    UINT_32 m_banksLog2;                ///< Number of bank Log2\n    UINT_32 m_pipesLog2;                ///< Number of pipe per shader engine Log2\n    UINT_32 m_seLog2;                   ///< Number of shader engine Log2\n    UINT_32 m_rbPerSeLog2;              ///< Number of render backend per shader engine Log2\n    UINT_32 m_maxCompFragLog2;          ///< Number of max compressed fragment Log2\n\n    UINT_32 m_pipeInterleaveLog2;       ///< Log2 of pipe interleave bytes\n\n    UINT_32 m_blockVarSizeLog2;         ///< Log2 of block var size\n\n    SwizzleModeFlags m_swizzleModeTable[ADDR_SW_MAX_TYPE];  ///< Swizzle mode table\n\n    // Max number of swizzle mode supported for equation\n    static const UINT_32    MaxSwModeType = 32;\n    // Max number of resource type (2D/3D) supported for equation\n    static const UINT_32    MaxRsrcType = 2;\n    // Max number of bpp (8bpp/16bpp/32bpp/64bpp/128bpp)\n    static const UINT_32    MaxElementBytesLog2  = 5;\n    // Almost all swizzle mode + resource type support equation\n    static const UINT_32    EquationTableSize = MaxElementBytesLog2 * MaxSwModeType * MaxRsrcType;\n    // Equation table\n    ADDR_EQUATION           m_equationTable[EquationTableSize];\n\n    // Number of equation entries in the table\n    UINT_32                 m_numEquations;\n    // Equation lookup table according to bpp and tile index\n    UINT_32                 m_equationLookupTable[MaxRsrcType][MaxSwModeType][MaxElementBytesLog2];\n\nprivate:\n    // Disallow the copy constructor\n    Lib(const Lib& a);\n\n    // Disallow the assignment operator\n    Lib& operator=(const Lib& a);\n};\n\n} // V2\n} // Addr\n} // namespace rocr\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib3.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n************************************************************************************************************************\n* @file  addrlib3.cpp\n* @brief Contains the implementation for the AddrLib3 base class.\n************************************************************************************************************************\n*/\n\n#include \"addrinterface.h\"\n#include \"addrlib3.h\"\n#include \"addrcommon.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V3\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst Dim2d         Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};\n\nconst ADDR_EXTENT3D Lib::Block1K_3d[]  = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Constructor/Destructor\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n/**\n************************************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the Addr::V3::Lib class\n*\n************************************************************************************************************************\n*/\nLib::Lib()\n    :\n    Addr::Lib(),\n    m_pipesLog2(0),\n    m_pipeInterleaveLog2(0),\n    m_numEquations(0)\n{\n    Init();\n}\n\n/**\n************************************************************************************************************************\n*   Lib::Lib\n*\n*   @brief\n*       Constructor for the AddrLib3 class with hClient as parameter\n*\n************************************************************************************************************************\n*/\nLib::Lib(\n    const Client* pClient)\n    :\n    Addr::Lib(pClient),\n    m_pipesLog2(0),\n    m_pipeInterleaveLog2(0),\n    m_numEquations(0)\n{\n    Init();\n}\n\n/**\n************************************************************************************************************************\n*   Lib::Init\n*\n*   @brief\n*       Initialization of class\n*\n************************************************************************************************************************\n*/\nvoid Lib::Init()\n{\n    memset(m_equationTable, 0, sizeof(m_equationTable));\n\n    // There is no equation table entry for linear, so start at the \"next\" swizzle mode entry.\n    for (UINT_32  swizzleModeIdx = ADDR3_LINEAR + 1; swizzleModeIdx < ADDR3_MAX_TYPE; swizzleModeIdx++)\n    {\n        for (UINT_32  msaaRateIdx = 0; msaaRateIdx < MaxMsaaRateLog2; msaaRateIdx++)\n        {\n            for (UINT_32  log2BytesIdx = 0; log2BytesIdx < MaxElementBytesLog2; log2BytesIdx++)\n            {\n                SetEquationTableEntry(static_cast<Addr3SwizzleMode>(swizzleModeIdx),\n                                      msaaRateIdx,\n                                      log2BytesIdx,\n                                      ADDR_INVALID_EQUATION_INDEX);\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Lib::~Lib\n*\n*   @brief\n*       Destructor for the AddrLib2 class\n*\n************************************************************************************************************************\n*/\nLib::~Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetLib\n*\n*   @brief\n*       Get Addr::V3::Lib pointer\n*\n*   @return\n*      An Addr::V2::Lib class pointer\n************************************************************************************************************************\n*/\nLib* Lib::GetLib(\n    ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE\n{\n    Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);\n\n    return static_cast<Lib*>(hLib);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetBlockSize\n*\n*   @brief\n*       Returns the byte size of a block for the swizzle mode.\n*\n*   @return\n*       Byte size of the block, zero if swizzle mode is invalid.\n************************************************************************************************************************\n*/\nUINT_32  Lib::GetBlockSize(\n    Addr3SwizzleMode  swizzleMode,\n    BOOL_32           forPitch\n    ) const\n{\n    return  (1 << GetBlockSizeLog2(swizzleMode, forPitch));\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetBlockSizeLog2\n*\n*   @brief\n*       Returns the log2 of the byte size of a block for the swizzle mode.\n*\n*   @return\n*       Byte size of the block, zero if swizzle mode is invalid.\n************************************************************************************************************************\n*/\nUINT_32  Lib::GetBlockSizeLog2(\n    Addr3SwizzleMode  swizzleMode,\n    BOOL_32           forPitch\n    ) const\n{\n    UINT_32  blockSize = 0;\n\n    switch (swizzleMode)\n    {\n        case ADDR3_256B_2D:\n            blockSize = 8;\n            break;\n        case ADDR3_4KB_2D:\n        case ADDR3_4KB_3D:\n            blockSize = 12;\n            break;\n        case ADDR3_64KB_2D:\n        case ADDR3_64KB_3D:\n            blockSize = 16;\n            break;\n        case ADDR3_256KB_2D:\n        case ADDR3_256KB_3D:\n            blockSize = 18;\n            break;\n        case ADDR3_LINEAR:\n            blockSize = (forPitch ? 7 : 8);\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            break;\n    }\n\n    return  blockSize;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceInfo\n*\n*   @brief\n*       Interface function stub of ComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(\n     const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR3_COMPUTE_SURFACE_INFO_INPUT)) ||\n            (pOut->size != sizeof(ADDR3_COMPUTE_SURFACE_INFO_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    // Adjust incoming parameters.\n    ADDR3_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;\n    localIn.width        = Max(pIn->width, 1u);\n    localIn.height       = Max(pIn->height, 1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n    localIn.numSlices    = Max(pIn->numSlices, 1u);\n    localIn.numSamples   = Max(pIn->numSamples, 1u);\n\n    UINT_32  expandX  = 1;\n    UINT_32  expandY  = 1;\n    ElemMode elemMode = ADDR_UNCOMPRESSED;\n\n    if (returnCode == ADDR_OK)\n    {\n        // Set format to INVALID will skip this conversion\n        if (localIn.format != ADDR_FMT_INVALID)\n        {\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,\n                                                        &elemMode,\n                                                        &expandX,\n                                                        &expandY);\n\n            // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is\n            // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-\n            // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw\n            // restrictions are different.\n            // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround\n            // but we use this flag to skip RestoreSurfaceInfo below\n            if ((elemMode == ADDR_EXPANDED) && (expandX > 1))\n            {\n                ADDR_ASSERT(IsLinear(localIn.swizzleMode));\n            }\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &localIn.bpp,\n                                            &basePitch,\n                                            &localIn.width,\n                                            &localIn.height);\n\n            // Overwrite these parameters if we have a valid format\n        }\n\n        if (localIn.bpp != 0)\n        {\n            localIn.width  = Max(localIn.width, 1u);\n            localIn.height = Max(localIn.height, 1u);\n        }\n        else // Rule out some invalid parameters\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        returnCode = HwlComputeSurfaceInfo(&localIn, pOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->bpp         = localIn.bpp;\n            pOut->pixelPitch  = pOut->pitch;\n            pOut->pixelHeight = pOut->height;\n\n            if (localIn.format != ADDR_FMT_INVALID)\n            {\n                UINT_32 pixelBits = pOut->pixelBits;\n\n                GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                 expandX,\n                                                 expandY,\n                                                 &pOut->pixelBits,\n                                                 &pOut->pixelPitch,\n                                                 &pOut->pixelHeight);\n\n                GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                 expandX,\n                                                 expandY,\n                                                 &pixelBits,\n                                                 &pOut->pixelMipChainPitch,\n                                                 &pOut->pixelMipChainHeight);\n\n                if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))\n                {\n                    for (UINT_32 i = 0; i < localIn.numMipLevels; i++)\n                    {\n                        pOut->pMipInfo[i].pixelPitch  = pOut->pMipInfo[i].pitch;\n                        pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;\n\n                        GetElemLib()->RestoreSurfaceInfo(elemMode,\n                                                         expandX,\n                                                         expandY,\n                                                         &pixelBits,\n                                                         &pOut->pMipInfo[i].pixelPitch,\n                                                         &pOut->pMipInfo[i].pixelHeight);\n                    }\n                }\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetPossibleSwizzleModes\n*\n*   @brief\n*       Interface function stub of AddrComputeSurfaceInfo.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes(\n     const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn,    ///< [in] input structure\n     ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size  != sizeof(ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT)) ||\n            (pOut->size != sizeof(ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        const ADDR3_SURFACE_FLAGS flags = pIn->flags;\n\n        // VRS images can only be 2D from the client API rules.\n        ADDR_ASSERT((flags.isVrsImage == 0) || IsTex2d(pIn->resourceType));\n\n        if (pIn->bpp == 96)\n        {\n            pOut->validModes.swLinear = 1;\n        }\n        // Depth/Stencil images can't be linear and must be 2D swizzle modes.\n        // These three are related to DB block that supports only SW_64KB_2D and SW_256KB_2D for DSV.\n        else if (flags.depth || flags.stencil)\n        {\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        // The organization of elements in the hierarchical surface is the same as any other surface, and it can support\n        // any 2D swizzle mode (SW_256_2D, SW_4KB_2D, SW_64KB_2D, or SW_256KB_2D).  The swizzle mode can be selected\n        // orthogonally to the underlying z or stencil surface.\n        else if (pIn->flags.hiZHiS)\n        {\n            pOut->validModes.sw2d256B  = 1;\n            pOut->validModes.sw2d4kB   = 1;\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        // MSAA can't be linear and must be 2D swizzle modes.\n        else if (pIn->numSamples > 1)\n        {\n            // NOTE: SW_256B_2D still supports MSAA. The removal of 256B for MSAA is reverted in HW Doc.\n            pOut->validModes.sw2d256B  = 1;\n            pOut->validModes.sw2d4kB   = 1;\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        // Block-compressed images need to be either using 2D or linear swizzle modes.\n        else if (flags.blockCompressed)\n        {\n            pOut->validModes.swLinear = 1;\n\n            // We find cases where Tex3d BlockCompressed image adopts 2D_256B should be prohibited.\n            if (IsTex3d(pIn->resourceType) == FALSE)\n            {\n                pOut->validModes.sw2d256B = 1;\n            }\n            pOut->validModes.sw2d4kB   = 1;\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        else if (IsTex1d(pIn->resourceType))\n        {\n            pOut->validModes.swLinear  = 1;\n            pOut->validModes.sw2d256B  = 1;\n            pOut->validModes.sw2d4kB   = 1;\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        else if (flags.nv12 || flags.p010 || IsTex2d(pIn->resourceType) || flags.view3dAs2dArray)\n        {\n            //      NV12 and P010 support\n            //      SW_LINEAR, SW_256B_2D, SW_4KB_2D, SW_64KB_2D, SW_256KB_2D\n            // There could be more multimedia formats that require more hw specific tiling modes...\n\n            // The exception is VRS images.\n            // Linear is not allowed and the VRS surface needs to be 8BPP format.\n            if (flags.isVrsImage)\n            {\n                ADDR_ASSERT(pIn->bpp == 8);\n            }\n            else\n            {\n                pOut->validModes.swLinear = 1;\n            }\n            if (flags.view3dAs2dArray == 0)\n            {\n                // ADDR3_256B_2D can't support 3D images.\n                pOut->validModes.sw2d256B = 1;\n            }\n            pOut->validModes.sw2d4kB   = 1;\n            pOut->validModes.sw2d64kB  = 1;\n            pOut->validModes.sw2d256kB = 1;\n        }\n        else if (IsTex3d(pIn->resourceType))\n        {\n            // An eventual determination would be based on pal setting of height_watermark and depth_watermark.\n            // However, we just adopt the simpler logic currently.\n            // For 3D images w/ view3dAs2dArray = 0, SW_3D is preferred.\n            // For 3D images w/ view3dAs2dArray = 1, it should go to 2D path above.\n            // Enable linear since client may force linear tiling for 3D texture that does not set view3dAs2dArray.\n            pOut->validModes.swLinear  = 1;\n            pOut->validModes.sw3d4kB   = 1;\n            pOut->validModes.sw3d64kB  = 1;\n            pOut->validModes.sw3d256kB = 1;\n        }\n    }\n\n    constexpr UINT_32 Size256  = 256u;\n    constexpr UINT_32 Size4K   = 4 * 1024;\n    constexpr UINT_32 Size64K  = 64 * 1024;\n    constexpr UINT_32 Size256K = 256 * 1024;\n\n    ADDR_ASSERT(pIn->maxAlign != 0);\n\n    if (pIn->maxAlign < Size256K)\n    {\n        pOut->validModes.value &= ~Gfx12Blk256KBSwModeMask;\n    }\n\n    if (pIn->maxAlign < Size64K)\n    {\n        pOut->validModes.value &= ~Gfx12Blk64KBSwModeMask;\n    }\n\n    if (pIn->maxAlign < Size4K)\n    {\n        pOut->validModes.value &= ~Gfx12Blk4KBSwModeMask;\n    }\n\n    if (pIn->maxAlign < Size256)\n    {\n        pOut->validModes.value &= ~Gfx12Blk256BSwModeMask;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::HwlConvertChipFamily\n*\n*   @brief\n*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision\n*   @return\n*       ChipFamily\n************************************************************************************************************************\n*/\nChipFamily Lib::HwlConvertChipFamily(\n    UINT_32 chipFamily,        ///< [in] chip family defined in atiih.h\n    UINT_32 chipRevision)      ///< [in] chip revision defined in \"asic_family\"_id.h\n{\n    return ADDR_CHIP_FAMILY_NAVI;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeBlockDimensionForSurf\n*\n*   @brief\n*       Internal function to get block width/height/depth in element from surface input params.\n*\n*   @return\n*       VOID\n************************************************************************************************************************\n*/\nVOID Lib::ComputeBlockDimensionForSurf(\n    ADDR_EXTENT3D*    pExtent,\n    UINT_32           bpp,\n    UINT_32           numSamples,\n    Addr3SwizzleMode  swizzleMode\n    ) const\n{\n    const UINT_32 eleBytes     = bpp >> 3;\n    const UINT_32 log2EleBytes = Log2(eleBytes);\n    const UINT_32 log2BlkSize  = GetBlockSizeLog2(swizzleMode);\n\n    if (IsLinear(swizzleMode))\n    {\n        pExtent->width  = 1 << (log2BlkSize - log2EleBytes);\n        pExtent->height = 1;\n        pExtent->depth  = 1;\n    }\n    else if (Is3dSwizzle(swizzleMode))\n    {\n        const UINT_32 base             = (log2BlkSize / 3) - (log2EleBytes / 3);\n        const UINT_32 log2BlkSizeMod3  = log2BlkSize % 3;\n        const UINT_32 log2EleBytesMod3 = log2EleBytes % 3;\n\n        UINT_32  x = base;\n        UINT_32  y = base;\n        UINT_32  z = base;\n\n        if (log2BlkSizeMod3 > 0)\n        {\n            x++;\n        }\n\n        if (log2BlkSizeMod3 > 1)\n        {\n            z++;\n        }\n\n        if (log2EleBytesMod3 > 0)\n        {\n            x--;\n        }\n\n        if (log2EleBytesMod3 > 1)\n        {\n            z--;\n        }\n\n        pExtent->width  = 1u << x;\n        pExtent->height = 1u << y;\n        pExtent->depth  = 1u << z;\n    }\n    else\n    {\n        const UINT_32 log2Samples = Log2(Max(numSamples, 1u));\n        const UINT_32 log2Width   = (log2BlkSize  >> 1)  -\n                                    (log2EleBytes >> 1)  -\n                                    (log2Samples  >> 1)  -\n                                    (log2EleBytes & log2Samples & 1);\n        const UINT_32 log2Height  = (log2BlkSize  >> 1)  -\n                                    (log2EleBytes >> 1)  -\n                                    (log2Samples  >> 1)  -\n                                    ((log2EleBytes | log2Samples) & 1);\n\n        // Return the extent in actual units, not log2\n        pExtent->width  = 1u << log2Width;\n        pExtent->height = 1u << log2Height;\n        pExtent->depth  = 1;\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Lib::GetMipTailDim\n*\n*   @brief\n*       Internal function to get out max dimension of first level in mip tail\n*\n*   @return\n*       Max Width/Height/Depth value of the first mip fitted in mip tail\n************************************************************************************************************************\n*/\nADDR_EXTENT3D Lib::GetMipTailDim(\n    Addr3SwizzleMode      swizzleMode,\n    const ADDR_EXTENT3D&  blockDims\n    ) const\n{\n    const UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);\n\n    ADDR_EXTENT3D  out = blockDims;\n\n    if (Is3dSwizzle(swizzleMode))\n    {\n        const UINT_32 dim = log2BlkSize % 3;\n\n        if (dim == 0)\n        {\n            out.height >>= 1;\n        }\n        else if (dim == 1)\n        {\n            out.width >>= 1;\n        }\n        else\n        {\n            out.depth >>= 1;\n        }\n    }\n    else\n    {\n        if ((log2BlkSize % 2) == 0)\n        {\n            out.width >>= 1;\n        }\n        else\n        {\n            out.height >>= 1;\n        }\n    }\n\n    return out;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Interface function stub of ComputeSurfaceAddrFromCoord.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(\n    const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (GetFillSizeFieldsFlags() == TRUE)\n    {\n        if ((pIn->size != sizeof(ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||\n            (pOut->size != sizeof(ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))\n        {\n            returnCode = ADDR_PARAMSIZEMISMATCH;\n        }\n    }\n\n    ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;\n    localIn.unAlignedDims.width  = Max(pIn->unAlignedDims.width,  1u);\n    localIn.unAlignedDims.height = Max(pIn->unAlignedDims.height, 1u);\n    localIn.unAlignedDims.depth  = Max(pIn->unAlignedDims.depth,  1u);\n    localIn.numMipLevels         = Max(pIn->numMipLevels,         1u);\n    localIn.numSamples           = Max(pIn->numSamples,           1u);\n\n    if ((localIn.bpp < 8)                               ||\n        (localIn.bpp > 128)                             ||\n        ((localIn.bpp % 8) != 0)                        ||\n        (localIn.sample >= localIn.numSamples)          ||\n        (localIn.slice >= localIn.unAlignedDims.depth)  ||\n        (localIn.mipId >= localIn.numMipLevels)         ||\n        (IsTex3d(localIn.resourceType)                  &&\n        (Valid3DMipSliceIdConstraint(localIn.unAlignedDims.depth, localIn.mipId, localIn.slice) == FALSE)))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        if (IsLinear(localIn.swizzleMode))\n        {\n            returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);\n        }\n        else\n        {\n            returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoord\n*\n*   @brief\n*       Interface function stub of Addr3ComputePipeBankXor.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputePipeBankXor(\n    const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n    ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size  != sizeof(ADDR3_COMPUTE_PIPEBANKXOR_INPUT)) ||\n         (pOut->size != sizeof(ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputePipeBankXor(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoordLinear\n*\n*   @brief\n*       Internal function to calculate address from coord for linear swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(\n     const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n    BOOL_32 valid = (pIn->numSamples <= 1);\n\n    if (valid)\n    {\n        if (IsTex1d(pIn->resourceType))\n        {\n            valid = (pIn->y == 0);\n        }\n    }\n\n    if (valid)\n    {\n        ADDR3_COMPUTE_SURFACE_INFO_INPUT  localIn  = {0};\n        ADDR3_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n        ADDR3_MIP_INFO                    mipInfo[MaxMipLevels];\n        ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n\n        localIn.size         = sizeof(localIn);\n        localIn.flags        = pIn->flags;\n        localIn.swizzleMode  = ADDR3_LINEAR;\n        localIn.resourceType = pIn->resourceType;\n        localIn.format       = ADDR_FMT_INVALID;\n        localIn.bpp          = pIn->bpp;\n        localIn.width        = Max(pIn->unAlignedDims.width,  1u);\n        localIn.height       = Max(pIn->unAlignedDims.height, 1u);\n        localIn.numSlices    = Max(pIn->unAlignedDims.depth,  1u);\n        localIn.numMipLevels = Max(pIn->numMipLevels,         1u);\n        localIn.numSamples   = Max(pIn->numSamples,           1u);\n\n        if (localIn.numMipLevels <= 1)\n        {\n            localIn.pitchInElement = pIn->pitchInElement;\n        }\n\n        localOut.size     = sizeof(localOut);\n        localOut.pMipInfo = mipInfo;\n\n        returnCode = ComputeSurfaceInfo(&localIn, &localOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->addr        = (localOut.sliceSize * pIn->slice) +\n                                mipInfo[pIn->mipId].offset +\n                                (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);\n            pOut->bitPosition = 0;\n        }\n        else\n        {\n            valid = FALSE;\n        }\n    }\n\n    if (valid == FALSE)\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(\n     const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeNonBlockCompressedView\n*\n*   @brief\n*       Interface function stub of Addr3ComputeNonBlockCompressedView.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeNonBlockCompressedView(\n    const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n    ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size  != sizeof(ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT)) ||\n         (pOut->size != sizeof(ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else if (Is3dSwizzle(pIn->swizzleMode))\n    {\n        // 3D volume images using ADDR3_XX_3D is currently not supported.\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else\n    {\n        returnCode = HwlComputeNonBlockCompressedView(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Interface function stub of Addr3ComputeSubResourceOffsetForSwizzlePattern.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n    ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size  != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||\n         (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ComputeSlicePipeBankXor\n*\n*   @brief\n*       Interface function stub of Addr3ComputeSlicePipeBankXor.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(\n    const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n    ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut)\n{\n    ADDR_E_RETURNCODE returnCode;\n\n    if ((GetFillSizeFieldsFlags() == TRUE) &&\n        ((pIn->size  != sizeof(ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||\n         (pOut->size != sizeof(ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    if ((pIn->bpe != 0) &&\n        (pIn->bpe != 8) &&\n        (pIn->bpe != 16) &&\n        (pIn->bpe != 32) &&\n        (pIn->bpe != 64) &&\n        (pIn->bpe != 128))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Lib::UseCustomHeight\n*\n*   @brief\n*       Determines if the calculations for this surface should use minimal HW values or user-specified values.\n*\n*   @return\n*       Returns TRUE if the user-specified alignment should be used\n************************************************************************************************************************\n*/\nBOOL_32 Lib::UseCustomHeight(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn\n    ) const\n{\n    return ((pIn->numMipLevels <= 1)   &&\n            IsLinear(pIn->swizzleMode) &&\n            (pIn->sliceAlign > 0));\n}\n\n/**\n************************************************************************************************************************\n*   Lib::UseCustomPitch\n*\n*   @brief\n*       Determines if the calculations for this surface should use minimal HW values or user-specified values.\n*\n*   @return\n*       Returns TRUE if the user-specified pitch should be used\n************************************************************************************************************************\n*/\nBOOL_32 Lib::UseCustomPitch(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn\n    ) const\n{\n    return ((pIn->numMipLevels <= 1)   &&\n            IsLinear(pIn->swizzleMode) &&\n            (pIn->pitchInElement > 0));\n}\n\n/**\n************************************************************************************************************************\n*   Lib::CanTrimLinearPadding\n*\n*   @brief\n*       Determines if the calculations for this surface can omit extra trailing padding for linear surfaces.\n*\n*   @return\n*       Returns TRUE if the trailing padding can be omitted.\n************************************************************************************************************************\n*/\nBOOL_32 Lib::CanTrimLinearPadding(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn\n    ) const\n{\n    return ((IsTex3d(pIn->resourceType) == FALSE) &&\n            (pIn->numSlices <= 1)                 &&\n            IsLinear(pIn->swizzleMode));\n}\n\n/**\n************************************************************************************************************************\n*   Lib::ApplyCustomizedPitchHeight\n*\n*   @brief\n*       Helper function to override hw required row pitch/slice pitch by customrized one\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    const UINT_32  elementBytes = pIn->bpp >> 3;\n\n    // Calculate the default pitch/height without any user inputs\n    pOut->pitch  = PowTwoAlign(pIn->width,  pOut->blockExtent.width);\n    pOut->height = PowTwoAlign(pIn->height, pOut->blockExtent.height);\n\n    // Custom pitches / alignments are only possible with single mip level / linear images; otherwise,\n    // ignore those parameters.\n    if (UseCustomPitch(pIn))\n    {\n        const UINT_32  pitchAlignmentBytes    = 1 << GetBlockSizeLog2(pIn->swizzleMode, TRUE);\n        const UINT_32  pitchAlignmentElements = pitchAlignmentBytes / elementBytes;\n\n        // Their requested pitch has to meet the pitch alignment constraints applied by the HW.\n        if ((pIn->pitchInElement % pitchAlignmentElements) != 0)\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        // And their pitch can't be less than the minimum\n        else if (pIn->pitchInElement < pOut->pitch)\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            pOut->pitch = pIn->pitchInElement;\n        }\n    }\n\n    if ((returnCode == ADDR_OK) && UseCustomHeight(pIn))\n    {\n        UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / pOut->pitch;\n\n        if (customizedHeight * elementBytes * pOut->pitch != pIn->sliceAlign)\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else if ((pIn->numSlices > 1) && (pOut->height != customizedHeight))\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            pOut->height = customizedHeight;\n        }\n    }\n\n    return returnCode;\n}\n\n} // V3\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrlib3.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2023 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n************************************************************************************************************************\n* @file  addrlib3.h\n* @brief Contains the Addr::V3::Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __ADDR3_LIB3_H__\n#define __ADDR3_LIB3_H__\n\n#include \"addrlib.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V3\n{\n\n/**\n************************************************************************************************************************\n* @brief Bitmasks for swizzle mode determination on GFX12\n************************************************************************************************************************\n*/\nconst UINT_32 Gfx12Blk256KBSwModeMask = (1u << ADDR3_256KB_2D)  |\n                                        (1u << ADDR3_256KB_3D);\n\nconst UINT_32 Gfx12Blk64KBSwModeMask  = (1u << ADDR3_64KB_2D)   |\n                                        (1u << ADDR3_64KB_3D);\n\nconst UINT_32 Gfx12Blk4KBSwModeMask   = (1u << ADDR3_4KB_2D)    |\n                                        (1u << ADDR3_4KB_3D);\n\nconst UINT_32 Gfx12Blk256BSwModeMask  = (1u << ADDR3_256B_2D);\n\n/**\n************************************************************************************************************************\n* @brief Bit setting for swizzle pattern\n************************************************************************************************************************\n*/\nunion ADDR_BIT_SETTING\n{\n    struct\n    {\n        UINT_16 x;\n        UINT_16 y;\n        UINT_16 z;\n        UINT_16 s;\n    };\n    UINT_64 value;\n};\n\n/**\n************************************************************************************************************************\n* @brief Flags for SwizzleModeTable\n************************************************************************************************************************\n*/\nunion SwizzleModeFlags\n{\n    struct\n    {\n        // Swizzle mode\n        UINT_32 isLinear        : 1;    // Linear\n        UINT_32 is2d            : 1;    // 2d mode\n        UINT_32 is3d            : 1;    // 3d mode\n\n        // Block size\n        UINT_32 is256b          : 1;    // Block size is 256B\n        UINT_32 is4kb           : 1;    // Block size is 4KB\n        UINT_32 is64kb          : 1;    // Block size is 64KB\n        UINT_32 is256kb         : 1;    // Block size is 256KB\n\n        UINT_32 reserved        : 25;   // Reserved bits\n    };\n\n    UINT_32 u32All;\n};\n\nstruct Dim2d\n{\n    UINT_32 w;\n    UINT_32 h;\n};\n\nconst UINT_32 Log2Size256  = 8u;\nconst UINT_32 Log2Size4K   = 12u;\nconst UINT_32 Log2Size64K  = 16u;\nconst UINT_32 Log2Size256K = 18u;\n\n/**\n************************************************************************************************************************\n* @brief Swizzle pattern information\n************************************************************************************************************************\n*/\n// Accessed by index representing the logbase2 of (8bpp/16bpp/32bpp/64bpp/128bpp)\n// contains the indices which map to 2D arrays SW_PATTERN_NIBBLE[1-4] which contain sections of an index equation.\nstruct ADDR_SW_PATINFO\n{\n    UINT_8 nibble1Idx;\n    UINT_8 nibble2Idx;\n    UINT_8 nibble3Idx;\n    UINT_8 nibble4Idx;\n};\n\n/**\n************************************************************************************************************************\n*   InitBit\n*\n*   @brief\n*       Initialize bit setting value via a return value\n************************************************************************************************************************\n*/\n#define InitBit(c, index) (1ull << ((c << 4) + index))\n\nconst UINT_64 X0  = InitBit(0,  0);\nconst UINT_64 X1  = InitBit(0,  1);\nconst UINT_64 X2  = InitBit(0,  2);\nconst UINT_64 X3  = InitBit(0,  3);\nconst UINT_64 X4  = InitBit(0,  4);\nconst UINT_64 X5  = InitBit(0,  5);\nconst UINT_64 X6  = InitBit(0,  6);\nconst UINT_64 X7  = InitBit(0,  7);\nconst UINT_64 X8  = InitBit(0,  8);\n\nconst UINT_64 Y0  = InitBit(1,  0);\nconst UINT_64 Y1  = InitBit(1,  1);\nconst UINT_64 Y2  = InitBit(1,  2);\nconst UINT_64 Y3  = InitBit(1,  3);\nconst UINT_64 Y4  = InitBit(1,  4);\nconst UINT_64 Y5  = InitBit(1,  5);\nconst UINT_64 Y6  = InitBit(1,  6);\nconst UINT_64 Y7  = InitBit(1,  7);\nconst UINT_64 Y8  = InitBit(1,  8);\n\nconst UINT_64 Z0  = InitBit(2,  0);\nconst UINT_64 Z1  = InitBit(2,  1);\nconst UINT_64 Z2  = InitBit(2,  2);\nconst UINT_64 Z3  = InitBit(2,  3);\nconst UINT_64 Z4  = InitBit(2,  4);\nconst UINT_64 Z5  = InitBit(2,  5);\n\nconst UINT_64 S0  = InitBit(3,  0);\nconst UINT_64 S1  = InitBit(3,  1);\nconst UINT_64 S2  = InitBit(3,  2);\n\n/**\n************************************************************************************************************************\n* @brief Bit setting for swizzle pattern\n************************************************************************************************************************\n*/\n\n/**\n************************************************************************************************************************\n* @brief This class contains asic independent address lib functionalities\n************************************************************************************************************************\n*/\nclass Lib : public Addr::Lib\n{\npublic:\n    virtual ~Lib();\n\n    static Lib* GetLib(\n        ADDR_HANDLE hLib);\n\n    //\n    // Interface stubs\n    //\n\n    // For data surface\n    ADDR_E_RETURNCODE ComputeSurfaceInfo(\n        const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE GetPossibleSwizzleModes(\n        const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT*   pIn,\n        ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT*        pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoord(\n        const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    // Misc\n    ADDR_E_RETURNCODE ComputePipeBankXor(\n        const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeNonBlockCompressedView(\n        const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut);\n\n    ADDR_E_RETURNCODE ComputeSlicePipeBankXor(\n        const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut);\n\nprotected:\n    Lib();  // Constructor is protected\n    Lib(const Client* pClient);\n\n    static const UINT_32 MaxImageDim  = 65536;\n    static const UINT_32 MaxMipLevels = 17; // Max image size is 64k\n    static const UINT_32 MaxNumOfBpp  = 5;\n    static const UINT_32 MaxNumOfAA   = 4;\n    UINT_32 m_pipesLog2;                ///< Number of pipe per shader engine Log2\n    UINT_32 m_pipeInterleaveLog2;       ///< Log2 of pipe interleave bytes\n\n    static const Dim2d         Block256_2d[MaxNumOfBpp];\n    static const ADDR_EXTENT3D Block1K_3d[MaxNumOfBpp];\n    SwizzleModeFlags m_swizzleModeTable[ADDR3_MAX_TYPE];  ///< Swizzle mode table\n\n    // Number of unique MSAA sample rates (1/2/4/8)\n    static const UINT_32 MaxMsaaRateLog2     = 4;\n    // Max number of bpp (8bpp/16bpp/32bpp/64bpp/128bpp)\n    static const UINT_32 MaxElementBytesLog2 = 5;\n    // Number of unique swizzle patterns (one entry per swizzle mode + MSAA + bpp configuration)\n    static const UINT_32 NumSwizzlePatterns  = 19 * MaxElementBytesLog2;\n\n    // Number of equation entries in the table\n    UINT_32              m_numEquations;\n    // Equation lookup table according to swizzle mode, MSAA sample rate, and bpp\n    UINT_32              m_equationLookupTable[ADDR3_MAX_TYPE - 1][MaxMsaaRateLog2][MaxElementBytesLog2];\n\n    // Equation table\n    ADDR_EQUATION        m_equationTable[NumSwizzlePatterns];\n\n    void SetEquationTableEntry(\n        Addr3SwizzleMode addrType,\n        UINT_32          msaaLog2,\n        UINT_32          elementLog2,\n        UINT_32          value)\n    {\n        m_equationLookupTable[addrType - 1][msaaLog2][elementLog2] = value;\n    }\n\n    const UINT_32 GetEquationTableEntry(\n        Addr3SwizzleMode addrType,\n        UINT_32          msaaLog2,\n        UINT_32          elementLog2) const\n    {\n        return m_equationLookupTable[addrType - 1][msaaLog2][elementLog2];\n    }\n\n    static BOOL_32 Valid3DMipSliceIdConstraint(\n        UINT_32 numSlices,\n        UINT_32 mipId,\n        UINT_32 slice)\n    {\n        return (Max((numSlices >> mipId), 1u) > slice);\n    }\n\n    UINT_32 GetBlockSize(\n        Addr3SwizzleMode  swizzleMode,\n        BOOL_32           forPitch = FALSE) const;\n\n    UINT_32 GetBlockSizeLog2(\n        Addr3SwizzleMode  swizzleMode,\n        BOOL_32           forPitch = FALSE) const;\n\n    BOOL_32 IsValidSwMode(Addr3SwizzleMode swizzleMode) const\n    {\n        return (m_swizzleModeTable[swizzleMode].u32All != 0);\n    }\n\n    UINT_32 IsLinear(Addr3SwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isLinear;\n    }\n\n    // Checking block size\n    BOOL_32 IsBlock256b(Addr3SwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is256b;\n    }\n\n    // Checking block size\n    BOOL_32 IsBlock4kb(Addr3SwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is4kb;\n    }\n\n    // Checking block size\n    BOOL_32 IsBlock64kb(Addr3SwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is64kb;\n    }\n\n    // Checking block size\n    BOOL_32 IsBlock256kb(Addr3SwizzleMode swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is256kb;\n    }\n\n    BOOL_32  Is2dSwizzle(Addr3SwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is2d;\n    }\n\n    BOOL_32  Is3dSwizzle(Addr3SwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].is3d;\n    }\n\n    virtual UINT_32 HwlComputeMaxBaseAlignments() const  { return 256 * 1024; }\n\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn)\n    {\n        ADDR_NOT_IMPLEMENTED();\n        // Although GFX12 addressing should be consistent regardless of the configuration, we still need to\n        // call some initialization for member variables.\n        return TRUE;\n    }\n\n    virtual ChipFamily HwlConvertChipFamily(\n        UINT_32 chipFamily,\n        UINT_32 chipRevision);\n\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const { return 0; }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(\n         const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    VOID ComputeBlockDimensionForSurf(\n        ADDR_EXTENT3D*    pExtent,\n        UINT_32           bpp,\n        UINT_32           numSamples,\n        Addr3SwizzleMode  swizzleMode) const;\n\n    ADDR_EXTENT3D GetMipTailDim(\n        Addr3SwizzleMode      swizzleMode,\n        const ADDR_EXTENT3D&  blockDims) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordLinear(\n        const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordTiled(\n        const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTIMPLEMENTED;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView(\n        const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    virtual VOID HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const\n    {\n        ADDR_NOT_IMPLEMENTED();\n        return ADDR_NOTSUPPORTED;\n    }\n\n    ADDR_E_RETURNCODE ApplyCustomizedPitchHeight(\n        const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    BOOL_32 UseCustomHeight(const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn) const;\n    BOOL_32 UseCustomPitch(const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn) const;\n    BOOL_32 CanTrimLinearPadding(const ADDR3_COMPUTE_SURFACE_INFO_INPUT*  pIn) const;\n\nprivate:\n    // Disallow the copy constructor\n    Lib(const Lib& a);\n\n    // Disallow the assignment operator\n    Lib& operator=(const Lib& a);\n\n    void Init();\n};\n\n} // V3\n} // Addr\n} // namespace rocr\n\n#endif"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrobject.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n****************************************************************************************************\n* @file  addrobject.cpp\n* @brief Contains the Object base class implementation.\n****************************************************************************************************\n*/\n\n#include \"addrinterface.h\"\n#include \"addrobject.h\"\n\nnamespace rocr {\nnamespace Addr\n{\n\n/**\n****************************************************************************************************\n*   Object::Object\n*\n*   @brief\n*       Constructor for the Object class.\n****************************************************************************************************\n*/\nObject::Object()\n{\n    m_client.handle = NULL;\n    m_client.callbacks.allocSysMem = NULL;\n    m_client.callbacks.freeSysMem = NULL;\n    m_client.callbacks.debugPrint = NULL;\n}\n\n/**\n****************************************************************************************************\n*   Object::Object\n*\n*   @brief\n*       Constructor for the Object class.\n****************************************************************************************************\n*/\nObject::Object(const Client* pClient)\n{\n    m_client = *pClient;\n}\n\n/**\n****************************************************************************************************\n*   Object::~Object\n*\n*   @brief\n*       Destructor for the Object class.\n****************************************************************************************************\n*/\nObject::~Object()\n{\n}\n\n/**\n****************************************************************************************************\n*   Object::ClientAlloc\n*\n*   @brief\n*       Calls instanced allocSysMem inside Client\n****************************************************************************************************\n*/\nVOID* Object::ClientAlloc(\n    size_t         objSize,    ///< [in] Size to allocate\n    const Client*  pClient)    ///< [in] Client pointer\n{\n    VOID* pObjMem = NULL;\n\n    if (pClient->callbacks.allocSysMem != NULL)\n    {\n        ADDR_ALLOCSYSMEM_INPUT allocInput = {0};\n\n        allocInput.size        = sizeof(ADDR_ALLOCSYSMEM_INPUT);\n        allocInput.flags.value = 0;\n        allocInput.sizeInBytes = static_cast<UINT_32>(objSize);\n        allocInput.hClient     = pClient->handle;\n\n        pObjMem = pClient->callbacks.allocSysMem(&allocInput);\n    }\n\n    return pObjMem;\n}\n\n/**\n****************************************************************************************************\n*   Object::Alloc\n*\n*   @brief\n*       A wrapper of ClientAlloc\n****************************************************************************************************\n*/\nVOID* Object::Alloc(\n    size_t objSize      ///< [in] Size to allocate\n    ) const\n{\n    return ClientAlloc(objSize, &m_client);;\n}\n\n/**\n****************************************************************************************************\n*   Object::ClientFree\n*\n*   @brief\n*       Calls freeSysMem inside Client\n****************************************************************************************************\n*/\nVOID Object::ClientFree(\n    VOID*          pObjMem,    ///< [in] User virtual address to free.\n    const Client*  pClient)    ///< [in] Client pointer\n{\n    if (pClient->callbacks.freeSysMem != NULL)\n    {\n        if (pObjMem != NULL)\n        {\n            ADDR_FREESYSMEM_INPUT freeInput = {0};\n\n            freeInput.size      = sizeof(ADDR_FREESYSMEM_INPUT);\n            freeInput.hClient   = pClient->handle;\n            freeInput.pVirtAddr = pObjMem;\n\n            pClient->callbacks.freeSysMem(&freeInput);\n        }\n    }\n}\n\n/**\n****************************************************************************************************\n*   Object::Free\n*\n*   @brief\n*       A wrapper of ClientFree\n****************************************************************************************************\n*/\nVOID Object::Free(\n    VOID* pObjMem       ///< [in] User virtual address to free.\n    ) const\n{\n    ClientFree(pObjMem, &m_client);\n}\n\n/**\n****************************************************************************************************\n*   Object::operator new\n*\n*   @brief\n*       Placement new operator. (with pre-allocated memory pointer)\n*\n*   @return\n*       Returns pre-allocated memory pointer.\n****************************************************************************************************\n*/\nVOID* Object::operator new(\n    size_t objSize,     ///< [in] Size to allocate\n    VOID*  pMem        ///< [in] Pre-allocated pointer\n    ) noexcept\n{\n    return pMem;\n}\n\n/**\n****************************************************************************************************\n*   Object::operator delete\n*\n*   @brief\n*       Frees Object object memory.\n****************************************************************************************************\n*/\nVOID Object::operator delete(\n    VOID* pObjMem)      ///< [in] User virtual address to free.\n{\n    Object* pObj = static_cast<Object*>(pObjMem);\n    ClientFree(pObjMem, &pObj->m_client);\n}\n\n/**\n****************************************************************************************************\n*   Object::DebugPrint\n*\n*   @brief\n*       Print debug message\n*\n*   @return\n*       N/A\n****************************************************************************************************\n*/\nVOID Object::DebugPrint(\n    const CHAR* pDebugString,     ///< [in] Debug string\n    ...\n    ) const\n{\n#if DEBUG\n    if (m_client.callbacks.debugPrint != NULL)\n    {\n        va_list ap;\n\n        va_start(ap, pDebugString);\n\n        ADDR_DEBUGPRINT_INPUT debugPrintInput = {0};\n\n        debugPrintInput.size         = sizeof(ADDR_DEBUGPRINT_INPUT);\n        debugPrintInput.pDebugString = const_cast<CHAR*>(pDebugString);\n        debugPrintInput.hClient      = m_client.handle;\n        va_copy(debugPrintInput.ap, ap);\n\n        m_client.callbacks.debugPrint(&debugPrintInput);\n\n        va_end(ap);\n        va_end(debugPrintInput.ap);\n    }\n#endif\n}\n\n} // Addr\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/addrobject.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n\n/**\n****************************************************************************************************\n* @file  addrobject.h\n* @brief Contains the Object base class definition.\n****************************************************************************************************\n*/\n\n#ifndef __ADDR_OBJECT_H__\n#define __ADDR_OBJECT_H__\n\n#include \"addrtypes.h\"\n#include \"addrcommon.h\"\n\nnamespace rocr {\nnamespace Addr\n{\n\n/**\n****************************************************************************************************\n* @brief This structure contains client specific data\n****************************************************************************************************\n*/\nstruct Client\n{\n    ADDR_CLIENT_HANDLE  handle;\n    ADDR_CALLBACKS      callbacks;\n};\n/**\n****************************************************************************************************\n* @brief This class is the base class for all ADDR class objects.\n****************************************************************************************************\n*/\nclass Object\n{\npublic:\n    Object();\n    Object(const Client* pClient);\n    virtual ~Object();\n\n    VOID* operator new(size_t size, VOID* pMem) noexcept;\n    VOID  operator delete(VOID* pObj);\n    /// Microsoft compiler requires a matching delete implementation, which seems to be called when\n    /// bad_alloc is thrown. But currently C++ exception isn't allowed so a dummy implementation is\n    /// added to eliminate the warning.\n    VOID  operator delete(VOID* pObj, VOID* pMem) { ADDR_ASSERT_ALWAYS(); }\n\n    VOID* Alloc(size_t size) const;\n    VOID  Free(VOID* pObj) const;\n\n    VOID DebugPrint(const CHAR* pDebugString, ...) const;\n\n    const Client* GetClient() const {return &m_client;}\n\nprotected:\n    Client m_client;\n\n    static VOID* ClientAlloc(size_t size, const Client* pClient);\n    static VOID  ClientFree(VOID* pObj, const Client* pClient);\n\nprivate:\n    // disallow the copy constructor\n    Object(const Object& a);\n\n    // disallow the assignment operator\n    Object& operator=(const Object& a);\n};\n\n} // Addr\n} // namespace rocr\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/coord.cpp",
    "content": "\n/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n// Coordinate class implementation\n#include \"addrcommon.h\"\n#include \"coord.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\nCoordinate::Coordinate()\n{\n    dim = DIM_X;\n    ord = 0;\n}\n\nCoordinate::Coordinate(enum Dim dim, INT_32 n)\n{\n    set(dim, n);\n}\n\nVOID Coordinate::set(enum Dim d, INT_32 n)\n{\n    dim = d;\n    ord = static_cast<INT_8>(n);\n}\n\nUINT_32 Coordinate::ison(const UINT_32 *coords) const\n{\n    UINT_32 bit = static_cast<UINT_32>(1ull << static_cast<UINT_32>(ord));\n\n    return (coords[dim] & bit) ? 1 : 0;\n}\n\nenum Dim Coordinate::getdim()\n{\n    return dim;\n}\n\nINT_8 Coordinate::getord()\n{\n    return ord;\n}\n\nBOOL_32 Coordinate::operator==(const Coordinate& b)\n{\n    return (dim == b.dim) && (ord == b.ord);\n}\n\nBOOL_32 Coordinate::operator<(const Coordinate& b)\n{\n    BOOL_32 ret;\n\n    if (dim == b.dim)\n    {\n        ret = ord < b.ord;\n    }\n    else\n    {\n        if (dim == DIM_S || b.dim == DIM_M)\n        {\n            ret = TRUE;\n        }\n        else if (b.dim == DIM_S || dim == DIM_M)\n        {\n            ret = FALSE;\n        }\n        else if (ord == b.ord)\n        {\n            ret = dim < b.dim;\n        }\n        else\n        {\n            ret = ord < b.ord;\n        }\n    }\n\n    return ret;\n}\n\nBOOL_32 Coordinate::operator>(const Coordinate& b)\n{\n    BOOL_32 lt = *this < b;\n    BOOL_32 eq = *this == b;\n    return !lt && !eq;\n}\n\nBOOL_32 Coordinate::operator<=(const Coordinate& b)\n{\n    return (*this < b) || (*this == b);\n}\n\nBOOL_32 Coordinate::operator>=(const Coordinate& b)\n{\n    return !(*this < b);\n}\n\nBOOL_32 Coordinate::operator!=(const Coordinate& b)\n{\n    return !(*this == b);\n}\n\nCoordinate& Coordinate::operator++(INT_32)\n{\n    ord++;\n    return *this;\n}\n\n// CoordTerm\n\nCoordTerm::CoordTerm()\n{\n    num_coords = 0;\n}\n\nVOID CoordTerm::Clear()\n{\n    num_coords = 0;\n}\n\nVOID CoordTerm::add(Coordinate& co)\n{\n    // This function adds a coordinate INT_32o the list\n    // It will prevent the same coordinate from appearing,\n    // and will keep the list ordered from smallest to largest\n    UINT_32 i;\n\n    for (i = 0; i < num_coords; i++)\n    {\n        if (m_coord[i] == co)\n        {\n            break;\n        }\n        if (m_coord[i] > co)\n        {\n            for (UINT_32 j = num_coords; j > i; j--)\n            {\n                m_coord[j] = m_coord[j - 1];\n            }\n            m_coord[i] = co;\n            num_coords++;\n            break;\n        }\n    }\n\n    if (i == num_coords)\n    {\n        m_coord[num_coords] = co;\n        num_coords++;\n    }\n}\n\nVOID CoordTerm::add(CoordTerm& cl)\n{\n    for (UINT_32 i = 0; i < cl.num_coords; i++)\n    {\n        add(cl.m_coord[i]);\n    }\n}\n\nBOOL_32 CoordTerm::remove(Coordinate& co)\n{\n    BOOL_32 remove = FALSE;\n    for (UINT_32 i = 0; i < num_coords; i++)\n    {\n        if (m_coord[i] == co)\n        {\n            remove = TRUE;\n            num_coords--;\n        }\n\n        if (remove)\n        {\n            m_coord[i] = m_coord[i + 1];\n        }\n    }\n    return remove;\n}\n\nBOOL_32 CoordTerm::Exists(Coordinate& co)\n{\n    BOOL_32 exists = FALSE;\n    for (UINT_32 i = 0; i < num_coords; i++)\n    {\n        if (m_coord[i] == co)\n        {\n            exists = TRUE;\n            break;\n        }\n    }\n    return exists;\n}\n\nVOID CoordTerm::copyto(CoordTerm& cl)\n{\n    cl.num_coords = num_coords;\n    for (UINT_32 i = 0; i < num_coords; i++)\n    {\n        cl.m_coord[i] = m_coord[i];\n    }\n}\n\nUINT_32 CoordTerm::getsize()\n{\n    return num_coords;\n}\n\nUINT_32 CoordTerm::getxor(const UINT_32 *coords) const\n{\n    UINT_32 out = 0;\n    for (UINT_32 i = 0; i < num_coords; i++)\n    {\n        out = out ^ m_coord[i].ison(coords);\n    }\n    return out;\n}\n\nVOID CoordTerm::getsmallest(Coordinate& co)\n{\n    co = m_coord[0];\n}\n\nUINT_32 CoordTerm::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)\n{\n    for (UINT_32 i = start;  i < num_coords;)\n    {\n        if (((f == '<' && m_coord[i] < co) ||\n             (f == '>' && m_coord[i] > co) ||\n             (f == '=' && m_coord[i] == co)) &&\n            (axis == NUM_DIMS || axis == m_coord[i].getdim()))\n        {\n            for (UINT_32 j = i; j < num_coords - 1; j++)\n            {\n                m_coord[j] = m_coord[j + 1];\n            }\n            num_coords--;\n        }\n        else\n        {\n            i++;\n        }\n    }\n    return num_coords;\n}\n\nCoordinate& CoordTerm::operator[](UINT_32 i)\n{\n    return m_coord[i];\n}\n\nBOOL_32 CoordTerm::operator==(const CoordTerm& b)\n{\n    BOOL_32 ret = TRUE;\n\n    if (num_coords != b.num_coords)\n    {\n        ret = FALSE;\n    }\n    else\n    {\n        for (UINT_32 i = 0; i < num_coords; i++)\n        {\n            // Note: the lists will always be in order, so we can compare the two lists at time\n            if (m_coord[i] != b.m_coord[i])\n            {\n                ret = FALSE;\n                break;\n            }\n        }\n    }\n    return ret;\n}\n\nBOOL_32 CoordTerm::operator!=(const CoordTerm& b)\n{\n    return !(*this == b);\n}\n\nBOOL_32 CoordTerm::exceedRange(const UINT_32 *ranges)\n{\n    BOOL_32 exceed = FALSE;\n    for (UINT_32 i = 0; (i < num_coords) && (exceed == FALSE); i++)\n    {\n        exceed = ((1u << m_coord[i].getord()) <= ranges[m_coord[i].getdim()]);\n    }\n\n    return exceed;\n}\n\n// coordeq\nCoordEq::CoordEq()\n{\n    m_numBits = 0;\n}\n\nVOID CoordEq::remove(Coordinate& co)\n{\n    for (UINT_32 i = 0; i < m_numBits; i++)\n    {\n        m_eq[i].remove(co);\n    }\n}\n\nBOOL_32 CoordEq::Exists(Coordinate& co)\n{\n    BOOL_32 exists = FALSE;\n\n    for (UINT_32 i = 0; i < m_numBits; i++)\n    {\n        if (m_eq[i].Exists(co))\n        {\n            exists = TRUE;\n        }\n    }\n    return exists;\n}\n\nVOID CoordEq::resize(UINT_32 n)\n{\n    if (n > m_numBits)\n    {\n        for (UINT_32 i = m_numBits; i < n; i++)\n        {\n            m_eq[i].Clear();\n        }\n    }\n    m_numBits = n;\n}\n\nUINT_32 CoordEq::getsize()\n{\n    return m_numBits;\n}\n\nUINT_64 CoordEq::solve(const UINT_32 *coords) const\n{\n    UINT_64 out = 0;\n    for (UINT_32 i = 0; i < m_numBits; i++)\n    {\n        out |= static_cast<UINT_64>(m_eq[i].getxor(coords)) << i;\n    }\n    return out;\n}\n\nVOID CoordEq::solveAddr(\n    UINT_64 addr, UINT_32 sliceInM,\n    UINT_32 *coords) const\n{\n    UINT_32 BitsValid[NUM_DIMS] = {0};\n\n    CoordEq temp = *this;\n\n    memset(coords, 0, NUM_DIMS * sizeof(coords[0]));\n\n    UINT_32 bitsLeft = 0;\n\n    for (UINT_32 i = 0; i < temp.m_numBits; i++)\n    {\n        UINT_32 termSize = temp.m_eq[i].getsize();\n\n        if (termSize == 1)\n        {\n            INT_8 bit = (addr >> i) & 1;\n            enum Dim dim = temp.m_eq[i][0].getdim();\n            INT_8 ord = temp.m_eq[i][0].getord();\n\n            ADDR_ASSERT((ord < 32) || (bit == 0));\n\n            BitsValid[dim] |= 1u << ord;\n            coords[dim] |= bit << ord;\n\n            temp.m_eq[i].Clear();\n        }\n        else if (termSize > 1)\n        {\n            bitsLeft++;\n        }\n    }\n\n    if (bitsLeft > 0)\n    {\n        if (sliceInM != 0)\n        {\n            coords[DIM_Z] = coords[DIM_M] / sliceInM;\n            BitsValid[DIM_Z] = 0xffffffff;\n        }\n\n        do\n        {\n            bitsLeft = 0;\n\n            for (UINT_32 i = 0; i < temp.m_numBits; i++)\n            {\n                UINT_32 termSize = temp.m_eq[i].getsize();\n\n                if (termSize == 1)\n                {\n                    INT_8 bit = (addr >> i) & 1;\n                    enum Dim dim = temp.m_eq[i][0].getdim();\n                    INT_8 ord = temp.m_eq[i][0].getord();\n\n                    ADDR_ASSERT((ord < 32) || (bit == 0));\n                    ADDR_ASSERT(dim < DIM_S);\n\n                    BitsValid[dim] |= 1u << ord;\n                    coords[dim] |= bit << ord;\n\n                    temp.m_eq[i].Clear();\n                }\n                else if (termSize > 1)\n                {\n                    CoordTerm tmpTerm = temp.m_eq[i];\n\n                    for (UINT_32 j = 0; j < termSize; j++)\n                    {\n                        enum Dim dim = temp.m_eq[i][j].getdim();\n                        INT_8 ord = temp.m_eq[i][j].getord();\n\n                        ADDR_ASSERT(dim < DIM_S);\n\n                        if (BitsValid[dim] & (1u << ord))\n                        {\n                            UINT_32 v = (((coords[dim] >> ord) & 1) << i);\n                            addr ^= static_cast<UINT_64>(v);\n                            tmpTerm.remove(temp.m_eq[i][j]);\n                        }\n                    }\n\n                    temp.m_eq[i] = tmpTerm;\n\n                    bitsLeft++;\n                }\n            }\n        } while (bitsLeft > 0);\n    }\n}\n\nVOID CoordEq::copy(CoordEq& o, UINT_32 start, UINT_32 num)\n{\n    o.m_numBits = (num == 0xFFFFFFFF) ? m_numBits : num;\n    for (UINT_32 i = 0; i < o.m_numBits; i++)\n    {\n        m_eq[start + i].copyto(o.m_eq[i]);\n    }\n}\n\nVOID CoordEq::reverse(UINT_32 start, UINT_32 num)\n{\n    UINT_32 n = (num == 0xFFFFFFFF) ? m_numBits : num;\n\n    for (UINT_32 i = 0; i < n / 2; i++)\n    {\n        CoordTerm temp;\n        m_eq[start + i].copyto(temp);\n        m_eq[start + n - 1 - i].copyto(m_eq[start + i]);\n        temp.copyto(m_eq[start + n - 1 - i]);\n    }\n}\n\nVOID CoordEq::xorin(CoordEq& x, UINT_32 start)\n{\n    UINT_32 n = ((m_numBits - start) < x.m_numBits) ? (m_numBits - start) : x.m_numBits;\n    for (UINT_32 i = 0; i < n; i++)\n    {\n        m_eq[start + i].add(x.m_eq[i]);\n    }\n}\n\nUINT_32 CoordEq::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)\n{\n    for (UINT_32 i = start; i < m_numBits;)\n    {\n        UINT_32 m = m_eq[i].Filter(f, co, 0, axis);\n        if (m == 0)\n        {\n            for (UINT_32 j = i; j < m_numBits - 1; j++)\n            {\n                m_eq[j] = m_eq[j + 1];\n            }\n            m_numBits--;\n        }\n        else\n        {\n            i++;\n        }\n    }\n    return m_numBits;\n}\n\nVOID CoordEq::shift(INT_32 amount, INT_32 start)\n{\n    if (amount != 0)\n    {\n        INT_32 numBits = static_cast<INT_32>(m_numBits);\n        amount = -amount;\n        INT_32 inc = (amount < 0) ? -1 : 1;\n        INT_32 i = (amount < 0) ? numBits - 1 : start;\n        INT_32 end = (amount < 0) ? start - 1 : numBits;\n        for (; (inc > 0) ? i < end : i > end; i += inc)\n        {\n            if ((i + amount < start) || (i + amount >= numBits))\n            {\n                m_eq[i].Clear();\n            }\n            else\n            {\n                m_eq[i + amount].copyto(m_eq[i]);\n            }\n        }\n    }\n}\n\nCoordTerm& CoordEq::operator[](UINT_32 i)\n{\n    return m_eq[i];\n}\n\nVOID CoordEq::mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start, UINT_32 end)\n{\n    if (end == 0)\n    {\n        ADDR_ASSERT(m_numBits > 0);\n        end = m_numBits - 1;\n    }\n    for (UINT_32 i = start; i <= end; i++)\n    {\n        UINT_32 select = (i - start) % 2;\n        Coordinate& c = (select == 0) ? c0 : c1;\n        m_eq[i].add(c);\n        c++;\n    }\n}\n\nVOID CoordEq::mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start, UINT_32 end)\n{\n    if (end == 0)\n    {\n        ADDR_ASSERT(m_numBits > 0);\n        end = m_numBits - 1;\n    }\n    for (UINT_32 i = start; i <= end; i++)\n    {\n        UINT_32 select = (i - start) % 3;\n        Coordinate& c = (select == 0) ? c0 : ((select == 1) ? c1 : c2);\n        m_eq[i].add(c);\n        c++;\n    }\n}\n\nBOOL_32 CoordEq::operator==(const CoordEq& b)\n{\n    BOOL_32 ret = TRUE;\n\n    if (m_numBits != b.m_numBits)\n    {\n        ret = FALSE;\n    }\n    else\n    {\n        for (UINT_32 i = 0; i < m_numBits; i++)\n        {\n            if (m_eq[i] != b.m_eq[i])\n            {\n                ret = FALSE;\n                break;\n            }\n        }\n    }\n    return ret;\n}\n\nBOOL_32 CoordEq::operator!=(const CoordEq& b)\n{\n    return !(*this == b);\n}\n\n} // V2\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/core/coord.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n// Class used to define a coordinate bit\n\n#ifndef __COORD_H\n#define __COORD_H\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n#if defined(__cplusplus)\n#if defined(_MSC_VER)\n    #if _MSC_VER >= 1900\n        #define ADDR_CPP11_COMPILER TRUE\n    #endif\n#else\n    #if __cplusplus >= 201103L\n        #define ADDR_CPP11_COMPILER TRUE\n    #endif\n#endif\n#endif\n\n#if defined(ADDR_CPP11_COMPILER)\nenum Dim : INT_8\n#else\nenum Dim\n#endif\n{\n   DIM_X,\n   DIM_Y,\n   DIM_Z,\n   DIM_S,\n   DIM_M,\n   NUM_DIMS\n};\n\nclass Coordinate\n{\npublic:\n    Coordinate();\n    Coordinate(enum Dim dim, INT_32 n);\n\n    VOID set(enum Dim dim, INT_32 n);\n    UINT_32 ison(const UINT_32 *coords) const;\n    enum Dim getdim();\n    INT_8   getord();\n\n    BOOL_32 operator==(const Coordinate& b);\n    BOOL_32 operator<(const Coordinate& b);\n    BOOL_32 operator>(const Coordinate& b);\n    BOOL_32 operator<=(const Coordinate& b);\n    BOOL_32 operator>=(const Coordinate& b);\n    BOOL_32 operator!=(const Coordinate& b);\n    Coordinate& operator++(INT_32);\n\nprivate:\n    enum Dim dim;\n    INT_8 ord;\n};\n\nclass CoordTerm\n{\npublic:\n    CoordTerm();\n    VOID Clear();\n    VOID add(Coordinate& co);\n    VOID add(CoordTerm& cl);\n    BOOL_32 remove(Coordinate& co);\n    BOOL_32 Exists(Coordinate& co);\n    VOID copyto(CoordTerm& cl);\n    UINT_32 getsize();\n    UINT_32 getxor(const UINT_32 *coords) const;\n\n    VOID getsmallest(Coordinate& co);\n    UINT_32 Filter(INT_8 f, Coordinate& co, UINT_32 start = 0, enum Dim axis = NUM_DIMS);\n    Coordinate& operator[](UINT_32 i);\n    BOOL_32 operator==(const CoordTerm& b);\n    BOOL_32 operator!=(const CoordTerm& b);\n    BOOL_32 exceedRange(const UINT_32 *ranges);\n\nprivate:\n    static const UINT_32 MaxCoords = 8;\n    UINT_32 num_coords;\n    Coordinate m_coord[MaxCoords];\n};\n\nclass CoordEq\n{\npublic:\n    CoordEq();\n    VOID remove(Coordinate& co);\n    BOOL_32 Exists(Coordinate& co);\n    VOID resize(UINT_32 n);\n    UINT_32 getsize();\n    virtual UINT_64 solve(const UINT_32 *coords) const;\n    virtual VOID solveAddr(UINT_64 addr, UINT_32 sliceInM,\n                           UINT_32 *coords) const;\n\n    VOID copy(CoordEq& o, UINT_32 start = 0, UINT_32 num = 0xFFFFFFFF);\n    VOID reverse(UINT_32 start = 0, UINT_32 num = 0xFFFFFFFF);\n    VOID xorin(CoordEq& x, UINT_32 start = 0);\n    UINT_32 Filter(INT_8 f, Coordinate& co, UINT_32 start = 0, enum Dim axis = NUM_DIMS);\n    VOID shift(INT_32 amount, INT_32 start = 0);\n    virtual CoordTerm& operator[](UINT_32 i);\n    VOID mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start = 0, UINT_32 end = 0);\n    VOID mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start = 0, UINT_32 end = 0);\n\n    BOOL_32 operator==(const CoordEq& b);\n    BOOL_32 operator!=(const CoordEq& b);\n\nprivate:\n    static const UINT_32 MaxEqBits = 64;\n    UINT_32 m_numBits;\n\n    CoordTerm m_eq[MaxEqBits];\n};\n\n} // V2\n} // Addr\n} // namespace rocr\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx10/gfx10SwizzlePattern.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx10SwizzlePattern.h\n* @brief swizzle pattern for gfx10.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX10_SWIZZLE_PATTERN_H__\n#define __GFX10_SWIZZLE_PATTERN_H__\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\nconst ADDR_SW_PATINFO GFX10_SW_256_S_PATINFO[] =\n{\n    {   1,    0,    0,    0,    0, } , // 1 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 1 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 1 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 1 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 1 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 2 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 2 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 2 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 2 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 2 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 4 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 4 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 4 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 4 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 4 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 8 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 8 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 8 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 8 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 8 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 16 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 16 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 16 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 16 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 16 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 32 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 32 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 32 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 32 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 32 pipes 16 bpe @ SW_256_S @ Navi1x\n    {   1,    0,    0,    0,    0, } , // 64 pipes 1 bpe @ SW_256_S @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 64 pipes 2 bpe @ SW_256_S @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 64 pipes 4 bpe @ SW_256_S @ Navi1x\n    {   1,    3,    0,    0,    0, } , // 64 pipes 8 bpe @ SW_256_S @ Navi1x\n    {   1,    4,    0,    0,    0, } , // 64 pipes 16 bpe @ SW_256_S @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_256_D_PATINFO[] =\n{\n    {   1,    5,    0,    0,    0, } , // 1 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 1 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 1 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 1 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 1 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 2 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 2 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 2 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 2 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 2 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 4 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 4 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 4 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 4 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 4 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 8 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 8 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 8 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 8 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 8 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 16 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 16 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 16 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 16 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 16 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 32 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 32 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 32 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 32 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 32 pipes 16 bpe @ SW_256_D @ Navi1x\n    {   1,    5,    0,    0,    0, } , // 64 pipes 1 bpe @ SW_256_D @ Navi1x\n    {   1,    1,    0,    0,    0, } , // 64 pipes 2 bpe @ SW_256_D @ Navi1x\n    {   1,    2,    0,    0,    0, } , // 64 pipes 4 bpe @ SW_256_D @ Navi1x\n    {   1,    6,    0,    0,    0, } , // 64 pipes 8 bpe @ SW_256_D @ Navi1x\n    {   1,    7,    0,    0,    0, } , // 64 pipes 16 bpe @ SW_256_D @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_S @ Navi1x\n    {   1,    0,    1,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_S @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_S @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_S @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_S @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_S @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_D_PATINFO[] =\n{\n    {   1,    5,    1,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_D @ Navi1x\n    {   1,    5,    1,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_D @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_D @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_D @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_D @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_D @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S_X_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   1,    3,    4,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   1,    4,    5,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,    6,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,    7,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,    8,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,    9,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   10,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,   11,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,   12,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,   13,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,   14,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   15,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,   16,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,   17,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,   18,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,   19,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   20,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,   21,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,   24,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   25,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,   21,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,   24,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   25,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    0,   21,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    3,   24,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_S_X @ Navi1x\n    {   3,    4,   25,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_S_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_D_X_PATINFO[] =\n{\n    {   1,    5,    1,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   1,    1,    2,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   1,    2,    3,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   1,    6,    4,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   1,    7,    5,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,    6,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,    7,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,    8,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,    9,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   10,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,   11,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,   12,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,   13,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,   14,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   15,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,   16,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,   17,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,   18,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,   19,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   20,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,   21,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,   24,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   25,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,   21,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,   24,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   25,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    5,   21,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    1,   22,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    2,   23,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    6,   24,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_D_X @ Navi1x\n    {   3,    7,   25,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_D_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S3_PATINFO[] =\n{\n    {   1,   29,  131,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   29,  131,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_S3 @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_S3 @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S3_X_PATINFO[] =\n{\n    {   1,   29,  131,    0,    0, } , // 1 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   1,   30,  132,    0,    0, } , // 1 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   1,   31,  133,    0,    0, } , // 1 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   1,   32,  134,    0,    0, } , // 1 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   1,   33,  135,    0,    0, } , // 1 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  136,    0,    0, } , // 2 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  137,    0,    0, } , // 2 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  138,    0,    0, } , // 2 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  139,    0,    0, } , // 2 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  140,    0,    0, } , // 2 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  141,    0,    0, } , // 4 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  142,    0,    0, } , // 4 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  143,    0,    0, } , // 4 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  144,    0,    0, } , // 4 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  145,    0,    0, } , // 4 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  146,    0,    0, } , // 8 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  147,    0,    0, } , // 8 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  148,    0,    0, } , // 8 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  149,    0,    0, } , // 8 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  150,    0,    0, } , // 8 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  151,    0,    0, } , // 16 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  152,    0,    0, } , // 16 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  153,    0,    0, } , // 16 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  154,    0,    0, } , // 16 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  155,    0,    0, } , // 16 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  151,    0,    0, } , // 32 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  152,    0,    0, } , // 32 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  153,    0,    0, } , // 32 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  154,    0,    0, } , // 32 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  155,    0,    0, } , // 32 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   29,  151,    0,    0, } , // 64 pipes 1 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   30,  152,    0,    0, } , // 64 pipes 2 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   31,  153,    0,    0, } , // 64 pipes 4 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   32,  154,    0,    0, } , // 64 pipes 8 bpe @ SW_4K_S3_X @ Navi1x\n    {   3,   33,  155,    0,    0, } , // 64 pipes 16 bpe @ SW_4K_S3_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 32 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 32 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 32 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 32 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 32 pipes 16 bpe @ SW_64K_S @ Navi1x\n    {   1,    0,    1,    1,    0, } , // 64 pipes 1 bpe @ SW_64K_S @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 64 pipes 2 bpe @ SW_64K_S @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 64 pipes 4 bpe @ SW_64K_S @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 64 pipes 8 bpe @ SW_64K_S @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 64 pipes 16 bpe @ SW_64K_S @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 32 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 32 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 32 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 32 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 32 pipes 16 bpe @ SW_64K_D @ Navi1x\n    {   1,    5,    1,    1,    0, } , // 64 pipes 1 bpe @ SW_64K_D @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 64 pipes 2 bpe @ SW_64K_D @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 64 pipes 4 bpe @ SW_64K_D @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 64 pipes 8 bpe @ SW_64K_D @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 64 pipes 16 bpe @ SW_64K_D @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_T_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,   36,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,   37,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,   38,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,   39,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,   40,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,   41,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,   42,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,   43,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,   44,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,   45,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,   46,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,   47,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,   48,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,   49,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,   50,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,   51,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,   52,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,   53,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,   54,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,   55,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,   56,   16,    0, } , // 32 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,   57,   17,    0, } , // 32 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,   58,   18,    0, } , // 32 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,   59,   19,    0, } , // 32 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,   60,   20,    0, } , // 32 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    0,    1,   21,    0, } , // 64 pipes 1 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    1,    2,   22,    0, } , // 64 pipes 2 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    2,    3,   23,    0, } , // 64 pipes 4 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    3,    4,   24,    0, } , // 64 pipes 8 bpe @ SW_64K_S_T @ Navi1x\n    {   2,    4,    5,   25,    0, } , // 64 pipes 16 bpe @ SW_64K_S_T @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_T_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,   36,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,   37,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,   38,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,   39,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,   40,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,   41,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,   42,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,   43,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,   44,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,   45,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,   46,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,   47,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,   48,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,   49,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,   50,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,   51,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,   52,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,   53,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,   54,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,   55,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,   56,   16,    0, } , // 32 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,   57,   17,    0, } , // 32 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,   58,   18,    0, } , // 32 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,   59,   19,    0, } , // 32 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,   60,   20,    0, } , // 32 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    5,    1,   21,    0, } , // 64 pipes 1 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    1,    2,   22,    0, } , // 64 pipes 2 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    2,    3,   23,    0, } , // 64 pipes 4 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    6,    4,   24,    0, } , // 64 pipes 8 bpe @ SW_64K_D_T @ Navi1x\n    {   2,    7,    5,   25,    0, } , // 64 pipes 16 bpe @ SW_64K_D_T @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_X_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   1,    3,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   1,    4,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,    6,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,    7,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,    8,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,    9,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   10,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,   11,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,   12,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,   13,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,   14,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   15,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,   16,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,   17,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,   18,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,   19,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   20,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,   21,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,   22,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,   23,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,   24,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   25,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,   26,    6,    0, } , // 32 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,   27,    7,    0, } , // 32 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,   28,    8,    0, } , // 32 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,   29,    9,    0, } , // 32 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   30,   10,    0, } , // 32 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    0,   31,   11,    0, } , // 64 pipes 1 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    1,   32,   12,    0, } , // 64 pipes 2 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    2,   33,   13,    0, } , // 64 pipes 4 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    3,   34,   14,    0, } , // 64 pipes 8 bpe @ SW_64K_S_X @ Navi1x\n    {   3,    4,   35,   15,    0, } , // 64 pipes 16 bpe @ SW_64K_S_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_X_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,    6,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,    7,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,    8,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,    9,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   10,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,   11,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,   12,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,   13,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,   14,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   15,    5,    0, } , // 4 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,   16,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,   17,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,   18,    3,    0, } , // 8 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,   19,    4,    0, } , // 8 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   20,    5,    0, } , // 8 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,   21,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,   22,    2,    0, } , // 16 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,   23,    3,    0, } , // 16 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,   24,    4,    0, } , // 16 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   25,    5,    0, } , // 16 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,   26,    6,    0, } , // 32 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,   27,    7,    0, } , // 32 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,   28,    8,    0, } , // 32 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,   29,    9,    0, } , // 32 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   30,   10,    0, } , // 32 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    5,   31,   11,    0, } , // 64 pipes 1 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    1,   32,   12,    0, } , // 64 pipes 2 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    2,   33,   13,    0, } , // 64 pipes 4 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    6,   34,   14,    0, } , // 64 pipes 8 bpe @ SW_64K_D_X @ Navi1x\n    {   3,    7,   35,   15,    0, } , // 64 pipes 16 bpe @ SW_64K_D_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_1xaa_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   1,    1,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   1,    2,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   1,    6,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   61,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   62,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,    8,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   63,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   64,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   65,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   66,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,   67,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   68,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   69,   26,    0, } , // 4 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   70,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   71,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,   72,   27,    0, } , // 8 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   72,   28,    0, } , // 8 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   73,   29,    0, } , // 8 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   74,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   74,   30,    0, } , // 16 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,   74,   31,    0, } , // 16 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   74,   32,    0, } , // 16 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   74,   33,    0, } , // 16 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   75,    6,    0, } , // 32 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   75,   34,    0, } , // 32 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,   75,   35,    0, } , // 32 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   75,   36,    0, } , // 32 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   76,   37,    0, } , // 32 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,   28,   77,   11,    0, } , // 64 pipes 1 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    1,   77,   38,    0, } , // 64 pipes 2 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    2,   77,   39,    0, } , // 64 pipes 4 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    6,   78,   40,    0, } , // 64 pipes 8 bpe @ SW_64K_R_X 1xaa @ Navi1x\n    {   3,    7,   79,   41,    0, } , // 64 pipes 16 bpe @ SW_64K_R_X 1xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_2xaa_PATINFO[] =\n{\n    {   2,    5,    1,   99,    0, } , // 1 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   2,    1,    2,  100,    0, } , // 1 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   2,    2,    3,  101,    0, } , // 1 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   2,    6,    4,  102,    0, } , // 1 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   2,    7,    5,  103,    0, } , // 1 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   61,   99,    0, } , // 2 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   62,  100,    0, } , // 2 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,    8,  101,    0, } , // 2 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   63,  102,    0, } , // 2 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,   64,  103,    0, } , // 2 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   65,   99,    0, } , // 4 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   66,  100,    0, } , // 4 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,   67,  101,    0, } , // 4 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   68,  102,    0, } , // 4 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,   69,  104,    0, } , // 4 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   70,   99,    0, } , // 8 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   71,  100,    0, } , // 8 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,   72,  105,    0, } , // 8 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   72,  106,    0, } , // 8 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,   73,  107,    0, } , // 8 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   74,   99,    0, } , // 16 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   74,  108,    0, } , // 16 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,   74,  109,    0, } , // 16 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   74,  107,    0, } , // 16 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,  113,   33,    0, } , // 16 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   75,  110,    0, } , // 32 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   75,  111,    0, } , // 32 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,   75,  112,    0, } , // 32 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   76,  113,    0, } , // 32 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,  114,   37,    0, } , // 32 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,   28,   78,  114,    0, } , // 64 pipes 1 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    1,   78,  115,    0, } , // 64 pipes 2 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    2,   78,  116,    0, } , // 64 pipes 4 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    6,   79,  117,    0, } , // 64 pipes 8 bpe @ SW_64K_R_X 2xaa @ Navi1x\n    {   3,    7,  115,   41,    0, } , // 64 pipes 16 bpe @ SW_64K_R_X 2xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_4xaa_PATINFO[] =\n{\n    {   2,    5,    1,  118,    0, } , // 1 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   2,    1,    2,  119,    0, } , // 1 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   2,    2,    3,  120,    0, } , // 1 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   2,    6,    4,  121,    0, } , // 1 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   2,    7,    5,  122,    0, } , // 1 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   61,  118,    0, } , // 2 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   62,  119,    0, } , // 2 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,    8,  120,    0, } , // 2 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,   63,  121,    0, } , // 2 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,   64,  122,    0, } , // 2 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   65,  118,    0, } , // 4 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   66,  119,    0, } , // 4 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,   67,  120,    0, } , // 4 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,   68,  121,    0, } , // 4 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,   69,  123,    0, } , // 4 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   70,  118,    0, } , // 8 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   71,  119,    0, } , // 8 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,   72,  124,    0, } , // 8 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,   93,  125,    0, } , // 8 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,  116,  107,    0, } , // 8 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   74,  118,    0, } , // 16 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   74,  126,    0, } , // 16 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,   74,  127,    0, } , // 16 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,  117,  107,    0, } , // 16 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,  118,   33,    0, } , // 16 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   76,  128,    0, } , // 32 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   76,  129,    0, } , // 32 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,   76,  130,    0, } , // 32 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,  119,  113,    0, } , // 32 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,  120,   37,    0, } , // 32 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,   28,   79,  131,    0, } , // 64 pipes 1 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    1,   79,  132,    0, } , // 64 pipes 2 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    2,   79,  133,    0, } , // 64 pipes 4 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    6,  121,  117,    0, } , // 64 pipes 8 bpe @ SW_64K_R_X 4xaa @ Navi1x\n    {   3,    7,  122,   41,    0, } , // 64 pipes 16 bpe @ SW_64K_R_X 4xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_8xaa_PATINFO[] =\n{\n    {   2,    5,    1,  134,    0, } , // 1 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   2,    1,    2,  135,    0, } , // 1 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   2,    2,    3,  135,    0, } , // 1 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   2,    6,    4,  136,    0, } , // 1 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   2,    7,    5,  136,    0, } , // 1 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,   61,  134,    0, } , // 2 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,   62,  135,    0, } , // 2 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,    8,  135,    0, } , // 2 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,   63,  136,    0, } , // 2 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,   64,  136,    0, } , // 2 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,   65,  134,    0, } , // 4 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,   66,  135,    0, } , // 4 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,   67,  135,    0, } , // 4 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,   68,  136,    0, } , // 4 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,  102,  137,    0, } , // 4 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,   70,  134,    0, } , // 8 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,   71,  135,    0, } , // 8 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,   72,  138,    0, } , // 8 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,  123,  139,    0, } , // 8 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,  124,  140,    0, } , // 8 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,  105,  134,    0, } , // 16 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,  105,  138,    0, } , // 16 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,  125,  127,    0, } , // 16 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,  126,  107,    0, } , // 16 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,  126,  141,    0, } , // 16 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,  107,  142,    0, } , // 32 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,  108,  143,    0, } , // 32 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,  127,  130,    0, } , // 32 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,  128,  113,    0, } , // 32 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,  128,  144,    0, } , // 32 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,   28,  110,  145,    0, } , // 64 pipes 1 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    1,  111,  146,    0, } , // 64 pipes 2 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    2,  129,  133,    0, } , // 64 pipes 4 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    6,  130,  117,    0, } , // 64 pipes 8 bpe @ SW_64K_R_X 8xaa @ Navi1x\n    {   3,    7,  130,  147,    0, } , // 64 pipes 16 bpe @ SW_64K_R_X 8xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_1xaa_PATINFO[] =\n{\n    {   1,    8,    1,    1,    0, } , // 1 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   1,    9,    2,    2,    0, } , // 1 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   1,   10,    3,    3,    0, } , // 1 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   1,   11,    4,    4,    0, } , // 1 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   1,    7,    5,    5,    0, } , // 1 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   61,    1,    0, } , // 2 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   62,    2,    0, } , // 2 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,    8,    3,    0, } , // 2 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   63,    4,    0, } , // 2 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   64,    5,    0, } , // 2 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   65,    1,    0, } , // 4 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   66,    2,    0, } , // 4 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,   67,    3,    0, } , // 4 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   68,    4,    0, } , // 4 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   69,   26,    0, } , // 4 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   70,    1,    0, } , // 8 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   71,    2,    0, } , // 8 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,   72,   27,    0, } , // 8 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   72,   28,    0, } , // 8 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   73,   29,    0, } , // 8 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   74,    1,    0, } , // 16 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   74,   30,    0, } , // 16 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,   74,   31,    0, } , // 16 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   74,   32,    0, } , // 16 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   74,   33,    0, } , // 16 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   75,    6,    0, } , // 32 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   75,   34,    0, } , // 32 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,   75,   35,    0, } , // 32 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   75,   36,    0, } , // 32 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   76,   37,    0, } , // 32 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   12,   77,   11,    0, } , // 64 pipes 1 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    9,   77,   38,    0, } , // 64 pipes 2 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   10,   77,   39,    0, } , // 64 pipes 4 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,   11,   78,   40,    0, } , // 64 pipes 8 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n    {   3,    7,   79,   41,    0, } , // 64 pipes 16 bpe @ SW_64K_Z_X 1xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_2xaa_PATINFO[] =\n{\n    {   1,   13,   80,   42,    0, } , // 1 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   1,   14,    3,    3,    0, } , // 1 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   2,   15,    3,   43,    0, } , // 1 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   2,   16,   81,   44,    0, } , // 1 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   2,   17,    5,   45,    0, } , // 1 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   82,   42,    0, } , // 2 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,    8,    3,    0, } , // 2 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,    8,   43,    0, } , // 2 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   83,   44,    0, } , // 2 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   64,   45,    0, } , // 2 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   84,   42,    0, } , // 4 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,   67,    3,    0, } , // 4 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,   67,   43,    0, } , // 4 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   85,   44,    0, } , // 4 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   69,   46,    0, } , // 4 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   86,   42,    0, } , // 8 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,   72,   27,    0, } , // 8 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,   72,   47,    0, } , // 8 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   73,   48,    0, } , // 8 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   73,   49,    0, } , // 8 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   74,   50,    0, } , // 16 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,   74,   31,    0, } , // 16 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,   74,   51,    0, } , // 16 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   74,   52,    0, } , // 16 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   87,   53,    0, } , // 16 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   75,   54,    0, } , // 32 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,   75,   35,    0, } , // 32 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,   75,   55,    0, } , // 32 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   76,   56,    0, } , // 32 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   88,   57,    0, } , // 32 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   13,   78,   58,    0, } , // 64 pipes 1 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   14,   78,   59,    0, } , // 64 pipes 2 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   15,   78,   60,    0, } , // 64 pipes 4 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   16,   79,   41,    0, } , // 64 pipes 8 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n    {   3,   17,   89,   61,    0, } , // 64 pipes 16 bpe @ SW_64K_Z_X 2xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_4xaa_PATINFO[] =\n{\n    {   1,   18,    3,    3,    0, } , // 1 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   2,   19,   90,   62,    0, } , // 1 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   2,   20,    3,   63,    0, } , // 1 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   2,   21,    4,   64,    0, } , // 1 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   2,   22,    5,   65,    0, } , // 1 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,    8,    3,    0, } , // 2 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   91,   62,    0, } , // 2 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,    8,   66,    0, } , // 2 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   63,   67,    0, } , // 2 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,   64,   68,    0, } , // 2 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,   67,    3,    0, } , // 4 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   92,   62,    0, } , // 4 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,   67,   63,    0, } , // 4 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   68,   64,    0, } , // 4 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,   69,   69,    0, } , // 4 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,   72,   27,    0, } , // 8 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   72,   70,    0, } , // 8 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,   72,   71,    0, } , // 8 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   93,   72,    0, } , // 8 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,   94,   73,    0, } , // 8 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,   74,   31,    0, } , // 16 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   74,   74,    0, } , // 16 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,   74,   75,    0, } , // 16 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   95,   76,    0, } , // 16 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,   96,   76,    0, } , // 16 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,   76,   77,    0, } , // 32 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   76,   78,    0, } , // 32 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,   76,   56,    0, } , // 32 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   97,   79,    0, } , // 32 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,   98,   79,    0, } , // 32 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   18,   79,   80,    0, } , // 64 pipes 1 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   19,   79,   81,    0, } , // 64 pipes 2 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   20,   79,   41,    0, } , // 64 pipes 4 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   21,   99,   82,    0, } , // 64 pipes 8 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n    {   3,   22,  100,   82,    0, } , // 64 pipes 16 bpe @ SW_64K_Z_X 4xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_8xaa_PATINFO[] =\n{\n    {   2,   23,    3,   43,    0, } , // 1 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   2,   24,    3,   63,    0, } , // 1 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   2,   25,    3,   83,    0, } , // 1 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   2,   26,   81,   84,    0, } , // 1 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   2,   27,    5,   85,    0, } , // 1 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,    8,   43,    0, } , // 2 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,    8,   66,    0, } , // 2 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,    8,   86,    0, } , // 2 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,  101,   87,    0, } , // 2 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,   64,   88,    0, } , // 2 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,   67,   43,    0, } , // 4 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,   67,   63,    0, } , // 4 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,   67,   83,    0, } , // 4 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,   85,   84,    0, } , // 4 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,  102,   89,    0, } , // 4 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,   72,   47,    0, } , // 8 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,   72,   71,    0, } , // 8 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,   72,   90,    0, } , // 8 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,  103,   91,    0, } , // 8 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,  104,   92,    0, } , // 8 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,  105,   51,    0, } , // 16 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,  105,   75,    0, } , // 16 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,   87,   93,    0, } , // 16 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,   96,   76,    0, } , // 16 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,  106,   94,    0, } , // 16 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,  107,   95,    0, } , // 32 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,  108,   56,    0, } , // 32 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,   88,   57,    0, } , // 32 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,   98,   79,    0, } , // 32 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,  109,   96,    0, } , // 32 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   23,  110,   97,    0, } , // 64 pipes 1 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   24,  111,   41,    0, } , // 64 pipes 2 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   25,   89,   61,    0, } , // 64 pipes 4 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   26,  100,   82,    0, } , // 64 pipes 8 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n    {   3,   27,  112,   98,    0, } , // 64 pipes 16 bpe @ SW_64K_Z_X 8xaa @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 1 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 1 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 1 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 1 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 2 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 2 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 2 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 2 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 2 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 4 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 4 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 4 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 4 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 4 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 8 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 8 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 8 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 8 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 8 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 16 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 16 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 16 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 16 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 16 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 32 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 32 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 32 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 32 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 32 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   29,  131,  148,    0, } , // 64 pipes 1 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 64 pipes 2 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 64 pipes 4 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 64 pipes 8 bpe @ SW_64K_S3 @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 64 pipes 16 bpe @ SW_64K_S3 @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_X_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 1 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 1 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 1 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 1 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  136,  148,    0, } , // 2 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  137,  149,    0, } , // 2 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  138,  150,    0, } , // 2 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  139,  151,    0, } , // 2 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  140,  152,    0, } , // 2 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  141,  148,    0, } , // 4 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  142,  149,    0, } , // 4 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  143,  150,    0, } , // 4 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  144,  151,    0, } , // 4 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  145,  152,    0, } , // 4 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  146,  148,    0, } , // 8 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  147,  149,    0, } , // 8 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  148,  150,    0, } , // 8 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  149,  151,    0, } , // 8 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  150,  152,    0, } , // 8 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  151,  148,    0, } , // 16 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  152,  149,    0, } , // 16 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  153,  150,    0, } , // 16 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  154,  151,    0, } , // 16 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  155,  152,    0, } , // 16 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  156,  153,    0, } , // 32 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  157,  154,    0, } , // 32 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  158,  155,    0, } , // 32 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  159,  156,    0, } , // 32 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  160,  157,    0, } , // 32 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   29,  161,  158,    0, } , // 64 pipes 1 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   30,  162,  159,    0, } , // 64 pipes 2 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   31,  163,  160,    0, } , // 64 pipes 4 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   32,  164,  161,    0, } , // 64 pipes 8 bpe @ SW_64K_S3_X @ Navi1x\n    {   3,   33,  165,  162,    0, } , // 64 pipes 16 bpe @ SW_64K_S3_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_T_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   1,   30,  132,  149,    0, } , // 1 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   1,   31,  133,  150,    0, } , // 1 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   1,   32,  134,  151,    0, } , // 1 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   1,   33,  135,  152,    0, } , // 1 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  136,  148,    0, } , // 2 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  137,  149,    0, } , // 2 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  138,  150,    0, } , // 2 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  139,  151,    0, } , // 2 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  140,  152,    0, } , // 2 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  141,  148,    0, } , // 4 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  142,  149,    0, } , // 4 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  143,  150,    0, } , // 4 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  144,  151,    0, } , // 4 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  145,  152,    0, } , // 4 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  166,  148,    0, } , // 8 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  167,  149,    0, } , // 8 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  168,  150,    0, } , // 8 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  169,  151,    0, } , // 8 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  170,  152,    0, } , // 8 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  171,  148,    0, } , // 16 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  172,  149,    0, } , // 16 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  173,  150,    0, } , // 16 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  174,  151,    0, } , // 16 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  175,  152,    0, } , // 16 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  176,  153,    0, } , // 32 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  177,  154,    0, } , // 32 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  178,  155,    0, } , // 32 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  179,  156,    0, } , // 32 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  180,  157,    0, } , // 32 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   29,  131,  163,    0, } , // 64 pipes 1 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   30,  132,  164,    0, } , // 64 pipes 2 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   31,  133,  165,    0, } , // 64 pipes 4 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   32,  134,  166,    0, } , // 64 pipes 8 bpe @ SW_64K_S3_T @ Navi1x\n    {   3,   33,  135,  167,    0, } , // 64 pipes 16 bpe @ SW_64K_S3_T @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D3_X_PATINFO[] =\n{\n    {   1,   34,  131,  148,    0, } , // 1 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   1,   35,  132,  149,    0, } , // 1 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   1,   36,  133,  150,    0, } , // 1 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   1,   37,  134,  151,    0, } , // 1 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   1,   38,  135,  152,    0, } , // 1 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   34,  181,  148,    0, } , // 2 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   35,  182,  149,    0, } , // 2 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   36,  183,  150,    0, } , // 2 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   37,  184,  168,    0, } , // 2 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   38,  185,  169,    0, } , // 2 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   34,  186,  170,    0, } , // 4 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   35,  186,  171,    0, } , // 4 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   36,  187,  172,    0, } , // 4 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   37,  188,  169,    0, } , // 4 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   38,  189,  169,    0, } , // 4 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   2,   34,  190,  173,    0, } , // 8 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   35,  191,  171,    0, } , // 8 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   36,  192,  172,    0, } , // 8 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   37,  193,  169,    0, } , // 8 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   38,  194,  169,    0, } , // 8 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   34,  195,  174,    0, } , // 16 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   35,  196,  171,    0, } , // 16 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   36,  197,  172,    0, } , // 16 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   37,  198,  169,    0, } , // 16 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   38,  199,  169,    0, } , // 16 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   34,  200,  175,    0, } , // 32 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   35,  201,  176,    0, } , // 32 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   36,  202,  177,    0, } , // 32 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   37,  203,  178,    0, } , // 32 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   38,  204,  178,    0, } , // 32 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   34,  205,  179,    0, } , // 64 pipes 1 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   35,  206,  180,    0, } , // 64 pipes 2 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   36,  207,  181,    0, } , // 64 pipes 4 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   37,  208,  182,    0, } , // 64 pipes 8 bpe @ SW_64K_D3_X @ Navi1x\n    {   3,   38,  209,  182,    0, } , // 64 pipes 16 bpe @ SW_64K_D3_X @ Navi1x\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_256_S_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    0,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256_S @ RbPlus\n    {   1,    0,    0,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256_S @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256_S @ RbPlus\n    {   1,    2,    0,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256_S @ RbPlus\n    {   1,    3,    0,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256_S @ RbPlus\n    {   1,    4,    0,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256_S @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_256_D_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    0,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256_D @ RbPlus\n    {   1,    5,    0,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256_D @ RbPlus\n    {   1,    1,    0,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256_D @ RbPlus\n    {   1,   39,    0,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256_D @ RbPlus\n    {   1,    6,    0,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256_D @ RbPlus\n    {   1,    7,    0,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256_D @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n    {   1,    0,    1,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_D_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n    {   1,    5,    1,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_D @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_D @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_D @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_D @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_D @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S_X_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   1,    2,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   1,    3,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   1,    4,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,    6,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,    7,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,    8,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,    9,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,   10,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  210,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  211,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  212,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  213,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  214,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  215,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  216,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  217,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  218,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  219,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,   11,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,   12,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,   13,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,   14,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,   15,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  220,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  221,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  222,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  223,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  224,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  225,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  226,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  227,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  228,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  229,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,   16,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,   17,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,   18,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,   19,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,   20,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  230,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  231,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  232,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  233,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  234,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  235,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  236,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  237,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  238,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  239,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,   21,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,   22,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,   23,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,   24,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,   25,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  240,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  241,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  242,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  243,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  244,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  245,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  246,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  247,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  248,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  249,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,   21,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,   22,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,   23,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,   24,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,   25,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    0,  240,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    1,  241,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    2,  242,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    3,  243,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S_X @ RbPlus\n    {   3,    4,  244,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_D_X_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   1,   39,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   1,    6,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   1,    7,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,    6,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,    7,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,    8,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,    9,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,   10,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  210,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  211,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  212,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  213,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  214,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  215,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  216,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  217,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  218,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  219,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,   11,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,   12,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,   13,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,   14,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,   15,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  220,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  221,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  222,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  223,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  224,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  225,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  226,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  227,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  228,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  229,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,   16,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,   17,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,   18,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,   19,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,   20,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  230,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  231,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  232,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  233,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  234,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  235,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  236,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  237,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  238,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  239,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,   21,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,   22,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,   23,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,   24,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,   25,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  240,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  241,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  242,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  243,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  244,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  245,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  246,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  247,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  248,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  249,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,   21,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,   22,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,   23,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,   24,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,   25,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    5,  240,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    1,  241,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_D_X @ RbPlus\n    {   3,   39,  242,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    6,  243,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_D_X @ RbPlus\n    {   3,    7,  244,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_D_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S3_RBPLUS_PATINFO[] =\n{\n    {   1,   29,  131,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   29,  131,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S3 @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S3 @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_4K_S3_X_RBPLUS_PATINFO[] =\n{\n    {   1,   29,  131,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   1,   30,  132,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   1,   31,  133,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   1,   32,  134,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   1,   33,  135,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  136,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  137,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  138,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  139,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  140,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  141,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  142,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  143,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  144,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  145,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  146,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  147,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  148,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  149,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  150,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  141,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  142,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  143,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  144,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  145,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  146,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  147,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  148,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  149,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  150,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  146,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  147,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  148,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  149,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  150,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   29,  151,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   30,  152,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   31,  153,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   32,  154,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S3_X @ RbPlus\n    {   3,   33,  155,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S3_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n    {   1,    0,    1,    1,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n    {   1,    5,    1,    1,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_T_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   36,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   37,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   38,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   39,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   40,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   41,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   42,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   43,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   44,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   45,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   46,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   48,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   49,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   50,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   41,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   42,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   43,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   44,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   45,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   46,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   48,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   49,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   50,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   51,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   53,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   54,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   55,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   46,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   48,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   49,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   50,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   51,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   53,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   54,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   55,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   56,   16,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   58,   18,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   59,   19,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   60,   20,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   51,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   53,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   54,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   55,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   56,   16,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   58,   18,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   59,   19,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   60,   20,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,    1,   21,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,    2,   22,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,    3,   23,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,    4,   24,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,    5,   25,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,   56,   16,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,   58,   18,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,   59,   19,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,   60,   20,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    0,    1,   21,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    1,    2,   22,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    2,    3,   23,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    3,    4,   24,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S_T @ RbPlus\n    {   2,    4,    5,   25,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S_T @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_T_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   36,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   37,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   38,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   39,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   40,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   41,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   42,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   43,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   44,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   45,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   46,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   48,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   49,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   50,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   41,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   42,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   43,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   44,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   45,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   46,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   48,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   49,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   50,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   51,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   53,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   54,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   55,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   46,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   47,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   48,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   49,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   50,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   51,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   53,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   54,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   55,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   56,   16,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   58,   18,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   59,   19,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   60,   20,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   51,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   52,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   53,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   54,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   55,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   56,   16,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   58,   18,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   59,   19,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   60,   20,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,    1,   21,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,    2,   22,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,    3,   23,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,    4,   24,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,    5,   25,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,   56,   16,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,   57,   17,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,   58,   18,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,   59,   19,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,   60,   20,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    5,    1,   21,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    1,    2,   22,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D_T @ RbPlus\n    {   2,   39,    3,   23,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    6,    4,   24,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D_T @ RbPlus\n    {   2,    7,    5,   25,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D_T @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S_X_RBPLUS_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,    6,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,    7,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,    8,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,    9,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,   10,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  210,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  211,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  212,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  213,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  214,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  215,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  216,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  217,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  218,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  219,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,   11,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,   12,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,   13,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,   14,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,   15,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  220,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  221,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  222,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  223,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  224,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  225,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  226,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  227,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  228,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  229,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,   16,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,   17,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,   18,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,   19,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,   20,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  230,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  231,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  232,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  233,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  234,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  250,    6,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  251,    7,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  252,    8,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  253,    9,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  254,   10,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,   21,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,   22,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,   23,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,   24,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,   25,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  255,    6,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  256,    7,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  257,    8,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  258,    9,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  259,   10,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  260,   11,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  261,   12,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  262,   13,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  263,   14,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  264,   15,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,   26,    6,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,   27,    7,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,   28,    8,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,   29,    9,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,   30,   10,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    0,  265,   11,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    1,  266,   12,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    2,  267,   13,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    3,  268,   14,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S_X @ RbPlus\n    {   3,    4,  269,   15,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D_X_RBPLUS_PATINFO[] =\n{\n    {   1,    5,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   1,   39,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   1,    6,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   1,    7,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,    6,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,    7,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,    8,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,    9,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,   10,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  210,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  211,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  212,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  213,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  214,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  215,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  216,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  217,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  218,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  219,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,   11,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,   12,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,   13,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,   14,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,   15,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  220,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  221,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  222,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  223,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  224,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  225,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  226,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  227,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  228,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  229,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,   16,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,   17,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,   18,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,   19,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,   20,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  230,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  231,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  232,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  233,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  234,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  250,    6,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  251,    7,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  252,    8,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  253,    9,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  254,   10,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,   21,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,   22,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,   23,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,   24,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,   25,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  255,    6,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  256,    7,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  257,    8,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  258,    9,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  259,   10,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  260,   11,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  261,   12,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  262,   13,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  263,   14,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  264,   15,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,   26,    6,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,   27,    7,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,   28,    8,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,   29,    9,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,   30,   10,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    5,  265,   11,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    1,  266,   12,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D_X @ RbPlus\n    {   3,   39,  267,   13,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    6,  268,   14,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D_X @ RbPlus\n    {   3,    7,  269,   15,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_1xaa_RBPLUS_PATINFO[] =\n{\n    {   2,    0,  347,  193,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   2,    1,  348,  366,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   2,   39,  349,  195,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   2,    6,  350,  367,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   2,    7,  351,  368,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  352,  193,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  353,  194,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  354,  195,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  355,  369,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  356,  370,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  280,  193,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  281,  194,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  283,  196,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  284,  197,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  394,  219,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  395,  371,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  396,  372,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  397,  373,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  398,  374,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  290,  203,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  291,  204,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  292,  205,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  293,  206,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  294,  207,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  295,  219,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  296,  375,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  297,  376,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  298,  377,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  299,  378,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  399,  379,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  399,  380,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  399,  381,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  399,  382,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  399,  383,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  400,  669,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  401,  670,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  402,  671,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  304,  387,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  305,  388,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  307,  379,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  307,  389,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  307,  381,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  307,  382,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  307,  390,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  307,  672,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  307,  673,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  307,  674,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  307,  675,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  307,  676,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  677,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  678,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  679,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  399,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  323,  400,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  680,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  681,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  682,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  404,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  323,  405,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  505,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  506,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  507,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  683,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  323,  684,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  311,  685,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  311,  686,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  311,  687,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  318,  411,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  324,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    0,  311,  513,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    1,  311,  514,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,   39,  311,  515,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    6,  318,  413,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 1xaa @ RbPlus\n    {   3,    7,  324,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 1xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_2xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  424,  526,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  348,  527,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  358,  528,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  350,  688,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  359,  689,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  352,  526,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  353,  527,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  354,  528,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  355,  688,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  356,  690,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  280,  526,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  281,  527,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  282,  528,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  283,  529,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  284,  530,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  394,  691,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  395,  692,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  396,  693,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  397,  694,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  425,  695,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  290,  534,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  291,  535,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  292,  536,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  293,  537,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  294,  538,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  295,  691,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  296,  696,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  297,  697,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  298,  698,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  299,  699,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  399,  700,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  399,  701,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  399,  702,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  399,  703,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  426,  429,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  400,  704,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  401,  705,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  402,  706,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  304,  707,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  364,  708,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  307,  700,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  307,  701,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  307,  702,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  307,  703,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  427,  390,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  307,  709,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  307,  710,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  307,  711,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  307,  712,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  427,  676,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  713,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  714,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  715,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  323,  716,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  428,  400,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  717,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  718,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  719,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  323,  720,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  428,  405,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  721,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  722,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  723,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  323,  724,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  428,  684,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  318,  725,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  318,  726,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  318,  727,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  324,  728,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  429,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    0,  318,  729,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    1,  318,  730,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,   39,  318,  731,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    6,  324,  732,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 2xaa @ RbPlus\n    {   3,    7,  429,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 2xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_4xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  347,  566,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  348,  733,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  349,  568,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  350,  734,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  351,  735,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  352,  566,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  353,  567,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  354,  568,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  355,  736,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  356,  737,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  280,  566,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  281,  567,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  282,  568,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  283,  569,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  284,  570,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  394,  587,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  395,  738,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  396,  739,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  397,  740,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  430,  741,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  290,  576,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  291,  577,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  292,  578,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  293,  579,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  405,  580,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  295,  587,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  296,  742,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  297,  743,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  298,  740,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  431,  699,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  399,  744,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  399,  745,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  399,  746,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  432,  747,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  433,  429,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  400,  748,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  401,  749,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  402,  750,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  434,  707,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  435,  708,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  307,  744,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  307,  751,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  307,  746,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  436,  703,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  437,  390,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  307,  752,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  307,  753,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  307,  754,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  436,  712,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  437,  676,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  755,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  756,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  757,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  438,  716,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  439,  400,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  758,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  759,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  760,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  438,  720,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  439,  405,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  761,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  762,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  763,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  438,  724,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  439,  684,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  324,  764,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  324,  765,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  324,  766,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  440,  728,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  441,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    0,  324,  767,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    1,  324,  768,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,   39,  324,  769,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    6,  440,  732,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 4xaa @ RbPlus\n    {   3,    7,  441,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 4xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_R_X_8xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  424,  619,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  348,  620,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  358,  621,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  350,  770,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  359,  771,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  352,  619,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  353,  620,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  354,  621,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  355,  770,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  378,  772,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  280,  619,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  281,  620,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  282,  621,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  283,  622,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  413,  623,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  394,  773,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  395,  774,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  442,  775,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  443,  776,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  444,  777,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  415,  629,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  291,  630,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  292,  631,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  416,  632,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  417,  580,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  295,  773,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  296,  778,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  297,  779,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  445,  780,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  446,  699,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  399,  781,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  399,  782,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  447,  783,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  448,  784,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  449,  429,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  450,  785,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  302,  786,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  303,  787,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  420,  788,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  451,  708,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  339,  781,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  339,  782,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  422,  746,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  452,  703,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  453,  390,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  339,  789,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  339,  790,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  422,  754,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  452,  712,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  453,  676,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  791,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  341,  792,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  423,  757,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  454,  716,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  455,  400,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  793,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  341,  794,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  423,  760,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  454,  720,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  455,  405,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  795,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  341,  796,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  423,  763,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  454,  724,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  455,  684,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  344,  797,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  345,  798,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  456,  766,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  457,  728,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  458,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    0,  344,  799,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    1,  345,  800,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,   39,  456,  769,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    6,  457,  732,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_R_X 8xaa @ RbPlus\n    {   3,    7,  458,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_R_X 8xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_1xaa_RBPLUS_PATINFO[] =\n{\n    {   2,    8,  347,  193,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   2,    9,  348,  366,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   2,   10,  349,  195,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   2,   11,  350,  367,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   2,    7,  351,  368,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  352,  193,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  353,  194,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  354,  195,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  355,  369,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  356,  370,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  280,  193,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  281,  194,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  283,  196,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  284,  197,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  285,  219,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  286,  371,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  287,  372,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  288,  373,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  289,  374,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  290,  203,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  291,  204,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  292,  205,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  293,  206,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  294,  207,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  295,  219,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  296,  375,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  297,  376,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  298,  377,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  299,  378,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  300,  379,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  300,  380,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  300,  381,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  300,  382,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  300,  383,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  301,  384,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  302,  385,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  303,  386,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  304,  387,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  305,  388,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  306,  379,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  306,  389,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  306,  381,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  307,  382,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  307,  390,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  306,  391,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  306,  392,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  306,  393,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  307,  394,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  307,  395,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  396,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  397,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  398,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  399,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  323,  400,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  401,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  402,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  403,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  404,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  323,  405,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  240,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  241,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  242,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  406,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  323,  407,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  310,  408,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  310,  409,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  310,  410,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  318,  411,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  324,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    8,  310,  250,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    9,  310,  251,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   10,  310,  252,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,   11,  318,  413,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n    {   3,    7,  324,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 1xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_2xaa_RBPLUS_PATINFO[] =\n{\n    {   2,   13,  357,  415,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   2,   14,  349,  195,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  358,  263,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  350,  416,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  359,  417,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  360,  415,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  354,  195,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  354,  263,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  361,  418,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  356,  419,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  281,  262,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  282,  263,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  317,  264,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  284,  265,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  286,  420,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  287,  376,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  287,  421,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  289,  422,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  289,  423,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  291,  268,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  292,  205,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  292,  269,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  293,  270,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  294,  271,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  296,  420,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  297,  376,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  297,  421,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  298,  424,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  299,  423,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  300,  425,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  300,  426,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  300,  427,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  362,  428,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  363,  429,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  302,  430,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  303,  386,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  303,  431,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  305,  432,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  364,  433,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  306,  380,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  306,  381,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  306,  434,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  307,  435,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  365,  435,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  306,  402,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  306,  403,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  306,  436,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  307,  405,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  365,  405,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  397,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  398,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  437,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  323,  438,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  366,  438,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  402,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  403,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  436,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  323,  439,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  366,  439,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  440,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  242,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  441,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  323,  442,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  366,  442,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  310,  443,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  310,  410,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  310,  444,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  324,  412,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  367,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   13,  310,  445,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   14,  310,  252,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   15,  310,  446,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   16,  324,  414,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n    {   3,   17,  367,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 2xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_4xaa_RBPLUS_PATINFO[] =\n{\n    {   2,   18,  349,  195,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  349,  447,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  349,  448,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  350,  449,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  351,  450,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  354,  195,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  368,  451,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  354,  299,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  355,  452,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  356,  453,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  282,  298,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  282,  299,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  283,  300,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  284,  301,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  287,  372,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  287,  454,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  287,  455,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  288,  456,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  331,  457,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  292,  205,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  292,  306,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  292,  307,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  320,  308,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  321,  309,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  297,  376,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  297,  458,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  297,  459,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  299,  460,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  369,  461,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  300,  381,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  300,  462,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  300,  463,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  363,  464,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  370,  465,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  303,  386,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  303,  466,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  303,  467,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  371,  468,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  337,  469,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  306,  381,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  306,  462,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  306,  470,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  372,  470,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  373,  470,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  306,  393,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  306,  471,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  306,  472,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  372,  472,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  373,  472,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  398,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  473,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  438,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  374,  438,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  375,  438,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  403,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  471,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  439,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  374,  439,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  375,  439,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  242,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  441,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  442,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  374,  442,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  375,  442,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  310,  410,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  310,  474,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  310,  412,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  376,  412,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  377,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   18,  310,  252,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   19,  310,  475,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   20,  310,  414,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   21,  376,  414,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n    {   3,   22,  377,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 4xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_Z_X_8xaa_RBPLUS_PATINFO[] =\n{\n    {   3,   23,  358,  263,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  349,  448,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  358,  332,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  350,  476,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  359,  477,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  354,  263,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  354,  299,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  354,  332,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  361,  478,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  378,  479,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  282,  263,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  282,  299,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  282,  332,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  317,  333,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  329,  334,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  287,  421,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  287,  480,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  287,  481,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  379,  482,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  380,  483,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  292,  269,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  292,  307,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  292,  339,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  332,  340,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  333,  341,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  297,  421,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  297,  459,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  297,  481,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  381,  484,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  382,  485,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  300,  434,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  300,  463,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  383,  486,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  384,  487,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  385,  488,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  303,  431,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  303,  467,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  303,  489,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  337,  469,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  386,  469,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  306,  434,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  306,  470,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  387,  490,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  373,  470,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  388,  470,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  306,  436,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  306,  472,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  387,  491,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  373,  472,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  388,  492,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  437,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  438,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  389,  493,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  375,  438,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  390,  438,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  436,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  439,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  391,  494,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  375,  439,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  390,  439,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  441,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  442,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  391,  495,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  375,  442,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  390,  442,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  310,  444,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  310,  412,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  392,  496,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  377,  412,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  393,  412,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   23,  310,  446,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   24,  310,  414,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   25,  367,  414,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   26,  377,  414,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n    {   3,   27,  393,  414,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_Z_X 8xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_RBPLUS_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   29,  131,  148,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3 @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3 @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_X_RBPLUS_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  136,  148,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  137,  149,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  138,  150,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  139,  151,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  140,  152,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  141,  148,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  142,  149,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  143,  150,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  144,  151,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  145,  152,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  146,  148,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  147,  149,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  148,  150,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  149,  151,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  150,  152,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  141,  148,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  142,  149,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  143,  150,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  144,  151,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  145,  152,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  146,  148,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  147,  149,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  148,  150,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  149,  151,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  150,  152,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  151,  148,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  152,  149,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  153,  150,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  154,  151,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  155,  152,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  146,  148,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  147,  149,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  148,  150,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  149,  151,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  150,  152,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  151,  148,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  152,  149,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  153,  150,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  154,  151,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  155,  152,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  156,  153,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  157,  154,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  158,  155,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  159,  156,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  160,  157,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  151,  148,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  152,  149,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  153,  150,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  154,  151,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  155,  152,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  156,  153,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  157,  154,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  158,  155,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  159,  156,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  160,  157,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  161,  158,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  162,  159,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  163,  160,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  164,  161,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  165,  162,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  156,  153,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  157,  154,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  158,  155,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  159,  156,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  160,  157,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   29,  161,  158,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   30,  162,  159,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   31,  163,  160,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   32,  164,  161,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3_X @ RbPlus\n    {   3,   33,  165,  162,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_S3_T_RBPLUS_PATINFO[] =\n{\n    {   1,   29,  131,  148,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   1,   30,  132,  149,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   1,   31,  133,  150,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   1,   32,  134,  151,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   1,   33,  135,  152,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  136,  148,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  137,  149,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  138,  150,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  139,  151,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  140,  152,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  141,  148,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  142,  149,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  143,  150,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  144,  151,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  145,  152,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  166,  148,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  167,  149,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  168,  150,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  169,  151,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  170,  152,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  141,  148,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  142,  149,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  143,  150,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  144,  151,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  145,  152,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  166,  148,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  167,  149,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  168,  150,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  169,  151,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  170,  152,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  171,  148,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  172,  149,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  173,  150,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  174,  151,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  175,  152,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  166,  148,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  167,  149,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  168,  150,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  169,  151,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  170,  152,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  171,  148,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  172,  149,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  173,  150,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  174,  151,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  175,  152,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  176,  153,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  177,  154,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  178,  155,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  179,  156,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  180,  157,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  171,  148,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  172,  149,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  173,  150,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  174,  151,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  175,  152,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  176,  153,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  177,  154,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  178,  155,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  179,  156,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  180,  157,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  131,  163,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  132,  164,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  133,  165,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  134,  166,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  135,  167,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  176,  153,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  177,  154,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  178,  155,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  179,  156,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  180,  157,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   29,  131,  163,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   30,  132,  164,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   31,  133,  165,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   32,  134,  166,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3_T @ RbPlus\n    {   3,   33,  135,  167,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3_T @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_64K_D3_X_RBPLUS_PATINFO[] =\n{\n    {   1,   34,  131,  148,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   1,   35,  132,  149,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   1,   36,  133,  150,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   1,   37,  134,  151,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   1,   38,  135,  152,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   2,   34,  459,  170,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   2,   35,  459,  801,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   2,   36,  460,  802,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   2,   37,  461,  152,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   38,  462,  152,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  463,  803,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  463,  804,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  464,  805,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  465,  806,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  466,  806,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  467,  803,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  467,  804,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  468,  805,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  469,  806,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  470,  806,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  471,  807,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  472,  808,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  473,  809,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  474,  810,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  475,  811,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  476,  812,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  477,  804,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  478,  805,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  479,  806,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  480,  806,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  481,  813,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  482,  804,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  483,  805,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  484,  806,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  485,  806,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  486,  814,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  486,  815,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  486,  816,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  487,  817,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  488,  817,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  489,  812,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  490,  804,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  491,  805,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  492,  806,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  493,  806,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  489,  818,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  494,  819,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  494,  820,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  495,  821,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  496,  821,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  497,  822,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  498,  823,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  499,  824,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  500,  825,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  501,  825,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  497,  826,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  498,  827,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  499,  828,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  500,  829,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  501,  829,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  497,  830,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  502,  831,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  502,  832,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  503,  833,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  504,  833,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  505,  834,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  506,  835,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  507,  836,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  508,  837,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  509,  837,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   34,  505,  838,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   35,  506,  839,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D3_X @ RbPlus\n    {   3,   36,  507,  840,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   37,  508,  841,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D3_X @ RbPlus\n    {   4,   38,  509,  841,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D3_X @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_R_X_1xaa_RBPLUS_PATINFO[] =\n{\n    {   2,    0,  270,  183,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   2,    1,  271,  184,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   2,   39,  272,  185,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   2,    6,  273,  186,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   2,    7,  274,  187,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  275,  188,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  276,  189,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  277,  190,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  278,  191,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  279,  192,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  280,  193,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  281,  194,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  283,  196,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  284,  197,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  394,  198,    1, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  395,  199,    2, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  396,  200,    3, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  397,  201,    4, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  398,  202,    5, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  290,  203,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  291,  204,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  292,  205,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  293,  206,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  294,  207,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  295,  208,    6, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  296,  209,    2, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  297,  210,    7, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  298,  211,    4, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  299,  212,    8, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  399,  213,    9, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  399,  214,   10, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  399,  215,   11, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  399,  216,   12, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  399,  217,   13, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  400,  218,   15, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  401,  219,   15, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  402,  220,   15, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  304,  221,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  305,  222,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  307,  213,    9, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  307,  223,   16, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  307,  215,   11, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  307,  216,   17, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  307,  224,   13, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  307,  497,   18, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  307,  498,   19, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  307,  499,   20, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  307,  500,   21, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  307,  501,   22, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  230,  125, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  231,  126, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  232,  127, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  233,   26, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  309,  234,   27, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  502,   28, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  503,   19, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  504,   29, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  238,   30, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  309,  239,   31, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  309,  505,   32, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  309,  506,   33, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  309,  507,   34, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  309,  508,   35, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  309,  509,   36, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  311,  510,  128, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  311,  511,  129, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  311,  512,  130, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  311,  248,   40, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  311,  249,   41, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    0,  311,  513,   32, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    1,  311,  514,   42, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,   39,  311,  515,   34, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    6,  311,  253,   43, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n    {   3,    7,  311,  254,   44, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 1xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_R_X_2xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  403,  516,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  271,  517,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  313,  518,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  273,  519,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  314,  520,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  404,  521,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  276,  522,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  315,  523,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  278,  524,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  316,  525,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  280,  526,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  281,  527,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  282,  528,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  283,  529,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  284,  530,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  394,  208,  131, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  395,  531,  132, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  396,  302,  133, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  397,  532,  134, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  398,  533,  135, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  290,  534,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  291,  535,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  292,  536,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  293,  537,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  294,  538,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  295,  208,  131, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  296,  209,  132, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  297,  210,  133, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  298,  211,  134, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  299,  212,  135, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  399,  539,  136, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  399,  214,  137, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  399,  280,  138, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  399,  216,  139, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  399,  224,  140, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  400,  540,   15, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  401,  541,   15, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  402,  542,   15, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  304,  543,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  305,  544,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  307,  539,  136, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  307,  214,  137, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  307,  280,  138, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  307,  216,  139, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  307,  224,  140, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  307,  545,  141, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  307,  498,  142, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  307,  546,  143, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  307,  500,  144, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  307,  547,  145, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  548,  146, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  231,  147, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  285,  148, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  309,  233,  149, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  309,  286,  150, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  502,  141, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  503,  151, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  504,  143, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  309,  238,  152, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  309,  239,  153, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  309,  505,  154, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  309,  506,  155, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  309,  507,  156, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  309,  508,  157, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  309,  509,  158, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  318,  549,  159, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  318,  550,  160, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  318,  551,  161, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  318,  287,  162, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  318,  288,  163, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    0,  318,  552,  154, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    1,  318,  553,  155, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,   39,  318,  554,  156, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    6,  318,  555,  157, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n    {   3,    7,  318,  290,  158, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 2xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_R_X_4xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  270,  556,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  271,  557,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  272,  558,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  273,  559,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  274,  560,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  275,  561,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  276,  562,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  277,  563,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  278,  564,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  279,  565,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  280,  566,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  281,  567,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  282,  568,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  283,  569,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  284,  570,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  394,  571,  164, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  395,  572,  165, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  396,  573,  166, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  397,  574,  167, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  398,  575,  168, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  290,  576,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  291,  577,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  292,  578,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  293,  579,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  405,  580,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  295,  581,  169, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  296,  582,  165, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  297,  583,  170, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  298,  584,  167, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  299,  585,  168, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  399,  213,  171, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  399,  214,  172, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  399,  215,  173, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  399,  216,  174, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  399,  217,  175, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  400,  586,   15, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  401,  587,   15, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  402,  588,   15, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  304,  589,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  406,  544,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  307,  213,  171, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  307,  223,  176, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  307,  215,  173, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  307,  216,  177, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  307,  224,  175, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  307,  497,  178, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  307,  498,  179, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  307,  499,  180, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  307,  500,  181, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  307,  501,  182, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  590,  183, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  591,  184, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  592,  185, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  323,  593,  186, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  323,  286,  187, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  594,  188, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  595,  179, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  596,  189, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  323,  321,  190, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  323,  322,  191, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  323,  597,  192, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  323,  598,  193, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  323,  599,  194, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  323,  600,  195, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  323,  601,  196, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  324,  602,  197, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  324,  603,  198, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  324,  604,  199, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  324,  605,  200, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  324,  606,  201, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    0,  324,  607,  192, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    1,  324,  608,  202, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,   39,  324,  609,  194, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    6,  324,  327,  203, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n    {   3,    7,  324,  328,  204, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 4xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_R_X_8xaa_RBPLUS_PATINFO[] =\n{\n    {   3,    0,  407,  610,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  408,  611,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  409,  612,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  410,  613,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  411,  614,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  404,  615,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  276,  616,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  315,  617,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  278,  618,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  412,  565,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  280,  619,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  281,  620,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  282,  621,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  283,  622,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  413,  623,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  394,  624,  205, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  395,  625,  206, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  396,  626,  207, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  397,  627,  208, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  414,  628,  209, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  415,  629,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  291,  630,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  292,  631,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  416,  632,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  417,  580,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  295,  624,  205, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  296,  633,  206, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  297,  634,  207, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  298,  627,  208, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  418,  635,  210, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  399,  636,  211, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  399,  637,  212, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  399,  638,  213, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  399,  639,  214, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  419,  640,  215, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  301,  641,  216, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  302,  642,  216, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  303,  643,  216, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  420,  589,  105, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  421,  544,  217, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  339,  636,  211, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  339,  637,  212, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  339,  638,  213, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  339,  639,  214, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  422,  224,  175, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  339,  545,  218, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  339,  498,  219, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  339,  546,  220, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  339,  500,  221, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  339,  644,  222, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  645,  223, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  343,  646,  224, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  343,  647,  225, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  341,  648,  226, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  423,  286,  187, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  649,  218, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  343,  650,  227, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  343,  651,  220, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  343,  652,  221, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  341,  653,  228, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  343,  654,  229, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  343,  655,  230, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  343,  656,  231, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  343,  657,  232, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  343,  658,  233, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  346,  659,  234, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  346,  660,  235, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  346,  661,  236, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  344,  662,  237, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  345,  663,  238, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    0,  346,  664,  229, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    1,  346,  665,  230, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,   39,  346,  666,  231, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    6,  346,  667,  232, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n    {   3,    7,  344,  668,  204, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_R_X 8xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_Z_X_1xaa_RBPLUS_PATINFO[] =\n{\n    {   2,    8,  270,  183,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   2,    9,  271,  184,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   2,   10,  272,  185,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   2,   11,  273,  186,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   2,    7,  274,  187,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  275,  188,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  276,  189,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  277,  190,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  278,  191,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  279,  192,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  280,  193,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  281,  194,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  283,  196,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  284,  197,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  285,  198,    1, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  286,  199,    2, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  287,  200,    3, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  288,  201,    4, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  289,  202,    5, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  290,  203,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  291,  204,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  292,  205,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  293,  206,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  294,  207,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  295,  208,    6, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  296,  209,    2, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  297,  210,    7, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  298,  211,    4, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  299,  212,    8, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  300,  213,    9, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  300,  214,   10, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  300,  215,   11, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  300,  216,   12, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  300,  217,   13, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  301,  218,   14, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  302,  219,   14, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  303,  220,   14, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  304,  221,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  305,  222,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  306,  213,    9, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  306,  223,   16, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  306,  215,   11, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  307,  216,   17, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  307,  224,   13, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  306,  225,   18, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  306,  226,   19, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  306,  227,   20, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  307,  228,   21, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  307,  229,   22, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  230,   23, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  231,   24, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  232,   25, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  233,   26, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  309,  234,   27, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  235,   28, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  236,   19, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  237,   29, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  238,   30, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  309,  239,   31, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  308,  240,   32, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  308,  241,   33, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  308,  242,   34, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  309,  243,   35, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  309,  244,   36, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  310,  245,   37, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  310,  246,   38, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  310,  247,   39, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  311,  248,   40, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  311,  249,   41, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    8,  310,  250,   32, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    9,  310,  251,   42, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   10,  310,  252,   34, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,   11,  311,  253,   43, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n    {   3,    7,  311,  254,   44, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 1xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_Z_X_2xaa_RBPLUS_PATINFO[] =\n{\n    {   2,   13,  312,  255,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   2,   14,  272,  185,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  313,  256,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  273,  257,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  314,  258,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  276,  189,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  277,  190,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  315,  259,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  278,  260,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  316,  261,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  281,  262,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  282,  263,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  317,  264,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  284,  265,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  286,  209,    2, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  287,  266,    3, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  287,  210,   45, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  288,  211,   46, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  289,  267,   47, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  291,  268,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  292,  205,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  292,  269,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  293,  270,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  294,  271,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  296,  209,    2, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  297,  210,    7, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  297,  210,   45, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  298,  211,   46, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  299,  212,   47, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  300,  272,   48, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  300,  273,   11, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  300,  273,   49, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  300,  274,   50, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  300,  275,   51, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  302,  219,   14, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  303,  220,   14, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  303,  276,   14, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  304,  277,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  305,  278,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  306,  279,   48, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  306,  215,   11, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  306,  280,   49, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  307,  281,   52, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  307,  224,   53, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  306,  236,   19, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  306,  237,   54, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  306,  237,   55, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  307,  282,   56, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  307,  283,   57, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  284,   24, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  232,   25, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  285,   58, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  309,  233,   59, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  309,  286,   60, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  236,   19, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  237,   29, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  237,   55, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  309,  238,   56, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  309,  239,   61, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  308,  241,   62, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  308,  242,   34, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  308,  242,   63, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  309,  243,   64, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  309,  244,   65, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  310,  246,   38, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  310,  247,   39, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  310,  247,   66, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  318,  287,   67, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  318,  288,   68, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   13,  310,  251,   62, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   14,  310,  252,   34, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   15,  310,  252,   63, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   16,  318,  289,   69, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n    {   3,   17,  318,  290,   65, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 2xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_Z_X_4xaa_RBPLUS_PATINFO[] =\n{\n    {   2,   18,  272,  185,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  272,  291,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  272,  292,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  273,  293,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  274,  294,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  277,  190,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  315,  259,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  277,  295,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  319,  296,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  279,  297,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  282,  195,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  282,  298,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  282,  299,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  283,  300,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  284,  301,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  287,  200,    3, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  287,  302,   45, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  287,  303,   70, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  289,  304,   71, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  289,  305,   72, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  292,  205,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  292,  306,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  292,  307,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  320,  308,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  321,  309,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  297,  210,    7, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  297,  210,   45, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  297,  310,   45, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  298,  311,   71, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  299,  312,   47, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  300,  215,   11, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  300,  215,   73, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  300,  215,   74, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  300,  216,   75, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  300,  217,   76, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  303,  220,   14, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  303,  276,   14, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  303,  313,   14, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  305,  314,   15, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  322,  315,   15, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  306,  215,   11, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  306,  232,   77, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  306,  215,   78, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  307,  216,   79, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  307,  224,   80, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  306,  227,   20, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  306,  316,   55, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  306,  227,   81, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  307,  317,   82, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  307,  229,   83, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  232,   25, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  232,   84, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  318,   84, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  323,  319,   85, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  323,  320,   86, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  237,   29, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  237,   55, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  237,   87, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  323,  321,   88, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  323,  322,   89, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  308,  242,   34, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  308,  242,   90, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  308,  242,   91, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  323,  323,   92, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  323,  324,   93, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  310,  247,   39, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  310,  247,   66, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  310,  247,   94, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  324,  325,   95, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  324,  326,   96, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   18,  310,  252,   34, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   19,  310,  252,   97, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   20,  310,  252,   98, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   21,  324,  327,   99, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n    {   3,   22,  324,  328,  100, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 4xaa @ RbPlus\n};\n\nconst ADDR_SW_PATINFO GFX10_SW_VAR_Z_X_8xaa_RBPLUS_PATINFO[] =\n{\n    {   3,   23,  313,  256,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  272,  292,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  325,  292,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  326,  329,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  327,  294,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  315,  259,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  277,  295,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  315,  330,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  278,  331,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  328,  331,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  282,  263,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  282,  299,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  282,  332,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  317,  333,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  329,  334,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  287,  210,   45, } , // 8 pipes (2 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  287,  335,   70, } , // 8 pipes (2 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  287,  336,   70, } , // 8 pipes (2 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  330,  337,   72, } , // 8 pipes (2 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  331,  338,  101, } , // 8 pipes (2 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  292,  269,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  292,  307,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  292,  339,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  332,  340,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  333,  341,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  297,  210,   45, } , // 8 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  297,  310,   45, } , // 8 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  297,  342,   45, } , // 8 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  299,  343,  102, } , // 8 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  334,  344,  103, } , // 8 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  300,  273,   49, } , // 16 pipes (4 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  300,  273,   74, } , // 16 pipes (4 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  300,  345,   74, } , // 16 pipes (4 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  335,  346,   76, } , // 16 pipes (4 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  336,  286,  104, } , // 16 pipes (4 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  303,  276,   14, } , // 8 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  303,  313,   14, } , // 8 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  303,  347,   14, } , // 8 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  337,  348,  105, } , // 8 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  338,  349,  106, } , // 8 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  306,  280,   49, } , // 16 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  306,  215,   78, } , // 16 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  306,  350,   74, } , // 16 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  339,  351,  107, } , // 16 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  340,  351,  108, } , // 16 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  306,  237,   55, } , // 32 pipes (8 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  306,  237,  109, } , // 32 pipes (8 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  306,  237,  110, } , // 32 pipes (8 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  339,  352,  111, } , // 32 pipes (8 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  339,  353,  112, } , // 32 pipes (8 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  285,   58, } , // 16 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  318,   84, } , // 16 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  308,  354,   84, } , // 16 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  341,  355,  113, } , // 16 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  342,  356,  114, } , // 16 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  237,   55, } , // 32 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  237,   87, } , // 32 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  308,  237,  115, } , // 32 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  343,  357,  116, } , // 32 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  341,  358,  117, } , // 32 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  308,  242,   63, } , // 64 pipes (16 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  308,  242,   91, } , // 64 pipes (16 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  308,  242,  118, } , // 64 pipes (16 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  343,  359,  119, } , // 64 pipes (16 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  343,  360,  120, } , // 64 pipes (16 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  310,  247,   66, } , // 32 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  310,  247,   94, } , // 32 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  310,  361,   94, } , // 32 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  344,  362,  121, } , // 32 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  345,  363,  122, } , // 32 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   23,  310,  252,   63, } , // 64 pipes (32 PKRs) 1 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   24,  310,  252,   98, } , // 64 pipes (32 PKRs) 2 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   25,  310,  252,  118, } , // 64 pipes (32 PKRs) 4 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   26,  346,  364,  123, } , // 64 pipes (32 PKRs) 8 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n    {   3,   27,  344,  365,  124, } , // 64 pipes (32 PKRs) 16 bpe @ SW_VAR_Z_X 8xaa @ RbPlus\n};\n\nconst UINT_64 GFX10_SW_PATTERN_NIBBLE01[][8] =\n{\n    {X0,            X1,            X2,            X3,            Y0,            Y1,            Y2,            Y3,            }, // 0\n    {0,             X0,            X1,            X2,            Y0,            Y1,            Y2,            X3,            }, // 1\n    {0,             0,             X0,            X1,            Y0,            Y1,            Y2,            X2,            }, // 2\n    {0,             0,             0,             X0,            Y0,            Y1,            X1,            X2,            }, // 3\n    {0,             0,             0,             0,             Y0,            Y1,            X0,            X1,            }, // 4\n    {X0,            X1,            X2,            Y1,            Y0,            Y2,            X3,            Y3,            }, // 5\n    {0,             0,             0,             X0,            Y0,            X1,            X2,            Y1,            }, // 6\n    {0,             0,             0,             0,             X0,            Y0,            X1,            Y1,            }, // 7\n    {X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            Y3,            }, // 8\n    {0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 9\n    {0,             0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 10\n    {0,             0,             0,             X0,            Y0,            X1,            Y1,            X2,            }, // 11\n    {X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            Y4,            }, // 12\n    {S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 13\n    {0,             S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 14\n    {0,             0,             S0,            X0,            Y0,            X1,            Y1,            X2,            }, // 15\n    {0,             0,             0,             S0,            X0,            Y0,            X1,            Y1,            }, // 16\n    {0,             0,             0,             0,             S0,            X0,            Y0,            X1,            }, // 17\n    {S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 18\n    {0,             S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            }, // 19\n    {0,             0,             S0,            S1,            X0,            Y0,            X1,            Y1,            }, // 20\n    {0,             0,             0,             S0,            S1,            X0,            Y0,            X1,            }, // 21\n    {0,             0,             0,             0,             S0,            S1,            X0,            Y0,            }, // 22\n    {S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            X2,            }, // 23\n    {0,             S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            }, // 24\n    {0,             0,             S0,            S1,            S2,            X0,            Y0,            X1,            }, // 25\n    {0,             0,             0,             S0,            S1,            S2,            X0,            Y0,            }, // 26\n    {0,             0,             0,             0,             S0,            S1,            S2,            X0,            }, // 27\n    {X0,            X1,            X2,            Y1,            Y0,            Y2,            X3,            Y4,            }, // 28\n    {X0,            X1,            Z0,            Y0,            Z1,            Y1,            X2,            Z2,            }, // 29\n    {0,             X0,            Z0,            Y0,            Z1,            Y1,            X1,            Z2,            }, // 30\n    {0,             0,             X0,            Y0,            Z0,            Y1,            X1,            Z1,            }, // 31\n    {0,             0,             0,             X0,            Z0,            Y0,            X1,            Z1,            }, // 32\n    {0,             0,             0,             0,             Z0,            Y0,            X0,            Z1,            }, // 33\n    {X0,            X1,            Z0,            Y0,            Y1,            Z1,            X2,            Z2,            }, // 34\n    {0,             X0,            Z0,            Y0,            X1,            Z1,            Y1,            Z2,            }, // 35\n    {0,             0,             X0,            Y0,            X1,            Z0,            Y1,            Z1,            }, // 36\n    {0,             0,             0,             X0,            Y0,            Z0,            X1,            Z1,            }, // 37\n    {0,             0,             0,             0,             X0,            Z0,            Y0,            Z1,            }, // 38\n    {0,             0,             X0,            X1,            Y0,            Y1,            X2,            Y2,            }, // 39\n};\n\nconst UINT_64 GFX10_SW_PATTERN_NIBBLE2[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y4,            X4,            Y5,            X5,            }, // 1\n    {Y3,            X4,            Y4,            X5,            }, // 2\n    {Y3,            X3,            Y4,            X4,            }, // 3\n    {Y2,            X3,            Y3,            X4,            }, // 4\n    {Y2,            X2,            Y3,            X3,            }, // 5\n    {Z0^X4^Y4,      X4,            Y5,            X5,            }, // 6\n    {Z0^Y3^X4,      X4,            Y4,            X5,            }, // 7\n    {Z0^X3^Y3,      X3,            Y4,            X4,            }, // 8\n    {Z0^Y2^X3,      X3,            Y3,            X4,            }, // 9\n    {Z0^X2^Y2,      X2,            Y3,            X3,            }, // 10\n    {Z1^Y4^X5,      Z0^X4^Y5,      Y5,            X5,            }, // 11\n    {Z1^Y3^X5,      Z0^X4^Y4,      Y4,            X5,            }, // 12\n    {Z1^Y3^X4,      Z0^X3^Y4,      Y4,            X4,            }, // 13\n    {Z1^Y2^X4,      Z0^X3^Y3,      Y3,            X4,            }, // 14\n    {Z1^Y2^X3,      Z0^X2^Y3,      Y3,            X3,            }, // 15\n    {Z2^Y4^X6,      Z1^X4^Y6,      Z0^X5^Y5,      X5,            }, // 16\n    {Z2^Y3^X6,      Z1^X4^Y5,      Z0^Y4^X5,      X5,            }, // 17\n    {Z2^Y3^X5,      Z1^X3^Y5,      Z0^X4^Y4,      X4,            }, // 18\n    {Y2^Z2^X5,      Z1^X3^Y4,      Z0^Y3^X4,      X4,            }, // 19\n    {Y2^Z2^X4,      Z1^X2^Y4,      Z0^X3^Y3,      X3,            }, // 20\n    {Z3^Y4^X7,      Z2^X4^Y7,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 21\n    {Y3^Z3^X7,      Z2^X4^Y6,      Z1^Y4^X6,      Z0^X5^Y5,      }, // 22\n    {Y3^Z3^X6,      Z2^X3^Y6,      Z1^Y4^X5,      Z0^X4^Y5,      }, // 23\n    {Y2^Z3^X6,      Z2^X3^Y5,      Z1^Y3^X5,      Z0^X4^Y4,      }, // 24\n    {Y2^Z3^X5,      X2^Z2^Y5,      Z1^Y3^X4,      Z0^X3^Y4,      }, // 25\n    {Y4^Z4^X8,      Z3^X4^Y8,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 26\n    {Y3^Z4^X8,      Z3^X4^Y7,      Z2^Y4^X7,      Z1^X5^Y6,      }, // 27\n    {Y3^Z4^X7,      X3^Z3^Y7,      Z2^Y4^X6,      Z1^X4^Y6,      }, // 28\n    {Y2^Z4^X7,      X3^Z3^Y6,      Z2^Y3^X6,      Z1^X4^Y5,      }, // 29\n    {Y2^Z4^X6,      X2^Z3^Y6,      Z2^Y3^X5,      Z1^X3^Y5,      }, // 30\n    {Y4^Z5^X9,      X4^Z4^Y9,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 31\n    {Y3^Z5^X9,      X4^Z4^Y8,      Z3^Y4^X8,      Z2^X5^Y7,      }, // 32\n    {Y3^Z5^X8,      X3^Z4^Y8,      Z3^Y4^X7,      Z2^X4^Y7,      }, // 33\n    {Y2^Z5^X8,      X3^Z4^Y7,      Y3^Z3^X7,      Z2^X4^Y6,      }, // 34\n    {Y2^Z5^X7,      X2^Z4^Y7,      Y3^Z3^X6,      Z2^X3^Y6,      }, // 35\n    {X4^Y4,         X4,            Y5,            X5,            }, // 36\n    {Y3^X4,         X4,            Y4,            X5,            }, // 37\n    {X3^Y3,         X3,            Y4,            X4,            }, // 38\n    {Y2^X3,         X3,            Y3,            X4,            }, // 39\n    {X2^Y2,         X2,            Y3,            X3,            }, // 40\n    {Y4^X5,         X4^Y5,         Y5,            X5,            }, // 41\n    {Y3^X5,         X4^Y4,         Y4,            X5,            }, // 42\n    {Y3^X4,         X3^Y4,         Y4,            X4,            }, // 43\n    {Y2^X4,         X3^Y3,         Y3,            X4,            }, // 44\n    {Y2^X3,         X2^Y3,         Y3,            X3,            }, // 45\n    {Y4^X6,         X4^Y6,         X5^Y5,         X5,            }, // 46\n    {Y3^X6,         X4^Y5,         Y4^X5,         X5,            }, // 47\n    {Y3^X5,         X3^Y5,         X4^Y4,         X4,            }, // 48\n    {Y2^X5,         X3^Y4,         Y3^X4,         X4,            }, // 49\n    {Y2^X4,         X2^Y4,         X3^Y3,         X3,            }, // 50\n    {Y4^X7,         X4^Y7,         Y5^X6,         X5^Y6,         }, // 51\n    {Y3^X7,         X4^Y6,         Y4^X6,         X5^Y5,         }, // 52\n    {Y3^X6,         X3^Y6,         Y4^X5,         X4^Y5,         }, // 53\n    {Y2^X6,         X3^Y5,         Y3^X5,         X4^Y4,         }, // 54\n    {Y2^X5,         X2^Y5,         Y3^X4,         X3^Y4,         }, // 55\n    {Y4,            X4,            Y5^X7,         X5^Y7,         }, // 56\n    {Y3,            X4,            Y4^X7,         X5^Y6,         }, // 57\n    {Y3,            X3,            Y4^X6,         X4^Y6,         }, // 58\n    {Y2,            X3,            Y3^X6,         X4^Y5,         }, // 59\n    {Y2,            X2,            Y3^X5,         X3^Y5,         }, // 60\n    {Z0^X3^Y3,      X4,            Y5,            X5,            }, // 61\n    {Z0^X3^Y3,      X4,            Y4,            X5,            }, // 62\n    {Z0^X3^Y3,      X3,            Y2,            X4,            }, // 63\n    {Z0^X3^Y3,      X2,            Y2,            X3,            }, // 64\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y5,            X5,            }, // 65\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y4,            X5,            }, // 66\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y3,            X4,            }, // 67\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2,            X3,            }, // 68\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2,            X2,            }, // 69\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X5,            }, // 70\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X4,            }, // 71\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X3,            }, // 72\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X2,            }, // 73\n    {X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 74\n    {X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 75\n    {X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      }, // 76\n    {X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 77\n    {X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      }, // 78\n    {X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      }, // 79\n    {Y3,            Y4,            X4,            Y5,            }, // 80\n    {X2,            Y3,            X3,            Y4,            }, // 81\n    {Z0^X3^Y3,      Y4,            X4,            Y5,            }, // 82\n    {Z0^X3^Y3,      X2,            X3,            Y4,            }, // 83\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y4,            Y5,            }, // 84\n    {Z1^X3^Y3,      Z0^X4^Y4,      X2,            Y3,            }, // 85\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y4,            }, // 86\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X6,      Y2^X5^Y6,      }, // 87\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      Y2^X5^Y7,      }, // 88\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      Y2^X5^Y8,      }, // 89\n    {X3,            Y3,            X4,            Y4,            }, // 90\n    {Z0^X3^Y3,      X3,            X4,            Y4,            }, // 91\n    {Z1^X3^Y3,      Z0^X4^Y4,      X3,            Y4,            }, // 92\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y2,            }, // 93\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2^X5^Y5,      X2,            }, // 94\n    {Z2^X3^Y3,      Z1^X4^Y4,      Y2^Y5^X6,      Z0^X5^Y6,      }, // 95\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2^Y5^X6,      X1^X5^Y6,      }, // 96\n    {Z2^X3^Y3,      Z1^X4^Y4,      Y2^Y5^X7,      Z0^X5^Y7,      }, // 97\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2^Y5^X7,      X1^X5^Y7,      }, // 98\n    {Z2^X3^Y3,      Z1^X4^Y4,      Y2^Y5^X8,      Z0^X5^Y8,      }, // 99\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2^Y5^X8,      X1^X5^Y8,      }, // 100\n    {Z0^X3^Y3,      Y2,            X3,            Y4,            }, // 101\n    {Z1^X3^Y3,      Z0^X4^Y4,      X2,            Y2,            }, // 102\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y2^X5^Y5,      Y3,            }, // 103\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y0^X5^Y5,      Y2,            }, // 104\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X6,      Z3^X5^Y6,      }, // 105\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y0^Y5^X6,      X1^X5^Y6,      }, // 106\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      Z4^X5^Y7,      }, // 107\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      Z3^X5^Y7,      }, // 108\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y0^Y5^X7,      X1^X5^Y7,      }, // 109\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      Z4^X5^Y8,      }, // 110\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      Z3^X5^Y8,      }, // 111\n    {Z1^X3^Y3,      Z0^X4^Y4,      Y0^Y5^X8,      X1^X5^Y8,      }, // 112\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X6,      S0^X5^Y6,      }, // 113\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      S0^X5^Y7,      }, // 114\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      S0^X5^Y8,      }, // 115\n    {Z1^X3^Y3,      Z0^X4^Y4,      S1^X5^Y5,      X2,            }, // 116\n    {Z2^X3^Y3,      Z1^X4^Y4,      S1^Y5^X6,      Z0^X5^Y6,      }, // 117\n    {Z1^X3^Y3,      Z0^X4^Y4,      S1^Y5^X6,      S0^X5^Y6,      }, // 118\n    {Z2^X3^Y3,      Z1^X4^Y4,      S1^Y5^X7,      Z0^X5^Y7,      }, // 119\n    {Z1^X3^Y3,      Z0^X4^Y4,      S1^Y5^X7,      S0^X5^Y7,      }, // 120\n    {Z2^X3^Y3,      Z1^X4^Y4,      S1^Y5^X8,      Z0^X5^Y8,      }, // 121\n    {Z1^X3^Y3,      Z0^X4^Y4,      S1^Y5^X8,      S0^X5^Y8,      }, // 122\n    {Z1^X3^Y3,      Z0^X4^Y4,      S2^X5^Y5,      Y2,            }, // 123\n    {Z1^X3^Y3,      Z0^X4^Y4,      S2^X5^Y5,      X2,            }, // 124\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X6,      S2^X5^Y6,      }, // 125\n    {Z1^X3^Y3,      Z0^X4^Y4,      S2^Y5^X6,      S1^X5^Y6,      }, // 126\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      S2^X5^Y7,      }, // 127\n    {Z1^X3^Y3,      Z0^X4^Y4,      S2^Y5^X7,      S1^X5^Y7,      }, // 128\n    {Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      S2^X5^Y8,      }, // 129\n    {Z1^X3^Y3,      Z0^X4^Y4,      S2^Y5^X8,      S1^X5^Y8,      }, // 130\n    {Y2,            X3,            Z3,            Y3,            }, // 131\n    {Y2,            X2,            Z3,            Y3,            }, // 132\n    {Y2,            X2,            Z2,            Y3,            }, // 133\n    {Y1,            X2,            Z2,            Y2,            }, // 134\n    {Y1,            X1,            Z2,            Y2,            }, // 135\n    {Y2^X3^Z3,      X3,            Z3,            Y3,            }, // 136\n    {X2^Y2^Z3,      X2,            Z3,            Y3,            }, // 137\n    {X2^Y2^Z2,      X2,            Z2,            Y3,            }, // 138\n    {Y1^X2^Z2,      X2,            Z2,            Y2,            }, // 139\n    {X1^Y1^Z2,      X1,            Z2,            Y2,            }, // 140\n    {Y2^X4^Z4,      X3^Y3^Z3,      Z3,            Y3,            }, // 141\n    {Y2^X3^Z4,      X2^Y3^Z3,      Z3,            Y3,            }, // 142\n    {Y2^X3^Z3,      X2^Z2^Y3,      Z2,            Y3,            }, // 143\n    {Y1^X3^Z3,      X2^Y2^Z2,      Z2,            Y2,            }, // 144\n    {Y1^X2^Z3,      X1^Y2^Z2,      Z2,            Y2,            }, // 145\n    {Y2^X5^Z5,      X3^Y4^Z4,      Y3^Z3^X4,      Y3,            }, // 146\n    {Y2^X4^Z5,      X2^Y4^Z4,      X3^Y3^Z3,      Y3,            }, // 147\n    {Y2^X4^Z4,      X2^Z3^Y4,      Z2^X3^Y3,      Y3,            }, // 148\n    {Y1^X4^Z4,      X2^Y3^Z3,      Y2^Z2^X3,      Y2,            }, // 149\n    {Y1^X3^Z4,      X1^Y3^Z3,      X2^Y2^Z2,      Y2,            }, // 150\n    {Y2^X6^Z6,      X3^Y5^Z5,      Z3^Y4^X5,      Y3^X4^Z4,      }, // 151\n    {Y2^X5^Z6,      X2^Y5^Z5,      Z3^X4^Y4,      X3^Y3^Z4,      }, // 152\n    {Y2^X5^Z5,      X2^Z4^Y5,      Z2^X4^Y4,      X3^Y3^Z3,      }, // 153\n    {Y1^X5^Z5,      X2^Y4^Z4,      Z2^Y3^X4,      Y2^X3^Z3,      }, // 154\n    {Y1^X4^Z5,      X1^Y4^Z4,      Z2^X3^Y3,      X2^Y2^Z3,      }, // 155\n    {Y2^X7^Z7,      X3^Y6^Z6,      Z3^Y5^X6,      Y3^X5^Z5,      }, // 156\n    {Y2^X6^Z7,      X2^Y6^Z6,      Z3^X5^Y5,      Y3^X4^Z5,      }, // 157\n    {Y2^X6^Z6,      X2^Z5^Y6,      Z2^X5^Y5,      Y3^X4^Z4,      }, // 158\n    {Y1^X6^Z6,      X2^Y5^Z5,      Z2^Y4^X5,      Y2^X4^Z4,      }, // 159\n    {Y1^X5^Z6,      X1^Y5^Z5,      Z2^X4^Y4,      Y2^X3^Z4,      }, // 160\n    {Y2^X8^Z8,      X3^Y7^Z7,      Z3^Y6^X7,      Y3^X6^Z6,      }, // 161\n    {Y2^X7^Z8,      X2^Y7^Z7,      Z3^X6^Y6,      Y3^X5^Z6,      }, // 162\n    {Y2^X7^Z7,      X2^Z6^Y7,      Z2^X6^Y6,      Y3^X5^Z5,      }, // 163\n    {Y1^X7^Z7,      X2^Y6^Z6,      Z2^Y5^X6,      Y2^X5^Z5,      }, // 164\n    {Y1^X6^Z7,      X1^Y6^Z6,      Z2^X5^Y5,      Y2^X4^Z5,      }, // 165\n    {Y2^X5,         X3^Y4^Z4,      Y3^Z3^X4,      Y3,            }, // 166\n    {Y2^X4,         X2^Y4^Z4,      X3^Y3^Z3,      Y3,            }, // 167\n    {Y2^X4,         X2^Z3^Y4,      Z2^X3^Y3,      Y3,            }, // 168\n    {Y1^X4,         X2^Y3^Z3,      Y2^Z2^X3,      Y2,            }, // 169\n    {Y1^X3,         X1^Y3^Z3,      X2^Y2^Z2,      Y2,            }, // 170\n    {Y2,            X3,            Z3^Y4^X5,      Y3^X4^Z4,      }, // 171\n    {Y2,            X2,            Z3^X4^Y4,      X3^Y3^Z4,      }, // 172\n    {Y2,            X2,            Z2^X4^Y4,      X3^Y3^Z3,      }, // 173\n    {Y1,            X2,            Z2^Y3^X4,      Y2^X3^Z3,      }, // 174\n    {Y1,            X1,            Z2^X3^Y3,      X2^Y2^Z3,      }, // 175\n    {Y2,            X3,            Z3,            Y3^X5,         }, // 176\n    {Y2,            X2,            Z3,            Y3^X4,         }, // 177\n    {Y2,            X2,            Z2,            Y3^X4,         }, // 178\n    {Y1,            X2,            Z2,            Y2^X4,         }, // 179\n    {Y1,            X1,            Z2,            Y2^X3,         }, // 180\n    {X3^Y3,         X3,            Z3,            Y2,            }, // 181\n    {X3^Y3,         X2,            Z3,            Y2,            }, // 182\n    {X3^Y3,         X2,            Z2,            Y2,            }, // 183\n    {X3^Y3,         X2,            Z2,            Y1,            }, // 184\n    {X3^Y3,         X1,            Z2,            Y1,            }, // 185\n    {X3^Y3,         X4^Y4,         Z3,            Y2,            }, // 186\n    {X3^Y3,         X4^Y4,         Z2,            Y2,            }, // 187\n    {X3^Y3,         X4^Y4,         Z2,            Y1,            }, // 188\n    {X3^Y3,         X1^X4^Y4,      Z2,            Y1,            }, // 189\n    {X3^Y3,         X4^Y4,         X5^Y5,         Z3,            }, // 190\n    {X3^Y3,         X4^Y4,         Z3^X5^Y5,      Y2,            }, // 191\n    {X3^Y3,         X4^Y4,         Z2^X5^Y5,      Y2,            }, // 192\n    {X3^Y3,         X4^Y4,         Z2^X5^Y5,      Y1,            }, // 193\n    {X3^Y3,         X1^X4^Y4,      Z2^X5^Y5,      Y1,            }, // 194\n    {X3^Y3,         X4^Y4,         Y2^Y5^X6,      X5^Y6,         }, // 195\n    {X3^Y3,         X4^Y4,         Z3^Y5^X6,      Y2^X5^Y6,      }, // 196\n    {X3^Y3,         X4^Y4,         Z2^Y5^X6,      Y2^X5^Y6,      }, // 197\n    {X3^Y3,         X4^Y4,         Z2^Y5^X6,      Y1^X5^Y6,      }, // 198\n    {X3^Y3,         X1^X4^Y4,      Z2^Y5^X6,      Y1^X5^Y6,      }, // 199\n    {X3^Y3,         X4^Y4,         Y2^Y5^X7,      X5^Y7,         }, // 200\n    {X3^Y3,         X4^Y4,         Z3^Y5^X7,      Y2^X5^Y7,      }, // 201\n    {X3^Y3,         X4^Y4,         Z2^Y5^X7,      Y2^X5^Y7,      }, // 202\n    {X3^Y3,         X4^Y4,         Z2^Y5^X7,      Y1^X5^Y7,      }, // 203\n    {X3^Y3,         X1^X4^Y4,      Z2^Y5^X7,      Y1^X5^Y7,      }, // 204\n    {X3^Y3,         X4^Y4,         Y2^Y5^X8,      X5^Y8,         }, // 205\n    {X3^Y3,         X4^Y4,         Z3^Y5^X8,      Y2^X5^Y8,      }, // 206\n    {X3^Y3,         X4^Y4,         Z2^Y5^X8,      Y2^X5^Y8,      }, // 207\n    {X3^Y3,         X4^Y4,         Z2^Y5^X8,      Y1^X5^Y8,      }, // 208\n    {X3^Y3,         X1^X4^Y4,      Z2^Y5^X8,      Y1^X5^Y8,      }, // 209\n    {Y4^X5,         Z0^X4^Y5,      Y5,            X5,            }, // 210\n    {Y3^X5,         Z0^X4^Y4,      Y4,            X5,            }, // 211\n    {Y3^X4,         Z0^X3^Y4,      Y4,            X4,            }, // 212\n    {Y2^X4,         Z0^X3^Y3,      Y3,            X4,            }, // 213\n    {Y2^X3,         Z0^X2^Y3,      Y3,            X3,            }, // 214\n    {Y4^X6,         X4^Y6,         Z0^X5^Y5,      X5,            }, // 215\n    {Y3^X6,         X4^Y5,         Z0^Y4^X5,      X5,            }, // 216\n    {Y3^X5,         X3^Y5,         Z0^X4^Y4,      X4,            }, // 217\n    {Y2^X5,         X3^Y4,         Z0^Y3^X4,      X4,            }, // 218\n    {Y2^X4,         X2^Y4,         Z0^X3^Y3,      X3,            }, // 219\n    {Y4^X6,         Z1^X4^Y6,      Z0^X5^Y5,      X5,            }, // 220\n    {Y3^X6,         Z1^X4^Y5,      Z0^Y4^X5,      X5,            }, // 221\n    {Y3^X5,         Z1^X3^Y5,      Z0^X4^Y4,      X4,            }, // 222\n    {Y2^X5,         Z1^X3^Y4,      Z0^Y3^X4,      X4,            }, // 223\n    {Y2^X4,         Z1^X2^Y4,      Z0^X3^Y3,      X3,            }, // 224\n    {Y4^X7,         X4^Y7,         Z1^Y5^X6,      Z0^X5^Y6,      }, // 225\n    {Y3^X7,         X4^Y6,         Z1^Y4^X6,      Z0^X5^Y5,      }, // 226\n    {Y3^X6,         X3^Y6,         Z1^Y4^X5,      Z0^X4^Y5,      }, // 227\n    {Y2^X6,         X3^Y5,         Z1^Y3^X5,      Z0^X4^Y4,      }, // 228\n    {Y2^X5,         X2^Y5,         Z1^Y3^X4,      Z0^X3^Y4,      }, // 229\n    {Y4^X7,         Z2^X4^Y7,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 230\n    {Y3^X7,         Z2^X4^Y6,      Z1^Y4^X6,      Z0^X5^Y5,      }, // 231\n    {Y3^X6,         Z2^X3^Y6,      Z1^Y4^X5,      Z0^X4^Y5,      }, // 232\n    {Y2^X6,         Z2^X3^Y5,      Z1^Y3^X5,      Z0^X4^Y4,      }, // 233\n    {Y2^X5,         X2^Z2^Y5,      Z1^Y3^X4,      Z0^X3^Y4,      }, // 234\n    {Y4^X7,         X4^Y7,         Z2^Y5^X6,      Z1^X5^Y6,      }, // 235\n    {Y3^X7,         X4^Y6,         Z2^Y4^X6,      Z1^X5^Y5,      }, // 236\n    {Y3^X6,         X3^Y6,         Z2^Y4^X5,      Z1^X4^Y5,      }, // 237\n    {Y2^X6,         X3^Y5,         Z2^Y3^X5,      Z1^X4^Y4,      }, // 238\n    {Y2^X5,         X2^Y5,         Z2^Y3^X4,      Z1^X3^Y4,      }, // 239\n    {Y4^X7,         Z3^X4^Y7,      Z2^Y5^X6,      Z1^X5^Y6,      }, // 240\n    {Y3^X7,         Z3^X4^Y6,      Z2^Y4^X6,      Z1^X5^Y5,      }, // 241\n    {Y3^X6,         X3^Z3^Y6,      Z2^Y4^X5,      Z1^X4^Y5,      }, // 242\n    {Y2^X6,         X3^Z3^Y5,      Z2^Y3^X5,      Z1^X4^Y4,      }, // 243\n    {Y2^X5,         X2^Z3^Y5,      Z2^Y3^X4,      Z1^X3^Y4,      }, // 244\n    {Y4^X7,         X4^Y7,         Z3^Y5^X6,      Z2^X5^Y6,      }, // 245\n    {Y3^X7,         X4^Y6,         Z3^Y4^X6,      Z2^X5^Y5,      }, // 246\n    {Y3^X6,         X3^Y6,         Z3^Y4^X5,      Z2^X4^Y5,      }, // 247\n    {Y2^X6,         X3^Y5,         Y3^Z3^X5,      Z2^X4^Y4,      }, // 248\n    {Y2^X5,         X2^Y5,         Y3^Z3^X4,      Z2^X3^Y4,      }, // 249\n    {Y4^X8,         X4^Y8,         Z2^Y5^X7,      Z1^X5^Y7,      }, // 250\n    {Y3^X8,         X4^Y7,         Z2^Y4^X7,      Z1^X5^Y6,      }, // 251\n    {Y3^X7,         X3^Y7,         Z2^Y4^X6,      Z1^X4^Y6,      }, // 252\n    {Y2^X7,         X3^Y6,         Z2^Y3^X6,      Z1^X4^Y5,      }, // 253\n    {Y2^X6,         X2^Y6,         Z2^Y3^X5,      Z1^X3^Y5,      }, // 254\n    {Y4^X8,         Z3^X4^Y8,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 255\n    {Y3^X8,         Z3^X4^Y7,      Z2^Y4^X7,      Z1^X5^Y6,      }, // 256\n    {Y3^X7,         X3^Z3^Y7,      Z2^Y4^X6,      Z1^X4^Y6,      }, // 257\n    {Y2^X7,         X3^Z3^Y6,      Z2^Y3^X6,      Z1^X4^Y5,      }, // 258\n    {Y2^X6,         X2^Z3^Y6,      Z2^Y3^X5,      Z1^X3^Y5,      }, // 259\n    {Y4^X9,         X4^Y9,         Z3^Y5^X8,      Z2^X5^Y8,      }, // 260\n    {Y3^X9,         X4^Y8,         Z3^Y4^X8,      Z2^X5^Y7,      }, // 261\n    {Y3^X8,         X3^Y8,         Z3^Y4^X7,      Z2^X4^Y7,      }, // 262\n    {Y2^X8,         X3^Y7,         Y3^Z3^X7,      Z2^X4^Y6,      }, // 263\n    {Y2^X7,         X2^Y7,         Y3^Z3^X6,      Z2^X3^Y6,      }, // 264\n    {Y4^X9,         X4^Z4^Y9,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 265\n    {Y3^X9,         X4^Z4^Y8,      Z3^Y4^X8,      Z2^X5^Y7,      }, // 266\n    {Y3^X8,         X3^Z4^Y8,      Z3^Y4^X7,      Z2^X4^Y7,      }, // 267\n    {Y2^X8,         X3^Z4^Y7,      Y3^Z3^X7,      Z2^X4^Y6,      }, // 268\n    {Y2^X7,         X2^Z4^Y7,      Y3^Z3^X6,      Z2^X3^Y6,      }, // 269\n    {X4,            Y4,            X5^Y8,         Y5^X8,         }, // 270\n    {Y3,            X4,            Y4^X8,         X5^Y7,         }, // 271\n    {X3,            Y3,            X4^Y7,         Y4^X7,         }, // 272\n    {Y2,            X3,            Y3^X7,         X4^Y6,         }, // 273\n    {X2,            Y2,            X3^Y6,         Y3^X6,         }, // 274\n    {Z0^X4^Y4,      Y4,            X5,            X6^Y8,         }, // 275\n    {Z0^X4^Y4,      Y3,            Y4,            X5^Y8,         }, // 276\n    {Z0^X4^Y4,      X3,            Y3,            X5^Y7,         }, // 277\n    {Z0^X4^Y4,      Y2,            X3,            Y3^X8,         }, // 278\n    {Z0^X4^Y4,      X2,            Y2,            X3^Y6,         }, // 279\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5,            Y5,            }, // 280\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y3,            X5,            }, // 281\n    {Y4^X5^Y5,      Z0^X4^Y4,      X3,            Y3,            }, // 282\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y2,            X3,            }, // 283\n    {Y4^X5^Y5,      Z0^X4^Y4,      X2,            Y2,            }, // 284\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y5,            }, // 285\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y3,            }, // 286\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X3,            }, // 287\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y2,            }, // 288\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X2,            }, // 289\n    {Y4^X6^Y6,      Z1^X4^Y4,      X5,            X6,            }, // 290\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y3,            X5,            }, // 291\n    {Y4^X6^Y6,      Z1^X4^Y4,      X3,            Y3,            }, // 292\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y2,            X3,            }, // 293\n    {Y4^X6^Y6,      Z1^X4^Y4,      X2,            Y2,            }, // 294\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5,            }, // 295\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y3,            }, // 296\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X3,            }, // 297\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y2,            }, // 298\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X2,            }, // 299\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         }, // 300\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X6,            }, // 301\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y3,            }, // 302\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X3,            }, // 303\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Y2,            }, // 304\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X2,            }, // 305\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         }, // 306\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 307\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         }, // 308\n    {Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 309\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         }, // 310\n    {Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 311\n    {Y3,            X4,            Y4^X8,         Y5^X7,         }, // 312\n    {X3,            Y3,            Y4^X7,         X4^Y7,         }, // 313\n    {X2,            Y2,            Y3^X6,         X3^Y6,         }, // 314\n    {Z0^X4^Y4,      X3,            Y3,            Y4^X8,         }, // 315\n    {Z0^X4^Y4,      X2,            Y2,            Y3^X7,         }, // 316\n    {Y4^X5^Y5,      Z0^X4^Y4,      X2,            X3,            }, // 317\n    {Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      }, // 318\n    {Z0^X4^Y4,      X2,            X3,            Y3^X8,         }, // 319\n    {Y4^X6^Y6,      Z1^X4^Y4,      X2,            X3,            }, // 320\n    {Y4^X6^Y6,      Z0^X4^Y4,      X2,            X3,            }, // 321\n    {Y4^X7^Y7,      Z1^X4^Y4,      Y1^Y5^X6,      X2,            }, // 322\n    {Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      }, // 323\n    {Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      }, // 324\n    {X3,            Y3,            Y4^X7,         Y1^X4^Y7,      }, // 325\n    {Y2,            X3,            Y3^X7,         X1^X4^Y6,      }, // 326\n    {X2,            Y2,            Y3^X6,         Y0^X3^Y6,      }, // 327\n    {Y0^X4^Y4,      Y2,            X3,            Y3^X8,         }, // 328\n    {Y4^X5^Y5,      Y0^X4^Y4,      X2,            X3,            }, // 329\n    {Y4^X5^Y5,      Z0^X4^Y4,      X2^X5^Y5,      Y2,            }, // 330\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y1^X5^Y5,      X2,            }, // 331\n    {Y4^X6^Y6,      Z0^X4^Y4,      X3,            Y3,            }, // 332\n    {Y4^X6^Y6,      Y0^X4^Y4,      X3,            Y3,            }, // 333\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y0^X5^Y5,      X2,            }, // 334\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X2^X5^Y5,      }, // 335\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y1^X5^Y5,      }, // 336\n    {Y4^X7^Y7,      Z0^X4^Y4,      Y1^Y5^X6,      X3,            }, // 337\n    {Y4^X7^Y7,      Z0^X4^Y4,      Y0^Y5^X6,      X3,            }, // 338\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Z2^X5^Y6,      }, // 339\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y0^X5^Y6,      }, // 340\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Z2^X5^Y7,      }, // 341\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y0^X5^Y7,      }, // 342\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Z3^X5^Y7,      }, // 343\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Z3^X5^Y8,      }, // 344\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Z2^X5^Y8,      }, // 345\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Z4^X5^Y8,      }, // 346\n    {X4,            Y4,            X5^Y10,        Y5^X10,        }, // 347\n    {Y3,            X4,            Y4^X10,        X5^Y9,         }, // 348\n    {X3,            Y3,            X4^Y9,         Y4^X9,         }, // 349\n    {Y2,            X3,            Y3^X9,         X4^Y8,         }, // 350\n    {X2,            Y2,            X3^Y8,         Y3^X8,         }, // 351\n    {Z0^X4^Y4,      Y4,            X5,            Y5^X10,        }, // 352\n    {Z0^X4^Y4,      Y3,            Y4,            X5^Y9,         }, // 353\n    {Z0^X4^Y4,      X3,            Y3,            Y4^X9,         }, // 354\n    {Z0^X4^Y4,      Y2,            X3,            Y3^X9,         }, // 355\n    {Z0^X4^Y4,      X2,            Y2,            Y3^X8,         }, // 356\n    {Y3,            X4,            Y4^X10,        Y5^X9,         }, // 357\n    {X3,            Y3,            Y4^X9,         X4^Y9,         }, // 358\n    {X2,            Y2,            Y3^X8,         X3^Y8,         }, // 359\n    {Z0^X4^Y4,      Y3,            Y4,            Y5^X9,         }, // 360\n    {Z0^X4^Y4,      X2,            X3,            Y3^X9,         }, // 361\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X2^X5^Y6,      }, // 362\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y1^X5^Y6,      }, // 363\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X2,            }, // 364\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y1^X5^Y6,      }, // 365\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y1^X5^Y7,      }, // 366\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Y1^X5^Y8,      }, // 367\n    {Z0^X4^Y4,      X3,            Y3,            X5^Y8,         }, // 368\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X2,            }, // 369\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X1^X5^Y6,      }, // 370\n    {Y4^X7^Y7,      Z1^X4^Y4,      Y1^Y5^X6,      X3,            }, // 371\n    {Y4^X7^Y7,      Z1^X4^Y4,      Y1^Y5^X6,      Z0^X5^Y6,      }, // 372\n    {Y4^X7^Y7,      Z0^X4^Y4,      Y1^Y5^X6,      X1^X5^Y6,      }, // 373\n    {Y4^X8^Y8,      Z1^X4^Y4,      Y1^Y5^X7,      Z0^X5^Y7,      }, // 374\n    {Y4^X8^Y8,      Z0^X4^Y4,      Y1^Y5^X7,      X1^X5^Y7,      }, // 375\n    {Y4^X9^Y9,      Z1^X4^Y4,      Y1^Y5^X8,      Z0^X5^Y8,      }, // 376\n    {Y4^X9^Y9,      Z0^X4^Y4,      Y1^Y5^X8,      X1^X5^Y8,      }, // 377\n    {Z0^X4^Y4,      X2,            Y2,            X3^Y7,         }, // 378\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y2^X5^Y5,      X2,            }, // 379\n    {Y4^X5^Y5,      Y0^X4^Y4,      X1^X5^Y5,      X2,            }, // 380\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X3,            }, // 381\n    {Y4^X6^Y6,      Y0^X4^Y4,      Y1^X5^Y5,      X3,            }, // 382\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y2^X5^Y6,      }, // 383\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X2^X5^Y6,      }, // 384\n    {Y4^X6^Y6,      Y0^X4^Y4,      Y1^X5^Y5,      Y2^X5^Y6,      }, // 385\n    {Y4^X7^Y7,      Y0^X4^Y4,      Y1^Y5^X6,      X3,            }, // 386\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y2^X5^Y6,      }, // 387\n    {Y4^X7^Y7,      Y0^X4^Y4,      Y1^Y5^X6,      X1^X5^Y6,      }, // 388\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y2^X5^Y7,      }, // 389\n    {Y4^X8^Y8,      Y0^X4^Y4,      Y1^Y5^X7,      X1^X5^Y7,      }, // 390\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X2^X5^Y7,      }, // 391\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X2^X5^Y8,      }, // 392\n    {Y4^X9^Y9,      Y0^X4^Y4,      Y1^Y5^X8,      X1^X5^Y8,      }, // 393\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y5,            }, // 394\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y3,            }, // 395\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      X3,            }, // 396\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y2,            }, // 397\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      X2,            }, // 398\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      }, // 399\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X6,            }, // 400\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Y3,            }, // 401\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X3,            }, // 402\n    {X4,            Y4,            Y5^X8,         X5^Y8,         }, // 403\n    {Z0^X4^Y4,      Y4,            X5,            Y5^X9,         }, // 404\n    {Y4^X6^Y6,      Z0^X4^Y4,      X2,            Y2,            }, // 405\n    {Y4^X7^Y7,      Z1^X4^Y4,      S1^Y5^X6,      X2,            }, // 406\n    {X4,            Y4,            Y5^X8,         S0^X5^Y8,      }, // 407\n    {Y3,            X4,            Y4^X8,         S0^X5^Y7,      }, // 408\n    {X3,            Y3,            Y4^X7,         S0^X4^Y7,      }, // 409\n    {Y2,            X3,            Y3^X7,         S0^X4^Y6,      }, // 410\n    {X2,            Y2,            Y3^X6,         S0^X3^Y6,      }, // 411\n    {S2^X4^Y4,      X2,            Y2,            X3^Y6,         }, // 412\n    {Y4^X5^Y5,      S2^X4^Y4,      X2,            Y2,            }, // 413\n    {Y4^X5^Y5,      Z0^X4^Y4,      X3^X6^Y6,      X2,            }, // 414\n    {Y4^X6^Y6,      Z1^X4^Y4,      X5,            Y6,            }, // 415\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y2,            X3,            }, // 416\n    {Y4^X6^Y6,      S2^X4^Y4,      X2,            Y2,            }, // 417\n    {Y4^X6^Y6,      Z0^X4^Y4,      S2^X5^Y5,      X2,            }, // 418\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X3^X7^Y7,      }, // 419\n    {Y4^X7^Y7,      Z0^X4^Y4,      S2^Y5^X6,      Y2,            }, // 420\n    {Y4^X7^Y7,      Z0^X4^Y4,      S2^Y5^X6,      X2,            }, // 421\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      S2^X5^Y6,      }, // 422\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      S2^X5^Y7,      }, // 423\n    {X4,            Y4,            Y5^X10,        X5^Y10,        }, // 424\n    {Y4^X5^Y5,      Z0^X4^Y4,      S0^X6^Y6,      X2,            }, // 425\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      S0^X7^Y7,      }, // 426\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      S0^X5^Y6,      }, // 427\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      S0^X5^Y7,      }, // 428\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      S0^X5^Y8,      }, // 429\n    {Y4^X5^Y5,      Z0^X4^Y4,      S1^X6^Y6,      X2,            }, // 430\n    {Y4^X6^Y6,      Z0^X4^Y4,      S1^X5^Y5,      X2,            }, // 431\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      S1^X7^Y7,      }, // 432\n    {Y4^X6^Y6,      Z0^X4^Y4,      S1^X5^Y5,      S0^X7^Y7,      }, // 433\n    {Y4^X7^Y7,      Z1^X4^Y4,      S1^Y5^X6,      Y2,            }, // 434\n    {Y4^X7^Y7,      Z0^X4^Y4,      S1^Y5^X6,      X2,            }, // 435\n    {Y4^X7^Y7,      Z1^X4^Y4,      S1^Y5^X6,      Z0^X5^Y6,      }, // 436\n    {Y4^X7^Y7,      Z0^X4^Y4,      S1^Y5^X6,      S0^X5^Y6,      }, // 437\n    {Y4^X8^Y8,      Z1^X4^Y4,      S1^Y5^X7,      Z0^X5^Y7,      }, // 438\n    {Y4^X8^Y8,      Z0^X4^Y4,      S1^Y5^X7,      S0^X5^Y7,      }, // 439\n    {Y4^X9^Y9,      Z1^X4^Y4,      S1^Y5^X8,      Z0^X5^Y8,      }, // 440\n    {Y4^X9^Y9,      Z0^X4^Y4,      S1^Y5^X8,      S0^X5^Y8,      }, // 441\n    {Y4^X5^Y5,      Z0^X4^Y4,      S2^X6^Y6,      X3,            }, // 442\n    {Y4^X5^Y5,      Z0^X4^Y4,      S2^X6^Y6,      Y2,            }, // 443\n    {Y4^X5^Y5,      S2^X4^Y4,      S1^X6^Y6,      X2,            }, // 444\n    {Y4^X6^Y6,      Z0^X4^Y4,      S2^X5^Y5,      Y2,            }, // 445\n    {Y4^X6^Y6,      S2^X4^Y4,      S1^X5^Y5,      X2,            }, // 446\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      S2^X7^Y7,      }, // 447\n    {Y4^X6^Y6,      Z0^X4^Y4,      S2^X5^Y5,      S1^X7^Y7,      }, // 448\n    {Y4^X6^Y6,      S2^X4^Y4,      S1^X5^Y5,      S0^X7^Y7,      }, // 449\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y6,            }, // 450\n    {Y4^X7^Y7,      S2^X4^Y4,      S1^Y5^X6,      X2,            }, // 451\n    {Y4^X7^Y7,      Z0^X4^Y4,      S2^Y5^X6,      S1^X5^Y6,      }, // 452\n    {Y4^X7^Y7,      S2^X4^Y4,      S1^Y5^X6,      S0^X5^Y6,      }, // 453\n    {Y4^X8^Y8,      Z0^X4^Y4,      S2^Y5^X7,      S1^X5^Y7,      }, // 454\n    {Y4^X8^Y8,      S2^X4^Y4,      S1^Y5^X7,      S0^X5^Y7,      }, // 455\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      S2^X5^Y8,      }, // 456\n    {Y4^X9^Y9,      Z0^X4^Y4,      S2^Y5^X8,      S1^X5^Y8,      }, // 457\n    {Y4^X9^Y9,      S2^X4^Y4,      S1^Y5^X8,      S0^X5^Y8,      }, // 458\n    {X4^Y4,         Y2,            Z3,            Y3,            }, // 459\n    {X4^Y4,         Y2,            Z2,            Y3,            }, // 460\n    {X4^Y4,         Y1,            Z2,            Y2,            }, // 461\n    {Y1^X4^Y4,      X1,            Z2,            Y2,            }, // 462\n    {Y4^X5^Y5,      X4^Y4,         Y2,            Z3,            }, // 463\n    {Y4^X5^Y5,      X4^Y4,         Y2,            Z2,            }, // 464\n    {Z3^Y4^X5^Y5,   X4^Y4,         Y1,            Z2,            }, // 465\n    {Z3^Y4^X5^Y5,   Y1^X4^Y4,      X1,            Z2,            }, // 466\n    {Y4^X5^Y5,      X4^Y4,         Z3^X5,         Y2,            }, // 467\n    {Y4^X5^Y5,      X4^Y4,         Z2^X5,         Y2,            }, // 468\n    {Z3^Y4^X5^Y5,   X4^Y4,         Z2^X5,         Y1,            }, // 469\n    {Z3^Y4^X5^Y5,   Y1^X4^Y4,      Z2^X5,         X1,            }, // 470\n    {Y4^X6^Y6,      X4^Y4,         Y2,            Y3,            }, // 471\n    {Y4^X6^Y6,      X4^Y4,         Z3,            Y3,            }, // 472\n    {Y4^X6^Y6,      X4^Y4,         Z2,            Y3,            }, // 473\n    {Z3^Y4^X6^Y6,   X4^Y4,         Z2,            Y2,            }, // 474\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      Z2,            Y2,            }, // 475\n    {Y4^X6^Y6,      X4^Y4,         X5^Y5,         Y2,            }, // 476\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z3,            }, // 477\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z2,            }, // 478\n    {Z3^Y4^X6^Y6,   X4^Y4,         Y1^X5^Y5,      Z2,            }, // 479\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      X1^X5^Y5,      Z2,            }, // 480\n    {Y4^X6^Y6,      X4^Y4,         X5^Y5,         Z3^X6,         }, // 481\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z3^X6,         }, // 482\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z2^X6,         }, // 483\n    {Z3^Y4^X6^Y6,   X4^Y4,         Y1^X5^Y5,      Z2^X6,         }, // 484\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      X1^X5^Y5,      Z2^X6,         }, // 485\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Y3,            }, // 486\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Y2,            }, // 487\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Y2,            }, // 488\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      X5^Y6,         }, // 489\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Z3^X5^Y6,      }, // 490\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Z2^X5^Y6,      }, // 491\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Z2^X5^Y6,      }, // 492\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Z2^X5^Y6,      }, // 493\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Y3^X5^Y6,      }, // 494\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Y2^X5^Y6,      }, // 495\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Y2^X5^Y6,      }, // 496\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      X5^Y7,         }, // 497\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Z3^X5^Y7,      }, // 498\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Z2^X5^Y7,      }, // 499\n    {Z3^Y4^X8^Y8,   X4^Y4,         Y1^Y5^X7,      Z2^X5^Y7,      }, // 500\n    {Z3^Y4^X8^Y8,   Y1^X4^Y4,      X1^Y5^X7,      Z2^X5^Y7,      }, // 501\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Y3^X5^Y7,      }, // 502\n    {Z3^Y4^X8^Y8,   X4^Y4,         Y1^Y5^X7,      Y2^X5^Y7,      }, // 503\n    {Z3^Y4^X8^Y8,   Y1^X4^Y4,      X1^Y5^X7,      Y2^X5^Y7,      }, // 504\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      X5^Y8,         }, // 505\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      Z3^X5^Y8,      }, // 506\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      Z2^X5^Y8,      }, // 507\n    {Z3^Y4^X9^Y9,   X4^Y4,         Y1^Y5^X8,      Z2^X5^Y8,      }, // 508\n    {Z3^Y4^X9^Y9,   Y1^X4^Y4,      X1^Y5^X8,      Z2^X5^Y8,      }, // 509\n};\n\nconst UINT_64 GFX10_SW_PATTERN_NIBBLE3[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y6,            X6,            Y7,            X7,            }, // 1\n    {Y5,            X6,            Y6,            X7,            }, // 2\n    {Y5,            X5,            Y6,            X6,            }, // 3\n    {Y4,            X5,            Y5,            X6,            }, // 4\n    {Y4,            X4,            Y5,            X5,            }, // 5\n    {Z0^X6^Y6,      X6,            Y7,            X7,            }, // 6\n    {Z0^Y5^X6,      X6,            Y6,            X7,            }, // 7\n    {Z0^X5^Y5,      X5,            Y6,            X6,            }, // 8\n    {Z0^Y4^X5,      X5,            Y5,            X6,            }, // 9\n    {Z0^X4^Y4,      X4,            Y5,            X5,            }, // 10\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y7,            X7,            }, // 11\n    {Z1^Y5^X7,      Z0^X6^Y6,      Y6,            X7,            }, // 12\n    {Z1^Y5^X6,      Z0^X5^Y6,      Y6,            X6,            }, // 13\n    {Z1^Y4^X6,      Z0^X5^Y5,      Y5,            X6,            }, // 14\n    {Z1^Y4^X5,      Z0^X4^Y5,      Y5,            X5,            }, // 15\n    {X6^Y6,         X6,            Y7,            X7,            }, // 16\n    {Y5^X6,         X6,            Y6,            X7,            }, // 17\n    {X5^Y5,         X5,            Y6,            X6,            }, // 18\n    {Y4^X5,         X5,            Y5,            X6,            }, // 19\n    {X4^Y4,         X4,            Y5,            X5,            }, // 20\n    {Y6^X7,         X6^Y7,         Y7,            X7,            }, // 21\n    {Y5^X7,         X6^Y6,         Y6,            X7,            }, // 22\n    {Y5^X6,         X5^Y6,         Y6,            X6,            }, // 23\n    {Y4^X6,         X5^Y5,         Y5,            X6,            }, // 24\n    {Y4^X5,         X4^Y5,         Y5,            X5,            }, // 25\n    {Y3,            X4,            Y5,            X5,            }, // 26\n    {Y4,            X5,            Y6,            X6,            }, // 27\n    {Y2,            X4,            Y5,            X6,            }, // 28\n    {Y2,            X3,            Y4,            X5,            }, // 29\n    {Y4,            X6,            Y6,            X7,            }, // 30\n    {Y3,            X4,            Y6,            X6,            }, // 31\n    {Y2,            X3,            Y4,            X6,            }, // 32\n    {Y2,            X2,            Y3,            X4,            }, // 33\n    {Z0^X6^Y6,      X4,            Y6,            X7,            }, // 34\n    {Z0^X6^Y6,      X3,            Y4,            X6,            }, // 35\n    {Z0^X6^Y6,      Y2,            X3,            Y4,            }, // 36\n    {Y2^X6^Y6,      X2,            Y3,            X4,            }, // 37\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y4,            X7,            }, // 38\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y3,            X4,            }, // 39\n    {Y2^Y6^X7,      Z0^X6^Y7,      Y3,            X4,            }, // 40\n    {Y2^Y6^X7,      X2^X6^Y7,      Y3,            X4,            }, // 41\n    {X5,            Y6,            X6,            Y7,            }, // 42\n    {Y5,            X5,            Y6,            Y2^Y7,         }, // 43\n    {X4,            Y5,            X5,            Y2^Y6,         }, // 44\n    {Y4,            X4,            Y5,            Y1^Y6,         }, // 45\n    {Y3,            X4,            Y5,            Y1^Y6,         }, // 46\n    {Y4,            X5,            Y6,            Y2^Y7,         }, // 47\n    {X3,            Y4,            X5,            Y2^Y6,         }, // 48\n    {Y2,            X3,            Y4,            Y1^Y6,         }, // 49\n    {Y4,            Y6,            X6,            Y7,            }, // 50\n    {Y3,            X4,            Y6,            Y2^Y7,         }, // 51\n    {X2,            Y3,            X4,            Y2^Y6,         }, // 52\n    {Y1,            X3,            Y4,            X2^Y6,         }, // 53\n    {Z0^X6^Y6,      Y4,            X6,            Y7,            }, // 54\n    {Z0^X6^Y6,      X3,            Y4,            Y2^Y7,         }, // 55\n    {Y2^X6^Y6,      Y3,            X4,            X2^Y7,         }, // 56\n    {X2^X6^Y6,      X3,            Y4,            Y1^Y7,         }, // 57\n    {Z0^Y6^X7,      Z5^X6^Y7,      Y4,            Y7,            }, // 58\n    {Z0^Y6^X7,      Z5^X6^Y7,      Y3,            X4,            }, // 59\n    {Z0^Y6^X7,      Y2^X6^Y7,      X3,            Y4,            }, // 60\n    {X2^Y6^X7,      Y1^X6^Y7,      X3,            Y4,            }, // 61\n    {X5,            Y5,            X6,            Y2^Y6,         }, // 62\n    {Y5,            X5,            Y2^Y6,         X2^Y7,         }, // 63\n    {Y4,            X5,            Y1^Y5,         X2^Y6,         }, // 64\n    {Y4,            X4,            Y1^Y5,         X1^Y6,         }, // 65\n    {Y5,            X5,            X2^Y6,         Y2^Y7,         }, // 66\n    {Y4,            X5,            X2^Y5,         Y1^Y6,         }, // 67\n    {Y4,            X4,            X1^Y5,         Y1^Y6,         }, // 68\n    {Y3,            X4,            Y1^Y5,         X1^Y6,         }, // 69\n    {X4,            Y5,            X6,            Y2^Y6,         }, // 70\n    {Y4,            X5,            X2^Y6,         Y2^Y7,         }, // 71\n    {X3,            Y4,            Y1^Y5,         X2^Y6,         }, // 72\n    {Y3,            X4,            X1^Y6,         Y1^Y7,         }, // 73\n    {X3,            Y4,            X6,            Y2^Y6,         }, // 74\n    {Y3,            X4,            Y2^Y6,         X2^Y7,         }, // 75\n    {Y3,            X4,            Y1^Y6,         X2^Y7,         }, // 76\n    {Z4^X6^Y6,      X3,            Y4,            X6,            }, // 77\n    {Z4^X6^Y6,      X3,            Y4,            Y2^Y6,         }, // 78\n    {Y1^X6^Y6,      Y3,            X4,            X2^Y7,         }, // 79\n    {Z5^Y6^X7,      Z4^X6^Y7,      Y3,            X4,            }, // 80\n    {Y2^Y6^X7,      Z4^X6^Y7,      Y3,            X4,            }, // 81\n    {Y1^Y6^X7,      X2^X6^Y7,      Y3,            X4,            }, // 82\n    {Y5,            Y1^Y6,         Y2^Y7,         X2^Y8,         }, // 83\n    {X4,            Y1^Y5,         X1^Y6,         Y2^Y7,         }, // 84\n    {Y4,            Y0^Y5,         Y1^Y6,         X1^Y7,         }, // 85\n    {Y5,            Y1^Y6,         X2^Y7,         Y2^Y8,         }, // 86\n    {X4,            X1^Y5,         Y1^Y6,         X2^Y7,         }, // 87\n    {Y4,            Y0^Y5,         X1^Y6,         Y1^Y7,         }, // 88\n    {X3,            Y0^Y5,         X1^Y6,         Y1^Y7,         }, // 89\n    {Y4,            Y1^Y6,         X2^Y7,         Y2^Y8,         }, // 90\n    {X4,            X1^Y6,         Y1^Y7,         X2^Y8,         }, // 91\n    {X3,            X1^Y6,         Y1^Y7,         X2^Y8,         }, // 92\n    {X3,            Y4,            X2^Y6,         Y1^Y7,         }, // 93\n    {X3,            Y1^Y6,         X2^Y7,         Y2^Y8,         }, // 94\n    {Z3^X6^Y6,      X3,            Y4,            Y2^Y7,         }, // 95\n    {Y2^X6^Y6,      X3,            X2^Y7,         Y1^Y8,         }, // 96\n    {Z3^Y6^X7,      Y2^X6^Y7,      X3,            Y4,            }, // 97\n    {Y2^Y6^X7,      X2^X6^Y7,      X3,            Y1^Y7,         }, // 98\n    {Y6,            X6,            Y7,            S0^Y8,         }, // 99\n    {Y5,            X6,            Y6,            S0^Y7,         }, // 100\n    {Y5,            X5,            Y6,            S0^Y7,         }, // 101\n    {Y4,            X5,            Y5,            S0^Y6,         }, // 102\n    {Y4,            X4,            Y5,            S0^Y6,         }, // 103\n    {Y3,            X4,            Y5,            S0^Y6,         }, // 104\n    {Y4,            X5,            Y6,            S0^Y7,         }, // 105\n    {Y2,            X4,            Y5,            S0^Y6,         }, // 106\n    {Y2,            X3,            Y4,            S0^Y6,         }, // 107\n    {Y4,            X6,            Y6,            S0^Y7,         }, // 108\n    {Y3,            X4,            Y6,            S0^Y7,         }, // 109\n    {Z0^X6^Y6,      X6,            Y7,            S0^Y8,         }, // 110\n    {Z0^X6^Y6,      X4,            Y6,            S0^Y7,         }, // 111\n    {Z0^X6^Y6,      X3,            Y4,            S0^Y7,         }, // 112\n    {S0^X6^Y6,      Y2,            X3,            Y4,            }, // 113\n    {Z0^Y6^X7,      Z5^X6^Y7,      Y7,            S0^Y8,         }, // 114\n    {Z0^Y6^X7,      Z5^X6^Y7,      Y4,            S0^Y7,         }, // 115\n    {Z0^Y6^X7,      S0^X6^Y7,      Y3,            X4,            }, // 116\n    {S0^Y6^X7,      Y2^X6^Y7,      X3,            Y4,            }, // 117\n    {Y6,            X6,            S0^Y7,         S1^Y8,         }, // 118\n    {Y5,            X6,            S0^Y6,         S1^Y7,         }, // 119\n    {Y5,            X5,            S0^Y6,         S1^Y7,         }, // 120\n    {Y4,            X5,            S0^Y5,         S1^Y6,         }, // 121\n    {Y4,            X4,            S0^Y5,         S1^Y6,         }, // 122\n    {Y3,            X4,            S0^Y5,         S1^Y6,         }, // 123\n    {Y4,            X5,            S0^Y6,         S1^Y7,         }, // 124\n    {X3,            Y4,            S0^Y5,         S1^Y6,         }, // 125\n    {Y4,            X6,            S0^Y6,         S1^Y7,         }, // 126\n    {Y3,            X4,            S0^Y6,         S1^Y7,         }, // 127\n    {Z4^X6^Y6,      X6,            S0^Y7,         S1^Y8,         }, // 128\n    {Z4^X6^Y6,      Y4,            S0^Y6,         S1^Y7,         }, // 129\n    {S1^X6^Y6,      X3,            Y4,            S0^Y7,         }, // 130\n    {Z5^Y6^X7,      Z4^X6^Y7,      S0^Y7,         S1^Y8,         }, // 131\n    {S1^Y6^X7,      Z4^X6^Y7,      Y4,            S0^Y7,         }, // 132\n    {S1^Y6^X7,      S0^X6^Y7,      Y3,            X4,            }, // 133\n    {Y6,            S0^Y7,         S1^Y8,         S2^Y9,         }, // 134\n    {Y5,            S0^Y6,         S1^Y7,         S2^Y8,         }, // 135\n    {Y4,            S0^Y5,         S1^Y6,         S2^Y7,         }, // 136\n    {X3,            S0^Y5,         S1^Y6,         S2^Y7,         }, // 137\n    {Y4,            S0^Y6,         S1^Y7,         S2^Y8,         }, // 138\n    {X3,            Y4,            S0^Y6,         S1^Y7,         }, // 139\n    {Y2,            X3,            S0^Y6,         S1^Y7,         }, // 140\n    {X2,            Y2,            X3,            S0^Y6,         }, // 141\n    {Z3^X6^Y6,      S0^Y7,         S1^Y8,         S2^Y9,         }, // 142\n    {S2^X6^Y6,      Y4,            S0^Y7,         S1^Y8,         }, // 143\n    {S0^X6^Y6,      X2,            Y2,            X3,            }, // 144\n    {Z3^Y6^X7,      S2^X6^Y7,      S0^Y7,         S1^Y8,         }, // 145\n    {S2^Y6^X7,      S1^X6^Y7,      Y4,            S0^Y7,         }, // 146\n    {S0^Y6^X7,      X2^X6^Y7,      Y2,            X3,            }, // 147\n    {X4,            Z4,            Y4,            X5,            }, // 148\n    {X3,            Z4,            Y4,            X4,            }, // 149\n    {X3,            Z3,            Y4,            X4,            }, // 150\n    {X3,            Z3,            Y3,            X4,            }, // 151\n    {X2,            Z3,            Y3,            X3,            }, // 152\n    {X4^Y4^Z4,      Z4,            Y4,            X5,            }, // 153\n    {X3^Y4^Z4,      Z4,            Y4,            X4,            }, // 154\n    {X3^Z3^Y4,      Z3,            Y4,            X4,            }, // 155\n    {X3^Y3^Z3,      Z3,            Y3,            X4,            }, // 156\n    {X2^Y3^Z3,      Z3,            Y3,            X3,            }, // 157\n    {X4^Y5^Z5,      Y4^Z4^X5,      Y4,            X5,            }, // 158\n    {X3^Y5^Z5,      X4^Y4^Z4,      Y4,            X4,            }, // 159\n    {X3^Z4^Y5,      Z3^X4^Y4,      Y4,            X4,            }, // 160\n    {X3^Y4^Z4,      Y3^Z3^X4,      Y3,            X4,            }, // 161\n    {X2^Y4^Z4,      X3^Y3^Z3,      Y3,            X3,            }, // 162\n    {X4,            Y4^Z4^X5,      Y4,            X5,            }, // 163\n    {X3,            X4^Y4^Z4,      Y4,            X4,            }, // 164\n    {X3,            Z3^X4^Y4,      Y4,            X4,            }, // 165\n    {X3,            Y3^Z3^X4,      Y3,            X4,            }, // 166\n    {X2,            X3^Y3^Z3,      Y3,            X3,            }, // 167\n    {X3,            Z3,            Y2,            X4,            }, // 168\n    {X2,            Z3,            Y2,            X3,            }, // 169\n    {X3,            Z4,            Y4,            X5,            }, // 170\n    {X2,            Z4,            Y3,            X4,            }, // 171\n    {X2,            Z3,            Y3,            X4,            }, // 172\n    {Y2,            X3,            Z4,            Y4,            }, // 173\n    {Z3,            Y3,            X4,            Z4,            }, // 174\n    {Z3^X6^Y6,      Y3,            X4,            Z4,            }, // 175\n    {X2^X6^Y6,      Z4,            Y3,            X4,            }, // 176\n    {X2^X6^Y6,      Z3,            Y3,            X4,            }, // 177\n    {X2^X6^Y6,      Z3,            Y2,            X3,            }, // 178\n    {Z3^Y6^X7,      Z4^X6^Y7,      Y3,            X4,            }, // 179\n    {X2^Y6^X7,      Z4^X6^Y7,      Y3,            X4,            }, // 180\n    {X2^Y6^X7,      Z3^X6^Y7,      Y3,            X4,            }, // 181\n    {X2^Y6^X7,      Z3^X6^Y7,      Y2,            X3,            }, // 182\n    {X6^Y7,         Y6^X7,         0,             0,             }, // 183\n    {Y5^X7,         X6^Y6,         0,             0,             }, // 184\n    {X5^Y6,         Y5^X6,         0,             0,             }, // 185\n    {Y4^X6,         X5^Y5,         0,             0,             }, // 186\n    {X4^Y5,         Y4^X5,         0,             0,             }, // 187\n    {Y5^X9,         X7^Y7,         Y6^X8,         0,             }, // 188\n    {Y5^X8,         X6^Y7,         Y6^X7,         0,             }, // 189\n    {Y4^X8,         X6^Y6,         Y5^X7,         0,             }, // 190\n    {Y4^X7,         X5^Y6,         Y5^X6,         0,             }, // 191\n    {Y3^X7,         X5^Y5,         Y4^X6,         0,             }, // 192\n    {X6^Y9,         Y6^X9,         X7^Y8,         Y7^X8,         }, // 193\n    {X6^Y8,         Y5^X9,         X7^Y7,         Y6^X8,         }, // 194\n    {X5^Y8,         Y5^X8,         X6^Y7,         Y6^X7,         }, // 195\n    {Y3^X8,         X5^Y7,         X6^Y6,         Y5^X7,         }, // 196\n    {Y3^X7,         X3^Y7,         X5^Y6,         Y5^X6,         }, // 197\n    {X6,            X7^Y9,         Y6^X10,        X8^Y8,         }, // 198\n    {Y5,            X6^Y9,         Y6^X9,         X7^Y8,         }, // 199\n    {Y3,            X6^Y8,         Y5^X9,         X7^Y7,         }, // 200\n    {X3,            Y3^X9,         Y5^X8,         X6^Y7,         }, // 201\n    {Y2,            X3^Y7,         Y3^X8,         X6^Y6,         }, // 202\n    {Y6^X9,         X7^Y8,         Y7^X8,         Z0^X5^Y5,      }, // 203\n    {X6^Y8,         Y6^X8,         X7^Y7,         Z0^X5^Y5,      }, // 204\n    {X5^Y8,         X6^Y7,         Y6^X7,         Z0^X5^Y5,      }, // 205\n    {Y3^X7,         X5^Y7,         X6^Y6,         Z0^X5^Y5,      }, // 206\n    {X3^Y7,         Y3^X6,         X5^Y6,         Z0^X5^Y5,      }, // 207\n    {X6,            Y6^X10,        X7^Y9,         Y7^X9,         }, // 208\n    {X5,            X6^Y9,         Y6^X9,         X7^Y8,         }, // 209\n    {Y3,            X5^Y9,         X6^Y8,         Y6^X8,         }, // 210\n    {X3,            Y3^X8,         X5^Y8,         X6^Y7,         }, // 211\n    {Y2,            X3^Y8,         Y3^X7,         X5^Y7,         }, // 212\n    {X6,            Y6,            X7^Y10,        Y7^X10,        }, // 213\n    {Y3,            X6,            Y6^X10,        X7^Y9,         }, // 214\n    {X3,            Y3,            X6^Y9,         Y6^X9,         }, // 215\n    {Y2,            X3,            Y3^X9,         X6^Y8,         }, // 216\n    {X2,            Y2,            X3^Y8,         Y3^X8,         }, // 217\n    {Y6,            X7^Y9,         X8^Y8,         Y7^X9,         }, // 218\n    {X6,            Y6^X9,         X7^Y8,         Y7^X8,         }, // 219\n    {Y3,            X6^Y8,         X7^Y7,         Y6^X8,         }, // 220\n    {X3,            Y3^X8,         X6^Y7,         Y6^X7,         }, // 221\n    {Y2,            X3^Y7,         Y3^X7,         X6^Y6,         }, // 222\n    {Y3,            X6,            X7^Y9,         Y6^X10,        }, // 223\n    {X2,            Y2,            Y3^X8,         X3^Y8,         }, // 224\n    {X6^Y6,         Y6,            X7,            X8^Y10,        }, // 225\n    {X6^Y6,         Y3,            Y6,            X7^Y10,        }, // 226\n    {X6^Y6,         X3,            Y3,            X7^Y9,         }, // 227\n    {X6^Y6,         Y2,            X3,            Y3^X10,        }, // 228\n    {X6^Y6,         X2,            Y2,            X3^Y8,         }, // 229\n    {X6,            X7,            Y7^X10,        X8^Y9,         }, // 230\n    {Y3,            X6,            X7^Y9,         Y7^X9,         }, // 231\n    {X3,            Y3,            X6^Y9,         X7^Y8,         }, // 232\n    {Y2,            X3,            Y3^X8,         X6^Y8,         }, // 233\n    {X2,            Y2,            X3^Y8,         Y3^X7,         }, // 234\n    {X6^Y6,         X6,            X7,            Y7^X11,        }, // 235\n    {X6^Y6,         Y3,            X6,            X7^Y10,        }, // 236\n    {X6^Y6,         X3,            Y3,            X6^Y10,        }, // 237\n    {Z0^X6^Y6,      Y2,            X3,            Y3^X9,         }, // 238\n    {Z0^X6^Y6,      X2,            Y2,            X3^Y9,         }, // 239\n    {X6^Y6,         X6^Y8,         X7,            Y7,            }, // 240\n    {X6^Y6,         X6^Y8,         Y3,            X7,            }, // 241\n    {X6^Y6,         X6^Y8,         X3,            Y3,            }, // 242\n    {Z0^X6^Y6,      X6^Y8,         Y2,            X3,            }, // 243\n    {Z0^X6^Y6,      X6^Y8,         X2,            Y2,            }, // 244\n    {Y6^X7,         X7,            Y7,            X8^Y10,        }, // 245\n    {Y6^X7,         Y3,            X7,            Y7^X10,        }, // 246\n    {Y6^X7,         X3,            Y3,            X7^Y9,         }, // 247\n    {Z1^Y6^X7,      Y2,            X3,            Y3^X9,         }, // 248\n    {Z1^Y6^X7,      X2,            Y2,            X3^Y8,         }, // 249\n    {Y6^X7,         X6^Y7,         X7,            Y7,            }, // 250\n    {Y6^X7,         X6^Y7,         Y3,            X7,            }, // 251\n    {Y6^X7,         X6^Y7,         X3,            Y3,            }, // 252\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y2,            X3,            }, // 253\n    {Z1^Y6^X7,      Z0^X6^Y7,      X2,            Y2,            }, // 254\n    {X5^Y7,         X6^Y6,         0,             0,             }, // 255\n    {Y5^X6,         Y2^X5^Y6,      0,             0,             }, // 256\n    {Y4^X6,         X2^X5^Y5,      0,             0,             }, // 257\n    {Y4^X5,         Y1^X4^Y5,      0,             0,             }, // 258\n    {X5^Y7,         Y5^X7,         Y2^X6^Y6,      0,             }, // 259\n    {X5^Y6,         Y4^X7,         X2^Y5^X6,      0,             }, // 260\n    {X3^Y6,         Y4^X6,         Y1^X5^Y5,      0,             }, // 261\n    {Y5^X9,         Y6^X8,         X6^Y8,         X7^Y7,         }, // 262\n    {Y5^X8,         X5^Y8,         Y6^X7,         Y2^X6^Y7,      }, // 263\n    {Y3^X8,         X5^Y7,         Y5^X7,         Y2^X6^Y6,      }, // 264\n    {Y3^X7,         X3^Y7,         Y5^X6,         Y1^X5^Y6,      }, // 265\n    {Y3,            X5^Y9,         X6^Y8,         X7^Y7,         }, // 266\n    {Y2,            Y3^X7,         X3^Y8,         X5^Y7,         }, // 267\n    {Y6^X8,         X6^Y8,         X7^Y7,         Z0^X5^Y5,      }, // 268\n    {X5^Y8,         Y6^X7,         Y2^X6^Y7,      Z0^X5^Y5,      }, // 269\n    {Y3^X7,         X5^Y7,         X2^X6^Y6,      Z0^X5^Y5,      }, // 270\n    {Y3^X6,         X3^Y7,         Y1^X5^Y6,      Z0^X5^Y5,      }, // 271\n    {Y3,            X5,            X6^Y10,        Y7^X9,         }, // 272\n    {X3,            Y3,            X5^Y10,        X6^Y9,         }, // 273\n    {Y2,            X3,            Y3^X8,         X5^Y9,         }, // 274\n    {X2,            Y2,            Y3^X7,         X3^Y9,         }, // 275\n    {Y3,            X6^Y8,         Y6^X8,         Y2^X7^Y7,      }, // 276\n    {X3,            Y3^X8,         X6^Y7,         X2^Y6^X7,      }, // 277\n    {Y2,            Y3^X7,         X3^Y7,         Y1^X6^Y6,      }, // 278\n    {Y3,            X6,            Y6^X10,        Y7^X9,         }, // 279\n    {X3,            Y3,            Y6^X9,         X6^Y9,         }, // 280\n    {X2,            X3,            Y3^X9,         X6^Y8,         }, // 281\n    {X6^Y6,         Y2,            X3,            Y3^X9,         }, // 282\n    {X6^Y6,         X2,            Y2,            Y3^X8,         }, // 283\n    {Y3,            X6,            Y7^X9,         X7^Y9,         }, // 284\n    {X3,            Y3,            X6^Y9,         Y7^X8,         }, // 285\n    {X2,            Y2,            Y3^X7,         X3^Y8,         }, // 286\n    {Z0^Y6^X7,      Y2,            X3,            Y3^X9,         }, // 287\n    {Z0^Y6^X7,      X2,            Y2,            Y3^X8,         }, // 288\n    {Z0^Y6^X7,      Z4^X6^Y7,      X2,            X3,            }, // 289\n    {Z0^Y6^X7,      Z4^X6^Y7,      X2,            Y2,            }, // 290\n    {X5^Y6,         Y2^Y5^X6,      0,             0,             }, // 291\n    {X2^X5^Y6,      Y2^Y5^X6,      0,             0,             }, // 292\n    {X2^X5^Y5,      Y1^Y4^X6,      0,             0,             }, // 293\n    {X1^X4^Y5,      Y1^Y4^X5,      0,             0,             }, // 294\n    {Y4^X8,         X2^X6^Y6,      Y2^Y5^X7,      0,             }, // 295\n    {Y4^X7,         Y2^Y5^X6,      Y1^X5^Y6,      0,             }, // 296\n    {Y3^X7,         X1^X5^Y5,      Y1^Y4^X6,      0,             }, // 297\n    {X5^Y8,         X6^Y7,         Y5^X8,         Y2^Y6^X7,      }, // 298\n    {X5^Y8,         Y5^X8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 299\n    {Y3^X8,         X5^Y7,         X2^Y5^X7,      Y1^X6^Y6,      }, // 300\n    {Y3^X7,         X3^Y7,         X1^Y5^X6,      Y1^X5^Y6,      }, // 301\n    {Y3,            Y5^X9,         X6^Y8,         Y6^X8,         }, // 302\n    {Y3,            X6^Y8,         Y5^X9,         X2^X7^Y7,      }, // 303\n    {X3,            Y3^X9,         Y5^X8,         Y2^Y6^X7,      }, // 304\n    {Y2,            X3^Y7,         Y3^X8,         X1^X6^Y6,      }, // 305\n    {X5^Y8,         X6^Y7,         Y2^Y6^X7,      Z0^X5^Y5,      }, // 306\n    {X5^Y8,         X2^X6^Y7,      Y2^Y6^X7,      Z0^X5^Y5,      }, // 307\n    {Y3^X8,         Y2^Y5^X7,      Y1^X6^Y6,      Z0^X5^Y5,      }, // 308\n    {Y3^X7,         Y2^X6^Y6,      X1^X5^Y7,      Y1^X5^Y5,      }, // 309\n    {Y3,            X5^Y9,         X6^Y8,         X2^Y6^X8,      }, // 310\n    {X3,            Y3^X8,         X5^Y8,         X2^Y6^X7,      }, // 311\n    {Y2,            Y3^X8,         X3^Y7,         X1^Y5^X7,      }, // 312\n    {Y3,            X6^Y8,         X2^X7^Y7,      Y2^Y6^X8,      }, // 313\n    {X3,            Y3^X8,         Y2^Y6^X7,      Y1^X6^Y7,      }, // 314\n    {X3,            Y3^X8,         Y2^Y6^X7,      X1^X6^Y7,      }, // 315\n    {X6^Y6,         X3,            Y3,            Y6^X10,        }, // 316\n    {X6^Y6,         X2,            X3,            Y3^X10,        }, // 317\n    {X3,            Y3,            X6^Y9,         X2^X7^Y8,      }, // 318\n    {X2,            X3,            Y3^X9,         Y2^Y6^X8,      }, // 319\n    {X2,            X3,            Y3^X8,         Y2^X7^Y7,      }, // 320\n    {Z3^X6^Y6,      Y2,            X3,            Y3^X9,         }, // 321\n    {Z3^X6^Y6,      X2,            Y2,            Y3^X9,         }, // 322\n    {Z3^X6^Y6,      X6^Y8,         Y2,            X3,            }, // 323\n    {Z3^X6^Y6,      X6^Y8,         X2,            Y2,            }, // 324\n    {Z4^Y6^X7,      X2,            X3,            Y3^X9,         }, // 325\n    {Y1^Y6^X7,      X2,            X3,            Y3^X9,         }, // 326\n    {Z4^Y6^X7,      Z3^X6^Y7,      Y2,            X3,            }, // 327\n    {Z4^Y6^X7,      Z3^X6^Y7,      X2,            Y2,            }, // 328\n    {Y1^Y4^X6,      X2^X5^Y5,      0,             0,             }, // 329\n    {Y1^X5^Y7,      X2^X6^Y6,      Y2^Y5^X7,      0,             }, // 330\n    {X1^X5^Y6,      Y1^Y4^X7,      X2^Y5^X6,      0,             }, // 331\n    {Y5^X8,         Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 332\n    {Y3^X8,         Y1^X5^Y7,      X1^Y5^X7,      Y2^X6^Y6,      }, // 333\n    {Y3^X7,         Y1^X4^Y7,      Y2^X5^Y6,      X1^Y5^X6,      }, // 334\n    {Y3,            X5^Y9,         X6^Y8,         X2^X7^Y7,      }, // 335\n    {Y3,            X5^Y9,         Y1^X6^Y8,      X2^X7^Y7,      }, // 336\n    {X3,            Y3^X8,         X5^Y7,         X1^X6^Y6,      }, // 337\n    {Y2,            Y3^X7,         X3^Y7,         Y0^X5^Y6,      }, // 338\n    {Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      Z0^X5^Y5,      }, // 339\n    {X1^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      Y1^X5^Y5,      }, // 340\n    {X1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      Y1^X5^Y5,      }, // 341\n    {Y3,            X5^Y9,         Y1^X6^Y8,      X2^Y6^X8,      }, // 342\n    {X3,            Y3^X9,         Y1^X6^Y7,      X1^Y5^X8,      }, // 343\n    {X3,            Y3^X8,         Y1^X5^Y8,      Y2^X6^Y7,      }, // 344\n    {X3,            Y3,            X5^Y10,        Y1^X6^Y9,      }, // 345\n    {Y2,            X3,            Y3^X8,         X5^Y8,         }, // 346\n    {Y3,            Y1^X6^Y8,      X2^X7^Y7,      Y2^Y6^X8,      }, // 347\n    {Y3,            X1^X6^Y8,      Y2^Y6^X8,      X2^X7^Y7,      }, // 348\n    {Y3,            X1^X6^Y8,      X2^X7^Y7,      Y2^Y6^X8,      }, // 349\n    {X3,            Y3,            Y6^X9,         Y1^X6^Y9,      }, // 350\n    {X2,            X3,            Y3^X9,         Y1^X6^Y8,      }, // 351\n    {X2^X6^Y6,      Y2,            X3,            Y3^X9,         }, // 352\n    {Y1^X6^Y6,      X2,            Y2,            Y3^X8,         }, // 353\n    {X3,            Y3,            Y1^X6^Y9,      X2^X7^Y8,      }, // 354\n    {X3,            Y3,            X1^X6^Y9,      Y2^Y7^X8,      }, // 355\n    {X3,            Y3,            X1^X6^Y9,      X2^X7^Y8,      }, // 356\n    {Z2^X6^Y6,      X2,            X3,            Y3^X10,        }, // 357\n    {Y0^X6^Y6,      X2,            X3,            Y3^X9,         }, // 358\n    {Z2^X6^Y6,      X6^Y8,         Y2,            X3,            }, // 359\n    {Z2^X6^Y6,      Y1^X6^Y8,      X2,            Y2,            }, // 360\n    {Y6^X7,         X3,            Y3,            Y1^X7^Y9,      }, // 361\n    {Y1^Y6^X7,      X3,            Y3,            X1^X7^Y9,      }, // 362\n    {Y0^Y6^X7,      X3,            Y3,            X1^X7^Y9,      }, // 363\n    {Z3^Y6^X7,      Z2^X6^Y7,      X2,            X3,            }, // 364\n    {Z2^Y6^X7,      Y0^X6^Y7,      X2,            X3,            }, // 365\n    {Y5^X9,         X6^Y8,         Y6^X8,         X7^Y7,         }, // 366\n    {Y4^X8,         X5^Y7,         Y5^X7,         X6^Y6,         }, // 367\n    {X4^Y7,         Y4^X7,         X5^Y6,         Y5^X6,         }, // 368\n    {X5^Y7,         Y4^X8,         X6^Y6,         Y5^X7,         }, // 369\n    {X3^Y7,         Y4^X7,         X5^Y6,         Y5^X6,         }, // 370\n    {Y5,            X6^Y8,         X7^Y7,         Y6^X8,         }, // 371\n    {Y3,            Y5^X8,         X6^Y7,         Y6^X7,         }, // 372\n    {X3,            Y3^X8,         X6^Y6,         Y5^X7,         }, // 373\n    {Y2,            Y3^X7,         X3^Y6,         Y5^X6,         }, // 374\n    {X5,            X6^Y8,         Y6^X8,         X7^Y7,         }, // 375\n    {Y3,            X5^Y8,         X6^Y7,         Y6^X7,         }, // 376\n    {X3,            Y3^X7,         X5^Y7,         X6^Y6,         }, // 377\n    {Y2,            X3^Y7,         Y3^X6,         X5^Y6,         }, // 378\n    {X6,            Y6,            X7^Y8,         Y7^X8,         }, // 379\n    {Y3,            X6,            Y6^X8,         X7^Y7,         }, // 380\n    {X3,            Y3,            X6^Y7,         Y6^X7,         }, // 381\n    {Y2,            X3,            Y3^X7,         X6^Y6,         }, // 382\n    {X2,            Y2,            X3^Y6,         Y3^X6,         }, // 383\n    {Y6,            X7^Y8,         Y7^X8,         X5^Y6,         }, // 384\n    {X6,            X7^Y7,         Y6^X8,         X5^Y6,         }, // 385\n    {Y3,            X6^Y7,         Y6^X7,         X5^Y6,         }, // 386\n    {X3,            Y3^X7,         X6^Y6,         Z0^X5^Y6,      }, // 387\n    {Y2,            Y3^X6,         X3^Y6,         Z0^X5^Y6,      }, // 388\n    {Y3,            X6,            X7^Y7,         Y6^X8,         }, // 389\n    {X2,            Y2,            Y3^X6,         X3^Y6,         }, // 390\n    {X6^Y6,         Y6,            X7,            Y7^X8,         }, // 391\n    {X6^Y6,         Y3,            Y6,            X7^Y7,         }, // 392\n    {X6^Y6,         X3,            Y3,            Y6^X7,         }, // 393\n    {X6^Y6,         Y2,            X3,            Y3^X7,         }, // 394\n    {X3^Y6,         X2,            Y2,            Y3^X6,         }, // 395\n    {X6,            X7,            Y7^X8,         X6^Y6,         }, // 396\n    {Y3,            X6,            X7^Y7,         X6^Y6,         }, // 397\n    {X3,            Y3,            X6^Y7,         X6^Y6,         }, // 398\n    {Y2,            X3,            Y3^X7,         Z0^X6^Y6,      }, // 399\n    {X2,            X3,            Y3^X6,         Y2^X6^Y6,      }, // 400\n    {X6^Y6,         X6,            X7,            Y7^X8,         }, // 401\n    {X6^Y6,         Y3,            X6,            X7^Y7,         }, // 402\n    {X6^Y6,         X3,            Y3,            X6^Y7,         }, // 403\n    {Z0^X6^Y6,      Y2,            X3,            Y3^X7,         }, // 404\n    {Y2^X6^Y6,      X2,            X3,            Y3^X6,         }, // 405\n    {Z0^X6^Y6,      X3^Y8,         Y2,            Y3,            }, // 406\n    {Y2^X6^Y6,      X3^Y8,         X2,            Y3,            }, // 407\n    {Y6^X7,         X7,            Y7,            X6^Y7,         }, // 408\n    {Y6^X7,         Y3,            X7,            X6^Y7,         }, // 409\n    {Y6^X7,         X3,            Y3,            X6^Y7,         }, // 410\n    {Y2^Y6^X7,      X3,            Y3,            Z0^X6^Y7,      }, // 411\n    {Y2^Y6^X7,      X3,            Y3,            X2^X6^Y7,      }, // 412\n    {Y2^Y6^X7,      Z0^X6^Y7,      X3,            Y3,            }, // 413\n    {Y2^Y6^X7,      X2^X6^Y7,      X3,            Y3,            }, // 414\n    {X5^Y9,         Y6^X8,         X6^Y8,         X7^Y7,         }, // 415\n    {Y4^X8,         X5^Y7,         Y5^X7,         X2^X6^Y6,      }, // 416\n    {Y4^X7,         X4^Y7,         Y5^X6,         Y1^X5^Y6,      }, // 417\n    {Y4^X8,         X5^Y7,         Y5^X7,         Y2^X6^Y6,      }, // 418\n    {Y4^X7,         X3^Y7,         Y5^X6,         Y1^X5^Y6,      }, // 419\n    {X5,            Y6^X8,         X6^Y8,         X7^Y7,         }, // 420\n    {Y3,            X5^Y8,         Y6^X7,         Y2^X6^Y7,      }, // 421\n    {X3,            Y3^X7,         X5^Y7,         Y2^X6^Y6,      }, // 422\n    {Y2,            Y3^X6,         X3^Y7,         Y1^X5^Y6,      }, // 423\n    {X3,            Y3^X7,         X5^Y7,         X2^X6^Y6,      }, // 424\n    {Y3,            X5,            X6^Y8,         X7^Y7,         }, // 425\n    {X3,            Y3,            X5^Y8,         X6^Y7,         }, // 426\n    {X3,            Y3,            X5^Y8,         Y2^X6^Y7,      }, // 427\n    {Y2,            X3,            Y3^X6,         X5^Y6,         }, // 428\n    {X2,            Y2,            Y3^X5,         X3^Y6,         }, // 429\n    {X6,            Y6^X8,         X7^Y7,         X5^Y6,         }, // 430\n    {Y3,            Y6^X7,         Y2^X6^Y7,      X5^Y6,         }, // 431\n    {X3,            Y3^X7,         Y2^X6^Y6,      Z0^X5^Y6,      }, // 432\n    {X3,            Y3^X7,         Y2^X6^Y6,      Y1^X5^Y6,      }, // 433\n    {X3,            Y3,            Y6^X7,         Y2^X6^Y7,      }, // 434\n    {X2,            X3,            Y3^X7,         Y2^X6^Y6,      }, // 435\n    {X6^Y6,         X3,            Y3,            Y2^X6^Y7,      }, // 436\n    {X3,            Y3,            Y2^X6^Y7,      X6^Y6,         }, // 437\n    {X3,            Y3,            X2^X6^Y7,      Y2^X6^Y6,      }, // 438\n    {Y2^X6^Y6,      X3,            Y3,            X2^X6^Y7,      }, // 439\n    {X6^Y6,         X6^Y8,         Y3,            Y7,            }, // 440\n    {X6^Y6,         Y2^X6^Y8,      X3,            Y3,            }, // 441\n    {Y2^X6^Y6,      X2^X6^Y8,      X3,            Y3,            }, // 442\n    {Y6^X7,         Y3,            Y7,            X6^Y7,         }, // 443\n    {Y6^X7,         X3,            Y3,            Y2^X6^Y7,      }, // 444\n    {Y6^X7,         X6^Y7,         Y3,            Y7,            }, // 445\n    {Y6^X7,         Y2^X6^Y7,      X3,            Y3,            }, // 446\n    {X5^Y8,         Y5^X8,         X6^Y7,         Y2^Y6^X7,      }, // 447\n    {X5^Y8,         Y5^X8,         X2^X6^Y7,      Y2^Y6^X7,      }, // 448\n    {Y4^X8,         X5^Y7,         X2^X6^Y6,      Y1^Y5^X7,      }, // 449\n    {X4^Y7,         Y4^X7,         X1^X5^Y6,      Y1^Y5^X6,      }, // 450\n    {Y4^X9,         X6^Y7,         Y5^X8,         Y2^Y6^X7,      }, // 451\n    {X5^Y7,         Y4^X8,         X2^Y5^X7,      Y1^X6^Y6,      }, // 452\n    {X3^Y7,         Y4^X7,         X1^Y5^X6,      Y1^X5^Y6,      }, // 453\n    {Y3,            X6^Y7,         Y5^X8,         Y2^Y6^X7,      }, // 454\n    {Y3,            Y5^X8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 455\n    {X3,            Y3^X8,         X2^Y5^X7,      Y1^X6^Y6,      }, // 456\n    {Y2,            Y3^X6,         X3^Y6,         X1^X5^Y5,      }, // 457\n    {Y3,            X5^Y8,         X6^Y7,         Y2^Y6^X7,      }, // 458\n    {Y3,            X5^Y8,         X2^X6^Y7,      Y2^Y6^X7,      }, // 459\n    {X3,            Y3^X8,         Y2^Y5^X7,      Y1^X6^Y6,      }, // 460\n    {X3,            Y3^X7,         Y2^X6^Y6,      X1^X5^Y7,      }, // 461\n    {X3,            Y3,            X6^Y7,         Y2^Y6^X7,      }, // 462\n    {X3,            Y3,            X2^X6^Y7,      Y2^Y6^X7,      }, // 463\n    {X2,            X3,            Y3^X7,         Y2^Y5^X6,      }, // 464\n    {X2,            X3,            Y3^X6,         Y2^X5^Y6,      }, // 465\n    {Y3,            X6^Y7,         Y2^Y6^X7,      X5^Y6,         }, // 466\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      X5^Y6,         }, // 467\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      Z0^X5^Y6,      }, // 468\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      X1^X5^Y6,      }, // 469\n    {X3,            Y3,            X2^Y6^X7,      Y2^X6^Y7,      }, // 470\n    {X6^Y6,         X3,            Y3,            Y2^Y6^X7,      }, // 471\n    {Y2^X6^Y6,      X3,            Y3,            X2^X6^Y6,      }, // 472\n    {X3,            Y3,            Y2^Y6^X7,      X6^Y6,         }, // 473\n    {Y2^Y6^X7,      X3,            Y3,            X6^Y7,         }, // 474\n    {Y2^Y6^X7,      X6^Y7,         X3,            Y3,            }, // 475\n    {Y4^X8,         X1^X5^Y7,      Y1^Y5^X7,      X2^X6^Y6,      }, // 476\n    {Y4^X7,         Y0^X4^Y7,      X1^X5^Y6,      Y1^Y5^X6,      }, // 477\n    {Y4^X8,         Y1^X5^Y7,      X1^Y5^X7,      Y2^X6^Y6,      }, // 478\n    {Y3^X7,         Y0^X4^Y6,      X1^Y4^X6,      Y1^X5^Y5,      }, // 479\n    {Y3,            X5^Y8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 480\n    {Y3,            Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 481\n    {X3,            Y3^X7,         Y1^X5^Y6,      X1^Y5^X6,      }, // 482\n    {X3,            Y3^X6,         Y1^X4^Y6,      Y2^X5^Y5,      }, // 483\n    {Y3,            X1^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      }, // 484\n    {Y3,            X1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 485\n    {X3,            Y3,            Y1^X5^Y7,      X2^X6^Y6,      }, // 486\n    {X3,            Y3,            X1^X5^Y7,      Y2^X6^Y6,      }, // 487\n    {X3,            Y3,            X1^X5^Y7,      X2^X6^Y6,      }, // 488\n    {Y3,            X2^Y6^X7,      Y1^X6^Y7,      Y2^X5^Y6,      }, // 489\n    {X3,            Y3,            X2^Y6^X7,      Y1^X6^Y7,      }, // 490\n    {X2^X6^Y6,      X3,            Y3,            Y1^X6^Y6,      }, // 491\n    {X2^X6^Y6,      X3,            Y3,            Y2^X6^Y6,      }, // 492\n    {X3,            Y3,            Y1^X6^Y7,      X2^X6^Y6,      }, // 493\n    {Y2^X6^Y6,      X3,            Y3,            Y1^X6^Y7,      }, // 494\n    {Y2^X6^Y6,      Y1^X6^Y8,      X3,            Y3,            }, // 495\n    {Y2^Y6^X7,      X3,            Y3,            Y1^X6^Y7,      }, // 496\n    {X6^X8^Y8,      Y6,            X7,            X8^Y10,        }, // 497\n    {X6^X8^Y8,      Y3,            Y6,            X7^Y10,        }, // 498\n    {X6^X8^Y8,      X3,            Y3,            X7^Y9,         }, // 499\n    {X6^X8^Y8,      Y2,            X3,            Y3^X10,        }, // 500\n    {X6^X8^Y8,      X2,            Y2,            X3^Y8,         }, // 501\n    {Z0^X6^Y6,      X6,            X7,            Y7^X11,        }, // 502\n    {Z0^X6^Y6,      Y3,            X6,            X7^Y10,        }, // 503\n    {Z0^X6^Y6,      X3,            Y3,            X6^Y10,        }, // 504\n    {Z0^X6^Y6,      X6^X9^Y9,      X7,            Y7,            }, // 505\n    {Z0^X6^Y6,      X6^X9^Y9,      Y3,            X7,            }, // 506\n    {Z0^X6^Y6,      X6^X9^Y9,      X3,            Y3,            }, // 507\n    {Z0^X6^Y6,      X6^X9^Y9,      Y2,            X3,            }, // 508\n    {Z0^X6^Y6,      X6^X9^Y9,      X2,            Y2,            }, // 509\n    {Z1^Y6^X7,      X7,            Y7,            X8^Y10,        }, // 510\n    {Z1^Y6^X7,      Y3,            X7,            Y7^X10,        }, // 511\n    {Z1^Y6^X7,      X3,            Y3,            X7^Y9,         }, // 512\n    {Z1^Y6^X7,      Z0^X6^Y7,      X7,            Y7,            }, // 513\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y3,            X7,            }, // 514\n    {Z1^Y6^X7,      Z0^X6^Y7,      X3,            Y3,            }, // 515\n    {Y6^X7,         S0^X6^Y7,      0,             0,             }, // 516\n    {Y5^X7,         S0^X6^Y6,      0,             0,             }, // 517\n    {Y5^X6,         S0^X5^Y6,      0,             0,             }, // 518\n    {Y4^X6,         S0^X5^Y5,      0,             0,             }, // 519\n    {Y4^X5,         S0^X4^Y5,      0,             0,             }, // 520\n    {X6^Y8,         Y6^X8,         S0^X7^Y7,      0,             }, // 521\n    {X6^Y7,         Y5^X8,         S0^Y6^X7,      0,             }, // 522\n    {X5^Y7,         Y5^X7,         S0^X6^Y6,      0,             }, // 523\n    {X5^Y6,         Y4^X7,         S0^Y5^X6,      0,             }, // 524\n    {X3^Y6,         Y4^X6,         S0^X5^Y5,      0,             }, // 525\n    {Y6^X9,         X6^Y9,         Y7^X8,         S0^X7^Y8,      }, // 526\n    {Y5^X9,         X6^Y8,         Y6^X8,         S0^X7^Y7,      }, // 527\n    {Y5^X8,         X5^Y8,         Y6^X7,         S0^X6^Y7,      }, // 528\n    {Y3^X8,         X5^Y7,         Y5^X7,         S0^X6^Y6,      }, // 529\n    {Y3^X7,         X3^Y7,         Y5^X6,         S0^X5^Y6,      }, // 530\n    {Y5,            X6^Y9,         X7^Y8,         Y6^X9,         }, // 531\n    {X3,            Y3^X9,         X6^Y7,         Y5^X8,         }, // 532\n    {Y2,            Y3^X8,         X3^Y7,         Y5^X7,         }, // 533\n    {Y6^X9,         Y7^X8,         S0^X7^Y8,      Z0^X5^Y5,      }, // 534\n    {X6^Y8,         Y6^X8,         S0^X7^Y7,      Z0^X5^Y5,      }, // 535\n    {X5^Y8,         Y6^X7,         S0^X6^Y7,      Z0^X5^Y5,      }, // 536\n    {Y3^X7,         X5^Y7,         S0^X6^Y6,      Z0^X5^Y5,      }, // 537\n    {Y3^X6,         X3^Y7,         S0^X5^Y6,      Z0^X5^Y5,      }, // 538\n    {X6,            Y6,            Y7^X10,        X7^Y10,        }, // 539\n    {Y6,            X7^Y9,         Y7^X9,         S0^X8^Y8,      }, // 540\n    {X6,            X7^Y8,         Y6^X9,         S0^Y7^X8,      }, // 541\n    {Y3,            X6^Y8,         Y6^X8,         S0^X7^Y7,      }, // 542\n    {X3,            Y3^X8,         X6^Y7,         S0^Y6^X7,      }, // 543\n    {Y2,            Y3^X7,         X3^Y7,         S0^X6^Y6,      }, // 544\n    {X6^X8^Y8,      Y6,            X7,            Y7^X11,        }, // 545\n    {X6^X8^Y8,      X3,            Y3,            Y6^X10,        }, // 546\n    {X6^X8^Y8,      X2,            Y2,            Y3^X9,         }, // 547\n    {X6,            X7,            Y7^X10,        Y8^X9,         }, // 548\n    {Z0^Y6^X7,      X7,            Y7,            X8^Y10,        }, // 549\n    {Z0^Y6^X7,      Y3,            X7,            X8^Y9,         }, // 550\n    {Z0^Y6^X7,      X3,            Y3,            X7^Y9,         }, // 551\n    {Z0^Y6^X7,      Z4^X6^Y7,      X7,            Y7,            }, // 552\n    {Z0^Y6^X7,      Z4^X6^Y7,      Y3,            X7,            }, // 553\n    {Z0^Y6^X7,      Z4^X6^Y7,      X3,            Y3,            }, // 554\n    {Z0^Y6^X7,      Z4^X6^Y7,      Y2,            X3,            }, // 555\n    {S0^X6^Y7,      S1^Y6^X7,      0,             0,             }, // 556\n    {S0^Y5^X7,      S1^X6^Y6,      0,             0,             }, // 557\n    {S0^X5^Y6,      S1^Y5^X6,      0,             0,             }, // 558\n    {S0^Y4^X6,      S1^X5^Y5,      0,             0,             }, // 559\n    {S0^X4^Y5,      S1^Y4^X5,      0,             0,             }, // 560\n    {Y5^X9,         S0^X7^Y7,      S1^Y6^X8,      0,             }, // 561\n    {Y5^X8,         S0^X6^Y7,      S1^Y6^X7,      0,             }, // 562\n    {Y4^X8,         S0^X6^Y6,      S1^Y5^X7,      0,             }, // 563\n    {Y4^X7,         S0^X5^Y6,      S1^Y5^X6,      0,             }, // 564\n    {Y3^X7,         S0^X5^Y5,      S1^Y4^X6,      0,             }, // 565\n    {X6^Y9,         Y6^X9,         S0^X7^Y8,      S1^Y7^X8,      }, // 566\n    {X6^Y8,         Y5^X9,         S0^X7^Y7,      S1^Y6^X8,      }, // 567\n    {X5^Y8,         Y5^X8,         S0^X6^Y7,      S1^Y6^X7,      }, // 568\n    {Y3^X8,         X5^Y7,         S0^X6^Y6,      S1^Y5^X7,      }, // 569\n    {Y3^X7,         X3^Y7,         S0^X5^Y6,      S1^Y5^X6,      }, // 570\n    {X6,            X7^Y9,         Y6^X10,        S0^X8^Y8,      }, // 571\n    {Y5,            X6^Y9,         Y6^X9,         S0^X7^Y8,      }, // 572\n    {Y3,            X6^Y8,         Y5^X9,         S0^X7^Y7,      }, // 573\n    {X3,            Y3^X9,         Y5^X8,         S0^X6^Y7,      }, // 574\n    {Y2,            X3^Y7,         Y3^X8,         S0^X6^Y6,      }, // 575\n    {Y6^X9,         S0^X7^Y8,      S1^Y7^X8,      Z0^X5^Y5,      }, // 576\n    {X6^Y8,         S0^Y6^X8,      S1^X7^Y7,      Z0^X5^Y5,      }, // 577\n    {X5^Y8,         S0^X6^Y7,      S1^Y6^X7,      Z0^X5^Y5,      }, // 578\n    {Y3^X8,         S0^X6^Y6,      S1^Y5^X7,      Z0^X5^Y5,      }, // 579\n    {Y3^X6,         X3^Y7,         S0^X5^Y6,      S1^X5^Y5,      }, // 580\n    {X6,            Y6^X10,        X7^Y9,         S0^Y7^X9,      }, // 581\n    {X5,            X6^Y9,         Y6^X9,         S0^X7^Y8,      }, // 582\n    {Y3,            X5^Y9,         X6^Y8,         S0^Y6^X8,      }, // 583\n    {X3,            Y3^X8,         X5^Y8,         S0^X6^Y7,      }, // 584\n    {Y2,            Y3^X8,         X3^Y7,         S0^X6^Y6,      }, // 585\n    {Y6,            X7^Y9,         S0^X8^Y8,      S1^Y7^X9,      }, // 586\n    {X6,            Y6^X9,         S0^X7^Y8,      S1^Y7^X8,      }, // 587\n    {Y3,            X6^Y8,         S0^X7^Y7,      S1^Y6^X8,      }, // 588\n    {X3,            Y3^X8,         S0^X6^Y7,      S1^Y6^X7,      }, // 589\n    {X6,            X7,            Y7^X10,        S0^X8^Y9,      }, // 590\n    {Y3,            X6,            X7^Y9,         S0^Y7^X9,      }, // 591\n    {X3,            Y3,            X6^Y9,         S0^X7^Y8,      }, // 592\n    {Y2,            X3,            Y3^X9,         S0^X7^Y7,      }, // 593\n    {Z3^X6^Y6,      X6,            X7,            Y7^X11,        }, // 594\n    {Z3^X6^Y6,      Y3,            X6,            X7^Y10,        }, // 595\n    {Z3^X6^Y6,      X3,            Y3,            X6^Y10,        }, // 596\n    {Z3^X6^Y6,      X6^X9^Y9,      X7,            Y7,            }, // 597\n    {Z3^X6^Y6,      X6^X9^Y9,      Y3,            X7,            }, // 598\n    {Z3^X6^Y6,      X6^X9^Y9,      X3,            Y3,            }, // 599\n    {Z3^X6^Y6,      X6^X9^Y9,      Y2,            X3,            }, // 600\n    {Z3^X6^Y6,      X6^X9^Y9,      X2,            Y2,            }, // 601\n    {Z4^Y6^X7,      X7,            Y7,            X8^Y10,        }, // 602\n    {Z4^Y6^X7,      Y3,            X7,            Y7^X10,        }, // 603\n    {Z4^Y6^X7,      X3,            Y3,            X7^Y9,         }, // 604\n    {Z4^Y6^X7,      Y2,            X3,            Y3^X9,         }, // 605\n    {S1^Y6^X7,      X2,            Y2,            Y3^X8,         }, // 606\n    {Z4^Y6^X7,      Z3^X6^Y7,      X7,            Y7,            }, // 607\n    {Z4^Y6^X7,      Z3^X6^Y7,      Y3,            X7,            }, // 608\n    {Z4^Y6^X7,      Z3^X6^Y7,      X3,            Y3,            }, // 609\n    {S1^Y6^X7,      S2^X6^Y7,      0,             0,             }, // 610\n    {S1^Y5^X7,      S2^X6^Y6,      0,             0,             }, // 611\n    {S1^Y5^X6,      S2^X5^Y6,      0,             0,             }, // 612\n    {S1^Y4^X6,      S2^X5^Y5,      0,             0,             }, // 613\n    {S1^Y4^X5,      S2^X4^Y5,      0,             0,             }, // 614\n    {S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      0,             }, // 615\n    {S0^X6^Y7,      S1^Y5^X8,      S2^Y6^X7,      0,             }, // 616\n    {S0^X5^Y7,      S1^Y5^X7,      S2^X6^Y6,      0,             }, // 617\n    {S0^X5^Y6,      S1^Y4^X7,      S2^Y5^X6,      0,             }, // 618\n    {Y6^X9,         S0^X6^Y9,      S1^Y7^X8,      S2^X7^Y8,      }, // 619\n    {Y5^X9,         S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      }, // 620\n    {Y5^X8,         S0^X5^Y8,      S1^Y6^X7,      S2^X6^Y7,      }, // 621\n    {Y3^X8,         S0^X5^Y7,      S1^Y5^X7,      S2^X6^Y6,      }, // 622\n    {Y3^X6,         X3^Y7,         S0^X4^Y6,      S1^X5^Y5,      }, // 623\n    {X6,            Y6^X10,        S0^X7^Y9,      S1^Y7^X9,      }, // 624\n    {Y5,            X6^Y9,         S0^X7^Y8,      S1^Y6^X9,      }, // 625\n    {Y3,            Y5^X9,         S0^X6^Y8,      S1^Y6^X8,      }, // 626\n    {X3,            Y3^X9,         S0^X6^Y7,      S1^Y5^X8,      }, // 627\n    {Y2,            Y3^X8,         S0^X5^Y7,      S1^Y5^X7,      }, // 628\n    {S0^X6^Y9,      S1^Y7^X8,      S2^X7^Y8,      Z0^X5^Y5,      }, // 629\n    {S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      Z0^X5^Y5,      }, // 630\n    {S0^X5^Y8,      S1^Y6^X7,      S2^X6^Y7,      Z0^X5^Y5,      }, // 631\n    {Y3^X7,         S0^X5^Y7,      S1^X6^Y6,      S2^X5^Y5,      }, // 632\n    {X5,            X6^Y9,         S0^Y6^X9,      S1^X7^Y8,      }, // 633\n    {Y3,            X5^Y9,         S0^X6^Y8,      S1^Y6^X8,      }, // 634\n    {Y2,            Y3^X7,         X3^Y8,         S0^X5^Y7,      }, // 635\n    {X6,            Y6,            Y7^X10,        S0^X7^Y10,     }, // 636\n    {Y3,            X6,            Y6^X10,        S0^X7^Y9,      }, // 637\n    {X3,            Y3,            Y6^X9,         S0^X6^Y9,      }, // 638\n    {Y2,            X3,            Y3^X9,         S0^X6^Y8,      }, // 639\n    {X2,            Y2,            Y3^X8,         S0^X5^Y8,      }, // 640\n    {Y6,            S0^X7^Y9,      S1^Y7^X9,      S2^X8^Y8,      }, // 641\n    {X6,            S0^X7^Y8,      S1^Y6^X9,      S2^Y7^X8,      }, // 642\n    {Y3,            S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      }, // 643\n    {X3^X8^Y8,      X2,            Y2,            Y3^X9,         }, // 644\n    {X6,            Y7,            S0^X7^Y10,     S1^Y8^X9,      }, // 645\n    {Y3,            X6,            S0^X7^Y9,      S1^Y7^X9,      }, // 646\n    {X3,            Y3,            S0^X6^Y9,      S1^Y7^X8,      }, // 647\n    {Y2,            X3,            Y3^X8,         S0^X6^Y8,      }, // 648\n    {Z2^X6^Y6,      X6,            X7,            Y7^X11,        }, // 649\n    {Z2^X6^Y6,      Y3,            X6,            X7^Y10,        }, // 650\n    {Z2^X6^Y6,      X3,            Y3,            X6^Y10,        }, // 651\n    {Z2^X6^Y6,      Y2,            X3,            Y3^X10,        }, // 652\n    {S2^X6^Y6,      X2,            Y2,            Y3^X8,         }, // 653\n    {Z2^X6^Y6,      X6^X9^Y9,      X7,            Y7,            }, // 654\n    {Z2^X6^Y6,      X6^X9^Y9,      Y3,            X7,            }, // 655\n    {Z2^X6^Y6,      X6^X9^Y9,      X3,            Y3,            }, // 656\n    {Z2^X6^Y6,      X6^X9^Y9,      Y2,            X3,            }, // 657\n    {Z2^X6^Y6,      X3^X9^Y9,      X2,            Y2,            }, // 658\n    {Z3^Y6^X7,      X7,            Y7,            S0^X8^Y10,     }, // 659\n    {Z3^Y6^X7,      Y3,            X7,            S0^X8^Y9,      }, // 660\n    {Z3^Y6^X7,      X3,            Y3,            S0^X7^Y9,      }, // 661\n    {S2^Y6^X7,      Y2,            X3,            Y3^X9,         }, // 662\n    {S2^Y6^X7,      X2,            Y2,            Y3^X8,         }, // 663\n    {Z3^Y6^X7,      Z2^X6^Y7,      X7,            Y7,            }, // 664\n    {Z3^Y6^X7,      Z2^X6^Y7,      Y3,            X7,            }, // 665\n    {Z3^Y6^X7,      Z2^X6^Y7,      X3,            Y3,            }, // 666\n    {Z3^Y6^X7,      Z2^X6^Y7,      Y2,            X3,            }, // 667\n    {Z2^Y6^X7,      S2^X6^Y7,      X2,            Y2,            }, // 668\n    {Y6,            X7^Y8,         Y7^X8,         Z0^X5^Y6,      }, // 669\n    {X6,            X7^Y7,         Y6^X8,         Z0^X5^Y6,      }, // 670\n    {Y3,            X6^Y7,         Y6^X7,         Z0^X5^Y6,      }, // 671\n    {X6^X8^Y8,      Y6,            X7,            Y7^X8,         }, // 672\n    {X6^X8^Y8,      Y3,            Y6,            X7^Y7,         }, // 673\n    {X6^X8^Y8,      X3,            Y3,            Y6^X7,         }, // 674\n    {X6^X8^Y8,      Y2,            X3,            Y3^X7,         }, // 675\n    {X3^X8^Y8,      X2,            Y2,            Y3^X6,         }, // 676\n    {X6,            X7,            Y7^X8,         Z0^X6^Y6,      }, // 677\n    {Y3,            X6,            X7^Y7,         Z0^X6^Y6,      }, // 678\n    {X3,            Y3,            X6^Y7,         Z0^X6^Y6,      }, // 679\n    {Z0^X6^Y6,      X6,            X7,            Y7^X8,         }, // 680\n    {Z0^X6^Y6,      Y3,            X6,            X7^Y7,         }, // 681\n    {Z0^X6^Y6,      X3,            Y3,            X6^Y7,         }, // 682\n    {Z0^X6^Y6,      X3^X9^Y9,      Y2,            Y3,            }, // 683\n    {Y2^X6^Y6,      X3^X9^Y9,      X2,            Y3,            }, // 684\n    {Z1^Y6^X7,      X7,            Y7,            Z0^X6^Y7,      }, // 685\n    {Z1^Y6^X7,      Y3,            X7,            Z0^X6^Y7,      }, // 686\n    {Z1^Y6^X7,      X3,            Y3,            Z0^X6^Y7,      }, // 687\n    {Y4^X8,         X5^Y7,         Y5^X7,         S0^X6^Y6,      }, // 688\n    {Y4^X7,         X4^Y7,         Y5^X6,         S0^X5^Y6,      }, // 689\n    {Y4^X7,         X3^Y7,         Y5^X6,         S0^X5^Y6,      }, // 690\n    {X6,            Y6^X9,         Y7^X8,         S0^X7^Y8,      }, // 691\n    {Y5,            X6^Y8,         Y6^X8,         S0^X7^Y7,      }, // 692\n    {Y3,            Y5^X8,         Y6^X7,         S0^X6^Y7,      }, // 693\n    {X3,            Y3^X8,         Y5^X7,         S0^X6^Y6,      }, // 694\n    {Y2,            Y3^X6,         X3^Y6,         X5^Y5,         }, // 695\n    {X5,            X6^Y8,         Y6^X8,         S0^X7^Y7,      }, // 696\n    {Y3,            X5^Y8,         Y6^X7,         S0^X6^Y7,      }, // 697\n    {X3,            Y3^X7,         X5^Y7,         S0^X6^Y6,      }, // 698\n    {Y2,            Y3^X6,         X3^Y7,         S0^X5^Y6,      }, // 699\n    {X6,            Y6,            Y7^X8,         S0^X7^Y8,      }, // 700\n    {Y3,            X6,            Y6^X8,         S0^X7^Y7,      }, // 701\n    {X3,            Y3,            Y6^X7,         S0^X6^Y7,      }, // 702\n    {Y2,            X3,            Y3^X7,         S0^X6^Y6,      }, // 703\n    {Y6,            Y7^X8,         S0^X7^Y8,      Z0^X5^Y6,      }, // 704\n    {X6,            Y6^X8,         S0^X7^Y7,      Z0^X5^Y6,      }, // 705\n    {Y3,            Y6^X7,         S0^X6^Y7,      Z0^X5^Y6,      }, // 706\n    {X3,            Y3^X7,         S0^X6^Y6,      Z0^X5^Y6,      }, // 707\n    {Y2,            Y3^X6,         X3^Y6,         S0^X5^Y6,      }, // 708\n    {X6^X8^Y8,      Y6,            Y7,            S0^X7^Y8,      }, // 709\n    {X6^X8^Y8,      Y3,            Y6,            S0^X7^Y7,      }, // 710\n    {S0^X8^Y8,      X3,            Y3,            X6^Y6,         }, // 711\n    {S0^X8^Y8,      Y2,            X3,            Y3^X6,         }, // 712\n    {X6,            Y7,            S0^X7^Y8,      Z0^X6^Y6,      }, // 713\n    {Y3,            X6,            S0^X7^Y7,      Z0^X6^Y6,      }, // 714\n    {X3,            Y3,            S0^X6^Y7,      Z0^X6^Y6,      }, // 715\n    {Y2,            X3,            Y3^X6,         S0^X6^Y6,      }, // 716\n    {Z0^X6^Y6,      X6,            Y7,            S0^X7^Y8,      }, // 717\n    {Z0^X6^Y6,      Y3,            X6,            S0^X7^Y7,      }, // 718\n    {Z0^X6^Y6,      X3,            Y3,            S0^X6^Y7,      }, // 719\n    {S0^X6^Y6,      Y2,            X3,            Y3^X6,         }, // 720\n    {Z0^X6^Y6,      X6^X9^Y9,      Y7,            S0^X7,         }, // 721\n    {Z0^X6^Y6,      X6^X9^Y9,      Y3,            S0^X7,         }, // 722\n    {Z0^X6^Y6,      S0^X9^Y9,      X3,            Y3,            }, // 723\n    {S0^X6^Y6,      X3^X9^Y9,      Y2,            Y3,            }, // 724\n    {Z0^Y6^X7,      Y7,            S0^X7,         Z4^X6^Y7,      }, // 725\n    {Z0^Y6^X7,      Y3,            S0^X7,         Z4^X6^Y7,      }, // 726\n    {Z0^Y6^X7,      X3,            Y3,            S0^X6^Y7,      }, // 727\n    {S0^Y6^X7,      X3,            Y3,            Y2^X6^Y7,      }, // 728\n    {Z0^Y6^X7,      Z4^X6^Y7,      Y7,            S0^X7,         }, // 729\n    {Z0^Y6^X7,      Z4^X6^Y7,      Y3,            S0^X7,         }, // 730\n    {Z0^Y6^X7,      S0^X6^Y7,      X3,            Y3,            }, // 731\n    {S0^Y6^X7,      Y2^X6^Y7,      X3,            Y3,            }, // 732\n    {Y5^X9,         X6^Y8,         S0^Y6^X8,      S1^X7^Y7,      }, // 733\n    {Y4^X8,         X5^Y7,         S0^Y5^X7,      S1^X6^Y6,      }, // 734\n    {X4^Y7,         Y4^X7,         S0^X5^Y6,      S1^Y5^X6,      }, // 735\n    {X5^Y7,         Y4^X8,         S0^X6^Y6,      S1^Y5^X7,      }, // 736\n    {X3^Y7,         Y4^X7,         S0^X5^Y6,      S1^Y5^X6,      }, // 737\n    {Y5,            X6^Y8,         S0^X7^Y7,      S1^Y6^X8,      }, // 738\n    {Y3,            Y5^X8,         S0^X6^Y7,      S1^Y6^X7,      }, // 739\n    {X3,            Y3^X8,         S0^X6^Y6,      S1^Y5^X7,      }, // 740\n    {Y2,            Y3^X6,         X3^Y6,         S0^X5^Y5,      }, // 741\n    {X5,            X6^Y8,         S0^Y6^X8,      S1^X7^Y7,      }, // 742\n    {Y3,            X5^Y8,         S0^X6^Y7,      S1^Y6^X7,      }, // 743\n    {X6,            Y6,            S0^X7^Y8,      S1^Y7^X8,      }, // 744\n    {Y3,            X6,            S0^Y6^X8,      S1^X7^Y7,      }, // 745\n    {X3,            Y3,            S0^X6^Y7,      S1^Y6^X7,      }, // 746\n    {Y2,            X3,            Y3^X7,         S0^Y5^X6,      }, // 747\n    {Y6,            S0^X7^Y8,      S1^Y7^X8,      Z0^X5^Y6,      }, // 748\n    {X6,            S0^X7^Y7,      S1^Y6^X8,      Z0^X5^Y6,      }, // 749\n    {Y3,            S0^X6^Y7,      S1^Y6^X7,      Z0^X5^Y6,      }, // 750\n    {Y3,            X6,            S0^X7^Y7,      S1^Y6^X8,      }, // 751\n    {X6^X8^Y8,      Y6,            S0^X7,         S1^Y7^X8,      }, // 752\n    {X6^X8^Y8,      Y3,            S0^X7,         S1^Y6^X8,      }, // 753\n    {S1^X8^Y8,      X3,            Y3,            S0^X6^Y6,      }, // 754\n    {X6,            S0^X7,         S1^Y7^X8,      Z3^X6^Y6,      }, // 755\n    {Y3,            S0^X7,         S1^Y6^X8,      Z3^X6^Y6,      }, // 756\n    {X3,            Y3,            S0^X6^Y7,      S1^X6^Y6,      }, // 757\n    {Z3^X6^Y6,      X6,            S0^X7,         S1^Y7^X8,      }, // 758\n    {Z3^X6^Y6,      Y3,            S0^X7,         S1^Y6^X8,      }, // 759\n    {S1^X6^Y6,      X3,            Y3,            S0^X6^Y7,      }, // 760\n    {Z3^X6^Y6,      X6^X9^Y9,      S0^X7,         S1^Y7,         }, // 761\n    {Z3^X6^Y6,      S1^X9^Y9,      Y3,            S0^X7,         }, // 762\n    {S1^X6^Y6,      S0^X9^Y9,      X3,            Y3,            }, // 763\n    {Z4^Y6^X7,      S0^X7,         S1^Y7,         Z3^X6^Y7,      }, // 764\n    {S1^Y6^X7,      Y3,            S0^X7,         Z3^X6^Y7,      }, // 765\n    {S1^Y6^X7,      X3,            Y3,            S0^X6^Y7,      }, // 766\n    {Z4^Y6^X7,      Z3^X6^Y7,      S0^X7,         S1^Y7,         }, // 767\n    {S1^Y6^X7,      Z3^X6^Y7,      Y3,            S0^X7,         }, // 768\n    {S1^Y6^X7,      S0^X6^Y7,      X3,            Y3,            }, // 769\n    {Y4^X8,         S0^X5^Y7,      S1^Y5^X7,      S2^X6^Y6,      }, // 770\n    {Y4^X7,         S0^X4^Y7,      S1^Y5^X6,      S2^X5^Y6,      }, // 771\n    {Y3^X7,         S0^X4^Y6,      S1^Y4^X6,      S2^X5^Y5,      }, // 772\n    {Y6,            S0^X6^Y9,      S1^Y7^X8,      S2^X7^Y8,      }, // 773\n    {Y5,            S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      }, // 774\n    {Y3,            Y5^X7,         S0^X5^Y7,      S1^X6^Y6,      }, // 775\n    {X3,            Y3^X7,         S0^X5^Y6,      S1^Y5^X6,      }, // 776\n    {Y2,            Y3^X5,         X3^Y6,         S0^X4^Y5,      }, // 777\n    {X5,            S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      }, // 778\n    {Y3,            S0^X5^Y8,      S1^Y6^X7,      S2^X6^Y7,      }, // 779\n    {X3,            Y3^X7,         S0^X5^Y7,      S1^X6^Y6,      }, // 780\n    {Y6,            S0^X6,         S1^Y7^X8,      S2^X7^Y8,      }, // 781\n    {Y3,            S0^X6,         S1^Y6^X8,      S2^X7^Y7,      }, // 782\n    {X3,            Y3,            S0^X5^Y7,      S1^X6^Y6,      }, // 783\n    {Y2,            X3,            Y3^X6,         S0^X5^Y6,      }, // 784\n    {S0^X6,         S1^Y7^X8,      S2^X7^Y8,      Z2^X5^Y6,      }, // 785\n    {S0^X6,         S1^Y6^X8,      S2^X7^Y7,      Z2^X5^Y6,      }, // 786\n    {Y3,            S0^X6^Y7,      S1^Y6^X7,      S2^X5^Y6,      }, // 787\n    {X3,            Y3^X7,         S0^X6^Y6,      S1^X5^Y6,      }, // 788\n    {S2^X8^Y8,      Y6,            S0^X6,         S1^X7^Y7,      }, // 789\n    {S2^X8^Y8,      Y3,            S0^X6,         S1^Y6^X7,      }, // 790\n    {S0^X6,         S1^Y7,         S2^X7^Y8,      Z2^X6^Y6,      }, // 791\n    {Y3,            S0^X6,         S1^X7^Y7,      S2^X6^Y6,      }, // 792\n    {Z2^X6^Y6,      S0^X6,         S1^Y7,         S2^X7^Y8,      }, // 793\n    {S2^X6^Y6,      Y3,            S0^X6,         S1^X7^Y7,      }, // 794\n    {Z2^X6^Y6,      S2^X9^Y9,      S0^X6,         S1^Y7,         }, // 795\n    {S2^X6^Y6,      S1^X9^Y9,      Y3,            S0^X6,         }, // 796\n    {Z2^Y6^X7,      S0^X7,         S1^Y7,         S2^X6^Y7,      }, // 797\n    {S2^Y6^X7,      Y3,            S0^X7,         S1^X6^Y7,      }, // 798\n    {Z2^Y6^X7,      S2^X6^Y7,      S0^X7,         S1^Y7,         }, // 799\n    {S2^Y6^X7,      S1^X6^Y7,      Y3,            S0^X7,         }, // 800\n    {X2,            Z4,            Y4,            X3,            }, // 801\n    {X2,            Z3,            Y4,            X3,            }, // 802\n    {Y3,            X3,            Z4,            X5,            }, // 803\n    {Y3,            X2,            Z4,            X3,            }, // 804\n    {Y3,            X2,            Z3,            X3,            }, // 805\n    {Y2,            X2,            Y3,            X3,            }, // 806\n    {Z3,            X3,            Z4,            X5^Y5,         }, // 807\n    {X2,            Z4,            X3,            Y2^X5^Y5,      }, // 808\n    {X2,            Z3,            X3,            Y2^X5^Y5,      }, // 809\n    {X2,            Y3,            X3,            Y1^X5^Y5,      }, // 810\n    {X2,            Y3,            X3,            X1^X5^Y5,      }, // 811\n    {Y3,            Z3,            X3,            Z4,            }, // 812\n    {Y2,            Y3,            X3,            Z4,            }, // 813\n    {Z3,            X3,            Z4,            X5^Y6,         }, // 814\n    {X2,            Z4,            X3,            Z3^X5^Y6,      }, // 815\n    {X2,            Z3,            X3,            Z2^X5^Y6,      }, // 816\n    {X2,            Y3,            X3,            Z2^X5^Y6,      }, // 817\n    {Z3^X7,         Y3,            X3,            Z4,            }, // 818\n    {Z3^X7,         X2,            Z4,            X3,            }, // 819\n    {Z2^X7,         X2,            Z3,            X3,            }, // 820\n    {Z2^X7,         X2,            Y3,            X3,            }, // 821\n    {Z3,            X3,            Z4,            Y3^X6^Y6,      }, // 822\n    {X2,            Z4,            X3,            Y3^X6^Y6,      }, // 823\n    {X2,            Z3,            X3,            Y3^X6^Y6,      }, // 824\n    {X2,            Y3,            X3,            Y2^X6^Y6,      }, // 825\n    {Y3^X6^Y6,      Z3,            X3,            Z4,            }, // 826\n    {Y3^X6^Y6,      X2,            Z4,            X3,            }, // 827\n    {Y3^X6^Y6,      X2,            Z3,            X3,            }, // 828\n    {Y2^X6^Y6,      X2,            Y3,            X3,            }, // 829\n    {Y3^X6^Y6,      Z3^X8,         X3,            Z4,            }, // 830\n    {X2^X6^Y6,      Z3^X8,         Z4,            X3,            }, // 831\n    {X2^X6^Y6,      Z2^X8,         Z3,            X3,            }, // 832\n    {X2^X6^Y6,      Z2^X8,         Y3,            X3,            }, // 833\n    {Y3^Y6^X7,      X3,            Z4,            Z3^X6^Y7,      }, // 834\n    {Y3^Y6^X7,      Z4,            X3,            X2^X6^Y7,      }, // 835\n    {Y3^Y6^X7,      Z3,            X3,            X2^X6^Y7,      }, // 836\n    {Y2^Y6^X7,      Y3,            X3,            X2^X6^Y7,      }, // 837\n    {Y3^Y6^X7,      Z3^X6^Y7,      X3,            Z4,            }, // 838\n    {Y3^Y6^X7,      X2^X6^Y7,      Z4,            X3,            }, // 839\n    {Y3^Y6^X7,      X2^X6^Y7,      Z3,            X3,            }, // 840\n    {Y2^Y6^X7,      X2^X6^Y7,      Y3,            X3,            }, // 841\n};\n\nconst UINT_64 GFX10_SW_PATTERN_NIBBLE4[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y7^X9,         0,             0,             0,             }, // 1\n    {Y7^X8,         0,             0,             0,             }, // 2\n    {Y6^X8,         0,             0,             0,             }, // 3\n    {Y6^X7,         0,             0,             0,             }, // 4\n    {Y5^X7,         0,             0,             0,             }, // 5\n    {X8^Y8,         0,             0,             0,             }, // 6\n    {X7^Y7,         0,             0,             0,             }, // 7\n    {X6^Y6,         0,             0,             0,             }, // 8\n    {X8^Y9,         Y8^X9,         0,             0,             }, // 9\n    {Y7^X9,         X8^Y8,         0,             0,             }, // 10\n    {X7^Y8,         Y7^X8,         0,             0,             }, // 11\n    {Y6^X8,         X7^Y7,         0,             0,             }, // 12\n    {X6^Y7,         Y6^X7,         0,             0,             }, // 13\n    {X5^Y6,         0,             0,             0,             }, // 14\n    {Z0^X5^Y6,      0,             0,             0,             }, // 15\n    {X8^Y8,         Y7^X9,         0,             0,             }, // 16\n    {X7^Y7,         Y6^X8,         0,             0,             }, // 17\n    {Y7^X11,        X9^Y9,         Y8^X10,        0,             }, // 18\n    {Y7^X10,        X8^Y9,         Y8^X9,         0,             }, // 19\n    {Y6^X10,        X8^Y8,         Y7^X9,         0,             }, // 20\n    {Y6^X9,         X7^Y8,         Y7^X8,         0,             }, // 21\n    {Y3^X9,         X7^Y7,         Y6^X8,         0,             }, // 22\n    {Y8^X9,         X6^Y6,         0,             0,             }, // 23\n    {X8^Y8,         X6^Y6,         0,             0,             }, // 24\n    {Y7^X8,         X6^Y6,         0,             0,             }, // 25\n    {X7^Y7,         Z0^X6^Y6,      0,             0,             }, // 26\n    {X6^Y7,         Z0^X6^Y6,      0,             0,             }, // 27\n    {X8^Y10,        Y8^X10,        X9^Y9,         0,             }, // 28\n    {X7^Y9,         Y7^X9,         X8^Y8,         0,             }, // 29\n    {X6^Y9,         X7^Y8,         Y7^X8,         0,             }, // 30\n    {Y3^X8,         X6^Y8,         X7^Y7,         0,             }, // 31\n    {X8^Y11,        Y8^X11,        X9^Y10,        Y9^X10,        }, // 32\n    {Y7^X11,        X8^Y10,        Y8^X10,        X9^Y9,         }, // 33\n    {X7^Y10,        Y7^X10,        X8^Y9,         Y8^X9,         }, // 34\n    {Y3^X10,        X7^Y9,         Y7^X9,         X8^Y8,         }, // 35\n    {X3^Y9,         Y3^X9,         X7^Y8,         Y7^X8,         }, // 36\n    {X9^Y9,         Y8^X10,        X6^Y7,         0,             }, // 37\n    {X8^Y9,         Y8^X9,         X6^Y7,         0,             }, // 38\n    {X8^Y8,         Y7^X9,         X6^Y7,         0,             }, // 39\n    {X7^Y8,         Y7^X8,         Z0^X6^Y7,      0,             }, // 40\n    {Y3^X8,         X7^Y7,         Z0^X6^Y7,      0,             }, // 41\n    {X8^Y10,        Y7^X11,        X9^Y9,         Y8^X10,        }, // 42\n    {Y3^X10,        X7^Y9,         X8^Y8,         Y7^X9,         }, // 43\n    {Y3^X9,         X3^Y9,         X7^Y8,         Y7^X8,         }, // 44\n    {Y2^X7^Y7,      0,             0,             0,             }, // 45\n    {X2^Y6^X7,      0,             0,             0,             }, // 46\n    {Y1^X6^Y6,      0,             0,             0,             }, // 47\n    {X7^Y9,         X8^Y8,         0,             0,             }, // 48\n    {Y7^X8,         Y2^X7^Y8,      0,             0,             }, // 49\n    {X6^Y8,         X2^X7^Y7,      0,             0,             }, // 50\n    {X5^Y8,         Y1^X6^Y7,      0,             0,             }, // 51\n    {Y6^X8,         Y2^X7^Y7,      0,             0,             }, // 52\n    {Y6^X7,         Y1^X6^Y7,      0,             0,             }, // 53\n    {X7^Y9,         X8^Y8,         Y7^X9,         0,             }, // 54\n    {X7^Y9,         Y7^X9,         Y2^X8^Y8,      0,             }, // 55\n    {X6^Y9,         X7^Y8,         X2^Y7^X8,      0,             }, // 56\n    {X3^Y9,         X6^Y8,         Y1^X7^Y7,      0,             }, // 57\n    {Y2^X7^Y8,      X6^Y6,         0,             0,             }, // 58\n    {X2^X7^Y7,      Z0^X6^Y6,      0,             0,             }, // 59\n    {Y1^X6^Y7,      Z0^X6^Y6,      0,             0,             }, // 60\n    {Y3^X8,         X6^Y8,         Y1^X7^Y7,      0,             }, // 61\n    {Y7^X11,        Y8^X10,        X8^Y10,        X9^Y9,         }, // 62\n    {Y7^X10,        X7^Y10,        Y8^X9,         Y2^X8^Y9,      }, // 63\n    {Y3^X10,        X7^Y9,         Y7^X9,         X2^X8^Y8,      }, // 64\n    {Y3^X9,         X3^Y9,         Y7^X8,         Y1^X7^Y8,      }, // 65\n    {Y7^X9,         Y2^X8^Y8,      X6^Y7,         0,             }, // 66\n    {X7^Y8,         X2^Y7^X8,      Z4^X6^Y7,      0,             }, // 67\n    {X3^Y8,         Y1^X7^Y7,      Z4^X6^Y7,      0,             }, // 68\n    {Y3^X10,        X7^Y9,         Y7^X9,         Y2^X8^Y8,      }, // 69\n    {Y2^Y6^X8,      0,             0,             0,             }, // 70\n    {Y1^X6^Y7,      0,             0,             0,             }, // 71\n    {Y1^Y5^X7,      0,             0,             0,             }, // 72\n    {X7^Y8,         Y2^Y7^X8,      0,             0,             }, // 73\n    {X2^X7^Y8,      Y2^Y7^X8,      0,             0,             }, // 74\n    {X2^X7^Y7,      Y1^Y6^X8,      0,             0,             }, // 75\n    {X1^X6^Y7,      Y1^Y6^X7,      0,             0,             }, // 76\n    {Y6^X9,         Y2^Y7^X8,      0,             0,             }, // 77\n    {X2^Y7^X8,      Y2^X7^Y8,      0,             0,             }, // 78\n    {X2^Y6^X8,      Y1^X7^Y7,      0,             0,             }, // 79\n    {X1^Y6^X7,      Y1^X6^Y7,      0,             0,             }, // 80\n    {Y6^X10,        X2^X8^Y8,      Y2^Y7^X9,      0,             }, // 81\n    {Y6^X9,         Y2^Y7^X8,      Y1^X7^Y8,      0,             }, // 82\n    {Y3^X9,         X1^X7^Y7,      Y1^Y6^X8,      0,             }, // 83\n    {Y2^Y7^X8,      X6^Y6,         0,             0,             }, // 84\n    {Y1^X7^Y7,      Z3^X6^Y6,      0,             0,             }, // 85\n    {X1^X6^Y8,      Y1^X6^Y6,      0,             0,             }, // 86\n    {X7^Y9,         X2^Y7^X9,      Y2^X8^Y8,      0,             }, // 87\n    {X6^Y9,         X2^Y7^X8,      Y1^X7^Y8,      0,             }, // 88\n    {X3^Y8,         X1^Y6^X8,      Y1^X7^Y7,      0,             }, // 89\n    {X7^Y10,        Y7^X10,        X8^Y9,         Y2^Y8^X9,      }, // 90\n    {X7^Y10,        Y7^X10,        X2^X8^Y9,      Y2^Y8^X9,      }, // 91\n    {Y3^X10,        X7^Y9,         X2^X8^Y8,      Y1^Y7^X9,      }, // 92\n    {X3^Y9,         Y3^X9,         X1^X7^Y8,      Y1^Y7^X8,      }, // 93\n    {X2^X8^Y8,      Y2^Y7^X9,      X6^Y7,         0,             }, // 94\n    {Y2^Y7^X8,      Y1^X7^Y8,      Z3^X6^Y7,      0,             }, // 95\n    {Y2^Y7^X8,      X1^X7^Y8,      Z3^X6^Y7,      0,             }, // 96\n    {X7^Y10,        X8^Y9,         Y7^X10,        Y2^Y8^X9,      }, // 97\n    {X7^Y10,        Y7^X10,        X2^Y8^X9,      Y2^X8^Y9,      }, // 98\n    {Y3^X10,        X7^Y9,         X2^Y7^X9,      Y1^X8^Y8,      }, // 99\n    {Y3^X9,         X3^Y9,         X1^Y7^X8,      Y1^X7^Y8,      }, // 100\n    {X1^Y5^X6,      0,             0,             0,             }, // 101\n    {Y2^Y6^X7,      0,             0,             0,             }, // 102\n    {X1^Y6^X7,      0,             0,             0,             }, // 103\n    {Y0^X5^Y7,      X1^X6^Y6,      0,             0,             }, // 104\n    {Z1^X5^Y6,      0,             0,             0,             }, // 105\n    {Y1^X5^Y6,      0,             0,             0,             }, // 106\n    {X1^Y6^X8,      Y2^X7^Y7,      0,             0,             }, // 107\n    {Y2^X7^Y7,      X1^Y6^X8,      0,             0,             }, // 108\n    {X7^Y9,         X2^X8^Y8,      Y2^Y7^X9,      0,             }, // 109\n    {Y1^X7^Y9,      X2^X8^Y8,      Y2^Y7^X9,      0,             }, // 110\n    {X6^Y8,         X1^X7^Y7,      Y1^Y6^X8,      0,             }, // 111\n    {X3^Y8,         Y0^X6^Y7,      X1^Y6^X7,      0,             }, // 112\n    {X2^X7^Y8,      Y1^X6^Y6,      0,             0,             }, // 113\n    {Y2^Y7^X8,      Y1^X6^Y6,      0,             0,             }, // 114\n    {Y1^X7^Y9,      X2^Y7^X9,      Y2^X8^Y8,      0,             }, // 115\n    {Y1^X7^Y8,      X1^Y6^X9,      Y2^Y7^X8,      0,             }, // 116\n    {Y1^X6^Y9,      Y2^X7^Y8,      X1^Y7^X8,      0,             }, // 117\n    {Y7^X10,        Y1^X7^Y10,     X2^X8^Y9,      Y2^Y8^X9,      }, // 118\n    {Y3^X10,        X1^X7^Y9,      Y1^Y7^X9,      X2^X8^Y8,      }, // 119\n    {Y3^X8,         X3^Y9,         Y0^X6^Y8,      X1^X7^Y7,      }, // 120\n    {Y2^Y7^X9,      X2^X8^Y8,      Z2^X6^Y7,      0,             }, // 121\n    {X2^X8^Y8,      Y2^Y7^X9,      Y1^X6^Y7,      0,             }, // 122\n    {Y3^X10,        Y1^X7^Y9,      X1^Y7^X9,      Y2^X8^Y8,      }, // 123\n    {Y3^X10,        Y1^X7^Y9,      Y2^X8^Y8,      X1^Y7^X9,      }, // 124\n    {Y8^X9,         Z0^X6^Y6,      0,             0,             }, // 125\n    {X8^Y8,         Z0^X6^Y6,      0,             0,             }, // 126\n    {Y7^X8,         Z0^X6^Y6,      0,             0,             }, // 127\n    {X9^Y9,         Y8^X10,        Z0^X6^Y7,      0,             }, // 128\n    {X8^Y9,         Y8^X9,         Z0^X6^Y7,      0,             }, // 129\n    {X8^Y8,         Y7^X9,         Z0^X6^Y7,      0,             }, // 130\n    {S0^X8^Y8,      0,             0,             0,             }, // 131\n    {S0^Y7^X8,      0,             0,             0,             }, // 132\n    {S0^X7^Y7,      0,             0,             0,             }, // 133\n    {S0^Y6^X7,      0,             0,             0,             }, // 134\n    {S0^X6^Y6,      0,             0,             0,             }, // 135\n    {Y8^X9,         S0^X8^Y9,      0,             0,             }, // 136\n    {Y7^X9,         S0^X8^Y8,      0,             0,             }, // 137\n    {Y7^X8,         S0^X7^Y8,      0,             0,             }, // 138\n    {Y6^X8,         S0^X7^Y7,      0,             0,             }, // 139\n    {Y6^X7,         S0^X6^Y7,      0,             0,             }, // 140\n    {X8^Y10,        Y8^X10,        S0^X9^Y9,      0,             }, // 141\n    {X8^Y9,         Y7^X10,        S0^Y8^X9,      0,             }, // 142\n    {X7^Y9,         Y7^X9,         S0^X8^Y8,      0,             }, // 143\n    {X7^Y8,         Y6^X9,         S0^Y7^X8,      0,             }, // 144\n    {X3^Y8,         Y6^X8,         S0^X7^Y7,      0,             }, // 145\n    {S0^X8^Y9,      Z0^X6^Y6,      0,             0,             }, // 146\n    {S0^X8^Y8,      Z0^X6^Y6,      0,             0,             }, // 147\n    {S0^X7^Y8,      Z0^X6^Y6,      0,             0,             }, // 148\n    {S0^X7^Y7,      Z0^X6^Y6,      0,             0,             }, // 149\n    {S0^X6^Y7,      Z0^X6^Y6,      0,             0,             }, // 150\n    {Y7^X10,        X8^Y9,         S0^Y8^X9,      0,             }, // 151\n    {X6^Y9,         X7^Y8,         S0^Y7^X8,      0,             }, // 152\n    {Y3^X8,         X6^Y8,         S0^X7^Y7,      0,             }, // 153\n    {Y8^X11,        X8^Y11,        Y9^X10,        S0^X9^Y10,     }, // 154\n    {Y7^X11,        X8^Y10,        Y8^X10,        S0^X9^Y9,      }, // 155\n    {Y7^X10,        X7^Y10,        Y8^X9,         S0^X8^Y9,      }, // 156\n    {Y3^X10,        X7^Y9,         Y7^X9,         S0^X8^Y8,      }, // 157\n    {Y3^X9,         X3^Y9,         Y7^X8,         S0^X7^Y8,      }, // 158\n    {Y8^X10,        S0^X9^Y9,      Z4^X6^Y7,      0,             }, // 159\n    {Y7^X10,        S0^Y8^X9,      Z4^X6^Y7,      0,             }, // 160\n    {Y7^X9,         S0^X8^Y8,      Z4^X6^Y7,      0,             }, // 161\n    {X7^Y8,         S0^Y7^X8,      Z4^X6^Y7,      0,             }, // 162\n    {X3^Y8,         S0^X7^Y7,      Z4^X6^Y7,      0,             }, // 163\n    {S1^Y7^X9,      0,             0,             0,             }, // 164\n    {S1^Y7^X8,      0,             0,             0,             }, // 165\n    {S1^Y6^X8,      0,             0,             0,             }, // 166\n    {S1^Y6^X7,      0,             0,             0,             }, // 167\n    {S1^Y5^X7,      0,             0,             0,             }, // 168\n    {S1^X8^Y8,      0,             0,             0,             }, // 169\n    {S1^X7^Y7,      0,             0,             0,             }, // 170\n    {S0^X8^Y9,      S1^Y8^X9,      0,             0,             }, // 171\n    {S0^Y7^X9,      S1^X8^Y8,      0,             0,             }, // 172\n    {S0^X7^Y8,      S1^Y7^X8,      0,             0,             }, // 173\n    {S0^Y6^X8,      S1^X7^Y7,      0,             0,             }, // 174\n    {S0^X6^Y7,      S1^Y6^X7,      0,             0,             }, // 175\n    {S0^X8^Y8,      S1^Y7^X9,      0,             0,             }, // 176\n    {S0^X7^Y7,      S1^Y6^X8,      0,             0,             }, // 177\n    {Y7^X11,        S0^X9^Y9,      S1^Y8^X10,     0,             }, // 178\n    {Y7^X10,        S0^X8^Y9,      S1^Y8^X9,      0,             }, // 179\n    {Y6^X10,        S0^X8^Y8,      S1^Y7^X9,      0,             }, // 180\n    {Y6^X9,         S0^X7^Y8,      S1^Y7^X8,      0,             }, // 181\n    {Y3^X9,         S0^X7^Y7,      S1^Y6^X8,      0,             }, // 182\n    {S1^Y8^X9,      Z3^X6^Y6,      0,             0,             }, // 183\n    {S1^X8^Y8,      Z3^X6^Y6,      0,             0,             }, // 184\n    {S1^Y7^X8,      Z3^X6^Y6,      0,             0,             }, // 185\n    {S1^Y6^X8,      Z3^X6^Y6,      0,             0,             }, // 186\n    {S0^X6^Y7,      S1^X6^Y6,      0,             0,             }, // 187\n    {X8^Y10,        S0^Y8^X10,     S1^X9^Y9,      0,             }, // 188\n    {X7^Y9,         S0^Y7^X9,      S1^X8^Y8,      0,             }, // 189\n    {X6^Y9,         S0^X7^Y8,      S1^Y7^X8,      0,             }, // 190\n    {X3^Y8,         S0^X7^Y7,      S1^Y6^X8,      0,             }, // 191\n    {X8^Y11,        Y8^X11,        S0^X9^Y10,     S1^Y9^X10,     }, // 192\n    {Y7^X11,        X8^Y10,        S0^Y8^X10,     S1^X9^Y9,      }, // 193\n    {X7^Y10,        Y7^X10,        S0^X8^Y9,      S1^Y8^X9,      }, // 194\n    {Y3^X10,        X7^Y9,         S0^Y7^X9,      S1^X8^Y8,      }, // 195\n    {X3^Y9,         Y3^X9,         S0^X7^Y8,      S1^Y7^X8,      }, // 196\n    {S0^X9^Y9,      S1^Y8^X10,     Z3^X6^Y7,      0,             }, // 197\n    {S0^X8^Y9,      S1^Y8^X9,      Z3^X6^Y7,      0,             }, // 198\n    {S0^X8^Y8,      S1^Y7^X9,      Z3^X6^Y7,      0,             }, // 199\n    {S0^X7^Y8,      S1^Y7^X8,      Z3^X6^Y7,      0,             }, // 200\n    {X3^Y8,         S0^X7^Y7,      Z3^X6^Y7,      0,             }, // 201\n    {X8^Y10,        Y7^X11,        S0^X9^Y9,      S1^Y8^X10,     }, // 202\n    {Y3^X10,        X7^Y9,         S0^X8^Y8,      S1^Y7^X9,      }, // 203\n    {Y3^X9,         X3^Y9,         S0^X7^Y8,      S1^Y7^X8,      }, // 204\n    {S2^X8^Y8,      0,             0,             0,             }, // 205\n    {S2^Y7^X8,      0,             0,             0,             }, // 206\n    {S2^X7^Y7,      0,             0,             0,             }, // 207\n    {S2^Y6^X7,      0,             0,             0,             }, // 208\n    {S2^X6^Y6,      0,             0,             0,             }, // 209\n    {S1^X6^Y6,      0,             0,             0,             }, // 210\n    {S1^Y8^X9,      S2^X8^Y9,      0,             0,             }, // 211\n    {S1^Y7^X9,      S2^X8^Y8,      0,             0,             }, // 212\n    {S1^Y7^X8,      S2^X7^Y8,      0,             0,             }, // 213\n    {S1^Y6^X8,      S2^X7^Y7,      0,             0,             }, // 214\n    {S1^Y6^X7,      S2^X6^Y7,      0,             0,             }, // 215\n    {Z2^X5^Y6,      0,             0,             0,             }, // 216\n    {S1^X5^Y6,      0,             0,             0,             }, // 217\n    {S0^X8^Y10,     S1^Y8^X10,     S2^X9^Y9,      0,             }, // 218\n    {S0^X8^Y9,      S1^Y7^X10,     S2^Y8^X9,      0,             }, // 219\n    {S0^X7^Y9,      S1^Y7^X9,      S2^X8^Y8,      0,             }, // 220\n    {S0^X7^Y8,      S1^Y6^X9,      S2^Y7^X8,      0,             }, // 221\n    {S0^X6^Y8,      S1^Y6^X8,      S2^X7^Y7,      0,             }, // 222\n    {S2^X8^Y9,      Z2^X6^Y6,      0,             0,             }, // 223\n    {S2^X8^Y8,      Z2^X6^Y6,      0,             0,             }, // 224\n    {S2^X7^Y8,      Z2^X6^Y6,      0,             0,             }, // 225\n    {S1^X7^Y7,      S2^X6^Y6,      0,             0,             }, // 226\n    {S0^Y7^X10,     S1^X8^Y9,      S2^Y8^X9,      0,             }, // 227\n    {X3^Y9,         S0^X6^Y8,      S1^X7^Y7,      0,             }, // 228\n    {Y8^X11,        S0^X8^Y11,     S1^Y9^X10,     S2^X9^Y10,     }, // 229\n    {Y7^X11,        S0^X8^Y10,     S1^Y8^X10,     S2^X9^Y9,      }, // 230\n    {Y7^X10,        S0^X7^Y10,     S1^Y8^X9,      S2^X8^Y9,      }, // 231\n    {Y3^X10,        S0^X7^Y9,      S1^Y7^X9,      S2^X8^Y8,      }, // 232\n    {Y3^X9,         S0^X6^Y9,      S1^Y7^X8,      S2^X7^Y8,      }, // 233\n    {S1^Y8^X10,     S2^X9^Y9,      Z2^X6^Y7,      0,             }, // 234\n    {S1^Y7^X10,     S2^Y8^X9,      Z2^X6^Y7,      0,             }, // 235\n    {S1^Y7^X9,      S2^X8^Y8,      Z2^X6^Y7,      0,             }, // 236\n    {S0^X7^Y8,      S1^Y7^X8,      Z2^X6^Y7,      0,             }, // 237\n    {X3^Y8,         S0^X7^Y7,      S1^X6^Y7,      0,             }, // 238\n};\n\nconst UINT_8 GFX10_DCC_64K_R_X_PATIDX[] =\n{\n       0, // 1 pipes 1 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       1, // 1 pipes 2 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       2, // 1 pipes 4 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       3, // 1 pipes 8 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       4, // 1 pipes 16 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       5, // 2 pipes 1 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       6, // 2 pipes 2 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       2, // 2 pipes 4 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       3, // 2 pipes 8 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       4, // 2 pipes 16 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       7, // 4+ pipes 1 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       6, // 4+ pipes 2 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       2, // 4+ pipes 4 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       3, // 4+ pipes 8 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       4, // 4+ pipes 16 bpe ua @ SW_64K_R_X 1xaa @ Navi1x\n       0, // 1 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       1, // 1 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       2, // 1 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       3, // 1 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       4, // 1 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       8, // 2 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n       9, // 2 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      10, // 2 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      11, // 2 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      12, // 2 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      13, // 4 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      14, // 4 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      15, // 4 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      16, // 4 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      17, // 4 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      18, // 8 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      19, // 8 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      20, // 8 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      21, // 8 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      22, // 8 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      23, // 16 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      24, // 16 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      25, // 16 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      26, // 16 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      27, // 16 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      28, // 32 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      29, // 32 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      30, // 32 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      31, // 32 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      32, // 32 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      33, // 64 pipes 1 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      34, // 64 pipes 2 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      35, // 64 pipes 4 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      36, // 64 pipes 8 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n      37, // 64 pipes 16 bpe pa @ SW_64K_R_X 1xaa @ Navi1x\n};\n\nconst UINT_8 GFX10_HTILE_PATIDX[] =\n{\n       0, // 1xaa ua @ HTILE_64K @ Navi1x\n       0, // 2xaa ua @ HTILE_64K @ Navi1x\n       0, // 4xaa ua @ HTILE_64K @ Navi1x\n       0, // 8xaa ua @ HTILE_64K @ Navi1x\n       0, // 1 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       0, // 1 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       0, // 1 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       0, // 1 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       1, // 2 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       1, // 2 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       1, // 2 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       1, // 2 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       2, // 4 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       2, // 4 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       2, // 4 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       2, // 4 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       3, // 8 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       3, // 8 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       3, // 8 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       3, // 8 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       4, // 16 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       4, // 16 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       4, // 16 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       5, // 16 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       6, // 32 pipes 1xaa pa @ HTILE_64K @ Navi1x\n       6, // 32 pipes 2xaa pa @ HTILE_64K @ Navi1x\n       7, // 32 pipes 4xaa pa @ HTILE_64K @ Navi1x\n       8, // 32 pipes 8xaa pa @ HTILE_64K @ Navi1x\n       9, // 64 pipes 1xaa pa @ HTILE_64K @ Navi1x\n      10, // 64 pipes 2xaa pa @ HTILE_64K @ Navi1x\n      11, // 64 pipes 4xaa pa @ HTILE_64K @ Navi1x\n      12, // 64 pipes 8xaa pa @ HTILE_64K @ Navi1x\n};\n\nconst UINT_8 GFX10_CMASK_64K_PATIDX[] =\n{\n       0, // 1 bpe ua @ CMASK_64K @ Navi1x\n       0, // 2 bpe ua @ CMASK_64K @ Navi1x\n       0, // 4 bpe ua @ CMASK_64K @ Navi1x\n       0, // 8 bpe ua @ CMASK_64K @ Navi1x\n       0, // 1 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       0, // 1 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       0, // 1 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       0, // 1 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       1, // 2 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       1, // 2 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       1, // 2 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       1, // 2 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       2, // 4 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       2, // 4 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       2, // 4 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       2, // 4 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       3, // 8 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       3, // 8 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       3, // 8 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       3, // 8 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       4, // 16 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       4, // 16 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       4, // 16 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       4, // 16 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       5, // 32 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       5, // 32 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       5, // 32 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       5, // 32 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n       6, // 64 pipes 1 bpe pa @ CMASK_64K @ Navi1x\n       6, // 64 pipes 2 bpe pa @ CMASK_64K @ Navi1x\n       6, // 64 pipes 4 bpe pa @ CMASK_64K @ Navi1x\n       7, // 64 pipes 8 bpe pa @ CMASK_64K @ Navi1x\n};\n\nconst UINT_8 GFX10_DCC_64K_R_X_RBPLUS_PATIDX[] =\n{\n       0, // 1 bpe ua @ SW_64K_R_X 1xaa @ RbPlus\n       1, // 2 bpe ua @ SW_64K_R_X 1xaa @ RbPlus\n       2, // 4 bpe ua @ SW_64K_R_X 1xaa @ RbPlus\n       3, // 8 bpe ua @ SW_64K_R_X 1xaa @ RbPlus\n       4, // 16 bpe ua @ SW_64K_R_X 1xaa @ RbPlus\n       0, // 1 pipes (1 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n       1, // 1 pipes (1 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n       2, // 1 pipes (1 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n       3, // 1 pipes (1 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n       4, // 1 pipes (1 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      38, // 2 pipes (1-2 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      39, // 2 pipes (1-2 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      40, // 2 pipes (1-2 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      41, // 2 pipes (1-2 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      42, // 2 pipes (1-2 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      43, // 4 pipes (1-2 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      44, // 4 pipes (1-2 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      45, // 4 pipes (1-2 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      46, // 4 pipes (1-2 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      47, // 4 pipes (1-2 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      48, // 8 pipes (2 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      49, // 8 pipes (2 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      50, // 8 pipes (2 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      51, // 8 pipes (2 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      52, // 8 pipes (2 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      53, // 4 pipes (4 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      54, // 4 pipes (4 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      55, // 4 pipes (4 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      56, // 4 pipes (4 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      57, // 4 pipes (4 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      58, // 8 pipes (4 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      59, // 8 pipes (4 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      60, // 8 pipes (4 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      61, // 8 pipes (4 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      62, // 8 pipes (4 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      63, // 16 pipes (4 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      64, // 16 pipes (4 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      65, // 16 pipes (4 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      66, // 16 pipes (4 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      67, // 16 pipes (4 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      68, // 8 pipes (8 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      69, // 8 pipes (8 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      70, // 8 pipes (8 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      71, // 8 pipes (8 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      72, // 8 pipes (8 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      73, // 16 pipes (8 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      74, // 16 pipes (8 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      75, // 16 pipes (8 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      76, // 16 pipes (8 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      77, // 16 pipes (8 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      78, // 32 pipes (8 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      79, // 32 pipes (8 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      80, // 32 pipes (8 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      81, // 32 pipes (8 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      82, // 32 pipes (8 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      83, // 16 pipes (16 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      84, // 16 pipes (16 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      85, // 16 pipes (16 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      86, // 16 pipes (16 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      87, // 16 pipes (16 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      88, // 32 pipes (16 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      89, // 32 pipes (16 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      90, // 32 pipes (16 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      91, // 32 pipes (16 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      92, // 32 pipes (16 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      93, // 64 pipes (16 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      94, // 64 pipes (16 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      95, // 64 pipes (16 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      96, // 64 pipes (16 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      97, // 64 pipes (16 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      98, // 32 pipes (32 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n      99, // 32 pipes (32 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     100, // 32 pipes (32 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     101, // 32 pipes (32 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     102, // 32 pipes (32 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     103, // 64 pipes (32 PKRs) 1 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     104, // 64 pipes (32 PKRs) 2 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     105, // 64 pipes (32 PKRs) 4 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     106, // 64 pipes (32 PKRs) 8 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n     107, // 64 pipes (32 PKRs) 16 bpe pa @ SW_64K_R_X 1xaa @ RbPlus\n};\n\nconst UINT_8 GFX10_HTILE_RBPLUS_PATIDX[] =\n{\n       0, // 1xaa ua @ HTILE_64K @ RbPlus\n       0, // 2xaa ua @ HTILE_64K @ RbPlus\n       0, // 4xaa ua @ HTILE_64K @ RbPlus\n       0, // 8xaa ua @ HTILE_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      14, // 4 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      14, // 4 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      14, // 4 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      14, // 4 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      15, // 8 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      15, // 8 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      15, // 8 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      15, // 8 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (4 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (4 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (4 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      13, // 2 pipes (4 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      16, // 4 pipes (4 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      16, // 4 pipes (4 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      16, // 4 pipes (4 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      16, // 4 pipes (4 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      17, // 8 pipes (4 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      17, // 8 pipes (4 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      17, // 8 pipes (4 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      17, // 8 pipes (4 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      18, // 16 pipes (4 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      18, // 16 pipes (4 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      18, // 16 pipes (4 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      18, // 16 pipes (4 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      19, // 4 pipes (8 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      19, // 4 pipes (8 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      19, // 4 pipes (8 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      19, // 4 pipes (8 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      20, // 8 pipes (8 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      20, // 8 pipes (8 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      20, // 8 pipes (8 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      20, // 8 pipes (8 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      21, // 16 pipes (8 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      21, // 16 pipes (8 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      21, // 16 pipes (8 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      21, // 16 pipes (8 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      22, // 32 pipes (8 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      22, // 32 pipes (8 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      22, // 32 pipes (8 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      22, // 32 pipes (8 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      23, // 8 pipes (16 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      23, // 8 pipes (16 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      23, // 8 pipes (16 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      23, // 8 pipes (16 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      24, // 16 pipes (16 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      24, // 16 pipes (16 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      24, // 16 pipes (16 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      24, // 16 pipes (16 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      25, // 32 pipes (16 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      25, // 32 pipes (16 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      25, // 32 pipes (16 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      25, // 32 pipes (16 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      26, // 64 pipes (16 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      26, // 64 pipes (16 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      26, // 64 pipes (16 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      26, // 64 pipes (16 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      28, // 32 pipes (32 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      28, // 32 pipes (32 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      28, // 32 pipes (32 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      28, // 32 pipes (32 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 1xaa pa @ HTILE_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 2xaa pa @ HTILE_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 4xaa pa @ HTILE_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 8xaa pa @ HTILE_64K @ RbPlus\n};\n\nconst UINT_8 GFX10_CMASK_64K_RBPLUS_PATIDX[] =\n{\n       0, // 1 bpe ua @ CMASK_64K @ RbPlus\n       0, // 2 bpe ua @ CMASK_64K @ RbPlus\n       0, // 4 bpe ua @ CMASK_64K @ RbPlus\n       0, // 8 bpe ua @ CMASK_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (4 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (4 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (4 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n       8, // 2 pipes (4 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      11, // 4 pipes (4 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      11, // 4 pipes (4 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      11, // 4 pipes (4 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      11, // 4 pipes (4 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      12, // 8 pipes (4 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      12, // 8 pipes (4 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      12, // 8 pipes (4 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      12, // 8 pipes (4 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      13, // 16 pipes (4 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      13, // 16 pipes (4 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      13, // 16 pipes (4 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      13, // 16 pipes (4 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      14, // 4 pipes (8 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      14, // 4 pipes (8 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      14, // 4 pipes (8 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      14, // 4 pipes (8 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      15, // 8 pipes (8 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      15, // 8 pipes (8 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      15, // 8 pipes (8 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      16, // 8 pipes (8 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      15, // 16 pipes (8 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      15, // 16 pipes (8 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      15, // 16 pipes (8 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      17, // 16 pipes (8 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      18, // 32 pipes (8 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      18, // 32 pipes (8 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      18, // 32 pipes (8 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      19, // 32 pipes (8 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      20, // 8 pipes (16 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      20, // 8 pipes (16 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      20, // 8 pipes (16 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      21, // 8 pipes (16 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      22, // 16 pipes (16 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      22, // 16 pipes (16 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      22, // 16 pipes (16 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      23, // 16 pipes (16 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      22, // 32 pipes (16 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      22, // 32 pipes (16 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      22, // 32 pipes (16 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      24, // 32 pipes (16 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      25, // 64 pipes (16 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      25, // 64 pipes (16 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      25, // 64 pipes (16 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      32, // 64 pipes (16 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      27, // 16 pipes (32 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      28, // 16 pipes (32 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      29, // 32 pipes (32 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      29, // 32 pipes (32 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      29, // 32 pipes (32 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      33, // 32 pipes (32 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 1 bpe pa @ CMASK_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 2 bpe pa @ CMASK_64K @ RbPlus\n      29, // 64 pipes (32 PKRs) 4 bpe pa @ CMASK_64K @ RbPlus\n      34, // 64 pipes (32 PKRs) 8 bpe pa @ CMASK_64K @ RbPlus\n};\n\nconst UINT_8 GFX10_CMASK_VAR_RBPLUS_PATIDX[] =\n{\n       0, // 1 bpe ua @ CMASK_VAR @ RbPlus\n       0, // 2 bpe ua @ CMASK_VAR @ RbPlus\n       0, // 4 bpe ua @ CMASK_VAR @ RbPlus\n       0, // 8 bpe ua @ CMASK_VAR @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n       0, // 1 pipes (1-2 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (1-2 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n       9, // 4 pipes (1-2 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      10, // 8 pipes (1-2 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (4 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (4 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (4 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n       8, // 2 pipes (4 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      11, // 4 pipes (4 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      11, // 4 pipes (4 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      11, // 4 pipes (4 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      11, // 4 pipes (4 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      12, // 8 pipes (4 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      12, // 8 pipes (4 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      12, // 8 pipes (4 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      12, // 8 pipes (4 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      13, // 16 pipes (4 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      13, // 16 pipes (4 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      13, // 16 pipes (4 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      13, // 16 pipes (4 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      14, // 4 pipes (8 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      14, // 4 pipes (8 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      14, // 4 pipes (8 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      14, // 4 pipes (8 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 8 pipes (8 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 8 pipes (8 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 8 pipes (8 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      16, // 8 pipes (8 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 16 pipes (8 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 16 pipes (8 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      15, // 16 pipes (8 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      17, // 16 pipes (8 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      18, // 32 pipes (8 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      18, // 32 pipes (8 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      18, // 32 pipes (8 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      19, // 32 pipes (8 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      20, // 8 pipes (16 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      20, // 8 pipes (16 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      20, // 8 pipes (16 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      21, // 8 pipes (16 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 16 pipes (16 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 16 pipes (16 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 16 pipes (16 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      23, // 16 pipes (16 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 32 pipes (16 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 32 pipes (16 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      22, // 32 pipes (16 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      24, // 32 pipes (16 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      25, // 64 pipes (16 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      25, // 64 pipes (16 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      25, // 64 pipes (16 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      26, // 64 pipes (16 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      27, // 16 pipes (32 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      27, // 16 pipes (32 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      27, // 16 pipes (32 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      28, // 16 pipes (32 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 32 pipes (32 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 32 pipes (32 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 32 pipes (32 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      30, // 32 pipes (32 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 64 pipes (32 PKRs) 1 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 64 pipes (32 PKRs) 2 bpe pa @ CMASK_VAR @ RbPlus\n      29, // 64 pipes (32 PKRs) 4 bpe pa @ CMASK_VAR @ RbPlus\n      31, // 64 pipes (32 PKRs) 8 bpe pa @ CMASK_VAR @ RbPlus\n};\n\nconst UINT_64 GFX10_DCC_64K_R_X_SW_PATTERN[][17] =\n{\n    {0,             X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            0,             0,             0,             0,             }, //0\n    {0,             Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            0,             0,             0,             0,             }, //1\n    {0,             X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            0,             0,             0,             0,             }, //2\n    {0,             Y2,            X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            0,             0,             0,             0,             }, //3\n    {0,             X2,            Y2,            X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            0,             0,             0,             0,             }, //4\n    {0,             X3^Y3,         X4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            0,             0,             0,             0,             }, //5\n    {0,             X3^Y3,         X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            0,             0,             0,             0,             }, //6\n    {0,             X3^Y3,         X4^Y4,         X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            0,             0,             0,             0,             }, //7\n    {0,             X4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z0^X3^Y3,      Y8,            X9,            Y9,            0,             0,             0,             0,             }, //8\n    {0,             Y4,            X4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z0^X3^Y3,      X8,            Y8,            X9,            0,             0,             0,             0,             }, //9\n    {0,             X3,            Y4,            X4,            X5,            Y5,            X6,            Y6,            X7,            Z0^X3^Y3,      Y7,            X8,            Y8,            0,             0,             0,             0,             }, //10\n    {0,             Y2,            X3,            Y4,            X4,            X5,            Y5,            X6,            Y6,            Z0^X3^Y3,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //11\n    {0,             X2,            Y2,            X3,            Y4,            X4,            X5,            Y5,            X6,            Z0^X3^Y3,      Y6,            X7,            Y7,            0,             0,             0,             0,             }, //12\n    {0,             X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Z1^X3^Y3,      Z0^X4^Y4,      X9,            Y9,            0,             0,             0,             0,             }, //13\n    {0,             Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z1^X3^Y3,      Z0^X4^Y4,      Y8,            X9,            0,             0,             0,             0,             }, //14\n    {0,             X3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z1^X3^Y3,      Z0^X4^Y4,      X8,            Y8,            0,             0,             0,             0,             }, //15\n    {0,             Y2,            X3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Z1^X3^Y3,      Z0^X4^Y4,      Y7,            X8,            0,             0,             0,             0,             }, //16\n    {0,             X2,            Y2,            X3,            Y4,            X5,            Y5,            X6,            Y6,            Z1^X3^Y3,      Z0^X4^Y4,      X7,            Y7,            0,             0,             0,             0,             }, //17\n    {0,             Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y9,            0,             0,             0,             0,             }, //18\n    {0,             Y4,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X9,            0,             0,             0,             0,             }, //19\n    {0,             X3,            Y4,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y8,            0,             0,             0,             0,             }, //20\n    {0,             Y2,            X3,            Y4,            Y5,            X6,            Y6,            X7,            Y7,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X8,            0,             0,             0,             0,             }, //21\n    {0,             X2,            Y2,            X3,            Y4,            Y5,            X6,            Y6,            X7,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            0,             0,             0,             0,             }, //22\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //23\n    {0,             Y4,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //24\n    {0,             X3,            Y4,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //25\n    {0,             Y2,            X3,            Y4,            X6,            Y6,            X7,            Y7,            X8,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //26\n    {0,             X2,            Y2,            X3,            Y4,            X6,            Y6,            X7,            Y7,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //27\n    {0,             Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //28\n    {0,             Y4,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //29\n    {0,             X3,            Y4,            Y6,            X7,            Y7,            X8,            Y8,            X9,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //30\n    {0,             Y2,            X3,            Y4,            Y6,            X7,            Y7,            X8,            Y8,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //31\n    {0,             X2,            X3,            Y4,            Y6,            X7,            Y7,            Y2,            X8,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      Y2^X6^Y6,      0,             0,             0,             }, //32\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //33\n    {0,             Y4,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //34\n    {0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //35\n    {0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            Y2,            X9,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y2^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //36\n    {0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            X2,            Y2,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      0,             0,             }, //37\n    {0,             Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z0^X4^Y4,      Y8,            X9,            Y9,            0,             0,             0,             0,             }, //38\n    {0,             Y3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z0^X4^Y4,      X8,            Y8,            X9,            0,             0,             0,             0,             }, //39\n    {0,             X3,            Y3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Z0^X4^Y4,      Y7,            X8,            Y8,            0,             0,             0,             0,             }, //40\n    {0,             Y2,            X3,            Y3,            Y4,            X5,            Y5,            X6,            Y6,            Z0^X4^Y4,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //41\n    {0,             X2,            Y2,            X3,            Y3,            Y4,            X5,            Y5,            X6,            Z0^X4^Y4,      Y6,            X7,            Y7,            0,             0,             0,             0,             }, //42\n    {0,             X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X5^Y5,      Z0^X4^Y4,      X9,            Y9,            0,             0,             0,             0,             }, //43\n    {0,             Y3,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X5^Y5,      Z0^X4^Y4,      Y8,            X9,            0,             0,             0,             0,             }, //44\n    {0,             X3,            Y3,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Y4^X5^Y5,      Z0^X4^Y4,      X8,            Y8,            0,             0,             0,             0,             }, //45\n    {0,             Y2,            X3,            Y3,            X5,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      Y7,            X8,            0,             0,             0,             0,             }, //46\n    {0,             X2,            Y2,            X3,            Y3,            X5,            Y5,            X6,            Y6,            Y4^X5^Y5,      Z0^X4^Y4,      X7,            Y7,            0,             0,             0,             0,             }, //47\n    {0,             Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y9,            0,             0,             0,             0,             }, //48\n    {0,             Y3,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      X9,            0,             0,             0,             0,             }, //49\n    {0,             X3,            Y3,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y8,            0,             0,             0,             0,             }, //50\n    {0,             Y2,            X3,            Y3,            Y5,            X6,            Y6,            X7,            Y7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      X8,            0,             0,             0,             0,             }, //51\n    {0,             X2,            Y2,            X3,            Y3,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^X6^Y6,      Y7,            0,             0,             0,             0,             }, //52\n    {0,             X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y9,            0,             0,             0,             0,             }, //53\n    {0,             Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         X9,            0,             0,             0,             0,             }, //54\n    {0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y8,            0,             0,             0,             0,             }, //55\n    {0,             Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         X8,            0,             0,             0,             0,             }, //56\n    {0,             X2,            Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y7,            0,             0,             0,             0,             }, //57\n    {0,             X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y9,            0,             0,             0,             0,             }, //58\n    {0,             Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X9,            0,             0,             0,             0,             }, //59\n    {0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y8,            0,             0,             0,             0,             }, //60\n    {0,             Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X8,            0,             0,             0,             0,             }, //61\n    {0,             X2,            Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            0,             0,             0,             0,             }, //62\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      0,             0,             0,             0,             }, //63\n    {0,             Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      0,             0,             0,             0,             }, //64\n    {0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      0,             0,             0,             0,             }, //65\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      0,             0,             0,             0,             }, //66\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^X7^Y7,      0,             0,             0,             0,             }, //67\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //68\n    {0,             Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //69\n    {0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //70\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //71\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //72\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //73\n    {0,             Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //74\n    {0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //75\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //76\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //77\n    {0,             Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^X8^Y8,      0,             0,             0,             }, //78\n    {0,             Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^X8^Y8,      0,             0,             0,             }, //79\n    {0,             X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^X8^Y8,      0,             0,             0,             }, //80\n    {0,             Y2,            X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^X8^Y8,      0,             0,             0,             }, //81\n    {0,             X2,            Y2,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X3^X8^Y8,      0,             0,             0,             }, //82\n    {0,             X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //83\n    {0,             Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //84\n    {0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //85\n    {0,             Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //86\n    {0,             X2,            X3,            Y3,            X6,            X7,            Y7,            Y2,            X8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      X6^Y6,         0,             0,             0,             }, //87\n    {0,             X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //88\n    {0,             Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //89\n    {0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //90\n    {0,             Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //91\n    {0,             X2,            X3,            Y3,            X6,            X7,            Y7,            Y2,            X8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      Y2^X6^Y6,      0,             0,             0,             }, //92\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^X9^Y9,      0,             0,             }, //93\n    {0,             Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^X9^Y9,      0,             0,             }, //94\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^X9^Y9,      0,             0,             }, //95\n    {0,             Y2,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X3^X9^Y9,      0,             0,             }, //96\n    {0,             X2,            Y3,            X6,            X7,            Y7,            X8,            Y2,            Y8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      Y2^X6^Y6,      X3^X9^Y9,      0,             0,             }, //97\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //98\n    {0,             Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //99\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //100\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y2,            X9,            Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y2^Y6^X7,      X6^Y7,         0,             0,             }, //101\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X2,            Y2,            Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y2^Y6^X7,      X6^Y7,         0,             0,             }, //102\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //103\n    {0,             Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //104\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //105\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y2,            X9,            Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y2^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //106\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X2,            Y2,            Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      0,             0,             }, //107\n};\n\nconst UINT_64 GFX10_HTILE_SW_PATTERN[][18] =\n{\n    {0,             0,             0,             X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            0,             0,             0,             0,             0,             }, //0\n    {0,             0,             0,             X3,            Y4,            X4,            X5,            Y5,            X6,            Z0^X3^Y3,      Y6,            X7,            Y7,            0,             0,             0,             0,             0,             }, //1\n    {0,             0,             0,             X3,            Y4,            X5,            Y5,            X6,            Y6,            Z1^X3^Y3,      Z0^X4^Y4,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //2\n    {0,             0,             0,             X3,            Y4,            Y5,            X6,            Y6,            X7,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            X8,            Y8,            0,             0,             0,             }, //3\n    {0,             0,             0,             X3,            Y4,            X6,            Y6,            X7,            Y7,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X8,            Y8,            X9,            0,             0,             }, //4\n    {0,             0,             0,             X3,            Y4,            X6,            Y6,            X7,            Y7,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X8,            Y8,            X9,            0,             0,             }, //5\n    {0,             0,             0,             X3,            Y4,            Y6,            X7,            Y7,            X8,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      Y8,            X9,            Y9,            0,             }, //6\n    {0,             0,             0,             X3,            Y4,            Y6,            X7,            Y7,            X8,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      X6^Y6,         Y8,            X9,            Y9,            0,             }, //7\n    {0,             0,             0,             X3,            Y4,            Y6,            X7,            Y7,            X8,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         Y8,            X9,            Y9,            0,             }, //8\n    {0,             0,             0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      X9,            Y9,            X10,           }, //9\n    {0,             0,             0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Z0^Y6^X7,      X6^Y7,         X9,            Y9,            X10,           }, //10\n    {0,             0,             0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y6^X7,         X6^Y7,         X9,            Y9,            X10,           }, //11\n    {0,             0,             0,             X3,            Y4,            X7,            Y7,            X8,            Y8,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         X9,            Y9,            X10,           }, //12\n    {0,             0,             0,             X3,            Y3,            Y4,            X5,            Y5,            X6,            Z0^X4^Y4,      Y6,            X7,            Y7,            0,             0,             0,             0,             0,             }, //13\n    {0,             0,             0,             X3,            Y3,            X5,            Y5,            X6,            Y6,            Y4^X5^Y5,      Z0^X4^Y4,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //14\n    {0,             0,             0,             X3,            Y3,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y7,            X8,            Y8,            0,             0,             0,             }, //15\n    {0,             0,             0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Y7,            X8,            Y8,            X5^Y5,         0,             0,             0,             }, //16\n    {0,             0,             0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            X8,            Y8,            0,             0,             0,             }, //17\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         X8,            Y8,            X9,            0,             0,             }, //18\n    {0,             0,             0,             X3,            Y3,            Y4,            X5,            X6,            Y6,            Z1^X4^Y4,      Z0^X5^Y5,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //19\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X8,            Y8,            X9,            X5^Y6,         0,             0,             }, //20\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X8,            Y8,            X9,            0,             0,             }, //21\n    {0,             0,             0,             X3,            Y3,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         Y8,            X9,            Y9,            0,             }, //22\n    {0,             0,             0,             X3,            Y3,            Y4,            X6,            Y6,            X7,            Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         Y7,            X8,            Y8,            0,             0,             0,             }, //23\n    {0,             0,             0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         Y8,            X9,            Y9,            X6^Y6,         0,             }, //24\n    {0,             0,             0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         Y8,            X9,            Y9,            0,             }, //25\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         X9,            Y9,            X10,           }, //26\n    {0,             0,             0,             X3,            Y3,            Y4,            X6,            X7,            Y7,            Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X8,            Y8,            X9,            0,             0,             }, //27\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X9,            Y9,            X10,           X6^Y7,         }, //28\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         X9,            Y9,            X10,           }, //29\n};\n\nconst UINT_64 GFX10_CMASK_SW_PATTERN[][17] =\n{\n    {X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            0,             0,             0,             0,             }, //0\n    {X3,            Y4,            X4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z0^X3^Y3,      X8,            Y8,            X9,            0,             0,             0,             0,             }, //1\n    {X3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z1^X3^Y3,      Z0^X4^Y4,      Y8,            X9,            0,             0,             0,             0,             }, //2\n    {X3,            Y4,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Z2^X3^Y3,      Z1^X4^Y4,      Z0^X5^Y5,      X9,            0,             0,             0,             0,             }, //3\n    {X3,            Y4,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            X3^Y3^Z3,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //4\n    {X3,            Y4,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //5\n    {X3,            Y4,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           X3^Y3^Z5,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //6\n    {X3,            Y4,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           X3^Y3^Z4,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y6^X7,         Z0^X6^Y7,      0,             0,             }, //7\n    {X3,            Y3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z0^X4^Y4,      X8,            Y8,            X9,            0,             0,             0,             0,             }, //8\n    {X3,            Y3,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X5^Y5,      Z0^X4^Y4,      Y8,            X9,            0,             0,             0,             0,             }, //9\n    {X3,            Y3,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X9,            0,             0,             0,             0,             }, //10\n    {X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         X9,            0,             0,             0,             0,             }, //11\n    {X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X9,            0,             0,             0,             0,             }, //12\n    {X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //13\n    {X3,            Y3,            Y4,            X5,            X6,            Y6,            X7,            Y7,            X8,            Z1^X4^Y4,      Z0^X5^Y5,      Y8,            X9,            0,             0,             0,             0,             }, //14\n    {X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //15\n    {X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //16\n    {X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //17\n    {X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         0,             0,             0,             }, //18\n    {X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^Y6,         0,             0,             0,             }, //19\n    {X3,            Y3,            Y4,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X9,            0,             0,             0,             0,             }, //20\n    {X3,            Y3,            Y4,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X9,            0,             0,             0,             0,             }, //21\n    {X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         0,             0,             0,             }, //22\n    {X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //23\n    {X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //24\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         0,             0,             }, //25\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^Y8,         0,             0,             }, //26\n    {X3,            Y3,            Y4,            X6,            X7,            Y7,            X8,            Y8,            X9,            Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         0,             0,             0,             0,             }, //27\n    {X3,            Y3,            Y4,            X6,            X7,            Y7,            X8,            Y8,            X9,            Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             0,             }, //28\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         0,             0,             }, //29\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //30\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //31\n    {X3,            Y3,            X6,            X7,            Y7,            X8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X3^Y8,         0,             0,             }, //32\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y6^X7,         X6^Y7,         0,             0,             }, //33\n    {X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y6^X7,         Z0^X6^Y7,      0,             0,             }, //34\n};\n\n}// V2\n} // Addr\n} // namespace rocr\n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx10/gfx10addrlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx10addrlib.cpp\n* @brief Contain the implementation for the Gfx10Lib class.\n************************************************************************************************************************\n*/\n\n#include \"gfx10addrlib.h\"\n#include \"addrcommon.h\"\n#include \"gfx10_gb_reg.h\"\n\n#include \"amdgpu_asic_addr.h\"\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\nnamespace rocr {\nnamespace Addr\n{\n/**\n************************************************************************************************************************\n*   Gfx10HwlInit\n*\n*   @brief\n*       Creates an Gfx10Lib object.\n*\n*   @return\n*       Returns an Gfx10Lib object pointer.\n************************************************************************************************************************\n*/\nAddr::Lib* Gfx10HwlInit(const Client* pClient)\n{\n    return V2::Gfx10Lib::CreateObj(pClient);\n}\n\nnamespace V2\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst SwizzleModeFlags Gfx10Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =\n{//Linear 256B  4KB  64KB   Var    Z    Std   Disp  Rot   XOR    T     RtOpt Reserved\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR\n    {{0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_S\n    {{0,    1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_S\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_S\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_S_T\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_D_T\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_S_X\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_D_X\n    {{0,    0,    1,    0,    0,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_4KB_R_X\n\n    {{0,    0,    0,    1,    0,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_Z_X\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_S_X\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_D_X\n    {{0,    0,    0,    1,    0,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_64KB_R_X\n\n    {{0,    0,    0,    0,    1,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_VAR_Z_X\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_VAR_R_X\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR_GENERAL\n};\n\nconst Dim3d Gfx10Lib::Block256_3d[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};\n\nconst Dim3d Gfx10Lib::Block64K_Log2_3d[] = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};\nconst Dim3d Gfx10Lib::Block4K_Log2_3d[]  = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::Gfx10Lib\n*\n*   @brief\n*       Constructor\n*\n************************************************************************************************************************\n*/\nGfx10Lib::Gfx10Lib(const Client* pClient)\n    :\n    Lib(pClient),\n    m_numPkrLog2(0),\n    m_numSaLog2(0),\n    m_colorBaseIndex(0),\n    m_xmaskBaseIndex(0),\n    m_htileBaseIndex(0),\n    m_dccBaseIndex(0)\n{\n    memset(&m_settings, 0, sizeof(m_settings));\n    memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::~Gfx10Lib\n*\n*   @brief\n*       Destructor\n************************************************************************************************************************\n*/\nGfx10Lib::~Gfx10Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeHtileInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeHtilenfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeHtileInfo(\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if (((pIn->swizzleMode != ADDR_SW_64KB_Z_X) &&\n         ((pIn->swizzleMode != ADDR_SW_VAR_Z_X) || (m_blockVarSizeLog2 == 0))) ||\n        (pIn->hTileFlags.pipeAligned != TRUE))\n    {\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        Dim3d         metaBlk     = {};\n        const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx10DataDepthStencil,\n                                                   ADDR_RSRC_TEX_2D,\n                                                   pIn->swizzleMode,\n                                                   0,\n                                                   0,\n                                                   TRUE,\n                                                   &metaBlk);\n\n        pOut->pitch         = PowTwoAlign(pIn->unalignedWidth,  metaBlk.w);\n        pOut->height        = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);\n        pOut->baseAlign     = Max(metaBlkSize, 1u << (m_pipesLog2 + 11u));\n        pOut->metaBlkWidth  = metaBlk.w;\n        pOut->metaBlkHeight = metaBlk.h;\n\n        if (pIn->numMipLevels > 1)\n        {\n            ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);\n\n            UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >=0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);\n\n                mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);\n                mipHeight = PowTwoAlign(mipHeight, metaBlk.h);\n\n                const UINT_32 pitchInM     = mipWidth  / metaBlk.w;\n                const UINT_32 heightInM    = mipHeight / metaBlk.h;\n                const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].inMiptail = FALSE;\n                    pOut->pMipInfo[i].offset    = offset;\n                    pOut->pMipInfo[i].sliceSize = mipSliceSize;\n                }\n\n                offset += mipSliceSize;\n            }\n\n            pOut->sliceSize          = offset;\n            pOut->metaBlkNumPerSlice = offset / metaBlkSize;\n            pOut->htileBytes         = pOut->sliceSize * pIn->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)\n                {\n                    pOut->pMipInfo[i].inMiptail = TRUE;\n                    pOut->pMipInfo[i].offset    = 0;\n                    pOut->pMipInfo[i].sliceSize = 0;\n                }\n\n                if (pIn->firstMipIdInTail != pIn->numMipLevels)\n                {\n                    pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;\n                }\n            }\n        }\n        else\n        {\n            const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;\n            const UINT_32 heightInM = pOut->height / metaBlk.h;\n\n            pOut->metaBlkNumPerSlice    = pitchInM * heightInM;\n            pOut->sliceSize             = pOut->metaBlkNumPerSlice * metaBlkSize;\n            pOut->htileBytes            = pOut->sliceSize * pIn->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].inMiptail = FALSE;\n                pOut->pMipInfo[0].offset    = 0;\n                pOut->pMipInfo[0].sliceSize = pOut->sliceSize;\n            }\n        }\n\n        // Get the HTILE address equation (copied from HtileAddrFromCoord).\n        // HTILE addressing depends on the number of samples, but this code doesn't support it yet.\n        const UINT_32 index = m_xmaskBaseIndex;\n        const UINT_8* patIdxTable = m_settings.supportRbPlus ? GFX10_HTILE_RBPLUS_PATIDX : GFX10_HTILE_PATIDX;\n\n        ADDR_C_ASSERT(sizeof(GFX10_HTILE_SW_PATTERN[patIdxTable[index]]) == 72 * 2);\n        pOut->equation.gfx10_bits = (UINT_16 *)GFX10_HTILE_SW_PATTERN[patIdxTable[index]];\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeCmaskInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskInfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeCmaskInfo(\n    const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if ((pIn->resourceType != ADDR_RSRC_TEX_2D) ||\n        (pIn->cMaskFlags.pipeAligned != TRUE)   ||\n        ((pIn->swizzleMode != ADDR_SW_64KB_Z_X) &&\n         ((pIn->swizzleMode != ADDR_SW_VAR_Z_X) || (m_blockVarSizeLog2 == 0))))\n    {\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        Dim3d         metaBlk     = {};\n        const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx10DataFmask,\n                                                   ADDR_RSRC_TEX_2D,\n                                                   pIn->swizzleMode,\n                                                   0,\n                                                   0,\n                                                   TRUE,\n                                                   &metaBlk);\n\n        pOut->pitch         = PowTwoAlign(pIn->unalignedWidth,  metaBlk.w);\n        pOut->height        = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);\n        pOut->baseAlign     = metaBlkSize;\n        pOut->metaBlkWidth  = metaBlk.w;\n        pOut->metaBlkHeight = metaBlk.h;\n\n        if (pIn->numMipLevels > 1)\n        {\n            ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);\n\n            UINT_32 metaBlkPerSlice = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : 1;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >= 0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);\n\n                mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);\n                mipHeight = PowTwoAlign(mipHeight, metaBlk.h);\n\n                const UINT_32 pitchInM  = mipWidth  / metaBlk.w;\n                const UINT_32 heightInM = mipHeight / metaBlk.h;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].inMiptail = FALSE;\n                    pOut->pMipInfo[i].offset    = metaBlkPerSlice * metaBlkSize;\n                    pOut->pMipInfo[i].sliceSize = pitchInM * heightInM * metaBlkSize;\n                }\n\n                metaBlkPerSlice += pitchInM * heightInM;\n            }\n\n            pOut->metaBlkNumPerSlice = metaBlkPerSlice;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)\n                {\n                    pOut->pMipInfo[i].inMiptail = TRUE;\n                    pOut->pMipInfo[i].offset    = 0;\n                    pOut->pMipInfo[i].sliceSize = 0;\n                }\n\n                if (pIn->firstMipIdInTail != pIn->numMipLevels)\n                {\n                    pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;\n                }\n            }\n        }\n        else\n        {\n            const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;\n            const UINT_32 heightInM = pOut->height / metaBlk.h;\n\n            pOut->metaBlkNumPerSlice = pitchInM * heightInM;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].inMiptail = FALSE;\n                pOut->pMipInfo[0].offset    = 0;\n                pOut->pMipInfo[0].sliceSize = pOut->metaBlkNumPerSlice * metaBlkSize;\n            }\n        }\n\n        pOut->sliceSize  = pOut->metaBlkNumPerSlice * metaBlkSize;\n        pOut->cmaskBytes = pOut->sliceSize * pIn->numSlices;\n\n        // Get the CMASK address equation (copied from CmaskAddrFromCoord)\n        const UINT_32  fmaskBpp      = GetFmaskBpp(1, 1);\n        const UINT_32  fmaskElemLog2 = Log2(fmaskBpp >> 3);\n        const UINT_32  index         = m_xmaskBaseIndex + fmaskElemLog2;\n        const UINT_8*  patIdxTable   =\n            (pIn->swizzleMode == ADDR_SW_VAR_Z_X) ? GFX10_CMASK_VAR_RBPLUS_PATIDX :\n            (m_settings.supportRbPlus ? GFX10_CMASK_64K_RBPLUS_PATIDX : GFX10_CMASK_64K_PATIDX);\n\n        ADDR_C_ASSERT(sizeof(GFX10_CMASK_SW_PATTERN[patIdxTable[index]]) == 68 * 2);\n        pOut->equation.gfx10_bits = (UINT_16*)GFX10_CMASK_SW_PATTERN[patIdxTable[index]];\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeDccInfo\n*\n*   @brief\n*       Interface function to compute DCC key info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeDccInfo(\n    const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if (IsLinear(pIn->swizzleMode) || IsBlock256b(pIn->swizzleMode))\n    {\n        // Hardware support dcc for 256 swizzle mode, but address lib will not support it because we only\n        // select 256 swizzle mode for small surface, and it's not helpful to enable dcc for small surface.\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else if (m_settings.dccUnsup3DSwDis && IsTex3d(pIn->resourceType) && IsDisplaySwizzle(pIn->swizzleMode))\n    {\n        // DCC is not supported on 3D Display surfaces for GFX10.0 and GFX10.1\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);\n\n        {\n            // only SW_*_R_X surfaces may be DCC compressed when attached to the CB\n            ADDR_ASSERT(IsRtOptSwizzle(pIn->swizzleMode));\n\n            const BOOL_32 isThick = IsThick(pIn->resourceType, pIn->swizzleMode);\n\n            pOut->compressBlkWidth  = isThick ? Block256_3d[elemLog2].w : Block256_2d[elemLog2].w;\n            pOut->compressBlkHeight = isThick ? Block256_3d[elemLog2].h : Block256_2d[elemLog2].h;\n            pOut->compressBlkDepth  = isThick ? Block256_3d[elemLog2].d : 1;\n        }\n\n        if (ret == ADDR_OK)\n        {\n            Dim3d         metaBlk     = {};\n            const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));\n            const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx10DataColor,\n                                                       pIn->resourceType,\n                                                       pIn->swizzleMode,\n                                                       elemLog2,\n                                                       numFragLog2,\n                                                       pIn->dccKeyFlags.pipeAligned,\n                                                       &metaBlk);\n\n            pOut->dccRamBaseAlign   = metaBlkSize;\n            pOut->metaBlkWidth      = metaBlk.w;\n            pOut->metaBlkHeight     = metaBlk.h;\n            pOut->metaBlkDepth      = metaBlk.d;\n            pOut->metaBlkSize       = metaBlkSize;\n\n            pOut->pitch             = PowTwoAlign(pIn->unalignedWidth,     metaBlk.w);\n            pOut->height            = PowTwoAlign(pIn->unalignedHeight,    metaBlk.h);\n            pOut->depth             = PowTwoAlign(Max(pIn->numSlices, 1u), metaBlk.d);\n\n            if (pIn->numMipLevels > 1)\n            {\n                ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);\n\n                UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;\n\n                for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >= 0; i--)\n                {\n                    UINT_32 mipWidth, mipHeight;\n\n                    GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);\n\n                    mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);\n                    mipHeight = PowTwoAlign(mipHeight, metaBlk.h);\n\n                    const UINT_32 pitchInM     = mipWidth  / metaBlk.w;\n                    const UINT_32 heightInM    = mipHeight / metaBlk.h;\n                    const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;\n\n                    if (pOut->pMipInfo != NULL)\n                    {\n                        pOut->pMipInfo[i].inMiptail = FALSE;\n                        pOut->pMipInfo[i].offset    = offset;\n                        pOut->pMipInfo[i].sliceSize = mipSliceSize;\n                    }\n\n                    offset += mipSliceSize;\n                }\n\n                pOut->dccRamSliceSize    = offset;\n                pOut->metaBlkNumPerSlice = offset / metaBlkSize;\n                pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)\n                    {\n                        pOut->pMipInfo[i].inMiptail = TRUE;\n                        pOut->pMipInfo[i].offset    = 0;\n                        pOut->pMipInfo[i].sliceSize = 0;\n                    }\n\n                    if (pIn->firstMipIdInTail != pIn->numMipLevels)\n                    {\n                        pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;\n                    }\n                }\n            }\n            else\n            {\n                const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;\n                const UINT_32 heightInM = pOut->height / metaBlk.h;\n\n                pOut->metaBlkNumPerSlice = pitchInM * heightInM;\n                pOut->dccRamSliceSize    = pOut->metaBlkNumPerSlice * metaBlkSize;\n                pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].inMiptail = FALSE;\n                    pOut->pMipInfo[0].offset    = 0;\n                    pOut->pMipInfo[0].sliceSize = pOut->dccRamSliceSize;\n                }\n            }\n\n            // Get the DCC address equation (copied from DccAddrFromCoord)\n            const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n            const UINT_32 numPipeLog2 = m_pipesLog2;\n            UINT_32       index       = m_dccBaseIndex + elemLog2;\n            const UINT_8* patIdxTable;\n\n            if (m_settings.supportRbPlus)\n            {\n                patIdxTable = GFX10_DCC_64K_R_X_RBPLUS_PATIDX;\n\n                if (pIn->dccKeyFlags.pipeAligned)\n                {\n                    index += MaxNumOfBpp;\n\n                    if (m_numPkrLog2 < 2)\n                    {\n                        index += m_pipesLog2 * MaxNumOfBpp;\n                    }\n                    else\n                    {\n                        // 4 groups for \"m_numPkrLog2 < 2\" case\n                        index += 4 * MaxNumOfBpp;\n\n                        const UINT_32 dccPipePerPkr = 3;\n\n                        index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +\n                                 (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;\n                    }\n                }\n            }\n            else\n            {\n                patIdxTable = GFX10_DCC_64K_R_X_PATIDX;\n\n                if (pIn->dccKeyFlags.pipeAligned)\n                {\n                    index += (numPipeLog2 + UnalignedDccType) * MaxNumOfBpp;\n                }\n                else\n                {\n                    index += Min(numPipeLog2, UnalignedDccType - 1) * MaxNumOfBpp;\n                }\n            }\n\n            ADDR_C_ASSERT(sizeof(GFX10_DCC_64K_R_X_SW_PATTERN[patIdxTable[index]]) == 68 * 2);\n            pOut->equation.gfx10_bits = (UINT_16*)GFX10_DCC_64K_R_X_SW_PATTERN[patIdxTable[index]];\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeCmaskAddrFromCoord(\n    const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure\n{\n    // Only support pipe aligned CMask\n    ADDR_ASSERT(pIn->cMaskFlags.pipeAligned == TRUE);\n\n    ADDR2_COMPUTE_CMASK_INFO_INPUT input = {};\n    input.size            = sizeof(input);\n    input.cMaskFlags      = pIn->cMaskFlags;\n    input.colorFlags      = pIn->colorFlags;\n    input.unalignedWidth  = Max(pIn->unalignedWidth,  1u);\n    input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n    input.numSlices       = Max(pIn->numSlices,       1u);\n    input.swizzleMode     = pIn->swizzleMode;\n    input.resourceType    = pIn->resourceType;\n\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT output = {};\n    output.size = sizeof(output);\n\n    ADDR_E_RETURNCODE returnCode = ComputeCmaskInfo(&input, &output);\n\n    if (returnCode == ADDR_OK)\n    {\n        const UINT_32  fmaskBpp      = GetFmaskBpp(pIn->numSamples, pIn->numFrags);\n        const UINT_32  fmaskElemLog2 = Log2(fmaskBpp >> 3);\n        const UINT_32  pipeMask      = (1 << m_pipesLog2) - 1;\n        const UINT_32  index         = m_xmaskBaseIndex + fmaskElemLog2;\n        const UINT_8*  patIdxTable   =\n            (pIn->swizzleMode == ADDR_SW_VAR_Z_X) ? GFX10_CMASK_VAR_RBPLUS_PATIDX :\n            (m_settings.supportRbPlus ? GFX10_CMASK_64K_RBPLUS_PATIDX : GFX10_CMASK_64K_PATIDX);\n\n        const UINT_32  blkSizeLog2  = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 7;\n        const UINT_32  blkMask      = (1 << blkSizeLog2) - 1;\n        const UINT_32  blkOffset    = ComputeOffsetFromSwizzlePattern(GFX10_CMASK_SW_PATTERN[patIdxTable[index]],\n                                                                      blkSizeLog2 + 1, // +1 for nibble offset\n                                                                      pIn->x,\n                                                                      pIn->y,\n                                                                      pIn->slice,\n                                                                      0);\n        const UINT_32 xb       = pIn->x / output.metaBlkWidth;\n        const UINT_32 yb       = pIn->y / output.metaBlkHeight;\n        const UINT_32 pb       = output.pitch / output.metaBlkWidth;\n        const UINT_32 blkIndex = (yb * pb) + xb;\n        const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;\n\n        pOut->addr = (output.sliceSize * pIn->slice) +\n                     (blkIndex * (1 << blkSizeLog2)) +\n                     ((blkOffset >> 1) ^ pipeXor);\n        pOut->bitPosition = (blkOffset & 1) << 2;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeHtileAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeHtileAddrFromCoord(\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->numMipLevels > 1)\n    {\n        returnCode = ADDR_NOTIMPLEMENTED;\n    }\n    else\n    {\n        ADDR2_COMPUTE_HTILE_INFO_INPUT input = {};\n        input.size            = sizeof(input);\n        input.hTileFlags      = pIn->hTileFlags;\n        input.depthFlags      = pIn->depthflags;\n        input.swizzleMode     = pIn->swizzleMode;\n        input.unalignedWidth  = Max(pIn->unalignedWidth,  1u);\n        input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n        input.numSlices       = Max(pIn->numSlices,       1u);\n        input.numMipLevels    = 1;\n\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {};\n        output.size = sizeof(output);\n\n        returnCode = ComputeHtileInfo(&input, &output);\n\n        if (returnCode == ADDR_OK)\n        {\n            const UINT_32  numSampleLog2 = Log2(pIn->numSamples);\n            const UINT_32  pipeMask      = (1 << m_pipesLog2) - 1;\n            const UINT_32  index         = m_htileBaseIndex + numSampleLog2;\n            const UINT_8*  patIdxTable   = m_settings.supportRbPlus ? GFX10_HTILE_RBPLUS_PATIDX : GFX10_HTILE_PATIDX;\n\n            const UINT_32  blkSizeLog2   = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 4;\n            const UINT_32  blkMask       = (1 << blkSizeLog2) - 1;\n            const UINT_32  blkOffset     = ComputeOffsetFromSwizzlePattern(GFX10_HTILE_SW_PATTERN[patIdxTable[index]],\n                                                                           blkSizeLog2 + 1, // +1 for nibble offset\n                                                                           pIn->x,\n                                                                           pIn->y,\n                                                                           pIn->slice,\n                                                                           0);\n            const UINT_32 xb       = pIn->x / output.metaBlkWidth;\n            const UINT_32 yb       = pIn->y / output.metaBlkHeight;\n            const UINT_32 pb       = output.pitch / output.metaBlkWidth;\n            const UINT_32 blkIndex = (yb * pb) + xb;\n            const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;\n\n            pOut->addr = (static_cast<UINT_64>(output.sliceSize) * pIn->slice) +\n                         (blkIndex * (1 << blkSizeLog2)) +\n                         ((blkOffset >> 1) ^ pipeXor);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeHtileCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeHtileCoordFromAddr(\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut)   ///< [out] output structure\n{\n    ADDR_NOT_IMPLEMENTED();\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlSupportComputeDccAddrFromCoord\n*\n*   @brief\n*       Check whether HwlComputeDccAddrFromCoord() can be done for the input parameter\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlSupportComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if ((pIn->resourceType       != ADDR_RSRC_TEX_2D) ||\n        (pIn->swizzleMode        != ADDR_SW_64KB_R_X) ||\n        (pIn->dccKeyFlags.linear == TRUE)             ||\n        (pIn->numFrags           >  1)                ||\n        (pIn->numMipLevels       >  1)                ||\n        (pIn->mipId              >  0))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else if ((pIn->pitch == 0)         ||\n             (pIn->metaBlkWidth == 0)  ||\n             (pIn->metaBlkHeight == 0) ||\n             (pIn->slice > 0 && pIn->dccRamSliceSize == 0))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeDccAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeDccAddrFromCoord\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx10Lib::HwlComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,  ///< [in] input structure\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut) ///< [out] output structure\n{\n    const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n    const UINT_32 numPipeLog2 = m_pipesLog2;\n    const UINT_32 pipeMask    = (1 << numPipeLog2) - 1;\n    UINT_32       index       = m_dccBaseIndex + elemLog2;\n    const UINT_8* patIdxTable;\n\n    if (m_settings.supportRbPlus)\n    {\n        patIdxTable = GFX10_DCC_64K_R_X_RBPLUS_PATIDX;\n\n        if (pIn->dccKeyFlags.pipeAligned)\n        {\n            index += MaxNumOfBpp;\n\n            if (m_numPkrLog2 < 2)\n            {\n                index += m_pipesLog2 * MaxNumOfBpp;\n            }\n            else\n            {\n                // 4 groups for \"m_numPkrLog2 < 2\" case\n                index += 4 * MaxNumOfBpp;\n\n                const UINT_32 dccPipePerPkr = 3;\n\n                index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +\n                         (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;\n            }\n        }\n    }\n    else\n    {\n        patIdxTable = GFX10_DCC_64K_R_X_PATIDX;\n\n        if (pIn->dccKeyFlags.pipeAligned)\n        {\n            index += (numPipeLog2 + UnalignedDccType) * MaxNumOfBpp;\n        }\n        else\n        {\n            index += Min(numPipeLog2, UnalignedDccType - 1) * MaxNumOfBpp;\n        }\n    }\n\n    const UINT_32  blkSizeLog2 = Log2(pIn->metaBlkWidth) + Log2(pIn->metaBlkHeight) + elemLog2 - 8;\n    const UINT_32  blkMask     = (1 << blkSizeLog2) - 1;\n    const UINT_32  blkOffset   =\n        ComputeOffsetFromSwizzlePattern(GFX10_DCC_64K_R_X_SW_PATTERN[patIdxTable[index]],\n                                        blkSizeLog2 + 1, // +1 for nibble offset\n                                        pIn->x,\n                                        pIn->y,\n                                        pIn->slice,\n                                        0);\n    const UINT_32 xb       = pIn->x / pIn->metaBlkWidth;\n    const UINT_32 yb       = pIn->y / pIn->metaBlkHeight;\n    const UINT_32 pb       = pIn->pitch / pIn->metaBlkWidth;\n    const UINT_32 blkIndex = (yb * pb) + xb;\n    const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;\n\n    pOut->addr = (static_cast<UINT_64>(pIn->dccRamSliceSize) * pIn->slice) +\n                 (blkIndex * (1 << blkSizeLog2)) +\n                 ((blkOffset >> 1) ^ pipeXor);\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlInitGlobalParams\n*\n*   @brief\n*       Initializes global parameters\n*\n*   @return\n*       TRUE if all settings are valid\n*\n************************************************************************************************************************\n*/\nBOOL_32 Gfx10Lib::HwlInitGlobalParams(\n    const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input\n{\n    BOOL_32              valid = TRUE;\n    GB_ADDR_CONFIG_GFX10 gbAddrConfig;\n\n    gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;\n\n    // These values are copied from CModel code\n    switch (gbAddrConfig.bits.NUM_PIPES)\n    {\n        case ADDR_CONFIG_1_PIPE:\n            m_pipes     = 1;\n            m_pipesLog2 = 0;\n            break;\n        case ADDR_CONFIG_2_PIPE:\n            m_pipes     = 2;\n            m_pipesLog2 = 1;\n            break;\n        case ADDR_CONFIG_4_PIPE:\n            m_pipes     = 4;\n            m_pipesLog2 = 2;\n            break;\n        case ADDR_CONFIG_8_PIPE:\n            m_pipes     = 8;\n            m_pipesLog2 = 3;\n            break;\n        case ADDR_CONFIG_16_PIPE:\n            m_pipes     = 16;\n            m_pipesLog2 = 4;\n            break;\n        case ADDR_CONFIG_32_PIPE:\n            m_pipes     = 32;\n            m_pipesLog2 = 5;\n            break;\n        case ADDR_CONFIG_64_PIPE:\n            m_pipes     = 64;\n            m_pipesLog2 = 6;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)\n    {\n        case ADDR_CONFIG_PIPE_INTERLEAVE_256B:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;\n            m_pipeInterleaveLog2  = 8;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_512B:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;\n            m_pipeInterleaveLog2  = 9;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;\n            m_pipeInterleaveLog2  = 10;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;\n            m_pipeInterleaveLog2  = 11;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and\n    // any larger value requires a post-process (left shift) on the output pipeBankXor bits.\n    // And more importantly, SW AddrLib doesn't support sw equation/pattern for PI != 256 case.\n    ADDR_ASSERT(m_pipeInterleaveBytes == ADDR_PIPEINTERLEAVE_256B);\n\n    switch (gbAddrConfig.bits.MAX_COMPRESSED_FRAGS)\n    {\n        case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS:\n            m_maxCompFrag     = 1;\n            m_maxCompFragLog2 = 0;\n            break;\n        case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS:\n            m_maxCompFrag     = 2;\n            m_maxCompFragLog2 = 1;\n            break;\n        case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS:\n            m_maxCompFrag     = 4;\n            m_maxCompFragLog2 = 2;\n            break;\n        case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS:\n            m_maxCompFrag     = 8;\n            m_maxCompFragLog2 = 3;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    {\n        // Skip unaligned case\n        m_xmaskBaseIndex += MaxNumOfBppCMask;\n        m_htileBaseIndex += MaxNumOfAA;\n\n        m_xmaskBaseIndex += m_pipesLog2 * MaxNumOfBppCMask;\n        m_htileBaseIndex += m_pipesLog2 * MaxNumOfAA;\n        m_colorBaseIndex += m_pipesLog2 * MaxNumOfBpp;\n\n        if (m_settings.supportRbPlus)\n        {\n            m_numPkrLog2 = gbAddrConfig.bits.NUM_PKRS;\n            m_numSaLog2  = (m_numPkrLog2 > 0) ? (m_numPkrLog2 - 1) : 0;\n\n            ADDR_ASSERT((m_numPkrLog2 <= m_pipesLog2) && ((m_pipesLog2 - m_numPkrLog2) <= 2));\n\n            ADDR_C_ASSERT(sizeof(GFX10_HTILE_RBPLUS_PATIDX) / sizeof(GFX10_HTILE_RBPLUS_PATIDX[0]) ==\n                          sizeof(GFX10_CMASK_64K_RBPLUS_PATIDX) / sizeof(GFX10_CMASK_64K_RBPLUS_PATIDX[0]));\n\n            if (m_numPkrLog2 >= 2)\n            {\n                m_colorBaseIndex += (2 * m_numPkrLog2 - 2) * MaxNumOfBpp;\n                m_xmaskBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfBppCMask;\n                m_htileBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;\n            }\n        }\n        else\n        {\n            const UINT_32 numPipeType = static_cast<UINT_32>(ADDR_CONFIG_64_PIPE) -\n                                        static_cast<UINT_32>(ADDR_CONFIG_1_PIPE)  +\n                                        1;\n\n            ADDR_C_ASSERT(sizeof(GFX10_HTILE_PATIDX) / sizeof(GFX10_HTILE_PATIDX[0]) == (numPipeType + 1) * MaxNumOfAA);\n            ADDR_C_ASSERT(sizeof(GFX10_CMASK_64K_PATIDX) / sizeof(GFX10_CMASK_64K_PATIDX[0]) ==\n                          (numPipeType + 1) * MaxNumOfBppCMask);\n        }\n    }\n\n    if (m_settings.supportRbPlus)\n    {\n        // VAR block size = 16K * num_pipes. For 4 pipe configuration, SW_VAR_* mode swizzle patterns are same as the\n        // corresponding SW_64KB_* mode\n        m_blockVarSizeLog2 = m_pipesLog2 + 14;\n    }\n\n    if (valid)\n    {\n        InitEquationTable();\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlConvertChipFamily\n*\n*   @brief\n*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision\n*   @return\n*       ChipFamily\n************************************************************************************************************************\n*/\nChipFamily Gfx10Lib::HwlConvertChipFamily(\n    UINT_32 chipFamily,        ///< [in] chip family defined in atiih.h\n    UINT_32 chipRevision)      ///< [in] chip revision defined in \"asic_family\"_id.h\n{\n    ChipFamily family = ADDR_CHIP_FAMILY_NAVI;\n\n    m_settings.dccUnsup3DSwDis  = 1;\n    m_settings.dsMipmapHtileFix = 1;\n\n    switch (chipFamily)\n    {\n        case FAMILY_NV:\n            if (ASICREV_IS_NAVI10_P(chipRevision))\n            {\n                m_settings.dsMipmapHtileFix = 0;\n                m_settings.isDcn20          = 1;\n            }\n\n            if (ASICREV_IS_NAVI12_P(chipRevision))\n            {\n                m_settings.isDcn20 = 1;\n            }\n\n            if (ASICREV_IS_NAVI14_M(chipRevision))\n            {\n                m_settings.isDcn20 = 1;\n            }\n\n            if (ASICREV_IS_NAVI21_M(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n\n            if (ASICREV_IS_NAVI22_P(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n\n            if (ASICREV_IS_NAVI23_P(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n\n            if (ASICREV_IS_NAVI24_P(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n            break;\n\n        case FAMILY_VGH:\n            if (ASICREV_IS_VANGOGH(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n            else\n            {\n                ADDR_ASSERT(!\"Unknown chip revision\");\n            }\n            break;\n        case FAMILY_RMB:\n            if (ASICREV_IS_REMBRANDT(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n            else\n            {\n                ADDR_ASSERT(!\"Unknown chip revision\");\n            }\n            break;\n        case FAMILY_RPL:\n            if (ASICREV_IS_RAPHAEL(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n            break;\n        case FAMILY_MDN:\n            if (ASICREV_IS_MENDOCINO(chipRevision))\n            {\n                m_settings.supportRbPlus   = 1;\n                m_settings.dccUnsup3DSwDis = 0;\n            }\n            else\n            {\n                ADDR_ASSERT(!\"Unknown chip revision\");\n            }\n            break;\n        default:\n            ADDR_ASSERT(!\"Unknown chip family\");\n            break;\n    }\n\n    m_configFlags.use32bppFor422Fmt = TRUE;\n\n    return family;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetBlk256SizeLog2\n*\n*   @brief\n*       Get block 256 size\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nvoid Gfx10Lib::GetBlk256SizeLog2(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    if (IsThin(resourceType, swizzleMode))\n    {\n        UINT_32 blockBits = 8 - elemLog2;\n\n        if (IsZOrderSwizzle(swizzleMode))\n        {\n            blockBits -= numSamplesLog2;\n        }\n\n        pBlock->w = (blockBits >> 1) + (blockBits & 1);\n        pBlock->h = (blockBits >> 1);\n        pBlock->d = 0;\n    }\n    else\n    {\n        ADDR_ASSERT(IsThick(resourceType, swizzleMode));\n\n        UINT_32 blockBits = 8 - elemLog2;\n\n        pBlock->d = (blockBits / 3) + (((blockBits % 3) > 0) ? 1 : 0);\n        pBlock->w = (blockBits / 3) + (((blockBits % 3) > 1) ? 1 : 0);\n        pBlock->h = (blockBits / 3);\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetCompressedBlockSizeLog2\n*\n*   @brief\n*       Get compress block size\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nvoid Gfx10Lib::GetCompressedBlockSizeLog2(\n    Gfx10DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    if (dataType == Gfx10DataColor)\n    {\n        GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, pBlock);\n    }\n    else\n    {\n        ADDR_ASSERT((dataType == Gfx10DataDepthStencil) || (dataType == Gfx10DataFmask));\n        pBlock->w = 3;\n        pBlock->h = 3;\n        pBlock->d = 0;\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetMetaOverlapLog2\n*\n*   @brief\n*       Get meta block overlap\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nINT_32 Gfx10Lib::GetMetaOverlapLog2(\n    Gfx10DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2     ///< [in] number of samples\n    ) const\n{\n    Dim3d compBlock;\n    Dim3d microBlock;\n\n    GetCompressedBlockSizeLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2, &compBlock);\n    GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, &microBlock);\n\n    const INT_32 compSizeLog2   = compBlock.w  + compBlock.h  + compBlock.d;\n    const INT_32 blk256SizeLog2 = microBlock.w + microBlock.h + microBlock.d;\n    const INT_32 maxSizeLog2    = Max(compSizeLog2, blk256SizeLog2);\n    const INT_32 numPipesLog2   = GetEffectiveNumPipes();\n    INT_32       overlap        = numPipesLog2 - maxSizeLog2;\n\n    if ((numPipesLog2 > 1) && m_settings.supportRbPlus)\n    {\n        overlap++;\n    }\n\n    // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)\n    if ((elemLog2 == 4) && (numSamplesLog2 == 3))\n    {\n        overlap--;\n    }\n    overlap = Max(overlap, 0);\n    return overlap;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::Get3DMetaOverlapLog2\n*\n*   @brief\n*       Get 3d meta block overlap\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nINT_32 Gfx10Lib::Get3DMetaOverlapLog2(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2           ///< [in] element size log2\n    ) const\n{\n    Dim3d microBlock;\n    GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, 0, &microBlock);\n\n    INT_32 overlap = GetEffectiveNumPipes() - static_cast<INT_32>(microBlock.w);\n\n    if (m_settings.supportRbPlus)\n    {\n        overlap++;\n    }\n\n    if ((overlap < 0) || (IsStandardSwizzle(resourceType, swizzleMode) == TRUE))\n    {\n        overlap = 0;\n    }\n    return overlap;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetPipeRotateAmount\n*\n*   @brief\n*       Get pipe rotate amount\n*\n*   @return\n*       Pipe rotate amount\n************************************************************************************************************************\n*/\n\nINT_32 Gfx10Lib::GetPipeRotateAmount(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode        ///< [in] Swizzle mode\n    ) const\n{\n    INT_32 amount = 0;\n\n    if (m_settings.supportRbPlus && (m_pipesLog2 >= (m_numSaLog2 + 1)) && (m_pipesLog2 > 1))\n    {\n        amount = ((m_pipesLog2 == (m_numSaLog2 + 1)) && IsRbAligned(resourceType, swizzleMode)) ?\n                 1 : m_pipesLog2 - (m_numSaLog2 + 1);\n    }\n\n    return amount;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetMetaBlkSize\n*\n*   @brief\n*       Get metadata block size\n*\n*   @return\n*       Meta block size\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::GetMetaBlkSize(\n    Gfx10DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    BOOL_32          pipeAlign,         ///< [in] pipe align\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    INT_32 metablkSizeLog2;\n\n    {\n        const INT_32 metaElemSizeLog2   = GetMetaElementSizeLog2(dataType);\n        const INT_32 metaCacheSizeLog2  = GetMetaCacheSizeLog2(dataType);\n        const INT_32 compBlkSizeLog2    = (dataType == Gfx10DataColor) ? 8 : 6 + numSamplesLog2 + elemLog2;\n        const INT_32 metaBlkSamplesLog2 = (dataType == Gfx10DataDepthStencil) ?\n                                          numSamplesLog2 : Min(numSamplesLog2, m_maxCompFragLog2);\n        const INT_32 dataBlkSizeLog2    = GetBlockSizeLog2(swizzleMode);\n        INT_32       numPipesLog2       = m_pipesLog2;\n\n        if (IsThin(resourceType, swizzleMode))\n        {\n            if ((pipeAlign == FALSE) ||\n                (IsStandardSwizzle(resourceType, swizzleMode) == TRUE) ||\n                (IsDisplaySwizzle(resourceType, swizzleMode)  == TRUE))\n            {\n                if (pipeAlign)\n                {\n                    metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);\n                    metablkSizeLog2 = Min(metablkSizeLog2, dataBlkSizeLog2);\n                }\n                else\n                {\n                    metablkSizeLog2 = Min(dataBlkSizeLog2, 12);\n                }\n            }\n            else\n            {\n                if (m_settings.supportRbPlus && (m_pipesLog2 == m_numSaLog2 + 1) && (m_pipesLog2 > 1))\n                {\n                    numPipesLog2++;\n                }\n\n                INT_32 pipeRotateLog2 = GetPipeRotateAmount(resourceType, swizzleMode);\n\n                if (numPipesLog2 >= 4)\n                {\n                    INT_32 overlapLog2 = GetMetaOverlapLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2);\n\n                    // In 16Bpe 8xaa, we have an extra overlap bit\n                    if ((pipeRotateLog2 > 0)  &&\n                        (elemLog2 == 4)       &&\n                        (numSamplesLog2 == 3) &&\n                        (IsZOrderSwizzle(swizzleMode) || (GetEffectiveNumPipes() > 3)))\n                    {\n                        overlapLog2++;\n                    }\n\n                    metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;\n                    metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);\n\n                    if (m_settings.supportRbPlus    &&\n                        IsRtOptSwizzle(swizzleMode) &&\n                        (numPipesLog2 == 6)         &&\n                        (numSamplesLog2 == 3)       &&\n                        (m_maxCompFragLog2 == 3)    &&\n                        (metablkSizeLog2 < 15))\n                    {\n                        metablkSizeLog2 = 15;\n                    }\n                }\n                else\n                {\n                    metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);\n                }\n\n                if (dataType == Gfx10DataDepthStencil)\n                {\n                    // For htile surfaces, pad meta block size to 2K * num_pipes\n                    metablkSizeLog2 = Max(metablkSizeLog2, 11 + numPipesLog2);\n                }\n\n                const INT_32 compFragLog2 = Min(m_maxCompFragLog2, numSamplesLog2);\n\n                if  (IsRtOptSwizzle(swizzleMode) && (compFragLog2 > 1) && (pipeRotateLog2 >= 1))\n                {\n                    const INT_32 tmp = 8 + m_pipesLog2 + Max(pipeRotateLog2, compFragLog2 - 1);\n\n                    metablkSizeLog2 = Max(metablkSizeLog2, tmp);\n                }\n            }\n\n            const INT_32 metablkBitsLog2 =\n                metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;\n            pBlock->w = 1 << ((metablkBitsLog2 >> 1) + (metablkBitsLog2 & 1));\n            pBlock->h = 1 << (metablkBitsLog2 >> 1);\n            pBlock->d = 1;\n        }\n        else\n        {\n            ADDR_ASSERT(IsThick(resourceType, swizzleMode));\n\n            if (pipeAlign)\n            {\n                if (m_settings.supportRbPlus         &&\n                    (m_pipesLog2 == m_numSaLog2 + 1) &&\n                    (m_pipesLog2 > 1)                &&\n                    IsRbAligned(resourceType, swizzleMode))\n                {\n                    numPipesLog2++;\n                }\n\n                const INT_32 overlapLog2 = Get3DMetaOverlapLog2(resourceType, swizzleMode, elemLog2);\n\n                metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;\n                metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);\n                metablkSizeLog2 = Max(metablkSizeLog2, 12);\n            }\n            else\n            {\n                metablkSizeLog2 = 12;\n            }\n\n            const INT_32 metablkBitsLog2 =\n                metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;\n            pBlock->w = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 0) ? 1 : 0));\n            pBlock->h = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 1) ? 1 : 0));\n            pBlock->d = 1 << (metablkBitsLog2 / 3);\n        }\n    }\n\n    return (1 << static_cast<UINT_32>(metablkSizeLog2));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ConvertSwizzlePatternToEquation\n*\n*   @brief\n*       Convert swizzle pattern to equation.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx10Lib::ConvertSwizzlePatternToEquation(\n    UINT_32                elemLog2,  ///< [in] element bytes log2\n    AddrResourceType       rsrcType,  ///< [in] resource type\n    AddrSwizzleMode        swMode,    ///< [in] swizzle mode\n    const ADDR_SW_PATINFO* pPatInfo,  ///< [in] swizzle pattern infor\n    ADDR_EQUATION*         pEquation) ///< [out] equation converted from swizzle pattern\n    const\n{\n    // Get full swizzle pattern and store it as an ADDR_BIT_SETTING list\n    ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];\n    GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n    const ADDR_BIT_SETTING* pSwizzle      = fullSwizzlePattern;\n    const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode);\n    memset(pEquation, 0, sizeof(ADDR_EQUATION));\n    pEquation->numBits            = blockSizeLog2;\n    pEquation->numBitComponents   = pPatInfo->maxItemCount;\n    pEquation->stackedDepthSlices = FALSE;\n\n    for (UINT_32 i = 0; i < elemLog2; i++)\n    {\n        pEquation->addr[i].channel = 0;\n        pEquation->addr[i].valid   = 1;\n        pEquation->addr[i].index   = i;\n    }\n\n    if (IsXor(swMode) == FALSE)\n    {\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            ADDR_ASSERT(IsPow2(pSwizzle[i].value));\n\n            if (pSwizzle[i].x != 0)\n            {\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].x)));\n\n                pEquation->addr[i].channel = 0;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].x) + elemLog2;\n            }\n            else if (pSwizzle[i].y != 0)\n            {\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].y)));\n\n                pEquation->addr[i].channel = 1;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n            }\n            else\n            {\n                ADDR_ASSERT(pSwizzle[i].z != 0);\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));\n\n                pEquation->addr[i].channel = 2;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].z);\n            }\n\n            pEquation->xor1[i].value = 0;\n            pEquation->xor2[i].value = 0;\n        }\n    }\n    else if (IsThin(rsrcType, swMode))\n    {\n        Dim3d dim;\n        ComputeThinBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, 0, rsrcType, swMode);\n\n        const UINT_32 blkXLog2 = Log2(dim.w);\n        const UINT_32 blkYLog2 = Log2(dim.h);\n        const UINT_32 blkXMask = dim.w - 1;\n        const UINT_32 blkYMask = dim.h - 1;\n\n        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};\n        UINT_32          xMask = 0;\n        UINT_32          yMask = 0;\n        UINT_32          bMask = (1 << elemLog2) - 1;\n\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            if (IsPow2(pSwizzle[i].value))\n            {\n                if (pSwizzle[i].x != 0)\n                {\n                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);\n                    xMask |= pSwizzle[i].x;\n\n                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);\n\n                    ADDR_ASSERT(xLog2 < blkXLog2);\n\n                    pEquation->addr[i].channel = 0;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = xLog2 + elemLog2;\n                }\n                else\n                {\n                    ADDR_ASSERT(pSwizzle[i].y != 0);\n                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);\n                    yMask |= pSwizzle[i].y;\n\n                    pEquation->addr[i].channel = 1;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                }\n\n                swizzle[i].value = 0;\n                bMask |= 1 << i;\n            }\n            else\n            {\n                if (pSwizzle[i].z != 0)\n                {\n                    ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));\n\n                    pEquation->xor2[i].channel = 2;\n                    pEquation->xor2[i].valid   = 1;\n                    pEquation->xor2[i].index   = Log2(pSwizzle[i].z);\n                }\n\n                swizzle[i].x = pSwizzle[i].x;\n                swizzle[i].y = pSwizzle[i].y;\n                swizzle[i].z = swizzle[i].s = 0;\n\n                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);\n\n                const UINT_32 xHi = swizzle[i].x & (~blkXMask);\n\n                if (xHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(xHi));\n                    ADDR_ASSERT(pEquation->xor1[i].value == 0);\n\n                    pEquation->xor1[i].channel = 0;\n                    pEquation->xor1[i].valid   = 1;\n                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;\n\n                    swizzle[i].x &= blkXMask;\n                }\n\n                const UINT_32 yHi = swizzle[i].y & (~blkYMask);\n\n                if (yHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(yHi));\n\n                    if (xHi == 0)\n                    {\n                        ADDR_ASSERT(pEquation->xor1[i].value == 0);\n                        pEquation->xor1[i].channel = 1;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(yHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 1;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(yHi);\n                    }\n\n                    swizzle[i].y &= blkYMask;\n                }\n\n                if (swizzle[i].value == 0)\n                {\n                    bMask |= 1 << i;\n                }\n            }\n        }\n\n        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;\n        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;\n\n        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);\n\n        while (bMask != blockMask)\n        {\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)\n            {\n                if ((bMask & (1 << i)) == 0)\n                {\n                    if (IsPow2(swizzle[i].value))\n                    {\n                        if (swizzle[i].x != 0)\n                        {\n                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);\n                            xMask |= swizzle[i].x;\n\n                            const UINT_32 xLog2 = Log2(swizzle[i].x);\n\n                            ADDR_ASSERT(xLog2 < blkXLog2);\n\n                            pEquation->addr[i].channel = 0;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = xLog2 + elemLog2;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzle[i].y != 0);\n                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);\n                            yMask |= swizzle[i].y;\n\n                            pEquation->addr[i].channel = 1;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].y);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                        }\n\n                        swizzle[i].value = 0;\n                        bMask |= 1 << i;\n                    }\n                    else\n                    {\n                        const UINT_32 x = swizzle[i].x & xMask;\n                        const UINT_32 y = swizzle[i].y & yMask;\n\n                        if (x != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(x));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 0;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(x) + elemLog2;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 0;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(x) + elemLog2;\n                            }\n                        }\n\n                        if (y != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(y));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 1;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(y);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 1;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(y);\n                            }\n                        }\n\n                        swizzle[i].x &= ~x;\n                        swizzle[i].y &= ~y;\n                    }\n                }\n            }\n        }\n\n        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask));\n    }\n    else\n    {\n        const UINT_32 blkXLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].w : Block64K_Log2_3d[elemLog2].w;\n        const UINT_32 blkYLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].h : Block64K_Log2_3d[elemLog2].h;\n        const UINT_32 blkZLog2 = (blockSizeLog2 == 12) ? Block4K_Log2_3d[elemLog2].d : Block64K_Log2_3d[elemLog2].d;\n        const UINT_32 blkXMask = (1 << blkXLog2) - 1;\n        const UINT_32 blkYMask = (1 << blkYLog2) - 1;\n        const UINT_32 blkZMask = (1 << blkZLog2) - 1;\n\n        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};\n        UINT_32          xMask = 0;\n        UINT_32          yMask = 0;\n        UINT_32          zMask = 0;\n        UINT_32          bMask = (1 << elemLog2) - 1;\n\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            if (IsPow2(pSwizzle[i].value))\n            {\n                if (pSwizzle[i].x != 0)\n                {\n                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);\n                    xMask |= pSwizzle[i].x;\n\n                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);\n\n                    ADDR_ASSERT(xLog2 < blkXLog2);\n\n                    pEquation->addr[i].channel = 0;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = xLog2 + elemLog2;\n                }\n                else if (pSwizzle[i].y != 0)\n                {\n                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);\n                    yMask |= pSwizzle[i].y;\n\n                    pEquation->addr[i].channel = 1;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                }\n                else\n                {\n                    ADDR_ASSERT(pSwizzle[i].z != 0);\n                    ADDR_ASSERT((zMask & pSwizzle[i].z) == 0);\n                    zMask |= pSwizzle[i].z;\n\n                    pEquation->addr[i].channel = 2;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].z);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);\n                }\n\n                swizzle[i].value = 0;\n                bMask |= 1 << i;\n            }\n            else\n            {\n                swizzle[i].x = pSwizzle[i].x;\n                swizzle[i].y = pSwizzle[i].y;\n                swizzle[i].z = pSwizzle[i].z;\n                swizzle[i].s = 0;\n\n                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);\n\n                const UINT_32 xHi = swizzle[i].x & (~blkXMask);\n                const UINT_32 yHi = swizzle[i].y & (~blkYMask);\n                const UINT_32 zHi = swizzle[i].z & (~blkZMask);\n\n                ADDR_ASSERT((xHi == 0) || (yHi== 0) || (zHi == 0));\n\n                if (xHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(xHi));\n                    ADDR_ASSERT(pEquation->xor1[i].value == 0);\n\n                    pEquation->xor1[i].channel = 0;\n                    pEquation->xor1[i].valid   = 1;\n                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;\n\n                    swizzle[i].x &= blkXMask;\n                }\n\n                if (yHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(yHi));\n\n                    if (pEquation->xor1[i].value == 0)\n                    {\n                        pEquation->xor1[i].channel = 1;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(yHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 1;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(yHi);\n                    }\n\n                    swizzle[i].y &= blkYMask;\n                }\n\n                if (zHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(zHi));\n\n                    if (pEquation->xor1[i].value == 0)\n                    {\n                        pEquation->xor1[i].channel = 2;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(zHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 2;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(zHi);\n                    }\n\n                    swizzle[i].z &= blkZMask;\n                }\n\n                if (swizzle[i].value == 0)\n                {\n                    bMask |= 1 << i;\n                }\n            }\n        }\n\n        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;\n        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;\n\n        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);\n\n        while (bMask != blockMask)\n        {\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)\n            {\n                if ((bMask & (1 << i)) == 0)\n                {\n                    if (IsPow2(swizzle[i].value))\n                    {\n                        if (swizzle[i].x != 0)\n                        {\n                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);\n                            xMask |= swizzle[i].x;\n\n                            const UINT_32 xLog2 = Log2(swizzle[i].x);\n\n                            ADDR_ASSERT(xLog2 < blkXLog2);\n\n                            pEquation->addr[i].channel = 0;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = xLog2 + elemLog2;\n                        }\n                        else if (swizzle[i].y != 0)\n                        {\n                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);\n                            yMask |= swizzle[i].y;\n\n                            pEquation->addr[i].channel = 1;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].y);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzle[i].z != 0);\n                            ADDR_ASSERT((zMask & swizzle[i].z) == 0);\n                            zMask |= swizzle[i].z;\n\n                            pEquation->addr[i].channel = 2;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].z);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);\n                        }\n\n                        swizzle[i].value = 0;\n                        bMask |= 1 << i;\n                    }\n                    else\n                    {\n                        const UINT_32 x = swizzle[i].x & xMask;\n                        const UINT_32 y = swizzle[i].y & yMask;\n                        const UINT_32 z = swizzle[i].z & zMask;\n\n                        if (x != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(x));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 0;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(x) + elemLog2;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 0;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(x) + elemLog2;\n                            }\n                        }\n\n                        if (y != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(y));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 1;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(y);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 1;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(y);\n                            }\n                        }\n\n                        if (z != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(z));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 2;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(z);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 2;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(z);\n                            }\n                        }\n\n                        swizzle[i].x &= ~x;\n                        swizzle[i].y &= ~y;\n                        swizzle[i].z &= ~z;\n                    }\n                }\n            }\n        }\n\n        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask) && (zMask == blkZMask));\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::InitEquationTable\n*\n*   @brief\n*       Initialize Equation table.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx10Lib::InitEquationTable()\n{\n    memset(m_equationTable, 0, sizeof(m_equationTable));\n\n    // Iterate through resourceTypes, up to MaxRsrcType where a \"resourceType\" refers to AddrResourceType (1D/2D/3D)\n    // resources. This starts with rsrcTypeIdx = 0, however there is an offset added that will start us off at\n    // computing 2D resources.\n    for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)\n    {\n        // Add offset. Start iterating from ADDR_RSRC_TEX_2D\n        const AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);\n\n        // Iterate through the maximum number of swizzlemodes a type can hold\n        for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwModeType; swModeIdx++)\n        {\n            const AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);\n\n            // Iterate through the different bits-per-pixel settings (8bpp/16bpp/32bpp/64bpp/128bpp)\n            for (UINT_32 elemLog2 = 0; elemLog2 < MaxElementBytesLog2; elemLog2++)\n            {\n                UINT_32                equationIndex = ADDR_INVALID_EQUATION_INDEX;\n                // May or may not return a ADDR_SW_PATINFO for a completely different swizzle mode, essentially\n                // overwriting the choice.\n                const ADDR_SW_PATINFO* pPatInfo      = GetSwizzlePatternInfo(swMode, rsrcType, elemLog2, 1);\n\n                if (pPatInfo != NULL)\n                {\n                    ADDR_ASSERT(IsValidSwMode(swMode));\n                    if (pPatInfo->maxItemCount <= 3) // Get a valid equationIndex\n                    {\n                        ADDR_EQUATION equation = {};\n\n                        // Passing in pPatInfo to get the addr equation\n                        ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);\n\n                        equationIndex = m_numEquations;\n                        ADDR_ASSERT(equationIndex < EquationTableSize);\n                        // Updates m_equationTable[m_numEquations] to be the addr equation for this PatInfo\n                        m_equationTable[equationIndex] = equation;\n                        // Increment m_numEquations\n                        m_numEquations++;\n                    }\n                    else // There is no equationIndex\n                    {\n                        // We only see \"ill\" equation from 64/128 BPE + 3D resource + SW_64KB_D_X under RB+ case\n                        ADDR_ASSERT((elemLog2 == 3) || (elemLog2 == 4));\n                        ADDR_ASSERT(rsrcTypeIdx == 1);\n                        ADDR_ASSERT(swMode == ADDR_SW_64KB_D_X);\n                        ADDR_ASSERT(m_settings.supportRbPlus == 1);\n                    }\n                }\n                // equationIndex, which is used to look up equations in m_equationTable, will be cached for every\n                // iteration in this nested for-loop\n                m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] = equationIndex;\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlGetEquationIndex\n*\n*   @brief\n*       Interface function stub of GetEquationIndex\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::HwlGetEquationIndex(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    UINT_32 equationIdx = ADDR_INVALID_EQUATION_INDEX;\n\n    if ((pIn->resourceType == ADDR_RSRC_TEX_2D) ||\n        (pIn->resourceType == ADDR_RSRC_TEX_3D))\n    {\n        const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swModeIdx   = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n\n        equationIdx = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];\n    }\n\n    if (pOut->pMipInfo != NULL)\n    {\n        for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n        {\n            pOut->pMipInfo[i].equationIndex = equationIdx;\n        }\n    }\n\n    return equationIdx;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetValidDisplaySwizzleModes\n*\n*   @brief\n*       Get valid swizzle modes mask for displayable surface\n*\n*   @return\n*       Valid swizzle modes mask for displayable surface\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::GetValidDisplaySwizzleModes(\n    UINT_32 bpp\n    ) const\n{\n    UINT_32 swModeMask = 0;\n\n    if (bpp <= 64)\n    {\n        if (m_settings.isDcn20)\n        {\n            swModeMask = (bpp == 64) ? Dcn20Bpp64SwModeMask : Dcn20NonBpp64SwModeMask;\n        }\n        else\n        {\n            swModeMask = (bpp == 64) ? Dcn21Bpp64SwModeMask : Dcn21NonBpp64SwModeMask;\n        }\n    }\n\n    return swModeMask;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::IsValidDisplaySwizzleMode\n*\n*   @brief\n*       Check if a swizzle mode is supported by display engine\n*\n*   @return\n*       TRUE is swizzle mode is supported by display engine\n************************************************************************************************************************\n*/\nBOOL_32 Gfx10Lib::IsValidDisplaySwizzleMode(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure\n    ) const\n{\n    ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);\n\n    return (GetValidDisplaySwizzleModes(pIn->bpp) & (1 << pIn->swizzleMode)) ? TRUE : FALSE;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetMaxNumMipsInTail\n*\n*   @brief\n*       Return max number of mips in tails\n*\n*   @return\n*       Max number of mips in tails\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::GetMaxNumMipsInTail(\n    UINT_32 blockSizeLog2,     ///< block size log2\n    BOOL_32 isThin             ///< is thin or thick\n    ) const\n{\n    UINT_32 effectiveLog2 = blockSizeLog2;\n\n    if (isThin == FALSE)\n    {\n        effectiveLog2 -= (blockSizeLog2 - 8) / 3;\n    }\n\n    return (effectiveLog2 <= 11) ? (1 + (1 << (effectiveLog2 - 9))) : (effectiveLog2 - 4);\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputePipeBankXor\n*\n*   @brief\n*       Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputePipeBankXor(\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,     ///< [in] input structure\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut     ///< [out] output structure\n    ) const\n{\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        const UINT_32 bankBits = GetBankXorBits(GetBlockSizeLog2(pIn->swizzleMode));\n\n        // No pipe xor...\n        const UINT_32 pipeXor = 0;\n        UINT_32       bankXor = 0;\n\n        const UINT_32         XorPatternLen = 8;\n        static const UINT_32  XorBankRot1b[XorPatternLen] = {0,  1,  0,  1,  0,  1,  0,  1};\n        static const UINT_32  XorBankRot2b[XorPatternLen] = {0,  2,  1,  3,  2,  0,  3,  1};\n        static const UINT_32  XorBankRot3b[XorPatternLen] = {0,  4,  2,  6,  1,  5,  3,  7};\n        static const UINT_32  XorBankRot4b[XorPatternLen] = {0,  8,  4, 12,  2, 10,  6, 14};\n        static const UINT_32* XorBankRotPat[] = {XorBankRot1b, XorBankRot2b, XorBankRot3b, XorBankRot4b};\n\n        switch (bankBits)\n        {\n            case 1:\n            case 2:\n            case 3:\n            case 4:\n                bankXor = XorBankRotPat[bankBits - 1][pIn->surfIndex % XorPatternLen] << (m_pipesLog2 + ColumnBits);\n                break;\n            default:\n                // valid bank bits should be 0~4\n                ADDR_ASSERT_ALWAYS();\n            case 0:\n                break;\n        }\n\n        pOut->pipeBankXor = bankXor | pipeXor;\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSlicePipeBankXor\n*\n*   @brief\n*       Generate slice PipeBankXor value based on base PipeBankXor value and slice id\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSlicePipeBankXor(\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,   ///< [in] input structure\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut   ///< [out] output structure\n    ) const\n{\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        const UINT_32 blockBits = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 pipeBits  = GetPipeXorBits(blockBits);\n        const UINT_32 pipeXor   = ReverseBitVector(pIn->slice, pipeBits);\n\n        pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeXor;\n\n        if (pIn->bpe != 0)\n        {\n            const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,\n                                                                    pIn->resourceType,\n                                                                    Log2(pIn->bpe >> 3),\n                                                                    1);\n\n            if (pPatInfo != NULL)\n            {\n                ADDR_BIT_SETTING fullSwizzlePattern[20];\n                GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n                const UINT_32 pipeBankXorOffset =\n                    ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),\n                                                    blockBits,\n                                                    0,\n                                                    0,\n                                                    pIn->slice,\n                                                    0);\n\n                const UINT_32 pipeBankXor = pipeBankXorOffset >> m_pipeInterleaveLog2;\n\n                // Should have no bit set under pipe interleave\n                ADDR_ASSERT((pipeBankXor << m_pipeInterleaveLog2) == pipeBankXorOffset);\n\n                // This assertion firing means old approach doesn't calculate a correct sliceXor value...\n                ADDR_ASSERT(pipeBankXor == pipeXor);\n\n                pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeBankXor;\n            }\n        }\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Compute sub resource offset to support swizzle pattern\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));\n\n    pOut->offset = pIn->slice * pIn->sliceSize + pIn->macroBlockOffset;\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeNonBlockCompressedView(\n    const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)\n    {\n        // Only thin swizzle mode can have a NonBC view...\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&\n             ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))\n    {\n        // Only support BC1~BC7, ASTC, or ETC2 for now...\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else\n    {\n        UINT_32 bcWidth, bcHeight;\n        UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, NULL, &bcWidth, &bcHeight);\n\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT infoIn = {};\n        infoIn.flags        = pIn->flags;\n        infoIn.swizzleMode  = pIn->swizzleMode;\n        infoIn.resourceType = pIn->resourceType;\n        infoIn.bpp          = bpp;\n        infoIn.width        = RoundUpQuotient(pIn->width, bcWidth);\n        infoIn.height       = RoundUpQuotient(pIn->height, bcHeight);\n        infoIn.numSlices    = pIn->numSlices;\n        infoIn.numMipLevels = pIn->numMipLevels;\n        infoIn.numSamples   = 1;\n        infoIn.numFrags     = 1;\n\n        ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {};\n        ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};\n        infoOut.pMipInfo = mipInfo;\n\n        const BOOL_32 tiled = (pIn->swizzleMode != ADDR_SW_LINEAR) ? TRUE : FALSE;\n\n        if (tiled)\n        {\n            returnCode = HwlComputeSurfaceInfoTiled(&infoIn, &infoOut);\n        }\n        else\n        {\n            returnCode = HwlComputeSurfaceInfoLinear(&infoIn, &infoOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT subOffIn = {};\n            subOffIn.swizzleMode      = infoIn.swizzleMode;\n            subOffIn.resourceType     = infoIn.resourceType;\n            subOffIn.slice            = pIn->slice;\n            subOffIn.sliceSize        = infoOut.sliceSize;\n            subOffIn.macroBlockOffset = mipInfo[pIn->mipId].macroBlockOffset;\n            subOffIn.mipTailOffset    = mipInfo[pIn->mipId].mipTailOffset;\n\n            ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT subOffOut = {};\n\n            // For any mipmap level, move nonBc view base address by offset\n            HwlComputeSubResourceOffsetForSwizzlePattern(&subOffIn, &subOffOut);\n            pOut->offset = subOffOut.offset;\n\n            ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT slicePbXorIn = {};\n            slicePbXorIn.bpe             = infoIn.bpp;\n            slicePbXorIn.swizzleMode     = infoIn.swizzleMode;\n            slicePbXorIn.resourceType    = infoIn.resourceType;\n            slicePbXorIn.basePipeBankXor = pIn->pipeBankXor;\n            slicePbXorIn.slice           = pIn->slice;\n\n            ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT slicePbXorOut = {};\n\n            // For any mipmap level, nonBc view should use computed pbXor\n            HwlComputeSlicePipeBankXor(&slicePbXorIn, &slicePbXorOut);\n            pOut->pipeBankXor = slicePbXorOut.pipeBankXor;\n\n            const BOOL_32 inTail           = tiled && (pIn->mipId >= infoOut.firstMipIdInTail) ? TRUE : FALSE;\n            const UINT_32 requestMipWidth  = RoundUpQuotient(Max(pIn->width >> pIn->mipId, 1u), bcWidth);\n            const UINT_32 requestMipHeight = RoundUpQuotient(Max(pIn->height >> pIn->mipId, 1u), bcHeight);\n\n            if (inTail)\n            {\n                // For mipmap level that is in mip tail block, hack a lot of things...\n                // Basically all mipmap levels in tail block will be viewed as a small mipmap chain that all levels\n                // are fit in tail block:\n\n                // - mipId = relative mip id (which is counted from first mip ID in tail in original mip chain)\n                pOut->mipId = pIn->mipId - infoOut.firstMipIdInTail;\n\n                // - at least 2 mipmap levels (since only 1 mipmap level will not be viewed as mipmap!)\n                pOut->numMipLevels = Max(infoIn.numMipLevels - infoOut.firstMipIdInTail, 2u);\n\n                // - (mip0) width = requestMipWidth << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unalignedWidth = Min(requestMipWidth << pOut->mipId, infoOut.blockWidth / 2);\n\n                // - (mip0) height = requestMipHeight << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unalignedHeight = Min(requestMipHeight << pOut->mipId, infoOut.blockHeight);\n            }\n            // This check should cover at least mipId == 0\n            else if (requestMipWidth << pIn->mipId == infoIn.width)\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded without losing element:\n                // - only one mipmap level and mipId = 0\n                pOut->mipId        = 0;\n                pOut->numMipLevels = 1;\n\n                // (mip0) width = requestMipWidth\n                pOut->unalignedWidth = requestMipWidth;\n\n                // (mip0) height = requestMipHeight\n                pOut->unalignedHeight = requestMipHeight;\n            }\n            else\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded with element losing,\n                // We have to make it a multiple mipmap view (2 levels view here), add one extra element if needed,\n                // because single mip view may have different pitch value than original (multiple) mip view...\n                // A simple case would be:\n                // - 64KB block swizzle mode, 8 Bytes-Per-Element. Block dim = [0x80, 0x40]\n                // - 2 mipmap levels with API mip0 width = 0x401/mip1 width = 0x200 and non-BC view\n                //   mip0 width = 0x101/mip1 width = 0x80\n                // By multiple mip view, the pitch for mip level 1 would be 0x100 bytes, due to rounding up logic in\n                // GetMipSize(), and by single mip level view the pitch will only be 0x80 bytes.\n\n                // - 2 levels and mipId = 1\n                pOut->mipId        = 1;\n                pOut->numMipLevels = 2;\n\n                const UINT_32 upperMipWidth  = RoundUpQuotient(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth);\n                const UINT_32 upperMipHeight = RoundUpQuotient(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight);\n\n                const BOOL_32 needToAvoidInTail =\n                    tiled && (requestMipWidth <= infoOut.blockWidth / 2) && (requestMipHeight <= infoOut.blockHeight) ?\n                    TRUE : FALSE;\n\n                const UINT_32 hwMipWidth  = PowTwoAlign(ShiftCeil(infoIn.width, pIn->mipId), infoOut.blockWidth);\n                const UINT_32 hwMipHeight = PowTwoAlign(ShiftCeil(infoIn.height, pIn->mipId), infoOut.blockHeight);\n\n                const BOOL_32 needExtraWidth =\n                    ((upperMipWidth < requestMipWidth * 2) ||\n                     ((upperMipWidth == requestMipWidth * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipWidth > PowTwoAlign(requestMipWidth, infoOut.blockWidth))))) ? TRUE : FALSE;\n\n                const BOOL_32 needExtraHeight =\n                    ((upperMipHeight < requestMipHeight * 2) ||\n                     ((upperMipHeight == requestMipHeight * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipHeight > PowTwoAlign(requestMipHeight, infoOut.blockHeight))))) ? TRUE : FALSE;\n\n                // (mip0) width = requestLastMipLevelWidth\n                pOut->unalignedWidth  = upperMipWidth + (needExtraWidth ? 1: 0);\n\n                // (mip0) height = requestLastMipLevelHeight\n                pOut->unalignedHeight = upperMipHeight + (needExtraHeight ? 1: 0);\n            }\n\n            // Assert the downgrading from this mip[0] width would still generate correct mip[N] width\n            ADDR_ASSERT(ShiftRight(pOut->unalignedWidth, pOut->mipId) == requestMipWidth);\n            // Assert the downgrading from this mip[0] height would still generate correct mip[N] height\n            ADDR_ASSERT(ShiftRight(pOut->unalignedHeight, pOut->mipId) == requestMipHeight);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ValidateNonSwModeParams\n*\n*   @brief\n*       Validate compute surface info params except swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx10Lib::ValidateNonSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const ADDR2_SURFACE_FLAGS flags    = pIn->flags;\n    const AddrResourceType    rsrcType = pIn->resourceType;\n    const BOOL_32             mipmap   = (pIn->numMipLevels > 1);\n    const BOOL_32             msaa     = (pIn->numFrags > 1);\n    const BOOL_32             display  = flags.display;\n    const BOOL_32             tex3d    = IsTex3d(rsrcType);\n    const BOOL_32             tex2d    = IsTex2d(rsrcType);\n    const BOOL_32             tex1d    = IsTex1d(rsrcType);\n    const BOOL_32             stereo   = flags.qbStereo;\n\n    // Resource type check\n    if (tex1d)\n    {\n        if (msaa || display || stereo)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex2d)\n    {\n        if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex3d)\n    {\n        if (msaa || display || stereo)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ValidateSwModeParams\n*\n*   @brief\n*       Validate compute surface info related to swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx10Lib::ValidateSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n    else if (IsValidSwMode(pIn->swizzleMode) == FALSE)\n    {\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    const ADDR2_SURFACE_FLAGS flags       = pIn->flags;\n    const AddrResourceType    rsrcType    = pIn->resourceType;\n    const AddrSwizzleMode     swizzle     = pIn->swizzleMode;\n    const BOOL_32             msaa        = (pIn->numFrags > 1);\n    const BOOL_32             zbuffer     = flags.depth || flags.stencil;\n    const BOOL_32             color       = flags.color;\n    const BOOL_32             display     = flags.display;\n    const BOOL_32             tex3d       = IsTex3d(rsrcType);\n    const BOOL_32             tex2d       = IsTex2d(rsrcType);\n    const BOOL_32             tex1d       = IsTex1d(rsrcType);\n    const BOOL_32             thin3d      = flags.view3dAs2dArray;\n    const BOOL_32             linear      = IsLinear(swizzle);\n    const BOOL_32             blk256B     = IsBlock256b(swizzle);\n    const BOOL_32             blkVar      = IsBlockVariable(swizzle);\n    const BOOL_32             isNonPrtXor = IsNonPrtXor(swizzle);\n    const BOOL_32             prt         = flags.prt;\n    const BOOL_32             fmask       = flags.fmask;\n\n    // Misc check\n    if ((pIn->numFrags > 1) &&\n        (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))\n    {\n        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if ((pIn->bpp == 96) && (linear == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const UINT_32 swizzleMask = 1 << swizzle;\n\n    // Resource type check\n    if (tex1d)\n    {\n        if ((swizzleMask & Gfx10Rsrc1dSwModeMask) == 0)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex2d)\n    {\n        if ((swizzleMask & Gfx10Rsrc2dSwModeMask) == 0)\n        {\n            {\n                ADDR_ASSERT_ALWAYS();\n                valid = FALSE;\n            }\n        }\n        else if ((prt && ((swizzleMask & Gfx10Rsrc2dPrtSwModeMask) == 0)) ||\n                 (fmask && ((swizzleMask & Gfx10ZSwModeMask) == 0)))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex3d)\n    {\n        if (((swizzleMask & Gfx10Rsrc3dSwModeMask) == 0) ||\n            (prt && ((swizzleMask & Gfx10Rsrc3dPrtSwModeMask) == 0)) ||\n            (thin3d && ((swizzleMask & Gfx10Rsrc3dViewAs2dSwModeMask) == 0)))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    // Swizzle type check\n    if (linear)\n    {\n        if (zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsZOrderSwizzle(swizzle))\n    {\n        if ((pIn->bpp > 64)                         ||\n            (msaa && (color || (pIn->bpp > 32)))    ||\n            ElemLib::IsBlockCompressed(pIn->format) ||\n            ElemLib::IsMacroPixelPacked(pIn->format))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsStandardSwizzle(rsrcType, swizzle))\n    {\n        if (zbuffer || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsDisplaySwizzle(rsrcType, swizzle))\n    {\n        if (zbuffer || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsRtOptSwizzle(swizzle))\n    {\n        if (zbuffer)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    // Block type check\n    if (blk256B)\n    {\n        if (zbuffer || tex3d || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (blkVar)\n    {\n        if (m_blockVarSizeLog2 == 0)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSurfaceInfoSanityCheck\n*\n*   @brief\n*       Compute surface info sanity check\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSurfaceInfoSanityCheck(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure\n    ) const\n{\n    return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlGetPreferredSurfaceSetting\n*\n*   @brief\n*       Internal function to get suggested surface information for client to use\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlGetPreferredSurfaceSetting(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->flags.fmask)\n    {\n        const BOOL_32 forbid64KbBlockType = pIn->forbiddenBlock.macroThin64KB ? TRUE : FALSE;\n        const BOOL_32 forbidVarBlockType  = ((m_blockVarSizeLog2 == 0) || (pIn->forbiddenBlock.var != 0));\n\n        if (forbid64KbBlockType && forbidVarBlockType)\n        {\n            // Invalid combination...\n            ADDR_ASSERT_ALWAYS();\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            pOut->resourceType                   = ADDR_RSRC_TEX_2D;\n            pOut->validBlockSet.value            = 0;\n            pOut->validBlockSet.macroThin64KB    = forbid64KbBlockType ? 0 : 1;\n            pOut->validBlockSet.var              = forbidVarBlockType  ? 0 : 1;\n            pOut->validSwModeSet.value           = 0;\n            pOut->validSwModeSet.sw64KB_Z_X      = forbid64KbBlockType ? 0 : 1;\n            pOut->validSwModeSet.gfx10.swVar_Z_X = forbidVarBlockType  ? 0 : 1;\n            pOut->canXor                         = TRUE;\n            pOut->validSwTypeSet.value           = AddrSwSetZ;\n            pOut->clientPreferredSwSet           = pOut->validSwTypeSet;\n\n            BOOL_32 use64KbBlockType = (forbid64KbBlockType == FALSE);\n\n            if ((forbid64KbBlockType == FALSE) && (forbidVarBlockType == FALSE))\n            {\n                const UINT_8  maxFmaskSwizzleModeType = 2;\n                const UINT_32 ratioLow                = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 3 : 2);\n                const UINT_32 ratioHi                 = pIn->flags.minimizeAlign ? 1 : (pIn->flags.opt4space ? 2 : 1);\n                const UINT_32 fmaskBpp                = GetFmaskBpp(pIn->numSamples, pIn->numFrags);\n                const UINT_32 numSlices               = Max(pIn->numSlices, 1u);\n                const UINT_32 width                   = Max(pIn->width, 1u);\n                const UINT_32 height                  = Max(pIn->height, 1u);\n                const UINT_64 sizeAlignInElement      = Max(NextPow2(pIn->minSizeAlign) / (fmaskBpp >> 3), 1u);\n\n                AddrSwizzleMode swMode[maxFmaskSwizzleModeType]  = {ADDR_SW_64KB_Z_X, ADDR_SW_VAR_Z_X};\n                Dim3d           blkDim[maxFmaskSwizzleModeType]  = {{}, {}};\n                Dim3d           padDim[maxFmaskSwizzleModeType]  = {{}, {}};\n                UINT_64         padSize[maxFmaskSwizzleModeType] = {};\n\n                for (UINT_8 i = 0; i < maxFmaskSwizzleModeType; i++)\n                {\n                    ComputeBlockDimensionForSurf(&blkDim[i].w,\n                                                 &blkDim[i].h,\n                                                 &blkDim[i].d,\n                                                 fmaskBpp,\n                                                 1,\n                                                 pOut->resourceType,\n                                                 swMode[i]);\n\n                    padSize[i] = ComputePadSize(&blkDim[i], width, height, numSlices, &padDim[i]);\n                    padSize[i] = PowTwoAlign(padSize[i], sizeAlignInElement);\n                }\n\n                if (Addr2BlockTypeWithinMemoryBudget(padSize[0],\n                                                padSize[1],\n                                                ratioLow,\n                                                ratioHi,\n                                                pIn->memoryBudget,\n                                                GetBlockSizeLog2(swMode[1]) >= GetBlockSizeLog2(swMode[0])))\n                {\n                    use64KbBlockType = FALSE;\n                }\n            }\n            else if (forbidVarBlockType)\n            {\n                use64KbBlockType = TRUE;\n            }\n\n            if (use64KbBlockType)\n            {\n                pOut->swizzleMode = ADDR_SW_64KB_Z_X;\n            }\n            else\n            {\n                pOut->swizzleMode = ADDR_SW_VAR_Z_X;\n            }\n        }\n    }\n    else\n    {\n        UINT_32 bpp    = pIn->bpp;\n        UINT_32 width  = Max(pIn->width, 1u);\n        UINT_32 height = Max(pIn->height, 1u);\n\n        // Set format to INVALID will skip this conversion\n        if (pIn->format != ADDR_FMT_INVALID)\n        {\n            ElemMode elemMode = ADDR_UNCOMPRESSED;\n            UINT_32 expandX, expandY;\n\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            bpp = GetElemLib()->GetBitsPerPixel(pIn->format,\n                                                &elemMode,\n                                                &expandX,\n                                                &expandY);\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &bpp,\n                                            &basePitch,\n                                            &width,\n                                            &height);\n        }\n\n        const UINT_32 numSlices    = Max(pIn->numSlices,    1u);\n        const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);\n        const UINT_32 numSamples   = Max(pIn->numSamples,   1u);\n        const UINT_32 numFrags     = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;\n        const BOOL_32 msaa         = (numFrags > 1) || (numSamples > 1);\n\n        // Pre sanity check on non swizzle mode parameters\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};\n        localIn.flags        = pIn->flags;\n        localIn.resourceType = pIn->resourceType;\n        localIn.format       = pIn->format;\n        localIn.bpp          = bpp;\n        localIn.width        = width;\n        localIn.height       = height;\n        localIn.numSlices    = numSlices;\n        localIn.numMipLevels = numMipLevels;\n        localIn.numSamples   = numSamples;\n        localIn.numFrags     = numFrags;\n\n        if (ValidateNonSwModeParams(&localIn))\n        {\n            // Forbid swizzle mode(s) by client setting\n            ADDR2_SWMODE_SET allowedSwModeSet = {};\n            allowedSwModeSet.value |= pIn->forbiddenBlock.linear ? 0 : Gfx10LinearSwModeMask;\n            allowedSwModeSet.value |= pIn->forbiddenBlock.micro  ? 0 : Gfx10Blk256BSwModeMask;\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThin4KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? 0 : Gfx10Blk4KBSwModeMask);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThick4KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx10Rsrc3dThick4KBSwModeMask : 0);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThin64KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx10Rsrc3dThin64KBSwModeMask : Gfx10Blk64KBSwModeMask);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThick64KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx10Rsrc3dThick64KBSwModeMask : 0);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.var ? 0 : (m_blockVarSizeLog2 ? Gfx10BlkVarSwModeMask : 0);\n\n            if (pIn->preferredSwSet.value != 0)\n            {\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx10ZSwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx10StandardSwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx10DisplaySwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx10RenderSwModeMask;\n            }\n\n            if (pIn->noXor)\n            {\n                allowedSwModeSet.value &= ~Gfx10XorSwModeMask;\n            }\n\n            if (pIn->maxAlign > 0)\n            {\n                if (pIn->maxAlign < (1u << m_blockVarSizeLog2))\n                {\n                    allowedSwModeSet.value &= ~Gfx10BlkVarSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size64K)\n                {\n                    allowedSwModeSet.value &= ~Gfx10Blk64KBSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size4K)\n                {\n                    allowedSwModeSet.value &= ~Gfx10Blk4KBSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size256)\n                {\n                    allowedSwModeSet.value &= ~Gfx10Blk256BSwModeMask;\n                }\n            }\n\n            // Filter out invalid swizzle mode(s) by image attributes and HW restrictions\n            switch (pIn->resourceType)\n            {\n                case ADDR_RSRC_TEX_1D:\n                    allowedSwModeSet.value &= Gfx10Rsrc1dSwModeMask;\n                    break;\n\n                case ADDR_RSRC_TEX_2D:\n                    allowedSwModeSet.value &= pIn->flags.prt ? Gfx10Rsrc2dPrtSwModeMask : Gfx10Rsrc2dSwModeMask;\n                    break;\n\n                case ADDR_RSRC_TEX_3D:\n                    allowedSwModeSet.value &= pIn->flags.prt ? Gfx10Rsrc3dPrtSwModeMask : Gfx10Rsrc3dSwModeMask;\n\n                    if (pIn->flags.view3dAs2dArray)\n                    {\n                        // SW_LINEAR can be used for 3D thin images, including BCn image format.\n                        allowedSwModeSet.value &= Gfx10Rsrc3dViewAs2dSwModeMask;\n                    }\n                    break;\n\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    allowedSwModeSet.value = 0;\n                    break;\n            }\n\n            if (ElemLib::IsBlockCompressed(pIn->format)  ||\n                ElemLib::IsMacroPixelPacked(pIn->format) ||\n                (bpp > 64)                               ||\n                (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))\n            {\n                allowedSwModeSet.value &= ~Gfx10ZSwModeMask;\n            }\n\n            if (pIn->format == ADDR_FMT_32_32_32)\n            {\n                allowedSwModeSet.value &= Gfx10LinearSwModeMask;\n            }\n\n            if (msaa)\n            {\n                allowedSwModeSet.value &= Gfx10MsaaSwModeMask;\n            }\n\n            if (pIn->flags.depth || pIn->flags.stencil)\n            {\n                allowedSwModeSet.value &= Gfx10ZSwModeMask;\n            }\n\n            if (pIn->flags.display)\n            {\n                allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);\n            }\n\n            if (allowedSwModeSet.value != 0)\n            {\n#if DEBUG\n                // Post sanity check, at least AddrLib should accept the output generated by its own\n                UINT_32 validateSwModeSet = allowedSwModeSet.value;\n\n                for (UINT_32 i = 0; validateSwModeSet != 0; i++)\n                {\n                    if (validateSwModeSet & 1)\n                    {\n                        localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);\n                        ADDR_ASSERT(ValidateSwModeParams(&localIn));\n                    }\n\n                    validateSwModeSet >>= 1;\n                }\n#endif\n\n                pOut->resourceType   = pIn->resourceType;\n                pOut->validSwModeSet = allowedSwModeSet;\n                pOut->canXor         = (allowedSwModeSet.value & Gfx10XorSwModeMask) ? TRUE : FALSE;\n                pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);\n                pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);\n\n                pOut->clientPreferredSwSet = pIn->preferredSwSet;\n\n                if (pOut->clientPreferredSwSet.value == 0)\n                {\n                    pOut->clientPreferredSwSet.value = AddrSwSetAll;\n                }\n\n                // Apply optional restrictions\n                if ((pIn->flags.depth || pIn->flags.stencil) && msaa && m_configFlags.nonPower2MemConfig)\n                {\n                    if ((allowedSwModeSet.value &= ~Gfx10BlkVarSwModeMask) != 0)\n                    {\n                        // MSAA depth in non power of 2 memory configs would suffer from non-local channel accesses from\n                        // the GL2 in VAR mode, so it should be avoided.\n                        allowedSwModeSet.value &= ~Gfx10BlkVarSwModeMask;\n                    }\n                    else\n                    {\n                        // We should still be able to use VAR for non power of 2 memory configs with MSAA z/stencil.\n                        // But we have to suffer from low performance because there is no other choice...\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n\n                if (pIn->flags.needEquation)\n                {\n                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :\n                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;\n                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);\n                }\n\n                if (allowedSwModeSet.value == Gfx10LinearSwModeMask)\n                {\n                    pOut->swizzleMode = ADDR_SW_LINEAR;\n                }\n                else\n                {\n                    const BOOL_32 computeMinSize = (pIn->flags.minimizeAlign == 1) || (pIn->memoryBudget >= 1.0);\n\n                    if ((height > 1) && (computeMinSize == FALSE))\n                    {\n                        // Always ignore linear swizzle mode if:\n                        // 1. This is a (2D/3D) resource with height > 1\n                        // 2. Client doesn't require computing minimize size\n                        allowedSwModeSet.swLinear = 0;\n                    }\n\n                    // A bitfield where each bit represents a block type. Each swizzle mode maps to a block.\n                    ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);\n\n                    // Determine block size if there are 2 or more block type candidates\n                    if (IsPow2(allowedBlockSet.value) == FALSE)\n                    {\n                        // Tracks a valid SwizzleMode for each valid block type\n                        AddrSwizzleMode swMode[AddrBlockMaxTiledType] = {};\n\n                        swMode[AddrBlockLinear] = ADDR_SW_LINEAR;\n\n                        if (m_blockVarSizeLog2 != 0)\n                        {\n                            swMode[AddrBlockThinVar] = ADDR_SW_VAR_R_X;\n                        }\n\n                        if (pOut->resourceType == ADDR_RSRC_TEX_3D)\n                        {\n                            swMode[AddrBlockThick4KB]  = ADDR_SW_4KB_S;\n                            swMode[AddrBlockThin64KB]  = ADDR_SW_64KB_R_X;\n                            swMode[AddrBlockThick64KB] = ADDR_SW_64KB_S;\n                        }\n                        else\n                        {\n                            swMode[AddrBlockMicro]    = ADDR_SW_256B_S;\n                            swMode[AddrBlockThin4KB]  = ADDR_SW_4KB_S;\n                            swMode[AddrBlockThin64KB] = ADDR_SW_64KB_S;\n                        }\n\n                        // Tracks the size of each valid swizzle mode's surface in bytes\n                        UINT_64 padSize[AddrBlockMaxTiledType] = {};\n\n                        const UINT_32 ratioLow           = computeMinSize ? 1 : (pIn->flags.opt4space ? 3 : 2);\n                        const UINT_32 ratioHi            = computeMinSize ? 1 : (pIn->flags.opt4space ? 2 : 1);\n                        const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);\n                        UINT_32       minSizeBlk         = AddrBlockMicro; // Tracks the most optimal block to use\n                        UINT_64       minSize            = 0;              // Tracks the minimum acceptable block type\n\n                        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n\n                        // Iterate through all block types\n                        for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)\n                        {\n                            if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                            {\n                                localIn.swizzleMode = swMode[i];\n\n                                if (localIn.swizzleMode == ADDR_SW_LINEAR)\n                                {\n                                    returnCode = HwlComputeSurfaceInfoLinear(&localIn, &localOut);\n                                }\n                                else\n                                {\n                                    returnCode = HwlComputeSurfaceInfoTiled(&localIn, &localOut);\n                                }\n\n                                if (returnCode == ADDR_OK)\n                                {\n                                    padSize[i] = localOut.surfSize;\n\n                                    if (minSize == 0)\n                                    {\n                                        minSize    = padSize[i];\n                                        minSizeBlk = i;\n                                    }\n                                    else\n                                    {\n                                        // Checks if the block type is within the memory budget but favors larger blocks\n                                        if (Addr2BlockTypeWithinMemoryBudget(\n                                                minSize,\n                                                padSize[i],\n                                                ratioLow,\n                                                ratioHi,\n                                                0.0,\n                                                GetBlockSizeLog2(swMode[i]) >= GetBlockSizeLog2(swMode[minSizeBlk])))\n                                        {\n                                            minSize    = padSize[i];\n                                            minSizeBlk = i;\n                                        }\n                                    }\n                                }\n                                else\n                                {\n                                    ADDR_ASSERT_ALWAYS();\n                                    break;\n                                }\n                            }\n                        }\n\n                        if (pIn->memoryBudget > 1.0)\n                        {\n                            // If minimum size is given by swizzle mode with bigger-block type, then don't ever check\n                            // smaller-block type again in coming loop\n                            switch (minSizeBlk)\n                            {\n                                case AddrBlockThick64KB:\n                                    allowedBlockSet.macroThin64KB = 0;\n                                case AddrBlockThinVar:\n                                case AddrBlockThin64KB:\n                                    allowedBlockSet.macroThick4KB = 0;\n                                case AddrBlockThick4KB:\n                                    allowedBlockSet.macroThin4KB = 0;\n                                case AddrBlockThin4KB:\n                                    allowedBlockSet.micro  = 0;\n                                case AddrBlockMicro:\n                                    allowedBlockSet.linear = 0;\n                                case AddrBlockLinear:\n                                    break;\n\n                                default:\n                                    ADDR_ASSERT_ALWAYS();\n                                    break;\n                            }\n\n                            for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)\n                            {\n                                if ((i != minSizeBlk) &&\n                                    Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                                {\n                                    if (Addr2BlockTypeWithinMemoryBudget(\n                                            minSize,\n                                            padSize[i],\n                                            0,\n                                            0,\n                                            pIn->memoryBudget,\n                                            GetBlockSizeLog2(swMode[i]) >= GetBlockSizeLog2(swMode[minSizeBlk])) == FALSE)\n                                    {\n                                        // Clear the block type if the memory waste is unacceptable\n                                        allowedBlockSet.value &= ~(1u << (i - 1));\n                                    }\n                                }\n                            }\n\n                            // Remove VAR block type if bigger block type is allowed\n                            if (GetBlockSizeLog2(swMode[AddrBlockThinVar]) < GetBlockSizeLog2(ADDR_SW_64KB_R_X))\n                            {\n                                if (allowedBlockSet.macroThick64KB || allowedBlockSet.macroThin64KB)\n                                {\n                                    allowedBlockSet.var = 0;\n                                }\n                            }\n\n                            // Remove linear block type if 2 or more block types are allowed\n                            if (IsPow2(allowedBlockSet.value) == FALSE)\n                            {\n                                allowedBlockSet.linear = 0;\n                            }\n\n                            // Select the biggest allowed block type\n                            minSizeBlk = Log2NonPow2(allowedBlockSet.value) + 1;\n\n                            if (minSizeBlk == static_cast<UINT_32>(AddrBlockMaxTiledType))\n                            {\n                                minSizeBlk = AddrBlockLinear;\n                            }\n                        }\n\n                        switch (minSizeBlk)\n                        {\n                            case AddrBlockLinear:\n                                allowedSwModeSet.value &= Gfx10LinearSwModeMask;\n                                break;\n\n                            case AddrBlockMicro:\n                                ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx10Blk256BSwModeMask;\n                                break;\n\n                            case AddrBlockThin4KB:\n                                ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx10Blk4KBSwModeMask;\n                                break;\n\n                            case AddrBlockThick4KB:\n                                ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx10Rsrc3dThick4KBSwModeMask;\n                                break;\n\n                            case AddrBlockThin64KB:\n                                allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?\n                                                          Gfx10Rsrc3dThin64KBSwModeMask : Gfx10Blk64KBSwModeMask;\n                                break;\n\n                            case AddrBlockThick64KB:\n                                ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx10Rsrc3dThick64KBSwModeMask;\n                                break;\n\n                            case AddrBlockThinVar:\n                                allowedSwModeSet.value &= Gfx10BlkVarSwModeMask;\n                                break;\n\n                            default:\n                                ADDR_ASSERT_ALWAYS();\n                                allowedSwModeSet.value = 0;\n                                break;\n                        }\n                    }\n\n                    // Block type should be determined.\n                    ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType).value));\n\n                    ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);\n\n                    // Determine swizzle type if there are 2 or more swizzle type candidates\n                    if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))\n                    {\n                        if (ElemLib::IsBlockCompressed(pIn->format))\n                        {\n                            if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx10DisplaySwModeMask;\n                            }\n                            else if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx10StandardSwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_R);\n                                allowedSwModeSet.value &= Gfx10RenderSwModeMask;\n                            }\n                        }\n                        else if (ElemLib::IsMacroPixelPacked(pIn->format))\n                        {\n                            if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx10StandardSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx10DisplaySwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_R);\n                                allowedSwModeSet.value &= Gfx10RenderSwModeMask;\n                            }\n                        }\n                        else if (pIn->resourceType == ADDR_RSRC_TEX_3D)\n                        {\n                            if (pIn->flags.color &&\n                                GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType).macroThick64KB &&\n                                allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx10DisplaySwModeMask;\n                            }\n                            else if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx10StandardSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_R)\n                            {\n                                allowedSwModeSet.value &= Gfx10RenderSwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_Z);\n                                allowedSwModeSet.value &= Gfx10ZSwModeMask;\n                            }\n                        }\n                        else\n                        {\n                            if (allowedSwSet.sw_R)\n                            {\n                                allowedSwModeSet.value &= Gfx10RenderSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx10DisplaySwModeMask;\n                            }\n                            else if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx10StandardSwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_Z);\n                                allowedSwModeSet.value &= Gfx10ZSwModeMask;\n                            }\n                        }\n\n                        // Swizzle type should be determined.\n                        ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));\n                    }\n\n                    // Determine swizzle mode now. Always select the \"largest\" swizzle mode for a given block type +\n                    // swizzle type combination. E.g, for AddrBlockThin64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's\n                    // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).\n                    pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));\n                }\n            }\n            else\n            {\n                // Invalid combination...\n                ADDR_ASSERT_ALWAYS();\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n        }\n        else\n        {\n            // Invalid combination...\n            ADDR_ASSERT_ALWAYS();\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeStereoInfo\n*\n*   @brief\n*       Compute height alignment and right eye pipeBankXor for stereo surface\n*\n*   @return\n*       Error code\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::ComputeStereoInfo(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,        ///< Compute surface info\n    UINT_32*                                pAlignY,    ///< Stereo requested additional alignment in Y\n    UINT_32*                                pRightXor   ///< Right eye xor\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    *pRightXor = 0;\n\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 rsrcType    = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swMode      = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 eqIndex     = m_equationLookupTable[rsrcType][swMode][elemLog2];\n\n        if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n        {\n            UINT_32 yMax     = 0;\n            UINT_32 yPosMask = 0;\n\n            // First get \"max y bit\"\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)\n            {\n                ADDR_ASSERT(m_equationTable[eqIndex].addr[i].valid == 1);\n\n                if ((m_equationTable[eqIndex].addr[i].channel == 1) &&\n                    (m_equationTable[eqIndex].addr[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].addr[i].index;\n                }\n\n                if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&\n                    (m_equationTable[eqIndex].xor1[i].channel == 1) &&\n                    (m_equationTable[eqIndex].xor1[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].xor1[i].index;\n                }\n\n                if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&\n                    (m_equationTable[eqIndex].xor2[i].channel == 1) &&\n                    (m_equationTable[eqIndex].xor2[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].xor2[i].index;\n                }\n            }\n\n            // Then loop again for populating a position mask of \"max Y bit\"\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)\n            {\n                if ((m_equationTable[eqIndex].addr[i].channel == 1) &&\n                    (m_equationTable[eqIndex].addr[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n                else if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&\n                         (m_equationTable[eqIndex].xor1[i].channel == 1) &&\n                         (m_equationTable[eqIndex].xor1[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n                else if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&\n                         (m_equationTable[eqIndex].xor2[i].channel == 1) &&\n                         (m_equationTable[eqIndex].xor2[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n            }\n\n            const UINT_32 additionalAlign = 1 << yMax;\n\n            if (additionalAlign >= *pAlignY)\n            {\n                *pAlignY = additionalAlign;\n\n                const UINT_32 alignedHeight = PowTwoAlign(pIn->height, additionalAlign);\n\n                if ((alignedHeight >> yMax) & 1)\n                {\n                    *pRightXor = yPosMask >> m_pipeInterleaveLog2;\n                }\n            }\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSurfaceInfoTiled\n*\n*   @brief\n*       Internal function to calculate alignment for tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSurfaceInfoTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    // Mip chain dimesion and epitch has no meaning in GFX10, set to default value\n    pOut->mipChainPitch    = 0;\n    pOut->mipChainHeight   = 0;\n    pOut->mipChainSlice    = 0;\n    pOut->epitchIsHeight   = FALSE;\n\n    // Following information will be provided in ComputeSurfaceInfoMacroTiled() if necessary\n    pOut->mipChainInTail   = FALSE;\n    pOut->firstMipIdInTail = pIn->numMipLevels;\n\n    if (IsBlock256b(pIn->swizzleMode))\n    {\n        ret = ComputeSurfaceInfoMicroTiled(pIn, pOut);\n    }\n    else\n    {\n        ret = ComputeSurfaceInfoMacroTiled(pIn, pOut);\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeSurfaceInfoMicroTiled\n*\n*   @brief\n*       Internal function to calculate alignment for micro tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceInfoMicroTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret = ComputeBlockDimensionForSurf(&pOut->blockWidth,\n                                                         &pOut->blockHeight,\n                                                         &pOut->blockSlices,\n                                                         pIn->bpp,\n                                                         pIn->numFrags,\n                                                         pIn->resourceType,\n                                                         pIn->swizzleMode);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 blockSize = GetBlockSize(pIn->swizzleMode);\n\n        pOut->pitch     = PowTwoAlign(pIn->width,  pOut->blockWidth);\n        pOut->height    = PowTwoAlign(pIn->height, pOut->blockHeight);\n        pOut->numSlices = pIn->numSlices;\n        pOut->baseAlign = blockSize;\n\n        if (pIn->numMipLevels > 1)\n        {\n            const UINT_32 mip0Width    = pIn->width;\n            const UINT_32 mip0Height   = pIn->height;\n            UINT_64       mipSliceSize = 0;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(mip0Width, mip0Height, 1, i, &mipWidth, &mipHeight);\n\n                const UINT_32 mipActualWidth  = PowTwoAlign(mipWidth,  pOut->blockWidth);\n                const UINT_32 mipActualHeight = PowTwoAlign(mipHeight, pOut->blockHeight);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].pitch            = mipActualWidth;\n                    pOut->pMipInfo[i].height           = mipActualHeight;\n                    pOut->pMipInfo[i].depth            = 1;\n                    pOut->pMipInfo[i].offset           = mipSliceSize;\n                    pOut->pMipInfo[i].mipTailOffset    = 0;\n                    pOut->pMipInfo[i].macroBlockOffset = mipSliceSize;\n                }\n\n                mipSliceSize += mipActualWidth * mipActualHeight * (pIn->bpp >> 3);\n            }\n\n            pOut->sliceSize = mipSliceSize;\n            pOut->surfSize  = mipSliceSize * pOut->numSlices;\n        }\n        else\n        {\n            pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3);\n            pOut->surfSize  = pOut->sliceSize * pOut->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].pitch            = pOut->pitch;\n                pOut->pMipInfo[0].height           = pOut->height;\n                pOut->pMipInfo[0].depth            = 1;\n                pOut->pMipInfo[0].offset           = 0;\n                pOut->pMipInfo[0].mipTailOffset    = 0;\n                pOut->pMipInfo[0].macroBlockOffset = 0;\n            }\n        }\n\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeSurfaceInfoMacroTiled\n*\n*   @brief\n*       Internal function to calculate alignment for macro tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceInfoMacroTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,\n                                                                &pOut->blockHeight,\n                                                                &pOut->blockSlices,\n                                                                pIn->bpp,\n                                                                pIn->numFrags,\n                                                                pIn->resourceType,\n                                                                pIn->swizzleMode);\n\n    if (returnCode == ADDR_OK)\n    {\n        UINT_32 heightAlign = pOut->blockHeight;\n\n        if (pIn->flags.qbStereo)\n        {\n            UINT_32 rightXor = 0;\n\n            returnCode = ComputeStereoInfo(pIn, &heightAlign, &rightXor);\n\n            if (returnCode == ADDR_OK)\n            {\n                pOut->pStereoInfo->rightSwizzle = rightXor;\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n            const UINT_32 blockSize     = 1 << blockSizeLog2;\n\n            pOut->pitch     = PowTwoAlign(pIn->width,     pOut->blockWidth);\n            pOut->height    = PowTwoAlign(pIn->height,    heightAlign);\n            pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);\n            pOut->baseAlign = blockSize;\n\n            if (pIn->numMipLevels > 1)\n            {\n                const Dim3d  tailMaxDim         = GetMipTailDim(pIn->resourceType,\n                                                                pIn->swizzleMode,\n                                                                pOut->blockWidth,\n                                                                pOut->blockHeight,\n                                                                pOut->blockSlices);\n                const UINT_32 mip0Width         = pIn->width;\n                const UINT_32 mip0Height        = pIn->height;\n                const BOOL_32 isThin            = IsThin(pIn->resourceType, pIn->swizzleMode);\n                const UINT_32 mip0Depth         = isThin ? 1 : pIn->numSlices;\n                const UINT_32 maxMipsInTail     = GetMaxNumMipsInTail(blockSizeLog2, isThin);\n                const UINT_32 index             = Log2(pIn->bpp >> 3);\n                UINT_32       firstMipInTail    = pIn->numMipLevels;\n                UINT_64       mipChainSliceSize = 0;\n                UINT_64       mipSize[MaxMipLevels];\n                UINT_64       mipSliceSize[MaxMipLevels];\n\n                ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n                Dim3d fixedTailMaxDim = tailMaxDim;\n\n                if (m_settings.dsMipmapHtileFix && IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))\n                {\n                    fixedTailMaxDim.w /= Block256_2d[index].w / Block256_2d[2].w;\n                    fixedTailMaxDim.h /= Block256_2d[index].h / Block256_2d[2].h;\n                }\n\n                for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n                {\n                    UINT_32 mipWidth, mipHeight, mipDepth;\n\n                    GetMipSize(mip0Width, mip0Height, mip0Depth, i, &mipWidth, &mipHeight, &mipDepth);\n\n                    if (IsInMipTail(fixedTailMaxDim, maxMipsInTail, mipWidth, mipHeight, pIn->numMipLevels - i))\n                    {\n                        firstMipInTail     = i;\n                        mipChainSliceSize += blockSize / pOut->blockSlices;\n                        break;\n                    }\n                    else\n                    {\n                        const UINT_32 pitch     = PowTwoAlign(mipWidth,  pOut->blockWidth);\n                        const UINT_32 height    = PowTwoAlign(mipHeight, pOut->blockHeight);\n                        const UINT_32 depth     = PowTwoAlign(mipDepth,  pOut->blockSlices);\n                        const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height * (pIn->bpp >> 3);\n\n                        mipSize[i]         = sliceSize * depth;\n                        mipSliceSize[i]    = sliceSize * pOut->blockSlices;\n                        mipChainSliceSize += sliceSize;\n\n                        if (pOut->pMipInfo != NULL)\n                        {\n                            pOut->pMipInfo[i].pitch  = pitch;\n                            pOut->pMipInfo[i].height = height;\n                            pOut->pMipInfo[i].depth  = IsTex3d(pIn->resourceType) ? pOut->numSlices : 1;\n                        }\n                    }\n                }\n\n                pOut->sliceSize        = mipChainSliceSize;\n                pOut->surfSize         = mipChainSliceSize * pOut->numSlices;\n                pOut->mipChainInTail   = (firstMipInTail == 0) ? TRUE : FALSE;\n                pOut->firstMipIdInTail = firstMipInTail;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    UINT_64 offset         = 0;\n                    UINT_64 macroBlkOffset = 0;\n                    UINT_32 tailMaxDepth   = 0;\n\n                    if (firstMipInTail != pIn->numMipLevels)\n                    {\n                        UINT_32 mipWidth, mipHeight;\n\n                        GetMipSize(mip0Width, mip0Height, mip0Depth, firstMipInTail,\n                                   &mipWidth, &mipHeight, &tailMaxDepth);\n\n                        offset         = blockSize * PowTwoAlign(tailMaxDepth, pOut->blockSlices) / pOut->blockSlices;\n                        macroBlkOffset = blockSize;\n                    }\n\n                    for (INT_32 i = firstMipInTail - 1; i >= 0; i--)\n                    {\n                        pOut->pMipInfo[i].offset           = offset;\n                        pOut->pMipInfo[i].macroBlockOffset = macroBlkOffset;\n                        pOut->pMipInfo[i].mipTailOffset    = 0;\n\n                        offset         += mipSize[i];\n                        macroBlkOffset += mipSliceSize[i];\n                    }\n\n                    UINT_32 pitch  = tailMaxDim.w;\n                    UINT_32 height = tailMaxDim.h;\n                    UINT_32 depth  = isThin ? 1 : PowTwoAlign(tailMaxDepth, Block256_3d[index].d);\n\n                    tailMaxDepth = isThin ? 1 : (depth / Block256_3d[index].d);\n\n                    for (UINT_32 i = firstMipInTail; i < pIn->numMipLevels; i++)\n                    {\n                        const UINT_32 m         = maxMipsInTail - 1 - (i - firstMipInTail);\n                        const UINT_32 mipOffset = (m > 6) ? (16 << m) : (m << 8);\n\n                        pOut->pMipInfo[i].offset           = mipOffset * tailMaxDepth;\n                        pOut->pMipInfo[i].mipTailOffset    = mipOffset;\n                        pOut->pMipInfo[i].macroBlockOffset = 0;\n\n                        pOut->pMipInfo[i].pitch  = pitch;\n                        pOut->pMipInfo[i].height = height;\n                        pOut->pMipInfo[i].depth  = IsTex3d(pIn->resourceType) ? pOut->numSlices : 1;\n\n                        UINT_32 mipX = ((mipOffset >> 9)  & 1)  |\n                                       ((mipOffset >> 10) & 2)  |\n                                       ((mipOffset >> 11) & 4)  |\n                                       ((mipOffset >> 12) & 8)  |\n                                       ((mipOffset >> 13) & 16) |\n                                       ((mipOffset >> 14) & 32);\n                        UINT_32 mipY = ((mipOffset >> 8)  & 1)  |\n                                       ((mipOffset >> 9)  & 2)  |\n                                       ((mipOffset >> 10) & 4)  |\n                                       ((mipOffset >> 11) & 8)  |\n                                       ((mipOffset >> 12) & 16) |\n                                       ((mipOffset >> 13) & 32);\n\n                        if (blockSizeLog2 & 1)\n                        {\n                            const UINT_32 temp = mipX;\n                            mipX = mipY;\n                            mipY = temp;\n\n                            if (index & 1)\n                            {\n                                mipY = (mipY << 1) | (mipX & 1);\n                                mipX = mipX >> 1;\n                            }\n                        }\n\n                        if (isThin)\n                        {\n                            pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_2d[index].w;\n                            pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_2d[index].h;\n                            pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                            pitch  = Max(pitch  >> 1, Block256_2d[index].w);\n                            height = Max(height >> 1, Block256_2d[index].h);\n                        }\n                        else\n                        {\n                            pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_3d[index].w;\n                            pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_3d[index].h;\n                            pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                            pitch  = Max(pitch  >> 1, Block256_3d[index].w);\n                            height = Max(height >> 1, Block256_3d[index].h);\n                        }\n                    }\n                }\n            }\n            else\n            {\n                pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3) * pIn->numFrags;\n                pOut->surfSize  = pOut->sliceSize * pOut->numSlices;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].pitch            = pOut->pitch;\n                    pOut->pMipInfo[0].height           = pOut->height;\n                    pOut->pMipInfo[0].depth            = IsTex3d(pIn->resourceType) ? pOut->numSlices : 1;\n                    pOut->pMipInfo[0].offset           = 0;\n                    pOut->pMipInfo[0].mipTailOffset    = 0;\n                    pOut->pMipInfo[0].macroBlockOffset = 0;\n                    pOut->pMipInfo[0].mipTailCoordX    = 0;\n                    pOut->pMipInfo[0].mipTailCoordY    = 0;\n                    pOut->pMipInfo[0].mipTailCoordZ    = 0;\n                }\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    if (IsBlock256b(pIn->swizzleMode))\n    {\n        ret = ComputeSurfaceAddrFromCoordMicroTiled(pIn, pOut);\n    }\n    else\n    {\n        ret = ComputeSurfaceAddrFromCoordMacroTiled(pIn, pOut);\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeOffsetFromEquation\n*\n*   @brief\n*       Compute offset from equation\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::ComputeOffsetFromEquation(\n    const ADDR_EQUATION* pEq,   ///< Equation\n    UINT_32              x,     ///< x coord in bytes\n    UINT_32              y,     ///< y coord in pixel\n    UINT_32              z      ///< z coord in slice\n    ) const\n{\n    UINT_32 offset = 0;\n\n    for (UINT_32 i = 0; i < pEq->numBits; i++)\n    {\n        UINT_32 v = 0;\n\n        for (UINT_32 c = 0; c < pEq->numBitComponents; c++)\n        {\n            if (pEq->comps[c][i].valid)\n            {\n                if (pEq->comps[c][i].channel == 0)\n                {\n                    v ^= (x >> pEq->comps[c][i].index) & 1;\n                }\n                else if (pEq->comps[c][i].channel == 1)\n                {\n                    v ^= (y >> pEq->comps[c][i].index) & 1;\n                }\n                else\n                {\n                    ADDR_ASSERT(pEq->comps[c][i].channel == 2);\n                    v ^= (z >> pEq->comps[c][i].index) & 1;\n                }\n            }\n        }\n\n        offset |= (v << i);\n    }\n\n    return offset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeOffsetFromSwizzlePattern\n*\n*   @brief\n*       Compute offset from swizzle pattern\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::ComputeOffsetFromSwizzlePattern(\n    const UINT_64* pPattern,    ///< Swizzle pattern\n    UINT_32        numBits,     ///< Number of bits in pattern\n    UINT_32        x,           ///< x coord in pixel\n    UINT_32        y,           ///< y coord in pixel\n    UINT_32        z,           ///< z coord in slice\n    UINT_32        s            ///< sample id\n    ) const\n{\n    UINT_32                 offset          = 0;\n    const ADDR_BIT_SETTING* pSwizzlePattern = reinterpret_cast<const ADDR_BIT_SETTING*>(pPattern);\n\n    for (UINT_32 i = 0; i < numBits; i++)\n    {\n        UINT_32 v = 0;\n\n        if (pSwizzlePattern[i].x != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].x;\n            UINT_32 xBits = x;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= xBits & 1;\n                }\n\n                xBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].y != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].y;\n            UINT_32 yBits = y;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= yBits & 1;\n                }\n\n                yBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].z != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].z;\n            UINT_32 zBits = z;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= zBits & 1;\n                }\n\n                zBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].s != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].s;\n            UINT_32 sBits = s;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= sBits & 1;\n                }\n\n                sBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        offset |= (v << i);\n    }\n\n    return offset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetSwizzlePatternInfo\n*\n*   @brief\n*       Get swizzle pattern\n*\n*   @return\n*       Swizzle pattern information\n************************************************************************************************************************\n*/\nconst ADDR_SW_PATINFO* Gfx10Lib::GetSwizzlePatternInfo(\n    AddrSwizzleMode  swizzleMode,       ///< Swizzle mode\n    AddrResourceType resourceType,      ///< Resource type\n    UINT_32          elemLog2,          ///< Element size in bytes log2\n    UINT_32          numFrag            ///< Number of fragment\n    ) const\n{\n    // Now elemLog2 is going to be used to access the correct index insode of the pPatInfo array so we will start from\n    // the right location\n    const UINT_32          index       = IsXor(swizzleMode) ? (m_colorBaseIndex + elemLog2) : elemLog2;\n    const ADDR_SW_PATINFO* patInfo     = NULL;\n    const UINT_32          swizzleMask = 1 << swizzleMode;\n\n    if (IsBlockVariable(swizzleMode))\n    {\n        if (m_blockVarSizeLog2 != 0)\n        {\n            ADDR_ASSERT(m_settings.supportRbPlus);\n\n            if (IsRtOptSwizzle(swizzleMode))\n            {\n                if (numFrag == 1)\n                {\n                    patInfo = GFX10_SW_VAR_R_X_1xaa_RBPLUS_PATINFO;\n                }\n                else if (numFrag == 2)\n                {\n                    patInfo = GFX10_SW_VAR_R_X_2xaa_RBPLUS_PATINFO;\n                }\n                else if (numFrag == 4)\n                {\n                    patInfo = GFX10_SW_VAR_R_X_4xaa_RBPLUS_PATINFO;\n                }\n                else\n                {\n                    ADDR_ASSERT(numFrag == 8);\n                    patInfo = GFX10_SW_VAR_R_X_8xaa_RBPLUS_PATINFO;\n                }\n            }\n            else if (IsZOrderSwizzle(swizzleMode))\n            {\n                if (numFrag == 1)\n                {\n                    patInfo = GFX10_SW_VAR_Z_X_1xaa_RBPLUS_PATINFO;\n                }\n                else if (numFrag == 2)\n                {\n                    patInfo = GFX10_SW_VAR_Z_X_2xaa_RBPLUS_PATINFO;\n                }\n                else if (numFrag == 4)\n                {\n                    patInfo = GFX10_SW_VAR_Z_X_4xaa_RBPLUS_PATINFO;\n                }\n                else\n                {\n                    ADDR_ASSERT(numFrag == 8);\n                    patInfo = GFX10_SW_VAR_Z_X_8xaa_RBPLUS_PATINFO;\n                }\n            }\n        }\n    }\n    else if (IsLinear(swizzleMode) == FALSE)\n    {\n        if (resourceType == ADDR_RSRC_TEX_3D)\n        {\n            ADDR_ASSERT(numFrag == 1);\n\n            if ((swizzleMask & Gfx10Rsrc3dSwModeMask) != 0)\n            {\n                if (IsRtOptSwizzle(swizzleMode))\n                {\n                    if (swizzleMode == ADDR_SW_4KB_R_X)\n                    {\n                        patInfo = NULL;\n                    }\n                    else\n                    {\n                        patInfo = m_settings.supportRbPlus ?\n                                  GFX10_SW_64K_R_X_1xaa_RBPLUS_PATINFO : GFX10_SW_64K_R_X_1xaa_PATINFO;\n                    }\n                }\n                else if (IsZOrderSwizzle(swizzleMode))\n                {\n                    patInfo = m_settings.supportRbPlus ?\n                              GFX10_SW_64K_Z_X_1xaa_RBPLUS_PATINFO : GFX10_SW_64K_Z_X_1xaa_PATINFO;\n                }\n                else if (IsDisplaySwizzle(resourceType, swizzleMode))\n                {\n                    ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_D_X);\n                    patInfo = m_settings.supportRbPlus ?\n                              GFX10_SW_64K_D3_X_RBPLUS_PATINFO : GFX10_SW_64K_D3_X_PATINFO;\n                }\n                else\n                {\n                    ADDR_ASSERT(IsStandardSwizzle(resourceType, swizzleMode));\n\n                    if (IsBlock4kb(swizzleMode))\n                    {\n                        if (swizzleMode == ADDR_SW_4KB_S)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_S3_RBPLUS_PATINFO : GFX10_SW_4K_S3_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_4KB_S_X);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_S3_X_RBPLUS_PATINFO : GFX10_SW_4K_S3_X_PATINFO;\n                        }\n                    }\n                    else\n                    {\n                        if (swizzleMode == ADDR_SW_64KB_S)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S3_RBPLUS_PATINFO : GFX10_SW_64K_S3_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_S_X)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S3_X_RBPLUS_PATINFO : GFX10_SW_64K_S3_X_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_S_T);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S3_T_RBPLUS_PATINFO : GFX10_SW_64K_S3_T_PATINFO;\n                        }\n                    }\n                }\n            }\n        }\n        else\n        {\n            if ((swizzleMask & Gfx10Rsrc2dSwModeMask) != 0)\n            {\n                if (IsBlock256b(swizzleMode))\n                {\n                    if (swizzleMode == ADDR_SW_256B_S)\n                    {\n                        patInfo = m_settings.supportRbPlus ?\n                                  GFX10_SW_256_S_RBPLUS_PATINFO : GFX10_SW_256_S_PATINFO;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(swizzleMode == ADDR_SW_256B_D);\n                        patInfo = m_settings.supportRbPlus ?\n                                  GFX10_SW_256_D_RBPLUS_PATINFO : GFX10_SW_256_D_PATINFO;\n                    }\n                }\n                else if (IsBlock4kb(swizzleMode))\n                {\n                    if (IsStandardSwizzle(resourceType, swizzleMode))\n                    {\n                        if (swizzleMode == ADDR_SW_4KB_S)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_S_RBPLUS_PATINFO : GFX10_SW_4K_S_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_4KB_S_X);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_S_X_RBPLUS_PATINFO : GFX10_SW_4K_S_X_PATINFO;\n                        }\n                    }\n                    else\n                    {\n                        if (swizzleMode == ADDR_SW_4KB_D)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_D_RBPLUS_PATINFO : GFX10_SW_4K_D_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_4KB_R_X)\n                        {\n                            patInfo = NULL;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_4KB_D_X);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_4K_D_X_RBPLUS_PATINFO : GFX10_SW_4K_D_X_PATINFO;\n                        }\n                    }\n                }\n                else\n                {\n                    if (IsRtOptSwizzle(swizzleMode))\n                    {\n                        if (numFrag == 1)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_R_X_1xaa_RBPLUS_PATINFO : GFX10_SW_64K_R_X_1xaa_PATINFO;\n                        }\n                        else if (numFrag == 2)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_R_X_2xaa_RBPLUS_PATINFO : GFX10_SW_64K_R_X_2xaa_PATINFO;\n                        }\n                        else if (numFrag == 4)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_R_X_4xaa_RBPLUS_PATINFO : GFX10_SW_64K_R_X_4xaa_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(numFrag == 8);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_R_X_8xaa_RBPLUS_PATINFO : GFX10_SW_64K_R_X_8xaa_PATINFO;\n                        }\n                    }\n                    else if (IsZOrderSwizzle(swizzleMode))\n                    {\n                        if (numFrag == 1)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_Z_X_1xaa_RBPLUS_PATINFO : GFX10_SW_64K_Z_X_1xaa_PATINFO;\n                        }\n                        else if (numFrag == 2)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_Z_X_2xaa_RBPLUS_PATINFO : GFX10_SW_64K_Z_X_2xaa_PATINFO;\n                        }\n                        else if (numFrag == 4)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_Z_X_4xaa_RBPLUS_PATINFO : GFX10_SW_64K_Z_X_4xaa_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(numFrag == 8);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_Z_X_8xaa_RBPLUS_PATINFO : GFX10_SW_64K_Z_X_8xaa_PATINFO;\n                        }\n                    }\n                    else if (IsDisplaySwizzle(resourceType, swizzleMode))\n                    {\n                        if (swizzleMode == ADDR_SW_64KB_D)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_D_RBPLUS_PATINFO : GFX10_SW_64K_D_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_D_X)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_D_X_RBPLUS_PATINFO : GFX10_SW_64K_D_X_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_D_T);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_D_T_RBPLUS_PATINFO : GFX10_SW_64K_D_T_PATINFO;\n                        }\n                    }\n                    else\n                    {\n                        if (swizzleMode == ADDR_SW_64KB_S)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S_RBPLUS_PATINFO : GFX10_SW_64K_S_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_S_X)\n                        {\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S_X_RBPLUS_PATINFO : GFX10_SW_64K_S_X_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_S_T);\n                            patInfo = m_settings.supportRbPlus ?\n                                      GFX10_SW_64K_S_T_RBPLUS_PATINFO : GFX10_SW_64K_S_T_PATINFO;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return (patInfo != NULL) ? &patInfo[index] : NULL;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for micro tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n    ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];\n    ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pIn->resourceType;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unalignedWidth,  1u);\n    localIn.height       = Max(pIn->unalignedHeight, 1u);\n    localIn.numSlices    = Max(pIn->numSlices,       1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels,    1u);\n    localIn.numSamples   = Max(pIn->numSamples,      1u);\n    localIn.numFrags     = Max(pIn->numFrags,        1u);\n    localOut.pMipInfo    = mipInfo;\n\n    ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMicroTiled(&localIn, &localOut);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);\n        const UINT_32 rsrcType = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swMode   = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 eqIndex  = m_equationLookupTable[rsrcType][swMode][elemLog2];\n\n        if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n        {\n            const UINT_32 pb           = mipInfo[pIn->mipId].pitch / localOut.blockWidth;\n            const UINT_32 yb           = pIn->y / localOut.blockHeight;\n            const UINT_32 xb           = pIn->x / localOut.blockWidth;\n            const UINT_32 blockIndex   = yb * pb + xb;\n            const UINT_32 blockSize    = 256;\n            const UINT_32 blk256Offset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                   pIn->x << elemLog2,\n                                                                   pIn->y,\n                                                                   0);\n            pOut->addr = localOut.sliceSize * pIn->slice +\n                         mipInfo[pIn->mipId].macroBlockOffset +\n                         (blockIndex * blockSize) +\n                         blk256Offset;\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for macro tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n    ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];\n    ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);\n\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pIn->resourceType;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unalignedWidth,  1u);\n    localIn.height       = Max(pIn->unalignedHeight, 1u);\n    localIn.numSlices    = Max(pIn->numSlices,       1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels,    1u);\n    localIn.numSamples   = Max(pIn->numSamples,      1u);\n    localIn.numFrags     = Max(pIn->numFrags,        1u);\n    localOut.pMipInfo    = mipInfo;\n\n    ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMacroTiled(&localIn, &localOut);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 blkMask     = (1 << blkSizeLog2) - 1;\n        const UINT_32 pipeMask    = (1 << m_pipesLog2) - 1;\n        const UINT_32 bankMask    = ((1 << GetBankXorBits(blkSizeLog2)) - 1) << (m_pipesLog2 + ColumnBits);\n        const UINT_32 pipeBankXor = IsXor(pIn->swizzleMode) ?\n                                    (((pIn->pipeBankXor & (pipeMask | bankMask)) << m_pipeInterleaveLog2) & blkMask) : 0;\n\n        if (localIn.numFrags > 1)\n        {\n            const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,\n                                                                    pIn->resourceType,\n                                                                    elemLog2,\n                                                                    localIn.numFrags);\n\n            if (pPatInfo != NULL)\n            {\n                const UINT_32 pb        = localOut.pitch / localOut.blockWidth;\n                const UINT_32 yb        = pIn->y / localOut.blockHeight;\n                const UINT_32 xb        = pIn->x / localOut.blockWidth;\n                const UINT_64 blkIdx    = yb * pb + xb;\n\n                ADDR_BIT_SETTING fullSwizzlePattern[20];\n                GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n                const UINT_32 blkOffset =\n                    ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),\n                                                    blkSizeLog2,\n                                                    pIn->x,\n                                                    pIn->y,\n                                                    pIn->slice,\n                                                    pIn->sample);\n\n                pOut->addr = (localOut.sliceSize * pIn->slice) +\n                             (blkIdx << blkSizeLog2) +\n                             (blkOffset ^ pipeBankXor);\n            }\n            else\n            {\n                ret = ADDR_INVALIDPARAMS;\n            }\n        }\n        else\n        {\n            const UINT_32 rsrcIdx = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? 1 : 0;\n            const UINT_32 swMode  = static_cast<UINT_32>(pIn->swizzleMode);\n            const UINT_32 eqIndex = m_equationLookupTable[rsrcIdx][swMode][elemLog2];\n\n            if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n            {\n                const BOOL_32 inTail    = (mipInfo[pIn->mipId].mipTailOffset != 0) ? TRUE : FALSE;\n                const BOOL_32 isThin    = IsThin(pIn->resourceType, pIn->swizzleMode);\n                const UINT_64 sliceSize = isThin ? localOut.sliceSize : (localOut.sliceSize * localOut.blockSlices);\n                const UINT_32 sliceId   = isThin ? pIn->slice : (pIn->slice / localOut.blockSlices);\n                const UINT_32 x         = inTail ? (pIn->x     + mipInfo[pIn->mipId].mipTailCoordX) : pIn->x;\n                const UINT_32 y         = inTail ? (pIn->y     + mipInfo[pIn->mipId].mipTailCoordY) : pIn->y;\n                const UINT_32 z         = inTail ? (pIn->slice + mipInfo[pIn->mipId].mipTailCoordZ) : pIn->slice;\n                const UINT_32 pb        = mipInfo[pIn->mipId].pitch / localOut.blockWidth;\n                const UINT_32 yb        = pIn->y / localOut.blockHeight;\n                const UINT_32 xb        = pIn->x / localOut.blockWidth;\n                const UINT_64 blkIdx    = yb * pb + xb;\n                const UINT_32 blkOffset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                    x << elemLog2,\n                                                                    y,\n                                                                    z);\n                pOut->addr = sliceSize * sliceId +\n                             mipInfo[pIn->mipId].macroBlockOffset +\n                             (blkIdx << blkSizeLog2) +\n                             (blkOffset ^ pipeBankXor);\n            }\n            else\n            {\n                ret = ADDR_INVALIDPARAMS;\n            }\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeMaxBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments\n*   @return\n*       maximum alignments\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::HwlComputeMaxBaseAlignments() const\n{\n    return m_blockVarSizeLog2 ? Max(Size64K, 1u << m_blockVarSizeLog2) : Size64K;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeMaxMetaBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments for metadata\n*   @return\n*       maximum alignments for metadata\n************************************************************************************************************************\n*/\nUINT_32 Gfx10Lib::HwlComputeMaxMetaBaseAlignments() const\n{\n    Dim3d metaBlk;\n\n    const AddrSwizzleMode ValidSwizzleModeForXmask[] =\n    {\n        ADDR_SW_64KB_Z_X,\n        m_blockVarSizeLog2 ? ADDR_SW_VAR_Z_X : ADDR_SW_64KB_Z_X,\n    };\n\n    UINT_32 maxBaseAlignHtile = 0;\n    UINT_32 maxBaseAlignCmask = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForXmask) / sizeof(ValidSwizzleModeForXmask[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < 3; bppLog2++)\n        {\n            for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)\n            {\n                // Max base alignment for Htile\n                const UINT_32 metaBlkSizeHtile = GetMetaBlkSize(Gfx10DataDepthStencil,\n                                                                ADDR_RSRC_TEX_2D,\n                                                                ValidSwizzleModeForXmask[swIdx],\n                                                                bppLog2,\n                                                                numFragLog2,\n                                                                TRUE,\n                                                                &metaBlk);\n\n                maxBaseAlignHtile = Max(maxBaseAlignHtile, metaBlkSizeHtile);\n            }\n        }\n\n        // Max base alignment for Cmask\n        const UINT_32 metaBlkSizeCmask = GetMetaBlkSize(Gfx10DataFmask,\n                                                        ADDR_RSRC_TEX_2D,\n                                                        ValidSwizzleModeForXmask[swIdx],\n                                                        0,\n                                                        0,\n                                                        TRUE,\n                                                        &metaBlk);\n\n        maxBaseAlignCmask = Max(maxBaseAlignCmask, metaBlkSizeCmask);\n    }\n\n    // Max base alignment for 2D Dcc\n    const AddrSwizzleMode ValidSwizzleModeForDcc2D[] =\n    {\n        ADDR_SW_64KB_S_X,\n        ADDR_SW_64KB_D_X,\n        ADDR_SW_64KB_R_X,\n        m_blockVarSizeLog2 ? ADDR_SW_VAR_R_X : ADDR_SW_64KB_R_X,\n    };\n\n    UINT_32 maxBaseAlignDcc2D = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc2D) / sizeof(ValidSwizzleModeForDcc2D[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)\n        {\n            for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)\n            {\n                const UINT_32 metaBlkSize2D = GetMetaBlkSize(Gfx10DataColor,\n                                                             ADDR_RSRC_TEX_2D,\n                                                             ValidSwizzleModeForDcc2D[swIdx],\n                                                             bppLog2,\n                                                             numFragLog2,\n                                                             TRUE,\n                                                             &metaBlk);\n\n                maxBaseAlignDcc2D = Max(maxBaseAlignDcc2D, metaBlkSize2D);\n            }\n        }\n    }\n\n    // Max base alignment for 3D Dcc\n    const AddrSwizzleMode ValidSwizzleModeForDcc3D[] =\n    {\n        ADDR_SW_64KB_Z_X,\n        ADDR_SW_64KB_S_X,\n        ADDR_SW_64KB_D_X,\n        ADDR_SW_64KB_R_X,\n        m_blockVarSizeLog2 ? ADDR_SW_VAR_R_X : ADDR_SW_64KB_R_X,\n    };\n\n    UINT_32 maxBaseAlignDcc3D = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc3D) / sizeof(ValidSwizzleModeForDcc3D[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)\n        {\n            const UINT_32 metaBlkSize3D = GetMetaBlkSize(Gfx10DataColor,\n                                                         ADDR_RSRC_TEX_3D,\n                                                         ValidSwizzleModeForDcc3D[swIdx],\n                                                         bppLog2,\n                                                         0,\n                                                         TRUE,\n                                                         &metaBlk);\n\n            maxBaseAlignDcc3D = Max(maxBaseAlignDcc3D, metaBlkSize3D);\n        }\n    }\n\n    return Max(Max(maxBaseAlignHtile, maxBaseAlignCmask), Max(maxBaseAlignDcc2D, maxBaseAlignDcc3D));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetMetaElementSizeLog2\n*\n*   @brief\n*       Gets meta data element size log2\n*   @return\n*       Meta data element size log2\n************************************************************************************************************************\n*/\nINT_32 Gfx10Lib::GetMetaElementSizeLog2(\n    Gfx10DataType dataType) ///< Data surface type\n{\n    INT_32 elemSizeLog2 = 0;\n\n    if (dataType == Gfx10DataColor)\n    {\n        elemSizeLog2 = 0;\n    }\n    else if (dataType == Gfx10DataDepthStencil)\n    {\n        elemSizeLog2 = 2;\n    }\n    else\n    {\n        ADDR_ASSERT(dataType == Gfx10DataFmask);\n        elemSizeLog2 = -1;\n    }\n\n    return elemSizeLog2;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::GetMetaCacheSizeLog2\n*\n*   @brief\n*       Gets meta data cache line size log2\n*   @return\n*       Meta data cache line size log2\n************************************************************************************************************************\n*/\nINT_32 Gfx10Lib::GetMetaCacheSizeLog2(\n    Gfx10DataType dataType) ///< Data surface type\n{\n    INT_32 cacheSizeLog2 = 0;\n\n    if (dataType == Gfx10DataColor)\n    {\n        cacheSizeLog2 = 6;\n    }\n    else if (dataType == Gfx10DataDepthStencil)\n    {\n        cacheSizeLog2 = 8;\n    }\n    else\n    {\n        ADDR_ASSERT(dataType == Gfx10DataFmask);\n        cacheSizeLog2 = 8;\n    }\n    return cacheSizeLog2;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx10Lib::HwlComputeSurfaceInfoLinear\n*\n*   @brief\n*       Internal function to calculate alignment for linear surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx10Lib::HwlComputeSurfaceInfoLinear(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsTex1d(pIn->resourceType) && (pIn->height > 1))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        const UINT_32 elementBytes = pIn->bpp >> 3;\n        const UINT_32 pitchAlign   = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 / elementBytes);\n        const UINT_32 mipDepth     = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? pIn->numSlices : 1;\n        UINT_32       pitch        = PowTwoAlign(pIn->width, pitchAlign);\n        UINT_32       actualHeight = pIn->height;\n        UINT_64       sliceSize    = 0;\n\n        if (pIn->numMipLevels > 1)\n        {\n            for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(pIn->width, pIn->height, 1, i, &mipWidth, &mipHeight);\n\n                const UINT_32 mipActualWidth = PowTwoAlign(mipWidth, pitchAlign);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].pitch            = mipActualWidth;\n                    pOut->pMipInfo[i].height           = mipHeight;\n                    pOut->pMipInfo[i].depth            = mipDepth;\n                    pOut->pMipInfo[i].offset           = sliceSize;\n                    pOut->pMipInfo[i].mipTailOffset    = 0;\n                    pOut->pMipInfo[i].macroBlockOffset = sliceSize;\n                }\n\n                sliceSize += static_cast<UINT_64>(mipActualWidth) * mipHeight * elementBytes;\n            }\n        }\n        else\n        {\n            returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlign, &pitch, &actualHeight);\n\n            if (returnCode == ADDR_OK)\n            {\n                sliceSize = static_cast<UINT_64>(pitch) * actualHeight * elementBytes;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].pitch            = pitch;\n                    pOut->pMipInfo[0].height           = actualHeight;\n                    pOut->pMipInfo[0].depth            = mipDepth;\n                    pOut->pMipInfo[0].offset           = 0;\n                    pOut->pMipInfo[0].mipTailOffset    = 0;\n                    pOut->pMipInfo[0].macroBlockOffset = 0;\n                }\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->pitch          = pitch;\n            pOut->height         = actualHeight;\n            pOut->numSlices      = pIn->numSlices;\n            pOut->sliceSize      = sliceSize;\n            pOut->surfSize       = sliceSize * pOut->numSlices;\n            pOut->baseAlign      = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? elementBytes : 256;\n            pOut->blockWidth     = pitchAlign;\n            pOut->blockHeight    = 1;\n            pOut->blockSlices    = 1;\n\n            // Following members are useless on GFX10\n            pOut->mipChainPitch  = 0;\n            pOut->mipChainHeight = 0;\n            pOut->mipChainSlice  = 0;\n            pOut->epitchIsHeight = FALSE;\n\n            // Post calculation validate\n            ADDR_ASSERT(pOut->sliceSize > 0);\n        }\n    }\n\n    return returnCode;\n}\n\n} // V2\n} // Addr\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx10/gfx10addrlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx10addrlib.h\n* @brief Contains the Gfx10Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX10_ADDR_LIB_H__\n#define __GFX10_ADDR_LIB_H__\n\n#include \"addrlib2.h\"\n#include \"coord.h\"\n#include \"gfx10SwizzlePattern.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\n/**\n************************************************************************************************************************\n* @brief GFX10 specific settings structure.\n************************************************************************************************************************\n*/\nstruct Gfx10ChipSettings\n{\n    struct\n    {\n        UINT_32 reserved1           : 32;\n\n        // Misc configuration bits\n        UINT_32 isDcn20             : 1; // If using DCN2.0\n        UINT_32 supportRbPlus       : 1;\n        UINT_32 dsMipmapHtileFix    : 1;\n        UINT_32 dccUnsup3DSwDis     : 1;\n        UINT_32                     : 4;\n        UINT_32 reserved2           : 24;\n    };\n};\n\n/**\n************************************************************************************************************************\n* @brief GFX10 data surface type.\n************************************************************************************************************************\n*/\nenum Gfx10DataType\n{\n    Gfx10DataColor,\n    Gfx10DataDepthStencil,\n    Gfx10DataFmask\n};\n\nconst UINT_32 Gfx10LinearSwModeMask = (1u << ADDR_SW_LINEAR);\n\nconst UINT_32 Gfx10Blk256BSwModeMask = (1u << ADDR_SW_256B_S) |\n                                       (1u << ADDR_SW_256B_D);\n\nconst UINT_32 Gfx10Blk4KBSwModeMask = (1u << ADDR_SW_4KB_S)   |\n                                      (1u << ADDR_SW_4KB_D)   |\n                                      (1u << ADDR_SW_4KB_S_X) |\n                                      (1u << ADDR_SW_4KB_D_X);\n\nconst UINT_32 Gfx10Blk64KBSwModeMask = (1u << ADDR_SW_64KB_S)   |\n                                       (1u << ADDR_SW_64KB_D)   |\n                                       (1u << ADDR_SW_64KB_S_T) |\n                                       (1u << ADDR_SW_64KB_D_T) |\n                                       (1u << ADDR_SW_64KB_Z_X) |\n                                       (1u << ADDR_SW_64KB_S_X) |\n                                       (1u << ADDR_SW_64KB_D_X) |\n                                       (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx10BlkVarSwModeMask = (1u << ADDR_SW_VAR_Z_X) |\n                                      (1u << ADDR_SW_VAR_R_X);\n\nconst UINT_32 Gfx10ZSwModeMask = (1u << ADDR_SW_64KB_Z_X) |\n                                 (1u << ADDR_SW_VAR_Z_X);\n\nconst UINT_32 Gfx10StandardSwModeMask = (1u << ADDR_SW_256B_S)   |\n                                        (1u << ADDR_SW_4KB_S)    |\n                                        (1u << ADDR_SW_64KB_S)   |\n                                        (1u << ADDR_SW_64KB_S_T) |\n                                        (1u << ADDR_SW_4KB_S_X)  |\n                                        (1u << ADDR_SW_64KB_S_X);\n\nconst UINT_32 Gfx10DisplaySwModeMask = (1u << ADDR_SW_256B_D)   |\n                                       (1u << ADDR_SW_4KB_D)    |\n                                       (1u << ADDR_SW_64KB_D)   |\n                                       (1u << ADDR_SW_64KB_D_T) |\n                                       (1u << ADDR_SW_4KB_D_X)  |\n                                       (1u << ADDR_SW_64KB_D_X);\n\nconst UINT_32 Gfx10RenderSwModeMask = (1u << ADDR_SW_64KB_R_X) |\n                                      (1u << ADDR_SW_VAR_R_X);\n\nconst UINT_32 Gfx10XSwModeMask = (1u << ADDR_SW_4KB_S_X)  |\n                                 (1u << ADDR_SW_4KB_D_X)  |\n                                 (1u << ADDR_SW_64KB_Z_X) |\n                                 (1u << ADDR_SW_64KB_S_X) |\n                                 (1u << ADDR_SW_64KB_D_X) |\n                                 (1u << ADDR_SW_64KB_R_X) |\n                                 Gfx10BlkVarSwModeMask;\n\nconst UINT_32 Gfx10TSwModeMask = (1u << ADDR_SW_64KB_S_T) |\n                                 (1u << ADDR_SW_64KB_D_T);\n\nconst UINT_32 Gfx10XorSwModeMask = Gfx10XSwModeMask |\n                                   Gfx10TSwModeMask;\n\nconst UINT_32 Gfx10Rsrc1dSwModeMask = Gfx10LinearSwModeMask |\n                                      Gfx10RenderSwModeMask |\n                                      Gfx10ZSwModeMask;\n\nconst UINT_32 Gfx10Rsrc2dSwModeMask = Gfx10LinearSwModeMask  |\n                                      Gfx10Blk256BSwModeMask |\n                                      Gfx10Blk4KBSwModeMask  |\n                                      Gfx10Blk64KBSwModeMask |\n                                      Gfx10BlkVarSwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dSwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                      (1u << ADDR_SW_4KB_S)    |\n                                      (1u << ADDR_SW_64KB_S)   |\n                                      (1u << ADDR_SW_64KB_S_T) |\n                                      (1u << ADDR_SW_4KB_S_X)  |\n                                      (1u << ADDR_SW_64KB_Z_X) |\n                                      (1u << ADDR_SW_64KB_S_X) |\n                                      (1u << ADDR_SW_64KB_D_X) |\n                                      (1u << ADDR_SW_64KB_R_X) |\n                                      Gfx10BlkVarSwModeMask;\n\nconst UINT_32 Gfx10Rsrc2dPrtSwModeMask = (Gfx10Blk4KBSwModeMask | Gfx10Blk64KBSwModeMask) & ~Gfx10XSwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dPrtSwModeMask = Gfx10Rsrc2dPrtSwModeMask & ~Gfx10DisplaySwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dThin64KBSwModeMask = (1u << ADDR_SW_64KB_Z_X) |\n                                              (1u << ADDR_SW_64KB_R_X);\n\n\nconst UINT_32 Gfx10Rsrc3dThinSwModeMask = Gfx10Rsrc3dThin64KBSwModeMask |\n                                          Gfx10BlkVarSwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dViewAs2dSwModeMask = Gfx10Rsrc3dThinSwModeMask | Gfx10LinearSwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dThickSwModeMask = Gfx10Rsrc3dSwModeMask & ~(Gfx10Rsrc3dThinSwModeMask | Gfx10LinearSwModeMask);\n\nconst UINT_32 Gfx10Rsrc3dThick4KBSwModeMask = Gfx10Rsrc3dThickSwModeMask & Gfx10Blk4KBSwModeMask;\n\nconst UINT_32 Gfx10Rsrc3dThick64KBSwModeMask = Gfx10Rsrc3dThickSwModeMask & Gfx10Blk64KBSwModeMask;\n\nconst UINT_32 Gfx10MsaaSwModeMask = (Gfx10ZSwModeMask       |\n                                     Gfx10RenderSwModeMask)\n                                    ;\n\nconst UINT_32 Dcn20NonBpp64SwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                        (1u << ADDR_SW_4KB_S)    |\n                                        (1u << ADDR_SW_64KB_S)   |\n                                        (1u << ADDR_SW_64KB_S_T) |\n                                        (1u << ADDR_SW_4KB_S_X)  |\n                                        (1u << ADDR_SW_64KB_S_X) |\n                                        (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Dcn20Bpp64SwModeMask = (1u << ADDR_SW_4KB_D)    |\n                                     (1u << ADDR_SW_64KB_D)   |\n                                     (1u << ADDR_SW_64KB_D_T) |\n                                     (1u << ADDR_SW_4KB_D_X)  |\n                                     (1u << ADDR_SW_64KB_D_X) |\n                                     Dcn20NonBpp64SwModeMask;\n\nconst UINT_32 Dcn21NonBpp64SwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                        (1u << ADDR_SW_64KB_S)   |\n                                        (1u << ADDR_SW_64KB_S_T) |\n                                        (1u << ADDR_SW_64KB_S_X) |\n                                        (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Dcn21Bpp64SwModeMask = (1u << ADDR_SW_64KB_D)   |\n                                     (1u << ADDR_SW_64KB_D_T) |\n                                     (1u << ADDR_SW_64KB_D_X) |\n                                     Dcn21NonBpp64SwModeMask;\n\n/**\n************************************************************************************************************************\n* @brief This class is the GFX10 specific address library\n*        function set.\n************************************************************************************************************************\n*/\nclass Gfx10Lib : public Lib\n{\npublic:\n    /// Creates Gfx10Lib object\n    static Addr::Lib* CreateObj(const Client* pClient)\n    {\n        VOID* pMem = Object::ClientAlloc(sizeof(Gfx10Lib), pClient);\n        return (pMem != NULL) ? new (pMem) Gfx10Lib(pClient) : NULL;\n    }\n\nprotected:\n    Gfx10Lib(const Client* pClient);\n    virtual ~Gfx10Lib();\n\n    virtual BOOL_32 HwlIsStandardSwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isStd;\n    }\n\n    virtual BOOL_32 HwlIsDisplaySwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isDisp;\n    }\n\n    virtual BOOL_32 HwlIsThin(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return ((IsTex1d(resourceType)  == TRUE) ||\n                (IsTex2d(resourceType)  == TRUE) ||\n                ((IsTex3d(resourceType) == TRUE)                  &&\n                 (m_swizzleModeTable[swizzleMode].isStd  == FALSE) &&\n                 (m_swizzleModeTable[swizzleMode].isDisp == FALSE)));\n    }\n\n    virtual BOOL_32 HwlIsThick(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return ((IsTex3d(resourceType) == TRUE) &&\n                (m_swizzleModeTable[swizzleMode].isStd || m_swizzleModeTable[swizzleMode].isDisp));\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileInfo(\n        const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskInfo(\n        const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeDccInfo(\n        const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(\n        const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(\n        const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileCoordFromAddr(\n        const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlSupportComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn);\n\n    virtual VOID HwlComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual UINT_32 HwlGetEquationIndex(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const\n    {\n        *ppEquationTable = m_equationTable;\n\n        return m_numEquations;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView(\n        const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoLinear(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlComputeMaxBaseAlignments() const;\n\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const;\n\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn);\n\n    virtual ChipFamily HwlConvertChipFamily(UINT_32 uChipFamily, UINT_32 uChipRevision);\n\nprivate:\n    // Initialize equation table\n    VOID InitEquationTable();\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoMacroTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoMicroTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordMacroTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordMicroTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    UINT_32 ComputeOffsetFromSwizzlePattern(\n        const UINT_64* pPattern,\n        UINT_32        numBits,\n        UINT_32        x,\n        UINT_32        y,\n        UINT_32        z,\n        UINT_32        s) const;\n\n    UINT_32 ComputeOffsetFromEquation(\n        const ADDR_EQUATION* pEq,\n        UINT_32              x,\n        UINT_32              y,\n        UINT_32              z) const;\n\n    ADDR_E_RETURNCODE ComputeStereoInfo(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        UINT_32*                                pAlignY,\n        UINT_32*                                pRightXor) const;\n\n    static void GetMipSize(\n        UINT_32  mip0Width,\n        UINT_32  mip0Height,\n        UINT_32  mip0Depth,\n        UINT_32  mipId,\n        UINT_32* pMipWidth,\n        UINT_32* pMipHeight,\n        UINT_32* pMipDepth = NULL)\n    {\n        *pMipWidth  = ShiftCeil(Max(mip0Width, 1u),  mipId);\n        *pMipHeight = ShiftCeil(Max(mip0Height, 1u), mipId);\n\n        if (pMipDepth != NULL)\n        {\n            *pMipDepth = ShiftCeil(Max(mip0Depth, 1u),  mipId);\n        }\n    }\n\n    const ADDR_SW_PATINFO* GetSwizzlePatternInfo(\n        AddrSwizzleMode  swizzleMode,\n        AddrResourceType resourceType,\n        UINT_32          log2Elem,\n        UINT_32          numFrag) const;\n\n    /**\n     * Will use the indices, \"nibbles\", to build an index equation inside pSwizzle\n     *\n     * @param pPatInfo Pointer to a patInfo. Contains indices mapping to the 2D nibble arrays which will be used to build an index equation.\n     * @param pSwizzle Array to write the index equation to.\n     */\n    VOID GetSwizzlePatternFromPatternInfo(\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_BIT_SETTING       (&pSwizzle)[20]) const\n    {\n        memcpy(pSwizzle,\n               GFX10_SW_PATTERN_NIBBLE01[pPatInfo->nibble01Idx],\n               sizeof(GFX10_SW_PATTERN_NIBBLE01[pPatInfo->nibble01Idx]));\n\n        memcpy(&pSwizzle[8],\n               GFX10_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx],\n               sizeof(GFX10_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx]));\n\n        memcpy(&pSwizzle[12],\n               GFX10_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx],\n               sizeof(GFX10_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx]));\n\n        memcpy(&pSwizzle[16],\n               GFX10_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx],\n               sizeof(GFX10_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx]));\n    }\n\n    VOID ConvertSwizzlePatternToEquation(\n        UINT_32                elemLog2,\n        AddrResourceType       rsrcType,\n        AddrSwizzleMode        swMode,\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_EQUATION*         pEquation) const;\n\n    static INT_32 GetMetaElementSizeLog2(Gfx10DataType dataType);\n\n    static INT_32 GetMetaCacheSizeLog2(Gfx10DataType dataType);\n\n    void GetBlk256SizeLog2(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        Dim3d*           pBlock) const;\n\n    void GetCompressedBlockSizeLog2(\n        Gfx10DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        Dim3d*           pBlock) const;\n\n    INT_32 GetMetaOverlapLog2(\n        Gfx10DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2) const;\n\n    INT_32 Get3DMetaOverlapLog2(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2) const;\n\n    UINT_32 GetMetaBlkSize(\n        Gfx10DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        BOOL_32          pipeAlign,\n        Dim3d*           pBlock) const;\n\n    INT_32 GetPipeRotateAmount(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    INT_32 GetEffectiveNumPipes() const\n    {\n        return ((m_settings.supportRbPlus == FALSE) ||\n                ((m_numSaLog2 + 1) >= m_pipesLog2)) ? m_pipesLog2 : m_numSaLog2 + 1;\n    }\n\n    BOOL_32 IsRbAligned(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        const BOOL_32 isRtopt   = IsRtOptSwizzle(swizzleMode);\n        const BOOL_32 isZ       = IsZOrderSwizzle(swizzleMode);\n        const BOOL_32 isDisplay = IsDisplaySwizzle(swizzleMode);\n\n        return (IsTex2d(resourceType) && (isRtopt || isZ)) ||\n               (IsTex3d(resourceType) && isDisplay);\n\n    }\n\n    UINT_32 GetValidDisplaySwizzleModes(UINT_32 bpp) const;\n\n    BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    UINT_32 GetMaxNumMipsInTail(UINT_32 blockSizeLog2, BOOL_32 isThin) const;\n\n    static ADDR2_BLOCK_SET GetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet, AddrResourceType rsrcType)\n    {\n        ADDR2_BLOCK_SET allowedBlockSet = {};\n\n        allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx10Blk256BSwModeMask) ? TRUE : FALSE;\n        allowedBlockSet.linear = (allowedSwModeSet.value & Gfx10LinearSwModeMask)  ? TRUE : FALSE;\n        allowedBlockSet.var    = (allowedSwModeSet.value & Gfx10BlkVarSwModeMask)  ? TRUE : FALSE;\n\n        if (rsrcType == ADDR_RSRC_TEX_3D)\n        {\n            allowedBlockSet.macroThick4KB  = (allowedSwModeSet.value & Gfx10Rsrc3dThick4KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThin64KB  = (allowedSwModeSet.value & Gfx10Rsrc3dThin64KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThick64KB = (allowedSwModeSet.value & Gfx10Rsrc3dThick64KBSwModeMask) ? TRUE : FALSE;\n        }\n        else\n        {\n            allowedBlockSet.macroThin4KB  = (allowedSwModeSet.value & Gfx10Blk4KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThin64KB = (allowedSwModeSet.value & Gfx10Blk64KBSwModeMask) ? TRUE : FALSE;\n        }\n\n        return allowedBlockSet;\n    }\n\n    static ADDR2_SWTYPE_SET GetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet)\n    {\n        ADDR2_SWTYPE_SET allowedSwSet = {};\n\n        allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx10ZSwModeMask)        ? TRUE : FALSE;\n        allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx10StandardSwModeMask) ? TRUE : FALSE;\n        allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx10DisplaySwModeMask)  ? TRUE : FALSE;\n        allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx10RenderSwModeMask)   ? TRUE : FALSE;\n\n        return allowedSwSet;\n    }\n\n    BOOL_32 IsInMipTail(\n        Dim3d   mipTailDim,\n        UINT_32 maxNumMipsInTail,\n        UINT_32 mipWidth,\n        UINT_32 mipHeight,\n        UINT_32 numMipsToTheEnd) const\n    {\n        BOOL_32 inTail = ((mipWidth <= mipTailDim.w) &&\n                          (mipHeight <= mipTailDim.h) &&\n                          (numMipsToTheEnd <= maxNumMipsInTail));\n\n        return inTail;\n    }\n\n    UINT_32 GetBankXorBits(UINT_32 blockBits) const\n    {\n        return (blockBits > m_pipeInterleaveLog2 + m_pipesLog2 + ColumnBits) ?\n               Min(blockBits - m_pipeInterleaveLog2 - m_pipesLog2 - ColumnBits, BankBits) : 0;\n    }\n\n    BOOL_32 ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n    BOOL_32 ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    static const UINT_32 ColumnBits       = 2;\n    static const UINT_32 BankBits         = 4;\n    static const UINT_32 UnalignedDccType = 3;\n\n    static const Dim3d Block256_3d[MaxNumOfBpp];\n    static const Dim3d Block64K_Log2_3d[MaxNumOfBpp];\n    static const Dim3d Block4K_Log2_3d[MaxNumOfBpp];\n\n    static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE];\n\n    // Number of packers log2\n    UINT_32 m_numPkrLog2;\n    // Number of shader array log2\n    UINT_32 m_numSaLog2;\n\n    Gfx10ChipSettings m_settings;\n\n    UINT_32 m_colorBaseIndex;\n    UINT_32 m_xmaskBaseIndex;\n    UINT_32 m_htileBaseIndex;\n    UINT_32 m_dccBaseIndex;\n};\n\n} // V2\n} // Addr\n} // namespace rocr\n\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx11/gfx11SwizzlePattern.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx11SwizzlePattern.h\n* @brief swizzle pattern for gfx11.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX11_SWIZZLE_PATTERN_H__\n#define __GFX11_SWIZZLE_PATTERN_H__\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\nconst ADDR_SW_PATINFO GFX11_SW_256_D_PATINFO[] =\n{\n    {   1,    0,    0,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256_D\n    {   1,    0,    0,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256_D\n    {   1,    1,    0,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256_D\n    {   1,    2,    0,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256_D\n    {   1,    3,    0,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256_D\n    {   1,    4,    0,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256_D\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_4K_D_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_D\n    {   1,    0,    1,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_D\n    {   1,    1,    2,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_D\n    {   1,    2,    3,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_D\n    {   1,    3,    4,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_D\n    {   1,    4,    5,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_D\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_4K_D_X_PATINFO[] =\n{\n    {   1,    0,    1,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_D_X\n    {   1,    1,    2,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_D_X\n    {   1,    2,    3,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_D_X\n    {   1,    3,    4,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_D_X\n    {   1,    4,    5,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,    6,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,    7,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,    8,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,    9,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   10,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   11,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   12,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   13,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   14,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   15,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   16,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   17,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   18,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   19,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   20,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   21,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   22,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   23,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   24,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   25,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   26,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   27,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   28,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   29,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   30,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   31,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   32,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   33,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   34,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   35,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   36,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   37,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   38,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   39,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   40,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   41,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   42,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   43,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   44,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   45,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   46,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   47,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   48,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   49,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   50,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   51,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   52,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   53,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   54,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   55,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   56,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   57,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   58,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   59,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   60,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   61,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   62,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   63,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   64,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   65,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   51,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   52,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   53,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   54,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   55,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_D_X\n    {   3,    0,   56,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_D_X\n    {   3,    1,   57,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_D_X\n    {   3,    2,   58,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_D_X\n    {   3,    3,   59,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_D_X\n    {   3,    4,   60,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_D_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_D_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D\n    {   1,    0,    1,    1,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D\n    {   1,    1,    2,    2,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D\n    {   1,    2,    3,    3,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D\n    {   1,    3,    4,    4,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D\n    {   1,    4,    5,    5,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_D_X_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D_X\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D_X\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D_X\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D_X\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,    6,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,    7,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,    8,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,    9,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   10,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   11,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   12,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   13,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   14,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   15,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   16,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   17,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   18,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   19,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   20,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   21,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   22,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   23,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   24,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   25,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   26,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   27,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   28,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   29,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   30,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   31,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   32,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   33,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   34,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   35,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   36,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   37,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   38,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   39,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   40,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   41,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   42,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   43,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   44,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   45,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   66,    6,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   67,    7,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   68,    8,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   69,    9,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   70,   10,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   51,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   52,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   53,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   54,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   55,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   71,    6,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   72,    7,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   73,    8,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   74,    9,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   75,   10,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   76,   11,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   77,   12,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   78,   13,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   79,   14,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   80,   15,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   81,    6,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   82,    7,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   83,    8,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   84,    9,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   85,   10,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D_X\n    {   3,    0,   86,   11,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D_X\n    {   3,    1,   87,   12,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D_X\n    {   3,    2,   88,   13,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D_X\n    {   3,    3,   89,   14,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D_X\n    {   3,    4,   90,   15,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_D_T_PATINFO[] =\n{\n    {   1,    0,    1,    1,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D_T\n    {   1,    1,    2,    2,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D_T\n    {   1,    2,    3,    3,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D_T\n    {   1,    3,    4,    4,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D_T\n    {   1,    4,    5,    5,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,   91,    1,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,   92,    2,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,   93,    3,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,   94,    4,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,   95,    5,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,   96,    1,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,   97,    2,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,   98,    3,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,   99,    4,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  100,    5,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  101,    1,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  102,    2,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  103,    3,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  104,    4,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  105,    5,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,   96,    1,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,   97,    2,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,   98,    3,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,   99,    4,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  100,    5,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  101,    1,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  102,    2,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  103,    3,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  104,    4,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  105,    5,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  106,    1,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  107,    2,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  108,    3,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  109,    4,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  110,    5,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  101,    1,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  102,    2,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  103,    3,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  104,    4,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  105,    5,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  106,    1,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  107,    2,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  108,    3,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  109,    4,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  110,    5,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  111,   16,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  112,   17,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  113,   18,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  114,   19,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  115,   20,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  106,    1,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  107,    2,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  108,    3,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  109,    4,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  110,    5,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  111,   16,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  112,   17,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  113,   18,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  114,   19,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  115,   20,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,    1,   21,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,    2,   22,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,    3,   23,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,    4,   24,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,    5,   25,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,  111,   16,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,  112,   17,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,  113,   18,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,  114,   19,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,  115,   20,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D_T\n    {   2,    0,    1,   21,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D_T\n    {   2,    1,    2,   22,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D_T\n    {   2,    2,    3,   23,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D_T\n    {   2,    3,    4,   24,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D_T\n    {   2,    4,    5,   25,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D_T\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_D_X_PATINFO[] =\n{\n    {   1,    0,    1,    1,    1, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_D_X\n    {   1,    1,    2,    2,    2, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_D_X\n    {   1,    2,    3,    3,    3, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_D_X\n    {   1,    3,    4,    4,    4, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_D_X\n    {   1,    4,    5,    5,    5, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,    6,    1,    1, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,    7,    2,    2, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,    8,    3,    3, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,    9,    4,    4, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   10,    5,    5, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   11,    1,    1, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   12,    2,    2, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   13,    3,    3, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   14,    4,    4, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   15,    5,    5, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   16,    1,    1, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   17,    2,    2, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   18,    3,    3, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   19,    4,    4, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   20,    5,    5, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   21,    1,    1, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   22,    2,    2, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   23,    3,    3, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   24,    4,    4, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   25,    5,    5, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   26,    1,    1, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   27,    2,    2, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   28,    3,    3, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   29,    4,    4, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   30,    5,    5, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   31,    1,    1, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   32,    2,    2, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   33,    3,    3, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   34,    4,    4, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   35,    5,    5, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   36,    1,    1, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   37,    2,    2, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   38,    3,    3, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   39,    4,    4, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   40,    5,    5, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   41,    1,    1, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   42,    2,    2, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   43,    3,    3, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   44,    4,    4, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   45,    5,    5, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   66,    6,    1, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   67,    7,    2, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   68,    8,    3, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   69,    9,    4, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   70,   10,    5, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   51,    1,    1, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   52,    2,    2, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   53,    3,    3, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   54,    4,    4, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   55,    5,    5, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   71,    6,    1, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   72,    7,    2, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   73,    8,    3, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   74,    9,    4, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   75,   10,    5, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   76,   11,    1, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   77,   12,    2, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   78,   13,    3, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   79,   14,    4, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   80,   15,    5, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   81,    6,    1, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   82,    7,    2, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   83,    8,    3, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   84,    9,    4, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   85,   10,    5, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_D_X\n    {   3,    0,   86,   11,    1, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_D_X\n    {   3,    1,   87,   12,    2, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_D_X\n    {   3,    2,   88,   13,    3, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_D_X\n    {   3,    3,   89,   14,    4, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_D_X\n    {   3,    4,   90,   15,    5, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_D_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_ZR_X_1xaa_PATINFO[] =\n{\n    {   2,    0,  116,   26,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   2,    1,  117,   22,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   2,    2,  118,   27,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   2,    3,  119,   28,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   2,    4,  120,   29,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  121,   30,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  122,   31,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  123,   32,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  124,   33,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  125,   34,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  126,   35,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  127,   36,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  128,   37,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  129,   38,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  130,   39,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  131,   40,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  132,   41,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  133,   42,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  134,   43,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  135,   44,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  136,   45,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  137,   46,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  138,   47,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  139,   48,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  140,   49,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  141,   40,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  142,   50,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  143,   51,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  144,   52,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  145,   53,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  146,   54,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  146,   55,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  146,   56,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  146,   57,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  146,   58,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  147,   59,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  148,   60,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  149,   61,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  150,   62,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  151,   63,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  152,   54,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  152,   64,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  152,   56,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  153,   57,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  153,   65,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  152,   66,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  152,   67,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  152,   68,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  153,   69,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  153,   70,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  154,   71,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  154,   72,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  154,   73,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  155,   74,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  156,   75,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  154,   76,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  154,   77,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  154,   78,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  155,   79,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  156,   80,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  154,   81,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  154,   82,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  154,   83,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  155,   84,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  156,   85,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  157,   86,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  157,   87,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  157,   88,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  158,   89,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  159,   90,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    0,  157,   91,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    1,  157,   92,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    2,  157,   93,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    3,  158,   94,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 1xaa\n    {   3,    4,  159,   95,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 1xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_ZR_X_2xaa_PATINFO[] =\n{\n    {   2,    5,  160,   96,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   2,    6,  118,   27,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   2,    7,  161,   97,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   2,    8,  119,   98,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   2,    9,  162,   99,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  163,  100,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  123,   32,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  123,  101,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  164,  102,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  125,  103,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  127,  104,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  128,   37,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  128,  105,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  165,  106,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  130,  107,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  132,  108,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  133,   51,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  133,  109,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  135,  110,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  135,  111,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  137,  112,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  138,   47,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  138,  113,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  139,  114,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  140,  115,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  142,  108,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  143,   51,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  143,  109,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  144,  116,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  145,  111,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  146,  117,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  146,  118,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  146,  119,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  166,  120,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  167,  121,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  148,  122,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  149,   61,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  149,  123,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  151,  124,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  168,  125,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  152,   55,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  152,   56,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  152,  126,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  153,  127,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  169,  127,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  152,   77,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  152,   78,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  152,  128,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  153,   80,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  169,   80,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  154,   72,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  154,   73,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  154,  129,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  156,  130,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  170,  130,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  154,   77,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  154,   78,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  154,  128,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  156,  131,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  170,  131,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  154,  132,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  154,   83,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  154,  133,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  156,  134,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  170,  134,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  157,  135,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  157,   88,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  157,  136,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  159,   90,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  171,   90,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    5,  157,  137,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    6,  157,   93,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    7,  157,  138,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    8,  159,   95,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 2xaa\n    {   3,    9,  171,   95,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 2xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_ZR_X_4xaa_PATINFO[] =\n{\n    {   2,   10,  118,   27,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   2,   11,  118,  139,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   2,   12,  118,  140,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   2,   13,  119,  141,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   2,   14,  120,  142,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  123,   32,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  172,  143,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  123,  144,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  124,  145,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  125,  146,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  128,   37,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  128,  147,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  128,  148,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  129,  149,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  130,  150,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  133,   42,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  133,  151,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  133,  152,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  134,  153,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  173,  154,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  138,   47,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  138,  155,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  138,  156,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  174,  157,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  175,  158,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  143,   51,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  143,  159,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  143,  160,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  145,  161,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  176,  162,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  146,   56,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  146,  163,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  146,  164,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  167,  165,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  177,  166,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  149,   61,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  149,  167,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  149,  168,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  178,  169,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  179,  170,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  152,   56,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  152,  163,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  152,  171,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  180,  171,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  181,  171,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  152,   68,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  152,  172,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  152,  173,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  180,  173,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  181,  173,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  154,   73,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  154,  174,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  154,  130,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  182,  130,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  183,  130,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  154,   78,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  154,  172,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  154,  131,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  182,  131,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  183,  131,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  154,   83,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  154,  133,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  154,  134,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  182,  134,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  183,  134,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  157,   88,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  157,  175,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  157,   90,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  184,   90,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  185,   90,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   10,  157,   93,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   11,  157,  176,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   12,  157,   95,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   13,  184,   95,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 4xaa\n    {   3,   14,  185,   95,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 4xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_ZR_X_8xaa_PATINFO[] =\n{\n    {   2,   15,  161,   97,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   2,   16,  118,  140,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  186,  177,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  187,  178,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  162,  179,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  123,  101,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  123,  144,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  188,  180,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  189,  181,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  190,  182,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  128,  105,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  128,  148,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  128,  183,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  165,  184,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  191,  185,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  133,  109,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  133,  186,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  133,  187,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  192,  188,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  193,  189,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  138,  113,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  138,  156,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  138,  190,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  194,  191,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  195,  192,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  143,  109,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  143,  160,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  143,  187,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  196,  193,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  197,  194,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  146,  126,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  146,  164,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  198,  195,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  199,  196,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  200,  197,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  149,  123,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  149,  168,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  149,  198,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  179,  170,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  201,  170,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  152,  126,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  152,  171,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  202,  199,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  181,  171,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  203,  171,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  152,  128,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  152,  173,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  202,  200,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  181,  173,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  203,  201,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  154,  129,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  154,  130,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  204,  202,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  183,  130,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  205,  130,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  154,  128,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  154,  131,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  206,  203,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  183,  131,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  205,  131,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  154,  133,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  154,  134,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  206,  204,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  183,  134,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  205,  134,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  157,  136,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  157,   90,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  207,  205,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  185,   90,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  208,   90,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   15,  157,  138,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   16,  157,   95,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   17,  171,   95,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   18,  185,   95,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_{Z,R}_X 8xaa\n    {   3,   19,  208,   95,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_{Z,R}_X 8xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_ZR_X_1xaa_PATINFO[] =\n{\n    {   2,    0,  116,   26,    6, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   2,    1,  117,   22,    2, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   2,    2,  118,   27,    7, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   2,    3,  119,   28,    4, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   2,    4,  120,   29,    8, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  121,   30,    6, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  122,   31,    9, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  123,   32,    7, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  124,   33,   10, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  125,   34,    8, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  126,   35,    6, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  127,   36,    9, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  128,   37,    7, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  129,   38,   10, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  130,   39,    8, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  131,  206,   11, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  132,  207,   12, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  133,  208,   13, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  134,  209,   14, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  135,  210,   15, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  136,  211,   16, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  137,   35,   17, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  138,  212,   18, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  139,  213,   19, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  140,  214,   20, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  141,  206,   11, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  142,  215,   21, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  143,  216,   13, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  144,  217,   22, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  145,  218,   15, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  146,  219,   23, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  146,  220,   24, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  146,  221,   25, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  146,  222,   26, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  146,  223,   27, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  147,  224,   28, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  148,  225,   29, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  149,  226,   30, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  150,  227,   31, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  151,  228,   32, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  152,  219,   23, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  152,  229,   33, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  152,  221,   25, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  153,  222,   34, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  153,  230,   27, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  152,  231,   23, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  152,  232,   33, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  152,  233,   25, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  153,  234,   34, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  153,  235,   35, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  154,  236,   36, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  154,  237,   37, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  154,  238,   38, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  155,  239,   39, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  155,  240,   40, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  154,  241,   23, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  154,  242,   24, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  154,  243,   25, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  155,  244,   41, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  155,  245,   42, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  154,   81,   23, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  154,   82,   24, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  154,   83,   25, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  155,  246,   43, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  155,  247,   44, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  157,  248,   45, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  157,  249,   46, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  157,  250,   47, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  209,  251,   48, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  209,  252,   49, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    0,  157,   91,   23, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    1,  157,   92,   33, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    2,  157,   93,   25, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    3,  209,  253,   43, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 1xaa\n    {   3,    4,  209,  254,   50, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 1xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_ZR_X_2xaa_PATINFO[] =\n{\n    {   2,    5,  160,   96,   51, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   2,    6,  118,   27,    7, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   2,    7,  210,  255,   52, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   2,    8,  120,   29,    8, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   2,    9,  211,  256,   53, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  163,  100,   51, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  123,   32,    7, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  212,  257,   52, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  125,   34,    8, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  213,  258,   53, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  127,  104,   51, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  128,   37,    7, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  129,  259,   52, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  130,   39,    8, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  214,  260,   53, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  132,  261,   54, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  133,  216,   13, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  134,  262,   55, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  135,  263,   15, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  215,  264,   56, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  137,  265,   16, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  138,  212,   18, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  139,  266,   18, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  140,  214,   20, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  216,  267,   20, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  142,  261,   54, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  143,  216,   13, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  144,  262,   55, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  145,  218,   15, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  217,  268,   56, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  146,  269,   57, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  146,  270,   25, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  146,  271,   41, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  146,  272,   58, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  146,  273,   59, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  148,  274,   60, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  149,  226,   30, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  218,  275,   61, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  151,  228,   32, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  219,  276,   62, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  152,  277,   57, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  152,  221,   25, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  152,  278,   41, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  153,  230,   27, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  153,  279,   63, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  152,  280,   57, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  152,  243,   25, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  152,  281,   41, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  153,  282,   64, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  153,  283,   65, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  154,  284,   37, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  154,  238,   38, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  154,  239,   66, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  155,  240,   40, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  155,  273,   67, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  154,  280,   57, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  154,  243,   25, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  154,  281,   41, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  155,  245,   42, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  155,  285,   68, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  154,   82,   24, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  154,   83,   25, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  154,  286,   43, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  155,  247,   44, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  155,  287,   69, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  157,  288,   70, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  157,  250,   47, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  157,  289,   71, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  158,  290,   72, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  158,  291,   73, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    5,  157,   92,   24, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    6,  157,   93,   25, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    7,  157,  292,   43, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    8,  158,  293,   50, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 2xaa\n    {   3,    9,  158,  294,   74, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 2xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_ZR_X_4xaa_PATINFO[] =\n{\n    {   2,   10,  118,   27,    7, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   2,   11,  119,   28,    4, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   2,   12,  120,   29,    8, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   2,   13,  220,  295,   75, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   2,   14,  221,  296,   76, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  123,   32,    7, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  124,   33,   10, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  125,   34,    8, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  222,  297,   77, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  223,  298,   76, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  128,   37,    7, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  129,   38,   10, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  130,   39,    8, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  224,  299,   77, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  225,  300,   76, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  133,  208,   13, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  134,  209,   14, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  135,  210,   15, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  215,  301,   78, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  226,  302,   79, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  138,  212,   18, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  139,  213,   19, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  140,  214,   20, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  216,  299,   80, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  227,  303,   81, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  143,  216,   13, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  144,  217,   22, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  145,  218,   15, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  217,  304,   82, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  228,  305,   83, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  146,  221,   25, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  146,  222,   26, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  146,  223,   27, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  146,  306,   84, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  146,  307,   85, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  149,  226,   30, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  218,  227,   86, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  168,  228,   87, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  219,  301,   62, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  229,  308,   88, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  152,  221,   25, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  152,  222,   34, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  152,  230,   27, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  153,  306,   84, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  153,  309,   89, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  152,  233,   25, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  152,  234,   34, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  152,  235,   35, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  153,  310,   90, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  153,  311,   91, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  154,  238,   38, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  154,  239,   66, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  154,  240,   92, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  156,  312,   93, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  156,  313,   94, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  154,  243,   25, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  154,  281,   41, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  154,  314,   42, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  156,  315,   95, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  156,  316,   96, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  154,   83,   25, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  154,  286,   43, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  154,  317,   44, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  156,  318,   97, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  156,  319,   68, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  157,  250,   47, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  157,  289,   71, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  157,  320,   98, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  159,  321,   99, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  159,  322,  100, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   10,  157,   93,   25, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   11,  157,  292,   43, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   12,  157,  323,   50, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   13,  159,  324,   74, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 4xaa\n    {   3,   14,  159,  325,  101, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 4xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_ZR_X_8xaa_PATINFO[] =\n{\n    {   2,   15,  210,  255,   52, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   2,   16,  120,   29,    8, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   2,   17,  211,  256,   53, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   2,   18,  221,  296,   76, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   2,   19,  230,  326,  102, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  212,  257,   52, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  125,   34,    8, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  213,  258,   53, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  223,  298,   76, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  231,  327,  103, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  129,  259,   52, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  130,   39,    8, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  214,  260,   53, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  225,  300,   76, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  232,  328,  103, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  134,  262,   55, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  135,  263,   15, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  215,  264,   56, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  226,  302,  104, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  233,  329,  105, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  139,  266,   18, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  140,  214,   20, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  216,  267,   20, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  227,  303,   81, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  234,  330,  106, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  144,  262,   55, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  145,  218,   15, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  217,  268,   56, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  228,  305,   83, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  235,  331,  107, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  146,  271,   41, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  146,  272,   58, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  146,  273,   59, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  236,  332,  108, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  237,  333,  109, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  218,  275,   61, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  168,  228,   87, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  238,  276,  110, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  239,  308,  111, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  239,  334,  112, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  152,  278,   41, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  152,  230,   27, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  152,  279,   63, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  240,  309,   89, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  241,  335,  113, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  152,  281,   41, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  152,  282,   64, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  152,  283,   65, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  240,  311,   91, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  241,  336,   89, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  154,  239,   66, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  154,  240,   92, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  154,  273,   63, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  242,  313,   94, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  243,  337,  114, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  154,  281,   41, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  154,  314,   42, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  154,  338,   68, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  242,  316,   96, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  243,  339,  115, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  154,  286,   43, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  154,  317,   44, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  154,  340,   68, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  242,  341,  116, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  243,  342,  115, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  157,  289,   71, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  157,  320,   98, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  157,  343,  117, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  244,  322,  100, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  245,  344,  118, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   15,  157,  292,   43, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   16,  157,  323,   50, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   17,  157,  345,  119, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   18,  244,  325,  101, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_{Z,R}_X 8xaa\n    {   3,   19,  245,  346,  120, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_{Z,R}_X 8xaa\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_4K_S3_PATINFO[] =\n{\n    {   1,   20,  246,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S3\n    {   1,   20,  246,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S3\n    {   1,   21,  247,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S3\n    {   1,   22,  248,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S3\n    {   1,   23,  249,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S3\n    {   1,   24,  250,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S3\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_4K_S3_X_PATINFO[] =\n{\n    {   1,   20,  246,    0,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_4K_S3_X\n    {   1,   21,  247,    0,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_4K_S3_X\n    {   1,   22,  248,    0,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_4K_S3_X\n    {   1,   23,  249,    0,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_4K_S3_X\n    {   1,   24,  250,    0,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  251,    0,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  252,    0,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  253,    0,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  254,    0,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  255,    0,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  256,    0,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  257,    0,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  258,    0,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  259,    0,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  260,    0,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  261,    0,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  262,    0,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  263,    0,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  264,    0,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  265,    0,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  256,    0,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  257,    0,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  258,    0,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  259,    0,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  260,    0,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  261,    0,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  262,    0,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  263,    0,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  264,    0,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  265,    0,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  261,    0,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  262,    0,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  263,    0,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  264,    0,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  265,    0,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_4K_S3_X\n    {   3,   20,  266,    0,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_4K_S3_X\n    {   3,   21,  267,    0,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_4K_S3_X\n    {   3,   22,  268,    0,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_4K_S3_X\n    {   3,   23,  269,    0,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_4K_S3_X\n    {   3,   24,  270,    0,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_4K_S3_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_S3_PATINFO[] =\n{\n    {   1,   20,  246,  347,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3\n    {   1,   20,  246,  347,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3\n    {   1,   21,  247,  348,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3\n    {   1,   22,  248,  349,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3\n    {   1,   23,  249,  350,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3\n    {   1,   24,  250,  351,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_S3_X_PATINFO[] =\n{\n    {   1,   20,  246,  347,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3_X\n    {   1,   21,  247,  348,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3_X\n    {   1,   22,  248,  349,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3_X\n    {   1,   23,  249,  350,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3_X\n    {   1,   24,  250,  351,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  251,  347,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  252,  348,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  253,  349,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  254,  350,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  255,  351,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  256,  347,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  257,  348,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  258,  349,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  259,  350,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  260,  351,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  261,  347,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  262,  348,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  263,  349,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  264,  350,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  265,  351,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  256,  347,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  257,  348,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  258,  349,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  259,  350,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  260,  351,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  261,  347,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  262,  348,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  263,  349,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  264,  350,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  265,  351,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  266,  347,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  267,  348,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  268,  349,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  269,  350,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  270,  351,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  261,  347,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  262,  348,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  263,  349,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  264,  350,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  265,  351,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  266,  347,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  267,  348,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  268,  349,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  269,  350,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  270,  351,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  271,  352,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  272,  353,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  273,  354,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  274,  355,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  275,  356,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  266,  347,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  267,  348,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  268,  349,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  269,  350,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  270,  351,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  271,  352,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  272,  353,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  273,  354,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  274,  355,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  275,  356,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  276,  357,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  277,  358,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  278,  359,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  279,  360,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  280,  361,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  271,  352,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  272,  353,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  273,  354,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  274,  355,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  275,  356,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3_X\n    {   3,   20,  276,  357,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3_X\n    {   3,   21,  277,  358,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3_X\n    {   3,   22,  278,  359,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3_X\n    {   3,   23,  279,  360,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3_X\n    {   3,   24,  280,  361,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_S3_T_PATINFO[] =\n{\n    {   1,   20,  246,  347,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_S3_T\n    {   1,   21,  247,  348,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_S3_T\n    {   1,   22,  248,  349,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_S3_T\n    {   1,   23,  249,  350,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_S3_T\n    {   1,   24,  250,  351,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  251,  347,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  252,  348,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  253,  349,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  254,  350,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  255,  351,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  256,  347,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  257,  348,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  258,  349,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  259,  350,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  260,  351,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  281,  347,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  282,  348,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  283,  349,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  284,  350,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  285,  351,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  256,  347,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  257,  348,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  258,  349,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  259,  350,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  260,  351,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  281,  347,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  282,  348,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  283,  349,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  284,  350,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  285,  351,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  286,  347,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  287,  348,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  288,  349,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  289,  350,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  290,  351,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  281,  347,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  282,  348,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  283,  349,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  284,  350,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  285,  351,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  286,  347,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  287,  348,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  288,  349,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  289,  350,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  290,  351,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  291,  352,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  292,  353,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  293,  354,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  294,  355,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  295,  356,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  286,  347,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  287,  348,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  288,  349,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  289,  350,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  290,  351,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  291,  352,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  292,  353,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  293,  354,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  294,  355,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  295,  356,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  246,  362,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  247,  363,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  248,  364,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  249,  365,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  250,  366,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  291,  352,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  292,  353,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  293,  354,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  294,  355,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  295,  356,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_S3_T\n    {   3,   20,  246,  362,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_S3_T\n    {   3,   21,  247,  363,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_S3_T\n    {   3,   22,  248,  364,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_S3_T\n    {   3,   23,  249,  365,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_S3_T\n    {   3,   24,  250,  366,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_S3_T\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_256K_S3_X_PATINFO[] =\n{\n    {   1,   20,  246,  347,  121, } , // 1 pipes (1 PKRs) 1 bpe @ SW_256K_S3_X\n    {   1,   21,  247,  348,  121, } , // 1 pipes (1 PKRs) 2 bpe @ SW_256K_S3_X\n    {   1,   22,  248,  349,  122, } , // 1 pipes (1 PKRs) 4 bpe @ SW_256K_S3_X\n    {   1,   23,  249,  350,  123, } , // 1 pipes (1 PKRs) 8 bpe @ SW_256K_S3_X\n    {   1,   24,  250,  351,  123, } , // 1 pipes (1 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  251,  347,  121, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  252,  348,  121, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  253,  349,  122, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  254,  350,  123, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  255,  351,  123, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  256,  347,  121, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  257,  348,  121, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  258,  349,  122, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  259,  350,  123, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  260,  351,  123, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  261,  347,  121, } , // 8 pipes (2 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  262,  348,  121, } , // 8 pipes (2 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  263,  349,  122, } , // 8 pipes (2 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  264,  350,  123, } , // 8 pipes (2 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  265,  351,  123, } , // 8 pipes (2 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  256,  347,  121, } , // 4 pipes (4 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  257,  348,  121, } , // 4 pipes (4 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  258,  349,  122, } , // 4 pipes (4 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  259,  350,  123, } , // 4 pipes (4 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  260,  351,  123, } , // 4 pipes (4 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  261,  347,  121, } , // 8 pipes (4 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  262,  348,  121, } , // 8 pipes (4 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  263,  349,  122, } , // 8 pipes (4 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  264,  350,  123, } , // 8 pipes (4 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  265,  351,  123, } , // 8 pipes (4 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  266,  347,  121, } , // 16 pipes (4 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  267,  348,  121, } , // 16 pipes (4 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  268,  349,  122, } , // 16 pipes (4 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  269,  350,  123, } , // 16 pipes (4 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  270,  351,  123, } , // 16 pipes (4 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  261,  347,  121, } , // 8 pipes (8 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  262,  348,  121, } , // 8 pipes (8 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  263,  349,  122, } , // 8 pipes (8 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  264,  350,  123, } , // 8 pipes (8 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  265,  351,  123, } , // 8 pipes (8 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  266,  347,  121, } , // 16 pipes (8 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  267,  348,  121, } , // 16 pipes (8 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  268,  349,  122, } , // 16 pipes (8 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  269,  350,  123, } , // 16 pipes (8 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  270,  351,  123, } , // 16 pipes (8 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  271,  352,  121, } , // 32 pipes (8 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  272,  353,  121, } , // 32 pipes (8 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  273,  354,  122, } , // 32 pipes (8 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  274,  355,  123, } , // 32 pipes (8 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  275,  356,  123, } , // 32 pipes (8 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  266,  347,  121, } , // 16 pipes (16 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  267,  348,  121, } , // 16 pipes (16 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  268,  349,  122, } , // 16 pipes (16 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  269,  350,  123, } , // 16 pipes (16 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  270,  351,  123, } , // 16 pipes (16 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  271,  352,  121, } , // 32 pipes (16 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  272,  353,  121, } , // 32 pipes (16 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  273,  354,  122, } , // 32 pipes (16 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  274,  355,  123, } , // 32 pipes (16 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  275,  356,  123, } , // 32 pipes (16 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  276,  357,  121, } , // 64 pipes (16 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  277,  358,  121, } , // 64 pipes (16 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  278,  359,  122, } , // 64 pipes (16 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  279,  360,  123, } , // 64 pipes (16 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  280,  361,  123, } , // 64 pipes (16 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  271,  352,  121, } , // 32 pipes (32 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  272,  353,  121, } , // 32 pipes (32 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  273,  354,  122, } , // 32 pipes (32 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  274,  355,  123, } , // 32 pipes (32 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  275,  356,  123, } , // 32 pipes (32 PKRs) 16 bpe @ SW_256K_S3_X\n    {   3,   20,  276,  357,  121, } , // 64 pipes (32 PKRs) 1 bpe @ SW_256K_S3_X\n    {   3,   21,  277,  358,  121, } , // 64 pipes (32 PKRs) 2 bpe @ SW_256K_S3_X\n    {   3,   22,  278,  359,  122, } , // 64 pipes (32 PKRs) 4 bpe @ SW_256K_S3_X\n    {   3,   23,  279,  360,  123, } , // 64 pipes (32 PKRs) 8 bpe @ SW_256K_S3_X\n    {   3,   24,  280,  361,  123, } , // 64 pipes (32 PKRs) 16 bpe @ SW_256K_S3_X\n};\n\nconst ADDR_SW_PATINFO GFX11_SW_64K_D3_X_PATINFO[] =\n{\n    {   1,   20,  246,  347,    0, } , // 1 pipes (1 PKRs) 1 bpe @ SW_64K_D3_X\n    {   1,   21,  247,  348,    0, } , // 1 pipes (1 PKRs) 2 bpe @ SW_64K_D3_X\n    {   1,   22,  248,  349,    0, } , // 1 pipes (1 PKRs) 4 bpe @ SW_64K_D3_X\n    {   1,   23,  249,  350,    0, } , // 1 pipes (1 PKRs) 8 bpe @ SW_64K_D3_X\n    {   1,   24,  250,  351,    0, } , // 1 pipes (1 PKRs) 16 bpe @ SW_64K_D3_X\n    {   2,   20,  296,  367,    0, } , // 2 pipes (1-2 PKRs) 1 bpe @ SW_64K_D3_X\n    {   2,   21,  296,  368,    0, } , // 2 pipes (1-2 PKRs) 2 bpe @ SW_64K_D3_X\n    {   2,   22,  297,  369,    0, } , // 2 pipes (1-2 PKRs) 4 bpe @ SW_64K_D3_X\n    {   2,   23,  298,  351,    0, } , // 2 pipes (1-2 PKRs) 8 bpe @ SW_64K_D3_X\n    {   3,   24,  299,  351,    0, } , // 2 pipes (1-2 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  300,  370,    0, } , // 4 pipes (1-2 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  300,  371,    0, } , // 4 pipes (1-2 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  301,  372,    0, } , // 4 pipes (1-2 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  302,  373,    0, } , // 4 pipes (1-2 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  303,  373,    0, } , // 4 pipes (1-2 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  304,  370,    0, } , // 8 pipes (2 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  304,  371,    0, } , // 8 pipes (2 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  305,  372,    0, } , // 8 pipes (2 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  306,  373,    0, } , // 8 pipes (2 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  307,  373,    0, } , // 8 pipes (2 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  308,  374,    0, } , // 4 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  309,  375,    0, } , // 4 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  310,  376,    0, } , // 4 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  311,  377,    0, } , // 4 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  312,  378,    0, } , // 4 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  313,  379,    0, } , // 8 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  314,  371,    0, } , // 8 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  315,  372,    0, } , // 8 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  316,  373,    0, } , // 8 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  317,  373,    0, } , // 8 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  318,  380,    0, } , // 16 pipes (4 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  319,  371,    0, } , // 16 pipes (4 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  320,  372,    0, } , // 16 pipes (4 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  321,  373,    0, } , // 16 pipes (4 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  322,  373,    0, } , // 16 pipes (4 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  323,  381,    0, } , // 8 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  323,  382,    0, } , // 8 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  323,  383,    0, } , // 8 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  324,  384,    0, } , // 8 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  325,  384,    0, } , // 8 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  326,  379,    0, } , // 16 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  327,  371,    0, } , // 16 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  328,  372,    0, } , // 16 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  329,  373,    0, } , // 16 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  330,  373,    0, } , // 16 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  326,  385,    0, } , // 32 pipes (8 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  331,  386,    0, } , // 32 pipes (8 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  331,  387,    0, } , // 32 pipes (8 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  332,  388,    0, } , // 32 pipes (8 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  333,  388,    0, } , // 32 pipes (8 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  334,  389,    0, } , // 16 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  335,  390,    0, } , // 16 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  336,  391,    0, } , // 16 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  337,  392,    0, } , // 16 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  338,  392,    0, } , // 16 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  334,  393,    0, } , // 32 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  335,  394,    0, } , // 32 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  336,  395,    0, } , // 32 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  337,  396,    0, } , // 32 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  338,  396,    0, } , // 32 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  334,  397,    0, } , // 64 pipes (16 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  339,  398,    0, } , // 64 pipes (16 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  339,  399,    0, } , // 64 pipes (16 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  340,  400,    0, } , // 64 pipes (16 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  341,  400,    0, } , // 64 pipes (16 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  342,  401,    0, } , // 32 pipes (32 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  343,  402,    0, } , // 32 pipes (32 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  344,  403,    0, } , // 32 pipes (32 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  345,  404,    0, } , // 32 pipes (32 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  346,  404,    0, } , // 32 pipes (32 PKRs) 16 bpe @ SW_64K_D3_X\n    {   3,   20,  342,  405,    0, } , // 64 pipes (32 PKRs) 1 bpe @ SW_64K_D3_X\n    {   3,   21,  343,  406,    0, } , // 64 pipes (32 PKRs) 2 bpe @ SW_64K_D3_X\n    {   3,   22,  344,  407,    0, } , // 64 pipes (32 PKRs) 4 bpe @ SW_64K_D3_X\n    {   4,   23,  345,  408,    0, } , // 64 pipes (32 PKRs) 8 bpe @ SW_64K_D3_X\n    {   4,   24,  346,  408,    0, } , // 64 pipes (32 PKRs) 16 bpe @ SW_64K_D3_X\n};\n\n\nconst UINT_64 GFX11_SW_PATTERN_NIBBLE01[][8] =\n{\n    {X0,            X1,            Y0,            X2,            Y1,            Y2,            X3,            Y3,            }, // 0\n    {0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 1\n    {0,             0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 2\n    {0,             0,             0,             X0,            Y0,            X1,            X2,            Y1,            }, // 3\n    {0,             0,             0,             0,             X0,            Y0,            X1,            Y1,            }, // 4\n    {S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 5\n    {0,             S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 6\n    {0,             0,             S0,            X0,            Y0,            X1,            Y1,            X2,            }, // 7\n    {0,             0,             0,             S0,            X0,            Y0,            X1,            Y1,            }, // 8\n    {0,             0,             0,             0,             S0,            X0,            Y0,            X1,            }, // 9\n    {S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 10\n    {0,             S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            }, // 11\n    {0,             0,             S0,            S1,            X0,            Y0,            X1,            Y1,            }, // 12\n    {0,             0,             0,             S0,            S1,            X0,            Y0,            X1,            }, // 13\n    {0,             0,             0,             0,             S0,            S1,            X0,            Y0,            }, // 14\n    {S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            X2,            }, // 15\n    {0,             S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            }, // 16\n    {0,             0,             S0,            S1,            S2,            X0,            Y0,            X1,            }, // 17\n    {0,             0,             0,             S0,            S1,            S2,            X0,            Y0,            }, // 18\n    {0,             0,             0,             0,             S0,            S1,            S2,            X0,            }, // 19\n    {X0,            X1,            Z0,            Y0,            Y1,            Z1,            X2,            Z2,            }, // 20\n    {0,             X0,            Z0,            Y0,            X1,            Z1,            Y1,            Z2,            }, // 21\n    {0,             0,             X0,            Y0,            X1,            Z0,            Y1,            Z1,            }, // 22\n    {0,             0,             0,             X0,            Y0,            Z0,            X1,            Z1,            }, // 23\n    {0,             0,             0,             0,             X0,            Z0,            Y0,            Z1,            }, // 24\n};\n\nconst UINT_64 GFX11_SW_PATTERN_NIBBLE2[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y4,            X4,            Y5,            X5,            }, // 1\n    {Y3,            X4,            Y4,            X5,            }, // 2\n    {Y3,            X3,            Y4,            X4,            }, // 3\n    {Y2,            X3,            Y3,            X4,            }, // 4\n    {Y2,            X2,            Y3,            X3,            }, // 5\n    {Z0^X4^Y4,      X4,            Y5,            X5,            }, // 6\n    {Z0^Y3^X4,      X4,            Y4,            X5,            }, // 7\n    {Z0^X3^Y3,      X3,            Y4,            X4,            }, // 8\n    {Z0^Y2^X3,      X3,            Y3,            X4,            }, // 9\n    {Z0^X2^Y2,      X2,            Y3,            X3,            }, // 10\n    {Y4^X5,         Z0^X4^Y5,      Y5,            X5,            }, // 11\n    {Y3^X5,         Z0^X4^Y4,      Y4,            X5,            }, // 12\n    {Y3^X4,         Z0^X3^Y4,      Y4,            X4,            }, // 13\n    {Y2^X4,         Z0^X3^Y3,      Y3,            X4,            }, // 14\n    {Y2^X3,         Z0^X2^Y3,      Y3,            X3,            }, // 15\n    {Y4^X6,         X4^Y6,         Z0^X5^Y5,      X5,            }, // 16\n    {Y3^X6,         X4^Y5,         Z0^Y4^X5,      X5,            }, // 17\n    {Y3^X5,         X3^Y5,         Z0^X4^Y4,      X4,            }, // 18\n    {Y2^X5,         X3^Y4,         Z0^Y3^X4,      X4,            }, // 19\n    {Y2^X4,         X2^Y4,         Z0^X3^Y3,      X3,            }, // 20\n    {Z1^Y4^X5,      Z0^X4^Y5,      Y5,            X5,            }, // 21\n    {Z1^Y3^X5,      Z0^X4^Y4,      Y4,            X5,            }, // 22\n    {Z1^Y3^X4,      Z0^X3^Y4,      Y4,            X4,            }, // 23\n    {Z1^Y2^X4,      Z0^X3^Y3,      Y3,            X4,            }, // 24\n    {Z1^Y2^X3,      Z0^X2^Y3,      Y3,            X3,            }, // 25\n    {Y4^X6,         Z1^X4^Y6,      Z0^X5^Y5,      X5,            }, // 26\n    {Y3^X6,         Z1^X4^Y5,      Z0^Y4^X5,      X5,            }, // 27\n    {Y3^X5,         Z1^X3^Y5,      Z0^X4^Y4,      X4,            }, // 28\n    {Y2^X5,         Z1^X3^Y4,      Z0^Y3^X4,      X4,            }, // 29\n    {Y2^X4,         Z1^X2^Y4,      Z0^X3^Y3,      X3,            }, // 30\n    {Y4^X7,         X4^Y7,         Z1^Y5^X6,      Z0^X5^Y6,      }, // 31\n    {Y3^X7,         X4^Y6,         Z1^Y4^X6,      Z0^X5^Y5,      }, // 32\n    {Y3^X6,         X3^Y6,         Z1^Y4^X5,      Z0^X4^Y5,      }, // 33\n    {Y2^X6,         X3^Y5,         Z1^Y3^X5,      Z0^X4^Y4,      }, // 34\n    {Y2^X5,         X2^Y5,         Z1^Y3^X4,      Z0^X3^Y4,      }, // 35\n    {Z2^Y4^X6,      Z1^X4^Y6,      Z0^X5^Y5,      X5,            }, // 36\n    {Z2^Y3^X6,      Z1^X4^Y5,      Z0^Y4^X5,      X5,            }, // 37\n    {Z2^Y3^X5,      Z1^X3^Y5,      Z0^X4^Y4,      X4,            }, // 38\n    {Y2^Z2^X5,      Z1^X3^Y4,      Z0^Y3^X4,      X4,            }, // 39\n    {Y2^Z2^X4,      Z1^X2^Y4,      Z0^X3^Y3,      X3,            }, // 40\n    {Y4^X7,         Z2^X4^Y7,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 41\n    {Y3^X7,         Z2^X4^Y6,      Z1^Y4^X6,      Z0^X5^Y5,      }, // 42\n    {Y3^X6,         Z2^X3^Y6,      Z1^Y4^X5,      Z0^X4^Y5,      }, // 43\n    {Y2^X6,         Z2^X3^Y5,      Z1^Y3^X5,      Z0^X4^Y4,      }, // 44\n    {Y2^X5,         X2^Z2^Y5,      Z1^Y3^X4,      Z0^X3^Y4,      }, // 45\n    {Y4^X7,         X4^Y7,         Z2^Y5^X6,      Z1^X5^Y6,      }, // 46\n    {Y3^X7,         X4^Y6,         Z2^Y4^X6,      Z1^X5^Y5,      }, // 47\n    {Y3^X6,         X3^Y6,         Z2^Y4^X5,      Z1^X4^Y5,      }, // 48\n    {Y2^X6,         X3^Y5,         Z2^Y3^X5,      Z1^X4^Y4,      }, // 49\n    {Y2^X5,         X2^Y5,         Z2^Y3^X4,      Z1^X3^Y4,      }, // 50\n    {Z3^Y4^X7,      Z2^X4^Y7,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 51\n    {Y3^Z3^X7,      Z2^X4^Y6,      Z1^Y4^X6,      Z0^X5^Y5,      }, // 52\n    {Y3^Z3^X6,      Z2^X3^Y6,      Z1^Y4^X5,      Z0^X4^Y5,      }, // 53\n    {Y2^Z3^X6,      Z2^X3^Y5,      Z1^Y3^X5,      Z0^X4^Y4,      }, // 54\n    {Y2^Z3^X5,      X2^Z2^Y5,      Z1^Y3^X4,      Z0^X3^Y4,      }, // 55\n    {Y4^X7,         Z3^X4^Y7,      Z2^Y5^X6,      Z1^X5^Y6,      }, // 56\n    {Y3^X7,         Z3^X4^Y6,      Z2^Y4^X6,      Z1^X5^Y5,      }, // 57\n    {Y3^X6,         X3^Z3^Y6,      Z2^Y4^X5,      Z1^X4^Y5,      }, // 58\n    {Y2^X6,         X3^Z3^Y5,      Z2^Y3^X5,      Z1^X4^Y4,      }, // 59\n    {Y2^X5,         X2^Z3^Y5,      Z2^Y3^X4,      Z1^X3^Y4,      }, // 60\n    {Y4^X7,         X4^Y7,         Z3^Y5^X6,      Z2^X5^Y6,      }, // 61\n    {Y3^X7,         X4^Y6,         Z3^Y4^X6,      Z2^X5^Y5,      }, // 62\n    {Y3^X6,         X3^Y6,         Z3^Y4^X5,      Z2^X4^Y5,      }, // 63\n    {Y2^X6,         X3^Y5,         Y3^Z3^X5,      Z2^X4^Y4,      }, // 64\n    {Y2^X5,         X2^Y5,         Y3^Z3^X4,      Z2^X3^Y4,      }, // 65\n    {Y4^X8,         X4^Y8,         Z2^Y5^X7,      Z1^X5^Y7,      }, // 66\n    {Y3^X8,         X4^Y7,         Z2^Y4^X7,      Z1^X5^Y6,      }, // 67\n    {Y3^X7,         X3^Y7,         Z2^Y4^X6,      Z1^X4^Y6,      }, // 68\n    {Y2^X7,         X3^Y6,         Z2^Y3^X6,      Z1^X4^Y5,      }, // 69\n    {Y2^X6,         X2^Y6,         Z2^Y3^X5,      Z1^X3^Y5,      }, // 70\n    {Y4^X8,         Z3^X4^Y8,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 71\n    {Y3^X8,         Z3^X4^Y7,      Z2^Y4^X7,      Z1^X5^Y6,      }, // 72\n    {Y3^X7,         X3^Z3^Y7,      Z2^Y4^X6,      Z1^X4^Y6,      }, // 73\n    {Y2^X7,         X3^Z3^Y6,      Z2^Y3^X6,      Z1^X4^Y5,      }, // 74\n    {Y2^X6,         X2^Z3^Y6,      Z2^Y3^X5,      Z1^X3^Y5,      }, // 75\n    {Y4^X9,         X4^Y9,         Z3^Y5^X8,      Z2^X5^Y8,      }, // 76\n    {Y3^X9,         X4^Y8,         Z3^Y4^X8,      Z2^X5^Y7,      }, // 77\n    {Y3^X8,         X3^Y8,         Z3^Y4^X7,      Z2^X4^Y7,      }, // 78\n    {Y2^X8,         X3^Y7,         Y3^Z3^X7,      Z2^X4^Y6,      }, // 79\n    {Y2^X7,         X2^Y7,         Y3^Z3^X6,      Z2^X3^Y6,      }, // 80\n    {Y4^Z4^X8,      Z3^X4^Y8,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 81\n    {Y3^Z4^X8,      Z3^X4^Y7,      Z2^Y4^X7,      Z1^X5^Y6,      }, // 82\n    {Y3^Z4^X7,      X3^Z3^Y7,      Z2^Y4^X6,      Z1^X4^Y6,      }, // 83\n    {Y2^Z4^X7,      X3^Z3^Y6,      Z2^Y3^X6,      Z1^X4^Y5,      }, // 84\n    {Y2^Z4^X6,      X2^Z3^Y6,      Z2^Y3^X5,      Z1^X3^Y5,      }, // 85\n    {Y4^X9,         X4^Z4^Y9,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 86\n    {Y3^X9,         X4^Z4^Y8,      Z3^Y4^X8,      Z2^X5^Y7,      }, // 87\n    {Y3^X8,         X3^Z4^Y8,      Z3^Y4^X7,      Z2^X4^Y7,      }, // 88\n    {Y2^X8,         X3^Z4^Y7,      Y3^Z3^X7,      Z2^X4^Y6,      }, // 89\n    {Y2^X7,         X2^Z4^Y7,      Y3^Z3^X6,      Z2^X3^Y6,      }, // 90\n    {X4^Y4,         X4,            Y5,            X5,            }, // 91\n    {Y3^X4,         X4,            Y4,            X5,            }, // 92\n    {X3^Y3,         X3,            Y4,            X4,            }, // 93\n    {Y2^X3,         X3,            Y3,            X4,            }, // 94\n    {X2^Y2,         X2,            Y3,            X3,            }, // 95\n    {Y4^X5,         X4^Y5,         Y5,            X5,            }, // 96\n    {Y3^X5,         X4^Y4,         Y4,            X5,            }, // 97\n    {Y3^X4,         X3^Y4,         Y4,            X4,            }, // 98\n    {Y2^X4,         X3^Y3,         Y3,            X4,            }, // 99\n    {Y2^X3,         X2^Y3,         Y3,            X3,            }, // 100\n    {Y4^X6,         X4^Y6,         X5^Y5,         X5,            }, // 101\n    {Y3^X6,         X4^Y5,         Y4^X5,         X5,            }, // 102\n    {Y3^X5,         X3^Y5,         X4^Y4,         X4,            }, // 103\n    {Y2^X5,         X3^Y4,         Y3^X4,         X4,            }, // 104\n    {Y2^X4,         X2^Y4,         X3^Y3,         X3,            }, // 105\n    {Y4^X7,         X4^Y7,         Y5^X6,         X5^Y6,         }, // 106\n    {Y3^X7,         X4^Y6,         Y4^X6,         X5^Y5,         }, // 107\n    {Y3^X6,         X3^Y6,         Y4^X5,         X4^Y5,         }, // 108\n    {Y2^X6,         X3^Y5,         Y3^X5,         X4^Y4,         }, // 109\n    {Y2^X5,         X2^Y5,         Y3^X4,         X3^Y4,         }, // 110\n    {Y4,            X4,            Y5^X7,         X5^Y7,         }, // 111\n    {Y3,            X4,            Y4^X7,         X5^Y6,         }, // 112\n    {Y3,            X3,            Y4^X6,         X4^Y6,         }, // 113\n    {Y2,            X3,            Y3^X6,         X4^Y5,         }, // 114\n    {Y2,            X2,            Y3^X5,         X3^Y5,         }, // 115\n    {X4,            Y4,            X5^Y8,         Y5^X8,         }, // 116\n    {Y3,            X4,            Y4^X8,         X5^Y7,         }, // 117\n    {X3,            Y3,            X4^Y7,         Y4^X7,         }, // 118\n    {Y2,            X3,            Y3^X7,         X4^Y7,         }, // 119\n    {X2,            Y2,            X3^Y7,         Y3^X6,         }, // 120\n    {Z0^X4^Y4,      Y4,            X5,            Y5^X9,         }, // 121\n    {Z0^X4^Y4,      Y3,            Y4,            X5^Y8,         }, // 122\n    {Z0^X4^Y4,      X3,            Y3,            Y4^X8,         }, // 123\n    {Z0^X4^Y4,      Y2,            X3,            Y3^X8,         }, // 124\n    {Z0^X4^Y4,      X2,            Y2,            Y3^X7,         }, // 125\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5,            Y5,            }, // 126\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y3,            X5,            }, // 127\n    {Y4^X5^Y5,      Z0^X4^Y4,      X3,            Y3,            }, // 128\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y2,            X3,            }, // 129\n    {Y4^X5^Y5,      Z0^X4^Y4,      X2,            Y2,            }, // 130\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y5,            }, // 131\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y3,            }, // 132\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X3,            }, // 133\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y2,            }, // 134\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X2,            }, // 135\n    {Y4^X6^Y6,      Z1^X4^Y4,      X5,            X6,            }, // 136\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y3,            X5,            }, // 137\n    {Y4^X6^Y6,      Z1^X4^Y4,      X3,            Y3,            }, // 138\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y2,            X3,            }, // 139\n    {Y4^X6^Y6,      Z1^X4^Y4,      X2,            Y2,            }, // 140\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5,            }, // 141\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y3,            }, // 142\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X3,            }, // 143\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y2,            }, // 144\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X2,            }, // 145\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         }, // 146\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X6,            }, // 147\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y3,            }, // 148\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X3,            }, // 149\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Y2,            }, // 150\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X2,            }, // 151\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         }, // 152\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      }, // 153\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         }, // 154\n    {Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      }, // 155\n    {Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      }, // 156\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         }, // 157\n    {Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      }, // 158\n    {Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      }, // 159\n    {Y3,            X4,            Y4^X8,         Y5^X7,         }, // 160\n    {X3,            Y3,            Y4^X7,         X4^Y7,         }, // 161\n    {X2,            Y2,            Y3^X6,         X3^Y7,         }, // 162\n    {Z0^X4^Y4,      Y3,            Y4,            Y5^X8,         }, // 163\n    {Z0^X4^Y4,      X2,            X3,            Y3^X8,         }, // 164\n    {Y4^X5^Y5,      Z0^X4^Y4,      X2,            X3,            }, // 165\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X2^X5^Y6,      }, // 166\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y1^X5^Y6,      }, // 167\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X2,            }, // 168\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y1^X5^Y6,      }, // 169\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y1^X5^Y7,      }, // 170\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Y1^X5^Y8,      }, // 171\n    {Z0^X4^Y4,      X3,            Y3,            X5^Y7,         }, // 172\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y1^X5^Y5,      X2,            }, // 173\n    {Y4^X6^Y6,      Z1^X4^Y4,      X2,            X3,            }, // 174\n    {Y4^X6^Y6,      Z0^X4^Y4,      X2,            X3,            }, // 175\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X2,            }, // 176\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X1^X5^Y6,      }, // 177\n    {Y4^X7^Y7,      Z1^X4^Y4,      Y1^Y5^X6,      X3,            }, // 178\n    {Y4^X7^Y7,      Z0^X4^Y4,      Y1^Y5^X6,      X3,            }, // 179\n    {Y4^X7^Y7,      Z1^X4^Y4,      Y1^Y5^X6,      Z0^X5^Y6,      }, // 180\n    {Y4^X7^Y7,      Z0^X4^Y4,      Y1^Y5^X6,      X1^X5^Y6,      }, // 181\n    {Y4^X8^Y8,      Z1^X4^Y4,      Y1^Y5^X7,      Z0^X5^Y7,      }, // 182\n    {Y4^X8^Y8,      Z0^X4^Y4,      Y1^Y5^X7,      X1^X5^Y7,      }, // 183\n    {Y4^X9^Y9,      Z1^X4^Y4,      Y1^Y5^X8,      Z0^X5^Y8,      }, // 184\n    {Y4^X9^Y9,      Z0^X4^Y4,      Y1^Y5^X8,      X1^X5^Y8,      }, // 185\n    {X3,            Y3,            Y4^X6,         X4^Y7,         }, // 186\n    {Y2,            X3,            Y3^X6,         X4^Y7,         }, // 187\n    {Z0^X4^Y4,      X3,            Y3,            Y4^X6,         }, // 188\n    {Z0^X4^Y4,      X2,            X3,            Y3^X7,         }, // 189\n    {Z0^X4^Y4,      X2,            Y2,            X3^Y7,         }, // 190\n    {Y4^X5^Y5,      Y0^X4^Y4,      X2,            X3,            }, // 191\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y2^X5^Y5,      X2,            }, // 192\n    {Y4^X5^Y5,      Y0^X4^Y4,      X1^X5^Y5,      X2,            }, // 193\n    {Y4^X6^Y6,      Z0^X4^Y4,      X3,            Y3,            }, // 194\n    {Y4^X6^Y6,      Y0^X4^Y4,      X3,            Y3,            }, // 195\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X3,            }, // 196\n    {Y4^X6^Y6,      Y0^X4^Y4,      Y1^X5^Y5,      X3,            }, // 197\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y2^X5^Y6,      }, // 198\n    {Y4^X6^Y6,      Z0^X4^Y4,      Y1^X5^Y5,      X2^X5^Y6,      }, // 199\n    {Y4^X6^Y6,      Y0^X4^Y4,      Y1^X5^Y5,      Y2^X5^Y6,      }, // 200\n    {Y4^X7^Y7,      Y0^X4^Y4,      Y1^Y5^X6,      X3,            }, // 201\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y2^X5^Y6,      }, // 202\n    {Y4^X7^Y7,      Y0^X4^Y4,      Y1^Y5^X6,      X1^X5^Y6,      }, // 203\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y2^X5^Y7,      }, // 204\n    {Y4^X8^Y8,      Y0^X4^Y4,      Y1^Y5^X7,      X1^X5^Y7,      }, // 205\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X2^X5^Y7,      }, // 206\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X2^X5^Y8,      }, // 207\n    {Y4^X9^Y9,      Y0^X4^Y4,      Y1^Y5^X8,      X1^X5^Y8,      }, // 208\n    {Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      }, // 209\n    {Y2,            X3,            Y3^X7,         Y4^X6,         }, // 210\n    {Y1,            X2,            Y2^X7,         Y3^X6,         }, // 211\n    {Z0^X4^Y4,      Y2,            Y3,            Y4^X7,         }, // 212\n    {Z0^X4^Y4,      Y1,            Y2,            Y3^X6,         }, // 213\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y1,            Y2,            }, // 214\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y1,            }, // 215\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y1,            X2,            }, // 216\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y1,            }, // 217\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y2,            }, // 218\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Y1,            }, // 219\n    {Y1,            X2,            Y2^X6,         X3^Y7,         }, // 220\n    {X1,            Y1,            X2^Y7,         Y2^X6,         }, // 221\n    {Z0^X4^Y4,      Y1,            X2,            Y2^X7,         }, // 222\n    {Z0^X4^Y4,      X1,            Y1,            Y2^X6,         }, // 223\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y1,            X2,            }, // 224\n    {Y4^X5^Y5,      Z0^X4^Y4,      X1,            Y1,            }, // 225\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X1,            }, // 226\n    {Y4^X6^Y6,      Z1^X4^Y4,      X1,            Y1,            }, // 227\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X1,            }, // 228\n    {Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X1,            }, // 229\n    {Y0,            X1,            Y1^X7,         Y2^X6,         }, // 230\n    {Z0^X4^Y4,      Y0,            Y1,            Y2^X6,         }, // 231\n    {Y4^X5^Y5,      Z0^X4^Y4,      Y0,            Y1,            }, // 232\n    {Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y0,            }, // 233\n    {Y4^X6^Y6,      Z1^X4^Y4,      Y0,            X1,            }, // 234\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y0,            }, // 235\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y3^X5,         }, // 236\n    {Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X3^Y5,         }, // 237\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y1,            }, // 238\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X1,            }, // 239\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Z2^X5^Y6,      }, // 240\n    {Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      Y0^X5^Y6,      }, // 241\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Z2^X5^Y7,      }, // 242\n    {Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      Y0^X5^Y7,      }, // 243\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Z2^X5^Y8,      }, // 244\n    {Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      Y0^X5^Y8,      }, // 245\n    {Y2,            X3,            Z3,            Y3,            }, // 246\n    {Y2,            X2,            Z3,            Y3,            }, // 247\n    {Y2,            X2,            Z2,            Y3,            }, // 248\n    {Y1,            X2,            Z2,            Y2,            }, // 249\n    {Y1,            X1,            Z2,            Y2,            }, // 250\n    {Y2^X3^Z3,      X3,            Z3,            Y3,            }, // 251\n    {X2^Y2^Z3,      X2,            Z3,            Y3,            }, // 252\n    {X2^Y2^Z2,      X2,            Z2,            Y3,            }, // 253\n    {Y1^X2^Z2,      X2,            Z2,            Y2,            }, // 254\n    {X1^Y1^Z2,      X1,            Z2,            Y2,            }, // 255\n    {Y2^X4^Z4,      X3^Y3^Z3,      Z3,            Y3,            }, // 256\n    {Y2^X3^Z4,      X2^Y3^Z3,      Z3,            Y3,            }, // 257\n    {Y2^X3^Z3,      X2^Z2^Y3,      Z2,            Y3,            }, // 258\n    {Y1^X3^Z3,      X2^Y2^Z2,      Z2,            Y2,            }, // 259\n    {Y1^X2^Z3,      X1^Y2^Z2,      Z2,            Y2,            }, // 260\n    {Y2^X5^Z5,      X3^Y4^Z4,      Y3^Z3^X4,      Y3,            }, // 261\n    {Y2^X4^Z5,      X2^Y4^Z4,      X3^Y3^Z3,      Y3,            }, // 262\n    {Y2^X4^Z4,      X2^Z3^Y4,      Z2^X3^Y3,      Y3,            }, // 263\n    {Y1^X4^Z4,      X2^Y3^Z3,      Y2^Z2^X3,      Y2,            }, // 264\n    {Y1^X3^Z4,      X1^Y3^Z3,      X2^Y2^Z2,      Y2,            }, // 265\n    {Y2^X6^Z6,      X3^Y5^Z5,      Z3^Y4^X5,      Y3^X4^Z4,      }, // 266\n    {Y2^X5^Z6,      X2^Y5^Z5,      Z3^X4^Y4,      X3^Y3^Z4,      }, // 267\n    {Y2^X5^Z5,      X2^Z4^Y5,      Z2^X4^Y4,      X3^Y3^Z3,      }, // 268\n    {Y1^X5^Z5,      X2^Y4^Z4,      Z2^Y3^X4,      Y2^X3^Z3,      }, // 269\n    {Y1^X4^Z5,      X1^Y4^Z4,      Z2^X3^Y3,      X2^Y2^Z3,      }, // 270\n    {Y2^X7^Z7,      X3^Y6^Z6,      Z3^Y5^X6,      Y3^X5^Z5,      }, // 271\n    {Y2^X6^Z7,      X2^Y6^Z6,      Z3^X5^Y5,      Y3^X4^Z5,      }, // 272\n    {Y2^X6^Z6,      X2^Z5^Y6,      Z2^X5^Y5,      Y3^X4^Z4,      }, // 273\n    {Y1^X6^Z6,      X2^Y5^Z5,      Z2^Y4^X5,      Y2^X4^Z4,      }, // 274\n    {Y1^X5^Z6,      X1^Y5^Z5,      Z2^X4^Y4,      Y2^X3^Z4,      }, // 275\n    {Y2^X8^Z8,      X3^Y7^Z7,      Z3^Y6^X7,      Y3^X6^Z6,      }, // 276\n    {Y2^X7^Z8,      X2^Y7^Z7,      Z3^X6^Y6,      Y3^X5^Z6,      }, // 277\n    {Y2^X7^Z7,      X2^Z6^Y7,      Z2^X6^Y6,      Y3^X5^Z5,      }, // 278\n    {Y1^X7^Z7,      X2^Y6^Z6,      Z2^Y5^X6,      Y2^X5^Z5,      }, // 279\n    {Y1^X6^Z7,      X1^Y6^Z6,      Z2^X5^Y5,      Y2^X4^Z5,      }, // 280\n    {Y2^X5,         X3^Y4^Z4,      Y3^Z3^X4,      Y3,            }, // 281\n    {Y2^X4,         X2^Y4^Z4,      X3^Y3^Z3,      Y3,            }, // 282\n    {Y2^X4,         X2^Z3^Y4,      Z2^X3^Y3,      Y3,            }, // 283\n    {Y1^X4,         X2^Y3^Z3,      Y2^Z2^X3,      Y2,            }, // 284\n    {Y1^X3,         X1^Y3^Z3,      X2^Y2^Z2,      Y2,            }, // 285\n    {Y2,            X3,            Z3^Y4^X5,      Y3^X4^Z4,      }, // 286\n    {Y2,            X2,            Z3^X4^Y4,      X3^Y3^Z4,      }, // 287\n    {Y2,            X2,            Z2^X4^Y4,      X3^Y3^Z3,      }, // 288\n    {Y1,            X2,            Z2^Y3^X4,      Y2^X3^Z3,      }, // 289\n    {Y1,            X1,            Z2^X3^Y3,      X2^Y2^Z3,      }, // 290\n    {Y2,            X3,            Z3,            Y3^X5,         }, // 291\n    {Y2,            X2,            Z3,            Y3^X4,         }, // 292\n    {Y2,            X2,            Z2,            Y3^X4,         }, // 293\n    {Y1,            X2,            Z2,            Y2^X4,         }, // 294\n    {Y1,            X1,            Z2,            Y2^X3,         }, // 295\n    {X4^Y4,         Y2,            Z3,            Y3,            }, // 296\n    {X4^Y4,         Y2,            Z2,            Y3,            }, // 297\n    {X4^Y4,         Y1,            Z2,            Y2,            }, // 298\n    {Y1^X4^Y4,      X1,            Z2,            Y2,            }, // 299\n    {Y4^X5^Y5,      X4^Y4,         Y2,            Z3,            }, // 300\n    {Y4^X5^Y5,      X4^Y4,         Y2,            Z2,            }, // 301\n    {Z3^Y4^X5^Y5,   X4^Y4,         Y1,            Z2,            }, // 302\n    {Z3^Y4^X5^Y5,   Y1^X4^Y4,      X1,            Z2,            }, // 303\n    {Y4^X5^Y5,      X4^Y4,         Z3^X5,         Y2,            }, // 304\n    {Y4^X5^Y5,      X4^Y4,         Z2^X5,         Y2,            }, // 305\n    {Z3^Y4^X5^Y5,   X4^Y4,         Z2^X5,         Y1,            }, // 306\n    {Z3^Y4^X5^Y5,   Y1^X4^Y4,      Z2^X5,         X1,            }, // 307\n    {Y4^X6^Y6,      X4^Y4,         Y2,            Y3,            }, // 308\n    {Y4^X6^Y6,      X4^Y4,         Z3,            Y3,            }, // 309\n    {Y4^X6^Y6,      X4^Y4,         Z2,            Y3,            }, // 310\n    {Z3^Y4^X6^Y6,   X4^Y4,         Z2,            Y2,            }, // 311\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      Z2,            Y2,            }, // 312\n    {Y4^X6^Y6,      X4^Y4,         X5^Y5,         Y2,            }, // 313\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z3,            }, // 314\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z2,            }, // 315\n    {Z3^Y4^X6^Y6,   X4^Y4,         Y1^X5^Y5,      Z2,            }, // 316\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      X1^X5^Y5,      Z2,            }, // 317\n    {Y4^X6^Y6,      X4^Y4,         X5^Y5,         Z3^X6,         }, // 318\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z3^X6,         }, // 319\n    {Y4^X6^Y6,      X4^Y4,         Y2^X5^Y5,      Z2^X6,         }, // 320\n    {Z3^Y4^X6^Y6,   X4^Y4,         Y1^X5^Y5,      Z2^X6,         }, // 321\n    {Z3^Y4^X6^Y6,   Y1^X4^Y4,      X1^X5^Y5,      Z2^X6,         }, // 322\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Y3,            }, // 323\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Y2,            }, // 324\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Y2,            }, // 325\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      X5^Y6,         }, // 326\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Z3^X5^Y6,      }, // 327\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Z2^X5^Y6,      }, // 328\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Z2^X5^Y6,      }, // 329\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Z2^X5^Y6,      }, // 330\n    {Y4^X7^Y7,      X4^Y4,         Y2^Y5^X6,      Y3^X5^Y6,      }, // 331\n    {Z3^Y4^X7^Y7,   X4^Y4,         Y1^Y5^X6,      Y2^X5^Y6,      }, // 332\n    {Z3^Y4^X7^Y7,   Y1^X4^Y4,      X1^Y5^X6,      Y2^X5^Y6,      }, // 333\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      X5^Y7,         }, // 334\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Z3^X5^Y7,      }, // 335\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Z2^X5^Y7,      }, // 336\n    {Z3^Y4^X8^Y8,   X4^Y4,         Y1^Y5^X7,      Z2^X5^Y7,      }, // 337\n    {Z3^Y4^X8^Y8,   Y1^X4^Y4,      X1^Y5^X7,      Z2^X5^Y7,      }, // 338\n    {Y4^X8^Y8,      X4^Y4,         Y2^Y5^X7,      Y3^X5^Y7,      }, // 339\n    {Z3^Y4^X8^Y8,   X4^Y4,         Y1^Y5^X7,      Y2^X5^Y7,      }, // 340\n    {Z3^Y4^X8^Y8,   Y1^X4^Y4,      X1^Y5^X7,      Y2^X5^Y7,      }, // 341\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      X5^Y8,         }, // 342\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      Z3^X5^Y8,      }, // 343\n    {Y4^X9^Y9,      X4^Y4,         Y2^Y5^X8,      Z2^X5^Y8,      }, // 344\n    {Z3^Y4^X9^Y9,   X4^Y4,         Y1^Y5^X8,      Z2^X5^Y8,      }, // 345\n    {Z3^Y4^X9^Y9,   Y1^X4^Y4,      X1^Y5^X8,      Z2^X5^Y8,      }, // 346\n};\n\nconst UINT_64 GFX11_SW_PATTERN_NIBBLE3[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y6,            X6,            Y7,            X7,            }, // 1\n    {Y5,            X6,            Y6,            X7,            }, // 2\n    {Y5,            X5,            Y6,            X6,            }, // 3\n    {Y4,            X5,            Y5,            X6,            }, // 4\n    {Y4,            X4,            Y5,            X5,            }, // 5\n    {Z0^X6^Y6,      X6,            Y7,            X7,            }, // 6\n    {Z0^Y5^X6,      X6,            Y6,            X7,            }, // 7\n    {Z0^X5^Y5,      X5,            Y6,            X6,            }, // 8\n    {Z0^Y4^X5,      X5,            Y5,            X6,            }, // 9\n    {Z0^X4^Y4,      X4,            Y5,            X5,            }, // 10\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y7,            X7,            }, // 11\n    {Z1^Y5^X7,      Z0^X6^Y6,      Y6,            X7,            }, // 12\n    {Z1^Y5^X6,      Z0^X5^Y6,      Y6,            X6,            }, // 13\n    {Z1^Y4^X6,      Z0^X5^Y5,      Y5,            X6,            }, // 14\n    {Z1^Y4^X5,      Z0^X4^Y5,      Y5,            X5,            }, // 15\n    {X6^Y6,         X6,            Y7,            X7,            }, // 16\n    {Y5^X6,         X6,            Y6,            X7,            }, // 17\n    {X5^Y5,         X5,            Y6,            X6,            }, // 18\n    {Y4^X5,         X5,            Y5,            X6,            }, // 19\n    {X4^Y4,         X4,            Y5,            X5,            }, // 20\n    {Y6^X7,         X6^Y7,         Y7,            X7,            }, // 21\n    {Y5^X7,         X6^Y6,         Y6,            X7,            }, // 22\n    {Y5^X6,         X5^Y6,         Y6,            X6,            }, // 23\n    {Y4^X6,         X5^Y5,         Y5,            X6,            }, // 24\n    {Y4^X5,         X4^Y5,         Y5,            X5,            }, // 25\n    {X6^Y7,         Y6^X7,         X7,            Y7,            }, // 26\n    {X5^Y6,         Y5^X6,         X6,            Y6,            }, // 27\n    {Y4^X6,         X5^Y6,         Y5,            X6,            }, // 28\n    {X4^Y6,         Y4^X5,         X5,            Y5,            }, // 29\n    {X6^Y8,         Y6^X8,         X7^Y7,         Y7,            }, // 30\n    {X6^Y7,         Y5^X8,         Y6^X7,         Y6,            }, // 31\n    {X5^Y7,         Y5^X7,         X6^Y6,         Y6,            }, // 32\n    {X5^Y7,         Y4^X7,         X6^Y6,         Y5,            }, // 33\n    {X3^Y7,         Y4^X6,         X5^Y6,         Y5,            }, // 34\n    {X6^Y9,         Y6^X9,         X7^Y8,         Y7^X8,         }, // 35\n    {X6^Y8,         Y5^X9,         X7^Y7,         Y6^X8,         }, // 36\n    {X5^Y8,         Y5^X8,         X6^Y7,         Y6^X7,         }, // 37\n    {Y3^X8,         X5^Y7,         X6^Y6,         Y5^X7,         }, // 38\n    {Y3^X7,         X3^Y7,         X5^Y6,         Y5^X6,         }, // 39\n    {X6,            Y6^X9,         X7^Y8,         Y7^X8,         }, // 40\n    {Y5,            X6^Y8,         X7^Y7,         Y6^X8,         }, // 41\n    {Y3,            Y5^X8,         X6^Y7,         Y6^X7,         }, // 42\n    {X3,            Y3^X8,         X6^Y6,         Y5^X7,         }, // 43\n    {Y2,            Y3^X7,         X3^Y6,         Y5^X6,         }, // 44\n    {Y6^X9,         X7^Y8,         Y7^X8,         Z0^X5^Y5,      }, // 45\n    {X6^Y8,         Y6^X8,         X7^Y7,         Z0^X5^Y5,      }, // 46\n    {X5^Y8,         X6^Y7,         Y6^X7,         Z0^X5^Y5,      }, // 47\n    {Y3^X7,         X5^Y7,         X6^Y6,         Z0^X5^Y5,      }, // 48\n    {X3^Y7,         Y3^X6,         X5^Y6,         Z0^X5^Y5,      }, // 49\n    {X5,            X6^Y8,         Y6^X8,         X7^Y7,         }, // 50\n    {Y3,            X5^Y8,         X6^Y7,         Y6^X7,         }, // 51\n    {X3,            Y3^X7,         X5^Y7,         X6^Y6,         }, // 52\n    {Y2,            X3^Y7,         Y3^X6,         X5^Y6,         }, // 53\n    {X6,            Y6,            X7^Y8,         Y7^X8,         }, // 54\n    {Y3,            X6,            Y6^X8,         X7^Y7,         }, // 55\n    {X3,            Y3,            X6^Y7,         Y6^X7,         }, // 56\n    {Y2,            X3,            Y3^X7,         X6^Y6,         }, // 57\n    {X2,            Y2,            X3^Y6,         Y3^X6,         }, // 58\n    {Y6,            X7^Y8,         Y7^X8,         X5^Y6,         }, // 59\n    {X6,            X7^Y7,         Y6^X8,         X5^Y6,         }, // 60\n    {Y3,            X6^Y7,         Y6^X7,         X5^Y6,         }, // 61\n    {X3,            Y3^X7,         X6^Y6,         Z0^X5^Y6,      }, // 62\n    {Y2,            Y3^X6,         X3^Y6,         Z0^X5^Y6,      }, // 63\n    {Y3,            X6,            X7^Y7,         Y6^X8,         }, // 64\n    {X2,            Y2,            Y3^X6,         X3^Y6,         }, // 65\n    {X6^Y6,         Y6,            X7,            Y7^X8,         }, // 66\n    {X6^Y6,         Y3,            Y6,            X7^Y7,         }, // 67\n    {X6^Y6,         X3,            Y3,            Y6^X7,         }, // 68\n    {X6^Y6,         Y2,            X3,            Y3^X7,         }, // 69\n    {X3^Y6,         X2,            Y2,            Y3^X6,         }, // 70\n    {X6,            X7,            Y7^X8,         X6^Y6,         }, // 71\n    {Y3,            X6,            X7^Y7,         X6^Y6,         }, // 72\n    {X3,            Y3,            X6^Y7,         X6^Y6,         }, // 73\n    {Y2,            X3,            Y3^X7,         Z0^X6^Y6,      }, // 74\n    {X2,            X3,            Y3^X6,         Y2^X6^Y6,      }, // 75\n    {X6^Y6,         X6,            X7,            Y7^X8,         }, // 76\n    {X6^Y6,         Y3,            X6,            X7^Y7,         }, // 77\n    {X6^Y6,         X3,            Y3,            X6^Y7,         }, // 78\n    {Z0^X6^Y6,      Y2,            X3,            Y3^X7,         }, // 79\n    {Y2^X6^Y6,      X2,            X3,            Y3^X6,         }, // 80\n    {X6^Y6,         X6^Y8,         X7,            Y7,            }, // 81\n    {X6^Y6,         X6^Y8,         Y3,            X7,            }, // 82\n    {X6^Y6,         X6^Y8,         X3,            Y3,            }, // 83\n    {Z0^X6^Y6,      X3^Y8,         Y2,            Y3,            }, // 84\n    {Y2^X6^Y6,      X3^Y8,         X2,            Y3,            }, // 85\n    {Y6^X7,         X7,            Y7,            X6^Y7,         }, // 86\n    {Y6^X7,         Y3,            X7,            X6^Y7,         }, // 87\n    {Y6^X7,         X3,            Y3,            X6^Y7,         }, // 88\n    {Y2^Y6^X7,      X3,            Y3,            Z0^X6^Y7,      }, // 89\n    {Y2^Y6^X7,      X3,            Y3,            X2^X6^Y7,      }, // 90\n    {Y6^X7,         X6^Y7,         X7,            Y7,            }, // 91\n    {Y6^X7,         X6^Y7,         Y3,            X7,            }, // 92\n    {Y6^X7,         X6^Y7,         X3,            Y3,            }, // 93\n    {Y2^Y6^X7,      Z0^X6^Y7,      X3,            Y3,            }, // 94\n    {Y2^Y6^X7,      X2^X6^Y7,      X3,            Y3,            }, // 95\n    {X5^Y7,         X6^Y6,         X6,            Y7,            }, // 96\n    {Y5^X6,         X5^Y6,         Y6,            Y2^X6,         }, // 97\n    {Y4^X6,         X5^Y6,         Y5,            X2^X6,         }, // 98\n    {Y4^X5,         X4^Y6,         Y5,            Y1^X5,         }, // 99\n    {X5^Y8,         Y6^X7,         X6^Y7,         Y7,            }, // 100\n    {Y5^X7,         X5^Y7,         X6^Y6,         Y2^X6,         }, // 101\n    {Y4^X7,         X5^Y6,         Y5^X6,         Y2^X6,         }, // 102\n    {Y4^X6,         X3^Y6,         X5^Y5,         Y1^X5,         }, // 103\n    {Y5^X9,         Y6^X8,         X6^Y8,         X7^Y7,         }, // 104\n    {Y5^X8,         X5^Y8,         Y6^X7,         Y2^X6^Y7,      }, // 105\n    {Y3^X8,         X5^Y7,         Y5^X7,         Y2^X6^Y6,      }, // 106\n    {Y3^X7,         X3^Y7,         Y5^X6,         Y1^X5^Y6,      }, // 107\n    {X5,            Y6^X8,         X6^Y8,         X7^Y7,         }, // 108\n    {Y3,            X5^Y8,         Y6^X7,         Y2^X6^Y7,      }, // 109\n    {X3,            Y3^X7,         X5^Y7,         Y2^X6^Y6,      }, // 110\n    {Y2,            Y3^X6,         X3^Y7,         Y1^X5^Y6,      }, // 111\n    {Y6^X8,         X6^Y8,         X7^Y7,         Z0^X5^Y5,      }, // 112\n    {X5^Y8,         Y6^X7,         Y2^X6^Y7,      Z0^X5^Y5,      }, // 113\n    {Y3^X7,         X5^Y7,         X2^X6^Y6,      Z0^X5^Y5,      }, // 114\n    {Y3^X6,         X3^Y7,         Y1^X5^Y6,      Z0^X5^Y5,      }, // 115\n    {X3,            Y3^X7,         X5^Y7,         X2^X6^Y6,      }, // 116\n    {Y3,            X5,            X6^Y8,         X7^Y7,         }, // 117\n    {X3,            Y3,            X5^Y8,         X6^Y7,         }, // 118\n    {X3,            Y3,            X5^Y8,         Y2^X6^Y7,      }, // 119\n    {Y2,            X3,            Y3^X6,         X5^Y6,         }, // 120\n    {X2,            Y2,            Y3^X5,         X3^Y6,         }, // 121\n    {X6,            Y6^X8,         X7^Y7,         X5^Y6,         }, // 122\n    {Y3,            Y6^X7,         Y2^X6^Y7,      X5^Y6,         }, // 123\n    {X3,            Y3^X7,         Y2^X6^Y6,      Z0^X5^Y6,      }, // 124\n    {X3,            Y3^X7,         Y2^X6^Y6,      Y1^X5^Y6,      }, // 125\n    {X3,            Y3,            Y6^X7,         Y2^X6^Y7,      }, // 126\n    {X2,            X3,            Y3^X7,         Y2^X6^Y6,      }, // 127\n    {X6^Y6,         X3,            Y3,            Y2^X6^Y7,      }, // 128\n    {X3,            Y3,            Y2^X6^Y7,      X6^Y6,         }, // 129\n    {X3,            Y3,            X2^X6^Y7,      Y2^X6^Y6,      }, // 130\n    {Y2^X6^Y6,      X3,            Y3,            X2^X6^Y7,      }, // 131\n    {X6^Y6,         X6^Y8,         Y3,            Y7,            }, // 132\n    {X6^Y6,         Y2^X6^Y8,      X3,            Y3,            }, // 133\n    {Y2^X6^Y6,      X2^X6^Y8,      X3,            Y3,            }, // 134\n    {Y6^X7,         Y3,            Y7,            X6^Y7,         }, // 135\n    {Y6^X7,         X3,            Y3,            Y2^X6^Y7,      }, // 136\n    {Y6^X7,         X6^Y7,         Y3,            Y7,            }, // 137\n    {Y6^X7,         Y2^X6^Y7,      X3,            Y3,            }, // 138\n    {X5^Y6,         Y5^X6,         X6,            Y2^Y6,         }, // 139\n    {X5^Y6,         Y5^X6,         X2^X6,         Y2^Y6,         }, // 140\n    {Y4^X6,         X5^Y6,         X2^X6,         Y1^Y5,         }, // 141\n    {X4^Y6,         Y4^X5,         X1^X5,         Y1^Y5,         }, // 142\n    {Y4^X8,         X6^Y6,         Y5^X7,         Y2^X7,         }, // 143\n    {X5^Y6,         Y5^X7,         X2^X6^Y6,      Y2^X6,         }, // 144\n    {X5^Y6,         Y4^X7,         X2^Y5^X6,      Y1^X6,         }, // 145\n    {X3^Y6,         Y4^X6,         X1^X5^Y5,      Y1^X5,         }, // 146\n    {X5^Y8,         X6^Y7,         Y5^X8,         Y2^Y6^X7,      }, // 147\n    {X5^Y8,         Y5^X8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 148\n    {Y3^X8,         X5^Y7,         X2^Y5^X7,      Y1^X6^Y6,      }, // 149\n    {Y3^X7,         X3^Y7,         X1^Y5^X6,      Y1^X5^Y6,      }, // 150\n    {Y3,            X6^Y7,         Y5^X8,         Y2^Y6^X7,      }, // 151\n    {Y3,            Y5^X8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 152\n    {X3,            Y3^X8,         X2^Y5^X7,      Y1^X6^Y6,      }, // 153\n    {Y2,            Y3^X6,         X3^Y6,         X1^X5^Y5,      }, // 154\n    {X5^Y8,         X6^Y7,         Y2^Y6^X7,      Z0^X5^Y5,      }, // 155\n    {X5^Y8,         X2^X6^Y7,      Y2^Y6^X7,      Z0^X5^Y5,      }, // 156\n    {Y3^X8,         Y2^Y5^X7,      Y1^X6^Y6,      Z0^X5^Y5,      }, // 157\n    {Y3^X7,         Y2^X6^Y6,      X1^X5^Y7,      Y1^X5^Y5,      }, // 158\n    {Y3,            X5^Y8,         X6^Y7,         Y2^Y6^X7,      }, // 159\n    {Y3,            X5^Y8,         X2^X6^Y7,      Y2^Y6^X7,      }, // 160\n    {X3,            Y3^X8,         Y2^Y5^X7,      Y1^X6^Y6,      }, // 161\n    {X3,            Y3^X7,         Y2^X6^Y6,      X1^X5^Y7,      }, // 162\n    {X3,            Y3,            X6^Y7,         Y2^Y6^X7,      }, // 163\n    {X3,            Y3,            X2^X6^Y7,      Y2^Y6^X7,      }, // 164\n    {X2,            X3,            Y3^X7,         Y2^Y5^X6,      }, // 165\n    {X2,            X3,            Y3^X6,         Y2^X5^Y6,      }, // 166\n    {Y3,            X6^Y7,         Y2^Y6^X7,      X5^Y6,         }, // 167\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      X5^Y6,         }, // 168\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      Z0^X5^Y6,      }, // 169\n    {Y3,            X2^Y6^X7,      Y2^X6^Y7,      X1^X5^Y6,      }, // 170\n    {X3,            Y3,            X2^Y6^X7,      Y2^X6^Y7,      }, // 171\n    {X6^Y6,         X3,            Y3,            Y2^Y6^X7,      }, // 172\n    {Y2^X6^Y6,      X3,            Y3,            X2^X6^Y6,      }, // 173\n    {X3,            Y3,            Y2^Y6^X7,      X6^Y6,         }, // 174\n    {Y2^Y6^X7,      X3,            Y3,            X6^Y7,         }, // 175\n    {Y2^Y6^X7,      X6^Y7,         X3,            Y3,            }, // 176\n    {X5^Y5,         Y1^X5^Y6,      X2^X6,         Y2^Y6,         }, // 177\n    {Y4^X5,         X1^X5^Y6,      Y1^Y5,         X2^X6,         }, // 178\n    {Y4^X5,         Y0^X4^Y6,      X1^X5,         Y1^Y5,         }, // 179\n    {X5^Y5,         Y1^X5^Y7,      X2^X6^Y6,      Y2^Y6,         }, // 180\n    {Y4^X6,         Y1^X5^Y6,      X1^X5^Y5,      Y2^X6,         }, // 181\n    {Y3^X6,         Y0^X4^Y6,      X1^Y4^X5,      Y1^X5,         }, // 182\n    {Y5^X8,         Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 183\n    {Y3^X8,         Y1^X5^Y7,      X1^Y5^X7,      Y2^X6^Y6,      }, // 184\n    {Y3^X7,         Y1^X4^Y7,      Y2^X5^Y6,      X1^Y5^X6,      }, // 185\n    {Y3,            X5^Y8,         X2^Y6^X7,      Y2^X6^Y7,      }, // 186\n    {Y3,            Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 187\n    {X3,            Y3^X7,         Y1^X5^Y6,      X1^Y5^X6,      }, // 188\n    {X3,            Y3^X6,         Y1^X4^Y6,      Y2^X5^Y5,      }, // 189\n    {Y1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      Z0^X5^Y5,      }, // 190\n    {X1^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      Y1^X5^Y5,      }, // 191\n    {X1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      Y1^X5^Y5,      }, // 192\n    {Y3,            X1^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      }, // 193\n    {Y3,            X1^X5^Y8,      X2^X6^Y7,      Y2^Y6^X7,      }, // 194\n    {X3,            Y3,            Y1^X5^Y7,      X2^X6^Y6,      }, // 195\n    {X3,            Y3,            X1^X5^Y7,      Y2^X6^Y6,      }, // 196\n    {X3,            Y3,            X1^X5^Y7,      X2^X6^Y6,      }, // 197\n    {Y3,            X2^Y6^X7,      Y1^X6^Y7,      Y2^X5^Y6,      }, // 198\n    {X3,            Y3,            X2^Y6^X7,      Y1^X6^Y7,      }, // 199\n    {X2^X6^Y6,      X3,            Y3,            Y1^X6^Y6,      }, // 200\n    {X2^X6^Y6,      X3,            Y3,            Y2^X6^Y6,      }, // 201\n    {X3,            Y3,            Y1^X6^Y7,      X2^X6^Y6,      }, // 202\n    {Y2^X6^Y6,      X3,            Y3,            Y1^X6^Y7,      }, // 203\n    {Y2^X6^Y6,      Y1^X6^Y8,      X3,            Y3,            }, // 204\n    {Y2^Y6^X7,      X3,            Y3,            Y1^X6^Y7,      }, // 205\n    {X6,            Y6^X10,        X7^Y9,         Y7^X9,         }, // 206\n    {Y5,            X6^Y9,         X7^Y8,         Y6^X9,         }, // 207\n    {Y3,            Y5^X9,         X6^Y8,         Y6^X8,         }, // 208\n    {X3,            Y3^X9,         X6^Y7,         Y5^X8,         }, // 209\n    {Y2,            Y3^X8,         X3^Y7,         Y5^X7,         }, // 210\n    {Y6^X10,        X7^Y9,         Y7^X9,         X8^Y8,         }, // 211\n    {X5^Y9,         X6^Y8,         Y6^X8,         X7^Y7,         }, // 212\n    {Y3^X8,         X5^Y8,         X6^Y7,         Y6^X7,         }, // 213\n    {X3^Y8,         Y3^X7,         X5^Y7,         X6^Y6,         }, // 214\n    {X5,            X6^Y9,         Y6^X9,         X7^Y8,         }, // 215\n    {Y3,            X5^Y9,         X6^Y8,         Y6^X8,         }, // 216\n    {X3,            Y3^X8,         X5^Y8,         X6^Y7,         }, // 217\n    {Y2,            X3^Y8,         Y3^X7,         X5^Y7,         }, // 218\n    {X6,            Y6,            X7^Y10,        Y7^X10,        }, // 219\n    {Y3,            X6,            Y6^X10,        X7^Y9,         }, // 220\n    {X3,            Y3,            X6^Y9,         Y6^X9,         }, // 221\n    {Y2,            X3,            Y3^X9,         X6^Y8,         }, // 222\n    {X2,            Y2,            X3^Y8,         Y3^X8,         }, // 223\n    {Y6,            X7^Y10,        Y7^X10,        X8^Y9,         }, // 224\n    {X6,            X7^Y9,         Y6^X10,        X8^Y8,         }, // 225\n    {Y3,            X6^Y9,         Y6^X9,         X7^Y8,         }, // 226\n    {X3,            Y3^X9,         X6^Y8,         X7^Y7,         }, // 227\n    {Y2,            Y3^X8,         X3^Y8,         X6^Y7,         }, // 228\n    {Y3,            X6,            X7^Y9,         Y6^X10,        }, // 229\n    {X2,            Y2,            Y3^X8,         X3^Y8,         }, // 230\n    {X6^Y6,         Y6,            X7,            Y7^X10,        }, // 231\n    {X6^Y6,         Y3,            Y6,            X7^Y9,         }, // 232\n    {X6^Y6,         X3,            Y3,            Y6^X9,         }, // 233\n    {X6^Y6,         Y2,            X3,            Y3^X9,         }, // 234\n    {X6^Y6,         X2,            Y2,            Y3^X8,         }, // 235\n    {X6,            X7,            Y7^X10,        X8^Y9,         }, // 236\n    {Y3,            X6,            X7^Y9,         Y7^X9,         }, // 237\n    {X3,            Y3,            X6^Y9,         X7^Y8,         }, // 238\n    {Y2,            X3,            Y3^X8,         X6^Y8,         }, // 239\n    {X2,            Y2,            X3^Y8,         Y3^X7,         }, // 240\n    {X6^Y6,         X6,            X7,            Y7^X10,        }, // 241\n    {X6^Y6,         Y3,            X6,            X7^Y9,         }, // 242\n    {X6^Y6,         X3,            Y3,            X6^Y9,         }, // 243\n    {Z0^X6^Y6,      Y2,            X3,            Y3^X8,         }, // 244\n    {Z0^X6^Y6,      X2,            Y2,            X3^Y8,         }, // 245\n    {Z0^X6^Y6,      X6^Y8,         Y2,            X3,            }, // 246\n    {Z0^X6^Y6,      X6^Y8,         X2,            Y2,            }, // 247\n    {Y6^X7,         X7,            Y7,            X8^Y9,         }, // 248\n    {Y6^X7,         Y3,            X7,            X8^Y8,         }, // 249\n    {Y6^X7,         X3,            Y3,            X7^Y8,         }, // 250\n    {Z1^Y6^X7,      Y2,            X3,            Y3^X8,         }, // 251\n    {Z1^Y6^X7,      X2,            Y2,            Y3^X7,         }, // 252\n    {Z1^Y6^X7,      Z0^X6^Y7,      Y2,            X3,            }, // 253\n    {Z1^Y6^X7,      Z0^X6^Y7,      X2,            Y2,            }, // 254\n    {X4^Y6,         X5^Y5,         X5,            Y6,            }, // 255\n    {X3^Y6,         Y4^X5,         X4,            Y5,            }, // 256\n    {X3^Y7,         Y5^X6,         X5^Y6,         Y6,            }, // 257\n    {X2^Y7,         Y4^X5,         X3^Y6,         Y5,            }, // 258\n    {Y3^X8,         Y5^X7,         X5^Y7,         X6^Y6,         }, // 259\n    {Y3^X6,         X2^Y7,         X3^Y6,         X5^Y5,         }, // 260\n    {X5,            Y6^X9,         X6^Y9,         Y7^X8,         }, // 261\n    {X3,            Y3^X8,         X5^Y8,         Y6^X7,         }, // 262\n    {Y2,            Y3^X7,         X3^Y8,         X5^Y7,         }, // 263\n    {Y2,            Y3^X6,         X2^Y8,         X3^Y7,         }, // 264\n    {Y6^X9,         X6^Y9,         Y7^X8,         X7^Y8,         }, // 265\n    {Y3^X8,         X5^Y8,         Y6^X7,         X6^Y7,         }, // 266\n    {Y2^X7,         Y3^X6,         X3^Y7,         X5^Y6,         }, // 267\n    {X2,            Y2^X7,         Y3^X6,         X3^Y7,         }, // 268\n    {Y3,            X5,            X6^Y10,        Y7^X9,         }, // 269\n    {X3,            Y3,            X5^Y10,        X6^Y9,         }, // 270\n    {Y2,            X3,            Y3^X8,         X5^Y9,         }, // 271\n    {X2,            Y2,            X3^Y9,         Y3^X7,         }, // 272\n    {Y1,            X2,            Y2^X7,         Y3^X6,         }, // 273\n    {X6,            Y6^X10,        Y7^X9,         X7^Y9,         }, // 274\n    {X3,            Y3^X9,         Y6^X8,         X6^Y8,         }, // 275\n    {Y2,            Y3^X7,         X2^Y8,         X3^Y7,         }, // 276\n    {Y3,            X6,            Y6^X10,        Y7^X9,         }, // 277\n    {Y2,            X3,            Y3^X9,         Y6^X8,         }, // 278\n    {Y1,            Y2,            Y3^X7,         X2^Y8,         }, // 279\n    {X6^Y6,         Y3,            X6,            Y7^X9,         }, // 280\n    {X6^Y6,         Y2,            X3,            Y3^X8,         }, // 281\n    {X6^Y6,         X2,            Y2,            Y3^X7,         }, // 282\n    {X6^Y6,         Y1,            Y2,            Y3^X6,         }, // 283\n    {Y3,            X6,            Y7^X9,         X7^Y9,         }, // 284\n    {Z0^X6^Y6,      Y1,            X2,            Y2^X7,         }, // 285\n    {X6^Y6,         X6^Y8,         Y2,            X3,            }, // 286\n    {Z0^X6^Y6,      X3^Y8,         Y1,            X2,            }, // 287\n    {Y6^X7,         Y3,            X7,            Y7^X9,         }, // 288\n    {Y6^X7,         Y2,            X3,            Y3^X8,         }, // 289\n    {Z0^Y6^X7,      X2,            Y2,            Y3^X7,         }, // 290\n    {Z0^Y6^X7,      X2,            X3,            Y3^X8,         }, // 291\n    {Y6^X7,         X6^Y7,         Y2,            X3,            }, // 292\n    {Z0^Y6^X7,      Z4^X6^Y7,      X2,            Y2,            }, // 293\n    {Z0^Y6^X7,      Y1^X6^Y7,      X2,            X3,            }, // 294\n    {Y3^X5,         X4^Y6,         Y4,            X5,            }, // 295\n    {X3^Y6,         Y3^X5,         X4,            Y4,            }, // 296\n    {X3^Y7,         Y3^X6,         X5^Y6,         Y4,            }, // 297\n    {X2^Y7,         Y3^X5,         X3^Y6,         Y4,            }, // 298\n    {Y2^X7,         X3^Y7,         Y3^X6,         X5^Y6,         }, // 299\n    {Y2^X6,         X2^Y7,         Y3^X5,         X3^Y6,         }, // 300\n    {X2,            Y2^X8,         X3^Y7,         Y3^X7,         }, // 301\n    {Y1,            Y2^X6,         X2^Y7,         Y3^X5,         }, // 302\n    {X2^Y7,         Y2^X6,         X3^Y6,         Y3^X5,         }, // 303\n    {X2,            Y2^X7,         X3^Y7,         Y3^X6,         }, // 304\n    {Y1,            X2^Y7,         Y2^X6,         X3^Y6,         }, // 305\n    {Y1,            X2,            Y2^X8,         X3^Y7,         }, // 306\n    {X1,            Y1,            X2^Y7,         Y2^X7,         }, // 307\n    {Y1,            Y2^X7,         X2^Y7,         Y3^X6,         }, // 308\n    {X1,            Y1,            Y2^X7,         X2^Y7,         }, // 309\n    {X6^Y6,         Y1,            X2,            Y2^X8,         }, // 310\n    {X3^Y6,         X1,            Y1,            Y2^X7,         }, // 311\n    {Y1,            X2,            Y2^X8,         Y3^X7,         }, // 312\n    {X2,            Y2,            Y3^X7,         X3^Y8,         }, // 313\n    {X6^Y6,         X2,            Y2,            X3^Y8,         }, // 314\n    {Z3^X6^Y6,      Y1,            X2,            Y2^X8,         }, // 315\n    {Y1^X6^Y6,      X2,            Y2,            Y3^X7,         }, // 316\n    {X6^Y6,         X6^Y8,         X2,            Y2,            }, // 317\n    {Z3^X6^Y6,      X3^Y8,         Y1,            X2,            }, // 318\n    {Y1^X6^Y6,      X1^X6^Y8,      X2,            Y2,            }, // 319\n    {Y6^X7,         X2,            Y2,            Y3^X7,         }, // 320\n    {Y1^Y6^X7,      X2,            X3,            Y3^X8,         }, // 321\n    {Y1^Y6^X7,      X3,            Y3,            X2^Y7^X8,      }, // 322\n    {Y6^X7,         X6^Y7,         X2,            Y2,            }, // 323\n    {Y1^Y6^X7,      Z3^X6^Y7,      X2,            X3,            }, // 324\n    {Y1^Y6^X7,      X1^X6^Y7,      X3,            Y3,            }, // 325\n    {X2^Y6,         Y3^X5,         X3,            Y4,            }, // 326\n    {X1^Y7,         Y3^X5,         X2^Y6,         Y4,            }, // 327\n    {Y2^X6,         X1^Y7,         Y3^X5,         X2^Y6,         }, // 328\n    {Y1,            Y2^X6,         X1^Y7,         Y3^X5,         }, // 329\n    {Y1^X7,         Y2^X6,         X2^Y6,         Y3^X5,         }, // 330\n    {X1,            Y1^X7,         Y2^X6,         X2^Y6,         }, // 331\n    {X1,            Y1,            X2^Y8,         Y2^X6,         }, // 332\n    {Y0,            X1,            Y1^X7,         Y2^X6,         }, // 333\n    {X2,            Y2^X8,         Y3^X7,         X3^Y7,         }, // 334\n    {X1,            X2,            Y2^X8,         Y3^X7,         }, // 335\n    {Y1^X6^Y6,      X1,            X2,            Y2^X7,         }, // 336\n    {X2,            X3,            Y3^X8,         Y2^X7^Y7,      }, // 337\n    {X6^Y6,         Y1,            X2,            Y2^X7,         }, // 338\n    {Y1^X6^Y6,      X2,            X3,            Y3^X8,         }, // 339\n    {X6^Y6,         Y2^X6^Y8,      Y1,            X2,            }, // 340\n    {Y1^X6^Y6,      X2^X6^Y8,      Y2,            X3,            }, // 341\n    {Y1^X6^Y6,      Y3^X8,         X2,            X3,            }, // 342\n    {Y6^X7,         X2,            X3,            Y3^X8,         }, // 343\n    {Y1^Y6^X7,      X3,            Y2,            Y3^X8^Y8,      }, // 344\n    {Y6^X7,         Y2^X6^Y7,      X2,            X3,            }, // 345\n    {Y1^Y6^X7,      X1^X6^Y7,      X3,            Y2,            }, // 346\n    {X4,            Z4,            Y4,            X5,            }, // 347\n    {X3,            Z4,            Y4,            X4,            }, // 348\n    {X3,            Z3,            Y4,            X4,            }, // 349\n    {X3,            Z3,            Y3,            X4,            }, // 350\n    {X2,            Z3,            Y3,            X3,            }, // 351\n    {X4^Y4^Z4,      Z4,            Y4,            X5,            }, // 352\n    {X3^Y4^Z4,      Z4,            Y4,            X4,            }, // 353\n    {X3^Z3^Y4,      Z3,            Y4,            X4,            }, // 354\n    {X3^Y3^Z3,      Z3,            Y3,            X4,            }, // 355\n    {X2^Y3^Z3,      Z3,            Y3,            X3,            }, // 356\n    {X4^Y5^Z5,      Y4^Z4^X5,      Y4,            X5,            }, // 357\n    {X3^Y5^Z5,      X4^Y4^Z4,      Y4,            X4,            }, // 358\n    {X3^Z4^Y5,      Z3^X4^Y4,      Y4,            X4,            }, // 359\n    {X3^Y4^Z4,      Y3^Z3^X4,      Y3,            X4,            }, // 360\n    {X2^Y4^Z4,      X3^Y3^Z3,      Y3,            X3,            }, // 361\n    {X4,            Y4^Z4^X5,      Y4,            X5,            }, // 362\n    {X3,            X4^Y4^Z4,      Y4,            X4,            }, // 363\n    {X3,            Z3^X4^Y4,      Y4,            X4,            }, // 364\n    {X3,            Y3^Z3^X4,      Y3,            X4,            }, // 365\n    {X2,            X3^Y3^Z3,      Y3,            X3,            }, // 366\n    {X3,            Z4,            Y4,            X5,            }, // 367\n    {X2,            Z4,            Y4,            X3,            }, // 368\n    {X2,            Z3,            Y4,            X3,            }, // 369\n    {Y3,            X3,            Z4,            X5,            }, // 370\n    {Y3,            X2,            Z4,            X3,            }, // 371\n    {Y3,            X2,            Z3,            X3,            }, // 372\n    {Y2,            X2,            Y3,            X3,            }, // 373\n    {Z3,            X3,            Z4,            X5^Y5,         }, // 374\n    {X2,            Z4,            X3,            Y2^X5^Y5,      }, // 375\n    {X2,            Z3,            X3,            Y2^X5^Y5,      }, // 376\n    {X2,            Y3,            X3,            Y1^X5^Y5,      }, // 377\n    {X2,            Y3,            X3,            X1^X5^Y5,      }, // 378\n    {Y3,            Z3,            X3,            Z4,            }, // 379\n    {Y2,            Y3,            X3,            Z4,            }, // 380\n    {Z3,            X3,            Z4,            X5^Y6,         }, // 381\n    {X2,            Z4,            X3,            Z3^X5^Y6,      }, // 382\n    {X2,            Z3,            X3,            Z2^X5^Y6,      }, // 383\n    {X2,            Y3,            X3,            Z2^X5^Y6,      }, // 384\n    {Z3^X7,         Y3,            X3,            Z4,            }, // 385\n    {Z3^X7,         X2,            Z4,            X3,            }, // 386\n    {Z2^X7,         X2,            Z3,            X3,            }, // 387\n    {Z2^X7,         X2,            Y3,            X3,            }, // 388\n    {Z3,            X3,            Z4,            Y3^X6^Y6,      }, // 389\n    {X2,            Z4,            X3,            Y3^X6^Y6,      }, // 390\n    {X2,            Z3,            X3,            Y3^X6^Y6,      }, // 391\n    {X2,            Y3,            X3,            Y2^X6^Y6,      }, // 392\n    {Y3^X6^Y6,      Z3,            X3,            Z4,            }, // 393\n    {Y3^X6^Y6,      X2,            Z4,            X3,            }, // 394\n    {Y3^X6^Y6,      X2,            Z3,            X3,            }, // 395\n    {Y2^X6^Y6,      X2,            Y3,            X3,            }, // 396\n    {Y3^X6^Y6,      Z3^X8,         X3,            Z4,            }, // 397\n    {X2^X6^Y6,      Z3^X8,         Z4,            X3,            }, // 398\n    {X2^X6^Y6,      Z2^X8,         Z3,            X3,            }, // 399\n    {X2^X6^Y6,      Z2^X8,         Y3,            X3,            }, // 400\n    {Y3^Y6^X7,      X3,            Z4,            Z3^X6^Y7,      }, // 401\n    {Y3^Y6^X7,      Z4,            X3,            X2^X6^Y7,      }, // 402\n    {Y3^Y6^X7,      Z3,            X3,            X2^X6^Y7,      }, // 403\n    {Y2^Y6^X7,      Y3,            X3,            X2^X6^Y7,      }, // 404\n    {Y3^Y6^X7,      Z3^X6^Y7,      X3,            Z4,            }, // 405\n    {Y3^Y6^X7,      X2^X6^Y7,      Z4,            X3,            }, // 406\n    {Y3^Y6^X7,      X2^X6^Y7,      Z3,            X3,            }, // 407\n    {Y2^Y6^X7,      X2^X6^Y7,      Y3,            X3,            }, // 408\n};\n\nconst UINT_64 GFX11_SW_PATTERN_NIBBLE4[][4] =\n{\n    {0,             0,             0,             0,             }, // 0\n    {Y8,            X8,            0,             0,             }, // 1\n    {Y7,            X8,            0,             0,             }, // 2\n    {Y7,            X7,            0,             0,             }, // 3\n    {Y6,            X7,            0,             0,             }, // 4\n    {Y6,            X6,            0,             0,             }, // 5\n    {X8,            Y8,            0,             0,             }, // 6\n    {X7,            Y7,            0,             0,             }, // 7\n    {X6,            Y6,            0,             0,             }, // 8\n    {X8,            Y7,            0,             0,             }, // 9\n    {X7,            Y6,            0,             0,             }, // 10\n    {X8^Y8,         Y8,            0,             0,             }, // 11\n    {Y7^X8,         Y7,            0,             0,             }, // 12\n    {X7^Y7,         Y7,            0,             0,             }, // 13\n    {Y6^X7,         Y6,            0,             0,             }, // 14\n    {X6^Y6,         Y6,            0,             0,             }, // 15\n    {Y8,            Z0^X5^Y5,      0,             0,             }, // 16\n    {X8,            Z0^X5^Y5,      0,             0,             }, // 17\n    {Y7,            Z0^X5^Y5,      0,             0,             }, // 18\n    {X7,            Z0^X5^Y5,      0,             0,             }, // 19\n    {Y6,            Z0^X5^Y5,      0,             0,             }, // 20\n    {Y7^X8,         X8,            0,             0,             }, // 21\n    {Y6^X7,         X7,            0,             0,             }, // 22\n    {X8^Y9,         Y8^X9,         0,             0,             }, // 23\n    {Y7^X9,         X8^Y8,         0,             0,             }, // 24\n    {X7^Y8,         Y7^X8,         0,             0,             }, // 25\n    {Y6^X8,         X7^Y7,         0,             0,             }, // 26\n    {X6^Y7,         Y6^X7,         0,             0,             }, // 27\n    {Y8^X9,         X5^Y6,         0,             0,             }, // 28\n    {Y7^X9,         X5^Y6,         0,             0,             }, // 29\n    {Y7^X8,         X5^Y6,         0,             0,             }, // 30\n    {Y6^X8,         Z0^X5^Y6,      0,             0,             }, // 31\n    {Y6^X7,         Z0^X5^Y6,      0,             0,             }, // 32\n    {X8^Y8,         Y7^X9,         0,             0,             }, // 33\n    {X7^Y7,         Y6^X8,         0,             0,             }, // 34\n    {X3^Y7,         Y6^X7,         0,             0,             }, // 35\n    {Y8^X9,         X6^Y6,         0,             0,             }, // 36\n    {X8^Y8,         X6^Y6,         0,             0,             }, // 37\n    {Y7^X8,         X6^Y6,         0,             0,             }, // 38\n    {X7^Y7,         Z0^X6^Y6,      0,             0,             }, // 39\n    {X6^Y7,         Z0^X6^Y6,      0,             0,             }, // 40\n    {X6^Y8,         X7^Y7,         0,             0,             }, // 41\n    {Y3^X7,         X6^Y7,         0,             0,             }, // 42\n    {Y3^X8,         X7^Y7,         0,             0,             }, // 43\n    {X3^Y7,         Y3^X7,         0,             0,             }, // 44\n    {Y8^X9,         X6^Y7,         0,             0,             }, // 45\n    {Y7^X9,         X6^Y7,         0,             0,             }, // 46\n    {Y7^X8,         X6^Y7,         0,             0,             }, // 47\n    {X7^Y7,         Z0^X6^Y7,      0,             0,             }, // 48\n    {X3^Y7,         Z0^X6^Y7,      0,             0,             }, // 49\n    {Y3^X7,         X3^Y7,         0,             0,             }, // 50\n    {X7,            Y8,            0,             0,             }, // 51\n    {X6,            Y7,            0,             0,             }, // 52\n    {X5,            Y6,            0,             0,             }, // 53\n    {X7^Y8,         Y8,            0,             0,             }, // 54\n    {X6^Y7,         Y7,            0,             0,             }, // 55\n    {X5^Y6,         Y6,            0,             0,             }, // 56\n    {X7^Y9,         X8^Y8,         0,             0,             }, // 57\n    {X5^Y8,         X6^Y7,         0,             0,             }, // 58\n    {X3^Y8,         X5^Y7,         0,             0,             }, // 59\n    {X8^Y8,         X5^Y6,         0,             0,             }, // 60\n    {X7^Y7,         X5^Y6,         0,             0,             }, // 61\n    {X6^Y6,         Z0^X5^Y6,      0,             0,             }, // 62\n    {X3^Y7,         X6^Y6,         0,             0,             }, // 63\n    {X3^Y8,         X6^Y7,         0,             0,             }, // 64\n    {X2^Y8,         X3^Y7,         0,             0,             }, // 65\n    {X7^Y7,         X6^Y6,         0,             0,             }, // 66\n    {X3^Y7,         Z0^X6^Y6,      0,             0,             }, // 67\n    {Y3^X6,         X3^Y7,         0,             0,             }, // 68\n    {Y2^X7,         Y3^X6,         0,             0,             }, // 69\n    {X8^Y8,         X6^Y7,         0,             0,             }, // 70\n    {X7^Y7,         X6^Y7,         0,             0,             }, // 71\n    {X3^Y7,         Z4^X6^Y7,      0,             0,             }, // 72\n    {Y2^X7^Y7,      Y1^X6^Y7,      0,             0,             }, // 73\n    {Y3^X8,         Y2^X7^Y7,      0,             0,             }, // 74\n    {Y5,            X6,            0,             0,             }, // 75\n    {X5,            Y5,            0,             0,             }, // 76\n    {X6,            Y5,            0,             0,             }, // 77\n    {X6^Y6,         Y5,            0,             0,             }, // 78\n    {X3^Y6,         Y5,            0,             0,             }, // 79\n    {X6,            Z0^X5^Y5,      0,             0,             }, // 80\n    {X5,            Z0^X5^Y5,      0,             0,             }, // 81\n    {X5^Y6,         X6,            0,             0,             }, // 82\n    {Y3^X5,         X5,            0,             0,             }, // 83\n    {Y3^X7,         X6^Y6,         0,             0,             }, // 84\n    {X3^Y6,         Y3^X6,         0,             0,             }, // 85\n    {Y6^X8,         X5^Y6,         0,             0,             }, // 86\n    {Y6^X7,         X5^Y6,         0,             0,             }, // 87\n    {X3^Y6,         Z0^X5^Y6,      0,             0,             }, // 88\n    {Y3^X6,         X3^Y6,         0,             0,             }, // 89\n    {X3^Y6,         Y3^X7,         0,             0,             }, // 90\n    {X2^Y6,         Y3^X6,         0,             0,             }, // 91\n    {X6^Y7,         X6^Y6,         0,             0,             }, // 92\n    {X3^Y6,         Z3^X6^Y6,      0,             0,             }, // 93\n    {X1^X6^Y7,      Y1^X6^Y6,      0,             0,             }, // 94\n    {Y3^X7,         X3^Y6,         0,             0,             }, // 95\n    {X3^Y8,         X1^X6^Y7,      0,             0,             }, // 96\n    {Y2^X8,         Y3^X7,         0,             0,             }, // 97\n    {X3^Y7,         X6^Y7,         0,             0,             }, // 98\n    {Y2^X7^Y7,      Z3^X6^Y7,      0,             0,             }, // 99\n    {Y2^X7^Y8,      X1^X6^Y7,      0,             0,             }, // 100\n    {X2^Y7^X8,      Y2^X7^Y8,      0,             0,             }, // 101\n    {X4,            Y5,            0,             0,             }, // 102\n    {X3,            Y5,            0,             0,             }, // 103\n    {X3^Y6,         X5,            0,             0,             }, // 104\n    {X2^Y6,         X3,            0,             0,             }, // 105\n    {X3,            Z0^X5^Y5,      0,             0,             }, // 106\n    {Y3^X5,         X3,            0,             0,             }, // 107\n    {X3^Y7,         X5^Y6,         0,             0,             }, // 108\n    {X2^Y6,         Y3^X5,         0,             0,             }, // 109\n    {X6^Y6,         X5^Y6,         0,             0,             }, // 110\n    {X3^Y6,         Z2^X5^Y6,      0,             0,             }, // 111\n    {Y1^X6^Y6,      Y0^X5^Y6,      0,             0,             }, // 112\n    {X3^Y7,         Y1^X6^Y6,      0,             0,             }, // 113\n    {X1^X6^Y8,      Y1^X6^Y6,      0,             0,             }, // 114\n    {Y2^X7^Y7,      X1^X6^Y8,      0,             0,             }, // 115\n    {Y3^X7,         X1^X6^Y7,      0,             0,             }, // 116\n    {Y1^X7^Y7,      Y2^X6^Y7,      0,             0,             }, // 117\n    {X2^Y7^X9,      X1^X6^Y7,      0,             0,             }, // 118\n    {Y3^X8,         Y1^X7^Y7,      0,             0,             }, // 119\n    {Y3^X8^Y8,      X2^Y7^X9,      0,             0,             }, // 120\n    {Z5,            Y5,            0,             0,             }, // 121\n    {Z4,            Y5,            0,             0,             }, // 122\n    {Z4,            Y4,            0,             0,             }, // 123\n};\n\nconst UINT_8 GFX11_DCC_64K_R_X_PATIDX[] =\n{\n       0, // 1 bpe ua @ SW_64K_{Z,R}_X 1xaa\n       1, // 2 bpe ua @ SW_64K_{Z,R}_X 1xaa\n       2, // 4 bpe ua @ SW_64K_{Z,R}_X 1xaa\n       3, // 8 bpe ua @ SW_64K_{Z,R}_X 1xaa\n       4, // 16 bpe ua @ SW_64K_{Z,R}_X 1xaa\n       0, // 1 pipes (1 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       1, // 1 pipes (1 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       2, // 1 pipes (1 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       3, // 1 pipes (1 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       4, // 1 pipes (1 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       5, // 2 pipes (1-2 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       6, // 2 pipes (1-2 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       7, // 2 pipes (1-2 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       8, // 2 pipes (1-2 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n       9, // 2 pipes (1-2 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      10, // 4 pipes (1-2 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      11, // 4 pipes (1-2 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      12, // 4 pipes (1-2 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      13, // 4 pipes (1-2 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      14, // 4 pipes (1-2 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      15, // 8 pipes (2 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      16, // 8 pipes (2 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      17, // 8 pipes (2 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      18, // 8 pipes (2 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      19, // 8 pipes (2 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      20, // 4 pipes (4 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      21, // 4 pipes (4 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      22, // 4 pipes (4 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      23, // 4 pipes (4 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      24, // 4 pipes (4 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      25, // 8 pipes (4 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      26, // 8 pipes (4 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      27, // 8 pipes (4 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      28, // 8 pipes (4 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      29, // 8 pipes (4 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      30, // 16 pipes (4 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      31, // 16 pipes (4 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      32, // 16 pipes (4 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      33, // 16 pipes (4 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      34, // 16 pipes (4 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      35, // 8 pipes (8 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      36, // 8 pipes (8 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      37, // 8 pipes (8 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      38, // 8 pipes (8 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      39, // 8 pipes (8 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      35, // 16 pipes (8 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      36, // 16 pipes (8 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      37, // 16 pipes (8 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      40, // 16 pipes (8 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      41, // 16 pipes (8 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      42, // 32 pipes (8 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      43, // 32 pipes (8 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      44, // 32 pipes (8 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      45, // 32 pipes (8 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      46, // 32 pipes (8 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      47, // 16 pipes (16 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      48, // 16 pipes (16 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      49, // 16 pipes (16 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      50, // 16 pipes (16 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      51, // 16 pipes (16 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      47, // 32 pipes (16 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      48, // 32 pipes (16 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      49, // 32 pipes (16 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      52, // 32 pipes (16 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      53, // 32 pipes (16 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      54, // 64 pipes (16 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      55, // 64 pipes (16 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      56, // 64 pipes (16 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      57, // 64 pipes (16 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      58, // 64 pipes (16 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      59, // 32 pipes (32 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      60, // 32 pipes (32 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      61, // 32 pipes (32 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      62, // 32 pipes (32 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      63, // 32 pipes (32 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      59, // 64 pipes (32 PKRs) 1 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      60, // 64 pipes (32 PKRs) 2 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      61, // 64 pipes (32 PKRs) 4 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      64, // 64 pipes (32 PKRs) 8 bpe pa @ SW_64K_{Z,R}_X 1xaa\n      65, // 64 pipes (32 PKRs) 16 bpe pa @ SW_64K_{Z,R}_X 1xaa\n};\n\nconst UINT_8 GFX11_DCC_256K_R_X_PATIDX[] =\n{\n       0, // 1 bpe ua @ SW_256K_{Z,R}_X 1xaa\n       1, // 2 bpe ua @ SW_256K_{Z,R}_X 1xaa\n       2, // 4 bpe ua @ SW_256K_{Z,R}_X 1xaa\n       3, // 8 bpe ua @ SW_256K_{Z,R}_X 1xaa\n       4, // 16 bpe ua @ SW_256K_{Z,R}_X 1xaa\n       0, // 1 pipes (1 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       1, // 1 pipes (1 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       2, // 1 pipes (1 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       3, // 1 pipes (1 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       4, // 1 pipes (1 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       5, // 2 pipes (1-2 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       6, // 2 pipes (1-2 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       7, // 2 pipes (1-2 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       8, // 2 pipes (1-2 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n       9, // 2 pipes (1-2 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      10, // 4 pipes (1-2 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      11, // 4 pipes (1-2 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      12, // 4 pipes (1-2 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      13, // 4 pipes (1-2 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      14, // 4 pipes (1-2 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      15, // 8 pipes (2 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      16, // 8 pipes (2 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      17, // 8 pipes (2 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      18, // 8 pipes (2 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      19, // 8 pipes (2 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      20, // 4 pipes (4 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      21, // 4 pipes (4 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      22, // 4 pipes (4 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      23, // 4 pipes (4 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      24, // 4 pipes (4 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      25, // 8 pipes (4 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      26, // 8 pipes (4 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      27, // 8 pipes (4 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      28, // 8 pipes (4 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      29, // 8 pipes (4 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      30, // 16 pipes (4 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      31, // 16 pipes (4 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      32, // 16 pipes (4 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      33, // 16 pipes (4 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      34, // 16 pipes (4 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      35, // 8 pipes (8 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      36, // 8 pipes (8 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      37, // 8 pipes (8 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      38, // 8 pipes (8 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      39, // 8 pipes (8 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      35, // 16 pipes (8 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      36, // 16 pipes (8 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      37, // 16 pipes (8 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      40, // 16 pipes (8 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      41, // 16 pipes (8 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      42, // 32 pipes (8 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      43, // 32 pipes (8 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      44, // 32 pipes (8 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      45, // 32 pipes (8 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      66, // 32 pipes (8 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      47, // 16 pipes (16 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      48, // 16 pipes (16 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      49, // 16 pipes (16 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      50, // 16 pipes (16 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      67, // 16 pipes (16 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      47, // 32 pipes (16 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      48, // 32 pipes (16 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      49, // 32 pipes (16 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      52, // 32 pipes (16 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      68, // 32 pipes (16 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      54, // 64 pipes (16 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      55, // 64 pipes (16 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      56, // 64 pipes (16 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      69, // 64 pipes (16 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      70, // 64 pipes (16 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      59, // 32 pipes (32 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      60, // 32 pipes (32 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      61, // 32 pipes (32 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      71, // 32 pipes (32 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      72, // 32 pipes (32 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      59, // 64 pipes (32 PKRs) 1 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      60, // 64 pipes (32 PKRs) 2 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      61, // 64 pipes (32 PKRs) 4 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      73, // 64 pipes (32 PKRs) 8 bpe pa @ SW_256K_{Z,R}_X 1xaa\n      74, // 64 pipes (32 PKRs) 16 bpe pa @ SW_256K_{Z,R}_X 1xaa\n};\n\nconst UINT_8 GFX11_HTILE_PATIDX[] =\n{\n       0, // 1xaa ua @ HTILE_64K\n       0, // 2xaa ua @ HTILE_64K\n       0, // 4xaa ua @ HTILE_64K\n       0, // 8xaa ua @ HTILE_64K\n       0, // 1 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K\n       0, // 1 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K\n       0, // 1 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K\n       0, // 1 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K\n       1, // 2 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K\n       1, // 2 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K\n       1, // 2 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K\n       1, // 2 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K\n       2, // 4 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K\n       2, // 4 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K\n       2, // 4 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K\n       2, // 4 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K\n       3, // 8 pipes (1-2 PKRs) 1xaa pa @ HTILE_64K\n       3, // 8 pipes (1-2 PKRs) 2xaa pa @ HTILE_64K\n       3, // 8 pipes (1-2 PKRs) 4xaa pa @ HTILE_64K\n       3, // 8 pipes (1-2 PKRs) 8xaa pa @ HTILE_64K\n       1, // 2 pipes (4 PKRs) 1xaa pa @ HTILE_64K\n       1, // 2 pipes (4 PKRs) 2xaa pa @ HTILE_64K\n       1, // 2 pipes (4 PKRs) 4xaa pa @ HTILE_64K\n       1, // 2 pipes (4 PKRs) 8xaa pa @ HTILE_64K\n       4, // 4 pipes (4 PKRs) 1xaa pa @ HTILE_64K\n       4, // 4 pipes (4 PKRs) 2xaa pa @ HTILE_64K\n       4, // 4 pipes (4 PKRs) 4xaa pa @ HTILE_64K\n       4, // 4 pipes (4 PKRs) 8xaa pa @ HTILE_64K\n       5, // 8 pipes (4 PKRs) 1xaa pa @ HTILE_64K\n       5, // 8 pipes (4 PKRs) 2xaa pa @ HTILE_64K\n       5, // 8 pipes (4 PKRs) 4xaa pa @ HTILE_64K\n       5, // 8 pipes (4 PKRs) 8xaa pa @ HTILE_64K\n       6, // 16 pipes (4 PKRs) 1xaa pa @ HTILE_64K\n       6, // 16 pipes (4 PKRs) 2xaa pa @ HTILE_64K\n       6, // 16 pipes (4 PKRs) 4xaa pa @ HTILE_64K\n       6, // 16 pipes (4 PKRs) 8xaa pa @ HTILE_64K\n       7, // 4 pipes (8 PKRs) 1xaa pa @ HTILE_64K\n       7, // 4 pipes (8 PKRs) 2xaa pa @ HTILE_64K\n       7, // 4 pipes (8 PKRs) 4xaa pa @ HTILE_64K\n       7, // 4 pipes (8 PKRs) 8xaa pa @ HTILE_64K\n       8, // 8 pipes (8 PKRs) 1xaa pa @ HTILE_64K\n       8, // 8 pipes (8 PKRs) 2xaa pa @ HTILE_64K\n       8, // 8 pipes (8 PKRs) 4xaa pa @ HTILE_64K\n       8, // 8 pipes (8 PKRs) 8xaa pa @ HTILE_64K\n       9, // 16 pipes (8 PKRs) 1xaa pa @ HTILE_64K\n       9, // 16 pipes (8 PKRs) 2xaa pa @ HTILE_64K\n       9, // 16 pipes (8 PKRs) 4xaa pa @ HTILE_64K\n       9, // 16 pipes (8 PKRs) 8xaa pa @ HTILE_64K\n      10, // 32 pipes (8 PKRs) 1xaa pa @ HTILE_64K\n      10, // 32 pipes (8 PKRs) 2xaa pa @ HTILE_64K\n      10, // 32 pipes (8 PKRs) 4xaa pa @ HTILE_64K\n      10, // 32 pipes (8 PKRs) 8xaa pa @ HTILE_64K\n      11, // 8 pipes (16 PKRs) 1xaa pa @ HTILE_64K\n      11, // 8 pipes (16 PKRs) 2xaa pa @ HTILE_64K\n      11, // 8 pipes (16 PKRs) 4xaa pa @ HTILE_64K\n      11, // 8 pipes (16 PKRs) 8xaa pa @ HTILE_64K\n      12, // 16 pipes (16 PKRs) 1xaa pa @ HTILE_64K\n      12, // 16 pipes (16 PKRs) 2xaa pa @ HTILE_64K\n      12, // 16 pipes (16 PKRs) 4xaa pa @ HTILE_64K\n      12, // 16 pipes (16 PKRs) 8xaa pa @ HTILE_64K\n      13, // 32 pipes (16 PKRs) 1xaa pa @ HTILE_64K\n      13, // 32 pipes (16 PKRs) 2xaa pa @ HTILE_64K\n      13, // 32 pipes (16 PKRs) 4xaa pa @ HTILE_64K\n      13, // 32 pipes (16 PKRs) 8xaa pa @ HTILE_64K\n      14, // 64 pipes (16 PKRs) 1xaa pa @ HTILE_64K\n      14, // 64 pipes (16 PKRs) 2xaa pa @ HTILE_64K\n      14, // 64 pipes (16 PKRs) 4xaa pa @ HTILE_64K\n      14, // 64 pipes (16 PKRs) 8xaa pa @ HTILE_64K\n      15, // 16 pipes (32 PKRs) 1xaa pa @ HTILE_64K\n      15, // 16 pipes (32 PKRs) 2xaa pa @ HTILE_64K\n      15, // 16 pipes (32 PKRs) 4xaa pa @ HTILE_64K\n      15, // 16 pipes (32 PKRs) 8xaa pa @ HTILE_64K\n      16, // 32 pipes (32 PKRs) 1xaa pa @ HTILE_64K\n      16, // 32 pipes (32 PKRs) 2xaa pa @ HTILE_64K\n      16, // 32 pipes (32 PKRs) 4xaa pa @ HTILE_64K\n      16, // 32 pipes (32 PKRs) 8xaa pa @ HTILE_64K\n      17, // 64 pipes (32 PKRs) 1xaa pa @ HTILE_64K\n      17, // 64 pipes (32 PKRs) 2xaa pa @ HTILE_64K\n      17, // 64 pipes (32 PKRs) 4xaa pa @ HTILE_64K\n      17, // 64 pipes (32 PKRs) 8xaa pa @ HTILE_64K\n};\n\nconst UINT_64 GFX11_DCC_R_X_SW_PATTERN[][17] =\n{\n    {0,             X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            0,             0,             0,             0,             }, //0\n    {0,             Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            0,             0,             0,             0,             }, //1\n    {0,             X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            0,             0,             0,             0,             }, //2\n    {0,             Y2,            X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            0,             0,             0,             0,             }, //3\n    {0,             X2,            Y2,            X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            0,             0,             0,             0,             }, //4\n    {0,             Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Z0^X4^Y4,      Y8,            X9,            Y9,            0,             0,             0,             0,             }, //5\n    {0,             Y3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Z0^X4^Y4,      X8,            Y8,            X9,            0,             0,             0,             0,             }, //6\n    {0,             X3,            Y3,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Z0^X4^Y4,      Y7,            X8,            Y8,            0,             0,             0,             0,             }, //7\n    {0,             Y2,            X3,            Y3,            Y4,            X5,            Y5,            X6,            Y6,            Z0^X4^Y4,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //8\n    {0,             X2,            Y2,            X3,            Y3,            Y4,            X5,            Y5,            X6,            Z0^X4^Y4,      Y6,            X7,            Y7,            0,             0,             0,             0,             }, //9\n    {0,             X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X5^Y5,      Z0^X4^Y4,      X9,            Y9,            0,             0,             0,             0,             }, //10\n    {0,             Y3,            X5,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X5^Y5,      Z0^X4^Y4,      Y8,            X9,            0,             0,             0,             0,             }, //11\n    {0,             X3,            Y3,            X5,            Y5,            X6,            Y6,            X7,            Y7,            Y4^X5^Y5,      Z0^X4^Y4,      X8,            Y8,            0,             0,             0,             0,             }, //12\n    {0,             Y2,            X3,            Y3,            X5,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      Y7,            X8,            0,             0,             0,             0,             }, //13\n    {0,             X2,            Y2,            X3,            Y3,            X5,            Y5,            X6,            Y6,            Y4^X5^Y5,      Z0^X4^Y4,      X7,            Y7,            0,             0,             0,             0,             }, //14\n    {0,             Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y9,            0,             0,             0,             0,             }, //15\n    {0,             Y3,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X9,            0,             0,             0,             0,             }, //16\n    {0,             X3,            Y3,            Y5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y8,            0,             0,             0,             0,             }, //17\n    {0,             Y2,            X3,            Y3,            Y5,            X6,            Y6,            X7,            Y7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         X8,            0,             0,             0,             0,             }, //18\n    {0,             X2,            Y2,            X3,            Y3,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y7,            0,             0,             0,             0,             }, //19\n    {0,             X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y9,            0,             0,             0,             0,             }, //20\n    {0,             Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         X9,            0,             0,             0,             0,             }, //21\n    {0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y8,            0,             0,             0,             0,             }, //22\n    {0,             Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         X8,            0,             0,             0,             0,             }, //23\n    {0,             X2,            Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      X5^Y5,         Y7,            0,             0,             0,             0,             }, //24\n    {0,             X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y9,            0,             0,             0,             0,             }, //25\n    {0,             Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X9,            0,             0,             0,             0,             }, //26\n    {0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y8,            0,             0,             0,             0,             }, //27\n    {0,             Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X8,            0,             0,             0,             0,             }, //28\n    {0,             X2,            Y2,            X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            0,             0,             0,             0,             }, //29\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //30\n    {0,             Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //31\n    {0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //32\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //33\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         0,             0,             0,             0,             }, //34\n    {0,             X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //35\n    {0,             Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //36\n    {0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //37\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //38\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      X5^Y6,         0,             0,             0,             0,             }, //39\n    {0,             Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //40\n    {0,             X2,            Y2,            X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      0,             0,             0,             0,             }, //41\n    {0,             Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         0,             0,             0,             }, //42\n    {0,             Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         0,             0,             0,             }, //43\n    {0,             X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         0,             0,             0,             }, //44\n    {0,             Y2,            X3,            Y3,            Y6,            X7,            Y7,            X8,            Y8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^Y6,         0,             0,             0,             }, //45\n    {0,             X2,            Y2,            Y3,            X6,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X3^Y6,         0,             0,             0,             }, //46\n    {0,             X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         0,             0,             0,             }, //47\n    {0,             Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         0,             0,             0,             }, //48\n    {0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         0,             0,             0,             }, //49\n    {0,             Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //50\n    {0,             X2,            X3,            Y3,            X6,            X7,            Y7,            Y2,            X8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      X6^Y6,         0,             0,             0,             }, //51\n    {0,             Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //52\n    {0,             X2,            X3,            Y3,            X6,            X7,            Y7,            Y2,            X8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      Y2^X6^Y6,      0,             0,             0,             }, //53\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         0,             0,             }, //54\n    {0,             Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         0,             0,             }, //55\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         0,             0,             }, //56\n    {0,             Y2,            Y3,            X6,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X3^Y8,         0,             0,             }, //57\n    {0,             X2,            Y3,            X6,            X7,            Y7,            X8,            Y2,            Y8,            Y4^X8^Y8,      Z2^X4^Y4,      Z1^Y5^X7,      Z0^X5^Y7,      Y2^X6^Y6,      X3^Y8,         0,             0,             }, //58\n    {0,             X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y10,           Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         0,             0,             }, //59\n    {0,             Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            X10,           Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         0,             0,             }, //60\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y9,            Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         0,             0,             }, //61\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y2,            X9,            Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y2^Y6^X7,      X6^Y7,         0,             0,             }, //62\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X2,            Y2,            Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y2^Y6^X7,      X6^Y7,         0,             0,             }, //63\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y2,            X9,            Y4^X9^Y9,      Z3^X4^Y4,      Z2^Y5^X8,      Z1^X5^Y8,      Y2^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //64\n    {0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            X2,            Y2,            Y4^X9^Y9,      Z2^X4^Y4,      Z1^Y5^X8,      Z0^X5^Y8,      Y2^Y6^X7,      X2^X6^Y7,      0,             0,             }, //65\n    {0,             X2,            Y2,            X3,            Y3,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z2^X4^Y4,      Z1^Y5^X6,      Z0^X5^Y6,      X6^Y6,         0,             0,             0,             }, //66\n    {0,             X2,            Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      X6^Y6,         0,             0,             0,             }, //67\n    {0,             X2,            Y2,            X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      0,             0,             0,             }, //68\n    {0,             Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^Y8,         0,             0,             }, //69\n    {0,             X2,            Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z3^X4^Y4,      Z2^Y5^X7,      Z1^X5^Y7,      Z0^X6^Y6,      X6^Y8,         0,             0,             }, //70\n    {0,             Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //71\n    {0,             X2,            Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      X6^Y7,         0,             0,             }, //72\n    {0,             Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            X9,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //73\n    {0,             X2,            Y2,            X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      X4^Y4^Z4,      Z3^Y5^X8,      Z2^X5^Y8,      Z1^Y6^X7,      Z0^X6^Y7,      0,             0,             }, //74\n};\n\nconst UINT_64 GFX11_HTILE_SW_PATTERN[][18] =\n{\n    {0,             0,             0,             X3,            Y3,            X4,            Y4,            X5,            Y5,            X6,            Y6,            X7,            Y7,            0,             0,             0,             0,             0,             }, //0\n    {0,             0,             0,             X3,            Y3,            Y4,            X5,            Y5,            X6,            Z0^X4^Y4,      Y6,            X7,            Y7,            0,             0,             0,             0,             0,             }, //1\n    {0,             0,             0,             X3,            Y3,            X5,            Y5,            X6,            Y6,            Y4^X5^Y5,      Z0^X4^Y4,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //2\n    {0,             0,             0,             X3,            Y3,            Y5,            X6,            Y6,            X7,            Y4^X5^Y5,      Z0^X4^Y4,      X5^Y5,         Y7,            X8,            Y8,            0,             0,             0,             }, //3\n    {0,             0,             0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Y7,            X8,            Y8,            X5^Y5,         0,             0,             0,             }, //4\n    {0,             0,             0,             X3,            Y3,            X5,            X6,            Y6,            X7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      Y7,            X8,            Y8,            0,             0,             0,             }, //5\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X6^Y6,      Z1^X4^Y4,      Z0^X5^Y5,      X5^Y6,         X8,            Y8,            X9,            0,             0,             }, //6\n    {0,             0,             0,             X3,            Y3,            Y4,            X5,            X6,            Y6,            Z1^X4^Y4,      Z0^X5^Y5,      X7,            Y7,            X8,            0,             0,             0,             0,             }, //7\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X8,            Y8,            X9,            X5^Y6,         0,             0,             }, //8\n    {0,             0,             0,             X3,            Y3,            X6,            Y6,            X7,            Y7,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X8,            Y8,            X9,            0,             0,             }, //9\n    {0,             0,             0,             X3,            Y3,            Y6,            X7,            Y7,            X8,            Y4^X7^Y7,      Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         X6^Y6,         Y8,            X9,            Y9,            0,             }, //10\n    {0,             0,             0,             X3,            Y3,            Y4,            X6,            Y6,            X7,            Z1^X4^Y4,      Z0^Y5^X6,      X5^Y6,         Y7,            X8,            Y8,            0,             0,             0,             }, //11\n    {0,             0,             0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         Y8,            X9,            Y9,            X6^Y6,         0,             }, //12\n    {0,             0,             0,             X3,            Y3,            X6,            X7,            Y7,            X8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         Y8,            X9,            Y9,            0,             }, //13\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X8^Y8,      Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X6^Y8,         X9,            Y9,            X10,           }, //14\n    {0,             0,             0,             X3,            Y3,            Y4,            X6,            X7,            Y7,            Z1^X4^Y4,      Z0^Y5^X7,      X5^Y7,         X6^Y6,         X8,            Y8,            X9,            0,             0,             }, //15\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X9,            Y9,            X10,           X6^Y7,         }, //16\n    {0,             0,             0,             X3,            Y3,            X7,            Y7,            X8,            Y8,            Y4^X9^Y9,      Z1^X4^Y4,      Z0^Y5^X8,      X5^Y8,         Y6^X7,         X6^Y7,         X9,            Y9,            X10,           }, //17\n};\n\n}// V2\n} // Addr\n} // namespace rocr\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx11/gfx11addrlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx11addrlib.cpp\n* @brief Contain the implementation for the Gfx11Lib class.\n************************************************************************************************************************\n*/\n\n#include \"gfx11addrlib.h\"\n#include \"gfx11_gb_reg.h\"\n\n#include \"amdgpu_asic_addr.h\"\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\nnamespace rocr {\nnamespace Addr\n{\n/**\n************************************************************************************************************************\n*   Gfx11HwlInit\n*\n*   @brief\n*       Creates an Gfx11Lib object.\n*\n*   @return\n*       Returns an Gfx11Lib object pointer.\n************************************************************************************************************************\n*/\nAddr::Lib* Gfx11HwlInit(const Client* pClient)\n{\n    return V2::Gfx11Lib::CreateObj(pClient);\n}\n\nnamespace V2\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst SwizzleModeFlags Gfx11Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =\n{//Linear 256B  4KB  64KB  256KB   Z    Std   Disp  Rot   XOR    T     RtOpt Reserved\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_S\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_S\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_D\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_S_T\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_D_T\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_S_X\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_D_X\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    1,    0,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_Z_X\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_S_X\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_D_X\n    {{0,    0,    0,    1,    0,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_64KB_R_X\n\n    {{0,    0,    0,    0,    1,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_Z_X\n    {{0,    0,    0,    0,    1,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_S_X\n    {{0,    0,    0,    0,    1,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_D_X\n    {{0,    0,    0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_256KB_R_X\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR_GENERAL\n};\n\nconst Dim3d Gfx11Lib::Block256_3d[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};\n\nconst Dim3d Gfx11Lib::Block256K_Log2_3d[] = {{6, 6, 6}, {5, 6, 6}, {5, 6, 5}, {5, 5, 5}, {4, 5, 5}};\nconst Dim3d Gfx11Lib::Block64K_Log2_3d[]  = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};\nconst Dim3d Gfx11Lib::Block4K_Log2_3d[]   = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::Gfx11Lib\n*\n*   @brief\n*       Constructor\n*\n************************************************************************************************************************\n*/\nGfx11Lib::Gfx11Lib(const Client* pClient)\n    :\n    Lib(pClient),\n    m_numPkrLog2(0),\n    m_numSaLog2(0),\n    m_colorBaseIndex(0),\n    m_htileBaseIndex(0),\n    m_dccBaseIndex(0)\n{\n    memset(&m_settings, 0, sizeof(m_settings));\n    memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::~Gfx11Lib\n*\n*   @brief\n*       Destructor\n************************************************************************************************************************\n*/\nGfx11Lib::~Gfx11Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeHtileInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeHtilenfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileInfo(\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if ((pIn->swizzleMode != ADDR_SW_64KB_Z_X)  &&\n        (pIn->swizzleMode != ADDR_SW_256KB_Z_X) &&\n        (pIn->hTileFlags.pipeAligned != TRUE))\n    {\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        Dim3d         metaBlk     = {};\n        const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataDepthStencil,\n                                                   ADDR_RSRC_TEX_2D,\n                                                   pIn->swizzleMode,\n                                                   0,\n                                                   0,\n                                                   TRUE,\n                                                   &metaBlk);\n\n        pOut->pitch         = PowTwoAlign(pIn->unalignedWidth,  metaBlk.w);\n        pOut->height        = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);\n        pOut->baseAlign     = Max(metaBlkSize, 1u << (m_pipesLog2 + 11u));\n        pOut->metaBlkWidth  = metaBlk.w;\n        pOut->metaBlkHeight = metaBlk.h;\n\n        if (pIn->numMipLevels > 1)\n        {\n            ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);\n\n            UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >=0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);\n\n                mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);\n                mipHeight = PowTwoAlign(mipHeight, metaBlk.h);\n\n                const UINT_32 pitchInM     = mipWidth  / metaBlk.w;\n                const UINT_32 heightInM    = mipHeight / metaBlk.h;\n                const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].inMiptail = FALSE;\n                    pOut->pMipInfo[i].offset    = offset;\n                    pOut->pMipInfo[i].sliceSize = mipSliceSize;\n                }\n\n                offset += mipSliceSize;\n            }\n\n            pOut->sliceSize          = offset;\n            pOut->metaBlkNumPerSlice = offset / metaBlkSize;\n            pOut->htileBytes         = pOut->sliceSize * pIn->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)\n                {\n                    pOut->pMipInfo[i].inMiptail = TRUE;\n                    pOut->pMipInfo[i].offset    = 0;\n                    pOut->pMipInfo[i].sliceSize = 0;\n                }\n\n                if (pIn->firstMipIdInTail != pIn->numMipLevels)\n                {\n                    pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;\n                }\n            }\n        }\n        else\n        {\n            const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;\n            const UINT_32 heightInM = pOut->height / metaBlk.h;\n\n            pOut->metaBlkNumPerSlice    = pitchInM * heightInM;\n            pOut->sliceSize             = pOut->metaBlkNumPerSlice * metaBlkSize;\n            pOut->htileBytes            = pOut->sliceSize * pIn->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].inMiptail = FALSE;\n                pOut->pMipInfo[0].offset    = 0;\n                pOut->pMipInfo[0].sliceSize = pOut->sliceSize;\n            }\n        }\n\n        // Get the HTILE address equation (copied from HtileAddrFromCoord).\n        // HTILE addressing depends on the number of samples, but this code doesn't support it yet.\n        const UINT_32  index         = m_htileBaseIndex;\n        const UINT_8* patIdxTable = GFX11_HTILE_PATIDX;\n\n        ADDR_C_ASSERT(sizeof(GFX11_HTILE_SW_PATTERN[patIdxTable[index]]) == 72 * 2);\n        pOut->equation.gfx10_bits = (UINT_16 *)GFX11_HTILE_SW_PATTERN[patIdxTable[index]];\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeDccInfo\n*\n*   @brief\n*       Interface function to compute DCC key info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeDccInfo(\n    const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    if (IsLinear(pIn->swizzleMode) || IsBlock256b(pIn->swizzleMode))\n    {\n        ret = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));\n        Dim3d         compBlock   = {};\n\n        GetCompressedBlockSizeLog2(Gfx11DataColor,\n                                   pIn->resourceType,\n                                   pIn->swizzleMode,\n                                   elemLog2,\n                                   numFragLog2,\n                                   &compBlock);\n        pOut->compressBlkWidth  = 1 << compBlock.w;\n        pOut->compressBlkHeight = 1 << compBlock.h;\n        pOut->compressBlkDepth  = 1 << compBlock.d;\n\n        if (ret == ADDR_OK)\n        {\n            Dim3d         metaBlk     = {};\n            const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataColor,\n                                                       pIn->resourceType,\n                                                       pIn->swizzleMode,\n                                                       elemLog2,\n                                                       numFragLog2,\n                                                       pIn->dccKeyFlags.pipeAligned,\n                                                       &metaBlk);\n\n            pOut->dccRamBaseAlign   = metaBlkSize;\n            pOut->metaBlkWidth      = metaBlk.w;\n            pOut->metaBlkHeight     = metaBlk.h;\n            pOut->metaBlkDepth      = metaBlk.d;\n            pOut->metaBlkSize       = metaBlkSize;\n\n            pOut->pitch             = PowTwoAlign(pIn->unalignedWidth,     metaBlk.w);\n            pOut->height            = PowTwoAlign(pIn->unalignedHeight,    metaBlk.h);\n            pOut->depth             = PowTwoAlign(Max(pIn->numSlices, 1u), metaBlk.d);\n\n            if (pIn->numMipLevels > 1)\n            {\n                ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);\n\n                UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;\n\n                for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >= 0; i--)\n                {\n                    UINT_32 mipWidth, mipHeight;\n\n                    GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);\n\n                    mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);\n                    mipHeight = PowTwoAlign(mipHeight, metaBlk.h);\n\n                    const UINT_32 pitchInM     = mipWidth  / metaBlk.w;\n                    const UINT_32 heightInM    = mipHeight / metaBlk.h;\n                    const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;\n\n                    if (pOut->pMipInfo != NULL)\n                    {\n                        pOut->pMipInfo[i].inMiptail = FALSE;\n                        pOut->pMipInfo[i].offset    = offset;\n                        pOut->pMipInfo[i].sliceSize = mipSliceSize;\n                    }\n\n                    offset += mipSliceSize;\n                }\n\n                pOut->dccRamSliceSize    = offset;\n                pOut->metaBlkNumPerSlice = offset / metaBlkSize;\n                pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)\n                    {\n                        pOut->pMipInfo[i].inMiptail = TRUE;\n                        pOut->pMipInfo[i].offset    = 0;\n                        pOut->pMipInfo[i].sliceSize = 0;\n                    }\n\n                    if (pIn->firstMipIdInTail != pIn->numMipLevels)\n                    {\n                        pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;\n                    }\n                }\n            }\n            else\n            {\n                const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;\n                const UINT_32 heightInM = pOut->height / metaBlk.h;\n\n                pOut->metaBlkNumPerSlice = pitchInM * heightInM;\n                pOut->dccRamSliceSize    = pOut->metaBlkNumPerSlice * metaBlkSize;\n                pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].inMiptail = FALSE;\n                    pOut->pMipInfo[0].offset    = 0;\n                    pOut->pMipInfo[0].sliceSize = pOut->dccRamSliceSize;\n                }\n            }\n\n            // Get the DCC address equation (copied from DccAddrFromCoord)\n            const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n            const UINT_32 numPipeLog2 = m_pipesLog2;\n            UINT_32       index       = m_dccBaseIndex + elemLog2;\n            const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?\n                                        GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;\n\n            if (pIn->dccKeyFlags.pipeAligned)\n            {\n                index += MaxNumOfBpp;\n\n                if (m_numPkrLog2 < 2)\n                {\n                    index += m_pipesLog2 * MaxNumOfBpp;\n                }\n                else\n                {\n                    // 4 groups for \"m_numPkrLog2 < 2\" case\n                    index += 4 * MaxNumOfBpp;\n\n                    const UINT_32 dccPipePerPkr = 3;\n\n                    index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +\n                             (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;\n                }\n            }\n\n            ADDR_C_ASSERT(sizeof(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]]) == 68 * 2);\n            pOut->equation.gfx10_bits = (UINT_16*)GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]];\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeHtileAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileAddrFromCoord(\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->numMipLevels > 1)\n    {\n        returnCode = ADDR_NOTIMPLEMENTED;\n    }\n    else\n    {\n        ADDR2_COMPUTE_HTILE_INFO_INPUT input = {};\n        input.size            = sizeof(input);\n        input.hTileFlags      = pIn->hTileFlags;\n        input.depthFlags      = pIn->depthflags;\n        input.swizzleMode     = pIn->swizzleMode;\n        input.unalignedWidth  = Max(pIn->unalignedWidth,  1u);\n        input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n        input.numSlices       = Max(pIn->numSlices,       1u);\n        input.numMipLevels    = 1;\n\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {};\n        output.size = sizeof(output);\n\n        returnCode = ComputeHtileInfo(&input, &output);\n\n        if (returnCode == ADDR_OK)\n        {\n            const UINT_32  numSampleLog2 = Log2(pIn->numSamples);\n            const UINT_32  pipeMask      = (1 << m_pipesLog2) - 1;\n            const UINT_32  index         = m_htileBaseIndex + numSampleLog2;\n            const UINT_8*  patIdxTable   = GFX11_HTILE_PATIDX;\n            const UINT_32  blkSizeLog2   = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 4;\n            const UINT_32  blkMask       = (1 << blkSizeLog2) - 1;\n            const UINT_32  blkOffset     = ComputeOffsetFromSwizzlePattern(GFX11_HTILE_SW_PATTERN[patIdxTable[index]],\n                                                                           blkSizeLog2 + 1, // +1 for nibble offset\n                                                                           pIn->x,\n                                                                           pIn->y,\n                                                                           pIn->slice,\n                                                                           0);\n            const UINT_32 xb       = pIn->x / output.metaBlkWidth;\n            const UINT_32 yb       = pIn->y / output.metaBlkHeight;\n            const UINT_32 pb       = output.pitch / output.metaBlkWidth;\n            const UINT_32 blkIndex = (yb * pb) + xb;\n            const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;\n\n            pOut->addr = (static_cast<UINT_64>(output.sliceSize) * pIn->slice) +\n                         (blkIndex * (1 << blkSizeLog2)) +\n                         ((blkOffset >> 1) ^ pipeXor);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeHtileCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileCoordFromAddr(\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut)   ///< [out] output structure\n{\n    ADDR_NOT_IMPLEMENTED();\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlSupportComputeDccAddrFromCoord\n*\n*   @brief\n*       Check whether HwlComputeDccAddrFromCoord() can be done for the input parameter\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlSupportComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if ((pIn->resourceType != ADDR_RSRC_TEX_2D) ||\n        ((pIn->swizzleMode != ADDR_SW_64KB_R_X) &&\n         (pIn->swizzleMode != ADDR_SW_256KB_R_X)) ||\n        (pIn->dccKeyFlags.linear == TRUE) ||\n        (pIn->numFrags > 1) ||\n        (pIn->numMipLevels > 1) ||\n        (pIn->mipId > 0))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else if ((pIn->pitch == 0)         ||\n             (pIn->metaBlkWidth == 0)  ||\n             (pIn->metaBlkHeight == 0) ||\n             (pIn->slice > 0 && pIn->dccRamSliceSize == 0))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeDccAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeDccAddrFromCoord\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx11Lib::HwlComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,  ///< [in] input structure\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut) ///< [out] output structure\n{\n    const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n    const UINT_32 numPipeLog2 = m_pipesLog2;\n    const UINT_32 pipeMask    = (1 << numPipeLog2) - 1;\n    UINT_32       index       = m_dccBaseIndex + elemLog2;\n    const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?\n                                GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;\n\n    if (pIn->dccKeyFlags.pipeAligned)\n    {\n        index += MaxNumOfBpp;\n\n        if (m_numPkrLog2 < 2)\n        {\n            index += m_pipesLog2 * MaxNumOfBpp;\n        }\n        else\n        {\n            // 4 groups for \"m_numPkrLog2 < 2\" case\n            index += 4 * MaxNumOfBpp;\n\n            const UINT_32 dccPipePerPkr = 3;\n\n            index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +\n                     (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;\n        }\n    }\n\n    const UINT_32  blkSizeLog2 = Log2(pIn->metaBlkWidth) + Log2(pIn->metaBlkHeight) + elemLog2 - 8;\n    const UINT_32  blkMask     = (1 << blkSizeLog2) - 1;\n    const UINT_32  blkOffset   = ComputeOffsetFromSwizzlePattern(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]],\n                                                                 blkSizeLog2 + 1, // +1 for nibble offset\n                                                                 pIn->x,\n                                                                 pIn->y,\n                                                                 pIn->slice,\n                                                                 0);\n    const UINT_32 xb       = pIn->x / pIn->metaBlkWidth;\n    const UINT_32 yb       = pIn->y / pIn->metaBlkHeight;\n    const UINT_32 pb       = pIn->pitch / pIn->metaBlkWidth;\n    const UINT_32 blkIndex = (yb * pb) + xb;\n    const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;\n\n    pOut->addr = (static_cast<UINT_64>(pIn->dccRamSliceSize) * pIn->slice) +\n                 (blkIndex * (1 << blkSizeLog2)) +\n                 ((blkOffset >> 1) ^ pipeXor);\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlInitGlobalParams\n*\n*   @brief\n*       Initializes global parameters\n*\n*   @return\n*       TRUE if all settings are valid\n*\n************************************************************************************************************************\n*/\nBOOL_32 Gfx11Lib::HwlInitGlobalParams(\n    const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input\n{\n    BOOL_32              valid = TRUE;\n    GB_ADDR_CONFIG_GFX11 gbAddrConfig;\n\n    gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;\n\n    switch (gbAddrConfig.bits.NUM_PIPES)\n    {\n        case ADDR_CONFIG_1_PIPE:\n            m_pipes     = 1;\n            m_pipesLog2 = 0;\n            break;\n        case ADDR_CONFIG_2_PIPE:\n            m_pipes     = 2;\n            m_pipesLog2 = 1;\n            break;\n        case ADDR_CONFIG_4_PIPE:\n            m_pipes     = 4;\n            m_pipesLog2 = 2;\n            break;\n        case ADDR_CONFIG_8_PIPE:\n            m_pipes     = 8;\n            m_pipesLog2 = 3;\n            break;\n        case ADDR_CONFIG_16_PIPE:\n            m_pipes     = 16;\n            m_pipesLog2 = 4;\n            break;\n        case ADDR_CONFIG_32_PIPE:\n            m_pipes     = 32;\n            m_pipesLog2 = 5;\n            break;\n        case ADDR_CONFIG_64_PIPE:\n            m_pipes     = 64;\n            m_pipesLog2 = 6;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)\n    {\n        case ADDR_CONFIG_PIPE_INTERLEAVE_256B:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;\n            m_pipeInterleaveLog2  = 8;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_512B:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;\n            m_pipeInterleaveLog2  = 9;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;\n            m_pipeInterleaveLog2  = 10;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:\n            m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;\n            m_pipeInterleaveLog2  = 11;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and\n    // any larger value requires a post-process (left shift) on the output pipeBankXor bits.\n    // And more importantly, SW AddrLib doesn't support sw equation/pattern for PI != 256 case.\n    ADDR_ASSERT(m_pipeInterleaveBytes == ADDR_PIPEINTERLEAVE_256B);\n\n    // These fields are deprecated on GFX11; they do nothing on HW.\n    m_maxCompFrag     = 1;\n    m_maxCompFragLog2 = 0;\n\n    // Skip unaligned case\n    m_htileBaseIndex += MaxNumOfAA;\n\n    m_htileBaseIndex += m_pipesLog2 * MaxNumOfAA;\n    m_colorBaseIndex += m_pipesLog2 * MaxNumOfBpp;\n\n    m_numPkrLog2 = gbAddrConfig.bits.NUM_PKRS;\n    m_numSaLog2  = (m_numPkrLog2 > 0) ? (m_numPkrLog2 - 1) : 0;\n\n    ADDR_ASSERT((m_numPkrLog2 <= m_pipesLog2) && ((m_pipesLog2 - m_numPkrLog2) <= 2));\n\n    if (m_numPkrLog2 >= 2)\n    {\n        m_colorBaseIndex += (2 * m_numPkrLog2 - 2) * MaxNumOfBpp;\n        m_htileBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;\n    }\n\n    // There is no so-called VAR swizzle mode on GFX11 and instead there are 4 256KB swizzle modes. Here we treat 256KB\n    // swizzle mode as \"VAR\" swizzle mode for reusing exising facilities (e.g GetBlockSizeLog2()) provided by base class\n    m_blockVarSizeLog2 = 18;\n\n    if (valid)\n    {\n        InitEquationTable();\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlConvertChipFamily\n*\n*   @brief\n*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision\n*   @return\n*       ChipFamily\n************************************************************************************************************************\n*/\nChipFamily Gfx11Lib::HwlConvertChipFamily(\n    UINT_32 chipFamily,        ///< [in] chip family defined in atiih.h\n    UINT_32 chipRevision)      ///< [in] chip revision defined in \"asic_family\"_id.h\n{\n    ChipFamily family = ADDR_CHIP_FAMILY_NAVI;\n\n    switch (chipFamily)\n    {\n        case FAMILY_NV3:\n            if (ASICREV_IS_NAVI31_P(chipRevision))\n            {\n            }\n            if (ASICREV_IS_NAVI32_P(chipRevision))\n            {\n            }\n            if (ASICREV_IS_NAVI33_P(chipRevision))\n            {\n            }\n            break;\n        case FAMILY_GFX1150:\n            if (ASICREV_IS_GFX1150(chipRevision))\n            {\n                m_settings.isGfx1150 = 1;\n            }\n            break;\n        case FAMILY_GFX1103:\n            m_settings.isGfx1103 = 1;\n            break;\n        default:\n            ADDR_ASSERT(!\"Unknown chip family\");\n            break;\n    }\n\n    m_configFlags.use32bppFor422Fmt = TRUE;\n\n    return family;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetBlk256SizeLog2\n*\n*   @brief\n*       Get block 256 size\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nvoid Gfx11Lib::GetBlk256SizeLog2(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    if (IsThin(resourceType, swizzleMode))\n    {\n        UINT_32 blockBits = 8 - elemLog2;\n\n        // On GFX11, Z and R modes are the same thing.\n        if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))\n        {\n            blockBits -= numSamplesLog2;\n        }\n\n        pBlock->w = (blockBits >> 1) + (blockBits & 1);\n        pBlock->h = (blockBits >> 1);\n        pBlock->d = 0;\n    }\n    else\n    {\n        ADDR_ASSERT(IsThick(resourceType, swizzleMode));\n\n        UINT_32 blockBits = 8 - elemLog2;\n\n        pBlock->d = (blockBits / 3) + (((blockBits % 3) > 0) ? 1 : 0);\n        pBlock->w = (blockBits / 3) + (((blockBits % 3) > 1) ? 1 : 0);\n        pBlock->h = (blockBits / 3);\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetCompressedBlockSizeLog2\n*\n*   @brief\n*       Get compress block size\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nvoid Gfx11Lib::GetCompressedBlockSizeLog2(\n    Gfx11DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    if (dataType == Gfx11DataColor)\n    {\n        GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, pBlock);\n    }\n    else\n    {\n        ADDR_ASSERT(dataType == Gfx11DataDepthStencil);\n        pBlock->w = 3;\n        pBlock->h = 3;\n        pBlock->d = 0;\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetMetaOverlapLog2\n*\n*   @brief\n*       Get meta block overlap\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nINT_32 Gfx11Lib::GetMetaOverlapLog2(\n    Gfx11DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2     ///< [in] number of samples\n    ) const\n{\n    Dim3d compBlock;\n    Dim3d microBlock;\n\n    GetCompressedBlockSizeLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2, &compBlock);\n    GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, &microBlock);\n\n    const INT_32 compSizeLog2   = compBlock.w  + compBlock.h  + compBlock.d;\n    const INT_32 blk256SizeLog2 = microBlock.w + microBlock.h + microBlock.d;\n    const INT_32 maxSizeLog2    = Max(compSizeLog2, blk256SizeLog2);\n    const INT_32 numPipesLog2   = GetEffectiveNumPipes();\n    INT_32       overlap        = numPipesLog2 - maxSizeLog2;\n\n    if (numPipesLog2 > 1)\n    {\n        overlap++;\n    }\n\n    // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)\n    if ((elemLog2 == 4) && (numSamplesLog2 == 3))\n    {\n        overlap--;\n    }\n    overlap = Max(overlap, 0);\n    return overlap;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::Get3DMetaOverlapLog2\n*\n*   @brief\n*       Get 3d meta block overlap\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nINT_32 Gfx11Lib::Get3DMetaOverlapLog2(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2           ///< [in] element size log2\n    ) const\n{\n    Dim3d microBlock;\n    GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, 0, &microBlock);\n\n    INT_32 overlap = GetEffectiveNumPipes() - static_cast<INT_32>(microBlock.w);\n\n    overlap++;\n\n    if ((overlap < 0) || (IsStandardSwizzle(resourceType, swizzleMode) == TRUE))\n    {\n        overlap = 0;\n    }\n    return overlap;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetPipeRotateAmount\n*\n*   @brief\n*       Get pipe rotate amount\n*\n*   @return\n*       Pipe rotate amount\n************************************************************************************************************************\n*/\n\nINT_32 Gfx11Lib::GetPipeRotateAmount(\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode        ///< [in] Swizzle mode\n    ) const\n{\n    INT_32 amount = 0;\n\n    if ((m_pipesLog2 >= (m_numSaLog2 + 1)) && (m_pipesLog2 > 1))\n    {\n        amount = ((m_pipesLog2 == (m_numSaLog2 + 1)) && IsRbAligned(resourceType, swizzleMode)) ?\n                 1 : m_pipesLog2 - (m_numSaLog2 + 1);\n    }\n\n    return amount;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetMetaBlkSize\n*\n*   @brief\n*       Get metadata block size\n*\n*   @return\n*       Meta block size\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::GetMetaBlkSize(\n    Gfx11DataType    dataType,          ///< [in] Data type\n    AddrResourceType resourceType,      ///< [in] Resource type\n    AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode\n    UINT_32          elemLog2,          ///< [in] element size log2\n    UINT_32          numSamplesLog2,    ///< [in] number of samples\n    BOOL_32          pipeAlign,         ///< [in] pipe align\n    Dim3d*           pBlock             ///< [out] block size\n    ) const\n{\n    INT_32 metablkSizeLog2;\n\n    const INT_32 metaElemSizeLog2   = GetMetaElementSizeLog2(dataType);\n    const INT_32 metaCacheSizeLog2  = GetMetaCacheSizeLog2(dataType);\n    const INT_32 compBlkSizeLog2    = (dataType == Gfx11DataColor) ? 8 : 6 + numSamplesLog2 + elemLog2;\n    const INT_32 metaBlkSamplesLog2 = numSamplesLog2;\n    const INT_32 dataBlkSizeLog2    = GetBlockSizeLog2(swizzleMode);\n    INT_32       numPipesLog2       = m_pipesLog2;\n\n    if (IsThin(resourceType, swizzleMode))\n    {\n        if ((pipeAlign == FALSE) ||\n            (IsStandardSwizzle(resourceType, swizzleMode) == TRUE) ||\n            (IsDisplaySwizzle(resourceType, swizzleMode)  == TRUE))\n        {\n            if (pipeAlign)\n            {\n                metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);\n                metablkSizeLog2 = Min(metablkSizeLog2, dataBlkSizeLog2);\n            }\n            else\n            {\n                metablkSizeLog2 = Min(dataBlkSizeLog2, 12);\n            }\n        }\n        else\n        {\n            if ((m_pipesLog2 == m_numSaLog2 + 1) && (m_pipesLog2 > 1))\n            {\n                numPipesLog2++;\n            }\n\n            INT_32 pipeRotateLog2 = GetPipeRotateAmount(resourceType, swizzleMode);\n\n            if (numPipesLog2 >= 4)\n            {\n                INT_32 overlapLog2 = GetMetaOverlapLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2);\n\n                // In 16Bpe 8xaa, we have an extra overlap bit\n                if ((pipeRotateLog2 > 0)  &&\n                    (elemLog2 == 4)       &&\n                    (numSamplesLog2 == 3) &&\n                    (IsZOrderSwizzle(swizzleMode) || (GetEffectiveNumPipes() > 3)))\n                {\n                    overlapLog2++;\n                }\n\n                metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;\n                metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);\n            }\n            else\n            {\n                metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);\n            }\n\n            if (dataType == Gfx11DataDepthStencil)\n            {\n                // For htile surfaces, pad meta block size to 2K * num_pipes\n                metablkSizeLog2 = Max(metablkSizeLog2, 11 + numPipesLog2);\n            }\n\n            const INT_32 compFragLog2 = numSamplesLog2;\n\n            if  (IsRtOptSwizzle(swizzleMode) && (compFragLog2 > 1) && (pipeRotateLog2 >= 1))\n            {\n                const INT_32 tmp = 8 + m_pipesLog2 + Max(pipeRotateLog2, compFragLog2 - 1);\n\n                metablkSizeLog2 = Max(metablkSizeLog2, tmp);\n            }\n        }\n\n        const INT_32 metablkBitsLog2 =\n            metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;\n        pBlock->w = 1 << ((metablkBitsLog2 >> 1) + (metablkBitsLog2 & 1));\n        pBlock->h = 1 << (metablkBitsLog2 >> 1);\n        pBlock->d = 1;\n    }\n    else\n    {\n        ADDR_ASSERT(IsThick(resourceType, swizzleMode));\n\n        if (pipeAlign)\n        {\n            if ((m_pipesLog2 == m_numSaLog2 + 1) &&\n                (m_pipesLog2 > 1)                &&\n                IsRbAligned(resourceType, swizzleMode))\n            {\n                numPipesLog2++;\n            }\n\n            const INT_32 overlapLog2 = Get3DMetaOverlapLog2(resourceType, swizzleMode, elemLog2);\n\n            metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;\n            metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);\n            metablkSizeLog2 = Max(metablkSizeLog2, 12);\n        }\n        else\n        {\n            metablkSizeLog2 = 12;\n        }\n\n        const INT_32 metablkBitsLog2 =\n            metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;\n        pBlock->w = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 0) ? 1 : 0));\n        pBlock->h = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 1) ? 1 : 0));\n        pBlock->d = 1 << (metablkBitsLog2 / 3);\n    }\n\n    return (1 << static_cast<UINT_32>(metablkSizeLog2));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ConvertSwizzlePatternToEquation\n*\n*   @brief\n*       Convert swizzle pattern to equation.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx11Lib::ConvertSwizzlePatternToEquation(\n    UINT_32                elemLog2,  ///< [in] element bytes log2\n    AddrResourceType       rsrcType,  ///< [in] resource type\n    AddrSwizzleMode        swMode,    ///< [in] swizzle mode\n    const ADDR_SW_PATINFO* pPatInfo,  ///< [in] swizzle pattern infor\n    ADDR_EQUATION*         pEquation) ///< [out] equation converted from swizzle pattern\n    const\n{\n    ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];\n    GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n    const ADDR_BIT_SETTING* pSwizzle      = fullSwizzlePattern;\n    const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode);\n    memset(pEquation, 0, sizeof(ADDR_EQUATION));\n    pEquation->numBits            = blockSizeLog2;\n    pEquation->numBitComponents   = pPatInfo->maxItemCount;\n    pEquation->stackedDepthSlices = FALSE;\n\n    for (UINT_32 i = 0; i < elemLog2; i++)\n    {\n        pEquation->addr[i].channel = 0;\n        pEquation->addr[i].valid   = 1;\n        pEquation->addr[i].index   = i;\n    }\n\n    if (IsXor(swMode) == FALSE)\n    {\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            ADDR_ASSERT(IsPow2(pSwizzle[i].value));\n\n            if (pSwizzle[i].x != 0)\n            {\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].x)));\n\n                pEquation->addr[i].channel = 0;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].x) + elemLog2;\n            }\n            else if (pSwizzle[i].y != 0)\n            {\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].y)));\n\n                pEquation->addr[i].channel = 1;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n            }\n            else\n            {\n                ADDR_ASSERT(pSwizzle[i].z != 0);\n                ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));\n\n                pEquation->addr[i].channel = 2;\n                pEquation->addr[i].valid   = 1;\n                pEquation->addr[i].index   = Log2(pSwizzle[i].z);\n            }\n\n            pEquation->xor1[i].value = 0;\n            pEquation->xor2[i].value = 0;\n        }\n    }\n    else if (IsThin(rsrcType, swMode))\n    {\n        Dim3d dim;\n        ComputeThinBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, 0, rsrcType, swMode);\n\n        const UINT_32 blkXLog2 = Log2(dim.w);\n        const UINT_32 blkYLog2 = Log2(dim.h);\n        const UINT_32 blkXMask = dim.w - 1;\n        const UINT_32 blkYMask = dim.h - 1;\n\n        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT];\n        UINT_32          xMask = 0;\n        UINT_32          yMask = 0;\n        UINT_32          bMask = (1 << elemLog2) - 1;\n\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            if (IsPow2(pSwizzle[i].value))\n            {\n                if (pSwizzle[i].x != 0)\n                {\n                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);\n                    xMask |= pSwizzle[i].x;\n\n                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);\n\n                    ADDR_ASSERT(xLog2 < blkXLog2);\n\n                    pEquation->addr[i].channel = 0;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = xLog2 + elemLog2;\n                }\n                else\n                {\n                    ADDR_ASSERT(pSwizzle[i].y != 0);\n                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);\n                    yMask |= pSwizzle[i].y;\n\n                    pEquation->addr[i].channel = 1;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                }\n\n                swizzle[i].value = 0;\n                bMask |= 1 << i;\n            }\n            else\n            {\n                if (pSwizzle[i].z != 0)\n                {\n                    ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));\n\n                    pEquation->xor2[i].channel = 2;\n                    pEquation->xor2[i].valid   = 1;\n                    pEquation->xor2[i].index   = Log2(pSwizzle[i].z);\n                }\n\n                swizzle[i].x = pSwizzle[i].x;\n                swizzle[i].y = pSwizzle[i].y;\n                swizzle[i].z = swizzle[i].s = 0;\n\n                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);\n\n                const UINT_32 xHi = swizzle[i].x & (~blkXMask);\n\n                if (xHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(xHi));\n                    ADDR_ASSERT(pEquation->xor1[i].value == 0);\n\n                    pEquation->xor1[i].channel = 0;\n                    pEquation->xor1[i].valid   = 1;\n                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;\n\n                    swizzle[i].x &= blkXMask;\n                }\n\n                const UINT_32 yHi = swizzle[i].y & (~blkYMask);\n\n                if (yHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(yHi));\n\n                    if (xHi == 0)\n                    {\n                        ADDR_ASSERT(pEquation->xor1[i].value == 0);\n                        pEquation->xor1[i].channel = 1;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(yHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 1;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(yHi);\n                    }\n\n                    swizzle[i].y &= blkYMask;\n                }\n\n                if (swizzle[i].value == 0)\n                {\n                    bMask |= 1 << i;\n                }\n            }\n        }\n\n        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;\n        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;\n\n        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);\n\n        while (bMask != blockMask)\n        {\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)\n            {\n                if ((bMask & (1 << i)) == 0)\n                {\n                    if (IsPow2(swizzle[i].value))\n                    {\n                        if (swizzle[i].x != 0)\n                        {\n                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);\n                            xMask |= swizzle[i].x;\n\n                            const UINT_32 xLog2 = Log2(swizzle[i].x);\n\n                            ADDR_ASSERT(xLog2 < blkXLog2);\n\n                            pEquation->addr[i].channel = 0;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = xLog2 + elemLog2;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzle[i].y != 0);\n                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);\n                            yMask |= swizzle[i].y;\n\n                            pEquation->addr[i].channel = 1;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].y);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                        }\n\n                        swizzle[i].value = 0;\n                        bMask |= 1 << i;\n                    }\n                    else\n                    {\n                        const UINT_32 x = swizzle[i].x & xMask;\n                        const UINT_32 y = swizzle[i].y & yMask;\n\n                        if (x != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(x));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 0;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(x) + elemLog2;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 0;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(x) + elemLog2;\n                            }\n                        }\n\n                        if (y != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(y));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 1;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(y);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 1;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(y);\n                            }\n                        }\n\n                        swizzle[i].x &= ~x;\n                        swizzle[i].y &= ~y;\n                    }\n                }\n            }\n        }\n\n        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask));\n    }\n    else\n    {\n        const Dim3d& blkDim = (blockSizeLog2 == Log2Size256K) ?\n                              Block256K_Log2_3d[elemLog2] :\n                              ((blockSizeLog2 == Log2Size4K) ? Block4K_Log2_3d[elemLog2] : Block64K_Log2_3d[elemLog2]);\n\n        const UINT_32 blkXLog2 = blkDim.w;\n        const UINT_32 blkYLog2 = blkDim.h;\n        const UINT_32 blkZLog2 = blkDim.d;\n        const UINT_32 blkXMask = (1 << blkXLog2) - 1;\n        const UINT_32 blkYMask = (1 << blkYLog2) - 1;\n        const UINT_32 blkZMask = (1 << blkZLog2) - 1;\n\n        ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};\n        UINT_32          xMask = 0;\n        UINT_32          yMask = 0;\n        UINT_32          zMask = 0;\n        UINT_32          bMask = (1 << elemLog2) - 1;\n\n        for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n        {\n            if (IsPow2(pSwizzle[i].value))\n            {\n                if (pSwizzle[i].x != 0)\n                {\n                    ADDR_ASSERT((xMask & pSwizzle[i].x) == 0);\n                    xMask |= pSwizzle[i].x;\n\n                    const UINT_32 xLog2 = Log2(pSwizzle[i].x);\n\n                    ADDR_ASSERT(xLog2 < blkXLog2);\n\n                    pEquation->addr[i].channel = 0;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = xLog2 + elemLog2;\n                }\n                else if (pSwizzle[i].y != 0)\n                {\n                    ADDR_ASSERT((yMask & pSwizzle[i].y) == 0);\n                    yMask |= pSwizzle[i].y;\n\n                    pEquation->addr[i].channel = 1;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].y);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                }\n                else\n                {\n                    ADDR_ASSERT(pSwizzle[i].z != 0);\n                    ADDR_ASSERT((zMask & pSwizzle[i].z) == 0);\n                    zMask |= pSwizzle[i].z;\n\n                    pEquation->addr[i].channel = 2;\n                    pEquation->addr[i].valid   = 1;\n                    pEquation->addr[i].index   = Log2(pSwizzle[i].z);\n\n                    ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);\n                }\n\n                swizzle[i].value = 0;\n                bMask |= 1 << i;\n            }\n            else\n            {\n                swizzle[i].x = pSwizzle[i].x;\n                swizzle[i].y = pSwizzle[i].y;\n                swizzle[i].z = pSwizzle[i].z;\n                swizzle[i].s = 0;\n\n                ADDR_ASSERT(IsPow2(swizzle[i].value) == FALSE);\n\n                const UINT_32 xHi = swizzle[i].x & (~blkXMask);\n                const UINT_32 yHi = swizzle[i].y & (~blkYMask);\n                const UINT_32 zHi = swizzle[i].z & (~blkZMask);\n\n                ADDR_ASSERT((xHi == 0) || (yHi== 0) || (zHi == 0));\n\n                if (xHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(xHi));\n                    ADDR_ASSERT(pEquation->xor1[i].value == 0);\n\n                    pEquation->xor1[i].channel = 0;\n                    pEquation->xor1[i].valid   = 1;\n                    pEquation->xor1[i].index   = Log2(xHi) + elemLog2;\n\n                    swizzle[i].x &= blkXMask;\n                }\n\n                if (yHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(yHi));\n\n                    if (pEquation->xor1[i].value == 0)\n                    {\n                        pEquation->xor1[i].channel = 1;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(yHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 1;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(yHi);\n                    }\n\n                    swizzle[i].y &= blkYMask;\n                }\n\n                if (zHi != 0)\n                {\n                    ADDR_ASSERT(IsPow2(zHi));\n\n                    if (pEquation->xor1[i].value == 0)\n                    {\n                        pEquation->xor1[i].channel = 2;\n                        pEquation->xor1[i].valid   = 1;\n                        pEquation->xor1[i].index   = Log2(zHi);\n                    }\n                    else\n                    {\n                        ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                        pEquation->xor2[i].channel = 2;\n                        pEquation->xor2[i].valid   = 1;\n                        pEquation->xor2[i].index   = Log2(zHi);\n                    }\n\n                    swizzle[i].z &= blkZMask;\n                }\n\n                if (swizzle[i].value == 0)\n                {\n                    bMask |= 1 << i;\n                }\n            }\n        }\n\n        const UINT_32 pipeIntMask = (1 << m_pipeInterleaveLog2) - 1;\n        const UINT_32 blockMask   = (1 << blockSizeLog2) - 1;\n\n        ADDR_ASSERT((bMask & pipeIntMask) == pipeIntMask);\n\n        while (bMask != blockMask)\n        {\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blockSizeLog2; i++)\n            {\n                if ((bMask & (1 << i)) == 0)\n                {\n                    if (IsPow2(swizzle[i].value))\n                    {\n                        if (swizzle[i].x != 0)\n                        {\n                            ADDR_ASSERT((xMask & swizzle[i].x) == 0);\n                            xMask |= swizzle[i].x;\n\n                            const UINT_32 xLog2 = Log2(swizzle[i].x);\n\n                            ADDR_ASSERT(xLog2 < blkXLog2);\n\n                            pEquation->addr[i].channel = 0;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = xLog2 + elemLog2;\n                        }\n                        else if (swizzle[i].y != 0)\n                        {\n                            ADDR_ASSERT((yMask & swizzle[i].y) == 0);\n                            yMask |= swizzle[i].y;\n\n                            pEquation->addr[i].channel = 1;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].y);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkYLog2);\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(swizzle[i].z != 0);\n                            ADDR_ASSERT((zMask & swizzle[i].z) == 0);\n                            zMask |= swizzle[i].z;\n\n                            pEquation->addr[i].channel = 2;\n                            pEquation->addr[i].valid   = 1;\n                            pEquation->addr[i].index   = Log2(swizzle[i].z);\n\n                            ADDR_ASSERT(pEquation->addr[i].index < blkZLog2);\n                        }\n\n                        swizzle[i].value = 0;\n                        bMask |= 1 << i;\n                    }\n                    else\n                    {\n                        const UINT_32 x = swizzle[i].x & xMask;\n                        const UINT_32 y = swizzle[i].y & yMask;\n                        const UINT_32 z = swizzle[i].z & zMask;\n\n                        if (x != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(x));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 0;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(x) + elemLog2;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 0;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(x) + elemLog2;\n                            }\n                        }\n\n                        if (y != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(y));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 1;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(y);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 1;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(y);\n                            }\n                        }\n\n                        if (z != 0)\n                        {\n                            ADDR_ASSERT(IsPow2(z));\n\n                            if (pEquation->xor1[i].value == 0)\n                            {\n                                pEquation->xor1[i].channel = 2;\n                                pEquation->xor1[i].valid   = 1;\n                                pEquation->xor1[i].index   = Log2(z);\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(pEquation->xor2[i].value == 0);\n                                pEquation->xor2[i].channel = 2;\n                                pEquation->xor2[i].valid   = 1;\n                                pEquation->xor2[i].index   = Log2(z);\n                            }\n                        }\n\n                        swizzle[i].x &= ~x;\n                        swizzle[i].y &= ~y;\n                        swizzle[i].z &= ~z;\n                    }\n                }\n            }\n        }\n\n        ADDR_ASSERT((xMask == blkXMask) && (yMask == blkYMask) && (zMask == blkZMask));\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::InitEquationTable\n*\n*   @brief\n*       Initialize Equation table.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx11Lib::InitEquationTable()\n{\n    memset(m_equationTable, 0, sizeof(m_equationTable));\n\n    for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)\n    {\n        const AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);\n\n        for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwModeType; swModeIdx++)\n        {\n            const AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);\n\n            for (UINT_32 elemLog2 = 0; elemLog2 < MaxElementBytesLog2; elemLog2++)\n            {\n                UINT_32                equationIndex = ADDR_INVALID_EQUATION_INDEX;\n                const ADDR_SW_PATINFO* pPatInfo      = GetSwizzlePatternInfo(swMode, rsrcType, elemLog2, 1);\n\n                if (pPatInfo != NULL)\n                {\n                    ADDR_ASSERT(IsValidSwMode(swMode));\n\n                    if (pPatInfo->maxItemCount <= 3) // Get a valid equationIndex\n                    {\n                        ADDR_EQUATION equation = {};\n\n                        // Passing in pPatInfo to get the addr equation\n                        ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);\n\n                        equationIndex = m_numEquations;\n                        ADDR_ASSERT(equationIndex < EquationTableSize);\n                        // Updates m_equationTable[m_numEquations] to be the addr equation for this PatInfo\n                        m_equationTable[equationIndex] = equation;\n                        // Increment m_numEquations\n                        m_numEquations++;\n                    }\n                    else // There is no equationIndex\n                    {\n                        // We only see \"ill\" equation from 64/128 BPE + 3D resource + SW_64KB_D_X\n                        ADDR_ASSERT((elemLog2 == 3) || (elemLog2 == 4));\n                        ADDR_ASSERT(rsrcType == ADDR_RSRC_TEX_3D);\n                        ADDR_ASSERT(swMode == ADDR_SW_64KB_D_X);\n                    }\n                }\n\n                m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] = equationIndex;\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlGetEquationIndex\n*\n*   @brief\n*       Interface function stub of GetEquationIndex\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::HwlGetEquationIndex(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    UINT_32 equationIdx = ADDR_INVALID_EQUATION_INDEX;\n\n    if ((pIn->resourceType == ADDR_RSRC_TEX_2D) ||\n        (pIn->resourceType == ADDR_RSRC_TEX_3D))\n    {\n        const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swModeIdx   = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n\n        equationIdx = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];\n    }\n\n    if (pOut->pMipInfo != NULL)\n    {\n        for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n        {\n            pOut->pMipInfo[i].equationIndex = equationIdx;\n        }\n    }\n\n    return equationIdx;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetValidDisplaySwizzleModes\n*\n*   @brief\n*       Get valid swizzle modes mask for displayable surface\n*\n*   @return\n*       Valid swizzle modes mask for displayable surface\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::GetValidDisplaySwizzleModes(\n    UINT_32 bpp\n    ) const\n{\n    UINT_32 swModeMask = 0;\n\n    if (bpp <= 64)\n    {\n        const ChipFamily  family = GetChipFamily();\n\n        swModeMask = Dcn32SwModeMask;\n\n        if (false\n            || (m_settings.isGfx1103)\n            || (m_settings.isGfx1150)\n           )\n        {\n            // Not all GPUs support displaying with 256kB swizzle modes.\n            swModeMask &= ~((1u << ADDR_SW_256KB_D_X) |\n                            (1u << ADDR_SW_256KB_R_X));\n        }\n    }\n\n    return swModeMask;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::IsValidDisplaySwizzleMode\n*\n*   @brief\n*       Check if a swizzle mode is supported by display engine\n*\n*   @return\n*       TRUE is swizzle mode is supported by display engine\n************************************************************************************************************************\n*/\nBOOL_32 Gfx11Lib::IsValidDisplaySwizzleMode(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure\n    ) const\n{\n    ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);\n\n    return (GetValidDisplaySwizzleModes(pIn->bpp) & (1 << pIn->swizzleMode)) ? TRUE : FALSE;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetMaxNumMipsInTail\n*\n*   @brief\n*       Return max number of mips in tails\n*\n*   @return\n*       Max number of mips in tails\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::GetMaxNumMipsInTail(\n    UINT_32 blockSizeLog2,     ///< block size log2\n    BOOL_32 isThin             ///< is thin or thick\n    ) const\n{\n    UINT_32 effectiveLog2 = blockSizeLog2;\n\n    if (isThin == FALSE)\n    {\n        effectiveLog2 -= (blockSizeLog2 - 8) / 3;\n    }\n\n    return (effectiveLog2 <= 11) ? (1 + (1 << (effectiveLog2 - 9))) : (effectiveLog2 - 4);\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputePipeBankXor\n*\n*   @brief\n*       Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputePipeBankXor(\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,     ///< [in] input structure\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut     ///< [out] output structure\n    ) const\n{\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        pOut->pipeBankXor = 0;\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSlicePipeBankXor\n*\n*   @brief\n*       Generate slice PipeBankXor value based on base PipeBankXor value and slice id\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSlicePipeBankXor(\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,   ///< [in] input structure\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut   ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        if (pIn->bpe == 0)\n        {\n            ADDR_ASSERT_ALWAYS();\n\n            // Require a valid bytes-per-element value passed from client...\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,\n                                                                    pIn->resourceType,\n                                                                    Log2(pIn->bpe >> 3),\n                                                                    1);\n\n            if (pPatInfo != NULL)\n            {\n                ADDR_BIT_SETTING fullSwizzlePattern[20];\n                GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n                const UINT_32 pipeBankXorOffset =\n                    ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),\n                                                    GetBlockSizeLog2(pIn->swizzleMode),\n                                                    0,\n                                                    0,\n                                                    pIn->slice,\n                                                    0);\n\n                const UINT_32 pipeBankXor = pipeBankXorOffset >> m_pipeInterleaveLog2;\n\n                // Should have no bit set under pipe interleave\n                ADDR_ASSERT((pipeBankXor << m_pipeInterleaveLog2) == pipeBankXorOffset);\n\n                pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeBankXor;\n            }\n            else\n            {\n                // Should never come here...\n                ADDR_NOT_IMPLEMENTED();\n\n                returnCode = ADDR_NOTSUPPORTED;\n            }\n        }\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Compute sub resource offset to support swizzle pattern\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));\n\n    pOut->offset = pIn->slice * pIn->sliceSize + pIn->macroBlockOffset;\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(\n    const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)\n    {\n        // Only thin swizzle mode can have a NonBC view...\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&\n             ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))\n    {\n        // Only support BC1~BC7, ASTC, or ETC2 for now...\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else\n    {\n        UINT_32 bcWidth, bcHeight;\n        UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, NULL, &bcWidth, &bcHeight);\n\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT infoIn = {};\n        infoIn.flags        = pIn->flags;\n        infoIn.swizzleMode  = pIn->swizzleMode;\n        infoIn.resourceType = pIn->resourceType;\n        infoIn.bpp          = bpp;\n        infoIn.width        = RoundUpQuotient(pIn->width, bcWidth);\n        infoIn.height       = RoundUpQuotient(pIn->height, bcHeight);\n        infoIn.numSlices    = pIn->numSlices;\n        infoIn.numMipLevels = pIn->numMipLevels;\n        infoIn.numSamples   = 1;\n        infoIn.numFrags     = 1;\n\n        ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {};\n\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};\n        infoOut.pMipInfo = mipInfo;\n\n        const BOOL_32 tiled = (pIn->swizzleMode != ADDR_SW_LINEAR) ? TRUE : FALSE;\n\n        if (tiled)\n        {\n            returnCode = HwlComputeSurfaceInfoTiled(&infoIn, &infoOut);\n        }\n        else\n        {\n            returnCode = HwlComputeSurfaceInfoLinear(&infoIn, &infoOut);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT subOffIn = {};\n            subOffIn.swizzleMode      = infoIn.swizzleMode;\n            subOffIn.resourceType     = infoIn.resourceType;\n            subOffIn.slice            = pIn->slice;\n            subOffIn.sliceSize        = infoOut.sliceSize;\n            subOffIn.macroBlockOffset = mipInfo[pIn->mipId].macroBlockOffset;\n            subOffIn.mipTailOffset    = mipInfo[pIn->mipId].mipTailOffset;\n\n            ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT subOffOut = {};\n\n            // For any mipmap level, move nonBc view base address by offset\n            HwlComputeSubResourceOffsetForSwizzlePattern(&subOffIn, &subOffOut);\n            pOut->offset = subOffOut.offset;\n\n            ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT slicePbXorIn = {};\n            slicePbXorIn.bpe             = infoIn.bpp;\n            slicePbXorIn.swizzleMode     = infoIn.swizzleMode;\n            slicePbXorIn.resourceType    = infoIn.resourceType;\n            slicePbXorIn.basePipeBankXor = pIn->pipeBankXor;\n            slicePbXorIn.slice           = pIn->slice;\n\n            ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT slicePbXorOut = {};\n\n            // For any mipmap level, nonBc view should use computed pbXor\n            HwlComputeSlicePipeBankXor(&slicePbXorIn, &slicePbXorOut);\n            pOut->pipeBankXor = slicePbXorOut.pipeBankXor;\n\n            const BOOL_32 inTail           = tiled && (pIn->mipId >= infoOut.firstMipIdInTail) ? TRUE : FALSE;\n            const UINT_32 requestMipWidth  = RoundUpQuotient(Max(pIn->width >> pIn->mipId, 1u), bcWidth);\n            const UINT_32 requestMipHeight = RoundUpQuotient(Max(pIn->height >> pIn->mipId, 1u), bcHeight);\n\n            if (inTail)\n            {\n                // For mipmap level that is in mip tail block, hack a lot of things...\n                // Basically all mipmap levels in tail block will be viewed as a small mipmap chain that all levels\n                // are fit in tail block:\n\n                // - mipId = relative mip id (which is counted from first mip ID in tail in original mip chain)\n                pOut->mipId = pIn->mipId - infoOut.firstMipIdInTail;\n\n                // - at least 2 mipmap levels (since only 1 mipmap level will not be viewed as mipmap!)\n                pOut->numMipLevels = Max(infoIn.numMipLevels - infoOut.firstMipIdInTail, 2u);\n\n                // - (mip0) width = requestMipWidth << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unalignedWidth = Min(requestMipWidth << pOut->mipId, infoOut.blockWidth / 2);\n\n                // - (mip0) height = requestMipHeight << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unalignedHeight = Min(requestMipHeight << pOut->mipId, infoOut.blockHeight);\n            }\n            // This check should cover at least mipId == 0\n            else if (requestMipWidth << pIn->mipId == infoIn.width)\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded without losing element:\n                // - only one mipmap level and mipId = 0\n                pOut->mipId        = 0;\n                pOut->numMipLevels = 1;\n\n                // (mip0) width = requestMipWidth\n                pOut->unalignedWidth = requestMipWidth;\n\n                // (mip0) height = requestMipHeight\n                pOut->unalignedHeight = requestMipHeight;\n            }\n            else\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded with element losing,\n                // We have to make it a multiple mipmap view (2 levels view here), add one extra element if needed,\n                // because single mip view may have different pitch value than original (multiple) mip view...\n                // A simple case would be:\n                // - 64KB block swizzle mode, 8 Bytes-Per-Element. Block dim = [0x80, 0x40]\n                // - 2 mipmap levels with API mip0 width = 0x401/mip1 width = 0x200 and non-BC view\n                //   mip0 width = 0x101/mip1 width = 0x80\n                // By multiple mip view, the pitch for mip level 1 would be 0x100 bytes, due to rounding up logic in\n                // GetMipSize(), and by single mip level view the pitch will only be 0x80 bytes.\n\n                // - 2 levels and mipId = 1\n                pOut->mipId        = 1;\n                pOut->numMipLevels = 2;\n\n                const UINT_32 upperMipWidth  = RoundUpQuotient(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth);\n                const UINT_32 upperMipHeight = RoundUpQuotient(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight);\n\n                const BOOL_32 needToAvoidInTail =\n                    tiled && (requestMipWidth <= infoOut.blockWidth / 2) && (requestMipHeight <= infoOut.blockHeight) ?\n                    TRUE : FALSE;\n\n                const UINT_32 hwMipWidth  = PowTwoAlign(ShiftCeil(infoIn.width, pIn->mipId), infoOut.blockWidth);\n                const UINT_32 hwMipHeight = PowTwoAlign(ShiftCeil(infoIn.height, pIn->mipId), infoOut.blockHeight);\n\n                const BOOL_32 needExtraWidth =\n                    ((upperMipWidth < requestMipWidth * 2) ||\n                     ((upperMipWidth == requestMipWidth * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipWidth > PowTwoAlign(requestMipWidth, infoOut.blockWidth))))) ? TRUE : FALSE;\n\n                const BOOL_32 needExtraHeight =\n                    ((upperMipHeight < requestMipHeight * 2) ||\n                     ((upperMipHeight == requestMipHeight * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipHeight > PowTwoAlign(requestMipHeight, infoOut.blockHeight))))) ? TRUE : FALSE;\n\n                // (mip0) width = requestLastMipLevelWidth\n                pOut->unalignedWidth  = upperMipWidth + (needExtraWidth ? 1: 0);\n\n                // (mip0) height = requestLastMipLevelHeight\n                pOut->unalignedHeight = upperMipHeight + (needExtraHeight ? 1: 0);\n            }\n\n            // Assert the downgrading from this mip[0] width would still generate correct mip[N] width\n            ADDR_ASSERT(ShiftRight(pOut->unalignedWidth, pOut->mipId) == requestMipWidth);\n            // Assert the downgrading from this mip[0] height would still generate correct mip[N] height\n            ADDR_ASSERT(ShiftRight(pOut->unalignedHeight, pOut->mipId) == requestMipHeight);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ValidateNonSwModeParams\n*\n*   @brief\n*       Validate compute surface info params except swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx11Lib::ValidateNonSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n    else if (pIn->flags.fmask == 1)\n    {\n        // There is no FMASK for GFX11 ASICs\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n    else if (pIn->numSamples > 8)\n    {\n        // There is no EQAA support for GFX11 ASICs, so the max number of sample is 8\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n    else if ((pIn->numFrags != 0) && (pIn->numSamples != pIn->numFrags))\n    {\n        // There is no EQAA support for GFX11 ASICs, so the number of sample has to be same as number of fragment\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const ADDR2_SURFACE_FLAGS flags    = pIn->flags;\n    const AddrResourceType    rsrcType = pIn->resourceType;\n    const BOOL_32             mipmap   = (pIn->numMipLevels > 1);\n    const BOOL_32             msaa     = (pIn->numSamples > 1);\n    const BOOL_32             display  = flags.display;\n    const BOOL_32             tex3d    = IsTex3d(rsrcType);\n    const BOOL_32             tex2d    = IsTex2d(rsrcType);\n    const BOOL_32             tex1d    = IsTex1d(rsrcType);\n    const BOOL_32             stereo   = flags.qbStereo;\n\n    // Resource type check\n    if (tex1d)\n    {\n        if (msaa || display || stereo)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex2d)\n    {\n        if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex3d)\n    {\n        if (msaa || display || stereo)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ValidateSwModeParams\n*\n*   @brief\n*       Validate compute surface info related to swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx11Lib::ValidateSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n    else if (IsValidSwMode(pIn->swizzleMode) == FALSE)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const ADDR2_SURFACE_FLAGS flags       = pIn->flags;\n    const AddrResourceType    rsrcType    = pIn->resourceType;\n    const AddrSwizzleMode     swizzle     = pIn->swizzleMode;\n    const BOOL_32             msaa        = (pIn->numSamples > 1);\n    const BOOL_32             zbuffer     = flags.depth || flags.stencil;\n    const BOOL_32             color       = flags.color;\n    const BOOL_32             display     = flags.display;\n    const BOOL_32             tex3d       = IsTex3d(rsrcType);\n    const BOOL_32             tex2d       = IsTex2d(rsrcType);\n    const BOOL_32             tex1d       = IsTex1d(rsrcType);\n    const BOOL_32             thin3d      = flags.view3dAs2dArray;\n    const BOOL_32             linear      = IsLinear(swizzle);\n    const BOOL_32             blk256B     = IsBlock256b(swizzle);\n    const BOOL_32             isNonPrtXor = IsNonPrtXor(swizzle);\n    const BOOL_32             prt         = flags.prt;\n\n    // Misc check\n    if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numSamples)))\n    {\n        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if ((pIn->bpp == 96) && (linear == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const UINT_32 swizzleMask = 1 << swizzle;\n\n    // Resource type check\n    if (tex1d)\n    {\n        if ((swizzleMask & Gfx11Rsrc1dSwModeMask) == 0)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex2d)\n    {\n        if ((swizzleMask & Gfx11Rsrc2dSwModeMask) == 0)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n        else if (prt && ((swizzleMask & Gfx11Rsrc2dPrtSwModeMask) == 0))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex3d)\n    {\n        if (((swizzleMask & Gfx11Rsrc3dSwModeMask) == 0) ||\n            (prt && ((swizzleMask & Gfx11Rsrc3dPrtSwModeMask) == 0)) ||\n            (thin3d && ((swizzleMask & Gfx11Rsrc3dThinSwModeMask) == 0)))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    // Swizzle type check\n    if (linear)\n    {\n        if (zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsZOrderSwizzle(swizzle))\n    {\n        if ((pIn->bpp > 64)                         ||\n            (msaa && (color || (pIn->bpp > 32)))    ||\n            ElemLib::IsBlockCompressed(pIn->format) ||\n            ElemLib::IsMacroPixelPacked(pIn->format))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsStandardSwizzle(rsrcType, swizzle))\n    {\n        if (zbuffer || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsDisplaySwizzle(rsrcType, swizzle))\n    {\n        if (zbuffer || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsRtOptSwizzle(swizzle))\n    {\n        if (zbuffer)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    // Block type check\n    if (blk256B)\n    {\n        if (zbuffer || tex3d || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSurfaceInfoSanityCheck\n*\n*   @brief\n*       Compute surface info sanity check\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoSanityCheck(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure\n    ) const\n{\n    return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlGetPreferredSurfaceSetting\n*\n*   @brief\n*       Internal function to get suggested surface information for cliet to use\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->flags.fmask)\n    {\n        // There is no FMASK for GFX11 ASICs.\n        ADDR_ASSERT_ALWAYS();\n\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        UINT_32 bpp    = pIn->bpp;\n        UINT_32 width  = Max(pIn->width, 1u);\n        UINT_32 height = Max(pIn->height, 1u);\n\n        // Set format to INVALID will skip this conversion\n        if (pIn->format != ADDR_FMT_INVALID)\n        {\n            ElemMode elemMode = ADDR_UNCOMPRESSED;\n            UINT_32 expandX, expandY;\n\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            bpp = GetElemLib()->GetBitsPerPixel(pIn->format,\n                                                &elemMode,\n                                                &expandX,\n                                                &expandY);\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &bpp,\n                                            &basePitch,\n                                            &width,\n                                            &height);\n        }\n\n        const UINT_32 numSlices    = Max(pIn->numSlices,    1u);\n        const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);\n        const UINT_32 numSamples   = Max(pIn->numSamples,   1u);\n        const BOOL_32 msaa         = numSamples > 1;\n\n        // Pre sanity check on non swizzle mode parameters\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};\n        localIn.flags        = pIn->flags;\n        localIn.resourceType = pIn->resourceType;\n        localIn.format       = pIn->format;\n        localIn.bpp          = bpp;\n        localIn.width        = width;\n        localIn.height       = height;\n        localIn.numSlices    = numSlices;\n        localIn.numMipLevels = numMipLevels;\n        localIn.numSamples   = numSamples;\n        localIn.numFrags     = numSamples;\n\n        if (ValidateNonSwModeParams(&localIn))\n        {\n            // Forbid swizzle mode(s) by client setting\n            ADDR2_SWMODE_SET allowedSwModeSet = {};\n            allowedSwModeSet.value |= pIn->forbiddenBlock.linear ? 0 : Gfx11LinearSwModeMask;\n            allowedSwModeSet.value |= pIn->forbiddenBlock.micro  ? 0 : Gfx11Blk256BSwModeMask;\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThin4KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? 0 : Gfx11Blk4KBSwModeMask);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThick4KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick4KBSwModeMask : 0);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThin64KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.macroThick64KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick64KBSwModeMask : 0);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.gfx11.thin256KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask);\n            allowedSwModeSet.value |=\n                pIn->forbiddenBlock.gfx11.thick256KB ? 0 :\n                ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick256KBSwModeMask : 0);\n\n            if (pIn->preferredSwSet.value != 0)\n            {\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx11ZSwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx11StandardSwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx11DisplaySwModeMask;\n                allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx11RenderSwModeMask;\n            }\n\n            if (pIn->noXor)\n            {\n                allowedSwModeSet.value &= ~Gfx11XorSwModeMask;\n            }\n\n            if (pIn->maxAlign > 0)\n            {\n                if (pIn->maxAlign < Size256K)\n                {\n                    allowedSwModeSet.value &= ~Gfx11Blk256KBSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size64K)\n                {\n                    allowedSwModeSet.value &= ~Gfx11Blk64KBSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size4K)\n                {\n                    allowedSwModeSet.value &= ~Gfx11Blk4KBSwModeMask;\n                }\n\n                if (pIn->maxAlign < Size256)\n                {\n                    allowedSwModeSet.value &= ~Gfx11Blk256BSwModeMask;\n                }\n            }\n\n            // Filter out invalid swizzle mode(s) by image attributes and HW restrictions\n            switch (pIn->resourceType)\n            {\n                case ADDR_RSRC_TEX_1D:\n                    allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;\n                    break;\n\n                case ADDR_RSRC_TEX_2D:\n                    allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;\n                    break;\n\n                case ADDR_RSRC_TEX_3D:\n                    allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;\n\n                    if (pIn->flags.view3dAs2dArray)\n                    {\n                        allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;\n                    }\n                    break;\n\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    allowedSwModeSet.value = 0;\n                    break;\n            }\n\n            if (ElemLib::IsBlockCompressed(pIn->format)  ||\n                ElemLib::IsMacroPixelPacked(pIn->format) ||\n                (bpp > 64)                               ||\n                (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))\n            {\n                allowedSwModeSet.value &= ~Gfx11ZSwModeMask;\n            }\n\n            if (pIn->format == ADDR_FMT_32_32_32)\n            {\n                allowedSwModeSet.value &= Gfx11LinearSwModeMask;\n            }\n\n            if (msaa)\n            {\n                allowedSwModeSet.value &= Gfx11MsaaSwModeMask;\n            }\n\n            if (pIn->flags.depth || pIn->flags.stencil)\n            {\n                allowedSwModeSet.value &= Gfx11ZSwModeMask;\n            }\n\n            if (pIn->flags.display)\n            {\n                allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);\n            }\n\n            if (allowedSwModeSet.value != 0)\n            {\n#if DEBUG\n                // Post sanity check, at least AddrLib should accept the output generated by its own\n                UINT_32 validateSwModeSet = allowedSwModeSet.value;\n\n                for (UINT_32 i = 0; validateSwModeSet != 0; i++)\n                {\n                    if (validateSwModeSet & 1)\n                    {\n                        localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);\n                        ADDR_ASSERT(ValidateSwModeParams(&localIn));\n                    }\n\n                    validateSwModeSet >>= 1;\n                }\n#endif\n\n                pOut->resourceType   = pIn->resourceType;\n                pOut->validSwModeSet = allowedSwModeSet;\n                pOut->canXor         = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;\n\n                GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &(pOut->validBlockSet));\n                GetAllowedSwSet(allowedSwModeSet, &(pOut->validSwTypeSet));\n\n                pOut->clientPreferredSwSet = pIn->preferredSwSet;\n\n                if (pOut->clientPreferredSwSet.value == 0)\n                {\n                    pOut->clientPreferredSwSet.value = AddrSwSetAll;\n                }\n\n                // Apply optional restrictions\n                if (pIn->flags.needEquation)\n                {\n                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :\n                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;\n                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);\n                }\n\n                if (allowedSwModeSet.value == Gfx11LinearSwModeMask)\n                {\n                    pOut->swizzleMode = ADDR_SW_LINEAR;\n                }\n                else\n                {\n                    const BOOL_32 computeMinSize = (pIn->flags.minimizeAlign == 1) || (pIn->memoryBudget >= 1.0);\n\n                    if ((height > 1) && (computeMinSize == FALSE))\n                    {\n                        // Always ignore linear swizzle mode if:\n                        // 1. This is a (2D/3D) resource with height > 1\n                        // 2. Client doesn't require computing minimize size\n                        allowedSwModeSet.swLinear = 0;\n                    }\n\n                    ADDR2_BLOCK_SET allowedBlockSet = {};\n                    GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);\n\n                    // Determine block size if there are 2 or more block type candidates\n                    if (IsPow2(allowedBlockSet.value) == FALSE)\n                    {\n                        AddrSwizzleMode swMode[AddrBlockMaxTiledType] = {};\n\n                        swMode[AddrBlockLinear] = ADDR_SW_LINEAR;\n\n                        if (pOut->resourceType == ADDR_RSRC_TEX_3D)\n                        {\n                            swMode[AddrBlockThick4KB]   = ADDR_SW_4KB_S_X;\n                            swMode[AddrBlockThin64KB]   = ADDR_SW_64KB_R_X;\n                            swMode[AddrBlockThick64KB]  = ADDR_SW_64KB_S_X;\n                            swMode[AddrBlockThin256KB]  = ADDR_SW_256KB_R_X;\n                            swMode[AddrBlockThick256KB] = ADDR_SW_256KB_S_X;\n                        }\n                        else\n                        {\n                            swMode[AddrBlockMicro]     = ADDR_SW_256B_D;\n                            swMode[AddrBlockThin4KB]   = ADDR_SW_4KB_D_X;\n                            swMode[AddrBlockThin64KB]  = ADDR_SW_64KB_D_X;\n                            swMode[AddrBlockThin256KB] = ADDR_SW_256KB_D_X;\n                        }\n\n                        UINT_64 padSize[AddrBlockMaxTiledType] = {};\n\n                        const UINT_32 ratioLow           = computeMinSize ? 1 : (pIn->flags.opt4space ? 3 : 2);\n                        const UINT_32 ratioHi            = computeMinSize ? 1 : (pIn->flags.opt4space ? 2 : 1);\n                        const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);\n                        UINT_32       minSizeBlk         = AddrBlockMicro;\n                        UINT_64       minSize            = 0;\n\n                        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n\n                        for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)\n                        {\n                            if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                            {\n                                localIn.swizzleMode = swMode[i];\n\n                                if (localIn.swizzleMode == ADDR_SW_LINEAR)\n                                {\n                                    returnCode = HwlComputeSurfaceInfoLinear(&localIn, &localOut);\n                                }\n                                else\n                                {\n                                    returnCode = HwlComputeSurfaceInfoTiled(&localIn, &localOut);\n                                }\n\n                                if (returnCode == ADDR_OK)\n                                {\n                                    padSize[i] = localOut.surfSize;\n\n                                    if ((minSize == 0) ||\n                                        Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))\n                                    {\n                                        minSize    = padSize[i];\n                                        minSizeBlk = i;\n                                    }\n                                }\n                                else\n                                {\n                                    ADDR_ASSERT_ALWAYS();\n                                    break;\n                                }\n                            }\n                        }\n\n                        if (pIn->memoryBudget > 1.0)\n                        {\n                            // If minimum size is given by swizzle mode with bigger-block type, then don't ever check\n                            // smaller-block type again in coming loop\n                            switch (minSizeBlk)\n                            {\n                                case AddrBlockThick256KB:\n                                    allowedBlockSet.gfx11.thin256KB = 0;\n                                case AddrBlockThin256KB:\n                                    allowedBlockSet.macroThick64KB = 0;\n                                case AddrBlockThick64KB:\n                                    allowedBlockSet.macroThin64KB = 0;\n                                case AddrBlockThin64KB:\n                                    allowedBlockSet.macroThick4KB = 0;\n                                case AddrBlockThick4KB:\n                                    allowedBlockSet.macroThin4KB = 0;\n                                case AddrBlockThin4KB:\n                                    allowedBlockSet.micro  = 0;\n                                case AddrBlockMicro:\n                                    allowedBlockSet.linear = 0;\n                                case AddrBlockLinear:\n                                    break;\n\n                                default:\n                                    ADDR_ASSERT_ALWAYS();\n                                    break;\n                            }\n\n                            for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)\n                            {\n                                if ((i != minSizeBlk) &&\n                                    Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                                {\n                                    if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)\n                                    {\n                                        // Clear the block type if the memory waste is unacceptable\n                                        allowedBlockSet.value &= ~(1u << (i - 1));\n                                    }\n                                }\n                            }\n\n                            // Remove linear block type if 2 or more block types are allowed\n                            if (IsPow2(allowedBlockSet.value) == FALSE)\n                            {\n                                allowedBlockSet.linear = 0;\n                            }\n\n                            // Select the biggest allowed block type\n                            minSizeBlk = Log2NonPow2(allowedBlockSet.value) + 1;\n\n                            if (minSizeBlk == static_cast<UINT_32>(AddrBlockMaxTiledType))\n                            {\n                                minSizeBlk = AddrBlockLinear;\n                            }\n                        }\n\n                        switch (minSizeBlk)\n                        {\n                            case AddrBlockLinear:\n                                allowedSwModeSet.value &= Gfx11LinearSwModeMask;\n                                break;\n\n                            case AddrBlockMicro:\n                                ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx11Blk256BSwModeMask;\n                                break;\n\n                            case AddrBlockThin4KB:\n                                ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx11Blk4KBSwModeMask;\n                                break;\n\n                            case AddrBlockThick4KB:\n                                ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx11Rsrc3dThick4KBSwModeMask;\n                                break;\n\n                            case AddrBlockThin64KB:\n                                allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?\n                                                          Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask;\n                                break;\n\n                            case AddrBlockThick64KB:\n                                ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx11Rsrc3dThick64KBSwModeMask;\n                                break;\n\n                            case AddrBlockThin256KB:\n                                allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?\n                                                          Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask;\n                                break;\n\n                            case AddrBlockThick256KB:\n                                ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                                allowedSwModeSet.value &= Gfx11Rsrc3dThick256KBSwModeMask;\n                                break;\n\n                            default:\n                                ADDR_ASSERT_ALWAYS();\n                                allowedSwModeSet.value = 0;\n                                break;\n                        }\n                    }\n\n                    // Block type should be determined.\n                    GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);\n                    ADDR_ASSERT(IsPow2(allowedBlockSet.value));\n\n                    ADDR2_SWTYPE_SET allowedSwSet = {};\n                    GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);\n\n                    // Determine swizzle type if there are 2 or more swizzle type candidates\n                    if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))\n                    {\n                        if (ElemLib::IsBlockCompressed(pIn->format))\n                        {\n                            if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;\n                            }\n                            else if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx11StandardSwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_R);\n                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;\n                            }\n                        }\n                        else if (ElemLib::IsMacroPixelPacked(pIn->format))\n                        {\n                            if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx11StandardSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_R);\n                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;\n                            }\n                        }\n                        else if (pIn->resourceType == ADDR_RSRC_TEX_3D)\n                        {\n                            if (pIn->flags.color && allowedSwSet.sw_R)\n                            {\n                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_S)\n                            {\n                                allowedSwModeSet.value &= Gfx11StandardSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT(allowedSwSet.sw_Z);\n                                allowedSwModeSet.value &= Gfx11ZSwModeMask;\n                            }\n                        }\n                        else\n                        {\n                            if (allowedSwSet.sw_R)\n                            {\n                                allowedSwModeSet.value &= Gfx11RenderSwModeMask;\n                            }\n                            else if (allowedSwSet.sw_D)\n                            {\n                                allowedSwModeSet.value &= Gfx11DisplaySwModeMask;\n                            }\n                            else if (allowedSwSet.sw_Z)\n                            {\n                                allowedSwModeSet.value &= Gfx11ZSwModeMask;\n                            }\n                            else\n                            {\n                                ADDR_ASSERT_ALWAYS();\n                            }\n                        }\n\n                        // Swizzle type should be determined.\n                        GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);\n                        ADDR_ASSERT(IsPow2(allowedSwSet.value));\n                    }\n\n                    // Determine swizzle mode now. Always select the \"largest\" swizzle mode for a given block type +\n                    // swizzle type combination. E.g, for AddrBlockThin64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's\n                    // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).\n                    pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));\n                }\n            }\n            else\n            {\n                // Invalid combination...\n                ADDR_ASSERT_ALWAYS();\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n        }\n        else\n        {\n            // Invalid combination...\n            ADDR_ASSERT_ALWAYS();\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlGetPossibleSwizzleModes\n*\n*   @brief\n*       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlGetPossibleSwizzleModes(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->flags.fmask)\n    {\n        // There is no FMASK for GFX11 ASICs.\n        ADDR_ASSERT_ALWAYS();\n\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        UINT_32 bpp    = pIn->bpp;\n        UINT_32 width  = Max(pIn->width, 1u);\n        UINT_32 height = Max(pIn->height, 1u);\n\n        // Set format to INVALID will skip this conversion\n        if (pIn->format != ADDR_FMT_INVALID)\n        {\n            ElemMode elemMode = ADDR_UNCOMPRESSED;\n            UINT_32 expandX, expandY;\n\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            bpp = GetElemLib()->GetBitsPerPixel(pIn->format,\n                &elemMode,\n                &expandX,\n                &expandY);\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                expandX,\n                expandY,\n                &bpp,\n                &basePitch,\n                &width,\n                &height);\n        }\n\n        const UINT_32 numSlices    = Max(pIn->numSlices, 1u);\n        const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);\n        const UINT_32 numSamples   = Max(pIn->numSamples, 1u);\n        const BOOL_32 msaa         = numSamples > 1;\n\n        // Pre sanity check on non swizzle mode parameters\n        ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};\n        localIn.flags = pIn->flags;\n        localIn.resourceType = pIn->resourceType;\n        localIn.format = pIn->format;\n        localIn.bpp = bpp;\n        localIn.width = width;\n        localIn.height = height;\n        localIn.numSlices = numSlices;\n        localIn.numMipLevels = numMipLevels;\n        localIn.numSamples = numSamples;\n        localIn.numFrags = numSamples;\n\n        if (ValidateNonSwModeParams(&localIn))\n        {\n            // Allow appropriate swizzle modes by default\n            ADDR2_SWMODE_SET allowedSwModeSet = {};\n            allowedSwModeSet.value |= Gfx11LinearSwModeMask | Gfx11Blk256BSwModeMask;\n            if (pIn->resourceType == ADDR_RSRC_TEX_3D)\n            {\n                allowedSwModeSet.value |= Gfx11Rsrc3dThick4KBSwModeMask  |\n                                          Gfx11Rsrc3dThin64KBSwModeMask  |\n                                          Gfx11Rsrc3dThick64KBSwModeMask |\n                                          Gfx11Rsrc3dThin256KBSwModeMask |\n                                          Gfx11Rsrc3dThick256KBSwModeMask;\n            }\n            else\n            {\n                allowedSwModeSet.value |= Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask | Gfx11Blk256KBSwModeMask;\n            }\n\n            // Filter out invalid swizzle mode(s) by image attributes and HW restrictions\n            switch (pIn->resourceType)\n            {\n            case ADDR_RSRC_TEX_1D:\n                allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;\n                break;\n\n            case ADDR_RSRC_TEX_2D:\n                allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;\n                break;\n\n            case ADDR_RSRC_TEX_3D:\n                allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;\n\n                if (pIn->flags.view3dAs2dArray)\n                {\n                    allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;\n                }\n                break;\n\n            default:\n                ADDR_ASSERT_ALWAYS();\n                allowedSwModeSet.value = 0;\n                break;\n            }\n\n            // TODO: figure out if following restrictions are correct on GFX11...\n            if (ElemLib::IsBlockCompressed(pIn->format) ||\n                ElemLib::IsMacroPixelPacked(pIn->format) ||\n                (bpp > 64) ||\n                (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))\n            {\n                allowedSwModeSet.value &= ~Gfx11ZSwModeMask;\n            }\n\n            if (pIn->format == ADDR_FMT_32_32_32)\n            {\n                allowedSwModeSet.value &= Gfx11LinearSwModeMask;\n            }\n\n            if (msaa)\n            {\n                allowedSwModeSet.value &= Gfx11MsaaSwModeMask;\n            }\n\n            if (pIn->flags.depth || pIn->flags.stencil)\n            {\n                allowedSwModeSet.value &= Gfx11ZSwModeMask;\n            }\n\n            if (pIn->flags.display)\n            {\n                allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);\n            }\n\n            if (allowedSwModeSet.value != 0)\n            {\n#if DEBUG\n                // Post sanity check, at least AddrLib should accept the output generated by its own\n                UINT_32 validateSwModeSet = allowedSwModeSet.value;\n\n                for (UINT_32 i = 0; validateSwModeSet != 0; i++)\n                {\n                    if (validateSwModeSet & 1)\n                    {\n                        localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);\n                        ADDR_ASSERT(ValidateSwModeParams(&localIn));\n                    }\n\n                    validateSwModeSet >>= 1;\n                }\n#endif\n\n                pOut->resourceType = pIn->resourceType;\n                pOut->clientPreferredSwSet = pIn->preferredSwSet;\n\n                if (pOut->clientPreferredSwSet.value == 0)\n                {\n                    pOut->clientPreferredSwSet.value = AddrSwSetAll;\n                }\n\n                if (pIn->flags.needEquation)\n                {\n                    UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :\n                                                                        ADDR_MAX_LEGACY_EQUATION_COMP;\n                    FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);\n                }\n\n                pOut->validSwModeSet = allowedSwModeSet;\n                pOut->canXor = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;\n            }\n            else\n            {\n                // Invalid combination...\n                ADDR_ASSERT_ALWAYS();\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n        }\n        else\n        {\n            // Invalid combination...\n            ADDR_ASSERT_ALWAYS();\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlGetAllowedBlockSet\n*\n*   @brief\n*       Returns the set of allowed block sizes given the allowed swizzle modes and resource type\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedBlockSet(\n    ADDR2_SWMODE_SET allowedSwModeSet,  ///< [in] allowed swizzle modes\n    AddrResourceType rsrcType,          ///< [in] resource type\n    ADDR2_BLOCK_SET* pAllowedBlockSet   ///< [out] allowed block sizes\n    ) const\n{\n    ADDR2_BLOCK_SET allowedBlockSet = {};\n\n    allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx11Blk256BSwModeMask) ? TRUE : FALSE;\n    allowedBlockSet.linear = (allowedSwModeSet.value & Gfx11LinearSwModeMask)  ? TRUE : FALSE;\n\n    if (rsrcType == ADDR_RSRC_TEX_3D)\n    {\n        allowedBlockSet.macroThick4KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThick4KBSwModeMask)   ? TRUE : FALSE;\n        allowedBlockSet.macroThin64KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThin64KBSwModeMask)   ? TRUE : FALSE;\n        allowedBlockSet.macroThick64KB   = (allowedSwModeSet.value & Gfx11Rsrc3dThick64KBSwModeMask)  ? TRUE : FALSE;\n        allowedBlockSet.gfx11.thin256KB  = (allowedSwModeSet.value & Gfx11Rsrc3dThin256KBSwModeMask)  ? TRUE : FALSE;\n        allowedBlockSet.gfx11.thick256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick256KBSwModeMask) ? TRUE : FALSE;\n    }\n    else\n    {\n        allowedBlockSet.macroThin4KB    = (allowedSwModeSet.value & Gfx11Blk4KBSwModeMask)   ? TRUE : FALSE;\n        allowedBlockSet.macroThin64KB   = (allowedSwModeSet.value & Gfx11Blk64KBSwModeMask)  ? TRUE : FALSE;\n        allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Blk256KBSwModeMask) ? TRUE : FALSE;\n    }\n\n    *pAllowedBlockSet = allowedBlockSet;\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlGetAllowedSwSet\n*\n*   @brief\n*       Returns the set of allowed swizzle types given the allowed swizzle modes\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedSwSet(\n    ADDR2_SWMODE_SET  allowedSwModeSet, ///< [in] allowed swizzle modes\n    ADDR2_SWTYPE_SET* pAllowedSwSet     ///< [out] allowed swizzle types\n    ) const\n{\n    ADDR2_SWTYPE_SET allowedSwSet = {};\n\n    allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx11ZSwModeMask)        ? TRUE : FALSE;\n    allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx11StandardSwModeMask) ? TRUE : FALSE;\n    allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx11DisplaySwModeMask)  ? TRUE : FALSE;\n    allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx11RenderSwModeMask)   ? TRUE : FALSE;\n\n    *pAllowedSwSet = allowedSwSet;\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeStereoInfo\n*\n*   @brief\n*       Compute height alignment and right eye pipeBankXor for stereo surface\n*\n*   @return\n*       Error code\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::ComputeStereoInfo(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,        ///< Compute surface info\n    UINT_32*                                pAlignY,    ///< Stereo requested additional alignment in Y\n    UINT_32*                                pRightXor   ///< Right eye xor\n    ) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    *pRightXor = 0;\n\n    if (IsNonPrtXor(pIn->swizzleMode))\n    {\n        const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 rsrcType    = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swMode      = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 eqIndex     = m_equationLookupTable[rsrcType][swMode][elemLog2];\n\n        if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n        {\n            UINT_32 yMax     = 0;\n            UINT_32 yPosMask = 0;\n\n            // First get \"max y bit\"\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)\n            {\n                ADDR_ASSERT(m_equationTable[eqIndex].addr[i].valid == 1);\n\n                if ((m_equationTable[eqIndex].addr[i].channel == 1) &&\n                    (m_equationTable[eqIndex].addr[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].addr[i].index;\n                }\n\n                if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&\n                    (m_equationTable[eqIndex].xor1[i].channel == 1) &&\n                    (m_equationTable[eqIndex].xor1[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].xor1[i].index;\n                }\n\n                if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&\n                    (m_equationTable[eqIndex].xor2[i].channel == 1) &&\n                    (m_equationTable[eqIndex].xor2[i].index > yMax))\n                {\n                    yMax = m_equationTable[eqIndex].xor2[i].index;\n                }\n            }\n\n            // Then loop again for populating a position mask of \"max Y bit\"\n            for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)\n            {\n                if ((m_equationTable[eqIndex].addr[i].channel == 1) &&\n                    (m_equationTable[eqIndex].addr[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n                else if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&\n                         (m_equationTable[eqIndex].xor1[i].channel == 1) &&\n                         (m_equationTable[eqIndex].xor1[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n                else if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&\n                         (m_equationTable[eqIndex].xor2[i].channel == 1) &&\n                         (m_equationTable[eqIndex].xor2[i].index == yMax))\n                {\n                    yPosMask |= 1u << i;\n                }\n            }\n\n            const UINT_32 additionalAlign = 1 << yMax;\n\n            if (additionalAlign >= *pAlignY)\n            {\n                *pAlignY = additionalAlign;\n\n                const UINT_32 alignedHeight = PowTwoAlign(pIn->height, additionalAlign);\n\n                if ((alignedHeight >> yMax) & 1)\n                {\n                    *pRightXor = yPosMask >> m_pipeInterleaveLog2;\n                }\n            }\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSurfaceInfoTiled\n*\n*   @brief\n*       Internal function to calculate alignment for tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    // Mip chain dimesion and epitch has no meaning in GFX11, set to default value\n    pOut->mipChainPitch    = 0;\n    pOut->mipChainHeight   = 0;\n    pOut->mipChainSlice    = 0;\n    pOut->epitchIsHeight   = FALSE;\n\n    // Following information will be provided in ComputeSurfaceInfoMacroTiled() if necessary\n    pOut->mipChainInTail   = FALSE;\n    pOut->firstMipIdInTail = pIn->numMipLevels;\n\n    if (IsBlock256b(pIn->swizzleMode))\n    {\n        ret = ComputeSurfaceInfoMicroTiled(pIn, pOut);\n    }\n    else\n    {\n        ret = ComputeSurfaceInfoMacroTiled(pIn, pOut);\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeSurfaceInfoMicroTiled\n*\n*   @brief\n*       Internal function to calculate alignment for micro tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMicroTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret = ComputeBlockDimensionForSurf(&pOut->blockWidth,\n                                                         &pOut->blockHeight,\n                                                         &pOut->blockSlices,\n                                                         pIn->bpp,\n                                                         pIn->numSamples,\n                                                         pIn->resourceType,\n                                                         pIn->swizzleMode);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 blockSize = GetBlockSize(pIn->swizzleMode);\n\n        pOut->pitch     = PowTwoAlign(pIn->width,  pOut->blockWidth);\n        pOut->height    = PowTwoAlign(pIn->height, pOut->blockHeight);\n        pOut->numSlices = pIn->numSlices;\n        pOut->baseAlign = blockSize;\n\n        if (pIn->numMipLevels > 1)\n        {\n            const UINT_32 mip0Width    = pIn->width;\n            const UINT_32 mip0Height   = pIn->height;\n            UINT_64       mipSliceSize = 0;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(mip0Width, mip0Height, 1, i, &mipWidth, &mipHeight);\n\n                const UINT_32 mipActualWidth  = PowTwoAlign(mipWidth,  pOut->blockWidth);\n                const UINT_32 mipActualHeight = PowTwoAlign(mipHeight, pOut->blockHeight);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].pitch            = mipActualWidth;\n                    pOut->pMipInfo[i].height           = mipActualHeight;\n                    pOut->pMipInfo[i].depth            = 1;\n                    pOut->pMipInfo[i].offset           = mipSliceSize;\n                    pOut->pMipInfo[i].mipTailOffset    = 0;\n                    pOut->pMipInfo[i].macroBlockOffset = mipSliceSize;\n                }\n\n                mipSliceSize += mipActualWidth * mipActualHeight * (pIn->bpp >> 3);\n            }\n\n            pOut->sliceSize = mipSliceSize;\n            pOut->surfSize  = mipSliceSize * pOut->numSlices;\n        }\n        else\n        {\n            pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3);\n            pOut->surfSize  = pOut->sliceSize * pOut->numSlices;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].pitch            = pOut->pitch;\n                pOut->pMipInfo[0].height           = pOut->height;\n                pOut->pMipInfo[0].depth            = 1;\n                pOut->pMipInfo[0].offset           = 0;\n                pOut->pMipInfo[0].mipTailOffset    = 0;\n                pOut->pMipInfo[0].macroBlockOffset = 0;\n            }\n        }\n\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeSurfaceInfoMacroTiled\n*\n*   @brief\n*       Internal function to calculate alignment for macro tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMacroTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,\n                                                                &pOut->blockHeight,\n                                                                &pOut->blockSlices,\n                                                                pIn->bpp,\n                                                                pIn->numSamples,\n                                                                pIn->resourceType,\n                                                                pIn->swizzleMode);\n\n    if (returnCode == ADDR_OK)\n    {\n        UINT_32 heightAlign = pOut->blockHeight;\n\n        if (pIn->flags.qbStereo)\n        {\n            UINT_32 rightXor = 0;\n\n            returnCode = ComputeStereoInfo(pIn, &heightAlign, &rightXor);\n\n            if (returnCode == ADDR_OK)\n            {\n                pOut->pStereoInfo->rightSwizzle = rightXor;\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n            const UINT_32 blockSize     = 1 << blockSizeLog2;\n\n            pOut->pitch     = PowTwoAlign(pIn->width,     pOut->blockWidth);\n            pOut->height    = PowTwoAlign(pIn->height,    heightAlign);\n            pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);\n            pOut->baseAlign = blockSize;\n\n            if (pIn->numMipLevels > 1)\n            {\n                const Dim3d  tailMaxDim         = GetMipTailDim(pIn->resourceType,\n                                                                pIn->swizzleMode,\n                                                                pOut->blockWidth,\n                                                                pOut->blockHeight,\n                                                                pOut->blockSlices);\n                const UINT_32 mip0Width         = pIn->width;\n                const UINT_32 mip0Height        = pIn->height;\n                const BOOL_32 isThin            = IsThin(pIn->resourceType, pIn->swizzleMode);\n                const UINT_32 mip0Depth         = isThin ? 1 : pIn->numSlices;\n                const UINT_32 maxMipsInTail     = GetMaxNumMipsInTail(blockSizeLog2, isThin);\n                const UINT_32 index             = Log2(pIn->bpp >> 3);\n                UINT_32       firstMipInTail    = pIn->numMipLevels;\n                UINT_64       mipChainSliceSize = 0;\n                UINT_64       mipSize[MaxMipLevels];\n                UINT_64       mipSliceSize[MaxMipLevels];\n\n                // For htile, we need to make z16 and stencil enter the mip tail at the same time as z32 would\n                Dim3d fixedTailMaxDim = tailMaxDim;\n                if (IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))\n                {\n                    fixedTailMaxDim.w /= Block256_2d[index].w / Block256_2d[2].w;\n                    fixedTailMaxDim.h /= Block256_2d[index].w / Block256_2d[2].w;\n                }\n\n                for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n                {\n                    UINT_32 mipWidth, mipHeight, mipDepth;\n\n                    GetMipSize(mip0Width, mip0Height, mip0Depth, i, &mipWidth, &mipHeight, &mipDepth);\n\n                    if (IsInMipTail(fixedTailMaxDim, maxMipsInTail, mipWidth, mipHeight, pIn->numMipLevels - i))\n                    {\n                        firstMipInTail     = i;\n                        mipChainSliceSize += blockSize / pOut->blockSlices;\n                        break;\n                    }\n                    else\n                    {\n                        const UINT_32 pitch     = PowTwoAlign(mipWidth,  pOut->blockWidth);\n                        const UINT_32 height    = PowTwoAlign(mipHeight, pOut->blockHeight);\n                        const UINT_32 depth     = PowTwoAlign(mipDepth,  pOut->blockSlices);\n                        const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height * (pIn->bpp >> 3);\n\n                        mipSize[i]         = sliceSize * depth;\n                        mipSliceSize[i]    = sliceSize * pOut->blockSlices;\n                        mipChainSliceSize += sliceSize;\n\n                        if (pOut->pMipInfo != NULL)\n                        {\n                            pOut->pMipInfo[i].pitch  = pitch;\n                            pOut->pMipInfo[i].height = height;\n                            pOut->pMipInfo[i].depth  = depth;\n                        }\n                    }\n                }\n\n                pOut->sliceSize        = mipChainSliceSize;\n                pOut->surfSize         = mipChainSliceSize * pOut->numSlices;\n                pOut->mipChainInTail   = (firstMipInTail == 0) ? TRUE : FALSE;\n                pOut->firstMipIdInTail = firstMipInTail;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    UINT_64 offset         = 0;\n                    UINT_64 macroBlkOffset = 0;\n                    UINT_32 tailMaxDepth   = 0;\n\n                    if (firstMipInTail != pIn->numMipLevels)\n                    {\n                        UINT_32 mipWidth, mipHeight;\n\n                        GetMipSize(mip0Width, mip0Height, mip0Depth, firstMipInTail,\n                                   &mipWidth, &mipHeight, &tailMaxDepth);\n\n                        offset         = blockSize * PowTwoAlign(tailMaxDepth, pOut->blockSlices) / pOut->blockSlices;\n                        macroBlkOffset = blockSize;\n                    }\n\n                    for (INT_32 i = firstMipInTail - 1; i >= 0; i--)\n                    {\n                        pOut->pMipInfo[i].offset           = offset;\n                        pOut->pMipInfo[i].macroBlockOffset = macroBlkOffset;\n                        pOut->pMipInfo[i].mipTailOffset    = 0;\n\n                        offset         += mipSize[i];\n                        macroBlkOffset += mipSliceSize[i];\n                    }\n\n                    UINT_32 pitch  = tailMaxDim.w;\n                    UINT_32 height = tailMaxDim.h;\n                    UINT_32 depth  = isThin ? 1 : PowTwoAlign(tailMaxDepth, Block256_3d[index].d);\n\n                    tailMaxDepth = isThin ? 1 : (depth / Block256_3d[index].d);\n\n                    for (UINT_32 i = firstMipInTail; i < pIn->numMipLevels; i++)\n                    {\n                        const UINT_32 m         = maxMipsInTail - 1 - (i - firstMipInTail);\n                        const UINT_32 mipOffset = (m > 6) ? (16 << m) : (m << 8);\n\n                        pOut->pMipInfo[i].offset           = mipOffset * tailMaxDepth;\n                        pOut->pMipInfo[i].mipTailOffset    = mipOffset;\n                        pOut->pMipInfo[i].macroBlockOffset = 0;\n\n                        pOut->pMipInfo[i].pitch  = pitch;\n                        pOut->pMipInfo[i].height = height;\n                        pOut->pMipInfo[i].depth  = depth;\n\n                        UINT_32 mipX = ((mipOffset >> 9)  & 1)  |\n                                       ((mipOffset >> 10) & 2)  |\n                                       ((mipOffset >> 11) & 4)  |\n                                       ((mipOffset >> 12) & 8)  |\n                                       ((mipOffset >> 13) & 16) |\n                                       ((mipOffset >> 14) & 32);\n                        UINT_32 mipY = ((mipOffset >> 8)  & 1)  |\n                                       ((mipOffset >> 9)  & 2)  |\n                                       ((mipOffset >> 10) & 4)  |\n                                       ((mipOffset >> 11) & 8)  |\n                                       ((mipOffset >> 12) & 16) |\n                                       ((mipOffset >> 13) & 32);\n\n                        if (blockSizeLog2 & 1)\n                        {\n                            const UINT_32 temp = mipX;\n                            mipX = mipY;\n                            mipY = temp;\n\n                            if (index & 1)\n                            {\n                                mipY = (mipY << 1) | (mipX & 1);\n                                mipX = mipX >> 1;\n                            }\n                        }\n\n                        if (isThin)\n                        {\n                            pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_2d[index].w;\n                            pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_2d[index].h;\n                            pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                            pitch  = Max(pitch  >> 1, Block256_2d[index].w);\n                            height = Max(height >> 1, Block256_2d[index].h);\n                            depth  = 1;\n                        }\n                        else\n                        {\n                            pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_3d[index].w;\n                            pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_3d[index].h;\n                            pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                            pitch  = Max(pitch  >> 1, Block256_3d[index].w);\n                            height = Max(height >> 1, Block256_3d[index].h);\n                            depth  = PowTwoAlign(Max(depth  >> 1, 1u), Block256_3d[index].d);\n                        }\n                    }\n                }\n            }\n            else\n            {\n                pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3) * pIn->numSamples;\n                pOut->surfSize  = pOut->sliceSize * pOut->numSlices;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].pitch            = pOut->pitch;\n                    pOut->pMipInfo[0].height           = pOut->height;\n                    pOut->pMipInfo[0].depth            = IsTex3d(pIn->resourceType)? pOut->numSlices : 1;\n                    pOut->pMipInfo[0].offset           = 0;\n                    pOut->pMipInfo[0].mipTailOffset    = 0;\n                    pOut->pMipInfo[0].macroBlockOffset = 0;\n                    pOut->pMipInfo[0].mipTailCoordX    = 0;\n                    pOut->pMipInfo[0].mipTailCoordY    = 0;\n                    pOut->pMipInfo[0].mipTailCoordZ    = 0;\n                }\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE ret;\n\n    if (IsBlock256b(pIn->swizzleMode))\n    {\n        ret = ComputeSurfaceAddrFromCoordMicroTiled(pIn, pOut);\n    }\n    else\n    {\n        ret = ComputeSurfaceAddrFromCoordMacroTiled(pIn, pOut);\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeOffsetFromEquation\n*\n*   @brief\n*       Compute offset from equation\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::ComputeOffsetFromEquation(\n    const ADDR_EQUATION* pEq,   ///< Equation\n    UINT_32              x,     ///< x coord in bytes\n    UINT_32              y,     ///< y coord in pixel\n    UINT_32              z      ///< z coord in slice\n    ) const\n{\n    UINT_32 offset = 0;\n\n    for (UINT_32 i = 0; i < pEq->numBits; i++)\n    {\n        UINT_32 v = 0;\n\n        for (UINT_32 c = 0; c < pEq->numBitComponents; c++)\n        {\n            if (pEq->comps[c][i].valid)\n            {\n                if (pEq->comps[c][i].channel == 0)\n                {\n                    v ^= (x >> pEq->comps[c][i].index) & 1;\n                }\n                else if (pEq->comps[c][i].channel == 1)\n                {\n                    v ^= (y >> pEq->comps[c][i].index) & 1;\n                }\n                else\n                {\n                    ADDR_ASSERT(pEq->comps[c][i].channel == 2);\n                    v ^= (z >> pEq->comps[c][i].index) & 1;\n                }\n            }\n        }\n\n        offset |= (v << i);\n    }\n\n    return offset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeOffsetFromSwizzlePattern\n*\n*   @brief\n*       Compute offset from swizzle pattern\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::ComputeOffsetFromSwizzlePattern(\n    const UINT_64* pPattern,    ///< Swizzle pattern\n    UINT_32        numBits,     ///< Number of bits in pattern\n    UINT_32        x,           ///< x coord in pixel\n    UINT_32        y,           ///< y coord in pixel\n    UINT_32        z,           ///< z coord in slice\n    UINT_32        s            ///< sample id\n    ) const\n{\n    UINT_32                 offset          = 0;\n    const ADDR_BIT_SETTING* pSwizzlePattern = reinterpret_cast<const ADDR_BIT_SETTING*>(pPattern);\n\n    for (UINT_32 i = 0; i < numBits; i++)\n    {\n        UINT_32 v = 0;\n\n        if (pSwizzlePattern[i].x != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].x;\n            UINT_32 xBits = x;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= xBits & 1;\n                }\n\n                xBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].y != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].y;\n            UINT_32 yBits = y;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= yBits & 1;\n                }\n\n                yBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].z != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].z;\n            UINT_32 zBits = z;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= zBits & 1;\n                }\n\n                zBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        if (pSwizzlePattern[i].s != 0)\n        {\n            UINT_16 mask  = pSwizzlePattern[i].s;\n            UINT_32 sBits = s;\n\n            while (mask != 0)\n            {\n                if (mask & 1)\n                {\n                    v ^= sBits & 1;\n                }\n\n                sBits >>= 1;\n                mask  >>= 1;\n            }\n        }\n\n        offset |= (v << i);\n    }\n\n    return offset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetSwizzlePatternInfo\n*\n*   @brief\n*       Get swizzle pattern\n*\n*   @return\n*       Swizzle pattern information\n************************************************************************************************************************\n*/\nconst ADDR_SW_PATINFO* Gfx11Lib::GetSwizzlePatternInfo(\n    AddrSwizzleMode  swizzleMode,       ///< Swizzle mode\n    AddrResourceType resourceType,      ///< Resource type\n    UINT_32          elemLog2,          ///< Element size in bytes log2\n    UINT_32          numFrag            ///< Number of fragment\n    ) const\n{\n    const UINT_32          index       = IsXor(swizzleMode) ? (m_colorBaseIndex + elemLog2) : elemLog2;\n    const ADDR_SW_PATINFO* patInfo     = NULL;\n    const UINT_32          swizzleMask = 1 << swizzleMode;\n    const BOOL_32          isBlock256k = IsBlock256kb(swizzleMode);\n    const BOOL_32          isBlock64K  = IsBlock64kb(swizzleMode);\n\n    if (IsLinear(swizzleMode) == FALSE)\n    {\n        if (resourceType == ADDR_RSRC_TEX_3D)\n        {\n            ADDR_ASSERT(numFrag == 1);\n\n            if ((swizzleMask & Gfx11Rsrc3dSwModeMask) != 0)\n            {\n                if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))\n                {\n                    if (isBlock256k)\n                    {\n                        ADDR_ASSERT((swizzleMode == ADDR_SW_256KB_Z_X) || (swizzleMode == ADDR_SW_256KB_R_X));\n                        patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;\n                    }\n                    else if (isBlock64K)\n                    {\n                        ADDR_ASSERT((swizzleMode == ADDR_SW_64KB_Z_X) || (swizzleMode == ADDR_SW_64KB_R_X));\n                        patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n                else if (IsDisplaySwizzle(resourceType, swizzleMode))\n                {\n                    if (isBlock256k)\n                    {\n                        ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);\n                        // patInfo = GFX11_SW_256K_D3_X_PATINFO;\n                    }\n                    else if (isBlock64K)\n                    {\n                        ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_D_X);\n                        patInfo = GFX11_SW_64K_D3_X_PATINFO;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n                else\n                {\n                    ADDR_ASSERT(IsStandardSwizzle(resourceType, swizzleMode));\n\n                    if (isBlock256k)\n                    {\n                        ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_S_X);\n                        patInfo = GFX11_SW_256K_S3_X_PATINFO;\n                    }\n                    else if (isBlock64K)\n                    {\n                        if (swizzleMode == ADDR_SW_64KB_S)\n                        {\n                            patInfo = GFX11_SW_64K_S3_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_S_X)\n                        {\n                            patInfo = GFX11_SW_64K_S3_X_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_S_T)\n                        {\n                            patInfo = GFX11_SW_64K_S3_T_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT_ALWAYS();\n                        }\n                    }\n                    else if (IsBlock4kb(swizzleMode))\n                    {\n                        if (swizzleMode == ADDR_SW_4KB_S)\n                        {\n                            patInfo = GFX11_SW_4K_S3_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_4KB_S_X)\n                        {\n                            patInfo = GFX11_SW_4K_S3_X_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT_ALWAYS();\n                        }\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n            }\n        }\n        else\n        {\n            if ((swizzleMask & Gfx11Rsrc2dSwModeMask) != 0)\n            {\n                if (IsBlock256b(swizzleMode))\n                {\n                    ADDR_ASSERT(swizzleMode == ADDR_SW_256B_D);\n                    patInfo = GFX11_SW_256_D_PATINFO;\n                }\n                else if (IsBlock4kb(swizzleMode))\n                {\n                    if (swizzleMode == ADDR_SW_4KB_D)\n                    {\n                        patInfo = GFX11_SW_4K_D_PATINFO;\n                    }\n                    else if (swizzleMode == ADDR_SW_4KB_D_X)\n                    {\n                        patInfo = GFX11_SW_4K_D_X_PATINFO;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n                else if (isBlock64K)\n                {\n                    if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))\n                    {\n                        if (numFrag == 1)\n                        {\n                            patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;\n                        }\n                        else if (numFrag == 2)\n                        {\n                            patInfo = GFX11_SW_64K_ZR_X_2xaa_PATINFO;\n                        }\n                        else if (numFrag == 4)\n                        {\n                            patInfo = GFX11_SW_64K_ZR_X_4xaa_PATINFO;\n                        }\n                        else if (numFrag == 8)\n                        {\n                            patInfo = GFX11_SW_64K_ZR_X_8xaa_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT_ALWAYS();\n                        }\n                    }\n                    else if (IsDisplaySwizzle(resourceType, swizzleMode))\n                    {\n                        if (swizzleMode == ADDR_SW_64KB_D)\n                        {\n                            patInfo = GFX11_SW_64K_D_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_D_X)\n                        {\n                            patInfo = GFX11_SW_64K_D_X_PATINFO;\n                        }\n                        else if (swizzleMode == ADDR_SW_64KB_D_T)\n                        {\n                            patInfo = GFX11_SW_64K_D_T_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT_ALWAYS();\n                        }\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n                else if (isBlock256k)\n                {\n                    if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))\n                    {\n                        if (numFrag == 1)\n                        {\n                            patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;\n                        }\n                        else if (numFrag == 2)\n                        {\n                            patInfo = GFX11_SW_256K_ZR_X_2xaa_PATINFO;\n                        }\n                        else if (numFrag == 4)\n                        {\n                            patInfo = GFX11_SW_256K_ZR_X_4xaa_PATINFO;\n                        }\n                        else if (numFrag == 8)\n                        {\n                            patInfo = GFX11_SW_256K_ZR_X_8xaa_PATINFO;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT_ALWAYS();\n                        }\n                    }\n                    else if (IsDisplaySwizzle(resourceType, swizzleMode))\n                    {\n                        ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);\n                        patInfo = GFX11_SW_256K_D_X_PATINFO;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n                else\n                {\n                    ADDR_ASSERT_ALWAYS();\n                }\n            }\n        }\n    }\n\n    return (patInfo != NULL) ? &patInfo[index] : NULL;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for micro tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n    ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];\n\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pIn->resourceType;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unalignedWidth,  1u);\n    localIn.height       = Max(pIn->unalignedHeight, 1u);\n    localIn.numSlices    = Max(pIn->numSlices,       1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels,    1u);\n    localIn.numSamples   = Max(pIn->numSamples,      1u);\n    localIn.numFrags     = localIn.numSamples;\n    localOut.pMipInfo    = mipInfo;\n\n    ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMicroTiled(&localIn, &localOut);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);\n        const UINT_32 rsrcType = static_cast<UINT_32>(pIn->resourceType) - 1;\n        const UINT_32 swMode   = static_cast<UINT_32>(pIn->swizzleMode);\n        const UINT_32 eqIndex  = m_equationLookupTable[rsrcType][swMode][elemLog2];\n\n        if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n        {\n            const UINT_32 pb           = mipInfo[pIn->mipId].pitch / localOut.blockWidth;\n            const UINT_32 yb           = pIn->y / localOut.blockHeight;\n            const UINT_32 xb           = pIn->x / localOut.blockWidth;\n            const UINT_32 blockIndex   = yb * pb + xb;\n            const UINT_32 blockSize    = 256;\n            const UINT_32 blk256Offset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                   pIn->x << elemLog2,\n                                                                   pIn->y,\n                                                                   0);\n            pOut->addr = localOut.sliceSize * pIn->slice +\n                         mipInfo[pIn->mipId].macroBlockOffset +\n                         (blockIndex * blockSize) +\n                         blk256Offset;\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for macro tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n    ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];\n\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pIn->resourceType;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unalignedWidth,  1u);\n    localIn.height       = Max(pIn->unalignedHeight, 1u);\n    localIn.numSlices    = Max(pIn->numSlices,       1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels,    1u);\n    localIn.numSamples   = Max(pIn->numSamples,      1u);\n    localIn.numFrags     = localIn.numSamples;\n    localOut.pMipInfo    = mipInfo;\n\n    ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMacroTiled(&localIn, &localOut);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 blkMask     = (1 << blkSizeLog2) - 1;\n        const UINT_32 pipeMask    = (1 << m_pipesLog2) - 1;\n        const UINT_32 bankMask    = ((1 << GetBankXorBits(blkSizeLog2)) - 1) << (m_pipesLog2 + ColumnBits);\n        const UINT_32 pipeBankXor = IsXor(pIn->swizzleMode) ?\n                                    (((pIn->pipeBankXor & (pipeMask | bankMask)) << m_pipeInterleaveLog2) & blkMask) : 0;\n\n        if (localIn.numSamples > 1)\n        {\n            const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,\n                                                                    pIn->resourceType,\n                                                                    elemLog2,\n                                                                    localIn.numSamples);\n\n            if (pPatInfo != NULL)\n            {\n                const UINT_32 pb     = localOut.pitch / localOut.blockWidth;\n                const UINT_32 yb     = pIn->y / localOut.blockHeight;\n                const UINT_32 xb     = pIn->x / localOut.blockWidth;\n                const UINT_64 blkIdx = yb * pb + xb;\n\n                ADDR_BIT_SETTING fullSwizzlePattern[20];\n                GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n                const UINT_32 blkOffset =\n                    ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),\n                                                    blkSizeLog2,\n                                                    pIn->x,\n                                                    pIn->y,\n                                                    pIn->slice,\n                                                    pIn->sample);\n\n                pOut->addr = (localOut.sliceSize * pIn->slice) +\n                             (blkIdx << blkSizeLog2) +\n                             (blkOffset ^ pipeBankXor);\n            }\n            else\n            {\n                ret = ADDR_INVALIDPARAMS;\n            }\n        }\n        else\n        {\n            const UINT_32 rsrcIdx = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? 1 : 0;\n            const UINT_32 swMode  = static_cast<UINT_32>(pIn->swizzleMode);\n            const UINT_32 eqIndex = m_equationLookupTable[rsrcIdx][swMode][elemLog2];\n\n            if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n            {\n                const BOOL_32 inTail    = (mipInfo[pIn->mipId].mipTailOffset != 0) ? TRUE : FALSE;\n                const BOOL_32 isThin    = IsThin(pIn->resourceType, pIn->swizzleMode);\n                const UINT_64 sliceSize = isThin ? localOut.sliceSize : (localOut.sliceSize * localOut.blockSlices);\n                const UINT_32 sliceId   = isThin ? pIn->slice : (pIn->slice / localOut.blockSlices);\n                const UINT_32 x         = inTail ? (pIn->x     + mipInfo[pIn->mipId].mipTailCoordX) : pIn->x;\n                const UINT_32 y         = inTail ? (pIn->y     + mipInfo[pIn->mipId].mipTailCoordY) : pIn->y;\n                const UINT_32 z         = inTail ? (pIn->slice + mipInfo[pIn->mipId].mipTailCoordZ) : pIn->slice;\n                const UINT_32 pb        = mipInfo[pIn->mipId].pitch / localOut.blockWidth;\n                const UINT_32 yb        = pIn->y / localOut.blockHeight;\n                const UINT_32 xb        = pIn->x / localOut.blockWidth;\n                const UINT_64 blkIdx    = yb * pb + xb;\n                const UINT_32 blkOffset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                    x << elemLog2,\n                                                                    y,\n                                                                    z);\n                pOut->addr = sliceSize * sliceId +\n                             mipInfo[pIn->mipId].macroBlockOffset +\n                             (blkIdx << blkSizeLog2) +\n                             (blkOffset ^ pipeBankXor);\n            }\n            else\n            {\n                ret = ADDR_INVALIDPARAMS;\n            }\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeMaxBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments\n*   @return\n*       maximum alignments\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::HwlComputeMaxBaseAlignments() const\n{\n    return Size256K;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeMaxMetaBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments for metadata\n*   @return\n*       maximum alignments for metadata\n************************************************************************************************************************\n*/\nUINT_32 Gfx11Lib::HwlComputeMaxMetaBaseAlignments() const\n{\n    Dim3d metaBlk;\n\n    // Max base alignment for Htile\n    const AddrSwizzleMode ValidSwizzleModeForHtile[] =\n    {\n        ADDR_SW_64KB_Z_X,\n        ADDR_SW_256KB_Z_X,\n    };\n\n    UINT_32 maxBaseAlignHtile = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForHtile) / sizeof(ValidSwizzleModeForHtile[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < 3; bppLog2++)\n        {\n            for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)\n            {\n                const UINT_32 metaBlkSizeHtile = GetMetaBlkSize(Gfx11DataDepthStencil,\n                                                                ADDR_RSRC_TEX_2D,\n                                                                ValidSwizzleModeForHtile[swIdx],\n                                                                bppLog2,\n                                                                numFragLog2,\n                                                                TRUE,\n                                                                &metaBlk);\n\n                maxBaseAlignHtile = Max(maxBaseAlignHtile, metaBlkSizeHtile);\n            }\n        }\n    }\n\n    // Max base alignment for 2D Dcc\n    // swizzle mode support DCC...\n    const AddrSwizzleMode ValidSwizzleModeForDcc2D[] =\n    {\n        ADDR_SW_64KB_R_X,\n        ADDR_SW_256KB_R_X,\n    };\n\n    UINT_32 maxBaseAlignDcc2D = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc2D) / sizeof(ValidSwizzleModeForDcc2D[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)\n        {\n            for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)\n            {\n                const UINT_32 metaBlkSize2D = GetMetaBlkSize(Gfx11DataColor,\n                                                             ADDR_RSRC_TEX_2D,\n                                                             ValidSwizzleModeForDcc2D[swIdx],\n                                                             bppLog2,\n                                                             numFragLog2,\n                                                             TRUE,\n                                                             &metaBlk);\n\n                maxBaseAlignDcc2D = Max(maxBaseAlignDcc2D, metaBlkSize2D);\n            }\n        }\n    }\n\n    // Max base alignment for 3D Dcc\n    const AddrSwizzleMode ValidSwizzleModeForDcc3D[] =\n    {\n        ADDR_SW_64KB_S_X,\n        ADDR_SW_64KB_D_X,\n        ADDR_SW_64KB_R_X,\n        ADDR_SW_256KB_S_X,\n        ADDR_SW_256KB_D_X,\n        ADDR_SW_256KB_R_X,\n    };\n\n    UINT_32 maxBaseAlignDcc3D = 0;\n\n    for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc3D) / sizeof(ValidSwizzleModeForDcc3D[0]); swIdx++)\n    {\n        for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)\n        {\n            const UINT_32 metaBlkSize3D = GetMetaBlkSize(Gfx11DataColor,\n                                                         ADDR_RSRC_TEX_3D,\n                                                         ValidSwizzleModeForDcc3D[swIdx],\n                                                         bppLog2,\n                                                         0,\n                                                         TRUE,\n                                                         &metaBlk);\n\n            maxBaseAlignDcc3D = Max(maxBaseAlignDcc3D, metaBlkSize3D);\n        }\n    }\n\n    return Max(maxBaseAlignHtile, Max(maxBaseAlignDcc2D, maxBaseAlignDcc3D));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetMetaElementSizeLog2\n*\n*   @brief\n*       Gets meta data element size log2\n*   @return\n*       Meta data element size log2\n************************************************************************************************************************\n*/\nINT_32 Gfx11Lib::GetMetaElementSizeLog2(\n    Gfx11DataType dataType) ///< Data surface type\n{\n    INT_32 elemSizeLog2 = 0;\n\n    if (dataType == Gfx11DataColor)\n    {\n        elemSizeLog2 = 0;\n    }\n    else\n    {\n        ADDR_ASSERT(dataType == Gfx11DataDepthStencil);\n        elemSizeLog2 = 2;\n    }\n\n    return elemSizeLog2;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::GetMetaCacheSizeLog2\n*\n*   @brief\n*       Gets meta data cache line size log2\n*   @return\n*       Meta data cache line size log2\n************************************************************************************************************************\n*/\nINT_32 Gfx11Lib::GetMetaCacheSizeLog2(\n    Gfx11DataType dataType) ///< Data surface type\n{\n    INT_32 cacheSizeLog2 = 0;\n\n    if (dataType == Gfx11DataColor)\n    {\n        cacheSizeLog2 = 6;\n    }\n    else\n    {\n        ADDR_ASSERT(dataType == Gfx11DataDepthStencil);\n        cacheSizeLog2 = 8;\n    }\n\n    return cacheSizeLog2;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx11Lib::HwlComputeSurfaceInfoLinear\n*\n*   @brief\n*       Internal function to calculate alignment for linear surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoLinear(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (IsTex1d(pIn->resourceType) && (pIn->height > 1))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n    else\n    {\n        const UINT_32 elementBytes = pIn->bpp >> 3;\n        const UINT_32 pitchAlign   = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 / elementBytes);\n        const UINT_32 mipDepth     = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? pIn->numSlices : 1;\n        UINT_32       pitch        = PowTwoAlign(pIn->width, pitchAlign);\n        UINT_32       actualHeight = pIn->height;\n        UINT_64       sliceSize    = 0;\n\n        if (pIn->numMipLevels > 1)\n        {\n            for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)\n            {\n                UINT_32 mipWidth, mipHeight;\n\n                GetMipSize(pIn->width, pIn->height, 1, i, &mipWidth, &mipHeight);\n\n                const UINT_32 mipActualWidth = PowTwoAlign(mipWidth, pitchAlign);\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[i].pitch            = mipActualWidth;\n                    pOut->pMipInfo[i].height           = mipHeight;\n                    pOut->pMipInfo[i].depth            = mipDepth;\n                    pOut->pMipInfo[i].offset           = sliceSize;\n                    pOut->pMipInfo[i].mipTailOffset    = 0;\n                    pOut->pMipInfo[i].macroBlockOffset = sliceSize;\n                }\n\n                sliceSize += static_cast<UINT_64>(mipActualWidth) * mipHeight * elementBytes;\n            }\n        }\n        else\n        {\n            returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlign, &pitch, &actualHeight);\n\n            if (returnCode == ADDR_OK)\n            {\n                sliceSize = static_cast<UINT_64>(pitch) * actualHeight * elementBytes;\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    pOut->pMipInfo[0].pitch            = pitch;\n                    pOut->pMipInfo[0].height           = actualHeight;\n                    pOut->pMipInfo[0].depth            = mipDepth;\n                    pOut->pMipInfo[0].offset           = 0;\n                    pOut->pMipInfo[0].mipTailOffset    = 0;\n                    pOut->pMipInfo[0].macroBlockOffset = 0;\n                }\n            }\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->pitch          = pitch;\n            pOut->height         = actualHeight;\n            pOut->numSlices      = pIn->numSlices;\n            pOut->sliceSize      = sliceSize;\n            pOut->surfSize       = sliceSize * pOut->numSlices;\n            pOut->baseAlign      = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? elementBytes : 256;\n            pOut->blockWidth     = pitchAlign;\n            pOut->blockHeight    = 1;\n            pOut->blockSlices    = 1;\n\n            // Following members are useless on GFX11\n            pOut->mipChainPitch  = 0;\n            pOut->mipChainHeight = 0;\n            pOut->mipChainSlice  = 0;\n            pOut->epitchIsHeight = FALSE;\n\n            // Post calculation validate\n            ADDR_ASSERT(pOut->sliceSize > 0);\n        }\n    }\n\n    return returnCode;\n}\n\n} // V2\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx11/gfx11addrlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx11addrlib.h\n* @brief Contains the Gfx11Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX11_ADDR_LIB_H__\n#define __GFX11_ADDR_LIB_H__\n\n#include \"addrlib2.h\"\n#include \"coord.h\"\n#include \"gfx11SwizzlePattern.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\n/**\n************************************************************************************************************************\n* @brief GFX11 specific settings structure.\n************************************************************************************************************************\n*/\nstruct Gfx11ChipSettings\n{\n    struct\n    {\n        UINT_32 isGfx1150           :  1;\n        UINT_32 isGfx1103           :  1;\n        UINT_32 reserved1           : 30;\n\n        // Misc configuration bits\n        UINT_32 reserved2           : 32;\n    };\n};\n\n/**\n************************************************************************************************************************\n* @brief GFX11 data surface type.\n************************************************************************************************************************\n*/\nenum Gfx11DataType\n{\n    Gfx11DataColor,\n    Gfx11DataDepthStencil,\n};\n\nconst UINT_32 Gfx11LinearSwModeMask = (1u << ADDR_SW_LINEAR);\n\nconst UINT_32 Gfx11Blk256BSwModeMask = (1u << ADDR_SW_256B_D);\n\nconst UINT_32 Gfx11Blk4KBSwModeMask = (1u << ADDR_SW_4KB_S)   |\n                                      (1u << ADDR_SW_4KB_D)   |\n                                      (1u << ADDR_SW_4KB_S_X) |\n                                      (1u << ADDR_SW_4KB_D_X);\n\nconst UINT_32 Gfx11Blk64KBSwModeMask = (1u << ADDR_SW_64KB_S)   |\n                                       (1u << ADDR_SW_64KB_D)   |\n                                       (1u << ADDR_SW_64KB_S_T) |\n                                       (1u << ADDR_SW_64KB_D_T) |\n                                       (1u << ADDR_SW_64KB_Z_X) |\n                                       (1u << ADDR_SW_64KB_S_X) |\n                                       (1u << ADDR_SW_64KB_D_X) |\n                                       (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx11Blk256KBSwModeMask = (1u << ADDR_SW_256KB_Z_X) |\n                                        (1u << ADDR_SW_256KB_S_X) |\n                                        (1u << ADDR_SW_256KB_D_X) |\n                                        (1u << ADDR_SW_256KB_R_X);\n\nconst UINT_32 Gfx11ZSwModeMask = (1u << ADDR_SW_64KB_Z_X) |\n                                 (1u << ADDR_SW_256KB_Z_X);\n\nconst UINT_32 Gfx11StandardSwModeMask = (1u << ADDR_SW_4KB_S)    |\n                                        (1u << ADDR_SW_64KB_S)   |\n                                        (1u << ADDR_SW_64KB_S_T) |\n                                        (1u << ADDR_SW_4KB_S_X)  |\n                                        (1u << ADDR_SW_64KB_S_X) |\n                                        (1u << ADDR_SW_256KB_S_X);\n\nconst UINT_32 Gfx11DisplaySwModeMask = (1u << ADDR_SW_256B_D)   |\n                                       (1u << ADDR_SW_4KB_D)    |\n                                       (1u << ADDR_SW_64KB_D)   |\n                                       (1u << ADDR_SW_64KB_D_T) |\n                                       (1u << ADDR_SW_4KB_D_X)  |\n                                       (1u << ADDR_SW_64KB_D_X) |\n                                       (1u << ADDR_SW_256KB_D_X);\n\nconst UINT_32 Gfx11RenderSwModeMask = (1u << ADDR_SW_64KB_R_X) |\n                                      (1u << ADDR_SW_256KB_R_X);\n\nconst UINT_32 Gfx11XSwModeMask = (1u << ADDR_SW_4KB_S_X)  |\n                                 (1u << ADDR_SW_4KB_D_X)  |\n                                 (1u << ADDR_SW_64KB_Z_X) |\n                                 (1u << ADDR_SW_64KB_S_X) |\n                                 (1u << ADDR_SW_64KB_D_X) |\n                                 (1u << ADDR_SW_64KB_R_X) |\n                                 Gfx11Blk256KBSwModeMask;\n\nconst UINT_32 Gfx11TSwModeMask = (1u << ADDR_SW_64KB_S_T) |\n                                 (1u << ADDR_SW_64KB_D_T);\n\nconst UINT_32 Gfx11XorSwModeMask = Gfx11XSwModeMask |\n                                   Gfx11TSwModeMask;\n\nconst UINT_32 Gfx11Rsrc1dSwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                      (1u << ADDR_SW_64KB_R_X) |\n                                      (1u << ADDR_SW_64KB_Z_X) ;\n\nconst UINT_32 Gfx11Rsrc2dSwModeMask = Gfx11LinearSwModeMask  |\n                                      Gfx11DisplaySwModeMask |\n                                      Gfx11ZSwModeMask       |\n                                      Gfx11RenderSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dSwModeMask = Gfx11LinearSwModeMask    |\n                                      Gfx11StandardSwModeMask  |\n                                      Gfx11ZSwModeMask         |\n                                      Gfx11RenderSwModeMask    |\n                                      (1u << ADDR_SW_64KB_D_X) |\n                                      (1u << ADDR_SW_256KB_D_X);\n\nconst UINT_32 Gfx11Rsrc2dPrtSwModeMask =\n    (Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask) & ~Gfx11XSwModeMask & Gfx11Rsrc2dSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dPrtSwModeMask =\n    (Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask) & ~Gfx11XSwModeMask & Gfx11Rsrc3dSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dThin64KBSwModeMask = (1u << ADDR_SW_64KB_Z_X) |\n                                              (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx11Rsrc3dThin256KBSwModeMask = (1u << ADDR_SW_256KB_Z_X) |\n                                               (1u << ADDR_SW_256KB_R_X);\n\nconst UINT_32 Gfx11Rsrc3dThinSwModeMask = Gfx11Rsrc3dThin64KBSwModeMask | Gfx11Rsrc3dThin256KBSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dThickSwModeMask = Gfx11Rsrc3dSwModeMask & ~(Gfx11Rsrc3dThinSwModeMask | Gfx11LinearSwModeMask);\n\nconst UINT_32 Gfx11Rsrc3dThick4KBSwModeMask = Gfx11Rsrc3dThickSwModeMask & Gfx11Blk4KBSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dThick64KBSwModeMask = Gfx11Rsrc3dThickSwModeMask & Gfx11Blk64KBSwModeMask;\n\nconst UINT_32 Gfx11Rsrc3dThick256KBSwModeMask = Gfx11Rsrc3dThickSwModeMask & Gfx11Blk256KBSwModeMask;\n\nconst UINT_32 Gfx11MsaaSwModeMask = Gfx11ZSwModeMask |\n                                    Gfx11RenderSwModeMask;\n\nconst UINT_32 Dcn32SwModeMask = (1u << ADDR_SW_LINEAR)    |\n                                (1u << ADDR_SW_64KB_D)    |\n                                (1u << ADDR_SW_64KB_D_T)  |\n                                (1u << ADDR_SW_64KB_D_X)  |\n                                (1u << ADDR_SW_64KB_R_X)  |\n                                (1u << ADDR_SW_256KB_D_X) |\n                                (1u << ADDR_SW_256KB_R_X);\n\nconst UINT_32 Size256K     = 262144u;\nconst UINT_32 Log2Size256K = 18u;\n\n/**\n************************************************************************************************************************\n* @brief This class is the GFX11 specific address library\n*        function set.\n************************************************************************************************************************\n*/\nclass Gfx11Lib : public Lib\n{\npublic:\n    /// Creates Gfx11Lib object\n    static Addr::Lib* CreateObj(const Client* pClient)\n    {\n        VOID* pMem = Object::ClientAlloc(sizeof(Gfx11Lib), pClient);\n        return (pMem != NULL) ? new (pMem) Gfx11Lib(pClient) : NULL;\n    }\n\nprotected:\n    Gfx11Lib(const Client* pClient);\n    virtual ~Gfx11Lib();\n\n    virtual BOOL_32 HwlIsStandardSwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isStd;\n    }\n\n    virtual BOOL_32 HwlIsDisplaySwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isDisp;\n    }\n\n    virtual BOOL_32 HwlIsThin(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return ((IsTex1d(resourceType)  == TRUE) ||\n                (IsTex2d(resourceType)  == TRUE) ||\n                ((IsTex3d(resourceType) == TRUE)                  &&\n                 (m_swizzleModeTable[swizzleMode].isStd  == FALSE) &&\n                 (m_swizzleModeTable[swizzleMode].isDisp == FALSE)));\n    }\n\n    virtual BOOL_32 HwlIsThick(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return ((IsTex3d(resourceType) == TRUE) &&\n                (m_swizzleModeTable[swizzleMode].isStd || m_swizzleModeTable[swizzleMode].isDisp));\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileInfo(\n        const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeDccInfo(\n        const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(\n        const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileCoordFromAddr(\n        const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlSupportComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn);\n\n    virtual VOID HwlComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual UINT_32 HwlGetEquationIndex(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const\n    {\n        *ppEquationTable = m_equationTable;\n\n        return m_numEquations;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView(\n        const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetAllowedBlockSet(\n        ADDR2_SWMODE_SET allowedSwModeSet,\n        AddrResourceType rsrcType,\n        ADDR2_BLOCK_SET* pAllowedBlockSet) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetAllowedSwSet(\n        ADDR2_SWMODE_SET  allowedSwModeSet,\n        ADDR2_SWTYPE_SET* pAllowedSwSet) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoLinear(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlComputeMaxBaseAlignments() const;\n\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const;\n\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn);\n\n    virtual ChipFamily HwlConvertChipFamily(UINT_32 uChipFamily, UINT_32 uChipRevision);\n\nprivate:\n    // Initialize equation table\n    VOID InitEquationTable();\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoMacroTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceInfoMicroTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordMacroTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordMicroTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    UINT_32 ComputeOffsetFromSwizzlePattern(\n        const UINT_64* pPattern,\n        UINT_32        numBits,\n        UINT_32        x,\n        UINT_32        y,\n        UINT_32        z,\n        UINT_32        s) const;\n\n    UINT_32 ComputeOffsetFromEquation(\n        const ADDR_EQUATION* pEq,\n        UINT_32              x,\n        UINT_32              y,\n        UINT_32              z) const;\n\n    ADDR_E_RETURNCODE ComputeStereoInfo(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        UINT_32*                                pAlignY,\n        UINT_32*                                pRightXor) const;\n\n    static void GetMipSize(\n        UINT_32  mip0Width,\n        UINT_32  mip0Height,\n        UINT_32  mip0Depth,\n        UINT_32  mipId,\n        UINT_32* pMipWidth,\n        UINT_32* pMipHeight,\n        UINT_32* pMipDepth = NULL)\n    {\n        *pMipWidth  = ShiftCeil(Max(mip0Width, 1u),  mipId);\n        *pMipHeight = ShiftCeil(Max(mip0Height, 1u), mipId);\n\n        if (pMipDepth != NULL)\n        {\n            *pMipDepth = ShiftCeil(Max(mip0Depth, 1u),  mipId);\n        }\n    }\n\n    const ADDR_SW_PATINFO* GetSwizzlePatternInfo(\n        AddrSwizzleMode  swizzleMode,\n        AddrResourceType resourceType,\n        UINT_32          log2Elem,\n        UINT_32          numFrag) const;\n\n    VOID GetSwizzlePatternFromPatternInfo(\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_BIT_SETTING       (&pSwizzle)[20]) const\n    {\n        memcpy(pSwizzle,\n               GFX11_SW_PATTERN_NIBBLE01[pPatInfo->nibble01Idx],\n               sizeof(GFX11_SW_PATTERN_NIBBLE01[pPatInfo->nibble01Idx]));\n\n        memcpy(&pSwizzle[8],\n               GFX11_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx],\n               sizeof(GFX11_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx]));\n\n        memcpy(&pSwizzle[12],\n               GFX11_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx],\n               sizeof(GFX11_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx]));\n\n        memcpy(&pSwizzle[16],\n               GFX11_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx],\n               sizeof(GFX11_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx]));\n    }\n\n    VOID ConvertSwizzlePatternToEquation(\n        UINT_32                elemLog2,\n        AddrResourceType       rsrcType,\n        AddrSwizzleMode        swMode,\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_EQUATION*         pEquation) const;\n\n    static INT_32 GetMetaElementSizeLog2(Gfx11DataType dataType);\n\n    static INT_32 GetMetaCacheSizeLog2(Gfx11DataType dataType);\n\n    void GetBlk256SizeLog2(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        Dim3d*           pBlock) const;\n\n    void GetCompressedBlockSizeLog2(\n        Gfx11DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        Dim3d*           pBlock) const;\n\n    INT_32 GetMetaOverlapLog2(\n        Gfx11DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2) const;\n\n    INT_32 Get3DMetaOverlapLog2(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2) const;\n\n    UINT_32 GetMetaBlkSize(\n        Gfx11DataType    dataType,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          elemLog2,\n        UINT_32          numSamplesLog2,\n        BOOL_32          pipeAlign,\n        Dim3d*           pBlock) const;\n\n    INT_32 GetPipeRotateAmount(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\n    INT_32 GetEffectiveNumPipes() const\n    {\n        return ((m_numSaLog2 + 1) >= m_pipesLog2) ? m_pipesLog2 : m_numSaLog2 + 1;\n    }\n\n    BOOL_32 IsRbAligned(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        const BOOL_32 isRtopt   = IsRtOptSwizzle(swizzleMode);\n        const BOOL_32 isZ       = IsZOrderSwizzle(swizzleMode);\n        const BOOL_32 isDisplay = IsDisplaySwizzle(swizzleMode);\n\n        return (IsTex2d(resourceType) && (isRtopt || isZ)) ||\n               (IsTex3d(resourceType) && isDisplay);\n\n    }\n\n    UINT_32 GetValidDisplaySwizzleModes(UINT_32 bpp) const;\n\n    BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    UINT_32 GetMaxNumMipsInTail(UINT_32 blockSizeLog2, BOOL_32 isThin) const;\n\n    BOOL_32 IsInMipTail(\n        Dim3d   mipTailDim,\n        UINT_32 maxNumMipsInTail,\n        UINT_32 mipWidth,\n        UINT_32 mipHeight,\n        UINT_32 numMipsToTheEnd) const\n    {\n        BOOL_32 inTail = ((mipWidth <= mipTailDim.w) &&\n                          (mipHeight <= mipTailDim.h) &&\n                          (numMipsToTheEnd <= maxNumMipsInTail));\n\n        return inTail;\n    }\n\n    UINT_32 GetBankXorBits(UINT_32 blockBits) const\n    {\n        return (blockBits > m_pipeInterleaveLog2 + m_pipesLog2 + ColumnBits) ?\n               Min(blockBits - m_pipeInterleaveLog2 - m_pipesLog2 - ColumnBits, BankBits) : 0;\n    }\n\n    BOOL_32 ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n    BOOL_32 ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    BOOL_32 IsBlock256kb(AddrSwizzleMode swizzleMode) const { return IsBlockVariable(swizzleMode); }\n\n    // TODO: figure out if there is any Column bits on GFX11...\n    static const UINT_32 ColumnBits       = 2;\n    static const UINT_32 BankBits         = 4;\n    static const UINT_32 UnalignedDccType = 3;\n\n    static const Dim3d Block256_3d[MaxNumOfBpp];\n    static const Dim3d Block256K_Log2_3d[MaxNumOfBpp];\n    static const Dim3d Block64K_Log2_3d[MaxNumOfBpp];\n    static const Dim3d Block4K_Log2_3d[MaxNumOfBpp];\n\n    static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE];\n\n    // Number of packers log2\n    UINT_32 m_numPkrLog2;\n    // Number of shader array log2\n    UINT_32 m_numSaLog2;\n\n    Gfx11ChipSettings m_settings;\n\n    UINT_32 m_colorBaseIndex;\n    UINT_32 m_htileBaseIndex;\n    UINT_32 m_dccBaseIndex;\n};\n\n} // V2\n} // Addr\n} // namespace rocr\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx12/gfx12SwizzlePattern.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2023 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx12SwizzlePattern.h\n* @brief swizzle pattern for gfx12.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX12_SWIZZLE_PATTERN_H__\n#define __GFX12_SWIZZLE_PATTERN_H__\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V3\n{\n    const ADDR_SW_PATINFO GFX12_SW_256B_2D_1xAA_PATINFO[] =\n    {\n        {   0,    0,    0,    0, } , // 1 BPE @ SW_256B_2D_1xAA\n        {   1,    0,    0,    0, } , // 2 BPE @ SW_256B_2D_1xAA\n        {   2,    0,    0,    0, } , // 4 BPE @ SW_256B_2D_1xAA\n        {   3,    0,    0,    0, } , // 8 BPE @ SW_256B_2D_1xAA\n        {   4,    0,    0,    0, } , // 16 BPE @ SW_256B_2D_1xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256B_2D_2xAA_PATINFO[] =\n    {\n        {   5,    0,    0,    0, } , // 1 BPE @ SW_256B_2D_2xAA\n        {   6,    0,    0,    0, } , // 2 BPE @ SW_256B_2D_2xAA\n        {   7,    0,    0,    0, } , // 4 BPE @ SW_256B_2D_2xAA\n        {   8,    0,    0,    0, } , // 8 BPE @ SW_256B_2D_2xAA\n        {   9,    0,    0,    0, } , // 16 BPE @ SW_256B_2D_2xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256B_2D_4xAA_PATINFO[] =\n    {\n        {  10,    0,    0,    0, } , // 1 BPE @ SW_256B_2D_4xAA\n        {  11,    0,    0,    0, } , // 2 BPE @ SW_256B_2D_4xAA\n        {  12,    0,    0,    0, } , // 4 BPE @ SW_256B_2D_4xAA\n        {  13,    0,    0,    0, } , // 8 BPE @ SW_256B_2D_4xAA\n        {  14,    0,    0,    0, } , // 16 BPE @ SW_256B_2D_4xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256B_2D_8xAA_PATINFO[] =\n    {\n        {  15,    0,    0,    0, } , // 1 BPE @ SW_256B_2D_8xAA\n        {  16,    0,    0,    0, } , // 2 BPE @ SW_256B_2D_8xAA\n        {  17,    0,    0,    0, } , // 4 BPE @ SW_256B_2D_8xAA\n        {  18,    0,    0,    0, } , // 8 BPE @ SW_256B_2D_8xAA\n        {  19,    0,    0,    0, } , // 16 BPE @ SW_256B_2D_8xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_4KB_2D_1xAA_PATINFO[] =\n    {\n        {   0,    1,    0,    0, } , // 1 BPE @ SW_4KB_2D_1xAA\n        {   1,    2,    0,    0, } , // 2 BPE @ SW_4KB_2D_1xAA\n        {   2,    3,    0,    0, } , // 4 BPE @ SW_4KB_2D_1xAA\n        {   3,    4,    0,    0, } , // 8 BPE @ SW_4KB_2D_1xAA\n        {   4,    5,    0,    0, } , // 16 BPE @ SW_4KB_2D_1xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_4KB_2D_2xAA_PATINFO[] =\n    {\n        {   5,    2,    0,    0, } , // 1 BPE @ SW_4KB_2D_2xAA\n        {   6,    3,    0,    0, } , // 2 BPE @ SW_4KB_2D_2xAA\n        {   7,    4,    0,    0, } , // 4 BPE @ SW_4KB_2D_2xAA\n        {   8,    5,    0,    0, } , // 8 BPE @ SW_4KB_2D_2xAA\n        {   9,    6,    0,    0, } , // 16 BPE @ SW_4KB_2D_2xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_4KB_2D_4xAA_PATINFO[] =\n    {\n        {  10,    3,    0,    0, } , // 1 BPE @ SW_4KB_2D_4xAA\n        {  11,    4,    0,    0, } , // 2 BPE @ SW_4KB_2D_4xAA\n        {  12,    5,    0,    0, } , // 4 BPE @ SW_4KB_2D_4xAA\n        {  13,    6,    0,    0, } , // 8 BPE @ SW_4KB_2D_4xAA\n        {  14,    7,    0,    0, } , // 16 BPE @ SW_4KB_2D_4xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_4KB_2D_8xAA_PATINFO[] =\n    {\n        {  15,    4,    0,    0, } , // 1 BPE @ SW_4KB_2D_8xAA\n        {  16,    5,    0,    0, } , // 2 BPE @ SW_4KB_2D_8xAA\n        {  17,    6,    0,    0, } , // 4 BPE @ SW_4KB_2D_8xAA\n        {  18,    7,    0,    0, } , // 8 BPE @ SW_4KB_2D_8xAA\n        {  19,    8,    0,    0, } , // 16 BPE @ SW_4KB_2D_8xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_64KB_2D_1xAA_PATINFO[] =\n    {\n        {   0,    1,    1,    0, } , // 1 BPE @ SW_64KB_2D_1xAA\n        {   1,    2,    2,    0, } , // 2 BPE @ SW_64KB_2D_1xAA\n        {   2,    3,    3,    0, } , // 4 BPE @ SW_64KB_2D_1xAA\n        {   3,    4,    4,    0, } , // 8 BPE @ SW_64KB_2D_1xAA\n        {   4,    5,    5,    0, } , // 16 BPE @ SW_64KB_2D_1xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_64KB_2D_2xAA_PATINFO[] =\n    {\n        {   5,    2,    2,    0, } , // 1 BPE @ SW_64KB_2D_2xAA\n        {   6,    3,    3,    0, } , // 2 BPE @ SW_64KB_2D_2xAA\n        {   7,    4,    4,    0, } , // 4 BPE @ SW_64KB_2D_2xAA\n        {   8,    5,    5,    0, } , // 8 BPE @ SW_64KB_2D_2xAA\n        {   9,    6,    6,    0, } , // 16 BPE @ SW_64KB_2D_2xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_64KB_2D_4xAA_PATINFO[] =\n    {\n        {  10,    3,    3,    0, } , // 1 BPE @ SW_64KB_2D_4xAA\n        {  11,    4,    4,    0, } , // 2 BPE @ SW_64KB_2D_4xAA\n        {  12,    5,    5,    0, } , // 4 BPE @ SW_64KB_2D_4xAA\n        {  13,    6,    6,    0, } , // 8 BPE @ SW_64KB_2D_4xAA\n        {  14,    7,    7,    0, } , // 16 BPE @ SW_64KB_2D_4xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_64KB_2D_8xAA_PATINFO[] =\n    {\n        {  15,    4,    4,    0, } , // 1 BPE @ SW_64KB_2D_8xAA\n        {  16,    5,    5,    0, } , // 2 BPE @ SW_64KB_2D_8xAA\n        {  17,    6,    6,    0, } , // 4 BPE @ SW_64KB_2D_8xAA\n        {  18,    7,    7,    0, } , // 8 BPE @ SW_64KB_2D_8xAA\n        {  19,    8,    8,    0, } , // 16 BPE @ SW_64KB_2D_8xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256KB_2D_1xAA_PATINFO[] =\n    {\n        {   0,    1,    1,    1, } , // 1 BPE @ SW_256KB_2D_1xAA\n        {   1,    2,    2,    2, } , // 2 BPE @ SW_256KB_2D_1xAA\n        {   2,    3,    3,    3, } , // 4 BPE @ SW_256KB_2D_1xAA\n        {   3,    4,    4,    4, } , // 8 BPE @ SW_256KB_2D_1xAA\n        {   4,    5,    5,    5, } , // 16 BPE @ SW_256KB_2D_1xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256KB_2D_2xAA_PATINFO[] =\n    {\n        {   5,    2,    2,    2, } , // 1 BPE @ SW_256KB_2D_2xAA\n        {   6,    3,    3,    3, } , // 2 BPE @ SW_256KB_2D_2xAA\n        {   7,    4,    4,    4, } , // 4 BPE @ SW_256KB_2D_2xAA\n        {   8,    5,    5,    5, } , // 8 BPE @ SW_256KB_2D_2xAA\n        {   9,    6,    6,    6, } , // 16 BPE @ SW_256KB_2D_2xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256KB_2D_4xAA_PATINFO[] =\n    {\n        {  10,    3,    3,    3, } , // 1 BPE @ SW_256KB_2D_4xAA\n        {  11,    4,    4,    4, } , // 2 BPE @ SW_256KB_2D_4xAA\n        {  12,    5,    5,    5, } , // 4 BPE @ SW_256KB_2D_4xAA\n        {  13,    6,    6,    6, } , // 8 BPE @ SW_256KB_2D_4xAA\n        {  14,    7,    7,    7, } , // 16 BPE @ SW_256KB_2D_4xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256KB_2D_8xAA_PATINFO[] =\n    {\n        {  15,    4,    4,    4, } , // 1 BPE @ SW_256KB_2D_8xAA\n        {  16,    5,    5,    5, } , // 2 BPE @ SW_256KB_2D_8xAA\n        {  17,    6,    6,    6, } , // 4 BPE @ SW_256KB_2D_8xAA\n        {  18,    7,    7,    7, } , // 8 BPE @ SW_256KB_2D_8xAA\n        {  19,    8,    8,    8, } , // 16 BPE @ SW_256KB_2D_8xAA\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_4KB_3D_PATINFO[] =\n    {\n        {  20,    9,    0,    0, } , // 1 BPE @ SW_4KB_3D\n        {  21,   10,    0,    0, } , // 2 BPE @ SW_4KB_3D\n        {  22,   11,    0,    0, } , // 4 BPE @ SW_4KB_3D\n        {  23,   12,    0,    0, } , // 8 BPE @ SW_4KB_3D\n        {  24,   13,    0,    0, } , // 16 BPE @ SW_4KB_3D\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_64KB_3D_PATINFO[] =\n    {\n        {  20,    9,    9,    0, } , // 1 BPE @ SW_64KB_3D\n        {  21,   10,   10,    0, } , // 2 BPE @ SW_64KB_3D\n        {  22,   11,   11,    0, } , // 4 BPE @ SW_64KB_3D\n        {  23,   12,   12,    0, } , // 8 BPE @ SW_64KB_3D\n        {  24,   13,   13,    0, } , // 16 BPE @ SW_64KB_3D\n    };\n\n    const ADDR_SW_PATINFO GFX12_SW_256KB_3D_PATINFO[] =\n    {\n        {  20,    9,    9,    9, } , // 1 BPE @ SW_256KB_3D\n        {  21,   10,   10,    9, } , // 2 BPE @ SW_256KB_3D\n        {  22,   11,   11,   10, } , // 4 BPE @ SW_256KB_3D\n        {  23,   12,   12,   11, } , // 8 BPE @ SW_256KB_3D\n        {  24,   13,   13,   11, } , // 16 BPE @ SW_256KB_3D\n    };\n\n\n    const UINT_64 GFX12_SW_PATTERN_NIBBLE1[][8] =\n    {\n        {X0,            X1,            Y0,            X2,            Y1,            Y2,            X3,            Y3,            }, // 0\n        {0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 1\n        {0,             0,             X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 2\n        {0,             0,             0,             X0,            Y0,            X1,            X2,            Y1,            }, // 3\n        {0,             0,             0,             0,             X0,            Y0,            X1,            Y1,            }, // 4\n        {S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            X3,            }, // 5\n        {0,             S0,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 6\n        {0,             0,             S0,            X0,            Y0,            X1,            Y1,            X2,            }, // 7\n        {0,             0,             0,             S0,            X0,            Y0,            X1,            Y1,            }, // 8\n        {0,             0,             0,             0,             S0,            X0,            Y0,            X1,            }, // 9\n        {S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            Y2,            }, // 10\n        {0,             S0,            S1,            X0,            Y0,            X1,            Y1,            X2,            }, // 11\n        {0,             0,             S0,            S1,            X0,            Y0,            X1,            Y1,            }, // 12\n        {0,             0,             0,             S0,            S1,            X0,            Y0,            X1,            }, // 13\n        {0,             0,             0,             0,             S0,            S1,            X0,            Y0,            }, // 14\n        {S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            X2,            }, // 15\n        {0,             S0,            S1,            S2,            X0,            Y0,            X1,            Y1,            }, // 16\n        {0,             0,             S0,            S1,            S2,            X0,            Y0,            X1,            }, // 17\n        {0,             0,             0,             S0,            S1,            S2,            X0,            Y0,            }, // 18\n        {0,             0,             0,             0,             S0,            S1,            S2,            X0,            }, // 19\n        {X0,            X1,            Z0,            Y0,            Y1,            Z1,            X2,            Z2,            }, // 20\n        {0,             X0,            Z0,            Y0,            X1,            Z1,            Y1,            Z2,            }, // 21\n        {0,             0,             X0,            Y0,            X1,            Z0,            Y1,            Z1,            }, // 22\n        {0,             0,             0,             X0,            Y0,            Z0,            X1,            Z1,            }, // 23\n        {0,             0,             0,             0,             X0,            Z0,            Y0,            Z1,            }, // 24\n    };\n\n    const UINT_64 GFX12_SW_PATTERN_NIBBLE2[][4] =\n    {\n        {0,             0,             0,             0,             }, // 0\n        {Y4,            X4,            Y5,            X5,            }, // 1\n        {Y3,            X4,            Y4,            X5,            }, // 2\n        {Y3,            X3,            Y4,            X4,            }, // 3\n        {Y2,            X3,            Y3,            X4,            }, // 4\n        {Y2,            X2,            Y3,            X3,            }, // 5\n        {Y1,            X2,            Y2,            X3,            }, // 6\n        {Y1,            X1,            Y2,            X2,            }, // 7\n        {Y0,            X1,            Y1,            X2,            }, // 8\n        {Y2,            X3,            Z3,            Y3,            }, // 9\n        {Y2,            X2,            Z3,            Y3,            }, // 10\n        {Y2,            X2,            Z2,            Y3,            }, // 11\n        {Y1,            X2,            Z2,            Y2,            }, // 12\n        {Y1,            X1,            Z2,            Y2,            }, // 13\n    };\n\n    const UINT_64 GFX12_SW_PATTERN_NIBBLE3[][4] =\n    {\n        {0,             0,             0,             0,             }, // 0\n        {Y6,            X6,            Y7,            X7,            }, // 1\n        {Y5,            X6,            Y6,            X7,            }, // 2\n        {Y5,            X5,            Y6,            X6,            }, // 3\n        {Y4,            X5,            Y5,            X6,            }, // 4\n        {Y4,            X4,            Y5,            X5,            }, // 5\n        {Y3,            X4,            Y4,            X5,            }, // 6\n        {Y3,            X3,            Y4,            X4,            }, // 7\n        {Y2,            X3,            Y3,            X4,            }, // 8\n        {X4,            Z4,            Y4,            X5,            }, // 9\n        {X3,            Z4,            Y4,            X4,            }, // 10\n        {X3,            Z3,            Y4,            X4,            }, // 11\n        {X3,            Z3,            Y3,            X4,            }, // 12\n        {X2,            Z3,            Y3,            X3,            }, // 13\n    };\n\n    const UINT_64 GFX12_SW_PATTERN_NIBBLE4[][2] =\n    {\n        {0,             0,             }, // 0\n        {Y8,            X8,            }, // 1\n        {Y7,            X8,            }, // 2\n        {Y7,            X7,            }, // 3\n        {Y6,            X7,            }, // 4\n        {Y6,            X6,            }, // 5\n        {Y5,            X6,            }, // 6\n        {Y5,            X5,            }, // 7\n        {Y4,            X5,            }, // 8\n        {Z5,            Y5,            }, // 9\n        {Z4,            Y5,            }, // 10\n        {Z4,            Y4,            }, // 11\n    };\n\n} // V3\n} // Addr\n} // namespace\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx12/gfx12addrlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2023 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx12addrlib.cpp\n* @brief Contain the implementation for the Gfx12Lib class.\n************************************************************************************************************************\n*/\n\n#include \"gfx12addrlib.h\"\n#include \"gfx12_gb_reg.h\"\n\n#include \"amdgpu_asic_addr.h\"\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\nnamespace rocr {\nnamespace Addr\n{\n/**\n************************************************************************************************************************\n*   Gfx12HwlInit\n*\n*   @brief\n*       Creates an Gfx12Lib object.\n*\n*   @return\n*       Returns an Gfx12Lib object pointer.\n************************************************************************************************************************\n*/\nAddr::Lib* Gfx12HwlInit(\n    const Client* pClient)\n{\n    return V3::Gfx12Lib::CreateObj(pClient);\n}\n\nnamespace V3\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\nconst SwizzleModeFlags Gfx12Lib::SwizzleModeTable[ADDR3_MAX_TYPE] =\n{//Linear 2d   3d  256B  4KB  64KB  256KB  Reserved\n    {{1,   0,   0,    0,   0,    0,     0,    0}}, // ADDR3_LINEAR\n    {{0,   1,   0,    1,   0,    0,     0,    0}}, // ADDR3_256B_2D\n    {{0,   1,   0,    0,   1,    0,     0,    0}}, // ADDR3_4KB_2D\n    {{0,   1,   0,    0,   0,    1,     0,    0}}, // ADDR3_64KB_2D\n    {{0,   1,   0,    0,   0,    0,     1,    0}}, // ADDR3_256KB_2D\n    {{0,   0,   1,    0,   1,    0,     0,    0}}, // ADDR3_4KB_3D\n    {{0,   0,   1,    0,   0,    1,     0,    0}}, // ADDR3_64KB_3D\n    {{0,   0,   1,    0,   0,    0,     1,    0}}, // ADDR3_256KB_3D\n};\n\nconst ADDR_EXTENT3D Gfx12Lib::Block4K_Log2_3d[]   = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};\nconst ADDR_EXTENT3D Gfx12Lib::Block64K_Log2_3d[]  = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};\nconst ADDR_EXTENT3D Gfx12Lib::Block256K_Log2_3d[] = {{6, 6, 6}, {5, 6, 6}, {5, 6, 5}, {5, 5, 5}, {4, 5, 5}};\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::Gfx12Lib\n*\n*   @brief\n*       Constructor\n*\n************************************************************************************************************************\n*/\nGfx12Lib::Gfx12Lib(\n    const Client* pClient)\n    :\n    Lib(pClient),\n    m_numSwizzleBits(0)\n{\n    memset(&m_settings, 0, sizeof(m_settings));\n    memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::~Gfx12Lib\n*\n*   @brief\n*       Destructor\n************************************************************************************************************************\n*/\nGfx12Lib::~Gfx12Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::ConvertSwizzlePatternToEquation\n*\n*   @brief\n*       Convert swizzle pattern to equation.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx12Lib::ConvertSwizzlePatternToEquation(\n    UINT_32                elemLog2,  ///< [in] element bytes log2\n    Addr3SwizzleMode       swMode,    ///< [in] swizzle mode\n    const ADDR_SW_PATINFO* pPatInfo,  ///< [in] swizzle pattern info\n    ADDR_EQUATION*         pEquation) ///< [out] equation converted from swizzle pattern\n    const\n{\n    ADDR_BIT_SETTING fullSwizzlePattern[Log2Size256K];\n    GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);\n\n    const ADDR_BIT_SETTING* pSwizzle = fullSwizzlePattern;\n    const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode, TRUE);\n\n    pEquation->numBits = blockSizeLog2;\n    pEquation->stackedDepthSlices = FALSE;\n\n    for (UINT_32 i = 0; i < elemLog2; i++)\n    {\n        pEquation->addr[i].channel = 0;\n        pEquation->addr[i].valid = 1;\n        pEquation->addr[i].index = i;\n    }\n\n    for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)\n    {\n        ADDR_ASSERT(IsPow2(pSwizzle[i].value));\n\n        if (pSwizzle[i].x != 0)\n        {\n            ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].x)));\n\n            pEquation->addr[i].channel = 0;\n            pEquation->addr[i].valid = 1;\n            pEquation->addr[i].index = Log2(pSwizzle[i].x) + elemLog2;\n        }\n        else if (pSwizzle[i].y != 0)\n        {\n            ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].y)));\n\n            pEquation->addr[i].channel = 1;\n            pEquation->addr[i].valid = 1;\n            pEquation->addr[i].index = Log2(pSwizzle[i].y);\n        }\n        else if (pSwizzle[i].z != 0)\n        {\n            ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));\n\n            pEquation->addr[i].channel = 2;\n            pEquation->addr[i].valid = 1;\n            pEquation->addr[i].index = Log2(pSwizzle[i].z);\n        }\n        else if (pSwizzle[i].s != 0)\n        {\n            ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].s)));\n\n            pEquation->addr[i].channel = 3;\n            pEquation->addr[i].valid = 1;\n            pEquation->addr[i].index = Log2(pSwizzle[i].s);\n        }\n        else\n        {\n            ADDR_ASSERT_ALWAYS();\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::InitEquationTable\n*\n*   @brief\n*       Initialize Equation table.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx12Lib::InitEquationTable()\n{\n    memset(m_equationTable, 0, sizeof(m_equationTable));\n\n    for (UINT_32 swModeIdx = 0; swModeIdx < ADDR3_MAX_TYPE; swModeIdx++)\n    {\n        const Addr3SwizzleMode swMode = static_cast<Addr3SwizzleMode>(swModeIdx);\n\n        if (IsLinear(swMode))\n        {\n            // Skip linear equation (data table is not useful for 2D/3D images-- only contains x-coordinate bits)\n            continue;\n        }\n\n        const UINT_32 maxMsaa = Is2dSwizzle(swMode) ? MaxMsaaRateLog2 : 1;\n\n        for (UINT_32 msaaIdx = 0; msaaIdx < maxMsaa; msaaIdx++)\n        {\n            for (UINT_32 elemLog2 = 0; elemLog2 < MaxElementBytesLog2; elemLog2++)\n            {\n                UINT_32                equationIndex = ADDR_INVALID_EQUATION_INDEX;\n                const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(swMode, elemLog2, 1 << msaaIdx);\n\n                if (pPatInfo != NULL)\n                {\n                    ADDR_ASSERT(IsValidSwMode(swMode));\n\n                    ADDR_EQUATION equation = {};\n\n                    ConvertSwizzlePatternToEquation(elemLog2, swMode, pPatInfo, &equation);\n\n                    equationIndex = m_numEquations;\n                    ADDR_ASSERT(equationIndex < NumSwizzlePatterns);\n\n                    m_equationTable[equationIndex] = equation;\n                    m_numEquations++;\n                }\n                SetEquationTableEntry(swMode, msaaIdx, elemLog2, equationIndex);\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetBlockPixelDimensions\n*\n*   @brief\n*       Returns the pixel dimensions of one block.\n*\n************************************************************************************************************************\n*/\nADDR_EXTENT3D  Gfx12Lib::GetBlockPixelDimensions(\n    Addr3SwizzleMode  swizzleMode,\n    UINT_32           log2BytesPerPixel\n    ) const\n{\n    ADDR_EXTENT3D  log2Dim = {};\n\n    switch (swizzleMode)\n    {\n        case ADDR3_4KB_3D:\n            log2Dim = Block4K_Log2_3d[log2BytesPerPixel];\n            break;\n        case ADDR3_64KB_3D:\n            log2Dim = Block64K_Log2_3d[log2BytesPerPixel];\n            break;\n        case ADDR3_256KB_3D:\n            log2Dim = Block256K_Log2_3d[log2BytesPerPixel];\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            break;\n    }\n\n    return { 1u << log2Dim.width, 1u << log2Dim.height, 1u << log2Dim.depth };\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetMipOrigin\n*\n*   @brief\n*       Internal function to calculate origins of the mip levels\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nVOID Gfx12Lib::GetMipOrigin(\n     const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,        ///< [in] input structure\n     const ADDR_EXTENT3D&                    mipExtentFirstInTail,\n     ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut        ///< [out] output structure\n     ) const\n{\n    const BOOL_32        is3d           = Is3dSwizzle(pIn->swizzleMode);\n    const UINT_32        bytesPerPixel  = pIn->bpp >> 3;\n    const UINT_32        log2Bpp        = Log2(bytesPerPixel);\n    const ADDR_EXTENT3D  pixelBlockDims = GetBlockPixelDimensions(ADDR3_4KB_3D, log2Bpp);\n    const ADDR_EXTENT3D  tailMaxDim     = GetMipTailDim(pIn->swizzleMode,\n                                                        pOut->blockExtent);\n    const UINT_32        blockSizeLog2  = GetBlockSizeLog2(pIn->swizzleMode);\n    const UINT_32        maxMipsInTail  = GetMaxNumMipsInTail(pIn->swizzleMode, blockSizeLog2);\n\n    UINT_32 pitch  = tailMaxDim.width;\n    UINT_32 height = tailMaxDim.height;\n\n    UINT_32 depth  = (is3d ? PowTwoAlign(mipExtentFirstInTail.depth, pixelBlockDims.depth) : 1);\n\n    const UINT_32 tailMaxDepth   = (is3d ? (depth / pixelBlockDims.depth) : 1);\n\n    for (UINT_32 i = pOut->firstMipIdInTail; i < pIn->numMipLevels; i++)\n    {\n        INT_32  mipInTail = static_cast<INT_32>(i) - static_cast<INT_32>(pOut->firstMipIdInTail);\n        if ((mipInTail < 0) || (pIn->numMipLevels == 1))\n        {\n            mipInTail = MaxMipLevels;\n        }\n\n        // \"m\" can be negative\n        const INT_32  signedM   = static_cast<INT_32>(maxMipsInTail) - static_cast<INT_32>(1) - mipInTail;\n        const UINT_32 m         = Max(0, signedM);\n        const UINT_32 mipOffset = (m > 6) ? (16 << m) : (m << 8);\n\n        pOut->pMipInfo[i].offset           = mipOffset * tailMaxDepth;\n        pOut->pMipInfo[i].mipTailOffset    = mipOffset;\n        pOut->pMipInfo[i].macroBlockOffset = 0;\n\n        pOut->pMipInfo[i].pitch  = pitch;\n        pOut->pMipInfo[i].height = height;\n        pOut->pMipInfo[i].depth  = depth;\n\n        if (IsLinear(pIn->swizzleMode))\n        {\n            pOut->pMipInfo[i].mipTailCoordX = mipOffset >> 8;\n            pOut->pMipInfo[i].mipTailCoordY = 0;\n            pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n            pitch = Max(pitch >> 1, 1u);\n        }\n        else\n        {\n            UINT_32 mipX = ((mipOffset >> 9)  & 1)  |\n                           ((mipOffset >> 10) & 2)  |\n                           ((mipOffset >> 11) & 4)  |\n                           ((mipOffset >> 12) & 8)  |\n                           ((mipOffset >> 13) & 16) |\n                           ((mipOffset >> 14) & 32);\n            UINT_32 mipY = ((mipOffset >> 8)  & 1)  |\n                           ((mipOffset >> 9)  & 2)  |\n                           ((mipOffset >> 10) & 4)  |\n                           ((mipOffset >> 11) & 8)  |\n                           ((mipOffset >> 12) & 16) |\n                           ((mipOffset >> 13) & 32);\n\n            if (is3d == FALSE)\n            {\n                pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_2d[log2Bpp].w;\n                pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_2d[log2Bpp].h;\n                pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                pitch  = Max(pitch  >> 1, Block256_2d[log2Bpp].w);\n                height = Max(height >> 1, Block256_2d[log2Bpp].h);\n                depth  = 1;\n            }\n            else\n            {\n                pOut->pMipInfo[i].mipTailCoordX = mipX * pixelBlockDims.width;\n                pOut->pMipInfo[i].mipTailCoordY = mipY * pixelBlockDims.height;\n                pOut->pMipInfo[i].mipTailCoordZ = 0;\n\n                pitch  = Max(pitch  >> 1, pixelBlockDims.width);\n                height = Max(height >> 1, pixelBlockDims.height);\n                depth  = PowTwoAlign(Max(depth >> 1, 1u), pixelBlockDims.depth);\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetMipOffset\n*\n*   @brief\n*       Internal function to calculate alignment for a surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nVOID Gfx12Lib::GetMipOffset(\n     const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    const UINT_32        bytesPerPixel = pIn->bpp >> 3;\n    const UINT_32        log2Bpp       = Log2(bytesPerPixel);\n    const UINT_32        blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n    const UINT_32        blockSize     = 1 << blockSizeLog2;\n    const ADDR_EXTENT3D  tailMaxDim    = GetMipTailDim(pIn->swizzleMode,\n                                                       pOut->blockExtent);\n    const ADDR_EXTENT3D  mip0Dims      = GetBaseMipExtents(pIn);\n    const UINT_32        maxMipsInTail = GetMaxNumMipsInTail(pIn->swizzleMode, blockSizeLog2);\n\n    UINT_32       firstMipInTail    = pIn->numMipLevels;\n    UINT_64       mipChainSliceSize = 0;\n    UINT_64       mipSize[MaxMipLevels];\n    UINT_64       mipSliceSize[MaxMipLevels];\n\n    const ADDR_EXTENT3D fixedTailMaxDim = tailMaxDim;\n\n    for (UINT_32 mipIdx = 0; mipIdx < pIn->numMipLevels; mipIdx++)\n    {\n        const ADDR_EXTENT3D  mipExtents = GetMipExtent(mip0Dims, mipIdx);\n\n        if (SupportsMipTail(pIn->swizzleMode) &&\n            IsInMipTail(fixedTailMaxDim, mipExtents, maxMipsInTail, pIn->numMipLevels - mipIdx))\n        {\n            firstMipInTail     = mipIdx;\n            mipChainSliceSize += blockSize / pOut->blockExtent.depth;\n            break;\n        }\n        else\n        {\n            const UINT_32 pitch  = UseCustomPitch(pIn)\n                                        ? pOut->pitch\n                                        : ((mipIdx == 0) && CanTrimLinearPadding(pIn))\n                                          ? PowTwoAlign(mipExtents.width,  128u / bytesPerPixel)\n                                          : PowTwoAlign(mipExtents.width,  pOut->blockExtent.width);\n            const UINT_32 height = UseCustomHeight(pIn)\n                                        ? pOut->height\n                                        : PowTwoAlign(mipExtents.height, pOut->blockExtent.height);\n            const UINT_32 depth  = PowTwoAlign(mipExtents.depth,  pOut->blockExtent.depth);\n\n            // The original \"blockExtent\" calculation does subtraction of logs (i.e., division) to get the\n            // sizes.  We aligned our pitch and height to those sizes, which means we need to multiply the various\n            // factors back together to get back to the slice size.\n            const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height * pIn->numSamples * (pIn->bpp >> 3);\n\n            mipSize[mipIdx]       = sliceSize * depth;\n            mipSliceSize[mipIdx]  = sliceSize * pOut->blockExtent.depth;\n            mipChainSliceSize    += sliceSize;\n\n            if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[mipIdx].pitch  = pitch;\n                pOut->pMipInfo[mipIdx].height = height;\n                pOut->pMipInfo[mipIdx].depth  = depth;\n\n                // The slice size of a linear image was calculated above as if the \"pitch\" is 256 byte aligned.\n                // However, the rendering pitch is aligned to 128 bytes, and that is what needs to be reported\n                // to our clients.\n                if (IsLinear(pIn->swizzleMode))\n                {\n                    pOut->pMipInfo[mipIdx].pitch = PowTwoAlign(mipExtents.width,  128u / bytesPerPixel);\n                }\n            }\n        }\n    }\n\n    pOut->sliceSize        = mipChainSliceSize;\n    pOut->surfSize         = mipChainSliceSize * pOut->numSlices;\n    pOut->mipChainInTail   = (firstMipInTail == 0) ? TRUE : FALSE;\n    pOut->firstMipIdInTail = firstMipInTail;\n\n    if (pOut->pMipInfo != NULL)\n    {\n       if (IsLinear(pIn->swizzleMode))\n        {\n            // 1. Linear swizzle mode doesn't have miptails.\n            // 2. The organization of linear 3D mipmap resource is same as GFX11, we should use mip slice size to\n            // caculate mip offset.\n            ADDR_ASSERT(firstMipInTail == pIn->numMipLevels);\n\n            UINT_64 sliceSize = 0;\n\n            for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)\n            {\n                pOut->pMipInfo[i].offset           = sliceSize;\n                pOut->pMipInfo[i].macroBlockOffset = sliceSize;\n                pOut->pMipInfo[i].mipTailOffset    = 0;\n\n                sliceSize += mipSliceSize[i];\n            }\n        }\n        else\n        {\n           UINT_64 offset         = 0;\n           UINT_64 macroBlkOffset = 0;\n           UINT_32 tailMaxDepth   = 0;\n\n           ADDR_EXTENT3D  mipExtentFirstInTail = {};\n           if (firstMipInTail != pIn->numMipLevels)\n           {\n              mipExtentFirstInTail = GetMipExtent(mip0Dims, firstMipInTail);\n\n              offset         = blockSize *\n                 PowTwoAlign(mipExtentFirstInTail.depth,\n                             pOut->blockExtent.depth) / pOut->blockExtent.depth;\n              macroBlkOffset = blockSize;\n           }\n\n           for (INT_32 i = firstMipInTail - 1; i >= 0; i--)\n           {\n              pOut->pMipInfo[i].offset           = offset;\n              pOut->pMipInfo[i].macroBlockOffset = macroBlkOffset;\n              pOut->pMipInfo[i].mipTailOffset    = 0;\n\n              offset         += mipSize[i];\n              macroBlkOffset += mipSliceSize[i];\n           }\n\n           GetMipOrigin(pIn, mipExtentFirstInTail, pOut);\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputeSurfaceInfo\n*\n*   @brief\n*       Internal function to calculate alignment for a surface\n*\n*   @return\n*       VOID\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx12Lib::HwlComputeSurfaceInfo(\n     const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ComputeBlockDimensionForSurf(&pOut->blockExtent,\n                                 pIn->bpp,\n                                 pIn->numSamples,\n                                 pIn->swizzleMode);\n\n    ADDR_E_RETURNCODE  returnCode = ApplyCustomizedPitchHeight(pIn, pOut);\n\n    if (returnCode == ADDR_OK)\n    {\n        pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockExtent.depth);\n        pOut->baseAlign = 1 << GetBlockSizeLog2(pIn->swizzleMode);\n\n        GetMipOffset(pIn, pOut);\n\n        SanityCheckSurfSize(pIn, pOut);\n\n        // Slices must be exact multiples of the block sizes.  However:\n        // - with 3D images, one block will contain multiple slices, so that needs to be taken into account.\n        // - with linear images that have only once slice, we may trim and use the pitch alignment for size.\n        ADDR_ASSERT(((pOut->sliceSize * pOut->blockExtent.depth) %\n                     GetBlockSize(pIn->swizzleMode, CanTrimLinearPadding(pIn))) == 0);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetBaseMipExtents\n*\n*   @brief\n*       Return the size of the base mip level in a nice cozy little structure.\n*\n************************************************************************************************************************\n*/\nADDR_EXTENT3D Gfx12Lib::GetBaseMipExtents(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn\n    ) const\n{\n    return { pIn->width,\n             pIn->height,\n             (IsTex3d(pIn->resourceType) ? pIn->numSlices : 1) }; // slices is depth for 3d\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetMaxNumMipsInTail\n*\n*   @brief\n*       Return max number of mips in tails\n*\n*   @return\n*       Max number of mips in tails\n************************************************************************************************************************\n*/\nUINT_32 Gfx12Lib::GetMaxNumMipsInTail(\n    Addr3SwizzleMode  swizzleMode,\n    UINT_32           blockSizeLog2     ///< block size log2\n    ) const\n{\n    UINT_32 effectiveLog2 = blockSizeLog2;\n    UINT_32 mipsInTail    = 1;\n\n    if (Is3dSwizzle(swizzleMode))\n    {\n        effectiveLog2 -= (blockSizeLog2 - 8) / 3;\n    }\n\n    if (effectiveLog2 > 8)\n    {\n        mipsInTail = (effectiveLog2 <= 11) ? (1 + (1 << (effectiveLog2 - 9))) : (effectiveLog2 - 4);\n    }\n\n    return mipsInTail;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx12Lib::HwlComputeSurfaceAddrFromCoordTiled(\n     const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    // 256B block cannot support 3D image.\n    ADDR_ASSERT((IsTex3d(pIn->resourceType) && IsBlock256b(pIn->swizzleMode)) == FALSE);\n\n    ADDR3_COMPUTE_SURFACE_INFO_INPUT  localIn = {};\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n    ADDR3_MIP_INFO                    mipInfo[MaxMipLevels];\n\n    localIn.size         = sizeof(localIn);\n    localIn.flags        = pIn->flags;\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.resourceType = pIn->resourceType;\n    localIn.format       = ADDR_FMT_INVALID;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unAlignedDims.width, 1u);\n    localIn.height       = Max(pIn->unAlignedDims.height, 1u);\n    localIn.numSlices    = Max(pIn->unAlignedDims.depth, 1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n    localIn.numSamples   = Max(pIn->numSamples, 1u);\n\n    localOut.size        = sizeof(localOut);\n    localOut.pMipInfo    = mipInfo;\n\n    ADDR_E_RETURNCODE ret = ComputeSurfaceInfo(&localIn, &localOut);\n\n    if (ret == ADDR_OK)\n    {\n        const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);\n        const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const UINT_32 eqIndex     = GetEquationTableEntry(pIn->swizzleMode, Log2(localIn.numSamples), elemLog2);\n\n        if (eqIndex != ADDR_INVALID_EQUATION_INDEX)\n        {\n            const BOOL_32 inTail     = ((mipInfo[pIn->mipId].mipTailOffset != 0) && (blkSizeLog2 != Log2Size256));\n            const BOOL_32 is3dNoMsaa = ((IsTex3d(pIn->resourceType) == TRUE) && (localIn.numSamples == 1));\n            const UINT_64 sliceSize  = is3dNoMsaa ? (localOut.sliceSize * localOut.blockExtent.depth)\n                                                  : localOut.sliceSize;\n            const UINT_32 sliceId    = is3dNoMsaa ? (pIn->slice / localOut.blockExtent.depth) : pIn->slice;\n            const UINT_32 x          = inTail ? (pIn->x + mipInfo[pIn->mipId].mipTailCoordX) : pIn->x;\n            const UINT_32 y          = inTail ? (pIn->y + mipInfo[pIn->mipId].mipTailCoordY) : pIn->y;\n            const UINT_32 z          = inTail ? (pIn->slice + mipInfo[pIn->mipId].mipTailCoordZ) : pIn->slice;\n            const UINT_32 pb         = mipInfo[pIn->mipId].pitch / localOut.blockExtent.width;\n            const UINT_32 yb         = pIn->y / localOut.blockExtent.height;\n            const UINT_32 xb         = pIn->x / localOut.blockExtent.width;\n            const UINT_64 blkIdx     = yb * pb + xb;\n            const UINT_32 blkOffset  = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                 x << elemLog2,\n                                                                 y,\n                                                                 z,\n                                                                 pIn->sample);\n            pOut->addr = sliceSize * sliceId +\n                         mipInfo[pIn->mipId].macroBlockOffset +\n                         (blkIdx << blkSizeLog2) +\n                         blkOffset;\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputePipeBankXor\n*\n*   @brief\n*       Generate a PipeBankXor value to be ORed into bits above numSwizzleBits of address\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx12Lib::HwlComputePipeBankXor(\n    const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,     ///< [in] input structure\n    ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut     ///< [out] output structure\n    ) const\n{\n    if ((m_numSwizzleBits != 0)               && // does this configuration support swizzling\n        //         base address XOR in GFX12 will be applied to all blk_size = 4KB, 64KB, or 256KB swizzle modes,\n        //         Note that Linear and 256B are excluded.\n        (IsLinear(pIn->swizzleMode) == FALSE) &&\n        (IsBlock256b(pIn->swizzleMode) == FALSE))\n    {\n        pOut->pipeBankXor = pIn->surfIndex % (1 << m_numSwizzleBits);\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::ComputeOffsetFromEquation\n*\n*   @brief\n*       Compute offset from equation\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nUINT_32 Gfx12Lib::ComputeOffsetFromEquation(\n    const ADDR_EQUATION* pEq,   ///< Equation\n    UINT_32              x,     ///< x coord in bytes\n    UINT_32              y,     ///< y coord in pixel\n    UINT_32              z,     ///< z coord in slice\n    UINT_32              s      ///< MSAA sample index\n    ) const\n{\n    UINT_32 offset = 0;\n\n    for (UINT_32 i = 0; i < pEq->numBits; i++)\n    {\n        UINT_32 v = 0;\n\n        if (pEq->addr[i].valid)\n        {\n            if (pEq->addr[i].channel == 0)\n            {\n                v ^= (x >> pEq->addr[i].index) & 1;\n            }\n            else if (pEq->addr[i].channel == 1)\n            {\n                v ^= (y >> pEq->addr[i].index) & 1;\n            }\n            else if (pEq->addr[i].channel == 2)\n            {\n                v ^= (z >> pEq->addr[i].index) & 1;\n            }\n            else if (pEq->addr[i].channel == 3)\n            {\n                v ^= (s >> pEq->addr[i].index) & 1;\n            }\n            else\n            {\n                ADDR_ASSERT_ALWAYS();\n            }\n        }\n\n        offset |= (v << i);\n    }\n\n    return offset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::GetSwizzlePatternInfo\n*\n*   @brief\n*       Get swizzle pattern\n*\n*   @return\n*       Swizzle pattern information\n************************************************************************************************************************\n*/\nconst ADDR_SW_PATINFO* Gfx12Lib::GetSwizzlePatternInfo(\n    Addr3SwizzleMode swizzleMode,       ///< Swizzle mode\n    UINT_32          elemLog2,          ///< Element size in bytes log2\n    UINT_32          numFrag            ///< Number of fragment\n    ) const\n{\n    const ADDR_SW_PATINFO* patInfo = NULL;\n\n    if (Is2dSwizzle(swizzleMode) == FALSE)\n    {\n        ADDR_ASSERT(numFrag == 1);\n    }\n\n    switch (swizzleMode)\n    {\n    case ADDR3_256KB_2D:\n        switch (numFrag)\n        {\n        case 1:\n            patInfo = GFX12_SW_256KB_2D_1xAA_PATINFO;\n            break;\n        case 2:\n            patInfo = GFX12_SW_256KB_2D_2xAA_PATINFO;\n            break;\n        case 4:\n            patInfo = GFX12_SW_256KB_2D_4xAA_PATINFO;\n            break;\n        case 8:\n            patInfo = GFX12_SW_256KB_2D_8xAA_PATINFO;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n        }\n        break;\n    case ADDR3_256KB_3D:\n        patInfo = GFX12_SW_256KB_3D_PATINFO;\n        break;\n    case ADDR3_64KB_2D:\n        switch (numFrag)\n        {\n        case 1:\n            patInfo = GFX12_SW_64KB_2D_1xAA_PATINFO;\n            break;\n        case 2:\n            patInfo = GFX12_SW_64KB_2D_2xAA_PATINFO;\n            break;\n        case 4:\n            patInfo = GFX12_SW_64KB_2D_4xAA_PATINFO;\n            break;\n        case 8:\n            patInfo = GFX12_SW_64KB_2D_8xAA_PATINFO;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n        }\n        break;\n    case ADDR3_64KB_3D:\n        patInfo = GFX12_SW_64KB_3D_PATINFO;\n        break;\n    case ADDR3_4KB_2D:\n        switch (numFrag)\n        {\n        case 1:\n            patInfo = GFX12_SW_4KB_2D_1xAA_PATINFO;\n            break;\n        case 2:\n            patInfo = GFX12_SW_4KB_2D_2xAA_PATINFO;\n            break;\n        case 4:\n            patInfo = GFX12_SW_4KB_2D_4xAA_PATINFO;\n            break;\n        case 8:\n            patInfo = GFX12_SW_4KB_2D_8xAA_PATINFO;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n        }\n        break;\n    case ADDR3_4KB_3D:\n        patInfo = GFX12_SW_4KB_3D_PATINFO;\n        break;\n    case ADDR3_256B_2D:\n        switch (numFrag)\n        {\n        case 1:\n            patInfo = GFX12_SW_256B_2D_1xAA_PATINFO;\n            break;\n        case 2:\n            patInfo = GFX12_SW_256B_2D_2xAA_PATINFO;\n            break;\n        case 4:\n            patInfo = GFX12_SW_256B_2D_4xAA_PATINFO;\n            break;\n        case 8:\n            patInfo = GFX12_SW_256B_2D_8xAA_PATINFO;\n            break;\n        default:\n            break;\n        }\n        break;\n    default:\n        ADDR_ASSERT_ALWAYS();\n        break;\n    }\n\n    return (patInfo != NULL) ? &patInfo[elemLog2] : NULL;\n}\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlInitGlobalParams\n*\n*   @brief\n*       Initializes global parameters\n*\n*   @return\n*       TRUE if all settings are valid\n*\n************************************************************************************************************************\n*/\nBOOL_32 Gfx12Lib::HwlInitGlobalParams(\n    const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input\n{\n    BOOL_32              valid = TRUE;\n    GB_ADDR_CONFIG_GFX12 gbAddrConfig;\n\n    gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;\n\n    switch (gbAddrConfig.bits.NUM_PIPES)\n    {\n        case ADDR_CONFIG_1_PIPE:\n            m_pipesLog2 = 0;\n            break;\n        case ADDR_CONFIG_2_PIPE:\n            m_pipesLog2 = 1;\n            break;\n        case ADDR_CONFIG_4_PIPE:\n            m_pipesLog2 = 2;\n            break;\n        case ADDR_CONFIG_8_PIPE:\n            m_pipesLog2 = 3;\n            break;\n        case ADDR_CONFIG_16_PIPE:\n            m_pipesLog2 = 4;\n            break;\n        case ADDR_CONFIG_32_PIPE:\n            m_pipesLog2 = 5;\n            break;\n        case ADDR_CONFIG_64_PIPE:\n            m_pipesLog2 = 6;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)\n    {\n        case ADDR_CONFIG_PIPE_INTERLEAVE_256B:\n            m_pipeInterleaveLog2 = 8;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_512B:\n            m_pipeInterleaveLog2 = 9;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:\n            m_pipeInterleaveLog2 = 10;\n            break;\n        case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:\n            m_pipeInterleaveLog2 = 11;\n            break;\n        default:\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n            break;\n    }\n\n    m_numSwizzleBits = ((m_pipesLog2 >= 3) ? m_pipesLog2 - 2 : 0);\n\n    if (valid)\n    {\n        InitEquationTable();\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputeNonBlockCompressedView\n*\n*   @brief\n*       Compute non-block-compressed view for a given mipmap level/slice.\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx12Lib::HwlComputeNonBlockCompressedView(\n    const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,    ///< [in] input structure\n    ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&\n        ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))\n    {\n        // Only support BC1~BC7, ASTC, or ETC2 for now...\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else\n    {\n        UINT_32 bcWidth, bcHeight;\n        const UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, NULL, &bcWidth, &bcHeight);\n\n        ADDR3_COMPUTE_SURFACE_INFO_INPUT infoIn = {};\n        infoIn.size         = sizeof(infoIn);\n        infoIn.flags        = pIn->flags;\n        infoIn.swizzleMode  = pIn->swizzleMode;\n        infoIn.resourceType = pIn->resourceType;\n        infoIn.format       = pIn->format;\n        infoIn.bpp          = bpp;\n        infoIn.width        = RoundUpQuotient(pIn->unAlignedDims.width, bcWidth);\n        infoIn.height       = RoundUpQuotient(pIn->unAlignedDims.height, bcHeight);\n        infoIn.numSlices    = pIn->unAlignedDims.depth;\n        infoIn.numMipLevels = pIn->numMipLevels;\n        infoIn.numSamples   = 1;\n\n        ADDR3_MIP_INFO mipInfo[MaxMipLevels] = {};\n\n        ADDR3_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};\n        infoOut.size     = sizeof(infoOut);\n        infoOut.pMipInfo = mipInfo;\n\n        returnCode = HwlComputeSurfaceInfo(&infoIn, &infoOut);\n\n        if (returnCode == ADDR_OK)\n        {\n            ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT subOffIn = {};\n            subOffIn.size             = sizeof(subOffIn);\n            subOffIn.swizzleMode      = infoIn.swizzleMode;\n            subOffIn.resourceType     = infoIn.resourceType;\n            subOffIn.pipeBankXor      = pIn->pipeBankXor;\n            subOffIn.slice            = pIn->slice;\n            subOffIn.sliceSize        = infoOut.sliceSize;\n            subOffIn.macroBlockOffset = mipInfo[pIn->mipId].macroBlockOffset;\n            subOffIn.mipTailOffset    = mipInfo[pIn->mipId].mipTailOffset;\n\n            ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT subOffOut = {};\n            subOffOut.size = sizeof(subOffOut);\n\n            // For any mipmap level, move nonBc view base address by offset\n            HwlComputeSubResourceOffsetForSwizzlePattern(&subOffIn, &subOffOut);\n            pOut->offset = subOffOut.offset;\n\n            ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT slicePbXorIn = {};\n            slicePbXorIn.size            = sizeof(slicePbXorIn);\n            slicePbXorIn.swizzleMode     = infoIn.swizzleMode;\n            slicePbXorIn.resourceType    = infoIn.resourceType;\n            slicePbXorIn.bpe             = infoIn.bpp;\n            slicePbXorIn.basePipeBankXor = pIn->pipeBankXor;\n            slicePbXorIn.slice           = pIn->slice;\n            slicePbXorIn.numSamples      = 1;\n\n            ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT slicePbXorOut = {};\n            slicePbXorOut.size = sizeof(slicePbXorOut);\n\n            // For any mipmap level, nonBc view should use computed pbXor\n            HwlComputeSlicePipeBankXor(&slicePbXorIn, &slicePbXorOut);\n            pOut->pipeBankXor = slicePbXorOut.pipeBankXor;\n\n            const BOOL_32 tiled            = (pIn->swizzleMode != ADDR3_LINEAR);\n            const BOOL_32 inTail           = tiled && (pIn->mipId >= infoOut.firstMipIdInTail);\n            const UINT_32 requestMipWidth  =\n                    RoundUpQuotient(Max(pIn->unAlignedDims.width  >> pIn->mipId, 1u), bcWidth);\n            const UINT_32 requestMipHeight =\n                    RoundUpQuotient(Max(pIn->unAlignedDims.height >> pIn->mipId, 1u), bcHeight);\n\n            if (inTail)\n            {\n                // For mipmap level that is in mip tail block, hack a lot of things...\n                // Basically all mipmap levels in tail block will be viewed as a small mipmap chain that all levels\n                // are fit in tail block:\n\n                // - mipId = relative mip id (which is counted from first mip ID in tail in original mip chain)\n                pOut->mipId = pIn->mipId - infoOut.firstMipIdInTail;\n\n                // - at least 2 mipmap levels (since only 1 mipmap level will not be viewed as mipmap!)\n                pOut->numMipLevels = Max(infoIn.numMipLevels - infoOut.firstMipIdInTail, 2u);\n\n                // - (mip0) width = requestMipWidth << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unAlignedDims.width  = Min(requestMipWidth << pOut->mipId, infoOut.blockExtent.width / 2);\n\n                // - (mip0) height = requestMipHeight << mipId, the value can't exceed mip tail dimension threshold\n                pOut->unAlignedDims.height = Min(requestMipHeight << pOut->mipId, infoOut.blockExtent.height);\n            }\n            // This check should cover at least mipId == 0\n            else if ((requestMipWidth << pIn->mipId) == infoIn.width)\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded without losing element:\n                // - only one mipmap level and mipId = 0\n                pOut->mipId        = 0;\n                pOut->numMipLevels = 1;\n\n                // (mip0) width = requestMipWidth\n                pOut->unAlignedDims.width  = requestMipWidth;\n\n                // (mip0) height = requestMipHeight\n                pOut->unAlignedDims.height = requestMipHeight;\n            }\n            else\n            {\n                // For mipmap level [N] that is not in mip tail block and downgraded with element losing,\n                // We have to make it a multiple mipmap view (2 levels view here), add one extra element if needed,\n                // because single mip view may have different pitch value than original (multiple) mip view...\n                // A simple case would be:\n                // - 64KB block swizzle mode, 8 Bytes-Per-Element. Block dim = [0x80, 0x40]\n                // - 2 mipmap levels with API mip0 width = 0x401/mip1 width = 0x200 and non-BC view\n                //   mip0 width = 0x101/mip1 width = 0x80\n                // By multiple mip view, the pitch for mip level 1 would be 0x100 bytes, due to rounding up logic in\n                // GetMipSize(), and by single mip level view the pitch will only be 0x80 bytes.\n\n                // - 2 levels and mipId = 1\n                pOut->mipId        = 1;\n                pOut->numMipLevels = 2;\n\n                const UINT_32 upperMipWidth  =\n                    RoundUpQuotient(Max(pIn->unAlignedDims.width  >> (pIn->mipId - 1), 1u), bcWidth);\n                const UINT_32 upperMipHeight =\n                    RoundUpQuotient(Max(pIn->unAlignedDims.height >> (pIn->mipId - 1), 1u), bcHeight);\n\n                const BOOL_32 needToAvoidInTail = tiled                                              &&\n                                                  (requestMipWidth <= infoOut.blockExtent.width / 2) &&\n                                                  (requestMipHeight <= infoOut.blockExtent.height);\n\n                const UINT_32 hwMipWidth  =\n                    PowTwoAlign(ShiftCeil(infoIn.width, pIn->mipId), infoOut.blockExtent.width);\n                const UINT_32 hwMipHeight =\n                    PowTwoAlign(ShiftCeil(infoIn.height, pIn->mipId), infoOut.blockExtent.height);\n\n                const BOOL_32 needExtraWidth =\n                    ((upperMipWidth < requestMipWidth * 2) ||\n                     ((upperMipWidth == requestMipWidth * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipWidth > PowTwoAlign(requestMipWidth, infoOut.blockExtent.width)))));\n\n                const BOOL_32 needExtraHeight =\n                    ((upperMipHeight < requestMipHeight * 2) ||\n                     ((upperMipHeight == requestMipHeight * 2) &&\n                      ((needToAvoidInTail == TRUE) ||\n                       (hwMipHeight > PowTwoAlign(requestMipHeight, infoOut.blockExtent.height)))));\n\n                // (mip0) width = requestLastMipLevelWidth\n                pOut->unAlignedDims.width  = upperMipWidth + (needExtraWidth ? 1: 0);\n\n                // (mip0) height = requestLastMipLevelHeight\n                pOut->unAlignedDims.height = upperMipHeight + (needExtraHeight ? 1: 0);\n            }\n\n            // Assert the downgrading from this mip[0] width would still generate correct mip[N] width\n            ADDR_ASSERT(ShiftRight(pOut->unAlignedDims.width, pOut->mipId)  == requestMipWidth);\n            // Assert the downgrading from this mip[0] height would still generate correct mip[N] height\n            ADDR_ASSERT(ShiftRight(pOut->unAlignedDims.height, pOut->mipId) == requestMipHeight);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Compute sub resource offset to support swizzle pattern\n*\n*   @return\n*       VOID\n************************************************************************************************************************\n*/\nVOID Gfx12Lib::HwlComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,    ///< [in] input structure\n    ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut    ///< [out] output structure\n    ) const\n{\n    pOut->offset = pIn->slice * pIn->sliceSize + pIn->macroBlockOffset;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::HwlComputeSlicePipeBankXor\n*\n*   @brief\n*       Generate slice PipeBankXor value based on base PipeBankXor value and slice id\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx12Lib::HwlComputeSlicePipeBankXor(\n    const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,   ///< [in] input structure\n    ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut   ///< [out] output structure\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    // PipeBankXor is only applied to 4KB, 64KB and 256KB on GFX12.\n    if ((IsLinear(pIn->swizzleMode) == FALSE) && (IsBlock256b(pIn->swizzleMode) == FALSE))\n    {\n        if (pIn->bpe == 0)\n        {\n            // Require a valid bytes-per-element value passed from client...\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,\n                                                                    Log2(pIn->bpe >> 3),\n                                                                    1);\n\n            if (pPatInfo != NULL)\n            {\n                const UINT_32 elemLog2    = Log2(pIn->bpe >> 3);\n                const UINT_32 eqIndex     = GetEquationTableEntry(pIn->swizzleMode, Log2(pIn->numSamples), elemLog2);\n\n                const UINT_32 pipeBankXorOffset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],\n                                                                            0,\n                                                                            0,\n                                                                            pIn->slice,\n                                                                            0);\n\n                const UINT_32 pipeBankXor = pipeBankXorOffset >> m_pipeInterleaveLog2;\n\n                // Should have no bit set under pipe interleave\n                ADDR_ASSERT((pipeBankXor << m_pipeInterleaveLog2) == pipeBankXorOffset);\n\n                pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeBankXor;\n            }\n            else\n            {\n                // Should never come here...\n                ADDR_NOT_IMPLEMENTED();\n\n                returnCode = ADDR_NOTSUPPORTED;\n            }\n        }\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx12Lib::SanityCheckSurfSize\n*\n*   @brief\n*       Calculate the surface size via the exact hardware algorithm to see if it matches.\n*\n*   @return\n************************************************************************************************************************\n*/\nvoid Gfx12Lib::SanityCheckSurfSize(\n    const ADDR3_COMPUTE_SURFACE_INFO_INPUT*   pIn,\n    const ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*  pOut\n    ) const\n{\n#if DEBUG\n    // Verify that the requested image size is valid for the below algorithm.  The below code includes\n    // implicit assumptions about the surface dimensions being less than \"MaxImageDim\"; otherwise, it can't\n    // calculate \"firstMipInTail\" accurately and the below assertion will trip incorrectly.\n    //\n    // Surfaces destined for use only on the SDMA engine can exceed the gfx-engine-imposed limitations of\n    // the \"maximum\" image dimensions.\n    if ((pIn->width  <= MaxImageDim)        &&\n        (pIn->height <= MaxImageDim)        &&\n        (pIn->numMipLevels <= MaxMipLevels) &&\n        (UseCustomPitch(pIn)  == FALSE)     &&\n        (UseCustomHeight(pIn) == FALSE)     &&\n        // HiZS surfaces have a reduced image size (i.e,. each pixel represents an 8x8 region of the parent\n        // image, at least for single samples) but they still have the same number of mip levels as the\n        // parent image.  This disconnect produces false assertions below as the image size doesn't apparently\n        // support the specified number of mip levels.\n        ((pIn->flags.hiZHiS == 0) || (pIn->numMipLevels == 1))   &&\n        !(pIn->flags.view3dAs2dArray))\n    {\n        UINT_32  lastMipSize   = 1;\n        UINT_32  dataChainSize = 0;\n\n        const ADDR_EXTENT3D  mip0Dims      = GetBaseMipExtents(pIn);\n        const UINT_32        blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);\n        const ADDR_EXTENT3D  tailMaxDim    = GetMipTailDim(pIn->swizzleMode, pOut->blockExtent);\n        const UINT_32        maxMipsInTail = GetMaxNumMipsInTail(pIn->swizzleMode, blockSizeLog2);\n\n        UINT_32  firstMipInTail = 0;\n        for (INT_32 mipIdx = MaxMipLevels - 1; mipIdx >= 0; mipIdx--)\n        {\n            const ADDR_EXTENT3D  mipExtents = GetMipExtent(mip0Dims, mipIdx);\n\n            if ((mipExtents.width  <= tailMaxDim.width)  &&\n                (mipExtents.height <= tailMaxDim.height) &&\n                ((static_cast<INT_32>(pIn->numMipLevels) - mipIdx) < static_cast<INT_32>(maxMipsInTail)))\n            {\n                firstMipInTail = mipIdx;\n            }\n        }\n\n        for (INT_32  mipIdx = firstMipInTail - 1; mipIdx >= -1; mipIdx--)\n        {\n            const ADDR_EXTENT3D  mipExtents     = GetMipExtent(mip0Dims, mipIdx);\n            const UINT_32        mipBlockWidth  = ShiftCeil(mipExtents.width,  Log2(pOut->blockExtent.width));\n            const UINT_32        mipBlockHeight = ShiftCeil(mipExtents.height, Log2(pOut->blockExtent.height));\n\n            if (mipIdx < (static_cast<INT_32>(pIn->numMipLevels) - 1))\n            {\n                dataChainSize += lastMipSize;\n            }\n\n            if (mipIdx >= 0)\n            {\n                lastMipSize = 4 * lastMipSize\n                    - ((mipBlockWidth  & 1) ? mipBlockHeight : 0)\n                    - ((mipBlockHeight & 1) ? mipBlockWidth  : 0)\n                    - ((mipBlockWidth  & mipBlockHeight & 1) ? 1 : 0);\n            }\n        }\n\n        if (CanTrimLinearPadding(pIn))\n        {\n            ADDR_ASSERT((pOut->sliceSize * pOut->blockExtent.depth) <= (dataChainSize << blockSizeLog2));\n        }\n        else\n        {\n            ADDR_ASSERT((pOut->sliceSize * pOut->blockExtent.depth) == (dataChainSize << blockSizeLog2));\n        }\n    }\n#endif\n}\n\n} // V3\n} // Addr\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx12/gfx12addrlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2023 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx12addrlib.h\n* @brief Contains the Gfx12Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX12_ADDR_LIB_H__\n#define __GFX12_ADDR_LIB_H__\n\n#include \"addrlib3.h\"\n#include \"coord.h\"\n#include \"gfx12SwizzlePattern.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V3\n{\n\n/**\n************************************************************************************************************************\n* @brief GFX12 specific settings structure.\n************************************************************************************************************************\n*/\nstruct Gfx12ChipSettings\n{\n    struct\n    {\n        // Misc configuration bits\n        UINT_32 reserved : 32;\n    };\n};\n\n/**\n************************************************************************************************************************\n* @brief GFX12 data surface type.\n************************************************************************************************************************\n*/\n\n/**\n************************************************************************************************************************\n* @brief This class is the GFX12 specific address library\n*        function set.\n************************************************************************************************************************\n*/\nclass Gfx12Lib : public Lib\n{\npublic:\n    /// Creates Gfx12Lib object\n    static Addr::Lib* CreateObj(const Client* pClient)\n    {\n        VOID* pMem = Object::ClientAlloc(sizeof(Gfx12Lib), pClient);\n        return (pMem != NULL) ? new (pMem) Gfx12Lib(pClient) : NULL;\n    }\n\nprotected:\n    Gfx12Lib(const Client* pClient);\n    virtual ~Gfx12Lib();\n\n    // Meta surfaces such as Hi-S/Z are essentially images on GFX12, so just return the max\n    // image alignment.\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const { return 256 * 1024; }\n\n    UINT_32 GetMaxNumMipsInTail(\n        Addr3SwizzleMode  swizzleMode,\n        UINT_32           blockSizeLog2) const;\n\n    BOOL_32 IsInMipTail(\n        const ADDR_EXTENT3D&  mipTailDim,\n        const ADDR_EXTENT3D&  mipDims,\n        UINT_32               maxNumMipsInTail,\n        UINT_32               numMipsToTheEnd) const\n    {\n        BOOL_32 inTail = ((mipDims.width   <= mipTailDim.width)  &&\n                          (mipDims.height  <= mipTailDim.height) &&\n                          (numMipsToTheEnd <= maxNumMipsInTail));\n\n        return inTail;\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView(\n        const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,\n        ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut) const;\n\n    virtual VOID HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const\n    {\n        *ppEquationTable = m_equationTable;\n\n        return m_numEquations;\n    }\n\nprivate:\n    Gfx12ChipSettings m_settings;\n    static const SwizzleModeFlags SwizzleModeTable[ADDR3_MAX_TYPE];\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const override;\n\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn) override;\n\n    void SanityCheckSurfSize(\n        const ADDR3_COMPUTE_SURFACE_INFO_INPUT*   pIn,\n        const ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*  pOut) const;\n\n    UINT_32           m_numSwizzleBits;\n\n    static const ADDR_EXTENT3D Block4K_Log2_3d[];\n    static const ADDR_EXTENT3D Block64K_Log2_3d[];\n    static const ADDR_EXTENT3D Block256K_Log2_3d[];\n\n    // Initialize equation table\n    VOID InitEquationTable();\n\n    VOID GetSwizzlePatternFromPatternInfo(\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_BIT_SETTING       (&pSwizzle)[Log2Size256K]) const\n    {\n        memcpy(pSwizzle,\n               GFX12_SW_PATTERN_NIBBLE1[pPatInfo->nibble1Idx],\n               sizeof(GFX12_SW_PATTERN_NIBBLE1[pPatInfo->nibble1Idx]));\n\n        memcpy(&pSwizzle[8],\n               GFX12_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx],\n               sizeof(GFX12_SW_PATTERN_NIBBLE2[pPatInfo->nibble2Idx]));\n\n        memcpy(&pSwizzle[12],\n               GFX12_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx],\n               sizeof(GFX12_SW_PATTERN_NIBBLE3[pPatInfo->nibble3Idx]));\n\n        memcpy(&pSwizzle[16],\n               GFX12_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx],\n               sizeof(GFX12_SW_PATTERN_NIBBLE4[pPatInfo->nibble4Idx]));\n    }\n\n    VOID ConvertSwizzlePatternToEquation(\n        UINT_32                elemLog2,\n        Addr3SwizzleMode       swMode,\n        const ADDR_SW_PATINFO* pPatInfo,\n        ADDR_EQUATION* pEquation) const;\n\n    ADDR_EXTENT3D GetBaseMipExtents(\n        const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    ADDR_EXTENT3D GetBlockPixelDimensions(\n        Addr3SwizzleMode  swizzleMode,\n        UINT_32           log2BytesPerPixel) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo(\n         const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const override;\n\n    static ADDR_EXTENT3D GetMipExtent(\n        const ADDR_EXTENT3D&  mip0,\n        UINT_32               mipId)\n    {\n        return {\n            ShiftCeil(Max(mip0.width, 1u),  mipId),\n            ShiftCeil(Max(mip0.height, 1u), mipId),\n            ShiftCeil(Max(mip0.depth, 1u),  mipId)\n        };\n    }\n\n    //# See 6.3 in //gfxip/gfx10/doc/architecture/ImageAddressing/gfx10_image_addressing.docx\n    // miptail is applied to only larger block size (4kb, 64kb, 256kb), so there is no miptail in linear and\n    // 256b_2d addressing since they are both 256b block.\n    BOOL_32 SupportsMipTail(Addr3SwizzleMode swizzleMode) const\n    {\n        return GetBlockSize(swizzleMode) > 256u;\n    }\n\n    UINT_32 ComputeOffsetFromEquation(\n        const ADDR_EQUATION* pEq,\n        UINT_32              x,\n        UINT_32              y,\n        UINT_32              z,\n        UINT_32              s) const;\n\n    const ADDR_SW_PATINFO* GetSwizzlePatternInfo(\n        Addr3SwizzleMode swizzleMode,\n        UINT_32          log2Elem,\n        UINT_32          numFrag) const;\n\n    VOID GetMipOffset(\n         const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    VOID GetMipOrigin(\n         const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         const ADDR_EXTENT3D&                    mipExtentFirstInTail,\n         ADDR3_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n};\n\n} // V3\n} // Addr\n} // namespace rocr\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx9/gfx9addrlib.cpp",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx9addrlib.cpp\n* @brief Contgfx9ns the implementation for the Gfx9Lib class.\n************************************************************************************************************************\n*/\n\n#include \"gfx9addrlib.h\"\n\n#include \"gfx9_gb_reg.h\"\n\n#include \"amdgpu_asic_addr.h\"\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////////////\nnamespace rocr {\nnamespace Addr\n{\n\n/**\n************************************************************************************************************************\n*   Gfx9HwlInit\n*\n*   @brief\n*       Creates an Gfx9Lib object.\n*\n*   @return\n*       Returns an Gfx9Lib object pointer.\n************************************************************************************************************************\n*/\nAddr::Lib* Gfx9HwlInit(const Client* pClient)\n{\n    return V2::Gfx9Lib::CreateObj(pClient);\n}\n\nnamespace V2\n{\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n//                               Static Const Member\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst SwizzleModeFlags Gfx9Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =\n{//Linear 256B  4KB  64KB   Var    Z    Std   Disp  Rot   XOR    T     RtOpt Reserved\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR\n    {{0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_S\n    {{0,    1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_D\n    {{0,    1,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0}}, // ADDR_SW_256B_R\n\n    {{0,    0,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_Z\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_S\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_D\n    {{0,    0,    1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0}}, // ADDR_SW_4KB_R\n\n    {{0,    0,    0,    1,    0,    1,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_Z\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_S\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_D\n    {{0,    0,    0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0}}, // ADDR_SW_64KB_R\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n\n    {{0,    0,    0,    1,    0,    1,    0,    0,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_Z_T\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_S_T\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_D_T\n    {{0,    0,    0,    1,    0,    0,    0,    0,    1,    1,    1,    0,    0}}, // ADDR_SW_64KB_R_T\n\n    {{0,    0,    1,    0,    0,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_Z_x\n    {{0,    0,    1,    0,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_S_x\n    {{0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_D_x\n    {{0,    0,    1,    0,    0,    0,    0,    0,    1,    1,    0,    0,    0}}, // ADDR_SW_4KB_R_x\n\n    {{0,    0,    0,    1,    0,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_Z_X\n    {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_S_X\n    {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_D_X\n    {{0,    0,    0,    1,    0,    0,    0,    0,    1,    1,    0,    0,    0}}, // ADDR_SW_64KB_R_X\n\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved\n    {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR_GENERAL\n};\n\nconst UINT_32 Gfx9Lib::MipTailOffset256B[] = {2048, 1024, 512, 256, 128, 64, 32, 16, 8, 6, 5, 4, 3, 2, 1, 0};\n\nconst Dim3d   Gfx9Lib::Block256_3dS[]  = {{16, 4, 4}, {8, 4, 4}, {4, 4, 4}, {2, 4, 4}, {1, 4, 4}};\n\nconst Dim3d   Gfx9Lib::Block256_3dZ[]  = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::Gfx9Lib\n*\n*   @brief\n*       Constructor\n*\n************************************************************************************************************************\n*/\nGfx9Lib::Gfx9Lib(const Client* pClient)\n    :\n    Lib(pClient)\n{\n    memset(&m_settings, 0, sizeof(m_settings));\n    memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));\n    memset(m_cachedMetaEqKey, 0, sizeof(m_cachedMetaEqKey));\n    m_metaEqOverrideIndex = 0;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::~Gfx9Lib\n*\n*   @brief\n*       Destructor\n************************************************************************************************************************\n*/\nGfx9Lib::~Gfx9Lib()\n{\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeHtileInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeHtilenfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileInfo(\n    const ADDR2_COMPUTE_HTILE_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pIn->hTileFlags.pipeAligned,\n                                                       pIn->swizzleMode);\n\n    UINT_32 numRbTotal = pIn->hTileFlags.rbAligned ? m_se * m_rbPerSe : 1;\n\n    UINT_32 numCompressBlkPerMetaBlk, numCompressBlkPerMetaBlkLog2;\n\n    if ((numPipeTotal == 1) && (numRbTotal == 1))\n    {\n        numCompressBlkPerMetaBlkLog2 = 10;\n    }\n    else\n    {\n        if (m_settings.applyAliasFix)\n        {\n            numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + Max(10u, m_pipeInterleaveLog2);\n        }\n        else\n        {\n            numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + 10;\n        }\n    }\n\n    numCompressBlkPerMetaBlk = 1 << numCompressBlkPerMetaBlkLog2;\n\n    Dim3d   metaBlkDim   = {8, 8, 1};\n    UINT_32 totalAmpBits = numCompressBlkPerMetaBlkLog2;\n    UINT_32 widthAmp     = (pIn->numMipLevels > 1) ? (totalAmpBits >> 1) : RoundHalf(totalAmpBits);\n    UINT_32 heightAmp    = totalAmpBits - widthAmp;\n    metaBlkDim.w <<= widthAmp;\n    metaBlkDim.h <<= heightAmp;\n\n#if DEBUG\n    Dim3d metaBlkDimDbg = {8, 8, 1};\n    for (UINT_32 index = 0; index < numCompressBlkPerMetaBlkLog2; index++)\n    {\n        if ((metaBlkDimDbg.h < metaBlkDimDbg.w) ||\n            ((pIn->numMipLevels > 1) && (metaBlkDimDbg.h == metaBlkDimDbg.w)))\n        {\n            metaBlkDimDbg.h <<= 1;\n        }\n        else\n        {\n            metaBlkDimDbg.w <<= 1;\n        }\n    }\n    ADDR_ASSERT((metaBlkDimDbg.w == metaBlkDim.w) && (metaBlkDimDbg.h == metaBlkDim.h));\n#endif\n\n    UINT_32 numMetaBlkX;\n    UINT_32 numMetaBlkY;\n    UINT_32 numMetaBlkZ;\n\n    GetMetaMipInfo(pIn->numMipLevels, &metaBlkDim, FALSE, pOut->pMipInfo,\n                   pIn->unalignedWidth, pIn->unalignedHeight, pIn->numSlices,\n                   &numMetaBlkX, &numMetaBlkY, &numMetaBlkZ);\n\n    const UINT_32 metaBlkSize = numCompressBlkPerMetaBlk << 2;\n    UINT_32       align       = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;\n\n    if ((IsXor(pIn->swizzleMode) == FALSE) && (numPipeTotal > 2))\n    {\n        align *= (numPipeTotal >> 1);\n    }\n\n    align = Max(align, metaBlkSize);\n\n    if (m_settings.metaBaseAlignFix)\n    {\n        align = Max(align, GetBlockSize(pIn->swizzleMode));\n    }\n\n    if (m_settings.htileAlignFix)\n    {\n        const INT_32 metaBlkSizeLog2        = numCompressBlkPerMetaBlkLog2 + 2;\n        const INT_32 htileCachelineSizeLog2 = 11;\n        const INT_32 maxNumOfRbMaskBits     = 1 + Log2(numPipeTotal) + Log2(numRbTotal);\n\n        INT_32 rbMaskPadding = Max(0, htileCachelineSizeLog2 - (metaBlkSizeLog2 - maxNumOfRbMaskBits));\n\n        align <<= rbMaskPadding;\n    }\n\n    pOut->pitch      = numMetaBlkX * metaBlkDim.w;\n    pOut->height     = numMetaBlkY * metaBlkDim.h;\n    pOut->sliceSize  = numMetaBlkX * numMetaBlkY * metaBlkSize;\n\n    pOut->metaBlkWidth       = metaBlkDim.w;\n    pOut->metaBlkHeight      = metaBlkDim.h;\n    pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;\n\n    pOut->baseAlign  = align;\n    pOut->htileBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, align);\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeCmaskInfo\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskInfo\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskInfo(\n    const ADDR2_COMPUTE_CMASK_INFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);\n\n    UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pIn->cMaskFlags.pipeAligned,\n                                                       pIn->swizzleMode);\n\n    UINT_32 numRbTotal = pIn->cMaskFlags.rbAligned ? m_se * m_rbPerSe : 1;\n\n    UINT_32 numCompressBlkPerMetaBlkLog2, numCompressBlkPerMetaBlk;\n\n    if ((numPipeTotal == 1) && (numRbTotal == 1))\n    {\n        numCompressBlkPerMetaBlkLog2 = 13;\n    }\n    else\n    {\n        if (m_settings.applyAliasFix)\n        {\n            numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + Max(10u, m_pipeInterleaveLog2);\n        }\n        else\n        {\n            numCompressBlkPerMetaBlkLog2 = m_seLog2 + m_rbPerSeLog2 + 10;\n        }\n\n        numCompressBlkPerMetaBlkLog2 = Max(numCompressBlkPerMetaBlkLog2, 13u);\n    }\n\n    numCompressBlkPerMetaBlk = 1 << numCompressBlkPerMetaBlkLog2;\n\n    Dim2d metaBlkDim = {8, 8};\n    UINT_32 totalAmpBits = numCompressBlkPerMetaBlkLog2;\n    UINT_32 heightAmp = totalAmpBits >> 1;\n    UINT_32 widthAmp = totalAmpBits - heightAmp;\n    metaBlkDim.w <<= widthAmp;\n    metaBlkDim.h <<= heightAmp;\n\n#if DEBUG\n    Dim2d metaBlkDimDbg = {8, 8};\n    for (UINT_32 index = 0; index < numCompressBlkPerMetaBlkLog2; index++)\n    {\n        if (metaBlkDimDbg.h < metaBlkDimDbg.w)\n        {\n            metaBlkDimDbg.h <<= 1;\n        }\n        else\n        {\n            metaBlkDimDbg.w <<= 1;\n        }\n    }\n    ADDR_ASSERT((metaBlkDimDbg.w == metaBlkDim.w) && (metaBlkDimDbg.h == metaBlkDim.h));\n#endif\n\n    UINT_32 numMetaBlkX = (pIn->unalignedWidth  + metaBlkDim.w - 1) / metaBlkDim.w;\n    UINT_32 numMetaBlkY = (pIn->unalignedHeight + metaBlkDim.h - 1) / metaBlkDim.h;\n    UINT_32 numMetaBlkZ = Max(pIn->numSlices, 1u);\n\n    UINT_32 sizeAlign = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;\n\n    if (m_settings.metaBaseAlignFix)\n    {\n        sizeAlign = Max(sizeAlign, GetBlockSize(pIn->swizzleMode));\n    }\n\n    pOut->pitch      = numMetaBlkX * metaBlkDim.w;\n    pOut->height     = numMetaBlkY * metaBlkDim.h;\n    pOut->sliceSize  = (numMetaBlkX * numMetaBlkY * numCompressBlkPerMetaBlk) >> 1;\n    pOut->cmaskBytes = PowTwoAlign(pOut->sliceSize * numMetaBlkZ, sizeAlign);\n    pOut->baseAlign  = Max(numCompressBlkPerMetaBlk >> 1, sizeAlign);\n\n    pOut->metaBlkWidth = metaBlkDim.w;\n    pOut->metaBlkHeight = metaBlkDim.h;\n\n    pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;\n\n    // Get the CMASK address equation (copied from CmaskAddrFromCoord)\n    UINT_32 fmaskBpp              = GetFmaskBpp(1, 1);\n    UINT_32 fmaskElementBytesLog2 = Log2(fmaskBpp >> 3);\n    UINT_32 metaBlkWidthLog2      = Log2(pOut->metaBlkWidth);\n    UINT_32 metaBlkHeightLog2     = Log2(pOut->metaBlkHeight);\n\n    MetaEqParams metaEqParams = {0, fmaskElementBytesLog2, 0, pIn->cMaskFlags,\n                                Gfx9DataFmask, pIn->swizzleMode, pIn->resourceType,\n                                metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0};\n\n    CoordEq *eq = (CoordEq *)((Gfx9Lib *)this)->GetMetaEquation(metaEqParams);\n\n    // Generate the CMASK address equation.\n    pOut->equation.gfx9.num_bits = Min(32u, eq->getsize());\n    bool checked = false;\n    for (unsigned b = 0; b < pOut->equation.gfx9.num_bits; b++) {\n       CoordTerm &bit = (*eq)[b];\n\n       unsigned c;\n       for (c = 0; c < bit.getsize(); c++) {\n          Coordinate &coord = bit[c];\n          pOut->equation.gfx9.bit[b].coord[c].dim = coord.getdim();\n          pOut->equation.gfx9.bit[b].coord[c].ord = coord.getord();\n       }\n       for (; c < 5; c++)\n          pOut->equation.gfx9.bit[b].coord[c].dim = 5; /* meaning invalid */\n    }\n\n    // Reduce num_bits because DIM_M fills the rest of the bits monotonically.\n    for (int b = pOut->equation.gfx9.num_bits - 1; b >= 1; b--) {\n       CoordTerm &prev = (*eq)[b - 1];\n       CoordTerm &cur = (*eq)[b];\n\n       if (cur.getsize() == 1 && cur[0].getdim() == DIM_M &&\n          prev.getsize() == 1 && prev[0].getdim() == DIM_M &&\n          prev[0].getord() + 1 == cur[0].getord())\n          pOut->equation.gfx9.num_bits = b;\n       else\n          break;\n    }\n\n    pOut->equation.gfx9.numPipeBits = GetPipeLog2ForMetaAddressing(pIn->cMaskFlags.pipeAligned,\n                                                                   pIn->swizzleMode);\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetMetaMipInfo\n*\n*   @brief\n*       Get meta mip info\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GetMetaMipInfo(\n    UINT_32 numMipLevels,           ///< [in]  number of mip levels\n    Dim3d* pMetaBlkDim,             ///< [in]  meta block dimension\n    BOOL_32 dataThick,              ///< [in]  data surface is thick\n    ADDR2_META_MIP_INFO* pInfo,     ///< [out] meta mip info\n    UINT_32 mip0Width,              ///< [in]  mip0 width\n    UINT_32 mip0Height,             ///< [in]  mip0 height\n    UINT_32 mip0Depth,              ///< [in]  mip0 depth\n    UINT_32* pNumMetaBlkX,          ///< [out] number of metablock X in mipchain\n    UINT_32* pNumMetaBlkY,          ///< [out] number of metablock Y in mipchain\n    UINT_32* pNumMetaBlkZ)          ///< [out] number of metablock Z in mipchain\n    const\n{\n    UINT_32 numMetaBlkX = (mip0Width  + pMetaBlkDim->w - 1) / pMetaBlkDim->w;\n    UINT_32 numMetaBlkY = (mip0Height + pMetaBlkDim->h - 1) / pMetaBlkDim->h;\n    UINT_32 numMetaBlkZ = (mip0Depth  + pMetaBlkDim->d - 1) / pMetaBlkDim->d;\n    UINT_32 tailWidth   = pMetaBlkDim->w;\n    UINT_32 tailHeight  = pMetaBlkDim->h >> 1;\n    UINT_32 tailDepth   = pMetaBlkDim->d;\n    BOOL_32 inTail      = FALSE;\n    AddrMajorMode major = ADDR_MAJOR_MAX_TYPE;\n\n    if (numMipLevels > 1)\n    {\n        if (dataThick && (numMetaBlkZ > numMetaBlkX) && (numMetaBlkZ > numMetaBlkY))\n        {\n            // Z major\n            major = ADDR_MAJOR_Z;\n        }\n        else if (numMetaBlkX >= numMetaBlkY)\n        {\n            // X major\n            major = ADDR_MAJOR_X;\n        }\n        else\n        {\n            // Y major\n            major = ADDR_MAJOR_Y;\n        }\n\n        inTail = ((mip0Width <= tailWidth) &&\n                  (mip0Height <= tailHeight) &&\n                  ((dataThick == FALSE) || (mip0Depth <= tailDepth)));\n\n        if (inTail == FALSE)\n        {\n            UINT_32 orderLimit;\n            UINT_32 *pMipDim;\n            UINT_32 *pOrderDim;\n\n            if (major == ADDR_MAJOR_Z)\n            {\n                // Z major\n                pMipDim = &numMetaBlkY;\n                pOrderDim = &numMetaBlkZ;\n                orderLimit = 4;\n            }\n            else if (major == ADDR_MAJOR_X)\n            {\n                // X major\n                pMipDim = &numMetaBlkY;\n                pOrderDim = &numMetaBlkX;\n                orderLimit = 4;\n            }\n            else\n            {\n                // Y major\n                pMipDim = &numMetaBlkX;\n                pOrderDim = &numMetaBlkY;\n                orderLimit = 2;\n            }\n\n            if ((*pMipDim < 3) && (*pOrderDim > orderLimit) && (numMipLevels > 3))\n            {\n                *pMipDim += 2;\n            }\n            else\n            {\n                *pMipDim += ((*pMipDim / 2) + (*pMipDim & 1));\n            }\n        }\n    }\n\n    if (pInfo != NULL)\n    {\n        UINT_32 mipWidth  = mip0Width;\n        UINT_32 mipHeight = mip0Height;\n        UINT_32 mipDepth  = mip0Depth;\n        Dim3d   mipCoord  = {0};\n\n        for (UINT_32 mip = 0; mip < numMipLevels; mip++)\n        {\n            if (inTail)\n            {\n                GetMetaMiptailInfo(&pInfo[mip], mipCoord, numMipLevels - mip,\n                                   pMetaBlkDim);\n                break;\n            }\n            else\n            {\n                mipWidth  = PowTwoAlign(mipWidth, pMetaBlkDim->w);\n                mipHeight = PowTwoAlign(mipHeight, pMetaBlkDim->h);\n                mipDepth  = PowTwoAlign(mipDepth, pMetaBlkDim->d);\n\n                pInfo[mip].inMiptail = FALSE;\n                pInfo[mip].startX = mipCoord.w;\n                pInfo[mip].startY = mipCoord.h;\n                pInfo[mip].startZ = mipCoord.d;\n                pInfo[mip].width  = mipWidth;\n                pInfo[mip].height = mipHeight;\n                pInfo[mip].depth  = dataThick ? mipDepth : 1;\n\n                if ((mip >= 3) || (mip & 1))\n                {\n                    switch (major)\n                    {\n                        case ADDR_MAJOR_X:\n                            mipCoord.w += mipWidth;\n                            break;\n                        case ADDR_MAJOR_Y:\n                            mipCoord.h += mipHeight;\n                            break;\n                        case ADDR_MAJOR_Z:\n                            mipCoord.d += mipDepth;\n                            break;\n                        default:\n                            break;\n                    }\n                }\n                else\n                {\n                    switch (major)\n                    {\n                        case ADDR_MAJOR_X:\n                            mipCoord.h += mipHeight;\n                            break;\n                        case ADDR_MAJOR_Y:\n                            mipCoord.w += mipWidth;\n                            break;\n                        case ADDR_MAJOR_Z:\n                            mipCoord.h += mipHeight;\n                            break;\n                        default:\n                            break;\n                    }\n                }\n\n                mipWidth  = Max(mipWidth >> 1, 1u);\n                mipHeight = Max(mipHeight >> 1, 1u);\n                mipDepth = Max(mipDepth >> 1, 1u);\n\n                inTail = ((mipWidth <= tailWidth) &&\n                          (mipHeight <= tailHeight) &&\n                          ((dataThick == FALSE) || (mipDepth <= tailDepth)));\n            }\n        }\n    }\n\n    *pNumMetaBlkX = numMetaBlkX;\n    *pNumMetaBlkY = numMetaBlkY;\n    *pNumMetaBlkZ = numMetaBlkZ;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeDccInfo\n*\n*   @brief\n*       Interface function to compute DCC key info\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeDccInfo(\n    const ADDR2_COMPUTE_DCCINFO_INPUT*    pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_DCCINFO_OUTPUT*         pOut    ///< [out] output structure\n    ) const\n{\n    BOOL_32 dataLinear = IsLinear(pIn->swizzleMode);\n    BOOL_32 metaLinear = pIn->dccKeyFlags.linear;\n    BOOL_32 pipeAligned = pIn->dccKeyFlags.pipeAligned;\n\n    if (dataLinear)\n    {\n        metaLinear = TRUE;\n    }\n    else if (metaLinear == TRUE)\n    {\n        pipeAligned = FALSE;\n    }\n\n    UINT_32 numPipeTotal = GetPipeNumForMetaAddressing(pipeAligned, pIn->swizzleMode);\n\n    if (metaLinear)\n    {\n        // Linear metadata supporting was removed for GFX9! No one can use this feature on GFX9.\n        ADDR_ASSERT_ALWAYS();\n\n        pOut->dccRamBaseAlign = numPipeTotal * m_pipeInterleaveBytes;\n        pOut->dccRamSize = PowTwoAlign((pIn->dataSurfaceSize / 256), pOut->dccRamBaseAlign);\n    }\n    else\n    {\n        BOOL_32 dataThick = IsThick(pIn->resourceType, pIn->swizzleMode);\n\n        UINT_32 minMetaBlkSize = dataThick ? 65536 : 4096;\n\n        UINT_32 numFrags = Max(pIn->numFrags, 1u);\n        UINT_32 numSlices = Max(pIn->numSlices, 1u);\n\n        minMetaBlkSize /= numFrags;\n\n        UINT_32 numCompressBlkPerMetaBlk = minMetaBlkSize;\n\n        UINT_32 numRbTotal = pIn->dccKeyFlags.rbAligned ? m_se * m_rbPerSe : 1;\n\n        if ((numPipeTotal > 1) || (numRbTotal > 1))\n        {\n            const UINT_32 thinBlkSize = 1 << (m_settings.applyAliasFix ? Max(10u, m_pipeInterleaveLog2) : 10);\n\n            numCompressBlkPerMetaBlk =\n                Max(numCompressBlkPerMetaBlk, m_se * m_rbPerSe * (dataThick ? 262144 : thinBlkSize));\n\n            if (numCompressBlkPerMetaBlk > 65536 * pIn->bpp)\n            {\n                numCompressBlkPerMetaBlk = 65536 * pIn->bpp;\n            }\n        }\n\n        Dim3d compressBlkDim = GetDccCompressBlk(pIn->resourceType, pIn->swizzleMode, pIn->bpp);\n        Dim3d metaBlkDim = compressBlkDim;\n\n        for (UINT_32 index = 1; index < numCompressBlkPerMetaBlk; index <<= 1)\n        {\n            if ((metaBlkDim.h < metaBlkDim.w) ||\n                ((pIn->numMipLevels > 1) && (metaBlkDim.h == metaBlkDim.w)))\n            {\n                if ((dataThick == FALSE) || (metaBlkDim.h <= metaBlkDim.d))\n                {\n                    metaBlkDim.h <<= 1;\n                }\n                else\n                {\n                    metaBlkDim.d <<= 1;\n                }\n            }\n            else\n            {\n                if ((dataThick == FALSE) || (metaBlkDim.w <= metaBlkDim.d))\n                {\n                    metaBlkDim.w <<= 1;\n                }\n                else\n                {\n                    metaBlkDim.d <<= 1;\n                }\n            }\n        }\n\n        UINT_32 numMetaBlkX;\n        UINT_32 numMetaBlkY;\n        UINT_32 numMetaBlkZ;\n\n        GetMetaMipInfo(pIn->numMipLevels, &metaBlkDim, dataThick, pOut->pMipInfo,\n                       pIn->unalignedWidth, pIn->unalignedHeight, numSlices,\n                       &numMetaBlkX, &numMetaBlkY, &numMetaBlkZ);\n\n        UINT_32 sizeAlign = numPipeTotal * numRbTotal * m_pipeInterleaveBytes;\n\n        if (numFrags > m_maxCompFrag)\n        {\n            sizeAlign *= (numFrags / m_maxCompFrag);\n        }\n\n        if (m_settings.metaBaseAlignFix)\n        {\n            sizeAlign = Max(sizeAlign, GetBlockSize(pIn->swizzleMode));\n        }\n\n        pOut->dccRamSize = numMetaBlkX * numMetaBlkY * numMetaBlkZ *\n                           numCompressBlkPerMetaBlk * numFrags;\n        pOut->dccRamSize = PowTwoAlign(pOut->dccRamSize, sizeAlign);\n        pOut->dccRamBaseAlign = Max(numCompressBlkPerMetaBlk, sizeAlign);\n\n        pOut->pitch = numMetaBlkX * metaBlkDim.w;\n        pOut->height = numMetaBlkY * metaBlkDim.h;\n        pOut->depth = numMetaBlkZ * metaBlkDim.d;\n\n        pOut->compressBlkWidth = compressBlkDim.w;\n        pOut->compressBlkHeight = compressBlkDim.h;\n        pOut->compressBlkDepth = compressBlkDim.d;\n\n        pOut->metaBlkWidth = metaBlkDim.w;\n        pOut->metaBlkHeight = metaBlkDim.h;\n        pOut->metaBlkDepth = metaBlkDim.d;\n        pOut->metaBlkSize = numCompressBlkPerMetaBlk * numFrags;\n\n        pOut->metaBlkNumPerSlice = numMetaBlkX * numMetaBlkY;\n        pOut->fastClearSizePerSlice =\n            pOut->metaBlkNumPerSlice * numCompressBlkPerMetaBlk * Min(numFrags, m_maxCompFrag);\n\n        // Get the DCC address equation (copied from DccAddrFromCoord)\n        UINT_32 elementBytesLog2  = Log2(pIn->bpp >> 3);\n        UINT_32 numSamplesLog2    = Log2(pIn->numFrags);\n        UINT_32 metaBlkWidthLog2  = Log2(pOut->metaBlkWidth);\n        UINT_32 metaBlkHeightLog2 = Log2(pOut->metaBlkHeight);\n        UINT_32 metaBlkDepthLog2  = Log2(pOut->metaBlkDepth);\n        UINT_32 compBlkWidthLog2  = Log2(pOut->compressBlkWidth);\n        UINT_32 compBlkHeightLog2 = Log2(pOut->compressBlkHeight);\n        UINT_32 compBlkDepthLog2  = Log2(pOut->compressBlkDepth);\n\n        MetaEqParams metaEqParams = {0, elementBytesLog2, numSamplesLog2, pIn->dccKeyFlags,\n                                     Gfx9DataColor, pIn->swizzleMode, pIn->resourceType,\n                                     metaBlkWidthLog2, metaBlkHeightLog2, metaBlkDepthLog2,\n                                     compBlkWidthLog2, compBlkHeightLog2, compBlkDepthLog2};\n\n        CoordEq *eq = (CoordEq *)((Gfx9Lib *)this)->GetMetaEquation(metaEqParams);\n\n        // Generate the DCC address equation.\n        pOut->equation.gfx9.num_bits = Min(32u, eq->getsize());\n        bool checked = false;\n        for (unsigned b = 0; b < pOut->equation.gfx9.num_bits; b++) {\n           CoordTerm &bit = (*eq)[b];\n\n           unsigned c;\n           for (c = 0; c < bit.getsize(); c++) {\n              Coordinate &coord = bit[c];\n              pOut->equation.gfx9.bit[b].coord[c].dim = coord.getdim();\n              pOut->equation.gfx9.bit[b].coord[c].ord = coord.getord();\n           }\n           for (; c < 5; c++)\n              pOut->equation.gfx9.bit[b].coord[c].dim = 5; /* meaning invalid */\n        }\n\n        // Reduce num_bits because DIM_M fills the rest of the bits monotonically.\n        for (int b = pOut->equation.gfx9.num_bits - 1; b >= 1; b--) {\n           CoordTerm &prev = (*eq)[b - 1];\n           CoordTerm &cur = (*eq)[b];\n\n           if (cur.getsize() == 1 && cur[0].getdim() == DIM_M &&\n               prev.getsize() == 1 && prev[0].getdim() == DIM_M &&\n               prev[0].getord() + 1 == cur[0].getord())\n              pOut->equation.gfx9.num_bits = b;\n           else\n              break;\n        }\n\n        pOut->equation.gfx9.numPipeBits = GetPipeLog2ForMetaAddressing(pIn->dccKeyFlags.pipeAligned,\n                                                                       pIn->swizzleMode);\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeMaxBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments\n*   @return\n*       maximum alignments\n************************************************************************************************************************\n*/\nUINT_32 Gfx9Lib::HwlComputeMaxBaseAlignments() const\n{\n    return Size64K;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeMaxMetaBaseAlignments\n*\n*   @brief\n*       Gets maximum alignments for metadata\n*   @return\n*       maximum alignments for metadata\n************************************************************************************************************************\n*/\nUINT_32 Gfx9Lib::HwlComputeMaxMetaBaseAlignments() const\n{\n    // Max base alignment for Htile\n    const UINT_32 maxNumPipeTotal = GetPipeNumForMetaAddressing(TRUE, ADDR_SW_64KB_Z);\n    const UINT_32 maxNumRbTotal   = m_se * m_rbPerSe;\n\n    // If applyAliasFix was set, the extra bits should be MAX(10u, m_pipeInterleaveLog2),\n    // but we never saw any ASIC whose m_pipeInterleaveLog2 != 8, so just put an assertion and simply the logic.\n    ADDR_ASSERT((m_settings.applyAliasFix == FALSE) || (m_pipeInterleaveLog2 <= 10u));\n    const UINT_32 maxNumCompressBlkPerMetaBlk = 1u << (m_seLog2 + m_rbPerSeLog2 + 10u);\n\n    UINT_32 maxBaseAlignHtile = maxNumPipeTotal * maxNumRbTotal * m_pipeInterleaveBytes;\n\n    if (maxNumPipeTotal > 2)\n    {\n        maxBaseAlignHtile *= (maxNumPipeTotal >> 1);\n    }\n\n    maxBaseAlignHtile = Max(maxNumCompressBlkPerMetaBlk << 2, maxBaseAlignHtile);\n\n    if (m_settings.metaBaseAlignFix)\n    {\n        maxBaseAlignHtile = Max(maxBaseAlignHtile, Size64K);\n    }\n\n    if (m_settings.htileAlignFix)\n    {\n        maxBaseAlignHtile *= maxNumPipeTotal;\n    }\n\n    // Max base alignment for Cmask will not be larger than that for Htile, no need to calculate\n\n    // Max base alignment for 2D Dcc will not be larger than that for 3D, no need to calculate\n    UINT_32 maxBaseAlignDcc3D = 65536;\n\n    if ((maxNumPipeTotal > 1) || (maxNumRbTotal > 1))\n    {\n        maxBaseAlignDcc3D = Min(m_se * m_rbPerSe * 262144, 65536 * 128u);\n    }\n\n    // Max base alignment for Msaa Dcc\n    UINT_32 maxBaseAlignDccMsaa = maxNumPipeTotal * maxNumRbTotal * m_pipeInterleaveBytes * (8 / m_maxCompFrag);\n\n    if (m_settings.metaBaseAlignFix)\n    {\n        maxBaseAlignDccMsaa = Max(maxBaseAlignDccMsaa, Size64K);\n    }\n\n    return Max(maxBaseAlignHtile, Max(maxBaseAlignDccMsaa, maxBaseAlignDcc3D));\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeCmaskAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeCmaskAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeCmaskAddrFromCoord(\n    const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR2_COMPUTE_CMASK_INFO_INPUT input = {0};\n    input.size            = sizeof(input);\n    input.cMaskFlags      = pIn->cMaskFlags;\n    input.colorFlags      = pIn->colorFlags;\n    input.unalignedWidth  = Max(pIn->unalignedWidth, 1u);\n    input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n    input.numSlices       = Max(pIn->numSlices, 1u);\n    input.swizzleMode     = pIn->swizzleMode;\n    input.resourceType    = pIn->resourceType;\n\n    ADDR2_COMPUTE_CMASK_INFO_OUTPUT output = {0};\n    output.size = sizeof(output);\n\n    ADDR_E_RETURNCODE returnCode = ComputeCmaskInfo(&input, &output);\n\n    if (returnCode == ADDR_OK)\n    {\n        UINT_32 fmaskBpp              = GetFmaskBpp(pIn->numSamples, pIn->numFrags);\n        UINT_32 fmaskElementBytesLog2 = Log2(fmaskBpp >> 3);\n        UINT_32 metaBlkWidthLog2      = Log2(output.metaBlkWidth);\n        UINT_32 metaBlkHeightLog2     = Log2(output.metaBlkHeight);\n\n        MetaEqParams metaEqParams = {0, fmaskElementBytesLog2, 0, pIn->cMaskFlags,\n                                     Gfx9DataFmask, pIn->swizzleMode, pIn->resourceType,\n                                     metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0};\n\n        const CoordEq* pMetaEq = GetMetaEquation(metaEqParams);\n\n        UINT_32 xb = pIn->x / output.metaBlkWidth;\n        UINT_32 yb = pIn->y / output.metaBlkHeight;\n        UINT_32 zb = pIn->slice;\n\n        UINT_32 pitchInBlock     = output.pitch / output.metaBlkWidth;\n        UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;\n        UINT_32 blockIndex       = zb * sliceSizeInBlock + yb * pitchInBlock + xb;\n\n        UINT_32 coords[] = {pIn->x, pIn->y, pIn->slice, 0, blockIndex};\n        UINT_64 address  = pMetaEq->solve(coords);\n\n        pOut->addr = address >> 1;\n        pOut->bitPosition = static_cast<UINT_32>((address & 1) << 2);\n\n\n        UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->cMaskFlags.pipeAligned,\n                                                           pIn->swizzleMode);\n\n        UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));\n\n        pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeHtileAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileAddrFromCoord\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileAddrFromCoord(\n    const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->numMipLevels > 1)\n    {\n        returnCode = ADDR_NOTIMPLEMENTED;\n    }\n    else\n    {\n        ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0};\n        input.size            = sizeof(input);\n        input.hTileFlags      = pIn->hTileFlags;\n        input.depthFlags      = pIn->depthflags;\n        input.swizzleMode     = pIn->swizzleMode;\n        input.unalignedWidth  = Max(pIn->unalignedWidth, 1u);\n        input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n        input.numSlices       = Max(pIn->numSlices, 1u);\n        input.numMipLevels    = Max(pIn->numMipLevels, 1u);\n\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0};\n        output.size = sizeof(output);\n\n        returnCode = ComputeHtileInfo(&input, &output);\n\n        if (returnCode == ADDR_OK)\n        {\n            UINT_32 elementBytesLog2  = Log2(pIn->bpp >> 3);\n            UINT_32 metaBlkWidthLog2  = Log2(output.metaBlkWidth);\n            UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);\n            UINT_32 numSamplesLog2    = Log2(pIn->numSamples);\n\n            MetaEqParams metaEqParams = {0, elementBytesLog2, numSamplesLog2, pIn->hTileFlags,\n                                         Gfx9DataDepthStencil, pIn->swizzleMode, ADDR_RSRC_TEX_2D,\n                                         metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0};\n\n            const CoordEq* pMetaEq = GetMetaEquation(metaEqParams);\n\n            UINT_32 xb = pIn->x / output.metaBlkWidth;\n            UINT_32 yb = pIn->y / output.metaBlkHeight;\n            UINT_32 zb = pIn->slice;\n\n            UINT_32 pitchInBlock     = output.pitch / output.metaBlkWidth;\n            UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;\n            UINT_32 blockIndex       = zb * sliceSizeInBlock + yb * pitchInBlock + xb;\n\n            UINT_32 coords[] = {pIn->x, pIn->y, pIn->slice, 0, blockIndex};\n            UINT_64 address  = pMetaEq->solve(coords);\n\n            pOut->addr = address >> 1;\n\n            UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->hTileFlags.pipeAligned,\n                                                               pIn->swizzleMode);\n\n            UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));\n\n            pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeHtileCoordFromAddr\n*\n*   @brief\n*       Interface function stub of AddrComputeHtileCoordFromAddr\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeHtileCoordFromAddr(\n    const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT*   pIn,    ///< [in] input structure\n    ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*        pOut)   ///< [out] output structure\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if (pIn->numMipLevels > 1)\n    {\n        returnCode = ADDR_NOTIMPLEMENTED;\n    }\n    else\n    {\n        ADDR2_COMPUTE_HTILE_INFO_INPUT input = {0};\n        input.size            = sizeof(input);\n        input.hTileFlags      = pIn->hTileFlags;\n        input.swizzleMode     = pIn->swizzleMode;\n        input.unalignedWidth  = Max(pIn->unalignedWidth, 1u);\n        input.unalignedHeight = Max(pIn->unalignedHeight, 1u);\n        input.numSlices       = Max(pIn->numSlices, 1u);\n        input.numMipLevels    = Max(pIn->numMipLevels, 1u);\n\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {0};\n        output.size = sizeof(output);\n\n        returnCode = ComputeHtileInfo(&input, &output);\n\n        if (returnCode == ADDR_OK)\n        {\n            UINT_32 elementBytesLog2  = Log2(pIn->bpp >> 3);\n            UINT_32 metaBlkWidthLog2  = Log2(output.metaBlkWidth);\n            UINT_32 metaBlkHeightLog2 = Log2(output.metaBlkHeight);\n            UINT_32 numSamplesLog2    = Log2(pIn->numSamples);\n\n            MetaEqParams metaEqParams = {0, elementBytesLog2, numSamplesLog2, pIn->hTileFlags,\n                                         Gfx9DataDepthStencil, pIn->swizzleMode, ADDR_RSRC_TEX_2D,\n                                         metaBlkWidthLog2, metaBlkHeightLog2, 0, 3, 3, 0};\n\n            const CoordEq* pMetaEq = GetMetaEquation(metaEqParams);\n\n            UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->hTileFlags.pipeAligned,\n                                                               pIn->swizzleMode);\n\n            UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));\n\n            UINT_64 nibbleAddress = (pIn->addr ^ (pipeXor << m_pipeInterleaveLog2)) << 1;\n\n            UINT_32 pitchInBlock     = output.pitch / output.metaBlkWidth;\n            UINT_32 sliceSizeInBlock = (output.height / output.metaBlkHeight) * pitchInBlock;\n\n            UINT_32 coords[NUM_DIMS];\n            pMetaEq->solveAddr(nibbleAddress, sliceSizeInBlock, coords);\n\n            pOut->slice = coords[DIM_M] / sliceSizeInBlock;\n            pOut->y     = ((coords[DIM_M] % sliceSizeInBlock) / pitchInBlock) * output.metaBlkHeight + coords[DIM_Y];\n            pOut->x     = (coords[DIM_M] % pitchInBlock) * output.metaBlkWidth + coords[DIM_X];\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlSupportComputeDccAddrFromCoord\n*\n*   @brief\n*       Check whether HwlComputeDccAddrFromCoord() can be done for the input parameter\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlSupportComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    if ((pIn->numMipLevels > 1) || (pIn->mipId > 1) || pIn->dccKeyFlags.linear)\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n    else if ((pIn->pitch == 0)             ||\n             (pIn->height == 0)            ||\n             (pIn->compressBlkWidth == 0)  ||\n             (pIn->compressBlkHeight == 0) ||\n             (pIn->compressBlkDepth == 0)  ||\n             (pIn->metaBlkWidth == 0)      ||\n             (pIn->metaBlkHeight == 0)     ||\n             (pIn->metaBlkDepth == 0)      ||\n             (pIn->slice > 0 && pIn->dccRamSliceSize == 0))\n    {\n        returnCode = ADDR_NOTSUPPORTED;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeDccAddrFromCoord\n*\n*   @brief\n*       Interface function stub of AddrComputeDccAddrFromCoord\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::HwlComputeDccAddrFromCoord(\n    const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT*  pIn,\n    ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut)\n{\n    UINT_32 elementBytesLog2  = Log2(pIn->bpp >> 3);\n    UINT_32 numSamplesLog2    = Log2(pIn->numFrags);\n    UINT_32 metaBlkWidthLog2  = Log2(pIn->metaBlkWidth);\n    UINT_32 metaBlkHeightLog2 = Log2(pIn->metaBlkHeight);\n    UINT_32 metaBlkDepthLog2  = Log2(pIn->metaBlkDepth);\n    UINT_32 compBlkWidthLog2  = Log2(pIn->compressBlkWidth);\n    UINT_32 compBlkHeightLog2 = Log2(pIn->compressBlkHeight);\n    UINT_32 compBlkDepthLog2  = Log2(pIn->compressBlkDepth);\n\n    MetaEqParams metaEqParams = {pIn->mipId, elementBytesLog2, numSamplesLog2, pIn->dccKeyFlags,\n                                 Gfx9DataColor, pIn->swizzleMode, pIn->resourceType,\n                                 metaBlkWidthLog2, metaBlkHeightLog2, metaBlkDepthLog2,\n                                 compBlkWidthLog2, compBlkHeightLog2, compBlkDepthLog2};\n\n    const CoordEq* pMetaEq = GetMetaEquation(metaEqParams);\n\n    UINT_32 xb = pIn->x / pIn->metaBlkWidth;\n    UINT_32 yb = pIn->y / pIn->metaBlkHeight;\n    UINT_32 zb = pIn->slice / pIn->metaBlkDepth;\n\n    UINT_32 pitchInBlock     = pIn->pitch / pIn->metaBlkWidth;\n    UINT_32 sliceSizeInBlock = (pIn->height / pIn->metaBlkHeight) * pitchInBlock;\n    UINT_32 blockIndex       = zb * sliceSizeInBlock + yb * pitchInBlock + xb;\n\n    UINT_32 coords[] = {pIn->x, pIn->y, pIn->slice, pIn->sample, blockIndex};\n    UINT_64 address  = pMetaEq->solve(coords);\n\n    pOut->addr = address >> 1;\n\n    UINT_32 numPipeBits = GetPipeLog2ForMetaAddressing(pIn->dccKeyFlags.pipeAligned,\n                                                       pIn->swizzleMode);\n\n    UINT_64 pipeXor = static_cast<UINT_64>(pIn->pipeXor & ((1 << numPipeBits) - 1));\n\n    pOut->addr ^= (pipeXor << m_pipeInterleaveLog2);\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlInitGlobalParams\n*\n*   @brief\n*       Initializes global parameters\n*\n*   @return\n*       TRUE if all settings are valid\n*\n************************************************************************************************************************\n*/\nBOOL_32 Gfx9Lib::HwlInitGlobalParams(\n    const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input\n{\n    BOOL_32 valid = TRUE;\n\n    if (m_settings.isArcticIsland)\n    {\n        GB_ADDR_CONFIG_GFX9 gbAddrConfig;\n\n        gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;\n\n        // These values are copied from CModel code\n        switch (gbAddrConfig.bits.NUM_PIPES)\n        {\n            case ADDR_CONFIG_1_PIPE:\n                m_pipes = 1;\n                m_pipesLog2 = 0;\n                break;\n            case ADDR_CONFIG_2_PIPE:\n                m_pipes = 2;\n                m_pipesLog2 = 1;\n                break;\n            case ADDR_CONFIG_4_PIPE:\n                m_pipes = 4;\n                m_pipesLog2 = 2;\n                break;\n            case ADDR_CONFIG_8_PIPE:\n                m_pipes = 8;\n                m_pipesLog2 = 3;\n                break;\n            case ADDR_CONFIG_16_PIPE:\n                m_pipes = 16;\n                m_pipesLog2 = 4;\n                break;\n            case ADDR_CONFIG_32_PIPE:\n                m_pipes = 32;\n                m_pipesLog2 = 5;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)\n        {\n            case ADDR_CONFIG_PIPE_INTERLEAVE_256B:\n                m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;\n                m_pipeInterleaveLog2 = 8;\n                break;\n            case ADDR_CONFIG_PIPE_INTERLEAVE_512B:\n                m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;\n                m_pipeInterleaveLog2 = 9;\n                break;\n            case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:\n                m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;\n                m_pipeInterleaveLog2 = 10;\n                break;\n            case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:\n                m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;\n                m_pipeInterleaveLog2 = 11;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits,\n        // and any larger value requires a post-process (left shift) on the output pipeBankXor bits.\n        ADDR_ASSERT(m_pipeInterleaveBytes == ADDR_PIPEINTERLEAVE_256B);\n\n        switch (gbAddrConfig.bits.NUM_BANKS)\n        {\n            case ADDR_CONFIG_1_BANK:\n                m_banks = 1;\n                m_banksLog2 = 0;\n                break;\n            case ADDR_CONFIG_2_BANK:\n                m_banks = 2;\n                m_banksLog2 = 1;\n                break;\n            case ADDR_CONFIG_4_BANK:\n                m_banks = 4;\n                m_banksLog2 = 2;\n                break;\n            case ADDR_CONFIG_8_BANK:\n                m_banks = 8;\n                m_banksLog2 = 3;\n                break;\n            case ADDR_CONFIG_16_BANK:\n                m_banks = 16;\n                m_banksLog2 = 4;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        switch (gbAddrConfig.bits.NUM_SHADER_ENGINES)\n        {\n            case ADDR_CONFIG_1_SHADER_ENGINE:\n                m_se = 1;\n                m_seLog2 = 0;\n                break;\n            case ADDR_CONFIG_2_SHADER_ENGINE:\n                m_se = 2;\n                m_seLog2 = 1;\n                break;\n            case ADDR_CONFIG_4_SHADER_ENGINE:\n                m_se = 4;\n                m_seLog2 = 2;\n                break;\n            case ADDR_CONFIG_8_SHADER_ENGINE:\n                m_se = 8;\n                m_seLog2 = 3;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        switch (gbAddrConfig.bits.NUM_RB_PER_SE)\n        {\n            case ADDR_CONFIG_1_RB_PER_SHADER_ENGINE:\n                m_rbPerSe = 1;\n                m_rbPerSeLog2 = 0;\n                break;\n            case ADDR_CONFIG_2_RB_PER_SHADER_ENGINE:\n                m_rbPerSe = 2;\n                m_rbPerSeLog2 = 1;\n                break;\n            case ADDR_CONFIG_4_RB_PER_SHADER_ENGINE:\n                m_rbPerSe = 4;\n                m_rbPerSeLog2 = 2;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        switch (gbAddrConfig.bits.MAX_COMPRESSED_FRAGS)\n        {\n            case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS:\n                m_maxCompFrag = 1;\n                m_maxCompFragLog2 = 0;\n                break;\n            case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS:\n                m_maxCompFrag = 2;\n                m_maxCompFragLog2 = 1;\n                break;\n            case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS:\n                m_maxCompFrag = 4;\n                m_maxCompFragLog2 = 2;\n                break;\n            case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS:\n                m_maxCompFrag = 8;\n                m_maxCompFragLog2 = 3;\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                break;\n        }\n\n        if ((m_rbPerSeLog2 == 1) &&\n            (((m_pipesLog2 == 1) && ((m_seLog2 == 2) || (m_seLog2 == 3))) ||\n             ((m_pipesLog2 == 2) && ((m_seLog2 == 1) || (m_seLog2 == 2)))))\n        {\n            ADDR_ASSERT(m_settings.isVega10 == FALSE);\n\n            ADDR_ASSERT(m_settings.isRaven == FALSE);\n\n            ADDR_ASSERT(m_settings.isVega20 == FALSE);\n\n            if (m_settings.isVega12)\n            {\n                m_settings.htileCacheRbConflict = 1;\n            }\n        }\n\n        // For simplicity we never allow VAR swizzle mode for GFX9, the actural value is 18 on GFX9\n        m_blockVarSizeLog2 = 0;\n    }\n    else\n    {\n        valid = FALSE;\n        ADDR_NOT_IMPLEMENTED();\n    }\n\n    if (valid)\n    {\n        InitEquationTable();\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlConvertChipFamily\n*\n*   @brief\n*       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision\n*   @return\n*       ChipFamily\n************************************************************************************************************************\n*/\nChipFamily Gfx9Lib::HwlConvertChipFamily(\n    UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h\n    UINT_32 uChipRevision)      ///< [in] chip revision defined in \"asic_family\"_id.h\n{\n    ChipFamily family = ADDR_CHIP_FAMILY_AI;\n\n    switch (uChipFamily)\n    {\n        case FAMILY_AI:\n            m_settings.isArcticIsland = 1;\n            m_settings.isVega10 = ASICREV_IS_VEGA10_P(uChipRevision);\n            m_settings.isVega12 = ASICREV_IS_VEGA12_P(uChipRevision);\n            m_settings.isVega20 = ASICREV_IS_VEGA20_P(uChipRevision);\n            m_settings.isDce12 = 1;\n\n            if (m_settings.isVega10 == 0)\n            {\n                m_settings.htileAlignFix = 1;\n                m_settings.applyAliasFix = 1;\n            }\n\n            m_settings.metaBaseAlignFix = 1;\n\n            m_settings.depthPipeXorDisable = 1;\n            break;\n        case FAMILY_RV:\n            m_settings.isArcticIsland = 1;\n\n            if (ASICREV_IS_RAVEN(uChipRevision))\n            {\n                m_settings.isRaven = 1;\n\n                m_settings.depthPipeXorDisable = 1;\n            }\n\n            if (ASICREV_IS_RAVEN2(uChipRevision))\n            {\n                m_settings.isRaven = 1;\n            }\n\n            if (m_settings.isRaven == 0)\n            {\n                m_settings.htileAlignFix = 1;\n                m_settings.applyAliasFix = 1;\n            }\n\n            m_settings.isDcn1 = m_settings.isRaven;\n\n            if (ASICREV_IS_RENOIR(uChipRevision))\n            {\n                m_settings.isRaven = 1;\n                m_settings.isDcn2  = 1;\n            }\n\n            m_settings.metaBaseAlignFix = 1;\n            break;\n\n        default:\n            ADDR_ASSERT(!\"No Chip found\");\n            break;\n    }\n\n    return family;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::InitRbEquation\n*\n*   @brief\n*       Init RB equation\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GetRbEquation(\n    CoordEq* pRbEq,             ///< [out] rb equation\n    UINT_32  numRbPerSeLog2,    ///< [in] number of rb per shader engine\n    UINT_32  numSeLog2)         ///< [in] number of shader engine\n    const\n{\n    // RB's are distributed on 16x16, except when we have 1 rb per se, in which case its 32x32\n    UINT_32 rbRegion = (numRbPerSeLog2 == 0) ? 5 : 4;\n    Coordinate cx(DIM_X, rbRegion);\n    Coordinate cy(DIM_Y, rbRegion);\n\n    UINT_32 start = 0;\n    UINT_32 numRbTotalLog2 = numRbPerSeLog2 + numSeLog2;\n\n    // Clear the rb equation\n    pRbEq->resize(0);\n    pRbEq->resize(numRbTotalLog2);\n\n    if ((numSeLog2 > 0) && (numRbPerSeLog2 == 1))\n    {\n        // Special case when more than 1 SE, and 2 RB per SE\n        (*pRbEq)[0].add(cx);\n        (*pRbEq)[0].add(cy);\n        cx++;\n        cy++;\n\n        if (m_settings.applyAliasFix == false)\n        {\n            (*pRbEq)[0].add(cy);\n        }\n\n        (*pRbEq)[0].add(cy);\n        start++;\n    }\n\n    UINT_32 numBits = 2 * (numRbTotalLog2 - start);\n\n    for (UINT_32 i = 0; i < numBits; i++)\n    {\n        UINT_32 idx =\n            start + (((start + i) >= numRbTotalLog2) ? (2 * (numRbTotalLog2 - start) - i - 1) : i);\n\n        if ((i % 2) == 1)\n        {\n            (*pRbEq)[idx].add(cx);\n            cx++;\n        }\n        else\n        {\n            (*pRbEq)[idx].add(cy);\n            cy++;\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetDataEquation\n*\n*   @brief\n*       Get data equation for fmask and Z\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GetDataEquation(\n    CoordEq* pDataEq,               ///< [out] data surface equation\n    Gfx9DataType dataSurfaceType,   ///< [in] data surface type\n    AddrSwizzleMode swizzleMode,    ///< [in] data surface swizzle mode\n    AddrResourceType resourceType,  ///< [in] data surface resource type\n    UINT_32 elementBytesLog2,       ///< [in] data surface element bytes\n    UINT_32 numSamplesLog2)         ///< [in] data surface sample count\n    const\n{\n    Coordinate cx(DIM_X, 0);\n    Coordinate cy(DIM_Y, 0);\n    Coordinate cz(DIM_Z, 0);\n    Coordinate cs(DIM_S, 0);\n\n    // Clear the equation\n    pDataEq->resize(0);\n    pDataEq->resize(27);\n\n    if (dataSurfaceType == Gfx9DataColor)\n    {\n        if (IsLinear(swizzleMode))\n        {\n            Coordinate cm(DIM_M, 0);\n\n            pDataEq->resize(49);\n\n            for (UINT_32 i = 0; i < 49; i++)\n            {\n                (*pDataEq)[i].add(cm);\n                cm++;\n            }\n        }\n        else if (IsThick(resourceType, swizzleMode))\n        {\n            // Color 3d_S and 3d_Z modes, 3d_D is same as color 2d\n            UINT_32 i;\n            if (IsStandardSwizzle(resourceType, swizzleMode))\n            {\n                // Standard 3d swizzle\n                // Fill in bottom x bits\n                for (i = elementBytesLog2; i < 4; i++)\n                {\n                    (*pDataEq)[i].add(cx);\n                    cx++;\n                }\n                // Fill in 2 bits of y and then z\n                for (i = 4; i < 6; i++)\n                {\n                    (*pDataEq)[i].add(cy);\n                    cy++;\n                }\n                for (i = 6; i < 8; i++)\n                {\n                    (*pDataEq)[i].add(cz);\n                    cz++;\n                }\n                if (elementBytesLog2 < 2)\n                {\n                    // fill in z & y bit\n                    (*pDataEq)[8].add(cz);\n                    (*pDataEq)[9].add(cy);\n                    cz++;\n                    cy++;\n                }\n                else if (elementBytesLog2 == 2)\n                {\n                    // fill in y and x bit\n                    (*pDataEq)[8].add(cy);\n                    (*pDataEq)[9].add(cx);\n                    cy++;\n                    cx++;\n                }\n                else\n                {\n                    // fill in 2 x bits\n                    (*pDataEq)[8].add(cx);\n                    cx++;\n                    (*pDataEq)[9].add(cx);\n                    cx++;\n                }\n            }\n            else\n            {\n                // Z 3d swizzle\n                UINT_32 m2dEnd = (elementBytesLog2 ==0) ? 3 : ((elementBytesLog2 < 4) ? 4 : 5);\n                UINT_32 numZs = (elementBytesLog2 == 0 || elementBytesLog2 == 4) ?\n                                2 : ((elementBytesLog2 == 1) ? 3 : 1);\n                pDataEq->mort2d(cx, cy, elementBytesLog2, m2dEnd);\n                for (i = m2dEnd + 1; i <= m2dEnd + numZs; i++)\n                {\n                    (*pDataEq)[i].add(cz);\n                    cz++;\n                }\n                if ((elementBytesLog2 == 0) || (elementBytesLog2 == 3))\n                {\n                    // add an x and z\n                    (*pDataEq)[6].add(cx);\n                    (*pDataEq)[7].add(cz);\n                    cx++;\n                    cz++;\n                }\n                else if (elementBytesLog2 == 2)\n                {\n                    // add a y and z\n                    (*pDataEq)[6].add(cy);\n                    (*pDataEq)[7].add(cz);\n                    cy++;\n                    cz++;\n                }\n                // add y and x\n                (*pDataEq)[8].add(cy);\n                (*pDataEq)[9].add(cx);\n                cy++;\n                cx++;\n            }\n            // Fill in bit 10 and up\n            pDataEq->mort3d( cz, cy, cx, 10 );\n        }\n        else if (IsThin(resourceType, swizzleMode))\n        {\n            UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);\n            // Color 2D\n            UINT_32 microYBits = (8 - elementBytesLog2) / 2;\n            UINT_32 tileSplitStart = blockSizeLog2 - numSamplesLog2;\n            UINT_32 i;\n            // Fill in bottom x bits\n            for (i = elementBytesLog2; i < 4; i++)\n            {\n                (*pDataEq)[i].add(cx);\n                cx++;\n            }\n            // Fill in bottom y bits\n            for (i = 4; i < 4 + microYBits; i++)\n            {\n                (*pDataEq)[i].add(cy);\n                cy++;\n            }\n            // Fill in last of the micro_x bits\n            for (i = 4 + microYBits; i < 8; i++)\n            {\n                (*pDataEq)[i].add(cx);\n                cx++;\n            }\n            // Fill in x/y bits below sample split\n            pDataEq->mort2d(cy, cx, 8, tileSplitStart - 1);\n            // Fill in sample bits\n            for (i = 0; i < numSamplesLog2; i++)\n            {\n                cs.set(DIM_S, i);\n                (*pDataEq)[tileSplitStart + i].add(cs);\n            }\n            // Fill in x/y bits above sample split\n            if ((numSamplesLog2 & 1) ^ (blockSizeLog2 & 1))\n            {\n                pDataEq->mort2d(cx, cy, blockSizeLog2);\n            }\n            else\n            {\n                pDataEq->mort2d(cy, cx, blockSizeLog2);\n            }\n        }\n        else\n        {\n            ADDR_ASSERT_ALWAYS();\n        }\n    }\n    else\n    {\n        // Fmask or depth\n        UINT_32 sampleStart = elementBytesLog2;\n        UINT_32 pixelStart = elementBytesLog2 + numSamplesLog2;\n        UINT_32 ymajStart = 6 + numSamplesLog2;\n\n        for (UINT_32 s = 0; s < numSamplesLog2; s++)\n        {\n            cs.set(DIM_S, s);\n            (*pDataEq)[sampleStart + s].add(cs);\n        }\n\n        // Put in the x-major order pixel bits\n        pDataEq->mort2d(cx, cy, pixelStart, ymajStart - 1);\n        // Put in the y-major order pixel bits\n        pDataEq->mort2d(cy, cx, ymajStart);\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetPipeEquation\n*\n*   @brief\n*       Get pipe equation\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GetPipeEquation(\n    CoordEq*         pPipeEq,            ///< [out] pipe equation\n    CoordEq*         pDataEq,            ///< [in] data equation\n    UINT_32          pipeInterleaveLog2, ///< [in] pipe interleave\n    UINT_32          numPipeLog2,        ///< [in] number of pipes\n    UINT_32          numSamplesLog2,     ///< [in] data surface sample count\n    Gfx9DataType     dataSurfaceType,    ///< [in] data surface type\n    AddrSwizzleMode  swizzleMode,        ///< [in] data surface swizzle mode\n    AddrResourceType resourceType        ///< [in] data surface resource type\n    ) const\n{\n    UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);\n    CoordEq dataEq;\n\n    pDataEq->copy(dataEq);\n\n    if (dataSurfaceType == Gfx9DataColor)\n    {\n        INT_32 shift = static_cast<INT_32>(numSamplesLog2);\n        dataEq.shift(-shift, blockSizeLog2 - numSamplesLog2);\n    }\n\n    dataEq.copy(*pPipeEq, pipeInterleaveLog2, numPipeLog2);\n\n    // This section should only apply to z/stencil, maybe fmask\n    // If the pipe bit is below the comp block size,\n    // then keep moving up the address until we find a bit that is above\n    UINT_32 pipeStart = 0;\n\n    if (dataSurfaceType != Gfx9DataColor)\n    {\n        Coordinate tileMin(DIM_X, 3);\n\n        while (dataEq[pipeInterleaveLog2 + pipeStart][0] < tileMin)\n        {\n            pipeStart++;\n        }\n\n        // if pipe is 0, then the first pipe bit is above the comp block size,\n        // so we don't need to do anything\n        // Note, this if condition is not necessary, since if we execute the loop when pipe==0,\n        // we will get the same pipe equation\n        if (pipeStart != 0)\n        {\n            for (UINT_32 i = 0; i < numPipeLog2; i++)\n            {\n                // Copy the jth bit above pipe interleave to the current pipe equation bit\n                dataEq[pipeInterleaveLog2 + pipeStart + i].copyto((*pPipeEq)[i]);\n            }\n        }\n    }\n\n    if (IsPrt(swizzleMode))\n    {\n        // Clear out bits above the block size if prt's are enabled\n        dataEq.resize(blockSizeLog2);\n        dataEq.resize(48);\n    }\n\n    if (IsXor(swizzleMode))\n    {\n        CoordEq xorMask;\n\n        if (IsThick(resourceType, swizzleMode))\n        {\n            CoordEq xorMask2;\n\n            dataEq.copy(xorMask2, pipeInterleaveLog2 + numPipeLog2, 2 * numPipeLog2);\n\n            xorMask.resize(numPipeLog2);\n\n            for (UINT_32 pipeIdx = 0; pipeIdx < numPipeLog2; pipeIdx++)\n            {\n                xorMask[pipeIdx].add(xorMask2[2 * pipeIdx]);\n                xorMask[pipeIdx].add(xorMask2[2 * pipeIdx + 1]);\n            }\n        }\n        else\n        {\n            // Xor in the bits above the pipe+gpu bits\n            dataEq.copy(xorMask, pipeInterleaveLog2 + pipeStart + numPipeLog2, numPipeLog2);\n\n            if ((numSamplesLog2 == 0) && (IsPrt(swizzleMode) == FALSE))\n            {\n                Coordinate co;\n                CoordEq xorMask2;\n                // if 1xaa and not prt, then xor in the z bits\n                xorMask2.resize(0);\n                xorMask2.resize(numPipeLog2);\n                for (UINT_32 pipeIdx = 0; pipeIdx < numPipeLog2; pipeIdx++)\n                {\n                    co.set(DIM_Z, numPipeLog2 - 1 - pipeIdx);\n                    xorMask2[pipeIdx].add(co);\n                }\n\n                pPipeEq->xorin(xorMask2);\n            }\n        }\n\n        xorMask.reverse();\n        pPipeEq->xorin(xorMask);\n    }\n}\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetMetaEquation\n*\n*   @brief\n*       Get meta equation for cmask/htile/DCC\n*   @return\n*       Pointer to a calculated meta equation\n************************************************************************************************************************\n*/\nconst CoordEq* Gfx9Lib::GetMetaEquation(\n    const MetaEqParams& metaEqParams)\n{\n    UINT_32 cachedMetaEqIndex;\n\n    for (cachedMetaEqIndex = 0; cachedMetaEqIndex < MaxCachedMetaEq; cachedMetaEqIndex++)\n    {\n        if (memcmp(&metaEqParams,\n                   &m_cachedMetaEqKey[cachedMetaEqIndex],\n                   static_cast<UINT_32>(sizeof(metaEqParams))) == 0)\n        {\n            break;\n        }\n    }\n\n    CoordEq* pMetaEq = NULL;\n\n    if (cachedMetaEqIndex < MaxCachedMetaEq)\n    {\n        pMetaEq = &m_cachedMetaEq[cachedMetaEqIndex];\n    }\n    else\n    {\n        m_cachedMetaEqKey[m_metaEqOverrideIndex] = metaEqParams;\n\n        pMetaEq = &m_cachedMetaEq[m_metaEqOverrideIndex++];\n\n        m_metaEqOverrideIndex %= MaxCachedMetaEq;\n\n        GenMetaEquation(pMetaEq,\n                        metaEqParams.maxMip,\n                        metaEqParams.elementBytesLog2,\n                        metaEqParams.numSamplesLog2,\n                        metaEqParams.metaFlag,\n                        metaEqParams.dataSurfaceType,\n                        metaEqParams.swizzleMode,\n                        metaEqParams.resourceType,\n                        metaEqParams.metaBlkWidthLog2,\n                        metaEqParams.metaBlkHeightLog2,\n                        metaEqParams.metaBlkDepthLog2,\n                        metaEqParams.compBlkWidthLog2,\n                        metaEqParams.compBlkHeightLog2,\n                        metaEqParams.compBlkDepthLog2);\n    }\n\n    return pMetaEq;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GenMetaEquation\n*\n*   @brief\n*       Get meta equation for cmask/htile/DCC\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GenMetaEquation(\n    CoordEq*         pMetaEq,               ///< [out] meta equation\n    UINT_32          maxMip,                ///< [in] max mip Id\n    UINT_32          elementBytesLog2,      ///< [in] data surface element bytes\n    UINT_32          numSamplesLog2,        ///< [in] data surface sample count\n    ADDR2_META_FLAGS metaFlag,              ///< [in] meta falg\n    Gfx9DataType     dataSurfaceType,       ///< [in] data surface type\n    AddrSwizzleMode  swizzleMode,           ///< [in] data surface swizzle mode\n    AddrResourceType resourceType,          ///< [in] data surface resource type\n    UINT_32          metaBlkWidthLog2,      ///< [in] meta block width\n    UINT_32          metaBlkHeightLog2,     ///< [in] meta block height\n    UINT_32          metaBlkDepthLog2,      ///< [in] meta block depth\n    UINT_32          compBlkWidthLog2,      ///< [in] compress block width\n    UINT_32          compBlkHeightLog2,     ///< [in] compress block height\n    UINT_32          compBlkDepthLog2)      ///< [in] compress block depth\n    const\n{\n    UINT_32 numPipeTotalLog2   = GetPipeLog2ForMetaAddressing(metaFlag.pipeAligned, swizzleMode);\n    UINT_32 pipeInterleaveLog2 = m_pipeInterleaveLog2;\n\n    // Get the correct data address and rb equation\n    CoordEq dataEq;\n    GetDataEquation(&dataEq, dataSurfaceType, swizzleMode, resourceType,\n                    elementBytesLog2, numSamplesLog2);\n\n    // Get pipe and rb equations\n    CoordEq pipeEquation;\n    GetPipeEquation(&pipeEquation, &dataEq, pipeInterleaveLog2, numPipeTotalLog2,\n                    numSamplesLog2, dataSurfaceType, swizzleMode, resourceType);\n    numPipeTotalLog2 = pipeEquation.getsize();\n\n    if (metaFlag.linear)\n    {\n        // Linear metadata supporting was removed for GFX9! No one can use this feature.\n        ADDR_ASSERT_ALWAYS();\n\n        ADDR_ASSERT(dataSurfaceType == Gfx9DataColor);\n\n        dataEq.copy(*pMetaEq);\n\n        if (IsLinear(swizzleMode))\n        {\n            if (metaFlag.pipeAligned)\n            {\n                // Remove the pipe bits\n                INT_32 shift = static_cast<INT_32>(numPipeTotalLog2);\n                pMetaEq->shift(-shift, pipeInterleaveLog2);\n            }\n            // Divide by comp block size, which for linear (which is always color) is 256 B\n            pMetaEq->shift(-8);\n\n            if (metaFlag.pipeAligned)\n            {\n                // Put pipe bits back in\n                pMetaEq->shift(numPipeTotalLog2, pipeInterleaveLog2);\n\n                for (UINT_32 i = 0; i < numPipeTotalLog2; i++)\n                {\n                    pipeEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2 + i]);\n                }\n            }\n        }\n\n        pMetaEq->shift(1);\n    }\n    else\n    {\n        UINT_32 maxCompFragLog2 = static_cast<INT_32>(m_maxCompFragLog2);\n        UINT_32 compFragLog2 =\n            ((dataSurfaceType == Gfx9DataColor) && (numSamplesLog2 > maxCompFragLog2)) ?\n            maxCompFragLog2 : numSamplesLog2;\n\n        UINT_32 uncompFragLog2 = numSamplesLog2 - compFragLog2;\n\n        // Make sure the metaaddr is cleared\n        pMetaEq->resize(0);\n        pMetaEq->resize(27);\n\n        if (IsThick(resourceType, swizzleMode))\n        {\n            Coordinate cx(DIM_X, 0);\n            Coordinate cy(DIM_Y, 0);\n            Coordinate cz(DIM_Z, 0);\n\n            if (maxMip > 0)\n            {\n                pMetaEq->mort3d(cy, cx, cz);\n            }\n            else\n            {\n                pMetaEq->mort3d(cx, cy, cz);\n            }\n        }\n        else\n        {\n            Coordinate cx(DIM_X, 0);\n            Coordinate cy(DIM_Y, 0);\n            Coordinate cs;\n\n            if (maxMip > 0)\n            {\n                pMetaEq->mort2d(cy, cx, compFragLog2);\n            }\n            else\n            {\n                pMetaEq->mort2d(cx, cy, compFragLog2);\n            }\n\n            //------------------------------------------------------------------------------------------------------------------------\n            // Put the compressible fragments at the lsb\n            // the uncompressible frags will be at the msb of the micro address\n            //------------------------------------------------------------------------------------------------------------------------\n            for (UINT_32 s = 0; s < compFragLog2; s++)\n            {\n                cs.set(DIM_S, s);\n                (*pMetaEq)[s].add(cs);\n            }\n        }\n\n        // Keep a copy of the pipe equations\n        CoordEq origPipeEquation;\n        pipeEquation.copy(origPipeEquation);\n\n        Coordinate co;\n        // filter out everything under the compressed block size\n        co.set(DIM_X, compBlkWidthLog2);\n        pMetaEq->Filter('<', co, 0, DIM_X);\n        co.set(DIM_Y, compBlkHeightLog2);\n        pMetaEq->Filter('<', co, 0, DIM_Y);\n        co.set(DIM_Z, compBlkDepthLog2);\n        pMetaEq->Filter('<', co, 0, DIM_Z);\n\n        // For non-color, filter out sample bits\n        if (dataSurfaceType != Gfx9DataColor)\n        {\n            co.set(DIM_X, 0);\n            pMetaEq->Filter('<', co, 0, DIM_S);\n        }\n\n        // filter out everything above the metablock size\n        co.set(DIM_X, metaBlkWidthLog2 - 1);\n        pMetaEq->Filter('>', co, 0, DIM_X);\n        co.set(DIM_Y, metaBlkHeightLog2 - 1);\n        pMetaEq->Filter('>', co, 0, DIM_Y);\n        co.set(DIM_Z, metaBlkDepthLog2 - 1);\n        pMetaEq->Filter('>', co, 0, DIM_Z);\n\n        // filter out everything above the metablock size for the channel bits\n        co.set(DIM_X, metaBlkWidthLog2 - 1);\n        pipeEquation.Filter('>', co, 0, DIM_X);\n        co.set(DIM_Y, metaBlkHeightLog2 - 1);\n        pipeEquation.Filter('>', co, 0, DIM_Y);\n        co.set(DIM_Z, metaBlkDepthLog2 - 1);\n        pipeEquation.Filter('>', co, 0, DIM_Z);\n\n        // Make sure we still have the same number of channel bits\n        if (pipeEquation.getsize() != numPipeTotalLog2)\n        {\n            ADDR_ASSERT_ALWAYS();\n        }\n\n        // Loop through all channel and rb bits,\n        // and make sure these components exist in the metadata address\n        for (UINT_32 i = 0; i < numPipeTotalLog2; i++)\n        {\n            for (UINT_32 j = pipeEquation[i].getsize(); j > 0; j--)\n            {\n                if (pMetaEq->Exists(pipeEquation[i][j - 1]) == FALSE)\n                {\n                    ADDR_ASSERT_ALWAYS();\n                }\n            }\n        }\n\n        const UINT_32 numSeLog2     = metaFlag.rbAligned ? m_seLog2      : 0;\n        const UINT_32 numRbPeSeLog2 = metaFlag.rbAligned ? m_rbPerSeLog2 : 0;\n        const UINT_32 numRbTotalLog2 = numRbPeSeLog2 + numSeLog2;\n        CoordEq       origRbEquation;\n\n        GetRbEquation(&origRbEquation, numRbPeSeLog2, numSeLog2);\n\n        CoordEq rbEquation = origRbEquation;\n\n        for (UINT_32 i = 0; i < numRbTotalLog2; i++)\n        {\n            for (UINT_32 j = rbEquation[i].getsize(); j > 0; j--)\n            {\n                if (pMetaEq->Exists(rbEquation[i][j - 1]) == FALSE)\n                {\n                    ADDR_ASSERT_ALWAYS();\n                }\n            }\n        }\n\n        if (m_settings.applyAliasFix)\n        {\n            co.set(DIM_Z, -1);\n        }\n\n        // Loop through each rb id bit; if it is equal to any of the filtered channel bits, clear it\n        for (UINT_32 i = 0; i < numRbTotalLog2; i++)\n        {\n            for (UINT_32 j = 0; j < numPipeTotalLog2; j++)\n            {\n                BOOL_32 isRbEquationInPipeEquation = FALSE;\n\n                if (m_settings.applyAliasFix)\n                {\n                    CoordTerm filteredPipeEq;\n                    filteredPipeEq = pipeEquation[j];\n\n                    filteredPipeEq.Filter('>', co, 0, DIM_Z);\n\n                    isRbEquationInPipeEquation = (rbEquation[i] == filteredPipeEq);\n                }\n                else\n                {\n                    isRbEquationInPipeEquation = (rbEquation[i] == pipeEquation[j]);\n                }\n\n                if (isRbEquationInPipeEquation)\n                {\n                    rbEquation[i].Clear();\n                }\n            }\n        }\n\n         bool rbAppendedWithPipeBits[1 << (MaxSeLog2 + MaxRbPerSeLog2)] = {};\n\n        // Loop through each bit of the channel, get the smallest coordinate,\n        // and remove it from the metaaddr, and rb_equation\n        for (UINT_32 i = 0; i < numPipeTotalLog2; i++)\n        {\n            pipeEquation[i].getsmallest(co);\n\n            UINT_32 old_size = pMetaEq->getsize();\n            pMetaEq->Filter('=', co);\n            UINT_32 new_size = pMetaEq->getsize();\n            if (new_size != old_size-1)\n            {\n                ADDR_ASSERT_ALWAYS();\n            }\n            pipeEquation.remove(co);\n            for (UINT_32 j = 0; j < numRbTotalLog2; j++)\n            {\n                if (rbEquation[j].remove(co))\n                {\n                    // if we actually removed something from this bit, then add the remaining\n                    // channel bits, as these can be removed for this bit\n                    for (UINT_32 k = 0; k < pipeEquation[i].getsize(); k++)\n                    {\n                        if (pipeEquation[i][k] != co)\n                        {\n                            rbEquation[j].add(pipeEquation[i][k]);\n                            rbAppendedWithPipeBits[j] = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Loop through the rb bits and see what remain;\n        // filter out the smallest coordinate if it remains\n        UINT_32 rbBitsLeft = 0;\n        for (UINT_32 i = 0; i < numRbTotalLog2; i++)\n        {\n            BOOL_32 isRbEqAppended = FALSE;\n\n            if (m_settings.applyAliasFix)\n            {\n                isRbEqAppended = (rbEquation[i].getsize() > (rbAppendedWithPipeBits[i] ? 1 : 0));\n            }\n            else\n            {\n                isRbEqAppended = (rbEquation[i].getsize() > 0);\n            }\n\n            if (isRbEqAppended)\n            {\n                rbBitsLeft++;\n                rbEquation[i].getsmallest(co);\n                UINT_32 old_size = pMetaEq->getsize();\n                pMetaEq->Filter('=', co);\n                UINT_32 new_size = pMetaEq->getsize();\n                if (new_size != old_size - 1)\n                {\n                    // assert warning\n                }\n                for (UINT_32 j = i + 1; j < numRbTotalLog2; j++)\n                {\n                    if (rbEquation[j].remove(co))\n                    {\n                        // if we actually removed something from this bit, then add the remaining\n                        // rb bits, as these can be removed for this bit\n                        for (UINT_32 k = 0; k < rbEquation[i].getsize(); k++)\n                        {\n                            if (rbEquation[i][k] != co)\n                            {\n                                rbEquation[j].add(rbEquation[i][k]);\n                                rbAppendedWithPipeBits[j] |= rbAppendedWithPipeBits[i];\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // capture the size of the metaaddr\n        UINT_32 metaSize = pMetaEq->getsize();\n        // resize to 49 bits...make this a nibble address\n        pMetaEq->resize(49);\n        // Concatenate the macro address above the current address\n        for (UINT_32 i = metaSize, j = 0; i < 49; i++, j++)\n        {\n            co.set(DIM_M, j);\n            (*pMetaEq)[i].add(co);\n        }\n\n        // Multiply by meta element size (in nibbles)\n        if (dataSurfaceType == Gfx9DataColor)\n        {\n            pMetaEq->shift(1);\n        }\n        else if (dataSurfaceType == Gfx9DataDepthStencil)\n        {\n            pMetaEq->shift(3);\n        }\n\n        //------------------------------------------------------------------------------------------\n        // Note the pipeInterleaveLog2+1 is because address is a nibble address\n        // Shift up from pipe interleave number of channel\n        // and rb bits left, and uncompressed fragments\n        //------------------------------------------------------------------------------------------\n\n        pMetaEq->shift(numPipeTotalLog2 + rbBitsLeft + uncompFragLog2, pipeInterleaveLog2 + 1);\n\n        // Put in the channel bits\n        for (UINT_32 i = 0; i < numPipeTotalLog2; i++)\n        {\n            origPipeEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2+1 + i]);\n        }\n\n        // Put in remaining rb bits\n        for (UINT_32 i = 0, j = 0; j < rbBitsLeft; i = (i + 1) % numRbTotalLog2)\n        {\n            BOOL_32 isRbEqAppended = FALSE;\n\n            if (m_settings.applyAliasFix)\n            {\n                isRbEqAppended = (rbEquation[i].getsize() > (rbAppendedWithPipeBits[i] ? 1 : 0));\n            }\n            else\n            {\n                isRbEqAppended = (rbEquation[i].getsize() > 0);\n            }\n\n            if (isRbEqAppended)\n            {\n                origRbEquation[i].copyto((*pMetaEq)[pipeInterleaveLog2 + 1 + numPipeTotalLog2 + j]);\n                // Mark any rb bit we add in to the rb mask\n                j++;\n            }\n        }\n\n        //------------------------------------------------------------------------------------------\n        // Put in the uncompressed fragment bits\n        //------------------------------------------------------------------------------------------\n        for (UINT_32 i = 0; i < uncompFragLog2; i++)\n        {\n            co.set(DIM_S, compFragLog2 + i);\n            (*pMetaEq)[pipeInterleaveLog2 + 1 + numPipeTotalLog2 + rbBitsLeft + i].add(co);\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::IsEquationSupported\n*\n*   @brief\n*       Check if equation is supported for given swizzle mode and resource type.\n*\n*   @return\n*       TRUE if supported\n************************************************************************************************************************\n*/\nBOOL_32 Gfx9Lib::IsEquationSupported(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode  swMode,\n    UINT_32          elementBytesLog2) const\n{\n    BOOL_32 supported = (elementBytesLog2 < MaxElementBytesLog2) &&\n                        (IsValidSwMode(swMode) == TRUE) &&\n                        (IsLinear(swMode) == FALSE) &&\n                        (((IsTex2d(rsrcType) == TRUE) &&\n                          ((elementBytesLog2 < 4) ||\n                           ((IsRotateSwizzle(swMode) == FALSE) &&\n                            (IsZOrderSwizzle(swMode) == FALSE)))) ||\n                         ((IsTex3d(rsrcType) == TRUE) &&\n                          (IsRotateSwizzle(swMode) == FALSE) &&\n                          (IsBlock256b(swMode) == FALSE)));\n\n    return supported;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::InitEquationTable\n*\n*   @brief\n*       Initialize Equation table.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::InitEquationTable()\n{\n    memset(m_equationTable, 0, sizeof(m_equationTable));\n\n    // Loop all possible resource type (2D/3D)\n    for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)\n    {\n        AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);\n\n        // Loop all possible swizzle mode\n        for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwModeType; swModeIdx++)\n        {\n            AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);\n\n            // Loop all possible bpp\n            for (UINT_32 bppIdx = 0; bppIdx < MaxElementBytesLog2; bppIdx++)\n            {\n                UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX;\n\n                // Check if the input is supported\n                if (IsEquationSupported(rsrcType, swMode, bppIdx))\n                {\n                    ADDR_EQUATION     equation;\n                    ADDR_E_RETURNCODE retCode;\n\n                    memset(&equation, 0, sizeof(ADDR_EQUATION));\n\n                    // Generate the equation\n                    if (IsBlock256b(swMode) && IsTex2d(rsrcType))\n                    {\n                        retCode = ComputeBlock256Equation(rsrcType, swMode, bppIdx, &equation);\n                    }\n                    else if (IsThin(rsrcType, swMode))\n                    {\n                        retCode = ComputeThinEquation(rsrcType, swMode, bppIdx, &equation);\n                    }\n                    else\n                    {\n                        retCode = ComputeThickEquation(rsrcType, swMode, bppIdx, &equation);\n                    }\n\n                    // Only fill the equation into the table if the return code is ADDR_OK,\n                    // otherwise if the return code is not ADDR_OK, it indicates this is not\n                    // a valid input, we do nothing but just fill invalid equation index\n                    // into the lookup table.\n                    if (retCode == ADDR_OK)\n                    {\n                        equationIndex = m_numEquations;\n                        ADDR_ASSERT(equationIndex < EquationTableSize);\n\n                        m_equationTable[equationIndex] = equation;\n\n                        m_numEquations++;\n                    }\n                    else\n                    {\n                        ADDR_ASSERT_ALWAYS();\n                    }\n                }\n\n                // Fill the index into the lookup table, if the combination is not supported\n                // fill the invalid equation index\n                m_equationLookupTable[rsrcTypeIdx][swModeIdx][bppIdx] = equationIndex;\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlGetEquationIndex\n*\n*   @brief\n*       Interface function stub of GetEquationIndex\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nUINT_32 Gfx9Lib::HwlGetEquationIndex(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut\n    ) const\n{\n    AddrResourceType rsrcType         = pIn->resourceType;\n    AddrSwizzleMode  swMode           = pIn->swizzleMode;\n    UINT_32          elementBytesLog2 = Log2(pIn->bpp >> 3);\n    UINT_32          index            = ADDR_INVALID_EQUATION_INDEX;\n\n    if (IsEquationSupported(rsrcType, swMode, elementBytesLog2))\n    {\n        UINT_32 rsrcTypeIdx = static_cast<UINT_32>(rsrcType) - 1;\n        UINT_32 swModeIdx   = static_cast<UINT_32>(swMode);\n\n        index = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elementBytesLog2];\n    }\n\n    if (pOut->pMipInfo != NULL)\n    {\n        for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n        {\n            pOut->pMipInfo[i].equationIndex = index;\n        }\n    }\n\n    return index;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeBlock256Equation\n*\n*   @brief\n*       Interface function stub of ComputeBlock256Equation\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeBlock256Equation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode  swMode,\n    UINT_32          elementBytesLog2,\n    ADDR_EQUATION*   pEquation) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    pEquation->numBits = 8;\n    pEquation->numBitComponents = 1;\n\n    UINT_32 i = 0;\n    for (; i < elementBytesLog2; i++)\n    {\n        InitChannel(1, 0 , i, &pEquation->addr[i]);\n    }\n\n    ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2];\n\n    const UINT_32 maxBitsUsed = 4;\n    ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};\n    ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};\n\n    for (i = 0; i < maxBitsUsed; i++)\n    {\n        InitChannel(1, 0, elementBytesLog2 + i, &x[i]);\n        InitChannel(1, 1, i, &y[i]);\n    }\n\n    if (IsStandardSwizzle(rsrcType, swMode))\n    {\n        switch (elementBytesLog2)\n        {\n            case 0:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = x[2];\n                pixelBit[3] = x[3];\n                pixelBit[4] = y[0];\n                pixelBit[5] = y[1];\n                pixelBit[6] = y[2];\n                pixelBit[7] = y[3];\n                break;\n            case 1:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = x[2];\n                pixelBit[3] = y[0];\n                pixelBit[4] = y[1];\n                pixelBit[5] = y[2];\n                pixelBit[6] = x[3];\n                break;\n            case 2:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = y[0];\n                pixelBit[3] = y[1];\n                pixelBit[4] = y[2];\n                pixelBit[5] = x[2];\n                break;\n            case 3:\n                pixelBit[0] = x[0];\n                pixelBit[1] = y[0];\n                pixelBit[2] = y[1];\n                pixelBit[3] = x[1];\n                pixelBit[4] = x[2];\n                break;\n            case 4:\n                pixelBit[0] = y[0];\n                pixelBit[1] = y[1];\n                pixelBit[2] = x[0];\n                pixelBit[3] = x[1];\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                ret = ADDR_INVALIDPARAMS;\n                break;\n        }\n    }\n    else if (IsDisplaySwizzle(rsrcType, swMode))\n    {\n        switch (elementBytesLog2)\n        {\n            case 0:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = x[2];\n                pixelBit[3] = y[1];\n                pixelBit[4] = y[0];\n                pixelBit[5] = y[2];\n                pixelBit[6] = x[3];\n                pixelBit[7] = y[3];\n                break;\n            case 1:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = x[2];\n                pixelBit[3] = y[0];\n                pixelBit[4] = y[1];\n                pixelBit[5] = y[2];\n                pixelBit[6] = x[3];\n                break;\n            case 2:\n                pixelBit[0] = x[0];\n                pixelBit[1] = x[1];\n                pixelBit[2] = y[0];\n                pixelBit[3] = x[2];\n                pixelBit[4] = y[1];\n                pixelBit[5] = y[2];\n                break;\n            case 3:\n                pixelBit[0] = x[0];\n                pixelBit[1] = y[0];\n                pixelBit[2] = x[1];\n                pixelBit[3] = x[2];\n                pixelBit[4] = y[1];\n                break;\n            case 4:\n                pixelBit[0] = x[0];\n                pixelBit[1] = y[0];\n                pixelBit[2] = x[1];\n                pixelBit[3] = y[1];\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                ret = ADDR_INVALIDPARAMS;\n                break;\n        }\n    }\n    else if (IsRotateSwizzle(swMode))\n    {\n        switch (elementBytesLog2)\n        {\n            case 0:\n                pixelBit[0] = y[0];\n                pixelBit[1] = y[1];\n                pixelBit[2] = y[2];\n                pixelBit[3] = x[1];\n                pixelBit[4] = x[0];\n                pixelBit[5] = x[2];\n                pixelBit[6] = x[3];\n                pixelBit[7] = y[3];\n                break;\n            case 1:\n                pixelBit[0] = y[0];\n                pixelBit[1] = y[1];\n                pixelBit[2] = y[2];\n                pixelBit[3] = x[0];\n                pixelBit[4] = x[1];\n                pixelBit[5] = x[2];\n                pixelBit[6] = x[3];\n                break;\n            case 2:\n                pixelBit[0] = y[0];\n                pixelBit[1] = y[1];\n                pixelBit[2] = x[0];\n                pixelBit[3] = y[2];\n                pixelBit[4] = x[1];\n                pixelBit[5] = x[2];\n                break;\n            case 3:\n                pixelBit[0] = y[0];\n                pixelBit[1] = x[0];\n                pixelBit[2] = y[1];\n                pixelBit[3] = x[1];\n                pixelBit[4] = x[2];\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n            case 4:\n                ret = ADDR_INVALIDPARAMS;\n                break;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        ret = ADDR_INVALIDPARAMS;\n    }\n\n    // Post validation\n    if (ret == ADDR_OK)\n    {\n        Dim2d microBlockDim = Block256_2d[elementBytesLog2];\n        ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 0)) ==\n                    (microBlockDim.w * (1 << elementBytesLog2)));\n        ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation->addr, 8, 1)) == microBlockDim.h);\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeThinEquation\n*\n*   @brief\n*       Interface function stub of ComputeThinEquation\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeThinEquation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode  swMode,\n    UINT_32          elementBytesLog2,\n    ADDR_EQUATION*   pEquation) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    UINT_32 blockSizeLog2 = GetBlockSizeLog2(swMode);\n\n    UINT_32 maxXorBits = blockSizeLog2;\n    if (IsNonPrtXor(swMode))\n    {\n        // For non-prt-xor, maybe need to initialize some more bits for xor\n        // The highest xor bit used in equation will be max the following 3 items:\n        // 1. m_pipeInterleaveLog2 + 2 * pipeXorBits\n        // 2. m_pipeInterleaveLog2 + pipeXorBits + 2 * bankXorBits\n        // 3. blockSizeLog2\n\n        maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 + 2 * GetPipeXorBits(blockSizeLog2));\n        maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 +\n                                     GetPipeXorBits(blockSizeLog2) +\n                                     2 * GetBankXorBits(blockSizeLog2));\n    }\n\n    const UINT_32 maxBitsUsed = 14;\n    ADDR_ASSERT((2 * maxBitsUsed) >= maxXorBits);\n    ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};\n    ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};\n\n    const UINT_32 extraXorBits = 16;\n    ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2);\n    ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {};\n\n    for (UINT_32 i = 0; i < maxBitsUsed; i++)\n    {\n        InitChannel(1, 0, elementBytesLog2 + i, &x[i]);\n        InitChannel(1, 1, i, &y[i]);\n    }\n\n    ADDR_CHANNEL_SETTING* pixelBit = pEquation->addr;\n\n    for (UINT_32 i = 0; i < elementBytesLog2; i++)\n    {\n        InitChannel(1, 0 , i, &pixelBit[i]);\n    }\n\n    UINT_32 xIdx = 0;\n    UINT_32 yIdx = 0;\n    UINT_32 lowBits = 0;\n\n    if (IsZOrderSwizzle(swMode))\n    {\n        if (elementBytesLog2 <= 3)\n        {\n            for (UINT_32 i = elementBytesLog2; i < 6; i++)\n            {\n                pixelBit[i] = (((i - elementBytesLog2) & 1) == 0) ? x[xIdx++] : y[yIdx++];\n            }\n\n            lowBits = 6;\n        }\n        else\n        {\n            ret = ADDR_INVALIDPARAMS;\n        }\n    }\n    else\n    {\n        ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);\n\n        if (ret == ADDR_OK)\n        {\n            Dim2d microBlockDim = Block256_2d[elementBytesLog2];\n            xIdx = Log2(microBlockDim.w);\n            yIdx = Log2(microBlockDim.h);\n            lowBits = 8;\n        }\n    }\n\n    if (ret == ADDR_OK)\n    {\n        for (UINT_32 i = lowBits; i < blockSizeLog2; i++)\n        {\n            pixelBit[i] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++];\n        }\n\n        for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++)\n        {\n            xorExtra[i - blockSizeLog2] = ((i & 1) == 0) ? y[yIdx++] : x[xIdx++];\n        }\n\n        if (IsXor(swMode))\n        {\n            // Fill XOR bits\n            UINT_32 pipeStart = m_pipeInterleaveLog2;\n            UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2);\n\n            UINT_32 bankStart = pipeStart + pipeXorBits;\n            UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2);\n\n            for (UINT_32 i = 0; i < pipeXorBits; i++)\n            {\n                UINT_32               xor1BitPos = pipeStart + 2 * pipeXorBits - 1 - i;\n                ADDR_CHANNEL_SETTING* pXor1Src   = (xor1BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src);\n            }\n\n            for (UINT_32 i = 0; i < bankXorBits; i++)\n            {\n                UINT_32               xor1BitPos = bankStart + 2 * bankXorBits - 1 - i;\n                ADDR_CHANNEL_SETTING* pXor1Src   = (xor1BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor1[bankStart + i], pXor1Src);\n            }\n\n            if (IsPrt(swMode) == FALSE)\n            {\n                for (UINT_32 i = 0; i < pipeXorBits; i++)\n                {\n                    InitChannel(1, 2, pipeXorBits - i - 1, &pEquation->xor2[pipeStart + i]);\n                }\n\n                for (UINT_32 i = 0; i < bankXorBits; i++)\n                {\n                    InitChannel(1, 2, bankXorBits - i - 1 + pipeXorBits, &pEquation->xor2[bankStart + i]);\n                }\n            }\n        }\n\n        FillEqBitComponents(pEquation);\n        pEquation->numBits = blockSizeLog2;\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeThickEquation\n*\n*   @brief\n*       Interface function stub of ComputeThickEquation\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeThickEquation(\n    AddrResourceType rsrcType,\n    AddrSwizzleMode  swMode,\n    UINT_32          elementBytesLog2,\n    ADDR_EQUATION*   pEquation) const\n{\n    ADDR_E_RETURNCODE ret = ADDR_OK;\n\n    ADDR_ASSERT(IsTex3d(rsrcType));\n\n    UINT_32 blockSizeLog2 = GetBlockSizeLog2(swMode);\n\n    UINT_32 maxXorBits = blockSizeLog2;\n    if (IsNonPrtXor(swMode))\n    {\n        // For non-prt-xor, maybe need to initialize some more bits for xor\n        // The highest xor bit used in equation will be max the following 3:\n        // 1. m_pipeInterleaveLog2 + 3 * pipeXorBits\n        // 2. m_pipeInterleaveLog2 + pipeXorBits + 3 * bankXorBits\n        // 3. blockSizeLog2\n\n        maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 + 3 * GetPipeXorBits(blockSizeLog2));\n        maxXorBits = Max(maxXorBits, m_pipeInterleaveLog2 +\n                                     GetPipeXorBits(blockSizeLog2) +\n                                     3 * GetBankXorBits(blockSizeLog2));\n    }\n\n    for (UINT_32 i = 0; i < elementBytesLog2; i++)\n    {\n        InitChannel(1, 0 , i, &pEquation->addr[i]);\n    }\n\n    ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[elementBytesLog2];\n\n    const UINT_32 maxBitsUsed = 12;\n    ADDR_ASSERT((3 * maxBitsUsed) >= maxXorBits);\n    ADDR_CHANNEL_SETTING x[maxBitsUsed] = {};\n    ADDR_CHANNEL_SETTING y[maxBitsUsed] = {};\n    ADDR_CHANNEL_SETTING z[maxBitsUsed] = {};\n\n    const UINT_32 extraXorBits = 24;\n    ADDR_ASSERT(extraXorBits >= maxXorBits - blockSizeLog2);\n    ADDR_CHANNEL_SETTING xorExtra[extraXorBits] = {};\n\n    for (UINT_32 i = 0; i < maxBitsUsed; i++)\n    {\n        InitChannel(1, 0, elementBytesLog2 + i, &x[i]);\n        InitChannel(1, 1, i, &y[i]);\n        InitChannel(1, 2, i, &z[i]);\n    }\n\n    if (IsZOrderSwizzle(swMode))\n    {\n        switch (elementBytesLog2)\n        {\n            case 0:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = x[1];\n                pixelBit[3]  = y[1];\n                pixelBit[4]  = z[0];\n                pixelBit[5]  = z[1];\n                pixelBit[6]  = x[2];\n                pixelBit[7]  = z[2];\n                pixelBit[8]  = y[2];\n                pixelBit[9]  = x[3];\n                break;\n            case 1:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = x[1];\n                pixelBit[3]  = y[1];\n                pixelBit[4]  = z[0];\n                pixelBit[5]  = z[1];\n                pixelBit[6]  = z[2];\n                pixelBit[7]  = y[2];\n                pixelBit[8]  = x[2];\n                break;\n            case 2:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = x[1];\n                pixelBit[3]  = z[0];\n                pixelBit[4]  = y[1];\n                pixelBit[5]  = z[1];\n                pixelBit[6]  = y[2];\n                pixelBit[7]  = x[2];\n                break;\n            case 3:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = z[0];\n                pixelBit[3]  = x[1];\n                pixelBit[4]  = z[1];\n                pixelBit[5]  = y[1];\n                pixelBit[6]  = x[2];\n                break;\n            case 4:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = z[0];\n                pixelBit[3]  = z[1];\n                pixelBit[4]  = y[1];\n                pixelBit[5]  = x[1];\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                ret = ADDR_INVALIDPARAMS;\n                break;\n        }\n    }\n    else if (IsStandardSwizzle(rsrcType, swMode))\n    {\n        switch (elementBytesLog2)\n        {\n            case 0:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = x[1];\n                pixelBit[2]  = x[2];\n                pixelBit[3]  = x[3];\n                pixelBit[4]  = y[0];\n                pixelBit[5]  = y[1];\n                pixelBit[6]  = z[0];\n                pixelBit[7]  = z[1];\n                pixelBit[8]  = z[2];\n                pixelBit[9]  = y[2];\n                break;\n            case 1:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = x[1];\n                pixelBit[2]  = x[2];\n                pixelBit[3]  = y[0];\n                pixelBit[4]  = y[1];\n                pixelBit[5]  = z[0];\n                pixelBit[6]  = z[1];\n                pixelBit[7]  = z[2];\n                pixelBit[8]  = y[2];\n                break;\n            case 2:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = x[1];\n                pixelBit[2]  = y[0];\n                pixelBit[3]  = y[1];\n                pixelBit[4]  = z[0];\n                pixelBit[5]  = z[1];\n                pixelBit[6]  = y[2];\n                pixelBit[7]  = x[2];\n                break;\n            case 3:\n                pixelBit[0]  = x[0];\n                pixelBit[1]  = y[0];\n                pixelBit[2]  = y[1];\n                pixelBit[3]  = z[0];\n                pixelBit[4]  = z[1];\n                pixelBit[5]  = x[1];\n                pixelBit[6]  = x[2];\n                break;\n            case 4:\n                pixelBit[0]  = y[0];\n                pixelBit[1]  = y[1];\n                pixelBit[2]  = z[0];\n                pixelBit[3]  = z[1];\n                pixelBit[4]  = x[0];\n                pixelBit[5]  = x[1];\n                break;\n            default:\n                ADDR_ASSERT_ALWAYS();\n                ret = ADDR_INVALIDPARAMS;\n                break;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        ret = ADDR_INVALIDPARAMS;\n    }\n\n    if (ret == ADDR_OK)\n    {\n        Dim3d microBlockDim = Block1K_3d[elementBytesLog2];\n        UINT_32 xIdx = Log2(microBlockDim.w);\n        UINT_32 yIdx = Log2(microBlockDim.h);\n        UINT_32 zIdx = Log2(microBlockDim.d);\n\n        pixelBit = pEquation->addr;\n\n        const UINT_32 lowBits = 10;\n        ADDR_ASSERT(pEquation->addr[lowBits - 1].valid == 1);\n        ADDR_ASSERT(pEquation->addr[lowBits].valid == 0);\n\n        for (UINT_32 i = lowBits; i < blockSizeLog2; i++)\n        {\n            if ((i % 3) == 0)\n            {\n                pixelBit[i] = x[xIdx++];\n            }\n            else if ((i % 3) == 1)\n            {\n                pixelBit[i] = z[zIdx++];\n            }\n            else\n            {\n                pixelBit[i] = y[yIdx++];\n            }\n        }\n\n        for (UINT_32 i = blockSizeLog2; i < maxXorBits; i++)\n        {\n            if ((i % 3) == 0)\n            {\n                xorExtra[i - blockSizeLog2] = x[xIdx++];\n            }\n            else if ((i % 3) == 1)\n            {\n                xorExtra[i - blockSizeLog2] = z[zIdx++];\n            }\n            else\n            {\n                xorExtra[i - blockSizeLog2] = y[yIdx++];\n            }\n        }\n\n        if (IsXor(swMode))\n        {\n            // Fill XOR bits\n            UINT_32 pipeStart = m_pipeInterleaveLog2;\n            UINT_32 pipeXorBits = GetPipeXorBits(blockSizeLog2);\n            for (UINT_32 i = 0; i < pipeXorBits; i++)\n            {\n                UINT_32               xor1BitPos = pipeStart + (3 * pipeXorBits) - 1 - (2 * i);\n                ADDR_CHANNEL_SETTING* pXor1Src   = (xor1BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor1[pipeStart + i], pXor1Src);\n\n                UINT_32               xor2BitPos = pipeStart + (3 * pipeXorBits) - 2 - (2 * i);\n                ADDR_CHANNEL_SETTING* pXor2Src   = (xor2BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor2[pipeStart + i], pXor2Src);\n            }\n\n            UINT_32 bankStart = pipeStart + pipeXorBits;\n            UINT_32 bankXorBits = GetBankXorBits(blockSizeLog2);\n            for (UINT_32 i = 0; i < bankXorBits; i++)\n            {\n                UINT_32               xor1BitPos = bankStart + (3 * bankXorBits) - 1 - (2 * i);\n                ADDR_CHANNEL_SETTING* pXor1Src   = (xor1BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor1BitPos] : &xorExtra[xor1BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor1[bankStart + i], pXor1Src);\n\n                UINT_32               xor2BitPos = bankStart + (3 * bankXorBits) - 2 - (2 * i);\n                ADDR_CHANNEL_SETTING* pXor2Src   = (xor2BitPos < blockSizeLog2) ?\n                                                   &pEquation->addr[xor2BitPos] : &xorExtra[xor2BitPos - blockSizeLog2];\n\n                InitChannel(&pEquation->xor2[bankStart + i], pXor2Src);\n            }\n        }\n\n        FillEqBitComponents(pEquation);\n        pEquation->numBits = blockSizeLog2;\n    }\n\n    return ret;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::IsValidDisplaySwizzleMode\n*\n*   @brief\n*       Check if a swizzle mode is supported by display engine\n*\n*   @return\n*       TRUE is swizzle mode is supported by display engine\n************************************************************************************************************************\n*/\nBOOL_32 Gfx9Lib::IsValidDisplaySwizzleMode(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 support = FALSE;\n\n    const UINT_32 swizzleMask = 1 << pIn->swizzleMode;\n\n    if (m_settings.isDce12)\n    {\n        if (pIn->bpp == 32)\n        {\n            support = (Dce12Bpp32SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n        else if (pIn->bpp <= 64)\n        {\n            support = (Dce12NonBpp32SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n    }\n    else if (m_settings.isDcn1)\n    {\n        if (pIn->bpp < 64)\n        {\n            support = (Dcn1NonBpp64SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n        else if (pIn->bpp == 64)\n        {\n            support = (Dcn1Bpp64SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n    }\n    else if (m_settings.isDcn2)\n    {\n        if (pIn->bpp < 64)\n        {\n            support = (Dcn2NonBpp64SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n        else if (pIn->bpp == 64)\n        {\n            support = (Dcn2Bpp64SwModeMask & swizzleMask) ? TRUE : FALSE;\n        }\n    }\n    else\n    {\n        ADDR_NOT_IMPLEMENTED();\n    }\n\n    return support;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputePipeBankXor\n*\n*   @brief\n*       Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputePipeBankXor(\n    const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const\n{\n    if (IsXor(pIn->swizzleMode))\n    {\n        UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);\n        UINT_32 pipeBits       = GetPipeXorBits(macroBlockBits);\n        UINT_32 bankBits       = GetBankXorBits(macroBlockBits);\n\n        UINT_32 pipeXor = 0;\n        UINT_32 bankXor = 0;\n\n        const UINT_32 bankMask = (1 << bankBits) - 1;\n        const UINT_32 index    = pIn->surfIndex & bankMask;\n\n        const UINT_32 bpp      = pIn->flags.fmask ?\n                                 GetFmaskBpp(pIn->numSamples, pIn->numFrags) : GetElemLib()->GetBitsPerPixel(pIn->format);\n        if (bankBits == 4)\n        {\n            static const UINT_32 BankXorSmallBpp[] = {0, 7, 4, 3, 8, 15, 12, 11, 1, 6, 5, 2, 9, 14, 13, 10};\n            static const UINT_32 BankXorLargeBpp[] = {0, 7, 8, 15, 4, 3, 12, 11, 1, 6, 9, 14, 5, 2, 13, 10};\n\n            bankXor = (bpp <= 32) ? BankXorSmallBpp[index] : BankXorLargeBpp[index];\n        }\n        else if (bankBits > 0)\n        {\n            UINT_32 bankIncrease = (1 << (bankBits - 1)) - 1;\n            bankIncrease = (bankIncrease == 0) ? 1 : bankIncrease;\n            bankXor = (index * bankIncrease) & bankMask;\n        }\n\n        pOut->pipeBankXor = (bankXor << pipeBits) | pipeXor;\n    }\n    else\n    {\n        pOut->pipeBankXor = 0;\n    }\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSlicePipeBankXor\n*\n*   @brief\n*       Generate slice PipeBankXor value based on base PipeBankXor value and slice id\n*\n*   @return\n*       PipeBankXor value\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSlicePipeBankXor(\n    const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n    ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const\n{\n    UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);\n    UINT_32 pipeBits       = GetPipeXorBits(macroBlockBits);\n    UINT_32 bankBits       = GetBankXorBits(macroBlockBits);\n\n    UINT_32 pipeXor        = ReverseBitVector(pIn->slice, pipeBits);\n    UINT_32 bankXor        = ReverseBitVector(pIn->slice >> pipeBits, bankBits);\n\n    pOut->pipeBankXor = pIn->basePipeBankXor ^ (pipeXor | (bankXor << pipeBits));\n\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern\n*\n*   @brief\n*       Compute sub resource offset to support swizzle pattern\n*\n*   @return\n*       Offset\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSubResourceOffsetForSwizzlePattern(\n    const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n    ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const\n{\n    ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));\n\n    UINT_32 macroBlockBits = GetBlockSizeLog2(pIn->swizzleMode);\n    UINT_32 pipeBits       = GetPipeXorBits(macroBlockBits);\n    UINT_32 bankBits       = GetBankXorBits(macroBlockBits);\n    UINT_32 pipeXor        = ReverseBitVector(pIn->slice, pipeBits);\n    UINT_32 bankXor        = ReverseBitVector(pIn->slice >> pipeBits, bankBits);\n    UINT_32 pipeBankXor    = ((pipeXor | (bankXor << pipeBits)) ^ (pIn->pipeBankXor)) << m_pipeInterleaveLog2;\n\n    pOut->offset = pIn->slice * pIn->sliceSize +\n                   pIn->macroBlockOffset +\n                   (pIn->mipTailOffset ^ pipeBankXor) -\n                   static_cast<UINT_64>(pipeBankXor);\n    return ADDR_OK;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::ValidateNonSwModeParams\n*\n*   @brief\n*       Validate compute surface info params except swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx9Lib::ValidateNonSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8) || (pIn->numSamples > 16))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (pIn->resourceType >= ADDR_RSRC_MAX_TYPE)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const BOOL_32 mipmap = (pIn->numMipLevels > 1);\n    const BOOL_32 msaa   = (pIn->numFrags > 1);\n    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);\n\n    const AddrResourceType rsrcType = pIn->resourceType;\n    const BOOL_32          tex3d    = IsTex3d(rsrcType);\n    const BOOL_32          tex2d    = IsTex2d(rsrcType);\n    const BOOL_32          tex1d    = IsTex1d(rsrcType);\n\n    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;\n    const BOOL_32             zbuffer = flags.depth || flags.stencil;\n    const BOOL_32             display = flags.display || flags.rotated;\n    const BOOL_32             stereo  = flags.qbStereo;\n    const BOOL_32             fmask   = flags.fmask;\n\n    // Resource type check\n    if (tex1d)\n    {\n        if (msaa || zbuffer || display || stereo || isBc || fmask)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex2d)\n    {\n        if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (tex3d)\n    {\n        if (msaa || zbuffer || display || stereo || fmask)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::ValidateSwModeParams\n*\n*   @brief\n*       Validate compute surface info related to swizzle mode\n*\n*   @return\n*       TRUE if parameters are valid, FALSE otherwise\n************************************************************************************************************************\n*/\nBOOL_32 Gfx9Lib::ValidateSwModeParams(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    BOOL_32 valid = TRUE;\n\n    if ((pIn->swizzleMode >= ADDR_SW_MAX_TYPE) || (IsValidSwMode(pIn->swizzleMode) == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    const BOOL_32 mipmap = (pIn->numMipLevels > 1);\n    const BOOL_32 msaa   = (pIn->numFrags > 1);\n    const BOOL_32 isBc   = ElemLib::IsBlockCompressed(pIn->format);\n    const BOOL_32 is422  = ElemLib::IsMacroPixelPacked(pIn->format);\n\n    const AddrResourceType rsrcType = pIn->resourceType;\n    const BOOL_32          tex3d    = IsTex3d(rsrcType);\n    const BOOL_32          tex2d    = IsTex2d(rsrcType);\n    const BOOL_32          tex1d    = IsTex1d(rsrcType);\n\n    const AddrSwizzleMode  swizzle     = pIn->swizzleMode;\n    const BOOL_32          linear      = IsLinear(swizzle);\n    const BOOL_32          blk256B     = IsBlock256b(swizzle);\n    const BOOL_32          isNonPrtXor = IsNonPrtXor(swizzle);\n\n    const ADDR2_SURFACE_FLAGS flags   = pIn->flags;\n    const BOOL_32             zbuffer = flags.depth || flags.stencil;\n    const BOOL_32             color   = flags.color;\n    const BOOL_32             texture = flags.texture;\n    const BOOL_32             display = flags.display || flags.rotated;\n    const BOOL_32             prt     = flags.prt;\n    const BOOL_32             fmask   = flags.fmask;\n\n    const BOOL_32             thin3d  = tex3d && flags.view3dAs2dArray;\n    const BOOL_32             zMaxMip = tex3d && mipmap &&\n                                        (pIn->numSlices >= pIn->width) && (pIn->numSlices >= pIn->height);\n\n    // Misc check\n    if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numFrags)))\n    {\n        // MSAA surface must have blk_bytes/pipe_interleave >= num_samples\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if ((pIn->bpp == 96) && (linear == FALSE))\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    if (prt && isNonPrtXor)\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    // Resource type check\n    if (tex1d)\n    {\n        if (linear == FALSE)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    // Swizzle type check\n    if (linear)\n    {\n        if (((tex1d == FALSE) && prt) || zbuffer || msaa || (pIn->bpp == 0) ||\n            ((pIn->bpp % 8) != 0) || (isBc && texture) || fmask)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsZOrderSwizzle(swizzle))\n    {\n        if ((color && msaa) || thin3d || isBc || is422 || (tex2d && (pIn->bpp > 64)) || (msaa && (pIn->bpp > 32)))\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsStandardSwizzle(swizzle))\n    {\n        if (zbuffer || thin3d || (tex3d && (pIn->bpp == 128) && color) || fmask)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsDisplaySwizzle(swizzle))\n    {\n        if (zbuffer || (prt && tex3d) || fmask || zMaxMip)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else if (IsRotateSwizzle(swizzle))\n    {\n        if (zbuffer || (pIn->bpp > 64) || tex3d || isBc || fmask)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        valid = FALSE;\n    }\n\n    // Block type check\n    if (blk256B)\n    {\n        if (prt || zbuffer || tex3d || mipmap || msaa)\n        {\n            ADDR_ASSERT_ALWAYS();\n            valid = FALSE;\n        }\n    }\n\n    return valid;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSurfaceInfoSanityCheck\n*\n*   @brief\n*       Compute surface info sanity check\n*\n*   @return\n*       ADDR_OK if parameters are valid, ADDR_INVALIDPARAMS otherwise\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoSanityCheck(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const\n{\n    return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlGetPreferredSurfaceSetting\n*\n*   @brief\n*       Internal function to get suggested surface information for cliet to use\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlGetPreferredSurfaceSetting(\n    const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_INVALIDPARAMS;\n    ElemLib*          pElemLib   = GetElemLib();\n\n    UINT_32 bpp        = pIn->bpp;\n    UINT_32 width      = Max(pIn->width, 1u);\n    UINT_32 height     = Max(pIn->height, 1u);\n    UINT_32 numSamples = Max(pIn->numSamples, 1u);\n    UINT_32 numFrags   = (pIn->numFrags == 0) ? numSamples : pIn->numFrags;\n\n    if (pIn->flags.fmask)\n    {\n        bpp                = GetFmaskBpp(numSamples, numFrags);\n        numFrags           = 1;\n        numSamples         = 1;\n        pOut->resourceType = ADDR_RSRC_TEX_2D;\n    }\n    else\n    {\n        // Set format to INVALID will skip this conversion\n        if (pIn->format != ADDR_FMT_INVALID)\n        {\n            UINT_32 expandX, expandY;\n\n            // Don't care for this case\n            ElemMode elemMode = ADDR_UNCOMPRESSED;\n\n            // Get compression/expansion factors and element mode which indicates compression/expansion\n            bpp = pElemLib->GetBitsPerPixel(pIn->format,\n                                            &elemMode,\n                                            &expandX,\n                                            &expandY);\n\n            UINT_32 basePitch = 0;\n            GetElemLib()->AdjustSurfaceInfo(elemMode,\n                                            expandX,\n                                            expandY,\n                                            &bpp,\n                                            &basePitch,\n                                            &width,\n                                            &height);\n        }\n\n        // The output may get changed for volume(3D) texture resource in future\n        pOut->resourceType = pIn->resourceType;\n    }\n\n    const UINT_32 numSlices    = Max(pIn->numSlices, 1u);\n    const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);\n    const BOOL_32 msaa         = (numFrags > 1) || (numSamples > 1);\n    const BOOL_32 displayRsrc  = pIn->flags.display || pIn->flags.rotated;\n\n    // Pre sanity check on non swizzle mode parameters\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pOut->resourceType;\n    localIn.format       = pIn->format;\n    localIn.bpp          = bpp;\n    localIn.width        = width;\n    localIn.height       = height;\n    localIn.numSlices    = numSlices;\n    localIn.numMipLevels = numMipLevels;\n    localIn.numSamples   = numSamples;\n    localIn.numFrags     = numFrags;\n\n    if (ValidateNonSwModeParams(&localIn))\n    {\n        // Forbid swizzle mode(s) by client setting\n        ADDR2_SWMODE_SET allowedSwModeSet = {};\n        allowedSwModeSet.value |= pIn->forbiddenBlock.linear ? 0 : Gfx9LinearSwModeMask;\n        allowedSwModeSet.value |= pIn->forbiddenBlock.micro  ? 0 : Gfx9Blk256BSwModeMask;\n        allowedSwModeSet.value |=\n            pIn->forbiddenBlock.macroThin4KB ? 0 :\n            ((pOut->resourceType == ADDR_RSRC_TEX_3D) ? Gfx9Rsrc3dThin4KBSwModeMask : Gfx9Blk4KBSwModeMask);\n        allowedSwModeSet.value |=\n            pIn->forbiddenBlock.macroThick4KB ? 0 :\n            ((pOut->resourceType == ADDR_RSRC_TEX_3D) ? Gfx9Rsrc3dThick4KBSwModeMask : 0);\n        allowedSwModeSet.value |=\n            pIn->forbiddenBlock.macroThin64KB ? 0 :\n            ((pOut->resourceType == ADDR_RSRC_TEX_3D) ? Gfx9Rsrc3dThin64KBSwModeMask : Gfx9Blk64KBSwModeMask);\n        allowedSwModeSet.value |=\n            pIn->forbiddenBlock.macroThick64KB ? 0 :\n            ((pOut->resourceType == ADDR_RSRC_TEX_3D) ? Gfx9Rsrc3dThick64KBSwModeMask : 0);\n\n        if (pIn->preferredSwSet.value != 0)\n        {\n            allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx9ZSwModeMask;\n            allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx9StandardSwModeMask;\n            allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx9DisplaySwModeMask;\n            allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx9RotateSwModeMask;\n        }\n\n        if (pIn->noXor)\n        {\n            allowedSwModeSet.value &= ~Gfx9XorSwModeMask;\n        }\n\n        if (pIn->maxAlign > 0)\n        {\n            if (pIn->maxAlign < Size64K)\n            {\n                allowedSwModeSet.value &= ~Gfx9Blk64KBSwModeMask;\n            }\n\n            if (pIn->maxAlign < Size4K)\n            {\n                allowedSwModeSet.value &= ~Gfx9Blk4KBSwModeMask;\n            }\n\n            if (pIn->maxAlign < Size256)\n            {\n                allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;\n            }\n        }\n\n        // Filter out invalid swizzle mode(s) by image attributes and HW restrictions\n        switch (pOut->resourceType)\n        {\n            case ADDR_RSRC_TEX_1D:\n                allowedSwModeSet.value &= Gfx9Rsrc1dSwModeMask;\n                break;\n\n            case ADDR_RSRC_TEX_2D:\n                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc2dPrtSwModeMask : Gfx9Rsrc2dSwModeMask;\n\n                if (bpp > 64)\n                {\n                    allowedSwModeSet.value &= ~(Gfx9RotateSwModeMask | Gfx9ZSwModeMask);\n                }\n                break;\n\n            case ADDR_RSRC_TEX_3D:\n                allowedSwModeSet.value &= pIn->flags.prt ? Gfx9Rsrc3dPrtSwModeMask : Gfx9Rsrc3dSwModeMask;\n\n                if ((numMipLevels > 1) && (numSlices >= width) && (numSlices >= height))\n                {\n                    // SW_*_D for 3D mipmaps (maxmip > 0) is only supported for Xmajor or Ymajor mipmap\n                    // When depth (Z) is the maximum dimension then must use one of the SW_*_S\n                    // or SW_*_Z modes if mipmapping is desired on a 3D surface\n                    allowedSwModeSet.value &= ~Gfx9DisplaySwModeMask;\n                }\n\n                if ((bpp == 128) && pIn->flags.color)\n                {\n                    allowedSwModeSet.value &= ~Gfx9StandardSwModeMask;\n                }\n\n                if (pIn->flags.view3dAs2dArray)\n                {\n                    allowedSwModeSet.value &= Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask;\n                }\n                break;\n\n            default:\n                ADDR_ASSERT_ALWAYS();\n                allowedSwModeSet.value = 0;\n                break;\n        }\n\n        if (pIn->format == ADDR_FMT_32_32_32)\n        {\n            allowedSwModeSet.value &= Gfx9LinearSwModeMask;\n        }\n\n        if (ElemLib::IsBlockCompressed(pIn->format))\n        {\n            if (pIn->flags.texture)\n            {\n                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask;\n            }\n            else\n            {\n                allowedSwModeSet.value &= Gfx9StandardSwModeMask | Gfx9DisplaySwModeMask | Gfx9LinearSwModeMask;\n            }\n        }\n\n        if (ElemLib::IsMacroPixelPacked(pIn->format) ||\n            (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))\n        {\n            allowedSwModeSet.value &= ~Gfx9ZSwModeMask;\n        }\n\n        if (pIn->flags.fmask || pIn->flags.depth || pIn->flags.stencil)\n        {\n            allowedSwModeSet.value &= Gfx9ZSwModeMask;\n\n            if (pIn->flags.noMetadata == FALSE)\n            {\n                if (pIn->flags.depth &&\n                    pIn->flags.texture &&\n                    (((bpp == 16) && (numFrags >= 4)) || ((bpp == 32) && (numFrags >= 2))))\n                {\n                    // When _X/_T swizzle mode was used for MSAA depth texture, TC will get zplane\n                    // equation from wrong address within memory range a tile covered and use the\n                    // garbage data for compressed Z reading which finally leads to corruption.\n                    allowedSwModeSet.value &= ~Gfx9XorSwModeMask;\n                }\n\n                if (m_settings.htileCacheRbConflict &&\n                    (pIn->flags.depth || pIn->flags.stencil) &&\n                    (numSlices > 1) &&\n                    (pIn->flags.metaRbUnaligned == FALSE) &&\n                    (pIn->flags.metaPipeUnaligned == FALSE))\n                {\n                    // Z_X 2D array with Rb/Pipe aligned HTile won't have metadata cache coherency\n                    allowedSwModeSet.value &= ~Gfx9XSwModeMask;\n                }\n            }\n        }\n\n        if (msaa)\n        {\n            allowedSwModeSet.value &= Gfx9MsaaSwModeMask;\n        }\n\n        if ((numFrags > 1) &&\n            (Size4K < (m_pipeInterleaveBytes * numFrags)))\n        {\n            // MSAA surface must have blk_bytes/pipe_interleave >= num_samples\n            allowedSwModeSet.value &= Gfx9Blk64KBSwModeMask;\n        }\n\n        if (numMipLevels > 1)\n        {\n            allowedSwModeSet.value &= ~Gfx9Blk256BSwModeMask;\n        }\n\n        if (displayRsrc)\n        {\n            if (m_settings.isDce12)\n            {\n                allowedSwModeSet.value &= (bpp == 32) ? Dce12Bpp32SwModeMask : Dce12NonBpp32SwModeMask;\n            }\n            else if (m_settings.isDcn1)\n            {\n                allowedSwModeSet.value &= (bpp == 64) ? Dcn1Bpp64SwModeMask : Dcn1NonBpp64SwModeMask;\n            }\n            else if (m_settings.isDcn2)\n            {\n                allowedSwModeSet.value &= (bpp == 64) ? Dcn2Bpp64SwModeMask : Dcn2NonBpp64SwModeMask;\n            }\n            else\n            {\n                ADDR_NOT_IMPLEMENTED();\n            }\n        }\n\n        if (allowedSwModeSet.value != 0)\n        {\n#if DEBUG\n            // Post sanity check, at least AddrLib should accept the output generated by its own\n            UINT_32 validateSwModeSet = allowedSwModeSet.value;\n\n            for (UINT_32 i = 0; validateSwModeSet != 0; i++)\n            {\n                if (validateSwModeSet & 1)\n                {\n                    localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);\n                    ADDR_ASSERT(ValidateSwModeParams(&localIn));\n                }\n\n                validateSwModeSet >>= 1;\n            }\n#endif\n\n            pOut->validSwModeSet = allowedSwModeSet;\n            pOut->canXor         = (allowedSwModeSet.value & Gfx9XorSwModeMask) ? TRUE : FALSE;\n            pOut->validBlockSet  = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);\n            pOut->validSwTypeSet = GetAllowedSwSet(allowedSwModeSet);\n\n            pOut->clientPreferredSwSet = pIn->preferredSwSet;\n\n            if (pOut->clientPreferredSwSet.value == 0)\n            {\n                pOut->clientPreferredSwSet.value = AddrSwSetAll;\n            }\n\n            // Apply optional restrictions\n            if (pIn->flags.needEquation)\n            {\n                UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :\n                                                                    ADDR_MAX_LEGACY_EQUATION_COMP;\n                FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);\n            }\n\n            if (allowedSwModeSet.value == Gfx9LinearSwModeMask)\n            {\n                pOut->swizzleMode = ADDR_SW_LINEAR;\n            }\n            else\n            {\n                const BOOL_32 computeMinSize = (pIn->flags.minimizeAlign == 1) || (pIn->memoryBudget >= 1.0);\n\n                if ((height > 1) && (computeMinSize == FALSE))\n                {\n                    // Always ignore linear swizzle mode if:\n                    // 1. This is a (2D/3D) resource with height > 1\n                    // 2. Client doesn't require computing minimize size\n                    allowedSwModeSet.swLinear = 0;\n                }\n\n                ADDR2_BLOCK_SET allowedBlockSet = GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType);\n\n                // Determine block size if there are 2 or more block type candidates\n                if (IsPow2(allowedBlockSet.value) == FALSE)\n                {\n                    AddrSwizzleMode swMode[AddrBlockMaxTiledType] = {};\n\n                    swMode[AddrBlockLinear]   = ADDR_SW_LINEAR;\n                    swMode[AddrBlockMicro]    = ADDR_SW_256B_D;\n                    swMode[AddrBlockThin4KB]  = ADDR_SW_4KB_D;\n                    swMode[AddrBlockThin64KB] = ADDR_SW_64KB_D;\n\n                    if (pOut->resourceType == ADDR_RSRC_TEX_3D)\n                    {\n                        swMode[AddrBlockThick4KB]  = ADDR_SW_4KB_S;\n                        swMode[AddrBlockThick64KB] = ADDR_SW_64KB_S;\n                    }\n\n                    UINT_64 padSize[AddrBlockMaxTiledType] = {};\n\n                    const UINT_32 ratioLow           = computeMinSize ? 1 : (pIn->flags.opt4space ? 3 : 2);\n                    const UINT_32 ratioHi            = computeMinSize ? 1 : (pIn->flags.opt4space ? 2 : 1);\n                    const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);\n                    UINT_32       minSizeBlk         = AddrBlockMicro;\n                    UINT_64       minSize            = 0;\n\n                    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};\n\n                    for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)\n                    {\n                        if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                        {\n                            localIn.swizzleMode = swMode[i];\n\n                            if (localIn.swizzleMode == ADDR_SW_LINEAR)\n                            {\n                                returnCode = HwlComputeSurfaceInfoLinear(&localIn, &localOut);\n                            }\n                            else\n                            {\n                                returnCode = HwlComputeSurfaceInfoTiled(&localIn, &localOut);\n                            }\n\n                            if (returnCode == ADDR_OK)\n                            {\n                                padSize[i] = localOut.surfSize;\n\n                                if ((minSize == 0) ||\n                                    Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))\n                                {\n                                    minSize    = padSize[i];\n                                    minSizeBlk = i;\n                                }\n                            }\n                            else\n                            {\n                                ADDR_ASSERT_ALWAYS();\n                                break;\n                            }\n                        }\n                    }\n\n                    if (pIn->memoryBudget > 1.0)\n                    {\n                        // If minimum size is given by swizzle mode with bigger-block type, then don't ever check\n                        // smaller-block type again in coming loop\n                        switch (minSizeBlk)\n                        {\n                            case AddrBlockThick64KB:\n                                allowedBlockSet.macroThin64KB = 0;\n                            case AddrBlockThin64KB:\n                                allowedBlockSet.macroThick4KB = 0;\n                            case AddrBlockThick4KB:\n                                allowedBlockSet.macroThin4KB = 0;\n                            case AddrBlockThin4KB:\n                                allowedBlockSet.micro  = 0;\n                            case AddrBlockMicro:\n                                allowedBlockSet.linear = 0;\n                            case AddrBlockLinear:\n                                break;\n\n                            default:\n                                ADDR_ASSERT_ALWAYS();\n                                break;\n                        }\n\n                        for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)\n                        {\n                            if ((i != minSizeBlk) &&\n                                Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<rocr::AddrBlockType>(i)))\n                            {\n                                if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)\n                                {\n                                    // Clear the block type if the memory waste is unacceptable\n                                    allowedBlockSet.value &= ~(1u << (i - 1));\n                                }\n                            }\n                        }\n\n                        // Remove linear block type if 2 or more block types are allowed\n                        if (IsPow2(allowedBlockSet.value) == FALSE)\n                        {\n                            allowedBlockSet.linear = 0;\n                        }\n\n                        // Select the biggest allowed block type\n                        minSizeBlk = Log2NonPow2(allowedBlockSet.value) + 1;\n\n                        if (minSizeBlk == static_cast<UINT_32>(AddrBlockMaxTiledType))\n                        {\n                            minSizeBlk = AddrBlockLinear;\n                        }\n                    }\n\n                    switch (minSizeBlk)\n                    {\n                        case AddrBlockLinear:\n                            allowedSwModeSet.value &= Gfx9LinearSwModeMask;\n                            break;\n\n                        case AddrBlockMicro:\n                            ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);\n                            allowedSwModeSet.value &= Gfx9Blk256BSwModeMask;\n                            break;\n\n                        case AddrBlockThin4KB:\n                            allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?\n                                                      Gfx9Rsrc3dThin4KBSwModeMask : Gfx9Blk4KBSwModeMask;\n                            break;\n\n                        case AddrBlockThick4KB:\n                            ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                            allowedSwModeSet.value &= Gfx9Rsrc3dThick4KBSwModeMask;\n                            break;\n\n                        case AddrBlockThin64KB:\n                            allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?\n                                                      Gfx9Rsrc3dThin64KBSwModeMask : Gfx9Blk64KBSwModeMask;\n                            break;\n\n                        case AddrBlockThick64KB:\n                            ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);\n                            allowedSwModeSet.value &= Gfx9Rsrc3dThick64KBSwModeMask;\n                            break;\n\n                        default:\n                            ADDR_ASSERT_ALWAYS();\n                            allowedSwModeSet.value = 0;\n                            break;\n                    }\n                }\n\n                // Block type should be determined.\n                ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType).value));\n\n                ADDR2_SWTYPE_SET allowedSwSet = GetAllowedSwSet(allowedSwModeSet);\n\n                // Determine swizzle type if there are 2 or more swizzle type candidates\n                if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))\n                {\n                    if (ElemLib::IsBlockCompressed(pIn->format))\n                    {\n                        if (allowedSwSet.sw_D)\n                        {\n                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(allowedSwSet.sw_S);\n                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;\n                        }\n                    }\n                    else if (ElemLib::IsMacroPixelPacked(pIn->format))\n                    {\n                        if (allowedSwSet.sw_S)\n                        {\n                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;\n                        }\n                        else if (allowedSwSet.sw_D)\n                        {\n                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(allowedSwSet.sw_R);\n                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;\n                        }\n                    }\n                    else if (pOut->resourceType == ADDR_RSRC_TEX_3D)\n                    {\n                        if (pIn->flags.color && allowedSwSet.sw_D)\n                        {\n                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;\n                        }\n                        else if (allowedSwSet.sw_Z)\n                        {\n                            allowedSwModeSet.value &= Gfx9ZSwModeMask;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(allowedSwSet.sw_S);\n                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;\n                        }\n                    }\n                    else\n                    {\n                        if (pIn->flags.rotated && allowedSwSet.sw_R)\n                        {\n                            allowedSwModeSet.value &= Gfx9RotateSwModeMask;\n                        }\n                        else if (allowedSwSet.sw_D)\n                        {\n                            allowedSwModeSet.value &= Gfx9DisplaySwModeMask;\n                        }\n                        else if (allowedSwSet.sw_S)\n                        {\n                            allowedSwModeSet.value &= Gfx9StandardSwModeMask;\n                        }\n                        else\n                        {\n                            ADDR_ASSERT(allowedSwSet.sw_Z);\n                            allowedSwModeSet.value &= Gfx9ZSwModeMask;\n                        }\n                    }\n\n                    // Swizzle type should be determined.\n                    ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet).value));\n                }\n\n                // Determine swizzle mode now. Always select the \"largest\" swizzle mode for a given block type + swizzle\n                // type combination. For example, for AddrBlockThin64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's\n                // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).\n                pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));\n            }\n\n            returnCode = ADDR_OK;\n        }\n        else\n        {\n            // Invalid combination...\n            ADDR_ASSERT_ALWAYS();\n        }\n    }\n    else\n    {\n        // Invalid combination...\n        ADDR_ASSERT_ALWAYS();\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::ComputeStereoInfo\n*\n*   @brief\n*       Compute height alignment and right eye pipeBankXor for stereo surface\n*\n*   @return\n*       Error code\n*\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::ComputeStereoInfo(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut,\n    UINT_32*                                pHeightAlign\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    UINT_32 eqIndex = HwlGetEquationIndex(pIn, pOut);\n\n    if (eqIndex < m_numEquations)\n    {\n        if (IsXor(pIn->swizzleMode))\n        {\n            const UINT_32        blkSizeLog2       = GetBlockSizeLog2(pIn->swizzleMode);\n            const UINT_32        numPipeBits       = GetPipeXorBits(blkSizeLog2);\n            const UINT_32        numBankBits       = GetBankXorBits(blkSizeLog2);\n            const UINT_32        bppLog2           = Log2(pIn->bpp >> 3);\n            const UINT_32        maxYCoordBlock256 = Log2(Block256_2d[bppLog2].h) - 1;\n            const ADDR_EQUATION *pEqToCheck        = &m_equationTable[eqIndex];\n\n            ADDR_ASSERT(maxYCoordBlock256 ==\n                        GetMaxValidChannelIndex(&pEqToCheck->addr[0], Log2Size256, 1));\n\n            const UINT_32 maxYCoordInBaseEquation =\n                (blkSizeLog2 - Log2Size256) / 2 + maxYCoordBlock256;\n\n            ADDR_ASSERT(maxYCoordInBaseEquation ==\n                        GetMaxValidChannelIndex(&pEqToCheck->addr[0], blkSizeLog2, 1));\n\n            const UINT_32 maxYCoordInPipeXor = (numPipeBits == 0) ? 0 : maxYCoordBlock256 + numPipeBits;\n\n            ADDR_ASSERT(maxYCoordInPipeXor ==\n                        GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2], numPipeBits, 1));\n\n            const UINT_32 maxYCoordInBankXor = (numBankBits == 0) ?\n                                               0 : maxYCoordBlock256 + (numPipeBits + 1) / 2 + numBankBits;\n\n            ADDR_ASSERT(maxYCoordInBankXor ==\n                        GetMaxValidChannelIndex(&pEqToCheck->xor1[m_pipeInterleaveLog2 + numPipeBits], numBankBits, 1));\n\n            const UINT_32 maxYCoordInPipeBankXor = Max(maxYCoordInPipeXor, maxYCoordInBankXor);\n\n            if (maxYCoordInPipeBankXor > maxYCoordInBaseEquation)\n            {\n                *pHeightAlign = 1u << maxYCoordInPipeBankXor;\n\n                if (pOut->pStereoInfo != NULL)\n                {\n                    pOut->pStereoInfo->rightSwizzle = 0;\n\n                    if ((PowTwoAlign(pIn->height, *pHeightAlign) % (*pHeightAlign * 2)) != 0)\n                    {\n                        if (maxYCoordInPipeXor == maxYCoordInPipeBankXor)\n                        {\n                            pOut->pStereoInfo->rightSwizzle |= (1u << 1);\n                        }\n\n                        if (maxYCoordInBankXor == maxYCoordInPipeBankXor)\n                        {\n                            pOut->pStereoInfo->rightSwizzle |=\n                                1u << ((numPipeBits % 2) ? numPipeBits : numPipeBits + 1);\n                        }\n\n                        ADDR_ASSERT(pOut->pStereoInfo->rightSwizzle ==\n                                    GetCoordActiveMask(&pEqToCheck->xor1[m_pipeInterleaveLog2],\n                                                       numPipeBits + numBankBits, 1, maxYCoordInPipeBankXor));\n                    }\n                }\n            }\n        }\n    }\n    else\n    {\n        ADDR_ASSERT_ALWAYS();\n        returnCode = ADDR_ERROR;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSurfaceInfoTiled\n*\n*   @brief\n*       Internal function to calculate alignment for tiled surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoTiled(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,\n                                                                &pOut->blockHeight,\n                                                                &pOut->blockSlices,\n                                                                pIn->bpp,\n                                                                pIn->numFrags,\n                                                                pIn->resourceType,\n                                                                pIn->swizzleMode);\n\n    if (returnCode == ADDR_OK)\n    {\n        UINT_32 pitchAlignInElement = pOut->blockWidth;\n\n        if ((IsTex2d(pIn->resourceType) == TRUE) &&\n            (pIn->flags.display || pIn->flags.rotated) &&\n            (pIn->numMipLevels <= 1) &&\n            (pIn->numSamples <= 1) &&\n            (pIn->numFrags <= 1))\n        {\n            // Display engine needs pitch align to be at least 32 pixels.\n            pitchAlignInElement = PowTwoAlign(pitchAlignInElement, 32);\n        }\n\n        pOut->pitch = PowTwoAlign(pIn->width, pitchAlignInElement);\n\n        if ((pIn->numMipLevels <= 1) && (pIn->pitchInElement > 0))\n        {\n            if ((pIn->pitchInElement % pitchAlignInElement) != 0)\n            {\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n            else if (pIn->pitchInElement < pOut->pitch)\n            {\n                returnCode = ADDR_INVALIDPARAMS;\n            }\n            else\n            {\n                pOut->pitch = pIn->pitchInElement;\n            }\n        }\n\n        UINT_32 heightAlign = 0;\n\n        if (pIn->flags.qbStereo)\n        {\n            returnCode = ComputeStereoInfo(pIn, pOut, &heightAlign);\n        }\n\n        if (returnCode == ADDR_OK)\n        {\n            pOut->height = PowTwoAlign(pIn->height, pOut->blockHeight);\n\n            if (heightAlign > 1)\n            {\n                pOut->height = PowTwoAlign(pOut->height, heightAlign);\n            }\n\n            pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);\n\n            pOut->epitchIsHeight   = FALSE;\n            pOut->mipChainInTail   = FALSE;\n            pOut->firstMipIdInTail = pIn->numMipLevels;\n\n            pOut->mipChainPitch    = pOut->pitch;\n            pOut->mipChainHeight   = pOut->height;\n            pOut->mipChainSlice    = pOut->numSlices;\n\n            if (pIn->numMipLevels > 1)\n            {\n                pOut->firstMipIdInTail = GetMipChainInfo(pIn->resourceType,\n                                                         pIn->swizzleMode,\n                                                         pIn->bpp,\n                                                         pIn->width,\n                                                         pIn->height,\n                                                         pIn->numSlices,\n                                                         pOut->blockWidth,\n                                                         pOut->blockHeight,\n                                                         pOut->blockSlices,\n                                                         pIn->numMipLevels,\n                                                         pOut->pMipInfo);\n\n                const UINT_32 endingMipId = Min(pOut->firstMipIdInTail, pIn->numMipLevels - 1);\n\n                if (endingMipId == 0)\n                {\n                    const Dim3d tailMaxDim = GetMipTailDim(pIn->resourceType,\n                                                           pIn->swizzleMode,\n                                                           pOut->blockWidth,\n                                                           pOut->blockHeight,\n                                                           pOut->blockSlices);\n\n                    pOut->epitchIsHeight = TRUE;\n                    pOut->pitch          = tailMaxDim.w;\n                    pOut->height         = tailMaxDim.h;\n                    pOut->numSlices      = IsThick(pIn->resourceType, pIn->swizzleMode) ?\n                                           tailMaxDim.d : pIn->numSlices;\n                    pOut->mipChainInTail = TRUE;\n                }\n                else\n                {\n                    UINT_32 mip0WidthInBlk  = pOut->pitch  / pOut->blockWidth;\n                    UINT_32 mip0HeightInBlk = pOut->height / pOut->blockHeight;\n\n                    AddrMajorMode majorMode = GetMajorMode(pIn->resourceType,\n                                                           pIn->swizzleMode,\n                                                           mip0WidthInBlk,\n                                                           mip0HeightInBlk,\n                                                           pOut->numSlices / pOut->blockSlices);\n                    if (majorMode == ADDR_MAJOR_Y)\n                    {\n                        UINT_32 mip1WidthInBlk = RoundHalf(mip0WidthInBlk);\n\n                        if ((mip1WidthInBlk == 1) && (endingMipId > 2))\n                        {\n                            mip1WidthInBlk++;\n                        }\n\n                        pOut->mipChainPitch += (mip1WidthInBlk * pOut->blockWidth);\n\n                        pOut->epitchIsHeight = FALSE;\n                    }\n                    else\n                    {\n                        UINT_32 mip1HeightInBlk = RoundHalf(mip0HeightInBlk);\n\n                        if ((mip1HeightInBlk == 1) && (endingMipId > 2))\n                        {\n                            mip1HeightInBlk++;\n                        }\n\n                        pOut->mipChainHeight += (mip1HeightInBlk * pOut->blockHeight);\n\n                        pOut->epitchIsHeight = TRUE;\n                    }\n                }\n\n                if (pOut->pMipInfo != NULL)\n                {\n                    UINT_32 elementBytesLog2 = Log2(pIn->bpp >> 3);\n\n                    for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n                    {\n                        Dim3d   mipStartPos          = {0};\n                        UINT_32 mipTailOffsetInBytes = 0;\n\n                        mipStartPos = GetMipStartPos(pIn->resourceType,\n                                                     pIn->swizzleMode,\n                                                     pOut->pitch,\n                                                     pOut->height,\n                                                     pOut->numSlices,\n                                                     pOut->blockWidth,\n                                                     pOut->blockHeight,\n                                                     pOut->blockSlices,\n                                                     i,\n                                                     elementBytesLog2,\n                                                     &mipTailOffsetInBytes);\n\n                        UINT_32 pitchInBlock     =\n                            pOut->mipChainPitch / pOut->blockWidth;\n                        UINT_32 sliceInBlock     =\n                            (pOut->mipChainHeight / pOut->blockHeight) * pitchInBlock;\n                        UINT_64 blockIndex       =\n                            mipStartPos.d * sliceInBlock + mipStartPos.h * pitchInBlock + mipStartPos.w;\n                        UINT_64 macroBlockOffset =\n                            blockIndex << GetBlockSizeLog2(pIn->swizzleMode);\n\n                        pOut->pMipInfo[i].macroBlockOffset = macroBlockOffset;\n                        pOut->pMipInfo[i].mipTailOffset    = mipTailOffsetInBytes;\n                    }\n                }\n            }\n            else if (pOut->pMipInfo != NULL)\n            {\n                pOut->pMipInfo[0].pitch  = pOut->pitch;\n                pOut->pMipInfo[0].height = pOut->height;\n                pOut->pMipInfo[0].depth  = IsTex3d(pIn->resourceType)? pOut->numSlices : 1;\n                pOut->pMipInfo[0].offset = 0;\n            }\n\n            pOut->sliceSize = static_cast<UINT_64>(pOut->mipChainPitch) * pOut->mipChainHeight *\n                              (pIn->bpp >> 3) * pIn->numFrags;\n            pOut->surfSize  = pOut->sliceSize * pOut->mipChainSlice;\n            pOut->baseAlign = ComputeSurfaceBaseAlignTiled(pIn->swizzleMode);\n\n            if ((IsBlock256b(pIn->swizzleMode) == FALSE) &&\n                (pIn->flags.color || pIn->flags.depth || pIn->flags.stencil || pIn->flags.fmask) &&\n                (pIn->flags.texture == TRUE) &&\n                (pIn->flags.noMetadata == FALSE) &&\n                (pIn->flags.metaPipeUnaligned == FALSE))\n            {\n                // Assume client requires pipe aligned metadata, which is TcCompatible and will be accessed by TC...\n                // Then we need extra padding for base surface. Otherwise, metadata and data surface for same pixel will\n                // be flushed to different pipes, but texture engine only uses pipe id of data surface to fetch both of\n                // them, which may cause invalid metadata to be fetched.\n                pOut->baseAlign = Max(pOut->baseAlign, m_pipeInterleaveBytes * m_pipes * m_se);\n            }\n\n            if (pIn->flags.prt)\n            {\n                pOut->baseAlign = Max(pOut->baseAlign, PrtAlignment);\n            }\n        }\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSurfaceInfoLinear\n*\n*   @brief\n*       Internal function to calculate alignment for linear surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceInfoLinear(\n     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR_E_RETURNCODE returnCode   = ADDR_OK;\n    UINT_32           pitch        = 0;\n    UINT_32           actualHeight = 0;\n    UINT_32           elementBytes = pIn->bpp >> 3;\n    const UINT_32     alignment    = pIn->flags.prt ? PrtAlignment : 256;\n\n    if (IsTex1d(pIn->resourceType))\n    {\n        if (pIn->height > 1)\n        {\n            returnCode = ADDR_INVALIDPARAMS;\n        }\n        else\n        {\n            const UINT_32 pitchAlignInElement = alignment / elementBytes;\n\n            pitch        = PowTwoAlign(pIn->width, pitchAlignInElement);\n            actualHeight = pIn->numMipLevels;\n\n            if (pIn->flags.prt == FALSE)\n            {\n                returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlignInElement,\n                                                        &pitch, &actualHeight);\n            }\n\n            if (returnCode == ADDR_OK)\n            {\n                if (pOut->pMipInfo != NULL)\n                {\n                    for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n                    {\n                        pOut->pMipInfo[i].offset = pitch * elementBytes * i;\n                        pOut->pMipInfo[i].pitch  = pitch;\n                        pOut->pMipInfo[i].height = 1;\n                        pOut->pMipInfo[i].depth  = 1;\n                    }\n                }\n            }\n        }\n    }\n    else\n    {\n        returnCode = ComputeSurfaceLinearPadding(pIn, &pitch, &actualHeight, pOut->pMipInfo);\n    }\n\n    if ((pitch == 0) || (actualHeight == 0))\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    if (returnCode == ADDR_OK)\n    {\n        pOut->pitch          = pitch;\n        pOut->height         = pIn->height;\n        pOut->numSlices      = pIn->numSlices;\n        pOut->mipChainPitch  = pitch;\n        pOut->mipChainHeight = actualHeight;\n        pOut->mipChainSlice  = pOut->numSlices;\n        pOut->epitchIsHeight = (pIn->numMipLevels > 1) ? TRUE : FALSE;\n        pOut->sliceSize      = static_cast<UINT_64>(pOut->pitch) * actualHeight * elementBytes;\n        pOut->surfSize       = pOut->sliceSize * pOut->numSlices;\n        pOut->baseAlign      = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? (pIn->bpp / 8) : alignment;\n        pOut->blockWidth     = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 / elementBytes);\n        pOut->blockHeight    = 1;\n        pOut->blockSlices    = 1;\n    }\n\n    // Post calculation validate\n    ADDR_ASSERT(pOut->sliceSize > 0);\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetMipChainInfo\n*\n*   @brief\n*       Internal function to get out information about mip chain\n*\n*   @return\n*       Smaller value between Id of first mip fitted in mip tail and max Id of mip being created\n************************************************************************************************************************\n*/\nUINT_32 Gfx9Lib::GetMipChainInfo(\n    AddrResourceType  resourceType,\n    AddrSwizzleMode   swizzleMode,\n    UINT_32           bpp,\n    UINT_32           mip0Width,\n    UINT_32           mip0Height,\n    UINT_32           mip0Depth,\n    UINT_32           blockWidth,\n    UINT_32           blockHeight,\n    UINT_32           blockDepth,\n    UINT_32           numMipLevel,\n    ADDR2_MIP_INFO*   pMipInfo) const\n{\n    const Dim3d tailMaxDim =\n        GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth);\n\n    UINT_32 mipPitch         = mip0Width;\n    UINT_32 mipHeight        = mip0Height;\n    UINT_32 mipDepth         = IsTex3d(resourceType) ? mip0Depth : 1;\n    UINT_32 offset           = 0;\n    UINT_32 firstMipIdInTail = numMipLevel;\n    BOOL_32 inTail           = FALSE;\n    BOOL_32 finalDim         = FALSE;\n    BOOL_32 is3dThick        = IsThick(resourceType, swizzleMode);\n    BOOL_32 is3dThin         = IsTex3d(resourceType) && (is3dThick == FALSE);\n\n    for (UINT_32 mipId = 0; mipId < numMipLevel; mipId++)\n    {\n        if (inTail)\n        {\n            if (finalDim == FALSE)\n            {\n                UINT_32 mipSize;\n\n                if (is3dThick)\n                {\n                    mipSize = mipPitch * mipHeight * mipDepth * (bpp >> 3);\n                }\n                else\n                {\n                    mipSize = mipPitch * mipHeight * (bpp >> 3);\n                }\n\n                if (mipSize <= 256)\n                {\n                    UINT_32 index = Log2(bpp >> 3);\n\n                    if (is3dThick)\n                    {\n                        mipPitch  = Block256_3dZ[index].w;\n                        mipHeight = Block256_3dZ[index].h;\n                        mipDepth  = Block256_3dZ[index].d;\n                    }\n                    else\n                    {\n                        mipPitch  = Block256_2d[index].w;\n                        mipHeight = Block256_2d[index].h;\n                    }\n\n                    finalDim = TRUE;\n                }\n            }\n        }\n        else\n        {\n            inTail = IsInMipTail(resourceType, swizzleMode, tailMaxDim,\n                                 mipPitch, mipHeight, mipDepth);\n\n            if (inTail)\n            {\n                firstMipIdInTail = mipId;\n                mipPitch         = tailMaxDim.w;\n                mipHeight        = tailMaxDim.h;\n\n                if (is3dThick)\n                {\n                    mipDepth = tailMaxDim.d;\n                }\n            }\n            else\n            {\n                mipPitch  = PowTwoAlign(mipPitch,  blockWidth);\n                mipHeight = PowTwoAlign(mipHeight, blockHeight);\n\n                if (is3dThick)\n                {\n                    mipDepth = PowTwoAlign(mipDepth,  blockDepth);\n                }\n            }\n        }\n\n        if (pMipInfo != NULL)\n        {\n            pMipInfo[mipId].pitch  = mipPitch;\n            pMipInfo[mipId].height = mipHeight;\n            pMipInfo[mipId].depth  = mipDepth;\n            pMipInfo[mipId].offset = offset;\n        }\n\n        offset += (mipPitch * mipHeight * mipDepth * (bpp >> 3));\n\n        if (finalDim)\n        {\n            if (is3dThin)\n            {\n                mipDepth = Max(mipDepth >> 1, 1u);\n            }\n        }\n        else\n        {\n            mipPitch  = Max(mipPitch >> 1, 1u);\n            mipHeight = Max(mipHeight >> 1, 1u);\n\n            if (is3dThick || is3dThin)\n            {\n                mipDepth = Max(mipDepth >> 1, 1u);\n            }\n        }\n    }\n\n    return firstMipIdInTail;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetMetaMiptailInfo\n*\n*   @brief\n*       Get mip tail coordinate information.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::GetMetaMiptailInfo(\n    ADDR2_META_MIP_INFO*    pInfo,          ///< [out] output structure to store per mip coord\n    Dim3d                   mipCoord,       ///< [in] mip tail base coord\n    UINT_32                 numMipInTail,   ///< [in] number of mips in tail\n    Dim3d*                  pMetaBlkDim     ///< [in] meta block width/height/depth\n    ) const\n{\n    BOOL_32 isThick   = (pMetaBlkDim->d > 1);\n    UINT_32 mipWidth  = pMetaBlkDim->w;\n    UINT_32 mipHeight = pMetaBlkDim->h >> 1;\n    UINT_32 mipDepth  = pMetaBlkDim->d;\n    UINT_32 minInc;\n\n    if (isThick)\n    {\n        minInc = (pMetaBlkDim->h >= 512) ? 128 : ((pMetaBlkDim->h == 256) ? 64 : 32);\n    }\n    else if (pMetaBlkDim->h >= 1024)\n    {\n        minInc = 256;\n    }\n    else if (pMetaBlkDim->h == 512)\n    {\n        minInc = 128;\n    }\n    else\n    {\n        minInc = 64;\n    }\n\n    UINT_32 blk32MipId = 0xFFFFFFFF;\n\n    for (UINT_32 mip = 0; mip < numMipInTail; mip++)\n    {\n        pInfo[mip].inMiptail = TRUE;\n        pInfo[mip].startX = mipCoord.w;\n        pInfo[mip].startY = mipCoord.h;\n        pInfo[mip].startZ = mipCoord.d;\n        pInfo[mip].width = mipWidth;\n        pInfo[mip].height = mipHeight;\n        pInfo[mip].depth = mipDepth;\n\n        if (mipWidth <= 32)\n        {\n            if (blk32MipId == 0xFFFFFFFF)\n            {\n                blk32MipId = mip;\n            }\n\n            mipCoord.w = pInfo[blk32MipId].startX;\n            mipCoord.h = pInfo[blk32MipId].startY;\n            mipCoord.d = pInfo[blk32MipId].startZ;\n\n            switch (mip - blk32MipId)\n            {\n                case 0:\n                    mipCoord.w += 32;       // 16x16\n                    break;\n                case 1:\n                    mipCoord.h += 32;       // 8x8\n                    break;\n                case 2:\n                    mipCoord.h += 32;       // 4x4\n                    mipCoord.w += 16;\n                    break;\n                case 3:\n                    mipCoord.h += 32;       // 2x2\n                    mipCoord.w += 32;\n                    break;\n                case 4:\n                    mipCoord.h += 32;       // 1x1\n                    mipCoord.w += 48;\n                    break;\n                // The following are for BC/ASTC formats\n                case 5:\n                    mipCoord.h += 48;       // 1/2 x 1/2\n                    break;\n                case 6:\n                    mipCoord.h += 48;       // 1/4 x 1/4\n                    mipCoord.w += 16;\n                    break;\n                case 7:\n                    mipCoord.h += 48;       // 1/8 x 1/8\n                    mipCoord.w += 32;\n                    break;\n                case 8:\n                    mipCoord.h += 48;       // 1/16 x 1/16\n                    mipCoord.w += 48;\n                    break;\n                default:\n                    ADDR_ASSERT_ALWAYS();\n                    break;\n            }\n\n            mipWidth = ((mip - blk32MipId) == 0) ? 16 : 8;\n            mipHeight = mipWidth;\n\n            if (isThick)\n            {\n                mipDepth = mipWidth;\n            }\n        }\n        else\n        {\n            if (mipWidth <= minInc)\n            {\n                // if we're below the minimal increment...\n                if (isThick)\n                {\n                    // For 3d, just go in z direction\n                    mipCoord.d += mipDepth;\n                }\n                else\n                {\n                    // For 2d, first go across, then down\n                    if ((mipWidth * 2) == minInc)\n                    {\n                        // if we're 2 mips below, that's when we go back in x, and down in y\n                        mipCoord.w -= minInc;\n                        mipCoord.h += minInc;\n                    }\n                    else\n                    {\n                        // otherwise, just go across in x\n                        mipCoord.w += minInc;\n                    }\n                }\n            }\n            else\n            {\n                // On even mip, go down, otherwise, go across\n                if (mip & 1)\n                {\n                    mipCoord.w += mipWidth;\n                }\n                else\n                {\n                    mipCoord.h += mipHeight;\n                }\n            }\n            // Divide the width by 2\n            mipWidth >>= 1;\n            // After the first mip in tail, the mip is always a square\n            mipHeight = mipWidth;\n            // ...or for 3d, a cube\n            if (isThick)\n            {\n                mipDepth = mipWidth;\n            }\n        }\n    }\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::GetMipStartPos\n*\n*   @brief\n*       Internal function to get out information about mip logical start position\n*\n*   @return\n*       logical start position in macro block width/heith/depth of one mip level within one slice\n************************************************************************************************************************\n*/\nDim3d Gfx9Lib::GetMipStartPos(\n    AddrResourceType  resourceType,\n    AddrSwizzleMode   swizzleMode,\n    UINT_32           width,\n    UINT_32           height,\n    UINT_32           depth,\n    UINT_32           blockWidth,\n    UINT_32           blockHeight,\n    UINT_32           blockDepth,\n    UINT_32           mipId,\n    UINT_32           log2ElementBytes,\n    UINT_32*          pMipTailBytesOffset) const\n{\n    Dim3d       mipStartPos = {0};\n    const Dim3d tailMaxDim  = GetMipTailDim(resourceType, swizzleMode, blockWidth, blockHeight, blockDepth);\n\n    // Report mip in tail if Mip0 is already in mip tail\n    BOOL_32 inMipTail      = IsInMipTail(resourceType, swizzleMode, tailMaxDim, width, height, depth);\n    UINT_32 log2BlkSize    = GetBlockSizeLog2(swizzleMode);\n    UINT_32 mipIndexInTail = mipId;\n\n    if (inMipTail == FALSE)\n    {\n        // Mip 0 dimension, unit in block\n        UINT_32 mipWidthInBlk   = width  / blockWidth;\n        UINT_32 mipHeightInBlk  = height / blockHeight;\n        UINT_32 mipDepthInBlk   = depth  / blockDepth;\n        AddrMajorMode majorMode = GetMajorMode(resourceType,\n                                               swizzleMode,\n                                               mipWidthInBlk,\n                                               mipHeightInBlk,\n                                               mipDepthInBlk);\n\n        UINT_32 endingMip = mipId + 1;\n\n        for (UINT_32 i = 1; i <= mipId; i++)\n        {\n            if ((i == 1) || (i == 3))\n            {\n                if (majorMode == ADDR_MAJOR_Y)\n                {\n                    mipStartPos.w += mipWidthInBlk;\n                }\n                else\n                {\n                    mipStartPos.h += mipHeightInBlk;\n                }\n            }\n            else\n            {\n                if (majorMode == ADDR_MAJOR_X)\n                {\n                   mipStartPos.w += mipWidthInBlk;\n                }\n                else if (majorMode == ADDR_MAJOR_Y)\n                {\n                   mipStartPos.h += mipHeightInBlk;\n                }\n                else\n                {\n                   mipStartPos.d += mipDepthInBlk;\n                }\n            }\n\n            BOOL_32 inTail = FALSE;\n\n            if (IsThick(resourceType, swizzleMode))\n            {\n                UINT_32 dim = log2BlkSize % 3;\n\n                if (dim == 0)\n                {\n                    inTail =\n                        (mipWidthInBlk <= 2) && (mipHeightInBlk == 1) && (mipDepthInBlk <= 2);\n                }\n                else if (dim == 1)\n                {\n                    inTail =\n                        (mipWidthInBlk == 1) && (mipHeightInBlk <= 2) && (mipDepthInBlk <= 2);\n                }\n                else\n                {\n                    inTail =\n                        (mipWidthInBlk <= 2) && (mipHeightInBlk <= 2) && (mipDepthInBlk == 1);\n                }\n            }\n            else\n            {\n                if (log2BlkSize & 1)\n                {\n                    inTail = (mipWidthInBlk <= 2) && (mipHeightInBlk == 1);\n                }\n                else\n                {\n                    inTail = (mipWidthInBlk == 1) && (mipHeightInBlk <= 2);\n                }\n            }\n\n            if (inTail)\n            {\n                endingMip = i;\n                break;\n            }\n\n            mipWidthInBlk  = RoundHalf(mipWidthInBlk);\n            mipHeightInBlk = RoundHalf(mipHeightInBlk);\n            mipDepthInBlk  = RoundHalf(mipDepthInBlk);\n        }\n\n        if (mipId >= endingMip)\n        {\n            inMipTail      = TRUE;\n            mipIndexInTail = mipId - endingMip;\n        }\n    }\n\n    if (inMipTail)\n    {\n        UINT_32 index = mipIndexInTail + MaxMacroBits - log2BlkSize;\n        ADDR_ASSERT(index < sizeof(MipTailOffset256B) / sizeof(UINT_32));\n        *pMipTailBytesOffset = MipTailOffset256B[index] << 8;\n    }\n\n    return mipStartPos;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled\n*\n*   @brief\n*       Internal function to calculate address from coord for tiled swizzle surface\n*\n*   @return\n*       ADDR_E_RETURNCODE\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::HwlComputeSurfaceAddrFromCoordTiled(\n     const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure\n     ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure\n     ) const\n{\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};\n    localIn.swizzleMode  = pIn->swizzleMode;\n    localIn.flags        = pIn->flags;\n    localIn.resourceType = pIn->resourceType;\n    localIn.bpp          = pIn->bpp;\n    localIn.width        = Max(pIn->unalignedWidth, 1u);\n    localIn.height       = Max(pIn->unalignedHeight, 1u);\n    localIn.numSlices    = Max(pIn->numSlices, 1u);\n    localIn.numMipLevels = Max(pIn->numMipLevels, 1u);\n    localIn.numSamples   = Max(pIn->numSamples, 1u);\n    localIn.numFrags     = Max(pIn->numFrags, 1u);\n    if (localIn.numMipLevels <= 1)\n    {\n        localIn.pitchInElement = pIn->pitchInElement;\n    }\n\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n    ADDR_E_RETURNCODE returnCode = ComputeSurfaceInfoTiled(&localIn, &localOut);\n\n    BOOL_32 valid = (returnCode == ADDR_OK) &&\n                    (IsThin(pIn->resourceType, pIn->swizzleMode) ||\n                     IsThick(pIn->resourceType, pIn->swizzleMode)) &&\n                    ((pIn->pipeBankXor == 0) || (IsXor(pIn->swizzleMode)));\n\n    if (valid)\n    {\n        UINT_32 log2ElementBytes   = Log2(pIn->bpp >> 3);\n        Dim3d   mipStartPos        = {0};\n        UINT_32 mipTailBytesOffset = 0;\n\n        if (pIn->numMipLevels > 1)\n        {\n            // Mip-map chain cannot be MSAA surface\n            ADDR_ASSERT((pIn->numSamples <= 1) && (pIn->numFrags<= 1));\n\n            mipStartPos = GetMipStartPos(pIn->resourceType,\n                                         pIn->swizzleMode,\n                                         localOut.pitch,\n                                         localOut.height,\n                                         localOut.numSlices,\n                                         localOut.blockWidth,\n                                         localOut.blockHeight,\n                                         localOut.blockSlices,\n                                         pIn->mipId,\n                                         log2ElementBytes,\n                                         &mipTailBytesOffset);\n        }\n\n        UINT_32 interleaveOffset = 0;\n        UINT_32 pipeBits = 0;\n        UINT_32 pipeXor = 0;\n        UINT_32 bankBits = 0;\n        UINT_32 bankXor = 0;\n\n        if (IsThin(pIn->resourceType, pIn->swizzleMode))\n        {\n            UINT_32 blockOffset = 0;\n            UINT_32 log2BlkSize = GetBlockSizeLog2(pIn->swizzleMode);\n\n            if (IsZOrderSwizzle(pIn->swizzleMode))\n            {\n                // Morton generation\n                if ((log2ElementBytes == 0) || (log2ElementBytes == 2))\n                {\n                    UINT_32 totalLowBits = 6 - log2ElementBytes;\n                    UINT_32 mortBits = totalLowBits / 2;\n                    UINT_32 lowBitsValue = MortonGen2d(pIn->y, pIn->x, mortBits);\n                    // Are 9 bits enough?\n                    UINT_32 highBitsValue =\n                        MortonGen2d(pIn->x >> mortBits, pIn->y >> mortBits, 9) << totalLowBits;\n                    blockOffset = lowBitsValue | highBitsValue;\n                    ADDR_ASSERT(blockOffset == lowBitsValue + highBitsValue);\n                }\n                else\n                {\n                    blockOffset = MortonGen2d(pIn->y, pIn->x, 13);\n                }\n\n                // Fill LSBs with sample bits\n                if (pIn->numSamples > 1)\n                {\n                    blockOffset *= pIn->numSamples;\n                    blockOffset |= pIn->sample;\n                }\n\n                // Shift according to BytesPP\n                blockOffset <<= log2ElementBytes;\n            }\n            else\n            {\n                // Micro block offset\n                UINT_32 microBlockOffset = ComputeSurface2DMicroBlockOffset(pIn);\n                blockOffset = microBlockOffset;\n\n                // Micro block dimension\n                ADDR_ASSERT(log2ElementBytes < MaxNumOfBpp);\n                Dim2d microBlockDim = Block256_2d[log2ElementBytes];\n                // Morton generation, does 12 bit enough?\n                blockOffset |=\n                    MortonGen2d((pIn->x / microBlockDim.w), (pIn->y / microBlockDim.h), 12) << 8;\n\n                // Sample bits start location\n                UINT_32 sampleStart = log2BlkSize - Log2(pIn->numSamples);\n                // Join sample bits information to the highest Macro block bits\n                if (IsNonPrtXor(pIn->swizzleMode))\n                {\n                    // Non-prt-Xor : xor highest Macro block bits with sample bits\n                    blockOffset = blockOffset ^ (pIn->sample << sampleStart);\n                }\n                else\n                {\n                    // Non-Xor or prt-Xor: replace highest Macro block bits with sample bits\n                    // after this op, the blockOffset only contains log2 Macro block size bits\n                    blockOffset %= (1 << sampleStart);\n                    blockOffset |= (pIn->sample << sampleStart);\n                    ADDR_ASSERT((blockOffset >> log2BlkSize) == 0);\n                }\n            }\n\n            if (IsXor(pIn->swizzleMode))\n            {\n                // Mask off bits above Macro block bits to keep page synonyms working for prt\n                if (IsPrt(pIn->swizzleMode))\n                {\n                    blockOffset &= ((1 << log2BlkSize) - 1);\n                }\n\n                // Preserve offset inside pipe interleave\n                interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1);\n                blockOffset >>= m_pipeInterleaveLog2;\n\n                // Pipe/Se xor bits\n                pipeBits = GetPipeXorBits(log2BlkSize);\n                // Pipe xor\n                pipeXor = FoldXor2d(blockOffset, pipeBits);\n                blockOffset >>= pipeBits;\n\n                // Bank xor bits\n                bankBits = GetBankXorBits(log2BlkSize);\n                // Bank Xor\n                bankXor = FoldXor2d(blockOffset, bankBits);\n                blockOffset >>= bankBits;\n\n                // Put all the part back together\n                blockOffset <<= bankBits;\n                blockOffset |= bankXor;\n                blockOffset <<= pipeBits;\n                blockOffset |= pipeXor;\n                blockOffset <<= m_pipeInterleaveLog2;\n                blockOffset |= interleaveOffset;\n            }\n\n            ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset));\n            ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2BlkSize)));\n\n            blockOffset |= mipTailBytesOffset;\n\n            if (IsNonPrtXor(pIn->swizzleMode) && (pIn->numSamples <= 1))\n            {\n                // Apply slice xor if not MSAA/PRT\n                blockOffset ^= (ReverseBitVector(pIn->slice, pipeBits) << m_pipeInterleaveLog2);\n                blockOffset ^= (ReverseBitVector(pIn->slice >> pipeBits, bankBits) <<\n                                (m_pipeInterleaveLog2 + pipeBits));\n            }\n\n            returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor,\n                                                  bankBits, pipeBits, &blockOffset);\n\n            blockOffset %= (1 << log2BlkSize);\n\n            UINT_32 pitchInMacroBlock = localOut.mipChainPitch / localOut.blockWidth;\n            UINT_32 paddedHeightInMacroBlock = localOut.mipChainHeight / localOut.blockHeight;\n            UINT_32 sliceSizeInMacroBlock = pitchInMacroBlock * paddedHeightInMacroBlock;\n            UINT_64 macroBlockIndex =\n                (pIn->slice + mipStartPos.d) * sliceSizeInMacroBlock +\n                ((pIn->y / localOut.blockHeight) + mipStartPos.h) * pitchInMacroBlock +\n                ((pIn->x / localOut.blockWidth) + mipStartPos.w);\n\n            pOut->addr = blockOffset | (macroBlockIndex << log2BlkSize);\n        }\n        else\n        {\n            UINT_32 log2BlkSize = GetBlockSizeLog2(pIn->swizzleMode);\n\n            Dim3d microBlockDim = Block1K_3d[log2ElementBytes];\n\n            UINT_32 blockOffset = MortonGen3d((pIn->x / microBlockDim.w),\n                                              (pIn->y / microBlockDim.h),\n                                              (pIn->slice / microBlockDim.d),\n                                              8);\n\n            blockOffset <<= 10;\n            blockOffset |= ComputeSurface3DMicroBlockOffset(pIn);\n\n            if (IsXor(pIn->swizzleMode))\n            {\n                // Mask off bits above Macro block bits to keep page synonyms working for prt\n                if (IsPrt(pIn->swizzleMode))\n                {\n                    blockOffset &= ((1 << log2BlkSize) - 1);\n                }\n\n                // Preserve offset inside pipe interleave\n                interleaveOffset = blockOffset & ((1 << m_pipeInterleaveLog2) - 1);\n                blockOffset >>= m_pipeInterleaveLog2;\n\n                // Pipe/Se xor bits\n                pipeBits = GetPipeXorBits(log2BlkSize);\n                // Pipe xor\n                pipeXor = FoldXor3d(blockOffset, pipeBits);\n                blockOffset >>= pipeBits;\n\n                // Bank xor bits\n                bankBits = GetBankXorBits(log2BlkSize);\n                // Bank Xor\n                bankXor = FoldXor3d(blockOffset, bankBits);\n                blockOffset >>= bankBits;\n\n                // Put all the part back together\n                blockOffset <<= bankBits;\n                blockOffset |= bankXor;\n                blockOffset <<= pipeBits;\n                blockOffset |= pipeXor;\n                blockOffset <<= m_pipeInterleaveLog2;\n                blockOffset |= interleaveOffset;\n            }\n\n            ADDR_ASSERT((blockOffset | mipTailBytesOffset) == (blockOffset + mipTailBytesOffset));\n            ADDR_ASSERT((mipTailBytesOffset == 0u) || (blockOffset < (1u << log2BlkSize)));\n            blockOffset |= mipTailBytesOffset;\n\n            returnCode = ApplyCustomerPipeBankXor(pIn->swizzleMode, pIn->pipeBankXor,\n                                                  bankBits, pipeBits, &blockOffset);\n\n            blockOffset %= (1 << log2BlkSize);\n\n            UINT_32 xb = pIn->x / localOut.blockWidth  + mipStartPos.w;\n            UINT_32 yb = pIn->y / localOut.blockHeight + mipStartPos.h;\n            UINT_32 zb = pIn->slice / localOut.blockSlices + + mipStartPos.d;\n\n            UINT_32 pitchInBlock = localOut.mipChainPitch / localOut.blockWidth;\n            UINT_32 sliceSizeInBlock =\n                (localOut.mipChainHeight / localOut.blockHeight) * pitchInBlock;\n            UINT_64 blockIndex = zb * sliceSizeInBlock + yb * pitchInBlock + xb;\n\n            pOut->addr = blockOffset | (blockIndex << log2BlkSize);\n        }\n    }\n    else\n    {\n        returnCode = ADDR_INVALIDPARAMS;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::ComputeSurfaceInfoLinear\n*\n*   @brief\n*       Internal function to calculate padding for linear swizzle 2D/3D surface\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nADDR_E_RETURNCODE Gfx9Lib::ComputeSurfaceLinearPadding(\n    const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,                    ///< [in] input srtucture\n    UINT_32*                                pMipmap0PaddedWidth,    ///< [out] padded width in element\n    UINT_32*                                pSlice0PaddedHeight,    ///< [out] padded height for HW\n    ADDR2_MIP_INFO*                         pMipInfo                ///< [out] per mip information\n    ) const\n{\n    ADDR_E_RETURNCODE returnCode = ADDR_OK;\n\n    UINT_32 elementBytes        = pIn->bpp >> 3;\n    UINT_32 pitchAlignInElement = 0;\n\n    if (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL)\n    {\n        ADDR_ASSERT(pIn->numMipLevels <= 1);\n        ADDR_ASSERT(pIn->numSlices <= 1);\n        pitchAlignInElement = 1;\n    }\n    else\n    {\n        pitchAlignInElement = (256 / elementBytes);\n    }\n\n    UINT_32 mipChainWidth      = PowTwoAlign(pIn->width, pitchAlignInElement);\n    UINT_32 slice0PaddedHeight = pIn->height;\n\n    returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlignInElement,\n                                            &mipChainWidth, &slice0PaddedHeight);\n\n    if (returnCode == ADDR_OK)\n    {\n        UINT_32 mipChainHeight = 0;\n        UINT_32 mipHeight      = pIn->height;\n        UINT_32 mipDepth       = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? pIn->numSlices : 1;\n\n        for (UINT_32 i = 0; i < pIn->numMipLevels; i++)\n        {\n            if (pMipInfo != NULL)\n            {\n                pMipInfo[i].offset = mipChainWidth * mipChainHeight * elementBytes;\n                pMipInfo[i].pitch  = mipChainWidth;\n                pMipInfo[i].height = mipHeight;\n                pMipInfo[i].depth  = mipDepth;\n            }\n\n            mipChainHeight += mipHeight;\n            mipHeight = RoundHalf(mipHeight);\n            mipHeight = Max(mipHeight, 1u);\n        }\n\n        *pMipmap0PaddedWidth = mipChainWidth;\n        *pSlice0PaddedHeight = (pIn->numMipLevels > 1) ? mipChainHeight : slice0PaddedHeight;\n    }\n\n    return returnCode;\n}\n\n/**\n************************************************************************************************************************\n*   Gfx9Lib::ComputeThinBlockDimension\n*\n*   @brief\n*       Internal function to get thin block width/height/depth in element from surface input params.\n*\n*   @return\n*       N/A\n************************************************************************************************************************\n*/\nVOID Gfx9Lib::ComputeThinBlockDimension(\n    UINT_32*         pWidth,\n    UINT_32*         pHeight,\n    UINT_32*         pDepth,\n    UINT_32          bpp,\n    UINT_32          numSamples,\n    AddrResourceType resourceType,\n    AddrSwizzleMode  swizzleMode) const\n{\n    ADDR_ASSERT(IsThin(resourceType, swizzleMode));\n\n    const UINT_32 log2BlkSize              = GetBlockSizeLog2(swizzleMode);\n    const UINT_32 eleBytes                 = bpp >> 3;\n    const UINT_32 microBlockSizeTableIndex = Log2(eleBytes);\n    const UINT_32 log2blkSizeIn256B        = log2BlkSize - 8;\n    const UINT_32 widthAmp                 = log2blkSizeIn256B / 2;\n    const UINT_32 heightAmp                = log2blkSizeIn256B - widthAmp;\n\n    ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0]));\n\n    *pWidth  = (Block256_2d[microBlockSizeTableIndex].w << widthAmp);\n    *pHeight = (Block256_2d[microBlockSizeTableIndex].h << heightAmp);\n    *pDepth  = 1;\n\n    if (numSamples > 1)\n    {\n        const UINT_32 log2sample = Log2(numSamples);\n        const UINT_32 q          = log2sample >> 1;\n        const UINT_32 r          = log2sample & 1;\n\n        if (log2BlkSize & 1)\n        {\n            *pWidth  >>= q;\n            *pHeight >>= (q + r);\n        }\n        else\n        {\n            *pWidth  >>= (q + r);\n            *pHeight >>= q;\n        }\n    }\n}\n\n} // V2\n} // Addr\n} // namespace rocr"
  },
  {
    "path": "runtime/hsa-runtime/image/addrlib/src/gfx9/gfx9addrlib.h",
    "content": "/*\n************************************************************************************************************************\n*\n*  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.\n*  SPDX-License-Identifier: MIT\n*\n***********************************************************************************************************************/\n\n/**\n************************************************************************************************************************\n* @file  gfx9addrlib.h\n* @brief Contgfx9ns the Gfx9Lib class definition.\n************************************************************************************************************************\n*/\n\n#ifndef __GFX9_ADDR_LIB_H__\n#define __GFX9_ADDR_LIB_H__\n\n#include \"addrlib2.h\"\n#include \"coord.h\"\n\nnamespace rocr {\nnamespace Addr\n{\nnamespace V2\n{\n\n/**\n************************************************************************************************************************\n* @brief GFX9 specific settings structure.\n************************************************************************************************************************\n*/\nstruct Gfx9ChipSettings\n{\n    struct\n    {\n        // Asic/Generation name\n        UINT_32 isArcticIsland      : 1;\n        UINT_32 isVega10            : 1;\n        UINT_32 isRaven             : 1;\n        UINT_32 isVega12            : 1;\n        UINT_32 isVega20            : 1;\n        UINT_32 reserved0           : 27;\n\n        // Display engine IP version name\n        UINT_32 isDce12             : 1;\n        UINT_32 isDcn1              : 1;\n        UINT_32 isDcn2              : 1;\n        UINT_32 reserved1           : 29;\n\n        // Misc configuration bits\n        UINT_32 metaBaseAlignFix    : 1;\n        UINT_32 depthPipeXorDisable : 1;\n        UINT_32 htileAlignFix       : 1;\n        UINT_32 applyAliasFix       : 1;\n        UINT_32 htileCacheRbConflict: 1;\n        UINT_32 reserved2           : 27;\n    };\n};\n\n/**\n************************************************************************************************************************\n* @brief GFX9 data surface type.\n************************************************************************************************************************\n*/\nenum Gfx9DataType\n{\n    Gfx9DataColor,\n    Gfx9DataDepthStencil,\n    Gfx9DataFmask\n};\n\nconst UINT_32 Gfx9LinearSwModeMask = (1u << ADDR_SW_LINEAR);\n\nconst UINT_32 Gfx9Blk256BSwModeMask = (1u << ADDR_SW_256B_S) |\n                                      (1u << ADDR_SW_256B_D) |\n                                      (1u << ADDR_SW_256B_R);\n\nconst UINT_32 Gfx9Blk4KBSwModeMask = (1u << ADDR_SW_4KB_Z)   |\n                                     (1u << ADDR_SW_4KB_S)   |\n                                     (1u << ADDR_SW_4KB_D)   |\n                                     (1u << ADDR_SW_4KB_R)   |\n                                     (1u << ADDR_SW_4KB_Z_X) |\n                                     (1u << ADDR_SW_4KB_S_X) |\n                                     (1u << ADDR_SW_4KB_D_X) |\n                                     (1u << ADDR_SW_4KB_R_X);\n\nconst UINT_32 Gfx9Blk64KBSwModeMask = (1u << ADDR_SW_64KB_Z)   |\n                                      (1u << ADDR_SW_64KB_S)   |\n                                      (1u << ADDR_SW_64KB_D)   |\n                                      (1u << ADDR_SW_64KB_R)   |\n                                      (1u << ADDR_SW_64KB_Z_T) |\n                                      (1u << ADDR_SW_64KB_S_T) |\n                                      (1u << ADDR_SW_64KB_D_T) |\n                                      (1u << ADDR_SW_64KB_R_T) |\n                                      (1u << ADDR_SW_64KB_Z_X) |\n                                      (1u << ADDR_SW_64KB_S_X) |\n                                      (1u << ADDR_SW_64KB_D_X) |\n                                      (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx9ZSwModeMask = (1u << ADDR_SW_4KB_Z)    |\n                                (1u << ADDR_SW_64KB_Z)   |\n                                (1u << ADDR_SW_64KB_Z_T) |\n                                (1u << ADDR_SW_4KB_Z_X)  |\n                                (1u << ADDR_SW_64KB_Z_X);\n\nconst UINT_32 Gfx9StandardSwModeMask = (1u << ADDR_SW_256B_S)   |\n                                       (1u << ADDR_SW_4KB_S)    |\n                                       (1u << ADDR_SW_64KB_S)   |\n                                       (1u << ADDR_SW_64KB_S_T) |\n                                       (1u << ADDR_SW_4KB_S_X)  |\n                                       (1u << ADDR_SW_64KB_S_X);\n\nconst UINT_32 Gfx9DisplaySwModeMask = (1u << ADDR_SW_256B_D)   |\n                                      (1u << ADDR_SW_4KB_D)    |\n                                      (1u << ADDR_SW_64KB_D)   |\n                                      (1u << ADDR_SW_64KB_D_T) |\n                                      (1u << ADDR_SW_4KB_D_X)  |\n                                      (1u << ADDR_SW_64KB_D_X);\n\nconst UINT_32 Gfx9RotateSwModeMask = (1u << ADDR_SW_256B_R)   |\n                                     (1u << ADDR_SW_4KB_R)    |\n                                     (1u << ADDR_SW_64KB_R)   |\n                                     (1u << ADDR_SW_64KB_R_T) |\n                                     (1u << ADDR_SW_4KB_R_X)  |\n                                     (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx9XSwModeMask = (1u << ADDR_SW_4KB_Z_X)  |\n                                (1u << ADDR_SW_4KB_S_X)  |\n                                (1u << ADDR_SW_4KB_D_X)  |\n                                (1u << ADDR_SW_4KB_R_X)  |\n                                (1u << ADDR_SW_64KB_Z_X) |\n                                (1u << ADDR_SW_64KB_S_X) |\n                                (1u << ADDR_SW_64KB_D_X) |\n                                (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Gfx9TSwModeMask = (1u << ADDR_SW_64KB_Z_T) |\n                                (1u << ADDR_SW_64KB_S_T) |\n                                (1u << ADDR_SW_64KB_D_T) |\n                                (1u << ADDR_SW_64KB_R_T);\n\nconst UINT_32 Gfx9XorSwModeMask = Gfx9XSwModeMask |\n                                  Gfx9TSwModeMask;\n\nconst UINT_32 Gfx9AllSwModeMask = Gfx9LinearSwModeMask   |\n                                  Gfx9ZSwModeMask        |\n                                  Gfx9StandardSwModeMask |\n                                  Gfx9DisplaySwModeMask  |\n                                  Gfx9RotateSwModeMask;\n\nconst UINT_32 Gfx9Rsrc1dSwModeMask = Gfx9LinearSwModeMask;\n\nconst UINT_32 Gfx9Rsrc2dSwModeMask = Gfx9AllSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dSwModeMask = Gfx9AllSwModeMask & ~Gfx9Blk256BSwModeMask & ~Gfx9RotateSwModeMask;\n\nconst UINT_32 Gfx9Rsrc2dPrtSwModeMask = (Gfx9Blk4KBSwModeMask | Gfx9Blk64KBSwModeMask) & ~Gfx9XSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dPrtSwModeMask = Gfx9Rsrc2dPrtSwModeMask & ~Gfx9RotateSwModeMask & ~Gfx9DisplaySwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dThinSwModeMask = Gfx9DisplaySwModeMask & ~Gfx9Blk256BSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dThin4KBSwModeMask = Gfx9Rsrc3dThinSwModeMask & Gfx9Blk4KBSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dThin64KBSwModeMask = Gfx9Rsrc3dThinSwModeMask & Gfx9Blk64KBSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dThickSwModeMask = Gfx9Rsrc3dSwModeMask & ~(Gfx9Rsrc3dThinSwModeMask | Gfx9LinearSwModeMask);\n\nconst UINT_32 Gfx9Rsrc3dThick4KBSwModeMask = Gfx9Rsrc3dThickSwModeMask & Gfx9Blk4KBSwModeMask;\n\nconst UINT_32 Gfx9Rsrc3dThick64KBSwModeMask = Gfx9Rsrc3dThickSwModeMask & Gfx9Blk64KBSwModeMask;\n\nconst UINT_32 Gfx9MsaaSwModeMask = Gfx9AllSwModeMask & ~Gfx9Blk256BSwModeMask & ~Gfx9LinearSwModeMask;\n\nconst UINT_32 Dce12NonBpp32SwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                        (1u << ADDR_SW_4KB_D)    |\n                                        (1u << ADDR_SW_4KB_R)    |\n                                        (1u << ADDR_SW_64KB_D)   |\n                                        (1u << ADDR_SW_64KB_R)   |\n                                        (1u << ADDR_SW_4KB_D_X)  |\n                                        (1u << ADDR_SW_4KB_R_X)  |\n                                        (1u << ADDR_SW_64KB_D_X) |\n                                        (1u << ADDR_SW_64KB_R_X);\n\nconst UINT_32 Dce12Bpp32SwModeMask = (1u << ADDR_SW_256B_D) |\n                                     (1u << ADDR_SW_256B_R) |\n                                     Dce12NonBpp32SwModeMask;\n\nconst UINT_32 Dcn1NonBpp64SwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                       (1u << ADDR_SW_4KB_S)    |\n                                       (1u << ADDR_SW_64KB_S)   |\n                                       (1u << ADDR_SW_64KB_S_T) |\n                                       (1u << ADDR_SW_4KB_S_X)  |\n                                       (1u << ADDR_SW_64KB_S_X);\nconst UINT_32 Dcn1Bpp64SwModeMask = (1u << ADDR_SW_4KB_D)    |\n                                    (1u << ADDR_SW_64KB_D)   |\n                                    (1u << ADDR_SW_64KB_D_T) |\n                                    (1u << ADDR_SW_4KB_D_X)  |\n                                    (1u << ADDR_SW_64KB_D_X) |\n                                    Dcn1NonBpp64SwModeMask;\n\nconst UINT_32 Dcn2NonBpp64SwModeMask = (1u << ADDR_SW_LINEAR)   |\n                                       (1u << ADDR_SW_64KB_S)   |\n                                       (1u << ADDR_SW_64KB_S_T) |\n                                       (1u << ADDR_SW_64KB_S_X);\n\nconst UINT_32 Dcn2Bpp64SwModeMask = (1u << ADDR_SW_64KB_D)   |\n                                    (1u << ADDR_SW_64KB_D_T) |\n                                    (1u << ADDR_SW_64KB_D_X) |\n                                    Dcn2NonBpp64SwModeMask;\n\n/**\n************************************************************************************************************************\n* @brief GFX9 meta equation parameters\n************************************************************************************************************************\n*/\nstruct MetaEqParams\n{\n    UINT_32          maxMip;\n    UINT_32          elementBytesLog2;\n    UINT_32          numSamplesLog2;\n    ADDR2_META_FLAGS metaFlag;\n    Gfx9DataType     dataSurfaceType;\n    AddrSwizzleMode  swizzleMode;\n    AddrResourceType resourceType;\n    UINT_32          metaBlkWidthLog2;\n    UINT_32          metaBlkHeightLog2;\n    UINT_32          metaBlkDepthLog2;\n    UINT_32          compBlkWidthLog2;\n    UINT_32          compBlkHeightLog2;\n    UINT_32          compBlkDepthLog2;\n};\n\n/**\n************************************************************************************************************************\n* @brief This class is the GFX9 specific address library\n*        function set.\n************************************************************************************************************************\n*/\nclass Gfx9Lib : public Lib\n{\npublic:\n    /// Creates Gfx9Lib object\n    static Addr::Lib* CreateObj(const Client* pClient)\n    {\n        VOID* pMem = Object::ClientAlloc(sizeof(Gfx9Lib), pClient);\n        return (pMem != NULL) ? new (pMem) Gfx9Lib(pClient) : NULL;\n    }\n\nprotected:\n    Gfx9Lib(const Client* pClient);\n    virtual ~Gfx9Lib();\n\n    virtual BOOL_32 HwlIsStandardSwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return m_swizzleModeTable[swizzleMode].isStd ||\n               (IsTex3d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp);\n    }\n\n    virtual BOOL_32 HwlIsDisplaySwizzle(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return IsTex2d(resourceType) && m_swizzleModeTable[swizzleMode].isDisp;\n    }\n\n    virtual BOOL_32 HwlIsThin(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return ((IsTex2d(resourceType)  == TRUE) ||\n                ((IsTex3d(resourceType) == TRUE)                  &&\n                 (m_swizzleModeTable[swizzleMode].isZ   == FALSE) &&\n                 (m_swizzleModeTable[swizzleMode].isStd == FALSE)));\n    }\n\n    virtual BOOL_32 HwlIsThick(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const\n    {\n        return (IsTex3d(resourceType) &&\n                (m_swizzleModeTable[swizzleMode].isZ || m_swizzleModeTable[swizzleMode].isStd));\n    }\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileInfo(\n        const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskInfo(\n        const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeDccInfo(\n        const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,\n        ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeCmaskAddrFromCoord(\n        const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileAddrFromCoord(\n        const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlComputeHtileCoordFromAddr(\n        const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,\n        ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut);\n\n    virtual ADDR_E_RETURNCODE HwlSupportComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn);\n\n    virtual VOID HwlComputeDccAddrFromCoord(\n        const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut);\n\n    virtual UINT_32 HwlGetEquationIndex(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeBlock256Equation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeThinEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeThickEquation(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2,\n        ADDR_EQUATION* pEquation) const;\n\n    // Get equation table pointer and number of equations\n    virtual UINT_32 HwlGetEquationTableInfo(const ADDR_EQUATION** ppEquationTable) const\n    {\n        *ppEquationTable = m_equationTable;\n\n        return m_numEquations;\n    }\n\n    virtual BOOL_32 IsEquationSupported(\n        AddrResourceType rsrcType,\n        AddrSwizzleMode swMode,\n        UINT_32 elementBytesLog2) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputePipeBankXor(\n        const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor(\n        const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,\n        ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSubResourceOffsetForSwizzlePattern(\n        const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,\n        ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlGetPreferredSurfaceSetting(\n        const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,\n        ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoSanityCheck(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoTiled(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfoLinear(\n         const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut) const;\n\n    virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled(\n        const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut) const;\n\n    virtual UINT_32 HwlComputeMaxBaseAlignments() const;\n\n    virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const;\n\n    virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn);\n\n    virtual ChipFamily HwlConvertChipFamily(UINT_32 uChipFamily, UINT_32 uChipRevision);\n\n    virtual VOID ComputeThinBlockDimension(\n        UINT_32*         pWidth,\n        UINT_32*         pHeight,\n        UINT_32*         pDepth,\n        UINT_32          bpp,\n        UINT_32          numSamples,\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode) const;\n\nprivate:\n    VOID GetRbEquation(CoordEq* pRbEq, UINT_32 rbPerSeLog2, UINT_32 seLog2) const;\n\n    VOID GetDataEquation(CoordEq* pDataEq, Gfx9DataType dataSurfaceType,\n                         AddrSwizzleMode swizzleMode, AddrResourceType resourceType,\n                         UINT_32 elementBytesLog2, UINT_32 numSamplesLog2) const;\n\n    VOID GetPipeEquation(CoordEq* pPipeEq, CoordEq* pDataEq,\n                         UINT_32 pipeInterleaveLog2, UINT_32 numPipesLog2,\n                         UINT_32 numSamplesLog2, Gfx9DataType dataSurfaceType,\n                         AddrSwizzleMode swizzleMode, AddrResourceType resourceType) const;\n\n    VOID GenMetaEquation(CoordEq* pMetaEq, UINT_32 maxMip,\n                         UINT_32 elementBytesLog2, UINT_32 numSamplesLog2,\n                         ADDR2_META_FLAGS metaFlag, Gfx9DataType dataSurfaceType,\n                         AddrSwizzleMode swizzleMode, AddrResourceType resourceType,\n                         UINT_32 metaBlkWidthLog2, UINT_32 metaBlkHeightLog2,\n                         UINT_32 metaBlkDepthLog2, UINT_32 compBlkWidthLog2,\n                         UINT_32 compBlkHeightLog2, UINT_32 compBlkDepthLog2) const;\n\n    const CoordEq* GetMetaEquation(const MetaEqParams& metaEqParams);\n\n    VOID GetMetaMipInfo(UINT_32 numMipLevels, Dim3d* pMetaBlkDim,\n                        BOOL_32 dataThick, ADDR2_META_MIP_INFO* pInfo,\n                        UINT_32 mip0Width, UINT_32 mip0Height, UINT_32 mip0Depth,\n                        UINT_32* pNumMetaBlkX, UINT_32* pNumMetaBlkY, UINT_32* pNumMetaBlkZ) const;\n\n    BOOL_32 IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    ADDR_E_RETURNCODE ComputeSurfaceLinearPadding(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        UINT_32*                                pMipmap0PaddedWidth,\n        UINT_32*                                pSlice0PaddedHeight,\n        ADDR2_MIP_INFO*                         pMipInfo = NULL) const;\n\n    static ADDR2_BLOCK_SET GetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet, AddrResourceType rsrcType)\n    {\n        ADDR2_BLOCK_SET allowedBlockSet = {};\n\n        allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx9Blk256BSwModeMask) ? TRUE : FALSE;\n        allowedBlockSet.linear = (allowedSwModeSet.value & Gfx9LinearSwModeMask)  ? TRUE : FALSE;\n\n        if (rsrcType == ADDR_RSRC_TEX_3D)\n        {\n            allowedBlockSet.macroThin4KB   = (allowedSwModeSet.value & Gfx9Rsrc3dThin4KBSwModeMask)   ? TRUE : FALSE;\n            allowedBlockSet.macroThick4KB  = (allowedSwModeSet.value & Gfx9Rsrc3dThick4KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThin64KB  = (allowedSwModeSet.value & Gfx9Rsrc3dThin64KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThick64KB = (allowedSwModeSet.value & Gfx9Rsrc3dThick64KBSwModeMask) ? TRUE : FALSE;\n        }\n        else\n        {\n            allowedBlockSet.macroThin4KB  = (allowedSwModeSet.value & Gfx9Blk4KBSwModeMask)  ? TRUE : FALSE;\n            allowedBlockSet.macroThin64KB = (allowedSwModeSet.value & Gfx9Blk64KBSwModeMask) ? TRUE : FALSE;\n        }\n\n        return allowedBlockSet;\n    }\n\n    static ADDR2_SWTYPE_SET GetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet)\n    {\n        ADDR2_SWTYPE_SET allowedSwSet = {};\n\n        allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx9ZSwModeMask)        ? TRUE : FALSE;\n        allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx9StandardSwModeMask) ? TRUE : FALSE;\n        allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx9DisplaySwModeMask)  ? TRUE : FALSE;\n        allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx9RotateSwModeMask)   ? TRUE : FALSE;\n\n        return allowedSwSet;\n    }\n\n    BOOL_32 IsInMipTail(\n        AddrResourceType  resourceType,\n        AddrSwizzleMode   swizzleMode,\n        Dim3d             mipTailDim,\n        UINT_32           width,\n        UINT_32           height,\n        UINT_32           depth) const\n    {\n        BOOL_32 inTail = ((width <= mipTailDim.w) &&\n                          (height <= mipTailDim.h) &&\n                          (IsThin(resourceType, swizzleMode) || (depth <= mipTailDim.d)));\n\n        return inTail;\n    }\n\n    BOOL_32 ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n    BOOL_32 ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const;\n\n    UINT_32 GetBankXorBits(UINT_32 macroBlockBits) const\n    {\n        UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);\n\n        // Bank xor bits\n        UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);\n\n        return bankBits;\n    }\n\n    UINT_32 ComputeSurfaceBaseAlignTiled(AddrSwizzleMode swizzleMode) const\n    {\n        UINT_32 baseAlign;\n\n        if (IsXor(swizzleMode))\n        {\n            baseAlign = GetBlockSize(swizzleMode);\n        }\n        else\n        {\n            baseAlign = 256;\n        }\n\n        return baseAlign;\n    }\n\n    // Initialize equation table\n    VOID InitEquationTable();\n\n    ADDR_E_RETURNCODE ComputeStereoInfo(\n        const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,\n        ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut,\n        UINT_32*                                pHeightAlign) const;\n\n    UINT_32 GetMipChainInfo(\n        AddrResourceType  resourceType,\n        AddrSwizzleMode   swizzleMode,\n        UINT_32           bpp,\n        UINT_32           mip0Width,\n        UINT_32           mip0Height,\n        UINT_32           mip0Depth,\n        UINT_32           blockWidth,\n        UINT_32           blockHeight,\n        UINT_32           blockDepth,\n        UINT_32           numMipLevel,\n        ADDR2_MIP_INFO*   pMipInfo) const;\n\n    VOID GetMetaMiptailInfo(\n        ADDR2_META_MIP_INFO*    pInfo,\n        Dim3d                   mipCoord,\n        UINT_32                 numMipInTail,\n        Dim3d*                  pMetaBlkDim) const;\n\n    Dim3d GetMipStartPos(\n        AddrResourceType  resourceType,\n        AddrSwizzleMode   swizzleMode,\n        UINT_32           width,\n        UINT_32           height,\n        UINT_32           depth,\n        UINT_32           blockWidth,\n        UINT_32           blockHeight,\n        UINT_32           blockDepth,\n        UINT_32           mipId,\n        UINT_32           log2ElementBytes,\n        UINT_32*          pMipTailBytesOffset) const;\n\n    AddrMajorMode GetMajorMode(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          mip0WidthInBlk,\n        UINT_32          mip0HeightInBlk,\n        UINT_32          mip0DepthInBlk) const\n    {\n        BOOL_32 yMajor = (mip0WidthInBlk < mip0HeightInBlk);\n        BOOL_32 xMajor = (yMajor == FALSE);\n\n        if (IsThick(resourceType, swizzleMode))\n        {\n            yMajor = yMajor && (mip0HeightInBlk >= mip0DepthInBlk);\n            xMajor = xMajor && (mip0WidthInBlk >= mip0DepthInBlk);\n        }\n\n        AddrMajorMode majorMode;\n        if (xMajor)\n        {\n            majorMode = ADDR_MAJOR_X;\n        }\n        else if (yMajor)\n        {\n            majorMode = ADDR_MAJOR_Y;\n        }\n        else\n        {\n            majorMode = ADDR_MAJOR_Z;\n        }\n\n        return majorMode;\n    }\n\n    Dim3d GetDccCompressBlk(\n        AddrResourceType resourceType,\n        AddrSwizzleMode  swizzleMode,\n        UINT_32          bpp) const\n    {\n        UINT_32 index = Log2(bpp >> 3);\n        Dim3d   compressBlkDim;\n\n        if (IsThin(resourceType, swizzleMode))\n        {\n            compressBlkDim.w = Block256_2d[index].w;\n            compressBlkDim.h = Block256_2d[index].h;\n            compressBlkDim.d = 1;\n        }\n        else if (IsStandardSwizzle(resourceType, swizzleMode))\n        {\n            compressBlkDim = Block256_3dS[index];\n        }\n        else\n        {\n            compressBlkDim = Block256_3dZ[index];\n        }\n\n        return compressBlkDim;\n    }\n\n    static const UINT_32 MaxSeLog2      = 3;\n    static const UINT_32 MaxRbPerSeLog2 = 2;\n\n    static const Dim3d   Block256_3dS[MaxNumOfBpp];\n    static const Dim3d   Block256_3dZ[MaxNumOfBpp];\n\n    static const UINT_32 MipTailOffset256B[];\n\n    static const SwizzleModeFlags SwizzleModeTable[ADDR_SW_MAX_TYPE];\n\n    static const UINT_32 MaxCachedMetaEq = 2;\n\n    Gfx9ChipSettings m_settings;\n\n    CoordEq      m_cachedMetaEq[MaxCachedMetaEq];\n    MetaEqParams m_cachedMetaEqKey[MaxCachedMetaEq];\n    UINT_32      m_metaEqOverrideIndex;\n};\n\n} // V2\n} // Addr\n} // namespace rocr\n#endif\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_kernel.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"blit_kernel.h\"\n\n#if (defined(WIN32) || defined(_WIN32))\n#define NOMINMAX\n#endif\n\n#include <algorithm>\n#include <atomic>\n#include <sstream>\n#include <string>\n\n#include \"image_manager.h\"\n#include \"image_runtime.h\"\n#include \"util.h\"\n\n#undef HSA_ARGUMENT_ALIGN_BYTES\n#define HSA_ARGUMENT_ALIGN_BYTES 16\n\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"core/inc/hsa_table_interface.h\"\n\nnamespace rocr {\nnamespace image {\n\nextern uint8_t blit_object_gfx7xx[14608];\nextern uint8_t blit_object_gfx8xx[15424];\nextern uint8_t blit_object_gfx9xx[15432];\n\nextern uint8_t ocl_blit_object_gfx700[];\nextern uint8_t ocl_blit_object_gfx701[];\nextern uint8_t ocl_blit_object_gfx702[];\nextern uint8_t ocl_blit_object_gfx801[];\nextern uint8_t ocl_blit_object_gfx802[];\nextern uint8_t ocl_blit_object_gfx803[];\nextern uint8_t ocl_blit_object_gfx805[];\nextern uint8_t ocl_blit_object_gfx810[];\nextern uint8_t ocl_blit_object_gfx900[];\nextern uint8_t ocl_blit_object_gfx902[];\nextern uint8_t ocl_blit_object_gfx904[];\nextern uint8_t ocl_blit_object_gfx906[];\nextern uint8_t ocl_blit_object_gfx908[];\nextern uint8_t ocl_blit_object_gfx909[];\nextern uint8_t ocl_blit_object_gfx90a[];\nextern uint8_t ocl_blit_object_gfx90c[];\nextern uint8_t ocl_blit_object_gfx942[];\nextern uint8_t ocl_blit_object_gfx950[];\nextern uint8_t ocl_blit_object_gfx1010[];\nextern uint8_t ocl_blit_object_gfx1011[];\nextern uint8_t ocl_blit_object_gfx1012[];\nextern uint8_t ocl_blit_object_gfx1013[];\nextern uint8_t ocl_blit_object_gfx1030[];\nextern uint8_t ocl_blit_object_gfx1031[];\nextern uint8_t ocl_blit_object_gfx1032[];\nextern uint8_t ocl_blit_object_gfx1033[];\nextern uint8_t ocl_blit_object_gfx1034[];\nextern uint8_t ocl_blit_object_gfx1035[];\nextern uint8_t ocl_blit_object_gfx1036[];\nextern uint8_t ocl_blit_object_gfx1100[];\nextern uint8_t ocl_blit_object_gfx1101[];\nextern uint8_t ocl_blit_object_gfx1102[];\nextern uint8_t ocl_blit_object_gfx1103[];\nextern uint8_t ocl_blit_object_gfx1150[];\nextern uint8_t ocl_blit_object_gfx1151[];\nextern uint8_t ocl_blit_object_gfx1152[];\nextern uint8_t ocl_blit_object_gfx1153[];\nextern uint8_t ocl_blit_object_gfx1200[];\nextern uint8_t ocl_blit_object_gfx1201[];\n\n// Arguments inserted by OCL compiler, all zero here.\nstruct OCLHiddenArgs {\n  uint64_t offset_x;\n  uint64_t offset_y;\n  uint64_t offset_z;\n  void* printf_buffer;\n  void* enqueue;\n  void* enqueue2;\n  void* multi_grid;\n};\n\nstatic void* Allocate(hsa_agent_t agent, size_t size) {\n  //use the host accessible kernarg pool\n  hsa_amd_memory_pool_t pool = ImageRuntime::instance()->kernarg_pool();\n\n  void* ptr = NULL;\n\n  hsa_status_t status = AMD::hsa_amd_memory_pool_allocate(pool, size, 0, &ptr);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  if (status != HSA_STATUS_SUCCESS) return NULL;\n\n  status = AMD::hsa_amd_agents_allow_access(1, &agent, NULL, ptr);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  if (status != HSA_STATUS_SUCCESS) {\n    AMD::hsa_amd_memory_pool_free(ptr);\n    return NULL;\n  }\n  return ptr;\n}\n\nBlitKernel::BlitKernel() {\n}\n\nBlitKernel::~BlitKernel() {}\n\nhsa_status_t BlitKernel::Initialize() { return HSA_STATUS_SUCCESS; }\n\nhsa_status_t BlitKernel::Cleanup() {\n\n  for (std::pair<const uint64_t, hsa_executable_t> pair :\n       code_executable_map_) {\n    HSA::hsa_executable_destroy(pair.second);\n  }\n\n  code_executable_map_.clear();\n\n  code_object_map_.clear();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::BuildBlitCode(\n    hsa_agent_t agent, std::vector<BlitCodeInfo>& blit_code_catalog) {\n  // Find existing kernels in the list that have compatible ISA.\n  hsa_isa_t agent_isa = {0};\n  hsa_status_t status = HSA::hsa_agent_get_info(agent, HSA_AGENT_INFO_ISA, &agent_isa);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  std::lock_guard<std::mutex> lock(lock_);\n\n  for (std::pair<uint64_t, hsa_executable_t> pair : code_executable_map_) {\n    bool isa_compatible = false;\n    hsa_isa_t code_isa = {pair.first};\n\n    status = HSA::hsa_isa_compatible(code_isa, agent_isa, &isa_compatible);\n    if (HSA_STATUS_SUCCESS != status) {\n      return status;\n    }\n\n    if (isa_compatible) {\n      return PopulateKernelCode(agent, pair.second, blit_code_catalog);\n    }\n  }\n\n  // No existing compatible kernels. Build new kernels.\n  hsa_code_object_t code_object = {0};\n\n  // Get the target name\n  char agent_name[64] = {0};\n  status = HSA::hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, &agent_name);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  // Get the patched code object\n  uint8_t* patched_code_object;\n  status = BlitKernel::GetPatchedBlitObject(agent_name, &patched_code_object);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  // Pass the patched code object\n  code_object.handle = reinterpret_cast<uint64_t>(patched_code_object);\n\n  code_object_map_[agent_isa.handle] = code_object;\n\n  // Create executable.\n  hsa_executable_t executable = {0};\n  status =\n      HSA::hsa_executable_create(HSA_PROFILE_FULL, HSA_EXECUTABLE_STATE_UNFROZEN, \"\", &executable);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  code_executable_map_[agent_isa.handle] = executable;\n\n  // Load code object.\n  status = HSA::hsa_executable_load_code_object(executable, agent, code_object, \"\");\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  // Freeze executable.\n  status = HSA::hsa_executable_freeze(executable, \"\");\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  return PopulateKernelCode(agent, executable, blit_code_catalog);\n}\n\nhsa_status_t BlitKernel::CopyBufferToImage(\n    BlitQueue& blit_queue, const std::vector<BlitCodeInfo>& blit_code_catalog,\n    const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n    const Image& dst_image, const hsa_ext_image_region_t& image_region) {\n  if (dst_image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    ImageManager* manager = ImageRuntime::instance()->image_manager(dst_image.component);\n\n    const uint32_t element_size =\n        manager->GetImageProperty(dst_image.component, dst_image.desc.format,\n                                  dst_image.desc.geometry).element_size;\n\n    const size_t dst_origin = image_region.offset.x * element_size;\n    char* dst_memory = reinterpret_cast<char*>(dst_image.data) + dst_origin;\n    const size_t size = image_region.range.x * element_size;\n\n    return HSA::hsa_memory_copy(dst_memory, src_memory, size);\n  }\n\n  const Image* dst_image_view = NULL;\n\n  hsa_status_t status = ConvertImage(dst_image, &dst_image_view);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  assert(dst_image_view != NULL);\n\n  hsa_kernel_dispatch_packet_t packet = { };\n\n  const BlitCodeInfo& blit_code =\n      blit_code_catalog.at(KERNEL_OP_COPY_BUFFER_TO_IMAGE);\n  packet.kernel_object = blit_code.code_handle_;\n  packet.group_segment_size = blit_code.group_segment_size_;\n  packet.private_segment_size = blit_code.private_segment_size_;\n\n  // Setup kernel argument.\n  /*\n  buffer is start of output pixel in destination buffer\n  format.x is element count\n  format.y is element size\n  format.z is max(dword per pixel, 1)\n  format.w is texture type.\n  pixelOrigin is start pixel address.\n  */\n  struct KernelArgs {\n    const void* buffer;\n    uint64_t image[5];\n    int32_t pixelOrigin[4];\n    uint32_t format[4];\n    uint64_t pitch;\n    uint64_t slice_pitch;\n    OCLHiddenArgs ocl;\n  };\n\n  KernelArgs* args = (KernelArgs*)Allocate(dst_image_view->component, sizeof(KernelArgs));\n  assert(args != NULL);\n  memset(args, 0, sizeof(KernelArgs));\n  args->buffer = src_memory;\n  for(auto& img : args->image)\n    img = dst_image_view->Convert();\n  args->pixelOrigin[0] = image_region.offset.x;\n  args->pixelOrigin[1] = image_region.offset.y;\n  args->pixelOrigin[2] = image_region.offset.z;\n\n  ImageManager* manager = ImageRuntime::instance()->image_manager(dst_image_view->component);\n\n  const uint32_t element_size =\n      manager->GetImageProperty(dst_image_view->component,\n                                dst_image_view->desc.format,\n                                dst_image_view->desc.geometry).element_size;\n\n  // Try to minimize the read operation to buffer by reading the buffer\n  // up to one DWORD at a time.\n  uint32_t buffer_read_count = element_size / sizeof(uint32_t);\n  buffer_read_count = (buffer_read_count == 0) ? 1 : buffer_read_count;\n\n  const uint32_t num_channel = GetNumChannel(*dst_image_view);\n  const uint32_t size_per_channel = element_size / num_channel;\n\n  args->format[0] = num_channel;\n  args->format[1] = size_per_channel;\n  args->format[2] = buffer_read_count;\n  args->format[3] = dst_image_view->desc.geometry;\n\n  unsigned long buffer_pitch[2] = {0, 0};\n  CalcBufferRowSlicePitchesInPixel(dst_image_view->desc.geometry, element_size,\n                                   image_region.range, src_row_pitch,\n                                   src_slice_pitch, buffer_pitch);\n\n  args->pitch = buffer_pitch[0];\n  args->slice_pitch = buffer_pitch[1];\n\n  packet.kernarg_address = args;\n\n  // Setup packet dimension and working size.\n  CalcWorkingSize(*dst_image_view, image_region.range, packet);\n\n  status = LaunchKernel(blit_queue, packet);\n\n  if (&dst_image != dst_image_view) {\n    Image::Destroy(dst_image_view);\n  }\n  AMD::hsa_amd_memory_pool_free(args);\n\n  return status;\n}\n\nhsa_status_t BlitKernel::CopyImageToBuffer(\n    BlitQueue& blit_queue, const std::vector<BlitCodeInfo>& blit_code_catalog,\n    const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n    size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region) {\n  if (src_image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    ImageManager* manager = ImageRuntime::instance()->image_manager(src_image.component);\n\n    const uint32_t element_size =\n        manager->GetImageProperty(src_image.component, src_image.desc.format,\n                                  src_image.desc.geometry).element_size;\n\n    const size_t src_origin = image_region.offset.x * element_size;\n    const char* src_memory =\n        reinterpret_cast<const char*>(src_image.data) + src_origin;\n    const size_t size = image_region.range.x * element_size;\n\n    return HSA::hsa_memory_copy(dst_memory, src_memory, size);\n  }\n\n  const Image* src_image_view = NULL;\n\n  hsa_status_t status = ConvertImage(src_image, &src_image_view);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n\n  assert(src_image_view != NULL);\n\n  hsa_kernel_dispatch_packet_t packet = { };\n\n  const BlitCodeInfo& blit_code =\n      blit_code_catalog.at(KERNEL_OP_COPY_IMAGE_TO_BUFFER);\n  packet.kernel_object = blit_code.code_handle_;\n  packet.group_segment_size = blit_code.group_segment_size_;\n  packet.private_segment_size = blit_code.private_segment_size_;\n\n  // Setup kernel argument.\n  /*\n  buffer is start of output pixel in destination buffer\n  format.x is element count\n  format.y is element size\n  format.z is max(dword per pixel, 1)\n  format.w is texture type.\n  pixelOrigin is start pixel address.\n  */\n  struct KernelArgs {\n    uint64_t image[5];\n    void* buffer;\n    int32_t pixelOrigin[4];\n    uint32_t format[4];\n    uint64_t pitch;\n    uint64_t slice_pitch;\n    OCLHiddenArgs ocl;\n  };\n\n  KernelArgs* args = (KernelArgs*)Allocate(src_image_view->component, sizeof(KernelArgs));\n  assert(args != NULL);\n  memset(args, 0, sizeof(KernelArgs));\n  for(auto &img : args->image)\n    img = src_image_view->Convert();\n  args->buffer = dst_memory;\n  args->pixelOrigin[0] = image_region.offset.x;\n  args->pixelOrigin[1] = image_region.offset.y;\n  args->pixelOrigin[2] = image_region.offset.z;\n\n  ImageManager* manager = ImageRuntime::instance()->image_manager(src_image_view->component);\n\n  const uint32_t element_size =\n      manager->GetImageProperty(src_image_view->component,\n                                src_image_view->desc.format,\n                                src_image_view->desc.geometry).element_size;\n\n  // Try to minimize the write operation to buffer by reading the buffer\n  // up to one DWORD at a time.\n  uint32_t buffer_write_count = element_size / sizeof(uint32_t);\n  buffer_write_count = (buffer_write_count == 0) ? 1 : buffer_write_count;\n\n  const uint32_t num_channel = GetNumChannel(*src_image_view);\n  const uint32_t size_per_channel = element_size / num_channel;\n\n  args->format[0] = num_channel;\n  args->format[1] = size_per_channel;\n  args->format[2] = buffer_write_count;\n  args->format[3] = src_image_view->desc.geometry;\n\n  unsigned long buffer_pitch[2] = {0, 0};\n  CalcBufferRowSlicePitchesInPixel(src_image_view->desc.geometry, element_size,\n                                   image_region.range, dst_row_pitch,\n                                   dst_slice_pitch, buffer_pitch);\n\n  args->pitch = buffer_pitch[0];\n  args->slice_pitch = buffer_pitch[1];\n\n  packet.kernarg_address = args;\n\n  // Setup packet dimension and working size.\n  CalcWorkingSize(*src_image_view, image_region.range, packet);\n\n  status = LaunchKernel(blit_queue, packet);\n\n  if (&src_image != src_image_view) {\n    Image::Destroy(src_image_view);\n  }\n  AMD::hsa_amd_memory_pool_free(args);\n\n  return status;\n}\n\nhsa_status_t BlitKernel::CopyImage(\n    BlitQueue& blit_queue, const std::vector<BlitCodeInfo>& blit_code_catalog,\n    const Image& dst_image, const Image& src_image,\n    const hsa_dim3_t& dst_origin, const hsa_dim3_t& src_origin,\n    const hsa_dim3_t size, KernelOp copy_type) {\n  assert(src_image.component.handle == dst_image.component.handle);\n\n  const Image* src_image_view = &src_image;\n  const Image* dst_image_view = &dst_image;\n  const BlitCodeInfo* blit_code = NULL;\n\n  if (copy_type == KERNEL_OP_COPY_IMAGE_DEFAULT) {\n    // Linear to linear image copy.\n\n    hsa_status_t status = ConvertImage(src_image, &src_image_view);\n    if (HSA_STATUS_SUCCESS != status) {\n      return status;\n    }\n\n    assert(src_image_view != NULL);\n\n    status = ConvertImage(dst_image, &dst_image_view);\n    if (HSA_STATUS_SUCCESS != status) {\n      return status;\n    }\n\n    assert(dst_image_view != NULL);\n\n    const hsa_ext_image_geometry_t src_geometry = src_image_view->desc.geometry;\n    const hsa_ext_image_geometry_t dst_geometry = dst_image_view->desc.geometry;\n\n    if (src_geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n        dst_geometry != HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      blit_code = &blit_code_catalog.at(KERNEL_OP_COPY_IMAGE_DEFAULT);\n    } else if (src_geometry == HSA_EXT_IMAGE_GEOMETRY_1DB &&\n               dst_geometry != HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      blit_code = &blit_code_catalog.at(KERNEL_OP_COPY_IMAGE_1DB_TO_REG);\n    } else if (src_geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n               dst_geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      blit_code = &blit_code_catalog.at(KERNEL_OP_COPY_IMAGE_REG_TO_1DB);\n    } else {\n      blit_code = &blit_code_catalog.at(KERNEL_OP_COPY_IMAGE_1DB);\n    }\n  } else {\n    blit_code = &blit_code_catalog.at(copy_type);\n  }\n\n  hsa_kernel_dispatch_packet_t packet = { };\n\n  packet.kernel_object = blit_code->code_handle_;\n  packet.group_segment_size = blit_code->group_segment_size_;\n  packet.private_segment_size = blit_code->private_segment_size_;\n\n  // Setup kernel argument.\n  struct KernelArgs {\n    uint64_t src[5];\n    uint64_t dst[5];\n    int32_t srcOrigin[4];\n    int32_t dstOrigin[4];\n    int32_t srcFormat;\n    int32_t dstFormat;\n    OCLHiddenArgs ocl;\n  };\n\n  KernelArgs* args = (KernelArgs*)Allocate(dst_image_view->component, sizeof(KernelArgs));\n  assert(args != NULL);\n  memset(args, 0, sizeof(KernelArgs));\n\n  for(auto& img : args->src)\n    img = src_image_view->Convert();\n  args->srcFormat = src_image_view->desc.geometry;\n  args->srcOrigin[0] = src_origin.x;\n  args->srcOrigin[1] = src_origin.y;\n  args->srcOrigin[2] = src_origin.z;\n\n  for(auto& img : args->dst)\n    img = dst_image_view->Convert();\n  args->dstFormat = dst_image_view->desc.geometry;\n  args->dstOrigin[0] = dst_origin.x;\n  args->dstOrigin[1] = dst_origin.y;\n  args->dstOrigin[2] = dst_origin.z;\n\n  packet.kernarg_address = args;\n\n  // Setup packet dimension and working size.\n  CalcWorkingSize(*src_image_view, *dst_image_view, size, packet);\n\n  hsa_status_t status = LaunchKernel(blit_queue, packet);\n\n  if (&src_image != src_image_view) {\n    Image::Destroy(src_image_view);\n  }\n\n  if (&dst_image != dst_image_view) {\n    Image::Destroy(dst_image_view);\n  }\n\n  AMD::hsa_amd_memory_pool_free(args);\n\n  return status;\n}\n\nhsa_status_t BlitKernel::FillImage(\n    BlitQueue& blit_queue, const std::vector<BlitCodeInfo>& blit_code_catalog,\n    const Image& image, const void* pattern,\n    const hsa_ext_image_region_t& region) {\n  hsa_kernel_dispatch_packet_t packet = { };\n\n  const BlitCodeInfo& blit_code =\n      (image.desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)\n          ? blit_code_catalog.at(KERNEL_OP_CLEAR_IMAGE)\n          : blit_code_catalog.at(KERNEL_OP_CLEAR_IMAGE_1DB);\n  packet.kernel_object = blit_code.code_handle_;\n  packet.group_segment_size = blit_code.group_segment_size_;\n  packet.private_segment_size = blit_code.private_segment_size_;\n\n  // Setup kernel argument.\n  struct KernelArgs {\n    uint64_t image[5];\n    int32_t format;\n    uint32_t type;\n    uint32_t data[4];\n    int32_t origin[4];\n    OCLHiddenArgs ocl;\n  };\n\n  KernelArgs* args = (KernelArgs*)Allocate(image.component, sizeof(KernelArgs));\n  assert(args != NULL);\n  memset(args, 0, sizeof(KernelArgs));\n\n  for(auto &img : args->image)\n    img = image.Convert();\n  args->format = image.desc.geometry;\n  for(int i=0; i<4; i++)\n    args->data[i] = ((const uint32_t*)pattern)[i];\n  args->origin[0] = region.offset.x;\n  args->origin[1] = region.offset.y;\n  args->origin[2] = region.offset.z;\n  args->type = GetImageAccessType(image);\n\n  packet.kernarg_address = args;\n\n  // Setup packet dimension and working size.\n  CalcWorkingSize(image, region.range, packet);\n\n  hsa_status_t status = LaunchKernel(blit_queue, packet);\n\n  AMD::hsa_amd_memory_pool_free(args);\n\n  return status;\n}\n\nconst char *BlitKernel::kernel_name_[KERNEL_OP_COUNT] = {\n      \"&__copy_image_to_buffer_kernel\",\n      \"&__copy_buffer_to_image_kernel\",\n      \"&__copy_image_default_kernel\",\n      \"&__copy_image_linear_to_standard_kernel\",\n      \"&__copy_image_standard_to_linear_kernel\",\n      \"&__copy_image_1db_kernel\",\n      \"&__copy_image_1db_to_reg_kernel\",\n      \"&__copy_image_reg_to_1db_kernel\",\n      \"&__clear_image_kernel\",\n      \"&__clear_image_1db_kernel\"};\n\nconst char *BlitKernel::ocl_kernel_name_[KERNEL_OP_COUNT] = {\n      \"copy_image_to_buffer.kd\",\n      \"copy_buffer_to_image.kd\",\n      \"copy_image_default.kd\",\n      \"copy_image_linear_to_standard.kd\",\n      \"copy_image_standard_to_linear.kd\",\n      \"copy_image_1db.kd\",\n      \"copy_image_1db_to_reg.kd\",\n      \"copy_image_reg_to_1db.kd\",\n      \"clear_image.kd\",\n      \"clear_image_1db.kd\"};\n\nhsa_status_t BlitKernel::PopulateKernelCode(\n    hsa_agent_t agent, hsa_executable_t executable,\n    std::vector<BlitCodeInfo>& blit_code_catalog) {\n  blit_code_catalog.clear();\n\n  for (int i = 0; i < KERNEL_OP_COUNT; ++i) {\n    // Get symbol handle.\n    hsa_executable_symbol_t kernel_symbol = {0};\n\n    hsa_status_t status = HSA::hsa_executable_get_symbol_by_name(executable, ocl_kernel_name_[i],\n                                                                 &agent, &kernel_symbol);\n    if (HSA_STATUS_SUCCESS != status) {\n      blit_code_catalog.clear();\n      return status;\n    }\n\n    // Get code handle.\n    BlitCodeInfo blit_code = {0};\n    status = HSA::hsa_executable_symbol_get_info(\n        kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &blit_code.code_handle_);\n    if (HSA_STATUS_SUCCESS != status) {\n      blit_code_catalog.clear();\n      return status;\n    }\n\n    status = HSA::hsa_executable_symbol_get_info(\n        kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE,\n        &blit_code.group_segment_size_);\n    if (HSA_STATUS_SUCCESS != status) {\n      blit_code_catalog.clear();\n      return status;\n    }\n\n    status = HSA::hsa_executable_symbol_get_info(\n        kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE,\n        &blit_code.private_segment_size_);\n    if (HSA_STATUS_SUCCESS != status) {\n      blit_code_catalog.clear();\n      return status;\n    }\n\n    blit_code_catalog.push_back(blit_code);\n  }\n\n  assert(blit_code_catalog.size() == KERNEL_OP_COUNT);\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid BlitKernel::CalcBufferRowSlicePitchesInPixel(\n    hsa_ext_image_geometry_t geometry, uint32_t element_size,\n    const hsa_dim3_t& copy_size, size_t in_row_pitch_byte,\n    size_t in_slice_pitch_byte, unsigned long* out_pitch_pixel) {\n  const bool is_1d_array =\n      (geometry == HSA_EXT_IMAGE_GEOMETRY_1DA) ? true : false;\n\n  out_pitch_pixel[0] =\n      std::max(static_cast<unsigned long>(copy_size.x),\n               static_cast<unsigned long>(in_row_pitch_byte / element_size));\n\n  out_pitch_pixel[1] =\n      (is_1d_array)\n          ? out_pitch_pixel[0]\n          : (std::max(\n                static_cast<unsigned long>(out_pitch_pixel[0] * copy_size.y),\n                static_cast<unsigned long>(in_slice_pitch_byte /\n                                           element_size)));\n\n  assert((out_pitch_pixel[0] <= out_pitch_pixel[1]));\n}\n\nuint32_t BlitKernel::GetDimSize(const Image& image) {\n  static const uint32_t kDimSizeTable[] = {\n      1,  // HSA_EXT_IMAGE_GEOMETRY_1D\n      2,  // HSA_EXT_IMAGE_GEOMETRY_2D\n      3,  // HSA_EXT_IMAGE_GEOMETRY_3D\n      2,  // HSA_EXT_IMAGE_GEOMETRY_1DA\n      3,  // HSA_EXT_IMAGE_GEOMETRY_2DA\n      1,  // HSA_EXT_IMAGE_GEOMETRY_1DB\n      2,  // HSA_EXT_IMAGE_GEOMETRY_2DDEPTH\n      3,  // HSA_EXT_IMAGE_GEOMETRY_2DADEPTH\n  };\n\n  return kDimSizeTable[image.desc.geometry];\n}\n\nuint32_t BlitKernel::GetNumChannel(const Image& image) {\n  static const uint32_t kNumChannelTable[] = {\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_A,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_R,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RX,\n      2,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RG,\n      2,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGX,\n      2,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RA,\n      3,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGB,\n      3,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR,\n      3,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB,\n      3,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA,\n      4,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH,\n      1,  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL\n  };\n\n  return kNumChannelTable[image.desc.format.channel_order];\n}\n\nuint32_t BlitKernel::GetImageAccessType(const Image& image) {\n  enum AccessType {\n    ACCESS_TYPE_F = 0,\n    ACCESS_TYPE_I = 1,\n    ACCESS_TYPE_UI = 2,\n  };\n\n  static const uint32_t kAccessType[] = {\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT8\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT16\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT16\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT24\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010\n      ACCESS_TYPE_I,   // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT8\n      ACCESS_TYPE_I,   // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT16\n      ACCESS_TYPE_I,   // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT32\n      ACCESS_TYPE_UI,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8\n      ACCESS_TYPE_UI,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16\n      ACCESS_TYPE_UI,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32\n      ACCESS_TYPE_F,   // HSA_EXT_IMAGE_CHANNEL_TYPE_HALF_FLOAT\n      ACCESS_TYPE_F    // HSA_EXT_IMAGE_CHANNEL_TYPE_FLOAT\n  };\n\n  return kAccessType[image.desc.format.channel_type];\n}\n\nvoid BlitKernel::CalcWorkingSize(const Image& image, const hsa_dim3_t& range,\n                                 hsa_kernel_dispatch_packet_t& packet) {\n  switch (image.desc.geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      packet.setup = 2;\n      packet.grid_size_x = range.x;\n      packet.grid_size_y = range.y;\n      packet.grid_size_z = 1;\n      packet.workgroup_size_x = 64;\n      packet.workgroup_size_y = packet.workgroup_size_z = 1;\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n      packet.setup = 3;\n      packet.grid_size_x = range.x;\n      packet.grid_size_y = range.y;\n      packet.grid_size_z = range.z;\n      packet.workgroup_size_x = packet.workgroup_size_y = 8;\n      packet.workgroup_size_z = 1;\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n      packet.setup = 3;\n      packet.grid_size_x = range.x;\n      packet.grid_size_y = range.y;\n      packet.grid_size_z = range.z;\n      packet.workgroup_size_x = packet.workgroup_size_y = 4;\n      packet.workgroup_size_z = 4;\n      break;\n  }\n}\n\nvoid BlitKernel::CalcWorkingSize(const Image& src_image, const Image& dst_image,\n                                 const hsa_dim3_t& range,\n                                 hsa_kernel_dispatch_packet_t& packet) {\n  if (GetDimSize(src_image) < GetDimSize(dst_image)) {\n    CalcWorkingSize(src_image, range, packet);\n  } else {\n    CalcWorkingSize(dst_image, range, packet);\n  }\n}\n\nhsa_status_t BlitKernel::ConvertImage(const Image& original_image,\n                                      const Image** new_image) {\n  // To simplify the kernel, some particular image channel types are converted\n  // to a new channel type, while preserving the actual per pixel size.\n  // E.g.: a UNORM SIGNED INT8 is converted into UNSIGNED INT8. This way the\n  // kernel can just use read_imageui on all images.\n\n  static const uint32_t kTypeConvertTable[] = {\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8,  // HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT8\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT16\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT16\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT24,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT24\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8,  // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT8\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT16\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32,  // HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT32\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32,  // HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16,  // HSA_EXT_IMAGE_CHANNEL_TYPE_HALF_FLOAT\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32  // HSA_EXT_IMAGE_CHANNEL_TYPE_FLOAT\n  };\n\n  // To simplify the kernel, some particular image channel orders are converted\n  // to a new channel order, while preserving the actual per pixel size.\n  // E.g.: a CHANNEL ORDER A is converted into CHANNEL ORDER R. This way the\n  // kernel can just read the first components of vector4 on all images.\n  static const uint32_t kOrderConvertTable[] = {\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,     // HSA_EXT_IMAGE_CHANNEL_ORDER_A\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,     // HSA_EXT_IMAGE_CHANNEL_ORDER_R\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,     // HSA_EXT_IMAGE_CHANNEL_ORDER_RX\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RG,    // HSA_EXT_IMAGE_CHANNEL_ORDER_RG\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RG,    // HSA_EXT_IMAGE_CHANNEL_ORDER_RGX\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RG,    // HSA_EXT_IMAGE_CHANNEL_ORDER_RA\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGB,   // HSA_EXT_IMAGE_CHANNEL_ORDER_RGB\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGB,   // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA,  // HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,  // HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,  // HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE\n      HSA_EXT_IMAGE_CHANNEL_ORDER_R,  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH\n      HSA_EXT_IMAGE_CHANNEL_ORDER_RG  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL\n  };\n\n  const uint32_t current_type = original_image.desc.format.channel_type;\n  uint32_t converted_type = kTypeConvertTable[current_type];\n  const uint32_t current_order = original_image.desc.format.channel_order;\n  uint32_t converted_order = kOrderConvertTable[current_order];\n\n  if ((current_type == converted_type) && (current_order == converted_order)) {\n    *new_image = &original_image;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  // Handle formats that drop channels on conversion, only usable with RGB(X)\n  if((current_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555) ||\n     (current_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565) ||\n     (current_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010)) {\n    converted_order = HSA_EXT_IMAGE_CHANNEL_ORDER_R;\n  }\n\n  // For internal book keeping, depth isn't a HW type.\n  const hsa_ext_image_geometry_t current_geometry =\n      original_image.desc.geometry;\n  hsa_ext_image_geometry_t converted_geometry = current_geometry;\n  if (converted_geometry == HSA_EXT_IMAGE_GEOMETRY_2DDEPTH) {\n    converted_geometry = HSA_EXT_IMAGE_GEOMETRY_2D;\n  } else if (converted_geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH) {\n    converted_geometry = HSA_EXT_IMAGE_GEOMETRY_2DA;\n  }\n\n  hsa_ext_image_format_t new_format = {\n      static_cast<hsa_ext_image_channel_type_t>(converted_type),\n      static_cast<hsa_ext_image_channel_order_t>(converted_order)};\n\n  Image* new_image_handle = Image::Create(original_image.component);\n  *new_image_handle=original_image;\n  new_image_handle->desc.geometry = converted_geometry;\n\n  hsa_status_t status = ImageRuntime::instance()\n                            ->image_manager(new_image_handle->component)\n                            ->ModifyImageSrd(*new_image_handle, new_format);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  *new_image = new_image_handle;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::LaunchKernel(BlitQueue& blit_queue,\n                                      hsa_kernel_dispatch_packet_t& packet) {\n  static const uint16_t kInvalidPacketHeader = HSA_PACKET_TYPE_INVALID;\n\n  static const uint16_t kDispatchPacketHeader =\n      (HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE) |\n      (0 << HSA_PACKET_HEADER_BARRIER) |\n      (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE) |\n      (HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE);\n\n  // Copying the packet content to the queue buffer is not atomic, so it is\n  // possible that the packet has a valid packet type but invalid content.\n  // To make sure packet processor does not read invalid packet, we first\n  // initialized the packet type to invalid.\n  packet.header = kInvalidPacketHeader;\n\n  // Setup completion signal.\n  hsa_signal_t kernel_signal = {0};\n  hsa_status_t status = HSA::hsa_signal_create(1, 0, NULL, &kernel_signal);\n  if (HSA_STATUS_SUCCESS != status) {\n    return status;\n  }\n  packet.completion_signal = kernel_signal;\n\n  // Populate the queue.\n  hsa_queue_t* queue = blit_queue.queue_;\n  const uint32_t bitmask = queue->size - 1;\n\n  // Reserve write index.\n  uint64_t write_index = HSA::hsa_queue_add_write_index_scacq_screl(queue, 1);\n\n  while (true) {\n    // Wait until we have room in the queue;\n    const uint64_t read_index = HSA::hsa_queue_load_read_index_relaxed(queue);\n    if ((write_index - read_index) < queue->size) {\n      break;\n    }\n  }\n\n  // Populate queue buffer with AQL packet.\n  hsa_kernel_dispatch_packet_t* queue_buffer =\n      reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue->base_address);\n  queue_buffer[write_index & bitmask] = packet;\n\n  std::atomic_thread_fence(std::memory_order_release);\n\n  // Enable packet.\n  queue_buffer[write_index & bitmask].header = kDispatchPacketHeader;\n\n  // Update doorbel register.\n  HSA::hsa_signal_store_screlease(queue->doorbell_signal, write_index);\n\n  // Wait for the packet to finish.\n  if (HSA::hsa_signal_wait_scacquire(kernel_signal, HSA_SIGNAL_CONDITION_LT, 1, uint64_t(-1),\n                                     HSA_WAIT_STATE_ACTIVE) != 0) {\n    status = HSA::hsa_signal_destroy(kernel_signal);\n    assert(status == HSA_STATUS_SUCCESS);\n    // Signal wait returned unexpected value.\n    return HSA_STATUS_ERROR;\n  }\n\n  // Cleanup\n  status = HSA::hsa_signal_destroy(kernel_signal);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t BlitKernel::GetPatchedBlitObject(const char* agent_name,\n                                              uint8_t** blit_code_object) {\n  std::string sname(agent_name);\n\n  if (sname == \"gfx700\") {\n    *blit_code_object = ocl_blit_object_gfx700;\n  } else if (sname == \"gfx701\") {\n    *blit_code_object = ocl_blit_object_gfx701;\n  } else if (sname == \"gfx702\") {\n    *blit_code_object = ocl_blit_object_gfx702;\n  } else if (sname == \"gfx801\") {\n    *blit_code_object = ocl_blit_object_gfx801;\n  } else if (sname == \"gfx802\") {\n    *blit_code_object = ocl_blit_object_gfx802;\n  } else if (sname == \"gfx803\") {\n    *blit_code_object = ocl_blit_object_gfx803;\n  } else if (sname == \"gfx805\") {\n    *blit_code_object = ocl_blit_object_gfx805;\n  } else if (sname == \"gfx810\") {\n    *blit_code_object = ocl_blit_object_gfx810;\n  } else if (sname == \"gfx900\") {\n    *blit_code_object = ocl_blit_object_gfx900;\n  } else if (sname == \"gfx902\") {\n    *blit_code_object = ocl_blit_object_gfx902;\n  } else if (sname == \"gfx904\") {\n    *blit_code_object = ocl_blit_object_gfx904;\n  } else if (sname == \"gfx906\") {\n    *blit_code_object = ocl_blit_object_gfx906;\n  } else if (sname == \"gfx908\") {\n    *blit_code_object = ocl_blit_object_gfx908;\n  } else if (sname == \"gfx909\") {\n    *blit_code_object = ocl_blit_object_gfx909;\n  } else if (sname == \"gfx90a\") {\n    *blit_code_object = ocl_blit_object_gfx90a;\n  } else if (sname == \"gfx90c\") {\n    *blit_code_object = ocl_blit_object_gfx90c;\n  } else if (sname == \"gfx942\") {\n    *blit_code_object = ocl_blit_object_gfx942;\n  } else if (sname == \"gfx950\") {\n    *blit_code_object = ocl_blit_object_gfx950;\n  } else if (sname == \"gfx1010\") {\n    *blit_code_object = ocl_blit_object_gfx1010;\n  } else if (sname == \"gfx1011\") {\n    *blit_code_object = ocl_blit_object_gfx1011;\n  } else if (sname == \"gfx1012\") {\n    *blit_code_object = ocl_blit_object_gfx1012;\n  } else if (sname == \"gfx1013\") {\n    *blit_code_object = ocl_blit_object_gfx1013;\n  } else if (sname == \"gfx1030\") {\n    *blit_code_object = ocl_blit_object_gfx1030;\n  } else if (sname == \"gfx1031\") {\n    *blit_code_object = ocl_blit_object_gfx1031;\n  } else if (sname == \"gfx1032\") {\n    *blit_code_object = ocl_blit_object_gfx1032;\n  } else if (sname == \"gfx1033\") {\n    *blit_code_object = ocl_blit_object_gfx1033;\n  } else if (sname == \"gfx1034\") {\n    *blit_code_object = ocl_blit_object_gfx1034;\n  } else if (sname == \"gfx1035\") {\n    *blit_code_object = ocl_blit_object_gfx1035;\n  } else if (sname == \"gfx1036\") {\n    *blit_code_object = ocl_blit_object_gfx1036;\n  } else if (sname == \"gfx1100\") {\n    *blit_code_object = ocl_blit_object_gfx1100;\n  } else if (sname == \"gfx1101\") {\n    *blit_code_object = ocl_blit_object_gfx1101;\n  } else if (sname == \"gfx1102\") {\n    *blit_code_object = ocl_blit_object_gfx1102;\n  } else if (sname == \"gfx1103\") {\n    *blit_code_object = ocl_blit_object_gfx1103;\n  } else if (sname == \"gfx1150\") {\n    *blit_code_object = ocl_blit_object_gfx1150;\n  } else if (sname == \"gfx1151\") {\n    *blit_code_object = ocl_blit_object_gfx1151;\n  } else if (sname == \"gfx1152\") {\n    *blit_code_object = ocl_blit_object_gfx1152;\n  } else if (sname == \"gfx1153\") {\n    *blit_code_object = ocl_blit_object_gfx1153;\n  } else if (sname == \"gfx1200\") {\n    *blit_code_object = ocl_blit_object_gfx1200;\n  } else if (sname == \"gfx1201\") {\n    *blit_code_object = ocl_blit_object_gfx1201;\n  } else {\n    return HSA_STATUS_ERROR_INVALID_ISA_NAME;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace image\n}  // namespace rocr\n#undef HSA_ARGUMENT_ALIGN_BYTES\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_kernel.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_BLIT_KERNEL_H\n#define HSA_RUNTIME_EXT_IMAGE_BLIT_KERNEL_H\n#include <assert.h>\n#include <atomic>\n#include <mutex>\n#include <unordered_map>\n#include <vector>\n\n#include \"inc/hsa.h\"\n#include \"resource.h\"\n\nnamespace rocr {\nnamespace image {\n\ntypedef struct BlitQueue {\n  hsa_queue_t* queue_;\n  volatile std::atomic<uint64_t> cached_index_;\n} BlitQueue;\n\ntypedef struct BlitCodeInfo {\n  uint64_t code_handle_;\n  uint32_t group_segment_size_;\n  uint32_t private_segment_size_;\n} BlitCodeInfo;\n\nclass BlitKernel {\n public:\n  typedef enum KernelOp {\n    KERNEL_OP_COPY_IMAGE_TO_BUFFER = 0,\n    KERNEL_OP_COPY_BUFFER_TO_IMAGE = 1,\n    KERNEL_OP_COPY_IMAGE_DEFAULT = 2,\n    KERNEL_OP_COPY_IMAGE_LINEAR_TO_STANDARD = 3,\n    KERNEL_OP_COPY_IMAGE_STANDARD_TO_LINEAR = 4,\n    KERNEL_OP_COPY_IMAGE_1DB = 5,\n    KERNEL_OP_COPY_IMAGE_1DB_TO_REG = 6,\n    KERNEL_OP_COPY_IMAGE_REG_TO_1DB = 7,\n    KERNEL_OP_CLEAR_IMAGE = 8,\n    KERNEL_OP_CLEAR_IMAGE_1DB = 9,\n    KERNEL_OP_COUNT = 10\n  } KernelOp;\n\n  explicit BlitKernel();\n  ~BlitKernel();\n\n  hsa_status_t Initialize();\n\n  hsa_status_t Cleanup();\n\n  hsa_status_t BuildBlitCode(hsa_agent_t agent,\n                             std::vector<BlitCodeInfo>& blit_code_catalog);\n\n  hsa_status_t CopyBufferToImage(\n      BlitQueue& blit_queue,\n      const std::vector<BlitCodeInfo>& blit_code_catalog,\n      const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n      const Image& dst_image, const hsa_ext_image_region_t& image_region);\n\n  hsa_status_t CopyImageToBuffer(\n      BlitQueue& blit_queue,\n      const std::vector<BlitCodeInfo>& blit_code_catalog,\n      const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n      size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region);\n\n  hsa_status_t CopyImage(BlitQueue& blit_queue,\n                         const std::vector<BlitCodeInfo>& blit_code_catalog,\n                         const Image& dst_image, const Image& src_image,\n                         const hsa_dim3_t& dst_origin,\n                         const hsa_dim3_t& src_origin, const hsa_dim3_t size,\n                         KernelOp copy_type);\n\n  hsa_status_t FillImage(BlitQueue& blit_queue,\n                         const std::vector<BlitCodeInfo>& blit_code_catalog,\n                         const Image& image, const void* pattern,\n                         const hsa_ext_image_region_t& region);\n\n private:\n\n  hsa_status_t PopulateKernelCode(\n      hsa_agent_t agent, hsa_executable_t executable,\n      std::vector<BlitCodeInfo>& blit_code_catalog);\n\n  inline void CalcBufferRowSlicePitchesInPixel(\n      hsa_ext_image_geometry_t geometry, uint32_t element_size,\n      const hsa_dim3_t& copy_size, size_t in_row_pitch_byte,\n      size_t in_slice_pitch_byte, unsigned long* out_pitch_pixel);\n\n  inline uint32_t GetDimSize(const Image& image);\n\n  inline uint32_t GetNumChannel(const Image& image);\n\n  inline uint32_t GetImageAccessType(const Image& image);\n\n  void CalcWorkingSize(const Image& image, const hsa_dim3_t& range,\n                       hsa_kernel_dispatch_packet_t& packet);\n\n  void CalcWorkingSize(const Image& src_image, const Image& dst_image,\n                       const hsa_dim3_t& range,\n                       hsa_kernel_dispatch_packet_t& packet);\n\n  hsa_status_t ConvertImage(const Image& original_image,\n                            const Image** new_image);\n\n  hsa_status_t LaunchKernel(BlitQueue& queue,\n                            hsa_kernel_dispatch_packet_t& packet);\n\n  // The kernels' name.\n  static const char* kernel_name_[KERNEL_OP_COUNT];\n  static const char* ocl_kernel_name_[KERNEL_OP_COUNT];\n\n  // Mapping of ISA and kernel object.\n  std::unordered_map<uint64_t, hsa_code_object_t> code_object_map_;\n\n  // Mapping of ISA and kernel executable.\n  std::unordered_map<uint64_t, hsa_executable_t> code_executable_map_;\n\n  std::mutex lock_;\n\n  DISALLOW_COPY_AND_ASSIGN(BlitKernel);\n\n  // Get the patched code object\n  hsa_status_t GetPatchedBlitObject(const char* agent_name, uint8_t** code_object_handle);\n};\n\n}  // namespace image\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_EXT_IMAGE_BLIT_KERNEL_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_object_gfx7xx.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <stdint.h>\nnamespace rocr {\nnamespace image {\nuint8_t blit_object_gfx7xx[] = {127, 69, 76, 70, 2, 1, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 224, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 16, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 56, 0, 2, 0, 64, 0, 8, 0, 1, 0, 2, 0, 0, 96, 6, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 96, 5, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 37, 0, 0, 0, 0, 0, 0, 220, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 115, 104, 115, 116, 114, 116, 97, 98, 0, 46, 115, 116, 114, 116, 97, 98, 0, 46, 110, 111, 116, 101, 0, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 46, 104, 115, 97, 116, 101, 120, 116, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 114, 101, 108, 97, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 69, 88, 80, 95, 69, 80, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 69, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 95, 73, 78, 86, 95, 69, 80, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 116, 111, 95, 98, 117, 102, 102, 101, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 98, 117, 102, 102, 101, 114, 95, 116, 111, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 100, 101, 102, 97, 117, 108, 116, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 108, 105, 110, 101, 97, 114, 95, 116, 111, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 116, 111, 95, 108, 105, 110, 101, 97, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 116, 111, 95, 114, 101, 103, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 114, 101, 103, 95, 116, 111, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0, 4, 0, 0, 0, 26, 0, 0, 0, 3, 0, 0, 0, 65, 77, 68, 0, 4, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 0, 65, 77, 68, 71, 80, 85, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 4, 0, 0, 0, 65, 77, 68, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 32, 72, 83, 65, 32, 82, 117, 110, 116, 105, 109, 101, 32, 70, 105, 110, 97, 108, 105, 122, 101, 114, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 65, 77, 68, 0, 22, 0, 45, 104, 115, 97, 95, 99, 97, 108, 108, 95, 99, 111, 110, 118, 101, 110, 116, 105, 111, 110, 61, 48, 0, 37, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 96, 129, 63, 119, 62, 26, 57, 0, 192, 130, 63, 138, 105, 216, 57, 0, 32, 132, 63, 29, 70, 81, 58, 0, 160, 133, 63, 124, 54, 172, 57, 0, 0, 135, 63, 180, 12, 123, 58, 0, 128, 136, 63, 4, 116, 64, 58, 0, 0, 138, 63, 170, 171, 38, 58, 0, 128, 139, 63, 31, 15, 46, 58, 0, 0, 141, 63, 219, 250, 86, 58, 0, 160, 142, 63, 104, 49, 7, 57, 0, 32, 144, 63, 24, 226, 14, 58, 0, 192, 145, 63, 234, 220, 244, 56, 0, 64, 147, 63, 120, 89, 81, 58, 0, 224, 148, 63, 71, 125, 39, 58, 0, 128, 150, 63, 185, 105, 33, 58, 0, 32, 152, 63, 140, 130, 63, 58, 0, 224, 153, 63, 65, 38, 11, 55, 0, 128, 155, 63, 157, 155, 211, 57, 0, 32, 157, 63, 57, 205, 118, 58, 0, 224, 158, 63, 4, 147, 41, 58, 0, 160, 160, 63, 125, 136, 2, 58, 0, 96, 162, 63, 24, 24, 2, 58, 0, 32, 164, 63, 112, 173, 40, 58, 0, 224, 165, 63, 77, 181, 118, 58, 0, 192, 167, 63, 78, 59, 217, 57, 0, 160, 169, 63, 117, 90, 45, 56, 0, 96, 171, 63, 173, 205, 81, 58, 0, 64, 173, 63, 82, 247, 65, 58, 0, 32, 175, 63, 107, 197, 91, 58, 0, 32, 177, 63, 116, 96, 253, 56, 0, 0, 179, 63, 149, 32, 14, 58, 0, 0, 181, 63, 127, 102, 30, 57, 0, 224, 182, 63, 25, 143, 108, 58, 0, 224, 184, 63, 59, 122, 93, 58, 0, 224, 186, 63, 144, 213, 122, 58, 0, 0, 189, 63, 245, 57, 138, 57, 0, 0, 191, 63, 179, 205, 60, 58, 0, 32, 193, 63, 166, 204, 196, 57, 0, 64, 195, 63, 68, 155, 89, 57, 0, 96, 197, 63, 42, 66, 101, 57, 0, 128, 199, 63, 138, 76, 215, 57, 0, 160, 201, 63, 51, 236, 77, 58, 0, 224, 203, 63, 239, 79, 193, 57, 0, 32, 206, 63, 163, 130, 17, 57, 0, 96, 208, 63, 187, 246, 204, 56, 0, 160, 210, 63, 31, 217, 129, 57, 0, 224, 212, 63, 94, 213, 26, 58, 0, 64, 215, 63, 90, 153, 31, 57, 0, 128, 217, 63, 19, 174, 104, 58, 0, 224, 219, 63, 190, 188, 93, 58, 0, 96, 222, 63, 94, 130, 244, 55, 0, 192, 224, 63, 194, 238, 205, 57, 0, 32, 227, 63, 149, 75, 124, 58, 0, 160, 229, 63, 59, 55, 72, 58, 0, 32, 232, 63, 129, 82, 75, 58, 0, 192, 234, 63, 221, 231, 198, 55, 0, 64, 237, 63, 237, 1, 243, 57, 0, 224, 239, 63, 123, 51, 23, 57, 0, 128, 242, 63, 44, 158, 59, 56, 0, 32, 245, 63, 164, 162, 47, 57, 0, 192, 247, 63, 152, 251, 6, 58, 0, 128, 250, 63, 220, 182, 236, 56, 0, 32, 253, 63, 103, 96, 112, 58, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 59, 65, 172, 41, 52, 0, 0, 126, 60, 252, 176, 168, 53, 0, 192, 189, 60, 234, 131, 141, 54, 0, 16, 252, 60, 120, 14, 27, 54, 0, 240, 28, 61, 254, 185, 135, 54, 0, 160, 59, 61, 101, 236, 49, 54, 0, 16, 90, 61, 25, 113, 221, 54, 0, 80, 120, 61, 69, 0, 195, 53, 0, 32, 139, 61, 81, 119, 155, 55, 0, 0, 154, 61, 13, 203, 235, 55, 0, 208, 168, 61, 131, 159, 131, 55, 0, 128, 183, 61, 229, 138, 82, 55, 0, 16, 198, 61, 24, 235, 162, 55, 0, 144, 212, 61, 149, 116, 218, 54, 0, 240, 226, 61, 183, 30, 169, 54, 0, 48, 241, 61, 21, 183, 131, 55, 0, 96, 255, 61, 219, 49, 17, 55, 0, 176, 6, 62, 104, 62, 63, 56, 0, 176, 13, 62, 151, 106, 21, 56, 0, 160, 20, 62, 15, 124, 41, 56, 0, 128, 27, 62, 15, 16, 126, 56, 0, 96, 34, 62, 101, 182, 21, 56, 0, 48, 41, 62, 161, 227, 229, 55, 0, 240, 47, 62, 83, 56, 24, 56, 0, 176, 54, 62, 157, 113, 254, 53, 0, 80, 61, 62, 8, 129, 68, 56, 0, 240, 67, 62, 144, 50, 80, 56, 0, 144, 74, 62, 232, 57, 53, 55, 0, 16, 81, 62, 241, 15, 94, 56, 0, 144, 87, 62, 64, 167, 100, 56, 0, 16, 94, 62, 45, 116, 134, 55, 0, 112, 100, 62, 205, 227, 123, 56, 0, 224, 106, 62, 62, 173, 133, 54, 0, 48, 113, 62, 21, 183, 3, 56, 0, 128, 119, 62, 220, 203, 173, 55, 0, 192, 125, 62, 175, 54, 12, 56, 0, 0, 130, 62, 211, 82, 22, 55, 0, 16, 133, 62, 57, 113, 146, 56, 0, 32, 136, 62, 215, 252, 197, 56, 0, 48, 139, 62, 213, 85, 174, 56, 0, 64, 142, 62, 105, 193, 24, 56, 0, 64, 145, 62, 231, 253, 160, 56, 0, 64, 148, 62, 239, 9, 173, 56, 0, 64, 151, 62, 225, 186, 98, 56, 0, 48, 154, 62, 76, 205, 238, 56, 0, 48, 157, 62, 210, 170, 152, 55, 0, 32, 160, 62, 26, 26, 66, 55, 0, 0, 163, 62, 14, 225, 197, 56, 0, 240, 165, 62, 238, 42, 191, 55, 0, 208, 168, 62, 45, 135, 45, 56, 0, 176, 171, 62, 138, 46, 238, 55, 0, 128, 174, 62, 172, 223, 222, 56, 0, 96, 177, 62, 185, 242, 2, 56, 0, 48, 180, 62, 155, 30, 72, 56, 0, 0, 183, 62, 43, 170, 14, 56, 0, 192, 185, 62, 93, 251, 235, 56, 0, 144, 188, 62, 221, 95, 37, 56, 0, 80, 191, 62, 130, 59, 120, 56, 0, 16, 194, 62, 30, 218, 81, 56, 0, 208, 196, 62, 5, 27, 78, 55, 0, 128, 199, 62, 155, 67, 143, 56, 0, 48, 202, 62, 16, 14, 202, 56, 0, 224, 204, 62, 139, 192, 202, 56, 0, 144, 207, 62, 95, 246, 145, 56, 0, 64, 210, 62, 203, 33, 129, 55, 0, 224, 212, 62, 154, 154, 108, 56, 0, 128, 215, 62, 35, 153, 148, 56, 0, 32, 218, 62, 204, 123, 119, 56, 0, 192, 220, 62, 38, 45, 177, 55, 0, 80, 223, 62, 211, 206, 166, 56, 0, 224, 225, 62, 230, 211, 235, 56, 0, 112, 228, 62, 205, 227, 251, 56, 0, 0, 231, 62, 194, 133, 215, 56, 0, 144, 233, 62, 0, 126, 126, 56, 0, 16, 236, 62, 197, 146, 243, 56, 0, 160, 238, 62, 131, 9, 212, 55, 0, 32, 241, 62, 124, 26, 8, 56, 0, 160, 243, 62, 173, 195, 132, 55, 0, 16, 246, 62, 35, 233, 204, 56, 0, 144, 248, 62, 175, 95, 15, 56, 0, 0, 251, 62, 56, 253, 145, 56, 0, 112, 253, 62, 188, 71, 172, 56, 0, 224, 255, 62, 43, 4, 151, 56, 0, 32, 1, 63, 210, 82, 41, 57, 0, 80, 2, 63, 212, 206, 111, 57, 0, 144, 3, 63, 115, 112, 249, 55, 0, 192, 4, 63, 174, 158, 94, 56, 0, 240, 5, 63, 74, 200, 101, 56, 0, 32, 7, 63, 163, 11, 19, 56, 0, 64, 8, 63, 22, 207, 121, 57, 0, 112, 9, 63, 201, 202, 56, 57, 0, 160, 10, 63, 244, 210, 195, 56, 0, 192, 11, 63, 236, 93, 117, 57, 0, 240, 12, 63, 103, 180, 230, 56, 0, 16, 14, 63, 184, 15, 92, 57, 0, 64, 15, 63, 224, 188, 62, 56, 0, 96, 16, 63, 146, 209, 220, 56, 0, 128, 17, 63, 223, 107, 24, 57, 0, 160, 18, 63, 76, 231, 45, 57, 0, 192, 19, 63, 68, 9, 47, 57, 0, 224, 20, 63, 97, 255, 27, 57, 0, 0, 22, 63, 68, 237, 233, 56, 0, 32, 23, 63, 200, 109, 104, 56, 0, 48, 24, 63, 167, 153, 107, 57, 0, 80, 25, 63, 137, 156, 9, 57, 0, 112, 26, 63, 115, 118, 162, 55, 0, 128, 27, 63, 163, 218, 11, 57, 0, 144, 28, 63, 171, 105, 112, 57, 0, 176, 29, 63, 255, 73, 132, 56, 0, 192, 30, 63, 56, 53, 1, 57, 0, 208, 31, 63, 104, 194, 45, 57, 0, 224, 32, 63, 35, 244, 71, 57, 0, 240, 33, 63, 124, 241, 79, 57, 0, 0, 35, 63, 14, 225, 69, 57, 0, 16, 36, 63, 245, 232, 41, 57, 0, 32, 37, 63, 176, 93, 248, 56, 0, 48, 38, 63, 153, 95, 115, 56, 0, 48, 39, 63, 219, 8, 108, 57, 0, 64, 40, 63, 0, 230, 9, 57, 0, 80, 41, 63, 111, 153, 180, 55, 0, 80, 42, 63, 204, 51, 18, 57, 0, 80, 43, 63, 217, 234, 124, 57, 0, 96, 44, 63, 205, 181, 173, 56, 0, 96, 45, 63, 26, 38, 32, 57, 0, 96, 46, 63, 54, 238, 88, 57, 0, 112, 47, 63, 5, 73, 170, 53, 0, 112, 48, 63, 30, 209, 203, 55, 0, 112, 49, 63, 244, 253, 5, 56, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 254, 63, 248, 3, 254, 56, 0, 0, 252, 63, 193, 15, 252, 57, 0, 0, 250, 63, 201, 179, 140, 58, 0, 0, 248, 63, 16, 62, 248, 58, 0, 0, 246, 63, 48, 123, 64, 59, 0, 0, 244, 63, 96, 141, 137, 59, 0, 0, 242, 63, 72, 214, 185, 59, 0, 0, 240, 63, 241, 240, 240, 59, 0, 0, 239, 63, 127, 220, 186, 58, 0, 0, 237, 63, 108, 7, 102, 59, 0, 0, 235, 63, 166, 178, 189, 59, 0, 0, 234, 63, 161, 14, 234, 57, 0, 0, 232, 63, 247, 88, 75, 59, 0, 0, 230, 63, 72, 180, 194, 59, 0, 0, 229, 63, 172, 96, 150, 58, 0, 0, 227, 63, 228, 56, 142, 59, 0, 0, 225, 63, 14, 120, 252, 59, 0, 0, 224, 63, 56, 112, 96, 59, 0, 0, 222, 63, 77, 92, 233, 59, 0, 0, 221, 63, 76, 145, 79, 59, 0, 0, 219, 63, 239, 97, 235, 59, 0, 0, 218, 63, 79, 27, 104, 59, 0, 0, 217, 63, 178, 1, 89, 56, 0, 0, 215, 63, 229, 53, 148, 59, 0, 0, 214, 63, 89, 3, 174, 58, 0, 0, 212, 63, 3, 123, 199, 59, 0, 0, 211, 63, 109, 26, 80, 59, 0, 0, 210, 63, 33, 13, 210, 57, 0, 0, 208, 63, 204, 159, 182, 59, 0, 0, 207, 63, 81, 233, 72, 59, 0, 0, 206, 63, 185, 83, 52, 58, 0, 0, 204, 63, 205, 204, 204, 59, 0, 0, 203, 63, 192, 39, 135, 59, 0, 0, 202, 63, 205, 15, 11, 59, 0, 0, 201, 63, 209, 73, 123, 57, 0, 0, 199, 63, 125, 12, 206, 59, 0, 0, 198, 63, 106, 12, 152, 59, 0, 0, 197, 63, 247, 144, 75, 59, 0, 0, 196, 63, 21, 190, 220, 58, 0, 0, 195, 63, 49, 12, 195, 57, 0, 0, 193, 63, 214, 187, 228, 59, 0, 0, 192, 63, 193, 192, 192, 59, 0, 0, 191, 63, 232, 47, 160, 59, 0, 0, 190, 63, 12, 250, 130, 59, 0, 0, 189, 63, 142, 32, 82, 59, 0, 0, 188, 63, 24, 200, 36, 59, 0, 0, 187, 63, 135, 156, 251, 58, 0, 0, 186, 63, 140, 46, 186, 58, 0, 0, 185, 63, 233, 15, 133, 58, 0, 0, 184, 63, 3, 23, 56, 58, 0, 0, 183, 63, 162, 181, 251, 57, 0, 0, 182, 63, 97, 11, 182, 57, 0, 0, 181, 63, 170, 104, 158, 57, 0, 0, 180, 63, 65, 11, 180, 57, 0, 0, 179, 63, 41, 53, 246, 57, 0, 0, 178, 63, 67, 22, 50, 58, 0, 0, 177, 63, 192, 157, 126, 58, 0, 0, 176, 63, 11, 44, 176, 58, 0, 0, 175, 63, 26, 119, 235, 58, 0, 0, 174, 63, 185, 130, 24, 59, 0, 0, 173, 63, 176, 86, 64, 59, 0, 0, 172, 63, 8, 35, 109, 59, 0, 0, 171, 63, 227, 105, 143, 59, 0, 0, 170, 63, 171, 170, 170, 59, 0, 0, 169, 63, 72, 74, 200, 59, 0, 0, 168, 63, 87, 63, 232, 59, 0, 0, 168, 63, 129, 10, 168, 57, 0, 0, 167, 63, 230, 20, 188, 58, 0, 0, 166, 63, 114, 136, 43, 59, 0, 0, 165, 63, 5, 106, 125, 59, 0, 0, 164, 63, 30, 207, 169, 59, 0, 0, 163, 63, 61, 10, 215, 59, 0, 0, 163, 63, 246, 199, 75, 57, 0, 0, 162, 63, 172, 12, 223, 58, 0, 0, 161, 63, 93, 98, 86, 59, 0, 0, 160, 63, 161, 160, 160, 59, 0, 0, 159, 63, 254, 9, 216, 59, 0, 0, 159, 63, 57, 47, 11, 58, 0, 0, 158, 63, 72, 90, 25, 59, 0, 0, 157, 63, 158, 216, 137, 59, 0, 0, 156, 63, 97, 225, 200, 59, 0, 0, 156, 63, 193, 9, 156, 57, 0, 0, 155, 63, 62, 223, 24, 59, 0, 0, 154, 63, 217, 231, 144, 59, 0, 0, 153, 63, 219, 34, 215, 59, 0, 0, 153, 63, 139, 210, 120, 58, 0, 0, 152, 63, 19, 144, 81, 59, 0, 0, 151, 63, 237, 37, 180, 59, 0, 0, 151, 63, 46, 1, 23, 56, 0, 0, 150, 63, 216, 180, 31, 59, 0, 0, 149, 63, 104, 37, 160, 59, 0, 0, 148, 63, 79, 9, 242, 59, 0, 0, 148, 63, 41, 1, 11, 59, 0, 0, 147, 63, 196, 133, 154, 59, 0, 0, 146, 63, 132, 19, 241, 59, 0, 0, 146, 63, 37, 73, 18, 59, 0, 0, 145, 63, 197, 179, 162, 59, 0, 0, 144, 63, 9, 188, 253, 59, 0, 0, 144, 63, 198, 112, 52, 59, 0, 0, 143, 63, 238, 35, 184, 59, 0, 0, 143, 63, 208, 206, 59, 58, 0, 0, 142, 63, 218, 106, 112, 59, 0, 0, 141, 63, 2, 82, 218, 59, 0, 0, 141, 63, 35, 44, 247, 58, 0, 0, 140, 63, 4, 156, 162, 59, 0, 0, 140, 63, 193, 8, 140, 57, 0, 0, 139, 63, 148, 104, 96, 59, 0, 0, 138, 63, 252, 242, 216, 59, 0, 0, 138, 63, 225, 240, 5, 59, 0, 0, 137, 63, 138, 64, 174, 59, 0, 0, 137, 63, 215, 57, 86, 58, 0, 0, 136, 63, 137, 136, 136, 59, 0, 0, 135, 63, 136, 128, 247, 59, 0, 0, 135, 63, 190, 86, 79, 59, 0, 0, 134, 63, 68, 5, 217, 59, 0, 0, 134, 63, 252, 20, 23, 59, 0, 0, 133, 63, 97, 55, 191, 59, 0, 0, 133, 63, 77, 33, 208, 58, 0, 0, 132, 63, 200, 249, 169, 59, 0, 0, 132, 63, 8, 33, 132, 58, 0, 0, 131, 63, 82, 48, 153, 59, 0, 0, 131, 63, 188, 116, 19, 58, 0, 0, 130, 63, 191, 191, 140, 59, 0, 0, 130, 63, 33, 8, 130, 57, 0, 0, 129, 63, 169, 141, 132, 59, 0, 0, 129, 63, 4, 2, 129, 56, 0, 0, 128, 63, 129, 128, 128, 59, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 11, 0, 11, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 26, 7, 70, 192, 28, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 2, 209, 1, 27, 0, 0, 8, 0, 2, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 135, 3, 4, 8, 125, 0, 106, 128, 135, 0, 36, 128, 190, 188, 0, 136, 191, 6, 7, 65, 192, 14, 7, 66, 192, 16, 7, 4, 192, 18, 7, 69, 192, 32, 135, 4, 192, 34, 7, 134, 192, 159, 0, 6, 48, 159, 2, 8, 48, 127, 0, 140, 191, 5, 0, 212, 210, 1, 25, 0, 0, 4, 0, 210, 210, 4, 25, 0, 0, 4, 11, 8, 74, 5, 0, 210, 210, 1, 27, 0, 0, 5, 9, 8, 74, 5, 0, 210, 210, 1, 25, 0, 0, 5, 106, 74, 210, 5, 1, 2, 0, 4, 7, 6, 80, 4, 0, 14, 74, 5, 2, 16, 74, 8, 4, 18, 74, 159, 4, 12, 48, 0, 3, 200, 192, 128, 2, 20, 126, 127, 0, 140, 191, 0, 95, 0, 240, 7, 7, 4, 0, 0, 0, 212, 210, 2, 29, 0, 0, 1, 0, 210, 210, 6, 29, 0, 0, 1, 1, 0, 74, 1, 0, 210, 210, 2, 31, 0, 0, 1, 1, 0, 74, 1, 0, 210, 210, 2, 29, 0, 0, 1, 106, 74, 210, 1, 11, 2, 0, 0, 7, 0, 80, 2, 0, 212, 210, 1, 19, 0, 0, 0, 0, 210, 210, 0, 19, 0, 0, 0, 5, 0, 74, 1, 0, 210, 210, 1, 19, 0, 0, 3, 106, 74, 210, 1, 21, 0, 0, 11, 2, 4, 126, 0, 5, 8, 80, 30, 7, 65, 192, 8, 7, 66, 192, 127, 0, 140, 191, 2, 132, 0, 191, 83, 0, 133, 191, 10, 7, 68, 192, 2, 130, 0, 191, 41, 0, 132, 191, 3, 132, 0, 191, 29, 0, 133, 191, 3, 130, 0, 191, 12, 0, 132, 191, 0, 0, 194, 210, 3, 5, 1, 0, 112, 15, 140, 191, 144, 16, 4, 52, 0, 106, 74, 210, 4, 0, 2, 0, 5, 2, 6, 126, 3, 3, 2, 80, 2, 15, 4, 56, 0, 0, 112, 220, 0, 2, 0, 0, 109, 0, 130, 191, 3, 129, 0, 191, 107, 0, 132, 191, 0, 0, 194, 210, 3, 3, 1, 0, 112, 15, 140, 191, 136, 16, 4, 52, 127, 0, 140, 191, 0, 106, 74, 210, 8, 0, 2, 0, 9, 2, 6, 126, 3, 3, 2, 80, 2, 15, 4, 56, 0, 0, 104, 220, 0, 2, 0, 0, 94, 0, 130, 191, 0, 0, 194, 210, 3, 5, 1, 0, 0, 106, 74, 210, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 80, 112, 15, 140, 191, 0, 0, 116, 220, 0, 7, 0, 0, 84, 0, 130, 191, 2, 129, 0, 191, 82, 0, 132, 191, 3, 132, 0, 191, 25, 0, 133, 191, 3, 130, 0, 191, 11, 0, 132, 191, 0, 0, 194, 210, 3, 3, 1, 0, 127, 0, 140, 191, 0, 106, 74, 210, 8, 0, 2, 0, 9, 2, 4, 126, 2, 3, 2, 80, 112, 15, 140, 191, 0, 0, 104, 220, 0, 7, 0, 0, 67, 0, 130, 191, 3, 129, 0, 191, 65, 0, 132, 191, 12, 7, 65, 192, 127, 0, 140, 191, 0, 106, 74, 210, 2, 6, 2, 0, 3, 2, 4, 126, 2, 9, 2, 80, 112, 15, 140, 191, 0, 0, 96, 220, 0, 7, 0, 0, 55, 0, 130, 191, 0, 0, 194, 210, 3, 5, 1, 0, 0, 106, 74, 210, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 80, 112, 15, 140, 191, 0, 0, 112, 220, 0, 7, 0, 0, 45, 0, 130, 191, 3, 132, 0, 191, 34, 0, 133, 191, 3, 130, 0, 191, 14, 0, 132, 191, 112, 15, 140, 191, 144, 16, 0, 52, 0, 15, 10, 56, 1, 0, 194, 210, 3, 5, 1, 0, 1, 106, 74, 210, 4, 2, 2, 0, 5, 2, 6, 126, 3, 5, 4, 80, 144, 20, 6, 52, 3, 19, 12, 56, 0, 0, 116, 220, 1, 5, 0, 0, 27, 0, 130, 191, 3, 129, 0, 191, 25, 0, 132, 191, 112, 15, 140, 191, 136, 16, 0, 52, 1, 0, 194, 210, 3, 5, 1, 0, 0, 15, 0, 56, 144, 18, 6, 52, 0, 7, 0, 56, 152, 20, 6, 52, 1, 106, 74, 210, 4, 2, 2, 0, 5, 2, 8, 126, 4, 5, 4, 80, 0, 7, 0, 56, 0, 0, 112, 220, 1, 0, 0, 0, 9, 0, 130, 191, 0, 0, 194, 210, 3, 5, 1, 0, 0, 106, 74, 210, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 80, 112, 15, 140, 191, 0, 0, 120, 220, 0, 7, 0, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 19, 0, 19, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 22, 7, 70, 192, 24, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 2, 209, 1, 27, 0, 0, 8, 0, 2, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 135, 3, 4, 8, 125, 0, 106, 128, 135, 0, 36, 128, 190, 193, 0, 136, 191, 10, 7, 65, 192, 18, 7, 66, 192, 20, 7, 4, 192, 28, 135, 4, 192, 30, 7, 134, 192, 159, 0, 6, 48, 159, 2, 8, 48, 127, 0, 140, 191, 5, 0, 212, 210, 1, 25, 0, 0, 4, 0, 210, 210, 4, 25, 0, 0, 4, 11, 8, 74, 5, 0, 210, 210, 1, 27, 0, 0, 5, 9, 8, 74, 5, 0, 210, 210, 1, 25, 0, 0, 5, 106, 74, 210, 5, 1, 2, 0, 4, 7, 6, 80, 159, 4, 8, 48, 6, 0, 212, 210, 2, 29, 0, 0, 4, 0, 210, 210, 4, 29, 0, 0, 4, 13, 8, 74, 6, 0, 210, 210, 2, 31, 0, 0, 6, 9, 8, 74, 6, 0, 210, 210, 2, 29, 0, 0, 5, 106, 74, 210, 6, 11, 2, 0, 4, 7, 6, 80, 4, 0, 212, 210, 5, 19, 0, 0, 3, 0, 210, 210, 3, 19, 0, 0, 3, 9, 6, 74, 4, 0, 210, 210, 5, 19, 0, 0, 6, 106, 74, 210, 4, 5, 0, 0, 3, 2, 10, 126, 3, 11, 14, 80, 4, 0, 30, 74, 5, 2, 32, 74, 8, 4, 34, 74, 26, 7, 65, 192, 6, 7, 68, 192, 127, 0, 140, 191, 2, 132, 0, 191, 77, 0, 133, 191, 2, 130, 0, 191, 39, 0, 132, 191, 3, 130, 0, 191, 13, 0, 132, 191, 3, 0, 194, 210, 6, 5, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 48, 220, 3, 0, 0, 3, 112, 0, 140, 191, 144, 6, 12, 44, 5, 0, 144, 210, 3, 1, 65, 2, 57, 0, 130, 191, 3, 129, 0, 191, 13, 0, 132, 191, 3, 0, 194, 210, 6, 3, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 40, 220, 3, 0, 0, 3, 112, 0, 140, 191, 136, 6, 12, 44, 5, 0, 144, 210, 3, 1, 33, 2, 42, 0, 130, 191, 3, 0, 194, 210, 6, 5, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 52, 220, 3, 0, 0, 5, 33, 0, 130, 191, 2, 129, 0, 191, 29, 0, 132, 191, 3, 130, 0, 191, 9, 0, 132, 191, 3, 0, 194, 210, 6, 3, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 40, 220, 3, 0, 0, 5, 19, 0, 130, 191, 3, 129, 0, 191, 7, 0, 132, 191, 3, 106, 74, 210, 8, 12, 2, 0, 9, 2, 10, 126, 5, 15, 8, 80, 0, 0, 32, 220, 3, 0, 0, 5, 10, 0, 130, 191, 3, 0, 194, 210, 6, 5, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 48, 220, 3, 0, 0, 5, 1, 0, 130, 191, 2, 2, 10, 126, 3, 2, 12, 126, 5, 2, 16, 126, 4, 2, 14, 126, 55, 0, 130, 191, 3, 129, 0, 191, 17, 0, 132, 191, 3, 0, 194, 210, 6, 5, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 48, 220, 3, 0, 0, 3, 112, 0, 140, 191, 152, 6, 16, 44, 7, 0, 144, 210, 3, 33, 33, 2, 6, 0, 144, 210, 3, 17, 33, 2, 5, 0, 144, 210, 3, 1, 33, 2, 36, 0, 130, 191, 3, 0, 194, 210, 6, 5, 1, 0, 3, 106, 74, 210, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 80, 0, 0, 48, 220, 3, 0, 0, 5, 3, 130, 0, 191, 14, 0, 132, 191, 3, 106, 74, 210, 3, 9, 1, 0, 4, 106, 80, 210, 4, 1, 169, 1, 0, 0, 48, 220, 3, 0, 0, 3, 112, 0, 140, 191, 144, 6, 16, 44, 7, 0, 144, 210, 3, 1, 65, 2, 144, 10, 12, 44, 5, 0, 144, 210, 5, 1, 65, 2, 12, 0, 130, 191, 6, 106, 74, 210, 3, 25, 1, 0, 7, 106, 80, 210, 4, 1, 169, 1, 0, 0, 48, 220, 6, 0, 0, 8, 3, 106, 74, 210, 3, 9, 1, 0, 4, 106, 80, 210, 4, 1, 169, 1, 0, 0, 52, 220, 3, 0, 0, 6, 8, 7, 65, 192, 127, 0, 140, 191, 0, 3, 194, 192, 128, 2, 36, 126, 112, 0, 140, 191, 0, 95, 32, 240, 15, 5, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 18, 7, 70, 192, 20, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 12, 209, 1, 27, 0, 0, 8, 0, 12, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 136, 3, 4, 6, 125, 0, 106, 234, 136, 126, 4, 128, 190, 0, 106, 254, 138, 22, 0, 136, 191, 6, 7, 132, 192, 10, 7, 65, 192, 12, 7, 2, 192, 127, 0, 140, 191, 0, 9, 198, 192, 2, 0, 6, 74, 3, 2, 8, 74, 4, 4, 10, 74, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 14, 7, 130, 192, 0, 11, 196, 192, 127, 0, 140, 191, 4, 0, 14, 74, 5, 2, 16, 74, 6, 4, 18, 74, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 21, 0, 21, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 18, 7, 70, 192, 20, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 12, 209, 1, 27, 0, 0, 8, 0, 12, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 136, 3, 4, 6, 125, 0, 106, 234, 136, 126, 4, 128, 190, 0, 106, 254, 138, 212, 2, 136, 191, 6, 7, 65, 192, 10, 7, 66, 192, 12, 7, 4, 192, 127, 0, 140, 191, 0, 3, 198, 192, 4, 0, 6, 74, 5, 2, 8, 74, 8, 4, 10, 74, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 112, 15, 140, 191, 106, 0, 16, 209, 3, 7, 1, 0, 3, 0, 0, 210, 3, 1, 169, 1, 242, 6, 28, 124, 106, 36, 130, 190, 223, 0, 136, 191, 128, 6, 8, 124, 106, 36, 132, 190, 128, 2, 6, 126, 4, 126, 254, 138, 217, 0, 136, 191, 255, 3, 136, 190, 28, 46, 77, 59, 8, 6, 8, 124, 106, 36, 136, 190, 255, 6, 6, 16, 82, 184, 78, 65, 8, 126, 254, 138, 242, 6, 6, 16, 208, 0, 136, 191, 255, 6, 14, 54, 255, 255, 255, 127, 242, 14, 16, 8, 255, 3, 138, 190, 0, 0, 128, 61, 106, 1, 22, 208, 8, 21, 0, 0, 126, 4, 138, 190, 10, 106, 254, 138, 7, 129, 16, 126, 69, 0, 136, 191, 129, 16, 18, 52, 255, 16, 16, 74, 0, 0, 128, 0, 255, 18, 18, 74, 0, 0, 0, 1, 255, 16, 20, 54, 0, 0, 127, 0, 255, 18, 18, 54, 0, 0, 1, 0, 9, 21, 18, 74, 144, 18, 20, 44, 128, 2, 22, 126, 10, 0, 194, 210, 10, 7, 1, 0, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 12, 106, 74, 210, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 80, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 10, 106, 74, 210, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 80, 0, 0, 52, 220, 10, 0, 0, 10, 255, 16, 16, 54, 255, 255, 127, 0, 240, 18, 18, 56, 240, 16, 16, 56, 9, 17, 16, 8, 113, 1, 140, 191, 13, 17, 18, 16, 12, 17, 18, 62, 255, 2, 28, 126, 171, 170, 170, 62, 255, 3, 140, 190, 0, 0, 128, 62, 7, 127, 30, 126, 12, 18, 28, 62, 12, 0, 130, 210, 12, 17, 38, 132, 193, 30, 30, 74, 14, 0, 130, 210, 9, 29, 194, 3, 9, 19, 32, 16, 13, 17, 24, 62, 15, 11, 16, 126, 14, 33, 24, 62, 255, 3, 140, 190, 244, 253, 5, 56, 12, 0, 130, 210, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 6, 8, 21, 16, 64, 0, 112, 49, 63, 12, 19, 30, 8, 255, 18, 28, 58, 0, 0, 0, 128, 8, 31, 26, 6, 10, 126, 254, 138, 8, 17, 18, 16, 21, 0, 136, 191, 8, 19, 20, 16, 255, 2, 22, 126, 171, 170, 42, 62, 255, 3, 140, 190, 37, 73, 18, 62, 12, 16, 22, 62, 8, 23, 22, 66, 205, 204, 76, 62, 8, 23, 22, 66, 0, 0, 128, 62, 8, 23, 22, 66, 171, 170, 170, 62, 10, 23, 20, 16, 241, 18, 28, 16, 15, 0, 130, 210, 9, 227, 41, 132, 15, 17, 26, 8, 255, 20, 24, 58, 0, 0, 0, 128, 255, 16, 16, 58, 0, 0, 0, 128, 10, 4, 254, 190, 8, 27, 20, 8, 15, 29, 18, 8, 15, 21, 20, 6, 12, 19, 18, 8, 255, 26, 22, 54, 0, 240, 255, 255, 9, 21, 18, 6, 13, 23, 16, 8, 9, 17, 16, 6, 255, 16, 18, 16, 0, 160, 42, 56, 11, 19, 18, 64, 0, 160, 42, 56, 8, 19, 16, 64, 0, 80, 213, 62, 11, 17, 18, 64, 0, 80, 213, 62, 255, 18, 20, 16, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 54, 131, 24, 24, 52, 255, 3, 139, 190, 85, 85, 85, 85, 255, 3, 138, 190, 85, 85, 85, 85, 12, 106, 74, 210, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 80, 210, 13, 1, 169, 1, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 138, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 130, 210, 10, 22, 38, 132, 14, 19, 30, 64, 0, 0, 49, 188, 8, 23, 16, 6, 14, 31, 22, 64, 239, 47, 228, 183, 8, 23, 22, 6, 255, 2, 28, 126, 171, 170, 42, 62, 255, 3, 138, 190, 171, 170, 42, 61, 10, 22, 28, 62, 14, 0, 130, 210, 14, 23, 194, 3, 11, 23, 30, 16, 14, 31, 22, 62, 255, 3, 138, 190, 8, 227, 130, 180, 255, 3, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 23, 26, 62, 12, 0, 8, 208, 8, 21, 0, 0, 11, 18, 4, 124, 12, 23, 26, 62, 106, 12, 140, 135, 11, 18, 2, 124, 134, 20, 16, 48, 12, 27, 20, 6, 106, 12, 234, 136, 10, 17, 16, 86, 255, 2, 20, 126, 0, 0, 128, 127, 255, 3, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 22, 124, 128, 16, 16, 0, 3, 15, 10, 125, 242, 16, 16, 16, 255, 2, 18, 126, 0, 0, 192, 127, 255, 3, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 10, 125, 10, 0, 4, 209, 3, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 210, 8, 19, 42, 0, 3, 19, 4, 125, 8, 19, 16, 0, 7, 19, 136, 125, 8, 7, 14, 0, 242, 6, 10, 125, 242, 14, 6, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 3, 138, 190, 61, 10, 135, 63, 3, 0, 130, 210, 3, 21, 28, 4, 4, 4, 254, 190, 2, 126, 254, 138, 242, 2, 6, 126, 2, 4, 254, 190, 106, 0, 16, 209, 4, 7, 1, 0, 4, 0, 0, 210, 4, 1, 169, 1, 242, 8, 28, 124, 2, 106, 254, 135, 223, 0, 136, 191, 128, 8, 8, 124, 106, 36, 132, 190, 128, 2, 8, 126, 4, 126, 254, 138, 217, 0, 136, 191, 255, 3, 136, 190, 28, 46, 77, 59, 8, 8, 8, 124, 106, 36, 136, 190, 255, 8, 8, 16, 82, 184, 78, 65, 8, 126, 254, 138, 242, 8, 8, 16, 208, 0, 136, 191, 255, 8, 14, 54, 255, 255, 255, 127, 242, 14, 16, 8, 255, 3, 138, 190, 0, 0, 128, 61, 106, 1, 22, 208, 8, 21, 0, 0, 126, 4, 138, 190, 10, 106, 254, 138, 7, 129, 16, 126, 69, 0, 136, 191, 129, 16, 18, 52, 255, 16, 16, 74, 0, 0, 128, 0, 255, 18, 18, 74, 0, 0, 0, 1, 255, 16, 20, 54, 0, 0, 127, 0, 255, 18, 18, 54, 0, 0, 1, 0, 9, 21, 18, 74, 144, 18, 20, 44, 128, 2, 22, 126, 10, 0, 194, 210, 10, 7, 1, 0, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 12, 106, 74, 210, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 80, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 10, 106, 74, 210, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 80, 0, 0, 52, 220, 10, 0, 0, 10, 255, 16, 16, 54, 255, 255, 127, 0, 240, 18, 18, 56, 240, 16, 16, 56, 9, 17, 16, 8, 113, 1, 140, 191, 13, 17, 18, 16, 12, 17, 18, 62, 255, 2, 28, 126, 171, 170, 170, 62, 255, 3, 140, 190, 0, 0, 128, 62, 7, 127, 30, 126, 12, 18, 28, 62, 12, 0, 130, 210, 12, 17, 38, 132, 193, 30, 30, 74, 14, 0, 130, 210, 9, 29, 194, 3, 9, 19, 32, 16, 13, 17, 24, 62, 15, 11, 16, 126, 14, 33, 24, 62, 255, 3, 140, 190, 244, 253, 5, 56, 12, 0, 130, 210, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 6, 8, 21, 16, 64, 0, 112, 49, 63, 12, 19, 30, 8, 255, 18, 28, 58, 0, 0, 0, 128, 8, 31, 26, 6, 10, 126, 254, 138, 8, 17, 18, 16, 21, 0, 136, 191, 8, 19, 20, 16, 255, 2, 22, 126, 171, 170, 42, 62, 255, 3, 140, 190, 37, 73, 18, 62, 12, 16, 22, 62, 8, 23, 22, 66, 205, 204, 76, 62, 8, 23, 22, 66, 0, 0, 128, 62, 8, 23, 22, 66, 171, 170, 170, 62, 10, 23, 20, 16, 241, 18, 28, 16, 15, 0, 130, 210, 9, 227, 41, 132, 15, 17, 26, 8, 255, 20, 24, 58, 0, 0, 0, 128, 255, 16, 16, 58, 0, 0, 0, 128, 10, 4, 254, 190, 8, 27, 20, 8, 15, 29, 18, 8, 15, 21, 20, 6, 12, 19, 18, 8, 255, 26, 22, 54, 0, 240, 255, 255, 9, 21, 18, 6, 13, 23, 16, 8, 9, 17, 16, 6, 255, 16, 18, 16, 0, 160, 42, 56, 11, 19, 18, 64, 0, 160, 42, 56, 8, 19, 16, 64, 0, 80, 213, 62, 11, 17, 18, 64, 0, 80, 213, 62, 255, 18, 20, 16, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 54, 131, 24, 24, 52, 255, 3, 139, 190, 85, 85, 85, 85, 255, 3, 138, 190, 85, 85, 85, 85, 12, 106, 74, 210, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 80, 210, 13, 1, 169, 1, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 138, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 130, 210, 10, 22, 38, 132, 14, 19, 30, 64, 0, 0, 49, 188, 8, 23, 16, 6, 14, 31, 22, 64, 239, 47, 228, 183, 8, 23, 22, 6, 255, 2, 28, 126, 171, 170, 42, 62, 255, 3, 138, 190, 171, 170, 42, 61, 10, 22, 28, 62, 14, 0, 130, 210, 14, 23, 194, 3, 11, 23, 30, 16, 14, 31, 22, 62, 255, 3, 138, 190, 8, 227, 130, 180, 255, 3, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 23, 26, 62, 12, 0, 8, 208, 8, 21, 0, 0, 11, 18, 4, 124, 12, 23, 26, 62, 106, 12, 140, 135, 11, 18, 2, 124, 134, 20, 16, 48, 12, 27, 20, 6, 106, 12, 234, 136, 10, 17, 16, 86, 255, 2, 20, 126, 0, 0, 128, 127, 255, 3, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 22, 124, 128, 16, 16, 0, 4, 15, 10, 125, 242, 16, 16, 16, 255, 2, 18, 126, 0, 0, 192, 127, 255, 3, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 10, 125, 10, 0, 4, 209, 4, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 210, 8, 19, 42, 0, 4, 19, 4, 125, 8, 19, 16, 0, 7, 19, 136, 125, 8, 9, 14, 0, 242, 8, 10, 125, 242, 14, 8, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 3, 138, 190, 61, 10, 135, 63, 4, 0, 130, 210, 4, 21, 28, 4, 4, 4, 254, 190, 2, 126, 254, 138, 242, 2, 8, 126, 2, 4, 254, 190, 14, 7, 132, 192, 106, 0, 16, 209, 5, 7, 1, 0, 5, 0, 0, 210, 5, 1, 169, 1, 127, 0, 140, 191, 8, 0, 34, 74, 9, 2, 36, 74, 10, 4, 38, 74, 242, 10, 28, 124, 106, 36, 130, 190, 223, 0, 136, 191, 128, 10, 8, 124, 106, 36, 132, 190, 128, 2, 10, 126, 4, 126, 254, 138, 217, 0, 136, 191, 255, 3, 136, 190, 28, 46, 77, 59, 8, 10, 8, 124, 106, 36, 136, 190, 255, 10, 10, 16, 82, 184, 78, 65, 8, 126, 254, 138, 242, 10, 10, 16, 208, 0, 136, 191, 255, 10, 14, 54, 255, 255, 255, 127, 242, 14, 16, 8, 255, 3, 138, 190, 0, 0, 128, 61, 106, 1, 22, 208, 8, 21, 0, 0, 126, 4, 138, 190, 10, 106, 254, 138, 7, 129, 16, 126, 69, 0, 136, 191, 129, 16, 18, 52, 255, 16, 16, 74, 0, 0, 128, 0, 255, 18, 18, 74, 0, 0, 0, 1, 255, 16, 20, 54, 0, 0, 127, 0, 255, 18, 18, 54, 0, 0, 1, 0, 9, 21, 18, 74, 144, 18, 20, 44, 128, 2, 22, 126, 10, 0, 194, 210, 10, 7, 1, 0, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 12, 106, 74, 210, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 80, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 141, 190, 85, 85, 85, 85, 255, 3, 140, 190, 85, 85, 85, 85, 10, 106, 74, 210, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 80, 0, 0, 52, 220, 10, 0, 0, 10, 255, 16, 16, 54, 255, 255, 127, 0, 240, 18, 18, 56, 240, 16, 16, 56, 9, 17, 16, 8, 113, 1, 140, 191, 13, 17, 18, 16, 12, 17, 18, 62, 255, 2, 28, 126, 171, 170, 170, 62, 255, 3, 140, 190, 0, 0, 128, 62, 7, 127, 30, 126, 12, 18, 28, 62, 12, 0, 130, 210, 12, 17, 38, 132, 193, 30, 30, 74, 14, 0, 130, 210, 9, 29, 194, 3, 9, 19, 32, 16, 13, 17, 24, 62, 15, 11, 16, 126, 14, 33, 24, 62, 255, 3, 140, 190, 244, 253, 5, 56, 12, 0, 130, 210, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 6, 8, 21, 16, 64, 0, 112, 49, 63, 12, 19, 26, 8, 255, 18, 28, 58, 0, 0, 0, 128, 8, 27, 30, 6, 10, 126, 254, 138, 8, 17, 18, 16, 21, 0, 136, 191, 8, 19, 20, 16, 255, 2, 22, 126, 171, 170, 42, 62, 255, 3, 140, 190, 37, 73, 18, 62, 12, 16, 22, 62, 8, 23, 22, 66, 205, 204, 76, 62, 8, 23, 22, 66, 0, 0, 128, 62, 8, 23, 22, 66, 171, 170, 170, 62, 10, 23, 20, 16, 241, 18, 28, 16, 13, 0, 130, 210, 9, 227, 41, 132, 13, 17, 30, 8, 255, 20, 24, 58, 0, 0, 0, 128, 255, 16, 16, 58, 0, 0, 0, 128, 10, 4, 254, 190, 8, 31, 16, 8, 13, 29, 20, 8, 13, 17, 16, 6, 12, 21, 18, 8, 255, 30, 20, 54, 0, 240, 255, 255, 9, 17, 16, 6, 15, 21, 18, 8, 8, 19, 16, 6, 255, 16, 18, 16, 0, 160, 42, 56, 10, 19, 18, 64, 0, 160, 42, 56, 8, 19, 16, 64, 0, 80, 213, 62, 10, 17, 18, 64, 0, 80, 213, 62, 255, 18, 22, 16, 59, 170, 184, 66, 11, 17, 22, 126, 191, 22, 24, 54, 131, 24, 24, 52, 255, 3, 139, 190, 85, 85, 85, 85, 255, 3, 138, 190, 85, 85, 85, 85, 12, 106, 74, 210, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 80, 210, 13, 1, 169, 1, 0, 0, 52, 220, 12, 0, 0, 12, 255, 3, 138, 190, 0, 80, 213, 62, 11, 11, 28, 126, 10, 0, 130, 210, 10, 20, 38, 132, 14, 19, 30, 64, 0, 0, 49, 188, 8, 21, 16, 6, 14, 31, 20, 64, 239, 47, 228, 183, 8, 21, 20, 6, 255, 2, 28, 126, 171, 170, 42, 62, 255, 3, 138, 190, 171, 170, 42, 61, 10, 20, 28, 62, 14, 0, 130, 210, 14, 21, 194, 3, 10, 21, 30, 16, 14, 31, 20, 62, 255, 3, 138, 190, 8, 227, 130, 180, 255, 3, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 21, 26, 62, 12, 0, 8, 208, 8, 21, 0, 0, 11, 18, 4, 124, 12, 21, 26, 62, 106, 12, 140, 135, 11, 18, 2, 124, 134, 22, 16, 48, 12, 27, 20, 6, 106, 12, 234, 136, 10, 17, 16, 86, 255, 2, 20, 126, 0, 0, 128, 127, 255, 3, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 22, 124, 128, 16, 16, 0, 5, 15, 10, 125, 242, 16, 16, 16, 255, 2, 18, 126, 0, 0, 192, 127, 255, 3, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 10, 125, 10, 0, 4, 209, 5, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 210, 8, 19, 42, 0, 5, 19, 4, 125, 8, 19, 16, 0, 7, 19, 136, 125, 8, 11, 14, 0, 242, 10, 10, 125, 242, 14, 10, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 3, 138, 190, 61, 10, 135, 63, 5, 0, 130, 210, 5, 21, 28, 4, 4, 4, 254, 190, 2, 126, 254, 138, 242, 2, 10, 126, 2, 4, 254, 190, 8, 7, 65, 192, 127, 0, 140, 191, 0, 3, 194, 192, 128, 2, 40, 126, 127, 0, 140, 191, 0, 95, 32, 240, 17, 3, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 18, 7, 70, 192, 20, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 12, 209, 1, 27, 0, 0, 8, 0, 12, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 136, 3, 4, 6, 125, 0, 106, 234, 136, 126, 4, 128, 190, 0, 106, 254, 138, 22, 0, 136, 191, 6, 7, 132, 192, 10, 7, 65, 192, 12, 7, 2, 192, 127, 0, 140, 191, 0, 9, 198, 192, 2, 0, 6, 74, 3, 2, 8, 74, 4, 4, 10, 74, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 14, 7, 130, 192, 0, 11, 196, 192, 127, 0, 140, 191, 4, 0, 14, 74, 5, 2, 16, 74, 6, 4, 18, 74, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 172, 0, 144, 0, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 5, 0, 5, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 192, 127, 0, 140, 191, 0, 255, 0, 135, 255, 255, 0, 0, 0, 8, 0, 147, 0, 7, 65, 192, 18, 135, 0, 192, 127, 0, 140, 191, 0, 2, 0, 128, 0, 0, 0, 74, 1, 0, 8, 125, 106, 36, 128, 190, 15, 0, 136, 191, 6, 7, 132, 192, 10, 7, 1, 192, 127, 0, 140, 191, 0, 9, 134, 192, 2, 0, 2, 74, 127, 0, 140, 191, 0, 32, 12, 224, 1, 1, 3, 128, 14, 7, 1, 192, 0, 11, 130, 192, 127, 0, 140, 191, 2, 0, 0, 74, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 66, 192, 18, 135, 1, 192, 127, 0, 140, 191, 2, 4, 2, 128, 2, 0, 0, 74, 3, 0, 8, 125, 106, 36, 130, 190, 22, 0, 136, 191, 2, 7, 196, 192, 10, 7, 2, 192, 127, 0, 140, 191, 0, 13, 136, 192, 4, 0, 6, 74, 127, 0, 140, 191, 0, 32, 12, 224, 3, 3, 4, 128, 14, 7, 130, 192, 0, 15, 198, 192, 1, 10, 1, 128, 0, 8, 0, 128, 127, 0, 140, 191, 1, 6, 1, 128, 0, 5, 0, 128, 4, 0, 14, 74, 1, 4, 18, 74, 0, 2, 16, 74, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 3, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 7, 0, 7, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 66, 192, 18, 135, 1, 192, 127, 0, 140, 191, 2, 4, 2, 128, 2, 0, 0, 74, 3, 0, 8, 125, 106, 36, 130, 190, 23, 0, 136, 191, 2, 7, 196, 192, 10, 7, 66, 192, 127, 0, 140, 191, 12, 135, 4, 192, 0, 13, 200, 192, 1, 10, 1, 128, 0, 8, 0, 128, 127, 0, 140, 191, 1, 9, 1, 128, 0, 5, 0, 128, 4, 0, 6, 74, 1, 4, 10, 74, 0, 2, 8, 74, 128, 2, 12, 126, 0, 95, 0, 240, 3, 1, 4, 0, 14, 7, 0, 192, 0, 15, 130, 192, 127, 0, 140, 191, 0, 0, 0, 74, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 64, 192, 127, 0, 140, 191, 0, 255, 2, 135, 255, 255, 0, 0, 0, 255, 128, 147, 16, 0, 16, 0, 1, 255, 1, 135, 255, 255, 0, 0, 2, 8, 2, 147, 0, 9, 0, 147, 1, 10, 1, 147, 0, 7, 132, 192, 4, 7, 66, 192, 24, 7, 70, 192, 26, 135, 1, 192, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 74, 0, 2, 2, 74, 1, 4, 0, 128, 4, 0, 2, 209, 1, 27, 0, 0, 8, 0, 2, 209, 0, 25, 0, 0, 0, 4, 4, 74, 8, 4, 128, 135, 3, 4, 8, 125, 0, 106, 128, 135, 0, 36, 128, 190, 46, 0, 136, 191, 20, 7, 132, 192, 127, 0, 140, 191, 8, 0, 14, 74, 9, 2, 16, 74, 10, 4, 18, 74, 28, 7, 1, 192, 6, 7, 66, 192, 127, 0, 140, 191, 2, 130, 0, 191, 26, 0, 133, 191, 2, 129, 0, 191, 11, 0, 132, 191, 12, 7, 132, 192, 0, 5, 198, 192, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 23, 0, 130, 191, 2, 128, 0, 191, 21, 0, 132, 191, 8, 7, 132, 192, 0, 5, 198, 192, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 10, 0, 130, 191, 16, 7, 132, 192, 0, 5, 198, 192, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 172, 0, 144, 0, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 5, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 192, 127, 0, 140, 191, 0, 255, 0, 135, 255, 255, 0, 0, 0, 8, 0, 147, 0, 7, 65, 192, 24, 135, 0, 192, 127, 0, 140, 191, 0, 2, 0, 128, 0, 0, 0, 74, 1, 0, 8, 125, 106, 36, 128, 190, 41, 0, 136, 191, 20, 7, 1, 192, 127, 0, 140, 191, 2, 0, 0, 74, 28, 7, 1, 192, 6, 7, 66, 192, 127, 0, 140, 191, 2, 130, 0, 191, 24, 0, 133, 191, 2, 129, 0, 191, 10, 0, 132, 191, 12, 7, 132, 192, 0, 5, 130, 192, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 21, 0, 130, 191, 2, 128, 0, 191, 19, 0, 132, 191, 8, 7, 132, 192, 0, 5, 130, 192, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 9, 0, 130, 191, 16, 7, 132, 192, 0, 5, 130, 192, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 1, 0, 4, 0, 8, 2, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 0, 4, 0, 16, 6, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 26, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 4, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 26, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 132, 4, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 26, 0, 5, 0, 0, 10, 0, 0, 0, 0, 0, 0, 220, 1, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 26, 0, 5, 0, 0, 12, 0, 0, 0, 0, 0, 0, 212, 12, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 26, 0, 5, 0, 0, 25, 0, 0, 0, 0, 0, 0, 220, 1, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 26, 0, 5, 0, 0, 27, 0, 0, 0, 0, 0, 0, 116, 1, 0, 0, 0, 0, 0, 0, 58, 1, 0, 0, 26, 0, 5, 0, 0, 29, 0, 0, 0, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 90, 1, 0, 0, 26, 0, 5, 0, 0, 31, 0, 0, 0, 0, 0, 0, 172, 1, 0, 0, 0, 0, 0, 0, 122, 1, 0, 0, 26, 0, 5, 0, 0, 33, 0, 0, 0, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 144, 1, 0, 0, 26, 0, 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 220, 1, 0, 0, 0, 0, 0, 0, 170, 1, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 1, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 14, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 14, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 14, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 14, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 18, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 18, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 18, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 18, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 19, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 19, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 21, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 21, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 21, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 21, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 23, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 23, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 2, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 3, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 1, 0, 0, 0, 7, 0, 192, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 220, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 51, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 53, 0, 0, 0, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0};\n}\n}\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_object_gfx8xx.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <stdint.h>\nnamespace rocr {\nnamespace image {\nuint8_t blit_object_gfx8xx[] = {127, 69, 76, 70, 2, 1, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 224, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 56, 0, 2, 0, 64, 0, 8, 0, 1, 0, 2, 0, 0, 96, 6, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 96, 5, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 41, 0, 0, 0, 0, 0, 0, 12, 41, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 115, 104, 115, 116, 114, 116, 97, 98, 0, 46, 115, 116, 114, 116, 97, 98, 0, 46, 110, 111, 116, 101, 0, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 46, 104, 115, 97, 116, 101, 120, 116, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 114, 101, 108, 97, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 69, 88, 80, 95, 69, 80, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 69, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 95, 73, 78, 86, 95, 69, 80, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 116, 111, 95, 98, 117, 102, 102, 101, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 98, 117, 102, 102, 101, 114, 95, 116, 111, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 100, 101, 102, 97, 117, 108, 116, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 108, 105, 110, 101, 97, 114, 95, 116, 111, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 116, 111, 95, 108, 105, 110, 101, 97, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 116, 111, 95, 114, 101, 103, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 114, 101, 103, 95, 116, 111, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0, 4, 0, 0, 0, 26, 0, 0, 0, 3, 0, 0, 0, 65, 77, 68, 0, 4, 0, 7, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 0, 65, 77, 68, 71, 80, 85, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 4, 0, 0, 0, 65, 77, 68, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 32, 72, 83, 65, 32, 82, 117, 110, 116, 105, 109, 101, 32, 70, 105, 110, 97, 108, 105, 122, 101, 114, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 65, 77, 68, 0, 22, 0, 45, 104, 115, 97, 95, 99, 97, 108, 108, 95, 99, 111, 110, 118, 101, 110, 116, 105, 111, 110, 61, 48, 0, 197, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 96, 129, 63, 119, 62, 26, 57, 0, 192, 130, 63, 138, 105, 216, 57, 0, 32, 132, 63, 29, 70, 81, 58, 0, 160, 133, 63, 124, 54, 172, 57, 0, 0, 135, 63, 180, 12, 123, 58, 0, 128, 136, 63, 4, 116, 64, 58, 0, 0, 138, 63, 170, 171, 38, 58, 0, 128, 139, 63, 31, 15, 46, 58, 0, 0, 141, 63, 219, 250, 86, 58, 0, 160, 142, 63, 104, 49, 7, 57, 0, 32, 144, 63, 24, 226, 14, 58, 0, 192, 145, 63, 234, 220, 244, 56, 0, 64, 147, 63, 120, 89, 81, 58, 0, 224, 148, 63, 71, 125, 39, 58, 0, 128, 150, 63, 185, 105, 33, 58, 0, 32, 152, 63, 140, 130, 63, 58, 0, 224, 153, 63, 65, 38, 11, 55, 0, 128, 155, 63, 157, 155, 211, 57, 0, 32, 157, 63, 57, 205, 118, 58, 0, 224, 158, 63, 4, 147, 41, 58, 0, 160, 160, 63, 125, 136, 2, 58, 0, 96, 162, 63, 24, 24, 2, 58, 0, 32, 164, 63, 112, 173, 40, 58, 0, 224, 165, 63, 77, 181, 118, 58, 0, 192, 167, 63, 78, 59, 217, 57, 0, 160, 169, 63, 117, 90, 45, 56, 0, 96, 171, 63, 173, 205, 81, 58, 0, 64, 173, 63, 82, 247, 65, 58, 0, 32, 175, 63, 107, 197, 91, 58, 0, 32, 177, 63, 116, 96, 253, 56, 0, 0, 179, 63, 149, 32, 14, 58, 0, 0, 181, 63, 127, 102, 30, 57, 0, 224, 182, 63, 25, 143, 108, 58, 0, 224, 184, 63, 59, 122, 93, 58, 0, 224, 186, 63, 144, 213, 122, 58, 0, 0, 189, 63, 245, 57, 138, 57, 0, 0, 191, 63, 179, 205, 60, 58, 0, 32, 193, 63, 166, 204, 196, 57, 0, 64, 195, 63, 68, 155, 89, 57, 0, 96, 197, 63, 42, 66, 101, 57, 0, 128, 199, 63, 138, 76, 215, 57, 0, 160, 201, 63, 51, 236, 77, 58, 0, 224, 203, 63, 239, 79, 193, 57, 0, 32, 206, 63, 163, 130, 17, 57, 0, 96, 208, 63, 187, 246, 204, 56, 0, 160, 210, 63, 31, 217, 129, 57, 0, 224, 212, 63, 94, 213, 26, 58, 0, 64, 215, 63, 90, 153, 31, 57, 0, 128, 217, 63, 19, 174, 104, 58, 0, 224, 219, 63, 190, 188, 93, 58, 0, 96, 222, 63, 94, 130, 244, 55, 0, 192, 224, 63, 194, 238, 205, 57, 0, 32, 227, 63, 149, 75, 124, 58, 0, 160, 229, 63, 59, 55, 72, 58, 0, 32, 232, 63, 129, 82, 75, 58, 0, 192, 234, 63, 221, 231, 198, 55, 0, 64, 237, 63, 237, 1, 243, 57, 0, 224, 239, 63, 123, 51, 23, 57, 0, 128, 242, 63, 44, 158, 59, 56, 0, 32, 245, 63, 164, 162, 47, 57, 0, 192, 247, 63, 152, 251, 6, 58, 0, 128, 250, 63, 220, 182, 236, 56, 0, 32, 253, 63, 103, 96, 112, 58, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 59, 65, 172, 41, 52, 0, 0, 126, 60, 252, 176, 168, 53, 0, 192, 189, 60, 234, 131, 141, 54, 0, 16, 252, 60, 120, 14, 27, 54, 0, 240, 28, 61, 254, 185, 135, 54, 0, 160, 59, 61, 101, 236, 49, 54, 0, 16, 90, 61, 25, 113, 221, 54, 0, 80, 120, 61, 69, 0, 195, 53, 0, 32, 139, 61, 81, 119, 155, 55, 0, 0, 154, 61, 13, 203, 235, 55, 0, 208, 168, 61, 131, 159, 131, 55, 0, 128, 183, 61, 229, 138, 82, 55, 0, 16, 198, 61, 24, 235, 162, 55, 0, 144, 212, 61, 149, 116, 218, 54, 0, 240, 226, 61, 183, 30, 169, 54, 0, 48, 241, 61, 21, 183, 131, 55, 0, 96, 255, 61, 219, 49, 17, 55, 0, 176, 6, 62, 104, 62, 63, 56, 0, 176, 13, 62, 151, 106, 21, 56, 0, 160, 20, 62, 15, 124, 41, 56, 0, 128, 27, 62, 15, 16, 126, 56, 0, 96, 34, 62, 101, 182, 21, 56, 0, 48, 41, 62, 161, 227, 229, 55, 0, 240, 47, 62, 83, 56, 24, 56, 0, 176, 54, 62, 157, 113, 254, 53, 0, 80, 61, 62, 8, 129, 68, 56, 0, 240, 67, 62, 144, 50, 80, 56, 0, 144, 74, 62, 232, 57, 53, 55, 0, 16, 81, 62, 241, 15, 94, 56, 0, 144, 87, 62, 64, 167, 100, 56, 0, 16, 94, 62, 45, 116, 134, 55, 0, 112, 100, 62, 205, 227, 123, 56, 0, 224, 106, 62, 62, 173, 133, 54, 0, 48, 113, 62, 21, 183, 3, 56, 0, 128, 119, 62, 220, 203, 173, 55, 0, 192, 125, 62, 175, 54, 12, 56, 0, 0, 130, 62, 211, 82, 22, 55, 0, 16, 133, 62, 57, 113, 146, 56, 0, 32, 136, 62, 215, 252, 197, 56, 0, 48, 139, 62, 213, 85, 174, 56, 0, 64, 142, 62, 105, 193, 24, 56, 0, 64, 145, 62, 231, 253, 160, 56, 0, 64, 148, 62, 239, 9, 173, 56, 0, 64, 151, 62, 225, 186, 98, 56, 0, 48, 154, 62, 76, 205, 238, 56, 0, 48, 157, 62, 210, 170, 152, 55, 0, 32, 160, 62, 26, 26, 66, 55, 0, 0, 163, 62, 14, 225, 197, 56, 0, 240, 165, 62, 238, 42, 191, 55, 0, 208, 168, 62, 45, 135, 45, 56, 0, 176, 171, 62, 138, 46, 238, 55, 0, 128, 174, 62, 172, 223, 222, 56, 0, 96, 177, 62, 185, 242, 2, 56, 0, 48, 180, 62, 155, 30, 72, 56, 0, 0, 183, 62, 43, 170, 14, 56, 0, 192, 185, 62, 93, 251, 235, 56, 0, 144, 188, 62, 221, 95, 37, 56, 0, 80, 191, 62, 130, 59, 120, 56, 0, 16, 194, 62, 30, 218, 81, 56, 0, 208, 196, 62, 5, 27, 78, 55, 0, 128, 199, 62, 155, 67, 143, 56, 0, 48, 202, 62, 16, 14, 202, 56, 0, 224, 204, 62, 139, 192, 202, 56, 0, 144, 207, 62, 95, 246, 145, 56, 0, 64, 210, 62, 203, 33, 129, 55, 0, 224, 212, 62, 154, 154, 108, 56, 0, 128, 215, 62, 35, 153, 148, 56, 0, 32, 218, 62, 204, 123, 119, 56, 0, 192, 220, 62, 38, 45, 177, 55, 0, 80, 223, 62, 211, 206, 166, 56, 0, 224, 225, 62, 230, 211, 235, 56, 0, 112, 228, 62, 205, 227, 251, 56, 0, 0, 231, 62, 194, 133, 215, 56, 0, 144, 233, 62, 0, 126, 126, 56, 0, 16, 236, 62, 197, 146, 243, 56, 0, 160, 238, 62, 131, 9, 212, 55, 0, 32, 241, 62, 124, 26, 8, 56, 0, 160, 243, 62, 173, 195, 132, 55, 0, 16, 246, 62, 35, 233, 204, 56, 0, 144, 248, 62, 175, 95, 15, 56, 0, 0, 251, 62, 56, 253, 145, 56, 0, 112, 253, 62, 188, 71, 172, 56, 0, 224, 255, 62, 43, 4, 151, 56, 0, 32, 1, 63, 210, 82, 41, 57, 0, 80, 2, 63, 212, 206, 111, 57, 0, 144, 3, 63, 115, 112, 249, 55, 0, 192, 4, 63, 174, 158, 94, 56, 0, 240, 5, 63, 74, 200, 101, 56, 0, 32, 7, 63, 163, 11, 19, 56, 0, 64, 8, 63, 22, 207, 121, 57, 0, 112, 9, 63, 201, 202, 56, 57, 0, 160, 10, 63, 244, 210, 195, 56, 0, 192, 11, 63, 236, 93, 117, 57, 0, 240, 12, 63, 103, 180, 230, 56, 0, 16, 14, 63, 184, 15, 92, 57, 0, 64, 15, 63, 224, 188, 62, 56, 0, 96, 16, 63, 146, 209, 220, 56, 0, 128, 17, 63, 223, 107, 24, 57, 0, 160, 18, 63, 76, 231, 45, 57, 0, 192, 19, 63, 68, 9, 47, 57, 0, 224, 20, 63, 97, 255, 27, 57, 0, 0, 22, 63, 68, 237, 233, 56, 0, 32, 23, 63, 200, 109, 104, 56, 0, 48, 24, 63, 167, 153, 107, 57, 0, 80, 25, 63, 137, 156, 9, 57, 0, 112, 26, 63, 115, 118, 162, 55, 0, 128, 27, 63, 163, 218, 11, 57, 0, 144, 28, 63, 171, 105, 112, 57, 0, 176, 29, 63, 255, 73, 132, 56, 0, 192, 30, 63, 56, 53, 1, 57, 0, 208, 31, 63, 104, 194, 45, 57, 0, 224, 32, 63, 35, 244, 71, 57, 0, 240, 33, 63, 124, 241, 79, 57, 0, 0, 35, 63, 14, 225, 69, 57, 0, 16, 36, 63, 245, 232, 41, 57, 0, 32, 37, 63, 176, 93, 248, 56, 0, 48, 38, 63, 153, 95, 115, 56, 0, 48, 39, 63, 219, 8, 108, 57, 0, 64, 40, 63, 0, 230, 9, 57, 0, 80, 41, 63, 111, 153, 180, 55, 0, 80, 42, 63, 204, 51, 18, 57, 0, 80, 43, 63, 217, 234, 124, 57, 0, 96, 44, 63, 205, 181, 173, 56, 0, 96, 45, 63, 26, 38, 32, 57, 0, 96, 46, 63, 54, 238, 88, 57, 0, 112, 47, 63, 5, 73, 170, 53, 0, 112, 48, 63, 30, 209, 203, 55, 0, 112, 49, 63, 244, 253, 5, 56, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 254, 63, 248, 3, 254, 56, 0, 0, 252, 63, 193, 15, 252, 57, 0, 0, 250, 63, 201, 179, 140, 58, 0, 0, 248, 63, 16, 62, 248, 58, 0, 0, 246, 63, 48, 123, 64, 59, 0, 0, 244, 63, 96, 141, 137, 59, 0, 0, 242, 63, 72, 214, 185, 59, 0, 0, 240, 63, 241, 240, 240, 59, 0, 0, 239, 63, 127, 220, 186, 58, 0, 0, 237, 63, 108, 7, 102, 59, 0, 0, 235, 63, 166, 178, 189, 59, 0, 0, 234, 63, 161, 14, 234, 57, 0, 0, 232, 63, 247, 88, 75, 59, 0, 0, 230, 63, 72, 180, 194, 59, 0, 0, 229, 63, 172, 96, 150, 58, 0, 0, 227, 63, 228, 56, 142, 59, 0, 0, 225, 63, 14, 120, 252, 59, 0, 0, 224, 63, 56, 112, 96, 59, 0, 0, 222, 63, 77, 92, 233, 59, 0, 0, 221, 63, 76, 145, 79, 59, 0, 0, 219, 63, 239, 97, 235, 59, 0, 0, 218, 63, 79, 27, 104, 59, 0, 0, 217, 63, 178, 1, 89, 56, 0, 0, 215, 63, 229, 53, 148, 59, 0, 0, 214, 63, 89, 3, 174, 58, 0, 0, 212, 63, 3, 123, 199, 59, 0, 0, 211, 63, 109, 26, 80, 59, 0, 0, 210, 63, 33, 13, 210, 57, 0, 0, 208, 63, 204, 159, 182, 59, 0, 0, 207, 63, 81, 233, 72, 59, 0, 0, 206, 63, 185, 83, 52, 58, 0, 0, 204, 63, 205, 204, 204, 59, 0, 0, 203, 63, 192, 39, 135, 59, 0, 0, 202, 63, 205, 15, 11, 59, 0, 0, 201, 63, 209, 73, 123, 57, 0, 0, 199, 63, 125, 12, 206, 59, 0, 0, 198, 63, 106, 12, 152, 59, 0, 0, 197, 63, 247, 144, 75, 59, 0, 0, 196, 63, 21, 190, 220, 58, 0, 0, 195, 63, 49, 12, 195, 57, 0, 0, 193, 63, 214, 187, 228, 59, 0, 0, 192, 63, 193, 192, 192, 59, 0, 0, 191, 63, 232, 47, 160, 59, 0, 0, 190, 63, 12, 250, 130, 59, 0, 0, 189, 63, 142, 32, 82, 59, 0, 0, 188, 63, 24, 200, 36, 59, 0, 0, 187, 63, 135, 156, 251, 58, 0, 0, 186, 63, 140, 46, 186, 58, 0, 0, 185, 63, 233, 15, 133, 58, 0, 0, 184, 63, 3, 23, 56, 58, 0, 0, 183, 63, 162, 181, 251, 57, 0, 0, 182, 63, 97, 11, 182, 57, 0, 0, 181, 63, 170, 104, 158, 57, 0, 0, 180, 63, 65, 11, 180, 57, 0, 0, 179, 63, 41, 53, 246, 57, 0, 0, 178, 63, 67, 22, 50, 58, 0, 0, 177, 63, 192, 157, 126, 58, 0, 0, 176, 63, 11, 44, 176, 58, 0, 0, 175, 63, 26, 119, 235, 58, 0, 0, 174, 63, 185, 130, 24, 59, 0, 0, 173, 63, 176, 86, 64, 59, 0, 0, 172, 63, 8, 35, 109, 59, 0, 0, 171, 63, 227, 105, 143, 59, 0, 0, 170, 63, 171, 170, 170, 59, 0, 0, 169, 63, 72, 74, 200, 59, 0, 0, 168, 63, 87, 63, 232, 59, 0, 0, 168, 63, 129, 10, 168, 57, 0, 0, 167, 63, 230, 20, 188, 58, 0, 0, 166, 63, 114, 136, 43, 59, 0, 0, 165, 63, 5, 106, 125, 59, 0, 0, 164, 63, 30, 207, 169, 59, 0, 0, 163, 63, 61, 10, 215, 59, 0, 0, 163, 63, 246, 199, 75, 57, 0, 0, 162, 63, 172, 12, 223, 58, 0, 0, 161, 63, 93, 98, 86, 59, 0, 0, 160, 63, 161, 160, 160, 59, 0, 0, 159, 63, 254, 9, 216, 59, 0, 0, 159, 63, 57, 47, 11, 58, 0, 0, 158, 63, 72, 90, 25, 59, 0, 0, 157, 63, 158, 216, 137, 59, 0, 0, 156, 63, 97, 225, 200, 59, 0, 0, 156, 63, 193, 9, 156, 57, 0, 0, 155, 63, 62, 223, 24, 59, 0, 0, 154, 63, 217, 231, 144, 59, 0, 0, 153, 63, 219, 34, 215, 59, 0, 0, 153, 63, 139, 210, 120, 58, 0, 0, 152, 63, 19, 144, 81, 59, 0, 0, 151, 63, 237, 37, 180, 59, 0, 0, 151, 63, 46, 1, 23, 56, 0, 0, 150, 63, 216, 180, 31, 59, 0, 0, 149, 63, 104, 37, 160, 59, 0, 0, 148, 63, 79, 9, 242, 59, 0, 0, 148, 63, 41, 1, 11, 59, 0, 0, 147, 63, 196, 133, 154, 59, 0, 0, 146, 63, 132, 19, 241, 59, 0, 0, 146, 63, 37, 73, 18, 59, 0, 0, 145, 63, 197, 179, 162, 59, 0, 0, 144, 63, 9, 188, 253, 59, 0, 0, 144, 63, 198, 112, 52, 59, 0, 0, 143, 63, 238, 35, 184, 59, 0, 0, 143, 63, 208, 206, 59, 58, 0, 0, 142, 63, 218, 106, 112, 59, 0, 0, 141, 63, 2, 82, 218, 59, 0, 0, 141, 63, 35, 44, 247, 58, 0, 0, 140, 63, 4, 156, 162, 59, 0, 0, 140, 63, 193, 8, 140, 57, 0, 0, 139, 63, 148, 104, 96, 59, 0, 0, 138, 63, 252, 242, 216, 59, 0, 0, 138, 63, 225, 240, 5, 59, 0, 0, 137, 63, 138, 64, 174, 59, 0, 0, 137, 63, 215, 57, 86, 58, 0, 0, 136, 63, 137, 136, 136, 59, 0, 0, 135, 63, 136, 128, 247, 59, 0, 0, 135, 63, 190, 86, 79, 59, 0, 0, 134, 63, 68, 5, 217, 59, 0, 0, 134, 63, 252, 20, 23, 59, 0, 0, 133, 63, 97, 55, 191, 59, 0, 0, 133, 63, 77, 33, 208, 58, 0, 0, 132, 63, 200, 249, 169, 59, 0, 0, 132, 63, 8, 33, 132, 58, 0, 0, 131, 63, 82, 48, 153, 59, 0, 0, 131, 63, 188, 116, 19, 58, 0, 0, 130, 63, 191, 191, 140, 59, 0, 0, 130, 63, 33, 8, 130, 57, 0, 0, 129, 63, 169, 141, 132, 59, 0, 0, 129, 63, 4, 2, 129, 56, 0, 0, 128, 63, 129, 128, 128, 59, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 11, 0, 11, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 104, 0, 0, 0, 195, 0, 2, 192, 112, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 193, 208, 1, 27, 0, 0, 8, 0, 193, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 134, 3, 4, 136, 125, 0, 106, 128, 134, 0, 32, 128, 190, 199, 0, 136, 191, 131, 0, 6, 192, 24, 0, 0, 0, 3, 1, 6, 192, 56, 0, 0, 0, 3, 2, 2, 192, 64, 0, 0, 0, 131, 2, 6, 192, 72, 0, 0, 0, 67, 2, 2, 192, 128, 0, 0, 0, 3, 3, 10, 192, 136, 0, 0, 0, 159, 0, 6, 34, 159, 2, 8, 34, 127, 0, 140, 191, 5, 0, 134, 210, 1, 25, 0, 0, 4, 0, 133, 210, 4, 25, 0, 0, 4, 11, 8, 50, 5, 0, 133, 210, 1, 27, 0, 0, 5, 9, 8, 50, 5, 0, 133, 210, 1, 25, 0, 0, 5, 106, 25, 209, 5, 1, 2, 0, 4, 7, 6, 56, 4, 0, 14, 50, 5, 2, 16, 50, 8, 4, 18, 50, 159, 4, 12, 34, 1, 4, 14, 192, 0, 0, 0, 0, 128, 2, 20, 126, 127, 0, 140, 191, 0, 95, 0, 240, 7, 7, 4, 0, 0, 0, 134, 210, 2, 29, 0, 0, 1, 0, 133, 210, 6, 29, 0, 0, 1, 1, 0, 50, 1, 0, 133, 210, 2, 31, 0, 0, 1, 1, 0, 50, 1, 0, 133, 210, 2, 29, 0, 0, 1, 106, 25, 209, 1, 11, 2, 0, 0, 7, 0, 56, 2, 0, 134, 210, 1, 19, 0, 0, 0, 0, 133, 210, 0, 19, 0, 0, 0, 5, 0, 50, 1, 0, 133, 210, 1, 19, 0, 0, 3, 106, 25, 209, 1, 21, 0, 0, 11, 2, 4, 126, 0, 5, 8, 56, 131, 0, 6, 192, 120, 0, 0, 0, 3, 1, 6, 192, 32, 0, 0, 0, 127, 0, 140, 191, 2, 132, 0, 191, 85, 0, 133, 191, 3, 2, 6, 192, 40, 0, 0, 0, 2, 130, 0, 191, 41, 0, 132, 191, 3, 132, 0, 191, 29, 0, 133, 191, 3, 130, 0, 191, 12, 0, 132, 191, 0, 0, 143, 210, 130, 6, 2, 0, 112, 15, 140, 191, 144, 16, 4, 36, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 6, 126, 3, 3, 2, 56, 2, 15, 4, 40, 0, 0, 112, 220, 0, 2, 0, 0, 110, 0, 130, 191, 3, 129, 0, 191, 108, 0, 132, 191, 0, 0, 143, 210, 129, 6, 2, 0, 112, 15, 140, 191, 136, 16, 4, 36, 127, 0, 140, 191, 0, 106, 25, 209, 8, 0, 2, 0, 9, 2, 6, 126, 3, 3, 2, 56, 2, 15, 4, 40, 0, 0, 104, 220, 0, 2, 0, 0, 95, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 0, 116, 220, 0, 7, 0, 0, 85, 0, 130, 191, 2, 129, 0, 191, 83, 0, 132, 191, 3, 132, 0, 191, 26, 0, 133, 191, 3, 130, 0, 191, 11, 0, 132, 191, 0, 0, 143, 210, 129, 6, 2, 0, 127, 0, 140, 191, 0, 106, 25, 209, 8, 0, 2, 0, 9, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 0, 104, 220, 0, 7, 0, 0, 68, 0, 130, 191, 3, 129, 0, 191, 66, 0, 132, 191, 131, 0, 6, 192, 48, 0, 0, 0, 127, 0, 140, 191, 0, 106, 25, 209, 2, 6, 2, 0, 3, 2, 4, 126, 2, 9, 2, 56, 112, 15, 140, 191, 0, 0, 96, 220, 0, 7, 0, 0, 55, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 0, 112, 220, 0, 7, 0, 0, 45, 0, 130, 191, 3, 132, 0, 191, 34, 0, 133, 191, 3, 130, 0, 191, 14, 0, 132, 191, 112, 15, 140, 191, 144, 16, 0, 36, 0, 15, 10, 40, 1, 0, 143, 210, 130, 6, 2, 0, 1, 106, 25, 209, 4, 2, 2, 0, 5, 2, 6, 126, 3, 5, 4, 56, 144, 20, 6, 36, 3, 19, 12, 40, 0, 0, 116, 220, 1, 5, 0, 0, 27, 0, 130, 191, 3, 129, 0, 191, 25, 0, 132, 191, 112, 15, 140, 191, 136, 16, 0, 36, 0, 15, 0, 40, 144, 18, 2, 36, 2, 0, 143, 210, 130, 6, 2, 0, 0, 3, 0, 40, 152, 20, 2, 36, 2, 106, 25, 209, 4, 4, 2, 0, 5, 2, 8, 126, 4, 7, 6, 56, 0, 3, 0, 40, 0, 0, 112, 220, 2, 0, 0, 0, 9, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 0, 124, 220, 0, 7, 0, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 19, 0, 19, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 88, 0, 0, 0, 195, 0, 2, 192, 96, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 193, 208, 1, 27, 0, 0, 8, 0, 193, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 134, 3, 4, 136, 125, 0, 106, 128, 134, 0, 32, 128, 190, 206, 0, 136, 191, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 6, 192, 72, 0, 0, 0, 3, 2, 2, 192, 80, 0, 0, 0, 67, 2, 2, 192, 112, 0, 0, 0, 3, 3, 10, 192, 120, 0, 0, 0, 159, 0, 6, 34, 159, 2, 8, 34, 127, 0, 140, 191, 5, 0, 134, 210, 1, 25, 0, 0, 4, 0, 133, 210, 4, 25, 0, 0, 4, 11, 8, 50, 5, 0, 133, 210, 1, 27, 0, 0, 5, 9, 8, 50, 5, 0, 133, 210, 1, 25, 0, 0, 5, 106, 25, 209, 5, 1, 2, 0, 4, 7, 6, 56, 159, 4, 8, 34, 6, 0, 134, 210, 2, 29, 0, 0, 4, 0, 133, 210, 4, 29, 0, 0, 4, 13, 8, 50, 6, 0, 133, 210, 2, 31, 0, 0, 6, 9, 8, 50, 6, 0, 133, 210, 2, 29, 0, 0, 5, 106, 25, 209, 6, 11, 2, 0, 4, 7, 6, 56, 4, 0, 134, 210, 5, 19, 0, 0, 3, 0, 133, 210, 3, 19, 0, 0, 3, 9, 6, 50, 4, 0, 133, 210, 5, 19, 0, 0, 6, 106, 25, 209, 4, 5, 0, 0, 3, 2, 10, 126, 3, 11, 14, 56, 4, 0, 30, 50, 5, 2, 32, 50, 8, 4, 34, 50, 131, 0, 6, 192, 104, 0, 0, 0, 3, 2, 6, 192, 24, 0, 0, 0, 127, 0, 140, 191, 2, 132, 0, 191, 78, 0, 133, 191, 2, 130, 0, 191, 40, 0, 132, 191, 3, 130, 0, 191, 14, 0, 132, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 80, 220, 3, 0, 0, 3, 112, 0, 140, 191, 249, 2, 12, 126, 3, 6, 5, 0, 249, 2, 10, 126, 3, 6, 4, 0, 57, 0, 130, 191, 3, 129, 0, 191, 13, 0, 132, 191, 3, 0, 143, 210, 129, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 72, 220, 3, 0, 0, 3, 112, 0, 140, 191, 136, 6, 12, 32, 249, 2, 10, 126, 3, 6, 0, 0, 42, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 84, 220, 3, 0, 0, 5, 33, 0, 130, 191, 2, 129, 0, 191, 29, 0, 132, 191, 3, 130, 0, 191, 9, 0, 132, 191, 3, 0, 143, 210, 129, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 72, 220, 3, 0, 0, 5, 19, 0, 130, 191, 3, 129, 0, 191, 7, 0, 132, 191, 3, 106, 25, 209, 8, 12, 2, 0, 9, 2, 10, 126, 5, 15, 8, 56, 0, 0, 64, 220, 3, 0, 0, 5, 10, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 80, 220, 3, 0, 0, 5, 1, 0, 130, 191, 2, 2, 10, 126, 3, 2, 12, 126, 5, 2, 16, 126, 4, 2, 14, 126, 58, 0, 130, 191, 3, 129, 0, 191, 18, 0, 132, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 80, 220, 3, 0, 0, 3, 112, 0, 140, 191, 249, 2, 16, 126, 3, 6, 3, 0, 249, 2, 14, 126, 3, 6, 2, 0, 249, 2, 12, 126, 3, 6, 1, 0, 249, 2, 10, 126, 3, 6, 0, 0, 38, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 0, 80, 220, 3, 0, 0, 5, 3, 130, 0, 191, 16, 0, 132, 191, 3, 106, 25, 209, 3, 9, 1, 0, 4, 106, 28, 209, 4, 1, 169, 1, 0, 0, 80, 220, 3, 0, 0, 3, 112, 0, 140, 191, 249, 2, 16, 126, 3, 6, 5, 0, 249, 2, 14, 126, 3, 6, 4, 0, 249, 2, 12, 126, 5, 6, 5, 0, 249, 2, 10, 126, 5, 6, 4, 0, 12, 0, 130, 191, 6, 106, 25, 209, 3, 25, 1, 0, 7, 106, 28, 209, 4, 1, 169, 1, 0, 0, 80, 220, 6, 0, 0, 8, 3, 106, 25, 209, 3, 9, 1, 0, 4, 106, 28, 209, 4, 1, 169, 1, 0, 0, 84, 220, 3, 0, 0, 6, 131, 0, 6, 192, 32, 0, 0, 0, 127, 0, 140, 191, 1, 1, 14, 192, 0, 0, 0, 0, 128, 2, 36, 126, 112, 0, 140, 191, 0, 95, 32, 240, 15, 5, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 195, 0, 2, 192, 80, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 198, 208, 1, 27, 0, 0, 8, 0, 198, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 135, 3, 4, 134, 125, 0, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 28, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 2, 192, 48, 0, 0, 0, 127, 0, 140, 191, 4, 3, 14, 192, 0, 0, 0, 0, 2, 0, 6, 50, 3, 2, 8, 50, 4, 4, 10, 50, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 3, 1, 10, 192, 56, 0, 0, 0, 5, 2, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 4, 0, 14, 50, 5, 2, 16, 50, 6, 4, 18, 50, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 21, 0, 21, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 195, 0, 2, 192, 80, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 198, 208, 1, 27, 0, 0, 8, 0, 198, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 135, 3, 4, 134, 125, 0, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 225, 2, 136, 191, 131, 0, 6, 192, 24, 0, 0, 0, 3, 1, 6, 192, 40, 0, 0, 0, 3, 2, 2, 192, 48, 0, 0, 0, 127, 0, 140, 191, 1, 3, 14, 192, 0, 0, 0, 0, 4, 0, 6, 50, 5, 2, 8, 50, 8, 4, 10, 50, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 112, 15, 140, 191, 106, 0, 16, 208, 3, 7, 1, 0, 3, 0, 0, 209, 3, 1, 169, 1, 242, 6, 156, 124, 106, 32, 130, 190, 225, 0, 136, 191, 128, 6, 136, 124, 106, 32, 132, 190, 128, 2, 6, 126, 4, 126, 254, 137, 219, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 8, 6, 136, 124, 106, 32, 136, 190, 255, 6, 6, 10, 82, 184, 78, 65, 8, 126, 254, 137, 242, 6, 6, 10, 210, 0, 136, 191, 255, 6, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 138, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 21, 0, 0, 126, 1, 138, 190, 10, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 50, 0, 0, 128, 0, 255, 18, 18, 50, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 50, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 0, 84, 220, 10, 0, 0, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 1, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 50, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 30, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 31, 26, 2, 10, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 15, 0, 193, 209, 9, 227, 41, 132, 15, 17, 26, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 10, 1, 254, 190, 8, 27, 20, 4, 15, 29, 18, 4, 15, 21, 20, 2, 12, 19, 18, 4, 255, 26, 22, 38, 0, 240, 255, 255, 9, 21, 18, 2, 13, 23, 16, 4, 9, 17, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 11, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 11, 17, 18, 46, 0, 80, 213, 62, 255, 18, 20, 10, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 38, 131, 24, 24, 36, 255, 0, 139, 190, 85, 85, 85, 85, 255, 0, 138, 190, 85, 85, 85, 85, 12, 106, 25, 209, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 138, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 193, 209, 10, 22, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 23, 16, 2, 14, 31, 22, 46, 239, 47, 228, 183, 8, 23, 22, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 138, 190, 171, 170, 42, 61, 10, 22, 28, 44, 14, 0, 193, 209, 14, 23, 194, 3, 11, 23, 30, 10, 14, 31, 22, 44, 255, 0, 138, 190, 8, 227, 130, 180, 255, 0, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 23, 26, 44, 12, 0, 68, 208, 8, 21, 0, 0, 11, 18, 132, 124, 12, 23, 26, 44, 106, 12, 140, 134, 11, 18, 130, 124, 134, 20, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 150, 124, 128, 16, 16, 0, 3, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 10, 0, 194, 208, 3, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 42, 0, 3, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 7, 14, 0, 242, 6, 138, 125, 242, 14, 6, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 138, 190, 61, 10, 135, 63, 3, 0, 193, 209, 3, 21, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 6, 126, 2, 1, 254, 190, 106, 0, 16, 208, 4, 7, 1, 0, 4, 0, 0, 209, 4, 1, 169, 1, 242, 8, 156, 124, 2, 106, 254, 134, 225, 0, 136, 191, 128, 8, 136, 124, 106, 32, 132, 190, 128, 2, 8, 126, 4, 126, 254, 137, 219, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 8, 8, 136, 124, 106, 32, 136, 190, 255, 8, 8, 10, 82, 184, 78, 65, 8, 126, 254, 137, 242, 8, 8, 10, 210, 0, 136, 191, 255, 8, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 138, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 21, 0, 0, 126, 1, 138, 190, 10, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 50, 0, 0, 128, 0, 255, 18, 18, 50, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 50, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 0, 84, 220, 10, 0, 0, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 1, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 50, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 30, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 31, 26, 2, 10, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 15, 0, 193, 209, 9, 227, 41, 132, 15, 17, 26, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 10, 1, 254, 190, 8, 27, 20, 4, 15, 29, 18, 4, 15, 21, 20, 2, 12, 19, 18, 4, 255, 26, 22, 38, 0, 240, 255, 255, 9, 21, 18, 2, 13, 23, 16, 4, 9, 17, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 11, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 11, 17, 18, 46, 0, 80, 213, 62, 255, 18, 20, 10, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 38, 131, 24, 24, 36, 255, 0, 139, 190, 85, 85, 85, 85, 255, 0, 138, 190, 85, 85, 85, 85, 12, 106, 25, 209, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 138, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 193, 209, 10, 22, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 23, 16, 2, 14, 31, 22, 46, 239, 47, 228, 183, 8, 23, 22, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 138, 190, 171, 170, 42, 61, 10, 22, 28, 44, 14, 0, 193, 209, 14, 23, 194, 3, 11, 23, 30, 10, 14, 31, 22, 44, 255, 0, 138, 190, 8, 227, 130, 180, 255, 0, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 23, 26, 44, 12, 0, 68, 208, 8, 21, 0, 0, 11, 18, 132, 124, 12, 23, 26, 44, 106, 12, 140, 134, 11, 18, 130, 124, 134, 20, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 150, 124, 128, 16, 16, 0, 4, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 10, 0, 194, 208, 4, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 42, 0, 4, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 9, 14, 0, 242, 8, 138, 125, 242, 14, 8, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 138, 190, 61, 10, 135, 63, 4, 0, 193, 209, 4, 21, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 8, 126, 2, 1, 254, 190, 3, 2, 10, 192, 56, 0, 0, 0, 106, 0, 16, 208, 5, 7, 1, 0, 5, 0, 0, 209, 5, 1, 169, 1, 127, 0, 140, 191, 8, 0, 34, 50, 9, 2, 36, 50, 10, 4, 38, 50, 242, 10, 156, 124, 106, 32, 130, 190, 225, 0, 136, 191, 128, 10, 136, 124, 106, 32, 132, 190, 128, 2, 10, 126, 4, 126, 254, 137, 219, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 8, 10, 136, 124, 106, 32, 136, 190, 255, 10, 10, 10, 82, 184, 78, 65, 8, 126, 254, 137, 242, 10, 10, 10, 210, 0, 136, 191, 255, 10, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 138, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 21, 0, 0, 126, 1, 138, 190, 10, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 50, 0, 0, 128, 0, 255, 18, 18, 50, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 50, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 0, 84, 220, 10, 0, 0, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 1, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 50, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 0, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 26, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 27, 30, 2, 10, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 13, 0, 193, 209, 9, 227, 41, 132, 13, 17, 30, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 10, 1, 254, 190, 8, 31, 16, 4, 13, 29, 20, 4, 13, 17, 16, 2, 12, 21, 18, 4, 255, 30, 20, 38, 0, 240, 255, 255, 9, 17, 16, 2, 15, 21, 18, 4, 8, 19, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 10, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 10, 17, 18, 46, 0, 80, 213, 62, 255, 18, 22, 10, 59, 170, 184, 66, 11, 17, 22, 126, 191, 22, 24, 38, 131, 24, 24, 36, 255, 0, 139, 190, 85, 85, 85, 85, 255, 0, 138, 190, 85, 85, 85, 85, 12, 106, 25, 209, 10, 24, 2, 0, 11, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 0, 84, 220, 12, 0, 0, 12, 255, 0, 138, 190, 0, 80, 213, 62, 11, 11, 28, 126, 10, 0, 193, 209, 10, 20, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 21, 16, 2, 14, 31, 20, 46, 239, 47, 228, 183, 8, 21, 20, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 138, 190, 171, 170, 42, 61, 10, 20, 28, 44, 14, 0, 193, 209, 14, 21, 194, 3, 10, 21, 30, 10, 14, 31, 20, 44, 255, 0, 138, 190, 8, 227, 130, 180, 255, 0, 139, 190, 24, 114, 177, 66, 112, 0, 140, 191, 13, 21, 26, 44, 12, 0, 68, 208, 8, 21, 0, 0, 11, 18, 132, 124, 12, 21, 26, 44, 106, 12, 140, 134, 11, 18, 130, 124, 134, 22, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 138, 190, 208, 142, 206, 194, 8, 21, 16, 0, 10, 18, 150, 124, 128, 16, 16, 0, 5, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 138, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 10, 0, 194, 208, 5, 21, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 42, 0, 5, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 11, 14, 0, 242, 10, 138, 125, 242, 14, 10, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 138, 190, 61, 10, 135, 63, 5, 0, 193, 209, 5, 21, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 10, 126, 2, 1, 254, 190, 131, 0, 6, 192, 32, 0, 0, 0, 127, 0, 140, 191, 1, 1, 14, 192, 0, 0, 0, 0, 128, 2, 40, 126, 127, 0, 140, 191, 0, 95, 32, 240, 17, 3, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 195, 0, 2, 192, 80, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 198, 208, 1, 27, 0, 0, 8, 0, 198, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 135, 3, 4, 134, 125, 0, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 28, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 2, 192, 48, 0, 0, 0, 127, 0, 140, 191, 4, 3, 14, 192, 0, 0, 0, 0, 2, 0, 6, 50, 3, 2, 8, 50, 4, 4, 10, 50, 128, 2, 12, 126, 127, 0, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 3, 1, 10, 192, 56, 0, 0, 0, 5, 2, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 4, 0, 14, 50, 5, 2, 16, 50, 6, 4, 18, 50, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 2, 172, 0, 144, 0, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 5, 0, 5, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 0, 134, 255, 255, 0, 0, 0, 8, 0, 146, 131, 0, 6, 192, 0, 0, 0, 0, 67, 0, 2, 192, 72, 0, 0, 0, 127, 0, 140, 191, 0, 2, 0, 128, 0, 0, 0, 50, 1, 0, 136, 125, 106, 32, 128, 190, 20, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 131, 0, 2, 192, 40, 0, 0, 0, 127, 0, 140, 191, 4, 3, 10, 192, 0, 0, 0, 0, 2, 0, 2, 50, 127, 0, 140, 191, 0, 32, 12, 224, 1, 1, 3, 128, 131, 0, 2, 192, 56, 0, 0, 0, 5, 1, 10, 192, 0, 0, 0, 0, 127, 0, 140, 191, 2, 0, 0, 50, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 11, 0, 11, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 1, 6, 192, 0, 0, 0, 0, 195, 0, 2, 192, 72, 0, 0, 0, 127, 0, 140, 191, 2, 4, 2, 128, 2, 0, 0, 50, 3, 0, 136, 125, 106, 32, 130, 190, 29, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 3, 1, 2, 192, 40, 0, 0, 0, 127, 0, 140, 191, 4, 3, 10, 192, 0, 0, 0, 0, 4, 0, 6, 50, 127, 0, 140, 191, 0, 32, 12, 224, 3, 3, 3, 128, 3, 3, 10, 192, 8, 0, 0, 0, 3, 1, 10, 192, 56, 0, 0, 0, 5, 4, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 1, 14, 1, 128, 0, 12, 0, 128, 1, 6, 1, 128, 0, 5, 0, 128, 4, 0, 14, 50, 1, 4, 18, 50, 0, 2, 16, 50, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 4, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 7, 0, 7, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 1, 6, 192, 0, 0, 0, 0, 195, 0, 2, 192, 72, 0, 0, 0, 127, 0, 140, 191, 2, 4, 2, 128, 2, 0, 0, 50, 3, 0, 136, 125, 106, 32, 130, 190, 31, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 3, 3, 10, 192, 8, 0, 0, 0, 3, 1, 6, 192, 40, 0, 0, 0, 127, 0, 140, 191, 67, 3, 2, 192, 48, 0, 0, 0, 4, 4, 14, 192, 0, 0, 0, 0, 1, 14, 1, 128, 0, 12, 0, 128, 127, 0, 140, 191, 1, 13, 1, 128, 0, 5, 0, 128, 4, 0, 6, 50, 1, 4, 10, 50, 0, 2, 8, 50, 128, 2, 12, 126, 0, 95, 0, 240, 3, 1, 4, 0, 3, 0, 2, 192, 56, 0, 0, 0, 5, 1, 10, 192, 0, 0, 0, 0, 127, 0, 140, 191, 0, 0, 0, 50, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 2, 172, 0, 144, 19, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 6, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 2, 134, 255, 255, 0, 0, 0, 255, 128, 146, 16, 0, 16, 0, 1, 255, 1, 134, 255, 255, 0, 0, 2, 8, 2, 146, 0, 9, 0, 146, 1, 10, 1, 146, 3, 2, 10, 192, 0, 0, 0, 0, 3, 1, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 96, 0, 0, 0, 195, 0, 2, 192, 104, 0, 0, 0, 127, 0, 140, 191, 2, 8, 2, 128, 0, 10, 0, 128, 2, 0, 0, 50, 0, 2, 2, 50, 1, 4, 0, 128, 4, 0, 193, 208, 1, 27, 0, 0, 8, 0, 193, 208, 0, 25, 0, 0, 0, 4, 4, 50, 8, 4, 128, 134, 3, 4, 136, 125, 0, 106, 128, 134, 0, 32, 128, 190, 55, 0, 136, 191, 3, 2, 10, 192, 80, 0, 0, 0, 127, 0, 140, 191, 8, 0, 14, 50, 9, 2, 16, 50, 10, 4, 18, 50, 131, 0, 2, 192, 112, 0, 0, 0, 3, 1, 6, 192, 24, 0, 0, 0, 127, 0, 140, 191, 2, 130, 0, 191, 30, 0, 133, 191, 2, 129, 0, 191, 13, 0, 132, 191, 3, 2, 10, 192, 48, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 27, 0, 130, 191, 2, 128, 0, 191, 25, 0, 132, 191, 3, 2, 10, 192, 32, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 12, 0, 130, 191, 3, 2, 10, 192, 64, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 2, 172, 0, 144, 0, 0, 0, 11, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 5, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 192, 4, 0, 0, 0, 127, 0, 140, 191, 0, 255, 0, 134, 255, 255, 0, 0, 0, 8, 0, 146, 131, 0, 6, 192, 0, 0, 0, 0, 67, 0, 2, 192, 96, 0, 0, 0, 127, 0, 140, 191, 0, 2, 0, 128, 0, 0, 0, 50, 1, 0, 136, 125, 106, 32, 128, 190, 50, 0, 136, 191, 131, 0, 2, 192, 80, 0, 0, 0, 127, 0, 140, 191, 2, 0, 0, 50, 131, 0, 2, 192, 112, 0, 0, 0, 3, 1, 6, 192, 24, 0, 0, 0, 127, 0, 140, 191, 2, 130, 0, 191, 28, 0, 133, 191, 2, 129, 0, 191, 12, 0, 132, 191, 3, 2, 10, 192, 48, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 25, 0, 130, 191, 2, 128, 0, 191, 23, 0, 132, 191, 3, 2, 10, 192, 32, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 11, 0, 130, 191, 3, 2, 10, 192, 64, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 0, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 1, 0, 4, 0, 8, 2, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 0, 4, 0, 16, 6, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 26, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 4, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 26, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 204, 4, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 26, 0, 5, 0, 0, 10, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 26, 0, 5, 0, 0, 13, 0, 0, 0, 0, 0, 0, 28, 13, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 26, 0, 5, 0, 0, 27, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 26, 0, 5, 0, 0, 30, 0, 0, 0, 0, 0, 0, 148, 1, 0, 0, 0, 0, 0, 0, 58, 1, 0, 0, 26, 0, 5, 0, 0, 32, 0, 0, 0, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 90, 1, 0, 0, 26, 0, 5, 0, 0, 34, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 122, 1, 0, 0, 26, 0, 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 0, 0, 0, 0, 144, 1, 0, 0, 26, 0, 5, 0, 0, 39, 0, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 170, 1, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 1, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 15, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 15, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 15, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 15, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 17, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 19, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 19, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 19, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 19, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 20, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 20, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 23, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 23, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 23, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 23, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 24, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 2, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 3, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 1, 0, 0, 0, 7, 0, 192, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 12, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 55, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 56, 0, 0, 0, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0};\n}\n}\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_object_gfx9xx.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <stdint.h>\nnamespace rocr {\nnamespace image {\nuint8_t blit_object_gfx9xx[] = {127, 69, 76, 70, 2, 1, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 224, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 72, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 56, 0, 2, 0, 64, 0, 8, 0, 1, 0, 2, 0, 0, 96, 6, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 96, 5, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 41, 0, 0, 0, 0, 0, 0, 24, 41, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 46, 115, 104, 115, 116, 114, 116, 97, 98, 0, 46, 115, 116, 114, 116, 97, 98, 0, 46, 110, 111, 116, 101, 0, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 46, 104, 115, 97, 116, 101, 120, 116, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 115, 121, 109, 116, 97, 98, 0, 46, 114, 101, 108, 97, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 69, 88, 80, 95, 69, 80, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 69, 0, 38, 104, 115, 97, 95, 101, 120, 116, 95, 105, 109, 97, 103, 101, 58, 58, 38, 95, 95, 111, 99, 109, 108, 116, 98, 108, 95, 77, 51, 50, 95, 76, 79, 71, 95, 73, 78, 86, 95, 69, 80, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 116, 111, 95, 98, 117, 102, 102, 101, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 98, 117, 102, 102, 101, 114, 95, 116, 111, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 100, 101, 102, 97, 117, 108, 116, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 108, 105, 110, 101, 97, 114, 95, 116, 111, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 115, 116, 97, 110, 100, 97, 114, 100, 95, 116, 111, 95, 108, 105, 110, 101, 97, 114, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 116, 111, 95, 114, 101, 103, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 111, 112, 121, 95, 105, 109, 97, 103, 101, 95, 114, 101, 103, 95, 116, 111, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 107, 101, 114, 110, 101, 108, 0, 38, 95, 95, 99, 108, 101, 97, 114, 95, 105, 109, 97, 103, 101, 95, 49, 100, 98, 95, 107, 101, 114, 110, 101, 108, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 100, 97, 116, 97, 95, 114, 101, 97, 100, 111, 110, 108, 121, 95, 97, 103, 101, 110, 116, 0, 95, 95, 104, 115, 97, 95, 115, 101, 99, 116, 105, 111, 110, 46, 104, 115, 97, 116, 101, 120, 116, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 65, 77, 68, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 0, 4, 0, 0, 0, 26, 0, 0, 0, 3, 0, 0, 0, 65, 77, 68, 0, 4, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 0, 65, 77, 68, 71, 80, 85, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 4, 0, 0, 0, 65, 77, 68, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 65, 77, 68, 32, 72, 83, 65, 32, 82, 117, 110, 116, 105, 109, 101, 32, 70, 105, 110, 97, 108, 105, 122, 101, 114, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 65, 77, 68, 0, 22, 0, 45, 104, 115, 97, 95, 99, 97, 108, 108, 95, 99, 111, 110, 118, 101, 110, 116, 105, 111, 110, 61, 48, 0, 5, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 96, 129, 63, 119, 62, 26, 57, 0, 192, 130, 63, 138, 105, 216, 57, 0, 32, 132, 63, 29, 70, 81, 58, 0, 160, 133, 63, 124, 54, 172, 57, 0, 0, 135, 63, 180, 12, 123, 58, 0, 128, 136, 63, 4, 116, 64, 58, 0, 0, 138, 63, 170, 171, 38, 58, 0, 128, 139, 63, 31, 15, 46, 58, 0, 0, 141, 63, 219, 250, 86, 58, 0, 160, 142, 63, 104, 49, 7, 57, 0, 32, 144, 63, 24, 226, 14, 58, 0, 192, 145, 63, 234, 220, 244, 56, 0, 64, 147, 63, 120, 89, 81, 58, 0, 224, 148, 63, 71, 125, 39, 58, 0, 128, 150, 63, 185, 105, 33, 58, 0, 32, 152, 63, 140, 130, 63, 58, 0, 224, 153, 63, 65, 38, 11, 55, 0, 128, 155, 63, 157, 155, 211, 57, 0, 32, 157, 63, 57, 205, 118, 58, 0, 224, 158, 63, 4, 147, 41, 58, 0, 160, 160, 63, 125, 136, 2, 58, 0, 96, 162, 63, 24, 24, 2, 58, 0, 32, 164, 63, 112, 173, 40, 58, 0, 224, 165, 63, 77, 181, 118, 58, 0, 192, 167, 63, 78, 59, 217, 57, 0, 160, 169, 63, 117, 90, 45, 56, 0, 96, 171, 63, 173, 205, 81, 58, 0, 64, 173, 63, 82, 247, 65, 58, 0, 32, 175, 63, 107, 197, 91, 58, 0, 32, 177, 63, 116, 96, 253, 56, 0, 0, 179, 63, 149, 32, 14, 58, 0, 0, 181, 63, 127, 102, 30, 57, 0, 224, 182, 63, 25, 143, 108, 58, 0, 224, 184, 63, 59, 122, 93, 58, 0, 224, 186, 63, 144, 213, 122, 58, 0, 0, 189, 63, 245, 57, 138, 57, 0, 0, 191, 63, 179, 205, 60, 58, 0, 32, 193, 63, 166, 204, 196, 57, 0, 64, 195, 63, 68, 155, 89, 57, 0, 96, 197, 63, 42, 66, 101, 57, 0, 128, 199, 63, 138, 76, 215, 57, 0, 160, 201, 63, 51, 236, 77, 58, 0, 224, 203, 63, 239, 79, 193, 57, 0, 32, 206, 63, 163, 130, 17, 57, 0, 96, 208, 63, 187, 246, 204, 56, 0, 160, 210, 63, 31, 217, 129, 57, 0, 224, 212, 63, 94, 213, 26, 58, 0, 64, 215, 63, 90, 153, 31, 57, 0, 128, 217, 63, 19, 174, 104, 58, 0, 224, 219, 63, 190, 188, 93, 58, 0, 96, 222, 63, 94, 130, 244, 55, 0, 192, 224, 63, 194, 238, 205, 57, 0, 32, 227, 63, 149, 75, 124, 58, 0, 160, 229, 63, 59, 55, 72, 58, 0, 32, 232, 63, 129, 82, 75, 58, 0, 192, 234, 63, 221, 231, 198, 55, 0, 64, 237, 63, 237, 1, 243, 57, 0, 224, 239, 63, 123, 51, 23, 57, 0, 128, 242, 63, 44, 158, 59, 56, 0, 32, 245, 63, 164, 162, 47, 57, 0, 192, 247, 63, 152, 251, 6, 58, 0, 128, 250, 63, 220, 182, 236, 56, 0, 32, 253, 63, 103, 96, 112, 58, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 59, 65, 172, 41, 52, 0, 0, 126, 60, 252, 176, 168, 53, 0, 192, 189, 60, 234, 131, 141, 54, 0, 16, 252, 60, 120, 14, 27, 54, 0, 240, 28, 61, 254, 185, 135, 54, 0, 160, 59, 61, 101, 236, 49, 54, 0, 16, 90, 61, 25, 113, 221, 54, 0, 80, 120, 61, 69, 0, 195, 53, 0, 32, 139, 61, 81, 119, 155, 55, 0, 0, 154, 61, 13, 203, 235, 55, 0, 208, 168, 61, 131, 159, 131, 55, 0, 128, 183, 61, 229, 138, 82, 55, 0, 16, 198, 61, 24, 235, 162, 55, 0, 144, 212, 61, 149, 116, 218, 54, 0, 240, 226, 61, 183, 30, 169, 54, 0, 48, 241, 61, 21, 183, 131, 55, 0, 96, 255, 61, 219, 49, 17, 55, 0, 176, 6, 62, 104, 62, 63, 56, 0, 176, 13, 62, 151, 106, 21, 56, 0, 160, 20, 62, 15, 124, 41, 56, 0, 128, 27, 62, 15, 16, 126, 56, 0, 96, 34, 62, 101, 182, 21, 56, 0, 48, 41, 62, 161, 227, 229, 55, 0, 240, 47, 62, 83, 56, 24, 56, 0, 176, 54, 62, 157, 113, 254, 53, 0, 80, 61, 62, 8, 129, 68, 56, 0, 240, 67, 62, 144, 50, 80, 56, 0, 144, 74, 62, 232, 57, 53, 55, 0, 16, 81, 62, 241, 15, 94, 56, 0, 144, 87, 62, 64, 167, 100, 56, 0, 16, 94, 62, 45, 116, 134, 55, 0, 112, 100, 62, 205, 227, 123, 56, 0, 224, 106, 62, 62, 173, 133, 54, 0, 48, 113, 62, 21, 183, 3, 56, 0, 128, 119, 62, 220, 203, 173, 55, 0, 192, 125, 62, 175, 54, 12, 56, 0, 0, 130, 62, 211, 82, 22, 55, 0, 16, 133, 62, 57, 113, 146, 56, 0, 32, 136, 62, 215, 252, 197, 56, 0, 48, 139, 62, 213, 85, 174, 56, 0, 64, 142, 62, 105, 193, 24, 56, 0, 64, 145, 62, 231, 253, 160, 56, 0, 64, 148, 62, 239, 9, 173, 56, 0, 64, 151, 62, 225, 186, 98, 56, 0, 48, 154, 62, 76, 205, 238, 56, 0, 48, 157, 62, 210, 170, 152, 55, 0, 32, 160, 62, 26, 26, 66, 55, 0, 0, 163, 62, 14, 225, 197, 56, 0, 240, 165, 62, 238, 42, 191, 55, 0, 208, 168, 62, 45, 135, 45, 56, 0, 176, 171, 62, 138, 46, 238, 55, 0, 128, 174, 62, 172, 223, 222, 56, 0, 96, 177, 62, 185, 242, 2, 56, 0, 48, 180, 62, 155, 30, 72, 56, 0, 0, 183, 62, 43, 170, 14, 56, 0, 192, 185, 62, 93, 251, 235, 56, 0, 144, 188, 62, 221, 95, 37, 56, 0, 80, 191, 62, 130, 59, 120, 56, 0, 16, 194, 62, 30, 218, 81, 56, 0, 208, 196, 62, 5, 27, 78, 55, 0, 128, 199, 62, 155, 67, 143, 56, 0, 48, 202, 62, 16, 14, 202, 56, 0, 224, 204, 62, 139, 192, 202, 56, 0, 144, 207, 62, 95, 246, 145, 56, 0, 64, 210, 62, 203, 33, 129, 55, 0, 224, 212, 62, 154, 154, 108, 56, 0, 128, 215, 62, 35, 153, 148, 56, 0, 32, 218, 62, 204, 123, 119, 56, 0, 192, 220, 62, 38, 45, 177, 55, 0, 80, 223, 62, 211, 206, 166, 56, 0, 224, 225, 62, 230, 211, 235, 56, 0, 112, 228, 62, 205, 227, 251, 56, 0, 0, 231, 62, 194, 133, 215, 56, 0, 144, 233, 62, 0, 126, 126, 56, 0, 16, 236, 62, 197, 146, 243, 56, 0, 160, 238, 62, 131, 9, 212, 55, 0, 32, 241, 62, 124, 26, 8, 56, 0, 160, 243, 62, 173, 195, 132, 55, 0, 16, 246, 62, 35, 233, 204, 56, 0, 144, 248, 62, 175, 95, 15, 56, 0, 0, 251, 62, 56, 253, 145, 56, 0, 112, 253, 62, 188, 71, 172, 56, 0, 224, 255, 62, 43, 4, 151, 56, 0, 32, 1, 63, 210, 82, 41, 57, 0, 80, 2, 63, 212, 206, 111, 57, 0, 144, 3, 63, 115, 112, 249, 55, 0, 192, 4, 63, 174, 158, 94, 56, 0, 240, 5, 63, 74, 200, 101, 56, 0, 32, 7, 63, 163, 11, 19, 56, 0, 64, 8, 63, 22, 207, 121, 57, 0, 112, 9, 63, 201, 202, 56, 57, 0, 160, 10, 63, 244, 210, 195, 56, 0, 192, 11, 63, 236, 93, 117, 57, 0, 240, 12, 63, 103, 180, 230, 56, 0, 16, 14, 63, 184, 15, 92, 57, 0, 64, 15, 63, 224, 188, 62, 56, 0, 96, 16, 63, 146, 209, 220, 56, 0, 128, 17, 63, 223, 107, 24, 57, 0, 160, 18, 63, 76, 231, 45, 57, 0, 192, 19, 63, 68, 9, 47, 57, 0, 224, 20, 63, 97, 255, 27, 57, 0, 0, 22, 63, 68, 237, 233, 56, 0, 32, 23, 63, 200, 109, 104, 56, 0, 48, 24, 63, 167, 153, 107, 57, 0, 80, 25, 63, 137, 156, 9, 57, 0, 112, 26, 63, 115, 118, 162, 55, 0, 128, 27, 63, 163, 218, 11, 57, 0, 144, 28, 63, 171, 105, 112, 57, 0, 176, 29, 63, 255, 73, 132, 56, 0, 192, 30, 63, 56, 53, 1, 57, 0, 208, 31, 63, 104, 194, 45, 57, 0, 224, 32, 63, 35, 244, 71, 57, 0, 240, 33, 63, 124, 241, 79, 57, 0, 0, 35, 63, 14, 225, 69, 57, 0, 16, 36, 63, 245, 232, 41, 57, 0, 32, 37, 63, 176, 93, 248, 56, 0, 48, 38, 63, 153, 95, 115, 56, 0, 48, 39, 63, 219, 8, 108, 57, 0, 64, 40, 63, 0, 230, 9, 57, 0, 80, 41, 63, 111, 153, 180, 55, 0, 80, 42, 63, 204, 51, 18, 57, 0, 80, 43, 63, 217, 234, 124, 57, 0, 96, 44, 63, 205, 181, 173, 56, 0, 96, 45, 63, 26, 38, 32, 57, 0, 96, 46, 63, 54, 238, 88, 57, 0, 112, 47, 63, 5, 73, 170, 53, 0, 112, 48, 63, 30, 209, 203, 55, 0, 112, 49, 63, 244, 253, 5, 56, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 254, 63, 248, 3, 254, 56, 0, 0, 252, 63, 193, 15, 252, 57, 0, 0, 250, 63, 201, 179, 140, 58, 0, 0, 248, 63, 16, 62, 248, 58, 0, 0, 246, 63, 48, 123, 64, 59, 0, 0, 244, 63, 96, 141, 137, 59, 0, 0, 242, 63, 72, 214, 185, 59, 0, 0, 240, 63, 241, 240, 240, 59, 0, 0, 239, 63, 127, 220, 186, 58, 0, 0, 237, 63, 108, 7, 102, 59, 0, 0, 235, 63, 166, 178, 189, 59, 0, 0, 234, 63, 161, 14, 234, 57, 0, 0, 232, 63, 247, 88, 75, 59, 0, 0, 230, 63, 72, 180, 194, 59, 0, 0, 229, 63, 172, 96, 150, 58, 0, 0, 227, 63, 228, 56, 142, 59, 0, 0, 225, 63, 14, 120, 252, 59, 0, 0, 224, 63, 56, 112, 96, 59, 0, 0, 222, 63, 77, 92, 233, 59, 0, 0, 221, 63, 76, 145, 79, 59, 0, 0, 219, 63, 239, 97, 235, 59, 0, 0, 218, 63, 79, 27, 104, 59, 0, 0, 217, 63, 178, 1, 89, 56, 0, 0, 215, 63, 229, 53, 148, 59, 0, 0, 214, 63, 89, 3, 174, 58, 0, 0, 212, 63, 3, 123, 199, 59, 0, 0, 211, 63, 109, 26, 80, 59, 0, 0, 210, 63, 33, 13, 210, 57, 0, 0, 208, 63, 204, 159, 182, 59, 0, 0, 207, 63, 81, 233, 72, 59, 0, 0, 206, 63, 185, 83, 52, 58, 0, 0, 204, 63, 205, 204, 204, 59, 0, 0, 203, 63, 192, 39, 135, 59, 0, 0, 202, 63, 205, 15, 11, 59, 0, 0, 201, 63, 209, 73, 123, 57, 0, 0, 199, 63, 125, 12, 206, 59, 0, 0, 198, 63, 106, 12, 152, 59, 0, 0, 197, 63, 247, 144, 75, 59, 0, 0, 196, 63, 21, 190, 220, 58, 0, 0, 195, 63, 49, 12, 195, 57, 0, 0, 193, 63, 214, 187, 228, 59, 0, 0, 192, 63, 193, 192, 192, 59, 0, 0, 191, 63, 232, 47, 160, 59, 0, 0, 190, 63, 12, 250, 130, 59, 0, 0, 189, 63, 142, 32, 82, 59, 0, 0, 188, 63, 24, 200, 36, 59, 0, 0, 187, 63, 135, 156, 251, 58, 0, 0, 186, 63, 140, 46, 186, 58, 0, 0, 185, 63, 233, 15, 133, 58, 0, 0, 184, 63, 3, 23, 56, 58, 0, 0, 183, 63, 162, 181, 251, 57, 0, 0, 182, 63, 97, 11, 182, 57, 0, 0, 181, 63, 170, 104, 158, 57, 0, 0, 180, 63, 65, 11, 180, 57, 0, 0, 179, 63, 41, 53, 246, 57, 0, 0, 178, 63, 67, 22, 50, 58, 0, 0, 177, 63, 192, 157, 126, 58, 0, 0, 176, 63, 11, 44, 176, 58, 0, 0, 175, 63, 26, 119, 235, 58, 0, 0, 174, 63, 185, 130, 24, 59, 0, 0, 173, 63, 176, 86, 64, 59, 0, 0, 172, 63, 8, 35, 109, 59, 0, 0, 171, 63, 227, 105, 143, 59, 0, 0, 170, 63, 171, 170, 170, 59, 0, 0, 169, 63, 72, 74, 200, 59, 0, 0, 168, 63, 87, 63, 232, 59, 0, 0, 168, 63, 129, 10, 168, 57, 0, 0, 167, 63, 230, 20, 188, 58, 0, 0, 166, 63, 114, 136, 43, 59, 0, 0, 165, 63, 5, 106, 125, 59, 0, 0, 164, 63, 30, 207, 169, 59, 0, 0, 163, 63, 61, 10, 215, 59, 0, 0, 163, 63, 246, 199, 75, 57, 0, 0, 162, 63, 172, 12, 223, 58, 0, 0, 161, 63, 93, 98, 86, 59, 0, 0, 160, 63, 161, 160, 160, 59, 0, 0, 159, 63, 254, 9, 216, 59, 0, 0, 159, 63, 57, 47, 11, 58, 0, 0, 158, 63, 72, 90, 25, 59, 0, 0, 157, 63, 158, 216, 137, 59, 0, 0, 156, 63, 97, 225, 200, 59, 0, 0, 156, 63, 193, 9, 156, 57, 0, 0, 155, 63, 62, 223, 24, 59, 0, 0, 154, 63, 217, 231, 144, 59, 0, 0, 153, 63, 219, 34, 215, 59, 0, 0, 153, 63, 139, 210, 120, 58, 0, 0, 152, 63, 19, 144, 81, 59, 0, 0, 151, 63, 237, 37, 180, 59, 0, 0, 151, 63, 46, 1, 23, 56, 0, 0, 150, 63, 216, 180, 31, 59, 0, 0, 149, 63, 104, 37, 160, 59, 0, 0, 148, 63, 79, 9, 242, 59, 0, 0, 148, 63, 41, 1, 11, 59, 0, 0, 147, 63, 196, 133, 154, 59, 0, 0, 146, 63, 132, 19, 241, 59, 0, 0, 146, 63, 37, 73, 18, 59, 0, 0, 145, 63, 197, 179, 162, 59, 0, 0, 144, 63, 9, 188, 253, 59, 0, 0, 144, 63, 198, 112, 52, 59, 0, 0, 143, 63, 238, 35, 184, 59, 0, 0, 143, 63, 208, 206, 59, 58, 0, 0, 142, 63, 218, 106, 112, 59, 0, 0, 141, 63, 2, 82, 218, 59, 0, 0, 141, 63, 35, 44, 247, 58, 0, 0, 140, 63, 4, 156, 162, 59, 0, 0, 140, 63, 193, 8, 140, 57, 0, 0, 139, 63, 148, 104, 96, 59, 0, 0, 138, 63, 252, 242, 216, 59, 0, 0, 138, 63, 225, 240, 5, 59, 0, 0, 137, 63, 138, 64, 174, 59, 0, 0, 137, 63, 215, 57, 86, 58, 0, 0, 136, 63, 137, 136, 136, 59, 0, 0, 135, 63, 136, 128, 247, 59, 0, 0, 135, 63, 190, 86, 79, 59, 0, 0, 134, 63, 68, 5, 217, 59, 0, 0, 134, 63, 252, 20, 23, 59, 0, 0, 133, 63, 97, 55, 191, 59, 0, 0, 133, 63, 77, 33, 208, 58, 0, 0, 132, 63, 200, 249, 169, 59, 0, 0, 132, 63, 8, 33, 132, 58, 0, 0, 131, 63, 82, 48, 153, 59, 0, 0, 131, 63, 188, 116, 19, 58, 0, 0, 130, 63, 191, 191, 140, 59, 0, 0, 130, 63, 33, 8, 130, 57, 0, 0, 129, 63, 169, 141, 132, 59, 0, 0, 129, 63, 4, 2, 129, 56, 0, 0, 128, 63, 129, 128, 128, 59, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 11, 0, 11, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 104, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 112, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 193, 208, 1, 27, 0, 0, 12, 0, 136, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 134, 127, 192, 140, 191, 1, 4, 136, 125, 2, 106, 128, 134, 0, 32, 128, 190, 199, 0, 136, 191, 131, 0, 6, 192, 24, 0, 0, 0, 3, 1, 6, 192, 56, 0, 0, 0, 3, 2, 2, 192, 64, 0, 0, 0, 131, 2, 6, 192, 72, 0, 0, 0, 67, 2, 2, 192, 128, 0, 0, 0, 3, 3, 10, 192, 136, 0, 0, 0, 159, 0, 6, 34, 159, 2, 8, 34, 127, 192, 140, 191, 5, 0, 134, 210, 1, 25, 0, 0, 4, 0, 133, 210, 4, 25, 0, 0, 6, 0, 133, 210, 1, 27, 0, 0, 4, 0, 255, 209, 4, 11, 26, 4, 5, 0, 133, 210, 1, 25, 0, 0, 5, 106, 25, 209, 5, 1, 2, 0, 4, 7, 6, 56, 4, 0, 14, 104, 5, 2, 16, 104, 8, 4, 18, 104, 159, 4, 12, 34, 1, 4, 14, 192, 0, 0, 0, 0, 128, 2, 20, 126, 127, 192, 140, 191, 0, 95, 0, 240, 7, 7, 4, 0, 0, 0, 134, 210, 2, 29, 0, 0, 1, 0, 133, 210, 6, 29, 0, 0, 4, 0, 133, 210, 2, 31, 0, 0, 0, 0, 255, 209, 1, 1, 18, 4, 1, 0, 133, 210, 2, 29, 0, 0, 1, 106, 25, 209, 1, 11, 2, 0, 0, 7, 0, 56, 2, 0, 134, 210, 1, 19, 0, 0, 0, 0, 133, 210, 0, 19, 0, 0, 0, 5, 0, 104, 1, 0, 133, 210, 1, 19, 0, 0, 3, 106, 25, 209, 1, 21, 0, 0, 11, 2, 4, 126, 0, 5, 8, 56, 131, 0, 6, 192, 120, 0, 0, 0, 3, 1, 6, 192, 32, 0, 0, 0, 127, 192, 140, 191, 2, 132, 0, 191, 85, 0, 133, 191, 3, 2, 6, 192, 40, 0, 0, 0, 2, 130, 0, 191, 41, 0, 132, 191, 3, 132, 0, 191, 29, 0, 133, 191, 3, 130, 0, 191, 12, 0, 132, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 2, 0, 0, 210, 8, 33, 29, 4, 0, 128, 112, 220, 0, 2, 127, 0, 110, 0, 130, 191, 3, 129, 0, 191, 108, 0, 132, 191, 0, 0, 143, 210, 129, 6, 2, 0, 127, 192, 140, 191, 0, 106, 25, 209, 8, 0, 2, 0, 9, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 2, 0, 0, 210, 8, 17, 29, 4, 0, 128, 104, 220, 0, 2, 127, 0, 95, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 128, 116, 220, 0, 7, 127, 0, 85, 0, 130, 191, 2, 129, 0, 191, 83, 0, 132, 191, 3, 132, 0, 191, 26, 0, 133, 191, 3, 130, 0, 191, 11, 0, 132, 191, 0, 0, 143, 210, 129, 6, 2, 0, 127, 192, 140, 191, 0, 106, 25, 209, 8, 0, 2, 0, 9, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 128, 104, 220, 0, 7, 127, 0, 68, 0, 130, 191, 3, 129, 0, 191, 66, 0, 132, 191, 131, 0, 6, 192, 48, 0, 0, 0, 127, 192, 140, 191, 0, 106, 25, 209, 2, 6, 2, 0, 3, 2, 4, 126, 2, 9, 2, 56, 112, 15, 140, 191, 0, 128, 96, 220, 0, 7, 127, 0, 55, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 128, 112, 220, 0, 7, 127, 0, 45, 0, 130, 191, 3, 132, 0, 191, 34, 0, 133, 191, 3, 130, 0, 191, 14, 0, 132, 191, 112, 15, 140, 191, 5, 0, 0, 210, 8, 33, 29, 4, 1, 0, 143, 210, 130, 6, 2, 0, 1, 106, 25, 209, 4, 2, 2, 0, 5, 2, 6, 126, 3, 5, 4, 56, 6, 0, 0, 210, 10, 33, 37, 4, 0, 128, 116, 220, 1, 5, 127, 0, 27, 0, 130, 191, 3, 129, 0, 191, 25, 0, 132, 191, 112, 15, 140, 191, 0, 0, 0, 210, 8, 17, 29, 4, 1, 0, 143, 210, 130, 6, 2, 0, 0, 0, 0, 210, 9, 33, 1, 4, 1, 106, 25, 209, 4, 2, 2, 0, 5, 2, 6, 126, 3, 5, 4, 56, 0, 0, 0, 210, 10, 49, 1, 4, 0, 128, 112, 220, 1, 0, 127, 0, 9, 0, 130, 191, 0, 0, 143, 210, 130, 6, 2, 0, 0, 106, 25, 209, 4, 0, 2, 0, 5, 2, 4, 126, 2, 3, 2, 56, 112, 15, 140, 191, 0, 128, 124, 220, 0, 7, 127, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 19, 0, 19, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 88, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 96, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 193, 208, 1, 27, 0, 0, 12, 0, 136, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 134, 127, 192, 140, 191, 1, 4, 136, 125, 2, 106, 128, 134, 0, 32, 128, 190, 194, 0, 136, 191, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 6, 192, 72, 0, 0, 0, 3, 2, 2, 192, 80, 0, 0, 0, 67, 2, 2, 192, 112, 0, 0, 0, 3, 3, 10, 192, 120, 0, 0, 0, 159, 0, 6, 34, 159, 2, 8, 34, 127, 192, 140, 191, 5, 0, 134, 210, 1, 25, 0, 0, 4, 0, 133, 210, 4, 25, 0, 0, 6, 0, 133, 210, 1, 27, 0, 0, 4, 0, 255, 209, 4, 11, 26, 4, 5, 0, 133, 210, 1, 25, 0, 0, 5, 106, 25, 209, 5, 1, 2, 0, 4, 7, 6, 56, 159, 4, 8, 34, 6, 0, 134, 210, 2, 29, 0, 0, 4, 0, 133, 210, 4, 29, 0, 0, 7, 0, 133, 210, 2, 31, 0, 0, 4, 0, 255, 209, 4, 13, 30, 4, 6, 0, 133, 210, 2, 29, 0, 0, 5, 106, 25, 209, 6, 11, 2, 0, 4, 7, 6, 56, 4, 0, 134, 210, 5, 19, 0, 0, 3, 0, 133, 210, 3, 19, 0, 0, 3, 9, 6, 104, 4, 0, 133, 210, 5, 19, 0, 0, 6, 106, 25, 209, 4, 5, 0, 0, 3, 2, 10, 126, 3, 11, 14, 56, 4, 0, 30, 104, 5, 2, 32, 104, 8, 4, 34, 104, 131, 0, 6, 192, 104, 0, 0, 0, 3, 2, 6, 192, 24, 0, 0, 0, 127, 192, 140, 191, 2, 132, 0, 191, 78, 0, 133, 191, 2, 130, 0, 191, 40, 0, 132, 191, 3, 130, 0, 191, 14, 0, 132, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 80, 220, 3, 0, 127, 3, 112, 15, 140, 191, 249, 2, 12, 126, 3, 6, 5, 0, 249, 2, 10, 126, 3, 6, 4, 0, 57, 0, 130, 191, 3, 129, 0, 191, 13, 0, 132, 191, 3, 0, 143, 210, 129, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 72, 220, 3, 0, 127, 3, 112, 15, 140, 191, 136, 6, 12, 32, 249, 2, 10, 126, 3, 6, 0, 0, 42, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 84, 220, 3, 0, 127, 5, 33, 0, 130, 191, 2, 129, 0, 191, 29, 0, 132, 191, 3, 130, 0, 191, 9, 0, 132, 191, 3, 0, 143, 210, 129, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 72, 220, 3, 0, 127, 5, 19, 0, 130, 191, 3, 129, 0, 191, 7, 0, 132, 191, 3, 106, 25, 209, 8, 12, 2, 0, 9, 2, 10, 126, 5, 15, 8, 56, 0, 128, 64, 220, 3, 0, 127, 5, 10, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 80, 220, 3, 0, 127, 5, 1, 0, 130, 191, 2, 2, 10, 126, 3, 2, 12, 126, 5, 2, 16, 126, 4, 2, 14, 126, 46, 0, 130, 191, 3, 129, 0, 191, 18, 0, 132, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 80, 220, 3, 0, 127, 3, 112, 15, 140, 191, 249, 2, 16, 126, 3, 6, 3, 0, 249, 2, 14, 126, 3, 6, 2, 0, 249, 2, 12, 126, 3, 6, 1, 0, 249, 2, 10, 126, 3, 6, 0, 0, 26, 0, 130, 191, 3, 0, 143, 210, 130, 12, 2, 0, 3, 106, 25, 209, 8, 6, 2, 0, 9, 2, 10, 126, 5, 9, 8, 56, 0, 128, 80, 220, 3, 0, 127, 5, 3, 130, 0, 191, 12, 0, 132, 191, 4, 128, 80, 220, 3, 0, 127, 3, 112, 15, 140, 191, 249, 2, 16, 126, 3, 6, 5, 0, 249, 2, 14, 126, 3, 6, 4, 0, 249, 2, 12, 126, 5, 6, 5, 0, 249, 2, 10, 126, 5, 6, 4, 0, 4, 0, 130, 191, 12, 128, 80, 220, 3, 0, 127, 8, 4, 128, 84, 220, 3, 0, 127, 6, 131, 0, 6, 192, 32, 0, 0, 0, 127, 192, 140, 191, 1, 1, 14, 192, 0, 0, 0, 0, 128, 2, 36, 126, 112, 0, 140, 191, 0, 95, 32, 240, 15, 5, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 80, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 198, 208, 1, 27, 0, 0, 12, 0, 134, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 135, 127, 192, 140, 191, 1, 4, 134, 125, 2, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 28, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 2, 192, 48, 0, 0, 0, 127, 192, 140, 191, 4, 3, 14, 192, 0, 0, 0, 0, 2, 0, 6, 104, 3, 2, 8, 104, 4, 4, 10, 104, 128, 2, 12, 126, 127, 192, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 3, 1, 10, 192, 56, 0, 0, 0, 5, 2, 14, 192, 0, 0, 0, 0, 127, 192, 140, 191, 4, 0, 14, 104, 5, 2, 16, 104, 6, 4, 18, 104, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 21, 0, 21, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 80, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 198, 208, 1, 27, 0, 0, 12, 0, 134, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 135, 127, 192, 140, 191, 1, 4, 134, 125, 2, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 233, 2, 136, 191, 131, 0, 6, 192, 24, 0, 0, 0, 3, 1, 6, 192, 40, 0, 0, 0, 3, 2, 2, 192, 48, 0, 0, 0, 127, 192, 140, 191, 1, 3, 14, 192, 0, 0, 0, 0, 4, 0, 6, 104, 5, 2, 8, 104, 8, 4, 10, 104, 128, 2, 12, 126, 127, 192, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 112, 15, 140, 191, 106, 0, 16, 208, 3, 7, 1, 0, 3, 0, 0, 209, 3, 1, 169, 1, 126, 1, 130, 190, 4, 0, 91, 208, 3, 229, 1, 0, 227, 0, 136, 191, 126, 1, 132, 190, 8, 0, 81, 208, 3, 1, 1, 0, 128, 2, 6, 126, 4, 126, 254, 137, 220, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 126, 1, 138, 190, 8, 0, 81, 208, 3, 17, 0, 0, 255, 6, 6, 10, 82, 184, 78, 65, 10, 126, 254, 137, 242, 6, 6, 10, 210, 0, 136, 191, 255, 6, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 136, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 17, 0, 0, 126, 1, 136, 190, 8, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 104, 0, 0, 128, 0, 255, 18, 18, 104, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 104, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 128, 84, 220, 10, 0, 127, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 15, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 104, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 15, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 30, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 31, 26, 2, 8, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 15, 0, 193, 209, 9, 227, 41, 132, 15, 17, 26, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 8, 1, 254, 190, 8, 27, 20, 4, 15, 29, 18, 4, 15, 21, 20, 2, 12, 19, 18, 4, 255, 26, 22, 38, 0, 240, 255, 255, 9, 21, 18, 2, 13, 23, 16, 4, 9, 17, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 11, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 11, 17, 18, 46, 0, 80, 213, 62, 255, 18, 20, 10, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 38, 131, 24, 24, 36, 255, 0, 137, 190, 85, 85, 85, 85, 255, 0, 136, 190, 85, 85, 85, 85, 12, 106, 25, 209, 8, 24, 2, 0, 9, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 136, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 193, 209, 8, 22, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 23, 16, 2, 14, 31, 22, 46, 239, 47, 228, 183, 8, 23, 22, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 136, 190, 171, 170, 42, 61, 8, 22, 28, 44, 14, 0, 193, 209, 14, 23, 194, 3, 11, 23, 30, 10, 14, 31, 22, 44, 255, 0, 136, 190, 8, 227, 130, 180, 255, 0, 137, 190, 24, 114, 177, 66, 112, 15, 140, 191, 13, 23, 26, 44, 12, 0, 68, 208, 8, 17, 0, 0, 9, 18, 132, 124, 12, 23, 26, 44, 106, 12, 140, 134, 9, 18, 130, 124, 134, 20, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 136, 190, 208, 142, 206, 194, 8, 21, 16, 0, 8, 18, 150, 124, 128, 16, 16, 0, 3, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 136, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 8, 0, 194, 208, 3, 17, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 34, 0, 3, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 7, 14, 0, 242, 6, 138, 125, 242, 14, 6, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 136, 190, 61, 10, 135, 63, 3, 0, 193, 209, 3, 17, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 6, 126, 2, 1, 254, 190, 106, 0, 16, 208, 4, 7, 1, 0, 4, 0, 0, 209, 4, 1, 169, 1, 242, 8, 156, 124, 2, 106, 254, 134, 227, 0, 136, 191, 126, 1, 132, 190, 8, 0, 81, 208, 4, 1, 1, 0, 128, 2, 8, 126, 4, 126, 254, 137, 220, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 126, 1, 138, 190, 8, 0, 81, 208, 4, 17, 0, 0, 255, 8, 8, 10, 82, 184, 78, 65, 10, 126, 254, 137, 242, 8, 8, 10, 210, 0, 136, 191, 255, 8, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 136, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 17, 0, 0, 126, 1, 136, 190, 8, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 104, 0, 0, 128, 0, 255, 18, 18, 104, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 104, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 128, 84, 220, 10, 0, 127, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 15, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 104, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 15, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 30, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 31, 26, 2, 8, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 15, 0, 193, 209, 9, 227, 41, 132, 15, 17, 26, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 8, 1, 254, 190, 8, 27, 20, 4, 15, 29, 18, 4, 15, 21, 20, 2, 12, 19, 18, 4, 255, 26, 22, 38, 0, 240, 255, 255, 9, 21, 18, 2, 13, 23, 16, 4, 9, 17, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 11, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 11, 17, 18, 46, 0, 80, 213, 62, 255, 18, 20, 10, 59, 170, 184, 66, 10, 17, 20, 126, 191, 20, 24, 38, 131, 24, 24, 36, 255, 0, 137, 190, 85, 85, 85, 85, 255, 0, 136, 190, 85, 85, 85, 85, 12, 106, 25, 209, 8, 24, 2, 0, 9, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 136, 190, 0, 80, 213, 62, 10, 11, 28, 126, 11, 0, 193, 209, 8, 22, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 23, 16, 2, 14, 31, 22, 46, 239, 47, 228, 183, 8, 23, 22, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 136, 190, 171, 170, 42, 61, 8, 22, 28, 44, 14, 0, 193, 209, 14, 23, 194, 3, 11, 23, 30, 10, 14, 31, 22, 44, 255, 0, 136, 190, 8, 227, 130, 180, 255, 0, 137, 190, 24, 114, 177, 66, 112, 15, 140, 191, 13, 23, 26, 44, 12, 0, 68, 208, 8, 17, 0, 0, 9, 18, 132, 124, 12, 23, 26, 44, 106, 12, 140, 134, 9, 18, 130, 124, 134, 20, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 136, 190, 208, 142, 206, 194, 8, 21, 16, 0, 8, 18, 150, 124, 128, 16, 16, 0, 4, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 136, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 8, 0, 194, 208, 4, 17, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 34, 0, 4, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 9, 14, 0, 242, 8, 138, 125, 242, 14, 8, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 136, 190, 61, 10, 135, 63, 4, 0, 193, 209, 4, 17, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 8, 126, 2, 1, 254, 190, 3, 2, 10, 192, 56, 0, 0, 0, 106, 0, 16, 208, 5, 7, 1, 0, 5, 0, 0, 209, 5, 1, 169, 1, 127, 192, 140, 191, 8, 0, 34, 104, 9, 2, 36, 104, 10, 4, 38, 104, 126, 1, 130, 190, 4, 0, 91, 208, 5, 229, 1, 0, 227, 0, 136, 191, 126, 1, 132, 190, 8, 0, 81, 208, 5, 1, 1, 0, 128, 2, 10, 126, 4, 126, 254, 137, 220, 0, 136, 191, 255, 0, 136, 190, 28, 46, 77, 59, 126, 1, 138, 190, 8, 0, 81, 208, 5, 17, 0, 0, 255, 10, 10, 10, 82, 184, 78, 65, 10, 126, 254, 137, 242, 10, 10, 10, 210, 0, 136, 191, 255, 10, 14, 38, 255, 255, 255, 127, 242, 14, 16, 4, 255, 0, 136, 190, 0, 0, 128, 61, 106, 1, 75, 208, 8, 17, 0, 0, 126, 1, 136, 190, 8, 106, 254, 137, 7, 105, 16, 126, 70, 0, 136, 191, 129, 16, 18, 36, 255, 16, 16, 104, 0, 0, 128, 0, 255, 18, 18, 104, 0, 0, 0, 1, 255, 16, 20, 38, 0, 0, 127, 0, 255, 18, 18, 38, 0, 0, 1, 0, 9, 21, 18, 104, 249, 2, 20, 126, 9, 6, 5, 0, 128, 2, 22, 126, 10, 0, 143, 210, 131, 20, 2, 0, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 12, 106, 25, 209, 12, 20, 2, 0, 13, 2, 26, 126, 13, 23, 26, 56, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 141, 190, 85, 85, 85, 85, 255, 0, 140, 190, 85, 85, 85, 85, 10, 106, 25, 209, 12, 20, 2, 0, 13, 2, 28, 126, 14, 23, 22, 56, 0, 128, 84, 220, 10, 0, 127, 10, 255, 16, 16, 38, 255, 255, 127, 0, 240, 18, 18, 40, 240, 16, 16, 40, 9, 17, 16, 4, 113, 15, 140, 191, 13, 17, 18, 10, 12, 17, 18, 44, 255, 2, 28, 126, 171, 170, 170, 62, 255, 0, 140, 190, 0, 0, 128, 62, 7, 103, 30, 126, 12, 18, 28, 44, 12, 0, 193, 209, 12, 17, 38, 132, 193, 30, 30, 104, 14, 0, 193, 209, 9, 29, 194, 3, 9, 19, 32, 10, 13, 17, 24, 44, 15, 11, 16, 126, 14, 33, 24, 44, 255, 0, 140, 190, 244, 253, 5, 56, 12, 0, 193, 209, 8, 25, 48, 132, 112, 15, 140, 191, 12, 23, 24, 2, 8, 21, 16, 46, 0, 112, 49, 63, 12, 19, 26, 4, 255, 18, 28, 42, 0, 0, 0, 128, 8, 27, 30, 2, 8, 126, 254, 137, 8, 17, 18, 10, 21, 0, 136, 191, 8, 19, 20, 10, 255, 2, 22, 126, 171, 170, 42, 62, 255, 0, 140, 190, 37, 73, 18, 62, 12, 16, 22, 44, 8, 23, 22, 48, 205, 204, 76, 62, 8, 23, 22, 48, 0, 0, 128, 62, 8, 23, 22, 48, 171, 170, 170, 62, 10, 23, 20, 10, 241, 18, 28, 10, 13, 0, 193, 209, 9, 227, 41, 132, 13, 17, 30, 4, 255, 20, 24, 42, 0, 0, 0, 128, 255, 16, 16, 42, 0, 0, 0, 128, 8, 1, 254, 190, 8, 31, 16, 4, 13, 29, 20, 4, 13, 17, 16, 2, 12, 21, 18, 4, 255, 30, 20, 38, 0, 240, 255, 255, 9, 17, 16, 2, 15, 21, 18, 4, 8, 19, 16, 2, 255, 16, 18, 10, 0, 160, 42, 56, 10, 19, 18, 46, 0, 160, 42, 56, 8, 19, 16, 46, 0, 80, 213, 62, 10, 17, 18, 46, 0, 80, 213, 62, 255, 18, 22, 10, 59, 170, 184, 66, 11, 17, 22, 126, 191, 22, 24, 38, 131, 24, 24, 36, 255, 0, 137, 190, 85, 85, 85, 85, 255, 0, 136, 190, 85, 85, 85, 85, 12, 106, 25, 209, 8, 24, 2, 0, 9, 2, 26, 126, 13, 106, 28, 209, 13, 1, 169, 1, 0, 128, 84, 220, 12, 0, 127, 12, 255, 0, 136, 190, 0, 80, 213, 62, 11, 11, 28, 126, 10, 0, 193, 209, 8, 20, 38, 132, 14, 19, 30, 46, 0, 0, 49, 188, 8, 21, 16, 2, 14, 31, 20, 46, 239, 47, 228, 183, 8, 21, 20, 2, 255, 2, 28, 126, 171, 170, 42, 62, 255, 0, 136, 190, 171, 170, 42, 61, 8, 20, 28, 44, 14, 0, 193, 209, 14, 21, 194, 3, 10, 21, 30, 10, 14, 31, 20, 44, 255, 0, 136, 190, 8, 227, 130, 180, 255, 0, 137, 190, 24, 114, 177, 66, 112, 15, 140, 191, 13, 21, 26, 44, 12, 0, 68, 208, 8, 17, 0, 0, 9, 18, 132, 124, 12, 21, 26, 44, 106, 12, 140, 134, 9, 18, 130, 124, 134, 22, 16, 34, 12, 27, 20, 2, 106, 12, 234, 135, 8, 0, 136, 210, 10, 17, 2, 0, 255, 2, 20, 126, 0, 0, 128, 127, 255, 0, 136, 190, 208, 142, 206, 194, 8, 21, 16, 0, 8, 18, 150, 124, 128, 16, 16, 0, 5, 15, 138, 125, 242, 16, 16, 10, 255, 2, 18, 126, 0, 0, 192, 127, 255, 0, 136, 190, 0, 0, 128, 255, 8, 19, 16, 0, 128, 14, 138, 125, 8, 0, 194, 208, 5, 17, 0, 0, 128, 16, 16, 0, 255, 2, 18, 126, 0, 0, 128, 127, 8, 0, 0, 209, 8, 19, 34, 0, 5, 19, 132, 125, 8, 19, 16, 0, 7, 19, 152, 125, 8, 11, 14, 0, 242, 10, 138, 125, 242, 14, 10, 0, 255, 2, 14, 126, 174, 71, 97, 189, 255, 0, 136, 190, 61, 10, 135, 63, 5, 0, 193, 209, 5, 17, 28, 4, 4, 1, 254, 190, 2, 126, 254, 137, 242, 2, 10, 126, 2, 1, 254, 190, 131, 0, 6, 192, 32, 0, 0, 0, 127, 192, 140, 191, 1, 1, 14, 192, 0, 0, 0, 0, 128, 2, 40, 126, 127, 192, 140, 191, 0, 95, 32, 240, 17, 3, 1, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 72, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 80, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 198, 208, 1, 27, 0, 0, 12, 0, 134, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 135, 127, 192, 140, 191, 1, 4, 134, 125, 2, 106, 234, 135, 126, 1, 128, 190, 0, 106, 254, 137, 28, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 131, 0, 6, 192, 40, 0, 0, 0, 3, 1, 2, 192, 48, 0, 0, 0, 127, 192, 140, 191, 4, 3, 14, 192, 0, 0, 0, 0, 2, 0, 6, 104, 3, 2, 8, 104, 4, 4, 10, 104, 128, 2, 12, 126, 127, 192, 140, 191, 0, 95, 0, 240, 3, 3, 3, 0, 3, 1, 10, 192, 56, 0, 0, 0, 5, 2, 14, 192, 0, 0, 0, 0, 127, 192, 140, 191, 4, 0, 14, 104, 5, 2, 16, 104, 6, 4, 18, 104, 128, 2, 20, 126, 112, 15, 140, 191, 0, 95, 32, 240, 7, 3, 2, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 172, 0, 148, 0, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 5, 0, 5, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 4, 134, 255, 255, 0, 0, 4, 10, 4, 146, 3, 0, 6, 192, 0, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 72, 0, 0, 0, 0, 2, 2, 126, 0, 0, 255, 209, 4, 2, 2, 4, 126, 1, 130, 190, 127, 192, 140, 191, 0, 0, 209, 208, 0, 3, 0, 0, 20, 0, 136, 191, 3, 2, 10, 192, 24, 0, 0, 0, 3, 0, 2, 192, 40, 0, 0, 0, 127, 192, 140, 191, 4, 3, 10, 192, 0, 0, 0, 0, 0, 0, 2, 104, 127, 192, 140, 191, 0, 32, 12, 224, 1, 1, 3, 128, 3, 0, 2, 192, 56, 0, 0, 0, 5, 1, 10, 192, 0, 0, 0, 0, 127, 192, 140, 191, 0, 0, 0, 104, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 13, 0, 13, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 6, 192, 0, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 72, 0, 0, 0, 0, 2, 6, 126, 0, 0, 255, 209, 8, 6, 2, 4, 126, 1, 130, 190, 127, 192, 140, 191, 0, 0, 209, 208, 0, 3, 0, 0, 29, 0, 136, 191, 3, 2, 14, 192, 8, 0, 0, 0, 3, 0, 2, 192, 40, 0, 0, 0, 127, 192, 140, 191, 6, 4, 10, 192, 0, 0, 0, 0, 0, 0, 6, 104, 127, 192, 140, 191, 0, 32, 12, 224, 3, 3, 4, 128, 3, 4, 10, 192, 56, 0, 0, 0, 7, 5, 14, 192, 0, 0, 0, 0, 5, 10, 0, 128, 127, 192, 140, 191, 18, 2, 14, 126, 4, 8, 1, 128, 17, 2, 16, 126, 16, 0, 18, 104, 11, 0, 255, 209, 0, 14, 10, 4, 10, 0, 255, 209, 1, 16, 6, 4, 128, 2, 24, 126, 112, 15, 140, 191, 0, 95, 32, 240, 9, 3, 5, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 9, 0, 9, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 6, 192, 0, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 72, 0, 0, 0, 0, 2, 6, 126, 0, 0, 255, 209, 8, 6, 2, 4, 126, 1, 130, 190, 127, 192, 140, 191, 0, 0, 209, 208, 0, 3, 0, 0, 31, 0, 136, 191, 3, 2, 14, 192, 8, 0, 0, 0, 3, 0, 6, 192, 40, 0, 0, 0, 127, 192, 140, 191, 67, 2, 2, 192, 48, 0, 0, 0, 6, 4, 14, 192, 0, 0, 0, 0, 5, 10, 5, 128, 127, 192, 140, 191, 9, 2, 6, 126, 4, 8, 4, 128, 1, 2, 8, 126, 0, 0, 10, 104, 7, 0, 255, 209, 5, 6, 10, 4, 6, 0, 255, 209, 4, 8, 6, 4, 128, 2, 16, 126, 0, 95, 0, 240, 5, 1, 4, 0, 3, 0, 2, 192, 56, 0, 0, 0, 7, 1, 10, 192, 0, 0, 0, 0, 127, 192, 140, 191, 0, 0, 0, 104, 112, 15, 140, 191, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 172, 0, 148, 19, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 11, 0, 11, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 6, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 8, 134, 255, 255, 0, 0, 4, 255, 132, 146, 16, 0, 16, 0, 5, 255, 5, 134, 255, 255, 0, 0, 8, 10, 8, 146, 4, 11, 4, 146, 5, 12, 5, 146, 3, 0, 10, 192, 0, 0, 0, 0, 131, 2, 6, 192, 16, 0, 0, 0, 3, 3, 6, 192, 96, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 104, 0, 0, 0, 0, 2, 6, 126, 2, 2, 8, 126, 0, 0, 255, 209, 8, 6, 2, 4, 1, 0, 255, 209, 4, 8, 6, 4, 10, 2, 6, 126, 2, 0, 193, 208, 1, 27, 0, 0, 12, 0, 136, 125, 2, 0, 255, 209, 5, 6, 10, 4, 106, 2, 130, 134, 127, 192, 140, 191, 1, 4, 136, 125, 2, 106, 128, 134, 0, 32, 128, 190, 55, 0, 136, 191, 3, 2, 10, 192, 80, 0, 0, 0, 127, 192, 140, 191, 8, 0, 14, 104, 9, 2, 16, 104, 10, 4, 18, 104, 131, 0, 2, 192, 112, 0, 0, 0, 3, 1, 6, 192, 24, 0, 0, 0, 127, 192, 140, 191, 2, 130, 0, 191, 30, 0, 133, 191, 2, 129, 0, 191, 13, 0, 132, 191, 3, 2, 10, 192, 48, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 27, 0, 130, 191, 2, 128, 0, 191, 25, 0, 132, 191, 3, 2, 10, 192, 32, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 12, 0, 130, 191, 3, 2, 10, 192, 64, 0, 0, 0, 2, 3, 14, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 0, 126, 9, 2, 2, 126, 10, 2, 4, 126, 11, 2, 6, 126, 128, 2, 20, 126, 0, 95, 32, 240, 7, 0, 3, 0, 0, 0, 129, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 172, 0, 148, 0, 0, 0, 43, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 5, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 192, 4, 0, 0, 0, 127, 192, 140, 191, 4, 255, 4, 134, 255, 255, 0, 0, 4, 10, 4, 146, 3, 0, 6, 192, 0, 0, 0, 0, 127, 192, 140, 191, 67, 0, 2, 192, 96, 0, 0, 0, 0, 2, 2, 126, 0, 0, 255, 209, 4, 2, 2, 4, 126, 1, 130, 190, 127, 192, 140, 191, 0, 0, 209, 208, 0, 3, 0, 0, 50, 0, 136, 191, 3, 0, 2, 192, 80, 0, 0, 0, 127, 192, 140, 191, 0, 0, 0, 104, 3, 0, 2, 192, 112, 0, 0, 0, 3, 1, 6, 192, 24, 0, 0, 0, 127, 192, 140, 191, 0, 130, 0, 191, 28, 0, 133, 191, 0, 129, 0, 191, 12, 0, 132, 191, 3, 2, 10, 192, 48, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 25, 0, 130, 191, 0, 128, 0, 191, 23, 0, 132, 191, 3, 2, 10, 192, 32, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 11, 0, 130, 191, 3, 2, 10, 192, 64, 0, 0, 0, 2, 1, 10, 192, 0, 0, 0, 0, 127, 192, 140, 191, 8, 2, 2, 126, 9, 2, 4, 126, 10, 2, 6, 126, 11, 2, 8, 126, 0, 32, 28, 224, 0, 1, 1, 128, 0, 0, 129, 191, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 1, 0, 4, 0, 8, 2, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 0, 4, 0, 16, 6, 0, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 26, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 4, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 26, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 168, 4, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 26, 0, 5, 0, 0, 10, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 26, 0, 5, 0, 0, 13, 0, 0, 0, 0, 0, 0, 72, 13, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 26, 0, 5, 0, 0, 27, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 33, 1, 0, 0, 26, 0, 5, 0, 0, 30, 0, 0, 0, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 58, 1, 0, 0, 26, 0, 5, 0, 0, 32, 0, 0, 0, 0, 0, 0, 220, 1, 0, 0, 0, 0, 0, 0, 90, 1, 0, 0, 26, 0, 5, 0, 0, 34, 0, 0, 0, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 0, 122, 1, 0, 0, 26, 0, 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 144, 1, 0, 0, 26, 0, 5, 0, 0, 39, 0, 0, 0, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 170, 1, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 1, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 15, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 15, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 15, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 15, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 17, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 19, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 19, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 19, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 19, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 20, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 21, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 23, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 23, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 23, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 23, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 24, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 240, 2, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 3, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 3, 0, 0, 0, 0, 0, 0, 24, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 1, 0, 0, 0, 7, 0, 192, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 24, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 55, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 56, 0, 0, 0, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0};\n}\n}\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_src/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.7 )\n\n# Import target 'clang'\nfind_package(Clang REQUIRED HINTS ${CMAKE_PREFIX_PATH}/llvm PATHS /opt/rocm/llvm )\n\n# Determine the target devices if not specified\nif (NOT DEFINED TARGET_DEVICES)\n  set (TARGET_DEVICES \"gfx700;gfx701;gfx702;gfx801;gfx802;gfx803;gfx805;gfx810\"\n                      \"gfx900;gfx902;gfx904;gfx906;gfx908;gfx909;gfx90a;gfx90c;gfx942;gfx950\"\n                      \"gfx1010;gfx1011;gfx1012;gfx1013;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036\"\n                      \"gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151;gfx1152;gfx1153;gfx1200;gfx1201\")\nendif()\nset( TARGET_DEVICES ${TARGET_DEVICES} CACHE STRING \"Build targets\" FORCE )\n\nif(${CMAKE_VERBOSE_MAKEFILE})\n  get_property(clang_path TARGET clang PROPERTY LOCATION)\n  message(\"Using clang from: ${clang_path}\")\n  message(\"Build Setting:\")\n  message(\"  Target Devices*: ${TARGET_DEVICES}\")\n  message(\"  (Specify \\\";\\\" separated list of target IDs.)\")\n  message(\"       Clang path: ${clang_path}\")\nendif()\n\n##==========================================\n##  Add custom command to generate a kernel code object file\n##==========================================\nfunction(gen_kernel_bc TARGET_ID INPUT_FILE OUTPUT_FILE)\n\n  separate_arguments(CLANG_ARG_LIST UNIX_COMMAND\n    \"-O2 -x cl -Xclang -finclude-default-header -cl-denorms-are-zero -cl-std=CL2.0\n    -target amdgcn-amd-amdhsa -mcpu=${TARGET_ID} -mcode-object-version=4\n    -o ${OUTPUT_FILE} ${INPUT_FILE}\")\n\n  ## Add custom command to produce a code object file.\n  ## This depends on the kernel source file & compiler.\n  add_custom_command(OUTPUT ${OUTPUT_FILE} COMMAND clang ${CLANG_ARG_LIST}\n    DEPENDS ${INPUT_FILE} clang\n    COMMENT \"BUILDING bitcode for ${OUTPUT_FILE}...\"\n    VERBATIM)\n\nif(${CMAKE_VERBOSE_MAKEFILE})\n  message(\"      Kernel Source: \" ${INPUT_FILE})\n  message(\"     Kernel Bitcode: \" ${OUTPUT_FILE})\nendif()\n\nendfunction(gen_kernel_bc)\n\n##==========================================\n## Find device code object name and forward to custom command\n##==========================================\nfunction(build_kernel BLIT_NAME TARGET_ID)\n\n  ## generate kernel bitcodes\n  set (CODE_OBJECT_FILE \"${BLIT_NAME}_${TARGET_ID}\")\n  set (CL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/imageblit_kernels.cl)\n  gen_kernel_bc(${TARGET_ID} ${CL_FILE} ${CODE_OBJECT_FILE})\n\n  ## Build a list of code object file names\n  ## These will be target dependencies.\n  set (HSACO_TARG_LIST ${HSACO_TARG_LIST} \"${CODE_OBJECT_FILE}\" PARENT_SCOPE)\n\nendfunction(build_kernel)\n\n##==========================================\n## Build the kernel for a list of devices\n##==========================================\nfunction(build_kernel_for_devices BLIT_NAME)\n\n  set(HSACO_TARG_LIST \"\")\n\n  foreach(dev ${TARGET_DEVICES})\n    if(${CMAKE_VERBOSE_MAKEFILE})\n      message(\"\\n  Generating: ${dev} ...\")\n    endif()\n    build_kernel(${BLIT_NAME} ${dev})\n  endforeach(dev)\n\n  set(HSACO_TARG_LIST ${HSACO_TARG_LIST} PARENT_SCOPE)\n\nendfunction(build_kernel_for_devices)\n\n##==========================================\n## Create BLIT Code Object blobs file\n##==========================================\nfunction(generate_blit_file BFILE)\n\n  ## Add a custom command that generates opencl_blit_objects.cpp\n  ## This depends on all the generated code object files and the C++ generator script.\n  add_custom_command(OUTPUT ${BFILE}.cpp\n                     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create_hsaco_ascii_file.sh ${CMAKE_CURRENT_BINARY_DIR}/${BFILE}.cpp\n                     DEPENDS ${HSACO_TARG_LIST} create_hsaco_ascii_file.sh )\n\n  ## Export a target that builds (and depends on) opencl_blit_objects.cpp\n  add_custom_target( ${BFILE} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BFILE}.cpp )\n\nendfunction(generate_blit_file)\n\nbuild_kernel_for_devices(\"ocl_blit_object\")\ngenerate_blit_file(\"opencl_blit_objects\")\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_src/README.md",
    "content": "## OVERVIEW\n\nThis directory contains the CMakeLists.txt for automatically generating\nthe ASCII code object file, \"opencl_blit_objects.cpp\", which contains the\nblobs of the code object of the Image BLIT kernels for the devices supported\non ROCm.  The blobs are loaded by the image library and required to update\nwhenever a new device is introduced.\n\n\n## ADD NEW DEVICE\n\nTo add a new supported device, the following steps are required:\n\n  1. Declare an extern variable of the device XXX, by adding the line of\n     \"extern uint32_t ocl_blit_object_gfxNNN[];\" in \"blit_kernel.cpp\".\n  2. Update the BlitKernel::GetPatchedBlitObject() function to support the\n     device by assigning \"blit_code_object\" to \"ocl_blit_object_gfxNNN[]\".\n  3. Add the target to the TARGET_DEVICES list in CMakeLists.txt. Specify using\n     the target ID syntax which is the target GFX IP name, optionally followed\n     by the settings for the target features such as XNACK and SRAMECC. If\n     omitted, a target feature defaults to producing code that will execute on\n     any setting. For example, \"gfx908\" for code that will run on any setting,\n     or \"gfx908:sramecc+:xnack-\" for code that will only run if SRAMECC is\n     enabled and XNACK is disabled.\n  4. Rebuild the image library.\n\n\n## REQUIREMENT\n\nIn order to create the code object file, the bitcodes of the kernels are\ngenerated by the compiler and the following bitcode libraries are required,\n\n   opencl.bc\n   ocml.bc\n   irif.bc\n   oclc_correctly_rounded_sqrt_off.bc\n   oclc_daz_opt_on.bc\n   oclc_finite_only_off.bc\n   oclc_isa_version_<GFXIP>.bc\n   oclc_unsafe_math_off.bc\n\nwhere <GFXIP> is the gfxip number of the GPU. The directory contains the\nbitcode libraries is specified in a CMake varaible.\n\nThere are several variables are required for CMake to build the code\nobject file.  All of them have default values, and defined as following:\n\n      OPENCL_DIR - the location of installed OpenCL\n                   (Default: /opt/rocm/opencl)\n     BITCODE_DIR - the directory contains the bitcode library\n                   (Default: /opt/rocm/amdgcn/bitcode)\n        LLVM_DIR - the directory contains the clang, llvm-link and llvm-dis\n                   executables\n                   (Default: ${PROJECT_BUILD_DIR}/../lightning/bin)\n  TARGET_DEVICES - list of gpu types for kernel builds (eg. \"gfx900;gfx902\")\n                   (Default: \"gfx900;gfx902;gfx904\")\n\n\n## STEPS TO BUILD\n\n  $ make build\n  $ cd build\n  $ cmake -D${OPENCL_DIR} -D${BITCODE_DIR} -D${LLVM_DIR} -D${TARGET_DEVICES} ..\n  $ make opencl_blit_objects.cpp\n\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_src/create_hsaco_ascii_file.sh",
    "content": "#!/bin/bash -e\n################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and/or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and/or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\nopencl_blit_file=\"$1\"\n\nif ! command -v xxd >/dev/null\nthen\n    echo \"xxd not found!\"\n    exit 1\nfi\n\n# Create the file in a temporary location and then move it in atomically\n{\ncat <<EOF\n//==============================================================================\n//  This file is automatically generated during build process, don't modify it\n//==============================================================================\n\nnamespace rocr {\nnamespace image {\n\nEOF\n\nfor file in ocl_blit_object*\ndo\n    xxd -i $file\n    echo -e '\\n'\ndone\n\ncat <<EOF\n} // namespace image\n} // namespace rocr\n\nEOF\n\n} > \"$opencl_blit_file\"\n"
  },
  {
    "path": "runtime/hsa-runtime/image/blit_src/imageblit_kernels.cl",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n/// Kernel code for HSA image import/export/copy/clear in OpenCL C form.\n\nuint4 read_image(__read_only image1d_t src1d,\n                 __read_only image2d_t src2d,\n                 __read_only image3d_t src3d,\n                 __read_only image1d_array_t src1da,\n                 __read_only image2d_array_t src2da,\n                 uint format,\n                 int4 coords) {\n  switch (format) {\n    case 0:  // 1D\n      return read_imageui(src1d, coords.x);\n      break;\n    case 1:  // 2D\n      return read_imageui(src2d, coords.xy);\n      break;\n    case 2:  // 3D\n      return read_imageui(src3d, coords);\n      break;\n    case 3:  // 1DA\n      return read_imageui(src1da, coords.xy);\n      break;\n    case 4:  // 2DA\n      return read_imageui(src2da, coords);\n      break;\n    // case 5: //1DB\n    //  return read_imageui(src1db, coords.x);\n    //  break;\n    default:  // Critical failure.\n      return 0;\n  }\n}\n\nvoid write_image(__write_only image1d_t src1d,\n                 __write_only image2d_t src2d,\n                 __write_only image3d_t src3d,\n                 __write_only image1d_array_t src1da,\n                 __write_only image2d_array_t src2da,\n                 uint format,\n                 int4 coords,\n                 uint4 texel) {\n  switch (format) {\n    case 0:  // 1D\n      write_imageui(src1d, coords.x, texel);\n      break;\n    case 1:  // 2D\n      write_imageui(src2d, coords.xy, texel);\n      break;\n    case 2:  // 3D\n      write_imageui(src3d, coords, texel);\n      break;\n    case 3:  // 1DA\n      write_imageui(src1da, coords.xy, texel);\n      break;\n    case 4:  // 2DA\n      write_imageui(src2da, coords, texel);\n      break;\n    // case 5: //1DB\n    //  write_imageui(src1db, coords.x, texel);\n    //  break;\n    default:  // Critical failure.\n      return;\n  }\n}\n\nfloat4 read_image_float(__read_only image1d_t src1d,\n                        __read_only image2d_t src2d,\n                        __read_only image3d_t src3d,\n                        __read_only image1d_array_t src1da,\n                        __read_only image2d_array_t src2da,\n                        uint format,\n                        int4 coords) {\n  switch (format) {\n    case 0:  // 1D\n      return read_imagef(src1d, coords.x);\n      break;\n    case 1:  // 2D\n      return read_imagef(src2d, coords.xy);\n      break;\n    case 2:  // 3D\n      return read_imagef(src3d, coords);\n      break;\n    case 3:  // 1DA\n      return read_imagef(src1da, coords.xy);\n      break;\n    case 4:  // 2DA\n      return read_imagef(src2da, coords);\n      break;\n    default:  // Critical failure.\n      return 0;\n  }\n}\n\nvoid write_image_float(__write_only image1d_t src1d,\n                       __write_only image2d_t src2d,\n                       __write_only image3d_t src3d,\n                       __write_only image1d_array_t src1da,\n                       __write_only image2d_array_t src2da,\n                       uint format,\n                       int4 coords,\n                       float4 texel) {\n  switch (format) {\n    case 0:  // 1D\n      write_imagef(src1d, coords.x, texel);\n      break;\n    case 1:  // 2D\n      write_imagef(src2d, coords.xy, texel);\n      break;\n    case 2:  // 3D\n      write_imagef(src3d, coords, texel);\n      break;\n    case 3:  // 1DA\n      write_imagef(src1da, coords.xy, texel);\n      break;\n    case 4:  // 2DA\n      write_imagef(src2da, coords, texel);\n      break;\n    default:  // Critical failure.\n      return;\n  }\n}\n\nvoid write_image_int(__write_only image1d_t src1d,\n                     __write_only image2d_t src2d,\n                     __write_only image3d_t src3d,\n                     __write_only image1d_array_t src1da,\n                     __write_only image2d_array_t src2da,\n                     uint format,\n                     int4 coords,\n                     int4 texel) {\n  switch (format) {\n    case 0:  // 1D\n      write_imagei(src1d, coords.x, texel);\n      break;\n    case 1:  // 2D\n      write_imagei(src2d, coords.xy, texel);\n      break;\n    case 2:  // 3D\n      write_imagei(src3d, coords, texel);\n      break;\n    case 3:  // 1DA\n      write_imagei(src1da, coords.xy, texel);\n      break;\n    case 4:  // 2DA\n      write_imagei(src2da, coords, texel);\n      break;\n    default:  // Critical failure.\n      return;\n  }\n}\n\n//image handle is repeated since OCL doesn't allow pointers to or casting of images.\n//dst is start of output pixel in destination buffer\n//format.x is element count\n//format.y is element size\n//format.z is max(dword per pixel, 1)\n//format.w is texture type.\n//srcOrigin is start pixel address.\n//No export for 64, 96, 128 bit formats\n__kernel void copy_image_to_buffer(\n    __read_only image1d_t src1d,\n    __read_only image2d_t src2d,\n    __read_only image3d_t src3d,\n    __read_only image1d_array_t src1da,\n    __read_only image2d_array_t src2da,\n    __global void* const dst,\n    int4        srcOrigin,\n    uint4       format,\n    ulong       pitch,\n    ulong       slice_pitch)\n{\n    ulong    idxDst;\n    int4     coordsSrc;\n    uint4    texel;\n\n    __global uchar* const dstUChar = (__global uchar* const)dst;\n    __global ushort* const dstUShort = (__global ushort* const)dst;\n    __global uint* const dstUInt = (__global uint* const)dst;\n\n    coordsSrc.x = get_global_id(0);\n    coordsSrc.y = get_global_id(1);\n    coordsSrc.z = get_global_id(2);\n    coordsSrc.w = 0;\n\n    idxDst = (coordsSrc.z * slice_pitch + coordsSrc.y * pitch +\n        coordsSrc.x) * format.z;\n\n    coordsSrc.x += srcOrigin.x;\n    coordsSrc.y += srcOrigin.y;\n    coordsSrc.z += srcOrigin.z;\n\n    texel = read_image(src1d, src2d, src3d, src1da, src2da, format.w, coordsSrc);\n\n    // Check components\n    switch (format.x) {\n    case 1:\n        // Check size\n        switch (format.y) {\n        case 1:\n            dstUChar[idxDst] = texel.x;\n            break;\n        case 2:\n            dstUShort[idxDst] = texel.x;\n            break;\n        case 4:\n            dstUInt[idxDst] = texel.x;\n            break;\n        }\n    break;\n    case 2:\n        // Check size\n        switch (format.y) {\n        case 1:\n            dstUShort[idxDst] = texel.x |\n               (texel.y << 8);\n            break;\n        case 2:\n            dstUInt[idxDst] = texel.x | (texel.y << 16);\n            break;\n        case 4:\n            dstUInt[idxDst++] = texel.x;\n            dstUInt[idxDst] = texel.y;\n            break;\n        }\n    break;\n    case 4:\n        // Check size\n        switch (format.y) {\n        case 1:\n            dstUInt[idxDst] = texel.x |\n               (texel.y << 8) |\n               (texel.z << 16) |\n               (texel.w << 24);\n            break;\n        case 2:\n            dstUInt[idxDst++] = texel.x | (texel.y << 16);\n            dstUInt[idxDst] = texel.z | (texel.w << 16);\n            break;\n        case 4:\n            dstUInt[idxDst++] = texel.x;\n            dstUInt[idxDst++] = texel.y;\n            dstUInt[idxDst++] = texel.z;\n            dstUInt[idxDst] = texel.w;\n            break;\n        }\n    break;\n    }\n}\n\n__kernel void copy_buffer_to_image(__global uint* src,\n                                   __write_only image1d_t dst1d,\n                                   __write_only image2d_t dst2d,\n                                   __write_only image3d_t dst3d,\n                                   __write_only image1d_array_t dst1da,\n                                   __write_only image2d_array_t dst2da,\n                                   int4 dstOrigin,\n                                   uint4 format,\n                                   ulong pitch,\n                                   ulong slice_pitch) {\n  ulong idxSrc;\n  int4 coordsDst;\n  uint4 texel;\n\n  __global uint* srcUInt = src;\n  __global ushort* srcUShort = (__global ushort*)src;\n  __global uchar* srcUChar = (__global uchar*)src;\n\n  ushort tmpUShort;\n  uint tmpUInt;\n\n  coordsDst.x = get_global_id(0);\n  coordsDst.y = get_global_id(1);\n  coordsDst.z = get_global_id(2);\n  coordsDst.w = 0;\n\n  idxSrc = (coordsDst.z * slice_pitch + coordsDst.y * pitch + coordsDst.x) * format.z;\n\n  coordsDst.x += dstOrigin.x;\n  coordsDst.y += dstOrigin.y;\n  coordsDst.z += dstOrigin.z;\n\n  // Check components\n  switch (format.x) {\n    case 1:\n        // Check size\n        switch (format.y) {\n          case 1:\n            texel.x = (uint)srcUChar[idxSrc];\n            break;\n          case 2:\n            texel.x = (uint)srcUShort[idxSrc];\n            break;\n          case 4:\n            texel.x = srcUInt[idxSrc];\n            break;\n        }\n    break;\n    case 2:\n        // Check size\n        switch (format.y) {\n          case 1:\n            tmpUShort = srcUShort[idxSrc];\n            texel.x = (uint)(tmpUShort & 0xff);\n            texel.y = (uint)(tmpUShort >> 8);\n            break;\n          case 2:\n            tmpUInt = srcUInt[idxSrc];\n            texel.x = (tmpUInt & 0xffff);\n            texel.y = (tmpUInt >> 16);\n            break;\n          case 4:\n            texel.x = srcUInt[idxSrc++];\n            texel.y = srcUInt[idxSrc];\n            break;\n        }\n    break;\n    case 4:\n        // Check size\n        switch (format.y) {\n          case 1:\n            tmpUInt = srcUInt[idxSrc];\n            texel.x = tmpUInt & 0xff;\n            texel.y = (tmpUInt >> 8) & 0xff;\n            texel.z = (tmpUInt >> 16) & 0xff;\n            texel.w = (tmpUInt >> 24) & 0xff;\n            break;\n          case 2:\n            tmpUInt = srcUInt[idxSrc++];\n            texel.x = tmpUInt & 0xffff;\n            texel.y = (tmpUInt >> 16);\n            tmpUInt = srcUInt[idxSrc];\n            texel.z = tmpUInt & 0xffff;\n            texel.w = (tmpUInt >> 16);\n            break;\n          case 4:\n            texel.x = srcUInt[idxSrc++];\n            texel.y = srcUInt[idxSrc++];\n            texel.z = srcUInt[idxSrc++];\n            texel.w = srcUInt[idxSrc];\n            break;\n        }\n        break;\n    }\n    // Write the final pixel\n    write_image(dst1d, dst2d, dst3d, dst1da, dst2da, format.w, coordsDst, texel);\n}\n\n__kernel void copy_image_default(__read_only image1d_t src1d,\n                                 __read_only image2d_t src2d,\n                                 __read_only image3d_t src3d,\n                                 __read_only image1d_array_t src1da,\n                                 __read_only image2d_array_t src2da,\n                                 __write_only image1d_t dst1d,\n                                 __write_only image2d_t dst2d,\n                                 __write_only image3d_t dst3d,\n                                 __write_only image1d_array_t dst1da,\n                                 __write_only image2d_array_t dst2da,\n                                 int4 srcOrigin,\n                                 int4 dstOrigin,\n                                 int srcFormat,\n                                 int dstFormat) {\n  int4 coordsDst;\n  int4 coordsSrc;\n\n  coordsDst.x = get_global_id(0);\n  coordsDst.y = get_global_id(1);\n  coordsDst.z = get_global_id(2);\n  coordsDst.w = 0;\n\n  coordsSrc = srcOrigin + coordsDst;\n  coordsDst += dstOrigin;\n\n  uint4 texel;\n  texel = read_image(src1d, src2d, src3d, src1da, src2da, srcFormat, coordsSrc);\n  write_image(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coordsDst, texel);\n}\n\nfloat linear_to_standard_rgba(float l_val) {\n  float s_val = l_val;\n\n  if (isnan(s_val)) s_val = 0.0f;\n\n  if (s_val > 1.0f) {\n    s_val = 1.0f;\n  } else if (s_val < 0.0f) {\n    s_val = 0.0f;\n  } else if (s_val < 0.0031308f) {\n    s_val = 12.92f * s_val;\n  } else {\n    s_val = (1.055f * pow(s_val, 5.0f / 12.0f)) - 0.055f;\n  }\n\n  return s_val;\n}\n\n__kernel void copy_image_linear_to_standard(\n                                            __read_only image1d_t src1d,\n                                            __read_only image2d_t src2d,\n                                            __read_only image3d_t src3d,\n                                            __read_only image1d_array_t src1da,\n                                            __read_only image2d_array_t src2da,\n                                            int srcFormat,\n                                            __write_only image1d_t dst1d,\n                                            __write_only image2d_t dst2d,\n                                            __write_only image3d_t dst3d,\n                                            __write_only image1d_array_t dst1da,\n                                            __write_only image2d_array_t dst2da,\n                                            int dstFormat,\n                                            int4 srcOrigin,\n                                            int4 dstOrigin) {\n  int4 coordsDst;\n  int4 coordsSrc;\n\n  coordsDst.x = get_global_id(0);\n  coordsDst.y = get_global_id(1);\n  coordsDst.z = get_global_id(2);\n  coordsDst.w = 0;\n\n  coordsSrc = srcOrigin + coordsDst;\n  coordsDst += dstOrigin;\n\n  float4 texel;\n  texel = read_image_float(src1d, src2d, src3d, src1da, src2da, srcFormat, coordsSrc);\n\n  texel.x = linear_to_standard_rgba(texel.x);\n  texel.y = linear_to_standard_rgba(texel.y);\n  texel.z = linear_to_standard_rgba(texel.z);\n\n  write_image_float(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coordsDst, texel);\n}\n\n__kernel void copy_image_standard_to_linear(\n                                            __read_only image1d_t src1d,\n                                            __read_only image2d_t src2d,\n                                            __read_only image3d_t src3d,\n                                            __read_only image1d_array_t src1da,\n                                            __read_only image2d_array_t src2da,\n                                            int srcFormat,\n                                            __write_only image1d_t dst1d,\n                                            __write_only image2d_t dst2d,\n                                            __write_only image3d_t dst3d,\n                                            __write_only image1d_array_t dst1da,\n                                            __write_only image2d_array_t dst2da,\n                                            int dstFormat,\n                                            int4 srcOrigin,\n                                            int4 dstOrigin) {\n  int4 coordsDst;\n  int4 coordsSrc;\n\n  coordsDst.x = get_global_id(0);\n  coordsDst.y = get_global_id(1);\n  coordsDst.z = get_global_id(2);\n  coordsDst.w = 0;\n\n  coordsSrc = srcOrigin + coordsDst;\n  coordsDst += dstOrigin;\n\n  float4 texel;\n  texel = read_image_float(src1d, src2d, src3d, src1da, src2da, srcFormat, coordsSrc);\n  write_image_float(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coordsDst, texel);\n}\n\n__kernel void copy_image_1db(\n                                            __read_only image1d_buffer_t src1d,\n                                            __read_only image2d_t src2d,\n                                            __read_only image3d_t src3d,\n                                            __read_only image1d_array_t src1da,\n                                            __read_only image2d_array_t src2da,\n                                            int srcFormat,\n                                            __write_only image1d_t dst1d,\n                                            __write_only image2d_t dst2d,\n                                            __write_only image3d_t dst3d,\n                                            __write_only image1d_array_t dst1da,\n                                            __write_only image2d_array_t dst2da,\n                                            int dstFormat,\n                                            int4 srcOrigin,\n                                            int4 dstOrigin)\n{\n    int    coordDst;\n    int    coordSrc;\n\n    coordDst = get_global_id(0);\n\n    coordSrc = srcOrigin.x + coordDst;\n    coordDst += dstOrigin.x;\n\n    uint4  texel;\n    texel = read_imageui(src1d, coordSrc);\n    write_imageui(dst1d, coordDst, texel);\n}\n\n__kernel void copy_image_1db_to_reg(\n                                            __read_only image1d_buffer_t src1d,\n                                            __read_only image2d_t src2d,\n                                            __read_only image3d_t src3d,\n                                            __read_only image1d_array_t src1da,\n                                            __read_only image2d_array_t src2da,\n                                            int srcFormat,\n                                            __write_only image1d_t dst1d,\n                                            __write_only image2d_t dst2d,\n                                            __write_only image3d_t dst3d,\n                                            __write_only image1d_array_t dst1da,\n                                            __write_only image2d_array_t dst2da,\n                                            int dstFormat,\n                                            int4 srcOrigin,\n                                            int4 dstOrigin)\n{\n    int4    coordsDst;\n    int    coordSrc;\n\n    coordsDst.x = get_global_id(0);\n    coordsDst.y = get_global_id(1);\n    coordsDst.z = get_global_id(2);\n    coordsDst.w = 0;\n\n    coordSrc = srcOrigin.x + coordsDst.x;\n    coordsDst += dstOrigin;\n\n    uint4  texel;\n    texel = read_imageui(src1d, coordSrc);\n    write_imageui(dst1d, coordsDst.x, texel);\n}\n\n__kernel void copy_image_reg_to_1db(\n                                            __read_only image1d_t src1d,\n                                            __read_only image2d_t src2d,\n                                            __read_only image3d_t src3d,\n                                            __read_only image1d_array_t src1da,\n                                            __read_only image2d_array_t src2da,\n                                            int srcFormat,\n                                            __write_only image1d_buffer_t dst1d,\n                                            __write_only image2d_t dst2d,\n                                            __write_only image3d_t dst3d,\n                                            __write_only image1d_array_t dst1da,\n                                            __write_only image2d_array_t dst2da,\n                                            int dstFormat,\n                                            int4 srcOrigin,\n                                            int4 dstOrigin)\n{\n    int    coordDst;\n    int4    coordsSrc;\n\n    coordsSrc.x = get_global_id(0);\n    coordsSrc.y = get_global_id(1);\n    coordsSrc.z = get_global_id(2);\n    coordsSrc.w = 0;\n\n    coordDst = dstOrigin.x + coordsSrc.x;\n    coordsSrc += srcOrigin;\n\n    uint4  texel;\n    texel = read_imageui(src1d, coordsSrc.x);\n    write_imageui(dst1d, coordDst, texel);\n}\n\n__kernel void clear_image(__write_only image1d_t dst1d,\n                          __write_only image2d_t dst2d,\n                          __write_only image3d_t dst3d,\n                          __write_only image1d_array_t dst1da,\n                          __write_only image2d_array_t dst2da,\n                          int dstFormat,\n                          uint type,\n                          uint4 fill_data,\n                          int4 origin) {\n  int4 coords;\n\n  coords.x = get_global_id(0);\n  coords.y = get_global_id(1);\n  coords.z = get_global_id(2);\n  coords.w = 0;\n\n  coords += origin;\n\n  // Check components\n  switch (type) {\n    case 0:\n      write_image_float(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coords, *(float4*)&fill_data);\n      break;\n    case 1:\n      write_image_int(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coords, *(int4*)&fill_data);\n      break;\n    case 2:\n      write_image(dst1d, dst2d, dst3d, dst1da, dst2da, dstFormat, coords, fill_data);\n      break;\n    }\n}\n\n__kernel void clear_image_1db(__write_only image1d_buffer_t dst1d,\n                              __write_only image2d_t dst2d,\n                              __write_only image3d_t dst3d,\n                              __write_only image1d_array_t dst1da,\n                              __write_only image2d_array_t dst2da,\n                              int dstFormat,\n                              uint4 fill_data,\n                              int4 origin,\n                              uint type) {\n  int4 coords;\n\n  coords.x = get_global_id(0);\n\n  coords += origin;\n\n  // Check components\n  switch (type) {\n    case 0:\n      write_imagef(dst1d, coords.x, *(float4*)&fill_data);\n      break;\n    case 1:\n      write_imagei(dst1d, coords.x, *(int4*)&fill_data);\n      break;\n    case 2:\n      write_imageui(dst1d, coords.x, fill_data);\n      break;\n    }\n}\n"
  },
  {
    "path": "runtime/hsa-runtime/image/device_info.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <assert.h>\n#include <string>\n\n#include \"core/inc/hsa_internal.h\"\n#include \"device_info.h\"\n#include \"addrlib/src/amdgpu_asic_addr.h\"\n\nnamespace rocr {\nnamespace image {\n\nuint32_t MajorVerFromDevID(uint32_t dev_id) { return dev_id >> 8; }\n\nuint32_t MinorVerFromDevID(uint32_t dev_id) { return (dev_id >> 4) & 0xF; }\n\nuint32_t StepFromDevID(uint32_t dev_id) { return dev_id & 0xF; }\n\nhsa_status_t GetGPUAsicID(hsa_agent_t agent, uint32_t *chip_id) {\n  char asic_name[64];\n  assert(chip_id != nullptr);\n\n  hsa_status_t status = HSA::hsa_agent_get_info(\n      agent, static_cast<hsa_agent_info_t>(HSA_AGENT_INFO_NAME), &asic_name);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n  std::string a_str(asic_name);\n\n  assert(a_str.compare(0, 3, \"gfx\", 3) == 0);\n\n  a_str.erase(0,3);\n\n  // Load chip_id accounting for stepping and minor in hex and major in dec.\n  *chip_id = std::stoi(a_str.substr(a_str.length() - 2), nullptr, 16);\n  *chip_id += (std::stoi(a_str.substr(0, a_str.length() - 2)) << 8);\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/device_info.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_INC_DEVICE_INFO_H_\n#define HSA_RUNTIME_CORE_INC_DEVICE_INFO_H_\n\n#include \"stdint.h\"\n#include \"inc/hsa.h\"\n\nnamespace rocr {\nnamespace image {\n\nuint32_t MajorVerFromDevID(uint32_t dev_id);\nuint32_t MinorVerFromDevID(uint32_t dev_id);\nuint32_t StepFromDevID(uint32_t dev_id);\nhsa_status_t GetGPUAsicID(hsa_agent_t agent, uint32_t *chip_id);\n\n}  // namespace image\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_CORE_INC_DEVICE_INFO_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/image/hsa_ext_image.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"image_runtime.h\"\n#include \"image/inc/hsa_ext_image_impl.h\"\n#include \"core/inc/exceptions.h\"\n\nnamespace rocr {\n\nnamespace AMD {\nhsa_status_t handleException();\n\ntemplate <class T> static __forceinline T handleExceptionT() {\n  handleException();\n  abort();\n  return T();\n}\n}   // namespace amd\n\n#define TRY try {\n#define CATCH } catch(...) { return AMD::handleException(); }\n#define CATCHRET(RETURN_TYPE) } catch(...) { return AMD::handleExceptionT<RETURN_TYPE>(); }\n\nnamespace image {\n\n//---------------------------------------------------------------------------//\n//  Utilty routines\n//---------------------------------------------------------------------------//\nstatic void enforceDefaultPitch(hsa_agent_t agent,\n                                const hsa_ext_image_descriptor_t* image_descriptor,\n                                size_t& image_data_row_pitch, size_t& image_data_slice_pitch) {\n  // Set default pitch\n  if (image_data_row_pitch == 0) {\n    auto manager = ImageRuntime::instance()->image_manager(agent);\n    assert((manager != nullptr) && \"Image manager should already exit.\");\n    image_data_row_pitch = image_descriptor->width *\n      manager->GetImageProperty(agent, image_descriptor->format, image_descriptor->geometry)\n      .element_size;\n  }\n\n  // Set default slice pitch\n  if ((image_data_slice_pitch == 0) &&\n    ((image_descriptor->depth != 0) || (image_descriptor->array_size != 0))) {\n      switch (image_descriptor->geometry) {\n      case HSA_EXT_IMAGE_GEOMETRY_3D:\n      case HSA_EXT_IMAGE_GEOMETRY_2DA:\n      case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH: {\n        image_data_slice_pitch = image_data_row_pitch * image_descriptor->height;\n        break;\n                                            }\n      case HSA_EXT_IMAGE_GEOMETRY_1DA: {\n        image_data_slice_pitch = image_data_row_pitch;\n        break;\n                                       }\n      default:\n        fprintf(stderr, \"Depth set on single layer image geometry.\\n\");\n        //assert(false && \"Depth set on single layer image geometry.\");\n      }\n  }\n}\n\n//---------------------------------------------------------------------------//\n//  APIs that implement Image functionality\n//---------------------------------------------------------------------------//\n\nhsa_status_t hsa_amd_image_get_info_max_dim(hsa_agent_t agent, hsa_agent_info_t attribute,\n                                            void* value) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (value == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->GetImageInfoMaxDimension(agent, attribute, value);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_get_capability(hsa_agent_t agent,\n                                          hsa_ext_image_geometry_t image_geometry,\n                                          const hsa_ext_image_format_t* image_format,\n                                          uint32_t* capability_mask) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if ((image_format == NULL) || (capability_mask == NULL) ||\n      (image_geometry < HSA_EXT_IMAGE_GEOMETRY_1D) ||\n      (image_geometry > HSA_EXT_IMAGE_GEOMETRY_2DADEPTH)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->GetImageCapability(agent, *image_format, image_geometry,\n                                                      *capability_mask);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_data_get_info(hsa_agent_t agent,\n                                         const hsa_ext_image_descriptor_t* image_descriptor,\n                                         hsa_access_permission_t access_permission,\n                                         hsa_ext_image_data_info_t* image_data_info) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if ((image_descriptor == NULL) || (image_data_info == NULL) ||\n      (access_permission < HSA_ACCESS_PERMISSION_RO) ||\n      (access_permission > HSA_ACCESS_PERMISSION_RW)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->GetImageSizeAndAlignment(\n      agent, *image_descriptor, HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0, 0, *image_data_info);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_create(hsa_agent_t agent,\n                                  const hsa_ext_image_descriptor_t* image_descriptor,\n                                  const void* image_data, hsa_access_permission_t access_permission,\n                                  hsa_ext_image_t* image) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (image_descriptor == NULL || image_data == NULL || image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CreateImageHandle(\n      agent, *image_descriptor, image_data, access_permission, HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE, 0,\n      0, *image);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_destroy(hsa_agent_t agent, hsa_ext_image_t image) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  return ImageRuntime::instance()->DestroyImageHandle(image);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_copy(hsa_agent_t agent, hsa_ext_image_t src_image,\n                                const hsa_dim3_t* src_offset, hsa_ext_image_t dst_image,\n                                const hsa_dim3_t* dst_offset, const hsa_dim3_t* range) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (src_image.handle == 0 || dst_image.handle == 0 || src_offset == NULL ||\n      dst_offset == NULL || range == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CopyImage(src_image, dst_image, *src_offset, *dst_offset,\n                                             *range);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_import(hsa_agent_t agent, const void* src_memory, size_t src_row_pitch,\n                                  size_t src_slice_pitch, hsa_ext_image_t dst_image,\n                                  const hsa_ext_image_region_t* image_region) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (src_memory == NULL || dst_image.handle == 0 || image_region == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CopyBufferToImage(src_memory, src_row_pitch, src_slice_pitch,\n                                                     dst_image, *image_region);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_export(hsa_agent_t agent, hsa_ext_image_t src_image, void* dst_memory,\n                                  size_t dst_row_pitch, size_t dst_slice_pitch,\n                                  const hsa_ext_image_region_t* image_region) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (dst_memory == NULL || src_image.handle == 0 || image_region == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CopyImageToBuffer(src_image, dst_memory, dst_row_pitch,\n                                                     dst_slice_pitch, *image_region);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_clear(hsa_agent_t agent, hsa_ext_image_t image, const void* data,\n                                 const hsa_ext_image_region_t* image_region) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (image.handle == 0 || image_region == NULL || data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->FillImage(image, data, *image_region);\n  CATCH;\n};\n\nhsa_status_t hsa_ext_sampler_create(hsa_agent_t agent,\n                                    const hsa_ext_sampler_descriptor_t* sampler_descriptor,\n                                    hsa_ext_sampler_t* sampler) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (sampler_descriptor == NULL || sampler == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  hsa_ext_sampler_descriptor_v2_t sampler_descriptor_v2 = {\n      sampler_descriptor->coordinate_mode,\n      sampler_descriptor->filter_mode,\n      {sampler_descriptor->address_mode,\n          sampler_descriptor->address_mode, sampler_descriptor->address_mode}\n  };\n  return ImageRuntime::instance()->CreateSamplerHandle(agent, sampler_descriptor_v2, *sampler);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_sampler_create_v2(hsa_agent_t agent,\n                                    const hsa_ext_sampler_descriptor_v2_t* sampler_descriptor,\n                                    hsa_ext_sampler_t* sampler) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (sampler_descriptor == NULL || sampler == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CreateSamplerHandle(agent, *sampler_descriptor, *sampler);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_sampler_destroy(hsa_agent_t agent, hsa_ext_sampler_t sampler) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  return ImageRuntime::instance()->DestroySamplerHandle(sampler);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_get_capability_with_layout(hsa_agent_t agent,\n                                                      hsa_ext_image_geometry_t image_geometry,\n                                                      const hsa_ext_image_format_t* image_format,\n                                                      hsa_ext_image_data_layout_t image_data_layout,\n                                                      uint32_t* capability_mask) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if ((image_format == NULL) || (capability_mask == NULL) ||\n      (image_geometry < HSA_EXT_IMAGE_GEOMETRY_1D) ||\n      (image_geometry > HSA_EXT_IMAGE_GEOMETRY_2DADEPTH) ||\n      (image_data_layout != HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->GetImageCapability(agent, *image_format, image_geometry,\n                                                      *capability_mask);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_data_get_info_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    hsa_access_permission_t access_permission, hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch, size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t* image_data_info) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if ((image_descriptor == NULL) || (image_data_info == NULL) ||\n      (access_permission < HSA_ACCESS_PERMISSION_RO) ||\n      (access_permission > HSA_ACCESS_PERMISSION_RW) ||\n      (image_data_layout != HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  enforceDefaultPitch(agent, image_descriptor, image_data_row_pitch, image_data_slice_pitch);\n\n  return ImageRuntime::instance()->GetImageSizeAndAlignment(\n      agent, *image_descriptor, image_data_layout, image_data_row_pitch, image_data_slice_pitch,\n      *image_data_info);\n  CATCH;\n}\n\nhsa_status_t hsa_ext_image_create_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor, const void* image_data,\n    hsa_access_permission_t access_permission, hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch, size_t image_data_slice_pitch, hsa_ext_image_t* image) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (image_descriptor == NULL || image_data == NULL || image == NULL ||\n      image_data_layout != HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  enforceDefaultPitch(agent, image_descriptor, image_data_row_pitch, image_data_slice_pitch);\n\n  return ImageRuntime::instance()->CreateImageHandle(\n      agent, *image_descriptor, image_data, access_permission, image_data_layout,\n      image_data_row_pitch, image_data_slice_pitch, *image);\n  CATCH;\n}\n\nhsa_status_t hsa_amd_image_create(hsa_agent_t agent,\n                                  const hsa_ext_image_descriptor_t* image_descriptor,\n                                  const hsa_amd_image_descriptor_t* image_layout,\n                                  const void* image_data, hsa_access_permission_t access_permission,\n                                  hsa_ext_image_t* image) {\n  TRY;\n  if (agent.handle == 0) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  if (image_descriptor == NULL || image_data == NULL || image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  return ImageRuntime::instance()->CreateImageHandleWithLayout(\n      agent, *image_descriptor, image_layout, image_data, access_permission, *image);\n  CATCH;\n}\n\nvoid LoadImage(core::ImageExtTableInternal* image_api,\n               decltype(::hsa_amd_image_create)** interface_api) {\n  image_api->hsa_ext_image_get_capability_fn = hsa_ext_image_get_capability;\n\n  image_api->hsa_ext_image_data_get_info_fn = hsa_ext_image_data_get_info;\n\n  image_api->hsa_ext_image_create_fn = hsa_ext_image_create;\n\n  image_api->hsa_ext_image_import_fn = hsa_ext_image_import;\n\n  image_api->hsa_ext_image_export_fn = hsa_ext_image_export;\n\n  image_api->hsa_ext_image_copy_fn = hsa_ext_image_copy;\n\n  image_api->hsa_ext_image_clear_fn = hsa_ext_image_clear;\n\n  image_api->hsa_ext_image_destroy_fn = hsa_ext_image_destroy;\n\n  image_api->hsa_ext_sampler_create_fn = hsa_ext_sampler_create;\n\n  image_api->hsa_ext_sampler_destroy_fn = hsa_ext_sampler_destroy;\n\n  image_api->hsa_ext_image_get_capability_with_layout_fn = hsa_ext_image_get_capability_with_layout;\n\n  image_api->hsa_ext_image_data_get_info_with_layout_fn = hsa_ext_image_data_get_info_with_layout;\n\n  image_api->hsa_ext_image_create_with_layout_fn = hsa_ext_image_create_with_layout;\n\n  image_api->hsa_amd_image_get_info_max_dim_fn = hsa_amd_image_get_info_max_dim;\n\n  image_api->hsa_ext_sampler_create_v2_fn = hsa_ext_sampler_create_v2;\n\n  *interface_api = hsa_amd_image_create;\n}\n\nvoid ReleaseImageRsrcs() { ImageRuntime::DestroySingleton(); }\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_lut.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_EXT_IMAGE_IMAGE_LUT_H\n#define AMD_HSA_EXT_IMAGE_IMAGE_LUT_H\n\n#include <stdint.h>\n\n#include \"inc/hsa_ext_image.h\"\n#include \"resource.h\"\n#include \"util.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageLut {\n public:\n  ImageLut() {}\n\n  virtual ~ImageLut() {}\n\n  virtual uint32_t MapGeometry(hsa_ext_image_geometry_t geometry) const = 0;\n\n  virtual ImageProperty MapFormat(const hsa_ext_image_format_t& format,\n                                  hsa_ext_image_geometry_t geometry) const = 0;\n\n  virtual Swizzle MapSwizzle(hsa_ext_image_channel_order32_t order) const = 0;\n\n  virtual uint32_t GetMaxWidth(hsa_ext_image_geometry_t geometry) const = 0;\n\n  virtual uint32_t GetMaxHeight(hsa_ext_image_geometry_t geometry) const = 0;\n\n  virtual uint32_t GetMaxDepth(hsa_ext_image_geometry_t geometry) const = 0;\n\n  virtual uint32_t GetMaxArraySize(hsa_ext_image_geometry_t geometry) const = 0;\n\n private:\n   DISALLOW_COPY_AND_ASSIGN(ImageLut);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // AMD_HSA_EXT_IMAGE_IMAGE_LUT_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_lut_gfx11.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"image_lut_gfx11.h\"\n#include \"resource_gfx11.h\"\n\nnamespace rocr {\nnamespace image {\n\n  /* \n   * The type table has changed for gfx11, so we need a separate instance for\n   * the Property LUT\n   */\n  const ImageProperty ImageLutGfx11::kPropLutGfx11_[ORDER_COUNT][TYPE_COUNT] = {\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_A\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 1, FMT_8, TYPE_SINT},\n     {RW, 2, FMT_16, TYPE_SINT},\n     {RW, 4, FMT_32, TYPE_SINT},\n     {RW, 1, FMT_8, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_UINT},\n     {RW, 4, FMT_32, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_R\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 1, FMT_8, TYPE_SINT},\n     {RW, 2, FMT_16, TYPE_SINT},\n     {RW, 4, FMT_32, TYPE_SINT},\n     {RW, 1, FMT_8, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_UINT},\n     {RW, 4, FMT_32, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RG\n     {RW, 2, FMT_8_8, TYPE_SNORM},\n     {RW, 4, FMT_16_16, TYPE_SNORM},\n     {RW, 2, FMT_8_8, TYPE_UNORM},\n     {RW, 4, FMT_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_8_8, TYPE_SINT},\n     {RW, 4, FMT_16_16, TYPE_SINT},\n     {RW, 8, FMT_32_32, TYPE_SINT},\n     {RW, 2, FMT_8_8, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_UINT},\n     {RW, 8, FMT_32_32, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_FLOAT},\n     {RW, 8, FMT_32_32, TYPE_FLOAT}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RA\n     {RW, 2, FMT_8_8, TYPE_SNORM},\n     {RW, 4, FMT_16_16, TYPE_SNORM},\n     {RW, 2, FMT_8_8, TYPE_UNORM},\n     {RW, 4, FMT_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_8_8, TYPE_SINT},\n     {RW, 4, FMT_16_16, TYPE_SINT},\n     {RW, 8, FMT_32_32, TYPE_SINT},\n     {RW, 2, FMT_8_8, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_UINT},\n     {RW, 8, FMT_32_32, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_FLOAT},\n     {RW, 8, FMT_32_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_RGB\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_1_5_5_5, TYPE_UNORM},\n     {RW, 2, FMT_5_6_5, TYPE_UNORM},\n     {RW, 4, FMT_2_10_10_10, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {RW, 8, FMT_16_16_16_16, TYPE_SNORM},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {RW, 8, FMT_16_16_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_SINT},\n     {RW, 16, FMT_32_32_32_32, TYPE_SINT},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_UINT},\n     {RW, 16, FMT_32_32_32_32, TYPE_UINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_FLOAT},\n     {RW, 16, FMT_32_32_32_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RO, 4, FMT_8_8_8_8, TYPE_SRGB},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {ROWO, 2, FMT_16, TYPE_UNORM},\n     // TODO: 24 bit\n     {0, 3, FMT_32, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {ROWO, 4, FMT_32, TYPE_FLOAT}},\n    {}  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL\n};\n\nImageProperty ImageLutGfx11::MapFormat(const hsa_ext_image_format_t& format,\n                                    hsa_ext_image_geometry_t geometry) const {\n  switch (geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n      return kPropLutGfx11_[format.channel_order][format.channel_type];\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n      switch (format.channel_order) {\n        // Hardware does not support buffer access to srgb image.\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA:\n          break;\n        default:\n          switch (format.channel_type) {\n            // Hardware does not support buffer access to 555/565 packed image.\n            case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555:\n            case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565:\n              break;\n            default:\n              return kPropLutGfx11_[format.channel_order][format.channel_type];\n          }\n      }\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      switch (format.channel_order) {\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL:\n          return kPropLutGfx11_[format.channel_order][format.channel_type];\n        default:\n          break;\n      }\n      break;\n    default:\n      assert(false && \"Should not reach here\");\n      break;\n  }\n\n  ImageProperty prop = {0};\n  return prop;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_lut_gfx11.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2022, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_EXT_IMAGE_IMAGE_LUT_GFX11_H\n#define AMD_HSA_EXT_IMAGE_IMAGE_LUT_GFX11_H\n\n#include \"image_lut.h\"\n#include \"image_lut_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageLutGfx11 : public ImageLutKv {\n public:\n  ImageLutGfx11() { }\n\n  ImageProperty MapFormat(const hsa_ext_image_format_t& format,\n                                  hsa_ext_image_geometry_t geometry) const;\n\n private:\n  // Lookup table of channel format property. Based on HSA Programmer's\n  // Reference Manual 1.0P Table 9-4 Channel Order, Channel type and Image\n  // Geometry Combinations.\n  static const ImageProperty kPropLutGfx11_[ORDER_COUNT][TYPE_COUNT];\n\n  DISALLOW_COPY_AND_ASSIGN(ImageLutGfx11);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // AMD_HSA_EXT_IMAGE_IMAGE_LUT_GFX11_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_lut_kv.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"image_lut_kv.h\"\n#include \"resource_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nconst uint32_t ImageLutKv::kGeometryLut_[GEOMETRY_COUNT] = {\n    SQ_RSRC_IMG_1D,        // HSA_EXT_IMAGE_GEOMETRY_1D\n    SQ_RSRC_IMG_2D,        // HSA_EXT_IMAGE_GEOMETRY_2D\n    SQ_RSRC_IMG_3D,        // HSA_EXT_IMAGE_GEOMETRY_3D\n    SQ_RSRC_IMG_1D_ARRAY,  // HSA_EXT_IMAGE_GEOMETRY_1DA\n    SQ_RSRC_IMG_2D_ARRAY,  // HSA_EXT_IMAGE_GEOMETRY_2DA\n    0,                     // HSA_EXT_IMAGE_GEOMETRY_1DB\n    SQ_RSRC_IMG_2D,        // HSA_EXT_IMAGE_GEOMETRY_2DDEPTH\n    SQ_RSRC_IMG_2D_ARRAY   // HSA_EXT_IMAGE_GEOMETRY_2DADEPTH\n};\n\nconst ImageProperty ImageLutKv::kPropLut_[ORDER_COUNT][TYPE_COUNT] = {\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_A\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 1, FMT_8, TYPE_SINT},\n     {RW, 2, FMT_16, TYPE_SINT},\n     {RW, 4, FMT_32, TYPE_SINT},\n     {RW, 1, FMT_8, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_UINT},\n     {RW, 4, FMT_32, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_R\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 1, FMT_8, TYPE_SINT},\n     {RW, 2, FMT_16, TYPE_SINT},\n     {RW, 4, FMT_32, TYPE_SINT},\n     {RW, 1, FMT_8, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_UINT},\n     {RW, 4, FMT_32, TYPE_UINT},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RG\n     {RW, 2, FMT_8_8, TYPE_SNORM},\n     {RW, 4, FMT_16_16, TYPE_SNORM},\n     {RW, 2, FMT_8_8, TYPE_UNORM},\n     {RW, 4, FMT_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_8_8, TYPE_SINT},\n     {RW, 4, FMT_16_16, TYPE_SINT},\n     {RW, 8, FMT_32_32, TYPE_SINT},\n     {RW, 2, FMT_8_8, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_UINT},\n     {RW, 8, FMT_32_32, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_FLOAT},\n     {RW, 8, FMT_32_32, TYPE_FLOAT}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RA\n     {RW, 2, FMT_8_8, TYPE_SNORM},\n     {RW, 4, FMT_16_16, TYPE_SNORM},\n     {RW, 2, FMT_8_8, TYPE_UNORM},\n     {RW, 4, FMT_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_8_8, TYPE_SINT},\n     {RW, 4, FMT_16_16, TYPE_SINT},\n     {RW, 8, FMT_32_32, TYPE_SINT},\n     {RW, 2, FMT_8_8, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_UINT},\n     {RW, 8, FMT_32_32, TYPE_UINT},\n     {RW, 4, FMT_16_16, TYPE_FLOAT},\n     {RW, 8, FMT_32_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_RGB\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_1_5_5_5, TYPE_UNORM},\n     {RW, 2, FMT_5_6_5, TYPE_UNORM},\n     {RW, 4, FMT_2_10_10_10, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {RW, 8, FMT_16_16_16_16, TYPE_SNORM},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {RW, 8, FMT_16_16_16_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_SINT},\n     {RW, 16, FMT_32_32_32_32, TYPE_SINT},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_UINT},\n     {RW, 16, FMT_32_32_32_32, TYPE_UINT},\n     {RW, 8, FMT_16_16_16_16, TYPE_FLOAT},\n     {RW, 16, FMT_32_32_32_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB\n     {RW, 4, FMT_8_8_8_8, TYPE_SNORM},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_SINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 4, FMT_8_8_8_8, TYPE_UINT},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RO, 4, FMT_8_8_8_8, TYPE_SRGB},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0}},\n    {},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA\n    {     // HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE\n     {RW, 1, FMT_8, TYPE_SNORM},\n     {RW, 2, FMT_16, TYPE_SNORM},\n     {RW, 1, FMT_8, TYPE_UNORM},\n     {RW, 2, FMT_16, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {RW, 2, FMT_16, TYPE_FLOAT},\n     {RW, 4, FMT_32, TYPE_FLOAT}},\n    {// HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {ROWO, 2, FMT_16, TYPE_UNORM},\n     // TODO: 24 bit\n     {0, 3, FMT_32, TYPE_UNORM},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {0, 0, 0, 0},\n     {ROWO, 4, FMT_32, TYPE_FLOAT}},\n    {}  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL\n};\n\nconst Swizzle ImageLutKv::kSwizzleLut_[ORDER_COUNT] = {\n    {SEL_0, SEL_0, SEL_0, SEL_X},  // HSA_EXT_IMAGE_CHANNEL_ORDER_A\n    {SEL_X, SEL_0, SEL_0, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_R\n    {SEL_X, SEL_0, SEL_0, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RX\n    {SEL_X, SEL_Y, SEL_0, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RG\n    {SEL_X, SEL_Y, SEL_0, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGX\n    {SEL_X, SEL_0, SEL_0, SEL_Y},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RA\n    {SEL_Z, SEL_Y, SEL_X, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGB\n    {SEL_Z, SEL_Y, SEL_X, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX\n    {SEL_X, SEL_Y, SEL_Z, SEL_W},  // HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA\n    {SEL_Z, SEL_Y, SEL_X, SEL_W},  // HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA\n    {SEL_Y, SEL_Z, SEL_W, SEL_X},  // HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB\n    {SEL_Y, SEL_X, SEL_W, SEL_Z},  // HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR\n    {SEL_X, SEL_Y, SEL_Z, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB\n    {SEL_X, SEL_Y, SEL_Z, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX\n    {SEL_X, SEL_Y, SEL_Z, SEL_W},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA\n    {SEL_Z, SEL_Y, SEL_X, SEL_W},  // HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA\n    {SEL_X, SEL_X, SEL_X, SEL_X},  // HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY\n    {SEL_X, SEL_X, SEL_X, SEL_1},  // HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE\n    {SEL_X, SEL_0, SEL_0, SEL_0},  // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH\n    {SEL_Y, SEL_0, SEL_0, SEL_0}   // HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL\n};\n\nconst uint32_t ImageLutKv::kMaxDimensionLut_[GEOMETRY_COUNT][4] = {\n    {16384, 1, 1, 1},         // HSA_EXT_IMAGE_GEOMETRY_1D\n    {16384, 16384, 1, 1},     // HSA_EXT_IMAGE_GEOMETRY_2D\n    {16384, 16384, 8192, 1},  // HSA_EXT_IMAGE_GEOMETRY_3D\n    {16384, 1, 1, 8192},      // HSA_EXT_IMAGE_GEOMETRY_1DA\n    {16384, 16384, 1, 8192},  // HSA_EXT_IMAGE_GEOMETRY_2DA\n    {4294967295, 1, 1, 1},    // HSA_EXT_IMAGE_GEOMETRY_1DB\n    {16384, 16384, 1, 1},     // HSA_EXT_IMAGE_GEOMETRY_2DDEPTH\n    {16384, 16384, 1, 8192}   // HSA_EXT_IMAGE_GEOMETRY_2DADEPTH\n};\n\nuint32_t ImageLutKv::MapGeometry(hsa_ext_image_geometry_t geometry) const {\n  switch (geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      return kGeometryLut_[geometry];\n    default:\n      assert(false && \"Should not reach here\");\n      return static_cast<uint32_t>(-1);\n  };\n}\n\nImageProperty ImageLutKv::MapFormat(const hsa_ext_image_format_t& format,\n                                    hsa_ext_image_geometry_t geometry) const {\n  switch (geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n      return kPropLut_[format.channel_order][format.channel_type];\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n      switch (format.channel_order) {\n        // Hardware does not support buffer access to srgb image.\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA:\n          break;\n        default:\n          switch (format.channel_type) {\n            // Hardware does not support buffer access to 555/565 packed image.\n            case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555:\n            case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565:\n              break;\n            default:\n              return kPropLut_[format.channel_order][format.channel_type];\n          }\n      }\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      switch (format.channel_order) {\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH:\n        case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL:\n          return kPropLut_[format.channel_order][format.channel_type];\n        default:\n          break;\n      }\n      break;\n    default:\n      assert(false && \"Should not reach here\");\n      break;\n  }\n\n  ImageProperty prop = {0};\n  return prop;\n}\n\nSwizzle ImageLutKv::MapSwizzle(hsa_ext_image_channel_order32_t order) const {\n  const Swizzle invalid_swizzle = {0xff, 0xff, 0xff, 0xff};\n  switch (order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_A:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_R:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RG:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL:\n      return kSwizzleLut_[order];\n    default:\n      assert(false && \"Should not reach here\");\n      return invalid_swizzle;\n  };\n}\n\nuint32_t ImageLutKv::GetMaxWidth(hsa_ext_image_geometry_t geometry) const {\n  return kMaxDimensionLut_[geometry][0];\n}\n\nuint32_t ImageLutKv::GetMaxHeight(hsa_ext_image_geometry_t geometry) const {\n  return kMaxDimensionLut_[geometry][1];\n}\n\nuint32_t ImageLutKv::GetMaxDepth(hsa_ext_image_geometry_t geometry) const {\n  return kMaxDimensionLut_[geometry][2];\n}\n\nuint32_t ImageLutKv::GetMaxArraySize(hsa_ext_image_geometry_t geometry) const {\n  return kMaxDimensionLut_[geometry][3];\n}\n\nuint32_t ImageLutKv::GetPixelSize(uint8_t data_format, uint8_t data_type) const {\n  //Currently only supports formats that ROCr can create.\n  switch(data_format) {\n    case FMT_1_5_5_5: return 2;\n    case FMT_16: return 2;\n    case FMT_16_16: return 4;\n    case FMT_16_16_16_16: return 8;\n    case FMT_2_10_10_10: return 4;\n    //SPK: Where is unorm returning 3?  Was this a Hawaii specific thing?\n    case FMT_32: return (data_type==TYPE_UNORM) ? 3 : 4;\n    case FMT_32_32: return 8;\n    case FMT_32_32_32_32: return 16;\n    case FMT_5_6_5: return 2;\n    case FMT_8: return 1;\n    case FMT_8_8: return 2;\n    case FMT_8_8_8_8: return 4;\n    default: return 0;\n  }\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_lut_kv.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_EXT_IMAGE_IMAGE_LUT_KV_H\n#define AMD_HSA_EXT_IMAGE_IMAGE_LUT_KV_H\n\n#include \"image_lut.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageLutKv : public ImageLut {\n public:\n  ImageLutKv() {}\n\n  virtual ~ImageLutKv() {}\n\n  virtual uint32_t MapGeometry(hsa_ext_image_geometry_t geometry) const;\n\n  virtual ImageProperty MapFormat(const hsa_ext_image_format_t& format,\n                                  hsa_ext_image_geometry_t geometry) const;\n\n  virtual Swizzle MapSwizzle(hsa_ext_image_channel_order32_t order) const;\n\n  virtual uint32_t GetMaxWidth(hsa_ext_image_geometry_t geometry) const;\n\n  virtual uint32_t GetMaxHeight(hsa_ext_image_geometry_t geometry) const;\n\n  virtual uint32_t GetMaxDepth(hsa_ext_image_geometry_t geometry) const;\n\n  virtual uint32_t GetMaxArraySize(hsa_ext_image_geometry_t geometry) const;\n\n  uint32_t GetPixelSize(uint8_t data_format, uint8_t data_type) const;\n\n private:\n  // Lookup table of image geometry to device geometry enum.\n  static const uint32_t kGeometryLut_[GEOMETRY_COUNT];\n\n  // Lookup table of channel format property. Based on HSA Programmer's\n  // Reference Manual 1.0P Table 9-4 Channel Order, Channel type and Image\n  // Geometry Combinations.\n  static const ImageProperty kPropLut_[ORDER_COUNT][TYPE_COUNT];\n\n  // Lookup table of channel order swizzle.\n  static const Swizzle kSwizzleLut_[ORDER_COUNT];\n\n  // Lookup table of image geometry to max dimension.\n  // Each record contains four values: widht, height, depth, array_size.\n  static const uint32_t kMaxDimensionLut_[GEOMETRY_COUNT][4];\n\n  DISALLOW_COPY_AND_ASSIGN(ImageLutKv);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // AMD_HSA_EXT_IMAGE_IMAGE_LUT_KV_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"inc/hsa_ext_amd.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"image_manager.h\"\n#include \"image_runtime.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n#include <cmath>\n\n#if (defined(WIN32) || defined(_WIN32))\n#define NOMINMAX\n__inline long int lrintf(float f) { return _mm_cvtss_si32(_mm_load_ss(&f)); }\n#endif\n\nnamespace rocr {\nnamespace image {\n\nImage* Image::Create(hsa_agent_t agent) {\n  hsa_amd_memory_pool_t pool = ImageRuntime::instance()->kernarg_pool();\n\n  Image* image = NULL;\n\n  hsa_status_t status =\n      AMD::hsa_amd_memory_pool_allocate(pool, sizeof(Image), 0, reinterpret_cast<void**>(&image));\n  assert(status == HSA_STATUS_SUCCESS);\n\n  if (status != HSA_STATUS_SUCCESS) return NULL;\n\n  new (image) Image();\n\n  status = AMD::hsa_amd_agents_allow_access(1, &agent, NULL, image);\n\n  if (status != HSA_STATUS_SUCCESS) {\n    Image::Destroy(image);\n    return NULL;\n  }\n\n  return image;\n}\n\nvoid Image::Destroy(const Image* image) {\n  assert(image != NULL);\n  image->~Image();\n\n  hsa_status_t status = AMD::hsa_amd_memory_pool_free(const_cast<Image*>(image));\n\n  assert(status == HSA_STATUS_SUCCESS);\n}\n\nSampler* Sampler::Create(hsa_agent_t agent) {\n  hsa_amd_memory_pool_t pool = ImageRuntime::instance()->kernarg_pool();\n\n  Sampler* sampler = NULL;\n\n  hsa_status_t status = AMD::hsa_amd_memory_pool_allocate(pool, sizeof(Sampler), 0,\n                                                          reinterpret_cast<void**>(&sampler));\n\n  if (status != HSA_STATUS_SUCCESS) return NULL;\n\n  new (sampler) Sampler();\n\n  status = AMD::hsa_amd_agents_allow_access(1, &agent, NULL, sampler);\n\n  if (status != HSA_STATUS_SUCCESS) {\n    Sampler::Destroy(sampler);\n    return NULL;\n  }\n\n  return sampler;\n}\n\nvoid Sampler::Destroy(const Sampler* sampler) {\n  assert(sampler != NULL);\n  sampler->~Sampler();\n\n  hsa_status_t status = AMD::hsa_amd_memory_pool_free(const_cast<Sampler*>(sampler));\n\n  assert(status == HSA_STATUS_SUCCESS);\n}\n\nImageManager::ImageManager() {}\n\nImageManager::~ImageManager() {}\n\nhsa_status_t ImageManager::CopyBufferToImage(\n    const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n    const Image& dst_image, const hsa_ext_image_region_t& image_region) {\n  Image* src_image = Image::Create(dst_image.component);\n\n  src_image->component = dst_image.component;\n  src_image->desc = dst_image.desc;\n  src_image->data = const_cast<void*>(src_memory);\n  src_image->permission = HSA_ACCESS_PERMISSION_RO;\n  src_image->row_pitch = src_row_pitch;\n  src_image->slice_pitch = src_slice_pitch;\n\n  const hsa_dim3_t dst_origin = image_region.offset;\n  const hsa_dim3_t src_origin = {0};\n  const hsa_dim3_t copy_size = image_region.range;\n\n  hsa_status_t status = ImageManager::CopyImage(\n      dst_image, *src_image, dst_origin, src_origin, copy_size);\n\n  Image::Destroy(src_image);\n\n  return status;\n}\n\nhsa_status_t ImageManager::CopyImageToBuffer(\n    const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n    size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region) {\n  // Treat buffer as image since we don't tile our image anyway.\n  Image* dst_image = Image::Create(src_image.component);\n\n  dst_image->component = src_image.component;\n  dst_image->desc = src_image.desc;  // the width, height, depth is ignored.\n  dst_image->data = dst_memory;\n  dst_image->permission = HSA_ACCESS_PERMISSION_WO;\n  dst_image->row_pitch = dst_row_pitch;\n  dst_image->slice_pitch = dst_slice_pitch;\n\n  const hsa_dim3_t dst_origin = {0};\n  const hsa_dim3_t src_origin = image_region.offset;\n  const hsa_dim3_t copy_size = image_region.range;\n\n  hsa_status_t status = ImageManager::CopyImage(\n      *dst_image, src_image, dst_origin, src_origin, copy_size);\n\n  Image::Destroy(dst_image);\n\n  return status;\n}\n\nhsa_status_t ImageManager::CopyImage(const Image& dst_image,\n                                     const Image& src_image,\n                                     const hsa_dim3_t& dst_origin,\n                                     const hsa_dim3_t& src_origin,\n                                     const hsa_dim3_t size) {\n  ImageProperty dst_image_prop = GetImageProperty(\n      dst_image.component, dst_image.desc.format, dst_image.desc.geometry);\n  assert(dst_image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n\n  const size_t dst_element_size = dst_image_prop.element_size;\n  assert(dst_element_size != 0);\n\n  ImageProperty src_image_prop = GetImageProperty(\n      src_image.component, src_image.desc.format, src_image.desc.geometry);\n  assert(src_image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n\n  const size_t src_element_size = src_image_prop.element_size;\n  assert(src_element_size != 0);\n\n  const hsa_ext_image_format_t src_format = src_image.desc.format;\n  const hsa_ext_image_channel_order32_t src_order = src_format.channel_order;\n  const hsa_ext_image_channel_type32_t src_type = src_format.channel_type;\n\n  const hsa_ext_image_format_t dst_format = dst_image.desc.format;\n  const hsa_ext_image_channel_order32_t dst_order = dst_format.channel_order;\n  const hsa_ext_image_channel_type32_t dst_type = dst_format.channel_type;\n\n  bool linear_to_standard_rgb = false;\n  bool standard_to_linear_rgb = false;\n\n  if ((src_order != dst_order) || (src_type != dst_type)) {\n    // Source and destination format must be the same, except for\n    // SRGBA <--> RGBA images.\n    if ((src_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8) &&\n        (dst_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8)) {\n      if ((src_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA) &&\n          (dst_order == HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA)) {\n        standard_to_linear_rgb = true;\n      } else if ((src_order == HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA) &&\n                 (dst_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA)) {\n        linear_to_standard_rgb = true;\n      } else {\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n    } else {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n  }\n\n  // Source and destination format should be the same so the element size\n  // should be same too.\n  const size_t element_size = src_element_size;\n\n  // row_pitch and slice_pitch in bytes.\n  const size_t dst_row_pitch =\n      std::max(dst_image.row_pitch, size.x * element_size);\n  const size_t dst_slice_pitch = std::max(\n      dst_image.slice_pitch,\n      dst_row_pitch *\n          (dst_image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ? 1 : size.y));\n\n  const size_t src_row_pitch =\n      std::max(src_image.row_pitch, size.x * element_size);\n  const size_t src_slice_pitch = std::max(\n      src_image.slice_pitch,\n      src_row_pitch *\n          (src_image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ? 1 : size.y));\n\n  size_t src_offset = src_origin.x;\n  size_t dst_offset = dst_origin.x;\n  size_t copy_size = size.x;\n\n  // Calculate source the offset in bytes.\n  src_offset *= element_size;\n  src_offset += src_row_pitch * src_origin.y;\n  src_offset += src_slice_pitch * src_origin.z;\n\n  // Calculate destination the offset in bytes.\n  dst_offset *= element_size;\n  dst_offset += dst_row_pitch * dst_origin.y;\n  dst_offset += dst_slice_pitch * dst_origin.z;\n\n  copy_size *= element_size;\n\n  // Get destination and source memory.\n  unsigned char* dst = static_cast<unsigned char*>(dst_image.data);\n  const unsigned char* src = static_cast<const unsigned char*>(src_image.data);\n\n  if (!linear_to_standard_rgb && !standard_to_linear_rgb) {\n    // Copy the memory by row.\n    for (size_t slice = 0; slice < size.z; ++slice) {\n      size_t src_offset_temp = src_offset + slice * src_slice_pitch;\n      size_t dst_offset_temp = dst_offset + slice * dst_slice_pitch;\n\n      for (size_t rows = 0; rows < size.y; ++rows) {\n        std::memcpy((dst + dst_offset_temp), (src + src_offset_temp),\n                    copy_size);\n        src_offset_temp += src_row_pitch;\n        dst_offset_temp += dst_row_pitch;\n      }\n    }\n  } else {\n    // Copy per pixel between RGBA-SRGBA images.\n    for (size_t slice = 0; slice < size.z; ++slice) {\n      size_t src_offset_temp = src_offset + slice * src_slice_pitch;\n      size_t dst_offset_temp = dst_offset + slice * dst_slice_pitch;\n\n      for (size_t rows = 0; rows < size.y; ++rows) {\n        const uint8_t* src_pixel = src + src_offset_temp;\n        uint8_t* dst_pixel = dst + dst_offset_temp;\n\n        if (linear_to_standard_rgb) {\n          for (size_t cols = 0; cols < size.x; ++cols) {\n            dst_pixel[0] =\n                Denormalize(LinearToStandardRGB(Normalize(src_pixel[0])));  // R\n            dst_pixel[1] =\n                Denormalize(LinearToStandardRGB(Normalize(src_pixel[1])));  // G\n            dst_pixel[2] =\n                Denormalize(LinearToStandardRGB(Normalize(src_pixel[2])));  // B\n            dst_pixel[3] = src_pixel[3];                                    // A\n\n            src_pixel += element_size;\n            dst_pixel += element_size;\n          }\n        } else {\n          assert(standard_to_linear_rgb);\n          for (size_t cols = 0; cols < size.x; ++cols) {\n            dst_pixel[0] =\n                Denormalize(StandardToLinearRGB(Normalize(src_pixel[0])));  // R\n            dst_pixel[1] =\n                Denormalize(StandardToLinearRGB(Normalize(src_pixel[1])));  // G\n            dst_pixel[2] =\n                Denormalize(StandardToLinearRGB(Normalize(src_pixel[2])));  // B\n            dst_pixel[3] = src_pixel[3];                                    // A\n\n            src_pixel += element_size;\n            dst_pixel += element_size;\n          }\n        }\n\n        src_offset_temp += src_row_pitch;\n        dst_offset_temp += dst_row_pitch;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nuint16_t ImageManager::FloatToHalf(float in) {\n  volatile union {\n    float f;\n    uint32_t u;\n  } fu;\n\n  fu.f = in;\n\n  const uint16_t sign_bit_16 = (fu.u >> 16) & 0x8000;\n\n  const uint32_t exp_32 = (fu.u >> 23) & 0xff;\n\n  const uint32_t mantissa_32 = (fu.u) & 0x7fffff;\n\n  if (exp_32 == 0 && mantissa_32 == 0) {\n    // Zero.\n    return sign_bit_16;\n  } else if (exp_32 == 0xff) {\n    if (mantissa_32 == 0) {\n      // Inf.\n      return (sign_bit_16 | 0x7c00);\n    } else if ((mantissa_32 & 0x400000)) {\n      // Quiet NaN.\n      return (sign_bit_16 | 0x7e00);\n    } else {\n      // Signal NaN.\n      return (sign_bit_16 | 0x7c01);\n    }\n  } else {\n    const uint32_t kMaxExpNormal = 0x477fe000 >> 23;     // 65504.\n    const uint32_t kMinExpNormal = 0x38800000 >> 23;     // 2^-14;\n    const uint32_t kMinExpSubnormal = 0x33800000 >> 23;  // 2^-24.\n    if (exp_32 > kMaxExpNormal) {\n      // Half overflow.\n      // TODO: clamp it to max half float or +Inf.\n      return (sign_bit_16 | 0x7bff);\n    } else if (exp_32 < kMinExpSubnormal) {\n      // Half underflow.\n      return (sign_bit_16);\n    } else if (exp_32 < kMinExpNormal) {\n      // Half subnormal.\n      return (sign_bit_16 |\n              ((0x0400 | (mantissa_32 >> 13)) >> (127 - exp_32 - 14)));\n    } else {\n      // Half normal.\n      return (sign_bit_16 |\n              (((exp_32 - 127 + 15) << 10) | (mantissa_32 >> 13)));\n    }\n  }\n}\n\nfloat ImageManager::Normalize(uint8_t u_val) {\n  if (u_val == 0) {\n    return 0.0f;\n  } else if (u_val == UINT8_MAX) {\n    return 1.0f;\n  } else {\n    return std::min(\n        std::max(static_cast<float>(u_val) / static_cast<float>(UINT8_MAX),\n                 0.0f),\n        1.0f);\n  }\n}\n\nuint8_t ImageManager::Denormalize(float f_val) {\n  const unsigned long kScale = UINT8_MAX;\n  return std::min(\n      static_cast<unsigned long>(std::max(lrintf(kScale * f_val), 0l)), kScale);\n}\n\nfloat ImageManager::StandardToLinearRGB(float s_val) {\n  // Map SRGB value to RGB color space based on HSA Programmers Reference\n  // Manual version 1.0 Provisional, chapter 7.1.4.1.2  Standard RGB (s-Form).\n  double l_val = (double)s_val;\n\n  l_val = (l_val <= 0.04045f) ? (l_val / 12.92f)\n                              : pow(((l_val + 0.055f) / 1.055f), 2.4f);\n\n  return l_val;\n}\n\nfloat ImageManager::LinearToStandardRGB(float l_val) {\n  // Map RGB value to SRGB color space based on HSA Programmers Reference\n  // Manual version 1.0 Provisional, chapter 7.1.4.1.2  Standard RGB (s-Form).\n  double s_val = (double)l_val;\n\n#if (defined(WIN32) || defined(_WIN32))\n  if (_isnan(s_val)) s_val = 0.0;\n#else\n  if (std::isnan(s_val)) s_val = 0.0;\n#endif\n\n  if (s_val > 1.0) {\n    s_val = 1.0;\n  } else if (s_val < 0.0) {\n    s_val = 0.0;\n  } else if (s_val < 0.0031308) {\n    s_val = 12.92 * s_val;\n  } else {\n    s_val = (1.055 * pow(s_val, 5.0 / 12.0)) - 0.055;\n  }\n\n  return s_val;\n}\n\nvoid ImageManager::FormatPattern(const hsa_ext_image_format_t& format,\n                                 const void* pattern_in, void* pattern_out) {\n  const int kR = 0;\n  const int kG = 1;\n  const int kB = 2;\n  const int kA = 3;\n\n  int index[4] = {0};\n  int num_channel = 0;\n\n  switch (format.channel_order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_A:\n      index[0] = kA;\n      num_channel = 1;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_R:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RX:\n      index[0] = kR;\n      num_channel = 1;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RG:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGX:\n      index[0] = kR;\n      index[1] = kG;\n      num_channel = 2;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RA:\n      index[0] = kR;\n      index[1] = kA;\n      num_channel = 2;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n      index[0] = kR;\n      index[1] = kG;\n      index[2] = kB;\n      num_channel = 3;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n      index[0] = kR;\n      index[1] = kG;\n      index[2] = kB;\n      index[3] = kA;\n      num_channel = 4;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA:\n      index[0] = kB;\n      index[1] = kG;\n      index[2] = kR;\n      index[3] = kA;\n      num_channel = 4;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB:\n      index[0] = kA;\n      index[1] = kR;\n      index[2] = kG;\n      index[3] = kB;\n      num_channel = 4;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR:\n      index[0] = kA;\n      index[1] = kB;\n      index[2] = kG;\n      index[3] = kR;\n      num_channel = 4;\n      break;\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL:\n      index[0] = kR;\n      num_channel = 1;\n      break;\n    default:\n      assert(false && \"Should not reach here.\");\n      break;\n  }\n\n  const float* pattern_in_f = NULL;\n  const int32_t* pattern_in_i32 = NULL;\n  const uint32_t* pattern_in_ui32 = NULL;\n\n  float new_pattern_in_f[4] = { 0 };\n  if ((format.channel_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB) ||\n      (format.channel_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX) ||\n      (format.channel_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA) ||\n      (format.channel_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA)) {\n    pattern_in_f = reinterpret_cast<const float*>(pattern_in);\n\n    new_pattern_in_f[0] = LinearToStandardRGB(pattern_in_f[0]);\n    new_pattern_in_f[1] = LinearToStandardRGB(pattern_in_f[1]);\n    new_pattern_in_f[2] = LinearToStandardRGB(pattern_in_f[2]);\n    new_pattern_in_f[3] = pattern_in_f[3];\n\n    pattern_in_f = reinterpret_cast<const float*>(new_pattern_in_f);\n  } else {\n    pattern_in_f = reinterpret_cast<const float*>(pattern_in);\n    pattern_in_i32 = reinterpret_cast<const int32_t*>(pattern_in);\n    pattern_in_ui32 = reinterpret_cast<const uint32_t*>(pattern_in);\n  }\n\n  for (int c = 0; c < num_channel; ++c) {\n    switch (format.channel_type) {\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT8: {\n        int8_t* pattern_out_i8 = reinterpret_cast<int8_t*>(pattern_out);\n        const long kScale = INT8_MAX;\n        const long conv = lrintf(kScale * pattern_in_f[index[c]]);\n        pattern_out_i8[c] = std::min(std::max(conv, -kScale - 1l), kScale);\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT16: {\n        int16_t* pattern_out_i16 = reinterpret_cast<int16_t*>(pattern_out);\n        const long kScale = INT16_MAX;\n        const long conv = lrintf(kScale * pattern_in_f[index[c]]);\n        pattern_out_i16[c] = std::min(std::max(conv, -kScale - 1l), kScale);\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8: {\n        uint8_t* pattern_out_ui8 = reinterpret_cast<uint8_t*>(pattern_out);\n        const unsigned long kScale = UINT8_MAX;\n        const long conv = lrintf(kScale * pattern_in_f[index[c]]);\n        pattern_out_ui8[c] =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT16: {\n        uint16_t* pattern_out_ui16 = reinterpret_cast<uint16_t*>(pattern_out);\n        const unsigned long kScale = UINT16_MAX;\n        const long conv = lrintf(kScale * pattern_in_f[index[c]]);\n        pattern_out_ui16[c] =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT24: {\n        typedef struct Order24 { uint32_t r : 24; } Order24;\n\n        Order24* pattern_out_u24 = reinterpret_cast<Order24*>(pattern_out);\n        const unsigned long kScale = 0xffffff;\n        const long conv = lrintf(kScale * pattern_in_f[index[c]]);\n        pattern_out_u24[c].r =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555: {\n        typedef struct Order555 {\n          uint32_t b : 5;\n          uint32_t g : 5;\n          uint32_t r : 5;\n        } Order555;\n\n        Order555* pattern_out_u555 = reinterpret_cast<Order555*>(pattern_out);\n        const unsigned long kScale = 0x1f;\n        long conv = lrintf(kScale * pattern_in_f[index[0]]);\n        pattern_out_u555->r =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n\n        conv = lrintf(kScale * pattern_in_f[index[1]]);\n        pattern_out_u555->g =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n\n        conv = lrintf(kScale * pattern_in_f[index[2]]);\n        pattern_out_u555->b =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n        return;\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565: {\n        typedef struct Order565 {\n          uint32_t b : 5;\n          uint32_t g : 6;\n          uint32_t r : 5;\n        } Order565;\n\n        Order565* pattern_out_u565 = reinterpret_cast<Order565*>(pattern_out);\n        unsigned long scale = 0x1f;\n        long conv = lrintf(scale * pattern_in_f[index[0]]);\n        pattern_out_u565->r =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), scale);\n\n        scale = 0x3f;\n        conv = lrintf(scale * pattern_in_f[index[1]]);\n        pattern_out_u565->g =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), scale);\n\n        scale = 0x1f;\n        conv = lrintf(scale * pattern_in_f[index[2]]);\n        pattern_out_u565->b =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), scale);\n        return;\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010: {\n        typedef struct Order101010 {\n          uint32_t b : 10;\n          uint32_t g : 10;\n          uint32_t r : 10;\n        } Order101010;\n\n        Order101010* pattern_out_u101010 =\n            reinterpret_cast<Order101010*>(pattern_out);\n        const unsigned long kScale = 0x3ff;\n        long conv = lrintf(kScale * pattern_in_f[index[0]]);\n        pattern_out_u101010->r =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n\n        conv = lrintf(kScale * pattern_in_f[index[1]]);\n        pattern_out_u101010->g =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n\n        conv = lrintf(kScale * pattern_in_f[index[2]]);\n        pattern_out_u101010->b =\n            std::min(static_cast<unsigned long>(std::max(conv, 0l)), kScale);\n\n        return;\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT8: {\n        int8_t* pattern_out_i8 = reinterpret_cast<int8_t*>(pattern_out);\n        pattern_out_i8[c] = pattern_in_i32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT16: {\n        int16_t* pattern_out_i16 = reinterpret_cast<int16_t*>(pattern_out);\n        pattern_out_i16[c] = pattern_in_i32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT32: {\n        int32_t* pattern_out_i32 = reinterpret_cast<int32_t*>(pattern_out);\n        pattern_out_i32[c] = pattern_in_i32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8: {\n        uint8_t* pattern_out_ui8 = reinterpret_cast<uint8_t*>(pattern_out);\n        pattern_out_ui8[c] = pattern_in_ui32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16: {\n        uint16_t* pattern_out_ui16 = reinterpret_cast<uint16_t*>(pattern_out);\n        pattern_out_ui16[c] = pattern_in_ui32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32: {\n        uint32_t* pattern_out_ui32 = reinterpret_cast<uint32_t*>(pattern_out);\n        pattern_out_ui32[c] = pattern_in_ui32[index[c]];\n      } break;\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_HALF_FLOAT: {\n        // TODO: convert to f16\n        uint16_t* pattern_out_ui16 = reinterpret_cast<uint16_t*>(pattern_out);\n        pattern_out_ui16[c] = FloatToHalf(pattern_in_f[index[c]]);\n        break;\n      }\n      case HSA_EXT_IMAGE_CHANNEL_TYPE_FLOAT: {\n        float* pattern_out_f = reinterpret_cast<float*>(pattern_out);\n        pattern_out_f[c] = pattern_in_f[index[c]];\n      } break;\n      default:\n        assert(false && \"Should not reach here.\");\n        break;\n    }\n  }\n}\n\nhsa_status_t ImageManager::FillImage(const Image& image, const void* pattern,\n                                     const hsa_ext_image_region_t& region) {\n  const hsa_dim3_t origin = region.offset;\n  const hsa_dim3_t size = region.range;\n\n  ImageProperty image_prop =\n      GetImageProperty(image.component, image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n\n  const size_t element_size = image_prop.element_size;\n  assert(element_size != 0);\n\n  const size_t row_pitch = image.row_pitch;\n  const size_t slice_pitch = image.slice_pitch;\n\n  // Map memory.\n  unsigned char* fill_mem = static_cast<unsigned char*>(image.data);\n\n  char fill_value[4 * sizeof(int)] = {0};\n  FormatPattern(image.desc.format, pattern, fill_value);\n\n  // Calculate offset.\n  size_t offset = origin.x * element_size;\n  offset += row_pitch * origin.y;\n  offset += slice_pitch * origin.z;\n\n  // Fill the image memory with the pattern.\n  for (size_t slice = 0; slice < size.z; ++slice) {\n    size_t offset_temp = offset + slice * slice_pitch;\n\n    for (size_t rows = 0; rows < size.y; ++rows) {\n      size_t pix_offset = offset_temp;\n\n      // Copy pattern per pixel.\n      for (size_t column = 0; column < size.x; ++column) {\n        memcpy((fill_mem + pix_offset), fill_value, element_size);\n        pix_offset += element_size;\n      }\n\n      offset_temp += row_pitch;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_EXT_IMAGE_IMAGE_MANAGER_H\n#define AMD_HSA_EXT_IMAGE_IMAGE_MANAGER_H\n\n#include <cstring>\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"resource.h\"\n#include \"util.h\"\n\nnamespace rocr {\nnamespace image {\n\n/// @brief Abstract class for creating AMD agent specific image / sampler\n/// resources and data transfer.\nclass ImageManager {\n public:\n  explicit ImageManager();\n  virtual ~ImageManager();\n\n  virtual hsa_status_t Initialize(hsa_agent_t agent_handle) = 0;\n\n  virtual void Cleanup() = 0;\n\n  /// @brief Retrieve device specific image property of a certain format\n  /// and geometry.\n  virtual ImageProperty GetImageProperty(\n      hsa_agent_t component, const hsa_ext_image_format_t& format,\n      hsa_ext_image_geometry_t geometry) const = 0;\n\n  /// @brief Retrieve device specific supported max width, height, depth,\n  /// and array size of an image geometry.\n  virtual void GetImageInfoMaxDimension(hsa_agent_t component,\n                                        hsa_ext_image_geometry_t geometry,\n                                        uint32_t& width, uint32_t& height,\n                                        uint32_t& depth,\n                                        uint32_t& array_size) const = 0;\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch,\n      size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const = 0;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const = 0;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const = 0;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(\n      Image& image, hsa_ext_image_format_t& new_format) const = 0;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const = 0;\n\n  // @brief Copy the content of a linear memory to an image object.\n  virtual hsa_status_t CopyBufferToImage(\n      const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n      const Image& dst_image, const hsa_ext_image_region_t& image_region);\n\n  /// @brief Copy the content of an image object to a linear memory.\n  virtual hsa_status_t CopyImageToBuffer(\n      const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n      size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region);\n\n  /// @brief Transfer images backing storage.\n  virtual hsa_status_t CopyImage(const Image& dst_image, const Image& src_image,\n                                 const hsa_dim3_t& dst_origin,\n                                 const hsa_dim3_t& src_origin,\n                                 const hsa_dim3_t size);\n\n  /// @brief Fill image backing storage using host copy.\n  virtual hsa_status_t FillImage(const Image& image, const void* pattern,\n                                 const hsa_ext_image_region_t& region);\n\n protected:\n  static uint16_t FloatToHalf(float in);\n\n  static inline float Normalize(uint8_t u_val);\n\n  static inline uint8_t Denormalize(float f_val);\n\n  static float StandardToLinearRGB(float s_val);\n\n  static float LinearToStandardRGB(float l_val);\n\n  static void FormatPattern(const hsa_ext_image_format_t& format,\n                            const void* pattern_in, void* pattern_out);\n\n  template <typename dstT, typename srcT>\n  static inline hsa_status_t convertAddressMode(dstT &word,\n                            const hsa_ext_sampler_addressing_mode32_t address_mode[3]) {\n    srcT clamp[3];\n    for (int i = 0; i < 3; i++) {\n      switch (address_mode[i]) {\n        case HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE:\n          clamp[i] = srcT::SQ_TEX_CLAMP_LAST_TEXEL;\n          break;\n        case HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_BORDER:\n          clamp[i] = srcT::SQ_TEX_CLAMP_BORDER;\n          break;\n        case HSA_EXT_SAMPLER_ADDRESSING_MODE_MIRRORED_REPEAT:\n          clamp[i] = srcT::SQ_TEX_MIRROR;\n          break;\n        case HSA_EXT_SAMPLER_ADDRESSING_MODE_UNDEFINED:\n        case HSA_EXT_SAMPLER_ADDRESSING_MODE_REPEAT:\n          clamp[i] = srcT::SQ_TEX_WRAP;\n          break;\n        default:\n          return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n    }\n    word.bits.CLAMP_X = static_cast<unsigned int>(clamp[0]);\n    word.bits.CLAMP_Y = static_cast<unsigned int>(clamp[1]);\n    word.bits.CLAMP_Z = static_cast<unsigned int>(clamp[2]);\n    return HSA_STATUS_SUCCESS;\n  }\n private:\n  DISALLOW_COPY_AND_ASSIGN(ImageManager);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // AMD_HSA_EXT_IMAGE_IMAGE_MANAGER_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_ai.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_manager_ai.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n\n#include \"core/inc/runtime.h\"\n#include \"hsakmt/hsakmt.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"addrlib/src/core/addrlib.h\"\n#include \"image_runtime.h\"\n#include \"resource.h\"\n#include \"resource_ai.h\"\n#include \"util.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nImageManagerAi::ImageManagerAi() : ImageManagerKv() {}\n\nImageManagerAi::~ImageManagerAi() {}\n\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD3)\n\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD3)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD4)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD5)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD6)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD7)\n\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD3)\n\nhsa_status_t ImageManagerAi::CalculateImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) const {\n  ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n  hsa_profile_t profile;\n\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  Image::TileMode tileMode = Image::TileMode::LINEAR;\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE) {\n    tileMode = (profile == HSA_PROFILE_BASE &&\n                desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)?\n      Image::TileMode::TILED : Image::TileMode::LINEAR;\n  }\n  if (GetAddrlibSurfaceInfoAi(component, desc, tileMode,\n        image_data_row_pitch, image_data_slice_pitch, out) == (uint32_t)(-1)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  size_t rowPitch   = (out.bpp >> 3) * out.pitch;\n  size_t slicePitch = rowPitch * out.height;\n  if (desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n      image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR &&\n      ((image_data_row_pitch && (rowPitch != image_data_row_pitch)) ||\n       (image_data_slice_pitch && (slicePitch != image_data_slice_pitch)))) {\n    return static_cast<hsa_status_t>(HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED);\n  }\n\n  image_info.size = out.surfSize;\n  assert(image_info.size != 0);\n  image_info.alignment = out.baseAlign;\n  assert(image_info.alignment != 0);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool ImageManagerAi::IsLocalMemory(const void* address) const {\n  return true;\n}\n\nhsa_status_t ImageManagerAi::PopulateImageSrd(Image& image, const metadata_amd_t* descriptor) const {\n  metadata_amd_ai_t* desc = (metadata_amd_ai_t*)descriptor;\n  const void* image_data_addr = image.data;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  if((image_prop.cap == HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED) ||\n     (image_prop.element_size == 0))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n\n  if (IsLocalMemory(image.data)) {\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  image.srd[0]=desc->word0.u32All;\n  image.srd[1]=desc->word1.u32All;\n  image.srd[2]=desc->word2.u32All;\n  image.srd[3]=desc->word3.u32All;\n  image.srd[4]=desc->word4.u32All;\n  image.srd[5]=desc->word5.u32All;\n  image.srd[6]=desc->word6.u32All;\n  image.srd[7]=desc->word7.u32All;\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    sq_buf_rsrc_word0_u word0;\n    sq_buf_rsrc_word1_u word1;\n    sq_buf_rsrc_word3_u word3;\n\n    word0.val = 0;\n    word0.f.base_address = PtrLow32(image_data_addr);\n\n    word1.val = image.srd[1];\n    word1.f.base_address_hi = PtrHigh32(image_data_addr);\n    word1.f.stride = image_prop.element_size;\n\n    word3.val = image.srd[3];\n    word3.f.dst_sel_x = swizzle.x;\n    word3.f.dst_sel_y = swizzle.y;\n    word3.f.dst_sel_z = swizzle.z;\n    word3.f.dst_sel_w = swizzle.w;\n    word3.f.num_format = image_prop.data_type;\n    word3.f.data_format = image_prop.data_format;\n    word3.f.index_stride = image_prop.element_size;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[3] = word3.val;\n  } else {\n    uint32_t hwPixelSize = ImageLut().GetPixelSize(desc->word1.bitfields.DATA_FORMAT,\n                                                   desc->word1.bitfields.NUM_FORMAT);\n    if(image_prop.element_size!=hwPixelSize)\n      return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n    ((SQ_IMG_RSRC_WORD0*)(&image.srd[0]))->bits.BASE_ADDRESS = PtrLow40Shift8(image_data_addr);\n    ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.BASE_ADDRESS_HI = PtrHigh64Shift40(image_data_addr);\n    ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.DATA_FORMAT = image_prop.data_format;\n    ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.NUM_FORMAT = image_prop.data_type;\n    ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.DST_SEL_X = swizzle.x;\n    ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.DST_SEL_Y = swizzle.y;\n    ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.DST_SEL_Z = swizzle.z;\n    ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.DST_SEL_W = swizzle.w;\n    if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n        image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1D) {\n      ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.TYPE =\n          ImageLut().MapGeometry(image.desc.geometry);\n    }\n    \n    // Imported metadata holds the offset to metadata, add the image base address.\n    uintptr_t meta = uintptr_t(((SQ_IMG_RSRC_WORD5*)(&image.srd[5]))->bits.META_DATA_ADDRESS_HI) << 40;\n    meta |= uintptr_t(((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS) << 8;\n    meta += reinterpret_cast<uintptr_t>(image_data_addr);\n\n    ((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS = PtrLow40Shift8((void*)meta);\n    ((SQ_IMG_RSRC_WORD5*)(&image.srd[5]))->bits.META_DATA_ADDRESS_HI =\n        PtrHigh64Shift40((void*)meta);\n  }\n  //Looks like this is only used for CPU copies.\n  image.row_pitch = 0;//desc->word4.bits.pitch+1*desc->word3.bits.element_size;\n  image.slice_pitch = 0;//desc->;\n\n  //Used by HSAIL shader ABI\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic TEX_BC_SWIZZLE GetBcSwizzle(const Swizzle& swizzle) {\n    SEL r = (SEL)swizzle.x;\n    SEL g = (SEL)swizzle.y;\n    SEL b = (SEL)swizzle.z;\n    SEL a = (SEL)swizzle.w;\n\n    TEX_BC_SWIZZLE bcSwizzle = TEX_BC_Swizzle_XYZW;\n\n    if (a == SEL_X)\n    {\n        // Have to use either TEX_BC_Swizzle_WZYX or TEX_BC_Swizzle_WXYZ\n        //\n        // For the pre-defined border color values (white, opaque black, transparent black), the only thing that\n        // matters is that the alpha channel winds up in the correct place (because the RGB channels are all the same)\n        // so either of these TEX_BC_Swizzle enumerations will work.  Not sure what happens with border color palettes.\n        if (b == SEL_Y)\n        {\n            // ABGR\n            bcSwizzle = TEX_BC_Swizzle_WZYX;\n        }\n        else if ((r == SEL_X) && (g == SEL_X) && (b == SEL_X))\n        {\n            //RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        }\n        else\n        {\n            // ARGB\n            bcSwizzle = TEX_BC_Swizzle_WXYZ;\n        }\n    }\n    else if (r == SEL_X)\n    {\n        // Have to use either TEX_BC_Swizzle_XYZW or TEX_BC_Swizzle_XWYZ\n        if (g == SEL_Y)\n        {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        }\n        else if((g == SEL_X) && (b == SEL_X) && (a == SEL_W))\n        {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        }\n        else\n        {\n            // RAGB\n            bcSwizzle = TEX_BC_Swizzle_XWYZ;\n        }\n    }\n    else if (g == SEL_X)\n    {\n        // GRAB, have to use TEX_BC_Swizzle_YXWZ\n        bcSwizzle = TEX_BC_Swizzle_YXWZ;\n    }\n    else if (b == SEL_X)\n    {\n        // BGRA, have to use TEX_BC_Swizzle_ZYXW\n        bcSwizzle = TEX_BC_Swizzle_ZYXW;\n    }\n\n    return bcSwizzle;\n}\n\n\nhsa_status_t ImageManagerAi::PopulateImageSrd(Image& image) const {\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  const void* image_data_addr = image.data;\n\n  if (IsLocalMemory(image.data))\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    sq_buf_rsrc_word0_u word0;\n    sq_buf_rsrc_word1_u word1;\n    sq_buf_rsrc_word2_u word2;\n    sq_buf_rsrc_word3_u word3;\n\n    word0.val = 0;\n    word0.f.base_address = PtrLow32(image_data_addr);\n\n    word1.val = 0;\n    word1.f.base_address_hi = PtrHigh32(image_data_addr);\n    word1.f.stride = image_prop.element_size;\n    word1.f.swizzle_enable = false;\n    word1.f.cache_swizzle = false;\n\n    word2.f.num_records = image.desc.width * image_prop.element_size;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.dst_sel_x = swizzle.x;\n    word3.f.dst_sel_y = swizzle.y;\n    word3.f.dst_sel_z = swizzle.z;\n    word3.f.dst_sel_w = swizzle.w;\n    word3.f.num_format = image_prop.data_type;\n    word3.f.data_format = image_prop.data_format;\n    word3.f.index_stride = image_prop.element_size;\n    word3.f.type = ImageLut().MapGeometry(image.desc.geometry);\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n\n    image.row_pitch = image.desc.width * image_prop.element_size;\n    image.slice_pitch = image.row_pitch;\n  } else {\n    sq_img_rsrc_word0_u word0;\n    sq_img_rsrc_word1_u word1;\n    sq_img_rsrc_word2_u word2;\n    sq_img_rsrc_word3_u word3;\n    sq_img_rsrc_word4_u word4;\n    sq_img_rsrc_word5_u word5;\n    sq_img_rsrc_word6_u word6;\n    sq_img_rsrc_word7_u word7;\n\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n\n    uint32_t swizzleMode = GetAddrlibSurfaceInfoAi(image.component, image.desc, image.tile_mode,\n          image.row_pitch, image.slice_pitch, out);\n    if (swizzleMode == (uint32_t)(-1)) {\n      return HSA_STATUS_ERROR;\n    }\n\n    assert((out.bpp / 8) == image_prop.element_size);\n\n    const size_t row_pitch_size = out.pitch * image_prop.element_size;\n\n    word0.f.base_address = PtrLow40Shift8(image_data_addr);\n\n    word1.val = 0;\n    word1.f.base_address_hi = PtrHigh64Shift40(image_data_addr);\n    word1.f.min_lod = 0;\n    word1.f.data_format = image_prop.data_format;\n    word1.f.num_format = image_prop.data_type;\n\n    word2.val = 0;\n    word2.f.width = image.desc.width - 1;\n    word2.f.height = image.desc.height - 1;\n    word2.f.perf_mod = 0;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.dst_sel_x = swizzle.x;\n    word3.f.dst_sel_y = swizzle.y;\n    word3.f.dst_sel_z = swizzle.z;\n    word3.f.dst_sel_w = swizzle.w;\n    word3.f.sw_mode = swizzleMode;\n    word3.f.type = ImageLut().MapGeometry(image.desc.geometry);\n\n    const bool image_array =\n        (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH);\n    const bool image_3d = (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_3D);\n\n    word4.val = 0;\n    word4.f.depth =\n        (image_array)\n            ? std::max(image.desc.array_size, static_cast<size_t>(1)) - 1\n            : (image_3d) ? image.desc.depth - 1 : 0;\n    word4.f.pitch = out.pitch - 1;\n    word4.f.bc_swizzle = GetBcSwizzle(swizzle);\n\n    word5.val = 0;\n    word6.val = 0;\n    word7.val = 0;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n    image.srd[4] = word4.val;\n    image.srd[5] = word5.val;\n    image.srd[6] = word6.val;\n    image.srd[7] = word7.val;\n\n    image.row_pitch = row_pitch_size;\n    image.slice_pitch = out.sliceSize;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerAi::ModifyImageSrd(\n    Image& image, hsa_ext_image_format_t& new_format) const {\n  image.desc.format = new_format;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_BUF_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n    word3->bits.NUM_FORMAT = image_prop.data_type;\n    word3->bits.DATA_FORMAT = image_prop.data_format;\n  } else {\n    SQ_IMG_RSRC_WORD1* word1 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1]);\n    word1->bits.DATA_FORMAT = image_prop.data_format;\n    word1->bits.NUM_FORMAT = image_prop.data_type;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_IMG_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerAi::PopulateSamplerSrd(Sampler& sampler) const {\n  const hsa_ext_sampler_descriptor_v2_t &sampler_descriptor = sampler.desc;\n\n  SQ_IMG_SAMP_WORD0 word0;\n  SQ_IMG_SAMP_WORD1 word1;\n  SQ_IMG_SAMP_WORD2 word2;\n  SQ_IMG_SAMP_WORD3 word3;\n\n  word0.u32All = 0;\n  hsa_status_t status = convertAddressMode<SQ_IMG_SAMP_WORD0, SQ_TEX_CLAMP>\n                                       (word0, sampler_descriptor.address_modes);\n  if (status != HSA_STATUS_SUCCESS) return status;\n  word0.bits.FORCE_UNNORMALIZED = (sampler_descriptor.coordinate_mode ==\n                                  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED);\n\n  word1.u32All = 0;\n  word1.bits.MAX_LOD = 4095;\n\n  word2.u32All = 0;\n  switch (sampler_descriptor.filter_mode) {\n    case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_POINT);\n      break;\n    case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_BILINEAR);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER;\n  word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE;\n  word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE;\n\n  word3.u32All = 0;\n\n  // TODO: check this bit with HSAIL spec.\n  word3.bits.BORDER_COLOR_TYPE = SQ_TEX_BORDER_COLOR_TRANS_BLACK;\n\n  sampler.srd[0] = word0.u32All;\n  sampler.srd[1] = word1.u32All;\n  sampler.srd[2] = word2.u32All;\n  sampler.srd[3] = word3.u32All;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nuint32_t ImageManagerAi::GetAddrlibSurfaceInfoAi(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    Image::TileMode tileMode,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const {\n  const ImageProperty image_prop =\n      GetImageProperty(component, desc.format, desc.geometry);\n\n  const AddrFormat addrlib_format = GetAddrlibFormat(image_prop);\n\n  const uint32_t width = static_cast<uint32_t>(desc.width);\n  const uint32_t height = static_cast<uint32_t>(desc.height);\n  static const size_t kMinNumSlice = 1;\n  const uint32_t num_slice = static_cast<uint32_t>(\n      std::max(kMinNumSlice, std::max(desc.array_size, desc.depth)));\n\n  ADDR2_COMPUTE_SURFACE_INFO_INPUT in = {0};\n  in.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);\n  in.format = addrlib_format;\n  in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n  in.width = width;\n  in.height = height;\n  in.numSlices = num_slice;\n  in.pitchInElement = image_data_row_pitch / image_prop.element_size;\n  switch(desc.geometry) {\n  case HSA_EXT_IMAGE_GEOMETRY_1D:\n  case HSA_EXT_IMAGE_GEOMETRY_1DB:\n  case HSA_EXT_IMAGE_GEOMETRY_1DA:\n    in.resourceType = ADDR_RSRC_TEX_1D;\n    break;\n  case HSA_EXT_IMAGE_GEOMETRY_2D:\n  case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n  case HSA_EXT_IMAGE_GEOMETRY_2DA:\n  case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n    in.resourceType = ADDR_RSRC_TEX_2D;\n    break;\n  case HSA_EXT_IMAGE_GEOMETRY_3D:\n    {\n\t    in.resourceType = ADDR_RSRC_TEX_3D;\n\t    /*\n\t     * 3D swizzle modes enforce alignment\n\t     * of the number of slices  to the block depth.\n\t     * If numSlices = 3 then the 3 slices are\n\t     * interleaved for 3D locality among the 8 slices\n\t     * that make up each block. This causes the memory\n\t     * footprint to jump to a 3x size of the ideal size\n\t     *\n\t     * 'enable3DSwizzleMode' flag tests for env variable\n\t     * HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG to enable or disable\n\t     * 3D swizzle:\n\t     * true: Keep view3dAs2dArray = 0 for real 3D interleaving.\n\t     * false: Use view3dAs2dArray = 1 to avoid the alignment\n\t     *       expansion.\n\t     * 2D swizzle modes can lower size overhead but may yield\n\t     * suboptimal cache behavior for fully 3D volumetric\n\t     * operations.\n\t     */\n\t    bool enable3DSwizzleMode = core::Runtime::runtime_singleton_->flag().enable_3d_swizzle();\n\t    if (enable3DSwizzleMode)\n\t\t    in.flags.view3dAs2dArray = 0;\n\t    else\n\t\t    in.flags.view3dAs2dArray = 1;\n\n\t    break;\n    }\n  }\n  in.flags.texture = 1;\n\n  ADDR2_GET_PREFERRED_SURF_SETTING_INPUT  prefSettingsInput = { 0 };\n  ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT prefSettingsOutput = { 0 };\n\n  prefSettingsInput.size            = sizeof(prefSettingsInput);\n  prefSettingsInput.flags           = in.flags;\n  prefSettingsInput.bpp             = in.bpp;\n  prefSettingsInput.format          = in.format;\n  prefSettingsInput.width           = in.width;\n  prefSettingsInput.height          = in.height;\n  prefSettingsInput.numFrags        = in.numFrags;\n  prefSettingsInput.numSamples      = in.numSamples;\n  prefSettingsInput.numMipLevels    = in.numMipLevels;\n  prefSettingsInput.numSlices       = in.numSlices;\n  prefSettingsInput.resourceLoction = ADDR_RSRC_LOC_UNDEF;\n  prefSettingsInput.resourceType    = in.resourceType;\n\n  // Disallow all swizzles but linear.\n  if (tileMode == Image::TileMode::LINEAR) \n  {\n      prefSettingsInput.forbiddenBlock.macroThin4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThin64KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick64KB = 1;\n  }\n\n  prefSettingsInput.forbiddenBlock.micro = 1; // but don't ever allow the 256b swizzle modes\n  prefSettingsInput.forbiddenBlock.var = 1; // and don't allow variable-size block modes\n\n  if (ADDR_OK != Addr2GetPreferredSurfaceSetting(addr_lib_, &prefSettingsInput, &prefSettingsOutput)) {\n    return (uint32_t)(-1);\n  }\n\n  in.swizzleMode = prefSettingsOutput.swizzleMode;\n\n  out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);\n  if (ADDR_OK != Addr2ComputeSurfaceInfo(addr_lib_, &in, &out)) {\n    return (uint32_t)(-1);\n  }\n  if (out.surfSize == 0) {\n    return (uint32_t)(-1);\n  }\n\n  return in.swizzleMode;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_ai.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_AI_H\n#define HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_AI_H\n\n#include \"addrlib/inc/addrinterface.h\"\n#include \"image_manager_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageManagerAi : public ImageManagerKv {\n public:\n  explicit ImageManagerAi();\n  virtual ~ImageManagerAi();\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch, size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(Image& image,\n                                      hsa_ext_image_format_t& new_format) const;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const;\n\n protected:\n  uint32_t GetAddrlibSurfaceInfoAi(hsa_agent_t component,\n                             const hsa_ext_image_descriptor_t& desc,\n                             Image::TileMode tileMode,\n                             size_t image_data_row_pitch,\n                             size_t image_data_slice_pitch,\n                             ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const;\n\n  bool IsLocalMemory(const void* address) const;\n\n private:\n  DISALLOW_COPY_AND_ASSIGN(ImageManagerAi);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_AI_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_gfx11.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2021, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_manager_gfx11.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n\n#include \"core/inc/runtime.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"addrlib/src/core/addrlib.h\"\n#include \"image_runtime.h\"\n#include \"resource.h\"\n#include \"resource_gfx11.h\"\n#include \"util.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD3)\n\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD3)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD4)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD5)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD6)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD7)\n\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD3)\n\n//-----------------------------------------------------------------------------\n// Workaround switch to combined format/type codes and missing gfx11\n// specific look up table.  Only covers types used in image_lut_gfx11.cpp.\n//-----------------------------------------------------------------------------\nstruct formatconverstion_t {\n  FMT fmt;\n  type type;\n  FORMAT format;\n};\n\n// Format/Type to combined format code table.\n// Sorted and indexed to allow fast searches.\nstatic const formatconverstion_t FormatLUT[] = {\n    {FMT_1_5_5_5, TYPE_UNORM, CFMT_1_5_5_5_UNORM},              // 0\n    {FMT_10_10_10_2, TYPE_UNORM, CFMT_10_10_10_2_UNORM},        // 1\n    {FMT_10_10_10_2, TYPE_SNORM, CFMT_10_10_10_2_SNORM},        // 2\n    {FMT_10_10_10_2, TYPE_UINT, CFMT_10_10_10_2_UINT},          // 3\n    {FMT_10_10_10_2, TYPE_SINT, CFMT_10_10_10_2_SINT},          // 4\n    {FMT_16, TYPE_UNORM, CFMT_16_UNORM},                        // 5\n    {FMT_16, TYPE_SNORM, CFMT_16_SNORM},                        // 6\n    {FMT_16, TYPE_UINT, CFMT_16_UINT},                          // 7\n    {FMT_16, TYPE_SINT, CFMT_16_SINT},                          // 8\n    {FMT_16, TYPE_FLOAT, CFMT_16_FLOAT},                        // 9\n    {FMT_16, TYPE_USCALED, CFMT_16_USCALED},                    // 10\n    {FMT_16, TYPE_SSCALED, CFMT_16_SSCALED},                    // 11\n    {FMT_16_16, TYPE_UNORM, CFMT_16_16_UNORM},                  // 12\n    {FMT_16_16, TYPE_SNORM, CFMT_16_16_SNORM},                  // 13\n    {FMT_16_16, TYPE_UINT, CFMT_16_16_UINT},                    // 14\n    {FMT_16_16, TYPE_SINT, CFMT_16_16_SINT},                    // 15\n    {FMT_16_16, TYPE_FLOAT, CFMT_16_16_FLOAT},                  // 16\n    {FMT_16_16, TYPE_USCALED, CFMT_16_16_USCALED},              // 17\n    {FMT_16_16, TYPE_SSCALED, CFMT_16_16_SSCALED},              // 18\n    {FMT_16_16_16_16, TYPE_UNORM, CFMT_16_16_16_16_UNORM},      // 19\n    {FMT_16_16_16_16, TYPE_SNORM, CFMT_16_16_16_16_SNORM},      // 20\n    {FMT_16_16_16_16, TYPE_UINT, CFMT_16_16_16_16_UINT},        // 21\n    {FMT_16_16_16_16, TYPE_SINT, CFMT_16_16_16_16_SINT},        // 22\n    {FMT_16_16_16_16, TYPE_FLOAT, CFMT_16_16_16_16_FLOAT},      // 23\n    {FMT_16_16_16_16, TYPE_USCALED, CFMT_16_16_16_16_USCALED},  // 24\n    {FMT_16_16_16_16, TYPE_SSCALED, CFMT_16_16_16_16_SSCALED},  // 25\n    {FMT_2_10_10_10, TYPE_UNORM, CFMT_2_10_10_10_UNORM},        // 26\n    {FMT_2_10_10_10, TYPE_SNORM, CFMT_2_10_10_10_SNORM},        // 27\n    {FMT_2_10_10_10, TYPE_UINT, CFMT_2_10_10_10_UINT},          // 28\n    {FMT_2_10_10_10, TYPE_SINT, CFMT_2_10_10_10_SINT},          // 29\n    {FMT_2_10_10_10, TYPE_USCALED, CFMT_2_10_10_10_USCALED},    // 30\n    {FMT_2_10_10_10, TYPE_SSCALED, CFMT_2_10_10_10_SSCALED},    // 31\n    {FMT_24_8, TYPE_UNORM, CFMT_24_8_UNORM},                    // 32\n    {FMT_24_8, TYPE_UINT, CFMT_24_8_UINT},                      // 33\n    {FMT_32, TYPE_UINT, CFMT_32_UINT},                          // 34\n    {FMT_32, TYPE_SINT, CFMT_32_SINT},                          // 35\n    {FMT_32, TYPE_FLOAT, CFMT_32_FLOAT},                        // 36\n    {FMT_32_32, TYPE_UINT, CFMT_32_32_UINT},                    // 37\n    {FMT_32_32, TYPE_SINT, CFMT_32_32_SINT},                    // 38\n    {FMT_32_32, TYPE_FLOAT, CFMT_32_32_FLOAT},                  // 39\n    {FMT_32_32_32, TYPE_UINT, CFMT_32_32_32_UINT},              // 40\n    {FMT_32_32_32, TYPE_SINT, CFMT_32_32_32_SINT},              // 41\n    {FMT_32_32_32, TYPE_FLOAT, CFMT_32_32_32_FLOAT},            // 42\n    {FMT_32_32_32_32, TYPE_UINT, CFMT_32_32_32_32_UINT},        // 43\n    {FMT_32_32_32_32, TYPE_SINT, CFMT_32_32_32_32_SINT},        // 44\n    {FMT_32_32_32_32, TYPE_FLOAT, CFMT_32_32_32_32_FLOAT},      // 45\n    {FMT_5_5_5_1, TYPE_UNORM, CFMT_5_5_5_1_UNORM},              // 46\n    {FMT_5_6_5, TYPE_UNORM, CFMT_5_6_5_UNORM},                  // 47\n    {FMT_8, TYPE_UNORM, CFMT_8_UNORM},                          // 48\n    {FMT_8, TYPE_SNORM, CFMT_8_SNORM},                          // 49\n    {FMT_8, TYPE_UINT, CFMT_8_UINT},                            // 50\n    {FMT_8, TYPE_SINT, CFMT_8_SINT},                            // 51\n    {FMT_8, TYPE_SRGB, CFMT_8_SRGB},                            // 52\n    {FMT_8, TYPE_USCALED, CFMT_8_USCALED},                      // 53\n    {FMT_8, TYPE_SSCALED, CFMT_8_SSCALED},                      // 54\n    {FMT_8_24, TYPE_UNORM, CFMT_8_24_UNORM},                    // 55\n    {FMT_8_24, TYPE_UINT, CFMT_8_24_UINT},                      // 56\n    {FMT_8_8, TYPE_UNORM, CFMT_8_8_UNORM},                      // 57\n    {FMT_8_8, TYPE_SNORM, CFMT_8_8_SNORM},                      // 58\n    {FMT_8_8, TYPE_UINT, CFMT_8_8_UINT},                        // 59\n    {FMT_8_8, TYPE_SINT, CFMT_8_8_SINT},                        // 60\n    {FMT_8_8, TYPE_SRGB, CFMT_8_8_SRGB},                        // 61\n    {FMT_8_8, TYPE_USCALED, CFMT_8_8_USCALED},                  // 62\n    {FMT_8_8, TYPE_SSCALED, CFMT_8_8_SSCALED},                  // 63\n    {FMT_8_8_8_8, TYPE_UNORM, CFMT_8_8_8_8_UNORM},              // 64\n    {FMT_8_8_8_8, TYPE_SNORM, CFMT_8_8_8_8_SNORM},              // 65\n    {FMT_8_8_8_8, TYPE_UINT, CFMT_8_8_8_8_UINT},                // 66\n    {FMT_8_8_8_8, TYPE_SINT, CFMT_8_8_8_8_SINT},                // 67\n    {FMT_8_8_8_8, TYPE_SRGB, CFMT_8_8_8_8_SRGB},                // 68\n    {FMT_8_8_8_8, TYPE_USCALED, CFMT_8_8_8_8_USCALED},          // 69\n    {FMT_8_8_8_8, TYPE_SSCALED, CFMT_8_8_8_8_SSCALED}           // 70\n};\nstatic const int FormatLUTSize = sizeof(FormatLUT)/sizeof(formatconverstion_t);\n\n//Index in FormatLUT to start search, indexed by FMT enum.\nstatic const int FormatEntryPoint[] = {\n  71, // FMT_INVALID\n  48, // FMT_8\n  5,  // FMT_16\n  57, // FMT_8_8\n  34, // FMT_32\n  12, // FMT_16_16\n  71, // FMT_10_11_11\n  71, // FMT_11_11_10\n  1,  // FMT_10_10_10_2\n  26, // FMT_2_10_10_10\n  64, // FMT_8_8_8_8\n  37, // FMT_32_32\n  19, // FMT_16_16_16_16\n  40, // FMT_32_32_32\n  43, // FMT_32_32_32_32\n  71, // RESERVED\n  47, // FMT_5_6_5\n  0,  // FMT_1_5_5_5\n  46, // FMT_5_5_5_1\n  71, // FMT_4_4_4_4\n  55, // FMT_8_24\n  32  // FMT_24_8\n};\n\nstatic FORMAT GetCombinedFormat(uint8_t fmt, uint8_t type) {\n  assert(fmt < sizeof(FormatEntryPoint)/sizeof(int) && \"FMT out of range.\");\n  int start = FormatEntryPoint[fmt];\n  int stop = std::min(start + 6, FormatLUTSize); // Only 6 types are used in image_kv_lut.cpp\n\n  for(int i=start; i<stop; i++) {\n    if((FormatLUT[i].fmt == fmt) && (FormatLUT[i].type == type))\n      return FormatLUT[i].format;\n  }\n  return CFMT_INVALID;\n};\n//-----------------------------------------------------------------------------\n// End workaround\n//-----------------------------------------------------------------------------\n\nImageManagerGfx11::ImageManagerGfx11() : ImageManagerKv() {}\n\nImageManagerGfx11::~ImageManagerGfx11() {}\n\n// TODO(cfreehil) remove from class, make it a utility function\nhsa_status_t ImageManagerGfx11::CalculateImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) const {\n  ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n  hsa_profile_t profile;\n\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  Image::TileMode tileMode = Image::TileMode::LINEAR;\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE) {\n    tileMode = (profile == HSA_PROFILE_BASE &&\n                desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)?\n      Image::TileMode::TILED : Image::TileMode::LINEAR;\n  }\n  if (GetAddrlibSurfaceInfoNv(component, desc, tileMode,\n        image_data_row_pitch, image_data_slice_pitch, out) ==\n                                                             (uint32_t)(-1)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  size_t rowPitch   = (out.bpp >> 3) * out.pitch;\n  size_t slicePitch = rowPitch * out.height;\n  if (desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n      image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR &&\n      ((image_data_row_pitch && (rowPitch != image_data_row_pitch)) ||\n       (image_data_slice_pitch && (slicePitch != image_data_slice_pitch)))) {\n    return static_cast<hsa_status_t>(\n                                HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED);\n  }\n\n  image_info.size = out.surfSize;\n  assert(image_info.size != 0);\n  image_info.alignment = out.baseAlign;\n  assert(image_info.alignment != 0);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool ImageManagerGfx11::IsLocalMemory(const void* address) const {\n  return true;\n}\n\nhsa_status_t ImageManagerGfx11::PopulateImageSrd(Image& image,\n                                     const metadata_amd_t* descriptor) const {\n  const metadata_amd_gfx11_t* desc = reinterpret_cast<const metadata_amd_gfx11_t*>(descriptor);\n  const void* image_data_addr = image.data;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  if ((image_prop.cap == HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED) ||\n     (image_prop.element_size == 0))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n\n  if (IsLocalMemory(image.data)) {\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  image.srd[0] = desc->word0.u32All;\n  image.srd[1] = desc->word1.u32All;\n  image.srd[2] = desc->word2.u32All;\n  image.srd[3] = desc->word3.u32All;\n  image.srd[4] = desc->word4.u32All;\n  image.srd[5] = desc->word5.u32All;\n  image.srd[6] = desc->word6.u32All;\n  image.srd[7] = desc->word7.u32All;\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = image.srd[1];\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n\n    word3.val = image.srd[3];\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[3] = word3.val;\n  } else {\n    uint32_t hwPixelSize = ImageLut().GetPixelSize(image_prop.data_format, image_prop.data_type);\n\n    if (image_prop.element_size != hwPixelSize) {\n      return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n    }\n    reinterpret_cast<SQ_IMG_RSRC_WORD0*>(&image.srd[0])->bits.BASE_ADDRESS =\n        PtrLow40Shift8(image_data_addr);\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.BASE_ADDRESS_HI =\n        PtrHigh64Shift40(image_data_addr);\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_X =\n                                                                    swizzle.x;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Y =\n                                                                    swizzle.y;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Z =\n                                                                    swizzle.z;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_W =\n                                                                    swizzle.w;\n    if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n        image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1D) {\n      reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.TYPE =\n          ImageLut().MapGeometry(image.desc.geometry);\n    }\n    \n    // Imported metadata holds the offset to metadata, add the image base address.\n    uintptr_t meta = uintptr_t(((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS_HI) << 16;\n    meta |= uintptr_t(((SQ_IMG_RSRC_WORD6*)(&image.srd[6]))->bits.META_DATA_ADDRESS) << 8;\n    meta += reinterpret_cast<uintptr_t>(image_data_addr);\n\n    ((SQ_IMG_RSRC_WORD6*)(&image.srd[6]))->bits.META_DATA_ADDRESS = PtrLow16Shift8((void*)meta);\n    ((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS_HI =\n        PtrHigh64Shift16((void*)meta);\n  }\n  // Looks like this is only used for CPU copies.\n  image.row_pitch = 0;\n  image.slice_pitch = 0;\n\n  // Used by HSAIL shader ABI\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic TEX_BC_SWIZZLE GetBcSwizzle(const Swizzle& swizzle) {\n    SEL r = (SEL)swizzle.x;\n    SEL g = (SEL)swizzle.y;\n    SEL b = (SEL)swizzle.z;\n    SEL a = (SEL)swizzle.w;\n\n    TEX_BC_SWIZZLE bcSwizzle = TEX_BC_Swizzle_XYZW;\n\n    if (a == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_WZYX or TEX_BC_Swizzle_WXYZ\n        //\n        // For the pre-defined border color values (white, opaque black,\n        // transparent black), the only thing that matters is that the alpha\n        // channel winds up in the correct place (because the RGB channels are\n        // all the same) so either of these TEX_BC_Swizzle enumerations will\n        // work.  Not sure what happens with border color palettes.\n        if (b == SEL_Y) {\n            // ABGR\n            bcSwizzle = TEX_BC_Swizzle_WZYX;\n        } else if ((r == SEL_X) && (g == SEL_X) && (b == SEL_X)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // ARGB\n            bcSwizzle = TEX_BC_Swizzle_WXYZ;\n        }\n    } else if (r == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_XYZW or TEX_BC_Swizzle_XWYZ\n        if (g == SEL_Y) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else if ((g == SEL_X) && (b == SEL_X) && (a == SEL_W)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // RAGB\n            bcSwizzle = TEX_BC_Swizzle_XWYZ;\n        }\n    } else if (g == SEL_X) {\n        // GRAB, have to use TEX_BC_Swizzle_YXWZ\n        bcSwizzle = TEX_BC_Swizzle_YXWZ;\n    } else if (b == SEL_X) {\n        // BGRA, have to use TEX_BC_Swizzle_ZYXW\n        bcSwizzle = TEX_BC_Swizzle_ZYXW;\n    }\n\n    return bcSwizzle;\n}\n\n\nhsa_status_t ImageManagerGfx11::PopulateImageSrd(Image& image) const {\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  const void* image_data_addr = image.data;\n\n  if (IsLocalMemory(image.data))\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD2 word2;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n    word1.f.SWIZZLE_ENABLE = 0;\n\n    word2.f.NUM_RECORDS = image.desc.width * image_prop.element_size;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n\n    image.row_pitch = image.desc.width * image_prop.element_size;\n    image.slice_pitch = image.row_pitch;\n  } else {\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD5 word6;\n    SQ_IMG_RSRC_WORD5 word7;\n\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n\n    uint32_t swizzleMode = GetAddrlibSurfaceInfoNv(\n         image.component, image.desc, image.tile_mode,\n                                     image.row_pitch, image.slice_pitch, out);\n    if (swizzleMode == (uint32_t)(-1)) {\n      return HSA_STATUS_ERROR;\n    }\n\n    assert((out.bpp / 8) == image_prop.element_size);\n\n    const size_t row_pitch_size = out.pitch * image_prop.element_size;\n\n    word0.f.BASE_ADDRESS = PtrLow40Shift8(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh64Shift40(image_data_addr);\n    word1.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    // Only take the lowest 2 bits of (image.desc.width - 1)\n    word1.f.WIDTH = BitSelect<0, 1>(image.desc.width - 1);\n\n    word2.val = 0;\n    // Take the high 12 bits of (image.desc.width - 1)\n    word2.f.WIDTH_HI = BitSelect<2, 13>(image.desc.width - 1);\n    word2.f.HEIGHT = image.desc.height ? image.desc.height - 1 : 0;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    word3.f.SW_MODE = swizzleMode;\n    word3.f.BC_SWIZZLE = GetBcSwizzle(swizzle);\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    const bool image_array =\n        (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH);\n    const bool image_3d = (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_3D);\n\n    word4.val = 0;\n    word4.f.DEPTH =\n        (image_array) // Doesn't hurt but isn't array_size already >0?\n            ? std::max(image.desc.array_size, static_cast<size_t>(1)) - 1\n            : (image_3d) ? image.desc.depth - 1 : 0;\n\n    // For 1d, 2d and 2d-msaa in gfx11 this is pitch-1\n    if (!image_array && !image_3d) word4.f.PITCH = out.pitch - 1;\n\n    word5.val = 0;\n    word6.val = 0;\n    word7.val = 0;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n    image.srd[4] = word4.val;\n    image.srd[5] = word5.val;\n    image.srd[6] = word6.val;\n    image.srd[7] = word7.val;\n\n    image.row_pitch = row_pitch_size;\n    image.slice_pitch = out.sliceSize;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerGfx11::ModifyImageSrd(\n    Image& image, hsa_ext_image_format_t& new_format) const {\n  image.desc.format = new_format;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_BUF_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n    word3->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n  } else {\n    SQ_IMG_RSRC_WORD1* word1 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1]);\n    word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_IMG_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerGfx11::PopulateSamplerSrd(Sampler& sampler) const {\n  const hsa_ext_sampler_descriptor_v2_t &sampler_descriptor = sampler.desc;\n\n  SQ_IMG_SAMP_WORD0 word0;\n  SQ_IMG_SAMP_WORD1 word1;\n  SQ_IMG_SAMP_WORD2 word2;\n  SQ_IMG_SAMP_WORD3 word3;\n\n  word0.u32All = 0;\n  hsa_status_t status = convertAddressMode<SQ_IMG_SAMP_WORD0, SQ_TEX_CLAMP>\n                                       (word0, sampler_descriptor.address_modes);\n  if (status != HSA_STATUS_SUCCESS) return status;\n  word0.bits.FORCE_UNNORMALIZED = (sampler_descriptor.coordinate_mode ==\n                                  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED);\n\n  word1.u32All = 0;\n  word1.bits.MAX_LOD = 4095;\n\n  word2.u32All = 0;\n  switch (sampler_descriptor.filter_mode) {\n    case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_POINT);\n      break;\n    case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_BILINEAR);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER;\n  word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE;\n  word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE;\n\n  word3.u32All = 0;\n\n  // TODO: check this bit with HSAIL spec.\n  word3.bits.BORDER_COLOR_TYPE = SQ_TEX_BORDER_COLOR_TRANS_BLACK;\n\n  sampler.srd[0] = word0.u32All;\n  sampler.srd[1] = word1.u32All;\n  sampler.srd[2] = word2.u32All;\n  sampler.srd[3] = word3.u32All;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nuint32_t ImageManagerGfx11::GetAddrlibSurfaceInfoNv(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    Image::TileMode tileMode,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const {\n  const ImageProperty image_prop =\n      GetImageProperty(component, desc.format, desc.geometry);\n\n  const AddrFormat addrlib_format = GetAddrlibFormat(image_prop);\n\n  const uint32_t width = static_cast<uint32_t>(desc.width);\n  const uint32_t height = static_cast<uint32_t>(desc.height);\n  static const size_t kMinNumSlice = 1;\n  const uint32_t num_slice = static_cast<uint32_t>(\n      std::max(kMinNumSlice, std::max(desc.array_size, desc.depth)));\n\n  ADDR2_COMPUTE_SURFACE_INFO_INPUT in = {0};\n  in.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);\n  in.format = addrlib_format;\n  in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n  in.width = width;\n  in.height = height;\n  in.numSlices = num_slice;\n  in.pitchInElement = image_data_row_pitch / image_prop.element_size;\n\n  switch (desc.geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      in.resourceType = ADDR_RSRC_TEX_1D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      in.resourceType = ADDR_RSRC_TEX_2D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n      {\n\t      in.resourceType = ADDR_RSRC_TEX_3D;\n\t      /*\n\t       * 3D swizzle modes enforce alignment\n\t       * of the number of slices  to the block depth.\n\t       * If numSlices = 3 then the 3 slices are\n\t       * interleaved for 3D locality among the 8 slices\n\t       * that make up each block. This causes the memory\n\t       * footprint to jump to a 3x size of the ideal size\n\t       *\n\t       * 'enable3DSwizzleMode' flag tests for env variable\n\t       * HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG to enable or disable\n\t       * 3D swizzle:\n\t       * true: Keep view3dAs2dArray = 0 for real 3D interleaving.\n\t       * false: Use view3dAs2dArray = 1 to avoid the alignment\n\t       *       expansion.\n\t       * 2D swizzle modes can lower size overhead but may yield\n\t       * suboptimal cache behavior for fully 3D volumetric\n\t       * operations.\n\t       */\n\t      bool enable3DSwizzleMode = core::Runtime::runtime_singleton_->flag().enable_3d_swizzle();\n\t      if (enable3DSwizzleMode)\n\t\t      in.flags.view3dAs2dArray = 0;\n\t      else\n\t\t      in.flags.view3dAs2dArray = 1;\n\n\t      break;\n      }\n  }\n  in.flags.texture = 1;\n\n  ADDR2_GET_PREFERRED_SURF_SETTING_INPUT  prefSettingsInput = { 0 };\n  ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT prefSettingsOutput = { 0 };\n\n  prefSettingsInput.size            = sizeof(prefSettingsInput);\n  prefSettingsInput.flags           = in.flags;\n  prefSettingsInput.bpp             = in.bpp;\n  prefSettingsInput.format          = in.format;\n  prefSettingsInput.width           = in.width;\n  prefSettingsInput.height          = in.height;\n  prefSettingsInput.numFrags        = in.numFrags;\n  prefSettingsInput.numSamples      = in.numSamples;\n  prefSettingsInput.numMipLevels    = in.numMipLevels;\n  prefSettingsInput.numSlices       = in.numSlices;\n  prefSettingsInput.resourceLoction = ADDR_RSRC_LOC_UNDEF;\n  prefSettingsInput.resourceType    = in.resourceType;\n\n  // Disallow all swizzles but linear.\n  if (tileMode == Image::TileMode::LINEAR) {\n      prefSettingsInput.forbiddenBlock.macroThin4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThin64KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick64KB = 1;\n      prefSettingsInput.forbiddenBlock.micro = 1;\n      prefSettingsInput.forbiddenBlock.var = 1;\n  }\n\n  // but don't ever allow the 256b swizzle modes\n  //prefSettingsInput.forbiddenBlock.micro = 1;\n  // and don't allow variable-size block modes\n  //prefSettingsInput.forbiddenBlock.var = 1;\n\n  if (ADDR_OK != Addr2GetPreferredSurfaceSetting(addr_lib_,\n                                   &prefSettingsInput, &prefSettingsOutput)) {\n    return (uint32_t)(-1);\n  }\n\n  in.swizzleMode = prefSettingsOutput.swizzleMode;\n\n  out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);\n  if (ADDR_OK != Addr2ComputeSurfaceInfo(addr_lib_, &in, &out)) {\n    return (uint32_t)(-1);\n  }\n  if (out.surfSize == 0) {\n    return (uint32_t)(-1);\n  }\n\n  return in.swizzleMode;\n}\n\nhsa_status_t ImageManagerGfx11::FillImage(const Image& image, const void* pattern,\n                                       const hsa_ext_image_region_t& region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  Image* image_view = const_cast<Image*>(&image);\n\n  SQ_BUF_RSRC_WORD3* word3_buff = NULL;\n  SQ_IMG_RSRC_WORD3* word3_image = NULL;\n  uint32_t dst_sel_w_original = 0;\n  if (image_view->desc.format.channel_type ==\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010) {\n    // Force GPU to ignore the last two bits (alpha bits).\n    if (image_view->desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      word3_buff = reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_buff->bits.DST_SEL_W;\n      word3_buff->bits.DST_SEL_W = SEL_0;\n    } else {\n      word3_image = reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_image->bits.DST_SEL_W;\n      word3_image->bits.DST_SEL_W = SEL_0;\n    }\n  }\n\n  SQ_IMG_RSRC_WORD1* word1 = NULL;\n  uint32_t num_format_original = 0;\n  const void* new_pattern = pattern;\n  float fill_value[4] = {0};\n  switch (image_view->desc.format.channel_order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA: {\n      // We do not have write support for SRGBA image, so convert pattern\n      // to standard form and treat the image as RGBA image.\n      const float* pattern_f = reinterpret_cast<const float*>(pattern);\n      fill_value[0] = LinearToStandardRGB(pattern_f[0]);\n      fill_value[1] = LinearToStandardRGB(pattern_f[1]);\n      fill_value[2] = LinearToStandardRGB(pattern_f[2]);\n      fill_value[3] = pattern_f[3];\n      new_pattern = fill_value;\n\n      ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n\n      word1 = reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image_view->srd[1]);\n      num_format_original = word1->bits.FORMAT;\n      word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, TYPE_UNORM);\n    } break;\n    default:\n      break;\n  }\n\n  hsa_status_t status = ImageRuntime::instance()->blit_kernel().FillImage(\n      blit_queue_, blit_code_catalog_, *image_view, new_pattern, region);\n\n  // Revert back original configuration.\n  if (word3_buff != NULL) {\n    word3_buff->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word3_image != NULL) {\n    word3_image->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word1 != NULL) {\n    word1->bits.FORMAT = num_format_original;\n  }\n\n  return status;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_gfx11.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2021, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_IMAGE_MANAGER_GFX11_H_\n#define EXT_IMAGE_IMAGE_MANAGER_GFX11_H_\n\n#include \"addrlib/inc/addrinterface.h\"\n#include \"image_lut_gfx11.h\"\n#include \"image_manager_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageManagerGfx11 : public ImageManagerKv {\n public:\n  ImageManagerGfx11();\n  virtual ~ImageManagerGfx11();\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch, size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(Image& image,\n                                      hsa_ext_image_format_t& new_format) const;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const;\n\n  /// @brief Fill image backing storage using agent copy.\n  virtual hsa_status_t FillImage(const Image& image, const void* pattern,\n                                 const hsa_ext_image_region_t& region);\n protected:\n  uint32_t GetAddrlibSurfaceInfoNv(hsa_agent_t component,\n                             const hsa_ext_image_descriptor_t& desc,\n                             Image::TileMode tileMode,\n                             size_t image_data_row_pitch,\n                             size_t image_data_slice_pitch,\n                             ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const;\n\n  bool IsLocalMemory(const void* address) const;\n  virtual const ImageLutGfx11& ImageLut() const { return image_lut_gfx11; };\n\n private:\n  ImageLutGfx11 image_lut_gfx11;\n  DISALLOW_COPY_AND_ASSIGN(ImageManagerGfx11);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_IMAGE_MANAGER_GFX11_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_gfx12.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_manager_gfx12.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n\n#include \"core/inc/runtime.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"core/util/utils.h\"\n#include \"addrlib/src/core/addrlib.h\"\n#include \"image_runtime.h\"\n#include \"resource.h\"\n#include \"resource_gfx12.h\"\n#include \"util.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nstatic_assert(sizeof(SQ_BUF_RSRC_WORD0) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_BUF_RSRC_WORD1) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_BUF_RSRC_WORD2) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_BUF_RSRC_WORD3) == sizeof(uint32_t), \"struct size is invalid\");\n\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD0) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD1) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD2) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD3) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD4) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD5) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD6) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_RSRC_WORD7) == sizeof(uint32_t), \"struct size is invalid\");\n\nstatic_assert(sizeof(SQ_IMG_SAMP_WORD0) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_SAMP_WORD1) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_SAMP_WORD2) == sizeof(uint32_t), \"struct size is invalid\");\nstatic_assert(sizeof(SQ_IMG_SAMP_WORD3) == sizeof(uint32_t), \"struct size is invalid\");\n\n//-----------------------------------------------------------------------------\n// Workaround switch to combined format/type codes and missing gfx11\n// specific look up table.  Only covers types used in image_lut_gfx11.cpp.\n//-----------------------------------------------------------------------------\nstruct formatconverstion_t {\n  FMT fmt;\n  type type;\n  FORMAT format;\n};\n\n// Format/Type to combined format code table.\n// Sorted and indexed to allow fast searches.\nstatic const formatconverstion_t FormatLUT[] = {\n    {FMT_1_5_5_5, TYPE_UNORM, CFMT_1_5_5_5_UNORM},              // 0\n    {FMT_10_10_10_2, TYPE_UNORM, CFMT_10_10_10_2_UNORM},        // 1\n    {FMT_10_10_10_2, TYPE_SNORM, CFMT_10_10_10_2_SNORM},        // 2\n    {FMT_10_10_10_2, TYPE_UINT, CFMT_10_10_10_2_UINT},          // 3\n    {FMT_10_10_10_2, TYPE_SINT, CFMT_10_10_10_2_SINT},          // 4\n    {FMT_16, TYPE_UNORM, CFMT_16_UNORM},                        // 5\n    {FMT_16, TYPE_SNORM, CFMT_16_SNORM},                        // 6\n    {FMT_16, TYPE_UINT, CFMT_16_UINT},                          // 7\n    {FMT_16, TYPE_SINT, CFMT_16_SINT},                          // 8\n    {FMT_16, TYPE_FLOAT, CFMT_16_FLOAT},                        // 9\n    {FMT_16, TYPE_USCALED, CFMT_16_USCALED},                    // 10\n    {FMT_16, TYPE_SSCALED, CFMT_16_SSCALED},                    // 11\n    {FMT_16_16, TYPE_UNORM, CFMT_16_16_UNORM},                  // 12\n    {FMT_16_16, TYPE_SNORM, CFMT_16_16_SNORM},                  // 13\n    {FMT_16_16, TYPE_UINT, CFMT_16_16_UINT},                    // 14\n    {FMT_16_16, TYPE_SINT, CFMT_16_16_SINT},                    // 15\n    {FMT_16_16, TYPE_FLOAT, CFMT_16_16_FLOAT},                  // 16\n    {FMT_16_16, TYPE_USCALED, CFMT_16_16_USCALED},              // 17\n    {FMT_16_16, TYPE_SSCALED, CFMT_16_16_SSCALED},              // 18\n    {FMT_16_16_16_16, TYPE_UNORM, CFMT_16_16_16_16_UNORM},      // 19\n    {FMT_16_16_16_16, TYPE_SNORM, CFMT_16_16_16_16_SNORM},      // 20\n    {FMT_16_16_16_16, TYPE_UINT, CFMT_16_16_16_16_UINT},        // 21\n    {FMT_16_16_16_16, TYPE_SINT, CFMT_16_16_16_16_SINT},        // 22\n    {FMT_16_16_16_16, TYPE_FLOAT, CFMT_16_16_16_16_FLOAT},      // 23\n    {FMT_16_16_16_16, TYPE_USCALED, CFMT_16_16_16_16_USCALED},  // 24\n    {FMT_16_16_16_16, TYPE_SSCALED, CFMT_16_16_16_16_SSCALED},  // 25\n    {FMT_2_10_10_10, TYPE_UNORM, CFMT_2_10_10_10_UNORM},        // 26\n    {FMT_2_10_10_10, TYPE_SNORM, CFMT_2_10_10_10_SNORM},        // 27\n    {FMT_2_10_10_10, TYPE_UINT, CFMT_2_10_10_10_UINT},          // 28\n    {FMT_2_10_10_10, TYPE_SINT, CFMT_2_10_10_10_SINT},          // 29\n    {FMT_2_10_10_10, TYPE_USCALED, CFMT_2_10_10_10_USCALED},    // 30\n    {FMT_2_10_10_10, TYPE_SSCALED, CFMT_2_10_10_10_SSCALED},    // 31\n    {FMT_24_8, TYPE_UNORM, CFMT_24_8_UNORM},                    // 32\n    {FMT_24_8, TYPE_UINT, CFMT_24_8_UINT},                      // 33\n    {FMT_32, TYPE_UINT, CFMT_32_UINT},                          // 34\n    {FMT_32, TYPE_SINT, CFMT_32_SINT},                          // 35\n    {FMT_32, TYPE_FLOAT, CFMT_32_FLOAT},                        // 36\n    {FMT_32_32, TYPE_UINT, CFMT_32_32_UINT},                    // 37\n    {FMT_32_32, TYPE_SINT, CFMT_32_32_SINT},                    // 38\n    {FMT_32_32, TYPE_FLOAT, CFMT_32_32_FLOAT},                  // 39\n    {FMT_32_32_32, TYPE_UINT, CFMT_32_32_32_UINT},              // 40\n    {FMT_32_32_32, TYPE_SINT, CFMT_32_32_32_SINT},              // 41\n    {FMT_32_32_32, TYPE_FLOAT, CFMT_32_32_32_FLOAT},            // 42\n    {FMT_32_32_32_32, TYPE_UINT, CFMT_32_32_32_32_UINT},        // 43\n    {FMT_32_32_32_32, TYPE_SINT, CFMT_32_32_32_32_SINT},        // 44\n    {FMT_32_32_32_32, TYPE_FLOAT, CFMT_32_32_32_32_FLOAT},      // 45\n    {FMT_5_5_5_1, TYPE_UNORM, CFMT_5_5_5_1_UNORM},              // 46\n    {FMT_5_6_5, TYPE_UNORM, CFMT_5_6_5_UNORM},                  // 47\n    {FMT_8, TYPE_UNORM, CFMT_8_UNORM},                          // 48\n    {FMT_8, TYPE_SNORM, CFMT_8_SNORM},                          // 49\n    {FMT_8, TYPE_UINT, CFMT_8_UINT},                            // 50\n    {FMT_8, TYPE_SINT, CFMT_8_SINT},                            // 51\n    {FMT_8, TYPE_SRGB, CFMT_8_SRGB},                            // 52\n    {FMT_8, TYPE_USCALED, CFMT_8_USCALED},                      // 53\n    {FMT_8, TYPE_SSCALED, CFMT_8_SSCALED},                      // 54\n    {FMT_8_24, TYPE_UNORM, CFMT_8_24_UNORM},                    // 55\n    {FMT_8_24, TYPE_UINT, CFMT_8_24_UINT},                      // 56\n    {FMT_8_8, TYPE_UNORM, CFMT_8_8_UNORM},                      // 57\n    {FMT_8_8, TYPE_SNORM, CFMT_8_8_SNORM},                      // 58\n    {FMT_8_8, TYPE_UINT, CFMT_8_8_UINT},                        // 59\n    {FMT_8_8, TYPE_SINT, CFMT_8_8_SINT},                        // 60\n    {FMT_8_8, TYPE_SRGB, CFMT_8_8_SRGB},                        // 61\n    {FMT_8_8, TYPE_USCALED, CFMT_8_8_USCALED},                  // 62\n    {FMT_8_8, TYPE_SSCALED, CFMT_8_8_SSCALED},                  // 63\n    {FMT_8_8_8_8, TYPE_UNORM, CFMT_8_8_8_8_UNORM},              // 64\n    {FMT_8_8_8_8, TYPE_SNORM, CFMT_8_8_8_8_SNORM},              // 65\n    {FMT_8_8_8_8, TYPE_UINT, CFMT_8_8_8_8_UINT},                // 66\n    {FMT_8_8_8_8, TYPE_SINT, CFMT_8_8_8_8_SINT},                // 67\n    {FMT_8_8_8_8, TYPE_SRGB, CFMT_8_8_8_8_SRGB},                // 68\n    {FMT_8_8_8_8, TYPE_USCALED, CFMT_8_8_8_8_USCALED},          // 69\n    {FMT_8_8_8_8, TYPE_SSCALED, CFMT_8_8_8_8_SSCALED}           // 70\n};\nstatic const int FormatLUTSize = sizeof(FormatLUT)/sizeof(formatconverstion_t);\n\n//Index in FormatLUT to start search, indexed by FMT enum.\nstatic const int FormatEntryPoint[] = {\n  71, // FMT_INVALID\n  48, // FMT_8\n  5,  // FMT_16\n  57, // FMT_8_8\n  34, // FMT_32\n  12, // FMT_16_16\n  71, // FMT_10_11_11\n  71, // FMT_11_11_10\n  1,  // FMT_10_10_10_2\n  26, // FMT_2_10_10_10\n  64, // FMT_8_8_8_8\n  37, // FMT_32_32\n  19, // FMT_16_16_16_16\n  40, // FMT_32_32_32\n  43, // FMT_32_32_32_32\n  71, // RESERVED\n  47, // FMT_5_6_5\n  0,  // FMT_1_5_5_5\n  46, // FMT_5_5_5_1\n  71, // FMT_4_4_4_4\n  55, // FMT_8_24\n  32  // FMT_24_8\n};\n\nstatic FORMAT GetCombinedFormat(uint8_t fmt, uint8_t type) {\n  assert(fmt < sizeof(FormatEntryPoint)/sizeof(int) && \"FMT out of range.\");\n  int start = FormatEntryPoint[fmt];\n  int stop = std::min(start + 6, FormatLUTSize); // Only 6 types are used in image_kv_lut.cpp\n\n  for(int i=start; i<stop; i++) {\n    if((FormatLUT[i].fmt == fmt) && (FormatLUT[i].type == type))\n      return FormatLUT[i].format;\n  }\n  return CFMT_INVALID;\n};\n//-----------------------------------------------------------------------------\n// End workaround\n//-----------------------------------------------------------------------------\n\nImageManagerGfx12::ImageManagerGfx12() : ImageManagerKv() {}\n\nImageManagerGfx12::~ImageManagerGfx12() {}\n\n// TODO(cfreehil) remove from class, make it a utility function\nhsa_status_t ImageManagerGfx12::CalculateImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) const {\n  ADDR3_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n  hsa_profile_t profile;\n\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  Image::TileMode tileMode = Image::TileMode::LINEAR;\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE) {\n    tileMode = (profile == HSA_PROFILE_BASE &&\n                desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)?\n      Image::TileMode::TILED : Image::TileMode::LINEAR;\n  }\n  if (GetAddrlibSurfaceInfoNv(component, desc, tileMode,\n        image_data_row_pitch, image_data_slice_pitch, out) ==\n                                                             (uint32_t)(-1)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  size_t rowPitch   = (out.bpp >> 3) * out.pitch;\n  size_t slicePitch = rowPitch * out.height;\n  if (desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n      image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR &&\n      ((image_data_row_pitch && (rowPitch != image_data_row_pitch)) ||\n       (image_data_slice_pitch && (slicePitch != image_data_slice_pitch)))) {\n    return static_cast<hsa_status_t>(\n                                HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED);\n  }\n\n  image_info.size = out.surfSize;\n  assert(image_info.size != 0);\n  image_info.alignment = out.baseAlign;\n  assert(image_info.alignment != 0);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool ImageManagerGfx12::IsLocalMemory(const void* address) const {\n  return true;\n}\n\nhsa_status_t ImageManagerGfx12::PopulateImageSrd(Image& image,\n                                     const metadata_amd_t* descriptor) const {\n  const metadata_amd_gfx12_t* desc = reinterpret_cast<const metadata_amd_gfx12_t*>(descriptor);\n  const void* image_data_addr = image.data;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  if ((image_prop.cap == HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED) ||\n     (image_prop.element_size == 0))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n\n  if (IsLocalMemory(image.data)) {\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  image.srd[0] = desc->word0.u32All;\n  image.srd[1] = desc->word1.u32All;\n  image.srd[2] = desc->word2.u32All;\n  image.srd[3] = desc->word3.u32All;\n  image.srd[4] = desc->word4.u32All;\n  image.srd[5] = desc->word5.u32All;\n  image.srd[6] = desc->word6.u32All;\n  image.srd[7] = desc->word7.u32All;\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = image.srd[1];\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n\n    word3.val = image.srd[3];\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n\n    // New to GFX12\n    //word3.f.WRITE_COMPRESS_ENABLE = 0;\n    //word3.f.COMPRESSION_EN = 0;\n    //word3.f.COMPRESSION_ACCESS_MODE = 0;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[3] = word3.val;\n  } else {\n    uint32_t hwPixelSize = ImageLut().GetPixelSize(image_prop.data_format, image_prop.data_type);\n\n    if (image_prop.element_size != hwPixelSize) {\n      return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n    }\n    reinterpret_cast<SQ_IMG_RSRC_WORD0*>(&image.srd[0])->bits.BASE_ADDRESS =\n        PtrLow40Shift8(image_data_addr);\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.BASE_ADDRESS_HI =\n        PtrHigh64Shift40(image_data_addr);\n\n    // New to GFX12...\n    //reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.MAX_MIP = 0;\n\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_X =\n                                                                    swizzle.x;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Y =\n                                                                    swizzle.y;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Z =\n                                                                    swizzle.z;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_W =\n                                                                    swizzle.w;\n    if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n        image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1D) {\n      reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.TYPE =\n          ImageLut().MapGeometry(image.desc.geometry);\n    }\n  }\n\n  // Looks like this is only used for CPU copies.\n  image.row_pitch = 0;\n  image.slice_pitch = 0;\n\n  // Used by HSAIL shader ABI\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic TEX_BC_SWIZZLE GetBcSwizzle(const Swizzle& swizzle) {\n    SEL r = (SEL)swizzle.x;\n    SEL g = (SEL)swizzle.y;\n    SEL b = (SEL)swizzle.z;\n    SEL a = (SEL)swizzle.w;\n\n    TEX_BC_SWIZZLE bcSwizzle = TEX_BC_Swizzle_XYZW;\n\n    if (a == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_WZYX or TEX_BC_Swizzle_WXYZ\n        //\n        // For the pre-defined border color values (white, opaque black,\n        // transparent black), the only thing that matters is that the alpha\n        // channel winds up in the correct place (because the RGB channels are\n        // all the same) so either of these TEX_BC_Swizzle enumerations will\n        // work.  Not sure what happens with border color palettes.\n        if (b == SEL_Y) {\n            // ABGR\n            bcSwizzle = TEX_BC_Swizzle_WZYX;\n        } else if ((r == SEL_X) && (g == SEL_X) && (b == SEL_X)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // ARGB\n            bcSwizzle = TEX_BC_Swizzle_WXYZ;\n        }\n    } else if (r == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_XYZW or TEX_BC_Swizzle_XWYZ\n        if (g == SEL_Y) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else if ((g == SEL_X) && (b == SEL_X) && (a == SEL_W)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // RAGB\n            bcSwizzle = TEX_BC_Swizzle_XWYZ;\n        }\n    } else if (g == SEL_X) {\n        // GRAB, have to use TEX_BC_Swizzle_YXWZ\n        bcSwizzle = TEX_BC_Swizzle_YXWZ;\n    } else if (b == SEL_X) {\n        // BGRA, have to use TEX_BC_Swizzle_ZYXW\n        bcSwizzle = TEX_BC_Swizzle_ZYXW;\n    }\n\n    return bcSwizzle;\n}\n\n\nhsa_status_t ImageManagerGfx12::PopulateImageSrd(Image& image) const {\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  const void* image_data_addr = image.data;\n\n  if (IsLocalMemory(image.data))\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD2 word2;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n\n    word1.f.SWIZZLE_ENABLE = 0;\n\n    word2.f.NUM_RECORDS = image.desc.width * image_prop.element_size;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n\n    // New to GFX12\n    //word3.f.WRITE_COMPRESS_ENABLE = 0;\n    //word3.f.COMPRESSION_EN = 0;\n    //word3.f.COMPRESSION_ACCESS_MODE = 0;\n\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n\n    image.row_pitch = image.desc.width * image_prop.element_size;\n    image.slice_pitch = image.row_pitch;\n  } else {\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD5 word6;\n    SQ_IMG_RSRC_WORD5 word7;\n\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n\n    uint32_t swizzleMode = GetAddrlibSurfaceInfoNv(\n         image.component, image.desc, image.tile_mode,\n                                     image.row_pitch, image.slice_pitch, out);\n    if (swizzleMode == (uint32_t)(-1)) {\n      return HSA_STATUS_ERROR;\n    }\n\n    assert((out.bpp / 8) == image_prop.element_size);\n\n    const size_t row_pitch_size = out.pitch * image_prop.element_size;\n\n    word0.f.BASE_ADDRESS = PtrLow40Shift8(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh64Shift40(image_data_addr);\n\n    // New to GFX12\n    //word1.f.MAX_MIP = 0;\n    //word1.f.BASE_LEVEL = 0;\n\n    word1.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    // Only take the lowest 2 bits of (image.desc.width - 1)\n    word1.f.WIDTH = BitSelect<0, 1>(image.desc.width - 1);\n\n    word2.val = 0;\n    // Take the high 14 bits of (image.desc.width - 1)\n    word2.f.WIDTH_HI = BitSelect<2, 15>(image.desc.width - 1);\n    word2.f.HEIGHT = image.desc.height ? image.desc.height - 1 : 0;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    //word3.f.NO_EDGE_CLAMP = 0;  // New to GFX12\n    //word3.f.LAST_LEVEL = 0;     // New to GFX12\n    word3.f.SW_MODE = swizzleMode;\n    word3.f.BC_SWIZZLE = GetBcSwizzle(swizzle);\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    const bool image_array =\n        (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH);\n    const bool image_3d = (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_3D);\n\n    word4.val = 0;\n\n    // For 1d, 2d and 2d-msaa, fields DEPTH+PITCH_MSB encode pitch-1\n    if (!image_array && !image_3d) {\n      uint32_t encPitch = out.pitch - 1;\n      word4.f.DEPTH = encPitch & 0x3fff;           // first 14 bits\n      word4.f.PITCH_MSB = (encPitch >> 14) & 0x3;  // last 2 bits\n    } else {\n      word4.f.DEPTH =\n        (image_array) // Doesn't hurt but isn't array_size already >0?\n            ? std::max(image.desc.array_size, static_cast<size_t>(1)) - 1\n            : (image_3d) ? image.desc.depth - 1 : 0;\n    }\n\n    word5.val = 0;\n    word6.val = 0;\n    word7.val = 0;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n    image.srd[4] = word4.val;\n    image.srd[5] = word5.val;\n    image.srd[6] = word6.val;\n    image.srd[7] = word7.val;\n\n    image.row_pitch = row_pitch_size;\n    image.slice_pitch = out.sliceSize;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerGfx12::ModifyImageSrd(\n    Image& image, hsa_ext_image_format_t& new_format) const {\n  image.desc.format = new_format;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_BUF_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n    word3->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n  } else {\n    SQ_IMG_RSRC_WORD1* word1 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1]);\n    word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_IMG_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerGfx12::PopulateSamplerSrd(Sampler& sampler) const {\n  const hsa_ext_sampler_descriptor_v2_t &sampler_descriptor = sampler.desc;\n\n  SQ_IMG_SAMP_WORD0 word0;\n  SQ_IMG_SAMP_WORD1 word1;\n  SQ_IMG_SAMP_WORD2 word2;\n  SQ_IMG_SAMP_WORD3 word3;\n\n  word0.u32All = 0;\n  hsa_status_t status = convertAddressMode<SQ_IMG_SAMP_WORD0, SQ_TEX_CLAMP>\n                                       (word0, sampler_descriptor.address_modes);\n  if (status != HSA_STATUS_SUCCESS) return status;\n  word0.bits.FORCE_UNNORMALIZED = (sampler_descriptor.coordinate_mode ==\n                                  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED);\n\n  word1.u32All = 0;\n  word1.bits.MAX_LOD = 4095;\n\n  word2.u32All = 0;\n  switch (sampler_descriptor.filter_mode) {\n    case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_POINT);\n      break;\n    case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_BILINEAR);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER;\n  word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE;\n  word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE;\n\n  word3.u32All = 0;\n\n  // TODO: check this bit with HSAIL spec.\n  word3.bits.BORDER_COLOR_TYPE = SQ_TEX_BORDER_COLOR_TRANS_BLACK;\n\n  sampler.srd[0] = word0.u32All;\n  sampler.srd[1] = word1.u32All;\n  sampler.srd[2] = word2.u32All;\n  sampler.srd[3] = word3.u32All;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nuint32_t ImageManagerGfx12::GetAddrlibSurfaceInfoNv(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    Image::TileMode tileMode,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    ADDR3_COMPUTE_SURFACE_INFO_OUTPUT& out) const {\n  const ImageProperty image_prop =\n      GetImageProperty(component, desc.format, desc.geometry);\n\n  const AddrFormat addrlib_format = GetAddrlibFormat(image_prop);\n\n  const uint32_t width = static_cast<uint32_t>(desc.width);\n  const uint32_t height = static_cast<uint32_t>(desc.height);\n  static const size_t kMinNumSlice = 1;\n  const uint32_t num_slice = static_cast<uint32_t>(\n      std::max(kMinNumSlice, std::max(desc.array_size, desc.depth)));\n\n  ADDR3_COMPUTE_SURFACE_INFO_INPUT in = {0};\n  in.size = sizeof(ADDR3_COMPUTE_SURFACE_INFO_INPUT);\n  in.format = addrlib_format;\n  in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n  in.width = width;\n  in.height = height;\n  in.numSlices = num_slice;\n  in.pitchInElement = image_data_row_pitch / image_prop.element_size;\n\n  switch (desc.geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      in.resourceType = ADDR_RSRC_TEX_1D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      in.resourceType = ADDR_RSRC_TEX_2D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n      {\n\tin.resourceType = ADDR_RSRC_TEX_3D;\n\t/*\n\t * 3D swizzle modes on GFX12 enforces alignment\n\t * of the number of slices  to the block depth.\n\t * If numSlices = 3 then the 3 slices are\n\t * interleaved for 3D locality among the 8 slices\n\t * that make up each block. This causes the memory\n\t * footprint to jump from an ideal size of ~12 GB\n\t * to ~32 GB.\n\t * 'enable3DSwizzleMode' flag tests for env variable\n\t * HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG to enable or disable\n\t * 3D swizzle:\n\t * true: Keep view3dAs2dArray = 0 for real 3D interleaving.\n\t * false: Use view3dAs2dArray = 1 to avoid the alignment\n\t *       expansion.\n\t * 2D swizzle modes can lower size overhead but may yield\n\t * suboptimal cache behavior for fully 3D volumetric\n\t * operations.\n\t */\n\tbool enable3DSwizzleMode = core::Runtime::runtime_singleton_->flag().enable_3d_swizzle();\n\tif (enable3DSwizzleMode)\n\t{\n\t\tin.flags.view3dAs2dArray = 0;\n\t}\n\telse\n\t{\n\t\tin.flags.view3dAs2dArray = 1;\n\t}\n\tbreak;\n      }\n  }\n\n  in.flags.texture = 1;\n\n  if (tileMode == Image::TileMode::LINEAR)\n  {\n    in.swizzleMode = ADDR3_LINEAR;\n  } else {\n\n    /*\n     * AddrLib3 does not provide the best swizzle mode (unlike AddrLib2).\n     * Instead, client has to request the list of possible swizzle mode and\n     * then pick the best one for its needs (i.e. performance/space tradeoffs).\n     *\n     */\n    ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT swOut = { 0 };\n    swOut.size = sizeof(ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT);\n\n    ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT swIn = { 0 };\n    swIn.size = sizeof(ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT);\n    swIn.flags = in.flags;\n    swIn.resourceType = in.resourceType;\n    swIn.bpp = in.bpp;\n    swIn.width = in.width;\n    swIn.height = in.height;\n    swIn.numSlices = in.numSlices;\n    swIn.numMipLevels = in.numMipLevels;\n    swIn.numSamples = in.numSamples;\n    /*\n     * Cannot leave it to 0 like GFX11 Addr2GetPreferredSurfaceSetting method\n     * as it triggers an ASSERT in AddrLib3 code.\n     *\n     * Setting it to 256K to allow for maximum number of swizzle mode in set\n     * returned (similar behaviour as GFX11).\n     *\n     */\n    swIn.maxAlign = 256 * 1024;\n\n\n    if (ADDR_OK != Addr3GetPossibleSwizzleModes(addr_lib_, &swIn, &swOut)) {\n      debug_print(\"Addr3GetPossibleSwizzleModes failed!\\n\");\n      return (uint32_t) -1;\n    }\n\n    /*\n     * Remove any modes that the client does not want (if any).\n     */\n    //swOut.validModes.sw***** = 0;\n\n\n    /*\n     * Pick the \"best\" swizzle mode.\n     *\n     * This algorithm is based on behaviour in GFX11 AddrLib and on\n     * GFX12 code in PAL (that is also based on the GFX11 behaviour).\n     *\n     * Ratio variables control the extra space that can be used to get a larger\n     * swizzle mode.\n     *\n     * ratioLow:ratioHi meanings:\n     *\n     *   2:1 ratio - same behaviour as GFX11.\n     *   3:2 ratio - would be equivalent if flag opt4space in GFX11 (not used in ROCr)\n     *   1:1 ratio - minimum size, not necessary best for performance\n     *\n     */\n    const UINT_32 ratioLow = 2;\n    const UINT_32 ratioHigh = 1;\n\n    // Same behaviour as GFX11, remove linear if height is 1.\n    if (in.height > 1) {\n      swOut.validModes.swLinear = 0;\n    }\n\n    UINT_64 minSize = 0;\n    Addr3SwizzleMode bestSwizzle = ADDR3_MAX_TYPE;\n\n    for (uint32_t i = ADDR3_LINEAR; i < ADDR3_MAX_TYPE; i++) {\n\n      if (swOut.validModes.value & (1 << i)) {\n        ADDR3_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};\n        localOut.size = sizeof(ADDR3_COMPUTE_SURFACE_INFO_OUTPUT);\n\n        in.swizzleMode = (Addr3SwizzleMode) i;\n\n        if (ADDR_OK != Addr3ComputeSurfaceInfo(addr_lib_, &in, &localOut)) {\n          // Should not happen, if it does, ignore this swizzle mode.\n          debug_print(\"Addr3ComputeSurfaceInfo failed!\\n\");\n          continue;\n        }\n\n        UINT_64 surfaceSize = localOut.surfSize;\n\n        if (bestSwizzle == ADDR3_MAX_TYPE) {\n          minSize = surfaceSize;\n          bestSwizzle = (Addr3SwizzleMode) i;\n        } else if ((surfaceSize * ratioHigh) <= (minSize * ratioLow)) {\n          minSize = surfaceSize;\n          bestSwizzle = (Addr3SwizzleMode) i;\n        }\n      }\n    }\n\n    if (bestSwizzle < ADDR3_MAX_TYPE) {\n      in.swizzleMode = (Addr3SwizzleMode) bestSwizzle;\n    } else {\n      debug_print(\"Unable to find a valid swizzleMode for the surface!\\n\");\n      return (uint32_t) -1;\n    }\n  }\n\n\n  out.size = sizeof(ADDR3_COMPUTE_SURFACE_INFO_OUTPUT);\n\n  if (ADDR_OK != Addr3ComputeSurfaceInfo(addr_lib_, &in, &out)) {\n    return (uint32_t)(-1);\n  }\n  if (out.surfSize == 0) {\n    return (uint32_t)(-1);\n  }\n\n  return in.swizzleMode;\n}\n\nhsa_status_t ImageManagerGfx12::FillImage(const Image& image, const void* pattern,\n                                       const hsa_ext_image_region_t& region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  Image* image_view = const_cast<Image*>(&image);\n\n  SQ_BUF_RSRC_WORD3* word3_buff = NULL;\n  SQ_IMG_RSRC_WORD3* word3_image = NULL;\n  uint32_t dst_sel_w_original = 0;\n  if (image_view->desc.format.channel_type ==\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010) {\n    // Force GPU to ignore the last two bits (alpha bits).\n    if (image_view->desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      word3_buff = reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_buff->bits.DST_SEL_W;\n      word3_buff->bits.DST_SEL_W = SEL_0;\n    } else {\n      word3_image = reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_image->bits.DST_SEL_W;\n      word3_image->bits.DST_SEL_W = SEL_0;\n    }\n  }\n\n  SQ_IMG_RSRC_WORD1* word1 = NULL;\n  uint32_t num_format_original = 0;\n  const void* new_pattern = pattern;\n  float fill_value[4] = {0};\n  switch (image_view->desc.format.channel_order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA: {\n      // We do not have write support for SRGBA image, so convert pattern\n      // to standard form and treat the image as RGBA image.\n      const float* pattern_f = reinterpret_cast<const float*>(pattern);\n      fill_value[0] = LinearToStandardRGB(pattern_f[0]);\n      fill_value[1] = LinearToStandardRGB(pattern_f[1]);\n      fill_value[2] = LinearToStandardRGB(pattern_f[2]);\n      fill_value[3] = pattern_f[3];\n      new_pattern = fill_value;\n\n      ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n\n      word1 = reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image_view->srd[1]);\n      num_format_original = word1->bits.FORMAT;\n      word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, TYPE_UNORM);\n    } break;\n    default:\n      break;\n  }\n\n  hsa_status_t status = ImageRuntime::instance()->blit_kernel().FillImage(\n      blit_queue_, blit_code_catalog_, *image_view, new_pattern, region);\n\n  // Revert back original configuration.\n  if (word3_buff != NULL) {\n    word3_buff->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word3_image != NULL) {\n    word3_image->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word1 != NULL) {\n    word1->bits.FORMAT = num_format_original;\n  }\n\n  return status;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_gfx12.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_IMAGE_MANAGER_GFX12_H_\n#define EXT_IMAGE_IMAGE_MANAGER_GFX12_H_\n\n#include \"addrlib/inc/addrinterface.h\"\n#include \"image_lut_gfx11.h\"\n#include \"image_manager_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageManagerGfx12 : public ImageManagerKv {\n public:\n  ImageManagerGfx12();\n  virtual ~ImageManagerGfx12();\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch, size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(Image& image,\n                                      hsa_ext_image_format_t& new_format) const;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const;\n\n  /// @brief Fill image backing storage using agent copy.\n  virtual hsa_status_t FillImage(const Image& image, const void* pattern,\n                                 const hsa_ext_image_region_t& region);\n protected:\n  uint32_t GetAddrlibSurfaceInfoNv(hsa_agent_t component,\n                             const hsa_ext_image_descriptor_t& desc,\n                             Image::TileMode tileMode,\n                             size_t image_data_row_pitch,\n                             size_t image_data_slice_pitch,\n                             ADDR3_COMPUTE_SURFACE_INFO_OUTPUT& out) const;\n\n  bool IsLocalMemory(const void* address) const;\n  virtual const ImageLutGfx11& ImageLut() const { return image_lut_gfx11; };\n\n private:\n  ImageLutGfx11 image_lut_gfx11;\n  DISALLOW_COPY_AND_ASSIGN(ImageManagerGfx12);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_IMAGE_MANAGER_GFX12_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_kv.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_manager_kv.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n\n#include \"core/inc/runtime.h\"\n#include \"hsakmt/hsakmt.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"core/inc/runtime.h\"\n#include \"addrlib/inc/addrinterface.h\"\n#include \"addrlib/src/core/addrlib.h\"\n#include \"image_runtime.h\"\n#include \"resource.h\"\n#include \"resource_kv.h\"\n#include \"util.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD3)\n\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD3)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD4)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD5)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD6)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD7)\n\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD3)\n\nImageManagerKv::ImageManagerKv() : ImageManager() {}\n\nImageManagerKv::~ImageManagerKv() {}\n\nhsa_status_t ImageManagerKv::Initialize(hsa_agent_t agent_handle) {\n  agent_ = agent_handle;\n\n  hsa_status_t status = GetGPUAsicID(agent_, &chip_id_);\n  uint32_t major_ver = MajorVerFromDevID(chip_id_);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  status = HSA::hsa_agent_get_info(\n      agent_, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_ASIC_FAMILY_ID), &family_type_);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  HsaGpuTileConfig tileConfig = {0};\n  unsigned int tc[40];\n  unsigned int mtc[40];\n  tileConfig.TileConfig = &tc[0];\n  tileConfig.NumTileConfigs = 40;\n  tileConfig.MacroTileConfig = &mtc[0];\n  tileConfig.NumMacroTileConfigs = 40;\n  uint32_t node_id = 0;\n  status = HSA::hsa_agent_get_info(\n      agent_, static_cast<hsa_agent_info_t>(HSA_AMD_AGENT_INFO_DRIVER_NODE_ID), &node_id);\n  assert(status == HSA_STATUS_SUCCESS);\n  hsa_status_t stat = HSA::hsa_get_tile_config(agent_handle, &tileConfig);\n  assert(stat == HSA_STATUS_SUCCESS);\n\n  // Initialize address library.\n  // TODO(bwicakso) hard coded based on UGL parameters.\n  // Need to get this information from KMD.\n  addr_lib_ = NULL;\n  ADDR_CREATE_INPUT addr_create_input = {0};\n  ADDR_CREATE_OUTPUT addr_create_output = {0};\n\n  if (major_ver >= 9) {\n    addr_create_input.chipEngine = CIASICIDGFXENGINE_ARCTICISLAND;\n  } else {\n    addr_create_input.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND;\n  }\n\n  addr_create_input.chipFamily = family_type_;\n  addr_create_input.chipRevision = 0;  // TODO(bwicakso): find how to get this.\n\n  ADDR_CREATE_FLAGS create_flags = {};\n  create_flags.value = 0;\n  create_flags.useTileIndex = 1;\n  addr_create_input.createFlags = create_flags;\n\n  addr_create_input.callbacks.allocSysMem = AllocSysMem;\n  addr_create_input.callbacks.freeSysMem = FreeSysMem;\n  addr_create_input.callbacks.debugPrint = 0;\n\n  ADDR_REGISTER_VALUE reg_val = {0};\n  reg_val.gbAddrConfig = tileConfig.GbAddrConfig;\n  reg_val.noOfBanks = tileConfig.NumBanks;\n  reg_val.noOfRanks = tileConfig.NumRanks;\n  reg_val.pTileConfig = tileConfig.TileConfig;\n  reg_val.noOfEntries = tileConfig.NumTileConfigs;\n  reg_val.noOfMacroEntries = tileConfig.NumMacroTileConfigs;\n  reg_val.pMacroTileConfig = tileConfig.MacroTileConfig;\n\n  addr_create_input.regValue = reg_val;\n\n  addr_create_input.minPitchAlignPixels = 0;\n\n  ADDR_E_RETURNCODE addr_ret =\n      AddrCreate(&addr_create_input, &addr_create_output);\n\n  if (addr_ret == ADDR_OK) {\n    addr_lib_ = addr_create_output.hLib;\n  } else {\n    return HSA_STATUS_ERROR;\n  }\n\n  // The ImageManagerKv::Initialize is called on the first call to\n  // hsa_ext_image_*, so checking the coherency mode here is fine as long as\n  // the change to the coherency mode happens before a call to\n  // hsa_ext_image_create.\n  hsa_amd_coherency_type_t coherency_type;\n  status = AMD::hsa_amd_coherency_get_type(agent_, &coherency_type);\n  assert(status == HSA_STATUS_SUCCESS);\n  mtype_ = (coherency_type == HSA_AMD_COHERENCY_TYPE_COHERENT) ? 3 : 1;\n\n  // TODO: handle the case where the call to hsa_set_memory_type happens after\n  // hsa_ext_image_create.\n\n  hsa_region_t local_region = {0};\n  status = HSA::hsa_agent_iterate_regions(agent_, GetLocalMemoryRegion, &local_region);\n  assert(status == HSA_STATUS_SUCCESS);\n\n  local_memory_base_address_ = 0;\n  if (local_region.handle != 0) {\n    status = HSA::hsa_region_get_info(local_region,\n                                      static_cast<hsa_region_info_t>(HSA_AMD_REGION_INFO_BASE),\n                                      &local_memory_base_address_);\n    assert(status == HSA_STATUS_SUCCESS);\n  }\n\n  // Zeroed the queue object so it can be created on demand.\n  blit_queue_.queue_ = NULL;\n  blit_queue_.cached_index_ = 0;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid ImageManagerKv::Cleanup() {\n  if (blit_queue_.queue_ != NULL) {\n    HSA::hsa_queue_destroy(blit_queue_.queue_);\n  }\n\n  if (addr_lib_ != NULL) {\n    AddrDestroy(addr_lib_);\n  }\n}\n\nImageProperty ImageManagerKv::GetImageProperty(\n    hsa_agent_t component, const hsa_ext_image_format_t& format,\n    hsa_ext_image_geometry_t geometry) const {\n  return ImageLut().MapFormat(format, geometry);\n}\n\nvoid ImageManagerKv::GetImageInfoMaxDimension(hsa_agent_t component,\n                                              hsa_ext_image_geometry_t geometry,\n                                              uint32_t& width, uint32_t& height,\n                                              uint32_t& depth,\n                                              uint32_t& array_size) const {\n  width = ImageLut().GetMaxWidth(geometry);\n  height = ImageLut().GetMaxHeight(geometry);\n  depth = ImageLut().GetMaxDepth(geometry);\n  array_size = ImageLut().GetMaxArraySize(geometry);\n}\n\nhsa_status_t ImageManagerKv::CalculateImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) const {\n  ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n  hsa_profile_t profile;\n\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  Image::TileMode tileMode = Image::TileMode::LINEAR;\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE) {\n    tileMode = (profile == HSA_PROFILE_BASE &&\n                desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)?\n      Image::TileMode::TILED : Image::TileMode::LINEAR;\n  }\n  if (!GetAddrlibSurfaceInfo(component, desc, tileMode,\n        image_data_row_pitch, image_data_slice_pitch, out)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  size_t rowPitch   = (out.bpp >> 3) * out.pitch;\n  size_t slicePitch = rowPitch * out.height;\n  if (desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n      image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR &&\n      ((image_data_row_pitch && (rowPitch != image_data_row_pitch)) ||\n       (image_data_slice_pitch && (slicePitch != image_data_slice_pitch)))) {\n    return static_cast<hsa_status_t>(HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED);\n  }\n\n  image_info.size = out.surfSize;\n  assert(image_info.size != 0);\n  image_info.alignment = out.baseAlign;\n  assert(image_info.alignment != 0);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic const uint64_t kLimitSystem = 1ULL << 48;\n\nbool ImageManagerKv::IsLocalMemory(const void* address) const {\n  uintptr_t u_address = reinterpret_cast<uintptr_t>(address);\n\n  uint32_t major_ver = MajorVerFromDevID(chip_id_);\n\n  if (major_ver >= 8) {\n    return true;\n  }\n#ifdef HSA_LARGE_MODEL\n  // Fast path without querying local memory region info.\n  // User mode system memory addressable by CPU is 0 to 2^48.\n  return (u_address >= kLimitSystem);\n#else\n  // No local memory on 32 bit.\n  return false;\n#endif\n}\n\nhsa_status_t ImageManagerKv::PopulateImageSrd(Image& image, const metadata_amd_t* descriptor) const {\n  metadata_amd_ci_vi_t* desc = (metadata_amd_ci_vi_t*)descriptor;\n  bool atc_access = true;\n  uint32_t mtype = mtype_;\n  const void* image_data_addr = image.data;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  if((image_prop.cap == HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED) ||\n     (image_prop.element_size == 0))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  uint32_t hwPixelSize =\n      ImageLut().GetPixelSize(desc->word1.bitfields.data_format, desc->word1.bitfields.num_format);\n  if(image_prop.element_size!=hwPixelSize)\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n\n  if (IsLocalMemory(image.data)) {\n    atc_access = false;\n    mtype = 1;\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  image.srd[0]=desc->word0.u32_all;\n  image.srd[1]=desc->word1.u32_all;\n  image.srd[2]=desc->word2.u32_all;\n  image.srd[3]=desc->word3.u32_all;\n  image.srd[4]=desc->word4.u32_all;\n  image.srd[5]=desc->word5.u32_all;\n  image.srd[6]=desc->word6.u32_all;\n  image.srd[7]=desc->word7.u32_all;\n\n  ((SQ_IMG_RSRC_WORD0*)(&image.srd[0]))->bits.base_address = PtrLow40Shift8(image_data_addr);\n  ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.base_address_hi = PtrHigh64Shift40(image_data_addr);\n  ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.data_format = image_prop.data_format;\n  ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.num_format = image_prop.data_type;\n  ((SQ_IMG_RSRC_WORD1*)(&image.srd[1]))->bits.mtype = mtype;\n  ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.atc=atc_access;\n  ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.dst_sel_x = swizzle.x;\n  ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.dst_sel_y = swizzle.y;\n  ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.dst_sel_z = swizzle.z;\n  ((SQ_IMG_RSRC_WORD3*)(&image.srd[3]))->bits.dst_sel_w = swizzle.w;\n  ((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.meta_data_address += PtrLow40Shift8(image_data_addr);\n\n  //Looks like this is only used for CPU copies.\n  image.row_pitch = (desc->word4.bits.pitch+1)*image_prop.element_size;\n  image.slice_pitch = image.row_pitch * (desc->word2.bits.height+1);\n\n  //Used by HSAIL shader ABI\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerKv::PopulateImageSrd(Image& image) const {\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  bool atc_access = true;\n  uint32_t mtype = mtype_;\n  const void* image_data_addr = image.data;\n\n  if (IsLocalMemory(image.data)) {\n    atc_access = false;\n    mtype = 1;\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD2 word2;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.u32_all = 0;\n    word0.bits.base_address = PtrLow32(image_data_addr);\n\n    word1.u32_all = 0;\n    word1.bits.base_address_hi = PtrHigh32(image_data_addr);\n    word1.bits.stride = image_prop.element_size;\n    word1.bits.swizzle_enable = false;\n    word1.bits.cache_swizzle = false;\n\n    uint32_t major_ver = MajorVerFromDevID(chip_id_);\n    word2.bits.num_records = (major_ver < 8) ?\n                image.desc.width : image.desc.width * image_prop.element_size;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.u32_all = 0;\n    word3.bits.dst_sel_x = swizzle.x;\n    word3.bits.dst_sel_y = swizzle.y;\n    word3.bits.dst_sel_z = swizzle.z;\n    word3.bits.dst_sel_w = swizzle.w;\n    word3.bits.num_format = image_prop.data_type;\n    word3.bits.data_format = image_prop.data_format;\n    word3.bits.atc = atc_access;\n    word3.bits.element_size = image_prop.element_size;\n    word3.bits.type = ImageLut().MapGeometry(image.desc.geometry);\n    word3.bits.mtype = mtype;\n\n    image.srd[0] = word0.u32_all;\n    image.srd[1] = word1.u32_all;\n    image.srd[2] = word2.u32_all;\n    image.srd[3] = word3.u32_all;\n\n    image.row_pitch = image.desc.width * image_prop.element_size;\n    image.slice_pitch = image.row_pitch;\n  } else {\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD6 word6;\n    SQ_IMG_RSRC_WORD7 word7;\n\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n    if (!GetAddrlibSurfaceInfo(image.component, image.desc, image.tile_mode,\n          image.row_pitch, image.slice_pitch, out)) {\n      return HSA_STATUS_ERROR;\n    }\n\n    assert((out.bpp / 8) == image_prop.element_size);\n\n    const size_t row_pitch_size = out.pitch * image_prop.element_size;\n\n    word0.bits.base_address = PtrLow40Shift8(image_data_addr);\n\n    word1.u32_all = 0;\n    word1.bits.base_address_hi = PtrHigh64Shift40(image_data_addr);\n    word1.bits.min_lod = 0;\n    word1.bits.data_format = image_prop.data_format;\n    word1.bits.num_format = image_prop.data_type;\n    word1.bits.mtype = mtype;\n\n    word2.u32_all = 0;\n    word2.bits.width = image.desc.width - 1;\n    word2.bits.height = image.desc.height - 1;\n    word2.bits.perf_mod = 0;\n    word2.bits.interlaced = 0;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.u32_all = 0;\n    word3.bits.dst_sel_x = swizzle.x;\n    word3.bits.dst_sel_y = swizzle.y;\n    word3.bits.dst_sel_z = swizzle.z;\n    word3.bits.dst_sel_w = swizzle.w;\n    word3.bits.tiling_index = out.tileIndex;\n    word3.bits.pow2_pad = (IsPowerOfTwo(row_pitch_size) && IsPowerOfTwo(image.desc.height)) ? 1 : 0;\n    word3.bits.type = ImageLut().MapGeometry(image.desc.geometry);\n    word3.bits.atc = atc_access;\n\n    const bool image_array =\n        (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH);\n    const bool image_3d = (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_3D);\n\n    word4.u32_all = 0;\n    word4.bits.depth =\n        (image_array)\n            ? std::max(image.desc.array_size, static_cast<size_t>(1)) - 1\n            : (image_3d) ? image.desc.depth - 1 : 0;\n    word4.bits.pitch = out.pitch - 1;\n\n    word5.u32_all = 0;\n    word5.bits.last_array =\n        (image_array)\n            ? (std::max(image.desc.array_size, static_cast<size_t>(1)) - 1)\n            : 0;\n\n    word6.u32_all = 0;\n    word7.u32_all = 0;\n\n    image.srd[0] = word0.u32_all;\n    image.srd[1] = word1.u32_all;\n    image.srd[2] = word2.u32_all;\n    image.srd[3] = word3.u32_all;\n    image.srd[4] = word4.u32_all;\n    image.srd[5] = word5.u32_all;\n    image.srd[6] = word6.u32_all;\n    image.srd[7] = word7.u32_all;\n\n    image.row_pitch = row_pitch_size;\n    image.slice_pitch = out.sliceSize;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerKv::ModifyImageSrd(\n    Image& image, hsa_ext_image_format_t& new_format) const {\n  image.desc.format = new_format;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_BUF_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.dst_sel_x = swizzle.x;\n    word3->bits.dst_sel_y = swizzle.y;\n    word3->bits.dst_sel_z = swizzle.z;\n    word3->bits.dst_sel_w = swizzle.w;\n    word3->bits.num_format = image_prop.data_type;\n    word3->bits.data_format = image_prop.data_format;\n  } else {\n    SQ_IMG_RSRC_WORD1* word1 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1]);\n    word1->bits.data_format = image_prop.data_format;\n    word1->bits.num_format = image_prop.data_type;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_IMG_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.dst_sel_x = swizzle.x;\n    word3->bits.dst_sel_y = swizzle.y;\n    word3->bits.dst_sel_z = swizzle.z;\n    word3->bits.dst_sel_w = swizzle.w;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerKv::PopulateSamplerSrd(Sampler& sampler) const {\n  const hsa_ext_sampler_descriptor_v2_t &sampler_descriptor = sampler.desc;\n\n  SQ_IMG_SAMP_WORD0 word0;\n  SQ_IMG_SAMP_WORD1 word1;\n  SQ_IMG_SAMP_WORD2 word2;\n  SQ_IMG_SAMP_WORD3 word3;\n\n  word0.u32_all = 0;\n  hsa_status_t status = convertAddressMode<SQ_IMG_SAMP_WORD0, SQ_TEX_CLAMP>\n                                         (word0, sampler_descriptor.address_modes);\n  if (status != HSA_STATUS_SUCCESS) return status;\n  word0.bits.force_unormalized = (sampler_descriptor.coordinate_mode ==\n                                  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED);\n\n  word1.u32_all = 0;\n  word1.bits.max_lod = 4095;\n\n  word2.u32_all = 0;\n  switch (sampler_descriptor.filter_mode) {\n    case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST:\n      word2.bits.xy_mag_filter = static_cast<int>(SQ_TEX_XY_FILTER_POINT);\n      break;\n    case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR:\n      word2.bits.xy_mag_filter = static_cast<int>(SQ_TEX_XY_FILTER_BILINEAR);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  word2.bits.xy_min_filter = word2.bits.xy_mag_filter;\n  word2.bits.z_filter = SQ_TEX_Z_FILTER_NONE;\n  word2.bits.mip_filter = SQ_TEX_MIP_FILTER_NONE;\n\n  word3.u32_all = 0;\n\n  // TODO: check this bit with HSAIL spec.\n  word3.bits.border_color_type = SQ_TEX_BORDER_COLOR_TRANS_BLACK;\n\n  sampler.srd[0] = word0.u32_all;\n  sampler.srd[1] = word1.u32_all;\n  sampler.srd[2] = word2.u32_all;\n  sampler.srd[3] = word3.u32_all;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerKv::CopyBufferToImage(\n    const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n    const Image& dst_image, const hsa_ext_image_region_t& image_region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  return ImageRuntime::instance()->blit_kernel().CopyBufferToImage(\n      blit_queue_, blit_code_catalog_, src_memory, src_row_pitch, src_slice_pitch, dst_image,\n      image_region);\n}\n\nhsa_status_t ImageManagerKv::CopyImageToBuffer(\n    const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n    size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  return ImageRuntime::instance()->blit_kernel().CopyImageToBuffer(\n      blit_queue_, blit_code_catalog_, src_image, dst_memory, dst_row_pitch, dst_slice_pitch,\n      image_region);\n}\n\nhsa_status_t ImageManagerKv::CopyImage(const Image& dst_image,\n                                       const Image& src_image,\n                                       const hsa_dim3_t& dst_origin,\n                                       const hsa_dim3_t& src_origin,\n                                       const hsa_dim3_t size) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  const hsa_ext_image_format_t src_format = src_image.desc.format;\n  const hsa_ext_image_channel_order32_t src_order = src_format.channel_order;\n  const hsa_ext_image_channel_type32_t src_type = src_format.channel_type;\n\n  const hsa_ext_image_format_t dst_format = dst_image.desc.format;\n  const hsa_ext_image_channel_order32_t dst_order = dst_format.channel_order;\n  const hsa_ext_image_channel_type32_t dst_type = dst_format.channel_type;\n\n  BlitKernel::KernelOp copy_type = BlitKernel::KERNEL_OP_COPY_IMAGE_DEFAULT;\n\n  if ((src_order == dst_order) && (src_type == dst_type)) {\n    return ImageRuntime::instance()->blit_kernel().CopyImage(blit_queue_, blit_code_catalog_,\n                                                             dst_image, src_image, dst_origin,\n                                                             src_origin, size, copy_type);\n  }\n\n  // Source and destination format must be the same, except for\n  // SRGBA <--> RGBA images.\n  if ((src_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8) &&\n      (dst_type == HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8)) {\n    if ((src_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA) &&\n        (dst_order == HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA)) {\n      copy_type = BlitKernel::KERNEL_OP_COPY_IMAGE_STANDARD_TO_LINEAR;\n    } else if ((src_order == HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA) &&\n               (dst_order == HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA)) {\n      copy_type = BlitKernel::KERNEL_OP_COPY_IMAGE_LINEAR_TO_STANDARD;\n    }\n\n    if (copy_type != BlitKernel::KERNEL_OP_COPY_IMAGE_DEFAULT) {\n      // KV and CZ don't have write support for SRGBA image, so treat the\n      // destination image as RGBA image.\n      SQ_IMG_RSRC_WORD1* word1 = reinterpret_cast<SQ_IMG_RSRC_WORD1*>(\n          &const_cast<Image&>(dst_image).srd[1]);\n\n      // Destination can be linear or standard, preserve the original value.\n      uint32_t num_format_original = word1->bits.num_format;\n      word1->bits.num_format = TYPE_UNORM;\n\n      hsa_status_t status = ImageRuntime::instance()->blit_kernel().CopyImage(\n          blit_queue_, blit_code_catalog_, dst_image, src_image, dst_origin, src_origin, size,\n          copy_type);\n\n      // Revert to the original format after the copy operation is finished.\n      word1->bits.num_format = num_format_original;\n\n      return status;\n    }\n  }\n\n  return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n}\n\nhsa_status_t ImageManagerKv::FillImage(const Image& image, const void* pattern,\n                                       const hsa_ext_image_region_t& region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  Image* image_view = const_cast<Image*>(&image);\n\n  SQ_BUF_RSRC_WORD3* word3_buff = NULL;\n  SQ_IMG_RSRC_WORD3* word3_image = NULL;\n  uint32_t dst_sel_w_original = 0;\n  if (image_view->desc.format.channel_type ==\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010) {\n    // Force GPU to ignore the last two bits (alpha bits).\n    if (image_view->desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      word3_buff = reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_buff->bits.dst_sel_w;\n      word3_buff->bits.dst_sel_w = SEL_0;\n    } else {\n      word3_image = reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_image->bits.dst_sel_w;\n      word3_image->bits.dst_sel_w = SEL_0;\n    }\n  }\n\n  SQ_IMG_RSRC_WORD1* word1 = NULL;\n  uint32_t num_format_original = 0;\n  const void* new_pattern = pattern;\n  float fill_value[4] = {0};\n  switch (image_view->desc.format.channel_order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA: {\n      // KV and CZ don't have write support for SRGBA image, so convert pattern\n      // to standard form and treat the image as RGBA image.\n      const float* pattern_f = reinterpret_cast<const float*>(pattern);\n      fill_value[0] = LinearToStandardRGB(pattern_f[0]);\n      fill_value[1] = LinearToStandardRGB(pattern_f[1]);\n      fill_value[2] = LinearToStandardRGB(pattern_f[2]);\n      fill_value[3] = pattern_f[3];\n      new_pattern = fill_value;\n\n      word1 = reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image_view->srd[1]);\n      num_format_original = word1->bits.num_format;\n      word1->bits.num_format = TYPE_UNORM;\n    } break;\n    default:\n      break;\n  }\n\n  hsa_status_t status = ImageRuntime::instance()->blit_kernel().FillImage(\n      blit_queue_, blit_code_catalog_, *image_view, new_pattern, region);\n\n  // Revert back original configuration.\n  if (word3_buff != NULL) {\n    word3_buff->bits.dst_sel_w = dst_sel_w_original;\n  }\n\n  if (word3_image != NULL) {\n    word3_image->bits.dst_sel_w = dst_sel_w_original;\n  }\n\n  if (word1 != NULL) {\n    word1->bits.num_format = num_format_original;\n  }\n\n  return status;\n}\n\nhsa_status_t ImageManagerKv::GetLocalMemoryRegion(hsa_region_t region,\n                                                  void* data) {\n  if (data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_region_segment_t segment;\n  hsa_status_t stat = HSA::hsa_region_get_info(region, HSA_REGION_INFO_SEGMENT, &segment);\n  if (stat != HSA_STATUS_SUCCESS) {\n    return stat;\n  }\n\n  if (segment != HSA_REGION_SEGMENT_GLOBAL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  uint32_t base = 0;\n  stat = HSA::hsa_region_get_info(region, HSA_REGION_INFO_GLOBAL_FLAGS, &base);\n  if (stat != HSA_STATUS_SUCCESS) {\n    return stat;\n  }\n\n  if ((base & HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED) != 0) {\n    hsa_region_t* local_memory_region = (hsa_region_t*)data;\n    *local_memory_region = region;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nAddrFormat ImageManagerKv::GetAddrlibFormat(const ImageProperty& image_prop) {\n  switch (image_prop.data_format) {\n    case FMT_8:\n      return ADDR_FMT_8;\n      break;\n    case FMT_16:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_16\n                                                  : ADDR_FMT_16_FLOAT;\n      break;\n    case FMT_8_8:\n      return ADDR_FMT_8_8;\n      break;\n    case FMT_32:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_32\n                                                  : ADDR_FMT_32_FLOAT;\n      break;\n    case FMT_16_16:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_16_16\n                                                  : ADDR_FMT_16_16_FLOAT;\n      break;\n    case FMT_2_10_10_10:\n      return ADDR_FMT_2_10_10_10;\n      break;\n    case FMT_8_8_8_8:\n      return ADDR_FMT_8_8_8_8;\n      break;\n    case FMT_32_32:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_32_32\n                                                  : ADDR_FMT_32_32_FLOAT;\n      break;\n    case FMT_16_16_16_16:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_16_16_16_16\n                                                  : ADDR_FMT_16_16_16_16_FLOAT;\n      break;\n    case FMT_32_32_32_32:\n      return (image_prop.data_type != TYPE_FLOAT) ? ADDR_FMT_32_32_32_32\n                                                  : ADDR_FMT_32_32_32_32_FLOAT;\n      break;\n    case FMT_5_6_5:\n      return ADDR_FMT_5_6_5;\n      break;\n    case FMT_1_5_5_5:\n      return ADDR_FMT_1_5_5_5;\n      break;\n    case FMT_8_24:\n      return ADDR_FMT_8_24;\n      break;\n    default:\n      assert(false && \"Should not reach here\");\n      return ADDR_FMT_INVALID;\n      break;\n  }\n\n  assert(false && \"Should not reach here\");\n  return ADDR_FMT_INVALID;\n}\n\nVOID* ADDR_API\n    ImageManagerKv::AllocSysMem(const ADDR_ALLOCSYSMEM_INPUT* input) {\n  return malloc(input->sizeInBytes);\n}\n\nADDR_E_RETURNCODE ADDR_API\n    ImageManagerKv::FreeSysMem(const ADDR_FREESYSMEM_INPUT* input) {\n  free(input->pVirtAddr);\n\n  return ADDR_OK;\n}\n\nbool ImageManagerKv::GetAddrlibSurfaceInfo(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    Image::TileMode tileMode,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    ADDR_COMPUTE_SURFACE_INFO_OUTPUT& out) const {\n  const ImageProperty image_prop =\n      GetImageProperty(component, desc.format, desc.geometry);\n\n  const AddrFormat addrlib_format = GetAddrlibFormat(image_prop);\n\n  const uint32_t width = static_cast<uint32_t>(desc.width);\n  const uint32_t height = static_cast<uint32_t>(desc.height);\n  static const size_t kMinNumSlice = 1;\n  const uint32_t num_slice = static_cast<uint32_t>(\n      std::max(kMinNumSlice, std::max(desc.array_size, desc.depth)));\n\n  uint32_t major_ver = MajorVerFromDevID(chip_id_);\n\n  if (major_ver >= 9) {\n    ADDR2_COMPUTE_SURFACE_INFO_INPUT in = {0};\n    in.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);\n    in.format = addrlib_format;\n    in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n    in.width = width;\n    in.height = height;\n    in.numSlices = num_slice;\n    in.pitchInElement = image_data_row_pitch / image_prop.element_size;\n    switch(desc.geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n      in.resourceType = ADDR_RSRC_TEX_1D;\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      in.resourceType = ADDR_RSRC_TEX_2D;\n      break;\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      {\n\t      in.resourceType = ADDR_RSRC_TEX_3D;\n\t      /*\n\t       * 3D swizzle modes enforce alignment\n\t       * of the number of slices  to the block depth.\n\t       * If numSlices = 3 then the 3 slices are\n\t       * interleaved for 3D locality among the 8 slices\n\t       * that make up each block. This causes the memory\n\t       * footprint to jump to a 3x size of the ideal size\n\t       * 'enable3DSwizzleMode' flag tests for env variable\n\t       * HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG to enable or disable\n\t       * 3D swizzle:\n\t       * true: Keep view3dAs2dArray = 0 for real 3D interleaving.\n\t       * false: Use view3dAs2dArray = 1 to avoid the alignment\n\t       *       expansion.\n\t       * 2D swizzle modes can lower size overhead but may yield\n\t       * suboptimal cache behavior for fully 3D volumetric\n\t       * operations.\n\t       */\n\t      bool enable3DSwizzleMode = core::Runtime::runtime_singleton_->flag().enable_3d_swizzle();\n\t      if (enable3DSwizzleMode)\n\t\t      in.flags.view3dAs2dArray = 0;\n\t      else\n\t\t      in.flags.view3dAs2dArray = 1;\n\n\t      break;\n      }\n    }\n    in.flags.texture = 1;\n\n    ADDR2_GET_PREFERRED_SURF_SETTING_INPUT  prefSettingsInput = { 0 };\n    ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT prefSettingsOutput = { 0 };\n\n    prefSettingsInput.size            = sizeof(prefSettingsInput);\n    prefSettingsInput.flags           = in.flags;\n    prefSettingsInput.bpp             = in.bpp;\n    prefSettingsInput.format          = in.format;\n    prefSettingsInput.width           = in.width;\n    prefSettingsInput.height          = in.height;\n    prefSettingsInput.numFrags        = in.numFrags;\n    prefSettingsInput.numSamples      = in.numSamples;\n    prefSettingsInput.numMipLevels    = in.numMipLevels;\n    prefSettingsInput.numSlices       = in.numSlices;\n    prefSettingsInput.resourceLoction = ADDR_RSRC_LOC_UNDEF;\n    prefSettingsInput.resourceType    = in.resourceType;\n\n    // Disallow all swizzles but linear.\n    if (tileMode == Image::TileMode::LINEAR)\n    {\n      prefSettingsInput.forbiddenBlock.macroThin4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThin64KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick64KB = 1;\n    }\n\n    prefSettingsInput.forbiddenBlock.micro = 1; // but don't ever allow the 256b swizzle modes\n    prefSettingsInput.forbiddenBlock.var = 1; // and don't allow variable-size block modes\n\n    if (ADDR_OK != Addr2GetPreferredSurfaceSetting(addr_lib_, &prefSettingsInput, &prefSettingsOutput)) {\n      return false;\n    }\n\n    in.swizzleMode = prefSettingsOutput.swizzleMode;\n\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out2 = {0};\n    out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);\n    if (ADDR_OK != Addr2ComputeSurfaceInfo(addr_lib_, &in, &out2)) {\n      return false;\n    }\n    out.pitch = out2.pitch;\n    out.height = out2.height;\n    out.surfSize = out2.surfSize;\n    out.bpp = out2.bpp;\n    out.baseAlign = out2.baseAlign;\n    out.tileIndex = in.swizzleMode;\n    out.sliceSize = out2.sliceSize;\n    return true;\n  }\n\n  ADDR_COMPUTE_SURFACE_INFO_INPUT in = {0};\n  in.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);\n  in.tileMode = (tileMode == Image::TileMode::LINEAR)?\n    ADDR_TM_LINEAR_ALIGNED : ADDR_TM_2D_TILED_THIN1;\n  in.format = addrlib_format;\n  in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n  in.numSamples = 1;\n  in.width = width;\n  in.height = height;\n  in.numSlices = num_slice;\n  in.flags.texture = 1;\n  in.flags.noStencil = 1;\n  in.flags.opt4Space = 0;\n  in.tileType = ADDR_NON_DISPLAYABLE;\n  in.tileIndex = -1;\n\n  if (image_data_row_pitch != 0) {\n    in.width = image_data_row_pitch / image_prop.element_size;\n//    in.pitchAlign  = image_data_row_pitch / image_prop.element_size;\n//    in.heightAlign = image_data_slice_pitch / image_data_row_pitch;\n  }\n\n  if (ADDR_OK != AddrComputeSurfaceInfo(addr_lib_, &in, &out)) {\n    return false;\n  }\n\n  assert(out.tileIndex != -1);\n\n  return (out.tileIndex != -1) ? true : false;\n}\n\nsize_t ImageManagerKv::CalWorkingSizeBytes(hsa_ext_image_geometry_t geometry,\n                                           hsa_dim3_t size_pixel,\n                                           uint32_t element_size) const {\n  switch (geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n      return size_pixel.x * element_size;\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      return size_pixel.x * size_pixel.y * element_size;\n    default:\n      return size_pixel.x * size_pixel.y * size_pixel.z * element_size;\n  }\n}\n\nBlitQueue& ImageManagerKv::BlitQueueInit() {\n  if (blit_queue_.queue_ == NULL) {\n    // Queue is a precious resource, so only create it when it is needed.\n    std::lock_guard<std::mutex> lock(lock_);\n    if (blit_queue_.queue_ == NULL) {\n      // Create the kernel queue.\n      blit_queue_.cached_index_ = 0;\n\n      uint32_t max_queue_size = 0;\n      hsa_status_t status =\n          HSA::hsa_agent_get_info(agent_, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &max_queue_size);\n\n      status = HSA::hsa_queue_create(agent_, max_queue_size, HSA_QUEUE_TYPE_MULTI, NULL, NULL,\n                                     UINT_MAX, UINT_MAX, &blit_queue_.queue_);\n\n      if (HSA_STATUS_SUCCESS != status) {\n        blit_queue_.queue_ = NULL;\n        return blit_queue_;\n      }\n\n      // Get the kernel handles.\n      status = ImageRuntime::instance()->blit_kernel().BuildBlitCode(agent_, blit_code_catalog_);\n\n      if (HSA_STATUS_SUCCESS != status) {\n        blit_code_catalog_.clear();\n        HSA::hsa_queue_destroy(blit_queue_.queue_);\n        blit_queue_.queue_ = NULL;\n        return blit_queue_;\n      }\n    }\n  }\n\n  assert(blit_queue_.queue_ != NULL &&\n         blit_code_catalog_.size() == BlitKernel::KERNEL_OP_COUNT);\n\n  return blit_queue_;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_kv.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_KV_H\n#define HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_KV_H\n\n#include \"addrlib/inc/addrinterface.h\"\n#include \"blit_kernel.h\"\n#include \"image_lut_kv.h\"\n#include \"image_manager.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageManagerKv : public ImageManager {\n public:\n  explicit ImageManagerKv();\n  virtual ~ImageManagerKv();\n\n  virtual hsa_status_t Initialize(hsa_agent_t agent_handle);\n\n  virtual void Cleanup();\n\n  /// @brief Retrieve device specific image property of a certain format\n  /// and geometry.\n  virtual ImageProperty GetImageProperty(\n      hsa_agent_t component, const hsa_ext_image_format_t& format,\n      hsa_ext_image_geometry_t geometry) const;\n\n  /// @brief Retrieve device specific supported max width, height, depth,\n  /// and array size of an image geometry.\n  virtual void GetImageInfoMaxDimension(hsa_agent_t component,\n                                        hsa_ext_image_geometry_t geometry,\n                                        uint32_t& width, uint32_t& height,\n                                        uint32_t& depth,\n                                        uint32_t& array_size) const;\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch, size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(Image& image,\n                                      hsa_ext_image_format_t& new_format) const;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const;\n\n  // @brief Copy the content of a linear memory to an image object.\n  virtual hsa_status_t CopyBufferToImage(\n      const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n      const Image& dst_image, const hsa_ext_image_region_t& image_region);\n\n  /// @brief Copy the content of an image object to a linear memory.\n  virtual hsa_status_t CopyImageToBuffer(\n      const Image& src_image, void* dst_memory, size_t dst_row_pitch,\n      size_t dst_slice_pitch, const hsa_ext_image_region_t& image_region);\n\n  /// @brief Transfer images backing storage using agent copy.\n  virtual hsa_status_t CopyImage(const Image& dst_image, const Image& src_image,\n                                 const hsa_dim3_t& dst_origin,\n                                 const hsa_dim3_t& src_origin,\n                                 const hsa_dim3_t size);\n\n  /// @brief Fill image backing storage using agent copy.\n  virtual hsa_status_t FillImage(const Image& image, const void* pattern,\n                                 const hsa_ext_image_region_t& region);\n\n protected:\n  static hsa_status_t GetLocalMemoryRegion(hsa_region_t region, void* data);\n\n  static AddrFormat GetAddrlibFormat(const ImageProperty& image_prop);\n\n  static VOID* ADDR_API AllocSysMem(const ADDR_ALLOCSYSMEM_INPUT* input);\n\n  static ADDR_E_RETURNCODE ADDR_API\n      FreeSysMem(const ADDR_FREESYSMEM_INPUT* input);\n\n  bool GetAddrlibSurfaceInfo(hsa_agent_t component,\n                             const hsa_ext_image_descriptor_t& desc,\n                             Image::TileMode tileMode,\n                             size_t image_data_row_pitch,\n                             size_t image_data_slice_pitch,\n                             ADDR_COMPUTE_SURFACE_INFO_OUTPUT& out) const;\n\n  size_t CalWorkingSizeBytes(hsa_ext_image_geometry_t geometry,\n                             hsa_dim3_t size_pixel,\n                             uint32_t element_size) const;\n\n  virtual bool IsLocalMemory(const void* address) const;\n\n  BlitQueue& BlitQueueInit();\n\n  virtual const ImageLutKv& ImageLut() const { return image_lut_; };\n\n  ADDR_HANDLE addr_lib_;\n\n  hsa_agent_t agent_;\n\n  uint32_t family_type_;\n\n  uint32_t chip_id_;\n\n  BlitQueue blit_queue_;\n\n  std::vector<BlitCodeInfo> blit_code_catalog_;\n\n  uint32_t mtype_;\n\n  uintptr_t local_memory_base_address_;\n\n  std::mutex lock_;\n\n private:\n  ImageLutKv image_lut_;\n  DISALLOW_COPY_AND_ASSIGN(ImageManagerKv);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_IMAGE_MANAGER_KV_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_nv.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_manager_nv.h\"\n\n#include <assert.h>\n\n#include <algorithm>\n#include <climits>\n\n#include \"core/inc/runtime.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"addrlib/src/core/addrlib.h\"\n#include \"image_runtime.h\"\n#include \"resource.h\"\n#include \"resource_nv.h\"\n#include \"util.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_BUF_RSRC_WORD3)\n\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD3)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD4)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD5)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD6)\nASSERT_SIZE_UINT32(SQ_IMG_RSRC_WORD7)\n\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD0)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD1)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD2)\nASSERT_SIZE_UINT32(SQ_IMG_SAMP_WORD3)\n\n//-----------------------------------------------------------------------------\n// Workaround switch to combined format/type codes and missing gfx10\n// specific look up table.  Only covers types used in image_lut_kv.cpp.\n//-----------------------------------------------------------------------------\nstruct formatconverstion_t {\n  FMT fmt;\n  type type;\n  FORMAT format;\n};\n\n// Format/Type to combined format code table.\n// Sorted and indexed to allow fast searches.\nstatic const formatconverstion_t FormatLUT[] = {\n    {FMT_1_5_5_5, TYPE_UNORM, CFMT_1_5_5_5_UNORM},          // 0\n    {FMT_10_10_10_2, TYPE_UNORM, CFMT_10_10_10_2_UNORM},    // 1\n    {FMT_10_10_10_2, TYPE_SNORM, CFMT_10_10_10_2_SNORM},    // 2\n    {FMT_10_10_10_2, TYPE_UINT, CFMT_10_10_10_2_UINT},      // 3\n    {FMT_10_10_10_2, TYPE_SINT, CFMT_10_10_10_2_SINT},      // 4\n    {FMT_16, TYPE_UNORM, CFMT_16_UNORM},                    // 5\n    {FMT_16, TYPE_SNORM, CFMT_16_SNORM},                    // 6\n    {FMT_16, TYPE_UINT, CFMT_16_UINT},                      // 7\n    {FMT_16, TYPE_SINT, CFMT_16_SINT},                      // 8\n    {FMT_16, TYPE_FLOAT, CFMT_16_FLOAT},                    // 9\n    {FMT_16_16, TYPE_UNORM, CFMT_16_16_UNORM},              // 10\n    {FMT_16_16, TYPE_SNORM, CFMT_16_16_SNORM},              // 11\n    {FMT_16_16, TYPE_UINT, CFMT_16_16_UINT},                // 12\n    {FMT_16_16, TYPE_SINT, CFMT_16_16_SINT},                // 13\n    {FMT_16_16, TYPE_FLOAT, CFMT_16_16_FLOAT},              // 14\n    {FMT_16_16_16_16, TYPE_UNORM, CFMT_16_16_16_16_UNORM},  // 15\n    {FMT_16_16_16_16, TYPE_SNORM, CFMT_16_16_16_16_SNORM},  // 16\n    {FMT_16_16_16_16, TYPE_UINT, CFMT_16_16_16_16_UINT},    // 17\n    {FMT_16_16_16_16, TYPE_SINT, CFMT_16_16_16_16_SINT},    // 18\n    {FMT_16_16_16_16, TYPE_FLOAT, CFMT_16_16_16_16_FLOAT},  // 19\n    {FMT_2_10_10_10, TYPE_UNORM, CFMT_2_10_10_10_UNORM},    // 20\n    {FMT_2_10_10_10, TYPE_SNORM, CFMT_2_10_10_10_SNORM},    // 21\n    {FMT_2_10_10_10, TYPE_UINT, CFMT_2_10_10_10_UINT},      // 22\n    {FMT_2_10_10_10, TYPE_SINT, CFMT_2_10_10_10_SINT},      // 23\n    {FMT_24_8, TYPE_UNORM, CFMT_24_8_UNORM},                // 24\n    {FMT_24_8, TYPE_UINT, CFMT_24_8_UINT},                  // 25\n    {FMT_32, TYPE_UINT, CFMT_32_UINT},                      // 26\n    {FMT_32, TYPE_SINT, CFMT_32_SINT},                      // 27\n    {FMT_32, TYPE_FLOAT, CFMT_32_FLOAT},                    // 28\n    {FMT_32_32, TYPE_UINT, CFMT_32_32_UINT},                // 29\n    {FMT_32_32, TYPE_SINT, CFMT_32_32_SINT},                // 30\n    {FMT_32_32, TYPE_FLOAT, CFMT_32_32_FLOAT},              // 31\n    {FMT_32_32_32, TYPE_UINT, CFMT_32_32_32_UINT},          // 32\n    {FMT_32_32_32, TYPE_SINT, CFMT_32_32_32_SINT},          // 33\n    {FMT_32_32_32, TYPE_FLOAT, CFMT_32_32_32_FLOAT},        // 34\n    {FMT_32_32_32_32, TYPE_UINT, CFMT_32_32_32_32_UINT},    // 35\n    {FMT_32_32_32_32, TYPE_SINT, CFMT_32_32_32_32_SINT},    // 36\n    {FMT_32_32_32_32, TYPE_FLOAT, CFMT_32_32_32_32_FLOAT},  // 37\n    {FMT_5_5_5_1, TYPE_UNORM, CFMT_5_5_5_1_UNORM},          // 38\n    {FMT_5_6_5, TYPE_UNORM, CFMT_5_6_5_UNORM},              // 39\n    {FMT_8, TYPE_UNORM, CFMT_8_UNORM},                      // 40\n    {FMT_8, TYPE_SNORM, CFMT_8_SNORM},                      // 41\n    {FMT_8, TYPE_UINT, CFMT_8_UINT},                        // 42\n    {FMT_8, TYPE_SINT, CFMT_8_SINT},                        // 43\n    {FMT_8, TYPE_SRGB, CFMT_8_SRGB},                        // 44\n    {FMT_8_24, TYPE_UNORM, CFMT_8_24_UNORM},                // 45\n    {FMT_8_24, TYPE_UINT, CFMT_8_24_UINT},                  // 46\n    {FMT_8_8, TYPE_UNORM, CFMT_8_8_UNORM},                  // 47\n    {FMT_8_8, TYPE_SNORM, CFMT_8_8_SNORM},                  // 48\n    {FMT_8_8, TYPE_UINT, CFMT_8_8_UINT},                    // 49\n    {FMT_8_8, TYPE_SINT, CFMT_8_8_SINT},                    // 50\n    {FMT_8_8, TYPE_SRGB, CFMT_8_8_SRGB},                    // 51\n    {FMT_8_8_8_8, TYPE_UNORM, CFMT_8_8_8_8_UNORM},          // 52\n    {FMT_8_8_8_8, TYPE_SNORM, CFMT_8_8_8_8_SNORM},          // 53\n    {FMT_8_8_8_8, TYPE_UINT, CFMT_8_8_8_8_UINT},            // 54\n    {FMT_8_8_8_8, TYPE_SINT, CFMT_8_8_8_8_SINT},            // 55\n    {FMT_8_8_8_8, TYPE_SRGB, CFMT_8_8_8_8_SRGB}             // 56\n};\nstatic const int FormatLUTSize = sizeof(FormatLUT)/sizeof(formatconverstion_t);\n\n//Index in FormatLUT to start search, indexed by FMT enum.\nstatic const int FormatEntryPoint[] = {\n  57,\n  40,\n  5,\n  47,\n  26,\n  10,\n  57,\n  57,\n  1,\n  20,\n  52,\n  29,\n  15,\n  32,\n  35,\n  57,\n  39,\n  0,\n  38,\n  57,\n  45,\n  24\n};\n\nstatic FORMAT GetCombinedFormat(uint8_t fmt, uint8_t type) {\n  assert(fmt < sizeof(FormatEntryPoint)/sizeof(int) && \"FMT out of range.\");\n  int start = FormatEntryPoint[fmt];\n  int stop = std::min(start + 6, FormatLUTSize); // Only 6 types are used in image_kv_lut.cpp\n\n  for(int i=start; i<stop; i++) {\n    if((FormatLUT[i].fmt == fmt) && (FormatLUT[i].type == type))\n      return FormatLUT[i].format;\n  }\n  return CFMT_INVALID;\n};\n//-----------------------------------------------------------------------------\n// End workaround \n//-----------------------------------------------------------------------------\n\nImageManagerNv::ImageManagerNv() : ImageManagerKv() {}\n\nImageManagerNv::~ImageManagerNv() {}\n\n// TODO(cfreehil) remove from class, make it a utility function\nhsa_status_t ImageManagerNv::CalculateImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) const {\n  ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n  hsa_profile_t profile;\n\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  Image::TileMode tileMode = Image::TileMode::LINEAR;\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE) {\n    tileMode = (profile == HSA_PROFILE_BASE &&\n                desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)?\n      Image::TileMode::TILED : Image::TileMode::LINEAR;\n  }\n  if (GetAddrlibSurfaceInfoNv(component, desc, tileMode,\n        image_data_row_pitch, image_data_slice_pitch, out) ==\n                                                             (uint32_t)(-1)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  size_t rowPitch   = (out.bpp >> 3) * out.pitch;\n  size_t slicePitch = rowPitch * out.height;\n  if (desc.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB &&\n      image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR &&\n      ((image_data_row_pitch && (rowPitch != image_data_row_pitch)) ||\n       (image_data_slice_pitch && (slicePitch != image_data_slice_pitch)))) {\n    return static_cast<hsa_status_t>(\n                                HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED);\n  }\n\n  image_info.size = out.surfSize;\n  assert(image_info.size != 0);\n  image_info.alignment = out.baseAlign;\n  assert(image_info.alignment != 0);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool ImageManagerNv::IsLocalMemory(const void* address) const {\n  return true;\n}\n\nhsa_status_t ImageManagerNv::PopulateImageSrd(Image& image,\n                                     const metadata_amd_t* descriptor) const {\n  const metadata_amd_nv_t* desc =\n                       reinterpret_cast<const metadata_amd_nv_t*>(descriptor);\n  const void* image_data_addr = image.data;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  if ((image_prop.cap == HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED) ||\n     (image_prop.element_size == 0))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n\n  if (IsLocalMemory(image.data)) {\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  image.srd[0] = desc->word0.u32All;\n  image.srd[1] = desc->word1.u32All;\n  image.srd[2] = desc->word2.u32All;\n  image.srd[3] = desc->word3.u32All;\n  image.srd[4] = desc->word4.u32All;\n  image.srd[5] = desc->word5.u32All;\n  image.srd[6] = desc->word6.u32All;\n  image.srd[7] = desc->word7.u32All;\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = image.srd[1];\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n\n    word3.val = image.srd[3];\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[3] = word3.val;\n  } else {\n    uint32_t hwPixelSize = ImageLut().GetPixelSize(image_prop.data_format, image_prop.data_type);\n\n    if (image_prop.element_size != hwPixelSize) {\n      return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n    }\n    reinterpret_cast<SQ_IMG_RSRC_WORD0*>(&image.srd[0])->bits.BASE_ADDRESS =\n        PtrLow40Shift8(image_data_addr);\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.BASE_ADDRESS_HI =\n        PtrHigh64Shift40(image_data_addr);\n    reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1])->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_X =\n                                                                    swizzle.x;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Y =\n                                                                    swizzle.y;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_Z =\n                                                                    swizzle.z;\n    reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.DST_SEL_W =\n                                                                    swizzle.w;\n    if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n        image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1D) {\n      reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3])->bits.TYPE =\n          ImageLut().MapGeometry(image.desc.geometry);\n    }\n    \n    // Imported metadata holds the offset to metadata, add the image base address.\n    uintptr_t meta = uintptr_t(((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS_HI) << 16;\n    meta |= uintptr_t(((SQ_IMG_RSRC_WORD6*)(&image.srd[6]))->bits.META_DATA_ADDRESS) << 8;\n    meta += reinterpret_cast<uintptr_t>(image_data_addr);\n\n    ((SQ_IMG_RSRC_WORD6*)(&image.srd[6]))->bits.META_DATA_ADDRESS = PtrLow16Shift8((void*)meta);\n    ((SQ_IMG_RSRC_WORD7*)(&image.srd[7]))->bits.META_DATA_ADDRESS_HI =\n        PtrHigh64Shift16((void*)meta);\n  }\n  // Looks like this is only used for CPU copies.\n  image.row_pitch = 0;\n  image.slice_pitch = 0;\n\n  // Used by HSAIL shader ABI\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic TEX_BC_SWIZZLE GetBcSwizzle(const Swizzle& swizzle) {\n    SEL r = (SEL)swizzle.x;\n    SEL g = (SEL)swizzle.y;\n    SEL b = (SEL)swizzle.z;\n    SEL a = (SEL)swizzle.w;\n\n    TEX_BC_SWIZZLE bcSwizzle = TEX_BC_Swizzle_XYZW;\n\n    if (a == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_WZYX or TEX_BC_Swizzle_WXYZ\n        //\n        // For the pre-defined border color values (white, opaque black,\n        // transparent black), the only thing that matters is that the alpha\n        // channel winds up in the correct place (because the RGB channels are\n        // all the same) so either of these TEX_BC_Swizzle enumerations will\n        // work.  Not sure what happens with border color palettes.\n        if (b == SEL_Y) {\n            // ABGR\n            bcSwizzle = TEX_BC_Swizzle_WZYX;\n        } else if ((r == SEL_X) && (g == SEL_X) && (b == SEL_X)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // ARGB\n            bcSwizzle = TEX_BC_Swizzle_WXYZ;\n        }\n    } else if (r == SEL_X) {\n        // Have to use either TEX_BC_Swizzle_XYZW or TEX_BC_Swizzle_XWYZ\n        if (g == SEL_Y) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else if ((g == SEL_X) && (b == SEL_X) && (a == SEL_W)) {\n            // RGBA\n            bcSwizzle = TEX_BC_Swizzle_XYZW;\n        } else {\n            // RAGB\n            bcSwizzle = TEX_BC_Swizzle_XWYZ;\n        }\n    } else if (g == SEL_X) {\n        // GRAB, have to use TEX_BC_Swizzle_YXWZ\n        bcSwizzle = TEX_BC_Swizzle_YXWZ;\n    } else if (b == SEL_X) {\n        // BGRA, have to use TEX_BC_Swizzle_ZYXW\n        bcSwizzle = TEX_BC_Swizzle_ZYXW;\n    }\n\n    return bcSwizzle;\n}\n\n\nhsa_status_t ImageManagerNv::PopulateImageSrd(Image& image) const {\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  const void* image_data_addr = image.data;\n\n  if (IsLocalMemory(image.data)) {\n    image_data_addr = reinterpret_cast<const void*>(\n        reinterpret_cast<uintptr_t>(image.data) - local_memory_base_address_);\n  }\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    SQ_BUF_RSRC_WORD0 word0;\n    SQ_BUF_RSRC_WORD1 word1;\n    SQ_BUF_RSRC_WORD2 word2;\n    SQ_BUF_RSRC_WORD3 word3;\n\n    word0.val = 0;\n    word0.f.BASE_ADDRESS = PtrLow32(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh32(image_data_addr);\n    word1.f.STRIDE = image_prop.element_size;\n    word1.f.SWIZZLE_ENABLE = false;\n    word1.f.CACHE_SWIZZLE = false;\n\n    word2.f.NUM_RECORDS = image.desc.width * image_prop.element_size;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.RESOURCE_LEVEL = 1;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    word3.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    word3.f.INDEX_STRIDE = image_prop.element_size;\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n\n    image.row_pitch = image.desc.width * image_prop.element_size;\n    image.slice_pitch = image.row_pitch;\n  } else {\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD5 word6;\n    SQ_IMG_RSRC_WORD5 word7;\n\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT out = {0};\n\n    uint32_t swizzleMode = GetAddrlibSurfaceInfoNv(\n         image.component, image.desc, image.tile_mode,\n                                     image.row_pitch, image.slice_pitch, out);\n    if (swizzleMode == (uint32_t)(-1)) {\n      return HSA_STATUS_ERROR;\n    }\n\n    assert((out.bpp / 8) == image_prop.element_size);\n\n    const size_t row_pitch_size = out.pitch * image_prop.element_size;\n\n    word0.f.BASE_ADDRESS = PtrLow40Shift8(image_data_addr);\n\n    word1.val = 0;\n    word1.f.BASE_ADDRESS_HI = PtrHigh64Shift40(image_data_addr);\n    word1.f.MIN_LOD = 0;\n    word1.f.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n    // Only take the lowest 2 bits of (image.desc.width - 1)\n    word1.f.WIDTH = BitSelect<0, 1>(image.desc.width - 1);\n\n    word2.val = 0;\n    // Take the high 12 bits of (image.desc.width - 1)\n    word2.f.WIDTH_HI = BitSelect<2, 13>(image.desc.width - 1);\n    word2.f.HEIGHT = image.desc.height ? image.desc.height - 1 : 0;\n    word2.f.RESOURCE_LEVEL = 1;\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    word3.val = 0;\n    word3.f.DST_SEL_X = swizzle.x;\n    word3.f.DST_SEL_Y = swizzle.y;\n    word3.f.DST_SEL_Z = swizzle.z;\n    word3.f.DST_SEL_W = swizzle.w;\n    word3.f.SW_MODE = swizzleMode;\n    word3.f.BC_SWIZZLE = GetBcSwizzle(swizzle);\n    word3.f.TYPE = ImageLut().MapGeometry(image.desc.geometry);\n\n    const bool image_array =\n        (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DA ||\n         image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_2DADEPTH);\n    const bool image_3d = (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_3D);\n\n    word4.val = 0;\n    word4.f.DEPTH =\n        (image_array) // Doesn't hurt but isn't array_size already >0?\n            ? std::max(image.desc.array_size, static_cast<size_t>(1)) - 1\n            : (image_3d) ? image.desc.depth - 1 : 0;\n    uint32_t minor_ver = MinorVerFromDevID(chip_id_);\n    // For 1d, 2d and 2d-msaa in gfx1030 and beyond this is pitch-1\n    if ((minor_ver >= 3) && !image_array && !image_3d)\n      word4.f.PITCH = out.pitch - 1;\n\n    word5.val = 0;\n    word6.val = 0;\n    word7.val = 0;\n\n    image.srd[0] = word0.val;\n    image.srd[1] = word1.val;\n    image.srd[2] = word2.val;\n    image.srd[3] = word3.val;\n    image.srd[4] = word4.val;\n    image.srd[5] = word5.val;\n    image.srd[6] = word6.val;\n    image.srd[7] = word7.val;\n\n    image.row_pitch = row_pitch_size;\n    image.slice_pitch = out.sliceSize;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerNv::ModifyImageSrd(\n    Image& image, hsa_ext_image_format_t& new_format) const {\n  image.desc.format = new_format;\n\n  ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n  assert(image_prop.cap != HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED);\n  assert(image_prop.element_size != 0);\n\n  if (image.desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_BUF_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n    word3->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n  } else {\n    SQ_IMG_RSRC_WORD1* word1 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image.srd[1]);\n    word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, image_prop.data_type);\n\n    const Swizzle swizzle = ImageLut().MapSwizzle(image.desc.format.channel_order);\n    SQ_IMG_RSRC_WORD3* word3 =\n        reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image.srd[3]);\n    word3->bits.DST_SEL_X = swizzle.x;\n    word3->bits.DST_SEL_Y = swizzle.y;\n    word3->bits.DST_SEL_Z = swizzle.z;\n    word3->bits.DST_SEL_W = swizzle.w;\n  }\n\n  image.srd[8] = image.desc.format.channel_type;\n  image.srd[9] = image.desc.format.channel_order;\n  image.srd[10] = static_cast<uint32_t>(image.desc.width);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageManagerNv::PopulateSamplerSrd(Sampler& sampler) const {\n  const hsa_ext_sampler_descriptor_v2_t &sampler_descriptor = sampler.desc;\n\n  SQ_IMG_SAMP_WORD0 word0;\n  SQ_IMG_SAMP_WORD1 word1;\n  SQ_IMG_SAMP_WORD2 word2;\n  SQ_IMG_SAMP_WORD3 word3;\n\n  word0.u32All = 0;\n  hsa_status_t status = convertAddressMode<SQ_IMG_SAMP_WORD0, SQ_TEX_CLAMP>\n                                       (word0, sampler_descriptor.address_modes);\n  if (status != HSA_STATUS_SUCCESS) return status;\n  word0.bits.FORCE_UNNORMALIZED = (sampler_descriptor.coordinate_mode ==\n                                  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED);\n\n  word1.u32All = 0;\n  word1.bits.MAX_LOD = 4095;\n\n  word2.u32All = 0;\n  switch (sampler_descriptor.filter_mode) {\n    case HSA_EXT_SAMPLER_FILTER_MODE_NEAREST:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_POINT);\n      break;\n    case HSA_EXT_SAMPLER_FILTER_MODE_LINEAR:\n      word2.bits.XY_MAG_FILTER = static_cast<int>(SQ_TEX_XY_FILTER_BILINEAR);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  word2.bits.XY_MIN_FILTER = word2.bits.XY_MAG_FILTER;\n  word2.bits.Z_FILTER = SQ_TEX_Z_FILTER_NONE;\n  word2.bits.MIP_FILTER = SQ_TEX_MIP_FILTER_NONE;\n\n  word3.u32All = 0;\n\n  // TODO: check this bit with HSAIL spec.\n  word3.bits.BORDER_COLOR_TYPE = SQ_TEX_BORDER_COLOR_TRANS_BLACK;\n\n  sampler.srd[0] = word0.u32All;\n  sampler.srd[1] = word1.u32All;\n  sampler.srd[2] = word2.u32All;\n  sampler.srd[3] = word3.u32All;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nuint32_t ImageManagerNv::GetAddrlibSurfaceInfoNv(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    Image::TileMode tileMode,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const {\n  const ImageProperty image_prop =\n      GetImageProperty(component, desc.format, desc.geometry);\n\n  const AddrFormat addrlib_format = GetAddrlibFormat(image_prop);\n\n  const uint32_t width = static_cast<uint32_t>(desc.width);\n  const uint32_t height = static_cast<uint32_t>(desc.height);\n  static const size_t kMinNumSlice = 1;\n  const uint32_t num_slice = static_cast<uint32_t>(\n      std::max(kMinNumSlice, std::max(desc.array_size, desc.depth)));\n\n  uint32_t minor_ver = MinorVerFromDevID(chip_id_);\n  ADDR2_COMPUTE_SURFACE_INFO_INPUT in = {0};\n  in.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);\n  in.format = addrlib_format;\n  in.bpp = static_cast<unsigned int>(image_prop.element_size) * 8;\n  in.width = width;\n  in.height = height;\n  in.numSlices = num_slice;\n  // Custom Pitch is supported in gfx1030 and beyond\n  if (minor_ver >= 3)\n    in.pitchInElement = image_data_row_pitch / image_prop.element_size;\n  switch (desc.geometry) {\n    case HSA_EXT_IMAGE_GEOMETRY_1D:\n    case HSA_EXT_IMAGE_GEOMETRY_1DB:\n    case HSA_EXT_IMAGE_GEOMETRY_1DA:\n      in.resourceType = ADDR_RSRC_TEX_1D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_2D:\n    case HSA_EXT_IMAGE_GEOMETRY_2DDEPTH:\n    case HSA_EXT_IMAGE_GEOMETRY_2DA:\n    case HSA_EXT_IMAGE_GEOMETRY_2DADEPTH:\n      in.resourceType = ADDR_RSRC_TEX_2D;\n      break;\n\n    case HSA_EXT_IMAGE_GEOMETRY_3D:\n      {\n         in.resourceType = ADDR_RSRC_TEX_3D;\n         /*\n\t  * 3D swizzle modes enforce alignment\n\t  * of the number of slices  to the block depth.\n\t  * If numSlices = 3 then the 3 slices are\n\t  * interleaved for 3D locality among the 8 slices\n\t  * that make up each block. This causes the memory\n\t  * footprint to jump from an ideal size to 3x the size.\n\t  * 'enable3DSwizzleMode' flag tests for env variable\n\t  * HSA_IMAGE_ENABLE_3D_SWIZZLE_DEBUG to enable or disable\n\t  * 3D swizzle:\n\t  * true: Keep view3dAs2dArray = 0 for real 3D interleaving.\n\t  * false: Use view3dAs2dArray = 1 to avoid the alignment\n\t  *       expansion.\n\t  * 2D swizzle modes can lower size overhead but may yield\n\t  * suboptimal cache behavior for fully 3D volumetric\n\t  * operations.\n\t  */\n\t  bool enable3DSwizzleMode = core::Runtime::runtime_singleton_->flag().enable_3d_swizzle();\n\t  if (enable3DSwizzleMode)\n\t      in.flags.view3dAs2dArray = 0;\n\t  else\n\t      in.flags.view3dAs2dArray = 1;\n\n\t  break;\n      }\n  }\n  in.flags.texture = 1;\n\n  ADDR2_GET_PREFERRED_SURF_SETTING_INPUT  prefSettingsInput = { 0 };\n  ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT prefSettingsOutput = { 0 };\n\n  prefSettingsInput.size            = sizeof(prefSettingsInput);\n  prefSettingsInput.flags           = in.flags;\n  prefSettingsInput.bpp             = in.bpp;\n  prefSettingsInput.format          = in.format;\n  prefSettingsInput.width           = in.width;\n  prefSettingsInput.height          = in.height;\n  prefSettingsInput.numFrags        = in.numFrags;\n  prefSettingsInput.numSamples      = in.numSamples;\n  prefSettingsInput.numMipLevels    = in.numMipLevels;\n  prefSettingsInput.numSlices       = in.numSlices;\n  prefSettingsInput.resourceLoction = ADDR_RSRC_LOC_UNDEF;\n  prefSettingsInput.resourceType    = in.resourceType;\n\n  // Disallow all swizzles but linear.\n  if (tileMode == Image::TileMode::LINEAR) {\n      prefSettingsInput.forbiddenBlock.macroThin4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick4KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThin64KB = 1;\n      prefSettingsInput.forbiddenBlock.macroThick64KB = 1;\n      prefSettingsInput.forbiddenBlock.micro = 1;\n      prefSettingsInput.forbiddenBlock.var = 1;\n  }\n\n  // but don't ever allow the 256b swizzle modes\n  //prefSettingsInput.forbiddenBlock.micro = 1;\n  // and don't allow variable-size block modes\n  //prefSettingsInput.forbiddenBlock.var = 1;\n\n  if (ADDR_OK != Addr2GetPreferredSurfaceSetting(addr_lib_,\n                                   &prefSettingsInput, &prefSettingsOutput)) {\n    return (uint32_t)(-1);\n  }\n\n  in.swizzleMode = prefSettingsOutput.swizzleMode;\n\n  out.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);\n  if (ADDR_OK != Addr2ComputeSurfaceInfo(addr_lib_, &in, &out)) {\n    return (uint32_t)(-1);\n  }\n  if (out.surfSize == 0) {\n    return (uint32_t)(-1);\n  }\n\n  return in.swizzleMode;\n}\n\nhsa_status_t ImageManagerNv::FillImage(const Image& image, const void* pattern,\n                                       const hsa_ext_image_region_t& region) {\n  if (BlitQueueInit().queue_ == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n\n  Image* image_view = const_cast<Image*>(&image);\n\n  SQ_BUF_RSRC_WORD3* word3_buff = NULL;\n  SQ_IMG_RSRC_WORD3* word3_image = NULL;\n  uint32_t dst_sel_w_original = 0;\n  if (image_view->desc.format.channel_type ==\n      HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010) {\n    // Force GPU to ignore the last two bits (alpha bits).\n    if (image_view->desc.geometry == HSA_EXT_IMAGE_GEOMETRY_1DB) {\n      word3_buff = reinterpret_cast<SQ_BUF_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_buff->bits.DST_SEL_W;\n      word3_buff->bits.DST_SEL_W = SEL_0;\n    } else {\n      word3_image = reinterpret_cast<SQ_IMG_RSRC_WORD3*>(&image_view->srd[3]);\n      dst_sel_w_original = word3_image->bits.DST_SEL_W;\n      word3_image->bits.DST_SEL_W = SEL_0;\n    }\n  }\n\n  SQ_IMG_RSRC_WORD1* word1 = NULL;\n  uint32_t num_format_original = 0;\n  const void* new_pattern = pattern;\n  float fill_value[4] = {0};\n  switch (image_view->desc.format.channel_order) {\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX:\n    case HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA: {\n      // KV and CZ don't have write support for SRGBA image, so convert pattern\n      // to standard form and treat the image as RGBA image.\n      const float* pattern_f = reinterpret_cast<const float*>(pattern);\n      fill_value[0] = LinearToStandardRGB(pattern_f[0]);\n      fill_value[1] = LinearToStandardRGB(pattern_f[1]);\n      fill_value[2] = LinearToStandardRGB(pattern_f[2]);\n      fill_value[3] = pattern_f[3];\n      new_pattern = fill_value;\n\n      ImageProperty image_prop = ImageLut().MapFormat(image.desc.format, image.desc.geometry);\n\n      word1 = reinterpret_cast<SQ_IMG_RSRC_WORD1*>(&image_view->srd[1]);\n      num_format_original = word1->bits.FORMAT;\n      word1->bits.FORMAT = GetCombinedFormat(image_prop.data_format, TYPE_UNORM);\n    } break;\n    default:\n      break;\n  }\n\n  hsa_status_t status = ImageRuntime::instance()->blit_kernel().FillImage(\n      blit_queue_, blit_code_catalog_, *image_view, new_pattern, region);\n\n  // Revert back original configuration.\n  if (word3_buff != NULL) {\n    word3_buff->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word3_image != NULL) {\n    word3_image->bits.DST_SEL_W = dst_sel_w_original;\n  }\n\n  if (word1 != NULL) {\n    word1->bits.FORMAT = num_format_original;\n  }\n\n  return status;\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_manager_nv.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_IMAGE_MANAGER_NV_H_ \n#define EXT_IMAGE_IMAGE_MANAGER_NV_H_ \n\n#include \"addrlib/inc/addrinterface.h\"\n#include \"image_manager_kv.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageManagerNv : public ImageManagerKv {\n public:\n  ImageManagerNv();\n  virtual ~ImageManagerNv();\n\n  /// @brief Calculate the size and alignment of the backing storage of an\n  /// image.\n  virtual hsa_status_t CalculateImageSizeAndAlignment(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch, size_t image_data_slice_pitch,\n      hsa_ext_image_data_info_t& image_info) const;\n\n  /// @brief Fill image structure with device specific image object.\n  virtual hsa_status_t PopulateImageSrd(Image& image) const;\n\n  /// @brief Fill image structure with device specific image object using the given format.\n  virtual hsa_status_t PopulateImageSrd(Image& image, const metadata_amd_t* desc) const;\n\n  /// @brief Modify device specific image object according to the specified\n  /// new format.\n  virtual hsa_status_t ModifyImageSrd(Image& image,\n                                      hsa_ext_image_format_t& new_format) const;\n\n  /// @brief Fill sampler structure with device specific sampler object.\n  virtual hsa_status_t PopulateSamplerSrd(Sampler& sampler) const;\n\n  /// @brief Fill image backing storage using agent copy.\n  virtual hsa_status_t FillImage(const Image& image, const void* pattern,\n                                 const hsa_ext_image_region_t& region);\n protected:\n  uint32_t GetAddrlibSurfaceInfoNv(hsa_agent_t component,\n                             const hsa_ext_image_descriptor_t& desc,\n                             Image::TileMode tileMode,\n                             size_t image_data_row_pitch,\n                             size_t image_data_slice_pitch,\n                             ADDR2_COMPUTE_SURFACE_INFO_OUTPUT& out) const;\n\n  bool IsLocalMemory(const void* address) const;\n\n private:\n  DISALLOW_COPY_AND_ASSIGN(ImageManagerNv);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_IMAGE_MANAGER_NV_H_ \n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_runtime.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#define NOMINMAX\n#include \"image_runtime.h\"\n\n#include <assert.h>\n#include <climits>\n#include <mutex>\n\n#include \"core/inc/runtime.h\"\n#include \"core/inc/hsa_internal.h\"\n#include \"core/inc/hsa_ext_amd_impl.h\"\n#include \"resource.h\"\n#include \"image_manager_kv.h\"\n#include \"image_manager_ai.h\"\n#include \"image_manager_nv.h\"\n#include \"image_manager_gfx11.h\"\n#include \"image_manager_gfx12.h\"\n#include \"device_info.h\"\n\nnamespace rocr {\nnamespace image {\n\nhsa_status_t FindKernelArgPool(hsa_amd_memory_pool_t pool, void* data) {\n  assert(data != nullptr);\n\n  hsa_status_t err;\n  hsa_amd_segment_t segment;\n  uint32_t flag;\n  size_t size;\n\n  err = AMD::hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT, &segment);\n  assert(err == HSA_STATUS_SUCCESS);\n\n  if (segment != HSA_AMD_SEGMENT_GLOBAL) return HSA_STATUS_SUCCESS;\n\n  err = AMD::hsa_amd_memory_pool_get_info(\n      pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &flag);\n  assert(err == HSA_STATUS_SUCCESS);\n\n  err = AMD::hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE, &size);\n  assert(err == HSA_STATUS_SUCCESS);\n\n  if (((HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT & flag) == 1) && (size != 0)) {\n    *(reinterpret_cast<hsa_amd_memory_pool_t*>(data)) = pool;\n    // Found the kernarg pool, stop the iteration.\n    return HSA_STATUS_INFO_BREAK;\n    }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::CreateImageManager(hsa_agent_t agent, void* data) {\n  ImageRuntime* runtime = reinterpret_cast<ImageRuntime*>(data);\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code =\n      HSA::hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &hsa_device_type);\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_GPU) {\n\n    uint32_t chip_id;\n    hsa_error_code = GetGPUAsicID(agent, &chip_id);\n    uint32_t major_ver = MajorVerFromDevID(chip_id);\n\n    ImageManager* image_manager;\n\n    switch (major_ver) {\n    case 12:\n      image_manager = new ImageManagerGfx12();\n      break;\n    case 11:\n      image_manager = new ImageManagerGfx11();\n      break;\n    case 10:\n      image_manager = new ImageManagerNv();\n      break;\n    case  9:\n      image_manager = new ImageManagerAi();\n      break;\n    default:\n      image_manager = new ImageManagerKv();\n      break;\n    }\n    hsa_error_code = image_manager->Initialize(agent);\n\n    if (hsa_error_code != HSA_STATUS_SUCCESS) {\n      delete image_manager;\n      return hsa_error_code;\n    }\n\n    runtime->image_managers_[agent.handle] = image_manager;\n  } else if (hsa_device_type == HSA_DEVICE_TYPE_CPU) {\n    uint32_t caches[4] = {0};\n    hsa_error_code = HSA::hsa_agent_get_info(agent, HSA_AGENT_INFO_CACHE_SIZE, caches);\n\n    if (hsa_error_code != HSA_STATUS_SUCCESS) {\n      return hsa_error_code;\n    }\n\n    runtime->cpu_l2_cache_size_ = caches[1];\n\n    if (runtime->kernarg_pool_.handle == 0)\n      hsa_amd_agent_iterate_memory_pools(agent, FindKernelArgPool, &runtime->kernarg_pool_);\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nImageRuntime* ImageRuntime::instance() {\n  ImageRuntime* instance = get_instance().load(std::memory_order_acquire);\n  if (instance == NULL) {\n    // Protect the initialization from multi threaded access.\n    std::lock_guard<std::mutex> lock(instance_mutex());\n\n    // Make sure we are not initializing it twice.\n    instance = get_instance().load(std::memory_order_relaxed);\n    if (instance != NULL) {\n      return instance;\n    }\n\n    instance = CreateSingleton();\n    if (instance == NULL) {\n      return NULL;\n    }\n\n    // UnloadCallback = &ext_image::ImageRuntime::DestroySingleton;\n  }\n\n  return instance;\n}\n\nImageRuntime* ImageRuntime::CreateSingleton() {\n  ImageRuntime* instance = new ImageRuntime();\n\n  if (HSA_STATUS_SUCCESS != instance->blit_kernel_.Initialize()) {\n    instance->Cleanup();\n    delete instance;\n    return NULL;\n  }\n\n  if (HSA_STATUS_SUCCESS != HSA::hsa_iterate_agents(CreateImageManager, instance)) {\n    instance->Cleanup();\n    delete instance;\n    return NULL;\n  }\n\n  assert(instance->kernarg_pool_.handle != 0);\n  assert(instance->image_managers_.size() != 0);\n\n  get_instance().store(instance, std::memory_order_release);\n  return instance;\n}\n\nvoid ImageRuntime::DestroySingleton() {\n  ImageRuntime* instance = get_instance().load(std::memory_order_acquire);\n  if (instance == NULL) {\n    return;\n  }\n\n  instance->Cleanup();\n\n  get_instance().store(NULL, std::memory_order_release);\n  delete instance;\n}\n\nhsa_status_t ImageRuntime::GetImageInfoMaxDimension(hsa_agent_t component,\n                                                    hsa_agent_info_t attribute,\n                                                    void* value) {\n  uint32_t* value_u32 = NULL;\n  uint32_t* value_u32_v2 = NULL;\n  uint32_t* value_u32_v3 = NULL;\n\n  hsa_ext_image_geometry_t geometry;\n\n  size_t image_attribute = static_cast<size_t>(attribute);\n  switch (image_attribute) {\n    case HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_1D;\n      value_u32 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_1DA_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_1DA;\n      value_u32 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_1DB_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_1DB;\n      value_u32 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_2D_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_2D;\n      value_u32_v2 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_2DA_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_2DA;\n      value_u32_v2 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_2DDEPTH_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_2DDEPTH;\n      value_u32_v2 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_2DADEPTH_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_2DADEPTH;\n      value_u32_v2 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_3D_MAX_ELEMENTS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_3D;\n      value_u32_v3 = static_cast<uint32_t*>(value);\n      break;\n    case HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS:\n      geometry = HSA_EXT_IMAGE_GEOMETRY_2DA;\n      value_u32 = static_cast<uint32_t*>(value);\n      break;\n    default:\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  uint32_t width = 0;\n  uint32_t height = 0;\n  uint32_t depth = 0;\n  uint32_t array_size = 0;\n\n  hsa_device_type_t device_type;\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_DEVICE, &device_type);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  // Image is only supported on a GPU device.\n\n  if (device_type == HSA_DEVICE_TYPE_GPU) {\n    image_manager(component)->GetImageInfoMaxDimension(\n        component, geometry, width, height, depth, array_size);\n  }\n\n  if (value_u32_v3 != NULL) {\n    value_u32_v3[0] = width;\n    value_u32_v3[1] = height;\n    value_u32_v3[2] = depth;\n  } else if (value_u32_v2 != NULL) {\n    value_u32_v2[0] = width;\n    value_u32_v2[1] = height;\n  } else {\n    *value_u32 = (image_attribute == HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS)\n                     ? array_size\n                     : width;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::GetImageCapability(\n    hsa_agent_t component, const hsa_ext_image_format_t& format,\n    hsa_ext_image_geometry_t geometry, uint32_t& capability) {\n  hsa_device_type_t device_type;\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_DEVICE, &device_type);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  if (device_type == HSA_DEVICE_TYPE_GPU) {\n    ImageManager* manager = image_manager(component);\n    capability = manager->GetImageProperty(component, format, geometry).cap;\n  } else {\n    // Image is only supported on a GPU device.\n    capability = 0;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::GetImageSizeAndAlignment(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& desc,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t& image_info) {\n  image_info.alignment = 0;\n  image_info.size = 0;\n\n  // Validate the image format and geometry.\n  uint32_t capability = 0;\n  hsa_status_t status =\n      GetImageCapability(component, desc.format, desc.geometry, capability);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  if (capability == 0) {\n    return static_cast<hsa_status_t>(\n        HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED);\n  }\n\n  const hsa_ext_image_geometry_t geometry = desc.geometry;\n  uint32_t max_width = 0;\n  uint32_t max_height = 0;\n  uint32_t max_depth = 0;\n  uint32_t max_array_size = 0;\n\n  ImageManager* manager = image_manager(component);\n\n  // Validate the image dimension.\n  manager->GetImageInfoMaxDimension(component, geometry, max_width, max_height,\n                                    max_depth, max_array_size);\n\n  if (desc.width > max_width || desc.height > max_height ||\n      desc.depth > max_depth || desc.array_size > max_array_size) {\n    return static_cast<hsa_status_t>(\n        HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED);\n  }\n\n  return manager->CalculateImageSizeAndAlignment(component, desc,\n    image_data_layout, image_data_row_pitch, image_data_slice_pitch, image_info);\n}\n\nhsa_status_t ImageRuntime::CreateImageHandle(\n    hsa_agent_t component, const hsa_ext_image_descriptor_t& image_descriptor,\n    const void* image_data, const hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_t& image_handle) {\n  image_handle.handle = 0;\n\n  assert(image_data != NULL);\n\n  // Validate image dimension.\n  hsa_ext_image_data_info_t image_info = {0};\n  hsa_status_t status =\n      GetImageSizeAndAlignment(component, image_descriptor,\n        image_data_layout, image_data_row_pitch, image_data_slice_pitch,\n        image_info);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  // Validate image address alignment.\n  if (!IsMultipleOf(reinterpret_cast<size_t>(image_data),\n                    image_info.alignment)) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  Image* image = Image::Create(component);\n  image->component = component;\n  image->desc = image_descriptor;\n  image->permission = access_permission;\n  image->data = const_cast<void*>(image_data);\n  image->row_pitch = image_data_row_pitch;\n  image->slice_pitch = image_data_slice_pitch;\n  hsa_profile_t profile;\n  status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_PROFILE, &profile);\n\n  if (image_data_layout == HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR) {\n    image->tile_mode = Image::TileMode::LINEAR;\n  } else {\n    Image::TileMode tileMode =\n        (profile == HSA_PROFILE_BASE && image_descriptor.geometry != HSA_EXT_IMAGE_GEOMETRY_1DB)\n        ? Image::TileMode::TILED\n        : Image::TileMode::LINEAR;\n    image->tile_mode = tileMode;\n  }\n\n  image_manager(component)->PopulateImageSrd(*image);\n\n  if (core::Runtime::runtime_singleton_->flag().image_print_srd()) image->printSRD();\n\n  image_handle.handle = image->Convert();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::CreateImageHandleWithLayout(\n  hsa_agent_t component, const hsa_ext_image_descriptor_t& image_descriptor,\n  const hsa_amd_image_descriptor_t* image_layout,\n  const void* image_data, const hsa_access_permission_t access_permission,\n  hsa_ext_image_t& image_handle)\n{\n  if(!IsMultipleOf(image_data, 256))\n    return HSA_STATUS_ERROR_INVALID_ALLOCATION;\n\n  if(image_layout->version!=1)\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n  \n  uint32_t id;\n  HSA::hsa_agent_get_info(component, (hsa_agent_info_t)HSA_AMD_AGENT_INFO_CHIP_ID, &id);\n\n  if(image_layout->deviceID!=(0x1002<<16|id))\n    return (hsa_status_t)HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED;\n\n  const metadata_amd_t* desc = reinterpret_cast<const metadata_amd_t*>(image_layout);\n\n  Image* image = Image::Create(component);\n  image->component = component;\n  image->desc = image_descriptor;\n  image->permission = access_permission;\n  image->data = const_cast<void*>(image_data);\n  image->tile_mode = Image::TILED;\n  hsa_status_t err=image_manager(component)->PopulateImageSrd(*image, desc);\n  if(err!=HSA_STATUS_SUCCESS) {\n    Image::Destroy(image);\n    return err;\n  }\n\n  if (core::Runtime::runtime_singleton_->flag().image_print_srd()) image->printSRD();\n\n  image_handle.handle = image->Convert();\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::DestroyImageHandle(\n    const hsa_ext_image_t& image_handle) {\n  const Image* image = Image::Convert(image_handle.handle);\n\n  if (image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  Image::Destroy(const_cast<Image*>(image));\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::CopyBufferToImage(\n    const void* src_memory, size_t src_row_pitch, size_t src_slice_pitch,\n    const hsa_ext_image_t& dst_image_handle,\n    const hsa_ext_image_region_t& image_region) {\n  const Image* dst_image = Image::Convert(dst_image_handle.handle);\n\n  if (dst_image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  ImageManager* manager = image_manager(dst_image->component);\n  return manager->CopyBufferToImage(src_memory, src_row_pitch, src_slice_pitch,\n                                    *dst_image, image_region);\n}\n\nhsa_status_t ImageRuntime::CopyImageToBuffer(\n    const hsa_ext_image_t& src_image_handle, void* dst_memory,\n    size_t dst_row_pitch, size_t dst_slice_pitch,\n    const hsa_ext_image_region_t& image_region) {\n  const Image* src_image = Image::Convert(src_image_handle.handle);\n\n  if (src_image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  ImageManager* manager = image_manager(src_image->component);\n  return manager->CopyImageToBuffer(*src_image, dst_memory, dst_row_pitch,\n                                    dst_slice_pitch, image_region);\n}\n\nhsa_status_t ImageRuntime::CopyImage(const hsa_ext_image_t& src_image_handle,\n                                     const hsa_ext_image_t& dst_image_handle,\n                                     const hsa_dim3_t& src_origin,\n                                     const hsa_dim3_t& dst_origin,\n                                     const hsa_dim3_t size) {\n  const Image* src_image = Image::Convert(src_image_handle.handle);\n\n  if (src_image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  const Image* dst_image = Image::Convert(dst_image_handle.handle);\n\n  if (dst_image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  if (src_image->component.handle != dst_image->component.handle) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  ImageManager* manager = image_manager(src_image->component);\n  return manager->CopyImage(*dst_image, *src_image, dst_origin, src_origin,\n                            size);\n}\n\nhsa_status_t ImageRuntime::FillImage(\n    const hsa_ext_image_t& image_handle, const void* pattern,\n    const hsa_ext_image_region_t& image_region) {\n  const Image* image = Image::Convert(image_handle.handle);\n\n  if (image == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  ImageManager* manager = image_manager(image->component);\n  return manager->FillImage(*image, pattern, image_region);\n}\n\nhsa_status_t ImageRuntime::CreateSamplerHandle(\n    hsa_agent_t component,\n    const hsa_ext_sampler_descriptor_v2_t& sampler_descriptor,\n    hsa_ext_sampler_t& sampler_handle) {\n  sampler_handle.handle = 0;\n\n  hsa_device_type_t device_type;\n  hsa_status_t status = HSA::hsa_agent_get_info(component, HSA_AGENT_INFO_DEVICE, &device_type);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  // Sampler is only supported on a GPU device.\n  if (device_type != HSA_DEVICE_TYPE_GPU) {\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  Sampler* sampler = Sampler::Create(component);\n  if (sampler == NULL) {\n    return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n  }\n  sampler->component = component;\n  sampler->desc = sampler_descriptor;\n\n  image_manager(component)->PopulateSamplerSrd(*sampler);\n\n  sampler_handle.handle = sampler->Convert();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ImageRuntime::DestroySamplerHandle(\n    hsa_ext_sampler_t& sampler_handle) {\n  const Sampler* sampler = Sampler::Convert(sampler_handle.handle);\n\n  if (sampler == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  Sampler::Destroy(sampler);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nImageRuntime::ImageRuntime()\n    : cpu_l2_cache_size_(0), kernarg_pool_({0}) {}\n\nImageRuntime::~ImageRuntime() {}\n\nvoid ImageRuntime::Cleanup() {\n  std::map<uint64_t, ImageManager*>::iterator it;\n  for (it = image_managers_.begin(); it != image_managers_.end(); ++it) {\n    it->second->Cleanup();\n    delete it->second;\n  }\n\n  blit_kernel_.Cleanup();\n}\n\n}  // namespace image\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/image/image_runtime.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_IMAGE_RUNTIME_H\n#define HSA_RUNTIME_EXT_IMAGE_IMAGE_RUNTIME_H\n\n#include <atomic>\n#include <map>\n#include <mutex>\n\n#include \"inc/hsa.h\"\n\n#include \"inc/hsa_ext_image.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"blit_kernel.h\"\n#include \"image_manager.h\"\n#include \"util.h\"\n\nnamespace rocr {\nnamespace image {\n\nclass ImageRuntime {\n public:\n  /// @brief Getter for the ImageRuntime singleton object.\n  static ImageRuntime* instance();\n\n  /// @brief Destroy singleton object.\n  static void DestroySingleton();\n\n  /// @brief Retrieve maximum size of width, height, depth, array size in pixels\n  /// for a particular geometry on a component.\n  hsa_status_t GetImageInfoMaxDimension(hsa_agent_t component,\n                                        hsa_agent_info_t attribute,\n                                        void* value);\n\n  /// @brief Query image support with particular format and geometry.\n  hsa_status_t GetImageCapability(hsa_agent_t component,\n                                  const hsa_ext_image_format_t& format,\n                                  hsa_ext_image_geometry_t geometry,\n                                  uint32_t& capability);\n\n  /// @brief Query the size and address alignment of the backing storage of\n  /// the image.\n  hsa_status_t GetImageSizeAndAlignment(hsa_agent_t component,\n                                        const hsa_ext_image_descriptor_t& desc,\n                                        hsa_ext_image_data_layout_t image_data_layout,\n                                        size_t image_data_row_pitch,\n                                        size_t image_data_slice_pitch,\n                                        hsa_ext_image_data_info_t& image_info);\n\n  /// @brief Create device image object and return its handle.\n  hsa_status_t CreateImageHandle(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& image_descriptor,\n      const void* image_data, const hsa_access_permission_t access_permission,\n      hsa_ext_image_data_layout_t image_data_layout,\n      size_t image_data_row_pitch,\n      size_t image_data_slice_pitch,\n      hsa_ext_image_t& image);\n\n  /// @brief Create device image object and return its handle.\n  hsa_status_t CreateImageHandleWithLayout(\n      hsa_agent_t component, const hsa_ext_image_descriptor_t& image_descriptor,\n      const hsa_amd_image_descriptor_t* image_layout,\n      const void* image_data, const hsa_access_permission_t access_permission,\n      hsa_ext_image_t& image);\n\n  /// @brief Destroy the device image object referenced by the handle.\n  hsa_status_t DestroyImageHandle(const hsa_ext_image_t& image);\n\n  /// @brief Copy the content of a linear memory to an image object.\n  hsa_status_t CopyBufferToImage(const void* src_memory, size_t src_row_pitch,\n                                 size_t src_slice_pitch,\n                                 const hsa_ext_image_t& dst_image,\n                                 const hsa_ext_image_region_t& image_region);\n\n  /// @brief Copy the content of an image object to a linear memory.\n  hsa_status_t CopyImageToBuffer(const hsa_ext_image_t& src_image,\n                                 void* dst_memory, size_t dst_row_pitch,\n                                 size_t dst_slice_pitch,\n                                 const hsa_ext_image_region_t& image_region);\n\n  /// @brief Copy the content of an image object to another image object.\n  hsa_status_t CopyImage(const hsa_ext_image_t& src_image,\n                         const hsa_ext_image_t& dst_image,\n                         const hsa_dim3_t& src_origin,\n                         const hsa_dim3_t& dst_origin, const hsa_dim3_t size);\n\n  /// @brief Fill the content of an image object with a pattern.\n  hsa_status_t FillImage(const hsa_ext_image_t& image, const void* pattern,\n                         const hsa_ext_image_region_t& image_region);\n\n  /// @brief Create device sampler object and return its handle.\n  hsa_status_t CreateSamplerHandle(\n      hsa_agent_t component,\n      const hsa_ext_sampler_descriptor_v2_t& sampler_descriptor,\n      hsa_ext_sampler_t& sampler);\n\n  /// @brief Destroy the device sampler object referenced by the handle.\n  hsa_status_t DestroySamplerHandle(hsa_ext_sampler_t& sampler);\n\n  ImageManager* image_manager(hsa_agent_t agent) {\n    std::map<uint64_t, ImageManager*>::iterator it = image_managers_.find(agent.handle);\n    return (it != image_managers_.end()) ? it->second : NULL;\n  }\n\n  BlitKernel& blit_kernel() { return blit_kernel_; }\n\n  size_t cpu_l2_cache_size() const { return cpu_l2_cache_size_; }\n\n  hsa_amd_memory_pool_t kernarg_pool() const {\n    return kernarg_pool_;\n  }\n\n private:\n  /// @brief Initialize singleton object, must be called once.\n  static ImageRuntime* CreateSingleton();\n\n  static hsa_status_t CreateImageManager(hsa_agent_t agent, void* data);\n\n  ImageRuntime();\n\n  ~ImageRuntime();\n\n  void Cleanup();\n\n  /// Pointer to singleton object.\n  static __forceinline std::atomic<ImageRuntime*>& get_instance() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static std::atomic<ImageRuntime*>* instance_ = new std::atomic<ImageRuntime*>();\n    return *instance_;\n  }\n\n  static __forceinline std::mutex& instance_mutex() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static std::mutex* instance_mutex_ = new std::mutex();\n    return *instance_mutex_;\n  }\n\n  /// @brief Contains mapping of agent and its corresponding ::ImageManager\n  ///        object.\n  std::map<uint64_t, ImageManager*> image_managers_;\n\n  /// @brief Manages kernel for accessing images.\n  BlitKernel blit_kernel_;\n\n  size_t cpu_l2_cache_size_;\n\n  hsa_amd_memory_pool_t kernarg_pool_;\n\n  DISALLOW_COPY_AND_ASSIGN(ImageRuntime);\n};\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_IMAGE_RUNTIME_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/inc/hsa_ext_image_impl.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2020-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_H\n#define HSA_RUNTIME_EXT_IMAGE_H\n\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"core/inc/hsa_ext_interface.h\"\n\n//---------------------------------------------------------------------------//\n//  APIs that implement Image functionality\n//---------------------------------------------------------------------------//\n\nnamespace rocr {\nnamespace image {\n\nhsa_status_t hsa_amd_image_get_info_max_dim(hsa_agent_t agent, hsa_agent_info_t attribute,\n                                            void* value);\n\nhsa_status_t hsa_ext_image_get_capability(hsa_agent_t agent,\n                                          hsa_ext_image_geometry_t image_geometry,\n                                          const hsa_ext_image_format_t* image_format,\n                                          uint32_t* capability_mask);\n\nhsa_status_t hsa_ext_image_data_get_info(hsa_agent_t agent,\n                                         const hsa_ext_image_descriptor_t* image_descriptor,\n                                         hsa_access_permission_t access_permission,\n                                         hsa_ext_image_data_info_t* image_data_info);\n\nhsa_status_t hsa_ext_image_create(hsa_agent_t agent,\n                                  const hsa_ext_image_descriptor_t* image_descriptor,\n                                  const void* image_data, hsa_access_permission_t access_permission,\n                                  hsa_ext_image_t* image);\n\nhsa_status_t hsa_ext_image_destroy(hsa_agent_t agent, hsa_ext_image_t image);\n\nhsa_status_t hsa_ext_image_copy(hsa_agent_t agent, hsa_ext_image_t src_image,\n                                const hsa_dim3_t* src_offset, hsa_ext_image_t dst_image,\n                                const hsa_dim3_t* dst_offset, const hsa_dim3_t* range);\n\nhsa_status_t hsa_ext_image_import(hsa_agent_t agent, const void* src_memory, size_t src_row_pitch,\n                                  size_t src_slice_pitch, hsa_ext_image_t dst_image,\n                                  const hsa_ext_image_region_t* image_region);\n\nhsa_status_t hsa_ext_image_export(hsa_agent_t agent, hsa_ext_image_t src_image, void* dst_memory,\n                                  size_t dst_row_pitch, size_t dst_slice_pitch,\n                                  const hsa_ext_image_region_t* image_region);\n\nhsa_status_t hsa_ext_image_clear(hsa_agent_t agent, hsa_ext_image_t image, const void* data,\n                                 const hsa_ext_image_region_t* image_region);\n\nhsa_status_t hsa_ext_sampler_create(hsa_agent_t agent,\n                                    const hsa_ext_sampler_descriptor_t* sampler_descriptor,\n                                    hsa_ext_sampler_t* sampler);\n\nhsa_status_t hsa_ext_sampler_create_v2(hsa_agent_t agent,\n                                    const hsa_ext_sampler_descriptor_v2_t* sampler_descriptor,\n                                    hsa_ext_sampler_t* sampler);\n\nhsa_status_t hsa_ext_sampler_destroy(hsa_agent_t agent, hsa_ext_sampler_t sampler);\n\nhsa_status_t hsa_ext_image_get_capability_with_layout(hsa_agent_t agent,\n                                                      hsa_ext_image_geometry_t image_geometry,\n                                                      const hsa_ext_image_format_t* image_format,\n                                                      hsa_ext_image_data_layout_t image_data_layout,\n                                                      uint32_t* capability_mask);\n\nhsa_status_t hsa_ext_image_data_get_info_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor,\n    hsa_access_permission_t access_permission, hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch, size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t* image_data_info);\n\nhsa_status_t hsa_ext_image_create_with_layout(\n    hsa_agent_t agent, const hsa_ext_image_descriptor_t* image_descriptor, const void* image_data,\n    hsa_access_permission_t access_permission, hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch, size_t image_data_slice_pitch, hsa_ext_image_t* image);\n\nhsa_status_t hsa_amd_image_create(hsa_agent_t agent,\n                                  const hsa_ext_image_descriptor_t* image_descriptor,\n                                  const hsa_amd_image_descriptor_t* image_layout,\n                                  const void* image_data, hsa_access_permission_t access_permission,\n                                  hsa_ext_image_t* image);\n\n// Update Api table with func pointers that implement functionality\nvoid LoadImage(core::ImageExtTableInternal* image_api,\n               decltype(::hsa_amd_image_create)** interface_api);\n\n// Release resources acquired by Image implementation\nvoid ReleaseImageRsrcs();\n\n}  // namespace image\n}  // namespace rocr\n\n#endif  //  HSA_RUNTIME_EXT_IMAGE_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_RESOURCE_H\n#define HSA_RUNTIME_EXT_IMAGE_RESOURCE_H\n\n#include <stdint.h>\n\n#include <cstring>\n\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_image.h\"\n\n#include \"util.h\"\n\n#define HSA_IMAGE_OBJECT_SIZE_DWORD 12\n#define HSA_IMAGE_OBJECT_ALIGNMENT 16\n\n#define HSA_SAMPLER_OBJECT_SIZE_DWORD 8\n#define HSA_SAMPLER_OBJECT_ALIGNMENT 16\n\n#define GEOMETRY_COUNT 8\n#define ORDER_COUNT 20\n#define TYPE_COUNT 16\n#define RO HSA_EXT_IMAGE_CAPABILITY_READ_ONLY\n#define ROWO \\\n  (HSA_EXT_IMAGE_CAPABILITY_READ_ONLY | HSA_EXT_IMAGE_CAPABILITY_WRITE_ONLY)\n#define RW                                                                    \\\n  (HSA_EXT_IMAGE_CAPABILITY_READ_ONLY | HSA_EXT_IMAGE_CAPABILITY_WRITE_ONLY | \\\n  HSA_EXT_IMAGE_CAPABILITY_READ_WRITE)\n\nnamespace rocr {\nnamespace image {\n\ntypedef struct metadata_amd_s {\n    uint32_t version; // Must be 1\n    uint32_t vendorID; // AMD | CZ\n    uint32_t words[8];\n    uint32_t mip_offsets[0]; //Mip level offset bits [39:8] for each level (if any)\n} metadata_amd_t;\n\n/// @brief Structure to represent image access component.\ntypedef struct Swizzle {\n  uint8_t x;\n  uint8_t y;\n  uint8_t z;\n  uint8_t w;\n} Swizzle;\n\n/// @brief Structure to contain the property of an image with a particular\n/// format and geometry.\ntypedef struct ImageProperty {\n  uint8_t cap;           // hsa_ext_image_format_capability_t mask.\n  uint8_t element_size;  // size per pixel in bytes.\n  uint8_t data_format;   // device specific channel ordering.\n  uint8_t data_type;     // device specific channel type.\n} ImageProperty;\n\n/// @brief Structure to represent an HSA image object.\ntypedef struct Image {\nprivate:\n  Image() {\n    component.handle = 0;\n    permission = HSA_ACCESS_PERMISSION_RO;\n    data = NULL;\n    std::memset(srd, 0, sizeof(srd));\n    std::memset(&desc, 0, sizeof(desc));\n    row_pitch = slice_pitch = 0;\n    tile_mode = LINEAR;\n  }\n\n  ~Image() {}\n\npublic:\n  typedef enum TileMode {\n    LINEAR,\n    TILED\n  } TileMode;\n\n  /// @brief Create an Image.\n  static Image* Create(hsa_agent_t agent);\n\n  /// @brief Destroy an Image.\n  static void Destroy(const Image* image);\n\n  /// @brief Convert from vendor representation to HSA handle.\n  uint64_t Convert() const { return reinterpret_cast<uint64_t>(srd); }\n\n  /// @brief Convert from HSA handle to vendor representation.\n  static Image* Convert(uint64_t handle) {\n    return reinterpret_cast<Image*>(handle - offsetof(Image, srd));\n  }\n\n  // Vendor specific image object.\n  __ALIGNED__(\n      HSA_IMAGE_OBJECT_ALIGNMENT) uint32_t srd[HSA_IMAGE_OBJECT_SIZE_DWORD];\n\n  void const printSRD() const {\n    char hexStr[200];\n    size_t hexStrLen = 0;\n    for (int i = 0; i < sizeof(srd) / sizeof(srd[0]); i++)\n      hexStrLen += sprintf(&hexStr[hexStrLen], \"0x%08x \", srd[i]);\n\n    printf(\"\\nSRD:%s\\n\\n\", hexStr);\n  }\n\n  // HSA component of the image object.\n  hsa_agent_t component;\n\n  // HSA image descriptor of the image object.\n  hsa_ext_image_descriptor_t desc;\n\n  // HSA image access permission of the image object.\n  hsa_access_permission_t permission;\n\n  // Backing storage of the image object.\n  void* data;\n\n  // Device specific row pitch of the image object in size.\n  size_t row_pitch;\n\n  // Device specific slice pitch of the image object in size.\n  size_t slice_pitch;\n\n  // Device specific tile mode\n  TileMode tile_mode;\n} Image;\n\n/// @brief Structure to represent an HSA sampler object.\ntypedef struct Sampler {\nprivate:\n  Sampler() {\n    component.handle = 0;\n    std::memset(srd, 0, sizeof(srd));\n    std::memset(&desc, 0, sizeof(desc));\n  }\n\n  ~Sampler() {}\n\npublic:\n  /// @brief Create a Sampler.\n  static Sampler* Create(hsa_agent_t agent);\n\n  /// @brief Destroy a Sampler.\n  static void Destroy(const Sampler* sampler);\n\n  /// @brief Convert from vendor representation to HSA handle.\n  uint64_t Convert() { return reinterpret_cast<uint64_t>(srd); }\n\n  /// @brief Convert from HSA handle to vendor representation.\n  static Sampler* Convert(uint64_t handle) {\n    return reinterpret_cast<Sampler*>(handle - offsetof(Sampler, srd));\n  }\n\n  // Vendor specific sampler object.\n  __ALIGNED__(HSA_SAMPLER_OBJECT_ALIGNMENT)\n  uint32_t srd[HSA_SAMPLER_OBJECT_SIZE_DWORD];\n\n  // HSA component of the sampler object.\n  hsa_agent_t component;\n\n  // HSA sampler descriptor of the image object.\n  hsa_ext_sampler_descriptor_v2_t desc;\n} Sampler;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_RESOURCE_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource_ai.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_RESOURCE_AI_H\n#define HSA_RUNTIME_EXT_IMAGE_RESOURCE_AI_H\n\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\n        union SQ_BUF_RSRC_WORD0 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                    BASE_ADDRESS : 32;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                    BASE_ADDRESS : 32;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_BUF_RSRC_WORD1 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                 BASE_ADDRESS_HI : 16;\n                unsigned int                          STRIDE : 14;\n                unsigned int                   CACHE_SWIZZLE : 1;\n                unsigned int                  SWIZZLE_ENABLE : 1;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                  SWIZZLE_ENABLE : 1;\n                unsigned int                   CACHE_SWIZZLE : 1;\n                unsigned int                          STRIDE : 14;\n                unsigned int                 BASE_ADDRESS_HI : 16;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_BUF_RSRC_WORD2 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                     NUM_RECORDS : 32;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                     NUM_RECORDS : 32;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_BUF_RSRC_WORD3 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                       DST_SEL_X : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                      NUM_FORMAT : 3;\n                unsigned int                     DATA_FORMAT : 4;\n                unsigned int                  USER_VM_ENABLE : 1;\n                unsigned int                    USER_VM_MODE : 1;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                                 : 3;\n                unsigned int                              NV : 1;\n                unsigned int                                 : 2;\n                unsigned int                            TYPE : 2;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                            TYPE : 2;\n                unsigned int                                 : 2;\n                unsigned int                              NV : 1;\n                unsigned int                                 : 3;\n                unsigned int                  ADD_TID_ENABLE : 1;\n                unsigned int                    INDEX_STRIDE : 2;\n                unsigned int                    USER_VM_MODE : 1;\n                unsigned int                  USER_VM_ENABLE : 1;\n                unsigned int                     DATA_FORMAT : 4;\n                unsigned int                      NUM_FORMAT : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_X : 3;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD0 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                    BASE_ADDRESS : 32;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                    BASE_ADDRESS : 32;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD1 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                 BASE_ADDRESS_HI : 8;\n                unsigned int                         MIN_LOD : 12;\n                unsigned int                     DATA_FORMAT : 6;\n                unsigned int                      NUM_FORMAT : 4;\n                unsigned int                              NV : 1;\n                unsigned int                     META_DIRECT : 1;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                     META_DIRECT : 1;\n                unsigned int                              NV : 1;\n                unsigned int                      NUM_FORMAT : 4;\n                unsigned int                     DATA_FORMAT : 6;\n                unsigned int                         MIN_LOD : 12;\n                unsigned int                 BASE_ADDRESS_HI : 8;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD2 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                           WIDTH : 14;\n                unsigned int                          HEIGHT : 14;\n                unsigned int                        PERF_MOD : 3;\n                unsigned int                                 : 1;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                                 : 1;\n                unsigned int                        PERF_MOD : 3;\n                unsigned int                          HEIGHT : 14;\n                unsigned int                           WIDTH : 14;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD3 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                       DST_SEL_X : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                      BASE_LEVEL : 4;\n                unsigned int                      LAST_LEVEL : 4;\n                unsigned int                         SW_MODE : 5;\n                unsigned int                                 : 3;\n                unsigned int                            TYPE : 4;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                            TYPE : 4;\n                unsigned int                                 : 3;\n                unsigned int                         SW_MODE : 5;\n                unsigned int                      LAST_LEVEL : 4;\n                unsigned int                      BASE_LEVEL : 4;\n                unsigned int                       DST_SEL_W : 3;\n                unsigned int                       DST_SEL_Z : 3;\n                unsigned int                       DST_SEL_Y : 3;\n                unsigned int                       DST_SEL_X : 3;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD4 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                           DEPTH : 13;\n                unsigned int                           PITCH : 16;\n                unsigned int                      BC_SWIZZLE : 3;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                      BC_SWIZZLE : 3;\n                unsigned int                           PITCH : 16;\n                unsigned int                           DEPTH : 13;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD5 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                      BASE_ARRAY : 13;\n                unsigned int                     ARRAY_PITCH : 4;\n                unsigned int            META_DATA_ADDRESS_HI : 8;\n                unsigned int                     META_LINEAR : 1;\n                unsigned int               META_PIPE_ALIGNED : 1;\n                unsigned int                 META_RB_ALIGNED : 1;\n                unsigned int                         MAX_MIP : 4;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                         MAX_MIP : 4;\n                unsigned int                 META_RB_ALIGNED : 1;\n                unsigned int               META_PIPE_ALIGNED : 1;\n                unsigned int                     META_LINEAR : 1;\n                unsigned int            META_DATA_ADDRESS_HI : 8;\n                unsigned int                     ARRAY_PITCH : 4;\n                unsigned int                      BASE_ARRAY : 13;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD6 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                    MIN_LOD_WARN : 12;\n                unsigned int                 COUNTER_BANK_ID : 8;\n                unsigned int                  LOD_HDW_CNT_EN : 1;\n                unsigned int                  COMPRESSION_EN : 1;\n                unsigned int                 ALPHA_IS_ON_MSB : 1;\n                unsigned int                 COLOR_TRANSFORM : 1;\n                unsigned int                 LOST_ALPHA_BITS : 4;\n                unsigned int                 LOST_COLOR_BITS : 4;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                 LOST_COLOR_BITS : 4;\n                unsigned int                 LOST_ALPHA_BITS : 4;\n                unsigned int                 COLOR_TRANSFORM : 1;\n                unsigned int                 ALPHA_IS_ON_MSB : 1;\n                unsigned int                  COMPRESSION_EN : 1;\n                unsigned int                  LOD_HDW_CNT_EN : 1;\n                unsigned int                 COUNTER_BANK_ID : 8;\n                unsigned int                    MIN_LOD_WARN : 12;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_RSRC_WORD7 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int               META_DATA_ADDRESS : 32;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int               META_DATA_ADDRESS : 32;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_SAMP_WORD0 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                         CLAMP_X : 3;\n                unsigned int                         CLAMP_Y : 3;\n                unsigned int                         CLAMP_Z : 3;\n                unsigned int                 MAX_ANISO_RATIO : 3;\n                unsigned int              DEPTH_COMPARE_FUNC : 3;\n                unsigned int              FORCE_UNNORMALIZED : 1;\n                unsigned int                 ANISO_THRESHOLD : 3;\n                unsigned int                  MC_COORD_TRUNC : 1;\n                unsigned int                   FORCE_DEGAMMA : 1;\n                unsigned int                      ANISO_BIAS : 6;\n                unsigned int                     TRUNC_COORD : 1;\n                unsigned int               DISABLE_CUBE_WRAP : 1;\n                unsigned int                     FILTER_MODE : 2;\n                unsigned int                     COMPAT_MODE : 1;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                     COMPAT_MODE : 1;\n                unsigned int                     FILTER_MODE : 2;\n                unsigned int               DISABLE_CUBE_WRAP : 1;\n                unsigned int                     TRUNC_COORD : 1;\n                unsigned int                      ANISO_BIAS : 6;\n                unsigned int                   FORCE_DEGAMMA : 1;\n                unsigned int                  MC_COORD_TRUNC : 1;\n                unsigned int                 ANISO_THRESHOLD : 3;\n                unsigned int              FORCE_UNNORMALIZED : 1;\n                unsigned int              DEPTH_COMPARE_FUNC : 3;\n                unsigned int                 MAX_ANISO_RATIO : 3;\n                unsigned int                         CLAMP_Z : 3;\n                unsigned int                         CLAMP_Y : 3;\n                unsigned int                         CLAMP_X : 3;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_SAMP_WORD1 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                         MIN_LOD : 12;\n                unsigned int                         MAX_LOD : 12;\n                unsigned int                        PERF_MIP : 4;\n                unsigned int                          PERF_Z : 4;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                          PERF_Z : 4;\n                unsigned int                        PERF_MIP : 4;\n                unsigned int                         MAX_LOD : 12;\n                unsigned int                         MIN_LOD : 12;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_SAMP_WORD2 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                        LOD_BIAS : 14;\n                unsigned int                    LOD_BIAS_SEC : 6;\n                unsigned int                   XY_MAG_FILTER : 2;\n                unsigned int                   XY_MIN_FILTER : 2;\n                unsigned int                        Z_FILTER : 2;\n                unsigned int                      MIP_FILTER : 2;\n                unsigned int              MIP_POINT_PRECLAMP : 1;\n                unsigned int                  BLEND_ZERO_PRT : 1;\n                unsigned int                 FILTER_PREC_FIX : 1;\n                unsigned int                  ANISO_OVERRIDE : 1;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int                  ANISO_OVERRIDE : 1;\n                unsigned int                 FILTER_PREC_FIX : 1;\n                unsigned int                  BLEND_ZERO_PRT : 1;\n                unsigned int              MIP_POINT_PRECLAMP : 1;\n                unsigned int                      MIP_FILTER : 2;\n                unsigned int                        Z_FILTER : 2;\n                unsigned int                   XY_MIN_FILTER : 2;\n                unsigned int                   XY_MAG_FILTER : 2;\n                unsigned int                    LOD_BIAS_SEC : 6;\n                unsigned int                        LOD_BIAS : 14;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n        union SQ_IMG_SAMP_WORD3 {\n        struct {\n#if             defined(LITTLEENDIAN_CPU)\n                unsigned int                BORDER_COLOR_PTR : 12;\n                unsigned int                    SKIP_DEGAMMA : 1;\n                unsigned int                                 : 17;\n                unsigned int               BORDER_COLOR_TYPE : 2;\n#elif           defined(BIGENDIAN_CPU)\n                unsigned int               BORDER_COLOR_TYPE : 2;\n                unsigned int                                 : 17;\n                unsigned int                    SKIP_DEGAMMA : 1;\n                unsigned int                BORDER_COLOR_PTR : 12;\n#endif\n        } bitfields, bits;\n        unsigned int    u32All;\n        signed int      i32All;\n        float   f32All;\n        };\n\n\n\n#define SQ_BUF_RSRC_WORD0_REG_SIZE     32\n#define SQ_BUF_RSRC_WORD0_BASE_ADDRESS_SIZE 32\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word0_t {\n          unsigned int base_address                   : SQ_BUF_RSRC_WORD0_BASE_ADDRESS_SIZE;\n     } sq_buf_rsrc_word0_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word0_t {\n          unsigned int base_address                   : SQ_BUF_RSRC_WORD0_BASE_ADDRESS_SIZE;\n     } sq_buf_rsrc_word0_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_buf_rsrc_word0_t f;\n} sq_buf_rsrc_word0_u;\n\n#define SQ_BUF_RSRC_WORD1_REG_SIZE     32\n#define SQ_BUF_RSRC_WORD1_BASE_ADDRESS_HI_SIZE 16\n#define SQ_BUF_RSRC_WORD1_STRIDE_SIZE  14\n#define SQ_BUF_RSRC_WORD1_CACHE_SWIZZLE_SIZE 1\n#define SQ_BUF_RSRC_WORD1_SWIZZLE_ENABLE_SIZE 1\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word1_t {\n          unsigned int base_address_hi                : SQ_BUF_RSRC_WORD1_BASE_ADDRESS_HI_SIZE;\n          unsigned int stride                         : SQ_BUF_RSRC_WORD1_STRIDE_SIZE;\n          unsigned int cache_swizzle                  : SQ_BUF_RSRC_WORD1_CACHE_SWIZZLE_SIZE;\n          unsigned int swizzle_enable                 : SQ_BUF_RSRC_WORD1_SWIZZLE_ENABLE_SIZE;\n     } sq_buf_rsrc_word1_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word1_t {\n          unsigned int swizzle_enable                 : SQ_BUF_RSRC_WORD1_SWIZZLE_ENABLE_SIZE;\n          unsigned int cache_swizzle                  : SQ_BUF_RSRC_WORD1_CACHE_SWIZZLE_SIZE;\n          unsigned int stride                         : SQ_BUF_RSRC_WORD1_STRIDE_SIZE;\n          unsigned int base_address_hi                : SQ_BUF_RSRC_WORD1_BASE_ADDRESS_HI_SIZE;\n     } sq_buf_rsrc_word1_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_buf_rsrc_word1_t f;\n} sq_buf_rsrc_word1_u;\n\n#define SQ_BUF_RSRC_WORD2_REG_SIZE     32\n#define SQ_BUF_RSRC_WORD2_NUM_RECORDS_SIZE 32\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word2_t {\n          unsigned int num_records                    : SQ_BUF_RSRC_WORD2_NUM_RECORDS_SIZE;\n     } sq_buf_rsrc_word2_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word2_t {\n          unsigned int num_records                    : SQ_BUF_RSRC_WORD2_NUM_RECORDS_SIZE;\n     } sq_buf_rsrc_word2_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_buf_rsrc_word2_t f;\n} sq_buf_rsrc_word2_u;\n\n#define SQ_BUF_RSRC_WORD3_REG_SIZE     32\n#define SQ_BUF_RSRC_WORD3_DST_SEL_X_SIZE 3\n#define SQ_BUF_RSRC_WORD3_DST_SEL_Y_SIZE 3\n#define SQ_BUF_RSRC_WORD3_DST_SEL_Z_SIZE 3\n#define SQ_BUF_RSRC_WORD3_DST_SEL_W_SIZE 3\n#define SQ_BUF_RSRC_WORD3_NUM_FORMAT_SIZE 3\n#define SQ_BUF_RSRC_WORD3_DATA_FORMAT_SIZE 4\n#define SQ_BUF_RSRC_WORD3_USER_VM_ENABLE_SIZE 1\n#define SQ_BUF_RSRC_WORD3_USER_VM_MODE_SIZE 1\n#define SQ_BUF_RSRC_WORD3_INDEX_STRIDE_SIZE 2\n#define SQ_BUF_RSRC_WORD3_ADD_TID_ENABLE_SIZE 1\n#define SQ_BUF_RSRC_WORD3_NV_SIZE      1\n#define SQ_BUF_RSRC_WORD3_TYPE_SIZE    2\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word3_t {\n          unsigned int dst_sel_x                      : SQ_BUF_RSRC_WORD3_DST_SEL_X_SIZE;\n          unsigned int dst_sel_y                      : SQ_BUF_RSRC_WORD3_DST_SEL_Y_SIZE;\n          unsigned int dst_sel_z                      : SQ_BUF_RSRC_WORD3_DST_SEL_Z_SIZE;\n          unsigned int dst_sel_w                      : SQ_BUF_RSRC_WORD3_DST_SEL_W_SIZE;\n          unsigned int num_format                     : SQ_BUF_RSRC_WORD3_NUM_FORMAT_SIZE;\n          unsigned int data_format                    : SQ_BUF_RSRC_WORD3_DATA_FORMAT_SIZE;\n          unsigned int user_vm_enable                 : SQ_BUF_RSRC_WORD3_USER_VM_ENABLE_SIZE;\n          unsigned int user_vm_mode                   : SQ_BUF_RSRC_WORD3_USER_VM_MODE_SIZE;\n          unsigned int index_stride                   : SQ_BUF_RSRC_WORD3_INDEX_STRIDE_SIZE;\n          unsigned int add_tid_enable                 : SQ_BUF_RSRC_WORD3_ADD_TID_ENABLE_SIZE;\n          unsigned int                                : 3;\n          unsigned int nv                             : SQ_BUF_RSRC_WORD3_NV_SIZE;\n          unsigned int                                : 2;\n          unsigned int type                           : SQ_BUF_RSRC_WORD3_TYPE_SIZE;\n     } sq_buf_rsrc_word3_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_buf_rsrc_word3_t {\n          unsigned int type                           : SQ_BUF_RSRC_WORD3_TYPE_SIZE;\n          unsigned int                                : 2;\n          unsigned int nv                             : SQ_BUF_RSRC_WORD3_NV_SIZE;\n          unsigned int                                : 3;\n          unsigned int add_tid_enable                 : SQ_BUF_RSRC_WORD3_ADD_TID_ENABLE_SIZE;\n          unsigned int index_stride                   : SQ_BUF_RSRC_WORD3_INDEX_STRIDE_SIZE;\n          unsigned int user_vm_mode                   : SQ_BUF_RSRC_WORD3_USER_VM_MODE_SIZE;\n          unsigned int user_vm_enable                 : SQ_BUF_RSRC_WORD3_USER_VM_ENABLE_SIZE;\n          unsigned int data_format                    : SQ_BUF_RSRC_WORD3_DATA_FORMAT_SIZE;\n          unsigned int num_format                     : SQ_BUF_RSRC_WORD3_NUM_FORMAT_SIZE;\n          unsigned int dst_sel_w                      : SQ_BUF_RSRC_WORD3_DST_SEL_W_SIZE;\n          unsigned int dst_sel_z                      : SQ_BUF_RSRC_WORD3_DST_SEL_Z_SIZE;\n          unsigned int dst_sel_y                      : SQ_BUF_RSRC_WORD3_DST_SEL_Y_SIZE;\n          unsigned int dst_sel_x                      : SQ_BUF_RSRC_WORD3_DST_SEL_X_SIZE;\n     } sq_buf_rsrc_word3_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_buf_rsrc_word3_t f;\n} sq_buf_rsrc_word3_u;\n\n\n#define SQ_IMG_RSRC_WORD0_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD0_BASE_ADDRESS_SIZE 32\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word0_t {\n          unsigned int base_address                   : SQ_IMG_RSRC_WORD0_BASE_ADDRESS_SIZE;\n     } sq_img_rsrc_word0_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word0_t {\n          unsigned int base_address                   : SQ_IMG_RSRC_WORD0_BASE_ADDRESS_SIZE;\n     } sq_img_rsrc_word0_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word0_t f;\n} sq_img_rsrc_word0_u;\n\n#define SQ_IMG_RSRC_WORD1_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD1_BASE_ADDRESS_HI_SIZE 8\n#define SQ_IMG_RSRC_WORD1_MIN_LOD_SIZE 12\n#define SQ_IMG_RSRC_WORD1_DATA_FORMAT_SIZE 6\n#define SQ_IMG_RSRC_WORD1_NUM_FORMAT_SIZE 4\n#define SQ_IMG_RSRC_WORD1_NV_SIZE      1\n#define SQ_IMG_RSRC_WORD1_META_DIRECT_SIZE 1\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word1_t {\n          unsigned int base_address_hi                : SQ_IMG_RSRC_WORD1_BASE_ADDRESS_HI_SIZE;\n          unsigned int min_lod                        : SQ_IMG_RSRC_WORD1_MIN_LOD_SIZE;\n          unsigned int data_format                    : SQ_IMG_RSRC_WORD1_DATA_FORMAT_SIZE;\n          unsigned int num_format                     : SQ_IMG_RSRC_WORD1_NUM_FORMAT_SIZE;\n          unsigned int nv                             : SQ_IMG_RSRC_WORD1_NV_SIZE;\n          unsigned int meta_direct                    : SQ_IMG_RSRC_WORD1_META_DIRECT_SIZE;\n     } sq_img_rsrc_word1_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word1_t {\n          unsigned int meta_direct                    : SQ_IMG_RSRC_WORD1_META_DIRECT_SIZE;\n          unsigned int nv                             : SQ_IMG_RSRC_WORD1_NV_SIZE;\n          unsigned int num_format                     : SQ_IMG_RSRC_WORD1_NUM_FORMAT_SIZE;\n          unsigned int data_format                    : SQ_IMG_RSRC_WORD1_DATA_FORMAT_SIZE;\n          unsigned int min_lod                        : SQ_IMG_RSRC_WORD1_MIN_LOD_SIZE;\n          unsigned int base_address_hi                : SQ_IMG_RSRC_WORD1_BASE_ADDRESS_HI_SIZE;\n     } sq_img_rsrc_word1_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word1_t f;\n} sq_img_rsrc_word1_u;\n\n#define SQ_IMG_RSRC_WORD2_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD2_WIDTH_SIZE   14\n#define SQ_IMG_RSRC_WORD2_HEIGHT_SIZE  14\n#define SQ_IMG_RSRC_WORD2_PERF_MOD_SIZE 3\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word2_t {\n          unsigned int width                          : SQ_IMG_RSRC_WORD2_WIDTH_SIZE;\n          unsigned int height                         : SQ_IMG_RSRC_WORD2_HEIGHT_SIZE;\n          unsigned int perf_mod                       : SQ_IMG_RSRC_WORD2_PERF_MOD_SIZE;\n          unsigned int                                : 1;\n     } sq_img_rsrc_word2_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word2_t {\n          unsigned int                                : 1;\n          unsigned int perf_mod                       : SQ_IMG_RSRC_WORD2_PERF_MOD_SIZE;\n          unsigned int height                         : SQ_IMG_RSRC_WORD2_HEIGHT_SIZE;\n          unsigned int width                          : SQ_IMG_RSRC_WORD2_WIDTH_SIZE;\n     } sq_img_rsrc_word2_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word2_t f;\n} sq_img_rsrc_word2_u;\n\n#define SQ_IMG_RSRC_WORD3_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD3_DST_SEL_X_SIZE 3\n#define SQ_IMG_RSRC_WORD3_DST_SEL_Y_SIZE 3\n#define SQ_IMG_RSRC_WORD3_DST_SEL_Z_SIZE 3\n#define SQ_IMG_RSRC_WORD3_DST_SEL_W_SIZE 3\n#define SQ_IMG_RSRC_WORD3_BASE_LEVEL_SIZE 4\n#define SQ_IMG_RSRC_WORD3_LAST_LEVEL_SIZE 4\n#define SQ_IMG_RSRC_WORD3_SW_MODE_SIZE 5\n#define SQ_IMG_RSRC_WORD3_TYPE_SIZE    4\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word3_t {\n          unsigned int dst_sel_x                      : SQ_IMG_RSRC_WORD3_DST_SEL_X_SIZE;\n          unsigned int dst_sel_y                      : SQ_IMG_RSRC_WORD3_DST_SEL_Y_SIZE;\n          unsigned int dst_sel_z                      : SQ_IMG_RSRC_WORD3_DST_SEL_Z_SIZE;\n          unsigned int dst_sel_w                      : SQ_IMG_RSRC_WORD3_DST_SEL_W_SIZE;\n          unsigned int base_level                     : SQ_IMG_RSRC_WORD3_BASE_LEVEL_SIZE;\n          unsigned int last_level                     : SQ_IMG_RSRC_WORD3_LAST_LEVEL_SIZE;\n          unsigned int sw_mode                        : SQ_IMG_RSRC_WORD3_SW_MODE_SIZE;\n          unsigned int                                : 3;\n          unsigned int type                           : SQ_IMG_RSRC_WORD3_TYPE_SIZE;\n     } sq_img_rsrc_word3_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word3_t {\n          unsigned int type                           : SQ_IMG_RSRC_WORD3_TYPE_SIZE;\n          unsigned int                                : 3;\n          unsigned int sw_mode                        : SQ_IMG_RSRC_WORD3_SW_MODE_SIZE;\n          unsigned int last_level                     : SQ_IMG_RSRC_WORD3_LAST_LEVEL_SIZE;\n          unsigned int base_level                     : SQ_IMG_RSRC_WORD3_BASE_LEVEL_SIZE;\n          unsigned int dst_sel_w                      : SQ_IMG_RSRC_WORD3_DST_SEL_W_SIZE;\n          unsigned int dst_sel_z                      : SQ_IMG_RSRC_WORD3_DST_SEL_Z_SIZE;\n          unsigned int dst_sel_y                      : SQ_IMG_RSRC_WORD3_DST_SEL_Y_SIZE;\n          unsigned int dst_sel_x                      : SQ_IMG_RSRC_WORD3_DST_SEL_X_SIZE;\n     } sq_img_rsrc_word3_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word3_t f;\n} sq_img_rsrc_word3_u;\n\n#define SQ_IMG_RSRC_WORD4_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD4_DEPTH_SIZE   13\n#define SQ_IMG_RSRC_WORD4_PITCH_SIZE   16\n#define SQ_IMG_RSRC_WORD4_BC_SWIZZLE_SIZE 3\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word4_t {\n          unsigned int depth                          : SQ_IMG_RSRC_WORD4_DEPTH_SIZE;\n          unsigned int pitch                          : SQ_IMG_RSRC_WORD4_PITCH_SIZE;\n          unsigned int bc_swizzle                     : SQ_IMG_RSRC_WORD4_BC_SWIZZLE_SIZE;\n     } sq_img_rsrc_word4_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word4_t {\n          unsigned int bc_swizzle                     : SQ_IMG_RSRC_WORD4_BC_SWIZZLE_SIZE;\n          unsigned int pitch                          : SQ_IMG_RSRC_WORD4_PITCH_SIZE;\n          unsigned int depth                          : SQ_IMG_RSRC_WORD4_DEPTH_SIZE;\n     } sq_img_rsrc_word4_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word4_t f;\n} sq_img_rsrc_word4_u;\n\n#define SQ_IMG_RSRC_WORD5_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD5_BASE_ARRAY_SIZE 13\n#define SQ_IMG_RSRC_WORD5_ARRAY_PITCH_SIZE 4\n#define SQ_IMG_RSRC_WORD5_META_DATA_ADDRESS_SIZE 8\n#define SQ_IMG_RSRC_WORD5_META_LINEAR_SIZE 1\n#define SQ_IMG_RSRC_WORD5_META_PIPE_ALIGNED_SIZE 1\n#define SQ_IMG_RSRC_WORD5_META_RB_ALIGNED_SIZE 1\n#define SQ_IMG_RSRC_WORD5_MAX_MIP_SIZE 4\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word5_t {\n          unsigned int base_array                     : SQ_IMG_RSRC_WORD5_BASE_ARRAY_SIZE;\n          unsigned int array_pitch                    : SQ_IMG_RSRC_WORD5_ARRAY_PITCH_SIZE;\n          unsigned int meta_data_address              : SQ_IMG_RSRC_WORD5_META_DATA_ADDRESS_SIZE;\n          unsigned int meta_linear                    : SQ_IMG_RSRC_WORD5_META_LINEAR_SIZE;\n          unsigned int meta_pipe_aligned              : SQ_IMG_RSRC_WORD5_META_PIPE_ALIGNED_SIZE;\n          unsigned int meta_rb_aligned                : SQ_IMG_RSRC_WORD5_META_RB_ALIGNED_SIZE;\n          unsigned int max_mip                        : SQ_IMG_RSRC_WORD5_MAX_MIP_SIZE;\n     } sq_img_rsrc_word5_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word5_t {\n          unsigned int max_mip                        : SQ_IMG_RSRC_WORD5_MAX_MIP_SIZE;\n          unsigned int meta_rb_aligned                : SQ_IMG_RSRC_WORD5_META_RB_ALIGNED_SIZE;\n          unsigned int meta_pipe_aligned              : SQ_IMG_RSRC_WORD5_META_PIPE_ALIGNED_SIZE;\n          unsigned int meta_linear                    : SQ_IMG_RSRC_WORD5_META_LINEAR_SIZE;\n          unsigned int meta_data_address              : SQ_IMG_RSRC_WORD5_META_DATA_ADDRESS_SIZE;\n          unsigned int array_pitch                    : SQ_IMG_RSRC_WORD5_ARRAY_PITCH_SIZE;\n          unsigned int base_array                     : SQ_IMG_RSRC_WORD5_BASE_ARRAY_SIZE;\n     } sq_img_rsrc_word5_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word5_t f;\n} sq_img_rsrc_word5_u;\n\n#define SQ_IMG_RSRC_WORD6_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD6_MIN_LOD_WARN_SIZE 12\n#define SQ_IMG_RSRC_WORD6_COUNTER_BANK_ID_SIZE 8\n#define SQ_IMG_RSRC_WORD6_LOD_HDW_CNT_EN_SIZE 1\n#define SQ_IMG_RSRC_WORD6_COMPRESSION_EN_SIZE 1\n#define SQ_IMG_RSRC_WORD6_ALPHA_IS_ON_MSB_SIZE 1\n#define SQ_IMG_RSRC_WORD6_COLOR_TRANSFORM_SIZE 1\n#define SQ_IMG_RSRC_WORD6_LOST_ALPHA_BITS_SIZE 4\n#define SQ_IMG_RSRC_WORD6_LOST_COLOR_BITS_SIZE 4\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word6_t {\n          unsigned int min_lod_warn                   : SQ_IMG_RSRC_WORD6_MIN_LOD_WARN_SIZE;\n          unsigned int counter_bank_id                : SQ_IMG_RSRC_WORD6_COUNTER_BANK_ID_SIZE;\n          unsigned int lod_hdw_cnt_en                 : SQ_IMG_RSRC_WORD6_LOD_HDW_CNT_EN_SIZE;\n          unsigned int compression_en                 : SQ_IMG_RSRC_WORD6_COMPRESSION_EN_SIZE;\n          unsigned int alpha_is_on_msb                : SQ_IMG_RSRC_WORD6_ALPHA_IS_ON_MSB_SIZE;\n          unsigned int color_transform                : SQ_IMG_RSRC_WORD6_COLOR_TRANSFORM_SIZE;\n          unsigned int lost_alpha_bits                : SQ_IMG_RSRC_WORD6_LOST_ALPHA_BITS_SIZE;\n          unsigned int lost_color_bits                : SQ_IMG_RSRC_WORD6_LOST_COLOR_BITS_SIZE;\n     } sq_img_rsrc_word6_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word6_t {\n          unsigned int lost_color_bits                : SQ_IMG_RSRC_WORD6_LOST_COLOR_BITS_SIZE;\n          unsigned int lost_alpha_bits                : SQ_IMG_RSRC_WORD6_LOST_ALPHA_BITS_SIZE;\n          unsigned int color_transform                : SQ_IMG_RSRC_WORD6_COLOR_TRANSFORM_SIZE;\n          unsigned int alpha_is_on_msb                : SQ_IMG_RSRC_WORD6_ALPHA_IS_ON_MSB_SIZE;\n          unsigned int compression_en                 : SQ_IMG_RSRC_WORD6_COMPRESSION_EN_SIZE;\n          unsigned int lod_hdw_cnt_en                 : SQ_IMG_RSRC_WORD6_LOD_HDW_CNT_EN_SIZE;\n          unsigned int counter_bank_id                : SQ_IMG_RSRC_WORD6_COUNTER_BANK_ID_SIZE;\n          unsigned int min_lod_warn                   : SQ_IMG_RSRC_WORD6_MIN_LOD_WARN_SIZE;\n     } sq_img_rsrc_word6_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word6_t f;\n} sq_img_rsrc_word6_u;\n\n#define SQ_IMG_RSRC_WORD7_REG_SIZE     32\n#define SQ_IMG_RSRC_WORD7_META_DATA_ADDRESS_SIZE 32\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word7_t {\n          unsigned int meta_data_address              : SQ_IMG_RSRC_WORD7_META_DATA_ADDRESS_SIZE;\n     } sq_img_rsrc_word7_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_rsrc_word7_t {\n          unsigned int meta_data_address              : SQ_IMG_RSRC_WORD7_META_DATA_ADDRESS_SIZE;\n     } sq_img_rsrc_word7_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_rsrc_word7_t f;\n} sq_img_rsrc_word7_u;\n\n#define SQ_IMG_SAMP_WORD0_REG_SIZE     32\n#define SQ_IMG_SAMP_WORD0_CLAMP_X_SIZE 3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Y_SIZE 3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Z_SIZE 3\n#define SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SIZE 3\n#define SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SIZE 3\n#define SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SIZE 1\n#define SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SIZE 3\n#define SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SIZE 1\n#define SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SIZE 1\n#define SQ_IMG_SAMP_WORD0_ANISO_BIAS_SIZE 6\n#define SQ_IMG_SAMP_WORD0_TRUNC_COORD_SIZE 1\n#define SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SIZE 1\n#define SQ_IMG_SAMP_WORD0_FILTER_MODE_SIZE 2\n#define SQ_IMG_SAMP_WORD0_COMPAT_MODE_SIZE 1\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word0_t {\n          unsigned int clamp_x                        : SQ_IMG_SAMP_WORD0_CLAMP_X_SIZE;\n          unsigned int clamp_y                        : SQ_IMG_SAMP_WORD0_CLAMP_Y_SIZE;\n          unsigned int clamp_z                        : SQ_IMG_SAMP_WORD0_CLAMP_Z_SIZE;\n          unsigned int max_aniso_ratio                : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SIZE;\n          unsigned int depth_compare_func             : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SIZE;\n          unsigned int force_unnormalized             : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SIZE;\n          unsigned int aniso_threshold                : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SIZE;\n          unsigned int mc_coord_trunc                 : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SIZE;\n          unsigned int force_degamma                  : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SIZE;\n          unsigned int aniso_bias                     : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SIZE;\n          unsigned int trunc_coord                    : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SIZE;\n          unsigned int disable_cube_wrap              : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SIZE;\n          unsigned int filter_mode                    : SQ_IMG_SAMP_WORD0_FILTER_MODE_SIZE;\n          unsigned int compat_mode                    : SQ_IMG_SAMP_WORD0_COMPAT_MODE_SIZE;\n     } sq_img_samp_word0_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word0_t {\n          unsigned int compat_mode                    : SQ_IMG_SAMP_WORD0_COMPAT_MODE_SIZE;\n          unsigned int filter_mode                    : SQ_IMG_SAMP_WORD0_FILTER_MODE_SIZE;\n          unsigned int disable_cube_wrap              : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SIZE;\n          unsigned int trunc_coord                    : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SIZE;\n          unsigned int aniso_bias                     : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SIZE;\n          unsigned int force_degamma                  : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SIZE;\n          unsigned int mc_coord_trunc                 : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SIZE;\n          unsigned int aniso_threshold                : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SIZE;\n          unsigned int force_unnormalized             : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SIZE;\n          unsigned int depth_compare_func             : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SIZE;\n          unsigned int max_aniso_ratio                : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SIZE;\n          unsigned int clamp_z                        : SQ_IMG_SAMP_WORD0_CLAMP_Z_SIZE;\n          unsigned int clamp_y                        : SQ_IMG_SAMP_WORD0_CLAMP_Y_SIZE;\n          unsigned int clamp_x                        : SQ_IMG_SAMP_WORD0_CLAMP_X_SIZE;\n     } sq_img_samp_word0_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_samp_word0_t f;\n} sq_img_samp_word0_u;\n\n#define SQ_IMG_SAMP_WORD1_REG_SIZE     32\n#define SQ_IMG_SAMP_WORD1_MIN_LOD_SIZE 12\n#define SQ_IMG_SAMP_WORD1_MAX_LOD_SIZE 12\n#define SQ_IMG_SAMP_WORD1_PERF_MIP_SIZE 4\n#define SQ_IMG_SAMP_WORD1_PERF_Z_SIZE  4\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word1_t {\n          unsigned int min_lod                        : SQ_IMG_SAMP_WORD1_MIN_LOD_SIZE;\n          unsigned int max_lod                        : SQ_IMG_SAMP_WORD1_MAX_LOD_SIZE;\n          unsigned int perf_mip                       : SQ_IMG_SAMP_WORD1_PERF_MIP_SIZE;\n          unsigned int perf_z                         : SQ_IMG_SAMP_WORD1_PERF_Z_SIZE;\n     } sq_img_samp_word1_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word1_t {\n          unsigned int perf_z                         : SQ_IMG_SAMP_WORD1_PERF_Z_SIZE;\n          unsigned int perf_mip                       : SQ_IMG_SAMP_WORD1_PERF_MIP_SIZE;\n          unsigned int max_lod                        : SQ_IMG_SAMP_WORD1_MAX_LOD_SIZE;\n          unsigned int min_lod                        : SQ_IMG_SAMP_WORD1_MIN_LOD_SIZE;\n     } sq_img_samp_word1_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_samp_word1_t f;\n} sq_img_samp_word1_u;\n\n#define SQ_IMG_SAMP_WORD2_REG_SIZE     32\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SIZE 14\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SIZE 6\n#define SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SIZE 2\n#define SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SIZE 2\n#define SQ_IMG_SAMP_WORD2_Z_FILTER_SIZE 2\n#define SQ_IMG_SAMP_WORD2_MIP_FILTER_SIZE 2\n#define SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SIZE 1\n#define SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SIZE 1\n#define SQ_IMG_SAMP_WORD2_FILTER_PREC_FIX_SIZE 1\n#define SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SIZE 1\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word2_t {\n          unsigned int lod_bias                       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SIZE;\n          unsigned int lod_bias_sec                   : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SIZE;\n          unsigned int xy_mag_filter                  : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SIZE;\n          unsigned int xy_min_filter                  : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SIZE;\n          unsigned int z_filter                       : SQ_IMG_SAMP_WORD2_Z_FILTER_SIZE;\n          unsigned int mip_filter                     : SQ_IMG_SAMP_WORD2_MIP_FILTER_SIZE;\n          unsigned int mip_point_preclamp             : SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SIZE;\n          unsigned int blend_zero_prt                 : SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SIZE;\n          unsigned int filter_prec_fix                : SQ_IMG_SAMP_WORD2_FILTER_PREC_FIX_SIZE;\n          unsigned int aniso_override                 : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SIZE;\n     } sq_img_samp_word2_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word2_t {\n          unsigned int aniso_override                 : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SIZE;\n          unsigned int filter_prec_fix                : SQ_IMG_SAMP_WORD2_FILTER_PREC_FIX_SIZE;\n          unsigned int blend_zero_prt                 : SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SIZE;\n          unsigned int mip_point_preclamp             : SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SIZE;\n          unsigned int mip_filter                     : SQ_IMG_SAMP_WORD2_MIP_FILTER_SIZE;\n          unsigned int z_filter                       : SQ_IMG_SAMP_WORD2_Z_FILTER_SIZE;\n          unsigned int xy_min_filter                  : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SIZE;\n          unsigned int xy_mag_filter                  : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SIZE;\n          unsigned int lod_bias_sec                   : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SIZE;\n          unsigned int lod_bias                       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SIZE;\n     } sq_img_samp_word2_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_samp_word2_t f;\n} sq_img_samp_word2_u;\n\n#define SQ_IMG_SAMP_WORD3_REG_SIZE     32\n#define SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SIZE 12\n#define SQ_IMG_SAMP_WORD3_SKIP_DEGAMMA_SIZE 1\n#define SQ_IMG_SAMP_WORD3_BORDER_COLOR_TYPE_SIZE 2\n\n#if             defined(LITTLEENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word3_t {\n          unsigned int border_color_ptr               : SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SIZE;\n          unsigned int skip_degamma                   : SQ_IMG_SAMP_WORD3_SKIP_DEGAMMA_SIZE;\n          unsigned int                                : 17;\n          unsigned int border_color_type              : SQ_IMG_SAMP_WORD3_BORDER_COLOR_TYPE_SIZE;\n     } sq_img_samp_word3_t;\n\n#elif           defined(BIGENDIAN_CPU)\n\n     typedef struct _sq_img_samp_word3_t {\n          unsigned int border_color_type              : SQ_IMG_SAMP_WORD3_BORDER_COLOR_TYPE_SIZE;\n          unsigned int                                : 17;\n          unsigned int skip_degamma                   : SQ_IMG_SAMP_WORD3_SKIP_DEGAMMA_SIZE;\n          unsigned int border_color_ptr               : SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SIZE;\n     } sq_img_samp_word3_t;\n\n#endif\n\ntypedef union {\n     unsigned int val : 32;\n     sq_img_samp_word3_t f;\n} sq_img_samp_word3_u;\n\ntypedef enum FMT {\nFMT_INVALID                              = 0x00000000,\nFMT_8                                    = 0x00000001,\nFMT_16                                   = 0x00000002,\nFMT_8_8                                  = 0x00000003,\nFMT_32                                   = 0x00000004,\nFMT_16_16                                = 0x00000005,\nFMT_10_11_11                             = 0x00000006,\nFMT_11_11_10                             = 0x00000007,\nFMT_10_10_10_2                           = 0x00000008,\nFMT_2_10_10_10                           = 0x00000009,\nFMT_8_8_8_8                              = 0x0000000a,\nFMT_32_32                                = 0x0000000b,\nFMT_16_16_16_16                          = 0x0000000c,\nFMT_32_32_32                             = 0x0000000d,\nFMT_32_32_32_32                          = 0x0000000e,\nFMT_RESERVED_4                           = 0x0000000f,\nFMT_5_6_5                                = 0x00000010,\nFMT_1_5_5_5                              = 0x00000011,\nFMT_5_5_5_1                              = 0x00000012,\nFMT_4_4_4_4                              = 0x00000013,\nFMT_8_24                                 = 0x00000014,\nFMT_24_8                                 = 0x00000015,\nFMT_X24_8_32_FLOAT                       = 0x00000016,\nFMT_RESERVED_33                          = 0x00000017,\nFMT_11_11_10_FLOAT                       = 0x00000018,\nFMT_16_FLOAT                             = 0x00000019,\nFMT_32_FLOAT                             = 0x0000001a,\nFMT_16_16_FLOAT                          = 0x0000001b,\nFMT_8_24_FLOAT                           = 0x0000001c,\nFMT_24_8_FLOAT                           = 0x0000001d,\nFMT_32_32_FLOAT                          = 0x0000001e,\nFMT_10_11_11_FLOAT                       = 0x0000001f,\nFMT_16_16_16_16_FLOAT                    = 0x00000020,\nFMT_3_3_2                                = 0x00000021,\nFMT_6_5_5                                = 0x00000022,\nFMT_32_32_32_32_FLOAT                    = 0x00000023,\nFMT_RESERVED_36                          = 0x00000024,\nFMT_1                                    = 0x00000025,\nFMT_1_REVERSED                           = 0x00000026,\nFMT_GB_GR                                = 0x00000027,\nFMT_BG_RG                                = 0x00000028,\nFMT_32_AS_8                              = 0x00000029,\nFMT_32_AS_8_8                            = 0x0000002a,\nFMT_5_9_9_9_SHAREDEXP                    = 0x0000002b,\nFMT_8_8_8                                = 0x0000002c,\nFMT_16_16_16                             = 0x0000002d,\nFMT_16_16_16_FLOAT                       = 0x0000002e,\nFMT_4_4                                  = 0x0000002f,\nFMT_32_32_32_FLOAT                       = 0x00000030,\nFMT_BC1                                  = 0x00000031,\nFMT_BC2                                  = 0x00000032,\nFMT_BC3                                  = 0x00000033,\nFMT_BC4                                  = 0x00000034,\nFMT_BC5                                  = 0x00000035,\nFMT_BC6                                  = 0x00000036,\nFMT_BC7                                  = 0x00000037,\nFMT_32_AS_32_32_32_32                    = 0x00000038,\nFMT_APC3                                 = 0x00000039,\nFMT_APC4                                 = 0x0000003a,\nFMT_APC5                                 = 0x0000003b,\nFMT_APC6                                 = 0x0000003c,\nFMT_APC7                                 = 0x0000003d,\nFMT_CTX1                                 = 0x0000003e,\nFMT_RESERVED_63                          = 0x0000003f,\n} FMT;\n\ntypedef enum type {\nTYPE_UNORM                     = 0x00000000,\nTYPE_SNORM                     = 0x00000001,\nTYPE_USCALED                   = 0x00000002,\nTYPE_SSCALED                   = 0x00000003,\nTYPE_UINT                      = 0x00000004,\nTYPE_SINT                      = 0x00000005,\nTYPE_RESERVED_6                = 0x00000006,\nTYPE_FLOAT                     = 0x00000007,\nTYPE_RESERVED_8                = 0x00000008,\nTYPE_SRGB                      = 0x00000009,\nTYPE_UNORM_UINT                = 0x0000000a,\n} type;\n\ntypedef enum SEL {\n  SEL_0 = 0x00000000,\n  SEL_1 = 0x00000001,\n  SEL_X = 0x00000004,\n  SEL_Y = 0x00000005,\n  SEL_Z = 0x00000006,\n  SEL_W = 0x00000007,\n} SEL;\n\ntypedef enum SQ_RSRC_IMG_TYPE {\n  SQ_RSRC_IMG_1D = 0x00000008,\n  SQ_RSRC_IMG_2D = 0x00000009,\n  SQ_RSRC_IMG_3D = 0x0000000a,\n  SQ_RSRC_IMG_1D_ARRAY = 0x0000000c,\n  SQ_RSRC_IMG_2D_ARRAY = 0x0000000d,\n} SQ_RSRC_IMG_TYPE;\n\ntypedef enum SQ_TEX_XY_FILTER {\n  SQ_TEX_XY_FILTER_POINT = 0x00000000,\n  SQ_TEX_XY_FILTER_BILINEAR = 0x00000001,\n  SQ_TEX_XY_FILTER_ANISO_POINT = 0x00000002,\n  SQ_TEX_XY_FILTER_ANISO_BILINEAR = 0x00000003,\n} SQ_TEX_XY_FILTER;\n\ntypedef enum SQ_TEX_Z_FILTER {\n  SQ_TEX_Z_FILTER_NONE = 0x00000000,\n  SQ_TEX_Z_FILTER_POINT = 0x00000001,\n  SQ_TEX_Z_FILTER_LINEAR = 0x00000002,\n} SQ_TEX_Z_FILTER;\n\ntypedef enum SQ_TEX_MIP_FILTER {\n  SQ_TEX_MIP_FILTER_NONE = 0x00000000,\n  SQ_TEX_MIP_FILTER_POINT = 0x00000001,\n  SQ_TEX_MIP_FILTER_LINEAR = 0x00000002,\n  SQ_TEX_MIP_FILTER_POINT_ANISO_ADJ__VI = 0x00000003,\n} SQ_TEX_MIP_FILTER;\n\ntypedef enum SQ_TEX_CLAMP {\n  SQ_TEX_WRAP = 0x00000000,\n  SQ_TEX_MIRROR = 0x00000001,\n  SQ_TEX_CLAMP_LAST_TEXEL = 0x00000002,\n  SQ_TEX_MIRROR_ONCE_LAST_TEXEL = 0x00000003,\n  SQ_TEX_CLAMP_HALF_BORDER = 0x00000004,\n  SQ_TEX_MIRROR_ONCE_HALF_BORDER = 0x00000005,\n  SQ_TEX_CLAMP_BORDER = 0x00000006,\n  SQ_TEX_MIRROR_ONCE_BORDER = 0x00000007,\n} SQ_TEX_CLAMP;\n\ntypedef enum SQ_TEX_BORDER_COLOR {\n  SQ_TEX_BORDER_COLOR_TRANS_BLACK = 0x00000000,\n  SQ_TEX_BORDER_COLOR_OPAQUE_BLACK = 0x00000001,\n  SQ_TEX_BORDER_COLOR_OPAQUE_WHITE = 0x00000002,\n  SQ_TEX_BORDER_COLOR_REGISTER = 0x00000003,\n} SQ_TEX_BORDER_COLOR;\n\ntypedef enum TEX_BC_SWIZZLE {\nTEX_BC_Swizzle_XYZW                      = 0x00000000,\nTEX_BC_Swizzle_XWYZ                      = 0x00000001,\nTEX_BC_Swizzle_WZYX                      = 0x00000002,\nTEX_BC_Swizzle_WXYZ                      = 0x00000003,\nTEX_BC_Swizzle_ZYXW                      = 0x00000004,\nTEX_BC_Swizzle_YXWZ                      = 0x00000005,\n} TEX_BC_SWIZZLE;\n\ntypedef struct metadata_amd_ai_s {\n    uint32_t version; // Must be 1\n    uint32_t vendorID; // AMD\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD6 word6;\n    SQ_IMG_RSRC_WORD7 word7;\n    uint32_t mip_offsets[0]; //Mip level offset bits [39:8] for each level (if any)\n} metadata_amd_ai_t;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_RESOURCE_AI_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource_gfx11.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_RESOURCE_GFX11_H_\n#define EXT_IMAGE_RESOURCE_GFX11_H_\n\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_BUF_RSC_WRD0_REG_SZ 32\n#define SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ 32\n\nstruct sq_buf_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD0 {\n  sq_buf_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n\n/***********/\n\n/* Note: These registers are also defined/used in registers.h\n * in SQ_BUF_RSRC_WORD1_GFX11\n */\n#define SQ_BUF_RSC_WRD1_REG_SZ 32\n#define SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ  16\n#define SQ_BUF_RSC_WRD1_STRIDE_SZ           14\n#define SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ   2\nstruct sq_buf_rsrc_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD1 {\n  sq_buf_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD2_REG_SZ 32\n#define SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ 32\nstruct sq_buf_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#endif\n};\nunion SQ_BUF_RSRC_WORD2 {\n  sq_buf_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD3_REG_SZ 32\n#define SQ_BUF_RSC_WRD3_DST_SEL_X_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_W_SZ        3\n#define SQ_BUF_RSC_WRD3_FORMAT_SZ           6\n#define SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ     2\n#define SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ   1\n#define SQ_BUF_RSC_WRD3_LLC_NOALLOC_SZ      2\n#define SQ_BUF_RSC_WORD3_OOB_SELECT_SZ      2\n#define SQ_BUF_RSC_WRD3_TYPE_SZ             2\nstruct sq_buf_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int                : 3;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int                : 2;\n  unsigned int LLC_NOALLOC    : SQ_BUF_RSC_WRD3_LLC_NOALLOC_SZ;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int LLC_NOALLOC    : SQ_BUF_RSC_WRD3_LLC_NOALLOC_SZ;\n  unsigned int                : 2;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int                : 3;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n\n#endif\n};\nunion SQ_BUF_RSRC_WORD3 {\n  sq_buf_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_IMG_RSC_WRD0_REG_SZ 32\n#define SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ 32\nstruct sq_img_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD0 {\n  sq_img_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD1_REG_SZ 32\n#define SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ  8\n#define SQ_IMG_RSC_WRD1_LLC_NOALLOC_SZ      2\n#define SQ_IMG_RSC_WRD1_BIG_PAGE_SZ         1\n#define SQ_IMG_RSC_WRD1_MAX_MIP_SZ          4\n#define SQ_IMG_RSC_WRD1_FORMAT_SZ           8\n#define SQ_IMG_RSC_WRD1_WIDTH_LO            2\n\nstruct sq_img_rsrc_word1_t{\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int                 : 5;\n  unsigned int LLC_NOALLOC     : SQ_IMG_RSC_WRD1_LLC_NOALLOC_SZ;\n  unsigned int BIG_PAGE        : SQ_IMG_RSC_WRD1_BIG_PAGE_SZ;\n  unsigned int MAX_MIP         : SQ_IMG_RSC_WRD1_MAX_MIP_SZ;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int                 : 2;\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n  unsigned int                 : 2;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int MAX_MIP         : SQ_IMG_RSC_WRD1_MAX_MIP_SZ;\n  unsigned int BIG_PAGE        : SQ_IMG_RSC_WRD1_BIG_PAGE_SZ;\n  unsigned int LLC_NOALLOC     : SQ_IMG_RSC_WRD1_LLC_NOALLOC_SZ;\n  unsigned int                 : 5;\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD1 {\n  sq_img_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD2_REG_SZ 32\n#define SQ_IMG_RSC_WRD2_WIDTH_HI_SZ        12\n#define SQ_IMG_RSC_WRD2_HEIGHT_SZ          14\nstruct sq_img_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_HI_SZ;\n  unsigned int                : 2;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int                : 2;\n  unsigned int                : 2;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int                : 2;\n  unsigned int                : 2;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int                : 2;\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD2 {\n  sq_img_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD3_REG_SZ 32\n#define SQ_IMG_RSC_WRD3_DST_SEL_X_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_W_SZ  3\n#define SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ 4\n#define SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ 4\n#define SQ_IMG_RSC_WRD3_SW_MODE_SZ    5\n#define SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ 3\n#define SQ_IMG_RSC_WRD3_TYPE_SZ       4\nstruct sq_img_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int BASE_LEVEL : SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int SW_MODE    : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int W_MODE     : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int BASE_LEVEL : SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD3 {\n  sq_img_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD4_REG_SZ 32\n#define SQ_IMG_RSC_WRD4_DEPTH_SZ    13\n#define SQ_IMG_RSC_WRD4_PITCH_SZ    14\n#define SQ_IMG_RSC_WRD4_BASE_ARR_SZ 13\nunion sq_img_rsrc_word4_t {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    // For arrays this is last slice in view, for 3D this is depth-1, For remaining this is pitch-1\n    unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ;\n    unsigned int            : 1;  // Pitch[13]\n    unsigned int            : 2;\n    unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n    unsigned int            : 3;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int            : 3;\n    unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n    unsigned int            : 2;\n    unsigned int            : 1;  // Pitch[13]\n    unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ;\n#endif\n  };\n\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    // For 1d, 2d and 2d-msaa in gfx1030 this is pitch-1\n    unsigned int PITCH      : SQ_IMG_RSC_WRD4_PITCH_SZ;\n    unsigned int            : SQ_IMG_RSC_WRD4_REG_SZ-SQ_IMG_RSC_WRD4_PITCH_SZ;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int            : SQ_IMG_RSC_WRD4_REG_SZ-SQ_IMG_RSC_WRD4_PITCH_SZ;\n    unsigned int PITCH      : SQ_IMG_RSC_WRD4_PITCH_SZ;\n#endif\n  };\n};\nunion SQ_IMG_RSRC_WORD4 {\n  sq_img_rsrc_word4_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD4_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD5_REG_SZ 32\n#define SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ               4\n#define SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ               4\n#define SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ              4\n#define SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ               4\n#define SQ_IMG_RSC_WRD5_PERF_MOD_SZ                  3\n#define SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ            1\n#define SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ           1\n#define SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN               1\n#define SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ               1\n#define SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ                5\n\n\nstruct sq_img_rsrc_word5_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int ARRAY_PITCH          : SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ;\n  unsigned int                      : 4;\n  unsigned int DEPTH_SCALE          : SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ;\n  unsigned int HEIGHT_SCALE         : SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ;\n  unsigned int WIDTH_SCALE          : SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int LOD_HWD_CNT          : SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN;\n  unsigned int PRT_DEFAULT          : SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ;\n  unsigned int MIN_LOD_LO           : SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ;\n\n#elif defined(BIGENDIAN_CPU)\n  unsigned int MIN_LOD_LO           : SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ;\n  unsigned int PRT_DEFAULT          : SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ;\n  unsigned int LOD_HWD_CNT          : SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int WIDTH_SCALE          : SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ;\n  unsigned int HEIGHT_SCALE         : SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ;\n  unsigned int DEPTH_SCALE          : SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ;\n  unsigned int                      : 4;\n  unsigned int ARRAY_PITCH          : SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ;\n#endif\n};\n\nunion SQ_IMG_RSRC_WORD5 {\n  sq_img_rsrc_word5_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD5_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD6_REG_SZ 32\n#define SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ             7\n#define SQ_IMG_RSC_WRD6_ITERATE_256               1\n#define SQ_IMG_RSC_WRD6_SAMPLE_PATTERN_OFFSET     4\n#define SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ      2\n#define SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ        2\n#define SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ      1\n#define SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ      1\n#define SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ     1\n#define SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ        1\n#define SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ        1\n#define SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ         8\nstruct sq_img_rsrc_word6_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int MIN_LOD_HI            : SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ;\n  unsigned int                       : 3;\n  unsigned int ITERATE_256           : SQ_IMG_RSC_WRD6_ITERATE_256;\n  unsigned int SAMPLE_PATTERN_OFFSET : SQ_IMG_RSC_WRD6_SAMPLE_PATTERN_OFFSET;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int META_PIPE_ALIGNED     : SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int ALPHA_IS_ON_MSB       : SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ;\n  unsigned int COLOR_TRANSFORM       : SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ;\n  unsigned int META_DATA_ADDRESS     : SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS     : SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ;\n  unsigned int COLOR_TRANSFORM       : SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ;\n  unsigned int ALPHA_IS_ON_MSB       : SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int META_PIPE_ALIGNED     : SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int SAMPLE_PATTERN_OFFSET : SQ_IMG_RSC_WRD6_SAMPLE_PATTERN_OFFSET;\n  unsigned int ITERATE_256           : SQ_IMG_RSC_WRD6_ITERATE_256;\n  unsigned int                       : 3;\n  unsigned int MIN_LOD_HI            : SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD6 {\n  sq_img_rsrc_word6_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD6_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD7_REG_SZ 32\n#define SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ 32\nstruct sq_img_rsrc_word7_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS_HI : SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS_HI : SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD7 {\n  sq_img_rsrc_word7_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD7_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n/**********************************************************/\n/**********************************************************/\n\n#define SQ_IMG_SAMP_WORD0_REG_SZ 32\n#define SQ_IMG_SAMP_WORD0_CLAMP_X_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ            3\n#define SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ    3\n#define SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ 3\n#define SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ 1\n#define SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ    3\n#define SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ     1\n#define SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ      1\n#define SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ         6\n#define SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ        1\n#define SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ  1\n#define SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ        2\n#define SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ       1\nstruct sq_img_samp_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD0 {\n  sq_img_samp_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD1_REG_SZ 32\n#define SQ_IMG_SAMP_WORD1_MIN_LOD_SZ  12\n#define SQ_IMG_SAMP_WORD1_MAX_LOD_SZ  12\n#define SQ_IMG_SAMP_WORD1_PERF_MIP_SZ 4\n#define SQ_IMG_SAMP_WORD1_PERF_Z_SZ   4\nstruct sq_img_samp_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int PERF_MIP : SQ_IMG_SAMP_WORD1_PERF_MIP_SZ;\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n  unsigned int PERF_MIP : SQ_IMG_SAMP_WORD1_PERF_MIP_SZ;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD1 {\n  sq_img_samp_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD2_REG_SZ 32\n#define SQ_IMG_SAMP_WORD2_BC_PTR_SZ               12\n#define SQ_IMG_SAMP_WORD2_BC_TYPE_SZ              2\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ         6\n#define SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_Z_FILTER_SZ             2\n#define SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ           2\n#define SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ       1\n#define SQ_IMG_SAMP_WORD2_BLEND_PTR_SZ            1\n#define SQ_IMG_SAMP_WORD2_DERIV_ADJUST_EN_SZ      1\nstruct sq_img_samp_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BC_PTR             : SQ_IMG_SAMP_WORD2_BC_PTR_SZ;\n  unsigned int BC_TYPE            : SQ_IMG_SAMP_WORD2_BC_TYPE_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int                    : 1;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int BLEND_PRT          : SQ_IMG_SAMP_WORD2_BLEND_PTR_SZ;\n  unsigned int DERIV_ADJUST_EN    : SQ_IMG_SAMP_WORD2_DERIV_ADJUST_EN_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int DERIV_ADJUST_EN    : SQ_IMG_SAMP_WORD2_DERIV_ADJUST_EN_SZ \n  unsigned int BLEND_PRT          : SQ_IMG_SAMP_WORD2_BLEND_PRT_SZ;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int                    : 1;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int BC_TYPE            : SQ_IMG_SAMP_WORD2_BC_TYPE_SZ;\n  unsigned int BC_PTR             : SQ_IMG_SAMP_WORD2_BC_PTR_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD2 {\n  sq_img_samp_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD3_REG_SZ 32\n#define SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ 16\n#define SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ      2\n#define SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ     12\n#define SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ 2\n\nstruct sq_img_samp_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int GRAD_ADJ_OR_DAV   : SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ;\n  unsigned int RES_OR_DAV        : SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ;\n  unsigned int BCP_LRS_DAV       : SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ;\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n  unsigned int BCP_LRS_DAV       : SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ;\n  unsigned int RES_OR_DAV        : SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ;\n  unsigned int GRAD_ADJ_OR_DAV   : SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD3 {\n  sq_img_samp_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**************************************************************/\n/**************************************************************/\n/**************************************************************/\n\ntypedef enum FMT {\nFMT_INVALID                              = 0x00000000,\nFMT_8                                    = 0x00000001,\nFMT_16                                   = 0x00000002,\nFMT_8_8                                  = 0x00000003,\nFMT_32                                   = 0x00000004,\nFMT_16_16                                = 0x00000005,\nFMT_10_11_11                             = 0x00000006,\nFMT_11_11_10                             = 0x00000007,\nFMT_10_10_10_2                           = 0x00000008,\nFMT_2_10_10_10                           = 0x00000009,\nFMT_8_8_8_8                              = 0x0000000a,\nFMT_32_32                                = 0x0000000b,\nFMT_16_16_16_16                          = 0x0000000c,\nFMT_32_32_32                             = 0x0000000d,\nFMT_32_32_32_32                          = 0x0000000e,\nFMT_RESERVED_78                          = 0x0000000f,\nFMT_5_6_5                                = 0x00000010,\nFMT_1_5_5_5                              = 0x00000011,\nFMT_5_5_5_1                              = 0x00000012,\nFMT_4_4_4_4                              = 0x00000013,\nFMT_8_24                                 = 0x00000014,\nFMT_24_8                                 = 0x00000015,\nFMT_X24_8_32                             = 0x00000016,\nFMT_RESERVED_155                         = 0x00000017,\n} FMT;\n\ntypedef enum type {\nTYPE_UNORM                               = 0x00000000,\nTYPE_SNORM                               = 0x00000001,\nTYPE_USCALED                             = 0x00000002,\nTYPE_SSCALED                             = 0x00000003,\nTYPE_UINT                                = 0x00000004,\nTYPE_SINT                                = 0x00000005,\nTYPE_SRGB                                = 0x00000006,\nTYPE_FLOAT                               = 0x00000007,\nTYPE_RESERVED_8                          = 0x00000008,\nTYPE_RESERVED_9                          = 0x00000009,\nTYPE_UNORM_UINT                          = 0x0000000a,\nTYPE_REVERSED_UNORM                      = 0x0000000b,\nTYPE_FLOAT_CLAMP                         = 0x0000000c,\n} type;\n\nenum FORMAT {\nCFMT_INVALID             = 0,\nCFMT_8_UNORM             = 1,\nCFMT_8_SNORM             = 2,\nCFMT_8_USCALED           = 3,\nCFMT_8_SSCALED           = 4,\nCFMT_8_UINT              = 5,\nCFMT_8_SINT              = 6,\nCFMT_16_UNORM            = 7,\nCFMT_16_SNORM            = 8,\nCFMT_16_USCALED          = 9,\nCFMT_16_SSCALED          = 10,\nCFMT_16_UINT             = 11,\nCFMT_16_SINT             = 12,\nCFMT_16_FLOAT            = 13,\nCFMT_8_8_UNORM           = 14,\nCFMT_8_8_SNORM           = 15,\nCFMT_8_8_USCALED         = 16,\nCFMT_8_8_SSCALED         = 17,\nCFMT_8_8_UINT            = 18,\nCFMT_8_8_SINT            = 19,\nCFMT_32_UINT             = 20,\nCFMT_32_SINT             = 21,\nCFMT_32_FLOAT            = 22,\nCFMT_16_16_UNORM         = 23,\nCFMT_16_16_SNORM         = 24,\nCFMT_16_16_USCALED       = 25,\nCFMT_16_16_SSCALED       = 26,\nCFMT_16_16_UINT          = 27,\nCFMT_16_16_SINT          = 28,\nCFMT_16_16_FLOAT         = 29,\nCFMT_10_11_11_FLOAT      = 30,\nCFMT_11_11_10_FLOAT      = 31,\nCFMT_10_10_10_2_UNORM    = 32,\nCFMT_10_10_10_2_SNORM    = 33,\nCFMT_10_10_10_2_UINT     = 34,\nCFMT_10_10_10_2_SINT     = 35,\nCFMT_2_10_10_10_UNORM    = 36,\nCFMT_2_10_10_10_SNORM    = 37,\nCFMT_2_10_10_10_USCALED  = 38,\nCFMT_2_10_10_10_SSCALED  = 39,\nCFMT_2_10_10_10_UINT     = 40,\nCFMT_2_10_10_10_SINT     = 41,\nCFMT_8_8_8_8_UNORM       = 42,\nCFMT_8_8_8_8_SNORM       = 43,\nCFMT_8_8_8_8_USCALED     = 44,\nCFMT_8_8_8_8_SSCALED     = 45,\nCFMT_8_8_8_8_UINT        = 46,\nCFMT_8_8_8_8_SINT        = 47,\nCFMT_32_32_UINT          = 48,\nCFMT_32_32_SINT          = 49,\nCFMT_32_32_FLOAT         = 50,\nCFMT_16_16_16_16_UNORM   = 51,\nCFMT_16_16_16_16_SNORM   = 52,\nCFMT_16_16_16_16_USCALED = 53,\nCFMT_16_16_16_16_SSCALED = 54,\nCFMT_16_16_16_16_UINT    = 55,\nCFMT_16_16_16_16_SINT    = 56,\nCFMT_16_16_16_16_FLOAT   = 57,\nCFMT_32_32_32_UINT       = 58,\nCFMT_32_32_32_SINT       = 59,\nCFMT_32_32_32_FLOAT      = 60,\nCFMT_32_32_32_32_UINT    = 61,\nCFMT_32_32_32_32_SINT    = 62,\nCFMT_32_32_32_32_FLOAT   = 63,\nCFMT_8_SRGB              = 64,\nCFMT_8_8_SRGB            = 65,\nCFMT_8_8_8_8_SRGB        = 66,\nCFMT_5_9_9_9_FLOAT       = 67,\nCFMT_5_6_5_UNORM         = 68,\nCFMT_1_5_5_5_UNORM       = 69,\nCFMT_5_5_5_1_UNORM       = 70,\nCFMT_4_4_4_4_UNORM       = 71,\nCFMT_4_4_UNORM           = 72,\nCFMT_1_UNORM             = 73,\nCFMT_1_REVERSED_UNORM    = 74,\nCFMT_32_FLOAT_CLAMP      = 75,\nCFMT_8_24_UNORM          = 76,\nCFMT_8_24_UINT           = 77,\nCFMT_24_8_UNORM          = 78,\nCFMT_24_8_UINT           = 79,\nCFMT_X24_8_32_UINT       = 80,\nCFMT_X24_8_32_FLOAT      = 81,\n};\n\ntypedef enum SEL {\n  SEL_0 = 0x00000000,\n  SEL_1 = 0x00000001,\n  SEL_X = 0x00000004,\n  SEL_Y = 0x00000005,\n  SEL_Z = 0x00000006,\n  SEL_W = 0x00000007,\n} SEL;\n\ntypedef enum SQ_RSRC_IMG_TYPE {\n  SQ_RSRC_IMG_1D            = 0x00000008,\n  SQ_RSRC_IMG_2D            = 0x00000009,\n  SQ_RSRC_IMG_3D            = 0x0000000a,\n  SQ_RSRC_IMG_CUBE_ARRAY    = 0x0000000b,\n  SQ_RSRC_IMG_1D_ARRAY      = 0x0000000c,\n  SQ_RSRC_IMG_2D_ARRAY      = 0x0000000d,\n  SQ_RSRC_IMG_2D_MSAA       = 0x0000000e,\n  SQ_RSRC_IMG_2D_MSAA_ARRAY = 0x0000000f,\n} SQ_RSRC_IMG_TYPE;\n\ntypedef enum SQ_TEX_XY_FILTER {\n  SQ_TEX_XY_FILTER_POINT          = 0x00000000,\n  SQ_TEX_XY_FILTER_BILINEAR       = 0x00000001,\n  SQ_TEX_XY_FILTER_ANISO_POINT    = 0x00000002,\n  SQ_TEX_XY_FILTER_ANISO_BILINEAR = 0x00000003,\n} SQ_TEX_XY_FILTER;\n\ntypedef enum SQ_TEX_Z_FILTER {\n  SQ_TEX_Z_FILTER_NONE   = 0x00000000,\n  SQ_TEX_Z_FILTER_POINT  = 0x00000001,\n  SQ_TEX_Z_FILTER_LINEAR = 0x00000002,\n} SQ_TEX_Z_FILTER;\n\ntypedef enum SQ_TEX_MIP_FILTER {\n  SQ_TEX_MIP_FILTER_NONE                = 0x00000000,\n  SQ_TEX_MIP_FILTER_POINT               = 0x00000001,\n  SQ_TEX_MIP_FILTER_LINEAR              = 0x00000002,\n  SQ_TEX_MIP_FILTER_POINT_ANISO_ADJ__VI = 0x00000003,\n} SQ_TEX_MIP_FILTER;\n\ntypedef enum SQ_TEX_CLAMP {\n  SQ_TEX_WRAP                    = 0x00000000,\n  SQ_TEX_MIRROR                  = 0x00000001,\n  SQ_TEX_CLAMP_LAST_TEXEL        = 0x00000002,\n  SQ_TEX_MIRROR_ONCE_LAST_TEXEL  = 0x00000003,\n  SQ_TEX_CLAMP_HALF_BORDER       = 0x00000004,\n  SQ_TEX_MIRROR_ONCE_HALF_BORDER = 0x00000005,\n  SQ_TEX_CLAMP_BORDER            = 0x00000006,\n  SQ_TEX_MIRROR_ONCE_BORDER      = 0x00000007,\n} SQ_TEX_CLAMP;\n\ntypedef enum SQ_TEX_BORDER_COLOR {\n  SQ_TEX_BORDER_COLOR_TRANS_BLACK  = 0x00000000,\n  SQ_TEX_BORDER_COLOR_OPAQUE_BLACK = 0x00000001,\n  SQ_TEX_BORDER_COLOR_OPAQUE_WHITE = 0x00000002,\n  SQ_TEX_BORDER_COLOR_REGISTER     = 0x00000003,\n} SQ_TEX_BORDER_COLOR;\n\ntypedef enum TEX_BC_SWIZZLE {\nTEX_BC_Swizzle_XYZW = 0x00000000,\nTEX_BC_Swizzle_XWYZ = 0x00000001,\nTEX_BC_Swizzle_WZYX = 0x00000002,\nTEX_BC_Swizzle_WXYZ = 0x00000003,\nTEX_BC_Swizzle_ZYXW = 0x00000004,\nTEX_BC_Swizzle_YXWZ = 0x00000005,\n} TEX_BC_SWIZZLE;\n\ntypedef struct metadata_amd_gfx11_s {\n  uint32_t version;   // Must be 1\n  uint32_t vendorID;  // AMD\n  SQ_IMG_RSRC_WORD0 word0;\n  SQ_IMG_RSRC_WORD1 word1;\n  SQ_IMG_RSRC_WORD2 word2;\n  SQ_IMG_RSRC_WORD3 word3;\n  SQ_IMG_RSRC_WORD4 word4;\n  SQ_IMG_RSRC_WORD5 word5;\n  SQ_IMG_RSRC_WORD6 word6;\n  SQ_IMG_RSRC_WORD7 word7;\n  uint32_t mip_offsets[0];\n} metadata_amd_gfx11_t;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_RESOURCE_GFX11_H_\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource_gfx12.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_RESOURCE_GFX12_H_\n#define EXT_IMAGE_RESOURCE_GFX12_H_\n\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_BUF_RSC_WRD0_REG_SZ 32\n#define SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ 32\n\nstruct sq_buf_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD0 {\n  sq_buf_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n\n/***********/\n\n/* Note: These registers are also defined/used in registers.h\n * in SQ_BUF_RSRC_WORD*_GFX12\n */\n#define SQ_BUF_RSC_WRD1_REG_SZ 32\n#define SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ  16\n#define SQ_BUF_RSC_WRD1_STRIDE_SZ           14\n#define SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ   2\nstruct sq_buf_rsrc_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD1 {\n  sq_buf_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD2_REG_SZ 32\n#define SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ 32\nstruct sq_buf_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#endif\n};\nunion SQ_BUF_RSRC_WORD2 {\n  sq_buf_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD3_REG_SZ 32\n#define SQ_BUF_RSC_WRD3_DST_SEL_X_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_W_SZ        3\n#define SQ_BUF_RSC_WRD3_FORMAT_SZ           6\n#define SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ     2\n#define SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ   1\n#define SQ_BUF_RSC_WRD3_WRITE_COMPRESS_ENABLE_SZ   1\n#define SQ_BUF_RSC_WRD3_COMPRESSION_EN_SZ          1\n#define SQ_BUF_RSC_WRD3_COMPRESSION_ACCESS_MODE_SZ 2\n#define SQ_BUF_RSC_WORD3_OOB_SELECT_SZ      2\n#define SQ_BUF_RSC_WRD3_TYPE_SZ             2\nstruct sq_buf_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int                : 3;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_BUF_RSC_WRD3_WRITE_COMPRESS_ENABLE_SZ;\n  unsigned int COMPRESSION_EN : SQ_BUF_RSC_WRD3_COMPRESSION_EN_SZ;\n  unsigned int COMPRESSION_ACCESS_MODE : SQ_BUF_RSC_WRD3_COMPRESSION_ACCESS_MODE_SZ;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int COMPRESSION_ACCESS_MODE : SQ_BUF_RSC_WRD3_COMPRESSION_ACCESS_MODE_SZ;\n  unsigned int COMPRESSION_EN : SQ_BUF_RSC_WRD3_COMPRESSION_EN_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_BUF_RSC_WRD3_WRITE_COMPRESS_ENABLE_SZ;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int                : 3;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n#endif\n};\nunion SQ_BUF_RSRC_WORD3 {\n  sq_buf_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_IMG_RSC_WRD0_REG_SZ 32\n#define SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ 32\nstruct sq_img_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD0 {\n  sq_img_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD1_REG_SZ 32\n#define SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ  8\n#define SQ_IMG_RSC_WRD1_MAX_MIP_SZ          5\n#define SQ_IMG_RSC_WRD1_FORMAT_SZ           8\n#define SQ_IMG_RSC_WRD1_BASE_LEVEL_SZ       5\n#define SQ_IMG_RSC_WRD1_WIDTH_LO            2\n\nstruct sq_img_rsrc_word1_t{\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int                 : 4;\n  unsigned int MAX_MIP         : SQ_IMG_RSC_WRD1_MAX_MIP_SZ;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int BASE_LEVEL      : SQ_IMG_RSC_WRD1_BASE_LEVEL_SZ;\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n  unsigned int BASE_LEVEL      : SQ_IMG_RSC_WRD1_BASE_LEVEL_SZ;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int MAX_MIP         : SQ_IMG_RSC_WRD1_MAX_MIP_SZ;\n  unsigned int                 : 4;\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD1 {\n  sq_img_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD2_REG_SZ 32\n#define SQ_IMG_RSC_WRD2_WIDTH_HI_SZ        14\n#define SQ_IMG_RSC_WRD2_HEIGHT_SZ          16\nstruct sq_img_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_HI_SZ;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int                : 2;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int                : 2;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD2 {\n  sq_img_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD3_REG_SZ 32\n#define SQ_IMG_RSC_WRD3_DST_SEL_X_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_W_SZ  3\n#define SQ_IMG_RSC_WRD3_NO_EDGE_CLAMP_SZ 1\n#define SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ 5\n#define SQ_IMG_RSC_WRD3_SW_MODE_SZ    5\n#define SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ 3\n#define SQ_IMG_RSC_WRD3_TYPE_SZ       4\nstruct sq_img_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int NO_EDGE_CLAMP : SQ_IMG_RSC_WRD3_NO_EDGE_CLAMP_SZ;\n  unsigned int            : 2;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int SW_MODE    : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int SW_MODE    : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int            : 2;\n  unsigned int NO_EDGE_CLAMP : SQ_IMG_RSC_WRD3_NO_EDGE_CLAMP_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD3 {\n  sq_img_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD4_REG_SZ 32\n#define SQ_IMG_RSC_WRD4_DEPTH_SZ    14\n#define SQ_IMG_RSC_WRD4_PITCH_MSB_SZ 2\n#define SQ_IMG_RSC_WRD4_BASE_ARR_SZ 13\n#define SQ_IMG_RSC_WRD4_BASE_ARRAY_MSB_SZ 1\n\nstruct sq_img_rsrc_word4_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ;\n  unsigned int PITCH_MSB  : SQ_IMG_RSC_WRD4_PITCH_MSB_SZ;\n  unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n  unsigned int BASE_ARRAY_MSB : SQ_IMG_RSC_WRD4_BASE_ARRAY_MSB_SZ;\n  unsigned int            : 2;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int            : 2;\n  unsigned int BASE_ARRAY_MSB : SQ_IMG_RSC_WRD4_BASE_ARRAY_MSB_SZ;\n  unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n  unsigned int PITCH_MSB  : SQ_IMG_RSC_WRD4_PITCH_MSB_SZ;\n  unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD4 {\n  sq_img_rsrc_word4_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD4_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD5_REG_SZ 32\n#define SQ_IMG_RSC_WRD5_UAV3D_SZ                     1\n#define SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ               5\n#define SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ              5\n#define SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ               5  // Combined two consecutive separate fields width[0:2] and width[3:4].\n#define SQ_IMG_RSC_WRD5_PERF_MOD_SZ                  3\n#define SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ            1\n#define SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ           1\n#define SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN_SZ            1\n#define SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ                6  // lowest 6 bits of MIN_LOD (13 bit total)\n\nstruct sq_img_rsrc_word5_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int                      : 4;\n  unsigned int UAV3D                : SQ_IMG_RSC_WRD5_UAV3D_SZ;\n  unsigned int DEPTH_SCALE          : SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ;\n  unsigned int HEIGHT_SCALE         : SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ;\n  unsigned int WIDTH_SCALE          : SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int LOD_HWD_CNT_EN       : SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN_SZ;\n  unsigned int MIN_LOD_LO           : SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int MIN_LOD_LO           : SQ_IMG_RSC_WRD5_MIN_LOD_LO_SZ;\n  unsigned int LOD_HWD_CNT_EN       : SQ_IMG_RSC_WRD5_LOD_HWD_CNT_EN_SZ;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int WIDTH_SCALE          : SQ_IMG_RSC_WRD5_WIDTH_SCALE_SZ;\n  unsigned int HEIGHT_SCALE         : SQ_IMG_RSC_WRD5_HEIGHT_SCALE_SZ;\n  unsigned int DEPTH_SCALE          : SQ_IMG_RSC_WRD5_DEPTH_SCALE_SZ;\n  unsigned int UAV3D                : SQ_IMG_RSC_WRD5_UAV3D_SZ;\n  unsigned int                      : 4;\n#endif\n};\n\nunion SQ_IMG_RSRC_WORD5 {\n  sq_img_rsrc_word5_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD5_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD6_REG_SZ 32\n\n#define SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ              7\n#define SQ_IMG_RSC_WRD5_COUNTER_BANK_ID_SZ         8  // 3 fields combined into bank_id\n#define SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ       1\n#define SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ         2\n#define SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ       1\n#define SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ      1\n#define SQ_IMG_RSC_WRD6_COMPRESSION_ACCESS_MODE_SZ 2\n#define SQ_IMG_RSC_WRD6_SPECULATIVE_READ_SZ        2\n\nstruct sq_img_rsrc_word6_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int MIN_LOD_HI            : SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ;\n  unsigned int COUNTER_BANK_ID       : SQ_IMG_RSC_WRD5_COUNTER_BANK_ID_SZ;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int                       : 1;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int                       : 1;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int COMPRESSION_ACCESS_MODE : SQ_IMG_RSC_WRD6_COMPRESSION_ACCESS_MODE_SZ;\n  unsigned int SPECULATIVE_READ      : SQ_IMG_RSC_WRD6_SPECULATIVE_READ_SZ;\n  unsigned int                       : 6;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int                       : 6;\n  unsigned int SPECULATIVE_READ      : SQ_IMG_RSC_WRD6_SPECULATIVE_READ_SZ;\n  unsigned int COMPRESSION_ACCESS_MODE : SQ_IMG_RSC_WRD6_COMPRESSION_ACCESS_MODE_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int                       : 1;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int                       : 1;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int COUNTER_BANK_ID       : SQ_IMG_RSC_WRD5_COUNTER_BANK_ID_SZ;\n  unsigned int MIN_LOD_HI            : SQ_IMG_RSC_WRD6_MIN_LOD_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD6 {\n  sq_img_rsrc_word6_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD6_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD7_REG_SZ 32\nstruct sq_img_rsrc_word7_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int : 32;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int : 32;\n#endif\n};\nunion SQ_IMG_RSRC_WORD7 {\n  sq_img_rsrc_word7_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD7_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n/**********************************************************/\n/**********************************************************/\n\n\n\n\t\n#define SQ_IMG_SAMP_WORD0_REG_SZ 32\n#define SQ_IMG_SAMP_WORD0_CLAMP_X_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ            3\n#define SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ    3\n#define SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ 3\n#define SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ 1\n#define SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ    3\n#define SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ     1\n#define SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ      1\n#define SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ         6\n#define SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ        1\n#define SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ  1\n#define SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ        2\n#define SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ       1\nstruct sq_img_samp_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD0 {\n  sq_img_samp_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD1_REG_SZ 32\n#define SQ_IMG_SAMP_WORD1_MIN_LOD_SZ 13\n#define SQ_IMG_SAMP_WORD1_MAX_LOD_SZ 13\n#define SQ_IMG_SAMP_WORD1_PERF_Z_SZ   4\nstruct sq_img_samp_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int : 2;\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n  unsigned int : 2;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD1 {\n  sq_img_samp_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD2_REG_SZ 32\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SZ            14\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ         6\n#define SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_Z_FILTER_SZ             2\n#define SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ           2\n#define SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ       1\n#define SQ_IMG_SAMP_WORD2_PERF_MIP_LO_SZ          2\nstruct sq_img_samp_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int LOD_BIAS           : SQ_IMG_SAMP_WORD2_LOD_BIAS_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int                    : 1;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int PERF_MIP_LO        : SQ_IMG_SAMP_WORD2_PERF_MIP_LO_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int PERF_MIP_LO        : SQ_IMG_SAMP_WORD2_PERF_MIP_LO_SZ;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int                    : 1;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int LOD_BIAS           : SQ_IMG_SAMP_WORD2_LOD_BIAS_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD2 {\n  sq_img_samp_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n\n#define SQ_IMG_SAMP_WORD3_REG_SZ 32\n#define SQ_IMG_SAMP_WORD3_PERF_MIP_HI_SZ       2\n#define SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SZ 12\n#define SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ   2\n\nstruct sq_img_samp_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int PERF_MIP_HI       : SQ_IMG_SAMP_WORD3_PERF_MIP_HI_SZ;\n  unsigned int                   : 16;\n  unsigned int BORDER_COLOR_PTR  : SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SZ;\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n  unsigned int BORDER_COLOR_PTR  : SQ_IMG_SAMP_WORD3_BORDER_COLOR_PTR_SZ;\n  unsigned int                   : 16;\n  unsigned int PERF_MIP_HI       : SQ_IMG_SAMP_WORD3_PERF_MIP_HI_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD3 {\n  sq_img_samp_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**************************************************************/\n/**************************************************************/\n/**************************************************************/\n\ntypedef enum FMT {\nFMT_INVALID                              = 0x00000000,\nFMT_8                                    = 0x00000001,\nFMT_16                                   = 0x00000002,\nFMT_8_8                                  = 0x00000003,\nFMT_32                                   = 0x00000004,\nFMT_16_16                                = 0x00000005,\nFMT_10_11_11                             = 0x00000006,\nFMT_11_11_10                             = 0x00000007,\nFMT_10_10_10_2                           = 0x00000008,\nFMT_2_10_10_10                           = 0x00000009,\nFMT_8_8_8_8                              = 0x0000000a,\nFMT_32_32                                = 0x0000000b,\nFMT_16_16_16_16                          = 0x0000000c,\nFMT_32_32_32                             = 0x0000000d,\nFMT_32_32_32_32                          = 0x0000000e,\nFMT_RESERVED_78                          = 0x0000000f,\nFMT_5_6_5                                = 0x00000010,\nFMT_1_5_5_5                              = 0x00000011,\nFMT_5_5_5_1                              = 0x00000012,\nFMT_4_4_4_4                              = 0x00000013,\nFMT_8_24                                 = 0x00000014,\nFMT_24_8                                 = 0x00000015,\nFMT_X24_8_32                             = 0x00000016,\nFMT_RESERVED_155                         = 0x00000017,\n} FMT;\n\ntypedef enum type {\nTYPE_UNORM                               = 0x00000000,\nTYPE_SNORM                               = 0x00000001,\nTYPE_USCALED                             = 0x00000002,\nTYPE_SSCALED                             = 0x00000003,\nTYPE_UINT                                = 0x00000004,\nTYPE_SINT                                = 0x00000005,\nTYPE_SRGB                                = 0x00000006,\nTYPE_FLOAT                               = 0x00000007,\nTYPE_RESERVED_8                          = 0x00000008,\nTYPE_RESERVED_9                          = 0x00000009,\nTYPE_UNORM_UINT                          = 0x0000000a,\nTYPE_REVERSED_UNORM                      = 0x0000000b,\nTYPE_FLOAT_CLAMP                         = 0x0000000c,\n} type;\n\nenum FORMAT {\nCFMT_INVALID             = 0,\nCFMT_8_UNORM             = 1,\nCFMT_8_SNORM             = 2,\nCFMT_8_USCALED           = 3,\nCFMT_8_SSCALED           = 4,\nCFMT_8_UINT              = 5,\nCFMT_8_SINT              = 6,\nCFMT_16_UNORM            = 7,\nCFMT_16_SNORM            = 8,\nCFMT_16_USCALED          = 9,\nCFMT_16_SSCALED          = 10,\nCFMT_16_UINT             = 11,\nCFMT_16_SINT             = 12,\nCFMT_16_FLOAT            = 13,\nCFMT_8_8_UNORM           = 14,\nCFMT_8_8_SNORM           = 15,\nCFMT_8_8_USCALED         = 16,\nCFMT_8_8_SSCALED         = 17,\nCFMT_8_8_UINT            = 18,\nCFMT_8_8_SINT            = 19,\nCFMT_32_UINT             = 20,\nCFMT_32_SINT             = 21,\nCFMT_32_FLOAT            = 22,\nCFMT_16_16_UNORM         = 23,\nCFMT_16_16_SNORM         = 24,\nCFMT_16_16_USCALED       = 25,\nCFMT_16_16_SSCALED       = 26,\nCFMT_16_16_UINT          = 27,\nCFMT_16_16_SINT          = 28,\nCFMT_16_16_FLOAT         = 29,\nCFMT_10_11_11_FLOAT      = 30,\nCFMT_11_11_10_FLOAT      = 31,\nCFMT_10_10_10_2_UNORM    = 32,\nCFMT_10_10_10_2_SNORM    = 33,\nCFMT_10_10_10_2_UINT     = 34,\nCFMT_10_10_10_2_SINT     = 35,\nCFMT_2_10_10_10_UNORM    = 36,\nCFMT_2_10_10_10_SNORM    = 37,\nCFMT_2_10_10_10_USCALED  = 38,\nCFMT_2_10_10_10_SSCALED  = 39,\nCFMT_2_10_10_10_UINT     = 40,\nCFMT_2_10_10_10_SINT     = 41,\nCFMT_8_8_8_8_UNORM       = 42,\nCFMT_8_8_8_8_SNORM       = 43,\nCFMT_8_8_8_8_USCALED     = 44,\nCFMT_8_8_8_8_SSCALED     = 45,\nCFMT_8_8_8_8_UINT        = 46,\nCFMT_8_8_8_8_SINT        = 47,\nCFMT_32_32_UINT          = 48,\nCFMT_32_32_SINT          = 49,\nCFMT_32_32_FLOAT         = 50,\nCFMT_16_16_16_16_UNORM   = 51,\nCFMT_16_16_16_16_SNORM   = 52,\nCFMT_16_16_16_16_USCALED = 53,\nCFMT_16_16_16_16_SSCALED = 54,\nCFMT_16_16_16_16_UINT    = 55,\nCFMT_16_16_16_16_SINT    = 56,\nCFMT_16_16_16_16_FLOAT   = 57,\nCFMT_32_32_32_UINT       = 58,\nCFMT_32_32_32_SINT       = 59,\nCFMT_32_32_32_FLOAT      = 60,\nCFMT_32_32_32_32_UINT    = 61,\nCFMT_32_32_32_32_SINT    = 62,\nCFMT_32_32_32_32_FLOAT   = 63,\nCFMT_8_SRGB              = 64,\nCFMT_8_8_SRGB            = 65,\nCFMT_8_8_8_8_SRGB        = 66,\nCFMT_5_9_9_9_FLOAT       = 67,\nCFMT_5_6_5_UNORM         = 68,\nCFMT_1_5_5_5_UNORM       = 69,\nCFMT_5_5_5_1_UNORM       = 70,\nCFMT_4_4_4_4_UNORM       = 71,\nCFMT_4_4_UNORM           = 72,\nCFMT_1_UNORM             = 73,\nCFMT_1_REVERSED_UNORM    = 74,\nCFMT_32_FLOAT_CLAMP      = 75,\nCFMT_8_24_UNORM          = 76,\nCFMT_8_24_UINT           = 77,\nCFMT_24_8_UNORM          = 78,\nCFMT_24_8_UINT           = 79,\nCFMT_X24_8_32_UINT       = 80,\nCFMT_X24_8_32_FLOAT      = 81,\n};\n\ntypedef enum SEL {\n  SEL_0 = 0x00000000,\n  SEL_1 = 0x00000001,\n  SEL_X = 0x00000004,\n  SEL_Y = 0x00000005,\n  SEL_Z = 0x00000006,\n  SEL_W = 0x00000007,\n} SEL;\n\ntypedef enum SQ_RSRC_IMG_TYPE {\n  SQ_RSRC_IMG_1D            = 0x00000008,\n  SQ_RSRC_IMG_2D            = 0x00000009,\n  SQ_RSRC_IMG_3D            = 0x0000000a,\n  SQ_RSRC_IMG_CUBE_ARRAY    = 0x0000000b,\n  SQ_RSRC_IMG_1D_ARRAY      = 0x0000000c,\n  SQ_RSRC_IMG_2D_ARRAY      = 0x0000000d,\n  SQ_RSRC_IMG_2D_MSAA       = 0x0000000e,\n  SQ_RSRC_IMG_2D_MSAA_ARRAY = 0x0000000f,\n} SQ_RSRC_IMG_TYPE;\n\ntypedef enum SQ_TEX_XY_FILTER {\n  SQ_TEX_XY_FILTER_POINT          = 0x00000000,\n  SQ_TEX_XY_FILTER_BILINEAR       = 0x00000001,\n  SQ_TEX_XY_FILTER_ANISO_POINT    = 0x00000002,\n  SQ_TEX_XY_FILTER_ANISO_BILINEAR = 0x00000003,\n} SQ_TEX_XY_FILTER;\n\ntypedef enum SQ_TEX_Z_FILTER {\n  SQ_TEX_Z_FILTER_NONE   = 0x00000000,\n  SQ_TEX_Z_FILTER_POINT  = 0x00000001,\n  SQ_TEX_Z_FILTER_LINEAR = 0x00000002,\n} SQ_TEX_Z_FILTER;\n\ntypedef enum SQ_TEX_MIP_FILTER {\n  SQ_TEX_MIP_FILTER_NONE                = 0x00000000,\n  SQ_TEX_MIP_FILTER_POINT               = 0x00000001,\n  SQ_TEX_MIP_FILTER_LINEAR              = 0x00000002,\n  SQ_TEX_MIP_FILTER_POINT_ANISO_ADJ__VI = 0x00000003,\n} SQ_TEX_MIP_FILTER;\n\ntypedef enum SQ_TEX_CLAMP {\n  SQ_TEX_WRAP                    = 0x00000000,\n  SQ_TEX_MIRROR                  = 0x00000001,\n  SQ_TEX_CLAMP_LAST_TEXEL        = 0x00000002,\n  SQ_TEX_MIRROR_ONCE_LAST_TEXEL  = 0x00000003,\n  SQ_TEX_CLAMP_HALF_BORDER       = 0x00000004,\n  SQ_TEX_MIRROR_ONCE_HALF_BORDER = 0x00000005,\n  SQ_TEX_CLAMP_BORDER            = 0x00000006,\n  SQ_TEX_MIRROR_ONCE_BORDER      = 0x00000007,\n} SQ_TEX_CLAMP;\n\ntypedef enum SQ_TEX_BORDER_COLOR {\n  SQ_TEX_BORDER_COLOR_TRANS_BLACK  = 0x00000000,\n  SQ_TEX_BORDER_COLOR_OPAQUE_BLACK = 0x00000001,\n  SQ_TEX_BORDER_COLOR_OPAQUE_WHITE = 0x00000002,\n  SQ_TEX_BORDER_COLOR_REGISTER     = 0x00000003,\n} SQ_TEX_BORDER_COLOR;\n\ntypedef enum TEX_BC_SWIZZLE {\nTEX_BC_Swizzle_XYZW = 0x00000000,\nTEX_BC_Swizzle_XWYZ = 0x00000001,\nTEX_BC_Swizzle_WZYX = 0x00000002,\nTEX_BC_Swizzle_WXYZ = 0x00000003,\nTEX_BC_Swizzle_ZYXW = 0x00000004,\nTEX_BC_Swizzle_YXWZ = 0x00000005,\n} TEX_BC_SWIZZLE;\n\ntypedef struct metadata_amd_gfx12_s {\n  uint32_t version;   // Must be 1\n  uint32_t vendorID;  // AMD\n  SQ_IMG_RSRC_WORD0 word0;\n  SQ_IMG_RSRC_WORD1 word1;\n  SQ_IMG_RSRC_WORD2 word2;\n  SQ_IMG_RSRC_WORD3 word3;\n  SQ_IMG_RSRC_WORD4 word4;\n  SQ_IMG_RSRC_WORD5 word5;\n  SQ_IMG_RSRC_WORD6 word6;\n  SQ_IMG_RSRC_WORD7 word7;\n  uint32_t mip_offsets[0];\n} metadata_amd_gfx12_t;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_RESOURCE_GFX12_H_\n\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource_kv.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_RESOURCE_KV_H\n#define HSA_RUNTIME_EXT_IMAGE_RESOURCE_KV_H\n\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\nunion SQ_BUF_RSRC_WORD0 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int base_address : 32;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int base_address : 32;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_BUF_RSRC_WORD1 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int base_address_hi : 16;\n    unsigned int stride : 14;\n    unsigned int cache_swizzle : 1;\n    unsigned int swizzle_enable : 1;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int swizzle_enable : 1;\n    unsigned int cache_swizzle : 1;\n    unsigned int stride : 14;\n    unsigned int base_address_hi : 16;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_BUF_RSRC_WORD2 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int num_records : 32;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int num_records : 32;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_BUF_RSRC_WORD3 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int dst_sel_x : 3;\n    unsigned int dst_sel_y : 3;\n    unsigned int dst_sel_z : 3;\n    unsigned int dst_sel_w : 3;\n    unsigned int num_format : 3;\n    unsigned int data_format : 4;\n    unsigned int element_size : 2;\n    unsigned int index_stride : 2;\n    unsigned int add_tid_enable : 1;\n    unsigned int atc : 1;\n    unsigned int hash_enable : 1;\n    unsigned int heap : 1;\n    unsigned int mtype : 3;\n    unsigned int type : 2;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int type : 2;\n    unsigned int mtype : 3;\n    unsigned int heap : 1;\n    unsigned int hash_enable : 1;\n    unsigned int atc : 1;\n    unsigned int add_tid_enable : 1;\n    unsigned int index_stride : 2;\n    unsigned int element_size : 2;\n    unsigned int data_format : 4;\n    unsigned int num_format : 3;\n    unsigned int dst_sel_w : 3;\n    unsigned int dst_sel_z : 3;\n    unsigned int dst_sel_y : 3;\n    unsigned int dst_sel_x : 3;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD0 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int base_address : 32;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int base_address : 32;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD1 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int base_address_hi : 8;\n    unsigned int min_lod : 12;\n    unsigned int data_format : 6;\n    unsigned int num_format : 4;\n    unsigned int mtype : 2;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int mtype : 2;\n    unsigned int num_format : 4;\n    unsigned int data_format : 6;\n    unsigned int min_lod : 12;\n    unsigned int base_address_hi : 8;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD2 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int width : 14;\n    unsigned int height : 14;\n    unsigned int perf_mod : 3;\n    unsigned int interlaced : 1;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int interlaced : 1;\n    unsigned int perf_mod : 3;\n    unsigned int height : 14;\n    unsigned int width : 14;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD3 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int dst_sel_x : 3;\n    unsigned int dst_sel_y : 3;\n    unsigned int dst_sel_z : 3;\n    unsigned int dst_sel_w : 3;\n    unsigned int base_level : 4;\n    unsigned int last_level : 4;\n    unsigned int tiling_index : 5;\n    unsigned int pow2_pad : 1;\n    unsigned int mtype : 1;\n    unsigned int atc : 1;\n    unsigned int type : 4;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int type : 4;\n    unsigned int atc : 1;\n    unsigned int mtype : 1;\n    unsigned int pow2_pad : 1;\n    unsigned int tiling_index : 5;\n    unsigned int last_level : 4;\n    unsigned int base_level : 4;\n    unsigned int dst_sel_w : 3;\n    unsigned int dst_sel_z : 3;\n    unsigned int dst_sel_y : 3;\n    unsigned int dst_sel_x : 3;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD4 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int depth : 13;\n    unsigned int pitch : 14;\n    unsigned int : 5;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int : 5;\n    unsigned int pitch : 14;\n    unsigned int depth : 13;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD5 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int base_array : 13;\n    unsigned int last_array : 13;\n    unsigned int : 6;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int : 6;\n    unsigned int last_array : 13;\n    unsigned int base_array : 13;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD6 {\n  struct {\n#if\tdefined(LITTLEENDIAN_CPU)\n    unsigned int min_lod_warn : 12;\n    unsigned int counter_bank_id : 8;\n    unsigned int lod_hdw_cnt_en : 1;\n    unsigned int compression_en : 1;\n    unsigned int alpha_is_on_msb : 1;\n    unsigned int color_transform : 1;\n    unsigned int lost_alpha_bits : 4;\n    unsigned int lost_color_bits : 4;\n#elif\tdefined(BIGENDIAN_CPU)\n    unsigned int lost_color_bits : 4;\n    unsigned int lost_alpha_bits : 4;\n    unsigned int color_transform : 1;\n    unsigned int alpha_is_on_msb : 1;\n    unsigned int compression_en : 1;\n    unsigned int lod_hdw_cnt_en : 1;\n    unsigned int counter_bank_id : 8;\n    unsigned int min_lod_warn : 12;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_RSRC_WORD7 {\n  struct {\n#if\t\tdefined(LITTLEENDIAN_CPU)\n    unsigned int meta_data_address : 32;\n#elif\t\tdefined(BIGENDIAN_CPU)\n    unsigned int meta_data_address : 32;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_SAMP_WORD0 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int CLAMP_X : 3;\n    unsigned int CLAMP_Y : 3;\n    unsigned int CLAMP_Z : 3;\n    unsigned int max_aniso_ratio : 3;\n    unsigned int depth_compare_func : 3;\n    unsigned int force_unormalized : 1;\n    unsigned int aniso_threshold : 3;\n    unsigned int mc_coord_trunc : 1;\n    unsigned int force_degamma : 1;\n    unsigned int aniso_bias : 6;\n    unsigned int trunc_coord : 1;\n    unsigned int disable_cube_wrap : 1;\n    unsigned int filter_mode : 2;\n    unsigned int compat_mode : 1;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int compat_mode : 1;\n    unsigned int filter_mode : 2;\n    unsigned int disable_cube_wrap : 1;\n    unsigned int trunc_coord : 1;\n    unsigned int aniso_bias : 6;\n    unsigned int force_degamma : 1;\n    unsigned int mc_coord_trunc : 1;\n    unsigned int aniso_threshold : 3;\n    unsigned int force_unormalized : 1;\n    unsigned int depth_compare_func : 3;\n    unsigned int max_aniso_ratio : 3;\n    unsigned int CLAMP_Z : 3;\n    unsigned int CLAMP_Y : 3;\n    unsigned int CLAMP_X : 3;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_SAMP_WORD1 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int min_lod : 12;\n    unsigned int max_lod : 12;\n    unsigned int perf_mip : 4;\n    unsigned int perf_z : 4;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int perf_z : 4;\n    unsigned int perf_mip : 4;\n    unsigned int max_lod : 12;\n    unsigned int min_lod : 12;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_SAMP_WORD2 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int lod_bias : 14;\n    unsigned int lod_bias_sec : 6;\n    unsigned int xy_mag_filter : 2;\n    unsigned int xy_min_filter : 2;\n    unsigned int z_filter : 2;\n    unsigned int mip_filter : 2;\n    unsigned int mip_point_preclamp : 1;\n    unsigned int disable_lsb_ceil : 1;\n    unsigned int filter_prec_fix : 1;\n    unsigned int aniso_override_vi : 1;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int aniso_override_vi : 1;\n    unsigned int filter_prec_fix : 1;\n    unsigned int disable_lsb_ceil : 1;\n    unsigned int mip_point_preclamp : 1;\n    unsigned int mip_filter : 2;\n    unsigned int z_filter : 2;\n    unsigned int xy_min_filter : 2;\n    unsigned int xy_mag_filter : 2;\n    unsigned int lod_bias_sec : 6;\n    unsigned int lod_bias : 14;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\nunion SQ_IMG_SAMP_WORD3 {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    unsigned int border_color_ptr : 12;\n    unsigned int : 18;\n    unsigned int border_color_type : 2;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int border_color_type : 2;\n    unsigned int : 18;\n    unsigned int border_color_ptr : 12;\n#endif\n  } bitfields, bits;\n  unsigned int u32_all;\n  signed int i32_all;\n  float f32_all;\n};\n\ntypedef enum FMT {\n  FMT_INVALID = 0x00000000,\n  FMT_8 = 0x00000001,\n  FMT_16 = 0x00000002,\n  FMT_8_8 = 0x00000003,\n  FMT_32 = 0x00000004,\n  FMT_16_16 = 0x00000005,\n  FMT_10_10_10_2 = 0x00000008,\n  FMT_2_10_10_10 = 0x00000009,\n  FMT_8_8_8_8 = 0x0000000a,\n  FMT_32_32 = 0x0000000b,\n  FMT_16_16_16_16 = 0x0000000c,\n  FMT_32_32_32 = 0x0000000d,\n  FMT_32_32_32_32 = 0x0000000e,\n  FMT_5_6_5 = 0x00000010,\n  FMT_1_5_5_5 = 0x00000011,\n  FMT_5_5_5_1 = 0x00000012,\n  FMT_8_24 = 0x00000014,\n  FMT_24_8 = 0x00000015,\n  FMT_X24_8_32 = 0x00000016,\n  FMT_RESERVED_24__SI__CI = 0x00000018\n} FMT;\n\ntypedef enum type {\n  TYPE_UNORM = 0x00000000,\n  TYPE_SNORM = 0x00000001,\n  TYPE_UINT = 0x00000004,\n  TYPE_SINT = 0x00000005,\n  TYPE_FLOAT = 0x00000007,\n  TYPE_SRGB = 0x00000009\n} type;\n\ntypedef enum SEL {\n  SEL_0 = 0x00000000,\n  SEL_1 = 0x00000001,\n  SEL_X = 0x00000004,\n  SEL_Y = 0x00000005,\n  SEL_Z = 0x00000006,\n  SEL_W = 0x00000007,\n} SEL;\n\ntypedef enum SQ_RSRC_IMG_TYPE {\n  SQ_RSRC_IMG_1D = 0x00000008,\n  SQ_RSRC_IMG_2D = 0x00000009,\n  SQ_RSRC_IMG_3D = 0x0000000a,\n  SQ_RSRC_IMG_1D_ARRAY = 0x0000000c,\n  SQ_RSRC_IMG_2D_ARRAY = 0x0000000d,\n} SQ_RSRC_IMG_TYPE;\n\ntypedef enum SQ_TEX_XY_FILTER {\n  SQ_TEX_XY_FILTER_POINT = 0x00000000,\n  SQ_TEX_XY_FILTER_BILINEAR = 0x00000001,\n  SQ_TEX_XY_FILTER_ANISO_POINT = 0x00000002,\n  SQ_TEX_XY_FILTER_ANISO_BILINEAR = 0x00000003,\n} SQ_TEX_XY_FILTER;\n\ntypedef enum SQ_TEX_Z_FILTER {\n  SQ_TEX_Z_FILTER_NONE = 0x00000000,\n  SQ_TEX_Z_FILTER_POINT = 0x00000001,\n  SQ_TEX_Z_FILTER_LINEAR = 0x00000002,\n} SQ_TEX_Z_FILTER;\n\ntypedef enum SQ_TEX_MIP_FILTER {\n  SQ_TEX_MIP_FILTER_NONE = 0x00000000,\n  SQ_TEX_MIP_FILTER_POINT = 0x00000001,\n  SQ_TEX_MIP_FILTER_LINEAR = 0x00000002,\n  SQ_TEX_MIP_FILTER_POINT_ANISO_ADJ__VI = 0x00000003,\n} SQ_TEX_MIP_FILTER;\n\ntypedef enum SQ_TEX_CLAMP {\n  SQ_TEX_WRAP = 0x00000000,\n  SQ_TEX_MIRROR = 0x00000001,\n  SQ_TEX_CLAMP_LAST_TEXEL = 0x00000002,\n  SQ_TEX_MIRROR_ONCE_LAST_TEXEL = 0x00000003,\n  SQ_TEX_CLAMP_HALF_BORDER = 0x00000004,\n  SQ_TEX_MIRROR_ONCE_HALF_BORDER = 0x00000005,\n  SQ_TEX_CLAMP_BORDER = 0x00000006,\n  SQ_TEX_MIRROR_ONCE_BORDER = 0x00000007,\n} SQ_TEX_CLAMP;\n\ntypedef enum SQ_TEX_BORDER_COLOR {\n  SQ_TEX_BORDER_COLOR_TRANS_BLACK = 0x00000000,\n  SQ_TEX_BORDER_COLOR_OPAQUE_BLACK = 0x00000001,\n  SQ_TEX_BORDER_COLOR_OPAQUE_WHITE = 0x00000002,\n  SQ_TEX_BORDER_COLOR_REGISTER = 0x00000003,\n} SQ_TEX_BORDER_COLOR;\n\ntypedef struct metadata_amd_ci_vi_s {\n    uint32_t version; // Must be 1\n    uint32_t vendorID; // AMD | CZ\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD6 word6;\n    SQ_IMG_RSRC_WORD7 word7;\n    uint32_t mip_offsets[0]; //Mip level offset bits [39:8] for each level (if any)\n} metadata_amd_ci_vi_t;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // HSA_RUNTIME_EXT_IMAGE_RESOURCE_KV_H\n"
  },
  {
    "path": "runtime/hsa-runtime/image/resource_nv.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef EXT_IMAGE_RESOURCE_NV_H_\n#define EXT_IMAGE_RESOURCE_NV_H_\n\n#if defined(LITTLEENDIAN_CPU)\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_BUF_RSC_WRD0_REG_SZ 32\n#define SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ 32\n\nstruct sq_buf_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_BUF_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD0 {\n  sq_buf_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n\n/***********/\n\n#define SQ_BUF_RSC_WRD1_REG_SZ 32\n#define SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ  16\n#define SQ_BUF_RSC_WRD1_STRIDE_SZ           14\n#define SQ_BUF_RSC_WRD1_CACHE_SWIZZLE_SZ    1\n#define SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ   1\nstruct sq_buf_rsrc_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int CACHE_SWIZZLE   : SQ_BUF_RSC_WRD1_CACHE_SWIZZLE_SZ;\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SWIZZLE_ENABLE  : SQ_BUF_RSC_WRD1_SWIZZLE_ENABLE_SZ;\n  unsigned int CACHE_SWIZZLE   : SQ_BUF_RSC_WRD1_CACHE_SWIZZLE_SZ;\n  unsigned int STRIDE          : SQ_BUF_RSC_WRD1_STRIDE_SZ;\n  unsigned int BASE_ADDRESS_HI : SQ_BUF_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\n\nunion SQ_BUF_RSRC_WORD1 {\n  sq_buf_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD2_REG_SZ 32\n#define SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ 32\nstruct sq_buf_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int NUM_RECORDS : SQ_BUF_RSC_WRD2_NUM_RECORDS_SZ;\n#endif\n};\nunion SQ_BUF_RSRC_WORD2 {\n  sq_buf_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_BUF_RSC_WRD3_REG_SZ 32\n#define SQ_BUF_RSC_WRD3_DST_SEL_X_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ        3\n#define SQ_BUF_RSC_WRD3_DST_SEL_W_SZ        3\n#define SQ_BUF_RSC_WRD3_FORMAT_SZ           7\n#define SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ     2\n#define SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ   1\n#define SQ_BUF_RSC_WRD3_RESOURCE_LEVEL      1\n#define SQ_BUF_RSC_WRD3_RESERVED_1          2\n#define SQ_BUF_RSC_WORD3_OOB_SELECT_SZ      2\n#define SQ_BUF_RSC_WRD3_TYPE_SZ             2\nstruct sq_buf_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int                : 2;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int RESOURCE_LEVEL : SQ_BUF_RSC_WRD3_RESOURCE_LEVEL;\n  unsigned int                : 1;\n  unsigned int RESERVED_1     : SQ_BUF_RSC_WRD3_RESERVED_1;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE           : SQ_BUF_RSC_WRD3_TYPE_SZ;\n  unsigned int OOB_SELECT     : SQ_BUF_RSC_WORD3_OOB_SELECT_SZ;\n  unsigned int RESERVED_1     : SQ_BUF_RSC_WRD3_RESERVED_1;\n  unsigned int                : 1;\n  unsigned int RESOURCE_LEVEL : SQ_BUF_RSC_WRD3_RESOURCE_LEVEL;\n  unsigned int ADD_TID_ENABLE : SQ_BUF_RSC_WRD3_ADD_TID_ENABLE_SZ;\n  unsigned int INDEX_STRIDE   : SQ_BUF_RSC_WRD3_INDEX_STRIDE_SZ;\n  unsigned int                : 2;\n  unsigned int FORMAT         : SQ_BUF_RSC_WRD3_FORMAT_SZ;\n  unsigned int DST_SEL_W      : SQ_BUF_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z      : SQ_BUF_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y      : SQ_BUF_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X      : SQ_BUF_RSC_WRD3_DST_SEL_X_SZ;\n\n#endif\n};\nunion SQ_BUF_RSRC_WORD3 {\n  sq_buf_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_BUF_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**********************************************************/\n/**********************************************************/\n#define SQ_IMG_RSC_WRD0_REG_SZ 32\n#define SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ 32\nstruct sq_img_rsrc_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BASE_ADDRESS : SQ_IMG_RSC_WRD0_BASE_ADDRESS_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD0 {\n  sq_img_rsrc_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD1_REG_SZ 32\n#define SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ  8\n#define SQ_IMG_RSC_WRD1_MIN_LOD_SZ          12\n#define SQ_IMG_RSC_WRD1_FORMAT_SZ           9\n#define SQ_IMG_RSC_WRD1_WIDTH_LO            2\n\nstruct sq_img_rsrc_word1_t{\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n  unsigned int MIN_LOD         : SQ_IMG_RSC_WRD1_MIN_LOD_SZ;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int                 : 1;\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int WIDTH           : SQ_IMG_RSC_WRD1_WIDTH_LO;\n  unsigned int                 : 1;\n  unsigned int FORMAT          : SQ_IMG_RSC_WRD1_FORMAT_SZ;\n  unsigned int MIN_LOD         : SQ_IMG_RSC_WRD1_MIN_LOD_SZ;\n  unsigned int BASE_ADDRESS_HI : SQ_IMG_RSC_WRD1_BASE_ADDRESS_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD1 {\n  sq_img_rsrc_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD2_REG_SZ 32\n#define SQ_IMG_RSC_WRD2_WIDTH_HI_SZ        12\n#define SQ_IMG_RSC_WRD2_HEIGHT_SZ          14\n#define SQ_IMG_RSC_WRD2_RESOURCE_LEVEL_SZ  1\nstruct sq_img_rsrc_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_HI_SZ;\n  unsigned int                : 2;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int                : 2;\n  unsigned int                : 1;\n  unsigned int RESOURCE_LEVEL : SQ_IMG_RSC_WRD2_RESOURCE_LEVEL_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int RESOURCE_LEVEL : SQ_IMG_RSC_WRD2_RESOURCE_LEVEL_SZ;\n  unsigned int RESERVED       : 1;\n  unsigned int RESERVED       : 2;\n  unsigned int HEIGHT         : SQ_IMG_RSC_WRD2_HEIGHT_SZ;\n  unsigned int                : 2;\n  unsigned int WIDTH_HI       : SQ_IMG_RSC_WRD2_WIDTH_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD2 {\n  sq_img_rsrc_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD3_REG_SZ 32\n#define SQ_IMG_RSC_WRD3_DST_SEL_X_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ  3\n#define SQ_IMG_RSC_WRD3_DST_SEL_W_SZ  3\n#define SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ 4\n#define SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ 4\n#define SQ_IMG_RSC_WRD3_SW_MODE_SZ    5\n#define SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ 3\n#define SQ_IMG_RSC_WRD3_TYPE_SZ       4\nstruct sq_img_rsrc_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int BASE_LEVEL : SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int SW_MODE    : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int TYPE       : SQ_IMG_RSC_WRD3_TYPE_SZ;\n  unsigned int BC_SWIZZLE : SQ_IMG_RSC_WRD3_BC_SWIZZLE_SZ;\n  unsigned int W_MODE     : SQ_IMG_RSC_WRD3_SW_MODE_SZ;\n  unsigned int LAST_LEVEL : SQ_IMG_RSC_WRD3_LAST_LEVEL_SZ;\n  unsigned int BASE_LEVEL : SQ_IMG_RSC_WRD3_BASE_LEVEL_SZ;\n  unsigned int DST_SEL_W  : SQ_IMG_RSC_WRD3_DST_SEL_W_SZ;\n  unsigned int DST_SEL_Z  : SQ_IMG_RSC_WRD3_DST_SEL_Z_SZ;\n  unsigned int DST_SEL_Y  : SQ_IMG_RSC_WRD3_DST_SEL_Y_SZ;\n  unsigned int DST_SEL_X  : SQ_IMG_RSC_WRD3_DST_SEL_X_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD3 {\n  sq_img_rsrc_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD4_REG_SZ 32\n#define SQ_IMG_RSC_WRD4_DEPTH_SZ    13\n#define SQ_IMG_RSC_WRD4_BASE_ARR_SZ 13\n#define SQ_IMG_RSC_WRD4_PITCH_SZ 14\nunion sq_img_rsrc_word4_t {\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    // For arrays this is last slice in view, for 3D this is depth-1, For remaining this is pitch-1\n    unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ;\n    unsigned int            : 1; //Pitch[13] in gfx1030\n    unsigned int            : 2;\n    unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n    unsigned int            : 3;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int            : 3;\n    unsigned int BASE_ARRAY : SQ_IMG_RSC_WRD4_BASE_ARR_SZ;\n    unsigned int            : 2;\n    unsigned int            : 1; //Pitch[13] in gfx1030\n    unsigned int DEPTH      : SQ_IMG_RSC_WRD4_DEPTH_SZ; //Pitch[0:12] in gfx1030\n#endif\n  };\n  struct {\n#if defined(LITTLEENDIAN_CPU)\n    // For 1d, 2d and 2d-msaa in gfx1030 this is pitch-1\n    unsigned int PITCH      : SQ_IMG_RSC_WRD4_PITCH_SZ;\n    unsigned int            : SQ_IMG_RSC_WRD4_REG_SZ-SQ_IMG_RSC_WRD4_PITCH_SZ;\n#elif defined(BIGENDIAN_CPU)\n    unsigned int            : SQ_IMG_RSC_WRD4_REG_SZ-SQ_IMG_RSC_WRD4_PITCH_SZ;\n    unsigned int PITCH      : SQ_IMG_RSC_WRD4_PITCH_SZ;\n#endif\n  };\n};\nunion SQ_IMG_RSRC_WORD4 {\n  sq_img_rsrc_word4_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD4_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD5_REG_SZ 32\n#define SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ               4\n#define SQ_IMG_RSC_WRD5_MAX_MIP_SZ                   4\n//#define SQ_IMG_RSC_WRD5_DSCAL_OR_MID_LOD_WRN_SZ      4\n//#define SQ_IMG_RSC_WRD5_HSCAL_OR_MID_LOD_WRN_SZ      4\n//#define SQ_IMG_RSC_WRD5_WSCAL_OR_MID_LOD_WRN_SZ      4\n#define SQ_IMG_RSC_WRD5_MID_LOD_WRN_SZ               12\n#define SQ_IMG_RSC_WRD5_PERF_MOD_SZ                  3\n#define SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ            1\n#define SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ           1\n#define SQ_IMG_RSC_WRD5_LOD_HDW_CNT_EN_SZ            1\n#define SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ               1\n#define SQ_IMG_RSC_WRD5_BIG_PAGE_SZ                  1\n\nstruct sq_img_rsrc_word5_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int ARRAY_PITCH          : SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ;\n  unsigned int MAX_MIP              : SQ_IMG_RSC_WRD5_MAX_MIP_SZ;\n  unsigned int MID_LOD_WRN          : SQ_IMG_RSC_WRD5_MID_LOD_WRN_SZ;\n//  unsigned int DSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_DSCAL_OR_MID_LOD_WRN_SZ;\n//  unsigned int HSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_HSCAL_OR_MID_LOD_WRN_SZ;\n//  unsigned int WSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_WSCAL_OR_MID_LOD_WRN_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int LOD_HDW_CNT_EN       : SQ_IMG_RSC_WRD5_LOD_HDW_CNT_EN_SZ;\n  unsigned int PRT_DEFAULT          : SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ;\n  unsigned int                      : 4;\n  unsigned int BIG_PAGE             : SQ_IMG_RSC_WRD5_BIG_PAGE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BIG_PAGE             : SQ_IMG_RSC_WRD5_BIG_PAGE_SZ;\n  unsigned int                      : 4;\n  unsigned int PRT_DEFAULT          : SQ_IMG_RSC_WRD5_PRT_DEFAULT_SZ;\n  unsigned int LOD_HDW_CNT_EN       : SQ_IMG_RSC_WRD5_LOD_HDW_CNT_EN_SZ;\n  unsigned int LINKED_RESOURCE      : SQ_IMG_RSC_WRD5_LINKED_RESOURCE_SZ;\n  unsigned int CORNER_SAMPLES       : SQ_IMG_RSC_WRD5_CORNER_SAMPLES_SZ;\n  unsigned int PERF_MOD             : SQ_IMG_RSC_WRD5_PERF_MOD_SZ;\n  unsigned int MID_LOD_WRN          : SQ_IMG_RSC_WRD5_MID_LOD_WRN_SZ;\n//  unsigned int WSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_WSCAL_OR_MID_LOD_WRN_SZ;\n//  unsigned int HSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_HSCAL_OR_MID_LOD_WRN_SZ;\n//  unsigned int DSCAL_OR_MID_LOD_WRN : SQ_IMG_RSC_WRD5_DSCAL_OR_MID_LOD_WRN_SZ;\n  unsigned int MAX_MIP              : SQ_IMG_RSC_WRD5_MAX_MIP_SZ;\n  unsigned int ARRAY_PITCH          : SQ_IMG_RSC_WRD5_ARRAY_PITCH_SZ;\n#endif\n};\n\nunion SQ_IMG_RSRC_WORD5 {\n  sq_img_rsrc_word5_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD5_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD6_REG_SZ 32\n#define SQ_IMG_RSC_WRD6_COUNTER_BANK_ID_SZ        8\n#define SQ_IMG_RSC_WRD6_RESERVED_2_SZ             2\n#define SQ_IMG_RSC_WRD6_ITERATE_256_SZ            1\n#define SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ      2\n#define SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ        2\n#define SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ      1\n#define SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ      1\n#define SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ     1\n#define SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ        1\n#define SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ        1\n#define SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ         8\nstruct sq_img_rsrc_word6_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int COUNTER_BANK_ID       : SQ_IMG_RSC_WRD6_COUNTER_BANK_ID_SZ;\n  unsigned int RESERVED_2            : SQ_IMG_RSC_WRD6_RESERVED_2_SZ;\n  unsigned int ITERATE_256           : SQ_IMG_RSC_WRD6_ITERATE_256_SZ;\n  unsigned int                       : 4;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int META_PIPE_ALIGNED     : SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int ALPHA_IS_ON_MSB       : SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ;\n  unsigned int COLOR_TRANSFORM       : SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ;\n  unsigned int META_DATA_ADDRESS     : SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS     : SQ_IMG_RSC_WRD6_META_DATA_ADDR_SZ;\n  unsigned int COLOR_TRANSFORM       : SQ_IMG_RSC_WRD6_COLOR_TRANSFORM_SZ;\n  unsigned int ALPHA_IS_ON_MSB       : SQ_IMG_RSC_WRD6_ALPHA_IS_ON_MSB_SZ;\n  unsigned int COMPRESSION_ENABLE    : SQ_IMG_RSC_WRD6_COMPRESSION_ENABLE_SZ;\n  unsigned int WRITE_COMPRESS_ENABLE : SQ_IMG_RSC_WRD6_WRITE_COMPRESS_EN_SZ;\n  unsigned int META_PIPE_ALIGNED     : SQ_IMG_RSC_WRD6_META_PIPE_ALIGNED_SZ;\n  unsigned int MAX_COMP_BLK_SZ       : SQ_IMG_RSC_WRD6_MAX_COMP_BLK_SZ_SZ;\n  unsigned int MAX_UNCOMP_BLK_SZ     : SQ_IMG_RSC_WRD6_MAX_UNCOMP_BLK_SZ_SZ;\n  unsigned int                       : 4;\n  unsigned int ITERATE_256           : SQ_IMG_RSC_WRD6_ITERATE_256_SZ;\n  unsigned int RESERVED_2            : SQ_IMG_RSC_WRD6_RESERVED_2_SZ;\n  unsigned int COUNTER_BANK_ID       : SQ_IMG_RSC_WRD6_COUNTER_BANK_ID_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD6 {\n  sq_img_rsrc_word6_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD6_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_RSC_WRD7_REG_SZ 32\n#define SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ 32\nstruct sq_img_rsrc_word7_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS_HI : SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int META_DATA_ADDRESS_HI : SQ_IMG_RSC_WRD7_META_DATA_ADDRESS_HI_SZ;\n#endif\n};\nunion SQ_IMG_RSRC_WORD7 {\n  sq_img_rsrc_word7_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_RSC_WRD7_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n/**********************************************************/\n/**********************************************************/\n\n#define SQ_IMG_SAMP_WORD0_REG_SZ 32\n#define SQ_IMG_SAMP_WORD0_CLAMP_X_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ            3\n#define SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ            3\n#define SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ    3\n#define SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ 3\n#define SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ 1\n#define SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ    3\n#define SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ     1\n#define SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ      1\n#define SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ         6\n#define SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ        1\n#define SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ  1\n#define SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ        2\n#define SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ       1\nstruct sq_img_samp_word0_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int SKIP_DEGAMMA       : SQ_IMG_SAMP_WORD0_SKIP_DEGAMMA_SZ;\n  unsigned int FILTER_MODE        : SQ_IMG_SAMP_WORD0_FILTER_MODE_SZ;\n  unsigned int DISABLE_CUBE_WRAP  : SQ_IMG_SAMP_WORD0_DISABLE_CUBE_WRAP_SZ;\n  unsigned int TRUNC_COORD        : SQ_IMG_SAMP_WORD0_TRUNC_COORD_SZ;\n  unsigned int ANISO_BIAS         : SQ_IMG_SAMP_WORD0_ANISO_BIAS_SZ;\n  unsigned int FORCE_DEGAMMA      : SQ_IMG_SAMP_WORD0_FORCE_DEGAMMA_SZ;\n  unsigned int MC_COORD_TRUNC     : SQ_IMG_SAMP_WORD0_MC_COORD_TRUNC_SZ;\n  unsigned int ANISO_THRESHOLD    : SQ_IMG_SAMP_WORD0_ANISO_THRESHOLD_SZ;\n  unsigned int FORCE_UNNORMALIZED : SQ_IMG_SAMP_WORD0_FORCE_UNNORMALIZED_SZ;\n  unsigned int DEPTH_COMPARE_FUNC : SQ_IMG_SAMP_WORD0_DEPTH_COMPARE_FUNC_SZ;\n  unsigned int MAX_ANISO_RATIO    : SQ_IMG_SAMP_WORD0_MAX_ANISO_RATIO_SZ;\n  unsigned int CLAMP_Z            : SQ_IMG_SAMP_WORD0_CLAMP_Z_SZ;\n  unsigned int CLAMP_Y            : SQ_IMG_SAMP_WORD0_CLAMP_Y_SZ;\n  unsigned int CLAMP_X            : SQ_IMG_SAMP_WORD0_CLAMP_X_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD0 {\n  sq_img_samp_word0_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD0_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD1_REG_SZ 32\n#define SQ_IMG_SAMP_WORD1_MIN_LOD_SZ  12\n#define SQ_IMG_SAMP_WORD1_MAX_LOD_SZ  12\n#define SQ_IMG_SAMP_WORD1_PERF_MIP_SZ 4\n#define SQ_IMG_SAMP_WORD1_PERF_Z_SZ   4\nstruct sq_img_samp_word1_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int PERF_MIP : SQ_IMG_SAMP_WORD1_PERF_MIP_SZ;\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int PERF_Z   : SQ_IMG_SAMP_WORD1_PERF_Z_SZ;\n  unsigned int PERF_MIP : SQ_IMG_SAMP_WORD1_PERF_MIP_SZ;\n  unsigned int MAX_LOD  : SQ_IMG_SAMP_WORD1_MAX_LOD_SZ;\n  unsigned int MIN_LOD  : SQ_IMG_SAMP_WORD1_MIN_LOD_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD1 {\n  sq_img_samp_word1_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD1_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD2_REG_SZ 32\n#define SQ_IMG_SAMP_WORD2_BC_LRS_LB_SZ            12\n#define SQ_IMG_SAMP_WORD2_BC_OR_BCT_SZ            2\n#define SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ         6\n#define SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ        2\n#define SQ_IMG_SAMP_WORD2_Z_FILTER_SZ             2\n#define SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ           2\n#define SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SZ   1\n#define SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ       1\n#define SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SZ       1\n#define SQ_IMG_SAMP_WORD2_DERIV_ADJUST_ENABLE_SZ  1\nstruct sq_img_samp_word2_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BC_LRS_LB          : SQ_IMG_SAMP_WORD2_BC_LRS_LB_SZ;\n  unsigned int BC_OR_BCT          : SQ_IMG_SAMP_WORD2_BC_OR_BCT_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int MIP_POINT_PRECLAMP : SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SZ;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int BLEND_ZERO_PRT     : SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SZ;\n  unsigned int DERIV_ADJUST_EN    : SQ_IMG_SAMP_WORD2_DERIV_ADJUST_ENABLE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int DERIV_ADJUST_EN    : SQ_IMG_SAMP_WORD2_DERIV_ADJUST_ENABLE_SZ;\n  unsigned int BLEND_ZERO_PRT     : SQ_IMG_SAMP_WORD2_BLEND_ZERO_PRT_SZ;\n  unsigned int ANISO_OVERRIDE     : SQ_IMG_SAMP_WORD2_ANISO_OVERRIDE_SZ;\n  unsigned int MIP_POINT_PRECLAMP : SQ_IMG_SAMP_WORD2_MIP_POINT_PRECLAMP_SZ;\n  unsigned int MIP_FILTER         : SQ_IMG_SAMP_WORD2_MIP_FILTER_SZ;\n  unsigned int Z_FILTER           : SQ_IMG_SAMP_WORD2_Z_FILTER_SZ;\n  unsigned int XY_MIN_FILTER      : SQ_IMG_SAMP_WORD2_XY_MIN_FILTER_SZ;\n  unsigned int XY_MAG_FILTER      : SQ_IMG_SAMP_WORD2_XY_MAG_FILTER_SZ;\n  unsigned int LOD_BIAS_SEC       : SQ_IMG_SAMP_WORD2_LOD_BIAS_SEC_SZ;\n  unsigned int BC_OR_BCT          : SQ_IMG_SAMP_WORD2_BC_OR_BCT_SZ;\n  unsigned int LOD_BIAS           : SQ_IMG_SAMP_WORD2_BC_LRS_LB_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD2 {\n  sq_img_samp_word2_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD2_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n#define SQ_IMG_SAMP_WORD3_REG_SZ 32\n#define SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ      12\n#define SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ  16\n#define SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ       2\n#define SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ  2\n\nstruct sq_img_samp_word3_t {\n#if defined(LITTLEENDIAN_CPU)\n  unsigned int BCP_LRS_DAV       : SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ;\n  unsigned int GRAD_ADJ_OR_DAV   : SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ;\n  unsigned int RES_OR_DAV        : SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ;\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n#elif defined(BIGENDIAN_CPU)\n  unsigned int BORDER_COLOR_TYPE : SQ_IMG_SAMP_WORD3_BORD_COLOR_TYPE_SZ;\n  unsigned int RES_OR_DAV        : SQ_IMG_SAMP_WORD3_RES_OR_DAV_SZ;\n  unsigned int GRAD_ADJ_OR_DAV   : SQ_IMG_SAMP_WORD3_GRAD_ADJ_OR_DAV_SZ;\n  unsigned int BCP_LRS_DAV       : SQ_IMG_SAMP_WORD3_BCP_LRS_DAV_SZ;\n#endif\n};\n\nunion SQ_IMG_SAMP_WORD3 {\n  sq_img_samp_word3_t bitfields, bits, f;\n  uint32_t val : SQ_IMG_SAMP_WORD3_REG_SZ;\n  uint32_t u32All;\n  int32_t  i32All;\n  float    f32All;\n};\n/***********/\n\n/**************************************************************/\n/**************************************************************/\n/**************************************************************/\n\ntypedef enum FMT {\nFMT_INVALID                              = 0x00000000,\nFMT_8                                    = 0x00000001,\nFMT_16                                   = 0x00000002,\nFMT_8_8                                  = 0x00000003,\nFMT_32                                   = 0x00000004,\nFMT_16_16                                = 0x00000005,\nFMT_10_11_11                             = 0x00000006,\nFMT_11_11_10                             = 0x00000007,\nFMT_10_10_10_2                           = 0x00000008,\nFMT_2_10_10_10                           = 0x00000009,\nFMT_8_8_8_8                              = 0x0000000a,\nFMT_32_32                                = 0x0000000b,\nFMT_16_16_16_16                          = 0x0000000c,\nFMT_32_32_32                             = 0x0000000d,\nFMT_32_32_32_32                          = 0x0000000e,\nFMT_RESERVED_78                          = 0x0000000f,\nFMT_5_6_5                                = 0x00000010,\nFMT_1_5_5_5                              = 0x00000011,\nFMT_5_5_5_1                              = 0x00000012,\nFMT_4_4_4_4                              = 0x00000013,\nFMT_8_24                                 = 0x00000014,\nFMT_24_8                                 = 0x00000015,\nFMT_X24_8_32                             = 0x00000016,\nFMT_RESERVED_155                         = 0x00000017,\nFMT_1                                    = 0x00000018,\nFMT_1_REVERSED                           = 0x00000019,\nFMT_GB_GR                                = 0x0000001a,\nFMT_BG_RG                                = 0x0000001b,\nFMT_4_4                                  = 0x0000001c,\nFMT_BC1                                  = 0x0000001d,\nFMT_BC2                                  = 0x0000001e,\nFMT_BC3                                  = 0x0000001f,\nFMT_BC4                                  = 0x00000020,\nFMT_BC5                                  = 0x00000021,\nFMT_BC6                                  = 0x00000022,\nFMT_BC7                                  = 0x00000023,\nFMT_6E4                                  = 0x00000024,\nFMT_5_9_9_9                              = 0x00000025,\nFMT_FMASK8_S2                            = 0x00000026,\nFMT_FMASK8_S4                            = 0x00000027,\nFMT_FMASK8_S8                            = 0x00000028,\nFMT_FMASK16_S16                          = 0x00000029,\nFMT_FMASK16_S8                           = 0x0000002a,\nFMT_FMASK32_S16                          = 0x0000002b,\nFMT_FMASK32_S8                           = 0x0000002c,\nFMT_FMASK64_S16                          = 0x0000002d,\nFMT_ETC2_RGB                             = 0x0000002e,\nFMT_ETC2_RGBA                            = 0x0000002f,\nFMT_ETC2_R                               = 0x00000030,\nFMT_ETC2_RG                              = 0x00000031,\nFMT_ETC2_RGBA1                           = 0x00000032,\nFMT_ASTC_2D_LDR                          = 0x00000033,\nFMT_ASTC_2D_HDR                          = 0x00000034,\nFMT_ASTC_2D_LDR_SRGB                     = 0x00000035,\nFMT_ASTC_3D_LDR                          = 0x00000036,\nFMT_ASTC_3D_HDR                          = 0x00000037,\nFMT_ASTC_3D_LDR_SRGB                     = 0x00000038,\nFMT_MM_8                                 = 0x00000039,\nFMT_MM_8_8                               = 0x0000003a,\nFMT_MM_8_8_8_8                           = 0x0000003b,\nFMT_MM_VYUY8                             = 0x0000003c,\nFMT_MM_10_11_11                          = 0x0000003d,\nFMT_MM_2_10_10_10                        = 0x0000003e,\nFMT_MM_16_16_16_16                       = 0x0000003f,\nFMT_10_IN_16                             = 0x00000040,\nFMT_10_IN_16_16                          = 0x00000041,\nFMT_10_IN_16_16_16_16                    = 0x00000042,\nFMT_7E3                                  = 0x00000043,\nFMT_YCBCR                                = 0x00000044,\n} FMT;\n\ntypedef enum type {\nTYPE_UNORM                               = 0x00000000,\nTYPE_SNORM                               = 0x00000001,\nTYPE_USCALED                             = 0x00000002,\nTYPE_SSCALED                             = 0x00000003,\nTYPE_UINT                                = 0x00000004,\nTYPE_SINT                                = 0x00000005,\nTYPE_RESERVED_6                          = 0x00000006,\nTYPE_FLOAT                               = 0x00000007,\nTYPE_RESERVED_8                          = 0x00000008,\nTYPE_SRGB                                = 0x00000009,\nTYPE_UNORM_UINT                          = 0x0000000a,\nTYPE_REVERSED_UNORM                      = 0x0000000b,\nTYPE_FLOAT_CLAMP                         = 0x0000000c,\n} type;\n\nenum FORMAT {\nCFMT_INVALID           = 0,\nCFMT_8_UNORM           = 1,\nCFMT_8_SNORM           = 2,\nCFMT_8_UINT            = 5,\nCFMT_8_SINT            = 6,\nCFMT_16_UNORM          = 7,\nCFMT_16_SNORM          = 8,\nCFMT_16_UINT           = 11,\nCFMT_16_SINT           = 12,\nCFMT_16_FLOAT          = 13,\nCFMT_8_8_UNORM         = 14,\nCFMT_8_8_SNORM         = 15,\nCFMT_8_8_UINT          = 18,\nCFMT_8_8_SINT          = 19,\nCFMT_32_UINT           = 20,\nCFMT_32_SINT           = 21,\nCFMT_32_FLOAT          = 22,\nCFMT_16_16_UNORM       = 23,\nCFMT_16_16_SNORM       = 24,\nCFMT_16_16_UINT        = 27,\nCFMT_16_16_SINT        = 28,\nCFMT_16_16_FLOAT       = 29,\nCFMT_10_10_10_2_UNORM  = 44,\nCFMT_10_10_10_2_SNORM  = 45,\nCFMT_10_10_10_2_UINT   = 48,\nCFMT_10_10_10_2_SINT   = 49,\nCFMT_2_10_10_10_UNORM  = 50,\nCFMT_2_10_10_10_SNORM  = 51,\nCFMT_2_10_10_10_UINT   = 54,\nCFMT_2_10_10_10_SINT   = 55,\nCFMT_8_8_8_8_UNORM     = 56,\nCFMT_8_8_8_8_SNORM     = 57,\nCFMT_8_8_8_8_UINT      = 60,\nCFMT_8_8_8_8_SINT      = 61,\nCFMT_32_32_UINT        = 62,\nCFMT_32_32_SINT        = 63,\nCFMT_32_32_FLOAT       = 64,\nCFMT_16_16_16_16_UNORM = 65,\nCFMT_16_16_16_16_SNORM = 66,\nCFMT_16_16_16_16_UINT  = 69,\nCFMT_16_16_16_16_SINT  = 70,\nCFMT_16_16_16_16_FLOAT = 71,\nCFMT_32_32_32_UINT     = 72,\nCFMT_32_32_32_SINT     = 73,\nCFMT_32_32_32_FLOAT    = 74,\nCFMT_32_32_32_32_UINT  = 75,\nCFMT_32_32_32_32_SINT  = 76,\nCFMT_32_32_32_32_FLOAT = 77,\nCFMT_8_SRGB            = 128,\nCFMT_8_8_SRGB          = 129,\nCFMT_8_8_8_8_SRGB      = 130,\nCFMT_5_6_5_UNORM       = 133,\nCFMT_1_5_5_5_UNORM     = 134,\nCFMT_5_5_5_1_UNORM     = 135,\nCFMT_8_24_UNORM        = 141,\nCFMT_8_24_UINT         = 142,\nCFMT_24_8_UNORM        = 143,\nCFMT_24_8_UINT         = 144\n};\n\ntypedef enum SEL {\n  SEL_0 = 0x00000000,\n  SEL_1 = 0x00000001,\n  SEL_X = 0x00000004,\n  SEL_Y = 0x00000005,\n  SEL_Z = 0x00000006,\n  SEL_W = 0x00000007,\n} SEL;\n\ntypedef enum SQ_RSRC_IMG_TYPE {\n  SQ_RSRC_IMG_1D            = 0x00000008,\n  SQ_RSRC_IMG_2D            = 0x00000009,\n  SQ_RSRC_IMG_3D            = 0x0000000a,\n  SQ_RSRC_IMG_CUBE_ARRAY    = 0x0000000b,\n  SQ_RSRC_IMG_1D_ARRAY      = 0x0000000c,\n  SQ_RSRC_IMG_2D_ARRAY      = 0x0000000d,\n  SQ_RSRC_IMG_2D_MSAA       = 0x0000000e,\n  SQ_RSRC_IMG_2D_MSAA_ARRAY = 0x0000000f,\n} SQ_RSRC_IMG_TYPE;\n\ntypedef enum SQ_TEX_XY_FILTER {\n  SQ_TEX_XY_FILTER_POINT          = 0x00000000,\n  SQ_TEX_XY_FILTER_BILINEAR       = 0x00000001,\n  SQ_TEX_XY_FILTER_ANISO_POINT    = 0x00000002,\n  SQ_TEX_XY_FILTER_ANISO_BILINEAR = 0x00000003,\n} SQ_TEX_XY_FILTER;\n\ntypedef enum SQ_TEX_Z_FILTER {\n  SQ_TEX_Z_FILTER_NONE   = 0x00000000,\n  SQ_TEX_Z_FILTER_POINT  = 0x00000001,\n  SQ_TEX_Z_FILTER_LINEAR = 0x00000002,\n} SQ_TEX_Z_FILTER;\n\ntypedef enum SQ_TEX_MIP_FILTER {\n  SQ_TEX_MIP_FILTER_NONE                = 0x00000000,\n  SQ_TEX_MIP_FILTER_POINT               = 0x00000001,\n  SQ_TEX_MIP_FILTER_LINEAR              = 0x00000002,\n  SQ_TEX_MIP_FILTER_POINT_ANISO_ADJ__VI = 0x00000003,\n} SQ_TEX_MIP_FILTER;\n\ntypedef enum SQ_TEX_CLAMP {\n  SQ_TEX_WRAP                    = 0x00000000,\n  SQ_TEX_MIRROR                  = 0x00000001,\n  SQ_TEX_CLAMP_LAST_TEXEL        = 0x00000002,\n  SQ_TEX_MIRROR_ONCE_LAST_TEXEL  = 0x00000003,\n  SQ_TEX_CLAMP_HALF_BORDER       = 0x00000004,\n  SQ_TEX_MIRROR_ONCE_HALF_BORDER = 0x00000005,\n  SQ_TEX_CLAMP_BORDER            = 0x00000006,\n  SQ_TEX_MIRROR_ONCE_BORDER      = 0x00000007,\n} SQ_TEX_CLAMP;\n\ntypedef enum SQ_TEX_BORDER_COLOR {\n  SQ_TEX_BORDER_COLOR_TRANS_BLACK  = 0x00000000,\n  SQ_TEX_BORDER_COLOR_OPAQUE_BLACK = 0x00000001,\n  SQ_TEX_BORDER_COLOR_OPAQUE_WHITE = 0x00000002,\n  SQ_TEX_BORDER_COLOR_REGISTER     = 0x00000003,\n} SQ_TEX_BORDER_COLOR;\n\ntypedef enum TEX_BC_SWIZZLE {\nTEX_BC_Swizzle_XYZW = 0x00000000,\nTEX_BC_Swizzle_XWYZ = 0x00000001,\nTEX_BC_Swizzle_WZYX = 0x00000002,\nTEX_BC_Swizzle_WXYZ = 0x00000003,\nTEX_BC_Swizzle_ZYXW = 0x00000004,\nTEX_BC_Swizzle_YXWZ = 0x00000005,\n} TEX_BC_SWIZZLE;\n\ntypedef struct metadata_amd_nv_s {\n    uint32_t version;  // Must be 1\n    uint32_t vendorID;  // AMD\n    SQ_IMG_RSRC_WORD0 word0;\n    SQ_IMG_RSRC_WORD1 word1;\n    SQ_IMG_RSRC_WORD2 word2;\n    SQ_IMG_RSRC_WORD3 word3;\n    SQ_IMG_RSRC_WORD4 word4;\n    SQ_IMG_RSRC_WORD5 word5;\n    SQ_IMG_RSRC_WORD6 word6;\n    SQ_IMG_RSRC_WORD7 word7;\n    uint32_t mip_offsets[0];\n} metadata_amd_nv_t;\n\n}  // namespace image\n}  // namespace rocr\n#endif  // EXT_IMAGE_RESOURCE_NV_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/image/util.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_EXT_IMAGE_UTIL_H\n#define HSA_RUNTIME_EXT_IMAGE_UTIL_H\n\n#include \"stdint.h\"\n#include \"stddef.h\"\n#include \"stdlib.h\"\n#include <assert.h>\n#include <iostream>\n#include <string>\n#include <algorithm>\n\n#include \"inc/hsa.h\"\n\nnamespace rocr {\nnamespace image {\n\n#if defined(_MSC_VER)\n#define ALIGNED_(x) __declspec(align(x))\n#else\n#if defined(__GNUC__)\n#define ALIGNED_(x) __attribute__((aligned(x)))\n#endif  // __GNUC__\n#endif // _MSC_VER\n\n#define MULTILINE(...) # __VA_ARGS__\n\n#define ASSERT_SIZE_UINT32(desc)                                                                   \\\n  static_assert(sizeof(desc) == sizeof(uint32_t), #desc \" size should be 32-bits\");\n\n}  // namespace image\n}  // namespace rocr\n\n\n#if defined(__GNUC__)\n#include \"mm_malloc.h\"\n#if defined(__i386__) || defined(__x86_64__)\n#include <x86intrin.h>\n#elif defined(__loongarch64)\n#else\n#error                                                                                             \\\n    \"Processor not identified.  \" \\\n            \"Need to provide a lightweight approximate clock interface (aka __rdtsc()).\"\n#endif\n\nnamespace rocr {\nnamespace image {\n\n#define __forceinline __inline__ __attribute__((always_inline))\nstatic __forceinline void __debugbreak() { __builtin_trap(); }\n#define __declspec(x) __attribute__((x))\n#undef __stdcall\n#define __stdcall  // __attribute__((__stdcall__))\n#define __ALIGNED__(x) __attribute__((aligned(x)))\n\nstatic __forceinline void* _aligned_malloc(size_t size, size_t alignment) {\n#ifdef _ISOC11_SOURCE\n  return aligned_alloc(alignment, size);\n#else\n  void* mem = NULL;\n  if (0 != posix_memalign(&mem, alignment, size)) return NULL;\n  return mem;\n#endif\n}\nstatic __forceinline void _aligned_free(void* ptr) { return free(ptr); }\n#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))\n#include \"intrin.h\"\n#define __ALIGNED__(x) __declspec(align(x))\n\nnamespace rocr {\nnamespace image {\n#else\n#error \"Compiler and/or processor not identified.\"\n#endif\n\n// A macro to disallow the copy and move constructor and operator= functions\n#define DISALLOW_COPY_AND_ASSIGN(TypeName)                                                         \\\n  TypeName(const TypeName&) = delete;                                                              \\\n  TypeName(TypeName&&) = delete;                                                                   \\\n  void operator=(const TypeName&) = delete;                                                        \\\n  void operator=(TypeName&&) = delete;\n\ntemplate <typename lambda> class ScopeGuard {\n public:\n  explicit __forceinline ScopeGuard(const lambda& release) : release_(release), dismiss_(false) {}\n\n  ScopeGuard(ScopeGuard& rhs) { *this = rhs; }\n\n  __forceinline ~ScopeGuard() {\n    if (!dismiss_) release_();\n  }\n  __forceinline ScopeGuard& operator=(ScopeGuard& rhs) {\n    dismiss_ = rhs.dismiss_;\n    release_ = rhs.release_;\n    rhs.dismiss_ = true;\n    return *this;\n  }\n  __forceinline void Dismiss() { dismiss_ = true; }\n\n private:\n  lambda release_;\n  bool dismiss_;\n};\n\ntemplate <typename lambda> static __forceinline ScopeGuard<lambda> MakeScopeGuard(lambda rel) {\n  return ScopeGuard<lambda>(rel);\n}\n\n#define MAKE_SCOPE_GUARD_HELPER(lname, sname, ...)                                                 \\\n  auto lname = __VA_ARGS__;                                                                        \\\n  ScopeGuard<decltype(lname)> sname(lname);\n#define MAKE_SCOPE_GUARD(...)                                                                      \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), PASTE(scopeGuard, __COUNTER__),    \\\n                          __VA_ARGS__)\n#define MAKE_NAMED_SCOPE_GUARD(name, ...)                                                          \\\n  MAKE_SCOPE_GUARD_HELPER(PASTE(scopeGuardLambda, __COUNTER__), name, __VA_ARGS__)\n\n/// @brief: Finds out the min one of two inputs, input must support \">\"\n/// operator.\n/// @param: a(Input), a reference to type T.\n/// @param: b(Input), a reference to type T.\n/// @return: T.\ntemplate <class T> static __forceinline T Min(const T& a, const T& b) { return (a > b) ? b : a; }\n\ntemplate <class T, class... Arg> static __forceinline T Min(const T& a, const T& b, Arg... args) {\n  return Min(a, Min(b, args...));\n}\n\n/// @brief: Find out the max one of two inputs, input must support \">\" operator.\n/// @param: a(Input), a reference to type T.\n/// @param: b(Input), a reference to type T.\n/// @return: T.\ntemplate <class T> static __forceinline T Max(const T& a, const T& b) { return (b > a) ? b : a; }\n\ntemplate <class T, class... Arg> static __forceinline T Max(const T& a, const T& b, Arg... args) {\n  return Max(a, Max(b, args...));\n}\n\n/// @brief: Free the memory space which is newed previously.\n/// @param: ptr(Input), a pointer to memory space. Can't be NULL.\n/// @return: void.\nstruct DeleteObject {\n  template <typename T> void operator()(const T* ptr) const { delete ptr; }\n};\n\n/// @brief: Checks if a value is power of two, if it is, return true. Be careful\n/// when passing 0.\n/// @param: val(Input), the data to be checked.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsPowerOfTwo(T val) {\n  return (val & (val - 1)) == 0;\n}\n\n/// @brief: Calculates the floor value aligned based on parameter of alignment.\n/// If value is at the boundary of alignment, it is unchanged.\n/// @param: value(Input), value to be calculated.\n/// @param: alignment(Input), alignment value.\n/// @return: T.\ntemplate <typename T>\nstatic __forceinline T AlignDown(T value, size_t alignment) {\n  assert(IsPowerOfTwo(alignment));\n  return (T)(value & ~(alignment - 1));\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: T*, pointer to type T.\ntemplate <typename T>\nstatic __forceinline T* AlignDown(T* value, size_t alignment) {\n  return (T*)AlignDown((intptr_t)value, alignment);\n}\n\n/// @brief: Calculates the ceiling value aligned based on parameter of\n/// alignment.\n/// If value is at the boundary of alignment, it is unchanged.\n/// @param: value(Input), value to be calculated.\n/// @param: alignment(Input), alignment value.\n/// @param: T.\ntemplate <typename T>\nstatic __forceinline T AlignUp(T value, size_t alignment) {\n  return AlignDown((T)(value + alignment - 1), alignment);\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: T*, pointer to type T.\ntemplate <typename T>\nstatic __forceinline T* AlignUp(T* value, size_t alignment) {\n  return (T*)AlignDown((intptr_t)((uint8_t*)value + alignment - 1), alignment);\n}\n\n/// @brief: Checks if the input value is at the boundary of alignment, if it is,\n/// @return true.\n/// @param: value(Input), value to be checked.\n/// @param: alignment(Input), alignment value.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsMultipleOf(T value, size_t alignment) {\n  return (AlignUp(value, alignment) == value);\n}\n\n/// @brief: Same as previous one, but first parameter becomes pointer, for more\n/// info, see the previous desciption.\n/// @param: value(Input), pointer to type T.\n/// @param: alignment(Input), alignment value.\n/// @return: bool.\ntemplate <typename T>\nstatic __forceinline bool IsMultipleOf(T* value, size_t alignment) {\n  return (AlignUp(value, alignment) == value);\n}\n\nstatic __forceinline uint32_t NextPow2(uint32_t value) {\n  if (value == 0) return 1;\n  uint32_t v = value - 1;\n  v |= v >> 1;\n  v |= v >> 2;\n  v |= v >> 4;\n  v |= v >> 8;\n  v |= v >> 16;\n  return v + 1;\n}\n\nstatic __forceinline uint64_t NextPow2(uint64_t value) {\n  if (value == 0) return 1;\n  uint64_t v = value - 1;\n  v |= v >> 1;\n  v |= v >> 2;\n  v |= v >> 4;\n  v |= v >> 8;\n  v |= v >> 16;\n  v |= v >> 32;\n  return v + 1;\n}\n\nstatic __forceinline bool strIsEmpty(const char* str) noexcept { return str[0] == '\\0'; }\n\nstatic __forceinline std::string& ltrim(std::string& s) {\n  auto it = std::find_if(s.begin(), s.end(),\n                         [](char c) { return !std::isspace<char>(c, std::locale::classic()); });\n  s.erase(s.begin(), it);\n  return s;\n}\n\nstatic __forceinline std::string& rtrim(std::string& s) {\n  auto it = std::find_if(s.rbegin(), s.rend(),\n                         [](char c) { return !std::isspace<char>(c, std::locale::classic()); });\n  s.erase(it.base(), s.end());\n  return s;\n}\n\nstatic __forceinline std::string& trim(std::string& s) { return ltrim(rtrim(s)); }\n\ntemplate<uint32_t lowBit, uint32_t highBit, typename T>\nstatic __forceinline uint32_t BitSelect(T p) {\n  static_assert(sizeof(T) <= sizeof(uintptr_t), \"Type out of range.\");\n  static_assert(highBit < sizeof(uintptr_t)*8, \"Bit index out of range.\");\n\n  uintptr_t ptr = p;\n  if(highBit != (sizeof(uintptr_t)*8-1))\n    return (uint32_t)((ptr & ((1ull<<(highBit+1))-1)) >> lowBit);\n  else\n    return (uint32_t)(ptr >> lowBit);\n}\n\ninline uint32_t PtrLow16Shift8(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFULL) >> 8);\n}\n\ninline uint32_t PtrHigh64Shift16(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFFFFFFFF0000ULL) >> 16);\n}\n\ninline uint32_t PtrLow40Shift8(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFFFFFFULL) >> 8);\n}\n\ninline uint32_t PtrHigh64Shift40(const void* p) {\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(p);\n  return (uint32_t)((ptr & 0xFFFFFF0000000000ULL) >> 40);\n}\n\ninline uint32_t PtrLow32(const void* p) {\n  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p));\n}\n\ninline uint32_t PtrHigh32(const void* p) {\n  uint32_t ptr = 0;\n#ifdef HSA_LARGE_MODEL\n  ptr = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(p) >> 32);\n#endif\n  return ptr;\n}\n\n}  // namespace image\n}  // namespace rocr\n\n#endif  // HSA_RUNTIME_EXT_IMAGE_UTIL_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/Brig.h",
    "content": "// University of Illinois/NCSA\n// Open Source License\n//\n// Copyright (c) 2013-2015, Advanced Micro Devices, Inc.\n// All rights reserved.\n//\n// Developed by:\n//\n//     HSA Team\n//\n//     Advanced Micro Devices, Inc\n//\n//     www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal with\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n//     * Redistributions of source code must retain the above copyright notice,\n//       this list of conditions and the following disclaimers.\n//\n//     * Redistributions in binary form must reproduce the above copyright notice,\n//       this list of conditions and the following disclaimers in the\n//       documentation and/or other materials provided with the distribution.\n//\n//     * Neither the names of the LLVM Team, University of Illinois at\n//       Urbana-Champaign, nor the names of its contributors may be used to\n//       endorse or promote products derived from this Software without specific\n//       prior written permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\n// SOFTWARE.\n\n#ifndef INCLUDED_BRIG_H\n#define INCLUDED_BRIG_H\n\n#include <stddef.h>   /* size_t */\n#include <stdint.h>   /* uintXX_t */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  /* __cplusplus */\n\n/*========================================================================================*/\n/* =======================================================================================*/\n/* =======================================================================================*/\n/* =======================================================================================*/\n\ntypedef uint32_t BrigCodeOffset32_t;\ntypedef uint32_t BrigOperandOffset32_t;\ntypedef uint32_t BrigDataOffset32_t;\n\ntypedef BrigDataOffset32_t BrigDataOffsetCodeList32_t;\ntypedef BrigDataOffset32_t BrigDataOffsetOperandList32_t;\ntypedef BrigDataOffset32_t BrigDataOffsetString32_t;\n\ntypedef uint32_t BrigVersion32_t;\nenum BrigVersion {\n    BRIG_VERSION_HSAIL_MAJOR = 1,\n    BRIG_VERSION_HSAIL_MINOR = 0,\n    BRIG_VERSION_BRIG_MAJOR  = 1,\n    BRIG_VERSION_BRIG_MINOR  = 0\n};\n\ntypedef uint16_t BrigKind16_t;\nenum BrigKind {\n    BRIG_KIND_NONE = 0x0000,\n\n    BRIG_KIND_DIRECTIVE_BEGIN = 0x1000,\n        BRIG_KIND_DIRECTIVE_ARG_BLOCK_END = 0x1000,\n        BRIG_KIND_DIRECTIVE_ARG_BLOCK_START = 0x1001,\n        BRIG_KIND_DIRECTIVE_COMMENT = 0x1002,\n        BRIG_KIND_DIRECTIVE_CONTROL = 0x1003,\n        BRIG_KIND_DIRECTIVE_EXTENSION = 0x1004,\n        BRIG_KIND_DIRECTIVE_FBARRIER = 0x1005,\n        BRIG_KIND_DIRECTIVE_FUNCTION = 0x1006,\n        BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION = 0x1007,\n        BRIG_KIND_DIRECTIVE_KERNEL = 0x1008,\n        BRIG_KIND_DIRECTIVE_LABEL = 0x1009,\n        BRIG_KIND_DIRECTIVE_LOC = 0x100a,\n        BRIG_KIND_DIRECTIVE_MODULE = 0x100b,\n        BRIG_KIND_DIRECTIVE_PRAGMA = 0x100c,\n        BRIG_KIND_DIRECTIVE_SIGNATURE = 0x100d,\n        BRIG_KIND_DIRECTIVE_VARIABLE = 0x100e,\n    BRIG_KIND_DIRECTIVE_END = 0x100f,\n\n    BRIG_KIND_INST_BEGIN = 0x2000,\n        BRIG_KIND_INST_ADDR = 0x2000,\n        BRIG_KIND_INST_ATOMIC = 0x2001,\n        BRIG_KIND_INST_BASIC = 0x2002,\n        BRIG_KIND_INST_BR = 0x2003,\n        BRIG_KIND_INST_CMP = 0x2004,\n        BRIG_KIND_INST_CVT = 0x2005,\n        BRIG_KIND_INST_IMAGE = 0x2006,\n        BRIG_KIND_INST_LANE = 0x2007,\n        BRIG_KIND_INST_MEM = 0x2008,\n        BRIG_KIND_INST_MEM_FENCE = 0x2009,\n        BRIG_KIND_INST_MOD = 0x200a,\n        BRIG_KIND_INST_QUERY_IMAGE = 0x200b,\n        BRIG_KIND_INST_QUERY_SAMPLER = 0x200c,\n        BRIG_KIND_INST_QUEUE = 0x200d,\n        BRIG_KIND_INST_SEG = 0x200e,\n        BRIG_KIND_INST_SEG_CVT = 0x200f,\n        BRIG_KIND_INST_SIGNAL = 0x2010,\n        BRIG_KIND_INST_SOURCE_TYPE = 0x2011,\n    BRIG_KIND_INST_END = 0x2012,\n\n    BRIG_KIND_OPERAND_BEGIN = 0x3000,\n        BRIG_KIND_OPERAND_ADDRESS = 0x3000,\n        BRIG_KIND_OPERAND_ALIGN = 0x3001,\n        BRIG_KIND_OPERAND_CODE_LIST = 0x3002,\n        BRIG_KIND_OPERAND_CODE_REF = 0x3003,\n        BRIG_KIND_OPERAND_CONSTANT_BYTES = 0x3004,\n        BRIG_KIND_OPERAND_RESERVED = 0x3005,\n        BRIG_KIND_OPERAND_CONSTANT_IMAGE = 0x3006,\n        BRIG_KIND_OPERAND_CONSTANT_OPERAND_LIST = 0x3007,\n        BRIG_KIND_OPERAND_CONSTANT_SAMPLER = 0x3008,\n        BRIG_KIND_OPERAND_OPERAND_LIST = 0x3009,\n        BRIG_KIND_OPERAND_REGISTER = 0x300a,\n        BRIG_KIND_OPERAND_STRING = 0x300b,\n        BRIG_KIND_OPERAND_WAVESIZE = 0x300c,\n    BRIG_KIND_OPERAND_END = 0x300d\n};\n\ntypedef uint8_t BrigAlignment8_t;\nenum BrigAlignment {\n    BRIG_ALIGNMENT_NONE = 0,\n    BRIG_ALIGNMENT_1 = 1,\n    BRIG_ALIGNMENT_2 = 2,\n    BRIG_ALIGNMENT_4 = 3,\n    BRIG_ALIGNMENT_8 = 4,\n    BRIG_ALIGNMENT_16 = 5,\n    BRIG_ALIGNMENT_32 = 6,\n    BRIG_ALIGNMENT_64 = 7,\n    BRIG_ALIGNMENT_128 = 8,\n    BRIG_ALIGNMENT_256 = 9,\n    BRIG_ALIGNMENT_MAX = BRIG_ALIGNMENT_256\n};\n\ntypedef uint8_t BrigAllocation8_t;\nenum BrigAllocation {\n    BRIG_ALLOCATION_NONE = 0,\n    BRIG_ALLOCATION_PROGRAM = 1,\n    BRIG_ALLOCATION_AGENT = 2,\n    BRIG_ALLOCATION_AUTOMATIC = 3\n};\n\ntypedef uint8_t BrigAluModifier8_t;\nenum BrigAluModifierMask {\n    BRIG_ALU_FTZ = 1\n};\n\ntypedef uint8_t BrigAtomicOperation8_t;\nenum BrigAtomicOperation {\n    BRIG_ATOMIC_ADD = 0,\n    BRIG_ATOMIC_AND = 1,\n    BRIG_ATOMIC_CAS = 2,\n    BRIG_ATOMIC_EXCH = 3,\n    BRIG_ATOMIC_LD = 4,\n    BRIG_ATOMIC_MAX = 5,\n    BRIG_ATOMIC_MIN = 6,\n    BRIG_ATOMIC_OR = 7,\n    BRIG_ATOMIC_ST = 8,\n    BRIG_ATOMIC_SUB = 9,\n    BRIG_ATOMIC_WRAPDEC = 10,\n    BRIG_ATOMIC_WRAPINC = 11,\n    BRIG_ATOMIC_XOR = 12,\n    BRIG_ATOMIC_WAIT_EQ = 13,\n    BRIG_ATOMIC_WAIT_NE = 14,\n    BRIG_ATOMIC_WAIT_LT = 15,\n    BRIG_ATOMIC_WAIT_GTE = 16,\n    BRIG_ATOMIC_WAITTIMEOUT_EQ = 17,\n    BRIG_ATOMIC_WAITTIMEOUT_NE = 18,\n    BRIG_ATOMIC_WAITTIMEOUT_LT = 19,\n    BRIG_ATOMIC_WAITTIMEOUT_GTE = 20\n};\n\ntypedef uint8_t BrigCompareOperation8_t;\nenum BrigCompareOperation {\n    BRIG_COMPARE_EQ = 0,\n    BRIG_COMPARE_NE = 1,\n    BRIG_COMPARE_LT = 2,\n    BRIG_COMPARE_LE = 3,\n    BRIG_COMPARE_GT = 4,\n    BRIG_COMPARE_GE = 5,\n    BRIG_COMPARE_EQU = 6,\n    BRIG_COMPARE_NEU = 7,\n    BRIG_COMPARE_LTU = 8,\n    BRIG_COMPARE_LEU = 9,\n    BRIG_COMPARE_GTU = 10,\n    BRIG_COMPARE_GEU = 11,\n    BRIG_COMPARE_NUM = 12,\n    BRIG_COMPARE_NAN = 13,\n    BRIG_COMPARE_SEQ = 14,\n    BRIG_COMPARE_SNE = 15,\n    BRIG_COMPARE_SLT = 16,\n    BRIG_COMPARE_SLE = 17,\n    BRIG_COMPARE_SGT = 18,\n    BRIG_COMPARE_SGE = 19,\n    BRIG_COMPARE_SGEU = 20,\n    BRIG_COMPARE_SEQU = 21,\n    BRIG_COMPARE_SNEU = 22,\n    BRIG_COMPARE_SLTU = 23,\n    BRIG_COMPARE_SLEU = 24,\n    BRIG_COMPARE_SNUM = 25,\n    BRIG_COMPARE_SNAN = 26,\n    BRIG_COMPARE_SGTU = 27\n};\n\ntypedef uint16_t BrigControlDirective16_t;\nenum BrigControlDirective {\n    BRIG_CONTROL_NONE = 0,\n    BRIG_CONTROL_ENABLEBREAKEXCEPTIONS = 1,\n    BRIG_CONTROL_ENABLEDETECTEXCEPTIONS = 2,\n    BRIG_CONTROL_MAXDYNAMICGROUPSIZE = 3,\n    BRIG_CONTROL_MAXFLATGRIDSIZE = 4,\n    BRIG_CONTROL_MAXFLATWORKGROUPSIZE = 5,\n    BRIG_CONTROL_REQUIREDDIM = 6,\n    BRIG_CONTROL_REQUIREDGRIDSIZE = 7,\n    BRIG_CONTROL_REQUIREDWORKGROUPSIZE = 8,\n    BRIG_CONTROL_REQUIRENOPARTIALWORKGROUPS = 9\n};\n\ntypedef uint8_t BrigExecutableModifier8_t;\nenum BrigExecutableModifierMask {\n    BRIG_EXECUTABLE_DEFINITION = 1\n};\n\ntypedef uint8_t BrigImageChannelOrder8_t;\nenum BrigImageChannelOrder {\n    BRIG_CHANNEL_ORDER_A = 0,\n    BRIG_CHANNEL_ORDER_R = 1,\n    BRIG_CHANNEL_ORDER_RX = 2,\n    BRIG_CHANNEL_ORDER_RG = 3,\n    BRIG_CHANNEL_ORDER_RGX = 4,\n    BRIG_CHANNEL_ORDER_RA = 5,\n    BRIG_CHANNEL_ORDER_RGB = 6,\n    BRIG_CHANNEL_ORDER_RGBX = 7,\n    BRIG_CHANNEL_ORDER_RGBA = 8,\n    BRIG_CHANNEL_ORDER_BGRA = 9,\n    BRIG_CHANNEL_ORDER_ARGB = 10,\n    BRIG_CHANNEL_ORDER_ABGR = 11,\n    BRIG_CHANNEL_ORDER_SRGB = 12,\n    BRIG_CHANNEL_ORDER_SRGBX = 13,\n    BRIG_CHANNEL_ORDER_SRGBA = 14,\n    BRIG_CHANNEL_ORDER_SBGRA = 15,\n    BRIG_CHANNEL_ORDER_INTENSITY = 16,\n    BRIG_CHANNEL_ORDER_LUMINANCE = 17,\n    BRIG_CHANNEL_ORDER_DEPTH = 18,\n    BRIG_CHANNEL_ORDER_DEPTH_STENCIL = 19,\n\n    BRIG_CHANNEL_ORDER_FIRST_USER_DEFINED = 128\n};\n\ntypedef uint8_t BrigImageChannelType8_t;\nenum BrigImageChannelType {\n    BRIG_CHANNEL_TYPE_SNORM_INT8 = 0,\n    BRIG_CHANNEL_TYPE_SNORM_INT16 = 1,\n    BRIG_CHANNEL_TYPE_UNORM_INT8 = 2,\n    BRIG_CHANNEL_TYPE_UNORM_INT16 = 3,\n    BRIG_CHANNEL_TYPE_UNORM_INT24 = 4,\n    BRIG_CHANNEL_TYPE_UNORM_SHORT_555 = 5,\n    BRIG_CHANNEL_TYPE_UNORM_SHORT_565 = 6,\n    BRIG_CHANNEL_TYPE_UNORM_INT_101010 = 7,\n    BRIG_CHANNEL_TYPE_SIGNED_INT8 = 8,\n    BRIG_CHANNEL_TYPE_SIGNED_INT16 = 9,\n    BRIG_CHANNEL_TYPE_SIGNED_INT32 = 10,\n    BRIG_CHANNEL_TYPE_UNSIGNED_INT8 = 11,\n    BRIG_CHANNEL_TYPE_UNSIGNED_INT16 = 12,\n    BRIG_CHANNEL_TYPE_UNSIGNED_INT32 = 13,\n    BRIG_CHANNEL_TYPE_HALF_FLOAT = 14,\n    BRIG_CHANNEL_TYPE_FLOAT = 15,\n\n    BRIG_CHANNEL_TYPE_FIRST_USER_DEFINED = 128\n};\n\ntypedef uint8_t BrigImageGeometry8_t;\nenum BrigImageGeometry {\n    BRIG_GEOMETRY_1D = 0,\n    BRIG_GEOMETRY_2D = 1,\n    BRIG_GEOMETRY_3D = 2,\n    BRIG_GEOMETRY_1DA = 3,\n    BRIG_GEOMETRY_2DA = 4,\n    BRIG_GEOMETRY_1DB = 5,\n    BRIG_GEOMETRY_2DDEPTH = 6,\n    BRIG_GEOMETRY_2DADEPTH = 7,\n\n    BRIG_GEOMETRY_FIRST_USER_DEFINED = 128\n};\n\ntypedef uint8_t BrigImageQuery8_t;\nenum BrigImageQuery {\n    BRIG_IMAGE_QUERY_WIDTH = 0,\n    BRIG_IMAGE_QUERY_HEIGHT = 1,\n    BRIG_IMAGE_QUERY_DEPTH = 2,\n    BRIG_IMAGE_QUERY_ARRAY = 3,\n    BRIG_IMAGE_QUERY_CHANNELORDER = 4,\n    BRIG_IMAGE_QUERY_CHANNELTYPE = 5,\n\n    BRIG_IMAGE_QUERY_FIRST_USER_DEFINED = 6\n};\n\ntypedef uint8_t BrigLinkage8_t;\nenum BrigLinkage {\n    BRIG_LINKAGE_NONE = 0,\n    BRIG_LINKAGE_PROGRAM = 1,\n    BRIG_LINKAGE_MODULE = 2,\n    BRIG_LINKAGE_FUNCTION = 3,\n    BRIG_LINKAGE_ARG = 4\n};\n\ntypedef uint8_t BrigMachineModel8_t;\nenum BrigMachineModel {\n    BRIG_MACHINE_SMALL = 0,\n    BRIG_MACHINE_LARGE = 1,\n};\n\ntypedef uint8_t BrigMemoryModifier8_t;\nenum BrigMemoryModifierMask {\n    BRIG_MEMORY_CONST = 1\n};\n\ntypedef uint8_t BrigMemoryOrder8_t;\nenum BrigMemoryOrder {\n    BRIG_MEMORY_ORDER_NONE = 0,\n    BRIG_MEMORY_ORDER_RELAXED = 1,\n    BRIG_MEMORY_ORDER_SC_ACQUIRE = 2,\n    BRIG_MEMORY_ORDER_SC_RELEASE = 3,\n    BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE = 4,\n};\n\ntypedef uint8_t BrigMemoryScope8_t;\nenum BrigMemoryScope {\n    BRIG_MEMORY_SCOPE_NONE = 0,\n    BRIG_MEMORY_SCOPE_WORKITEM = 1,\n    BRIG_MEMORY_SCOPE_WAVEFRONT = 2,\n    BRIG_MEMORY_SCOPE_WORKGROUP = 3,\n    BRIG_MEMORY_SCOPE_AGENT = 4,\n    BRIG_MEMORY_SCOPE_SYSTEM = 5,\n};\n\ntypedef uint16_t BrigOpcode16_t;\nenum BrigOpcode {\n    BRIG_OPCODE_NOP = 0,\n    BRIG_OPCODE_ABS = 1,\n    BRIG_OPCODE_ADD = 2,\n    BRIG_OPCODE_BORROW = 3,\n    BRIG_OPCODE_CARRY = 4,\n    BRIG_OPCODE_CEIL = 5,\n    BRIG_OPCODE_COPYSIGN = 6,\n    BRIG_OPCODE_DIV = 7,\n    BRIG_OPCODE_FLOOR = 8,\n    BRIG_OPCODE_FMA = 9,\n    BRIG_OPCODE_FRACT = 10,\n    BRIG_OPCODE_MAD = 11,\n    BRIG_OPCODE_MAX = 12,\n    BRIG_OPCODE_MIN = 13,\n    BRIG_OPCODE_MUL = 14,\n    BRIG_OPCODE_MULHI = 15,\n    BRIG_OPCODE_NEG = 16,\n    BRIG_OPCODE_REM = 17,\n    BRIG_OPCODE_RINT = 18,\n    BRIG_OPCODE_SQRT = 19,\n    BRIG_OPCODE_SUB = 20,\n    BRIG_OPCODE_TRUNC = 21,\n    BRIG_OPCODE_MAD24 = 22,\n    BRIG_OPCODE_MAD24HI = 23,\n    BRIG_OPCODE_MUL24 = 24,\n    BRIG_OPCODE_MUL24HI = 25,\n    BRIG_OPCODE_SHL = 26,\n    BRIG_OPCODE_SHR = 27,\n    BRIG_OPCODE_AND = 28,\n    BRIG_OPCODE_NOT = 29,\n    BRIG_OPCODE_OR = 30,\n    BRIG_OPCODE_POPCOUNT = 31,\n    BRIG_OPCODE_XOR = 32,\n    BRIG_OPCODE_BITEXTRACT = 33,\n    BRIG_OPCODE_BITINSERT = 34,\n    BRIG_OPCODE_BITMASK = 35,\n    BRIG_OPCODE_BITREV = 36,\n    BRIG_OPCODE_BITSELECT = 37,\n    BRIG_OPCODE_FIRSTBIT = 38,\n    BRIG_OPCODE_LASTBIT = 39,\n    BRIG_OPCODE_COMBINE = 40,\n    BRIG_OPCODE_EXPAND = 41,\n    BRIG_OPCODE_LDA = 42,\n    BRIG_OPCODE_MOV = 43,\n    BRIG_OPCODE_SHUFFLE = 44,\n    BRIG_OPCODE_UNPACKHI = 45,\n    BRIG_OPCODE_UNPACKLO = 46,\n    BRIG_OPCODE_PACK = 47,\n    BRIG_OPCODE_UNPACK = 48,\n    BRIG_OPCODE_CMOV = 49,\n    BRIG_OPCODE_CLASS = 50,\n    BRIG_OPCODE_NCOS = 51,\n    BRIG_OPCODE_NEXP2 = 52,\n    BRIG_OPCODE_NFMA = 53,\n    BRIG_OPCODE_NLOG2 = 54,\n    BRIG_OPCODE_NRCP = 55,\n    BRIG_OPCODE_NRSQRT = 56,\n    BRIG_OPCODE_NSIN = 57,\n    BRIG_OPCODE_NSQRT = 58,\n    BRIG_OPCODE_BITALIGN = 59,\n    BRIG_OPCODE_BYTEALIGN = 60,\n    BRIG_OPCODE_PACKCVT = 61,\n    BRIG_OPCODE_UNPACKCVT = 62,\n    BRIG_OPCODE_LERP = 63,\n    BRIG_OPCODE_SAD = 64,\n    BRIG_OPCODE_SADHI = 65,\n    BRIG_OPCODE_SEGMENTP = 66,\n    BRIG_OPCODE_FTOS = 67,\n    BRIG_OPCODE_STOF = 68,\n    BRIG_OPCODE_CMP = 69,\n    BRIG_OPCODE_CVT = 70,\n    BRIG_OPCODE_LD = 71,\n    BRIG_OPCODE_ST = 72,\n    BRIG_OPCODE_ATOMIC = 73,\n    BRIG_OPCODE_ATOMICNORET = 74,\n    BRIG_OPCODE_SIGNAL = 75,\n    BRIG_OPCODE_SIGNALNORET = 76,\n    BRIG_OPCODE_MEMFENCE = 77,\n    BRIG_OPCODE_RDIMAGE = 78,\n    BRIG_OPCODE_LDIMAGE = 79,\n    BRIG_OPCODE_STIMAGE = 80,\n    BRIG_OPCODE_IMAGEFENCE = 81,\n    BRIG_OPCODE_QUERYIMAGE = 82,\n    BRIG_OPCODE_QUERYSAMPLER = 83,\n    BRIG_OPCODE_CBR = 84,\n    BRIG_OPCODE_BR = 85,\n    BRIG_OPCODE_SBR = 86,\n    BRIG_OPCODE_BARRIER = 87,\n    BRIG_OPCODE_WAVEBARRIER = 88,\n    BRIG_OPCODE_ARRIVEFBAR = 89,\n    BRIG_OPCODE_INITFBAR = 90,\n    BRIG_OPCODE_JOINFBAR = 91,\n    BRIG_OPCODE_LEAVEFBAR = 92,\n    BRIG_OPCODE_RELEASEFBAR = 93,\n    BRIG_OPCODE_WAITFBAR = 94,\n    BRIG_OPCODE_LDF = 95,\n    BRIG_OPCODE_ACTIVELANECOUNT = 96,\n    BRIG_OPCODE_ACTIVELANEID = 97,\n    BRIG_OPCODE_ACTIVELANEMASK = 98,\n    BRIG_OPCODE_ACTIVELANEPERMUTE = 99,\n    BRIG_OPCODE_CALL = 100,\n    BRIG_OPCODE_SCALL = 101,\n    BRIG_OPCODE_ICALL = 102,\n    BRIG_OPCODE_RET = 103,\n    BRIG_OPCODE_ALLOCA = 104,\n    BRIG_OPCODE_CURRENTWORKGROUPSIZE = 105,\n    BRIG_OPCODE_CURRENTWORKITEMFLATID = 106,\n    BRIG_OPCODE_DIM = 107,\n    BRIG_OPCODE_GRIDGROUPS = 108,\n    BRIG_OPCODE_GRIDSIZE = 109,\n    BRIG_OPCODE_PACKETCOMPLETIONSIG = 110,\n    BRIG_OPCODE_PACKETID = 111,\n    BRIG_OPCODE_WORKGROUPID = 112,\n    BRIG_OPCODE_WORKGROUPSIZE = 113,\n    BRIG_OPCODE_WORKITEMABSID = 114,\n    BRIG_OPCODE_WORKITEMFLATABSID = 115,\n    BRIG_OPCODE_WORKITEMFLATID = 116,\n    BRIG_OPCODE_WORKITEMID = 117,\n    BRIG_OPCODE_CLEARDETECTEXCEPT = 118,\n    BRIG_OPCODE_GETDETECTEXCEPT = 119,\n    BRIG_OPCODE_SETDETECTEXCEPT = 120,\n    BRIG_OPCODE_ADDQUEUEWRITEINDEX = 121,\n    BRIG_OPCODE_CASQUEUEWRITEINDEX = 122,\n    BRIG_OPCODE_LDQUEUEREADINDEX = 123,\n    BRIG_OPCODE_LDQUEUEWRITEINDEX = 124,\n    BRIG_OPCODE_STQUEUEREADINDEX = 125,\n    BRIG_OPCODE_STQUEUEWRITEINDEX = 126,\n    BRIG_OPCODE_CLOCK = 127,\n    BRIG_OPCODE_CUID = 128,\n    BRIG_OPCODE_DEBUGTRAP = 129,\n    BRIG_OPCODE_GROUPBASEPTR = 130,\n    BRIG_OPCODE_KERNARGBASEPTR = 131,\n    BRIG_OPCODE_LANEID = 132,\n    BRIG_OPCODE_MAXCUID = 133,\n    BRIG_OPCODE_MAXWAVEID = 134,\n    BRIG_OPCODE_NULLPTR = 135,\n    BRIG_OPCODE_WAVEID = 136,\n\n    BRIG_OPCODE_FIRST_USER_DEFINED = 32768,\n};\n\ntypedef uint8_t BrigPack8_t;\nenum BrigPack {\n    BRIG_PACK_NONE = 0,\n    BRIG_PACK_PP = 1,\n    BRIG_PACK_PS = 2,\n    BRIG_PACK_SP = 3,\n    BRIG_PACK_SS = 4,\n    BRIG_PACK_S = 5,\n    BRIG_PACK_P = 6,\n    BRIG_PACK_PPSAT = 7,\n    BRIG_PACK_PSSAT = 8,\n    BRIG_PACK_SPSAT = 9,\n    BRIG_PACK_SSSAT = 10,\n    BRIG_PACK_SSAT = 11,\n    BRIG_PACK_PSAT = 12\n};\n\ntypedef uint8_t BrigProfile8_t;\nenum BrigProfile {\n    BRIG_PROFILE_BASE = 0,\n    BRIG_PROFILE_FULL = 1,\n};\n\ntypedef uint16_t BrigRegisterKind16_t;\nenum BrigRegisterKind {\n    BRIG_REGISTER_KIND_CONTROL = 0,\n    BRIG_REGISTER_KIND_SINGLE = 1,\n    BRIG_REGISTER_KIND_DOUBLE = 2,\n    BRIG_REGISTER_KIND_QUAD = 3\n};\n\ntypedef uint8_t BrigRound8_t;\nenum BrigRound {\n    BRIG_ROUND_NONE = 0,\n    BRIG_ROUND_FLOAT_DEFAULT = 1,\n    BRIG_ROUND_FLOAT_NEAR_EVEN = 2,\n    BRIG_ROUND_FLOAT_ZERO = 3,\n    BRIG_ROUND_FLOAT_PLUS_INFINITY = 4,\n    BRIG_ROUND_FLOAT_MINUS_INFINITY = 5,\n    BRIG_ROUND_INTEGER_NEAR_EVEN = 6,\n    BRIG_ROUND_INTEGER_ZERO = 7,\n    BRIG_ROUND_INTEGER_PLUS_INFINITY = 8,\n    BRIG_ROUND_INTEGER_MINUS_INFINITY = 9,\n    BRIG_ROUND_INTEGER_NEAR_EVEN_SAT = 10,\n    BRIG_ROUND_INTEGER_ZERO_SAT = 11,\n    BRIG_ROUND_INTEGER_PLUS_INFINITY_SAT = 12,\n    BRIG_ROUND_INTEGER_MINUS_INFINITY_SAT = 13,\n    BRIG_ROUND_INTEGER_SIGNALING_NEAR_EVEN = 14,\n    BRIG_ROUND_INTEGER_SIGNALING_ZERO = 15,\n    BRIG_ROUND_INTEGER_SIGNALING_PLUS_INFINITY = 16,\n    BRIG_ROUND_INTEGER_SIGNALING_MINUS_INFINITY = 17,\n    BRIG_ROUND_INTEGER_SIGNALING_NEAR_EVEN_SAT = 18,\n    BRIG_ROUND_INTEGER_SIGNALING_ZERO_SAT = 19,\n    BRIG_ROUND_INTEGER_SIGNALING_PLUS_INFINITY_SAT = 20,\n    BRIG_ROUND_INTEGER_SIGNALING_MINUS_INFINITY_SAT = 21\n};\n\ntypedef uint8_t BrigSamplerAddressing8_t;\nenum BrigSamplerAddressing {\n    BRIG_ADDRESSING_UNDEFINED = 0,\n    BRIG_ADDRESSING_CLAMP_TO_EDGE = 1,\n    BRIG_ADDRESSING_CLAMP_TO_BORDER = 2,\n    BRIG_ADDRESSING_REPEAT = 3,\n    BRIG_ADDRESSING_MIRRORED_REPEAT = 4,\n\n    BRIG_ADDRESSING_FIRST_USER_DEFINED = 128\n};\n\ntypedef uint8_t BrigSamplerCoordNormalization8_t;\nenum BrigSamplerCoordNormalization {\n    BRIG_COORD_UNNORMALIZED = 0,\n    BRIG_COORD_NORMALIZED = 1\n};\n\ntypedef uint8_t BrigSamplerFilter8_t;\nenum BrigSamplerFilter {\n    BRIG_FILTER_NEAREST = 0,\n    BRIG_FILTER_LINEAR = 1,\n\n    BRIG_FILTER_FIRST_USER_DEFINED = 128\n};\n\ntypedef uint8_t BrigSamplerQuery8_t;\nenum BrigSamplerQuery {\n    BRIG_SAMPLER_QUERY_ADDRESSING = 0,\n    BRIG_SAMPLER_QUERY_COORD = 1,\n    BRIG_SAMPLER_QUERY_FILTER = 2\n};\n\ntypedef uint32_t BrigSectionIndex32_t;\nenum BrigSectionIndex {\n    BRIG_SECTION_INDEX_DATA = 0,\n    BRIG_SECTION_INDEX_CODE = 1,\n    BRIG_SECTION_INDEX_OPERAND = 2,\n\n    BRIG_SECTION_INDEX_BEGIN_IMPLEMENTATION_DEFINED = 3,\n};\n\ntypedef uint8_t BrigSegCvtModifier8_t;\nenum BrigSegCvtModifierMask {\n    BRIG_SEG_CVT_NONULL = 1\n};\n\ntypedef uint8_t BrigSegment8_t;\nenum BrigSegment {\n    BRIG_SEGMENT_NONE = 0,\n    BRIG_SEGMENT_FLAT = 1,\n    BRIG_SEGMENT_GLOBAL = 2,\n    BRIG_SEGMENT_READONLY = 3,\n    BRIG_SEGMENT_KERNARG = 4,\n    BRIG_SEGMENT_GROUP = 5,\n    BRIG_SEGMENT_PRIVATE = 6,\n    BRIG_SEGMENT_SPILL = 7,\n    BRIG_SEGMENT_ARG = 8,\n\n    BRIG_SEGMENT_FIRST_USER_DEFINED = 128\n};\n\nenum {\n    BRIG_TYPE_BASE_SIZE  = 5,\n    BRIG_TYPE_PACK_SIZE  = 2,\n    BRIG_TYPE_ARRAY_SIZE = 1,\n\n    BRIG_TYPE_BASE_SHIFT  = 0,\n    BRIG_TYPE_PACK_SHIFT  = BRIG_TYPE_BASE_SHIFT + BRIG_TYPE_BASE_SIZE,\n    BRIG_TYPE_ARRAY_SHIFT = BRIG_TYPE_PACK_SHIFT + BRIG_TYPE_PACK_SIZE,\n\n    BRIG_TYPE_BASE_MASK  = ((1 << BRIG_TYPE_BASE_SIZE)  - 1) << BRIG_TYPE_BASE_SHIFT,\n    BRIG_TYPE_PACK_MASK  = ((1 << BRIG_TYPE_PACK_SIZE)  - 1) << BRIG_TYPE_PACK_SHIFT,\n    BRIG_TYPE_ARRAY_MASK = ((1 << BRIG_TYPE_ARRAY_SIZE) - 1) << BRIG_TYPE_ARRAY_SHIFT,\n\n    BRIG_TYPE_PACK_NONE = 0 << BRIG_TYPE_PACK_SHIFT,\n    BRIG_TYPE_PACK_32   = 1 << BRIG_TYPE_PACK_SHIFT,\n    BRIG_TYPE_PACK_64   = 2 << BRIG_TYPE_PACK_SHIFT,\n    BRIG_TYPE_PACK_128  = 3 << BRIG_TYPE_PACK_SHIFT,\n\n    BRIG_TYPE_ARRAY     = 1 << BRIG_TYPE_ARRAY_SHIFT\n};\n\ntypedef uint16_t BrigType16_t;\nenum BrigType {\n    BRIG_TYPE_NONE  = 0,\n    BRIG_TYPE_U8    = 1,\n    BRIG_TYPE_U16   = 2,\n    BRIG_TYPE_U32   = 3,\n    BRIG_TYPE_U64   = 4,\n    BRIG_TYPE_S8    = 5,\n    BRIG_TYPE_S16   = 6,\n    BRIG_TYPE_S32   = 7,\n    BRIG_TYPE_S64   = 8,\n    BRIG_TYPE_F16   = 9,\n    BRIG_TYPE_F32   = 10,\n    BRIG_TYPE_F64   = 11,\n    BRIG_TYPE_B1    = 12,\n    BRIG_TYPE_B8    = 13,\n    BRIG_TYPE_B16   = 14,\n    BRIG_TYPE_B32   = 15,\n    BRIG_TYPE_B64   = 16,\n    BRIG_TYPE_B128  = 17,\n    BRIG_TYPE_SAMP  = 18,\n    BRIG_TYPE_ROIMG = 19,\n    BRIG_TYPE_WOIMG = 20,\n    BRIG_TYPE_RWIMG = 21,\n    BRIG_TYPE_SIG32 = 22,\n    BRIG_TYPE_SIG64 = 23,\n\n    BRIG_TYPE_U8X4  = BRIG_TYPE_U8  | BRIG_TYPE_PACK_32,\n    BRIG_TYPE_U8X8  = BRIG_TYPE_U8  | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_U8X16 = BRIG_TYPE_U8  | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_U16X2 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_32,\n    BRIG_TYPE_U16X4 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_U16X8 = BRIG_TYPE_U16 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_U32X2 = BRIG_TYPE_U32 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_U32X4 = BRIG_TYPE_U32 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_U64X2 = BRIG_TYPE_U64 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_S8X4  = BRIG_TYPE_S8  | BRIG_TYPE_PACK_32,\n    BRIG_TYPE_S8X8  = BRIG_TYPE_S8  | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_S8X16 = BRIG_TYPE_S8  | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_S16X2 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_32,\n    BRIG_TYPE_S16X4 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_S16X8 = BRIG_TYPE_S16 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_S32X2 = BRIG_TYPE_S32 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_S32X4 = BRIG_TYPE_S32 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_S64X2 = BRIG_TYPE_S64 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_F16X2 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_32,\n    BRIG_TYPE_F16X4 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_F16X8 = BRIG_TYPE_F16 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_F32X2 = BRIG_TYPE_F32 | BRIG_TYPE_PACK_64,\n    BRIG_TYPE_F32X4 = BRIG_TYPE_F32 | BRIG_TYPE_PACK_128,\n    BRIG_TYPE_F64X2 = BRIG_TYPE_F64 | BRIG_TYPE_PACK_128,\n\n    BRIG_TYPE_U8_ARRAY    = BRIG_TYPE_U8    | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U16_ARRAY   = BRIG_TYPE_U16   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U32_ARRAY   = BRIG_TYPE_U32   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U64_ARRAY   = BRIG_TYPE_U64   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S8_ARRAY    = BRIG_TYPE_S8    | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S16_ARRAY   = BRIG_TYPE_S16   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S32_ARRAY   = BRIG_TYPE_S32   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S64_ARRAY   = BRIG_TYPE_S64   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F16_ARRAY   = BRIG_TYPE_F16   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F32_ARRAY   = BRIG_TYPE_F32   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F64_ARRAY   = BRIG_TYPE_F64   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_B8_ARRAY    = BRIG_TYPE_B8    | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_B16_ARRAY   = BRIG_TYPE_B16   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_B32_ARRAY   = BRIG_TYPE_B32   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_B64_ARRAY   = BRIG_TYPE_B64   | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_B128_ARRAY  = BRIG_TYPE_B128  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_SAMP_ARRAY  = BRIG_TYPE_SAMP  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_ROIMG_ARRAY = BRIG_TYPE_ROIMG | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_WOIMG_ARRAY = BRIG_TYPE_WOIMG | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_RWIMG_ARRAY = BRIG_TYPE_RWIMG | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_SIG32_ARRAY = BRIG_TYPE_SIG32 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_SIG64_ARRAY = BRIG_TYPE_SIG64 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U8X4_ARRAY  = BRIG_TYPE_U8X4  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U8X8_ARRAY  = BRIG_TYPE_U8X8  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U8X16_ARRAY = BRIG_TYPE_U8X16 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U16X2_ARRAY = BRIG_TYPE_U16X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U16X4_ARRAY = BRIG_TYPE_U16X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U16X8_ARRAY = BRIG_TYPE_U16X8 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U32X2_ARRAY = BRIG_TYPE_U32X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U32X4_ARRAY = BRIG_TYPE_U32X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_U64X2_ARRAY = BRIG_TYPE_U64X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S8X4_ARRAY  = BRIG_TYPE_S8X4  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S8X8_ARRAY  = BRIG_TYPE_S8X8  | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S8X16_ARRAY = BRIG_TYPE_S8X16 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S16X2_ARRAY = BRIG_TYPE_S16X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S16X4_ARRAY = BRIG_TYPE_S16X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S16X8_ARRAY = BRIG_TYPE_S16X8 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S32X2_ARRAY = BRIG_TYPE_S32X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S32X4_ARRAY = BRIG_TYPE_S32X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_S64X2_ARRAY = BRIG_TYPE_S64X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F16X2_ARRAY = BRIG_TYPE_F16X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F16X4_ARRAY = BRIG_TYPE_F16X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F16X8_ARRAY = BRIG_TYPE_F16X8 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F32X2_ARRAY = BRIG_TYPE_F32X2 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F32X4_ARRAY = BRIG_TYPE_F32X4 | BRIG_TYPE_ARRAY,\n    BRIG_TYPE_F64X2_ARRAY = BRIG_TYPE_F64X2 | BRIG_TYPE_ARRAY,\n};\n\ntypedef uint8_t BrigVariableModifier8_t;\nenum BrigVariableModifierMask {\n    BRIG_VARIABLE_DEFINITION = 1,\n    BRIG_VARIABLE_CONST = 2\n};\n\ntypedef uint8_t BrigWidth8_t;\nenum BrigWidth {\n    BRIG_WIDTH_NONE = 0,\n    BRIG_WIDTH_1 = 1,\n    BRIG_WIDTH_2 = 2,\n    BRIG_WIDTH_4 = 3,\n    BRIG_WIDTH_8 = 4,\n    BRIG_WIDTH_16 = 5,\n    BRIG_WIDTH_32 = 6,\n    BRIG_WIDTH_64 = 7,\n    BRIG_WIDTH_128 = 8,\n    BRIG_WIDTH_256 = 9,\n    BRIG_WIDTH_512 = 10,\n    BRIG_WIDTH_1024 = 11,\n    BRIG_WIDTH_2048 = 12,\n    BRIG_WIDTH_4096 = 13,\n    BRIG_WIDTH_8192 = 14,\n    BRIG_WIDTH_16384 = 15,\n    BRIG_WIDTH_32768 = 16,\n    BRIG_WIDTH_65536 = 17,\n    BRIG_WIDTH_131072 = 18,\n    BRIG_WIDTH_262144 = 19,\n    BRIG_WIDTH_524288 = 20,\n    BRIG_WIDTH_1048576 = 21,\n    BRIG_WIDTH_2097152 = 22,\n    BRIG_WIDTH_4194304 = 23,\n    BRIG_WIDTH_8388608 = 24,\n    BRIG_WIDTH_16777216 = 25,\n    BRIG_WIDTH_33554432 = 26,\n    BRIG_WIDTH_67108864 = 27,\n    BRIG_WIDTH_134217728 = 28,\n    BRIG_WIDTH_268435456 = 29,\n    BRIG_WIDTH_536870912 = 30,\n    BRIG_WIDTH_1073741824 = 31,\n    BRIG_WIDTH_2147483648 = 32,\n    BRIG_WIDTH_WAVESIZE = 33,\n    BRIG_WIDTH_ALL = 34,\n};\n\nstruct BrigUInt64 {\n    uint32_t lo;\n    uint32_t hi;\n};\n\nstruct BrigBase {\n    uint16_t byteCount;\n    BrigKind16_t kind;\n};\n\nstruct BrigData {\n    uint32_t byteCount;\n    uint8_t bytes[1];\n};\n\nstruct BrigDirectiveArgBlock {\n    BrigBase base;\n};\n\nstruct BrigDirectiveComment {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n};\n\nstruct BrigDirectiveControl {\n    BrigBase base;\n    BrigControlDirective16_t control;\n    uint16_t reserved;\n    BrigDataOffsetOperandList32_t operands;\n};\n\nstruct BrigDirectiveExecutable {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n    uint16_t outArgCount;\n    uint16_t inArgCount;\n    BrigCodeOffset32_t firstInArg;\n    BrigCodeOffset32_t firstCodeBlockEntry;\n    BrigCodeOffset32_t nextModuleEntry;\n    BrigExecutableModifier8_t modifier;\n    BrigLinkage8_t linkage;\n    uint16_t reserved;\n};\n\nstruct BrigDirectiveExtension {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n};\n\nstruct BrigDirectiveFbarrier {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n    BrigVariableModifier8_t modifier;\n    BrigLinkage8_t linkage;\n    uint16_t reserved;\n};\n\nstruct BrigDirectiveLabel {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n};\n\nstruct BrigDirectiveLoc {\n    BrigBase base;\n    BrigDataOffsetString32_t filename;\n    uint32_t line;\n    uint32_t column;\n};\n\nstruct BrigDirectiveNone {\n    BrigBase base;\n};\n\nstruct BrigDirectivePragma {\n    BrigBase base;\n    BrigDataOffsetOperandList32_t operands;\n};\n\nstruct BrigDirectiveVariable {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n    BrigOperandOffset32_t init;\n    BrigType16_t type;\n    BrigSegment8_t segment;\n    BrigAlignment8_t align;\n    BrigUInt64 dim;\n    BrigVariableModifier8_t modifier;\n    BrigLinkage8_t linkage;\n    BrigAllocation8_t allocation;\n    uint8_t reserved;\n};\n\nstruct BrigDirectiveModule {\n    BrigBase base;\n    BrigDataOffsetString32_t name;\n    BrigVersion32_t hsailMajor;\n    BrigVersion32_t hsailMinor;\n    BrigProfile8_t profile;\n    BrigMachineModel8_t machineModel;\n    BrigRound8_t defaultFloatRound;\n    uint8_t reserved;\n};\n\nstruct BrigInstBase {\n    BrigBase base;\n    BrigOpcode16_t opcode;\n    BrigType16_t type;\n    BrigDataOffsetOperandList32_t operands;\n};\n\nstruct BrigInstAddr {\n    BrigInstBase base;\n    BrigSegment8_t segment;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstAtomic {\n    BrigInstBase base;\n    BrigSegment8_t segment;\n    BrigMemoryOrder8_t memoryOrder;\n    BrigMemoryScope8_t memoryScope;\n    BrigAtomicOperation8_t atomicOperation;\n    uint8_t equivClass;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstBasic {\n    BrigInstBase base;\n};\n\nstruct BrigInstBr {\n    BrigInstBase base;\n    BrigWidth8_t width;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstCmp {\n    BrigInstBase base;\n    BrigType16_t sourceType;\n    BrigAluModifier8_t modifier;\n    BrigCompareOperation8_t compare;\n    BrigPack8_t pack;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstCvt {\n    BrigInstBase base;\n    BrigType16_t sourceType;\n    BrigAluModifier8_t modifier;\n    BrigRound8_t round;\n};\n\nstruct BrigInstImage {\n    BrigInstBase base;\n    BrigType16_t imageType;\n    BrigType16_t coordType;\n    BrigImageGeometry8_t geometry;\n    uint8_t equivClass;\n    uint16_t reserved;\n};\n\nstruct BrigInstLane {\n    BrigInstBase base;\n    BrigType16_t sourceType;\n    BrigWidth8_t width;\n    uint8_t reserved;\n};\n\nstruct BrigInstMem {\n    BrigInstBase base;\n    BrigSegment8_t segment;\n    BrigAlignment8_t align;\n    uint8_t equivClass;\n    BrigWidth8_t width;\n    BrigMemoryModifier8_t modifier;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstMemFence {\n    BrigInstBase base;\n    BrigMemoryOrder8_t memoryOrder;\n    BrigMemoryScope8_t globalSegmentMemoryScope;\n    BrigMemoryScope8_t groupSegmentMemoryScope;\n    BrigMemoryScope8_t imageSegmentMemoryScope;\n};\n\nstruct BrigInstMod {\n    BrigInstBase base;\n    BrigAluModifier8_t modifier;\n    BrigRound8_t round;\n    BrigPack8_t pack;\n    uint8_t reserved;\n};\n\nstruct BrigInstQueryImage {\n    BrigInstBase base;\n    BrigType16_t imageType;\n    BrigImageGeometry8_t geometry;\n    BrigImageQuery8_t query;\n};\n\nstruct BrigInstQuerySampler {\n    BrigInstBase base;\n    BrigSamplerQuery8_t query;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstQueue {\n    BrigInstBase base;\n    BrigSegment8_t segment;\n    BrigMemoryOrder8_t memoryOrder;\n    uint16_t reserved;\n};\n\nstruct BrigInstSeg {\n    BrigInstBase base;\n    BrigSegment8_t segment;\n    uint8_t reserved[3];\n};\n\nstruct BrigInstSegCvt {\n    BrigInstBase base;\n    BrigType16_t sourceType;\n    BrigSegment8_t segment;\n    BrigSegCvtModifier8_t modifier;\n};\n\nstruct BrigInstSignal {\n    BrigInstBase base;\n    BrigType16_t signalType;\n    BrigMemoryOrder8_t memoryOrder;\n    BrigAtomicOperation8_t signalOperation;\n};\n\nstruct BrigInstSourceType {\n    BrigInstBase base;\n    BrigType16_t sourceType;\n    uint16_t reserved;\n};\n\nstruct BrigOperandAddress {\n    BrigBase base;\n    BrigCodeOffset32_t symbol;\n    BrigOperandOffset32_t reg;\n    BrigUInt64 offset;\n};\n\nstruct BrigOperandAlign {\n    BrigBase base;\n    BrigAlignment8_t align;\n    uint8_t reserved[3];\n};\n\nstruct BrigOperandCodeList {\n    BrigBase base;\n    BrigDataOffsetCodeList32_t elements;\n};\n\nstruct BrigOperandCodeRef {\n    BrigBase base;\n    BrigCodeOffset32_t ref;\n};\n\nstruct BrigOperandConstantBytes {\n    BrigBase base;\n    BrigType16_t type;\n    uint16_t reserved;\n    BrigDataOffsetString32_t bytes;\n};\n\nstruct BrigOperandConstantOperandList {\n    BrigBase base;\n    BrigType16_t type;\n    uint16_t reserved;\n    BrigDataOffsetOperandList32_t elements;\n};\n\nstruct BrigOperandConstantImage {\n    BrigBase base;\n    BrigType16_t type;\n    BrigImageGeometry8_t geometry;\n    BrigImageChannelOrder8_t channelOrder;\n    BrigImageChannelType8_t channelType;\n    uint8_t reserved[3];\n    BrigUInt64 width;\n    BrigUInt64 height;\n    BrigUInt64 depth;\n    BrigUInt64 array;\n};\n\nstruct BrigOperandOperandList {\n    BrigBase base;\n    BrigDataOffsetOperandList32_t elements;\n};\n\nstruct BrigOperandRegister {\n    BrigBase base;\n    BrigRegisterKind16_t regKind;\n    uint16_t regNum;\n};\n\nstruct BrigOperandConstantSampler {\n    BrigBase base;\n    BrigType16_t type;\n    BrigSamplerCoordNormalization8_t coord;\n    BrigSamplerFilter8_t filter;\n    BrigSamplerAddressing8_t addressing;\n    uint8_t reserved[3];\n};\n\nstruct BrigOperandString {\n    BrigBase base;\n    BrigDataOffsetString32_t string;\n};\n\nstruct BrigOperandWavesize {\n    BrigBase base;\n};\n\ntypedef uint32_t BrigExceptions32_t;\nenum BrigExceptionsMask {\n    BRIG_EXCEPTIONS_INVALID_OPERATION = 1 << 0,\n    BRIG_EXCEPTIONS_DIVIDE_BY_ZERO = 1 << 1,\n    BRIG_EXCEPTIONS_OVERFLOW = 1 << 2,\n    BRIG_EXCEPTIONS_UNDERFLOW = 1 << 3,\n    BRIG_EXCEPTIONS_INEXACT = 1 << 4,\n\n    BRIG_EXCEPTIONS_FIRST_USER_DEFINED = 1 << 16\n};\n\nstruct BrigSectionHeader {\n    uint64_t byteCount;\n    uint32_t headerByteCount;\n    uint32_t nameLength;\n    uint8_t name[1];\n};\n\nstruct BrigModuleHeader {\n    char identification[8];\n    BrigVersion32_t brigMajor;\n    BrigVersion32_t brigMinor;\n    uint64_t byteCount;\n    uint8_t hash[64];\n    uint32_t reserved;\n    uint32_t sectionCount;\n    uint64_t sectionIndex;\n};\n\ntypedef BrigModuleHeader* BrigModule_t;\n\n#ifdef __cplusplus\n}\n#endif  /*__cplusplus*/\n\n#endif // defined(INCLUDED_BRIG_H)\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/amd_hsa_common.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// The following set of header files provides definitions for AMD GPU\n// Architecture:\n//   - amd_hsa_common.h\n//   - amd_hsa_elf.h\n//   - amd_hsa_kernel_code.h\n//   - amd_hsa_queue.h\n//   - amd_hsa_signal.h\n//\n// Refer to \"HSA Application Binary Interface: AMD GPU Architecture\" for more\n// information.\n\n#ifndef AMD_HSA_COMMON_H\n#define AMD_HSA_COMMON_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n// Descriptive version of the HSA Application Binary Interface.\n#define AMD_HSA_ABI_VERSION \"AMD GPU Architecture v0.35 (June 25, 2015)\"\n\n// Alignment attribute that specifies a minimum alignment (in bytes) for\n// variables of the specified type.\n#if defined(__GNUC__)\n#  define __ALIGNED__(x) __attribute__((aligned(x)))\n#elif defined(_MSC_VER)\n#  define __ALIGNED__(x) __declspec(align(x))\n#elif defined(RC_INVOKED)\n#  define __ALIGNED__(x)\n#else\n#  error\n#endif\n\n// Creates enumeration entries for packed types. Enumeration entries include\n// bit shift amount, bit width, and bit mask.\n#define AMD_HSA_BITS_CREATE_ENUM_ENTRIES(name, shift, width)                   \\\n  name##_SHIFT = (shift),                                                      \\\n  name##_WIDTH = (width),                                                      \\\n  name = (((1 << (width)) - 1) << (shift))                                     \\\n\n// Gets bits for specified mask from specified src packed instance.\n#define AMD_HSA_BITS_GET(src, mask)                                            \\\n  ((src & mask) >> mask ## _SHIFT)                                             \\\n\n// Sets val bits for specified mask in specified dst packed instance.\n#define AMD_HSA_BITS_SET(dst, mask, val)                                       \\\n  dst &= (~(1 << mask##_SHIFT) & ~mask);                                       \\\n  dst |= (((val) << mask##_SHIFT) & mask)                                      \\\n\n#endif // AMD_HSA_COMMON_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/amd_hsa_elf.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// Undefine the macro in case it is defined in the system elf.h.\n#undef EM_AMDGPU\n\n#ifndef AMD_HSA_ELF_H\n#define AMD_HSA_ELF_H\n\n// AMD GPU Specific ELF Header Enumeration Values.\n//\n// Values are copied from LLVM BinaryFormat/ELF.h . This file also contains\n// code object V1 defintions which are not part of the LLVM header. Code object\n// V1 was only supported by the Finalizer which is now deprecated and removed.\n//\n// TODO: Deprecate and remove V1 support and replace this header with using the\n// LLVM header.\nnamespace ELF {\n\n// Machine architectures\n// See current registered ELF machine architectures at:\n//    http://www.uxsglobal.com/developers/gabi/latest/ch4.eheader.html\nenum {\n  EM_AMDGPU = 224,        // AMD GPU architecture\n};\n\n// OS ABI identification.\nenum {\n  ELFOSABI_AMDGPU_HSA = 64,    // AMD HSA runtime\n};\n\n// AMDGPU OS ABI Version identification.\nenum {\n  // ELFABIVERSION_AMDGPU_HSA_V1 does not exist because OS ABI identification\n  // was never defined for V1.\n  ELFABIVERSION_AMDGPU_HSA_V2 = 0,\n  ELFABIVERSION_AMDGPU_HSA_V3 = 1,\n  ELFABIVERSION_AMDGPU_HSA_V4 = 2,\n  ELFABIVERSION_AMDGPU_HSA_V5 = 3,\n  ELFABIVERSION_AMDGPU_HSA_V6 = 4,\n};\n\n// AMDGPU specific e_flags.\nenum : unsigned {\n  // Processor selection mask for EF_AMDGPU_MACH_* values.\n  EF_AMDGPU_MACH = 0x0ff,\n\n  // Not specified processor.\n  EF_AMDGPU_MACH_NONE = 0x000,\n\n  // AMDGCN-based processors.\n  // clang-format off\n  EF_AMDGPU_MACH_AMDGCN_GFX600          = 0x020,\n  EF_AMDGPU_MACH_AMDGCN_GFX601          = 0x021,\n  EF_AMDGPU_MACH_AMDGCN_GFX700          = 0x022,\n  EF_AMDGPU_MACH_AMDGCN_GFX701          = 0x023,\n  EF_AMDGPU_MACH_AMDGCN_GFX702          = 0x024,\n  EF_AMDGPU_MACH_AMDGCN_GFX703          = 0x025,\n  EF_AMDGPU_MACH_AMDGCN_GFX704          = 0x026,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X27   = 0x027,\n  EF_AMDGPU_MACH_AMDGCN_GFX801          = 0x028,\n  EF_AMDGPU_MACH_AMDGCN_GFX802          = 0x029,\n  EF_AMDGPU_MACH_AMDGCN_GFX803          = 0x02a,\n  EF_AMDGPU_MACH_AMDGCN_GFX810          = 0x02b,\n  EF_AMDGPU_MACH_AMDGCN_GFX900          = 0x02c,\n  EF_AMDGPU_MACH_AMDGCN_GFX902          = 0x02d,\n  EF_AMDGPU_MACH_AMDGCN_GFX904          = 0x02e,\n  EF_AMDGPU_MACH_AMDGCN_GFX906          = 0x02f,\n  EF_AMDGPU_MACH_AMDGCN_GFX908          = 0x030,\n  EF_AMDGPU_MACH_AMDGCN_GFX909          = 0x031,\n  EF_AMDGPU_MACH_AMDGCN_GFX90C          = 0x032,\n  EF_AMDGPU_MACH_AMDGCN_GFX1010         = 0x033,\n  EF_AMDGPU_MACH_AMDGCN_GFX1011         = 0x034,\n  EF_AMDGPU_MACH_AMDGCN_GFX1012         = 0x035,\n  EF_AMDGPU_MACH_AMDGCN_GFX1030         = 0x036,\n  EF_AMDGPU_MACH_AMDGCN_GFX1031         = 0x037,\n  EF_AMDGPU_MACH_AMDGCN_GFX1032         = 0x038,\n  EF_AMDGPU_MACH_AMDGCN_GFX1033         = 0x039,\n  EF_AMDGPU_MACH_AMDGCN_GFX602          = 0x03a,\n  EF_AMDGPU_MACH_AMDGCN_GFX705          = 0x03b,\n  EF_AMDGPU_MACH_AMDGCN_GFX805          = 0x03c,\n  EF_AMDGPU_MACH_AMDGCN_GFX1035         = 0x03d,\n  EF_AMDGPU_MACH_AMDGCN_GFX1034         = 0x03e,\n  EF_AMDGPU_MACH_AMDGCN_GFX90A          = 0x03f,\n  EF_AMDGPU_MACH_AMDGCN_GFX940          = 0x040,\n  EF_AMDGPU_MACH_AMDGCN_GFX1100         = 0x041,\n  EF_AMDGPU_MACH_AMDGCN_GFX1013         = 0x042,\n  EF_AMDGPU_MACH_AMDGCN_GFX1150         = 0x043,\n  EF_AMDGPU_MACH_AMDGCN_GFX1103         = 0x044,\n  EF_AMDGPU_MACH_AMDGCN_GFX1036         = 0x045,\n  EF_AMDGPU_MACH_AMDGCN_GFX1101         = 0x046,\n  EF_AMDGPU_MACH_AMDGCN_GFX1102         = 0x047,\n  EF_AMDGPU_MACH_AMDGCN_GFX1200         = 0x048,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X49   = 0x049,\n  EF_AMDGPU_MACH_AMDGCN_GFX1151         = 0x04a,\n  EF_AMDGPU_MACH_AMDGCN_GFX941          = 0x04b,\n  EF_AMDGPU_MACH_AMDGCN_GFX942          = 0x04c,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X4D   = 0x04d,\n  EF_AMDGPU_MACH_AMDGCN_GFX1201         = 0x04e,\n  EF_AMDGPU_MACH_AMDGCN_GFX950          = 0x04f,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X50   = 0x050,\n  EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC    = 0x051,\n  EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC = 0x052,\n  EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC = 0x053,\n  EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC   = 0x054,\n  EF_AMDGPU_MACH_AMDGCN_GFX1152         = 0x055,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X56   = 0x056,\n  EF_AMDGPU_MACH_AMDGCN_RESERVED_0X57   = 0x057,\n  EF_AMDGPU_MACH_AMDGCN_GFX1153         = 0x058,\n  EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC   = 0x059,\n  EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC  = 0x05f,\n  // clang-format on\n\n  // First/last AMDGCN-based processors.\n  EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600,\n  EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC,\n\n  // Indicates if the \"xnack\" target feature is enabled for all code contained\n  // in the object.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V2.\n  EF_AMDGPU_FEATURE_XNACK_V2 = 0x01,\n  // Indicates if the trap handler is enabled for all code contained\n  // in the object.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V2.\n  EF_AMDGPU_FEATURE_TRAP_HANDLER_V2 = 0x02,\n\n  // Indicates if the \"xnack\" target feature is enabled for all code contained\n  // in the object.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V3.\n  EF_AMDGPU_FEATURE_XNACK_V3 = 0x100,\n  // Indicates if the \"sramecc\" target feature is enabled for all code\n  // contained in the object.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V3.\n  EF_AMDGPU_FEATURE_SRAMECC_V3 = 0x200,\n\n  // XNACK selection mask for EF_AMDGPU_FEATURE_XNACK_* values.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V4.\n  EF_AMDGPU_FEATURE_XNACK_V4 = 0x300,\n  // XNACK is not supported.\n  EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4 = 0x000,\n  // XNACK is any/default/unspecified.\n  EF_AMDGPU_FEATURE_XNACK_ANY_V4 = 0x100,\n  // XNACK is off.\n  EF_AMDGPU_FEATURE_XNACK_OFF_V4 = 0x200,\n  // XNACK is on.\n  EF_AMDGPU_FEATURE_XNACK_ON_V4 = 0x300,\n\n  // SRAMECC selection mask for EF_AMDGPU_FEATURE_SRAMECC_* values.\n  //\n  // Only valid for ELFOSABI_AMDGPU_HSA and ELFABIVERSION_AMDGPU_HSA_V4.\n  EF_AMDGPU_FEATURE_SRAMECC_V4 = 0xc00,\n  // SRAMECC is not supported.\n  EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4 = 0x000,\n  // SRAMECC is any/default/unspecified.\n  EF_AMDGPU_FEATURE_SRAMECC_ANY_V4 = 0x400,\n  // SRAMECC is off.\n  EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 = 0x800,\n  // SRAMECC is on.\n  EF_AMDGPU_FEATURE_SRAMECC_ON_V4 = 0xc00,\n\n  // Generic target versioning. This is contained in the list byte of EFLAGS.\n  EF_AMDGPU_GENERIC_VERSION = 0xff000000,\n  EF_AMDGPU_GENERIC_VERSION_OFFSET = 24,\n  EF_AMDGPU_GENERIC_VERSION_MIN = 1,\n  EF_AMDGPU_GENERIC_VERSION_MAX = 0xff,\n};\n\n// ELF Relocation types for AMDGPU.\nenum : unsigned {\n  R_AMDGPU_ABS32_LO = 1,\n  R_AMDGPU_ABS32_HI = 2,\n  R_AMDGPU_ABS64 = 3,\n  R_AMDGPU_ABS32 = 6,\n  R_AMDGPU_RELATIVE64 = 13,\n};\n\n} // end namespace ELF\n\n// ELF Section Header Flag Enumeration Values.\n#define SHF_AMDGPU_HSA_GLOBAL   (0x00100000 & SHF_MASKOS)\n#define SHF_AMDGPU_HSA_READONLY (0x00200000 & SHF_MASKOS)\n#define SHF_AMDGPU_HSA_CODE     (0x00400000 & SHF_MASKOS)\n#define SHF_AMDGPU_HSA_AGENT    (0x00800000 & SHF_MASKOS)\n\n//\ntypedef enum {\n  AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM = 0,\n  AMDGPU_HSA_SEGMENT_GLOBAL_AGENT = 1,\n  AMDGPU_HSA_SEGMENT_READONLY_AGENT = 2,\n  AMDGPU_HSA_SEGMENT_CODE_AGENT = 3,\n  AMDGPU_HSA_SEGMENT_LAST,\n} amdgpu_hsa_elf_segment_t;\n\n// ELF Program Header Type Enumeration Values.\n#define PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM (PT_LOOS + AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM)\n#define PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT   (PT_LOOS + AMDGPU_HSA_SEGMENT_GLOBAL_AGENT)\n#define PT_AMDGPU_HSA_LOAD_READONLY_AGENT (PT_LOOS + AMDGPU_HSA_SEGMENT_READONLY_AGENT)\n#define PT_AMDGPU_HSA_LOAD_CODE_AGENT     (PT_LOOS + AMDGPU_HSA_SEGMENT_CODE_AGENT)\n\n// ELF Symbol Type Enumeration Values.\n#define STT_AMDGPU_HSA_KERNEL            (STT_LOOS + 0)\n#define STT_AMDGPU_HSA_INDIRECT_FUNCTION (STT_LOOS + 1)\n#define STT_AMDGPU_HSA_METADATA          (STT_LOOS + 2)\n\n// ELF Symbol Binding Enumeration Values.\n#define STB_AMDGPU_HSA_EXTERNAL (STB_LOOS + 0)\n\n// ELF Symbol Other Information Creation/Retrieval.\n#define ELF64_ST_AMDGPU_ALLOCATION(o)  (((o) >> 2) & 0x3)\n#define ELF64_ST_AMDGPU_FLAGS(o)       ((o) >> 4)\n#define ELF64_ST_AMDGPU_OTHER(f, a, v) (((f) << 4) + (((a) & 0x3) << 2) + ((v) & 0x3))\n\ntypedef enum {\n  AMDGPU_HSA_SYMBOL_ALLOCATION_DEFAULT = 0,\n  AMDGPU_HSA_SYMBOL_ALLOCATION_GLOBAL_PROGRAM = 1,\n  AMDGPU_HSA_SYMBOL_ALLOCATION_GLOBAL_AGENT = 2,\n  AMDGPU_HSA_SYMBOL_ALLOCATION_READONLY_AGENT = 3,\n  AMDGPU_HSA_SYMBOL_ALLOCATION_LAST,\n} amdgpu_hsa_symbol_allocation_t;\n\n// ELF Symbol Allocation Enumeration Values.\n#define STA_AMDGPU_HSA_DEFAULT        AMDGPU_HSA_SYMBOL_ALLOCATION_DEFAULT\n#define STA_AMDGPU_HSA_GLOBAL_PROGRAM AMDGPU_HSA_SYMBOL_ALLOCATION_GLOBAL_PROGRAM\n#define STA_AMDGPU_HSA_GLOBAL_AGENT   AMDGPU_HSA_SYMBOL_ALLOCATION_GLOBAL_AGENT\n#define STA_AMDGPU_HSA_READONLY_AGENT AMDGPU_HSA_SYMBOL_ALLOCATION_READONLY_AGENT\n\ntypedef enum {\n  AMDGPU_HSA_SYMBOL_FLAG_DEFAULT = 0,\n  AMDGPU_HSA_SYMBOL_FLAG_CONST = 1,\n  AMDGPU_HSA_SYMBOL_FLAG_LAST,\n} amdgpu_hsa_symbol_flag_t;\n\n// ELF Symbol Flag Enumeration Values.\n#define STF_AMDGPU_HSA_CONST AMDGPU_HSA_SYMBOL_FLAG_CONST\n\n// Legacy/V1 AMD GPU Relocation Type Enumeration Values.\n#define R_AMDGPU_V1_NONE         0\n#define R_AMDGPU_V1_32_LOW       1\n#define R_AMDGPU_V1_32_HIGH      2\n#define R_AMDGPU_V1_64           3\n#define R_AMDGPU_V1_INIT_SAMPLER 4\n#define R_AMDGPU_V1_INIT_IMAGE   5\n#define R_AMDGPU_V1_RELATIVE64   13\n\n// AMD GPU Note Type Enumeration Values.\n#define NT_AMD_HSA_CODE_OBJECT_VERSION 1\n#define NT_AMD_HSA_HSAIL               2\n#define NT_AMD_HSA_ISA_VERSION         3\n#define NT_AMD_HSA_PRODUCER            4\n#define NT_AMD_HSA_PRODUCER_OPTIONS    5\n#define NT_AMD_HSA_EXTENSION           6\n#define NT_AMD_HSA_ISA_NAME            11\n/* AMDGPU snapshots of runtime, agent and queues state for use in core dump */\n#define NT_AMDGPU_CORE_STATE           33\n#define NT_AMD_HSA_HLDEBUG_DEBUG       101\n#define NT_AMD_HSA_HLDEBUG_TARGET      102\n\n// AMD GPU Metadata Kind Enumeration Values.\ntypedef uint16_t amdgpu_hsa_metadata_kind16_t;\ntypedef enum {\n  AMDGPU_HSA_METADATA_KIND_NONE = 0,\n  AMDGPU_HSA_METADATA_KIND_INIT_SAMP = 1,\n  AMDGPU_HSA_METADATA_KIND_INIT_ROIMG = 2,\n  AMDGPU_HSA_METADATA_KIND_INIT_WOIMG = 3,\n  AMDGPU_HSA_METADATA_KIND_INIT_RWIMG = 4\n} amdgpu_hsa_metadata_kind_t;\n\n// AMD GPU Sampler Coordinate Normalization Enumeration Values.\ntypedef uint8_t amdgpu_hsa_sampler_coord8_t;\ntypedef enum {\n  AMDGPU_HSA_SAMPLER_COORD_UNNORMALIZED = 0,\n  AMDGPU_HSA_SAMPLER_COORD_NORMALIZED = 1\n} amdgpu_hsa_sampler_coord_t;\n\n// AMD GPU Sampler Filter Enumeration Values.\ntypedef uint8_t amdgpu_hsa_sampler_filter8_t;\ntypedef enum {\n  AMDGPU_HSA_SAMPLER_FILTER_NEAREST = 0,\n  AMDGPU_HSA_SAMPLER_FILTER_LINEAR = 1\n} amdgpu_hsa_sampler_filter_t;\n\n// AMD GPU Sampler Addressing Enumeration Values.\ntypedef uint8_t amdgpu_hsa_sampler_addressing8_t;\ntypedef enum {\n  AMDGPU_HSA_SAMPLER_ADDRESSING_UNDEFINED = 0,\n  AMDGPU_HSA_SAMPLER_ADDRESSING_CLAMP_TO_EDGE = 1,\n  AMDGPU_HSA_SAMPLER_ADDRESSING_CLAMP_TO_BORDER = 2,\n  AMDGPU_HSA_SAMPLER_ADDRESSING_REPEAT = 3,\n  AMDGPU_HSA_SAMPLER_ADDRESSING_MIRRORED_REPEAT = 4\n} amdgpu_hsa_sampler_addressing_t;\n\n// AMD GPU Sampler Descriptor.\ntypedef struct amdgpu_hsa_sampler_descriptor_s {\n  uint16_t size;\n  amdgpu_hsa_metadata_kind16_t kind;\n  amdgpu_hsa_sampler_coord8_t coord;\n  amdgpu_hsa_sampler_filter8_t filter;\n  amdgpu_hsa_sampler_addressing8_t addressing;\n  uint8_t reserved1;\n} amdgpu_hsa_sampler_descriptor_t;\n\n// AMD GPU Image Geometry Enumeration Values.\ntypedef uint8_t amdgpu_hsa_image_geometry8_t;\ntypedef enum {\n  AMDGPU_HSA_IMAGE_GEOMETRY_1D = 0,\n  AMDGPU_HSA_IMAGE_GEOMETRY_2D = 1,\n  AMDGPU_HSA_IMAGE_GEOMETRY_3D = 2,\n  AMDGPU_HSA_IMAGE_GEOMETRY_1DA = 3,\n  AMDGPU_HSA_IMAGE_GEOMETRY_2DA = 4,\n  AMDGPU_HSA_IMAGE_GEOMETRY_1DB = 5,\n  AMDGPU_HSA_IMAGE_GEOMETRY_2DDEPTH = 6,\n  AMDGPU_HSA_IMAGE_GEOMETRY_2DADEPTH = 7\n} amdgpu_hsa_image_geometry_t;\n\n// AMD GPU Image Channel Order Enumeration Values.\ntypedef uint8_t amdgpu_hsa_image_channel_order8_t;\ntypedef enum {\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_A = 0,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_R = 1,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RX = 2,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RG = 3,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RGX = 4,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RA = 5,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RGB = 6,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RGBX = 7,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_RGBA = 8,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_BGRA = 9,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_ARGB = 10,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_ABGR = 11,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_SRGB = 12,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_SRGBX = 13,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_SRGBA = 14,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_SBGRA = 15,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_INTENSITY = 16,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_LUMINANCE = 17,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_DEPTH = 18,\n  AMDGPU_HSA_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL = 19\n} amdgpu_hsa_image_channel_order_t;\n\n// AMD GPU Image Channel Type Enumeration Values.\ntypedef uint8_t amdgpu_hsa_image_channel_type8_t;\ntypedef enum {\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SNORM_INT8 = 0,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SNORM_INT16 = 1,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNORM_INT8 = 2,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNORM_INT16 = 3,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNORM_INT24 = 4,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SHORT_555 = 5,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SHORT_565 = 6,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_INT_101010 = 7,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SIGNED_INT8 = 8,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SIGNED_INT16 = 9,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_SIGNED_INT32 = 10,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8 = 11,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16 = 12,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32 = 13,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_HALF_FLOAT = 14,\n  AMDGPU_HSA_IMAGE_CHANNEL_TYPE_FLOAT = 15\n} amdgpu_hsa_image_channel_type_t;\n\n// AMD GPU Image Descriptor.\ntypedef struct amdgpu_hsa_image_descriptor_s {\n  uint16_t size;\n  amdgpu_hsa_metadata_kind16_t kind;\n  amdgpu_hsa_image_geometry8_t geometry;\n  amdgpu_hsa_image_channel_order8_t channel_order;\n  amdgpu_hsa_image_channel_type8_t channel_type;\n  uint8_t reserved1;\n  uint64_t width;\n  uint64_t height;\n  uint64_t depth;\n  uint64_t array;\n} amdgpu_hsa_image_descriptor_t;\n\ntypedef struct amdgpu_hsa_note_code_object_version_s {\n  uint32_t major_version;\n  uint32_t minor_version;\n} amdgpu_hsa_note_code_object_version_t;\n\ntypedef struct amdgpu_hsa_note_hsail_s {\n  uint32_t hsail_major_version;\n  uint32_t hsail_minor_version;\n  uint8_t profile;\n  uint8_t machine_model;\n  uint8_t default_float_round;\n} amdgpu_hsa_note_hsail_t;\n\ntypedef struct amdgpu_hsa_note_isa_s {\n  uint16_t vendor_name_size;\n  uint16_t architecture_name_size;\n  uint32_t major;\n  uint32_t minor;\n  uint32_t stepping;\n  char vendor_and_architecture_name[1];\n} amdgpu_hsa_note_isa_t;\n\ntypedef struct amdgpu_hsa_note_producer_s {\n  uint16_t producer_name_size;\n  uint16_t reserved;\n  uint32_t producer_major_version;\n  uint32_t producer_minor_version;\n  char producer_name[1];\n} amdgpu_hsa_note_producer_t;\n\ntypedef struct amdgpu_hsa_note_producer_options_s {\n  uint16_t producer_options_size;\n  char producer_options[1];\n} amdgpu_hsa_note_producer_options_t;\n\ntypedef enum {\n  AMDGPU_HSA_RODATA_GLOBAL_PROGRAM = 0,\n  AMDGPU_HSA_RODATA_GLOBAL_AGENT,\n  AMDGPU_HSA_RODATA_READONLY_AGENT,\n  AMDGPU_HSA_DATA_GLOBAL_PROGRAM,\n  AMDGPU_HSA_DATA_GLOBAL_AGENT,\n  AMDGPU_HSA_DATA_READONLY_AGENT,\n  AMDGPU_HSA_BSS_GLOBAL_PROGRAM,\n  AMDGPU_HSA_BSS_GLOBAL_AGENT,\n  AMDGPU_HSA_BSS_READONLY_AGENT,\n  AMDGPU_HSA_SECTION_LAST,\n} amdgpu_hsa_elf_section_t;\n\n#endif // AMD_HSA_ELF_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/amd_hsa_kernel_code.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_KERNEL_CODE_H\n#define AMD_HSA_KERNEL_CODE_H\n\n#include \"amd_hsa_common.h\"\n#include \"hsa.h\"\n\n// AMD Kernel Code Version Enumeration Values.\ntypedef uint32_t amd_kernel_code_version32_t;\nenum amd_kernel_code_version_t {\n  AMD_KERNEL_CODE_VERSION_MAJOR = 1,\n  AMD_KERNEL_CODE_VERSION_MINOR = 1\n};\n\n// AMD Machine Kind Enumeration Values.\ntypedef uint16_t amd_machine_kind16_t;\nenum amd_machine_kind_t {\n  AMD_MACHINE_KIND_UNDEFINED = 0,\n  AMD_MACHINE_KIND_AMDGPU = 1\n};\n\n// AMD Machine Version.\ntypedef uint16_t amd_machine_version16_t;\n\n// AMD Float Round Mode Enumeration Values.\nenum amd_float_round_mode_t {\n  AMD_FLOAT_ROUND_MODE_NEAREST_EVEN = 0,\n  AMD_FLOAT_ROUND_MODE_PLUS_INFINITY = 1,\n  AMD_FLOAT_ROUND_MODE_MINUS_INFINITY = 2,\n  AMD_FLOAT_ROUND_MODE_ZERO = 3\n};\n\n// AMD Float Denorm Mode Enumeration Values.\nenum amd_float_denorm_mode_t {\n  AMD_FLOAT_DENORM_MODE_FLUSH_SOURCE_OUTPUT = 0,\n  AMD_FLOAT_DENORM_MODE_FLUSH_OUTPUT = 1,\n  AMD_FLOAT_DENORM_MODE_FLUSH_SOURCE = 2,\n  AMD_FLOAT_DENORM_MODE_NO_FLUSH = 3\n};\n\n// AMD Compute Program Resource Register One.\ntypedef uint32_t amd_compute_pgm_rsrc_one32_t;\nenum amd_compute_pgm_rsrc_one_t {\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WORKITEM_VGPR_COUNT, 0, 6),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WAVEFRONT_SGPR_COUNT, 6, 4),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_PRIORITY, 10, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_ROUND_MODE_32, 12, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_ROUND_MODE_16_64, 14, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_DENORM_MODE_32, 16, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_DENORM_MODE_16_64, 18, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_PRIV, 20, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_ENABLE_DX10_CLAMP, 21, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_DEBUG_MODE, 22, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_ENABLE_IEEE_MODE, 23, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_BULKY, 24, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_CDBG_USER, 25, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_ONE_RESERVED1, 26, 6)\n};\n\n// AMD System VGPR Workitem ID Enumeration Values.\nenum amd_system_vgpr_workitem_id_t {\n  AMD_SYSTEM_VGPR_WORKITEM_ID_X = 0,\n  AMD_SYSTEM_VGPR_WORKITEM_ID_X_Y = 1,\n  AMD_SYSTEM_VGPR_WORKITEM_ID_X_Y_Z = 2,\n  AMD_SYSTEM_VGPR_WORKITEM_ID_UNDEFINED = 3\n};\n\n// AMD Compute Program Resource Register Two.\ntypedef uint32_t amd_compute_pgm_rsrc_two32_t;\nenum amd_compute_pgm_rsrc_two_t {\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_PRIVATE_SEGMENT_WAVE_BYTE_OFFSET, 0, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_USER_SGPR_COUNT, 1, 5),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_TRAP_HANDLER, 6, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_X, 7, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_Y, 8, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_Z, 9, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_INFO, 10, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_VGPR_WORKITEM_ID, 11, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_ADDRESS_WATCH, 13, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_MEMORY_VIOLATION, 14, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_GRANULATED_LDS_SIZE, 15, 9),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION, 24, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE, 25, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO, 26, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW, 27, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW, 28, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT, 29, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_INT_DIVISION_BY_ZERO, 30, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_COMPUTE_PGM_RSRC_TWO_RESERVED1, 31, 1)\n};\n\n// AMD Element Byte Size Enumeration Values.\nenum amd_element_byte_size_t {\n  AMD_ELEMENT_BYTE_SIZE_2 = 0,\n  AMD_ELEMENT_BYTE_SIZE_4 = 1,\n  AMD_ELEMENT_BYTE_SIZE_8 = 2,\n  AMD_ELEMENT_BYTE_SIZE_16 = 3\n};\n\n// AMD Kernel Code Properties.\ntypedef uint32_t amd_kernel_code_properties32_t;\nenum amd_kernel_code_properties_t {\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER, 0, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_DISPATCH_PTR, 1, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_QUEUE_PTR, 2, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_KERNARG_SEGMENT_PTR, 3, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_DISPATCH_ID, 4, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_FLAT_SCRATCH_INIT, 5, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE, 6, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_X, 7, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y, 8, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z, 9, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_WAVEFRONT_SIZE32, 10, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_RESERVED1, 11, 5),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_ENABLE_ORDERED_APPEND_GDS, 16, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_PRIVATE_ELEMENT_SIZE, 17, 2),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_IS_PTR64, 19, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_IS_DYNAMIC_CALLSTACK, 20, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_IS_DEBUG_ENABLED, 21, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_IS_XNACK_ENABLED, 22, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_KERNEL_CODE_PROPERTIES_RESERVED2, 23, 9)\n};\n\n// AMD Power Of Two Enumeration Values.\ntypedef uint8_t amd_powertwo8_t;\nenum amd_powertwo_t {\n  AMD_POWERTWO_1 = 0,\n  AMD_POWERTWO_2 = 1,\n  AMD_POWERTWO_4 = 2,\n  AMD_POWERTWO_8 = 3,\n  AMD_POWERTWO_16 = 4,\n  AMD_POWERTWO_32 = 5,\n  AMD_POWERTWO_64 = 6,\n  AMD_POWERTWO_128 = 7,\n  AMD_POWERTWO_256 = 8\n};\n\n// AMD Enabled Control Directive Enumeration Values.\ntypedef uint64_t amd_enabled_control_directive64_t;\nenum amd_enabled_control_directive_t {\n  AMD_ENABLED_CONTROL_DIRECTIVE_ENABLE_BREAK_EXCEPTIONS = 1,\n  AMD_ENABLED_CONTROL_DIRECTIVE_ENABLE_DETECT_EXCEPTIONS = 2,\n  AMD_ENABLED_CONTROL_DIRECTIVE_MAX_DYNAMIC_GROUP_SIZE = 4,\n  AMD_ENABLED_CONTROL_DIRECTIVE_MAX_FLAT_GRID_SIZE = 8,\n  AMD_ENABLED_CONTROL_DIRECTIVE_MAX_FLAT_WORKGROUP_SIZE = 16,\n  AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_DIM = 32,\n  AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_GRID_SIZE = 64,\n  AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_WORKGROUP_SIZE = 128,\n  AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRE_NO_PARTIAL_WORKGROUPS = 256\n};\n\n// AMD Exception Kind Enumeration Values.\ntypedef uint16_t amd_exception_kind16_t;\nenum amd_exception_kind_t {\n  AMD_EXCEPTION_KIND_INVALID_OPERATION = 1,\n  AMD_EXCEPTION_KIND_DIVISION_BY_ZERO = 2,\n  AMD_EXCEPTION_KIND_OVERFLOW = 4,\n  AMD_EXCEPTION_KIND_UNDERFLOW = 8,\n  AMD_EXCEPTION_KIND_INEXACT = 16\n};\n\n// AMD Control Directives.\n#define AMD_CONTROL_DIRECTIVES_ALIGN_BYTES 64\n#define AMD_CONTROL_DIRECTIVES_ALIGN __ALIGNED__(AMD_CONTROL_DIRECTIVES_ALIGN_BYTES)\ntypedef AMD_CONTROL_DIRECTIVES_ALIGN struct amd_control_directives_s {\n  amd_enabled_control_directive64_t enabled_control_directives;\n  uint16_t enable_break_exceptions;\n  uint16_t enable_detect_exceptions;\n  uint32_t max_dynamic_group_size;\n  uint64_t max_flat_grid_size;\n  uint32_t max_flat_workgroup_size;\n  uint8_t required_dim;\n  uint8_t reserved1[3];\n  uint64_t required_grid_size[3];\n  uint32_t required_workgroup_size[3];\n  uint8_t reserved2[60];\n} amd_control_directives_t;\n\n// AMD Kernel Code.\n#define AMD_ISA_ALIGN_BYTES 256\n#define AMD_KERNEL_CODE_ALIGN_BYTES 64\n#define AMD_KERNEL_CODE_ALIGN __ALIGNED__(AMD_KERNEL_CODE_ALIGN_BYTES)\ntypedef AMD_KERNEL_CODE_ALIGN struct amd_kernel_code_s {\n  amd_kernel_code_version32_t amd_kernel_code_version_major;\n  amd_kernel_code_version32_t amd_kernel_code_version_minor;\n  amd_machine_kind16_t amd_machine_kind;\n  amd_machine_version16_t amd_machine_version_major;\n  amd_machine_version16_t amd_machine_version_minor;\n  amd_machine_version16_t amd_machine_version_stepping;\n  int64_t kernel_code_entry_byte_offset;\n  int64_t kernel_code_prefetch_byte_offset;\n  uint64_t kernel_code_prefetch_byte_size;\n  uint64_t max_scratch_backing_memory_byte_size;\n  amd_compute_pgm_rsrc_one32_t compute_pgm_rsrc1;\n  amd_compute_pgm_rsrc_two32_t compute_pgm_rsrc2;\n  amd_kernel_code_properties32_t kernel_code_properties;\n  uint32_t workitem_private_segment_byte_size;\n  uint32_t workgroup_group_segment_byte_size;\n  uint32_t gds_segment_byte_size;\n  uint64_t kernarg_segment_byte_size;\n  uint32_t workgroup_fbarrier_count;\n  uint16_t wavefront_sgpr_count;\n  uint16_t workitem_vgpr_count;\n  uint16_t reserved_vgpr_first;\n  uint16_t reserved_vgpr_count;\n  uint16_t reserved_sgpr_first;\n  uint16_t reserved_sgpr_count;\n  uint16_t debug_wavefront_private_segment_offset_sgpr;\n  uint16_t debug_private_segment_buffer_sgpr;\n  amd_powertwo8_t kernarg_segment_alignment;\n  amd_powertwo8_t group_segment_alignment;\n  amd_powertwo8_t private_segment_alignment;\n  amd_powertwo8_t wavefront_size;\n  int32_t call_convention;\n  uint8_t reserved1[12];\n  uint64_t runtime_loader_kernel_symbol;\n  amd_control_directives_t control_directives;\n} amd_kernel_code_t;\n\n// TODO: this struct should be completely gone once debugger designs/implements\n// Debugger APIs.\ntypedef struct amd_runtime_loader_debug_info_s {\n  const void* elf_raw;\n  size_t elf_size;\n  const char *kernel_name;\n  const void *owning_segment;\n} amd_runtime_loader_debug_info_t;\n\n#endif // AMD_HSA_KERNEL_CODE_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/amd_hsa_queue.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_QUEUE_H\n#define AMD_HSA_QUEUE_H\n\n#include \"amd_hsa_common.h\"\n#include \"hsa.h\"\n\n// AMD Queue Properties.\ntypedef uint32_t amd_queue_properties32_t;\nenum amd_queue_properties_t {\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_ENABLE_TRAP_HANDLER, 0, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_IS_PTR64, 1, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_ENABLE_TRAP_HANDLER_DEBUG_SGPRS, 2, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_ENABLE_PROFILING, 3, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_USE_SCRATCH_ONCE, 4, 1),\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_PROPERTIES_RESERVED1, 5, 27)\n};\n\n// AMD Queue.\n#define AMD_QUEUE_ALIGN_BYTES 64\n#define AMD_QUEUE_ALIGN __ALIGNED__(AMD_QUEUE_ALIGN_BYTES)\n\n// AMD Queue Capabilities.\ntypedef uint32_t amd_queue_capabilities32_t;\nenum amd_queue_capabilities_t {\n  /* This version of CP FW supports dual-scratch and async-reclaim */\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_CAPS_CP_ASYNC_RECLAIM, 0, 1),\n\n  /*\n   * This version of ROCr supports async-reclaim and CP FW may access the\n   * V2 fields.\n   */\n  AMD_HSA_BITS_CREATE_ENUM_ENTRIES(AMD_QUEUE_CAPS_SW_ASYNC_RECLAIM, 1, 1),\n};\n\n/* This is the original amd_queue_t structure. The definition is only kept\n * for reference purposes. This structure should not be used. */\ntypedef struct AMD_QUEUE_ALIGN amd_queue_s {\n  hsa_queue_t hsa_queue;\n  uint32_t caps;\n  uint32_t reserved1[3];\n  volatile uint64_t write_dispatch_id;\n  uint32_t group_segment_aperture_base_hi;\n  uint32_t private_segment_aperture_base_hi;\n  uint32_t max_cu_id;\n  uint32_t max_wave_id;\n  volatile uint64_t max_legacy_doorbell_dispatch_id_plus_1;\n  volatile uint32_t legacy_doorbell_lock;\n  uint32_t reserved2[9];\n  volatile uint64_t read_dispatch_id;\n  uint32_t read_dispatch_id_field_base_byte_offset;\n  uint32_t compute_tmpring_size;\n  uint32_t scratch_resource_descriptor[4];\n  uint64_t scratch_backing_memory_location;\n  uint32_t reserved3[2];\n  uint32_t scratch_wave64_lane_byte_size;\n  amd_queue_properties32_t queue_properties;\n  uint32_t reserved4[2];\n  hsa_signal_t queue_inactive_signal;\n  uint32_t reserved5[14];\n} amd_queue_t;\n\n/*\n * AMD_QUEUE Version 2\n * amd_queue_v2_t is backwards compatible with amd_queue_t structure and can\n * be used with previous versions of CP FW. The added fields tagged as V2 are\n * ignored when running previous versions of CP FW.\n * CP FW will not try to access elements beyond the original 64-bytes\n * (sizeof(amd_queue_t)) unless the AMD_QUEUE_CAPS_SW_ASYNC_RECLAIM bit is set.\n */\n\n#define MAX_NUM_XCC 128\ntypedef struct scratch_last_used_index_xcc_s {\n  volatile uint64_t main;\n  volatile uint64_t alt;\n} scratch_last_used_index_xcc_t;\n\ntypedef struct AMD_QUEUE_ALIGN amd_queue_v2_s {\n  hsa_queue_t hsa_queue;\n  uint32_t caps;\n  uint32_t reserved1[3];\n  volatile uint64_t write_dispatch_id;\n  uint32_t group_segment_aperture_base_hi;\n  uint32_t private_segment_aperture_base_hi;\n  uint32_t max_cu_id;\n  uint32_t max_wave_id;\n  volatile uint64_t max_legacy_doorbell_dispatch_id_plus_1;\n  volatile uint32_t legacy_doorbell_lock;\n  uint32_t reserved2[9];\n  volatile uint64_t read_dispatch_id;\n  uint32_t read_dispatch_id_field_base_byte_offset;\n  uint32_t compute_tmpring_size;\n  uint32_t scratch_resource_descriptor[4];\n  uint64_t scratch_backing_memory_location;\n  uint64_t scratch_backing_memory_byte_size;\n  uint32_t scratch_wave64_lane_byte_size;\n  amd_queue_properties32_t queue_properties;\n  volatile uint64_t scratch_max_use_index;       /* V2 */\n  hsa_signal_t queue_inactive_signal;\n  volatile uint64_t alt_scratch_max_use_index;  /* V2 */\n  uint32_t alt_scratch_resource_descriptor[4];   /* V2 */\n  uint64_t alt_scratch_backing_memory_location;  /* V2 */\n  uint32_t alt_scratch_dispatch_limit_x;         /* V2 */\n  uint32_t alt_scratch_dispatch_limit_y;         /* V2 */\n  uint32_t alt_scratch_dispatch_limit_z;         /* V2 */\n  uint32_t alt_scratch_wave64_lane_byte_size;    /* V2 */\n  uint32_t alt_compute_tmpring_size;             /* V2 */\n  uint32_t reserved5;\n\n  scratch_last_used_index_xcc_t scratch_last_used_index[MAX_NUM_XCC];\n} amd_queue_v2_t;\n\n#endif // AMD_HSA_QUEUE_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/amd_hsa_signal.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_SIGNAL_H\n#define AMD_HSA_SIGNAL_H\n\n#include \"amd_hsa_common.h\"\n#include \"amd_hsa_queue.h\"\n\n// AMD Signal Kind Enumeration Values.\ntypedef int64_t amd_signal_kind64_t;\nenum amd_signal_kind_t {\n  AMD_SIGNAL_KIND_INVALID = 0,\n  AMD_SIGNAL_KIND_USER = 1,\n  AMD_SIGNAL_KIND_DOORBELL = -1,\n  AMD_SIGNAL_KIND_LEGACY_DOORBELL = -2\n};\n\n// AMD Signal.\n#define AMD_SIGNAL_ALIGN_BYTES 64\n#define AMD_SIGNAL_ALIGN __ALIGNED__(AMD_SIGNAL_ALIGN_BYTES)\ntypedef struct AMD_SIGNAL_ALIGN amd_signal_s {\n  amd_signal_kind64_t kind;\n  union {\n    volatile int64_t value;\n    volatile uint64_t* hardware_doorbell_ptr;\n  };\n  uint64_t event_mailbox_ptr;\n  uint32_t event_id;\n  uint32_t reserved1;\n  uint64_t start_ts;\n  uint64_t end_ts;\n  union {\n    amd_queue_v2_t* queue_ptr;\n    uint64_t reserved2;\n  };\n  uint32_t reserved3[2];\n} amd_signal_t;\n\n#endif // AMD_HSA_SIGNAL_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_INC_HSA_H_\n#define HSA_RUNTIME_INC_HSA_H_\n\n#include <stddef.h>   /* size_t */\n#include <stdint.h>   /* uintXX_t */\n\n#ifndef __cplusplus\n#include <stdbool.h>  /* bool */\n#endif /* __cplusplus */\n\n// Placeholder for calling convention and import/export macros\n#ifndef HSA_CALL\n#define HSA_CALL\n#endif\n\n#ifndef HSA_EXPORT_DECORATOR\n#ifdef __GNUC__\n#define HSA_EXPORT_DECORATOR __attribute__ ((visibility (\"default\")))\n#else\n#define HSA_EXPORT_DECORATOR\n#endif\n#endif\n#define HSA_API_EXPORT HSA_EXPORT_DECORATOR HSA_CALL\n#define HSA_API_IMPORT HSA_CALL\n\n#if !defined(HSA_API) && defined(HSA_EXPORT)\n#define HSA_API HSA_API_EXPORT\n#else\n#define HSA_API HSA_API_IMPORT\n#endif\n\n// Detect and set large model builds.\n#undef HSA_LARGE_MODEL\n#if defined(__LP64__) || defined(_M_X64)\n#define HSA_LARGE_MODEL\n#endif\n\n// Try to detect CPU endianness\n#if !defined(LITTLEENDIAN_CPU) && !defined(BIGENDIAN_CPU)\n#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#define LITTLEENDIAN_CPU\n#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define BIGENDIAN_CPU\n#elif defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \\\n      defined(_M_X64) || defined(__loongarch64) || defined(__riscv)\n#define LITTLEENDIAN_CPU\n#endif\n#endif\n\n#undef HSA_LITTLE_ENDIAN\n#if defined(LITTLEENDIAN_CPU)\n#define HSA_LITTLE_ENDIAN\n#elif defined(BIGENDIAN_CPU)\n#else\n#error \"BIGENDIAN_CPU or LITTLEENDIAN_CPU must be defined\"\n#endif\n\n#ifndef HSA_DEPRECATED\n#define HSA_DEPRECATED\n//#ifdef __GNUC__\n//#define HSA_DEPRECATED __attribute__((deprecated))\n//#else\n//#define HSA_DEPRECATED __declspec(deprecated)\n//#endif\n#endif\n\n#define HSA_VERSION_1_0                              1\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  /* __cplusplus */\n\n/** \\addtogroup error-codes Error codes\n *  @{\n */\n\n/**\n * @brief Status codes.\n */\ntypedef enum {\n  /**\n   * The function has been executed successfully.\n   */\n  HSA_STATUS_SUCCESS = 0x0,\n  /**\n   * A traversal over a list of elements has been interrupted by the\n   * application before completing.\n   */\n  HSA_STATUS_INFO_BREAK = 0x1,\n  /**\n   * A generic error has occurred.\n   */\n  HSA_STATUS_ERROR = 0x1000,\n  /**\n   * One of the actual arguments does not meet a precondition stated in the\n   * documentation of the corresponding formal argument.\n   */\n  HSA_STATUS_ERROR_INVALID_ARGUMENT = 0x1001,\n  /**\n   * The requested queue creation is not valid.\n   */\n  HSA_STATUS_ERROR_INVALID_QUEUE_CREATION = 0x1002,\n  /**\n   * The requested allocation is not valid.\n   */\n  HSA_STATUS_ERROR_INVALID_ALLOCATION = 0x1003,\n  /**\n   * The agent is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_AGENT = 0x1004,\n  /**\n   * The memory region is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_REGION = 0x1005,\n  /**\n   * The signal is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_SIGNAL = 0x1006,\n  /**\n   * The queue is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_QUEUE = 0x1007,\n  /**\n   * The HSA runtime failed to allocate the necessary resources. This error\n   * may also occur when the HSA runtime needs to spawn threads or create\n   * internal OS-specific events.\n   */\n  HSA_STATUS_ERROR_OUT_OF_RESOURCES = 0x1008,\n  /**\n   * The AQL packet is malformed.\n   */\n  HSA_STATUS_ERROR_INVALID_PACKET_FORMAT = 0x1009,\n  /**\n   * An error has been detected while releasing a resource.\n   */\n  HSA_STATUS_ERROR_RESOURCE_FREE = 0x100A,\n  /**\n   * An API other than ::hsa_init has been invoked while the reference count\n   * of the HSA runtime is 0.\n   */\n  HSA_STATUS_ERROR_NOT_INITIALIZED = 0x100B,\n  /**\n   * The maximum reference count for the object has been reached.\n   */\n  HSA_STATUS_ERROR_REFCOUNT_OVERFLOW = 0x100C,\n  /**\n   * The arguments passed to a functions are not compatible.\n   */\n  HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS = 0x100D,\n  /**\n   * The index is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_INDEX = 0x100E,\n  /**\n   * The instruction set architecture is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_ISA = 0x100F,\n  /**\n   * The instruction set architecture name is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_ISA_NAME = 0x1017,\n  /**\n   * The code object is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_CODE_OBJECT = 0x1010,\n  /**\n   * The executable is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_EXECUTABLE = 0x1011,\n  /**\n   * The executable is frozen.\n   */\n  HSA_STATUS_ERROR_FROZEN_EXECUTABLE = 0x1012,\n  /**\n   * There is no symbol with the given name.\n   */\n  HSA_STATUS_ERROR_INVALID_SYMBOL_NAME = 0x1013,\n  /**\n   * The variable is already defined.\n   */\n  HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED = 0x1014,\n  /**\n   * The variable is undefined.\n   */\n  HSA_STATUS_ERROR_VARIABLE_UNDEFINED = 0x1015,\n  /**\n   * An HSAIL operation resulted in a hardware exception.\n   */\n  HSA_STATUS_ERROR_EXCEPTION = 0x1016,\n  /**\n   * The code object symbol is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_CODE_SYMBOL = 0x1018,\n  /**\n   * The executable symbol is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_EXECUTABLE_SYMBOL = 0x1019,\n  /**\n   * The file descriptor is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_FILE = 0x1020,\n  /**\n   * The code object reader is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER = 0x1021,\n  /**\n   * The cache is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_CACHE = 0x1022,\n  /**\n   * The wavefront is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_WAVEFRONT = 0x1023,\n  /**\n   * The signal group is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP = 0x1024,\n  /**\n   * The HSA runtime is not in the configuration state.\n   */\n  HSA_STATUS_ERROR_INVALID_RUNTIME_STATE = 0x1025,\n  /**\n  * The queue received an error that may require process termination.\n  */\n  HSA_STATUS_ERROR_FATAL = 0x1026\n} hsa_status_t;\n\n/**\n * @brief Query additional information about a status code.\n *\n * @param[in] status Status code.\n *\n * @param[out] status_string A NUL-terminated string that describes the error\n * status.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p status is an invalid\n * status code, or @p status_string is NULL.\n */\nhsa_status_t HSA_API hsa_status_string(\n    hsa_status_t status,\n    const char ** status_string);\n\n/** @} */\n\n/** \\defgroup common Common Definitions\n *  @{\n */\n\n/**\n * @brief Three-dimensional coordinate.\n */\ntypedef struct hsa_dim3_s {\n  /**\n   * X dimension.\n   */\n   uint32_t x;\n\n  /**\n   * Y dimension.\n   */\n   uint32_t y;\n\n   /**\n    * Z dimension.\n    */\n   uint32_t z;\n} hsa_dim3_t;\n\n/**\n * @brief Access permissions.\n */\ntypedef enum {\n  /**\n   * Used to remove existing access\n   */\n  HSA_ACCESS_PERMISSION_NONE = 0,\n  /**\n   * Read-only access.\n   */\n  HSA_ACCESS_PERMISSION_RO = 1,\n  /**\n   * Write-only access.\n   */\n  HSA_ACCESS_PERMISSION_WO = 2,\n  /**\n   * Read and write access.\n   */\n  HSA_ACCESS_PERMISSION_RW = 3\n} hsa_access_permission_t;\n\n/**\n * @brief POSIX file descriptor.\n */\ntypedef int hsa_file_t;\n\n/** @} **/\n\n\n/** \\defgroup initshutdown Initialization and Shut Down\n *  @{\n */\n\n/**\n * @brief Initialize the HSA runtime.\n *\n * @details Initializes the HSA runtime if it is not already initialized, and\n * increases the reference counter associated with the HSA runtime for the\n * current process. Invocation of any HSA function other than ::hsa_init results\n * in undefined behavior if the current HSA runtime reference counter is less\n * than one.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_REFCOUNT_OVERFLOW The HSA runtime reference\n * count reaches INT32_MAX.\n */\nhsa_status_t HSA_API hsa_init();\n\n/**\n * @brief Shut down the HSA runtime.\n *\n * @details Decreases the reference count of the HSA runtime instance. When the\n * reference count reaches 0, the HSA runtime is no longer considered valid\n * but the application might call ::hsa_init to initialize the HSA runtime\n * again.\n *\n * Once the reference count of the HSA runtime reaches 0, all the resources\n * associated with it (queues, signals, agent information, etc.) are\n * considered invalid and any attempt to reference them in subsequent API calls\n * results in undefined behavior. When the reference count reaches 0, the HSA\n * runtime may release resources associated with it.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n */\nhsa_status_t HSA_API hsa_shut_down();\n\n/** @} **/\n\n/** \\defgroup agentinfo System and Agent Information\n *  @{\n */\n\n/**\n * @brief Endianness. A convention used to interpret the bytes making up a data\n * word.\n */\ntypedef enum {\n    /**\n     * The least significant byte is stored in the smallest address.\n     */\n    HSA_ENDIANNESS_LITTLE = 0,\n    /**\n     * The most significant byte is stored in the smallest address.\n     */\n    HSA_ENDIANNESS_BIG = 1\n} hsa_endianness_t;\n\n/**\n * @brief Machine model. A machine model determines the size of certain data\n * types in HSA runtime and an agent.\n */\ntypedef enum {\n    /**\n     * Small machine model. Addresses use 32 bits.\n     */\n    HSA_MACHINE_MODEL_SMALL = 0,\n    /**\n     * Large machine model. Addresses use 64 bits.\n     */\n    HSA_MACHINE_MODEL_LARGE = 1\n} hsa_machine_model_t;\n\n/**\n * @brief Profile. A profile indicates a particular level of feature\n * support. For example, in the base profile the application must use the HSA\n * runtime allocator to reserve shared virtual memory, while in the full profile\n * any host pointer can be shared across all the agents.\n */\ntypedef enum {\n    /**\n     * Base profile.\n     */\n    HSA_PROFILE_BASE = 0,\n    /**\n     * Full profile.\n     */\n    HSA_PROFILE_FULL = 1\n} hsa_profile_t;\n\n/**\n * @brief System attributes.\n */\ntypedef enum {\n  /**\n   * Major version of the HSA runtime specification supported by the\n   * implementation. The type of this attribute is uint16_t.\n   */\n  HSA_SYSTEM_INFO_VERSION_MAJOR = 0,\n  /**\n   * Minor version of the HSA runtime specification supported by the\n   * implementation. The type of this attribute is uint16_t.\n   */\n  HSA_SYSTEM_INFO_VERSION_MINOR = 1,\n  /**\n   * Current timestamp. The value of this attribute monotonically increases at a\n   * constant rate. The type of this attribute is uint64_t.\n   */\n  HSA_SYSTEM_INFO_TIMESTAMP = 2,\n  /**\n   * Timestamp value increase rate, in Hz. The timestamp (clock) frequency is\n   * in the range 1-400MHz. The type of this attribute is uint64_t.\n   */\n  HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY = 3,\n  /**\n   * Maximum duration of a signal wait operation. Expressed as a count based on\n   * the timestamp frequency. The type of this attribute is uint64_t.\n   */\n  HSA_SYSTEM_INFO_SIGNAL_MAX_WAIT = 4,\n  /**\n   * Endianness of the system. The type of this attribute is ::hsa_endianness_t.\n   */\n  HSA_SYSTEM_INFO_ENDIANNESS = 5,\n  /**\n   * Machine model supported by the HSA runtime. The type of this attribute is\n   * ::hsa_machine_model_t.\n   */\n  HSA_SYSTEM_INFO_MACHINE_MODEL = 6,\n  /**\n   * Bit-mask indicating which extensions are supported by the\n   * implementation. An extension with an ID of @p i is supported if the bit at\n   * position @p i is set. The type of this attribute is uint8_t[128].\n   */\n  HSA_SYSTEM_INFO_EXTENSIONS = 7,\n  /**\n  * String containing the ROCr build identifier.\n  */\n  HSA_AMD_SYSTEM_INFO_BUILD_VERSION = 0x200,\n  /**\n   * Returns true if hsa_amd_svm_* APIs are supported by the driver.  The type of\n   * this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_SVM_SUPPORTED = 0x201,\n  // TODO: Should this be per Agent?\n  /**\n   * Returns true if all Agents have access to system allocated memory (such as\n   * that allocated by mmap, malloc, or new) by default.\n   * If false then system allocated memory may only be made SVM accessible to\n   * an Agent by declaration of accessibility with hsa_amd_svm_set_attributes.\n   * The type of this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_SVM_ACCESSIBLE_BY_DEFAULT = 0x202,\n  /**\n   * Returns true if mwaitx is enabled on this system\n   * The type of this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_MWAITX_ENABLED = 0x203,\n  /**\n   * Returns true if DMABUF APIs are supported by the driver.  The type of\n   * this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_DMABUF_SUPPORTED = 0x204,\n  /**\n   * Returns true if Virtual Memory APIs are supported by the driver.  The type of\n   * this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_VIRTUAL_MEM_API_SUPPORTED = 0x205,\n  /**\n   * Returns true if XNACK is enabled on this system.  The type of\n   * this attribute is bool.\n   */\n  HSA_AMD_SYSTEM_INFO_XNACK_ENABLED = 0x206,\n  /**\n   * Major version of the HSA runtime extension specification supported by the\n   * implementation. The type of this attribute is uint16_t.\n   */\n  HSA_AMD_SYSTEM_INFO_EXT_VERSION_MAJOR = 0x207,\n  /**\n   * Minor version of the HSA runtime extension specification supported by the\n   * implementation. The type of this attribute is uint16_t.\n   */\n  HSA_AMD_SYSTEM_INFO_EXT_VERSION_MINOR = 0x208,\n} hsa_system_info_t;\n\n/**\n * @brief Get the current value of a system attribute.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * system attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_system_get_info(\n    hsa_system_info_t attribute,\n    void* value);\n\n/**\n * @brief HSA extensions.\n */\ntypedef enum {\n  /**\n   * Finalizer extension.\n   */\n  HSA_EXTENSION_FINALIZER = 0,\n  /**\n   * Images extension.\n   */\n  HSA_EXTENSION_IMAGES = 1,\n\n  /**\n   * Performance counter extension.\n   */\n  HSA_EXTENSION_PERFORMANCE_COUNTERS = 2,\n\n  /**\n   * Profiling events extension.\n   */\n  HSA_EXTENSION_PROFILING_EVENTS = 3,\n  /**\n   * Extension count.\n   */\n  HSA_EXTENSION_STD_LAST = 3,\n  /**\n   * First AMD extension number.\n   */\n  HSA_AMD_FIRST_EXTENSION = 0x200,\n  /**\n   * Profiler extension.\n   */\n  HSA_EXTENSION_AMD_PROFILER = 0x200,\n  /**\n   * Loader extension.\n   */\n  HSA_EXTENSION_AMD_LOADER = 0x201,\n  /**\n   * AqlProfile extension.\n   */\n  HSA_EXTENSION_AMD_AQLPROFILE = 0x202,\n  /**\n   * PC Sampling extension.\n   */\n  HSA_EXTENSION_AMD_PC_SAMPLING = 0x203,\n  /**\n   * Last AMD extension.\n   */\n  HSA_AMD_LAST_EXTENSION = 0x203\n} hsa_extension_t;\n\n/**\n * @brief Query the name of a given extension.\n *\n * @param[in] extension Extension identifier. If the extension is not supported\n * by the implementation (see ::HSA_SYSTEM_INFO_EXTENSIONS), the behavior\n * is undefined.\n *\n * @param[out] name Pointer to a memory location where the HSA runtime stores\n * the extension name. The extension name is a NUL-terminated string.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p name is NULL.\n */\nhsa_status_t HSA_API hsa_extension_get_name(\n    uint16_t extension,\n    const char **name);\n\n/**\n * @deprecated\n *\n * @brief Query if a given version of an extension is supported by the HSA\n * implementation.\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] version_major Major version number.\n *\n * @param[in] version_minor Minor version number.\n *\n * @param[out] result Pointer to a memory location where the HSA runtime stores\n * the result of the check. The result is true if the specified version of the\n * extension is supported, and false otherwise.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p result is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_system_extension_supported(\n    uint16_t extension,\n    uint16_t version_major,\n    uint16_t version_minor,\n    bool* result);\n\n/**\n * @brief Query if a given version of an extension is supported by the HSA\n * implementation. All minor versions from 0 up to the returned @p version_minor\n * must be supported by the implementation.\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] version_major Major version number.\n *\n * @param[out] version_minor Minor version number.\n *\n * @param[out] result Pointer to a memory location where the HSA runtime stores\n * the result of the check. The result is true if the specified version of the\n * extension is supported, and false otherwise.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p version_minor is NULL, or @p result is NULL.\n */\nhsa_status_t HSA_API hsa_system_major_extension_supported(\n    uint16_t extension,\n    uint16_t version_major,\n    uint16_t *version_minor,\n    bool* result);\n\n\n/**\n * @deprecated\n *\n * @brief Retrieve the function pointers corresponding to a given version of an\n * extension. Portable applications are expected to invoke the extension API\n * using the returned function pointers\n *\n * @details The application is responsible for verifying that the given version\n * of the extension is supported by the HSA implementation (see\n * ::hsa_system_extension_supported). If the given combination of extension,\n * major version, and minor version is not supported by the implementation, the\n * behavior is undefined.\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] version_major Major version number for which to retrieve the\n * function pointer table.\n *\n * @param[in] version_minor Minor version number for which to retrieve the\n * function pointer table.\n *\n * @param[out] table Pointer to an application-allocated function pointer table\n * that is populated by the HSA runtime. Must not be NULL. The memory associated\n * with table can be reused or freed after the function returns.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p table is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_system_get_extension_table(\n    uint16_t extension,\n    uint16_t version_major,\n    uint16_t version_minor,\n    void *table);\n\n/**\n * @brief Retrieve the function pointers corresponding to a given major version\n * of an extension. Portable applications are expected to invoke the extension\n * API using the returned function pointers.\n *\n * @details The application is responsible for verifying that the given major\n * version of the extension is supported by the HSA implementation (see\n * ::hsa_system_major_extension_supported). If the given combination of extension\n * and major version is not supported by the implementation, the behavior is\n * undefined. Additionally if the length doesn't allow space for a full minor\n * version, it is implementation defined if only some of the function pointers for\n * that minor version get written.\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] version_major Major version number for which to retrieve the\n * function pointer table.\n *\n * @param[in] table_length Size in bytes of the function pointer table to be\n * populated. The implementation will not write more than this many bytes to the\n * table.\n *\n * @param[out] table Pointer to an application-allocated function pointer table\n * that is populated by the HSA runtime. Must not be NULL. The memory associated\n * with table can be reused or freed after the function returns.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p table is NULL.\n */\nhsa_status_t HSA_API hsa_system_get_major_extension_table(\n    uint16_t extension,\n    uint16_t version_major,\n    size_t table_length,\n    void *table);\n\n/**\n * @brief Struct containing an opaque handle to an agent, a device that participates in\n * the HSA memory model. An agent can submit AQL packets for execution, and\n * may also accept AQL packets for execution (agent dispatch packets or kernel\n * dispatch packets launching HSAIL-derived binaries).\n */\ntypedef struct hsa_agent_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_agent_t;\n\n/**\n * @brief Agent features.\n */\ntypedef enum {\n    /**\n     * The agent supports AQL packets of kernel dispatch type. If this\n     * feature is enabled, the agent is also a kernel agent.\n     */\n    HSA_AGENT_FEATURE_KERNEL_DISPATCH = 1,\n    /**\n     * The agent supports AQL packets of agent dispatch type.\n     */\n    HSA_AGENT_FEATURE_AGENT_DISPATCH = 2\n} hsa_agent_feature_t;\n\n/**\n * @brief Hardware device type.\n */\ntypedef enum {\n  /**\n   * CPU device.\n   */\n  HSA_DEVICE_TYPE_CPU = 0,\n  /**\n   * GPU device.\n   */\n  HSA_DEVICE_TYPE_GPU = 1,\n  /**\n   * DSP device.\n   */\n  HSA_DEVICE_TYPE_DSP = 2,\n  /**\n   * AI Engine (AIE) device.\n   */\n  HSA_DEVICE_TYPE_AIE = 3\n} hsa_device_type_t;\n\n/**\n * @brief Default floating-point rounding mode.\n */\ntypedef enum {\n  /**\n   * Use a default floating-point rounding mode specified elsewhere.\n   */\n  HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT = 0,\n  /**\n   * Operations that specify the default floating-point mode are rounded to zero\n   * by default.\n   */\n  HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO = 1,\n  /**\n   * Operations that specify the default floating-point mode are rounded to the\n   * nearest representable number and that ties should be broken by selecting\n   * the value with an even least significant bit.\n   */\n  HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR = 2\n} hsa_default_float_rounding_mode_t;\n\n/**\n * @brief Agent attributes.\n */\ntypedef enum {\n  /**\n   * Agent name. The type of this attribute is a NUL-terminated char[64]. The\n   * name must be at most 63 characters long (not including the NUL terminator)\n   * and all array elements not used for the name must be NUL.\n   */\n  HSA_AGENT_INFO_NAME = 0,\n  /**\n   * Name of vendor. The type of this attribute is a NUL-terminated char[64].\n   * The name must be at most 63 characters long (not including the NUL\n   * terminator) and all array elements not used for the name must be NUL.\n   */\n  HSA_AGENT_INFO_VENDOR_NAME = 1,\n  /**\n   * Agent capability. The type of this attribute is ::hsa_agent_feature_t.\n   */\n  HSA_AGENT_INFO_FEATURE = 2,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_MACHINE_MODELS for a given intruction set\n   * architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Machine model supported by the agent. The type of this attribute is\n   * ::hsa_machine_model_t.\n   */\n  HSA_AGENT_INFO_MACHINE_MODEL = 3,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_PROFILES for a given intruction set\n   * architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Profile supported by the agent. The type of this attribute is\n   * ::hsa_profile_t.\n   */\n  HSA_AGENT_INFO_PROFILE = 4,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_DEFAULT_FLOAT_ROUNDING_MODES for a given\n   * intruction set architecture supported by the agent instead.  If more than\n   * one ISA is supported by the agent, the returned value corresponds to the\n   * first ISA enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Default floating-point rounding mode. The type of this attribute is\n   * ::hsa_default_float_rounding_mode_t, but the value\n   * ::HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT is not allowed.\n   */\n  HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE = 5,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES\n   * for a given intruction set architecture supported by the agent instead.  If\n   * more than one ISA is supported by the agent, the returned value corresponds\n   * to the first ISA enumerated by ::hsa_agent_iterate_isas.\n   *\n   * A bit-mask of ::hsa_default_float_rounding_mode_t values, representing the\n   * default floating-point rounding modes supported by the agent in the Base\n   * profile. The type of this attribute is uint32_t. The default floating-point\n   * rounding mode (::HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE) bit must not\n   * be set.\n   */\n  HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES = 23,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_FAST_F16_OPERATION for a given intruction\n   * set architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Flag indicating that the f16 HSAIL operation is at least as fast as the\n   * f32 operation in the current agent. The value of this attribute is\n   * undefined if the agent is not a kernel agent. The type of this\n   * attribute is bool.\n   */\n  HSA_AGENT_INFO_FAST_F16_OPERATION = 24,\n  /**\n   * @deprecated Query ::HSA_WAVEFRONT_INFO_SIZE for a given wavefront and\n   * intruction set architecture supported by the agent instead.  If more than\n   * one ISA is supported by the agent, the returned value corresponds to the\n   * first ISA enumerated by ::hsa_agent_iterate_isas and the first wavefront\n   * enumerated by ::hsa_isa_iterate_wavefronts for that ISA.\n   *\n   * Number of work-items in a wavefront. Must be a power of 2 in the range\n   * [1,256]. The value of this attribute is undefined if the agent is not\n   * a kernel agent. The type of this attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_WAVEFRONT_SIZE = 6,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_WORKGROUP_MAX_DIM for a given intruction\n   * set architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Maximum number of work-items of each dimension of a work-group.  Each\n   * maximum must be greater than 0. No maximum can exceed the value of\n   * ::HSA_AGENT_INFO_WORKGROUP_MAX_SIZE. The value of this attribute is\n   * undefined if the agent is not a kernel agent. The type of this\n   * attribute is uint16_t[3].\n   */\n  HSA_AGENT_INFO_WORKGROUP_MAX_DIM = 7,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_WORKGROUP_MAX_SIZE for a given intruction\n   * set architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Maximum total number of work-items in a work-group. The value of this\n   * attribute is undefined if the agent is not a kernel agent. The type\n   * of this attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_WORKGROUP_MAX_SIZE = 8,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_GRID_MAX_DIM for a given intruction set\n   * architecture supported by the agent instead.\n   *\n   * Maximum number of work-items of each dimension of a grid. Each maximum must\n   * be greater than 0, and must not be smaller than the corresponding value in\n   * ::HSA_AGENT_INFO_WORKGROUP_MAX_DIM. No maximum can exceed the value of\n   * ::HSA_AGENT_INFO_GRID_MAX_SIZE. The value of this attribute is undefined\n   * if the agent is not a kernel agent. The type of this attribute is\n   * ::hsa_dim3_t.\n   */\n  HSA_AGENT_INFO_GRID_MAX_DIM = 9,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_GRID_MAX_SIZE for a given intruction set\n   * architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Maximum total number of work-items in a grid. The value of this attribute\n   * is undefined if the agent is not a kernel agent. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_GRID_MAX_SIZE = 10,\n  /**\n   * @deprecated Query ::HSA_ISA_INFO_FBARRIER_MAX_SIZE for a given intruction\n   * set architecture supported by the agent instead.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Maximum number of fbarriers per work-group. Must be at least 32. The value\n   * of this attribute is undefined if the agent is not a kernel agent. The\n   * type of this attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_FBARRIER_MAX_SIZE = 11,\n  /**\n   * @deprecated The maximum number of queues is not statically determined.\n   *\n   * Maximum number of queues that can be active (created but not destroyed) at\n   * one time in the agent. The type of this attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_QUEUES_MAX = 12,\n  /**\n   * Minimum number of packets that a queue created in the agent\n   * can hold. Must be a power of 2 greater than 0. Must not exceed\n   * the value of ::HSA_AGENT_INFO_QUEUE_MAX_SIZE. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_QUEUE_MIN_SIZE = 13,\n  /**\n   * Maximum number of packets that a queue created in the agent can\n   * hold. Must be a power of 2 greater than 0. The type of this attribute\n   * is uint32_t.\n   */\n  HSA_AGENT_INFO_QUEUE_MAX_SIZE = 14,\n  /**\n   * Type of a queue created in the agent. The type of this attribute is\n   * ::hsa_queue_type32_t.\n   */\n  HSA_AGENT_INFO_QUEUE_TYPE = 15,\n  /**\n   * @deprecated NUMA information is not exposed anywhere else in the API.\n   *\n   * Identifier of the NUMA node associated with the agent. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AGENT_INFO_NODE = 16,\n  /**\n   * Type of hardware device associated with the agent. The type of this\n   * attribute is ::hsa_device_type_t.\n   */\n  HSA_AGENT_INFO_DEVICE = 17,\n  /**\n   * @deprecated Query ::hsa_agent_iterate_caches to retrieve information about\n   * the caches present in a given agent.\n   *\n   * Array of data cache sizes (L1..L4). Each size is expressed in bytes. A size\n   * of 0 for a particular level indicates that there is no cache information\n   * for that level. The type of this attribute is uint32_t[4].\n   */\n  HSA_AGENT_INFO_CACHE_SIZE = 18,\n  /**\n   * @deprecated An agent may support multiple instruction set\n   * architectures. See ::hsa_agent_iterate_isas.  If more than one ISA is\n   * supported by the agent, the returned value corresponds to the first ISA\n   * enumerated by ::hsa_agent_iterate_isas.\n   *\n   * Instruction set architecture of the agent. The type of this attribute\n   * is ::hsa_isa_t.\n   */\n  HSA_AGENT_INFO_ISA = 19,\n  /**\n   * Bit-mask indicating which extensions are supported by the agent. An\n   * extension with an ID of @p i is supported if the bit at position @p i is\n   * set. The type of this attribute is uint8_t[128].\n   */\n  HSA_AGENT_INFO_EXTENSIONS = 20,\n  /**\n   * Major version of the HSA runtime specification supported by the\n   * agent. The type of this attribute is uint16_t.\n   */\n  HSA_AGENT_INFO_VERSION_MAJOR = 21,\n  /**\n   * Minor version of the HSA runtime specification supported by the\n   * agent. The type of this attribute is uint16_t.\n   */\n  HSA_AGENT_INFO_VERSION_MINOR = 22,\n  /**\n   * This enum does not have a fixed underlying type, thus in C++ post D2338:\n   * If the enumeration type does not have a fixed underlying type, the value is\n   * unchanged if the original value is within the range of the enumeration\n   * values (9.7.1 [dcl.enum]), and otherwise, the behavior is\n   * undefined.\n   * Thus increase the range of this enum to encompass vendor extensions.\n   */\n  HSA_AGENT_INFO_LAST = INT32_MAX\n} hsa_agent_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given agent.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * agent attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_agent_get_info(\n    hsa_agent_t agent,\n    hsa_agent_info_t attribute,\n    void* value);\n\n/**\n * @brief Iterate over the available agents, and invoke an\n * application-defined callback on every iteration.\n *\n * @param[in] callback Callback to be invoked once per agent. The HSA\n * runtime passes two arguments to the callback: the agent and the\n * application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_iterate_agents returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n*/\nhsa_status_t HSA_API hsa_iterate_agents(\n    hsa_status_t (*callback)(hsa_agent_t agent, void* data),\n    void* data);\n\n/*\n\n// If we do not know the size of an attribute, we need to query it first\n// Note: this API will not be in the spec unless needed\nhsa_status_t HSA_API hsa_agent_get_info_size(\n    hsa_agent_t agent,\n    hsa_agent_info_t attribute,\n    size_t* size);\n\n// Set the value of an agents attribute\n// Note: this API will not be in the spec unless needed\nhsa_status_t HSA_API hsa_agent_set_info(\n    hsa_agent_t agent,\n    hsa_agent_info_t attribute,\n    void* value);\n\n*/\n\n/**\n * @brief Exception policies applied in the presence of hardware exceptions.\n */\ntypedef enum {\n    /**\n     * If a hardware exception is detected, a work-item signals an exception.\n     */\n    HSA_EXCEPTION_POLICY_BREAK = 1,\n    /**\n     * If a hardware exception is detected, a hardware status bit is set.\n     */\n    HSA_EXCEPTION_POLICY_DETECT = 2\n} hsa_exception_policy_t;\n\n/**\n * @deprecated Use ::hsa_isa_get_exception_policies for a given intruction set\n * architecture supported by the agent instead. If more than one ISA is\n * supported by the agent, this function uses the first value returned by\n * ::hsa_agent_iterate_isas.\n *\n * @brief Retrieve the exception policy support for a given combination of\n * agent and profile\n *\n * @param[in] agent Agent.\n *\n * @param[in] profile Profile.\n *\n * @param[out] mask Pointer to a memory location where the HSA runtime stores a\n * mask of ::hsa_exception_policy_t values. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p profile is not a valid\n * profile, or @p mask is NULL.\n *\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_agent_get_exception_policies(\n    hsa_agent_t agent,\n    hsa_profile_t profile,\n    uint16_t *mask);\n\n/**\n * @brief Cache handle.\n */\ntypedef struct hsa_cache_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_cache_t;\n\n/**\n * @brief Cache attributes.\n */\ntypedef enum {\n  /**\n   * The length of the cache name in bytes, not including the NUL terminator.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_CACHE_INFO_NAME_LENGTH = 0,\n  /**\n   * Human-readable description.  The type of this attribute is a NUL-terminated\n   * character array with the length equal to the value of\n   * ::HSA_CACHE_INFO_NAME_LENGTH attribute.\n   */\n  HSA_CACHE_INFO_NAME = 1,\n  /**\n   * Cache level. A L1 cache must return a value of 1, a L2 must return a value\n   * of 2, and so on.  The type of this attribute is uint8_t.\n   */\n  HSA_CACHE_INFO_LEVEL = 2,\n  /**\n   * Cache size, in bytes. A value of 0 indicates that there is no size\n   * information available. The type of this attribute is uint32_t.\n   */\n  HSA_CACHE_INFO_SIZE = 3\n} hsa_cache_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given cache object.\n *\n * @param[in] cache Cache.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CACHE The cache is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * instruction set architecture attribute, or @p value is\n * NULL.\n */\nhsa_status_t HSA_API hsa_cache_get_info(\n    hsa_cache_t cache,\n    hsa_cache_info_t attribute,\n    void* value);\n\n/**\n * @brief Iterate over the memory caches of a given agent, and\n * invoke an application-defined callback on every iteration.\n *\n * @details Caches are visited in ascending order according to the value of the\n * ::HSA_CACHE_INFO_LEVEL attribute.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] callback Callback to be invoked once per cache that is present in\n * the agent.  The HSA runtime passes two arguments to the callback: the cache\n * and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * that value is returned.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_agent_iterate_caches(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_cache_t cache, void* data),\n    void* data);\n\n/**\n * @deprecated\n *\n * @brief Query if a given version of an extension is supported by an agent\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] agent Agent.\n *\n * @param[in] version_major Major version number.\n *\n * @param[in] version_minor Minor version number.\n *\n * @param[out] result Pointer to a memory location where the HSA runtime stores\n * the result of the check. The result is true if the specified version of the\n * extension is supported, and false otherwise. The result must be false if\n * ::hsa_system_extension_supported returns false for the same extension\n * version.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p result is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_agent_extension_supported(\n    uint16_t extension,\n    hsa_agent_t agent,\n    uint16_t version_major,\n    uint16_t version_minor,\n    bool* result);\n\n/**\n * @brief Query if a given version of an extension is supported by an agent. All\n * minor versions from 0 up to the returned @p version_minor must be supported.\n *\n * @param[in] extension Extension identifier.\n *\n * @param[in] agent Agent.\n *\n * @param[in] version_major Major version number.\n *\n * @param[out] version_minor Minor version number.\n *\n * @param[out] result Pointer to a memory location where the HSA runtime stores\n * the result of the check. The result is true if the specified version of the\n * extension is supported, and false otherwise. The result must be false if\n * ::hsa_system_extension_supported returns false for the same extension\n * version.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p extension is not a valid\n * extension, or @p version_minor is NULL, or @p result is NULL.\n */\nhsa_status_t HSA_API hsa_agent_major_extension_supported(\n    uint16_t extension,\n    hsa_agent_t agent,\n    uint16_t version_major,\n    uint16_t *version_minor,\n    bool* result);\n\n\n/** @} */\n\n\n/** \\defgroup signals Signals\n *  @{\n */\n\n/**\n * @brief Signal handle.\n */\ntypedef struct hsa_signal_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal. The value 0 is reserved.\n   */\n  uint64_t handle;\n} hsa_signal_t;\n\n/**\n * @brief Signal value. The value occupies 32 bits in small machine mode, and 64\n * bits in large machine mode.\n */\n#ifdef HSA_LARGE_MODEL\n  typedef int64_t hsa_signal_value_t;\n#else\n  typedef int32_t hsa_signal_value_t;\n#endif\n\n/**\n * @brief Create a signal.\n *\n * @param[in] initial_value Initial value of the signal.\n *\n * @param[in] num_consumers Size of @p consumers. A value of 0 indicates that\n * any agent might wait on the signal.\n *\n * @param[in] consumers List of agents that might consume (wait on) the\n * signal. If @p num_consumers is 0, this argument is ignored; otherwise, the\n * HSA runtime might use the list to optimize the handling of the signal\n * object. If an agent not listed in @p consumers waits on the returned\n * signal, the behavior is undefined. The memory associated with @p consumers\n * can be reused or freed after the function returns.\n *\n * @param[out] signal Pointer to a memory location where the HSA runtime will\n * store the newly created signal handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p signal is NULL, @p\n * num_consumers is greater than 0 but @p consumers is NULL, or @p consumers\n * contains duplicates.\n */\nhsa_status_t HSA_API hsa_signal_create(\n    hsa_signal_value_t initial_value,\n    uint32_t num_consumers,\n    const hsa_agent_t *consumers,\n    hsa_signal_t *signal);\n\n/**\n * @brief Destroy a signal previous created by ::hsa_signal_create.\n *\n * @param[in] signal Signal.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL @p signal is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT The handle in @p signal is 0.\n */\nhsa_status_t HSA_API hsa_signal_destroy(\n    hsa_signal_t signal);\n\n/**\n * @brief Atomically read the current value of a signal.\n *\n * @param[in] signal Signal.\n *\n * @return Value of the signal.\n*/\nhsa_signal_value_t HSA_API hsa_signal_load_scacquire(\n    hsa_signal_t signal);\n\n/**\n * @copydoc hsa_signal_load_scacquire\n */\nhsa_signal_value_t HSA_API hsa_signal_load_relaxed(\n    hsa_signal_t signal);\n\n/**\n * @deprecated Renamed as ::hsa_signal_load_scacquire.\n *\n * @copydoc hsa_signal_load_scacquire\n*/\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_load_acquire(\n    hsa_signal_t signal);\n\n/**\n * @brief Atomically set the value of a signal.\n *\n * @details If the value of the signal is changed, all the agents waiting\n * on @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal.\n *\n * @param[in] value New signal value.\n */\nvoid HSA_API hsa_signal_store_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_store_relaxed\n */\nvoid HSA_API hsa_signal_store_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_store_screlease.\n *\n * @copydoc hsa_signal_store_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_store_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically set the value of a signal without necessarily notifying the\n * the agents waiting on it.\n *\n * @details The agents waiting on @p signal may not wake up even when the new\n * value satisfies their wait condition. If the application wants to update the\n * signal and there is no need to notify any agent, invoking this function can\n * be more efficient than calling the non-silent counterpart.\n *\n * @param[in] signal Signal.\n *\n * @param[in] value New signal value.\n */\nvoid HSA_API hsa_signal_silent_store_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_silent_store_relaxed\n */\nvoid HSA_API hsa_signal_silent_store_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically set the value of a signal and return its previous value.\n *\n * @details If the value of the signal is changed, all the agents waiting\n * on @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value New value.\n *\n * @return Value of the signal prior to the exchange.\n *\n */\nhsa_signal_value_t HSA_API hsa_signal_exchange_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_exchange_scacq_screl.\n *\n * @copydoc hsa_signal_exchange_scacq_screl\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_exchange_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_exchange_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_exchange_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_exchange_scacquire.\n *\n * @copydoc hsa_signal_exchange_scacquire\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_exchange_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_exchange_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_exchange_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n/**\n * @copydoc hsa_signal_exchange_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_exchange_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_exchange_screlease.\n *\n * @copydoc hsa_signal_exchange_screlease\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_exchange_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically set the value of a signal if the observed value is equal to\n * the expected value. The observed value is returned regardless of whether the\n * replacement was done.\n *\n * @details If the value of the signal is changed, all the agents waiting\n * on @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue\n * doorbell signal, the behavior is undefined.\n *\n * @param[in] expected Value to compare with.\n *\n * @param[in] value New value.\n *\n * @return Observed value of the signal.\n *\n */\nhsa_signal_value_t HSA_API hsa_signal_cas_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_cas_scacq_screl.\n *\n * @copydoc hsa_signal_cas_scacq_screl\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_cas_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_cas_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_cas_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_cas_scacquire.\n *\n * @copydoc hsa_signal_cas_scacquire\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_cas_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_cas_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_cas_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_cas_scacq_screl\n */\nhsa_signal_value_t HSA_API hsa_signal_cas_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_cas_screlease.\n *\n * @copydoc hsa_signal_cas_screlease\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_cas_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t expected,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically increment the value of a signal by a given amount.\n *\n * @details If the value of the signal is changed, all the agents waiting on\n * @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value Value to add to the value of the signal.\n *\n */\nvoid HSA_API hsa_signal_add_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_add_scacq_screl.\n *\n * @copydoc hsa_signal_add_scacq_screl\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_add_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_add_scacq_screl\n */\nvoid HSA_API hsa_signal_add_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_add_scacquire.\n *\n * @copydoc hsa_signal_add_scacquire\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_add_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_add_scacq_screl\n */\nvoid HSA_API hsa_signal_add_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_add_scacq_screl\n */\nvoid HSA_API hsa_signal_add_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_add_screlease.\n *\n * @copydoc hsa_signal_add_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_add_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically decrement the value of a signal by a given amount.\n *\n * @details If the value of the signal is changed, all the agents waiting on\n * @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value Value to subtract from the value of the signal.\n *\n */\nvoid HSA_API hsa_signal_subtract_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_subtract_scacq_screl.\n *\n * @copydoc hsa_signal_subtract_scacq_screl\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_subtract_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_subtract_scacq_screl\n */\nvoid HSA_API hsa_signal_subtract_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_subtract_scacquire.\n *\n * @copydoc hsa_signal_subtract_scacquire\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_subtract_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_subtract_scacq_screl\n */\nvoid HSA_API hsa_signal_subtract_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_subtract_scacq_screl\n */\nvoid HSA_API hsa_signal_subtract_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_subtract_screlease.\n *\n * @copydoc hsa_signal_subtract_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_subtract_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically perform a bitwise AND operation between the value of a\n * signal and a given value.\n *\n * @details If the value of the signal is changed, all the agents waiting on\n * @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value Value to AND with the value of the signal.\n *\n */\nvoid HSA_API hsa_signal_and_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_and_scacq_screl.\n *\n * @copydoc hsa_signal_and_scacq_screl\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_and_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_and_scacq_screl\n */\nvoid HSA_API hsa_signal_and_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_and_scacquire.\n *\n * @copydoc hsa_signal_and_scacquire\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_and_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_and_scacq_screl\n */\nvoid HSA_API hsa_signal_and_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_and_scacq_screl\n */\nvoid HSA_API hsa_signal_and_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_and_screlease.\n *\n * @copydoc hsa_signal_and_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_and_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically perform a bitwise OR operation between the value of a\n * signal and a given value.\n *\n * @details If the value of the signal is changed, all the agents waiting on\n * @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value Value to OR with the value of the signal.\n */\nvoid HSA_API hsa_signal_or_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_or_scacq_screl.\n *\n * @copydoc hsa_signal_or_scacq_screl\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_or_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_or_scacq_screl\n */\nvoid HSA_API hsa_signal_or_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_or_scacquire.\n *\n * @copydoc hsa_signal_or_scacquire\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_or_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_or_scacq_screl\n */\nvoid HSA_API hsa_signal_or_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_or_scacq_screl\n */\nvoid HSA_API hsa_signal_or_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_or_screlease.\n *\n * @copydoc hsa_signal_or_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_or_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Atomically perform a bitwise XOR operation between the value of a\n * signal and a given value.\n *\n * @details If the value of the signal is changed, all the agents waiting on\n * @p signal for which @p value satisfies their wait condition are awakened.\n *\n * @param[in] signal Signal. If @p signal is a queue doorbell signal, the\n * behavior is undefined.\n *\n * @param[in] value Value to XOR with the value of the signal.\n *\n */\nvoid HSA_API hsa_signal_xor_scacq_screl(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n\n/**\n * @deprecated Renamed as ::hsa_signal_xor_scacq_screl.\n *\n * @copydoc hsa_signal_xor_scacq_screl\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_xor_acq_rel(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_xor_scacq_screl\n */\nvoid HSA_API hsa_signal_xor_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_xor_scacquire.\n *\n * @copydoc hsa_signal_xor_scacquire\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_xor_acquire(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_xor_scacq_screl\n */\nvoid HSA_API hsa_signal_xor_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @copydoc hsa_signal_xor_scacq_screl\n */\nvoid HSA_API hsa_signal_xor_screlease(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @deprecated Renamed as ::hsa_signal_xor_screlease.\n *\n * @copydoc hsa_signal_xor_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_signal_xor_release(\n    hsa_signal_t signal,\n    hsa_signal_value_t value);\n\n/**\n * @brief Wait condition operator.\n */\ntypedef enum {\n    /**\n     * The two operands are equal.\n     */\n    HSA_SIGNAL_CONDITION_EQ = 0,\n    /**\n     * The two operands are not equal.\n     */\n    HSA_SIGNAL_CONDITION_NE = 1,\n    /**\n     * The first operand is less than the second operand.\n     */\n    HSA_SIGNAL_CONDITION_LT = 2,\n    /**\n     * The first operand is greater than or equal to the second operand.\n     */\n    HSA_SIGNAL_CONDITION_GTE = 3\n} hsa_signal_condition_t;\n\n/**\n * @brief State of the application thread during a signal wait.\n */\ntypedef enum {\n    /**\n     * The application thread may be rescheduled while waiting on the signal.\n     */\n    HSA_WAIT_STATE_BLOCKED = 0,\n    /**\n     * The application thread stays active while waiting on a signal.\n     */\n    HSA_WAIT_STATE_ACTIVE = 1\n} hsa_wait_state_t;\n\n\n/**\n * @brief Wait until a signal value satisfies a specified condition, or a\n * certain amount of time has elapsed.\n *\n * @details A wait operation can spuriously resume at any time sooner than the\n * timeout (for example, due to system or other external factors) even when the\n * condition has not been met.\n *\n * The function is guaranteed to return if the signal value satisfies the\n * condition at some point in time during the wait, but the value returned to\n * the application might not satisfy the condition. The application must ensure\n * that signals are used in such way that wait wakeup conditions are not\n * invalidated before dependent threads have woken up.\n *\n * When the wait operation internally loads the value of the passed signal, it\n * uses the memory order indicated in the function name.\n *\n * @param[in] signal Signal.\n *\n * @param[in] condition Condition used to compare the signal value with @p\n * compare_value.\n *\n * @param[in] compare_value Value to compare with.\n *\n * @param[in] timeout_hint Maximum duration of the wait.  Specified in the same\n * unit as the system timestamp. The operation might block for a shorter or\n * longer time even if the condition is not met. A value of UINT64_MAX indicates\n * no maximum.\n *\n * @param[in] wait_state_hint Hint used by the application to indicate the\n * preferred waiting state. The actual waiting state is ultimately decided by\n * HSA runtime and may not match the provided hint. A value of\n * ::HSA_WAIT_STATE_ACTIVE may improve the latency of response to a signal\n * update by avoiding rescheduling overhead.\n *\n * @return Observed value of the signal, which might not satisfy the specified\n * condition.\n *\n*/\nhsa_signal_value_t HSA_API hsa_signal_wait_scacquire(\n    hsa_signal_t signal,\n    hsa_signal_condition_t condition,\n    hsa_signal_value_t compare_value,\n    uint64_t timeout_hint,\n    hsa_wait_state_t wait_state_hint);\n\n/**\n * @copydoc hsa_signal_wait_scacquire\n */\nhsa_signal_value_t HSA_API hsa_signal_wait_relaxed(\n    hsa_signal_t signal,\n    hsa_signal_condition_t condition,\n    hsa_signal_value_t compare_value,\n    uint64_t timeout_hint,\n    hsa_wait_state_t wait_state_hint);\n\n/**\n * @deprecated Renamed as ::hsa_signal_wait_scacquire.\n *\n * @copydoc hsa_signal_wait_scacquire\n */\nhsa_signal_value_t HSA_API HSA_DEPRECATED hsa_signal_wait_acquire(\n    hsa_signal_t signal,\n    hsa_signal_condition_t condition,\n    hsa_signal_value_t compare_value,\n    uint64_t timeout_hint,\n    hsa_wait_state_t wait_state_hint);\n\n/**\n * @brief Group of signals.\n */\ntypedef struct hsa_signal_group_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_signal_group_t;\n\n/**\n * @brief Create a signal group.\n *\n * @param[in] num_signals Number of elements in @p signals. Must not be 0.\n *\n * @param[in] signals List of signals in the group. The list must not contain\n * any repeated elements. Must not be NULL.\n *\n * @param[in] num_consumers Number of elements in @p consumers. Must not be 0.\n *\n * @param[in] consumers List of agents that might consume (wait on) the signal\n * group. The list must not contain repeated elements, and must be a subset of\n * the set of agents that are allowed to wait on all the signals in the\n * group. If an agent not listed in @p consumers waits on the returned group,\n * the behavior is undefined. The memory associated with @p consumers can be\n * reused or freed after the function returns. Must not be NULL.\n *\n * @param[out] signal_group Pointer to newly created signal group. Must not be\n * NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p num_signals is 0, @p signals\n * is NULL, @p num_consumers is 0, @p consumers is NULL, or @p signal_group is\n * NULL.\n */\nhsa_status_t HSA_API hsa_signal_group_create(\n    uint32_t num_signals,\n    const hsa_signal_t *signals,\n    uint32_t num_consumers,\n    const hsa_agent_t *consumers,\n    hsa_signal_group_t *signal_group);\n\n/**\n * @brief Destroy a signal group previous created by ::hsa_signal_group_create.\n *\n * @param[in] signal_group Signal group.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP @p signal_group is invalid.\n */\nhsa_status_t HSA_API hsa_signal_group_destroy(\n    hsa_signal_group_t signal_group);\n\n/**\n * @brief Wait until the value of at least one of the signals in a signal group\n * satisfies its associated condition.\n *\n * @details The function is guaranteed to return if the value of at least one of\n * the signals in the group satisfies its associated condition at some point in\n * time during the wait, but the signal value returned to the application may no\n * longer satisfy the condition. The application must ensure that signals in the\n * group are used in such way that wait wakeup conditions are not invalidated\n * before dependent threads have woken up.\n *\n * When this operation internally loads the value of the passed signal, it uses\n * the memory order indicated in the function name.\n *\n * @param[in] signal_group Signal group.\n *\n * @param[in] conditions List of conditions. Each condition, and the value at\n * the same index in @p compare_values, is used to compare the value of the\n * signal at that index in @p signal_group (the signal passed by the application\n * to ::hsa_signal_group_create at that particular index). The size of @p\n * conditions must not be smaller than the number of signals in @p signal_group;\n * any extra elements are ignored. Must not be NULL.\n *\n * @param[in] compare_values List of comparison values.  The size of @p\n * compare_values must not be smaller than the number of signals in @p\n * signal_group; any extra elements are ignored. Must not be NULL.\n *\n * @param[in] wait_state_hint Hint used by the application to indicate the\n * preferred waiting state. The actual waiting state is decided by the HSA runtime\n * and may not match the provided hint. A value of ::HSA_WAIT_STATE_ACTIVE may\n * improve the latency of response to a signal update by avoiding rescheduling\n * overhead.\n *\n * @param[out] signal Signal in the group that satisfied the associated\n * condition. If several signals satisfied their condition, the function can\n * return any of those signals. Must not be NULL.\n *\n * @param[out] value Observed value for @p signal, which might no longer satisfy\n * the specified condition. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL_GROUP @p signal_group is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p conditions is NULL, @p\n * compare_values is NULL, @p signal is NULL, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_signal_group_wait_any_scacquire(\n    hsa_signal_group_t signal_group,\n    const hsa_signal_condition_t *conditions,\n    const hsa_signal_value_t *compare_values,\n    hsa_wait_state_t wait_state_hint,\n    hsa_signal_t *signal,\n    hsa_signal_value_t *value);\n\n/**\n * @copydoc hsa_signal_group_wait_any_scacquire\n */\nhsa_status_t HSA_API hsa_signal_group_wait_any_relaxed(\n    hsa_signal_group_t signal_group,\n    const hsa_signal_condition_t *conditions,\n    const hsa_signal_value_t *compare_values,\n    hsa_wait_state_t wait_state_hint,\n    hsa_signal_t *signal,\n    hsa_signal_value_t *value);\n\n/** @} */\n\n/** \\defgroup memory Memory\n *  @{\n */\n\n/**\n * @brief A memory region represents a block of virtual memory with certain\n * properties. For example, the HSA runtime represents fine-grained memory in\n * the global segment using a region. A region might be associated with more\n * than one agent.\n */\ntypedef struct hsa_region_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_region_t;\n\n/** @} */\n\n\n/** \\defgroup queue Queues\n *  @{\n */\n\n/**\n * @brief Queue type. Intended to be used for dynamic queue protocol\n * determination.\n */\ntypedef enum {\n  /**\n   * Queue supports multiple producers. Use of multiproducer queue mechanics is\n   * required.\n   */\n  HSA_QUEUE_TYPE_MULTI = 0,\n  /**\n   * Queue only supports a single producer. In some scenarios, the application\n   * may want to limit the submission of AQL packets to a single agent. Queues\n   * that support a single producer may be more efficient than queues supporting\n   * multiple producers. Use of multiproducer queue mechanics is not supported.\n   */\n  HSA_QUEUE_TYPE_SINGLE = 1,\n  /**\n   * Queue supports multiple producers and cooperative dispatches. Cooperative\n   * dispatches are able to use GWS synchronization. Queues of this type may be\n   * limited in number. The runtime may return the same queue to serve multiple\n   * ::hsa_queue_create calls when this type is given. Callers must inspect the\n   * returned queue to discover queue size. Queues of this type are reference\n   * counted and require a matching number of ::hsa_queue_destroy calls to\n   * release. Use of multiproducer queue mechanics is required. See\n   * ::HSA_AMD_AGENT_INFO_COOPERATIVE_QUEUES to query agent support for this\n   * type.\n   */\n  HSA_QUEUE_TYPE_COOPERATIVE = 2\n} hsa_queue_type_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_queue_type_t constants.\n */\ntypedef uint32_t hsa_queue_type32_t;\n\n/**\n * @brief Queue features.\n */\ntypedef enum {\n  /**\n   * Queue supports kernel dispatch packets.\n   */\n  HSA_QUEUE_FEATURE_KERNEL_DISPATCH = 1,\n\n  /**\n   * Queue supports agent dispatch packets.\n   */\n  HSA_QUEUE_FEATURE_AGENT_DISPATCH = 2\n} hsa_queue_feature_t;\n\n/**\n * @brief User mode queue.\n *\n * @details The queue structure is read-only and allocated by the HSA runtime,\n * but agents can directly modify the contents of the buffer pointed by @a\n * base_address, or use HSA runtime APIs to access the doorbell signal.\n *\n */\ntypedef struct hsa_queue_s {\n  /**\n   * Queue type.\n   */\n  hsa_queue_type32_t type;\n\n  /**\n   * Queue features mask. This is a bit-field of ::hsa_queue_feature_t\n   * values. Applications should ignore any unknown set bits.\n   */\n  uint32_t features;\n\n#ifdef HSA_LARGE_MODEL\n  void* base_address;\n#elif defined HSA_LITTLE_ENDIAN\n  /**\n   * Starting address of the HSA runtime-allocated buffer used to store the AQL\n   * packets. Must be aligned to the size of an AQL packet.\n   */\n  void* base_address;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved0;\n#else\n  uint32_t reserved0;\n  void* base_address;\n#endif\n\n  /**\n   * Signal object used by the application to indicate the ID of a packet that\n   * is ready to be processed. The HSA runtime manages the doorbell signal. If\n   * the application tries to replace or destroy this signal, the behavior is\n   * undefined.\n   *\n   * If @a type is ::HSA_QUEUE_TYPE_SINGLE, the doorbell signal value must be\n   * updated in a monotonically increasing fashion. If @a type is\n   * ::HSA_QUEUE_TYPE_MULTI, the doorbell signal value can be updated with any\n   * value.\n   */\n  hsa_signal_t doorbell_signal;\n\n  /**\n   * Maximum number of packets the queue can hold. Must be a power of 2.\n   */\n  uint32_t size;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n  /**\n   * Queue identifier, which is unique over the lifetime of the application.\n   */\n  uint64_t id;\n\n} hsa_queue_t;\n\n/**\n * @brief Create a user mode queue.\n *\n * @details The HSA runtime creates the queue structure, the underlying packet\n * buffer, the completion signal, and the write and read indexes. The initial\n * value of the write and read indexes is 0. The type of every packet in the\n * buffer is initialized to ::HSA_PACKET_TYPE_INVALID.\n *\n * The application should only rely on the error code returned to determine if\n * the queue is valid.\n *\n * @param[in] agent Agent where to create the queue.\n *\n * @param[in] size Number of packets the queue is expected to\n * hold. Must be a power of 2 between 1 and the value of\n * ::HSA_AGENT_INFO_QUEUE_MAX_SIZE in @p agent. The size of the newly\n * created queue is the maximum of @p size and the value of\n * ::HSA_AGENT_INFO_QUEUE_MIN_SIZE in @p agent.\n *\n * @param[in] type Type of the queue, a bitwise OR of hsa_queue_type_t values.\n * If the value of ::HSA_AGENT_INFO_QUEUE_TYPE in @p agent is ::HSA_QUEUE_TYPE_SINGLE,\n * then @p type must also be ::HSA_QUEUE_TYPE_SINGLE.\n *\n * @param[in] callback Callback invoked by the HSA runtime for every\n * asynchronous event related to the newly created queue. May be NULL. The HSA\n * runtime passes three arguments to the callback: a code identifying the event\n * that triggered the invocation, a pointer to the queue where the event\n * originated, and the application data.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @param[in] private_segment_size Hint indicating the maximum\n * expected private segment usage per work-item, in bytes. There may\n * be performance degradation if the application places a kernel\n * dispatch packet in the queue and the corresponding private segment\n * usage exceeds @p private_segment_size. If the application does not\n * want to specify any particular value for this argument, @p\n * private_segment_size must be UINT32_MAX. If the queue does not\n * support kernel dispatch packets, this argument is ignored.\n *\n * @param[in] group_segment_size Hint indicating the maximum expected\n * group segment usage per work-group, in bytes. There may be\n * performance degradation if the application places a kernel dispatch\n * packet in the queue and the corresponding group segment usage\n * exceeds @p group_segment_size. If the application does not want to\n * specify any particular value for this argument, @p\n * group_segment_size must be UINT32_MAX. If the queue does not\n * support kernel dispatch packets, this argument is ignored.\n *\n * @param[out] queue Memory location where the HSA runtime stores a pointer to\n * the newly created queue.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE_CREATION @p agent does not\n * support queues of the given type.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p size is not a power of two,\n * @p size is 0, @p type is an invalid queue type, or @p queue is NULL.\n *\n */\nhsa_status_t HSA_API hsa_queue_create(\n    hsa_agent_t agent,\n    uint32_t size,\n    hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t *source, void *data),\n    void *data,\n    uint32_t private_segment_size,\n    uint32_t group_segment_size,\n    hsa_queue_t **queue);\n\n/**\n * @brief Create a queue for which the application or a kernel is responsible\n * for processing the AQL packets.\n *\n * @details The application can use this function to create queues where AQL\n * packets are not parsed by the packet processor associated with an agent,\n * but rather by a unit of execution running on that agent (for example, a\n * thread in the host application).\n *\n * The application is responsible for ensuring that all the producers and\n * consumers of the resulting queue can access the provided doorbell signal\n * and memory region. The application is also responsible for ensuring that the\n * unit of execution processing the queue packets supports the indicated\n * features (AQL packet types).\n *\n * When the queue is created, the HSA runtime allocates the packet buffer using\n * @p region, and the write and read indexes. The initial value of the write and\n * read indexes is 0, and the type of every packet in the buffer is initialized\n * to ::HSA_PACKET_TYPE_INVALID. The value of the @e size, @e type, @e features,\n * and @e doorbell_signal fields in the returned queue match the values passed\n * by the application.\n *\n * @param[in] region Memory region that the HSA runtime should use to allocate\n * the AQL packet buffer and any other queue metadata.\n *\n * @param[in] size Number of packets the queue is expected to hold. Must be a\n * power of 2 greater than 0.\n *\n * @param[in] type Queue type.\n *\n * @param[in] features Supported queue features. This is a bit-field of\n * ::hsa_queue_feature_t values.\n *\n * @param[in] doorbell_signal Doorbell signal that the HSA runtime must\n * associate with the returned queue. The signal handle must not be 0.\n *\n * @param[out] queue Memory location where the HSA runtime stores a pointer to\n * the newly created queue. The application should not rely on the value\n * returned for this argument but only in the status code to determine if the\n * queue is valid. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p size is not a power of two, @p\n * size is 0, @p type is an invalid queue type, the doorbell signal handle is\n * 0, or @p queue is NULL.\n *\n */\nhsa_status_t HSA_API hsa_soft_queue_create(\n    hsa_region_t region,\n    uint32_t size,\n    hsa_queue_type32_t type,\n    uint32_t features,\n    hsa_signal_t doorbell_signal,\n    hsa_queue_t **queue);\n\n/**\n * @brief Destroy a user mode queue.\n *\n * @details When a queue is destroyed, the state of the AQL packets that have\n * not been yet fully processed (their completion phase has not finished)\n * becomes undefined. It is the responsibility of the application to ensure that\n * all pending queue operations are finished if their results are required.\n *\n * The resources allocated by the HSA runtime during queue creation (queue\n * structure, ring buffer, doorbell signal) are released.  The queue should not\n * be accessed after being destroyed.\n *\n * @param[in] queue Pointer to a queue created using ::hsa_queue_create.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE The queue is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p queue is NULL.\n */\nhsa_status_t HSA_API hsa_queue_destroy(\n    hsa_queue_t *queue);\n\n/**\n * @brief Inactivate a queue.\n *\n * @details Inactivating the queue aborts any pending executions and prevent any\n * new packets from being processed. Any more packets written to the queue once\n * it is inactivated will be ignored by the packet processor.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE The queue is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p queue is NULL.\n */\nhsa_status_t HSA_API hsa_queue_inactivate(\n    hsa_queue_t *queue);\n\n/**\n * @deprecated Renamed as ::hsa_queue_load_read_index_scacquire.\n *\n * @copydoc hsa_queue_load_read_index_scacquire\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_load_read_index_acquire(\n    const hsa_queue_t *queue);\n\n/**\n * @brief Atomically load the read index of a queue.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @return Read index of the queue pointed by @p queue.\n */\nuint64_t HSA_API hsa_queue_load_read_index_scacquire(\n    const hsa_queue_t *queue);\n\n/**\n * @copydoc hsa_queue_load_read_index_scacquire\n */\nuint64_t HSA_API hsa_queue_load_read_index_relaxed(\n    const hsa_queue_t *queue);\n\n/**\n * @deprecated Renamed as ::hsa_queue_load_write_index_scacquire.\n *\n * @copydoc hsa_queue_load_write_index_scacquire\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_load_write_index_acquire(\n    const hsa_queue_t *queue);\n\n/**\n * @brief Atomically load the write index of a queue.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @return Write index of the queue pointed by @p queue.\n */\nuint64_t HSA_API hsa_queue_load_write_index_scacquire(\n    const hsa_queue_t *queue);\n\n/**\n * @copydoc hsa_queue_load_write_index_scacquire\n */\nuint64_t HSA_API hsa_queue_load_write_index_relaxed(\n    const hsa_queue_t *queue);\n\n/**\n * @brief Atomically set the write index of a queue.\n *\n * @details It is recommended that the application uses this function to update\n * the write index when there is a single agent submitting work to the queue\n * (the queue type is ::HSA_QUEUE_TYPE_SINGLE).\n *\n * @param[in] queue Pointer to a queue.\n *\n * @param[in] value Value to assign to the write index.\n *\n */\nvoid HSA_API hsa_queue_store_write_index_relaxed(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_store_write_index_screlease.\n *\n * @copydoc hsa_queue_store_write_index_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_queue_store_write_index_release(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_store_write_index_relaxed\n */\nvoid HSA_API hsa_queue_store_write_index_screlease(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_cas_write_index_scacq_screl.\n *\n * @copydoc hsa_queue_cas_write_index_scacq_screl\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_cas_write_index_acq_rel(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @brief Atomically set the write index of a queue if the observed value is\n * equal to the expected value. The application can inspect the returned value\n * to determine if the replacement was done.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @param[in] expected Expected value.\n *\n * @param[in] value Value to assign to the write index if @p expected matches\n * the observed write index. Must be greater than @p expected.\n *\n * @return Previous value of the write index.\n */\nuint64_t HSA_API hsa_queue_cas_write_index_scacq_screl(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_cas_write_index_scacquire.\n *\n * @copydoc hsa_queue_cas_write_index_scacquire\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_cas_write_index_acquire(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_cas_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_cas_write_index_scacquire(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_cas_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_cas_write_index_relaxed(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_cas_write_index_screlease.\n *\n * @copydoc hsa_queue_cas_write_index_screlease\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_cas_write_index_release(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_cas_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_cas_write_index_screlease(\n    const hsa_queue_t *queue,\n    uint64_t expected,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_add_write_index_scacq_screl.\n *\n * @copydoc hsa_queue_add_write_index_scacq_screl\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_add_write_index_acq_rel(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @brief Atomically increment the write index of a queue by an offset.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @param[in] value Value to add to the write index.\n *\n * @return Previous value of the write index.\n */\nuint64_t HSA_API hsa_queue_add_write_index_scacq_screl(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_add_write_index_scacquire.\n *\n * @copydoc hsa_queue_add_write_index_scacquire\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_add_write_index_acquire(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_add_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_add_write_index_scacquire(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_add_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_add_write_index_relaxed(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_add_write_index_screlease.\n *\n * @copydoc hsa_queue_add_write_index_screlease\n */\nuint64_t HSA_API HSA_DEPRECATED hsa_queue_add_write_index_release(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_add_write_index_scacq_screl\n */\nuint64_t HSA_API hsa_queue_add_write_index_screlease(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @brief Atomically set the read index of a queue.\n *\n * @details Modifications of the read index are not allowed and result in\n * undefined behavior if the queue is associated with an agent for which\n * only the corresponding packet processor is permitted to update the read\n * index.\n *\n * @param[in] queue Pointer to a queue.\n *\n * @param[in] value Value to assign to the read index.\n *\n */\nvoid HSA_API hsa_queue_store_read_index_relaxed(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @deprecated Renamed as ::hsa_queue_store_read_index_screlease.\n *\n * @copydoc hsa_queue_store_read_index_screlease\n */\nvoid HSA_API HSA_DEPRECATED hsa_queue_store_read_index_release(\n    const hsa_queue_t *queue,\n    uint64_t value);\n\n/**\n * @copydoc hsa_queue_store_read_index_relaxed\n */\nvoid HSA_API hsa_queue_store_read_index_screlease(\n   const hsa_queue_t *queue,\n   uint64_t value);\n/** @} */\n\n\n/** \\defgroup aql Architected Queuing Language\n *  @{\n */\n\n/**\n * @brief Packet type.\n */\ntypedef enum {\n  /**\n   * Vendor-specific packet.\n   */\n  HSA_PACKET_TYPE_VENDOR_SPECIFIC = 0,\n  /**\n   * The packet has been processed in the past, but has not been reassigned to\n   * the packet processor. A packet processor must not process a packet of this\n   * type. All queues support this packet type.\n   */\n  HSA_PACKET_TYPE_INVALID = 1,\n  /**\n   * Packet used by agents for dispatching jobs to kernel agents. Not all\n   * queues support packets of this type (see ::hsa_queue_feature_t).\n   */\n  HSA_PACKET_TYPE_KERNEL_DISPATCH = 2,\n  /**\n   * Packet used by agents to delay processing of subsequent packets, and to\n   * express complex dependencies between multiple packets. All queues support\n   * this packet type.\n   */\n  HSA_PACKET_TYPE_BARRIER_AND = 3,\n  /**\n   * Packet used by agents for dispatching jobs to agents.  Not all\n   * queues support packets of this type (see ::hsa_queue_feature_t).\n   */\n  HSA_PACKET_TYPE_AGENT_DISPATCH = 4,\n  /**\n   * Packet used by agents to delay processing of subsequent packets, and to\n   * express complex dependencies between multiple packets. All queues support\n   * this packet type.\n   */\n  HSA_PACKET_TYPE_BARRIER_OR = 5\n} hsa_packet_type_t;\n\n/**\n * @brief Scope of the memory fence operation associated with a packet.\n */\ntypedef enum {\n  /**\n   * No scope (no fence is applied). The packet relies on external fences to\n   * ensure visibility of memory updates.\n   */\n  HSA_FENCE_SCOPE_NONE = 0,\n  /**\n   * The fence is applied with agent scope for the global segment.\n   */\n  HSA_FENCE_SCOPE_AGENT = 1,\n  /**\n   * The fence is applied across both agent and system scope for the global\n   * segment.\n   */\n  HSA_FENCE_SCOPE_SYSTEM = 2\n} hsa_fence_scope_t;\n\n/**\n * @brief Sub-fields of the @a header field that is present in any AQL\n * packet. The offset (with respect to the address of @a header) of a sub-field\n * is identical to its enumeration constant. The width of each sub-field is\n * determined by the corresponding value in ::hsa_packet_header_width_t. The\n * offset and the width are expressed in bits.\n */\n typedef enum {\n  /**\n   * Packet type. The value of this sub-field must be one of\n   * ::hsa_packet_type_t. If the type is ::HSA_PACKET_TYPE_VENDOR_SPECIFIC, the\n   * packet layout is vendor-specific.\n   */\n   HSA_PACKET_HEADER_TYPE = 0,\n  /**\n   * Barrier bit. If the barrier bit is set, the processing of the current\n   * packet only launches when all preceding packets (within the same queue) are\n   * complete.\n   */\n   HSA_PACKET_HEADER_BARRIER = 8,\n  /**\n   * Acquire fence scope. The value of this sub-field determines the scope and\n   * type of the memory fence operation applied before the packet enters the\n   * active phase. An acquire fence ensures that any subsequent global segment\n   * or image loads by any unit of execution that belongs to a dispatch that has\n   * not yet entered the active phase on any queue of the same kernel agent,\n   * sees any data previously released at the scopes specified by the acquire\n   * fence. The value of this sub-field must be one of ::hsa_fence_scope_t.\n   */\n   HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE = 9,\n   /**\n    * @deprecated Renamed as ::HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE.\n    */\n   HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE = 9,\n  /**\n   * Release fence scope, The value of this sub-field determines the scope and\n   * type of the memory fence operation applied after kernel completion but\n   * before the packet is completed. A release fence makes any global segment or\n   * image data that was stored by any unit of execution that belonged to a\n   * dispatch that has completed the active phase on any queue of the same\n   * kernel agent visible in all the scopes specified by the release fence. The\n   * value of this sub-field must be one of ::hsa_fence_scope_t.\n   */\n   HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE = 11,\n   /**\n    * @deprecated Renamed as ::HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE.\n    */\n   HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE = 11\n } hsa_packet_header_t;\n\n/**\n * @brief Width (in bits) of the sub-fields in ::hsa_packet_header_t.\n */\n typedef enum {\n   HSA_PACKET_HEADER_WIDTH_TYPE = 8,\n   HSA_PACKET_HEADER_WIDTH_BARRIER = 1,\n   HSA_PACKET_HEADER_WIDTH_SCACQUIRE_FENCE_SCOPE = 2,\n   /**\n    * @deprecated Use HSA_PACKET_HEADER_WIDTH_SCACQUIRE_FENCE_SCOPE.\n    */\n   HSA_PACKET_HEADER_WIDTH_ACQUIRE_FENCE_SCOPE = 2,\n   HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE = 2,\n   /**\n    * @deprecated Use HSA_PACKET_HEADER_WIDTH_SCRELEASE_FENCE_SCOPE.\n    */\n   HSA_PACKET_HEADER_WIDTH_RELEASE_FENCE_SCOPE = 2\n } hsa_packet_header_width_t;\n\n/**\n * @brief Sub-fields of the kernel dispatch packet @a setup field. The offset\n * (with respect to the address of @a setup) of a sub-field is identical to its\n * enumeration constant. The width of each sub-field is determined by the\n * corresponding value in ::hsa_kernel_dispatch_packet_setup_width_t. The\n * offset and the width are expressed in bits.\n */\n typedef enum {\n  /**\n   * Number of dimensions of the grid. Valid values are 1, 2, or 3.\n   *\n   */\n   HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS = 0\n } hsa_kernel_dispatch_packet_setup_t;\n\n/**\n * @brief Width (in bits) of the sub-fields in\n * ::hsa_kernel_dispatch_packet_setup_t.\n */\n typedef enum {\n   HSA_KERNEL_DISPATCH_PACKET_SETUP_WIDTH_DIMENSIONS = 2\n } hsa_kernel_dispatch_packet_setup_width_t;\n\n/**\n * @brief AQL kernel dispatch packet\n */\ntypedef struct hsa_kernel_dispatch_packet_s {\n  union {\n    struct {\n        /**\n         * Packet header. Used to configure multiple packet parameters such as the\n         * packet type. The parameters are described by ::hsa_packet_header_t.\n         */\n        uint16_t header;\n\n        /**\n         * Dispatch setup parameters. Used to configure kernel dispatch parameters\n         * such as the number of dimensions in the grid. The parameters are described\n         * by ::hsa_kernel_dispatch_packet_setup_t.\n         */\n        uint16_t setup;\n    };\n    uint32_t full_header;\n  };\n\n  /**\n   * X dimension of work-group, in work-items. Must be greater than 0.\n   */\n  uint16_t workgroup_size_x;\n\n  /**\n   * Y dimension of work-group, in work-items. Must be greater than\n   * 0. If the grid has 1 dimension, the only valid value is 1.\n   */\n  uint16_t workgroup_size_y;\n\n  /**\n   * Z dimension of work-group, in work-items. Must be greater than\n   * 0. If the grid has 1 or 2 dimensions, the only valid value is 1.\n   */\n  uint16_t workgroup_size_z;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint16_t reserved0;\n\n  /**\n   * X dimension of grid, in work-items. Must be greater than 0. Must\n   * not be smaller than @a workgroup_size_x.\n   */\n  uint32_t grid_size_x;\n\n  /**\n   * Y dimension of grid, in work-items. Must be greater than 0. If the grid has\n   * 1 dimension, the only valid value is 1. Must not be smaller than @a\n   * workgroup_size_y.\n   */\n  uint32_t grid_size_y;\n\n  /**\n   * Z dimension of grid, in work-items. Must be greater than 0. If the grid has\n   * 1 or 2 dimensions, the only valid value is 1. Must not be smaller than @a\n   * workgroup_size_z.\n   */\n  uint32_t grid_size_z;\n\n  /**\n   * Size in bytes of private memory allocation request (per work-item).\n   */\n  uint32_t private_segment_size;\n\n  /**\n   * Size in bytes of group memory allocation request (per work-group). Must not\n   * be less than the sum of the group memory used by the kernel (and the\n   * functions it calls directly or indirectly) and the dynamically allocated\n   * group segment variables.\n   */\n  uint32_t group_segment_size;\n\n  /**\n   * Opaque handle to a code object that includes an implementation-defined\n   * executable code for the kernel.\n   */\n  uint64_t kernel_object;\n\n#ifdef HSA_LARGE_MODEL\n  void* kernarg_address;\n#elif defined HSA_LITTLE_ENDIAN\n  /**\n   * Pointer to a buffer containing the kernel arguments. May be NULL.\n   *\n   * The buffer must be allocated using ::hsa_memory_allocate, and must not be\n   * modified once the kernel dispatch packet is enqueued until the dispatch has\n   * completed execution.\n   */\n  void* kernarg_address;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n#else\n  uint32_t reserved1;\n  void* kernarg_address;\n#endif\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n\n  /**\n   * Signal used to indicate completion of the job. The application can use the\n   * special signal handle 0 to indicate that no signal is used.\n   */\n  hsa_signal_t completion_signal;\n\n} hsa_kernel_dispatch_packet_t;\n\n/**\n * @brief Agent dispatch packet.\n */\ntypedef struct hsa_agent_dispatch_packet_s {\n  /**\n   * Packet header. Used to configure multiple packet parameters such as the\n   * packet type. The parameters are described by ::hsa_packet_header_t.\n   */\n  uint16_t header;\n\n  /**\n   * Application-defined function to be performed by the destination agent.\n   */\n  uint16_t type;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved0;\n\n#ifdef HSA_LARGE_MODEL\n  void* return_address;\n#elif defined HSA_LITTLE_ENDIAN\n  /**\n   * Address where to store the function return values, if any.\n   */\n  void* return_address;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n#else\n  uint32_t reserved1;\n  void* return_address;\n#endif\n\n  /**\n   * Function arguments.\n   */\n  uint64_t arg[4];\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n\n  /**\n   * Signal used to indicate completion of the job. The application can use the\n   * special signal handle 0 to indicate that no signal is used.\n   */\n  hsa_signal_t completion_signal;\n\n} hsa_agent_dispatch_packet_t;\n\n/**\n * @brief Barrier-AND packet.\n */\ntypedef struct hsa_barrier_and_packet_s {\n  /**\n   * Packet header. Used to configure multiple packet parameters such as the\n   * packet type. The parameters are described by ::hsa_packet_header_t.\n   */\n  uint16_t header;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint16_t reserved0;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n\n  /**\n   * Array of dependent signal objects. Signals with a handle value of 0 are\n   * allowed and are interpreted by the packet processor as satisfied\n   * dependencies.\n   */\n  hsa_signal_t dep_signal[5];\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n\n  /**\n   * Signal used to indicate completion of the job. The application can use the\n   * special signal handle 0 to indicate that no signal is used.\n   */\n  hsa_signal_t completion_signal;\n\n} hsa_barrier_and_packet_t;\n\n/**\n * @brief Barrier-OR packet.\n */\ntypedef struct hsa_barrier_or_packet_s {\n  /**\n   * Packet header. Used to configure multiple packet parameters such as the\n   * packet type. The parameters are described by ::hsa_packet_header_t.\n   */\n  uint16_t header;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint16_t reserved0;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n\n  /**\n   * Array of dependent signal objects. Signals with a handle value of 0 are\n   * allowed and are interpreted by the packet processor as dependencies not\n   * satisfied.\n   */\n  hsa_signal_t dep_signal[5];\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n\n  /**\n   * Signal used to indicate completion of the job. The application can use the\n   * special signal handle 0 to indicate that no signal is used.\n   */\n  hsa_signal_t completion_signal;\n\n} hsa_barrier_or_packet_t;\n\n/** @} */\n\n/** \\addtogroup memory Memory\n *  @{\n */\n\n/**\n * @brief Memory segments associated with a region.\n */\ntypedef enum {\n  /**\n   * Global segment. Used to hold data that is shared by all agents.\n   */\n  HSA_REGION_SEGMENT_GLOBAL = 0,\n  /**\n   * Read-only segment. Used to hold data that remains constant during the\n   * execution of a kernel.\n   */\n  HSA_REGION_SEGMENT_READONLY = 1,\n  /**\n   * Private segment. Used to hold data that is local to a single work-item.\n   */\n  HSA_REGION_SEGMENT_PRIVATE = 2,\n  /**\n   * Group segment. Used to hold data that is shared by the work-items of a\n   * work-group.\n  */\n  HSA_REGION_SEGMENT_GROUP = 3,\n  /**\n   * Kernarg segment. Used to store kernel arguments.\n  */\n  HSA_REGION_SEGMENT_KERNARG = 4\n} hsa_region_segment_t;\n\n/**\n * @brief Global region flags.\n */\ntypedef enum {\n  /**\n   * The application can use memory in the region to store kernel arguments, and\n   * provide the values for the kernarg segment of a kernel dispatch. If this\n   * flag is set, then ::HSA_REGION_GLOBAL_FLAG_FINE_GRAINED must be set.\n   */\n  HSA_REGION_GLOBAL_FLAG_KERNARG = 1,\n  /**\n   * Updates to memory in this region are immediately visible to all the\n   * agents under the terms of the HSA memory model. If this\n   * flag is set, then ::HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED must not be set.\n   */\n  HSA_REGION_GLOBAL_FLAG_FINE_GRAINED = 2,\n  /**\n   * Updates to memory in this region can be performed by a single agent at\n   * a time. If a different agent in the system is allowed to access the\n   * region, the application must explicitely invoke ::hsa_memory_assign_agent\n   * in order to transfer ownership to that agent for a particular buffer.\n   */\n  HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED = 4,\n\n  /**\n   * Updates to memory in this region have extended scope, where the device-scope atomics\n   * to this memory type act as system-scope with respect to all variables located in\n   * memory regions of this type.\n   * Note: On non-compliant systems, the application may still be responsible for performing\n   * device-specific actions necessary to achieve system-scope coherence.\n   */\n  HSA_REGION_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED = 8\n} hsa_region_global_flag_t;\n\n/**\n * @brief Attributes of a memory region.\n */\n\n#ifdef __cplusplus\ntypedef enum : int {\n#else\ntypedef enum {\n#endif\n  /**\n   * Segment where memory in the region can be used. The type of this\n   * attribute is ::hsa_region_segment_t.\n   */\n  HSA_REGION_INFO_SEGMENT = 0,\n  /**\n   * Flag mask. The value of this attribute is undefined if the value of\n   * ::HSA_REGION_INFO_SEGMENT is not ::HSA_REGION_SEGMENT_GLOBAL. The type of\n   * this attribute is uint32_t, a bit-field of ::hsa_region_global_flag_t\n   * values.\n   */\n  HSA_REGION_INFO_GLOBAL_FLAGS = 1,\n  /**\n   * Size of this region, in bytes. The type of this attribute is size_t.\n   */\n  HSA_REGION_INFO_SIZE = 2,\n  /**\n   * Maximum allocation size in this region, in bytes. Must not exceed the value\n   * of ::HSA_REGION_INFO_SIZE. The type of this attribute is size_t.\n   *\n   * If the region is in the global or readonly segments, this is the maximum\n   * size that the application can pass to ::hsa_memory_allocate.\n   *\n   * If the region is in the group segment, this is the maximum size (per\n   * work-group) that can be requested for a given kernel dispatch. If the\n   * region is in the private segment, this is the maximum size (per work-item)\n   * that can be requested for a specific kernel dispatch, and must be at least\n   * 256 bytes.\n   */\n  HSA_REGION_INFO_ALLOC_MAX_SIZE = 4,\n  /**\n   * Maximum size (per work-group) of private memory that can be requested for a\n   * specific kernel dispatch. Must be at least 65536 bytes. The type of this\n   * attribute is uint32_t. The value of this attribute is undefined if the\n   * region is not in the private segment.\n   */\n  HSA_REGION_INFO_ALLOC_MAX_PRIVATE_WORKGROUP_SIZE = 8,\n  /**\n   * Indicates whether memory in this region can be allocated using\n   * ::hsa_memory_allocate. The type of this attribute is bool.\n   *\n   * The value of this flag is always false for regions in the group and private\n   * segments.\n   */\n  HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED = 5,\n  /**\n   * Allocation granularity of buffers allocated by ::hsa_memory_allocate in\n   * this region. The size of a buffer allocated in this region is a multiple of\n   * the value of this attribute. The value of this attribute is only defined if\n   * ::HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED is true for this region. The type\n   * of this attribute is size_t.\n   */\n  HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE = 6,\n  /**\n   * Alignment of buffers allocated by ::hsa_memory_allocate in this region. The\n   * value of this attribute is only defined if\n   * ::HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED is true for this region, and must be\n   * a power of 2. The type of this attribute is size_t.\n   */\n  HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT = 7\n} hsa_region_info_t;\n\n/**\n * @brief Get the current value of an attribute of a region.\n *\n * @param[in] region A valid region.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to a application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_REGION The region is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * region attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_region_get_info(\n    hsa_region_t region,\n    hsa_region_info_t attribute,\n    void* value);\n\n/**\n * @brief Iterate over the memory regions associated with a given agent, and\n * invoke an application-defined callback on every iteration.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] callback Callback to be invoked once per region that is\n * accessible from the agent.  The HSA runtime passes two arguments to the\n * callback, the region and the application data.  If @p callback returns a\n * status other than ::HSA_STATUS_SUCCESS for a particular iteration, the\n * traversal stops and ::hsa_agent_iterate_regions returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_agent_iterate_regions(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_region_t region, void* data),\n    void* data);\n\n/**\n * @brief Allocate a block of memory in a given region.\n *\n * @param[in] region Region where to allocate memory from. The region must have\n * the ::HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED flag set.\n *\n * @param[in] size Allocation size, in bytes. Must not be zero. This value is\n * rounded up to the nearest multiple of ::HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE\n * in @p region.\n *\n * @param[out] ptr Pointer to the location where to store the base address of\n * the allocated block. The returned base address is aligned to the value of\n * ::HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT in @p region. If the allocation\n * fails, the returned value is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_REGION The region is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION The host is not allowed to\n * allocate memory in @p region, or @p size is greater than the value of\n * HSA_REGION_INFO_ALLOC_MAX_SIZE in @p region.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr is NULL, or @p size is 0.\n */\nhsa_status_t HSA_API hsa_memory_allocate(hsa_region_t region,\n    size_t size,\n    void** ptr);\n\n/**\n * @brief Deallocate a block of memory previously allocated using\n * ::hsa_memory_allocate.\n *\n * @param[in] ptr Pointer to a memory block. If @p ptr does not match a value\n * previously returned by ::hsa_memory_allocate, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n */\nhsa_status_t HSA_API hsa_memory_free(void* ptr);\n\n/**\n * @brief Copy a block of memory from the location pointed to by @p src to the\n * memory block pointed to by @p dst.\n *\n * @param[out] dst Buffer where the content is to be copied. If @p dst is in\n * coarse-grained memory, the copied data is only visible to the agent currently\n * assigned (::hsa_memory_assign_agent) to @p dst.\n *\n * @param[in] src A valid pointer to the source of data to be copied. The source\n * buffer must not overlap with the destination buffer. If the source buffer is\n * in coarse-grained memory then it must be assigned to an agent, from which the\n * data will be retrieved.\n *\n * @param[in] size Number of bytes to copy. If @p size is 0, no copy is\n * performed and the function returns success. Copying a number of bytes larger\n * than the size of the buffers pointed by @p dst or @p src results in undefined\n * behavior.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT The source or destination\n * pointers are NULL.\n */\nhsa_status_t HSA_API hsa_memory_copy(\n    void *dst,\n    const void *src,\n    size_t size);\n\n/**\n * @brief Change the ownership of a global, coarse-grained buffer.\n *\n * @details The contents of a coarse-grained buffer are visible to an agent\n * only after ownership has been explicitely transferred to that agent. Once the\n * operation completes, the previous owner cannot longer access the data in the\n * buffer.\n *\n * An implementation of the HSA runtime is allowed, but not required, to change\n * the physical location of the buffer when ownership is transferred to a\n * different agent. In general the application must not assume this\n * behavior. The virtual location (address) of the passed buffer is never\n * modified.\n *\n * @param[in] ptr Base address of a global buffer. The pointer must match an\n * address previously returned by ::hsa_memory_allocate. The size of the buffer\n * affected by the ownership change is identical to the size of that previous\n * allocation. If @p ptr points to a fine-grained global buffer, no operation is\n * performed and the function returns success. If @p ptr does not point to\n * global memory, the behavior is undefined.\n *\n * @param[in] agent Agent that becomes the owner of the buffer. The\n * application is responsible for ensuring that @p agent has access to the\n * region that contains the buffer. It is allowed to change ownership to an\n * agent that is already the owner of the buffer, with the same or different\n * access permissions.\n *\n * @param[in] access Access permissions requested for the new owner.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr is NULL, or @p access is\n * not a valid access value.\n */\nhsa_status_t HSA_API hsa_memory_assign_agent(\n    void *ptr,\n    hsa_agent_t agent,\n    hsa_access_permission_t access);\n\n/**\n *\n * @brief Register a global, fine-grained buffer.\n *\n * @details Registering a buffer serves as an indication to the HSA runtime that\n * the memory might be accessed from a kernel agent other than the\n * host. Registration is a performance hint that allows the HSA runtime\n * implementation to know which buffers will be accessed by some of the kernel\n * agents ahead of time.\n *\n * Registration is only recommended for buffers in the global segment that have\n * not been allocated using the HSA allocator (::hsa_memory_allocate), but an OS\n * allocator instead. Registering an OS-allocated buffer in the base profile is\n * equivalent to a no-op.\n *\n * Registrations should not overlap.\n *\n * @param[in] ptr A buffer in global, fine-grained memory. If a NULL pointer is\n * passed, no operation is performed. If the buffer has been allocated using\n * ::hsa_memory_allocate, or has already been registered, no operation is\n * performed.\n *\n * @param[in] size Requested registration size in bytes. A size of 0 is\n * only allowed if @p ptr is NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p size is 0 but @p ptr\n * is not NULL.\n */\nhsa_status_t HSA_API hsa_memory_register(\n    void *ptr,\n    size_t size);\n\n/**\n *\n * @brief Deregister memory previously registered using ::hsa_memory_register.\n *\n * @details If the memory interval being deregistered does not match a previous\n * registration (start and end addresses), the behavior is undefined.\n *\n * @param[in] ptr A pointer to the base of the buffer to be deregistered. If\n * a NULL pointer is passed, no operation is performed.\n *\n * @param[in] size Size of the buffer to be deregistered.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n */\nhsa_status_t HSA_API hsa_memory_deregister(\n    void *ptr,\n    size_t size);\n\n/** @} */\n\n\n/** \\defgroup instruction-set-architecture Instruction Set Architecture.\n *  @{\n */\n\n/**\n * @brief Instruction set architecture.\n */\ntypedef struct hsa_isa_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_isa_t;\n\n/**\n * @brief Retrieve a reference to an instruction set architecture handle out of\n * a symbolic name.\n *\n * @param[in] name Vendor-specific name associated with a a particular\n * instruction set architecture. @p name must start with the vendor name and a\n * colon (for example, \"AMD:\"). The rest of the name is vendor-specific. Must be\n * a NUL-terminated string.\n *\n * @param[out] isa Memory location where the HSA runtime stores the ISA handle\n * corresponding to the given name. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA_NAME The given name does not\n * correspond to any instruction set architecture.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p name is NULL, or @p isa is\n * NULL.\n */\nhsa_status_t HSA_API hsa_isa_from_name(\n    const char *name,\n    hsa_isa_t *isa);\n\n/**\n * @brief Iterate over the instruction sets supported by the given agent, and\n * invoke an application-defined callback on every iteration. The iterator is\n * deterministic: if an agent supports several instruction set architectures,\n * they are traversed in the same order in every invocation of this function.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] callback Callback to be invoked once per instruction set\n * architecture.  The HSA runtime passes two arguments to the callback: the\n * ISA and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * that status value is returned.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_agent_iterate_isas(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_isa_t isa, void *data),\n    void *data);\n\n/**\n * @brief Instruction set architecture attributes.\n */\ntypedef enum {\n  /**\n   * The length of the ISA name in bytes, not including the NUL terminator. The\n   * type of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_NAME_LENGTH = 0,\n  /**\n   * Human-readable description.  The type of this attribute is character array\n   * with the length equal to the value of ::HSA_ISA_INFO_NAME_LENGTH attribute.\n   */\n  HSA_ISA_INFO_NAME = 1,\n  /**\n   * @deprecated\n   *\n   * Number of call conventions supported by the instruction set architecture.\n   * Must be greater than zero. The type of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_CALL_CONVENTION_COUNT = 2,\n  /**\n   * @deprecated\n   *\n   * Number of work-items in a wavefront for a given call convention. Must be a\n   * power of 2 in the range [1,256]. The type of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_CALL_CONVENTION_INFO_WAVEFRONT_SIZE = 3,\n  /**\n   * @deprecated\n   *\n   * Number of wavefronts per compute unit for a given call convention. In\n   * practice, other factors (for example, the amount of group memory used by a\n   * work-group) may further limit the number of wavefronts per compute\n   * unit. The type of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_CALL_CONVENTION_INFO_WAVEFRONTS_PER_COMPUTE_UNIT = 4,\n  /**\n   * Machine models supported by the instruction set architecture. The type of\n   * this attribute is a bool[2]. If the ISA supports the small machine model,\n   * the element at index ::HSA_MACHINE_MODEL_SMALL is true. If the ISA supports\n   * the large model, the element at index ::HSA_MACHINE_MODEL_LARGE is true.\n   */\n  HSA_ISA_INFO_MACHINE_MODELS = 5,\n  /**\n   * Profiles supported by the instruction set architecture. The type of this\n   * attribute is a bool[2]. If the ISA supports the base profile, the element\n   * at index ::HSA_PROFILE_BASE is true. If the ISA supports the full profile,\n   * the element at index ::HSA_PROFILE_FULL is true.\n   */\n  HSA_ISA_INFO_PROFILES = 6,\n  /**\n   * Default floating-point rounding modes supported by the instruction set\n   * architecture. The type of this attribute is a bool[3]. The value at a given\n   * index is true if the corresponding rounding mode in\n   * ::hsa_default_float_rounding_mode_t is supported. At least one default mode\n   * has to be supported.\n   *\n   * If the default mode is supported, then\n   * ::HSA_ISA_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES must report that\n   * both the zero and the near roundings modes are supported.\n   */\n  HSA_ISA_INFO_DEFAULT_FLOAT_ROUNDING_MODES = 7,\n  /**\n   * Default floating-point rounding modes supported by the instruction set\n   * architecture in the Base profile. The type of this attribute is a\n   * bool[3]. The value at a given index is true if the corresponding rounding\n   * mode in ::hsa_default_float_rounding_mode_t is supported. The value at\n   * index HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT must be false.  At least one\n   * of the values at indexes ::HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO or\n   * HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR must be true.\n   */\n  HSA_ISA_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES = 8,\n  /**\n   * Flag indicating that the f16 HSAIL operation is at least as fast as the\n   * f32 operation in the instruction set architecture. The type of this\n   * attribute is bool.\n   */\n  HSA_ISA_INFO_FAST_F16_OPERATION = 9,\n  /**\n   * Maximum number of work-items of each dimension of a work-group.  Each\n   * maximum must be greater than 0. No maximum can exceed the value of\n   * ::HSA_ISA_INFO_WORKGROUP_MAX_SIZE. The type of this attribute is\n   * uint16_t[3].\n   */\n  HSA_ISA_INFO_WORKGROUP_MAX_DIM = 12,\n  /**\n   * Maximum total number of work-items in a work-group. The type\n   * of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_WORKGROUP_MAX_SIZE = 13,\n  /**\n   * Maximum number of work-items of each dimension of a grid. Each maximum must\n   * be greater than 0, and must not be smaller than the corresponding value in\n   * ::HSA_ISA_INFO_WORKGROUP_MAX_DIM. No maximum can exceed the value of\n   * ::HSA_ISA_INFO_GRID_MAX_SIZE. The type of this attribute is\n   * ::hsa_dim3_t.\n   */\n  HSA_ISA_INFO_GRID_MAX_DIM = 14,\n  /**\n   * Maximum total number of work-items in a grid. The type of this\n   * attribute is uint64_t.\n   */\n  HSA_ISA_INFO_GRID_MAX_SIZE = 16,\n  /**\n   * Maximum number of fbarriers per work-group. Must be at least 32. The\n   * type of this attribute is uint32_t.\n   */\n  HSA_ISA_INFO_FBARRIER_MAX_SIZE = 17\n} hsa_isa_info_t;\n\n/**\n * @deprecated The concept of call convention has been deprecated. If the\n * application wants to query the value of an attribute for a given instruction\n * set architecture, use ::hsa_isa_get_info_alt instead. If the application\n * wants to query an attribute that is specific to a given combination of ISA\n * and wavefront, use ::hsa_wavefront_get_info.\n *\n * @brief Get the current value of an attribute for a given instruction set\n * architecture (ISA).\n *\n * @param[in] isa A valid instruction set architecture.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[in] index Call convention index. Used only for call convention\n * attributes, otherwise ignored. Must have a value between 0 (inclusive) and\n * the value of the attribute ::HSA_ISA_INFO_CALL_CONVENTION_COUNT (not\n * inclusive) in @p isa.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA The instruction set architecture is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_INDEX The index is out of range.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * instruction set architecture attribute, or @p value is\n * NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_isa_get_info(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    uint32_t index,\n    void *value);\n\n/**\n * @brief Get the current value of an attribute for a given instruction set\n * architecture (ISA).\n *\n * @param[in] isa A valid instruction set architecture.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA The instruction set architecture is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * instruction set architecture attribute, or @p value is\n * NULL.\n */\nhsa_status_t HSA_API hsa_isa_get_info_alt(\n    hsa_isa_t isa,\n    hsa_isa_info_t attribute,\n    void *value);\n\n/**\n * @brief Retrieve the exception policy support for a given combination of\n * instruction set architecture and profile.\n *\n * @param[in] isa A valid instruction set architecture.\n *\n * @param[in] profile Profile.\n *\n * @param[out] mask Pointer to a memory location where the HSA runtime stores a\n * mask of ::hsa_exception_policy_t values. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA The instruction set architecture is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p profile is not a valid\n * profile, or @p mask is NULL.\n */\nhsa_status_t HSA_API hsa_isa_get_exception_policies(\n    hsa_isa_t isa,\n    hsa_profile_t profile,\n    uint16_t *mask);\n\n/**\n * @brief Floating-point types.\n */\ntypedef enum {\n  /**\n   * 16-bit floating-point type.\n   */\n  HSA_FP_TYPE_16 = 1,\n  /**\n   * 32-bit floating-point type.\n   */\n  HSA_FP_TYPE_32 = 2,\n  /**\n   * 64-bit floating-point type.\n   */\n  HSA_FP_TYPE_64 = 4\n} hsa_fp_type_t;\n\n/**\n * @brief Flush to zero modes.\n */\ntypedef enum {\n  /**\n   * Flush to zero.\n   */\n  HSA_FLUSH_MODE_FTZ = 1,\n  /**\n   * Do not flush to zero.\n   */\n  HSA_FLUSH_MODE_NON_FTZ = 2\n} hsa_flush_mode_t;\n\n/**\n * @brief Round methods.\n */\ntypedef enum {\n  /**\n   * Single round method.\n   */\n  HSA_ROUND_METHOD_SINGLE = 1,\n  /**\n   * Double round method.\n   */\n  HSA_ROUND_METHOD_DOUBLE = 2\n} hsa_round_method_t;\n\n/**\n * @brief Retrieve the round method (single or double) used to implement the\n * floating-point multiply add instruction (mad) for a given combination of\n * instruction set architecture, floating-point type, and flush to zero\n * modifier.\n *\n * @param[in] isa Instruction set architecture.\n *\n * @param[in] fp_type Floating-point type.\n *\n * @param[in] flush_mode Flush to zero modifier.\n *\n * @param[out] round_method Pointer to a memory location where the HSA\n * runtime stores the round method used by the implementation. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA The instruction set architecture is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p fp_type is not a valid\n * floating-point type, or @p flush_mode is not a valid flush to zero modifier,\n * or @p round_method is NULL.\n */\nhsa_status_t HSA_API hsa_isa_get_round_method(\n    hsa_isa_t isa,\n    hsa_fp_type_t fp_type,\n    hsa_flush_mode_t flush_mode,\n    hsa_round_method_t *round_method);\n\n/**\n * @brief Wavefront handle\n */\ntypedef struct hsa_wavefront_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_wavefront_t;\n\n/**\n * @brief Wavefront attributes.\n */\ntypedef enum {\n  /**\n   * Number of work-items in the wavefront. Must be a power of 2 in the range\n   * [1,256]. The type of this attribute is uint32_t.\n   */\n  HSA_WAVEFRONT_INFO_SIZE = 0\n} hsa_wavefront_info_t;\n\n/**\n * @brief Get the current value of a wavefront attribute.\n *\n * @param[in] wavefront A wavefront.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_WAVEFRONT The wavefront is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * wavefront attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_wavefront_get_info(\n    hsa_wavefront_t wavefront,\n    hsa_wavefront_info_t attribute,\n    void *value);\n\n/**\n * @brief Iterate over the different wavefronts supported by an instruction set\n * architecture, and invoke an application-defined callback on every iteration.\n *\n * @param[in] isa Instruction set architecture.\n *\n * @param[in] callback Callback to be invoked once per wavefront that is\n * supported by the agent. The HSA runtime passes two arguments to the callback:\n * the wavefront handle and the application data.  If @p callback returns a\n * status other than ::HSA_STATUS_SUCCESS for a particular iteration, the\n * traversal stops and that value is returned.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA The instruction set architecture is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_isa_iterate_wavefronts(\n    hsa_isa_t isa,\n    hsa_status_t (*callback)(hsa_wavefront_t wavefront, void *data),\n    void *data);\n\n/**\n * @deprecated Use ::hsa_agent_iterate_isas to query which instructions set\n * architectures are supported by a given agent.\n *\n * @brief Check if the instruction set architecture of a code object can be\n * executed on an agent associated with another architecture.\n *\n * @param[in] code_object_isa Instruction set architecture associated with a\n * code object.\n *\n * @param[in] agent_isa Instruction set architecture associated with an agent.\n *\n * @param[out] result Pointer to a memory location where the HSA runtime stores\n * the result of the check. If the two architectures are compatible, the result\n * is true; if they are incompatible, the result is false.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA @p code_object_isa or @p agent_isa are\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p result is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_isa_compatible(\n    hsa_isa_t code_object_isa,\n    hsa_isa_t agent_isa,\n    bool *result);\n\n/** @} */\n\n\n/** \\defgroup executable Executable\n *  @{\n */\n\n/**\n * @brief Code object reader handle. A code object reader is used to\n * load a code object from file (when created using\n * ::hsa_code_object_reader_create_from_file), or from memory (if created using\n * ::hsa_code_object_reader_create_from_memory).\n */\ntypedef struct hsa_code_object_reader_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_code_object_reader_t;\n\n/**\n * @brief Create a code object reader to operate on a file.\n *\n * @param[in] file File descriptor. The file must have been opened by\n * application with at least read permissions prior calling this function. The\n * file must contain a vendor-specific code object.\n *\n * The file is owned and managed by the application; the lifetime of the file\n * descriptor must exceed that of any associated code object reader.\n *\n * @param[out] code_object_reader Memory location to store the newly created\n * code object reader handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_FILE @p file is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p code_object_reader is NULL.\n */\nhsa_status_t HSA_API hsa_code_object_reader_create_from_file(\n    hsa_file_t file,\n    hsa_code_object_reader_t *code_object_reader);\n\n/**\n * @brief Create a code object reader to operate on memory.\n *\n * @param[in] code_object Memory buffer that contains a vendor-specific code\n * object. The buffer is owned and managed by the application; the lifetime of\n * the buffer must exceed that of any associated code object reader.\n *\n * @param[in] size Size of the buffer pointed to by @p code_object. Must not be\n * 0.\n *\n * @param[out] code_object_reader Memory location to store newly created code\n * object reader handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p code_object is NULL, @p size\n * is zero, or @p code_object_reader is NULL.\n */\nhsa_status_t HSA_API hsa_code_object_reader_create_from_memory(\n    const void *code_object,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader);\n\n/**\n * @brief Destroy a code object reader.\n *\n * @details The code object reader handle becomes invalid after completion of\n * this function. Any file or memory used to create the code object read is not\n * closed, removed, or deallocated by this function.\n *\n * @param[in] code_object_reader Code object reader to destroy.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER @p code_object_reader\n * is invalid.\n */\nhsa_status_t HSA_API hsa_code_object_reader_destroy(\n    hsa_code_object_reader_t code_object_reader);\n\n/**\n * @brief Struct containing an opaque handle to an executable, which contains\n * ISA for finalized kernels and indirect functions together with the allocated\n * global or readonly segment variables they reference.\n */\ntypedef struct hsa_executable_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_executable_t;\n\n/**\n * @brief Executable state.\n */\ntypedef enum {\n  /**\n   * Executable state, which allows the user to load code objects and define\n   * external variables. Variable addresses, kernel code handles, and\n   * indirect function code handles are not available in query operations until\n   * the executable is frozen (zero always returned).\n   */\n  HSA_EXECUTABLE_STATE_UNFROZEN = 0,\n  /**\n   * Executable state, which allows the user to query variable addresses,\n   * kernel code handles, and indirect function code handles using query\n   * operations. Loading new code objects, as well as defining external\n   * variables, is not allowed in this state.\n   */\n  HSA_EXECUTABLE_STATE_FROZEN = 1\n} hsa_executable_state_t;\n\n/**\n * @deprecated Use ::hsa_executable_create_alt instead, which allows the\n * application to specify the default floating-point rounding mode of the\n * executable and assumes an unfrozen initial state.\n *\n * @brief Create an empty executable.\n *\n * @param[in] profile Profile used in the executable.\n *\n * @param[in] executable_state Executable state. If the state is\n * ::HSA_EXECUTABLE_STATE_FROZEN, the resulting executable is useless because no\n * code objects can be loaded, and no variables can be defined.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] executable Memory location where the HSA runtime stores the newly\n * created executable handle.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p profile is invalid, or\n * @p executable is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_executable_create(\n    hsa_profile_t profile,\n    hsa_executable_state_t executable_state,\n    const char *options,\n    hsa_executable_t *executable);\n\n/**\n * @brief Create an empty executable.\n *\n * @param[in] profile Profile used in the executable.\n *\n * @param[in] default_float_rounding_mode Default floating-point rounding mode\n * used in the executable. Allowed rounding modes are near and zero (default is\n * not allowed).\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] executable Memory location where the HSA runtime stores newly\n * created executable handle. The initial state of the executable is\n * ::HSA_EXECUTABLE_STATE_UNFROZEN.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p profile is invalid, or\n * @p executable is NULL.\n */\nhsa_status_t HSA_API hsa_executable_create_alt(\n    hsa_profile_t profile,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode,\n    const char *options,\n    hsa_executable_t *executable);\n\n/**\n * @brief Destroy an executable.\n *\n * @details An executable handle becomes invalid after the executable has been\n * destroyed. Code object handles that were loaded into this executable are\n * still valid after the executable has been destroyed, and can be used as\n * intended. Resources allocated outside and associated with this executable\n * (such as external global or readonly variables) can be released after the\n * executable has been destroyed.\n *\n * Executable should not be destroyed while kernels are in flight.\n *\n * @param[in] executable Executable.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n */\nhsa_status_t HSA_API hsa_executable_destroy(\n    hsa_executable_t executable);\n\n/**\n * @brief Loaded code object handle.\n */\ntypedef struct hsa_loaded_code_object_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_loaded_code_object_t;\n\n/**\n * @brief Load a program code object into an executable.\n *\n * @details A program code object contains information about resources that are\n * accessible by all kernel agents that run the executable, and can be loaded\n * at most once into an executable.\n *\n * If the program code object uses extensions, the implementation must support\n * them for this operation to return successfully.\n *\n * @param[in] executable Executable.\n *\n * @param[in] code_object_reader A code object reader that holds the program\n * code object to load. If a code object reader is destroyed before all the\n * associated executables are destroyed, the behavior is undefined.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] loaded_code_object Pointer to a memory location where the HSA\n * runtime stores the loaded code object handle. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE The executable is frozen.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER @p code_object_reader\n * is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS The program code object is\n * not compatible with the executable or the implementation (for example, the\n * code object uses an extension that is not supported by the implementation).\n */\nhsa_status_t HSA_API hsa_executable_load_program_code_object(\n    hsa_executable_t executable,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object);\n\n/**\n * @brief Load an agent code object into an executable.\n *\n * @details The agent code object contains all defined agent\n * allocation variables, functions, indirect functions, and kernels in a given\n * program for a given instruction set architecture.\n *\n * Any module linkage declaration must have been defined either by a define\n * variable or by loading a code object that has a symbol with module linkage\n * definition.\n *\n * The default floating-point rounding mode of the code object associated with\n * @p code_object_reader must match that of the executable\n * (::HSA_EXECUTABLE_INFO_DEFAULT_FLOAT_ROUNDING_MODE), or be default (in which\n * case the value of ::HSA_EXECUTABLE_INFO_DEFAULT_FLOAT_ROUNDING_MODE is used).\n * If the agent code object uses extensions, the implementation and the agent\n * must support them for this operation to return successfully.\n *\n * @param[in] executable Executable.\n *\n * @param[in] agent Agent to load code object for. A code object can be loaded\n * into an executable at most once for a given agent. The instruction set\n * architecture of the code object must be supported by the agent.\n *\n * @param[in] code_object_reader A code object reader that holds the code object\n * to load. If a code object reader is destroyed before all the associated\n * executables are destroyed, the behavior is undefined.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] loaded_code_object Pointer to a memory location where the HSA\n * runtime stores the loaded code object handle. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE The executable is frozen.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER @p code_object_reader\n * is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS The code object read by @p\n * code_object_reader is not compatible with the agent (for example, the agent\n * does not support the instruction set architecture of the code object), the\n * executable (for example, there is a default floating-point mode mismatch\n * between the two), or the implementation.\n */\nhsa_status_t HSA_API hsa_executable_load_agent_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_reader_t code_object_reader,\n    const char *options,\n    hsa_loaded_code_object_t *loaded_code_object);\n\n/**\n * @brief Freeze the executable.\n *\n * @details No modifications to executable can be made after freezing: no code\n * objects can be loaded to the executable, and no external variables can be\n * defined. Freezing the executable does not prevent querying the executable's\n * attributes. The application must define all the external variables in an\n * executable before freezing it.\n *\n * @param[in] executable Executable.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_VARIABLE_UNDEFINED One or more variables are\n * undefined in the executable.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE @p executable is already frozen.\n */\nhsa_status_t HSA_API hsa_executable_freeze(\n    hsa_executable_t executable,\n    const char *options);\n\n/**\n * @brief Executable attributes.\n */\ntypedef enum {\n  /**\n   * Profile this executable is created for. The type of this attribute is\n   * ::hsa_profile_t.\n   */\n  HSA_EXECUTABLE_INFO_PROFILE = 1,\n  /**\n   * Executable state. The type of this attribute is ::hsa_executable_state_t.\n   */\n  HSA_EXECUTABLE_INFO_STATE = 2,\n  /**\n   * Default floating-point rounding mode specified when executable was created.\n   * The type of this attribute is ::hsa_default_float_rounding_mode_t.\n   */\n  HSA_EXECUTABLE_INFO_DEFAULT_FLOAT_ROUNDING_MODE = 3\n} hsa_executable_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given executable.\n *\n * @param[in] executable Executable.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * executable attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_executable_get_info(\n    hsa_executable_t executable,\n    hsa_executable_info_t attribute,\n    void *value);\n\n/**\n * @brief Define an external global variable with program allocation.\n *\n * @details This function allows the application to provide the definition\n * of a variable in the global segment memory with program allocation. The\n * variable must be defined before loading a code object into an executable.\n * In addition, code objects loaded must not define the variable.\n *\n * @param[in] executable Executable. Must not be in frozen state.\n *\n * @param[in] variable_name Name of the variable. The Programmer's Reference\n * Manual describes the standard name mangling scheme.\n *\n * @param[in] address Address where the variable is defined. This address must\n * be in global memory and can be read and written by any agent in the\n * system. The application cannot deallocate the buffer pointed by @p address\n * before @p executable is destroyed.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED The variable is\n * already defined.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no variable with the\n * @p variable_name.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE @p executable is frozen.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p variable_name is NULL.\n */\nhsa_status_t HSA_API hsa_executable_global_variable_define(\n    hsa_executable_t executable,\n    const char *variable_name,\n    void *address);\n\n/**\n * @brief Define an external global variable with agent allocation.\n *\n * @details This function allows the application to provide the definition\n * of a variable in the global segment memory with agent allocation. The\n * variable must be defined before loading a code object into an executable.\n * In addition, code objects loaded must not define the variable.\n *\n * @param[in] executable Executable. Must not be in frozen state.\n *\n * @param[in] agent Agent for which the variable is being defined.\n *\n * @param[in] variable_name Name of the variable. The Programmer's Reference\n * Manual describes the standard name mangling scheme.\n *\n * @param[in] address Address where the variable is defined. This address must\n * have been previously allocated using ::hsa_memory_allocate in a global region\n * that is only visible to @p agent. The application cannot deallocate the\n * buffer pointed by @p address before @p executable is destroyed.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT @p agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED The variable is\n * already defined.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no variable with the\n * @p variable_name.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE @p executable is frozen.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p variable_name is NULL.\n */\nhsa_status_t HSA_API hsa_executable_agent_global_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address);\n\n/**\n * @brief Define an external readonly variable.\n *\n * @details This function allows the application to provide the definition\n * of a variable in the readonly segment memory. The variable must be defined\n * before loading a code object into an executable. In addition, code objects\n * loaded must not define the variable.\n *\n * @param[in] executable Executable. Must not be in frozen state.\n *\n * @param[in] agent Agent for which the variable is being defined.\n *\n * @param[in] variable_name Name of the variable. The Programmer's Reference\n * Manual describes the standard name mangling scheme.\n *\n * @param[in] address Address where the variable is defined. This address must\n * have been previously allocated using ::hsa_memory_allocate in a readonly\n * region associated with @p agent. The application cannot deallocate the buffer\n * pointed by @p address before @p executable is destroyed.\n *\n * @param[in] address Address where the variable is defined. The buffer pointed\n * by @p address is owned by the application, and cannot be deallocated before\n * @p executable is destroyed.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE Executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT @p agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED The variable is\n * already defined.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no variable with the\n * @p variable_name.\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE @p executable is frozen.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p variable_name is NULL.\n */\nhsa_status_t HSA_API hsa_executable_readonly_variable_define(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    const char *variable_name,\n    void *address);\n\n/**\n * @brief Validate an executable. Checks that all code objects have matching\n * machine model, profile, and default floating-point rounding mode. Checks that\n * all declarations have definitions. Checks declaration-definition\n * compatibility (see the HSA Programming Reference Manual for compatibility\n * rules). Invoking this function is equivalent to invoking\n * ::hsa_executable_validate_alt with no options.\n *\n * @param[in] executable Executable. Must be in frozen state.\n *\n * @param[out] result Memory location where the HSA runtime stores the\n * validation result. If the executable passes validation, the result is 0.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE @p executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p result is NULL.\n */\nhsa_status_t HSA_API hsa_executable_validate(\n    hsa_executable_t executable,\n    uint32_t *result);\n\n/**\n * @brief Validate an executable. Checks that all code objects have matching\n * machine model, profile, and default floating-point rounding mode. Checks that\n * all declarations have definitions. Checks declaration-definition\n * compatibility (see the HSA Programming Reference Manual for compatibility\n * rules).\n *\n * @param[in] executable Executable. Must be in frozen state.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] result Memory location where the HSA runtime stores the\n * validation result. If the executable passes validation, the result is 0.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE @p executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p result is NULL.\n */\nhsa_status_t HSA_API hsa_executable_validate_alt(\n    hsa_executable_t executable,\n    const char *options,\n    uint32_t *result);\n\n/**\n * @brief Executable symbol handle.\n *\n * The lifetime of an executable object symbol matches that of the executable\n * associated with it. An operation on a symbol whose associated executable has\n * been destroyed results in undefined behavior.\n */\ntypedef struct hsa_executable_symbol_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_executable_symbol_t;\n\n/**\n * @deprecated Use ::hsa_executable_get_symbol_by_name instead.\n *\n * @brief Get the symbol handle for a given a symbol name.\n *\n * @param[in] executable Executable.\n *\n * @param[in] module_name Module name. Must be NULL if the symbol has\n * program linkage.\n *\n * @param[in] symbol_name Symbol name.\n *\n * @param[in] agent Agent associated with the symbol. If the symbol is\n * independent of any agent (for example, a variable with program\n * allocation), this argument is ignored.\n *\n * @param[in] call_convention Call convention associated with the symbol. If the\n * symbol does not correspond to an indirect function, this argument is ignored.\n *\n * @param[out] symbol Memory location where the HSA runtime stores the symbol\n * handle.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no symbol with a name\n * that matches @p symbol_name.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p symbol_name is NULL, or\n * @p symbol is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_executable_get_symbol(\n    hsa_executable_t executable,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_agent_t agent,\n    int32_t call_convention,\n    hsa_executable_symbol_t *symbol);\n\n/**\n * @brief Retrieve the symbol handle corresponding to a given a symbol name.\n *\n * @param[in] executable Executable.\n *\n * @param[in] symbol_name Symbol name. Must be a NUL-terminated character\n * array. The Programmer's Reference Manual describes the standard name mangling\n * scheme.\n *\n * @param[in] agent Pointer to the agent for which the symbol with the given\n * name is defined. If the symbol corresponding to the given name has program\n * allocation, @p agent must be NULL.\n *\n * @param[out] symbol Memory location where the HSA runtime stores the symbol\n * handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no symbol with a name\n * that matches @p symbol_name.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p symbol_name is NULL, or @p\n * symbol is NULL.\n */\nhsa_status_t HSA_API hsa_executable_get_symbol_by_name(\n    hsa_executable_t executable,\n    const char *symbol_name,\n    const hsa_agent_t *agent,\n    hsa_executable_symbol_t *symbol);\n\n/**\n * @brief Symbol type.\n */\ntypedef enum {\n  /**\n   * Variable.\n   */\n  HSA_SYMBOL_KIND_VARIABLE = 0,\n  /**\n   * Kernel.\n   */\n  HSA_SYMBOL_KIND_KERNEL = 1,\n  /**\n   * Indirect function.\n   */\n  HSA_SYMBOL_KIND_INDIRECT_FUNCTION = 2\n} hsa_symbol_kind_t;\n\n/**\n * @brief Linkage type of a symbol.\n */\ntypedef enum {\n  /**\n   * Module linkage.\n   */\n  HSA_SYMBOL_LINKAGE_MODULE = 0,\n  /**\n   * Program linkage.\n   */\n  HSA_SYMBOL_LINKAGE_PROGRAM = 1\n} hsa_symbol_linkage_t;\n\n/**\n * @brief Allocation type of a variable.\n */\ntypedef enum {\n  /**\n   * Agent allocation.\n   */\n  HSA_VARIABLE_ALLOCATION_AGENT = 0,\n  /**\n   * Program allocation.\n   */\n  HSA_VARIABLE_ALLOCATION_PROGRAM = 1\n} hsa_variable_allocation_t;\n\n/**\n * @brief Memory segment associated with a variable.\n */\ntypedef enum {\n  /**\n   * Global memory segment.\n   */\n  HSA_VARIABLE_SEGMENT_GLOBAL = 0,\n  /**\n   * Readonly memory segment.\n   */\n  HSA_VARIABLE_SEGMENT_READONLY = 1\n} hsa_variable_segment_t;\n\n/**\n * @brief Executable symbol attributes.\n */\ntypedef enum {\n  /**\n   * The kind of the symbol. The type of this attribute is ::hsa_symbol_kind_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_TYPE = 0,\n  /**\n   * The length of the symbol name in bytes, not including the NUL terminator.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH = 1,\n  /**\n   * The name of the symbol. The type of this attribute is character array with\n   * the length equal to the value of ::HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH\n   * attribute.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_NAME = 2,\n  /**\n   * @deprecated\n   *\n   * The length of the module name in bytes (not including the NUL terminator)\n   * to which this symbol belongs if this symbol has module linkage, otherwise 0\n   * is returned. The type of this attribute is uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_MODULE_NAME_LENGTH = 3,\n  /**\n   * @deprecated\n   *\n   * The module name to which this symbol belongs if this symbol has module\n   * linkage, otherwise an empty string is returned. The type of this attribute\n   * is character array with the length equal to the value of\n   * ::HSA_EXECUTABLE_SYMBOL_INFO_MODULE_NAME_LENGTH attribute.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_MODULE_NAME = 4,\n  /**\n   * @deprecated\n   *\n   * Agent associated with this symbol. If the symbol is a variable, the\n   * value of this attribute is only defined if\n   * ::HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ALLOCATION is\n   * ::HSA_VARIABLE_ALLOCATION_AGENT. The type of this attribute is hsa_agent_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_AGENT = 20,\n  /**\n   * The address of the variable. The value of this attribute is undefined if\n   * the symbol is not a variable. The type of this attribute is uint64_t.\n   *\n   * If executable's state is ::HSA_EXECUTABLE_STATE_UNFROZEN, then 0 is\n   * returned.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ADDRESS = 21,\n  /**\n   * The linkage kind of the symbol. The type of this attribute is\n   * ::hsa_symbol_linkage_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_LINKAGE = 5,\n  /**\n   * Indicates whether the symbol corresponds to a definition. The type of this\n   * attribute is bool.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_IS_DEFINITION = 17,\n  /**\n   * @deprecated\n   *\n   * The allocation kind of the variable. The value of this attribute is\n   * undefined if the symbol is not a variable.  The type of this attribute is\n   * ::hsa_variable_allocation_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ALLOCATION = 6,\n  /**\n   * @deprecated\n   *\n   * The segment kind of the variable. The value of this attribute is undefined\n   * if the symbol is not a variable. The type of this attribute is\n   * ::hsa_variable_segment_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SEGMENT = 7,\n  /**\n   * @deprecated\n   *\n   * Alignment of the symbol in memory. The value of this attribute is undefined\n   * if the symbol is not a variable. The type of this attribute is uint32_t.\n   *\n   * The current alignment of the variable in memory may be greater than the\n   * value specified in the source program variable declaration.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ALIGNMENT = 8,\n  /**\n   * @deprecated\n   *\n   * Size of the variable. The value of this attribute is undefined if\n   * the symbol is not a variable. The type of this attribute is uint32_t.\n   *\n   * A value of 0 is returned if the variable is an external variable and has an\n   * unknown dimension.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SIZE = 9,\n  /**\n   * @deprecated\n   *\n   * Indicates whether the variable is constant. The value of this attribute is\n   * undefined if the symbol is not a variable. The type of this attribute is\n   * bool.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_IS_CONST = 10,\n  /**\n   * Kernel object handle, used in the kernel dispatch packet. The value of this\n   * attribute is undefined if the symbol is not a kernel. The type of this\n   * attribute is uint64_t.\n   *\n   * If the state of the executable is ::HSA_EXECUTABLE_STATE_UNFROZEN, then 0\n   * is returned.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT = 22,\n  /**\n   * Size of kernarg segment memory that is required to hold the values of the\n   * kernel arguments, in bytes. Must be a multiple of 16. The value of this\n   * attribute is undefined if the symbol is not a kernel. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE = 11,\n  /**\n   * Alignment (in bytes) of the buffer used to pass arguments to the kernel,\n   * which is the maximum of 16 and the maximum alignment of any of the kernel\n   * arguments. The value of this attribute is undefined if the symbol is not a\n   * kernel. The type of this attribute is uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT = 12,\n  /**\n   * Size of static group segment memory required by the kernel (per\n   * work-group), in bytes. The value of this attribute is undefined\n   * if the symbol is not a kernel. The type of this attribute is uint32_t.\n   *\n   * The reported amount does not include any dynamically allocated group\n   * segment memory that may be requested by the application when a kernel is\n   * dispatched.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE = 13,\n  /**\n   * Size of static private, spill, and arg segment memory required by\n   * this kernel (per work-item), in bytes. The value of this attribute is\n   * undefined if the symbol is not a kernel. The type of this attribute is\n   * uint32_t.\n   *\n   * If the value of ::HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK is\n   * true, the kernel may use more private memory than the reported value, and\n   * the application must add the dynamic call stack usage to @a\n   * private_segment_size when populating a kernel dispatch packet.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE = 14,\n  /**\n   * Dynamic callstack flag. The value of this attribute is undefined if the\n   * symbol is not a kernel. The type of this attribute is bool.\n   *\n   * If this flag is set (the value is true), the kernel uses a dynamically\n   * sized call stack. This can happen if recursive calls, calls to indirect\n   * functions, or the HSAIL alloca instruction are present in the kernel.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK = 15,\n  /**\n   * @deprecated\n   *\n   * Call convention of the kernel. The value of this attribute is undefined if\n   * the symbol is not a kernel. The type of this attribute is uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_CALL_CONVENTION = 18,\n  /**\n   * Indirect function object handle. The value of this attribute is undefined\n   * if the symbol is not an indirect function, or the associated agent does\n   * not support the Full Profile. The type of this attribute depends on the\n   * machine model: the type is uint32_t for small machine model, and uint64_t\n   * for large model.\n   *\n   * If the state of the executable is ::HSA_EXECUTABLE_STATE_UNFROZEN, then 0\n   * is returned.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_INDIRECT_FUNCTION_OBJECT = 23,\n  /**\n   * @deprecated\n   *\n   * Call convention of the indirect function. The value of this attribute is\n   * undefined if the symbol is not an indirect function, or the associated\n   * agent does not support the Full Profile. The type of this attribute is\n   * uint32_t.\n   */\n  HSA_EXECUTABLE_SYMBOL_INFO_INDIRECT_FUNCTION_CALL_CONVENTION = 16\n} hsa_executable_symbol_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given executable symbol.\n *\n * @param[in] executable_symbol Executable symbol.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE_SYMBOL The executable symbol is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * executable symbol attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_executable_symbol_get_info(\n    hsa_executable_symbol_t executable_symbol,\n    hsa_executable_symbol_info_t attribute,\n    void *value);\n\n/**\n * @deprecated\n *\n * @brief Iterate over the symbols in a executable, and invoke an\n * application-defined callback on every iteration.\n *\n * @param[in] executable Executable.\n *\n * @param[in] callback Callback to be invoked once per executable symbol. The\n * HSA runtime passes three arguments to the callback: the executable, a symbol,\n * and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_executable_iterate_symbols returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_executable_iterate_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data);\n\n/**\n * @brief Iterate over the kernels, indirect functions, and agent allocation\n * variables in an executable for a given agent, and invoke an application-\n * defined callback on every iteration.\n *\n * @param[in] executable Executable.\n *\n * @param[in] agent Agent.\n *\n * @param[in] callback Callback to be invoked once per executable symbol. The\n * HSA runtime passes three arguments to the callback: the executable, a symbol,\n * and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_executable_iterate_symbols returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_executable_iterate_agent_symbols(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_agent_t agent,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data);\n\n/**\n * @brief Iterate over the program allocation variables in an executable, and\n * invoke an application-defined callback on every iteration.\n *\n * @param[in] executable Executable.\n *\n * @param[in] callback Callback to be invoked once per executable symbol. The\n * HSA runtime passes three arguments to the callback: the executable, a symbol,\n * and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_executable_iterate_symbols returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_executable_iterate_program_symbols(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data);\n\n/** @} */\n\n\n/** \\defgroup code-object Code Objects (deprecated).\n *  @{\n */\n\n/**\n * @deprecated\n *\n * @brief Struct containing an opaque handle to a code object, which contains\n * ISA for finalized kernels and indirect functions together with information\n * about the global or readonly segment variables they reference.\n */\ntypedef struct hsa_code_object_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_code_object_t;\n\n/**\n * @deprecated\n *\n * @brief Application data handle that is passed to the serialization\n * and deserialization functions.\n */\ntypedef struct hsa_callback_data_s {\n  /**\n   * Opaque handle.\n   */\n  uint64_t handle;\n} hsa_callback_data_t;\n\n/**\n * @deprecated\n *\n * @brief Serialize a code object. Can be used for offline finalization,\n * install-time finalization, disk code caching, etc.\n *\n * @param[in] code_object Code object.\n *\n * @param[in] alloc_callback Callback function for memory allocation. Must not\n * be NULL. The HSA runtime passes three arguments to the callback: the\n * allocation size, the application data, and a pointer to a memory location\n * where the application stores the allocation result. The HSA runtime invokes\n * @p alloc_callback once to allocate a buffer that contains the serialized\n * version of @p code_object.  If the callback returns a status code other than\n * ::HSA_STATUS_SUCCESS, this function returns the same code.\n *\n * @param[in] callback_data Application data that is passed to @p\n * alloc_callback. May be NULL.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] serialized_code_object Memory location where the HSA runtime\n * stores a pointer to the serialized code object. Must not be NULL.\n *\n * @param[out] serialized_code_object_size Memory location where the HSA runtime\n * stores the size (in bytes) of @p serialized_code_object. The returned value\n * matches the allocation size passed by the HSA runtime to @p\n * alloc_callback. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p alloc_callback, @p\n * serialized_code_object, or @p serialized_code_object_size are NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_serialize(\n    hsa_code_object_t code_object,\n    hsa_status_t (*alloc_callback)(size_t size,\n                                   hsa_callback_data_t data,\n                                   void **address),\n    hsa_callback_data_t callback_data,\n    const char *options,\n    void **serialized_code_object,\n    size_t *serialized_code_object_size);\n\n/**\n * @deprecated\n *\n * @brief Deserialize a code object.\n *\n * @param[in] serialized_code_object A serialized code object. Must not be NULL.\n *\n * @param[in] serialized_code_object_size The size (in bytes) of @p\n * serialized_code_object. Must not be 0.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @param[out] code_object Memory location where the HSA runtime stores the\n * deserialized code object.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p serialized_code_object, or @p\n * code_object are NULL, or @p serialized_code_object_size is 0.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_deserialize(\n    void *serialized_code_object,\n    size_t serialized_code_object_size,\n    const char *options,\n    hsa_code_object_t *code_object);\n\n/**\n * @deprecated\n *\n * @brief Destroy a code object.\n *\n * @details The lifetime of a code object must exceed that of any executable\n * where it has been loaded. If an executable that loaded @p code_object has not\n * been destroyed, the behavior is undefined.\n *\n * @param[in] code_object Code object. The handle becomes invalid after it has\n * been destroyed.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_destroy(\n    hsa_code_object_t code_object);\n\n/**\n * @deprecated\n *\n * @brief Code object type.\n */\ntypedef enum {\n  /**\n   * Produces code object that contains ISA for all kernels and indirect\n   * functions in HSA source.\n   */\n  HSA_CODE_OBJECT_TYPE_PROGRAM = 0\n} hsa_code_object_type_t;\n\n/**\n * @deprecated\n *\n * @brief Code object attributes.\n */\ntypedef enum {\n  /**\n   * The version of the code object. The type of this attribute is a\n   * NUL-terminated char[64]. The name must be at most 63 characters long (not\n   * including the NUL terminator) and all array elements not used for the name\n   * must be NUL.\n   */\n  HSA_CODE_OBJECT_INFO_VERSION = 0,\n  /**\n   * Type of code object. The type of this attribute is\n   * ::hsa_code_object_type_t.\n   */\n  HSA_CODE_OBJECT_INFO_TYPE = 1,\n  /**\n   * Instruction set architecture this code object is produced for. The type of\n   * this attribute is ::hsa_isa_t.\n   */\n  HSA_CODE_OBJECT_INFO_ISA = 2,\n  /**\n   * Machine model this code object is produced for. The type of this attribute\n   * is ::hsa_machine_model_t.\n   */\n  HSA_CODE_OBJECT_INFO_MACHINE_MODEL = 3,\n  /**\n   * Profile this code object is produced for. The type of this attribute is\n   * ::hsa_profile_t.\n   */\n  HSA_CODE_OBJECT_INFO_PROFILE = 4,\n  /**\n   * Default floating-point rounding mode used when the code object is\n   * produced. The type of this attribute is\n   * ::hsa_default_float_rounding_mode_t.\n   */\n  HSA_CODE_OBJECT_INFO_DEFAULT_FLOAT_ROUNDING_MODE = 5\n} hsa_code_object_info_t;\n\n/**\n * @deprecated\n *\n * @brief Get the current value of an attribute for a given code object.\n *\n * @param[in] code_object Code object.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * code object attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_get_info(\n    hsa_code_object_t code_object,\n    hsa_code_object_info_t attribute,\n    void *value);\n\n/**\n * @deprecated\n *\n * @brief Load code object into the executable.\n *\n * @details Every global or readonly variable that is external must be defined\n * before loading the code object. An internal global or readonly variable is\n * allocated once the code object, that is being loaded, references this\n * variable and this variable is not allocated.\n *\n * Any module linkage declaration must have been defined either by a define\n * variable or by loading a code object that has a symbol with module linkage\n * definition.\n *\n * @param[in] executable Executable.\n *\n * @param[in] agent Agent to load code object for. The agent must support the\n * default floating-point rounding mode used by @p code_object.\n *\n * @param[in] code_object Code object to load.  The lifetime of the code object\n * must exceed that of the executable: if @p code_object is destroyed before @p\n * executable, the behavior is undefined.\n *\n * @param[in] options Standard and vendor-specific options. Unknown options are\n * ignored. A standard option begins with the \"-hsa_\" prefix. Options beginning\n * with the \"-hsa_ext_<extension_name>_\" prefix are reserved for extensions. A\n * vendor-specific option begins with the \"-<vendor_name>_\" prefix. Must be a\n * NUL-terminated string. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS @p agent is not compatible\n * with @p code_object (for example, @p agent does not support the default\n * floating-point rounding mode specified by @p code_object), or @p code_object\n * is not compatible with @p executable (for example, @p code_object and @p\n * executable have different machine models or profiles).\n *\n * @retval ::HSA_STATUS_ERROR_FROZEN_EXECUTABLE @p executable is frozen.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_executable_load_code_object(\n    hsa_executable_t executable,\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    const char *options);\n\n/**\n * @deprecated\n *\n * @brief Code object symbol handle.\n *\n * The lifetime of a code object symbol matches that of the code object\n * associated with it. An operation on a symbol whose associated code object has\n * been destroyed results in undefined behavior.\n */\ntypedef struct hsa_code_symbol_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_code_symbol_t;\n\n/**\n * @deprecated\n *\n * @brief Get the symbol handle within a code object for a given a symbol name.\n *\n * @param[in] code_object Code object.\n *\n * @param[in] symbol_name Symbol name.\n *\n * @param[out] symbol Memory location where the HSA runtime stores the symbol\n * handle.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no symbol with a name\n * that matches @p symbol_name.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p symbol_name is NULL, or\n * @p symbol is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_get_symbol(\n    hsa_code_object_t code_object,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol);\n\n/**\n * @deprecated\n *\n * @brief Get the symbol handle within a code object for a given a symbol name.\n *\n * @param[in] code_object Code object.\n *\n * @param[in] module_name Module name. Must be NULL if the symbol has\n * program linkage.\n *\n * @param[in] symbol_name Symbol name.\n *\n * @param[out] symbol Memory location where the HSA runtime stores the symbol\n * handle.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SYMBOL_NAME There is no symbol with a name\n * that matches @p symbol_name.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p symbol_name is NULL, or\n * @p symbol is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_get_symbol_from_name(\n    hsa_code_object_t code_object,\n    const char *module_name,\n    const char *symbol_name,\n    hsa_code_symbol_t *symbol);\n\n/**\n * @deprecated\n *\n * @brief Code object symbol attributes.\n */\ntypedef enum {\n  /**\n   * The type of the symbol. The type of this attribute is ::hsa_symbol_kind_t.\n   */\n  HSA_CODE_SYMBOL_INFO_TYPE = 0,\n  /**\n   * The length of the symbol name in bytes, not including the NUL terminator.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_NAME_LENGTH = 1,\n  /**\n   * The name of the symbol. The type of this attribute is character array with\n   * the length equal to the value of ::HSA_CODE_SYMBOL_INFO_NAME_LENGTH\n   * attribute.\n   */\n  HSA_CODE_SYMBOL_INFO_NAME = 2,\n  /**\n   * The length of the module name in bytes (not including the NUL terminator)\n   * to which this symbol belongs if this symbol has module linkage, otherwise 0\n   * is returned. The type of this attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_MODULE_NAME_LENGTH = 3,\n  /**\n   * The module name to which this symbol belongs if this symbol has module\n   * linkage, otherwise an empty string is returned. The type of this attribute\n   * is character array with the length equal to the value of\n   * ::HSA_CODE_SYMBOL_INFO_MODULE_NAME_LENGTH attribute.\n   */\n  HSA_CODE_SYMBOL_INFO_MODULE_NAME = 4,\n  /**\n   * The linkage kind of the symbol. The type of this attribute is\n   * ::hsa_symbol_linkage_t.\n   */\n  HSA_CODE_SYMBOL_INFO_LINKAGE = 5,\n  /**\n   * Indicates whether the symbol corresponds to a definition. The type of this\n   * attribute is bool.\n   */\n  HSA_CODE_SYMBOL_INFO_IS_DEFINITION = 17,\n  /**\n   * The allocation kind of the variable. The value of this attribute is\n   * undefined if the symbol is not a variable. The type of this attribute is\n   * ::hsa_variable_allocation_t.\n   */\n  HSA_CODE_SYMBOL_INFO_VARIABLE_ALLOCATION = 6,\n  /**\n   * The segment kind of the variable. The value of this attribute is\n   * undefined if the symbol is not a variable. The type of this attribute is\n   * ::hsa_variable_segment_t.\n   */\n  HSA_CODE_SYMBOL_INFO_VARIABLE_SEGMENT = 7,\n  /**\n   * Alignment of the symbol in memory. The value of this attribute is undefined\n   * if the symbol is not a variable. The type of this attribute is uint32_t.\n   *\n   * The current alignment of the variable in memory may be greater than the\n   * value specified in the source program variable declaration.\n   */\n  HSA_CODE_SYMBOL_INFO_VARIABLE_ALIGNMENT = 8,\n  /**\n   * Size of the variable. The value of this attribute is undefined if the\n   * symbol is not a variable. The type of this attribute is uint32_t.\n   *\n   * A size of 0 is returned if the variable is an external variable and has an\n   * unknown dimension.\n   */\n  HSA_CODE_SYMBOL_INFO_VARIABLE_SIZE = 9,\n  /**\n   * Indicates whether the variable is constant. The value of this attribute is\n   * undefined if the symbol is not a variable. The type of this attribute is\n   * bool.\n   */\n  HSA_CODE_SYMBOL_INFO_VARIABLE_IS_CONST = 10,\n  /**\n   * Size of kernarg segment memory that is required to hold the values of the\n   * kernel arguments, in bytes. Must be a multiple of 16. The value of this\n   * attribute is undefined if the symbol is not a kernel. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE = 11,\n  /**\n   * Alignment (in bytes) of the buffer used to pass arguments to the kernel,\n   * which is the maximum of 16 and the maximum alignment of any of the kernel\n   * arguments. The value of this attribute is undefined if the symbol is not a\n   * kernel. The type of this attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT = 12,\n  /**\n   * Size of static group segment memory required by the kernel (per\n   * work-group), in bytes. The value of this attribute is undefined\n   * if the symbol is not a kernel. The type of this attribute is uint32_t.\n   *\n   * The reported amount does not include any dynamically allocated group\n   * segment memory that may be requested by the application when a kernel is\n   * dispatched.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE = 13,\n  /**\n   * Size of static private, spill, and arg segment memory required by\n   * this kernel (per work-item), in bytes. The value of this attribute is\n   * undefined if the symbol is not a kernel. The type of this attribute is\n   * uint32_t.\n   *\n   * If the value of ::HSA_CODE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK is true,\n   * the kernel may use more private memory than the reported value, and the\n   * application must add the dynamic call stack usage to @a\n   * private_segment_size when populating a kernel dispatch packet.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE = 14,\n  /**\n   * Dynamic callstack flag. The value of this attribute is undefined if the\n   * symbol is not a kernel. The type of this attribute is bool.\n   *\n   * If this flag is set (the value is true), the kernel uses a dynamically\n   * sized call stack. This can happen if recursive calls, calls to indirect\n   * functions, or the HSAIL alloca instruction are present in the kernel.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK = 15,\n  /**\n   * Call convention of the kernel. The value of this attribute is undefined if\n   * the symbol is not a kernel. The type of this attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_CALL_CONVENTION = 18,\n  /**\n   * Call convention of the indirect function. The value of this attribute is\n   * undefined if the symbol is not an indirect function. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_INDIRECT_FUNCTION_CALL_CONVENTION = 16,\n  /**\n   * Wavefront size used by the kernel. The value of this attribute is either\n   * 32 or 64. The type of this attribute is uint32_t.\n   */\n  HSA_CODE_SYMBOL_INFO_KERNEL_WAVEFRONT_SIZE = 19\n} hsa_code_symbol_info_t;\n\n/**\n * @deprecated\n *\n * @brief Get the current value of an attribute for a given code symbol.\n *\n * @param[in] code_symbol Code symbol.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_SYMBOL The code symbol is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * code symbol attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_symbol_get_info(\n    hsa_code_symbol_t code_symbol,\n    hsa_code_symbol_info_t attribute,\n    void *value);\n\n/**\n * @deprecated\n *\n * @brief Iterate over the symbols in a code object, and invoke an\n * application-defined callback on every iteration.\n *\n * @param[in] code_object Code object.\n *\n * @param[in] callback Callback to be invoked once per code object symbol. The\n * HSA runtime passes three arguments to the callback: the code object, a\n * symbol, and the application data.  If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_code_object_iterate_symbols returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT @p code_object is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API HSA_DEPRECATED hsa_code_object_iterate_symbols(\n    hsa_code_object_t code_object,\n    hsa_status_t (*callback)(hsa_code_object_t code_object,\n                             hsa_code_symbol_t symbol,\n                             void *data),\n    void *data);\n\n/** @} */\n\n#ifdef __cplusplus\n}  // end extern \"C\" block\n#endif\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_amd_tool.h",
    "content": "#ifndef HSA_RUNTIME_AMD_TOOL_EVENTS_H_\n#define HSA_RUNTIME_AMD_TOOL_EVENTS_H_\n\n// Insert license header\n\n#include <stddef.h>\n#include <stdint.h>\n#include \"hsa.h\"\n\n\ntypedef enum {\n  HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_NONE = 0,\n  HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_USE_ONCE =\n      (1 << 0),  // This scratch allocation is only valid for 1 dispatch.\n  HSA_AMD_EVENT_SCRATCH_ALLOC_FLAG_ALT =\n      (1 << 1),  // Used alternate scratch instead of main scratch\n} hsa_amd_event_scratch_alloc_flag_t;\n\ntypedef enum {\n  HSA_AMD_TOOL_EVENT_MIN = 0,\n\n  // Scratch memory tracking\n  HSA_AMD_TOOL_EVENT_SCRATCH_ALLOC_START,\n  HSA_AMD_TOOL_EVENT_SCRATCH_ALLOC_END,\n  HSA_AMD_TOOL_EVENT_SCRATCH_FREE_START,\n  HSA_AMD_TOOL_EVENT_SCRATCH_FREE_END,\n  HSA_AMD_TOOL_EVENT_SCRATCH_ASYNC_RECLAIM_START,\n  HSA_AMD_TOOL_EVENT_SCRATCH_ASYNC_RECLAIM_END,\n\n  // Add new events above ^\n  HSA_AMD_TOOL_EVENT_MAX\n} hsa_amd_tool_event_kind_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n} hsa_amd_tool_event_none_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n  uint64_t dispatch_id;  // Dispatch ID of the AQL packet that needs more scratch memory\n} hsa_amd_event_scratch_alloc_start_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n  uint64_t dispatch_id;  // Dispatch ID of the AQL packet that needs more scratch memory\n  size_t size;           // Amount of scratch allocated - in bytes\n  size_t num_slots;      // limit of number of waves\n} hsa_amd_event_scratch_alloc_end_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n} hsa_amd_event_scratch_free_start_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n} hsa_amd_event_scratch_free_end_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n} hsa_amd_event_scratch_async_reclaim_start_t;\n\ntypedef struct {\n  hsa_amd_tool_event_kind_t kind;\n  const hsa_queue_t* queue;\n  hsa_amd_event_scratch_alloc_flag_t flags;\n} hsa_amd_event_scratch_async_reclaim_end_t;\n\ntypedef union {\n  const hsa_amd_tool_event_none_t* none;\n  const hsa_amd_event_scratch_alloc_start_t* scratch_alloc_start;\n  const hsa_amd_event_scratch_alloc_end_t* scratch_alloc_end;\n  const hsa_amd_event_scratch_free_start_t* scratch_free_start;\n  const hsa_amd_event_scratch_free_end_t* scratch_free_end;\n  const hsa_amd_event_scratch_async_reclaim_start_t* scratch_async_reclaim_start;\n  const hsa_amd_event_scratch_async_reclaim_end_t* scratch_async_reclaim_end;\n} hsa_amd_tool_event_t;\n\ntypedef hsa_status_t (*hsa_amd_tool_event)(hsa_amd_tool_event_t);\n\n\n#endif"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_api_trace.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_INC_HSA_API_TRACE_H\n#define HSA_RUNTIME_INC_HSA_API_TRACE_H\n\n#include \"hsa.h\"\n#include \"hsa_api_trace_version.h\"\n#ifdef AMD_INTERNAL_BUILD\n#include \"hsa_ext_image.h\"\n#include \"hsa_ext_amd.h\"\n#include \"hsa_ext_finalize.h\"\n#include \"hsa_amd_tool.h\"\n#include \"hsa_ven_amd_pc_sampling.h\"\n#else\n#include \"inc/hsa_ext_image.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"inc/hsa_ext_finalize.h\"\n#include \"inc/hsa_amd_tool.h\"\n#include \"inc/hsa_ven_amd_pc_sampling.h\"\n#endif\n\n#include <string.h>\n#include <assert.h>\n#include <stddef.h>\n\n// Table MAJOR_VERSION and STEP_VERSION defines have moved to hsa_api_trace_version.h\n\n// Min function used to copy Api Tables\nstatic inline uint32_t Min(const uint32_t a, const uint32_t b) {\n  return (a > b) ? b : a;\n}\n\n// Declarations of APIs intended for use only by tools.\n\n// An AQL packet that can be put in an intercept queue to cause a callback to\n// be invoked when the packet is about to be submitted to the underlying\n// hardware queue. These packets are not copied to the underlying hardware\n// queue. These packets should come immediately before the regular AQL packet\n// they relate to. This implies that packet rewriters should always keep these\n// packets adjacent to the regular AQL packet that follows them.\nconst uint32_t AMD_AQL_FORMAT_INTERCEPT_MARKER = 0xFE;\n\nstruct amd_aql_intercept_marker_s;\n\n// When an intercept queue is processing rewritten packets to put them on the\n// underlying hardware queue, if it encounters a\n// AMD_AQL_FORMAT_INTERCEPT_MARKER vendor AQL packet it will call the following\n// handler. packet points to the packet, queue is the underlying hardware\n// queue, and packet_id is the packet id of the next packet to be put on the\n// underlying hardware queue. The intercept queue does not put these packets\n// onto the underlying hardware queue.\ntypedef void (*amd_intercept_marker_handler)(const struct amd_aql_intercept_marker_s* packet,\n                                             hsa_queue_t* queue, uint64_t packet_id);\n// An AQL vendor packet used by the intercept queue to mark the following\n// packet. The callback will be invoked to allow a tool to know where in the\n// underlying hardware queue the following packet will be placed. user_data can\n// be used to hold any data useful to the tool.\ntypedef struct amd_aql_intercept_marker_s {\n  uint16_t header; // Must have a packet type of HSA_PACKET_TYPE_VENDOR_SPECIFIC.\n  uint8_t format; // Must be AMD_AQL_FORMAT_INTERCEPT_MARKER.\n  uint8_t reserved[5]; // Must be 0.\n#ifdef HSA_LARGE_MODEL\n  amd_intercept_marker_handler callback;\n#elif defined HSA_LITTLE_ENDIAN\n  amd_intercept_marker_handler callback;\n  uint32_t reserved1; // Must be 0.\n#else\n  uint32_t reserved1; // Must be 0.\n  amd_intercept_marker_handler callback;\n#endif\n  uint64_t user_data[6];\n} amd_aql_intercept_marker_t;\n\ntypedef void (*hsa_amd_queue_intercept_packet_writer)(const void* pkts, uint64_t pkt_count);\ntypedef void (*hsa_amd_queue_intercept_handler)(const void* pkts, uint64_t pkt_count,\n                                                uint64_t user_pkt_index, void* data,\n                                                hsa_amd_queue_intercept_packet_writer writer);\nhsa_status_t hsa_amd_queue_intercept_register(hsa_queue_t* queue,\n                                              hsa_amd_queue_intercept_handler callback,\n                                              void* user_data);\nhsa_status_t hsa_amd_queue_intercept_create(\n    hsa_agent_t agent_handle, uint32_t size, hsa_queue_type32_t type,\n    void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,\n    uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue);\n\ntypedef void (*hsa_amd_runtime_queue_notifier)(const hsa_queue_t* queue, hsa_agent_t agent,\n                                               void* data);\nhsa_status_t hsa_amd_runtime_queue_create_register(hsa_amd_runtime_queue_notifier callback,\n                                                   void* user_data);\n\n// Structure of Version used to identify an instance of Api table\n// Must be the first member (offsetof == 0) of all API tables.\n// This is the root of the table passing ABI.\nstruct ApiTableVersion {\n  uint32_t major_id;\n  uint32_t minor_id;\n  uint32_t step_id;\n  uint32_t reserved;\n};\n\nstruct ToolsApiTable {\n  ApiTableVersion version;\n\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_alloc_start_fn;\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_alloc_end_fn;\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_free_start_fn;\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_free_end_fn;\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_async_reclaim_start_fn;\n  hsa_amd_tool_event hsa_amd_tool_scratch_event_async_reclaim_end_fn;\n};\n\n// Table to export HSA Finalizer Extension Apis\nstruct FinalizerExtTable {\n  ApiTableVersion version;\n\tdecltype(hsa_ext_program_create)* hsa_ext_program_create_fn;\n\tdecltype(hsa_ext_program_destroy)* hsa_ext_program_destroy_fn;\n\tdecltype(hsa_ext_program_add_module)* hsa_ext_program_add_module_fn;\n\tdecltype(hsa_ext_program_iterate_modules)* hsa_ext_program_iterate_modules_fn;\n\tdecltype(hsa_ext_program_get_info)* hsa_ext_program_get_info_fn;\n\tdecltype(hsa_ext_program_finalize)* hsa_ext_program_finalize_fn;\n};\n\n// Table to export HSA Image Extension Apis\nstruct ImageExtTable {\n  ApiTableVersion version;\n\tdecltype(hsa_ext_image_get_capability)* hsa_ext_image_get_capability_fn;\n\tdecltype(hsa_ext_image_data_get_info)* hsa_ext_image_data_get_info_fn;\n\tdecltype(hsa_ext_image_create)* hsa_ext_image_create_fn;\n\tdecltype(hsa_ext_image_import)* hsa_ext_image_import_fn;\n\tdecltype(hsa_ext_image_export)* hsa_ext_image_export_fn;\n\tdecltype(hsa_ext_image_copy)* hsa_ext_image_copy_fn;\n\tdecltype(hsa_ext_image_clear)* hsa_ext_image_clear_fn;\n\tdecltype(hsa_ext_image_destroy)* hsa_ext_image_destroy_fn;\n\tdecltype(hsa_ext_sampler_create)* hsa_ext_sampler_create_fn;\n\tdecltype(hsa_ext_sampler_destroy)* hsa_ext_sampler_destroy_fn;\n  decltype(hsa_ext_image_get_capability_with_layout)* hsa_ext_image_get_capability_with_layout_fn;\n  decltype(hsa_ext_image_data_get_info_with_layout)* hsa_ext_image_data_get_info_with_layout_fn;\n  decltype(hsa_ext_image_create_with_layout)* hsa_ext_image_create_with_layout_fn;\n  decltype(hsa_ext_sampler_create_v2)* hsa_ext_sampler_create_v2_fn;\n\n};\n\n// Table to export HSA PC Sampling Extension Apis\nstruct PcSamplingExtTable {\n  ApiTableVersion version;\n  decltype(hsa_ven_amd_pcs_iterate_configuration)* hsa_ven_amd_pcs_iterate_configuration_fn;\n  decltype(hsa_ven_amd_pcs_create)* hsa_ven_amd_pcs_create_fn;\n  decltype(hsa_ven_amd_pcs_create_from_id)* hsa_ven_amd_pcs_create_from_id_fn;\n  decltype(hsa_ven_amd_pcs_destroy)* hsa_ven_amd_pcs_destroy_fn;\n  decltype(hsa_ven_amd_pcs_start)* hsa_ven_amd_pcs_start_fn;\n  decltype(hsa_ven_amd_pcs_stop)* hsa_ven_amd_pcs_stop_fn;\n  decltype(hsa_ven_amd_pcs_flush)* hsa_ven_amd_pcs_flush_fn;\n};\n\n\n// Table to export AMD Extension Apis\nstruct AmdExtTable {\n  ApiTableVersion version;\n\tdecltype(hsa_amd_coherency_get_type)* hsa_amd_coherency_get_type_fn;\n\tdecltype(hsa_amd_coherency_set_type)* hsa_amd_coherency_set_type_fn;\n  decltype(hsa_amd_profiling_set_profiler_enabled)* hsa_amd_profiling_set_profiler_enabled_fn;\n  decltype(hsa_amd_profiling_async_copy_enable) *hsa_amd_profiling_async_copy_enable_fn;\n  decltype(hsa_amd_profiling_get_dispatch_time)* hsa_amd_profiling_get_dispatch_time_fn;\n  decltype(hsa_amd_profiling_get_async_copy_time) *hsa_amd_profiling_get_async_copy_time_fn;\n  decltype(hsa_amd_profiling_convert_tick_to_system_domain)* hsa_amd_profiling_convert_tick_to_system_domain_fn;\n  decltype(hsa_amd_signal_async_handler)* hsa_amd_signal_async_handler_fn;\n  decltype(hsa_amd_async_function)* hsa_amd_async_function_fn;\n  decltype(hsa_amd_signal_wait_any)* hsa_amd_signal_wait_any_fn;\n  decltype(hsa_amd_queue_cu_set_mask)* hsa_amd_queue_cu_set_mask_fn;\n  decltype(hsa_amd_memory_pool_get_info)* hsa_amd_memory_pool_get_info_fn;\n  decltype(hsa_amd_agent_iterate_memory_pools)* hsa_amd_agent_iterate_memory_pools_fn;\n  decltype(hsa_amd_memory_pool_allocate)* hsa_amd_memory_pool_allocate_fn;\n  decltype(hsa_amd_memory_pool_free)* hsa_amd_memory_pool_free_fn;\n  decltype(hsa_amd_memory_async_copy)* hsa_amd_memory_async_copy_fn;\n  decltype(hsa_amd_memory_async_copy_on_engine)* hsa_amd_memory_async_copy_on_engine_fn;\n  decltype(hsa_amd_memory_copy_engine_status)* hsa_amd_memory_copy_engine_status_fn;\n  decltype(hsa_amd_agent_memory_pool_get_info)* hsa_amd_agent_memory_pool_get_info_fn;\n  decltype(hsa_amd_agents_allow_access)* hsa_amd_agents_allow_access_fn;\n  decltype(hsa_amd_memory_pool_can_migrate)* hsa_amd_memory_pool_can_migrate_fn;\n  decltype(hsa_amd_memory_migrate)* hsa_amd_memory_migrate_fn;\n  decltype(hsa_amd_memory_lock)* hsa_amd_memory_lock_fn;\n  decltype(hsa_amd_memory_unlock)* hsa_amd_memory_unlock_fn;\n  decltype(hsa_amd_memory_fill)* hsa_amd_memory_fill_fn;\n  decltype(hsa_amd_interop_map_buffer)* hsa_amd_interop_map_buffer_fn;\n  decltype(hsa_amd_interop_unmap_buffer)* hsa_amd_interop_unmap_buffer_fn;\n  decltype(hsa_amd_image_create)* hsa_amd_image_create_fn;\n  decltype(hsa_amd_pointer_info)* hsa_amd_pointer_info_fn;\n  decltype(hsa_amd_pointer_info_set_userdata)* hsa_amd_pointer_info_set_userdata_fn;\n  decltype(hsa_amd_ipc_memory_create)* hsa_amd_ipc_memory_create_fn;\n  decltype(hsa_amd_ipc_memory_attach)* hsa_amd_ipc_memory_attach_fn;\n  decltype(hsa_amd_ipc_memory_detach)* hsa_amd_ipc_memory_detach_fn;\n  decltype(hsa_amd_signal_create)* hsa_amd_signal_create_fn;\n  decltype(hsa_amd_ipc_signal_create)* hsa_amd_ipc_signal_create_fn;\n  decltype(hsa_amd_ipc_signal_attach)* hsa_amd_ipc_signal_attach_fn;\n  decltype(hsa_amd_register_system_event_handler)* hsa_amd_register_system_event_handler_fn;\n  decltype(hsa_amd_queue_intercept_create)* hsa_amd_queue_intercept_create_fn;\n  decltype(hsa_amd_queue_intercept_register)* hsa_amd_queue_intercept_register_fn;\n  decltype(hsa_amd_queue_set_priority)* hsa_amd_queue_set_priority_fn;\n  decltype(hsa_amd_memory_async_copy_rect)* hsa_amd_memory_async_copy_rect_fn;\n  decltype(hsa_amd_runtime_queue_create_register)* hsa_amd_runtime_queue_create_register_fn;\n  decltype(hsa_amd_memory_lock_to_pool)* hsa_amd_memory_lock_to_pool_fn;\n  decltype(hsa_amd_register_deallocation_callback)* hsa_amd_register_deallocation_callback_fn;\n  decltype(hsa_amd_deregister_deallocation_callback)* hsa_amd_deregister_deallocation_callback_fn;\n  decltype(hsa_amd_signal_value_pointer)* hsa_amd_signal_value_pointer_fn;\n  decltype(hsa_amd_svm_attributes_set)* hsa_amd_svm_attributes_set_fn;\n  decltype(hsa_amd_svm_attributes_get)* hsa_amd_svm_attributes_get_fn;\n  decltype(hsa_amd_svm_prefetch_async)* hsa_amd_svm_prefetch_async_fn;\n  decltype(hsa_amd_spm_acquire)* hsa_amd_spm_acquire_fn;\n  decltype(hsa_amd_spm_release)* hsa_amd_spm_release_fn;\n  decltype(hsa_amd_spm_set_dest_buffer)* hsa_amd_spm_set_dest_buffer_fn;\n  decltype(hsa_amd_queue_cu_get_mask)* hsa_amd_queue_cu_get_mask_fn;\n  decltype(hsa_amd_portable_export_dmabuf)* hsa_amd_portable_export_dmabuf_fn;\n  decltype(hsa_amd_portable_close_dmabuf)* hsa_amd_portable_close_dmabuf_fn;\n  decltype(hsa_amd_vmem_address_reserve)* hsa_amd_vmem_address_reserve_fn;\n  decltype(hsa_amd_vmem_address_free)* hsa_amd_vmem_address_free_fn;\n  decltype(hsa_amd_vmem_handle_create)* hsa_amd_vmem_handle_create_fn;\n  decltype(hsa_amd_vmem_handle_release)* hsa_amd_vmem_handle_release_fn;\n  decltype(hsa_amd_vmem_map)* hsa_amd_vmem_map_fn;\n  decltype(hsa_amd_vmem_unmap)* hsa_amd_vmem_unmap_fn;\n  decltype(hsa_amd_vmem_set_access)* hsa_amd_vmem_set_access_fn;\n  decltype(hsa_amd_vmem_get_access)* hsa_amd_vmem_get_access_fn;\n  decltype(hsa_amd_vmem_export_shareable_handle)* hsa_amd_vmem_export_shareable_handle_fn;\n  decltype(hsa_amd_vmem_import_shareable_handle)* hsa_amd_vmem_import_shareable_handle_fn;\n  decltype(hsa_amd_vmem_retain_alloc_handle)* hsa_amd_vmem_retain_alloc_handle_fn;\n  decltype(hsa_amd_vmem_get_alloc_properties_from_handle)*\n      hsa_amd_vmem_get_alloc_properties_from_handle_fn;\n  decltype(hsa_amd_agent_set_async_scratch_limit)* hsa_amd_agent_set_async_scratch_limit_fn;\n  decltype(hsa_amd_queue_get_info)* hsa_amd_queue_get_info_fn;\n  decltype(hsa_amd_vmem_address_reserve_align)* hsa_amd_vmem_address_reserve_align_fn;\n  decltype(hsa_amd_enable_logging)* hsa_amd_enable_logging_fn;\n  decltype(hsa_amd_signal_wait_all)* hsa_amd_signal_wait_all_fn;\n  decltype(hsa_amd_memory_get_preferred_copy_engine)* hsa_amd_memory_get_preferred_copy_engine_fn;\n  decltype(hsa_amd_portable_export_dmabuf_v2)* hsa_amd_portable_export_dmabuf_v2_fn;\n};\n\n// Table to export HSA Core Runtime Apis\nstruct CoreApiTable {\n  ApiTableVersion version;\n  decltype(hsa_init)* hsa_init_fn;\n  decltype(hsa_shut_down)* hsa_shut_down_fn;\n  decltype(hsa_system_get_info)* hsa_system_get_info_fn;\n  decltype(hsa_system_extension_supported)* hsa_system_extension_supported_fn;\n  decltype(hsa_system_get_extension_table)* hsa_system_get_extension_table_fn;\n  decltype(hsa_iterate_agents)* hsa_iterate_agents_fn;\n  decltype(hsa_agent_get_info)* hsa_agent_get_info_fn;\n  decltype(hsa_queue_create)* hsa_queue_create_fn;\n  decltype(hsa_soft_queue_create)* hsa_soft_queue_create_fn;\n  decltype(hsa_queue_destroy)* hsa_queue_destroy_fn;\n  decltype(hsa_queue_inactivate)* hsa_queue_inactivate_fn;\n  decltype(hsa_queue_load_read_index_scacquire)* hsa_queue_load_read_index_scacquire_fn;\n  decltype(hsa_queue_load_read_index_relaxed)* hsa_queue_load_read_index_relaxed_fn;\n  decltype(hsa_queue_load_write_index_scacquire)* hsa_queue_load_write_index_scacquire_fn;\n  decltype(hsa_queue_load_write_index_relaxed)* hsa_queue_load_write_index_relaxed_fn;\n  decltype(hsa_queue_store_write_index_relaxed)* hsa_queue_store_write_index_relaxed_fn;\n  decltype(hsa_queue_store_write_index_screlease)* hsa_queue_store_write_index_screlease_fn;\n  decltype(hsa_queue_cas_write_index_scacq_screl)* hsa_queue_cas_write_index_scacq_screl_fn;\n  decltype(hsa_queue_cas_write_index_scacquire)* hsa_queue_cas_write_index_scacquire_fn;\n  decltype(hsa_queue_cas_write_index_relaxed)* hsa_queue_cas_write_index_relaxed_fn;\n  decltype(hsa_queue_cas_write_index_screlease)* hsa_queue_cas_write_index_screlease_fn;\n  decltype(hsa_queue_add_write_index_scacq_screl)* hsa_queue_add_write_index_scacq_screl_fn;\n  decltype(hsa_queue_add_write_index_scacquire)* hsa_queue_add_write_index_scacquire_fn;\n  decltype(hsa_queue_add_write_index_relaxed)* hsa_queue_add_write_index_relaxed_fn;\n  decltype(hsa_queue_add_write_index_screlease)* hsa_queue_add_write_index_screlease_fn;\n  decltype(hsa_queue_store_read_index_relaxed)* hsa_queue_store_read_index_relaxed_fn;\n  decltype(hsa_queue_store_read_index_screlease)* hsa_queue_store_read_index_screlease_fn;\n  decltype(hsa_agent_iterate_regions)* hsa_agent_iterate_regions_fn;\n  decltype(hsa_region_get_info)* hsa_region_get_info_fn;\n  decltype(hsa_agent_get_exception_policies)* hsa_agent_get_exception_policies_fn;\n  decltype(hsa_agent_extension_supported)* hsa_agent_extension_supported_fn;\n  decltype(hsa_memory_register)* hsa_memory_register_fn;\n  decltype(hsa_memory_deregister)* hsa_memory_deregister_fn;\n  decltype(hsa_memory_allocate)* hsa_memory_allocate_fn;\n  decltype(hsa_memory_free)* hsa_memory_free_fn;\n  decltype(hsa_memory_copy)* hsa_memory_copy_fn;\n  decltype(hsa_memory_assign_agent)* hsa_memory_assign_agent_fn;\n  decltype(hsa_signal_create)* hsa_signal_create_fn;\n  decltype(hsa_signal_destroy)* hsa_signal_destroy_fn;\n  decltype(hsa_signal_load_relaxed)* hsa_signal_load_relaxed_fn;\n  decltype(hsa_signal_load_scacquire)* hsa_signal_load_scacquire_fn;\n  decltype(hsa_signal_store_relaxed)* hsa_signal_store_relaxed_fn;\n  decltype(hsa_signal_store_screlease)* hsa_signal_store_screlease_fn;\n  decltype(hsa_signal_wait_relaxed)* hsa_signal_wait_relaxed_fn;\n  decltype(hsa_signal_wait_scacquire)* hsa_signal_wait_scacquire_fn;\n  decltype(hsa_signal_and_relaxed)* hsa_signal_and_relaxed_fn;\n  decltype(hsa_signal_and_scacquire)* hsa_signal_and_scacquire_fn;\n  decltype(hsa_signal_and_screlease)* hsa_signal_and_screlease_fn;\n  decltype(hsa_signal_and_scacq_screl)* hsa_signal_and_scacq_screl_fn;\n  decltype(hsa_signal_or_relaxed)* hsa_signal_or_relaxed_fn;\n  decltype(hsa_signal_or_scacquire)* hsa_signal_or_scacquire_fn;\n  decltype(hsa_signal_or_screlease)* hsa_signal_or_screlease_fn;\n  decltype(hsa_signal_or_scacq_screl)* hsa_signal_or_scacq_screl_fn;\n  decltype(hsa_signal_xor_relaxed)* hsa_signal_xor_relaxed_fn;\n  decltype(hsa_signal_xor_scacquire)* hsa_signal_xor_scacquire_fn;\n  decltype(hsa_signal_xor_screlease)* hsa_signal_xor_screlease_fn;\n  decltype(hsa_signal_xor_scacq_screl)* hsa_signal_xor_scacq_screl_fn;\n  decltype(hsa_signal_exchange_relaxed)* hsa_signal_exchange_relaxed_fn;\n  decltype(hsa_signal_exchange_scacquire)* hsa_signal_exchange_scacquire_fn;\n  decltype(hsa_signal_exchange_screlease)* hsa_signal_exchange_screlease_fn;\n  decltype(hsa_signal_exchange_scacq_screl)* hsa_signal_exchange_scacq_screl_fn;\n  decltype(hsa_signal_add_relaxed)* hsa_signal_add_relaxed_fn;\n  decltype(hsa_signal_add_scacquire)* hsa_signal_add_scacquire_fn;\n  decltype(hsa_signal_add_screlease)* hsa_signal_add_screlease_fn;\n  decltype(hsa_signal_add_scacq_screl)* hsa_signal_add_scacq_screl_fn;\n  decltype(hsa_signal_subtract_relaxed)* hsa_signal_subtract_relaxed_fn;\n  decltype(hsa_signal_subtract_scacquire)* hsa_signal_subtract_scacquire_fn;\n  decltype(hsa_signal_subtract_screlease)* hsa_signal_subtract_screlease_fn;\n  decltype(hsa_signal_subtract_scacq_screl)* hsa_signal_subtract_scacq_screl_fn;\n  decltype(hsa_signal_cas_relaxed)* hsa_signal_cas_relaxed_fn;\n  decltype(hsa_signal_cas_scacquire)* hsa_signal_cas_scacquire_fn;\n  decltype(hsa_signal_cas_screlease)* hsa_signal_cas_screlease_fn;\n  decltype(hsa_signal_cas_scacq_screl)* hsa_signal_cas_scacq_screl_fn;\n\n  //===--- Instruction Set Architecture -----------------------------------===//\n\n  decltype(hsa_isa_from_name)* hsa_isa_from_name_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_isa_get_info)* hsa_isa_get_info_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_isa_compatible)* hsa_isa_compatible_fn;\n\n  //===--- Code Objects (deprecated) --------------------------------------===//\n\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_serialize)* hsa_code_object_serialize_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_deserialize)* hsa_code_object_deserialize_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_destroy)* hsa_code_object_destroy_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_get_info)* hsa_code_object_get_info_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_get_symbol)* hsa_code_object_get_symbol_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_symbol_get_info)* hsa_code_symbol_get_info_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_iterate_symbols)* hsa_code_object_iterate_symbols_fn;\n\n  //===--- Executable -----------------------------------------------------===//\n\n  // Deprecated since v1.1.\n  decltype(hsa_executable_create)* hsa_executable_create_fn;\n  decltype(hsa_executable_destroy)* hsa_executable_destroy_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_executable_load_code_object)* hsa_executable_load_code_object_fn;\n  decltype(hsa_executable_freeze)* hsa_executable_freeze_fn;\n  decltype(hsa_executable_get_info)* hsa_executable_get_info_fn;\n  decltype(hsa_executable_global_variable_define)*\n      hsa_executable_global_variable_define_fn;\n  decltype(hsa_executable_agent_global_variable_define)*\n      hsa_executable_agent_global_variable_define_fn;\n  decltype(hsa_executable_readonly_variable_define)*\n      hsa_executable_readonly_variable_define_fn;\n  decltype(hsa_executable_validate)* hsa_executable_validate_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_executable_get_symbol)* hsa_executable_get_symbol_fn;\n  decltype(hsa_executable_symbol_get_info)* hsa_executable_symbol_get_info_fn;\n  // Deprecated since v1.1.\n  decltype(hsa_executable_iterate_symbols)* hsa_executable_iterate_symbols_fn;\n\n  //===--- Runtime Notifications ------------------------------------------===//\n\n  decltype(hsa_status_string)* hsa_status_string_fn;\n\n  // Start HSA v1.1 additions\n  decltype(hsa_extension_get_name)* hsa_extension_get_name_fn;\n  decltype(hsa_system_major_extension_supported)* hsa_system_major_extension_supported_fn;\n  decltype(hsa_system_get_major_extension_table)* hsa_system_get_major_extension_table_fn;\n  decltype(hsa_agent_major_extension_supported)* hsa_agent_major_extension_supported_fn;\n  decltype(hsa_cache_get_info)* hsa_cache_get_info_fn;\n  decltype(hsa_agent_iterate_caches)* hsa_agent_iterate_caches_fn;\n  decltype(hsa_signal_silent_store_relaxed)* hsa_signal_silent_store_relaxed_fn;\n  decltype(hsa_signal_silent_store_screlease)* hsa_signal_silent_store_screlease_fn;\n  decltype(hsa_signal_group_create)* hsa_signal_group_create_fn;\n  decltype(hsa_signal_group_destroy)* hsa_signal_group_destroy_fn;\n  decltype(hsa_signal_group_wait_any_scacquire)* hsa_signal_group_wait_any_scacquire_fn;\n  decltype(hsa_signal_group_wait_any_relaxed)* hsa_signal_group_wait_any_relaxed_fn;\n\n  //===--- Instruction Set Architecture - HSA v1.1 additions --------------===//\n\n  decltype(hsa_agent_iterate_isas)* hsa_agent_iterate_isas_fn;\n  decltype(hsa_isa_get_info_alt)* hsa_isa_get_info_alt_fn;\n  decltype(hsa_isa_get_exception_policies)* hsa_isa_get_exception_policies_fn;\n  decltype(hsa_isa_get_round_method)* hsa_isa_get_round_method_fn;\n  decltype(hsa_wavefront_get_info)* hsa_wavefront_get_info_fn;\n  decltype(hsa_isa_iterate_wavefronts)* hsa_isa_iterate_wavefronts_fn;\n\n  //===--- Code Objects (deprecated) - HSA v1.1 additions -----------------===//\n\n  // Deprecated since v1.1.\n  decltype(hsa_code_object_get_symbol_from_name)*\n      hsa_code_object_get_symbol_from_name_fn;\n\n  //===--- Executable - HSA v1.1 additions --------------------------------===//\n\n  decltype(hsa_code_object_reader_create_from_file)*\n      hsa_code_object_reader_create_from_file_fn;\n  decltype(hsa_code_object_reader_create_from_memory)*\n      hsa_code_object_reader_create_from_memory_fn;\n  decltype(hsa_code_object_reader_destroy)* hsa_code_object_reader_destroy_fn;\n  decltype(hsa_executable_create_alt)* hsa_executable_create_alt_fn;\n  decltype(hsa_executable_load_program_code_object)*\n      hsa_executable_load_program_code_object_fn;\n  decltype(hsa_executable_load_agent_code_object)*\n      hsa_executable_load_agent_code_object_fn;\n  decltype(hsa_executable_validate_alt)* hsa_executable_validate_alt_fn;\n  decltype(hsa_executable_get_symbol_by_name)*\n      hsa_executable_get_symbol_by_name_fn;\n  decltype(hsa_executable_iterate_agent_symbols)*\n      hsa_executable_iterate_agent_symbols_fn;\n  decltype(hsa_executable_iterate_program_symbols)*\n      hsa_executable_iterate_program_symbols_fn;\n};\n\n// Table to export HSA Apis from Core Runtime, Amd Extensions\n// Finalizer and Images\nstruct HsaApiTable {\n\n  // Version of Hsa Api Table\n  ApiTableVersion version;\n\n  // Table of function pointers to HSA Core Runtime\n\tCoreApiTable* core_;\n\n  // Table of function pointers to AMD extensions\n\tAmdExtTable* amd_ext_;\n\n  // Table of function pointers to HSA Finalizer Extension\n\tFinalizerExtTable* finalizer_ext_;\n\n  // Table of function pointers to HSA Image Extension\n\tImageExtTable* image_ext_;\n\n  // Table of function pointers for tools to use\n  ToolsApiTable* tools_;\n\n  // Table of function pointers to AMD PC Sampling Extension\n  PcSamplingExtTable* pc_sampling_ext_;\n};\n\n// Structure containing instances of different api tables\nstruct HsaApiTableContainer {\n  HsaApiTable root;\n\tCoreApiTable core;\n\tAmdExtTable amd_ext;\n\tFinalizerExtTable finalizer_ext;\n\tImageExtTable image_ext;\n\tToolsApiTable tools;\n  PcSamplingExtTable pc_sampling_ext;\n\n  // Default initialization of a container instance\n  HsaApiTableContainer() {\n    root.version.major_id = HSA_API_TABLE_MAJOR_VERSION;\n    root.version.minor_id = sizeof(HsaApiTable);\n    root.version.step_id = HSA_API_TABLE_STEP_VERSION;\n\n    core.version.major_id = HSA_CORE_API_TABLE_MAJOR_VERSION;\n    core.version.minor_id = sizeof(CoreApiTable);\n    core.version.step_id = HSA_CORE_API_TABLE_STEP_VERSION;\n    root.core_ = &core;\n\n    amd_ext.version.major_id = HSA_AMD_EXT_API_TABLE_MAJOR_VERSION;\n    amd_ext.version.minor_id = sizeof(AmdExtTable);\n    amd_ext.version.step_id = HSA_AMD_EXT_API_TABLE_STEP_VERSION;\n    root.amd_ext_ = &amd_ext;\n\n    finalizer_ext.version.major_id = HSA_FINALIZER_API_TABLE_MAJOR_VERSION;\n    finalizer_ext.version.minor_id = sizeof(FinalizerExtTable);\n    finalizer_ext.version.step_id = HSA_FINALIZER_API_TABLE_STEP_VERSION;\n    root.finalizer_ext_ = &finalizer_ext;\n\n    image_ext.version.major_id = HSA_IMAGE_API_TABLE_MAJOR_VERSION;\n    image_ext.version.minor_id = sizeof(ImageExtTable);\n    image_ext.version.step_id = HSA_IMAGE_API_TABLE_STEP_VERSION;\n    root.image_ext_ = &image_ext;\n\n    tools.version.major_id = HSA_TOOLS_API_TABLE_MAJOR_VERSION;\n    tools.version.minor_id = sizeof(ToolsApiTable);\n    tools.version.step_id = HSA_TOOLS_API_TABLE_STEP_VERSION;\n    root.tools_ = &tools;\n\n    pc_sampling_ext.version.major_id = HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION;\n    pc_sampling_ext.version.minor_id = sizeof(PcSamplingExtTable);\n    pc_sampling_ext.version.step_id = HSA_PC_SAMPLING_API_TABLE_STEP_VERSION;\n    root.pc_sampling_ext_ = &pc_sampling_ext;\n  }\n};\n\n// Api to copy function pointers of a table\nstatic\nvoid inline copyApi(void* src, void* dest, size_t size) {\n  assert(size >= sizeof(ApiTableVersion));\n  memcpy((char*)src + sizeof(ApiTableVersion),\n         (char*)dest + sizeof(ApiTableVersion),\n         (size - sizeof(ApiTableVersion)));\n}\n\n// Copy Api child tables if valid.\nstatic void inline copyElement(ApiTableVersion* dest, ApiTableVersion* src) {\n  if (src->major_id && (dest->major_id == src->major_id)) {\n    dest->step_id = src->step_id;\n    dest->minor_id = Min(dest->minor_id, src->minor_id);\n    copyApi(dest, src, dest->minor_id);\n  } else {\n    dest->major_id = 0;\n    dest->minor_id = 0;\n    dest->step_id = 0;\n  }\n}\n\n// Copy constructor for all Api tables. The function assumes the\n// user has initialized an instance of tables container correctly\n// for the Major, Minor and Stepping Ids of Root and Child Api tables.\n// The function will overwrite the value of Minor Id by taking the\n// minimum of source and destination parameters. It will also overwrite\n// the stepping Id with value from source parameter.\nstatic void inline copyTables(const HsaApiTable* src, HsaApiTable* dest) {\n  // Verify Major Id of source and destination tables match\n  if (dest->version.major_id != src->version.major_id) {\n    dest->version.major_id = 0;\n    dest->version.minor_id = 0;\n    dest->version.step_id = 0;\n    return;\n  }\n\n  // Initialize the stepping id and minor id of root table. For the\n  // minor id which encodes struct size, take the minimum of source\n  // and destination parameters\n  dest->version.step_id = src->version.step_id;\n  dest->version.minor_id = Min(dest->version.minor_id, src->version.minor_id);\n\n  // Copy child tables if present\n  if ((offsetof(HsaApiTable, core_) < dest->version.minor_id))\n    copyElement(&dest->core_->version, &src->core_->version);\n  if ((offsetof(HsaApiTable, amd_ext_) < dest->version.minor_id))\n    copyElement(&dest->amd_ext_->version, &src->amd_ext_->version);\n  if ((offsetof(HsaApiTable, finalizer_ext_) < dest->version.minor_id))\n    copyElement(&dest->finalizer_ext_->version, &src->finalizer_ext_->version);\n  if ((offsetof(HsaApiTable, image_ext_) < dest->version.minor_id))\n    copyElement(&dest->image_ext_->version, &src->image_ext_->version);\n  if ((offsetof(HsaApiTable, tools_) < dest->version.minor_id))\n    copyElement(&dest->tools_->version, &src->tools_->version);\n  if ((offsetof(HsaApiTable, pc_sampling_ext_) < dest->version.minor_id))\n    copyElement(&dest->pc_sampling_ext_->version, &src->pc_sampling_ext_->version);\n}\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_api_trace_version.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_INC_HSA_API_TRACE_VERSION_H\n#define HSA_RUNTIME_INC_HSA_API_TRACE_VERSION_H\n\n// CODE IN THIS FILE **MUST** BE C-COMPATIBLE\n\n// Major Ids of the Api tables exported by Hsa Core Runtime\n#define HSA_API_TABLE_MAJOR_VERSION                 0x03\n#define HSA_CORE_API_TABLE_MAJOR_VERSION            0x02\n#define HSA_AMD_EXT_API_TABLE_MAJOR_VERSION         0x02\n#define HSA_FINALIZER_API_TABLE_MAJOR_VERSION       0x02\n#define HSA_IMAGE_API_TABLE_MAJOR_VERSION           0x02\n#define HSA_AQLPROFILE_API_TABLE_MAJOR_VERSION      0x01\n#define HSA_TOOLS_API_TABLE_MAJOR_VERSION           0x01\n#define HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION     0x01\n\n// Step Ids of the Api tables exported by Hsa Core Runtime\n#define HSA_API_TABLE_STEP_VERSION                  0x01\n#define HSA_CORE_API_TABLE_STEP_VERSION             0x00\n#define HSA_AMD_EXT_API_TABLE_STEP_VERSION          0x07\n#define HSA_FINALIZER_API_TABLE_STEP_VERSION        0x00\n#define HSA_IMAGE_API_TABLE_STEP_VERSION            0x01\n// Rocprofiler just checks HSA_MAGE_EXT_API_TABLE_STEP_VERSION\n#define HSA_IMAGE_EXT_API_TABLE_STEP_VERSION        HSA_IMAGE_API_TABLE_STEP_VERSION\n#define HSA_AQLPROFILE_API_TABLE_STEP_VERSION       0x00\n#define HSA_TOOLS_API_TABLE_STEP_VERSION            0x00\n#define HSA_PC_SAMPLING_API_TABLE_STEP_VERSION      0x00\n\n#endif  // HSA_RUNTIME_INC_HSA_API_TRACE_VERSION_H\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ext_amd.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2025, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA AMD extension.\n\n#ifndef HSA_RUNTIME_EXT_AMD_H_\n#define HSA_RUNTIME_EXT_AMD_H_\n\n#include \"hsa.h\"\n#include \"hsa_ext_image.h\"\n#include \"hsa_ven_amd_pc_sampling.h\"\n\n/**\n * - 1.0 - initial version\n * - 1.1 - dmabuf export\n * - 1.2 - hsa_amd_memory_async_copy_on_engine\n * - 1.3 - HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED pool\n * - 1.4 - Virtual Memory API\n * - 1.5 - hsa_amd_agent_info: HSA_AMD_AGENT_INFO_MEMORY_PROPERTIES\n * - 1.6 - Virtual Memory API: hsa_amd_vmem_address_reserve_align\n * - 1.7 - hsa_amd_signal_wait_all\n * - 1.8 - hsa_amd_memory_get_preferred_copy_engine\n * - 1.9 - hsa_amd_portable_export_dmabuf_v2\n * - 1.10 - hsa_amd_vmem_address_reserve: HSA_AMD_VMEM_ADDRESS_NO_REGISTER\n * - 1.11 - hsa_amd_agent_info_t: HSA_AMD_AGENT_INFO_CLOCK_COUNTERS\n */\n#define HSA_AMD_INTERFACE_VERSION_MAJOR 1\n#define HSA_AMD_INTERFACE_VERSION_MINOR 11\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** \\addtogroup aql Architected Queuing Language\n *  @{\n */\n\n/**\n * @brief Macro to set a flag within uint8_t[8] types.\n */\nstatic inline void hsa_flag_set64(uint8_t* value, uint32_t bit) {\n  unsigned int index = bit / 8;\n  unsigned int subBit = bit % 8;\n  (((uint8_t*)value)[index]) |= (1 << subBit);\n}\n\n/**\n * @brief Macro to determine whether a flag is set within uint8_t[8] types.\n */\nstatic inline bool hsa_flag_isset64(uint8_t* value, uint32_t bit) {\n  unsigned int index = bit / 8;\n  unsigned int subBit = bit % 8;\n  return ((uint8_t*)value)[index] & (1 << subBit);\n}\n\n/**\n * @brief A fixed-size type used to represent ::hsa_signal_condition_t constants.\n */\ntypedef uint32_t hsa_signal_condition32_t;\n\n/**\n * @brief AMD vendor specific packet type.\n */\ntypedef enum {\n  /**\n   * Packet used by agents to delay processing of subsequent packets until a\n   * configurable condition is satisfied by an HSA signal.  Only kernel dispatch\n   * queues created from AMD GPU Agents support this packet.\n   */\n  HSA_AMD_PACKET_TYPE_BARRIER_VALUE = 2,\n  /**\n   * Packet used to send commands to an AIE agent's embedded runtime (ERT). The\n   * ERT is responsible for, among other things, handling dispatches. Only\n   * queues created on AIE agents support this packet.\n   */\n  HSA_AMD_PACKET_TYPE_AIE_ERT = 3\n} hsa_amd_packet_type_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_amd_packet_type_t constants.\n */\ntypedef uint8_t hsa_amd_packet_type8_t;\n\n/**\n * @brief AMD vendor specific AQL packet header\n */\ntypedef struct hsa_amd_packet_header_s {\n  /**\n   * Packet header. Used to configure multiple packet parameters such as the\n   * packet type. The parameters are described by ::hsa_packet_header_t.\n   */\n  uint16_t header;\n\n  /**\n   * Format of the vendor specific packet.\n   */\n  hsa_amd_packet_type8_t AmdFormat;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint8_t reserved;\n} hsa_amd_vendor_packet_header_t;\n\n/**\n * @brief AMD barrier value packet.  Halts packet processing and waits for\n * (signal_value & ::mask) ::cond ::value to be satisfied, where signal_value\n * is the value of the signal ::signal.\n */\ntypedef struct hsa_amd_barrier_value_packet_s {\n  /**\n   * AMD vendor specific packet header.\n   */\n  hsa_amd_vendor_packet_header_t header;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved0;\n\n  /**\n   * Dependent signal object. A signal with a handle value of 0 is\n   * allowed and is interpreted by the packet processor a satisfied\n   * dependency.\n   */\n  hsa_signal_t signal;\n\n  /**\n   * Value to compare against.\n   */\n  hsa_signal_value_t value;\n\n  /**\n   * Bit mask to be combined by bitwise AND with ::signal's value.\n   */\n  hsa_signal_value_t mask;\n\n  /**\n   * Comparison operation.  See ::hsa_signal_condition_t.\n   */\n  hsa_signal_condition32_t cond;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved3;\n\n  /**\n   * Signal used to indicate completion of the job. The application can use the\n   * special signal handle 0 to indicate that no signal is used.\n   */\n  hsa_signal_t completion_signal;\n} hsa_amd_barrier_value_packet_t;\n\n/**\n * State of an AIE ERT command.\n */\ntypedef enum {\n  /**\n   * Set by the host before submitting a command to the scheduler.\n   */\n  HSA_AMD_AIE_ERT_STATE_NEW = 1,\n  /**\n   * Internal scheduler state.\n   */\n  HSA_AMD_AIE_ERT_STATE_QUEUED = 2,\n  /**\n   * Internal scheduler state.\n   */\n  HSA_AMD_AIE_ERT_STATE_RUNNING = 3,\n  /**\n   * Set by the scheduler when a command completes.\n   */\n  HSA_AMD_AIE_ERT_STATE_COMPLETED = 4,\n  /**\n   * Set by the scheduler if a command failed.\n   */\n  HSA_AMD_AIE_ERT_STATE_ERROR = 5,\n  /**\n   * Set by the scheduler if a command aborted.\n   */\n  HSA_AMD_AIE_ERT_STATE_ABORT = 6,\n  /**\n   * Internal scheduler state.\n   */\n  HSA_AMD_AIE_ERT_STATE_SUBMITTED = 7,\n  /**\n   * Set by the scheduler on a timeout and reset.\n   */\n  HSA_AMD_AIE_ERT_STATE_TIMEOUT = 8,\n  /**\n   * Set by the scheduler on a timeout and fail to reset.\n   */\n  HSA_AMD_AIE_ERT_STATE_NORESPONSE = 9,\n  HSA_AMD_AIE_ERT_STATE_SKERROR = 10,\n  HSA_AMD_AIE_ERT_STATE_SKCRASHED = 11,\n  HSA_AMD_AIE_ERT_STATE_MAX\n} hsa_amd_aie_ert_state;\n\n/**\n * Opcode types for HSA AIE ERT commands.\n */\ntypedef enum {\n  /**\n   * Start a workgroup on a compute unit (CU).\n   */\n  HSA_AMD_AIE_ERT_START_CU = 0,\n  /**\n   * Currently aliased to HSA_AMD_AIE_ERT_START_CU.\n   */\n  HSA_AMD_AIE_ERT_START_KERNEL = 0,\n  /**\n   * Configure command scheduler.\n   */\n  HSA_AMD_AIE_ERT_CONFIGURE = 2,\n  HSA_AMD_AIE_ERT_EXIT = 3,\n  HSA_AMD_AIE_ERT_ABORT = 4,\n  /**\n   * Execute a specified CU after writing.\n   */\n  HSA_AMD_AIE_ERT_EXEC_WRITE = 5,\n  /**\n   * Get stats about a CU's execution.\n   */\n  HSA_AMD_AIE_ERT_CU_STAT = 6,\n  /**\n   * Start KDMA CU or P2P.\n   */\n  HSA_AMD_AIE_ERT_START_COPYBO = 7,\n  /**\n   * Configure a soft kernel.\n   */\n  HSA_AMD_AIE_ERT_SK_CONFIG = 8,\n  /**\n   * Start a soft kernel.\n   */\n  HSA_AMD_AIE_ERT_SK_START = 9,\n  /**\n   * Unconfigure a soft kernel.\n   */\n  HSA_AMD_AIE_ERT_SK_UNCONFIG = 10,\n  /**\n   * Initialize a CU.\n   */\n  HSA_AMD_AIE_ERT_INIT_CU = 11,\n  HSA_AMD_AIE_ERT_START_FA = 12,\n  HSA_AMD_AIE_ERT_CLK_CALIB = 13,\n  HSA_AMD_AIE_ERT_MB_VALIDATE = 14,\n  /**\n   * Same as HSA_AMD_AIE_ERT_START_CU but with a key-value pair.\n   */\n  HSA_AMD_AIE_ERT_START_KEY_VAL = 15,\n  HSA_AMD_AIE_ERT_ACCESS_TEST_C = 16,\n  HSA_AMD_AIE_ERT_ACCESS_TEST = 17,\n  /**\n   * Instruction buffer command format.\n   */\n  HSA_AMD_AIE_ERT_START_DPU = 18,\n  /**\n   * Command chain.\n   */\n  HSA_AMD_AIE_ERT_CMD_CHAIN = 19,\n  /**\n   * Instruction buffer command format on NPU.\n   */\n  HSA_AMD_AIE_ERT_START_NPU = 20,\n  /**\n   * Instruction buffer command with pre-emption format on the NPU.\n   */\n  HSA_AMD_AIE_ERT_START_NPU_PREEMPT = 21\n} hsa_amd_aie_ert_cmd_opcode_t;\n\n/**\n * Payload data for AIE ERT start kernel packets (i.e., when the opcode is\n * HSA_AMD_AIE_ERT_START_KERNEL).\n */\ntypedef struct hsa_amd_aie_ert_start_kernel_data_s {\n  /**\n   * Address to the PDI.\n   */\n  void* pdi_addr;\n  /**\n   * Opcode, instructions and kernel arguments.\n   */\n  uint32_t data[];\n} hsa_amd_aie_ert_start_kernel_data_t;\n\n/**\n * AMD AIE ERT packet. Used for sending a command to an AIE agent.\n */\ntypedef struct hsa_amd_aie_ert_packet_s {\n  /**\n   * AMD vendor specific packet header.\n   */\n  hsa_amd_vendor_packet_header_t header;\n  /**\n   * Format for packets interpreted by the ERT to understand the command and\n   * payload data.\n   */\n  struct {\n    /**\n     * Current state of a command.\n     */\n    uint32_t state : 4;\n    /**\n     * Flexible field that can be interpreted on a per-command basis.\n     */\n    uint32_t custom : 8;\n    /**\n     * Number of DWORDs in the payload data.\n     */\n    uint32_t count : 11;\n    /**\n     * Opcode identifying the command.\n     */\n    uint32_t opcode : 5;\n    /**\n     * Type of a command (currently 0).\n     */\n    uint32_t type : 4;\n  };\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved0;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved1;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved2;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved3;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved4;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint64_t reserved5;\n  /**\n   * Address of packet data payload. ERT commands contain arbitrarily sized\n   * data payloads.\n   */\n  uint64_t payload_data;\n} hsa_amd_aie_ert_packet_t;\n\n/** @} */\n\n/** \\defgroup error-codes Error codes\n *  @{\n */\n\n/**\n * @brief Enumeration constants added to ::hsa_status_t.\n *\n * @remark Additions to hsa_status_t\n */\nenum {\n  /**\n   * The memory pool is invalid.\n   */\n  HSA_STATUS_ERROR_INVALID_MEMORY_POOL = 40,\n\n  /**\n   * Agent accessed memory beyond the maximum legal address.\n   */\n  HSA_STATUS_ERROR_MEMORY_APERTURE_VIOLATION = 41,\n\n  /**\n   * Agent executed an invalid shader instruction.\n   */\n  HSA_STATUS_ERROR_ILLEGAL_INSTRUCTION = 42,\n\n  /**\n   * Agent attempted to access an inaccessible address.\n   * See hsa_amd_register_system_event_handler and\n   * HSA_AMD_GPU_MEMORY_FAULT_EVENT for more information on illegal accesses.\n   */\n  HSA_STATUS_ERROR_MEMORY_FAULT = 43,\n\n  /**\n   * The CU mask was successfully set but the mask attempted to enable a CU\n   * which was disabled for the process.  CUs disabled for the process remain\n   * disabled.\n   */\n  HSA_STATUS_CU_MASK_REDUCED = 44,\n\n  /**\n   * Exceeded number of VGPRs available on this agent\n   */\n  HSA_STATUS_ERROR_OUT_OF_REGISTERS = 45,\n\n  /**\n   * Resource is busy or temporarily unavailable\n   */\n  HSA_STATUS_ERROR_RESOURCE_BUSY = 46,\n\n  /**\n   * Request is not supported by this system\n   */\n  HSA_STATUS_ERROR_NOT_SUPPORTED = 47,\n};\n\n/** @} */\n\n/** \\addtogroup memory Memory\n *  @{\n */\n\n/**\n * @brief IOMMU version supported\n */\ntypedef enum {\n  /**\n   * IOMMU not supported\n   */\n  HSA_IOMMU_SUPPORT_NONE = 0,\n  /* IOMMU V1 support is not relevant to user applications, so not reporting it */\n  /**\n   * IOMMU V2 supported\n   */\n  HSA_IOMMU_SUPPORT_V2 = 1,\n} hsa_amd_iommu_version_t;\n\n/**\n * @brief Structure containing information on the agent's clock counters.\n */\ntypedef struct hsa_amd_clock_counters_s {\n  uint64_t gpu_clock_counter;\n  uint64_t cpu_clock_counter;\n  uint64_t system_clock_counter;\n  uint64_t system_clock_frequency;\n} hsa_amd_clock_counters_t;\n\n/**\n * @brief Agent attributes.\n */\ntypedef enum hsa_amd_agent_info_s {\n  /**\n   * Chip identifier. The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_CHIP_ID = 0xA000,\n  /**\n   * Size of a cacheline in bytes. The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_CACHELINE_SIZE = 0xA001,\n  /**\n   * The number of compute unit available in the agent. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT = 0xA002,\n  /**\n   * The maximum clock frequency of the agent in MHz. The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_MAX_CLOCK_FREQUENCY = 0xA003,\n  /**\n   * Internal driver node identifier. The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_DRIVER_NODE_ID = 0xA004,\n  /**\n   * Max number of watch points on memory address ranges to generate exception\n   * events when the watched addresses are accessed.  The type of this\n   * attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_MAX_ADDRESS_WATCH_POINTS = 0xA005,\n  /**\n   * Agent BDF_ID, named LocationID in thunk. The type of this attribute is\n   * uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_BDFID = 0xA006,\n  /**\n   * Memory Interface width, the return value type is uint32_t.\n   * This attribute is deprecated.\n   */\n  HSA_AMD_AGENT_INFO_MEMORY_WIDTH = 0xA007,\n  /**\n   * Max Memory Clock, the return value type is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_MEMORY_MAX_FREQUENCY = 0xA008,\n  /**\n   * Board name of Agent - populated from MarketingName of Kfd Node\n   * The value is an Ascii string of 64 chars.\n   */\n  HSA_AMD_AGENT_INFO_PRODUCT_NAME = 0xA009,\n  /**\n   * Maximum number of waves possible in a Compute Unit.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_MAX_WAVES_PER_CU = 0xA00A,\n  /**\n   * Number of SIMD's per compute unit CU\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_SIMDS_PER_CU = 0xA00B,\n  /**\n   * Number of Shader Engines (SE) in Gpu\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_SHADER_ENGINES = 0xA00C,\n  /**\n   * Number of Shader Arrays Per Shader Engines in Gpu\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_SHADER_ARRAYS_PER_SE = 0xA00D,\n  /**\n   * Address of the HDP flush registers.  Use of these registers does not conform to the HSA memory\n   * model and should be treated with caution.\n   * The type of this attribute is hsa_amd_hdp_flush_t.\n   */\n  HSA_AMD_AGENT_INFO_HDP_FLUSH = 0xA00E,\n  /**\n   * PCIe domain for the agent.  Pairs with HSA_AMD_AGENT_INFO_BDFID\n   * to give the full physical location of the Agent.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_DOMAIN = 0xA00F,\n  /**\n   * Queries for support of cooperative queues.  See ::HSA_QUEUE_TYPE_COOPERATIVE.\n   * The type of this attribute is bool.\n   */\n  HSA_AMD_AGENT_INFO_COOPERATIVE_QUEUES = 0xA010,\n  /**\n   * Queries UUID of an agent. The value is an Ascii string with a maximum\n   * of 21 chars including NUL. The string value consists of two parts: header\n   * and body. The header identifies device type (GPU, CPU, DSP) while body\n   * encodes UUID as a 16 digit hex string\n   *\n   * Agents that do not support UUID will return the string \"GPU-XX\" or\n   * \"CPU-XX\" or \"DSP-XX\" depending upon their device type ::hsa_device_type_t\n   */\n  HSA_AMD_AGENT_INFO_UUID = 0xA011,\n  /**\n   * Queries for the ASIC revision of an agent. The value is an integer that\n   * increments for each revision. This can be used by user-level software to\n   * change how it operates, depending on the hardware version. This allows\n   * selective workarounds for hardware errata.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_ASIC_REVISION = 0xA012,\n  /**\n   * Queries whether or not the host can directly access SVM memory that is\n   * physically resident in the agent's local memory.\n   * The type of this attribute is bool.\n   */\n  HSA_AMD_AGENT_INFO_SVM_DIRECT_HOST_ACCESS = 0xA013,\n  /**\n   * Some processors support more CUs than can reliably be used in a cooperative\n   * dispatch.  This queries the count of CUs which are fully enabled for\n   * cooperative dispatch.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_COOPERATIVE_COMPUTE_UNIT_COUNT = 0xA014,\n  /**\n   * Queries the amount of memory available in bytes accross all global pools\n   * owned by the agent.\n   * The type of this attribute is uint64_t.\n   */\n  HSA_AMD_AGENT_INFO_MEMORY_AVAIL = 0xA015,\n  /**\n   * Timestamp value increase rate, in Hz. The timestamp (clock) frequency is\n   * in the range 1-400MHz.\n   * The type of this attribute is uint64_t.\n   */\n  HSA_AMD_AGENT_INFO_TIMESTAMP_FREQUENCY = 0xA016,\n  /**\n   * Queries for the ASIC family ID of an agent.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_ASIC_FAMILY_ID = 0xA107,\n  /**\n   * Queries for the Packet Processor(CP Firmware) ucode version of an agent.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_UCODE_VERSION = 0xA108,\n  /**\n   * Queries for the SDMA engine ucode of an agent.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_SDMA_UCODE_VERSION = 0xA109,\n  /**\n   * Queries the number of SDMA engines.\n   * If HSA_AMD_AGENT_INFO_NUM_SDMA_XGMI_ENG query returns non-zero,\n   * this query returns the the number of SDMA engines optimized for\n   * host to device bidirectional traffic.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_SDMA_ENG = 0xA10A,\n  /**\n   * Queries the number of additional SDMA engines optimized for D2D xGMI copies.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_SDMA_XGMI_ENG = 0xA10B,\n  /**\n   * Queries for version of IOMMU supported by agent.\n   * The type of this attribute is hsa_amd_iommu_version_t.\n   */\n  HSA_AMD_AGENT_INFO_IOMMU_SUPPORT = 0xA110,\n  /**\n   * Queries for number of XCCs within the agent.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_NUM_XCC = 0xA111,\n  /**\n   * Queries for driver unique identifier.\n   * The type of this attribute is uint32_t.\n   */\n  HSA_AMD_AGENT_INFO_DRIVER_UID = 0xA112,\n  /**\n   * Returns the hsa_agent_t of the nearest CPU agent\n   * The type of this attribute is hsa_agent_t.\n   */\n  HSA_AMD_AGENT_INFO_NEAREST_CPU = 0xA113,\n  /**\n   * Bit-mask indicating memory properties of this agent. A memory property is set if the flag bit\n   * is set at that position. User may use the hsa_flag_isset64 macro to verify whether a flag\n   * is set. The type of this attribute is uint8_t[8].\n   */\n  HSA_AMD_AGENT_INFO_MEMORY_PROPERTIES = 0xA114,\n  /**\n   * Bit-mask indicating AQL Extensions supported by this agent. An AQL extension is set if the flag\n   * bit is set at that position. User may use the hsa_flag_isset64 macro to verify whether a flag\n   * is set. The type of this attribute is uint8_t[8].\n   */\n  HSA_AMD_AGENT_INFO_AQL_EXTENSIONS = 0xA115, /* Not implemented yet */\n  /**\n   * Maximum allowed value in bytes for scratch limit for this agent. This amount\n   * is shared accross all queues created on this agent.\n   * The type of this attribute is uint64_t.\n   */\n  HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_MAX = 0xA116,\n  /**\n   * Current scratch limit threshold in bytes for this agent. This limit can be\n   * modified using the hsa_amd_agent_set_async_scratch_limit call.\n   * - AQL dispatches that require scratch-memory above this threshold will trigger a\n   *   scratch use-once.\n   * - AQL dispatches using less scratch-memory than this threshold, ROCr will\n   *   permanently assign the allocated scratch memory to the queue handling the dispatch.\n   *   This memory can be reclaimed by calling hsa_amd_agent_set_async_scratch_limit\n   *   with a lower threshold by current value.\n   *\n   * The type of this attribute is uint64_t.\n   */\n  HSA_AMD_AGENT_INFO_SCRATCH_LIMIT_CURRENT = 0xA117,\n  /**\n   * Queries the driver for clock counters of the agent.\n   * The type of this attribute is hsa_amd_clock_counters_t.\n   */\n  HSA_AMD_AGENT_INFO_CLOCK_COUNTERS = 0xA118\n} hsa_amd_agent_info_t;\n\n/**\n * @brief Agent memory properties attributes\n */\ntypedef enum hsa_amd_agent_memory_properties_s {\n  HSA_AMD_MEMORY_PROPERTY_AGENT_IS_APU = (1 << 0),\n} hsa_amd_agent_memory_properties_t;\n\n/**\n * @brief SDMA engine IDs unique by single set bit position.\n */\ntypedef enum hsa_amd_sdma_engine_id {\n  HSA_AMD_SDMA_ENGINE_0 = 0x1,\n  HSA_AMD_SDMA_ENGINE_1 = 0x2,\n  HSA_AMD_SDMA_ENGINE_2 = 0x4,\n  HSA_AMD_SDMA_ENGINE_3 = 0x8,\n  HSA_AMD_SDMA_ENGINE_4 = 0x10,\n  HSA_AMD_SDMA_ENGINE_5 = 0x20,\n  HSA_AMD_SDMA_ENGINE_6 = 0x40,\n  HSA_AMD_SDMA_ENGINE_7 = 0x80,\n  HSA_AMD_SDMA_ENGINE_8 = 0x100,\n  HSA_AMD_SDMA_ENGINE_9 = 0x200,\n  HSA_AMD_SDMA_ENGINE_10 = 0x400,\n  HSA_AMD_SDMA_ENGINE_11 = 0x800,\n  HSA_AMD_SDMA_ENGINE_12 = 0x1000,\n  HSA_AMD_SDMA_ENGINE_13 = 0x2000,\n  HSA_AMD_SDMA_ENGINE_14 = 0x4000,\n  HSA_AMD_SDMA_ENGINE_15 = 0x8000\n} hsa_amd_sdma_engine_id_t;\n\ntypedef struct hsa_amd_hdp_flush_s {\n  uint32_t* HDP_MEM_FLUSH_CNTL;\n  uint32_t* HDP_REG_FLUSH_CNTL;\n} hsa_amd_hdp_flush_t;\n\n/**\n * @brief Region attributes.\n */\n#ifdef __cplusplus\ntypedef enum hsa_amd_region_info_s : int {\n#else\ntypedef enum hsa_amd_region_info_s {\n#endif\n  /**\n   * Determine if host can access the region. The type of this attribute\n   * is bool.\n   */\n  HSA_AMD_REGION_INFO_HOST_ACCESSIBLE = 0xA000,\n  /**\n   * Base address of the region in flat address space.\n   */\n  HSA_AMD_REGION_INFO_BASE = 0xA001,\n  /**\n   * Memory Interface width, the return value type is uint32_t.\n   * This attribute is deprecated. Use HSA_AMD_AGENT_INFO_MEMORY_WIDTH.\n   */\n  HSA_AMD_REGION_INFO_BUS_WIDTH = 0xA002,\n  /**\n   * Max Memory Clock, the return value type is uint32_t.\n   * This attribute is deprecated. Use HSA_AMD_AGENT_INFO_MEMORY_MAX_FREQUENCY.\n   */\n  HSA_AMD_REGION_INFO_MAX_CLOCK_FREQUENCY = 0xA003,\n} hsa_amd_region_info_t;\n\n/**\n * @brief Coherency attributes of fine grain region.\n */\ntypedef enum hsa_amd_coherency_type_s {\n  /**\n   * Coherent region.\n   */\n  HSA_AMD_COHERENCY_TYPE_COHERENT = 0,\n  /**\n   * Non coherent region.\n   */\n  HSA_AMD_COHERENCY_TYPE_NONCOHERENT = 1\n} hsa_amd_coherency_type_t;\n\n\n/**\n * @brief dmabuf attributes\n */\n#ifdef __cplusplus\ntypedef enum hsa_amd_dma_buf_mapping_type_s : int {\n#else\ntypedef enum hsa_amd_dma_buf_mapping_type_s {\n#endif\n  HSA_AMD_DMABUF_MAPPING_TYPE_NONE = 0,\n  HSA_AMD_DMABUF_MAPPING_TYPE_PCIE = 1\n} hsa_amd_dma_buf_mapping_type_t;\n/**\n * @brief Get the coherency type of the fine grain region of an agent.\n *\n * @param[in] agent A valid agent.\n *\n * @param[out] type Pointer to a memory location where the HSA runtime will\n * store the coherency type of the fine grain region.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p type is NULL.\n */\nhsa_status_t HSA_API hsa_amd_coherency_get_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t* type);\n\n/**\n * @brief Set the coherency type of the fine grain region of an agent.\n * Deprecated.  This is supported on KV platforms.  For backward compatibility\n * other platforms will spuriously succeed.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] type The coherency type to be set.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p type is invalid.\n */\nhsa_status_t HSA_API hsa_amd_coherency_set_type(hsa_agent_t agent,\n                                                hsa_amd_coherency_type_t type);\n\n/** @} */\n\n/** \\defgroup profile Profiling\n *  @{\n */\n\n/**\n * @brief Structure containing profiling dispatch time information.\n *\n * Times are reported as ticks in the domain of the HSA system clock.\n * The HSA system clock tick and frequency is obtained via hsa_system_get_info.\n */\ntypedef struct hsa_amd_profiling_dispatch_time_s {\n  /**\n   * Dispatch packet processing start time.\n   */\n  uint64_t start;\n  /**\n   * Dispatch packet completion time.\n   */\n  uint64_t end;\n} hsa_amd_profiling_dispatch_time_t;\n\n/**\n * @brief Structure containing profiling async copy time information.\n *\n * Times are reported as ticks in the domain of the HSA system clock.\n * The HSA system clock tick and frequency is obtained via hsa_system_get_info.\n */\ntypedef struct hsa_amd_profiling_async_copy_time_s {\n  /**\n   * Async copy processing start time.\n   */\n  uint64_t start;\n  /**\n   * Async copy completion time.\n   */\n  uint64_t end;\n} hsa_amd_profiling_async_copy_time_t;\n\n/**\n * @brief Enable or disable profiling capability of a queue.\n *\n * @param[in] queue A valid queue.\n *\n * @param[in] enable 1 to enable profiling. 0 to disable profiling.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE The queue is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p queue is NULL.\n */\nhsa_status_t HSA_API\n    hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable);\n\n/**\n * @brief Enable or disable asynchronous memory copy profiling.\n *\n * @details The runtime will provide the copy processing start timestamp and\n * completion timestamp of each call to hsa_amd_memory_async_copy if the\n * async copy profiling is enabled prior to the call to\n * hsa_amd_memory_async_copy. The completion signal object is used to\n * hold the last async copy start and end timestamp. The client can retrieve\n * these timestamps via call to hsa_amd_profiling_get_async_copy_time.\n *\n * @param[in] enable True to enable profiling. False to disable profiling.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Failed on allocating resources\n * needed to profile the asynchronous copy.\n */\nhsa_status_t HSA_API\n    hsa_amd_profiling_async_copy_enable(bool enable);\n\n/**\n * @brief Retrieve packet processing time stamps.\n *\n * @param[in] agent The agent with which the signal was last used.  For\n * instance, if the profiled dispatch packet is dispatched onto queue Q,\n * which was created on agent A, then this parameter must be A.\n *\n * @param[in] signal A signal used as the completion signal of the dispatch\n * packet to retrieve time stamps from.  This dispatch packet must have been\n * issued to a queue with profiling enabled and have already completed.  Also\n * the signal must not have yet been used in any other packet following the\n * completion of the profiled dispatch packet.\n *\n * @param[out] time Packet processing timestamps in the HSA system clock\n * domain.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL The signal is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p time is NULL.\n */\nhsa_status_t HSA_API hsa_amd_profiling_get_dispatch_time(\n    hsa_agent_t agent, hsa_signal_t signal,\n    hsa_amd_profiling_dispatch_time_t* time);\n\n/**\n * @brief Retrieve asynchronous copy timestamps.\n *\n * @details Async copy profiling is enabled via call to\n * hsa_amd_profiling_async_copy_enable.\n *\n * @param[in] signal A signal used as the completion signal of the call to\n * hsa_amd_memory_async_copy.\n *\n * @param[out] time Async copy processing timestamps in the HSA system clock\n * domain.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL The signal is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p time is NULL.\n */\nhsa_status_t HSA_API hsa_amd_profiling_get_async_copy_time(\n    hsa_signal_t signal, hsa_amd_profiling_async_copy_time_t* time);\n\n/**\n * @brief Computes the frequency ratio and offset between the agent clock and\n * HSA system clock and converts the agent's tick to HSA system domain tick.\n *\n * @param[in] agent The agent used to retrieve the agent_tick. It is user's\n * responsibility to make sure the tick number is from this agent, otherwise,\n * the behavior is undefined.\n *\n * @param[in] agent_tick The tick count retrieved from the specified @p agent.\n *\n * @param[out] system_tick The translated HSA system domain clock counter tick.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p system_tick is NULL;\n */\nhsa_status_t HSA_API\n    hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent,\n                                                    uint64_t agent_tick,\n                                                    uint64_t* system_tick);\n\n/** @} */\n\n/** \\defgroup status Runtime notifications\n *  @{\n */\n\n/**\n * @brief Signal attribute flags.\n */\ntypedef enum {\n  /**\n   * Signal will only be consumed by AMD GPUs.  Limits signal consumption to\n   * AMD GPU agents only.  Ignored if @p num_consumers is not zero (all agents).\n   */\n  HSA_AMD_SIGNAL_AMD_GPU_ONLY = 1,\n  /**\n   * Signal may be used for interprocess communication.\n   * IPC signals can be read, written, and waited on from any process.\n   * Profiling using an IPC enabled signal is only supported in a single process\n   * at a time.  Producing profiling data in one process and consuming it in\n   * another process is undefined.\n   */\n  HSA_AMD_SIGNAL_IPC = 2,\n} hsa_amd_signal_attribute_t;\n\n/**\n * @brief Create a signal with specific attributes.\n *\n * @param[in] initial_value Initial value of the signal.\n *\n * @param[in] num_consumers Size of @p consumers. A value of 0 indicates that\n * any agent might wait on the signal.\n *\n * @param[in] consumers List of agents that might consume (wait on) the\n * signal. If @p num_consumers is 0, this argument is ignored; otherwise, the\n * HSA runtime might use the list to optimize the handling of the signal\n * object. If an agent not listed in @p consumers waits on the returned\n * signal, the behavior is undefined. The memory associated with @p consumers\n * can be reused or freed after the function returns.\n *\n * @param[in] attributes Requested signal attributes.  Multiple signal attributes\n * may be requested by combining them with bitwise OR.  Requesting no attributes\n * (@p attributes == 0) results in the same signal as would have been obtained\n * via hsa_signal_create.\n *\n * @param[out] signal Pointer to a memory location where the HSA runtime will\n * store the newly created signal handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p signal is NULL, @p\n * num_consumers is greater than 0 but @p consumers is NULL, or @p consumers\n * contains duplicates.\n */\nhsa_status_t HSA_API hsa_amd_signal_create(hsa_signal_value_t initial_value, uint32_t num_consumers,\n                                           const hsa_agent_t* consumers, uint64_t attributes,\n                                           hsa_signal_t* signal);\n\n/**\n * @brief Returns a pointer to the value of a signal.\n *\n * Use of this API does not modify the lifetime of ::signal and any\n * hsa_signal_value_t retrieved by this API has lifetime equal to that of\n * ::signal.\n *\n * This API is intended for partial interoperability with non-HSA compatible\n * devices and should not be used where HSA interfaces are available.\n *\n * Use of the signal value must comply with use restritions of ::signal.\n * Use may result in data races if the operations performed are not platform\n * atomic.  Use with HSA_AMD_SIGNAL_AMD_GPU_ONLY or HSA_AMD_SIGNAL_IPC\n * attributed signals is required.\n *\n * @param[in] Signal handle to extract the signal value pointer from.\n *\n * @param[out] Location where the extracted signal value pointer will be placed.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL signal is not a valid hsa_signal_t\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT value_ptr is NULL.\n */\nhsa_status_t hsa_amd_signal_value_pointer(hsa_signal_t signal,\n                                          volatile hsa_signal_value_t** value_ptr);\n\n/**\n * @brief Asyncronous signal handler function type.\n *\n * @details Type definition of callback function to be used with\n * hsa_amd_signal_async_handler. This callback is invoked if the associated\n * signal and condition are met. The callback receives the value of the signal\n * which satisfied the associated wait condition and a user provided value. If\n * the callback returns true then the callback will be called again if the\n * associated signal and condition are satisfied again. If the callback returns\n * false then it will not be called again.\n *\n * @param[in] value Contains the value of the signal observed by\n * hsa_amd_signal_async_handler which caused the signal handler to be invoked.\n *\n * @param[in] arg Contains the user provided value given when the signal handler\n * was registered with hsa_amd_signal_async_handler\n *\n * @retval true resumes monitoring the signal with this handler (as if calling\n * hsa_amd_signal_async_handler again with identical parameters)\n *\n * @retval false stops monitoring the signal with this handler (handler will\n * not be called again for this signal)\n *\n */\ntypedef bool (*hsa_amd_signal_handler)(hsa_signal_value_t value, void* arg);\n\n/**\n * @brief Register asynchronous signal handler function.\n *\n * @details Allows registering a callback function and user provided value with\n * a signal and wait condition. The callback will be invoked if the associated\n * signal and wait condition are satisfied. Callbacks will be invoked serially\n * but in an arbitrary order so callbacks should be independent of each other.\n * After being invoked a callback may continue to wait for its associated signal\n * and condition and, possibly, be invoked again. Or the callback may stop\n * waiting. If the callback returns true then it will continue waiting and may\n * be called again. If false then the callback will not wait again and will not\n * be called again for the associated signal and condition. It is possible to\n * register the same callback multiple times with the same or different signals\n * and/or conditions. Each registration of the callback will be treated entirely\n * independently.\n *\n * @param[in] signal hsa signal to be asynchronously monitored\n *\n * @param[in] cond condition value to monitor for\n *\n * @param[in] value signal value used in condition expression\n *\n * @param[in] handler asynchronous signal handler invoked when signal's\n * condition is met\n *\n * @param[in] arg user provided value which is provided to handler when handler\n * is invoked\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL signal is not a valid hsa_signal_t\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT handler is invalid (NULL)\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime is out of\n * resources or blocking signals are not supported by the HSA driver component.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_signal_async_handler(hsa_signal_t signal,\n                                 hsa_signal_condition_t cond,\n                                 hsa_signal_value_t value,\n                                 hsa_amd_signal_handler handler, void* arg);\n\n/**\n * @brief Wait for all signal-condition pairs to be satisfied.\n *\n * @details Allows waiting for all of several signal and condition pairs to be\n * satisfied. The function returns 0 if all signals met their conditions and -1\n * on a timeout. The value of each signal's satisfying value is returned in\n * satisfying_value unless satisfying_value is nullptr. NULL and invalid signals\n * are considered to have value 0 and their conditions already satisfied. This\n * function provides only relaxed memory semantics.\n */\nuint32_t HSA_API hsa_amd_signal_wait_all(uint32_t signal_count, hsa_signal_t* signals,\n                                         hsa_signal_condition_t* conds, hsa_signal_value_t* values,\n                                         uint64_t timeout_hint, hsa_wait_state_t wait_hint,\n                                         hsa_signal_value_t* satisfying_values);\n\n/**\n * @brief Wait for any signal-condition pair to be satisfied.\n *\n * @details Allows waiting for any of several signal and conditions pairs to be\n * satisfied. The function returns the index into the list of signals of the\n * first satisfying signal-condition pair. The function returns\n * std::numeric_limits<uint32_t>::max() if no valid signal is provided. The value\n * of the satisfying signal's value is returned in satisfying_value, unless\n * satisfying_value is nullptr or there's no valid signal in the signal-condition\n * pairs. NULL and invalid signals are ignored. This function provides only\n * relaxed memory semantics.\n */\nuint32_t HSA_API\n    hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* signals,\n                            hsa_signal_condition_t* conds,\n                            hsa_signal_value_t* values, uint64_t timeout_hint,\n                            hsa_wait_state_t wait_hint,\n                            hsa_signal_value_t* satisfying_value);\n\n/** @} */\n\n/**\n * @brief Call a function asynchronously\n *\n * @details Provides access to the runtime's asynchronous event handling thread\n * for general asynchronous functions.  Functions queued this way are executed\n * in the same manner as if they were a signal handler who's signal is\n * satisfied.\n *\n * @param[in] callback asynchronous function to be invoked\n *\n * @param[in] arg user provided value which is provided to handler when handler\n * is invoked\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT handler is invalid (NULL)\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime is out of\n * resources or blocking signals are not supported by the HSA driver component.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_async_function(void (*callback)(void* arg), void* arg);\n\n/** \\addtogroup ext-images Images and samplers\n *  @{\n */\n\n/**\n * @brief Encodes an opaque vendor specific image format.  The length of data\n * depends on the underlying format.  This structure must not be copied as its\n * true length can not be determined.\n */\ntypedef struct hsa_amd_image_descriptor_s {\n  /*\n  Version number of the descriptor\n  */\n  uint32_t version;\n\n  /*\n  Vendor and device PCI IDs for the format as VENDOR_ID<<16|DEVICE_ID.\n  */\n  uint32_t deviceID;\n\n  /*\n  Start of vendor specific data.\n  */\n  uint32_t data[1];\n} hsa_amd_image_descriptor_t;\n\n/**\n * @brief Creates an image from an opaque vendor specific image format.\n * Does not modify data at image_data.  Intended initially for\n * accessing interop images.\n *\n * @param agent[in] Agent on which to create the image\n *\n * @param[in] image_descriptor[in] Vendor specific image format\n *\n * @param[in] image_data Pointer to image backing store\n *\n * @param[in] access_permission Access permissions for the image object\n *\n * @param[out] image Created image object.\n *\n * @retval HSA_STATUS_SUCCESS Image created successfully\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT Bad or mismatched descriptor,\n * null image_data, or mismatched access_permission.\n */\nhsa_status_t HSA_API hsa_amd_image_create(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const hsa_amd_image_descriptor_t *image_layout,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_t *image\n);\n\n/**\n * @brief Query image limits.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] attribute HSA image info attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE @p value is NULL or @p attribute <\n * HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS or @p attribute >\n * HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS.\n *\n */\nhsa_status_t HSA_API hsa_amd_image_get_info_max_dim(hsa_agent_t agent,\n                                                    hsa_agent_info_t attribute,\n                                                    void* value);\n\n/** @} */\n\n/** \\addtogroup queue Queues\n *  @{\n */\n\n/**\n * @brief Set a queue's CU affinity mask.\n *\n * @details Enables the queue to run on only selected CUs.  The given mask is\n * combined by bitwise AND with any device wide mask in HSA_CU_MASK before\n * being applied.\n * If num_cu_mask_count is 0 then the request is interpreted as a request to\n * enable all CUs and no cu_mask array need be given.\n *\n * @param[in] queue A pointer to HSA queue.\n *\n * @param[in] num_cu_mask_count Size of CUMask bit array passed in, in bits.\n *\n * @param[in] cu_mask Bit-vector representing the CU mask.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_CU_MASK_REDUCED The function was successfully executed\n * but the given mask attempted to enable a CU which was disabled by\n * HSA_CU_MASK.  CUs disabled by HSA_CU_MASK remain disabled.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE @p queue is NULL or invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p num_cu_mask_count is not\n * a multiple of 32 or @p num_cu_mask_count is not 0 and cu_mask is NULL.\n * Devices with work group processors must even-index contiguous pairwise\n * CU enable e.g. 0x33(b'110011) is valid while 0x5(0x101) and 0x6(b'0110)\n * are invalid.\n *\n */\nhsa_status_t HSA_API hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue,\n                                               uint32_t num_cu_mask_count,\n                                               const uint32_t* cu_mask);\n\n/**\n * @brief Retrieve a queue's CU affinity mask.\n *\n * @details Returns the first num_cu_mask_count bits of a queue's CU mask.\n * Ensure that num_cu_mask_count is at least as large as\n * HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT to retrieve the entire mask.\n *\n * @param[in] queue A pointer to HSA queue.\n *\n * @param[in] num_cu_mask_count Size of CUMask bit array passed in, in bits.\n *\n * @param[out] cu_mask Bit-vector representing the CU mask.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_QUEUE @p queue is NULL or invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p num_cu_mask_count is 0, not\n * a multiple of 32 or @p cu_mask is NULL.\n *\n */\nhsa_status_t HSA_API hsa_amd_queue_cu_get_mask(const hsa_queue_t* queue, uint32_t num_cu_mask_count,\n                                               uint32_t* cu_mask);\n\n/** @} */\n\n/** \\addtogroup memory Memory\n *  @{\n */\n\n/**\n * @brief Memory segments associated with a memory pool.\n */\ntypedef enum {\n  /**\n   * Global segment. Used to hold data that is shared by all agents.\n   */\n  HSA_AMD_SEGMENT_GLOBAL = 0,\n  /**\n   * Read-only segment. Used to hold data that remains constant during the\n   * execution of a kernel.\n   */\n  HSA_AMD_SEGMENT_READONLY = 1,\n  /**\n   * Private segment. Used to hold data that is local to a single work-item.\n   */\n  HSA_AMD_SEGMENT_PRIVATE = 2,\n  /**\n   * Group segment. Used to hold data that is shared by the work-items of a\n   * work-group.\n   */\n  HSA_AMD_SEGMENT_GROUP = 3,\n} hsa_amd_segment_t;\n\n/**\n * @brief A memory pool encapsulates physical storage on an agent\n * along with a memory access model.\n *\n * @details A memory pool encapsulates a physical partition of an agent's\n * memory system along with a memory access model.  Division of a single\n * memory system into separate pools allows querying each partition's access\n * path properties (see ::hsa_amd_agent_memory_pool_get_info). Allocations\n * from a pool are preferentially bound to that pool's physical partition.\n * Binding to the pool's preferential physical partition may not be\n * possible or persistent depending on the system's memory policy\n * and/or state which is beyond the scope of HSA APIs.\n *\n * For example, a multi-node NUMA memory system may be represented by multiple\n * pool's with each pool providing size and access path information for the\n * partition it represents.  Allocations from a pool are preferentially bound\n * to the pool's partition (which in this example is a NUMA node) while\n * following its memory access model. The actual placement may vary or migrate\n * due to the system's NUMA policy and state, which is beyond the scope of\n * HSA APIs.\n */\ntypedef struct hsa_amd_memory_pool_s {\n  /**\n   * Opaque handle.\n   */\n  uint64_t handle;\n} hsa_amd_memory_pool_t;\n\ntypedef enum hsa_amd_memory_pool_global_flag_s {\n  /**\n   * The application can use allocations in the memory pool to store kernel\n   * arguments, and provide the values for the kernarg segment of\n   * a kernel dispatch.\n   */\n  HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT = 1,\n  /**\n   * Updates to memory in this pool conform to HSA memory consistency model.\n   * If this flag is set, then ::HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED\n   * must not be set.\n   */\n  HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED = 2,\n  /**\n   * Writes to memory in this pool can be performed by a single agent at a time.\n   */\n  HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED = 4,\n\n  /** Updates to memory in this memory pool have extended scope, acting as\n   * system-scope atomics for variables in memory regions of this type.\n   * Note: On non-compliant systems, device-specific actions may be required\n   * for system-scope coherence. */\n  HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_EXTENDED_SCOPE_FINE_GRAINED = 8,\n\n} hsa_amd_memory_pool_global_flag_t;\n\ntypedef enum hsa_amd_memory_pool_location_s {\n    /**\n     * This memory pool resides on the host (CPU)\n     */\n    HSA_AMD_MEMORY_POOL_LOCATION_CPU = 0,\n    /**\n     * This memory pool resides on a GPU\n     */\n    HSA_AMD_MEMORY_POOL_LOCATION_GPU = 1\n} hsa_amd_memory_pool_location_t;\n\n/**\n * @brief Memory pool features.\n */\ntypedef enum {\n  /**\n  * Segment where the memory pool resides. The type of this attribute is\n  * ::hsa_amd_segment_t.\n  */\n  HSA_AMD_MEMORY_POOL_INFO_SEGMENT = 0,\n  /**\n  * Flag mask. The value of this attribute is undefined if the value of\n  * ::HSA_AMD_MEMORY_POOL_INFO_SEGMENT is not ::HSA_AMD_SEGMENT_GLOBAL. The type\n  * of\n  * this attribute is uint32_t, a bit-field of\n  * ::hsa_amd_memory_pool_global_flag_t\n  * values.\n  */\n  HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS = 1,\n  /**\n  * Size of this pool, in bytes. The type of this attribute is size_t.\n  */\n  HSA_AMD_MEMORY_POOL_INFO_SIZE = 2,\n  /**\n  * Indicates whether memory in this pool can be allocated using\n  * ::hsa_amd_memory_pool_allocate. The type of this attribute is bool.\n  *\n  * The value of this flag is always false for memory pools in the group and\n  * private segments.\n  */\n  HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED = 5,\n  /**\n   * Allocation granularity of buffers allocated by\n   * ::hsa_amd_memory_pool_allocate\n   * in this memory pool. The size of a buffer allocated in this pool is a\n   * multiple of the value of this attribute. While this is the minimum size of\n   * allocation allowed, it is recommened to use\n   * HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE to obtain the recommended\n   * allocation granularity size for this pool.\n   * The value of this attribute is only defined if\n   * ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED is true for\n   * this pool. The type of this attribute is size_t.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE = 6,\n  /**\n   * Alignment of buffers allocated by ::hsa_amd_memory_pool_allocate in this\n   * pool. The value of this attribute is only defined if\n   * ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED is true for this pool, and\n   * must be a power of 2. The type of this attribute is size_t.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT = 7,\n  /**\n   * This memory_pool can be made directly accessible by all the agents in the\n   * system (::hsa_amd_agent_memory_pool_get_info does not return\n   * ::HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED for any agent). The type of this\n   * attribute is bool.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL = 15,\n  /**\n   * Maximum aggregate allocation size in bytes. The type of this attribute\n   * is size_t.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE = 16,\n  /**\n   * Location of this memory pool. The type of this attribute\n   * is hsa_amd_memory_pool_location_t.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_LOCATION = 17,\n  /**\n   * Internal block size for allocations. This would also be the recommended\n   * granularity size for allocations as this prevents internal fragmentation.\n   * The value of this attribute is only defined if\n   * ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED is true for this pool.\n   * The size of this attribute is size_t.\n   */\n  HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE = 18,\n} hsa_amd_memory_pool_info_t;\n\n/**\n * @brief Memory pool flag used to specify allocation directives\n *\n */\ntypedef enum hsa_amd_memory_pool_flag_s {\n  /**\n   * Allocates memory that conforms to standard HSA memory consistency model\n   */\n  HSA_AMD_MEMORY_POOL_STANDARD_FLAG = 0,\n  /**\n   * Allocates fine grain memory type where memory ordering is per point to point\n   * connection. Atomic memory operations on these memory buffers are not\n   * guaranteed to be visible at system scope.\n   */\n  HSA_AMD_MEMORY_POOL_PCIE_FLAG = (1 << 0),\n  /**\n   *  Allocates physically contiguous memory\n   */\n  HSA_AMD_MEMORY_POOL_CONTIGUOUS_FLAG = (1 << 1),\n  /**\n   *  Allocates executable memory\n   */\n  HSA_AMD_MEMORY_POOL_EXECUTABLE_FLAG = (1 << 2),\n\n} hsa_amd_memory_pool_flag_t;\n\n/**\n * @brief Get the current value of an attribute of a memory pool.\n *\n * @param[in] memory_pool A valid memory pool.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to a application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,\n                                 hsa_amd_memory_pool_info_t attribute,\n                                 void* value);\n\n/**\n * @brief Iterate over the memory pools associated with a given agent, and\n * invoke an application-defined callback on every iteration.\n *\n * @details An agent can directly access buffers located in some memory pool, or\n * be enabled to access them by the application (see ::hsa_amd_agents_allow_access),\n * yet that memory pool may not be returned by this function for that given\n * agent.\n *\n * A memory pool of fine-grained type must be associated only with the host.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] callback Callback to be invoked on the same thread that called\n * ::hsa_amd_agent_iterate_memory_pools, serially, once per memory pool that is\n * associated with the agent.  The HSA runtime passes two arguments to the\n * callback: the memory pool, and the application data.  If @p callback\n * returns a status other than ::HSA_STATUS_SUCCESS for a particular iteration,\n * the traversal stops and ::hsa_amd_agent_iterate_memory_pools returns that status\n * value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_amd_agent_iterate_memory_pools(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),\n    void* data);\n\n/**\n * @brief Allocate a block of memory (or buffer) in the specified pool.\n *\n * @param[in] memory_pool Memory pool where to allocate memory from. The memory\n * pool must have the ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED flag set.\n *\n * @param[in] size Allocation size, in bytes. Must not be zero. This value is\n * rounded up to the nearest multiple of\n * ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE in @p memory_pool.\n *\n * @param[in] flags A bit-field that is used to specify allocation\n * directives.\n *\n * @param[out] ptr Pointer to the location where to store the base virtual\n * address of\n * the allocated block. The returned base address is aligned to the value of\n * ::HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT in @p memory_pool. If the\n * allocation fails, the returned value is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES No memory is available.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_MEMORY_POOL The memory pool is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION The host is not allowed to\n * allocate memory in @p memory_pool, or @p size is greater than\n * the value of HSA_AMD_MEMORY_POOL_INFO_ALLOC_MAX_SIZE in @p memory_pool.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr is NULL, or @p size is 0,\n * or flags is not 0.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,\n                                 uint32_t flags, void** ptr);\n\n/**\n * @brief Deallocate a block of memory previously allocated using\n * ::hsa_amd_memory_pool_allocate.\n *\n * @param[in] ptr Pointer to a memory block. If @p ptr does not match a value\n * previously returned by ::hsa_amd_memory_pool_allocate, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n */\nhsa_status_t HSA_API hsa_amd_memory_pool_free(void* ptr);\n\n/**\n * @brief Asynchronously copy a block of memory from the location pointed to by\n * @p src on the @p src_agent to the memory block pointed to by @p dst on the @p\n * dst_agent.\n * Because the DMA engines used may not be in the same coherency domain, the caller must ensure\n * that buffers are system-level coherent. In general this requires the sending device to have\n * released the buffer to system scope prior to executing the copy API and the receiving device\n * must execute a system scope acquire fence prior to use of the destination buffer.\n *\n * @param[out] dst Buffer where the content is to be copied.\n *\n * @param[in] dst_agent Agent associated with the @p dst. The agent must be able to directly\n * access both the source and destination buffers in their current locations.\n * May be zero in which case the runtime will attempt to discover the destination agent.\n * Discovery may have variable and/or high latency.\n *\n * @param[in] src A valid pointer to the source of data to be copied. The source\n * buffer must not overlap with the destination buffer, otherwise the copy will succeed\n * but contents of @p dst is undefined.\n *\n * @param[in] src_agent Agent associated with the @p src. The agent must be able to directly\n * access both the source and destination buffers in their current locations.\n * May be zero in which case the runtime will attempt to discover the destination agent.\n * Discovery may have variable and/or high latency.\n *\n * @param[in] size Number of bytes to copy. If @p size is 0, no copy is\n * performed and the function returns success. Copying a number of bytes larger\n * than the size of the buffers pointed by @p dst or @p src results in undefined\n * behavior.\n *\n * @param[in] num_dep_signals Number of dependent signals. Can be 0.\n *\n * @param[in] dep_signals List of signals that must be waited on before the copy\n * operation starts. The copy will start after every signal has been observed with\n * the value 0. The dependent signal should not include completion signal from\n * hsa_amd_memory_async_copy operation to be issued in future as that can result\n * in a deadlock. If @p num_dep_signals is 0, this argument is ignored.\n *\n * @param[in] completion_signal Signal used to indicate completion of the copy\n * operation. When the copy operation is finished, the value of the signal is\n * decremented. The runtime indicates that an error has occurred during the copy\n * operation by setting the value of the completion signal to a negative\n * number. The signal handle must not be 0.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully. The\n * application is responsible for checking for asynchronous error conditions\n * (see the description of @p completion_signal).\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT An agent is invalid or no discovered agent has access.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_SIGNAL @p completion_signal is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT The source or destination\n * pointers are NULL, or the completion signal is 0.\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal);\n\n/**\n * @brief Asynchronously copy a block of memory from the location pointed to by\n * @p src on the @p src_agent to the memory block pointed to by @p dst on the @p\n * dst_agent on engine_id.\n *\n * WARNING: Concurrent use of this call with hsa_amd_memory_async_copy can result\n * in resource conflicts as HSA runtime will auto assign engines with the latter\n * call.  Approach using both calls concurrently with caution.\n *\n * All param definitions are identical to hsa_amd_memory_async_copy with the\n * exception of engine_id and force_copy_on_sdma.\n *\n * @param[in] - engine_id Target engine defined by hsa_amd_sdma_engine_id_t.\n * Client should use hsa_amd_memory_copy_engine_status first to get the ID\n * availability.\n *\n * @param[in] - force_copy_on_sdma By default, blit kernel copies are used when\n * dst_agent == src_agent.  Setting this to true will force the copy over SDMA1.\n *\n * All return definitions are identical to hsa_amd_memory_async_copy with the\n * following ammendments:\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT The source or destination\n * pointers are NULL, or the completion signal is 0 or engine_id is improperly\n * bounded.\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_async_copy_on_engine(void* dst, hsa_agent_t dst_agent, const void* src,\n                              hsa_agent_t src_agent, size_t size,\n                              uint32_t num_dep_signals,\n                              const hsa_signal_t* dep_signals,\n                              hsa_signal_t completion_signal,\n                              hsa_amd_sdma_engine_id_t engine_id,\n                              bool force_copy_on_sdma);\n/**\n * @brief Reports the availability of SDMA copy engines.\n *\n * @param[in] dst_agent Destination agent of copy status direction.\n *\n * @param[in] src_agent Source agent of copy status direction.\n *\n * @param[out] engine_ids_mask returns available SDMA engine IDs that can be masked\n * with hsa_amd_sdma_engine_id_t.\n *\n * @retval ::HSA_STATUS_SUCCESS Agent has available SDMA engines.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Agent does not have available SDMA engines.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT dst_agent and src_agent are the same as\n * dst_agent == src_agent is generally used for shader copies.\n */\nhsa_status_t HSA_API\nhsa_amd_memory_copy_engine_status(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                      uint32_t *engine_ids_mask);\n /**\n * @brief Returns the preferred SDMA engine mask.\n *\n * @param[in] dst_agent Destination agent of copy status direction.\n *\n * @param[in] src_agent Source agent of copy status direction.\n *\n * @param[out] recommended_ids_mask returns available SDMA engine IDs for max bandwidth\n * that can be masked with hsa_amd_sdma_engine_id_t. Can be 0 if there is no preference\n *\n * @retval ::HSA_STATUS_SUCCESS For mask returned\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT dst_agent and src_agent are the same as\n * dst_agent == src_agent is generally used for shader copies.\n */\nhsa_status_t HSA_API\nhsa_amd_memory_get_preferred_copy_engine(hsa_agent_t dst_agent, hsa_agent_t src_agent,\n                                         uint32_t* recommended_ids_mask);\n\n/*\n[Provisional API]\nPitched memory descriptor.\nAll elements must be 4 byte aligned.  Pitch and slice are in bytes.\n*/\ntypedef struct hsa_pitched_ptr_s {\n  void* base;\n  size_t pitch;\n  size_t slice;\n} hsa_pitched_ptr_t;\n\n/*\n[Provisional API]\nCopy direction flag.\n*/\ntypedef enum {\n  hsaHostToHost = 0,\n  hsaHostToDevice = 1,\n  hsaDeviceToHost = 2,\n  hsaDeviceToDevice = 3\n} hsa_amd_copy_direction_t;\n\n/*\n[Provisional API]\nSDMA 3D memory copy API.  The same requirements must be met by src and dst as in\nhsa_amd_memory_async_copy.\nBoth src and dst must be directly accessible to the copy_agent during the copy, src and dst rects\nmust not overlap.\nCPU agents are not supported.  API requires SDMA and will return an error if SDMA is not available.\nOffsets and range carry x in bytes, y and z in rows and layers.\n*/\nhsa_status_t HSA_API hsa_amd_memory_async_copy_rect(\n    const hsa_pitched_ptr_t* dst, const hsa_dim3_t* dst_offset, const hsa_pitched_ptr_t* src,\n    const hsa_dim3_t* src_offset, const hsa_dim3_t* range, hsa_agent_t copy_agent,\n    hsa_amd_copy_direction_t dir, uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n    hsa_signal_t completion_signal);\n\n/**\n * @brief Type of accesses to a memory pool from a given agent.\n */\ntypedef enum {\n  /**\n  * The agent cannot directly access any buffer in the memory pool.\n  */\n  HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED = 0,\n  /**\n  * The agent can directly access a buffer located in the pool; the application\n  * does not need to invoke ::hsa_amd_agents_allow_access.\n  */\n  HSA_AMD_MEMORY_POOL_ACCESS_ALLOWED_BY_DEFAULT = 1,\n  /**\n  * The agent can directly access a buffer located in the pool, but only if the\n  * application has previously requested access to that buffer using\n  * ::hsa_amd_agents_allow_access.\n  */\n  HSA_AMD_MEMORY_POOL_ACCESS_DISALLOWED_BY_DEFAULT = 2\n} hsa_amd_memory_pool_access_t;\n\n/**\n * @brief Properties of the relationship between an agent a memory pool.\n */\ntypedef enum {\n  /**\n  * Hyper-transport bus type.\n  */\n  HSA_AMD_LINK_INFO_TYPE_HYPERTRANSPORT = 0,\n\n  /**\n  * QPI bus type.\n  */\n  HSA_AMD_LINK_INFO_TYPE_QPI = 1,\n\n  /**\n  * PCIe bus type.\n  */\n  HSA_AMD_LINK_INFO_TYPE_PCIE = 2,\n\n  /**\n  * Infiniband bus type.\n  */\n  HSA_AMD_LINK_INFO_TYPE_INFINBAND = 3,\n\n  /**\n  * xGMI link type.\n  */\n  HSA_AMD_LINK_INFO_TYPE_XGMI = 4\n\n} hsa_amd_link_info_type_t;\n\n/**\n * @brief Link properties when accessing the memory pool from the specified\n * agent.\n */\ntypedef struct hsa_amd_memory_pool_link_info_s {\n  /**\n  * Minimum transfer latency (rounded to ns).\n  */\n  uint32_t min_latency;\n\n  /**\n  * Maximum transfer latency (rounded to ns).\n  */\n  uint32_t max_latency;\n\n  /**\n  * Minimum link interface bandwidth in MB/s.\n  */\n  uint32_t min_bandwidth;\n\n  /**\n  * Maximum link interface bandwidth in MB/s.\n  */\n  uint32_t max_bandwidth;\n\n  /**\n  * Support for 32-bit atomic transactions.\n  */\n  bool atomic_support_32bit;\n\n  /**\n  * Support for 64-bit atomic transactions.\n  */\n  bool atomic_support_64bit;\n\n  /**\n  * Support for cache coherent transactions.\n  */\n  bool coherent_support;\n\n  /**\n  * The type of bus/link.\n  */\n  hsa_amd_link_info_type_t link_type;\n\n  /**\n   * NUMA distance of memory pool relative to querying agent\n   */\n  uint32_t numa_distance;\n} hsa_amd_memory_pool_link_info_t;\n\n/**\n * @brief Properties of the relationship between an agent a memory pool.\n */\ntypedef enum {\n  /**\n  * Access to buffers located in the memory pool. The type of this attribute\n  * is ::hsa_amd_memory_pool_access_t.\n  *\n  * An agent can always directly access buffers currently located in a memory\n  * pool that is associated (the memory_pool is one of the values returned by\n  * ::hsa_amd_agent_iterate_memory_pools on the agent) with that agent. If the\n  * buffer is currently located in a memory pool that is not associated with\n  * the agent, and the value returned by this function for the given\n  * combination of agent and memory pool is not\n  * HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED, the application still needs to invoke\n  * ::hsa_amd_agents_allow_access in order to gain direct access to the buffer.\n  *\n  * If the given agent can directly access buffers the pool, the result is not\n  * HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED. If the memory pool is associated with\n  * the agent, or it is of fined-grained type, the result must not be\n  * HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED. If the memory pool is not associated\n  * with the agent, and does not reside in the global segment, the result must\n  * be HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED.\n  */\n  HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS = 0,\n\n  /**\n  * Number of links to hop when accessing the memory pool from the specified\n  * agent. The value of this attribute is zero if the memory pool is associated\n  * with the agent, or if the access type is\n  * HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED. The type of this attribute is\n  * uint32_t.\n  */\n  HSA_AMD_AGENT_MEMORY_POOL_INFO_NUM_LINK_HOPS = 1,\n\n  /**\n  * Details of each link hop when accessing the memory pool starting from the\n  * specified agent. The type of this attribute is an array size of\n  * HSA_AMD_AGENT_MEMORY_POOL_INFO_NUM_LINK_HOPS with each element containing\n  * ::hsa_amd_memory_pool_link_info_t.\n  */\n  HSA_AMD_AGENT_MEMORY_POOL_INFO_LINK_INFO = 2\n\n} hsa_amd_agent_memory_pool_info_t;\n\n/**\n * @brief Get the current value of an attribute of the relationship between an\n * agent and a memory pool.\n *\n * @param[in] agent Agent.\n *\n * @param[in] memory_pool Memory pool.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to a application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n */\nhsa_status_t HSA_API hsa_amd_agent_memory_pool_get_info(\n    hsa_agent_t agent, hsa_amd_memory_pool_t memory_pool,\n    hsa_amd_agent_memory_pool_info_t attribute, void* value);\n\n/**\n * @brief Enable direct access to a buffer from a given set of agents.\n *\n * @details\n *\n * Upon return, only the listed agents and the agent associated with the\n * buffer's memory pool have direct access to the @p ptr.\n *\n * Any agent that has access to the buffer before and after the call to\n * ::hsa_amd_agents_allow_access will also have access while\n * ::hsa_amd_agents_allow_access is in progress.\n *\n * The caller is responsible for ensuring that each agent in the list\n * must be able to access the memory pool containing @p ptr\n * (using ::hsa_amd_agent_memory_pool_get_info with ::HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS attribute),\n * otherwise error code is returned.\n *\n * @param[in] num_agents Size of @p agents.\n *\n * @param[in] agents List of agents. If @p num_agents is 0, this argument is\n * ignored.\n *\n * @param[in] flags A list of bit-field that is used to specify access\n * information in a per-agent basis. This is currently reserved and must be NULL.\n *\n * @param[in] ptr A buffer previously allocated using ::hsa_amd_memory_pool_allocate.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p num_agents is 0, or @p agents\n * is NULL, @p flags is not NULL, or attempting to enable access to agent(s)\n * because @p ptr is allocated from an inaccessible pool.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,\n                                const uint32_t* flags, const void* ptr);\n\n/**\n * @brief Query if buffers currently located in some memory pool can be\n * relocated to a destination memory pool.\n *\n * @details If the returned value is non-zero, a migration of a buffer to @p\n * dst_memory_pool using ::hsa_amd_memory_migrate may nevertheless fail due to\n * resource limitations.\n *\n * @param[in] src_memory_pool Source memory pool.\n *\n * @param[in] dst_memory_pool Destination memory pool.\n *\n * @param[out] result Pointer to a memory location where the result of the query\n * is stored. Must not be NULL. If buffers currently located in @p\n * src_memory_pool can be relocated to @p dst_memory_pool, the result is\n * true.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_MEMORY_POOL One of the memory pools is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p result is NULL.\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,\n                                    hsa_amd_memory_pool_t dst_memory_pool,\n                                    bool* result);\n\n/**\n * @brief Relocate a buffer to a new memory pool.\n *\n * @details When a buffer is migrated, its virtual address remains the same but\n * its physical contents are moved to the indicated memory pool.\n *\n * After migration, only the agent associated with the destination pool will have access.\n *\n * The caller is also responsible for ensuring that the allocation in the\n * source memory pool where the buffer is currently located can be migrated to the\n * specified destination memory pool (using ::hsa_amd_memory_pool_can_migrate returns a value of true\n * for the source and destination memory pools), otherwise behavior is undefined.\n *\n * The caller must ensure that the buffer is not accessed while it is migrated.\n *\n * @param[in] ptr Buffer to be relocated. The buffer must have been released to system\n * prior to call this API.  The buffer will be released to system upon completion.\n *\n * @param[in] memory_pool Memory pool where to place the buffer.\n *\n * @param[in] flags A bit-field that is used to specify migration\n * information. Must be zero.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_MEMORY_POOL The destination memory pool is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure in\n * allocating the necessary resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p flags is not 0.\n */\nhsa_status_t HSA_API hsa_amd_memory_migrate(const void* ptr,\n                                            hsa_amd_memory_pool_t memory_pool,\n                                            uint32_t flags);\n\n/**\n *\n * @brief Pin a host pointer allocated by C/C++ or OS allocator (i.e. ordinary system DRAM) and\n * return a new pointer accessible by the @p agents. If the @p host_ptr overlaps with previously\n * locked memory, then the overlap area is kept locked (i.e multiple mappings are permitted). In\n * this case, the same input @p host_ptr may give different locked @p agent_ptr and when it does,\n * they are not necessarily coherent (i.e. accessing either @p agent_ptr is not equivalent).\n * Accesses to @p agent_ptr are coarse grained.\n *\n * @param[in] host_ptr A buffer allocated by C/C++ or OS allocator.\n *\n * @param[in] size The size to be locked.\n *\n * @param[in] agents Array of agent handle to gain access to the @p host_ptr.\n * If this parameter is NULL and the @p num_agent is 0, all agents\n * in the platform will gain access to the @p host_ptr.\n *\n * @param[out] agent_ptr Pointer to the location where to store the new address.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure in\n * allocating the necessary resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT One or more agent in @p agents is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p size is 0 or @p host_ptr or\n * @p agent_ptr is NULL or @p agents not NULL but @p num_agent is 0 or @p agents\n * is NULL but @p num_agent is not 0.\n */\nhsa_status_t HSA_API hsa_amd_memory_lock(void* host_ptr, size_t size,\n                                         hsa_agent_t* agents, int num_agent,\n                                         void** agent_ptr);\n\n/**\n *\n * @brief Pin a host pointer allocated by C/C++ or OS allocator (i.e. ordinary system DRAM) and\n * return a new pointer accessible by the @p agents. If the @p host_ptr overlaps with previously\n * locked memory, then the overlap area is kept locked (i.e. multiple mappings are permitted).\n * In this case, the same input @p host_ptr may give different locked @p agent_ptr and when it\n * does, they are not necessarily coherent (i.e. accessing either @p agent_ptr is not equivalent).\n * Acesses to the memory via @p agent_ptr have the same access properties as memory allocated from\n * @p pool as determined by ::hsa_amd_memory_pool_get_info and ::hsa_amd_agent_memory_pool_get_info\n * (ex. coarse/fine grain, platform atomic support, link info).  Physical composition and placement\n * of the memory (ex. page size, NUMA binding) is not changed.\n *\n * @param[in] host_ptr A buffer allocated by C/C++ or OS allocator.\n *\n * @param[in] size The size to be locked.\n *\n * @param[in] agents Array of agent handle to gain access to the @p host_ptr.\n * If this parameter is NULL and the @p num_agent is 0, all agents\n * in the platform will gain access to the @p host_ptr.\n *\n * @param[in] pool Global memory pool owned by a CPU agent.\n *\n * @param[in] flags A bit-field that is used to specify allocation\n * directives. Reserved parameter, must be 0.\n *\n * @param[out] agent_ptr Pointer to the location where to store the new address.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure in\n * allocating the necessary resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT One or more agent in @p agents is\n * invalid or can not access @p pool.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_MEMORY_POOL @p pool is invalid or not owned\n * by a CPU agent.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p size is 0 or @p host_ptr or\n * @p agent_ptr is NULL or @p agents not NULL but @p num_agent is 0 or @p agents\n * is NULL but @p num_agent is not 0 or flags is not 0.\n */\nhsa_status_t HSA_API hsa_amd_memory_lock_to_pool(void* host_ptr, size_t size, hsa_agent_t* agents,\n                                                 int num_agent, hsa_amd_memory_pool_t pool,\n                                                 uint32_t flags, void** agent_ptr);\n\n/**\n *\n * @brief Unpin the host pointer previously pinned via ::hsa_amd_memory_lock or\n * ::hsa_amd_memory_lock_to_pool.\n *\n * @details The behavior is undefined if the host pointer being unpinned does not\n * match previous pinned address or if the host pointer was already deallocated.\n *\n * @param[in] host_ptr A buffer allocated by C/C++ or OS allocator that was\n * pinned previously via ::hsa_amd_memory_lock or ::hsa_amd_memory_lock_to_pool.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n */\nhsa_status_t HSA_API hsa_amd_memory_unlock(void* host_ptr);\n\n/**\n * @brief Sets the first @p count of uint32_t of the block of memory pointed by\n * @p ptr to the specified @p value.\n *\n * @param[in] ptr Pointer to the block of memory to fill.\n *\n * @param[in] value Value to be set.\n *\n * @param[in] count Number of uint32_t element to be set to the value.\n *\n * @retval HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr is NULL or\n * not 4 bytes aligned\n *\n * @retval HSA_STATUS_ERROR_INVALID_ALLOCATION if the given memory\n * region was not allocated with HSA runtime APIs.\n *\n */\nhsa_status_t HSA_API\n    hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count);\n\n/**\n * @brief Maps an interop object into the HSA flat address space and establishes\n * memory residency.  The metadata pointer is valid during the lifetime of the\n * map (until hsa_amd_interop_unmap_buffer is called).\n * Multiple calls to hsa_amd_interop_map_buffer with the same interop_handle\n * result in multiple mappings with potentially different addresses and\n * different metadata pointers.  Concurrent operations on these addresses are\n * not coherent.  Memory must be fenced to system scope to ensure consistency,\n * between mappings and with any views of this buffer in the originating\n * software stack.\n *\n * @param[in] num_agents Number of agents which require access to the memory\n *\n * @param[in] agents List of accessing agents.\n *\n * @param[in] interop_handle Handle of interop buffer (dmabuf handle in Linux)\n *\n * @param [in] flags Reserved, must be 0\n *\n * @param[out] size Size in bytes of the mapped object\n *\n * @param[out] ptr Base address of the mapped object\n *\n * @param[out] metadata_size Size of metadata in bytes, may be NULL\n *\n * @param[out] metadata Pointer to metadata, may be NULL\n *\n * @retval HSA_STATUS_SUCCESS if successfully mapped\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT all other errors\n */\nhsa_status_t HSA_API hsa_amd_interop_map_buffer(uint32_t num_agents,\n                                        hsa_agent_t* agents,\n                                        int interop_handle,\n                                        uint32_t flags,\n                                        size_t* size,\n                                        void** ptr,\n                                        size_t* metadata_size,\n                                        const void** metadata);\n\n/**\n * @brief Removes a previously mapped interop object from HSA's flat address space.\n * Ends lifetime for the mapping's associated metadata pointer.\n */\nhsa_status_t HSA_API hsa_amd_interop_unmap_buffer(void* ptr);\n\n/**\n * @brief Denotes the type of memory in a pointer info query.\n */\ntypedef enum {\n  /*\n  Memory is not known to the HSA driver.  Unallocated or unlocked system memory.\n  */\n  HSA_EXT_POINTER_TYPE_UNKNOWN = 0,\n  /*\n  Memory was allocated with an HSA memory allocator.\n  */\n  HSA_EXT_POINTER_TYPE_HSA = 1,\n  /*\n  System memory which has been locked for use with an HSA agent.\n\n  Memory of this type is normal malloc'd memory and is always accessible to\n  the CPU.  Pointer info queries may not include CPU agents in the accessible\n  agents list as the CPU has implicit access.\n  */\n  HSA_EXT_POINTER_TYPE_LOCKED = 2,\n  /*\n  Memory originated in a graphics component and is shared with ROCr.\n  */\n  HSA_EXT_POINTER_TYPE_GRAPHICS = 3,\n  /*\n  Memory has been shared with the local process via ROCr IPC APIs.\n  */\n  HSA_EXT_POINTER_TYPE_IPC = 4,\n  /*\n  No backend memory but virtual address\n  */\n  HSA_EXT_POINTER_TYPE_RESERVED_ADDR = 5\n} hsa_amd_pointer_type_t;\n\n/**\n * @brief Describes a memory allocation known to ROCr.\n * Within a ROCr major version this structure can only grow.\n */\ntypedef struct hsa_amd_pointer_info_s {\n  /*\n  Size in bytes of this structure.  Used for version control within a major ROCr\n  revision.  Set to sizeof(hsa_amd_pointer_t) prior to calling\n  hsa_amd_pointer_info.  If the runtime supports an older version of pointer\n  info then size will be smaller on return.  Members starting after the return\n  value of size will not be updated by hsa_amd_pointer_info.\n  */\n  uint32_t size;\n  /*\n  The type of allocation referenced.\n  */\n  hsa_amd_pointer_type_t type;\n  /*\n  Base address at which non-host agents may access the allocation. This field is\n  not meaningful if the type of the allocation is HSA_EXT_POINTER_TYPE_UNKNOWN.\n  */\n  void* agentBaseAddress;\n  /*\n  Base address at which the host agent may access the allocation. This field is\n  not meaningful if the type of the allocation is HSA_EXT_POINTER_TYPE_UNKNOWN.\n  */\n  void* hostBaseAddress;\n  /*\n  Size of the allocation. This field is not meaningful if the type of the allocation\n  is HSA_EXT_POINTER_TYPE_UNKNOWN.\n  */\n  size_t sizeInBytes;\n  /*\n  Application provided value. This field is not meaningful if the type of the\n  allocation is HSA_EXT_POINTER_TYPE_UNKNOWN.\n  */\n  void* userData;\n  /*\n  Reports an agent which \"owns\" (ie has preferred access to) the pool in which the\n  allocation was\n  made.  When multiple agents share equal access to a pool (ex: multiple CPU agents, or multi-die\n  GPU boards) any such agent may be returned. This field is not meaningful if\n  the type of the allocation is HSA_EXT_POINTER_TYPE_UNKNOWN or if this agent is not available in\n  this process, for e.g if this agent is masked using ROCR_VISIBLE_DEVICES.\n  */\n  hsa_agent_t agentOwner;\n  /*\n  Contains a bitfield of hsa_amd_memory_pool_global_flag_t values.\n  Reports the effective global flags bitmask for the allocation.  This field is not\n  meaningful if the type of the allocation is HSA_EXT_POINTER_TYPE_UNKNOWN.\n  */\n  uint32_t global_flags;\n} hsa_amd_pointer_info_t;\n\n/**\n * @brief Retrieves information about the allocation referenced by the given\n * pointer.  Optionally returns the number and list of agents which can\n * directly access the allocation. In case this virtual address is unknown, the\n * pointer type returned will be HSA_EXT_POINTER_TYPE_UNKNOWN and the only fields\n * that are valid after hsa_amd_pointer_info returns are size and type.\n *\n * @param[in] ptr Pointer which references the allocation to retrieve info for.\n *\n * @param[in, out] info Pointer to structure to be filled with allocation info.\n * Data member size must be set to the size of the structure prior to calling\n * hsa_amd_pointer_info.  On return size will be set to the size of the\n * pointer info structure supported by the runtime, if smaller.  Members\n * beyond the returned value of size will not be updated by the API.\n * Must not be NULL.\n *\n * @param[in] alloc Function pointer to an allocator used to allocate the\n * @p accessible array.  If NULL @p accessible will not be returned.\n *\n * @param[out] num_agents_accessible Recieves the count of agents in\n * @p accessible.  If NULL @p accessible will not be returned.\n *\n * @param[out] accessible Recieves a pointer to the array, allocated by @p alloc,\n * holding the list of agents which may directly access the allocation.\n * May be NULL.\n *\n * @retval HSA_STATUS_SUCCESS Info retrieved successfully\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT NULL in @p ptr or @p info.\n */\nhsa_status_t HSA_API hsa_amd_pointer_info(const void* ptr,\n                                          hsa_amd_pointer_info_t* info,\n                                          void* (*alloc)(size_t),\n                                          uint32_t* num_agents_accessible,\n                                          hsa_agent_t** accessible);\n\n/**\n * @brief Associates an arbitrary pointer with an allocation known to ROCr.\n * The pointer can be fetched by hsa_amd_pointer_info in the userData field.\n *\n * @param[in] ptr Pointer to the first byte of an allocation known to ROCr\n * with which to associate @p userdata.\n *\n * @param[in] userdata Abitrary pointer to associate with the allocation.\n *\n * @retval HSA_STATUS_SUCCESS @p userdata successfully stored.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr is not known to ROCr.\n */\nhsa_status_t HSA_API hsa_amd_pointer_info_set_userdata(const void* ptr,\n                                                       void* userdata);\n\n/**\n * @brief 256-bit process independent identifier for a ROCr shared memory\n * allocation.\n */\ntypedef struct hsa_amd_ipc_memory_s {\n  uint32_t handle[8];\n} hsa_amd_ipc_memory_t;\n\n/**\n * @brief Prepares an allocation for interprocess sharing and creates a\n * handle of type hsa_amd_ipc_memory_t uniquely identifying the allocation.  A\n * handle is valid while the allocation it references remains accessible in\n * any process.  In general applications should confirm that a shared memory\n * region has been attached (via hsa_amd_ipc_memory_attach) in the remote\n * process prior to releasing that memory in the local process.\n * Repeated calls for the same allocation may, but are not required to, return\n * unique handles. The allocation needs to be on memory on an agent of type\n * HSA_DEVICE_TYPE_GPU.\n *\n * @param[in] ptr Pointer to device memory allocated via ROCr APIs to prepare for\n * sharing.\n *\n * @param[in] len Length in bytes of the allocation to share.\n *\n * @param[out] handle Process independent identifier referencing the shared\n * allocation.\n *\n * @retval HSA_STATUS_SUCCESS allocation is prepared for interprocess sharing.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p ptr does not point to the\n * first byte of an allocation made through ROCr, or len is not the full length\n * of the allocation or handle is NULL.\n */\nhsa_status_t HSA_API hsa_amd_ipc_memory_create(void* ptr, size_t len,\n                                               hsa_amd_ipc_memory_t* handle);\n\n/**\n * @brief Imports shared memory into the local process and makes it accessible\n * by the given agents.  If a shared memory handle is attached multiple times\n * in a process each attach may return a different address.  Each returned\n * address is refcounted and requires a matching number of calls to\n * hsa_amd_ipc_memory_detach to release the shared memory mapping.\n *\n * @param[in] handle Pointer to the identifier for the shared memory.\n *\n * @param[in] len Length of the shared memory to import.\n * Reserved.  Must be the full length of the shared allocation in this version.\n *\n * @param[in] num_agents Count of agents in @p mapping_agents.\n * May be zero if all agents are to be allowed access.\n *\n * @param[in] mapping_agents List of agents to access the shared memory.\n * Ignored if @p num_agents is zero.\n *\n * @param[out] mapped_ptr Recieves a process local pointer to the shared memory.\n *\n * @retval HSA_STATUS_SUCCESS if memory is successfully imported.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p handle is not valid, @p len is\n * incorrect, @p mapped_ptr is NULL, or some agent for which access was\n * requested can not access the shared memory.\n */\nhsa_status_t HSA_API hsa_amd_ipc_memory_attach(\n    const hsa_amd_ipc_memory_t* handle, size_t len,\n    uint32_t num_agents,\n    const hsa_agent_t* mapping_agents,\n    void** mapped_ptr);\n\n/**\n * @brief Decrements the reference count for the shared memory mapping and\n * releases access to shared memory imported with hsa_amd_ipc_memory_attach.\n *\n * @param[in] mapped_ptr Pointer to the first byte of a shared allocation\n * imported with hsa_amd_ipc_memory_attach.\n *\n * @retval HSA_STATUS_SUCCESS if @p mapped_ptr was imported with\n * hsa_amd_ipc_memory_attach.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p mapped_ptr was not imported\n * with hsa_amd_ipc_memory_attach.\n */\nhsa_status_t HSA_API hsa_amd_ipc_memory_detach(void* mapped_ptr);\n\n/** @} */\n\n/** \\addtogroup status Runtime notifications\n *  @{\n */\n\n/**\n * @brief 256-bit process independent identifier for a ROCr IPC signal.\n */\ntypedef hsa_amd_ipc_memory_t hsa_amd_ipc_signal_t;\n\n/**\n * @brief Obtains an interprocess sharing handle for a signal.  The handle is\n * valid while the signal it references remains valid in any process.  In\n * general applications should confirm that the signal has been attached (via\n * hsa_amd_ipc_signal_attach) in the remote process prior to destroying that\n * signal in the local process.\n * Repeated calls for the same signal may, but are not required to, return\n * unique handles.\n *\n * @param[in] signal Signal created with attribute HSA_AMD_SIGNAL_IPC.\n *\n * @param[out] handle Process independent identifier referencing the shared\n * signal.\n *\n * @retval HSA_STATUS_SUCCESS @p handle is ready to use for interprocess sharing.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p signal is not a valid signal\n * created with attribute HSA_AMD_SIGNAL_IPC or handle is NULL.\n */\nhsa_status_t HSA_API hsa_amd_ipc_signal_create(hsa_signal_t signal, hsa_amd_ipc_signal_t* handle);\n\n/**\n * @brief Imports an IPC capable signal into the local process.  If an IPC\n * signal handle is attached multiple times in a process each attach may return\n * a different signal handle.  Each returned signal handle is refcounted and\n * requires a matching number of calls to hsa_signal_destroy to release the\n * shared signal.\n *\n * @param[in] handle Pointer to the identifier for the shared signal.\n *\n * @param[out] signal Recieves a process local signal handle to the shared signal.\n *\n * @retval HSA_STATUS_SUCCESS if the signal is successfully imported.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED if HSA is not initialized\n *\n * @retval HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p handle is not valid.\n */\nhsa_status_t HSA_API hsa_amd_ipc_signal_attach(const hsa_amd_ipc_signal_t* handle,\n                                               hsa_signal_t* signal);\n\n/**\n * @brief GPU system event type.\n */\ntypedef enum hsa_amd_event_type_s {\n  /*\n   AMD GPU memory fault.\n   */\n  HSA_AMD_GPU_MEMORY_FAULT_EVENT = 0,\n  /*\n   AMD GPU HW Exception.\n   */\n  HSA_AMD_GPU_HW_EXCEPTION_EVENT,\n  /*\n   AMD GPU memory error.\n   */\n  HSA_AMD_GPU_MEMORY_ERROR_EVENT,\n} hsa_amd_event_type_t;\n\n/**\n * @brief Flags denoting the cause of a memory fault.\n */\ntypedef enum {\n  // Page not present or supervisor privilege.\n  HSA_AMD_MEMORY_FAULT_PAGE_NOT_PRESENT = 1 << 0,\n  // Write access to a read-only page.\n  HSA_AMD_MEMORY_FAULT_READ_ONLY = 1 << 1,\n  // Execute access to a page marked NX.\n  HSA_AMD_MEMORY_FAULT_NX = 1 << 2,\n  // GPU attempted access to a host only page.\n  HSA_AMD_MEMORY_FAULT_HOST_ONLY = 1 << 3,\n  // DRAM ECC failure.\n  HSA_AMD_MEMORY_FAULT_DRAMECC = 1 << 4,\n  // Can't determine the exact fault address.\n  HSA_AMD_MEMORY_FAULT_IMPRECISE = 1 << 5,\n  // SRAM ECC failure (ie registers, no fault address).\n  HSA_AMD_MEMORY_FAULT_SRAMECC = 1 << 6,\n  // GPU reset following unspecified hang.\n  HSA_AMD_MEMORY_FAULT_HANG = 1U << 31\n} hsa_amd_memory_fault_reason_t;\n\n/**\n * @brief AMD GPU memory fault event data.\n */\ntypedef struct hsa_amd_gpu_memory_fault_info_s {\n  /*\n  The agent where the memory fault occurred.\n  */\n  hsa_agent_t agent;\n  /*\n  Virtual address accessed.\n  */\n  uint64_t virtual_address;\n  /*\n  Bit field encoding the memory access failure reasons. There could be multiple bits set\n  for one fault.  Bits are defined in hsa_amd_memory_fault_reason_t.\n  */\n  uint32_t fault_reason_mask;\n} hsa_amd_gpu_memory_fault_info_t;\n\n/**\n * @brief Flags denoting the cause of a memory error.\n */\ntypedef enum {\n  // Memory was in use by low-level HW component and cannot be released\n  HSA_AMD_MEMORY_ERROR_MEMORY_IN_USE = (1 << 0),\n} hsa_amd_memory_error_reason_t;\n\n/**\n * @brief AMD GPU memory error event data.\n */\ntypedef struct hsa_amd_gpu_memory_error_info_s {\n  /*\n  The agent where the memory error occurred.\n  */\n  hsa_agent_t agent;\n  /*\n  Virtual address involved.\n  */\n  uint64_t virtual_address;\n  /*\n  Bit field encoding the memory error failure reasons. There could be multiple bits set\n  for one error.  Bits are defined in hsa_amd_memory_error_reason_t.\n  */\n  uint32_t error_reason_mask;\n} hsa_amd_gpu_memory_error_info_t;\n\n/**\n * @brief Flags denoting the type of a HW exception\n */\ntypedef enum {\n  // Unused for now\n  HSA_AMD_HW_EXCEPTION_RESET_TYPE_OTHER = 1 << 0,\n} hsa_amd_hw_exception_reset_type_t;\n\n/**\n * @brief Flags denoting the cause of a HW exception\n */\ntypedef enum {\n  // GPU Hang\n  HSA_AMD_HW_EXCEPTION_CAUSE_GPU_HANG = 1 << 0,\n  // SRAM ECC\n  HSA_AMD_HW_EXCEPTION_CAUSE_ECC = 1 << 1,\n} hsa_amd_hw_exception_reset_cause_t;\n\n/**\n * @brief AMD GPU HW Exception event data.\n */\ntypedef struct hsa_amd_gpu_hw_exception_info_s {\n  /*\n  The agent where the HW exception occurred.\n  */\n  hsa_agent_t agent;\n  hsa_amd_hw_exception_reset_type_t reset_type;\n  hsa_amd_hw_exception_reset_cause_t reset_cause;\n} hsa_amd_gpu_hw_exception_info_t;\n\n/**\n * @brief AMD GPU event data passed to event handler.\n */\ntypedef struct hsa_amd_event_s {\n  /*\n  The event type.\n  */\n  hsa_amd_event_type_t event_type;\n  union {\n    /*\n    The memory fault info, only valid when @p event_type is HSA_AMD_GPU_MEMORY_FAULT_EVENT.\n    */\n    hsa_amd_gpu_memory_fault_info_t memory_fault;\n    /*\n    The memory fault info, only valid when @p event_type is HSA_AMD_GPU_HW_EXCEPTION_EVENT.\n    */\n    hsa_amd_gpu_hw_exception_info_t hw_exception;\n    /*\n    The memory error info, only valid when @p event_type is HSA_AMD_GPU_MEMORY_ERROR_EVENT.\n    */\n    hsa_amd_gpu_memory_error_info_t memory_error;\n  };\n} hsa_amd_event_t;\n\ntypedef hsa_status_t (*hsa_amd_system_event_callback_t)(const hsa_amd_event_t* event, void* data);\n\n/**\n * @brief Register AMD GPU event handler.\n *\n * @param[in] callback Callback to be invoked when an event is triggered.\n * The HSA runtime passes two arguments to the callback: @p event\n * is defined per event by the HSA runtime, and @p data is the user data.\n *\n * @param[in] data User data that is passed to @p callback. May be NULL.\n *\n * @retval HSA_STATUS_SUCCESS The handler has been registered successfully.\n *\n * @retval HSA_STATUS_ERROR An event handler has already been registered.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p event is invalid.\n */\nhsa_status_t HSA_API hsa_amd_register_system_event_handler(hsa_amd_system_event_callback_t callback,\n                                                   void* data);\n\n/** @} */\n\n/** \\addtogroup queue Queues\n *  @{\n */\n\n/**\n * @brief Per-queue dispatch and wavefront scheduling priority.\n */\ntypedef enum hsa_amd_queue_priority_s {\n  /*\n  Below normal/high priority compute and all graphics\n  */\n  HSA_AMD_QUEUE_PRIORITY_LOW = 0,\n  /*\n  Above low priority compute, below high priority compute and all graphics\n  */\n  HSA_AMD_QUEUE_PRIORITY_NORMAL = 1,\n  /*\n  Above low/normal priority compute and all graphics\n  */\n  HSA_AMD_QUEUE_PRIORITY_HIGH = 2,\n} hsa_amd_queue_priority_t;\n\n/**\n * @brief Modifies the dispatch and wavefront scheduling prioirty for a\n * given compute queue. The default is HSA_AMD_QUEUE_PRIORITY_NORMAL.\n *\n * @param[in] queue Compute queue to apply new priority to.\n *\n * @param[in] priority Priority to associate with queue.\n *\n * @retval HSA_STATUS_SUCCESS if priority was changed successfully.\n *\n * @retval HSA_STATUS_ERROR_INVALID_QUEUE if queue is not a valid\n * compute queue handle.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT if priority is not a valid\n * value from hsa_amd_queue_priority_t.\n */\nhsa_status_t HSA_API hsa_amd_queue_set_priority(hsa_queue_t* queue,\n                                                hsa_amd_queue_priority_t priority);\n\n/**\n * @brief Queue creation attributes.\n */\ntypedef enum {\n  /**\n   * The queue's packet buffer and queue descriptor struct should be\n   * allocated in system memory (default). Mutually exclusive with\n   * HSA_AMD_QUEUE_CREATE_DEVICE_MEM_RING_BUF and\n   * HSA_AMD_QUEUE_CREATE_DEVICE_MEM_QUEUE_DESCRIPTOR.\n   */\n  HSA_AMD_QUEUE_CREATE_SYSTEM_MEM = 0,\n  /**\n   * The queue's packet buffer should be allocated in the agent's\n   * fine-grain device memory region.\n   */\n  HSA_AMD_QUEUE_CREATE_DEVICE_MEM_RING_BUF = (1 << 0),\n  /**\n   * The queue desciptor struct should be allocated in the agent's\n   * fine-grain device memory region. Not supported for devices\n   * connected via PCIe because the CPU's atomic read-modify-write\n   * operations cannot be promoted to PCIe atomic read-modify-write\n   * operations.\n   */\n  HSA_AMD_QUEUE_CREATE_DEVICE_MEM_QUEUE_DESCRIPTOR = (1 << 1),\n} hsa_amd_queue_create_flag_t;\n\n/** @} */\n\n/** \\addtogroup memory Memory\n *  @{\n */\n\n/**\n * @brief Deallocation notifier function type.\n */\ntypedef void (*hsa_amd_deallocation_callback_t)(void* ptr, void* user_data);\n\n/**\n * @brief Registers a deallocation notifier monitoring for release of agent\n * accessible address @p ptr.  If successful, @p callback will be invoked when\n * @p ptr is removed from accessibility from all agents.\n *\n * Notification callbacks are automatically deregistered when they are invoked.\n *\n * Note: The current version supports notifications of address release\n * originating from ::hsa_amd_memory_pool_free.  Support for other address\n * release APIs will follow.\n *\n * @param[in] ptr Agent accessible address to monitor for deallocation.  Passed\n * to @p callback.\n *\n * @param[in] callback Notifier to be invoked when @p ptr is released from\n * agent accessibility.\n *\n * @param[in] user_data User provided value passed to @p callback.  May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The notifier registered successfully\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION @p ptr does not refer to a valid agent accessible\n * address.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL or @p ptr is NULL.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES if there is a failure in allocating\n * necessary resources\n */\nhsa_status_t HSA_API hsa_amd_register_deallocation_callback(void* ptr,\n                                                    hsa_amd_deallocation_callback_t callback,\n                                                    void* user_data);\n\n/**\n * @brief Removes a deallocation notifier previously registered with\n * ::hsa_amd_register_deallocation_callback.  Arguments must be identical to\n * those given in ::hsa_amd_register_deallocation_callback.\n *\n * @param[in] ptr Agent accessible address which was monitored for deallocation.\n *\n * @param[in] callback Notifier to be removed.\n *\n * @retval ::HSA_STATUS_SUCCESS The notifier has been removed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT The given notifier was not registered.\n */\nhsa_status_t HSA_API hsa_amd_deregister_deallocation_callback(void* ptr,\n                                                      hsa_amd_deallocation_callback_t callback);\n\ntypedef enum hsa_amd_svm_model_s {\n  /**\n   * Updates to memory with this attribute conform to HSA memory consistency\n   * model.\n   */\n  HSA_AMD_SVM_GLOBAL_FLAG_FINE_GRAINED = 0,\n  /**\n   * Writes to memory with this attribute can be performed by a single agent\n   * at a time.\n   */\n  HSA_AMD_SVM_GLOBAL_FLAG_COARSE_GRAINED = 1,\n  /**\n   * Memory region queried contains subregions with both\n   * HSA_AMD_SVM_GLOBAL_FLAG_COARSE_GRAINED and\n   * HSA_AMD_SVM_GLOBAL_FLAG_FINE_GRAINED attributes.\n   *\n   * This attribute can not be used in hsa_amd_svm_attributes_set.  It is a\n   * possible return from hsa_amd_svm_attributes_get indicating that the query\n   * region contains both coarse and fine grained memory.\n   */\n  HSA_AMD_SVM_GLOBAL_FLAG_INDETERMINATE = 2\n} hsa_amd_svm_model_t;\n\ntypedef enum hsa_amd_svm_attribute_s {\n  // Memory model attribute.\n  // Type of this attribute is hsa_amd_svm_model_t.\n  HSA_AMD_SVM_ATTRIB_GLOBAL_FLAG = 0,\n  // Marks the range read only.  This allows multiple physical copies to be\n  // placed local to each accessing device.\n  // Type of this attribute is bool.\n  HSA_AMD_SVM_ATTRIB_READ_ONLY = 1,\n  // Automatic migrations should attempt to keep the memory within the xgmi hive\n  // containing accessible agents.\n  // Type of this attribute is bool.\n  HSA_AMD_SVM_ATTRIB_HIVE_LOCAL = 2,\n  // Page granularity to migrate at once.  Page granularity is specified as\n  // log2(page_count).\n  // Type of this attribute is uint64_t.\n  HSA_AMD_SVM_ATTRIB_MIGRATION_GRANULARITY = 3,\n  // Physical location to prefer when automatic migration occurs.\n  // Set to the null agent handle (handle == 0) to indicate there\n  // is no preferred location.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_PREFERRED_LOCATION = 4,\n  // This attribute can not be used in ::hsa_amd_svm_attributes_set (see\n  // ::hsa_amd_svm_prefetch_async).\n  // Queries the physical location of most recent prefetch command.\n  // If the prefetch location has not been set or is not uniform across the\n  // address range then returned hsa_agent_t::handle will be 0.\n  // Querying this attribute will return the destination agent of the most\n  // recent ::hsa_amd_svm_prefetch_async targeting the address range.  If\n  // multiple async prefetches have been issued targeting the region and the\n  // most recently issued prefetch has completed then the query will return\n  // the location of the most recently completed prefetch.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION = 5,\n  // Optimizes with the anticipation that the majority of operations to the\n  // range will be read operations.\n  // Type of this attribute is bool.\n  HSA_AMD_SVM_ATTRIB_READ_MOSTLY = 6,\n  // Allows the execution on GPU.\n  // Type of this attribute is bool.\n  HSA_AMD_SVM_ATTRIB_GPU_EXEC = 7,\n  // This attribute can not be used in ::hsa_amd_svm_attributes_get.\n  // Enables an agent for access to the range.  Access may incur a page fault\n  // and associated memory migration.  Either this or\n  // HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE is required prior to SVM\n  // access if HSA_AMD_SYSTEM_INFO_SVM_ACCESSIBLE_BY_DEFAULT is false.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE = 0x200,\n  // This attribute can not be used in ::hsa_amd_svm_attributes_get.\n  // Enables an agent for access to the range without page faults.  Access\n  // will not incur a page fault and will not cause access based migration.\n  // and associated memory migration.  Either this or\n  // HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE is required prior to SVM access if\n  // HSA_AMD_SYSTEM_INFO_SVM_ACCESSIBLE_BY_DEFAULT is false.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE = 0x201,\n  // This attribute can not be used in ::hsa_amd_svm_attributes_get.\n  // Denies an agent access to the memory range.  Access will cause a terminal\n  // segfault.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_AGENT_NO_ACCESS = 0x202,\n  // This attribute can not be used in ::hsa_amd_svm_attributes_set.\n  // Returns the access attribute associated with the agent.\n  // The agent to query must be set in the attribute value field.\n  // The attribute enum will be replaced with the agent's current access\n  // attribute for the address range.\n  // TODO: Clarify KFD return value for non-uniform access attribute.\n  // Type of this attribute is hsa_agent_t.\n  HSA_AMD_SVM_ATTRIB_ACCESS_QUERY = 0x203,\n} hsa_amd_svm_attribute_t;\n\n// List type for hsa_amd_svm_attributes_set/get.\ntypedef struct hsa_amd_svm_attribute_pair_s {\n  // hsa_amd_svm_attribute_t value.\n  uint64_t attribute;\n  // Attribute value.  Bit values should be interpreted according to the type\n  // given in the associated attribute description.\n  uint64_t value;\n} hsa_amd_svm_attribute_pair_t;\n\n/**\n * @brief Sets SVM memory attributes.\n *\n * If HSA_AMD_SYSTEM_INFO_SVM_ACCESSIBLE_BY_DEFAULT returns false then enabling\n * access to an Agent via this API (setting HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE\n * or HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE) is required prior to SVM\n * memory access by that Agent.\n *\n * Attributes HSA_AMD_SVM_ATTRIB_ACCESS_QUERY and HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION\n * may not be used with this API.\n *\n * @param[in] ptr Will be aligned down to nearest page boundary.\n *\n * @param[in] size Will be aligned up to nearest page boundary.\n *\n * @param[in] attribute_list List of attributes to set for the address range.\n *\n * @param[in] attribute_count Length of @p attribute_list.\n */\nhsa_status_t hsa_amd_svm_attributes_set(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count);\n\n/**\n * @brief Gets SVM memory attributes.\n *\n * Attributes HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE,\n * HSA_AMD_SVM_ATTRIB_AGENT_ACCESSIBLE_IN_PLACE and\n * HSA_AMD_SVM_ATTRIB_PREFETCH_LOCATION may not be used with this API.\n *\n * Note that attribute HSA_AMD_SVM_ATTRIB_ACCESS_QUERY takes as input an\n * hsa_agent_t and returns the current access type through its attribute field.\n *\n * @param[in] ptr Will be aligned down to nearest page boundary.\n *\n * @param[in] size Will be aligned up to nearest page boundary.\n *\n * @param[in] attribute_list List of attributes to set for the address range.\n *\n * @param[in] attribute_count Length of @p attribute_list.\n */\nhsa_status_t hsa_amd_svm_attributes_get(void* ptr, size_t size,\n                                        hsa_amd_svm_attribute_pair_t* attribute_list,\n                                        size_t attribute_count);\n\n/**\n * @brief Asynchronously migrates memory to an agent.\n *\n * Schedules memory migration to @p agent when @p dep_signals have been observed equal to zero.\n * @p completion_signal will decrement when the migration is complete.\n *\n * @param[in] ptr Will be aligned down to nearest page boundary.\n *\n * @param[in] size Will be aligned up to nearest page boundary.\n *\n * @param[in] agent Agent to migrate to.\n *\n * @param[in] num_dep_signals Number of dependent signals. Can be 0.\n *\n * @param[in] dep_signals List of signals that must be waited on before the migration\n * operation starts. The migration will start after every signal has been observed with\n * the value 0. If @p num_dep_signals is 0, this argument is ignored.\n *\n * @param[in] completion_signal Signal used to indicate completion of the migration\n * operation. When the migration operation is finished, the value of the signal is\n * decremented. The runtime indicates that an error has occurred during the copy\n * operation by setting the value of the completion signal to a negative\n * number. If no completion signal is required this handle may be null.\n */\nhsa_status_t hsa_amd_svm_prefetch_async(void* ptr, size_t size, hsa_agent_t agent,\n                                        uint32_t num_dep_signals, const hsa_signal_t* dep_signals,\n                                        hsa_signal_t completion_signal);\n\n/** @} */\n\n/** \\addtogroup profile Profiling\n *  @{\n */\n\n/**\n * @brief Acquire Stream Performance Monitor on an agent\n *\n * Acquire exclusive use of SPM on @p preferred_agent.\n * See hsa_amd_spm_set_dest_buffer to provide a destination buffer to KFD to start recording and\n * retrieve this data.\n * @param[in] preferred_agent Agent on which to acquire SPM\n */\nhsa_status_t hsa_amd_spm_acquire(hsa_agent_t preferred_agent);\n\n/**\n * @brief Release Stream Performance Monitor on an agent\n *\n * Release exclusive use of SPM on @p preferred_agent. This will stop KFD writing SPM data.\n * If a destination buffer is set, then data in the destination buffer is available to user\n * when this function returns.\n *\n * @param[in] preferred_agent Agent on which to release SPM\n */\nhsa_status_t hsa_amd_spm_release(hsa_agent_t preferred_agent);\n\n/**\n * @brief  Set up the current destination user mode buffer for stream performance\n * counter data. KFD will start writing SPM data into the destination buffer. KFD will continue\n * to copy data into the current destination buffer until any of the following functions are called\n * - hsa_amd_spm_release\n * - hsa_amd_spm_set_dest_buffer with dest set to NULL\n * - hsa_amd_spm_set_dest_buffer with dest set to a new buffer\n *\n * if @p timeout is non-0, the call will wait for up to @p timeout ms for the previous\n * buffer to be filled. If previous buffer to be filled before timeout, the @p timeout\n * will be updated value with the time remaining. If the timeout is exceeded, the function\n * copies any partial data available into the previous user buffer and returns success.\n * User should not access destination data while KFD is copying data.\n * If the previous destination buffer was full, then @p is_data_loss flag is set.\n * @p dest is CPU accessible memory. It could be malloc'ed memory or host allocated memory\n *\n * @param[in] preferred_agent Agent on which to set the dest buffer\n *\n * @param[in] size_in_bytes size of the buffer\n *\n * @param[in,out] timeout timeout in milliseconds\n *\n * @param[out] size_copied number of bytes copied\n *\n * @param[in] dest destination address. Set to NULL to stop copy on previous buffer\n *\n * @param[out] is_data_loss true is data was lost\n */\nhsa_status_t hsa_amd_spm_set_dest_buffer(hsa_agent_t preferred_agent, size_t size_in_bytes,\n                                         uint32_t* timeout, uint32_t* size_copied, void* dest,\n                                         bool* is_data_loss);\n\n/** @} */\n\n/** \\addtogroup memory Memory\n *  @{\n */\n\n/**\n * @brief Older version of export dmabuf\n *\n * This is the same as calling the v2 version of export dmabuf with the\n * flags argument set to HSA_AMD_DMABUF_MAPPING_TYPE_NONE.\n *\n * @param[in] ptr Pointer to the allocation being exported.\n *\n * @param[in] size Size in bytes to export following @p ptr.  The entire range\n * being exported must be contained within a single allocation.\n *\n * @param[out] dmabuf Pointer to a dma-buf file descriptor holding a reference to the\n * allocation.  Contents will not be altered in the event of failure.\n *\n * @param[out] offset Offset in bytes into the memory referenced by the dma-buf\n * object at which @p ptr resides.  Contents will not be altered in the event\n * of failure.\n *\n * @retval ::HSA_STATUS_SUCCESS Export completed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT One or more arguments is NULL.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION The address range described by\n * @p ptr and @p size are not contained within a single allocation.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The allocation described by @p ptr\n * and @p size was allocated on a device which can not export memory.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The return file descriptor,\n * @p dmabuf, could not be created.\n */\nhsa_status_t hsa_amd_portable_export_dmabuf(const void* ptr, size_t size, int* dmabuf,\n                                            uint64_t* offset);\n\n                                            /**\n * @brief Obtains an OS specific, vendor neutral, handle to a memory allocation.\n *\n * Obtains an OS specific handle to GPU agent memory.  The memory must be part\n * of a single allocation from an hsa_amd_memory_pool_t exposed by a GPU Agent.\n * The handle may be used with other APIs (e.g. Vulkan) to obtain shared access\n * to the allocation.\n *\n * Shared access to the memory is not guaranteed to be fine grain coherent even\n * if the allocation exported is from a fine grain pool.  The shared memory\n * consistency model will be no stronger than the model exported from, consult\n * the importing API to determine the final consistency model.\n *\n * The allocation's memory remains valid as long as the handle and any mapping\n * of the handle remains valid.  When the handle and all mappings are closed\n * the backing memory will be released for reuse.\n *\n * @param[in] ptr Pointer to the allocation being exported.\n *\n * @param[in] size Size in bytes to export following @p ptr.  The entire range\n * being exported must be contained within a single allocation.\n *\n * @param[out] dmabuf Pointer to a dma-buf file descriptor holding a reference to the\n * allocation.  Contents will not be altered in the event of failure.\n *\n * @param[out] offset Offset in bytes into the memory referenced by the dma-buf\n * object at which @p ptr resides.  Contents will not be altered in the event\n * of failure.\n *\n * @param[in] flags Bitmask of hsa_amd_dma_buf_mapping_type_t flags.\n *\n * @retval ::HSA_STATUS_SUCCESS Export completed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT One or more arguments is NULL.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION The address range described by\n * @p ptr and @p size are not contained within a single allocation.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The allocation described by @p ptr\n * and @p size was allocated on a device which can not export memory.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The return file descriptor,\n * @p dmabuf, could not be created.\n */\nhsa_status_t hsa_amd_portable_export_dmabuf_v2(const void* ptr, size_t size,\n                               int* dmabuf, uint64_t* offset, uint64_t flags);\n\n/**\n * @brief Closes an OS specific, vendor neutral, handle to a memory allocation.\n *\n * Closes an OS specific handle to GPU agent memory.\n *\n * Applications should close a handle after imports are complete.  The handle\n * is not required to remain open for the lifetime of imported mappings.  The\n * referenced allocation will remain valid until all handles and mappings\n * are closed.\n *\n * @param[in] dmabuf Handle to be closed.\n *\n * @retval ::HSA_STATUS_SUCCESS Handle closed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_RESOURCE_FREE A generic error was encountered\n * when closing the handle.  The handle may have been closed already or an\n * async IO error may have occured.\n */\nhsa_status_t hsa_amd_portable_close_dmabuf(int dmabuf);\n\ntypedef enum hsa_amd_vmem_address_reserve_flag_s {\n  // Only reserve a VA range without registering it to the underlying driver\n  HSA_AMD_VMEM_ADDRESS_NO_REGISTER = (1UL << 0),\n} hsa_amd_vmem_address_reserve_flag_t;\n\n/**\n * @brief Allocate a reserved address range\n *\n * Reserve a virtual address range. The size must be a multiple of the system page size.\n * If it is not possible to allocate the address specified by @p address, then @p va will be\n * a different address range.\n * Address range should be released by calling hsa_amd_vmem_address_free.\n *\n * @param[out] va virtual address allocated\n * @param[in] size of address range requested\n * @param[in] address requested\n * @param[in] flags optional hsa_amd_vmem_address_reserve_flag_t\n *\n * @retval ::HSA_STATUS_SUCCESS Address range allocated successfully\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Insufficient resources to allocate an address\n * range of this size.\n *\n * Note that this API will be deprecated in a future release and replaced by\n * hsa_amd_vmem_address_reserve_align\n */\nhsa_status_t hsa_amd_vmem_address_reserve(void** va, size_t size, uint64_t address,\n                                          uint64_t flags);\n\n/**\n * @brief Allocate a reserved address range\n *\n * Reserve a virtual address range. The size must be a multiple of the system page size.\n * If it is not possible to allocate the address specified by @p address, then @p va will be\n * a different address range.\n * Address range should be released by calling hsa_amd_vmem_address_free.\n *\n * @param[out] va virtual address allocated\n * @param[in] size of address range requested\n * @param[in] address requested\n * @param[in] alignment requested. 0 for default. Must be >= page-size and a power of 2\n * @param[in] flags optional hsa_amd_vmem_address_reserve_flag_t\n *\n * @retval ::HSA_STATUS_SUCCESS Address range allocated successfully\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Insufficient resources to allocate an address\n * range of this size.\n */\nhsa_status_t hsa_amd_vmem_address_reserve_align(void** va, size_t size, uint64_t address,\n                                          uint64_t alignment, uint64_t flags);\n\n/**\n * @brief Free a reserved address range\n *\n * Free a previously allocated address range. The size must match the size of a previously\n * allocated address range.\n *\n * @param[out] va virtual address to be freed\n * @param[in] size of address range\n *\n * @retval ::HSA_STATUS_SUCCESS Address range released successfully\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid va specified\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid size specified\n * @retval ::HSA_STATUS_ERROR_RESOURCE_FREE Address range is still in use\n * @retval ::HSA_STATUS_ERROR Internal unexpected error\n */\nhsa_status_t hsa_amd_vmem_address_free(void* va, size_t size);\n\n/**\n * @brief Struct containing an opaque handle to a memory allocation handle\n */\ntypedef struct hsa_amd_vmem_alloc_handle_s {\n  /**\n   * Opaque handle. Two handles reference the same object of the enclosing type\n   * if and only if they are equal.\n   */\n  uint64_t handle;\n} hsa_amd_vmem_alloc_handle_t;\n\ntypedef enum {\n  MEMORY_TYPE_NONE,\n  MEMORY_TYPE_PINNED,\n} hsa_amd_memory_type_t;\n\n/**\n * @brief Create a virtual memory handle\n *\n * Create a virtual memory handle within this pool\n * @p size must be a aligned to allocation granule size for this memory pool, see\n * HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE\n * To minimize internal memory fragmentation, align the size to the recommended allocation granule\n * size, see HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_REC_GRANULE\n *\n * @param[in] pool memory to use\n * @param[in] size of the memory allocation\n * @param[in] type of memory\n * @param[in] flags - currently unsupported\n * @param[out] memory_handle - handle for the allocation\n *\n * @retval ::HSA_STATUS_SUCCESS memory allocated successfully\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid arguments\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION This memory pool does not support allocations\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Insufficient resources to allocate this memory\n */\nhsa_status_t hsa_amd_vmem_handle_create(hsa_amd_memory_pool_t pool, size_t size,\n                                        hsa_amd_memory_type_t type, uint64_t flags,\n                                        hsa_amd_vmem_alloc_handle_t* memory_handle);\n\n/**\n * @brief Release a virtual memory handle\n *\n * @param[in] memory handle that was previously allocated\n *\n * @retval ::HSA_STATUS_SUCCESS Address range allocated successfully\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid memory handle\n */\nhsa_status_t hsa_amd_vmem_handle_release(hsa_amd_vmem_alloc_handle_t memory_handle);\n\n/**\n * @brief Map a virtual memory handle\n *\n * Map a virtual memory handle to a reserved address range. The virtual address requested must be\n * within a previously reserved address range. @p va and (@p va + size) must be must be within\n * (va + size) of the previous allocated address range.\n * @p size must be equal to size of the @p memory_handle\n * hsa_amd_vmem_set_access needs to be called to make the memory accessible to specific agents\n *\n * @param[in] va virtual address range where memory will be mapped\n * @param[in] size of memory mapping\n * @param[in] in_offset offset into memory. Currently unsupported\n * @param[in] memory_handle virtual memory handle to be mapped\n * @param[in] flags. Currently unsupported\n *\n * @retval ::HSA_STATUS_SUCCESS Memory mapped successfully\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT va, size or memory_handle are invalid\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Insufficient resources\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_map(void* va, size_t size, size_t in_offset,\n                              hsa_amd_vmem_alloc_handle_t memory_handle, uint64_t flags);\n\n/**\n * @brief Unmap a virtual memory handle\n *\n * Unmap previously mapped virtual address range\n *\n * @param[in] va virtual address range where memory will be mapped\n * @param[in] size of memory mapping\n *\n * @retval ::HSA_STATUS_SUCCESS Memory backing unmapped successfully\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION memory_handle is invalid\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT size is invalid\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_unmap(void* va, size_t size);\n\ntypedef struct hsa_amd_memory_access_desc_s {\n  hsa_access_permission_t permissions;\n  hsa_agent_t agent_handle;\n} hsa_amd_memory_access_desc_t;\n\n/**\n * @brief Make a memory mapping accessible\n *\n * Make previously mapped virtual address accessible to specific agents. @p size must be equal to\n * size of previously mapped virtual memory handle.\n * Calling hsa_amd_vmem_set_access multiple times on the same @p va:\n *  - Will overwrite permissions for agents specified in @p desc\n *  - Will leave permissions unchanged for agents not specified in @p desc\n *\n * @param[in] va previously mapped virtual address\n * @param[in] size of memory mapping\n * @param[in] desc list of access permissions for each agent\n * @param[in] desc_cnt number of elements in desc\n *\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT va, size or memory_handle are invalid\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION memory_handle is invalid\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Insufficient resources\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT Invalid agent in desc\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_set_access(void* va, size_t size,\n                                     const hsa_amd_memory_access_desc_t* desc,\n                                     size_t desc_cnt);\n\n/**\n * @brief Get current access permissions for memory mapping\n *\n * Get access permissions for memory mapping for specific agent.\n *\n * @param[in] va previously mapped virtual address\n * @param[in] perms current permissions\n * @param[in] agent_handle agent\n *\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT Invalid agent\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION va is not mapped or permissions never set for this\n * agent\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_get_access(void* va, hsa_access_permission_t* perms,\n                                     hsa_agent_t agent_handle);\n\n/**\n * @brief Get an exportable shareable handle\n *\n * Get an exportable shareable handle for a memory_handle. This shareabl handle can then be used to\n * re-create a virtual memory handle using hsa_amd_vmem_import_shareable_handle. The shareable\n * handle can be transferred using mechanisms that support posix file descriptors Once all shareable\n * handles are closed, the memory_handle is released.\n *\n * @param[out] dmabuf_fd shareable handle\n * @param[in] handle previously allocated virtual memory handle\n * @param[in] flags Currently unsupported\n *\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid memory handle\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Out of resources\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_export_shareable_handle(int* dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t handle,\n                                                  uint64_t flags);\n/**\n * @brief Import a shareable handle\n *\n * Import a shareable handle for a memory handle. Importing a shareable handle that has been closed\n * and released results in undefined behavior.\n *\n * @param[in] dmabuf_fd shareable handle exported with hsa_amd_vmem_export_shareable_handle\n * @param[out] handle virtual memory handle\n *\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid memory handle\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Out of resources\n *\n * @retval ::HSA_STATUS_ERROR Unexpected internal error\n */\nhsa_status_t hsa_amd_vmem_import_shareable_handle(int dmabuf_fd,\n                                                  hsa_amd_vmem_alloc_handle_t* handle);\n\n/**\n * @brief Returns memory handle for mapped memory\n *\n * Return a memory handle for previously mapped memory. The handle will be the same value of handle\n * used to map the memory. The returned handle must be released with corresponding number of calls\n * to hsa_amd_vmem_handle_release.\n *\n * @param[out] memory_handle memory handle for this mapped address\n * @param[in] mapped address\n *\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid address\n */\nhsa_status_t hsa_amd_vmem_retain_alloc_handle(hsa_amd_vmem_alloc_handle_t* memory_handle,\n                                              void* addr);\n\n/**\n * @brief Returns the current allocation properties of a handle\n *\n * Returns the allocation properties of an existing handle\n *\n * @param[in] memory_handle memory handle to be queried\n * @param[out] pool memory pool that owns this handle\n * @param[out] memory type\n\n * @retval ::HSA_STATUS_SUCCESS\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ALLOCATION Invalid memory_handle\n */\nhsa_status_t hsa_amd_vmem_get_alloc_properties_from_handle(\n    hsa_amd_vmem_alloc_handle_t memory_handle, hsa_amd_memory_pool_t* pool,\n    hsa_amd_memory_type_t* type);\n\n/** @} */\n\n/** \\addtogroup queue Queues\n *  @{\n */\n\n/**\n * @brief Set the asynchronous scratch limit threshold on all the queues for this agent.\n * Dispatches that are enqueued on HW queues on this agent that are smaller than threshold will not\n * result in a scratch use-once method.\n *\n * Increasing this threshold will only increase the internal limit and not cause immediate allocation\n * of additional scratch memory. Decreasing this threshold will result in a release in scratch memory\n * on queues where the current amount of allocated scratch exceeds the new limit.\n *\n * If this API call would result in a release in scratch memory and there are dispatches that are\n * currently using scratch memory on this agent, this will result into a blocking call until the\n * current dispatches are completed.\n *\n * This API is only supported on devices that support asynchronous scratch reclaim.\n *\n * @param[in] agent A valid agent.\n *\n * @param[in] threshold Threshold size in bytes\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT This agent does not support asynchronous scratch\n * reclaim\n */\nhsa_status_t HSA_API hsa_amd_agent_set_async_scratch_limit(hsa_agent_t agent, size_t threshold);\n\ntypedef enum {\n  /*\n   * Returns the agent that owns the underlying HW queue.\n   * The type of this attribute is hsa_agent_t.\n   */\n  HSA_AMD_QUEUE_INFO_AGENT,\n  /*\n   * Returns the doorbell ID of the completion signal of the queue\n   * The type of this attribute is uint64_t.\n   */\n  HSA_AMD_QUEUE_INFO_DOORBELL_ID,\n} hsa_queue_info_attribute_t;\n\nhsa_status_t hsa_amd_queue_get_info(hsa_queue_t* queue, hsa_queue_info_attribute_t attribute,\n                                    void* value);\n\n/**\n * @brief logging types\n */\ntypedef enum hsa_amd_log_flag_s {\n   /* Log AQL packets internally enqueued by HSA for Blit Kernels */\n  HSA_AMD_LOG_FLAG_BLIT_KERNEL_PKTS = 0,\n} hsa_amd_log_flag_t;\n\n/**\n * @brief Enable logging via external file\n * If this function is called multiple times, the last call to this function will overwrite the\n * previous @p flags and @p file.\n *\n * @param[in] flags is used to filter types of logging. Type is uint8_t[8].\n * Can be set using the hsa_flag_set64 macro. Setting @p flags to 0 will disable logging.\n * @param[in] file file stream to output logging. If file is NULL, prints are sent to stderr.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n */\nhsa_status_t hsa_amd_enable_logging(uint8_t* flags, void* file);\n\n/** @} */\n\n#ifdef __cplusplus\n}  // end extern \"C\" block\n#endif\n\n#endif  // header guard\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ext_finalize.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_INC_HSA_EXT_FINALIZE_H_\n#define HSA_RUNTIME_INC_HSA_EXT_FINALIZE_H_\n\n#include \"hsa.h\"\n\n#undef HSA_API\n#ifdef HSA_EXPORT_FINALIZER\n#define HSA_API HSA_API_EXPORT\n#else\n#define HSA_API HSA_API_IMPORT\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif // __cplusplus\n\nstruct BrigModuleHeader;\ntypedef struct BrigModuleHeader* BrigModule_t;\n\n/** \\defgroup ext-alt-finalizer-extensions Finalization Extensions\n *  @{\n */\n\n/**\n * @brief Enumeration constants added to ::hsa_status_t by this extension.\n */\nenum {\n  /**\n   * The HSAIL program is invalid.\n   */\n  HSA_EXT_STATUS_ERROR_INVALID_PROGRAM = 0x2000,\n  /**\n   * The HSAIL module is invalid.\n   */\n  HSA_EXT_STATUS_ERROR_INVALID_MODULE = 0x2001,\n  /**\n   * Machine model or profile of the HSAIL module do not match the machine model\n   * or profile of the HSAIL program.\n   */\n  HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE = 0x2002,\n  /**\n   * The HSAIL module is already a part of the HSAIL program.\n   */\n  HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED = 0x2003,\n  /**\n   * Compatibility mismatch between symbol declaration and symbol definition.\n   */\n  HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH = 0x2004,\n  /**\n   * The finalization encountered an error while finalizing a kernel or\n   * indirect function.\n   */\n  HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED = 0x2005,\n  /**\n   * Mismatch between a directive in the control directive structure and in\n   * the HSAIL kernel.\n   */\n  HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH = 0x2006\n};\n\n/** @} */\n\n/** \\defgroup ext-alt-finalizer-program Finalization Program\n *  @{\n */\n\n/**\n * @brief HSAIL (BRIG) module. The HSA Programmer's Reference Manual contains\n * the definition of the BrigModule_t type.\n */\ntypedef BrigModule_t hsa_ext_module_t;\n\n/**\n * @brief An opaque handle to a HSAIL program, which groups a set of HSAIL\n * modules that collectively define functions and variables used by kernels and\n * indirect functions.\n */\ntypedef struct hsa_ext_program_s {\n  /**\n   * Opaque handle.\n   */\n  uint64_t handle;\n} hsa_ext_program_t;\n\n/**\n * @brief Create an empty HSAIL program.\n *\n * @param[in] machine_model Machine model used in the HSAIL program.\n *\n * @param[in] profile Profile used in the HSAIL program.\n *\n * @param[in] default_float_rounding_mode Default float rounding mode used in\n * the HSAIL program.\n *\n * @param[in] options Vendor-specific options. May be NULL.\n *\n * @param[out] program Memory location where the HSA runtime stores the newly\n * created HSAIL program handle.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure to allocate\n * resources required for the operation.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p machine_model is invalid,\n * @p profile is invalid, @p default_float_rounding_mode is invalid, or\n * @p program is NULL.\n */\nhsa_status_t HSA_API hsa_ext_program_create(\n    hsa_machine_model_t machine_model,\n    hsa_profile_t profile,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode,\n    const char *options,\n    hsa_ext_program_t *program);\n\n/**\n * @brief Destroy a HSAIL program.\n *\n * @details The HSAIL program handle becomes invalid after it has been\n * destroyed. Code object handles produced by ::hsa_ext_program_finalize are\n * still valid after the HSAIL program has been destroyed, and can be used as\n * intended. Resources allocated outside and associated with the HSAIL program\n * (such as HSAIL modules that are added to the HSAIL program) can be released\n * after the finalization program has been destroyed.\n *\n * @param[in] program HSAIL program.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_PROGRAM The HSAIL program is\n * invalid.\n */\nhsa_status_t HSA_API hsa_ext_program_destroy(\n    hsa_ext_program_t program);\n\n/**\n * @brief Add a HSAIL module to an existing HSAIL program.\n *\n * @details The HSA runtime does not perform a deep copy of the HSAIL module\n * upon addition. Instead, it stores a pointer to the HSAIL module. The\n * ownership of the HSAIL module belongs to the application, which must ensure\n * that @p module is not released before destroying the HSAIL program.\n *\n * The HSAIL module is successfully added to the HSAIL program if @p module is\n * valid, if all the declarations and definitions for the same symbol are\n * compatible, and if @p module specify machine model and profile that matches\n * the HSAIL program.\n *\n * @param[in] program HSAIL program.\n *\n * @param[in] module HSAIL module. The application can add the same HSAIL module\n * to @p program at most once. The HSAIL module must specify the same machine\n * model and profile as @p program. If the floating-mode rounding mode of @p\n * module is not default, then it should match that of @p program.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure to allocate\n * resources required for the operation.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_PROGRAM The HSAIL program is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_MODULE The HSAIL module is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE The machine model of @p\n * module does not match machine model of @p program, or the profile of @p\n * module does not match profile of @p program.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED The HSAIL module is\n * already a part of the HSAIL program.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH Symbol declaration and symbol\n * definition compatibility mismatch. See the symbol compatibility rules in the\n * HSA Programming Reference Manual.\n */\nhsa_status_t HSA_API hsa_ext_program_add_module(\n    hsa_ext_program_t program,\n    hsa_ext_module_t module);\n\n/**\n * @brief Iterate over the HSAIL modules in a program, and invoke an\n * application-defined callback on every iteration.\n *\n * @param[in] program HSAIL program.\n *\n * @param[in] callback Callback to be invoked once per HSAIL module in the\n * program. The HSA runtime passes three arguments to the callback: the program,\n * a HSAIL module, and the application data.  If @p callback returns a status\n * other than ::HSA_STATUS_SUCCESS for a particular iteration, the traversal\n * stops and ::hsa_ext_program_iterate_modules returns that status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_PROGRAM The program is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t HSA_API hsa_ext_program_iterate_modules(\n    hsa_ext_program_t program,\n    hsa_status_t (*callback)(hsa_ext_program_t program, hsa_ext_module_t module,\n                             void* data),\n    void* data);\n\n/**\n * @brief HSAIL program attributes.\n */\ntypedef enum {\n  /**\n   * Machine model specified when the HSAIL program was created. The type\n   * of this attribute is ::hsa_machine_model_t.\n   */\n  HSA_EXT_PROGRAM_INFO_MACHINE_MODEL = 0,\n  /**\n   * Profile specified when the HSAIL program was created. The type of\n   * this attribute is ::hsa_profile_t.\n   */\n  HSA_EXT_PROGRAM_INFO_PROFILE = 1,\n  /**\n   * Default float rounding mode specified when the HSAIL program was\n   * created. The type of this attribute is ::hsa_default_float_rounding_mode_t.\n   */\n  HSA_EXT_PROGRAM_INFO_DEFAULT_FLOAT_ROUNDING_MODE = 2\n} hsa_ext_program_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given HSAIL program.\n *\n * @param[in] program HSAIL program.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behaviour is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_PROGRAM The HSAIL program is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * HSAIL program attribute, or @p value is NULL.\n */\nhsa_status_t HSA_API hsa_ext_program_get_info(\n    hsa_ext_program_t program,\n    hsa_ext_program_info_t attribute,\n    void *value);\n\n/**\n * @brief Finalizer-determined call convention.\n */\ntypedef enum {\n /**\n  * Finalizer-determined call convention.\n  */\n  HSA_EXT_FINALIZER_CALL_CONVENTION_AUTO = -1\n} hsa_ext_finalizer_call_convention_t;\n\n/**\n * @brief Control directives specify low-level information about the\n * finalization process.\n */\ntypedef struct hsa_ext_control_directives_s {\n  /**\n   * Bitset indicating which control directives are enabled. The bit assigned to\n   * a control directive is determined by the corresponding value in\n   * BrigControlDirective.\n   *\n   * If a control directive is disabled, its corresponding field value (if any)\n   * must be 0. Control directives that are only present or absent (such as\n   * partial workgroups) have no corresponding field as the presence of the bit\n   * in this mask is sufficient.\n   */\n  uint64_t control_directives_mask;\n  /**\n   * Bitset of HSAIL exceptions that must have the BREAK policy enabled. The bit\n   * assigned to an HSAIL exception is determined by the corresponding value\n   * in BrigExceptionsMask. If the kernel contains a enablebreakexceptions\n   * control directive, the finalizer uses the union of the two masks.\n   */\n  uint16_t break_exceptions_mask;\n  /**\n   * Bitset of HSAIL exceptions that must have the DETECT policy enabled. The\n   * bit assigned to an HSAIL exception is determined by the corresponding value\n   * in BrigExceptionsMask. If the kernel contains a enabledetectexceptions\n   * control directive, the finalizer uses the union of the two masks.\n   */\n  uint16_t detect_exceptions_mask;\n  /**\n   * Maximum size (in bytes) of dynamic group memory that will be allocated by\n   * the application for any dispatch of the kernel.  If the kernel contains a\n   * maxdynamicsize control directive, the two values should match.\n   */\n  uint32_t max_dynamic_group_size;\n  /**\n   * Maximum number of grid work-items that will be used by the application to\n   * launch the kernel. If the kernel contains a maxflatgridsize control\n   * directive, the value of @a max_flat_grid_size must not be greater than the\n   * value of the directive, and takes precedence.\n   *\n   * The value specified for maximum absolute grid size must be greater than or\n   * equal to the product of the values specified by @a required_grid_size.\n   *\n   * If the bit at position BRIG_CONTROL_MAXFLATGRIDSIZE is set in @a\n   * control_directives_mask, this field must be greater than 0.\n   */\n  uint64_t max_flat_grid_size;\n  /**\n   * Maximum number of work-group work-items that will be used by the\n   * application to launch the kernel. If the kernel contains a\n   * maxflatworkgroupsize control directive, the value of @a\n   * max_flat_workgroup_size must not be greater than the value of the\n   * directive, and takes precedence.\n   *\n   * The value specified for maximum absolute grid size must be greater than or\n   * equal to the product of the values specified by @a required_workgroup_size.\n   *\n   * If the bit at position BRIG_CONTROL_MAXFLATWORKGROUPSIZE is set in @a\n   * control_directives_mask, this field must be greater than 0.\n   */\n  uint32_t max_flat_workgroup_size;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint32_t reserved1;\n  /**\n   * Grid size that will be used by the application in any dispatch of the\n   * kernel. If the kernel contains a requiredgridsize control directive, the\n   * dimensions should match.\n   *\n   * The specified grid size must be consistent with @a required_workgroup_size\n   * and @a required_dim. Also, the product of the three dimensions must not\n   * exceed @a max_flat_grid_size. Note that the listed invariants must hold\n   * only if all the corresponding control directives are enabled.\n   *\n   * If the bit at position BRIG_CONTROL_REQUIREDGRIDSIZE is set in @a\n   * control_directives_mask, the three dimension values must be greater than 0.\n   */\n  uint64_t required_grid_size[3];\n  /**\n   * Work-group size that will be used by the application in any dispatch of the\n   * kernel. If the kernel contains a requiredworkgroupsize control directive,\n   * the dimensions should match.\n   *\n   * The specified work-group size must be consistent with @a required_grid_size\n   * and @a required_dim. Also, the product of the three dimensions must not\n   * exceed @a max_flat_workgroup_size. Note that the listed invariants must\n   * hold only if all the corresponding control directives are enabled.\n   *\n   * If the bit at position BRIG_CONTROL_REQUIREDWORKGROUPSIZE is set in @a\n   * control_directives_mask, the three dimension values must be greater than 0.\n   */\n  hsa_dim3_t required_workgroup_size;\n  /**\n   * Number of dimensions that will be used by the application to launch the\n   * kernel. If the kernel contains a requireddim control directive, the two\n   * values should match.\n   *\n   * The specified dimensions must be consistent with @a required_grid_size and\n   * @a required_workgroup_size. This invariant must hold only if all the\n   * corresponding control directives are enabled.\n   *\n   * If the bit at position BRIG_CONTROL_REQUIREDDIM is set in @a\n   * control_directives_mask, this field must be 1, 2, or 3.\n   */\n  uint8_t required_dim;\n  /**\n   * Reserved. Must be 0.\n   */\n  uint8_t reserved2[75];\n} hsa_ext_control_directives_t;\n\n/**\n * @brief Finalize an HSAIL program for a given instruction set architecture.\n *\n * @details Finalize all of the kernels and indirect functions that belong to\n * the same HSAIL program for a specific instruction set architecture (ISA). The\n * transitive closure of all functions specified by call or scall must be\n * defined. Kernels and indirect functions that are being finalized must be\n * defined. Kernels and indirect functions that are referenced in kernels and\n * indirect functions being finalized may or may not be defined, but must be\n * declared. All the global/readonly segment variables that are referenced in\n * kernels and indirect functions being finalized may or may not be defined, but\n * must be declared.\n *\n * @param[in] program HSAIL program.\n *\n * @param[in] isa Instruction set architecture to finalize for.\n *\n * @param[in] call_convention A call convention used in a finalization. Must\n * have a value between ::HSA_EXT_FINALIZER_CALL_CONVENTION_AUTO (inclusive)\n * and the value of the attribute ::HSA_ISA_INFO_CALL_CONVENTION_COUNT in @p\n * isa (not inclusive).\n *\n * @param[in] control_directives Low-level control directives that influence\n * the finalization process.\n *\n * @param[in] options Vendor-specific options. May be NULL.\n *\n * @param[in] code_object_type Type of code object to produce.\n *\n * @param[out] code_object Code object generated by the Finalizer, which\n * contains the machine code for the kernels and indirect functions in the HSAIL\n * program. The code object is independent of the HSAIL module that was used to\n * generate it.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES There is a failure to allocate\n * resources required for the operation.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_INVALID_PROGRAM The HSAIL program is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ISA @p isa is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH The directive in\n * the control directive structure and in the HSAIL kernel mismatch, or if the\n * same directive is used with a different value in one of the functions used by\n * this kernel.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED The Finalizer\n * encountered an error while compiling a kernel or an indirect function.\n */\nhsa_status_t HSA_API hsa_ext_program_finalize(\n    hsa_ext_program_t program,\n    hsa_isa_t isa,\n    int32_t call_convention,\n    hsa_ext_control_directives_t control_directives,\n    const char *options,\n    hsa_code_object_type_t code_object_type,\n    hsa_code_object_t *code_object);\n\n/** @} */\n\n#define hsa_ext_finalizer_1_00\n\ntypedef struct hsa_ext_finalizer_1_00_pfn_s {\n  hsa_status_t (*hsa_ext_program_create)(\n      hsa_machine_model_t machine_model, hsa_profile_t profile,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode,\n      const char *options, hsa_ext_program_t *program);\n\n  hsa_status_t (*hsa_ext_program_destroy)(hsa_ext_program_t program);\n\n  hsa_status_t (*hsa_ext_program_add_module)(hsa_ext_program_t program,\n                                                 hsa_ext_module_t module);\n\n  hsa_status_t (*hsa_ext_program_iterate_modules)(\n      hsa_ext_program_t program,\n      hsa_status_t (*callback)(hsa_ext_program_t program,\n                               hsa_ext_module_t module, void *data),\n      void *data);\n\n  hsa_status_t (*hsa_ext_program_get_info)(\n      hsa_ext_program_t program, hsa_ext_program_info_t attribute,\n      void *value);\n\n  hsa_status_t (*hsa_ext_program_finalize)(\n      hsa_ext_program_t program, hsa_isa_t isa, int32_t call_convention,\n      hsa_ext_control_directives_t control_directives, const char *options,\n      hsa_code_object_type_t code_object_type, hsa_code_object_t *code_object);\n} hsa_ext_finalizer_1_00_pfn_t;\n\n#ifdef __cplusplus\n} // extern \"C\" block\n#endif // __cplusplus\n\n#endif // HSA_RUNTIME_INC_HSA_EXT_FINALIZE_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ext_image.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n// \n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n// \n// Developed by:\n// \n//                 AMD Research and AMD HSA Software Development\n// \n//                 Advanced Micro Devices, Inc.\n// \n//                 www.amd.com\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n// \n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_EXT_IMAGE_H\n#define HSA_EXT_IMAGE_H\n\n#include \"hsa.h\"\n\n#undef HSA_API\n#ifdef HSA_EXPORT_IMAGES\n#define HSA_API HSA_API_EXPORT\n#else\n#define HSA_API HSA_API_IMPORT\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /*__cplusplus*/ \n\n/** \\defgroup ext-images Images and Samplers\n *  @{\n */\n\n/**\n * @brief Enumeration constants added to ::hsa_status_t by this extension.\n *\n * @remark Additions to hsa_status_t\n */\nenum {\n    /**\n     * Image format is not supported.\n     */\n    HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED = 0x3000,\n    /**\n     * Image size is not supported.\n     */\n    HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED = 0x3001,\n    /**\n     * Image pitch is not supported or invalid.\n     */\n    HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED = 0x3002,\n    /**\n     * Sampler descriptor is not supported or invalid.\n     */\n    HSA_EXT_STATUS_ERROR_SAMPLER_DESCRIPTOR_UNSUPPORTED = 0x3003\n};\n\n/**\n * @brief Enumeration constants added to ::hsa_agent_info_t by this\n * extension.\n *\n * @remark Additions to hsa_agent_info_t\n */\nenum {\n  /**\n   * Maximum number of elements in 1D images. Must be at least 16384. The type\n   * of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_1D_MAX_ELEMENTS = 0x3000,\n  /**\n   * Maximum number of elements in 1DA images. Must be at least 16384. The type\n   * of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_1DA_MAX_ELEMENTS = 0x3001,\n  /**\n   * Maximum number of elements in 1DB images. Must be at least 65536. The type\n   * of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_1DB_MAX_ELEMENTS = 0x3002,\n  /**\n   * Maximum dimensions (width, height) of 2D images, in image elements. The X\n   * and Y maximums must be at least 16384. The type of this attribute is\n   * size_t[2].\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_2D_MAX_ELEMENTS = 0x3003,\n  /**\n   * Maximum dimensions (width, height) of 2DA images, in image elements. The X\n   * and Y maximums must be at least 16384. The type of this attribute is\n   * size_t[2].\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_2DA_MAX_ELEMENTS = 0x3004,\n  /**\n   * Maximum dimensions (width, height) of 2DDEPTH images, in image\n   * elements. The X and Y maximums must be at least 16384. The type of this\n   * attribute is size_t[2].\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_2DDEPTH_MAX_ELEMENTS = 0x3005,\n  /**\n   * Maximum dimensions (width, height) of 2DADEPTH images, in image\n   * elements. The X and Y maximums must be at least 16384. The type of this\n   * attribute is size_t[2].\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_2DADEPTH_MAX_ELEMENTS = 0x3006,\n  /**\n   * Maximum dimensions (width, height, depth) of 3D images, in image\n   * elements. The maximum along any dimension must be at least 2048. The type\n   * of this attribute is size_t[3].\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_3D_MAX_ELEMENTS = 0x3007,\n  /**\n   * Maximum number of image layers in a image array. Must be at least 2048. The\n   * type of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_ARRAY_MAX_LAYERS = 0x3008,\n  /**\n   * Maximum number of read-only image handles that can be created for an agent at any one\n   * time. Must be at least 128. The type of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_MAX_IMAGE_RD_HANDLES = 0x3009,\n  /**\n   * Maximum number of write-only and read-write image handles (combined) that\n   * can be created for an agent at any one time. Must be at least 64. The type of this\n   * attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_MAX_IMAGE_RORW_HANDLES = 0x300A,\n  /**\n   * Maximum number of sampler handlers that can be created for an agent at any one\n   * time. Must be at least 16. The type of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_MAX_SAMPLER_HANDLERS = 0x300B,\n  /**\n   * Image pitch alignment. The agent only supports linear image data\n   * layouts with a row pitch that is a multiple of this value. Must be\n   * a power of 2. The type of this attribute is size_t.\n   */\n  HSA_EXT_AGENT_INFO_IMAGE_LINEAR_ROW_PITCH_ALIGNMENT = 0x300C\n};\n\n/**\n * @brief Image handle, populated by ::hsa_ext_image_create or\n * ::hsa_ext_image_create_with_layout. Image\n * handles are only unique within an agent, not across agents.\n *\n */\ntypedef struct hsa_ext_image_s {\n  /**\n   *  Opaque handle. For a given agent, two handles reference the same object of\n   *  the enclosing type if and only if they are equal.\n   */\n    uint64_t handle;\n\n} hsa_ext_image_t;\n\n/**\n * @brief Geometry associated with the image. This specifies the\n * number of image dimensions and whether the image is an image\n * array. See the <em>Image Geometry</em> section in the <em>HSA\n * Programming Reference Manual</em> for definitions on each\n * geometry. The enumeration values match the BRIG type @p\n * hsa_ext_brig_image_geometry_t.\n */\ntypedef enum {\n/**\n   * One-dimensional image addressed by width coordinate.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_1D = 0,\n\n  /**\n   * Two-dimensional image addressed by width and height coordinates.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_2D = 1,\n\n  /**\n   * Three-dimensional image addressed by width, height, and depth coordinates.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_3D = 2,\n\n  /**\n   * Array of one-dimensional images with the same size and format. 1D arrays\n   * are addressed by width and index coordinate.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_1DA = 3,\n\n  /**\n   * Array of two-dimensional images with the same size and format. 2D arrays\n   * are addressed by width,  height, and index coordinates.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_2DA = 4,\n\n  /**\n   * One-dimensional image addressed by width coordinate. It has\n   * specific restrictions compared to ::HSA_EXT_IMAGE_GEOMETRY_1D. An\n   * image with an opaque image data layout will always use a linear\n   * image data layout, and one with an explicit image data layout\n   * must specify ::HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_1DB = 5,\n\n  /**\n   * Two-dimensional depth image addressed by width and height coordinates.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_2DDEPTH = 6,\n\n  /**\n   * Array of two-dimensional depth images with the same size and format. 2D\n   * arrays are addressed by width, height, and index coordinates.\n   */\n  HSA_EXT_IMAGE_GEOMETRY_2DADEPTH = 7\n} hsa_ext_image_geometry_t;\n\n/**\n * @brief Channel type associated with the elements of an image. See\n * the <em>Channel Type</em> section in the <em>HSA Programming Reference\n * Manual</em> for definitions on each channel type. The\n * enumeration values and definition match the BRIG type @p\n * hsa_ext_brig_image_channel_type_t.\n */\ntypedef enum {\n    HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT8 = 0,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_SNORM_INT16 = 1,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT8 = 2,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT16 = 3,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_INT24 = 4,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_555 = 5,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_565 = 6,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNORM_SHORT_101010 = 7,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT8 = 8,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT16 = 9,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_SIGNED_INT32 = 10,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT8 = 11,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT16 = 12,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_UNSIGNED_INT32 = 13,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_HALF_FLOAT = 14,\n    HSA_EXT_IMAGE_CHANNEL_TYPE_FLOAT = 15\n} hsa_ext_image_channel_type_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_ext_image_channel_type_t constants.\n */\ntypedef uint32_t hsa_ext_image_channel_type32_t;\n    \n/**\n *\n * @brief Channel order associated with the elements of an image. See\n * the <em>Channel Order</em> section in the <em>HSA Programming Reference\n * Manual</em> for definitions on each channel order. The\n * enumeration values match the BRIG type @p\n * hsa_ext_brig_image_channel_order_t.\n */\ntypedef enum {\n    HSA_EXT_IMAGE_CHANNEL_ORDER_A = 0,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_R = 1,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RX = 2,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RG = 3,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RGX = 4,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RA = 5,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RGB = 6,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RGBX = 7,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_RGBA = 8,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_BGRA = 9,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_ARGB = 10,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_ABGR = 11,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB = 12,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBX = 13,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_SRGBA = 14,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_SBGRA = 15,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_INTENSITY = 16,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_LUMINANCE = 17,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH = 18,\n    HSA_EXT_IMAGE_CHANNEL_ORDER_DEPTH_STENCIL = 19\n} hsa_ext_image_channel_order_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_ext_image_channel_order_t constants.\n */\ntypedef uint32_t hsa_ext_image_channel_order32_t;\n    \n\n/**\n * @brief Image format.\n */\ntypedef struct hsa_ext_image_format_s {\n  /**\n    * Channel type.\n    */\n    hsa_ext_image_channel_type32_t channel_type;\n\n   /**\n    * Channel order.\n    */\n    hsa_ext_image_channel_order32_t channel_order;\n} hsa_ext_image_format_t;\n\n/**\n * @brief Implementation independent image descriptor.\n */\ntypedef struct hsa_ext_image_descriptor_s {\n    /**\n     * Image geometry.\n     */\n    hsa_ext_image_geometry_t geometry;\n    /**\n     * Width of the image, in components.\n     */\n    size_t width;\n    /**\n     * Height of the image, in components. Only used if the geometry is\n     * ::HSA_EXT_IMAGE_GEOMETRY_2D, ::HSA_EXT_IMAGE_GEOMETRY_3D,\n     * HSA_EXT_IMAGE_GEOMETRY_2DA, HSA_EXT_IMAGE_GEOMETRY_2DDEPTH, or\n     * HSA_EXT_IMAGE_GEOMETRY_2DADEPTH, otherwise must be 0.\n     */\n    size_t height;\n    /**\n     * Depth of the image, in components. Only used if the geometry is\n     * ::HSA_EXT_IMAGE_GEOMETRY_3D, otherwise must be 0.\n     */\n    size_t depth;\n    /**\n     * Number of image layers in the image array. Only used if the geometry is\n     * ::HSA_EXT_IMAGE_GEOMETRY_1DA, ::HSA_EXT_IMAGE_GEOMETRY_2DA, or\n     * HSA_EXT_IMAGE_GEOMETRY_2DADEPTH, otherwise must be 0.\n     */\n    size_t array_size;\n    /**\n     * Image format.\n     */\n    hsa_ext_image_format_t format;\n} hsa_ext_image_descriptor_t;\n\n/**\n * @brief Image capability.\n */\ntypedef enum  {\n   /**\n    * Images of this geometry, format, and layout are not supported by\n    * the agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_NOT_SUPPORTED = 0x0,\n   /**\n    * Read-only images of this geometry, format, and layout are\n    * supported by the agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_READ_ONLY = 0x1,\n   /**\n    * Write-only images of this geometry, format, and layout are\n    * supported by the agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_WRITE_ONLY = 0x2,\n   /**\n    * Read-write images of this geometry, format, and layout are\n    * supported by the agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_READ_WRITE = 0x4,\n   /**\n    * @deprecated Images of this geometry, format, and layout can be accessed from\n    * read-modify-write atomic operations in the agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_READ_MODIFY_WRITE = 0x8,\n    /**\n    * Images of this geometry, format, and layout are guaranteed to\n    * have a consistent data layout regardless of how they are\n    * accessed by the associated agent.\n    */\n    HSA_EXT_IMAGE_CAPABILITY_ACCESS_INVARIANT_DATA_LAYOUT = 0x10\n} hsa_ext_image_capability_t;\n\n/**\n * @brief Image data layout.\n *\n * @details An image data layout denotes such aspects of image data\n * layout as tiling and organization of channels in memory. Some image\n * data layouts may only apply to specific image geometries, formats,\n * and access permissions. Different agents may support different\n * image layout identifiers, including vendor specific layouts. Note\n * that an agent may not support the same image data layout for\n * different access permissions to images with the same image\n * geometry, size, and format. If multiple agents support the same\n * image data layout then it is possible to use separate image handles\n * for each agent that references the same image data.\n */\n\ntypedef enum  {\n   /**\n    * An implementation specific opaque image data layout which can\n    * vary depending on the agent, geometry, image format, image size,\n    * and access permissions.\n    */\n    HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE = 0x0,\n   /**\n    * The image data layout is specified by the following rules in\n    * ascending byte address order. For a 3D image, 2DA image array,\n    * or 1DA image array, the image data is stored as a linear sequence\n    * of adjacent 2D image slices, 2D images, or 1D images\n    * respectively, spaced according to the slice pitch. Each 2D image\n    * is stored as a linear sequence of adjacent image rows, spaced\n    * according to the row pitch. Each 1D or 1DB image is stored as a\n    * single image row. Each image row is stored as a linear sequence\n    * of image elements. Each image element is stored as a linear\n    * sequence of image components specified by the left to right\n    * channel order definition. Each image component is stored using\n    * the memory type specified by the channel type.\n    *\n    * The 1DB image geometry always uses the linear image data layout.\n    */\n    HSA_EXT_IMAGE_DATA_LAYOUT_LINEAR = 0x1\n} hsa_ext_image_data_layout_t;\n\n/**\n * @brief Retrieve the supported image capabilities for a given combination of\n * agent, geometry, and image format for an image created with an opaque image\n * data layout.\n *\n * @param[in] agent Agent to be associated with the image handle.\n *\n * @param[in] geometry Geometry.\n *\n * @param[in] image_format Pointer to an image format. Must not be NULL.\n *\n * @param[out] capability_mask Pointer to a memory location where the HSA\n * runtime stores a bit-mask of supported image capability\n * (::hsa_ext_image_capability_t) values. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_format is\n * NULL, or @p capability_mask is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_get_capability(\n    hsa_agent_t agent,\n    hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t *image_format,\n    uint32_t *capability_mask);\n\n/**\n * @brief Retrieve the supported image capabilities for a given combination of\n * agent, geometry, image format, and image layout for an image created with\n * an explicit image data layout.\n *\n * @param[in] agent Agent to be associated with the image handle.\n *\n * @param[in] geometry Geometry.\n *\n * @param[in] image_format Pointer to an image format. Must not be NULL.\n *\n * @param[in] image_data_layout The image data layout.\n * It is invalid to use ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE; use\n * ::hsa_ext_image_get_capability instead.\n *\n * @param[out] capability_mask Pointer to a memory location where the HSA\n * runtime stores a bit-mask of supported image capability\n * (::hsa_ext_image_capability_t) values. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_format is\n * NULL, @p image_data_layout is ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE,\n * or @p capability_mask is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_get_capability_with_layout(\n    hsa_agent_t agent,\n    hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t *image_format,\n    hsa_ext_image_data_layout_t image_data_layout,\n    uint32_t *capability_mask);\n\n/**\n * @brief Agent specific image size and alignment requirements, populated by\n * ::hsa_ext_image_data_get_info and ::hsa_ext_image_data_get_info_with_layout.\n */\ntypedef struct hsa_ext_image_data_info_s {\n  /**\n   * Image data size, in bytes.\n   */\n  size_t size;\n\n  /**\n   * Image data alignment, in bytes. Must always be a power of 2.\n   */\n  size_t alignment;\n\n} hsa_ext_image_data_info_t;\n\n/**\n * @brief Retrieve the image data requirements for a given combination of agent, image\n * descriptor, and access permission for an image created with an opaque image\n * data layout.\n *\n * @details The optimal image data size and alignment requirements may\n * vary depending on the image attributes specified in @p\n * image_descriptor, the @p access_permission, and the @p agent. Also,\n * different implementations of the HSA runtime may return different\n * requirements for the same input values.\n *\n * The implementation must return the same image data requirements for\n * different access permissions with matching image descriptors as long\n * as ::hsa_ext_image_get_capability reports\n * ::HSA_EXT_IMAGE_CAPABILITY_ACCESS_INVARIANT_DATA_LAYOUT. Image\n * descriptors match if they have the same values, with the exception\n * that s-form channel orders match the corresponding non-s-form\n * channel order and vice versa.\n *\n * @param[in] agent Agent to be associated with the image handle.\n *\n * @param[in] image_descriptor Pointer to an image descriptor. Must not be NULL.\n *\n * @param[in] access_permission Access permission of the image when\n * accessed by @p agent. The access permission defines how the agent\n * is allowed to access the image and must match the corresponding\n * HSAIL image handle type. The @p agent must support the image format\n * specified in @p image_descriptor for the given @p\n * access_permission.\n *\n * @param[out] image_data_info Memory location where the runtime stores the\n * size and alignment requirements. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED The @p\n * agent does not support the image format specified by @p\n * image_descriptor with the specified @p access_permission.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED The agent\n * does not support the image dimensions specified by @p\n * image_descriptor with the specified @p access_permission.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_descriptor is NULL, @p\n * access_permission is not a valid access permission value, or @p\n * image_data_info is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_data_get_info(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_info_t *image_data_info);\n\n/**\n * @brief Retrieve the image data requirements for a given combination of\n * image descriptor, access permission, image data layout, image data row pitch,\n * and image data slice pitch for an image created with an explicit image\n * data layout.\n *\n * @details The image data size and alignment requirements may vary\n * depending on the image attributes specified in @p image_descriptor,\n * the @p access_permission, and the image layout. However, different\n * implementations of the HSA runtime will return the same\n * requirements for the same input values.\n *\n * The implementation must return the same image data requirements for\n * different access permissions with matching image descriptors and\n * matching image layouts as long as ::hsa_ext_image_get_capability\n * reports\n * ::HSA_EXT_IMAGE_CAPABILITY_ACCESS_INVARIANT_DATA_LAYOUT. Image\n * descriptors match if they have the same values, with the exception\n * that s-form channel orders match the corresponding non-s-form\n * channel order and vice versa. Image layouts match if they are the\n * same image data layout and use the same image row and slice pitch\n * values.\n *\n * @param[in] image_descriptor Pointer to an image descriptor. Must not be NULL.\n *\n * @param[in] access_permission Access permission of the image when\n * accessed by an agent. The access permission defines how the agent\n * is allowed to access the image and must match the corresponding\n * HSAIL image handle type.\n *\n * @param[in] image_data_layout The image data layout to use.\n * It is invalid to use ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE; use\n * ::hsa_ext_image_data_get_info instead.\n *\n * @param[in] image_data_row_pitch The size in bytes for a single row\n * of the image in the image data. If 0 is specified then the default\n * row pitch value is used: image width * image element byte size.\n * The value used must be greater than or equal to the default row\n * pitch, and be a multiple of the image element byte size. For the\n * linear image layout it must also be a multiple of the image linear\n * row pitch alignment for the agents that will access the image data\n * using image instructions.\n *\n * @param[in] image_data_slice_pitch The size in bytes of a single\n * slice of a 3D image, or the size in bytes of each image layer in an\n * image array in the image data. If 0 is specified then the default\n * slice pitch value is used: row pitch * height if geometry is\n * ::HSA_EXT_IMAGE_GEOMETRY_3D, ::HSA_EXT_IMAGE_GEOMETRY_2DA, or\n * ::HSA_EXT_IMAGE_GEOMETRY_2DADEPTH; row pitch if geometry is\n * ::HSA_EXT_IMAGE_GEOMETRY_1DA; and 0 otherwise. The value used must\n * be 0 if the default slice pitch is 0, be greater than or equal to\n * the default slice pitch, and be a multiple of the row pitch.\n *\n * @param[out] image_data_info Memory location where the runtime stores the\n * size and alignment requirements. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED The image\n * format specified by @p image_descriptor is not supported for the\n * @p access_permission and @p image_data_layout specified.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED The image\n * dimensions specified by @p image_descriptor are not supported for\n * the @p access_permission and @p image_data_layout specified.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED The row and\n * slice pitch specified by @p image_data_row_pitch and @p\n * image_data_slice_pitch are invalid or not supported.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_descriptor is\n * NULL, @p image_data_layout is ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE,\n * or @p image_data_info is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_data_get_info_with_layout(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t *image_data_info);\n\n/**\n * @brief Creates an agent specific image handle to an image with an\n * opaque image data layout.\n *\n * @details Images with an opaque image data layout created with\n * different access permissions but matching image descriptors and\n * same agent can share the same image data if\n * ::HSA_EXT_IMAGE_CAPABILITY_ACCESS_INVARIANT_DATA_LAYOUT is reported\n * by ::hsa_ext_image_get_capability for the image format specified in\n * the image descriptor. Image descriptors match if they have the same\n * values, with the exception that s-form channel orders match the\n * corresponding non-s-form channel order and vice versa.\n *\n * If necessary, an application can use image operations (import,\n * export, copy, clear) to prepare the image for the intended use\n * regardless of the access permissions.\n *\n * @param[in] agent agent to be associated with the image handle created.\n *\n * @param[in] image_descriptor Pointer to an image descriptor. Must not be NULL.\n *\n * @param[in] image_data Image data buffer that must have been allocated\n * according to the size and alignment requirements dictated by\n * ::hsa_ext_image_data_get_info. Must not be NULL.\n *\n * Any previous memory contents are preserved upon creation. The application is\n * responsible for ensuring that the lifetime of the image data exceeds that of\n * all the associated images.\n *\n * @param[in] access_permission Access permission of the image when\n * accessed by agent. The access permission defines how the agent\n * is allowed to access the image using the image handle created and\n * must match the corresponding HSAIL image handle type. The agent\n * must support the image format specified in @p image_descriptor for\n * the given @p access_permission.\n *\n * @param[out] image Pointer to a memory location where the HSA runtime stores\n * the newly created image handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED The agent\n * does not have the capability to support the image format contained\n * in @p image_descriptor using the specified @p access_permission.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED The agent\n * does not support the image dimensions specified by @p\n * image_descriptor using the specified @p access_permission.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * support the creation of more image handles with the given @p access_permission).\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_descriptor is NULL, @p\n * image_data is NULL, @p image_data does not have a valid alignment,\n * @p access_permission is not a valid access permission\n * value, or @p image is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_create(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_t *image);\n\n/**\n * @brief Creates an agent specific image handle to an image with an explicit\n * image data layout.\n *\n * @details Images with an explicit image data layout created with\n * different access permissions but matching image descriptors and\n * matching image layout can share the same image data if\n * ::HSA_EXT_IMAGE_CAPABILITY_ACCESS_INVARIANT_DATA_LAYOUT is reported\n * by ::hsa_ext_image_get_capability_with_layout for the image format\n * specified in the image descriptor and specified image data\n * layout. Image descriptors match if they have the same values, with\n * the exception that s-form channel orders match the corresponding\n * non-s-form channel order and vice versa. Image layouts match if\n * they are the same image data layout and use the same image row and\n * slice values.\n *\n * If necessary, an application can use image operations (import, export, copy,\n * clear) to prepare the image for the intended use regardless of the access\n * permissions.\n *\n * @param[in] agent agent to be associated with the image handle created.\n *\n * @param[in] image_descriptor Pointer to an image descriptor. Must not be NULL.\n *\n * @param[in] image_data Image data buffer that must have been allocated\n * according to the size and alignment requirements dictated by\n * ::hsa_ext_image_data_get_info_with_layout. Must not be NULL.\n *\n * Any previous memory contents are preserved upon creation. The application is\n * responsible for ensuring that the lifetime of the image data exceeds that of\n * all the associated images.\n *\n * @param[in] access_permission Access permission of the image when\n * accessed by the agent. The access permission defines how the agent\n * is allowed to access the image and must match the corresponding\n * HSAIL image handle type. The agent must support the image format\n * specified in @p image_descriptor for the given @p access_permission\n * and @p image_data_layout.\n *\n * @param[in] image_data_layout The image data layout to use for the\n * @p image_data. It is invalid to use\n * ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE; use ::hsa_ext_image_create\n * instead.\n *\n * @param[in] image_data_row_pitch The size in bytes for a single row\n * of the image in the image data. If 0 is specified then the default\n * row pitch value is used: image width * image element byte size.\n * The value used must be greater than or equal to the default row\n * pitch, and be a multiple of the image element byte size. For the\n * linear image layout it must also be a multiple of the image linear\n * row pitch alignment for the agents that will access the image data\n * using image instructions.\n *\n * @param[in] image_data_slice_pitch The size in bytes of a single\n * slice of a 3D image, or the size in bytes of each image layer in an\n * image array in the image data. If 0 is specified then the default\n * slice pitch value is used: row pitch * height if geometry is\n * ::HSA_EXT_IMAGE_GEOMETRY_3D, ::HSA_EXT_IMAGE_GEOMETRY_2DA, or\n * ::HSA_EXT_IMAGE_GEOMETRY_2DADEPTH; row pitch if geometry is\n * ::HSA_EXT_IMAGE_GEOMETRY_1DA; and 0 otherwise. The value used must\n * be 0 if the default slice pitch is 0, be greater than or equal to\n * the default slice pitch, and be a multiple of the row pitch.\n *\n * @param[out] image Pointer to a memory location where the HSA runtime stores\n * the newly created image handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_FORMAT_UNSUPPORTED The agent does\n * not have the capability to support the image format contained in the image\n * descriptor using the specified @p access_permission and @p image_data_layout.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_SIZE_UNSUPPORTED The agent\n * does not support the image dimensions specified by @p\n * image_descriptor using the specified @p access_permission and @p\n * image_data_layout.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_IMAGE_PITCH_UNSUPPORTED The agent does\n * not support the row and slice pitch specified by @p image_data_row_pitch\n * and @p image_data_slice_pitch, or the values are invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * support the creation of more image handles with the given @p access_permission).\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p image_descriptor is NULL, @p\n * image_data is NULL, @p image_data does not have a valid alignment,\n * @p image_data_layout is ::HSA_EXT_IMAGE_DATA_LAYOUT_OPAQUE,\n * or @p image is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_create_with_layout(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_t *image);\n\n/**\n * @brief Destroy an image handle previously created using ::hsa_ext_image_create or\n * ::hsa_ext_image_create_with_layout.\n *\n * @details Destroying the image handle does not free the associated image data,\n * or modify its contents. The application should not destroy an image handle while\n * there are references to it queued for execution or currently being used in a\n * kernel dispatch.\n *\n * @param[in] agent Agent associated with the image handle.\n *\n * @param[in] image Image handle to destroy.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n */\nhsa_status_t HSA_API hsa_ext_image_destroy(\n    hsa_agent_t agent,\n    hsa_ext_image_t image);\n\n/**\n * @brief Copies a portion of one image (the source) to another image (the\n * destination).\n *\n * @details The source and destination image formats should be the\n * same, with the exception that s-form channel orders match the\n * corresponding non-s-form channel order and vice versa. For example,\n * it is allowed to copy a source image with a channel order of\n * HSA_EXT_IMAGE_CHANNEL_ORDER_SRGB to a destination image with a\n * channel order of HSA_EXT_IMAGE_CHANNEL_ORDER_RGB.\n *\n * The source and destination images do not have to be of the same geometry and\n * appropriate scaling is performed by the HSA runtime. It is possible to copy\n * subregions between any combinations of source and destination geometries, provided\n * that the dimensions of the subregions are the same. For example, it is\n * allowed to copy a rectangular region from a 2D image to a slice of a 3D\n * image.\n *\n * If the source and destination image data overlap, or the combination of\n * offset and range references an out-out-bounds element in any of the images,\n * the behavior is undefined.\n *\n * @param[in] agent Agent associated with both the source and destination image handles.\n *\n * @param[in] src_image Image handle of source image. The agent associated with the source\n * image handle must be identical to that of the destination image.\n *\n * @param[in] src_offset Pointer to the offset within the source image where to\n * copy the data from. Must not be NULL.\n *\n * @param[in] dst_image Image handle of destination image.\n *\n * @param[in] dst_offset Pointer to the offset within the destination\n * image where to copy the data. Must not be NULL.\n *\n * @param[in] range Dimensions of the image portion to be copied. The HSA\n * runtime computes the size of the image data to be copied using this\n * argument. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p src_offset is\n * NULL, @p dst_offset is NULL, or @p range is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_copy(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    const hsa_dim3_t* src_offset,\n    hsa_ext_image_t dst_image,\n    const hsa_dim3_t* dst_offset,\n    const hsa_dim3_t* range);\n\n/**\n * @brief Image region.\n */\ntypedef struct hsa_ext_image_region_s {\n   /**\n    * Offset within an image (in coordinates).\n    */\n    hsa_dim3_t offset;\n\n   /**\n    * Dimension size of the image range (in coordinates). The x, y, and z dimensions\n    * correspond to width, height, and depth or index respectively.\n    */\n    hsa_dim3_t range;\n} hsa_ext_image_region_t;\n\n/**\n * @brief Import a linearly organized image data from memory directly to an\n * image handle.\n *\n * @details This operation updates the image data referenced by the image handle\n * from the source memory. The size of the data imported from memory is\n * implicitly derived from the image region.\n *\n * It is the application's responsibility to avoid out of bounds memory access.\n *\n * None of the source memory or destination image data memory can\n * overlap. Overlapping of any of the source and destination image\n * data memory within the import operation produces undefined results.\n *\n * @param[in] agent Agent associated with the image handle.\n *\n * @param[in] src_memory Source memory. Must not be NULL.\n *\n * @param[in] src_row_pitch The size in bytes of a single row of the image in the\n * source memory. If the value is smaller than the destination image region\n * width * image element byte size, then region width * image element byte\n * size is used.\n *\n * @param[in] src_slice_pitch The size in bytes of a single 2D slice of a 3D image,\n * or the size in bytes of each image layer in an image array in the source memory.\n * If the geometry is ::HSA_EXT_IMAGE_GEOMETRY_1DA and the value is smaller than the\n * value used for @p src_row_pitch, then the value used for @p src_row_pitch is used.\n * If the geometry is ::HSA_EXT_IMAGE_GEOMETRY_3D, ::HSA_EXT_IMAGE_GEOMETRY_2DA, or\n * HSA_EXT_IMAGE_GEOMETRY_2DADEPTH and the value is smaller than the value used for\n * @p src_row_pitch * destination image region height, then the value used for\n * @p src_row_pitch * destination image region height is used.\n * Otherwise, the value is not used.\n *\n * @param[in] dst_image Image handle of destination image.\n *\n * @param[in] image_region Pointer to the image region to be updated. Must not\n * be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p src_memory is NULL, or @p\n * image_region is NULL.\n *\n */\nhsa_status_t HSA_API hsa_ext_image_import(\n    hsa_agent_t agent,\n    const void *src_memory,\n    size_t src_row_pitch,\n    size_t src_slice_pitch,\n    hsa_ext_image_t dst_image,\n    const hsa_ext_image_region_t *image_region);\n\n/**\n * @brief Export the image data to linearly organized memory.\n *\n * @details The operation updates the destination memory with the image data of\n * @p src_image. The size of the data exported to memory is implicitly derived\n * from the image region.\n *\n * It is the application's responsibility to avoid out of bounds memory access.\n *\n * None of the destination memory or source image data memory can\n * overlap. Overlapping of any of the source and destination image\n * data memory within the export operation produces undefined results.\n *\n * @param[in] agent Agent associated with the image handle.\n *\n * @param[in] src_image Image handle of source image.\n *\n * @param[in] dst_memory Destination memory. Must not be NULL.\n *\n * @param[in] dst_row_pitch The size in bytes of a single row of the image in the\n * destination memory. If the value is smaller than the source image region\n * width * image element byte size, then region width * image element byte\n * size is used.\n *\n * @param[in] dst_slice_pitch The size in bytes of a single 2D slice of a 3D image,\n * or the size in bytes of each image in an image array in the destination memory.\n * If the geometry is ::HSA_EXT_IMAGE_GEOMETRY_1DA and the value is smaller than the\n * value used for @p dst_row_pitch, then the value used for @p dst_row_pitch is used.\n * If the geometry is ::HSA_EXT_IMAGE_GEOMETRY_3D, ::HSA_EXT_IMAGE_GEOMETRY_2DA, or\n * HSA_EXT_IMAGE_GEOMETRY_2DADEPTH and the value is smaller than the value used for\n * @p dst_row_pitch * source image region height, then the value used for\n * @p dst_row_pitch * source image region height is used.\n * Otherwise, the value is not used.\n *\n * @param[in] image_region Pointer to the image region to be exported. Must not\n * be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p dst_memory is NULL, or @p\n * image_region is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_export(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    void *dst_memory,\n    size_t dst_row_pitch,\n    size_t dst_slice_pitch,\n    const hsa_ext_image_region_t *image_region);\n\n/**\n * @brief Clear a region of an image so that every image element has\n * the specified value.\n *\n * @param[in] agent Agent associated with the image handle.\n *\n * @param[in] image Image handle for image to be cleared.\n *\n * @param[in] data The value to which to set each image element being\n * cleared. It is specified as an array of image component values. The\n * number of array elements must match the number of access components\n * for the image channel order. The type of each array element must\n * match the image access type of the image channel type. When the\n * value is used to set the value of an image element, the conversion\n * method corresponding to the image channel type is used. See the\n * <em>Channel Order</em> section and <em>Channel Type</em> section in\n * the <em>HSA Programming Reference Manual</em> for more\n * information. Must not be NULL.\n *\n * @param[in] image_region Pointer to the image region to clear. Must not be\n * NULL. If the region references an out-out-bounds element, the behavior is\n * undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p data is NULL, or @p\n * image_region is NULL.\n */\nhsa_status_t HSA_API hsa_ext_image_clear(\n    hsa_agent_t agent,\n    hsa_ext_image_t image,\n    const void* data,\n    const hsa_ext_image_region_t *image_region);\n\n/**\n * @brief Sampler handle. Samplers are populated by\n * ::hsa_ext_sampler_create or ::hsa_ext_sampler_create_v2. Sampler handles are only unique\n *  within an agent, not across agents.\n */\ntypedef struct hsa_ext_sampler_s {\n  /**\n   *  Opaque handle. For a given agent, two handles reference the same object of\n   *  the enclosing type if and only if they are equal.\n   */\n    uint64_t handle;\n} hsa_ext_sampler_t;\n\n/**\n * @brief Sampler address modes. The sampler address mode describes\n * the processing of out-of-range image coordinates. See the\n * <em>Addressing Mode</em> section in the <em>HSA Programming Reference\n * Manual</em> for definitions on each address mode. The values\n * match the BRIG type @p hsa_ext_brig_sampler_addressing_t.\n */\ntypedef enum {\n  /**\n   * Out-of-range coordinates are not handled.\n   */\n  HSA_EXT_SAMPLER_ADDRESSING_MODE_UNDEFINED = 0,\n\n  /**\n   * Clamp out-of-range coordinates to the image edge.\n   */\n  HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE = 1,\n\n  /**\n   * Clamp out-of-range coordinates to the image border color.\n   */\n  HSA_EXT_SAMPLER_ADDRESSING_MODE_CLAMP_TO_BORDER = 2,\n\n  /**\n   * Wrap out-of-range coordinates back into the valid coordinate\n   * range so the image appears as repeated tiles.\n   */\n  HSA_EXT_SAMPLER_ADDRESSING_MODE_REPEAT = 3,\n\n  /**\n   * Mirror out-of-range coordinates back into the valid coordinate\n   * range so the image appears as repeated tiles with every other\n   * tile a reflection.\n   */\n  HSA_EXT_SAMPLER_ADDRESSING_MODE_MIRRORED_REPEAT = 4\n\n} hsa_ext_sampler_addressing_mode_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_ext_sampler_addressing_mode_t constants.\n */\ntypedef uint32_t hsa_ext_sampler_addressing_mode32_t;\n\n/**\n * @brief Sampler coordinate normalization modes. See the\n * <em>Coordinate Normalization Mode</em> section in the <em>HSA\n * Programming Reference Manual</em> for definitions on each\n * coordinate normalization mode. The values match the BRIG type @p\n * hsa_ext_brig_sampler_coord_normalization_t.\n */\ntypedef enum {\n\n  /**\n   * Coordinates are used to directly address an image element.\n   */\n  HSA_EXT_SAMPLER_COORDINATE_MODE_UNNORMALIZED = 0,\n\n  /**\n   * Coordinates are scaled by the image dimension size before being\n   * used to address an image element.\n   */\n  HSA_EXT_SAMPLER_COORDINATE_MODE_NORMALIZED = 1\n\n} hsa_ext_sampler_coordinate_mode_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_ext_sampler_coordinate_mode_t constants.\n */\ntypedef uint32_t hsa_ext_sampler_coordinate_mode32_t;\n    \n\n/**\n * @brief Sampler filter modes. See the <em>Filter Mode</em> section\n * in the <em>HSA Programming Reference Manual</em> for definitions\n * on each address mode. The enumeration values match the BRIG type @p\n * hsa_ext_brig_sampler_filter_t.\n */\ntypedef enum {\n  /**\n   * Filter to the image element nearest (in Manhattan distance) to the\n   * specified coordinate.\n   */\n  HSA_EXT_SAMPLER_FILTER_MODE_NEAREST = 0,\n\n  /**\n   * Filter to the image element calculated by combining the elements in a 2x2\n   * square block or 2x2x2 cube block around the specified coordinate. The\n   * elements are combined using linear interpolation.\n   */\n  HSA_EXT_SAMPLER_FILTER_MODE_LINEAR = 1\n\n} hsa_ext_sampler_filter_mode_t;\n\n/**\n * @brief A fixed-size type used to represent ::hsa_ext_sampler_filter_mode_t constants.\n */\ntypedef uint32_t hsa_ext_sampler_filter_mode32_t;\n\n/**\n * @brief Implementation independent sampler descriptor.\n */\ntypedef struct hsa_ext_sampler_descriptor_s {\n  /**\n   * Sampler coordinate mode describes the normalization of image coordinates.\n   */\n  hsa_ext_sampler_coordinate_mode32_t coordinate_mode;\n\n  /**\n   * Sampler filter type describes the type of sampling performed.\n   */\n  hsa_ext_sampler_filter_mode32_t filter_mode;\n\n  /**\n   * Sampler address mode describes the processing of out-of-range image\n   * coordinates.\n   */\n  hsa_ext_sampler_addressing_mode32_t address_mode;\n} hsa_ext_sampler_descriptor_t;\n\n/**\n * @brief Implementation independent sampler descriptor v2 which supports\n *  different address modes in X, Y and Z axises.\n */\ntypedef struct hsa_ext_sampler_descriptor_v2_s {\n  /**\n   * Sampler coordinate mode describes the normalization of image coordinates.\n   */\n  hsa_ext_sampler_coordinate_mode32_t coordinate_mode;\n\n  /**\n   * Sampler filter type describes the type of sampling performed.\n   */\n  hsa_ext_sampler_filter_mode32_t filter_mode;\n\n  /**\n   * Sampler address mode describes the processing of out-of-range image\n   * coordinates.\n   */\n  hsa_ext_sampler_addressing_mode32_t address_modes[3]; // in X, Y and Z axises\n} hsa_ext_sampler_descriptor_v2_t;\n\n/**\n * @brief Create an agent specific sampler handle for a given agent\n * independent sampler descriptor and agent.\n *\n * @param[in] agent Agent to be associated with the sampler handle created.\n *\n * @param[in] sampler_descriptor Pointer to a sampler descriptor. Must not be\n * NULL.\n *\n * @param[out] sampler Memory location where the HSA runtime stores the newly\n * created sampler handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_SAMPLER_DESCRIPTOR_UNSUPPORTED The\n * @p agent does not have the capability to support the properties\n * specified by @p sampler_descriptor or it is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p sampler_descriptor is NULL, or\n * @p sampler is NULL.\n */\nhsa_status_t HSA_API hsa_ext_sampler_create(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler);\n\n/**\n * @brief Create an agent specific sampler handle for a given agent\n * independent sampler descriptor v2 and agent.\n *\n * @param[in] agent Agent to be associated with the sampler handle created.\n *\n * @param[in] sampler_descriptor v2 Pointer to a sampler descriptor. Must not be\n * NULL.\n *\n * @param[out] sampler Memory location where the HSA runtime stores the newly\n * created sampler handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n *\n * @retval ::HSA_EXT_STATUS_ERROR_SAMPLER_DESCRIPTOR_UNSUPPORTED The\n * @p agent does not have the capability to support the properties\n * specified by @p sampler_descriptor or it is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to allocate\n * the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p sampler_descriptor is NULL, or\n * @p sampler is NULL.\n */\nhsa_status_t HSA_API hsa_ext_sampler_create_v2(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_v2_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler);\n\n/**\n * @brief Destroy a sampler handle previously created using ::hsa_ext_sampler_create or\n * ::hsa_ext_sampler_create_v2.\n *\n * @details The sampler handle should not be destroyed while there are\n * references to it queued for execution or currently being used in a\n * kernel dispatch.\n *\n * @param[in] agent Agent associated with the sampler handle.\n *\n * @param[in] sampler Sampler handle to destroy.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_AGENT The agent is invalid.\n */\nhsa_status_t HSA_API hsa_ext_sampler_destroy(\n    hsa_agent_t agent,\n    hsa_ext_sampler_t sampler);\n\n\n#define hsa_ext_images_1_00\n\n/**\n * @brief The function pointer table for the images v1.00 extension. Can be returned by ::hsa_system_get_extension_table or ::hsa_system_get_major_extension_table.\n */\ntypedef struct hsa_ext_images_1_00_pfn_s {\n\n  hsa_status_t (*hsa_ext_image_get_capability)(\n    hsa_agent_t agent,\n    hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t *image_format,\n    uint32_t *capability_mask);\n\n  hsa_status_t (*hsa_ext_image_data_get_info)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_info_t *image_data_info);\n\n  hsa_status_t (*hsa_ext_image_create)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_t *image);\n\n  hsa_status_t (*hsa_ext_image_destroy)(\n    hsa_agent_t agent,\n    hsa_ext_image_t image);\n\n  hsa_status_t (*hsa_ext_image_copy)(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    const hsa_dim3_t* src_offset,\n    hsa_ext_image_t dst_image,\n    const hsa_dim3_t* dst_offset,\n    const hsa_dim3_t* range);\n\n  hsa_status_t (*hsa_ext_image_import)(\n    hsa_agent_t agent,\n    const void *src_memory,\n    size_t src_row_pitch,\n    size_t src_slice_pitch,\n    hsa_ext_image_t dst_image,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_image_export)(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    void *dst_memory,\n    size_t dst_row_pitch,\n    size_t dst_slice_pitch,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_image_clear)(\n    hsa_agent_t agent,\n    hsa_ext_image_t image,\n    const void* data,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_sampler_create)(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler);\n\n  hsa_status_t (*hsa_ext_sampler_destroy)(\n    hsa_agent_t agent,\n    hsa_ext_sampler_t sampler);\n\n} hsa_ext_images_1_00_pfn_t;\n\n#define hsa_ext_images_1\n\n/**\n * @brief The function pointer table for the images v1 extension. Can be returned by ::hsa_system_get_extension_table or ::hsa_system_get_major_extension_table.\n */\ntypedef struct hsa_ext_images_1_pfn_s {\n\n  hsa_status_t (*hsa_ext_image_get_capability)(\n    hsa_agent_t agent,\n    hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t *image_format,\n    uint32_t *capability_mask);\n\n  hsa_status_t (*hsa_ext_image_data_get_info)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_info_t *image_data_info);\n\n  hsa_status_t (*hsa_ext_image_create)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_t *image);\n\n  hsa_status_t (*hsa_ext_image_destroy)(\n    hsa_agent_t agent,\n    hsa_ext_image_t image);\n\n  hsa_status_t (*hsa_ext_image_copy)(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    const hsa_dim3_t* src_offset,\n    hsa_ext_image_t dst_image,\n    const hsa_dim3_t* dst_offset,\n    const hsa_dim3_t* range);\n\n  hsa_status_t (*hsa_ext_image_import)(\n    hsa_agent_t agent,\n    const void *src_memory,\n    size_t src_row_pitch,\n    size_t src_slice_pitch,\n    hsa_ext_image_t dst_image,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_image_export)(\n    hsa_agent_t agent,\n    hsa_ext_image_t src_image,\n    void *dst_memory,\n    size_t dst_row_pitch,\n    size_t dst_slice_pitch,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_image_clear)(\n    hsa_agent_t agent,\n    hsa_ext_image_t image,\n    const void* data,\n    const hsa_ext_image_region_t *image_region);\n\n  hsa_status_t (*hsa_ext_sampler_create)(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler);\n\n  hsa_status_t (*hsa_ext_sampler_destroy)(\n    hsa_agent_t agent,\n    hsa_ext_sampler_t sampler);\n\n  hsa_status_t (*hsa_ext_image_get_capability_with_layout)(\n    hsa_agent_t agent,\n    hsa_ext_image_geometry_t geometry,\n    const hsa_ext_image_format_t *image_format,\n    hsa_ext_image_data_layout_t image_data_layout,\n    uint32_t *capability_mask);\n\n  hsa_status_t (*hsa_ext_image_data_get_info_with_layout)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_data_info_t *image_data_info);\n\n  hsa_status_t (*hsa_ext_image_create_with_layout)(\n    hsa_agent_t agent,\n    const hsa_ext_image_descriptor_t *image_descriptor,\n    const void *image_data,\n    hsa_access_permission_t access_permission,\n    hsa_ext_image_data_layout_t image_data_layout,\n    size_t image_data_row_pitch,\n    size_t image_data_slice_pitch,\n    hsa_ext_image_t *image);\n\n  hsa_status_t (*hsa_ext_sampler_create_v2)(\n    hsa_agent_t agent,\n    const hsa_ext_sampler_descriptor_v2_t *sampler_descriptor,\n    hsa_ext_sampler_t *sampler);\n\n} hsa_ext_images_1_pfn_t;\n/** @} */\n    \n#ifdef __cplusplus\n}  // end extern \"C\" block\n#endif /*__cplusplus*/ \n\n#endif\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ven_amd_aqlprofile.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2017-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef OPENSRC_HSA_RUNTIME_INC_HSA_VEN_AMD_AQLPROFILE_H_\n#define OPENSRC_HSA_RUNTIME_INC_HSA_VEN_AMD_AQLPROFILE_H_\n\n#include <stdint.h>\n#include \"hsa.h\"\n\n#define HSA_AQLPROFILE_VERSION_MAJOR 2\n#define HSA_AQLPROFILE_VERSION_MINOR 0\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif  // __cplusplus\n\n////////////////////////////////////////////////////////////////////////////////\n// Library version\nuint32_t hsa_ven_amd_aqlprofile_version_major();\nuint32_t hsa_ven_amd_aqlprofile_version_minor();\n\n///////////////////////////////////////////////////////////////////////\n// Library API:\n// The library provides helper methods for instantiation of\n// the profile context object and for populating of the start\n// and stop AQL packets. The profile object contains a profiling\n// events list and needed for profiling buffers descriptors,\n// a command buffer and an output data buffer. To check if there\n// was an error the library methods return a status code. Also\n// the library provides methods for querying required buffers\n// attributes, to validate the event attributes and to get profiling\n// output data.\n//\n// Returned status:\n//     hsa_status_t – HSA status codes are used from hsa.h header\n//\n// Supported profiling features:\n//\n// Supported profiling events\ntypedef enum {\n  HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC = 0,\n  HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_TRACE = 1,\n} hsa_ven_amd_aqlprofile_event_type_t;\n\n// Supported performance counters (PMC) blocks\n// The block ID is the same for a block instances set, for example\n// each block instance from the TCC block set, TCC0, TCC1, …, TCCN\n// will have the same block ID HSA_VEN_AMD_AQLPROFILE_BLOCKS_TCC.\ntypedef enum {\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_CPC = 0,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_CPF = 1,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GDS = 2,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GRBM = 3,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GRBMSE = 4,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SPI = 5,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SQ = 6,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SQCS = 7,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SRBM = 8,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SX = 9,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TA = 10,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TCA = 11,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TCC = 12,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TCP = 13,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_TD = 14,\n  // Memory related blocks\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCARB = 15,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCHUB = 16,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCMCBVM = 17,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCSEQ = 18,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCVML2 = 19,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MCXBAR = 20,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_ATC = 21,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_ATCL2 = 22,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GCEA = 23,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_RPB = 24,\n  // System blocks\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_SDMA = 25,\n  // GFX10 added blocks\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GL1A = 26,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GL1C = 27,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GL2A = 28,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GL2C = 29,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GCR = 30,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_GUS = 31,\n\n  // UMC & MMEA System Blocks\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_UMC = 32,\n  HSA_VEN_AMD_AQLPROFILE_BLOCK_NAME_MMEA = 33,\n\n  HSA_VEN_AMD_AQLPROFILE_BLOCKS_NUMBER\n} hsa_ven_amd_aqlprofile_block_name_t;\n\n// PMC event object structure\n// ‘counter_id’ value is specified in GFXIPs perfcounter user guides\n// which is the counters select value, “Performance Counters Selection”\n// chapter.\ntypedef struct {\n  hsa_ven_amd_aqlprofile_block_name_t block_name;\n  uint32_t block_index;\n  uint32_t counter_id;\n} hsa_ven_amd_aqlprofile_event_t;\n\n// Check if event is valid for the specific GPU\nhsa_status_t hsa_ven_amd_aqlprofile_validate_event(\n    hsa_agent_t agent,                            // HSA handle for the profiling GPU\n    const hsa_ven_amd_aqlprofile_event_t* event,  // [in] Pointer on validated event\n    bool* result);                                // [out] True if the event valid, False otherwise\n\n// Profiling parameters\n// All parameters are generic and if not applicable for a specific\n// profile configuration then error status will be returned.\ntypedef enum {\n  /**\n   * Select the target compute unit (wgp) for profiling.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_COMPUTE_UNIT_TARGET = 0,\n  /**\n   * VMID Mask\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_VM_ID_MASK = 1,\n  /**\n   * Legacy. Deprecated.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_MASK = 2,\n  /**\n   * Legacy. Deprecated.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_TOKEN_MASK = 3,\n  /**\n   * Legacy. Deprecated.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_TOKEN_MASK2 = 4,\n  /**\n   * Shader engine mask for selection.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SE_MASK = 5,\n  /**\n   * Legacy. Deprecated.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SAMPLE_RATE = 6,\n  /**\n   * Legacy. Deprecated.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_K_CONCURRENT = 7,\n  /**\n   * Set SIMD Mask (GFX9) or SIMD ID for collection (Navi)\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SIMD_SELECTION = 8,\n  /**\n   * Set true for occupancy collection only.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_OCCUPANCY_MODE = 9,\n  /**\n   * ATT collection max data size, in MB. Shared among shader engines.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_ATT_BUFFER_SIZE = 10,\n  /**\n   * Mask of which compute units to generate perfcounters. GFX9 only.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_PERFCOUNTER_MASK = 240,\n  /**\n   * Select collection period for perfcounters. GFX9 only.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_PERFCOUNTER_CTRL = 241,\n  /**\n   * Select perfcounter ID (SQ block) for collection. GFX9 only.\n   */\n  HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_PERFCOUNTER_NAME = 242,\n} hsa_ven_amd_aqlprofile_parameter_name_t;\n\n// Profile parameter object\ntypedef struct {\n  hsa_ven_amd_aqlprofile_parameter_name_t parameter_name;\n  uint32_t value;\n} hsa_ven_amd_aqlprofile_parameter_t;\n\ntypedef enum {\n  HSA_VEN_AMD_AQLPROFILE_ATT_CHANNEL_0 = 0,\n  HSA_VEN_AMD_AQLPROFILE_ATT_CHANNEL_1,\n  HSA_VEN_AMD_AQLPROFILE_ATT_CHANNEL_2,\n  HSA_VEN_AMD_AQLPROFILE_ATT_CHANNEL_3\n} hsa_ven_amd_aqlprofile_att_marker_channel_t;\n\n//\n// Profile context object:\n// The library provides a profile object structure which contains\n// the events array, a buffer for the profiling start/stop commands\n// and a buffer for the output data.\n// The buffers are specified by the buffer descriptors and allocated\n// by the application. The buffers allocation attributes, the command\n// buffer size, the PMC output buffer size as well as profiling output\n// data can be get using the generic get profile info helper _get_info.\n//\n// Buffer descriptor\ntypedef struct {\n  void* ptr;\n  uint32_t size;\n} hsa_ven_amd_aqlprofile_descriptor_t;\n\n// Profile context object structure, contains profiling events list and\n// needed for profiling buffers descriptors, a command buffer and\n// an output data buffer\ntypedef struct {\n  hsa_agent_t agent;                                     // GFXIP handle\n  hsa_ven_amd_aqlprofile_event_type_t type;              // Events type\n  const hsa_ven_amd_aqlprofile_event_t* events;          // Events array\n  uint32_t event_count;                                  // Events count\n  const hsa_ven_amd_aqlprofile_parameter_t* parameters;  // Parameters array\n  uint32_t parameter_count;                              // Parameters count\n  hsa_ven_amd_aqlprofile_descriptor_t output_buffer;     // Output buffer\n  hsa_ven_amd_aqlprofile_descriptor_t command_buffer;    // PM4 commands\n} hsa_ven_amd_aqlprofile_profile_t;\n\n//\n// AQL packets populating methods:\n// The helper methods to populate provided by the application START and\n// STOP AQL packets which the application is required to submit before and\n// after profiled GPU task packets respectively.\n//\n// AQL Vendor Specific packet which carries a PM4 command\ntypedef struct {\n  uint16_t header;\n  uint16_t pm4_command[27];\n  hsa_signal_t completion_signal;\n} hsa_ext_amd_aql_pm4_packet_t;\n\n// Method to populate the provided AQL packet with profiling start commands\n// Only 'pm4_command' fields of the packet are set and the application\n// is responsible to set Vendor Specific header type a completion signal\nhsa_status_t hsa_ven_amd_aqlprofile_start(\n    hsa_ven_amd_aqlprofile_profile_t* profile,        // [in,out] profile context object\n    hsa_ext_amd_aql_pm4_packet_t* aql_start_packet);  // [out] profile start AQL packet\n\n// Method to populate the provided AQL packet with profiling stop commands\n// Only 'pm4_command' fields of the packet are set and the application\n// is responsible to set Vendor Specific header type and a completion signal\nhsa_status_t hsa_ven_amd_aqlprofile_stop(\n    const hsa_ven_amd_aqlprofile_profile_t* profile,  // [in] profile context object\n    hsa_ext_amd_aql_pm4_packet_t* aql_stop_packet);   // [out] profile stop AQL packet\n\n// Method to populate the provided AQL packet with profiling read commands\n// Only 'pm4_command' fields of the packet are set and the application\n// is responsible to set Vendor Specific header type and a completion signal\nhsa_status_t hsa_ven_amd_aqlprofile_read(\n    const hsa_ven_amd_aqlprofile_profile_t* profile,  // [in] profile context object\n    hsa_ext_amd_aql_pm4_packet_t* aql_read_packet);   // [out] profile stop AQL packet\n\n// Legacy devices, PM4 profiling packet size\nconst unsigned HSA_VEN_AMD_AQLPROFILE_LEGACY_PM4_PACKET_SIZE = 192;\n// Legacy devices, converting the profiling AQL packet to PM4 packet blob\nhsa_status_t hsa_ven_amd_aqlprofile_legacy_get_pm4(\n    const hsa_ext_amd_aql_pm4_packet_t* aql_packet,  // [in] AQL packet\n    void* data);                                     // [out] PM4 packet blob\n\n// Method to add a marker (correlation ID) into the ATT buffer.\nhsa_status_t hsa_ven_amd_aqlprofile_att_marker(\n    hsa_ven_amd_aqlprofile_profile_t* profile,            // [in,out] profile context object\n    hsa_ext_amd_aql_pm4_packet_t* aql_marker_packet,      // [out] profile marker AQL packet\n    uint32_t data,                                        // [in] Data to be inserted\n    hsa_ven_amd_aqlprofile_att_marker_channel_t channel); // [in] Comm channel\n\n//\n// Get profile info:\n// Generic method for getting various profile info including profile buffers\n// attributes like the command buffer size and the profiling PMC results.\n// It’s implied that all counters are 64bit values.\n//\n// Profile generic output data:\ntypedef struct {\n  uint32_t sample_id;  // PMC sample or trace buffer index\n  union {\n    struct {\n      hsa_ven_amd_aqlprofile_event_t event;  // PMC event\n      uint64_t result;                       // PMC result\n    } pmc_data;\n    hsa_ven_amd_aqlprofile_descriptor_t trace_data;  // Trace output data descriptor\n  };\n} hsa_ven_amd_aqlprofile_info_data_t;\n\n// ID query type\ntypedef struct {\n  const char* name;\n  uint32_t id;\n  uint32_t instance_count;\n} hsa_ven_amd_aqlprofile_id_query_t;\n\n// Profile attributes\ntypedef enum {\n  HSA_VEN_AMD_AQLPROFILE_INFO_COMMAND_BUFFER_SIZE = 0,  // get_info returns uint32_t value\n  HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA_SIZE = 1,        // get_info returns uint32_t value\n  HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA = 2,             // get_info returns PMC uint64_t value\n                                                        // in info_data object\n  HSA_VEN_AMD_AQLPROFILE_INFO_TRACE_DATA = 3,           // get_info returns trace buffer ptr/size\n                                                        // in info_data object\n  HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS = 4,       // get_info returns number of block counter\n  HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_ID = 5,             // get_info returns block id, instances\n                                                        // by name string using _id_query_t\n  HSA_VEN_AMD_AQLPROFILE_INFO_ENABLE_CMD = 6,           // get_info returns size/pointer for\n                                                        // counters enable command buffer\n  HSA_VEN_AMD_AQLPROFILE_INFO_DISABLE_CMD = 7,          // get_info returns size/pointer for\n                                                        // counters disable command buffer\n} hsa_ven_amd_aqlprofile_info_type_t;\n\n\n// Definition of output data iterator callback\ntypedef hsa_status_t (*hsa_ven_amd_aqlprofile_data_callback_t)(\n    hsa_ven_amd_aqlprofile_info_type_t info_type,   // [in] data type, PMC or trace data\n    hsa_ven_amd_aqlprofile_info_data_t* info_data,  // [in] info_data object\n    void* callback_data);                           // [in,out] data passed to the callback\n\n// Method for getting the profile info\nhsa_status_t hsa_ven_amd_aqlprofile_get_info(\n    const hsa_ven_amd_aqlprofile_profile_t* profile,  // [in] profile context object\n    hsa_ven_amd_aqlprofile_info_type_t attribute,     // [in] requested profile attribute\n    void* value);                                     // [in,out] returned value\n\n// Method for iterating the events output data\nhsa_status_t hsa_ven_amd_aqlprofile_iterate_data(\n    const hsa_ven_amd_aqlprofile_profile_t* profile,  // [in] profile context object\n    hsa_ven_amd_aqlprofile_data_callback_t callback,  // [in] callback to iterate the output data\n    void* data);                                      // [in,out] data passed to the callback\n\n// Return error string\nhsa_status_t hsa_ven_amd_aqlprofile_error_string(\n    const char** str);  // [out] pointer on the error string\n\n/**\n * @brief Callback for iteration of all possible event coordinate IDs and coordinate names.\n */\ntypedef hsa_status_t(*hsa_ven_amd_aqlprofile_eventname_callback_t)(int id, const char* name);\n/**\n * @brief Iterate over all possible event coordinate IDs and their names.\n */\nhsa_status_t hsa_ven_amd_aqlprofile_iterate_event_ids(hsa_ven_amd_aqlprofile_eventname_callback_t);\n\n/**\n * @brief Iterate over all event coordinates for a given agent_t and event_t.\n * @param position A counting sequence indicating callback number.\n * @param id Coordinate ID as in _iterate_event_ids.\n * @param extent Coordinate extent indicating maximum allowed instances.\n * @param coordinate The coordinate, in the range [0,extent-1].\n * @param name Coordinate name as in _iterate_event_ids.\n * @param userdata Userdata returned from _iterate_event_coord function.\n */\ntypedef hsa_status_t(*hsa_ven_amd_aqlprofile_coordinate_callback_t)(\n  int position,\n  int id,\n  int extent,\n  int coordinate,\n  const char* name,\n  void* userdata\n);\n\n/**\n * @brief Iterate over all event coordinates for a given agent_t and event_t.\n * @param[in] agent HSA agent.\n * @param[in] event The event ID and block ID to iterate for.\n * @param[in] sample_id aqlprofile_info_data_t.sample_id returned from _aqlprofile_iterate_data.\n * @param[in] callback Callback function to return the coordinates.\n * @param[in] userdata Arbitrary data pointer to be sent back to the user via callback.\n */\nhsa_status_t hsa_ven_amd_aqlprofile_iterate_event_coord(\n  hsa_agent_t agent,\n  hsa_ven_amd_aqlprofile_event_t event,\n  uint32_t sample_id,\n  hsa_ven_amd_aqlprofile_coordinate_callback_t callback,\n  void* userdata\n);\n\n/**\n * @brief Extension version.\n */\n#define hsa_ven_amd_aqlprofile_VERSION_MAJOR 1\n#define hsa_ven_amd_aqlprofile_LIB(suff) \"libhsa-amd-aqlprofile\" suff \".so\"\n\n#ifdef HSA_LARGE_MODEL\nstatic const char kAqlProfileLib[] = hsa_ven_amd_aqlprofile_LIB(\"64\");\n#else\nstatic const char kAqlProfileLib[] = hsa_ven_amd_aqlprofile_LIB(\"\");\n#endif\n\n/**\n * @brief Extension function table.\n */\ntypedef struct hsa_ven_amd_aqlprofile_1_00_pfn_s {\n  uint32_t (*hsa_ven_amd_aqlprofile_version_major)();\n  uint32_t (*hsa_ven_amd_aqlprofile_version_minor)();\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_error_string)(\n      const char** str);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_validate_event)(\n      hsa_agent_t agent,\n      const hsa_ven_amd_aqlprofile_event_t* event,\n      bool* result);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_start)(\n      hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ext_amd_aql_pm4_packet_t* aql_start_packet);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_stop)(\n      const hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ext_amd_aql_pm4_packet_t* aql_stop_packet);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_read)(\n      const hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ext_amd_aql_pm4_packet_t* aql_read_packet);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_legacy_get_pm4)(\n      const hsa_ext_amd_aql_pm4_packet_t* aql_packet,\n      void* data);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_get_info)(\n      const hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ven_amd_aqlprofile_info_type_t attribute,\n      void* value);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_iterate_data)(\n      const hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ven_amd_aqlprofile_data_callback_t callback,\n      void* data);\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_iterate_event_ids)(\n      hsa_ven_amd_aqlprofile_eventname_callback_t\n  );\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_iterate_event_coord)(\n      hsa_agent_t agent,\n      hsa_ven_amd_aqlprofile_event_t event,\n      uint32_t sample_id,\n      hsa_ven_amd_aqlprofile_coordinate_callback_t callback,\n      void* userdata\n  );\n\n  hsa_status_t (*hsa_ven_amd_aqlprofile_att_marker)(\n      hsa_ven_amd_aqlprofile_profile_t* profile,\n      hsa_ext_amd_aql_pm4_packet_t* aql_packet,\n      uint32_t data,\n      hsa_ven_amd_aqlprofile_att_marker_channel_t channel\n  );\n} hsa_ven_amd_aqlprofile_1_00_pfn_t;\n\ntypedef hsa_ven_amd_aqlprofile_1_00_pfn_t hsa_ven_amd_aqlprofile_pfn_t;\n\n#ifdef __cplusplus\n}\n#endif  // __cplusplus\n\n#endif  // OPENSRC_HSA_RUNTIME_INC_HSA_VEN_AMD_AQLPROFILE_H_\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ven_amd_loader.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n// HSA AMD extension for additional loader functionality.\n\n#ifndef HSA_VEN_AMD_LOADER_H\n#define HSA_VEN_AMD_LOADER_H\n\n#include \"hsa.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/**\n * @brief Queries equivalent host address for given @p device_address, and\n * records it in @p host_address.\n *\n *\n * @details Contents of memory pointed to by @p host_address would be identical\n * to contents of memory pointed to by @p device_address. Only difference\n * between the two is host accessibility: @p host_address is always accessible\n * from host, @p device_address might not be accessible from host.\n *\n * If @p device_address already points to host accessible memory, then the value\n * of @p device_address is simply copied into @p host_address.\n *\n * The lifetime of @p host_address is the same as the lifetime of @p\n * device_address, and both lifetimes are limited by the lifetime of the\n * executable that is managing these addresses.\n *\n *\n * @param[in] device_address Device address to query equivalent host address\n * for.\n *\n * @param[out] host_address Pointer to application-allocated buffer to record\n * queried equivalent host address in.\n *\n *\n * @retval HSA_STATUS_SUCCESS Function is executed successfully.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED Runtime is not initialized.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p device_address is invalid or\n * null, or @p host_address is null.\n */\nhsa_status_t hsa_ven_amd_loader_query_host_address(\n  const void *device_address,\n  const void **host_address);\n\n/**\n * @brief The storage type of the code object that is backing loaded memory\n * segment.\n */\ntypedef enum {\n  /**\n   * Loaded memory segment is not backed by any code object (anonymous), as the\n   * case would be with BSS (uninitialized data).\n   */\n  HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE = 0,\n  /**\n   * Loaded memory segment is backed by the code object that is stored in the\n   * file.\n   */\n  HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE = 1,\n  /**\n   * Loaded memory segment is backed by the code object that is stored in the\n   * memory.\n   */\n  HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY = 2\n} hsa_ven_amd_loader_code_object_storage_type_t;\n\n/**\n * @brief Loaded memory segment descriptor.\n *\n *\n * @details Loaded memory segment descriptor describes underlying loaded memory\n * segment. Loaded memory segment is created/allocated by the executable during\n * the loading of the code object that is backing underlying memory segment.\n *\n * The lifetime of underlying memory segment is limited by the lifetime of the\n * executable that is managing underlying memory segment.\n */\ntypedef struct hsa_ven_amd_loader_segment_descriptor_s {\n  /**\n   * Agent underlying memory segment is allocated on. If the code object that is\n   * backing underlying memory segment is program code object, then 0.\n   */\n  hsa_agent_t agent;\n  /**\n   * Executable that is managing this underlying memory segment.\n   */\n  hsa_executable_t executable;\n  /**\n   * Storage type of the code object that is backing underlying memory segment.\n   */\n  hsa_ven_amd_loader_code_object_storage_type_t code_object_storage_type;\n  /**\n   * If the storage type of the code object that is backing underlying memory\n   * segment is:\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then null;\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE, then null-terminated\n   *     filepath to the code object;\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY, then host\n   *     accessible pointer to the first byte of the code object.\n   */\n  const void *code_object_storage_base;\n  /**\n   * If the storage type of the code object that is backing underlying memory\n   * segment is:\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then 0;\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE, then the length of\n   *     the filepath to the code object (including null-terminating character);\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY, then the size, in\n   *     bytes, of the memory occupied by the code object.\n   */\n  size_t code_object_storage_size;\n  /**\n   * If the storage type of the code object that is backing underlying memory\n   * segment is:\n   *   - HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_NONE, then 0;\n   *   - other, then offset, in bytes, from the beginning of the code object to\n   *     the first byte in the code object data is copied from.\n   */\n  size_t code_object_storage_offset;\n  /**\n   * Starting address of the underlying memory segment.\n   */\n  const void *segment_base;\n  /**\n   * Size, in bytes, of the underlying memory segment.\n   */\n  size_t segment_size;\n} hsa_ven_amd_loader_segment_descriptor_t;\n\n/**\n * @brief Either queries loaded memory segment descriptors, or total number of\n * loaded memory segment descriptors.\n *\n *\n * @details If @p segment_descriptors is not null and @p num_segment_descriptors\n * points to number that exactly matches total number of loaded memory segment\n * descriptors, then queries loaded memory segment descriptors, and records them\n * in @p segment_descriptors. If @p segment_descriptors is null and @p\n * num_segment_descriptors points to zero, then queries total number of loaded\n * memory segment descriptors, and records it in @p num_segment_descriptors. In\n * all other cases returns appropriate error code (see below).\n *\n * The caller of this function is responsible for the allocation/deallocation\n * and the lifetime of @p segment_descriptors and @p num_segment_descriptors.\n *\n * The lifetime of loaded memory segments that are described by queried loaded\n * memory segment descriptors is limited by the lifetime of the executable that\n * is managing loaded memory segments.\n *\n * Queried loaded memory segment descriptors are always self-consistent: they\n * describe a complete set of loaded memory segments that are being backed by\n * fully loaded code objects that are present at the time (i.e. this function\n * is blocked until all executable manipulations are fully complete).\n *\n *\n * @param[out] segment_descriptors Pointer to application-allocated buffer to\n * record queried loaded memory segment descriptors in. Can be null if @p\n * num_segment_descriptors points to zero.\n *\n * @param[in,out] num_segment_descriptors Pointer to application-allocated\n * buffer that contains either total number of loaded memory segment descriptors\n * or zero.\n *\n *\n * @retval HSA_STATUS_SUCCESS Function is executed successfully.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED Runtime is not initialized.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT @p segment_descriptors is null\n * while @p num_segment_descriptors points to non-zero number, @p\n * segment_descriptors is not null while @p num_segment_descriptors points to\n * zero, or @p num_segment_descriptors is null.\n *\n * @retval HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS @p num_segment_descriptors\n * does not point to number that exactly matches total number of loaded memory\n * segment descriptors.\n */\nhsa_status_t hsa_ven_amd_loader_query_segment_descriptors(\n  hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n  size_t *num_segment_descriptors);\n\n/**\n * @brief Obtains the handle of executable to which the device address belongs.\n *\n * @details This method should not be used to obtain executable handle by using\n * a host address. The executable returned is expected to be alive until its\n * destroyed by the user.\n *\n * @retval HSA_STATUS_SUCCESS Function is executed successfully.\n *\n * @retval HSA_STATUS_ERROR_NOT_INITIALIZED Runtime is not initialized.\n *\n * @retval HSA_STATUS_ERROR_INVALID_ARGUMENT The input is invalid or there\n * is no exectuable found for this kernel code object.\n */\nhsa_status_t hsa_ven_amd_loader_query_executable(\n  const void *device_address,\n  hsa_executable_t *executable);\n\n//===----------------------------------------------------------------------===//\n\n/**\n * @brief Iterate over the loaded code objects in an executable, and invoke\n * an application-defined callback on every iteration.\n *\n * @param[in] executable Executable.\n *\n * @param[in] callback Callback to be invoked once per loaded code object. The\n * HSA runtime passes three arguments to the callback: the executable, a\n * loaded code object, and the application data. If @p callback returns a\n * status other than ::HSA_STATUS_SUCCESS for a particular iteration, the\n * traversal stops and\n * ::hsa_ven_amd_loader_executable_iterate_loaded_code_objects returns that\n * status value.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_EXECUTABLE The executable is invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n */\nhsa_status_t hsa_ven_amd_loader_executable_iterate_loaded_code_objects(\n  hsa_executable_t executable,\n  hsa_status_t (*callback)(\n    hsa_executable_t executable,\n    hsa_loaded_code_object_t loaded_code_object,\n    void *data),\n  void *data);\n\n/**\n * @brief Loaded code object kind.\n */\ntypedef enum {\n  /**\n   * Program code object.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_KIND_PROGRAM = 1,\n  /**\n   * Agent code object.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_KIND_AGENT = 2\n} hsa_ven_amd_loader_loaded_code_object_kind_t;\n\n/**\n * @brief Loaded code object attributes.\n */\ntypedef enum hsa_ven_amd_loader_loaded_code_object_info_e {\n  /**\n   * The executable in which this loaded code object is loaded. The\n   * type of this attribute is ::hsa_executable_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_EXECUTABLE = 1,\n  /**\n   * The kind of this loaded code object. The type of this attribute is\n   * ::uint32_t interpreted as ::hsa_ven_amd_loader_loaded_code_object_kind_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_KIND = 2,\n  /**\n   * The agent on which this loaded code object is loaded. The\n   * value of this attribute is only defined if\n   * ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_KIND is\n   * ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_KIND_AGENT. The type of this\n   * attribute is ::hsa_agent_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_AGENT = 3,\n  /**\n   * The storage type of the code object reader used to load the loaded code object.\n   * The type of this attribute is ::uint32_t interpreted as a\n   * ::hsa_ven_amd_loader_code_object_storage_type_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE = 4,\n  /**\n   * The memory address of the first byte of the code object that was loaaded.\n   * The value of this attribute is only defined if\n   * ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE is\n   * ::HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY. The type of this\n   * attribute is ::uint64_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_BASE = 5,\n  /**\n   * The memory size in bytes of the code object that was loaaded.\n   * The value of this attribute is only defined if\n   * ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE is\n   * ::HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY. The type of this\n   * attribute is ::uint64_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_MEMORY_SIZE = 6,\n  /**\n   * The file descriptor of the code object that was loaaded.\n   * The value of this attribute is only defined if\n   * ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_TYPE is\n   * ::HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_FILE. The type of this\n   * attribute is ::int.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_CODE_OBJECT_STORAGE_FILE = 7,\n  /**\n   * The signed byte address difference of the memory address at which the code\n   * object is loaded minus the virtual address specified in the code object\n   * that is loaded. The value of this attribute is only defined if the\n   * executable in which the code object is loaded is froozen. The type of this\n   * attribute is ::int64_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_DELTA = 8,\n  /**\n   * The base memory address at which the code object is loaded. This is the\n   * base address of the allocation for the lowest addressed segment of the code\n   * object that is loaded. Note that any non-loaded segments before the first\n   * loaded segment are ignored. The value of this attribute is only defined if\n   * the executable in which the code object is loaded is froozen. The type of\n   * this attribute is ::uint64_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_BASE = 9,\n  /**\n   * The byte size of the loaded code objects contiguous memory allocation. The\n   * value of this attribute is only defined if the executable in which the code\n   * object is loaded is froozen. The type of this attribute is ::uint64_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_SIZE = 10,\n  /**\n   * The length of the URI in bytes, not including the NUL terminator. The type\n   * of this attribute is uint32_t.\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI_LENGTH = 11,\n  /**\n   * The URI name from which the code object was loaded. The type of this\n   * attribute is a NUL terminated \\p char* with the length equal to the value\n   * of ::HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI_LENGTH attribute.\n   * The URI name syntax is defined by the following BNF syntax:\n   *\n   *     code_object_uri ::== file_uri | memory_uri\n   *     file_uri        ::== \"file://\" file_path [ range_specifier ]\n   *     memory_uri      ::== \"memory://\" process_id range_specifier\n   *     range_specifier ::== [ \"#\" | \"?\" ] \"offset=\" number \"&\" \"size=\" number\n   *     file_path       ::== URI_ENCODED_OS_FILE_PATH\n   *     process_id      ::== DECIMAL_NUMBER\n   *     number          ::== HEX_NUMBER | DECIMAL_NUMBER | OCTAL_NUMBER\n   *\n   * ``number`` is a C integral literal where hexadecimal values are prefixed by\n   * \"0x\" or \"0X\", and octal values by \"0\".\n   *\n   * ``file_path`` is the file's path specified as a URI encoded UTF-8 string.\n   * In URI encoding, every character that is not in the regular expression\n   * ``[a-zA-Z0-9/_.~-]`` is encoded as two uppercase hexidecimal digits\n   * proceeded by \"%\".  Directories in the path are separated by \"/\".\n   *\n   * ``offset`` is a 0-based byte offset to the start of the code object.  For a\n   * file URI, it is from the start of the file specified by the ``file_path``,\n   * and if omitted defaults to 0. For a memory URI, it is the memory address\n   * and is required.\n   *\n   * ``size`` is the number of bytes in the code object.  For a file URI, if\n   * omitted it defaults to the size of the file.  It is required for a memory\n   * URI.\n   *\n   * ``process_id`` is the identity of the process owning the memory.  For Linux\n   * it is the C unsigned integral decimal literal for the process ID (PID).\n   *\n   * For example:\n   *\n   *     file:///dir1/dir2/file1\n   *     file:///dir3/dir4/file2#offset=0x2000&size=3000\n   *     memory://1234#offset=0x20000&size=3000\n   */\n  HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI = 12,\n} hsa_ven_amd_loader_loaded_code_object_info_t;\n\n/**\n * @brief Get the current value of an attribute for a given loaded code\n * object.\n *\n * @param[in] loaded_code_object Loaded code object.\n *\n * @param[in] attribute Attribute to query.\n *\n * @param[out] value Pointer to an application-allocated buffer where to store\n * the value of the attribute. If the buffer passed by the application is not\n * large enough to hold the value of @p attribute, the behavior is undefined.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT The loaded code object is\n * invalid.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p attribute is an invalid\n * loaded code object attribute, or @p value is NULL.\n */\nhsa_status_t hsa_ven_amd_loader_loaded_code_object_get_info(\n  hsa_loaded_code_object_t loaded_code_object,\n  hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n  void *value);\n\n//===----------------------------------------------------------------------===//\n\n/**\n * @brief Create a code object reader to operate on a file with size and offset.\n *\n * @param[in] file File descriptor. The file must have been opened by\n * application with at least read permissions prior calling this function. The\n * file must contain a vendor-specific code object.\n *\n * The file is owned and managed by the application; the lifetime of the file\n * descriptor must exceed that of any associated code object reader.\n *\n * @param[in] size Size of the code object embedded in @p file.\n *\n * @param[in] offset 0-based offset relative to the beginning of the @p file\n * that denotes the beginning of the code object embedded within the @p file.\n *\n * @param[out] code_object_reader Memory location to store the newly created\n * code object reader handle. Must not be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_FILE @p file is not opened with at least\n * read permissions. This condition may also be reported as\n * ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT_READER by the\n * ::hsa_executable_load_agent_code_object function.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT The bytes starting at offset\n * do not form a valid code object. If file size is 0. Or offset > file size.\n * This condition may also be reported as\n * ::HSA_STATUS_ERROR_INVALID_CODE_OBJECT by the\n * ::hsa_executable_load_agent_code_object function.\n *\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES The HSA runtime failed to\n * allocate the required resources.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p code_object_reader is NULL.\n */\nhsa_status_t\nhsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size(\n    hsa_file_t file,\n    size_t offset,\n    size_t size,\n    hsa_code_object_reader_t *code_object_reader);\n\n//===----------------------------------------------------------------------===//\n\n/**\n * @brief Iterate over the available executables, and invoke an\n * application-defined callback on every iteration. While\n * ::hsa_ven_amd_loader_iterate_executables is executing any calls to\n * ::hsa_executable_create, ::hsa_executable_create_alt, or\n * ::hsa_executable_destroy will be blocked.\n *\n * @param[in] callback Callback to be invoked once per executable. The HSA\n * runtime passes two arguments to the callback: the executable and the\n * application data. If @p callback returns a status other than\n * ::HSA_STATUS_SUCCESS for a particular iteration, the traversal stops and\n * ::hsa_ven_amd_loader_iterate_executables returns that status value. If\n * @p callback invokes ::hsa_executable_create, ::hsa_executable_create_alt, or\n * ::hsa_executable_destroy then the behavior is undefined.\n *\n * @param[in] data Application data that is passed to @p callback on every\n * iteration. May be NULL.\n *\n * @retval ::HSA_STATUS_SUCCESS The function has been executed successfully.\n *\n * @retval ::HSA_STATUS_ERROR_NOT_INITIALIZED The HSA runtime has not been\n * initialized.\n *\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT @p callback is NULL.\n*/\nhsa_status_t\nhsa_ven_amd_loader_iterate_executables(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      void *data),\n    void *data);\n\n//===----------------------------------------------------------------------===//\n\n/**\n * @brief Extension version.\n */\n#define hsa_ven_amd_loader 001003\n\n/**\n * @brief Extension function table version 1.00.\n */\ntypedef struct hsa_ven_amd_loader_1_00_pfn_s {\n  hsa_status_t (*hsa_ven_amd_loader_query_host_address)(\n    const void *device_address,\n    const void **host_address);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_segment_descriptors)(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_executable)(\n    const void *device_address,\n    hsa_executable_t *executable);\n} hsa_ven_amd_loader_1_00_pfn_t;\n\n/**\n * @brief Extension function table version 1.01.\n */\ntypedef struct hsa_ven_amd_loader_1_01_pfn_s {\n  hsa_status_t (*hsa_ven_amd_loader_query_host_address)(\n    const void *device_address,\n    const void **host_address);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_segment_descriptors)(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_executable)(\n    const void *device_address,\n    hsa_executable_t *executable);\n\n  hsa_status_t (*hsa_ven_amd_loader_executable_iterate_loaded_code_objects)(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      hsa_loaded_code_object_t loaded_code_object,\n      void *data),\n    void *data);\n\n  hsa_status_t (*hsa_ven_amd_loader_loaded_code_object_get_info)(\n    hsa_loaded_code_object_t loaded_code_object,\n    hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n    void *value);\n} hsa_ven_amd_loader_1_01_pfn_t;\n\n/**\n * @brief Extension function table version 1.02.\n */\ntypedef struct hsa_ven_amd_loader_1_02_pfn_s {\n  hsa_status_t (*hsa_ven_amd_loader_query_host_address)(\n    const void *device_address,\n    const void **host_address);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_segment_descriptors)(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_executable)(\n    const void *device_address,\n    hsa_executable_t *executable);\n\n  hsa_status_t (*hsa_ven_amd_loader_executable_iterate_loaded_code_objects)(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      hsa_loaded_code_object_t loaded_code_object,\n      void *data),\n    void *data);\n\n  hsa_status_t (*hsa_ven_amd_loader_loaded_code_object_get_info)(\n    hsa_loaded_code_object_t loaded_code_object,\n    hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n    void *value);\n\n  hsa_status_t\n    (*hsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size)(\n      hsa_file_t file,\n      size_t offset,\n      size_t size,\n      hsa_code_object_reader_t *code_object_reader);\n} hsa_ven_amd_loader_1_02_pfn_t;\n\n/**\n * @brief Extension function table version 1.03.\n */\ntypedef struct hsa_ven_amd_loader_1_03_pfn_s {\n  hsa_status_t (*hsa_ven_amd_loader_query_host_address)(\n    const void *device_address,\n    const void **host_address);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_segment_descriptors)(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors);\n\n  hsa_status_t (*hsa_ven_amd_loader_query_executable)(\n    const void *device_address,\n    hsa_executable_t *executable);\n\n  hsa_status_t (*hsa_ven_amd_loader_executable_iterate_loaded_code_objects)(\n    hsa_executable_t executable,\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      hsa_loaded_code_object_t loaded_code_object,\n      void *data),\n    void *data);\n\n  hsa_status_t (*hsa_ven_amd_loader_loaded_code_object_get_info)(\n    hsa_loaded_code_object_t loaded_code_object,\n    hsa_ven_amd_loader_loaded_code_object_info_t attribute,\n    void *value);\n\n  hsa_status_t\n    (*hsa_ven_amd_loader_code_object_reader_create_from_file_with_offset_size)(\n      hsa_file_t file,\n      size_t offset,\n      size_t size,\n      hsa_code_object_reader_t *code_object_reader);\n\n  hsa_status_t\n    (*hsa_ven_amd_loader_iterate_executables)(\n      hsa_status_t (*callback)(\n        hsa_executable_t executable,\n        void *data),\n      void *data);\n} hsa_ven_amd_loader_1_03_pfn_t;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* HSA_VEN_AMD_LOADER_H */\n"
  },
  {
    "path": "runtime/hsa-runtime/inc/hsa_ven_amd_pc_sampling.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_VEN_AMD_PC_SAMPLING_H\n#define HSA_VEN_AMD_PC_SAMPLING_H\n\n#include \"hsa.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /*__cplusplus*/\n\n\n/**\n * @brief HSA AMD Vendor PC Sampling APIs\n * EXPERIMENTAL: All PC Sampling APIs are currently in an experimental phase and the APIs may be\n * modified extensively in the future\n */\n\n/**\n * @brief PC Sampling sample data for hosttrap sampling method\n */\ntypedef struct {\n  uint64_t pc;\n  uint64_t exec_mask;\n  uint32_t workgroup_id_x;\n  uint32_t workgroup_id_y;\n  uint32_t workgroup_id_z;\n  uint32_t wave_in_wg : 6;\n  uint32_t chiplet    : 3;   // Currently not used\n  uint32_t reserved   : 23;\n  uint32_t hw_id;\n  uint32_t reserved0;\n  uint64_t reserved1;\n  uint64_t timestamp;\n  uint64_t correlation_id;\n} perf_sample_hosttrap_v1_t;\n\n/**\n * @brief PC Sampling sample data for stochastic sampling method\n */\ntypedef struct {\n  uint64_t pc;\n  uint64_t exec_mask;\n  uint32_t workgroup_id_x;\n  uint32_t workgroup_id_y;\n  uint32_t workgroup_id_z;\n  uint32_t wave_in_wg : 6;\n  uint32_t chiplet    : 3;   // Currently not used\n  uint32_t reserved   : 23;\n  uint32_t hw_id;\n  uint32_t perf_snapshot_data;\n  uint32_t perf_snapshot_data1;\n  uint32_t perf_snapshot_data2;\n  uint64_t timestamp;\n  uint64_t correlation_id;\n} perf_sample_snapshot_v1_t;\n\n/**\n * @brief PC Sampling method kinds\n */\ntypedef enum {\n  HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1,\n  HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1\n} hsa_ven_amd_pcs_method_kind_t;\n\n/**\n * @brief PC Sampling interval unit type\n */\ntypedef enum {\n  HSA_VEN_AMD_PCS_INTERVAL_UNITS_MICRO_SECONDS,\n  HSA_VEN_AMD_PCS_INTERVAL_UNITS_CLOCK_CYCLES,\n  HSA_VEN_AMD_PCS_INTERVAL_UNITS_INSTRUCTIONS\n} hsa_ven_amd_pcs_units_t;\n\n/**\n * @brief HSA callback function to perform the copy onto a destination buffer\n *\n * If data_size is 0, HSA will stop current copy operation and keep remaining data in internal\n * buffers. Remaining contents of HSA internal buffers will be included in next\n * hsa_ven_amd_pcs_data_ready_callback_t. HSA internal buffers can also be drained by calling\n * hsa_ven_amd_pcs_flush.\n *\n * @param[in] hsa_callback_data private data to pass back to HSA. Provided in\n * hsa_ven_amd_pcs_data_ready_callback_t\n *\n * @param[in] data_size size of destination buffer in bytes.\n * @param[in] destination destination buffer\n * @retval    TBD: but could be used to indicate that there is no more data to be read.\n * Or indicate an error and abort of current copy operations\n */\ntypedef hsa_status_t (*hsa_ven_amd_pcs_data_copy_callback_t)(void* hsa_callback_data,\n                                                             size_t data_size, void* destination);\n\n/**\n * @brief HSA callback function to to indicate that there is data ready to be copied\n *\n * When the client receives this callback, the client should call back @p data_copy_callback for HSA\n * to perform the copy operation into an available buffer. @p data_copy_callback can be called back\n * multiple times with smaller @p data_size to split the copy operation.\n *\n * This callback must not call ::hsa_ven_amd_pcs_flush.\n *\n * @param[in] client_callback_data client private data passed in via\n * hsa_ven_amd_pcs_create/hsa_ven_amd_pcs_create_from_id\n * @param[in] data_size size of data available to be copied\n * @param[in] lost_sample_count number of lost samples since last call to\n * hsa_ven_amd_pcs_data_ready_callback_t.\n * @param[in] data_copy_callback callback function for HSA to perform the actual copy\n * @param[in] hsa_callback_data private data to pass back to HSA\n */\ntypedef void (*hsa_ven_amd_pcs_data_ready_callback_t)(\n    void* client_callback_data, size_t data_size, size_t lost_sample_count,\n    hsa_ven_amd_pcs_data_copy_callback_t data_copy_callback, void* hsa_callback_data);\n\n/**\n * @brief Opaque handle representing a sampling session.\n * Two sessions having same handle value represent the same session\n */\ntypedef struct {\n  uint64_t handle;\n} hsa_ven_amd_pcs_t;\n\n/**\n * @brief PC Sampling configuration flag options\n */\ntypedef enum {\n  /* The interval for this sampling method have to be a power of 2 */\n  HSA_VEN_AMD_PCS_CONFIGURATION_FLAGS_INTERVAL_POWER_OF_2 = (1 << 0)\n} hsa_ven_amd_pcs_configuration_flags_t;\n\n/**\n * @brief PC Sampling method information\n * Used to provide client with list of supported PC Sampling methods\n */\ntypedef struct {\n  hsa_ven_amd_pcs_method_kind_t method;\n  hsa_ven_amd_pcs_units_t units;\n  size_t min_interval;\n  size_t max_interval;\n  uint64_t flags;\n} hsa_ven_amd_pcs_configuration_t;\n\n/**\n * @brief Callback function to iterate through list of supported PC Sampling configurations\n *\n * @param[in] configuration one entry for supported PC Sampling method and configuration options\n * @param[in] callback_data client private callback data that was passed in when calling\n * hsa_ven_amd_pcs_iterate_configuration\n */\ntypedef hsa_status_t (*hsa_ven_amd_pcs_iterate_configuration_callback_t)(\n    const hsa_ven_amd_pcs_configuration_t* configuration, void* callback_data);\n\n/**\n * @brief Iterate through list of current supported PC Sampling configurations for this @p agent\n *\n * HSA will callback @p configuration_callback for each currently available PC Sampling\n * configuration. The list of currently available configurations may not be the complete list of\n * configurations supported on the @p agent. The list of currently available configurations may be\n * reduced if the @p agent is currently handling other PC sampling sessions.\n *\n * @param[in] agent target agent\n * @param[in] configuration_callback callback function to iterate through list of configurations\n * @param[in] callback_data client private callback data\n **/\nhsa_status_t hsa_ven_amd_pcs_iterate_configuration(\n    hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n    void* callback_data);\n\n/**\n * @brief  Create a PC Sampling session on @p agent\n *\n * Allocate the resources required for a PC Sampling session. The @p method, @p units, @p interval\n * parameters must be a legal configuration value, as described by the\n * hsa_ven_amd_pcs_configuration_t configurations passed to the callbacks of\n * hsa_ven_amd_pcs_iterate_configuration for this @p agent.\n * A successfull call may restrict the list of possible PC sampling methods available to subsequent\n * calls to hsa_ven_amd_pcs_iterate_configuration on the same agent as agents have limitations\n * on what types of PC sampling they can perform concurrently.\n * For all successful calls, hsa_ven_amd_pcs_destroy should be called to free this session.\n * The session will be in a stopped/inactive state after this call\n *\n * @param[in] agent target agent\n * @param[in] method method to use\n * @param[in] units sampling units\n * @param[in] interval sampling interval in @p units\n * @param[in] latency expected latency in microseconds for client to provide a buffer for the data\n * copy callback once HSA calls @p data_ready_callback. This is a performance hint to avoid the\n * buffer filling up before the client is notified that data is ready. HSA-runtime will estimate\n * how many samples are received within @p latency and call @p data_ready_callback ahead of time so\n * that the client has @p latency time to allocate the buffer before the HSA-runtime internal\n * buffers are full. The value of latency can be 0.\n * @param[in] buffer_size size of client buffer in bytes. @p data_ready_callback will be called once\n * HSA-runtime has enough samples to fill @p buffer_size. This needs to be a multiple of size of\n * perf_sample_hosttrap_v1_t or size of perf_sample_snapshot_v1_t.\n * @param[in] data_ready_callback client callback function that will be called when:\n *   1. There is enough samples fill a buffer with @p buffer_size  - estimated samples received\n *      within @p latency period.\n * OR\n *   2. When hsa_ven_amd_pcs_flush is called.\n * @param[in] client_callback_data client private data to be provided back when data_ready_callback\n * is called.\n * @param[out] pc_sampling PC sampling session handle used to reference this session when calling\n * hsa_ven_amd_pcs_start, hsa_ven_amd_pcs_stop, hsa_ven_amd_pcs_destroy\n *\n * @retval ::HSA_STATUS_SUCCESS session created successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT invalid parameters\n * @retval ::HSA_STATUS_ERROR_RESOURCE_BUSY agent currently handling another PC Sampling session and\n * cannot handle the type requested.\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Failed to allocate resources\n * @retval ::HSA_STATUS_ERROR Unexpected error\n **/\nhsa_status_t hsa_ven_amd_pcs_create(hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n                                    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency,\n                                    size_t buffer_size,\n                                    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback,\n                                    void* client_callback_data, hsa_ven_amd_pcs_t* pc_sampling);\n\n\n/**\n * @brief  Creates a PC Sampling session on @p agent. Assumes that the caller provides the\n * @p pcs_id generated by the previous call to the underlying driver that reserved PC sampling\n * on the @p agent.\n *\n * Similar to the @ref hsa_ven_amd_pcs_create with the difference that it inherits an existing\n * PC sampling session that was previously created in the underlying driver.\n *\n * Allocate the resources required for a PC Sampling session. The @p method, @p units, @p interval\n * parameters must be a legal configuration value, and match the parameters that we used to create\n * the underlying PC Sampling session in the underlying driver.\n * A successfull call may restrict the list of possible PC sampling methods available to subsequent\n * calls to hsa_ven_amd_pcs_iterate_configuration on the same agent as agents have limitations\n * on what types of PC sampling they can perform concurrently.\n * For all successful calls, hsa_ven_amd_pcs_destroy should be called to free this session.\n * The session will be in a stopped/inactive state after this call\n *\n * @param[in] pcs_id ID that uniquely identifies the PC sampling session within underlying driver\n * @param[in] agent target agent\n * @param[in] method method to use\n * @param[in] units sampling units\n * @param[in] interval sampling interval in @p units\n * @param[in] latency expected latency in microseconds for client to provide a buffer for the data\n * copy callback once HSA calls @p data_ready_callback. This is a performance hint to avoid the\n * buffer filling up before the client is notified that data is ready. HSA-runtime will estimate\n * how many samples are received within @p latency and call @p data_ready_callback ahead of time so\n * that the client has @p latency time to allocate the buffer before the HSA-runtime internal\n * buffers are full. The value of latency can be 0.\n * @param[in] buffer_size size of client buffer in bytes. @p data_ready_callback will be called once\n * HSA-runtime has enough samples to fill @p buffer_size. This needs to be a multiple of size of\n * perf_sample_hosttrap_v1_t or size of perf_sample_snapshot_v1_t.\n * @param[in] data_ready_callback client callback function that will be called when:\n *   1. There is enough samples fill a buffer with @p buffer_size  - estimated samples received\n *      within @p latency period.\n * OR\n *   2. When hsa_ven_amd_pcs_flush is called.\n * @param[in] client_callback_data client private data to be provided back when data_ready_callback\n * is called.\n * @param[out] pc_sampling PC sampling session handle used to reference this session when calling\n * hsa_ven_amd_pcs_start, hsa_ven_amd_pcs_stop, hsa_ven_amd_pcs_destroy\n *\n * @retval ::HSA_STATUS_SUCCESS session created successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT invalid parameters\n * @retval ::HSA_STATUS_ERROR_RESOURCE_BUSY agent currently handling another PC Sampling session and\n * cannot handle the type requested.\n * @retval ::HSA_STATUS_ERROR_OUT_OF_RESOURCES Failed to allocate resources\n * @retval ::HSA_STATUS_ERROR Unexpected error\n **/\nhsa_status_t hsa_ven_amd_pcs_create_from_id(\n    uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data,\n    hsa_ven_amd_pcs_t* pc_sampling);\n\n/**\n * @brief  Free a PC Sampling session on @p agent\n *\n * Free all the resources allocated for a PC Sampling session on @p agent\n * Internal buffers for this session will be lost.\n * If the session was active, the session will be stopped before it is destroyed.\n *\n * @param[in] pc_sampling PC sampling session handle\n *\n * @retval ::HSA_STATUS_SUCCESS Session destroyed successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid PC sampling handle\n * @retval ::HSA_STATUS_ERROR unexpected error\n */\nhsa_status_t hsa_ven_amd_pcs_destroy(hsa_ven_amd_pcs_t pc_sampling);\n\n/**\n * @brief  Start a PC Sampling session\n *\n * Activate a PC Sampling session that was previous created.\n * The session with be in a active state after this call\n * If the session was already active, this will result in a no-op and will return HSA_STATUS_SUCCESS\n *\n * @param[in] pc_sampling PC sampling session handle\n *\n * @retval ::HSA_STATUS_SUCCESS Session started successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid PC sampling handle\n * @retval ::HSA_STATUS_ERROR unexpected error\n */\nhsa_status_t hsa_ven_amd_pcs_start(hsa_ven_amd_pcs_t pc_sampling);\n\n/**\n * @brief  Stop a PC Sampling session\n *\n * Stop a session that is currently active\n * After a session is stopped HSA may still have some PC Sampling data in its internal buffers.\n * The internal buffers can be drained using hsa_ven_amd_pcs_flush. If the internal\n * buffers are not drained and the session is started again, the internal buffers will be available\n * on the next data_ready_callback.\n * If the session was already inactive, this will result in a no-op and will return\n * HSA_STATUS_SUCCESS\n *\n * @param[in] pc_sampling PC sampling session handle\n *\n * @retval ::HSA_STATUS_SUCCESS Session stopped successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid PC sampling handle\n */\nhsa_status_t hsa_ven_amd_pcs_stop(hsa_ven_amd_pcs_t pc_sampling);\n\n/**\n * @brief  Flush internal buffers for a PC Sampling session\n *\n * Drain internal buffers for a PC Sampling session. If internal buffers have available data,\n * this trigger a data_ready_callback.\n *\n * The function blocks until all PC samples associated with the @p pc_sampling session\n * generated prior to the function call have been communicated by invocations of\n * @p data_ready_callback having completed execution.\n *\n * @param[in] pc_sampling PC sampling session handle\n *\n * @retval ::HSA_STATUS_SUCCESS Session flushed successfully\n * @retval ::HSA_STATUS_ERROR_INVALID_ARGUMENT Invalid PC sampling handle\n */\nhsa_status_t hsa_ven_amd_pcs_flush(hsa_ven_amd_pcs_t pc_sampling);\n\n#define hsa_ven_amd_pc_sampling_1_00\n\n/**\n * @brief The function pointer table for the PC Sampling v1.00 extension. Can be returned by\n * ::hsa_system_get_extension_table or ::hsa_system_get_major_extension_table.\n */\ntypedef struct hsa_ven_amd_pc_sampling_1_00_pfn_t {\n  hsa_status_t (*hsa_ven_amd_pcs_iterate_configuration)(\n      hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n      void* callback_data);\n\n  hsa_status_t (*hsa_ven_amd_pcs_create)(hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n                                         hsa_ven_amd_pcs_units_t units, size_t interval,\n                                         size_t latency, size_t buffer_size,\n                                         hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback,\n                                         void* client_callback_data,\n                                         hsa_ven_amd_pcs_t* pc_sampling);\n\n  hsa_status_t (*hsa_ven_amd_pcs_create_from_id)(\n      uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n      hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size,\n      hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data,\n      hsa_ven_amd_pcs_t* pc_sampling);\n\n  hsa_status_t (*hsa_ven_amd_pcs_destroy)(hsa_ven_amd_pcs_t pc_sampling);\n\n  hsa_status_t (*hsa_ven_amd_pcs_start)(hsa_ven_amd_pcs_t pc_sampling);\n\n  hsa_status_t (*hsa_ven_amd_pcs_stop)(hsa_ven_amd_pcs_t pc_sampling);\n\n  hsa_status_t (*hsa_ven_amd_pcs_flush)(hsa_ven_amd_pcs_t pc_sampling);\n\n} hsa_ven_amd_pc_sampling_1_00_pfn_t;\n\n#ifdef __cplusplus\n}  // end extern \"C\" block\n#endif /*__cplusplus*/\n\n#endif /* HSA_VEN_AMD_PC_SAMPLING_H */\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_core_dump.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <unistd.h>\n#include <elf.h>\n#include <fcntl.h>\n#include <sys/resource.h>\n#include <cstring>\n#include <vector>\n#include <sstream>\n#include <fstream>\n#include <memory>\n#include \"core/util/utils.h\"\n#include \"core/inc/runtime.h\"\n#include \"./amd_hsa_code_util.hpp\"\n#include \"core/inc/amd_core_dump.hpp\"\n#include \"hsakmt/hsakmt.h\"\n\nconstexpr char SNAPSHOT_INFO_ALIGNMENT = 0x8;\nconstexpr uint32_t LOAD_ALIGNMENT_SHIFT = 4;\nconstexpr uint32_t NOTE_ALIGNMENT_SHIFT = 2;\nconst std::string PREFIX_FILE_NAME = \"gpucore\";\nconstexpr size_t MAX_BUFFER_SIZE = 4 * 1024 * 1024;\n\nnamespace rocr {\nnamespace amd {\nnamespace coredump {\n/* Implementation details */\nnamespace impl {\nclass PackageBuilder {\n public:\n  PackageBuilder() : st_(std::stringstream::out | std::stringstream::binary) {}\n  size_t Size() const { return st_.str().size(); }\n  template <typename T, typename = typename std::enable_if<!std::is_pointer<T>::value>::type>\n  void Write(const T& v) {\n    st_.write((char*)&v, sizeof(T));\n  }\n  void Write(const std::vector<uint8_t>& v) { st_.write((const char*)v.data(), v.size()); }\n  void Write(void* data, uint32_t size) { st_.write((const char*)data, size); }\n  bool GetBuffer(void* out) {\n    size_t sz = Size();\n\n    if (!sz) return false;\n    std::memcpy(out, st_.str().c_str(), sz);\n    return true;\n  }\n  void Print(void* buf, uint64_t size) {\n    int i;\n    for (i = 0; i < size; i++) debug_print(\"%02x \", 0xFF & ((uint8_t*)buf)[i]);\n    debug_print(\"\\n\");\n  }\n private:\n  std::stringstream st_;\n};\n\nenum SegmentType { LOAD, NOTE };\nstruct SegmentBuilder;\n\nstruct SegmentInfo {\n  SegmentType stype;\n  uint64_t vaddr = 0;\n  uint64_t size = 0;\n  uint32_t flags = 0;\n  SegmentBuilder* builder;\n};\n\nusing SegmentsInfo = std::vector<SegmentInfo>;\nusing rocr::amd::hsa::alignUp;\nstruct SegmentBuilder {\n  virtual ~SegmentBuilder() = default;\n  /* Find which segments needs to be created.  */\n  virtual hsa_status_t Collect(SegmentsInfo& segments) = 0;\n  /* Called to read a given SegmentInfo's data.  */\n  virtual hsa_status_t Read(void* buf, size_t buf_size, off_t offset) = 0;\n};\n\nstruct NoteSegmentBuilder : public SegmentBuilder {\n  hsa_status_t Collect(SegmentsInfo& segments) override {\n    void *runtime_ptr, *agents_ptr = NULL, *queues_ptr = NULL;\n    uint32_t runtime_size, agents_size, queue_size, n_entries, entry_size;\n    HsaVersionInfo versionInfo = {0};\n\n    if (HSAKMT_CALL(hsaKmtDbgEnable(&runtime_ptr, &runtime_size))) {\n      fprintf(stderr, \"Failed to enable debug interface, \"\n              \"debugger might be already attached.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n    std::unique_ptr<void, decltype(std::free) *> runtime_info(runtime_ptr, std::free);\n\n    if (HSAKMT_CALL(hsaKmtGetVersion(&versionInfo))) {\n      HSAKMT_CALL(hsaKmtDbgDisable());\n      fprintf(stderr, \"Failed to fetch driver ABI version.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n    /* Note version */\n    note_package_builder_.Write<uint64_t>(1);\n    /* Store version_major in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(versionInfo.KernelInterfaceMajorVersion);\n    /* Store version_minor in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(versionInfo.KernelInterfaceMinorVersion);\n    /* Store runtime_info_size in PT_NOTE package */\n    note_package_builder_.Write<uint64_t>(runtime_size);\n\n    if (HSAKMT_CALL(hsaKmtDbgGetDeviceData(&agents_ptr, &n_entries, &entry_size))) {\n       HSAKMT_CALL(hsaKmtDbgDisable());\n       fprintf(stderr, \"Failed to fetch agents snapshot.\\n\");\n       return HSA_STATUS_ERROR;\n    }\n    agents_size = n_entries * entry_size;\n    std::unique_ptr<void, decltype(std::free) *> agents_info(agents_ptr, std::free);\n    /* Store n_agents in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(n_entries);\n    /* Store agent_info_entry_size in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(entry_size);\n\n    if (HSAKMT_CALL(hsaKmtDbgGetQueueData(&queues_ptr, &n_entries, &entry_size, true))) {\n       HSAKMT_CALL(hsaKmtDbgDisable());\n       fprintf(stderr, \"Failed to fetch queues snapshot.\\n\");\n       return HSA_STATUS_ERROR;\n    }\n    queue_size = n_entries * entry_size;\n    std::unique_ptr<void, decltype(std::free) *> queues_info(queues_ptr, std::free);\n    /* Store n_queues in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(n_entries);\n    /* Store queue_info_entry_size in PT_NOTE package */\n    note_package_builder_.Write<uint32_t>(entry_size);\n\n    PushInfo(runtime_info.get(), runtime_size);\n    PushInfo(agents_info.get(), agents_size);\n    PushInfo(queues_info.get(), queue_size);\n    if (HSAKMT_CALL(hsaKmtDbgDisable())) {\n      fprintf(stderr, \"Failed to disable debug interface.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n\n    /* With note content, package this in the PT_NOTE.  */\n    PackageBuilder noteHeaderBuilder;\n    noteHeaderBuilder.Write<uint32_t> (7);  /* namesz */\n    noteHeaderBuilder.Write<uint32_t> (note_package_builder_.Size());\n    noteHeaderBuilder.Write<uint32_t> (NT_AMDGPU_CORE_STATE);  /* type.  */\n    noteHeaderBuilder.Write<char[8]> (\"AMDGPU\\0\");\n\n    raw_.resize(noteHeaderBuilder.Size() + note_package_builder_.Size());\n    if (!(noteHeaderBuilder.GetBuffer(raw_.data())\n          && note_package_builder_.GetBuffer(&raw_[noteHeaderBuilder.Size()]))) {\n      fprintf(stderr, \"Failed to build the NT_AMDGPU_CORE_STATE note.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n\n    SegmentInfo s;\n    s.stype = NOTE;\n    s.vaddr = 0;\n    s.size = raw_.size();\n    s.flags = 0;\n    s.builder = this;\n    segments.push_back(s);\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n  hsa_status_t Read(void* buf, size_t buf_size, off_t offset) override {\n    if (offset + buf_size >raw_.size ()) return HSA_STATUS_ERROR;\n    memcpy(buf, raw_.data() + offset, buf_size);\n    return HSA_STATUS_SUCCESS;\n  }\n\n private:\n  PackageBuilder note_package_builder_;\n  std::vector<unsigned char> raw_;\n\n  void PushInfo(void *data, uint32_t size) {\n    note_package_builder_.Write(data, size);\n    size = alignUp(size, SNAPSHOT_INFO_ALIGNMENT) - size;\n    for (int i = 0; i < size; i++)\n      note_package_builder_.Write<uint8_t>(0);\n  }\n};\n\nstruct LoadSegmentBuilder : public SegmentBuilder {\n  LoadSegmentBuilder() : fd_(open(\"/proc/self/mem\", O_RDONLY)) {}\n\n  ~LoadSegmentBuilder() {\n    if (fd_ != -1) close(fd_);\n  }\n\n  hsa_status_t Collect(SegmentsInfo& segments) override {\n    const std::string maps_path = \"/proc/self/maps\";\n    std::ifstream maps(maps_path);\n    if (!maps.is_open()) {\n      fprintf(stderr, \"Could not open '%s'\", maps_path.c_str());\n      return HSA_STATUS_ERROR;\n    }\n\n    std::string line;\n    while (std::getline(maps, line)) {\n      std::istringstream isl{ line };\n      std::string address, perms, offset, dev, inode, path;\n      if (!(isl >> address >> perms >> offset >> dev >> inode)) {\n        fprintf(stderr, \"Failed to parse '%s'\", maps_path.c_str());\n        return HSA_STATUS_ERROR;\n      }\n\n      std::getline(isl >> std::ws, path);\n\n      /* Look for the /dev/dri/renderD* files.  */\n      if (path.rfind(\"/dev/dri/renderD\", 0) == 0) {\n        uint64_t start, end;\n        if (sscanf(address.c_str(), \"%lx-%lx\", &start, &end) != 2) {\n          fprintf(stderr, \"Failed to parse '%s'\", maps_path.c_str());\n          return HSA_STATUS_ERROR;\n        }\n        uint32_t flags = SHF_ALLOC;\n        flags |= (perms.find('w', 0) != std::string::npos) ? SHF_WRITE : 0;\n        flags |= (perms.find('x', 0) != std::string::npos) ? SHF_EXECINSTR : 0;\n        uint64_t size = end - start;\n\n        debug_print(\"LOAD 0x%lx size: %ld\\n\", start, size);\n        SegmentInfo s;\n        s.stype = LOAD;\n        s.vaddr = start;\n        s.size = size;\n        s.flags = flags;\n        s.builder = this;\n        segments.push_back(s);\n       }\n     }\n     return HSA_STATUS_SUCCESS;\n  }\n\n  hsa_status_t Read(void* buf, size_t buf_size, off_t offset) override {\n    if (fd_ == -1) return HSA_STATUS_ERROR;\n\n    size_t done = 0;\n    ssize_t read;\n    do {\n      read = pread(fd_, static_cast<char *>(buf) + done, buf_size - done,\n                   offset + done);\n\n      if (read == -1 && errno != EINTR) {\n        perror(\"Failed to read GPU memory\");\n        return HSA_STATUS_ERROR;\n      }\n      else if (read > 0)\n        done += read;\n    } while (read != 0 && done < buf_size);\n\n    if (read == 0 && done < buf_size) {\n      fprintf(stderr, \"Reached unexpected EOF while reading VRAM.\\n\");\n      return HSA_STATUS_ERROR;\n    }\n\n    return HSA_STATUS_SUCCESS;\n  }\n\n private:\n  int fd_ = -1;\n};\n\nhsa_status_t build_core_dump(const std::string& filename, const SegmentsInfo& segments, size_t size_limit) {\n  std::unique_ptr<unsigned char[]> copy_buffer(new unsigned char[MAX_BUFFER_SIZE]);\n  if (!segments.size()) return HSA_STATUS_SUCCESS;\n  SegmentInfo front = segments.front();\n  off_t offset = sizeof(Elf64_Ehdr) + segments.size() * sizeof(Elf64_Phdr);\n\n  if (size_limit != -1 && (offset + front.size > size_limit)) {\n    debug_print(\"Core file size over limit\\n\");\n    return HSA_STATUS_SUCCESS;\n  }\n  int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);\n  if (fd == -1) {\n    perror(\"Failed to create GPU coredump\");\n    return HSA_STATUS_ERROR;\n  }\n  Elf64_Ehdr ehdr{};\n  ehdr.e_ident[EI_MAG0] = ELFMAG0;\n  ehdr.e_ident[EI_MAG1] = ELFMAG1;\n  ehdr.e_ident[EI_MAG2] = ELFMAG2;\n  ehdr.e_ident[EI_MAG3] = ELFMAG3;\n  ehdr.e_ident[EI_CLASS] = ELFCLASS64;\n  ehdr.e_ident[EI_DATA] = ELFDATA2LSB;\n  ehdr.e_ident[EI_VERSION] = EV_CURRENT;\n  ehdr.e_ident[EI_OSABI] = ELF::ELFOSABI_AMDGPU_HSA;\n  ehdr.e_ident[EI_ABIVERSION] = 0;\n  ehdr.e_type = ET_CORE;\n  ehdr.e_machine = ELF::EM_AMDGPU;\n  ehdr.e_version = EV_CURRENT;\n  ehdr.e_entry = 0;\n  ehdr.e_phoff = sizeof(Elf64_Ehdr);\n  ehdr.e_shoff = 0;\n  ehdr.e_flags = 0;\n  ehdr.e_ehsize = sizeof(Elf64_Ehdr);\n  ehdr.e_phentsize = sizeof(Elf64_Phdr);\n  ehdr.e_phnum = segments.size();\n  ehdr.e_shentsize = 0;\n  ehdr.e_shnum = 0;\n  ehdr.e_shstrndx = 0;\n\n  if (write(fd, &ehdr, sizeof(ehdr)) == -1) {\n    perror(\"Failed to write ELF header\");\n    close(fd);\n    return HSA_STATUS_ERROR;\n  }\n\n  /* Make sure that the underlying file has enough space for the file headers. */\n  int error = posix_fallocate(fd, sizeof(Elf64_Ehdr), segments.size() * sizeof(Elf64_Phdr));\n  if (error != 0) {\n    fprintf(stderr, \"Failed to allocate file: %s\\n\", strerror(error));\n    close(fd);\n    return HSA_STATUS_ERROR;\n  }\n  size_t idx = 0;\n  for (SegmentInfo seg : segments) {\n    Elf64_Phdr phdr{};\n    phdr.p_type = [](SegmentType s) {\n      switch (s) {\n        case LOAD:\n          return PT_LOAD;\n        case NOTE:\n          return PT_NOTE;\n        default:\n          assert(false);\n          return PT_NULL;\n      }\n    }(seg.stype);\n    phdr.p_flags = seg.flags;\n    phdr.p_vaddr = seg.vaddr;\n    phdr.p_paddr = 0;\n    phdr.p_memsz = seg.size;\n    phdr.p_filesz = seg.size;\n    phdr.p_align = [](SegmentType s) {\n      switch (s) {\n        case LOAD:\n          return LOAD_ALIGNMENT_SHIFT;\n        case NOTE:\n          return NOTE_ALIGNMENT_SHIFT;\n        default:\n          assert(false);\n          return (uint32_t)0;\n      }\n    }(seg.stype);\n    if (size_limit != -1 && (offset + seg.size > size_limit)) {\n      printf(\"Core limit file reached. GPU core dump created: %s\\n\", filename.c_str());\n      close(fd);\n      return HSA_STATUS_SUCCESS;\n    }\n    phdr.p_offset = alignUp(offset, (uint64_t)1 << phdr.p_align);\n    if (pwrite(fd, &phdr, sizeof(phdr), sizeof(Elf64_Ehdr) + idx * sizeof(Elf64_Phdr)) == -1) {\n      perror(\"Failed to write ELF header\");\n      close(fd);\n      return HSA_STATUS_ERROR;\n    }\n    /* Allocate stace for the segment on the file, and write the segment\n       content.  */\n    error = posix_fallocate(fd, phdr.p_offset, phdr.p_filesz);\n    if (error != 0) {\n      fprintf(stderr, \"Failed to allocate file: %s\\n\", strerror(error));\n      close(fd);\n      return HSA_STATUS_ERROR;\n    }\n    size_t remaining = phdr.p_filesz;\n    while (remaining > 0) {\n      size_t curr_chunk = std::min(remaining, MAX_BUFFER_SIZE);\n      try {\n        hsa_status_t st = seg.builder->Read(copy_buffer.get(), curr_chunk,\n                                                    phdr.p_vaddr + phdr.p_filesz - remaining);\n        if (st != HSA_STATUS_SUCCESS) {\n          close(fd);\n          return st;\n        }\n        if (pwrite(fd, copy_buffer.get(), curr_chunk, phdr.p_offset + phdr.p_filesz - remaining) ==\n            -1) {\n          perror(\"Failed to white core dump\");\n          close(fd);\n          return HSA_STATUS_ERROR;\n        }\n      } catch (...) {\n        close(fd);\n        return HSA_STATUS_ERROR;\n      }\n      remaining -= curr_chunk;\n    }\n    offset += phdr.p_filesz;\n    idx++;\n  }\n  printf(\"GPU core dump created: %s\\n\", filename.c_str());\n  close(fd);\n  return HSA_STATUS_SUCCESS;\n}\n}   //  namespace impl\n\nhsa_status_t dump_gpu_core() {\n  impl::NoteSegmentBuilder nbuilder;\n  impl::LoadSegmentBuilder lbuilder;\n  impl::SegmentsInfo segments;\n\n  struct rlimit rlimit;\n\n  if (getrlimit(RLIMIT_CORE, &rlimit)) {\n    perror(\"Could not get core file size\\n\");\n    return HSA_STATUS_ERROR;\n  }\n  debug_print(\"core file size: %ld\\n\", rlimit.rlim_cur);\n\n  if (rlimit.rlim_cur == 0)\n    return HSA_STATUS_SUCCESS;\n\n  hsa_status_t status = nbuilder.Collect(segments);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  status = lbuilder.Collect(segments);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  std::stringstream st;\n  st << PREFIX_FILE_NAME << \".\" << getpid();\n  return build_core_dump(st.str(), segments, rlimit.rlim_cur);\n}\n}   //  namespace coredump\n}   //  namespace amd\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_elf_image.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"core/inc/amd_elf_image.hpp\"\n#include \"amd_hsa_code_util.hpp\"\n#include <gelf.h>\n#include <errno.h>\n#include <cstring>\n#include <cerrno>\n#include <fstream>\n#include <memory>\n#include <cassert>\n#include <cstdlib>\n#include <algorithm>\n#ifdef _WIN32\n#include <Windows.h>\n#define alignof __alignof\n#endif // _WIN32\n#include <libelf.h>\n\n#ifndef _WIN32\n#define _open open\n#define _close close\n#define _tempnam tempnam\n#include <fcntl.h>\n#include <unistd.h>\n#endif\n\n#if defined(USE_MEMFILE)\n\n#include \"memfile.h\"\n#define OpenTemp(f)           mem_open(NULL, 0, 0)\n#define CloseTemp(f)          mem_close(f)\n#define _read(f, b, l)        mem_read((f), (b), (l))\n#define _write(f, b, l)       mem_write((f), (b), (l))\n#define _lseek(f, l, w)       mem_lseek((f), (l), (w))\n#define _ftruncate(f, l)      mem_ftruncate((f), (size_t)(l))\n#define sendfile(o, i, p, s)  mem_sendfile((o), (i), (p), (s))\n\n#else // USE_MEMFILE\n\n#define OpenTemp(f) amd::hsa::OpenTempFile(f);\n#define CloseTemp(f) amd::hsa::CloseTempFile(f);\n\n#ifndef _WIN32\n#define _read read\n#define _write write\n#define _lseek lseek\n#define _ftruncate ftruncate\n#include <sys/sendfile.h>\n#else\n#define _ftruncate _chsize\n#endif // !_WIN32\n\n#endif // !USE_MEMFILE\n\n#if !defined(BSD_LIBELF)\n  #define elf_setshstrndx elfx_update_shstrndx\n#endif\n\n#define NOTE_RECORD_ALIGNMENT 4\n\nusing rocr::amd::hsa::alignUp;\n\nnamespace rocr {\nnamespace amd {\nnamespace elf {\n\n    class FileImage {\n    public:\n      FileImage();\n      ~FileImage();\n      bool create();\n      bool readFrom(const std::string& filename);\n      bool copyFrom(const void* data, size_t size);\n      bool writeTo(const std::string& filename);\n      bool copyTo(void** buffer, size_t* size = 0);\n      bool copyTo(void* buffer, size_t size);\n      size_t getSize();\n\n      std::string output() { return out.str(); }\n\n      int fd() { return d; }\n\n    private:\n      int d;\n      std::ostringstream out;\n\n      bool error(const char* msg);\n      bool perror(const char *msg);\n      std::string werror();\n    };\n\n    FileImage::FileImage()\n      : d(-1)\n    {\n    }\n\n    FileImage::~FileImage()\n    {\n      if (d != -1) { CloseTemp(d); }\n    }\n\n    bool FileImage::error(const char* msg)\n    {\n      out << \"Error: \" << msg << std::endl;\n      return false;\n    }\n\n    bool FileImage::perror(const char* msg)\n    {\n      out << \"Error: \" << msg << \": \" << strerror(errno) << std::endl;\n      return false;\n    }\n\n#ifdef _WIN32\n    std::string FileImage::werror()\n    {\n      LPVOID lpMsgBuf;\n      DWORD dw = GetLastError();\n\n      FormatMessage(\n        FORMAT_MESSAGE_ALLOCATE_BUFFER |\n        FORMAT_MESSAGE_FROM_SYSTEM |\n        FORMAT_MESSAGE_IGNORE_INSERTS,\n        NULL,\n        dw,\n        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n        (LPTSTR)&lpMsgBuf,\n        0, NULL);\n      std::string result((LPTSTR)lpMsgBuf);\n      LocalFree(lpMsgBuf);\n      return result;\n    }\n#endif // _WIN32\n\n    bool FileImage::create()\n    {\n      d = OpenTemp(\"amdelf\");\n      if (d == -1) { return error(\"Failed to open temporary file for elf image\"); }\n      return true;\n    }\n\n    bool FileImage::readFrom(const std::string& filename)\n    {\n#ifdef _WIN32\n      std::unique_ptr<char> buffer(new char[32 * 1024 * 1024]);\n      HANDLE in = CreateFile(filename.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n      if (in == INVALID_HANDLE_VALUE) { out << \"Failed to open \" << filename << \": \" << werror() << std::endl; return false; }\n      DWORD read;\n      unsigned write;\n      int written;\n      do {\n        if (!ReadFile(in, buffer.get(), sizeof(buffer), &read, NULL)) {\n          out << \"Failed to read \" << filename << \": \" << werror() << std::endl;\n          CloseHandle(in);\n          return false;\n        }\n        if (read > 0) {\n          write = read;\n          do {\n            written = _write(d, buffer.get(), write);\n            if (written < 0) {\n              out << \"Failed to write image file: \" << werror() << std::endl;\n              CloseHandle(in);\n            }\n            write -= written;\n          } while (write > 0);\n        }\n      } while (read > 0);\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek(0) failed\"); }\n      CloseHandle(in);\n      return true;\n#else // _WIN32\n      int in = _open(filename.c_str(), O_RDONLY);\n      if (in < 0) { return perror(\"open failed\"); }\n      if (_lseek(in, 0L, SEEK_END) < 0) { \n        _close(in);\n        return perror(\"lseek failed\"); \n      }\n      off_t size;\n      if ((size = _lseek(in, 0L, SEEK_CUR)) < 0) { \n        _close(in);\n        return perror(\"lseek(2) failed\"); \n      }\n      if (_lseek(in, 0L, SEEK_SET) < 0) { \n        _close(in);\n        return perror(\"lseek(3) failed\"); \n      }\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek(3) failed\"); }\n      ssize_t written;\n      do {\n        written = sendfile(d, in, NULL, size);\n        if (written < 0) {\n          _close(in);\n          return perror(\"sendfile failed\");\n        }\n        size -= written;\n      } while (size > 0);\n      _close(in);\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek(0) failed\"); }\n      return true;\n#endif // _WIN32\n    }\n\n    bool FileImage::copyFrom(const void* data, size_t size)\n    {\n      assert(d != -1);\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek failed\"); }\n      if (_ftruncate(d, 0) < 0) { return perror(\"ftruncate failed\"); }\n      int written, offset = 0;\n      while (size > 0) {\n        written = _write(d, (const char*) data + offset, size);\n        if (written < 0) {\n          return perror(\"write failed\");\n        }\n        size -= written;\n        offset += written;\n      }\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek failed\"); }\n      return true;\n    }\n\n    size_t FileImage::getSize()\n    {\n      assert(d != -1);\n      if (_lseek(d, 0L, SEEK_END) < 0) { return perror(\"lseek failed\"); }\n      long seek = 0;\n      if ((seek = _lseek(d, 0L, SEEK_CUR)) < 0) { return perror(\"lseek(2) failed\"); }\n      if (_lseek(d, 0L, SEEK_SET) < 0) { return perror(\"lseek(3) failed\"); }\n      return seek;\n    }\n\n    bool FileImage::copyTo(void** buffer, size_t* size)\n    {\n      size_t size1 = getSize();\n      void* buffer1 = malloc(size1);\n      if (_read(d, buffer1, size1) < 0) { free(buffer1); return perror(\"read failed\"); }\n      *buffer = buffer1;\n      if (size) { *size = size1; }\n      return true;\n    }\n\n    bool FileImage::copyTo(void* buffer, size_t size)\n    {\n      size_t size1 = getSize();\n      if (size < size1) { return error(\"Buffer size is not enough\"); }\n      if (_read(d, buffer, size1) < 0) { return perror(\"read failed\"); }\n      return true;\n    }\n\n    bool FileImage::writeTo(const std::string& filename)\n    {\n      bool res = false;\n      size_t size = 0;\n      void *buffer = nullptr;\n      if (copyTo(&buffer, &size)) {\n        res = true;\n        std::ofstream out(filename.c_str(), std::ios::binary);\n        out.write((char*)buffer, size);\n      }\n      free(buffer);\n      return res;\n    }\n\n    class Buffer {\n    public:\n      typedef unsigned char byte_type;\n      typedef size_t size_type;\n\n      Buffer();\n      Buffer(const byte_type *src, size_type size, size_type align = 0);\n      virtual ~Buffer();\n\n      const byte_type* raw() const\n        { return this->isConst() ? ptr_ : data_.data(); }\n      size_type align() const\n        { return align_; }\n      size_type size() const\n        { return this->isConst() ? size_ : data_.size(); }\n      bool isConst() const\n        { return 0 != size_; }\n      bool isEmpty()\n        { return size() == 0; }\n      bool hasRaw(const byte_type *src) const\n        { return (src >= this->raw()) && (src < this->raw() + this->size()); }\n      template<typename T>\n      bool has(const T *src) const\n        { return this->hasRaw((const byte_type*)src); }\n      bool has(size_type offset) const\n        { return offset < this->size(); }\n\n      template<typename T>\n      size_type getOffset(const T *src) const\n        { return this->getRawOffset((const byte_type*)src); }\n      template<typename T>\n      T get(size_type offset) const\n        { return (T)this->getRaw(offset); }\n      size_type addString(const std::string &str, size_type align = 0);\n      size_type addStringLength(const std::string &str, size_type align = 0);\n      size_type nextOffset(size_type align) const { return alignUp(this->size(), align); }\n      template<typename T>\n      size_type add(const T *src, size_type size, size_type align)\n        { return this->addRaw((const byte_type*)src, size, align); }\n      template<typename T>\n      size_type add(const T &src, size_type align = 0)\n        { return this->addRaw((const byte_type*)&src, sizeof(T), align == 0 ? alignof(T) : align); }\n      size_type align(size_type align);\n\n      template<typename T>\n      size_type reserve()\n      {\n        Buffer::size_type offset = this->align(alignof(T));\n        data_.insert(data_.end(), sizeof(T), 0x0);\n        return offset;\n      }\n\n    private:\n      size_type getRawOffset(const byte_type *src) const;\n      const byte_type* getRaw(size_type offset) const;\n      size_type addRaw(const byte_type *src, size_type size, size_type align);\n\n      std::vector<byte_type> data_;\n      const byte_type *ptr_;\n      size_type size_;\n      size_type align_;\n    };\n\n    Buffer::Buffer()\n      : ptr_(nullptr)\n      , size_(0)\n      , align_(0)\n    {\n    }\n\n    Buffer::Buffer(const Buffer::byte_type *src, Buffer::size_type size, Buffer::size_type align)\n      : ptr_(src)\n      , size_(size)\n      , align_(align)\n    {\n    }\n\n    Buffer::~Buffer()\n    {\n    }\n\n    Buffer::size_type Buffer::getRawOffset(const Buffer::byte_type *src) const\n    {\n      assert(this->has(src));\n      return src - this->raw();\n    }\n\n    const Buffer::byte_type* Buffer::getRaw(Buffer::size_type offset) const\n    {\n      assert(this->has(offset));\n      return this->raw() + offset;\n    }\n\n    Buffer::size_type Buffer::addRaw(const Buffer::byte_type *src, Buffer::size_type size, Buffer::size_type align)\n    {\n      assert(!this->isConst());\n      assert(nullptr != src);\n      assert(0 != size);\n      assert(0 != align);\n      Buffer::size_type offset = this->align(align);\n      data_.insert(data_.end(), src, src + size);\n      return offset;\n    }\n\n    Buffer::size_type Buffer::addString(const std::string &str, size_type align)\n    {\n      return this->add(str.c_str(), str.length() + 1, align == 0 ? alignof(char) : align);\n    }\n\n    Buffer::size_type Buffer::addStringLength(const std::string &str, size_type align)\n    {\n      return this->add((uint32_t)(str.length() + 1), align == 0 ? alignof(uint32_t) : align);\n    }\n\n    Buffer::size_type Buffer::align(Buffer::size_type align)\n    {\n      assert(!this->isConst());\n      assert(0 != align);\n      Buffer::size_type offset = alignUp(this->size(), align);\n      align_ = (std::max)(align_, align);\n      data_.insert(data_.end(), offset - this->size(), 0x0);\n      return offset;\n    }\n\n    class GElfImage;\n    class GElfSegment;\n\n    class GElfSection : public virtual Section {\n    public:\n      GElfSection(GElfImage* elf);\n\n      bool push(const char* name, uint32_t shtype, uint64_t shflags, uint16_t shlink, uint32_t info, uint32_t align, uint64_t entsize = 0);\n      bool pull0();\n      bool pull(uint16_t ndx);\n      virtual bool pullData() { return true; }\n      bool push();\n      uint16_t getSectionIndex() const override;\n      uint32_t type() const override { return hdr.sh_type; }\n      std::string Name() const override;\n      uint64_t offset() const override { return hdr.sh_offset; }\n      uint64_t addr() const override { return hdr.sh_addr; }\n      bool updateAddr(uint64_t addr) override;\n      uint64_t addralign() const override { return data0.size() == 0 ? data.align() : data0.align(); }\n      uint64_t flags() const override { return hdr.sh_flags; }\n      uint64_t size() const override { return data0.size() == 0 ? data.size() : data0.size(); }\n      uint64_t nextDataOffset(uint64_t align) const override;\n      uint64_t addData(const void *src, uint64_t size, uint64_t align) override;\n      bool getData(uint64_t offset, void* dest, uint64_t size) override;\n      bool hasRelocationSection() const override { return reloc_sec != 0; }\n      RelocationSection* relocationSection(SymbolTable* symtab = 0) override;\n      Segment* segment() override { return seg; }\n      RelocationSection* asRelocationSection() override { return 0; }\n      bool setMemSize(uint64_t s) override { memsize_ = s; return true; }\n      uint64_t memSize() const override { return memsize_ ? memsize_ : size(); }\n      bool setAlign(uint64_t a) override { align_ = a; return true; }\n      uint64_t memAlign() const override { return align_ ? align_ : addralign(); }\n\n    protected:\n      GElfImage* elf;\n      Segment* seg;\n      GElf_Shdr hdr;\n      Buffer data0, data;\n      uint64_t memsize_;\n      uint64_t align_;\n      RelocationSection *reloc_sec;\n\n      size_t ndxscn;\n\n      friend class GElfSymbol;\n      friend class GElfSegment;\n      friend class GElfImage;\n    };\n\n    class GElfSegment : public Segment {\n    public:\n      GElfSegment(GElfImage* elf, uint16_t index);\n      GElfSegment(GElfImage* elf, uint16_t index, uint32_t type, uint32_t flags, uint64_t paddr = 0);\n      bool push(uint64_t vaddr);\n      bool pull();\n      uint64_t type() const override { return phdr.p_type; }\n      uint64_t memSize() const override { return phdr.p_memsz; }\n      uint64_t align() const override { return phdr.p_align; }\n      uint64_t imageSize() const override { return phdr.p_filesz; }\n      uint64_t vaddr() const override { return phdr.p_vaddr; }\n      uint64_t flags() const override { return phdr.p_flags; }\n      uint64_t offset() const override { return phdr.p_offset; }\n      const char* data() const override;\n      uint16_t getSegmentIndex() override;\n      bool updateAddSection(Section *section) override;\n\n    private:\n      GElfImage* elf;\n      uint16_t index;\n      GElf_Phdr phdr;\n      std::vector<Section*> sections;\n    };\n\n    class GElfStringTable : public GElfSection, public StringTable {\n    public:\n      GElfStringTable(GElfImage* elf);\n      bool push(const char* name, uint32_t shtype, uint64_t shflags);\n      bool pullData() override;\n      const char* addString(const std::string& s) override;\n      size_t addString1(const std::string& s) override;\n      const char* getString(size_t ndx) override;\n      size_t getStringIndex(const char* name) override;\n\n      uint16_t getSectionIndex() const override { return GElfSection::getSectionIndex(); }\n      uint32_t type() const override { return GElfSection::type(); }\n      std::string Name() const override { return GElfSection::Name(); }\n      uint64_t addr() const override { return GElfSection::addr(); }\n      uint64_t offset() const override { return GElfSection::offset(); }\n      bool updateAddr(uint64_t addr) override { return GElfSection::updateAddr(addr); }\n      uint64_t addralign() const override { return GElfSection::addralign(); }\n      uint64_t flags() const override { return GElfSection::flags(); }\n      uint64_t size() const override { return GElfSection::size(); }\n      Segment* segment() override { return GElfSection::segment(); }\n      uint64_t nextDataOffset(uint64_t align) const override { return GElfSection::nextDataOffset(align); }\n      uint64_t addData(const void *src, uint64_t size, uint64_t align) override { return GElfSection::addData(src, size, align); }\n      bool getData(uint64_t offset, void* dest, uint64_t size) override { return GElfSection::getData(offset, dest, size); }\n      bool hasRelocationSection() const override { return GElfSection::hasRelocationSection(); }\n      RelocationSection* relocationSection(SymbolTable* symtab) override { return GElfSection::relocationSection(); }\n      RelocationSection* asRelocationSection() override { return 0; }\n      uint64_t memSize() const override { return GElfSection::memSize(); }\n      bool setMemSize(uint64_t s) override { return GElfSection::setMemSize(s); }\n      uint64_t memAlign() const override { return GElfSection::memAlign(); }\n      bool setAlign(uint64_t a) override { return GElfSection::setAlign(a); }\n    };\n\n    class GElfSymbolTable;\n\n    class GElfSymbol : public Symbol {\n    public:\n      GElfSymbol(GElfSymbolTable* symtab, Buffer &data, size_t index);\n\n      bool push(const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, uint16_t shndx, unsigned char other);\n\n      uint32_t index() override { return eindex / sizeof(GElf_Rela); }\n      uint32_t type() override { return GELF_ST_TYPE(Sym()->st_info); }\n      uint32_t binding() override { return GELF_ST_BIND(Sym()->st_info); }\n      uint64_t size() override { return Sym()->st_size; }\n      uint64_t value() override { return Sym()->st_value; }\n      unsigned char other() override { return Sym()->st_other; }\n      std::string name() override;\n      Section* section() override;\n\n      void setValue(uint64_t value) override { Sym()->st_value = value; }\n      void setSize(uint64_t size) override { Sym()->st_size = size; }\n\n    private:\n      GElf_Sym* Sym() { return edata.get<GElf_Sym*>(eindex); }\n      GElfSymbolTable* symtab;\n      Buffer &edata;\n      size_t eindex;\n      friend class GElfSymbolTable;\n    };\n\n    class GElfSymbolTable : public GElfSection, public SymbolTable {\n    private:\n      Symbol* addSymbolInternal(Section* section, const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, unsigned char other = 0);\n\n      GElfStringTable* strtab;\n      std::vector<std::unique_ptr<GElfSymbol>> symbols;\n      friend class GElfSymbol;\n\n    public:\n      GElfSymbolTable(GElfImage* elf);\n      bool push(const char* name, GElfStringTable* strtab);\n      bool pullData() override;\n      uint16_t getSectionIndex() const override { return GElfSection::getSectionIndex(); }\n      uint32_t type() const override { return GElfSection::type(); }\n      std::string Name() const override { return GElfSection::Name(); }\n      uint64_t offset() const override { return GElfSection::offset(); }\n      uint64_t addr() const override { return GElfSection::addr(); }\n      bool updateAddr(uint64_t addr) override { return GElfSection::updateAddr(addr); }\n      uint64_t addralign() const override { return GElfSection::addralign(); }\n      uint64_t flags() const override { return GElfSection::flags(); }\n      uint64_t size() const override { return GElfSection::size(); }\n      Segment* segment() override { return GElfSection::segment(); }\n      uint64_t nextDataOffset(uint64_t align) const override { return GElfSection::nextDataOffset(align); }\n      uint64_t addData(const void *src, uint64_t size, uint64_t align) override { return GElfSection::addData(src, size, align); }\n      bool getData(uint64_t offset, void* dest, uint64_t size) override { return GElfSection::getData(offset, dest, size); }\n      bool hasRelocationSection() const override { return GElfSection::hasRelocationSection(); }\n      RelocationSection* relocationSection(SymbolTable* symtab) override { return GElfSection::relocationSection(); }\n      Symbol* addSymbol(Section* section, const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, unsigned char other = 0) override;\n      size_t symbolCount() override;\n      Symbol* symbol(size_t i) override;\n      RelocationSection* asRelocationSection() override { return 0; }\n      uint64_t memSize() const override { return GElfSection::memSize(); }\n      bool setMemSize(uint64_t s) override { return GElfSection::setMemSize(s); }\n      uint64_t memAlign() const override { return GElfSection::memAlign(); }\n      bool setAlign(uint64_t a) override { return GElfSection::setAlign(a); }\n    };\n\n    class GElfNoteSection : public GElfSection, public NoteSection {\n    public:\n      GElfNoteSection(GElfImage* elf);\n      bool push(const std::string& name);\n      uint16_t getSectionIndex() const override { return GElfSection::getSectionIndex(); }\n      uint32_t type() const override { return GElfSection::type(); }\n      std::string Name() const override { return GElfSection::Name(); }\n      uint64_t addr() const override { return GElfSection::addr(); }\n      bool updateAddr(uint64_t addr) override { return GElfSection::updateAddr(addr); }\n      uint64_t offset() const override { return GElfSection::offset(); }\n      uint64_t addralign() const override { return GElfSection::addralign(); }\n      uint64_t flags() const override { return GElfSection::flags(); }\n      uint64_t size() const override { return GElfSection::size(); }\n      Segment* segment() override { return GElfSection::segment(); }\n      uint64_t nextDataOffset(uint64_t align) const override { return GElfSection::nextDataOffset(align); }\n      uint64_t addData(const void *src, uint64_t size, uint64_t align) override { return GElfSection::addData(src, size, align); }\n      bool getData(uint64_t offset, void* dest, uint64_t size) override { return GElfSection::getData(offset, dest, size); }\n      bool hasRelocationSection() const override { return GElfSection::hasRelocationSection(); }\n      RelocationSection* relocationSection(SymbolTable* symtab) override { return GElfSection::relocationSection(); }\n      bool addNote(const std::string& name, uint32_t type, const void* desc, uint32_t desc_size) override;\n      bool getNote(const std::string& name, uint32_t type, void** desc, uint32_t* desc_size) override;\n      RelocationSection* asRelocationSection() override { return 0; }\n      uint64_t memSize() const override { return GElfSection::memSize(); }\n      bool setMemSize(uint64_t s) override { return GElfSection::setMemSize(s); }\n      uint64_t memAlign() const override { return GElfSection::memAlign(); }\n      bool setAlign(uint64_t a) override { return GElfSection::setAlign(a); }\n    };\n\n    class GElfRelocationSection;\n\n    class GElfRelocation : public Relocation {\n    private:\n      GElf_Rela *Rela() { return edata.get<GElf_Rela*>(eindex); }\n\n      GElfRelocationSection* rsection;\n      Buffer &edata;\n      size_t eindex;\n\n    public:\n      GElfRelocation(GElfRelocationSection* rsection_, Buffer &edata_, size_t eindex_)\n        : rsection(rsection_),\n          edata(edata_), eindex(eindex_)\n      {\n      }\n\n      bool push(uint32_t type, Symbol* symbol, uint64_t offset, int64_t addend);\n\n      RelocationSection* section() override;\n      uint32_t type() override { return GELF_R_TYPE(Rela()->r_info); }\n      uint32_t symbolIndex() override { return GELF_R_SYM(Rela()->r_info); }\n      Symbol* symbol() override;\n      uint64_t offset() override { return Rela()->r_offset; }\n      int64_t addend() override { return Rela()->r_addend; }\n    };\n\n    class GElfRelocationSection : public GElfSection, public RelocationSection {\n    private:\n      Section* section;\n      GElfSymbolTable* symtab;\n      std::vector<std::unique_ptr<GElfRelocation>> relocations;\n\n    public:\n      GElfRelocationSection(GElfImage* elf, Section* targetSection = 0, GElfSymbolTable* symtab_ = 0);\n      bool push(const std::string& name);\n      bool pullData() override;\n      uint16_t getSectionIndex() const override { return GElfSection::getSectionIndex(); }\n      uint32_t type() const override { return GElfSection::type(); }\n      std::string Name() const override { return GElfSection::Name(); }\n      uint64_t addr() const override { return GElfSection::addr(); }\n      uint64_t offset() const override { return GElfSection::offset(); }\n      bool updateAddr(uint64_t addr) override { return GElfSection::updateAddr(addr); }\n      uint64_t addralign() const override { return GElfSection::addralign(); }\n      uint64_t flags() const override { return GElfSection::flags(); }\n      uint64_t size() const override { return GElfSection::size(); }\n      Segment* segment() override { return GElfSection::segment(); }\n      uint64_t nextDataOffset(uint64_t align) const override { return GElfSection::nextDataOffset(align); }\n      uint64_t addData(const void *src, uint64_t size, uint64_t align) override { return GElfSection::addData(src, size, align); }\n      bool getData(uint64_t offset, void* dest, uint64_t size) override { return GElfSection::getData(offset, dest, size); }\n      bool hasRelocationSection() const override { return GElfSection::hasRelocationSection(); }\n      RelocationSection* relocationSection(SymbolTable* symtab) override { return GElfSection::relocationSection(); }\n      RelocationSection* asRelocationSection() override { return this; }\n\n      size_t relocationCount() const override { return relocations.size(); }\n      Relocation* relocation(size_t i) override { return relocations[i].get(); }\n      Relocation* addRelocation(uint32_t type, Symbol* symbol, uint64_t offset, int64_t addend) override;\n      Section* targetSection() override { return section; }\n      uint64_t memSize() const override { return GElfSection::memSize(); }\n      bool setMemSize(uint64_t s) override { return GElfSection::setMemSize(s); }\n      uint64_t memAlign() const override { return GElfSection::memAlign(); }\n      bool setAlign(uint64_t a) override { return GElfSection::setAlign(a); }\n      friend class GElfRelocation;\n    };\n\n    class GElfImage : public Image {\n    public:\n      GElfImage(int elfclass);\n      ~GElfImage();\n      bool initNew(uint16_t machine, uint16_t type, uint8_t os_abi = 0, uint8_t abi_version = 0, uint32_t e_flags = 0) override;\n      bool loadFromFile(const std::string& filename) override;\n      bool saveToFile(const std::string& filename) override;\n      bool initFromBuffer(const void* buffer, size_t size) override;\n      bool initAsBuffer(const void* buffer, size_t size) override;\n      bool close();\n      bool writeTo(const std::string& filename) override;\n      bool copyToBuffer(void** buf, size_t* size = 0) override;\n      bool copyToBuffer(void* buf, size_t size) override;\n\n      const char* data() override { assert(buffer); return buffer; }\n      uint64_t size() override;\n\n      bool push();\n\n      bool Freeze() override;\n      bool Validate() override;\n\n      uint16_t Machine() override { return ehdr.e_machine; }\n      uint16_t Type() override { return ehdr.e_type; }\n      uint32_t EFlags() override { return ehdr.e_flags; }\n      uint32_t ABIVersion() override { return (uint32_t)(ehdr.e_ident[EI_ABIVERSION]); }\n      uint32_t EClass() override { return (uint32_t)(ehdr.e_ident[EI_CLASS]); }\n      uint32_t OsAbi() override { return (uint32_t)(ehdr.e_ident[EI_OSABI]); }\n\n      GElfStringTable* shstrtab() override;\n      GElfStringTable* strtab() override;\n      GElfSymbolTable* getReferencedSymbolTable(uint16_t index)\n      {\n        return static_cast<GElfSymbolTable*>(section(index));\n      }\n      GElfSymbolTable* getSymtab(uint16_t index) override\n      {\n        if (section(index)->type() == SHT_SYMTAB)\n          return static_cast<GElfSymbolTable*>(section(index));\n        return nullptr;\n      }\n      GElfSymbolTable* getDynsym(uint16_t index) override\n      {\n        if (section(index)->type() == SHT_DYNSYM)\n          return static_cast<GElfSymbolTable*>(section(index));\n        return nullptr;\n      }\n\n      GElfSymbolTable* getSymbolTable() override;\n      GElfSymbolTable* getSymbolTable(uint16_t index) override\n      {\n        const char *UseDynsym = getenv(\"LOADER_USE_DYNSYM\");\n        if (UseDynsym && std::strncmp(UseDynsym, \"0\", 1) != 0)\n          return getDynsym(index);\n        return getSymtab(index);\n      }\n\n      GElfStringTable* addStringTable(const std::string& name) override;\n      GElfStringTable* getStringTable(uint16_t index) override;\n\n      GElfSymbolTable* addSymbolTable(const std::string& name, StringTable* stab = 0) override;\n      GElfSymbolTable* symtab() override;\n      GElfSymbolTable* dynsym() override;\n\n      GElfSegment* segment(size_t i) override { return segments[i].get(); }\n      Segment* segmentByVAddr(uint64_t vaddr) override;\n      size_t sectionCount() override { return sections.size(); }\n      GElfSection* section(size_t i) override { return sections[i].get(); }\n      Section* sectionByVAddr(uint64_t vaddr) override;\n      uint16_t machine() const;\n      uint16_t etype() const;\n      int eclass() const { return elfclass; }\n      bool elfError(const char* msg);\n\n      GElfNoteSection* note() override;\n      GElfNoteSection* addNoteSection(const std::string& name) override;\n\n      size_t segmentCount() override { return segments.size(); }\n      Segment* initSegment(uint32_t type, uint32_t flags, uint64_t paddr = 0) override;\n      bool addSegments() override;\n\n      Section* addSection(const std::string &name,\n                          uint32_t type,\n                          uint64_t flags = 0,\n                          uint64_t entsize = 0,\n                          Segment* segment = 0) override;\n\n      RelocationSection* addRelocationSection(Section* sec, SymbolTable* symtab);\n      RelocationSection* relocationSection(Section* sec, SymbolTable* symtab = 0) override;\n\n    private:\n      bool frozen;\n      int elfclass;\n      FileImage img;\n      const char* buffer;\n      size_t bufferSize;\n      Elf* e;\n      GElf_Ehdr ehdr;\n      GElfStringTable* shstrtabSection;\n      GElfStringTable* strtabSection;\n      GElfSymbolTable* symtabSection;\n      GElfSymbolTable* dynsymSection;\n      GElfNoteSection* noteSection;\n      std::vector<std::unique_ptr<GElfSegment>> segments;\n      std::vector<std::unique_ptr<GElfSection>> sections;\n\n      bool imgError();\n      const char *elfError();\n      bool elfBegin(Elf_Cmd cmd);\n      bool elfEnd();\n      bool push0();\n      bool pullElf();\n\n      friend class GElfSection;\n      friend class GElfSymbolTable;\n      friend class GElfNoteSection;\n      friend class GElfRelocationSection;\n      friend class GElfSegment;\n      friend class GElfSymbol;\n    };\n\n    GElfSegment::GElfSegment(GElfImage* elf_, uint16_t index_)\n      : elf(elf_),\n        index(index_)\n    {\n      memset(&phdr, 0, sizeof(phdr));\n    }\n\n    GElfSegment::GElfSegment(GElfImage* elf_, uint16_t index_,\n      uint32_t type, uint32_t flags, uint64_t paddr)\n      : elf(elf_),\n        index(index_)\n    {\n      memset(&phdr, 0, sizeof(phdr));\n      phdr.p_type = type;\n      phdr.p_flags = flags;\n      phdr.p_paddr = paddr;\n    }\n\n    const char* GElfSegment::data() const\n    {\n      return (const char*) elf->data() + phdr.p_offset;\n    }\n\n    bool GElfImage::Freeze()\n    {\n      assert(!frozen);\n      if (!push()) { return false; }\n      frozen = true;\n      return true;\n    }\n\n    bool GElfImage::Validate()\n    {\n      if (ELFMAG0 != ehdr.e_ident[EI_MAG0] ||\n          ELFMAG1 != ehdr.e_ident[EI_MAG1] ||\n          ELFMAG2 != ehdr.e_ident[EI_MAG2] ||\n          ELFMAG3 != ehdr.e_ident[EI_MAG3]) {\n        out << \"Invalid ELF magic\" << std::endl;\n        return false;\n      }\n      if (EV_CURRENT != ehdr.e_version) {\n        out << \"Invalid ELF version\" << std::endl;\n        return false;\n      }\n      return true;\n    }\n\n    bool GElfSegment::push(uint64_t vaddr)\n    {\n      phdr.p_align = 0;\n      phdr.p_offset = 0;\n      if (!sections.empty()) {\n        phdr.p_offset = sections[0]->offset();\n      }\n      for (Section* section : sections) {\n        phdr.p_align = (std::max)(phdr.p_align, section->memAlign());\n      }\n      phdr.p_vaddr = alignUp(vaddr, (std::max)(phdr.p_align, (uint64_t) 1));\n      phdr.p_filesz = 0;\n      phdr.p_memsz = 0;\n      for (Section* section : sections) {\n        phdr.p_memsz = alignUp(phdr.p_memsz, (std::max)(section->memAlign(), (uint64_t) 1));\n        phdr.p_filesz = alignUp(phdr.p_filesz, (std::max)(section->memAlign(), (uint64_t) 1));\n        if (!section->updateAddr(phdr.p_vaddr + phdr.p_memsz)) { return false; }\n        phdr.p_filesz += (section->type() == SHT_NOBITS) ? 0 : section->size();\n        phdr.p_memsz += section->memSize();\n      }\n      if (!gelf_update_phdr(elf->e, index, &phdr)) { return elf->elfError(\"gelf_update_phdr failed\"); }\n      return true;\n    }\n\n    bool GElfSegment::pull()\n    {\n      if (!gelf_getphdr(elf->e, index, &phdr)) { return elf->elfError(\"gelf_getphdr failed\"); }\n      return true;\n    }\n\n    uint16_t GElfSegment::getSegmentIndex()\n    {\n      return index;\n    }\n\n    bool GElfSegment::updateAddSection(Section *section)\n    {\n      sections.push_back(section);\n      return true;\n    }\n\n    GElfSection::GElfSection(GElfImage* elf_)\n      : elf(elf_),\n        seg(nullptr),\n        hdr{},\n        memsize_(0),\n        align_(0),\n        reloc_sec(nullptr),\n        ndxscn(0)\n    {\n    }\n\n    uint16_t GElfSection::getSectionIndex() const\n    {\n      return (uint16_t)ndxscn;\n    }\n\n    std::string GElfSection::Name() const\n    {\n      return std::string(elf->shstrtab()->getString(hdr.sh_name));\n    }\n\n    bool GElfSection::updateAddr(uint64_t addr)\n    {\n      Elf_Scn *scn = elf_getscn(elf->e, ndxscn);\n      assert(scn);\n      if (!gelf_getshdr(scn, &hdr)) { return elf->elfError(\"gelf_get_shdr failed\"); }\n      hdr.sh_addr = addr;\n      if (!gelf_update_shdr(scn, &hdr)) { return elf->elfError(\"gelf_update_shdr failed\"); }\n      return true;\n    }\n\n    bool GElfSection::push(const char* name, uint32_t shtype, uint64_t shflags, uint16_t shlink, uint32_t info, uint32_t align, uint64_t entsize)\n    {\n      Elf_Scn *scn = elf_newscn(elf->e);\n      if (!scn) { return false; }\n      ndxscn = elf_ndxscn(scn);\n      if (!gelf_getshdr(scn, &hdr)) { return elf->elfError(\"gelf_get_shdr failed\"); }\n      align = (std::max)(align, (uint32_t) 8);\n      hdr.sh_name = elf->shstrtab()->addString1(name);\n      hdr.sh_type = shtype;\n      hdr.sh_flags = shflags;\n      hdr.sh_link = shlink;\n      hdr.sh_addr = 0;\n      hdr.sh_info = info;\n      hdr.sh_addralign = align;\n      hdr.sh_entsize = entsize;\n      if (!gelf_update_shdr(scn, &hdr)) { return elf->elfError(\"gelf_update_shdr failed\"); }\n      return true;\n    }\n\n    bool GElfSection::pull0()\n    {\n      Elf_Scn *scn = elf_getscn(elf->e, ndxscn);\n      if (!scn) { return false; }\n      if (!gelf_getshdr(scn, &hdr)) { return elf->elfError(\"gelf_get_shdr failed\"); }\n      return true;\n    }\n\n    bool GElfSection::pull(uint16_t ndx)\n    {\n      ndxscn = (size_t) ndx;\n      if (!pull0()) { return false; }\n      Elf_Scn *scn = elf_getscn(elf->e, ndx);\n      if (!scn) { return false; }\n      Elf_Data *edata0 = elf_getdata(scn, NULL);\n      if (edata0) {\n        data0 = Buffer((const Buffer::byte_type*)edata0->d_buf, edata0->d_size, edata0->d_align);\n      }\n      seg = elf->segmentByVAddr(hdr.sh_addr);\n      return true;\n    }\n\n    bool GElfSection::push()\n    {\n      Elf_Scn *scn = elf_getscn(elf->e, ndxscn);\n      assert(scn);\n      Elf_Data *edata = nullptr;\n      edata = elf_newdata(scn);\n      if (!edata) { return elf->elfError(\"elf_newdata failed\"); }\n      if (hdr.sh_type == SHT_NOBITS) {\n        edata->d_buf = 0;\n        edata->d_size = memsize_;\n        if (align_ != 0) {\n          edata->d_align = align_;\n        }\n      } else {\n        edata->d_buf = (void*)data.raw();\n        edata->d_size = data.size();\n        if (data.align() != 0) {\n          edata->d_align = data.align();\n        }\n      }\n      edata->d_align = (std::max)(edata->d_align, (uint64_t) 8);\n      switch (hdr.sh_type) {\n      case SHT_RELA:\n        edata->d_type = ELF_T_RELA;\n        break;\n      case SHT_SYMTAB:\n        edata->d_type = ELF_T_SYM;\n        break;\n      default:\n        edata->d_type = ELF_T_BYTE;\n        break;\n      }\n      edata->d_version = EV_CURRENT;\n      if (!gelf_getshdr(scn, &hdr)) { return elf->elfError(\"gelf_get_shdr failed\"); }\n      hdr.sh_size = edata->d_size;\n      hdr.sh_addralign = edata->d_align;\n      if (!gelf_update_shdr(scn, &hdr)) { return elf->elfError(\"gelf_update_shdr failed\"); }\n      return true;\n    }\n\n    uint64_t GElfSection::nextDataOffset(uint64_t align) const\n    {\n      return data.nextOffset(align);\n    }\n\n    uint64_t GElfSection::addData(const void *src, uint64_t size, uint64_t align)\n    {\n      return data.add(src, size, align);\n    }\n\n    bool GElfSection::getData(uint64_t offset, void* dest, uint64_t size)\n    {\n      Elf_Data* edata = 0;\n      uint64_t coffset = 0;\n      uint64_t csize = 0;\n      Elf_Scn *scn = elf_getscn(elf->e, ndxscn);\n      assert(scn);\n      if ((edata = elf_getdata(scn, edata)) != 0) {\n        if (coffset <= offset && offset <= coffset + edata->d_size) {\n          csize = (std::min)(size, edata->d_size - offset);\n          memcpy(dest, (const char*) edata->d_buf + offset - coffset, csize);\n          dest = (char*) dest + csize;\n          size -= csize;\n          if (!size) { return true; }\n        }\n      }\n      return false;\n    }\n\n    RelocationSection* GElfSection::relocationSection(SymbolTable* symtab)\n    {\n      if (!reloc_sec) {\n        reloc_sec = elf->addRelocationSection(this, symtab);\n      }\n      return reloc_sec;\n    }\n\n    GElfStringTable::GElfStringTable(GElfImage* elf)\n      : GElfSection(elf)\n    {\n    }\n\n    bool GElfStringTable::push(const char* name, uint32_t shtype, uint64_t shflags)\n    {\n      if (!GElfSection::push(name, shtype, shflags, SHN_UNDEF, 0, 0)) { return false; }\n      return true;\n    }\n\n    bool GElfStringTable::pullData()\n    {\n      return true;\n    }\n\n    const char* GElfStringTable::addString(const std::string& s)\n    {\n      if (data0.size() == 0 && data.size() == 0) {\n        data.add('\\0');\n      }\n      return data.get<const char*>(data.addString(s));\n    }\n\n    size_t GElfStringTable::addString1(const std::string& s)\n    {\n      if (data0.size() == 0 && data.size() == 0) {\n        data.add('\\0');\n      }\n      return data.addString(s);\n    }\n\n    const char* GElfStringTable::getString(size_t ndx)\n    {\n      if (data0.has(ndx)) { return data0.get<const char*>(ndx); }\n      else if (data.has(ndx)) { return data.get<const char*>(ndx); }\n      return nullptr;\n    }\n\n    size_t GElfStringTable::getStringIndex(const char* s)\n    {\n      if (data0.has(s)) {\n        return data0.getOffset(s);\n      } else if (data.has(s)) {\n        return data.getOffset(s);\n      } else {\n        assert(false);\n        return 0;\n      }\n    }\n\n    GElfSymbol::GElfSymbol(GElfSymbolTable* symtab_, Buffer &data_, size_t index_)\n      : symtab(symtab_),\n        edata(data_),\n        eindex(index_)\n    {\n    }\n\n    Section* GElfSymbol::section()\n    {\n      if (Sym()->st_shndx != SHN_UNDEF) {\n        return symtab->elf->section(Sym()->st_shndx);\n      }\n      return 0;\n    }\n\n    bool GElfSymbol::push(const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, uint16_t shndx, unsigned char other)\n    {\n      Sym()->st_name = symtab->strtab->addString1(name.c_str());\n      Sym()->st_value = value;\n      Sym()->st_size = size;\n      Sym()->st_info = GELF_ST_INFO(binding, type);\n      Sym()->st_shndx = shndx;\n      Sym()->st_other = other;\n      return true;\n    }\n\n    std::string GElfSymbol::name()\n    {\n      return symtab->strtab->getString(Sym()->st_name);\n    }\n\n    GElfSymbolTable::GElfSymbolTable(GElfImage* elf)\n      : GElfSection(elf),\n        strtab(0)\n    {\n    }\n\n    bool GElfSymbolTable::push(const char* name, GElfStringTable* strtab)\n    {\n      if (!strtab) { strtab = elf->strtab(); }\n      this->strtab = strtab;\n      if (!GElfSection::push(name, SHT_SYMTAB, 0, strtab->getSectionIndex(), 0, 0, sizeof(Elf64_Sym))) { return false;  }\n      return true;\n    }\n\n    bool GElfSymbolTable::pullData()\n    {\n      strtab = elf->getStringTable(hdr.sh_link);\n      for (size_t i = 0; i < data0.size() / sizeof(GElf_Sym); ++i) {\n        symbols.push_back(std::unique_ptr<GElfSymbol>(new GElfSymbol(this, data0, i * sizeof(GElf_Sym))));\n      }\n      return true;\n    }\n\n    Symbol* GElfSymbolTable::addSymbolInternal(Section* section, const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, unsigned char other)\n    {\n      GElfSymbol *sym = new (std::nothrow) GElfSymbol(this, data, data.reserve<GElf_Sym>());\n      uint16_t shndx = section ? section->getSectionIndex() : (uint16_t) SHN_UNDEF;\n      if (!sym->push(name, value, size, type, binding, shndx, other)) {\n        delete sym;\n        return nullptr;\n      }\n      symbols.push_back(std::unique_ptr<GElfSymbol>(sym));\n      return sym;\n    }\n\n    Symbol* GElfSymbolTable::addSymbol(Section* section, const std::string& name, uint64_t value, uint64_t size, unsigned char type, unsigned char binding, unsigned char other)\n    {\n      if (symbols.size() == 0) {\n        this->addSymbolInternal(nullptr, \"\", 0, 0, 0, 0, 0);\n      }\n      return this->addSymbolInternal(section, name, value, size, type, binding, other);\n    }\n\n    size_t GElfSymbolTable::symbolCount()\n    {\n      return symbols.size();\n    }\n\n    Symbol* GElfSymbolTable::symbol(size_t i)\n    {\n      return symbols[i].get();\n    }\n\n    GElfNoteSection::GElfNoteSection(GElfImage* elf)\n      : GElfSection(elf)\n    {\n    }\n\n    bool GElfNoteSection::push(const std::string& name)\n    {\n      return GElfSection::push(name.c_str(), SHT_NOTE, 0, 0, 0, 8);\n    }\n\n    bool GElfNoteSection::addNote(const std::string& name, uint32_t type, const void* desc, uint32_t desc_size)\n    {\n      data.addStringLength(name, NOTE_RECORD_ALIGNMENT);\n      data.add(desc_size, NOTE_RECORD_ALIGNMENT);\n      data.add(type, NOTE_RECORD_ALIGNMENT);\n      data.addString(name, NOTE_RECORD_ALIGNMENT);\n      data.align(NOTE_RECORD_ALIGNMENT);\n      if (desc_size > 0) {\n        assert(desc);\n        data.add(desc, desc_size, NOTE_RECORD_ALIGNMENT);\n        data.align(NOTE_RECORD_ALIGNMENT);\n      }\n      return true;\n    }\n\n    bool GElfNoteSection::getNote(const std::string& name, uint32_t type, void** desc, uint32_t* desc_size)\n    {\n      Elf_Data* data = 0;\n      Elf_Scn *scn = elf_getscn(elf->e, ndxscn);\n      assert(scn);\n      while ((data = elf_getdata(scn, data)) != 0) {\n        uint32_t note_offset = 0;\n        while (note_offset < data->d_size) {\n          char* notec = (char *) data->d_buf + note_offset;\n          Elf64_Nhdr* note = (Elf64_Nhdr*) notec;\n          if (type == note->n_type) {\n            std::string note_name = GetNoteString(note->n_namesz, notec + sizeof(Elf64_Nhdr));\n            if (name == note_name) {\n              *desc = notec + sizeof(Elf64_Nhdr) + alignUp(note->n_namesz, 4);\n              *desc_size = note->n_descsz;\n              return true;\n            }\n          }\n          note_offset += sizeof(Elf64_Nhdr) + alignUp(note->n_namesz, 4) + alignUp(note->n_descsz, 4);\n        }\n      }\n      return false;\n    }\n\n    bool GElfRelocation::push(uint32_t type, Symbol* symbol, uint64_t offset, int64_t addend)\n    {\n      Rela()->r_info = GELF_R_INFO((uint64_t) symbol->index(), type);\n      Rela()->r_offset = offset;\n      Rela()->r_addend = addend;\n      return true;\n    }\n\n    RelocationSection* GElfRelocation::section()\n    {\n      return rsection;\n    }\n\n    Symbol* GElfRelocation::symbol()\n    {\n      return rsection->symtab->symbol(symbolIndex());\n    }\n\n    GElfRelocationSection::GElfRelocationSection(GElfImage* elf, Section* section_, GElfSymbolTable* symtab_)\n      : GElfSection(elf),\n        section(section_),\n        symtab(symtab_)\n    {\n    }\n\n    bool GElfRelocationSection::push(const std::string& name)\n    {\n      return GElfSection::push(name.c_str(), SHT_RELA, 0, symtab->getSectionIndex(), section->getSectionIndex(), 0, sizeof(Elf64_Rela));\n    }\n\n    Relocation* GElfRelocationSection::addRelocation(uint32_t type, Symbol* symbol, uint64_t offset, int64_t addend)\n    {\n      GElfRelocation *rela = new (std::nothrow) GElfRelocation(this, data, data.reserve<GElf_Rela>());\n      if (!rela || !rela->push(type, symbol, offset, addend)) {\n        delete rela;\n        return nullptr;\n      }\n      relocations.push_back(std::unique_ptr<GElfRelocation>(rela));\n      return rela;\n    }\n\n    bool GElfRelocationSection::pullData()\n    {\n      section = elf->section(hdr.sh_info);\n      symtab = elf->getReferencedSymbolTable(hdr.sh_link);\n      Elf_Scn *lScn = elf_getscn(elf->e, ndxscn);\n      assert(lScn);\n      Elf_Data *lData = elf_getdata(lScn, nullptr);\n      assert(lData);\n      data0 = Buffer((const Buffer::byte_type*)lData->d_buf, lData->d_size, lData->d_align);\n      for (size_t i = 0; i < data0.size() / sizeof(GElf_Rela); ++i) {\n        relocations.push_back(std::unique_ptr<GElfRelocation>(new GElfRelocation(this, data0, i * sizeof(GElf_Rela))));\n      }\n      return true;\n    }\n\n    GElfImage::GElfImage(int elfclass_)\n      : frozen(true),\n        elfclass(elfclass_),\n        buffer(0), bufferSize(0),\n        e(0),\n        shstrtabSection(0), strtabSection(0),\n        symtabSection(0),\n        dynsymSection(0),\n        noteSection(0)\n    {\n      if (EV_NONE == elf_version(EV_CURRENT)) {\n        assert(false);\n      }\n    }\n\n    GElfImage::~GElfImage()\n    {\n      elf_end(e);\n    }\n\n    bool GElfImage::imgError()\n    {\n      out << img.output();\n      return false;\n    }\n\n    const char *GElfImage::elfError()\n    {\n      return elf_errmsg(-1);\n    }\n\n    bool GElfImage::elfBegin(Elf_Cmd cmd)\n    {\n      if ((e = elf_begin(img.fd(), cmd, NULL\n#ifdef AMD_LIBELF\n                       , NULL\n#endif\n        )) == NULL) {\n        out << \"elf_begin failed: \" << elfError() << std::endl;\n        return false;\n      }\n      return true;\n    }\n\n    bool GElfImage::initNew(uint16_t machine, uint16_t type, uint8_t os_abi, uint8_t abi_version, uint32_t e_flags)\n    {\n      if (!img.create()) { return imgError(); }\n      if (!elfBegin(ELF_C_WRITE)) { return false; }\n      if (!gelf_newehdr(e, elfclass)) { return elfError(\"gelf_newehdr failed\"); }\n      if (!gelf_getehdr(e, &ehdr)) { return elfError(\"gelf_getehdr failed\"); }\n      ehdr.e_ident[EI_DATA] = ELFDATA2LSB;\n      ehdr.e_ident[EI_VERSION] = EV_CURRENT;\n      ehdr.e_ident[EI_OSABI] = os_abi;\n      ehdr.e_ident[EI_ABIVERSION] = abi_version;\n      ehdr.e_machine = machine;\n      ehdr.e_type = type;\n      ehdr.e_version = EV_CURRENT;\n      ehdr.e_flags = e_flags;\n      if (!gelf_update_ehdr(e, &ehdr)) { return elfError(\"gelf_updateehdr failed\"); }\n      sections.push_back(std::unique_ptr<GElfSection>());\n      if (!shstrtab()->push(\".shstrtab\", SHT_STRTAB, SHF_STRINGS)) { return elfError(\"Failed to create shstrtab\"); }\n      ehdr.e_shstrndx = shstrtab()->getSectionIndex();\n      if (!gelf_update_ehdr(e, &ehdr)) { return elfError(\"gelf_updateehdr failed\"); }\n      if (!strtab()->push(\".strtab\", SHT_STRTAB, SHF_STRINGS)) { return elfError(\"Failed to create strtab\"); }\n      frozen = false;\n      return true;\n    }\n\n    bool GElfImage::loadFromFile(const std::string& filename)\n    {\n      if (!img.create()) { return imgError(); }\n      if (!img.readFrom(filename)) { return imgError(); }\n      if (!elfBegin(ELF_C_RDWR)) { return false; }\n      return pullElf();\n    }\n\n    bool GElfImage::saveToFile(const std::string& filename)\n    {\n      if (buffer) {\n        std::ofstream out(filename.c_str(), std::ios::binary);\n        if (out.fail()) { return false; }\n        out.write(buffer, bufferSize);\n        return !out.fail();\n      } else {\n        if (!push()) { return false; }\n        return img.writeTo(filename);\n      }\n    }\n\n    bool GElfImage::initFromBuffer(const void* buffer, size_t size)\n    {\n      if (size == 0) { size = ElfSize(buffer); }\n      if (!img.create()) { return imgError(); }\n      if (!img.copyFrom(buffer, size)) { return imgError(); }\n      if (!elfBegin(ELF_C_RDWR)) { return false; }\n      return pullElf();\n    }\n\n    bool GElfImage::initAsBuffer(const void* buffer, size_t size)\n    {\n      if (size == 0) { size = ElfSize(buffer); }\n      if ((e = elf_memory(reinterpret_cast<char*>(const_cast<void*>(buffer)), size\n#ifdef AMD_LIBELF\n                       , NULL\n#endif\n        )) == NULL) {\n        out << \"elf_begin(buffer) failed: \" << elfError() << std::endl;\n        return false;\n      }\n      this->buffer = reinterpret_cast<const char*>(buffer);\n      this->bufferSize = size;\n      return pullElf();\n    }\n\n    bool GElfImage::pullElf()\n    {\n      if (!gelf_getehdr(e, &ehdr)) { return elfError(\"gelf_getehdr failed\"); }\n      segments.reserve(ehdr.e_phnum);\n      for (size_t i = 0; i < ehdr.e_phnum; ++i) {\n        GElfSegment* segment = new GElfSegment(this, i);\n        segment->pull();\n        segments.push_back(std::unique_ptr<GElfSegment>(segment));\n      }\n\n      shstrtabSection = new GElfStringTable(this);\n      if (!shstrtabSection->pull(ehdr.e_shstrndx)) { return false; }\n      Elf_Scn* scn = 0;\n      for (unsigned n = 0; n < ehdr.e_shnum; ++n) {\n        scn = elf_getscn(e, n);\n        if (n == ehdr.e_shstrndx) {\n          sections.push_back(std::unique_ptr<GElfSection>(shstrtabSection));\n          continue;\n        }\n        GElf_Shdr shdr;\n        if (!gelf_getshdr(scn, &shdr)) { return elfError(\"Failed to get shdr\"); }\n        GElfSection* section = 0;\n        if (shdr.sh_type == SHT_NOTE) {\n          section = new GElfNoteSection(this);\n        } else if (shdr.sh_type == SHT_RELA) {\n          section = new GElfRelocationSection(this);\n        } else if (shdr.sh_type == SHT_STRTAB) {\n          section = new GElfStringTable(this);\n        } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {\n          section = new GElfSymbolTable(this);\n        } else if (shdr.sh_type == SHT_NULL) {\n          section = 0;\n          sections.push_back(std::unique_ptr<GElfSection>());\n        } else {\n          section = new GElfSection(this);\n        }\n        if (section) {\n          sections.push_back(std::unique_ptr<GElfSection>(section));\n          if (!section->pull(n)) { return false; }\n        }\n      }\n\n      for (size_t n = 1; n < sections.size(); ++n) {\n        GElfSection* section = sections[n].get();\n        if (section->type() == SHT_STRTAB) {\n          if (!section->pullData()) { return false; }\n        }\n      }\n\n      for (size_t n = 1; n < sections.size(); ++n) {\n        GElfSection* section = sections[n].get();\n        if (section->type() == SHT_SYMTAB || section->type() == SHT_DYNSYM) {\n          if (!section->pullData()) { return false; }\n        }\n      }\n\n      for (size_t n = 1; n < sections.size(); ++n) {\n        GElfSection* section = sections[n].get();\n        if (section->type() != SHT_STRTAB && section->type() != SHT_SYMTAB && section->type() != SHT_DYNSYM) {\n          if (!section->pullData()) { return false; }\n        }\n      }\n\n      for (size_t i = 1; i < sections.size(); ++i) {\n        if (i == ehdr.e_shstrndx) { continue; }\n        std::unique_ptr<GElfSection>& section = sections[i];\n        if (section->type() == SHT_STRTAB) { strtabSection = static_cast<GElfStringTable*>(section.get()); }\n        if (section->type() == SHT_SYMTAB) { symtabSection = static_cast<GElfSymbolTable*>(section.get()); }\n        if (section->type() == SHT_NOTE) { noteSection = static_cast<GElfNoteSection*>(section.get()); }\n        if (section->type() == SHT_DYNSYM) { dynsymSection = static_cast<GElfSymbolTable*>(section.get()); }\n      }\n\n      size_t phnum;\n      if (elf_getphdrnum(e, &phnum) < 0) { return elfError(\"elf_getphdrnum failed\"); }\n      for (size_t i = 0; i < phnum; ++i) {\n        segments.push_back(std::unique_ptr<GElfSegment>(new GElfSegment(this, i)));\n        if (!segments[i]->pull()) { return false; }\n      }\n\n      return true;\n    }\n\n    bool GElfImage::elfError(const char* msg)\n    {\n      out << \"Error: \" << msg << \": \" << elfError() << std::endl;\n      return false;\n    }\n\n    uint64_t GElfImage::size()\n    {\n      if (buffer) {\n        return ElfSize(buffer);\n      } else {\n        return img.getSize();\n      }\n    }\n\n    bool GElfImage::push0()\n    {\n      assert(e);\n      for (std::unique_ptr<GElfSection>& section : sections) {\n        if (section && !section->push()) { return false; }\n      }\n\n      for (std::unique_ptr<GElfSection>& section : sections) {\n        if (section && !section->pull0()) { return false; }\n      }\n\n      if (!segments.empty()) {\n        if (!gelf_newphdr(e, segments.size())) { return elfError(\"gelf_newphdr failed\"); }\n      }\n      if (elf_update(e, ELF_C_NULL) < 0) { return elfError(\"elf_update (1.1) failed\"); }\n      if (!segments.empty()) {\n        for (std::unique_ptr<GElfSection>& section : sections) {\n          // Update section offsets.\n          if (section && !section->pull0()) { return false; }\n        }\n        uint64_t vaddr = 0;\n        for (std::unique_ptr<GElfSegment>& segment : segments) {\n          if (!segment->push(vaddr)) { return false; }\n          vaddr = segment->vaddr() + segment->memSize();\n        }\n      }\n      return true;\n    }\n\n    bool GElfImage::push()\n    {\n      if (!push0()) { return false; }\n      if (elf_update(e, ELF_C_WRITE) < 0) { return elfError(\"elf_update (2) failed\"); }\n      return true;\n    }\n\n    Segment* GElfImage::segmentByVAddr(uint64_t vaddr)\n    {\n      for (std::unique_ptr<GElfSegment>& seg : segments) {\n        if (seg->vaddr() <= vaddr && vaddr < seg->vaddr() + seg->memSize()) {\n          return seg.get();\n        }\n      }\n      return 0;\n    }\n\n    Section* GElfImage::sectionByVAddr(uint64_t vaddr)\n    {\n      for (size_t n = 1; n < sections.size(); ++n) {\n        if (sections[n]->addr() <= vaddr && vaddr < sections[n]->addr() + sections[n]->size()) {\n          return sections[n].get();\n        }\n      }\n      return nullptr;\n    }\n\n    bool GElfImage::elfEnd()\n    {\n      return false;\n    }\n\n    bool GElfImage::writeTo(const std::string& filename)\n    {\n      if (!img.writeTo(filename)) { return imgError(); }\n      return true;\n    }\n\n    bool GElfImage::copyToBuffer(void** buf, size_t* size)\n    {\n      if (buffer) {\n        *buf = malloc(bufferSize);\n        memcpy(*buf, buffer, bufferSize);\n        if (size) { *size = bufferSize; }\n        return true;\n      } else {\n        return img.copyTo(buf, size);\n      }\n    }\n\n    bool GElfImage::copyToBuffer(void* buf, size_t size)\n    {\n      if (buffer) {\n        if (size < bufferSize) { return false; }\n        memcpy(buf, buffer, bufferSize);\n        return true;\n      } else {\n        return img.copyTo(buf, size);\n      }\n    }\n\n    GElfStringTable* GElfImage::addStringTable(const std::string& name)\n    {\n      GElfStringTable* stab = new GElfStringTable(this);\n      sections.push_back(std::unique_ptr<GElfStringTable>(stab));\n      return stab;\n    }\n\n    GElfStringTable* GElfImage::getStringTable(uint16_t index)\n    {\n      return static_cast<GElfStringTable*>(sections[index].get());\n    }\n\n    GElfSymbolTable* GElfImage::addSymbolTable(const std::string& name, StringTable* stab)\n    {\n      if (!stab) { stab = strtab(); }\n      const char* name0 = shstrtab()->addString(name);\n      GElfSymbolTable* symtab = new GElfSymbolTable(this);\n      symtab->push(name0, static_cast<GElfStringTable*>(stab));\n      sections.push_back(std::unique_ptr<GElfSection>(symtab));\n      return symtab;\n    }\n\n    GElfStringTable* GElfImage::shstrtab() {\n      if (!shstrtabSection) {\n        shstrtabSection = addStringTable(\".shstrtab\");\n      }\n      return shstrtabSection;\n    }\n\n    GElfStringTable* GElfImage::strtab() {\n      if (!strtabSection) {\n        strtabSection = addStringTable(\".shstrtab\");\n      }\n      return strtabSection;\n    }\n\n    GElfSymbolTable* GElfImage::symtab()\n    {\n      if (!symtabSection) {\n        symtabSection = addSymbolTable(\".symtab\", strtab());\n      }\n      return symtabSection;\n    }\n\n    GElfSymbolTable* GElfImage::dynsym()\n    {\n      if (!dynsymSection) {\n        dynsymSection = addSymbolTable(\".dynsym\", strtab());\n      }\n      return dynsymSection;\n    }\n\n    GElfSymbolTable* GElfImage::getSymbolTable()\n    {\n      const char *UseDynsym = getenv(\"LOADER_USE_DYNSYM\");\n      if (UseDynsym && std::strncmp(UseDynsym, \"0\", 1) != 0)\n        return dynsym();\n      return symtab();\n    }\n\n    GElfNoteSection* GElfImage::note()\n    {\n      if (!noteSection) { noteSection = addNoteSection(\".note\"); }\n      return noteSection;\n    }\n\n    GElfNoteSection* GElfImage::addNoteSection(const std::string& name)\n    {\n      GElfNoteSection* note = new GElfNoteSection(this);\n      note->push(name);\n      sections.push_back(std::unique_ptr<GElfSection>(note));\n      return note;\n    }\n\n    Segment* GElfImage::initSegment(uint32_t type, uint32_t flags, uint64_t paddr)\n    {\n      GElfSegment *seg = new (std::nothrow) GElfSegment(this, segments.size(), type, flags, paddr);\n      segments.push_back(std::unique_ptr<GElfSegment>(seg));\n      return seg;\n    }\n\n    bool GElfImage::addSegments()\n    {\n      return true;\n    }\n\n    Section* GElfImage::addSection(const std::string &name,\n                                   uint32_t type,\n                                   uint64_t flags,\n                                   uint64_t entsize, Segment* segment)\n    {\n      GElfSection *section = new (std::nothrow) GElfSection(this);\n      if (!section || !section->push(name.c_str(), type, flags, 0, 0, 0, entsize)) {\n        delete section;\n        return nullptr;\n      }\n      if (segment) {\n        if (!segment->updateAddSection(section)) {\n          delete section;\n          return nullptr;\n        }\n      }\n      sections.push_back(std::unique_ptr<GElfSection>(section));\n      return section;\n    }\n\n    RelocationSection* GElfImage::addRelocationSection(Section* sec, SymbolTable* symtab)\n    {\n      std::string section_name = \".rela\" + sec->Name();\n      if (!symtab) { symtab = this->symtab(); }\n      GElfRelocationSection *rsec = new GElfRelocationSection(this, sec, (GElfSymbolTable*) symtab);\n      if (!rsec || !rsec->push(section_name)) {\n        delete rsec;\n        return nullptr;\n      }\n      sections.push_back(std::unique_ptr<GElfRelocationSection>(rsec));\n      return rsec;\n    }\n\n    RelocationSection* GElfImage::relocationSection(Section* sec, SymbolTable* symtab)\n    {\n      return sec->relocationSection(symtab);\n    }\n\n    uint16_t GElfImage::machine() const\n    {\n      return ehdr.e_machine;\n    }\n\n    uint16_t GElfImage::etype() const\n    {\n      return ehdr.e_type;\n    }\n\n    Image* NewElf32Image() { return new GElfImage(ELFCLASS32); }\n    Image* NewElf64Image() { return new GElfImage(ELFCLASS64); }\n\n    uint64_t ElfSize(const void* emi)\n    {\n      const Elf64_Ehdr *ehdr = (const Elf64_Ehdr*) emi;\n      if (NULL == ehdr || EV_CURRENT != ehdr->e_version) {\n        return false;\n      }\n\n      const Elf64_Shdr *shdr = (const Elf64_Shdr*)((char*)emi + ehdr->e_shoff);\n      if (NULL == shdr) {\n        return false;\n      }\n\n      uint64_t max_offset = ehdr->e_shoff;\n      uint64_t total_size = max_offset + static_cast<uint64_t>(ehdr->e_shentsize) * static_cast<uint64_t>(ehdr->e_shnum);\n\n      for (uint16_t i = 0; i < ehdr->e_shnum; ++i) {\n        uint64_t cur_offset = static_cast<uint64_t>(shdr[i].sh_offset);\n        if (max_offset < cur_offset) {\n          max_offset = cur_offset;\n          total_size = max_offset;\n          if (SHT_NOBITS != shdr[i].sh_type) {\n            total_size += static_cast<uint64_t>(shdr[i].sh_size);\n          }\n        }\n      }\n\n      return total_size;\n    }\n\n    std::string GetNoteString(uint32_t s_size, const char* s)\n    {\n      if (!s_size) { return \"\"; }\n      if (s[s_size-1] == '\\0') {\n        return std::string(s, s_size-1);\n      } else {\n        return std::string(s, s_size);\n      }\n    }\n\n}   //  namespace elf\n}   //  namespace amd\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_hsa_code.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include <assert.h>\n#include <cstring>\n#include <iomanip>\n#include <algorithm>\n#include \"core/inc/amd_hsa_code.hpp\"\n#include \"amd_hsa_code_util.hpp\"\n#include <libelf.h>\n#include \"inc/amd_hsa_elf.h\"\n#include <fstream>\n#include <sstream>\n#include <cstdlib>\n#include <algorithm>\n\n#ifdef SP3_STATIC_LIB\n#include \"sp3.h\"\n#endif // SP3_STATIC_LIB\n\n#ifndef _WIN32\n#define _alloca alloca\n#endif\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace code {\n\n    using amd::elf::GetNoteString;\n\n    bool Symbol::IsDeclaration() const\n    {\n      return elfsym->type() == STT_COMMON;\n    }\n\n    bool Symbol::IsDefinition() const\n    {\n      return !IsDeclaration();\n    }\n\n    bool Symbol::IsAgent() const\n    {\n      return elfsym->section()->flags() & SHF_AMDGPU_HSA_AGENT ? true : false;\n    }\n\n    hsa_symbol_linkage_t Symbol::Linkage() const\n    {\n      return elfsym->binding() == STB_GLOBAL ? HSA_SYMBOL_LINKAGE_PROGRAM : HSA_SYMBOL_LINKAGE_MODULE;\n    }\n\n    hsa_variable_allocation_t Symbol::Allocation() const\n    {\n      return IsAgent() ? HSA_VARIABLE_ALLOCATION_AGENT : HSA_VARIABLE_ALLOCATION_PROGRAM;\n    }\n\n    hsa_variable_segment_t Symbol::Segment() const\n    {\n      return elfsym->section()->flags() & SHF_AMDGPU_HSA_READONLY ? HSA_VARIABLE_SEGMENT_READONLY : HSA_VARIABLE_SEGMENT_GLOBAL;\n    }\n\n    uint64_t Symbol::Size() const\n    {\n      return elfsym->size();\n    }\n\n    uint32_t Symbol::Size32() const\n    {\n      assert(elfsym->size() < UINT32_MAX);\n      return (uint32_t) Size();\n    }\n\n    uint32_t Symbol::Alignment() const\n    {\n      assert(elfsym->section()->addralign() < UINT32_MAX);\n      return uint32_t(elfsym->section()->addralign());\n    }\n\n    bool Symbol::IsConst() const\n    {\n      return elfsym->section()->flags() & SHF_WRITE ? true : false;\n    }\n\n    hsa_status_t Symbol::GetInfo(hsa_code_symbol_info_t attribute, void *value)\n    {\n      if (!value) {\n          return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n\n      switch (attribute) {\n        case HSA_CODE_SYMBOL_INFO_TYPE: {\n          *((hsa_symbol_kind_t*)value) = Kind();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_NAME_LENGTH: {\n          *((uint32_t*)value) = GetSymbolName().size();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_NAME: {\n          std::string SymbolName = GetSymbolName();\n          memset(value, 0x0, SymbolName.size());\n          memcpy(value, SymbolName.c_str(), SymbolName.size());\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_MODULE_NAME_LENGTH: {\n          *((uint32_t*)value) = GetModuleName().size();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_MODULE_NAME: {\n          std::string ModuleName = GetModuleName();\n          memset(value, 0x0, ModuleName.size());\n          memcpy(value, ModuleName.c_str(), ModuleName.size());\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_LINKAGE: {\n          *((hsa_symbol_linkage_t*)value) = Linkage();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_IS_DEFINITION: {\n          *((bool*)value) = IsDefinition();\n          break;\n        }\n        default: {\n          return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n        }\n      }\n      return HSA_STATUS_SUCCESS;\n    }\n\n    std::string Symbol::GetModuleName() const {\n      std::string FullName = Name();\n      return FullName.rfind(\":\") != std::string::npos ?\n        FullName.substr(0, FullName.find(\":\")) : \"\";\n    }\n\n    std::string Symbol::GetSymbolName() const {\n      std::string FullName = Name();\n      return FullName.rfind(\":\") != std::string::npos ?\n        FullName.substr(FullName.rfind(\":\") + 1) : std::move(FullName);\n    }\n\n    hsa_code_symbol_t Symbol::ToHandle(Symbol* sym)\n    {\n      hsa_code_symbol_t s;\n      s.handle = reinterpret_cast<uint64_t>(sym);\n      return s;\n    }\n\n    Symbol* Symbol::FromHandle(hsa_code_symbol_t s)\n    {\n      return reinterpret_cast<Symbol*>(s.handle);\n    }\n\n    KernelSymbol::KernelSymbol(amd::elf::Symbol* elfsym_, const amd_kernel_code_t* akc)\n        : Symbol(elfsym_)\n        , kernarg_segment_size(0)\n        , kernarg_segment_alignment(0)\n        , group_segment_size(0)\n        , private_segment_size(0)\n        , is_dynamic_callstack(0)\n    {\n      if (akc) {\n        kernarg_segment_size = (uint32_t) akc->kernarg_segment_byte_size;\n        kernarg_segment_alignment = (uint32_t) (1 << akc->kernarg_segment_alignment);\n        group_segment_size = uint32_t(akc->workgroup_group_segment_byte_size);\n        private_segment_size = uint32_t(akc->workitem_private_segment_byte_size);\n        is_dynamic_callstack =\n          AMD_HSA_BITS_GET(akc->kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_DYNAMIC_CALLSTACK) ? true : false;\n      }\n    }\n\n    hsa_status_t KernelSymbol::GetInfo(hsa_code_symbol_info_t attribute, void *value)\n    {\n      assert(value);\n      switch (attribute) {\n        case HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE: {\n          *((uint32_t*)value) = kernarg_segment_size;\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT: {\n          *((uint32_t*)value) = kernarg_segment_alignment;\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE: {\n          *((uint32_t*)value) = group_segment_size;\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE: {\n          *((uint32_t*)value) = private_segment_size;\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK: {\n          *((bool*)value) = is_dynamic_callstack;\n          break;\n        }\n        default: {\n          return Symbol::GetInfo(attribute, value);\n        }\n      }\n      return HSA_STATUS_SUCCESS;\n    }\n\n    hsa_status_t VariableSymbol::GetInfo(hsa_code_symbol_info_t attribute, void *value)\n    {\n      assert(value);\n      switch (attribute) {\n        case HSA_CODE_SYMBOL_INFO_VARIABLE_ALLOCATION: {\n          *((hsa_variable_allocation_t*)value) = Allocation();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_VARIABLE_SEGMENT: {\n          *((hsa_variable_segment_t*)value) = Segment();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_VARIABLE_ALIGNMENT: {\n          *((uint32_t*)value) = Alignment();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_VARIABLE_SIZE: {\n          *((uint32_t*)value) = Size();\n          break;\n        }\n        case HSA_CODE_SYMBOL_INFO_VARIABLE_IS_CONST: {\n          *((bool*)value) = IsConst();\n          break;\n        }\n        default: {\n          return Symbol::GetInfo(attribute, value);\n        }\n      }\n      return HSA_STATUS_SUCCESS;\n    }\n\n    AmdHsaCode::AmdHsaCode(bool combineDataSegments_)\n      : img(nullptr),\n        combineDataSegments(combineDataSegments_),\n        hsatext(0), imageInit(0), samplerInit(0),\n        debugInfo(0), debugLine(0), debugAbbrev(0)\n    {\n      for (unsigned i = 0; i < AMDGPU_HSA_SEGMENT_LAST; ++i) {\n        for (unsigned j = 0; j < 2; ++j) {\n          hsaSegments[i][j] = 0;\n        }\n      }\n      for (unsigned i = 0; i < AMDGPU_HSA_SECTION_LAST; ++i) {\n        hsaSections[i] = 0;\n      }\n    }\n\n    AmdHsaCode::~AmdHsaCode()\n    {\n      for (Symbol* sym : symbols) { delete sym; }\n    }\n\n    bool AmdHsaCode::PullElf()\n    {\n      uint32_t majorVersion, minorVersion;\n      if (!GetCodeObjectVersion(&majorVersion, &minorVersion)) {\n        return false;\n      }\n      if (majorVersion >= 2) {\n        return PullElfV2();\n      } else {\n        return PullElfV1();\n      }\n    }\n\n    bool AmdHsaCode::PullElfV1()\n    {\n      for (size_t i = 0; i < img->segmentCount(); ++i) {\n        Segment* s = img->segment(i);\n        if (s->type() == PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM ||\n            s->type() == PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT ||\n            s->type() == PT_AMDGPU_HSA_LOAD_READONLY_AGENT ||\n            s->type() == PT_AMDGPU_HSA_LOAD_CODE_AGENT) {\n          dataSegments.push_back(s);\n        }\n      }\n      for (size_t i = 0; i < img->sectionCount(); ++i) {\n        Section* sec = img->section(i);\n        if (!sec) { continue; }\n        if ((sec->type() == SHT_PROGBITS || sec->type() == SHT_NOBITS) &&\n            (sec->flags() & (SHF_AMDGPU_HSA_AGENT | SHF_AMDGPU_HSA_GLOBAL | SHF_AMDGPU_HSA_READONLY | SHF_AMDGPU_HSA_CODE))) {\n          dataSections.push_back(sec);\n        } else if (sec->type() == SHT_RELA) {\n          relocationSections.push_back(sec->asRelocationSection());\n        }\n        if (sec->Name() == \".hsatext\") {\n          hsatext = sec;\n        }\n      }\n      for (size_t i = 0; i < img->symtab()->symbolCount(); ++i) {\n        amd::elf::Symbol* elfsym = img->symtab()->symbol(i);\n        Symbol* sym = 0;\n        switch (elfsym->type()) {\n        case STT_AMDGPU_HSA_KERNEL: {\n          amd::elf::Section* sec = elfsym->section();\n          amd_kernel_code_t akc;\n          if (!sec) {\n            out << \"Failed to find section for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          if (!(sec->flags() & (SHF_AMDGPU_HSA_AGENT | SHF_AMDGPU_HSA_CODE | SHF_EXECINSTR))) {\n            out << \"Invalid code section for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          if (!sec->getData(elfsym->value(), &akc, sizeof(amd_kernel_code_t))) {\n            out << \"Failed to get AMD Kernel Code for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          sym = new KernelSymbol(elfsym, &akc);\n          break;\n        }\n        case STT_OBJECT:\n        case STT_COMMON:\n          sym = new VariableSymbol(elfsym);\n          break;\n        default:\n          break; // Skip unknown symbols.\n        }\n        if (sym) { symbols.push_back(sym); }\n      }\n\n      return true;\n    }\n\n    bool AmdHsaCode::LoadFromFile(const std::string& filename)\n    {\n      if (!img) { img.reset(amd::elf::NewElf64Image()); }\n      if (!img->loadFromFile(filename)) { return ElfImageError(); }\n      if (!PullElf()) { return ElfImageError(); }\n      return true;\n    }\n\n    bool AmdHsaCode::SaveToFile(const std::string& filename)\n    {\n      return img->saveToFile(filename) || ElfImageError();\n    }\n\n    bool AmdHsaCode::WriteToBuffer(void* buffer)\n    {\n      return img->copyToBuffer(buffer, ElfSize()) || ElfImageError();\n    }\n\n\n    bool AmdHsaCode::InitFromBuffer(const void* buffer, size_t size)\n    {\n      if (!img) { img.reset(amd::elf::NewElf64Image()); }\n      if (!img->initFromBuffer(buffer, size)) { return ElfImageError(); }\n      if (!PullElf()) { return ElfImageError(); }\n      return true;\n    }\n\n    bool AmdHsaCode::InitAsBuffer(const void* buffer, size_t size)\n    {\n      if (!img) { img.reset(amd::elf::NewElf64Image()); }\n      if (!img->initAsBuffer(buffer, size)) { return ElfImageError(); }\n      if (!PullElf()) { return ElfImageError(); }\n      return true;\n    }\n\n    bool AmdHsaCode::InitAsHandle(hsa_code_object_t code_object)\n    {\n      void *elfmemrd = reinterpret_cast<void*>(code_object.handle);\n      if (!elfmemrd) { return false; }\n      return InitAsBuffer(elfmemrd, 0);\n    }\n\n    bool AmdHsaCode::InitNew(bool xnack)\n    {\n      if (!img) {\n        img.reset(amd::elf::NewElf64Image());\n        uint32_t flags = 0;\n        if (xnack) { flags |= ELF::EF_AMDGPU_FEATURE_XNACK_V2; }\n        return img->initNew(ELF::EM_AMDGPU, ET_EXEC, ELF::ELFOSABI_AMDGPU_HSA, ELF::ELFABIVERSION_AMDGPU_HSA_V2, flags) ||\n          ElfImageError(); // FIXME: elfutils libelf does not allow program headers in ET_REL file type, so change it later in finalizer.\n      }\n      return false;\n    }\n\n    bool AmdHsaCode::Freeze()\n    {\n      return img->Freeze() || ElfImageError();\n    }\n\n    hsa_code_object_t AmdHsaCode::GetHandle()\n    {\n      hsa_code_object_t code_object;\n      code_object.handle = reinterpret_cast<uint64_t>(img->data());\n      return code_object;\n    }\n\n    const char* AmdHsaCode::ElfData()\n    {\n      return img->data();\n    }\n\n    uint64_t AmdHsaCode::ElfSize()\n    {\n      return img->size();\n    }\n\n    bool AmdHsaCode::Validate()\n    {\n      if (!img->Validate()) { return ElfImageError(); }\n      if (img->Machine() != ELF::EM_AMDGPU) {\n        out << \"ELF error: Invalid machine\" << std::endl;\n        return false;\n      }\n      return true;\n    }\n\n    void AmdHsaCode::AddAmdNote(uint32_t type, const void* desc, uint32_t desc_size)\n    {\n      img->note()->addNote(\"AMD\", type, desc, desc_size);\n    }\n\n    void AmdHsaCode::AddNoteCodeObjectVersion(uint32_t major, uint32_t minor)\n    {\n      amdgpu_hsa_note_code_object_version_t desc;\n      desc.major_version = major;\n      desc.minor_version = minor;\n      AddAmdNote(NT_AMD_HSA_CODE_OBJECT_VERSION, &desc, sizeof(desc));\n    }\n\n    bool AmdHsaCode::GetCodeObjectVersion(uint32_t* major, uint32_t* minor)\n    {\n      switch (img->ABIVersion()) {\n      case ELF::ELFABIVERSION_AMDGPU_HSA_V2:\n        amdgpu_hsa_note_code_object_version_t* desc;\n        if (GetAmdNote(NT_AMD_HSA_CODE_OBJECT_VERSION, &desc)) {\n          *major = desc->major_version;\n          *minor = desc->minor_version;\n          return *major <= 2;\n        }\n        return false;\n      case ELF::ELFABIVERSION_AMDGPU_HSA_V3:\n        *major = 3;\n        *minor = 0;\n        return true;\n      case ELF::ELFABIVERSION_AMDGPU_HSA_V4:\n        *major = 4;\n        *minor = 0;\n        return true;\n      case ELF::ELFABIVERSION_AMDGPU_HSA_V5:\n        *major = 5;\n        *minor = 0;\n        return true;\n      case ELF::ELFABIVERSION_AMDGPU_HSA_V6:\n        *major = 6;\n        *minor = 0;\n        return true;\n      }\n\n      return false;\n    }\n\n    bool AmdHsaCode::GetNoteCodeObjectVersion(std::string& version)\n    {\n      amdgpu_hsa_note_code_object_version_t* desc;\n      if (!GetAmdNote(NT_AMD_HSA_CODE_OBJECT_VERSION, &desc)) { return false; }\n      version.clear();\n      version += std::to_string(desc->major_version);\n      version += \".\";\n      version += std::to_string(desc->minor_version);\n      return true;\n    }\n\n    void AmdHsaCode::AddNoteHsail(uint32_t hsail_major, uint32_t hsail_minor, hsa_profile_t profile, hsa_machine_model_t machine_model, hsa_default_float_rounding_mode_t rounding_mode)\n    {\n      amdgpu_hsa_note_hsail_t desc;\n      memset(&desc, 0, sizeof(desc));\n      desc.hsail_major_version = hsail_major;\n      desc.hsail_minor_version = hsail_minor;\n      desc.profile = uint8_t(profile);\n      desc.machine_model = uint8_t(machine_model);\n      desc.default_float_round = uint8_t(rounding_mode);\n      AddAmdNote(NT_AMD_HSA_HSAIL, &desc, sizeof(desc));\n    }\n\n    bool AmdHsaCode::GetNoteHsail(uint32_t* hsail_major, uint32_t* hsail_minor, hsa_profile_t* profile, hsa_machine_model_t* machine_model, hsa_default_float_rounding_mode_t* default_float_round)\n    {\n      amdgpu_hsa_note_hsail_t *desc;\n      if (!GetAmdNote(NT_AMD_HSA_HSAIL, &desc)) { return false; }\n      *hsail_major = desc->hsail_major_version;\n      *hsail_minor = desc->hsail_minor_version;\n      *profile = (hsa_profile_t) desc->profile;\n      *machine_model = (hsa_machine_model_t) desc->machine_model;\n      *default_float_round = (hsa_default_float_rounding_mode_t) desc->default_float_round;\n      return true;\n    }\n\n    void AmdHsaCode::AddNoteIsa(const std::string& vendor_name, const std::string& architecture_name, uint32_t major, uint32_t minor, uint32_t stepping)\n    {\n      size_t size = sizeof(amdgpu_hsa_note_producer_t) + vendor_name.length() + architecture_name.length() + 1;\n      amdgpu_hsa_note_isa_t* desc = (amdgpu_hsa_note_isa_t*) _alloca(size);\n      memset(desc, 0, size);\n      desc->vendor_name_size = vendor_name.length()+1;\n      desc->architecture_name_size = architecture_name.length()+1;\n      desc->major = major;\n      desc->minor = minor;\n      desc->stepping = stepping;\n      memcpy(desc->vendor_and_architecture_name, vendor_name.c_str(), vendor_name.length() + 1);\n      memcpy(desc->vendor_and_architecture_name + desc->vendor_name_size, architecture_name.c_str(), architecture_name.length() + 1);\n      AddAmdNote(NT_AMD_HSA_ISA_VERSION, desc, size);\n    }\n\n    bool AmdHsaCode::GetNoteIsa(std::string& vendor_name, std::string& architecture_name, uint32_t* major_version, uint32_t* minor_version, uint32_t* stepping)\n    {\n      amdgpu_hsa_note_isa_t *desc;\n      if (!GetAmdNote(NT_AMD_HSA_ISA_VERSION, &desc)) { return false; }\n      vendor_name = GetNoteString(desc->vendor_name_size, desc->vendor_and_architecture_name);\n      architecture_name = GetNoteString(desc->architecture_name_size, desc->vendor_and_architecture_name + vendor_name.length() + 1);\n      *major_version = desc->major;\n      *minor_version = desc->minor;\n      *stepping = desc->stepping;\n      return true;\n    }\n\n    struct MachInfo {\n      std::string Name = \"\";\n      bool XnackSupported = false;\n      bool SrameccSupported = false;\n    };\n\n    // TODO: Move isa registry into the loader.\n    static bool GetMachInfo(unsigned Mach, MachInfo &MI) {\n      switch (Mach) {\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:  MI.Name = \"gfx600\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:  MI.Name = \"gfx601\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:  MI.Name = \"gfx602\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:  MI.Name = \"gfx700\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:  MI.Name = \"gfx701\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:  MI.Name = \"gfx702\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:  MI.Name = \"gfx703\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:  MI.Name = \"gfx704\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:  MI.Name = \"gfx705\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:  MI.Name = \"gfx801\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:  MI.Name = \"gfx802\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:  MI.Name = \"gfx803\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:  MI.Name = \"gfx805\";  MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:  MI.Name = \"gfx810\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:  MI.Name = \"gfx900\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:  MI.Name = \"gfx902\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:  MI.Name = \"gfx904\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:  MI.Name = \"gfx906\";  MI.XnackSupported = true;  MI.SrameccSupported = true;  break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:  MI.Name = \"gfx908\";  MI.XnackSupported = true;  MI.SrameccSupported = true;  break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:  MI.Name = \"gfx909\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A:  MI.Name = \"gfx90a\";  MI.XnackSupported = true;  MI.SrameccSupported = true;  break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:  MI.Name = \"gfx90c\";  MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX942:  MI.Name = \"gfx942\";  MI.XnackSupported = true;  MI.SrameccSupported = true;  break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX950:  MI.Name = \"gfx950\";  MI.XnackSupported = true;  MI.SrameccSupported = true;  break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: MI.Name = \"gfx1010\"; MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: MI.Name = \"gfx1011\"; MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: MI.Name = \"gfx1012\"; MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013: MI.Name = \"gfx1013\"; MI.XnackSupported = true;  MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: MI.Name = \"gfx1030\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031: MI.Name = \"gfx1031\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032: MI.Name = \"gfx1032\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033: MI.Name = \"gfx1033\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034: MI.Name = \"gfx1034\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035: MI.Name = \"gfx1035\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036: MI.Name = \"gfx1036\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100: MI.Name = \"gfx1100\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101: MI.Name = \"gfx1101\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102: MI.Name = \"gfx1102\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103: MI.Name = \"gfx1103\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150: MI.Name = \"gfx1150\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151: MI.Name = \"gfx1151\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152: MI.Name = \"gfx1152\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153: MI.Name = \"gfx1153\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200: MI.Name = \"gfx1200\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201: MI.Name = \"gfx1201\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC:    MI.Name = \"gfx9-generic\";    MI.XnackSupported = true; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC:  MI.Name = \"gfx9-4-generic\";  MI.XnackSupported = true;  MI.SrameccSupported = true; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC: MI.Name = \"gfx10-1-generic\"; MI.XnackSupported = true; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC: MI.Name = \"gfx10-3-generic\"; MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC:   MI.Name = \"gfx11-generic\";   MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      case ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC:   MI.Name = \"gfx12-generic\";   MI.XnackSupported = false; MI.SrameccSupported = false; break;\n      default: return false;\n      }\n      return true;\n    }\n\n    // This fuction is also copied to the Code Object Manager library.\n    static std::string ConvertOldTargetNameToNew(const std::string &old_name, bool is_finalizer, uint32_t e_flags) {\n      assert(!old_name.empty() && \"Expecting non-empty old name\");\n\n      unsigned mach = 0;\n      if (old_name == \"AMD:AMDGPU:6:0:0\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX600;\n      else if (old_name == \"AMD:AMDGPU:6:0:1\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX601;\n      else if (old_name == \"AMD:AMDGPU:6:0:2\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX602;\n      else if (old_name == \"AMD:AMDGPU:7:0:0\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX700;\n      else if (old_name == \"AMD:AMDGPU:7:0:1\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX701;\n      else if (old_name == \"AMD:AMDGPU:7:0:2\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX702;\n      else if (old_name == \"AMD:AMDGPU:7:0:3\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX703;\n      else if (old_name == \"AMD:AMDGPU:7:0:4\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX704;\n      else if (old_name == \"AMD:AMDGPU:7:0:5\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX705;\n      else if (old_name == \"AMD:AMDGPU:8:0:1\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX801;\n      else if (old_name == \"AMD:AMDGPU:8:0:0\" || old_name == \"AMD:AMDGPU:8:0:2\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX802;\n      else if (old_name == \"AMD:AMDGPU:8:0:3\" || old_name == \"AMD:AMDGPU:8:0:4\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX803;\n      else if (old_name == \"AMD:AMDGPU:8:0:5\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX805;\n      else if (old_name == \"AMD:AMDGPU:8:1:0\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX810;\n      else if (old_name == \"AMD:AMDGPU:9:0:0\" || old_name == \"AMD:AMDGPU:9:0:1\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX900;\n      else if (old_name == \"AMD:AMDGPU:9:0:2\" || old_name == \"AMD:AMDGPU:9:0:3\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX902;\n      else if (old_name == \"AMD:AMDGPU:9:0:4\" || old_name == \"AMD:AMDGPU:9:0:5\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX904;\n      else if (old_name == \"AMD:AMDGPU:9:0:6\" || old_name == \"AMD:AMDGPU:9:0:7\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX906;\n      else if (old_name == \"AMD:AMDGPU:9:0:12\")\n        mach = ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C;\n      else {\n        // Code object v2 only supports asics up to gfx906 plus gfx90c. Do NOT\n        // add handling of new asics into this if-else-if* block.\n        return \"\";\n      }\n      MachInfo MI;\n      if (!GetMachInfo(mach, MI))\n        return \"\";\n\n      // Only \"AMD:AMDGPU:9:0:6\" and \"AMD:AMDGPU:9:0:7\" supports SRAMECC for\n      // code object V2, and it must be OFF.\n      if (MI.SrameccSupported)\n        MI.Name += \":sramecc-\";\n\n      if (is_finalizer) {\n        if (e_flags & ELF::EF_AMDGPU_FEATURE_XNACK_V2)\n          MI.Name += \":xnack+\";\n        else if (MI.XnackSupported)\n          MI.Name += \":xnack-\";\n      } else {\n        if (old_name == \"AMD:AMDGPU:8:0:1\")\n          MI.Name += \":xnack+\";\n        else if (old_name == \"AMD:AMDGPU:8:1:0\")\n          MI.Name += \":xnack+\";\n        else if (old_name == \"AMD:AMDGPU:9:0:1\")\n          MI.Name += \":xnack+\";\n        else if (old_name == \"AMD:AMDGPU:9:0:3\")\n          MI.Name += \":xnack+\";\n        else if (old_name == \"AMD:AMDGPU:9:0:5\")\n          MI.Name += \":xnack+\";\n        else if (old_name == \"AMD:AMDGPU:9:0:7\")\n          MI.Name += \":xnack+\";\n        else if (MI.XnackSupported)\n          MI.Name += \":xnack-\";\n      }\n\n      return MI.Name;\n    }\n\n    bool AmdHsaCode::GetIsa(std::string& isa_name, unsigned *genericVersion)\n    {\n      isa_name.clear();\n\n      uint32_t code_object_major_version = 0;\n      uint32_t code_object_minor_version = 0;\n\n      // Generic versioning starts at 1, so zero means no generic version.\n      if (genericVersion)\n        *genericVersion = 0;\n\n      switch (img->EClass()) {\n      case ELFCLASS64:\n        // There is no e_machine and/or OS ABI for R600 so rely on checking\n        // the ELFCLASS to determine if AMDGCN versus R600. AMDHSA always uses\n        // ELFCLASS64 and R600 always uses ELFCLASS32.\n        isa_name += \"amdgcn\";\n        break;\n      default:\n        return false;\n      }\n      if (img->Machine() != ELF::EM_AMDGPU)\n        return false;\n      isa_name += \"-amd-\";\n\n      if (!GetCodeObjectVersion(&code_object_major_version, &code_object_minor_version)) {\n        return false;\n      }\n      if (code_object_major_version >= 3) {\n\n        switch (img->OsAbi()) {\n        case ELF::ELFOSABI_AMDGPU_HSA:\n          isa_name += \"amdhsa\";\n          break;\n        default:\n          // Only support AMDHSA in the ROCm runtime.\n          return false;\n        }\n\n        isa_name += \"--\";\n\n        unsigned mach = img->EFlags() & ELF::EF_AMDGPU_MACH;\n        MachInfo MI;\n\n        if (!GetMachInfo(mach, MI))\n          return false;\n\n        if (code_object_major_version == 3) {\n          if (img->EFlags() & ELF::EF_AMDGPU_FEATURE_SRAMECC_V3)\n            MI.Name += \":sramecc+\";\n          else if (MI.SrameccSupported)\n            MI.Name += \":sramecc-\";\n\n          if (img->EFlags() & ELF::EF_AMDGPU_FEATURE_XNACK_V3)\n            MI.Name += \":xnack+\";\n          else if (MI.XnackSupported)\n            MI.Name += \":xnack-\";\n        } else if (code_object_major_version >= 4) {\n          switch (img->EFlags() & ELF::EF_AMDGPU_FEATURE_SRAMECC_V4) {\n          case ELF::EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:\n            MI.Name += \":sramecc-\";\n            break;\n          case ELF::EF_AMDGPU_FEATURE_SRAMECC_ON_V4:\n            MI.Name += \":sramecc+\";\n            break;\n          }\n\n          switch (img->EFlags() & ELF::EF_AMDGPU_FEATURE_XNACK_V4) {\n          case ELF::EF_AMDGPU_FEATURE_XNACK_OFF_V4:\n            MI.Name += \":xnack-\";\n            break;\n          case ELF::EF_AMDGPU_FEATURE_XNACK_ON_V4:\n            MI.Name += \":xnack+\";\n            break;\n          }\n\n          // Generic version is not part of the ISA name.\n          // Only parse it when the caller wants it.\n          if (genericVersion && code_object_major_version >= 6) {\n            *genericVersion = (img->EFlags() & ELF::EF_AMDGPU_GENERIC_VERSION) >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET;\n          }\n        } else {\n          return false;\n        }\n\n        isa_name += MI.Name;\n\n        return true;\n      } else {\n\n        std::string vendor_name, architecture_name;\n        uint32_t major_version, minor_version, stepping;\n        if (!GetNoteIsa(vendor_name, architecture_name, &major_version, &minor_version, &stepping))\n          return false;\n\n        isa_name += \"amdhsa--\";\n\n        std::string target_name = vendor_name + ':' + architecture_name + ':' +\n            std::to_string(major_version) + ':' + std::to_string(minor_version) + ':' +\n            std::to_string(stepping);\n\n        amdgpu_hsa_note_hsail_t *hsail_note;\n        bool is_finalizer = GetAmdNote(NT_AMD_HSA_HSAIL, &hsail_note);\n        target_name = ConvertOldTargetNameToNew(target_name, is_finalizer, img->EFlags());\n        if (target_name.empty()) return false;\n\n        isa_name += target_name;\n\n        return true;\n      }\n    }\n\n    void AmdHsaCode::AddNoteProducer(uint32_t major, uint32_t minor, const std::string& producer)\n    {\n      size_t size = sizeof(amdgpu_hsa_note_producer_t) + producer.length();\n      amdgpu_hsa_note_producer_t* desc = (amdgpu_hsa_note_producer_t*) _alloca(size);\n      memset(desc, 0, size);\n      desc->producer_name_size = producer.length();\n      desc->producer_major_version = major;\n      desc->producer_minor_version = minor;\n      memcpy(desc->producer_name, producer.c_str(), producer.length() + 1);\n      AddAmdNote(NT_AMD_HSA_PRODUCER, desc, size);\n    }\n\n    bool AmdHsaCode::GetNoteProducer(uint32_t* major, uint32_t* minor, std::string& producer_name)\n    {\n      amdgpu_hsa_note_producer_t* desc;\n      if (!GetAmdNote(NT_AMD_HSA_PRODUCER, &desc)) { return false; }\n      *major = desc->producer_major_version;\n      *minor = desc->producer_minor_version;\n      producer_name = GetNoteString(desc->producer_name_size, desc->producer_name);\n      return true;\n    }\n\n    void AmdHsaCode::AddNoteProducerOptions(const std::string& options)\n    {\n      size_t size = sizeof(amdgpu_hsa_note_producer_options_t) + options.length();\n      amdgpu_hsa_note_producer_options_t *desc = (amdgpu_hsa_note_producer_options_t*) _alloca(size);\n      desc->producer_options_size = options.length();\n      memcpy(desc->producer_options, options.c_str(), options.length() + 1);\n      AddAmdNote(NT_AMD_HSA_PRODUCER_OPTIONS, desc, size);\n    }\n\n    void AmdHsaCode::AddNoteProducerOptions(int32_t call_convention, const hsa_ext_control_directives_t& user_directives, const std::string& user_options)\n    {\n      using namespace code_options;\n      std::ostringstream ss;\n      ss <<\n        space << \"-hsa_call_convention=\" << call_convention <<\n        control_directives(user_directives);\n      if (!user_options.empty()) {\n        ss << space << user_options;\n      }\n\n      AddNoteProducerOptions(ss.str());\n    }\n\n    bool AmdHsaCode::GetNoteProducerOptions(std::string& options)\n    {\n      amdgpu_hsa_note_producer_options_t* desc;\n      if (!GetAmdNote(NT_AMD_HSA_PRODUCER_OPTIONS, &desc)) { return false; }\n      options = GetNoteString(desc->producer_options_size, desc->producer_options);\n      return true;\n    }\n\n    hsa_status_t AmdHsaCode::GetInfo(hsa_code_object_info_t attribute, void *value)\n    {\n      assert(value);\n      switch (attribute) {\n      case HSA_CODE_OBJECT_INFO_VERSION: {\n        std::string version;\n        if (!GetNoteCodeObjectVersion(version)) { return HSA_STATUS_ERROR_INVALID_CODE_OBJECT; }\n        char *svalue = (char*)value;\n        memset(svalue, 0x0, 64);\n        memcpy(svalue, version.c_str(), (std::min)(size_t(63), version.length()));\n        break;\n      }\n      case HSA_CODE_OBJECT_INFO_ISA: {\n        // TODO: Currently returns string representation instead of hsa_isa_t\n        // which is unavailable here.\n        std::string isa;\n        if (!GetIsa(isa)) { return HSA_STATUS_ERROR_INVALID_CODE_OBJECT; }\n        char *svalue = (char*)value;\n        memset(svalue, 0x0, 64);\n        memcpy(svalue, isa.c_str(), (std::min)(size_t(63), isa.length()));\n        break;\n      }\n      case HSA_CODE_OBJECT_INFO_MACHINE_MODEL:\n      case HSA_CODE_OBJECT_INFO_PROFILE:\n      case HSA_CODE_OBJECT_INFO_DEFAULT_FLOAT_ROUNDING_MODE: {\n        uint32_t hsail_major, hsail_minor;\n        hsa_profile_t profile;\n        hsa_machine_model_t machine_model;\n        hsa_default_float_rounding_mode_t default_float_round;\n        if (!GetNoteHsail(&hsail_major, &hsail_minor, &profile, &machine_model, &default_float_round)) {\n          return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n        }\n        switch (attribute) {\n        case HSA_CODE_OBJECT_INFO_MACHINE_MODEL:\n           *((hsa_machine_model_t*)value) = machine_model; break;\n        case HSA_CODE_OBJECT_INFO_PROFILE:\n          *((hsa_profile_t*)value) = profile; break;\n        case HSA_CODE_OBJECT_INFO_DEFAULT_FLOAT_ROUNDING_MODE:\n          *((hsa_default_float_rounding_mode_t*)value) = default_float_round; break;\n        default: break;\n        }\n        break;\n      }\n      default:\n        assert(false);\n        return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n      }\n      return HSA_STATUS_SUCCESS;\n    }\n\n    hsa_status_t AmdHsaCode::GetSymbol(const char *module_name, const char *symbol_name, hsa_code_symbol_t *s)\n    {\n      std::string mname = MangleSymbolName(\n        std::string(module_name ? module_name : \"\"),\n        std::string(symbol_name)\n      );\n      for (Symbol* sym : symbols) {\n        if (sym->Name() == mname) {\n          *s = Symbol::ToHandle(sym);\n          return HSA_STATUS_SUCCESS;\n        }\n      }\n      return HSA_STATUS_ERROR_INVALID_SYMBOL_NAME;\n    }\n\n    hsa_status_t AmdHsaCode::IterateSymbols(hsa_code_object_t code_object,\n                                  hsa_status_t (*callback)(\n                                  hsa_code_object_t code_object,\n                                  hsa_code_symbol_t symbol,\n                                  void* data),\n                                void* data)\n    {\n      for (Symbol* sym : symbols) {\n        hsa_code_symbol_t s = Symbol::ToHandle(sym);\n        hsa_status_t status = callback(code_object, s, data);\n        if (status != HSA_STATUS_SUCCESS) { return status; }\n      }\n      return HSA_STATUS_SUCCESS;\n    }\n\n    Section* AmdHsaCode::ImageInitSection()\n    {\n      if (!imageInit) {\n        imageInit = img->addSection(\n          \".hsaimage_imageinit\",\n          SHT_PROGBITS,\n          SHF_MERGE,\n          sizeof(amdgpu_hsa_image_descriptor_t));\n      }\n      return imageInit;\n    }\n\n    void AmdHsaCode::AddImageInitializer(Symbol* image, uint64_t destOffset, const amdgpu_hsa_image_descriptor_t& desc)\n    {\n      uint64_t offset = ImageInitSection()->addData(&desc, sizeof(desc), 8);\n      amd::elf::Symbol* imageInit =\n        img->symtab()->addSymbol(ImageInitSection(), \"\", offset, 0, STT_AMDGPU_HSA_METADATA, STB_LOCAL);\n      image->elfSym()->section()->relocationSection()->addRelocation(R_AMDGPU_V1_INIT_IMAGE, imageInit, image->elfSym()->value() + destOffset, 0);\n    }\n\n    void AmdHsaCode::AddImageInitializer(\n      Symbol* image, uint64_t destOffset,\n      amdgpu_hsa_metadata_kind16_t kind,\n      amdgpu_hsa_image_geometry8_t geometry,\n      amdgpu_hsa_image_channel_order8_t channel_order, amdgpu_hsa_image_channel_type8_t channel_type,\n      uint64_t width, uint64_t height, uint64_t depth, uint64_t array)\n    {\n      amdgpu_hsa_image_descriptor_t desc;\n      desc.size = (uint16_t) sizeof(amdgpu_hsa_image_descriptor_t);\n      desc.kind = kind;\n      desc.geometry = geometry;\n      desc.channel_order = channel_order;\n      desc.channel_type = channel_type;\n      desc.width = width;\n      desc.height = height;\n      desc.depth = depth;\n      desc.array = array;\n      AddImageInitializer(image, destOffset, desc);\n    }\n\n\n    Section* AmdHsaCode::SamplerInitSection()\n    {\n      if (!samplerInit) {\n        samplerInit = img->addSection(\n          \".hsaimage_samplerinit\",\n          SHT_PROGBITS,\n          SHF_MERGE,\n          sizeof(amdgpu_hsa_sampler_descriptor_t));\n      }\n      return samplerInit;\n    }\n\n    void AmdHsaCode::AddSamplerInitializer(Symbol* sampler, uint64_t destOffset, const amdgpu_hsa_sampler_descriptor_t& desc)\n    {\n      uint64_t offset = SamplerInitSection()->addData(&desc, sizeof(desc), 8);\n      amd::elf::Symbol* samplerInit =\n        img->symtab()->addSymbol(SamplerInitSection(), \"\", offset, 0, STT_AMDGPU_HSA_METADATA, STB_LOCAL);\n      sampler->elfSym()->section()->relocationSection()->addRelocation(R_AMDGPU_V1_INIT_SAMPLER, samplerInit, sampler->elfSym()->value() + destOffset, 0);\n    }\n\n    void AmdHsaCode::AddSamplerInitializer(Symbol* sampler, uint64_t destOffset,\n        amdgpu_hsa_sampler_coord8_t coord,\n        amdgpu_hsa_sampler_filter8_t filter,\n        amdgpu_hsa_sampler_addressing8_t addressing)\n    {\n      amdgpu_hsa_sampler_descriptor_t desc;\n      desc.size = (uint16_t) sizeof(amdgpu_hsa_sampler_descriptor_t);\n      desc.kind = AMDGPU_HSA_METADATA_KIND_INIT_SAMP;\n      desc.coord = coord;\n      desc.filter = filter;\n      desc.addressing = addressing;\n      AddSamplerInitializer(sampler, destOffset, desc);\n    }\n\n    void AmdHsaCode::AddInitVarWithAddress(bool large, Symbol* dest, uint64_t destOffset, Symbol* addrOf, uint64_t addrAddend)\n    {\n      uint32_t rtype = large ? R_AMDGPU_V1_64 : R_AMDGPU_V1_32_LOW;\n      dest->elfSym()->section()->relocationSection()->addRelocation(rtype, addrOf->elfSym(), dest->elfSym()->value() + destOffset, addrAddend);\n    }\n\n    uint64_t AmdHsaCode::NextKernelCodeOffset() const\n    {\n      return HsaText()->nextDataOffset(256);\n    }\n\n    bool AmdHsaCode::AddKernelCode(KernelSymbol* sym, const void* code, size_t size)\n    {\n      assert(nullptr != sym);\n\n      uint64_t offset = HsaText()->addData(code, size, 256);\n      sym->setValue(offset);\n      sym->setSize(size);\n      return true;\n    }\n\n    Section* AmdHsaCode::AddEmptySection()\n    {\n      dataSections.push_back(nullptr); return nullptr;\n    }\n\n    Section* AmdHsaCode::AddCodeSection(Segment* segment)\n    {\n      if (nullptr == img) { return nullptr; }\n      Section *sec = img->addSection(\n        \".hsatext\",\n        SHT_PROGBITS,\n        SHF_ALLOC | SHF_EXECINSTR | SHF_WRITE | SHF_AMDGPU_HSA_CODE | SHF_AMDGPU_HSA_AGENT,\n        0,\n        segment);\n      dataSections.push_back(sec);\n      hsatext = sec;\n      return sec;\n    }\n\n    Section* AmdHsaCode::AddDataSection(const std::string &name,\n                                        uint32_t type,\n                                        uint64_t flags,\n                                        Segment* segment)\n    {\n      if (nullptr == img) { return nullptr; }\n      Section *sec = img->addSection(name, type, flags, 0, segment);\n      dataSections.push_back(sec);\n      return sec;\n    }\n\n    void AmdHsaCode::InitHsaSectionSegment(amdgpu_hsa_elf_section_t section, bool combineSegments)\n    {\n      InitHsaSegment(AmdHsaElfSectionSegment(section), combineSegments || !IsAmdHsaElfSectionROData(section));\n    }\n\n    Section* AmdHsaCode::HsaDataSection(amdgpu_hsa_elf_section_t sec, bool combineSegments)\n    {\n      if (!hsaSections[sec]) {\n        bool writable = combineSegments || !IsAmdHsaElfSectionROData(sec);\n        Segment* segment = HsaSegment(AmdHsaElfSectionSegment(sec), writable);\n        assert(segment); // Expected to be init the segment via InitHsaSegment.\n        Section* section;\n        switch (sec) {\n        case AMDGPU_HSA_RODATA_GLOBAL_PROGRAM:\n          section = AddDataSection(\".hsarodata_global_program\", SHT_PROGBITS, SHF_ALLOC | SHF_AMDGPU_HSA_GLOBAL, segment); break;\n        case AMDGPU_HSA_RODATA_GLOBAL_AGENT:\n          section = AddDataSection(\".hsarodata_global_agent\", SHT_PROGBITS, SHF_ALLOC | SHF_AMDGPU_HSA_GLOBAL | SHF_AMDGPU_HSA_AGENT, segment); break;\n        case AMDGPU_HSA_RODATA_READONLY_AGENT:\n          section = AddDataSection(\".hsarodata_readonly_agent\", SHT_PROGBITS, SHF_ALLOC | SHF_AMDGPU_HSA_READONLY | SHF_AMDGPU_HSA_AGENT, segment); break;\n        case AMDGPU_HSA_DATA_GLOBAL_PROGRAM:\n          section = AddDataSection(\".hsadata_global_program\", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_GLOBAL, segment); break;\n        case AMDGPU_HSA_DATA_GLOBAL_AGENT:\n          section = AddDataSection(\".hsadata_global_agent\", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_GLOBAL | SHF_AMDGPU_HSA_AGENT, segment); break;\n        case AMDGPU_HSA_DATA_READONLY_AGENT:\n          section = AddDataSection(\".hsadata_readonly_agent\", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_READONLY | SHF_AMDGPU_HSA_AGENT, segment); break;\n        case AMDGPU_HSA_BSS_GLOBAL_PROGRAM:\n          section = AddDataSection(\".hsabss_global_program\", SHT_NOBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_GLOBAL, segment); break;\n        case AMDGPU_HSA_BSS_GLOBAL_AGENT:\n          section = AddDataSection(\".hsabss_global_agent\", SHT_NOBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_GLOBAL | SHF_AMDGPU_HSA_AGENT, segment); break;\n        case AMDGPU_HSA_BSS_READONLY_AGENT:\n          section = AddDataSection(\".hsabss_readonly_agent\", SHT_NOBITS, SHF_ALLOC | SHF_WRITE | SHF_AMDGPU_HSA_READONLY | SHF_AMDGPU_HSA_AGENT, segment); break;\n        default:\n          assert(false); return 0;\n        }\n        hsaSections[sec] = section;\n      }\n      return hsaSections[sec];\n    }\n\n    void AmdHsaCode::InitHsaSegment(amdgpu_hsa_elf_segment_t segment, bool writable)\n    {\n      if (!hsaSegments[segment][writable]) {\n        uint32_t flags = PF_R;\n        if (writable) { flags |= PF_W; }\n        if (segment == AMDGPU_HSA_SEGMENT_CODE_AGENT) { flags |= PF_X; }\n        uint32_t type = PT_LOOS + segment;\n        assert(segment < AMDGPU_HSA_SEGMENT_LAST);\n        hsaSegments[segment][writable] = img->initSegment(type, flags);\n      }\n    }\n\n    bool AmdHsaCode::AddHsaSegments()\n    {\n      if (!img->addSegments()) { return ElfImageError(); }\n      return true;\n    }\n\n    Segment* AmdHsaCode::HsaSegment(amdgpu_hsa_elf_segment_t segment, bool writable)\n    {\n      return hsaSegments[segment][writable];\n    }\n\n    Symbol* AmdHsaCode::AddExecutableSymbol(const std::string &name,\n                                            unsigned char type,\n                                            unsigned char binding,\n                                            unsigned char other,\n                                            Section *section)\n    {\n      if (nullptr == img) { return nullptr; }\n      if (!section) { section = HsaText(); }\n      symbols.push_back(new KernelSymbol(img->symtab()->addSymbol(section, name, 0, 0, type, binding, other), nullptr));\n      return symbols.back();\n    }\n\n    Symbol* AmdHsaCode::AddVariableSymbol(const std::string &name,\n                                          unsigned char type,\n                                          unsigned char binding,\n                                          unsigned char other,\n                                          Section *section,\n                                          uint64_t value,\n                                          uint64_t size)\n    {\n      if (nullptr == img) { return nullptr; }\n      symbols.push_back(new VariableSymbol(img->symtab()->addSymbol(section, name, value, size, type, binding, other)));\n      return symbols.back();\n    }\n\n    void AmdHsaCode::AddSectionSymbols()\n    {\n      if (nullptr == img) { return; }\n      for (size_t i = 0; i < dataSections.size(); ++i) {\n        if (dataSections[i] && dataSections[i]->flags() & SHF_ALLOC) {\n          symbols.push_back(new VariableSymbol(img->symtab()->addSymbol(dataSections[i], \"__hsa_section\" + dataSections[i]->Name(), 0, 0, STT_SECTION, STB_LOCAL)));\n        }\n      }\n    }\n\n    Symbol* AmdHsaCode::GetSymbolByElfIndex(size_t index)\n    {\n      for (auto &s : symbols) {\n        if (s && index == s->Index()) {\n          return s;\n        }\n      }\n      return nullptr;\n    }\n\n    Symbol* AmdHsaCode::FindSymbol(const std::string &n)\n    {\n      for (auto &s : symbols) {\n        if (s && n == s->Name()) {\n          return s;\n        }\n      }\n      return nullptr;\n    }\n\n    void AmdHsaCode::AddData(amdgpu_hsa_elf_section_t s, const void* data, size_t size)\n    {\n//      getDataSection(s)->addData(data, size);\n    }\n\n    Section* AmdHsaCode::DebugInfo()\n    {\n      if (!debugInfo) {\n        debugInfo = img->addSection(\".debug_info\", SHT_PROGBITS);\n      }\n      return debugInfo;\n    }\n\n    Section* AmdHsaCode::DebugLine()\n    {\n      if (!debugLine) {\n        debugLine = img->addSection(\".debug_line\", SHT_PROGBITS);\n      }\n      return debugLine;\n    }\n\n    Section* AmdHsaCode::DebugAbbrev()\n    {\n      if (!debugAbbrev) {\n        debugAbbrev = img->addSection(\".debug_abbrev\", SHT_PROGBITS);\n      }\n      return debugAbbrev;\n    }\n\n    Section* AmdHsaCode::AddHsaHlDebug(const std::string& name, const void* data, size_t size)\n    {\n      Section* section = img->addSection(name, SHT_PROGBITS, SHF_OS_NONCONFORMING);\n      section->addData(data, size, 1);\n      return section;\n    }\n\n    bool AmdHsaCode::PrintToFile(const std::string& filename)\n    {\n      std::ofstream out(filename);\n      if (out.fail()) { return false; }\n      Print(out);\n      return out.fail();\n    }\n\n    void AmdHsaCode::Print(std::ostream& out)\n    {\n      PrintNotes(out);\n      out << std::endl;\n      PrintSegments(out);\n      out << std::endl;\n      PrintSections(out);\n      out << std::endl;\n      PrintSymbols(out);\n      out << std::endl;\n      PrintMachineCode(out);\n      out << std::endl;\n      out << \"AMD HSA Code Object End\" << std::endl;\n    }\n\n    void AmdHsaCode::PrintNotes(std::ostream& out)\n    {\n      {\n        uint32_t major_version, minor_version;\n        if (GetCodeObjectVersion(&major_version, &minor_version)) {\n          out << \"AMD HSA Code Object\" << std::endl\n              << \"  Version \" << major_version << \".\" << minor_version << std::endl;\n        }\n      }\n      {\n        uint32_t hsail_major, hsail_minor;\n        hsa_profile_t profile;\n        hsa_machine_model_t machine_model;\n        hsa_default_float_rounding_mode_t rounding_mode;\n        if (GetNoteHsail(&hsail_major, &hsail_minor, &profile, &machine_model, &rounding_mode)) {\n          out << \"HSAIL \" << std::endl\n              << \"  Version: \" << hsail_major << \".\" << hsail_minor << std::endl\n              << \"  Profile: \" << HsaProfileToString(profile)\n              << \"  Machine model: \" << HsaMachineModelToString(machine_model)\n              << \"  Default float rounding: \" << HsaFloatRoundingModeToString(rounding_mode) << std::endl;\n        }\n      }\n      {\n        std::string vendor_name, architecture_name;\n        uint32_t major_version, minor_version, stepping;\n        if (GetNoteIsa(vendor_name, architecture_name, &major_version, &minor_version, &stepping)) {\n          out << \"ISA\" << std::endl\n              << \"  Vendor \" << vendor_name\n              << \"  Arch \" << architecture_name\n              << \"  Version \" << major_version << \":\" << minor_version << \":\" << stepping << std::endl;\n        }\n      }\n      {\n        std::string producer_name, producer_options;\n        uint32_t major, minor;\n        if (GetNoteProducer(&major, &minor, producer_name)) {\n          out << \"Producer '\" << producer_name << \"' \" << \"Version \" << major << \":\" << minor << std::endl;\n        }\n      }\n      {\n        std::string producer_options;\n        if (GetNoteProducerOptions(producer_options)) {\n          out << \"Producer options\" << std::endl\n              << \"  '\" << producer_options << \"'\" << std::endl;\n        }\n      }\n    }\n\n    void AmdHsaCode::PrintSegments(std::ostream& out)\n    {\n      out << \"Segments (total \" << DataSegmentCount() << \"):\" << std::endl;\n      for (size_t i = 0; i < DataSegmentCount(); ++i) {\n        PrintSegment(out, DataSegment(i));\n      }\n    }\n\n    void AmdHsaCode::PrintSections(std::ostream& out)\n    {\n      out << \"Data Sections (total \" << DataSectionCount() << \"):\" << std::endl;\n      for (size_t i = 0; i < DataSectionCount(); ++i) {\n        PrintSection(out, DataSection(i));\n      }\n      out << std::endl;\n      out << \"Relocation Sections (total \" << RelocationSectionCount() << \"):\" << std::endl;\n      for (size_t i = 0; i < RelocationSectionCount(); ++i) {\n        PrintSection(out, GetRelocationSection(i));\n      }\n    }\n\n    void AmdHsaCode::PrintSymbols(std::ostream& out)\n    {\n      out << \"Symbols (total \" << SymbolCount() << \"):\" << std::endl;\n      for (size_t i = 0; i < SymbolCount(); ++i) {\n        PrintSymbol(out, GetSymbol(i));\n      }\n    }\n\n    void AmdHsaCode::PrintMachineCode(std::ostream& out)\n    {\n      if (HasHsaText()) {\n        out << std::dec;\n        for (size_t i = 0; i < SymbolCount(); ++i) {\n          Symbol* sym = GetSymbol(i);\n          if (sym->IsKernelSymbol() && sym->IsDefinition()) {\n            amd_kernel_code_t kernel_code;\n            HsaText()->getData(sym->SectionOffset(), &kernel_code, sizeof(amd_kernel_code_t));\n            out << \"AMD Kernel Code for \" << sym->Name() << \": \" << std::endl << std::dec;\n            PrintAmdKernelCode(out, &kernel_code);\n            out << std::endl;\n          }\n        }\n\n        std::vector<uint8_t> isa(HsaText()->size(), 0);\n        HsaText()->getData(0, isa.data(), HsaText()->size());\n\n        out << \"Disassembly:\" << std::endl;\n        PrintDisassembly(out, isa.data(), HsaText()->size(), 0);\n        out << std::endl << std::dec;\n      } else {\n        out << \"Machine code section is not present\" << std::endl << std::endl;\n      }\n    }\n\n    void AmdHsaCode::PrintSegment(std::ostream& out, Segment* segment)\n    {\n      out << \"  Segment (\" << segment->getSegmentIndex() << \")\" << std::endl;\n      out << \"    Type: \" << AmdPTLoadToString(segment->type())\n          << \" \"\n          << \"    Flags: \" << \"0x\" << std::hex << std::setw(8) << std::setfill('0') << segment->flags() << std::dec\n          << std::endl\n          << \"    Image Size: \" << segment->imageSize()\n          << \" \"\n          << \"    Memory Size: \" << segment->memSize()\n          << \" \"\n          << \"    Align: \" << segment->align()\n          << \" \"\n          << \"    VAddr: \" << segment->vaddr()\n          << std::endl;\n      out << std::dec;\n    }\n\n    void AmdHsaCode::PrintSection(std::ostream& out, Section* section)\n    {\n      out << \"  Section \" << section->Name() << \" (Index \" << section->getSectionIndex() << \")\" << std::endl;\n      out << \"    Type: \" << section->type()\n          << \" \"\n          << \"    Flags: \" << \"0x\" << std::hex << std::setw(8) << std::setfill('0') << section->flags() << std::dec\n          << std::endl\n          << \"    Size:  \" << section->size()\n          << \" \"\n          << \"    Address: \" << section->addr()\n          << \" \"\n          << \"    Align: \" << section->addralign()\n          << std::endl;\n      out << std::dec;\n\n      if (section->flags() & SHF_AMDGPU_HSA_CODE) {\n        // Printed separately.\n        return;\n      }\n\n      switch (section->type()) {\n      case SHT_NOBITS:\n        return;\n      case SHT_RELA:\n        PrintRelocationData(out, section->asRelocationSection());\n        return;\n      default:\n        PrintRawData(out, section);\n      }\n    }\n\n    void AmdHsaCode::PrintRawData(std::ostream& out, Section* section)\n    {\n      out << \"    Data:\" << std::endl;\n      unsigned char *sdata = (unsigned char*)alloca(section->size());\n      section->getData(0, sdata, section->size());\n      PrintRawData(out, sdata, section->size());\n    }\n\n    void AmdHsaCode::PrintRawData(std::ostream& out, const unsigned char *data, size_t size)\n    {\n      out << std::hex << std::setfill('0');\n      for (size_t i = 0; i < size; i += 16) {\n        out << \"      \" << std::setw(7) << i << \":\";\n\n        for (size_t j = 0; j < 16; j += 1) {\n          uint32_t value = i + j < size ? (uint32_t)data[i + j] : 0;\n          if (j % 2 == 0) { out << ' '; }\n          out << std::setw(2) << value;\n        }\n        out << \"  \";\n\n        for (size_t j = 0; i + j < size && j < 16; j += 1) {\n          char value = (char)data[i + j] >= 32 && (char)data[i + j] <= 126 ? (char)data[i + j] : '.';\n          out << value;\n        }\n        out << std::endl;\n      }\n      out << std::dec;\n    }\n\n    void AmdHsaCode::PrintRelocationData(std::ostream& out, RelocationSection* section)\n    {\n      if (section->targetSection()) {\n        out << \"    Relocation Entries for \" << section->targetSection()->Name() << \" Section (total \" << section->relocationCount() << \"):\" << std::endl;\n      } else {\n        // Dynamic relocations do not have a target section, they work with\n        // virtual addresses.\n        out << \"    Dynamic Relocation Entries (total \" << section->relocationCount() << \"):\" << std::endl;\n      }\n      for (size_t i = 0; i < section->relocationCount(); ++i) {\n        out << \"      Relocation (Index \" << i << \"):\" << std::endl;\n        out << \"        Type: \" << section->relocation(i)->type() << std::endl;\n        out << \"        Symbol: \" << section->relocation(i)->symbol()->name() << std::endl;\n        out << \"        Offset: \" << section->relocation(i)->offset() << \" Addend: \" << section->relocation(i)->addend() << std::endl;\n      }\n      out << std::dec;\n    }\n\n    void AmdHsaCode::PrintSymbol(std::ostream& out, Symbol* sym)\n    {\n      out << \"  Symbol \" << sym->Name() << \" (Index \" << sym->Index() << \"):\" << std::endl;\n      if (sym->IsKernelSymbol() || sym->IsVariableSymbol()) {\n        out << \"    Section: \" << sym->GetSection()->Name() << \" \";\n        out << \"    Section Offset: \" << sym->SectionOffset() << std::endl;\n        out << \"    VAddr: \" << sym->VAddr() << \" \";\n        out << \"    Size: \" << sym->Size() << \" \";\n        out << \"    Alignment: \" << sym->Alignment() << std::endl;\n        out << \"    Kind: \" << HsaSymbolKindToString(sym->Kind()) << \" \";\n        out << \"    Linkage: \" << HsaSymbolLinkageToString(sym->Linkage()) << \" \";\n        out << \"    Definition: \" << (sym->IsDefinition() ? \"TRUE\" : \"FALSE\") << std::endl;\n      }\n      if (sym->IsVariableSymbol()) {\n        out << \"    Allocation: \" << HsaVariableAllocationToString(sym->Allocation()) << \" \";\n        out << \"    Segment: \" << HsaVariableSegmentToString(sym->Segment()) << \" \";\n        out << \"    Constant: \" << (sym->IsConst() ? \"TRUE\" : \"FALSE\") << std::endl;\n      }\n      out << std::dec;\n    }\n\n    void AmdHsaCode::PrintMachineCode(std::ostream& out, KernelSymbol* sym)\n    {\n      assert(HsaText());\n      amd_kernel_code_t kernel_code;\n      HsaText()->getData(sym->SectionOffset(), &kernel_code, sizeof(amd_kernel_code_t));\n\n      out << \"AMD Kernel Code for \" << sym->Name() << \": \" << std::endl << std::dec;\n      PrintAmdKernelCode(out, &kernel_code);\n      out << std::endl;\n\n      std::vector<uint8_t> isa(HsaText()->size(), 0);\n      HsaText()->getData(0, isa.data(), HsaText()->size());\n      uint64_t isa_offset = sym->SectionOffset() + kernel_code.kernel_code_entry_byte_offset;\n\n      out << \"Disassembly for \" << sym->Name() << \": \" << std::endl;\n      PrintDisassembly(out, isa.data(), HsaText()->size(), isa_offset);\n      out << std::endl << std::dec;\n    }\n\n    void AmdHsaCode::PrintDisassembly(std::ostream& out, const unsigned char *isa, size_t size, uint32_t isa_offset)\n    {\n    #ifdef SP3_STATIC_LIB\n      // Default asic is ci.\n      std::string asic = \"CI\";\n      std::string vendor_name, architecture_name;\n      uint32_t major_version, minor_version, stepping;\n      if (GetNoteIsa(vendor_name, architecture_name, &major_version, &minor_version, &stepping)) {\n        if (major_version == 7) {\n          asic = \"CI\";\n        } else if (major_version == 8) {\n          asic = \"VI\";\n        } else if (major_version == 9) {\n          asic = \"GFX9\";\n        } else if (major_version == 10) {\n          asic = \"GFX10\";\n        } else {\n          assert(!\"unknown compute capability\");\n        }\n      }\n\n      struct sp3_context *dis_state = sp3_new();\n      sp3_setasic(dis_state, asic.c_str());\n\n      sp3_vma *dis_vma = sp3_vm_new_ptr(0, size / 4, (const uint32_t*)isa);\n\n      std::vector<uint32_t> comments(HsaText()->size() / 4, 0);\n      for (size_t i = 0; i < SymbolCount(); ++i) {\n        Symbol* sym = GetSymbol(i);\n        if (sym->IsKernelSymbol() && sym->IsDefinition()) {\n          comments[sym->SectionOffset() / 4] = COMMENT_AMD_KERNEL_CODE_T_BEGIN;\n          comments[(sym->SectionOffset() + 252) / 4] = COMMENT_AMD_KERNEL_CODE_T_END;\n          amd_kernel_code_t kernel_code;\n          HsaText()->getData(sym->SectionOffset(), &kernel_code, sizeof(amd_kernel_code_t));\n          comments[(kernel_code.kernel_code_entry_byte_offset + sym->SectionOffset()) / 4] = COMMENT_KERNEL_ISA_BEGIN;\n        }\n      }\n      sp3_vma *comment_vma = sp3_vm_new_ptr(0, comments.size(), (const uint32_t*)comments.data());\n      sp3_setcomments(dis_state, comment_vma, CommentTopCallBack, CommentRightCallBack, this);\n\n      // When isa_offset == 0 disassembly full hsatext section.\n      // Otherwise disassembly only from this offset till endpgm instruction.\n      char *text = sp3_disasm(\n        dis_state,\n        dis_vma,\n        isa_offset / 4,\n        nullptr,\n        SP3_SHTYPE_CS,\n        nullptr,\n        (unsigned)(size / 4),\n        isa_offset == 0 ? SP3DIS_FORCEVALID | SP3DIS_COMMENTS : SP3DIS_COMMENTS);\n\n      enum class IsaState {\n        UNKNOWN,\n        AMD_KERNEL_CODE_T_BEGIN,\n        AMD_KERNEL_CODE_T,\n        AMD_KERNEL_CODE_T_END,\n        ISA_BEGIN,\n        ISA,\n        PADDING,\n      };\n\n      std::string line;\n      char *text_ptr = text;\n      IsaState state = IsaState::UNKNOWN;\n\n      uint32_t offset = 0;\n      uint32_t padding_end = 0;\n      std::string padding;\n\n      while (text_ptr && text_ptr[0] != '\\0') {\n        line.clear();\n        while (text_ptr[0] != '\\0' && text_ptr[0] != '\\n') {\n          line.push_back(text_ptr[0]);\n          ++text_ptr;\n        }\n        ltrim(line);\n        if (text_ptr[0] == '\\n') {\n          ++text_ptr;\n        }\n        switch (state) {\n        case IsaState::UNKNOWN:\n          assert(line != \"// amd_kernel_code_t end\");\n          padding.clear();\n          if (line == \"// amd_kernel_code_t begin\") {\n            state = IsaState::AMD_KERNEL_CODE_T_BEGIN;\n          } else if (line == \"// isa begin\") {\n            state = IsaState::ISA_BEGIN;\n          } else if (line == \"end\") {\n            out << line << std::endl;\n          } else if (line.find(\"v_cndmask_b32  v0, s0, v0, vcc\") != std::string::npos) {\n            padding += \"  \" + line + \"\\n\";\n            offset = ParseInstructionOffset(line);\n            padding_end = ParseInstructionOffset(line);\n            state = IsaState::PADDING;\n          } else if (line != \"shader (null)\") {\n            out << \"  \" << line << std::endl;\n          }\n          break;\n\n        case IsaState::AMD_KERNEL_CODE_T_BEGIN:\n          assert(line != \"// amd_kernel_code_t begin\");\n          assert(line != \"// amd_kernel_code_t end\");\n          assert(line != \"// isa begin\");\n          assert(line != \"end\");\n          padding.clear();\n          offset = ParseInstructionOffset(line);\n          state = IsaState::AMD_KERNEL_CODE_T;\n          break;\n\n        case IsaState::AMD_KERNEL_CODE_T:\n          assert(line != \"// amd_kernel_code_t begin\");\n          assert(line != \"// isa begin\");\n          assert(line != \"end\");\n          assert(padding.empty());\n          if (line == \"// amd_kernel_code_t end\") {\n            state = IsaState::AMD_KERNEL_CODE_T_END;\n          }\n          break;\n\n        case IsaState::AMD_KERNEL_CODE_T_END:\n          assert(line != \"// amd_kernel_code_t begin\");\n          assert(line != \"// amd_kernel_code_t end\");\n          assert(line != \"// isa begin\");\n          assert(line != \"end\");\n          assert(padding.empty());\n          for (size_t i = 0; i < SymbolCount(); ++i) {\n            Symbol* sym = GetSymbol(i);\n            if (sym->IsKernelSymbol() && sym->IsDefinition() && sym->SectionOffset() == offset) {\n              std::ostream::fmtflags flags = out.flags();\n              char fill = out.fill();\n              out << \"  //\" << std::endl;\n              out << \"  // amd_kernel_code_t for \" << sym->Name()\n                  << \" (\" << std::hex << std::setw(12) << std::setfill('0') << std::right << offset\n                  << \" - \" << std::setw(12) << (offset + 256) << ')' << std::endl;\n              out << \"  //\" << std::endl;\n              out << std::setfill(fill);\n              out.flags(flags);\n              break;\n            }\n          }\n          state = IsaState::UNKNOWN;\n          break;\n\n        case IsaState::ISA_BEGIN:\n          assert(line != \"// amd_kernel_code_t begin\");\n          assert(line != \"// amd_kernel_code_t end\");\n          assert(line != \"// isa begin\");\n          padding.clear();\n          offset = ParseInstructionOffset(line);\n          for (size_t i = 0; i < SymbolCount(); ++i) {\n            Symbol* sym = GetSymbol(i);\n            if (sym->IsKernelSymbol() && sym->IsDefinition()) {\n              amd_kernel_code_t kernel_code;\n              HsaText()->getData(sym->SectionOffset(), &kernel_code, sizeof(amd_kernel_code_t));\n              if ((sym->SectionOffset() + kernel_code.kernel_code_entry_byte_offset) == offset) {\n                out << \"  //\" << std::endl;\n                out << \"  // \" << sym->Name() << ':' << std::endl;\n                out << \"  //\" << std::endl;\n                break;\n              }\n            }\n          }\n          if (line == \"end\") {\n            out << line << std::endl;\n            state = IsaState::UNKNOWN;\n          } else {\n            out << \"  \" << line << std::endl;\n            state = IsaState::ISA;\n          }\n          break;\n\n        case IsaState::ISA:\n          assert(line != \"// amd_kernel_code_t end\");\n          if (!padding.empty()) {\n            out << padding;\n            out.flush();\n            padding.clear();\n          }\n          if (line == \"// amd_kernel_code_t begin\") {\n            state = IsaState::AMD_KERNEL_CODE_T_BEGIN;\n          } else if (line == \"// isa begin\") {\n            state = IsaState::ISA_BEGIN;\n          } else if (line == \"end\") {\n            out << line << std::endl;\n            state = IsaState::UNKNOWN;\n          } else if (line.find(\"v_cndmask_b32  v0, s0, v0, vcc\") != std::string::npos) {\n            padding += \"  \" + line + \"\\n\";\n            offset = ParseInstructionOffset(line);\n            padding_end = offset;\n            state = IsaState::PADDING;\n          } else {\n            out << \"  \" << line << std::endl;\n          }\n          break;\n\n        case IsaState::PADDING:\n          assert(line != \"// amd_kernel_code_t end\");\n          if (line.find(\"v_cndmask_b32  v0, s0, v0, vcc\") != std::string::npos) {\n            padding += \"  \" + line + \"\\n\";\n            padding_end = ParseInstructionOffset(line);\n          } else if (line == \"// amd_kernel_code_t begin\" || line == \"// isa begin\" || line == \"end\") {\n              padding.clear();\n              std::ostream::fmtflags flags = out.flags();\n              char fill = out.fill();\n              out << \"  //\" << std::endl;\n              out << \"  // padding (\"\n                  << std::hex << std::setw(12) << std::setfill('0') << std::right << offset\n                  << \" - \" << std::setw(12) << (padding_end + 4) << ')' << std::endl;\n              out << \"  //\" << std::endl;\n              out << std::setfill(fill);\n              out.flags(flags);\n              if (line == \"// amd_kernel_code_t begin\") {\n                state = IsaState::AMD_KERNEL_CODE_T_BEGIN;\n              } else if (line == \"// isa begin\") {\n                state = IsaState::ISA_BEGIN;\n              } else if (line == \"end\") {\n                out << line << std::endl;\n                state = IsaState::UNKNOWN;\n              }\n          } else {\n            padding += \"  \" + line + \"\\n\";\n            state = IsaState::ISA;\n          }\n          break;\n\n        default:\n          assert(false);\n          break;\n        }\n      }\n\n      sp3_free(text);\n      sp3_close(dis_state);\n      sp3_vm_free(dis_vma);\n      sp3_vm_free(comment_vma);\n    #else\n      PrintRawData(out, isa, size);\n    #endif // SP3_STATIC_LIB\n      out << std::dec;\n    }\n\n    std::string AmdHsaCode::MangleSymbolName(const std::string& module_name, const std::string& symbol_name)\n    {\n      if (module_name.empty()) {\n        return symbol_name;\n      } else {\n        return module_name + \"::\" + symbol_name;\n      }\n    }\n\n    bool AmdHsaCode::ElfImageError()\n    {\n      out << img->output();\n      return false;\n    }\n\n      AmdHsaCode* AmdHsaCodeManager::FromHandle(hsa_code_object_t c)\n      {\n        CodeMap::iterator i = codeMap.find(c.handle);\n        if (i == codeMap.end()) {\n          AmdHsaCode* code = new AmdHsaCode();\n          const void* buffer = reinterpret_cast<const void*>(c.handle);\n          if (!code->InitAsBuffer(buffer, 0)) {\n            delete code;\n            return 0;\n          }\n          codeMap[c.handle] = code;\n          return code;\n        }\n        return i->second;\n      }\n\n      bool AmdHsaCodeManager::Destroy(hsa_code_object_t c)\n      {\n        CodeMap::iterator i = codeMap.find(c.handle);\n        if (i == codeMap.end()) {\n          // Currently, we do not always create map entry for every code object buffer.\n          return true;\n        }\n        delete i->second;\n        codeMap.erase(i);\n        return true;\n      }\n\n    bool AmdHsaCode::PullElfV2()\n    {\n      for (size_t i = 0; i < img->segmentCount(); ++i) {\n        Segment* s = img->segment(i);\n        if (s->type() == PT_LOAD) {\n          dataSegments.push_back(s);\n        }\n      }\n      for (size_t i = 0; i < img->sectionCount(); ++i) {\n        Section* sec = img->section(i);\n        if (!sec) { continue; }\n        if ((sec->type() == SHT_PROGBITS || sec->type() == SHT_NOBITS) &&\n            !(sec->flags() & SHF_EXECINSTR)) {\n          dataSections.push_back(sec);\n        } else if (sec->type() == SHT_RELA) {\n          relocationSections.push_back(sec->asRelocationSection());\n        }\n        if (sec->Name() == \".text\") {\n          hsatext = sec;\n        }\n      }\n      for (size_t i = 0; i < img->getSymbolTable()->symbolCount(); ++i) {\n        amd::elf::Symbol* elfsym = img->getSymbolTable()->symbol(i);\n        Symbol* sym = 0;\n        switch (elfsym->type()) {\n        case STT_AMDGPU_HSA_KERNEL: {\n          amd::elf::Section* sec = elfsym->section();\n          amd_kernel_code_t akc;\n          if (!sec) {\n            out << \"Failed to find section for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          if (!(sec->flags() & (SHF_ALLOC | SHF_EXECINSTR))) {\n            out << \"Invalid code section for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          if (!sec->getData(elfsym->value() - sec->addr(), &akc, sizeof(amd_kernel_code_t))) {\n            out << \"Failed to get AMD Kernel Code for symbol \" << elfsym->name() << std::endl;\n            return false;\n          }\n          sym = new KernelSymbolV2(elfsym, &akc);\n          break;\n        }\n        case STT_OBJECT:\n        case STT_COMMON:\n          sym = new VariableSymbolV2(elfsym);\n          break;\n        default:\n          break; // Skip unknown symbols.\n        }\n        if (sym) { symbols.push_back(sym); }\n      }\n\n      return true;\n    }\n\n    KernelSymbolV2::KernelSymbolV2(amd::elf::Symbol* elfsym_, const amd_kernel_code_t* akc) :\n      KernelSymbol(elfsym_, akc) { }\n}   // namespace code\n}   // namespace hsa\n}   // namespace amd\n}   // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_hsa_code_util.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"amd_hsa_code_util.hpp\"\n#include <libelf.h>\n#include <fstream>\n#include <cstring>\n#include <iomanip>\n#include <cassert>\n#include <algorithm>\n#include <sstream>\n#ifdef _WIN32\n#include <Windows.h>\n#include <io.h>\n#include <process.h>\n#else // _WIN32\n#include <sys/types.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#endif // _WIN32\n#include \"inc/Brig.h\"\n\nnamespace {\nauto eq = \" = \";\n\nstd::ostream& attr1(std::ostream& out)\n{\n  out << \"  \" << std::left << std::setw(60) << std::setfill(' ');\n  return out;\n}\n\nstd::ostream& attr2(std::ostream& out)\n{\n  out << \"    \" << std::left << std::setw(58) << std::setfill(' ');\n  return out;\n}\n} // namespace anonymous\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace common {\n\nbool IsAccessibleMemoryAddress(uint64_t address)\n{\n  if (0 == address) {\n    return false;\n  }\n#if defined(_WIN32) || defined(_WIN64)\n    MEMORY_BASIC_INFORMATION memory_info;\n    if (!VirtualQuery(reinterpret_cast<void*>(address), &memory_info, sizeof(memory_info))) {\n      return false;\n    }\n    int32_t is_accessible = ((memory_info.Protect & PAGE_READONLY) ||\n                             (memory_info.Protect & PAGE_READWRITE) ||\n                             (memory_info.Protect & PAGE_WRITECOPY) ||\n                             (memory_info.Protect & PAGE_EXECUTE_READ) ||\n                             (memory_info.Protect & PAGE_EXECUTE_READWRITE) ||\n                             (memory_info.Protect & PAGE_EXECUTE_WRITECOPY));\n    if (memory_info.Protect & PAGE_GUARD) {\n      is_accessible = 0;\n    }\n    if (memory_info.Protect & PAGE_NOACCESS) {\n      is_accessible = 0;\n    }\n    return is_accessible > 0;\n#else\n  int32_t random_fd = 0;\n  ssize_t bytes_written = 0;\n  if (-1 == (random_fd = open(\"/dev/random\", O_WRONLY))) {\n    return true;  // Skip check if /dev/random is not available.\n  }\n  bytes_written = write(random_fd, (void*)address, 1);\n  if (-1 == close(random_fd)) {\n    return false;\n  }\n  return bytes_written == 1;\n#endif // _WIN32 || _WIN64\n}\n\n}   //  namespace common\n\nstd::string HsaSymbolKindToString(hsa_symbol_kind_t kind)\n{\n  switch (kind) {\n  case HSA_SYMBOL_KIND_VARIABLE: return \"VARIABLE\";\n  case HSA_SYMBOL_KIND_INDIRECT_FUNCTION: return \"INDIRECT_FUNCTION\";\n  case HSA_SYMBOL_KIND_KERNEL: return \"KERNEL\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaSymbolLinkageToString(hsa_symbol_linkage_t linkage)\n{\n  switch (linkage) {\n  case HSA_SYMBOL_LINKAGE_MODULE: return \"MODULE\";\n  case HSA_SYMBOL_LINKAGE_PROGRAM: return \"PROGRAM\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaVariableAllocationToString(hsa_variable_allocation_t allocation)\n{\n  switch (allocation) {\n  case HSA_VARIABLE_ALLOCATION_AGENT: return \"AGENT\";\n  case HSA_VARIABLE_ALLOCATION_PROGRAM: return \"PROGRAM\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaVariableSegmentToString(hsa_variable_segment_t segment)\n{\n  switch (segment) {\n  case HSA_VARIABLE_SEGMENT_GLOBAL: return \"GLOBAL\";\n  case HSA_VARIABLE_SEGMENT_READONLY: return \"READONLY\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaProfileToString(hsa_profile_t profile)\n{\n  switch (profile) {\n  case HSA_PROFILE_BASE: return \"BASE\";\n  case HSA_PROFILE_FULL: return \"FULL\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaMachineModelToString(hsa_machine_model_t model)\n{\n  switch (model) {\n  case HSA_MACHINE_MODEL_SMALL: return \"SMALL\";\n  case HSA_MACHINE_MODEL_LARGE: return \"LARGE\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string HsaFloatRoundingModeToString(hsa_default_float_rounding_mode_t mode)\n{\n  switch (mode) {\n  case HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT: return \"DEFAULT\";\n  case HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO: return \"ZERO\";\n  case HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR: return \"NEAR\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdMachineKindToString(amd_machine_kind16_t machine)\n{\n  switch (machine) {\n  case AMD_MACHINE_KIND_UNDEFINED: return \"UNDEFINED\";\n  case AMD_MACHINE_KIND_AMDGPU: return \"AMDGPU\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdFloatRoundModeToString(amd_float_round_mode_t round_mode)\n{\n  switch (round_mode) {\n  case AMD_FLOAT_ROUND_MODE_NEAREST_EVEN: return \"NEAREST_EVEN\";\n  case AMD_FLOAT_ROUND_MODE_PLUS_INFINITY: return \"PLUS_INFINITY\";\n  case AMD_FLOAT_ROUND_MODE_MINUS_INFINITY: return \"MINUS_INFINITY\";\n  case AMD_FLOAT_ROUND_MODE_ZERO: return \"ZERO\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdFloatDenormModeToString(amd_float_denorm_mode_t denorm_mode)\n{\n  switch (denorm_mode) {\n  case AMD_FLOAT_DENORM_MODE_FLUSH_SOURCE_OUTPUT: return \"FLUSH_SOURCE_OUTPUT\";\n  case AMD_FLOAT_DENORM_MODE_FLUSH_OUTPUT: return \"FLUSH_OUTPUT\";\n  case AMD_FLOAT_DENORM_MODE_FLUSH_SOURCE: return \"FLUSH_SOURCE\";\n  case AMD_FLOAT_DENORM_MODE_NO_FLUSH: return \"FLUSH_NONE\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdSystemVgprWorkitemIdToString(amd_system_vgpr_workitem_id_t system_vgpr_workitem_id)\n{\n  switch (system_vgpr_workitem_id) {\n  case AMD_SYSTEM_VGPR_WORKITEM_ID_X: return \"X\";\n  case AMD_SYSTEM_VGPR_WORKITEM_ID_X_Y: return \"X, Y\";\n  case AMD_SYSTEM_VGPR_WORKITEM_ID_X_Y_Z: return \"X, Y, Z\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdElementByteSizeToString(amd_element_byte_size_t element_byte_size)\n{\n  switch (element_byte_size) {\n  case AMD_ELEMENT_BYTE_SIZE_2: return \"WORD (2 bytes)\";\n  case AMD_ELEMENT_BYTE_SIZE_4: return \"DWORD (4 bytes)\";\n  case AMD_ELEMENT_BYTE_SIZE_8: return \"QWORD (8 bytes)\";\n  case AMD_ELEMENT_BYTE_SIZE_16: return \"16 bytes\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdExceptionKindToString(amd_exception_kind16_t exceptions)\n{\n  std::string e;\n  if (exceptions & AMD_EXCEPTION_KIND_INVALID_OPERATION) {\n    e += \", INVALID_OPERATON\";\n    exceptions &= ~AMD_EXCEPTION_KIND_INVALID_OPERATION;\n  }\n  if (exceptions & AMD_EXCEPTION_KIND_DIVISION_BY_ZERO) {\n    e += \", DIVISION_BY_ZERO\";\n    exceptions &= ~AMD_EXCEPTION_KIND_DIVISION_BY_ZERO;\n  }\n  if (exceptions & AMD_EXCEPTION_KIND_OVERFLOW) {\n    e += \", OVERFLOW\";\n    exceptions &= ~AMD_EXCEPTION_KIND_OVERFLOW;\n  }\n  if (exceptions & AMD_EXCEPTION_KIND_UNDERFLOW) {\n    e += \", UNDERFLOW\";\n    exceptions &= ~AMD_EXCEPTION_KIND_UNDERFLOW;\n  }\n  if (exceptions & AMD_EXCEPTION_KIND_INEXACT) {\n    e += \", INEXACT\";\n    exceptions &= ~AMD_EXCEPTION_KIND_INEXACT;\n  }\n  if (exceptions) {\n    e += \", UNKNOWN\";\n  }\n  if (!e.empty()) {\n    e = \"[\" + e.erase(0, 2) + \"]\";\n  }\n  return e;\n}\n\nstd::string AmdPowerTwoToString(amd_powertwo8_t p)\n{\n  return std::to_string(1 << (unsigned) p);\n}\n\namdgpu_hsa_elf_segment_t AmdHsaElfSectionSegment(amdgpu_hsa_elf_section_t sec)\n{\n  switch (sec) {\n  case AMDGPU_HSA_RODATA_GLOBAL_PROGRAM:\n  case AMDGPU_HSA_DATA_GLOBAL_PROGRAM:\n  case AMDGPU_HSA_BSS_GLOBAL_PROGRAM:\n    return AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM;\n  case AMDGPU_HSA_RODATA_GLOBAL_AGENT:\n  case AMDGPU_HSA_DATA_GLOBAL_AGENT:\n  case AMDGPU_HSA_BSS_GLOBAL_AGENT:\n    return AMDGPU_HSA_SEGMENT_GLOBAL_AGENT;\n  case AMDGPU_HSA_RODATA_READONLY_AGENT:\n  case AMDGPU_HSA_DATA_READONLY_AGENT:\n  case AMDGPU_HSA_BSS_READONLY_AGENT:\n    return AMDGPU_HSA_SEGMENT_READONLY_AGENT;\n  default:\n    assert(false); return AMDGPU_HSA_SEGMENT_LAST;\n  }\n}\n\nbool IsAmdHsaElfSectionROData(amdgpu_hsa_elf_section_t sec)\n{\n  switch (sec) {\n  case AMDGPU_HSA_RODATA_GLOBAL_PROGRAM:\n  case AMDGPU_HSA_RODATA_GLOBAL_AGENT:\n  case AMDGPU_HSA_RODATA_READONLY_AGENT:\n  default:\n    return false;\n  }\n}\n\nstd::string AmdHsaElfSegmentToString(amdgpu_hsa_elf_segment_t seg)\n{\n  switch (seg) {\n  case AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM: return \"GLOBAL_PROGRAM\";\n  case AMDGPU_HSA_SEGMENT_GLOBAL_AGENT: return \"GLOBAL_AGENT\";\n  case AMDGPU_HSA_SEGMENT_READONLY_AGENT: return \"READONLY_AGENT\";\n  case AMDGPU_HSA_SEGMENT_CODE_AGENT: return \"CODE_AGENT\";\n  default: return \"UNKNOWN\";\n  }\n}\n\nstd::string AmdPTLoadToString(uint64_t type)\n{\n  if (PT_LOOS <= type && type < PT_LOOS + AMDGPU_HSA_SEGMENT_LAST) {\n    return AmdHsaElfSegmentToString((amdgpu_hsa_elf_segment_t) (type - PT_LOOS));\n  } else {\n    return \"UNKNOWN (\" + std::to_string(type) + \")\";\n  }\n}\n\nvoid PrintAmdKernelCode(std::ostream& out, const amd_kernel_code_t *akc)\n{\n  uint32_t is_debug_enabled = AMD_HSA_BITS_GET(akc->kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_DEBUG_ENABLED);\n\n  out << attr1 << \"amd_kernel_code_version_major\" << eq\n      << akc->amd_kernel_code_version_major\n      << std::endl;\n  out << attr1 << \"amd_kernel_code_version_minor\" << eq\n      << akc->amd_kernel_code_version_minor\n      << std::endl;\n  out << attr1 << \"amd_machine_kind\" << eq\n      << AmdMachineKindToString(akc->amd_machine_kind)\n      << std::endl;\n  out << attr1 << \"amd_machine_version_major\" << eq\n      << (uint32_t)akc->amd_machine_version_major\n      << std::endl;\n  out << attr1 << \"amd_machine_version_minor\" << eq\n      << (uint32_t)akc->amd_machine_version_minor\n      << std::endl;\n  out << attr1 << \"amd_machine_version_stepping\" << eq\n      << (uint32_t)akc->amd_machine_version_stepping\n      << std::endl;\n  out << attr1 << \"kernel_code_entry_byte_offset\" << eq\n      << akc->kernel_code_entry_byte_offset\n      << std::endl;\n  if (akc->kernel_code_prefetch_byte_offset) {\n    out << attr1 << \"kernel_code_prefetch_byte_offset\" << eq\n        << akc->kernel_code_prefetch_byte_offset\n        << std::endl;\n  }\n  if (akc->kernel_code_prefetch_byte_size) {\n    out << attr1 << \"kernel_code_prefetch_byte_size\" << eq\n        << akc->kernel_code_prefetch_byte_size\n        << std::endl;\n  }\n  out << attr1 << \"max_scratch_backing_memory_byte_size\" << eq\n      << akc->max_scratch_backing_memory_byte_size\n      << std::endl;\n  PrintAmdComputePgmRsrcOne(out, akc->compute_pgm_rsrc1);\n  PrintAmdComputePgmRsrcTwo(out, akc->compute_pgm_rsrc2);\n  PrintAmdKernelCodeProperties(out, akc->kernel_code_properties);\n  if (akc->workitem_private_segment_byte_size) {\n    out << attr1 << \"workitem_private_segment_byte_size\" << eq\n        << akc->workitem_private_segment_byte_size\n        << std::endl;\n  }\n  if (akc->workgroup_group_segment_byte_size) {\n    out << attr1 << \"workgroup_group_segment_byte_size\" << eq\n        << akc->workgroup_group_segment_byte_size\n        << std::endl;\n  }\n  if (akc->gds_segment_byte_size) {\n    out << attr1 << \"gds_segment_byte_size\" << eq\n        << akc->gds_segment_byte_size\n        << std::endl;\n  }\n  if (akc->kernarg_segment_byte_size) {\n    out << attr1 << \"kernarg_segment_byte_size\" << eq\n        << akc->kernarg_segment_byte_size\n        << std::endl;\n  }\n  if (akc->workgroup_fbarrier_count) {\n    out << attr1 << \"workgroup_fbarrier_count\" << eq\n        << akc->workgroup_fbarrier_count\n        << std::endl;\n  }\n  out << attr1 << \"wavefront_sgpr_count\" << eq\n      << (uint32_t)akc->wavefront_sgpr_count\n      << std::endl;\n  out << attr1 << \"workitem_vgpr_count\" << eq\n      << (uint32_t)akc->workitem_vgpr_count\n      << std::endl;\n  if (akc->reserved_vgpr_count > 0) {\n    out << attr1 << \"reserved_vgpr_first\" << eq\n        << (uint32_t)akc->reserved_vgpr_first\n        << std::endl;\n    out << attr1 << \"reserved_vgpr_count\" << eq\n        << (uint32_t)akc->reserved_vgpr_count\n        << std::endl;\n  }\n  if (akc->reserved_sgpr_count > 0) {\n    out << attr1 << \"reserved_sgpr_first\" << eq\n        << (uint32_t)akc->reserved_sgpr_first\n        << std::endl;\n    out << attr1 << \"reserved_sgpr_count\" << eq\n        << (uint32_t)akc->reserved_sgpr_count\n        << std::endl;\n  }\n  if (is_debug_enabled && (akc->debug_wavefront_private_segment_offset_sgpr != uint16_t(-1))) {\n    out << attr1 << \"debug_wavefront_private_segment_offset_sgpr\" << eq\n        << (uint32_t)akc->debug_wavefront_private_segment_offset_sgpr\n        << std::endl;\n  }\n  if (is_debug_enabled && (akc->debug_private_segment_buffer_sgpr != uint16_t(-1))) {\n    out << attr1 << \"debug_private_segment_buffer_sgpr\" << eq\n        << (uint32_t)akc->debug_private_segment_buffer_sgpr\n        << \":\"\n        << (uint32_t)(akc->debug_private_segment_buffer_sgpr + 3)\n        << std::endl;\n  }\n  if (akc->kernarg_segment_alignment) {\n    out << attr1 << \"kernarg_segment_alignment\" << eq\n        << AmdPowerTwoToString(akc->kernarg_segment_alignment)\n        << \" (\" << (uint32_t) akc->kernarg_segment_alignment << \")\"\n        << std::endl;\n  }\n  if (akc->group_segment_alignment) {\n    out << attr1 << \"group_segment_alignment\" << eq\n        << AmdPowerTwoToString(akc->group_segment_alignment)\n        << \" (\" << (uint32_t) akc->group_segment_alignment << \")\"\n        << std::endl;\n  }\n  if (akc->private_segment_alignment) {\n    out << attr1 << \"private_segment_alignment\" << eq\n        << AmdPowerTwoToString(akc->private_segment_alignment)\n        << \" (\" << (uint32_t) akc->private_segment_alignment << \")\"\n        << std::endl;\n  }\n  out << attr1 << \"wavefront_size\" << eq\n      << AmdPowerTwoToString(akc->wavefront_size)\n      << \" (\" << (uint32_t) akc->wavefront_size << \")\"\n      << std::endl;\n  PrintAmdControlDirectives(out, akc->control_directives);\n}\n\nvoid PrintAmdComputePgmRsrcOne(std::ostream& out, amd_compute_pgm_rsrc_one32_t compute_pgm_rsrc1)\n{\n  out << \"  COMPUTE_PGM_RSRC1 (0x\" << std::hex << std::setw(8) << std::setfill('0') << compute_pgm_rsrc1 << \"):\" << std::endl;\n  out << std::dec;\n\n  uint32_t granulated_workitem_vgpr_count = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WORKITEM_VGPR_COUNT);\n  out << attr2 << \"granulated_workitem_vgpr_count\" << eq\n      << granulated_workitem_vgpr_count\n      << std::endl;\n  uint32_t granulated_wavefront_sgpr_count = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_GRANULATED_WAVEFRONT_SGPR_COUNT);\n  out << attr2 << \"granulated_wavefront_sgpr_count\" << eq\n      << granulated_wavefront_sgpr_count\n      << std::endl;\n  uint32_t priority = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_PRIORITY);\n  out << attr2 << \"priority\" << eq\n      << priority\n      << std::endl;\n  uint32_t float_round_mode_32 = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_ROUND_MODE_32);\n  out << attr2 << \"float_round_mode_32\" << eq\n      << AmdFloatRoundModeToString((amd_float_round_mode_t)float_round_mode_32)\n      << std::endl;\n  uint32_t float_round_mode_16_64 = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_ROUND_MODE_16_64);\n  out << attr2 << \"float_round_mode_16_64\" << eq\n      << AmdFloatRoundModeToString((amd_float_round_mode_t)float_round_mode_16_64)\n      << std::endl;\n  uint32_t float_denorm_mode_32 = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_DENORM_MODE_32);\n  out << attr2 << \"float_denorm_mode_32\" << eq\n      << AmdFloatDenormModeToString((amd_float_denorm_mode_t)float_denorm_mode_32)\n      << std::endl;\n  uint32_t float_denorm_mode_16_64 = AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_FLOAT_DENORM_MODE_16_64);\n  out << attr2 << \"float_denorm_mode_16_64\" << eq\n      << AmdFloatDenormModeToString((amd_float_denorm_mode_t)float_denorm_mode_16_64)\n      << std::endl;\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_PRIV)) {\n    out << attr2 << \"priv\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_ENABLE_DX10_CLAMP)) {\n    out << attr2 << \"enable_dx10_clamp\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_DEBUG_MODE)) {\n    out << attr2 << \"debug_mode\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_ENABLE_IEEE_MODE)) {\n    out << attr2 << \"enable_ieee_mode\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_BULKY)) {\n    out << attr2 << \"bulky\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc1, AMD_COMPUTE_PGM_RSRC_ONE_CDBG_USER)) {\n    out << attr2 << \"cdbg_user\" << eq << \"TRUE\"\n        << std::endl;\n  }\n}\n\nvoid PrintAmdComputePgmRsrcTwo(std::ostream& out, amd_compute_pgm_rsrc_two32_t compute_pgm_rsrc2)\n{\n  out << \"  COMPUTE_PGM_RSRC2 (0x\" << std::hex << std::setw(8) << std::setfill('0') << compute_pgm_rsrc2 << \"):\" << std::endl;\n  out << std::dec;\n\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_PRIVATE_SEGMENT_WAVE_BYTE_OFFSET)) {\n    out << attr2 << \"enable_sgpr_private_segment_wave_byte_offset\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  uint32_t user_sgpr_count = AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_USER_SGPR_COUNT);\n  out << attr2 << \"user_sgpr_count\" << eq\n      << user_sgpr_count\n      << std::endl;\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_TRAP_HANDLER)) {\n    out << attr2 << \"enable_trap_handler\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_X)) {\n    out << attr2 << \"enable_sgpr_workgroup_id_x\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_Y)) {\n    out << attr2 << \"enable_sgpr_workgroup_id_y\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_ID_Z)) {\n    out << attr2 << \"enable_sgpr_workgroup_id_z\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_SGPR_WORKGROUP_INFO)) {\n    out << attr2 << \"enable_sgpr_workgroup_info\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  uint32_t enable_vgpr_workitem_id = AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_VGPR_WORKITEM_ID);\n  out << attr2 << \"enable_vgpr_workitem_id\" << eq\n      << AmdSystemVgprWorkitemIdToString((amd_system_vgpr_workitem_id_t)enable_vgpr_workitem_id)\n      << std::endl;\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_ADDRESS_WATCH)) {\n    out << attr2 << \"enable_exception_address_watch\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_MEMORY_VIOLATION)) {\n    out << attr2 << \"enable_exception_memory_violation\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  uint32_t granulated_lds_size = AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_GRANULATED_LDS_SIZE);\n  out << attr2 << \"granulated_lds_size\" << eq\n      << granulated_lds_size\n      << std::endl;\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION)) {\n    out << attr2 << \"enable_exception_ieee_754_fp_invalid_operation\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE)) {\n    out << attr2 << \"enable_exception_fp_denormal_source\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO)) {\n    out << attr2 << \"enable_exception_ieee_754_fp_division_by_zero\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW)) {\n    out << attr2 << \"enable_exception_ieee_754_fp_overflow\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW)) {\n    out << attr2 << \"enable_exception_ieee_754_fp_underflow\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT)) {\n    out << attr2 << \"enable_exception_ieee_754_fp_inexact\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(compute_pgm_rsrc2, AMD_COMPUTE_PGM_RSRC_TWO_ENABLE_EXCEPTION_INT_DIVISION_BY_ZERO)) {\n    out << attr2 << \"enable_exception_int_division_by_zero\" << eq << \"TRUE\"\n        << std::endl;\n  }\n}\n\nvoid PrintAmdKernelCodeProperties(std::ostream& out, amd_kernel_code_properties32_t kernel_code_properties)\n{\n  out << \"  KERNEL_CODE_PROPERTIES (0x\" << std::hex << std::setw(8) << std::setfill('0') << kernel_code_properties << \"):\" << std::endl;\n  out << std::dec;\n\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER)) {\n    out << attr2 << \"enable_sgpr_private_segment_buffer\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_DISPATCH_PTR)) {\n    out << attr2 << \"enable_sgpr_dispatch_ptr\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_QUEUE_PTR)) {\n    out << attr2 << \"enable_sgpr_queue_ptr\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_KERNARG_SEGMENT_PTR)) {\n    out << attr2 << \"enable_sgpr_kernarg_segment_ptr\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_DISPATCH_ID)) {\n    out << attr2 << \"enable_sgpr_dispatch_id\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_FLAT_SCRATCH_INIT)) {\n    out << attr2 << \"enable_sgpr_flat_scratch_init\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE)) {\n    out << attr2 << \"enable_sgpr_private_segment_size\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_X)) {\n    out << attr2 << \"enable_sgpr_grid_workgroup_count_x\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y)) {\n    out << attr2 << \"enable_sgpr_grid_workgroup_count_y\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z)) {\n    out << attr2 << \"enable_sgpr_grid_workgroup_count_z\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_ENABLE_ORDERED_APPEND_GDS)) {\n    out << attr2 << \"enable_ordered_append_gds\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  uint32_t private_element_size = AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_PRIVATE_ELEMENT_SIZE);\n  out << attr2 << \"private_element_size\" << eq\n      << AmdElementByteSizeToString((amd_element_byte_size_t)private_element_size)\n      << std::endl;\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_PTR64)) {\n    out << attr2 << \"is_ptr64\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_DYNAMIC_CALLSTACK)) {\n    out << attr2 << \"is_dynamic_callstack\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_DEBUG_ENABLED)) {\n    out << attr2 << \"is_debug_enabled\" << eq << \"TRUE\"\n        << std::endl;\n  }\n  if (AMD_HSA_BITS_GET(kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_XNACK_ENABLED)) {\n    out << attr2 << \"is_xnack_enabled\" << eq << \"TRUE\"\n        << std::endl;\n  }\n}\n\nvoid PrintAmdControlDirectives(std::ostream& out, const amd_control_directives_t &control_directives)\n{\n  if (!control_directives.enabled_control_directives) {\n    return;\n  }\n\n  out << \"  CONTROL_DIRECTIVES:\" << std::endl;\n\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_ENABLE_BREAK_EXCEPTIONS) {\n    out << attr2 << \"enable_break_exceptions\" << eq\n        << AmdExceptionKindToString(control_directives.enable_break_exceptions).c_str()\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_ENABLE_DETECT_EXCEPTIONS) {\n    out << attr2 << \"enable_detect_exceptions\" << eq\n        << AmdExceptionKindToString(control_directives.enable_detect_exceptions).c_str()\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_MAX_DYNAMIC_GROUP_SIZE) {\n    out << attr2 << \"max_dynamic_group_size\" << eq\n        << control_directives.max_dynamic_group_size\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_MAX_FLAT_GRID_SIZE) {\n    out << attr2 << \"max_flat_grid_size\" << eq\n        << control_directives.max_flat_grid_size\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_MAX_FLAT_WORKGROUP_SIZE) {\n    out << attr2 << \"max_flat_workgroup_size\" << eq\n        << control_directives.max_flat_workgroup_size\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_DIM) {\n    out << attr2 << \"required_dim\" << eq\n        << (uint32_t)control_directives.required_dim\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_GRID_SIZE) {\n    out << attr2 << \"required_grid_size\" << eq\n        << \"(\"\n        << control_directives.required_grid_size[0]\n        << \", \"\n        << control_directives.required_grid_size[1]\n        << \", \"\n        << control_directives.required_grid_size[2]\n        << \")\"\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRED_WORKGROUP_SIZE) {\n    out << attr2 << \"required_workgroup_size\" << eq\n        << \"(\"\n        << control_directives.required_workgroup_size[0]\n        << \", \"\n        << control_directives.required_workgroup_size[1]\n        << \", \"\n        << control_directives.required_workgroup_size[2]\n        << \")\"\n        << std::endl;\n  }\n  if (control_directives.enabled_control_directives & AMD_ENABLED_CONTROL_DIRECTIVE_REQUIRE_NO_PARTIAL_WORKGROUPS) {\n    out << attr2 << \"require_no_partial_workgroups\" << eq << \"TRUE\"\n        << std::endl;\n  }\n}\n\nnamespace code_options {\n\n  std::ostream& space(std::ostream& out)\n  {\n    if (out.tellp()) { out << \" \"; }\n    return out;\n  }\n\n  std::ostream& operator<<(std::ostream& out, const control_directive& d)\n  {\n    out << space <<\n      \"-hsa_control_directive:\" << d.name << \"=\";\n    return out;\n  }\n\n  const char *BrigExceptionString(BrigExceptions32_t e)\n  {\n    switch (e) {\n    case BRIG_EXCEPTIONS_INVALID_OPERATION: return \"INVALID_OPERATION\";\n    case BRIG_EXCEPTIONS_DIVIDE_BY_ZERO: return \"DIVIDE_BY_ZERO\";\n    case BRIG_EXCEPTIONS_OVERFLOW: return \"OVERFLOW\";\n    case BRIG_EXCEPTIONS_INEXACT: return \"INEXACT\";\n    default:\n      assert(false); return \"<unknown_BRIG_exception>\";\n    }\n  }\n\n  std::ostream& operator<<(std::ostream& out, const exceptions_mask& e)\n  {\n    bool first = true;\n    for (BrigExceptions32_t be = BRIG_EXCEPTIONS_INVALID_OPERATION; be < BRIG_EXCEPTIONS_FIRST_USER_DEFINED; ++be) {\n      if (e.mask & be) {\n        if (first) { first = false; } else { out << \",\"; }\n        out << BrigExceptionString(be);\n      }\n    }\n    return out;\n  }\n\n  std::ostream& operator<<(std::ostream& out, const control_directives& cd)\n  {\n    const hsa_ext_control_directives_t& d = cd.d;\n    uint64_t mask = d.control_directives_mask;\n    if (!mask) { return out; }\n\n    if (mask & BRIG_CONTROL_ENABLEBREAKEXCEPTIONS) {\n      out <<\n        control_directive(\"ENABLEBREAKEXCEPTIONS\") <<\n        exceptions_mask(d.break_exceptions_mask);\n    }\n    if (mask & BRIG_CONTROL_ENABLEDETECTEXCEPTIONS) {\n      out <<\n        control_directive(\"ENABLEDETECTEXCEPTIONS\") <<\n        exceptions_mask(d.detect_exceptions_mask);\n    }\n    if (mask & BRIG_CONTROL_MAXDYNAMICGROUPSIZE) {\n      out <<\n        control_directive(\"MAXDYNAMICGROUPSIZE\") <<\n        d.max_dynamic_group_size;\n    }\n    if (mask & BRIG_CONTROL_MAXFLATGRIDSIZE) {\n      out <<\n        control_directive(\"MAXFLATGRIDSIZE\") <<\n        d.max_flat_grid_size;\n    }\n    if (mask & BRIG_CONTROL_MAXFLATWORKGROUPSIZE) {\n      out <<\n        control_directive(\"MAXFLATWORKGROUPSIZE\") <<\n        d.max_flat_workgroup_size;\n    }\n    if (mask & BRIG_CONTROL_REQUIREDDIM) {\n      out <<\n        control_directive(\"REQUIREDDIM\") <<\n        d.required_dim;\n    }\n    if (mask & BRIG_CONTROL_REQUIREDGRIDSIZE) {\n      out <<\n        control_directive(\"REQUIREDGRIDSIZE\") <<\n        d.required_grid_size[0] << \",\" <<\n        d.required_grid_size[1] << \",\" <<\n        d.required_grid_size[2];\n    }\n    if (mask & BRIG_CONTROL_REQUIREDWORKGROUPSIZE) {\n      out <<\n        control_directive(\"REQUIREDWORKGROUPSIZE\") <<\n        d.required_workgroup_size.x << \",\" <<\n        d.required_workgroup_size.y << \",\" <<\n        d.required_workgroup_size.z;\n    }\n    return out;\n  }\n}\n\nconst char* hsaerr2str(hsa_status_t status) {\n  switch ((unsigned) status) {\n    case HSA_STATUS_SUCCESS:\n      return\n          \"HSA_STATUS_SUCCESS: The function has been executed successfully.\";\n    case HSA_STATUS_INFO_BREAK:\n      return\n          \"HSA_STATUS_INFO_BREAK: A traversal over a list of \"\n          \"elements has been interrupted by the application before \"\n          \"completing.\";\n    case HSA_STATUS_ERROR:\n      return \"HSA_STATUS_ERROR: A generic error has occurred.\";\n    case HSA_STATUS_ERROR_INVALID_ARGUMENT:\n      return\n          \"HSA_STATUS_ERROR_INVALID_ARGUMENT: One of the actual \"\n          \"arguments does not meet a precondition stated in the \"\n          \"documentation of the corresponding formal argument.\";\n    case HSA_STATUS_ERROR_INVALID_QUEUE_CREATION:\n      return\n          \"HSA_STATUS_ERROR_INVALID_QUEUE_CREATION: The requested \"\n          \"queue creation is not valid.\";\n    case HSA_STATUS_ERROR_INVALID_ALLOCATION:\n      return\n          \"HSA_STATUS_ERROR_INVALID_ALLOCATION: The requested \"\n          \"allocation is not valid.\";\n    case HSA_STATUS_ERROR_INVALID_AGENT:\n      return\n          \"HSA_STATUS_ERROR_INVALID_AGENT: The agent is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_REGION:\n      return\n          \"HSA_STATUS_ERROR_INVALID_REGION: The memory region is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_SIGNAL:\n      return\n          \"HSA_STATUS_ERROR_INVALID_SIGNAL: The signal is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_QUEUE:\n      return\n          \"HSA_STATUS_ERROR_INVALID_QUEUE: The queue is invalid.\";\n    case HSA_STATUS_ERROR_OUT_OF_RESOURCES:\n      return\n          \"HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to \"\n          \"allocate the necessary resources. This error may also \"\n          \"occur when the core runtime library needs to spawn \"\n          \"threads or create internal OS-specific events.\";\n    case HSA_STATUS_ERROR_INVALID_PACKET_FORMAT:\n      return\n          \"HSA_STATUS_ERROR_INVALID_PACKET_FORMAT: The AQL packet \"\n          \"is malformed.\";\n    case HSA_STATUS_ERROR_RESOURCE_FREE:\n      return\n          \"HSA_STATUS_ERROR_RESOURCE_FREE: An error has been \"\n          \"detected while releasing a resource.\";\n    case HSA_STATUS_ERROR_NOT_INITIALIZED:\n      return\n          \"HSA_STATUS_ERROR_NOT_INITIALIZED: An API other than \"\n          \"hsa_init has been invoked while the reference count of \"\n          \"the HSA runtime is zero.\";\n    case HSA_STATUS_ERROR_REFCOUNT_OVERFLOW:\n      return\n          \"HSA_STATUS_ERROR_REFCOUNT_OVERFLOW: The maximum \"\n          \"reference count for the object has been reached.\";\n    case HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS:\n      return\n          \"HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS: The arguments passed to \"\n          \"a functions are not compatible.\";\n    case HSA_STATUS_ERROR_INVALID_INDEX:\n      return \"The index is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_ISA:\n      return \"The instruction set architecture is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_CODE_OBJECT:\n      return \"The code object is invalid.\";\n    case HSA_STATUS_ERROR_INVALID_EXECUTABLE:\n      return \"The executable is invalid.\";\n    case HSA_STATUS_ERROR_FROZEN_EXECUTABLE:\n      return \"The executable is frozen.\";\n    case HSA_STATUS_ERROR_INVALID_SYMBOL_NAME:\n      return \"There is no symbol with the given name.\";\n    case HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED:\n      return \"The variable is already defined.\";\n    case HSA_STATUS_ERROR_VARIABLE_UNDEFINED:\n      return \"The variable is undefined.\";\n    case HSA_EXT_STATUS_ERROR_INVALID_PROGRAM:\n      return\n          \"HSA_EXT_STATUS_ERROR_INVALID_PROGRAM: Invalid program\";\n    case HSA_EXT_STATUS_ERROR_INVALID_MODULE:\n      return \"HSA_EXT_STATUS_ERROR_INVALID_MODULE: Invalid module\";\n    case HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE:\n      return\n          \"HSA_EXT_STATUS_ERROR_INCOMPATIBLE_MODULE: Incompatible module\";\n    case HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED:\n      return\n          \"HSA_EXT_STATUS_ERROR_MODULE_ALREADY_INCLUDED: Module already \"\n          \"included\";\n    case HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH:\n      return\n          \"HSA_EXT_STATUS_ERROR_SYMBOL_MISMATCH: Symbol mismatch\";\n    case HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED:\n      return\n          \"HSA_EXT_STATUS_ERROR_FINALIZATION_FAILED: Finalization failed\";\n    case HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH:\n      return\n          \"HSA_EXT_STATUS_ERROR_DIRECTIVE_MISMATCH: Directive mismatch\";\n    default:\n      return\n          \"Unknown HSA status\";\n  }\n}\n\nbool ReadFileIntoBuffer(const std::string& filename, std::vector<char>& buffer)\n{\n  std::ifstream file(filename, std::ios::binary);\n  if (!file) { return false; }\n  file.seekg(0, std::ios::end);\n  std::streamsize size = file.tellg();\n  file.seekg(0, std::ios::beg);\n\n  buffer.resize((size_t) size);\n  if (!file.read(buffer.data(), size)) { return false; }\n  return true;\n}\n\n#ifndef _WIN32\n#define _tempnam tempnam\n#define _close close\n#define _getpid getpid\n#define _open open\n#endif // _WIN32\n\nint OpenTempFile(const char* prefix)\n{\n  unsigned c = 0;\n  std::string tname = prefix;\n  tname += \"_\";\n  tname += std::to_string(_getpid());\n  tname += \"_\";\n  while (c++ < 20) { // Loop because several threads can generate same filename.\n#ifdef _WIN32\n    char dir[MAX_PATH+1];\n    if (!GetTempPath(sizeof(dir), dir)) { return -1; }\n    char *name = _tempnam(dir, tname.c_str());\n    if (!name) { return -1; }\n    HANDLE h = CreateFile(\n      name,\n      GENERIC_READ | GENERIC_WRITE,\n      0, // No sharing\n      NULL,\n      CREATE_NEW,\n      FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,\n      NULL);\n    free(name);\n    if (h == INVALID_HANDLE_VALUE) { continue; }\n    return _open_osfhandle((intptr_t)h, 0);\n#else // _WIN32\n    tname += \"XXXXXX\";\n    int d = mkstemp((char*)tname.c_str());\n    if (d < 0) { continue; }\n    if (unlink(tname.c_str()) < 0) { _close(d); return -1; }\n    return d;\n#endif // _WIN32\n  }\n  return -1;\n}\n\nvoid CloseTempFile(int fd)\n{\n  _close(fd);\n}\n\nconst char * CommentTopCallBack(void *ctx, int type) {\n  static const char* amd_kernel_code_t_begin = \"amd_kernel_code_t begin\";\n  static const char* amd_kernel_code_t_end = \"amd_kernel_code_t end\";\n  static const char* isa_begin = \"isa begin\";\n  switch(type) {\n  case COMMENT_AMD_KERNEL_CODE_T_BEGIN:\n    return amd_kernel_code_t_begin;\n  case COMMENT_AMD_KERNEL_CODE_T_END:\n    return amd_kernel_code_t_end;\n  case COMMENT_KERNEL_ISA_BEGIN:\n    return isa_begin;\n  default:\n    assert(false);\n    return \"\";\n  }\n}\nconst char * CommentRightCallBack(void *ctx, int type) {\n  return nullptr;\n}\n\nuint32_t ParseInstructionOffset(const std::string& instruction) {\n  // instruction format: opcode op1, op2 ... // offset: binopcode\n  std::string::size_type n = instruction.find(\"//\");\n  assert(n != std::string::npos);\n  std::string comment = instruction.substr(n);\n  n = comment.find(':');\n  assert(n != std::string::npos);\n  comment.erase(n);\n  assert(comment.size() > 3);\n  comment.erase(0, 3);\n  return strtoul(comment.c_str(), nullptr, 16);\n}\n\nbool IsNotSpace(char c) {\n  return !isspace(static_cast<int>(c));\n}\n\nvoid ltrim(std::string &str) {\n  str.erase(str.begin(), std::find_if(str.begin(), str.end(), IsNotSpace));\n}\n\nstd::string DumpFileName(const std::string& dir, const char* prefix, const char* ext, unsigned n, unsigned i)\n{\n  std::ostringstream ss;\n  if (!dir.empty()) {\n    ss << dir << \"/\";\n  }\n  ss <<\n    prefix <<\n    std::setfill('0') << std::setw(3) << n;\n  if (i) { ss << \"_\" << i; }\n  if (ext) { ss << \".\" << ext; }\n  return ss.str();\n}\n\n\n}   //  namespace hsa\n}   //  namespace amd\n}   //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_hsa_code_util.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_CODE_UTIL_HPP_\n#define AMD_HSA_CODE_UTIL_HPP_\n\n#include <cassert>\n#include <string>\n#include <vector>\n#include <iostream>\n#ifdef _WIN32\n#include <malloc.h>\n#else // _WIN32\n#include <cstdlib>\n#endif // _WIN32\n#include \"inc/amd_hsa_kernel_code.h\"\n#include \"inc/amd_hsa_elf.h\"\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_finalize.h\"\n\n#define hsa_error(e) static_cast<hsa_status_t>(e)\n\n#define release_assert(e)                                                      \\\n  if (!(e)) {                                                                  \\\n    std::cerr << __FILE__ << \":\";                                              \\\n    std::cerr << __LINE__ << \":\";                                              \\\n    std::cerr << \" Assertion `\" << #e << \"' failed.\" << std::endl;             \\\n    std::abort();                                                              \\\n  }                                                                            \\\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\n\nstd::string HsaSymbolKindToString(hsa_symbol_kind_t kind);\nstd::string HsaSymbolLinkageToString(hsa_symbol_linkage_t linkage);\nstd::string HsaVariableAllocationToString(hsa_variable_allocation_t allocation);\nstd::string HsaVariableSegmentToString(hsa_variable_segment_t segment);\nstd::string HsaProfileToString(hsa_profile_t profile);\nstd::string HsaMachineModelToString(hsa_machine_model_t model);\nstd::string HsaFloatRoundingModeToString(hsa_default_float_rounding_mode_t mode);\nstd::string AmdMachineKindToString(amd_machine_kind16_t machine);\nstd::string AmdFloatRoundModeToString(amd_float_round_mode_t round_mode);\nstd::string AmdFloatDenormModeToString(amd_float_denorm_mode_t denorm_mode);\nstd::string AmdSystemVgprWorkitemIdToString(amd_system_vgpr_workitem_id_t system_vgpr_workitem_id);\nstd::string AmdElementByteSizeToString(amd_element_byte_size_t element_byte_size);\nstd::string AmdExceptionKindToString(amd_exception_kind16_t exceptions);\nstd::string AmdPowerTwoToString(amd_powertwo8_t p);\namdgpu_hsa_elf_segment_t AmdHsaElfSectionSegment(amdgpu_hsa_elf_section_t sec);\nbool IsAmdHsaElfSectionROData(amdgpu_hsa_elf_section_t sec);\nstd::string AmdHsaElfSegmentToString(amdgpu_hsa_elf_segment_t seg);\nstd::string AmdPTLoadToString(uint64_t type);\n\nvoid PrintAmdKernelCode(std::ostream& out, const amd_kernel_code_t *akc);\nvoid PrintAmdComputePgmRsrcOne(std::ostream& out, amd_compute_pgm_rsrc_one32_t compute_pgm_rsrc1);\nvoid PrintAmdComputePgmRsrcTwo(std::ostream& out, amd_compute_pgm_rsrc_two32_t compute_pgm_rsrc2);\nvoid PrintAmdKernelCodeProperties(std::ostream& out, amd_kernel_code_properties32_t kernel_code_properties);\nvoid PrintAmdControlDirectives(std::ostream& out, const amd_control_directives_t &control_directives);\n\nnamespace code_options {\n  // Space between options (not at the beginning).\n  std::ostream& space(std::ostream& out);\n\n  // Control directive option without value.\n  struct control_directive {\n    const char *name;\n    control_directive(const char* name_) : name(name_) { }\n  };\n  std::ostream& operator<<(std::ostream& out, const control_directive& d);\n\n  // Exceptions mask string.\n  struct exceptions_mask {\n    uint16_t mask;\n    exceptions_mask(uint16_t mask_) : mask(mask_) { }\n  };\n  std::ostream& operator<<(std::ostream& out, const exceptions_mask& e);\n\n  // Control directives options.\n  struct control_directives {\n    const hsa_ext_control_directives_t& d;\n    control_directives(const hsa_ext_control_directives_t& d_) : d(d_) { }\n  };\n  std::ostream& operator<<(std::ostream& out, const control_directives& cd);\n}\n\nconst char* hsaerr2str(hsa_status_t status);\nbool ReadFileIntoBuffer(const std::string& filename, std::vector<char>& buffer);\n\n// Create new empty temporary file that will be deleted when closed.\nint OpenTempFile(const char* prefix);\nvoid CloseTempFile(int fd);\n\n// Helper comment types for isa disassembler\nenum DumpIsaCommentType  {\n  COMMENT_AMD_KERNEL_CODE_T_BEGIN = 1,\n  COMMENT_AMD_KERNEL_CODE_T_END,\n  COMMENT_KERNEL_ISA_BEGIN,\n};\n\n// Callbacks to create helper comments for isa disassembler\nconst char * CommentTopCallBack(void *ctx, int type);\nconst char * CommentRightCallBack(void *ctx, int type);\n\n// Parse disassembler instruction line to find offset\nuint32_t ParseInstructionOffset(const std::string& instruction);\n\n// Trim whitespaces from start of string\nvoid ltrim(std::string &str);\n\n\n// Helper function that allocates an aligned memory.\ninline void*\nalignedMalloc(size_t size, size_t alignment)\n{\n#if defined(_WIN32)\n  return ::_aligned_malloc(size, alignment);\n#else\n  void * ptr = NULL;\n  alignment = (std::max)(alignment, sizeof(void*));\n  if (0 == ::posix_memalign(&ptr, alignment, size)) {\n    return ptr;\n  }\n  return NULL;\n#endif\n}\n\n// Helper function that frees an aligned memory.\ninline void\nalignedFree(void *ptr)\n{\n#if defined(_WIN32)\n  ::_aligned_free(ptr);\n#else\n  free(ptr);\n#endif\n}\n\ninline uint64_t alignUp(uint64_t num, uint64_t align)\n{\n  assert(align);\n  assert((align & (align - 1)) == 0);\n  return (num + align - 1) & ~(align - 1);\n}\n\ninline uint32_t alignUp(uint32_t num, uint32_t align)\n{\n  assert(align);\n  assert((align & (align - 1)) == 0);\n  return (num + align - 1) & ~(align - 1);\n}\n\nstd::string DumpFileName(const std::string& dir, const char* prefix, const char* ext, unsigned n, unsigned i = 0);\n\n}   //  namespace hsa\n}   //  namespace amd\n}   //  namespace rocr\n\n#endif // AMD_HSA_CODE_UTIL_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_hsa_locks.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"amd_hsa_locks.hpp\"\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace common {\n\nvoid ReaderWriterLock::ReaderLock()\n{\n  internal_lock_.lock();\n  while (0 < writers_count_) {\n    readers_condition_.wait(internal_lock_);\n  }\n  readers_count_ += 1;\n  internal_lock_.unlock();\n}\n\nvoid ReaderWriterLock::ReaderUnlock()\n{\n  internal_lock_.lock();\n  readers_count_ -= 1;\n  if (0 == readers_count_ && 0 < writers_waiting_) {\n    writers_condition_.notify_one();\n  }\n  internal_lock_.unlock();\n}\n\nvoid ReaderWriterLock::WriterLock()\n{\n  internal_lock_.lock();\n  writers_waiting_ += 1;\n  while (0 < readers_count_ || 0 < writers_count_) {\n    writers_condition_.wait(internal_lock_);\n  }\n  writers_count_ += 1;\n  writers_waiting_ -= 1;\n  internal_lock_.unlock();\n}\n\nvoid ReaderWriterLock::WriterUnlock()\n{\n  internal_lock_.lock();\n  writers_count_ -= 1;\n  if (0 < writers_waiting_) {\n    writers_condition_.notify_one();\n  }\n  readers_condition_.notify_all();\n  internal_lock_.unlock();\n}\n\n} // namespace common\n} // namespace hsa\n} // namespace amd\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_hsa_locks.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_HSA_LOCKS_HPP\n#define AMD_HSA_LOCKS_HPP\n\n#include <condition_variable>\n#include <cstddef>\n#include <mutex>\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace common {\n\ntemplate<typename LockType>\nclass ReaderLockGuard final {\npublic:\n  explicit ReaderLockGuard(LockType &lock):\n    lock_(lock)\n  {\n    lock_.ReaderLock();\n  }\n\n  ~ReaderLockGuard()\n  {\n    lock_.ReaderUnlock();\n  }\n\nprivate:\n  ReaderLockGuard(const ReaderLockGuard&);\n  ReaderLockGuard& operator=(const ReaderLockGuard&);\n\n  LockType &lock_;\n};\n\ntemplate<typename LockType>\nclass WriterLockGuard final {\npublic:\n  explicit WriterLockGuard(LockType &lock):\n    lock_(lock)\n  {\n    lock_.WriterLock();\n  }\n\n  ~WriterLockGuard()\n  {\n    lock_.WriterUnlock();\n  }\n\nprivate:\n  WriterLockGuard(const WriterLockGuard&);\n  WriterLockGuard& operator=(const WriterLockGuard&);\n\n  LockType &lock_;\n};\n\nclass ReaderWriterLock final {\npublic:\n  ReaderWriterLock():\n    readers_count_(0), writers_count_(0), writers_waiting_(0) {}\n\n  ~ReaderWriterLock() {}\n\n  void ReaderLock();\n\n  void ReaderUnlock();\n\n  void WriterLock();\n\n  void WriterUnlock();\n\nprivate:\n  ReaderWriterLock(const ReaderWriterLock&);\n  ReaderWriterLock& operator=(const ReaderWriterLock&);\n\n  size_t readers_count_;\n  size_t writers_count_;\n  size_t writers_waiting_;\n  std::mutex internal_lock_;\n  std::condition_variable_any readers_condition_;\n  std::condition_variable_any writers_condition_;\n};\n\n} // namespace common\n} // namespace hsa\n} // namespace amd\n} // namespace rocr\n\n#endif // AMD_HSA_LOCKS_HPP\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_options.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"amd_options.hpp\"\n\n#include <algorithm>\n#include <cassert>\n#include <cctype>\n#include <cstdarg>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <list>\n#include <string>\n\n#include <cstddef>\n\nnamespace rocr {\nnamespace amd {\nnamespace options {\n\n//===----------------------------------------------------------------------===//\n// StringFactory.                                                             //\n//===----------------------------------------------------------------------===//\n\nstd::string StringFactory::Flatten(const char **cstrs,\n                                   const uint32_t &cstrs_count,\n                                   const char &spacer) {\n  if (NULL == cstrs || 0 == cstrs_count) {\n    return std::string();\n  }\n\n  std::string flattened;\n  for (uint32_t i = 0; i < cstrs_count; ++i) {\n    if (NULL == cstrs[i]) {\n      return std::string();\n    }\n    flattened += cstrs[i];\n    if (i != (cstrs_count - 1)) {\n      flattened += spacer;\n    }\n  }\n  return flattened;\n}\n\nstd::list<std::string> StringFactory::Tokenize(const char *cstr,\n                                               const char &delim) {\n  if (NULL == cstr) {\n    return std::list<std::string>();\n  }\n\n  const std::string str = cstr;\n  size_t start = 0;\n  size_t end = 0;\n\n  std::list<std::string> tokens;\n  while ((end = str.find(delim, start)) != std::string::npos) {\n    if (start != end) {\n      tokens.push_back(str.substr(start, end - start));\n    }\n    start = end + 1;\n  }\n  if (str.size() > start) {\n    tokens.push_back(str.substr(start));\n  }\n  return tokens;\n}\n\nstd::string StringFactory::ToLower(const std::string& str) {\n  std::string lower(str.length(), ' ');\n  std::transform(str.begin(), str.end(), lower.begin(), ::tolower);\n  return lower;\n}\n\nstd::string StringFactory::ToUpper(const std::string& str) {\n  std::string upper(str.length(), ' ');\n  std::transform(str.begin(), str.end(), upper.begin(), ::toupper);\n  return upper;\n}\n\n//===----------------------------------------------------------------------===//\n// HelpPrinter, HelpStreambuf.                                                //\n//===----------------------------------------------------------------------===//\n\nHelpStreambuf::HelpStreambuf(std::ostream& stream)\n  : basicStream_(&stream),\n    basicBuf_(stream.rdbuf()),\n    wrapWidth_(0),\n    indentSize_(0),\n    atLineStart_(true),\n    lineWidth_(0)\n{\n  basicStream_->rdbuf(this);\n}\n\nHelpStreambuf::int_type HelpStreambuf::overflow(HelpStreambuf::int_type ch) {\n    if (atLineStart_ && ch != '\\n') {\n      std::string indent(indentSize_, ' ');\n      basicBuf_->sputn(indent.data(), indent.size());\n      lineWidth_ = indentSize_;\n      atLineStart_ = false;\n    } else if (ch == '\\n') {\n      atLineStart_ = true;\n      lineWidth_ = 0;\n    }\n\n    if (wrapWidth_ > 0 && lineWidth_ == wrapWidth_) {\n      basicBuf_->sputc('\\n');\n      std::string indent(indentSize_, ' ');\n      basicBuf_->sputn(indent.data(), indent.size());\n      lineWidth_ = indentSize_;\n      atLineStart_ = false;\n    }\n\n    lineWidth_++;\n    return basicBuf_->sputc(ch);\n  }\n\nHelpPrinter& HelpPrinter::PrintUsage(const std::string& usage) {\n  sbuf_.IndentSize(0);\n  sbuf_.WrapWidth(0);\n  Stream() << usage;\n  if (usage.length() < USAGE_WIDTH) {\n    Stream() <<  std::string(USAGE_WIDTH - usage.length(), ' ');\n  }\n  Stream() << std::string(PADDING_WIDTH, ' ');\n  return *this;\n}\n\nHelpPrinter& HelpPrinter::PrintDescription(const std::string& description) {\n  sbuf_.WrapWidth(USAGE_WIDTH + PADDING_WIDTH + DESCRIPTION_WIDTH);\n  sbuf_.IndentSize(USAGE_WIDTH + PADDING_WIDTH);\n  Stream() << description << std::endl;\n  sbuf_.IndentSize(0);\n  sbuf_.WrapWidth(0);\n  return *this;\n}\n\n//===----------------------------------------------------------------------===//\n// ChoiceOptioin.                                                             //\n//===----------------------------------------------------------------------===//\nChoiceOption::ChoiceOption(const std::string& name,\n                           const std::vector<std::string>& choices,\n                           const std::string& help,\n                           std::ostream& error)\n  : OptionBase(name, help, error) {\n    for (const auto& choice: choices) {\n      choices_.insert(choice);\n    }\n  }\n\nbool ChoiceOption::ProcessTokens(std::list<std::string> &tokens) {\n  assert(0 == name_.compare(tokens.front()) && \"option name is mismatched\");\n  if (2 != tokens.size()) {\n    error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n    return false;\n  }\n\n  tokens.pop_front();\n\n  if (0 == choices_.count(tokens.front())) {\n    error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n    return false;\n  }\n\n  is_set_ = true;\n  value_ = tokens.front();\n  tokens.pop_front();\n  return true;\n}\n\nvoid ChoiceOption::PrintHelp(HelpPrinter& printer) const {\n  std::string usage = \"-\" + name_ + \"=[\";\n  bool first = true;\n  for (const auto& choice: choices_) {\n    if (!first) {\n      usage += '|';\n    } else {\n      first = false;\n    }\n    usage += choice;\n  }\n  usage += \"]\";\n  printer.PrintUsage(usage).PrintDescription(help_);\n}\n\n//===----------------------------------------------------------------------===//\n// PrefixOption.                                                             //\n//===----------------------------------------------------------------------===//\nbool PrefixOption::IsValid() const {\n  return (0 < name_.size()) && (name_.find(':') == std::string::npos);\n}\n\nstd::string::size_type PrefixOption::FindPrefix(const std::string& token) const {\n  auto prefix = name_ + ':';\n  return token.find(prefix);\n}\n\nbool PrefixOption::Accept(const std::string& token) const {\n  return\n    (token.compare(0, name_.length(), name_) == 0) &&\n    token.length() > name_.length() &&\n    token[name_.length()] == ':';\n}\n\nbool PrefixOption::ProcessTokens(std::list<std::string> &tokens) {\n  assert(1 <= tokens.size());\n  assert(Accept(tokens.front()) && \"option name is mismatched\");\n\n  std::string value = tokens.front(); tokens.pop_front();\n  value = value.substr(name_.length() + 1);\n\n  for (const auto& token: tokens) {\n    value += '=';\n    value += token;\n  }\n  tokens.clear();\n\n  values_.push_back(value);\n  is_set_ = true;\n  return true;\n}\n\nvoid PrefixOption::PrintHelp(HelpPrinter& printer) const {\n  printer.PrintUsage(\"-\" + name_ + \":[value]\").PrintDescription(help_);\n}\n\n//===----------------------------------------------------------------------===//\n// OptionParser.                                                              //\n//===----------------------------------------------------------------------===//\nstd::vector<OptionBase*>::iterator\nOptionParser::FindOption(const std::string& name) {\n  std::vector<OptionBase*>::iterator it = options_.begin();\n  std::vector<OptionBase*>::iterator end = options_.end();\n  for (; it != end; ++it) {\n    if ((*it)->Accept(name)) {\n      return it;\n    }\n  }\n  return end;\n}\n\nbool OptionParser::AddOption(OptionBase *option) {\n  if (NULL == option || !option->IsValid()) {\n    return false;\n  }\n  if (FindOption(option->name()) != options_.end()) {\n    return false;\n  }\n  options_.push_back(option);\n  return true;\n}\n\nconst std::string& OptionParser::Unknown() const {\n  assert(collectUnknown_);\n  return unknownOptions_;\n}\n\nbool OptionParser::ParseOptions(const char *options) {\n  std::list<std::string> tokens_l1 = StringFactory::Tokenize(options, ' ');\n  if (0 == tokens_l1.size()) {\n    return true;\n  }\n\n  std::list<std::string>::iterator tokens_l1i = tokens_l1.begin();\n  while (tokens_l1i != tokens_l1.end()) {\n    if ('-' == tokens_l1i->at(0)) {\n      std::list<std::string>::iterator option_begin = tokens_l1i;\n      std::list<std::string> tokens_l2;\n      do {\n        tokens_l2.push_back(*tokens_l1i);\n        tokens_l1i++;\n      } while (tokens_l1i != tokens_l1.end() && '-' != tokens_l1i->at(0));\n      std::list<std::string>::iterator option_end = tokens_l1i;\n      tokens_l2.front().erase(0, 1);\n\n      if (1 == tokens_l2.size()) {\n        tokens_l2 = StringFactory::Tokenize(tokens_l2.front().c_str(), '=');\n        if (2 < tokens_l2.size()) {\n          if (collectUnknown_) {\n            unknownOptions_ += *tokens_l1i + \" \";\n            continue;\n          } else {\n            error() << \"error: invalid option format: \\'\"\n                    << tokens_l2.front() << '\\'' << std::endl;\n            Reset();\n            return false;\n          }\n        }\n      }\n\n      auto find_status = FindOption(tokens_l2.front());\n      if (find_status == options_.end()) {\n        if (collectUnknown_) {\n          for (; option_begin != option_end; ++option_begin) {\n            unknownOptions_ += *option_begin + \" \";\n          }\n          continue;\n        } else {\n          error() << \"error: unknown option: \\'\"\n                  << tokens_l2.front() << '\\'' << std::endl;\n          Reset();\n          return false;\n        }\n      }\n\n      if (!(*find_status)->ProcessTokens(tokens_l2)) {\n        Reset();\n        return false;\n      }\n      assert(0 == tokens_l2.size());\n    } else {\n      if (collectUnknown_) {\n        unknownOptions_ += *tokens_l1i + \" \";\n      } else {\n        error() << \"error: unknown option: \\'\"\n                << *tokens_l1i << '\\'' << std::endl;\n        Reset();\n        return false;\n      }\n    }\n  }\n\n  return true;\n}\n\nvoid OptionParser::PrintHelp(std::ostream& out, const std::string& addition) const {\n  HelpPrinter printer(out);\n  for (const auto& option: options_) {\n    option->PrintHelp(printer);\n  }\n  out << addition << std::endl;\n}\n\nvoid OptionParser::Reset() {\n  unknownOptions_.clear();\n  for (auto &option : options_) {\n    option->Reset();\n  }\n}\n\n} // namespace options\n} // namespace amd\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/libamdhsacode/amd_options.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef AMD_OPTIONS_HPP\n#define AMD_OPTIONS_HPP\n\n#include <cstdlib>\n#include <iostream>\n#include <list>\n#include <vector>\n#include <cstdint>\n\n#include <cassert>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <unordered_set>\n\nnamespace rocr {\nnamespace amd {\nnamespace options {\n\n//===----------------------------------------------------------------------===//\n// StringFactory.                                                             //\n//===----------------------------------------------------------------------===//\n\nclass StringFactory final {\npublic:\n  static std::string Flatten(const char **cstrs,\n                             const uint32_t &cstrs_count,\n                             const char &spacer = '\\0');\n\n  static std::list<std::string> Tokenize(const char *cstr, const char &delim);\n\n  static std::string ToLower(const std::string& str);\n  static std::string ToUpper(const std::string& str);\n};\n\n//===----------------------------------------------------------------------===//\n// HelpPrinter, HelpStreambuf.                                                //\n//===----------------------------------------------------------------------===//\n\nclass HelpStreambuf : public std::streambuf {\npublic:\n  explicit HelpStreambuf(std::ostream& stream);\n\n  virtual ~HelpStreambuf() {\n    basicStream_->rdbuf(basicBuf_);\n  }\n\n  void IndentSize(unsigned indent) {\n    assert(wrapWidth_ == 0 || indentSize_ < wrapWidth_);\n    indentSize_ = indent;\n  }\n\n  void WrapWidth(unsigned wrap) {\n    assert(wrapWidth_ == 0 || indentSize_ < wrapWidth_);\n    wrapWidth_ = wrap;\n  }\n\nprotected:\n  virtual int_type overflow(int_type ch) override;\n\nprivate:\n  std::ostream* basicStream_;\n  std::streambuf* basicBuf_;\n\n  unsigned wrapWidth_;\n  unsigned indentSize_;\n\n  bool atLineStart_;\n  unsigned lineWidth_;\n};\n\n\nclass HelpPrinter {\nprivate:\n  static const unsigned USAGE_WIDTH = 30;\n  static const unsigned PADDING_WIDTH = 2;\n  static const unsigned DESCRIPTION_WIDTH = 50;\n\npublic:\n  HelpPrinter& PrintUsage(const std::string& usage);\n  HelpPrinter& PrintDescription(const std::string& description);\n\n  std::ostream& Stream() { return *out_; }\n\nprivate:\n  explicit HelpPrinter(std::ostream& out = std::cout) : out_(&out), sbuf_(*out_) {}\n\n  /// @brief Not copy-constructible.\n  HelpPrinter(const HelpPrinter&);\n  /// @brief Not copy-assignable.\n  HelpPrinter& operator =(const HelpPrinter&);\n\n  friend class OptionParser;\n\n  std::ostream *out_;\n  HelpStreambuf sbuf_;\n};\n\n//===----------------------------------------------------------------------===//\n// OptionBase.                                                                //\n//===----------------------------------------------------------------------===//\n\nclass OptionBase {\npublic:\n  virtual ~OptionBase() {}\n\n  const std::string& name() const {\n    return name_;\n  }\n  const bool& is_set() const {\n    return is_set_;\n  }\n\n  virtual bool IsValid() const {\n    return 0 < name_.size();\n  }\n\nprotected:\n  explicit OptionBase(const std::string& name,\n                      const std::string& help = \"\",\n                      std::ostream &error = std::cerr)\n    : name_(name),\n      help_(help),\n      is_set_(false),\n      error_(&error) {}\n\n  virtual void PrintHelp(HelpPrinter& printer) const = 0;\n  virtual bool Accept(const std::string& name) const { return name_ == name; }\n\n  const std::string name_;\n  const std::string help_;\n  bool is_set_;\n\n  std::ostream &error() const { return *error_; }\n\nprivate:\n  /// @brief Not copy-constructible.\n  OptionBase(const OptionBase &ob);\n  /// @brief Not copy-assignable.\n  OptionBase& operator=(const OptionBase &ob);\n\n  void Reset() {\n    is_set_ = false;\n  }\n\n  virtual bool ProcessTokens(std::list<std::string> &tokens) = 0;\n\n  friend class OptionParser;\n\n  mutable std::ostream *error_;\n};\n\n\n//===----------------------------------------------------------------------===//\n// Option<T>.                                                                 //\n//===----------------------------------------------------------------------===//\n\ntemplate<typename T>\nclass Option final: public OptionBase {\npublic:\n  explicit Option(const std::string& name,\n                  const std::string& help = \"\",\n                  std::ostream& error = std::cerr):\n    OptionBase(name, help, error) {}\n\n  ~Option() {}\n\n  const std::list<T>& values() const {\n    return values_;\n  }\n\nprotected:\n  virtual void PrintHelp(HelpPrinter& printer) const override;\n\nprivate:\n  /// @brief Not copy-constructible.\n  Option(const Option &o);\n  /// @brief Not copy-assignable.\n  Option& operator=(const Option &o);\n\n  bool ProcessTokens(std::list<std::string> &tokens);\n\n  std::list<T> values_;\n};\n\ntemplate<typename T>\nbool Option<T>::ProcessTokens(std::list<std::string> &tokens) {\n  assert(0 == name_.compare(tokens.front()) && \"option name is mismatched\");\n  if (2 > tokens.size()) {\n    error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n    return false;\n  }\n\n  is_set_ = true;\n  tokens.pop_front();\n\n  while (!tokens.empty()) {\n    std::istringstream token_stream(tokens.front());\n    if (!token_stream.good()) {\n      error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n      return false;\n    }\n\n    T value;\n    token_stream >> value;\n\n    values_.push_back(value);\n    tokens.pop_front();\n  }\n  return true;\n}\n\ntemplate<typename T>\nvoid Option<T>::PrintHelp(HelpPrinter& printer) const {\n  printer.PrintUsage(\"-\" + name_ + \" [\" + StringFactory::ToUpper(name_) + \"s]\")\n         .PrintDescription(help_);\n}\n\n//===----------------------------------------------------------------------===//\n// ValueOption<T>.                                                            //\n//===----------------------------------------------------------------------===//\n\ntemplate<typename T>\nclass ValueOption final: public OptionBase {\npublic:\n  explicit ValueOption(const std::string& name,\n                       const std::string& help = \"\",\n                       std::ostream& error = std::cerr):\n    OptionBase(name, help, error) {}\n\n  ~ValueOption() {}\n\n  const T& value() const {\n    return value_;\n  }\n\nprotected:\n  void PrintHelp(HelpPrinter& printer) const override;\n\nprivate:\n  /// @brief Not copy-constructible.\n  ValueOption(const ValueOption &o);\n  /// @brief Not copy-assignable.\n  ValueOption& operator=(const ValueOption &o);\n\n  bool ProcessTokens(std::list<std::string> &tokens) override;\n\n  T value_;\n};\n\ntemplate<typename T>\nbool ValueOption<T>::ProcessTokens(std::list<std::string> &tokens) {\n  assert(0 == name_.compare(tokens.front()) && \"option name is mismatched\");\n  if (2 != tokens.size()) {\n    error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n    return false;\n  }\n\n  is_set_ = true;\n  tokens.pop_front();\n\n  std::istringstream token_stream(tokens.front());\n  if (!token_stream.good()) {\n    error() << \"error: invalid option: \\'\" << name_ << '\\'' << std::endl;\n    return false;\n  }\n  token_stream >> value_;\n  tokens.pop_front();\n  return true;\n}\n\ntemplate<typename T>\nvoid ValueOption<T>::PrintHelp(HelpPrinter& printer) const {\n  printer.PrintUsage(\"-\" + name_ + \"=[VAL]\")\n         .PrintDescription(help_);\n}\n\n//===----------------------------------------------------------------------===//\n// ChoiceOptioin.                                                             //\n//===----------------------------------------------------------------------===//\nclass ChoiceOption final: public OptionBase {\npublic:\n  ChoiceOption(const std::string& name,\n               const std::vector<std::string>& choices,\n               const std::string& help = \"\",\n               std::ostream& error = std::cerr);\n\n  ~ChoiceOption() {}\n\n  const std::string& value() const {\n    return value_;\n  }\n\nprotected:\n  void PrintHelp(HelpPrinter& printer) const override;\n\nprivate:\n  /// @brief Not copy-constructible.\n  ChoiceOption(const ChoiceOption&);\n  /// @brief Not copy-assignable.\n  ChoiceOption& operator =(const ChoiceOption&);\n\n  bool ProcessTokens(std::list<std::string> &tokens) override;\n\n  std::unordered_set<std::string> choices_;\n  std::string value_;\n};\n\n//===----------------------------------------------------------------------===//\n// Option<void>.                                                              //\n//===----------------------------------------------------------------------===//\n\nclass NoArgOption final: public OptionBase {\npublic:\n  explicit NoArgOption(const std::string& name,\n                       const std::string& help = \"\",\n                       std::ostream& error = std::cerr):\n    OptionBase(name, help, error) {}\n\n  ~NoArgOption() {}\n\nprotected:\n  void PrintHelp(HelpPrinter& printer) const override {\n    printer.PrintUsage(\"-\" + name_).PrintDescription(help_);\n  }\n\nprivate:\n  /// @brief Not copy-constructible.\n  NoArgOption(const NoArgOption &o);\n  /// @brief Not copy-assignable.\n  NoArgOption& operator=(const NoArgOption &o);\n\n  bool ProcessTokens(std::list<std::string> &tokens) override {\n    assert(0 == name_.compare(tokens.front()) && \"option name is mismatched\");\n    if (1 == tokens.size()) {\n      tokens.pop_front();\n      is_set_ = true;\n      return true;\n    } else if (2 == tokens.size()) {\n      tokens.pop_front();\n      if (tokens.front() == \"1\") {\n        is_set_ = true;\n        tokens.pop_front();\n        return true;\n      } else if (tokens.front() == \"0\") {\n        is_set_ = false;\n        tokens.pop_front();\n        return true;\n      }\n    }\n    error() << \"error: invalid option: '\" << name_ << \"'\" << std::endl;\n    return false;\n  }\n};\n\n//===----------------------------------------------------------------------===//\n// PrefixOption.                                                              //\n//===----------------------------------------------------------------------===//\nclass PrefixOption final: public OptionBase {\npublic:\n  PrefixOption(const std::string& prefix,\n               const std::string& help = \"\",\n               std::ostream& error = std::cerr)\n    : OptionBase(prefix, help, error) {}\n\n  ~PrefixOption() {}\n\n  const std::vector<std::string>& values() const {\n    return values_;\n  }\n\n  bool IsValid() const override;\n\nprotected:\n  void PrintHelp(HelpPrinter& printer) const override;\n  bool Accept(const std::string& token) const override;\n\nprivate:\n  /// @brief Not copy-constructible.\n  PrefixOption(const PrefixOption&);\n  /// @brief Not copy-assignable.\n  PrefixOption& operator =(const PrefixOption&);\n\n  bool ProcessTokens(std::list<std::string>& tokens) override;\n\n  std::string::size_type FindPrefix(const std::string& token) const;\n\n  std::vector<std::string> values_;\n};\n\n//===----------------------------------------------------------------------===//\n// OptionParser.                                                              //\n//===----------------------------------------------------------------------===//\n\nclass OptionParser final {\npublic:\n  explicit OptionParser(bool collectUnknown = false, std::ostream& error = std::cerr)\n    : collectUnknown_(collectUnknown),\n      error_(&error) {}\n\n  ~OptionParser() {}\n\n  bool AddOption(OptionBase *option);\n\n  bool ParseOptions(const char *options);\n\n  const std::string& Unknown() const;\n  void CollectUnknown(bool b) { collectUnknown_ = b; }\n\n  void PrintHelp(std::ostream& out, const std::string& addition = \"\") const;\n\n  void Reset();\n\nprivate:\n  /// @brief Not copy-constructible.\n  OptionParser(const OptionParser &op);\n  /// @brief Not copy-assignable.\n  OptionParser& operator=(const OptionParser &op);\n\n  std::ostream& error() { return *error_; }\n\n  std::vector<OptionBase*>::iterator FindOption(const std::string& name);\n\n  std::vector<OptionBase*> options_;\n\n  std::string unknownOptions_;\n  bool collectUnknown_;\n\n  std::ostream *error_;\n};\n\n} // namespace options\n} // namespace amd\n} // namespace rocr\n\n#endif // AMD_OPTIONS_HPP\n"
  },
  {
    "path": "runtime/hsa-runtime/loader/AMDHSAKernelDescriptor.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef LLVM_SUPPORT_AMDHSAKERNELDESCRIPTOR_H\n#define LLVM_SUPPORT_AMDHSAKERNELDESCRIPTOR_H\n\n#include <cstddef>\n#include <cstdint>\n\n// Gets offset of specified member in specified type.\n#ifndef offsetof\n#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)\n#endif // offsetof\n\n// Creates enumeration entries used for packing bits into integers. Enumeration\n// entries include bit shift amount, bit width, and bit mask.\n#ifndef AMDHSA_BITS_ENUM_ENTRY\n#define AMDHSA_BITS_ENUM_ENTRY(NAME, SHIFT, WIDTH) \\\n  NAME ## _SHIFT = (SHIFT),                        \\\n  NAME ## _WIDTH = (WIDTH),                        \\\n  NAME = (((1 << (WIDTH)) - 1) << (SHIFT))\n#endif // AMDHSA_BITS_ENUM_ENTRY\n\n// Gets bits for specified bit mask from specified source.\n#ifndef AMDHSA_BITS_GET\n#define AMDHSA_BITS_GET(SRC, MSK) ((SRC & MSK) >> MSK ## _SHIFT)\n#endif // AMDHSA_BITS_GET\n\n// Sets bits for specified bit mask in specified destination.\n#ifndef AMDHSA_BITS_SET\n#define AMDHSA_BITS_SET(DST, MSK, VAL)  \\\n  DST &= ~MSK;                          \\\n  DST |= ((VAL << MSK ## _SHIFT) & MSK)\n#endif // AMDHSA_BITS_SET\n\nnamespace rocr {\nnamespace llvm {\nnamespace amdhsa {\n\n// Floating point rounding modes. Must match hardware definition.\nenum : uint8_t {\n  FLOAT_ROUND_MODE_NEAR_EVEN = 0,\n  FLOAT_ROUND_MODE_PLUS_INFINITY = 1,\n  FLOAT_ROUND_MODE_MINUS_INFINITY = 2,\n  FLOAT_ROUND_MODE_ZERO = 3,\n};\n\n// Floating point denorm modes. Must match hardware definition.\nenum : uint8_t {\n  FLOAT_DENORM_MODE_FLUSH_SRC_DST = 0,\n  FLOAT_DENORM_MODE_FLUSH_DST = 1,\n  FLOAT_DENORM_MODE_FLUSH_SRC = 2,\n  FLOAT_DENORM_MODE_FLUSH_NONE = 3,\n};\n\n// System VGPR workitem IDs. Must match hardware definition.\nenum : uint8_t {\n  SYSTEM_VGPR_WORKITEM_ID_X = 0,\n  SYSTEM_VGPR_WORKITEM_ID_X_Y = 1,\n  SYSTEM_VGPR_WORKITEM_ID_X_Y_Z = 2,\n  SYSTEM_VGPR_WORKITEM_ID_UNDEFINED = 3,\n};\n\n// Compute program resource register 1. Must match hardware definition.\n#define COMPUTE_PGM_RSRC1(NAME, SHIFT, WIDTH) \\\n  AMDHSA_BITS_ENUM_ENTRY(COMPUTE_PGM_RSRC1_ ## NAME, SHIFT, WIDTH)\nenum : int32_t {\n  COMPUTE_PGM_RSRC1(GRANULATED_WORKITEM_VGPR_COUNT, 0, 6),\n  COMPUTE_PGM_RSRC1(GRANULATED_WAVEFRONT_SGPR_COUNT, 6, 4),\n  COMPUTE_PGM_RSRC1(PRIORITY, 10, 2),\n  COMPUTE_PGM_RSRC1(FLOAT_ROUND_MODE_32, 12, 2),\n  COMPUTE_PGM_RSRC1(FLOAT_ROUND_MODE_16_64, 14, 2),\n  COMPUTE_PGM_RSRC1(FLOAT_DENORM_MODE_32, 16, 2),\n  COMPUTE_PGM_RSRC1(FLOAT_DENORM_MODE_16_64, 18, 2),\n  COMPUTE_PGM_RSRC1(PRIV, 20, 1),\n  COMPUTE_PGM_RSRC1(ENABLE_DX10_CLAMP, 21, 1),\n  COMPUTE_PGM_RSRC1(DEBUG_MODE, 22, 1),\n  COMPUTE_PGM_RSRC1(ENABLE_IEEE_MODE, 23, 1),\n  COMPUTE_PGM_RSRC1(BULKY, 24, 1),\n  COMPUTE_PGM_RSRC1(CDBG_USER, 25, 1),\n  COMPUTE_PGM_RSRC1(FP16_OVFL, 26, 1),    // GFX9+\n  COMPUTE_PGM_RSRC1(RESERVED0, 27, 2),\n  COMPUTE_PGM_RSRC1(WGP_MODE, 29, 1),     // GFX10+\n  COMPUTE_PGM_RSRC1(MEM_ORDERED, 30, 1),  // GFX10+\n  COMPUTE_PGM_RSRC1(FWD_PROGRESS, 31, 1), // GFX10+\n};\n#undef COMPUTE_PGM_RSRC1\n\n// Compute program resource register 2. Must match hardware definition.\n#define COMPUTE_PGM_RSRC2(NAME, SHIFT, WIDTH) \\\n  AMDHSA_BITS_ENUM_ENTRY(COMPUTE_PGM_RSRC2_ ## NAME, SHIFT, WIDTH)\nenum : int32_t {\n  COMPUTE_PGM_RSRC2(ENABLE_PRIVATE_SEGMENT, 0, 1),\n  COMPUTE_PGM_RSRC2(USER_SGPR_COUNT, 1, 5),\n  COMPUTE_PGM_RSRC2(ENABLE_TRAP_HANDLER, 6, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_SGPR_WORKGROUP_ID_X, 7, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_SGPR_WORKGROUP_ID_Y, 8, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_SGPR_WORKGROUP_ID_Z, 9, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_SGPR_WORKGROUP_INFO, 10, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_VGPR_WORKITEM_ID, 11, 2),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_ADDRESS_WATCH, 13, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_MEMORY, 14, 1),\n  COMPUTE_PGM_RSRC2(GRANULATED_LDS_SIZE, 15, 9),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION, 24, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_FP_DENORMAL_SOURCE, 25, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO, 26, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW, 27, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW, 28, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_IEEE_754_FP_INEXACT, 29, 1),\n  COMPUTE_PGM_RSRC2(ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO, 30, 1),\n  COMPUTE_PGM_RSRC2(RESERVED0, 31, 1),\n};\n#undef COMPUTE_PGM_RSRC2\n\n// Compute program resource register 3 for GFX90A+. Must match hardware\n// definition.\n#define COMPUTE_PGM_RSRC3_GFX90A(NAME, SHIFT, WIDTH) \\\n  AMDHSA_BITS_ENUM_ENTRY(COMPUTE_PGM_RSRC3_GFX90A_ ## NAME, SHIFT, WIDTH)\nenum : int32_t {\n  COMPUTE_PGM_RSRC3_GFX90A(ACCUM_OFFSET, 0, 6),\n  COMPUTE_PGM_RSRC3_GFX90A(RESERVED0, 6, 10),\n  COMPUTE_PGM_RSRC3_GFX90A(TG_SPLIT, 16, 1),\n  COMPUTE_PGM_RSRC3_GFX90A(RESERVED1, 17, 15),\n};\n#undef COMPUTE_PGM_RSRC3_GFX90A\n\n// Compute program resource register 3 for GFX10+. Must match hardware\n// definition.\n#define COMPUTE_PGM_RSRC3_GFX10_PLUS(NAME, SHIFT, WIDTH) \\\n  AMDHSA_BITS_ENUM_ENTRY(COMPUTE_PGM_RSRC3_GFX10_PLUS_ ## NAME, SHIFT, WIDTH)\nenum : int32_t {\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(SHARED_VGPR_COUNT, 0, 4), // GFX10+\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(INST_PREF_SIZE, 4, 6),    // GFX11+\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(TRAP_ON_START, 10, 1),    // GFX11+\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(TRAP_ON_END, 11, 1),      // GFX11+\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(RESERVED0, 12, 19),\n  COMPUTE_PGM_RSRC3_GFX10_PLUS(IMAGE_OP, 31, 1),         // GFX11+\n};\n#undef COMPUTE_PGM_RSRC3_GFX10_PLUS\n\n// Kernel code properties. Must be kept backwards compatible.\n#define KERNEL_CODE_PROPERTY(NAME, SHIFT, WIDTH) \\\n  AMDHSA_BITS_ENUM_ENTRY(KERNEL_CODE_PROPERTY_ ## NAME, SHIFT, WIDTH)\nenum : int32_t {\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER, 0, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_DISPATCH_PTR, 1, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_QUEUE_PTR, 2, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_KERNARG_SEGMENT_PTR, 3, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_DISPATCH_ID, 4, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_FLAT_SCRATCH_INIT, 5, 1),\n  KERNEL_CODE_PROPERTY(ENABLE_SGPR_PRIVATE_SEGMENT_SIZE, 6, 1),\n  KERNEL_CODE_PROPERTY(RESERVED0, 7, 3),\n  KERNEL_CODE_PROPERTY(ENABLE_WAVEFRONT_SIZE32, 10, 1), // GFX10+\n  KERNEL_CODE_PROPERTY(USES_DYNAMIC_STACK, 11, 1),\n  KERNEL_CODE_PROPERTY(RESERVED1, 12, 4),\n};\n#undef KERNEL_CODE_PROPERTY\n\n// Kernel descriptor. Must be kept backwards compatible.\nstruct kernel_descriptor_t {\n  uint32_t group_segment_fixed_size;\n  uint32_t private_segment_fixed_size;\n  uint32_t kernarg_size;\n  uint8_t reserved0[4];\n  int64_t kernel_code_entry_byte_offset;\n  uint8_t reserved1[20];\n  uint32_t compute_pgm_rsrc3; // GFX10+ and GFX90A+\n  uint32_t compute_pgm_rsrc1;\n  uint32_t compute_pgm_rsrc2;\n  uint16_t kernel_code_properties;\n  uint8_t reserved2[6];\n};\n\nenum : uint32_t {\n  GROUP_SEGMENT_FIXED_SIZE_OFFSET = 0,\n  PRIVATE_SEGMENT_FIXED_SIZE_OFFSET = 4,\n  KERNARG_SIZE_OFFSET = 8,\n  RESERVED0_OFFSET = 12,\n  KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET = 16,\n  RESERVED1_OFFSET = 24,\n  COMPUTE_PGM_RSRC3_OFFSET = 44,\n  COMPUTE_PGM_RSRC1_OFFSET = 48,\n  COMPUTE_PGM_RSRC2_OFFSET = 52,\n  KERNEL_CODE_PROPERTIES_OFFSET = 56,\n  RESERVED2_OFFSET = 58,\n};\n\nstatic_assert(\n    sizeof(kernel_descriptor_t) == 64,\n    \"invalid size for kernel_descriptor_t\");\nstatic_assert(offsetof(kernel_descriptor_t, group_segment_fixed_size) ==\n                  GROUP_SEGMENT_FIXED_SIZE_OFFSET,\n              \"invalid offset for group_segment_fixed_size\");\nstatic_assert(offsetof(kernel_descriptor_t, private_segment_fixed_size) ==\n                  PRIVATE_SEGMENT_FIXED_SIZE_OFFSET,\n              \"invalid offset for private_segment_fixed_size\");\nstatic_assert(offsetof(kernel_descriptor_t, kernarg_size) ==\n                  KERNARG_SIZE_OFFSET,\n              \"invalid offset for kernarg_size\");\nstatic_assert(offsetof(kernel_descriptor_t, reserved0) == RESERVED0_OFFSET,\n              \"invalid offset for reserved0\");\nstatic_assert(offsetof(kernel_descriptor_t, kernel_code_entry_byte_offset) ==\n                  KERNEL_CODE_ENTRY_BYTE_OFFSET_OFFSET,\n              \"invalid offset for kernel_code_entry_byte_offset\");\nstatic_assert(offsetof(kernel_descriptor_t, reserved1) == RESERVED1_OFFSET,\n              \"invalid offset for reserved1\");\nstatic_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc3) ==\n                  COMPUTE_PGM_RSRC3_OFFSET,\n              \"invalid offset for compute_pgm_rsrc3\");\nstatic_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc1) ==\n                  COMPUTE_PGM_RSRC1_OFFSET,\n              \"invalid offset for compute_pgm_rsrc1\");\nstatic_assert(offsetof(kernel_descriptor_t, compute_pgm_rsrc2) ==\n                  COMPUTE_PGM_RSRC2_OFFSET,\n              \"invalid offset for compute_pgm_rsrc2\");\nstatic_assert(offsetof(kernel_descriptor_t, kernel_code_properties) ==\n                  KERNEL_CODE_PROPERTIES_OFFSET,\n              \"invalid offset for kernel_code_properties\");\nstatic_assert(offsetof(kernel_descriptor_t, reserved2) == RESERVED2_OFFSET,\n              \"invalid offset for reserved2\");\n\n} // end namespace amdhsa\n} // end namespace llvm\n} // end namespace rocr\n\n#endif // LLVM_SUPPORT_AMDHSAKERNELDESCRIPTOR_H\n"
  },
  {
    "path": "runtime/hsa-runtime/loader/executable.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"executable.hpp\"\n\n#include <libelf.h>\n#include <limits.h>\n#include <link.h>\n#include <unistd.h>\n\n#include <algorithm>\n#include <cstddef>\n#include <cstring>\n#include <iomanip>\n#include <iostream>\n#include <atomic>\n#include <fstream>\n#include \"inc/amd_hsa_elf.h\"\n#include \"inc/amd_hsa_kernel_code.h\"\n#include \"core/inc/amd_hsa_code.hpp\"\n#include \"amd_hsa_code_util.hpp\"\n#include \"amd_options.hpp\"\n#include \"core/util/utils.h\"\n\n#include \"AMDHSAKernelDescriptor.h\"\n\nusing namespace rocr::amd::hsa;\nusing namespace rocr::amd::hsa::common;\n\n// r_version history:\n// 1: Initial debug protocol\n// 2: New trap handler ABI. The reason for halting a wave is recorded in ttmp11[8:7].\n// 3: New trap handler ABI. A wave halted at S_ENDPGM rewinds its PC by 8 bytes, and sets ttmp11[9]=1.\n// 4: New trap handler ABI. Save the trap id in ttmp11[16:9]\n// 5: New trap handler ABI. Save the PC in ttmp11[22:7] ttmp6[31:0], and park the wave if stopped\n// 6: New trap handler ABI. ttmp6[25:0] contains dispatch index modulo queue size\n// 7: New trap handler ABI. Send interrupts as a bitmask, coalescing concurrent exceptions.\n// 8: New trap handler ABI. for gfx942: Initialize ttmp[4:5] if ttmp11[31] == 0.\n// 9: New trap handler ABI. For gfx11: Save PC in ttmp11[22:7] ttmp6[31:0], and park the wave if stopped.\n// 10: New trap handler ABI. Set status.skip_export when halting the wave.\n//                           For gfx942, set ttmp6[31] = 0 if ttmp11[31] == 0.\n\nHSA_API r_debug _amdgpu_r_debug;\nstatic __forceinline link_map*& r_debug_tail() {\n  static link_map* r_debug_tail_ = nullptr;\n  return r_debug_tail_;\n}\n\nnamespace rocr {\n  // Having a side effect prevents call site optimization that allows removal of a noinline function call\n  // with no side effect.\n__attribute__((noinline)) void _loader_debug_state() {\n  static volatile int function_needs_a_side_effect = 0;\n  function_needs_a_side_effect ^= 1;\n}\n\nnamespace amd {\nnamespace hsa {\nnamespace loader {\n\nclass LoaderOptions {\npublic:\n  explicit LoaderOptions(std::ostream &error = std::cerr);\n\n  const amd::options::NoArgOption* Help() const { return &help; }\n  const amd::options::NoArgOption* DumpCode() const { return &dump_code; }\n  const amd::options::NoArgOption* DumpIsa() const { return &dump_isa; }\n  const amd::options::NoArgOption* DumpExec() const { return &dump_exec; }\n  const amd::options::NoArgOption* DumpAll() const { return &dump_all; }\n  const amd::options::ValueOption<std::string>* DumpDir() const { return &dump_dir; }\n  const amd::options::PrefixOption* Substitute() const { return &substitute; }\n\n  bool ParseOptions(const std::string& options);\n  void Reset();\n  void PrintHelp(std::ostream& out) const;\n\nprivate:\n  /// @brief Copy constructor - not available.\n  LoaderOptions(const LoaderOptions&);\n\n  /// @brief Assignment operator - not available.\n  LoaderOptions& operator=(const LoaderOptions&);\n\n  amd::options::NoArgOption help;\n  amd::options::NoArgOption dump_code;\n  amd::options::NoArgOption dump_isa;\n  amd::options::NoArgOption dump_exec;\n  amd::options::NoArgOption dump_all;\n  amd::options::ValueOption<std::string> dump_dir;\n  amd::options::PrefixOption substitute;\n  amd::options::OptionParser option_parser;\n};\n\nLoaderOptions::LoaderOptions(std::ostream& error) :\n  help(\"help\", \"print help\"),\n  dump_code(\"dump-code\", \"Dump finalizer output code object\"),\n  dump_isa(\"dump-isa\", \"Dump finalizer output to ISA text file\"),\n  dump_exec(\"dump-exec\", \"Dump executable to text file\"),\n  dump_all(\"dump-all\", \"Dump all finalizer input and output (as above)\"),\n  dump_dir(\"dump-dir\", \"Dump directory\"),\n  substitute(\"substitute\", \"Substitute code object with given index or index range on loading from file\"),\n  option_parser(false, error)\n{\n  option_parser.AddOption(&help);\n  option_parser.AddOption(&dump_code);\n  option_parser.AddOption(&dump_isa);\n  option_parser.AddOption(&dump_exec);\n  option_parser.AddOption(&dump_all);\n  option_parser.AddOption(&dump_dir);\n  option_parser.AddOption(&substitute);\n}\n\nbool LoaderOptions::ParseOptions(const std::string& options)\n{\n  return option_parser.ParseOptions(options.c_str());\n}\n\nvoid LoaderOptions::Reset()\n{\n  option_parser.Reset();\n}\n\nvoid LoaderOptions::PrintHelp(std::ostream& out) const\n{\n  option_parser.PrintHelp(out);\n}\n\nstatic const char *LOADER_DUMP_PREFIX = \"amdcode\";\n\nLoader* Loader::Create(Context* context)\n{\n  return new AmdHsaCodeLoader(context);\n}\n\nvoid Loader::Destroy(Loader *loader)\n{\n  // Loader resets the link_map, but the executables and loaded code objects are not deleted.\n  _amdgpu_r_debug.r_map = nullptr;\n  _amdgpu_r_debug.r_state = r_debug::RT_CONSISTENT;\n  r_debug_tail() = nullptr;\n  delete loader;\n}\n\nExecutable* AmdHsaCodeLoader::CreateExecutable(\n  hsa_profile_t profile, const char *options, hsa_default_float_rounding_mode_t default_float_rounding_mode)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n\n  executables.push_back(new ExecutableImpl(profile, context, executables.size(), default_float_rounding_mode));\n  return executables.back();\n}\n\nExecutable* AmdHsaCodeLoader::CreateExecutable(\n      std::unique_ptr<Context> isolated_context,\n      hsa_profile_t profile,\n      const char *options,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n\n  executables.push_back(new ExecutableImpl(profile, std::move(isolated_context), executables.size(), default_float_rounding_mode));\n  return executables.back();\n}\n\nstatic void AddCodeObjectInfoIntoDebugMap(link_map* map) {\n  if (r_debug_tail()) {\n      r_debug_tail()->l_next = map;\n      map->l_prev = r_debug_tail();\n      map->l_next = nullptr;\n  } else {\n      _amdgpu_r_debug.r_map = map;\n      map->l_prev = nullptr;\n      map->l_next = nullptr;\n  }\n  r_debug_tail() = map;\n}\n\nstatic void RemoveCodeObjectInfoFromDebugMap(link_map* map) {\n  if (r_debug_tail() == map) {\n      r_debug_tail() = map->l_prev;\n  }\n  if (_amdgpu_r_debug.r_map == map) {\n      _amdgpu_r_debug.r_map = map->l_next;\n  }\n\n  if (map->l_prev) {\n      map->l_prev->l_next = map->l_next;\n  }\n  if (map->l_next) {\n      map->l_next->l_prev = map->l_prev;\n  }\n\n  free(map->l_name);\n  memset(map, 0, sizeof(link_map));\n}\n\nhsa_status_t AmdHsaCodeLoader::FreezeExecutable(Executable *executable, const char *options) {\n  hsa_status_t  status = executable->Freeze(options);\n  if (status != HSA_STATUS_SUCCESS) {\n    return status;\n  }\n\n  // Assuming runtime atomic implements C++ std::memory_order\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  atomic::Store(&_amdgpu_r_debug.r_state, r_debug::RT_ADD, std::memory_order_relaxed);\n  atomic::Fence(std::memory_order_acq_rel);\n  _loader_debug_state();\n  atomic::Fence(std::memory_order_acq_rel);\n  for (auto &lco : reinterpret_cast<ExecutableImpl*>(executable)->loaded_code_objects) {\n    AddCodeObjectInfoIntoDebugMap(&(lco->r_debug_info));\n  }\n  atomic::Store(&_amdgpu_r_debug.r_state, r_debug::RT_CONSISTENT, std::memory_order_release);\n  _loader_debug_state();\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid AmdHsaCodeLoader::DestroyExecutable(Executable *executable) {\n  // Assuming runtime atomic implements C++ std::memory_order\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  atomic::Store(&_amdgpu_r_debug.r_state, r_debug::RT_DELETE, std::memory_order_relaxed);\n  atomic::Fence(std::memory_order_acq_rel);\n  _loader_debug_state();\n  atomic::Fence(std::memory_order_acq_rel);\n  for (auto &lco : reinterpret_cast<ExecutableImpl*>(executable)->loaded_code_objects) {\n    RemoveCodeObjectInfoFromDebugMap(&(lco->r_debug_info));\n  }\n  atomic::Store(&_amdgpu_r_debug.r_state, r_debug::RT_CONSISTENT, std::memory_order_release);\n  _loader_debug_state();\n\n  executables[((ExecutableImpl*)executable)->id()] = nullptr;\n  delete executable;\n}\n\nhsa_status_t AmdHsaCodeLoader::IterateExecutables(\n  hsa_status_t (*callback)(\n    hsa_executable_t executable,\n    void *data),\n  void *data)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  assert(callback);\n\n  for (auto &exec : executables) {\n    if(exec != nullptr){\n      hsa_status_t status = callback(Executable::Handle(exec), data);\n      if (status != HSA_STATUS_SUCCESS) {\n        return status;\n      }\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t AmdHsaCodeLoader::QuerySegmentDescriptors(\n  hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n  size_t *num_segment_descriptors)\n{\n  if (!num_segment_descriptors) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  if (*num_segment_descriptors == 0 && segment_descriptors) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  if (*num_segment_descriptors != 0 && !segment_descriptors) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  this->EnableReadOnlyMode();\n\n  size_t actual_num_segment_descriptors = 0;\n  for (auto &executable : executables) {\n    if (executable) {\n      actual_num_segment_descriptors += executable->GetNumSegmentDescriptors();\n    }\n  }\n\n  if (*num_segment_descriptors == 0) {\n    *num_segment_descriptors = actual_num_segment_descriptors;\n    this->DisableReadOnlyMode();\n    return HSA_STATUS_SUCCESS;\n  }\n  if (*num_segment_descriptors != actual_num_segment_descriptors) {\n    this->DisableReadOnlyMode();\n    return HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n  }\n\n  size_t i = 0;\n  for (auto &executable : executables) {\n    if (executable) {\n      i += executable->QuerySegmentDescriptors(segment_descriptors, actual_num_segment_descriptors, i);\n    }\n  }\n\n  this->DisableReadOnlyMode();\n  return HSA_STATUS_SUCCESS;\n}\n\nuint64_t AmdHsaCodeLoader::FindHostAddress(uint64_t device_address)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  if (device_address == 0) {\n    return 0;\n  }\n\n  for (auto &exec : executables) {\n    if (exec != nullptr) {\n      uint64_t host_address = exec->FindHostAddress(device_address);\n      if (host_address != 0) {\n        return host_address;\n      }\n    }\n  }\n  return 0;\n}\n\nvoid AmdHsaCodeLoader::PrintHelp(std::ostream& out)\n{\n  LoaderOptions().PrintHelp(out);\n}\n\nvoid AmdHsaCodeLoader::EnableReadOnlyMode()\n{\n  rw_lock_.ReaderLock();\n  for (auto &executable : executables) {\n    if (executable) {\n      ((ExecutableImpl*)executable)->EnableReadOnlyMode();\n    }\n  }\n}\n\nvoid AmdHsaCodeLoader::DisableReadOnlyMode()\n{\n  rw_lock_.ReaderUnlock();\n  for (auto &executable : executables) {\n    if (executable) {\n      ((ExecutableImpl*)executable)->DisableReadOnlyMode();\n    }\n  }\n}\n\n//===----------------------------------------------------------------------===//\n// SymbolImpl.                                                                    //\n//===----------------------------------------------------------------------===//\n\nbool SymbolImpl::GetInfo(hsa_symbol_info32_t symbol_info, void *value) {\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_TYPE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_TYPE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_TYPE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_TYPE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_NAME_LENGTH) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_NAME) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_NAME)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_MODULE_NAME_LENGTH) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_MODULE_NAME_LENGTH)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_MODULE_NAME) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_MODULE_NAME)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_LINKAGE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_LINKAGE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_IS_DEFINITION) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_IS_DEFINITION)),\n    \"attributes are not compatible\"\n  );\n\n  assert(value);\n\n  switch (symbol_info) {\n    case HSA_CODE_SYMBOL_INFO_TYPE: {\n      *((hsa_symbol_kind_t*)value) = kind;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_NAME_LENGTH: {\n      *((uint32_t*)value) = symbol_name.size();\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_NAME: {\n      memset(value, 0x0, symbol_name.size());\n      memcpy(value, symbol_name.c_str(), symbol_name.size());\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_MODULE_NAME_LENGTH: {\n      *((uint32_t*)value) = module_name.size();\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_MODULE_NAME: {\n      memset(value, 0x0, module_name.size());\n      memcpy(value, module_name.c_str(), module_name.size());\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_LINKAGE: {\n      *((hsa_symbol_linkage_t*)value) = linkage;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_IS_DEFINITION: {\n      *((bool*)value) = is_definition;\n      break;\n    }\n    case HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_CALL_CONVENTION: {\n      *((uint32_t*)value) = 0;\n      break;\n    }\n    case HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT:\n    case HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ADDRESS: {\n      if (!is_loaded) {\n        return false;\n      }\n      *((uint64_t*)value) = address;\n      break;\n    }\n    case HSA_EXECUTABLE_SYMBOL_INFO_AGENT: {\n      if (!is_loaded) {\n        return false;\n      }\n      *((hsa_agent_t*)value) = agent;\n      break;\n    }\n    default: {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n//===----------------------------------------------------------------------===//\n// KernelSymbol.                                                              //\n//===----------------------------------------------------------------------===//\n\nbool KernelSymbol::GetInfo(hsa_symbol_info32_t symbol_info, void *value) {\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK)),\n    \"attributes are not compatible\"\n  );\n\n  assert(value);\n\n  switch (symbol_info) {\n    case HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE: {\n      *((uint32_t*)value) = kernarg_segment_size;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_ALIGNMENT: {\n      *((uint32_t*)value) = kernarg_segment_alignment;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE: {\n      *((uint32_t*)value) = group_segment_size;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE: {\n      *((uint32_t*)value) = private_segment_size;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_KERNEL_DYNAMIC_CALLSTACK: {\n      *((bool*)value) = is_dynamic_callstack;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_KERNEL_WAVEFRONT_SIZE: {\n      *((uint32_t*)value) = wavefront_size;\n      break;\n    }\n    case HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_SIZE: {\n      *((uint32_t*)value) = size;\n      break;\n    }\n    case HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_ALIGN: {\n      *((uint32_t*)value) = alignment;\n      break;\n    }\n    default: {\n      return SymbolImpl::GetInfo(symbol_info, value);\n    }\n  }\n\n  return true;\n}\n\n//===----------------------------------------------------------------------===//\n// VariableSymbol.                                                            //\n//===----------------------------------------------------------------------===//\n\nbool VariableSymbol::GetInfo(hsa_symbol_info32_t symbol_info, void *value) {\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_VARIABLE_ALLOCATION) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ALLOCATION)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_VARIABLE_SEGMENT) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SEGMENT)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_VARIABLE_ALIGNMENT) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ALIGNMENT)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_VARIABLE_SIZE) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SIZE)),\n    \"attributes are not compatible\"\n  );\n  static_assert(\n    (symbol_attribute32_t(HSA_CODE_SYMBOL_INFO_VARIABLE_IS_CONST) ==\n     symbol_attribute32_t(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_IS_CONST)),\n    \"attributes are not compatible\"\n  );\n\n  switch (symbol_info) {\n    case HSA_CODE_SYMBOL_INFO_VARIABLE_ALLOCATION: {\n      *((hsa_variable_allocation_t*)value) = allocation;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_VARIABLE_SEGMENT: {\n      *((hsa_variable_segment_t*)value) = segment;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_VARIABLE_ALIGNMENT: {\n      *((uint32_t*)value) = alignment;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_VARIABLE_SIZE: {\n      *((uint32_t*)value) = size;\n      break;\n    }\n    case HSA_CODE_SYMBOL_INFO_VARIABLE_IS_CONST: {\n      *((bool*)value) = is_constant;\n      break;\n    }\n    default: {\n      return SymbolImpl::GetInfo(symbol_info, value);\n    }\n  }\n\n  return true;\n}\n\nbool LoadedCodeObjectImpl::GetInfo(amd_loaded_code_object_info_t attribute, void *value)\n{\n  assert(value);\n\n  switch (attribute) {\n    case AMD_LOADED_CODE_OBJECT_INFO_ELF_IMAGE:\n      ((hsa_code_object_t*)value)->handle = reinterpret_cast<uint64_t>(elf_data);\n      break;\n    case AMD_LOADED_CODE_OBJECT_INFO_ELF_IMAGE_SIZE:\n      *((size_t*)value) = elf_size;\n      break;\n    default: {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nhsa_status_t LoadedCodeObjectImpl::IterateLoadedSegments(\n  hsa_status_t (*callback)(\n    amd_loaded_segment_t loaded_segment,\n    void *data),\n  void *data)\n{\n  assert(callback);\n\n  for (auto &loaded_segment : loaded_segments) {\n    hsa_status_t status = callback(LoadedSegment::Handle(loaded_segment), data);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid LoadedCodeObjectImpl::Print(std::ostream& out)\n{\n  out << \"Code Object\" << std::endl;\n}\n\nbool Segment::GetInfo(amd_loaded_segment_info_t attribute, void *value)\n{\n  assert(value);\n\n  switch (attribute) {\n    case AMD_LOADED_SEGMENT_INFO_TYPE: {\n      *((amdgpu_hsa_elf_segment_t*)value) = segment;\n      break;\n    }\n    case AMD_LOADED_SEGMENT_INFO_ELF_BASE_ADDRESS: {\n      *((uint64_t*)value) = vaddr;\n      break;\n    }\n    case AMD_LOADED_SEGMENT_INFO_LOAD_BASE_ADDRESS: {\n      *((uint64_t*)value) = reinterpret_cast<uint64_t>(this->Address(this->VAddr()));\n      break;\n    }\n    case AMD_LOADED_SEGMENT_INFO_SIZE: {\n      *((size_t*)value) = size;\n      break;\n    }\n    default: {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nuint64_t Segment::Offset(uint64_t addr)\n{\n  assert(IsAddressInSegment(addr));\n  return addr - vaddr;\n}\n\nvoid* Segment::Address(uint64_t addr)\n{\n  return owner->context()->SegmentAddress(segment, agent, ptr, Offset(addr));\n}\n\nbool Segment::Freeze()\n{\n  return !frozen ? (frozen = owner->context()->SegmentFreeze(segment, agent, ptr, size)) : true;\n}\n\nbool Segment::IsAddressInSegment(uint64_t addr)\n{\n  return vaddr <= addr && addr < vaddr + size;\n}\n\nvoid Segment::Copy(uint64_t addr, const void* src, size_t size)\n{\n  // loader must do copies before freezing.\n  assert(!frozen);\n\n  if (size > 0) {\n    owner->context()->SegmentCopy(segment, agent, ptr, Offset(addr), src, size);\n  }\n}\n\nvoid Segment::Print(std::ostream& out)\n{\n  out << \"Segment\" << std::endl\n    << \"    Type: \" << AmdHsaElfSegmentToString(segment)\n    << \"    Size: \" << size\n    << \"    VAddr: \" << vaddr << std::endl\n    << \"    Ptr: \" << std::hex << ptr << std::dec\n    << std::endl;\n}\n\nvoid Segment::Destroy()\n{\n  owner->context()->SegmentFree(segment, agent, ptr, size);\n}\n\n//===----------------------------------------------------------------------===//\n// ExecutableImpl.                                                                //\n//===----------------------------------------------------------------------===//\n\nExecutableImpl::ExecutableImpl(\n    const hsa_profile_t &_profile,\n    Context *context,\n    size_t id,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode)\n  : Executable()\n  , profile_(_profile)\n  , context_(context)\n  , id_(id)\n  , default_float_rounding_mode_(default_float_rounding_mode)\n  , state_(HSA_EXECUTABLE_STATE_UNFROZEN)\n  , program_allocation_segment(nullptr)\n{\n}\n\nExecutableImpl::ExecutableImpl(\n    const hsa_profile_t &_profile,\n    std::unique_ptr<Context> unique_context,\n    size_t id,\n    hsa_default_float_rounding_mode_t default_float_rounding_mode)\n  : Executable()\n  , profile_(_profile)\n  , unique_context_(std::move(unique_context))\n  , id_(id)\n  , default_float_rounding_mode_(default_float_rounding_mode)\n  , state_(HSA_EXECUTABLE_STATE_UNFROZEN)\n  , program_allocation_segment(nullptr)\n{\n  context_ = unique_context_.get();\n}\n\nExecutableImpl::~ExecutableImpl() {\n  for (ExecutableObject* o : objects) {\n    o->Destroy();\n    delete o;\n  }\n  objects.clear();\n\n  for (auto &symbol_entry : program_symbols_) {\n    delete symbol_entry.second;\n  }\n  for (auto &symbol_entry : agent_symbols_) {\n    delete symbol_entry.second;\n  }\n}\n\nhsa_status_t ExecutableImpl::DefineProgramExternalVariable(\n  const char *name, void *address)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  assert(name);\n\n  if (HSA_EXECUTABLE_STATE_FROZEN == state_) {\n    return HSA_STATUS_ERROR_FROZEN_EXECUTABLE;\n  }\n\n  auto symbol_entry = program_symbols_.find(std::string(name));\n  if (symbol_entry != program_symbols_.end()) {\n    return HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED;\n  }\n\n  program_symbols_.insert(\n    std::make_pair(std::string(name),\n                   new VariableSymbol(true,\n                                      \"\", // Only program linkage symbols can be\n                                          // defined.\n                                      std::string(name),\n                                      HSA_SYMBOL_LINKAGE_PROGRAM,\n                                      true,\n                                      HSA_VARIABLE_ALLOCATION_PROGRAM,\n                                      HSA_VARIABLE_SEGMENT_GLOBAL,\n                                      0,     // TODO: size.\n                                      0,     // TODO: align.\n                                      false, // TODO: const.\n                                      true,\n                                      reinterpret_cast<uint64_t>(address))));\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::DefineAgentExternalVariable(\n  const char *name,\n  hsa_agent_t agent,\n  hsa_variable_segment_t segment,\n  void *address)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  assert(name);\n\n  if (HSA_EXECUTABLE_STATE_FROZEN == state_) {\n    return HSA_STATUS_ERROR_FROZEN_EXECUTABLE;\n  }\n\n  auto symbol_entry = agent_symbols_.find(std::make_pair(std::string(name), agent));\n  if (symbol_entry != agent_symbols_.end()) {\n    return HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED;\n  }\n\n  auto insert_status = agent_symbols_.insert(\n    std::make_pair(std::make_pair(std::string(name), agent),\n                   new VariableSymbol(true,\n                                      \"\", // Only program linkage symbols can be\n                                          // defined.\n                                      std::string(name),\n                                      HSA_SYMBOL_LINKAGE_PROGRAM,\n                                      true,\n                                      HSA_VARIABLE_ALLOCATION_AGENT,\n                                      segment,\n                                      0,     // TODO: size.\n                                      0,     // TODO: align.\n                                      false, // TODO: const.\n                                      true,\n                                      reinterpret_cast<uint64_t>(address))));\n  assert(insert_status.second);\n  insert_status.first->second->agent = agent;\n\n  return HSA_STATUS_SUCCESS;\n}\n\nbool ExecutableImpl::IsProgramSymbol(const char *symbol_name) {\n  assert(symbol_name);\n\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  return program_symbols_.find(std::string(symbol_name)) != program_symbols_.end();\n}\n\nSymbol* ExecutableImpl::GetSymbol(\n  const char *symbol_name,\n  const hsa_agent_t *agent)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  return this->GetSymbolInternal(symbol_name, agent);\n}\n\nSymbol* ExecutableImpl::GetSymbolInternal(\n  const char *symbol_name,\n  const hsa_agent_t *agent)\n{\n  assert(symbol_name);\n\n  std::string mangled_name = std::string(symbol_name);\n  if (mangled_name.empty()) {\n    return nullptr;\n  }\n\n  if (!agent) {\n    auto program_symbol = program_symbols_.find(mangled_name);\n    if (program_symbol != program_symbols_.end()) {\n      return program_symbol->second;\n    }\n    return nullptr;\n  }\n\n  auto agent_symbol = agent_symbols_.find(std::make_pair(mangled_name, *agent));\n  if (agent_symbol != agent_symbols_.end()) {\n    return agent_symbol->second;\n  }\n  return nullptr;\n}\n\nhsa_status_t ExecutableImpl::IterateSymbols(\n  iterate_symbols_f callback, void *data)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  assert(callback);\n\n  for (auto &symbol_entry : program_symbols_) {\n    hsa_status_t hsc =\n      callback(Executable::Handle(this), Symbol::Handle(symbol_entry.second), data);\n    if (HSA_STATUS_SUCCESS != hsc) {\n      return hsc;\n    }\n  }\n  for (auto &symbol_entry : agent_symbols_) {\n    hsa_status_t hsc =\n      callback(Executable::Handle(this), Symbol::Handle(symbol_entry.second), data);\n    if (HSA_STATUS_SUCCESS != hsc) {\n      return hsc;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::IterateAgentSymbols(\n    hsa_agent_t agent,\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_agent_t agent,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  assert(callback);\n\n  for (auto &symbol_entry : agent_symbols_) {\n    if (symbol_entry.second->GetAgent().handle != agent.handle) {\n      continue;\n    }\n\n    hsa_status_t status = callback(\n        Executable::Handle(this), agent, Symbol::Handle(symbol_entry.second),\n        data);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::IterateProgramSymbols(\n    hsa_status_t (*callback)(hsa_executable_t exec,\n                             hsa_executable_symbol_t symbol,\n                             void *data),\n    void *data) {\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  assert(callback);\n\n  for (auto &symbol_entry : program_symbols_) {\n    hsa_status_t status = callback(\n        Executable::Handle(this), Symbol::Handle(symbol_entry.second), data);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::IterateLoadedCodeObjects(\n  hsa_status_t (*callback)(\n    hsa_executable_t executable,\n    hsa_loaded_code_object_t loaded_code_object,\n    void *data),\n  void *data)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  assert(callback);\n\n  for (auto &loaded_code_object : loaded_code_objects) {\n    hsa_status_t status = callback(\n        Executable::Handle(this),\n        LoadedCodeObject::Handle(loaded_code_object),\n        data);\n    if (status != HSA_STATUS_SUCCESS) {\n      return status;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nsize_t ExecutableImpl::GetNumSegmentDescriptors()\n{\n  // assuming we are in readonly mode.\n  size_t actual_num_segment_descriptors = 0;\n  for (auto &obj : loaded_code_objects) {\n    actual_num_segment_descriptors += obj->LoadedSegments().size();\n  }\n  return actual_num_segment_descriptors;\n}\n\nsize_t ExecutableImpl::QuerySegmentDescriptors(\n  hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n  size_t total_num_segment_descriptors,\n  size_t first_empty_segment_descriptor)\n{\n  // assuming we are in readonly mode.\n  assert(segment_descriptors);\n  assert(first_empty_segment_descriptor < total_num_segment_descriptors);\n\n  size_t i = first_empty_segment_descriptor;\n  for (auto &obj : loaded_code_objects) {\n    assert(i < total_num_segment_descriptors);\n    for (auto &seg : obj->LoadedSegments()) {\n      segment_descriptors[i].agent = seg->Agent();\n      segment_descriptors[i].executable = Executable::Handle(seg->Owner());\n      segment_descriptors[i].code_object_storage_type = HSA_VEN_AMD_LOADER_CODE_OBJECT_STORAGE_TYPE_MEMORY;\n      segment_descriptors[i].code_object_storage_base = obj->ElfData();\n      segment_descriptors[i].code_object_storage_size = obj->ElfSize();\n      segment_descriptors[i].code_object_storage_offset = seg->StorageOffset();\n      segment_descriptors[i].segment_base = seg->Address(seg->VAddr());\n      segment_descriptors[i].segment_size = seg->Size();\n      ++i;\n    }\n  }\n\n  return i - first_empty_segment_descriptor;\n}\n\nhsa_agent_t LoadedCodeObjectImpl::getAgent() const {\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return loaded_segments.front()->Agent();\n}\nhsa_executable_t LoadedCodeObjectImpl::getExecutable() const {\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return Executable::Handle(loaded_segments.front()->Owner());\n}\nuint64_t LoadedCodeObjectImpl::getElfData() const {\n  return reinterpret_cast<uint64_t>(elf_data);\n}\nuint64_t LoadedCodeObjectImpl::getElfSize() const {\n  return (uint64_t)elf_size;\n}\nuint64_t LoadedCodeObjectImpl::getStorageOffset() const {\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return (uint64_t)loaded_segments.front()->StorageOffset();\n}\nuint64_t LoadedCodeObjectImpl::getLoadBase() const {\n  // TODO Add support for code objects with 0 segments.\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return reinterpret_cast<uint64_t>(loaded_segments.front()->Address(0));\n}\nuint64_t LoadedCodeObjectImpl::getLoadSize() const {\n  // TODO Add support for code objects with 0 or >1 segments.\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return (uint64_t)loaded_segments.front()->Size();\n}\nint64_t LoadedCodeObjectImpl::getDelta() const {\n  // TODO Add support for code objects with 0 segments.\n  assert(loaded_segments.size() == 1 && \"Only supports code objects v2+\");\n  return getLoadBase() - loaded_segments.front()->VAddr();\n}\n\nstd::string LoadedCodeObjectImpl::getUri() const {\n  return std::string(r_debug_info.l_name);\n}\n\nhsa_executable_t AmdHsaCodeLoader::FindExecutable(uint64_t device_address)\n{\n  hsa_executable_t execHandle = {0};\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  if (device_address == 0) {\n    return execHandle;\n  }\n\n  for (auto &exec : executables) {\n    if (exec != nullptr) {\n      uint64_t host_address = exec->FindHostAddress(device_address);\n      if (host_address != 0) {\n        return Executable::Handle(exec);\n      }\n    }\n  }\n  return execHandle;\n}\n\nuint64_t ExecutableImpl::FindHostAddress(uint64_t device_address)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n  for (auto &obj : loaded_code_objects) {\n    assert(obj);\n    for (auto &seg : obj->LoadedSegments()) {\n      assert(seg);\n      uint64_t paddr = (uint64_t)(uintptr_t)seg->Address(seg->VAddr());\n      if (paddr <= device_address && device_address < paddr + seg->Size()) {\n        void *haddr = context_->SegmentHostAddress(\n          seg->ElfSegment(), seg->Agent(), seg->Ptr(), device_address - paddr);\n        return nullptr == haddr ? 0 : (uint64_t)(uintptr_t)haddr;\n      }\n    }\n  }\n  return 0;\n}\n\nvoid ExecutableImpl::EnableReadOnlyMode()\n{\n  rw_lock_.ReaderLock();\n}\n\nvoid ExecutableImpl::DisableReadOnlyMode()\n{\n  rw_lock_.ReaderUnlock();\n}\n\n#define HSAERRCHECK(hsc)                                                       \\\n  if (hsc != HSA_STATUS_SUCCESS) {                                             \\\n    assert(false);                                                             \\\n    return hsc;                                                                \\\n  }                                                                            \\\n\n\nhsa_status_t ExecutableImpl::GetInfo(\n    hsa_executable_info_t executable_info, void *value)\n{\n  ReaderLockGuard<ReaderWriterLock> reader_lock(rw_lock_);\n\n  assert(value);\n\n  switch (executable_info) {\n    case HSA_EXECUTABLE_INFO_PROFILE: {\n      *((hsa_profile_t*)value) = profile_;;\n      break;\n    }\n    case HSA_EXECUTABLE_INFO_STATE: {\n      *((hsa_executable_state_t*)value) = state_;\n      break;\n    }\n    case HSA_EXECUTABLE_INFO_DEFAULT_FLOAT_ROUNDING_MODE: {\n      *((hsa_default_float_rounding_mode_t*)value) =\n          default_float_rounding_mode_;\n      break;\n    }\n    default: {\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n    }\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nstatic uint32_t NextCodeObjectNum()\n{\n  static std::atomic_uint_fast32_t dumpN(1);\n  return dumpN++;\n}\n\nhsa_status_t ExecutableImpl::LoadCodeObject(\n  hsa_agent_t agent,\n  hsa_code_object_t code_object,\n  const char *options,\n  const std::string &uri,\n  hsa_loaded_code_object_t *loaded_code_object)\n{\n  return LoadCodeObject(agent, code_object, 0, options, uri, loaded_code_object);\n}\n\nhsa_status_t ExecutableImpl::LoadCodeObject(\n  hsa_agent_t agent,\n  hsa_code_object_t code_object,\n  size_t code_object_size,\n  const char *options,\n  const std::string &uri,\n  hsa_loaded_code_object_t *loaded_code_object)\n{\n  WriterLockGuard<ReaderWriterLock> writer_lock(rw_lock_);\n  if (HSA_EXECUTABLE_STATE_FROZEN == state_) {\n    logger_ << \"LoaderError: executable is already frozen\\n\";\n    return HSA_STATUS_ERROR_FROZEN_EXECUTABLE;\n  }\n\n  LoaderOptions loaderOptions;\n  if (options && !loaderOptions.ParseOptions(options)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  const char *options_append = getenv(\"LOADER_OPTIONS_APPEND\");\n  if (options_append && !loaderOptions.ParseOptions(options_append)) {\n    return HSA_STATUS_ERROR;\n  }\n\n  typedef std::tuple<uint32_t, uint32_t, std::string> Substitute;\n  std::vector<Substitute> substitutes;\n\n  for (const std::string& s : loaderOptions.Substitute()->values()) {\n    std::string::size_type vi = s.find('=');\n    if (vi == std::string::npos) { return HSA_STATUS_ERROR; }\n    std::string value = s.substr(vi + 1);\n    std::string range = s.substr(0, vi);\n    std::string::size_type mi = range.find('-');\n    uint32_t n1 = UINT32_MAX, n2 = UINT32_MAX;\n    if (mi != std::string::npos) {\n      std::string s1, s2;\n      s1 = range.substr(0, mi - 1);\n      s2 = range.substr(mi + 1);\n      std::istringstream is1(s1); is1 >> n1;\n      std::istringstream is2(s2); is2 >> n2;\n    } else {\n      std::istringstream is(range); is >> n1;\n      n2 = n1;\n    }\n    substitutes.push_back(std::make_tuple(n1, n2, value));\n  }\n\n  uint32_t codeNum = NextCodeObjectNum();\n\n  code.reset(new code::AmdHsaCode());\n\n  std::string substituteFileName;\n  for (const Substitute& ss : substitutes) {\n    if (codeNum >= std::get<0>(ss) && codeNum <= std::get<1>(ss)) {\n      substituteFileName = std::get<2>(ss);\n      break;\n    }\n  }\n  std::vector<char> buffer;\n  if (substituteFileName.empty()) {\n   if (!code->InitAsHandle(code_object)) {\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n    }\n  } else {\n    if (!ReadFileIntoBuffer(substituteFileName, buffer)) {\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n    }\n    if (!code->InitAsBuffer(&buffer[0], buffer.size())) {\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n    }\n  }\n\n  if (loaderOptions.DumpAll()->is_set() || loaderOptions.DumpCode()->is_set()) {\n    if (!code->SaveToFile(amd::hsa::DumpFileName(loaderOptions.DumpDir()->value(), LOADER_DUMP_PREFIX, \"hsaco\", codeNum))) {\n      // Ignore error.\n    }\n  }\n  if (loaderOptions.DumpAll()->is_set() || loaderOptions.DumpIsa()->is_set()) {\n    if (!code->PrintToFile(amd::hsa::DumpFileName(loaderOptions.DumpDir()->value(), LOADER_DUMP_PREFIX, \"isa\", codeNum))) {\n      // Ignore error.\n    }\n  }\n\n  std::string codeIsa;\n  unsigned genericVersion;\n  if (!code->GetIsa(codeIsa, &genericVersion)) {\n    logger_ << \"LoaderError: failed to determine code object's ISA\\n\";\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  uint32_t majorVersion, minorVersion;\n  if (!code->GetCodeObjectVersion(&majorVersion, &minorVersion)) {\n    logger_ << \"LoaderError: failed to determine code object's version\\n\";\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  if (majorVersion < 1 || majorVersion > 6) {\n    logger_ << \"LoaderError: unsupported code object version: \" << majorVersion << \"\\n\";\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n  if (agent.handle == 0 && majorVersion == 1) {\n    logger_ << \"LoaderError: code object v1 requires non-null agent\\n\";\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n  }\n\n  uint32_t codeHsailMajor;\n  uint32_t codeHsailMinor;\n  hsa_profile_t codeProfile;\n  hsa_machine_model_t codeMachineModel;\n  hsa_default_float_rounding_mode_t codeRoundingMode;\n  if (!code->GetNoteHsail(&codeHsailMajor, &codeHsailMinor, &codeProfile, &codeMachineModel, &codeRoundingMode)) {\n    codeProfile = profile_;\n  }\n  if (profile_ != codeProfile) {\n    logger_ << \"LoaderError: mismatched profiles\\n\";\n    return HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n  }\n\n  hsa_isa_t objectsIsa = context_->IsaFromName(codeIsa.c_str());\n  if (!objectsIsa.handle) {\n    logger_ << \"LoaderError: code object's ISA (\" << codeIsa.c_str() << \") is invalid\\n\";\n    return HSA_STATUS_ERROR_INVALID_ISA_NAME;\n  }\n\n  if (agent.handle != 0 && !context_->IsaSupportedByAgent(agent, objectsIsa, genericVersion)) {\n    logger_ << \"LoaderError: code object's ISA (\" << codeIsa.c_str() << \") is not supported by the agent\\n\";\n    return HSA_STATUS_ERROR_INCOMPATIBLE_ARGUMENTS;\n  }\n\n  hsa_status_t status;\n\n  objects.push_back(new LoadedCodeObjectImpl(this, agent, code->ElfData(), code->ElfSize()));\n  loaded_code_objects.push_back((LoadedCodeObjectImpl*)objects.back());\n\n  status = LoadSegments(agent, code.get(), majorVersion);\n  if (status != HSA_STATUS_SUCCESS) return status;\n\n  for (size_t i = 0; i < code->SymbolCount(); ++i) {\n    if (majorVersion >= 2 &&\n        code->GetSymbol(i)->elfSym()->type() != STT_AMDGPU_HSA_KERNEL &&\n        code->GetSymbol(i)->elfSym()->binding() == STB_LOCAL)\n      continue;\n\n    status = LoadSymbol(agent, code->GetSymbol(i), majorVersion);\n    if (status != HSA_STATUS_SUCCESS) { return status; }\n  }\n\n  status = ApplyRelocations(agent, code.get());\n  if (status != HSA_STATUS_SUCCESS) { return status; }\n\n  code.reset();\n\n  if (loaderOptions.DumpAll()->is_set() || loaderOptions.DumpExec()->is_set()) {\n    if (!PrintToFile(amd::hsa::DumpFileName(loaderOptions.DumpDir()->value(), LOADER_DUMP_PREFIX, \"exec\", codeNum))) {\n      // Ignore error.\n    }\n  }\n\n  loaded_code_objects.back()->r_debug_info.l_addr = loaded_code_objects.back()->getDelta();\n  loaded_code_objects.back()->r_debug_info.l_name = strdup(uri.c_str());\n  loaded_code_objects.back()->r_debug_info.l_prev = nullptr;\n  loaded_code_objects.back()->r_debug_info.l_next = nullptr;\n\n  if (nullptr != loaded_code_object) { *loaded_code_object = LoadedCodeObject::Handle(loaded_code_objects.back()); }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadSegments(hsa_agent_t agent,\n                                          const code::AmdHsaCode *c,\n                                          uint32_t majorVersion) {\n  if (majorVersion < 2)\n    return LoadSegmentsV1(agent, c);\n  else\n    return LoadSegmentsV2(agent, c);\n}\n\nhsa_status_t ExecutableImpl::LoadSegmentsV1(hsa_agent_t agent,\n                                            const code::AmdHsaCode *c) {\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  for (size_t i = 0; i < c->DataSegmentCount(); ++i) {\n    status = LoadSegmentV1(agent, c->DataSegment(i));\n    if (status != HSA_STATUS_SUCCESS) return status;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadSegmentsV2(hsa_agent_t agent,\n                                            const code::AmdHsaCode *c) {\n  assert(c->Machine() == ELF::EM_AMDGPU && \"Program code objects are not supported\");\n\n  if (!c->DataSegmentCount()) return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n\n  uint64_t vaddr = c->DataSegment(0)->vaddr();\n  uint64_t size = c->DataSegment(c->DataSegmentCount() - 1)->vaddr() +\n                  c->DataSegment(c->DataSegmentCount() - 1)->memSize();\n\n  void *ptr = context_->SegmentAlloc(AMDGPU_HSA_SEGMENT_CODE_AGENT, agent, size,\n      AMD_ISA_ALIGN_BYTES, true);\n  if (!ptr) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  Segment *load_segment = new Segment(this, agent, AMDGPU_HSA_SEGMENT_CODE_AGENT,\n      ptr, size, vaddr, c->DataSegment(0)->offset());\n  if (!load_segment) return HSA_STATUS_ERROR_OUT_OF_RESOURCES;\n\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  for (size_t i = 0; i < c->DataSegmentCount(); ++i) {\n    status = LoadSegmentV2(c->DataSegment(i), load_segment);\n    if (status != HSA_STATUS_SUCCESS) return status;\n  }\n\n  objects.push_back(load_segment);\n  loaded_code_objects.back()->LoadedSegments().push_back(load_segment);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadSegmentV1(hsa_agent_t agent,\n                                           const code::Segment *s) {\n  assert(s->type() < PT_LOOS + AMDGPU_HSA_SEGMENT_LAST);\n  if (s->memSize() == 0)\n    return HSA_STATUS_SUCCESS;\n  amdgpu_hsa_elf_segment_t segment = (amdgpu_hsa_elf_segment_t)(s->type() - PT_LOOS);\n  Segment *new_seg = nullptr;\n  bool need_alloc = true;\n  if (segment == AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM && nullptr != program_allocation_segment) {\n    new_seg = program_allocation_segment;\n    need_alloc = false;\n  }\n  if (need_alloc) {\n    void* ptr = context_->SegmentAlloc(segment, agent, s->memSize(), s->align(), true);\n    if (!ptr) { return HSA_STATUS_ERROR_OUT_OF_RESOURCES; }\n    new_seg = new Segment(this, agent, segment, ptr, s->memSize(), s->vaddr(), s->offset());\n    new_seg->Copy(s->vaddr(), s->data(), s->imageSize());\n    objects.push_back(new_seg);\n\n    if (segment == AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM) {\n      program_allocation_segment = new_seg;\n    }\n  }\n  assert(new_seg);\n  loaded_code_objects.back()->LoadedSegments().push_back(new_seg);\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadSegmentV2(const code::Segment *data_segment,\n                                           loader::Segment *load_segment) {\n  assert(data_segment && load_segment);\n  load_segment->Copy(data_segment->vaddr(), data_segment->data(),\n                     data_segment->imageSize());\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadSymbol(hsa_agent_t agent,\n                                        code::Symbol* sym,\n                                        uint32_t majorVersion)\n{\n  if (sym->IsDeclaration()) {\n    return LoadDeclarationSymbol(agent, sym, majorVersion);\n  } else {\n    return LoadDefinitionSymbol(agent, sym, majorVersion);\n  }\n}\n\nnamespace {\n\nbool string_ends_with(const std::string &str, const std::string &suf) {\n  return str.size() >= suf.size() ? str.compare(str.size() - suf.size(), suf.size(), suf) == 0 : false;\n}\n\n}\n\nhsa_status_t ExecutableImpl::LoadDefinitionSymbol(hsa_agent_t agent,\n                                                  code::Symbol* sym,\n                                                  uint32_t majorVersion)\n{\n  bool isAgent = sym->IsAgent();\n  if (majorVersion >= 2) {\n    isAgent = agent.handle != 0;\n  }\n  if (isAgent) {\n    auto agent_symbol = agent_symbols_.find(std::make_pair(sym->Name(), agent));\n    if (agent_symbol != agent_symbols_.end()) {\n      // TODO(spec): this is not spec compliant.\n      return HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED;\n    }\n  } else {\n    auto program_symbol = program_symbols_.find(sym->Name());\n    if (program_symbol != program_symbols_.end()) {\n      // TODO(spec): this is not spec compliant.\n      return HSA_STATUS_ERROR_VARIABLE_ALREADY_DEFINED;\n    }\n  }\n\n  uint64_t address = SymbolAddress(agent, sym);\n  SymbolImpl *symbol = nullptr;\n  if (string_ends_with(sym->GetSymbolName(), \".kd\")) {\n    // V3.\n    llvm::amdhsa::kernel_descriptor_t kd;\n    sym->GetSection()->getData(sym->SectionOffset(), &kd, sizeof(kd));\n\n    uint32_t kernarg_segment_size = kd.kernarg_size; // FIXME: If 0 then the compiler is not specifying the size.\n    uint32_t kernarg_segment_alignment = 16;         // FIXME: Use the minumum HSA required alignment.\n    uint32_t group_segment_size = kd.group_segment_fixed_size;\n    uint32_t private_segment_size = kd.private_segment_fixed_size;\n    bool is_dynamic_callstack = AMDHSA_BITS_GET(kd.kernel_code_properties, rocr::llvm::amdhsa::KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK);\n    bool uses_wave32 = AMDHSA_BITS_GET( kd.kernel_code_properties, rocr::llvm::amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32);\n\n    uint64_t size = sym->Size();\n\n    KernelSymbol *kernel_symbol = new KernelSymbol(true,\n                                    sym->GetModuleName(),\n                                    sym->GetSymbolName(),\n                                    sym->Linkage(),\n                                    true, // sym->IsDefinition()\n                                    kernarg_segment_size,\n                                    kernarg_segment_alignment,\n                                    group_segment_size,\n                                    private_segment_size,\n                                    is_dynamic_callstack,\n                                    size,\n                                    64,\n                                    uses_wave32 ? 32 : 64,\n                                    address);\n    symbol = kernel_symbol;\n  } else if (sym->IsVariableSymbol()) {\n    symbol = new VariableSymbol(true,\n                       sym->GetModuleName(),\n                       sym->GetSymbolName(),\n                       sym->Linkage(),\n                       true, // sym->IsDefinition()\n                       sym->Allocation(),\n                       sym->Segment(),\n                       sym->Size(),\n                       sym->Alignment(),\n                       sym->IsConst(),\n                       false,\n                       address);\n  } else if (sym->IsKernelSymbol()) {\n      amd_kernel_code_t akc;\n      sym->GetSection()->getData(sym->SectionOffset(), &akc, sizeof(akc));\n\n      uint32_t kernarg_segment_size =\n        uint32_t(akc.kernarg_segment_byte_size);\n      uint32_t kernarg_segment_alignment =\n        uint32_t(1 << akc.kernarg_segment_alignment);\n      uint32_t group_segment_size =\n        uint32_t(akc.workgroup_group_segment_byte_size);\n      uint32_t private_segment_size =\n        uint32_t(akc.workitem_private_segment_byte_size);\n      bool is_dynamic_callstack =\n        AMD_HSA_BITS_GET(akc.kernel_code_properties, AMD_KERNEL_CODE_PROPERTIES_IS_DYNAMIC_CALLSTACK) ? true : false;\n      bool uses_wave32 = akc.wavefront_size == AMD_POWERTWO_32;\n\n      uint64_t size = sym->Size();\n\n      if (!size && sym->SectionOffset() < sym->GetSection()->size()) {\n        // ORCA Runtime relies on symbol size equal to size of kernel ISA. If symbol size is 0 in ELF,\n        // calculate end of segment - symbol value.\n        size = sym->GetSection()->size() - sym->SectionOffset();\n      }\n      KernelSymbol *kernel_symbol = new KernelSymbol(true,\n                                      sym->GetModuleName(),\n                                      sym->GetSymbolName(),\n                                      sym->Linkage(),\n                                      true, // sym->IsDefinition()\n                                      kernarg_segment_size,\n                                      kernarg_segment_alignment,\n                                      group_segment_size,\n                                      private_segment_size,\n                                      is_dynamic_callstack,\n                                      size,\n                                      256,\n                                      uses_wave32 ? 32 : 64,\n                                      address);\n      kernel_symbol->debug_info.elf_raw = code->ElfData();\n      kernel_symbol->debug_info.elf_size = code->ElfSize();\n      kernel_symbol->debug_info.kernel_name = kernel_symbol->full_name.c_str();\n      kernel_symbol->debug_info.owning_segment = (void*)SymbolSegment(agent, sym)->Address(sym->GetSection()->addr());\n      symbol = kernel_symbol;\n\n      // \\todo kzhuravl 10/15/15 This is a debugger backdoor: needs to be\n      // removed.\n      uint64_t target_address = sym->GetSection()->addr() + sym->SectionOffset() + ((size_t)(&((amd_kernel_code_t*)0)->runtime_loader_kernel_symbol));\n      uint64_t source_value = (uint64_t) (uintptr_t) &kernel_symbol->debug_info;\n      SymbolSegment(agent, sym)->Copy(target_address, &source_value, sizeof(source_value));\n  } else {\n    assert(!\"Unexpected symbol type in LoadDefinitionSymbol\");\n    return HSA_STATUS_ERROR;\n  }\n\n  assert(symbol);\n  if (isAgent) {\n    symbol->agent = agent;\n    agent_symbols_.insert(std::make_pair(std::make_pair(sym->Name(), agent), symbol));\n  } else {\n    program_symbols_.insert(std::make_pair(sym->Name(), symbol));\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::LoadDeclarationSymbol(hsa_agent_t agent,\n                                                   code::Symbol* sym,\n                                                   uint32_t majorVersion)\n{\n  auto program_symbol = program_symbols_.find(sym->Name());\n  if (program_symbol == program_symbols_.end()) {\n    auto agent_symbol = agent_symbols_.find(std::make_pair(sym->Name(), agent));\n    if (agent_symbol == agent_symbols_.end()) {\n      logger_ << \"LoaderError: symbol \\\"\" << sym->Name() << \"\\\" is undefined\\n\";\n\n      // TODO(spec): this is not spec compliant.\n      return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n    }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nSegment* ExecutableImpl::VirtualAddressSegment(uint64_t vaddr)\n{\n  for (auto &seg : loaded_code_objects.back()->LoadedSegments()) {\n    if (seg->IsAddressInSegment(vaddr)) {\n      return seg;\n    }\n  }\n  return 0;\n}\n\nuint64_t ExecutableImpl::SymbolAddress(hsa_agent_t agent, code::Symbol* sym)\n{\n  code::Section* sec = sym->GetSection();\n  Segment* seg = SectionSegment(agent, sec);\n  return nullptr == seg ? 0 : (uint64_t) (uintptr_t) seg->Address(sym->VAddr());\n}\n\nuint64_t ExecutableImpl::SymbolAddress(hsa_agent_t agent, elf::Symbol* sym)\n{\n  elf::Section* sec = sym->section();\n  Segment* seg = SectionSegment(agent, sec);\n  uint64_t vaddr = sec->addr() + sym->value();\n  return nullptr == seg ? 0 : (uint64_t) (uintptr_t) seg->Address(vaddr);\n}\n\nSegment* ExecutableImpl::SymbolSegment(hsa_agent_t agent, code::Symbol* sym)\n{\n  return SectionSegment(agent, sym->GetSection());\n}\n\nSegment* ExecutableImpl::SectionSegment(hsa_agent_t agent, code::Section* sec)\n{\n  for (Segment* seg : loaded_code_objects.back()->LoadedSegments()) {\n    if (seg->IsAddressInSegment(sec->addr())) {\n      return seg;\n    }\n  }\n  return 0;\n}\n\nhsa_status_t ExecutableImpl::ApplyRelocations(hsa_agent_t agent, amd::hsa::code::AmdHsaCode *c)\n{\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n\n  uint32_t majorVersion, minorVersion;\n  if (!c->GetCodeObjectVersion(&majorVersion, &minorVersion)) {\n    return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n\n  for (size_t i = 0; i < c->RelocationSectionCount(); ++i) {\n    if (c->GetRelocationSection(i)->targetSection()) {\n      // Static relocations may be present if --emit-relocs\n      // option was passed to lld, but they cannot be applied\n      // again, so skip it for code object v2 and up.\n      if (majorVersion >= 2) {\n        continue;\n      }\n\n      status = ApplyStaticRelocationSection(agent, c->GetRelocationSection(i));\n    } else {\n      // Dynamic relocations are supported starting code object v2.1.\n      if (majorVersion < 2) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      if (majorVersion == 2 && minorVersion < 1) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      status = ApplyDynamicRelocationSection(agent, c->GetRelocationSection(i));\n    }\n    if (status != HSA_STATUS_SUCCESS) { return status; }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::ApplyStaticRelocationSection(hsa_agent_t agent, amd::hsa::code::RelocationSection* sec)\n{\n  // Skip link-time relocations (if any).\n  if (!(sec->targetSection()->flags() & SHF_ALLOC)) { return HSA_STATUS_SUCCESS; }\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  for (size_t i = 0; i < sec->relocationCount(); ++i) {\n    status = ApplyStaticRelocation(agent, sec->relocation(i));\n    if (status != HSA_STATUS_SUCCESS) { return status; }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::ApplyStaticRelocation(hsa_agent_t agent, amd::hsa::code::Relocation *rel)\n{\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  amd::elf::Symbol* sym = rel->symbol();\n  code::RelocationSection* rsec = rel->section();\n  code::Section* sec = rsec->targetSection();\n  Segment* rseg = SectionSegment(agent, sec);\n  size_t reladdr = sec->addr() + rel->offset();\n  switch (rel->type()) {\n    case R_AMDGPU_V1_32_LOW:\n    case R_AMDGPU_V1_32_HIGH:\n    case R_AMDGPU_V1_64:\n    {\n      uint64_t addr;\n      switch (sym->type()) {\n        case STT_OBJECT:\n        case STT_SECTION:\n        case STT_AMDGPU_HSA_KERNEL:\n        case STT_AMDGPU_HSA_INDIRECT_FUNCTION:\n          addr = SymbolAddress(agent, sym);\n          if (!addr) { return HSA_STATUS_ERROR_INVALID_CODE_OBJECT; }\n          break;\n        case STT_COMMON: {\n          hsa_agent_t *sagent = &agent;\n          if (STA_AMDGPU_HSA_GLOBAL_PROGRAM == ELF64_ST_AMDGPU_ALLOCATION(sym->other())) {\n            sagent = nullptr;\n          }\n          SymbolImpl* esym = (SymbolImpl*) GetSymbolInternal(sym->name().c_str(), sagent);\n          if (!esym) {\n            logger_ << \"LoaderError: symbol \\\"\" << sym->name() << \"\\\" is undefined\\n\";\n            return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n          }\n          addr = esym->address;\n          break;\n        }\n        default:\n          return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      addr += rel->addend();\n\n      uint32_t addr32 = 0;\n      switch (rel->type()) {\n        case R_AMDGPU_V1_32_HIGH:\n          addr32 = uint32_t((addr >> 32) & 0xFFFFFFFF);\n          rseg->Copy(reladdr, &addr32, sizeof(addr32));\n          break;\n        case R_AMDGPU_V1_32_LOW:\n          addr32 = uint32_t(addr & 0xFFFFFFFF);\n          rseg->Copy(reladdr, &addr32, sizeof(addr32));\n          break;\n        case R_AMDGPU_V1_64:\n          rseg->Copy(reladdr, &addr, sizeof(addr));\n          break;\n        default:\n          return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      break;\n    }\n\n    case R_AMDGPU_V1_INIT_SAMPLER:\n    {\n      if (STT_AMDGPU_HSA_METADATA != sym->type() ||\n          SHT_PROGBITS != sym->section()->type() ||\n          !(sym->section()->flags() & SHF_MERGE)) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      amdgpu_hsa_sampler_descriptor_t desc;\n      if (!sym->section()->getData(sym->value(), &desc, sizeof(desc))) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      if (AMDGPU_HSA_METADATA_KIND_INIT_SAMP != desc.kind) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n\n      hsa_ext_sampler_descriptor_t hsa_sampler_descriptor;\n      hsa_sampler_descriptor.coordinate_mode =\n        hsa_ext_sampler_coordinate_mode_t(desc.coord);\n      hsa_sampler_descriptor.filter_mode =\n        hsa_ext_sampler_filter_mode_t(desc.filter);\n      hsa_sampler_descriptor.address_mode =\n        hsa_ext_sampler_addressing_mode_t(desc.addressing);\n\n      hsa_ext_sampler_t hsa_sampler = {0};\n      status = context_->SamplerCreate(agent, &hsa_sampler_descriptor, &hsa_sampler);\n      if (status != HSA_STATUS_SUCCESS) { return status; }\n      assert(hsa_sampler.handle);\n      rseg->Copy(reladdr, &hsa_sampler, sizeof(hsa_sampler));\n      break;\n    }\n\n    case R_AMDGPU_V1_INIT_IMAGE:\n    {\n      if (STT_AMDGPU_HSA_METADATA != sym->type() ||\n          SHT_PROGBITS != sym->section()->type() ||\n          !(sym->section()->flags() & SHF_MERGE)) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n\n      amdgpu_hsa_image_descriptor_t desc;\n      if (!sym->section()->getData(sym->value(), &desc, sizeof(desc))) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n      if (AMDGPU_HSA_METADATA_KIND_INIT_ROIMG != desc.kind &&\n          AMDGPU_HSA_METADATA_KIND_INIT_WOIMG != desc.kind &&\n          AMDGPU_HSA_METADATA_KIND_INIT_RWIMG != desc.kind) {\n        return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n      }\n\n      hsa_ext_image_format_t hsa_image_format;\n      hsa_image_format.channel_order =\n        hsa_ext_image_channel_order_t(desc.channel_order);\n      hsa_image_format.channel_type =\n        hsa_ext_image_channel_type_t(desc.channel_type);\n\n      hsa_ext_image_descriptor_t hsa_image_descriptor;\n      hsa_image_descriptor.geometry =\n        hsa_ext_image_geometry_t(desc.geometry);\n      hsa_image_descriptor.width = size_t(desc.width);\n      hsa_image_descriptor.height = size_t(desc.height);\n      hsa_image_descriptor.depth = size_t(desc.depth);\n      hsa_image_descriptor.array_size = size_t(desc.array);\n      hsa_image_descriptor.format = hsa_image_format;\n\n      hsa_access_permission_t hsa_image_permission = HSA_ACCESS_PERMISSION_RO;\n      switch (desc.kind) {\n        case AMDGPU_HSA_METADATA_KIND_INIT_ROIMG: {\n          hsa_image_permission = HSA_ACCESS_PERMISSION_RO;\n          break;\n        }\n        case AMDGPU_HSA_METADATA_KIND_INIT_WOIMG: {\n          hsa_image_permission = HSA_ACCESS_PERMISSION_WO;\n          break;\n        }\n        case AMDGPU_HSA_METADATA_KIND_INIT_RWIMG: {\n          hsa_image_permission = HSA_ACCESS_PERMISSION_RW;\n          break;\n        }\n        default: {\n          assert(false);\n          return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n        }\n      }\n\n      hsa_ext_image_t hsa_image = {0};\n      status = context_->ImageCreate(agent, hsa_image_permission,\n                                  &hsa_image_descriptor,\n                                  NULL, // TODO: image_data?\n                                  &hsa_image);\n      if (status != HSA_STATUS_SUCCESS) { return status; }\n      rseg->Copy(reladdr, &hsa_image, sizeof(hsa_image));\n      break;\n    }\n\n    default:\n      // Ignore.\n      break;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::ApplyDynamicRelocationSection(hsa_agent_t agent, amd::hsa::code::RelocationSection* sec)\n{\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  for (size_t i = 0; i < sec->relocationCount(); ++i) {\n    status = ApplyDynamicRelocation(agent, sec->relocation(i));\n    if (status != HSA_STATUS_SUCCESS) { return status; }\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::ApplyDynamicRelocation(hsa_agent_t agent, amd::hsa::code::Relocation *rel)\n{\n  Segment* relSeg = VirtualAddressSegment(rel->offset());\n  uint64_t symAddr = 0;\n  switch (rel->symbol()->type()) {\n    case STT_OBJECT:\n    case STT_AMDGPU_HSA_KERNEL:\n    case STT_FUNC:\n    {\n      Segment* symSeg = VirtualAddressSegment(rel->symbol()->value());\n      symAddr = reinterpret_cast<uint64_t>(symSeg->Address(rel->symbol()->value()));\n      break;\n    }\n\n    // External symbols, they must be defined prior loading.\n    case STT_NOTYPE:\n    {\n      // TODO: Only agent allocation variables are supported in v2.1. How will\n      // we distinguish between program allocation and agent allocation\n      // variables?\n      auto agent_symbol = agent_symbols_.find(std::make_pair(rel->symbol()->name(), agent));\n      if (agent_symbol != agent_symbols_.end())\n        symAddr = agent_symbol->second->address;\n      break;\n    }\n\n    default:\n      // Only objects and kernels are supported in v2.1.\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n  symAddr += rel->addend();\n\n  switch (rel->type()) {\n    case ELF::R_AMDGPU_ABS32_HI:\n    {\n      if (!symAddr) {\n        logger_ << \"LoaderError: symbol \\\"\" << rel->symbol()->name() << \"\\\" is undefined\\n\";\n        return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n      }\n\n      uint32_t symAddr32 = uint32_t((symAddr >> 32) & 0xFFFFFFFF);\n      relSeg->Copy(rel->offset(), &symAddr32, sizeof(symAddr32));\n      break;\n    }\n\n    case ELF::R_AMDGPU_ABS32_LO:\n    {\n      if (!symAddr) {\n        logger_ << \"LoaderError: symbol \\\"\" << rel->symbol()->name() << \"\\\" is undefined\\n\";\n        return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n      }\n\n      uint32_t symAddr32 = uint32_t(symAddr & 0xFFFFFFFF);\n      relSeg->Copy(rel->offset(), &symAddr32, sizeof(symAddr32));\n      break;\n    }\n\n    case ELF::R_AMDGPU_ABS32:\n    {\n      if (!symAddr) {\n        logger_ << \"LoaderError: symbol \\\"\" << rel->symbol()->name() << \"\\\" is undefined\\n\";\n        return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n      }\n\n      uint32_t symAddr32 = uint32_t(symAddr);\n      relSeg->Copy(rel->offset(), &symAddr32, sizeof(symAddr32));\n      break;\n    }\n\n    case ELF::R_AMDGPU_ABS64:\n    {\n      if (!symAddr) {\n        logger_ << \"LoaderError: symbol \\\"\" << rel->symbol()->name() << \"\\\" is undefined\\n\";\n        return HSA_STATUS_ERROR_VARIABLE_UNDEFINED;\n      }\n\n      relSeg->Copy(rel->offset(), &symAddr, sizeof(symAddr));\n      break;\n    }\n\n    case ELF::R_AMDGPU_RELATIVE64:\n    {\n      int64_t baseDelta = reinterpret_cast<uint64_t>(relSeg->Address(0)) - relSeg->VAddr();\n      uint64_t relocatedAddr = baseDelta + rel->addend();\n      relSeg->Copy(rel->offset(), &relocatedAddr, sizeof(relocatedAddr));\n      break;\n    }\n\n    default:\n      return HSA_STATUS_ERROR_INVALID_CODE_OBJECT;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t ExecutableImpl::Freeze(const char *options) {\n  amd::hsa::common::WriterLockGuard<amd::hsa::common::ReaderWriterLock> writer_lock(rw_lock_);\n  if (HSA_EXECUTABLE_STATE_FROZEN == state_) {\n    return HSA_STATUS_ERROR_FROZEN_EXECUTABLE;\n  }\n\n  for (auto &lco : loaded_code_objects) {\n    for (auto &ls : lco->LoadedSegments()) {\n      ls->Freeze();\n    }\n  }\n\n  state_ = HSA_EXECUTABLE_STATE_FROZEN;\n  return HSA_STATUS_SUCCESS;\n}\n\nvoid ExecutableImpl::Print(std::ostream& out)\n{\n  out << \"AMD Executable\" << std::endl;\n  out << \"  Id: \" << id()\n      << \"  Profile: \" << HsaProfileToString(profile())\n      << std::endl << std::endl;\n  out << \"Loaded Objects (total \" << objects.size() << \")\" << std::endl;\n  size_t i = 0;\n  for (ExecutableObject* o : objects) {\n    out << \"Loaded Object \" << i++ << \": \";\n    o->Print(out);\n    out << std::endl;\n  }\n  out << \"End AMD Executable\" << std::endl;\n}\n\nbool ExecutableImpl::PrintToFile(const std::string& filename)\n{\n  std::ofstream out(filename);\n  if (out.fail()) { return false; }\n  Print(out);\n  return out.fail();\n}\n\n} // namespace loader\n} // namespace hsa\n} // namespace amd\n} // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/loader/executable.hpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_CORE_LOADER_EXECUTABLE_HPP_\n#define HSA_RUNTIME_CORE_LOADER_EXECUTABLE_HPP_\n\n#include <array>\n#include <cassert>\n#include <cstdint>\n#include <iostream>\n#include <libelf.h>\n#include <link.h>\n#include <list>\n#include <string>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n#include <cstring>\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_image.h\"\n#include \"core/inc/amd_hsa_loader.hpp\"\n#include \"core/inc/amd_hsa_code.hpp\"\n#include \"inc/amd_hsa_kernel_code.h\"\n#include \"amd_hsa_locks.hpp\"\n\nnamespace rocr {\nnamespace amd {\nnamespace hsa {\nnamespace loader {\n\nclass MemoryAddress;\nclass SymbolImpl;\nclass KernelSymbol;\nclass VariableSymbol;\nclass ExecutableImpl;\n\n//===----------------------------------------------------------------------===//\n// SymbolImpl.                                                                //\n//===----------------------------------------------------------------------===//\n\ntypedef uint32_t symbol_attribute32_t;\n\nclass SymbolImpl: public Symbol {\npublic:\n  virtual ~SymbolImpl() {}\n\n  bool IsKernel() const {\n    return HSA_SYMBOL_KIND_KERNEL == kind;\n  }\n  bool IsVariable() const {\n    return HSA_SYMBOL_KIND_VARIABLE == kind;\n  }\n\n  bool is_loaded;\n  hsa_symbol_kind_t kind;\n  std::string module_name;\n  std::string symbol_name;\n  hsa_symbol_linkage_t linkage;\n  bool is_definition;\n  uint64_t address;\n  hsa_agent_t agent;\n\n  hsa_agent_t GetAgent() override {\n    return agent;\n  }\n\nprotected:\n  SymbolImpl(const bool &_is_loaded,\n             const hsa_symbol_kind_t &_kind,\n             const std::string &_module_name,\n             const std::string &_symbol_name,\n             const hsa_symbol_linkage_t &_linkage,\n             const bool &_is_definition,\n             const uint64_t &_address = 0)\n    : is_loaded(_is_loaded)\n    , kind(_kind)\n    , module_name(_module_name)\n    , symbol_name(_symbol_name)\n    , linkage(_linkage)\n    , is_definition(_is_definition)\n    , address(_address) {}\n\n  virtual bool GetInfo(hsa_symbol_info32_t symbol_info, void* value) override;\n\n private:\n  SymbolImpl(const SymbolImpl &s);\n  SymbolImpl& operator=(const SymbolImpl &s);\n};\n\n//===----------------------------------------------------------------------===//\n// KernelSymbol.                                                              //\n//===----------------------------------------------------------------------===//\n\nclass KernelSymbol final: public SymbolImpl {\npublic:\n  KernelSymbol(const bool &_is_loaded,\n               const std::string &_module_name,\n               const std::string &_symbol_name,\n               const hsa_symbol_linkage_t &_linkage,\n               const bool &_is_definition,\n               const uint32_t &_kernarg_segment_size,\n               const uint32_t &_kernarg_segment_alignment,\n               const uint32_t &_group_segment_size,\n               const uint32_t &_private_segment_size,\n               const bool &_is_dynamic_callstack,\n               const uint32_t &_size,\n               const uint32_t &_alignment,\n               const uint32_t &_wavefront_size,\n               const uint64_t &_address = 0)\n    : SymbolImpl(_is_loaded,\n                 HSA_SYMBOL_KIND_KERNEL,\n                 _module_name,\n                 _symbol_name,\n                 _linkage,\n                 _is_definition,\n                 _address)\n    , full_name(_module_name.empty() ? _symbol_name : _module_name + \"::\" + _symbol_name)\n    , kernarg_segment_size(_kernarg_segment_size)\n    , kernarg_segment_alignment(_kernarg_segment_alignment)\n    , group_segment_size(_group_segment_size)\n    , private_segment_size(_private_segment_size)\n    , is_dynamic_callstack(_is_dynamic_callstack)\n    , size(_size)\n    , alignment(_alignment)\n    , wavefront_size(_wavefront_size)\n    , debug_info{} {}\n\n  ~KernelSymbol() {}\n\n  bool GetInfo(hsa_symbol_info32_t symbol_info, void *value);\n\n  std::string full_name;\n  uint32_t kernarg_segment_size;\n  uint32_t kernarg_segment_alignment;\n  uint32_t group_segment_size;\n  uint32_t private_segment_size;\n  bool is_dynamic_callstack;\n  uint32_t size;\n  uint32_t alignment;\n  uint32_t wavefront_size;\n  amd_runtime_loader_debug_info_t debug_info;\n\nprivate:\n  KernelSymbol(const KernelSymbol &ks);\n  KernelSymbol& operator=(const KernelSymbol &ks);\n};\n\n//===----------------------------------------------------------------------===//\n// VariableSymbol.                                                            //\n//===----------------------------------------------------------------------===//\n\nclass VariableSymbol final: public SymbolImpl {\npublic:\n  VariableSymbol(const bool &_is_loaded,\n                 const std::string &_module_name,\n                 const std::string &_symbol_name,\n                 const hsa_symbol_linkage_t &_linkage,\n                 const bool &_is_definition,\n                 const hsa_variable_allocation_t &_allocation,\n                 const hsa_variable_segment_t &_segment,\n                 const uint32_t &_size,\n                 const uint32_t &_alignment,\n                 const bool &_is_constant,\n                 const bool &_is_external = false,\n                 const uint64_t &_address = 0)\n    : SymbolImpl(_is_loaded,\n                 HSA_SYMBOL_KIND_VARIABLE,\n                 _module_name,\n                 _symbol_name,\n                 _linkage,\n                 _is_definition,\n                 _address)\n    , allocation(_allocation)\n    , segment(_segment)\n    , size(_size)\n    , alignment(_alignment)\n    , is_constant(_is_constant)\n    , is_external(_is_external) {}\n\n  ~VariableSymbol() {}\n\n  bool GetInfo(hsa_symbol_info32_t symbol_info, void *value);\n\n  hsa_variable_allocation_t allocation;\n  hsa_variable_segment_t segment;\n  uint32_t size;\n  uint32_t alignment;\n  bool is_constant;\n  bool is_external;\n\nprivate:\n  VariableSymbol(const VariableSymbol &vs);\n  VariableSymbol& operator=(const VariableSymbol &vs);\n};\n\n//===----------------------------------------------------------------------===//\n// Logger.                                                                    //\n//===----------------------------------------------------------------------===//\n\nclass Logger final {\npublic:\n  Logger(std::ostream &Stream = std::cerr) : OutStream(Stream) {}\n\n  template <typename T>\n  Logger &operator<<(const T &Data) {\n    if (!IsLoggingEnabled())\n      return *this;\n    OutStream << Data;\n    return *this;\n  }\n\nprivate:\n  Logger(const Logger &L);\n  Logger& operator=(const Logger &L);\n\n  bool IsLoggingEnabled() const {\n    const char *enable_logging = getenv(\"LOADER_ENABLE_LOGGING\");\n    if (!enable_logging)\n      return false;\n    if (std::string(enable_logging) == \"0\")\n      return false;\n    return true;\n  }\n\n  std::ostream &OutStream;\n};\n\n//===----------------------------------------------------------------------===//\n// Executable.                                                                //\n//===----------------------------------------------------------------------===//\n\nclass ExecutableImpl;\nclass LoadedCodeObjectImpl;\nclass Segment;\n\nclass ExecutableObject {\nprotected:\n  ExecutableImpl *owner;\n  hsa_agent_t agent;\n\npublic:\n  ExecutableObject(ExecutableImpl *owner_, hsa_agent_t agent_)\n    : owner(owner_), agent(agent_) { }\n\n  ExecutableImpl* Owner() const { return owner; }\n  hsa_agent_t Agent() const { return agent; }\n  virtual void Print(std::ostream& out) = 0;\n  virtual void Destroy() = 0;\n\n  virtual ~ExecutableObject() { }\n};\n\nclass LoadedCodeObjectImpl : public LoadedCodeObject, public ExecutableObject {\nfriend class AmdHsaCodeLoader;\nprivate:\n  LoadedCodeObjectImpl(const LoadedCodeObjectImpl&);\n  LoadedCodeObjectImpl& operator=(const LoadedCodeObjectImpl&);\n\n  const void *elf_data;\n  const size_t elf_size;\n  std::vector<Segment*> loaded_segments;\n\npublic:\n  LoadedCodeObjectImpl(ExecutableImpl *owner_, hsa_agent_t agent_, const void *elf_data_, size_t elf_size_)\n    : ExecutableObject(owner_, agent_), elf_data(elf_data_), elf_size(elf_size_) {\n      memset(&r_debug_info, 0, sizeof(r_debug_info));\n    }\n\n  const void* ElfData() const { return elf_data; }\n  size_t ElfSize() const { return elf_size; }\n  std::vector<Segment*>& LoadedSegments() { return loaded_segments; }\n\n  bool GetInfo(amd_loaded_code_object_info_t attribute, void *value) override;\n\n  hsa_status_t IterateLoadedSegments(\n    hsa_status_t (*callback)(\n      amd_loaded_segment_t loaded_segment,\n      void *data),\n    void *data) override;\n\n  void Print(std::ostream& out) override;\n\n  void Destroy() override {}\n\n  hsa_agent_t getAgent() const override;\n  hsa_executable_t getExecutable() const override;\n  uint64_t getElfData() const override;\n  uint64_t getElfSize() const override;\n  uint64_t getStorageOffset() const override;\n  uint64_t getLoadBase() const override;\n  uint64_t getLoadSize() const override;\n  int64_t getDelta() const override;\n  std::string getUri() const override;\n\n  link_map r_debug_info;\n};\n\nclass Segment : public LoadedSegment, public ExecutableObject {\nprivate:\n  amdgpu_hsa_elf_segment_t segment;\n  void *ptr;\n  size_t size;\n  uint64_t vaddr;\n  bool frozen;\n  size_t storage_offset;\n\npublic:\n  Segment(ExecutableImpl *owner_, hsa_agent_t agent_, amdgpu_hsa_elf_segment_t segment_, void* ptr_, size_t size_, uint64_t vaddr_, size_t storage_offset_)\n    : ExecutableObject(owner_, agent_), segment(segment_),\n      ptr(ptr_), size(size_), vaddr(vaddr_), frozen(false), storage_offset(storage_offset_) { }\n\n  amdgpu_hsa_elf_segment_t ElfSegment() const { return segment; }\n  void* Ptr() const { return ptr; }\n  size_t Size() const { return size; }\n  uint64_t VAddr() const { return vaddr; }\n  size_t StorageOffset() const { return storage_offset;  }\n\n  bool GetInfo(amd_loaded_segment_info_t attribute, void *value) override;\n\n  uint64_t Offset(uint64_t addr); // Offset within segment. Used together with ptr with loader context functions.\n\n  void* Address(uint64_t addr); // Address in segment. Used for relocations and valid on agent.\n\n  bool Freeze();\n\n  bool IsAddressInSegment(uint64_t addr);\n  void Copy(uint64_t addr, const void* src, size_t size);\n  void Print(std::ostream& out) override;\n  void Destroy() override;\n};\n\nclass Sampler : public ExecutableObject {\nprivate:\n  hsa_ext_sampler_t samp;\n\npublic:\n  Sampler(ExecutableImpl *owner, hsa_agent_t agent, hsa_ext_sampler_t samp_)\n    : ExecutableObject(owner, agent), samp(samp_) { }\n  void Print(std::ostream& out) override;\n  void Destroy() override;\n};\n\nclass Image : public ExecutableObject {\nprivate:\n  hsa_ext_image_t img;\n\npublic:\n  Image(ExecutableImpl *owner, hsa_agent_t agent, hsa_ext_image_t img_)\n    : ExecutableObject(owner, agent), img(img_) { }\n  void Print(std::ostream& out) override;\n  void Destroy() override;\n};\n\ntypedef std::string ProgramSymbol;\ntypedef std::unordered_map<ProgramSymbol, SymbolImpl*> ProgramSymbolMap;\n\ntypedef std::pair<std::string, hsa_agent_t> AgentSymbol;\nstruct ASC {\n  bool operator()(const AgentSymbol &las, const AgentSymbol &ras) const {\n    return las.first == ras.first && las.second.handle == ras.second.handle;\n  }\n};\nstruct ASH {\n  size_t operator()(const AgentSymbol &as) const {\n    size_t h = std::hash<std::string>()(as.first);\n    size_t i = std::hash<uint64_t>()(as.second.handle);\n    return h ^ (i << 1);\n  }\n};\ntypedef std::unordered_map<AgentSymbol, SymbolImpl*, ASH, ASC> AgentSymbolMap;\n\nclass ExecutableImpl final: public Executable {\nfriend class AmdHsaCodeLoader;\npublic:\n  const hsa_profile_t& profile() const {\n    return profile_;\n  }\n  const hsa_executable_state_t& state() const {\n    return state_;\n  }\n\n  ExecutableImpl(\n      const hsa_profile_t &_profile,\n      Context *context,\n      size_t id,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode);\n\n  ExecutableImpl(\n      const hsa_profile_t &_profile,\n      std::unique_ptr<Context> unique_context,\n      size_t id,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode);\n\n  ~ExecutableImpl();\n\n  hsa_status_t GetInfo(hsa_executable_info_t executable_info, void *value) override;\n\n  hsa_status_t DefineProgramExternalVariable(\n    const char *name, void *address) override;\n\n  hsa_status_t DefineAgentExternalVariable(\n    const char *name,\n    hsa_agent_t agent,\n    hsa_variable_segment_t segment,\n    void *address) override;\n\n  hsa_status_t LoadCodeObject(\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    const char *options,\n    const std::string &uri,\n    hsa_loaded_code_object_t *loaded_code_object) override;\n\n  hsa_status_t LoadCodeObject(\n    hsa_agent_t agent,\n    hsa_code_object_t code_object,\n    size_t code_object_size,\n    const char *options,\n    const std::string &uri,\n    hsa_loaded_code_object_t *loaded_code_object) override;\n\n  hsa_status_t Freeze(const char *options) override;\n\n  hsa_status_t Validate(uint32_t *result) override {\n    amd::hsa::common::ReaderLockGuard<amd::hsa::common::ReaderWriterLock> reader_lock(rw_lock_);\n    assert(result);\n    *result = 0;\n    return HSA_STATUS_SUCCESS;\n  }\n\n  /// @note needed for hsa v1.0.\n  /// @todo remove during loader refactoring.\n  bool IsProgramSymbol(const char *symbol_name) override;\n\n  Symbol* GetSymbol(\n    const char *symbol_name,\n    const hsa_agent_t *agent) override;\n\n  hsa_status_t IterateSymbols(\n    iterate_symbols_f callback, void *data) override;\n\n  /// @since hsa v1.1.\n  hsa_status_t IterateAgentSymbols(\n      hsa_agent_t agent,\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_agent_t agent,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data) override;\n\n  /// @since hsa v1.1.\n  hsa_status_t IterateProgramSymbols(\n      hsa_status_t (*callback)(hsa_executable_t exec,\n                               hsa_executable_symbol_t symbol,\n                               void *data),\n      void *data) override;\n\n  hsa_status_t IterateLoadedCodeObjects(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      hsa_loaded_code_object_t loaded_code_object,\n      void *data),\n    void *data) override;\n\n  size_t GetNumSegmentDescriptors() override;\n\n  size_t QuerySegmentDescriptors(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t total_num_segment_descriptors,\n    size_t first_empty_segment_descriptor) override;\n\n  uint64_t FindHostAddress(uint64_t device_address) override;\n\n  void EnableReadOnlyMode();\n  void DisableReadOnlyMode();\n\n  void Print(std::ostream& out) override;\n  bool PrintToFile(const std::string& filename) override;\n\n  Context* context() { return context_; }\n  size_t id() { return id_; }\n\nprivate:\n  ExecutableImpl(const ExecutableImpl &e);\n  ExecutableImpl& operator=(const ExecutableImpl &e);\n\n  std::unique_ptr<amd::hsa::code::AmdHsaCode> code;\n\n  Symbol* GetSymbolInternal(\n    const char *symbol_name,\n    const hsa_agent_t *agent);\n\n  hsa_status_t LoadSegments(hsa_agent_t agent, const code::AmdHsaCode *c,\n                            uint32_t majorVersion);\n  hsa_status_t LoadSegmentsV1(hsa_agent_t agent, const code::AmdHsaCode *c);\n  hsa_status_t LoadSegmentsV2(hsa_agent_t agent, const code::AmdHsaCode *c);\n  hsa_status_t LoadSegmentV1(hsa_agent_t agent, const code::Segment *s);\n  hsa_status_t LoadSegmentV2(const code::Segment *data_segment,\n                             loader::Segment *load_segment);\n\n  hsa_status_t LoadSymbol(hsa_agent_t agent, amd::hsa::code::Symbol* sym, uint32_t majorVersion);\n  hsa_status_t LoadDefinitionSymbol(hsa_agent_t agent, amd::hsa::code::Symbol* sym, uint32_t majorVersion);\n  hsa_status_t LoadDeclarationSymbol(hsa_agent_t agent, amd::hsa::code::Symbol* sym, uint32_t majorVersion);\n\n  hsa_status_t ApplyRelocations(hsa_agent_t agent, amd::hsa::code::AmdHsaCode *c);\n  hsa_status_t ApplyStaticRelocationSection(hsa_agent_t agent, amd::hsa::code::RelocationSection* sec);\n  hsa_status_t ApplyStaticRelocation(hsa_agent_t agent, amd::hsa::code::Relocation *rel);\n  hsa_status_t ApplyDynamicRelocationSection(hsa_agent_t agent, amd::hsa::code::RelocationSection* sec);\n  hsa_status_t ApplyDynamicRelocation(hsa_agent_t agent, amd::hsa::code::Relocation *rel);\n\n  Segment* VirtualAddressSegment(uint64_t vaddr);\n  uint64_t SymbolAddress(hsa_agent_t agent, amd::hsa::code::Symbol* sym);\n  uint64_t SymbolAddress(hsa_agent_t agent, amd::elf::Symbol* sym);\n  Segment* SymbolSegment(hsa_agent_t agent, amd::hsa::code::Symbol* sym);\n  Segment* SectionSegment(hsa_agent_t agent, amd::hsa::code::Section* sec);\n\n  amd::hsa::common::ReaderWriterLock rw_lock_;\n  hsa_profile_t profile_;\n  Context *context_;\n  std::unique_ptr<Context> unique_context_;\n  Logger logger_;\n  const size_t id_;\n  hsa_default_float_rounding_mode_t default_float_rounding_mode_;\n  hsa_executable_state_t state_;\n\n  ProgramSymbolMap program_symbols_;\n  AgentSymbolMap agent_symbols_;\n  std::vector<ExecutableObject*> objects;\n  Segment *program_allocation_segment;\n  std::vector<LoadedCodeObjectImpl*> loaded_code_objects;\n};\n\nclass AmdHsaCodeLoader : public Loader {\nprivate:\n  Context* context;\n  std::vector<Executable*> executables;\n  amd::hsa::common::ReaderWriterLock rw_lock_;\n\npublic:\n  AmdHsaCodeLoader(Context* context_)\n    : context(context_) { assert(context); }\n\n  Context* GetContext() const override { return context; }\n\n  Executable* CreateExecutable(\n      hsa_profile_t profile,\n      const char *options,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode = HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT) override;\n\n  Executable* CreateExecutable(\n      std::unique_ptr<Context> isolated_context,\n      hsa_profile_t profile,\n      const char *options,\n      hsa_default_float_rounding_mode_t default_float_rounding_mode = HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT) override;\n\n  hsa_status_t FreezeExecutable(Executable *executable, const char *options) override;\n  void DestroyExecutable(Executable *executable) override;\n\n  hsa_status_t IterateExecutables(\n    hsa_status_t (*callback)(\n      hsa_executable_t executable,\n      void *data),\n    void *data) override;\n\n  hsa_status_t QuerySegmentDescriptors(\n    hsa_ven_amd_loader_segment_descriptor_t *segment_descriptors,\n    size_t *num_segment_descriptors) override;\n\n  hsa_executable_t FindExecutable(uint64_t device_address) override;\n\n  uint64_t FindHostAddress(uint64_t device_address) override;\n\n  void PrintHelp(std::ostream& out) override;\n\n  void EnableReadOnlyMode();\n  void DisableReadOnlyMode();\n};\n\n} // namespace loader\n} // namespace hsa\n} // namespace amd\n} // namespace rocr\n\n#endif // HSA_RUNTIME_CORE_LOADER_EXECUTABLE_HPP_\n"
  },
  {
    "path": "runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"pcs_runtime.h\"\n#include \"core/inc/agent.h\"\n#include \"core/inc/amd_gpu_agent.h\"\n#include \"core/inc/exceptions.h\"\n\nnamespace rocr {\nnamespace AMD {\nhsa_status_t handleException();\n\ntemplate <class T> static __forceinline T handleExceptionT() {\n  handleException();\n  abort();\n  return T();\n}\n}  // namespace AMD\n\n#define IS_OPEN()                                                                                  \\\n  do {                                                                                             \\\n    if (!core::Runtime::runtime_singleton_->IsOpen()) return HSA_STATUS_ERROR_NOT_INITIALIZED;     \\\n  } while (false)\n\ntemplate <class T> static __forceinline bool IsValid(T* ptr) {\n  return (ptr == NULL) ? NULL : ptr->IsValid();\n}\n\n#define TRY try {\n#define CATCH                                                                                      \\\n  }                                                                                                \\\n  catch (...) {                                                                                    \\\n    return AMD::handleException();                                                                 \\\n  }\n#define CATCHRET(RETURN_TYPE)                                                                      \\\n  }                                                                                                \\\n  catch (...) {                                                                                    \\\n    return AMD::handleExceptionT<RETURN_TYPE>();                                                   \\\n  }\n\nnamespace pcs {\n\nhsa_status_t hsa_ven_amd_pcs_iterate_configuration(\n    hsa_agent_t hsa_agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n    void* callback_data) {\n  TRY;\n  IS_OPEN();\n\n  core::Agent* agent = core::Agent::Convert(hsa_agent);\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return PcsRuntime::instance()->PcSamplingIterateConfig(agent, configuration_callback,\n                                                         callback_data);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_create(hsa_agent_t hsa_agent, hsa_ven_amd_pcs_method_kind_t method,\n                                    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency,\n                                    size_t buffer_size,\n                                    hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                    void* client_cb_data, hsa_ven_amd_pcs_t* handle) {\n  TRY;\n  IS_OPEN();\n  core::Agent* agent = core::Agent::Convert(hsa_agent);\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return PcsRuntime::instance()->PcSamplingCreate(\n      agent, method, units, interval, latency, buffer_size, data_ready_cb, client_cb_data, handle);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_create_from_id(uint32_t pcs_id, hsa_agent_t hsa_agent,\n                                            hsa_ven_amd_pcs_method_kind_t method,\n                                            hsa_ven_amd_pcs_units_t units, size_t interval,\n                                            size_t latency, size_t buffer_size,\n                                            hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                            void* client_cb_data, hsa_ven_amd_pcs_t* handle) {\n  TRY;\n  IS_OPEN();\n  core::Agent* agent = core::Agent::Convert(hsa_agent);\n  if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice)\n    return HSA_STATUS_ERROR_INVALID_AGENT;\n\n  return PcsRuntime::instance()->PcSamplingCreateFromId(pcs_id, agent, method, units, interval,\n                                                        latency, buffer_size, data_ready_cb,\n                                                        client_cb_data, handle);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_destroy(hsa_ven_amd_pcs_t handle) {\n  TRY;\n  return PcsRuntime::instance()->PcSamplingDestroy(handle);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_start(hsa_ven_amd_pcs_t handle) {\n  TRY;\n  return PcsRuntime::instance()->PcSamplingStart(handle);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_stop(hsa_ven_amd_pcs_t handle) {\n  TRY;\n  return PcsRuntime::instance()->PcSamplingStop(handle);\n  CATCH;\n}\n\nhsa_status_t hsa_ven_amd_pcs_flush(hsa_ven_amd_pcs_t handle) {\n  TRY;\n  return PcsRuntime::instance()->PcSamplingFlush(handle);\n  CATCH;\n}\n\nvoid LoadPcSampling(core::PcSamplingExtTableInternal* pcs_api) {\n  pcs_api->hsa_ven_amd_pcs_iterate_configuration_fn = hsa_ven_amd_pcs_iterate_configuration;\n  pcs_api->hsa_ven_amd_pcs_create_fn = hsa_ven_amd_pcs_create;\n  pcs_api->hsa_ven_amd_pcs_create_from_id_fn = hsa_ven_amd_pcs_create_from_id;\n  pcs_api->hsa_ven_amd_pcs_destroy_fn = hsa_ven_amd_pcs_destroy;\n  pcs_api->hsa_ven_amd_pcs_start_fn = hsa_ven_amd_pcs_start;\n  pcs_api->hsa_ven_amd_pcs_stop_fn = hsa_ven_amd_pcs_stop;\n  pcs_api->hsa_ven_amd_pcs_flush_fn = hsa_ven_amd_pcs_flush;\n}\n\n}  //  namespace pcs\n}  //  namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/pcs/inc/hsa_ven_amd_pc_sampling_impl.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_VEN_AMD_PC_SAMPLING_IMPL_H\n#define HSA_VEN_AMD_PC_SAMPLING_IMPL_H\n\n#include \"inc/hsa.h\"\n#include \"inc/hsa_ext_amd.h\"\n#include \"inc/hsa_ven_amd_pc_sampling.h\"\n#include \"core/inc/hsa_ext_interface.h\"\n\n//---------------------------------------------------------------------------//\n//  APIs that implement PC Sampling functionality\n//---------------------------------------------------------------------------//\n\nnamespace rocr {\nnamespace pcs {\n\nhsa_status_t hsa_ven_amd_pcs_iterate_configuration(\n    hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n    void* callback_data);\n\nhsa_status_t hsa_ven_amd_pcs_create(hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n                                    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency,\n                                    size_t buffer_size,\n                                    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback,\n                                    void* client_callback_data, hsa_ven_amd_pcs_t* pc_sampling);\n\nhsa_status_t hsa_ven_amd_pcs_create_from_id(\n    uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method,\n    hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data,\n    hsa_ven_amd_pcs_t* pc_sampling);\n\nhsa_status_t hsa_ven_amd_pcs_destroy(hsa_ven_amd_pcs_t pc_sampling);\n\nhsa_status_t hsa_ven_amd_pcs_start(hsa_ven_amd_pcs_t pc_sampling);\n\nhsa_status_t hsa_ven_amd_pcs_stop(hsa_ven_amd_pcs_t pc_sampling);\n\nhsa_status_t hsa_ven_amd_pcs_flush(hsa_ven_amd_pcs_t pc_sampling);\n\n// Update Api table with func pointers that implement functionality\nvoid LoadPcSampling(core::PcSamplingExtTableInternal* pcs_api);\n\n// Release resources acquired by Image implementation\nvoid ReleasePcSamplingRsrcs();\n\n}  // namespace pcs\n}  // namespace rocr\n\n#endif  //  HSA_VEN_AMD_PC_SAMPLING_IMPL_H\n"
  },
  {
    "path": "runtime/hsa-runtime/pcs/pcs_runtime.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#include \"pcs_runtime.h\"\n\n#include <assert.h>\n#include <mutex>\n\n#include \"core/inc/runtime.h\"\n\n#include \"core/inc/amd_gpu_agent.h\"\n\nnamespace rocr {\nnamespace pcs {\n\n#define IS_BAD_PTR(ptr)                                          \\\ndo {                                                           \\\n  if ((ptr) == NULL) return HSA_STATUS_ERROR_INVALID_ARGUMENT; \\\n} while (false)\n\n\nPcsRuntime* PcsRuntime::instance() {\n  PcsRuntime* instance = get_instance().load(std::memory_order_acquire);\n  if (instance == NULL) {\n    // Protect the initialization from multi threaded access.\n    std::lock_guard<std::mutex> lock(instance_mutex());\n\n    // Make sure we are not initializing it twice.\n    instance = get_instance().load(std::memory_order_relaxed);\n    if (instance != NULL) {\n      return instance;\n    }\n\n    instance = CreateSingleton();\n    if (instance == NULL) {\n      return NULL;\n    }\n  }\n\n  return instance;\n}\n\nPcsRuntime* PcsRuntime::CreateSingleton() {\n  PcsRuntime* instance = new PcsRuntime();\n\n  get_instance().store(instance, std::memory_order_release);\n  return instance;\n}\n\nvoid PcsRuntime::DestroySingleton() {\n  PcsRuntime* instance = get_instance().load(std::memory_order_acquire);\n  if (instance == NULL) {\n    return;\n  }\n\n  get_instance().store(NULL, std::memory_order_release);\n  delete instance;\n}\n\nvoid ReleasePcSamplingRsrcs() { PcsRuntime::DestroySingleton(); }\n\nbool PcsRuntime::SessionsActive() const {\n  return pc_sampling_.size() > 0;\n}\n\nPcsRuntime::PcSamplingSession::PcSamplingSession(\n    core::Agent* _agent, hsa_ven_amd_pcs_method_kind_t method, hsa_ven_amd_pcs_units_t units,\n    size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data)\n    : agent(_agent), thunkId_(0), active_(false), valid_(true), sample_size_(0) {\n  switch (method) {\n    case HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1:\n      sample_size_ = sizeof(perf_sample_hosttrap_v1_t);\n      break;\n    case HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1:\n      sample_size_ = sizeof(perf_sample_snapshot_v1_t);\n      break;\n    default:\n      valid_ = false;\n      return;\n  }\n\n  if (!interval || !buffer_size || (buffer_size % (2 * sample_size_))) {\n    valid_ = false;\n    return;\n  }\n\n  csd.method = method;\n  csd.units = units;\n  csd.interval = interval;\n  csd.latency = latency;\n  csd.buffer_size = buffer_size;\n  csd.data_ready_callback = data_ready_callback;\n  csd.client_callback_data = client_callback_data;\n\n  data_rdy.buf1 = nullptr;\n  data_rdy.buf1_sz = 0;\n  data_rdy.buf2 = nullptr;\n  data_rdy.buf2_sz = 0;\n}\n\nvoid PcsRuntime::PcSamplingSession::GetHsaKmtSamplingInfo(HsaPcSamplingInfo* sampleInfo) {\n  sampleInfo->value_min = 0;\n  sampleInfo->value_max = 0;\n  sampleInfo->flags = 0;\n  sampleInfo->value = csd.interval;\n\n  switch (csd.method) {\n    case HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1:\n      sampleInfo->method = HSA_PC_SAMPLING_METHOD_KIND_HOSTTRAP_V1;\n      break;\n    case HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1:\n      sampleInfo->method = HSA_PC_SAMPLING_METHOD_KIND_STOCHASTIC_V1;\n      break;\n  }\n\n  switch (csd.units) {\n    case HSA_VEN_AMD_PCS_INTERVAL_UNITS_MICRO_SECONDS:\n      sampleInfo->units = HSA_PC_SAMPLING_UNIT_INTERVAL_MICROSECONDS;\n      break;\n    case HSA_VEN_AMD_PCS_INTERVAL_UNITS_CLOCK_CYCLES:\n      sampleInfo->units = HSA_PC_SAMPLING_UNIT_INTERVAL_CYCLES;\n      break;\n    case HSA_VEN_AMD_PCS_INTERVAL_UNITS_INSTRUCTIONS:\n      sampleInfo->units = HSA_PC_SAMPLING_UNIT_INTERVAL_INSTRUCTIONS;\n      break;\n  }\n}\n\nhsa_status_t PcSamplingDataCopyCallback(void* _session, size_t bytes_to_copy, void* destination) {\n  assert(_session);\n  assert(destination);\n\n  PcsRuntime::PcSamplingSession* session =\n      reinterpret_cast<PcsRuntime::PcSamplingSession*>(_session);\n\n  return session->DataCopyCallback(reinterpret_cast<uint8_t*>(destination), bytes_to_copy);\n}\n\nhsa_status_t PcsRuntime::PcSamplingSession::DataCopyCallback(uint8_t* buffer,\n                                                             size_t bytes_to_copy) {\n  if (bytes_to_copy != (data_rdy.buf1_sz + data_rdy.buf2_sz)) return HSA_STATUS_ERROR_EXCEPTION;\n\n  if (data_rdy.buf1_sz) memcpy(buffer, data_rdy.buf1, data_rdy.buf1_sz);\n  if (data_rdy.buf2_sz) memcpy(buffer + data_rdy.buf1_sz, data_rdy.buf2, data_rdy.buf2_sz);\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t PcsRuntime::PcSamplingSession::HandleSampleData(uint8_t* buf1, size_t buf1_sz,\n                                                             uint8_t* buf2, size_t buf2_sz,\n                                                             size_t lost_sample_count) {\n  data_rdy.buf1 = buf1;\n  data_rdy.buf1_sz = buf1_sz;\n  data_rdy.buf2 = buf2;\n  data_rdy.buf2_sz = buf2_sz;\n\n  AMD::GpuAgent* gpuAgent = static_cast<AMD::GpuAgent*>(agent);\n\n  switch (csd.method) {\n    case HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1: {\n      size_t buf_samples = buf1_sz / sizeof(perf_sample_hosttrap_v1_t);\n      perf_sample_hosttrap_v1_t* samples = reinterpret_cast<perf_sample_hosttrap_v1_t*>(buf1);\n      while (buf_samples--) {\n        samples->timestamp = gpuAgent->TranslateTime(samples->timestamp);\n        samples++;\n      }\n\n      buf_samples = buf2_sz / sizeof(perf_sample_hosttrap_v1_t);\n      samples = reinterpret_cast<perf_sample_hosttrap_v1_t*>(buf2);\n      while (buf_samples--) {\n        samples->timestamp = gpuAgent->TranslateTime(samples->timestamp);\n        samples++;\n      }\n    }\n    break;\n    case HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1: {\n      size_t buf_samples = buf1_sz / sizeof(perf_sample_snapshot_v1_t);\n      perf_sample_snapshot_v1_t* samples = reinterpret_cast<perf_sample_snapshot_v1_t*>(buf1);\n      while (buf_samples--) {\n        samples->timestamp = gpuAgent->TranslateTime(samples->timestamp);\n        samples++;\n      }\n\n      buf_samples = buf2_sz / sizeof(perf_sample_snapshot_v1_t);\n      samples = reinterpret_cast<perf_sample_snapshot_v1_t*>(buf2);\n      while (buf_samples--) {\n        samples->timestamp = gpuAgent->TranslateTime(samples->timestamp);\n        samples++;\n      }\n    }\n    break;\n  }\n\n  csd.data_ready_callback(csd.client_callback_data, buf1_sz + buf2_sz, lost_sample_count,\n                          &PcSamplingDataCopyCallback,\n                          /* hsa_callback_data*/ this);\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t PcsRuntime::PcSamplingIterateConfig(\n    core::Agent* agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n    void* callback_data) {\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(agent);\n  return gpu_agent->PcSamplingIterateConfig(configuration_callback, callback_data);\n}\n\nhsa_status_t PcsRuntime::PcSamplingCreate(core::Agent* agent, hsa_ven_amd_pcs_method_kind_t method,\n                                          hsa_ven_amd_pcs_units_t units, size_t interval,\n                                          size_t latency, size_t buffer_size,\n                                          hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                          void* client_cb_data, hsa_ven_amd_pcs_t* handle) {\n\n  IS_BAD_PTR(handle);\n  IS_BAD_PTR(data_ready_cb);\n\n  return PcSamplingCreateInternal(\n      agent, method, units, interval, latency, buffer_size, data_ready_cb, client_cb_data, handle,\n      [](core::Agent* agent_, PcSamplingSession& session_) {\n        return static_cast<AMD::GpuAgentInt*>(agent_)->PcSamplingCreate(session_);\n      });\n}\n\nhsa_status_t PcsRuntime::PcSamplingCreateFromId(uint32_t ioctl_pcs_id, core::Agent* agent,\n                                                hsa_ven_amd_pcs_method_kind_t method,\n                                                hsa_ven_amd_pcs_units_t units, size_t interval,\n                                                size_t latency, size_t buffer_size,\n                                                hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                                void* client_cb_data, hsa_ven_amd_pcs_t* handle) {\n  IS_BAD_PTR(handle);\n  IS_BAD_PTR(data_ready_cb);\n\n  return PcSamplingCreateInternal(\n      agent, method, units, interval, latency, buffer_size, data_ready_cb, client_cb_data, handle,\n      [&](core::Agent* agent_, PcSamplingSession& session_) {\n        return static_cast<AMD::GpuAgentInt*>(agent_)->PcSamplingCreateFromId(ioctl_pcs_id,\n                                                                              session_);\n      });\n}\n\nhsa_status_t PcsRuntime::PcSamplingCreateInternal(\n    core::Agent* agent, hsa_ven_amd_pcs_method_kind_t method, hsa_ven_amd_pcs_units_t units,\n    size_t interval, size_t latency, size_t buffer_size,\n    hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb, void* client_cb_data,\n    hsa_ven_amd_pcs_t* handle, agent_pcs_create_fn_t agent_pcs_create_fn) {\n  ScopedAcquire<KernelMutex> lock(&pc_sampling_lock_);\n\n  handle->handle = ++pc_sampling_id_;\n  // create a new PcSamplingSession(agent, method, units, interval, latency, buffer_size,\n  // data_ready_cb, client_cb_data) reference and insert into pc_sampling_\n  pc_sampling_.emplace(std::piecewise_construct, std::forward_as_tuple(handle->handle),\n                       std::forward_as_tuple(agent, method, units, interval, latency, buffer_size,\n                                             data_ready_cb, client_cb_data));\n\n  if (!pc_sampling_[handle->handle].isValid()) {\n      pc_sampling_.erase(handle->handle);\n      return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_status_t ret = agent_pcs_create_fn(agent, pc_sampling_[handle->handle]);\n  if (ret != HSA_STATUS_SUCCESS) {\n    pc_sampling_.erase(handle->handle);\n    return ret;\n  }\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t PcsRuntime::PcSamplingDestroy(hsa_ven_amd_pcs_t handle) {\n  ScopedAcquire<KernelMutex> lock(&pc_sampling_lock_);\n  auto pcSamplingSessionIt = pc_sampling_.find(reinterpret_cast<uint64_t>(handle.handle));\n  if (pcSamplingSessionIt == pc_sampling_.end()) {\n    debug_warning(false && \"Cannot find PcSampling session\");\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(pcSamplingSessionIt->second.agent);\n\n  hsa_status_t ret = gpu_agent->PcSamplingDestroy(pcSamplingSessionIt->second);\n  pc_sampling_.erase(pcSamplingSessionIt);\n  return ret;\n}\n\nhsa_status_t PcsRuntime::PcSamplingStart(hsa_ven_amd_pcs_t handle) {\n  ScopedAcquire<KernelMutex> lock(&pc_sampling_lock_);\n  auto pcSamplingSessionIt = pc_sampling_.find(reinterpret_cast<uint64_t>(handle.handle));\n  if (pcSamplingSessionIt == pc_sampling_.end()) {\n    debug_warning(false && \"Cannot find PcSampling session\");\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(pcSamplingSessionIt->second.agent);\n\n  return gpu_agent->PcSamplingStart(pcSamplingSessionIt->second);\n}\n\nhsa_status_t PcsRuntime::PcSamplingStop(hsa_ven_amd_pcs_t handle) {\n  ScopedAcquire<KernelMutex> lock(&pc_sampling_lock_);\n  auto pcSamplingSessionIt = pc_sampling_.find(reinterpret_cast<uint64_t>(handle.handle));\n  if (pcSamplingSessionIt == pc_sampling_.end()) {\n    debug_warning(false && \"Cannot find PcSampling session\");\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(pcSamplingSessionIt->second.agent);\n\n  return gpu_agent->PcSamplingStop(pcSamplingSessionIt->second);\n}\n\nhsa_status_t PcsRuntime::PcSamplingFlush(hsa_ven_amd_pcs_t handle) {\n  ScopedAcquire<KernelMutex> lock(&pc_sampling_lock_);\n  auto pcSamplingSessionIt = pc_sampling_.find(reinterpret_cast<uint64_t>(handle.handle));\n  if (pcSamplingSessionIt == pc_sampling_.end()) {\n    debug_warning(false && \"Cannot find PcSampling session\");\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n  AMD::GpuAgentInt* gpu_agent = static_cast<AMD::GpuAgentInt*>(pcSamplingSessionIt->second.agent);\n\n  return gpu_agent->PcSamplingFlush(pcSamplingSessionIt->second);\n}\n\n}  // namespace pcs\n}  // namespace rocr\n"
  },
  {
    "path": "runtime/hsa-runtime/pcs/pcs_runtime.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n//\n// The University of Illinois/NCSA\n// Open Source License (NCSA)\n//\n// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved.\n//\n// Developed by:\n//\n//                 AMD Research and AMD HSA Software Development\n//\n//                 Advanced Micro Devices, Inc.\n//\n//                 www.amd.com\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal with the Software without restriction, including without limitation\n// the rights to use, copy, modify, merge, publish, distribute, sublicense,\n// and/or sell copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following conditions:\n//\n//  - Redistributions of source code must retain the above copyright notice,\n//    this list of conditions and the following disclaimers.\n//  - Redistributions in binary form must reproduce the above copyright\n//    notice, this list of conditions and the following disclaimers in\n//    the documentation and/or other materials provided with the distribution.\n//  - Neither the names of Advanced Micro Devices, Inc,\n//    nor the names of its contributors may be used to endorse or promote\n//    products derived from this Software without specific prior written\n//    permission.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS WITH THE SOFTWARE.\n//\n////////////////////////////////////////////////////////////////////////////////\n\n#ifndef HSA_RUNTIME_PCS_RUNTIME_H\n#define HSA_RUNTIME_PCS_RUNTIME_H\n\n#include <atomic>\n#include <map>\n#include <mutex>\n\n#include \"hsakmt/hsakmt.h\"\n\n#include \"hsa_ven_amd_pc_sampling.h\"\n#include \"core/inc/agent.h\"\n#include \"core/inc/exceptions.h\"\n\n\nnamespace rocr {\nnamespace pcs {\n\nclass PcsRuntime {\n public:\n  PcsRuntime() : pc_sampling_id_(0) {}\n  ~PcsRuntime() {}\n\n  /// @brief Getter for the PcsRuntime singleton object.\n  static PcsRuntime* instance();\n\n  bool SessionsActive() const;\n\n  /// @brief Destroy singleton object.\n  static void DestroySingleton();\n\n  class PcSamplingSession {\n   public:\n    PcSamplingSession() : agent(NULL), thunkId_(0), active_(false){};\n    PcSamplingSession(core::Agent* agent, hsa_ven_amd_pcs_method_kind_t method,\n                      hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency,\n                      size_t buffer_size, hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback,\n                      void* client_callback_data);\n    ~PcSamplingSession(){};\n\n    bool isValid() const { return valid_; }\n    size_t buffer_size() const { return csd.buffer_size; }\n    hsa_ven_amd_pcs_method_kind_t method() const { return csd.method; }\n    size_t latency() const { return csd.latency; }\n    size_t sample_size() const { return sample_size_; }\n\n    void GetHsaKmtSamplingInfo(HsaPcSamplingInfo* sampleInfo);\n    hsa_status_t HandleSampleData(uint8_t* buf1, size_t buf1_sz, uint8_t* buf2, size_t buf2_sz,\n                                  size_t lost_sample_count);\n    hsa_status_t DataCopyCallback(uint8_t* buffer, size_t buffer_size);\n\n    core::Agent* agent;\n    void SetThunkId(HsaPcSamplingTraceId thunkId) { thunkId_ = thunkId; }\n    HsaPcSamplingTraceId ThunkId() { return thunkId_; }\n    bool isActive() { return active_; }\n    void start() { active_ = true; }\n    void stop() { active_ = false; }\n\n   private:\n    HsaPcSamplingTraceId thunkId_;\n\n    bool active_;  // Set to true when the session is started\n    bool valid_;   // Whether configuration parameters are valid\n    size_t sample_size_;\n\n    struct client_session_data_t {\n      hsa_ven_amd_pcs_method_kind_t method;\n      hsa_ven_amd_pcs_units_t units;\n      size_t interval;\n      size_t latency;\n      size_t buffer_size;\n      hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback;\n      void* client_callback_data;\n    };\n    struct client_session_data_t csd;\n\n    struct data_ready_info_t {\n      uint8_t* buf1;\n      size_t buf1_sz;\n      uint8_t* buf2;\n      size_t buf2_sz;\n    };\n    struct data_ready_info_t data_rdy;\n  };  // class PcSamplingSession\n\n  hsa_status_t PcSamplingIterateConfig(\n      core::Agent* agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback,\n      void* callback_data);\n\n  hsa_status_t PcSamplingCreate(core::Agent* agent, hsa_ven_amd_pcs_method_kind_t method,\n                                hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency,\n                                size_t buffer_size,\n                                hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                void* client_cb_data, hsa_ven_amd_pcs_t* handle);\n\n\n  hsa_status_t PcSamplingCreateFromId(uint32_t ioctl_pcs_id, core::Agent* agent,\n                                      hsa_ven_amd_pcs_method_kind_t method,\n                                      hsa_ven_amd_pcs_units_t units, size_t interval,\n                                      size_t latency, size_t buffer_size,\n                                      hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                      void* client_cb_data, hsa_ven_amd_pcs_t* handle);\n\n  hsa_status_t PcSamplingDestroy(hsa_ven_amd_pcs_t handle);\n  hsa_status_t PcSamplingStart(hsa_ven_amd_pcs_t handle);\n  hsa_status_t PcSamplingStop(hsa_ven_amd_pcs_t handle);\n  hsa_status_t PcSamplingFlush(hsa_ven_amd_pcs_t handle);\n\n private:\n  /// @brief Initialize singleton object, must be called once.\n  static PcsRuntime* CreateSingleton();\n\n  /// Pointer to singleton object.\n  static __forceinline std::atomic<PcsRuntime*>& get_instance() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n    static std::atomic<PcsRuntime*>* instance_ = new std::atomic<PcsRuntime*>();\n    return *instance_;\n  }\n  static __forceinline std::mutex& instance_mutex() {\n    // This allocation is meant to last until the last thread has exited.\n    // It is intentionally not freed.\n   static std::mutex* instance_mutex_ = new std::mutex();\n   return *instance_mutex_;\n}\n  // Map of pc sampling sessions indexed by hsa_ven_amd_pcs_t handle\n  std::map<uint64_t, PcSamplingSession> pc_sampling_;\n  KernelMutex pc_sampling_lock_;\n  uint64_t pc_sampling_id_;\n\n  DISALLOW_COPY_AND_ASSIGN(PcsRuntime);\n\n  using agent_pcs_create_fn_t = std::function<hsa_status_t(core::Agent*, PcSamplingSession&)>;\n  hsa_status_t PcSamplingCreateInternal(core::Agent* agent, hsa_ven_amd_pcs_method_kind_t method,\n                                        hsa_ven_amd_pcs_units_t units, size_t interval,\n                                        size_t latency, size_t buffer_size,\n                                        hsa_ven_amd_pcs_data_ready_callback_t data_ready_cb,\n                                        void* client_cb_data, hsa_ven_amd_pcs_t* handle,\n                                        agent_pcs_create_fn_t agent_pcs_create_fn);\n};\n\n}  // namespace pcs\n}  // namespace rocr\n#endif  // HSA_RUNTIME_PCS_RUNTIME_H\n"
  },
  {
    "path": "runtime/hsa-runtime-tools/CMakeLists.txt",
    "content": "cmake_minimum_required ( VERSION 3.5.0 )\n\n# Set ext runtime module name and project name.\nset ( TOOLS_NAME \"hsa-runtime-tools\" )\nset ( TOOLS_TARGET \"${TOOLS_NAME}64\" )\nset ( TOOLS_LIBRARY \"lib${TOOLS_TARGET}\" )\nproject ( ${TOOLS_TARGET} )\n\n# Optionally, build with ccache.\nset(ROCM_CCACHE_BUILD OFF CACHE BOOL \"Set to ON for a ccache enabled build\")\nif (ROCM_CCACHE_BUILD)\n  find_program(CCACHE_PROGRAM ccache)\n  if (CCACHE_PROGRAM)\n    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PROGRAM})\n  else()\n    message(WARNING \"Unable to find ccache. Falling back to real compiler\")\n  endif() # if (CCACHE_PROGRAM)\nendif() # if (ROCM_CCACHE_BUILD)\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules\" )\ninclude ( utils )\n\n## Compiler preproc definitions.\n#add_definitions ( -D__linux__ )\nadd_definitions ( -DUNIX_OS )\nadd_definitions ( -DLINUX )\nadd_definitions ( -D__AMD64__ )\nadd_definitions ( -D__x86_64__ )\nadd_definitions ( -DAMD_INTERNAL_BUILD )\nadd_definitions ( -DLITTLEENDIAN_CPU=1 )\nadd_definitions ( -D HSA_DEPRECATED= )\n\n## Get the package version. The defaults to 1.0.0.\nget_version( \"1.1.9\")\nset(SO_MAJOR 1)\nset(SO_MINOR 1)\nif ( ${ROCM_PATCH_VERSION} )\n    set ( SO_PATCH ${ROCM_PATCH_VERSION})\n    set ( VERSION_PATCH ${ROCM_PATCH_VERSION})\nelse ()\n    set(SO_PATCH 9)\nendif ()\n\nset( SO_VERSION_STRING \"${SO_MAJOR}.${SO_MINOR}.${SO_PATCH}\" )\nset( PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_COMMIT_COUNT}-${VERSION_JOB}-${VERSION_HASH}\" )\n\n## Find the hsakmt library and include files\nget_include_path( HSAKMT_INC_PATH \"libhsakmt include path\" NAMES \"hsakmt.h\" \"libhsakmt/hsakmt.h\" HINTS \"${CMAKE_BINARY_DIR}/../../include\" \"${CMAKE_CURRENT_SOURCE_DIR}/../../../../libhsakmt/include\" PATHS \"/opt/rocm/include\")\nget_library_path( HSAKMT_LIB_PATH \"libhsakmt library path\" NAMES \"libhsakmt.so\" HINTS \"${CMAKE_BINARY_DIR}/../../lib\" \"${CMAKE_BINARY_DIR}/../roct\" PATHS \"/opt/rocm/lib\")\ninclude_directories( ${HSAKMT_INC_PATH} )\nlink_directories( ${HSAKMT_LIB_PATH} )\n\n## Find the hsa-runtime and include files\nget_include_path( HSA_INC_PATH \"ROCr include path\" NAMES \"hsa.h\" \"hsa/hsa.h\" HINTS \"${CMAKE_BINARY_DIR}/../../include\" \"${CMAKE_CURRENT_SOURCE_DIR}/../hsa-runtime/inc\" PATHS \"/opt/rocm/include\")\nget_library_path( HSA_LIB_PATH \"ROCr library path\" NAMES \"libhsa-runtime64.so\" HINTS \"${CMAKE_BINARY_DIR}/../../lib\" \"${CMAKE_BINARY_DIR}/../hsa-core\" \"${CMAKE_CURRENT_SOURCE_DIR}/../hsa-runtime/build\" PATHS \"/opt/rocm/lib\")\ninclude_directories( ${HSA_INC_PATH} )\nlink_directories( ${HSA_LIB_PATH} )\n\n## External dependencies\nget_include_path( REG_INCLUDE \"ASIC register directory\" NAMES \"si_id.h\" HINTS \"${CMAKE_CURRENT_SOURCE_DIR}/../../../../p4/driver/drivers/inc/asic_reg\" \"${HSA_CLOSED_SOURCE_DIR}/drivers/inc/asic_reg\" \"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../drivers/inc/asic_reg\" )\n\n## Find self\nif( \"${TOOLS_SOURCE_DIR}\" STREQUAL \"\" )\n    get_include_path( TOOLS_SOURCE_FILE null NAMES \"inc/amd_hsa_tools_interfaces.h\" HINTS \"${CMAKE_CURRENT_SOURCE_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}/../../tools/\" )\n    get_filename_component( TOOLS_SOURCE_DIR \"${TOOLS_SOURCE_FILE}/..\" ABSOLUTE )\n    unset( TOOLS_SOURCE_FILE CACHE )\nendif()\nset( TOOLS_SOURCE_DIR ${TOOLS_SOURCE_DIR} CACHE PATH \"Tools lib source dir\" FORCE )\n\nget_filename_component( OPEN_SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/..\" ABSOLUTE CACHE )\nset( OPEN_SOURCE_DIR ${OPEN_SOURCE_DIR} CACHE PATH \"Open source root dir\" FORCE )\n\n## Set RUNPATH - ../../lib covers use of the legacy symlink in /hsa/lib/\nset(CMAKE_INSTALL_RPATH \"$ORIGIN;$ORIGIN/../../lib;$ORIGIN/../../lib64;$ORIGIN/../lib64\")\n\n## ------------------------- Linux Compiler and Linker options -------------------------\nset ( CMAKE_CXX_FLAGS \"-std=c++11 \")\n\nset ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Werror=return-type -Werror -fexceptions -fno-rtti -fvisibility=hidden -Wno-error=sign-compare -Wno-error=enum-compare -Wno-sign-compare -Wno-write-strings -Wno-deprecated-declarations -Wno-conversion-null -fno-math-errno -fno-threadsafe-statics -fmerge-all-constants -fms-extensions -Wno-error=comment -Wno-comment -Wno-error=pointer-arith -Wno-pointer-arith -fPIC\" )\n\nif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86_64\" )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m64  -msse -msse2\" )\nelseif ( CMAKE_SYSTEM_PROCESSOR STREQUAL \"x86\" )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -m32\" )\nendif ()\n\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Debug )\n    set ( CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ggdb\" )\nendif ()\n\nset ( DRVDEF \"${TOOLS_SOURCE_DIR}/make/hsatools.so.def\" )\n\nset ( CMAKE_SHARED_LINKER_FLAGS \"-Wl,-Bdynamic -Wl,-z,noexecstack -Wl,--version-script=${DRVDEF} -Wl,--enable-new-dtags\" )\n\n## Library path(s).\ninclude_directories ( ${REG_INCLUDE} )\ninclude_directories ( ${TOOLS_SOURCE_DIR} )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/.. )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime/inc )\ninclude_directories ( ${OPEN_SOURCE_DIR}/hsa-runtime/core/inc )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/inc )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/commandwriter )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/commandwriter/include/si )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/common )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/debugger )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/intercept )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/profiler )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/threadtrace )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000 )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gen )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8 )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81 )\ninclude_directories ( ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9 )\n\nset ( CORE_SRC   ${OPEN_SOURCE_DIR}/hsa-runtime/core/common/shared.cpp\n                 ${OPEN_SOURCE_DIR}/hsa-runtime/core/common/hsa_table_interface.cpp )\n\nset ( CMDWRITER_SRC   ${TOOLS_SOURCE_DIR}/commandwriter/aql_hw_cmdwriter.cpp\n                      ${TOOLS_SOURCE_DIR}/commandwriter/ci_aql_common.cpp\n                      ${TOOLS_SOURCE_DIR}/commandwriter/gfx9_cmdwriter.cpp\n                      ${TOOLS_SOURCE_DIR}/commandwriter/gfx9_factory.cpp\n                      ${TOOLS_SOURCE_DIR}/commandwriter/pre_gfx9_factory.cpp\n                      ${TOOLS_SOURCE_DIR}/commandwriter/cmdwriter.cpp )\n\nset ( COMMON_SRC      ${TOOLS_SOURCE_DIR}/common/amd_asic_type.cpp\n                      ${TOOLS_SOURCE_DIR}/common/amd_tools_interface.cpp )\n\nset ( DEBUGGER_SRC    ${TOOLS_SOURCE_DIR}/debugger/cwsr_trapstring_perf.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/gpu_trap_event.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/hsa_ext_debugger.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/kfd_event.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/pm4_queue.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/runtime_trapstring.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/shader_event.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/trap_finalizer.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/trap_handler.cpp\n                      ${TOOLS_SOURCE_DIR}/debugger/trap_manager.cpp )\n\nset ( INTERCEPT_SRC   ${TOOLS_SOURCE_DIR}/intercept/amd_sw_aql_command_processor.cpp\n                      ${TOOLS_SOURCE_DIR}/intercept/hsa_amd_tools.cpp\n                      ${TOOLS_SOURCE_DIR}/intercept/aql_pm4_factory.cpp\n                      ${TOOLS_SOURCE_DIR}/intercept/aql_proxy_queue.cpp\n                      ${TOOLS_SOURCE_DIR}/intercept/profiler.cpp )\n\nset ( PROFILER_SRC    ${TOOLS_SOURCE_DIR}/profiler/gpu_countergroup.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/gpu_counter.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/var_data.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/info_set.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/parameter_set.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/ci_blockinfo.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/ci_pmu.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/vi_blockinfo.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/vi_pmu.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/ai_blockinfo.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/ai_pmu.cpp\n                      ${TOOLS_SOURCE_DIR}/profiler/hsa_ext_profiler.cpp )\n\nset ( THREAD_TRACE_SRC    ${TOOLS_SOURCE_DIR}/threadtrace/thread_trace.cpp\n                          ${TOOLS_SOURCE_DIR}/threadtrace/gfx9_factory.cpp\n                          ${TOOLS_SOURCE_DIR}/threadtrace/gfx9_thread_trace.cpp\n                          ${TOOLS_SOURCE_DIR}/threadtrace/pre_gfx9_factory.cpp\n                          ${TOOLS_SOURCE_DIR}/threadtrace/pre_gfx9_thread_trace.cpp )\n\nset ( SP3_R1000_SRC   ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-dispatch.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-eval.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-gc.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-int.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-lib.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-main.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-merge-shaders.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-native.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/sp3-vm.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gen/sp3-parse.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gen/sp3-lex.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-dis.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-gen.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-inst-info.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-regs.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/ci/sp3-ci-tables.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-dis.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-gen.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-inst-info.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-regs.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/si/sp3-si-tables.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81/sp3-gfx81-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81/sp3-gfx81-dis.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81/sp3-gfx81-gen.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81/sp3-gfx81-inst-info.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx81/sp3-gfx81-regs.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-dis.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-gen.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-inst-info.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-regs.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx8/sp3-gfx8-tables.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9/sp3-gfx9-asic.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9/sp3-gfx9-dis.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9/sp3-gfx9-gen.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9/sp3-gfx9-inst-info.c\n                      ${TOOLS_SOURCE_DIR}/sp3/Chip/R1000/gfx9/sp3-gfx9-regs.c )\n\nset ( UTIL_SRC   ${OPEN_SOURCE_DIR}/hsa-runtime/core/util/timer.cpp\n                 ${OPEN_SOURCE_DIR}/hsa-runtime/core/util/small_heap.cpp\n                 ${OPEN_SOURCE_DIR}/hsa-runtime/core/util/lnx/os_linux.cpp )\n\n\n## This is the main shared library.\nadd_library ( ${TOOLS_TARGET} SHARED ${CORE_SRC}\n                                     ${COMMON_SRC}\n                                     ${CMD_WRITER_SRC}\n                                     ${CMDWRITER_SRC}\n                                     ${DEBUGGER_SRC}\n                                     ${INTERCEPT_SRC}\n                                     ${PROFILER_SRC}\n                                     ${THREAD_TRACE_SRC}\n                                     ${SP3_R1000_SRC}\n                                     ${UTIL_SRC} )\n\n## Set the VERSION and SOVERSION values\nset_property ( TARGET ${TOOLS_TARGET} PROPERTY VERSION \"${SO_VERSION_STRING}\" )\nset_property ( TARGET ${TOOLS_TARGET} PROPERTY SOVERSION \"${SO_MAJOR}\" )\n\n## Add the required link libraries\ntarget_link_libraries (\n    ${TOOLS_TARGET}\n    PRIVATE hsa-runtime64\n    PRIVATE hsakmt\n    c dl pthread rt\n)\n\n## If the build is Release, strip the target library\nif ( \"${CMAKE_BUILD_TYPE}\" STREQUAL Release )\n    add_custom_command ( TARGET ${TOOLS_TARGET} POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE_NAME:${TOOLS_TARGET}> )\nendif ()\n\n## Create symlinks for legacy packaging and install\nadd_custom_target ( hsa_tools_lib_link ALL WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E create_symlink ../hsa/lib/${TOOLS_LIBRARY}.so ${TOOLS_LIBRARY}-link.so )\n\n## Set install information\ninstall ( TARGETS ${TOOLS_TARGET} LIBRARY DESTINATION hsa/lib )\ninstall ( DIRECTORY ${TOOLS_SOURCE_DIR}/inc/ DESTINATION hsa/include/hsa FILES_MATCHING PATTERN \"*.h\" )\ninstall ( FILES ${CMAKE_CURRENT_BINARY_DIR}/${TOOLS_LIBRARY}-link.so DESTINATION lib PERMISSIONS OWNER_WRITE OWNER_READ RENAME ${TOOLS_LIBRARY}.so )\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and#or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and#or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.5.0 )\n\n## Set the name and project name.\nset ( PROJECT_STRING hsa-ext-rocr-dev )\nproject ( ${PROJECT_STRING} )\n\nadd_subdirectory(\"${CMAKE_CURRENT_SOURCE_DIR}/../../hsa-ext-image\" \"../hsa-ext-image\")\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../../cmake_modules\" )\ninclude ( utils )\n\n## Get the package version.\nget_version ( \"1.1.9\" )\nif ( ${ROCM_PATCH_VERSION} )\n    set ( VERSION_PATCH ${ROCM_PATCH_VERSION})\nendif ()\n\nset( PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_COMMIT_COUNT}-${VERSION_JOB}-${VERSION_HASH}\" )\n\n## Packaging directives\nset ( CPACK_GENERATOR \"DEB;RPM\" CACHE STRING \"Package types to build\")\n\nset ( CPACK_PACKAGE_NAME ${PROJECT_NAME} )\nset ( CPACK_PACKAGE_VENDOR \"Advanced Micro Devices, Inc.\" )\nset ( CPACK_PACKAGE_VERSION ${PACKAGE_VERSION_STRING} )\nset ( CPACK_PACKAGE_CONTACT \"Advanced Micro Devices, Inc.\" )\nset ( CPACK_PACKAGE_DESCRIPTION_SUMMARY \"AMD Heterogeneous System Architecture HSA - Linux HSA Runtime extensions for ROCm platforms\" )\nset ( CPACK_PACKAGE_DESCRIPTION_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/description\" )\nset ( CPACK_RESOURCE_FILE_LICENSE \"${CMAKE_CURRENT_SOURCE_DIR}/copyright\" )\n\n# Debian package specific variables\nset ( CPACK_DEBIAN_FILE_NAME \"DEB-DEFAULT\" )\nset ( CPACK_DEBIAN_PACKAGE_DEPENDS \"hsakmt-roct, hsa-rocr-dev\" )\nset ( CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/RadeonOpenCompute/ROCR-Runtime\" )\nset ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA \"${CMAKE_CURRENT_SOURCE_DIR}/postinst;${CMAKE_CURRENT_SOURCE_DIR}/prerm\" )\n\n# RPM package specific variables\nset ( CPACK_RPM_FILE_NAME \"RPM-DEFAULT\" )\nset ( CPACK_RPM_PACKAGE_DEPENDS \"hsakmt-roct, hsa-rocr-dev\" )\nset ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_post\" )\nset ( CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_postun\" )\n\ninclude ( CPack )\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/Old CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and#or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and#or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.5.0 )\n\n## Set the name and project name.\nset ( PROJECT_STRING hsa-ext-rocr-dev )\nproject ( ${PROJECT_STRING} )\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../../cmake_modules\" )\ninclude ( utils )\n\n## Get the package version.\nget_version ( \"1.2.0\" )\n\nset( PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_COMMIT_COUNT}-${VERSION_JOB}-${VERSION_BUILD_ID}-${VERSION_HASH}\" )\n\n## Packaging directives\nset ( CPACK_GENERATOR \"DEB;RPM\" CACHE STRING \"Package types to build\")\n\nset ( PACKAGE_DIRECTORIES \"hsa/lib\")\nadd_custom_command ( OUTPUT ${PACKAGE_DIRECTORIES} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory \"hsa/lib\" ) \nadd_custom_target (create_dirs DEPENDS ${PACKAGE_DIRECTORIES} )\n\nset ( TOOLS_NAME     \"libhsa-runtime-tools64\" )\nset ( IMAGE_NAME     \"libhsa-ext-image64\" )\n\nset ( TOOLS_LIBRARY_SOURCE     \"${OUT_DIR}/lib/${TOOLS_NAME}.so*\" )\nset ( IMAGE_LIBRARY_SOURCE     \"${OUT_DIR}/lib/${IMAGE_NAME}.so*\" )\n\nset ( TOOLS_LIBRARY_TARGET     \"${CMAKE_CURRENT_BINARY_DIR}/hsa/lib/${TOOLS_NAME}.so\" )\nset ( IMAGE_LIBRARY_TARGET     \"${CMAKE_CURRENT_BINARY_DIR}/hsa/lib/${IMAGE_NAME}.so\" )\n\nadd_custom_command ( OUTPUT ${TOOLS_LIBRARY_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n                     COMMAND ${CMAKE_COMMAND} -E copy ${TOOLS_LIBRARY_SOURCE} \"${CMAKE_CURRENT_BINARY_DIR}/hsa/lib/\" )\n\nadd_custom_command ( OUTPUT ${IMAGE_LIBRARY_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n                     COMMAND ${CMAKE_COMMAND} -E copy ${IMAGE_LIBRARY_SOURCE} \"${CMAKE_CURRENT_BINARY_DIR}/hsa/lib/\" )\n\nadd_custom_target ( copy_targets ALL DEPENDS create_dirs\n                                        ${TOOLS_LIBRARY_TARGET}\n                                        ${IMAGE_LIBRARY_TARGET}\n                                        )\n\ninstall ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hsa/ DESTINATION hsa USE_SOURCE_PERMISSIONS )\n\nset ( CPACK_PACKAGE_NAME ${PROJECT_NAME} )\nset ( CPACK_PACKAGE_VENDOR \"AMD\" )\nset ( CPACK_PACKAGE_VERSION ${PACKAGE_VERSION_STRING} )\nset ( CPACK_PACKAGE_CONTACT \"Advanced Micro Devices Inc.\" )\nset ( CPACK_PACKAGE_DESCRIPTION_SUMMARY \"AMD Heterogeneous System Architecture HSA - Linux HSA Runtime extensions for ROCm platforms\" )\nset ( CPACK_PACKAGE_DESCRIPTION_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/description\" )\nset ( CPACK_RESOURCE_FILE_LICENSE \"${CMAKE_CURRENT_SOURCE_DIR}/copyright\" )\n\n# Debian package specific variables\nset ( CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/RadeonOpenCompute/ROCR-Runtime\" )\nset ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA \"${CMAKE_CURRENT_SOURCE_DIR}/postinst;${CMAKE_CURRENT_SOURCE_DIR}/prerm\" )\n\n# RPM package specific variables\nset ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_post\" )\nset ( CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_postun\" )\n\ninclude ( CPack )\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/copyright",
    "content": "The University of Illinois/NCSA\nOpen Source License (NCSA)\n\nCopyright (c) 2014-2016, Advanced Micro Devices, Inc. All rights reserved.\n\nDeveloped by:\n\n                AMD Research and AMD HSA Software Development\n\n                Advanced Micro Devices, Inc.\n\n                www.amd.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal with the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\n - Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimers.\n - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimers in\n   the documentation and/or other materials provided with the distribution.\n - Neither the names of Advanced Micro Devices, Inc,\n   nor the names of its contributors may be used to endorse or promote\n   products derived from this Software without specific prior written\n   permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS WITH THE SOFTWARE.\n\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/description",
    "content": "This package includes the user-mode runtime necessary for host applications to launch compute kernels to available HSA and ROCm components. This version is consistent with the 1.0 Final HSA Runtime Programmer's Reference Manual and targets AMD AMD Fiji ASICS on supported platforms.\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/postinst",
    "content": "#/bin/bash\n\nset -e\n\ndo_ldconfig() {\n    echo /opt/rocm/hsa/lib > /etc/ld.so.conf.d/hsa-ext-rocr-dev.conf && ldconfig\n}\n\ncase \"$1\" in\n   configure)\n       do_ldconfig\n   ;;\n   abort-upgrade|abort-remove|abort-deconfigure)\n       echo \"$1\"\n   ;;\n   *)\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/prerm",
    "content": "#!/bin/bash\n\nset -e\n\nrm_ldconfig() {\n    rm -f /etc/ld.so.conf.d/hsa-ext-rocr-dev.conf && ldconfig\n}\n\ncase \"$1\" in\n   remove)\n       rm_ldconfig\n   ;;\n   purge)\n   ;;\n   *)\n       exit 0\n   ;;\nesac\n\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/rpm_post",
    "content": "echo /opt/rocm/hsa/lib > /etc/ld.so.conf.d/hsa-ext-rocr-dev.conf && ldconfig\n"
  },
  {
    "path": "runtime/packages/hsa-ext-rocr-dev/rpm_postun",
    "content": "if [ $1 -eq 0 ]; then\n    rm -f /etc/ld.so.conf.d/hsa-ext-rocr-dev.conf && ldconfig\nfi\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/CMakeLists.txt",
    "content": "################################################################################\n##\n## The University of Illinois/NCSA\n## Open Source License (NCSA)\n##\n## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.\n##\n## Developed by:\n##\n##                 AMD Research and AMD HSA Software Development\n##\n##                 Advanced Micro Devices, Inc.\n##\n##                 www.amd.com\n##\n## Permission is hereby granted, free of charge, to any person obtaining a copy\n## of this software and associated documentation files (the \"Software\"), to\n## deal with the Software without restriction, including without limitation\n## the rights to use, copy, modify, merge, publish, distribute, sublicense,\n## and#or sell copies of the Software, and to permit persons to whom the\n## Software is furnished to do so, subject to the following conditions:\n##\n##  - Redistributions of source code must retain the above copyright notice,\n##    this list of conditions and the following disclaimers.\n##  - Redistributions in binary form must reproduce the above copyright\n##    notice, this list of conditions and the following disclaimers in\n##    the documentation and#or other materials provided with the distribution.\n##  - Neither the names of Advanced Micro Devices, Inc,\n##    nor the names of its contributors may be used to endorse or promote\n##    products derived from this Software without specific prior written\n##    permission.\n##\n## THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n## THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n## DEALINGS WITH THE SOFTWARE.\n##\n################################################################################\n\ncmake_minimum_required ( VERSION 3.5.0 )\n\n## Set the name and project name.\nset ( PROJECT_STRING rocr-tools-legacy )\nproject ( ${PROJECT_STRING} )\n\n#\n# The parameter \"tool_objs\" specifies the folder where build\n# products accumulate. It is specified relative to current cmake\n# binary directory\n#\nadd_subdirectory(\"${CMAKE_CURRENT_SOURCE_DIR}/../../hsa-runtime-tools\" \"${CMAKE_CURRENT_BINARY_DIR}/tools_objs\")\n\n## Include the cmake_modules utils.cmake\nlist ( APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/../../cmake_modules\" )\ninclude ( utils )\n\n## Get the package version.\nget_version ( \"1.1.9\" )\n\nset( PACKAGE_VERSION_STRING \"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_COMMIT_COUNT}-${VERSION_JOB}-${VERSION_HASH}\" )\n\n## Packaging directives\nset ( CPACK_GENERATOR \"DEB;RPM\" CACHE STRING \"Package types to build\")\n\nset ( CPACK_PACKAGE_NAME ${PROJECT_NAME} )\nset ( CPACK_PACKAGE_VENDOR \"AMD\" )\nset ( CPACK_PACKAGE_VERSION ${PACKAGE_VERSION_STRING} )\nset ( CPACK_PACKAGE_CONTACT \"Advanced Micro Devices Inc.\" )\nset ( CPACK_PACKAGE_DESCRIPTION_SUMMARY \"AMD Heterogeneous System Architecture HSA - Linux HSA Runtime extensions for ROCm platforms\" )\nset ( CPACK_PACKAGE_DESCRIPTION_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/description\" )\nset ( CPACK_RESOURCE_FILE_LICENSE \"${CMAKE_CURRENT_SOURCE_DIR}/copyright\" )\n\n# Debian package specific variables\nset ( CPACK_DEBIAN_PACKAGE_DEPENDS \"hsakmt-roct, hsa-rocr-dev\" )\nset ( CPACK_DEBIAN_PACKAGE_HOMEPAGE \"https://github.com/RadeonOpenCompute/ROCR-Runtime\" )\nset ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA \"${CMAKE_CURRENT_SOURCE_DIR}/postinst;${CMAKE_CURRENT_SOURCE_DIR}/prerm\" )\n\n# RPM package specific variables\nset ( CPACK_RPM_PACKAGE_DEPENDS \"hsakmt-roct, hsa-rocr-dev\" )\nset ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_post\" )\nset ( CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE \"${CMAKE_CURRENT_SOURCE_DIR}/rpm_postun\" )\n\ninclude ( CPack )\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/copyright",
    "content": "The University of Illinois/NCSA\nOpen Source License (NCSA)\n\nCopyright (c) 2014-2016, Advanced Micro Devices, Inc. All rights reserved.\n\nDeveloped by:\n\n                AMD Research and AMD HSA Software Development\n\n                Advanced Micro Devices, Inc.\n\n                www.amd.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal with the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\n - Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimers.\n - Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimers in\n   the documentation and/or other materials provided with the distribution.\n - Neither the names of Advanced Micro Devices, Inc,\n   nor the names of its contributors may be used to endorse or promote\n   products derived from this Software without specific prior written\n   permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS WITH THE SOFTWARE.\n\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/description",
    "content": "This package includes legacy version of ROCr Tools library. The use\nof this library is deprecatd and no longer supported.\n\nThis library provides following services:\n\n  - Kernel dispatches via PM4 path\n  - Collection of Performance Counters\n    - The last ROCm release that supported CodeXL was 2.6\n    - Submission of Pm4 commands via AQL packets enables this functionality\n  - Support various Debugger related activities\n    - The last ROCm release that supported Debugger was 2.6\n\nServices other than kernel dispatches are AMD private i.e. are\nnot defined by any specification.\n\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/postinst",
    "content": "#/bin/bash\n\nset -e\n\ndo_ldconfig() {\n    echo /opt/rocm/hsa/lib > /etc/ld.so.conf.d/rocr_tools_legacy.conf && ldconfig\n}\n\ncase \"$1\" in\n   configure)\n       do_ldconfig\n   ;;\n   abort-upgrade|abort-remove|abort-deconfigure)\n       echo \"$1\"\n   ;;\n   *)\n       exit 0\n   ;;\nesac\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/prerm",
    "content": "#!/bin/bash\n\nset -e\n\nrm_ldconfig() {\n    rm -f /etc/ld.so.conf.d/rocr_tools_legacy.conf && ldconfig\n}\n\ncase \"$1\" in\n   remove)\n       rm_ldconfig\n   ;;\n   purge)\n   ;;\n   *)\n       exit 0\n   ;;\nesac\n\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/rpm_post",
    "content": "echo /opt/rocm/hsa/lib > /etc/ld.so.conf.d/rocr_tools_legacy.conf && ldconfig\n"
  },
  {
    "path": "runtime/packages/rocr_tools_legacy/rpm_postun",
    "content": "if [ $1 -eq 0]; then\n    rm -f /etc/ld.so.conf.d/rocr_tools_legacy.conf && ldconfig\nfi\n"
  },
  {
    "path": "samples/GetInfo/get_info.cpp",
    "content": "#include \"get_info.h\"\n\n#include <iostream>\n\nGetInfo::GetInfo() : HsaTest(\"HSA Info\") {}\n\nGetInfo::~GetInfo() {}\n\nvoid GetInfo::Run() {\n  std::cout << std::endl;\n  std::cout << \"Num CPUs in platform: \" << cpus_.size() << std::endl;\n  std::cout << \"------------------------------------------------\\n\";\n\n  for (size_t i = 0; i < cpus_.size(); ++i) {\n    hsa_agent_t cpu = cpus_[i];\n    std::cout << \"CPU[\" << i << \"] properties:\" << std::endl;\n    std::cout << \"------------------------------------------------\\n\";\n    AgentProps prop(cpu);\n    PrintAgentInfo(prop);\n    PrintPeers(cpu);\n    std::cout << \"------------------------------------------------\\n\";\n\n    hsa_amd_memory_pool_t global_fine = global_fine_[cpu.handle];\n    if (global_fine.handle != 0) {\n      std::cout << \"CPU[\" << i << \"] system fine grain pool properties:\\n\";\n      std::cout << \"------------------------------------------------\\n\";\n      PoolProps prop(global_fine);\n      PrintPoolInfo(prop);\n      std::cout << \"------------------------------------------------\\n\";\n    }\n\n    hsa_amd_memory_pool_t global_coarse = global_coarse_[cpu.handle];\n    if (global_coarse.handle != 0) {\n      std::cout << \"CPU[\" << i << \"] system coarse grain pool properties:\\n\";\n      std::cout << \"------------------------------------------------\\n\";\n      PoolProps prop(global_coarse);\n      PrintPoolInfo(prop);\n      std::cout << \"------------------------------------------------\\n\";\n    }\n  }\n\n  std::cout << std::endl;\n  std::cout << \"Num GPUs in platform: \" << gpus_.size() << std::endl;\n  std::cout << \"------------------------------------------------\\n\";\n\n  for (size_t i = 0; i < gpus_.size(); ++i) {\n    hsa_agent_t gpu = gpus_[i];\n    std::cout << \"GPU[\" << i << \"] properties:\" << std::endl;\n    std::cout << \"------------------------------------------------\\n\";\n    AgentProps prop(gpu);\n    PrintAgentInfo(prop);\n    PrintPeers(gpu);\n    std::cout << \"------------------------------------------------\\n\";\n\n    hsa_amd_memory_pool_t global_coarse = global_coarse_[gpu.handle];\n    if (global_coarse.handle != 0) {\n      std::cout << \"GPU[\" << i << \"] local memory pool properties:\\n\";\n      std::cout << \"------------------------------------------------\\n\";\n      PoolProps prop(global_coarse);\n      PrintPoolInfo(prop);\n      std::cout << \"------------------------------------------------\\n\";\n    }\n\n    hsa_amd_memory_pool_t group = group_[gpu.handle];\n    if (group.handle != 0) {\n      std::cout << \"GPU[\" << i << \"] group memory pool properties:\\n\";\n      std::cout << \"------------------------------------------------\\n\";\n      PoolProps prop(group);\n      PrintPoolInfo(prop);\n      std::cout << \"------------------------------------------------\\n\";\n    }\n  }\n}\n\nint main(int argc, char* argv[]) {\n  GetInfo get_info;\n\n  get_info.Init();\n  get_info.Run();\n  get_info.Cleanup();\n\n  return 0;\n}"
  },
  {
    "path": "samples/GetInfo/get_info.h",
    "content": "#ifndef GET_INFO_H\n#define GET_INFO_H\n\n#include \"samples/common/hsa_test.h\"\n\nclass GetInfo : public HsaTest {\n public:\n  GetInfo();\n  ~GetInfo();\n\n  void Run() override;\n};\n\n#endif // GET_INFO_H\n"
  },
  {
    "path": "samples/common/common.cpp",
    "content": "#include \"common.hpp\"\n\nvoid ErrorCheck(hsa_status_t hsa_error_code) {\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    std::cerr << \"HSA reported error!\" << std::endl;\n    exit(EXIT_FAILURE);\n  }\n}\n\nhsa_status_t FindGpuDevice(hsa_agent_t agent, void *data) {\n  if (data == NULL) {\n     return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  hsa_device_type_t hsa_device_type;\n  hsa_status_t hsa_error_code = hsa_agent_get_info(\n    agent, HSA_AGENT_INFO_DEVICE, &hsa_device_type\n  );\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (hsa_device_type == HSA_DEVICE_TYPE_GPU) {\n    *((hsa_agent_t*)data) = agent;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t FindHostRegion(hsa_region_t region, void *data) {\n  if (data == NULL) {\n    return HSA_STATUS_ERROR_INVALID_ARGUMENT;\n  }\n\n  bool is_host_region = false;\n  hsa_status_t hsa_error_code = hsa_region_get_info(\n      region, (hsa_region_info_t)HSA_AMD_REGION_INFO_HOST_ACCESSIBLE,\n      &is_host_region);\n  if (hsa_error_code != HSA_STATUS_SUCCESS) {\n    return hsa_error_code;\n  }\n\n  if (is_host_region) {\n    *((hsa_region_t*)data) = region;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "samples/common/common.hpp",
    "content": "#ifndef COMMON_COMMON_HPP\n#define COMMON_COMMON_HPP\n\n#include <cstdlib>\n#include <iostream>\n\n#include \"hsa.h\"\n#include \"hsa_ext_finalize.h\"\n#include \"hsa_ext_amd.h\"\n\n#if defined(_MSC_VER)\n  #define ALIGNED_(x) __declspec(align(x))\n#else\n  #if defined(__GNUC__)\n    #define ALIGNED_(x) __attribute__ ((aligned(x)))\n  #endif // __GNUC__\n#endif // _MSC_VER\n\n#define MULTILINE(...) # __VA_ARGS__\n\nvoid ErrorCheck(hsa_status_t hsa_error_code);\n\nhsa_status_t FindGpuDevice(hsa_agent_t agent, void *data);\n\nhsa_status_t FindHostRegion(hsa_region_t region, void *data);\n\n#endif // COMMON_COMMON_HPP\n"
  },
  {
    "path": "samples/common/common_utility.cpp",
    "content": "#include \"common_utility.h\"\n\n\ndouble CalcMedian(vector<double> scores)\n{\n\tdouble median;\n\tsize_t size = scores.size();\n\n\tif (size  % 2 == 0)\n\t\tmedian = (scores[size / 2 - 1] + scores[size / 2]) / 2;\n\telse \n\t\tmedian = scores[size / 2];\n\n\treturn median;\n}\n\ndouble CalcMean(vector<double> scores)\n{\n\tdouble mean = 0;\n\tsize_t size = scores.size();\n\n       for (int i=0; i<size; ++i)\n\t   \tmean += scores[i];\n\n\treturn mean/size;\n}\n\n\ndouble CalcStdDeviation(vector<double> scores, int score_mean)\n{\n\tdouble ret = 0.0;\n\tfor (int i=0; i<scores.size(); ++i)\n\t{\n\t\tret += (scores[i] - score_mean) * (scores[i] - score_mean);\n\t}\n\n\tret /= scores.size();\n\n\treturn sqrt(ret);\n}\n\nint CalcConcurrentQueues(vector<double> scores)\n{\n    int num_of_concurrent_queues = 0;\n    vector<double>execpted_exec_time_array;\n    \n    for (int i=0; i<scores.size(); ++i)\n    {\n        execpted_exec_time_array.push_back(scores[0]/(1<<i));\n    }\n\n   \n   for (int i=0; i<scores.size(); ++i)\n   {\n\t   cout << \"expected exe time = \" << execpted_exec_time_array[i] << endl;\n   }\n\n    for (int i=1; i<scores.size(); ++i)\n    {\n        if ((execpted_exec_time_array[i] - scores[i]) < 0.1 * execpted_exec_time_array[i])\n            ++num_of_concurrent_queues;\n    }\n\n    return num_of_concurrent_queues;\n}\n\n\n"
  },
  {
    "path": "samples/common/common_utility.h",
    "content": "#include <iostream>\n#include <algorithm>\n#include <cmath>\n#include <vector>\nusing namespace std;\n\ndouble CalcMean(vector<double> scores);\ndouble CalcMedian(vector<double> scores);\ndouble CalcStdDeviation(vector<double> scores, int score_mean);\nint CalcConcurrentQueues(vector<double> scores);\n\n\n\n"
  },
  {
    "path": "samples/common/helper_funcs.cpp",
    "content": "/**********************************************************************\nCopyright 2013 Advanced Micro Devices, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n\tRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\tRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or\n other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY\n DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n********************************************************************/\n\n#include \"helper_funcs.hpp\"\n\n#ifndef _WIN32\n#include <unistd.h>\n#endif\n\n\n/*\n * Prints no more than 256 elements of the given array.\n * Prints full array if length is less than 256.\n * Prints Array name followed by elements.\n */\ntemplate<typename T> \nvoid printArray(\n    const std::string header, \n    const T * data, \n    const int width,\n    const int height)\n{\n    std::cout<<\"\\n\"<<header<<\"\\n\";\n    for(int i = 0; i < height; i++)\n    {\n        for(int j = 0; j < width; j++)\n        {\n            std::cout<<data[i*width+j]<<\" \";\n        }\n        std::cout<<\"\\n\";\n    }\n    std::cout<<\"\\n\";\n}\n\ntemplate<typename T> \nint fillRandom(\n         T * arrayPtr, \n         const int width,\n         const int height,\n         const T rangeMin,\n         const T rangeMax,\n         unsigned int seed)\n{\n    if(!arrayPtr)\n    {\n        error(\"Cannot fill array. NULL pointer.\");\n        return HSA_SDK_FAILURE;\n    }\n\n    if(!seed)\n        seed = (unsigned int)time(NULL);\n\n    srand(seed);\n    double range = double(rangeMax - rangeMin) + 1.0; \n\n    /* random initialisation of input */\n    for(int i = 0; i < height; i++)\n        for(int j = 0; j < width; j++)\n        {\n            int index = i*width + j;\n            arrayPtr[index] = rangeMin + T(range*rand()/(RAND_MAX + 1.0)); \n        }\n\n    return HSA_SDK_SUCCESS;\n}\n\ntemplate<typename T> \nint fillPos(\n         T * arrayPtr, \n         const int width,\n         const int height)\n{\n    if(!arrayPtr)\n    {\n        error(\"Cannot fill array. NULL pointer.\");\n        return HSA_SDK_FAILURE;\n    }\n\n    /* initialisation of input with positions*/\n    for(T i = 0; i < height; i++)\n        for(T j = 0; j < width; j++)\n        {\n            T index = i*width + j;\n            arrayPtr[index] = index;\n        }\n\n    return HSA_SDK_SUCCESS;\n}\n\ntemplate<typename T> \nint fillConstant(\n         T * arrayPtr, \n         const int width,\n         const int height,\n         const T val)\n{\n    if(!arrayPtr)\n    {\n        error(\"Cannot fill array. NULL pointer.\");\n        return HSA_SDK_FAILURE;\n    }\n\n    /* initialisation of input with constant value*/\n    for(int i = 0; i < height; i++)\n        for(int j = 0; j < width; j++)\n        {\n            int index = i*width + j;\n            arrayPtr[index] = val;\n        }\n\n    return HSA_SDK_SUCCESS;\n}\n\ntemplate<typename T>\nT roundToPowerOf2(T val)\n{\n    int bytes = sizeof(T);\n\n    val--;\n    for(int i = 0; i < bytes; i++)\n        val |= val >> (1<<i);  \n    val++;\n\n    return val;\n}\n\ntemplate<typename T>\nint isPowerOf2(T val)\n{\n    long long _val = val;\n    if((_val & (-_val))-_val == 0 && _val != 0)\n        return HSA_SDK_SUCCESS;\n    else\n        return HSA_SDK_FAILURE;\n}\n\n\n\ntemplate<typename T>\nbool checkVal(\n    T input, \n    T reference, \n    std::string message,\n    bool isAPIerror)\n{\n    if(input==reference)\n    {\n        return true;\n    }\n    else\n    {\n        error(message);   \n        return false;\n    }\n}\n\n\ntemplate<typename T>\nstd::string toString(T t, std::ios_base &(*r)(std::ios_base&))\n{\n  std::ostringstream output;\n  output << r << t;\n  return output.str();\n}\n\n\nbool\ncompare(const float *refData, const float *data, \n                        const int length, const float epsilon)\n{\n    float error = 0.0f;\n    float ref = 0.0f;\n\n    for(int i = 1; i < length; ++i) \n    {\n        float diff = refData[i] - data[i];\n        error += diff * diff;\n        ref += refData[i] * refData[i];\n    }\n\n    float normRef =::sqrtf((float) ref);\n    if (::fabs((float) ref) < 1e-7f) {\n        return false;\n    }\n    float normError = ::sqrtf((float) error);\n    error = normError / normRef;\n\n    return error < epsilon;\n}\n\nbool\ncompare(const double *refData, const double *data, \n                        const int length, const double epsilon)\n{\n    double error = 0.0;\n    double ref = 0.0;\n\n    for(int i = 1; i < length; ++i) \n    {\n        double diff = refData[i] - data[i];\n        error += diff * diff;\n        ref += refData[i] * refData[i];\n    }\n\n    double normRef =::sqrt((double) ref);\n    if (::fabs((double) ref) < 1e-7) {\n        return false;\n    }\n    double normError = ::sqrt((double) error);\n    error = normError / normRef;\n\n    return error < epsilon;\n}\n\nvoid \nerror(const char* errorMsg)\n{\n    std::cout<<\"Error: \"<<errorMsg<<std::endl;\n}\n\nvoid \nerror(std::string errorMsg)\n{\n    std::cout<<\"Error: \"<<errorMsg<<std::endl;\n}\n\nvoid \nexpectedError(const char* errorMsg)\n{\n    std::cout<<\"Expected Error: \"<<errorMsg<<std::endl;\n}\n\nvoid \nexpectedError(std::string errorMsg)\n{\n    std::cout<<\"Expected Error: \"<<errorMsg<<std::endl;\n}\n\n\n/////////////////////////////////////////////////////////////////\n// Template Instantiations \n/////////////////////////////////////////////////////////////////\ntemplate \nvoid printArray<short>(const std::string, \n        const short*, int, int);\ntemplate \nvoid printArray<unsigned char>(const std::string, \n        const unsigned char *, int, int);\ntemplate \nvoid printArray<unsigned int>(const std::string, \n        const unsigned int *, int, int);\ntemplate \nvoid printArray<int>(const std::string, \n        const int *, int, int);\ntemplate \nvoid printArray<long>(const std::string, \n        const long*, int, int);\ntemplate \nvoid printArray<float>(const std::string, \n        const float*, int, int);\ntemplate \nvoid printArray<double>(const std::string, \n        const double*, int, int);\n\ntemplate \nint fillRandom<unsigned char>(unsigned char* arrayPtr, \n        const int width, const int height, \n        unsigned char rangeMin, unsigned char rangeMax, unsigned int seed);\t\ntemplate \nint fillRandom<unsigned int>(unsigned int* arrayPtr, \n        const int width, const int height, \n        unsigned int rangeMin, unsigned int rangeMax, unsigned int seed);\t\ntemplate \nint fillRandom<int>(int* arrayPtr, \n        const int width, const int height, \n        int rangeMin, int rangeMax, unsigned int seed);\t\ntemplate \nint fillRandom<long>(long* arrayPtr, \n        const int width, const int height, \n        long rangeMin, long rangeMax, unsigned int seed);\t\ntemplate \nint fillRandom<float>(float* arrayPtr, \n        const int width, const int height, \n        float rangeMin, float rangeMax, unsigned int seed);\t\ntemplate \nint fillRandom<double>(double* arrayPtr, \n        const int width, const int height, \n        double rangeMin, double rangeMax, unsigned int seed);\t\n\ntemplate \nshort roundToPowerOf2<short>(short val);\ntemplate \nunsigned int roundToPowerOf2<unsigned int>(unsigned int val);\ntemplate \nint roundToPowerOf2<int>(int val);\ntemplate \nlong roundToPowerOf2<long>(long val);\n\ntemplate\nint isPowerOf2<short>(short val);\ntemplate\nint isPowerOf2<unsigned int>(unsigned int val);\ntemplate\nint isPowerOf2<int>(int val);\ntemplate\nint isPowerOf2<long>(long val);\n\ntemplate<> \nint fillPos<short>(short * arrayPtr, const int width, const int height);\ntemplate<> \nint fillPos<unsigned int>(unsigned int * arrayPtr, const int width, const int height);\ntemplate<> \nint fillPos<int>(int * arrayPtr, const int width, const int height);\ntemplate<> \nint fillPos<long>(long * arrayPtr, const int width, const int height);\n\ntemplate<> \nint fillConstant<short>(short * arrayPtr, \n        const int width, const int height, \n        const short val);\ntemplate<> \nint fillConstant(unsigned int * arrayPtr, \n        const int width, const int height, \n        const unsigned int val);\ntemplate<> \nint fillConstant(int * arrayPtr, \n        const int width, const int height, \n        const int val);\ntemplate<> \nint fillConstant(long * arrayPtr, \n        const int width, const int height, \n        const long val);\ntemplate<> \nint fillConstant(long * arrayPtr, \n        const int width, const int height, \n        const long val);\ntemplate<> \nint fillConstant(long * arrayPtr, \n        const int width, const int height, \n        const long val);\n\n\ntemplate\nbool checkVal<char>(char input, char reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<bool>(bool input, bool reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<std::string>(std::string input, std::string reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<short>(short input, short reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<unsigned int>(unsigned int  input, unsigned int  reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<int>(int input, int reference, std::string message, bool isAPIerror);\ntemplate\nbool checkVal<long>(long input, long reference, std::string message, bool isAPIerror);\n\n\ntemplate\nstd::string toString<char>(char t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<short>(short t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<unsigned int>(unsigned int t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<int>(int t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<long>(long t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<float>(float t, std::ios_base &(*r)(std::ios_base&));\ntemplate\nstd::string toString<double>(double t, std::ios_base &(*r)(std::ios_base&));\n\n"
  },
  {
    "path": "samples/common/helper_funcs.hpp",
    "content": "/**********************************************************************\nCopyright 2013 Advanced Micro Devices, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n\tRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\tRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or\n other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY\n DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n********************************************************************/\n#ifndef HELPER_FUNCS_HPP_\n#define HELPER_FUNCS_HPP_\n\n#define HSA_SDK_SUCCESS 0\n#define HSA_SDK_FAILURE 1\n#define HSA_SDK_EXPECTED_FAILURE 2\n\n#include <iostream>\n#include <fstream>\n#include <iomanip>\n#include <sstream>\n#include <string>\n#include <ctime>\n#include <cmath>\n#include <time.h>\n#include <stdlib.h>\n#include <string.h>\n#include <vector>\n#include <malloc.h>\n\n/**\n * error\n * constant function, Prints error messages \n * @param errorMsg char* message\n */\nvoid error(const char* errorMsg);\t\n\n/**\n * error\n * constant function, Prints error messages \n * @param errorMsg std::string message\n */\nvoid error(std::string errorMsg);\n\n/**\n * expectedError\n * constant function, Prints error messages \n * @param errorMsg char* message\n */\nvoid expectedError(const char* errorMsg);\t\n\n/**\n * expectedError\n * constant function, Prints error messages \n * @param errorMsg string message\n */\nvoid expectedError(std::string errorMsg);\n\n/**\n * compare template version\n * compare data to check error\n * @param refData templated input\n * @param data templated input\n * @param length number of values to compare\n * @param epsilon errorWindow\n */\nbool compare(const float *refData, const float *data, \n        const int length, const float epsilon = 1e-6f); \nbool compare(const double *refData, const double *data, \n        const int length, const double epsilon = 1e-6); \n\n/**\n * printArray\n * displays a array on std::out\n */\ntemplate<typename T> \nvoid printArray(\n     const std::string header,\n     const T * data, \n     const int width,\n     const int height);\n\n\n/**\n * fillRandom\n * fill array with random values\n */\ntemplate<typename T> \nint fillRandom(\n     T * arrayPtr, \n     const int width,\n     const int height,\n     const T rangeMin,\n     const T rangeMax,\n     unsigned int seed=123);\t\n  \n/**\n * fillPos\n * fill the specified positions\n */\ntemplate<typename T> \nint fillPos(\n     T * arrayPtr, \n     const int width,\n     const int height);\n  \n/**\n * fillConstant\n * fill the array with constant value\n */\ntemplate<typename T> \nint fillConstant(\n     T * arrayPtr, \n     const int width,\n     const int height,\n     const T val);\n\n  \n/**\n * roundToPowerOf2\n * rounds to a power of 2\n */\ntemplate<typename T>\nT roundToPowerOf2(T val);\n\n/**\n * isPowerOf2\n * checks if input is a power of 2\n */\ntemplate<typename T>\nint isPowerOf2(T val);\n  \n/**\n * checkVal\n * Set default(isAPIerror) parameter to false \n * if checkVaul is used to check otherthan OpenCL API error code \n */\ntemplate<typename T> \nbool checkVal(\n  T input, \n  T reference, \n  std::string message, bool isAPIerror = true);\n\n/**\n * toString\n * convert a T type to string\n */\ntemplate<typename T>\nstd::string toString(T t, std::ios_base & (*r)(std::ios_base&)); \n\n\n\n\n#endif\n"
  },
  {
    "path": "samples/common/hsa_base_util.cpp",
    "content": "#include \"hsa_base_util.h\"\n#include \"HSAILAmdExt.h\"\n\n\nvoid HSA_UTIL::GetHsailNameAndKernelName(char * file_name_full, char *file_name_base, char *kernel_name)\n{\n\tstrcpy(hail_file_name_full, file_name_full);\n\tstrcpy(hail_file_name_base, file_name_base);\n\tstrcpy(hsa_kernel_name, kernel_name);\n}\n\nHSA_UTIL::HSA_UTIL()\n{\n#ifdef TIME\n    \tbase_kernel_time_idx = base_timer.CreateTimer();\n\tbase_setup_time_idx = base_timer.CreateTimer();\n#endif\n}\n\nHSA_UTIL::~HSA_UTIL()\n{\n\n}\n\n\nbool HSA_UTIL::HsaInit()\n{\n#ifdef TIME\n       base_timer.StartTimer(base_setup_time_idx);\n#endif\n\n \terr = hsa_init();\n \tcheck(Initializing the hsa runtime, err);\n\n\t/* \n\t * Iterate over the agents and pick the gpu agent using \n\t * the find_gpu callback.\n\t */\n\terr = hsa_iterate_agents(find_gpu, &device);\n\tcheck(Calling hsa_iterate_agents, err);\n\n\terr = (device.handle== 0) ? HSA_STATUS_ERROR : HSA_STATUS_SUCCESS;\n\tcheck(Checking if the GPU device is non-zero, err);\n\n\tif (err == HSA_STATUS_ERROR)\n\t\treturn false;\n\n\t/*\n\t * Query the maximum size of the queue.\n\t */\n\terr = hsa_agent_get_info(device, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &queue_size);\n\tcheck(Querying the device maximum queue size, err);\n\n\t/*  \n\t * Create a queue using the maximum size.\n\t */\n\terr = hsa_queue_create(device, queue_size, HSA_QUEUE_TYPE_MULTI, NULL, NULL, 0, 0, &command_queue);\n\tcheck(Creating the queue, err);\n\n\tprofile = hsa_profile_t(108);\n       hsa_agent_get_info(device, HSA_AGENT_INFO_PROFILE, &profile);\n\n       if (profile == HSA_PROFILE_BASE) \n\t{\n\t    memset(hail_file_name_full, 0, sizeof(char)*128);\n           cout << \"Loading base profile!!!\" << endl;\n           strcpy(hail_file_name_full, hail_file_name_base); //overwrite full hsail file name with base \n       } \n   \n        amd::hsail::registerExtensions();\n        if (!tool.assembleFromFile(hail_file_name_full)) \n\t{\n          std::cout << tool.output();\n          return false;\n        }\n        module = tool.brigModule();\n\n\t// Create hsail program.\n\terr = hsa_ext_program_create(HSA_MACHINE_MODEL_LARGE, profile, HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO, NULL, &hsa_program);\n\tcheck(\"Error in creating program object\", err);\n\n\t// Add hsail module.\n\t//cout << \"hsail file name = \" << hail_file_name_full << endl;\n\terr = hsa_ext_program_add_module(hsa_program, module);\n\tcheck(\"Error in adding module to program object\", err);\n\n\t// Finalize hsail program.\n        hsa_isa_t isa = {0};\n        err = hsa_agent_get_info(device, HSA_AGENT_INFO_ISA, &isa);\n        check(\"Get hsa agent info isa\", err);\n\n\thsa_ext_control_directives_t control_directives;\n\tmemset(&control_directives, 0, sizeof(hsa_ext_control_directives_t));\n\n\terr = hsa_ext_program_finalize(hsa_program,\n\t\t\tisa,\n\t\t\t0,\n\t\t\tcontrol_directives,\n\t\t\tNULL, //\"-g -O0 -dump-isa\",\n\t\t\tHSA_CODE_OBJECT_TYPE_PROGRAM,\n\t\t\t&code_object);\n\tcheck(\"Error in finalizing program object\", err);\n\n\t// Create executable.\n\terr = hsa_executable_create(profile, HSA_EXECUTABLE_STATE_UNFROZEN, \"\", &hsaExecutable);\n\tcheck(\"Error in creating executable object\", err);\n\n\t// Load code object.\n\terr = hsa_executable_load_code_object(hsaExecutable, device, code_object, \"\");\n\tcheck(\"Error in loading executable object\", err);\n\n\t// Freeze executable.\n\terr = hsa_executable_freeze(hsaExecutable, \"\");\n\tcheck(\"Error in freezing executable object\", err);\n\n\t// Get symbol handle.\n\terr = hsa_executable_get_symbol(hsaExecutable, NULL,  hsa_kernel_name, device, 0, &kernelSymbol);\n\tcheck(\"get symbol handle\", err);\n\n\t// Get code handle.\n\t\n\terr = hsa_executable_symbol_get_info(kernelSymbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &codeHandle);\n\tcheck(\"Get code handle\", err);\n\n#ifdef TIME\n\tbase_timer.StopTimer(base_setup_time_idx);\n#endif\n\n\n\t//hsa_region_t local_kernarg_region;\n\tmem_region.kernarg_region.handle = 0;\n\tmem_region.coarse_region.handle = 0;\n\n\thsa_agent_iterate_regions(device, get_memory_region, &mem_region);\n\terr = (mem_region.kernarg_region.handle== 0) ? HSA_STATUS_ERROR : HSA_STATUS_SUCCESS;\n\tcheck(Finding a kernarg memory region, err);\n\n\treturn true;\n}\n\ndouble HSA_UTIL::Run(int dim, int group_x, int group_y, int group_z, int s_size, int grid_x, int grid_y, int grid_z, void* kernel_args, int kernel_args_size)\n{\n#ifdef TIME\n\t\tbase_timer.StartTimer(base_kernel_time_idx);\n#endif\n\n\t/*\n\t * Create a signal to wait for the dispatch to finish.\n\t */\n\thsa_signal_t local_signal;\n\terr=hsa_signal_create(1, 0, NULL, &local_signal);\n\tcheck(Creating a HSA_UTIL signal, err);\n\n\t/* Initialize the dispatch packet */\n\thsa_kernel_dispatch_packet_t local_dispatch_packet;\n\tmemset(&local_dispatch_packet, 0, sizeof(hsa_kernel_dispatch_packet_t));\n\t/*\n\t * Setup the dispatch information.\n\t */\n\tlocal_dispatch_packet.completion_signal=local_signal;\n\tlocal_dispatch_packet.setup |=  dim<< HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS;\n\tlocal_dispatch_packet.workgroup_size_x = group_x;\n\tlocal_dispatch_packet.workgroup_size_y = group_y;\n\tlocal_dispatch_packet.workgroup_size_z = group_z;\n\tlocal_dispatch_packet.group_segment_size = s_size;\n\tlocal_dispatch_packet.grid_size_x = grid_x;\n\tlocal_dispatch_packet.grid_size_y = grid_y;\n\tlocal_dispatch_packet.grid_size_z = grid_z;\n\tlocal_dispatch_packet.header |= HSA_PACKET_TYPE_KERNEL_DISPATCH;\n\t//local_dispatch_packet.header |= HSA_FENCE_SCOPE_AGENT << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n\t//local_dispatch_packet.header |= HSA_FENCE_SCOPE_AGENT << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\tlocal_dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;\n\tlocal_dispatch_packet.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;\n\tlocal_dispatch_packet.kernel_object = codeHandle;\n\n  // Specify amount of private segment size (in bytes) that is needed per work-item\n  // Retrieve the amount of private memory needed\n  uint32_t private_mem_size = 0;\n  hsa_executable_symbol_get_info(kernelSymbol,\n                        HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE, &private_mem_size);\n  local_dispatch_packet.private_segment_size = private_mem_size;\n\n\t///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n\t/*\n\t * Find a memory region that supports kernel arguments.\n\t */\n\n\n/*\n\tkernarg_region.handle = 0;\n\n\thsa_agent_iterate_regions(device, get_kernarg, &kernarg_region);\n\terr = (kernarg_region.handle== 0) ? HSA_STATUS_ERROR : HSA_STATUS_SUCCESS;\n\tcheck(Finding a kernarg memory region, err);\n\t\n*/\n\n        void* local_kernel_arg_buffer = NULL;\n\t/*\n\t * Allocate the kernel argument buffer from the correct region.\n\t */\n\terr = hsa_memory_allocate(mem_region.kernarg_region, kernel_args_size, &local_kernel_arg_buffer);\n\tcheck(Allocating kernel argument memory buffer, err);\n\tmemcpy(local_kernel_arg_buffer, kernel_args, kernel_args_size);\n\tlocal_dispatch_packet.kernarg_address = local_kernel_arg_buffer;\n\n\t/*\t\n\t * Obtain the current queue write index.\n\t */\n\tuint64_t index = hsa_queue_load_write_index_relaxed(command_queue);\n\n\t/*\t\n\t * Write the aql packet at the calculated queue index address.\n\t */\n\tconst uint32_t queueMask = command_queue->size - 1;\n\t((hsa_kernel_dispatch_packet_t*)(command_queue->base_address))[index&queueMask]=local_dispatch_packet;\n\n\t/*\t\n\t * Increment the write index and ring the doorbell to dispatch the kernel.\n\t */\n\thsa_queue_store_write_index_relaxed(command_queue, index+1);\n\thsa_signal_store_release(command_queue->doorbell_signal, index);\n\n\t/*\t\n\t * Wait on the dispatch signal until all kernel are finished.\n\t */\n\twhile (hsa_signal_wait_acquire(local_signal, HSA_SIGNAL_CONDITION_EQ, 0, UINT64_MAX, HSA_WAIT_STATE_ACTIVE)  != 0);\n\n#ifdef TIME\n\tbase_timer.StopTimer(base_kernel_time_idx);\n#endif\n\n\t/*\n\t * Cleanup all allocated resources.\n\t */\n\n        err = hsa_memory_free(local_kernel_arg_buffer);\n        check(Deallocate memory, err);\n\n\terr=hsa_signal_destroy(local_signal);\n\tcheck(Destroying the local_signal, err);\n\n\treturn 0;\n}\n\ndouble HSA_UTIL::GetKernelTime()\n{\n    return base_timer.ReadTimer(base_kernel_time_idx);\n}\n\ndouble HSA_UTIL::GetSetupTime()\n{\n    return base_timer.ReadTimer(base_setup_time_idx);\n}\n\nvoid HSA_UTIL::Close()\n{\n\terr = hsa_executable_destroy(hsaExecutable); \n\tcheck(Destroying the hsaExecutable, err)\n\n\terr = hsa_code_object_destroy(code_object);\n\tcheck(Destroying the code_object, err);\n\n\terr=hsa_queue_destroy(command_queue);\n\tcheck(Destroying the queue, err);\n\n\terr=hsa_shut_down();\n\tcheck(Shutting down the runtime, err);\n}\n\nvoid* HSA_UTIL::AllocateLocalMemory(size_t size) \n{\n  void *buffer = NULL;\n\n  // Allocate in local memory only if it is available\n  if (mem_region.coarse_region.handle != 0) \n  {\n      cout << \"Allocating in local memory\" << endl;\n      err = hsa_memory_allocate(mem_region.coarse_region, size, (void **)&buffer);\n      check(hsa memory allocation in local memory, err);\n\n      // register agent\n      err = hsa_memory_assign_agent(buffer, device, HSA_ACCESS_PERMISSION_RW);\n      return (err == HSA_STATUS_SUCCESS) ? buffer : NULL;\n  }\n\n  // Allocate in system memory if local memory is not available\n  cout << \"Allocating in system memory\" << endl;\n  err = hsa_memory_allocate(mem_region.kernarg_region, size, (void **)&buffer);\n  return (err == HSA_STATUS_SUCCESS) ? buffer : NULL;\n}\n\nvoid* HSA_UTIL::AllocateSysMemory( size_t size)\n{\n    void *buffer = NULL;\n    err = hsa_memory_allocate(mem_region.kernarg_region, size, (void **)&buffer);\n    return (err == HSA_STATUS_SUCCESS) ? buffer : NULL;\n}\n\nbool HSA_UTIL::TransferData(void *dest, void *src, uint length, bool host_to_dev) \n{\n\n  hsa_status_t status;\n\n  void *buffer = (host_to_dev) ? dest : src;\n  err = hsa_memory_assign_agent(buffer, device, HSA_ACCESS_PERMISSION_RW);\n  if (err != HSA_STATUS_SUCCESS) \n  {\n      return false;\n  }\n  err = hsa_memory_copy(dest, src, length);  // first is dest, second is src \n  return (err == HSA_STATUS_SUCCESS);\n\n}\n\n\n\n"
  },
  {
    "path": "samples/common/hsa_base_util.h",
    "content": "#ifndef __HSA_BASE__\n#define __HSA_BASE__\n\n\n#include <vector>\n#include \"hsa.h\"\n#include \"hsa_ext_finalize.h\"\n#include \"hsa_ext_amd.h\"\n#include \"hsatimer.h\"\n#include \"utilities.h\"\n#include \"common.hpp\"\n#include \"HSAILTool.h\"\n\nclass HSA_UTIL{\n    public:\n\t    HSA_UTIL();\n\t    ~HSA_UTIL();\n\n\tpublic:\n\t    void GetHsailNameAndKernelName(char *hail_file_name_full, char *hail_file_name_base, char *kernel_name);\n\t    bool HsaInit();\n        void Close();\n\tdouble GetKernelTime();\n\tdouble GetSetupTime();\n\tvoid* AllocateLocalMemory(size_t size) ;\n\tvoid* AllocateSysMemory(size_t size);\n\tbool TransferData(void *dest, void *src, uint length, bool host_to_dev) ;\n\t\n\tdouble Run(int dim, int group_x, int group_y, int group_z, int s_size, int grid_x, int grid_y, int grid_z, void* kernel_args, int kernel_args_size);\n\n\tpublic:\n\t\thsa_status_t err;\n\t\tuint32_t queue_size;\n\t\thsa_agent_t device;\n\t\tMemRegion mem_region;\n              //hsa_region_t kernarg_region;\n\t\t// Memory region supporting kernel parameters\n             // hsa_region_t coarse_region;\n\t\t// Hsail profile supported by agent\n              hsa_profile_t profile;\n\n\t\tchar hail_file_name_full[128];\n\t\tchar hail_file_name_base[128];\n\t\tchar hsa_kernel_name[128];\n\n\t\thsa_queue_t* command_queue;\n\t\tHSAIL_ASM::Tool tool;\n\t\thsa_ext_module_t module;\n\t\thsa_ext_program_t hsa_program;\n\t\thsa_executable_t hsaExecutable;\n\t  hsa_executable_symbol_t kernelSymbol;\n\t\thsa_code_object_t code_object;\n\t\tuint64_t codeHandle;\n\t\thsa_signal_t hsa_signal;\n\t\thsa_kernel_dispatch_packet_t dispatch_packet; \t\n\t\thsa_region_t hsa_kernarg_region;\n\n\t\tPerfTimer base_timer;\n\t\tint base_kernel_time_idx;\n\t\tint base_setup_time_idx;\n};\n\n\n#endif\n\n"
  },
  {
    "path": "samples/common/hsa_perf_cntrs.cpp",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <cassert>\n\n#include <iostream>\n#include <vector>\n#include <string>\n\n#include <stdlib.h>\n\n#include \"hsa.h\"\n#include \"tools/inc/hsa_ext_profiler.h\"\n#include \"tools/inc/amd_hsa_tools_interfaces.h\"\n\n#include \"hsa_perf_cntrs.hpp\"\n\nusing namespace std;\n\nvoid PreDispatchCallback(const hsa_dispatch_callback_t* dispParam, void* usrArg) {\n  assert((dispParam->pre_dispatch) && \"Pre Dispatch Callback Param is Malformed\");\n\n  hsa_ext_tools_pmu_t* perfMgr = reinterpret_cast<hsa_ext_tools_pmu_t*>(usrArg);\n  hsa_status_t status = hsa_ext_tools_pmu_begin(*perfMgr, dispParam->queue,\n                                                dispParam->aql_translation_handle, true);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in beginning Perf Cntr Session\");\n}\n\nvoid PostDispatchCallback(const hsa_dispatch_callback_t* dispParam, void* usrArg) {\n  assert((!dispParam->pre_dispatch) && \"Post Dispatch Callback Param is Malformed\");\n\n  hsa_ext_tools_pmu_t* perfMgr = reinterpret_cast<hsa_ext_tools_pmu_t*>(usrArg);\n  hsa_status_t status = hsa_ext_tools_pmu_end(*perfMgr, dispParam->queue,\n                                              dispParam->aql_translation_handle);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in endning Perf Cntr Session\");\n}\n\n// Constructor of the class\nRocrPerfCntrApp::RocrPerfCntrApp( ) : perfMgr_(NULL) {\n\n}\n\n// Destructor of the class. Ideally it should delete the\n// PMU and its counters\nRocrPerfCntrApp::~RocrPerfCntrApp( ) {\n\n}\n\n// Return the number of perf counters\nuint32_t RocrPerfCntrApp::GetNumPerfCntrs( ) {\n  return uint32_t(cntrList_.size());\n}\n\n// Return the handle of perf counter at specified index\nCntrInfo* RocrPerfCntrApp::GetPerfCntr(uint32_t idx) {\n  return cntrList_[idx];\n}\n\n// Print the various fields of Perf Cntrs being programmed\nbool RocrPerfCntrApp::PrintCntrs( ) {\n\n  CntrInfo *info;\n  int size = uint32_t(cntrList_.size());\n  for (int idx = 0; idx < size; idx++) {\n    info = cntrList_[idx];\n    std::cout << std::endl;\n    std::cout << \"Rocr Perf Cntr Id: \" << info->cntrId << std::endl;\n    std::cout << \"Rocr Perf Cntr Name: \" << info->cntrName << std::endl;\n    std::cout << \"Rocr Perf Cntr Blk Id: \" << info->blkId << std::endl;\n    std::cout << \"Rocr Perf Cntr Value: \" << info->cntrResult << std::endl;\n    std::cout << \"Rocr Perf Cntr Validation: \" << info->cnfType << std::endl;\n    std::cout << std::endl;\n  }\n  return true;\n}\n\n// Initialize the list of perf counters\n// block id of kHsaAiCounterBlockSQ = 14 == 0x0E\nhsa_status_t RocrPerfCntrApp::Init(hsa_agent_t agent) {\n\n  // Initialize the list of Perf Cntrs\n  // Add SQ counter for number of waves\n  CntrInfo* info = NULL;\n  cntrList_.reserve(23);\n  \n  char *cntrChoice = getenv(\"IOMMU\");\n  if (cntrChoice == NULL) {\n    // Event for number of Waves\n    info = new CntrInfo(0x4, \"SQ_SQ_PERF_SEL_WAVES\", NULL,\n                                  0x0E, NULL, 0x00, 0xFFFFFFFF, CntrValCnf_Exact);\n    cntrList_.push_back(info);\n    \n    // Event for number of Threads\n    info = new CntrInfo(0xE, \"SQ_SQ_PERF_SEL_ITEMS\", NULL,\n                                  0x0E, NULL, 0x00, 0xFFFFFFFF, CntrValCnf_Exact);\n    cntrList_.push_back(info);\n  \n  } else {\n\n    // Program to collect event number 4\n    info = new CntrInfo(0x4, \"Iommu_Cntr_4\", NULL,\n                        0x63, NULL, 0x00, 0xFFFFFFFF, CntrValCnf_None);\n    cntrList_.push_back(info);\n  \n    // Program to collect event number 6\n    info = new CntrInfo(0x6, \"Iommu_Cntr_6\", NULL,\n                        0x63, NULL, 0x00, 0xFFFFFFFF, CntrValCnf_None);\n    cntrList_.push_back(info);\n  }\n  \n\n  // Create an instance of Perf Mgr\n  hsa_status_t status;\n  status = hsa_ext_tools_create_pmu(agent, &perfMgr_);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in creating Perf Cntr Mgr\");\n\n  // Process each counter from the list as necessary\n  // each counter descriptor with its perf block handle\n  // and create an instance of counter in that block\n  uint32_t size = GetNumPerfCntrs();\n  for (uint32_t idx = 0; idx < size; idx++) {\n    info = GetPerfCntr(idx);\n    \n    // Obtain the handle of perf block\n    if (info->blkHndl == NULL) {\n      status = hsa_ext_tools_get_counter_block_by_id(perfMgr_, info->blkId, &info->blkHndl);\n      assert((status == HSA_STATUS_SUCCESS) && \"Error in getting Perf Cntr Blk Hndl\");\n    }\n\n    // Create an instance of counter in the perf block\n    status = hsa_ext_tools_create_counter(info->blkHndl, &info->cntrHndl);\n    assert((status == HSA_STATUS_SUCCESS) && \"Error in creating Perf Cntr in Perf Blk\");\n\n    // Update the Event Index property of counter\n    uint32_t cntrProp = HSA_EXT_TOOLS_COUNTER_PARAMETER_EVENT_INDEX;\n    status = hsa_ext_tools_set_counter_parameter(info->cntrHndl, cntrProp,\n                                                 sizeof(uint32_t), (void*)&info->cntrId);\n    assert((status == HSA_STATUS_SUCCESS) && \"Error in updating Perf Cntr Property Event Index\");\n\n    // Enable the updated perf counter\n    status = hsa_ext_tools_set_counter_enabled(info->cntrHndl, true);\n    assert((status == HSA_STATUS_SUCCESS) && \"Error in enabing Perf Cntr\");\n  }\n\n  return status;\n}\n\n// Register Pre and Post dispatch callbacks\nvoid RocrPerfCntrApp::RegisterCallbacks(hsa_queue_t *queue){\n  \n  hsa_status_t status;\n  status = hsa_ext_tools_set_callback_functions(queue, PreDispatchCallback, PostDispatchCallback);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in registering Pre & Post Dispatch Callbacks\");\n  status = hsa_ext_tools_set_callback_arguments(queue, &perfMgr_, &perfMgr_);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in registering Pre & Post Dispatch Callback Params\");\n  return;\n}\n\n// Wait for perf counter collection to complete\nhsa_status_t RocrPerfCntrApp::Wait() {\n\n  hsa_status_t status;\n  status = hsa_ext_tools_pmu_wait_for_completion(perfMgr_, 5000);\n  assert((status == HSA_STATUS_SUCCESS) && \"Error in Waiting for Perf Cntr Completion\");\n  return status;\n}\n\n// Validate perf counter values\nhsa_status_t RocrPerfCntrApp::Validate() {\n\n  // Retrieve the results of the different Perf Cntrs\n  // and validate them as configured\n  CntrInfo* info = NULL;\n  hsa_status_t status = HSA_STATUS_SUCCESS;\n  uint32_t size = GetNumPerfCntrs();\n  for (uint32_t idx = 0; idx < size; idx++) {\n    info = GetPerfCntr(idx);\n    status = hsa_ext_tools_get_counter_result(info->cntrHndl, &info->cntrResult);\n    std::cout << \"Value of Perf Cntr is: \" << info->cntrResult << std::endl;\n  }\n\n  return status;\n}\n"
  },
  {
    "path": "samples/common/hsa_perf_cntrs.hpp",
    "content": "#ifndef ROCR_PERF_CNTR_APP_H_\n#define ROCR_PERF_CNTR_APP_H_\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#include <iostream>\n#include <vector>\n#include <string>\n\n#include \"hsa.h\"\n#include \"tools/inc/hsa_ext_profiler.h\"\n\ntypedef enum CntrValCnfType {\n  \n  ///< no counter value validation should be performed\n  CntrValCnf_None,\n\n  ///< counter value should be an exact match to expectedResult\n  CntrValCnf_Exact,\n\n  ///< counter value should be greater than expectedResult\n  CntrValCnf_GreaterThan,\n  \n  ///< counter value should be less than expectedResult\n  CntrValCnf_LessThan\n\n} CntrValCnfType;\n\n/// Struct used to encapsulate Counter Info\ntypedef struct CntrInfo {\n  \n  ///< Id of counter in hardware block\n  uint32_t cntrId;\n  \n  ///< Name of counter\n  char cntrName[72];\n  \n  ///< Handle of perf counter\n  hsa_ext_tools_counter_t cntrHndl;\n  \n  ///< Id of hardware block containing the counter\n  uint32_t blkId;\n  \n  ///< Handle of counter block\n  hsa_ext_tools_counter_block_t blkHndl;\n  \n  ///< Expected value of perf counte\n  uint64_t  expectedResult;\n\n  ///< Value of perf counter expected\n  uint64_t cntrResult;\n  \n  ///< Type of validation upon completion of dispatch\n  CntrValCnfType cnfType;\n\n  CntrInfo(uint32_t cntrId, char* cntrName, void* cntrHndl,\n           uint32_t blkId, void* blkHndl,\n           uint64_t expResult, uint64_t result, CntrValCnfType cnfType) {\n    this->cntrId = cntrId;\n    this->cntrHndl = cntrHndl;\n    this->blkId = blkId;\n    this->blkHndl = blkHndl;\n    this->expectedResult = expResult;\n    this->cntrResult = result;\n    this->cnfType = cnfType;\n    memcpy(this->cntrName, cntrName, strlen(cntrName));\n  }\n  \n} CntrInfo;\n\nclass RocrPerfCntrApp {\n\n public:\n\n  // Constructor of the class. Will initialize the list of perf counters\n  // that will be used to program the device\n  RocrPerfCntrApp( );\n\n  // Destructor of the class\n  ~RocrPerfCntrApp( );\n\n  // Return the number of perf counters\n  uint32_t GetNumPerfCntrs();\n\n  // Return the handle of perf counter at specified index\n  CntrInfo* GetPerfCntr(uint32_t idx);\n\n  // Print the list of perf counters\n  bool PrintCntrs();\n\n  // Initialize the list of perf counters\n  hsa_status_t Init(hsa_agent_t agent);\n\n  // Register Pre and Post dispatch callbacks\n  void RegisterCallbacks(hsa_queue_t *queue);\n\n  // Wait for perf counter collection to complete\n  hsa_status_t Wait();\n\n  // Validate perf counter values\n  hsa_status_t Validate();\n \n private:\n \n  // Number of queues to create\n  std::vector<CntrInfo *> cntrList_;\n\n  // Handle of Perf Cntr Manager\n  hsa_ext_tools_pmu_t perfMgr_;\n};\n\n#endif  //  ROCR_PERF_CNTR_APP_H_\n"
  },
  {
    "path": "samples/common/hsa_rsrc_factory.cpp",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <cassert>\n\n#include <iostream>\n#include <vector>\n#include <string>\n\n#include \"hsa.h\"\n#include \"hsa_rsrc_factory.hpp\"\n#include \"hsa_ext_finalize.h\"\n#include \"tools/inc/hsa_ext_profiler.h\"\n#include \"HSAILAmdExt.h\"\n\n#include \"common.hpp\"\n\nusing namespace std;\n\n// Provide access to command line arguments passed in by user\nuint32_t hsa_cmdline_arg_cnt;\nchar **hsa_cmdline_arg_list;\n\n// Callback function to find and bind kernarg region of an agent\nstatic hsa_status_t find_memregions(hsa_region_t region, void *data) {\n\n  hsa_region_global_flag_t flags;\n  hsa_region_segment_t segment_id;\n\n  hsa_region_get_info(region, HSA_REGION_INFO_SEGMENT, &segment_id);\n  if (segment_id != HSA_REGION_SEGMENT_GLOBAL) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  AgentInfo *agent_info = (AgentInfo *)data;\n  hsa_region_get_info(region, HSA_REGION_INFO_GLOBAL_FLAGS, &flags);\n  if (flags & HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED) {\n    agent_info->coarse_region = region;\n  }\n\n  if (flags & HSA_REGION_GLOBAL_FLAG_KERNARG) {\n    agent_info->kernarg_region = region;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\n// Callback function to get the number of agents\nstatic hsa_status_t get_hsa_agents(hsa_agent_t agent, void *data) {\n\n  // Copy handle of agent and increment number of agents reported\n  HsaRsrcFactory *rsrcFactory = reinterpret_cast<HsaRsrcFactory *>(data);\n\n  // Determine if device is a Gpu agent\n  hsa_status_t status;\n  hsa_device_type_t type;\n  status = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type);\n  if (type == HSA_DEVICE_TYPE_DSP) {\n    return HSA_STATUS_SUCCESS;\n  }\n\n  if (type == HSA_DEVICE_TYPE_CPU) {\n    AgentInfo *agent_info = reinterpret_cast<AgentInfo *>(malloc(sizeof(AgentInfo)));\n    agent_info->dev_id = agent;\n    agent_info->dev_type = HSA_DEVICE_TYPE_CPU;\n    rsrcFactory->AddAgentInfo(agent_info, false);\n    return HSA_STATUS_SUCCESS;\n  }\n  \n  // Device is a Gpu agent, build an instance of AgentInfo\n  AgentInfo *agent_info = reinterpret_cast<AgentInfo *>(malloc(sizeof(AgentInfo)));\n  agent_info->dev_id = agent;\n  agent_info->dev_type = HSA_DEVICE_TYPE_GPU;\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, agent_info->name);\n  agent_info->max_wave_size = 0;\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_WAVEFRONT_SIZE, &agent_info->max_wave_size);\n  agent_info->max_queue_size = 0;\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MAX_SIZE, &agent_info->max_queue_size);\n  agent_info->profile = hsa_profile_t(108);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_PROFILE, &agent_info->profile);\n\n  // Initialize memory regions to zero\n  agent_info->kernarg_region.handle = 0;\n  agent_info->coarse_region.handle = 0;\n  \n  // Find and Bind Memory regions of the Gpu agent\n  hsa_agent_iterate_regions(agent, find_memregions, agent_info);\n\n  // Save the instance of AgentInfo\n  rsrcFactory->AddAgentInfo(agent_info, true);\n  return HSA_STATUS_SUCCESS;\n}\n\n// Definitions for Static Data members of the class\nchar* HsaRsrcFactory::brig_path_ = NULL;\nuint32_t HsaRsrcFactory::num_cus_;\nuint32_t HsaRsrcFactory::num_waves_;\nuint32_t HsaRsrcFactory::num_workitems_;\nuint32_t HsaRsrcFactory::kernel_loop_count_;\nbool HsaRsrcFactory::print_debug_info_ = false;\n\nchar* HsaRsrcFactory::num_cus_key_ = \"num_cus\";\nchar* HsaRsrcFactory::brig_path_key_ = \"brig_path\";\nchar* HsaRsrcFactory::num_waves_key_ = \"waves_per_cu\";\nchar* HsaRsrcFactory::num_workitems_key_ = \"workitems_per_wave\";\nchar* HsaRsrcFactory::print_debug_key_ = \"print_debug\";\nchar* HsaRsrcFactory::kernel_loop_count_key_ = \"kernel_loop_count\";\n\n// Constructor of the class\nHsaRsrcFactory::HsaRsrcFactory( ) {\n\n  // Initialize the Hsa Runtime\n  hsa_status_t status = hsa_init();\n  assert(status == HSA_STATUS_SUCCESS);\n\n  // Discover the set of Gpu devices available on the platform\n  status = hsa_iterate_agents(get_hsa_agents, this);\n  check(\"Error Calling hsa_iterate_agents\", status);\n\n  // Process command line arguments\n  ProcessCmdline( );\n}\n\n// Destructor of the class\nHsaRsrcFactory::~HsaRsrcFactory( ) {\n\n}\n\n// Get the count of Hsa Gpu Agents available on the platform\n//\n// @return uint32_t Number of Gpu agents on platform\n//\nuint32_t HsaRsrcFactory::GetCountOfGpuAgents( ) {\n  return uint32_t(gpu_list_.size());\n}\n\n// Get the count of Hsa Cpu Agents available on the platform\n//\n// @return uint32_t Number of Cpu agents on platform\n//\nuint32_t HsaRsrcFactory::GetCountOfCpuAgents( ) {\n  return uint32_t(cpu_list_.size());\n}\n\n// Get the AgentInfo handle of a Gpu device\n//\n// @param idx Gpu Agent at specified index\n//\n// @param agent_info Output parameter updated with AgentInfo\n//\n// @return bool true if successful, false otherwise\n//\nbool HsaRsrcFactory::GetGpuAgentInfo(uint32_t idx, AgentInfo **agent_info) {\n\n  // Determine if request is valid\n  uint32_t size = uint32_t(gpu_list_.size());\n  if (idx >= size) {\n    return false;\n  }\n\n  // Copy AgentInfo from specified index\n  *agent_info = gpu_list_[idx];\n  return true;\n}\n\n// Get the AgentInfo handle of a Cpu device\n//\n// @param idx Cpu Agent at specified index\n//\n// @param agent_info Output parameter updated with AgentInfo\n//\n// @return bool true if successful, false otherwise\n//\nbool HsaRsrcFactory::GetCpuAgentInfo(uint32_t idx, AgentInfo **agent_info) {\n\n  // Determine if request is valid\n  uint32_t size = uint32_t(cpu_list_.size());\n  if (idx >= size) {\n    return false;\n  }\n\n  // Copy AgentInfo from specified index\n  *agent_info = cpu_list_[idx];\n  return true;\n}\n\n// Create a Queue object and return its handle. The queue object is expected\n// to support user requested number of Aql dispatch packets.\n//\n// @param agent_info Gpu Agent on which to create a queue object\n//\n// @param num_Pkts Number of packets to be held by queue\n//\n// @param queue Output parameter updated with handle of queue object\n//\n// @return bool true if successful, false otherwise\n//\nbool HsaRsrcFactory::CreateQueue(AgentInfo *agent_info,\n                                 uint32_t num_pkts, hsa_queue_t **queue) {\n\n  hsa_status_t status;\n\n  // Code to create a Profile Queue object\n  if (num_pkts == UINT32_MAX) {\n    status = hsa_ext_tools_queue_create_profiled(agent_info->dev_id,\n                                  512, HSA_QUEUE_TYPE_SINGLE, NULL,\n                                  NULL, UINT32_MAX, UINT32_MAX, queue);\n    return (status == HSA_STATUS_SUCCESS);\n  }\n\n  status = hsa_queue_create(agent_info->dev_id, num_pkts,\n                            HSA_QUEUE_TYPE_MULTI, NULL, NULL,\n                            UINT32_MAX, UINT32_MAX, queue);\n  return (status == HSA_STATUS_SUCCESS);\n}\n\n// Create a Signal object and return its handle.\n//\n// @param value Initial value of signal object\n//\n// @param signal Output parameter updated with handle of signal object\n//\n// @return bool true if successful, false otherwise\n//\nbool HsaRsrcFactory::CreateSignal(uint32_t value, hsa_signal_t *signal) {\n\n  hsa_status_t status;\n  status = hsa_signal_create(value, 0, NULL, signal);\n  return (status == HSA_STATUS_SUCCESS);\n}\n\n// Allocate memory for use by a kernel of specified size in specified\n// agent's memory region. Currently supports Global segment whose Kernarg\n// flag set.\n//\n// @param agent_info Agent from whose memory region to allocate\n//\n// @param size Size of memory in terms of bytes\n//\n// @return uint8_t* Pointer to buffer, null if allocation fails.\n//\nuint8_t* HsaRsrcFactory::AllocateLocalMemory(AgentInfo *agent_info, size_t size) {\n\n  hsa_status_t status;\n  uint8_t *buffer = NULL;\n\n  // Allocate in local memory only if it is available\n  if (agent_info->coarse_region.handle != 0) {\n    std::cout << \"Allocating in local memory\" << std::endl;\n    status = hsa_memory_allocate(agent_info->coarse_region, size, (void **)&buffer);\n    if (status == HSA_STATUS_SUCCESS) {\n      status = hsa_memory_assign_agent(buffer, agent_info->dev_id, HSA_ACCESS_PERMISSION_RW);\n      return (status == HSA_STATUS_SUCCESS) ? buffer : NULL;\n    }\n    return NULL;\n  }\n\n  // Allocate in system memory if local memory is not available\n  std::cout << \"Allocating in system memory\" << std::endl;\n  status = hsa_memory_allocate(agent_info->kernarg_region, size, (void **)&buffer);\n  return (status == HSA_STATUS_SUCCESS) ? buffer : NULL;\n}\n\n// Allocate memory tp pass kernel parameters.\n//\n// @param agent_info Agent from whose memory region to allocate\n//\n// @param size Size of memory in terms of bytes\n//\n// @return uint8_t* Pointer to buffer, null if allocation fails.\n//\nuint8_t* HsaRsrcFactory::AllocateSysMemory(AgentInfo *agent_info, size_t size) {\n\n  hsa_status_t status;\n  uint8_t *buffer = NULL;\n  status = hsa_memory_allocate(agent_info->kernarg_region, size, (void **)&buffer);\n  return (status == HSA_STATUS_SUCCESS) ? buffer : NULL;\n}\n\nbool HsaRsrcFactory::TransferData(uint8_t *dest_buff, uint8_t *src_buff,\n                                  uint32_t length, bool host_to_dev) {\n\n  hsa_status_t status;\n  status = hsa_memory_copy(dest_buff, src_buff, length);\n  return (status == HSA_STATUS_SUCCESS);\n\n}\n\n// Fake method for compilation steps only\nuint8_t* HsaRsrcFactory::AllocateMemory(AgentInfo *agent_info, size_t size) {\n\n  hsa_status_t status;\n  uint8_t *buffer = NULL;\n  status = hsa_memory_allocate(agent_info->kernarg_region, size, (void **)&buffer);\n  return (status == HSA_STATUS_SUCCESS) ? buffer : NULL;\n}\n\n// Loads an Assembled Brig file and Finalizes it into Device Isa\n//\n// @param agent_info Gpu device for which to finalize\n//\n// @param brig_path File path of the Assembled Brig file\n//\n// @param kernel_name Name of the kernel to finalize\n//\n// @param code_desc Handle of finalized Code Descriptor that could\n// be used to submit for execution\n//\n// @return bool true if successful, false otherwise\n//\nbool HsaRsrcFactory::LoadAndFinalize(AgentInfo *agent_info,\n                                     const char *brig_path, char *kernel_name,\n                                     hsa_executable_symbol_t *code_desc) {\n\n  hsa_status_t status;\n  // Load BRIG, encapsulated in an ELF container, into a BRIG module.\n  /*\n  status_t build_err;\n  hsa_ext_brig_module_t *brig_obj;\n  build_err = (status_t)create_brig_module_from_brig_file(brig_path, &brig_obj);\n  check_build(\"Error in creating the brig module from brig file\", build_err);\n\n  // Determine the Brig module has the kernel symbol\n  hsa_status_t status;\n  hsa_ext_brig_code_section_offset32_t kernel_symbol;\n  status = hsa_find_symbol_offset(brig_obj, kernel_name, &kernel_symbol);\n  check(\"Error in Finding the Symbol Offset for the Kernel\", status);\n  */\n\n  amd::hsail::registerExtensions();\n\n  // Copy handle of Brig object\n  hsa_ext_module_t brig_module_v3;\n  if (!tool.assembleFromFile(brig_path)) {\n    std::cout << tool.output();\n    return false;\n  }\n  brig_module_v3 = tool.brigModule();\n  \n  // Create hsail program.\n  hsa_ext_program_t hsailProgram;\n  status = hsa_ext_program_create(HSA_MACHINE_MODEL_LARGE,\n                                  agent_info->profile,\n                                  HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO,\n                                  NULL, &hsailProgram);\n  check(\"Error in creating program object\", status);\n\n  // Add hsail module.\n  status = hsa_ext_program_add_module(hsailProgram, brig_module_v3);\n  check(\"Error in adding module to program object\", status);\n\n  // Finalize hsail program.\n  hsa_isa_t isa = {0};\n  status = hsa_agent_get_info(agent_info->dev_id, HSA_AGENT_INFO_ISA, &isa);\n  check(\"Error in getting Id of Isa supported by agent\", status);\n\n  hsa_ext_control_directives_t control_directives;\n  memset(&control_directives, 0, sizeof(hsa_ext_control_directives_t));\n\n  hsa_code_object_t code_object;\n  status = hsa_ext_program_finalize(hsailProgram,\n                                           isa,\n                                           0,\n                                           control_directives,\n                                           NULL, //\"-g -O0 -dump-isa\",\n                                           HSA_CODE_OBJECT_TYPE_PROGRAM,\n                                           &code_object);\n  check(\"Error in finalizing program object\", status);\n\n  //status = hsa_ext_program_destroy(hsailProgram);\n  //check(\"Error in destroying program object\", status);\n\n  // Create executable.\n  hsa_executable_t hsaExecutable;\n  status = hsa_executable_create(agent_info->profile,\n                                 HSA_EXECUTABLE_STATE_UNFROZEN,\n                                 \"\", &hsaExecutable);\n  check(\"Error in creating executable object\", status);\n\n  // Load code object.\n  status = hsa_executable_load_code_object(hsaExecutable, agent_info->dev_id, code_object, \"\");\n  check(\"Error in loading executable object\", status);\n\n  // Freeze executable.\n  status = hsa_executable_freeze(hsaExecutable, \"\");\n  check(\"Error in freezing executable object\", status);\n\n  // Get symbol handle.\n  hsa_executable_symbol_t kernelSymbol;\n  status = hsa_executable_get_symbol(hsaExecutable, NULL,\n                             kernel_name, agent_info->dev_id, 0, &kernelSymbol);\n  \n  // Update output parameter\n  *code_desc = kernelSymbol;\n  return true;\n\n  /**\n\n  // Create Hsa Program\n  hsa_ext_program_handle_t program;\n  status = hsa_ext_program_create(&agent_info->dev_id, 1,\n                                  HSA_EXT_BRIG_MACHINE_LARGE,\n                                  HSA_EXT_BRIG_PROFILE_FULL, &program);\n  check(\"Error in Creating Hsa Program\", status);\n\n  // Add the BRIG module to hsa program.\n  hsa_ext_brig_module_handle_t brig_handle;\n  status = hsa_ext_add_module(program, brig_obj, &brig_handle);\n  check(\"Error in Adding Brig Module to the Program\", status);\n\n  // Construct finalization request list.\n  hsa_ext_finalization_request_t finalize_request;\n  finalize_request.module = brig_handle;\n  finalize_request.symbol = kernel_symbol;\n  finalize_request.program_call_convention = 0;\n\n  // Finalize the Hsa Program.\n  status = hsa_ext_finalize_program(program, agent_info->dev_id,\n                                    1, &finalize_request, NULL, NULL, 0, NULL, 0);\n  check(\"Error in Finalizing the Hsa Program\", status);\n\n  // Destroy the brig module. The program was successfully created the kernel\n  // symbol was found and the program was finalized, so it is no longer needed.\n  destroy_brig_module(brig_obj);\n\n  // Get the hsa code descriptor address.\n  status = hsa_ext_query_kernel_descriptor_address(program, brig_handle, kernel_symbol, code_desc);\n  check(\"Error Querying the Kernel Descriptor Address\", status);\n\n  return true;\n  **/\n}\n\n// Add an instance of AgentInfo representing a Hsa Gpu agent\nvoid HsaRsrcFactory::AddAgentInfo(AgentInfo *agent_info, bool gpu) {\n  \n  // Add input to Gpu list\n  if (gpu) {\n    gpu_list_.push_back(agent_info);\n    return;\n  }\n\n  // Add input to Cpu list\n  cpu_list_.push_back(agent_info);\n}\n\n// Print the various fields of Hsa Gpu Agents\nbool HsaRsrcFactory::PrintGpuAgents( ) {\n\n  AgentInfo *agent_info;\n  int size = uint32_t(gpu_list_.size());\n  for (int idx = 0; idx < size; idx++) {\n    agent_info = gpu_list_[idx];\n    std::cout << std::endl;\n    std::cout << \"Hsa Gpu Agent Id: \" << agent_info->dev_id.handle << std::endl;\n    std::cout << \"Hsa Gpu Agent Name: \" << agent_info->name << std::endl;\n    std::cout << \"Hsa Gpu Agent Max Wave Size: \" << agent_info->max_wave_size << std::endl;\n    std::cout << \"Hsa Gpu Agent Max Queue Size: \" << agent_info->max_queue_size << std::endl;\n    std::cout << \"Hsa Gpu Agent Kernarg Region Id: \" << agent_info->coarse_region.handle << std::endl;\n    std::cout << std::endl;\n  }\n  return true;\n}\n\n// Returns the file path where brig files is located. Value is\n// available only after an instance has been built.\nchar* HsaRsrcFactory::GetBrigPath( ) {\n  return HsaRsrcFactory::brig_path_;\n}\n\n// Returns the number of compute units present on platform\n// Value is available only after an instance has been built.\nuint32_t HsaRsrcFactory::GetNumOfCUs( ) {\n  return HsaRsrcFactory::num_cus_;\n}\n\n// Returns the maximum number of waves that can be launched\n// per compute unit. The actual number that can be launched\n// is affected by resource availability\n//\n// Value is available only after an instance has been built.\nuint32_t HsaRsrcFactory::GetNumOfWavesPerCU( ) {\n  return HsaRsrcFactory::num_waves_;\n}\n\n// Returns the number of work-items that can execute per wave\n// Value is available only after an instance has been built.\nuint32_t HsaRsrcFactory::GetNumOfWorkItemsPerWave( ) {\n  return HsaRsrcFactory::num_workitems_;\n}\n\n// Returns the number of times kernel loop body should execute.\n// Value is available only after an instance has been built.\nuint32_t HsaRsrcFactory::GetKernelLoopCount() {\n  return HsaRsrcFactory::kernel_loop_count_;\n}\n\n// Returns boolean flag to indicate if debug info should be printed\n// Value is available only after an instance has been built.\nuint32_t HsaRsrcFactory::GetPrintDebugInfo() {\n  return HsaRsrcFactory::print_debug_info_;\n}\n\n// Process command line arguments. The method will capture\n// various user command line parameters for tests to use\nvoid HsaRsrcFactory::ProcessCmdline( ) {\n \n  // Command line arguments are given\n  uint32_t idx;\n  uint32_t arg_idx;\n  for (idx = 1; idx < hsa_cmdline_arg_cnt; idx += 2) {\n    arg_idx = GetArgIndex((char *)hsa_cmdline_arg_list[idx]);\n    switch(arg_idx) {\n      case 0:\n        HsaRsrcFactory::brig_path_ = hsa_cmdline_arg_list[idx + 1];\n        break;\n      case 1:\n        HsaRsrcFactory::num_cus_ = atoi(hsa_cmdline_arg_list[idx + 1]);\n        break;\n      case 2:\n        HsaRsrcFactory::num_waves_ = atoi(hsa_cmdline_arg_list[idx + 1]);\n        break;\n      case 3:\n        HsaRsrcFactory::num_workitems_ = atoi(hsa_cmdline_arg_list[idx + 1]);\n        break;\n      case 4:\n        HsaRsrcFactory::kernel_loop_count_ = atoi(hsa_cmdline_arg_list[idx + 1]);\n        break;\n      case 5:\n        HsaRsrcFactory::print_debug_info_ = true;\n        break;\n    }\n  }\n\n}\n\nuint32_t HsaRsrcFactory::GetArgIndex(char *arg_value ) {\n\n  // Map Brig file path to index zero\n  if (!strcmp(HsaRsrcFactory::brig_path_key_, arg_value)) {\n      return 0;\n  }\n\n  // Map Number of Compute Units to index one\n  if (!strcmp(HsaRsrcFactory::num_cus_key_, arg_value)) {\n      return 1;\n  }\n\n  // Map Number of Waves per CU to index two\n  if (!strcmp(HsaRsrcFactory::num_waves_key_, arg_value)) {\n      return 2;\n  }\n\n  // Map Number of Workitems per Wave to index three\n  if (!strcmp(HsaRsrcFactory::num_workitems_key_, arg_value)) {\n      return 3;\n  }\n\n  // Map Kernel Loop Count to index four\n  if (!strcmp(HsaRsrcFactory::kernel_loop_count_key_, arg_value)) {\n      return 4;\n  }\n\n  // Map print debug info parameter\n  if (!strcmp(HsaRsrcFactory::print_debug_key_, arg_value)) {\n      return 5;\n  }\n  \n  return 108;\n\n}\n\nvoid HsaRsrcFactory::PrintHelpMsg( ) {\n\n  std::cout << \"Key for passing Brig filepath: \" << HsaRsrcFactory::brig_path_key_ << std::endl;\n  std::cout << \"Key for passing Number of Compute Units: \" << HsaRsrcFactory::num_cus_key_ << std::endl;\n  std::cout << \"Key for passing Number of Waves per CU: \" << HsaRsrcFactory::num_waves_key_ << std::endl;\n  std::cout << \"Key for passing Number of Workitems per Wave: \" << HsaRsrcFactory::num_workitems_key_ << std::endl;\n  std::cout << \"Key for passing Kernel Loop Count: \" << HsaRsrcFactory::kernel_loop_count_key_ << std::endl;\n\n}\n"
  },
  {
    "path": "samples/common/hsa_rsrc_factory.hpp",
    "content": "#ifndef HSA_RSRC_FACTORY_H_\n#define HSA_RSRC_FACTORY_H_\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#include <iostream>\n#include <vector>\n#include <string>\n\n#include \"hsatimer.h\"\n#include \"hsa.h\"\n#include \"hsa_ext_finalize.h\"\n#include \"HSAILTool.h\"\n\n\n#define HSA_ARGUMENT_ALIGN_BYTES 16\n#define HSA_QUEUE_ALIGN_BYTES 64\n#define HSA_PACKET_ALIGN_BYTES 64\n\n#define check(msg, status) \\\nif (status != HSA_STATUS_SUCCESS) { \\\n    const char *emsg = 0; \\\n    hsa_status_string(status, &emsg); \\\n    printf(\"%s: %s\\n\", msg, emsg ? emsg : \"<unknown error>\"); \\\n    exit(1); \\\n}\n\n#define check_build(msg, status) \\\nif (status != STATUS_SUCCESS) { \\\n    printf(\"%s\\n\", msg); \\\n    exit(1); \\\n}\n\n// Define required BRIG data structures.\ntypedef uint32_t BrigCodeOffset32_t;\ntypedef uint32_t BrigDataOffset32_t;\ntypedef uint16_t BrigKinds16_t;\ntypedef uint8_t BrigLinkage8_t;\ntypedef uint8_t BrigExecutableModifier8_t;\ntypedef BrigDataOffset32_t BrigDataOffsetString32_t;\n\n/*\nenum BrigKinds {\n  BRIG_KIND_NONE = 0x0000,\n  BRIG_KIND_DIRECTIVE_BEGIN = 0x1000,\n  BRIG_KIND_DIRECTIVE_KERNEL = 0x1008,\n};\n\ntypedef struct BrigBase BrigBase;\nstruct BrigBase {\n  uint16_t byteCount;\n  BrigKinds16_t kind;\n};\n\ntypedef struct BrigExecutableModifier BrigExecutableModifier;\nstruct BrigExecutableModifier {\n  BrigExecutableModifier8_t allBits;\n};\n\ntypedef struct BrigDirectiveExecutable BrigDirectiveExecutable;\nstruct BrigDirectiveExecutable {\n  uint16_t byteCount;\n  BrigKinds16_t kind;\n  BrigDataOffsetString32_t name;\n  uint16_t outArgCount;\n  uint16_t inArgCount;\n  BrigCodeOffset32_t firstInArg;\n  BrigCodeOffset32_t firstCodeBlockEntry;\n  BrigCodeOffset32_t nextModuleEntry;\n  uint32_t codeBlockEntryCount;\n  BrigExecutableModifier modifier;\n  BrigLinkage8_t linkage;\n  uint16_t reserved;\n};\n\ntypedef struct BrigData BrigData;\nstruct BrigData {\n  uint32_t byteCount;\n  uint8_t bytes[1];\n};\n*/\n\n// Provide access to command line arguments passed in by user\nextern uint32_t hsa_cmdline_arg_cnt;\nextern char **hsa_cmdline_arg_list;\n\n// Encapsulates information about a Hsa Agent such as its\n// handle, name, max queue size, max wavefront size, etc.\ntypedef struct {\n\n  // Handle of Agent\n  hsa_agent_t dev_id;\n  \n  // Agent type - Cpu = 0, Gpu = 1 or Dsp = 2\n  uint32_t dev_type;\n\n  // Name of Agent whose length is less than 64\n  char name[64];\n\n  // Max size of Wavefront size\n  uint32_t max_wave_size;\n\n  // Max size of Queue buffer\n  uint32_t max_queue_size;\n\n  // Hsail profile supported by agent\n  hsa_profile_t profile;\n\n  // Memory region supporting kernel parameters\n  hsa_region_t coarse_region;\n\n  // Memory region supporting kernel arguments\n  hsa_region_t kernarg_region;\n\n} AgentInfo;\n\nclass HsaRsrcFactory {\n\n public:\n\n  // Constructor of the class. Will initialize the Hsa Runtime and\n  // query the system topology to get the list of Cpu and Gpu devices\n  HsaRsrcFactory( );\n\n  // Destructor of the class\n  ~HsaRsrcFactory( );\n\n  // Get the count of Hsa Gpu Agents available on the platform\n  //\n  // @return uint32_t Number of Gpu agents on platform\n  //\n  uint32_t GetCountOfGpuAgents( );\n\n  // Get the count of Hsa Cpu Agents available on the platform\n  //\n  // @return uint32_t Number of Cpu agents on platform\n  //\n  uint32_t GetCountOfCpuAgents( );\n\n  // Get the AgentInfo handle of a Gpu device\n  //\n  // @param idx Gpu Agent at specified index\n  //\n  // @param agent_info Output parameter updated with AgentInfo\n  //\n  // @return bool true if successful, false otherwise\n  //\n  bool GetGpuAgentInfo(uint32_t idx, AgentInfo **agent_info);\n\n  // Get the AgentInfo handle of a Cpu device\n  //\n  // @param idx Cpu Agent at specified index\n  //\n  // @param agent_info Output parameter updated with AgentInfo\n  //\n  // @return bool true if successful, false otherwise\n  //\n  bool GetCpuAgentInfo(uint32_t idx, AgentInfo **agent_info);\n\n  // Create a Queue object and return its handle. The queue object is expected\n  // to support user requested number of Aql dispatch packets.\n  //\n  // @param agent_info Gpu Agent on which to create a queue object\n  //\n  // @param num_Pkts Number of packets to be held by queue\n  //\n  // @param queue Output parameter updated with handle of queue object\n  //\n  // @return bool true if successful, false otherwise\n  //\n  bool CreateQueue(AgentInfo *agent_info,\n                   uint32_t num_pkts, hsa_queue_t **queue);\n\n  // Create a Signal object and return its handle.\n  //\n  // @param value Initial value of signal object\n  //\n  // @param signal Output parameter updated with handle of signal object\n  //\n  // @return bool true if successful, false otherwise\n  //\n  bool CreateSignal(uint32_t value, hsa_signal_t *signal);\n\n  // Allocate memory for use by a kernel of specified size in specified\n  // agent's memory region. Currently supports Global segment whose Kernarg\n  // flag set.\n  //\n  // @param agent_info Agent from whose memory region to allocate\n  //\n  // @param size Size of memory in terms of bytes\n  //\n  // @return uint8_t* Pointer to buffer, null if allocation fails.\n  //\n  uint8_t* AllocateLocalMemory(AgentInfo *agent_info, size_t size);\n  uint8_t* AllocateMemory(AgentInfo *agent_info, size_t size);\n\n  bool TransferData(uint8_t *dest_buff, uint8_t *src_buff,\n                    uint32_t length, bool host_to_dev);\n\n  // Allocate memory tp pass kernel parameters.\n  //\n  // @param agent_info Agent from whose memory region to allocate\n  //\n  // @param size Size of memory in terms of bytes\n  //\n  // @return uint8_t* Pointer to buffer, null if allocation fails.\n  //\n  uint8_t* AllocateSysMemory(AgentInfo *agent_info, size_t size);\n\n  // Loads an Assembled Brig file and Finalizes it into Device Isa\n  //\n  // @param agent_info Gpu device for which to finalize\n  //\n  // @param brig_path File path of the Assembled Brig file\n  //\n  // @param kernel_name Name of the kernel to finalize\n  //\n  // @param code_desc Handle of finalized Code Descriptor that could\n  // be used to submit for execution\n  //\n  // @return bool true if successful, false otherwise\n  //\n  bool LoadAndFinalize(AgentInfo *agent_info,\n                       const char *brig_path, char *kernel_name,\n                       hsa_executable_symbol_t *code_desc);\n\n  // Add an instance of AgentInfo representing a Hsa Gpu agent\n  void AddAgentInfo(AgentInfo *agent_info, bool gpu);\n\n  // Returns the file path where brig files is located\n  static char* GetBrigPath( );\n\n  // Returns the number of compute units present on platform\n  static uint32_t GetNumOfCUs( );\n\n  // Returns the maximum number of waves that can be launched\n  // per compute unit. The actual number that can be launched\n  // is affected by resource availability\n  static uint32_t GetNumOfWavesPerCU( );\n\n  // Returns the number of work-items that can execute per wave\n  static uint32_t GetNumOfWorkItemsPerWave( );\n  \n  // Returns the number of times kernel loop body should execute.\n  static uint32_t GetKernelLoopCount();\n  \n  // Returns boolean flag to indicate if debug info should be printed\n  static uint32_t GetPrintDebugInfo();\n\n private:\n \n  // Number of queues to create\n  uint32_t num_queues_;\n\n  // Used to maintain a list of Hsa Queue handles\n  std::vector<hsa_queue_t *> queue_list_;\n \n  // Number of Signals to create\n  uint32_t num_signals_;\n \n  // Used to maintain a list of Hsa Signal handles\n  std::vector<hsa_signal_t *> signal_list_;\n \n  // Number of agents reported by platform\n  uint32_t num_agents_;\n \n  // Used to maintain a list of Hsa Gpu Agent Info\n  std::vector<AgentInfo *> gpu_list_;\n \n  // Used to maintain a list of Hsa Cpu Agent Info\n  std::vector<AgentInfo *> cpu_list_;\n\n  // Records the file path where Brig file is located.\n  // Value is available only after an instance has been built.\n  static char* brig_path_;\n  static char* brig_path_key_;\n\n  // Records the number of Compute units present on system.\n  // Value is available only after an instance has been built.\n  static uint32_t num_cus_;\n  static char* num_cus_key_;\n\n  // Records the number of waves that can be launched per Compute unit\n  // Value is available only after an instance has been built.\n  static uint32_t num_waves_;\n  static char* num_waves_key_;\n\n  // Records the number of work-items that can be packed into a wave\n  // Value is available only after an instance has been built.\n  static uint32_t num_workitems_;\n  static char* num_workitems_key_;\n\n  // Records the number of times kernel loop body should run. Value\n  // is available only after an instance has been built.\n  static uint32_t kernel_loop_count_;\n  static char* kernel_loop_count_key_;\n\n  // Records the number of times kernel loop body should run. Value\n  // is available only after an instance has been built.\n  static bool print_debug_info_;\n  static char* print_debug_key_;\n\n  // Print the various fields of Hsa Gpu Agents\n  bool PrintGpuAgents( );\n  \n  // Process command line arguments. The method will capture\n  // various user command line parameters for tests to use\n  static void ProcessCmdline( );\n  \n  // Prints the help banner on user arg keys\n  static void PrintHelpMsg( );\n\n  // Maps an index for the user argument\n  static uint32_t GetArgIndex(char *arg_value);\n\n  HSAIL_ASM::Tool tool;\n};\n\n#endif  //  HSA_RSRC_FACTORY_H_\n"
  },
  {
    "path": "samples/common/hsa_test.cpp",
    "content": "#include \"hsa_test.h\"\n\n#include <atomic>\n#include <iostream>\n\n#define PRINT_ATTRIBUTE(attribute, value, metric) \\\n  std::cout << #attribute \" = \" << value << \" \" << metric << std::endl;\n\nstatic size_t ToMB(size_t size) { return (size / (1024 * 1024)); }\n\nHsaTest::HsaTest(const char* test_name) : test_name_(test_name) {\n  std::cout << \"Running \" << test_name_ << std::endl;\n  std::cout << \"------------------------------------------------\\n\";\n}\n\nHsaTest::~HsaTest() {}\n\nvoid HsaTest::Init() {\n  hsa_status_t stat = hsa_init();\n  if (stat != HSA_STATUS_SUCCESS) {\n    std::cerr << \"hsa_init fail with status \" << stat << std::endl;\n  }\n\n  stat = hsa_iterate_agents(IterateAgents, (void*)this);\n}\n\nvoid HsaTest::Cleanup() { hsa_shut_down(); }\n\nhsa_status_t HsaTest::IterateAgents(hsa_agent_t agent, void* data) {\n  HsaTest* hsatest = (HsaTest*)data;\n\n  AgentProps prop(agent);\n\n  if (prop.device_type == HSA_DEVICE_TYPE_CPU) {\n    hsatest->cpus_.push_back(agent);\n  } else if (prop.device_type == HSA_DEVICE_TYPE_GPU) {\n    hsatest->gpus_.push_back(agent);\n  }\n\n  hsa_amd_memory_pool_t pools[3] = {{0}, {0}, {0}};\n  hsa_status_t stat =\n      hsa_amd_agent_iterate_memory_pools(agent, IteratePools, pools);\n\n  hsatest->global_fine_[agent.handle] = pools[0];\n  hsatest->global_coarse_[agent.handle] = pools[1];\n  hsatest->group_[agent.handle] = pools[2];\n\n  return HSA_STATUS_SUCCESS;\n}\n\nhsa_status_t HsaTest::IteratePools(hsa_amd_memory_pool_t pool, void* data) {\n  hsa_amd_memory_pool_t* pools = (hsa_amd_memory_pool_t*)data;\n\n  PoolProps prop(pool);\n\n  if (prop.segment == HSA_AMD_SEGMENT_GLOBAL) {\n    if (prop.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED) {\n      pools[0].handle = pool.handle;\n    } else {\n      pools[1].handle = pool.handle;\n    }\n  } else if (prop.segment == HSA_AMD_SEGMENT_GROUP) {\n    pools[2].handle = pool.handle;\n  }\n\n  return HSA_STATUS_SUCCESS;\n}\n\nHsaTest::AgentProps::AgentProps(hsa_agent_t agent) {\n  if (agent.handle == 0) {\n    return;\n  }\n\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_NAME, (void*)name);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_VENDOR_NAME, (void*)vendor_name);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_FEATURE, (void*)&feature);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_MACHINE_MODEL,\n                     (void*)&machine_model);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_PROFILE, (void*)&profile);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE,\n                     (void*)&default_float_rounding_mode);\n  hsa_agent_get_info(agent,\n                     HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES,\n                     (void*)&base_profile_float_rounding_mode);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_FAST_F16_OPERATION,\n                     (void*)&fast_f16_operation);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_WAVEFRONT_SIZE,\n                     (void*)&wavefront_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_WORKGROUP_MAX_DIM,\n                     (void*)workgroup_max_dim);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_WORKGROUP_MAX_SIZE,\n                     (void*)&workgroup_max_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_GRID_MAX_DIM, (void*)&grid_max_dim);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_GRID_MAX_SIZE,\n                     (void*)&grid_max_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_FBARRIER_MAX_SIZE,\n                     (void*)&fbarrier_max_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUES_MAX, (void*)&queue_max);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MIN_SIZE,\n                     (void*)&queue_min_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_MAX_SIZE,\n                     (void*)&queue_max_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_QUEUE_TYPE, (void*)&queue_type);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_NODE, (void*)&node);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, (void*)&device_type);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_CACHE_SIZE, (void*)cache_size);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_ISA, (void*)&isa);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_EXTENSIONS, (void*)extensions);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_VERSION_MAJOR,\n                     (void*)&version_major);\n  hsa_agent_get_info(agent, HSA_AGENT_INFO_VERSION_MINOR,\n                     (void*)&version_minor);\n}\n\nHsaTest::PoolProps::PoolProps(hsa_amd_memory_pool_t pool) {\n  if (pool.handle == 0) {\n    return;\n  }\n\n  hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                               (void*)&segment);\n  hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS,\n                               (void*)&global_flag);\n  hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_SIZE,\n                               (void*)&size);\n  hsa_amd_memory_pool_get_info(pool,\n                               HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,\n                               (void*)&alloc_allowed);\n  hsa_amd_memory_pool_get_info(pool,\n                               HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE,\n                               (void*)&alloc_granule);\n  hsa_amd_memory_pool_get_info(pool,\n                               HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT,\n                               (void*)&alloc_alignment);\n  hsa_amd_memory_pool_get_info(pool, HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL,\n                               (void*)&all_accessible);\n}\n\nHsaTest::Kernel::Kernel(hsa_agent_t agent, std::string hsail_text)\n    : agent_(agent), hsail_file_(hsail_text) {\n  program_.handle = 0;\n  code_object_.handle = 0;\n  executable_.handle = 0;\n\n  AgentProps prop(agent_);\n  profile_ = prop.profile;\n\n  Initialize();\n}\n\nHsaTest::Kernel::~Kernel() { Cleanup(); }\n\nuint64_t HsaTest::Kernel::GetCodeHandle(const char* kernel_name) {\n  kernel_symbol_ = {0};\n  if (HSA_STATUS_SUCCESS != hsa_executable_get_symbol(executable_, NULL,\n                                                      kernel_name, agent_, 0,\n                                                      &kernel_symbol_)) {\n    return 0;\n  }\n\n  uint64_t code_handle = 0;\n  if (HSA_STATUS_SUCCESS !=\n      hsa_executable_symbol_get_info(kernel_symbol_,\n                                     HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT,\n                                     &code_handle)) {\n    return 0;\n  }\n\n  return code_handle;\n}\n\nhsa_status_t HsaTest::Kernel::GetScratchSize(uint32_t* size) {\n\n  hsa_status_t status;\n  status = hsa_executable_symbol_get_info(kernel_symbol_,\n               HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE, size);\n  return status;\n}\n\nvoid HsaTest::Kernel::Initialize() {\n  CreateProgramFromHsailFile();\n  CreateCodeObjectAndExecutable();\n}\n\nvoid HsaTest::Kernel::Cleanup() {\n  if (executable_.handle != 0) {\n    hsa_executable_destroy(executable_);\n    executable_.handle = 0;\n  }\n\n  if (code_object_.handle != 0) {\n    hsa_code_object_destroy(code_object_);\n    code_object_.handle = 0;\n  }\n\n  if (program_.handle != 0) {\n    hsa_ext_program_destroy(program_);\n    program_.handle = 0;\n  }\n}\n\nbool HsaTest::Kernel::CreateProgramFromHsailFile() {\n  if (HSA_STATUS_SUCCESS !=\n      hsa_ext_program_create(HSA_MACHINE_MODEL_LARGE, profile_,\n                             HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO, NULL,\n                             &program_)) {\n    return false;\n  }\n\n  if (!tool_.assembleFromFile(hsail_file_.c_str())) {\n    return false;\n  }\n\n  hsa_ext_module_t module = tool_.brigModule();\n  if (HSA_STATUS_SUCCESS != hsa_ext_program_add_module(program_, module)) {\n    return false;\n  }\n\n  return true;\n}\n\nbool HsaTest::Kernel::CreateCodeObjectAndExecutable() {\n  hsa_isa_t isa = {0};\n  if (HSA_STATUS_SUCCESS !=\n      hsa_agent_get_info(agent_, HSA_AGENT_INFO_ISA, &isa)) {\n    return false;\n  }\n\n  hsa_ext_control_directives_t control_directives = {0};\n  if (HSA_STATUS_SUCCESS !=\n      hsa_ext_program_finalize(program_, isa, 0, control_directives, \"\",\n                               HSA_CODE_OBJECT_TYPE_PROGRAM, &code_object_)) {\n    return false;\n  }\n\n  if (HSA_STATUS_SUCCESS != hsa_executable_create(profile_,\n                                                  HSA_EXECUTABLE_STATE_UNFROZEN,\n                                                  \"\", &executable_)) {\n    return false;\n  }\n\n  if (HSA_STATUS_SUCCESS !=\n      hsa_executable_load_code_object(executable_, agent_, code_object_, \"\")) {\n    return false;\n  }\n\n  if (HSA_STATUS_SUCCESS != hsa_executable_freeze(executable_, \"\")) {\n    return false;\n  }\n\n  return true;\n}\n\nvoid HsaTest::GetGpuPeer(hsa_agent_t master,\n                         std::vector<hsa_agent_t>& gpu_peers) {\n  AgentProps master_prop(master);\n  for (hsa_agent_t agent : gpus_) {\n    AgentProps agent_prop(agent);\n    if (master.handle == agent.handle ||\n        agent_prop.device_type != HSA_DEVICE_TYPE_GPU) {\n      continue;\n    }\n\n    hsa_amd_memory_pool_t peer_local_pool = global_coarse_[agent.handle];\n\n    hsa_amd_memory_pool_access_t access =\n        HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED;\n    if (HSA_STATUS_SUCCESS == hsa_amd_agent_memory_pool_get_info(\n                                  master, peer_local_pool,\n                                  HSA_AMD_AGENT_MEMORY_POOL_INFO_ACCESS,\n                                  (void*)&access) &&\n        access != HSA_AMD_MEMORY_POOL_ACCESS_NEVER_ALLOWED) {\n      gpu_peers.push_back(agent);\n    }\n  }\n}\n\nvoid* HsaTest::AllocateSystemMemory(bool fine_grain, size_t size) {\n  if (cpus_.size() == 0) {\n    return NULL;\n  }\n\n  hsa_amd_memory_pool_t pool = (fine_grain) ? global_fine_[cpus_[0].handle]\n                                            : global_coarse_[cpus_[0].handle];\n\n  void* ptr = NULL;\n  if (HSA_STATUS_SUCCESS != hsa_amd_memory_pool_allocate(pool, size, 0, &ptr)) {\n    return NULL;\n  }\n\n  return ptr;\n}\n\nvoid* HsaTest::AllocateLocalMemory(hsa_agent_t agent, size_t size) {\n  if (gpus_.size() == 0) {\n    return NULL;\n  }\n\n  hsa_amd_memory_pool_t pool = global_coarse_[agent.handle];\n\n  void* ptr = NULL;\n  if (HSA_STATUS_SUCCESS != hsa_amd_memory_pool_allocate(pool, size, 0, &ptr)) {\n    return NULL;\n  }\n\n  return ptr;\n}\n\nvoid HsaTest::FreeMemory(void* ptr) { hsa_amd_memory_pool_free(ptr); }\n\nvoid HsaTest::LaunchPacket(hsa_queue_t& queue, hsa_packet_type_t type,\n                           void* packet) {\n  uint32_t queue_bitmask = queue.size - 1;\n  const uint64_t write_index = hsa_queue_add_write_index_acq_rel(&queue, 1);\n\n  static const uint16_t kInvalidPacketHeader = HSA_PACKET_TYPE_INVALID;\n\n  if (type == HSA_PACKET_TYPE_KERNEL_DISPATCH) {\n    hsa_kernel_dispatch_packet_t* dispatch_packet =\n        reinterpret_cast<hsa_kernel_dispatch_packet_t*>(packet);\n    const uint16_t temp_header = dispatch_packet->header;\n    dispatch_packet->header = kInvalidPacketHeader;\n\n    // Populate queue buffer.\n    hsa_kernel_dispatch_packet_t* queue_buffer =\n        reinterpret_cast<hsa_kernel_dispatch_packet_t*>(queue.base_address);\n    queue_buffer[write_index & queue_bitmask] = *dispatch_packet;\n\n    // Enable packet.\n    std::atomic_thread_fence(std::memory_order_release);\n    queue_buffer[write_index & queue_bitmask].header = temp_header;\n    dispatch_packet->header = temp_header;\n  } else if (type == HSA_PACKET_TYPE_BARRIER_AND) {\n    hsa_barrier_and_packet_t* barrier_and_packet =\n        reinterpret_cast<hsa_barrier_and_packet_t*>(packet);\n    const uint16_t temp_header = barrier_and_packet->header;\n    barrier_and_packet->header = kInvalidPacketHeader;\n\n    // Populate queue buffer.\n    hsa_barrier_and_packet_t* queue_buffer =\n        reinterpret_cast<hsa_barrier_and_packet_t*>(queue.base_address);\n    queue_buffer[write_index & queue_bitmask] = *barrier_and_packet;\n\n    // Enable packet.\n    std::atomic_thread_fence(std::memory_order_release);\n    queue_buffer[write_index & queue_bitmask].header = temp_header;\n    barrier_and_packet->header = temp_header;\n  } else if (type == HSA_PACKET_TYPE_BARRIER_OR) {\n    hsa_barrier_or_packet_t* barrier_or_packet =\n        reinterpret_cast<hsa_barrier_or_packet_t*>(packet);\n    const uint16_t temp_header = barrier_or_packet->header;\n    barrier_or_packet->header = kInvalidPacketHeader;\n\n    // Populate queue buffer.\n    hsa_barrier_or_packet_t* queue_buffer =\n        reinterpret_cast<hsa_barrier_or_packet_t*>(queue.base_address);\n    queue_buffer[write_index & queue_bitmask] = *barrier_or_packet;\n\n    // Enable packet.\n    std::atomic_thread_fence(std::memory_order_release);\n    queue_buffer[write_index & queue_bitmask].header = temp_header;\n    barrier_or_packet->header = temp_header;\n  }\n\n  hsa_signal_store_release(queue.doorbell_signal, write_index);\n}\n\nvoid HsaTest::PrintAgentInfo(AgentProps& prop) {\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_NAME, prop.name, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_VENDOR_NAME, prop.vendor_name, \"\");\n\n  const char* feature_strings[] = {\"NONE\", \"HSA_AGENT_FEATURE_DISPATCH\",\n                                   \"HSA_AGENT_FEATURE_AGENT_DISPATCH\"};\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_FEATURE, feature_strings[prop.feature], \"\");\n\n  const char* model_strings[] = {\"HSA_MACHINE_MODEL_SMALL\",\n                                 \"HSA_MACHINE_MODEL_LARGE\"};\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_MACHINE_MODEL,\n                  model_strings[prop.machine_model], \"\");\n\n  const char* profile_strings[] = {\"HSA_PROFILE_BASE\", \"HSA_PROFILE_FULL\"};\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_PROFILE, profile_strings[prop.profile], \"\");\n\n  const char* default_float_rounding_strings[] = {\n      \"HSA_DEFAULT_FLOAT_ROUNDING_MODE_DEFAULT\",\n      \"HSA_DEFAULT_FLOAT_ROUNDING_MODE_ZERO\",\n      \"HSA_DEFAULT_FLOAT_ROUNDING_MODE_NEAR\"};\n  PRINT_ATTRIBUTE(\n      HSA_AGENT_INFO_DEFAULT_FLOAT_ROUNDING_MODE,\n      default_float_rounding_strings[prop.default_float_rounding_mode], \"\");\n  PRINT_ATTRIBUTE(\n      HSA_AGENT_INFO_BASE_PROFILE_DEFAULT_FLOAT_ROUNDING_MODES,\n      default_float_rounding_strings[prop.base_profile_float_rounding_mode],\n      \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_FAST_F16_OPERATION, prop.fast_f16_operation,\n                  \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_WAVEFRONT_SIZE, prop.wavefront_size, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_WORKGROUP_MAX_DIM[0],\n                  prop.workgroup_max_dim[0], \"\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_WORKGROUP_MAX_DIM[1],\n                  prop.workgroup_max_dim[1], \"\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_WORKGROUP_MAX_DIM[2],\n                  prop.workgroup_max_dim[2], \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_WORKGROUP_MAX_SIZE, prop.workgroup_max_size,\n                  \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_GRID_MAX_DIM.x, prop.grid_max_dim.x, \"\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_GRID_MAX_DIM.y, prop.grid_max_dim.y, \"\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_GRID_MAX_DIM.z, prop.grid_max_dim.z, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_GRID_MAX_SIZE, prop.grid_max_size, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_FBARRIER_MAX_SIZE, prop.fbarrier_max_size, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_QUEUES_MAX, prop.queue_max, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_QUEUE_MIN_SIZE, prop.queue_min_size, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_QUEUE_MAX_SIZE, prop.queue_max_size, \"\");\n\n  const char* queue_type_strings[] = {\"HSA_QUEUE_TYPE_MULTI\",\n                                      \"HSA_QUEUE_TYPE_SINGLE\"};\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_QUEUE_TYPE,\n                  queue_type_strings[prop.queue_type], \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_NODE, prop.node, \"\");\n\n  const char* device_type_strings[] = {\n      \"HSA_DEVICE_TYPE_CPU\", \"HSA_DEVICE_TYPE_GPU\", \"HSA_DEVICE_TYPE_DSP\"};\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_DEVICE, device_type_strings[prop.device_type],\n                  \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_CACHE_SIZE[0], prop.cache_size[0], \"bytes\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_CACHE_SIZE[1], prop.cache_size[1], \"bytes\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_CACHE_SIZE[2], prop.cache_size[2], \"bytes\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_CACHE_SIZE[3], prop.cache_size[3], \"bytes\");\n\n  std::string extensions = \"\";\n  extensions += (prop.extensions[HSA_EXTENSION_FINALIZER])\n                    ? \"HSA_EXTENSION_FINALIZER | \"\n                    : \"\";\n  extensions +=\n      (prop.extensions[HSA_EXTENSION_IMAGES]) ? \"HSA_EXTENSION_IMAGES | \" : \"\";\n  extensions += (prop.extensions[HSA_EXTENSION_AMD_PROFILER])\n                    ? \"HSA_EXTENSION_AMD_PROFILER \"\n                    : \"\";\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_EXTENSIONS, extensions, \"\");\n\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_VERSION_MAJOR, prop.version_major, \"\");\n  PRINT_ATTRIBUTE(HSA_AGENT_INFO_VERSION_MINOR, prop.version_minor, \"\");\n}\n\nvoid HsaTest::PrintPeers(hsa_agent_t agent) {\n  std::cout << \"Peer GPUs: \";\n  std::vector<hsa_agent_t> gpu_peers;\n  GetGpuPeer(agent, gpu_peers);\n  if (gpu_peers.size() > 0) {\n    for (hsa_agent_t peer_agent : gpu_peers) {\n      // Get the index of the peer in gpus_.\n      size_t peer_idx = 0;\n      for (; peer_idx < gpus_.size(); ++peer_idx) {\n        if (peer_agent.handle == gpus_[peer_idx].handle) {\n          std::cout << \"GPU[\" << peer_idx << \"] \";\n          break;\n        }\n      }\n    }\n    std::cout << std::endl;\n  } else {\n    std::cout << \"No peer GPUs\\n\";\n  }\n}\n\nvoid HsaTest::PrintPoolInfo(PoolProps& prop) {\n  const char* segment_strings[] = {\n      \"HSA_SEGMENT_GLOBAL\", \"HSA_AMD_SEGMENT_READONLY\",\n      \"HSA_AMD_SEGMENT_PRIVATE\", \"HSA_AMD_SEGMENT_GROUP\"};\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_SEGMENT,\n                  segment_strings[prop.segment], \"\");\n\n  std::string global_flag = \"\";\n  global_flag +=\n      (prop.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT)\n          ? \"HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_KERNARG_INIT | \"\n          : \"\";\n  global_flag +=\n      (prop.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED)\n          ? \"HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED | \"\n          : \"\";\n  global_flag +=\n      (prop.global_flag & HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED)\n          ? \"HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED \"\n          : \"\";\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, global_flag, \"\");\n\n  static const size_t kMb = 1024 * 1024;\n  if (prop.size >= kMb) {\n    PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_SIZE, ToMB(prop.size), \"MB\");\n  } else {\n    PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_SIZE, prop.size, \"bytes\");\n  }\n\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALLOWED,\n                  prop.alloc_allowed, \"\");\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_GRANULE,\n                  prop.alloc_granule, \"bytes\");\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_RUNTIME_ALLOC_ALIGNMENT,\n                  prop.alloc_alignment, \"bytes\");\n  PRINT_ATTRIBUTE(HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL,\n                  prop.all_accessible, \"\");\n}\n"
  },
  {
    "path": "samples/common/hsa_test.h",
    "content": "#ifndef HSA_TEST_H\n#define HSA_TEST_H\n\n#include <map>\n#include <string>\n#include <vector>\n\n#include \"hsa.h\"\n#include \"hsa_ext_amd.h\"\n#include \"hsa_ext_finalize.h\"\n\n#include \"HSAILTool.h\"\n\nclass HsaTest {\n public:\n  HsaTest(const char* test_name);\n  virtual ~HsaTest();\n\n  void Init();\n  void Cleanup();\n\n  virtual void Run() = 0;\n\n protected:\n  static hsa_status_t IterateAgents(hsa_agent_t agent, void* data);\n  static hsa_status_t IteratePools(hsa_amd_memory_pool_t pool, void* data);\n\n  typedef struct AgentProps {\n    AgentProps(hsa_agent_t);\n\n    char name[64];\n    char vendor_name[64];\n    hsa_agent_feature_t feature;\n    hsa_machine_model_t machine_model;\n    hsa_profile_t profile;\n    hsa_default_float_rounding_mode_t default_float_rounding_mode;\n    hsa_default_float_rounding_mode_t base_profile_float_rounding_mode;\n    bool fast_f16_operation;\n    uint32_t wavefront_size;\n    uint16_t workgroup_max_dim[3];\n    uint32_t workgroup_max_size;\n    hsa_dim3_t grid_max_dim;\n    uint32_t grid_max_size;\n    uint32_t fbarrier_max_size;\n    uint32_t queue_max;\n    uint32_t queue_min_size;\n    uint32_t queue_max_size;\n    hsa_queue_type_t queue_type;\n    uint32_t node;\n    hsa_device_type_t device_type;\n    uint32_t cache_size[4];\n    hsa_isa_t isa;\n    uint8_t extensions[128];\n    uint16_t version_major;\n    uint16_t version_minor;\n  } AgentProps;\n\n  typedef struct PoolProps {\n    PoolProps(hsa_amd_memory_pool_t pool);\n\n    hsa_amd_segment_t segment;\n    hsa_amd_memory_pool_global_flag_t global_flag;\n    size_t size;\n    bool alloc_allowed;\n    size_t alloc_granule;\n    size_t alloc_alignment;\n    bool all_accessible;\n  } PoolProps;\n\n  class Kernel {\n   public:\n    Kernel(hsa_agent_t agent, std::string hsail_file);\n\n    virtual ~Kernel();\n\n    uint64_t GetCodeHandle(const char* kernel_name);\n    hsa_status_t GetScratchSize(uint32_t* size);\n\n   protected:\n    virtual void Initialize();\n\n    virtual void Cleanup();\n\n    bool CreateProgramFromHsailFile();\n\n    bool CreateCodeObjectAndExecutable();\n\n    HSAIL_ASM::Tool tool_;\n\n    hsa_agent_t agent_;\n    hsa_profile_t profile_;\n\n    hsa_ext_program_t program_;\n    hsa_code_object_t code_object_;\n    hsa_executable_t executable_;\n    hsa_executable_symbol_t kernel_symbol_;\n\n    std::string hsail_file_;\n  };\n\n  virtual void GetGpuPeer(hsa_agent_t master,\n                          std::vector<hsa_agent_t>& gpu_peers);\n  virtual void* AllocateSystemMemory(bool fine_grain, size_t size);\n  virtual void* AllocateLocalMemory(hsa_agent_t agent, size_t size);\n  virtual void FreeMemory(void* ptr);\n\n  virtual void LaunchPacket(hsa_queue_t& queue, hsa_packet_type_t type,\n                            void* packet);\n\n  virtual void PrintAgentInfo(AgentProps& prop);\n  virtual void PrintPeers(hsa_agent_t agent);\n  virtual void PrintPoolInfo(PoolProps& prop);\n\n  std::string test_name_;\n\n  std::vector<hsa_agent_t> cpus_;\n  std::vector<hsa_agent_t> gpus_;\n\n  std::map<uint64_t, hsa_amd_memory_pool_t> global_fine_;\n  std::map<uint64_t, hsa_amd_memory_pool_t> global_coarse_;\n  std::map<uint64_t, hsa_amd_memory_pool_t> group_;\n};\n\n#endif  // HSA_TEST_H\n"
  },
  {
    "path": "samples/common/hsatimer.cpp",
    "content": "#include \"hsatimer.h\"\n\nPerfTimer::PerfTimer()\n{\n    freq_in_100mhz = MeasureTSCFreqHz();\n}\n\nPerfTimer::~PerfTimer()\n{\n\twhile(!_timers.empty())\n\t{\n\t\tTimer *temp = _timers.back();\n\t\t_timers.pop_back();\n\t\tdelete temp;\n\t}\n}\n\n//a new cretaed timer instantance index will be returned\nint PerfTimer::CreateTimer()\n{\n    Timer *newTimer = new Timer;\n\tnewTimer->_start = 0;\n\tnewTimer->_clocks = 0;\n\n#ifdef _WIN32\n    QueryPerformanceFrequency((LARGE_INTEGER*)&newTimer->_freq);       \n#else\n\tnewTimer->_freq = (long long)1.0E3;\n#endif\n\n\t/* Push back the address of new Timer instance created */\n\t_timers.push_back(newTimer);\n\treturn (int)(_timers.size() - 1);\n}\n\nint PerfTimer::StartTimer(int index)\n{\n\tif(index >= (int)_timers.size())\n\t{\n\t\tError(\"Cannot reset timer. Invalid handle.\");\n\t\treturn HSA_FAILURE;\n\t}\n\t\n#ifdef _WIN32\n        // General Windows timing method\n       #ifndef _AMD\n\tlong long tmpStart;\n\tQueryPerformanceCounter((LARGE_INTEGER*)&(tmpStart));\n\t_timers[index]->_start = (double)tmpStart;\n       #else\n       // AMD Windows timing method      \n\n       #endif\n\t   \n#else\n       // General Linux timing method\n      #ifndef _AMD\n\tstruct timeval s;\n\tgettimeofday(&s, 0);\n\t_timers[index]->_start = s.tv_sec * 1.0E3 + ((double)(s.tv_usec / 1.0E3)); \n       #else\n\n       // AMD timing method\n\n\tunsigned int unused;\n\t_timers[index]->_start = __rdtscp(&unused);\n\n       #endif\n\t   \n#endif\n\n\treturn HSA_SUCCESS;\n}\n\n\nint PerfTimer::StopTimer(int index)\n{\n\tdouble n=0;\n\tif(index >= (int)_timers.size())\n\t{\n\t\tError(\"Cannot reset timer. Invalid handle.\");\n\t\treturn HSA_FAILURE;\n\t}\n#ifdef _WIN32\n       #ifndef _AMD\n\tlong long n1;\n\tQueryPerformanceCounter((LARGE_INTEGER*)&(n1));\n\tn = (double) n1;\n\t#else\n\t\n        // AMD Window Timing\n        \n\t#endif\n\t\n#else\n        // General Linux timing method\n        #ifndef _AMD\n\tstruct timeval s;\n\tgettimeofday(&s, 0);\n\tn = s.tv_sec * 1.0E3+ (double)(s.tv_usec/1.0E3);\n\t#else\n       // AMD Linux timing\n\n\tunsigned int unused;\n\tn = __rdtscp(&unused);\n\t#endif\n\t\n#endif\n\n\tn -= _timers[index]->_start;\n\t_timers[index]->_start = 0;\n\n\t#ifndef _AMD\n\t_timers[index]->_clocks += n;\n\t#else\n        //_timers[index]->_clocks += 10 * n /freq_in_100mhz;      // unit is ns\n\t_timers[index]->_clocks += 1.0E-6 * 10  * n /freq_in_100mhz;  // convert to ms\n\tcout << \"_AMD is enabled!!!\" << endl;\n\t#endif\n\t\n\treturn HSA_SUCCESS;\n}\n\nvoid PerfTimer::Error(string str)\n{\n    cout << str << endl;\n}\n\n\ndouble PerfTimer::ReadTimer(int index)\n{\n\n\tif(index >= (int)_timers.size())\n\t{\n\t\tError(\"Cannot read timer. Invalid handle.\");\n\t\treturn HSA_FAILURE;\n\t}\n\t\n\tdouble reading = double(_timers[index]->_clocks);\n\t\n\treading = double(reading / _timers[index]->_freq);\n\t\n\treturn reading;\n}\n\n\nuint64_t PerfTimer::CoarseTimestampUs() \n{\n#ifdef _WIN32\n\tuint64_t freqHz, ticks;\n\tQueryPerformanceFrequency((LARGE_INTEGER *)&freqHz);\n\tQueryPerformanceCounter((LARGE_INTEGER *)&ticks);\n\n\t// Scale numerator and divisor until (ticks * 1000000) fits in uint64_t.\n\twhile (ticks > (1ULL << 44)) {\n\t\tticks /= 16;\n\t\tfreqHz /= 16;\n\t}\n\n\treturn (ticks * 1000000) / freqHz;\n#else\n\tstruct timespec ts;\n\tclock_gettime(CLOCK_MONOTONIC_RAW, &ts); \n\treturn uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;\n#endif\n}\n\nuint64_t PerfTimer::MeasureTSCFreqHz() \n{\n\t// Make a coarse interval measurement of TSC ticks for 1 gigacycles.\n\tunsigned int unused;\n\tuint64_t tscTicksEnd;\n\n\tuint64_t coarseBeginUs = CoarseTimestampUs();\n\tuint64_t tscTicksBegin = __rdtscp(&unused);\n\tdo \n\t{\n\t\ttscTicksEnd = __rdtscp(&unused);\n\t} \n\twhile (tscTicksEnd - tscTicksBegin < 1000000000);\n\t\n\tuint64_t coarseEndUs = CoarseTimestampUs();\n\n\t// Compute the TSC frequency and round to nearest 100MHz.\n\tuint64_t coarseIntervalNs = (coarseEndUs - coarseBeginUs) * 1000;\n\tuint64_t tscIntervalTicks = tscTicksEnd - tscTicksBegin;\n\treturn (tscIntervalTicks * 10 + (coarseIntervalNs / 2)) / coarseIntervalNs;\n}\n\n\n"
  },
  {
    "path": "samples/common/hsatimer.h",
    "content": "#ifndef __MYTIME__\n#define __MYTIME__\n\n// Will use AMD timer and general Linux timer based on users' need --> compilation flag\n// need to consider platform is Windows or Linux\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\n#if defined(_MSC_VER)\n  #include <time.h>\n  #include <windows.h>\n  #include <intrin.h>\n#else\n  #if defined(__GNUC__)\n    #include <sys/time.h>\n    #include <x86intrin.h>\n  #endif // __GNUC__\n#endif //_MSC_VER\n\n#define HSA_FAILURE  1\n#define HSA_SUCCESS 0\n\nclass PerfTimer {\n\tprivate:\n\t\tstruct Timer\n\t\t{\n\t\t\tstring name;          /* < name name of time object*/\n\t\t\tlong long _freq;      /* < _freq frequency*/\n\t\t\tdouble _clocks;       /* < _clocks number of ticks at end*/\n\t\t\tdouble _start;        /* < _start start point ticks*/\n\t\t};\n\n\t\tstd::vector<Timer*> _timers;  /*< _timers vector to Timer objects */\n\t\tdouble freq_in_100mhz;\n\n\tpublic:\n\t\tPerfTimer();\n\t\t~PerfTimer();\n\n\tprivate:\n\t\t//AMD timing method\n\t\tuint64_t CoarseTimestampUs();\n\t\tuint64_t MeasureTSCFreqHz();\n\n\t\t//General Linux timing method\n\n\tpublic:\n\t\tint CreateTimer();\n\t\tint StartTimer(int index);\n\t\tint StopTimer(int index);\n\n\tpublic:\n\t\t// retrieve time\n\t\tdouble ReadTimer(int index);\n\t\t// write into a file\n\t\tdouble WriteTimer(int index);\n\n\tpublic:\n\t\tvoid Error(string str);\n};\n\n#endif\n\n"
  },
  {
    "path": "samples/common/os.cpp",
    "content": "#ifdef _WIN32 // Compiling for Windows Platform\n\n#include <stdlib.h>\n#include <Windows.h>\n#include \"os.h\"\n#include <stdio.h>\n\nvoid SetEnv(const char* env_var_name, const char* env_var_value) {\n  BOOL err = SetEnvironmentVariable(env_var_name, env_var_value);\n  if(FALSE == err){\n\t  printf(\"Set environment variable failed!\\n\");\n\t  exit(1);\n  }\n  return;\n}\n\nchar* GetEnv(const char* env_var_name){\n  char* buff;\n  DWORD char_count = GetEnvironmentVariable(env_var_name, NULL, 0);\n  if (char_count == 0) return NULL;\n  buff = (char*)malloc(sizeof(char) * char_count);\n  GetEnvironmentVariable(env_var_name, buff, char_count);\n  buff[char_count - 1] = '\\0';\n  return buff;\n}\n\n#elif defined(__linux__)\n\n#include \"os.h\"\n#include <stdlib.h>\n\nvoid SetEnv(const char* env_var_name, const char* env_var_value){\n\tint err = setenv(env_var_name, env_var_value, 1);\n\tif(0 != err){\n\t\tprintf(\"Set environment variable failed!\\n\");\n\t\texit(1);\n\t}\n\treturn;\n}\n\nchar* GetEnv(const char* env_var_name) {\n  return getenv(env_var_name);\n}\n\n#endif\n"
  },
  {
    "path": "samples/common/os.h",
    "content": "#ifndef HSA_PERF_SRC_UTILS_OS_H_\n#define HSA_PERF_SRC_UTILS_OS_H_\n\n#include <stdio.h>\n\n// Set envriroment variable\nvoid SetEnv(const char* env_var_name, const char* env_var_value);\n\n// Get the value of enviroment\nchar* GetEnv(const char* env_var_name);\n\n#endif\n"
  },
  {
    "path": "samples/common/utilities.cpp",
    "content": "#include \"utilities.h\"\n\n/*\n * Prints no more than 256 elements of the given array.\n * Prints full array if length is less than 256.\n * Prints Array name followed by elements.\n */\ntemplate<typename T> \nvoid PrintArray(\n    string header, \n    const T * data, \n    const int width,\n    const int height) \n{\n    cout<<\"\\n\"<<header<<\"\\n\";\n    for(int i = 0; i < height; i++)\n    {\n        for(int j = 0; j < width; j++)\n        {\n            cout<<data[i*width+j]<<\" \";\n        }\n        cout<<\"\\n\";\n    }\n    cout<<\"\\n\";\n}\n\ntemplate<typename T>\nint IsPowerOf2(T val)\n{\n    long long _val = val;\n    if((_val & (-_val))-_val == 0 && _val != 0)\n        return 0;\n    else\n        return -1;\n}\n\n\ntemplate<typename T>\nT RoundToPowerOf2(T val)\n{\n    int bytes = sizeof(T);\n\n    val--;\n    for(int i = 0; i < bytes; i++)\n        val |= val >> (1<<i);  \n    val++;\n\n    return val;\n}\n\ntemplate<typename T> \nint FillRandom(\n         T * arrayPtr, \n         const int width,\n         const int height,\n         const T rangeMin,\n         const T rangeMax,\n         unsigned int seed)\n{\n    if(!arrayPtr)\n    {\n        printf(\"Cannot fill array. NULL pointer.\");\n        return -1;\n    }\n\n    if(!seed)\n        seed = (unsigned int)time(NULL);\n\n    srand(seed);\n    double range = double(rangeMax - rangeMin) + 1.0; \n\n    /* random initialisation of input */\n    for(int i = 0; i < height; i++)\n        for(int j = 0; j < width; j++)\n        {\n            int index = i*width + j;\n            arrayPtr[index] = rangeMin + T(range*rand()/(RAND_MAX + 1.0)); \n        }\n\n    return 0;\n}\n\n#if 0\n//get a memory region that can be used for global memory allocations.\nhsa_status_t get_global_region(hsa_region_t region, void* data) \n{\n\thsa_region_segment_t segment;\n\thsa_region_get_info(region, HSA_REGION_INFO_SEGMENT, &segment);\n\tif (HSA_REGION_SEGMENT_GLOBAL == segment) \n\t{\n\t\thsa_region_t* ret = (hsa_region_t*) data;\n\t\t*ret = region;\n\t}\n\treturn HSA_STATUS_SUCCESS;\n}\n\n\n/*\n * Finds the specified symbols offset in the specified brig_module.\n * If the symbol is found the function returns HSA_STATUS_SUCCESS, \n * otherwise it returns HSA_STATUS_ERROR.\n */\nhsa_status_t find_symbol_offset(hsa_ext_brig_module_t* brig_module, \n\t\tchar* symbol_name,\n\t\thsa_ext_brig_code_section_offset32_t* offset) \n{\n\n\t/*  \n\t * Get the data section \n\t */\n\thsa_ext_brig_section_header_t* data_section_header = \n\t\tbrig_module->section[HSA_EXT_BRIG_SECTION_DATA];\n\t/*  \n\t * Get the code section\n\t */\n\thsa_ext_brig_section_header_t* code_section_header =\n\t\tbrig_module->section[HSA_EXT_BRIG_SECTION_CODE];\n\n\t/*  \n\t * First entry into the BRIG code section\n\t */\n\tBrigCodeOffset32_t code_offset = code_section_header->header_byte_count;\n\tBrigBase* code_entry = (BrigBase*) ((char*)code_section_header + code_offset);\n\twhile (code_offset != code_section_header->byte_count) \n\t{\n\t\tif (code_entry->kind == BRIG_KIND_DIRECTIVE_KERNEL) \n\t\t{\n\t\t\t/* \n\t\t\t * Now find the data in the data section\n\t\t\t */\n\t\t\tBrigDirectiveExecutable* directive_kernel = (BrigDirectiveExecutable*) (code_entry);\n\t\t\tBrigDataOffsetString32_t data_name_offset = directive_kernel->name;\n\t\t\tBrigData* data_entry = (BrigData*)((char*) data_section_header + data_name_offset);\n\t\t\tif (!strncmp(symbol_name, (char*) data_entry->bytes, strlen(symbol_name))) \n\t\t\t{\n\t\t\t\t*offset = code_offset;\n\t\t\t\treturn HSA_STATUS_SUCCESS;\n\t\t\t}\n\t\t}\n\t\tcode_offset += code_entry->byteCount;\n\t\tcode_entry = (BrigBase*) ((char*)code_section_header + code_offset);\n\t}   \n\treturn HSA_STATUS_ERROR;\n}\n#endif\n\n/*\n * Determines if the given agent is of type HSA_DEVICE_TYPE_GPU\n * and sets the value of data to the agent handle if it is.\n */\nhsa_status_t find_gpu(hsa_agent_t agent, void *data) \n{\n\tif (data == NULL) \n\t{\n\t\treturn HSA_STATUS_ERROR_INVALID_ARGUMENT;\n\t}   \n\thsa_device_type_t device_type;\n\thsa_status_t stat = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);\n\tif (stat != HSA_STATUS_SUCCESS) \n\t{\n\t\treturn stat;\n\t}   \n\tif (device_type == HSA_DEVICE_TYPE_GPU) \n\t{\n\t\t*((hsa_agent_t *)data) = agent;\n\t}   \n\treturn HSA_STATUS_SUCCESS;\n}\n\n\n/*\n * Determines if a memory region can be used for kernarg\n * allocations.\n */\nhsa_status_t get_memory_region(hsa_region_t region, void* data) \n{\n\thsa_region_global_flag_t flags;\n\thsa_region_get_info(region, HSA_REGION_INFO_GLOBAL_FLAGS, &flags);\n\n\tMemRegion *my_mem_region = (MemRegion *)data;\n\t\n\tif (flags & HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED) {\n             my_mem_region->coarse_region = region;\n       }\n\t\n\tif (flags & HSA_REGION_GLOBAL_FLAG_KERNARG) \n\t{\n\t\tmy_mem_region->kernarg_region= region;\n\t}   \n\t\n\treturn HSA_STATUS_SUCCESS;\n}\n\n"
  },
  {
    "path": "samples/common/utilities.h",
    "content": "#ifndef __HSA_UTILITY__\n#define __HSA_UTILITY__\n\n#include <vector>\n#include <thread>\n\n#include \"hsa.h\"\n#include \"hsa_ext_finalize.h\"\n\n#include <string.h>\n#include<iostream>\nusing namespace std;\n\n\n\n#define HSA_ARGUMENT_ALIGN_BYTES 16\n\n#if defined(_MSC_VER)\n  #define ALIGNED_(x) __declspec(align(x))\n\n#pragma warning(disable: 4800)\n#pragma warning(disable: 4305) // truncation from 'double' to 'const float'\n#pragma warning(disable: 4267) // conversion from 'size_t' to 'int', possible loss of data\n\ntypedef unsigned int uint;\n\n#else\n  #if defined(__GNUC__)\n    #define ALIGNED_(x) __attribute__ ((aligned(x)))\n  #endif // __GNUC__\n#endif // _MSC_VER\n\n#define SDK_FAILURE 1\n#define SDK_SUCCESS 0\n\n/*\n#define check(msg, status) \\\nif (status != HSA_STATUS_SUCCESS) { \\\n\tprintf(\"%s failed.\\n\", #msg); \\\n\texit(1); \\\n} else { \\\n\tprintf(\"%s succeeded.\\n\", #msg); \\\n}\n*/\n#define check(msg, status) \\\nif (status != HSA_STATUS_SUCCESS) { \\\n\tprintf(\"%s failed.\\n\", #msg); \\\n\texit(1); \\\n} else { \\\n\t; \\\n}\n\n/*\n * Define required BRIG data structures.\n */\n\ntypedef uint32_t BrigCodeOffset32_t;\n\ntypedef uint32_t BrigDataOffset32_t;\n\ntypedef uint16_t BrigKinds16_t;\n\ntypedef uint8_t BrigLinkage8_t;\n\ntypedef uint8_t BrigExecutableModifier8_t;\n\ntypedef BrigDataOffset32_t BrigDataOffsetString32_t;\n\ntypedef struct {\n  // memory region accessed by GPU only\n  hsa_region_t coarse_region;\n\n  // system memory access by gpu and cpu\n  hsa_region_t kernarg_region;\n\n} MemRegion;\n\n\n/*\nenum BrigKinds {\n\tBRIG_KIND_NONE = 0x0000,\n\tBRIG_KIND_DIRECTIVE_BEGIN = 0x1000,\n\tBRIG_KIND_DIRECTIVE_KERNEL = 0x1008,\n};\n\ntypedef struct BrigBase BrigBase;\nstruct BrigBase {\n\tuint16_t byteCount;\n\tBrigKinds16_t kind;\n};\n\ntypedef struct BrigExecutableModifier BrigExecutableModifier;\nstruct BrigExecutableModifier {\n\tBrigExecutableModifier8_t allBits;\n};\n\ntypedef struct BrigDirectiveExecutable BrigDirectiveExecutable;\nstruct BrigDirectiveExecutable {\n\tuint16_t byteCount;\n\tBrigKinds16_t kind;\n\tBrigDataOffsetString32_t name;\n\tuint16_t outArgCount;\n\tuint16_t inArgCount;\n\tBrigCodeOffset32_t firstInArg;\n\tBrigCodeOffset32_t firstCodeBlockEntry;\n\tBrigCodeOffset32_t nextModuleEntry;\n\tuint32_t codeBlockEntryCount;\n\tBrigExecutableModifier modifier;\n\tBrigLinkage8_t linkage;\n\tuint16_t reserved;\n};\n\ntypedef struct BrigData BrigData;\nstruct BrigData {\n\tuint32_t byteCount;\n\tuint8_t bytes[1];\n};\n*/\n\nstruct float2\n{\n    float s0;\n    float s1;\n\n\n    float2 operator * (float2 &fl)\n    {\n        float2 temp;\n        temp.s0 = (this->s0) * fl.s0;\n        temp.s1 = (this->s1) * fl.s1;\n        return temp;\n    }\n\n    float2 operator * (float scalar)\n    {\n        float2 temp;\n        temp.s0 = (this->s0) * scalar;\n        temp.s1 = (this->s1) * scalar;\n        return temp;\n    }\n\n    float2 operator + (float2 &fl)\n    {\n        float2 temp;\n        temp.s0 = (this->s0) + fl.s0;\n        temp.s1 = (this->s1) + fl.s1;\n        return temp;\n    }\n    \n    float2 operator - (float2 fl)\n    {\n        float2 temp;\n        temp.s0 = (this->s0) - fl.s0;\n        temp.s1 = (this->s1) - fl.s1;\n        return temp;\n    }\n};\n\n\nstruct uint2\n{\n    uint s0;\n    uint s1;\n\n\n    uint2 operator * (uint2 &fl)\n    {\n        uint2 temp;\n        temp.s0 = (this->s0) * fl.s0;\n        temp.s1 = (this->s1) * fl.s1;\n        return temp;\n    }\n\n    uint2 operator * (float scalar)\n    {\n        uint2 temp;\n        temp.s0 = (this->s0) * scalar;\n        temp.s1 = (this->s1) * scalar;\n        return temp;\n    }\n\n    uint2 operator + (uint2 &fl)\n    {\n        uint2 temp;\n        temp.s0 = (this->s0) + fl.s0;\n        temp.s1 = (this->s1) + fl.s1;\n        return temp;\n    }\n    \n    uint2 operator - (uint2 fl)\n    {\n        uint2 temp;\n        temp.s0 = (this->s0) - fl.s0;\n        temp.s1 = (this->s1) - fl.s1;\n        return temp;\n    }\n};\n\n\n/*\n * Prints no more than 256 elements of the given array.\n * Prints full array if length is less than 256.\n * Prints Array name followed by elements.\n */\ntemplate<typename T> void PrintArray(string header, const T * data, const int width, const int height);\n\ntemplate<typename T> int IsPowerOf2(T val);\n\ntemplate<typename T> T RoundToPowerOf2(T val);\n\ntemplate<typename T> int FillRandom(T * arrayPtr, const int width, const int height, const T rangeMin, const T rangeMax, unsigned int seed=123);\n\n//get a memory region that can be used for global memory allocations.\nhsa_status_t get_global_region(hsa_region_t region, void* data); \n\n/*\n * Finds the specified symbols offset in the specified brig_module.\n * If the symbol is found the function returns HSA_STATUS_SUCCESS, \n * otherwise it returns HSA_STATUS_ERROR.\n */\n \n//hsa_status_t find_symbol_offset(hsa_ext_brig_module_t* brig_module, char* symbol_name, hsa_ext_brig_code_section_offset32_t* offset);\n\n/*\n * Determines if the given agent is of type HSA_DEVICE_TYPE_GPU\n * and sets the value of data to the agent handle if it is.\n */\nhsa_status_t find_gpu(hsa_agent_t agent, void *data);\n\n/*\n * Determines if a memory region can be used for kernarg\n * allocations.\n */\nhsa_status_t get_memory_region(hsa_region_t region, void* data);\n\n#endif\n"
  }
]